《剑指 offer》小结

前言:

经历这半年的洗礼,本身的综合能力和素质都获得了一个质的提高。c++

实话说对于将来去哪里,即将如何发展尚未清晰的规划。迷茫老是会有的,但这并非中止脚步的理由。找工做是在漫长的职业生涯中时常出现的转折点,而学习和和积累是终生的任务。这里不打算对这一段时间的各项细节和收获展开太多讨论,后续将会专门进行整理。git

本文主要是对《剑指 offer》这本面试经典进行一个小结,也是将来继续坚持刷题的一个开端。程序员

在准备面试过程当中手写 bug free 代码的环节是必不可少的。本人并不是 ACM 出身,虽然说在学校基础课程学得还不错,但对于刷题并没有太多经验,一开始仍是吃力的。慢慢的发现这一过程仍是挺有意思的,虽然校招找工做已结束,但这刷算法题会成为我新的爱好。最近将《剑指 offer》这本经典的面试宝典梳理了一遍,并实现和整理了书中的全部题目,并在“牛客网”上提交测试以保证代码的正确性。github

平时有时间也能够刷一刷 leetcodehihocoder,不少题目思考起来仍是颇有意思的。对于其余的课本,我以为《算法导论》《编程珠玑》《编程之美》都是不错的经典教材,若是之后有时间也会一一对这几本书进行总结。面试

对于刷题,谈谈个人几点感觉:算法

  1. 熟练一门编程语言很重要,这决定了你能不能将 idea 尽快实现并印证。在一开始能够先写一些 easy 的题,主要是将本身的编程语言练熟。本人主要使用 c++ 实现,其实算法涉及的结构不是不少,stl 基本就能够很好的 cover。
  2. 凡事开头难,坚持老是会有收获的。我建议刷题要有一个持续的过程,不要间断,最好一段时间集中攻克一件事情。好比 x 天完成一本书,或者一块内容,这样有助于集中精力突破。若是三天打鱼两天晒网,每次捡起来都很吃力,会造成恶性循环。题目刷多了之后会培养出感受和思考问题的思路。
  3. 不管简单与否都要思考清楚再开始写代码。分析题目时能够将问题进行分解,还能够借助实例,作图抽象等方法帮助理解。
  4. 注意细节,写 bug free 的代码(应该成为一种追求)。实现代码过程当中应该分析好输入输出,考虑好特殊状况和边界条件等。好比字符串转换成整数须要考虑:不合法输入,溢出等状况。使用指针时刻注意是否为空的判断等。
  5. 优美,鲁棒的高质量代码。不只仅是追求完成功能,还应该对代码的布局,变量名见名见意,关键边界条件的检查等。代码是程序员交流的语言,所以应该写得优美
  6. 重复检查,人脑 debug。不管是否在手写代码的环境中,写完代码都应该养成重复 review 的习惯,本身跑几个测试用例,肯定没有问题以后再把你代码交给面试官。
  7. 没有完美的代码,注意沟通完成知足需求的代码。每个程序均可以当作是输入到输出的映射过程,而输入和输出老是有不少可能的,咱们一个程序不可能 cover 掉大千世界,函数 function,也能够叫作“功能”,即完成必定任务的函数,这就须要咱们经过沟通去了解用户的意图,将问题抽象,并基于某些假设去完成这样的 function。
  8. 解决问题的方法老是多样的。无论是作题仍是平时练习,在完成任务的基础上应该还要发散性思考,一个题目的不一样解法,类似题目的解法,类似场景的结局等。
  9. 在进行时间和空间复杂度分析时,要注意考虑实际使用的语言,其内置数据结构或函数的复杂度会影响你实际程序的复杂度。好比 C++ 中 map 和 unordered_map,set 和 unordered_set 的区别等。
  10. 一味的 practice,还要适时的总结和 review 才能及时的查漏补缺,让本身能更好的成长。

下面是课本中的一些总结,其实主要是经典语录。因为本人平时很喜欢记录一些大师/大神们的话,所以在总结中也是重点摘抄了不少大牛们的切身感悟和体验。有时候看看不只是一种学习更是一种前人的激励。编程

第1章:面试的流程

面试官谈面试:

“对于初级程序员,我通常会偏向考察算法和数据结构,看应聘者的基本功;对于高级程序员,我会多关注专业技能和项目经验”——何幸杰(SAP,高级工程师)设计模式

“应聘者要事先作好准备,对公司近况、项目状况有所了解,对所应聘的工做真的颇有热情。另外,应聘者还要准备好合适的问题问面试官。”——韩伟东(盛大,高级研究员)api

“应聘者在面试过程首先要放松,不要过于紧张,这有助于后面解决问题时开拓思路。其次不要急于编写代码,应该先了解清楚所要解决的问题。这时候最好先和面试官多作沟通,而后开始作一些总体的设计和规划,这有助于编写高质量和高可读性的代码。写完代码后不要立刻提交,最后本身review并借助一些测试用例来走几遍代码,找出可能出现的错误。”—— 尧敏(淘宝,资深经历)安全

“‘神马’,都是浮云,应聘技术岗位就是要踏实写程序。”——田超(微软,SDE II)

面试

面试的三种形式:

1.电话面试(听不清楚时要勇于说pardon)

2.共享桌面远程面试(最关心的应聘者的编程习惯以及调试能力,几种编程习惯:思考清楚再开始编码,良好的代码命名和缩进对齐习惯,可以单元测试。)

3.现场面试 (准备:规划好路线并估算出行时间,准备好得体的衣服,注意面试邀请函里面的面试流程,准备几个问题。面试:面试官经过应聘者的语言和行动,考察他的沟通能力、学习能力、编程能力等综合实力。)

面试的是三个环节:

1.行为面试(5~10min,过一遍简历内容)

1.1 自我介绍30s-1m

主要学习、工做经历以及意向,面试官若对某些细节感兴趣会提问

1.2 项目经历(注意“参与”vs “负责”):STAR模型描述

  • situation(简短的项目背景)
  • task(完成的任务)
  • action(为了完成任务作了哪些工做,怎么作的)
  • result(本身的贡献,用数字说话,多少功能?优化后提升百分比?修复了多少个bug?)

    例子:Winforms是微软.NET中一个成熟的UI平台(Situation)。本人的工做是在添加少许新功能以外主要负责维护已有的功能(Task)。新的功能主要是让Winforms的控件的风格和Vista, Windows 7 的风格保持一致。在维护方面,对于较难的问题我用WinDbg等工具进行调试( Action)。在过去两年中我总共修改了200个Bug(Result)。
    常见问题:(1)你在该项目中碰到的最大的问题是什么,你是怎么解决的?(2)从这个项目中你学到了什么?(3)何时会和其余团队成员(包括开发人员、测试人员、设计人员、项目经理等)有什么样的冲突,大家是怎么解决冲突的?
    要作好准备!!!!
    小提示:在介绍项目经验(包括简历和口述)时,应聘者没必要详述项目的背景,而要突出介绍本身完成的工做以及取得的成绩。

1.3 应聘者掌握的技能(注意“了解” vs “熟悉” vs “精通”):

了解:对某一个技术知识上过课或看过书,但没有作过实际的项目。(一般不建议在简历中列出只是肤浅地了解一点的技能,除非这项技术应聘的职位的确须要。)

熟悉:(大多状况下使用)在实践项目中适用某一项技术已经有较长的时间,经过查阅相关的文档能够独立解决大部分问题,咱们就熟悉它了。对于应届毕业生而言,毕业设计所用到的技能;对于已工做过的,在项目开发过程当中所用到的技能。

精通:对一项技术驾轻就熟,在项目开发过程当中当同窗或同事向咱们请教这个领域的问题咱们都有信心也有能力解决。(应聘者不要试图在简历中把本身修饰成“高人”而轻易适用“精通”,除非本身可以很轻松地回答这个领域里的绝大多数问题,不然就会拔苗助长。)

1.4 回答为何跳槽:

了解应聘者的性格,能够大胆的回答本身真实的想法,但也不能想说什么就说什么,以避免给面试官留下负面的印象。

避免一下几个缘由:老板太苛刻,同事太难相处,加班太频繁,工资过低。

笔者在面试的时候,一般给出的答案是:如今的工做作了一段时间了,已经没有太多的激情了,所以但愿寻找一份更有挑战的工做。而后具体论述为何有些厌倦如今的职位,以及面试的职位我为何会有兴趣。

第一次跳槽(从Autodesk -> 微软):我在Autodesk 开发的软件Civil 3D 是一款面向土木行业的设计软件。若是我想在如今的职位上获得提高,就必须增强土木行业的学习,可我对诸如计算土方量、道路设计等没有太多兴趣,所以出来寻找机会。

第二次跳槽(从微软->思科):我在微软的主要工做是开发和维护.NET的UI平台Windows。因为Windows已经很是成熟,不须要添加多少新功能,所以个人大部分工做都是维护和修改BUG。两年下来,调试的能力获得了很大的提升,但长期如此本身的软件开发和设计能力将不能获得提升,所以想出来寻找能够设计和开发系统的职位。同时,我在过去几年里的工做都是开发桌面软件,对网络了解甚少,所以但愿下一个工做能与网络相关(思科是网络公司)。

2.技术面试 (40~50min)

5种素质:扎实的基础知识(编程语言、数据结构、算法等)、能写高质量的代码(正确的、完整的、鲁棒的)、分析问题时思路清晰(思路清晰分析和解决复杂问题)、能优化时间效率和空间效率(从时间和空间角度优化算法)、学习沟通等各方面的能力(沟通能力、学习能力和发散思惟能力)。

3.应聘者提问(5~10min)

为每一轮面试准备2~3个问题。至少要问一两个问题。

不要问的问题:(1)不要问和本身的职位没有关系的问题,好比问“公司将来五年的发展战略是什么?”(2)不要问薪水,等过了技术面到HR面再说。(3)不要当即打听面试结果。

推荐问的问题:与招聘职位或者项目相关的问题,若是这类问题问得很到位,那么面试官就会以为你对应聘的职位很感兴趣。从两个方面收集信息:(1)面试前要作足功课,到网上收集一些相关信息,作到对公司成立时间、主要业务、职位要求了然于胸;(2)面试过程当中留心面试官说过的话。
好比:如何对新员工进行培训?须要掌握什么样的知识?

第2章:面试须要的基础知识

面试官谈基础知识

c++的基础知识,如面向对象的特性、构造函数、析构函数、动态绑定等,可以反映出应聘者是否善于把握问题本质,有没有耐心深刻一个问题。另外还有经常使用的设计模式、UML图等,这些都能体现应聘者是否有软件工程方面的经验。—— 王海波(Autodesk,软件工程师)

对基础知识的考察我特别重视c++中对内存的适用管理。我以为内存管理是c++程序员特别要注意的,由于内存的适用和管理会影响程序的效率和稳定性。—— 蓝诚 (Autodesk, 软件工程师)

基础知识反映了一我的的基本能力和基础素质、是之后工做中最核心的能力要求。我通常考察:(1)数据结构和算法;(2)编程能力;(3)部分数学知识,如几率;(4)问题的分析和推理能力。 —— 张晓禹(百度,技术经理)

我比较重视四块基础知识:(1)编程基本功(特别喜欢字符串处理这一类的问题);(2)并发控制;(3)算法、复杂度;(4)语言的基本概念。 —— 张珺(百度,高级软件工程师)

我会考察编程基础、计算机系统基础知识、算法以及设计能力。这些是一个软件工程师的最基本的东西,这些方面表现出色的人,咱们通常认为是有发展潜力的。—— 韩伟东(盛大,高级研究员)

(1)对os的理解程度。这些知识对于工做中常遇到的内存管理、文件操做、程序性能、多线程、程序安全等有重要帮助。对于os理解比较深刻的人对于偏底层的工做上手通常比快。(2)对于一门编程语言的掌握程度。一个热爱编程的人应该对某种语言有比较深刻的了解。一般这样的人对于新的编程语言上手也比较快,并且理解比较深刻。(3)经常使用的算法和数据结构。不了解这些的程序员基本只能写写“hello world”。 —— 陈黎明(微软, SDE II)

推荐的c++书籍:

《Effective C++》, 《C++ Primer》, 《Inside C++ Object Model》, 《The C++ Programming Language》

基础知识:

编程语言 + 数据结构 + 算法和数据操做

第3章:高质量的代码

面试官谈代码质量

通常会考察代码的容错处理能力,针对一些特别的输入会询问应聘人员是否考虑,如何处理。不能容忍代码只是针对一种遐想的‘正常值’进行处理,不考虑异常情况,也不考虑资源的回收等问题。 —— 殷焰(支付宝,高级安全测试工程师)

若是是由于粗心犯错,能够原谅,由于毕竟面试的时候会紧张;不能容忍的是,该掌握的知识点却没有掌握,并且提醒了还不知道。好比下面的:double d1, d2; .... if(d1 == d2) ... —— 马凌洲(Autodesk, Software Development Manager)
(解释:犹豫精度缘由不能用等号判断两个小数是否相等)

最不能容忍功能错误,忽略边界状况。 —— 尹彦 (Intel, Software Engineer)

若是一个程序员连变量、函数命名都毫无章法,解决一个具体问题都找不到一个最合适的数据结果,这会让面试官印象大打折扣,由于这个只能说明他程序写得太少,不够熟悉。—— 吴斌 (NVidia, Graphics Architect)

我会从程序的正确性和鲁棒性两方面检查代码的质量。会关注对输入参数的检查、处理错误和异常的方式、命名方式等。对于没有工做经验的学生,程序正确性以外的错误基本都能容忍,但通过提示后但愿可以很快解决。对于有工做经验的人,不能容忍考虑不周到、有明显的鲁棒性错误。 —— 田超 (微软,SDE II)

代码质量

代码的规范性: 清晰的书写、清晰的布局、合理的命名

代码的完整性: 3个方面保证代码完整性:功能测试、边界测试、负面测试 (溢出、递归正确退出、不合法的输入)。3种错误处理方法:返回值、全局变量、异常

. 优势 缺点
返回值 和系统api一致 不能方便地适用计算结果
全局变量 可以方便地适用计算结果 用户可能忘记检查全局变量
异常 能够为不一样出错缘由定义不一样异常类型,逻辑清晰明了 有些语言不支持异常,抛出异常时对性能有负面影响。

代码的鲁棒性:采起防护式编程、处理无效的输入

第4章:解决面试题的思路

面试官谈面试思路

编码前讲本身的思路是一个考查指标。一个合格的应聘者应该在他作事以前明白本身要作的事情到底是什么,以及该怎么作。一开始就编码的人员,除非后面表现很是优秀,不然很容易通不过。 —— 殷焰(支付宝,高级安全测试工程师)

让应聘者给我讲具体的问题分析过程,常常会要求他证实。 —— 张晓禹(百度,技术经理)

我的比较倾向于让应聘者在写代码以前解释他的思路。应聘者若是没有想清楚就动手自己就不是太好。应聘者能够采用举例子、画图等多种方式,解释清楚问题自己和问题解决方案是关键。 —— 何幸杰(SAP,高级工程师)

对于比较复杂的算法和设计,通常来说最好是在开始写代码前讲清楚思路和设计。 —— 尧敏(淘宝,资深经理)

喜欢应聘者先讲清思路。若是觉察到方案的错误和漏洞,我会让他证实是否正确,主要是但愿他能在分析的过程当中发现这些错误和漏洞并加以改正。 —— 陈黎明(微软,SDE II)

喜欢应聘者在写代码以前先讲思路,举例子和画图都是很好的方法。 —— 田超(微软, SDE II)

复杂问题解决思路

画图 、举例子 、 分解

第5章:优化时间和空间效率

面试官谈效率

一般针对一些senior的candidates会问一些关于时间、空间效率的问题,这可以体现一个应聘者较好的编程素养和能力。 —— 刘景勇(Autodesk, 软件工程师)

面试时通常会直接要求空间和时间复杂度,这二者都很重要。 —— 张珺(百度,高级软件工程师)

咱们有不少考查时间、空间效率方面的问题。一般二者都给应聘者限定,而后让他给出解决方案。 —— 张晓禹(百度,技术经理)

只要不是特别大的内存开销,时间复杂度比较重要。由于改进时间复杂度对算法的要求更高。 —— 吴斌(NVidia, Graphics Architect)

空间换时间仍是时间换空间,这要看具体的题目了。对于普通的应用,通常是空间换时间,由于一般用户更关心速度,并且通常有足够的存储空间容许这么作。但对于如今的通常嵌入式设备,不少时候空间换时间就不现实了,由于存储空间太少了。 —— 陈黎明 (微软, SDE II)

一些小提示

c/c++程序员养成采用引用(或指针)传递复杂类型参数的习惯。若是采用值传递的方式,从形参到实参会产生一次复制操做。

循环和递归。循环通常效率较高,递归通常较为简洁。递归须要适用函数栈,严格来讲分析的时候要考虑。
展示敏捷的思惟能力和追求完美的激情。(先给出直观的办法,而后继续优化)

第6章:面试中的各项能力

面试官谈能力

应聘者可以礼貌平和、不卑不亢地和面试官交流,逻辑清晰、详略得当地介绍本身及项目经历,谈论题目时可以发现问题的细节并向面试官进行询问,这些都是比较好的沟通表现。对本身作的项目可以了解很深刻、对面试题可以快速寻找解决方法是判断应聘者学习能力的一个方法。这两个能力都很重要,基本可以起到一票否决的做用。 —— 殷焰(支付宝,高级安全测试工程师)

有时候会问一些应聘者不是很熟悉的领域,看应聘者在遇到难题时的反映,在他们回答不出时会有人员提供解答,在解答过程当中观察他们的沟通能力及求知欲。 —— 朱麟(交通银行,项目经理)

沟通能力其实整个过程都在考核,包括询问他过往的经历,也一般会涉及沟通能力。学习能力是在考查算法或者项目经验过程当中,经过提问,尤为是一些他没有接触过的问题来考核的。沟通能力和学习能力很重要,在某种程度上这些都是潜力。若是应聘者沟通能力不行、难以合做,咱们不会录取。 —— 何幸杰(SAP,高级工程师)

让其介绍过往项目其实就是在考查沟通和表达能力。学习能力经过问其看书和关注什么来考查。沟通能力、学习能力对最终面试结果会有必定的影响。对于资深的应聘者,影响要大些。—— 韩伟东(盛大,高级研究员)

应聘者会被问及一些需求不是很明确的问题,解决这些问题须要应聘者和面试官进行沟通,以及在讲解设计思路和代码的过程当中也须要和面试官交流互动。沟通及学习能力是面试成绩中关键的考查点。 —— 尧敏(淘宝,资深经理)

沟通、学习能力就是看面试者可否清晰、有条理地表达本身,是否会在本身所获得的信息不够的状况下主动发问澄清,可否在获得一些暗示以后迅速作出反映纠正错误。 —— 陈黎明(微软,SDE II)

综合能力

编程能力、沟通能力、学习能力、知识迁移能力、抽象建模能力、发散思惟能力....

第7章:题目和源码

https://github.com/hfl15
相关文章
相关标签/搜索