扎实的基础知识、高质量的代码、清晰的思路、优化代码的能力、的综合能力是编程技术面试的五大要点。

  找工作一直是一个热门话题。要想找到心仪的工作,难免需要经过多轮面试。编程面试是程序员面试过程中为重要的一个环节。如果能在编程面试的环节充分展示自己的能力,那么拿到中意的Offer是水到渠成的事情。

  我先后在欧特克、微软和思科等公司任软件工程师,多次接受他人的面试,同时也面试过很多人。总结面试与被面试的经验,我发现尽管面试官的背景、性格各不相同,但都关注应聘者五种素质:扎实的基础知识;能写高质量的代码;分析问题时思路清晰;能优化时间效率和空间效率;具备包括学习能力、沟通能力、发散思维能力等在内的综合能力。

  扎实的基础知识

  扎实的基本功是成为程序员的前提条件,因此面试官首要关注应聘者的素质即是否具备扎实的基础。通常基本功在编程面试环节体现在两个方面:一是编程语言,二是数据结构和算法。

  每个程序员至少要熟练掌握1~2门编程语言。面试官从应聘者在面试过程中写的代码以及跟进的提问中,能看出他编程语言掌握的熟练程度。以大部分公司面试要求的C++为例,如果函数需要传入一个指针,面试官可能会问是否需要为该指针加上const,把const加在指针不同的位置有什么区别;如果写的函数需要传入的参数是一个复杂类型的实例,面试官可能会问传入值参数或者引用参数有什么区别,什么时候需要为传入的引用参数加上const。

  数据结构通常是编程面试过程中考查的重点。在参加面试之前,应聘者需要熟练掌握链表、树、栈、队列以及哈希表等数据结构以及它们的操作。如果我们留心各大公司的面试题,会发现链表和二叉树相关的问题是很多面试官喜欢问的问题。这方面的问题看似简单,但真正掌握也很不容易,特别适合在短短几十分钟的面试时间内检验应聘者的基本功。如果应聘者事先对链表的插入和删除结点了如指掌,对二叉树的各种遍历方法的循环和递归写法都烂熟于胸,那么真正到了面试时也游刃有余了。

  大部分公司对算法的要求都只是考查查找和排序。应聘者可以在了解各种查找和排序算法的基础上,重点掌握二分查找、归并排序和快速排序,因为很多面试题都只是这些算法的变体而已。比如把排序好的数组的前面若干个数字移到数组的后面,然后问怎样在这个数组之中找到小的数字。这道题其本质是考查二分查找。少数对算法很重视的公司比如谷歌或者百度,还会要求应聘者熟练掌握动态规划和贪婪算法。如果对这种类型的公司感兴趣,那么应聘者在参加面试之前应该加强对相关算法题目的练习。

  高质量的代码

  只有注重质量的程序员,才能写出鲁棒稳定的大型软件。在面试过程中,面试官总会格外关注边界条件、特殊输入等看似细枝末节但实质至关重要的地方,以此来分析应聘者是否注重代码质量。很多时候,面试官发现应聘者写出来的代码只能完成基本的功能,一旦输入特殊的边界条件参数会错误百出甚至程序崩溃。

  举个很多应聘者都被问过的一个问题:写一个函数,把字符串转化成整数。这道题看似很简单,绝大部分计算机专业的毕业生都能用十行以内的代码实现基本的功能。可是在实际面试过程中,十个应聘者中只有一个人能通过这道题的面试,因为绝大部分应聘者不能全面考虑到各种特殊输入,比如输入的字符串含中有非数字的符号、在字符串的开头有正负号、字符串中有正负号但其位置不是在字符串的开头。

  除此之外,面试官还希望应聘者能考虑的边界条件包括2147483647(0×7FFFFFFF,int能表示的大正整数)和-2147483648(0×80000000,int能表示的小负整数)。

  除了边界条件和特殊输入考虑不足之外,面试官还有一个不能容忍的错误是程序崩溃。面试时很多应聘者都会忘记对空指针做特殊处理而导致程序崩溃。如果面试时遇到链表、二叉树相关的题目,应聘者一定要特别小心。因为这两种题目对应的代码里通常会有大量的指针操作,如果考虑不周到,有可能对空指针进行操作而使程序崩溃。

  比如这样一道题:输入一个链表的头指针和一个无符号整数k,输出该链表的倒数第k个结点。这个题目很多人都能想到用两个指针来解决:第一个指针先在链表上移动k-1步,同时让第一个指针和第二个指针在链表上移动。当第一个指针移动到尾指针时,第二个指针指向的是倒数第k个结点。然而不是每个应聘者都能根据正确思路写出完整的代码。不少应聘者会忽略两种可能:一是输入的链表头指针有可能是空指针;二是链表上结点的数目有可能少于k个。忽略这两点的代码都存在崩溃的可能,从而很难获得面试官的青睐。

  要想写出鲁棒的高质量代码,需要在动手写代码之前想好测试用例。在写代码之前,先要想好各种边界条件和特殊输入作为测试用例。当代码写好之后,自己在心里用之前想好的测试用例来检验自己写出的代码,这样能在面试官之前发现并解决问题。以求链表的倒数第k个结点为例,如果事先想到了输入头指针为空指针和链表上的结点总数少于k这两个测试用例,并且在写好代码之后在心里模拟代码的运行过程,确保能够通过这两个测试用例的测试,那么这轮面试必然是能够通过的。