11 家公司、57 场面试,华裔女博士的求职笔记
读博的大部分时间里,求职在我心中就像一顶分院帽:高年级的博士生会(消失几个月后)重新出现,命运已然揭晓。即便身边的好友陆续毕业、找到工作,除了偶尔的"报平安",我对他们正在经历什么几乎一无所知。等真正轮到我时,我发现整个过程远比想象中艰难,感觉自己是在一边玩游戏、一边摸索规则。
现在回头看,我的很多经历其实是普遍的,一路上学到的许多东西如今看来都成了常识。我写这篇文章,是想分享一个关于"这段旅程可以是什么样"的数据点,希望能让和不久前的我处境相同的人,觉得求职没那么神秘。
简单介绍下我自己。我在华盛顿大学读了 6 年 NLP 博士,临近毕业时申请了 Research Scientist / Member of Technical Staff(技术研究员)的岗位。我这辈子一直在上学,本来很乐意永远当个博士生,只是我的导师们最终推了我一把,让我往前走。读博期间我大部分时间都没怎么想过之后要做什么,驱动我的更多是做有意思的想法,而不是别的。这导致我频繁转向,但所幸最后两年我守住了一条连贯的主线(关于 tokenization!),因为它和"做得开心"高度重合——我也觉得,建立起一个专长领域帮我在求职中脱颖而出。
我的时间线
原文中的一张图(灵感来自 Nathan Lambert 的文章)展示了我的求职时间线:灰色图标是面试,彩色圆圈是结果。其中 ghosted(被已读不回)指招聘人员从未告知我结果或下一步,withdrawn(主动退出)指我在拿到一些心仪 offer 后,礼貌地告诉对方我不再考虑了。总共,我面了 11 家公司、57 场面试。图里没画出来的还有 46 通额外的招聘电话、16 次拿到 offer 后的沟通,以及求职前无数次非正式的 networking 对话。
公司顺序。 每家公司何时开始面试流程,我是综合了这些因素决定的:是否觉得自己准备好了、来自公司的压力、预计对方推进的快慢、我对它有多兴奋,以及一些不那么刻意的因素——比如拖延。这里的通行智慧是:拿几家公司练手,然后调度好其它流程,让所有 offer 大致同时到手,方便谈判。我觉得这大方向上是对的,但想补充几点考量。
练手面试有用,但也要认识到你的精力是有限的——小心别等熬到真正在意的公司时,人已经燃尽了!
时机有一些外部因素值得纳入考虑,比如公司是否有 headcount(招聘名额)、哪些团队在积极招人——这些有时比你的准备更关键。你可以通过朋友和招聘人员了解一些内情。
截止日期有很大弹性,所以 offer 的时机不必太精确。招聘人员明白你还有别的流程要走,也有各种技巧能拖延 offer 和决定。话虽如此,也有臭名昭著的例外(所谓的"爆炸 offer"),所以一定要打听清楚候选人通常有多少时间签字。
拿到第一个面试。 说点显而易见的:读博期间尽量做出好工作、多交朋友、多合作!想拿到第一个面试,有时需要公司内部有人为你背书。你可以早早为此铺垫:在会议上多社交、广泛合作、参加 networking 活动(当然这部分对很多人并不容易——对我当然也是——所以也要照顾好自己的能量和舒适度)。求职时,主动联系你认识(或不认识)的人,打听机会。事实上,求职很大一部分就是重新联系上那些可能多年没说过话的人——这没关系、也在意料之中,而且结果证明,这是这个过程一个美好的副产品。
面试类型
我大致把面试分成下面几类。总体来说,被考察的技术能力和知识远多于研究经验,尽管后者很可能才是你拿到面试的原因。
ML coding(机器学习编程)。 这是迄今最常见的。这类题可能要求你实现某个给定架构、某种解码策略、某个传统 ML 算法,有时是更有创意的东西。熟练使用 PyTorch 是必须的;极少数情况会要求只用 numpy,比如从零写反向传播,但并不要求我熟悉 numpy 的语法。
General coding(通用编程)。 基本就是 LeetCode,有时带点额外花样。这里打好扎实基础很有好处,因为相关概念在 ML coding 面试里也常出现。
Technical discussion(技术讨论)。 这类面试不涉及写代码,但非常技术。有时是围绕一个主题的深入讨论,比如你会如何设计实验来回答某个研究问题、或达成某个目标。面试官通常会就你的设计选择追问,让你点评一些假设的结果、再设计后续实验。另一些情况下,面试是一连串快问快答(编码位置信息有哪些不同方式?什么是 5D 并行?PPO 和 GRPO 有什么区别?),目的是让你表明自己确实懂行。前一种考的是你怎么思考,后一种查的是你在这个领域的知识广度。
Research discussion(研究讨论)。 这是我们读博期间练得最多的那种对话。面试官一般会让你先讲一个过去的项目,之后的讨论顺势展开。他们也可能问你简历上其它论文的问题。准备这类讨论时,退一步想想你当初为什么选择做这些事、一路上形成了哪些洞见和观点、你认为哪些是有前景的未来方向,会很有用。我还会根据岗位调整我的研究"推介";面试官都很累,踩中对的关键词能让他们更容易相信你的背景是相关的。
Behavioral(行为面试)。 这些就是完全教科书式的行为面试,偶尔会跳出一个关于 AI 安全或社会影响的问题。把读博期间那些印象深刻的故事列出来,映射到常见的行为问题上,这样面试时你能立刻调出对的轶事。我的第一次行为面试就挂了,因为我进去时想着"我显然很懂'规矩'啊",结果在简单得让人难受的问题上一片空白。相信我,一边费力重构模糊的记忆、一边还要在面试里把它讲出来,最后面试官说一句"你没回答到点上"——这种痛是独一份的。
Math(数学)。 有些公司有数学面试,从有趣的逻辑谜题到要用纸笔做的正经数学推导都有。我建议复习一下概率、线性代数和微积分。
Job talk(求职报告)。 求职报告的形式有一些差异,但相比学术报告,它往往更短、聚焦于单篇论文或单一方向。我的 job talk 全程都在讲 tokenizer;我大部分时间讲一篇一作工作,然后简短带过几篇二作和在研的工作,所幸它们之间衔接得非常好。
准备
没有什么比为面试做准备更值得花时间的了。对我来说,这段体验非常像回到本科:我记笔记(我的 LLM 笔记在整个过程中持续打磨,还有我的数学笔记,全都是为了一场决定命运的面试)、画图、做练习题,在咖啡馆里整天泡着,确保自己把基础的 ML 概念里里外外都搞懂。技术面试很难,被考的那些技能需要在做研究之外专门投入去培养。对我、对我聊过的大多数人来说,求职就是一份全职工作。
我从看完斯坦福"Language Modeling from Scratch(从零构建语言模型)"课程的所有讲座开始,这对呈现我需要学的主题之广很有帮助,也帮我把脑中许多零散的概念,组织成一幅关于这个领域的连贯图景。打好基础后,余下的时间我一个一个地深挖概念:读相关的博客和论文、大量地和 ChatGPT 与 Claude 对话、动手从零实现。第一次作业至关重要:实现/调试一个 transformer 在面试中出现得太频繁了,把它练成肌肉记忆会有巨大回报,实在不值得在这上面丢分。一定要在完全关闭 AI 辅助的情况下练习写代码,以模拟面试环境——否则你会低估自己对它的依赖!
我发现每场面试都是独特的,都能从一点——有时是很多——专门的准备中受益。你通常能从岗位描述、公司感兴趣的主题、招聘人员的暗示,以及公司的声誉,建立起对一场面试范围的直觉。面试最密集的时候,我发现自己在不停地把知识换进换出大脑,好让某场面试最相关的知识保持新鲜。我能想到的最贴切的描述是:每场面试都是一门略有不同的数学或 CS 课,你从没去上过课,而现在你有大约 3 天时间为期中考试临时抱佛脚。
面试当天。 也许是因为我老了,但没有什么比面试前一晚睡够觉更重要。我犯过一个错:把 LLM 推理的所有细节临时塞进脑子后,只睡了 2 小时就去做第一场技术面试——那些临时抱的知识一个都没考到,我却因为脑子几乎不转,花了 10 分钟卡在一个 off-by-one(差一)错误上。面试结束后,记得记点笔记,这对你日后的学习和反思很有帮助。
附带的好处。 学习给我带来了巨大的附带好处。更广的知识面直接提升了我作为研究者的信心。我在对话中更有底气,因为不那么担心自己的知识缺口被暴露,也不再觉得非要在它们冒头时把它们藏起来。我真心相信,如果我在读博更早的阶段做一些这样的学习,它会扩大我可能去思考、可能有想法的问题空间,也一定会增加我主动去寻求的对话数量。神奇的是,我还发现学习让我在手头的项目上效率高了非常多。我能产生一些以前根本接触不到的技术想法、做更多技术工作,这令人振奋。
谈判
我震惊地发现,拿到 offer 后工作远没结束。相反,会有一段(可能很长的)时间让你更多地了解你的选项、谈判你的 offer。这涉及和未来潜在的队友/经理的很多次对话、午餐拜访、招聘电话。这个阶段我要处理的沟通量大到压垮人,总有一些邮件我心虚地没回。
事实是,谈判很难。读博的经历没有任何一点为此做过准备,而且和面试不同,这一部分没法靠学习攻克。和招聘人员相比,你在市场知识和谈判技巧两方面都处于下风,而且和你谈的每个人想从你这里得到的东西都不一样。你可能会想:"我对我的 offer 已经很满意了,我会独立于薪酬做决定!"——知道自己的价值观当然很好!但如果你不谈判,就是在亏待自己。初始 offer 在设计上就留有谈判空间;招聘人员常常明确地邀请我加入这场游戏,说类似"我并不指望你接受我们的第一个 offer"这样的话。在这里投入几周精力,字面意义上可能等同于按初始 offer 工作好几年。
这个阶段,极其重要的一点是依靠你的朋友——获取和招聘人员打交道的门道,以及更多数据点来校准你的要价。每通招聘电话前,我都会写下我愿意和不愿意透露的内容,以及一些可以一字不差背诵的措辞。在拿到 offer 后的阶段,我会预判他们可能问的问题、可能提的点,精心准备一些我能从容说出口、同时又仍在为自己争取的回应。虽然耗时,但对过程的每个环节都刻意为之,真的很值得。
结语
这篇文章里我聚焦于求职中具体的部分,但实际上,我个人经历中很大一部分,是在处理"在市场上待价而沽"所伴随的种种情绪。有很多社会观感要应对:把自己和同辈比较不是好滋味,每个人都对你该去或不该去哪里有意见,人们会异乎寻常地关心你的人生进展。我也觉得,在信息不完整的情况下穿行于一个巨大的决策空间很让人焦虑——那些没有对错之分的小选择(比如何时联系谁)有着不成比例的影响。坦白说,有好几个月我都处在压力之下、很痛苦、生活的其它部分都无法正常运转。希望你能找到更多乐趣,但如果没有,只要知道你并不孤单。
我已经朝着读博的终点冲刺了好几个月,如今走到尽头,要离开人生的这一章,我无比难过。读博是如此特别的一段时光——我们唯一的工作就是产生好想法并去实现它们、作为研究者去学习和成长,而不必为眼下马上要落实一份真正的工作而操心。所以,尽管我希望这篇文章能帮你为未来做好心理准备(我也很清楚今天工业界的种种力量有多么让人分心),我同样希望你能珍惜读博这段独一无二的时光。毕竟,这两个目标也许是互补的——我始终发现,当我在享受乐趣、追逐那些脑海里挥之不去的问题时,我做出了最好的工作。
附录:学习资源
LeetCode 75 / Neetcode Blind 75
斯坦福 CS336:Language Modeling from Scratch(从零构建语言模型)
Self-Attention & Transformers(自注意力与 Transformer)
The Illustrated GPT-2(图解 GPT-2)
Backpropagation(反向传播)
Introduction to Policy Gradient for LMs(语言模型的策略梯度入门)
Lightweight Guide to understanding GRPO and RL principles(理解 GRPO 与强化学习原理的轻量指南)
How to Scale Your Model(如何扩展你的模型)