程序员面试中徒手写代码的意义

今天看了一篇文章,分析讲解了技术人员面试中,现场编写代码的意义,我觉得说得非常在理。

其实我在本科的时候,就有一次有机会面试谷歌的实习生。但是因为在徒手写代码的时候,失败了,成了我毕生的遗憾。也造成了我在这类面试中的恐惧心理。当时,我只是一名大三学生,我 C 语言课程成绩优秀,算法课成绩一般,但是我很有动手能力,做过不少网站和项目,还在学校的网站设计大赛拿奖。我认真做了学过课程的大作业,都是照着最高要求做的,比如实现数据库引擎,实现编译器等等。我自我感觉不错,可是,仍然在面试官让我写出围棋提子算法的时候,一脸茫然。

我觉得这非常不公平,只是因为我对这种冷僻的问题没有研究,对算法的套路不熟悉,就遭逢此让人遗憾一生的失败,实在难以服气。

工作多年后,我也成为了一名面试官,我就非常反对在面试中考徒手编程,但是后来我发现,识别一个优秀程序员,着实没有什么好的方法,如果不用徒手编程的话,我们识别一个好的程序员的概率更加低下。所以,我做出了退让,候选人必须过手写代码这一关,但是我不会考算法套路,我们都知道,很多人朗朗上口的深度优先,广度优先,回溯法,线性规划等等,在你实现一个电商业务系统的时候,或者在你实现一个对账系统的时候,或者在你实现一个网站管理后台的时候,用到的概率微乎其微,就算要用,也不会自己去写,因为经常会写出漏洞百出的代码,使用已经存在的类库要稳妥得多。所以对于真实工作来说,这些套路被一些同学喷成是屠龙之术,我觉得也无可厚非。

所以,我当时要求候选人写这样一种代码,仅仅根据直觉,就一下子知道解法是什么,只要智力正常,有初中数学水平就可以随口讲得头头是道。越是这样的题目,越能进入我惯用的题库。我举个例子,计算两个数字之和。这个看似很简单的题目,是很多 ACM 比赛的入门题,加法是任何编程语言内嵌的方法。如果候选人想得太过简单,我就会提示,编程语言的变量都有取值范围,我出的这道题目,不限制两数的取值范围。

这样一来,就不如表面那么简单,但是仍然知道怎么做。首先要选取合适的变量作为容器,其次要按步就班来计算求和。最后可能要考虑很多的情况,比如正负数,浮点数等等。但是,想不出来这个怎么做的人,少之又少。但是写不出来的人,比比皆是。

我此前的想法是,能用嘴说得头头是道,说明候选人智力正常,能用笔写出来,说明候选人是个熟手,不怕繁琐,是个耐烦的人,因为我们的日常工作琐事,往往就是需要细致耐心,有时候甚至是个重复的工作,如果不耐烦,畏惧繁琐,可能就不是很好的候选人。另外不能把自己的想法写出来,说明对自己惯用的语言并不熟练,不一定是个熟手。

我秉持这样的理念很多年。类似这样的题目,我知道还有不少。我有个同事也秉承类似的理念,跟我不同他坚持需要有一点绕弯的题目。他想考察候选人会不会奋力争取,能不能与面试官充分沟通,在提示之下到底能不能被循循善诱找出正确答案。一方面考察沟通,一方面考察智力,一方面还考察候选人的性格。我觉得这也是不错的方式。

有一次,我在拉钩或者知乎上回答别人对编码面试的质疑,我解释过我的理念,我觉得自己还是比较理直气壮的,我说,编码面试确实不能证明一个候选人有多好,但是,测试出了这个候选人的下限有多低。最不济,候选人还是一个可以熟练写出代码的人。

今天看到的文章是这篇《为什么时至今日编码面试依然这么糟糕?》,这篇文章从另一个角度解释了这个问题。我觉得这个作者解释得也比较好。

我们当然会在面试中看走眼,不过,这种看走眼,有两种情况,一个是放进来错误的人,另一个是拒绝了优秀的人。这两种情况来看,放进来错误的人,成本是非常高的,但是拒绝了优秀的人,成本则很低(对于优秀的顶级企业来说尤其如此)。

通过艰难的徒手编码测试,对一个人的心性,毅力,能力都是一种有效地证明,所以,抬高了录用的门槛,极大降低了“错放”的概率,哪怕增加了误拒的概率,但是综合来看成本是降低了。再加上企业有很好的品牌,就更不惧没有人来面试了。

最后,我也想说跟文章作者一样的话。作为候选人,你已经足够优秀了,这个世界上一定有适合你的岗位。一场面试什么都说明不了,因为面试官背后的种种想法,都是希望在统计意义上去优化成本和收益,对于个体的候选人来说,不具备什么绝对的说服力,运气成分很大。所以,千万不要因为过不了编码面试就气馁。