微信号:infoqchina

介绍:有内容的技术社区媒体

如何面试工程师?

2017-07-27 08:00 Ammon Bartram
作者|Ammon Bartram
编译|蔡芳芳
技术面试常常有很多坑,不管是对面试官还是面试者来说,都是如此。这篇文章可以让技术面试官规避很多面试过程中可能出现的问题,也可以给即将参与技术面试的面试者一定的启发。
写在前面

我们在 Triplebyte 进行过很多次面试。事实上,在过去的两年中,我曾经面试过 900 多名工程师。这到底算不算很好地利用了我的时间还有待商榷!(我有时会突然惊醒并对此产生怀疑。)现在暂且不管这个问题,我们的目标是改善雇用工程师的方法。为此,我们采用盲背景面试,只考察编程技能,而不看证书或简历。在工程师通过我们的面试之后,他们会直接进入和我们合作的公司的最终面试(包括苹果、Facebook、Dropbox 和 Stripe)。我们面试工程师时并不看他们的背景条件,而会在后续观察他们在各个顶尖科技公司中表现如何。我认为这种方法为我们提供了一些非常棒的面试数据。

在这篇文章中,我将介绍一下我们从这些数据中学到的东西。技术面试在很多方面都存在问题。说这话实在太容易了。(许多博文也确实是这么说的!)最难的部分是如何解决这些问题。我写这篇文章的目的就是要直面这个挑战,并为招聘经理和首席技术官提出具体的建议。面试确实很难。但是我认为更小心谨慎地进行面试可以解决很多问题 [1]。

技术面试现状

大部分面试过程包括两个主要步骤:

  1. 申请人筛选

  2. 面对面最终面试

申请人筛选的目的是尽早过滤候选人,并节省面试时间。筛选过程通常先是招聘人员浏览候选人的简历(约 10 秒钟),然后是 30 分钟至 1 小时的电话面试。与我们合作的公司中约有 18% 的公司会让候选人进行一项可带回家完成的编程挑战(代替电话面试或者作为电话面试的补充)。有趣的是,绝大多数候选人在筛选步骤就会被拒绝。事实上,在所有与我们合作的公司中,超过 50% 的候选人在简历筛选阶段就被拒绝了,另外 30% 的候选人在电话面试或编程挑战中被拒绝。筛选阶段可以说是招聘中最反复无常的。招聘人员不堪重负,因此需要快速做出决定。这一步也是证书和模式匹配发挥作用的地方。

面对面最终面试大部分会包括一系列 45 分钟到 1 小时的谈话,每次谈话对应不同的面试官。这些谈话主要是技术性的(每个公司会有一两次谈话重点考察文化适应度和软技能)。在候选人离开之后,招聘经理和面试过候选人的所有人会聚在一起开会做出最终是否录用的决定。基本上,候选人至少需要得到一个人强有力的肯定,同时没有强烈的反对者才会被录用 [2]。

除了常见的面谈形式之外,最终面试还有各种不同特点。

  • 在与我们合作的公司中有 39% 在面试中会让候选人在白板上展示解题过程

  • 52% 允许候选人使用自己的电脑(剩下还有 9% 既不用白板也不用电脑)

  • 55% 让面试官自己提问题(剩下的 45% 使用标准的问题库)

  • 40% 需要考察候选人学术方面的计算机软件技能来决定是否录用

  • 15% 不喜欢过于学术的计算机软件技能(并认为谈论学术能力暗示候选人缺乏创造性)

  • 80% 允许候选人在面试中使用任何编程语言(其余 20% 要求使用特定编程语言)

  • 5% 在面试中会明确评估编程代码的细节

在与我们合作的所有公司中,参加最终面试的候选人有 22% 能得到工作机会。(这个数字是从公司的内部候选人通道询问得来的。通过 Triplebyte 申请的候选人有 53% 在面试之后得到了工作机会。)通过面试的人中约 65% 接受了这个工作机会(即最终被雇用)。1 年以后,公司对大约 30% 的新聘用员工感到满意,同时已经有 5% 左右的新员工被解雇 [3]。

漏判和误判

那么现状到底存在什么问题呢?毕竟,解雇比例似乎还在可控范围内。为了搞明白其中的问题,需要考虑面试失败的两种情况。面试可能会雇用一名不合适的工程师, 然后过一段时间又解雇掉(此为误判)。同时面试也可能会错误地低估那些本来可能做得很好的人(此为漏判)。糟糕的雇员是很容易被发现的,而且对公司而言代价昂贵(从薪酬、管理成本和整个团队的士气来看)。一个糟糕的雇员还会损耗团队的精力。相比之下,那些本来能做得很好但没得到机会的候选人带来的损失则难以察觉。每次这种情况的出现总会存在争议。由于这种不对称性,公司进行面试时更多地倾向于拒绝。

这种倾向还会被面试过程中的噪音加强。在 1 小时内判断编程技能水平从根本上来说是非常困难的。在此基础上再加上模式匹配和几次电话考察,以及前面讨论过的按公司各种偏好进行的复杂考察,最终留给面试官的是一个包含了大量噪音的信号。

面对这些噪音,为了保持较低的误判率公司在做决定时必须倾向于拒绝。这样做会导致公司的面试过程可能错过优秀的工程师,常常过于看重证书而非真才实学,且会让参加面试的候选人感到反复无常和备受打击。如果你所在的公司中每个人都为了得到现在的工作重新进行面试,那通过率会是多少呢?这是一个非常可怕的问题。答案肯定远不到 100%。那些本来可以很好地完成工作的候选人在被公司拒绝后会受到伤害,而公司在找不到所需人才时也会受到伤害。

这里需要声明一下,我并不是说公司应该要降低面试的门槛。面试本来就需要拒绝一部分人!我也不认为公司更担心误判而不是漏判是错误的。毕竟糟糕的雇员确实需要付出高昂的代价。我只是认为当一个充满噪音的信号与避免糟糕的雇员的需求同时出现时,会导致非常高的漏判率,这样做会伤害到候选人。而这个问题的解决办法是改善信号

面试中减少噪音的具体方法
1. 明确你要寻找的技能

世界上并不存在一套唯一的可以定义一个好程序员的技能。反之,存在着大量各不相同的技能集。没有工程师可以精通所有技能。事实上,我们在 Triplebyte 经常看到很多优秀且成功的软件工程师具备完全不同的技能。那么,进行一次成功的面试的第一步就是决定对于面试的职位来说什么技能是重要的。我建议你问自己以下问题(这些是我们在 Triplebyte 开始为新合作的公司招募人才时会提出的问题)。

  • 你需要的是能快速进行开发和迭代的程序员,还是小心仔细、思维严谨的程序员?

  • 你想要的是对解决技术问题有兴趣的人,还是对开发产品有兴趣的人?

  • 你需要的是已经掌握特定技术的人,还是允许聪明的程序员在工作中学习这一技术?

  • 学术方面的计算机软件、数学、算法能力是重要还是无关紧要?

  • 理解并发、C 内存模型、HTTP 重要吗?

以上问题并没有正确答案。我们所合作的成功的公司给出的答案两种皆有。最重要的是要依据自身的需求做决定。需要避免随机挑选面试问题(或让每个面试官自己决定)。当这种情况发生时,公司的工程文化可能会出现偏斜,即越来越多的工程师具有特定的技能或方法,但那些技能或方法对公司来说可能并不重要,而没有那些技能的工程师(但是拥有其他重要技能)却被拒绝了。

2. 提问时尽可能贴近实际工作

聘请专业的程序员是为了解决耗时数周甚至数月的庞大而涉及面甚广的问题。但面试官并没有数周或数月的时间来评估候选人。每个面试官通常只有 1 小时。因此,面试官转而考察候选人在一定压力下迅速解决小问题的能力。其实这并不是同一个技能。它是相关的(面试不是完全随机的),但并不完全相关。制定面试问题的目标就是最小化这种差异。

要达到这个目标需要使面试问题尽可能地贴近你想要候选人完成的工作(或你打算评估的技能)。例如,如果你关心的是后端编程,要求候选人开发一个简单的 API 端点然后添加功能会是一个更好的问题,而不应该要求他们解决 BFS 词链问题。如果你关心的是算法能力,要求候选人应用算法来解决问题(比如开发一个简单的搜索索引,可以基于二叉搜索树和哈希表,以提高删除性能)会是一个更好的问题,而不应该要求他们判断一个点是否包含在一个凹多边形中。让候选人在真实代码库中编码并调试通常都优于让候选人在白板上解决一个小问题。

也就是说,采用白板方式进行面试是存在争议的。作为面试官,我不在乎工程师是否记住了 Python 的 itertools 模块。我关心的是他们能不能思考如何使用迭代器来解决问题。通过让候选人在白板上解决问题,可以让他们暂时不用考虑语法是否正确,而是专注于逻辑。但我还是认为这个说法有问题,因为理由仍然不够充分。让候选人在计算机上编写代码同样可以获得所有的好处,只要告诉他们代码不需要运行即可(甚至更好,可以把它变成开卷的面试,并允许他们在谷歌上查找任何他们想要的信息)。

面试问题应该反映实际工作还需要注意一点,即面试问题不应该依赖于外部依赖包。例如,要求候选人使用 Ruby 编写一个简单的 Web 爬虫看上去似乎是一个很好的真实问题。然而,如果候选人需要安装 Nokogiri(一个 Ruby 解析库,安装过程可能会很痛苦),并且在本机扩展中苦苦挣扎了 30 分钟才搞定,这将变成一次可怕的面试。不仅浪费时间,而且会让候选人承受巨大的压力。

3. 提问时将问题拆分成多个部分,使之无法泄漏

面试提问时还有另一个很好的经验法则是避免提出可能“泄露”的问题,即避免提出候选人可以提前在 Glassdoor 上看到答案要点的问题,否则他们回答问题就过于轻松了。这显然能排除脑力衰退者或任何需要极高洞察力的问题。但远不止如此,这还意味着面试问题需要包含一系列相互依存的步骤,而不是单一的核心问题。另一种有用的考虑方式是问问自己应该如何帮助一个被问题卡住的候选人,并且以积极的印象结束面试。对于一个只有一个步骤的问题,如果你必须给予候选人大量的帮助,那么他们就不能通过面试。而在一个分成多个部分的问题上,你可以在其中一步给予帮助,候选人就可以在剩下其他部分完成得很好。

这不仅仅是因为你的面试问题可能会泄漏到 Glassdoor 上,而且(更重要的是),分成多个部分的问题不会包含那么多噪音。好的候选人也会因为太过紧张而被问题困住。面试官应该能够帮助他们并看到他们恢复到良好状态。基于候选人最近是否看到过类似的问题(可能只是无意看到),会给评估候选人解决一个编程逻辑块的能力引入很大的噪音。分成多个部分的问题可以消除部分噪音。同时也为候选人提供了一个机会以展示他们努力的过程。在一个步骤中做出的努力往往有助于他们解决后续步骤。这在实际工作中将成为一个重要的动力,而在面试过程中捕捉到这一点就能减少噪音。

举个例子,要求候选人在终端上实现游戏 Connect Four(包含一系列步骤)可能比要求候选人旋转一个矩阵(只有一个步骤,而有一些简单的窍门)更好。又比如说,实现 k 均值聚类(包含相互依存的多个步骤)可能比确定适配直方图的最大矩形更好。

4. 避免提太难的问题

如果候选人能很好地解决一个非常困难的问题,那么你可以得到和他的技能有关的很多信息。但是,由于问题太难,大多数候选人都无法很好的解决问题。那么问题的难度将严重影响预期能从这个问题获得的信息量。我们发现,面试中问题的最佳难度比大多数面试官认为的要容易得多。

这种影响由于面试候选人时存在的两个信号来源而被放大:即他们是否给出了一个问题的“正确”答案、他们得到答案的过程或容易程度。我们在 Triplebyte 已经收集了很多相关数据(根据候选人是否得到正确答案以及他们花费了多少努力对问题进行评分,然后衡量哪些评分能预测他们在公司中的表现)。我们发现这里有一个权衡问题。对于更难的问题,候选人的答案是否正确携带了大部分信号。相比之下,对于更容易的问题,更多信号来源于候选人解决问题的过程以及他们的努力程度。考虑到信号的两个来源,显然选择比较容易的问题更好。

我们现在遵循的经验法则是,面试官应该能在他们期望候选人花费的时间的 25% 的时间内解决问题。所以,如果我正在制定一个用于 1 小时面试的新问题,我希望我的同事(没有任何提示)能够在 15 分钟内回答这个问题。再配合前面所说的将问题分成多个部分且尽可能贴近实际工作,我们要得到最佳面试问题其实很简单。

需要声明的是,我并不认为为了提高通过率要降低门槛。我想说的是要提出简单的问题,然后在评估结果中包含候选人回答问题的过程。我认为提出的问题应该简单,但评判时需要相当严苛。这就是我们发现的可以优化信号的方法。它的另一个的好处就是对大部分候选人来说压力比较小。

举个例子,要求候选人开发一个简单的命令行界面,其命令用于存储和检索键值对(如果他们完成得很好,还可以添加更多功能)可能比要求候选人实现算术表达式的解析器更好。而一个涉及最常见的数据结构(列表、散列或者树)的问题可能比涉及跳跃表、树堆或其他晦涩的数据结构的问题更好。

5. 对每一个候选人提同样的问题

面试是为了对候选人进行比较。目标是将候选人分为能够为公司做出贡献的人以及不能为公司做出贡献的人(如果只有一个职位空缺,则选择最适合的人)。鉴于此,向不同候选人提出不同的问题将难以做出判断。如果以不同的方式评估同一工作的不同候选人,则会引入噪音。

我认为,以特别的方式选择问题之所以常见,是因为面试官更喜欢这种方式。技术公司的工程师通常不喜欢面试。他们只是偶尔为之,而且面试会让他们无法专注于本职工作。为了规范对每个候选人提出的问题,面试官需要花更多的时间来学习问题,并讨论如何评分和交付。每次更换问题时,他们都需要重复这一过程。另外,总是问同样的问题难免会有些乏味。

不幸的是,这里唯一的解决方法就是面试官付出努力。一致性是进行成功的面试的关键,这意味着要对每个候选人提出相同的问题,并规范交付。别无选择。

6. 考虑进行多个版本的面试

考虑提供几个完全不同版本的面试,看似与我前面的观点相冲突。设计面试的第一步是考虑该职位需要什么技能。但是,其中部分答案可能会发生冲突!例如,需要一些真正的数学工程师,以及一些非常有创造性或能做到快速迭代的工程师(这甚至可能是对同一个角色的要求),都是非常常见的。在这种情况下,就要考虑提供多个版本的面试。关键是要有足够大的规模以便对每个版本都进行完全标准化。这正是 Triplebyte 正在做的事情。我们发现,你完全可以直接询问每个候选人他们想要进行哪种类型的面试。

7. 不要因证书或资质产生偏见

证书和资质并非毫无意义。从麻省理工学院或斯坦福大学毕业的工程师,或在 Google 和苹果公司工作过的工程师,总体来说,确实比其他的工程师更优秀。问题是绝大多数的工程师(包括我自己)既不是从这些名校毕业的,也未曾在这些名企工作过。所以如果一家公司过于依赖这些信息,他们会错过绝大多数技能符合要求的申请人。在筛选步骤中结合证书和资质进行筛选有其合理性。但我们在 Triplebyte 不会这样做(我们进行所有评估时都是 100% 盲背景的)。但若对筛选有意义,也会为证书和资质增加一些权重。

然而,让证书和资质影响最终面试决定则毫无意义。我们有数据表明确实存在这种情况。对于在我们的盲背景流程中表现出同样水平的候选人,其中拥有顶级名校学位的候选人相比那些没有名牌高校履历的候选人通过面试的比例高出 30%。如果面试官知道候选人具有麻省理工学院的学位,他们更愿意原谅候选人在面试中表现欠佳的地方。

这就是噪音,面试时应尽量避免。最简单的方法就是将学校和公司的名称从简历中删除,再交给面试官。部分候选人可能会在面试中提到他们的学校或公司,但是当我们在不了解候选人背景的情况下进行所有面试,候选人在技术评估过程中提到学校或公司的情况实际上非常罕见。

8. 避免让面试陷入阴霾

面试失败最糟糕的方式之一就是陷入阴霾。面试不仅仅是在评估候选人的技能,也是团队在考虑是否接纳一个新成员。从后者来看,面试可能会成为一个加入仪式。面试确实压力很大也很可怕,但是如果我们都这样想那么候选人也会这样想。当候选人表现得不好时,这种情况还会加重。作为面试官,看到一个候选人无法解决问题时可能会非常沮丧,尤其当答案看起来如此明显的时候!你可能会短暂地觉得生气和沮丧,当然,这只会令申请人徒增压力。

这是你应该极力避免的情况。解决办法是探讨这个问题并对面试官进行培训。我们会用的一个窍门是,当候选人确实表现得很差时,从评估模式转向教学模式,前者的目标是评估候选人,而后者的目标则是让候选人理解问题的答案。切换模式将大有助益。当你处于教学模式时,就没有任何理由拒绝提供信息或者表现得不友好。

9. 做决定时基于技能的长板而非平均水平或短板

到目前为止,我只谈到单个面试问题,还没谈到最后的面试决定。对于这一点,我的建议是尝试根据候选人表现出来的各项技能的长板(涵盖所有你所关心的技能领域)来做出决策,而不是各项技能的平均水平或短板。

或许你已经有意无意地在这么做了。决定录用还是不录用的方式是每个面试了候选人的人聚在一起开会,如果至少有一个人强烈要求录用,而且没有人强烈反对,就可以给出录用要约。要让至少一位面试官强烈地支持录用,候选人需要在面试的某一环节表现良好。从我们的数据来看,最强技能一般是与公司面试中至少一个环节最相关的特性。然而,要得到录用要约,候选人还需要没有人强烈地反对录用。如果候选人在某个问题上表现得特别愚蠢,就可能会被一票否决。

我们在这个环节发现了很多噪音。成为一名技术纯熟的工程师有很多不同的途径,但几乎没有候选人可以掌握所有技能。这意味着如果你提出正确的(或错误的)问题,任何工程师都可能看起来很愚蠢。只有当候选人在至少一次面试中显示出某一领域的长处(最强技能),而且在其他领域没有明显的弱点时,才会得到录用要约。但问题是这中间是存在噪音的。同一个工程师可能因为在网络相关问题上看起来很蠢而没能通过面试,也可能因为这个话题没有出现而出色地通过了其他的面试。

我认为最好的解决方案是公司专注于最强技能,并且对于在面试某些部分表现不太好的人也可以适当地提出录用要约。即寻找强有力的理由说同意,而不过多担心候选人偏弱的技术领域。我不想说得过于绝对。总有一些技术领域对于公司而言是至关重要的。决定你想要的公司文化,使团队中的每个人都在某一技术领域具备一定水平也是有道理的。但更多地关注最强技能可以降低面试的噪音。

到底为什么要面试?

我要解答的最后一个问题是——到底为什么要面试?我相信有一些读者一直在咬牙切齿地说:“为什么要为了一个混乱不堪的系统考虑这么多呢?就采取可带回家完成的编程项目或者试用的方法就可以了吧!”毕竟,确实有一些非常成功的公司就是采取试用的方法(让候选人加入团队工作一个星期),或者采取可带回家完成的编程项目完全取代了面谈。试用的方法确实是很有意义的。与工程师一起工作一个星期(或者观察他们如何完成一个实际项目)肯定比在一个小时内观察他们如何解决面试问题能更好地衡量他们的能力。然而,仍存在两个问题使试用无法取代标准面试:

  1. 对公司来说采取试用的方法成本过高。没有公司能够为每个申请人都花费一整周的时间。为了决定让谁来参加试用,公司必须先采取一些其他的面试方法。

  2. 候选人的试用(和大型的可带回家完成的编程项目)对候选人来说代价同样昂贵。即使公司会支付薪水,也不是所有的候选人都有足够的时间。例如,已经拥有全职工作的工程师可能就没办法抽出时间。即使可以抽出时间,也还是有许多人不愿意这么做。如果工程师手上已经有了一些工作机会,那么他们就不太愿意承担试用的不确定性。我们在 Triplebyte 的候选人身上清楚地看到了这一点。许多优秀的候选人(手上已经有了其他工作机会)一般会直接拒绝大型项目或试用考察。

综上所述,试用对于一些候选人来说确实是最佳选择。我认为如果公司有足够的能力可以支持多种面试方法,新增一个试用的方法不失为一个好主意。然而,完全取代面谈是不可行的。

也有人提出跟候选人谈论过去的经验来取代技术面试。如果想知道候选人是否能在未来做好工作,就去看他们过去的工作完成情况,这个逻辑倒也说得通。我们也在 Triplebyte 对这一点进行了试验,可惜并没有得到很好的结果。沟通能力(展现自己的能力)最终会掩盖技术能力。口才好的人会夸大他们的角色(将整个团队的工作视为自己的功劳),而谦虚的人则会淡化他们所做的事情,这种情况非常常见。花更多的时间、提更多的问题,或许还是能够挖掘出真实情况。但是,我们认为在通常面试的时限内,谈论过去的经验并不能取代技术面试。这是一种与候选人消除陌生感并了解他们的兴趣的好方法(同时可以评估沟通能力或者文化适应度),但是并不是一个可行的面试替代方案。

编程技术面试的好处!

我想以更积极的方式结束这篇文章。对于面试中存在的所有问题,很多是确有其事。

面试是直接对技能进行评估。我有一个朋友是教师,他告诉我,教师面试基本上考察的是沟通能力(表现自己的能力)和证书资质。对很多专业来说似乎都是如此。硅谷还未能做到完全任人唯贤。但是至少我们尝试直接评估重要技能,并且认为任何具备这些技能的人(无论背景如何)都可以成为优秀的工程师。证书资质带来的偏见往往阻碍了这一点。但是,在 Triplebyte 我们已经尽可能克服这个问题,并帮助很多背景并不优秀的人获得了很好的技术工作。当然,我认为 Triplebyte 在某些领域可能无法做到这一点,例如法律领域。因为这些领域对证书资质的要求太高了。

程序员也会选择面试。虽然这是一个非常有争议的话题(肯定有程序员不这么觉得),我们进行了一项实验,向候选人提出不同评估类型供他们选择,发现大多数程序员仍然选择了常规的面试。我们发现只有少数程序员对采取试用或可带回家完成的项目的公司感兴趣。无论未来会如何变化,目前技术面试仍是主流。其他类型的评估可以作为很好的补充,但似乎不太可能取代面谈而成为评估工程师的主要方式。这里不恰当地引用丘吉尔的一句话:“面试是对工程师进行评估的最差方法,除非你已经尝试了无数次其他的方法。”

写在最后

面试很难。人类简直复杂到令人绝望。从某种程度来说,通过四个小时的面试判断一个人的能力真是一件愚蠢的差事。我认为我们不得不对此保持谦虚的态度。任何面试都注定要失败很多次,因为人实在太复杂了。

但这并不意味着要放弃。尝试使面试过程变得更好总好过什么也不去尝试。在 Triplebyte,面试就是我们的产品。我们集思广益提出想法,测试这些想法,并随着时间的推移不断改进。我认为这才是改进雇用工程师的过程应该采取的方式。

附录:

[1] 这篇文章仅针对技术技能评估。后续我会发表与文化适应、行为面试和非技术评估有关的文章。

[2] 当然这并不绝对。有的公司要求所有面试官都非匿名给出肯定答复才决定录用,还有的公司由招聘经理全权负责作决定。

[3] 这些数字来自公司对内部候选人的报告。不同公司之间的数量差别很大(例如,他们报告的解雇率最低 1%,最高则有 30%)。通过 Triplebyte 申请的候选人的数字明显更好。到目前为止,通过我们申请的候选人在公司面试后有 53% 得到了工作机会,只有 2% 被解雇。

原文链接:

http://blog.triplebyte.com/how-to-interview-engineers

今日荐文

点击下方图片即可阅读

gRPC 服务端创建和调用原理解析


  
 
InfoQ 更多文章 诱人却非万能,理性看待Serverless的落地 gRPC 服务端创建和调用原理解析 大神们的大学生涯:无限挂科的PHP大神,放羊长成的白帽子传奇,以及繁多不可胜举之故事 普通程序员学习 AI 的简易指南 Q新闻丨2017开发者生态报告:Java最火,Go 最有前途;关于Go 2的讨论;《我的世界》中国版私用开源
猜您喜欢 致未来,致媒体同行 编写你的第一个sublime插件 MYSQL事务-隔离级别 凛冬将至,O2O的用户体验,你得这么做! 人工智能的应用:如何打破“有多少人工,才有多少智能”的魔咒(1)