Skip to content

最近帮几个兄弟看简历、模拟面试,发现一个通病:大家的底子都不差,但一开口就是满满的“培训班味”

面试官问:“谈谈你对HashMap的理解?”

你答:“HashMap是一个基于哈希表Map接口实现,它允许null值和null键……”

停! 面试官听到第一句就已经想打哈欠了。这些定义书上都有,还要你说?

现在的行情,面试不是背书比赛,而是场景重现。今天咱们不整虚的,挑几个Java面试里的“硬骨头”,聊聊怎么答才能让面试官觉得:“这人是真干过活的,不是背题库的”

一、 关于集合:别只盯着扩容,聊聊“死法”

HashMap 肯定是必问的,但别一上来就背“数组+链表+红黑树”

建议怎么答:

生产环境的角度切入。

“HashMap我平时用得很多,但只有在局部方法或者单线程处理数据时用。如果是多线程环境,我肯定上 ConcurrentHashMap

我看过源码,JDK 1.7里HashMap在多线程扩容时容易出现死循环(环形链表),虽然1.8修了这个问题,但并发下还是会丢数据。”

高分点:

如果面试官追问 ConcurrentHashMap,千万别只背“分段锁”。你要说:“1.7的确是分段锁,但那太重了。1.8直接用了 CAS + synchronized 来保证并发安全,锁的粒度更细了,锁的是链表头节点。而且我看它源码里大量使用了 Unsafe 类直接操作内存,性能榨得很干。”

去培训班味: 加入版本对比,加入“为什么不安全”的具体后果,加入对源码实现的个人评价(比如“锁太重了”)。

二、 关于多线程:少谈概念,多谈“坑”

问到多线程,很多人喜欢背 JMM(Java内存模型)的图。什么工作内存、主内存……

建议怎么答:

直接拿Volatile开刀,结合硬件讲。
“多线程里最头疼的就是可见性问题。比如我有一个标志位 flag,一个线程改了,另一个线程死活读不到,这就是因为CPU缓存没刷新。加了 volatile,底层就是加了内存屏障(Memory Barrier),强迫CPU把数据刷回主存,并让其他核心的缓存失效(MESI协议)。但要注意,它不保原子性,像 count++ 这种操作,高并发下还是得用 AtomicInteger 或者加锁。”

高分点:
提到线程池时,别光背那7个参数。
你要说:“线程池的参数配置最考验经验。书上说CPU密集型设N+1,IO密集型设2N,但实战里根本不是这样。我们会先看监控,如果IO耗时特别长,线程数甚至要开到几十倍。而且,拒绝策略我一般不用默认的 AbortPolicy,而是自定义策略,把丢弃的任务记到日志或者发MQ里,防止业务数据静悄悄地丢了。”

去培训班味: 否定教科书的死板结论(如N+1配置),强调监控和兜底方案(自定义拒绝策略)。

三、 关于JVM:别背参数,讲讲你救火的故事

面试官问 JVM,不是让你背垃圾回收算法(标记清除、复制……),而是想看你会不会调优

建议怎么答:

构造一个场景。
“平时开发不太动JVM参数,但在上线大促或者处理报表导出时,我遇到过OOM。当时现象是服务频繁Full GC,CPU飙高。我没急着重启,而是先保留了堆转储文件(Dump)。
后来用MAT工具一分析,发现是有一个大对象(比如Excel导出列表)一直没被回收。后来调整了代码,改成分页查询流式写入,顺便把堆内存(Xmx)调大了一点,问题就解决了。”

高分点:
“其实比起GC日志,我更关注线上的 Arthas 这种工具。有时候不确定是不是代码逻辑卡死,直接上去 thread -b 看看有没有死锁,或者 trace 一下慢方法的耗时,这比盲猜参数有用多了。”

去培训班味: 讲故事(Storytelling),提及具体工具(MAT, Arthas),展示排查问题的思路,而不是背诵GC流程。

四、 关于MySQL:索引不是万能药

别只说 B+ 树,别只说“最左前缀原则”。

建议怎么答:

聊聊索引失效的痛苦经历。
“索引这东西,建好了是神,建不好是坑。我有次发现一条SQL特别慢,明明加了索引。后来一看执行计划(Explain),发现是因为我对索引字段做了函数计算(比如 DATE(create_time)),直接导致走了全表扫描。

还有那种 order by 导致的文件排序(Using filesort),也是因为没利用好联合索引。我的经验是,尽量让索引覆盖查询,少回表,这比什么都强。”

去培训班味: 用 ExplainFilesort回表 这些行话,结合具体写法错误(函数计算)来举例。

小结

技术面试的本质,是两个程序员在交流技术,而不是老师在考学生背书。展示你的思考过程,比展示正确的标准答案更值钱

祝兄弟们都能拿个满意的Offer,冲!

最后更新: