# 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 形成滞回,避免反复切换 ✓ 正确答案