Java面试中总有一些题被反复问,候选人觉得“太简单”,面试官却用它快速筛人。原因很现实:这些题看似基础,却能暴露你是否真正理解Java的设计哲学。以下10道被问烂的题,答错3道,基本宣告面试失败。
1. String、StringBuilder、StringBuffer的区别?
String不可变,每次拼接产生新对象;StringBuilder可变、线程不安全、性能最高;StringBuffer可变、线程安全、方法加synchronized。答错“StringBuffer比StringBuilder快”直接挂,因为混淆了安全与性能的取舍。
2. ==和equals的区别?
==比较基本类型的值或引用地址;equals默认比较地址,但String、Integer等重写后比较内容。必须补充:重写equals必须重写hashCode,否则HashMap中会出现两个“相等”的key。只答“一个比地址一个比内容”不够,面试官会追问hashCode契约。
3. HashMap的底层原理?线程安全吗?
JDK8后是数组+链表+红黑树,链表长度≥8且数组长度≥64转红黑树,扩容2倍。线程不安全,多线程扩容可能形成循环链表(JDK7)或数据丢失。答“线程安全”或“用HashTable替代”说明没有并发实战经验。
4. ArrayList和LinkedList的区别?
ArrayList基于动态数组,随机访问O(1),增删慢;LinkedList基于双向链表,随机访问O(n),增删快。但实际开发中ArrayList更常用,因为CPU缓存友好。若只背“一个数组一个链表”,不提及使用场景,会被认为缺乏判断力。
5. JVM内存区域与GC Roots?
必须准确说出:程序计数器、虚拟机栈、本地方法栈、堆、方法区(元空间)。GC Roots包括虚拟机栈引用、静态属性、常量、本地方法栈引用。答漏“本地方法栈”或把“方法区”说成“永久代”,暴露知识停留在JDK7。
6. 线程池核心参数与执行流程?
七个参数:corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。流程:核心线程→队列→最大线程→拒绝策略。面试官必问:“无界队列会怎样?”答不出OOM风险,说明没配过线程池。
7. synchronized和ReentrantLock的区别?
synchronized是JVM层面,自动释放,非公平;ReentrantLock是JDK层面,手动释放,支持公平锁、条件队列、中断响应。AQS核心是state+CLH队列。答“ReentrantLock性能更好”已过时,JDK6后synchronized优化后差距不大。
8. Spring Bean生命周期与循环依赖?
生命周期:实例化→属性赋值→初始化→销毁,BeanPostProcessor贯穿其中。循环依赖靠三级缓存解决,但必须解释:一级成品,二级半成品,三级ObjectFactory。只答“三级缓存”而说不清为什么需要三级,直接挂。
9. MySQL索引为什么用B+树?事务隔离级别?
B+树矮胖、叶子链表、范围查询高效。隔离级别:读未提交、读已提交、可重复读、串行化。MVCC通过undo log+ReadView实现,RC每次查询生成ReadView,RR第一次查询生成。答“RR完全解决幻读”不准确,需补充间隙锁。
10. Redis缓存穿透、击穿、雪崩的区别?
穿透:查不存在的数据,用布隆过滤器或空值缓存;击穿:热点Key过期,用互斥锁或永不过期;雪崩:大量Key同时过期,用随机过期时间+高可用集群。混淆三者,说明没处理过线上缓存问题。
结语
这10道题之所以被问烂,是因为它们覆盖了Java后端的地基:字符串、集合、JVM、并发、框架、数据库、缓存。答错3道,不是运气差,而是基础存在系统性漏洞。面试官不是刁难,而是这些点一旦在生产环境出错,就是OOM、死锁、数据不一致。准备时不要死记硬背,多问“为什么这样设计”“代价是什么”。地基不牢,地动山摇。