良好的招聘流程抵万金,本文中就来和你探讨下如何设计招聘流程,以及聪明的雇主应该避免哪些做法。
以下为译文:
在论坛Reddit的/r/ programming板块上,有200多万名成员。其中大多数帖子只是一些评论,热门的帖子有多达100-200条的评论。但是搜索“面试”(interview),你会看到更多的帖子。
许多开发人员都很反感编程测试,上面的所有文章都对于应聘软件工程师时必须进行编程测试的现状感到悲痛,没有任何一个人敢站出来为这种做法辩护。
但在本文中,我打算讨论一下如下方面:
编程测试的必要性;列举一些最好避免的常见做法;解释为什么面试中总是会出现一些毫无意义的算法题,而不是“真正的”编程。在我的职业生涯中,我面试过300多位开发人员,而且还设计了现在公司的主要面试流程,所以我觉得在这个主题上我还有一些话语权。我们的团队每天都会面试开发人员,良好的招聘流程抵万金,所以本文并不是教你如何设计招聘流程,本文只想探讨一些候选人厌烦的做法(而且他们的这种情绪合情合理)以及聪明的雇主应该避免哪些做法。
首先,我们公司如何招聘?目前为了构建以开源比特币为基础的分散式数据库,我们正在全球各地招聘各个技术岗位的人员。首先,在开发人员的面试过程中,我们会要求你快速审核一段代码(大约5分钟),接下来是30-60分钟的视频面试+屏幕共享,你可以从自己家中接受面试,并用你喜欢的编辑器和语言编写一段代码,最后是面对面的面试——与团队和高级管理层的面试。有时编程测试还包括设计和“探讨”问题,具体取决于候选人的背景以及工作岗位:这部分的面试不仅仅是编程。我们认为这套流程非常奏效,而且效率很高(至少与某些招聘流程相比!)。
注意:本文中提到的问题都不是我们会在实际中提问的问题,只是想给你一个大致的印象。
首先,让我们来看看面试中应该避免哪些方面。
面试官应该避免哪些方面虽然有些公司会在招聘流程中采用如下方式,但我不建议这样做:
“机器人面试”与自动评估。没有人喜欢成为一名面试官,所以很多团队希望将招聘的工作外包出去。但是我们非常简短地尝试了一下这种做法,结果证明这种方法根本无法与人为的评估相提并论,更重要的是,要求候选人参加面试时尊重他们宝贵的时间是一种基本的礼貌。我感觉要求候选人拿出时间来参加面试,而公司却没有付出相同的时间,这本身就是不尊重对方。面试官花一个小时与候选人面试,表明他们非常重视对方和自己的时间。通过“面试考题”网络应用自动化不可靠的面试,只会让你付出另一种代价。我们感觉高级工程师都会(肯定会)拒绝做这种面试。
白板面试。虽然多年来这种做法被广泛采用,但是如今笔记本电脑和屏幕共享无处不在。更为自然的编程是在编辑器上,通过键盘,并借助搜索引擎和编译器。通过视频通话的面试可以让候选人使用自己的工具,在家中使用自己的计算机进行编程。远好过站在一个小小的会议室里,让某人用白板笔写代码。一整天的面试。许多公司希望对开发人员进行一整天的面试,通常需要5-8次单独的面试,这对于有工作的开发人员来说太难了。相反,利用午休时间进行远程的面试,就不需要候选人请假了,所以他们更有可能完成整个过程。我个人认为,8次面试也不一定会比两次面试的结果更好。大规模的编程任务。虽然最近我们也开始要求候选人先做一个简单的编程任务,但是这个任务不涉及编写任何代码,可以在几分钟内完成。我听说有些公司要求考生在面试时间之外,写真正的一套代码。同样,这也不尊重对方的时间,很多人会拒绝这样做。
临场提问。设计提问的问题很困难,你希望候选人做好准备,不是吗?因此,你也应该做好准备。修改真正的bug或实现真正的功能。显而易见如果候选人没有授权的话,你会陷入版权的问题,除此之外你也没办法重复这个任务,没办法确保问题总是合时宜,也没办法确保你可以看到良好的编程技巧的范围(例如,该功能可能只需要复制/粘贴一些现有代码,然后做轻微的改动)。而且你只是为了现有的Java代码库而招聘Java开发人员,或为现有的Ruby代码库而招聘Ruby开发人员:如果你雇佣熟练的开发人员,让他们在工作中学习工具,那么这种面试就没有任何效果。上面是招聘中应该避免的一些方面,但在实际的面试中,我们还是应该让开发人员现场编程。下面让我们来谈谈为什么这个要求虽然不受欢迎,却很普遍。
许多候选人不喜欢编程测试。有人蒙混过关,还有由于面试题设计糟糕而引发大量误解,从而导致候选人愤恨不平。没有人喜欢因为刻板的面试过程而导致他们无法展现自己真正的技术力。
Google:90%的工程师在使用我写的软件,但我却因没能在白板上解出一道二叉树的问题而被拒。
明明知道自己可以胜任,却惨遭拒绝的经历会给心理带来沉重的阴影,特别是当面试的过程宣称很科学很准确的情况下。
因此,不采用这种面试方式,而采用比较传统的谈论以往经验的公司可能会占据优势。然而,从微软等公司流行起来的编程测试已经成为了普及度很高的标准,而且现在很少有软件公司可以仅凭电话面试就下offer。这是为什么?
编程测试的必要性看着实习生鼓起勇气参加第一次编程测试,我总是觉得很有趣。首先是亮晶晶的大眼睛,无辜震惊的表情,然后咆哮。
候选人怎么可能用一种语言开始编码,中途才发现他们不了解这种语言,应该用另一种语言从头重新开始呢?在简历中写明有10年经验的人怎么可能不会用自己的编辑器建立一个新项目呢?候选人怎么可能花30分钟生成随机数,却以失败告终呢?这太不可思议了!
经历过这些历史时刻的前辈笑了,他们会告诉你:“并非不可思议。让我给你讲个故事吧……”
在20世纪90年代,微软推出了科技行业的结构化面试,该流程就是著名的脑筋急转弯“为什么下水道的井盖是圆的?”以及编程难题,例如“在白板上用C语言反转链接列表”。Joel Spolsky根据微软的流程撰写了一篇关于这种面试形式的文章“软件人员面试教战守则”(的小公司。
Joel Spolsky反思微软推动的世界趋势。这是非结构化面试的一大进步,但他并没有满足于此。不幸的是,他提议的替代方案是适用于招聘实习生。
但我认为,Imran Gohry提出的FizzBuzz问题(在他的博文中说:
任何事都有个开始。但令我感到不解和震惊的是,所谓的程序员申请工作的时候,却无法编写最简单的程序。对于那些以软件为生的人而言,这无疑是一记响亮的耳光。
Dan Kegel是一位曾与我在Google以及在Wine项目中共事的受人尊敬的同事。2006年,他在“如何招聘”一文中说:
大多数申请人,即使是那些拥有硕士学位和计算机科学博士学位的申请人,在面试中编写基本的程序时也会失败。例如,我在面试中遇到过的毕业生答不出:“写一个从1到10的循环”或“用十六进制表示F后面的数字是多少”等问题。
负责面试的开发者们很容易把这些故事写的很夸张,因为这样可以显得他们比接受面试的人更强。我想在这里澄清事实并非如此,每个负责组建团队的人很快就会习惯那些非常善于面试却连最简单的程序都写不出的人。
人们普遍认为,公司之所以会进行编程测试,是因为他们喜欢迷恋算法的书呆子,他们想找到最具学术精神的候选人,并希望成为下一个Google。然而事实并非如此。各个公司之所以会进行编程测试,是因为他们遇到过许多面试候选人纸上谈兵的本领很强,但却无法按照要求编写出程序。完全不行。
如果你是一名求职者,那么做到下列几项就可以让你脱颖而出:
如果你懂一门编程语言,那么就在面试中使用这门语言。我猜在简历中写明懂C++的候选人中,有50%都拒绝在面试的时候编写程序(但是他们愿意使用更简单的语言)。掌握开发工具。如果你是Java开发人员,那么就应该知道如何在你选择的IDE中创建新项目,编写一些代码,运行代码,然后展示程序创建的输出。你还应该知道如何编写和运行测试,以及使用调试器。如果对方要求你带自己的工具参加面试,那么就照做。不要在面试的过程中安装东西。掌握基础知识:集合、输入输出、字符串操作、循环、数据类型。如果你是一名优秀的程序员,那么就知道实际应该掌握哪些知识(我面试过的Scala程序员在面对一个非常明显的问题时全军覆灭。)掌握你打算在面试中使用的语言。不要因语法或类型安全的普通错误而陷入困境。如果你觉得上述都很基本,那么就欢迎来开发人员面试的世界来看看吧。
编程测试很重要的原因还有一个。技术娴熟的工程师都明白这个问题,而且他们不想加入一个随便什么人都能进的团队。强大的招聘流程不仅仅是候选人给面试官留下好印象的机会,而且也是候选人感受面试官的机会。有些与我合作过的优秀人才之所以被他们的工作吸引就是因为面试非常有难度。在效率、漏掉优秀的人才以及有人蒙混过关之间寻求平衡是构建软件公司的艺术。
尽管如此,大多数从候选人的角度写的糟糕的面试故事其实都不是来自那些面试失败的人。大多数人对编程测试感到恼火,是因为他们觉得他们在面试中需要解决繁琐且没有意义的怪问题。
为什么算法问题必不可少?编写排序函数,反转二叉树,图搜索。
求职面试让人感觉又重回了大学。这么多年来实际编程的经验突然间都被抛到脑后,就好象你再次坐在演讲厅里,证明你对理论课程的掌握,实际上这些问题已经早就让那些喜欢阅读高德纳的开发人员解决了。
我在讨论区见到的最常见的解释就是老板是白痴。其次最常见的解释是,老板们都希望成为Google,而Google确实需要计算机科学专家,而其他公司都不需要。但无论如何,这些公司都采用了Google的招聘流程,并希望借此成为亿万富翁。
其实,真正的理由很简单。当你坐下来为开发人员撰写面试问题时,你必须满足许多限制才能写出一个好问题。而满足所有这些限制的问题最后往往都看起来像“算法”问题。
面试的目的是尽快获取候选人的信息。一个好的面试问题并不一定要代表日常工作。为了解释清楚这一点,想象一下飞行员的面试。在有了基本的了解之后,理应询问候选人在各种紧急情况下该做什么。紧急情况并不代表飞行的日常工作,但安全很重要,因此没有人会指责面试官提出无关紧要的问题。然而,在软件面试中却出现了这样的问题。
既然我们的目标是尽快获取候选人的信息,那么我们的限制是什么?
首先,要完成的程序必须短小精悍。除非你想整个面试就问一个问题,否则这个问题应该是一个称职的开发人员在30分钟内完成的问题。30分钟你根本写不了多少代码。这重限制已经排除了大多数能带来实用价值的“真实”程序。
其次,这个程序必须单独完成,没有复杂的设置或网站特定的知识。花费在解释问题上的时间每多一秒,候选人展示技术力的时间就少一秒。有时我看到网上论坛里有人评论说:“这个公司是傻X,他们使用的是标准的商业网络应用程序,却不让我写REST API,非要让我编写自己的排序函数。”但是编写一个“写一个REST API”形式的问题,并通过这个问题实际验证候选人能否成功通过面试,这项工作非常困难。这个API应该干些什么?数据从哪里来?你是希望连接到某个数据库,还是通过文件提供数据,抑或者将其保存在内存中?等等。理想情况下,面试的问题应该在30秒以内解释清楚。有些公司确实会提这样的问题,但他们只想招聘懂得特定选择框架的开发人员,而且该框架已经自动完成了所有的样板代码。但在我们公司,我们想招聘各种背景和专业的开发人员,因此我们必须坚持在没有任何特定框架或技术的情况下,仍然可以照常回答的问题。
第三,这种方法实际上可以表现出候选人是否懂得编程。编写几个返回一些假HTML的函数不能证明什么,但至少证明候选人可以使用循环、集合、类、以及输入输出,还熟悉他们的标准库(我的意思是大致了解编程技术,而不是说他们记住了每个API)。
第四,这种方法可以给优秀的候选人提供脱颖而出的机会。上述我提到的基础看起来可能非常基础。但这并不意味着我们公司的门槛很低。一个良好的编程测试问题需要掌握一定的深度,让优秀的候选人可以快速高效地创建一个比新手更好的解决方案。面试官通过了充分的练习,即使每个人面对的都是同一组问题,他们也知道如何区分经验丰富的开发人员和初学者。
最后,你需要一些证据,证明候选人可以解决一个没有明显解决方案的问题,让他们自行思考答案,而不是手足无措。这类问题的具体性质并不重要,只需保证候选人无法用以前见过的方法解决。这是面试过程中最模糊的部分:这对测试候选人的思维能力有什么真正的意义?这也是排除“利用他人的代码解决我的问题”的方法,尽管这常常是实际工作中的正确方法。
简短、易于解释、仅使用基本语言功能,解决方案既可以是最基本的,也可以有一定的深度,而且还不至于千篇一律。我认为所有这些都是招聘到一个称职的团队成员的基础问题,但是满足这些条件的问题必然最后会成为没有代表性的算法难题。这些问题的目的不是想要考察你是否真的记得计算机科学课程中晦涩难懂的算法(你可能永远也不会在实际工作中使用),而只是为了让你编写一些包含大部分基础知识的代码的契机。
所以不要过于关注你的答案是否具有理想的计算复杂性,至少在第一次尝试中没必要。面试官可能并不在意。相反,你应该快速出色地编写干净且没有bug的代码。然后,如果有多余的时间的话,再去优化。
总结由于缺乏全球认可的认证机构以及对具体技术技能的需求,招聘开发人员的过程比某些专业更为严格。
多年来,从雇主的角度来看,招聘的流程已经得到了极大的改善。对于那些习惯于这种面试的候选人来说,这种方式可以招聘到更均衡的团队,避免有人滥竽充数,尽管有关这种方式的抱怨也很普遍。
尽管如此,我依然看到无论我们在该行业中付出多大的努力,招聘仍然具有很大程度的随机性。经过精心设计的面试流程可以改善这种随机性,这也是我们的努力方向。但是,鉴于解雇一个不合格的人的成本之高,漏掉优秀的人才总好过让人蒙混过关,因此才有了这些面试的悲惨故事:一些有真正实力的人才因为机械的流程而被拒。正如Spolsky提出的面试实习生的替代方案一样,尽管这种流程存在各种缺陷,但也是一个无人能及的系统。
原文:
本文为 CSDN 翻译,转载请注明来源出处。
想要在程序员生涯内有更高的成就的话,C/C++就是一个既可以强化思维能力,又可以打好编程基础的编程语言,将来想要做软件开发,有一份好的前景的话,学习C/C++的话笔者有一个C/C++的编程俩千人羣(Q艘索:C/C++编程学习13)群,你如果感觉自学C/C++语言有困难的话,有兴趣学习或者了解一下C/C++编程的小伙伴就可以进来交流。