《剑指Offer》第一章 笔记

第一章 面试的流程

1.1 面试官谈到

初级程序员: 偏向考察==算法==和==数据结构==; 对==公司近况==和==项目情况==应该有所了解;

1.2 面试的三种形式

image-20220111172848268

1.2.1 电话面试 (略)

1.2.2 共享桌面远程面试 (Phone-Screen Interview)

此时,面试官最关心的是应聘者的==编程习惯==及==调试能力==。

  • 思考清楚再开始编码
    • 不要一听到题目就匆忙打开编程软件开始编码,因为这样写出来的代码通常漏洞百出。
    • 应先想清楚==解决问题的思路,算法的时空复杂度,需要处理的特殊情况==等,再开始动手。
  • 良好的代码命名和缩进对齐习惯
    • 一目了然的==变量和函数名==、合理的==缩进==和括号==对齐==。
  • 能够单元测试
    • 在定义函数后==立即对函数进行全面的单元测试==。
    • 或者,先写单元测试用例,再写解决问题的函数。

通常我们写的代码都会有各种问题,当我们发现运行结果不对之后的表现也是面试官关注的重点。 熟练地==设置断点、单步跟踪、查看内存、分析调用栈==。

1.2.3 现场面试 (Onsite Interview)

整场面试中的重头戏。

1.3 面试的三个环节

首先是行为面试,参照简历了解应聘者的过往经验; 然后是技术面试,可能要求应聘者现场写代码; 最后是应聘者的提问时间。

image-20220111180526677

1.3.1 行为面试环节

面试的一开始,面试官会注意应聘者的性格特点、深入了解==简历中的项目经历==。 不少面试官也会要求应聘者做一个简短的==自我介绍==。

1. 项目经历

建议采用STAR模型描述自己的每一个项目经历。

image-20220111182434319

  • Situation: 简短的==项目背景==。项目规模、软件的功能、目标用户等。

  • Task: 自己的==任务==。注意"参与"和"负责"的区别。

    负责: 项目的 总体框架设计、核心算法、团队合作等问题。

  • Action: 为了完成任务 自己做了哪些工作,==怎么去做的==。

    系统设计: 系统架构;软件开发: 平台、工具、技术;软件测试: 手工/自动化测试、白盒/黑盒 等。

  • Result: 自己的==贡献==。可以用具体的==数字==来说明。

    功能开发: 按时完成了多少功能;优化: 性能提高的百分比;维护: 修改了多少个BUG。

本书作者在微软项目组经历的例子:

Winforms是微软.NET中的一个成熟的UI平台(Situation)。本人的工作是在添加少量新功能之外主要负责维护已有的功能(Task)。新的功能主要是让Winforms的控件的风格和Vista、Windows 7的风格保持一致。在维护方面,对于较难的问题我用WinDbg等工具进行调试(Action)。在过去两年中我总共修改了超过200个Bug(Result)。

除此之外面试官可能会追问的问题:

  • 你在该项目中==碰到的最大的问题是什么,怎么解决的==?
  • 你从这个项目中==学到了什么==?
  • 什么时候会和其他==团队成员== (开发人员、测试人员、设计人员、项目经理等) 有什么样的==冲突==,怎么解决的?

2. 应聘者掌握的技能

注意"了解"、"熟悉"和"精通"的区别。

"了解": 指对某一种技术==只是上过课或者看过书==,但没有做过实际的项目。 通常不建议在简历中列出只是肤浅了解的技能,除非所应聘的职位的确需要这项技术。

简历中我们所描述技能的掌握程度大部分应该是"熟悉"。 即==在实际项目中使用某一项技术已经有较长时间==,通过==查阅相关的文档可以独立解决大部分问题==。 对应届毕业生而言,毕设中所用到的技能可以用"熟悉";对工作过的而言,在项目开发中用到的技能也可以用"熟悉"。

"精通": 对一项技术已经得心应手。(应该谨慎使用) 在开发过程中当同学或同事向我们请教这个领域的问题时我们有信心和能力解决。

3. 回答"为什么跳槽"

面试官希望通过这个问题了解应聘者的==性格==。

==不要抱怨,也不要流露出负面情绪==,以免被当做负面情绪的传染源,从而影响到团队士气。 应该避免以下四个原因:老板太苛刻、同事太难相处、加班太频繁、工资太低。

通常给出的答案可以是:现在的工作做了一段时间,已经没有太多的激情了,因此希望寻找一份更有挑战的工作。 然后具体论述为什么有些厌倦现在的职位,以及面试的职位我为什么会有兴趣。

本书作者给出的两个例子:

Civil 3D是一款面向土木行业的设计软件。如果我想在现在的职位上得到提升,就必须加强土木行业的学习,可我对诸如计算土方量、道路设计等没有太多兴趣,因此出来寻找机会。

我在微软的主要工作是开发和维护.NET的UI平台Winforms。由于Winforms已经非常成熟,不需要添加多少新功能,因此我的大部分工作都是维护和修改BUG。两年下来,调试的能力得到了很大的提高,但长期如此自己的软件开发和设计能力将不能得到提高,因此想出来寻找可以设计和开发系统的职位。同时,我在过去几年里的工作都是开发桌面软件,对网络了解甚少,因此希望下一个工作能与网络相关。众所周知,思科是个网络公司,这里的软件和系统或多或少都离不开网络,因此我对思科的职位很感兴趣。

1.3.2 技术面试环节

这是面试的重头戏。面试官通常会关注应聘者的5种素质。

1. 扎实的基础知识

通常体现在3个方面: ==编程语言、数据结构和算法==。

首先应该掌握一两门编程语言。面试官从面试过程中应聘者写的代码和跟进的提问中,能看出其掌握的熟练程度。 数据结构:链表、二叉树等。 算法:查找、排序、动态规划、贪婪等。

2. 高质量的代码

简单的问题:面试官的期待会很高。 基本功能之外:==边界条件、特殊输入、错误处理、程序鲁棒性==等。

应该:在==动手写代码之前想好测试用例==,事先考虑好各种可能的输入。 写完代码后也==不要立即提交==,而是在心里默默地运行。 当预想的所有测试用例都能得到合理的输出时,再将代码提交给面试官。

3. 清晰的思路

复杂的问题: 面试官甚至不期待给出完整的答案,可能更看重是否思路清晰。 面试官通常不喜欢应聘者在没有形成清晰的思路之前就开始草率地写代码。

形成清晰的思路的几个简单的方法: 首先是举几个简单的==例子==让自己==理解问题==,寻找其中隐藏的抽象==规律==; 其次可以试着用==图形==表示抽象的==数据结构==。 最后可以试着把复杂的问题==分解==成若干个简单的子问题,再一一解决。

4. 优化效率的能力

当问题有多种解法的时候,面试官通常期待应聘者能最终找到==最优解==。 当面试官提示还有更好的解法时,应聘者不能放弃思考,而是努力寻找在时间或者空间消耗上可以优化的地方。

要优化时空效率,首先需要知道如何==分析效率==。 另外,我们还需要熟知==各种数据结构的优缺点==。 当然,还需要熟练掌握==常用的算法==,例如查找和排序。

5. 优秀的综合能力

软技能 (Soft Skills): ==沟通能力和学习能力==。

沟通能力: 在介绍项目经验或者算法思路时,面试官会观察应聘者是否==观点明确、逻辑清晰==; 另外,也会从==神态和语气==判断他是否有团队合作意识。

学习能力: IT行业知识更新很快。面试官通常有两种方法考察这一点。 首先是询问应聘者==最近在看什么书、从中学到了哪些技术==。 其次是抛出一个==新的概念==,观察应聘者能否短时间内通过==提问、思考、再提问==的过程理解这个概念并解决相关问题。

知识迁移能力的考察: 通常会先问一个简单的问题,再问一个复杂但和前面的问题相关的问题。

抽象建模能力和发散思维能力的考察: 从日常生活中提炼问题、限制应聘者不能使用常规方法来考察创新精神等。

1.3.3 应聘者提问环节

面试官想要了解应聘者最关心的问题有哪些。 应该提前做好功课,为每一轮面试准备至少==2~3个==问题。

有些问题不适合在技术面试环节问。 首先,==不要问和自己的职位没有关系的问题==,例如"公司未来五年的发展策略是什么"。 其次,不要问薪水。 再者,不要立即打听面试结果。

推荐的问题是==与招聘的职位或者项目相关的问题==。 应该对所应聘的职位或者项目的背景有一定的了解。 有两种方法做到这一点: 提前在网上搜集信息,或者留心面试过程中面试官说的话。