当前位置: 首页 > article >正文

Java面试八股文之暑假合集

八股文暑假合集

      • 基础篇
        • 二分查找
    • java基础篇
      • 7月12号
        • 面向对象和面向过程的区别
        • 重载和重写
        • String
      • 7月13号
        • 自动装箱和拆箱
        • 静态方法
        • 构造方法
        • 成员变量和局部变量
        • 对象引用和对象实例
        • 返回值
        • == 与equals(重要)
        • hashcode()和equals()
        • HashMap
      • 7月16号
        • 线程,进程和程序
        • final关键字的总结
      • 7月18号
        • 小厂一面30问
      • 7月22号
        • 面试经典题
        • Java8新特性详解
        • 异常处理详解
        • MySQL 索引的最左原则详解
      • spring
      • springMVC
      • springboot
      • springcloud
      • redis
      • MybatisPlus
      • spring security
      • git
      • 微服务
      • 7月30号 java实习广东小厂面试
      • http中关于各个状态码怎么分类的,了解哪些
      • 8月6号 某小厂面试
      • 8月15
      • 8月17号
    • 吉因加面试
        • 1、线程创建方法
        • 2、多目标遗传算法实现
        • 3、简历项目每个细节都要说清楚 重要
        • 4、动态代理实现方式2个
        • 5、状态码
        • 6、数组的扩容机制
        • 7、maven项目的目录
        • 8、http的传输数据的方式
        • 9、mybatis和mybatispius的区别
        • 10、专业单词会读
        • 11、clone两种下载数据的区别
        • 12、异常的分类
        • 13、arraylist和linklist
        • 14、集合分类
        • 15、Linux常用命令
        • 1.简单系统命令
        • 2.Linux文件操作
          • 2.1查看文件列表
          • 2.2 切换目录
          • 2.3新建文件夹及文件
          • 2.4删除文件
          • 2.5拷贝文件
          • 2.6移动文件或修改文件名
        • 3.系统管理
        • 16、docker创建镜像的命令

基础篇

二分查找

步骤:

  1. 有序数组(这是前提,默认)

  2. 创建一个最左变量L,一个最右变量R,中间索引M=(L+R)/2(这里要注意,在java中浮点数取整为向下取整,如(3+2)/2=2,也要和4舍5入区分开),循环执行步骤3

  3. 如果L<=R

    • 如果目标值等于下标为M的值,则返回M

    • 如果目标值大于下标为M的值,则L=M+1

    • 如果目标值小于下标为M的值,则R=M-1

  4. 如果L>R,没找到返回-1

代码:

public class d {
    public static void main(String[] args) {

        int[] num={23,24,26,36,234,453,2357,123456};
        int target=4;
        int i = binTree(num, target);
        System.out.println(i);

    }

    public static int binTree(int[] num,int target){
        int L=0,R=num.length-1;
        while (L<=R){
            int M=(L+R)/2;
            if (target==num[M]){
                return M;
            }else if (target<num[M]){
                R=M-1;
            }else{
                L=M+1;
            }
        }
        return -1;
    }
}
public static void main(String[] args) {
    int a=(Integer.MAX_VALUE+(Integer.MAX_VALUE-1))/2;
    System.out.println(a);
}

输出:

-1

不足:当L和R都特别大时就会存在M值大于int类型的最大值,存在整数溢出。

原因:int 类型和Integer包装类型的取值范围都为-2147483648~2147483647,当int的值大于2147483647或小于-2147483648时就会产生溢出。

方法一

实际需要的值:(2147483646+2147483647)/2=2,147,483,646 

溢出后的值:-1      (L+R)/2
 
中间索引:L+(R-L)/2   --->L+R/2-L/2--->(L+R)/2   (R-L)/2   两数相减值不会溢出
public static void main(String[] args) {
    int a=Integer.MAX_VALUE+(-Integer.MAX_VALU+(Integer.MAX_VALUE-1))/2;
    int b=(Integer.MAX_VALUE+(Integer.MAX_VALUE-1))/2;
    System.out.println(a);
    System.out.println(b);

}

输出:

2147483647
-1

方法二

因为计算机存储数字都是以补码的形式存储的。所以可以通过移位运算来避免溢出。
举个例子,8位带符号的二进制数运算

01111111+01111111=111111110 127+127=-2 (127+127)/2=127

将结果向右移一位:01111111 ------>127 刚好等于我们想要的值

中间索引:M=(L+R)>>>1
public static void main(String[] args) {
    int a=Integer.MAX_VALUE+(-Integer.MAX_VALUE+(Integer.MAX_VALUE-1))/2;
    int b=(Integer.MAX_VALUE+(Integer.MAX_VALUE-1))>>>1;
    System.out.println(a);
    System.out.println(b);

}
2147483647
2147483647

java基础篇

7月12号

面向对象和面向过程的区别

​ 先理解什么是面向对象和什么是面向过程简单来说面向对象是指编程时以对象为中心,通过封装,继承,多态和实现等概念来实现功能,程序以类和对象组成,类包含一组属性和方法,对象是类的一个实例,通过在对象之间传递消息来实现数据的处理和传递。然后面向过程的话是以步骤为中心,代码主要包括函数和过程,而这些函数和过程都是独立的,他们通过传递参数来实现数据的处理和传递。

面向过程

优点:性能比面向对象高,因为面向对象中的对象调用时需要实例化,消耗资源。面向过程的话一般用于单片机,LInux,嵌入式开发等,这些都是有性能要求。

缺点:没有面向对象的易复用,易维护,易拓展

面向对象

优点:易维护,易拓展,易复用,面向对象包含继承,多态,封装等特性,设计出来的系统低耦合,系统更加灵活。

缺点:性能比面向过程低。

重载和重写

重写

发生在父子类之间,子类重写父类中的方法,方法名和参数必须相同,返回值,异常抛出的范围小于等于父类,否则向上转型后的类型不兼容,从而引发异常;子类对象可以调用父类中没被private修饰的方法,当子类中重写了父类中的某个方法,而子类对象想调用父类中的该方法,而不是重载后的方法,可以使用super关键字调用该方法;父类通常情况下不能调用子类中的方法。

重载

在一个类中存在多个相同名称的方法或构造函数,但是参数列表必须不同(参数的类型,名称,个数等),使用重载可以增加代码的灵活性,可读性。
String

StringBuffer StringBuilder 的区别是什么? String 为什么是不可变的?

可变性看是否被final关键字修饰

答:String类中他是由final关键字修饰的字符数组保存字符串,private final char value[],所以String对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中用字符数组保存字符串但是没用final关键字修饰,所以这两个都是可变的。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
 char[] value;
 int count;
 AbstractStringBuilder() {
 }
 AbstractStringBuilder(int capacity) {
 value = new char[capacity];
 }

线程安全

线程是进程的执行单位,一个进程包含多个线程

先了解什么是线程安全,每个进程都会有一个共同的区域在内存中,叫做堆(内存),由于这个堆内存每个进程中的线程都可以访问里面的数据,在没有限制的情况下,数据存在被修改的风险。然后这个堆内存存储着对象实例,线程使用对象的引用调用对象的实例从而访问对象的成员变量和方法。

然后分析下String类,StringBuilder类,StringBuffer类是否是线程安全的?

首先String类他是由final修饰的字符数组组成的字符串,是一个常量,因此是线程安全的。

StringBuffer类他使用synchronized关键字来实现同步锁(互斥锁),synchronized修饰方法或者代码块,所以线程安全。就是当一个线程访问由synchronized修饰的方法或者代码块时,线程或尝试获取锁,如果获取成功则执行该方法,如果锁被其他线程占用,则该线程被阻塞,直到锁被释放为止。然后这个同步锁只能保证共享资源的互斥访问,不能保证数据是否正确,因为当多个线程访问同一个数据时,进行读写操作后,数据并不能保证没有被修改,因此可以增加原子性操作,来保证数据的一致性。

StringBulider类并未加同步锁,所以是非线程安全

7月13号

性能

StringBuilder的性能比StringBuffer的性能高10%~15%,但是要冒着线程不安全的风险。每次对String对象进行改变时都会生成一个新的String对象然后将指针指向新的对象,对StringBuilder和StringBuffer对象进行操作时都是对原有的对象进行操作。

总结:

少量数据=String

单线程操作字符串缓冲区大量数据=StringBuffer

多线程操作字符串缓冲区大量数据=StringBuilder

自动装箱和拆箱

装箱

将基本数据类型用他们对应的引用类型包装起来

int q=1;
Integer w=q;

拆箱

将包装类型转换为基本数据类型

Integer q=10;
int w=q;
静态方法

问:在一个静态方法内调用一个非静态方法 为什么是非法的

答:有不同的作用域和生命周期,静态方法直接用类名进行调用,无需创建类的实例,而非静态方法依赖于类的实例,如果你要在静态方法中调用非静态方法,需要先创建类的实例,再来调用非静态方法。

构造方法

问:在 Java 中定义一个不做事且没有参数的构造方法的作用

答:在父子类中,当子类不用super()指定调用父类的构造方法,子类会默认调用无参构造,此时当父类不存在无参构造时,程序就会出现编译错误,解决方法就是在父类中加上一个无参构造。

成员变量和局部变量

问:成员变量和局部变量的区别

答:从语法形式上看,成员变量存在于类中,局部变量存在于方法或代码块中,成员变量可以被控制修饰符修饰,局部变量不能被访问控制修饰符和static修饰,但是两者都可以被final修饰。

从存储方式来看,成员变量因为在对象中因此存储在堆内存里,局部变量存储在栈内存中。

从变量在内存中的生存时间来看,成员变量随对象的创建而创建,局部变量随方法的执行而自动消失。

public class MyClass {
    private int x; // x 是一个成员变量
    public void setX(int value) {
        int b=1;  // b 是一个局部变量
        x = value;  
    }
    public int getX() {
        return x;
    }
}
对象引用和对象实例

问:创建一个对象用什么运算符?对象实例与对象引用有何不同?

使用new运算符来创建对象,对像实例存储在堆内存中,对象引用存储在栈内存中,一个对象实例可以被多个对象引用所指向(可以用 n 条绳子系住一个气球),一个对象引用指向一个或0个对象实例(一根绳子可以不系气球,也可以系一个气球)。

返回值

问:什么是返回值?返回值的作用是什么?

答:返回值就是获取方法体运行结束后返回的结果(前提是有结果),返回值的作用是接收结果,将其用于其他操作。

== 与equals(重要)

问:==和equals的特点

答:==如果比较的是基本数据类型的话,那么就是比较这两个数据的值是否相等,如果比较的是两个对象的话,那么比较的是这两个对象的内存地址是否相等。

​ equals判断两个对象是否相等,但是他有两种使用情况,第一种就是equals()方法没有被类覆盖,那么比较的是两个对象的内存地址,第二种类覆盖了equals()方法,通常都会使用重写该方法的方式去比较两个对象的值是否相等。

​ 然后的话String类重写了equals()方法,比较的是两个对象的值是否相等,Object类里面的equals()方法跟==一样比较的是两个类的内存地址是否相同,StringBuffer类和StringBuilder类并没有重写equals()方法,其比较的还是引用类型的地址。

public class test1 {
 public static void main(String[] args) {
 String a = new String("ab"); // a 为一个引用
 String b = new String("ab"); // b 为另一个引用,对象的内容一样
 String aa = "ab"; // 放在常量池中
 String bb = "ab"; // 从常量池中查找
 if (aa == bb) // true
 System.out.println("aa==bb");
 if (a == b) // false,非同一对象
 System.out.println("a==b");
 if (a.equals(b)) // true
 System.out.println("aEQb");
 if (42 == 42.0) { // true
 System.out.println("true");
 }
 }
}
hashcode()和equals()

问:你有没有重写过hashcode()和equals()方法,为什么重写equals()方法必须重写hashcode()方法?

答:重写过,首先先了解下hashcode()方法的作用是什么,hashcode()方法用来获取哈希码,实际上就是返回一个int整数。这个哈希码的作用是用来获取对象在哈希表中的位置,hashcode()定义在JDK中的Object类中,因此意味着java中的任何类都包含hashcode()函数。这个哈希表存储着键值对,可以通过键快速检索出对应的值。

我通过hashset来解释hashcode的作用,当我们存对象到hashset中时,hashset会先获取该对象的hashcode值来判断对象的存储位置,同时也会将其与已经加入对象的hashcode值作比较,如果不存在相同的hashcode值,则hashset同意加入该对象。如果存在hashcode值相等的对象,则会使用equals()方法来检查hashcode值相等的对象是否真的相同。如果相同,则hashset不会让加入操作成功,如果不同,则将该对象散列到其他位置。这样就大大减少了equals的次数,提高了执行速度。

如果两个对象相等,则hashcode一定相等

如果hashcode相同则用equals方法比较不一定相等

如果用equals比较相等的话,hashcode一定相等。

hashcode不相同则用equals方法比较一定不相等

hashcode用==比较int,equals比较对象地址,要保证相等的对象具有相同的hashcode。

HashMap
  1. HashMap的底层原理是什么?

HashMap底层的实现是一个数组,每个元素称为桶(bucket),每个桶存储一个键值对,其中键值对的键通过哈希函数计算出一个哈希值,然后根据哈希值将键值对存储到相应的桶中。

  1. HashMap的put是怎么存储数据的,哈希冲突怎么解决的?

当我们向HashMap中put一个键值对时,首先会根据键的hashcode值计算出它在数组中的索引位置,然后将值存储在对应的链表(或红黑树)中,如果是链表的话使用的是尾插法,如果是红黑树的话,则根据值的大小自动排序。hashmap解决哈希冲突的方法是链地址法,优点是简单,易实现,但是也存在一些缺点,当链表长度过程,会导致查询速度过慢,在java8中规定当链表中元素个数大于等于8时,将链表转化为红黑树。

  1. HashMap不是线程安全的,那有什么是线程安全的?

ConcurrentHashMap是线程安全的HashMap实现。

  1. ConcurrentHashMap是怎么实现的线程安全?

ConcurrentHashMap内部维护了多个Segment,每个Segment相当于一个小的HashMap,它们之间相互独立,互不影响。在进行插入、查找或删除操作时,只需要锁定对应的Segment,而不是整个HashMap,这样可以减小锁的粒度,提高并发能力。

  1. HashMap初始容量大小是多少?

HashMap的初始容量大小是16。

  1. HashMap怎么实现的扩容?

当HashMap中的元素数量达到容量的75%时,就会触发扩容操作,即将容量扩大为原来的两倍,并重新构建哈希表。

  1. HashMap为什么每次扩容为2的n次方?

HashMap每次扩容为2的n次方是为了让元素在哈希表中分布更加均匀。

7月16号

线程,进程和程序

问:简述线程,进程,程序的基本概念。以及他们之间的关系是什么?

答:线程与进程相似,但是线程是一个比进程更小的执行单位。一个进程在执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一个内存空间和同一组系统资源,所以系统产生一个或多个线程,并在各个线程之间进行切换工作时,负担要比进程小得多,因此线程也被叫做轻量级进程。

​ 程序是含有指令和数据的文件,被存储在磁盘或者其他存储设备中,也就是说程序是静态的代码。

​ 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序及是一个进程的创建,执行和消亡的过程。简单来说一个进程就是一个执行中的程序,他在计算机中一个指令一个指令的执行,同时每个进程还会占用某些系统资源,如cpu时间,内存空间,文件,输入输出设备等。线程是进程的执行单位,进程是程序的执行单位。

问:线程的状态

答:

1 、新建状态( New ):新创建了一个线程对象。
2 、就绪状态( Runnable ):线程对象创建后,其他线程调用了该对象的 start() 方法。
该状态的线程位于可运行线程池中,变得可运行,等待获取 CPU 的使用权。
3 、运行状态( Running ):就绪状态的线程获取了 CPU ,执行程序代码。
4 、阻塞状态( Blocked ):阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止
运行。直到线程进入就绪状态,才有机会转到运行状态。
阻塞的情况分三种 :
(一)、等待阻塞:运行的线程执行 wait() 方法, JVM 会把该线程放入等待池中。 (wait会释放持有的锁 )
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行 sleep() 或 join() 方法,或者发出了 I/O 请求时, JVM会把该线程置为阻塞状态。当 sleep() 状态超时、 join() 等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。(注意,sleep 是不会释放持有的锁)
5 、死亡状态( Dead ):线程执行完了或者因异常退出了 run() 方法,该线程结束生命周期。

final关键字的总结

问:final关键字的作用是什么

答:final关键字一般用来修饰方法,类,变量

1.用来修饰变量的话有两种情况,当修饰的是基本数据类型的变量,那么该变量的值一旦完成初始化后就不能更改;如果修饰引用类型的变量,那么在完成初始化后,该变量不能指向其他对象。

2.用来修饰类的话,表明该类不能被继承,且该类中的方法隐式为final方法。

3.使用final方法有两个原因,第一个就是方法锁定,防止继承类修改该方法的含义;第二个原因是效率问题,在早期的java版本中,会把final方法内嵌调用,如果方法过于庞大,可能也难以看出内嵌调用带来效率的提升,现在的java版本已经不需要使用final方法来实现性能的优化了,类中的所有private方法都隐式的指定为final。

7月18号

小厂一面30问
  1. Redis除了存储数据外还能实现什么功能?

除了存储数据外,Redis还可以实现数据的缓存、分布式锁、消息队列、计数器等功能。Redis还支持事务、Lua脚本、发布/订阅等高级功能。

  1. Java8有什么新特性?

Java8的新特性包括Lambda表达式、函数式接口、Stream API、默认方法、新的Date/Time API等。

  1. Java中有哪些语法糖?

Java中的语法糖包括自动装箱/拆箱、泛型、foreach循环、变长参数、枚举、注解等。

  1. foreach和for有什么区别?

foreach循环是用来遍历集合或数组的简化语法,它不需要我们定义一个计数器或索引变量,可以直接遍历每一个元素。而for循环则需要我们手动定义计数器或索引变量,并通过循环来遍历集合或数组。

  1. foreach底层是怎么实现的?

foreach底层是通过迭代器实现的,它会自动调用集合或数组的iterator()方法获取一个迭代器,然后使用迭代器进行遍历。

  1. MySQL的事务有哪些?

MySQL中的事务包括四个基本操作:ACID,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。

  1. MySQL事务中隔离性是怎么实现的?

MySQL中的隔离性是通过锁和MVCC(多版本并发控制)实现的,不同程度的隔离级别使用不同的实现方式。锁实现了串行化执行,而MVCC实现了读写分离,多版本并发控制,可以提高并发性能。

  1. 能讲讲MVCC具体怎么实现事务的隔离性的?

MVCC是MySQL中实现事务隔离性的一种方式,它通过在每行记录中保存多个版本来实现。当进行读操作时,会根据事务启动时的时间戳和版本号来选择符合要求的记录版本,从而实现读操作不会被写操作影响的隔离性。当进行写操作时,会将新版本的记录插入到对应的行中,并将旧版本的记录标记为删除,从而实现更新操作不会影响到其他事务读取旧版本数据的隔离性。

  1. ReadView具体是保存了什么数据?

ReadView是MySQL中实现MVCC的一种机制,它保存了当前事务开始执行时的系统版本号和所有活跃事务的ID列表。在事务执行过程中,ReadView会根据这些信息来判断当前事务是否可见其他事务的修改。

  1. InnoDB存储引擎有什么好处?
InnoDB存储引擎具有以下优点:
- 支持事务和行级锁,可以实现高并发和数据一致性。
- 支持MVCC,可以提高读写性能。
- 支持外键约束,可以保证数据的完整性。
- 支持在线热备份和恢复,可以提高数据可用性。
  1. 如果要查询前1-5条数据,在B+树中是怎么进行查找的?

在B+树中,数据是按照键值大小有序地存储在叶子节点上。如果要查询前1-5条数据,可以先定位到最左边的叶子节点,然后从左往右依次扫描叶子节点,取出前5个数据即可。

  1. MySQL中除了InnoDB以外还有什么存储引擎?

MySQL中还有MyISAM(myisanm)、Memory、CSV等多个存储引擎。

  1. MyISAM与InnoDB的区别,有什么优点?

MyISAM和InnoDB在存储方式、锁机制、事务支持等方面有很大的区别。MyISAM适合于读多写少的场景,不支持事务和行级锁,但是具有快速读取和空间占用小的优点;InnoDB适合于高并发、事务严格要求一致性的场景,支持事务和行级锁,但是具有写入慢、空间占用大的缺点。

  1. MySQL中有什么锁?

MySQL中有共享锁(S锁)、排他锁(X锁)、意向共享锁(IS锁)、意向排他锁(IX锁)等多种锁。

  1. 间隙锁是锁的什么数据?

间隙锁是针对B+树中的间隙(即不存在的数据)进行的锁定,它是InnoDB实现MVCC的一种方式,可以避免幻读的问题。

26、在查看某次查询索引时一般看的什么

在查看某次查询索引时一般要看索引是否被正确地使用,可以通过explain命令查看查询计划、索引类型、扫描行数、是否使用了索引等信息。

27、说一下对分布式锁的理解

分布式锁是在分布式系统中实现锁管理的一种方式,它可以保证在分布式系统中的多个节点同时对共享资源进行操作时,只有一个节点能够获得锁,并且在操作完成之后释放锁,从而保证数据的一致性和正确性。

28、说一下什么是线程池

线程池是一种用于管理和复用线程的机制,它可以在应用程序中预先创建一定数量的线程,并将它们保存在一个线程池中,以便根据需要动态地分配线程来处理任务。

29、线程池怎么创建

创建线程池可以使用Java中的Executors工具类提供的静态方法来创建,例如newFixedThreadPool、newCachedThreadPool等方法。

30、创建线程池时主要设置什么属性

创建线程池时主要要设置线程池的核心线程数、最大线程数、线程空闲时间、任务队列等属性。

31、线程池一般可以用在什么情况下

线程池一般可以用在需要频繁创建和销毁线程的场景,例如高并发的网络服务器、大规模数据处理等。

32、springcloud中 你熟悉什么

在Spring Cloud中,我比较熟悉的是服务注册与发现组件Eureka、配置中心组件Config、负载均衡组件Ribbon、断路器组件Hystrix等。

33、nacos是什么,主要实现什么功能

Nacos是阿里巴巴开源的一个服务注册中心和配置中心,主要实现了服务的注册、发现、配置管理等功能。

34、SpringBoot中 请求进来时mapping是怎么处理的,底层是怎么实现的(如Getmapping是怎么处理请求的)

在Spring Boot中,请求进来时mapping是通过Spring MVC框架来处理的。底层实现是通过反射机制来扫描所有的Controller类和方法,并将它们映射到对应的URL上,当请求进来时,会根据请求的URL和HTTP方法来匹配对应的Controller方法,然后执行该方法,并将返回结果封装成HTTP响应返回给客户端。Getmapping是通过RequestMappingHandlerMapping类的getMappingForMethod方法来处理的,该方法会根据方法上的GetMapping注解和请求的URL来匹配对应的方法。

1、Java吸引你的地方是什么?

支持多线程,可跨平台,面向对象

2、面向对象的重点是什么?

封装、继承、多态、抽象

3、Java是如何实现跨平台的?

通过jvm实现,也有一个叫jmm的内存模型概念,它能实现屏蔽硬件和操作系统的内存访问差异

4、如何实现线程安全?

可以加锁,也可以通过原子操作类,或threadlocal类对需要的数据保证线程安全,也可以使用volatile修饰状态记录变量保证数据安全

5、spring和springboot的区 别?

springboot有自动装配功能,能够更简化开发者的工程量

6、如何注入同一个bean对象?

可以设置bean的作用域为单例模式,并在需要注入这个bean的地方属性设置中注入这个bean

7、你了解的设计模式有哪些?

8、jvm的堆内存有什么内容?

7月22号

面试经典题
  1. 为什么重写 equals 还要重写 hashcode?

答:重写过,首先先了解下hashcode()方法的作用是什么,hashcode()方法用来获取哈希码,实际上就是返回一个int整数。这个哈希码的作用是用来获取对象在哈希表中的位置,hashcode()定义在JDK中的Object类中,因此意味着java中的任何类都包含hashcode()函数。这个哈希表存储着键值对,可以通过键快速检索出对应的值。

我通过hashset来解释hashcode的作用,当我们存对象到hashset中时,hashset会先获取该对象的hashcode值来判断对象的存储位置,同时也会将其与已经加入对象的hashcode值作比较,如果不存在相同的hashcode值,则hashset同意加入该对象。如果存在hashcode值相等的对象,则会使用equals()方法来检查hashcode值相等的对象是否真的相同。如果相同,则hashset不会让加入操作成功,如果不同,则将该对象散列到其他位置。而java中解决这种哈希冲突的方法是链地址法,就是数组中的每个元素为一个桶,这个桶对应一个链表,在java8中链表插入新元素用的是尾插法,但是使用数组和链表的构存在查询时间过长的问题,用数组加链表的话查询时间为链表的长度,也就是O(N),当链表太长的话,查询时间也就变长,为了解决这个问题在java8中规定当链表长度大于8时,使用红黑树存储数据,查询时间为O(lgn),用这种先比较hashcode再用equals的方式大大减少了equals的次数,提高了执行速度。

如果两个对象相等,则hashcode一定相等

如果hashcode相同则用equals方法比较不一定相等

如果用equals比较相等的话,hashcode一定相等。

hashcode不相同则用equals方法比较一定不相等

hashcode用==比较int,equals比较对象地址,要保证相等的对象具有相同的hashcode。

  1. == 和 equals 比较的区别

    答:==如果比较的是基本数据类型的话,那么就是比较这两个数据的值是否相等,如果比较的是两个对象的话,那么比较的是这两个对象的内存地址是否相等。

    ​ equals判断两个对象是否相等,但是他有两种使用情况,第一种就是equals()方法没有被类覆盖,那么比较的是两个对象的内存地址,第二种类覆盖了equals()方法,通常都会使用重写该方法的方式去比较两个对象的值是否相等。

  2. 为啥有时会出现 4.0 - 3.6 = 0.40000001 这种现象?

    这种现象是由于Java中浮点数的精度问题造成的。

    在Java中,浮点数使用IEEE 754标准表示,同样会存在舍入误差。由于计算机使用二进制来表示浮点数,而有些十进制分数在二进制下是无限循环的,因此在转换为二进制表示时就会出现精度损失。

    在你的示例中,4.0和3.6都无法用有限的二进制位数表示,因此在计算时,Java会使用最接近的浮点数来代替这两个数,从而产生舍入误差。这种误差通常很小,对于大多数计算结果的影响不大,但是在某些情况下可能会导致计算结果出现较大误差。

    为了避免浮点数误差问题,可以使用BigDecimal(big dai si mo)类来进行精确计算。BigDecimal类可以精确表示任意精度的十进制数,并且可以进行精确的加减乘除运算。如果需要进行高精度计算,建议使用BigDecimal类。

  3. final 关键字的作用

    答:final关键字一般用来修饰方法,类,变量

    1.用来修饰变量的话有两种情况,当修饰的是基本数据类型的变量,那么该变量的值一旦完成初始化后就不能更改;如果修饰引用类型的变量,那么在完成初始化后,该变量不能指向其他对象。

    2.用来修饰类的话,表明该类不能被继承,且该类中的方法隐式为final方法。

    3.使用final方法有两个原因,第一个就是方法锁定,防止继承类修改该方法的含义;第二个原因是效率问题,在早期的java版本中,会把final方法内嵌调用,如果方法过于庞大,可能也难以看出内嵌调用带来效率的提升,现在的java版本已经不需要使用final方法来实现性能的优化了,类中的所有private方法都隐式的指定为final。

  4. 介绍 Java 的集合类

    Java集合框架包括两个主要接口:Collection和Map。Collection接口表示一组对象,而Map接口表示一组键值对。

    Java集合类的主要分类如下:

    1. List:List是一种有序的集合,可以存储重复的元素。它的实现类包括ArrayList、LinkedList和Vector。
    2. Set:Set是一种不允许重复元素的集合。它的实现类包括HashSet、TreeSet和LinkedHashSet。
    3. Map:Map是一种键值对的映射表。它的实现类包括HashMap、TreeMap和LinkedHashMap。
    4. Queue:Queue是一种先进先出(FIFO)的数据结构,可以使用它来实现排队等待的功能。它的实现类包括LinkedList和PriorityQueue。
    5. Stack:Stack是一种后进先出(LIFO)的数据结构,可以使用它来实现撤销和回退等功能。它的实现类是Stack类本身。
  5. ArrayList 和 LinkedList 的区别

    ArrayList和LinkedList都是Java集合框架中List接口的实现类,它们都可以存储有序的元素,并且支持随机访问和修改元素。但是它们之间的实现方式和性能特点有所不同,下面是它们的主要区别:

    1. 内部实现方式:ArrayList是基于动态数组实现的,而LinkedList是基于双向链表实现的。
    2. 查询操作:对于查询操作,ArrayList比LinkedList更加高效。因为ArrayList可以直接通过索引来访问元素,而LinkedList需要从头节点或者尾节点开始遍历链表。
    3. 插入和删除操作:对于插入和删除操作,LinkedList比ArrayList更加高效。因为LinkedList只需要修改相邻节点的指针,而ArrayList需要移动其他元素的位置。
    4. 内存空间占用:对于相同数量的元素,LinkedList比ArrayList占用更多的内存空间。因为LinkedList需要为每个节点额外分配内存空间来存储指针。
  6. java 8 有哪些新特性?

    Java 8的一些主要新特性:

    1. Lambda表达式:Lambda表达式是一个匿名函数,可以作为参数传递给方法或作为返回值返回。它可以简化代码并提高可读性。
    2. Stream API:Stream API是一种新的数据处理方式,可以对集合和数组进行函数式操作。它提供了丰富的中间操作和终止操作,可以帮助我们快速高效地处理数据。
    3. 方法引用:方法引用是一种简洁的Lambda表达式的替代方式,用于引用已经存在的方法。
    4. 接口的默认方法和静态方法:在Java 8之前,接口只能定义抽象方法。Java 8引入了接口的默认方法和静态方法,使得接口具有更多的灵活性和功能。
    5. 日期和时间API:Java 8引入了新的日期和时间API,可以更方便地处理日期和时间,避免了旧的Date和Calendar类的一些问题。
    6. Optional类:Optional类是一种容器对象,可以包含一个非空的值或者一个空值。它可以避免空指针异常的出现。
  7. HashMap 在 jdk 1.7 和 1.8 的区别?

    在JDK 1.7中,HashMap使用了数组和链表的结合来实现,即当多个键映射到同一个桶时,它们会被存储在同一个链表中。这种实现方式在并发环境下存在安全性问题,需要使用锁来保证线程安全,导致并发性能较差并且查询数据的时间与链表的长度有关即O(n),当链表长度过长,查询效率低。

    在JDK 1.8中,HashMap的实现方式进行了优化,采用了数组和链表的结合来实现,当链表长度超过一定阈值时(默认为8),链表会转换为红黑树,查找的时间父杂度为O(lgn),提高查找效率。此外,JDK 1.8中引入了CAS操作和synchronized锁升级机制,使得HashMap在并发环境下具有更好的性能。

  8. 什么是死锁?死锁产生的条件?

    死锁是指在多线程程序中,两个或多个线程被阻塞,它们在等待相互持有的资源,导致程序无法继续执行下去,形成了一种僵局。

    死锁通常发生在多线程程序中,有两个或多个线程相互持有资源,而它们同时又在等待其它线程持有的资源。这种情况下,程序就会进入死锁状态,不再向前执行。

    死锁产生的条件有以下四个:

    1. 互斥条件:多个进程竞争同一个资源。
    2. 请求与保持条件:指某个进程因为没有获取到资源而阻塞,这个进程不会因此放弃请求该资源,而是保存阻塞状态。
    3. 不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由进程自己释放。
    4. 环路等待条件:指在发生死锁时,必然存在一个进程–资源的环形链。
  9. 线程有哪几种状态?

    线程可以有以下几种状态:

    1. 新建状态(New):当一个线程对象被创建时,它处于新建状态。此时,操作系统已经为该线程分配了资源,但尚未开始执行线程的代码。

    2. 就绪状态(Ready):当线程的 run 方法被调用时,线程进入就绪状态。此时,线程已经准备好执行,但还没有被分配到 CPU 时间片。

    3. 运行状态(Running):当线程被分配到 CPU 时间片后,线程进入运行状态。此时,线程的代码正在 CPU 上执行。

    4. 阻塞状态(Blocked):当线程需要等待某个事件发生时,它可能会进入阻塞状态。例如,线程等待一个锁或者等待一个 IO 操作完成时,它都会进入阻塞状态。在阻塞状态下,线程不会占用 CPU 资源,直到等待的事件发生。

    5. 死亡状态(Dead):当线程完成了它的任务或者发生了未捕获的异常时,线程进入死亡状态。此时,线程不再执行任何代码,并且不再占用任何资源。

      发生了未捕获的异常时—->异常抛出和try-catch-finally

  10. 有哪些进程调度算法?

    操作系统中常见的进程调度算法有以下几种:

    1. 先来先服务调度算法(FCFS):按照进程到达的先后顺序进行调度,先到达的进程先执行,直到该进程执行完毕或者发生阻塞。

    2. 短作业优先调度算法(SJF):按照进程需要运行的时间长短进行调度,需要运行时间短的进程先执行。该算法可以减少平均等待时间和平均周转时间,但是可能会导致长时间运行的进程饥饿。

    3. 优先级调度算法:按照进程的优先级进行调度,优先级高的进程先执行。优先级可以根据进程的重要性、紧急程度等因素进行设置。需要注意的是,该算法可能会导致优先级低的进程长时间等待,产生饥饿问题。

    4. 时间片轮转调度算法:将 CPU 时间划分为固定长度的时间片,每个进程分配一个时间片,进行轮流执行。如果进程在时间片结束前没有执行完毕,那么它会被放到队列的末尾等待下一次调度。该算法可以避免长时间运行的进程饥饿,但是可能会导致进程切换频繁,影响系统性能。

    5. 多级反馈队列调度算法:将进程按照优先级分为多个队列,并且每个队列都有自己的时间片大小。优先级高的进程分配更短的时间片,而优先级低的进程分配更长的时间片。如果一个进程在当前队列中使用完了时间片还没有执行完毕,那么它会被移到下一个队列中等待下一次调度。该算法可以根据进程的特点动态调整时间片大小和优先级,从而提高系统的效率。

      进程饥饿是指某个进程长时间得不到运行的机会,一直处于等待状态,无法执行其任务的现象。进程饥饿可能会导致系统出现性能问题,甚至使系统崩溃。

  11. 什么是缓冲区溢出?

    缓冲区溢出是指程序试图向缓冲区写入超出其容量的数据,导致数据溢出到相邻的内存区域,从而覆盖相邻内存区域的数据,甚至修改程序的执行流程,从而导致程序崩溃或者被攻击者利用。

    为了避免缓冲区溢出,可以采用以下措施:

    1. 使用 Java 提供的安全函数,例如 StringBuffer、StringBuilder 等,以避免缓冲区溢出。
    2. 对输入的数据进行检查和过滤,限制输入数据的长度。
    3. 使用 Java 提供的安全库函数,例如 Arrays.copyOf、Arrays.copyOfRange 等,避免数组越界访问等问题。

    Arrays.copyOf,Arrays.copyOfRange 可以用于数组的扩容

  12. 计算机网络各层有哪些协议?

    1. 物理层:定义了物理介质和数据传输的电气、机械、功能和规程,常见的协议有:Ethernet、Fast Ethernet、Gigabit Ethernet 等。
    2. 数据链路层:提供了数据传输的逻辑连接和物理地址寻址,常见的协议有:ARP、RARP、PPP、HDLC、IEEE 802.3、IEEE 802.11 等。
    3. 网络层:负责数据包的路由和转发,常见的协议有:IP、IPX、RIP、OSPF、BGP、ICMP、IGMP 等。
    4. 传输层:提供端到端的可靠数据传输服务,常见的协议有:TCP、UDP、SPX 等。
    5. 会话层:提供了进程之间的会话控制和同步,常见的协议有:RPC、NFS、SQL 等。
    6. 表示层:提供了数据的格式化和加密,常见的协议有:ASCII、EBCDIC、JPEG、MPEG、SSL 等。
    7. 应用层:提供了各种应用程序的服务,常见的协议有:HTTP、FTP、SMTP、DNS、Telnet、SSH 等。
  13. TCP 和 UDP 协议的区别?

    TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是网络传输层常见的两种协议,它们有以下几个方面的不同:

    1. 连接方面:TCP 是面向连接的协议,UDP 是无连接的协议。TCP 在数据传输前需要先建立连接,而 UDP 不需要建立连接,直接发送数据报文。
    2. 可靠性方面:TCP 提供可靠的数据传输,UDP 不保证数据传输的可靠性。TCP 在传输数据时会进行校验和错误检测,如果发现数据包有错误,会要求重新发送。而 UDP 不会进行重新发送,如果数据包丢失或者错误,就会丢失这些数据。
    3. 传输速度方面:UDP 传输速度比 TCP 更快。因为 TCP 需要进行连接的建立、数据包的确认等复杂操作,会造成一定的传输延迟,而 UDP 直接发送数据包,没有这些额外的操作,传输速度相对较快。
    4. 数据量方面:TCP 可以传输大量的数据,而 UDP 只适合传输少量的数据。因为 TCP 在传输数据时需要进行分段、重组等操作,对于大量数据的传输比较适合,而 UDP 直接发送数据包,对于数据量较小的传输比较适合。
    5. 流量控制方面:TCP 可以进行流量控制,而 UDP 不能进行流量控制。TCP 可以通过拥塞控制等机制来控制数据的传输速度,避免网络拥塞,而 UDP 没有这些机制。
  14. TCP 为什么需要三次握手和四次挥手?

    TCP协议是一种可靠的传输协议,主要是通过三次握手和四次挥手来保证数据的可靠传输和连接的正常关闭。以下是对于TCP三次握手和四次挥手的详细解释。

    三次握手:

    1.第一次握手:客户端向服务器发送一个SYN标志的数据包,请求建立连接,此时客户端进入SYN_SEND状态。
    2.第二次握手:服务器收到客户端的SYN数据包后,向客户端发送一个SYN/ACK标志的数据包,表示同意建立连接,此时服务器进入SYN_RECV状态。
    3.第三次握手:客户端收到服务器的SYN/ACK数据包后,向服务器发送一个ACK标志的数据包,表示确认连接请求,此时客户端进入ESTABLISHED状态,服务器也进入ESTABLISHED状态,连接建立成功。

    在三次握手过程中,可以保证双方的状态都是同步的,并且可以防止因网络延迟等原因导致的重复连接请求。

    四次挥手:

    1.第一次挥手:客户端向服务器发送一个FIN标志的数据包,表示要关闭连接,此时客户端进入FIN_WAIT_1状态。
    2.第二次挥手:服务器收到客户端的FIN数据包后,向客户端发送一个ACK标志的数据包,表示确认关闭连接,此时服务器进入CLOSE_WAIT状态。
    3.第三次挥手:服务器向客户端发送一个FIN标志的数据包,表示服务器也要关闭连接,此时服务器进入LAST_ACK状态。
    4.第四次挥手:客户端收到服务器的FIN数据包后,向服务器发送一个ACK标志的数据包,表示确认关闭连接,此时客户端进入TIME_WAIT状态,等待2MSL后进入CLOSED状态,服务器也进入CLOSED状态。

    在四次挥手过程中,可以保证双方都能正常关闭连接,并且可以确保数据的完整性,避免数据丢失或重复传输。

  15. HTTP 和 HTTPS 协议的区别?

    HTTP和HTTPS协议是互联网上常用的两种协议,它们之间的主要区别在于安全性和数据传输方式。以下是HTTP和HTTPS协议的区别:

    1. 数据传输方式:
      HTTP协议是明文传输,数据传输过程中不进行加密,容易被窃听和篡改;而HTTPS协议通过使用SSL/TLS协议对数据进行加密和解密,保证数据传输的安全性。
    2. 端口号:
      HTTP协议默认使用80端口进行数据传输,而HTTPS协议默认使用443端口进行数据传输。
    3. 证书验证:
      HTTPS协议需要使用数字证书来进行身份验证,确保通信双方的身份和数据的完整性。HTTP协议没有这种机制,很容易被伪造。
    4. 连接速度:
      HTTPS协议因为需要进行加密和解密,会增加数据传输的时间和连接的建立时间,因此连接速度较HTTP协议慢。
    5. 缓存:
      由于HTTPS协议的加密和解密过程,数据无法在中间节点进行缓存,因此缓存效率较HTTP协议低。
  16. MySQL 索引的最左原则

    MySQL索引的最左前缀原则是指在使用多列组成的联合索引时,使用索引进行查询时必须从索引的最左边列开始使用,不能跳过索引中的任何一个列,这样才能保证索引的有效性。例如,如果有一个联合索引(a, b, c),那么当查询条件包含a和b时,可以使用该联合索引进行查询;但是,如果查询条件只包含b和c,那么该联合索引就无法使用。

  17. InnoDB 和 MyIsam 引擎的区别?

    InnoDB和MyISAM是MySQL常用的两种存储引擎,它们在内部实现和特性上有很大的差异。以下是它们之间的一些区别:

    1. 数据存储方式

    MyISAM使用表级锁来实现对表的并发访问,而InnoDB使用行级锁,可以实现更细粒度的并发控制。这意味着在高并发读写的场景下,InnoDB的性能更好。

    1. 事务支持

    InnoDB支持ACID事务,而MyISAM不支持事务。如果需要使用事务来保证数据的一致性和完整性,应该选择InnoDB。

    1. 外键支持

    InnoDB支持外键,MyISAM不支持外键,如果需要使用外键来保证数据的完整性和一致性,应该选择InnoDB。

    1. 索引方式

    MyISAM使用B树索引,而InnoDB使用B+树索引。B+树索引相对于B树索引有更好的查询性能和更低的存储空间需求。

    1. 查询性能

    由于InnoDB支持行级锁和事务,因此它在高并发读写的场景下具有更好的查询性能和更高的并发控制能力。而MyISAM在读密集型场景下具有更好的查询性能。

  18. 有哪些优化数据库性能的方法?

    以下是优化数据库性能的一些方法:

    1. 使用索引:合理地创建索引可以提高查询效率,减少查询时间和资源消耗。但是需要注意的是,过多的索引会增加额外的存储空间和维护成本,而且可能会导致索引的失效,降低查询效率。
    2. 优化SQL语句:优化SQL语句可以减少查询时间和资源消耗。例如,尽量使用简单的SQL语句、避免使用SELECT *、尽量使用WHERE子句限制查询范围等。
    3. 使用缓存:使用缓存可以减少数据库的访问次数,提高访问速度和性能。例如,使用Redis等缓存系统缓存查询结果,避免重复查询数据库。
    4. 数据库分库分表:当数据量过大时,可以将数据分为多个库或多个表,以减少单个数据库的负载和提高查询效率。
    5. 优化数据库服务器:优化数据库服务器可以提高数据库的性能和稳定性。例如,增加内存、优化磁盘、调整数据库参数等。
    6. 使用连接池:使用连接池可以避免频繁地创建和关闭数据库连接,提高连接复用率和性能。
    7. 优化数据模型:优化数据模型可以提高数据的查询效率和性能。例如,避免使用过多的关联表、避免使用过多的冗余数据等。
  19. 如何定位慢查询?

    在Java应用程序中,慢查询通常是指执行时间较长的SQL查询语句或者方法调用。定位慢查询可以通过以下几个步骤来实现:

    1. 确定阈值:首先需要确定一个合理的执行时间阈值来定义什么是慢查询。可以根据系统的响应时间和资源利用率等因素来决定阈值。通常来说,执行时间超过1秒的查询可以被视为慢查询。
    2. 监控系统:使用监控工具对系统进行监控,收集SQL查询的执行时间、访问频率、资源利用率等信息。常用的监控工具包括JMX、JProfiler、Java Melody等。
    3. 定位慢查询:通过监控工具收集的信息,可以定位到慢查询的具体SQL语句或者方法调用。可以使用数据库的慢查询日志或者ORM框架的日志来收集SQL语句的执行时间和执行计划等信息。同时还可以使用性能分析工具来分析方法调用的性能瓶颈。
    4. 优化查询:定位到慢查询后,可以根据具体情况进行优化。例如,可以通过添加索引、优化SQL语句、减少网络传输等方式来提高查询性能。同时还可以使用缓存等技术来减少对数据库的访问次数,提高系统性能。
  20. MySQL 支持行锁还是表锁?分别有哪些优缺点?

    MySQL 支持行锁和表锁两种锁机制。

    表锁是在对整张表进行加锁,当一个事务对表进行更新时,其他事务无法对该表进行任何修改操作,直到该事务结束。表锁的优点是加锁简单、资源消耗少,缺点是并发性能较差,因为锁的粒度太大,容易造成大量的阻塞和锁等待。

    行锁是在对表中的行加锁,当一个事务对某行进行更新时,其他事务仍然可以对其他行进行修改操作,不会造成整张表的锁定。行锁的优点是并发性能较好,因为锁的粒度比较细,可以减少锁等待时间和阻塞的情况,缺点是加锁的成本比表锁高,因为需要对每一行进行加锁。

    在实际应用中,行锁和表锁的选择取决于具体的业务需求和并发访问情况。如果应用场景中并发访问比较高,建议使用行锁来提高并发性能。如果并发访问比较低,或者需要对整张表进行更新操作,可以使用表锁来简化锁的管理和消耗。

  21. Spring 的 IOC 和 AOP 是什么,有哪些优点?

    Spring的IOC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的两个核心概念。

    IOC是指将对象的创建、依赖注入等工作交由Spring容器来完成,即控制反转,将原本由程序员手动创建和管理对象的过程交由Spring框架来完成。这样可以降低程序员的开发难度,提高代码的可重用性和可维护性。

    AOP是指将系统中的横切关注点进行抽象和封装,从而实现系统关注点的分离,即面向切面编程。通过AOP技术,可以将系统中的横切关注点(如日志记录、安全控制、性能统计等)从业务逻辑中剥离出来,在需要时进行动态织入,从而提高代码的可维护性和可重用性。

    Spring的IOC和AOP的优点包括:

    1. 降低了系统的复杂度和耦合度,使得代码更加清晰,易于维护和升级。
    2. 提高了代码的可重用性和可扩展性,使得程序员可以更加专注于业务逻辑的编写,而不必关注框架底层的实现细节。
    3. 提高了系统的可测试性,使得开发人员可以更加方便地进行单元测试和集成测试。
    4. 提高了系统的性能和可靠性,使得系统更加稳定、安全和高效。
    5. 增加了代码的可读性和可维护性,使得开发人员可以更加方便地理解和修改代码。
  22. Spring 框架用到了哪些设计模式?

    Spring框架使用了多种设计模式,下面列举几个常用的设计模式:

    1. IOC容器使用了工厂模式和单例模式。Spring的IOC容器使用工厂模式来创建对象,并且默认情况下使用单例模式来管理对象,从而实现对象的统一管理和复用。
    2. AOP使用了代理模式。Spring的AOP功能主要是基于代理模式实现的,通过动态代理技术来实现横切关注点的统一管理。
    3. MVC使用了前端控制器模式和模板模式。Spring的MVC框架采用前端控制器模式来处理请求,同时采用模板模式来实现视图层的实现。
    4. 事务管理使用了模板方法模式。Spring的事务管理采用模板方法模式,将事务管理的流程抽象成模板方法,让子类实现具体的业务逻辑,从而实现事务管理的统一管理和复用。
    5. 依赖注入使用了依赖注入模式。Spring的依赖注入功能主要是基于依赖注入模式实现的,通过将对象之间的依赖关系交由IOC容器来管理,从而实现对象的解耦和依赖关系的管理。
  23. 介绍 Spring Bean 的生命周期

  24. MyBatis 如何实现延迟加载?

  25. 介绍 MyBatis 的多级缓存机制

  26. 如何解决提交冲突?

  27. 提交不小心出现误操作,如何撤销?

  28. 什么是 Git Flow,它有什么好处?

  29. 如何查看某个进程的运行状态?

  30. 如何在 Linux 上查看 2 G 的大文件?

  31. Linux 软链接和硬链接的区别

  32. 单例模式有哪些实现方式?有哪些优缺点?请手写其中一种

  33. 你用过哪些设计模式,为什么用它?

  34. Redis 为什么快?

  35. Redis 有哪些常用的数据结构?

  36. Redis RDB 和 AOF 持久化的区别,如何选择?

  37. 如何解决缓存击穿、缓存穿透、雪崩问题?

  38. 如何用 Redis 实现点赞功能,怎么设计 Key / Value?

  39. 使用消息队列有哪些优缺点?

  40. 如何保证消息消费的幂等性?

  41. 消息队列有哪些路由模型?

  42. 你是否用过消息队列,解决过什么问题?

  43. Nginx 有哪些作用?

  44. Nginx 为什么支持高并发?

  45. Nginx 有哪些负载均衡策略?

  46. 什么是 Nginx 惊群问题,如何解决它?

  47. Netty 有哪些优点?

  48. 什么是 NIO?

  49. 介绍 Netty 的零拷贝机制

  50. 什么是微服务,有哪些优缺点?

  51. 什么是注册中心,能解决什么问题?

  52. 什么是容器?

  53. 使用 Docker 有哪些好处?

  54. 如何快速启动多个 Docker 节点?

Java8新特性详解

好的,下面是一些具体的代码示例,演示Java 8的一些新特性:

  1. Lambda表达式:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 使用Lambda表达式对集合进行遍历和操作
names.forEach(name -> System.out.println("Hello, " + name));

// 使用Lambda表达式对集合进行过滤和统计
long count = names.stream().filter(name -> name.startsWith("A")).count();
System.out.println("The number of names starting with 'A' is: " + count);

names.stream().filter()含义
    
names.stream().filter()Java 8Stream API提供的一种数据处理方式,用于对集合中的元素进行筛选和过滤。
  1. Stream API:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 使用Stream API对集合进行操作
int sum = numbers.stream().filter(n -> n % 2 == 0).mapToInt(Integer::intValue).sum();
System.out.println("The sum of even numbers is: " + sum);

::含义

::Java 8中方法引用的操作符,可以用来引用类的静态方法、对象的实例方法和构造方法。
  1. 方法引用:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 使用方法引用对集合进行排序
names.sort(String::compareToIgnoreCase);
  1. 接口的默认方法和静态方法:
interface Greeting {
    void sayHello();

    default void sayHi() {
        System.out.println("Hi!");
    }

    static void sayBye() {
        System.out.println("Bye!");
    }
}

class GreetingImpl implements Greeting {
    public void sayHello() {
        System.out.println("Hello!");
    }
}

// 使用接口的默认方法和静态方法
Greeting greeting = new GreetingImpl();
greeting.sayHello();
greeting.sayHi();
Greeting.sayBye();
  1. 日期和时间API:
// 使用新的日期和时间API
LocalDate today = LocalDate.now();
System.out.println("Today's date is: " + today);

LocalDateTime now = LocalDateTime.now();
System.out.println("Current date and time is: " + now);

LocalDateTime christmas = LocalDateTime.of(2023, Month.DECEMBER, 25, 0, 0);
System.out.println("Christmas is on: " + christmas);

以上这些代码示例演示了Java 8的一些新特性,包括Lambda表达式、Stream API、方法引用、接口的默认方法和静态方法、日期和时间API等。这些新特性可以使得Java的代码更加简洁、易读、高效。

异常处理详解

异常抛出(throw)和 try-catch-finally是 Java 中用于处理异常的两种机制。

异常抛出指的是在程序执行过程中,当发生异常时,可以使用 throw 语句将异常对象抛出,从而将异常传递给上层调用者。

try-catch-finally

  1. try 块中包含可能会抛出异常的代码。
  2. catch 块用于捕获和处理 try 块中抛出的异常。catch 块中的代码会根据抛出的异常类型进行匹配,如果匹配成功,则执行 catch 块中的代码;否则,程序将会继续抛出异常。
  3. finally 块中的代码无论是否抛出异常都会被执行。finally 块通常用于释放资源、关闭连接等操作。

在 Java 中,try-catchtry-finally 是两种不同的异常处理机制,它们之间是可以单独使用的,也可以组合使用。

如果我们只想捕获异常并进行处理,而不需要在 finally 块中执行任何代码,那么可以省略 finally 块。例如:

try {
    // 可能会抛出异常的代码
} catch (Exception e) {
    // 处理异常
}

如果我们只需要在 finally 块中执行必须被执行的代码,而不需要捕获和处理异常,那么可以省略 catch 块。例如:

try {
    // 可能会抛出异常的代码
} finally {
    // 必须被执行的代码
}

需要注意的是,如果 try 块中的代码抛出了异常,并且没有被 catch 块捕获和处理,那么该异常将会被抛出给上层调用者处理,可能会导致程序崩溃。因此,建议在编写 try-finally 代码时,至少加入一个 catch 块来捕获和处理异常。

MySQL 索引的最左原则详解

创建索引是SQL优化的一种常见手段,可以通过创建合适的索引来提高查询效率和性能。

以下是一个使用MySQL联合索引并遵循最左前缀原则的查询示例代码:

假设有一个名为users的表,其中包含三个列:id、name和age。为了提高查询效率,我们可以创建一个联合索引(name, age),代码如下:

CREATE INDEX idx_users_name_age ON users(name, age);

现在,我们想要查询所有名字为"Tom"且年龄为30岁的用户,我们可以使用以下SQL语句进行查询:

SELECT * FROM users WHERE name = 'Tom' AND age = 30;

由于查询条件是从索引的最左边开始的,而且查询条件涵盖了索引的所有列,因此MySQL可以使用联合索引进行查询,提高查询效率。

另外,如果我们只查询名字为"Tom"的用户,那么也可以使用该联合索引进行查询,因为查询条件包含了索引的最左列,示例代码如下:

SELECT * FROM users WHERE name = 'Tom';

而如果我们只查询年龄为30岁的用户,那么该联合索引就无法使用,因为查询条件没有涵盖索引的最左列,需要进行全表扫描,示例代码如下:

SELECT * FROM users WHERE age = 30;

综上所述,最左前缀原则可以提高MySQL索引的查询效率,因此在设计和使用索引时需要遵循这个原则。

当创建了索引时

当执行以下查询语句时:

SELECT * FROM users WHERE name = 'Tom' AND age = 30;

如果users表上创建了(name, age)联合索引,并且该索引已经被MySQL选择使用,那么MySQL会按照以下步骤进行查询:

  1. MySQL会根据(name, age)联合索引中的name列进行查找,找到所有name为’Tom’的行。
  2. 对于找到的所有行,MySQL会继续根据(age)索引中的age列进行过滤,只保留age=30的行。
  3. 对于符合条件的行,MySQL会到原始数据表中获取所有相关的列数据,即使用"SELECT *"语句获取所有列的值。

**由于联合索引中的列顺序是按照(name, age)的顺序进行排序的,因此MySQL必须先使用name列进行查找,然后才能使用age列进行过滤。**这样可以最大化地利用索引,提高查询效率。

没创建索引

当执行以下查询语句时:

SELECT * FROM users WHERE name = 'Tom' AND age = 30;

如果users表上没有创建(name, age)联合索引,MySQL就无法利用索引进行查询,需要进行全表扫描,即按顺序扫描users表中的每一行,逐行判断是否满足查询条件。具体的执行过程如下:

  1. MySQL会从users表的第一行开始扫描,获取该行的name和age列的值。
  2. 对于获取的每一行,MySQL会判断name是否为’Tom’,并且判断age是否为30。
  3. 如果该行满足条件,MySQL会将该行的所有列的值都返回给客户端。
  4. 如果该行不满足条件,MySQL会继续扫描下一行,重复上述步骤。
  5. 如果扫描到表的末尾仍没有找到符合条件的行,MySQL会返回空结果集。

由于该查询没有使用索引,MySQL需要扫描整个users表,无法利用索引的优势,因此查询效率较低。在实际应用中,如果需要频繁进行类似的查询,可以考虑在name和age列上创建联合索引,以提高查询效率。

spring

  1. 什么是Spring框架?

    • Spring框架是一个开源的Java应用开发框架,提供了一种轻量级的编程和配置模型,用于构建企业级应用程序。它提供了依赖注入(DI)、面向切面编程(AOP)、事务管理、Web开发支持等功能。
  2. Spring框架的 核心特点是什么?

    • Spring框架的核心特点包括:
      • 松耦合:通过依赖注入和面向接口编程,实现了组件之间的松耦合。
      • 面向切面编程:提供了面向切面编程的支持,用于处理横切关注点。
      • 容器管理:提供了一个容器(Application Context)用于管理和配置应用程序中的组件和对象。
      • 组件重用:通过配置和注解,实现了组件的重用和模块化。
      • 统一的异常处理:提供了统一的异常处理机制,方便开发者处理异常情况。
  3. Spring的核心模块有哪些?

    • Spring的核心模块包括:
      • Spring Core:提供了依赖注入和控制反转的功能,是整个Spring框架的核心。
      • Spring AOP:提供了面向切面编程的支持。
      • Spring JDBC:提供了对JDBC的简化封装和易用性。
      • Spring ORM:提供了对各种ORM框架(如Hibernate、MyBatis)的集成支持。
      • Spring Web:提供了对Web应用程序的开发支持,包括MVC框架、RESTful Web服务等。
  4. 什么是依赖注入(DI)?

    • 依赖注入是Spring框架的核心特性之一,它是一种通过容器自动将依赖关系注入到对象中的机制。开发者不需要手动创建和管理对象,而是通过配置或注解的方式,由Spring容器负责创建和维护对象的依赖关系。
  5. Spring中的Bean是什么?

    • 在Spring中,Bean是由Spring容器管理的对象。Bean可以是应用程序中的任何一个对象,通过配置或注解告知Spring容器如何创建、初始化和管理该对象。
  6. Spring框架中的AOP是什么?

    • AOP(Aspect-Oriented Programming)是一种编程范式,用于处理横切关注点。在Spring框架中,AOP通过将横切关注点(如事务管理、日志记录)从业务逻辑中分离出来,并将其模块化,提供了更好的代码重用性和可维护性。
  7. Spring的事务管理是如何实现的?

    • Spring提供了声明式的事务管理机制,通过配置和注解的方式实现事务管理。开发者可以通过在方法或类上添加事务相关的注解,告知Spring容器如何管理事务。Spring使用AOP和底层事务管理器(如JDBC事务、JTA事务)来实现事务管理。
  8. Spring MVC是什么?它的作用是什么?

    • Spring MVC是Spring框架中的一个Web开发模块,用于构建基于MVC模式的Web应用程序。它提供了一组组件和功能,用于处理HTTP请求、请求路由、视图解析、数据绑定等。Spring MVC的作用是简化Web应用程序的开发过程,实现灵活的请求处理和响应生成。
  9. Spring框架中的国际化支持是什么?

    • Spring提供了国际化(i18n)和本地化(l10n)的支持。通过Spring的国际化支持,开发者可以在应用程序中实现多语言支持,根据用户的语言偏好提供不同的语言资源和消息。
  10. Spring Boot和Spring框架有什么区别?

    • Spring框架是一个用于构建企业级应用程序的开发框架,提供了一系列的模块和功能。而Spring Boot是基于Spring框架的一个快速开发框架,旨在简化Spring应用程序的初始配置和部署。Spring Boot提供了自动配置、开箱即用的特性,使得开发者可以更快地搭建和部署Spring应用程序。

springMVC

它是一个基于Java的实现的MVC设计模式的请求驱动类型的轻量级web框架。它主要用于处理Web层的请求,并将业务逻辑、数据和视图进行分离,实现各个组件之间的解耦,从而提高代码的可读性和可维护性。

具体来说,Spring MVC的核心结构由模型(Model)、视图(View)和控制器(Controller)三部分组成。模型负责处理业务逻辑和数据,视图用于呈现数据给用户,而控制器则负责处理用户请求并返回相应的视图。

工作原理通常是用户的请求先到达控制器,控制器根据请求的信息调用相应的模型进行处理,模型处理完成后将结果返回给控制器,然后控制器根据模型返回的结果调用相应的视图生成用户可见的页面。

Spring MVC的优点包括:

  1. 低分层设计:Spring MVC将应用程序分为不同的层次,包括数据访问层、业务逻辑层、控制层和视图层,提高了代码的模块化程度,便于维护和测试。

  2. 轻量级:Spring MVC是一个轻量级的框架,使用灵活,没有过多的约束,可以自由选择适合自己的技术。

  3. 强大的注解支持:Spring MVC提供了丰富的注解来简化配置,例如@RequestMapping@RequestParam等,使开发人员能够更专注于业务逻辑的实现。

  4. 与Spring框架的集成:Spring MVC可以与Spring框架的其他组件无缝集成,例如Spring Security用于实现安全性控制,Spring Data JPA用于简化数据库操作等。

总之,Spring MVC是一款优秀的Java Web框架,它采用了MVC设计模式,简化了外部开发的工作流程,提高了代码的可读性和可维护性,同时提供了丰富的注解支持,使开发人员能够更专注于业务逻辑的实现。

springboot

Springboot是spring的子项目,称为一站式解决方案,集成了外部很多的优秀的框架,如常用的mysql、jdbc,Spring Boot旨在简化Spring应用程序的开发和部署。

主要优点:

  • 通过maven导入各种jar包,可以减少jar包的冲突;
  • 屏息了繁琐的xml配置文件;
  • 集成的开发框架,可以做到开箱即用

主要缺点:

  • 学习曲线陡峭
开箱即用—>在初始的状态下即可使用,无需额外的配置或自定义设置。

一站式解决方案—>一站式解决方案在许多领域中都有应用,如云计算、企业资源规划(ERP)、客户关系管理(CRM)等。它们旨在简化复杂性,提高效率,并为用户提供一个一站式的平台来满足他们的需求。

什么是 Spring Boot?

多年来,随着新功能的增加,spring 变得越来越复杂。只需访问 https://spring.io/projects

页面,我们就会看到可以在我们的应用程序中使用的所有 Spring 项目的不同功能。如果必

须启动一个新的 Spring 项目,我们必须添加构建路径或添加 Maven 依赖关系,配置应用程

序服务器,添加 spring 配置。因此,开始一个新的 spring 项目需要很多努力,因为我们现

在必须从头开始做所有事情。

Spring Boot 是解决这个问题的方法。Spring Boot 已经建立在现有 spring 框架之上。使用

spring 启动,我们避免了之前我们必须做的所有样板代码和配置。因此,Spring Boot 可以

帮助我们以最少的工作量,更加健壮地使用现有的 Spring 功能。

Spring Boot 有哪些优缺点?

Spring Boot 的优点有:

  • 减少开发,测试时间和努力。
  • 使用 JavaConfig 有助于避免使用 XML。
  • 避免大量的 Maven 导入和各种版本冲突。
  • 提供意见发展方法。通过提供默认值快速开始开发。
  • 没有单独的 Web 服务器需要。这意味着你不再需要启动 Tomcat,Glassfish 或其他任何东西。
  • 需要更少的配置 因为没有 web.xml 文件。只需添加用@ Configuration 注释的类,然后添加用@Bean 注释的方法,Spring 将自动加载对象并像以前一样对其进行管理。您甚至可以将@Autowired 添加到 bean 方法中,以使 Spring 自动装入需要的依赖关系中。
  • 基于环境的配置使用这些属性,您可以将您正在使用的环境传递到应用程序:-Dspring.profiles.active = {enviornment}。在加载主应用程序属性文件后,Spring 将在(application{environment} .properties)中加载后续的应用程序属性文件。

Spring Boot 的缺点有:

  1. 什么是Spring Boot?
    • Spring Boot是一个开源的Java框架,用于快速创建和部署独立的、生产级别的Spring应用程序。
  2. 它的主要优点是什么?
    • 通过maven导入各种jar包,可以减少jar包的冲突;
    • 屏息了繁琐的xml配置文件;
    • 集成的开发框架,可以做到开箱即用
  3. Spring Boot和Spring框架之间的关系是什么?
    • Spring Boot是构建在Spring框架之上的,它简化了Spring应用程序的开发和部署。
    • Spring Boot利用Spring框架的核心功能,并提供了额外的自动化配置和便利的特性。
  4. Spring Boot利用Spring框架的核心功能IOC和AOP。
    • ioc为了解决对象管理和对象依赖的问题。本来要手动new出来的对象,现在交给spring的ioc容器进行管理,ioc容器可以理解为一个对象工厂,我们把对象交给工厂处理,工厂管理对象的创建以及依赖关系,当我们需要使用对象的时候从工厂获取即可。
    • 控制反转是一种思想,依赖注入是实现的方式。依赖注入有三种实现方式,分别是构造函数注入,setter方法注入,字段注入,字段注入要使用@Autowired注解进行标记。
    • ioc好处就是方便对对象进行集中管理和解耦合,提高代码的可复用性,以及降低开发成本,减少基础代码的编写和维护。如果你自己new对象的话,那什这个对象还得你自己去管理,甚至自己还得去创建工厂,但这些也是spring提供了的,并且spring还有一套完整的生命周期管理,直接拿来用即可。
    • spring aop 是非业务代码抽取,他的底层是动态代理,在spring中实现的依赖是BeanPostProcessor,如果我们需要在某个上下文中插入一些重复性的非业务代码,那就可以使用spring aop。
    • 代理模式,好处出就是解耦,方便业务的拓展,把公共业务交给代理角色,做好业务的分工。静态代理和动态代理,静态代理可以理解为租客去找专门的中介去租房,但是会存在一个问题,每个租客去租房的时候要找自己想要的那个房子的中介,也就是说每次都要创建代理类,造成代码冗余,而动态代理很好的解决了这个问题,动态代理在运行时生成代理对象。
  5. 如何创建一个Spring Boot应用程序?请简要描述创建一个简单的Spring Boot应用程序的步骤。
    • 创建一个新的Maven或Gradle项目。
    • 添加Spring Boot的起步依赖。
    • 创建一个主应用程序类,并使用@SpringBootApplication注解进行标记。
    • 编写业务逻辑和处理程序。
    • 使用构建工具(Maven或Gradle)构建和运行应用程序。
  6. Spring Boot的自动配置是如何工作的?它是如何简化开发过程的?
    • Spring Boot通过扫描类路径和配置文件中的依赖关系,自动配置应用程序的各个部分。
    • 自动配置基于条件化,根据应用程序的类路径和配置属性决定启用哪些功能。
    • 自动配置大大减少了开发人员需要手动配置的工作量,简化了应用程序的搭建和部署过程。
  7. 如何在Spring Boot应用程序中配置数据库连接?
    • application.propertiesapplication.yml文件中配置数据库连接属性,如数据库URL、用户名和密码。
    • 使用Spring Boot提供的数据源自动配置,例如spring-boot-starter-data-jpaspring-boot-starter-data-mongodb等。
  8. Spring Boot中的"Starter"是什么?它们的作用是什么?
    • "Starter"是一组预配置的依赖项,用于简化特定功能的集成。
    • Starter提供了所需的依赖项和自动配置,以便快速启动和使用特定的技术栈或功能。
  9. 如何在Spring Boot应用程序中处理跨域请求?
    • 在主应用程序类上使用@CrossOrigin注解或使用全局配置WebMvcConfigurer来处理跨域请求。
  10. 如何在Spring Boot中实现日志记录?
  • Spring Boot默认使用Logback作为日志记录框架。
  • 通过在application.propertiesapplication.yml中配置日志级别和输出格式,可以自定义日志记录行为。
  1. Spring Boot中的Actuator是什么?它提供了哪些功能?

    • Actuator是Spring Boot的一个扩展模块,提供了监控和管理应用程序的功能。
    • 它可以提供应用程序的健康状况、性能指标、配置信息等,还可以暴露端点用于远程管理和监控。
  2. 如何在Spring Boot应用程序中进行单元测试?

    • 使用JUnit等测试框架编写测试类。
    • 使用Spring Boot的测试注解,如@SpringBootTest@MockBean等。
    • 使用MockMvc或TestRestTemplate进行集成测试。
  3. Spring Boot的优点是什么?它在开发中的实际应用场景是什么?

    • Spring Boot简化了Spring应用程序的开发、配置和部署。
    • 它提供了自动配置、起步依赖、快速开发和可扩展性等特性。
    • Spring Boot适用于构建各种类型的应用程序,包括Web应用、微服务、RESTful API等。
  4. 如何处理Spring Boot应用程序的异常和错误?

    • 使用Spring的异常处理机制,例如@ControllerAdvice@ExceptionHandler
    • 自定义异常类并创建适当的异常处理程序。
    • 使用Spring Boot提供的错误处理机制来处理未捕获的异常和错误。
  5. SpringBoot启动时,配置文件的运行顺序。

    1. application.properties/application.yml:这是默认的配置文件,位于classpath的根目录下。它包含了应用程序的通用配置。
    2. application-{profile}.properties/application-{profile}.yml:这些是针对特定配置文件的配置文件,其中{profile}是激活的配置文件的名称。例如,如果激活了"dev"配置文件,那么Spring Boot将加载application-dev.properties或application-dev.yml。
    3. 在Spring Boot中,可以使用spring.config.namespring.config.location属性来指定其他的配置文件名称和位置。spring.config.name用于指定配置文件的基本名称(不包括文件扩展名),spring.config.location用于指定配置文件的位置。如果指定了spring.config.location,Spring Boot将只加载指定位置的配置文件,并忽略默认的配置文件。
    4. 配置文件的加载顺序是按照上述规则从上到下的顺序进行的。在加载过程中,后面加载的配置文件会覆盖前面加载的配置文件中的相同属性。

springcloud

  1. 什么是Spring Cloud?
    • Spring Cloud是一个用于构建分布式系统和微服务架构的开发工具集合。它提供了一系列开箱即用的模块和组件,用于解决微服务架构中的常见问题,如服务发现、服务调用、负载均衡、配置管理等。
  2. Spring Cloud和Spring Boot之间的关系是什么?
    • Spring Boot是用于快速创建和部署独立的Spring应用程序的框架,而Spring Cloud是构建在Spring Boot之上的,用于开发分布式系统和微服务的工具集合。Spring Boot简化了Spring应用程序的开发和部署,而Spring Cloud提供了更多的分布式系统的功能和支持。
  3. 什么是服务注册和发现?Spring Cloud中如何实现服务注册和发现?
    • 服务注册和发现是指将各个微服务实例注册到服务注册中心,并通过服务注册中心来发现和获取服务实例的过程。Spring Cloud中,常用的服务注册和发现组件是Netflix Eureka和Consul。服务提供者通过向服务注册中心注册自己的信息,而服务消费者则通过查询服务注册中心获取可用的服务实例列表。
  4. 什么是服务调用和负载均衡?Spring Cloud中如何实现服务调用和负载均衡?
    • 服务调用是指在微服务架构中,一个服务通过网络调用另一个服务提供的接口或方法。负载均衡是指将请求分发到多个服务实例上,以实现请求的均衡分配和高可用性。Spring Cloud中,常用的服务调用和负载均衡组件是Netflix Ribbon和OpenFeign。它们提供了客户端负载均衡的能力,可以根据配置和算法选择合适的服务实例来进行请求。
  5. 什么是配置中心?Spring Cloud中如何实现配置中心?
    • 配置中心是用于集中管理和动态配置微服务应用程序的配置信息的系统。它可以将应用程序的配置信息独立于代码进行管理,实现配置的集中化和动态更新。Spring Cloud中,常用的配置中心组件是Spring Cloud Config。它通过将配置文件存储在版本控制系统(如Git)中,并提供RESTful接口来实现配置的集中管理和动态更新。
  6. 什么是断路器模式?Spring Cloud中如何实现断路器模式?
    • 断路器模式是一种容错机制,用于处理分布式系统中的故障和异常情况,防止故障扩散和系统崩溃。它通过在调用链路上设置断路器,当某个服务出现故障或超时时,可以快速失败并返回预先定义的降级响应。Spring Cloud中,常用的断路器模式组件是Netflix Hystrix。它提供了断路器、隔离、降级、缓存等功能,可以帮助开发者构建弹性和可靠的分布式系统。
  7. 什么是服务网关?Spring Cloud中如何实现服务网关?
    • 服务网关是位于微服务架构前端的入口,用于统一访问和处理来自客户端的请求。它可以提供路由、认证、鉴权、限流、日志记录等功能。Spring Cloud中,常用的服务网关组件是Spring Cloud Gateway和Netflix Zuul。它们提供了灵活的路由配置和过滤器机制,可以对请求进行转发、过滤和增强。

redis

  1. 什么是Redis?

    • Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,它支持键值对、数据结构、发布/订阅等功能。它被广泛用作缓存、消息队列、会话存储等。
  2. Redis支持哪些数据结构?

    • Redis支持多种数据结构,包括字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)、有序集合(Sorted Sets)等。这些数据结构可以满足不同场景下的需求。
  3. Redis的优点是什么?

    • Redis具有以下优点:
      • 高性能:Redis存储在内存中,读写速度非常快。
      • 支持丰富的数据结构:Redis提供了多种数据结构,使其适用于不同类型的应用。
      • 数据持久化:Redis支持将数据持久化到磁盘,以防止数据丢失。
      • 高可用性:Redis支持主从复制和哨兵机制,实现高可用性和故障转移。
      • 扩展性:Redis可以通过集群模式进行水平扩展,处理大规模数据集。
  4. Redis与Memcached有什么区别?

    • Redis和Memcached都是常用的内存数据存储系统,但有以下区别:
      • 数据结构:Redis支持丰富的数据结构,而Memcached只支持简单的键值对。
      • 数据持久化:Redis支持数据持久化到磁盘,而Memcached不支持。
      • 复制和故障转移:Redis支持主从复制和哨兵机制,实现高可用性和故障转移,而Memcached没有内置的复制和故障转移机制。
      • 扩展性:Redis可以通过集群模式进行水平扩展,而Memcached需要使用客户端分片来进行扩展。
  5. Redis的持久化方式有哪些?

    • Redis有两种持久化方式:
      • RDB(Redis Database)持久化:将内存中的数据定期快照保存到磁盘上的二进制文件。
      • AOF(Append-Only File)持久化:将每个写操作追加到文件中,以记录数据变化的日志。
  6. Redis如何处理并发访问?

    • Redis是单线程的,但通过使用事件驱动的方式处理并发请求。它使用事件循环和非阻塞I/O来实现高效的并发处理。此外,Redis提供了事务和乐观锁等机制来处理并发访问。
  7. Redis的数据淘汰策略是什么?

    • Redis提供了多种数据淘汰策略,包括:
      • LRU(Least Recently Used):淘汰最近最少使用的数据。
      • LFU(Least Frequently Used):淘汰使用频率最低的数据。
      • TTL(Time To Live):设置数据的过期时间,在过期后自动淘汰。
  8. Redis支持哪些复制方式?

    • Redis支持主从复制。主节点将数据同步到一个或多个从节点,从节点可以接受读请求,提高读取性能和可用性。
  9. Redis如何实现发布/订阅?

    • Redis使用发布/订阅模式来实现消息发布和订阅。客户端可以通过订阅特定的频道,当有消息发布到该频道时,客户端将收到相应的消息。
  10. Redis的应用场景有哪些?

    • Redis的应用场景包括:
      • 缓存:作为高性能的缓存存储,提高访问速度。
      • 会话存储:存储用户会话信息,实现分布式会话管理。
      • 消息队列:通过Redis的列表结构实现简单的消息队列。
      • 计数器和排行榜:使用Redis的计数器和有序集合实现计数和排行功能。
      • 实时数据处理:存储和处理实时数据,如实时统计、在线用户等。

MybatisPlus

  1. 什么是MyBatis-Plus?

    • MyBatis-Plus(简称MP)是一个基于MyBatis的增强工具,提供了一系列简化开发的特性和功能。它扩展了MyBatis的功能,提供了更方便的CRUD操作、代码生成、分页查询、乐观锁、逻辑删除等功能。
  2. MyBatis-Plus和MyBatis之间的关系是什么?

    • MyBatis-Plus是基于MyBatis的增强工具,它简化了MyBatis的开发流程,提供了更多的便捷特性和功能。可以说,MyBatis-Plus是在MyBatis的基础上进行扩展和增强的工具。
  3. MyBatis-Plus的核心特性有哪些?

    • MyBatis-Plus的核心特性包括:
      • 简化的CRUD操作:提供了基础的增删改查操作,减少了编写重复代码的工作量。
      • 代码生成:支持根据数据库表结构自动生成实体类、Mapper接口和XML映射文件。
      • 分页查询:提供了简单的分页查询功能,方便处理大量数据的分页显示。
      • 乐观锁:支持乐观锁机制,用于处理并发修改时的数据一致性问题。
      • 逻辑删除:提供了逻辑删除的功能,通过标记删除状态而不是真正删除数据。
      • 条件构造器:支持使用链式调用构建复杂的查询条件。
      • 自动填充:支持在插入或更新数据时自动填充指定的字段值。
  4. 如何使用MyBatis-Plus进行代码生成?

    • 可以使用MyBatis-Plus提供的代码生成器功能来自动生成实体类、Mapper接口和XML映射文件。需要配置生成器的相关参数,如数据库连接信息、表名、生成路径等。执行代码生成命令后,就会根据配置生成对应的代码文件。
  5. MyBatis-Plus如何实现分页查询?

    • MyBatis-Plus通过Page对象和PageHelper类实现分页查询。可以在查询方法中传入Page对象作为参数,并使用PageHelper类提供的静态方法进行分页设置,然后通过Page对象获取分页查询的结果。
  6. MyBatis-Plus如何实现乐观锁?

    • MyBatis-Plus通过在实体类中添加@Version注解,并在数据库表中添加版本号字段实现乐观锁。在更新数据时,会比较版本号是否一致,如果一致则更新数据并增加版本号,如果不一致则表示数据已被其他线程修改,需要进行相应的处理。
  7. 如何使用MyBatis-Plus进行条件查询?

    • MyBatis-Plus通过QueryWrapperLambdaQueryWrapper提供了强大的条件构造器,可以使用链式调用的方式构建复杂的查询条件。可以通过设置条件、排序、分组等来筛选出满足条件的数据。
  8. MyBatis-Plus支持哪些数据库?

    • MyBatis-Plus支持多种数据库,包括MySQL、Oracle、SQL Server、PostgreSQL等常见的关系型数据库。
  9. 如何实现逻辑删除功能?

    • MyBatis-Plus通过在实体类的逻辑删除字段上添加@TableLogic注解,并配置逻辑删除的值,实现逻辑删除功能。在删除数据时,会将逻辑删除字段的值更新为指定的逻辑删除标记,而不是真正删除数据。
  10. MyBatis-Plus与Spring Boot集成需要哪些配置?

    • 需要在application.propertiesapplication.yml中配置MyBatis-Plus的相关属性,如数据源配置、实体类扫描路径、Mapper接口扫描路径等。同时,还需要在启动类上添加@MapperScan注解,指定Mapper接口的扫描路径。

spring security

  1. 什么是Spring Security?

    • Spring Security是一个用于在Java应用程序中提供身份验证和授权的强大框架。它可以用于保护Web应用程序、REST API和方法级别的安全性,提供了各种功能,如用户认证、访问控制、记住我功能、单点登录等。
  2. Spring Security的核心原理是什么?

    • Spring Security的核心原理是基于过滤器链(Filter Chain)的安全处理机制。请求经过一系列的过滤器,每个过滤器负责执行特定的安全任务,如用户认证、权限检查等。通过配置不同的过滤器,可以实现不同的安全策略。
  3. Spring Security提供的身份验证方式有哪些?

    • Spring Security提供了多种身份验证方式,包括基于表单的身份验证、HTTP基本身份验证、LDAP身份验证、OpenID身份验证等。可以根据应用程序的需求选择合适的身份验证方式。
  4. 如何配置Spring Security?

    • 可以通过在Spring配置文件中配置Spring Security的相关属性来进行配置。可以设置用户认证方式、访问控制规则、记住我功能、登录页面等。另外,还可以使用Java配置或注解方式进行Spring Security的配置。
  5. Spring Security中的角色和权限有什么区别?

    • 角色和权限是Spring Security中的两个重要概念。角色是用于对用户进行分类的,表示用户具有的某种角色,而权限表示用户可以执行的特定操作或访问的资源。一个用户可以具有多个角色,而每个角色可以拥有多个权限。
  6. 如何实现自定义的用户认证?

    • 可以实现自定义的用户认证逻辑,通过实现UserDetailsService接口的loadUserByUsername()方法,自定义加载用户信息的逻辑。可以从数据库、LDAP等数据源中获取用户信息,并返回一个实现了UserDetails接口的对象。
  7. 如何实现方法级别的安全性控制?

    • 可以使用Spring Security的@PreAuthorize@PostAuthorize注解来实现方法级别的安全性控制。通过在方法上添加这些注解,并提供相应的表达式,可以对方法的访问进行权限控制。
  8. Spring Security中的记住我功能是如何实现的?

    • Spring Security的记住我功能通过在用户登录成功后生成一个持久的cookie,并将该cookie存储在客户端。下次用户访问时,系统会自动读取cookie中的用户信息,并进行自动登录。
  9. 如何实现单点登录(SSO)?

    • 实现单点登录可以使用Spring Security提供的AuthenticationEntryPointAuthenticationSuccessHandler接口,结合其他技术如OAuth、SAML等实现。在SSO场景中,用户只需要登录一次,即可访问多个关联应用,提供了便捷和安全的用户体验。
  10. 如何处理Spring Security的异常?

    • Spring Security抛出的异常通常需要进行适当的处理,可以使用ExceptionTranslationFilterAuthenticationEntryPoint来处理认证和授权异常。可以配置自定义的异常处理器,用于捕获和处理Spring Security抛出的异常。

git

  1. 什么是Git?

    • Git是一个分布式版本控制系统,用于追踪和管理项目代码的变化。它允许多个开发者在同一个项目上并行工作,并提供了版本控制、分支管理、合并等功能。
  2. Git和SVN有什么区别?

    • Git是分布式的,而SVN是集中式的版本控制系统。在Git中,每个开发者都可以在本地拥有完整的代码仓库,可以在没有网络连接的情况下进行工作。而在SVN中,开发者需要依赖中央服务器来获取代码。
  3. Git的工作流程是什么样的?

    • Git的工作流程通常包括克隆(Clone)、修改(Modify)、提交(Commit)、推送(Push)和拉取(Pull)。开发者通过克隆远程仓库获取代码,在本地进行修改并提交到本地仓库,然后将变更推送到远程仓库,其他开发者可以拉取最新代码。
  4. Git中的分支是什么?如何创建和切换分支?

    • 分支是Git中用于并行开发和管理代码变化的重要概念。可以使用git branch命令创建新分支,并使用git checkout命令切换到不同的分支。
  5. Git的常用命令有哪些?

    • 常用的Git命令包括:git clone(克隆远程仓库)、git add(添加文件到暂存区)、git commit(提交变更到本地仓库)、git push(推送变更到远程仓库)、git pull(拉取最新代码)、git branch(查看分支)、git checkout(切换分支)、git merge(合并分支)等。
  6. 如何解决代码冲突?

    • 当多个开发者对同一个文件的同一部分进行修改时,就会产生代码冲突。解决冲突通常需要手动编辑冲突文件,查看冲突标记,并选择合适的代码。解决冲突后,需要重新提交变更。
  7. Git中的.gitignore文件的作用是什么?

    • .gitignore文件用于指定Git忽略的文件和文件夹,以避免将其纳入版本控制。通常在该文件中添加临时文件、编译输出文件、IDE生成的文件等。
  8. 如何撤销已提交的变更?

    • 可以使用git revert命令撤销单个提交,并生成一个新的提交来还原变更。或者使用git reset命令回退到之前的提交,但要注意这种操作会改变提交历史,可能会造成数据丢失。
  9. 如何查看提交历史?

    • 可以使用git log命令查看提交历史记录。可以添加不同的选项来获取不同的提交信息,如作者、日期、变更等。
  10. 如何将本地仓库与远程仓库关联?

    • 可以使用git remote add命令将本地仓库与远程仓库关联起来,以便进行推送和拉取操作。

微服务

  1. 什么是微服务?
  • 微服务是一种架构风格,将一个大型应用程序拆分为一组小型、独立部署的服务。每个服务都可以独立开发、部署和扩展,并通过轻量级的通信机制(如HTTP/REST)进行通以下优点:

    • 独立开发和部署:每个微服务可以独立开发、测试和部署,提高了开发效率和灵活性。
    • 松耦合:每个微服务都是独立的,可以使用不同的技术栈和语言,降低了耦合性。
    • 可扩展性:每个微服务可以独立地进行水平扩展,以满足不同服务的需求。
    • 容错性:一个微服务的故障不会影响整个应用程序,提高了容错性和可用性。
    • 易于维护:由于每个微服务都相对较小,因此更容易理解和维护。
  1. 微服务架构的挑战是什么?

    • 微服务架构面临以下挑战:
      • 分布式系统复杂性:微服务架构涉及多个分布式服务之间的通信和协调,增加了系统的复杂性。
      • 服务间通信:微服务之间的通信需要设计和管理,可能会引入网络延迟和故障。
      • 数据一致性:数据的一致性变得更加复杂,需要使用合适的机制来处理数据一致性问题。
      • 部署和运维:微服务架构需要对大量的服务进行部署、监控和管理,增加了运维的复杂性。
      • 团队组织和沟通:微服务架构需要跨多个团队进行协作,需要良好的组织和沟通。
  2. 如何实现微服务之间的通信?

    • 微服务之间的通信可以使用多种方式,包括:
      • HTTP/REST:通过HTTP协议和RESTful风格的API进行通信。
      • 消息队列:使用消息队列作为中间件,实现异步通信和解耦。
      • RPC:使用远程过程调用(RPC)框架进行微服务之间的通信。
      • 事件驱动:通过事件发布和订阅机制进行微服务之间的通信。
  3. 如何保证微服务架构中的数据一致性?

    • 在微服务架构中保证数据一致性可以使用以下方法:
      • 异步通信:通过消息队列等方式实现异步通信,降低了数据一致性的要求。
      • 两阶段提交(2PC):使用两阶段提交协议来保证分布式事务的一致性。
      • 补偿事务:当某个服务发生故障时,使用补偿事务来回滚之前的操作。
      • 事件溯源:使用事件溯源机制来记录和回放事件,保证数据的一致性和可追溯性。
  4. 微服务架构和单体架构相比有什么优势和劣势?

  • 微服务架构的优势包括灵活性、可扩展性、独立部署和维护性;而劣势包括系统复杂性、服务间通信和数据一致性的挑战。
  1. 微服务架构中的服务发现和负载均衡如何实现?
  • 服务发现可以使用服务注册中心(如Consul、Eureka)来实现,微服务通过注册到服务注册中心,其他服务可以通过查询服务注册中心来发现服务。负载均衡可以通过使用负载均衡器(如Nginx、Ribbon)来实现,将请求分发到不同的服务实例上。
  1. 如何进行微服务架构的监控和容错处理?
  • 监控可以通过使用监控工具(如Prometheus、Grafana)来收集和可视化微服务的运行指标。容错处理可以使用断路器(如Hystrix)来实现,当某个服务出现故障时,断路器可以快速切换到备用逻辑,避免级联故障。
  1. 什么是API网关(API Gateway)?
  • API网关是微服务架构中的入口点,负责处理所有的外部请求并将其路由到相应的微服务。它可以实现请求转发、负载均衡、安全认证、缓存等功能。
  1. 如何实现微服务的部署和自动化运维?

    • 微服务的部署和自动化运维可以使用容器技术(如Docker、Kubernetes)来实现,通过容器化每个微服务,并使用自动化工具(如Jenkins、Ansible)来进行部署和管理。

7月30号 java实习广东小厂面试

自我介绍

Java8新特性详解

介绍 Java 的集合类

spring中的注解有哪些

spring事务处理

post和get

POST和GET是HTTP协议中常用的两种请求方法,用于在客户端(如浏览器)和服务器之间传递数据。它们有不同的特点和用途:

  1. GET请求:
  • GET用于从服务器获取资源或数据。
  • GET请求将参数附加在URL的查询字符串中,以?符号分隔URL和参数,参数之间使用&符号分隔。
  • GET请求的参数通常会显示在URL中,因此不适合传递敏感信息。
  • GET请求可以被缓存,可以被收藏为书签。
  • GET请求具有幂等性,即多次发送相同的GET请求不会对服务器产生副作用。
  1. POST请求:
  • POST用于向服务器提交数据,通常用于创建、更新或发送数据到服务器上的资源。
  • POST请求将参数包含在请求的主体中,而不是在URL中。
  • POST请求的参数不会在URL中显示,因此适合传递敏感信息。
  • POST请求不会被缓存,不能被收藏为书签。
  • POST请求不具有幂等性,即多次发送相同的POST请求可能会对服务器产生不同的副作用。

对cookie和session了解,存储位置

异常处理

springcloud中的组件了解哪些

http中关于各个状态码怎么分类的,了解哪些

  1. 1xx(信息类):表示接收的请求正在处理。
  • 100 Continue:服务器已接收到请求的初始部分,并且客户端应继续发送剩余的请求。
  1. 2xx(成功):表示请求已成功处理。
  • 200 OK:请求成功,服务器已返回请求的内容。
  • 201 Created:请求已成功处理,并在服务器上创建了新的资源。
  • 204 No Content:服务器已成功处理请求,但没有返回任何内容。
  1. 3xx(重定向):表示需要进一步操作才能完成请求。
  • 301 Moved Permanently:请求的资源已永久移动到新位置。
  • 302 Found:请求的资源临时移动到新位置。
  • 304 Not Modified:客户端可以使用缓存的版本,因为资源未被修改。
  1. 4xx(客户端错误):表示请求包含错误或无法完成请求。
  • 400 Bad Request:请求无效,服务器无法理解。
  • 401 Unauthorized:请求需要身份验证。
  • 404 Not Found:请求的资源不存在。
  1. 5xx(服务器错误):表示服务器在处理请求时遇到错误。
  • 500 Internal Server Error:服务器遇到意外错误,无法完成请求。
  • 503 Service Unavailable:服务器当前无法处理请求,通常是由于过载或维护。

过滤器和拦截器的区别

1、触发时机不同 过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

2、拦截的请求范围不同 过滤器Filter执行了两次,拦截器Interceptor只执行了一次。这是因为过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

8月6号 某小厂面试

1.spring ioc aop

IOC(Inversion of Control)是一种设计原则,它将原本由程序员手动创建和管理的对象交给Spring容器来管理。Spring容器充当对象工厂的角色,负责对象的创建和依赖关系的管理。通过IOC,当我们需要使用对象时,只需从容器中获取即可。

实现IOC的方式之一是依赖注入(Dependency Injection)。依赖注入可以通过以下三种方法来实现:

  1. 注解注入:使用注解(如@Autowired、@Resource)来标注需要注入的依赖对象,Spring容器会根据注解信息自动完成对象的创建和注入。
  2. Setter注入:通过为依赖对象提供对应的setter方法,在XML配置或者注解中配置依赖关系,Spring容器在创建对象时会自动调用setter方法来完成依赖注入。
  3. 构造方法注入:通过在构造方法中声明依赖参数,Spring容器会根据构造方法的参数信息来创建对象并完成依赖注入。

AOP(Aspect-Oriented Programming)是一种编程范式,它允许在程序的某个特定点(切入点)插入非业务性的代码,比如日志记录等。这些代码被称为切面(Aspect),可以通过AOP来实现。

2.arraylist和linkedlist哪个查询快

ArrayList和LinkedList在查询、删除和插入操作上具有不同的性能特点。

  1. 查询:ArrayList的查询速度较快,因为它内部使用数组实现,可以通过索引直接访问元素,时间复杂度为O(1)。而LinkedList需要从头或尾开始遍历链表,直到找到目标元素,时间复杂度为O(n)。
  2. 删除和插入:LinkedList在删除和插入操作上比ArrayList更快。当需要删除或插入元素时,ArrayList需要移动其他元素以保持连续性,导致时间复杂度为O(n)。而LinkedList只需要更改相邻节点的指针,时间复杂度为O(1)。特别是在链表的首尾操作上,LinkedList表现更为突出。

3.java基本数据类型

基本数据类型指的是Java语言中的基本数据类型,包括整型、浮点型、布尔型和字符型。以下是Java中的基本数据类型:

  1. 整型:
    • int:用于表示整数,占用4个字节。
    • byte:1个字节,范围为-128到12
    • long:用于表示长整数,占用8个字节。
    • short:用于表示短整数,占用2个字节。
  2. 浮点型:
    • float:用于表示单精度浮点数,占用4个字节。
    • double:用于表示双精度浮点数,占用8个字节。
  3. 布尔型:
    • boolean:用于表示逻辑值,只有两个取值:true和false。
  4. 字符型:
    • char:用于表示单个字符,占用2个字节。

4.自动装箱拆箱

自动装箱就是将基本数据类型用对应的引用数据类型封装起来

比如:

int a=1;

Interge w=a;

自动拆箱就是指将包装类对象自动转换为对应的基本数据类型。

比如:

Interge a=1;

int w=a;

5.关系型数据库用过吗

用过,比如mysql,sqlserver

6.mysql连接方式

  • JDBC连接:使用Java数据库连接(JDBC)API通过驱动程序连接到MySQL数据库,导入库,在配置文件中配置url,username,password。
  • 命令行连接:使用MySQL命令行客户端通过命令行界面连接到MySQL数据库,mysql -u -p,username为主机名或者主机的IP地址。
  • 图形化工具连接:使用图形化工具如Navicat Premium 15等连接到MySQL数据库。
  • 编程语言连接:通过编程语言的MySQL连接库(如Python的MySQLdb、PHP的mysqli扩展等)连接到MySQL数据库。

7.内连接和外连接

  • 内连接:内连接根据两个或多个表之间的匹配条件,返回同时在这些表中存在的行。只有满足连接条件的行才会被返回,其他行将被过滤掉。
  • 外连接:外连接根据连接条件,返回左表(左外连接)或右表(右外连接)中的所有行,同时根据连接条件匹配的行将被返回。如果没有匹配的行,将使用NULL值填充缺失的列。

将使用一个名为 Employees 的表和一个名为 Departments 的表来演示。

  1. Employees 表包含员工的信息,具有以下列:

    • EmployeeID: 员工ID
    • EmployeeName: 员工姓名
  • DepartmentID: 所属部门ID

下面是 Employees 表的示例数据:

EmployeeIDEmployeeNameDepartmentID
1John1
2Mary2
3David1
4Lisa3
  1. Departments 表包含部门的信息,具有以下列:

    • DepartmentID: 部门ID
    • DepartmentName: 部门名称

    下面是 Departments 表的示例数据:

    DepartmentIDDepartmentName
    1Sales
    2Marketing
    3Finance
    4HR

现在,我们可以使用内连接和外连接来获取不同的结果:

  1. 内连接(Inner Join):
    内连接会返回同时存在于两个表中的匹配行。

    示例查询:

    SELECT Employees.EmployeeName, Departments.DepartmentName
    FROM Employees
    INNER JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
    

    查询结果:

    EmployeeNameDepartmentName
    JohnSales
    MaryMarketing
    DavidSales
    LisaFinance

    上述结果显示了员工的姓名和他们所属的部门名称,仅包括存在于 Employees 表和 Departments 表中的匹配行。

  2. 左外连接(Left Outer Join):
    左外连接会返回所有的左表行,以及与左表匹配的右表行。如果右表中没有匹配的行,则使用 NULL 值填充右表的列。

    示例查询:

    SELECT Employees.EmployeeName, Departments.DepartmentName
    FROM Employees
    LEFT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
    

    查询结果:

    EmployeeNameDepartmentName
    JohnSales
    MaryMarketing
    DavidSales
    LisaFinance

    注意,左外连接的查询结果与内连接的结果相同。这是因为在这个示例中,所有的员工都有所属的部门,没有员工没有部门。

  3. 右外连接(Right Outer Join):
    右外连接会返回所有的右表行,以及与右表匹配的左表行。如果左表中没有匹配的行,则使用 NULL 值填充左表的列。

    示例查询:

    SELECT Employees.EmployeeName, Departments.DepartmentName
    FROM Employees
    RIGHT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
    

    查询结果:

    EmployeeNameDepartmentName
    JohnSales
    MaryMarketing
    DavidSales
    NULLHR

    上述结果显示了部门的名称以及与之匹配的员工姓名。注意到最后一行中的员工姓名为 NULL,这是因为 “HR” 部门在 Employees 表中没有匹配的员工。

8.主键和外键

  • 主键:主键是用于唯一标识表中每一行数据的列或列组合。它具有唯一性和非空性约束,用于确保每一行都有唯一的标识,并且不允许为空值。主键可以帮助在表中快速查找和识别特定的行。
  • 外键:外键是表中的一个列,它创建了与另一个表中的主键之间的关联。外键用于建立表之间的关系,它指向其他表中的主键,用于实现表之间的引用完整性。外键可以用于实现表之间的关联查询和数据一致性。

8月15

华创云鼎面试:

1、项目:项目业务介绍、项目人员组成

2、分布式锁用过哪些

基于数据库的锁:可以使用关系型数据库的事务和行级锁来实现分布式锁。通过在数据库中创建一个标志位或特定的锁表来表示资源的锁定状态,其他进程在访问该资源之前需要先获取该锁。这种方法的优势是使用了数据库的事务机制来确保锁的原子性。

基于缓存的锁:使用分布式缓存系统如Redis或Memcached来实现锁。通过在缓存中设置一个特定的键值对来表示资源的锁定状态,其他进程在访问该资源之前需要先获取该锁。这种方法的优势是缓存系统的高性能和支持分布式部署。

基于ZooKeeper的锁:ZooKeeper是一个开源的分布式协调服务,可以用于实现分布式锁。通过在ZooKeeper中创建一个临时顺序节点来表示资源的锁定状态,其他进程可以通过比较自己创建的节点与已存在节点的顺序来判断是否获取到锁。这种方法的优势是ZooKeeper提供了强一致性和高可靠性。

3、Linux常用命令

  1. ls:列出目录中的文件和子目录。
  2. cd:切换当前工作目录。
  3. pwd:显示当前工作目录的路径。
  4. mkdir:创建新目录。
  5. rm:删除文件或目录。
  6. cp:复制文件或目录。
  7. mv:移动文件或目录,也可用于重命名文件。
  8. cat:连接文件并打印到标准输出设备上。
  9. grep:在文件中搜索指定模式的文本。
  10. chmod:修改文件或目录的权限。
  11. chown:修改文件或目录的所有者。
  12. chgrp:修改文件或目录的所属组。
  13. tar:打包和解压文件。
  14. find:在指定目录中查找文件。
  15. ssh:通过安全外壳协议远程登录到另一台计算机。
  16. ping:向目标主机发送网络数据包以测试连接性。
  17. ifconfig:显示和配置网络接口信息。
  18. wget:从网络上下载文件。
  19. top:实时显示系统中运行的进程和系统资源使用情况。
  20. ps:显示当前运行的进程。

4、java8新特性

1、Lambda表达式和函数式接口:使用Lambda表达式可以更简洁地编写函数式代码,例如在集合中进行筛选、映射和聚合操作。您可以创建自定义的函数式接口,并将Lambda表达式作为参数传递给接受函数式接口的方法。

2、Stream API:Stream API提供了许多便利的方法来处理集合数据。例如,您可以使用filter()方法过滤集合中的元素,使用map()方法将元素进行转换,使用sorted()方法对元素进行排序,使用collect()方法将结果收集到一个新的集合中等等。

3、方法引用:方法引用可以简化代码,使得代码更加可读和易于维护。您可以使用方法引用来引用现有的方法,例如静态方法、实例方法或构造方法。

4、新的日期和时间API:新的日期和时间API(java.time包)提供了一套更好的日期和时间处理工具。您可以使用LocalDateLocalTimeLocalDateTime等类来表示日期和时间,执行各种日期和时间的计算和操作。

5、Spring的理解,IOC、AOP在实际项目中怎么用的

Spring是一个开源的Java框架,用于开发企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过使用控制反转(Inversion of Control,IoC)和面向切面编程(Aspect-Oriented Programming,AOP)等技术,简化了Java应用程序的开发过程。

  1. 控制反转(IoC):
    IoC是Spring框架的核心概念之一。它通过将对象的创建、依赖解析和生命周期管理等任务交给Spring容器来实现。在实际项目中,您可以通过以下方式使用IoC:
  • 定义Bean:在Spring配置文件(如XML文件)或使用注解(如@Component@Service等)来标识类为Bean。Spring容器会负责创建和管理这些Bean。
  • 依赖注入(Dependency Injection,DI):通过构造函数、Setter方法或字段上的注解,将依赖对象注入到目标对象中。Spring容器会自动解析依赖关系,并将所需的依赖对象注入到目标对象中。
  1. 面向切面编程(AOP):
    AOP是一种编程范式,用于解耦横切关注点(如日志记录、事务管理等)和核心业务逻辑。在Spring中,您可以使用AOP来实现以下功能:
  • 切面(Aspect):定义横切关注点的行为,如日志记录、事务管理等。
  • 切点(Pointcut):定义在哪些连接点(Join Point)上应用切面。
  • 通知(Advice):定义在切点上执行的具体操作,如在方法执行前后进行日志记录等。
  • 织入(Weaving):将切面应用到目标对象的过程,可以通过编译期织入、类加载期织入或运行时织入来实现。

在实际项目中,您可以使用AOP来实现日志记录、事务管理、安全性检查等横切关注点。通过将这些关注点与核心业务逻辑进行分离,可以提高代码的可维护性和重用性。

综合来说,Spring框架提供了IoC容器来管理对象的创建和依赖注入,以及AOP功能来实现横切关注点的解耦。通过合理地使用IoC和AOP,可以使项目代码更加模块化、可测试和易于扩展。

6、数据库性能优化、SQL优化

  1. 确保适当的索引:索引是加快数据库查询速度的关键。根据查询模式和表结构,创建合适的索引可以显著提高查询性能。
  2. 优化查询语句:通过分析查询语句的执行计划,可以确定性能瓶颈并进行优化。使用适当的JOIN语句、WHERE子句和排序等操作,减少不必要的数据访问和处理。
  3. 避免全表扫描:尽量避免执行全表扫描操作,可以使用索引或其他查询优化技术来减少查询所需的数据量。
  4. 优化数据库设计:良好的数据库设计可以提高查询和更新操作的性能。合理划分表和字段,避免冗余和不必要的复杂性。
  5. 调整数据库参数:根据数据库系统的特点和硬件环境,调整数据库参数,如缓冲区大小、并发连接数等,以提高性能。
  6. 缓存数据和查询结果:使用缓存技术可以减少数据库的访问次数,提高响应速度。可以使用内存缓存、分布式缓存或查询结果缓存等方式。

7、用过什么设计模式

当解释设计模式时,我将使用Java代码示例来说明单例模式、工厂模式和策略模式的概念和用法。

  1. 单例模式(Singleton Pattern):

单例模式确保一个类只有一个实例,并提供一个全局访问点。

java

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // 私有构造函数,防止外部实例化
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在上述示例中,通过将构造函数声明为私有的,防止外部直接实例化对象。通过静态方法getInstance()来获取唯一的实例,如果实例还不存在,则创建一个新的实例并返回。这样可以确保在整个应用程序中只有一个Singleton实例。

  1. 工厂模式(Factory Pattern):

工厂模式通过使用工厂方法或抽象工厂来创建对象,而不是直接实例化对象。

java

public interface Product {
    void doSomething();
}

public class ConcreteProduct implements Product {
    @Override
    public void doSomething() {
        System.out.println("Doing something in ConcreteProduct.");
    }
}

public interface ProductFactory {
    Product createProduct();
}

public class ConcreteProductFactory implements ProductFactory {
    @Override
    public Product createProduct() {
        return new ConcreteProduct();
    }
}

在上述示例中,Product是一个接口,定义了产品的行为。ConcreteProduct是实现了Product接口的具体产品类。ProductFactory是一个工厂接口,定义了创建产品的方法。ConcreteProductFactory是实现了ProductFactory接口的具体工厂类,负责创建ConcreteProduct对象。

  1. 策略模式(Strategy Pattern):

策略模式定义了一系列算法,将每个算法封装起来,并使它们可以互换使用,使得算法可以独立于使用它的客户端而变化。

java

public interface Strategy {
    void execute();
}

public class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        System.out.println("Executing strategy A.");
    }
}

public class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        System.out.println("Executing strategy B.");
    }
}

public class Context {
    private Strategy strategy;

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void executeStrategy() {
        strategy.execute();
    }
}

在上述示例中,Strategy是一个接口,定义了策略的行为。ConcreteStrategyAConcreteStrategyB是实现了Strategy接口的具体策略类,分别表示不同的算法或行为。Context是上下文类,维护一个对策略接口的引用,并提供设置策略和执行策略的方法。

使用策略模式时,可以创建一个Context对象,并根据需要设置具体的策略,然后调用executeStrategy()方法执行策略。这样可以在运行时动态切换不同的策略。

8、mysql索引数据结构,为什么用它?

在MySQL中,常用的索引数据结构包括B-tree索引和哈希索引。

  1. B-tree索引:
    B-tree(Balanced Tree)是一种自平衡的树状数据结构,常用于数据库索引。MySQL中的B-tree索引是基于B+树实现的,具有以下特点:

    • 支持范围查询:B-tree索引可以高效地支持范围查询,例如大于、小于、区间查询等。
    • 适用于有序数据:B-tree索引对于有序数据的查询效率较高。
    • 支持高效的插入和删除:B-tree索引在插入和删除数据时,能够自动进行平衡调整,保持树的平衡状态。
    • 提供数据的有序访问:B-tree索引的叶子节点是按照索引顺序存储的,可以提供有序的数据访问。

    为什么使用B-tree索引?

    • 加快查询速度:使用B-tree索引可以快速定位到满足查询条件的数据行,提高查询效率。
    • 支持排序和范围查询:B-tree索引可以高效地支持排序和范围查询操作。
    • 适用于大数据量:B-tree索引适用于处理大量数据的情况,可以提供较好的查询性能。
  2. 哈希索引:
    哈希索引使用哈希表来存储索引数据,将索引键映射到哈希表中的桶(bucket)。MySQL中的哈希索引具有以下特点:

    • 快速哈希查找:哈希索引使用哈希函数进行查找,具有非常快速的查找速度,通常为O(1)时间复杂度。
    • 不支持范围查询:哈希索引只能支持精确匹配的查询,不适合范围查询或排序操作。
    • 不支持部分索引键查询:哈希索引要求查询条件必须包含所有哈希索引的键列。

    为什么使用哈希索引?

    • 高速查找:哈希索引在等值查询(例如根据主键进行查询)时具有非常快速的查找速度。
    • 适用于内存数据:哈希索引适用于数据完全加载到内存中的情况,可以提供非常高效的查询性能。

选择何种索引数据结构取决于具体的应用场景和查询需求。一般而言,B-tree索引适用于大部分常见的查询场景,而哈希索引适用于需要快速等值查询的内存数据。在MySQL中,常见的索引类型包括主键索引、唯一索引、普通索引等,可以根据具体的表结构和查询需求选择合适的索引类型和数据结构。

8月17号

衡泰一面

  1. 怎么安排工作,进行工作的,作为队长
  1. 需求分析阶段(2022/12/22——2022/12/31):
    • 确定项目目标和参赛要求。
    • 分配团队成员的任务和侧重分工。
    • 提供参赛手册和项目简介,引导团队成员广泛查阅资料和收集论文。
    • 组织讨论会,确保团队对项目背景、规则和作品要求有整体性把握。
  2. 系统设计阶段(2023/1/1——2023/1/20):
    • 根据需求分析阶段的成果,组织团队进行系统设计。
    • 对多目标遗传算法和模拟退火算法模型进行对比,并最终确定使用多目标遗传算法。
    • 完成架构设计、模块设计、接口设计和数据库设计。
  3. 系统实现阶段(2023/1/21——2023/3/20):
    • 根据设计阶段的成果,指导团队成员编写软件代码。
    • 进行单元测试,确保每个模块的功能正常运行。
    • 进行系统测试和系统优化。
    • 完成系统相关文档的编写。
  4. 系统测试阶段(2023/3/21——2023/3/31):
    • 制定测试计划,包括功能测试、性能测试、安全测试和兼容性测试。
    • 按计划进行测试用例编写和执行,进行缺陷管理。
  5. 撰写方案并系统提交阶段(2023/4/1——2023/4/17):
    • 完善项目方案,进行评估和审查。
    • 确保团队通过充分沟通和协作,保证智能排班系统的可行性和合理性。
    • 提前发现和解决问题,确保项目的顺利实施。
    • 完善研发成果和相关材料,并按时提交给客户。

在以上每个阶段,作为队长,您需要与团队成员保持良好的沟通、协调和监督,确保任务按时完成,并提供必要的支持和指导。同时,您还可以定期召开会议,进行进度更新、问题解决和团队合作的促进。

  1. 怎么停止线程

要停止线程,可以采用以下方法:

  1. 使用标志位:在线程的执行逻辑中使用一个标志位来控制线程是否继续执行。在外部需要停止线程的地方,将标志位设为相应的值,使得线程在下一次循环或条件判断时退出执行。

java

// 定义标志位
private volatile boolean running = true;

// 线程执行逻辑
public void run() {
    while (running) {
        // 线程执行的操作

        // 检查标志位
        if (!running) {
            break; // 退出循环,停止线程
        }
    }
}

// 停止线程的方法
public void stopThread() {
    running = false;
}

在上述示例中,线程的执行逻辑中通过检查标志位running来判断是否继续执行。在外部需要停止线程的地方,调用stopThread()方法将标志位设为false,从而使线程退出循环停止执行。

  1. 使用Thread的interrupt()方法:可以调用线程的interrupt()方法来中断线程的执行。在线程的执行逻辑中,在适当的地方通过检查Thread.currentThread().isInterrupted()来判断是否接收到中断信号,并在必要的情况下退出线程的执行。

java

// 线程执行逻辑
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        // 线程执行的操作
    }
}

// 停止线程的方法
public void stopThread() {
    thread.interrupt();
}

衡泰二面

之前:

  1. 单例模式怎么实现(懒汉写法),怎么保证线程安全(加synchronized),怎么加,加在哪?

    单例模式的懒汉写法是一种延迟加载的方式,在需要时才创建实例。实现懒汉写法的单例模式可以通过以下方式:

    java

    public class Singleton {
     private static Singleton instance;
    
     private Singleton() {
         // 私有构造函数
     }
    
     public static synchronized Singleton getInstance() {
         if (instance == null) {
             instance = new Singleton();
         }
         return instance;
     }
    }
    

    在懒汉写法中,通过在getInstance()方法上加上synchronized关键字,可以保证线程安全。synchronized关键字用于保证在同一时间只有一个线程能够进入该方法,从而避免了多线程环境下创建多个实例的问题。

    synchronized关键字可以加在getInstance()方法上,也可以加在代码块内部,如下所示:

    java

    public static Singleton getInstance() {
     synchronized (Singleton.class) {
         if (instance == null) {
             instance = new Singleton();
         }
     }
     return instance;
    }
    
  2. jvm的底层有了解过么?

    JVM(Java虚拟机)的底层是虚拟机实现的,它负责将Java字节码转换为机器码并执行。JVM包括了类加载、内存管理、垃圾回收、线程管理等功能,是Java程序运行的基础。

  3. 动态代理怎么实现的?

  4. 常用的包有哪些(并发包和集合包,当时怎么也想不起来并发包这个名词,就知道并发包里有哪些)

  5. 提示了并发包和集合包后,就让你说说包里面都有哪些常用的,说一下你自己熟悉的,经常用的。(我说了集合类那些以及一些锁);

    常用的并发包和集合包包括:

    1. 并发包(java.util.concurrent):
      • LockReentrantLock:提供了替代synchronized关键字的锁机制。
      • Semaphore:用于控制同时访问某个资源的线程数量。
      • CountDownLatch:用于等待其他线程执行完毕再继续执行。
      • CyclicBarrier:用于多个线程之间的同步。
      • ThreadPoolExecutor:用于创建线程池。
      • BlockingQueue:用于实现线程间的数据共享。
    2. 集合包(java.util):
      • List:有序可重复集合,如ArrayListLinkedList
      • Set:无序不可重复集合,如HashSetTreeSet
      • Map:键值对集合,如HashMapTreeMap
  6. 说下spring的理解

    Spring是一个开源的Java框架,用于简化Java应用程序的开发。它提供了一种轻量级的编程模型,通过依赖注入和面向切面编程等技术,使得开发人员可以更加专注于业务逻辑而不需要过多关注底层的技术细节。

  7. 说下springboot里面常用的注释

    在Spring Boot中,常用的注解包括:

    • @RestController:用于标识一个类是RESTful风格的控制器。
    • @RequestMapping:用于映射HTTP请求的URL路径。
    • @Autowired:用于自动注入依赖对象。
    • @Resource
      java的注解,属性较多,type无法分辨时可以用name分辨
      @Autowired:
      spring的注解,一个属性,type无法分辨时需要借助@Qualifier注解才能使用
    • @Service:用于标识一个类是服务层组件。
    • @Repository:用于标识一个类是数据访问层组件。
    • @Component:用于标识一个类是普通组件。
    • @Configuration:用于标识一个类是配置类。
    • @Value:用于注入配置属性值。
  8. 说下springmvc的底层实现,以及自我理解

    Spring MVC是基于Servlet API的MVC(Model-View-Controller)框架,用于开发Web应用程序。它的底层实现主要依赖于Servlet容器,如Tomcat。Spring MVC的工作流程如下:

    1. 客户端发送HTTP请求到前置控制器。
    2. 前置控制器根据请求的URL路径,调用相应的Controller方法。
    3. Controller方法处理请求,进行业务逻辑处理,并返回ModelAndView对象。
    4. 前置控制器根据视图解析器(View Resolver)解析视图,并将模型数据传递给视图。
    5. 视图渲染,生成响应结果。
    6. 前置控制器将响应结果返回给客户端。
  9. 说下mysql的函数有哪些,怎么用

    MySQL提供了许多内置函数,用于在查询和处理数据时进行各种操作和计算。以下是一些常用的MySQL函数及其用法的示例:

    1. COUNT 函数:用于计算满足条件的行数。

      SELECT COUNT(*) FROM 表名;  -- 计算表中的总行数
      SELECT COUNT(列名) FROM 表名 WHERE 条件;  -- 计算满足条件的行数
      
    2. SUM 函数:用于计算某个列或表达式的总和。

      SELECT SUM(列名) FROM 表名;  -- 计算列的总和
      SELECT SUM(列名) FROM 表名 WHERE 条件;  -- 计算满足条件的列的总和
      
    3. AVG 函数:用于计算某个列或表达式的平均值。

      SELECT AVG(列名) FROM 表名;  -- 计算列的平均值
      SELECT AVG(列名) FROM 表名 WHERE 条件;  -- 计算满足条件的列的平均值
      
    4. MAX 函数:用于获取某个列或表达式的最大值。

      SELECT MAX(列名) FROM 表名;  -- 获取列的最大值
      SELECT MAX(列名) FROM 表名 WHERE 条件;  -- 获取满足条件的列的最大值
      
    5. MIN 函数:用于获取某个列或表达式的最小值。

      SELECT MIN(列名) FROM 表名;  -- 获取列的最小值
      SELECT MIN(列名) FROM 表名 WHERE 条件;  -- 获取满足条件的列的最小值
      
  10. 给你一个正在面试的场景(面试官,面试者,动作)进行类的创建

  11. Static的理解

    • 静态变量:使用 static 关键字声明的变量称为静态变量或类变量。它们在内存中只有一份拷贝,被所有类的实例共享。
    • 静态方法:使用 static 关键字声明的方法称为静态方法。静态方法属于类,不依赖于任何实例。可以通过类名直接调用静态方法,而不需要创建类的实例。
    • 静态代码块:使用 static 关键字定义的代码块称为静态代码块。它在类被加载时执行,用于初始化静态变量或执行一些静态的初始化操作。
  12. String为什么不可变

    因为string是由final char value[] 表示的字符串,是一个常量

  13. Stringbuild如果加了final能改变内容吗

    StringBuilder 类是可变的字符串序列,可以用于拼接和修改字符串。当使用 final 关键字修饰 StringBuilder 对象时,表示该对象的引用不可更改,但对象本身仍然可以修改。因为StringBuilder类继承了AbstractStringBuilder 类的,在这个类里面是用char value[]没有被final修饰的字符数组表示的,所以是可变的.

  14. Jvm运行与编译的理解

    JVM运行过程如下:

    1. 编写Java源代码(.java 文件)。
    2. 使用Java编译器(javac 命令)将源代码编译成字节码文件(.class 文件)。
    3. JVM将字节码文件加载到内存中。
    4. JVM解释执行字节码指令,将字节码转换为机器码并运行。

    编译是将高级语言代码转换为机器可以执行的指令的过程。在Java中,编译器将Java源代码编译为字节码,而不是直接编译为机器码。这使得Java程序可以实现平台无关性,因为字节码可以在任何支持Java虚拟机的平台上运行。这也是java语言跨平台特性的原因。

  15. 垃圾回收

    垃圾回收(Garbage Collection)是一种自动化的内存管理机制,用于自动释放不再使用的内存对象。在Java中,垃圾回收器负责跟踪和回收不再被引用的对象,以释放内存空间并防止内存泄漏。

    垃圾回收的工作原理如下:

    1. 标记阶段:垃圾回收器从根对象(如栈和静态变量)开始,标记所有可达的对象。
    2. 清除阶段:垃圾回收器清除所有未标记的对象,并回收它们所占用的内存空间。
    3. 压缩阶段(可选):垃圾回收器将存活的对象压缩,使它们连续存放,以减少内存碎片化。
  16. Mysql索引

    1. 主键索引(Primary Key Index):
      主键索引是用于唯一标识数据库表中每一行的索引。它是一种特殊的唯一索引,用于保证表中的每一行都具有唯一的标识符。主键索引的值不能为NULL,并且在表中只能有一个主键索引。

      例如,考虑一个名为"users"的用户表,其中有一个名为"id"的列作为主键索引。每个用户在"id"列上都有一个唯一的标识符,可以通过该主键索引快速准确定位和访问。

    2. 唯一索引(Unique Index):
      唯一索引是保证表中某一列或多列的值都是唯一的索引。唯一索引允许NULL值,但在索引列中的非NULL值必须是唯一的。

      例如,考虑一个名为"emails"的电子邮件表,其中有一个名为"email_address"的列使用唯一索引。该唯一索引确保每个电子邮件地址在"email_address"列上都是唯一的,避免重复的邮件地址。

    3. 普通索引(Normal/Index):
      普通索引是最常见的索引类型,用于加快对表中列的查询速度。它没有唯一性或主键约束,可以包含重复值。普通索引可以在表的一个或多个列上创建。

      例如,考虑一个名为"products"的产品表,其中有一个名为"product_name"的列使用普通索引。这个普通索引可以加快根据产品名称进行查询的速度。

    4. 全文索引(Full-Text Index):
      全文索引是用于执行全文搜索的一种特殊索引类型。它允许在文本字段中进行关键字搜索,而不仅仅是精确匹配。全文索引适用于包含大量文本数据的列,如文章内容或博客评论。

      例如,考虑一个名为"articles"的文章表,其中有一个名为"content"的列使用全文索引。通过全文索引,可以在"content"列中进行关键字搜索,以找到包含特定词语或短语的文章。

  17. 给你一个场景问你索引会不会失效

    使用不等于操作符(< >!=)或IS NOT NULL条件。

    对索引列进行函数操作或类型转换。

    在查询条件中使用 OR 连接多个条件。

    对索引列进行模糊搜索(如使用通配符 %)。

吉因加面试

1、线程创建方法
1、继承 Tread类, 重写 run方法

2、实现 Runnable接口,实现 run方法

3、实现 Callable接口,实现 call方法,该方式可以获取线程的执行结果
2、多目标遗传算法实现
3、简历项目每个细节都要说清楚 重要
4、动态代理实现方式2个
1、JDK动态代理
2、Cglib动态代理
5、状态码
1. 1xx(信息类):表示接收的请求正在处理。

- 100 Continue:服务器已接收到请求的初始部分,并且客户端应继续发送剩余的请求。

2. 2xx(成功):表示请求已成功处理。

- 200 OK:请求成功,服务器已返回请求的内容。
- 201 Created:请求已成功处理,并在服务器上创建了新的资源。
- 204 No Content:服务器已成功处理请求,但没有返回任何内容。

3. 3xx(重定向):表示需要进一步操作才能完成请求。

- 301 Moved Permanently:请求的资源已永久移动到新位置。
- 302 Found:请求的资源临时移动到新位置。
- 304 Not Modified:客户端可以使用缓存的版本,因为资源未被修改。

4. 4xx(客户端错误):表示请求包含错误或无法完成请求。

- 400 Bad Request:请求无效,服务器无法理解。
- 401 Unauthorized:请求需要身份验证。
- 404 Not Found:请求的资源不存在。

5. 5xx(服务器错误):表示服务器在处理请求时遇到错误。

- 500 Internal Server Error:服务器遇到意外错误,无法完成请求。
- 503 Service Unavailable:服务器当前无法处理请求,通常是由于过载或维护。
6、数组的扩容机制
2,数组进行扩容时,会将老数据中得元素重新拷贝一份道新的数组中,每次数组容量得增长大于时原用量得1.5倍。

3,默认空参创建ArrayList长度是0,

当然也可以在创建时指定长度

也可以放一个集合进去,他就会使用c的大小做为容量,如果放入的集合 为null的话会报空值针异常

4,第一次add添加时会默认初始化长度为10

5,addAll没有元素时,扩容为Math.max(10,实际元素个数),有元素时为Math.max(原容量1.5倍,实际元素个数)
如果使用addAll添加元素时,要添加的元素长度超过下一次要扩容的长度时,他会使用要添加的元素作为扩容,反正他们两个谁长度大就用谁。
7、maven项目的目录

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

8、http的传输数据的方式
1)GET:获取资源

GET方法用来请求访问已被URL识别的资源

2)POST:传输实体主体

POST方法用来请求服务器传输信息实体的主体

GET和POST的区别:

首先,使用目标不同:GET方法只是用来查询,不会对浏览器上的信息产生影响,每次GET的方法都是相同的

其次,大小不同:GET是放在URL首部,因此大小随着浏览器而定,而POST则是在报文中,只要没有具体限制,文件的大小是没限制的

然后,安全性不同:GET采用的是明文传输,而POST是放在报文内部,无法看到

从使用场景的角度来说,一般像用户注册登录这种信息都是私密的,采用POST,而针对查询等,为了快速,大多采用GET传输。


3)PUT:传输文件

PUT要求在请求报文的主体中包含文件内容,然后保存到请求URL指定的位置

4)HEAD:获得报文首部

HEAD和GET方法一样,只不过不返回报文主体部分,用于确认URI的有效性及资源更新的日期时间等

5)DELETE:删除文件

DELETE是与PUT相反的方法,是按请求URI删除指定的资源

处于安全考虑,一般web网站不使用此方法,若配合web的安全验证机制,或者架构采用REST标准的网站,就可能开放使用此方法

6)OPTIONS:询问支持的方法

用来查询针对请求URI指定的资源支持的方法

7)TRACE:追踪路径

是让web服务器端将之前的请求通信还回给客户端的方法
9、mybatis和mybatispius的区别
    1、实现方式不同

MyBatis是基于XML或注解方式进行数据库操作的持久化框架,它提供了简单的CRUD操作及动态SQL生成等功能。而MyBatis-Plus是在MyBatis框架上的封装,通过对于增强简化后的API更加方便地进行开发,并且在性能、效率和易用性上都有一定的优化。

   2、 功能支持不同

MyBatis-Plus相比于MyBatis提供了很多额外的功能,例如像条件构造器、代码生成器、分页插件、性能分析拦截器等实用的组件,使得开发者可以轻松快速完成业务逻辑的开发。而MyBatis相对较为原始,需要手写大量的SQL以完成各种功能的实现。

   3、编程风格有所差异

MyBatis的编程风格更加传统,需要定义mapper.xml文件并根据传入的参数使用相应的SQL查询语句,需要实现 Mybatis 提供的各种方法;而MyBatis-Plus具有许多针对CRUD进行的简化方法,通过继承BaseMapper以及使用Lambda表达式,可以让我们像SpringDataJPA类似地使用接口编程方式进行数据库操作。
10、专业单词会读
clone (ke第三声 long第四声)
tread 
mkdir 直接拼
11、clone两种下载数据的区别
Git是一种分布式版本控制系统,支持多种协议,包括HTTP和SSH。HTTP和SSH都是用于远程访问Git仓库的协议,但它们之间有一些区别。

1. 认证方式不同

使用HTTP协议访问Git仓库时,需要使用用户名和密码进行认证。而使用SSH协议访问Git仓库时,需要使用SSH密钥进行认证。

2. 传输方式不同

使用HTTP协议访问Git仓库时,数据传输是通过HTTP协议进行的,即使用HTTP请求和响应来传输数据。而使用SSH协议访问Git仓库时,数据传输是通过SSH协议进行的,即使用SSH加密通道来传输数据。

3. 速度和安全性不同

使用HTTP协议访问Git仓库时,由于数据传输是通过HTTP请求和响应来完成的,因此速度可能会比较慢。而使用SSH协议访问Git仓库时,由于数据传输是通过SSH加密通道来完成的,因此速度可能会比较快。此外,SSH协议还提供了更高的安全性,因为数据传输是加密的。

总的来说,使用HTTP协议访问Git仓库比较简单,但速度和安全性可能会受到影响。而使用SSH协议访问Git仓库可能会更快和更安全,但需要进行SSH密钥认证。
12、异常的分类
img
Throwable

是java异常的顶级类,所有异常都继承于这个类。
Error,Exception是异常类的两个大分类。
Error

Error是非程序异常,即程序不能捕获的异常,一般是编译或者系统性的错误,如OutOfMemorry内存溢出异常等。
Exception

Exception是程序异常类,由程序内部产生。Exception
又分为运行时异常,非运行时异常类。
运行时异常

运行时异常的特点是java编译器不会检查它,也就是说,当程序中可能出现这类异常时,会编译通过,但是在运行时会出现错误。
如NullPointException,ArrayIndexoutOfBuoundsException等。
非运行时异常

程序必须进行处理的异常,编译不通过,必须捕获或者抛出。如IOException,ClassNo
tFoundException等。
java常见的异常有哪些?
NullPointerException

空指针异常,操作一个null对象的方法或者属性时触发。
OutOfMemoryError

内存异常异常,这不是程序能控制的,是指要分配的对象的内存超出了当前最大的内存堆,需要调整堆内存大小(-Xmx)以及优化才程序。
IOException

IO,即:input,output,我们在读写磁盘文件,网络内容的时候会发生的一种异常,这种异常是受检查的异常,需要手工捕获。
FileNotFoundException

文件找不到异常,如果文件不存在就会抛出这种异常。
ClassNotFoundException

类找不到异常,在类路径下不能加载指定的类。
ClassCastException

类型转换异常,如将一个数字强制转换成字符串。
throw和throws的区别?

throw: 是真实抛出一个异常
throws: 是声明程序可能会抛出一个异常
13、arraylist和linklist
ArrayList和LinkedList在查询、删除和插入操作上具有不同的性能特点。

1. 查询:ArrayList的查询速度较快,因为它内部使用数组实现,可以通过索引直接访问元素,时间复杂度为O(1)。而LinkedList需要从头或尾开始遍历链表,直到找到目标元素,时间复杂度为O(n)。
2. 删除和插入:LinkedList在删除和插入操作上比ArrayList更快。当需要删除或插入元素时,ArrayList需要移动其他元素以保持连续性,导致时间复杂度为O(n)。而LinkedList只需要更改相邻节点的指针,时间复杂度为O(1)。特别是在链表的首尾操作上,LinkedList表现更为突出。
14、集合分类
Java集合框架包括两个主要接口:Collection和Map。Collection接口表示一组对象,而Map接口表示一组键值对。

Java集合类的主要分类如下:

1. List:List是一种有序的集合,可以存储重复的元素。它的实现类包括ArrayList、LinkedList和Vector。
2. Set:Set是一种不允许重复元素的集合。它的实现类包括HashSet、TreeSet和LinkedHashSet。
3. Map:Map是一种键值对的映射表。它的实现类包括HashMap、TreeMap和LinkedHashMap。
4. Queue:Queue是一种先进先出(FIFO)的数据结构,可以使用它来实现排队等待的功能。它的实现类包括LinkedList和PriorityQueue。
5. Stack:Stack是一种后进先出(LIFO)的数据结构,可以使用它来实现撤销和回退等功能。它的实现类是Stack类本身。
15、Linux常用命令
1.简单系统命令
# 查看ip地址
	ip a
	ip addr
# ping网络(测试网络连通)
	ping 目标机器的ip
# 查看系统时间
	date
# 注销
	logout
# 关机
	shutdown now
# 重启
	reboot
# 清屏
	clear
2.Linux文件操作
2.1查看文件列表
# 查看当前目录下的文件列表
	ls
# 查看指定目录下的文件
	ls /
# 查看详细信息,元数据信息(用户、组、大小、创建时间、权限信息、文件类型)
	ls -l
# 查看隐藏文件
	ls -a 
# 参数并用
	ls -la
2.2 切换目录
# 绝对路径切换
	cd 绝对路径
# 相对路径切换
	cd 相对路径
# 例子:切换到/etc/sysconfig/networks-scripts 目录下
2.3新建文件夹及文件
# 在当前位置新建文件夹
	mkdir 文件夹名
# 在指定目录位置,创建文件夹,并创建父文件夹
	mkdir -p /a/b/文件夹名
# 在当前目录下新建文件
	touch 文件名
2.4删除文件
# 删除文件
	rm 文件
# 删除文件夹
	rm -r 文件夹
# 强制删除不询问
	rm -rf 文件
2.5拷贝文件
# 拷贝文件
	cp 原文件  新文件
# 拷贝文件夹
	cp -r 源文件夹 新文件夹
2.6移动文件或修改文件名
# 移动源文件到目标文件夹中
	mv 文件  文件夹
# 修改文件A的名字为文件B
	mv 文件A 文件B
3.系统管理
# 关闭进程
	kill 进程id 
# 强制关闭进程(谨慎使用)
	kill -9 进程id
16、docker创建镜像的命令
docker build -f dockerfile文件路径 -t 镜像名:[tag] .

http://www.kler.cn/news/108089.html

相关文章:

  • Seata入门系列【15】@GlobalLock注解使用场景及源码分析
  • 面试经典150题——Day24
  • React Router初学者入门指南(2023版)
  • Pytorch代码入门学习之分类任务(三):定义损失函数与优化器
  • 【Qt】绘图与绘图设备
  • C++不能在子类中构造函数的初始化成员列表中直接初始化基类成员变量
  • C++ 运算符
  • Linux touch命令:创建文件及修改文件时间
  • 底层驱动day8作业
  • 【C++】智能指针:auto_ptr、unique_ptr、share_ptr、weak_ptr(技术介绍 + 代码实现)(待更新)
  • Megatron-LM GPT 源码分析(三) Pipeline Parallel分析
  • AWS SAP-C02教程11-解决方案
  • C#,数值计算——分类与推理,基座向量机的 Svmgenkernel的计算方法与源程序
  • 中微爱芯74逻辑兼容替代TI/ON/NXP工规品质型号全
  • 【杂记】Ubuntu20.04装系统,安装CUDA等
  • python爬虫之feapder.AirSpider轻量爬虫案例:豆瓣
  • PHP简单实现预定义钩子和自定义钩子
  • Linux国产系统无法连接身份证读卡器USB权限解决办法
  • nrf52832 开发板入手笔记:J-Flash 蓝牙协议栈烧写
  • Nginx 的配置文件(负载均衡,反向代理)
  • Spring Security: 整体架构
  • uniapp-图片压缩(适配H5,APP)
  • 10月Java行情 回暖?
  • 【机器学习可解释性】4.SHAP 值
  • 第10期 | GPTSecurity周报
  • scratch接钻石 2023年9月中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析
  • 力扣第763题 划分字母区间 c++ 哈希 + 双指针 + 小小贪心
  • 制作自己的前端组件库并上传到npm上
  • MySQL实战2
  • 华为c语言编程规范