招聘面试程序员的一些心得
BY NETSMELL
最近雅虎北研解散的消息触动了各大互联网公司 HR 的神经。公司里一下子面试的任务多了起来。正好借机会总结一下自己毕业后作面试官以来参与若干场技术面试的一点心得,分享一下。
当好一个面试官其实也很不容易,不但要练就一双火眼金睛,把优秀的人才和水货在短短的面试的几十分钟里分辨出来,同时面试官本身就是候选人观察公司的一个窗口。在面试中,面试官还要注意很多接人待物的细节,既能彰显公司求贤若渴、对人才的尊重,又能将公司的技术水平和文化氛围展露一二,以求给候选人留下良好的印象。
社招某种意义上比校园招聘更困难。面对形形色色的社招候选人,首先一个要想清楚的问题就是我们到底该招什么样的人?简单的说就一句话,适合自己公司的人。每个公司都有独特的文化和特定的业务需求,更有各自的业务发展阶段。就算同样是招程序员,也应该因地制宜,有所侧重。拿我现在所在的公司(某大型外企驻华研发机构)、所在的行业(瞬息万变的互联网)来说,我觉得最重要的就是下面几点:
第一,聪明。作为大公司,尤其是外企,总部的制约总是一定程度的存在,互联网行业更是一个日新月异的行业。这时,项目背景和知识远没有能力靠谱。如果一个人的工作业绩,是来自无数岁月一脉相承而延续下来的知识体系,是积累到某种程度的知识土壤上很自然的发芽、开花、结果,那么在这种充满未知、充满变化的行业和工作中,一旦项目发生较大变化,那么你在适应新任务、新角色、新挑战时就会出现很大的落差甚至困难,最后的结果通常是工作效率显著下降,严重的甚至只能一拍两散。公司花这么大的力气招聘和培养人才,如果仅仅因为项目变化就发生大规模的离职,想来从公司角度是非常不划算的。所以,在我参与的面试中,我最提倡招聪明人,要招比自己聪明的人,招能适应各种新技术、新行业、接受新挑战的人,招和自己不一样的人。当然,这也是由公司的特点决定的。我们公司的特点是组织机构调整、项目变化频繁,公司规模很大、业务范围很宽,对正式员工相对较负责,内部培训较完善,裁人比较慎重,发生各种变化时内部换岗机会多。其他公司未必可以参考,但可以结合自己的需求和特点对号入座。
为了测试一个人的聪明程度,我通常会给他一道算法类的题目,让候选人尝试给出一个经过优化的解。选题时,我通常会选择那些不同思路、不同水平的解非常多的题目。我一般并不指望候选人一下子把最优解做出来(实际上也有个别能做到的特别优秀的候选人,但同时也要小心他以前做过类似的题)。我会通过交流去尝试理解他的优化思路,然后适时的沿着他的思路给点提示,看看他能不能有什么进展。在交流中,我主要观察一个人的逻辑思维的严密性、考虑问题是否全面,思考是否迅捷,能不能突破既有思路的框框。我还要观察候选人能否在解题过程中很好的理解问题,对问题能否进行系统性的有条理的分析。俗话说文无第一、武无第二,其实任何最优解都有一些充分限定的条件或假设作为前提,除非用数学公式的风格严谨的出题,常规意义的完美解是很少存在的。一个人,如果能突破常规,能对问题有很好的分析,取得一定进展,我觉得在有限的时间和面试的压力下,能做到这些已经难能可贵了,面试官也并不一定有必要盲目的追求最优解。
在这里,也要顺道提醒参加面试的候选人。解题时,要留意面试官的问题和提示(如果有的话)。我记得见过一些候选人在面试中完全封闭在自己的世界里,从面试官的角度来说,他们完全没有任何进展的憋在那里,甚至在面试官主动帮助他的时候也没有取得任何有意义的反馈。纵使候选人天赋异禀、聪明绝顶,但如果在面试中与面试官都无法顺利协作,那么实际工作中又会如何呢?面试官既然花费时间参加面试,从内心深处都是非常希望找到合适候选人的,面试官也希望被面试的你通过面试。所以,从心态上不要简单的把面试当作一个非黑即白、相互对立的考试。从某种意义上说,我更不仅仅是一次考试,他更像相亲,呵呵。
第二,技术深度。作为软件工程师,毕竟还是一个技术性岗位。不管你有多聪明,如果你的个性和主观意愿上决定了,你并没有在技术上钻研到一定深度的意愿或能力,那么公司派你冲锋陷阵的时候就要考虑一下了。毕竟就算对你来说是新领域,从互联网公司的需求来说,公司通常要你在最短的时间帮助他们提高产品技术水平,以便有机会能在残酷的市场上取得有利的竞争地位。并非公司没有耐心等你慢慢成长,而是外部环境、那些虎视眈眈的竞争者不允许。如果你个人没有追求卓越的习惯,不能在有限时间将你学习和掌握的技术钻研到足够的深度,那么公司将无法在残酷的市场竞争中生存,公司雇佣你、留住你的意义又何在?所以,我觉得公司需要的人才是这样的,他们有追求卓越的意愿,有独立探索、不断学习和自我进步的能力,他们哪怕从事的是全新的领域,只要给他一点合理的适应和探索的时间,他都可以做的比很多人、比其他公司更好。
在技术深度的面试中,我通常会通过候选人以前做的项目、读过的书或者熟悉的编程语言,围绕着这些话题来出题。面试官当然不可能什么都懂得很深,所以面试题也不需要过于刁钻、古怪。拿以项目背景为主的话题为例,可以通过不断深入的去了解对方的角色和职责,看看他对项目中的各种技术、架构和具体实现是否熟悉。如果发现系统设计上的瑕疵或挑战,还可以更深入的探讨,看看候选人的反应。有些候选人号称是核心开发人员或者项目主管,但实际上问他很多细节问题根本回答不出来,这种候选人或许浮在上面做管理工作太多、技术上不是特别擅长,要么就是简历中水分太大并没有多少真金白银。谈谈熟悉的编程语言或技术书籍也是不错的选择,但要注意别考很偏的问题,因为那是在考知识,不是考能力。知识对于聪明人来说是可以学习的,面试中要侧重对知识的运用。很多技术涉猎不深的程序员,常常是知其然不知其所以然,更谈不上活学活用。当然实际上知其然恐怕有不少候选人都做不到,这类人特别是工作年限很长的就算了,说明他缺少对技术的理解还是很浅,难以承担重任。很遗憾在这里不能通过面试题举例一二,以后方便的时候再跟大家交流吧。
第三,技术沟通能力。排除个性和常规的沟通技巧等因素,很好的技术沟通能力实际上在日常工作中非常重要。我们需要优秀的工程师不但能孤军奋战,也能团队协作。这就要求大家能抓住问题要旨,在交流和对话中完全没有沟通障碍的可以并肩战斗的伙伴。而良好的技术沟通能力,实际上需要很多素质,包括即时反应能力、很强的技术理解力、系统性的思考和分析能力、总结和概括能力以及具象化的展示和表达能力,实际上当真是很难得的。在面试中要格外关注候选人在交流中所表现出来的种种行为特征和模式,比如木讷、啰嗦、跑题、抢话、傲慢等等。对有比较严重的沟通缺陷的候选人,纵使其它各项面试表现良好,也要格外慎重,否则极有可能会拖累团队的效率。
第四,代码。归根到底,程序员特别是基层是用代码说话的职业。我很难想象一个事业上成功的优秀的程序员,居然不能再面试中写出清晰、严谨、高效的代码。我个人是建议算法题和代码题分开,最好混在一起。我的代码题一般重点考察两点:候选人的代码风格如何,包括函数和变量的命名,包括程序逻辑是否存在大量的冗余,包括一些个人的编程习惯如何;此外,还会考察候选人的程序逻辑上是否严密,对输入有无断言或正确性验证,对各种逻辑上的边界条件能否正确处理,特别是写好程序后有没有自我测试的过程,通过合适的测试用例验证程序的正确性。即便对于那些面向基层管理职位和架构师职位的人我也是一视同仁的,在我看来没能力用代码说话的技术人员,是很难做好基层的项目管理、研发管理等职位的,除个别妖孽外我也很难想象一个没能力写好代码的人能做好架构层面的设计。归根到底,这一切都是相通的,是程序员的基本功,说的或许不贴切,但至少我没见过初等数学一团糟但微积分非常出色的人。
第五,品味和兴趣。通常我开始了解一个候选人的技术品味的时候,他已经通过了面试,而且我对他的面试成绩一定是非常满意的。在这个层面,我会问问他最近在业余时间读了什么技术书籍,探索了什么有趣的新技术,或者经常去什么网站学习。一方面,一个人的技术水平的提高除了来自工作时间公司项目里身边的这些同事,也来自他业余时间自己的个人涉猎,这时候他的兴趣和品味会为他选择最适合他的渠道。如果一个候选人足够优秀,我常常会问他这方面的问题,一方面我可以借机学习,多多参考他公司之外的学习之道;另一方面,也可以更全面掌握他的知识结构和兴趣爱好,看看有没有给面试加分的或者适配于工作需要的地方。
好了,今天先分享到这。有什么不当和疏漏在所难免,欢迎业界朋友多多指教!
[原创文章,作者 @晴月浩雪]