编程技术面试的五大要点

  (写在前面的话:本文最初发表于《程序员》杂志2011年10月刊,并收录到《剑指Offer——名企面试官精讲典型编程题》一书中。)


  近年来找工作一直是一个很热门的话题。我们要想找到心仪的工作,难免需要经过很多轮面试。编程面试是程序员面试过程中最为重要的一个环节。如果能在编程面试的环节充分展示自己的能力,那么拿到中意的Offer就是水到渠成的事情。笔者先后在欧特克、微软和思科等知名公司任软件工程师,多次接受他人的面试,同时也面试过很多人。总结面试与被面试的经验,笔者发现尽管面试官的背景、性格各不相同,但都关注应聘者五种素质:(1)扎实的基础知识、(2)能写高质量的代码、(3)分析问题时思路清晰、(4)能优化时间效率和空间效率、(5)具备包括学习能力、沟通能力、发散思维能力等在内的综合能力。


扎实的基础知识

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

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

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

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


高质量的代码

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

  举个很多应聘者都被问过的一个问题:写一个函数,把字符串转化成整数。这道题看似很简单,绝大部分计算机专业的毕业生都能用十行以内的代码实现最基本的功能。可是在实际面试过程中,十个应聘者中只有一个人能通过这道题的面试,因为绝大部分应聘者不能全面各种特殊输入,比如输入的字符串含中有非数字的符号、在字符串的开头有正负号、字符串中有正负号但其位置不是在字符串的开头。除此之外,面试官还希望应聘者能考虑的边界条件包括2147483647(0x7FFFFFFF,int能表示的最大正整数)和-2147483648(0x80000000,int能表示的最小负整数)。

  除了边界条件和特殊输入考虑不足之外,面试官还有一个不能容忍的错误就是程序崩溃。面试的时候有很多应聘者都会忘了对空指针做特殊处理而导致程序崩溃。如果面试的时候遇到链表、二叉树相关的题目,应聘者一定要特别小心。因为这两种题目对应的代码里通常会有大量的指针操作,如果考虑不周到,就有可能对空指针进行操作而使程序崩溃。比如这样的一道题:输入一个链表的头指针和一个无符号整数k,输出该链表的倒数第k个结点。这个题目很多人都能想到用两个指针来解决这个问题:第一个指针先在链表上移动k-1步,然后同时让第一个指针和第二个指针在链表上移动。当第一个指针移动到尾指针的时候,第二个指针指向的就是倒数第k个结点。然而不是每个应聘者都能根据正确思路写出完整的代码。不少应聘者会忽略两种可能:一是输入的链表头指针有可能是空指针;二是链表上结点的数目有可能少于k个。忽略这两点的代码都存在崩溃的可能,不是鲁棒的程序,从而很也很难获得面试官的青睐。

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


清晰的思路

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

  应聘者可以用几个简单的方法帮助自己形成清晰的思路。首先是举几个简单的具体例子让自己理解问题。当我们一眼看不出问题中隐藏的规律的时候,可以试着用一两个具体的例子模拟操作的过程,这样说不定就能通过具体的例子找到抽象的规律。其次可以试着用图形表示抽象的数据结构。像分析与链表、二叉树相关的题目,我们都可以画出它们的结构图来简化题目。最后可以试着把复杂的问题分解成若干个简单的子问题,再一一解决。很多基于递归的思路,包括分治法和动态规划法,都是把复杂的问题分解成一个或者多个简单的子问题。

  比如把二叉搜索树转化排序的双向链表这个问题就很复杂。碰到这个问题,我们不妨先画出一两个具体的二叉搜索树及其对应的排序双向链表,直观地感受二叉搜索树和排序的双向链表有哪些联系。如果一下子找不出转换的规律,我们可以把整个二叉树看出三部分:根结点、左子树和右子树。当我们递归地把转换左右子树这两个子问题解决之后,再把转换左右子树得到的链表和根结点链接起来,整个问题也就解决了。


优化代码的能力

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

  要想优化时间或者空间效率,首先要知道如何分析效率。即使是同一个算法,用不同方法实现的效率可能也会大不相同,我们要能够分析出算法及其代码实现的效率。例如求斐波那契数列,很多人喜欢用递归公式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张扑克牌是不是顺子,考查应聘者能不能把问题抽象出来用合理的数据结构表示,并找到其中的规律解决这个问题。面试官也可以限制应聘者不得使用常规方法,这要求应聘者具备创新精神,能够打开思路从多角度去分析、解决问题。比如面试官要求应聘者不用加减乘除四则运算实现两个整数的加法。此时面试官期待应聘者能够打开思路,用位运算实现整数的加法。


小结

  我们可以用下图总结应聘者需要具备的素质。

图1:应聘者需要具备的素质

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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454649.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

访问linux服务主机,如何把Linux配置为日志服务主机。

如网络设备很多,可把同类的设备配置为相同的设备号例:more switch.log | grep X.X.X.X //查看某一设备的日志审核和记录系统的事件是非常重要的。如果仅仅把系统事件作为日志记录下来,而不去查看,还是无济于事。可用webadmin管理和…

WSARecv() 函数使用解析

详情参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms741688(vvs.85).aspx 简述 The WSARecv function receives data from a connected socket or a bound connectionless socket. The WSARecv function provides some additional features comp…

获取 docker 容器(container)的 ip 地址

获取单个IP docker inspect --format {{ .NetworkSettings.IPAddress }} <container-ID> 获取所有容器IP docker inspect -f {{.Name}} - {{.NetworkSettings.IPAddress }} $(docker ps -aq)转载于:https://www.cnblogs.com/Tempted/p/7774789.html

山西台达plc可编程控制器_可编程控制器2(PLC)控制原理

采用继电器控制采用PC控制PC的控制原理(继电器PC控制)a)当SB1按下&#xff0c;输入继电器00000的线圈通电&#xff0c;00000的常开触点闭合&#xff0c;使得输出继电器01000的线圈得电&#xff0c;01000对应的硬输出触电闭合&#xff0c;KM1得电M1开始运转&#xff0c;同时0100…

一篇读懂 可转债

可转债兴起的原因 可转债是1992年底开始进入中国证券市场的&#xff0c;到现在已经27个年头了。可以说&#xff0c;以前可转债在中国证券市场一直不是市场的焦点和幸运儿&#xff0c;始终没能成为一个上规模的可配置的投资品种——其原因很简单&#xff0c;因为相对而言企业发…

bodhi linux 安装 ubuntu软件,Bodhi Linux 5.1.0 发布,基于Ubuntu的轻量级发行版

Bodhi Linux是基于Ubuntu的轻量级发行版&#xff0c;具有Moksha桌面环境。现在有很多Linux发行版。有些是独特的&#xff0c;但很多是重复的&#xff0c;可能没有存在的必要。由于使用了Moksha桌面环境&#xff0c;一个基于Linux的操作系统Bodhi脱颖而出。如果你不熟悉Bodhi&am…

谈一谈周公所理解的面试

因为公司最近招聘的力度很大&#xff0c;所以最近公司的面试很多&#xff0c;加之很多同事项目紧&#xff0c;所以让我参加了一些技术面试。不论是作为面试官还是应聘者&#xff0c;参加工作以来我参与的面试的次数我自己也记不清了&#xff0c;所以在此想从面试官和应聘者的角…

idc机房运维巡检_智和信通赋能国产信创 建设IT智能监控运维体系 - 蔚颖willing...

作为信创领域深耕多年的企业&#xff0c;北京智和信通技术有限公司始终坚持研发自主知识产权的IT智能运维监控大数据分析系统——智和网管平台SugarNMS&#xff0c;积极探索AIOps智能运维&#xff0c;通过“国产安全监控分析安管日志运维开发”七合一模式&#xff0c;赋能IDC数…

long long or int

long long or int 很多时候long long爆空间&#xff0c;int有时又不够 。 在算乘法的时候&#xff0c;要保证乘出来的中间项也不爆long long 转载于:https://www.cnblogs.com/war1111/p/7532412.html

用Python的Tultle模块创建一个五角星

方案所需准备Python官方手册。 这里是我找到的中文版。一个可执行Python的解释器Ttultle简介来源乌龟图形是一个不错的方式来为孩子们介绍编程。它是Wally Feurzig和Seymour Papert在1966年开发的原始Logo编程语言的一部分。想象一只在x-y平面上&#xff0c;从&#xff08;0,0&…

镜像上传到linux失败,Docker push镜像失败解决方法

Docker push镜像失败解决方法发布时间&#xff1a;2017-03-09 12:07来源&#xff1a;互联网当前栏目&#xff1a;web技术类Docker push镜像失败的问题。以下是输入push自己的tomcat后出现了失败[rootslave3 ~]# docker push lekkoliu/tomcat8:latestThe push refers to a repos…

Python 之 Python2 和 Python3 的区别

1、默认编码方式 # Python2 默认编码方式是 ascll码 # Python3 默认编码方式是 utf-8 # Python2 输出中文要加 # -*- encoding:utf-8 -*- # Python3 不需要 2、print # Python2 可以使用 print&#xff0c;也可以使用 print() 例&#xff1a; print(lili) 或 print lili # Py…

【C/C++开发】C++11 并发指南二(std::thread 详解)

上一篇博客《C11 并发指南一(C11 多线程初探)》中只是提到了 std::thread 的基本用法&#xff0c;并给出了一个最简单的例子&#xff0c;本文将稍微详细地介绍 std::thread 的用法。 std::thread 在 <thread> 头文件中声明&#xff0c;因此使用 std::thread 时需要包含 &…

【找工作资料】外企面试技巧

这里谈谈面试的技巧。这是根据诚迅联丰咨询公司许国庆在北大光华管理学院、经济学院和清华经济管理学院的讲座整理出来的。他曾在美国的投资银行和商业银行工作了近十年。 一、面试前的准备 1&#xff0e;确定3W 明确面试前的三要素&#xff0d;When (时间)、Where&#xf…

触摸屏Sensor叠构实例学习记录(一)

现在从事TP这个行业&#xff0c;看再多的资料和介绍&#xff0c;不如直接拿个实例的工程图来看&#xff0c;分析每一部分具体是什么东西&#xff0c;比看再多的资料更容易入门。 以下图纸和图片都是我从网上随便下的&#xff0c;仅次于学习记录使用&#xff0c;不做另外的商业用…

linux查找influx的安装位置,InfluxDB学习之InfluxDB的安装和简介 | Linux大学

最近用到了 InfluxDB&#xff0c;在此记录下学习过程&#xff0c;同时也希望能够帮助到其他学习的同学。本文主要介绍InfluxDB的功能特点以及influxDB的安装过程。更多InfluxDB详细教程请看&#xff1a;InfluxDB系列学习教程目录一、InfluxDB 简介InfluxDB 是用Go语言编写的一个…

Python 之数据类型

文章收集于网络&#xff0c;如有版权&#xff0c;请联系作者 一、引子 1 什么是数据&#xff1f; x10&#xff0c;10是我们要存储的数据 2 为何数据要分不同的类型 数据是用来表示状态的&#xff0c;不同的状态就应该用不同的类型的数据去表示 3 数据类型 数字、字符串、列表…

Jquery中$(document).ready(function(){ })函数的使用详解

Jquery是优秀的Javascrīpt框架,$是jquery库的申明&#xff0c;它很不稳定&#xff08;我就常遇上&#xff09;,换一种稳定的写法jQuery.noConflict(); jQuery(document).ready(function(){}); 使用jQuery的好处是它包装了各种浏览器版本对DOM对象(javascript的DOM对象你应该知…

爬虫数据executemany插入_金融数据的获取——一个爬虫的简单例子

对量化投资策略进行研究&#xff0c;第一步就是获取我们需要的数据。使用历史数据能够对策略进行回测&#xff0c;以验证策略的有效性和可信性。另一方面&#xff0c;量化投资本身也是一种对数据的研究&#xff0c;因此它也必须遵循数据分析的相关步骤。作为一个业余的量化投资…

洛谷 P1736 创意吃鱼法

P1736 创意吃鱼法 题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中&#xff0c;然后开始思考&#xff1a;到底要以何种方法吃鱼呢&#xff08;猫猫就是这么可爱&#xff0c;吃鱼也要想好吃法 ^_*&#xff09;。她发现&#xff0c;把大池子视为01矩阵&#xff0…