hashmap扩容采用2的n次方倍,是为了通过位运算hash & (n-1)高效替代取模运算,并确保扩容时元素仅需判断高位比特即可定位至原索引或原索引+旧容量,大幅降低rehash开销。

Java基础面试题的高频痛点,不是知识点记不牢,而是“知道但讲不透”“能写但说不清为什么”。比如HashMap扩容、线程安全实现、AOP原理这些题,很多人背了答案却过不了关——因为面试官要听的是你对设计动机、权衡取舍和真实场景的理解。
HashMap:别只答“数组+链表+红黑树”
重点不在结构本身,而在设计背后的工程判断:
- 为什么链表长度到8才转红黑树?不是拍脑袋定的——这是泊松分布算出来的概率阈值(哈希均匀时,链表长度≥8的概率≈0.00000006),说明哈希已严重失衡,必须降维处理
- 为什么扩容是2的幂?为了用
(n-1) & hash替代hash % n,位运算快得多;同时保证扩容后元素只可能在原位置或原位置+旧容量,减少rehash开销 - JDK7并发扩容死循环怎么来的?多线程同时触发resize,头插法导致链表成环——这说明线程安全不能靠“看起来没问题”,得看底层操作是否原子
线程安全集合:ConcurrentHashMap 不是“无锁”
很多候选人误以为它完全不用锁。其实关键在“锁粒度”和“场景适配”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- JDK8之后,
put操作先用CAS尝试插入;冲突时只对当前桶的头节点加synchronized,不影响其他桶 -
get不加锁,靠volatile修饰val和next字段保证可见性——这是读多写少场景下的经典优化 -
size()返回近似值,因为精确统计需全局遍历,会牺牲性能;真要强一致性,得用mappingCount()
AOP:别光说“横切关注点”,要讲清“谁在什么时候干了什么”
面试官想确认你真用过,不是只会抄注解:
- Spring AOP本质是动态代理:接口用JDK代理,类用CGLIB;代理对象在目标方法前后织入增强逻辑
- @Transactional生效的前提:必须走代理对象调用(即不能本类内方法直接调用),否则事务切面根本没机会介入
- 实际项目里,我们用AOP统一处理接口耗时打点,但排除健康检查路径(/actuator/**)——说明你会配置切入点,不是无脑全包
String、Integer等包装类:考点在常量池与缓存策略
看似简单,一问就露馅:
- String s1 = "abc"; String s2 = "abc"; → s1 == s2 为true,因为字面量进字符串常量池,复用同一对象
- Integer i1 = 127; Integer i2 = 127; → i1 == i2 为true;但Integer i3 = 128; Integer i4 = 128; → i3 == i4 为false——因为IntegerCache默认只缓存-128~127
- new String("abc")一定新建对象,不管常量池有没有;而"abc"一定优先查池
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










