Java程序员

面试 900 多位工程师后总结了这些经验

2018-08-16  本文已影响111人  Java架构技术分享

我们在 Triplebyte上进行过很多场面试,实际上,我在过去的几年面试的工程师已经达到 900 余人,这到底算不算卓有成效还真是不好说!(有时我会冒着一身冷汗从梦中惊醒,对这一点充满质疑)。但是不管怎样,我们目标是改进应聘工程师的方式。为此,我们面试时不看求职者的背景,不在乎他们的文凭或简历,只关注他们的编程能力。一个工程师通过了我们这一关后,能直接到我们的合作方公司(包括 Apple、Facebook、Dropbox 和 Stripe)进行终面。我们面试时不知道应聘者的背景,这种情况下看他们是如何在众多顶尖科技公司前大展身手的,我觉得可以给我们的面试提供一些最佳的可用资料。

伯乐在线补注:Triplebyte 是国外一家专注工程师招聘的网站。

在这篇博客中,我要讲讲迄今为止我从这些资料中所学到的东西。技术面试在很多方面都是漏洞百出的,这一点口头说说很简单(而且许多博客都只是这样说说而已!),难的是想出实际的解决方法。我写这篇博客就是为了迎接这个挑战,并为招聘经理和 CTO 提供一些具体的建议。面试这件事有难度,但我想只要遵循一套缜密的流程,那么许多问题都会迎刃而解。

现状

大多数的面试过程主要包括两步:

简历筛选

面试

对求职者的筛选就是为了提前淘汰一些求职申请者,节省面试工作的时间。通常筛选过程包括:招聘官大体浏览求职申请者的简历(大概用时 10 秒以内),然后进行 30~60 分钟的电话面试。我们的合作方公司中有 18% 的公司为了考验求职者,也会出编程题让他们回家完成(要么代替电话面试,要么作为电话面试以外的附加题)。有意思的是,绝大多数的求职申请者都是在筛选这一关被拒的。真是这样,我们合作的所有公司中,单纯因为简历就被筛掉的求职申请者已超过了 50%,另外有 30% 因为电话面试/带回家的项目完成不佳而被刷掉。筛选也是聘用过程最变化无常捉摸不定的环节,应聘者太多,导致招聘人员应接不暇,只能做出仓促的决定,因此这时候求职者的文凭资历和专业匹配度就派上了用场。

终面几乎普遍都是由一系列 45 分钟到 1 小时的会谈组成,每次会谈的面试官都不一样,会谈主要考技术题(每个公司外加一两个针对文化适应和软技能的问题)。招聘经理和每个面试官会在求职申请者离开后,在决策会议上做出他们最终录用/淘汰的决定。在至少有一人力挺,且没人强烈反对的情况下,一个求职申请者才可能被录用。

终面除了常见的形式之外,还有各种千变万化的类型。

我们合作的公司中,39% 会使用白板面试。

有 52% 允许求职者使用他们自己的电脑作答(剩下的 9% 视情况而定)。

有 55% 让面试官随意提问(剩下的 45% 采用一套标准面试题)。

有 40% 要考察求职者的 CS 学术技能后,才能确定去或留。

有 15% 不喜欢 CS 学术技能(而且觉得探讨计算机科学只能暴露该求职者生产力低)。

有 80% 允许求职申请者在面试时使用任何编程语言(剩下的20%要求他们使用特定编程语言)。

有 5% 会在面试过程中直白地评价求职者编程语言的细节。

放眼所有与我们合作的公司,终面后决定录用的占 22%。(这个数据是通过询问公司内部招聘渠道获得的。Triplebyte 上的求职者通过公司面试被录用的成功率为 53%。)其中大概 65% 会接受 offer(达成雇佣关系)。一年后,公司对录用了 30%、开除率 5% 的情况非常满意。

漏招 VS 误招

所以,现在的面试存在什么问题呢?毕竟开除员工的频率并非是不可控的。为了更清楚地看待这个问题,我们需要考虑导致面试失败的两种情况:

面试了一个不合格的工程师,却将其聘用,过后只好开除(误招);

面试了一个工作能力很强的工程师,却认为他不合格,选择不予聘用(漏招)。

误招一眼就能看出来,公司会(在薪水、管理成本和全团队的精神面貌上)付出很大代价,会把一个团队搞得萎靡不振。而与之对比,漏招的损失却看不出来。虽然以上任意一种情况都很有问题,但由于这误招和漏招引发的后果乍一看很不平衡,所以公司的面试很大程度上倾向于不予聘用。

面试中存在的干扰会使公司不予聘用的倾向更加严重。在一小时内评估一个人的编程能力本来就是很难的,各种条件经历的匹配、某些直觉感受和以上谈到的公司的复杂喜好等因素掺杂进来,使得你在面试别人时被各种干扰团团围困。

为了在受干扰环境下把误招率控制在一个较低的水平,公司在招聘时越来越偏向于不予聘用。这样会错过优秀的工程师,会使文凭的重要程度高过实力,也会由于反复无常,使参与其中的人(面试官和求职者等)感到失望。假使你公司中的每个员工为了争取他们当前的职位都得重新参加面试,那么通过率能有多大呢?这个问题很骇人,几乎可以确定他们不可能都被录取。求职申请人会因为本有能力为公司好好效力却没被录用而神伤,公司也会因为找不到可用之才而遭受损失。

要澄清一点,我不是说公司应该降低面试的门槛,相反,面试招人正因为会有拒绝才存在的意义!我更不是说公司对误招的担忧远大过漏招是不对的,招错人要付出高昂代价,我想说的是:各种干扰信号的影响外加之对于误招的防范,会导致面试的漏招率大大攀升,导致人才流失。为解决这一问题,就需要改善面试环境

减少面试中干扰因素的具体方法

1.决定你想要招聘哪方面的技术人才

一个程序员不可能因为具备了哪一套技能就能被定义为优秀的程序员了,相反,世上的编程技能多得犹如汪洋大海,没有工程师能在所有的领域都游刃有余。实际上,我们在 Triplebyte上碰到过一些杰出、成功的软件工程师,他们在几个毫不相关的领域都颇有建树。面试成功的第一步就是决定你想要招聘哪方面的技术人才。我建议你问自己以下几个问题:

你想要的程序员是效率高,但写的代码不完善需反复修改的,还是一丝不苟、思维严密的?

你想要的程序员是热衷于解决技术难题的还是构建产品的?

你想要已经具备某种特定技能的人才还是在工作中有很强的学习能力的?

计算机科学学术/数学/算法方面的能力是至关重要的还是无关紧要的?

了解并发/ C内存模型/ HTTP 很重要吗?

这些问题没有正确答案,我们合作的成功企业对以上每个问题选任一方的都有。但关键是要根据自己的需求有针对性地做出选择,应该避免随便向求职者抛个面试问题了事(或者让每个面试官决定)。这样的话,公司的工程文化就会有一定倾向:淘汰掉越来越多虽然有一技之长但是对公司并没太大用处的、以及不具备公司所需技能(却具备其他重要技能)的工程师。

2.问尽可能和实际工作相贴切的问题

专业程序员的任务是花数周数月的时间解决大型的、错杂延展的问题,但是面试官并没有数周数月的时间去评估求职申请者的能力,通常每个面试官只有一个小时去考核,所以他们会转而去考察求职申请者在强压下迅速解决小问题的能力。这是两种不同的能力测试。二者有一定的相关性(面试并不完全随机),但并不是完全相关。制定面试问题的一大目标就是减少面试考察和实际工作的差异。

方法是在面试时向申请某一职位的求职者(或者为了衡量某一技能)问尽可能相似的问题。比如说,如果你关心后端编程,那就让求职申请者建一个简单的 API 端点,再添加特性,几乎可以肯定,这比让他们解决一个 BFS 词链问题有意义得多;如果你关心算法能力,那让求职者在问题中运用算法(比方说,建一个简单的搜索索引,可能使用 BST 和 hashmap,实现提升删除操作的性能),几乎可以肯定,这比让他们确定一点是否包含在一个凹多边形中有意义得多;让求职者在实际编程过程中去尝试调试程序,几乎可以肯定,这比让他们去解决一个白板上的小问题有意义得多。

即便如此,面试中要不要让程序员在白板上作答还是有争议的。作为面试官,我不在乎工程师是否记住了 Python 中的 itertools 模块,我在乎的是他们是否想通了如何用 itertools 模块去解决问题。通过让他们在白板上答题,他们便可以不用遵循严格的编程语法,而完全专注于逻辑问题。但最终白板答题的提议还是行不通,因为白板上答案的形式五花八门,没有那么多的评判标准可以对它们一一进行对错评判。所以让求职申请者们回归到电脑上编程,同时告诉他们不必真正去运行代码(或者采用更好的方法,进行开卷面试,让他们在 Google 上查询任何所需的信息),那么考察他们的目的就已经达到了。

面试问题应该对日后工作有所反应,对此要特别警告,面试不依赖于外部因素是至关重要的。比如说,让一个求职者用 Ruby 编写一个简单的爬虫看似是个很好的实际问题,但是,如果求职者为此需要先安装 Nokogiri (一个安装起来非常费劲的 Ruby 解析库),结果花了 30 分钟绞尽脑汁应对本地扩展,那么这次面试就糟透了,不仅浪费了时间,而且也让求职者一下子压力爆棚。

3.问不会提前泄露的多面性问题

另一个针对面试提问的经验之谈是避免提问有可能会“泄露”出去的问题。比如说,有些问题的某些信息可能求职申请者提前能从 Glassdoor 上读到,所以他们回答起来就会轻而易举,因此这类问题就要避免提问,否则求职者明显就不用动脑筋了,也抹杀了需要考验他们直觉洞察力的地方。而且除此之外,也意味着面试的问题应该由一系列相互承载的部分组成,而不是一个单一的中心。换种有用的方式去想,问问你自己,能不能在面试时帮助一个陷于困境的求职者,并让他在面试结束还能给大家留下一个不错的印象。对答案唯一的问题,如果你给求职申请者提供了明显的帮助,那么他就直接面临淘汰;而对于多面性的问题,你帮了求职申请者一步,那么他还有机会在其余部分大展身手,完美表现。

伯乐在线补注:Glassdoor 是国外一家做企业点评和职位搜索网站。

这一点很重要,不仅因为你的问题会在  Glassdoor 上泄露出来,而且(更重要的)是因为多面性的问题可以减少干扰。优秀的求职者会背负压力,陷于困境,面试时很重要的一点就是对他们提供帮助,从而让其好好发挥。考查他们解决任意小编程逻辑问题的能力时,他们最近一段时间是不是看到过、或可能只是恰巧碰到过类似的问题,会对考查造成明显干扰,而多面性的问题则可以消除一些干扰,也让求职者们有机会看到他们的努力像滚雪球一样越积越大。给他们提供一步的帮助,往往能帮他们解决紧接着的下一步,这给实际工作提供了重要动力,在面试时把握这一点就可以减少干扰。

举例来说,让一个求职者在终端实现“四子连珠”游戏(一系列多个步骤),可能要比让他去旋转矩阵(一个单独步骤,外加之一些小操作)要好得多;让求职者实现 k 均值聚类(建立在彼此之上的多个操作)可能要比找到直方图中的最大矩形(leetcode 的一道算法题)要好得多。

4.避免问很难的问题

如果求职者很好地解决了一个很难的问题,那能极大地证明他的能力,但也正因为这个问题很难,所以大多数求职者都无力招架。你想要获得的信息量就很大程度上依赖于问题的难度,我们发现面试问题最合适的难度要明显比大多数面试官所想的简单得多。

这一点影响更大,因为面试求职者时,获得的信息有两种来源:他们是否对一个问题给出了“正确的”答案、他们得出答案的过程/得出答案的容易程度。我们在 Triplebyte上收集了这方面的数据(同时给他们是否得出了正确答案和他们花费了多大努力这两项打分,然后衡量对公司而言哪个分数能更准确地对求职者能力进行预测)。我们发现这是一种权衡,对于更难的问题,求职者是否给出了正确的答案更能说明问题,相比之下,对于更简单的问题,求职者的答题过程和他们花费的努力程度则更有参考价值。考量了这两种信息来源后,面试问题最适宜的难度会往更加简单的方向偏移。

我们现在遵循的经验法则是,面试官解决问题所用的时间应该是他们希望求职申请者们解决问题所花时间的25%。所以如果我在为时1小时的面试中提出了一个新的问题,我希望我的同事(没有提醒的情况下)能在15分钟内解答。外加之我们应问实际环境下的多面性问题,这意味着最佳的面试问题真的是相当直白和简单的。

要澄清一点,我不是说要降低通过率的门槛。我支持问简单的问题,然后将他们回答的情况纳入考评范围;我支持问简单的问题,然后给予相当严苛的评判。这就是我们所找到的对面试环境进行优化的方式,这种方式额外产生的好处就是可以降低大部分求职者的面试压力。

举例来说,让一个求职者创建一个简单的命令行接口,要求存储和检索键值对(如果做得好的话就再增添功能),可能要比让他们为算数表达式实现解析器要好得多;面试问题包含最普通的数据结构(表、哈希、还可能有树)可能要比涉及跳表、二叉排序树或其他更模糊的数据结构要好得多。

5 向每个求职申请者问相同的问题

面试就要对各个求职申请者进行比较,我们的目标就是将他们分为能为公司奉献光与热的和不能奉献的(在大家申请同一职位的情况下,选出申请人中最优秀的一个)。鉴于此,就没有理由向不同的求职申请者问不同的问题。如果你对申请同一职位的不同求职申请者采用不同的方式进行评判,那么你就引入了干扰因素。

面试之所以一直都是当场选择问题,我觉得是因为面试官更喜欢这种方式。科技公司的工程师通常不喜欢面试别人,他们只是偶尔面试一下,面试会使他们偏离工作重点。为了将针对每个求职申请者的面试问题规范化,面试官们就需要花费更多的时间去学习如何制定面试问题,并且探讨面试打分、交接的方式。而且每次问题一发生变化,他们就需要重复以上过程。经常问同样的问题只是有些枯燥乏味而已。

不幸的是,面试成功唯一的正解就是面试官需要花费心力。保证一致性是实现良好面试的关键所在,也就是说向每个求职申请者问相同的问题,并且要确保交接标准化,除此之外别无他法。

6.考虑实行多重的面试方法

与我之前的观点相悖,这里我们可以考虑提供几种截然不同的面试方法。筹备面试时,我们首先应该考虑想要招哪种类型的技术人才,但是我们想要的人才特质可能是相矛盾的,这一点很常见,例如想要招非常有数学天分的工程师,和一些高产/重复性强的工程师(甚至可能是针对同一职位)。在这种情况下,考虑采用多重的面试方法,其中关键在于你要很大程度上保证每种面试方法都是完全规范化的,我们在 Triplebyte上就在这样做。我们发现你仅需问每个求职申请者他们所青睐的面试方法即可。

7.不要因为资历而小看别人

资历不是没用的,毕业于麻省理工或者斯坦福的,抑或在谷歌和苹果公司工作过的工程师组建的队伍确实要比没这些资历的工程师更加优秀,但问题是绝大多数工程师(包括我自己)都没有以上资历,所以如果一个公司对此过分看重,那他们就会错失大多数编程大牛。在筛选环节将申请人的资历纳入考量范围并非毫无道理。我们在 Triplebyte 上没这么做(我们的考评是100%不看背景的),但是在筛选时对申请人的资历做一定的参考可能会有用。

但是若让资历问题影响最终面试结果,那就没有道理了,数据表明这种情况确有发生。在我们不看背景进行考评的过程中,对于表现情况一定的求职申请者,那些简历上写有名校文凭的要在比没有名校文凭的人过关率高30%。如果面试官知道求职申请者手握麻省理工的文凭,那他们就更愿意原谅他们在面试环节暴露出来的一些瑕疵。

这就是你应该避免的干扰,最显而易见的解决方式就是在开始面试前直接跳过申请者简历上的学校和公司名,有些求职申请者可能会提到他们的学校或公司,但是我们的面试都不看申请者的背景,而且在进行技术考评时,申请者自己提背景的情况也是相当少见的。

8.避免羞辱

面试失败的最丑恶的一种情况,就是招聘人员表现出一种羞辱的态度。他们不仅是对求职者技能进行考评的人,而且也代表即将要纳入成员的一个组或一支团队,在第二种身份下,面试是迎接新成员的重要仪式。面试确实让人有压力,很恐怖,但我们都会背负面试压力,所以求职者也自然会有压力,尤其在求职者表现不佳时,面试压力会更加凸显出来。当面试官看到求职者对着答案看上去那么显而易见的问题,就是答不出来急得砸脑袋时,就会觉得大失所望,气不打一处来,同时又万分沮丧,这样无疑会让求职者压力更大,形成恶性循环。

一般这种情况面试官唯恐避之不及,为此应该展开探讨,并且对面试官进行培训。我们用的一个策略是,当求职者表现很差劲时,就将想要对其进行考评的评估模式切换成想要让其理解问题正解的教学模式。心理上的这种切换大有裨益,当你采用教学模式时,你就没有理由硬忍住不说答案了,也会变得完全亲和友善。

9.根据最高技能,而非平均或最低技能做录用决定

迄今为止,我只探讨过单独的问题,却没有谈过最终的面试决策。我的建议:在做录用决定时应看求职者(在你所关心的技能中)具备的最高水平技能,而非中等或最低水平技能。

无论是有意还是无意,你们好像就是这么做的。每个面试过求职者的面试官通过聚在一起开会,来制定最终的录用/淘汰决定。在至少有一人力挺,且没有人强烈反对的情况下,求职申请者就会被录用。要想让一人力挺,求职申请者就需要主攻面试的其中一个部分,大显身手。我们的数据显示,要在公司面试的至少其中一个部分表现优异,求职者具备的最高技能就是最紧密的影响因素了。然而,为了得到 offer,求职者也需要保证没有强烈反对的声音,而若回答问题时表现得非常愚蠢,那么就不会引发强烈的反对。

这里我们会发现大量的干扰,技术高明的工程师具备的能力各式各样,因而几乎不可能有求职者能驾驭所有技能。这就意味着如果你问了一个正确的(或错误的)问题,任何工程师都有可能出丑。那么求职者至少在一次面试中,体现了在一方面的优势(最高技能),且没有暴露在某些方面的明显劣势,才能获得 offer,而这里就有干扰出现。如同一个工程师在回答有关网络系统的面试问题时表现不好而遭到淘汰,但却在另一个面试中成绩优异,只因为面试没出网络系统的问题。

我认为最好的解决方法就是让公司专注于求职者的最高技能,同时对于面试中部分环节表现不佳的人也能通融给过。这就是说,寻找充分的理由去录用,而不要因为求职申请者在某些技术领域能力薄弱的而过分担心。我不想表现得过于绝对,当然有些领域对公司是至关重要的。而且对于企业文化,若团队中每个人在特定的领域都有特定的定位,那很可能大有裨益,但是将更多的注意力集中于最高技能着实可以减少面试中的干扰。

到底为什么要搞面试?

我应该回答的最后一个问题是为什么要搞面试?我确信有些读者已经咬牙切齿地问“对一个破败的系统想那么多干嘛?直接用带回家的项目进行考评不就行了!或者直接采取试用呗!”毕竟,一些非常成功的企业都会进行试用(求职者在团队中待一周),或者用带回家的项目取代当面面试。试用是很有意义的,几乎可以肯定的是,让他们花一周的时间跟在一个工程师旁边工作(或者看他们是如何完成一个实际的项目的),要比让他们回答1小时的面试问题更能反映能力。然而,有两个问题导致试用一直无法取代标准面试:

1.要进行试用的话,公司要承受高昂成本,没有公司能为每个求职申请者承担整整一周的试用花销。因而公司必须采用其他的面试环节来决定试用的人选。

2.试用(以及大型的带回家完成的项目)对求职者而言成本高昂,即使他们能获得报酬,那也未必有空参与。比如一个工程师的工作是全职的,就可能没法抽空干别的,而且就算能抽出时间,可能也不愿意。而且如果一个工程师已经获得了一些offer,那就不太可能再甘愿承受结果还充满不确定性的试用考验了,这一现象明显能从 Tripletype 上的求职者中看到。许多最优秀的求职申请者(拥有其他公司的offer)只是单纯不做大型项目或者不经受试用考验。

试用是一种选人的绝佳方式。我认为如果你有开展试用的经济实力,那么加上试用这种选人方式是很不错的。但要想让这取代技术面试,并不完全可行。

了解工程师过去的开发经历也可以成为取代技术面试的一种方式。逻辑上来看,通过了解他们过去的开发情况,就可以推知他们未来是否可以将工作干得得心应手。遗憾的是,我们在 Triplebyte 上实行此方法时,收效甚微。表达能力(推销自己的能力)强的到头来要比技术能力强的人更有胜算,巧舌如簧的工程师对自己的职能夸夸其谈(将整个团队的功劳独吞),谦虚谨慎的工程师却对自己的成绩轻描淡写,这样的现象屡见不鲜。如果有充分的时间和大量的问题去刨根究底,就有可能弄清楚真实情况,但是我们发现,常规面试时间有限,谈论过去的开发经历通常并不能取代技术面试。虽然谈过去经历有助于破冰,拉近和求职申请者间的关系,能够对他们的兴趣有所了解,(而且能从中评判求职者的表达能力,还有可能看出他和企业的的文化契合度),但要想让这取代技术面试,并不完全可行。

编程面试的好处!

我想让这篇博客以更加乐观的角度作结,无论面试存在多大的问题,但采用这种方法其实也有颇多好处。

面试是对申请者能力的直接评估,我有一些朋友是当老师的,他们告诉我教师面试基本上考察的是语言表达能力(推销自己的能力)和所具备的文凭资历,这一点似乎从很多职业中都能得到印证。硅谷没有非常完美的精英体制,但我们至少确实在设法对申请者应具备的重要能力进行直接衡量,并且秉持达观开放的思想,认为一个人无论背景如何,只要具备相应的能力,就能够成为非常优秀的工程师。对文凭资历的偏见会成为贯彻这种思想的阻力,但我们在 Triplebyte 上已经很大程度上克服了这种偏见,并帮助很多没有常规资历的人找到了很好的技术工作。我认为 Triplebyte 不太可能解决比如在法律层面的问题,因为社会对于求职者文凭资历实在是太重视了。

程序员同时也在选择面试形式。尽管这个话题颇有争议(当然有程序员对此持异议),但我们提供了各式各样不同的考评形式,通过试验,我们发现绝大多数的程序员还是会挑选常规的面试形式,仅有一小部分人会对公司采用试用或带回家的项目进行考评的形式更感兴趣。无论怎样,我们这里要说的是编程面试,其他形式的考评都能作为很好的补充备选,但看起来不太可能取代面试成为考评工程师的主要形式。不确切地套用丘吉尔的一句话:“面试是最差的一种考评工程师的方式,但它是我们迄今为止所能找到的最好的一种方式。”

结论

面试工作很难,无奈的是人类都是复杂的。从某种程度上来说,想要靠区区几小时的面试去评判一个人的能力,这是傻子才会干的事,因而我觉得保持谦逊的态度是至关重要的。任何面试在很多时候都注定会失败,只是因为人实在是太复杂了。

但这并不是说着我们应该放弃,试着将面试过程不断优化要比什么都不做好得多。在 Triplebyte 上,面试就是我们的产品,我们集体讨论,想出考评测试方法,进而随着时间的推移不断优化面试方式。我在这篇博客中分享了过去两年多学到的一些重点,期待反馈,想知道这些观点是否能够让大家受益。

上一篇下一篇

猜你喜欢

热点阅读