面试就好像是在第一次约会的时候就要决定是不是要结婚
这是一个真实的笑话。在每日高强度的工作当中,我们和一些同事相处的时间甚至会比家人还要长。所以面试是工作中十分重要的一个环节。
最近在给公司内部的软件工程师做面试培训,我想借着这个机会把一些面试的经验总结出来和大家一起交流。先介绍一下笔者的经历。
本人在 Facebook 的五年里面试了几百个人,现在在吴恩达老师的公司 Landing AI 里做 Tech Lead。我也参加过 Google、Amazon、Uber 等大小公司的面试。本文总结了笔者在 Facebook 接受的面试培训以及这几年的面试经验。虽然人在硅谷,但软件工程师的职责和标准在国内外很相似,所以希望本文对国内的读者有一定的借鉴价值。
正文开始之前,请你先想像一个场景:
有一天,你的老板找到你,让你和另一名工程师合作完成一个项目,那么你希望这名的工程师具有什么样的品质?开发速度快(coding machine)?代码清晰易懂?接口易用?系统搞设计能力强?知识渊博?靠谱?有激情?容易相处?自我驱动力强?或者以上所有?
那么你所想看到的优点也就同样是你在面试时候需要考察的重点。面试首先要明确目标,再通过目标反向推导出面试的考察点和内容。
硅谷大公司的面试分为三种类型:编程面试、系统设计面试、行为面试。一般在编程面试或者系统设计面试中不会涉及行为面试,但是在行为面试中可能会加入简单的系统设计以及编程。
本文主要分享的是编程面试的经验总结,所以不会涉及过多的系统设计或者行为面试的内容。其他类型的面试会在之后的文章中讨论。
编程面试中,我们应该考察面试者的什么能力呢?
编程面试主要测试面试者的如下几点能力和品质:解决复杂问题的能力、沟通能力、编程能力、调试能力、测试能力、知识储备等。除此之外,面试者的态度、习惯等也在考察范围之内。
解决问题:解决问题的能力包括是否能把复杂问题简单化,比如把一个大问题分解成若干个小问题。面对复杂问题的时候,面试者能否先想出一个简单的解法而非最优的解法。在工作中,我们经常会遇到复杂的项目和问题,需要工程师把问题分解,先想出一个方案可以快速满足需求。
沟通能力:沟通能力十分重要。我相信很多人都经历过因为沟通中出现的问题导致项目进展不顺利或者做了无用的努力。在系统设计和行为面试两轮会对面试者的沟通能力有更全面的评估,代码轮更多的是考察面试者解释思路的能力。
编程能力:这个涉及的范围就非常广泛了:代码的正确性,结构是否清晰,设计是否合理,编程习惯是否良好,代码是否易读,速度是否快。对于代码的要求和在平时工作当中是一样的,并不会因为是在面试而降低要求。
调试能力:我很少见到有人在面试的时候能把代码一次写对,编译和运行的过程当中总会有错误。我们需要每一位工程师都有能快速找出代码问题的能力。
测试能力:这里最重要的一点是能否找出所有的 edge case 以提高测试的覆盖率。我们每天在做代码审查的时候会尽量考虑到所有可能的情况。然而现实中,大部分的 edge case 都是由代码编写者发现并处理。所以写好测试的能力是十分重要的。
什么样的题目算是一个好的面试题?
一个好的面试题应该能够考察面试者以上所有的能力。
首先,一道题目不能太过直接简单。简单的题目既不能测试出面试者的能力,又不能拉开优秀和普通工程师的距离。
其次,问题应该具有延展性。有些面试者会比其它人更快的做出题目。这个时候如果重新问一道全新的题需要花时间解释。然而在已经完成的题目上做延伸就不会有这样的问题。 比如可以禁止一些操作,或者对复杂性提出更高的要求。更难的问题可以帮你找出真正优秀的工程师。
第三,题目可以具有一些不确定性。比如在解释题目的时候漏掉一些信息。举个例子,输入 integer 的范围和正负性。这种方式可以帮助你考察面试者思考问题是不是全面(测试能力),以及是否有良好的沟通能力。
第四,要避免智力题和脑筋急转弯。有些问题太过于依赖面试者的智力表现。举个例子,25 匹马赛跑,最少几次找出前 3 名。不推荐这类问题有几个原因:
通过智力题目选出来的工程师不一定能写出优秀的代码。上文中提到的绝大部分能力都无法考察。
尤里卡时刻依赖灵光一现。面试的时候有没有尤里卡时刻有一定的运气成分。一个优秀的工程师很有可能因为客观的原因没有想到答案而被淘汰。
第五,请时不时的去网上搜索一下贵公司的面经,看看自己的题目有没有被泄露。如果被泄露,为了公平起见,请及时更换题目。
如何把握面试的节奏?
如果面试是一个小时的话,我一般这么分割时间:
0-5 分钟:问面试者是不是需要喝水上卫生间。简单的互相介绍一下,问问面试者之前的经历。从面试者熟悉的内容开始有助于缓解面试者紧张的情绪。
5-55 分钟:做题。这个时候你需要尽量收集面试者的信息。所以如果面试者卡在某个具体的问题上太久,你可以适当地给一些提示,如果在一个问题上花费太多的时间,你就没有机会考察他/她其它方面的能力了。
55-60 分钟:回答面试者的问题。这个环节有两个事情需要做:第一是推销你的公司,第二是从其他方面了解面试者。面试者的问题很多时候都反映出了工作中哪些地方对他/她重要。比如公司文化、工作时长等。
如果是第一轮电面(电话面试),我会多花 5 分钟在面试者的 behavior 上,以确定面试者在文化和背景上是否适合我们公司。
如果面试是 45 分钟,我会把中间编程的时间缩短,前后的十分钟保持不变。因为两部分对面试十分重要,不能缩的更短了。
要注意面试者的哪些错误?
有一些常见的错误是面试者的通病,需要在面试反馈中记下来:
1.在没弄清楚题目之前就开始写代码。 比如题目的输入是一个数字,面试者有可能假设这个数字是整数而直接写代码。
2.没有想清楚思路就开始写代码。 经常有面试者写着写着发现思路不对,于是删了代码重写。这个时候时间已经过了一半。大部分情况下,做开发之前都要弄清楚需求,不然很有可能会做无用功。以上两个问题都可以反映出面试者是不是有犯这类问题的潜质。
3.代码没有处理一些明显的 edge case。如果一个人的代码只能在 80%的情况下运行,环境稍微特殊一点就会 crush,那么你以后审核他的代码必须要小心翼翼,这样的人招到组里来大家都很累。
4.写代码很慢。 大部分公司都需要程序员可以高效的开发。这里就不赘述了。
5.代码不规范。 写出清晰漂亮的代码应该是深深刻在每个程序员骨子里的东西。面试的时候虽然时间紧张,但是有些时候一个空格、一个换行都应该是习惯性的肌肉记忆。如果代码写的很乱一定程度上反映出了面试者平时的编程的习惯。
6.基础知识缺乏。 从简单的时间和空间复杂性到常用的数据结构,都应该是各个层次的面试者要熟练掌握的。
7.沟通能力较差。 无法清晰的解释自己的思路或者代码。这个在工作沟通当中效率会受到影响,招进来需要进一步培训。
如何写好面试反馈?
1.Facebook 最常用的是“加减号”记录法:按时间顺序记录面试者的 data points,用加减号区分加分项和减分项。比如:
+清晰的描述了解题思路,并确认了输入数值的范围。
-没有处理输入值是 0 的情况
这样时候我们可以清晰明了的看出面试者的优缺点。
1.要有一个概括总结。 上一条提到我们提到按时间顺序记录面试的过程,但是这个过程往往很长,我们还需写出简单干练的总结,概括出面试者在各项能力上的表现。这样别人在看你写的反馈的时候就不需要通读全文了。
2.备份面试者的代码。 如果是在线面试,只需要把代码复制一下。如果是在白板上,那么请照相,然后贴在反馈里。
3.为了提高效率,我会准备一个反馈模板。 填空要比每次重头写更有效率。也可以防止漏掉重要的信息和考察点。
如何决定是不是给 offer?
无论是否给 offer,很多时候都是一个艰难的决定。当两难的时候,我通常问自己的问题是:我愿不愿意在未来的几年里,和这个人坐在一起,共同开发一个项目? 这个通常是一个很实用的标准。
如果遇到十分极端的情况,你在问完自己这个问题以后还是不确定,那么就不要给 offer。一个好的 hire 一定是让你和他/她一起工作你会很兴奋。如果做不到的话,宁缺毋滥。
面试官要注意什么?
面试是双向的。面试不仅是我们考察面试者是否合格,也同样是面试者考察这个公司或者这个组是否值得加入。我们经常看到因面试体验很差在网上吐槽的事情。这对公司来说是个极其负面的宣传。所以请在面试的时候尊重面试者,无论他看起来是否符合你的招聘标准。通常 Facebook 要求面试官做到一下几点:
1.关闭手机的消息提醒。频繁的震动会给面试者带来不必要的压力,也会打断面试者的思路。
2.用电脑之前告诉面试者你是在记笔记,而不是在处理自己的事情。
3.态度要友善、专业。
如何培训面试官?
Facebook 一般在面试官上任之前要经过如下四个步骤:
1.在公司呆满三个月,这样对公司的文化才有一定的了解。
2.经过一个小时的面试培训,培训的内容已经包括在上文中了。
3.shadow interview 一轮,也就是在旁边看资深面试官是怎么面试的。
4.Reverse-shadow inteview 这轮面试的时候有资深面试官在旁边观察你,如果你通过考察之后就可以独立面试了。
写在最后
乔布斯曾经说过“一流的人只愿跟一流的人在一起,如果有二流的人进来,就会有三流、四流、不入流的人进来”。找到一流的人才会给公司带来更多一流的人才。所以作为公司的面试官,一定要为公司把好关。
作者:
何平洋,前 Facebook Tech Lead(五年),现担任吴恩达公司(Landing,AI)Tech Lead,关注人工智能、大数据、人工智能平台、广告排序。
评论 9 条评论