面试游击队员指南

Joel on Software

面试游击队员指南

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部分是询问候选人最近做过的项目情况。如果是面试还在大学的孩子,问他们毕业设计,如果有的话,或者他们在某门课上做过的一个他们真正喜欢的大的项目。比如说,有时候我会问,"上个学期你上的什么课你最喜欢?这不一定要和计算机相关的。"实际上如果他们说了一个和计算机无关的课程我会很开心。有时候你看了他们的课程表,选择了一个学分最少的计算机科学课程,但是所有的选择都和音乐有关。然后他们告诉我他们最喜欢的课程是面向对象数据库。是的,这样也行。我更希望他们能直接承认相比与计算机他们更喜欢音乐,而不是拍我马屁。

当面试有工作经验的候选人,你可以和他谈谈他的前一份工作。

这下面的这些问题中,我只是在寻找一个东西:激情。当谈起他们最近做过的一个项目时,下面这些都是好的表现:

  • 他们谈到这个的时候非常兴奋;他们表现的说的更快和更活跃。这表明当他对某件事感兴趣的时候他会充满激情。有太多的人能有做某一方面的工作但是什么也不在乎。即使他们有负面的激情,这也是好的表象。"我上一份工作竟然为我老板装Foo Bar MarkII,他竟然还这么兴奋。"这些都是我们想要雇佣的优秀的候选人。糟糕的候选人会漠不关心而且在整个面试期间都看不到他的热情。优秀的候选人会在谈论到某个话题的时候充满激情而忘记现在是在面试。有些候选人刚进来的时候会很紧张-这很正常。但是接下来当我谈到计算机单色艺术的时候,他们会特别兴奋完全看不出来之前的紧张。好的,我喜欢有激情的人(如果要看计算机单色艺术疏通一下你的显示器。)
  • 他们注意解释。我曾经回绝过一个候选人,因为他不能够把他上个项目中用到的专业术语解释成一般人也能听懂的话。一般工程学专业的人都假定认为每个人都知道贝茨定理和皮诺娅公里。如果他们开始做这类事情,阻止他们"能不能帮我个忙,能不能把这术语解释得连我祖母都能听懂。"即使这样,还是有很多人继续说着自己行业的黑话完全不管别人能不能听懂,滚。
  • 如果谈起的项目是一个团队项目,注意是否采取某种领导手段。一个候选人也许说:"我们在做X,但是老板说要Y,而客户说要Z。"我会问,"那么你们做了什么?"好的答案是"我和其他组员一起写了个提议。。。"糟糕的答案是,"我们什么都做不了,这完全是不可能的情况。"记住,聪明而且能做事。看一个人能不能做事情的好的方法是看他以前是不是能把事情完成。实际上,你甚至可能叫他们直接举个例子,在最近的项目中采取了某种领导手段把事情做完-克服了一些保守的制度。

列表上的第三个事情是问不可能的问题。这很有意思。这样做的本意是问一些不可能有答案的问题,看他们能不能处理他。"Seattle有多少验光师?""Washington的山总共有多少重?""Los Angeles有多少加油站?""纽约有多少钢琴调音师?"

  • 聪明的候选人会意识到这不是在考验他们的知识,然后他们会很有热情的试着去分析问题背后的东西。"我想想,LA的人口有7百万;每个人平均有2.5辆车。。。"当然即使完全错了那也没有关系。重要的是对问题产生兴趣。他们可能会真的试着去计算加油站的容量。"需要4分钟把车加满油,加油站有10个加油泵,每天加油18小时。。。"有时候他们会非常吃惊你会竟然会问他们Los Angeles有多少黄纸。这些都是好现象。
  • 不是很聪明的候选人会失望和不安。他们会盯着你好像你来自火星。你只能指导他们。"如果你在正在建造像Log Angeles那么大的城市,你会往那里放多少加油站?"你也可以给他们一点提示。"加满一辆车需要多少时间?"还是那样,对于不怎么聪明的候选人,你只能在他们坐在那里发呆等着你去拯救的时候拉他们一把。这些人不能解决问题,我们也不想和他们一起工作。

对于编程问题,我会要求候选人写一小段C函数。

下面是我经常会问的问题:

  1. 将字符串反转
  2. 将链表反转
  3. 统计一个字节中1的个数
  4. 二分查找
  5. 搜索最长的字符串
  6. atoi
  7. itoa(这个很棒,因为这个需要用到堆栈)

你不会给他们一个多于5行代码量的问题;你没有那么多的时间。

我们关注一下细节。#1:我有生以来的面试中每个人这道题第一次都做错了。毫无例外,他们都想去申请另外一个空间,然后反转字符串放到这个空间中。问题是,谁申请空间就要谁释放空间。我问题很多人这个问题,我发现了一个有趣的事实。大部分认为自己精通C的人其实完全不知道内存或者指针。他们就是不理解这些。我很惊讶这种人也能叫程序员。对于这个问题,下面有几种方法判断候选人:

  • 他们的函数执行快吗?看他们用了多少次strlen。我看到过O(n^2)的反转算法,实际上只需要O(n),应为他们在两层循环中都调用了strlen。
  • 他们使用了和指针有关的算法吗?这是个好现象。很多"C程序员"就是不明白怎么在算法中使用指针。一般情况,我不会因为某一个技能而回绝一位候选人。然而,我发现理解C中的指针根本就不是技能,这是资质。计算机科学的新生,计算机科学新生总共有200多个孩子,他们在4岁的时候都能用BASIC在Atari 800s上写复杂的游戏。他们都有良好的编程经验;到了在大学学习Pascal的时候,一直到教授介绍指针了,突然他们不明白了。他们再也弄不懂任何事情了。班级中90%的人离开变成了政治学专业的学生,然后他们对他们的朋友说计算机科学的男女比例不和谐,所以他们换了专业。由于种种原因,有些人天生就缺少能理解指针的能力。这是资质的问题,不是技能-这需要复杂的双重间接思考能力,有些人就是不会。

对于#3,你可以理解他们对C语言的位运算符学的怎么样,但是这是一项技能,而不是资质,因此你可以在这方面帮助他们。有趣的地方是看他们写统计一个字节中所有位的子程序,然后要他们做的更好,程序能运行的更快。真正聪明的候选人会创造一个查找表(最终,这只需要256项),这个表只需要产生一次。和好的候选人一起,你可以有一场关于时间/空间权衡的有趣的交流。让他们做的更好:告诉他们你不想每次每次运行初始化的时候都要建造这一张查找表。聪明的候选人甚至会建议引进缓存机制,第一次计算一个字节的时候计算它,然后把结果存储到查找表中,等下次遇到相同的字节都不要计算了。真正,真正聪明的候选人会利用这个查找表的基本规律推导出计算这张表的方法。

当你观看某个人写代码的时候,这里有一些东西也许有用:

  • 你要经常告诉他们你知道不由编辑器写代码是多么困难,把纸写得很乱没有关系。还有你理解没有编译器写出没有BUG的代码是多少困难,所以会把这些考虑在内。
  • 优秀的程序员的一些标志:优秀的程序员有这样的习惯,写了{然后直接跳到纸的后面写}然后往之间空白的地方写代码。他们也有自己的固有的命名变量的方式,也许,优秀的程序员趋向于用很短的变量名用来做循环计数。如果他们把循环变量命名为CurrentPagePositionLoopCounter,这可以肯定他们这一生没有写多少代码。偶尔你会看到C程序员会写类似if(0==strlen(x))这样的代码,把常量放在==的左边,这是非常好的现象。这意味着他们因为弄混=和==而痛苦了很多次,所以要逼自己养成新的习惯不再重蹈覆辙。
  • 优秀的程序员先计划再写代码,特别是要用到指针的地方。比如,如果你要求他们反转一个链表,优秀的候选人经常在一边画出指针的比变化情况。这是必须的。不画一些带着箭头的小方块而直接写反转链表的代码对人类来说是不可能的。差的程序员直接开始写代码。

不可避免的,你会看到他们写的函数中存在BUG。因此我们进行到了第5个步骤:你对这些代码满意吗?你也许想问:"BUG在哪里?"这个是经典的开放式问题。所有的程序员都会犯错误,这并没有错,只是他们必须能找他它们。对于字符串函数,他们几乎总是忘记给新的字符串用null结尾。所有的函数,都会犯缓冲溢出的错误。他们会忘记用分号结尾。他们的函数对于0长度的字符串没用,或者当malloc失败的时候出现一般保护错误。一个候选人第一次就没有出现任何BUG,这是非常,非常少见的。在这一步骤中,这样的问题可能更有意思。当你说,"你的代码有BUG"他们会很认真的查看一下他们的代码,然后你就可以观察他们是否有足够的信心确定自己的代码是完美的。总体来说,进行下一步骤之前询问一下候选人时候对自己的回答满意是一个好主意。

第六部分:设计题。要求候选人设计一个东西。Excel的原始设计者,Jabe Blumenthal,喜欢叫候选人设计一座房子。根据Jabe,他曾经有过一个候选人直接站起来在白板上画了一个矩形。一个矩形!这个立即就这么干的人不要雇佣。在这一步骤,我们在寻找什么?

  • 优秀的候选人会试着得到对于这个问题更多的信息。这座房子是给谁的?作为指导方针,我不会雇佣连房子给谁住都不问就进行设计的人。我一般很讨厌在给定时间的中间打扰他们说:"实际上,你忘记问这个了,这间房子是给48英寸高的失明的长颈鹿一家的"
  • 不怎么聪明的候选人认为设计就像画画:你有一个白板,你可以在上面画任何你想要画的。聪明的候选人明白设计是一系列困看的权衡过程。一个好的设计题:设计放在城市接到角落的垃圾桶。思考一下所有需要权衡的东西!这必须很容易就清空,但是不能被偷走;这到东西进去必须很容易,但是在下雨天也很难让东西漏出来;这必须很结实,但是不能太贵;在一些城市,这必须特比设计以避免恐怖分子把藏里面。
  • 有创造性的候选人经常会有有趣的,不显而易见的答案使你惊讶。我最喜欢的一个问题是设计给盲人用的调味品架子。必然地,很多候选人会把盲文刻到调味品的瓶子上,而且由于种种原因一般都是刻在瓶子盖的上面。我曾经有个候选人,他决定把调味品放到抽屉形的架子上更好,因为读盲文显然水平摸比垂直摸更舒服(你可以试试!)这想法如此有创造性,太让我惊讶了--面试了这么多次,我从来没有听过这种答案。单单由于这个答案的力量,毫无疑问,我雇佣了这位候选人,他后来成为Excel团队最好的程序经理之一。
  • 寻找结束点。这是把测试候选人是否能做事的一部分。有时候候选人会摇摆不定,不能作出决定,或者他们试着避免困难的问题。有时候他们会把困难的问题放在不去回答它而想继续下去。不好。优秀的候选人会试着使事情继续下去,即使你故意拖住他们。如果谈话开始在那里循环往复,那些候选人会说类似"我们可以讨论这个一整天,但是我们要先做其他事情,我们先做X决定"的话。这是非常好的现象。

什么是#7带给我们的。挑战。这个很有意思。在面试期间,你可以寻找候选人说的绝对正确的地方。然后你说,"等一下,等一下,"然后花个两分钟唱反调。在你知道他们正确的情况下和他们争论。

  • 软弱的候选人会放弃。不要雇佣。
  • 顽强的候选人会想到方法说服你。他们有一系列Dale Carnegie般的技巧来说服你。"也许我误会你了"他们会这么说。但是他们会坚持自己的主张。雇佣。

无可否认的,在面试这种情况下,并不是和派对一样,候选人会害怕和你争论因为你在比他们强势的位置上。但是,优秀的候选人会保持在争论中公平的地位,他们会一度忘记现在正在面试,他们会非常投入的试着说服你。这些就是我们想要雇佣的人。

最后,你应该要问一下候选人他们是否有其他问题。有些人会想听到候选人问一些有才智的问题,像那些面试书中标准的问题。就我个人来说,我并不关心他们会问什么问题;到目前为止我已经作出决定了。候选人一天必须见5-6人,让他们一天问5-6个人不同的,有才智的问题很难,因此如果他们没有问题,没有关系。

我总是在面试的最后5分钟推销Fog Creek。这是非常重要的,即使你并不打算雇佣他们。如果你足够幸运找到了一个优秀的候选人,你也想做一些事情来确定他想要来Fog Creek工作。即使他们是糟糕的候选人,你也应该让他们对Fog Creek软件公司感到兴奋,因此可以给他们留下对公司正面的印象。这么想:这些人并不仅仅是潜在的雇员,也是我们的客户。他们也是我们招募工作的销售人员:如果他们认为Fog Creek是一个工作的好地方,他们会怂恿他们的朋友来这里。

啊,我刚刚想起来我曾答应过给你们一些不应该问的问题的例子。

首先,避免问非法的问题。任何有关种族,宗教信仰,性别,国家,年龄,兵役资格,退伍军人状态,性取向,或者生理缺陷的问题都是非法的。如果他们的建立写着他们1990在军队,不要问他们是否经历过海湾战争,即使是使对话更和谐。如果他们的建立写着加入过Haifa的以色列理工学院,不要问他们是不是以色列人,即使是为了使对话更和谐。这与法律不符。

其次,避免那些可能让我们看起来重视的问题或者根据这个鉴别候选人,但是,实际上我们并不关心这个问题也并不根据鉴别候选人的问题。最好的例子就是问候选人他是否有孩子或者他是否结婚了。这可能给候选人错误的印象,让他们以为我们认为有小孩的人不能把全部的时间投入到工作上,或者候选人会跑去休产假。

最后,避免问脑筋急转弯,像怎么样让6根一样长的火柴做4个全等三角形。这就是一个"啊"类型的问题。根据任何问题你不能得到任何信息候选人是否"聪明/能做事"。

面试更像是艺术而不是科学,但是如果你记住聪明/能做事的原则你就在良好的状态。当你有机会的时候,问一下你的同事他们最喜欢的问题和他们想要得到的答案。在Redmond的16号建筑的咖啡厅里这是经久不衰的午餐谈话的话题。

你可能感兴趣的:(编程,算法,面试,Excel,招聘)