面试题
- Java面试题
- Java基础面试题
- 描述Java的深拷贝和浅拷贝
- 回答:
浅拷贝只拷贝对象里的值,不拷贝引用关系。 深拷贝除了对象的值还拷贝对象中的引用关系。 - Java中有哪些引用类型
- 回答:
强:new 出来的对象都是强引用对象。 软:特点:只有内存不够用时会被回收。场景:缓存 弱:特点:只要垃圾回收就会被回收。场景:ThreadLocal就会使用,防止内存泄露。 虚:特点:管理堆外内存。不会被get到。只要垃圾回收就会被回收。回收的对象会被放到队列中。监听队列获取被回收的堆外内存。场景:堆外内存是netty NIO作为网络通讯时使用。 - java对象包含哪些数据,new object占用多少字节
- 回答:
对象头 12 or 16 字节 1.标记字 mark word 8字节 2.类型指针 4 or 8 字节 实例数据 1字节: byte boolean 2字节: char short 4字节: int float 8字节: double long 4 or 8 字节: 对象引用 对象填充字节 如果对象的大小不足8的倍数,则补充字节直到8的倍数。 - 动态代理jdk和cglib的区别
- 回答:
33 - HashMap底层工作原理
- 回答:
4 - ConcurrentHashMap工作原理
- 回答:
5 - 线程的生命周期
- 回答:
测试 - JVM面试题
- JVM的组成部分及其作用
- 回答:
12 - 描述类加载过程
- 回答:
2 - 什么是类加载器,类加载器有哪些
- 回答:
类加载器的种类 启动类加载器(Bootstrap ClassLoader):这是JVM内置的类加载器,通常由C/C++实现,负责加载JAVA_HOME/lib目录下的核心类库,如rt.jar、resources.jar等。启动类加载器无法被Java程序直接引用 扩展类加载器(Extension ClassLoader):负责加载Java平台的扩展类库,位于JAVA_HOME/lib/ext目录下。它的父加载器是启动类加载器 应用程序类加载器(Application ClassLoader):也称为系统类加载器,负责加载应用程序的类路径(classpath)下的类。它的父加载器是扩展类加载器 用户自定义类加载器:开发人员可以通过继承java.lang.ClassLoader类来实现自定义的类加载器,用于实现特殊的类加载策略,如从数据库、网络或加密存储中加载类 - 什么是双亲委派模型,如何打破双亲委派
- 回答:
21 - Java多线程面试题
- 描述synchronized,Lock,volatile的实现原理和区别
- 回答:
2 - AQS的实现原理
- 回答:
32 - 线程池的核心参数是什么?如何合理的配置线程池大小
- 回答:
21 - ThreadLocal的使用场景和原理,ThreadLocal的内存泄露的场景.
- 回答:
12 - 线程池的状态都有什么
- 回答:
32 - 垃圾回收面试题
- 垃圾回收算法有哪些
- 回答:
1.复制 2.标记清除 3.标记整理 - 垃圾回收器有哪些
- 回答:
Serial:新生代单线程串行的垃圾回收器。它会在垃圾回收时暂停所有用户线程(Stop-The-World)。 ParNew:这是Serial的多线程版本,主要用于新生代的垃圾收集,适合多核处理器环境。它可以与CMS收集器配合使用 Parallel Scavenge:这是一个多线程并行回收器,主要用于新生代垃圾收集,注重吞吐量,即CPU用于运行用户代码的时间比率 Serial Old:这是Serial的老年代版本,采用单线程工作方式,使用标记-整理算法。 Parallel Old:这是Parallel Scavenge的老年代版本,使用多线程并行工作,目标是提高系统吞吐量。 CMS (Concurrent Mark Sweep):这是第一个用户线程和垃圾回收线程能够并行工作的垃圾回收器,使用多线程并发标记和清除算法,主要用于老年代的垃圾回收。 G1 (Garbage-First):这是一种面向服务端应用的垃圾收集器,采用分区堆和增量式垃圾回收,兼顾吞吐量和停顿时间。 ZGC和Shenandoah:这两种收集器适用于新生代和老年代的混合回收,具有低延迟和高吞吐量的特点。 - 描述分代回收过程
- 回答:
12 - 如何判断对象是否需要被回收
- 回答:
是否被gc root 引用。 GC Roots的对象主要包括以下几类: 虚拟机栈中引用的对象:虚拟机栈中的本地变量表引用的对象,包括各个线程调用方法时使用的参数、局部变量等。 方法区中静态属性引用的对象:方法区中存储了类的元数据信息,包括静态变量和常量池。当静态变量引用一个对象时,该对象就是一个GC Root对象。 方法区中常量引用的对象:常量池中的常量引用的对象也是GC Root对象,例如字符串常量池中的字符串对象。 本地方法栈中JNI引用的对象:JNI(Java Native Interface)允许Java代码与本地代码进行交互,本地方法栈中JNI引用的对象也被视为GC Root对象。 正在运行的线程:正在运行的线程被认为是GC Root对象,因为它们可以访问堆中的任何对象。 虚拟机内部的引用对象:虚拟机内部的一些特殊引用,如系统类加载器、异常对象(如NullPointerException、OutOfMemoryError)等,也可以作为GC Root对象。 - 描述CMS垃圾回收过程
- 回答:
32 - mysql面试题
- mysql基础面试题
- innodb和myisam的区别
- 回答:
1.索引不同 InnoDB聚簇索引,MyISAM非聚簇索引 2.事务不同 InnoDB 支持事务处理(ACID兼容),包括提交(commit)、回滚(rollback)和崩溃恢复能力。 MyISAM 不支持事务处理,不支持行级锁定和外键。 3.机制 InnoDB 支持行级锁定和外键,这可以提供更高的并发处理能力。 MyISAM 只支持表级锁定。 4.主键 InnoDB必须要有主键,MyISAM允许没有主键 5.锁机制 MyISAM只支持表级锁,而InnoDB支持行级锁。表级锁是加锁时对整张表进行加锁,行级锁是对表中的某一行进行加锁。 - mysql共有多少种日志,作用是什么
- 回答:
MySQL中有六种日志文件,分别是: 重做日志(redo log)、innodb才有的日志,主要是用于记录事务时的操作日志。 回滚日志(undo log)、innodb才有的日志,主要是用于记录事务一些信息,便于事务回滚。 二进制日志(binlog)、mysql各个存储引擎都包含binlog, 用于记录数据信息。 错误日志(errorlog)、 慢查询日志(slow query log)、 一般查询日志(general log), 中继日志(relay log) - binlog共有多少种类型
- 回答:
1) STATEMENT STATEMENT 类型记录的是执行 SQL 语句的内容,比如 INSERT、UPDATE、DELETE 等语句本身。 比如: insert into users (name, email) values("张三", "12345@qq.com"), ("李四", "345123@qq.com"); update users set email = "4123@qq.com" where id=1; 如果包含了函数,那么就出现执行结果不一样的情况,例如 uuid或者now()函数。 2) ROW 存储的是数据行的变更,会包含变更前后的内容。日志内容是mysql自己设定的规则,日志内容较多,文件内容较大 3) MIXED MIXED 类型则是 STATEMENT 和 ROW 两种类型的综合,它会根据具体的情况来选择 STATEMENT 或者是 ROW 其中一种类型来进行存储。 比如说涉及函数或者一些比较复杂和无法还原的操作时,就会选择 ROW 格式来存储变更的数据行,如果是一些比较简单的插入、更新或者删除操作,那么则会选择 STATEMENT 格式来进行存储。 - mysql查询数据和修改删除数据的流程是什么
- 回答:
6 - mysql索引面试题
- mysql索引数据结构
- 回答:
2 - 聚集索引和非聚集索引的区别
- 回答:
聚集索引和非聚集索引的区别: 聚簇索引就是索引数据和表数据存储在一起,叶子节点为数据,非叶子节点为索引数据。innodb通常为主键索引。 非聚簇索引就是叶子为索引的字段值, 例如 用户表中按照age创建索引,那么非聚簇索引的叶子节点就为age的具体的值和对应的数据指针,便于回表查询。 物理存储顺序: 聚集索引:决定了数据在磁盘上的物理存储顺序,即数据行的物理顺序与索引键值顺序相同。叶子节点直接包含行数据。 非聚集索引:索引键值与数据行物理存储顺序无关。它是一种独立的数据结构,叶子节点包含索引键值和指向实际数据行的指针。 索引数量: 聚集索引:每个表只能有一个聚集索引,通常为主键。 非聚集索引:每个表可以有多个非聚集索引,用于加速不同列的查询。 查询性能: 聚集索引:由于数据行的物理顺序与索引顺序一致,查找速度较快。当按照聚集索引的列进行查询时,数据库引擎会按照索引的顺序直接定位到数据行,提高查询效率。 非聚集索引:查询时可能需要两次查找:先在索引中查找键值,再通过指针访问数据行。因此,查询速度可能相对较慢。 操作影响: 聚集索引:插入、删除和更新操作可能需要更多的磁盘I/O,因为可能需要移动数据行以保持物理存储顺序。 非聚集索引:对数据的插入、删除和更新操作影响较小,因为索引结构与数据存储顺序无关。 内存占用: 聚集索引:通常需要较少的内存来进行操作,因为数据行的物理顺序与索引顺序一致,减少了额外的索引存储需求。 非聚集索引:由于索引值和数据行是分开存储的,可能需要更多的内存用于操作。 应用场景: 聚集索引:适用于经常需要进行范围查询的场景,如主键查询,因为数据行的物理顺序与索引顺序一致,可以提高查询效率。 非聚集索引:适用于需要提高查询效率但不影响数据物理存储顺序的场景,如频繁进行查询但不修改的列上创建非聚集索引。 综上所述,聚集索引和非聚集索引在物理存储顺序、索引数量、查询性能、操作影响以及内存占用等方面存在显著差异。在选择使用哪种索引时,需要根据具体的业务需求和查询模式来决定。 - b+tree和b tree的区别
- 回答:
节点结构 B+树:在B+树中,所有数据都存储在叶子节点中,非叶子节点只存储键值而不存储数据。 B树:非叶子节点不仅存储键值,还存储数据。 - 什么是mysql的最左匹配原则
- 回答:
最佳左前缀法则:如果创建联合索引,那么遵循最佳左前缀法则,使用该索引时,where 条件从索引的最左列开始使用,不能跳过中间的列使用。 例如user表中建立联合索引 user_name,user_age,user_level。 场景1。正常使用索引 select * from user where username='tom' and user_age=17 and user_level ='A' 场景2.无法使用索引 , 因为索引的顺序为 username 第一位, 如果条件中没有username 则无法命中索引。 select * from user where user_age=17 and user_level ='A' - b+tree索引何时失效
- 回答:
MySQL索引在以下情况下会失效: 函数操作: 如果在查询中对索引列进行了函数操作,如LOWER、UPPER、CONCAT等,索引可能会失效。例如,WHERE LOWER(name) = 'john'会导致索引失效12。 数据类型不一致,隐式转换: 查询条件的字段类型与索引字段类型不一致时,索引可能失效。例如,索引字段是字符串类型,但查询条件是数值类型,这会导致MySQL进行隐式类型转换,从而使索引失效23。 使用不等号: 使用不等号(!= 或 <>)会导致索引失效,因为不等号无法利用索引的排序特性来快速定位数据。 LIKE模式匹配以通配符开头: LIKE '%abc'无法使用索引,因为MySQL需要对每一行进行扫描以查找匹配项。然而,LIKE 'abc%'可以使用索引,因为它可以利用前缀匹配23。 OR条件: OR条件如果涉及的字段都没有索引,或者只有部分字段有索引,会导致索引失效。例如,WHERE column1 = 'value1' OR column2 = 'value2',如果只有column1有索引,column2没有,则索引会失效。但如果OR两边的字段都有索引,索引则可能生效。 范围查询不使用复合索引的后续列: 例如,复合索引(a, b, c),如果查询条件是WHERE a = 1 AND b > 2,则索引不会使用到列c2。 - b+tree能存放多少数据
- 回答:
6 - 什么是索引下推
- 回答:
索引下推。重点是减少回表次数。 如果没有索引下推,那么查询过程为先查索引,然后回表后再根据where条件过滤。 如果有索引下推,那么查询过程为先查索引,然后判断where条件有没有包含索引字段,如果包含则进行过滤,然后再回表。 - innodb面试题
- innodb如何管理page页
- 回答:
free page :空闲page, 未被使用。 clean page :被使用page , 数据未被修改。 dirty page:脏页,数据已被修改。 主要是通过三个链表来管理page页。 1. free list 表示空闲缓冲区。free链表是把所有的Buffer Pool中的空闲页对应的控制快(数据描述)作为free链表中的一个个node节点。 当一个缓存页被使用后就会从free链表中移除。 基节点:free 链表中只有一个基节点是不记录缓存页信息的。里面存了头节点的地址,未节点的地址和有多少个缓存页。 2. flush list 表示需要刷新到磁盘的缓存页链表。内部是按照修改时间排序的。 innoDb为了提高效率,每次修改数据都不是直接修改磁盘,而是修改bufferpool里的缓存页。修改后为脏页。后续会将脏页刷盘。 3. lru list 表示正在使用的缓冲区。管理cleanPage和dirtyPage。缓冲区以midpoint为基点。前面链表称为new 列表区。存放经常存放的数据,占63%。后面的链表称为old数据区,占37%。 - 描述mysql的mvcc
- 回答:
21 - 数据库事务面试题
- 什么是事务的ACID
- 回答:
原子性(Atomicity) :事务是一个不可分割的工作单元,要么全部成功执行,要么全部不执行。如果事务中的任何操作失败,则整个事务将被回滚到初始状态,就像这个事务从未执行过一样。 一致性(Consistency) :事务必须使数据库从一个一致状态转换到另一个一致状态。这意味着事务的执行不会破坏数据库的完整性约束,例如数据类型、外键约束等。 隔离性(Isolation) :事务的执行是独立的,不会被其他事务干扰。每个事务都像是在独立的环境中运行,从而避免了并发操作带来的数据不一致问题。 持久性(Durability) :一旦事务提交,其对数据库的更改就是永久性的,即使在系统故障或崩溃后,这些更改也不会丢失。 - 事务的隔离级别有哪些
- 回答:
2 - 描述事务的脏读、脏写、幻读、不可重复读。
- 回答:
1.脏写 两个事务同时写一条数据。 A事务 将字段name 从 null -> 小明 B事务 将字段name 从 小明 ->张无忌 此时事务b完成。 事务A回滚,然后执行undo log。 然后将数据回滚成了null 。 事务b因此看到了不符合预期的数据。 2.脏读 A事务 将字段name 从 null -> 小明 B事务 读取字段name 小明 然后B事务用小明做若干操作。 但是A回滚了。 3.不可重复读 A事务读取一条数据,name=小明 B事务更改此数据,并提交 name = 张无忌 A事务读取一次, 变成了张无忌。 C事务更改此值 name = 罗纳尔多 A事务读取一次, 变成了罗纳尔多。 可重复读的表现: A 三次都是读取 小明 不可重复读的表现:A->小明 B->张无忌 c -> 罗纳尔多。三次读取的都是不同的值。 默认为 不可重复读 幻读 A事务:select * from table where id >10 。 查询出10条数据 事务B 又插入了俩条数据。 事务A又再次查询,发现查出了12条数据,与之前的不一样,此种称为幻读 - 分布式事务面试题
- redis面试题
- redis的基础面试题
- redis效率为何高
- 回答:
* 纯内存处理。 * 单线程避免上下文切换。 * 将近式hash 如果扩容的话需要将全数组链表都进行扩容,这样比较消耗时间。 为了避免这个问题,Redis 采用了渐进式 rehash。 首先、Redis 默认使用了两个全局哈希表:哈希表 1 和哈希表 2。一开始,当你刚插入数据时,默认使用哈希表 1,此时的哈希表 2 并没有被分配空间。随着数据逐步增多,Redis 开始执行 rehash。 1、给哈希表 2 分配更大的空间,例如是当前哈希表 1 大小的两倍 2、把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中 3、释放哈希表 1 的空间 在上面的第二步涉及大量的数据拷贝,如果一次性把哈希表 1 中的数据都迁移完,会造成 Redis 线程阻塞,无法服务其他请求。此时,Redis 就无法快速访问数据了。 * 缓存时间戳 我们平时使用系统时间戳时,常常是不假思索地使用System.currentTimeInMillis或者time.time()来获取系统的毫秒时间戳。Redis不能这样,因为每一次获取系统时间戳都是一次系统调用,系统调用相对来说是比较费时间的,作为单线程的Redis承受不起,所以它需要对时间进行缓存,由一个定时任务,每毫秒更新一次时间缓存,获取时间都是从缓存中直接拿。 - redis的数据结构和底层原理
- 回答:
3 - redis内存删除方式
- 回答:
1、定期:定时扫描。过期字典随机扫描 2、惰性:用户查的时候再删。为了就是删除定期删除时未被删除的信息。 - redis内存淘汰策略
- 回答:
noeviction:不会逐出任何数据,当内存不足时,新的写请求会被拒绝。 volatile-lru:逐出设置了过期时间的key中最近最少使用的数据。 volatile-lfu:逐出设置了过期时间的key中最近使用次数最少的数据。 volatile-ttl:逐出设置了过期时间的key中将要过期的数据。 volatile-random:随机逐出设置了过期时间的key中的数据。 allkeys-lru:逐出所有key中最近最少使用的数据。 allkeys-lfu:逐出所有key中最近使用次数最少的数据。 allkeys-random:随机逐出所有key中的数据。 实现细节:Redis使用近似LRU算法来实现内存淘汰。通过给每个key增加一个额外的小字段来记录key最后一次被访问的时间,当需要淘汰数据时,Redis会随机采样一定数量的key,并淘汰其中最旧的key。 - redis事务是如何实现的
- 回答:
multi命令开启事务。 exec执行事务。 但是事务比较弱,如果之前执行了,则后面出问题, 前面的也不会回滚。 执行原理。执行multi后会将命令放到一个后台队列里, 但是不执行, 当执行exec时会将队列里的数据顺序执行,如果后面某个命令执行失败了,则前面的也不会执行。 - redis的持久化方式
- 回答:
Redis的持久化机制主要包括RDB(Redis DataBase)和AOF(Append Only File)两种方式,它们各有优缺点,适用于不同的场景。 技术原理和触发机制 RDB:RDB通过将Redis在内存中的数据库记录定时dump到磁盘上的二进制文件中,实现数据的持久化。这个过程可以理解为对Redis内存数据的快照。Redis会fork一个子进程来完成RDB的持久化操作,主进程可以继续处理客户端请求,不会受到持久化操作的影响。 AOF:AOF通过将Redis服务器执行的每个写操作记录到一个日志文件中,采用追加的方式写入。AOF文件保存了Redis数据库的完整状态,使得可以从任意时间点进行数据恢复。 优点和缺点 RDB: 优点:文件体积小,恢复速度快,对系统性能影响小。 缺点:数据安全性相对较低,可能会丢失最后一次快照后的数据。 AOF: 优点:数据安全性高,可以实时保存数据,适合对数据安全性要求高的场景。 缺点:文件体积较大,恢复速度较慢,对系统性能有一定影响。 使用场景 RDB:适合用于定期备份和数据恢复,适合对数据实时性要求不高、恢复速度要求高的场景。 AOF:适合需要更高数据安全性、能够接受较大存储空间的场景 - redis的集群面试题
- redis的Clutes模式的分片算法
- 回答:
Redis Cluster 使用了一种称为“槽(slot)”的机制来实现数据分片。Redis Cluster 将所有的数据分成 16384 个槽(slot),每个键值对根据其 key 的 CRC16 校验和来决定它属于哪个槽。 2. 槽分配 在 Redis Cluster 中,每个节点负责维护一部分槽,通常每个节点负责一部分槽的集合。例如,一个包含三个节点的集群可能会这样分配槽: 节点 A 负责槽 0 到 5000 节点 B 负责槽 5001 到 10000 节点 C 负责槽 10001 到 16383 3. 键到槽的映射 键到槽的映射是通过计算键的 CRC16 值,然后将这个值对 16384 取模来实现的。例如,如果有一个键 key1,它的 CRC16 值是 2345,那么 key1 就会映射到槽 2345 % 16384 = 2345。 4. 重新分片 Redis Cluster 支持动态重新分片,即在不停止服务的情况下,可以在线重新分配槽到不同的节点。这通过 Redis Cluster 的管理命令如 MIGRATE 和 CLUSTER SETSLOT 来实现。 5. 数据迁移 当需要对槽进行重新分配时(例如添加或删除节点),Redis Cluster 会自动将数据从一个节点迁移到另一个节点。迁移过程是自动进行的,并且对用户透明。 6. 故障转移 Redis Cluster 还提供了自动的故障转移机制。如果一个节点因为某些原因(如硬件故障或网络问题)变得不可用,集群会自动将该节点负责的槽分配给其他健康的节点,确保系统的持续可用性。 7. 使用和管理 添加或删除节点:可以通过命令如 CLUSTER MEET、CLUSTER FORGET 来添加或删除节点。 手动重新分片:使用 CLUSTER SETSLOT 和 MIGRATE 命令可以手动重新分配槽。 查询集群状态:使用 CLUSTER INFO 和 CLUSTER NODES 等命令可以查看集群的状态和配置。 结论 通过上述机制,Redis Cluster 提供了一个高度可扩展、高可用性的数据存储解决方案。开发者可以轻松地在多个节点之间分配和迁移数据,同时保持系统的稳定性和性能。 - redis的部署方式有哪些?
- 回答:
Redis主要有以下几种部署方式:单机模式、主从模式、哨兵模式和集群模式。 单机模式 单机模式是Redis最基本的部署方式。在这种模式下,Redis仅在一台服务器上运行,所有的读写操作都在这一台服务器上完成。这种部署方式非常简单,因为不需要配置其他服务器,但存在单点故障的风险,如果这台服务器出现问题,整个系统将会停止工作。 主从模式 主从模式是为了解决单机模式的单点故障问题而设计的。在这种模式下,一个Redis服务器被指定为主服务器(Master),其他的Redis服务器则被指定为从服务器(Slave)。主服务器可以执行读写操作,并将更新的数据同步到从服务器。从服务器只能执行读操作,数据由主服务器同步过来。这样,即使主服务器发生故障,从服务器也可以接管主服务器的工作。 哨兵模式 哨兵模式是为了解决主从模式中主服务器故障切换问题而设计的。在这种模式下,一个或多个Redis服务器被指定为哨兵服务器。哨兵服务器的主要工作是监控主服务器的状态,并在主服务器发生故障时,自动将从服务器切换为主服务器。哨兵模式提高了系统的可用性,但配置相对复杂,需要额外的哨兵节点。 集群模式 集群模式是为了解决单个Redis服务器内存有限的问题而设计的。在这种模式下,多个Redis服务器组成一个集群,每个节点保存部分数据。当一个节点无法存储更多数据时,系统会自动将一部分数据迁移到其他节点上。 - redis集群何时不可用,如何避免
- 回答:
9 - spring面试题
- spring如何解决循环依赖
- 回答:
循环依赖主要是通过三级缓存解决。 缓存名称 描述 singletonObjects 一级缓存:存储完全初始化好的单例 Bean(可直接使用)。 earlySingletonObjects 二级缓存:存储提前暴露的 Bean(已实例化但未完成属性填充和初始化)。 singletonFactories 三级缓存:存储 Bean 工厂对象(用于生成未初始化 Bean 的早期引用)。 流程步骤。 步骤 1:创建 Bean A 1.实例化:调用构造函数创建 Bean A 的实例(此时对象未初始化)。 2.提前暴露引用:将 Bean A 的工厂对象(ObjectFactory)放入 三级缓存 singletonFactories。 3.属性填充:尝试为 Bean A 注入 Bean B。 步骤 2:创建 Bean B 1.实例化:调用构造函数创建 Bean B 的实例。 2.提前暴露引用:将 Bean B 的工厂对象放入 三级缓存。 3.属性填充:尝试为 Bean B 注入 Bean A: a.检查 一级缓存 singletonObjects → 无。 b.检查 二级缓存 earlySingletonObjects → 无。 c.从三级缓存获取工厂对象,生成 Bean A 的早期引用,并将此引用移动到 二级缓存。 d.将 Bean A 的早期引用注入到 Bean B。 步骤 3:完成 Bean B 的初始化 1.属性填充完成:Bean B 获得 Bean A 的早期引用。 2.初始化:执行 Bean B 的初始化方法(如 @PostConstruct)。 3.移入一级缓存:将完整的 Bean B 放入 singletonObjects,并清除二、三级缓存中的 Bean B。 步骤 4:完成 Bean A 的初始化 1.属性填充完成:Bean A 获得完整的 Bean B。 2.初始化:执行 Bean A 的初始化方法。 3.移入一级缓存:将完整的 Bean A 放入 singletonObjects,并清除二、三级缓存中的 Bean A。 4. 关键机制 1.提前暴露对象:通过三级缓存暴露未初始化的 Bean 实例,打破循环依赖。 2.缓存升级策略:Bean 的引用从三级缓存逐步升级到一级缓存,确保最终使用完全初始化的 Bean。 5. 局限性 1.仅支持单例模式:原型(Prototype)作用域的 Bean 无法解决循环依赖,因为 Spring 不缓存原型 Bean。 2.构造器注入不适用:若循环依赖通过构造器注入,无法解决(实例化前无法暴露引用) - lazy 是否能解决构造器循环依赖
- 回答:
23 - spring的bean的生命周期
- 回答:
1.推断构造方法,通过反射实例化bean对象,对象里的值都是默认值。 2.填充对象属性,populateBean方法,就是依赖注入 3.检查aware相关接口的实现类和设置相关依赖。因为spring中的类分为俩类,一类是spring自定义的一些类,另外一部分是自定义的类,aware的主要目的就是将spring中的类对象能让自定义的类对象进行使用。 4.beanPostProcessor的前置处理。可用PostConstruct注解处理。主要是为了初始化时增强bean。 5.检查是否是InitializingBean的子类,来决定是否调用afterPropertiesSet方法。如果实现这个类就调用afterPropertiesSet方法。 6.检查是否有配置的init-method方法。 7.执行beanPostProcessor的后置处理方法,主要是aop。 8.注册必要的 destruction注解 - beanFactory,applicationContext,factoryBean
- 回答:
34 - spring aop的实现原理
- 回答:
21 - autowired 和 resource的区别
- 回答:
32 - spring的事务隔离级别
- 回答:
23 - spring的事务传播属性
- 回答:
12 - spring事务的实现原理
- 回答:
32 - spring常用的注解有哪些
- 回答:
3 - spring常用的设计模式有哪些
- 回答:
23 - spring支持哪几种作用域
- 回答:
21 - spring boot面试题
- 描述spring boot的自动装配功能
- 回答:
33 - 描述spring boot的start机制
- 回答:
4 - spring boot的启动原理
- 回答:
5 - kafka面试题
- kafka的核心组件都有哪些,作用是什么。
- 回答:
21 - kafka副本leader选举的过程
- 回答:
21 - kafka如何保证不丢失消息
- 回答:
21 - kafka零拷贝原理
- 回答:
12 - 计算机基础知识
- 什么是零拷贝
- 回答:
12 - tcp三次握手和四次挥手
- 回答:
32 - http和https的区别
- 回答:
12