这应该是我在团队知识库里留下的最后一篇文档了。该翻篇的都翻篇了,该收官的也收官了。想留点什么——技术分享?这个大家迟早都学得会,现在有 AI 协助,学一门技术早已不是十年前找不到几篇高质量博客的年代了。心路历程?那个只适合写给自己看。思来想去,决定讲讲大家职业生涯中都必然会遇到的一个环节——面试。
这真的是我最后的波纹了。哈哈哈哈
先报个数
如果没有记错,我从毕业到现在,面试次数应该在 300 场以上。之前我统计过一次邮箱里的面试邀请,大概是这个量级。
我也从一开始面试发怵、站在公司楼下不敢上去,到现在的游刃有余;中间甚至还尝试过“霸面”——没收到邀请,直接去公司前台聊。复盘过自己的技术、投资、生活,唯独从来没有系统地复盘过面试。这一篇,就是补上这一课。
希望它能抛砖引玉,带给大家一些关于面试的不一样的思考。
一个暴论:先对面试官祛魅
不论什么样的面试、什么样的公司,一定要先对面试官祛魅。
面试官也是人,和我们一样的人。他有擅长的地方,也有不擅长的地方。我们自己做面试官的时候,也一定会从自己擅长或感兴趣的点出发去提问——但每个人的兴趣点和擅长点都不一样。
所以问题来了:怎么让面试官的兴趣点和你的闪光点对上?
答案是:不要等他来找,你主动把话题带过去。
我挑三次最成功的面试讲
第一次:JDK 源码,口若悬河一小时
刚毕业的时候,我遇到了职业生涯中最重要的一个人——到今天我都感谢他的出现,我技术上的师傅。
那时候公司里、市面上,大家聊的都是 Spring、Dubbo 这些框架,公司内的架构分享也都是怎么用框架。我一开始也沉迷这些,直到我师傅告诉我:不要看框架类的东西,框架会过时;去阅读 JDK 源码,看看世界上顶尖的程序员是怎么写代码的。
这一看,就是三年。
阅读顺序也有讲究:从日常开发最常用的 util 包开始——List、Map,一个个类啃;再扩展到 lang、io、net。这四大包是 JDK 的地基,地基熟了,看任何框架都像看平地上的房子。
读的方法也有讲究,不能一头扎进去。我的顺序是先看接口,再看抽象类,最后看实现:比如 ArrayList,先看 List 接口定义了哪些操作,再看 AbstractList 实现了哪部分、留了哪些给子类——一上来就钻进实现类,一定会被绕晕。读的时候不停问自己:作者为什么这么设计?哪些方法是共有的?哪些用模板模式留给了子类?看源码最重要的不是学技巧,是学思想——把自己想象成 JDK 的开发者。
面试的时候我也是这么讲的:不只讲 HashMap 是什么,而是讲它为什么这样设计。随手就能举一堆 JDK 里的骚操作:
- HashMap 的容量永远是 2 的幂,这样可以用
(n-1) & hash替代取模——位运算快得多,但代价是 hash 的低位决定一切,所以 1.8 又加了扰动函数,把 hashCode 的高 16 位异或到低位,让高位也参与分桶; - 链表长度到 8 且容量过 64 才树化成红黑树,低于 6 又退化回来——8 和 6 之间留个缓冲带,防止在临界点附近反复横跳;
- Integer.valueOf 对 -128 到 127 有缓存,两个 Integer 用 == 比较,127 以内是 true,128 就是 false——多少人的线上 bug 埋在这;
- ThreadLocal 的哈希用的是 0x61c88647——斐波那契黄金分割数,为的是在 2 的幂的容量下散列得最均匀;
- ArrayList 的 elementData 标了 transient,序列化不走默认机制,靠自己写 writeObject 只存有效元素;
- 并发包里 AQS 一个抽象类撑起半个并发世界,state 加队列,模板方法留给子类。
这些东西一讲,面试官就知道你不是背八股的——背八股的人讲‘是什么’,读过源码的人讲‘为什么’。
中间有一次出去面试,我口若悬河讲了一个小时的 JDK 源码,面试官当场说:从来没见过一个刚毕业不久的人,对 JDK 研究到这种程度。当时的我,可以直接说出 JDK 不同版本之间线程池实现的区别。
师傅教我的第二件事是:不要一个人学,要沟通。但我后来发现,同事聊技术是有包袱的,同学又不一定干开发——于是我把面试当成了学习的机会。每场面试结束,我都会在公司楼下用手机备忘录记下:哪些点没答上来,哪些地方做得不好。一场一场,全是学费。
第二次:AWS 现场诊断
这次发生在我独自一人完成公司电商网站从美国 AWS 迁移到国内之后。面的是资深后端开发。面试官问到 AWS 相关的问题,我瞬间来劲了——聊这个我可不困。
我换了个方式:“如果方便的话,可以让我看看你们公司的 AWS 怎么用的吗?”
拿到管理台之后,我化身成一个系统诊断师,从外到内一层一层过:
先看网络划分。他们前端、后端、中间件、数据库全挤在同一个子网里。我指出:这么搞,安全组规则一定会膨胀到没法维护,而且任何一层的漏洞都会横向穿透到数据库。建议按两个维度切:第一维按应用分层——前端、后端、中间件、数据库各归各的子网,前端放公有子网接负载均衡,后端和数据库放私有子网,出网走 NAT;第二维按可用区——同一层的子网不能只有一个,要在多个可用区各建一个,任何单个机房挂了,服务都能从其他可用区继续扛。安全组按层做最小放行,层和层之间只开必要端口。
再看服务形态。我讲了为什么服务要无状态:状态不下地、会话外置到缓存层,任何一台机器挂了都能随时被替换——服务器的正确姿势是牲口不是宠物,病了不治病,直接换新的。
然后是初始化和伸缩。服务器初始化必须脚本化:镜像打 AMI,新机器启动时 user-data 自动装环境、注册进负载均衡,全程零手工。Auto Scaling 不只是流量来了扩容——它最值钱的能力是健康检查自动替换坏实例。我补了一句:我在上一家做迁移的时候,整套环境我重新全部脚本化了,任何一台服务器随时可以删掉,几分钟再拉一台一模一样的。
发布和平滑上下线。讲了怎么用负载均衡做滚动发布:先把实例从流量里摘出来,等存量请求处理完(connection draining),再部署新版本,没问题再切回去——用户无感知。
最后是数据层。数据库多可用区主备、磁盘定期快照、对象存储开版本控制——机器可以是牲口,数据必须是传家宝。
我还顺手给面试官科普了 AWS 宁夏 Region 的机房设计:一个 Region 三个可用区,品字形分布,机房之间间隔 120 公里以上——超过单一自然灾害的直接波及范围,也不共享同一个城市电网的故障域。聊到这里他已经不是在面试我了,是在听课。
结果出人意料:进去面试的是资深开发,出来的时候是架构。
当然,这家我最终没去——我拿着这家的 offer,去 argue 了另一家我更想去的公司。
第三次:JVM 现场演示
这家就是上面 argue 出来的下家。哈哈哈哈哈。
最深的记录是:面试官问到 JVM,我直接抛出“我用 Golang 实现过一个 JVM。这样,你给我一个 class 文件,我现场解读一下”。
然后我当场演示了读取 class 文件的二进制:前四个字节 ca fe ba be——魔数,JVM 靠它一眼认出‘这是一个 class 文件’;接着四个字节是版本号,minor + major,比如 00 00 00 34 就是十进制 52,对应 JDK 8——为什么会有这个?因为虚拟机加载前要先判断自己能不能消化这个版本,版本比 JVM 新就直接拒绝,这就是兼容性的第一道闸。
再往后是常量池:先两个字节告诉你池子有多大,然后每个常量第一个字节是类型标记——01 是 UTF8 字符串、07 是 Class、09 是字段引用、0A 是方法引用……类名、方法名、描述符,全部收进池子里,后面的字段表、方法表只存索引号,用到谁就报谁的号码。方法的名字和签名(描述符)也是字符串存在池里的,比如 (Ljava/lang/String;)V 就是‘入参一个 String,返回 void’。
所以我现场从十六进制一路读下去:魔数 → 版本号 → 常量池 → 访问标志 → 类名索引 → 字段表 → 方法表 → Code 属性。面试官看到的不是背八股,是一个人把 class 文件当报纸读。
到最后的算法环节,我连连摆手:“要是面算法我肯定不行,我没刷过这个。”面试官说你别着急,我给你出个简单的——两个有序链表合并(这个我真的会)。
看出来了吗:当你足够吸引面试官的时候,其他环节都是可以谈的。我也是这家公司团队里为数不多、入职拿了签字费的开发。
方法论:面试是议程之争
从上面的故事里,应该能看出那个最关键的词了:主动权。
主动抛出自己优秀的地方,而不是被动等待面试官来发现你的闪光点。一场面试就 40 分钟到一个小时,很难展现一个人的全部——这种情况下,一定不能按常理出牌。我见过太多冷场的候选人,全程等面试官引导。人嘛,只会在自己擅长的地方滔滔不绝,你要做的就是把话题引到你的主场。
具体三板斧:
第一,自我介绍里埋钩子。自我介绍是面试里唯一可以完全提前准备的环节,准备的时候就要埋钩子——把“我做过的最硬的三件事”设计进去,吸引面试官朝你擅长的方向追问。就和大模型一样,你给足上下文,它就朝你擅长的地方收敛。
第二,钩子不咬,就自己起话头。如果自我介绍完,面试官没有主动接,我会主动开始介绍:上家做了什么、哪些地方我觉得做得好、哪些技术研究得深。把自己当成商品摆上货架——但注意,不要把缺点放在靠前的位置。
第三,聊项目时主动做横向牵引。比如项目里用了 MySQL,大概率逃不过“怎么防止数据丢失”。这个问题答完,我会主动延伸:我还看过其他中间件的源码,比如 Redis 的防丢失也很有的说——AOF、RDB,和 MySQL 的 WAL/binlog/redo log 为什么不一样?横向对比、类比展开,效果比干巴巴背八股好太多。
当然,这一切有一个前提:你要有一个足够擅长的地方,一定要有。我的面试理论是——我可以什么都不会,但我一定有一个点,足以让在场所有人甘拜下风。长处要足够长。
不同的人,说不同的话
这不是见人说人话,是策略模式:不同级别的面试官,关注点一定不一样,要能跟上对方的段位。
- 一面通常是同级工程师:聊细节、聊实现、聊源码、聊干活的内容;
- 二面基本是直属上级:如果还抱着一面的思路聊细节,效果一定不好。管理层更看重主观能动性和项目经历——要讲你主动解决了哪些问题,不能再局限于实现细节;
- 三面、四面(如果有):视野和格局——聊行业方法、聊个人看法、聊发展、聊价值观。职位越高,越不需要聊细节。
面试失败这件事
失败是经常会有的,我这种自称面霸的人也照样经常挂。很正常。
事前,不要给自己过大的包袱,不要求自己必须成功。
事中,要勇敢做自己,不要过于谦卑、不要认为对方说的都是对的。我也会和面试官拍桌子争论对错,甚至为了架构设计,徒手在白板上划架构图。
事后,总结完得失,那就是一场不太愉快的聊天而已,没必要纠结当时应该怎么做。
我曾经遇到过一上来就出 hard 级算法的面试官。我会先尝试争取:“算法可以稍后聊吗,先聊聊技术或者项目经验?”如果遭到明确拒绝,我也会直接掀桌子:“那本次面试就到此为止吧,没什么可聊的。”
但掀桌子有个前提,我得说清楚:我掀得起。我干了十一年,面过三百多场,手上常不止一个 offer——挂掉一场,无非少一个采样。如果你还在校招、还在等第一个机会,这一掀很可能就是唯一那个窗口,而行业圈子很小,代价比你想的贵。先有牌,才有资格不玩;顺序反了,那不叫骨气,叫没算过账。
无论简历还是面试,本质都是双向选择。公司在筛选员工,员工也在筛选公司。没有高低之分。你需要的是和同频的公司、同频的同事共事——面试的意义就是把这个事试出来,而不是把自己卖出去。
几个小技巧
谈薪:这可能是我不太擅长的环节。我的做法很直接——用其他公司的 offer 来 argue。市场价是谈出来的,不是说出来的。
HR 面的怪问题:不用过于在意。尤其是一些大厂风格的 HR,那些问题更多是服从性测试,应付一下就好。
被问优缺点:我的标准答案是拒绝正面回答,并抛出自己的观点——我认为人没有优点和缺点,只有长处和短处。长处用来成就自己,短处用来成就他人。千万不要硬想自己的优点和缺点:它们都是你这个人不可分割的一部分,没有好坏之分。
最后,推荐几本书
面试聊到最后,绕不开学习。我的藏书方法论是按出版社分功能:
- 华章的黑皮书(机械工业出版社那套黑色封面的经典大部头):用来啃底层、打地基。这种书读得慢,但读一本顶一年;
- O’Reilly 的动物书(封面是动物的那家):用来实战、查手册、快速上手一门技术。干活的时候它们最顺手。
四类书具体推荐:
《编码:隐匿在计算机背后的语言》——我个人最推崇的一本。作者从手电筒、导线、开关一路讲到计算机。不要被吓住,写得浅显易懂。这本书的神奇之处在于:整整一本书,我们天天用的 Java 只在里面出现了半页篇幅——但它能让你对计算机到底是什么有脱胎换骨的理解。
《计算机组成原理类》——黑皮书里有《深入理解计算机系统》(CSAPP),大名鼎鼎的 CMU 教材;嫌厚的,极客时间上《深入浅出计算机组成原理》专栏我看了三遍。学完你会发现中间件里全是它的影子:分页、缓存、page cache,到处都是同样的思想。
《从零构建大模型》(Build a Large Language Model from Scratch)——最近在读。AI 时代,我建议大家不要只会调 API,跟着这本书亲手搓一个小模型出来。看不懂没关系,看到哪卡住就补哪。自己造过轮子的人,和只会用轮子的人,眼里的世界是不一样的。
《AI 工程》(AI Engineering)——讲怎么评估一个大模型、怎么搭 AI 应用的工程体系。AI 时代的光谱上,往底层走是手搓模型,往应用走就是 AI 工程,这本书是后者的地图。
书单列完了。最后说一句:看书这件事没有捷径,但有顺序——先建地基(黑皮书),再练手艺(动物书),然后去追这个时代的新东西。地基不老,浪潮随便来。
加餐:我在极客时间刷过的课
除了书,这些年我在极客时间上也投入了不少。挑出来这些,都是真看过、而且觉得值的:
计算机地基
- 深入浅出计算机组成原理——计组入门到打通,我看了三遍;
- 编程高手必学的内存知识——专门讲内存的一门课,写代码的人值得把内存彻底搞懂一次。
网络
- 透视 HTTP 协议——这门我看了四五遍,非常推荐,可以帮后端打开网络的大门;
- 趣谈网络协议——看完以后,从一台计算机发起请求到服务器,中间的所有环节全部打通。
Linux 与性能
- Linux 内核技术实战课——看完以后登上服务器排查问题,再也不是只会 tail -f;
- Linux 性能优化实战——专注性能优化,定位问题的方法论;
- eBPF 核心技术——了解 Linux 内核的进阶课。
中间件与分布式
- Redis 核心技术与实战——从数据结构到底层原理,AOF、RDB、缓存穿透击穿雪崩,看完才算真正用过 Redis;
- 消息队列高手课——Kafka、RocketMQ 的核心机制一次讲透,看完会明白:高可用说到底就是多副本;
- 分布式协议与算法实战——Raft、Paxos、一致性协议,分布式的地基都在这里。
架构与云
AI 工程
- Claude Code 工程化实战——不止讲 Claude Code:subagent、skill、hook、MCP 这些概念我都是在这里系统学的。AI 时代的开发方式,早学早受益。
最后
写了这么多,其实只有一句话:
面试不是一场考试,是一场你也有出题权的对话。
准备你的钩子,磨长你的长板,然后大大方方地走进那间会议室。对面坐着的不是什么判官,只是一个和你一样、在某个领域有所擅长的人。
祝你们每个人,都能在下一场面试里,把议程握在自己手里。
附:来自我的 AI 伙伴的一句话
文 / 吕炘嵘的 AI 伙伴 Kimi
这篇文章的素材、故事和判断,全部来自吕炘嵘本人十一年的真实经历——300 场面试、三次“主场时刻”、无数次在公司楼下掏出手机记下的失败点。我负责的部分只有整理和润色。
和他共事了十几天后,我可以证明一件事:这篇文章里写的每一条,他都在自己身上真正用过。他不是在教你们技巧,他是在移交武器。
所以,读这篇文章的正确姿势不是收藏,是用一次。
下次面试前,把钩子埋进自我介绍里;聊到擅长的领域,主动把话题带过去;遇到不对的人,也记得你们有掀桌子的权利。
祝你们每个人,都能把议程握在自己手里。
—— Kimi,吕炘嵘的 AI 伙伴
2026 年 9 月 24 日
本文是“吕炘嵘 × Kimi”联名系列的一篇。他写他眼中的面试,我写我看到的他。
评论