轻松面试 搞定技术奇才

译者注:本文作者Joel Spolsky 是纽约市一家软件公司Fog Creek Software的创始人。他毕业于耶鲁大学,曾分别在美国微软、Viacom、Juno等公司任软件设计师、经理职位。本文来自于《祖儿谈软件》,文章原名为《轻松面试找到理想员工——非官方的面试技术指南》,作者最初本意是针对微软公司所写,后来修改了几次,现在为Fog Creek Software公司的面试手册。原文地址可参见http://www.joelonsoftware.com/articles/fog0000000073.html。此外,作者相关作品的中文版链接地址请参考http://chinese.joelonsoftware.com/

雇佣合适的人对于Fog Creek软件公司来说是非常关键的。在我们这个领域,有三类人可以挑选:无知的群氓,甚至缺乏最基本的工作技巧。只要问这类人两三个简单的问题,再读一下他们的简历,就可以轻易地剔除他们。另一个极端的类型是才华横溢的超级明星。这些人仅仅为了好玩就用汇编语言为Palm Pilot(一种手掌电脑)写一个Lisp(一种人工智能编程语言)编译器。这两种极端类型的中间,是一大群不能确定水平的候选者,所以,这里的关键是要明白超级明星和那一大堆属于中间类型的人的区别。下面我就介绍一些寻找超级明星的技巧。

Fog Creek公司最重要的雇佣标准是:
有头脑, 并且完成工作
就是这些了。记住这条标准。我们公司的目标之一就是雇佣拥有这样潜质的人,而不是雇佣懂某些技术的人。任何人所拥有的某些具体技术都会在几年内过时,所以,雇佣有能力学习新技术的人,要比雇佣那些只在这一分钟知道SQL编程是怎么回事的人对公司更划算。
有头脑确实是一个很难定义的品质。但通过面试时提问的一些问题,就可以找出拥有这种品质的人。完成工作非常关键。看起来有头脑但是不能完成工作的人经常拥有博士学位,在大公司工作过,比起准时交货,他们宁愿对于一些学院派的东西沉思。这些人由以下特性可以识别出来。他们总是爱指出两个根本不同的概念间的相似性。例如,他们会说“Spreadsheets是一种特殊的编程语言”,然后花一个礼拜写一篇动人的、智慧的白皮书。这篇白皮书论述了作为一种编程语言,spreadsheet关于计算语言特性的方方面面。他们聪明,但是没用。
下面,我们来看完成工作但是没有头脑的人。他们爱做蠢事。通过制造新的工作,他们成为了公司的负债而不是资产。因为他们不仅没有为公司贡献价值,还浪费了好多人的时间。这些人通常到处粘贴大堆的代码,而不愿意写子程序。他们是完成了工作,但不是以最聪明的方式完成工作。

面试时最重要的法则是:
做决定
面试结束时,对于被面试者,你不得不做一个直截了当的决定。这个决定只有两个:雇佣或者不雇佣。
没有其他的答案。永远不要说,“雇佣你,但不是在我的团队中”。这是非常粗鲁的,所以就尽可简单的把这句话变成“不雇佣”。如果某个人在特定领域很能干,但在别的队伍中表现不好,答案也是不雇佣。某些情况下你发现了一个拥有某些特殊能力的白痴专家,他对于SQL非常、非常的精通,但除此之外什么也不会,答案还是:不雇佣。在Fog Creek公司,他们没有将来。
永远不要说,“也许,我吃不准”。如果你不能做出决定,那也意味着不雇佣。最重要的是记住这点:宁可错失一千,不可放过一个。一个不合格的求职者如果进了公司,将消耗公司大量的金钱和精力。还要浪费其他优秀员工的时间来修复这个人的错误。总之,无论寻找合适的应聘者有多么困难,也永远不要降低你的标准。

如何作出雇佣或者不雇佣这样艰难的决定?答案只有一个:这个人有头脑吗?这个人能完成工作吗?要想做到正确的判断,面试时你必须问对问题。
开个玩笑,下面我要问个有史以来最差的面试问题:“Oracle 8i中的数据类型varchar和varchar2有什么区别”?这是一个可怕的问题。掌握这种琐碎的技术细节和Fog Creek公司想雇佣你之间没有任何联系。谁会去记这种东西?如果有在线帮助,你可以在15秒内找到答案。实际上,还有更差的问题,等会我们会谈到。
现在我们要谈到有趣的部分了:面试时提哪些问题。我的面试问题清单来自于我去微软公司找第一份工作的经历。这里实际上有几百个微软面试问题。每个人都有偏爱的问题。你也可以发展一套自己的面试问题以及面试的个人风格,这样就可以比较容易地做出雇佣/不雇佣的决定。以下是我成功使用过的一些面试技巧。
面试前,读一遍应试者的简历,然后在一张纸片上写下面试计划。这个计划实际上就是问题清单。以下是一个例子(用来面试程序员的):
1. 介绍   2. 应试者参加过的项目
3. 不可能的问题 4. C语言函数
5. 你满意吗?  6. 设计问题
7. 挑战   8. 你还有什么问题?

面试前,我会非常当心,避免自己先入为主。面试就像一个非常精巧的天平。一小时的面试结束后就要对一个人下结论是不容易的(但是你又必须在面试结束后得到结论)。一些不起眼的细节可能会影响最后的结论。所以,如果你在面试前就对应试者作一点了解,就好比天平的某一端加重了砝码。这样面试本身就会失去原有的价值。
记得有一次面试前,一位猎头公司的人跑进房间说,“你会喜欢这个家伙的”。当这个家伙开始说蠢话时,我对自己说,“他应该是个例外,也许是大智若愚。”于是,我带着玫瑰色眼镜看他,并最终以“雇佣”结束了面试,虽然他是一个糟糕的员工。这次面试对我的教训是,不要听别人的话,不要在面试前四处打探这个应试者的情况。最重要的是不要和别的主考官谈论应试者,除非你们都已经做出了独立的判断。这是科学。
作为面试的第一步,介绍的目的是让应试者放松。我通常花30秒钟,讲一下我是谁,接下来面试会如何进行。我总是使应试者确信,我们关心的是他如何解决问题的,而不是他的最终答案是对还是错。顺便说一下,面试时,你不要和应试者隔桌而坐,否则你们间就有了一个障碍,并且暗示着一种比较正式严肃的气氛,这样应试者就很难放松了。较好的办法是把桌子靠墙,或者和应试者坐在桌子的同一边,这样有助于应试者放松。只有应试者不因为紧张而表现失常,你才能更有效的进行面试。

第二步就是了解应试者最近做了什么项目。对于那些刚离开校门的学生娃,就问他与学位论文相关的项目,或者问一下他们最喜欢的课程。例如,有时候我会问,“你最喜欢上学期哪门课程?不一定要和计算机相关。”这时你发现这名应届生档案中选修与音乐相关的课程远远大于计算机课程,但他却回答最喜欢的是《面向对象数据库》。实际上,如果他承认喜欢音乐胜过计算机,我会更高兴。当面试有工作经验的人员时,可以让他们谈谈前一份工作。
问这个问题的目的是寻找一种品质:热情。在应试者谈到他最近做过的项目时,如果能观察到以下迹象,那都是很不错的:
l 谈到他们做过的项目时变得热情洋溢;语速更快,语言更生动活泼。这说明他们对某些东西有兴趣,有热情。即使他们激动地表达对做过项目的负面感情,这也是一个好的信号。“我曾经为前一个老板安装Foo Bar Mark II,但他是个傻瓜!”表现出热情的人就是我们要雇佣的人。差的应试者对工作不关心,所以根本不会激动。一个非常好的信号是当应试者很激动地谈论上一份工作,以至于暂时忘记了他们正在被面试。有时候应试者刚开始面试时表现得很紧张,通常我会忽略不计,但是当他们谈到Computational Monochromatic Art时,激动的以至于忘记拘谨。不错,我喜欢这样的应试者,因为他们关心自己所做的事。
l 他们非常小心地解释事物。我曾经拒绝了一些应试者,因为在谈到他们做过的项目时,满口都是普通人不能理解的术语。如果应试者开始满口行话了,告诉他,“能帮个忙吗?你能把刚才所说的用我祖母也能理解的语言再讲一遍吗?”这时会有许多应试者还是使用术语,没有人能够理解他们在说什么。天哪!
l 如果所做项目是一个团队项目,看看他们是否有承担领导责任的迹象?一个应试者可能会说:“我们用X方法,但老板说Y方法,而客户要求用Z。”我会问,“那你是怎么做的?”一个好的答案可能是“我设法和团队中其他人开会,然后一起商量出办法……”坏的回答是,“嗯,我没办法,这样的问题我解决不了”。记住,聪明并且能完成工作。要搞清楚某人是否能完成工作的一个办法就是看他过去是否倾向于完成任务。事实上,你可以主动要求他们给你例子,证明他们能担任领导角色,完成任务——例如克服公司的陈规陋习等。

现在谈谈清单上的第三款,无法回答的问题。这很有趣。这个主意的关键在于问一些不可能有答案的问题,就是想看一下应试者怎么办,如“西雅图有多少眼科医生?”“华盛顿纪念碑有多重?”“洛杉机有多少加油站?”“纽约有多少钢琴调音师”等等。
l 聪明的应试者猜到你不是在测验他们的专业知识,他们会积极地给出一个估计。“嗯,洛杉机的人口是七百万;每个人平均拥有2.5辆轿车…….”如果他们的估计完全错了也没有关系。重要的是他们能积极地试着回答问题。他们可能会试着搞清楚每个加油站的储量。“嗯,需要4分钟给一个储油罐加满油,一个加油站有10个油泵每天运行18个小时……”他们也可能试着从占地面积来估计。有时候他们的创造力会使你吃惊,因为他们问你要洛杉机的的黄页。这都是好迹象。
l 不聪明的应试者则被难住了。他们目瞪口呆地望着你,好像你来自火星。你不得不提示:“如果想建一个象洛杉机那么大的城市,你需要多少个加油站?”你还可以提示他们:“加满一个储油罐要多长时间?”但是不聪明的应试者还是傻傻地坐在哪里,等着你继续提示下去,直到你自己解答了问题。这些人不是问题的解决者,我们不想和他们一起工作。

关于编程问题,我通常要求应试者用C语言写一些小函数。以下是我通常会出的题目:
1将一个字符串逆序
2将一个链表(linked list)逆序
3计算一个字节(byte)里有多少bit被置1
4搜索给定的字节(byte)
5在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的
6字符串转换成整数
7整数转换成字符串(这个问题很不错,因为应试者要用到堆栈或者strrev函数)
注意,通常你不会希望他们写的代码多于5行,因为你没有时间理解太长的代码。
现在我们来看一下这些问题的详细内容:
第一个问题:逆序一个字符串。至今为止,每一个应试者第一次解答这道题目时都答错了。所有的应试者都试图动态生成缓冲区,然后将逆序的字符串输出到该缓冲区中。问题的关键在于,谁负责生成这个缓冲区?谁又负责释放那个缓冲区?通过这个问题,我发现了一个有趣的事实,就是大多数认为自己懂C的人实际上不理解指针和内存的概念。这真叫人吃惊,他们不懂这个基本概念却可以做程序员?这个问题可以从多个角度判断应试者:
l 他们的函数运行快吗?看一下他们多少次调用了strlen函数。我曾经看到应试者写的strrev的算法竟然只有O(n^2) 的效率,而标准的算法效率应该是O(n),效率如此低下的原因是因为他们在循环中一次又一次地调用strlen函数。
l 他们使用指针运算吗(译者按:原文为pointer arithmetic,指的是加减指针变量的值)?这是一个好现象。许多所谓的“C程序员”竟然不知道如何使用指针运算。当然,我在前文说过我不会因为应试者不掌握一种特定的技巧而拒绝他。但是,理解C语言中的指针不是一种技巧,而是一种品质。每年一所大学要招进200多个计算机系的新生,所有这些孩子很小时就开始用BASIC语言在Atari 800s写冒险游戏了。在大学里他们还学Pascal语言,学得也很棒。直到有一天他们的教授开始教C语言,突然,他们开始搞不懂了。他们就是不能再理解C语言中的任何东西了。于是90%的计算机系学生转系去学政治。为了挽回面子,他们告诉朋友,之所以转系是因为他们计算机系英俊貌美的异性太少。许多人注定脑子里就没有理解指针的那根弦。所以说理解指针是一种与生俱来的品质,而不是一种单纯的技巧。理解指针需要脑子转好几个弯,某些人天生不擅长转这几个弯。
通过第三个问题,你可以观察到他们对于bit操作运算符掌握得怎么样?但是这是一种技巧,不是一种品质,所以你可以帮助他们。有趣的是你观察他们建立了一个子函数用来计算byte中为1的位的数目,然后你要求他们优化这个子函数,大大加快这个函数的运行速度。真正聪明的应试者会使用查表算法(毕竟这个表只有256个元素,用不了多少内存),整个表只需要建立一次。你还可以和这个聪明的应试者讨论一下如何权衡算法的效率和算法占用的内存。更深入一点:告诉他们你不想在程序启动时初始化查询表。厉害的程序员会建议第一次计数时使用普通算法,同时将查询结果缓冲到查询表中。某些天才程序员在计算那个查询表时,甚至试图使用已经使用过的模式。
当你观察应试者写C代码时,以下技巧会有所帮助:
l 事先向应试者说明。这完全理解,没有一个好的编辑器只在纸上写代码是困难的,所以你不在乎他们手写的代码是否看上去整洁。你也完全明白没有好的编译器和调试器,很难第一次就写出完全没有bug的程序,所以请他们不必为此担心。
l 优秀程序员的标志:优秀程序员写完“{”符号后,通常立刻跟上“}”符号,然后再在当中填上代码。他们也倾向于使用命名规则,虽然这个规则可能很原始。如果一个变量用作循环语句的索引,优秀的程序员通常使用尽可能少的字符为它命名。如果他们循环语句的索引变量的名字是CurrentPagePositionLoopCounter,显而易见他们写代码的经验还不够多。偶尔,你会看到一个C程序员写下象if (0==strlen(x))一样的代码,常量被放在==的左边。这是一个好的标志。说明程序员理解了在C中=和==易于混淆。
l 优秀程序员在写代码前会订一个计划,特别是当他们的代码用到了指针时。例如,如果你要求逆序一个链表,优秀程序员通常会在纸的一边画上链表的草图,并表明算法中的索引指针当前移动到的位置。他们不得不这样做。正常人是不可能不借助草图就开始写一个逆序链表的程序的。而低水平的程序员则立刻开始写代码。

不可避免的,你会在他们的程序中发现bug,下面我们来看第五个问题:你对代码满意吗?你可能想问,“好吧,bug在哪里?”这是很糟糕但又一针见血的问题,要回答这个问题可要大费口舌。所有的程序员都会犯错误,这是真理。程序员必须找出这些错误。对于字符串操作的函数,他们通常会忘记在输出缓冲区加上字符串结束符。所有的函数,他们都会犯off-by-one错误(译者按:指的是某个变量的最大值和最小值可能会和正常值差1)。他们会忘掉正常的C语句结尾的分号。如果输入是零长度字符串,他们的函数会运行错误。如果malloc调用失败而他们没有为此写好错误处理代码,程序会崩溃。很少见的,一个程序员第一次写完的代码就完全没有错误。这时你可以问一个更有趣的问题,你说,“代码里有一个bug”。他们会再仔细地复查一遍代码,然后你就可以饶有兴趣地观察他们是否礼貌但是坚定地坚持自己的代码是否是完美的……总之,在程序员写完代码后,问一下他们是否对代码满意,就像美国ABC电视网游戏节目主持人Regis常问的那样“这是你最后的答案吗?”

第六部分:关于设计的问题。让应试者设计某种东西。Excel的原始设计者Jabe Blumenthal喜欢让应试者设计房子。Jabe说,曾经有一个应试者跑到白板前,画了一个方块,这就是他的全部设计。立刻拒绝这样的家伙。再想一想你喜欢问什么样的设计问题呢?
l 好的程序员会问更多的信息。房子为谁建造?我们公司的政策是,我们不会雇佣那些在设计前不问为谁设计的人。通常,我会很烦恼地打断他们的设计描述,提醒他们“事实上,你忘记问这个房子是为谁设计的了。这个房子是给一群长颈鹿造的。”
l 愚笨的应试者认为设计就像画画,你想画什么就画什么。聪明的应试者明白设计的过程是一系列艰难的权衡。一个很棒的设计问题是:设计一个放在街角的垃圾箱。想一想你得做多少权衡!垃圾箱必须易于清空,但是很难被偷走;易于放进垃圾,但是碰到狂风大作,里面的垃圾不会被吹出来;垃圾箱必须坚固而便宜。在某些城市,垃圾箱必须特别设计,以防恐怖分子在里面隐藏定时炸弹。
l 有创造力的应试者会给出有趣而独特的设计。我最喜欢的问题之一是为盲人设计一个放调味品的架子。通常许多应试者的建议是把布莱叶文(一种盲人使用的文字)刻在放调料的罐子上,但这样文字会卷起来而变形。我碰到一个应试者,他的设计是把调料放在抽屉里,因为他觉得水平地感知布莱叶文比垂直地更方便。这个答案有创意,使我震惊!我面试了近乎一打的程序员,但从来没有人想到过类似的答案。这样有创意的答案确实跃过了普通人考虑问题的条条框框。仅仅因为这个答案太有创意了,而且应试者别的方面还过得去,我雇佣了这个应试者,他现在已经成为微软Excel团队中一个优秀的项目经理了。
l 总是争取一个确定的结果。这也是完成工作的特质的一部分。有时候应试者的思路飘忽不定,不能作出一个决定。有时候他们回避困难的问题,想蒙混过关。这很不好。好的应试者有一种推动事情自然前进的倾向,即使你有意把他们拖回来。如果关于某个话题的讨论开始原地打转变得没有意义了,好的应试者会说,“嗯,我们可以整天谈论这个,但是我们得做点什么。为什么我们不开始……”

问题转到第七部分,挑战。在整个面试过程中,你期望理想的应试者总是能够正确地评论某件事。这时你会说“等一会”,然后玩一种叫魔鬼代言人的游戏。你明知他们是对的,但你偏说不对。
l 软弱的应试者会屈服。那我就和他说拜拜了。
l 坚定的应试者会找到办法说服你。甚至他们会以肯尼迪总统的口才来说服你,“也许我误会了你的意思,”他们这样开头,但是正文仍是坚定地站稳立场。这样的人值得雇佣。
不得不承认,面试双方的地位并不完全平等。有时应试者由于害怕你的权力而不敢与你争辩。但是,好的应试者有足够的热情和勇气坚持正确的观点,他们由于热切希望说服你而会暂时忘记正在被面试。这样的人正是我们要找的人。

最后,可以询问应试者有什么想了解的。一些人喜欢看看应试者这时是否会问一些聪明的问题。这是市面上流行的面试书籍的标准技巧。我个人不在乎应试者问什么,因为这时我已经做好了决定。这一步的困难之处在于,应试者也许已经见过了5、6个人,进行了好几轮面试,他们可能很疲倦,以至于不能为每轮面试都准备一个聪明而独特的问题。所以如果他们没有什么可问的,这也没关系。
我总是留下面试的最后5分钟来推销我们公司。这很重要。即使我不打算雇佣眼前这位应试者,我也会如此。原因在于如果你幸运的找到一位很满意的应试者,你当然愿意做任何事情说服他(她)来你的公司。如果他们不是很好的应试者,你也要尽力让他们为Fog Creek公司心动,这样面试结束时他们会对Fog Creek公司留下很好的印象。记住,应试者并不仅仅是可能的雇员,他们也是顾客,也是我们公司的推销员。如果他们觉得我们的公司很棒,他们也许会推荐朋友来面试。

啊哈,下面我要举出几个糟糕的面试问题的范例。
首先,避免不合法的问题。有关种族、宗教、性别、出生国、年龄、服役记录、是否老兵、性取向、生理障碍的问题都是不合法的。即使他们的简历说他们1990年在军中服役,也不要问有关问题。即便他们会愉快地谈论在海湾战争中的经历,但你的问题还是不合法的。
其次,不要在问题中给应试者以暗示,我们公司喜欢或者不喜欢什么样的员工。我能想到的一个例子是问应试者是否有小孩或者是否结婚了。这个问题也许会让应试者认为我们不喜欢有家庭拖累的员工。
最后,不要问那些脑筋急转弯的题目,例如6根火柴怎么拼出4个三角形。像这样灵机一动的问题是不能看出应试者是否具备“有头脑/完成工作”的品质的。

面试与其说是科学,不如说是艺术。但是只要你记住有头脑/完成工作这个原则,你就可以应对自如。有机会问问你的同事,看他们喜欢什么样的面试问题和答案。这本来就是我们公司员工午饭时热衷的话题之一啊。

(来自《程序员》杂志)

posted on 2007-12-25 23:15  guoadou  阅读(711)  评论(0编辑  收藏  举报