?/ 何v?/strong>
扎实的基知识、高质量的代码、清晰的思\、优化代码的能力、优U的综合能力是~程技术面试的五大要点?/p>
扑ַ作一直是一个热门话题。要x到心(j)仪的工作Q难免需要经q多轮面试。编E面试是E序员面试过E中最为重要的一个环节。如果能在编E面试的环节充分展示自己的能力,那么拿到中意的Offer是水到渠成的事情?/p>
我先后在Ƨ特克、微软和思科{公怓Q软g工程师,多次接受他h的面试,同时也面试过很多人。ȝ面试与被面试的经验,我发现尽面试官的背景、性格各不相同Q但都关注应聘者五U素质:(x)扎实的基知识Q能写高质量的代码;分析问题时思\清晰Q能优化旉效率和空间效率;具备包括学习(fn)能力、沟通能力、发散思维能力{在内的l合能力?span id="more-8435" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; ">
扎实的基知识
扎实的基本功是成ZUE序员的前提条gQ因此面试官首要x应聘者的素质x否具备扎实的基础。通常基本功在~程面试环节体现在两个方面:(x)一是编E语aQ二是数据结构和法?/p>
每个E序员至要熟练掌握1~2门编E语a。面试官从应聘者在面试q程中写的代码以?qing)跟q的提问中,能看Z~程语言掌握的熟l程度。以大部分公叔R试要求的C++ZQ如果函数需要传入一个指针,面试官可能会(x)问是否需要ؓ(f)该指针加上constQ把const加在指针不同的位|有什么区别;如果写的函数需要传入的参数是一个复杂类型的实例Q面试官可能?x)问传入值参数或者引用参数有什么区别,什么时候需要ؓ(f)传入的引用参数加上const?/p>
数据l构通常是编E面试过E中考查的重炏V在参加面试之前Q应聘者需要熟l掌握链表、树(wi)、栈、队列以?qing)哈希表{数据结构以?qing)它们的操作。如果我们留?j)各大公司的面试题,׃?x)发现链表和二叉树(wi)相关的问题是很多面试官喜Ƣ问的问题。这斚w的问题看似简单,但真正掌握也很不Ҏ(gu)Q特别适合在短短几十分钟的面试旉内检验应聘者的基本功。如果应聘者事先对链表的插入和删除l点?jin)如指掌Q对二叉?wi)的各种遍历?gu)的@环和递归写法都烂熟于胸,那么真正C(jin)面试时也游刃有余了(jin)?/p>
大部分公司对法的要求都只是考查查找和排序。应聘者可以在?jin)解各种查找和排序算法的基础上,重点掌握二分查找、归q排序和快速排序,因ؓ(f)很多面试题都只是q些法的变体而已。比如把排序好的数组的前面若q个数字Ud数组的后面,然后问怎样在这个数l之中找到最的数字。这道题其本质就是考查二分查找。少数对法很重视的公司比如h或者百度,q会(x)要求应聘者熟l掌握动态规划和贪婪法。如果对q种cd的公司感兴趣Q那么应聘者在参加面试之前应该加强对相关法题目的练?fn)?strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; ">
高质量的代码
只有注重质量的程序员Q才能写出鲁稳定的大型软g。在面试q程中,面试官M(x)格外x边界条g、特D输入等看似l枝末节但实质至关重要的地方Q以此来分析应聘者是否注重代码质量。很多时候,面试官发现应聘者写出来的代码只能完成最基本的功能,一旦输入特D的边界条g参数׃(x)错误癑և甚至E序崩溃?/p>
举个很多应聘者都被问q的一个问题:(x)写一个函敎ͼ把字W串转化成整数。这道题看似很简单,l大部分计算Z业的毕业生都能用十行以内的代码实现最基本的功能。可是在实际面试q程中,十个应聘者中只有一个h能通过q道题的面试Q因为绝大部分应聘者不能全面考虑到各U特D输入,比如输入的字W串含中有非数字的符受在字符串的开头有正负受字W串中有正负号但其位|不是在字符串的开头?/p>
除此之外Q面试官q希望应聘者能考虑的边界条件包?147483647Q?×7FFFFFFFQint能表C的最大正整数Q和-2147483648Q?×80000000Qint能表C的最负整数Q?/p>
除了(jin)边界条g和特D输入考虑不之外Q面试官q有一个不能容忍的错误是E序崩溃。面试时很多应聘者都?x)忘记对I指针做Ҏ(gu)处理而导致程序崩溃。如果面试时遇到链表、二叉树(wi)相关的题目,应聘者一定要特别心(j)。因两种题目对应的代码里通常?x)有大量的指针操作,如果考虑不周刎ͼ有可能对空指针q行操作而ɽE序崩溃?/p>
比如q样一道题Q输入一个链表的头指针和一个无W号整数kQ输?gu)链表的倒数Wk个结炏V这个题目很多h都能惛_用两个指针来解决Q第一个指针先在链表上Udk-1步,同时让第一个指针和W二个指针在链表上移动。当W一个指针移动到指针时Q第二个指针指向的就是倒数Wk个结炏V然而不是每个应聘者都能根据正思\写出完整的代码。不应聘者会(x)忽略两种可能Q一是输入的链表头指针有可能是空指针Q二是链表上l点的数目有可能于k个。忽略这两点的代码都存在崩溃的可能,从而很难获得面试官的青睐?/p>
要想写出鲁棒的高质量代码Q需要在动手写代码之前想好测试用例。在写代码之前,先要惛_各种边界条g和特D输入作为测试用例。当代码写好之后Q自己在?j)里用之前想好的试用例来检验自己写出的代码Q这样就能在面试官之前发现ƈ解决问题。以求链表的倒数Wk个结点ؓ(f)例,如果事先惛_?jin)输入头指针为空指针和链表上的结?gu)L于kq两个测试用例,q且在写好代码之后在?j)里模拟代码的运行过E,保能够通过q两个测试用例的试Q那么这轮面试必然是能够通过的?/p>
清晰的思\
只有思\清晰Q应聘者才有可能在面试q程中解军_杂的问题。有旉试官?x)有意出一些比较复杂的问题Q以考查能否在短旉内Ş成清晰的思\q解决问题。对于确实很复杂的问题,面试官甚至不期待应聘者能在面试不C个小时的旉里给出完整的{案Q他更看重的可能q是应聘者是否有清晰的思\。面试官通常不会(x)喜欢应聘者在没有形成清晰思\之前p率地开始写代码Q结果写出来的代码容易逻辑混ؕ、错误百出?/p>
应聘者可以用几个单的Ҏ(gu)帮助自己形成清晰的思\?/p>
首先是D几个单的具体例子让自q解问题。当一眼看不出问题中隐藏的规律Ӟ可以试着?~2个具体的例子模拟操作的过E,q样说不定就能通过具体的例子找到抽象的规律?/p>
其次可以试着用图形表C抽象的数据l构。像分析与链表、二叉树(wi)相关的题目时Q可以画出它们的l构图来化题目?/p>
最后可以试着把复杂的问题分解成若q个单的子问题,再一一解决。很多基于递归的思\Q包括分L和动态规划法Q都是把复杂的问题分解成一个或者多个简单的子问题?/p>
比如把二叉搜索树(wi)转化排序的双向链表这个问题就很复杂。碰到这个问题,不妨先画?~2个具体的二叉搜烦(ch)?wi)?qing)其对应的排序双向链表Q直观地感受二叉搜烦(ch)?wi)和排序的双向链表有哪些联系。如果一下子找不?gu){换的规律Q可以把整个二叉?wi)看Z部分Q根l点、左子树(wi)和右子树(wi)。当递归地把转换左右子树(wi)q两个子问题解决之后Q再把{换左叛_?wi)得到的链表和根l点链接hQ整个问题也p决了(jin)?/p>
优化代码的能?/strong>
优秀的程序员Ҏ(gu)间和I间的消耗锱铢必较,他们很有Ȁ情不断优化自q代码。当面试官出的题目有多种解法Ӟ通常他会(x)期待应聘者最l能够找到最优解。这p求应聘者在面试官提C有更好的解法Ӟ不能攑ּ思考,而应该努力寻扑֜旉消耗或者空间消耗上可以优化的地斏V?/p>
要想优化旉或者空间效率,首先要知道如何分析效率。即使是同一个算法,用不同方法实现的效率可能也会(x)大不相同Q要能够分析出算法及(qing)其代码实现的效率。例如求斐L那契数列Q很多h喜欢用递归公式f(n)=f(n-1)+f(n-2)求解。如果分析它的递归调用?wi),׃?x)发现有大量的计算是重复的Q时间效率是以n的指数增加。但如果先求f(1)、f(2)Q再Ҏ(gu)f(1)和f(2)求出f(3)Q接下来Ҏ(gu)f(2)、f(3)求出f(4)Qƈ以此cL用一个@环求出f(n)Q这U计方法的旉效率只有O(n)Q比前面递归的方法要好很多?/p>
要想优化代码的效率,q要熟知各种数据l构的优~点Qƈ能选择合适的数据l构解决问题。我们在数组中根据下标可以用O(1)完成查找。数l的q个特征可以用来实现单的哈希表解军_多面试题Q比如在字符串中扑ֈW一个只出现一ơ的字符。再比如Z(jin)扑ևn个数字中最的k个数Q需要一个数据容器来存储k个数字。在q个数据容器中,我们希望能够快速地扑ֈ最大值ƈ且能快速地替换其中的数字。经q权衡,我们发现二叉?wi)比如最大堆或者红黑树(wi)都是实现q个数据容器的理想选择?/p>
要想优化代码的效率,也要熟练掌握常用的算法。面试中最常用的算法是查找和排序。如果从头到N序扫描一个数l,需要O(n)旉才能完成查找操作。但如果数组是排序的Q应用二分查扄法就能把旉复杂度降低到O(logn)。排序算法除?jin)能够给数组排序之外Q还能用来解军_他问题。比如快速排序算法中的Partition函数能够用来在n个数里查扄k大的数字Q从而可以用O(n)的时间在数组中找到出现次数超q数l长度一半的数字。如果面试题是一个求最大值或者最值的题目Q则可以试用动态规划法或者贪婪算法,比如用动态规划法求出数组中连l子数组的最大和?/p>
优秀的综合能?/span>
在面试过E中Q应聘者除?jin)展Cq~程能力和技术功底之外,q需要展Cq软技能,诸如沟通能力和学习(fn)能力?strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; ">随着软gpȝ的规模越来越大,软g开发已l告别了(jin)单打独斗的年代,E序员与他h的沟通变得越来越重要?/strong>在面试过E中Q面试官?x)观察应聘者在介绍目l验或者算法思\时是否观Ҏ(gu)、逻辑清晰Qƈ以此判断他沟通能力的强弱。另外,面试官也?x)从应聘者说话的态和语气来判断他是否有团队合作的意识。通常面试官不?x)喜Ƣ高傲或者轻视合作者的人?/p>
IT行业知识更新很快Q因此程序员只有具备很好的学?fn)能力才能跟上知识更替的步伐。通常面试官有两种办法考查应聘者的学习(fn)能力。第一U方法是询问应聘者最q在看什么书、从中学C(jin)哪些新技术。面试官可以用这个问题了(jin)解应聘者的学习(fn)愿望和学?fn)能力。第二种Ҏ(gu)是抛Z个新概念Q接下来他会(x)观察应聘者能不能在较短时间内理解q个新概念ƈ解决相关的问题。比如面试官要求应聘者计第1500个丑数。很多h都没有听说过丑数q个概念。这旉试官׃(x)观察应聘者面对丑数这个新概念Q能不能l过提问、思考、再提问的过E,最l找Z数的规律从而找到解x案?/p>
知识q移能力是一U特D的学习(fn)能力。如果我们能够把已经掌握的知识迁Ud其他领域Q那么学?fn)新技术或者解x问题׃(x)变得Ҏ(gu)。面试官l常?x)先问一个简单的问题Q再问一个很复杂但和前面的简单问题相关的问题。这旉试官期待应聘者能够从单问题中得到启示Q从而找到解军_杂问题的H门。比如面试官先要求应聘者写一个函数求斐L那契数列Q再问一个青蛙蟩台阶的问题:(x)一只青蛙一ơ可以蟩?U台Ӟ也可以蟩?U台Ӟ请问q只青蛙跳上nU的台阶d有多种xQ应聘者如果具有较强的知识q移能力Q就能分析出青蛙跛_阉题实质上只是斐L那契数列的一个应用?/p>
q有不少面试官喜Ƣ考查应聘者的抽象建模能力和发散思维能力。面试官从日常生zM提炼出问题,比如如何判断5张扑克牌是不是顺子,考查应聘者能不能把问题抽象出来用合理的数据结构表C,q找到其中的规律解决q个问题。面试官也可以限制应聘者不得用常规方法,q要求应聘者具备创新精,能够打开思\从多角度d析、解决问题。比如面试官要求应聘者不用加减乘除四则运实C个整数的加法。此旉试官期待应聘者能够打开思\Q用位运实现整数的加法?/p>
结
我们可以用下图来ȝ出应聘者需要具备的素质?/p>
从上囑֏以看出,应聘者在面试之前需要做_备,对编E语a、数据结构和法{基知识有全面的?jin)解。面试时如果到单的问题应聘者一定要注重l节写出完整、鲁的代码。如果碰到复杂的问题应聘者可以通过d、D具体例子分析和分解复杂问题等Ҏ(gu)先理清思\再动手编E。除此之外,应聘者还应该不断优化旉效率和空间效率,力求扑ֈ最优的解法。在面试q程中,应聘者还应该d提问弄清楚题目的要求Q表现自q沟通能力。当面试官前后问的两个问题有相关性时Q尽量把解决前面问题的思\q移到后面的问题中去Q展Cp好的学习(fn)能力。如果能做到q么几点Q那么应聘者顺利通过面试获得?j)A的职位将是瓜熟蒂落的事情?/p>
在读《Accelerated c++》时Q对" while(cin>>x) " 感到疑惑?N cin ?x)变为NULL么?不然要死循环?jin)。猜?io 应该重蝲?bool 函数?特{载这博文?/em>
C++的运符重蝲功能真的很强大,除了(jin)可以重蝲常规q算W(比如Q? - * / > < = etc. Q也可以重蝲cd转换q算W(比如, (int) (bool) (char *) etc. Q?L(fng)下面的例子,cStudent重蝲?jin)运?(bool) .
#include <iostream>
using namespace std;
class Student
{
public:
Student(bool _isok = true) : isok(_isok){}
operator bool()
{
return isok;
}
bool isok;
~Student(){}
};
int main(int argc, char *argv[])
{
Student a(true), b(false);
cout<<((bool)a)<<endl;
cout<<((bool)b)<<endl;
if( a )
cout<<"a is ok"<<endl;
if( b )
cout<<"b is ok"<<endl;
return 0;
}
q行l果Q?/p>
1
0
a is ok
注意看那两个if语句Q?l果中只出现“a is ok”Q说明if语句条g表达式隐含地q行?jin)类型{换(转换成bool型)(j)Q这P我们p理解Qؓ(f)什么可以写q样的语句:(x)
int n;
if ( cin>>n )
{
......
}
可以推断Qio类也重载了(jin)bool型{换运符?/u>