最近有一本很红的面试书叫《剑指Offer:名企面试官精讲典型编程题》,作者是美国微软总部资深软件工程师何海涛,他在书中以面试官的角度分享了程序员面试的方方面面,并且还在书中停供了80余道面试题,大部分是与数据结构和算法有关。本文不会重点分析这些面试题目,而是归纳总结书中所提到的一些面试相关的编程技能和软技能。
一、面试流程
1)面试的3种形式
第一种是电话面试,应聘者在投出简历一到二周之内,不仅要保证手机电池能连续通话一小时,还要避免长时间待在嘈杂的地方。电话面试没有了肢体语言、面部表情,应聘者表达自己想法的难度要比现场面试大很多,因此,应聘者尽可能用形象化的语言把细节说清楚。例如在电话面试中,如果想说一棵二叉树,就需要把二叉树中有哪些节点,每个节点的左子节点是什么、右子节点是什么都要说得很清楚,只有这样面试官才能准确地理解应聘者的思路。当不确定面试官的问题的时候,应聘者一定要大胆地向面试官多提问,直到弄清楚面试官的意图为止,切忌不懂装懂、答非所问。
第二种是共享桌面远程面试,利用一些共享桌面的软件,应聘者把自己电脑共享给远程的面试官。这样两个人虽然没有坐在一起,但是面试管却能通过共享桌面观看应聘者编程和调试的过程。这种形式的面试,面试关心的是应聘者的编程习惯和调试能力,通常面试官会认可应聘者下面几种编程习惯:
1、思考清楚再开始编码。
2、良好的代码命名和缩进对齐习惯。
3、能够进行单元测试。
当应聘者运行代码发现结果不对之后的表现,是面试官关注的重点,因为应聘者此时的反应、采取的措施都能体现出他的调试功底。如果应聘者能够熟练地设置断点、单步跟踪、查看内存、分析调用栈,就能很快发现问题的根源并最终解决问题,那么面试官将会觉得他的开发经验丰富,在写面试报告的时候是不会吝啬赞美之词的。
第三种是现场面试,在去公司参加现场面试之前,应聘者应该做好以下几点准备:
1、规划好线路并估算出行时间。
2、准备好得体的衣服。
3、注意面试邀请函里的面试流程。
4、准备几个问题。
现场面试是整个面试流程中的重头戏。由于是坐在面试官的对面,应聘者的一举一动都看在面试官眼里。面试官通过应聘者的语言和行动考察他的沟通能力、学习能力、编程能力等综合实力。
2)面试的3个环节
首先是行为面试,面试开始的5~10分钟通常是行为面试的时间。面试官在这段时间会注意应聘者的性格特点,深入了解简历中列举的项目经历。这是一个暖场的过程,应聘者可以利用这几分钟调整自己的情绪,进入面试状态。不少面试官会让应聘者做一个简短的自我介绍,而自我介绍不用花很多时间,用30秒到1分钟的时间介绍自己的主要学习、工作经历即可。如果面试官对某一段经历或者参与的某一个项目感兴趣,那么他会有针对性的提几个问题详细了解。
1、应聘者的项目经验建议用STAR模型描述,Situation:简短的项目背景;Task:自己完成的任务;Action:为完成任务自己做了哪些工作,是怎么做的;Result:自己的贡献。除此之外,面试官针对项目经验最常问的问题包括以下几个类型。
a)你在该项目中碰到的最大问题是什么,你是怎么解决的?
b)从这个项目中你学到了什么?
c)什么时候会和其他团队成员有什么样的冲突,你们是怎么解决冲突的?
2、应聘者掌握的技能,描述技能掌握程度时也要注意“了解”、“熟悉”和“精通”的区别。
a)了解是指对某项技能只是上过课或看过书,但没有做过实际的项目。不建议在简历中列出只是肤浅地了解一点的技能。
b)熟悉是指在实际项目中使用某项技能已经有很长的时间,通过查阅相关的文档可以独立解决大部分问题。简历中技能的掌握大部分应该是熟悉。
c)精通是指对一项技术使用的得心应手,在项目开发过程中,有信心也有能力解决各种问题。除非自己能轻松回答这个领域里的绝大多数问题,否则不要在简历中使用精通。
3、回答“为什么跳槽”。面试官会通过这个问题来了解应聘者的性格,在回答时不要抱怨,也不要流露出负面情绪。应聘者尽量避免以下4个原因:
a)老板太苛刻。
b)同事太难相处。
c)加班太频繁。
d)工资太低。
其次是技术面试,一轮一小时的面试,通常计算面试会占据40~50分钟,对面试的结果起决定性作用。总体来说,面试官都会关注应聘者的5种素质:
1、扎实的基础知识,包括编程语言、数据结构和算法。
2、能写出正确的、完整的、鲁棒(健壮)的高质量的代码,面试官会格外关注边界条件、特殊输入等看似细枝末节但至关重要的地方。
3、分析问题时思路清晰,面试官不喜欢应聘者草率地开始写代码,这样的代码容易逻辑混乱、错误百出。应聘者可以用几个简单的方法帮助自己形成清晰的思路。
a)举几个简单的例子让自己理解问题,举例能使抽象问题具体化。
b)用图形表示抽象的数据结构,图形能使抽象的问题具体化、形象化。
c)把复杂的问题分解成若干个简单的子问题,然后逐个击破。
4、能优化时间效率和空间效率,需要熟知各种数据结构的优缺点,并且熟练掌握常用的算法。
5、学习、沟通等各方面的能力。
a)面试官会观察应聘者在介绍项目经验或算法思路时是否观点明确、逻辑清晰,并以此判断其沟通能力的强弱。有意向加入外企的应聘者注意提高自己英语交流的能力。
b)面试官也会从应聘者说话的神态和语气来判断他是否有团队合作的意识。
c)面试官通过询问应聘者最近在看什么书、从中学到了哪些技术来了解应聘者的学习愿望和学习能力。
d)面试官抛出一个新概念,观察应聘者能否在短时间内理解新概念,期待他们通过思考、提问、再思考的过程,理解并最终解决相关问题。
e)建议应聘者在面试过程中遇到不明白的地方多提问,这样面试官会觉得你态度积极、求知欲强烈,会给面试结果加分。
f)知识迁移能力是一种特殊的学习能力,通俗的说法是举一反三,如果能够把已经掌握的知识迁移到其它领域,那么学习新技术或者解决新问题会变得容易。
g)不少面试官从日常生活中提炼出问题,考查应聘者的抽象建模能力和发散思维能力。
最后是应聘者提问,在结束面试前的5~10分钟,面试官会给应聘者机会问几个问题,应聘者的问题质量对面试的结果也有一定的影响。首先,不要问和自己的职位没有关系的问题,例如公司未来五年的发展战略是什么;其次,不要问薪水;再次,不要打听面试结果;最后,推荐问与应聘的职位或项目相关的问题。要问好这类问题可以从两方面去了解:一是面试前做足功课,到网上搜索一些相关的信息,做到对公司成立时间、主要业务、职位要求等都了然于胸;二是面试过程中留心面试官说过的话,他的话中可能会包含其它渠道无法得到的信息,例如项目进展情况等。
二、高质量的代码
1)代码的规范性
如果应聘者代码写得不够规范,影响面试官阅读代码的兴致,那么面试官就会默默地减去几分。书写、布局和命名都决定着代码的规范性。
首先,规范的代码书写清晰,在白板或白纸上写代码,要减慢写字的速度,尽量把每个字母写清楚,不要担心时间不够。其次,规范的代码布局清晰,离开了工具手写代码,格外要注意布局问题。最后,规范的代码命名合理,用完整的英文单词组合命名变量和函数。
2)代码的完整性
面试官会非常关注应聘者考虑问题是否周全。通过检查代码是否完整来考察应聘者的思维是否全面。
1、从功能测试、边界测试和负面测试3个方面确保代码的完整性。
a)功能测试保证写出的代码能够完成面试官要求的基本功能。
b)边界测试用于检查循环的边界条件是否正确,递归终止的边界值是否正确等。
c)负面测试需要考虑各种可能的错误输入,对其做出合理的错误处理。
2、通常有3种方式把错误信息传递给函数的调用者:
a)用返回值告知调用者是否出错。
b)当错误发生时设置一个全局变量。
c)当函数运行出错的时候,就抛出一个异常,根据不同出错原因定义不同的异常类型。
3)代码的鲁棒性
鲁棒性也称为健壮性,是指程序能够判断输入是否合乎规范要求,并对不符合要求的输入予以合理的处理。容错性是鲁棒性的一个重要提现。提高代码鲁棒性的有效途径是进行防御性编程。防御性编程是一种编程习惯,是指预见在什么地方可能会出现问题,并为这些可能出现的问题制定处理方式。在面试时,最简单也是最实用的防御性编程就是在函数入口添加代码以验证用户输入是否符合要求。