「8000字攻略」如何创建有效的技术面试流程

【导读】成功的技术面试需要三根支柱:TCP,Tool(工具)+Challenge(问题)+Process(流程)。服务全球100多个国家、数千家企业的全球知名技术面试平台——HackerRank经过对平台上著名企业和顶级工程师实操案例的分析,针对技术面试流程梳理出了一份详尽的实践指南。八哥君(小编)吐血翻译,全网独家,粉丝专供!

步骤一:在你开始动手做之前

“问题并不重要。首先重要的是清楚地明白你想要什么。” Interview Kickstart CEO Soham Mehta 说。花80%的时间想清楚你要什么,再用20%的时间设计面试中要给候选人出的问题。

思考能力和技术经验是优秀工程师两项最重要的核心价值。算法方面的问题最适合考察思维能力,而技术经验则要通过知识性的或者基于工具的问题。

但是大多数管理人员没有意识到,最好是将上述两个维度的考察分开来进行。在相同时间段同时评估这两方面素质会有带来很多的限制,进而缩小你候选人的可选范围。那怎样才能知道你的需求是什么呢?这很大程度上取决于你的公司规模。

A.挑选聪明的高级工程师

像Google和Facebook这样的大公司,他们在面试中所问的算法和数据结构方面的问题不太有名。如果你有比较大的团队,候选人思考能力的重要性要高过技术经验。因为你可能拥有很多高级工程师来培训资历尚浅的新人。毕竟那些聪明的人才会非常快地学会具体技术。

这是被一项有85年历史的组织研究理论所支撑的:“认知能力(或智力、思考能力)测试是对各个领域的成功进行预测的最好方式。”算法问题,比如说问二叉树问题,在编程领域就相当于是认知能力的测试,因为它们评估的是推理、问题解决能力和批判性思考技能。

有意思的是像简历上的文凭,包括教育程度、年龄(或经验)和学习成绩等则是最差的预测指标。

有人可能会争论说,基础性的问题更适合于新人或者说年轻的工程师,毕竟他们的经验尚浅。不过我的意思是,如果是一个资深的工程师,怎么可能在他所处的位置上还需要用到二叉树呢?McDowell, Mehta和其他我们所认识的技术经理几乎都强调,要考察高级工程师的基础性问题是基于两方面的原因:

如果算法问题是对初级工程师的认知能力的标准测试,那么你需要对高级工程师也要一视同仁。否则,你的团队当中既有聪明的初级工程师,也有不那么聪明的高级工程师。

Sonos的开发主管David Taylor喜欢问资深一些的工程师关于数据结构和算法的问题,他说因为“如果候选人避开这些问题,你就要打一个大大的问号。”这是一个淘汰掉那些自认为厉害到不愿卷起袖子亲自干并且不断心态归零的家伙们的方法。

B.寻找有经验的人才

小规模的公司,很可能关注实战的经验胜过认知能力的优劣,因为他们等不起招那些资深的工程师来临时学习项目所需要的技术。通过设计便于反映技术经验的问题,能够帮你招到能够在入职第一天就可以着手开发一个新应用的人。所以,如果你是一个名不见经传的初创公司,你最好把注意力发在构思非常具体的问题上。

步骤二:设计有效的问题

在步骤1当中,我们已经指出你需要评估哪一方面是你更看重的:思考能力还是技术经验?现在我们将讨论设计相关问题的关键。一般来讲,我们发现有三个方面的技术能力你需要考察候选人:

  1. 他(或她)的基本功是否扎实?
  2. 技术经验积累的深度如何?
  3. 对问题的思考深度如何?

前两个问题可能都不需要通过代码面试就能评估。第三个问题最好是亲自来沟通。这也是这份指引最长的部分,因为我们提供了每类问题相关的具体案例以及企业最容易犯的错误。

设计算法问题
有个问题需要立即进行确认:候选人会编程吗?这看起来像是个废话。但是 ,多年来,那些著名的工程师不断指出:“相当多数所谓的程序员在进行代码面试时却不能写出最简单的一行代码。”Jeff Atwood说。他是业内非常有名的程序员,也是Stack Overflow的联合创始人。你可以让他们来解决一个基本的代码问题来进行筛选。你的第一个问题可能像下面这道题一样简单:
01.给定N个不同的数字,您可以形成多少个子集?
答案:2^N
02.给定长度为N的字符串,该字符串存在多少个排列?
答案:N!, 或者 N x (N-1) x (N-2) … x 1

多项选择题
多项选择题对于候选人来讲比较简单和容易。提供一组问题,每个问题都有多个选项,减少随机勾选就能选对答案的可能性。

下面是一个考察经验的多项选择题:
下面哪一项正确描述了载入程序?
A.加载程序使在活动或片段中同步加载数据变得容易。
B.加载程序使在活动或片段中异步加载数据变得容易。
C.加载程序使在活动或片段中异步加载数据变得不容易。
D.以上皆不是。

下面是针对算法的多项选择题:
在具有n个元素的二进制搜索树中搜索元素所需的时间为:
A.0(1)
B.0(log2n)
C.0(n)
D.0(n log2 n)

代码补全
代码补全是另外一种对候选人进行初步考察的简便方法。代码补全是指候选人需要把一段有空白的代码补充完整。一些最出色的程序员会花费花费非常多的时间来看源代码。你可以提供代码给候选人,留出一些空白让他完成,这对他来讲比较有趣,在此过程中又可以考察他的批判性思考和审查别人代码的能力。

另外,代码补全是一种趣事儿。我们最近针对平台社群里的成员发起了一个代码补全的系列挑战赛。这是迄今我们组织的活动当中参与度最高的一个。你可以找一些代码补全的问题作为自己设计类似问题的参考。

设计考察代码经验的问题
与基础性的算法问题不同,针对编程经验的问题会更直接,因为它们依赖于某个特定领域或技术的经验。举例来讲,关于客户端服务器、多线程和Sockets的问题对于评估候选人对分布式系统的熟悉程度是很有效的。
思考能力是预测人才未来的成功最好的指标,但是针对新手和专家有一个明显的不同之处。

设计考察思考深度的问题
这与经验的长短无关,而是你对问题的思考有多深。Taylor 认为那些领导过大型项目,比如:服务器、应用或者框架的工程师才能算作专家。因为有了这些领导经验以及方法,专家相比于新手能够在更高的层面以直觉看待问题,这是被科学方法所证实的。Dreyfus & Dreyfus(德雷福斯兄弟)分析了技能水平与心智运作之间的关系:

新手:“新手根据明显的规则和知识基础来行动。他们需要深思熟虑地分析,行动比较迟缓,因为需要决策或者选择。”
专家:“专家则根据成熟的、全局性的理解来行动,是通过直觉而不再需要有意识的深入思考。这是由经验产生效果,他们不会把问题和解决方案分开孤立来看,而是直接采取行动。”

另外一个激动人心的发现是通过功能性核磁共振(fMRI)测量艺术家中的新手和专家大脑中的血液流动情况。实验结果与我们之前看到的一致:
新手:在处理事物特征(浅层次)的大脑区域处理加工信息。
专家:在处理深度意义的大脑区域加工信息。

“艺术家思考画作,而不是简单观察它们。”
你是怎样来考察候选人思考深度的?你如何来来判断 工程师是思考软件而不仅是在观察代码?前面两类问题(算法和经验)可以通过直接的问题来自动考察,但是关于思考深度的评估只能亲自来进行。你可以从简单的问题出发,逐步设计出复杂到你自己难以解答的问题。

下面有两种类型的问题可以便于你评估思考的深度:

A.开放式的问题:
如果一组候选人都通过了技术问题的考察,你可以问有关开发的整体策略方面的问题以评估他们的思考深度。Taylor发现像类似下面的问题比较有效:
“告诉我你曾经做过哪些对项目产生重大并且积极影响的事情,你是如何思考和规划的。又有哪些产生了负面的影响?”
“我发现错误容易发生在技术人员径直地去思考如何开发一个东西而不是思考什么是应该开发的与(站在用户角度)思考如果产品成功应该是什么样子的时候。”他说。
还有一些针对经验深浅和领导力的开放性问题的例子:
1.你会怎样来开发Gmail的搜索功能?
2.告诉一些你曾经看过或用过的烂代码的例子?
3.你怎么来评估你的代码可以放到生产环境了?

B.把你的问题分拆为多个部分:
Josh Tyler,在Coures Hero负责开发,最近出版一本书叫《创建卓越的软件工程团队》。他认为针对高级工程师设计问题时,最有效的方法是问题的表述要有足够多的空间来深度挖掘候选人的思考过程。例如,这里是一个典型的优化问题:
“给您许多单词,并且您必须找到每个单词的频率。在这里,简单的映射、数组、列表将不起作用。相反,您应该使用Trie,这里是一种有效的数据结构。”Greg Badros,Prepared Mind Innovations的创始人,他会把问题拆分成如下几个部分:

  1. 告诉候选人你会从简单的开始,逐渐提出更复杂的问题;
  2. 询问单词的频率;
  3. 确定他们在没有写代码的情况下获得简单的映射解决方案;
  4. 告诉他们会拥有多少内存(RAM)以及数据库有多大;
  5. 叫他们估算一下根据他们使用的语言需要多少时间来完成;
  6. 如果时间会过长,让他们替换新的存储效率更高的数据结构,否则他们的内存会不够用;
  7. 当他们超出设计构想时,请让他们尽可能地写代码。

问题清单
截至到目前,我们一直在讨论的是根据你的需求会涉及的不同问题类型。现在我们开始解决具体如何设计问题。我们查询了不同公司的比较成功的代码面试问题,梳理出核心的模式出来。基于这些模式,归纳出以下五个常见的需要规避的错误,以确保每个问题都能很好的评估候选人:

1.你有正确的答案吗?

这个问题似乎有点脑残。但是当你知道有多少公司的代码面试问题是错误的时候肯定会很惊讶。McDowell经常给不同规模的企业提供招聘流程咨询服务,“我收到的企业题库中,有10%的答案是错的。”他说。背后的原因不是因为粗心大意或者是在输入答案时出了一点小bug。问题的设计者执意认为他们的算法是正确的直到他们被证明是错误的。花点时间确认你的答案是百分之百正确的。然后,你的注意力可以转向下一个。

2.你的算法问题足够有挑战吗?

对于算法问题,McDowell测算如果有5%的候选人很快就有了解决方案,那意味着过于简单了。面对既有一般又有优秀的候选人,简单的问题很难将后者筛选出来。你的问题需要有足够的难度以将拔尖的人才挑选出来。

在算法类代码面试当中,你应当保证至少有一个问题只有20%的候选人能够很好地解答。一个好的算法问题至少有两个及以上的解决方案。其中一个是最优的。结果会将候选人的表现分出三个层次:

第一层(Tier 1):最优秀的那部分候选人会拿出正确并且出色的解决方案通过所有测评。
第二层 (Tier 2):中等资质的候选人会解答大部分的问题,其中一个算法问题的答案正确,但解法可能比较普通。他们的代码可以正确地运行,不过大多数情况下时间不够用。
第三层 (Tier 3 ):那部分连一道算法问题都没有解出的候选人你肯定是不愿意要的。如果你使用了一个类似HackerRank的平台,你可以有足够的时间完成一个测试评估,当然是在综合考虑逐步增加的难度和较少限制的前提下。并非所有的评估都要有时间的约束。这取决于作为问题设计者的你评估时效是不是重要的指标。

3.问题的表述是否具体同时又体现了你公司的特点?

问题的表述越是贴近你的行业并且具体,越是有可能吸引到能够通过代码面试的高质量候选人。

对此我们做了一项实验,对比两个公司同样类型的问题,不过一个的表述比较笼统,另一个则很具体。我们发现后者面试问题的完成率要高出前者10%。更有趣的是,我们不断看到这样类似的相关性。相比于笼统的、冷冰冰的问题,候选人对围绕他们的任务来设计的问题更感兴趣。

例如,VMware创建了非常具体又复杂的问题库并可视化。你会逻辑中心控制器(Logical Hub Controller)问题与他们日常在处理的典型虚拟数据中心问题。将针对性的代码面试替代简历后两年,VMware发现:
每个季度都会节省工程师数百个小时的时间,这些时间仅仅是花在电话通知候选人已经通过代码考察上面;相比于手工筛选简历,邀约候选人参加现场面试的成功率也得到提升。

对问题进行恰当表述的工作可能比较艰巨,但对于高级工程师来讲,这可能是个如何表达的挑战。一个工程师如果能够很好拆分问题和解决细化后的问题并把这两个步骤有机整合在一起,那么他很可能成为你的组织当中一个成功的管理者。

对于任何一个高级工程师来讲,能够拆分问题、找到模式同时系统性地攻破问题都是关键并且高阶的能力。在我们的经验当中,非常聚焦而又具体的问题可能会有比较低的完成率,但是却有非常高的招聘成功率。这一现象与前面的章节(“设计考察思考深度的问题”)有关。

4.你排除掉了运气或偏见了吗?

如果一个候选人在解答问题过程当中被卡主了,那么他们是运气不好吗?区分这些因素(实力or运气?)是很重要的,最好的办法就是获取多样性的数据点。操作办法是,在问题中设置不同的障碍,候选人在其中一个点上卡住了,你可以帮助他越过去,然后他们任然可以有其他的路径来解决问题(后面你还可以利用其他点的来进行评估)。

举个例子,考虑如下问题:
给你一组人群,有他们出生和死亡的时间(年份),请计算出人口最多时是哪一年。这个问题会有一打的解法,每一种都会包含一个新的挑战:

第1个障碍:会来自任何任何一个正确解法。大多数的候选人会想出一种暴力算法(例如,每一年当中活着的人,接触并数遍所有在那一年活着的人),但是有一些不会这样做。如果碰上这样的候选人,给他们提供一点帮助,看看这个是否只是他们在推理过程中的短暂失误还是连续性的行为。

第2个障碍:候选人可能会注意到其实没有必要重复计算每一年。你可以使用哈希表缓存这个数据。

第3个障碍:可能会意识到你只需计算第一个出生的年份和最后一个死亡的年份之间的年数。候选人可能会首先获取那个信息,然后核算这些年数的值。

第4个障碍:事实上你只需计算第一个出生年份至最后一个出生年份。你没有必要计算只有人死亡的年份,因为这些年份肯定不会出现人口的峰值。

5.你确定去除掉了所有的计算机科学行话或术语?

我们继续讨论,直到得出一个最优解决方案。极其优秀的候选人可能会一次性越过前几个障碍得出解法,这会是一个非常好的预兆。提出类似包含有多重障碍的问题,你可以更有效发现候选人的表现是否有一个模式。

为了实现好的评估,你可以找你的同事进行事先测试。在发送给候选人之前让至少2至3个工程师来实际解决这些问题。这可以帮助你问题中包含了哪些障碍,以及你希望候选人有什么样的表现。

要成为一个优秀的程序员得先有个计算机科学的学位,这是普遍存在的误区。事实上,在一份调查中显示只有40%的在职工程师拥有计算机科学的学位。在我们撰写这些内容的期间,在一次TechCrunch的活动上,Wavefront CEO Sam Pullara 告诉我们,他同意这点。尤其是高级工程师很有可能对计算机科学教材的术语不熟悉。所以,要避免使用类似“state machine”或“dependency injection”这样的术语。因此,为了避免将那些没有上过计算机科学的课(或者已经记不得课程内容)的高级工程师候选人淘汰掉,要尽量少用那些包含了晦涩算法知识的问题。

步骤三:设定期望,让候选人活跃起来

在步骤1之中,你厘清了自己的需求并且设计出可以帮到你筛选出能够助你开疆拓土的工程师的问题。现在你应该聚焦在执行面试流程最重要的部分,那就是有技巧地与候选人沟通。

高级工程师喜欢有挑战的,而不是无聊和浪费时间的问题。事实上,有几把刷子的工程师会对那种冷冰冰的面试邀约邮件嗤之以鼻,因为需要花上他1到2个小时去完成一个之前闻所未闻的公司菜鸟级代码面试。这是可以理解的,他们何苦呢?可能昨天晚上还在为一个正在(以这样或那样方式)改变我们世界的软件加班到很晚。一个随意设计和发送的自动化面试会被视作一种侮辱。因此在设计和发送面试邀约的过程中充分融入同理心是非常重要的。

如果面试邮件没有很好的作解释以及说明候选人为什么会被邀约,那肯定会被一个高级工程师给忽略的。那些在不断扩大招聘规模的同时还努力让候选人感觉被重视的企业,才会赢得人才争夺战。避免出现类似的问题需要注意以下几点:

要非常清楚你想问什么和想得到什么。不要让候选人感觉你很唐突。这是确保不会把优秀的人才拒之门外很重要的一步。例如,你需要给候选人讲明白你不会随机选用那些在工作中用不着的问题来进行测试。反过来,类似二叉树问题则可以考察候选人解决问题和批判性思维的能力。如果你发送的是没有解释和准备的代码面试问题,你的面试工具会变成一种干瘪瘪的知识测验。你肯定会因此冒犯资深的工程师。

评估面试的可能时长(一般在45分钟到90分钟之间),然后给候选人充足的时间来完成它。把面试的时长告诉候选人,说明面试不超过一个小时,你会有足够的时间来进行面试。这样可以简单传递一个信息,你了解候选人非常忙,他们的时间是宝贵的,因此不需要特别仓促地答题。

向候选人解释为什么要这样做。例如,如果代码面试替代了简历或者是前期的电话面试,告诉他们:“进行代码面试意味着你不需要花更多时间和不同的工程师进行电话面试。”

我们对大量的代码面试题做了快速分析,发现相当比例的候选人没有基本的计算机科学知识。大多数高级工程师并没有立即去学习计算机科学知识。首先,在一项研究中,近60%的在职软件工程师没有计算机科学专业的背景;其次,即使他们有,也会因为时间太久而回忆不起那些在现实世界中无用的知识。

步骤四:面试结束后的评估

在步骤1~3中,你了解了如何针对你想招聘的工程师来设计出最合适的问题。但是当需要以不同的问题来考察不同的候选人时,怎样的代码面试问题才是好的?保持一致性会让你收集到的信息有意义。

Memelli 发现,招聘企业经常在候选人进入下一轮面试时改变了之前设定的问题,从而把收集到信息破坏了。在完成前期的面试之后,需要把代码面试的问题和接下来的面试需要考察的内容结合起来考虑。这是符合常理的——成功通过了线上的自动化代码面试的候选人很可能在现场面试中也表现得很好。自动化的代码面试是预测谁会在现场面试中表现得好的最好方法。
尝试选择之前在现场面试问过的问题,以观察候选人会如何反应。这也可以帮助你把问题的表述设计得更合适。当然,这意味着在后面的现场面试中,需要把这些问题剔除掉。“所以,尽可能地把代码面试的问题和现场面试的问题结合起来考虑。”

在面试过程中让资深的工程师解答基础性的问题可能会令其恼怒。简单粗暴地给候选人发送面试邀约也会这样。但是自动化的代码面试是最客观、有效地批量筛选候选人的方式。不仅考察候选人的思考能力,同时还通过算法和数据结构方面的问题评估他们对基本功的重视,是寻找最优秀的工程师的有力工具。

如果你设定好期望并意识到资深工程师可能有傲慢的复杂心态,你就可能会接触到优秀的资深工程师候选人。你也要创建一套可复制的系统来组建和扩大工程师团队。通过精心设计并且创建成体系的,可以考察基本功、技术经验和思考深度的题库,可以淘汰掉你原本寄希望于他来开发革命性的软件产品但却无奈缺乏基本技能的候选人。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShowMeBug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值