源码阅读高频(HashMap/ConcurrentHashMap/Spring)

共 20 题
#

1. HashMap 的 treeifyBin 阈值 8 与扩容阈值 0.75 的设计依据分别是什么?

A 负载因子 0.75 表示空间利用率越高越好
B 树化阈值 8 依据泊松分布,理想哈希下链表长度达到 8 概率极低 ✓ 正确答案
C 树化只认链表长度,不要求数组长度达到 64
D 负载因子越大,冲突越少
#

2. ConcurrentHashMap 的 size() 为什么用 CounterCell 数组,与 LongAdder 的关系?

A CounterCell 数组把计数分散到各单元,减少写竞争 ✓ 正确答案
B size() 返回精确的实时值
C CounterCell 与 LongAdder 无关
D 单一计数器在高并发下竞争更少
#

3. HashMap 1.7 与 1.8 的关键差异,头插改尾插、引入红黑树、扩容时高低位拆分,分别解决了什么问题?

A 1.7 引入红黑树
B 1.8 改尾插,避免并发扩容时形成环形链表 ✓ 正确答案
C 高低位拆分需要重新计算所有哈希
D 1.8 是线程安全的
#

4. HashMap 为什么线程不安全,JDK 1.7 死循环(环形链表)、1.8 数据覆盖,ConcurrentHashMap 如何避免?

A 1.8 已完全线程安全
B 1.7 并发扩容可能形成环形链表导致死循环 ✓ 正确答案
C ConcurrentHashMap 用全局锁保证安全
D 1.8 数据覆盖问题不存在
#

5. Spring Bean 生命周期中 Aware 接口、BeanPostProcessor 与 InitializingBean 的执行顺序?

A Aware 回调发生在初始化之后
B InitializingBean 在 BeanPostProcessor 前置与后置之间执行 ✓ 正确答案
C AOP 代理在 postProcessBeforeInitialization 生成
D BeanPostProcessor 在属性填充之前执行
#

6. Spring AOP 的代理选择,JDK 代理 vs CGLIB 在什么条件下自动切换?

A 目标有接口默认用 JDK 代理,无接口用 CGLIB ✓ 正确答案
B CGLIB 能代理 final 方法
C JDK 代理不要求接口
D proxyTargetClass 只能关掉 CGLIB
#

7. ConcurrentHashMap 的 get 为何无锁,volatile 数组引用与 Node 字段的可见性保证,读取期间并发修改的安全性

A 依赖数组引用与 Node 字段的 volatile 保证可见性 ✓ 正确答案
B get 会加锁避免读到脏数据
C Node 的 next 不是 volatile
D 扩容时 get 会读到损坏数据
#

8. Spring @Configuration 的 CGLIB 代理,full/lite 模式判定,为什么 @Bean 方法互相调用能保持单例

A 只有 @Component 才触发 CGLIB 代理
B lite 模式也保证 @Bean 单例
C full 模式用 CGLIB 代理,保证 @Bean 方法互相调用返回单例 ✓ 正确答案
D full 模式不代理 @Bean 方法
#

9. ConcurrentHashMap 1.7 分段锁与 1.8 CAS+synchronized 的演进,锁粒度、扩容并发、size 计数的差异如何?

A 1.7 用 CAS 锁桶头
B 1.7 也支持多线程协助扩容
C 1.8 size 用 Segment.count 累加
D 1.8 锁粒度从段级降到桶级,并发度更高 ✓ 正确答案
#

10. ThreadLocal 源码,ThreadLocalMap 的弱引用 Key 与内存泄漏,为什么建议用完 remove?

A 用完 remove 会增加泄漏
B 弱引用 key 保证 value 也能被回收
C 弱引用 key 被回收后 value 仍可能残留,故需 remove ✓ 正确答案
D 线程池线程复用不会泄漏
#

11. String 源码,hashCode 缓存、equals 优化与 compareTo 的字节比较

A hashCode 缓存利用 String 不可变,重算一次后复用 ✓ 正确答案
B equals 先比较长度再比较引用
C compareTo 比较的是对象引用
D String 可变,所以 hash 不能缓存
#

12. ReentrantLock 源码,AQS 的入队/唤醒(unparkSuccessor)与公平/非公平锁的差异

A 非公平锁获取时不检查队列,可能插队 ✓ 正确答案
B 公平锁更高效
C unparkSuccessor 从队首向后找取消节点
D 公平锁先到先得因此吞吐更高
#

13. Spring 循环依赖的解决,三级缓存(singletonObjects/earlySingletonObjects/singletonFactories)为何需要第三级?

A 二级缓存就能完整支持 AOP 代理
B 第三级 ObjectFactory 用于在早期引用阶段支持 AOP 代理 ✓ 正确答案
C 构造器注入也能解决循环依赖
D 三级缓存用于原型作用域
#

14. ConcurrentHashMap 的扩容,多线程协助迁移与 sizeCtl 的作用如何?

A ForwardingNode 用于存储数据
B 扩容只能由单线程完成
C sizeCtl 为负数表示扩容中,多线程可协助迁移 ✓ 正确答案
D sizeCtl 只在初始时使用
#

15. HashMap 的扰动函数(hash 高低位异或)与 tableSizeFor 容量计算

A 扰动函数用于树化
B tableSizeFor 返回任意容量
C 扰动函数让高位参与低位计算,降低冲突 ✓ 正确答案
D 容量不一定是 2 的幂
#

16. ConcurrentHashMap 的 put 流程,空槽 CAS、链表头 synchronized、冲突升级与树化的触发路径

A 所有 put 都需要加锁
B 空槽用 CAS 放入,非空槽对链表头加 synchronized ✓ 正确答案
C 树化只需链表长度达到 8
D 遇到 ForwardingNode 直接插入
#

17. Spring 容器 refresh() 的核心阶段,BeanFactoryPostProcessor 与 BeanPostProcessor 的注册与执行时机

A BeanPostProcessor 在 BeanDefinition 修改前执行
B BeanFactoryPostProcessor 在 Bean 实例化前执行,用于修改 BeanDefinition ✓ 正确答案
C 单例实例化在 registerBeanPostProcessors 之前
D BeanFactoryPostProcessor 每个 Bean 都执行一次
#

18. ArrayList 的 modCount 与 fail-fast 机制如何与迭代器协作?

A 迭代器通过比较 expectedModCount 与 modCount 检测并发修改 ✓ 正确答案
B fail-fast 能保证检测所有并发修改
C 迭代器自身 remove 会误报
D modCount 只在迭代时递增
#

19. ArrayList 的扩容策略,1.5 倍扩容与 System.arraycopy 的性能影响如何?

A 预分配容量会增加扩容次数
B System.arraycopy 是 O(1) 操作
C 扩容倍率越大浪费越少
D 1.5 倍扩容在内存浪费与扩容次数间平衡 ✓ 正确答案
#

20. HashMap 的树与链表切换,为什么反树化阈值是 6 而非 8(滞回设计),退化时如何重建链表

A 反树化时直接丢弃节点
B 树化和反树化应用同一阈值
C 滞回设计让切换更频繁
D 反树化阈值 6 与树化 8 形成滞回,避免反复切换 ✓ 正确答案