作为候选人,最重要的是要记住:45 分钟的编码面试并不能准确评估你是否会胜任这份工作。 高错误否定比率意味着你绝不应该为被拒绝而感到难过。拒绝通常只意味着在一个人工设定的、时间紧迫的环境中,你需要更多练习来展示你已具备的技术能力。
“我们有 90% 的工程师在用你写的软件,但你不能在白板上写出反转二叉树的代码实现,所以你被拒了!”
Homebrew 的创始人 Max Howell 在 2015 年的这条推特吐槽了谷歌的编码面试,收到了 1 万多个赞,引发了热烈的讨论。但是一直到 2019 年的现在,编码面试仍然在互联网面试中占据重要地位,一直被吐槽,从未被动摇。本文作者曾是一名经历编码面试被拒的候选人,后来又成为了一名 Facebook 的编码面试官,他在文中分享了这种视角的变化,深入分析了编码面试占据重要地位的原因和一些改进的想法。
你很紧张。电话面试即将开始。这可能是你今年获得理想工作的唯一机会。这一切都归结为一点 —— 你要在 45 分钟内证明你解决问题的能力和编码水平。
电话突然响起。
你接起电话,只能听到心跳的声音。在简短的寒暄之后,面试官将第一个问题粘贴到你的共享编码环境中,并开始解释问题。
你的大脑一片空白。你太紧张了,在巨大压力下你无法清晰地思考。
你不停地看表。5 分钟过去了。
沉默。
你知道面试官一直在等你说些什么。你试图用你的想法打破沉默,但这只会破坏你的思考过程。你又看了看表。20 分钟过去了。
你很惊慌,不知不觉面试官说时间到了,你有机会向他们提问。
你的心情很低落。
你没有机会进入下一阶段。但你还是心不在焉地提了几个问题。
通话结束,几天后你收到一封拒绝的邮件。
理性上,我知道我已经足够好了。但经历过几次这种可怕过程之后,我开始失去信心。
我可以告诉自己,我比大多数人更懂得如何编写代码。我已经搭建了多年的网站和应用程序,其中一些被成千上万的人使用。我以良好的成绩获得了牛津大学的计算机科学学位。但在感性上,一连串被拒绝的痛苦仍然困扰着我。
我把这种痛苦转化为擅长编码面试的决心。我买了一块白板、一些马克笔和一本《程序员面试金典(Cracking the Coding Interview)》。
几周后,我完成了书中所有的题目。对于每一个问题,我都在白板上写出代码,并且说出我的思考过程,然后把代码输入到笔记本电脑的 IDE 中。我写了一些测试用例来保证我的解决方案是有效的。我也看了书后的参考答案。对于我犯的每一个错误,从小的语法错误到算法使用错误,我都把它记录在文档里。在开始下一个问题之前,我会复习所有的错误。
下一轮面试进展顺利。我收到了多个 offer 并决定加入一个伦敦科技创业公司——Improbable。
在 Improbable 工作了一年后,出于各种原因我决定再找一份工作。我不得不再次进行编码面试,但距离上次训练已经有一段时间了,所以我需要更多练习。我对 LeetCode 和 HackerRank 上的题目重复了同样的过程。LeetCode 高级订阅提供了一个巨大的题库,里面的题目按提问的公司分类,并且按提问频次排序。这种方式非常好,我可以把精力集中在最常见的问题上。
在这轮面试之后,我收到了 Facebook 的 offer。
我现在已经在 Facebook 工作两年多了,发现自己变成了在手机另一端面试其他候选人的角色。我经常看到候选人不能克服自己的紧张情绪,犯下和我相同的错误。我知道这不能代表他们作为软件工程师的能力,也不是衡量他们未来工作表现的一个特别好的指标。
那我们为什么还要这么做呢
对我来说,我在工作中表现是否良好并没有因为我学习并通过编码面试而改变。但是我能够学习和通过编码面试的事实证明了我拥有工作所需的原始技能。
如果有人可以通过编码面试,他们很有可能拥有在工作中取得成功的技术技能 —— 他们将会是一个很好的员工。如果有人没有通过编码面试,他们仍然很有可能成为一名出色的雇员。
让我们再进一步分析一下。本质上讲,面试是一种从候选人中提取信号的方法,这些信号可以预测他们是否会在工作中取得成功。像任何涉及分类的预测任务一样,预测结果有时是正确的,有时候是错误的。
当你和候选人时间有限时,你可以提取的信号是有限的,你的评估准确性会降低并且会犯更多错误。
当你错误地认为某人是一个出色的员工时,这是一个错误的肯定。当你错误地认为某人是一个糟糕的员工时,这是一个错误的否定。
事实上,对于公司而言,错误的肯定是比错误的否定的问题要大得多。招聘错误的人的成本非常高,新员工最初是公司的净损失,因为他们必须经历昂贵的入职上手期,这段时间他们不仅没有生产力,而且还会占用其他人的时间,与此同时仍然要拿着报酬。如果新手期过后,你必须要解雇候选人,你将永远收不回这项成本。如果由于该国的就业法律很难解雇员工,那么成本还会飚升。
另一方面,拒绝一个好的候选人的成本非常低。随着优秀候选人数量的增加,拒绝一个好的候选人的成本会更低。
在任何二元分类任务中,都有错误肯定比率和错误否定比率。你可以更改分类阈值,预测某人为肯定而非否定的阈值,以优化这些比率。
在这个情况中,
- 错误肯定的比率是:(你招聘的不良候选人数)/(你招聘的人数)
- 错误否定比率是:(你拒绝的合格候选人数)/(你拒绝的人数)
当你提高阈值(雇用要求)时,你以增加错误否定比率为代价来降低错误肯定比率。这意味着那些拥有大量求职者并在新员工中投入大量资金的公司更倾向于提高他们的门槛。
这个系统通常对公司很合适,这就是它没有一直没怎么变化的原因。但它对候选人个体就不太合适了,单个候选人只是求职者大池中的一个分子,在这个系统中运气变得很重要。
由于面试表现与工作表现并不完全相关,因此经常会发生公司拒绝的那些候选人,比他们招聘的人能更加胜任这份工作。
编码面试的情况尤其如此。在解决传统编码问题方面花费更多时间的候选人可能更有优势,而他们在现实世界中解决真实问题的经验比较少。
看看 Homebrew 的创始人 Max Howell 的这条推特:
如何改进系统呢?
面试的目的是从候选人那里提取足够的信号,以预测他们是否能够胜任工作。如果你有完全准确的预测,你可以招聘到所有胜任本工作岗位的人,这对公司和候选人来说都很完美。
一种几乎完全准确的方法是在一段固定的时间内给候选人一份工作,如果他们成功了,就给他们提供一份永久的工作。这就是实习,延长版的面试。问题是这对公司来说是一项风险投资。这就是为什么实习机会也依赖于编码面试。
实际上,公司从候选人那里获取信号的时间和资源有限。候选人通常只有有限的时间进行面试。在这些时间限制内,公司希望收集作为软件工程师成功所必需的几个关键信号。
作为一名面试官,我希望看到候选人掌握基础的数据结构和算法知识。通过讨论其他方法和利弊权衡,他们可以利用这些知识为问题提出算法解决方案。我希望看到他们用编程语言编写解决方案代码,解释时间和空间的复杂度,走查他们的代码并予以测试。
因此,如果你只有 45 分钟,这种编码面试的普遍形式确实是有意义的。
改进编码面试
话虽如此,白板是不必要的。如果你没有在白板上编码过,你会感觉有点奇怪并且被干扰。因此,如果候选人更喜欢使用键盘,公司应该让他们用键盘。你不会想因为候选人不喜欢在白板上编码而拒绝他们的。
作为面试官,另一件要改进的事是选择问题。最好不要选择在一些数学或计算机狭窄领域中的问题,同时这些问题还需要重大的创造性思维或特定领域知识才能解决。理想情况下,候选人应该能够逻辑推理并逐步迭代得出最佳解决方案。你不会想因为候选人在 45 分钟的面试中没有灵机一动得出答案而拒绝他们的。
最后,让候选人放松是很重要的。当你的思维在竞争和压力之下时,很难做到合乎逻辑有条不紊。通过几个他们过去最喜欢的项目的快速问题进行面试,可以很好地平息候选人的紧张情绪。你不会希望因为候选人发现时间紧迫、编码压力很大导致没发挥出应有水平而拒绝一个候选人。
但除此之外,如果不放开时间限制,很难提高面试信号的准确性。
获得更多信号
一些公司会请候选人把一个任务带回家来做,以消除时间压力,并会设想一个更复杂的编码问题,以提供更多的信号。
有些公司会通过多个阶段的面试来收集更多信号,所以期望候选人能休几天假来进行面试。
有些公司会进行更多种类的面试,测试更多实用技能,例如浏览大型代码库或者构建与某些公共 API 交互的 React 前端程序。
虽然这些方法提供了更好的信号,让公司向优秀候选人提供更多 offer,但也需要占用候选人的很多时间,这会使面试经历不太愉快。问题是,如果候选人一次申请多家公司,而每个公司都有极其耗时的面试流程,那根本就不可行。
面试即服务
对此的一个解决方案是统一多个公司的编码面试流程。独立的编码面试服务可以比任何一家公司花费多 5-10 倍的时间面试候选人,让他们能够更清楚地了解候选人的技术能力,减少错误否定比率,同时保持很低的错误肯定比率。这将为候选人提供更有效更愉快的体验,因为他们可以避免在多个公司重复相同的面试过程并且避免依靠运气。这样可以释放公司的资源,使公司专注于最终的非技术性面试,如团队和文化契合度面试。像 Triplebyte 这样的公司已经在努力尝试这一做法。但他们似乎更多地将其用于筛选,而不是完全取代技术面试。
我认为用更准确、统一和独立的版本替换大公司自己的技术面试流程的主要挑战是获得他们对流程的信任,同时允许在评估特定技术技能和应聘水平方面进行定制。
最后的想法
作为候选人,最重要的是要记住:45 分钟的编码面试并不能准确评估你是否会胜任这份工作。 高错误否定比率意味着你绝不应该为被拒绝而感到难过。拒绝通常只意味着在一个人工设定的、时间紧迫的环境中,你需要更多练习来展示你已具备的技术能力。