2021年Java面试题(待完善答案,可以先看题目,没时间写)

Java基础

基础概念与常识
1、JDK、JVM和JRE的区别是什么?

JDK(开发工具包): JDK是针对Java开发人员的开发工具包,它包含了Java的运行环境、Java工具及Java基础类库
JRE(运行环境): JRE是运行Java程序所必须的环境集合,包含了JVM标准实现及Java核心类库
JVM(虚拟机): JVM是Java的虚拟机,是Java能实现跨平台的核心部分,能够运行以Java编写的程序

2、Java和C++的区别是什么?
JavaC++
Java提供垃圾回收器C++没有
Java有反射机制C++没有
Java可以跨平台C++不能
Java没有指针的概念C++有

总结:Java其实也是由C++发展而来,保留了C++的大部分内容,其编程方式类似于C++,但是摒弃了C++的诸多不合理之处,从根本上解决了C++的固有缺陷。使得Java句法更清晰,规模更小,更易学,同时更趋于健壮性,安全性和平台无关性。

3、Java和Javax的区别是什么?

Java诞生之初,所必须的包都在Java包中定义,javax只是扩展JavaApi使用,随着时间的推移javax逐渐成为Java的组成部分,后期由于合并对原有的类影响较大,所以最终javax也成了java的标准API,现在的java和javax是一样的。

4、String、StringBuffer和StringBuilder的区别是什么?

String、StringBuffer和StringBuilder都是用来表示字符串。
String类是不可变类,任何对String的改变都会引发新的String对象的生成
StringBuffer和StringBuilder都是可变类,StringBuffer是线程安全的,而StringBuilder是线程不安全的,在单线程中建议使用StringBuilder,因为不考虑线程安全问题,StringBuilder比StringBuffer性能更高。

5、String为什么是不可变的?

java将String设为不可变最大原因应该是效率和安全。

6、==和equals的区别什么什么?
  1. == 既可以比较基本类型也可以比较引用类型,对于基本类型比较的是值,对于引用类型比较的是地址值。
  2. equals属于Object类里的方法,如果该方法没有被重写,则默认也是==,重写后比较类中的相应属性是否都相等
7、hashCode和equals的关系是什么?

通过hashcode来比较,如果hashcode相等,那么就用equals方法来比较两个对象是否相等,用个例子说明:hash表中的8个位置,就好比8个桶,每个桶里能装很多的对象,对象A通过hash函数算法得到将它放到1号桶中,当然肯定有别的对象也会放到1号桶中,如果对象B也通过算法分到了1号桶,那么它如何识别桶中其他对象是否和它一样呢,这时候就需要equals方法来进行筛选了。
1、如果两个对象equals相等,那么这两个对象的HashCode一定也相同
2、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置

8、介绍一下hashCode?

hashcode就是通过hash函数得来的,通俗的说,就是通过某一种算法得到的,hashcode就是在hash表中有对应的位置。

9、Java序列化中如果有些字段不想序列化怎么办?

对于不想进行序列化的变量,使用 transient 关键字修饰。
transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。transient 只能修饰变量,不能修饰类和方法。

10、为什么Java中只有值传递?

值传递,不论传递的参数类型是值类型还是引用类型,都会在调用栈上创建一个形参的副本。不同的是,对于值类型来说,复制的就是整个原始值的复制。而对于引用类型来说,由于在调用栈中只存储对象的引用,因此复制的只是这个引用,而不是原始对象。

11、深拷贝和浅拷贝的区别?

深拷贝:
相当于创建了一个新的对象,只是这个对象的所有内容,都和被拷贝的对象内容一模一样而已,即两者的修改是隔离的,相互之间不受影响
浅拷贝:
也是创建了一个对象,不过这个对象的某些内容(比如A)依然是被拷贝对象的,即通过这两个对象中任意一个修改A,两个对象的A都会受到影响

总结:
深拷贝是在原对象内容复制一份出来进行操作,两个对象互不影响
浅拷贝是在原对象内容上进行操作,修改任一对象后,双方受影响

12、ACID是什么?

A:原子性
C:一致性
I :隔离性
D:持久性

13、CAP是什么?

C:一致性
A:可用性
P:分区容错性

14、乐观锁的实现方式是什么?

给对象设置一个version版本属性,每次修改前先查询version保存下来,提交修改时检查一下version版本是否被修改,如果version版本一致再做修改操作

15、乐观锁的aba问题怎么解决?

ABA解释:线程1将值A修改为B,线程2修改值A为B之后又将B修改为A,在高并发的时候,线程1开始执行,还没执行完,线程2已经执行完了,线程1去判断值是否为A,此时认为值未被修改,就会修改这个值为B,这样就出现了线程不安全
解决方式:在JDK1.5以后,通过AtomicStamPedReference类来解决这个问题,原理同version一样,只要修改就让version版本自增

语法
1、字符型常量和字符串常量的区别?

形式上:字符常量是单引号引起的一个字符,字符串常量是双引号引起的若干字符
含义上:字符常量是一个整数值,可以参加逻辑运算,字符串常量是一个地址值
内存上:字符常量只占2个字节,字符串常量占若干字节

2、标识符和关键字的区别?

标识符:标识符是为方法、变量和其它用户自定义的名称
关键字:关键字是对编译器有特殊意义的单词,不能在程序中作为其它途径使用

3、continue、break和return的区别?

continue:是指跳出当前循环,执行下次循环
break:是指跳出循环体,继续执行循环外的代码
return:是指跳出当前方法

基本数据类型
1、Java中几种基本数据类型是什么?

java中有8种基本数据类型:
1、int --> 整型
2、short --> 短整型
3、long --> 长整形
4、float --> 单精度浮点型
5、double --> 双精度浮点型
6、byte --> 字节型
7、char -->字符型
8、boolean --> 布尔型

2、介绍一下自动拆箱与装箱?

自动装箱:自动装箱指的是将一个基本类型自动转为包装类型

//自动装箱举例:
Integer a = 12;
//在执行自动装箱操作时会自动执行
Integer a = Integer.ValueOf(12);

自动拆箱:自动拆箱指的是将一个包装类型自动转为基本类型

//自动拆箱举例:
int b = a;
//在执行自动拆箱操作时会自动执行
int b = a.intValue();
类和对象
1、构造方法有哪些特征?

1、构造方法与类同名
2、构造方法不能有返回值(void也不行)
3、不定义构造方法时,默认有无参构造
4、定义有参构造后,默认无参构造消失
5、构造方法不能被继承
6、构造方法不能手动调用

2、对象的相等与指向他们的引用相等有什么区别?

对象相等比较的是内容是否相等,引用相等比较的是两个地址值是否相等

3、接口与抽象类的区别?
抽象类接口
抽象类使用extends来继承接口使用Implements来实现
抽象类可以有构造方法接口不能有构造方法
抽象类可以有main方法,并可以执行接口不能有main方法
抽象类只能继承一次接口可以多实现
抽象类可以使用任意访问修饰符接口只能使用public
容器
1、简述ArrayList底层原理?

ArrayList底层使用数组进行元素存储,利用数组下标可以快速访问元素,因为是数组,所以在ArrayList初始化时,初始化大小为10,在插入新元素时,需判断是否需要扩容,扩容步长为:1.5倍原容量,扩容方式为:利用数组的复制,因此会有一定的开销。

2、简述LinkedList底层原理?

LinkedList底层使用双向循环链表进行元素存储,LinkedList有一个内部类,作为元素存储单元,存放元素本身和前后两个引用,另外,LinkedList有一个header属性,用来表示起始位置,第一个单元和最后一个单元都会指向这个header,来形成双向循环链表结构。

3、简述HashMap底层原理?

HashMap底层使用数组+链表实现的,当我们插入一个key,value时,首先会生成一个node对象,node对象中有成员key、value和next,next表示指向下一个node对象,当我们创建一个HashMap时,会在内存中创建一个长度为16的数组,数组的类型就是node,HashMap会对key的hashCode进行计算,得到一个0~15之间的值,这个值就是node要存放在数组中的索引,但是不同的key有时会得到相同的索引值,这时hashCode会判断新传入的node的key是否和已有的node的key相同,如果相同,就会用新node的value覆盖原node的value,如果不相同就会将新传入的node设置为原有node的下一个元素,形成一个链表,当一个链表上的元素个数到达8个的时候,为防止元素过多导致的遍历速度过慢,HashMap就会自动扩容,增加数组的长度,然后重新计算所有node的索引位置,重新存储,但如果数组长度扩容到64之后,如果某个位置上的链表元素超过8个,HashMap会将这个链表调整为红黑树,当这个红黑树上的元素少于6个的时候,HashMap又会将这个位置上的红黑树调整为链表

4、简述HashSet底层原理?

HashSet底层使用HashMap实现的,将HashSet的值放在HashMap的key上,HashMap的value统一为present。

5、Collection和Collections有什么区别?

collection是集合类的顶级接口,是为各种具体集合提供最大化的统一操作方式。
collections是集合的工具类,其中提供了一系列操作集合的静态方法。

6、Array和ArrayList有什么区别?
ArrayArrayList
Array可以容纳基本数据类型和对象ArrayList只能容纳对象
Array是指定大小ArrayList是动态大小
Array没有ArrayList那么多功能
7、HashMap和HashTable有什么区别?

HashMap去掉了HashTable的contains方法,添加了containsKey()和containsValue()方法。
HashMap是非同步的,HashTable是同步的,HashMap比HashTable的效率要高。
HashMap允许有空键值,HashTable不允许有空键值。

8、如何决定使用HashMap还是TreeMap?

如果是对插入、删除和定位元素这类操作时,使用HashMap最好。
如果是对一个有序的key集合进行遍历,TreeMap是最好。

面向对象
1、面向对象的三大特征?

1、封装
2、继承
3、多态
4、抽象(如果问四大特征,那么就把抽象答出来)

反射
1、反射是什么?

反射是java语言的一种特性,它允许程序在运行的时候进行自我检查并对内部的成员进行操作。

2、反射机制的优缺点?

优点:可以实现动态创建对象和编译
缺点:对性能有一定影响

3、反射的应用场景?

比如一个大型APP,在上线后获得了大量用户,某一天因产品需要升级,我们不能强制要求前面大量用户把APP卸载后重新安装,这样的用户体验太差就会损失大量客户。采用静态的话,需要我们重新编译才能实现新功能,但采用反射,我们可以不要求用户卸载之前APP,只需要在运行时才动态的创建和编译,就可以实现新功能。

多线程
1、简述线程、进程和程序的基本概念?

线程: 线程是进程的实体,是CPU调度和分派的基本单位,线程是能够独立运行的最小的基本单位,同一进程中的多个线程可并发执行。
进程: 进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程,进程在运行过程中拥有独立的内存单元,多个线程共享该内存单元,减少切换次数,从而提高效率。
程序: 程序是含有指令和数据的文件,被存储在磁盘或者其它存储设备中,也就是说程序就是代码。

2、并发和并行的区别是什么?
并行并发
并行是指多个事件在同一时刻发生并发是指多个事件在同一时间间隔发生
并行是在不同实体上的多个事件并发是在同一实体上的多个事件
并行是在多台处理器上执行的并发是在同一处理器上执行的
3、线程有哪些状态?

线程状态:
创建 -->> 就绪 -->> 运行 -->> 阻塞 -->> 死亡

4、常用线程池有哪些?
线程池名称描述
newCachedThreadPool是一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool是一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
newSingleThreadExecutor是一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。
newScheduleThreadPool是一个定长的线程池,而且支持定时的以及周期性的任务执行
5、线程池的调优参数有哪些?

1、设置线程池大小
2、设置创建连接数量
3、设置分发链接数量
4、设置等待时间

6、什么是乐观锁?什么是悲观锁?

乐观锁:
乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。
悲观锁:
当我们要对一个数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制,在修改数据之前先锁定,该修改的方式被称之为悲观并发控制

总结:
乐观锁比较乐观,总认为没人跟他竞争,直到提交更新时才会检测是否有冲突。
悲观锁比较悲观,总认为有人要跟他竞争,每次修改时现将数据锁起来,不让别人动。

7、什么是死锁?

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。

8、怎样预防死锁?

要讲如何防止死锁,那么就要先了解死锁是怎么生成的。
生成死锁有四个必要条件
1、互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
2、请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
3、不可剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
4、环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。
预防死锁:

  • 资源一次性分配:一次性分配所有资源,这样就不会再有请求了(破坏请求条件);
  • 只要有一个资源得不到分配,也不给这个进程分配其他的资源(破坏请保持条件);
  • 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件);
  • 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件);
9、start()和run()的区别是什么?

调用start()方法才能真正启用多线程,而run()方法只是thread的一个普通方法。

10、sleep()和wait()的区别是什么?

sleep:
sleep是线程类的静态方法,让调用线程进入休眠,让出执行权限给其它线程,等待休眠时间结束后,再次进入就绪状态,和其它线程抢占CPU执行时间,因为是静态方法,所以不能改变对象的机锁,在synchronized块中,若调用了sleep,线程虽然休眠,但无法释放机锁,其它线程依旧无法获得执行权限。
wait:
wait是object类中的方法,当线程执行到wait时,就会进入一个和对象相关的等待池,同时释放对象的机锁,是其它线程能够访问,可以通过notify或notifyAll来唤醒线程。

总结:sleep和wait相同点:一旦执行都可以使当前线程进入休眠
不同点:
1、sleep在Thread类中声明 ;wait在Object类中声明
2、sleep可以在任何需要的场景下调用;wait必须使用在同步代码块或同步方法中
3、如果两个方法都使用在同步代码块或同步方法中,sleep不能释放锁,而wait可以释放锁

11、Runnable和Callable接口的区别是什么?

1、实现Runnable接口的任务线程不能返回执行结果,但实现Callable接口对的任务线程能返回执行结果
2、Runnable接口实现类中run()方法的异常必须内部处理,不能向上抛出,而Callable接口实现类中的run()方法允许将异常向上抛出,也可以在内部处理。

12、线程实现的方式有哪些?
  • 继承Thread
  • 实现Runnable
  • 实现Callable
  • 使用线程池
13、HashMap在多线程环境下使用需要注意什么?

线程安全问题

14、HashMap为何是线程不安全的?
15、synchronized和lock的区别是什么?
synchronizedlock
synchronized是JVM级别的关键字Lock是Java类
synchronized无法判断是否获取到锁Lock可以判断
synchronized能根据当前情况释放锁Lock需要手动释放
synchronized在多线程下,若一条线程阻塞,其它线程需一直等待Lock可以不一直等待
synchronized的锁为:可重入,不可中断,非公平Lock的锁为:可重入,可中断,可公平
设计模式
1、什么是设计模式?

所谓的设计模式,其实就是一套被反复使用过的代码,对设计经验的总结,使用设计模式是为了可重用代码,让代码更容易被别人理解,保证代码的可靠性。

2、简述常用的几种设计模式?

单例模式:
工厂方法模式:
抽象工厂模式:
建造者模式:
享元模式:
装饰者模式:
策略模式:
适配器模式:
原型模式:
门面模式:
观察者模式:
模板模式:
责任链模式:

IO流
1、Java中IO的分类?
IO分类结果
按类型分为字节流和字符流
按功能分为标准流、缓冲流和增强流
按处理目标分为文件流、数据流和对象流
2、字节流和字符流的区别是什么?

1、最主要的区别在于:字节流在操作时不会用到缓冲区,是文件本身直接操作的,而字符流在操作的时候会使用缓冲区,通关缓冲区去操作文件

3、BIO、NIO和AIO的区别是什么?

BIO:
BIO为同步阻塞式IO,当读写操作时,会阻塞线程,但实现简单,对大数据量比较稳定
NIO:
NIO为同步非阻塞IO,当读写操作时,不会阻塞线程,实现复杂,对小数据多连接场景友好
AIO:
AIO为异步非阻塞IO,是基于回调机制,当读写操作时,会先挂起,当主线程执行完毕后再进行回调

4、BIO、NIO和AIO的使用场景分别是什么?
名称场景
BIOBIO方式适用于连接数目比较少且固定的架构
NIONIO方式适用于连接数目多且比较短的架构,比如聊天服务器
AIOAIO方式适用于连接数目多且连接比较长的架构,比如相册服务器

Spring

1、Spring是什么?

Spring 是一款开源的轻量级 Java 开发框架,指在提高开发人员的开发效率以及系统的可维护性。

我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说 Spring 支持 IoC(Inversion of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、可以很方便地集成第三方组件(电子邮件,任务,调度,缓存等等)、对单元测试支持比较好、支持 RESTful Java 应用程序的开发。

2、Spring有哪些优点?
3、Spring主要特性是什么?
4、Spring是如何解决循环依赖的?

Spring使用三级缓存来解决循环依赖;

5、简述Spring中Bean的创建过程?
6、简述Spring中Bean的生命周期?

1、实例化
2、属性赋值
3、初始化
4、使用
5、销毁

7、Spring事务的实现方式是什么?

1、编程式事务:在代码中硬编码(不推荐使用) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。
2、声明式事务:在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)

8、Spring事务的隔离级别是什么?
隔离级别描述
DEFAULT使用数据库本身的隔离级别
READ_UNCOMITTED未提交读
READ_COMMITED已提交读
REPEATABLE_READ可重复读
SERLALIZABLE串行化
9、Spring事务的传播属性有哪些?

PROPAGATION_REQUIRED – 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
 PROPAGATION_SUPPORTS – 支持当前事务,如果当前没有事务,就以非事务方式执行。
 PROPAGATION_MANDATORY – 支持当前事务,如果当前没有事务,就抛出异常。
 PROPAGATION_REQUIRES_NEW – 新建事务,如果当前存在事务,把当前事务挂起。
 PROPAGATION_NOT_SUPPORTED – 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
 PROPAGATION_NEVER – 以非事务方式执行,如果当前存在事务,则抛出异常。
 PROPAGATION_NESTED – 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
则进行与PROPAGATION_REQUIRED类似的操作。

10、BeanFactory和ApplicationContext有什么区别?

BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。
1、BeanFactory是Spring里面最底层的接口,是IoC的核心,定义了IoC的基本功能,包含了各种Bean的定义、加载、实例化,依赖注入和生命周期管理。ApplicationContext接口作为BeanFactory的子类,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能
2、
2.1、BeanFactroy采用的是延迟加载形式来注入Bean的,只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。
2.2、ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。
2.3、ApplicationContext启动后预载入所有的单实例Bean,所以在运行的时候速度比较快,因为它们已经创建好了。相对于BeanFactory,ApplicationContext 唯一的不足是占用内存空间,当应用程序配置Bean较多时,程序启动较慢。
3、BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建、

11、Spring的单例实现原理?
12、Spring中的依赖注入是什么?
13、Spring中IOC容器是什么?
14、Spring的IOC有什么优点?
15、SpringAOP原理是什么?
16、什么是Bean的自动装配?
17、什么是连接点?

连接点是指:程序运行过程中所执行的方法

18、什么是切点?

切点用于定义要对哪些Join point进行拦截

19、什么是织入?什么是织入应用的不同点?

通过动态代理,在目标对象的方法中增强逻辑的过程

20、什么是目标对象?

目标对象是指:包含连接点的对象,也称作被通知对象

21、什么是代理?
22、Spring的通知是什么?有哪几种通知?

通知的类型:
1、前置通知
2、后置通知
3、环绕通知
4、返回后通知
5、抛出异常后通知

23、Spring 框架中用到了哪些设计模式?

工厂设计模式 : Spring 使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
代理设计模式 : Spring AOP 功能的实现。单例设计模式 : Spring 中的 Bean 默认都是单例的。
模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
适配器模式 : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。

SpringMVC

1、SpringMVC五大组件是什么?

1、前端控制器
2、处理器映射器
3、处理器适配器
4、处理器
5、视图解析器

2、SpringMVC运行流程是什么?

客户端发来的请求交给前端控制器,前端控制器将请求交给处理器映射器,处理器映射返回一个执行链给前端控制器,前端控制器根据执行链调用处理器适配器,处理器适配器执行处理器,返回ModelAndView,处理器适配器将返回的ModelAndView返回给前端控制器,前端控制器将ModelAndView交给视图解析器进行解析,视图解析器返回View给前端控制器,前端控制器将View进行渲染,响应给客户端

3、SpringMVC怎么样设定重定向和转发?

(1)转发:在返回值前面加"forward:“,譬如"forward:user.do?name=method4”

(2)重定向:在返回值前面加"redirect:“,譬如"redirect:http://www.baidu.com”

4、SpringMVC的控制器是不是单例模式,如果是,有什么问题?怎么解决?
5、@RequestMapping的作用?
6、@Autowired的作用?

SpringBoot

1、SpringBoot核心注解是什么?

@SpringBootApplication

2、简述SpringBoot自动配置原理?

在springboot项目的启动类上有一个@SpringBootApplication注解,这个注解是一个复合注解,里面会有一个@EnableAutoConfiguration注解,这又是一个复合注解,里面会有一个@Import注解,这个注解导入了一个AutoConfigurationImportSelector.Class类,在这个类里会去扫描ClassPath路径下的META-INF/spring.factories这个文件的信息,会将里面的信息封装成一个map进行返回,那么这个map里面的就是一些自动配置类的全限定名,会将这些jar包注入到容器中。

3、SpringBoot的核心配置文件有哪些?有几种格式?它们的区别是什么?

SpringBoot核心配置文件有两种:application和bootstarp
有两种格式:properties和yml
两者区别为:
application文件主要用于springboot自动化配置文件
bootstarp文件主要用于:一些固定的不能覆盖的属性和一些加密解密的场景

SpringCloud

1、SpringCloud五大组件是什么?

1、Eureka - 注册中心
2、Hystrix - 熔断降级
3、Zuul - 网关
4、Feign - 远程调用
5、Ribbon - 负载均衡

2、SpringCloud断路器的作用是什么?
3、解释一下雪崩的概念?
4、什么是服务降级?

MySQL

1、简述MySQL数据索引底层结构?

按数据结构划分:RTree索引、BTree索引、Hash索引、全文索引;
按存储结构划分:聚簇索引、非聚簇索引;
按维度划分:主键索引、唯一索引、普通索引、覆盖索引、联合索引、全文索引;

2、简述数据库的锁机制?

按颗粒度划分:行锁(记录锁、间隙锁、临键锁)、页锁、表锁
按级别划分:共享锁(读锁[S锁])、排它锁(写锁[X锁])、意向锁(意向共享锁、意向排它锁)

3、MySQL的B+Tree和原BTree有什么区别?
4、数据库引擎有哪些?

MyIsam、InnoDB和MEMORY

5、MyIsam和InnoDB有什么区别?
区别MyIsamInnoDB
事务安全不支持支持
外键不支持支持
锁机制表锁行锁
查询和添加速度添加快查询快
全文检索支持不支持
内存空间使用率
6、数据库三范式是什么?

1、字段不可再拆分
2、有主键,非主键字段依赖主键
3、非主键字段不可相互依赖

7、什么是事务?

将多个操作作为一个整体向系统提交,要么都成功,要么都失败,是一组不可在拆分的操作;

8、事务的四大特性是什么(ACID)?

A、原子性:事务是最小的执行单位,事务的原子性保证了操作要么都完成、要么都失败。
C、一致性:执行事务后,数据保持一致;
I、隔离性:并发访问下,一个事务不受另一个事务的影响;
D、持久性:一个事务提交数据后,这个数据在数据库中应该是持久的;

9、事务的隔离级别有哪些?

1、未提交读:一个事务读到另一个事务未提交的数据;
2、已提交读:只能读到已提交的数据;
3、可重复读:同一个事务多次读取的数据相同;
4、串行化:每次读取都会获取标记共享锁,读写都会阻塞;

10、脏读、不可重复读和幻读是指什么?

脏读:一个事务读到另一个事务还没提交的数据;
不可重复读:同一事务内,两次相同的查询返回了不一样的结果;
幻读:当事务不独立运行时,A事务执行插入或删除操作时,B事务抢先执行完A事务,类似发生幻觉了;

11、如何SQL优化?

1、不使用select *;
2、不在where子句中使用:对字段null值的判断、对字段进行表达式操作、对字段进行函数操作;
3、少用in 和 not in;
4、在子查询中使用exists代替in;

12、什么是数据库索引?

可以看成一个目录,索引的存在其实就是为了查询数据效率快;

13、谈一下对数据库索引B+Tree的理解?
14、聚集索引和非聚集索引的区别是什么?
15、聚集索引和非聚集索引的优势与缺点是什么?
16、举几个索引失效的场景?
17、如何解决高并发减库存问题?
18、为什么MySQL底层使用B+Tree而不是Hash?

1、hash表只能匹配是否相等,不能实现范围查找
2、当需要按照索引进行order by时,hash值没办法支持排序
3、组合索引可以支持部分索引查询,如(a,b,c)的组合索引,查询中只用到了a和b也可以查询的,如果使用hash表,组合索引会将几个字段合并hash,没办法支持部分索引
4、当数据量很大时,hash冲突的概率也会非常大
5、B+树作为索引时,非叶子节点只保存索引,叶子节点才会保存数据,这样方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

Redis

redis基础
1、Redis是什么?

redis是C语言编写的高性能键值对的内存数据库,可以用作数据库、缓存、消息中间件等。是一种NoSql数据库。
那么redis作为一款内存数据库:
1、它性能优秀,数据存储在内存中,读写速度非常快,官方数据表示支持并发10W QPS
2、单进程单线程,是线程安全的,采用IO多路复用机制
3、有丰富的数据类型
4、支持持久化
5、主从复制、哨兵机制、高可用
6、可用作分布式锁
7、可以作为消息中间件使用,支持发布订阅

2、Redis五种基本数据类型是什么?

1、String
2、hash
3、list
4、set
5、zset

3、Redis很快吗?

很快,官方数据是10W+ QPS(每秒内的查询次数)

4、Redis这么快,那它的多线程模型了解吗?

只要问redis多线程那么这个面试官就是在给你挖坑!!!
答:您是想问redis这么快为什么还是单线程的是吗?redis的确是单进程单线程的,因为redis是完全基于内存操作的,CPU不是它的瓶颈,它的瓶颈最有可能是在服务器的内存或者网络带宽上,既然单线程能够实现,且CPU不会是瓶颈,那么顺理成章的使用单线程。

5、Redis是单线程的为什么还能这么快?

从四个方面说一下吧:
第一:redis是完全基于内存,绝大部分请求是纯粹的内存操作,所以非常迅速
第二:redis数据结构简单,对数据操作也简单
第三:采用单线程,避免了不必要的上下文切换和资源竞争,不用考虑锁的问题
第四:采用多路复用IO模型,非阻塞IO

6、为什么选择redis而不选择memcached呢?

1、数据存储方面:memcached将数据全放入内存中,数据不能大于内存,redis将部分数据存在硬盘上,能保证数据的持久化
2、数据结构方面:redis支持多种数据结构,memcached仅支持key-value形式
3、底层模型:redis自己构建了VM机制,一般的系统调用系统函数,会浪费一定的时间去转移和请求。
4、value存储大小:redis中value能存储1G,memcached中value只能存储1MB

7、Redis两种过期删除方式是什么?

1、定期删除
2、惰性删除

8、说一下你了解的Redis内存淘汰策略?

1、从已设置过期时间中删除最近最少使用的key
2、从已设置过期时间中删除将要过期的key
3、从已设置过期时间中随机挑选删除
4、从数据集中删除最近最少使用的key
5、从数据集中随机删除
6、禁止驱逐数据

9、Redis中最多能存多少key?

2.5亿

10、Redis中字符串最大存储是多少?

512M

11、如果DB中有2000W数据,而Redis中只能存20W数据,如何保证Redis中都是热点数据?

方案一:redis内存数据集达到一定大小时,就会实行内存淘汰策略,选择合适的内存淘汰策略;
方案二:请求时将要统计的key通过Hadoop存储起来,通过Hive进行统计分析并放入redis缓存中;

redis缓存
1、Redis的雪崩了解吗?

缓存在同一时间内大面积失效,导致请求全部落在数据库上,数据库短时间内承受不了大量请求而崩掉

2、如何解决雪崩?

事前:搭建redis集群,保证高可用,选择合适的内存淘汰策略。
事中:使用降级和限流,保证MySQL不宕机。
事后:使用redis持久化机制,快速恢复。

3、缓存穿透和缓存击穿了解吗?他们和雪崩有什么区别?

缓存穿透是指:缓冲中和数据库中都没有的数据,而用户不断发起请求
缓存击穿则和缓存雪崩有点类似,缓存击穿是指:一个热点key在大量请求下,缓存失效时,瞬间大量请求打在DB上,造成数据库宕机,缓存击穿和缓存雪崩不一样的是,缓存雪崩是大面积key失效打在DB上,而缓存击穿是从一个热点key打在DB上

4、如何解决缓存穿透和缓存击穿?

缓存穿透解决方案:
1、做好最基本的参数校验,不符合规则的直接返回客户端
2、缓存中和数据库中都没有时,将这个key存到缓存中,缺点是无法针对不断变化的key
3、使用布隆过滤器,将所有可能存在请求中的值都放入布隆过滤器中,当请求到达时,会先判断这个值是否在布隆过滤器中,如不存在直接返回客户端,如存在向下执行

5、在实际项目中使用缓存遇到过什么问题吗?如何解决的?

遇到过,遇到的是redis和数据库双写一致性问题。
解决办法:
方案一:使用双删策略
1、先删除缓存
2、修改数据库
3、等待1秒后再次删除缓存

方案二:canal

redis持久化
1、Redis持久化机制了解吗?怎样保证Redis挂掉之后重启数据可以恢复?

redis有两种持久化机制:RDB(快照)和AOF(只追加文件)
在redis重启时会先加载AOF,若AOF不存在则使用RDB进行数据恢复

2、说一下RDB是怎么工作的?

redis默认使用快照形式将数据持久化到磁盘的二进制文件中。工作原理简单说一下:在redis需要持久化时会fork一个子进程,将数据写入磁盘的一个临时RDB文件中,当子进程写文临时文件后,将原来的RDB替换掉。

3、RDB的优点是什么?

RDB优点是:这种文件非常适合灾难恢复
RDB缺点是:在灾难发生时如果想要更好的保留数据则RDB不适合

4、说一下AOF是怎么工作的?

使用AOF做持久化,每一个对redis数据修改的命令,都会把它添加到AOF文件中,当redis重启时会加载AOF文件,恢复到服务器宕机前最后一刻

5、AOF的优点是什么?

AOF优点:AOF持久化会让redis变得非常耐久
AOF缺点:同数据集下,AOF文件体积要大于RDB,效率上RDB比AOF更快

6、Redis 4.0对持久化机制的优化是什么?
7、能介绍一下AOF重写吗?
redis主从复制
1、说一下Redis主从复制的过程和原理?

说一下redis主从复制的过程:
1、从节点保存主节点的IP和端口号
2、从节点的定时任务发现主节点信息时,建立和主节点的socket链接
3、从节点发送ping,主节点回应pong,两边能互相通信
4、连接建立后,主节点将所有数据发送给从节点
5、主节点把当前数据同步给从节点后,便完成了复制的建立过程,之后,主节点就会持续的把写命令发送给从节点,保证数据的一致性

2、能详细说一下数据同步的过程吗?
3、能说一下全量复制和部分复制的过程吗?
redis哨兵
1、主从复制会有什么问题?

1、一旦主节点宕机,从节点晋升为主节点,其它从节点要去保存新的主节点地址,还需要去命令所有从节点去复制新的在主节点数据,整个过程需要人工干预
2、主节点写能力受到单机限制
3、主节点存储能力受到单机限制
4、原生复制在早期版本中也会比较突出,如:redis在复制过程中中断,从节点会发起psync,此时如果同步不成功,则会发起全量同步,主库执行全量同步时,会造成毫秒或秒级卡顿。

2、主流的解决方案是什么?

哨兵机制

3、哨兵有哪些功能?

1、监控主节点的存活状态
2、检测主从节点的运行状态
3、自动故障转移
4、主从切换

4、哨兵的主要任务有哪些?

1、监控
2、通知
3、自动故障转移
4、配置提供者

5、哨兵的工作原理能说一下吗?

1、每个Sentinel会向它的主服务器、从服务器、Sentinel实例发送一个ping命令;
2、如果一个实例距离最后一次有效回复ping命令超过配置时间,这个实例就会标记为主观下线;
3、如果一个主服务器被标记为主观下线,那么监视这个主服务器的所有Sentinel将会每秒一次的频率确认主服务器的确进入主观下线状态;
4、如果一个主服务器被标记为主观下线后,并且有足够的Sentinel同意这一判断,那么主服务器就被标记为客观下线;
5、一般情况下,Sentinel会以每10秒一次频率向主服务器和从服务器发送INFO命令,当主服务器被标记为客观下线后,Sentinel会向所有从服务器以每秒1次频率发送INFO命令;
6、Sentinel会和其他Sentinel进行协商客观下线的主节点状态,如果处于SDWON状态,则投票选举出新的主节点,将剩余的从节点指向新的主节点进项数据复制;
7、当没有足够的Sentinel支持主节点客观下线时,主节点的客观下线会被移除,当主节点重新回复ping命令后,主观下线状态也会被移除;

redis分布式锁
1、自己使用Redis实现分布式锁应该考虑的问题有哪些?

1、保证获取锁的原子性问题;
使用:SET NX;
2、解决程序异常下,不造成死锁问题;
使用:有效时间;
3、解决因业务逻辑过多,造成锁提前释放问题;
使用:守护线程进行锁续期;

2、如何高效的实现分布式锁?

Redisson

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值