面试游击队员指南
by Joel Spolsky
Thursday, March 23, 2000
原文链接 http://www.joelonsoftware.com/articles/fog0000000073.html
对Fog Creek软件公司来说雇佣正确的人是极其重要的。在我们这领域,有三种类型的人。在尺度的一端,是平民,缺少最基本的编程常识。他们非常容易挑出来并且消除掉,一般只需要浏览下简历或者问2至3个问题。在另外一个极端,是充满智慧的超级明星,他们只是觉得有趣写个Lisp编译器,在周末,用掌上设备编译。然而在中层的,有大量的"可能者",他们看上去刚好能做出什么事情。这里的技巧只是区分超级明星和可能者,因为Fog Creek软件公司只雇佣超级明星。这里有一些做这个事情的技巧。
第一,第#1重要的标准:
聪明,和
能做事。
就这些,我们所有要找的东西就是这些。记住它。每天晚上睡觉前背诵它。我们的目标是雇佣有资质的人,而不是某一个技能。不管怎么说,每一个人带进工作的技能会在几年之内过时,因此最好雇佣一个有能力学习任何新技术的人而不是现在正好知道SQL语言的人。
聪明是很难去定义的,但是我们在面试时候问一些问题就能够分辨出来。能做事是决定性的。既聪明又不能做事的一般有博士学位,和在一个大公司工作过而且没有人听他们因为他们不切实际。他们会认真思考一些学术性的难题而不顾时间。这种人能分辨出来因为他们喜欢指出两种完全不相关的概念在理论上是相似的。举个例子,他们会说"电子表格实际上只是另外一种形式的编程语言"然后他们离开一个星期,写了一份令人震撼的,精彩的论文,关于电子表格作为编程语言的理论上的计算机语言特性。聪明,但是没有用。
能做事但是不够聪明的人会做出愚蠢的事情来,还对这种事情视而不见。其他人只好时候帮他们处理乱局。这使得他们成为公司的债务,因为他们没有做任何事情,还占用了其他人的时间。他们是那种人,会去大段大段的四处拷贝程序而不是自己写一个子程序,因为这能让他们把事情做完,只是不是用最聪明的方式。
面试中最重要的规则:
做决定
在面试的最后,你必须已经准备好对候选人做一个明确的决定。这里只有两种可能性:雇佣或者不雇佣。打开你的电脑立即给招聘人员发一个反馈。主题栏应该写上候选人的姓名。电子邮件的第一行应该是雇佣或者不雇佣。然后你可以花两个段落的长度说明自己的决定。
这里没有其他的答案。永远不要说,"雇佣,但是不要放在我的团队。"这是粗鲁的暗示那个候选人不够聪明和你一起工作,而可能足够聪明和其他小组的失败者一起工作。如果你发现你想要说"雇佣,但是不要放在我的团队,"只要简单的翻译成"不雇佣"就好了。即使你的候选者的才智能够做一部分工作,但是在另外一个小组就不会很好,那就不雇佣。情况变化如此频繁如此快我们需要员工在任何方面胜任。如果你发现一个白痴学者,他非常,非常,非常精通SQL但是完全没有能力学习其他东西,不要雇佣。这种人在Fog Creek没有未来。
永远不要说"也许,我分辨不出来"如果你不能分辨,那就意味着不要雇佣。这比你想象的要简单。不能分辨?只要说不行就可以了!同样的,如果你在犹豫,也就意味着不要雇佣。永远不要说,"好的,雇佣了,但是我有一点担心。。。"那也是说不雇佣。
一件重要的事情是记住面试是这样一件事情:拒绝一个优秀的候选者比接受一个糟糕的候选者要好很多。一个糟糕的候选者会花费大量的金钱和力气而浪费了其他人的时间去修复他的BUG。如果你有任何疑虑,不要雇佣。
当你主持面试的时候,不要为你拒绝太多的人而担心,Fog Creek不能找到可以雇佣的人。这不是你的问题。这是招聘人员的问题,是HR的问题,这是Joel的问题,绝不是你的问题。扪心自问以下哪种情况更糟-我们变成了很大,糟糕的软件公司还有很多椰子,或者我们保持又小又高质量?当然,寻找优秀的候选人是非常重要的,而且每个人都应该把寻找招募聪明的能做事的人作为自己的一部分任务。但是一旦你真的面试某些人,假装Fog Creek有足够优秀的候选人。永远不要降低你的标准,不管寻找真正优秀的候选人有多难。
你是怎么做如此困难的决定的?你只需要在面试期间不停问自己:这个人聪明吗?这个人能做事吗?为了能分辨,你将要问他一些问题。
只是取乐,这里有一些地球上最垃圾的问题:"varchar和Oracle 8i中的varchar2有什么不同?"这真是个糟糕的问题。这样不可能,也没有相关性能分辨出知道这琐碎的无用的细节和Fog Creek真正想雇佣的人。谁理这两者有什么区别?你可以在网上15秒就能找到。
实际上,还有比这个更垃圾的问题。我会在以后说。
现在我们到个有趣的环节:面试问题。我的面试题的列表来自我在微软的第一份工作。实际上有数百个有名的微软面试题。每个人都有一部分他们喜欢的问题。你也一样,会发展出一部分问题的集合和个人的面试风格,这会帮助你作出雇佣或者不雇佣的决定。这里有一些我以前用过的成功的技巧。
面试之前,我读一遍候选人的简历,在小纸上略记下面试的计划。这里只是一些我想问的问题的列表。这里是典型的面试程序员的计划:
1. 介绍
2. 询问候选人做过的项目
3. 不可能的问题
4. C函数
5. 你满意吗?
6. 设计题
7. 挑战
8. 你有问题吗?
在面试之前,我是非常,非常小心避免对某个候选者有先入为主的观念。如果在候选人进入房间之前就觉得这个人很聪明,那只是因为他有MIT的博士学位,然后接下来1个小时没有什么可以纠正初始的偏见。如果你认为他们是笨蛋,没有什么会克服初始的印象。一场面试像是一个非常,非常微妙的尺度-靠1小时的面试是非常难判断一个人的而且会觉得他们都差不多。但是如果你之前了解一点候选人,这就好像一个很重的物体放到了天平的一端,使得这次的面试作废。有一次,就在一次面试之前,一个招聘人员来到我的办公司。"你将会喜欢这个人,"她说。她的行为使我恼火。我那时候应该说,"好的,如果你这么肯定我将会喜欢这个人呢,你为什么不直接雇佣他而免得浪费我的时间去进行这次面试?"但是我那时候年轻而且幼稚,因此我还是面试了他。
当他说了一些不是很聪明的话,我对我自己说,"他肯定是一个例外"我透过玫瑰色的玻璃审查了他说的所有东西。我兴奋的认为可以雇佣即使他是一个令人讨厌的候选人。你知道吗?所有面试过他的人认为不雇佣他。因此:不要听招聘人员;不要向周围在面试之前打听候选人;还有永远不要与其他面试人员谈论候选人知道你自己独立做好了决定。这才是科学的方法。
面试人员介绍阶段是为了是候选人放松。我大约花30秒告诉他们我是怎么样的人和这次面试会怎么样。我总是使候选人知道我们关心的是他怎么样解决问题而不是他的答案。顺便说一下,在面试期间,你应该确定你们没有面对面坐在桌子两边。这样会制造阻隔使候选人紧张。最好把桌子移到靠着墙的位置,或者围绕着桌子坐在桌子的另一边;这样有助于候选人放松。这样的结果是有助于面试因为这可以减少紧张带来的影响。
第2部分是询问候选人最近做过的项目情况。如果是面试还在大学的孩子,问他们毕业设计,如果有的话,或者他们在某门课上做过的一个他们真正喜欢的大的项目。比如说,有时候我会问,"上个学期你上的什么课你最喜欢?这不一定要和计算机相关的。"实际上如果他们说了一个和计算机无关的课程我会很开心。有时候你看了他们的课程表,选择了一个学分最少的计算机科学课程,但是所有的选择都和音乐有关。然后他们告诉我他们最喜欢的课程是面向对象数据库。是的,这样也行。我更希望他们能直接承认相比与计算机他们更喜欢音乐,而不是拍我马屁。
当面试有工作经验的候选人,你可以和他谈谈他的前一份工作。
这下面的这些问题中,我只是在寻找一个东西:激情。当谈起他们最近做过的一个项目时,下面这些都是好的表现:
列表上的第三个事情是问不可能的问题。这很有意思。这样做的本意是问一些不可能有答案的问题,看他们能不能处理他。"Seattle有多少验光师?""Washington的山总共有多少重?""Los Angeles有多少加油站?""纽约有多少钢琴调音师?"
对于编程问题,我会要求候选人写一小段C函数。
下面是我经常会问的问题:
你不会给他们一个多于5行代码量的问题;你没有那么多的时间。
我们关注一下细节。#1:我有生以来的面试中每个人这道题第一次都做错了。毫无例外,他们都想去申请另外一个空间,然后反转字符串放到这个空间中。问题是,谁申请空间就要谁释放空间。我问题很多人这个问题,我发现了一个有趣的事实。大部分认为自己精通C的人其实完全不知道内存或者指针。他们就是不理解这些。我很惊讶这种人也能叫程序员。对于这个问题,下面有几种方法判断候选人:
对于#3,你可以理解他们对C语言的位运算符学的怎么样,但是这是一项技能,而不是资质,因此你可以在这方面帮助他们。有趣的地方是看他们写统计一个字节中所有位的子程序,然后要他们做的更好,程序能运行的更快。真正聪明的候选人会创造一个查找表(最终,这只需要256项),这个表只需要产生一次。和好的候选人一起,你可以有一场关于时间/空间权衡的有趣的交流。让他们做的更好:告诉他们你不想每次每次运行初始化的时候都要建造这一张查找表。聪明的候选人甚至会建议引进缓存机制,第一次计算一个字节的时候计算它,然后把结果存储到查找表中,等下次遇到相同的字节都不要计算了。真正,真正聪明的候选人会利用这个查找表的基本规律推导出计算这张表的方法。
当你观看某个人写代码的时候,这里有一些东西也许有用:
不可避免的,你会看到他们写的函数中存在BUG。因此我们进行到了第5个步骤:你对这些代码满意吗?你也许想问:"BUG在哪里?"这个是经典的开放式问题。所有的程序员都会犯错误,这并没有错,只是他们必须能找他它们。对于字符串函数,他们几乎总是忘记给新的字符串用null结尾。所有的函数,都会犯缓冲溢出的错误。他们会忘记用分号结尾。他们的函数对于0长度的字符串没用,或者当malloc失败的时候出现一般保护错误。一个候选人第一次就没有出现任何BUG,这是非常,非常少见的。在这一步骤中,这样的问题可能更有意思。当你说,"你的代码有BUG"他们会很认真的查看一下他们的代码,然后你就可以观察他们是否有足够的信心确定自己的代码是完美的。总体来说,进行下一步骤之前询问一下候选人时候对自己的回答满意是一个好主意。
第六部分:设计题。要求候选人设计一个东西。Excel的原始设计者,Jabe Blumenthal,喜欢叫候选人设计一座房子。根据Jabe,他曾经有过一个候选人直接站起来在白板上画了一个矩形。一个矩形!这个立即就这么干的人不要雇佣。在这一步骤,我们在寻找什么?
什么是#7带给我们的。挑战。这个很有意思。在面试期间,你可以寻找候选人说的绝对正确的地方。然后你说,"等一下,等一下,"然后花个两分钟唱反调。在你知道他们正确的情况下和他们争论。
无可否认的,在面试这种情况下,并不是和派对一样,候选人会害怕和你争论因为你在比他们强势的位置上。但是,优秀的候选人会保持在争论中公平的地位,他们会一度忘记现在正在面试,他们会非常投入的试着说服你。这些就是我们想要雇佣的人。
最后,你应该要问一下候选人他们是否有其他问题。有些人会想听到候选人问一些有才智的问题,像那些面试书中标准的问题。就我个人来说,我并不关心他们会问什么问题;到目前为止我已经作出决定了。候选人一天必须见5-6人,让他们一天问5-6个人不同的,有才智的问题很难,因此如果他们没有问题,没有关系。
我总是在面试的最后5分钟推销Fog Creek。这是非常重要的,即使你并不打算雇佣他们。如果你足够幸运找到了一个优秀的候选人,你也想做一些事情来确定他想要来Fog Creek工作。即使他们是糟糕的候选人,你也应该让他们对Fog Creek软件公司感到兴奋,因此可以给他们留下对公司正面的印象。这么想:这些人并不仅仅是潜在的雇员,也是我们的客户。他们也是我们招募工作的销售人员:如果他们认为Fog Creek是一个工作的好地方,他们会怂恿他们的朋友来这里。
啊,我刚刚想起来我曾答应过给你们一些不应该问的问题的例子。
首先,避免问非法的问题。任何有关种族,宗教信仰,性别,国家,年龄,兵役资格,退伍军人状态,性取向,或者生理缺陷的问题都是非法的。如果他们的建立写着他们1990在军队,不要问他们是否经历过海湾战争,即使是使对话更和谐。如果他们的建立写着加入过Haifa的以色列理工学院,不要问他们是不是以色列人,即使是为了使对话更和谐。这与法律不符。
其次,避免那些可能让我们看起来重视的问题或者根据这个鉴别候选人,但是,实际上我们并不关心这个问题也并不根据鉴别候选人的问题。最好的例子就是问候选人他是否有孩子或者他是否结婚了。这可能给候选人错误的印象,让他们以为我们认为有小孩的人不能把全部的时间投入到工作上,或者候选人会跑去休产假。
最后,避免问脑筋急转弯,像怎么样让6根一样长的火柴做4个全等三角形。这就是一个"啊"类型的问题。根据任何问题你不能得到任何信息候选人是否"聪明/能做事"。
面试更像是艺术而不是科学,但是如果你记住聪明/能做事的原则你就在良好的状态。当你有机会的时候,问一下你的同事他们最喜欢的问题和他们想要得到的答案。在Redmond的16号建筑的咖啡厅里这是经久不衰的午餐谈话的话题。