编程技术面试的五大要点

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

找工做一直是一个热门话题。要想找到心仪的工做,不免须要通过多轮面试。编程面试是程序员面试过程当中最为重要的一个环节。若是能在编程面试的环节充分展现本身的能力,那么拿到中意的Offer就是水到渠成的事情。面试

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

扎实的基础知识编程

扎实的基本功是成为优秀程序员的前提条件,所以面试官首要关注应聘者的素质便是否具有扎实的基础。一般基本功在编程面试环节体如今两个方面:一是编程语言,二是数据结构和算法。设计模式

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

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

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

高质量的代码编程语言

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

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

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

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

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

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

清晰的思路

只有思路清晰,应聘者才有可能在面试过程当中解决复杂的问题。有时面试官会有意出一些比较复杂的问题,以考查可否在短期内造成清晰的思路并解决问 题。对于确实很复杂的问题,面试官甚至不期待应聘者能在面试不到一个小时的时间里给出完整的答案,他更看重的可能仍是应聘者是否有清晰的思路。面试官一般 不会喜欢应聘者在没有造成清晰思路以前就草率地开始写代码,结果写出来的代码容易逻辑混乱、错误百出。

应聘者能够用几个简单的方法帮助本身造成清晰的思路。

首先是举几个简单的具体例子让本身理解问题。当一眼看不出问题中隐藏的规律时,能够试着用1~2个具体的例子模拟操做的过程,这样说不定就能经过具体的例子找到抽象的规律。

其次能够试着用图形表示抽象的数据结构。像分析与链表、二叉树相关的题目时,能够画出它们的结构图来简化题目。

最后能够试着把复杂的问题分解成若干个简单的子问题,再一一解决。不少基于递归的思路,包括分治法和动态规划法,都是把复杂的问题分解成一个或者多个简单的子问题。

好比把二叉搜索树转化排序的双向链表这个问题就很复杂。碰到这个问题,不妨先画出1~2个具体的二叉搜索树及其对应的排序双向链表,直观地感觉二叉 搜索树和排序的双向链表有哪些联系。若是一会儿找不出转换的规律,能够把整个二叉树看出三部分:根结点、左子树和右子树。当递归地把转换左右子树这两个子 问题解决以后,再把转换左右子树获得的链表和根结点连接起来,整个问题也就解决了。

优化代码的能力

优秀的程序员对时间和空间的消耗锱铢必较,他们颇有激情不断优化本身的代码。当面试官出的题目有多种解法时,一般他会期待应聘者最终可以找到最优解。这就要求应聘者在面试官提示还有更好的解法时,不能放弃思考,而应该努力寻找在时间消耗或者空间消耗上能够优化的地方。

要想优化时间或者空间效率,首先要知道如何分析效率。即便是同一个算法,用不一样方法实现的效率可能也会大不相同,要可以分析出算法及其代码实现的效 率。例如求斐波那契数列,不少人喜欢用递归公式f(n)=f(n-1)+f(n-2)求解。若是分析它的递归调用树,就会发现有大量的计算是重复的,时间 效率是以n的指数增长。但若是先求f(1)、f(2),再根据f(1)和f(2)求出f(3),接下来根据f(2)、f(3)求出f(4),并以此类推用 一个循环求出f(n),这种计算方法的时间效率就只有O(n),比前面递归的方法要好不少。

要想优化代码的效率,还要熟知各类数据结构的优缺点,并能选择合适的数据结构解决问题。咱们在数组中根据下标能够用O(1)完成查找。数组的这个特 征能够用来实现简单的哈希表解决不少面试题,好比在字符串中找到第一个只出现一次的字符。再好比为了找出n个数字中最小的k个数,须要一个数据容器来存储 k个数字。在这个数据容器中,咱们但愿可以快速地找到最大值而且能快速地替换其中的数字。通过权衡,咱们发现二叉树好比最大堆或者红黑树都是实现这个数据 容器的理想选择。

要想优化代码的效率,也要熟练掌握经常使用的算法。面试中最经常使用的算法是查找和排序。若是从头至尾顺序扫描一个数组,须要O(n)时间才能完成查找操 做。但若是数组是排序的,应用二分查找算法就能把时间复杂度下降到O(logn)。排序算法除了可以给数组排序以外,还能用来解决其余问题。好比快速排序 算法中的Partition函数可以用来在n个数里查找第k大的数字,从而能够用O(n)的时间在数组中找到出现次数超过数组长度一半的数字。若是面试题 是一个求最大值或者最小值的题目,则能够尝试用动态规划法或者贪婪算法,好比用动态规划法求出数组中连续子数组的最大和。

优秀的综合能力

在面试过程当中,应聘者除了展现本身的编程能力和技术功底以外,还须要展现本身的软技能,诸如沟通能力和学习能力。随着软件系统的规模愈来愈大,软件开发已经告别了单打独斗的年代,程序员与他人的沟通变得愈来愈重要。在面试过程当中,面试官会观察应聘者在介绍项目经验或者算法思路时是否观点明确、逻辑清晰,并以此判断他沟通能力的强弱。另外,面试官也会从应聘者说话的神态和语气来判断他是否有团队合做的意识。一般面试官不会喜欢高傲或者轻视合做者的人。

IT行业知识更新很快,所以程序员只有具有很好的学习能力才能跟上知识更替的步伐。一般面试官有两种办法考查应聘者的学习能力。第一种方法是询问应 聘者最近在看什么书、从中学到了哪些新技术。面试官能够用这个问题了解应聘者的学习愿望和学习能力。第二种方法是抛出一个新概念,接下来他会观察应聘者能 不能在较短期内理解这个新概念并解决相关的问题。好比面试官要求应聘者计算第1500个丑数。不少人都没有据说过丑数这个概念。这时面试官就会观察应聘 者面对丑数这个新概念,能不能通过提问、思考、再提问的过程,最终找出丑数的规律从而找到解决方案。

知识迁移能力是一种特殊的学习能力。若是咱们可以把已经掌握的知识迁移到其余领域,那么学习新技术或者解决新问题就会变得容易。面试官常常会先问一 个简单的问题,再问一个很复杂但和前面的简单问题相关的问题。这时面试官期待应聘者可以从简单问题中获得启示,从而找到解决复杂问题的窍门。好比面试官先 要求应聘者写一个函数求斐波那契数列,再问一个青蛙跳台阶的问题:一只青蛙一次能够跳上1级台阶,也能够跳上2级台阶,请问这只青蛙跳上n级的台阶总共有 多少种跳法?应聘者若是具备较强的知识迁移能力,就能分析出青蛙跳台阶问题实质上只是斐波那契数列的一个应用。

还有很多面试官喜欢考查应聘者的抽象建模能力和发散思惟能力。面试官从平常生活中提炼出问题,好比如何判断5张扑克牌是否是顺子,考查应聘者能不能 把问题抽象出来用合理的数据结构表示,并找到其中的规律解决这个问题。面试官也能够限制应聘者不得使用常规方法,这要求应聘者具有创新精神,可以打开思路 从多角度去分析、解决问题。好比面试官要求应聘者不用加减乘除四则运算实现两个整数的加法。此时面试官期待应聘者可以打开思路,用位运算实现整数的加法。

小结

咱们能够用下图来总结出应聘者须要具有的素质。

未命名_副本

从上图能够看出,应聘者在面试以前须要作足准备,对编程语言、数据结构和算法等基础知识有全面的了解。面试时若是碰到简单的问题应聘者必定要注重细 节写出完整、鲁棒的代码。若是碰到复杂的问题应聘者能够经过画图、举具体例子分析和分解复杂问题等方法先理清思路再动手编程。除此以外,应聘者还应该不断 优化时间效率和空间效率,力求找到最优的解法。在面试过程当中,应聘者还应该主动提问弄清楚题目的要求,表现本身的沟通能力。当面试官先后问的两个问题有相 关性时,尽可能把解决前面问题的思路迁移到后面的问题中去,展现本身良好的学习能力。若是能作到这么几点,那么应聘者顺利经过面试得到心仪的职位将是瓜熟蒂 落的事情。

做者何海涛,思科高级软件工程师,以前前后任职于Autodesk和微软。主要关注C++/C#的开发技术,并对设计模式和项目管理也很感兴趣。

相关文章
相关标签/搜索