作者:何海涛 日期:2014-07-06 11:24:45
《剑指Offer——名企面试官精讲典型编程题(纪念版)》是为纪念本书英文版全球发行而推出的特殊版本,在原版基础上新增大量本书英文版中的精选题目,系统整理基础知识、代码质量、解题思路、优化效率和综合能力这5个面试要点。全书分为8章,主要包括面试流程:讨论面试每一环节需要注意的问题;面试需要的基础知识:从编程语言、数据结构及算法三方面总结程序员面试知识点;高质量代码:讨论影响代码质量的3个要素(规范性、完整性和鲁棒性),强调高质量代码除完成基本功能外,还能考虑特殊情况并对非法输入进行合理处理;解题思路:总结编程面试中解决难题的有效思考模式,如在面试中遇到复杂难题,应聘者可利用画图、举例和分解这3种方法将其化繁为简,先形成清晰思路再动手编程;优化时间和空间效率:读者将学会优化时间效率及空间换时间的常用算法,从而在面试中找到最优解;面试必备能力:总结应聘者如何充分表现学习和沟通能力,并通过具体面试题讨论如何培养知识迁移、抽象建模和发散思维能力;综合面试案例:总结哪些面试举动是不良行为,而哪些表现又是面试官所期待的行为;英文版面试题增补,优选久经欧美知名企业面试考验的经典题目,帮助国内读者开阔视野、增补技能。
《剑指Offer——名企面试官精讲典型编程题(纪念版)》适合即将走向工作岗位的大学生阅读,也适合作为正在应聘软件行业的相关就业人员和计算机爱好者的参考书。
目录:
第1章面试的流程1
1.1面试官谈面试1
1.2面试的三种形式2
1.2.1电话面试2
1.2.2共享桌面远程面试3
1.2.3现场面试4
1.3面试的三个环节5
1.3.1行为面试环节5第1章面试的流程1
1.1面试官谈面试1
1.2面试的三种形式2
1.2.1电话面试2
1.2.2共享桌面远程面试3
1.2.3现场面试4
1.3面试的三个环节5
1.3.1行为面试环节5
应聘者的项目经验6
应聘者掌握的技能7
回答“为什么跳槽”8
1.3.2技术面试环节10
扎实的基础知识10
高质量的代码11
清晰的思路14
优化效率的能力15
优秀的综合能力16
1.3.3应聘者提问环节17
1.4本章小结18
第2章面试需要的基础知识20
2.1面试官谈基础知识20
2.2编程语言22
2.2.1C++22
面试题1:赋值运算符函数24
经典的解法,适用于初级程序员25
考虑异常安全性的解法,高级程序员必备26
2.2.2C#27
面试题2:实现Singleton模式31
不好的解法一:只适用于单线程31
不好的解法二:可用于多线程但效率不高32
可行的解法:同步锁前后两次判断33
推荐的解法一:利用静态构造函数34
推荐的解法二:按需创建实例34
解法比较35
2.3数据结构36
2.3.1数组36
面试题3:二维数组中的查找38
2.3.2字符串42
面试题4:替换空格44
O(n2)的解法,不足以拿到Offer45
O(n)的解法,搞定Offer就靠它46
2.3.3链表49
面试题5:从尾到头打印链表51
2.3.4树53
面试题6:重建二叉树55
2.3.5栈和队列58
面试题7:用两个栈实现队列59
2.4算法和数据操作62
2.4.1查找和排序63
面试题8:旋转数组的最小数字66
2.4.2递归和循环71
面试题9:斐波那契数列73
效率很低的解法,面试官不会喜欢73
面试官期待的实用解法74
O(logn)但不够实用的解法74
解法比较75
2.4.3位运算77
面试题10:二进制中1的个数78
可能引起死循环的解法79
常规解法79
能给面试官带来惊喜的解法80
2.5本章小结82
第3章高质量的代码84
3.1面试官谈代码质量84
3.2代码的规范性86
3.3代码的完整性87
从3方面确保代码的完整性87
3种错误处理的方法88
面试题11:数值的整数次方90
自以为题目简单的解法90
全面但不够高效的解法,离Offer已经很近了90
全面又高效的解法,确保能拿到Offer92
面试题12:打印1到最大的n位数94
跳进面试官陷阱94
在字符串上模拟数字加法94
把问题转换成数字排列97
面试题13:在O(1)时间删除链表结点99
面试题14:调整数组顺序使奇数位于偶数前面102
只完成基本功能的解法,仅适用于初级程序员102
考虑可扩展性的解法,能秒杀Offer104
3.4代码的鲁棒性106
面试题15:链表中倒数第k个结点107
面试题16:反转链表112
面试题17:合并两个排序的链表114
面试题18:树的子结构117
3.5本章小结121
第4章解决面试题的思路123
4.1面试官谈面试思路123
面试题19:二叉树的镜像125
4.2画图让抽象问题形象化125
面试题20:顺时针打印矩阵127
4.3举例让抽象问题具体化131
面试题21:包含min函数的栈132
面试题22:栈的压入、弹出序列134
面试题23:从上往下打印二叉树137
面试题24:二叉搜索树的后序遍历序列140
面试题25:二叉树中和为某一值的路径143
4.4分解让复杂问题简单化146
面试题26:复杂链表的复制147
面试题27:二叉搜索树与双向链表151
面试题28:字符串的排列154
4.5本章小结158
第5章优化时间和空间效率160
5.1面试官谈效率160
5.2时间效率162
面试题29:数组中出现次数超过一半的数字163
基于Partition函数的O(n)算法163
利用数组特点的O(n)算法165
解法比较166
面试题30:最小的k个数167
O(n)的算法,只当可以修改输入数组时可用167
O(nlogk)的算法,适合处理海量数据168
解法比较169
面试题31:连续子数组的最大和171
举例分析数组的规律171
应用动态规划法173
面试题32:从1到n整数中1出现的次数174
不考虑效率的解法,想拿Offer有点难174
明显提高效率的解法,让面试官耳目一新175
面试题33:把数组排成最小的数177
5.3时间效率与空间效率的平衡181
面试题34:丑数182
逐个判断整数是不是丑数的解法182
创建数组保存已经找到的丑数的解法183
面试题35:第一个只出现一次的字符186
面试题36:数组中的逆序对189
面试题37:两个链表的第一个公共结点193
5.4本章小结196
第6章面试中的各项能力198
6.1面试官谈能力198
6.2沟通能力和学习能力200
沟通能力200
学习能力200
善于学习、沟通的人也善于提问201
6.3知识迁移能力203
面试题38:数字在排序数组中出现的次数204
面试题39:二叉树的深度207
重复遍历结点的解法,不足以打动面试官209
只遍历结点一次的解法,正是面试官喜欢的209
面试题40:数组中只出现一次的数字211
面试题41:和为s的两个数字VS和为s的连续正数序列214
面试题42:翻转单词顺序VS左旋转字符串218
6.4抽象建模能力222
面试题43:n个骰子的点数223
基于递归求骰子点数,时间效率不够高223
基于循环求骰子点数,时间性能好224
面试题44:扑克牌的顺子226
面试题45:圆圈中最后剩下的数字228
经典的解法,用循环链表模拟圆圈229
创新的解法,拿到Offer不在话下230
6.5发散思维能力232
面试题46:求1+2+…+n233
利用构造函数求解234
利用虚函数求解234
利用函数指针求解235
利用模板类型求解236
面试题47:不用加减乘除做加法237
面试题48:不能被继承的类239
常规的解法:把构造函数设为私有函数239
新奇的解法:利用虚拟继承240
6.6本章小结241
第7章两个面试案例243
7.1案例一:(面试题49)把字符串转换成整数244
7.2案例二:(面试题50)树中两个结点的最低公共祖先252
第8章英文版新增面试题261
8.1数组261
面试题51:数组中重复的数字261
面试题52:构建乘积数组263
8.2字符串265
面试题53:正则表达式匹配265
面试题54:表示数值的字符串267
面试题55:字符流中第一个不重复的字符269
8.3链表270
面试题56:链表中环的入口结点270
面试题57:删除链表中重复的结点273
8.4树275
面试题58:二叉树的下一个结点275
面试题59:对称的二叉树277
面试题60:把二叉树打印成多行278
面试题61:按之字形顺序打印二叉树280
面试题62:序列化二叉树283
面试题63:二叉搜索树的第k个结点285
面试题64:数据流中的中位数286
8.5栈和队列290
面试题65:滑动窗口的最大值290
8.6回溯法294
面试题66:矩阵中的路径294
面试题67:机器人的运动范围296
海涛2008年在我的团队做过软件开发工程师。他是一个很细心的员工,对面试这个话题很感兴趣,经常和我及其他员工讨论,积累了很多面试方面的技巧和经验。他曾跟我提过想要写本有关面试的书,三年过后他把书写出来了!他是一个有目标、有耐心和持久力的人。
我在微软做了很多年的面试官,后面七年多作为把关面试官也面试了很多应聘者。应聘者要想做好面试,确实应把面试当作一门技巧来学习,更重要的是要提高自身的能力。我遇到很多应试者可能自身能力也不差但因为不懂得怎样回答提问,不能很好发挥。也有很多校园来的应聘者也学过数据结构和算法分析,可是到处理具体问题时不能用学过的知识来有效地解决问题。这些朋友读读海涛的这本书,会很受益,在面试中的发挥也会有很大提高。这本书也可以作为很好的教学补充资料,让学生不只学到书本知识,也学到解决问题的能力。
在向我汇报的员工中有面试发挥很好但工作平平的,也有面试一般但工作优秀的。对于追求职业发展的人来说,通过面试只是迈过一个门槛而不是目的,真正的较量是在入职后的成长。就像学钓鱼,你可能在有经验的垂钓者的指导下能钓到几条鱼,但如果没有学到垂钓的真谛,离开了指导者你可能就很难钓到很多鱼。我希望读这本书的朋友不要只学一些技巧来对付面试,而是通过学习如何解决面试中的难题来提高自己的编程和解决问题的能力,进而提高自信心,在职场中能迅速成长。
徐鹏阳(PungXu)海涛2008年在我的团队做过软件开发工程师。他是一个很细心的员工,对面试这个话题很感兴趣,经常和我及其他员工讨论,积累了很多面试方面的技巧和经验。他曾跟我提过想要写本有关面试的书,三年过后他把书写出来了!他是一个有目标、有耐心和持久力的人。
我在微软做了很多年的面试官,后面七年多作为把关面试官也面试了很多应聘者。应聘者要想做好面试,确实应把面试当作一门技巧来学习,更重要的是要提高自身的能力。我遇到很多应试者可能自身能力也不差但因为不懂得怎样回答提问,不能很好发挥。也有很多校园来的应聘者也学过数据结构和算法分析,可是到处理具体问题时不能用学过的知识来有效地解决问题。这些朋友读读海涛的这本书,会很受益,在面试中的发挥也会有很大提高。这本书也可以作为很好的教学补充资料,让学生不只学到书本知识,也学到解决问题的能力。
在向我汇报的员工中有面试发挥很好但工作平平的,也有面试一般但工作优秀的。对于追求职业发展的人来说,通过面试只是迈过一个门槛而不是目的,真正的较量是在入职后的成长。就像学钓鱼,你可能在有经验的垂钓者的指导下能钓到几条鱼,但如果没有学到垂钓的真谛,离开了指导者你可能就很难钓到很多鱼。我希望读这本书的朋友不要只学一些技巧来对付面试,而是通过学习如何解决面试中的难题来提高自己的编程和解决问题的能力,进而提高自信心,在职场中能迅速成长。
徐鹏阳(PungXu)
PrincipalDevelopmentManager,SearchTechnologyCenterAsia
Microsoft
IhadtheprivilegeofworkingwithHarryatMicrosoft.Hisbackgroundandindustryexperienceareagreatassetinlearningabouttheprocessandtechniquesoftechnicalinterviews.Harrysharespracticalinformationaboutwhattoexpectinatechnicalinterviewthatgoesbeyondthecoreengineeringskills.Aninterviewismorethanaskillsassessment.Itisthechanceforyouandaprospectiveemployertogaugewhetherthereisamutualfit.Harryincludesremindersaboutthekeyfactorsthatcandetermineasuccessfulinterviewaswellassuccessinyournewjob.
Harrytakesyouthroughasetofinterviewquestionstosharehisinsightintothekeyaspectsofthequestion.Byunderstandingthesequestions,youcanlearnhowtoapproachanyquestionmoreeffectively.Thebasicsoflanguages,algorithmsanddatastructuresarediscussedaswellasquestionsthatexplorehowtowriterobustsolutionsafterbreakingdownproblemsintomanageablepieces.Harryalsoincludesexamplestofocusonmodelingandcreativeproblemsolving.
TheskillsthatHarryteachesforproblemsolvingcanhelpyouwithyournextinterviewandinyournextjob.Understandingbetterthekeyproblemsolvingtechniquesthatareanalyzedinaninterviewcanhelpyougetthefirstjobafteruniversityormakeyournextcareermove.
MattGibbs
DirectofDevelopment,AsiaResearch&Development
MicrosoftCorporation2011年9月份以来,我的面试题博客(http://zhedahht.blog.163.com/)点击率上升很快,累计点击量超过了70万,并且平均每天还会增加约3000次点击。每一年随着秋季新学期的开始,新一轮招聘高峰也即将来到。这不禁让我想起几年前自己找工作的情形。那个时候的我,也是在网络的各个角落搜索面试经验,尽可能多地收集各个公司的面试题。
当时网上的面试经验还很零散,应聘者如果想系统地收集面试题,需要付出很大的努力。于是我萌生了一个念头,在博客上系统地收集、整理有代表性的面试题,这样可以极大地方便后来人。经过一段时间的准备,我于2007年2月在网易博客上发表了第一篇关于编程面试题的博客。
在过去4年多的日子里,我陆续发表了60余篇关于面试题的博客。随着博客数目的增加,我也逐渐意识到一篇篇博客仍然是零散的。一篇博客只是单纯地分析一个面试题,但对解题思路缺乏系统性的梳理。于是在2010年10月我有了把博客整理成一本书的想法。经过一年的努力,这本书终于和读者见面了。
本书内容
全书分为7章,各章的主要内容如下:
第1章介绍面试的流程。通常整个面试过程可以分为电话面试、共享桌面远程面试和现场面试3个阶段,每一轮面试又可以分为行为面试、技术面试和应聘者提问3个环节。本章详细讨论了面试中每一环节需要注意的问题。其中第1.3.2节深入讨论了技术面试中的5个要素,是全书的大纲,接下来的第2~6章逐一讨论每个要点。
第2章梳理应聘者接受技术面试时需要用到的基础知识。本章从编程语言、数据结构及算法三方面总结了程序员面试的知识点。
第3章讨论应聘者在面试时写出高质量代码的3个要点。通常面试官除了期待应聘者写出的代码能够完成基本的功能之外,还能应对特殊情况并对非法输入进行合理的处理。读完这一章,读者将学会如何从规范性、完整性和鲁棒性3个方面提高代码的质量。
第4章总结在编程面试中解决难题的常用思路。如果在面试过程中遇到复杂的难题,应聘者最好在写代码之前形成清晰的思路。读者在读完这一章之后将学会如何用画图、举例和分解复杂问题3种思路来解决问题。
第5章介绍如何优化代码的时间效率和空间效率。如果一个问题有多种解法,面试官总是期待应聘者能找到最优的解法。读完这一章,读者将学会优化时间效率及空间换时间的常用算法。
第6章总结面试中的各项能力。面试官在面试过程中会一直关注应聘者的学习能力和沟通能力。除此之外,有些面试官还喜欢考查应聘者的知识迁移能力、抽象建模能力和发散思维能力。读完这一章,读者将学会如何培养和运用这些能力。
第7章是两个面试的案例。在这两个案例中,我们将看到应聘者在面试过程中的哪些举动是不好的行为,而哪些表现又是面试官所期待的行为。衷心地希望应聘者能在面试时少犯甚至不犯错误,完美地表现出自己的综合素质,最终拿到心仪的Offer。
本书特色
正如前面提到的那样,本书的原型是我过去4年多陆陆续续发表的几十篇博客,但这本书也不仅仅是这些博客的总和,它在博客的基础上添加了如下内容。
本书试图以面试官的视角来剖析面试题。本书前6章的第一节都是“面试官谈面试”,收录了分布在不同IT企业(或者IT部门)的面试官们对代码质量、应聘者如何形成及表达解题思路等方面的理解。在本书中穿插着几十条“面试小提示”,是我作为面试官给应聘者在面试方法、技巧方面的建议。在第7章的案例中,“面试官心理”揭示了面试官在听到应聘者不同回答时的心理活动。应聘者如果能了解面试官的心理活动,无疑能在面试时更好地表现自己。
本书总结了解决面试难题的常用方法,而不仅仅只是解决一道道零散的题目。在仔细分析、解决了几十道典型的面试题之后,我发现其实是有一些通用的方法可以在面试的时候帮助我们解题的。举个例子,如果面试的时候遇到的题目很难,我们可以试图把一个大的复杂的问题分解成若干个小的简单的子问题,然后递归地去解决这些子问题。再比如,我们可以用数组实现一个简单的哈希表解决一系列与字符串相关的面试题。在详细分析了一道面试题之后,很多章节都会在“相关题目”中列举出同类型的面试题,并在“举一反三”中总结解决这一类型题目的方法和要点。
本书收集的面试题都是各大公司的编程面试题,极具实战意义。包括谷歌、微软在内的知名IT企业在招聘的时候,都非常重视应聘者的编程能力,编程技术面试也是整个面试流程中最为重要的一个环节。本书选取的题目都是被各大公司面试官反复采用的编程题。如果读者一开始觉得书中的有些题目比较难,那也正常,没有必要感到气馁,因为像谷歌、微软这样的大企业的面试本身就不简单。读者逐步掌握了书中总结的解题方法之后,编程能力和分析复杂问题的能力将会得到很大的提升,再去大公司面试将会轻松很多。
本书附带提供了50道编程题的完整的源代码,其中包含了每道题的测试用例。很多面试官在应聘者写完程序之后,都会要求应聘者自己想一些测试用例来测试自己的代码,一些没有实际项目开发经验的应聘者不知道如何做单元测试。相信读者朋友在读完这本书之后就会知道如何从基本功能测试、边界值测试、性能测试等方面去设计测试用例,从而提高编写高质量代码的能力。
本书体例
在本书的正文中间或者章节的末尾,穿插了不少特殊体例。这些体例或用来给应聘者提出建议,或用来总结解题方法,希望能够引起读者的注意。
面试小提示:
本条目是从面试官的角度对应聘者的建议或者希望应聘者能够注意到的细节。
源代码:
读者将在本条目中看到一个格式为XX_YYYYY或者XX_Y_ZZZZZ的项目名称,该名称与用VisualStudio打开文件InterviewQuestions.sln之后看到的项目名称对应。本书附带的源代码请到电子工业出版社博文视点的官方网站下载。读者下载源代码并解压缩之后,请用VisualStudio2008或者更新的版本阅读或者运行代码。
测试用例:
本条目列举应聘者在面试时可以用来测试代码是否完整、鲁棒的单元测试用例。通常本书从基本功能、边界值、无效的输入等方面测试代码的完整性和鲁棒性,针对在时间效率或者空间效率有要求的面试题还包含性能测试的测试用例。
本题考点:
本条目总结面试官采用一道面试题的考查要点。
相关题目:
本条目列举一些和详细分析的面试例题相关或者类似的面试题。
举一反三:
本条目从解决面试例题中提炼出常用的解题方法。这些解题方法能够应用到解决其他同类型的问题中去,达到举一反三的目的。
面试官心理:
在第七章的面试案例中,本条目用来模拟面试官听到应聘者的回答之后的心理活动。
关于遗漏的问题
由于时间仓促,再加上笔者的能力有限,书中难免会有一些遗漏。今后一旦发现遗漏的问题,我将第一时间在博客(http://zhedahht.blog.163.com/)上公布勘误信息。读者如果发现任何问题或者有任何建议,也请在博客上留言、评论,或者通过微博(http://weibo.com/zhedahht)和我联系。
致谢
在写博客及把博客整理成书的过程中,我得到了很多人的帮助。没有他们,也就没有这本书。因此,我想在这里对他们诚挚地说一声:谢谢!
首先我要谢谢个人博客上的读者。网友们的鼓励让我在博客上的写作从2007年2月开始坚持到了现在。也正是由于网友们的鼓励,我最终下定决心把博客整理成一本书。
在本书的写作过程中,我得到了很多同学、同事的帮忙,包括Autodesk的马凌洲、刘景勇、王海波、蓝诚,支付宝的殷焰,百度的张珺、张晓禹,Intel的尹彦,交通银行的朱麟,淘宝的尧敏,微软的陈黎明、田超,NVidia的吴斌,SAP的何幸杰和华为的韩伟东(在书稿写作阶段他还在盛大工作)。感谢他们和大家分享了对编程面试的理解和思考。同时还要感谢GlaxoSmithKlineInvestment的Recruitment&HRISManager蔡咏来(也是2008年把我招进微软的HR)和大家分享了微软所推崇的STAR简历模型。还要感谢在微软期间我的两个老板徐鹏阳和MattGibbs,他们都是在微软有十几年面试经验的资深面试官,对面试有着深刻的理解。感谢二位在百忙之中抽时间为本书写序,为本书增色不少。
我同样要感谢现在思科的老板MinLu及TQSG上海团队的同事王劦、赵斌和朱波对我的理解。他们在我写作期间替我分担了大量的工作,让我能够集中更多的精力来写书。
感谢电子工业出版社的工作人员,尤其是张春雨和赵树刚的帮助。两位编辑大到全书的构架,小到文字的推敲,都给予了我极大的帮助,从而使本书的质量有了极大的提升。
本书还得到了很多朋友的支持和帮助,限于篇幅,虽然不能在此一一说出他们的名字,但我一样对他们心存感激。
最后,我要衷心地感谢我的爱人刘素云。感谢她在过去一年中对我的理解和支持,为我营造了一个温馨而又浪漫的家,让我能够心无旁骛地写书。我无以为谢,谨以此书献给她及我们尚未出生的小宝宝。
何海涛
2011年9月8日清晨于上海三泾南宅