186-技术面试官识人手册

开篇词 | 世事洞明皆学问，人情练达即文章：小面试，大道理

你好，我是软件工程师熊燚，网上大家都叫我四火，很高兴在这个专栏和你见面。

我曾经是华为、Amazon 的软件工程师，现在我在 Oracle 工作，我之前在极客时间写过一个技术专栏《全栈工程师修炼指南》，自己也有一个很长时间的独立技术博客《四火的唠叨》。

工作的这十多年来，我以工程师的身份经历过不少团队，面试过许多软件工程师候选人，指导过一些经验尚浅的面试官，也目睹过许许多多不同风格的面试，更了解过这些面试的候选人在入职后截然不同的职业发展轨迹。

现在我在云计算的某个团队工作，除了是一个几十人团队的 Team Lead，也担任公司招聘环节的 Bartender 角色。过去这一年多来，我面试了将近 100 位候选人，主导或参与了他们每个人的面试结果决策会（debrief）。也就是说，平均下来基本上每周我都会参与面试，而他们中的大部分人都是软件工程师。

面试这件事听起来似乎挺简单，做起来却非常困难。从我的长期经验来看，这里存在的问题和误区实在太多了，不妨听听来自面试官的真实“吐槽”吧：

“是不是拿算法题让候选人做就好了？可如果他做过这个题目怎么办？”

“候选人都是工作好多年的老司机了，怎么有面试官问那种简单粗暴的算法题！”

“‘面试造火箭，工作拧螺丝。’工作内容普普通通，为什么面试要问那么难的问题！”

“新入职的同事，上来就给我们的系统埋雷，还不服批评，这种性格脾气面试是怎么过的？”

“招怎样的人好，是能立马干活的，还是有潜力的？有潜力的培养起来跑掉了怎么办？”

有没有觉得“似曾相识”或者“一见如故”呢？

这样的问题还有很多，我就不一一例举了，但有一点，我想你是非常清楚的，面试就是打造团队的第一道门槛，它可能短暂、直接地影响你一个项目的进度，也可能长期、潜在地左右你整个团队的战斗力。

既然如此，那我们不妨重新来系统地审视一下，负责技术面试这件事儿，对你、对团队来说，到底意味着什么？

晋升第一课，招募人才

首先，去负责技术面试，帮助公司和团队招募人才，就是一个职业上升通道的必攻克项。

这里你不妨想想，你们公司的面试官都是什么样的人？技术骨干，管理骨干，具备软件工程师背景？对于绝大多数团队来说，的确是这样的，因为经验等综合能力可以帮助他们做出中肯评价与合理评估。

所以，当你开始关注这些，或者已经为公司和团队把关人才的时候，恭喜你，你的视野、看问题的方式、沟通和筹划事情的技巧，还有做出合理判断的能力，已经有了质的提升，或者说得到了团队的认可。这对你的职业生涯来说，无疑是一个助推器。

但我也要实话实说，做好这点，挑战可不小！在后面的课程中，你将会深刻体会到这点，但我还是非常鼓励在阅读学习的同时，不断去尝试。

因为，面试还是一个预期和限制都很明确的快速学习机会，并且，是一个双向的学习机会。预期，指的是我们针对软件工程师这个特定岗位对于候选人的期待；而限制，则明确了双方需要在每轮短短几十分钟的时间内进行交流与合作，完成话题的讨论，或是问题的解决。面试官可以从中得到不同的观点，获知各异的思路，拓宽自己的视野。而这些东西，课本上没有，老师不会教给你，项目组内也学不到，这就更显得颇为珍贵了。

所以，在专栏中，我会讲到一些经典的面试问题，其中一些我已经在面试中问过不下几十次了。比较有意思的是，有的问题我见过 10 种以上的解题思路，其中超过一半，都是我从候选人身上学来的。

从这点出发，你还能深度体验换位思考，让自己和市场保持同步。显然，你不会永远是面试官，没有人会。当你准备往更高处发展，去接受新的挑战时，这之前的每一天就都成了准备。

流畅地表现和表达自己，具备出色的沟通能力，都会是你当下以及未来的加分项，这也恰恰体现了面试官这个角色为技术人职业发展所带来的价值。

除了个人，在团队里，这对于你个人影响力的打造也是很有帮助的。这就不局限于工作中做一个项目、解一个 bug 了，还有同事间相处、合作、互助等等。无疑，参与面试是一个加深了解的好机会。

正所谓“世事洞明皆学问，人情练达即文章”，小小的面试，隐藏了大大的道理。在通过反复实践来磨练以后，能够承担面试官重任的人，最终一定会同时具备优秀的技术功底与良好的沟通技巧，以及相应的理性思维与决策能力。

打造优秀团队，严把人才关

当你了解了面试对于个人发展的意义之后，我想从公司和团队层面再给你一点建议。在其位、谋其政，高度更高，视野要更广。

你有没有听过这样一句话，“招聘是研发团队日常活动的第一要务”。Facebook 是有比较多的类似观点在宣扬，而在我刚加入 Amazon 的第一天，我的老板也和我讲过类似的话。

可能你觉得夸张了，人不对换了就是了，工作还得继续，给招聘戴上高帽未免危言耸听。

先说说工作这么多年后我对这句话的体会，对于招聘的重要性，我是认同的。举个最简单的例子，就说软件工程吧，如果开发环节马马虎虎，那么测试环节就需要加倍投入去覆盖核心功能与非功能点；如果测试草草了事，那么运维就要开足马力修 bug、打补丁。总之，从需求、设计、开发、测试到运维，你总归要有一个环节把质量严格地把控好，否则就要让某个下游环节买单，下游环节不买单，那就要留给用户买单了。

同理，研发团队不同岗位之间的协作也是如此。如果软件工程师们具备优秀的沟通与合作技巧，脾气秉性能够兼容，那么团队经理的负担就会轻很多；如果他们具备一定的项目和任务管理能力，那么 PM 的介入就不用那么激进；如果他们能够具备优良的编程习惯，严格把控好质量，那么许多产品我们并不需要专职的测试团队……

你看，从研发团队的核心来看这件事，面试严把关，可以省掉不少管理工程师的成本，以及给其它环节买单的成本，甚至是“少招人”；反之，一个“不合适”的工程师加入，不但研发团队无法高效运转，还要其它环节和角色陪跑，此时付出的代价就太大了。

于公司、于团队、于面试官来说，管理成本和团队建设都是逃不开的两个关键词。而面试，就是在有限的时间内，评估候选人是否“合适”的最佳方式。

候选人成长空间

最后，还有一点我觉得值得讨论一下。如果你此时还只是一位候选人，你会关心面试官的目的和套路吗？

金融市场上，有投资和投机两种行为，前者更看重长期的回报，而后者更关注短期的收益。我认为，了解面试行为本身，恰恰是二者都注重的表现。在面试这个过程中，长期看，你可以了解到哪些知识和能力是值得长期投入的；短期看，你可以了解对方的初衷和心态是怎样的。

面试通过了，皆大欢喜，我们还可以从中评估和强化自己的认识；面试没通过，你也不至于说挂得不明不白。

但更重要的一点是，不要觉得你只有候选人的身份，其实，候选人也是面试官。因为面试是双向的，面试官在面试你的时候，你也在面试他。如果对方考察候选人的方式折射出欠缺思考的视角、糟糕的判断，甚至对候选人缺乏尊重，那么十有八九，这样的公司和团队，你也是忌惮加入的，对吗？

你的收获

到这，我再来说说你能从这个专栏中具体学到什么吧。

从范围上讲，这个专栏不是讲完整招聘的，而是专注于技术面试本身，并且，更多例子和技巧是针对软件工程师这个职位的。当然，我们也会讨论通用型的招聘技巧，和面试前后的林林总总。

具体分为以下三部分：

面试前：我将介绍为什么要对软件工程师进行技术面试，应当覆盖哪些面试角度，以及我们该怎样去设计面试题。

面试中：专栏的重中之重，我将结合实例探讨怎样主导技术面试。包括怎样把控流程，怎样进行算法和数据结构的考察，系统设计的考察，面向对象和测试能力的考察，基础知识的考察，以及行为面试的操作方法等等。

面试后：我将针对候选人的评估讨论会如何开展来介绍。包括怎样收集事实、提炼数据，怎样引导争辩、达成共识，以及最终怎样给出客观中肯的评估。

从交付形式上看，你会一直处于面试场景中，熟悉的问题会带你步步深入，我希望能通过先破典型、后立观点的方式，打破你对于面试的固有认知，收获不一样的学习体验。另外，你在课程中还会看到很多的技能卡片和总结性脑图，来帮助你记忆与回顾。

再者，我想说，市面上系统、完整讲解如何主导软件工程师技术面试的材料非常少，这个专栏融汇了我 10 多年来在国内外大厂的面试经验与思考总结，相信能带给你富有启发性的设计思路，以及实战检验过的全新观点。对于面试来说，“问题是多变的，套路是永恒的”，如果你能消化和吸收隐藏在它背后的原则和思路，这趟旅程定不虚此行。

最后，我深知技术面试和一般的技术内容相比，观点繁杂、方法多样，落到个体实践更是差异巨大，但就像我们期待一场相谈甚欢的面试一样，这个专栏除了交付体系化的方法心得，我也希望给你提供一个畅所欲言的窗口，一把打开更多技术面试相关话题的钥匙。

因此，对于更多问题，欢迎你在评论区留言，我将尽力一一回复。此外，我还特别策划了若干期专题答疑，尽可能把你的疑惑都覆盖到。

我是四火，我们下节课见。

01 | 评估体系：公司和团队到底需要怎样的技术人才？

你好，我是四火。

孙子兵法中，有句话叫做“胜兵先胜而后求战，败兵先战而后求胜”，这句话的意思是说，胜利的军队总是先制造胜利的态势然后向敌方挑战，失败的军队则反过来，先发起交战，然后在作战中求得侥幸的胜利。

招聘和面试的过程，就如同一场大战，在我们正式开始讨论招聘和面试过程的话题之前，我们需要把初衷搞清楚，把对于软件工程师候选人考察的策略大体订立清楚，做到心中有谱，以“先胜后战”。

大公司也好，小公司也罢，招人，就需要面试，这我们都知道。可是公司和团队，到底需要怎样的技术人才？这就是我们建立整个面试考察评估体系的时候，最最基础的那个问号。

常见答案

在回答这个问题之前，我们先来看看一些常见的答案。

“能干活的，能加班的”

我相信给出这个答案的大有人在，我听过这样的说法：“软件的架构都已经做好了，设计都已经完成了，现在需要的就是普通劳动力，把代码填上。”

在我看来，这种初衷可以理解，但实施起来却非常困难。也许在某些行业这的确是可行的，但是在软件工程的世界里却恰恰相反。

究其原因，是持有这个观点的人，把软件工程这个复杂的行为，使用简单的劳动分工来划分了。在历史上，这样的做法并非没有人尝试过，只不过大多数的尝试都失败了，或是最终令它的其它环节成本，高到失去了这样做的意义。

这是为何？

让我来进一步解释一下。比方说，我们可以把软件工程的流程简单地分为需求、设计、实现、测试、维护等几个步骤。当我们将“实现”环节的人员要求降低，也相应地将质量要求降低，那么我们就将迫不得已在其它环节投入更多的人力去平衡，最终导致研发成本并没有得到本质上的改善，反而在实现环节埋下隐患，比如糟糕的代码设计为未来的维护和扩展挖坑。

这样的平衡，可能是花更多时间来完成更细致的设计文档，可能是添加更多的测试人手和执行更全面的测试，也可能是花更长时间试运行版本和 bug 修复，还可能是招更多的、专门的管理人员来盯着这些程序员严格遵守流程。

说白了，就是在软件工程的其它环节做更多的工作，然后给糟糕的实现环节擦屁股和买单。

“算法好的”

这是第二个常见的答案，但有意思的是，这个答案却很少从有经验的团队负责人或者招聘人员那里听到，而更多地是从踏入职场没多久的候选人那里听到。在我见到的面试实践中，这也确实是一个普遍现象。好端端一个软件工程师的面试，最后变成了刷题成果检验会。这个现象，你是不是也觉得似曾相识？

那么，为什么这样的观点是错误的？

原因很简单，用四个字来概括，就是“以偏概全”。

软件工程是一个多维度的、复杂的行为，代码实现只是其中的一个部分；而算法，更只是代码实现的其中一个部分。单纯的算法牛人离真正的软件工程师，其实还差了十万八千里。

也许你会有这样的问题，那既然单纯的算法面试如此片面，为什么还有那么多公司如此频繁地使用它？别急，我在这里先卖个关子，因为我会在这个专栏中慢慢展开来讲，详细告诉你这是为什么。

“牛人”

这也是一个常见的答案，我不能简单地说这是一个错误的答案，因为“牛人”二字的定义实在是不明确。如果我们把这里的“牛人”理解成“技术杰出的人”是否就正确了呢？

我觉得，这依然不正确。相较于“牛人”，团队更需要的是“合适的人”。

先从技术角度来说。理想的团队，技术层面上是需要在一定程度上互补的。比方说，在一个全栈的团队中，有的成员擅长系统底层，有的擅长 Web 应用；有的系统思维严谨，有的产品直觉敏锐，那么无论在系统设计还是在问题定位的时候，团队的决策就可以因为取长补短而达到一定的平衡。

再从非技术角度来说。即便在技术层面候选人已经无可挑剔，我们都还有很多非技术因素需要考虑；即便在个人的非技术层面已经无可指摘，我们依然需要考虑候选人和团队风格的契合程度。举例来说，某些技术特别出色的人，个性更为鲜明，或者说不易相处。我们应该对这样的候选人说 yes 还是 no？

这就要牵涉到一个公司的文化，以及团队的接纳程度了。显而易见的是，一个团队里面，如果全都是“刺儿头”，到处是激烈的观点碰撞，这肯定是一个糟糕的状况，很可能经理每天要忙于摆平冲突；而一个团队里面，如果全是“老好人”，只有赞美和观点认可，这其实也是一个令人担忧的状况，因为缺乏观点往往就意味着决策力的缺乏。

“聪明、有潜力的”

这一类回答，主要是针对职场经验尚浅的候选人来说的。

一家公司也好，一个团队也好，有经验的工程师和有潜力的工程师，需要在构成上达成一定的平衡。

有的团队相对技术成熟，架构稳定，流程确凿，而有经验的工程师可以有一定的时间来指导和帮助新人成长，团队可以培养自己的骨干，那么这样的候选人可以说是再好不过了。

而有的团队则相反，特别是某些创业团队，或是产品初创团队，每个人都要挑大梁，甚至大家都忙于救火，那么这种情况就特别需要自我管理能力强、综合素质和经验皆备的老兵，这时这样的候选人就不适合。

你看，团队需要怎样的技术人才？这个问题并不是那么好回答的。

考察角度

那么，不回避问题，公司和团队到底需要怎样的技术人才？或者说，反映在面试中，我们应该从怎样的角度去考察和甄选人才？

我将分两个部分来回答这个问题。在这一讲我将谈谈，从宏观上怎样去把握软件工程师候选人甄选的维度；而在下一讲我将结合实际案例来分解面试计划，讲解在操作上的要点。

好，我认为，首先我们要充分认识职位，这里面既包括职位在普遍认知中所具备的共通部分，也是主要部分；又包括特定职位特殊的要求，这有时只占小部分比例，但也不可或缺。

共通部分

共通部分，说白了，就是对于一名优秀的软件工程师普遍的、客观的理解。

我们来看一个真实的例子，以下是一段来自某互联网公司的职位描述：

1. 扎实的编程和数据结构算法基础，深入理解面向对象编程思想，具有较强的设计能力。

2. 具有较强的分析和解决问题的能力，有强烈的责任心和团队精神，善于沟通合作。

3. 具有音视频、直播、OpenGL 相关开发经验者优先。

非常精简，但也很有代表性。短短的几条描述，就已经包含了下面我要讲的关于人才甄选共通（第 1、2 点）和特殊（第 3 点）这两个部分，并且也包含了技术和非技术这两个对立的范畴。

技术层面

技术层面上，我们要考察软件工程师的基础技能。包括：实际问题解决能力，代码设计和实现能力，系统分析设计能力，测试和验证的能力。

首先是关于实际问题解决能力，工程师毕竟是要做工程的，做工程的目的就是要解决实际问题。

这也是为什么，我不赞成面试中，较多地使用单纯的算法和数据结构问题。不是因为它不具备考察性，而是它的覆盖面太窄，具体说，一个典型的实际问题的解决，需要包含两个部分：

1.把具体问题抽象成若干个可解决的软件问题；

2.使用软件工程的知识与技能去解决这些问题。

而单纯的算法和数据结构问题，不但只能解决上述两点中的第二点，而且这第二点还必须得是一个落得到编码层面、甚至数学层面上的问题，足见其覆盖面之窄。至于怎样的问题才是一个好的面试问题，我们在专栏的后文中会去专门讨论。

其次是代码设计和实现能力，这是软件工程师的基础技能，就如同厨师切菜和钢琴师读谱一样，都是看家本领，技术面试要花相当比例的时间来验证这一点。

但请注意，即便只讨论这一点，它涵盖的范围也比单纯的算法和数据结构广泛得多了，像是有些公司特别喜欢考察的面向对象就属于这个范畴。

再次是系统分析和设计能力，包括是否能够针对问题给出合理的系统估算、架构设计等等。这一部分是和经验密切挂钩的。

对于代码实现层面，可以简单地认为，无论是刚工作 1 年的新手，还是工作 15 年的老兵，预期上当然会有差别，但并不那么大。

但是，如果是系统的分析和设计能力，就截然相反了，一般来说，丰富的工作经验，理应意味着一定的系统分析和设计能力，我们可以简单这样认为：

需要强调的是，这里说的“系统”是泛指的“软件系统”，而不是“分布式系统”。

这么强调是因为我觉得，如今的互联网的浪潮，给技术人也带来了一些不太好的影响，比如过度追捧“分布式”这样的热门词汇。仿佛谈及系统，就是大数据、海量、高吞吐，一些简单的系统都不太瞧得上了，我觉得这是很不妥的。

对于系统的理解，就如同数学的基础是初等算术一样，还是要把根基打扎实。

剩下的共通的技术层面的部分，我觉得可以叫做“其它综合工程能力”，比如测试与验证的能力等等。不是说它们不重要，也不是说不考察，而是说，在面试中，对于软件工程师的技术考察，我们要有所侧重。比方说，我们可以简单地约定只把 20% 的技术考察时间，放在这部分。

你也许会问，计算机的基础知识考察在哪里啊？其实，它就蕴藏在上述的考察项之中。对于这些分项的考察，是不可能脱离扎实的计算机基础知识来进行的。

比方说，要设计一个网站系统，要有对于网络协议，特别是 HTTP 协议的基础认识吧，要有对于中间件、容器的基础知识吧，还要有对于数据库的基础理解吧。

在实际面试和考察的过程中，专业技术层面的指标相对容易辨别、容易执行，也往往是作为一个“技术人”的考察重点，我们也确实会花很多时间、设计很多方法在这一部分。但是非技术层面，却容易被具备软件工程师背景的面试官所轻视。

非技术层面

那我们就再来说说非技术层面。我们关注工程师的基础品格、团队合作能力、学习能力、沟通能力，以及任务管理能力等等。

在非技术层面，单纯地分项考察有时候会比较困难，也很难覆盖所有我们关心的点（但并不是不能做，我在后续会介绍一些方法）。但我们每一个人，其实都带着我们对于职业素养的基本认知，如果某一点上出了问题，我们会察觉到的。因此多数情况下，我们只需要对于技术面试中发生的一切，保持敏锐。

举例来说，面试中，如果你发现与候选人的沟通存在很大问题，那么你不可能不留意到这一点，而根本不需要特别地去问一个“专门”考察沟通能力的问题。

综上，对于软件工程师的候选人来说，面试的轮次要保证大部分都以技术面试的形式覆盖，而允许少部分以非技术面试的形式覆盖（比如 5 轮中有 4 轮技术面试，1 轮非技术面试）。但是每一轮技术面试拿到的数据，却应当同时覆盖二者。

举例来说，技术面试中，候选人被要求设计一个短网址系统。候选人二话不说，上来就开始绘制系统组件图，既不确认功能性需求，也不讨论非功能性需求。

面对这样的情况，面试官可能会觉得，候选人缺乏良好的问题澄清和沟通的习惯。也就是说，我们在技术面试的轮次中，也会得到一些非技术层面的数据。即我们并没有在这个轮次的考察中特别地规划这个非技术考察项，但是我们却得到了关于它的考察数据。

在技术层面，我们谈到了针对不同工作经验的候选人，我们考察项的不同侧重，而在非技术层面，这里也有一样的情况。

对于踏入职场不久的工程师，要更关注潜力相关的素质，比如是否能够听从建议并加以思考，以及是否具备兴趣与热情，因为这是学不到的东西。

而对于有丰富经验的工程师，要更关注视野，技术理解的深度，以及职业素养。

也就是说，“经验”，不是体现在年头上，不是体现在更复杂的算法和更高级的数据结构上，也不是体现在记忆那些晦涩难懂的参数配置上，而是对于软件系统的理解，对于团队和产品的理解，对于软件工程的理解。

这有点像足球俱乐部的建制，引入年轻球员更多考虑的是未来和潜力，而引入老兵则是要带来立竿见影的效果。

特殊部分

特殊的部分，指的是不同的团队和细分职位，对于软件工程师候选人，有着不一样的要求。

技术层面上，比方说有一些职位要求具备前端技能，有一些职位要求具备 AI 背景，而有的团队则要求云计算方面的工作经验。

在非技术层面，很多大厂都会设置几条特定的指导原则，这些原则就像纲领一样，指导对于候选人非技术部分评估的过程。比如亚马逊的领导力准则，这几年来讨论的人很多，在亚马逊每一轮面试都会被要求覆盖其中的一到两条。

好，上面就是我们从宏观上，从公司和团队的需要出发，对于面试的考察角度，所应具备的大体认识。

你可能注意到了，即便某一特定的细分职位，对于技能有着较为细致和明确的需求，我们还是可以发现，对于大厂的面试，往往共通部分所占比例就越大，我想在这里解释一下原因。

显而易见的是，越细分的职位，越特定的要求，就越能够提高候选人的匹配度，但是这也降低了人才筛选的普适性，让招聘变得无比困难。因此，这些大厂，给出了模糊的招聘标准，而选择在招进来以后，做进一步地培养。这既是刻意为之，也是无奈之举。

但请注意，这里面也蕴含了一个简单的道理，一个面试中在“共通”部分表现优秀的软件工程师，更可能就是一个通常意义上的优秀的软件工程师，那么就算他并不立即具备特定职位的某项技能，但是经过较短时间的学习和融入，他也很可能可以很快地胜任这个职位。

关于职位细分，我还想拓展一点，谈一下我对于开篇词中那个“培养起来跑掉了怎么办”担忧的看法。

在前文中，我已经提到，对于任何一个公司和团队来说，都不是要招“牛人”，而是要招“合适的人”，我们大的目标是和候选人一起共赢，而不是单纯的劳动性价比。

无论是领域、薪酬，还是工作内容，大家接触到的信息都是开放的，候选人和公司如果各自都能够在大体上得到想要的，就可以在一定程度上缓解这种担忧，你也可以不用太担心这个跑路的问题。

总结与思考

面试就像打仗，在打仗之前，我们要高屋建瓴，预先做好规划。因此，作为第一讲，今天我们介绍了，从团队需要的角度出发，宏观上该从怎样的角度去考察软件工程师候选人。这同时包括了技术层面以及非技术层面的关注点。

在最后，我想知道，你的团队又是从怎样的角度招人的呢，能否分享一下？欢迎在留言区一起讨论。

好，我是四火，我们下一讲见。

02 | 制定计划：好的计划是成功的一半

你好，我是四火。

在上一讲中，我们谈到了在面试之前，从宏观上去认识和理解公司和团队需要，和大致的人才甄选标准的重要性。今天，让我们来继续深入这个话题，我将结合实际案例继续分解面试计划，讲解在操作上的要点。

常见问题

你们公司和团队，会为即将到来的面试做计划吗？根据我的观察，计划这件事情，是非常容易遭到轻视的。可能我这样说你感触并不深，下面我列举几个常见的因为不做或者没有做好计划，而导致面试执行有失偏颇的情况。

我曾经作为普通面试官参加过一次面试，那是一个涉及网络安全的职位。在交流过程中，候选人明确地表达了希望成为一名安全领域工程师的决心，只可惜面试团队里面没有这方面的专家。

我们大体上是按照普通软件工程师的思路来面试的，专业领域方面没有办法做有深度的覆盖。显然，这是欠妥的，候选人也或多或少表露出了失望。最后，我们不得不找来相关领域的同事，重新加了两轮专业面试。

还有一次，是关于软件工程师候选人，5 轮现场面试中，只有一轮覆盖了编码。候选人其它四轮表现都不错，可惜编码略失水准。

从正面反馈的比例来看，其实候选人还是挺不错的，其它没什么问题，但是由于编码对于软件工程师来说是一个绕不过去的硬技能，而面试考察的覆盖明显不合理，coding 方面的数据点不够，所以当时我们也是挺纠结的。

综合考虑之下，这位候选人最后还是入职了，但是入职仅仅大半年就离职了，其中一条不佳的反馈就是，几位同事都提到他的代码写得一塌糊涂。

前面描述了两个我印象比较深刻的问题，其实还有一些其它的典型问题，我在这里简单提一下，看看你们公司是否也有类似的情况发生呢？

面试一位十几年经验的工程师，对方倒是认认真真准备了，结果面试官拿的都是要写个快排之类的简单粗暴的算法题。基本上是拿着面试初级工程师的路子来面试经验丰富的候选人，最后的决策靠谱程度可想而知，而候选人也很不开心。

走完了整个面试，候选人拿到 offer 的时候说：“啊，我不知道这个职位还需要我长期出差办公啊？我不能接受出差办公。”

你看，发生这些问题，几乎都是缺乏面试计划，或者没有做好面试计划造成的。这样的代价，轻则浪费时间，让候选人失望，让面试官尴尬，重则招进来不合适的成员影响团队。

那么，我们该怎样合理地制定面试计划呢？

实例解析

这里我们从一个具体的例子出发，这个例子可以形象化地帮助我们理解，到底一份面试计划应该怎样做。

由于不同的公司、团队，面试的情况有所差异，例如轮次、时间等等，因此在实际操作中，请勿照搬照抄，而是把握原则，去因地制宜地执行。

候选人小张，硕士计算机专业毕业，7 年工作经验，现就职于某互联网金融公司，面试团队是某互联网大厂的云计算团队，职位是高级软件工程师。

确定人选

以大厂为例，通常来说，电话面试一般 1~2 轮，现场面试少则 3 轮，多则 5、6 轮。

由于错招一个人的成本太高，基本上都会用“车轮战”的方式来尽可能地多收集数据，以做出更加合理的判断。每一轮都有单独的一位面试官（少数情况出于学习和培训的需要，可能安排两位）。

面试团队的人员角色包括这样几个：

招聘经理（Hiring Manager，HM）：一般都是由团队经理担任，这时的招聘也往往是“给他自己的团队”招人。招聘经理特别关注候选人和团队的匹配程度，而将诸多技术考察的活儿，留给其余的面试官。

技术负责人（Bartender）：这个角色的名称在不同的公司叫法也不同（比如，有叫 Bar Raiser 的），具体职责也有差异，但是大致的目的，就是要维持整个面试的水准。这个角色往往经过了专门的训练，他们有比一般的面试官多得多的面试经验，并且，为了考虑利益相关性和平衡性，他必须来自于一个不同于招聘经理所在大部门的组织。

其他面试官：这些面试官一般都来自于招聘经理的团队，或者兄弟团队。

制定计划

电话面试（Phone Screen）安排如下：

小张通过了电话面试，现场面试（On-site Interview，当然，疫情期间一般的现场面试也变成远程进行的了）安排如下：

让我们来对上面的这两个表格中的安排做个说明。请注意，在计划的过程中，我们更关注的是考察重点和考察角度是不是能够以合理的方式分配，其比例是不是恰当，而不是具体的考察内容。

事实上，对于具体的考察内容，不同的面试官也有自己的习惯，我们应当保持尊重。这里面的考察内容，我也仅仅是以举例的方式给你提示，之后的课程我还会详细讲解怎样设计这些考察问题。

计划剖析

首先，清楚团队的需求和限制，设立合理预期。我们想把这件事情尽可能做好，但是它本身存在着诸多局限性：

面试的过程可以轻松自然，但面试本身是一件严肃认真的事情，其中的责任是巨大的。在我第一次参加 Bartender 培训的时候，讲师说过一句话，我至今记忆犹新：面试对于我们，可能最终只是其中一个必须要做出的决定，但是对于候选人来说，却可能是影响整个职业生涯的事情。我们当然不希望招错人，但是我们也不希望错过优秀和合适的人。

面试是一个复杂的活动，但是对于任何一位软件工程师的评估，是一个远比面试复杂得多的活动。最理想的面试，其实应该是实习。因为实习会有更充分的时间，通过深入的项目和团队活动，来得到足够多的可信数据，来帮助决策。但是由于人力、时间成本的原因，招人不可能仅靠实习，面试也不会有实习的时长。因此面试的目的，不是做出 100% 准确的决定，而是要在有限的时间里，尽量通过合理的角度布局，尽可能挖掘到有帮助的信息，从而做出风险范围可接受的决策。

我们需要明确的是，时间、人力成本的足够投入，和考察角度的合理覆盖，是两件完全不同且都必不可少的事情。我们希望达到的效果是，面试团队通过足够量的投入，得到了可以帮助评估候选人的较为全面的数据，但却没有过度地重复覆盖某一个角度。

每位面试官的标准不同，视角不同，最终很可能这个 bar 参差不齐。但是 Bartender 要利用自己的经验和好的实践，去规范和约束整个流程，帮助大家把注意力聚焦在流程上，把判断的依据放在通过面试挖掘到的数据点上。流程正确了，数据充分了，结果就会是合理的。

其次，面试团队的职位和角色匹配上，要遵从一致性原则。换言之，让工程师来选工程师。

在这个例子中，7 轮面试（2 轮电话面试 +5 轮现场面试）中，这里面有 4 位工程师（这里的 Bartender 也是工程师），和目标职位的一致程度超过了 50%，并且另外两个角色团队经理和产品经理，都是工程师日常工作接触比较密切的角色。

再次，考察角度、考察重点、考察内容，三者也要遵从一致性原则。还记得我们上一讲介绍的考察角度吗？如果忘记了，不妨回看温习一下。这三者其实是一个从宏观向具体细化的过程，根据考察角度来确定考察重点，而考察内容则是最后的落实。

在这个例子中，纵览考察重点，有 3 轮考察了代码层面，1 轮考察了系统层面，1 轮考察了用户接口层面，还有两轮考察了对于软件工程的理解，以及团队匹配度等等。

而具体到了考察内容，电梯系统、限流功能、Email 系统等等，你可以看到，无论描述多简洁，这些内容大多都涉及一个实际问题，或者是一个具体的系统。这是和考察重点中的“实际问题的解决”相一致的，这也符合做工程就是要解决实际问题的本质。

从这些内容中，你可能注意到了，“讨论”这个词用得很多。其实，这里面几乎所有的主要考察内容，都是以“讨论”的形式展开的。

讨论可以带来很好的交互性，候选人会具备主动的参与感，也可以帮助面试官获得很多有价值的数据点，我们在后面的课程中还会详细介绍。

最后，考察轮次需要保持渐进性。我们这个例子中，你可以看到，电话面试做了一个比较初步的筛查，问题难度也相对较低；而现场面试则给出候选人更有层次性和挑战性的问题，技术层面的难度也相对更高。使用这种方式，我们可以让电话面试能够初步筛选掉不靠谱的人选，让所谓的“细筛”，留到现场面试。

另外，现场面试的最后一列是企业和团队的文化关注点，这部分不同的企业和团队变动比较大。

我上面的这一列的例子来自于 Amazon，为了保证面试符合企业文化的基本原则，每一轮都要求赋予一个“领导力准则”的考察项，在评估的时候考虑在内。这是一种企业文化深入工作方方面面的途径，有些互联网大厂比较喜欢这种方式。

当我们理解了团队需要和考察角度，把人选和计划排出来（一般这个事情是招聘经理或者 Bartender 主导的），虽然真正的面试轮次还没正式开始，可是已经成功了一半。

总结与思考

好，上面我以一个具体的例子，详细介绍了面试计划制定的方方面面。在此基础上，我还想对两个相关的常见问题，做出进一步的解释。

电话面试与现场面试

为什么不直接奔赴现场，直接搞定现场面试？电话面试的目的是什么？

其实，确实有这么做的。但是，要让候选人直接来公司，见团队，考虑到时间的成本以及交通食宿的开销，有时候代价还是比较大的，对双方都是。因此，电话面试最大的作用，就是用相对较小的代价，“过滤”掉那些明显不靠谱的人。

因此在计划中，电话面试轮次通常会比较少（1~2 轮），因而，电话面试要能覆盖到我们最关心的那部分内容。而电话面试的决策，通常也非常迅速，电话面试的面试官互相碰个头，如果通过，招聘经理也觉得没什么大问题，那就可以继续，进入现场面试。

从上面的例子你也可以看到，从技术角度来看，电话面试的难度应该不大，但是又要足以过滤掉那些硬条件不符合，或是明显不能达到面试 bar 的候选人。

而从非技术角度来看，要重点关心对方是否有一些明确的要求，是否和团队能提供的所匹配。比如说，如果这个职位要求外派出差办公，而候选人不能接受这一点，那就必须要在电话面试或者之前就沟通清楚，以节约大家的时间。

应届生与老兵

前一讲已经提到过，应届生与老兵，这是两类截然相反的候选人，我们考察的重点是不同的。对于没什么经验的工程师来说，我们更看重的是潜力；而对于经验丰富的工程师来说，我们更看重的是能力，这从对于系统设计能力的要求上就能看出来。

因此，对于上面的面试计划，如果候选人从 7 年经验的社招变成了应届，那么可以考虑做的调整有：

减少总的面试轮次。通常来说，应届生，或者校园招聘，我们的投入时间成本可以适当减少。

去掉系统设计的面试轮次。我们当然可以考察系统设计，但是系统设计不应成为主要的考查内容。对于系统的理解，是一个需要时间和经历逐渐积累的过程。

减少对于工程方面理解的考察。如果考察应届生对于项目和任务管理的理解，对于软件工程的理解，往往意义不大，理由同上。

增大对于兴趣、热情、学习能力，以及是不是能够接纳意见等“潜力素质”的考察比例。一句话，你觉得他能否在团队的帮助下快速地成长，能不能很快地晋升为高级工程师。

增加对于 CS 基础能力的考察。这部分反映了候选人技术的“底子”牢不牢靠。

“不打无准备之仗”，今天，我介绍了怎样去给面试活动制定计划，希望对你有帮助。有了良好计划的保障，在下一讲，我们就要开始真正接触实际的面试环节了。

好了，在文末，我想知道，你所在的团队，是否为面试做计划，又是怎样安排面试实际考察的角度的呢？你能否在评论区聊一聊？

好，我是四火，我们下一讲见。

03 | 问题设计（上）：三大原则理清面试考察方向

你好，我是四火。

相信你在学习了第 02 讲的面试计划之后，心中对于它已经有了更深入的理解。

我们在面试计划中，谈到了规划合适的面试内容，来帮助我们获取面试重点所对应的数据。而在技术面试中，技术问题就是这个面试内容的直接体现。

我们也重点提到了，这个过程中，考察角度、考察重点、考察内容，三者要遵从一致性原则。因此，如果技术问题没有设计正确，对于候选人的考察，就不可能靠谱。

那么接下来的两讲，我就来说说，具体怎么去设计“合适”的技术问题。这一讲我会先从反面介绍几个糟糕的技术问题典型，再从正面讲讲技术问题设计的原则；下一讲我会介绍一些技术问题的设计技巧，以及一些实践中的注意点。

相信在学习完这两讲之后，你对怎样设计技术问题就能做到心中有谱了。

糟糕的技术问题

首先，让我们来看几个典型的、在面试中不断被使用的技术问题，看看你有没有似曾相识的感觉。

下面这样的问题，可以在适合的场合下快速地使用，但是，通常来说却是不适合作为面试的“主要”问题的，换句话说，这些问题并不适合花大量的时间和候选人去讨论、分析和解决。

知识性的问题

有一些问题，是知识性的，这一类问题，考察的是知识，是记忆力，而不是任何一项工程师的核心能力。举例来说，有这样的问题：

“对于 OA 系统，我们该怎样配置 Tomcat？”

为什么说这个问题不好呢？这是因为这里抠了一个 Tomcat 配置的细节：

首先，如果候选人不了解 Tomcat，回答不了这个问题呢？是不是就可以认为这是一个负面的考察数据？

其次，就算候选人了解 Tomcat，但是具体配置项记不起来了呢？这是否又可以成为一个负面的考察数据？

这一类问题，我们简单地称其为“知识性问题”，在技术面试中，我们通常就应该避免。因为一方面它不具备普适性，另一方面它又具备太强的随机性。

不具备普适性，指的是候选人必须要了解特定的框架或者库，考虑到优秀的候选人的知识背景有所区别，所以这一要求过于武断；而太强的随机性，指的是候选人是否知道这一个知识点，随机性太强，而并不能反映候选人的技能水准。

另外，有一些问题并不像上面的例子那么直接，但是本质上有类似性。特定编程语言、框架和库限定下的问题就是其中之一，比如：

“请实现 C++ 的 atoi 算法。”

这个问题，如果团队就是要求候选人必须具备 C++ 技能，那没什么问题；但是对于大多数团队来说，情况并非如此，那么这个问题就对平时以 Java 为主要编程语言的候选人不太公平了。这也是为什么，很多大厂对于面试流程的培训中，有一条指导原则：不限制候选人使用的编程语言。

还有一些问题，可能有一些隐含的知识，或者说“背景知识”前提蕴藏在问题中，而这样的知识从面试角度来看，又不是我们关心的。

这一类问题需要注意，可以问，但这部分背景知识最好是众所周知的“常识”，倘若候选人不知道，那就应该最直接快速地告诉他，而不应该把时间浪费在它上面。比如说：

“请设计一个算法，把十进制的数字，用罗马数字来表示。”

你看，这看似是一个挺好的问题，可假如说候选人不知道罗马数字的书写规则，是不是就卡壳了？而罗马数字的书写规则是我们对软件工程师候选人考察的内容吗？显然不是。

你可能会问，那么假如候选人知道这个规则，是不是就可以问了？

原则上没错，可前面已经提到了，我们需要的问题是具有“普适性”的，这样我们才能把这个问题频繁地拿出来问，积累足够多的、可以用于比较的数据。好问题千千万，何必死磕这一类呢？

你还可能会问，那我要是告知候选人这个规则，是不是这就变成一个好问题了呢？说得好，可答案依然是否定的，至于原因，我先卖个关子，你不妨先想一想。

过于常见的问题

这一类问题，我想应该很容易理解吧，但是我们却经常见到。举例来说，算法题有：

“请对二叉树做一次先序遍历。”

系统设计问题有：

“请设计一个 URL 短网址系统。”

我们考察候选人，是希望得到真实的数据，而被使用太多遍的问题，很有可能就是候选人准备好了的，这就让考察的真实性大打折扣了。诚实的候选人会告诉你，这题我做过了，但你不能奢望每个候选人都如是操作。

每一个面试官，随着经验与时间的积累，自己应该有那么两三个“杀手锏”问题。这样的问题经得起多次面试中询问的考验，并且积累了足够的数据，而更重要的是，这样的问题要具备一定的“独特性”，是候选人通常准备不到的。

另外，这里我必须要强调一下，我们这里是指问题本身不要过于常见，而不是说，“问题类型”和背后的“原理”不要过于常见。

相反，我们恰恰就是要通过“新”问题考察候选人的“旧”能力。这就是为什么我们说，问题是多变的，但套路是永恒的。

因为这些套路恰恰就是，软件工程师得以在问题的千变万化中，依然能够游刃有余地分析和解决它们的原因。比方说，URL 短网址系统的设计问题都被考烂了，但是背后的系统设计的考察要素，比如对于网络协议的理解、系统容量的估计、存储技术的选型等等，都是非常好的具体考察点。

规则过于复杂的问题

再回到前面提到的罗马数字的问题：

“请设计一个算法，把十进制的数字，用罗马数字来表示。”

为什么即便告知候选人规则，这依然不是一个好问题呢？因为这就可能是一个“规则过于复杂”的典型例子。因为如果候选人对罗马数字一无所知，那么把罗马数字的规则前前后后都讲清楚，怎么也得花费十多分钟的时间。

因此这样的问题，往往就不是一个好问题，毕竟，我们要把宝贵的时间尽量地分配到考察的重点内容上。

当然，这样的问题也不是不能“抢救”一下的。同样是考察代码层面的能力，如果我们给这个问题加一个小小的限制，比如，我们只考虑二十以内的数字，我们假设输入都是正确的等等，规则就会简单不少，那么，候选人就可以把精力集中在核心实现上。

需要说明的是，复杂问题的简化途径，和考察项是密切相关的。如果你就要考察候选人，是不是能够对各种场景考虑周全，那么就不要假设输入都是正确的，而让候选人自己去进行必要的输入判断和错误处理。

技术问题的设计原则

好，上面我们谈到了几个糟糕的技术问题，这是反面典型。接下来我们就从正面来谈谈，到底应该把握怎样的原则去设计和选择技术问题，以及到底怎样的问题才是好问题吧。

和考察角度、考察重点保持一致

不知你是否还记得，我们之前第 02 讲里，关于制定计划的内容，面试内容，就是要和考察角度、考察重点保持一致的。我们的目标，是和候选人一起来解决这个技术问题，在这个过程中，我们可以围绕它来获得有效考察数据，从而便于我们在面试后做出决策。

举个例子，某面试官要对候选人进行面试考察，重点是“实际问题的解决以及对系统的理解”。于是，他决定使用一个“网约车系统的设计”问题来作为主要问题，在面试中和候选人一起讨论。那么，从这里我们大致可以看出，面试官需要把握这两个要点：

实际问题的解决：面试官打算给出实际问题，关注候选人是不是能够逐步通过工程师的技能，把这个“网约车”（比如滴滴打车，这就是一个实际的系统）实际问题中最核心的部分，简化和抽象为软件问题，并加以解决。

对系统的理解：面试官打算在和候选人讨论清楚需求后，要求候选人设计一个软件系统来实现它，这个过程中重点关注候选人是不是有系统设计的技能，以及是不是能够根据问题的特点，做出合适的技术选择。

对于怎样执行这个要点把握，还是不够明确对不对？别急，我们接着看，我会在接下来的技术问题设计原则中，完整地把它描述出来。

从模糊到清晰，从实际到抽象

你读到这里，可能会问，从模糊到清晰可以理解，可是什么是从实际到抽象呢？难道不应该是从抽象到实际吗？只有落到实际才能够实现啊！

别急，我这就来做一个解释。从专栏一开始我就讲到，软件工程师，就是要做工程的，而做工程，从本质上说，就是要解决实际问题的。

这里说的从模糊到清晰，以及从实际到抽象，看似是两个过程，但其实它们恰恰是统一的：实际问题，往往就是模糊的，它可能来源于顾客的一句抱怨，用户的一个建议，或是一个不明不白的痛点；而软件途径可以解的问题，必须是清晰的、简单的，如果连软件的设计人员自己都说不清楚需求和逻辑，实现就无从谈起了，既然能够说清楚，这个描述肯定是经过了简化和抽象，去掉了细枝末节，只保留问题的核心。

因此，一个具体问题只会有某些核心的部分可以通过软件来解决，而余下的大部分只能是作为陪衬。这一条原则，其实谈的是“深度”。

这个对实际问题的简化和抽象的过程，正是软件工程师的重要能力，并且它还和实打实的经验密切相关。

我前面提到过，纯算法题当然可以拿来问，但是我通常是不推荐的，因为考察面太窄，这样的问题本身就已经是一个经过抽象和简化了的数学问题了。或者说，直接讨论这样的问题，就失去了将实际问题简化和抽象成软件工程可解的问题，这样一个非常有价值的过程。

我接着前面的例子来讲。面试官向候选人提出了这样的技术问题：

“请你设计一个网约车系统。”

就这样简简单单一句话，有些候选人拿到问题以后，会不知所措，“天呐，我该从何下手？”没错，这个问题看起来就非常大，但这也是一个实际问题，工程师要去解决的，经常就是模糊的实际问题。

因此，我们希望和候选人一起，做出这样一个将问题从模糊到清晰，从实际到抽象的转化过程，以系统设计的考察路径为例：

根据模糊的表述，明确我们要解决的核心问题是什么？网约车系统那么大，解决问题中，哪一类问题是我们最关注的。

根据我们明确了的最关注的问题，列出相关的功能需求和非功能需求。需求可能包含很多，我们的目标是从中确定在面试时间内关心的部分。

根据需求进行系统设计，包括从客户端、网络、service 到存储等等各层，有了大致的方案以后，我们的目标是从中筛选出我们最关心的一小部分展开讨论。

如果还要考察代码层面，那么就从上述的设计中选取某一个组件，某一个机制，讨论代码层面的设计。

根据代码层面的设计，择要实现，比如可以要求实现核心逻辑，核心数据结构等等。

从中你可以看出，整个思路是这样的：

问题 > 需求 > 系统设计 > 代码设计 > 代码实现

这不就是一个做迷你项目开发的过程吗？没错！虽然说，为了可操作性，每前进一步，都会缩小范围，纵深地考察候选人不同层次的技能。用一个图示来表示的话，正像一个漏斗：

需要说明的是，这就是一个最完整的典型系统设计考察路径，我们不一定要覆盖全部的步骤，但是我观察到许多面试官会覆盖前三步，或是将代码层面的考察，替代为深挖某一个组件或某一个机制的技术选型与 trade off。

不止一个考察角度，不止一个解

这里说的“不止一个考察角度”，指的是一开始同样模糊的描述，可以根据面试计划中的安排，逐步引导到某一个特定的考察角度上去。这一条原则，其实谈的是“广度”。

比方说，就上面提到的这个网约车系统的模糊问题，我们走的是一条系统设计考察的路径。

但是如果考察重点要求我们走一条数据结构和算法考察的路径，那也是可以的，比如从起点到终点的简单的寻路算法，落地到代码；我们还可以走面向对象设计考察的路径，设计关键用例中涉及到的类，包括它们的结构和关联关系，等等。

跟随每一条路径，都一样可以逐步细化、抽象到一个具体的、软件可解的问题。

这里说的“不止一个解”，指的是在更低一级的层面，在细化到上述的具体的问题之后，解答不应该是唯一的，而应该存在多种不同的方法。比方说，寻路类的算法问题，我们有时可以用暴力回溯法来解，有时候可以用经过优化的动态规划方法来解，等等。

事实上，做面试官的一大乐趣正在此——可以和不同的候选人，一起讨论一些自己已经思考过、应用过的技术问题，看到不同人新颖的思路，有些很巧妙，有些很周全。

总结与思考

好，今天我们通过正反两个角度，先从反面介绍了几个糟糕的技术问题典型，再从正面结合例子讲解了我们该把握怎样的技术问题设计原则。

这些设计原则中，我想再谈一谈“从模糊到清晰，从实际到抽象”这一点。我们要看到的是，并不是所有的候选人都可以非常顺利地将一个模糊问题逐步细化清晰的，我们自然也不能复制同一套流程。

我的建议是，越是软件经验丰富的候选人，我们就越可以给一个较为模糊的问题，尽量让他来主导这个分解和细化的过程；而对于校招生，我们则可以给一个相对清晰具体的需求。当然，在这个过程中，如果发现难度过高，我们可以积极地给出提示，或者帮助他完成部分过程，这都是在合理范围内的。

好，今天的内容就是这些，如果你觉得在大方向上有数了，但是还不是特别有谱，那也别着急，因为在下一讲，我会继续讲解技术问题的设计技巧，以及实践中的注意点。在该过程中，我会将例子完全地展开。

最后，我想和你交流一下，你能否谈一谈，在你的面试经历中，是否遇到过糟糕的技术问题，而它们又为什么糟糕呢？

好，我是四火，我们下一讲见。

04 | 问题设计（下）：五个技巧助攻技术问题设计

你好，我是四火。

在上一讲我们学习了技术问题设计的原则之后，今天我们将继续结合实例，围绕原则来进一步分享一些技术问题的设计技巧，以及一些实践中的注意点。希望在这一讲之后，你可以真正掌握技术问题设计的技巧，真正做到“手边有粮，心中不慌”。

技术问题的设计技巧

下面我将逐条讲解技术问题的设计技巧，这些技巧看似都有各自的独立性，但是其实它们是围绕着领域、深度和广度这三个方面展开的，我将给出尽可能具体和完整的例子，来帮助你理解。

从熟悉的领域设计问题

在具体实践方面，这是第一条，也是最重要的一条技巧。什么样的问题，哪怕在发散性探讨时，你依然觉得尽在掌握？那一定是自己熟悉的。相信每一个人都有特别熟悉的领域，举个例子来说，我有一位朋友，也是一位面试官，他在亚马逊工作了 9 年，他喜欢和候选人探讨的一个问题是：

“如果你从头设计亚马逊（或是其它大型电商）的零售业务，你打算怎么做？”

其实这就是一个挺好的问题，话题描述很容易理解，但又足够模糊、足够宽泛，而且可以有很多不同的角度来切入并细化。最重要的是，对他来说，这个领域太熟悉了，基本上不存在明显的思路盲区。

当然，这个问题的领域也必须是“大众”所熟知的，你要是问一个冷门话题，就有可能偏离了考察方向（具体请参考第 3 讲，我在其中做了详细说明）。如果你的工作领域并不为大家所熟知，那么从生活中找问题，或者是从自己的知识领域找问题，也是一个很好的办法，当然，这往往需要多做一点功课。

由浅入深，分层展开

这一条技巧，讲的是“深度”方面，也就是上一讲我们说的“从模糊到清晰，从实际到抽象”原则。还记得我拿来举例的那个问题吗？

“请你设计一个网约车系统。”

下面我们继续沿着系统设计的路径，分析这个问题深入的过程。

在问题抛出以后，有的候选人能够淡定地做进一步沟通，明确问题，而有的候选人则需要面试官逐步引导——“这个问题具体包括什么？”没错，这正是一个分析和细化需求的过程，需要候选人和面试官一起讨论。

显然，我们不可能在面试中完整实现一个网约车系统，但我们可以专注于某几项核心功能。我们可以从核心用例的角度来思考，想想都有什么角色，可以通过该系统完成什么功能，比方说：

乘客可以随时随地叫车；

系统寻找邻近的司机并转发请求，如果无法接单，继续扩大寻找范围；

司机可以抢单，即接受或者拒绝叫车请求；

双方可以刷新自己在地图上的位置，也可以查看彼此当前的位置；

等待期间双方可以查看对方信息；

双方可以查看对方评分，也可以在约车结束后给对方打分；

……

这样梳理后，虽然清楚一点了，但是我们发现其中的内容很多，于是我们可以选择其中最必不可少的一项或几项功能，来跟候选人继续进行探讨，毕竟面试时间有限，贪多嚼不烂。例如，我们就选其中的几项来讨论，其它一概忽略，这就把这个已经简化了的问题进一步简化，于是，问题的范围变得更小了。

在功能需求明确以后，进入设计步骤前，我们还需要讨论确定几项重要的非功能需求。比如用户量有多少、每日的请求数有多少等等。这些数值不需要多么精准，但是数值的数量级会影响到系统的设计。

在上面的过程中，候选人和面试官一起对问题层层梳理，把一个模糊问题转化为一个简化了的业务问题，只剩下有限的几个需求点要实现。

但是麻雀虽小五脏俱全，功能需求和非功能需求都包括了。下一步，才是根据前面选定的需求点，从技术角度去考虑怎么实现；而技术实现，依然要秉承一样的原则，从模糊到清晰，逐步细化：

整个系统上看，有哪些组件，或者说有哪些 service？（组件的调用和依赖关系）

把系统组件和用户角色放到一起，乘客和司机怎样和系统交互？（交互的时序关系）

每一个 service 都有什么职责，系统的数据存储选用什么技术？（存储层设计）

你看，从上面这几个具体问题也可以看出，这正是在花主要的时间，考察候选人对于系统的理解。

在有了一个大体可行的系统设计后，从中选出一层、一个组件，或是一个机制，进一步细化展开。

比如说，对于存储方面，如果候选人提出使用关系型数据来存储乘客和司机的位置信息，那么我们可以通过这样的思路来展开：

你打算设计怎样的表结构来存储这样的信息？

这样的方案是否存在隐患，在产品上线后可能发生怎样的问题？

你打算怎样解决这样的问题？

设定“踮踮脚能够到”的最高难度

下面来谈谈问题的难度。

很显然，不同的候选人，能力是不同的，对于同一个问题能够完成的进展也是不同的。我前面已经说了，问题的深入要有层次，逐步细化问题、抽丝剥茧，最后落实到一个短时间内就能完成的局部实现上。

如果留意到问题对于候选人较为困难，面试官需要动态调控，目的是降低难度，方法可以是给出问题提示、主动减小问题范围、弱化问题要求，甚至直接推进问题分析。而如果问题对于候选人来说过于简单，那就要压缩流程中时间的分配，更多地把时间放到问题解决之后，对于进一步改进等等的“follow-up”的讨论上面。

举个例子，如果一个算法问题是，使用非递归算法实现二叉树的前序和后序遍历，而候选人看起来缺乏头绪，那么我们可以：

给出问题提示：“二叉树是怎样的一种数据结构？前序和后序遍历的定义是什么？”；

减小问题范围：“我们先来只实现前序遍历吧！”；

弱化问题要求：“如果我们可以使用递归来实现呢？”；

推进问题分析：直接介绍前序或者后序遍历，使用非递归来实现的思路。

一句话，通过暗示也好，明推也好，不断深入并击破难度递增的每一层问题挑战，并且最理想的效果，是最终这个迷你项目的最高难度，恰恰是候选人“踮踮脚能够到”的难度，既不会过度简单，又不会难不可达。

这就有点像打电脑游戏，太简单了没意思，候选人也会觉得这家公司和团队不怎么样；太难了则又可能对候选人打击太大，或者导致他无法完成整个问题的解决流程。我们可以通过上面的四种办法，引导候选人理清思路，直到可以开始动手编码的程度。

这个动态调整的过程是需要通过经验的积累，才能驾驭自如。但是我们从一开始，就可以树立这样的目标，我们希望不同程度的候选人，都可以“来时开开心心，走时不住回味”。

面试的过程，如我们之前所说，考察是双向的，我们既要考察候选人的情况，也要给候选人留一个好印象。

持续收集数据，调整你的问题

对于前面提到的“问题的解决流程要完整”，和“抵达‘踮踮脚能够到’的难度”，不知你是否会觉得听起来很难做到，这需要比较高的经验和技巧。

没有错，这也是为什么我们需要“持续收集数据，调整你的问题”。就好像要把任何一件复杂的事情做好，都要经过千锤百炼一样，一个问题设计好了以后，我们要反复地在实践中使用它。

一方面，可以不断地获取数据，这样的数据可以帮助你建立起属于自己的“坐标参考系”，在评估一个新的候选人的时候，我们知道他大概处于一个什么位置；另一方面，又可以根据结果，反向地调整、改进，甚至替换问题，包括可以根据情况适当地增大或者减小问题的范围等等。

举个例子，我认识一位面试官，他在考察算法的面试中，使用一道有关无向图求路径的问题，如果候选人对于无向图的基本知识缺乏了解的话，它就是一道挺难的题目了，毕竟，图的表示和路径求解，并不包含在我们最常见的数据结构和算法里面。这个题目他用了好几次，但是发现候选人普遍“没有思路，答不上来”，于是就不再使用这个题目了。

我的一个经验是，在一个问题（包含确定的某一考察角度）被用了 5 次以上之后，基本上这个问题本身就成熟得多了。

使用一个你自己设计的问题，还会给候选人带来一定的“新鲜感”，做这个迷你项目，解决一个新颖、有趣的问题，而不是互联网上一搜一大把那些。感觉这是一个信手拈来的事情，可他所不知道的是，这个问题是面试官精心准备的，也是在实践中锤炼过的。

拓宽广度，给问题设置多角度延伸

这一条技巧讲的是“广度”，其实就是我们上一讲的“不止一个考察角度，不止一个解”原则。

这次拿我自己来举例，我拿这样一个问题，问了好几十人：

“如果你所在的团队拥有一个重要的 service，它的平均请求响应时间为 1 秒，有一天你部署了软件新版本后，留意到它的平均请求响应时间异常地增大到了 10 秒，你该怎么做？”

这显然是一个实际的问题，而且可以是一大串不同问题的引子，根据考察的需要，我们可以把它延伸出去，进行各种追问。

延伸一——考察对用户体验、对工程的理解：第一时间我们该怎样做，才能把对用户的影响降到最低？我们可能会谈到回滚，那么我们就可以讨论 Ops。怎样避免未来再出现这样的问题？这就可以讨论软件工程的流程，讨论质量保证，讨论 CI/CD，讨论灰度发布等等。这个延伸可以考察软件工程流程的方面，考察 Engineering Excellence 的方面。

延伸二——考察监控和告警系统设计：我们该怎样争取在第一时间知道我们的系统出了问题？这就可以谈论软件监控和告警，我们需要对怎样的数据进行监控和告警？怎样采集数据，怎样发送数据，即怎样设计告警系统？这个延伸可以继续细化到一个监控系统设计的问题，或是做代码层面的考察。

延伸三——考察问题排查思路、系统的理解：我们该怎样去定位问题，问题可能出现在哪一个层面？

比如，可能 service 根本没事，只不过客户端出了问题，也可能网络有了问题，还可能就是 service 出的问题。而 service 出的问题，又可能有哪些原因造成，可以采用怎样的策略，去一层一层从高到低去定位问题所在？这一个延伸可以继续考察候选人对于系统的理解，尤其是通过一个请求响应的过程，考察他对于系统全栈的理解。

延伸四——聚焦系统某一层：通过细化到某一层来进一步展开，这部分的思路就很多了，根据需要我们可以选择几个常用的切入点。

比方说，如果问题是关系数据库的语句过慢造成的，这里我们就可以进一步聚焦，讨论一些常见的关系数据库性能问题出现的原因，以及相应的解决思路。如果是应用层面的问题，比如应用的内存不足，那么可以从这个角度进一步展开。

延伸五——聚焦系统限流问题：如果问题是恰巧由于该时间点某一客户端在短时间内发送过量的请求，系统无法及时处理而导致的拖慢，那么我们就又可以从流量控制的角度展开。流量控制的问题也是属于经典的系统问题之一，既可以从系统设计的角度考察，也可以从代码设计的角度考察。

你看，一个模糊的实际问题，可以拿过来做多种方向的延伸，而这些延伸之间又具备密切的联系。我们可以根据需要，在面试中选取其中一个延伸的角度来进行考察。

平衡考察的深度和广度

如果我们总是能把技术考察，从一个简略、模糊的实际问题开始，逐步深入，到最后以一个完整的问题解决过程收尾，那么几乎就可以说，我们就做到了深度和广度的兼顾。

我曾经两次提到过，为什么我不推荐面试中使用简单粗暴的纯算法题？说到底就是一个考察面的问题，单纯地考察算法题，就是一个可以具备足够的考察深度，但是很容易丢失考察广度的例子。

反过来也一样，我下面来说说覆盖广度而丢失深度的情况。有一种面试风格，是让候选人谈论一个他自己最熟悉，或是最自豪的一个项目，然后从中抓住某些点不断深挖。这本身听起来似乎也是一个挺不错的考察思路，和我们前面谈到的面试官去准备问题的思路，恰好相反——由候选人来主导这个过程。

但是现实中，对于经验尚浅的面试官，我一般不太推荐上面的方式，主要原因是，在实践中这个方式对于面试官的素质要求非常高：如果候选人谈到的项目或者系统，面试官比较熟悉，那一切都好说，但是如果不熟悉呢，面试官就很难把握住这里的关键，容易被候选人牵着鼻子走，可能这一轮面试候选人一直在泛泛地说，谈到了许多方面，但是面试官也提不出什么一针见血的问题。

总结与思考

在上一讲谈论的技术问题设计原则之后，今天我们结合了几个实际例子，讨论了几个技术问题的设计技巧，相信你通过今天的内容，在之前大致思路的基础上，收获到了一些可以用于实践的小窍门。

在文章的最后，我想提一个问题，你能否分享一下，你觉得行之有效的，在面试中考察候选人的小窍门呢？

好，我是四火，我们下一讲见！

答疑课堂01：面试计划篇热点问题解答

你好，我是四火。

这一讲是关于常见问题的答疑课，对专栏第一大板块的“面试准备 / 计划”的篇章，还有一些很有意思的问题，在专栏正文中并没有得到足够透彻的讨论，那么我们就在这里把它们讲透。

问题 1：候选人经验比我丰富，我自认技术上也不如他，因而缺乏驾驭面试的自信怎么办？

这是一个非常常见的面试官心理建设的问题。尤其对刚做面试工作没多久的面试官，这个问题尤为常见。

首先需要明确的一点是，闻道有先后，术业有专攻。没有任何一条面试的原则说，你非要比候选人在某个特定的方面更加出色，才可以面试他。就是在一起工作的团队，其中的不同成员在特定业务和技术上，能力层次还有高有低呢，不过在做项目和沟通交流的时候，大家都是平等的。

其次，面试的过程，从你的角度看，就是使用你的方法考察候选人的过程，也是候选人考察目标团队的过程。

既然如此，把注意力放到你的面试具体实践上，无论是一起讨论一个问题，还是一起做一个小项目。在面试中，不妨把你们之间的关系，看做工作中的同事，一起解决一个业务或技术的难题。

再次，每个面试官都是这样过来的。据我所知，即便经过了相当长的时间，有些面试官还依然觉得战战兢兢，如履薄冰。

要知道有些情况下这是好事，缺乏自信可以让你远离自负，更加认真地对待面试这件事情，从做计划，到面试实施，再到之后的决策。

最后，最开始遇到这种情形时，有些面试官可能会紧张，这是完全正常的。事实上，无论紧张的原因是什么，不要去刻意地尝试克服紧张情绪，而是坦然地接受它。

再说了，适度的紧张还能够帮助提高专注力，我们只需要把注意力尽量转移到面试的流程和步骤上。相信经过多次的实践以后，我们就会慢慢淡定下来了。

问题 2：怎样看待脑筋急转弯类问题？

三个字，不推荐。

脑筋急转弯类问题，英文里比较接近的词是 Brain Teaser，指的是一类题面比较简单，但是解答需要跳出常规思维，给出“出乎意料”答案的一类问题。

原本这类问题就是问着玩儿的，但是后来它被用到了一些面试中去，甚至有不少是大公司，网上有很多关于大厂拿脑筋急转弯面试候选人的故事。

最开始，脑筋急转弯就是一些“娱乐性”很强的问题，但后来慢慢演变出更广泛的形式，看似更考验候选人的思维能力，比方说：

填满一辆校车需要多少个高尔夫球？

不知道你听过这个问题没有，这是网上流传得颇为广泛的一道题，据说是 Google 拿来面试候选人的。

我想说的是，我们只讨论针对软件工程师的面试的话，其实 Google 的技术面试的流程和其它几家互联网大厂都是类似的，如今说他们问脑筋急转弯问题是无稽之谈。而在一些互联网大厂的面试官培训中，都会强调一句话——不要问脑筋急转弯问题。

那我们进一步解释一下这是为什么。还记得我们在第 1 讲中就介绍了，面试的目的就是为了寻找“合适”的技术人才吗？

正因为这样，我们才那么希望面试尽可能还原实际工作的场景，这才有了希望在面试中“讨论一个问题”和“做一个迷你项目”这样的目标，这样收集到的数据，才能比较有效地判断候选人是不是“匹配”的。

而脑筋急转弯呢？即便它能考察候选人的思路是不是开阔，反应是不是迅速，但因为它远离了我们要解决的实际问题，远离了我们的工作场景，既没有业务覆盖，也没有技术覆盖，它在技术面试中的价值实际就很低了。

事实上，这些年来，有许多研究者仔细地分析了脑筋急转弯在面试中的应用，他们发现候选人对于这类问题的回答，和他们在实际工作中的表现缺乏相关性。

比方说这篇论文，它提到在面试中使用脑筋急转弯问题“缺乏有效的证据，且会令候选人感到不安”：

lacks evidence for validity and is unsettling to job applicants

问题 3：怎样看待系统估算类问题？

系统估算类问题，是一种特定的考察候选人对软件系统理解的问题，它要求候选人估算一下在指定场景中，系统的规模的大小。比方说：

已知 Twitter 2020 年大约有 2000 亿的推文（tweets），如果你来设计 Twitter 系统，请问发推服务的吞吐量需要多少，网络带宽要占用多大，要存储它们需要多少磁盘容量？

这里说的是 Twitter 系统，但是类似的提问方式，套用到面试中讨论的软件系统，也是一样的。这个问题如何分析和求解呢？我可以给你一个简单的参考思路：

吞吐量，一般可以估算 TPS（Transaction Per Second），2000 亿 / 365 天 / 24 小时 / 60 分 / 60 秒，大概是 6000 左右，那么考虑 TPS 的波动性，我们简单预留 3 倍的空间，认为系统的 TPS 需要预留到 20000 左右，就大致可行了。

网络带宽，我们假设平均每条推文 200 个字符，众所周知每个字符占用 2 个字节（B，Byte），每个字节为 8 个比特（b，bit），我们在这里统一使用 Byte，而不是 bit（这里说明一下，你的网络运营商为了数据好看，可能会用比特每秒，而不是字节每秒宣传它的带宽）。这样每条推文就占用了 200 * 2 = 400 Byte，因此带宽就是 400 Byte * 20000 吞吐量 = 8 MB 的带宽。这里其实从 B 到 MB 应该使用 1/1024 的倍率，但是估算就使用了近似的 1/1000 的倍率。

存储，2000 亿推文 * 200 个字符 * 2 Byte = 80 TB 一年。

对于系统估算类问题，最重要的是过程要符合逻辑，而估算的最后结果并不是最重要的。过程正确的话，结果的数量级基本上是八九不离十的，那么设计出的系统往往就是靠谱的。

实践上，这一类问题我以前尝试用过，但是和其它类型的问题类型相比，它对候选人的要求其实比较高。我通常在面试高级工程师级别以下的职位时，就不考虑使用系统估算的问题了。

从职位来看，如果职位需要比较强的架构设计能力，或者团队是做软件中的基础设施部分的，那往往就需要候选人具备靠谱且快速的估算能力。

问题 4：对于小公司来说，怎样在人才招聘中和大厂竞争？

严格说，这是一个招聘的问题，而不是一个单纯面试的问题。但是，对于小公司来说，负责面试的同事，很可能承担了更多的职责，甚至有很重的“招人”的压力，这是很多大厂的面试官无法感同身受的。

因此，对他们来说，怎样去和大厂竞争，这就成为了一个实际的、需要在面试前搞清楚的问题，而这个问题有很强的普遍性，因此我想在这里专门谈一下。

有位同学 lihp 在专栏中留言谈到：

最近公司在招聘新人，秉承公司一贯用人理念，精英式团队，对人员的素质要求高，C/C++ 的技术基础扎实，还需要是一个培养潜力的人，尤其是在招聘有经验的工程师岗位（入职即可快速适应工作，参与产品和项目开发），招聘的进度不及预期，年初至今尚未找到合适的人才。

岗位要求技能和能力比较综合，不存在过度关注算法或某一项专项技术的问题，以能力面试为主，只要面试者表现强烈的学习意愿、良好的学习能力和沟通能力，技术基础与经验相匹配即可。

于是我就问道：

就你提到的“尚未找到合适的人才”我也好奇，因为从你简单的描述看似乎要求并不算特别高。那么，你觉得招不到人到底是什么原因呢？

接着他答复道：

公司岗位对合适的人，综合要求较高，学习能力强，思维逻辑清晰，专业技能扎实，也就是说我们觉得合适的人也符合多数大厂要求，候选人可选择性多。

品牌知名度不及大厂。相比于知名的互联网公司，我司主要从事 toB 软件产品开发，在细分行业内还略有名气，但普通大众压根不知道，品牌商和大厂是没法比；

薪资竞争力弱，大厂给更多，即使相同或者略少，大多数候选人也会选择大厂；

筛选得到的候选人少，优秀的人才通过线下、内推等渠道选择工作，我司主要是通过简历、猎头等渠道，符合岗位需要的人数量较少。

对于中小公司，这就是一个现实的问题。

我记得一位负责招聘的朋友说，招人也有“二八现象”，就是市场上长期流通的简历中，有 80% 都是来自那 20% 的候选人，而很多优秀的候选人，在人才市场上出现的时间都很短。

如果要通过常规的招聘网站、猎头等渠道找到优秀的人，必然要面临巨大的竞争，而那些相对优秀的候选人，也就比较容易拿到 offer，甚至多家 offer，这时候企业面临人才的竞争就比较激烈了。

再从这位朋友的描述看，他对他们需要的人才的标准叙述很清晰，对优秀软件工程师的认识也符合主流的招聘标准，但由于知名度、薪资竞争力等方面不及大厂，那么自然，招聘就确实是一件较为困难的事情了。

分析完问题，再说说问题解决的思路。

首先是要清楚自身的优势。知名度和薪资竞争力不及大厂，这是事实，那么也要看到，大厂往往有着大公司病，小公司也可以有它自己的优势，因此差异化是关键。

这个差异化既包括在对候选人的要求上有所区别，也包括提供的福利待遇和工作挑战有自己的优势。比如工作时间和地点灵活，在某些技术细分上顶尖，职位重要性高，工作影响力大，以及能提供未来兑现的期权等等。

无论如何，不和大厂硬刚，寻找自身的优势，只要双方的需求能够得到大致匹配，那么候选人就能招得进来，也能留得住。

我举个自己主导面试的例子吧。大家都知道，无论是从国际上看，还是在北美，Amazon 的 AWS 在云计算领域都遥遥领先，而 Oracle 的 OCI（Oracle Cloud Infrastructure）进入市场晚得多，份额也显然不能同日而语。因此我经常被候选人问到一个问题，作为软件工程师，在 OCI 工作和 AWS 工作相比，有哪些优势？

我会谈到几个方面，其中一个是流程，我经常举一个真实的例子，一位朋友在 AWS 的 S3 组工作，他修改了一行普通的代码，需要经过好多个组的评审，花了整整三个月才让他的代码上线。而在 OCI 就不会有这样的情况发生，流程更为敏捷和快速。

另一方面，如果要讨论影响力（impact），很明显一个相对小一些的组织，软件工程师更需要承担更重要的职责，也往往能在组织中带来更大的影响力。

再者，相较于成熟的 AWS，在 OCI 要解决的问题，往往是模糊的，很多问题更“新”，也更考验软件工程师解决实际问题的能力，这一点很锻炼人。

其次，小公司尤其要扩展招人的渠道。以前我的老板说过一句话，叫做“时刻在招人”。线下的招人渠道，通常竞争更少，比如线下的技术活动，或者是因为开源项目而认识的朋友等等。

我有位朋友正在创业，他的团队能力很强，有意思的是这些人几乎没有一个是通过常规的猎头渠道，或者招聘网站渠道招进来的。

那好，今天就谈这几个问题吧，希望你有所收获。如果你有其它问题，也欢迎你在留言区继续跟我交流探讨，我也会和你聊聊我的看法。

好，我是四火，我们下一讲见。

05 | 流程把控：控好流程，让面试进程高效有温度

你好，我是四火。

“工欲善其事，必先利其器”，在专栏前面的部分，我们已经讲了怎样理解团队的需要，怎样做面试计划，以及怎样设计合适的技术问题，这些，可以说都是在正式面试之前需要搞定的事情。

今天这节课，我将会和你分享面试流程把控的基本思路，以及一些常用技巧。只有把控好流程，我们前面辛苦设计的面试计划、技术问题才能真正派上用场。

流程把控的反面例子

先来问一个开门见山的问题，究竟谁来把控面试流程，候选人还是面试官？

有人说是候选人，当候选人带着自由度表现的时候，才能发挥自己的实力；有人说是面试官，因为面试官需要按照预想，领着候选人来推进面试进展。

好像都有道理对不对？我卖个关子，先不回答这个问题，带着这个问题，我们来看看几个流程把控的反面例子。看看这些例子中，有没有你熟悉的。

收尾时间狂飙代码

这可能是一个一下就映入脑海的反面例子了，也是我见到的最多的一种流程把控的反面例子。

无论是由于问题过于复杂、沟通出现误会、候选人解决问题能力不强，或是候选人或面试官迟到等等原因，到了白板编码环节，候选人有了思路，也开始写了，可时间快没了。

这时候直接放弃吧，有点可惜，于是候选人就擦擦额头上的汗珠，颤抖地拿起记号笔，开始马力十足地在白板上狂奔，字也是越写越龙飞凤舞；而面试官呢，也颇为体谅，让下一位面试官在门外稍加等待，要求延期“就五分钟”，并不断提醒候选人时间越来越少。

最后，无论代码是否写完，面试匆匆结束，就仿佛一场大战结束，候选人累得瘫坐下来，这一轮的面试官一只脚刚迈出会议室，下一轮的面试官另一只脚就迈进来。若是代码基本写完了，候选人心里想，我去，真够紧张刺激，幸亏老子搞定了；若是没写完，可得失落和恍惚好一阵子。结束的时候，双方礼貌性地握手，手心满是汗。

寒暄时间占比不当

这里的“寒暄时间”，指的是技术面试中，正儿八经讨论技术问题以外的时间，一般发生在面试开始时和结束前。

一种极端情况是这个时间过短，甚至没有。候选人和面试官见了面，握个手，就开始做题，连个过渡都没有，让人觉得颇为唐突——“是不是这个团队都是老古板啊？”。

另一种极端情况是，打个招呼，互相介绍一下，聊两句感兴趣的话题，或是最近的热点新闻。扯扯淡，聊聊天，帮助候选人放松一下。本来这些都是挺好的“操作”，但问题是这个时间如果拖得太长，原本的技术考察重点就打了折扣。

我分享一个我 shadow（观摩）的经历，有一位面试官在面试中和候选人“闲聊”，面试的一半时间过去了，候选人终于忍不住了，她主动问面试官，“咱们不谈点什么技术问题吗？还是继续这样随便聊吗？”，他们这才开始讨论技术。

考虑到在面试计划的时候，这位面试官是确定要考察算法和数据结构的，因此事后我问面试官，我理解这也是一种面试风格，可既然面试计划已经确定了，你为什么没有主导这个面试过程，让技术方面的讨论早一点开始？面试官回答说，他想看看候选人有没有足够的主动性主导这个面试过程。

对于这个案例，我的想法是，面试官这样做，虽然考察了他所关心的“候选人的主动性”这个数据点，但也使得这个面试偏离了原本的计划，也就是说，在我看来，确有所得，但得不偿失。

踌躇不定的思路选择

这个例子是来自于我自己。

一个问题往往有很多解决的思路，有一次，候选人和我讨论某个问题的算法，这个过程一开始还挺顺利，候选人选择使用 Map+ 数组排序的思路做，方案虽然略有一些硬伤，但是也行得通；期间他忽然想到，使用一个二叉搜索树数据结构的思路更好，于是我们又放弃了前面的思路，沿着这条路推进；结果忙活到一半，他忽然再一次“恍然大悟”，觉得可以用一个 Map+ 链表的方式来做更简单。

这整个过程其实没有太大的问题，整个思路的转变，反映了候选人很好的思考能力，能够跳出具体实现，重新审视问题。

但是由于这一系列的思路调整耽误了太长时间，导致到面试结束的时候，我们只讨论了思路，连完整的方案都没有讨论清楚，自然原本计划的编码根本没有时间开展。从考察角度来说的话，我们就丢失了相当一部分考察项的覆盖。

流程把控的技巧

不知道刚才那几个例子是否给你带来了似曾相识的感觉？其实这些反例说到底还是因为流程把控没做好。

那既然如此，下面我就来正面谈一谈我的理解，带你一起看看有哪些流程把控的技巧。这些技巧能够帮助我们在面试中，保证最核心的考察项能够覆盖到，同时，还能够给候选人留下一个好印象。毕竟，如同我们在专栏前文中所说，面试是“双向”的。

有头有尾，有礼有节

首先我要谈的，不是什么复杂的技巧，而是礼节。

什么，礼节？对，你没有看错。我认为，面试官有义务确保考察过程的完整性，这能让候选人心情愉悦，在友好的氛围里完成面试的过程。

不知你是否听说过，有一些面试的风格颇为激进，甚至不尊重人，观察候选人在极端压力下的表现。也许这确实可以让面试官得到他想要的考察数据，但我认为这是非常不妥的。

面试，说到底是社交活动的一种，我们必须建立在平等和尊重的基础上，我们要达到目的，但不能不择手段，因此在我看来，这就是一个根本性的错误。

我觉得面试就有点像是江湖上相逢，缘分一场，我们客客气气地切磋武艺，点到为止，你我互相尊重，为的也是来日好再相见。

面试应该做到有头有尾，在面试开始时，我们可以：

礼貌地打招呼、握手，邀请候选人坐下，问问今天感觉怎么样，如果迟到了要表示歉意；

询问候选人是不是需要休息两分钟，是不是需要喝水，是不是需要使用洗手间，在不少互联网大厂的面试培训里，这一条都被反复提到；

做自我介绍，这个自我介绍可以很简单，一两句话概括，但是让彼此认识的环节不能少；

可以简单提一提，在今天的面试中可以预期的内容，这样候选人会有个心理准备。

而在面试结束前，我们可以：

表示问题的讨论告一段落，留给对方问问题的机会，表示在自己力所能及的范围内将努力回答对方的问题；

对于候选人的到访表示感谢，可以赞许一下今天的讨论，也可以对他后续的求职过程表示祝愿；

礼貌地握手、告别。

对于电话面试，或者是特殊时期的线上面试，不能握手了，可上面大部分礼节还是一样的。上述这样的过程也许用不了 5 分钟、10 分钟，但是面试的整个过程显得自然、得体，并且也能够帮助候选人放松。

你看，这些有什么特别的技巧吗？完全没有，上面这些哪是在说面试啊，其实只是礼仪之邦的待客之道对不对？

没错！其实，要做到上面这些，只需要细心，并不需要多么高深的技巧，但是却能够令候选人大大提升印象分。还是那句话，面试是双向的。面对多家竞争对手的时候，你肯定希望优秀的候选人能够选择你的公司和团队。

我说一个我自己的故事，那是在好几年前了，我在找工作期间，在国内几个城市都面试了几家公司，只有当时在北京的亚马逊，面试的过程中，面试官主动给我倒水，面试完毕后送我离开（当时需要上出租车，赶去机场）。且不说面试的内容，这些细节给了我非常正面的印象，我相信无论业务和技术怎样，面试我的团队至少是非常懂得尊重人的。

做一个完整的项目

对于技术面试而言，面试官要抱着和候选人一起做一个有头有尾的迷你项目的心态。

这里，“迷你项目”这四个字可以说是重中之重，即所谓“麻雀虽小而五脏俱全”。这个问题的解决过程要完整，从需求澄清，到分解、设计、抽象、落地、验证、改进，有头有尾。

举例来说，前文所谈到的这个网约车的问题，我们考察的是数据结构和算法，在代码层面“落地”的思路沟通清楚以后，就可以写白板代码了。

在代码完成后，候选人可以使用一个简单用例走读代码，验证正确性。再之后，面试官还可以提出“follow-up”问题，比如聊一聊有什么瓶颈，怎么改进。

好，我想从中你可以看到这样一个完整的过程，而理想的面试，确实也不应该在中间的某一个过程戛然而止。

比方说，如果代码实现的思路讨论清楚了，但是因为没有时间完成代码实现，想必候选人也会觉得沮丧；而只有一个完整的过程，才会让候选人如释重负，有一种“项目完成了”的成就感。

举例来说，一个模糊的问题，一个代码层面考察（例如算法和数据结构）的路径，一轮面试总时间为 1 小时，而去除寒暄和收尾的环节，核心时间为 50 分钟，那么可以参考这样一个时间分配的思路：

10 分钟澄清问题，厘清面试中需要实现的需求，细化到可讨论实现的层面；

15 分钟分析、讨论该需求抽象后的问题，这些问题必须是软件可解的，比如该使用怎样的数据结构和算法来解决，时间、空间复杂度各是多少；

15 分钟现场编码；

5 分钟使用实际用例走读代码，验证正确性；

5 分钟讨论算法的优化，以及进一步的改进空间。

你可能会问，现场编码只有 15 分钟，这么短的时间，够吗？

够。这里我必须说明的是，在编码前，我们期待候选人和面试官已经将思路大体上沟通清楚了，那么这个编码过程，其实只不过是一个将思路“翻译”成代码的过程而已。

我们在编码前对于思路和逻辑的讨论，目的就是要保证编码能够顺利进行，所有的关于“problem solving”的部分基本已经解决，于是就只剩编码过程。

值得注意的是，编码前的思路和讨论，以及编码本身，我们考察的侧重点是不一样的。比方说，有的候选人就是具备很强的逻辑能力，来解决问题，但是就是无法将思路落实到代码上。因此，别看过程很短暂，却是不可缺少的。

你可能也注意到，在需求确认以后，很多候选人都喜欢上来就立马落笔写代码，但作为面试官来说，是不是可以落笔，需要着重关注候选人是不是已经有了清晰的思路，否则很可能浪费时间。这样急于落笔也很难一蹴而就，来回涂改，会做很多无用功。

如果你留意到，候选人即便有了清晰的思路，在基础编码能力具备的情况下，代码的实现依然要花费超过 15 分钟，那么你就应该考虑调整这个问题的设计了，是不是要求代码实现的部分过于复杂，从而最终导致在限定时间内，整个问题的解决流程无法完成。

如果是这种情况，我们可以要求只实现代码片段，例如算法的核心部分，或者是涉及到的几个重要的类，而不是整段代码。通过这种方式，我们可以将预期的编码时长降下来。

举例来说，如果实现一个完整的 LRU 缓存颇为耗时，那么算法实现可以要求写出数据结构，以及其中缓存更新的部分。

另外，你可能还听说过，在有些面试中，面试官会在一轮面试中，要求实现两个较为简单的算法。这种情况确实有，但是我一般是不推荐的，原因就是，这整个问题的讨论和解决过程已经颇为耗时了，很难在一轮面试中覆盖一个以上的算法实现。

如果硬要塞进两个算法题的实现，那就要问非常简单的问题，那么，即便勉强做到了，用意又何在呢？

选择合适的介入时机

还记得这一讲一开始，我开门见山地问的那个问题吗？“究竟谁来把控面试流程，候选人还是面试官？”

我打个比方，一个国家的经济活动有强有弱，走势有高有低，通常情况下，从大体上看，市场经济可以自然地发展，但是在某些特殊环节，或者极端情况下，国家需要介入，需要调控。

面试也是如此。我认为，在核心时间中，面试官应该关注于大的层面上，是不是能够顺利完成今天的考察内容，是不是能够得到自己关心的考察数据。

如果候选人能力很强，对于问题的推进合理有效，那么面试官就要学会做“绿叶”，给对方更多的发挥空间，让对方去主导问题的解决，这当然是最理想的情况，候选人能跟着自己的计划走，自然也最舒服。

反之，如果遇到了困难（还记得我们上一讲在“设定‘踮踮脚能够到’的最高难度”部分，谈到的降低难度的方法吗？），或者看着路线要“跑偏”，或者时间进度已经大大落后，那么面试官就要毫不犹豫地及时介入，主动调控，从而保证整个方向和时间的可控。

总结与思考

好，今天我们开始讲怎样主导技术面试，把控流程了，既谈到了一些常见的反面例子，又介绍了我们应该掌握怎样的技巧，完成一个成功的技术面试。

在这一讲的最后，我想再次强调“互相尊重”的重要性，虽然我不会在专栏中再反复强调它，但请记得它是我们面试等一切职业行为的最基本要求。

最后，我有一个问题，正在阅读的你，能否在评论区和大家一起聊一聊，你作为候选人参与过的面试，都有哪一些有意思的细节呢？期待你的分享。

好，我是四火，我们下一讲见！

06 | 算法和数据结构考察：怎样有层次地驾驭算法考察？

你好，我是四火。

在上一讲中，我们学习了从整体上怎样做流程把控，那么从这一讲我将针对技术面试中最常见的考察重点，做进一步的展开。

为了让你系统地学习，我会根据常见的技术考察重点分类，从数据结构和算法，系统设计，面向对象、测试和其它工程技能，以及行为面试这样几个部分分别介绍。

每一部分，我都会从反面列举一些典型的不当实践，再从正面分享一些考察技巧。今天要讲的是数据结构和算法的部分，除去上述内容，我在最后还给出了一个模拟案例，帮助你完全理解进行算法和数据结构考察的过程。

首先我要说明的是，今天这一讲开始的这些阐述，都不是针对一个完整的面试过程展开的，而是从整个过程中，提炼出最能够体现考察重点的其中几个步骤。如果你不清楚一个完整面试过程应该怎样去把握，可以回看前几讲。

糟糕的例子

我先说几个典型的、糟糕的例子，可以说，数据结构和算法恐怕是技术层面最常见的考察点了，所以，所谓的不当操作，也出现得最多。

闷头编码

在我见到的编码面试中，这一点可以说是出现得最为频繁的问题。请你联想实际工作，如果你的团队中有这样一个工程师，拿到需求以后，不确认问题、不沟通设计、不讨论方案，直接就开始埋头苦干，就算能写出可以工作的代码，这是不是依然是一件无比恐怖的事情？

显然，我们的面试一大目的就是排雷，就是要尽可能避免这样的事情在实际工作中发生。毕竟我们要找的是软件工程师，不是只会刷题的编码者。

在专栏前面的几讲，我已经反复讲到了，我们怎样去设计问题，怎样层层推进，而不要上来就编码。

但事实上，据我观察，我相信大部分具备技术背景的面试官都非常清楚，闷头编码“不好”，但往往还是由于缺乏主动、坚决介入的决心，在这种情况下听之任之。作为面试官，我们不要去想当然地认为，这只是候选人自己应该意识到的问题。

只写伪代码

你也许会对这一点不以为然，为什么只写伪代码不行？伪代码和实际代码能差多远？

从工程的角度说，它们差得很远。伪代码，其实说到底，只是问题解决逻辑的其中一个表达形式而已，或者说，不写伪代码，也可以用作图、文字描述等等方式将逻辑表达出来。

我们不反对候选人写伪代码，如果这能帮助他理清思路，那为什么不呢？但作为数据结构和算法面试的一个核心，候选人不能只写伪代码。

那么我们就再说说代码。从代码可以看出编码能力，这是软件工程师最最基本的工程技能。就好像造房子，图纸上可以设计得清清楚楚，而编码就是根据图纸把房子造出来、把方案真正落地。编码能力，从本质上说，就是将思路、逻辑工程化的能力。

从编码可以看出工程思维是不是严谨，是不是各种 corner case 都考虑到了？是不是具备编程语言功底，能够比较流畅地将思路转化到具体实现上？是不是能够比较好地组织代码，方法设计合理，层次结构清晰，变量命名一致？是不是具备良好的面向对象思维和模块化思维？

有了具体代码以后，我们还可以进一步给面试中这个迷你项目收尾，比如讨论一下对于实现的代码，怎样使用测试去覆盖，哪些地方容易出现瓶颈，哪些地方可以进一步优化等等。从这里可以看出，实际代码的作用非常之大，别的形式都无法代替。

事实上，我本周刚刚面试了一个职业经历很丰富的软件工程师候选人，他做过产品经理，做过解决方案工程师，最近的一份工作是咨询师。

他的面试其它表现基本可以说还不错，但就是几乎没有编码能力。最后我们给了他一个进行其它职位评估的可能，但毫无疑问的是，软件工程师的岗位，恐怕他是很难胜任的。

纠结编码细节

不同的编程语言，有不同的库函数、API 可以调用，但是有的时候候选人记不太清楚。比如说，对于 Java 的 Queue 接口来说，往队列里面添加一个元素可以用 offer()，或者用 add()，我注意到很多候选人都不清楚这两个的区别，甚至有用 push() 的。有时候候选人就很沮丧，觉得这是一个大错。

但在我看来，这完全不是什么问题，属于“知道最好，不记得也没什么大不了”的小记忆点而已，它并不能左右我们对于候选人整体的评估。我遇到这种情况时，为了避免候选人担心，往往会主动向其说明。

类似地，有时候我们能见到候选人纠结于某一个变量的命名，把 A 改成 B，觉得不好，又改成 C，过一会又回来把它改回 A。

这样的“纠结症”真的非常常见，我们当然要关心变量的命名，是不是一致、是不是具体化、是不是符合实际的意义，但是归根结底，我们需要帮助候选人把最多的编码时间精力花费在最核心的代码逻辑上，不要让他们捡了芝麻，丢了西瓜。

考察技巧

好，前面我们从反面列了一些典型情况，它们都发生在数据结构和编码的考察过程中，它们也都说明，面试官本可以帮助候选人在这样的面试中给出更充分、更客观的，关于编码能力的数据点，不知道你是否也有相似的经历呢？

下面我从正面介绍几个考察技巧。这些内容来自我的经验，这里选了面试比较常见和常用的，但如果你有希望补充的场景，或是遇到了具体问题，也欢迎在评论区提出来。

白板编码

一直有争议的白板编码必须得放在第一条。

现场的白板编码好不好？老实说，不好。面对什么都没有的白板，候选人压力大，也没有工作中 IDE 能够带来的方法提示，还需要考验候选人的握笔和书写能力。

但是，我依然觉得，白板编码是如今这些现场编码考察的操作方式中，最公平、最直接，且最有效的一种方式了，这有点像高考。

和使用 IDE 编码比，它更为公平、统一，所有候选人都是一样的，而且候选人往往更放得开、参与性强，在白板上讨论问题可以说是非常高效；和使用白纸相比，除去前述优点以外，还便于涂改。

当然，现在疫情期间，或是电话面试的原因，如果白板不方便，那么一些在线的编码工具也是一个折中的方案。

白板编码的过程中，作为面试官，我们要扮演一个怎样的角色呢？我们不光要做候选人的同事，一起讨论问题，我们还需要在必要的时候介入，推进问题的解决，或是帮助候选人进行时间管理。

追随候选人的思路

在思考数据结构和算法这一类问题的时候，我观察到，有很多不同的思维方式。比如说，有自上而下的，也有自下而上的，有按照递归思考的，有按照循环思考的。

作为面试官，只要思考是向着大体正确的方向，我们的优先选项一定是顺着候选人的思路走，一起讨论，即便这样的思路不是最佳的。

在有了思路基本清晰了以后，如果时间充裕，且候选人显示出具备挑战更好的解决方法的能力，那么我们可以再进一步挖掘，看看能否在给出一定提示的前提下，促使候选人更进一步，找到一个更好的解。

但是如果觉得继续前进比较困难，或者看起来要花费较多的时间，我们可以立即收手，告诉候选人“我们一会有时间的话再来讨论这个思路”，先回归到他原来的思路上去。

我们经常能够听到一些面试“箴言”说：如果你无法给出最优解，那么至少也给出一个解，哪怕是一个暴力解，也比没有解要强。这道理朴素且正确，但我们要清楚的是，这件事情不能完全依赖于候选人，期望他自己就能意识到，还需要面试官引导。

模拟案例

好，在正反两个角度都谈过之后，我们讲一个模拟案例。比如有这样一个问题：

某社交网站有两千万的注册用户，每个用户都有积分属性，且根据在线用户在社交网站上的行为，积分会有小幅度的变更（比如登录一次就 +1 分，评论一次就 +2 分等等，每次不超过 3 分），在线用户还需要频繁地获取自己在所有用户中基于积分的排名，那么，要设计一种什么样的算法，才能高效、准确、实时地获取指定用户的排名呢？

这个问题描述有两个关键字：“准确”和“实时”，如果没有这两个词的限制，那么很多“模糊准确”的方法都可以采用，说白了就是牺牲一致性的方法，比如异步、定时的排序，就些是最容易想到的方案。

如果候选人具备更进一步的能力，我们就可以尝试，能否在满足这两个修饰词限制的情况下，找到好的实现方案。

接下来，我会列举一个详细的对话片段，我们来看看面试官怎样和候选人一起讨论，逐步推进模拟案例中这个积分排序问题的求解。

第一阶段：简单排序

候选人：我觉得问题的解法就是，在每次需要获取排名的时候，根据用户的积分，对这两千万个用户进行排序。

面试官：好，这样的方式下，对于每次排名的获取，时间、空间复杂度是多少？（要求澄清）

候选人：用户量是 n 的话，时间复杂度是 n*log(n)……（说着说着自己意识到时间复杂度较大）

面试官：对了，如果说这个时间复杂度我们无法接受，你能否优化这个效率？（给出挑战）

候选人：……（提出了一些排序的优化思路，但是他自己对它们的效率也不满意）

第二阶段：维护用户的有序数组

面试官：好，为什么这些思路的效率都不令人满意呢，就是因为这个排序对不对？如果在需要获取排名的时候，才给那么大的数组排序，看起来就很难高效了。（给出挑战）

候选人：对了，可以让数据一直是排好序的！这样就不用在获取排名的时候现排了。

面试官：嗯，是一个挺有意思的方向，那你怎么设计这个机制呢？（要求澄清）

候选人：我可以使用一个 map 来保存用户 ID 到排序记录的映射，再把所有用户的记录，根据积分从大到小按序放在数组中，这样二分查找就可以找到对应积分所处的排名。

面试官：能举例说说吗？（要求澄清）

候选人：你看下面这个图，左边是一个 map，右边是一个数组。用户（ID=6）通过数组下标 index 找到对应的在右边数组中的记录，积分是 12345，和用户（ID=7）的积分相同，排名也是相同的 3337；而用户（ID=8）的积分是 545，排名是 65654。

面试官：了解了，很不错的想法。那么这时候获取排名的时间复杂度是多少？（要求澄清）

候选人：Map 映射的复杂度是 O(1)，找到右侧数组中的记录，也就找到了排名，所以整体的时间复杂度是 O(1)。

面试官：嗯，那每当用户的积分小幅变化的时候，你怎么保持这个数组依然有序？（要求澄清）

候选人：更新一下这个积分，然后再调整一下这个记录在右侧数组中的位置。

面试官：这个变更影响的数据量有多少呢？（要求澄清）

候选人：影响的数据量取决于积分变化幅度，对于积分是 12345 的这条记录，如果积分 +3，那么就可能影响所有积分从 12345 到 12348 的用户。

面试官：不错，那么这些受影响用户，对应右侧表中的 index 都可能会发生改变，你怎么去更新左侧 map 中的记录呢？（要求澄清）

候选人：哦，那就需要在右侧数组的每一条记录中，增加一个用户 ID，这样对于任意一条发生更新的记录，就可以以 O(1) 的时间复杂度找到左侧 map 中的记录来更新。

第三阶段：维护积分的有序数组

面试官：好，现在，假设说新注册用户很多，可能会有大量的用户拥有相同的积分，比如只有 1 分，或者 2 分这样非常小的数。那样的话，如果这些用户的积分有一点微小的变化，就会引起排名的剧烈变化，于是右侧数组中大量数据的移位——这个问题，你能否解决？（给出挑战）

候选人：……有了！使用积分关联，而不是单个用户数据来关联——左侧 map 只存放用户 ID 和对应右侧数组中积分记录的下标，右侧数组只存放积分对应的排名，这样每次小的积分变更，只需要根据下标往上、往下找几条记录就可以了，因此影响的行数就非常少了，并且右侧数组的更新也不需要改变左侧 map。

面试官：能举例说说吗？（要求澄清）

候选人：你看下面这个图，左边 map 的用户（ID=6）和用户（ID=7）都有 12345 分，都指向了下标是 1220 的数组记录，因此在右侧数组的第 1220 条记录中就找到了排名。下标是 1221 的排名比相邻的 1220 的排名高了 2，说明有两个用户的积分都是 12345。

第四阶段：维护积分的有序链表

面试官：很好，可右侧的数组里面，积分的出现并不一定是连续的，因此这个方法会带来一个问题，你能想到吗？（给出挑战）

候选人：……（思考）

面试官：比如说，上面的例子，右侧数组里面，用户（ID=6）增加了 1 分，12345 变成了 12346，而 12346 又不存在，会出现什么问题？（给出挑战）

候选人：哦，如果积分变化以后，新的积分是没有出现过的，那么添加到数组里，就是一个新元素，于是所有比它小的积分，其所在的数组元素全部都要向后平移（shift）一个单位，这样的错位导致左边的 map 和右边的数组中的元素都要大量更新。

面试官：非常好，那么你怎么优化？（要求澄清）

候选人：如果使用链表代替数组，就可以解决这个问题了。把通过数组下标的关联，改成通过链表元素引用的关联。因此，我需要一个双向列表，这样积分新增或减去一个小的变化量的时候，就可以快速完成更新了。

第五阶段：Follow-up 问题

对于上面这个问题，在讨论清楚思路以后就可以写代码了，如果编码顺利，还可以继续 follow-up 问题的挑战，比如：

面试官：由于某个原因，我们一次赠送给一批量用户十万积分，也就是说，我们讨论的这个积分变化的增量，如果非常大，那么在右侧链表中可能影响的数据量也非常大，这种情况有没有办法优化？（给出挑战）

候选人：……（这一步也有很多可行的思路，比如有用跳表的，有用线段树等解法的）

以上，问题其实有很多解法，而这个具体的问题与解法不是最重要的，最重要的是，我希望通过刚才的例子把这个互动的模式交代清楚。

你可能已经发现了，面试官最重要的话基本可以分成下面这两类：

给出挑战：接着既有的内容，提出新的问题，增加新的限制，给候选人创造新的挑战；

要求澄清：基于候选人的陈述，要求进一步解释问题，细化解决方法，或者给出实例。

候选人往往就是这样在面试官给出挑战，或者是要求澄清的反复引导下，一起分析思考，逐步推进问题的解决。

实际这个过程并不一定那么顺利，或许也只能抵达到其中的某一步位置，但是我们的难度控制，是希望最终候选人能抵达一个“踮踮脚能够到”的位置（我们在第 4 讲已经谈到过），并至少有时间完成核心代码。

如果你觉得意犹未尽，我在《全栈工程师修炼指南》的第 36 讲中，介绍了一个流量控制问题如何从算法角度层层推进，你可以继续做拓展阅读。

总结与思考

好，今天的内容主要就是这些，我列出了算法和数据结构考察的一些反面实践，并结合自身经验推荐给你一些考察技巧，最后还通过一个模拟案例，帮助你理解这个过程。

在这个过程中，我们需要用“给出挑战”和“要求澄清”两种方式，不断地推进问题的解决。

在最后，我想问一个问题，对于算法和数据结构的考察，都有哪些你觉得很有价值的技巧，或者有哪些需要避开的坑，你能否在留言区谈一谈呢？我会就你的想法和问题和大家一起讨论。

好，我是四火，我们下一讲见！

07 | 系统设计能力考察：系统设计内功到底怎么考？

你好，我是四火。

在上一讲，我们谈到对于数据结构和算法部分考察的把控，这一讲，我们来聊聊系统设计。

我们经常说软件工程师要注意积累工作经验，那么，年复一年的工作中，我们到底积累了哪些技术方面的经验？

我想，其中很重要的一个就是对于系统的理解。对于刚毕业和工作不久的工程师来说，我们不应苛求他们对系统具备相当深度的理解；另一方面，即便工作年数相同，不同候选人对于系统的认识深度也有着非常大的差距。

和能够明确判断出正误的算法类问题不同，系统设计我们往往没法给出丁是丁卯是卯的正误判断，因而面试中讨论的更多是可行性，以及对于不同实现方案的利弊权衡。这也是符合现实逻辑的，有一些相似的系统，它们的实现技术截然不同，有着不同的优势和短板，但是最终都解决了最核心的问题。

糟糕的例子

好，我们先来说几个典型的反面例子，和算法、数据结构的面试不同，系统设计的面试往往能遵循的简单套路更少，因而也能见到更多的“踩坑”实践。

排斥不一样的思路

最典型的例子就是面试官缺乏包容心。就像“看自己的代码越看越开心，看别人的代码越看越糟心”一样，在讨论一些经典系统设计思路的时候，如果对方的思路和常规思路明显不同，某些面试官可能会立即觉得对方的想法很“奇葩”。

这种想法其实是非常危险的，因为面试官在心里默默建立了一个护城墙，凡是不符合“标准”的解决思路，都会产生排斥心理。

下面我举一个具体例子说明吧。有一次，某位面试官和候选人讨论，怎样设计一个篮球比赛的文字直播系统。

这个系统需要实时显示当前的比分等信息，那么一种思路是使用普通的查询，客户端主动发起，即定时地不断询问服务端最新的比分；还有一种思路是使用长连接，或者 long poll 这样的机制，使得服务端可以更实时地推送最新的比分更新。

很多系统都采用后者的思路来实现，这主要是基于实时性等方面的考虑，但是当时候选人考虑使用前一种方案。于是，面试官就直接中断了他的陈述，并直接解释为什么应该选择后者。

暂且不说所谓的正误，或者好与不好。这个技术实现选择的不一致，本来可以引出一个很好的面试实践，也就是对两种实现机制的利弊做讨论，但很遗憾，这种打断的做法直接终止了这样的讨论。

也就是说，我们完全可以跟着候选人的思路，用上一讲提到的“要求澄清”的办法让他自己来分析出实现的利弊来。

之后，如果候选人自己意识到，或者面试官使用“给出挑战”这样的办法，通过讨论这个方案的不足，来引出后一个方案，并放到一起进行优劣比较。

这样一来就可以有比较多的讨论与互动，我们也能得到更多的关于候选人对于系统理解的数据点。我想强调的是，最后采用哪一个方案其实并不重要，重要的是这个过程和我们得到的考察数据。

还有种类似情况是，有时候选人对于系统的设计思路是自底向上的，而面试官则是自上而下的。

一般说来，自底向上去思考和设计系统的时候，确实存在“捡了芝麻丢了西瓜”的情况，但是如果面试中候选人这么做，我们不要去打断他，或者破坏他的这种思维模式，而要顺着他最熟悉的方法来讨论这个问题。

我们做系统设计面试的目的，是要考察候选人对于系统的理解，抓住一些有意义的数据点，而不是要尝试去把系统设计做到最好。

换言之，我们在面试中，一定要摒弃掉所谓的“最佳设计”或者“推荐方案”这样的想法，而是尽量追着候选人的思路跑！

最后设计出的系统也许有这样那样的问题，但请记住面试官可以主导面试，却最好不要主导设计——完成的系统一定是一个候选人主导设计的系统，而不是面试官。

无意义的深挖

我们当然可以针对系统的某一个点进行深挖，但是如果候选人已经暴露出，他还不具备深挖该问题的基础知识，那么这个继续深挖很可能就是徒劳的，因为它除了给候选人带来沮丧以外，并不能得到太多更有价值的考察数据点。

举个例子，有一位面试官和候选人一起讨论“短 URL 系统”的设计问题。其中一个点是，在做短 URL 重定向的时候，返回码应该选择 301 还是 302？

302 是临时重定向，301 是永久重定向，虽然 301 可能会减轻一定的访问压力，但通常来说，我们一般都选择 302。这里的原因是，这些系统有一个很大的价值就是可以获取用户的访问数据，使用 301 可能会使得用户后续的访问直接跳过了这个系统，而去访问重定向后的系统，这样，这些有价值的 URL 访问数据就丢失了。

但是，当时候选人只对 HTTP 返回码略有了解，并不知道 301 和 302 的意义是什么，回答也明显有些搪塞，这种情况下，面试官还想继续往下挖，问到底应该选择 301 还是 302。我觉得，这种深挖的意义就不大了。

考察技巧

好了，说完反面，下面来从正面讲讲系统设计考察的技巧。通常来说，系统设计的考察有两种主要形式：

第一种，是让候选人讲他自己熟悉的、做过的系统，或者是引以为豪的项目；

第二种，是像前几讲中介绍的那样，给出一个实际问题，细化、分析，延伸成一个对于核心功能的系统设计问题，并加以讨论和解决。

做过的系统

第一种面试方式非常常见。让候选人谈论做过的系统，把握一条原则，是候选人必须非常熟悉，最好是“最”熟悉的系统，这样我们才能了解到，候选人在过去的工作中，表现如何，有多深入的理解，又有多少思考。

我们不妨回想一下其它的技术方面的考察路径，如果是算法和数据结构，问“做过的算法”，好像很难这么问，而且这么问很可能也挖不到什么有价值的信息；如果是面向对象，问“做过的项目中，类和方法的设计”，听起来就觉得非常别扭，对不对？

确实如此，对于技术方面的考察点，唯有系统设计，问“做过的系统”，是一个非常好的途径。

话说回来，这样的面试方式，也存在着一定的局限性。

最大的问题，就是它只考察了候选人对于“已有系统”的理解，多为“经验之谈”，这是可以事先充分准备的。它并不能很好反映出，对于一个陌生的新问题，候选人能否灵活地运用掌握的套路和方法来解决它。

事实上，在面试中，我也确实遇到个别候选人，虽然对于自己做过的项目说得头头是道，但给出一个新问题，却畏手畏脚，缺乏想法，表现不佳。

其次，必须指出的是，这种方式，对于面试官的素质也有着相当高的要求。

因为相对而言，这种方式下，谈论怎样的系统，包含着怎样的问题，涉及到怎样的技术，都是候选人所主导的，如果面试官并不具备丰富的经验，又恰好遇到一个不属于自己熟悉领域的软件系统，有时候就没办法提出一针见血的问题，也没法采集到充分且有说服力的考察数据。

在某些大厂的面试培训中，培训老师甚至会明确建议，经验较少的面试官不要主导系统设计面试，而是主导相对容易操作的算法和数据结构的面试。

对于发问，我们可以这样做：

你能否介绍一下，过去有哪一个你最熟悉，或是最引以为傲的软件系统？

我们也可以找到简历上最加以渲染的项目，而发问：

你在简历上说，你主导了一个半年期的项目 X，我对于这个系统很感兴趣，你能否介绍一下？

其实这两个方式的目的是一致的。

对于考察的过程，我觉得要从宏观和微观层面去分别把握。

在宏观上，观察候选人能否对他介绍的系统有着清晰的把握，有着整体的认识，而不是一下子就跳到某一个具体细节实现上去。比如说：

系统解决了什么问题？

系统的架构是怎样的？

模块、组件之间的交互是怎样的？

系统存在哪些问题，有哪些瓶颈？

如果再给一次重新设计系统的机会，哪些地方可以改善？

在微观上，对于候选人自己熟悉的、做过的部分，我们要选择几个点向下挖，并且挖掘得足够深，到“具体是怎样实现的”这样的程度，毕竟在现实中，夸夸其谈的人不在少数。

“深入”的核心，就是要抓住两个词——“具体”和“细节”，下面我通过一个小例子来说明。

比方说，候选人说，他最近主导了一个三个月期的性能优化项目，那我们就可以抓住这一点进一步细化。请看下面这个对话片段：

候选人：我最近在项目中把门户网站的性能优化了一倍。

面试官：我很感兴趣，能具体说说是什么方面的性能优化了一倍吗？

候选人：是网页的加载时间优化了一倍，以前平均一个页面要将近 3 秒，现在 1.5 秒就可以打开了。

面试官：是什么网页，门户网站的所有网页吗？

候选人：不是，是媒体详情页，不是媒体列表页。

面试官：哦，那你做了哪些改进才做到的呢？

候选人：我把详情页上的评论部分改成 Ajax 调用了，这样页面加载出来，用户浏览评论区时再去异步请求获取评论。

面试官：了解了，那你通过什么方法得知这个页面加载时间从 3 秒优化成 1.5 秒的呢？

候选人：我们做了性能测试，压测我们 beta 环境的系统，1.5 秒是 TP99 的值。

面试官：那在压测的过程中，系统的吞吐量是多少呢？

候选人：只有一个主请求，没有模拟静态资源访问的情况下，QPS 上限大概是 2000。

面试官：那在测试中你是怎样确认这个 QPS 已经达到上限了？

候选人：根据我们的单机压测模型，开始并发数逐渐增加，吞吐量线性增大，后来增长减缓，但到大概第 10 分钟的时候出现拐点，延迟突然增大，吞吐量也过了峰值走低。

这里抓住一个点深挖的目的，并不是考察候选人能否记得性能优化的每一处细节，而是要确认候选人是否真正参与了这个过程，是否对这个优化过程的几个核心问题有清晰准确的认识。

换言之，如果候选人重新做一个类似的性能优化项目，要看看他是否确实因为这个项目而具备了相当的功底。从中我们也可以看出候选人对于某项技术，到底把握到何种程度，对于做过的项目和系统，是否具备一定深度的理解。

需要说明的是，一个技术点的深挖要以拿到预期的考察数据为目标，可以问 1 分钟，可以问 10 分钟，这都是没有限制的。一旦拿到了预期考察的数据，不必过多纠缠，继续下一个环节。

当然，这个话题点一定要是候选人（至少是自称）熟悉的，并且，深挖和关注细节不是纠缠于细节，我们不要把追问变成钻牛角尖，也不要把追问变成“考记忆力”。

全新的问题

前面讲了我们怎样去考察候选人对于他做过的、熟悉的系统，到底有多少理解，下面我们再来讲讲，如果是一个新问题呢，候选人能否顺利地设计一个全新的系统来解决它？这两个方面其实是互相独立的。

那我们就用一个模拟案例来介绍，如果我们像第 4 讲说的，像做一个迷你项目一样，给出一个实际问题，层层递进，逐步细化、分解和延伸成一个系统设计的问题（如果你忘记了，请一定回看第 4 讲），我们又该注意哪些方面。那个具体问题就是：

“请你设计一个网约车系统。”

并且我们也谈到了，经过细化以后，下面的系统设计考察，就是要求设计一个系统，来完成定位、叫车、搜索、接单等网约车系统的核心功能，如：

乘客可以随时随地叫车；

系统寻找邻近的司机并转发请求，如果无法接单，继续扩大寻找范围；

司机可以抢单，即接受或者拒绝叫车请求；

双方可以刷新自己在地图上的位置，也可以查看彼此当前的位置。

对于非功能需求，特别是系统容量的估算，我们后续将在专题中谈到；而对于功能需求的系统实现方面，我们继续来看后面候选人和面试官之间的对话片段。

第一阶段：客户端 - Service - 存储的基本层次建立

面试官：根据我们的讨论所确定的需求，这个系统中会有哪些主要模块？（要求澄清）

候选人：我觉得这个系统中，乘客可以叫车，司机可以接单，因此我打算创建一个 Ride Service 来接受乘客的请求，ride 的信息存放在数据库中。整个交互过程如下图：

乘客请求乘坐，提交一个 ride（相当于一个请求乘坐的订单）；

Ride Service 将乘坐请求发给多个司机；

司机抢单；

Ride Service 再将接单的信息告知乘客。

第二阶段：Service 解耦

面试官：嗯，那么其中的第 2 步和第 4 步，消息怎样从服务端传递给客户端呢？（要求澄清）

候选人：我觉得可以使用长连接，来保证消息能够第一时间送达，如果这一步失败，iOS 或者安卓平台还有统一的消息推送机制。

面试官：好，那么 Ride Service 怎么来寻找合适的司机来转发乘客的乘坐请求呢？（给出挑战）

候选人：我觉得 Ride Service 知道所有乘客和司机的位置，那就可以寻找最近的一些匹配，位置可以通过司机和乘客各自手机上的 app 来汇报，比如每十秒钟就汇报一次 GPS 位置。

面试官：可是我没有看到你画的图中有这个啊？（要求澄清）

候选人：哦，他们都汇报给 Ride Service。

面试官：所以，位置信息归 Ride Service 管，乘车请求的匹配归 Ride Service 管，匹配上了以后，结果的通知也归 Ride Service 管，它一个 service 要管那么多事情吗？（给出提示）

候选人：嗯……我觉得可以解耦，根据单一职责的原则，让一个 service 只做一件主要的事情：

Ride Service 只管 ride 的匹配和决策；

Notification Service 负责通知消息；

Location Service 负责维护司机和乘客的位置。

第三阶段：进一步解耦，补足缺失

面试官：嗯，确实看起来好多了。但是我还有个问题，司机和乘客汇报 GPS 位置的时候，从图上看，只有在乘客请求和司机接受 ride 的时候才会汇报位置信息吗？。（要求澄清）

候选人：哦，系统是需要实时获取位置信息，才好做匹配，我觉得 GPS 的信息也应该从 ride 的逻辑解耦开，应该有单独的位置汇报请求发给 Location Service。

第四阶段：细化存储层设计

面试官：嗯，不错。我注意到 ride 数据和位置数据也随着 Ride Service 和 Location Service 的解耦而分离开了，这很好。那么，对于这两类数据的存储，你打算分别选用怎样的技术来实现呢？

候选人：ride 数据需要接受关系查询，位置信息需要根据司机、乘客的 ID 来查询，还需要能够快速找到邻近位置的司机和乘客……（对于这两类数据的存储，可以作为下一个话题来详细展开）

不知道你发现没有，这个小片段，就模拟了面试官使用“要求澄清”和“给出挑战”两大法宝，怎样领着候选人一步步攻克系统设计问题的过程，这个过程和上一讲的算法和数据结构面试，是类似的。

其中，对于位置数据的存储，如果感兴趣的话《全栈工程师修炼指南》的第 26 讲中，我做了详细的介绍，你可以做延伸阅读。

总结与思考

好，今天的内容主要就是这些。

我先给你举了一些系统设计面试的踩坑案例，然后又给你分享了两类主要的面试方式，深挖候选人做过的系统，或者和他一起讨论一个全新迷你项目的实现，它们都能考察候选人对于系统的理解，但是又各有侧重。

你可以结合我为你还原的面试现场对话，仔细体会系统面试的操作方法。

这里我需要额外强调的是，系统设计就和算法一样，我们还是更应该关注基础，选择合适的问题，可以问，但不要一味追求高大上的“海量存储”、“大数据”这样的问题，这和算法和数据结构的面试不要过度追求“偏题”、“怪题”是一样的。

毕竟，能将生活中那些实际的问题，选择合适的工程技术来解决，才是软件工程师最根本的使命。

在最后，我想请你聊一聊你在阅读后的想法，特别是你是否有系统面试的经历，你觉得有哪些特别重要的方面，能否在留言区谈一谈呢？我会积极回复你的想法和问题。

好，我是四火，我们下一讲见！

08 | 其它技能考察：见微知著，不可忽略的其它考察点

你好，我是四火。

关于怎样主导技术面试的问题，在前面几讲里，我们分别对算法和数据结构，以及系统设计这两个最常见的考察路径，做了重点讲解。

而在技术考察方面，还有一些常见的其它路径，比如面向对象的考察，还有针对测试能力的考察等等。

据我观察，近几年来大家对于软件工程师的全面性要求越来越高，早就不再是会写代码逻辑、会设计系统就可以轻松当面霸了，在这一讲中，我就介绍一些比较常见的其它面试路径。

其它工程技能考察

面向对象考察

严格说起来，多数情况下，这一点应该叫做代码设计能力考察，只不过面向对象是最常见的其中一个方面而已。从技术角度上说，它包含了两个方面：

1.考察候选人代码层面的面向对象设计能力；

2.考察候选人代码层面的综合代码组织的能力。

先来说说上面的第 1 点。面向对象考察，尤其是对于入职没多久的程序员候选人来说，这是一个非常常见的形式。我们有时讲的代码层面的建模，其实就是通过面向对象的办法，把实际问题使用代码的类、方法等抽象来描述的过程。

既然重点是面向对象，这就意味着往往问题并不夹带复杂的算法逻辑，而面试官的重点也将放在代码设计的层面，能否将实际问题场景的核心抽象成一个又一个的类、方法和属性，安排它们之间的关系，并且应用合适的设计模式，作出合理的解耦，最终落地到代码上。

这种考察方式其实很考验候选人代码层面的设计能力，又和同为代码层面的算法能力有明显区别。我们也确实见到有一些候选人，他们虽然能够攻克复杂的算法，但是在代码设计和组织上却不尽人意。

再来说说上面的第 2 点，综合代码组织的能力。如果我们再站高一点看，其实好的代码都不一定非得是面向对象的，即便是过程式的代码，一样可以做好模块化、解耦，因此本质上我们考察的重点是候选人综合的代码组织能力。

另外，这样的面试也需要对编程语言的许多语言特性有准确的认知。比方说，如果面试题目明确指出了要求面向对象的方式来完成实现，那么除了代码设计层面，我们也能看出候选人对于封装、继承、多态等等一些现代编程语言基本特性的理解如何。

无论这一轮面试关注于上面说的哪一点，都要像我们前几讲介绍的那样，专注于具体问题的解决，即和候选人一起使用这些技能和工具解决实际问题，而不是单纯地做设计原则和设计模式理论和概念的问答。

事实上，面向对象考察中，我观察到最常见的误区，恰恰就是纠结于设计模式。说到底，代码层面的设计，最终目的是为了代码具备更好的可读性、可重用性和可扩展性。

因此，分层清晰，做到了良好的模块化、做到了合适的解耦，又留下了一定的扩展能力的代码，往往就已经是好代码了，不一定非得扯上某个著名的设计模式；反过来也一样，即便能够准确地说出某个设计模式的定义，它也不能作为对于代码设计能力的有力证明。

API 设计考察

现在对于很多大厂来说，业务都分得很细致，那么每一个团队往往都要维护若干个 service，并且将业务能力通过 API 的形式暴露出来。在这种情况下，API 的调用方就是团队的用户。

因为 API 的设计能力显得举足轻重，所以针对它的考察能够从相当程度上，看出候选人是否在代码接口和客户端与 service 的交互方面有一个平衡的理解。前者是对代码的理解，而后者是对系统的理解。

比方说，还记得第 7 讲中谈到的网约车系统吗？对于其中的 Ride Service，我们就可以引导候选人完成类似如下的 API 接口设计表格：

假如说我们把这个提供 API 的模块当作一个黑盒，当它所有的 API 都已经清楚了，我们对于这个黑盒的功能，以及这个黑盒的用户怎样和它进行交互，这两件事情也就非常明确了。

上面这个 API 的设计，是从 HTTP 协议，或者说是从 REST 服务的角度来描述的，对于不符合这种情况的，或者候选人不熟悉网络协议，我们也可以简单从编程语言代码中方法签名的角度描述，说清楚方法的作用，入参、返回值和数据结构，以及常见的异常种类，其本质是一样的：

Response createRide(Request req);

测试能力考察

测试能力的考察，在某些北美的互联网大厂中更为常见。比方说，Google 的工程师面试 loop 中，经常会单独放一轮由测试工程师主导的测试能力考察面试。

你可能会好奇，为什么这些大厂格外重视这点呢？

这里面的初衷是这样的，测试能力是对于一个具备全栈能力的工程师，所必须包含的一项重要素质，而这些企业的大多数负责开发的工程师岗位，都不会再匹配大量的测试工程师来完成项目，因此需要开发独立完成测试。

说白了，就是自己写的代码要自己测试，自己上线，自己 oncall 和修复问题，完成闭环。

对于测试能力的考察，有两种常见形式。

第一种形式是针对已经完成的代码，做白盒测试。面试官会期望候选人，能够拿着简单的测试用例来走一遍代码。之后也可能会提问，怎样设计测试用例才能将刚写的代码覆盖到，甚至要求写一小段单元测试代码，这是属于白盒测试。

白盒测试一般时间需求比较少，适合结合在每一轮包含编码的面试中，在编码完成后进行拓展。这种形式除了对于测试本身的考察，对于候选人在代码层面的理解也有着很明确的要求。

而第二种形式，则是黑盒测试。对于某一个产品，或者某一个功能特性，从黑盒的角度讨论，怎样才能做好它的测试。黑盒测试主要出现在单独的测试能力考察轮次，这种形式除了对于测试本身的考察，也要求候选人在系统和产品的层面有一定的理解。

举例来说，一个经典的黑盒测试能力考察的面试题是：

如果你负责 Google Map 地图的设计，系统给出了从 A 点到 B 的通行路径，你计划做怎样的测试，来保证从 A 到 B 的路径这一结果是合理的？

两种形式，黑盒白盒虽然差异很大，但是很多独立完成测试的工程师所需要的重要素质，比如问题场景的分析能力和用例设计的能力，其实都覆盖到了。

项目与任务管理

我们再来说说项目管理与任务管理方面的考察。在很多大厂的面试中，有一轮经常是由 PM 来负责的，这个 PM 有时候是 Project Manager，更多时候则是 Program Manager，他们会比较关注项目、任务和软件工程的流程方面。

最常见的考察方法是问经历，即直接了当地询问候选人，当前团队中，项目是怎样管理的，产品是怎样上线的，任务是怎样管理的，优先级又是怎样排的。其中很大一部分都可以用询问行为型问题的方法来操作，而这部分我们将在后面重点介绍。

好，上面介绍了一些常见的工程技能的考察类型，但是还有一些其它类型我并没有逐一展开来细数，比如针对产品思维的考察，一些在招聘团队中的产品经理很喜欢这种形式，抛出一个问题，和候选人一起挖掘用户的痛点，从产品角度讨论设计等等。

行为型问题

最后我想介绍一下行为型问题（Behavior Question），这是一种非常流行的非具体技术考察方式。这种方式不光很多重视价值观、领导力的大厂愿意采用，其中很多招聘团队中的 Hiring Manager 更是特别热衷于它。

概念与逻辑

首先，我们必须要弄清楚一个概念，什么是行为型问题？

行为型问题基本上是一类用来观察候选人过去在特定的工作情境下，是怎样解决困难并取得成功的问题。

这里要求候选人所描述的情境，包含的内容非常广泛，可以是与内部同事之间的，可以是与外部客户之间的，可以是关乎项目和任务的，可以是业务决策方面的，也可以是具体技术实现上的。

无论哪一种，这里面的逻辑是，候选人在过去遇到困难的时候，遵循的逻辑和采取的行为，这相当程度上反映了未来候选人将怎样应对类似的困难。

如果你还觉得不太清楚的话，可以看看下面这个行为型问题的例子：

你能否告诉我一个实例，让我了解你在工作中是怎样说服同事，采纳你的技术决策的？

从这个问题的回答，我们能够看出很多内容，譬如说，对于不同的技术决策，候选人是根据怎样的标准来评估优劣的，候选人是怎样和同事沟通的，等等。通过这样的问答方式，面试官可以看出候选人的许多品质，比如这个例子中，候选人对问题的分析思考能力，和同事的交流沟通能力，以及是否具备 backbone（不轻易动摇）等等。

再比如下面这样的例子：

你在工作中是否遇到过不同意你主管（经理）看法的时候？你又是怎样处理的？

对于预先订立的项目目标，你有没有遇到过未能按时实现的情况？

对于在你做过的项目中的软件设计，有没有事后你觉得自己做错了的？

原则与窍门

好，看完例子，我来总结一下，如果要向候选人提出行为型问题，有这样几个原则和窍门：

第一，问题都是基于“过去”的，或者说，我们希望知道的，都是活生生的，已经在候选人身上发生了什么事情，他抱了怎样的看法，又是怎样应对的。与之相对的是，“假如”型问题，比如：

假如你觉得同事的 code change 给系统造成了一个很严重的隐患，但是他又拒绝修改，你该怎么办？

这样的问题当然有它的价值，但它就不属于行为型问题，也不符合前面所说的“过去反映未来”的逻辑来得到考察数据，以帮助我们对候选人做出评估。

为什么这么说？因为所有人是可以“假想”的，但是假想并不能像过去的“事实”一样反映他真的会那样做。

第二，情境要包含冲突，如果可能，最好是一个棘手的冲突。不是所有的行为型问题都要求包含“冲突”的，比方说：

介绍一个你自己认为最为成功的项目，并说明为什么你觉得它是成功的？

这个问题本身就不包含明显的冲突，没有冲突就不利于我们知道，在“困难”的情境下，候选人是怎样应对的。当然，这样温和的问题可以进一步发散开去，引出更多尖锐的、包含冲突的问题，那当然是另一回事。

反过来，看看前面我前文中举的一些例子，比如“和主管看法不同”的例子，就隐含了一个和主管观点不一致的冲突。在面试双方能够顺利沟通的前提下，挖掘一些对于尖锐冲突场景应对的事例，可以很好地帮助我们了解候选人。

第三，追问并达到一定深度。这一点和前面几讲中提到的第 7 讲中怎样询问项目一样，我们当然不是希望事无巨细，但有深度的挖掘能在一定程度上帮助确认这些都是发生过的事实，而非随口应付而编造的答案。

第四，尽量避免太过常见的问题。这和技术问题的设计类似，面试都是可以提前准备的，一些太过常见的问题，可能会变成“背答案”，自然也无法得到真实的考察数据。

第五，事先明确并聚焦考察的数据点，控制问题展开的进度。一般采用行为型问题来进行面试的时候，我们可以逐步展开一个问题，并不断发问，但是需要注意的是，小心不要被候选人“拐跑了”，结果就感觉聊了很多，却没有什么有用的事实数据。

由于这种面试形式，并不像前面我们讨论一个“迷你项目”那样很容易看出其中的主线，因此我们需要很明确到底要着重考察什么，而不是和候选人“随便聊聊过去”。在得到自己想要的信息以后，可以先给讨论的问题收个尾，再开始下一个问题。

最后，我们来回想一下，对于一个行为型问题，我们希望从候选人那里得到哪些内容？我觉得可以用“情境”、“思考”、“应对”和“结果”这样四个词来概括。

也就是说，对于当时那种情况，候选人是怎样分析和思考的，于是采取了哪些做法，以及最后的结果如何。当然，在候选人的表达之后，根据内容我们可以从中提炼我们关心的考察数据，那完全是面试官的事了。

总之，对候选人的性格态度、沟通方法、处事风格等等与团队文化密切相关的要素，我们可以通过行为型问题做比较有针对性的考察，可以说这是对技术层面考察的一个非常必要的补充。这样的形式并不需要花很多时间，非常精心地准备技术问题，而且讨论非常自由，对于没有工程师技术背景的面试官，更是可以比较顺利地采用，因此这种形式还是比较流行的。

总结与思考

在前面几讲介绍了针对软件工程师候选人的算法和数据结构考察，系统设计考察之后，在这一讲我讲解了一些其它工程技能的考察路径，并对于非常常见的一种非技术范畴的考察方式——怎样问行为型问题做了解读。

我要特别给你强调的是，行为型问题很有价值，但是我们还是要保证整个面试过程中，大部分的时间，还是要放在软件工程相关的技术考察方面，这一点我在第 2 讲的计划制定部分已经说过了。

今天的主要内容就是这些。我想在最后留下一个问题，你能否在留言区和我一起讨论——在你的经历中，都有哪些我们没有介绍到的面试考察形式呢？

好，我是四火，我们下一讲见！

答疑课堂02：面试实践篇热点问题解答

你好，我是四火。

又到答疑课了，这一讲主要是围绕第二大板块的“面试进行 / 实践篇”的主要内容叙述的。这一讲中，我将回答一些专栏正文内容之外的热点问题，因为从面试角度看这些问题也相当重要。

问题 1：面试官对候选人谈及的业务或技术不甚了解时，如何把控局面？

好，我们先谈一个频繁出现的问题。在面试官和候选人的沟通过程中，一旦把话题谈论深入一点，特别是在候选人介绍项目、介绍系统的时候，就很容易出现候选人大聊特聊，面试官却听不懂的情况，那么，我们该怎样把控这样的局面呢？

首先，摆正交流的心态，正视彼此认知的交集与盲区。每个人背景不甚相同，你有你的领域，我有我的专长，既不需要惭愧，也不需要惊慌，这非常常见。

其实反过来也一样，某一方面内容，也许你觉得它是“常识”，甚至觉得理解它是“理所当然”，那么假如对方不知道，你也请继续保持谦逊平和的心态，保持“职业修养”。也许这的确是一个很简单的道理，但要知道自卑与自负同样来自人性，因此有时候这一点并不容易做到，需要时不时提醒自己。

其次，判断为什么觉得自己“不了解”或者“听不懂”，是因为自己对通用的业务或技术领域缺乏认知，还是候选人的思路与表达有问题？

比方说，假如候选人介绍他做的项目，那么通常他需要说明，这个项目的背景是什么，系统的用户是什么，他在其中做了哪些事，最后有着怎样的结果等等。这些内容，对任何一个“外人”说，都是不了解的，面试官也不例外。

这就不是一般意义上的“缺乏认知”了，面试官可以通过几个问题介入，通过有来有回的“沟通”，而不是单纯地听候选人的叙述，理解他介绍的内容。

再次，谈及具体的业务或技术的时候，把“请候选人介绍”，变为“向候选人请教”，即便自己对它相当了解。近似的问题，问法不同，可能效果会大不相同。

举个例子，候选人说，他优化了某个缓存的开源库中，锁竞争的逻辑，使得它在高并发的场景下，实现了更好的性能。那么面试官无论对这个库是否了解，都可以这样问：

我听说过这个库，能否趁此机会向你请教一下，它原来性能上的缺陷在哪里，而你又做了怎样的修改提升了它的性能？

为什么这样的方式有时会有更好的效果呢？因为一方面是“示弱”，面试官主动暴露给候选人自己的“无知”一面，而非高高在上，候选人会下意识提升信心；另一方面也能向候选人明确，面试官的知识背景，候选人会根据这一情况，调整他的陈述方式，以尽可能直白、充分和清楚。

事实上，一个好的面试官，不应该说太多，反而更应该成为一个倾听者。在候选人介绍业务或技术的时候，无论有多了解，都是一个很好的倾听的机会。这样的方式能有效帮助候选人抛开顾虑，更“敢说”，尽其所能把这些问题表述清楚。

如果面试官对这个业务或技术本来不了解，藉由候选人清晰的表述，依然可以获得更好的沟通，进一步了解候选人的真实一面；而如果面试官实际对它是有一定了解的，那么可以更好地判断出候选人是不是真正理解它。

据我观察，一些面试官无法放下身段，听不懂就“嗯”、“啊”过去了，候选人也就认为听的人知识渊博，相应地简化陈述，想避免啰嗦，这反而不利于面试官获得真实的考察数据。

问题 2：面试过程中，发现候选人作弊，该如何应对？

作弊或撒谎的情况其实并不少见，我在面试中就遇到过多次。有一次，在我们谈论一个算法的时候，候选人忙着敲键盘在互联网上搜索，无论是敲键盘的声音，还是视频里眼镜的反光，都暴露了他的“行踪”。

印象最深的是某次校招，有一个笔试环节，候选人线上答题，最后笔试得分排名靠前的十位里面，居然有好几个都是从某处拷贝了题解，整个粘贴到答题页面，然后再修改一下变量名、方法名、注释和格式。候选人可能以为代码提交前面试官一无所知，殊不知整个过程都被答题工具记录下来了。

如果在面试中遇到类似的情况，我们该怎样应对呢？我听过许多不同的看法，我的建议是，不要戳穿，不要质疑，一如既往地继续流程，但在这个过程中注意收集事实数据。

在面试后的决策会环节，可以首先提出这一点并与其他面试官交换意见，看看是否有类似的观察。作弊是品德问题，在一些企业中，遇到这样的候选人，是要列入黑名单中的，后续他的再次应聘，直接会被系统拒绝掉。

例如在我工作的公司 OCI（甲骨文的子公司）中，除了 Hire / Weak Hire / Weak No Hire / No Hire 这几个选项以外，还有一个很少使用的 Never Hire，就是为这种情况准备的。这类严重的品德问题在决策会一开始就可以在 Bartender 的引导下进行确认，一旦事实清楚，后面的流程就可以跳过了（这也几乎是实际操作中，唯一可以快速结束决策会的情形）。

问题 3：如何在面试中“推销”自己的公司和团队？

我在 [开篇词] 中说过，面试这个过程是双向的，很多人忽略了这一点。所以市场有些时候是买方的，有些时候是卖方的，这一点随时都在改变。因此我们在考虑考察角度的时候，也别忘了审视自己具备什么。

从公司的角度来说，不同的公司有不同特质，大公司在待遇上丰厚一些，小公司则能提供有挑战性和独立性的工作机会，而创业公司，则能够给以未来的期许。从团队的角度来说，也有类似的分析，即你的团队，能给候选人提供什么？

如果对方是优秀的软件工程师，通常不缺有竞争力的机会，那么如何在竞争中赢得青睐，这是面试中面试官需要向对方“推销”的内容。

对，你没有听错，在面试的时候，面试官绝不是一个高高在上的考官，而是一个平起平坐的工作伙伴，面试的过程就是一个互相体验工作氛围的过程，并且遇到了优秀的候选人，一定要找机会向对方介绍目标团队，这样的机会比宣传册上的文字更接地气。

举例来说，某团队有做分布式基础设施的机会，这更合候选人的胃口，而且团队规模和产品规模都还不大，属于较早期，工程师的工作更容易产生影响力，这就是很好的可用于“兜售”的内容。这件事情，不只经理面试官可以做，工程师面试官也可以做，而他们的角度是不同的。

你不妨回想一下，我们的专栏很详细地讲了怎样设计问题，怎样主导面试。别忘了这也正是一个展示自己团队的好途径。对于候选人来说，能有一个不住回味的面试体验，能够在面试中和面试官讨论得充实、开心，这不就是一个理想工作机会的金字招牌吗？

但是，反过来，我们也要坦诚告知公司和团队的局限。在沟通过程中，我们可以询问对方的近期目标、远期目标，对于公司和团队的要求等等，得到对方的期望，如果和团队能够提供的差得比较远，那么双方就没法具备合作的机会。

这一点，不能光靠直白地询问，还要靠多次的旁敲侧击，因为有时候选人口中的期望，和他心中的期望其实不一致。一般来说，我们希望这方面在电话面试的时候就已经大致确认清楚了，但是如果遗漏了，到了现场面试的时候就要补上。

举个例子，候选人说，他很希望做大数据的项目，而自己的团队却明确没有这样的机会，那么就可以进一步打探，对方对这个要求有多看重。如果这个愿望很强烈，那么我们的团队即使发了 offer，也很可能是一个陪跑的角色，候选人加入了也呆不久，这种情况下，可以考虑公司其他团队能否为候选人提供机会了。

再有一个典型的例子，是关于 oncall 的，有的团队 ops 压力比较大，这一点不需要隐瞒，可以指明，给出诚实的预期，如果对方非常介意，那自然也没有办法继续下一步了。

问题 4：怎样主导自由提问的环节？

在面试结束前，我们尽量要留出两三分钟的时间，给候选人一个问问题的机会。不是说每轮面试非得保留这个机会，但是，这是一个进一步沟通和展示的好机会。有些时候，候选人有问题，但是没有机会问；有些时候，候选人能和经理能够进行充分的沟通，但是却没有机会和工程师聊一聊。

回答要得体，因为你代表的不是你个人，而是公司和团队。我觉得比较可信和诚恳的回答，都是面试官从自己的角度出发，举例而谈的。一般这种情况下，不要使用夸张的表述，也不要去贬损其它公司和团队。

有些时候，有些问题属于自己并不熟知的领域，那也可以增加一个“声明”，向对方表示一下自己并不熟悉，以免一面之词误导对方；而还有些时候，那些问题不适合回答，那就直接指出，不要越界。比如，可以说相对于自己，某位其他人更适合回答这个问题，像是候选人询问薪资，一些公司是要求面试官闭口不谈的。

在具体回答问题的操作上，我在这里给你提供这样几个小技巧：

首先，如果问题含义不清楚，先确认问题。一定要领会候选人具体想问什么，有时候，候选人会绕弯子，隐晦地表达；有时候，则是表意不清，或有歧义。无论是哪种，只要不清楚，就先确认清楚问题。

其次，先评价问题，再回答。在问题清楚的情况下，可以对于对方的问题适当地表示认可。比如说，可以泛泛地说“这是一个很好的问题”，之后再回答。

再次，在回答后，可以再次确认。比如可以说，“不知道我的这个回答是否解答了你的疑惑？”。

问题 5：怎样在观摩的面试实践中指导其他面试官？

观摩（shadow）是一种很常见的快速学习和上手的形式，开会可以观摩，oncall 也可以观摩，面试实践也一样。

具体怎么操作呢？就是新手面试官寻找一位有经验的面试官，像影子一样观摩其组织和参与面试流程的整个过程，从中学习并加以思考。因此，如果有别的面试官希望 shadow 你的面试，或者说观摩你的面试过程，学习你的经验方法，那么祝贺你，这是对你能力的一种认可。

具体操作上面，我相信你会有自己的“套路”，我在这里给你分享一下我的做法。简单来说，就是把自己的面试流程完整地呈献给对方，并提供面试前、面试后和决策会后的三次沟通机会答疑解惑。

首先我会跟该新手面试官做一个简短的沟通，叙述一下大致的流程，从面试计划、面试进行到决策会，都有大致的哪些内容。如果他有问题，也顺便做一个解答。面试计划等过程中的邮件传递、材料发送等，也要抄送给他。

在面试过程中，主面试官需要向候选人介绍这位 shadow 的面试官，但他在面试过程中，通常是较少参与沟通的，而是在一旁安静地观察和思考，并做记录。这主要是因为，一旦参与了沟通，就容易影响到主面试官的计划安排。在面试之后，可以和这位新手面试官一起快速碰个面，趁着面试的过程在脑海中还新鲜，交流一下彼此的想法。

在决策会的环节，shadow 的面试官通常是不参与投票的，但是可以表述他的观察，但是大家需要清楚，他的表述和主面试官的表述，针对的都是同一轮次而得到的反馈，不能算做两个独立的数据点。在决策会之后，两位面试官还可以第三次碰头，在沟通中做个回顾，这三次交流的用时都很短，也许每次 10 分钟，但作用却很关键。

今天，我和你聊了聊我对面试实践环节的几个热点问题有什么看法，希望这些内容对你有所帮助。如果你有问题，也欢迎在留言区提出来。

好，我是四火，我们下一讲见。

09 | 决策会准备：怎样全面收集事实，有效提炼数据？

你好，我是四火。

讲完了面试前的准备，讲完了面试时的把控，现在我们要讲到面试后的决策了。在决策会前，我们通常要求面试官准备好一份简短的面试反馈（feedback），这份反馈包含了面试官自己观察，以及对于候选人“推荐程度”的结论。

你我都知道，包括面试在内，凡是“考试”，最基本的原则就是要客观公正，可是事实上，每个人都难免戴着有色眼镜看世界，这跟我们总是期望着的客观公正背道而驰。

那么在这一讲，我来着重谈一谈，我们该怎样去收集事实、提炼数据，尽可能地少受情绪与主观臆断的影响，尽量保持客观公正，把这些采集到的信息真实地提供给决策会。因此，这里的关键就是，专注于具体的事实和考察数据，减少对模糊主观感受的依赖。

常见的误区

老规矩，我们先从反面来看看在数据采集和整理方面，都有哪些常见的误区。

脱离面试计划

还记得第 2 讲介绍的面试计划吗？没错，脱离面试计划，就是最常见的一个问题，有时候这个“脱离”，是面试官忽略了计划安排，而有时候甚至就是因为压根儿“没有”面试计划，在这种情况下，谈何“全面、客观”地评估呢？

面试计划的一大要点就是确定了每个面试官的考察重点，谁负责考察编码能力，谁负责考察对系统的理解，都分别确定了下来，因此对于一个面试，哪怕大家遵循了一个非常简单的面试计划，都要远远好于没有计划，或者是订立了计划却抛之脑后。

我们当然鼓励面试官自由发挥，但是自由发挥的底线是保证和安排的面试重点保持一致。这就像是做软件，如果没有遵循设计，甚至根本没有设计，哪怕代码写得再精致，很可能也是事与愿违，甚至南辕北辙。

缺乏事实依托

“专注于事实和数据”有时是一件并不容易做到的事情。我们都知道要摆事实、讲道理，通过实际的事实和数据来佐证我们的观点。但是在实际操作的时候，特别对于一些面试经验较浅的面试官而言，很容易被情绪或者是第一印象带着跑。

我来举一个真实的例子，有一位面试官在他的面试反馈里说，候选人“coding 能力不足”，但是读完整个面试反馈也没有找到非常扎实的事实描述，来佐证他的判断。于是在 debrief 的时候，我就仔细追问了他给出这个观点的原因。

后来才知道，候选人的 coding 之所以表现不佳，是因为他走了一条错误的路线，但其实问题的根源是候选人没有能够沟通清楚和理解问题，而并非 coding 本身。再结合其他两位覆盖 coding 的面试官的反馈，我们得到的大致结论是，候选人的 coding 本身是没有问题的，基础知识也比较扎实，但是沟通等方面存在不小的问题。

事实数据浮于表面

这一点，指的是有时候我们觉得已经得到了考察数据，但是这样的数据不够深入，缺乏足够的说服力。比如说，知道概念，不知道原理；说得出选择什么技术来实现，却说不出为什么。有时候面试官缺乏过硬的技术基础，或者缺少一点往“具体”，甚至“细节”挖掘下去的动力，就很容易陷到这个坑里。

比方说，有位候选人对于一个分布式系统的大致理解谈论得还可以，在问到怎样做系统平滑扩容的时候，他也明确提到可以使用基于“一致性哈希”的技术，那好，“什么是一致性哈希呢？”，结果候选人听到这个问题就卡壳了。

其实对于面试官来说，多一个这样的追问并不难，而对于候选人来说，一致性哈希也可以说是分布式系统的一个基础知识，但这个快速追问就是一个向下探查的过程，很有意义。换言之，可能通过这样的提问来谈论自己的理解，加起来也就一分钟时间，这个过程很自然地发生了，但是却可以得到一个很有价值的考察数据。后来，我们发现，这位候选人对于系统的很多基础知识并不是真正理解。

类似地，在技术选型的讨论上也有这样的情况。例如说持久层的技术选择，有候选人说要使用 NoSQL，那我们就可以要求澄清，“使用哪一种 NoSQL 存储技术呢？”，候选人说是 HBase，紧接着进一步追问就可以抛出来“那为什么选择它呢？”。通过这样的方式，我们希望获得的数据，是候选人是否真正理解这些他自己说出来的概念和技术，还是只知道一个名词而已。

此外，需要小心的是，在技术方面，我们可以考察能力和基础，而不是考单纯的记忆力，更不是钻牛角尖。这在第 3 讲的“知识性的问题”部分我已经强调过了。

重复考察已明确的数据点

面试的时间是宝贵的，面试官都应当有“珍惜双方的时间”这样的意识，因此，我们对于已经非常明确的考察数据，不应该再去重复考察，而是应该把时间分配到其它的考察项上去。

我来举一个例子吧。候选人在算法部分，problem solving 的部分表现得非常好，思路清晰，问题解决推进迅速，复杂度分析准确，但是代码却写得有些混乱，比如命名不一致，组织欠缺条理，重复代码多等等。

这时候，在编码后问 follow-up 问题的部分，我觉得面试官就可以先放一放对于 problem solving 的进一步考察了，而是可以问一下候选人，对于代码的组织和书写，有没有可以优化的地方呢？

这样做的目的就是，对于我们有疑虑的部分，又觉得考察程度还不够，可以给出提示，看看候选人能否改进他的“作品”，而对于他已经很明确的强项部分，我们已经有了足够的数据，就可以先放一放了。

可采用的技巧

好，说完了常见的问题，下面我们就从正面来讲一讲，除了上面提到的注意要点，还有哪些数据采集和整理的技巧。这些技巧的目的都是一致的，围绕预先规划好的考察重点，尽量客观地去评估候选人。

面试情况速记

速记，这是一个很有价值的技能，并且这个技能因人而异，需要不断练习。我的习惯是，对于面试过程中的沟通，基本上重要的信息，都会用几个单独的词记录下来，这些信息，自己能看懂就好，目的只有一个，就是能够帮助自己回忆。同时，在记录笔记的过程中，最好能大部分情况下盲敲键盘，这样，眼睛可以用来和候选人进行沟通，提供直接的眼神交流是很重要的。

及时预定决策会

决策会将是所有参与该候选人面试的面试官碰头的一个机会。一般来说，“及时”是要点，只要各自的面试反馈能够及时在会前整理，这个会议定的时间越早越好，因为越早大家脑海中的印象也越新鲜。

如果这个会议发生在面试的一周后，判断的准确性就要大打折扣了。在有的公司里，这个会一开始由招聘专员（Recruiter）制定，有的则是由招聘经理制定，这都可以，但是，我们要尽量保证每个面试官都参加。特殊情况下个别人无法参加的，需要提供一份比较详细的面试反馈。

使用面试反馈模板

在我看来，面试反馈模板的使用，是效果最强大的技巧了。一般来说，每一组面试的 Bartender，可以在面试计划的时候，给出一个反馈模板，要求大家都按照模板上的格式来提供反馈意见。模板的要求很简单，就两点：

保证包含面试考察最关心的点；

模板要简单、直接（越简单、直接，可操作性就越强）。

下面这个模板的例子供你参考：

考察重点：

主要考察内容：

优势：

不足 / 担忧：

结论：

其它重要信息：

好，我来逐条讲一下。

首先是反馈模板的第一部分：考察重点和主要考察内容。它们各一句话，这些都要和第 2 讲的面试计划一致。如果你忘了，请回看。比如说，考察重点是：

实际问题的解决，代码设计和实现，面向对象设计

这就要求这一轮面试的反馈，要包含对上述考察项的评估意见。通过模板的方式再一次明确这一点，从而保证面试过程有着明确的目的，而不是漫无边际地谈论。

接着的主要考察内容，也是来自于面试计划，也就一句话，比方说：

要求设计一个电梯系统，设计其中的主要类和方法。

要不要详细说明具体是怎样定义的，划定了哪些具体需求点，又是怎样实现的？我的建议是：不要求。如同上面所说，模板要尽量保持简单、直接，要求越多就越难以实施。

但是不知道你注意到没有，各一句话，考察重点是目的，考察内容是途径——通过这两句话，就可以大致了解，这一轮面试，通过怎样的途径，主要要考察候选人的哪些方面。

其次，反馈模板第二部分，优势和不足。这两个部分，我想谈这样两个操作要点：

第一，优势和不足都要写到，如果面试官只看到了一面，也就是只看到了好的一面，或者是差的一面，这样的反馈是不合格的。因为这样的观察说明是不客观的，或者是不深入的。

第二，写出观点的时候必须要写事实论据吗？需要，但是我们不强求每一条观点都写论据。比如这样的例子：

编码能力不够扎实，花了很长时间才把一个 BFS 逻辑的基本结构写出来。

这就是一个合格的表述，但是据我观察，大多数人在反馈中，总会有部分观点是不写事实论据的，有时甚至连描述性的语句也没有。但只要在整个反馈中占比是属于少数的，这就没有关系，遇到这种情况，我们可以在决策会的时候再要求该面试官说明即可。

再次，是反馈模板的第三部分：结论。怎样写结论？这包括两个部分：

1. 推荐程度

2. 级别

“推荐程度”，指的是根据该轮表现，面试官认为候选人是否能通过面试，成为团队的一员。有的公司要求填写 Hire / Weak Hire / Weak No Hire / No Hire，有的公司要求填写强烈推荐 / 推荐 / 不推荐 / 强烈不推荐，还有的公司干脆要求打 1~5 分，但它们原理都是类似的。

“级别”，顾名思义，根据该轮面试官对于候选人的综合评估，如果结论是正面的，那么该结论是基于哪个级别得出的。如果不提及级别，那么就以面试计划中设定的默认级别为准。

有些时候，有的面试官会给出一个简单的“条件表述”，也是可以的。比如：

综合表现尚可，但对于 coding 有所疑虑，如果其它轮次 coding 没问题的话，我给出“Weak Hire”，否则“No Hire”。

最后，是“其他重要信息”，但这是一个选填内容。通常这部分都是留白的，但是有些特殊情况需要和整个面试团队交代，比方说，我经历过的一个例子，有位面试官发现候选人作弊，具体来说就是线上面试，一遍用语言应付，一遍在互联网上搜索问题的答案。这就是一个非常重要的信息，对这一类“道德品行”的问题该怎样看待，我们在后续会谈到。

此外，如果有候选人的绘图、代码片段等你认为有必要陈列的，可以一并附在反馈中。

催促面试官提交反馈

上面我讲了一个我推荐的面试反馈模板的例子。那么，这个反馈写好了发给谁呢？一般来说，不要发给面试团队全员，而是只发给 Bartender（技术负责人，我们在第 2 讲介绍过，如果忘记了请回看）和招聘经理就好了。

按理说，反馈写得越及时，面试过去的时间越短，效果就越好。如果面试已经过去一天了，或者是决策会快要开始了，而有的面试官还没有提交反馈，那么 Bartender 就需要催促面试官把反馈提交上来（当然，有时候这个角色是招聘经理负责的）。

好，接下来，我想讲一讲为什么把面试反馈写下来那么重要。

首先，面试反馈确保最基本的逻辑正确性，明确立场。作为一个面试官，我这一轮关注的重点是什么，我做了什么操作来考察候选人，候选人有哪些好与不好的表现，分别支持我的哪些判断，而最后又是一个怎样的结论。

这些内容，说起来都是很简单的逻辑，但是只有把它们写下来，有因有果，才算真正梳理清楚了。尤其对于“纠结症患者”，逻辑清楚非常重要，这样在激烈的决策会讨论中，对于自己的观察，有着明确的立场，不会轻易摇摆。从这个角度说，其实，面试反馈写下来这个过程，要比面试反馈本身的内容，重要得多。

其次，面试反馈帮助记忆，也留下重要的记录。如果你做过面试官，你也许会有这样的体会，完成了一轮面试，感觉有很多话要说，但是过了一天之后，忘记了一半，剩下的部分，再过一天，又忘记了剩下的一半。但是面试反馈可以帮助你把最重要的部分记录下来，在 debrief 的时候帮助回忆。

有些时候，面试的决策不容易做出，在极端情况下甚至需要有其它人参与进来，回看面试的情况（我们在后两讲会谈到，如果面试团队自己无法达成一致怎么办），那么这些面试反馈就是很有价值的文字记录了。

最后，这些反馈可以帮助 Bartender 和招聘经理在决策会前留意到一些重要信息。比如前文中提到的一些反映严重道德品行问题的事情，这样的信息在后面决策会的时候可以优先拿出来确认。

总结与思考

今天，我介绍了在面试中收集数据和记录事实信息的误区，以及可以采用的正确的技巧，并且介绍了在面试后如何根据它们总结成客观、有效的反馈。

希望这些内容对你有所帮助，但是我要强调的一点是，要保持独立思考的习惯，所有的这些对候选人的评价，要独立进行，在决策会开始以前，不要去和任何别的面试官讨论面试的事情，以免影响自己的判断。

在本文的最后，我想留一个问题供大家讨论。动员面试官写反馈的一个常见困难是，对方说“太忙，没时间”，对此，你怎么看？

好，我是四火，我们下一讲见！

10 | 决策会开展（上）：怎样引导争辩，达成共识？

你好，我是四火。

今天这一讲，我们来聊聊技术面试后的决策会。决策会，就是大家碰头商讨候选人情况，达成面试共识的过程。显然，这在一定程度上将决定，公司和团队是否愿意接纳候选人，也就是说，候选人是否能得到相应的工作机会，其重要性不言而喻。

“开会”这个事儿是技术团队的长期热门词汇，无论你是否喜欢，在很多情况下，它是一种群聚的同步交流方式，目前并没有更好的方式可以替代开会。

今天我们要讨论的情况便是如此，候选人经过了技术面试，怎样给出最终的评估结论？大多数的情况，还得靠开会。

其实这个给出结论的过程，一般有两种形式：

第一种，是一个特殊角色的人（这个人一般是级别较高的管理者），收集了面试后各位面试官的评价，然后独立决定；

第二种，是面试团队坐到一起，以会议的形式讨论并达成共识，共同决定。这个会议，有很多叫法，我们在这里把它简单称作“决策会”（Debrief）。

通常来说，对于普通的软件工程师面试，第二种，也就是决策会的形式，更为多见，我也更为推荐。因为相较于第一种，它也保证了更高的参与度，团队内部保持公开透明，更能真正做到让团队为团队自己选人，而这一讲的讨论也是针对这一种方式展开的。

典型的误区

决策会的误区其实还是非常多的，我们来讲最典型的几个，看看有没有你熟悉的。

把决策行为变成了民主选举

对面试结果的决策变成了民主选举，无论是简单粗暴的直接投票，还是共识无法达成索性强行投票，本质上都是一个“少数人服从多数人”的逻辑，这看似很公平，其实恰恰相反。关于这一点，我觉得可以从这样两个角度去理解：

1. 评估一个面试决策，更具意义的衡量标准是，它背后的逻辑是不是合理，而非人数是不是占优。我们平时说的“以理服人”，其实说的就是这件事情。

2. 在某些情况下，面试官其实对于自己的选择也并不坚定、或者思考并不成熟，需要引导、需要讨论，而民主投票在一定程度上，直接粗暴地“绕过”了这个过程。比如说，面试官有他的观察，也有他的数据，但是如同在第 9 讲中提到的那样，它不够深入，或是不能较为准确地剖析和认识它所代表的意义。

Bartender（技术负责人）应该在这样的面试决策会上，根据已明确的事实和数据，针对所有在会上的讨论内容综合分析以后，引导面试官做出合理的决策，达成基于团队的共识。

由于这个问题太过常见，我见过一些决策会中，虽说 Bartender 都明白这个道理，还是会不知不觉地犯下“民主选举”的错误，特别是在争辩较为激烈的情况下，为了收场，在很多分歧还没有得到解决，很多疑点还没有澄清的情况下，选择了投票选举这种简单粗暴的办法。

因此，我要再一次强调，面试结果的决策，不是民主选举。

过于倚重招聘经理的意见

招聘经理的话语权重过大，这个问题也非常常见。特别是某一些团队中，工程师资历比较浅，他们有时会无意识地倾向于经理的观点，因为在平时工作中，招聘经理就是他们的主管，有时候即便有不同的看法，自己也不一定在决策会上提出来，或者即便有足够的理由，也不能够坚持自己的看法，据理力争。

因此，Bartender 的协调作用就非常大了，他需要站出来，帮助团队识别出具体的事实数据，而不是单纯的具有倾向性的观点。在这一讲的后面，以及下一讲我还会介绍一些技巧，尽量减轻这个问题可能带来的影响。

缺乏事实依托

缺乏事实依托，其实在上一讲也谈到了这个误区。在收集和整理对候选人的反馈时，需要有事实依据，在决策会的讨论中，凡是抛出对于候选人评估的观点一旦需要求证，要能拿得出事实数据来。

举例来说，有的面试官讲，他注意到候选人并不能听取和接纳他人的意见，那么，要是有人要求他拿出事实数据，来解释为什么给出这样的观点，如果他没法说出来，或者只能说“不太记得了，就这个印象确实很深”，这样的观点逻辑就不成立。

但是，如果这位面试官确实拿出了一条数据呢？

比如说，候选人在一个算法问题的求解上陷入了挣扎，他原本的回溯法思路走不通，于是面试官提示候选人另外一种排列组合的思路，候选人听到了，但是却选择了忽略建议，继续在他原有的思路方法上挣扎。

有了这样的事实数据，我们是否就能认定候选人“不能听取和接纳他人意见”呢？我认为，单单凭此还是不能的，至于原因，我先卖个关子，我在后面会告诉你为什么。

不合理的决策因素影响

有一些事实不应该影响到决策，但正所谓“旁观者清，当局者迷”，在决策会上，其实经常会看到一些不合理的决策因素。

比方说，我经历过一场决策会，本来大家对结果达成一致了，认为候选人通过了面试，并且也确定了级别。

结果会后，招聘经理突然把大家召集到一起，说我们能不能把给候选人的级别增加一级，因为他已经从别的公司得到了一份 offer，原有级别的 offer 无法说服他来我们公司。

我认为，这个试图改变决策的初衷就是不合理的，因为候选人有没有其它 offer 既不属于候选人过去的经验、履历，也和候选人当时的面试表现无关，那么这样的因素就不应当影响面试结果的决策。

流程把控

好，介绍完典型的误区以后，我再从 Bartender 的视角介绍一下，作为面试官，我们对于决策会应该有一个怎样的预期，又应该怎样把控整个决策会的进程。

整体认识

一般绝大多数的决策会都可以在 30 分钟完成，并且是由 Bartender 主持的。少数情况，譬如候选人的情况比较复杂，或是争议较大，达成一致较为困难，我们就需要延长时间。

从参与的人员上看，所有现场面试的面试官都应该参加决策会，而之前电话面试的面试官，可以不参加。有时，负责招聘的同事（recruiter），也会参加，一般不发表看法，而是倾听，了解这位候选人的情况。

如果有个别面试官由于个人情况无法参会，只要提交了清晰的面试反馈，这也没关系，不影响会议进行，但是，如果 Bartender 或是招聘经理无法参会，那么这个会就必须要延期。这是因为，这两个角色在整个面试团队中比较重要，而且相互制衡（具体原因请参见第 2 讲），缺乏任何一方都无法保证决策会的全面、客观、公正。

从输入上看，我们要求所有面试官都将完成的面试反馈，交给招聘经理和 Bartender，这是会议高效的保证，当然，如果存在没有提交的情况，虽不理想，但也不应成为会议进行的阻碍，具体的反馈内容可以在会上详述。

从输出上看，最重要的就是得出面试结果，包括两点，首先是面试是否通过；其次，如果通过的话，面试团队为候选人裁定的角色级别是什么。

具体形式上，不同公司会有不同要求，很多公司都有内部的一个管理招聘流程的网站，有了结果后就需要更新上面的信息。

好，在整体上有了感观认识，下面我来介绍一下决策会的几个重点环节。这些环节可能在不同公司和团队中有所差异，我所介绍的实践方案，是在我看来比较推荐的一种。

第一环节：初始投票

会议开始以后，Bartender 会介绍一下候选人的姓名和目标职位、默认的目标职位级别。然后，大家开始投票，投票内容其实就是一个事儿：对候选人的推荐程度，例如 Hire / Weak Hire / Weak No Hire / No Hire（具体介绍你可以参见第 9 讲）。

具体操作上，把握一个原则，尽量让大家不要互相影响，而是完全凭借自己的判断给出结果。如果非疫情期间，大家都坐在会议室里，那么一种推荐的方法是，Bartender 数 1、2、3，然后大家一起伸出大拇指，Hire 就垂直朝上，Weak Hire 就 45 度角朝上，Weak No Hire 就 45 度角朝下，No Hire 就垂直朝下。

其中的原因我想也很容易理解，比方说，如果招聘经理先表态，而招聘经理往往也是团队的经理，其它面试官也很可能平时就是汇报给他的，那么某些面试官就更容易受到经理表态的影响。

需要说明的是，这一轮投票让大家先开门见山地亮出自己简要的结论，而并非据此直接裁定决策会的结果，并且我们在第二环节中会再展开陈述反馈，即“先摆明态度，再慢慢解释”。

经过实践的验证，这是一种比较好的方式，有助于每个面试官独立地表达和明确自己的观点，并且能让每一位与会者快速参与，进入思考与讨论的状态。

第二环节：反馈陈述

第一环节很简单，一般一两分钟就结束了，下面进入具体陈述反馈的第二环节，它的花费时间一般可以比较长，但也请尽量保留至少 10 分钟的时间给第三环节。

具体操作的方法是，在 Bartender 的提示下，所有面试官依次来介绍他那一轮的面试简况，面试的重点和内容大致是什么，候选人的优势和不足是什么，也就是说，给出第一环节的那个投票，你的逻辑是什么。叙述顺序还是一样的——普通面试官、招聘经理、Bartender。

在反馈陈述方面，Bartender 需要控场，主要抓住这样几个要点：

陈述时间控制。可以先提示一下，也可以在陈述的过程中判断，如果发现陈述过于细致具体，那么就要提醒一下，我们的目标是给其他人，以及第三环节保留一定的时间。

事实支撑的鉴别。对于主要的观点，如果发现只有观点陈述而没有事实依托，需要立即追问，确保对方谈到的事实和观点是匹配的。

主要内容的速记。这一步很重要，我在上一讲也已经谈到了，把诸位面试官的判断中，几个关键词记录下来，在第三环节需要纵览这些反馈，获得一个比较清晰的认识，如果不动笔而单纯靠记忆力，是比较困难的。

第三环节：争辩开展与共识达成

接着是第三环节，首先，Bartender 可以简单地帮大家回顾一下前两个环节的情况，比如说：

一共 3 票 Hire，两票 No Hire；两轮覆盖了 coding，两轮覆盖了系统设计，还有一轮综合考察。

不要小看这一步，除了可以帮助大家强化一下这个基本印象，还能够识别一些面试程序上明显的问题。

比如说，如果软件工程师候选人没有人进行代码面试，这就是一个覆盖面的硬伤。如果真的遇到这种情况，也别担心。对于这样硬伤的处理，我在下文中会谈到。

然后，寻找反馈的模式（pattern），和大家一起讨论。这里所说的“模式”，指的就是对候选人出现一次以上的相似评价，或者是体现出的相同问题。我来举个例子：

面试官 A 说：

候选人谈到他做 xxx 项目的时候，周末加班把它完成了，但是下周一的时候，他主管说他做的其中一个主要功能并不是需要的。

面试官 B 说：

我让候选人将一棵二叉树序列化成字符串，他和我很简单地沟通了一下，就开始介绍该怎样实现了，但我们并没有讨论清楚序列化的具体要求是什么。

虽然两位面试官说的明显是两件不同的事，但这里隐约暴露出了一个模式，也就是同一个问题：候选人在工作的时候，很让人担心他能不能做到充分的沟通：

做了一个不需要的功能，这不是技术问题，更像是缺乏充分的沟通；

没有讨论清楚需求就开始设计和实现，这也反映了缺乏充分的沟通。

作为 Bartender，就是要领着大家，从茫茫反馈的数据中，挖掘出这些模式来。模式所体现的优势，或是暴露的问题，要比单一的数据点要有说服力得多。

因为单一的数据点偶然性很大，兴许候选人可能就是单纯地没做好，但模式经过了超过一个支撑事实，或是不止一名面试官的验证，就可信得多。这有点像医生看病时，结合化验报告和症状等多项“证据”，给出诊断。

接着，汇总建议，收敛分歧，达成共识。经过 Bartender 引导的分析讨论，有些面试官提到的担忧，可能不是问题；有些提到的优势或不足，可能事实支撑并不构成较强的“模式”；而还有些优缺点，则会得到验证。

经过这样逻辑清晰的分析，很多情况下面试官会调整或者改变原先观点，大家逐步达成一个“共识”，这个共识就是前面提到的决策会需要产出的面试结果——综合来看，候选人有哪些优势和不足，他是不是通过了面试，大家对他认可的级别又是什么。而 Bartender，这时可以归纳总结一下，并给出自己的建议。

当然，这个从争辩到共识的过程并不好做，而且它非常考验 Bartender 对于对话组织和内容概括的功力，我们将在下一讲介绍这方面的许多技巧。

对于共识的达成，通常有三种结果：

1. 最终如果大家能够达成共识，那最好不过，这也是大多数的情况；

2. 如果招聘经理和 Bartender 和多数其它面试官达成了共识，但个别面试官依然不认可，但这个不认可的程度较弱，那么我们依然可以采纳这个不完全的“共识”作为结果，但保留个人意见，完成决策会的输出；

3. 但如果招聘经理和 Bartender 都无法达成一致，或是大家分歧比较大，这就可能需要依赖于外部资源了，不同公司和团队处理方法不同。比方说，某些公司中，这种无法达成一致的情况，就表示面试不通过，简单直接；还有一些公司，有一个独立的“招聘委员会”，它由一些经验丰富的面试官等人组成，他们会根据所有的面试反馈，以及 Bartender 提交的面试会记录等材料，做出进一步的裁决。

最后，无论是上面的哪一种情况，Bartender 需要简单陈述一下结果，确保整体决策的逻辑清晰合理。

总结与思考

今天我给你介绍了面试后决策会的大致流程，包括其中都有哪些典型误区，对它的把控又有哪些步骤。

就像我前面所说，Bartender 作为面试官中的一个特殊角色，决策会的流程把控其实非常考验他的对话组织和内容概括的功力，这需要在实践中反复练习以及经验的积累。

这个环节一旦做不好，由于观点碰撞和意见分歧，决策会就很可能变成乱糟糟的“吵架”大会。

今天的内容就是这些，我在最后留一个小问题吧：你作为面试官在面试后，是怎样做出通过或不通过的结论呢？能否在留言区和我分享一下呢？

好，我是四火，我们下一讲见！

11 | 决策会开展（下）：怎样确保评估全面且有深度？

你好，我是四火。

上一讲，我们介绍了决策会流程的整体把控，包括大体有怎样的过程，期望从这个会议得到怎样的结果。

但你可能也注意到了，在这短短的半个小时里，剖析事实、总结模式、管理争论、收敛分歧，并最终引导得出共识结论，这些步骤对 Bartender 的要求还是非常高的。

那么这一讲，我会进一步为你阐述，决策会中这些步骤的实用操作技巧。

你可以回想一下上一讲我们介绍的决策会流程，根据流程的划分，这些操作技巧可以分为两个方面，分别是剖析事实和总结模式，以及管理争论和收敛分歧。

剖析事实和总结模式的操作技巧

避免对事实的简单罗列

“事实数据的简单堆积”，这个问题并不少见，一些经验比较少的面试官常常容易走入这个误区。

我们经常说，对候选人面试的反馈，不能只讲观点，而没有事实数据的佐证；可是，反过来也一样，有时候全是事实数据，缺乏观点，这也是不行的。

比如说，某位面试官在决策会上，谈论了他问了候选人什么问题，候选人是怎样澄清问题的，他们是怎样分析问题的，接着又是怎样讨论解决思路的，等等，洋洋洒洒一大堆，很花时间不说，还很难让人抓住主要的观点。

这种情况下，Bartender 应当介入，要求把这个观点和事实陈述的顺序反过来：问面试官，“你觉得候选人最大的几个优势是什么，不足又是什么？”

这样一来，面试官自然而然就会思考并抛出“观点”。根据提到的优势或者不足，Bartender 可以再进一步要求面试官提供佐证的事实数据，而那些相对不重要的陈述呢，就被略过了。

你看，这种方式下，面试官就不会把或大或小的过程细节全部叙述出来了，而是谈论最重要的部分，因此，这个过程中 Bartender 的引导作用举足轻重。

合理采纳推荐人的意见

我记得在我刚工作那会儿，身边朋友们，也包括我自己，主要的求职方式，还是去各大招聘网站投简历；十多年过去了，这事儿已经发生了巨大的变化，现在我很多的朋友找工作都用 LinkedIn，等待猎头联系，或是点对点地找到目标公司内的朋友来推荐。

据负责招聘的同事说，总体来说推荐来的候选人，通常要靠谱得多。

如今很多互联网公司，对于“推荐”，甚至“强力推荐”的候选人，都有一些流程上的“福利”，比如，可以简化，甚至跳过电话面试，可以直接对接目标团队，而一旦候选人通过了面试并入职，目标公司内的推荐人还可以拿到一笔丰厚的推荐奖励等等。

从面试官的角度看，如果候选人是经过推荐而来参加面试的，那么在同一家公司的推荐人就很可能提供额外的考察数据。在具体操作上，我们应该怎样采纳推荐人意见呢？

首先，在决策会之前，流程上没有什么不同，我们不要安排整个面试团队去和推荐人详谈，这是为了尽量保证面试过程客观，避免详谈可能带来的潜在倾向性。

其次，在决策会上，我们可以收集推荐人的推荐陈述，但是它只能作为参考，主要的决策依据，依然是不变的。对于这一点，在具体操作上，该怎样做呢？我把我的做法列在下面供你参考：

决策会一开始，或者在第一环节的初始投票（如果你忘记了，请回看上一讲）前，请推荐人发言，Bartender 要问清楚这样三件事：

1. 推荐人在公司和团队中的职位角色，他和候选人的工作关系，以及推荐的程度。一起工作了多长时间，有多了解候选人？这一点很重要，有些时候这个推荐关系只是因为他们认识，或者是因为有一个共同好友而已；而有时候基于过去长时间共同工作的经历，他很了解并认可候选人。

2. 候选人有哪些优秀的素质，可以为公司和团队带来价值？这是属于推荐的“常规”内容了。

3. 还有没有需要面试团队知道的，候选人有关工作的重要情况？

需要说明的是，如果客观条件上推荐人不方便参会，那在会前由 Bartender 收集上面这些信息也是可以的。

你可能会问，我们都说要讨论正反两面，这里只要求谈论“优秀的素质”，是否不够客观？其实，我们当然可以请推荐人谈论候选人的不足，但是据我的经验，这个操作基本行不通。

具体说，就是很多情况下，特别是推荐人是候选人的好朋友时，他并不愿意在公开场合谈论候选人的不足，即便谈论，也是随便找一点内容搪塞过去。那既然如此，我们何必追问，搞得彼此很尴尬呢？

再次，在推荐人的陈述完毕后，我们请他离开决策会。

对，你没有看错，我们不希望他参加决策会的主体部分，不希望他了解投票和决策的过程，因此那样也就避免了潜在的尴尬。而且，对于所有的面试官来说，也可以继续常规的决策会流程，而不用把心思放到顾忌推荐人的感受上。

需要强调的是，推荐陈述对丰富反馈数据很有帮助，但从这个陈述的重要性来看，它不能超越我们的面试反馈。面试官还是要继续相信自己的观察和收集到的数据，决策流程不应该因此有什么大的改变。

最后，推荐人依然是一个可供确认候选人具体情况的资源，在一些特殊情况下，比如对于个别的观察有所担忧，因而面试官摇摆不定，那我们可以就单个具体问题询问推荐人，以获得更多信息。

妥善处理考察项覆盖的缺失

首先，大家都应该清楚，对于有面试计划的情况，这种情况其实是不应该出现的。但是一旦出现了，也不要抱怨，而应继续这个决策会，根据当前的讨论结果决定下一步的策略。

举例来说，如果在决策会的时候，我们注意到，原计划希望面试覆盖 2~3 轮编码，但是结果该候选人的考察只覆盖了一轮，因此我们就认为这一系列面试缺少了编码能力的考察数据：

如果候选人在该面试系列中表现不错，并且在所覆盖的那轮编码考察中表现出色，那么虽然数据有所欠缺，我们还是可以认为候选人编码能力是过关的，因此面试的最终结果为：通过。

如果候选人在该面试系列中表现不佳，没能通过，那就没有必要继续考虑编码的覆盖情况了，最终结果就是：不通过。

如果候选人在该面试系列中表现总体不错，但是在那一轮编码考察中问题却不少，这就是比较纠结的一种情况了。这时可以考虑调取电话面试中代码考察的数据，如果还是不好判断，又不愿意错过候选人，可以考虑额外增加一轮代码考察。

你看，就是这样，我们有时候得到的数据不够完美，但是就像用软件来解决复杂的实际问题一样，我们就是要能够应对这样不完美的情况。

我这里想补充一点，你也许会问，那一旦遇到考察覆盖不全的情况，加面一轮不就行了吗？事实上，由于它会明显消耗候选人和面试官双方的时间和精力，我们只有在没有更好的办法时，才会这么做。

最后，在这种情况发生以后，Bartender 和招聘经理需要从中吸取教训，在未来的面试安排中做得更好，尽量避免这样的情况再次发生。

管理争论和收敛分歧的操作技巧

处理面试官态度摇摆不定的情况

就像软件领域的二八定律一样，面试决策会也是，80% 的会议都很明确，大家的观点也很可能一边倒，很容易达成共识。但是剩下那 20%，则可能出现各种“纠结”的状态。

比方说，一种常见的情况，就是候选人优缺点并存，长项和短处都很明显，而很多面试官虽然有观点，但不坚定，或者说“自己也说不清楚”。

这时候，Bartender 的价值就体现出来了，可以积极介入，对事实数据进行分析和引导，而这些事实数据，恰恰都是这些摇摆不定的面试官自己得到的。

除此以外，在这里我还可以给你分享一个小技巧，就是把“从事实推定结论”，转换为“从结论思考事实”。比方说，某位面试官纠结于候选人过强的个性，听不进建议的做事风格，是否最终可能给团队带来弊大于利的影响，那么，Bartender 可以快速地问他这样两个问题——如果候选人加入了团队：

你觉得他是否能够很好地融入团队？

你是否愿意和他在工作中相处和合作？

前一个问题其实针对的是团队中的“其他同事”，而后一个问题针对的就是面试官“自己”了。两个问题都是为了得到面试官对候选人的团队契合度判断。

先回答，再反过来想“为什么”这么说，如果最终能够通过这个结合实际数据的“为什么”来佐证，那就是有效的观点，但必须明确的是，用“为什么”来佐证这一点必不可少，否则就真的变成主观臆断了。

通过这样的方式，其实是让你的“下意识”帮助你给出更准确的判断。

不要小看这一点，人的“下意识”其实是一种很强大的工具，很多事情的判断其实是有明确理由的，只是有时候我们自己并不清楚而已，因此我们需要一点技巧把它梳理出来。

引导对候选人的定级

作为决策会输出的一部分，面试团队需要给出一个明确的建议级别。虽说根据某些公司的流程，实际 offer 上写着的级别，未必完全由这一步确定，但面试团队经过了相当系统的面试和评估，其建议级别无疑具有举足轻重的作用。

级别怎样确定？我觉得你大致可以从这两个部分来考虑：

候选人的背景和经验。

候选人的面试表现。

前者，包括候选人的工作年限、在行业的影响力，已经做出的得到认可的成就等等。这听起来似乎理所当然，但是我注意到一些技术面试流程从一开始，对候选人设置的“默认级别”或者“期望级别”就是不合理的。

从决策会的角度说，根据候选人的面试表现，最终给出的推荐级别有可能会基于默认级别，有一定的上下浮动，但通常不会有较大出入。

因此，如果一开始大家都认可的期望级别设置出现了很大偏差，那么后面的流程就很难把它掰回来了。

以某公司为例，软件工程师的技术级别“初级工程师”一般工作经验不超过 3 年，而“高级工程师”为 5 到 10 年。那么，对于一名有着 7 年软件工程师工作经验的候选人来说，如果他去面试初级工程师，这个方向从一开始就是不合理的。

请让我进一步解释这一点。从初级工程师到高级工程师，这不仅仅对能力和经验方面要求更高了，还可以说，对他期望也是体现在不同的方面了。回想一下第 2 讲，我们已经谈到，对于初级工程师，我们更看重的是潜力；而对于经验丰富的工程师来说，我们更看重的是能力——这就是区别。

举例来说，对于初级工程师，我们更关心兴趣、热情、学习能力，以及是不是具备能够接纳意见等“潜力素质”，这些都是很难学到的、教不来的东西，而弱化了他立即独当一面，来工作和产出的能力。

但是，如果这位候选人已经有很多年的经验，或者说，无论基础的积累，还是做事的方法，都已经“成熟”了，那么我们就希望他已经能带领团队、快速产出了，招他的目的，自然就不是为了他的“潜力”。

也就是说，如果这样的“沙场老兵”候选人达不到高级工程师的要求，却满足了初级工程师的 bar，我们可以“降级”，给他一个初级工程师的 offer 吗？显然是不能的。

另外，对于工作年限，我想再做一个说明。工作经验，从量的数据来看，确实是和工作年限成正相关的。但是，放到个体上，这并不是绝对的。

举例来说，一个在互联网前沿领域，每天做着有挑战性工作的工程师，有了三年的工作经验；和一个在传统产业，每天机械地做着重复性的工作，也工作了三年，他们作为软件工程师所积累的“经验”，可能有着很大的差别。

总结与思考

今天我给你分享了一些操作技巧，帮助你在决策会中剖析事实、总结模式、管理争论、收敛分歧，并最终引导得出共识结论。不知道你是否有所收获呢？

在最后，我想给你留一个问题。假如说，决策会上，大家第一环节的初始投票时，就已经表达了非常一致的态度，比如说，所有人都是 No Hire，那么，你觉得这个决策会还有必要继续进行下去吗？还是说，直接给出一个共识结论——“不通过”就可以了呢？欢迎在留言区讨论。

好，我是四火，我们下一讲见。

12 | 线上面试：隔屏对话，交流依然畅通

你好，我是四火。

这是我们场景再现部分的第一篇，我想和你聊一聊线上面试。

线上面试，是指候选人和面试官双方不实际见面，而是通过电话、网络等形式“虚拟”地面对面交谈，最终完成面试。

通常来说，电话面试就是线上面试最典型的情形，而在当前的疫情大背景下，许多本该面对面进行的现场面试，也移到了线上。

这一讲，我将从三个部分谈论线上面试：首先是常见问题，我会介绍几个因为面试操作移到线上而导致的常见问题，接着明确线上面试和常规线下面试相比，需要把握的要点，以及一些具体操作方面的技巧，希望这些内容对你有所帮助。

常见问题

电话面试不确认基本要求

在第 2 讲的时候，我讲了这样一个例子：

走完了整个面试，候选人拿到 offer 的时候说：“啊，我不知道这个职位还需要我长期出差办公啊？我不能接受出差办公。”

还有类似的例子，比方说，有不少候选人对于自己的职业生涯有明确的规划，而对于自己在技术或业务方面的选择也非常清晰。

有的说“我不做前端”，有的说“想进入‘大数据’团队”，还有的说“希望从事和分布式系统有关的工作”。可是，有很多时候，候选人直到进入了现场面试，甚至通过了面试，都没有人和他们确认这些最基本的需求。

显然，这样的面试流程是有问题的，那问题出在哪里呢？

我们知道，所有的职位都是有“基本情况”的，而所有的候选人也其实都是有“基本要求”的，但是他们往往不会明说。

等到职位的基本情况和人的基本要求不符，矛盾总有一天会暴露，那时面试团队也好，公司也好，都要被迫承担浪费时间、浪费资源的损失，甚至还会大大影响团队建设。

也许是 offer 发放了，但是候选人拒绝了；也可能候选人入职了，但是因为这样的原因不顺心，不能发挥所长，甚至还会早早离职。

那么，这样的信息到底包括哪些内容，又应该在什么时候确认呢？

我认为，基本要求是不是匹配，需要问清楚两个方面的问题：

公司和职位的基础信息，比如说，工作地点在哪里，是不是需要出差等等，看候选人是不是能够接受；

业务和技术的基础信息，包括团队是做哪方面的产品或项目的，如果候选人加入团队，那么他会承担怎样的角色。

通常来说，一些非技术和业务方面的基础信息，一般招聘专员（recruiter）一开始就应该和候选人聊清楚了，如果候选人不接受，那么后面的面试就不应该安排下来。

还有一些具体信息，招聘的同事不一定懂，但是负责电话面试的面试官必须要清楚，并且要在电话面试的环节就要和候选人明确下来。

因此，这里的分工合作非常重要。一般说来，在电话面试中，有一轮是团队的经理去负责的，原因之一就是经理往往是团队中对这两个问题最清楚的人。

冷场过多，沟通不足

在第 5 讲的时候，我们谈到了面试礼节的重要性，不知道你是否记得，其中一条就是要做简单的自我介绍，哪怕再简单，它也是面试互动中必不可少的环节。

尤其在线上面试时，其实双方很容易会因为缺乏语言交流，干扰整个面试氛围，有时甚至会陷入一种尴尬的境地。

如果面对面交流，哪怕语言交流不充分，大家还可以用其他方法弥补，可能一个眼神、一个点头就能表达相当丰富的信息了。但到了线上，交流更依赖语言这个形式，所以语言沟通不充分带来的影响就被放大了。

当然，我还想提醒你，线上面试确实更依赖于语言，但我们也还是有其它沟通方式的。比方说，我们曾经讲到过，远程沟通的时候，摄像头请尽量打开，面对面的沟通会让彼此距离拉近很多。

如果考虑到网络带宽受限等因素，必须关闭摄像头，那也请和候选人说清楚。而且，我们还有一些在线编辑工具，通过这些工具，候选人和面试官都可以看到彼此输入的文字，甚至绘制的简单图像。

我知道面试官都清楚用它们可以考察代码，但是其实作为常规沟通套路的辅助工具，它们依然很有价值。

要点把握与面试技巧

好，分析完常见问题，我们从正面谈一谈线上面试的一些常见操作要点，以及相应的面试技巧。

电话面试难度把握的原则

对于电话面试的难度，我的建议是更重视广度覆盖，把基本情况了解清楚，把基本问题排查清楚。

至于技术深度，我反而认为是第二位的。这里面的逻辑是，我们要优先考虑电话面试带来的特有价值，它最大的价值其实就是两个字——“初筛”。

为什么需要初筛？这里我们不妨简单估算一下成本。

比方说，电话面试两轮 + 现场面试 5 轮，加上决策会，面试前后的联系、沟通、反馈等等时间和人力开销，加起来就相当于工程师一天的工作时间。再加上其他人员、培训、宣传、差旅、招聘渠道合作等等费用，可以说成本相当巨大。

以下数字来自我自己的经历，而非官方数据，但你也会有个大体感受：电话面试的通过率大概在一半左右，在此之后我们还要考虑现场面试的通过率（大概在 1/3 左右），以及发了 offer 后候选人接受的比例（每家企业差异较大，这里按 1/3 估算），粗略估算一下，整体的 offer 接受比例就只有 1/2 x 1/3 x 1/3 = 1/18。

可以看出，仅从综合费用的角度考虑，招聘成本也是非常高的。

所以，在电话面试中，我们要达到这个初筛的目的。通过电话面试这样成本相对较低的流程，留下基本素质合格、基本要求符合，且有一定希望通过现场面试的候选人，而这，也正是电话面试难度把握的原则。

至于候选人全面和有深度的考察和评估，就放到之后的现场面试去完成。这样，在电话面试之后的大量流程成本，就能节省下来了。

另外，这些年来我还发现一个有意思的现象，和你分享一下。有时候和候选人沟通的“第一棒”——recruiter，甚至也会问一点技术问题探底了。比方说，我所认识的一位 recruiter 朋友，就会在第一次和某些候选人沟通的时候，问候选人这样的问题：

进程和线程的区别是什么？

这其实是属于很常见的问题，当然，他是懂一点，但毕竟不是软件工程师，也直言只是想“听听回答是不是靠谱”。但是通过这样的方式，可以过滤掉那些明显不合格的候选人，这样，连电话面试的流程成本都可以省下来。

电话面试的内容安排

既然我们已经提到了电话面试的最大价值就是“初筛”，那么具体我们该怎样安排电话面试的考察内容呢？

电话面试一般安排较为简洁，招聘经理和某位工程师一碰头，双方各自过一下对方简历和 recruiter 留下的重要信息，就可以参与电话面试了。电话面试之后，双方也一碰头，确定要不要继续下一步的现场面试。

电话面试有一轮的，也有两轮的，两种情况都不少。

对于一轮的情况，一般由具备技术背景的经理主持，既要考察一些较为简单的技术问题，也要通过询问尽量了解对方的基础信息。

如果是两轮，那一般其中一轮由工程师完成，主要考察技术和业务背景，而把其它方面的考察，留给另一轮的经理。

关于技术考察，有个细节值得一说——要不要在电话面试考察编码呢？

我的建议是，只要时间安排能够满足，就尽量覆盖编码考察。我们已经强调过，对于软件工程师来说，编码能力是硬能力，如果连基本的编码能力都不具备，就没有继续这个面试流程的必要了。

当然，电话面试时间往往较短，一个简单的算法问题，或者写一段简单的代码逻辑，就可以了，我们不要在电话面试中，像第 6 讲一样去层层递进，完整地覆盖问题分析、讨论、解决的考察链。

说了那么多，我来举一个具体的电话面试安排的实例吧。

候选人小王是一名软件工程师，他研究生毕业后工作 3 年了，第一年做的是软件测试工作，而后转为开发。他面试的岗位是一家互联网公司的某后端软件工程师岗位，电话面试一共包括了两轮：

第一轮的面试官由一位团队经理担任，在寒暄之后，他和候选人顺着简历的内容，讨论了他的背景和工作经历，包括他对下一份工作的期望；之后，他向候选人介绍了职位、工作地点、工作内容，使用的技术和流程，以及团队的文化氛围等基本情况，并向小王了解了他的想法；最后，在提问时间他回答了不少小王关心的问题。

第二轮的面试由该经理团队中的一名软件工程师担任，他们花了大约二十分钟时间讨论了小王最近在做的一个项目，候选人都负责了哪些部分，系统的架构是怎样的，主要用到了哪些技术；之后面试官和小王一起讨论了二叉树几种遍历的形式，小王也写了一段递归的二叉树遍历代码。

在电话面试之后，两位面试官聊了一下。

主导第一轮电话面试的团队经理表示，候选人小王对于这个职位有明确的意向，背景经验符合要求，性格和沟通等方面也没有什么问题；而主导第二轮电话面试的软件工程师表示，候选人小王对业务和技术的理解均衡，有一定的经验积累，而且对做过的项目和系统有清楚的理解，他写的代码逻辑虽然简单，但是可以看出具备合格的算法和数据结构功底。

于是，小王就通过了电话面试，准备进入下一轮的现场面试。

最后，我想额外提一下，某些企业，满足一定条件的情况下，甚至允许候选人跳过（直接通过）电话面试，而直接进入现场面试的环节。有这样两种情况比较常见。

第一种情况，对于重要岗位员工“强烈推荐”的候选人，这背后的逻辑是企业和团队对于自己员工“眼光”的高度信任。

第二种情况是，该候选人是“旧人”，曾经在这里工作过，或是在冷冻期（一般大厂都会设立一个招聘冷冻期，比方说，候选人在面试后的半年内，不可以申请相同类型的职位）之前曾经面试过，属于二次求职，而他的历史数据显示，他在曾经的面试表现不错。

当然，无论是哪一种情况，如果电话面试选择跳过，那么我们通常也要求招聘经理和候选人至少电话沟通一次，以了解、更新一些基本信息，确认一下双方的需求。

准备好 Plan B

无论是电话面试，还是移到线上进行的现场面试，我们都要有 Plan B。这里的 Plan B 指的是，在线上面试遇到阻碍的时候，要有基本的替代方案。

最常见的情况是，网络不佳，声音断断续续，这很影响面试沟通交流。

在一些成熟的面试团队中，负责一开始接洽候选人的 recruiter，就会提示候选人准备好面试当天的设备条件。但是，谁也没有办法避免突然出现的网络状况，无论是彻底掉线还是视频或音频卡顿。

对于这样的情况，我们要有准备。例如，在网络不好时，我们可以关闭视频信号，甚至，可以将线上会议改为使用手机通话来进行，当然，在线编辑（包括编码）的工具的使用可以保留，一方面这样的工具对网络条件的要求低，另一方面，我们确实也没有更好的替代工具，可以在离线状况下考察编码能力。如果条件过于恶劣，我们只能考虑改天再继续面试。

总结与思考

今天我先介绍了两个线上面试的常见问题，然后分享了线上面试，特别是电话面试中的一些要点，以及该怎样具体把握。

总的来说，线上面试在很多方面都有所限制，不能像面对面的现场面试那样沟通自然、直接，但在固定的电话面试环节，以及如今“后疫情”的大背景下，线上面试已经从一个选择，变成了唯一的选项。

因此，希望你能很好地掌握这些技巧，逐渐积累经验，真正驾驭好它。

在文章的最后，我想给你提一个问题。你能否在留言区，分享一下你经历过的电话面试呢？无论是作为候选人，还是面试官。

好，我是四火，我们下一讲见。

13 | 简历识人：洞悉简历背后信息，动态调节面试策略

你好，我是四火。

简历，有多重要？我听说过截然相反的两种观点。

一种观点是说，简历非常重要，因为简历就好比是人的脸面。未见其人，未闻其声，先读简历。从简历这短短的文字中，可以看出候选人的诸多品质，而简历如果不过关，下一步的求职面试就根本无从谈起。

还有一种观点认为，简历作用很小。如今简历包装的成分太大，上面的信息夸张的情况随处可见，作为面试官，还是更应该相信自己的观察，候选人在面试中的表现才是实打实的。

那么，到底谁才是正确的？

其实，这两种陈述都有道理。这两种截然不同的观点，背后的认识并没有多少冲突，主要是因为人们看问题的视角不同。事实上，我问过多位面试官，大家对于简历重要性的分歧也很大。

那今天，我们就来聊一聊简历，而我的视角，更多的是以面试官的身份，结合面试和评估候选人这一方面为你做讲解。

面试前的简历识人技巧

确认职位的匹配情况

面试前，一般招聘专员（recruiter）有他们自己的一套方法审阅简历。他们会根据简历上的内容，以及和候选人电话、邮件沟通得到的信息，来确认候选人跟职位确实大致匹配，而且，在很多公司，他们还会先确认一个候选人的参考级别。

但是，他们通常不具备技术背景，因此对于软件工程师候选人，面试团队需要审视并且确定职位是合理的。

在 OCI，Bartender（技术负责人）需要在做面试计划的时候过一遍候选人的简历，确保职位和默认级别大致没问题。

比如说，一般 1~3 年软件开发经验的候选人考虑定位到 OCI 内部名为 IC2 的级别。

这一步很重要，因为整个面试团队的面试官，就会对应着这个默认的职位级别衡量和评估候选人，一个离谱的定位会导致后面整个面试和评估的逻辑体系坍塌。

此外，我们经常会听到候选人说，“我现在的级别虽然只是 xx，但我‘即将升职’”，这样的信息通常我们不会考虑进默认级别的评估里。因为这样的事情并不明确，没有足够的参考价值。

收集技术背景等重要信息

在面试之前，浏览简历的过程当中，我们确实需要重点关注那些实际的背景数据，比如是什么学校毕业的、有没有获奖和专利、有怎样的工作经历等等，但是这样的过程，基本上早就经过了专业的 recruiter 们的法眼。

Recruiter 就是候选人和团队接洽的桥梁，在大多数公司，recruiter 会把简历和候选人的材料发送给目标团队的招聘经理；还有些公司，这一步做得更为开放，recruiter 会把通过他们审阅的简历，放到公司的平台上供各个团队的招聘经理取阅，优秀的候选人往往会引起好多团队的兴趣，之后 recruiter 会让候选人挑选其中的一两个团队进行下一步的面试。

无论是哪一种，大多数面试官拿到简历的时候，已经不需要做什么实际的简历初筛了，因为 recruiter 和经理已经把这件事做完了。但是，Bartender一定要独立地过一遍简历的大致内容，主要是关注一些技术背景和职业经历等信息，如果有一些重要的疑问，需要在面试的过程中得到解答。比方说：

1. 候选人说他有 5 年软件开发经历，但是简历上显示其中有一年他的职位是软件测试，还有一年的空白时期；

2. 候选人的项目背景基本全是后端开发的，但是这一次的职位却是一个前端的 Team Lead；

3. 候选人最近这两年的职位是团队经理，但是这次面试的是一个资深开发工程师的职位。

面试官找到这些重要信息以后，就可以在面试的时候加以关注。例如，对于上面的第 2 个例子，需要重点覆盖一些职位必要的前端技能。

此外，对于一些特殊的、重要的角色，由于对候选人要求较高，我们尤其需要关注简历中的背景信息，更严苛地寻找候选人。

比如说，如果是一家小企业，或者是大厂的新部门，要招一位相当资深的工程师，需要这个人带团队和主导一个新项目，这个人的简历，需要足够“亮眼”（比如作为骨干做过相关产品、有所属领域的专利、毕业于名校对应专业或是有相关的开源项目的开发经验等），证明他具备这个职位职责所必须的潜力。

面试中的简历识人技巧

对面试官来说，候选人的简历不仅仅是一篇短短的文字，而可以看做是候选人的“上下文”，从这个角度来说，面试就是考察上下文和目标职位匹配程度的一个过程，而简历的内容就为考察提供了一个非常好的了解和切入的点。

深挖简历中的事实数据

我们在专栏中已经介绍了，简历是一个用来深挖候选人对于项目、对于系统理解的一个很好的途径。但是，具体怎么挖呢？

简单来说，就是寻找简历中的“具体事实”，而非“模糊描述”。举例来说，候选人的简历上说：

性格开朗、乐观，沟通能力强，乐于主动帮助同事。

这样的文字，就更偏向于“模糊描述”，更何况，性格具体如何，还是面试过程中体现出来的内容更有说服力。面试时间如此宝贵，对于这样的描述，技术面试官基本上可以跳过。

而对于“具体事实”，最常见的一类内容，就是项目了，比如说：

带领一个 3 人团队，半年时间完成了公司内部上千人使用的工时管理系统，前端使用 Angular 技术实现，application 层使用 Spring + Tomcat 搭建，数据库使用 SQL Server。

这样的文字，无论多么简单，都是我们面试时一个很好的切入点，因为它包含了很多有价值的信息：

从组织管理层面，可以看出候选人有带领小型团队的能力；

从项目层面，可以看出这是一个半年期的项目，而且用户定位为公司内部使用，有上千人的用户数量；

从技术层面，可以看出候选人在项目中使用的技术。

而这些分项，每一条都是一个可以用来深挖的好方向，这就要看面试官的考察重点了，这部分我们在专栏中已经介绍过了。

另外，根据我的观察，这些年来的简历，质量可以说是越来越高了，那些说空话、套话的简历越来越少，而陈列具体经历的简历越来越多。

和资深的候选人聊经历

一般说来，越是资深的候选人，他们的简历中，“职业经历”的分量就越重。可能很多面试官理解这一点，但是在具体操作的时候并没有加以区分。

我记得我刚参与面试没多久，有一位老面试官教了我一个技巧，对于老兵，他们的简历要仔细挖，这里有两方面的原因：一方面是他们的简历确实有东西可挖，项目也好，软件系统也好，往往都有很多东西可以聊；另一方面，挖他们的简历，也是对于他们的尊重，这是一个不可缺少的环节。

这其中的第二点当时就让我觉得耳目一新了，一开始不太理解，但后来细想确实有一定道理，经过这些年的积累，我越发觉得这是一个很有意义的观点。至少，经过我的检验，别的不说，这种做法往往能够调动起来对方的情绪，候选人饶有兴致地介绍他的某一段经历，而对我们来说，这就是一个可以展开讨论，并顺着向下挖掘的信号。

那这背后的逻辑是什么？我们都知道，对于战场上的老兵来说，一种属于他们的自豪感，就是他们的经历和功勋。对于软件工程师候选人来说，做过的项目也好、系统也罢，这些一样是他们宝贵的经历。

而且，别忘了我们说过很多次，面试是双向的，在面试中，我们并不只是采集数据评估候选人而已，而是还要向对方展示出面试团队求贤的态度。毕竟，当你在反复强调希望候选人加入团队的时候，却对他在简历上的背景和经历毫无兴趣，这显然是有些不合情理了。

留意技术掌握程度的表述

不知你是否注意过，很大比例的简历都有一些对于技术掌握程度的描述，比如说，“精通 Java”、“熟悉 Spring”、“熟练掌握 JavaScript”等等。遇到这种情况，可以择其一二进行确认，一般最好鉴别的就是其中掌握程度最高的那几个。

比如说，既然说“精通 Java”，如果面试官也对 Java 有一定深度的了解，那么就可以询问一些关于 Java 技术的知识了，而且这样的问题可以具备一定的深度，毕竟“精通”这样的标准已经在简历中明确了。

通过两三次这样的考察，我们有时候就能发现一个形成“模式”了的数据点——如果候选人都能够很好地回答，那么他很可能在简历中，对于这些技术掌握程度的表述就是准确的；反之，如果候选人的回答，显示出他并不“精通”他宣称精通的技术，那么我们也可以认为，候选人很可能在简历中对于技术掌握程度的内容，不够可信，或者说是要打折扣的。

这样的问题，可以作为一个很好的探查候选人技术深度的数据点。需要说明的是，这和我们第 3 讲中说的，避免问“知识性问题”不同，因为这是一个候选人在简历中明确了的擅长的技术领域，对于这次的面试来说，并不存在“随机性过强、普适性较弱”的问题。

再举一个我自己经常实践的例子吧。如今“分布式系统”已经成为热门词汇了，很多候选人的简历上也写有他擅长的领域包括了分布式系统。那么，我有时就会问候选人一个看似简单的问题，“什么是分布式系统？”。

别看这个问题看似简单，能够回答好的候选人其实不多，而大多数人只能用描述性的语言，给出自己对于“分布式系统”这个词的理解，而这个理解可以说是五花八门，有不少候选人甚至直接把一个 Server 集群就等同于分布式系统的定义了。

根据候选人的回答，我大致就对后续进行的系统设计等考察心里有谱了，无论是问题的展开，还是难度的控制，都可以做相应的调整。

面试后的简历识人技巧

协助评估决策的数据来源

通常在面试后，包括面试后的决策会上，我们是很少再把候选人的简历拿出来讨论的。但是，在一些特殊情况下，我们还要再回看候选人的简历，以帮助我们做出更好的决策。其中之一就是在给候选人定级出现纠结的时候，候选人的简历就是一个很好的参考内容来源。

还记得我们在第 11 讲的决策会定级部分的时候提到，对于候选人的评估，包括这样两个部分：

1. 候选人的背景和经验；

2. 候选人的面试表现。

这样两个部分中，而前者的数据来源之一，就是候选人的简历。在一些特殊情况下，例如，在 OCI，决策会无法达成共识，因而 Bartender 将面试的记录，送往专门处理这种特殊案例的“招聘委员会”，那么候选人的信息，特别是他的简历，就是其中必要的材料之一。

当然，必须要说明的是，这样的数据来源，始终是起辅助作用的，最重要的数据，还应该是我们在面试过程中所记录下来的那些。

总结与思考

今天我们根据面试前、面试中和面试后的顺序，介绍了“简历识人”的要点。希望你能够体会到简历在面试过程中，特别是文中提到的特定情形下，所扮演的重要作用。

好，我是四火，我们下一讲见。

结束语 | 操千曲而后晓声，观千剑而后识器

你好，我是四火。

经历了疫情的特殊一年，又是一个阳光明媚，草长莺飞的五月，招聘季已经到来，很快我们这个讲解技术面试的专栏将迎来尾声，不知道你是否系统学完了这个专栏的内容，并且有所思、有所得呢？

现在，让我们温习和梳理一下，我们在专栏中都学到了哪些内容。我结合每一讲的内容，提炼了课程中重要的知识和观点，为你准备了一张体系化的思维导图，供你查漏补缺。

在这里，我不会面面俱到地覆盖所有要点，而是按照专栏的结构，挑选几个要点回顾，帮你强化记忆，掌握已有的知识技巧。

要点回顾

第一部分：面试准备 / 计划篇

在第一大部分，我们其实讲了三件事情：体系评估，计划制定，以及问题设计。

体系评估很重要，但我们只需要认真仔细地做一次，后续只需要定期调整即可。而对每一位参加现场面试的候选人，面试官都要制定计划，这是一件花不了多少时间，但很容易被忽视的事情。还有问题设计，这需要面试官慢慢积累，逐步调整自己在面试中使用的问题列表。

接下来我把这三件事展开给你说一说。

先来看体系评估。公司和团队，到底需要怎样的技术人才？这就是我们建立整个面试考察评估体系的时候，最最基础的那个问号。

对于候选人的评估体系，大致可分为两个角度：一个是共通部分，就是对于一名优秀的软件工程师普遍的、客观的理解；另一个是特殊部分，指的是不同的团队和细分职位，对于软件工程师候选人，有着不一样的要求。

前者是考察角度的主体，我们经常从技术角度和非技术角度来划分，技术部分包括实际问题解决能力、代码设计和实现能力、系统分析和设计能力和其它综合工程能力，非技术部分包括基础品格、团队合作能力、学习能力、沟通能力，以及任务管理能力等。

其次是计划制定。想要完成一次成功的现场面试，制定计划必不可少。缺乏面试计划，轻则浪费时间，让候选人失望，让面试官尴尬，重则招进来不合适的成员影响团队。

面试计划制定的重点是确定人选（包括两个特殊的角色招聘经理和技术负责人），以及考察内容、考察重点的安排。这里所说的安排需要遵循两个方面的“一致性”原则，分别是面试团队的职位和角色匹配上，要遵从一致性原则；以及考察角度、考察重点、考察内容，三者也要遵从一致性原则。

接着是问题设计。在技术面试中，技术问题就是这个面试内容的直接体现，它要围绕考察重点展开，如果技术问题没有设计正确，对于候选人的考察，就不可能靠谱。

技术问题最理想的效果是，问题覆盖了我们要考察的重点，平衡了深度和广度，并且问题的最高难度，恰恰是候选人“踮踮脚能够到”的难度，既不会过度简单，又不会难不可达。

第二部分：面试进行 / 实践篇

专栏的第二大部分，就是讨论真刀真枪面试的流程把控了。只有把控好流程，我们辛苦设计的面试计划、技术问题才会真正派上用场，才能收集到足够的事实数据，全面合理地评估候选人。

这部分主要讲了整体把控流程的原则和技巧，同时我们详细讲了最常见的算法和数据结构考察和系统设计能力考察这两类考察方式怎样实现，还介绍了对于其它工程技能的考察方式。

面试的流程把控，它对面试的质量影响特别大，因此面试官需要始终保持状况的可控，保证最核心的考察项能够覆盖到，同时还能够给候选人留下一个好印象，这里我们学习了一些原则和技巧。

面试，说到底是社交活动的一种，必须建立在平等和尊重的基础上。因此我们要保证整个面试过程有头有尾，在面试中表现得有礼有节。

对于技术面试而言，面试官要抱着和候选人一起做一个有头有尾的迷你项目的心态，这样，不但可以实现广度和深度平衡的考察，还可以令整个面试过程完整。

在问题求解和面试推进过程中，面试官需要选择合适时机介入。如果候选人能力很强，对于问题的推进合理有效，那么面试官就要学会做“绿叶”，给对方更多的发挥空间，让对方去主导问题的解决；反之，如果困难过大，时间落后，或者看着路线要“跑偏”，那么面试官就要毫不犹豫地及时介入，主动调控，保证整个方向和时间可控。

算法和数据结构考察可以说是最经典的一种技术面试考察类型，具体的流程把控上有不少技巧，我使用一个详细的案例向你呈现了，该怎样使用“给出挑战”和“要求澄清”两种方式，不断地推进问题解决。

作为面试官，只要是思考向着大体正确的方向，我们的优先选项一定是顺着候选人的思路走，一起讨论，即便这样的思路不是最佳的。

考察算法和数据结构，编码能力考察往往是必选项，这就牵涉到白板编码的问题。在我看来，白板编码虽然也有不足，但现在却无法被替代。事实上，它是如今现场编码考察的操作方式中，最公平、最直接，且最有效的一种方式了。

相较于算法和数据结构的考察，系统设计能力考察的流程推进和评判标准明显不同，我们往往没法给出丁是丁卯是卯的正误判断，因而面试中更多是讨论可行性，以及对于不同实现方案的利弊权衡。

我们在面试中，一定要摒弃掉所谓的“最佳设计”或者“推荐方案”这样的想法，而是尽量追着候选人的思路跑。换言之，面试官可以主导面试，却不要主导设计。

从具体的考察形式看，主要有两种，一种是让候选人讲他自己熟悉的、做过的系统；另一种是给出一个实际问题，细化、分析，延伸成一个对于核心功能的系统设计问题，并加以讨论和解决。这两者，我们都结合实际案例做了详细说明。

最后是其它技能考察，近几年来大家对于软件工程师的全面性要求越来越高，考察的类型也愈发多样。面向对象考察就是其中一种，它通常包含了两个方面，一方面是考察代码层面的面向对象设计能力，另一方面则是综合代码组织的能力。

还有 API 设计考察、测试能力考察和项目、任务管理能力考察等等，这些项虽然看起来琐碎，但随着对软件工程师候选人的全面性要求越来越高，你也不要忽视它们。

对于行为型问题的考察，我们不但学习了背后的逻辑（即候选人在过去遇到困难的时候，遵循的逻辑和采取的行为，这相当程度上反映了未来候选人将怎样应对类似的困难），还重点讲了操作要点的四大关键步骤，即“情境”、“思考”、“应对”和“结果”。

第三部分：面试反馈 / 决策篇

第三大部分围绕着面试之后的决策展开。也就是我们该怎样收集事实、提炼数据，并在决策会中对候选人做出全面和有深度的评估决策。

首先在收集事实数据，书写面试反馈方面，使用反馈模板这个技巧用处很大。具体操作上需要注意，一个是要保证包含面试考察最关心的点；另一个是模板要简单、直接，因为越简单、直接，可操作性就越强。我给出的参考模板包含了考察重点和主要考察内容，优势和不足，以及综合结论这样几个部分。

接着就是决策会了。决策会，就是大家碰头商讨候选人情况，达成面试共识的过程，这个环节很重要，且没有其它方式替代。

决策会有不少典型误区，我在文中介绍了几个，我们尤其要避免“将决策行为变成民主选举”这个非常常见的做法。我们要关注的是，决策背后的逻辑是不是合理，而非人数是不是占优。

我们介绍的决策会流程，可以大致分为三个环节：初始投票、反馈陈述，争辩开展与共识达成。其中，对于 Bartender 来说，最具挑战性的是在第三环节中，怎样汇总建议，收敛分歧，达成共识，为此我们一起专门讨论了一些方法技巧。

场景再现

在场景再现模块，我跟你探讨了两个专题内容，第一个是关于线上面试的。线上面试既包括传统的电话面试，也包括由于疫情等原因，移到线上进行的现场面试。

其中，对于电话面试广度和深度的平衡，我的建议是更重视广度覆盖，掌握好基本情况，把基本问题排查清楚，因为电话面试的最大的价值其实就是初筛。在后续的讨论中，我分享了线上面试的一些技巧，并给出了一个具体的案例帮助你理解。

第二个专题是关于简历识人的。面试官去认识候选人，未见其人，未闻其声，先读简历，从简历这短短的文字中，可以看出候选人的诸多品质。尤其结合面试的流程，这里面更有一些重要的技巧。

面试前，简历可以帮助确认职位的匹配情况，也可以帮助面试官收集候选人技术背景等重要的信息。面试中，简历可以作为切入点，面试官可以和候选人聊经历，深挖其中的事实数据。而在面试后，简历也能作为候选人评估的参考内容。

结课寄语

天下没有不散的筵席，专栏到这里，也要告一段落了。相信你也已经看到，小小面试的背后，水确实很深。正所谓“操千曲而后晓声，观千剑而后识器”，技术面试也需要你学以致用，在实践中深化认识。

如果你把专栏的学习、你自己的思考，与后续具体的面试实践三者结合起来，反复地操练，不断完善你自己的面试原则和方法论，这趟旅程才算真正“功德圆满”。

在你未来的职业生涯发展的道路上，我很期待这个专栏带给你的启发和收获，能成为真正助力的一步。希望疫情尽快过去，祝愿你的公司和团队能够招募到合适的人才，愿你百尺竿头，更进一步。

在这个专栏结束之际，不知道你是否有所收获呢？

我想听听你的看法。欢迎你继续在留言区发表观点，专栏更新结束了，但专栏的问答和讨论并没有结束。

此外，如果你对全栈开发感兴趣的话，我在之前还写过另一个专栏《全栈工程师修炼指南》，也欢迎你移步阅读。

最后，我还为你准备了一份调查问卷，题目不多，希望你可以花两分钟填一下。十分期待能听到你的反馈，说说你对这门课程的想法和建议。

好，我是四火，我们后会有期！