<audio id="audio" title="92 | 程序员面试攻略：面试前的准备" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/0a/7b/0aed6e0f0cb8aa69983934541844737b.mp3"></audio>

学习了《程序员练级攻略》以后，我觉得你应该来学习一下“如何面试”了。在我的职业生涯中，我应聘过很多公司，小公司、中型公司、大公司、国内的公司、国外的公司都有。我有成功获得offer的经历，也有过不少失败的经历。

我从2007年做管理以来，面试过至少1000多人次的工程师。这十多年来，我发现有一些事情没什么变化，我们一代又一代的年轻人在应聘时的表现和我20年前没什么两样，连简历都没什么改进，更不要说程序员在表达能力方面的长进了。如果只看面试表现的话，感觉世界停止了20年似的。

我一直在想，为什么应聘、与人沟通、赚钱等这些重要的软技能，学校里不教呢？这么重要的技能居然要你自己去学，不得不说是教育上的一种失败。另外，关于如何应聘的事，估计你也看过一些文章了，我这里只分享一些我的实实在在的经验和相关的技巧。一定你和看过的不太一样。相信一定能帮得到你！

应聘是需要准备的，下面这些点你需要好好地准备一下。如果你没有准备的话，那么被pass掉的概率会非常大。

# 怎样写简历

首先你要准备的是简历。简历很重要，这是别人了解你的第一个地方，所以简历要好好写。当然，**我们知道真正的好简历是要用自己的经历去写的**，比如，有人的简历就是一句话：我发明了Unix。

当然，并不是所有的人都有这样的经历，但这依然告诉我们，自己的经历才是简历最大的亮点。所以，你要去那些能让你的简历有更多含金量的公司工作，要做那些能让你的简历更闪亮的工作。这是写简历的最佳实践——用自己的经历聊，而不是用文字写。

但从另一方面来说，简历这个文本也是要好好写的，况且，我们不是每个人都会有很耀眼的经历，所以，还是要好好写简历。基本上来说，简历上的信息不要写太多，信息太多相当于没有信息，不要单纯地罗列，要突出自己的长处和技能。一般来说，简历需要包括以下几项内容。

<li>
**自我简介**。这个自我简介是用最简单的话来说明自己的情况，不超过200字。比如：10+年的软件开发经验（说明你的主业），4+年的团队leader经验（说明你的领导力），擅长高可用高性能的分布式架构（说明你的专业和专攻），多年互联网和金融行业背景（说明你的行业背景），任职于XXX公司的XX职位（说明你的职业），负责XXX平台或系统（说明你的业务场景）……
</li>
<li>
**个人信息**。这里有几点需要注意。
<ul>
<li>
**基本信息**。电子邮箱建议用Gmail，千万不要用QQ邮箱，要让人感觉职业化一些。
</li>
<li>
**个人网站**。如果你有个人主页、博客、GitHub或是Stack Overflow，请一定附上，这是加分项。如果个人主页或博客有独立域名，那更好，这会给人一种你爱动手做事的感觉。页面也要干净有美感，这样会让人感觉你有品味。
</li>
<li>
**网站内容**。一般来说这些项都会被面试官点看浏览，所以，里面的内容你需要小心组织和呈现，千万不要造假。另外，除了技术上的一些知识总结（不要太初级，要有深度的、原理型的、刨根问底型的文章），你也可以秀一秀自己的技术价值观（比如，对代码整洁的追求，对一些技术热点事件的看法），这会让你更容易获得面试官的好感。面试官的好感很重要。
</li>
<li>
**作品展**。如果你有一些作品展现，会更好。当然，对于前端程序员来说，这是比较容易的。而对于后端程序员来说，这会比较难一些，只能展示一下自己的GitHub了。如果你有一些比较不错的证书或奖项（如微软的认证、Oracle 的认证），也可以展示一下。
</li>

**个人技能**。个人信息下面你应该罗列几条个人的技能。这些内容要能很明显地让对方了解你掌握的技术和熟悉的领域。

<li>
**技术技能栈**。其中包括你擅长和会用的编程语言（如Java、Go、Python等），编程框架或一些重要的库（如Spring Boot、Netty、React.js、gRPC等），熟悉的一些技术软件（如Redis、Kafka、Docker等），设计或架构（如面向对象设计、分布式系统架构、异步编程、高性能调优等）。
</li>
<li>
**技术领域**。前端、算法、机器学习、分布式、底层、数据库等。
</li>
<li>
**业务领域**。一方面是行业领域，如金融、电商、电信等，另一方面是业务领域，如CRM、支付、物流、商品等。
</li>
<li>
**经验和软技能**。带过多少人的团队、有多少年的项目管理经验、学习能力如何、执行力怎么样、设计过什么样的系统。（不要太多，几句话就好）
</li>

其实和用人单位发布的招聘信息中的职位技能需求很相似。有时候我都在想，明明用人单位的职位需求里写成那样，为什么应聘人还不依葫芦画瓢呢？所以，**对应于你的简历，如果能和职位需求看齐有相类似的描述，这样可以快速地让人觉得你和要应聘的职位很匹配**。

<li>
**工作经历和教育经历**
<ul>
<li>
列一下你的工作经历。每份工作完成的主要项目（不要列一大堆项目，挑重要的），主要突出项目的难度、规模、挑战、职责，以及获得的认可和荣誉。
</li>
<li>
工作经历和教育经历，主要是对上述的个人技能的印证。不要东拉西扯，要紧紧地围绕着你的技能、特长和亮点来展开。
</li>

一般来说，你简历中的内容最好控制在两页A4纸以内，最好有中英文版，简历不要是Word版的，最好是PDF版，然后**简历的格式和风格请参考LinkedIn上的**（在 [微软的Office模板网站](https://templates.office.com/en-us/Resumes-and-Cover-Letters) 上也能找到一些不错的简历模板）。简历的内容不要太多，内容太多，重点就不明显了。写简历的目的是呈现自己的特长、亮点和特点。只要你能呈现出2-3个亮点和特长，就可以吸引到人了。

简历只是一块敲门砖。一些热门的公司和项目能够吸引到很多很多人的简历，所以，你要在众多的简历中脱颖而出。除了自己的经历和能力有亮点外，你还需要有吸引用人单位的方法。

有很多公司都是HR先来筛一遍简历，HR其实并不懂技术，她们只会看你的过往经历、能力是否和职位描述上的匹配。如果简历上的经历和技术亮点不足的话，那么你可以在简历的版式和形式的制作上花些心思，以及在简历的自我描述中加上一些“虚”的东西。

比如“工作态度积极，不分份内和份外的事，只要对公司和个人有利，都会努力做好；勤奋踏实，热爱学习，喜欢做一个全栈工程师；善于发现问题，并解决问题……”表示我虽然现在的经历和技能不足以打动你，但是我的态度端正，潜力巨大，你不能错过……

# 技术知识准备

一般来说，你的简历上写什么，面试官就会问什么，所以，不要打自己的脸，精通就是精通，熟悉就是熟悉，了解就是了解。然后对于你列出来的这些技术，你一定要把其最基本的技术细节给掌握了。面试官一般也会逐步加大问题的难度和深度，看看你到底在哪个层次上。所以，你还是需要系统地看看书，才能应对面试官的问题。比如：

<li>
你写上了Java，那么Java的基本语法都要了解，并发编程、NIO、JVM等，你多少要有点儿了解，Spring、Netty这些框架也要了解。
</li>
<li>
你写上了Go，那么至少得把官网上的Effective Go给看了。
</li>
<li>
你写上了Redis，那么除了Redis的数据结构，Redis的性能优化、高可用配置、分布式锁什么的，你多少也要把官网上的那几篇文章读一读。
</li>
<li>
你写上了面向对象，那么怎么着也得把《设计模式》中的23个模式了解一下。
</li>
<li>
你写上了分布式架构，那么CAP理论、微服务架构、弹力设计、Spring Cloud、Cloud Native这些架构就要做到心里有数。
</li>
<li>
你写上网络编程，那么TCP/IP的三次握手，四次挥手，两端的状态变化你得知道吧，Socket编程的那几个系统调用，还有select、poll、epoll这些异步IO多路复用的东西，你得知道。
</li>

总之，无论你在简历里写什么技术，这些技术的基础知识你都得学一下。本质上来说，这跟考试一样啊。你想想你是怎样准备期末考试的，是不是得把教科书上所有章节中的关键知识点都过一下？你不见得要记住所有的知识点，但是80%以上的关键知识点，你多少得知道吧。

# 算法题准备

国外的公司一般还会面算法题，他们用算法题来过滤掉那些非计算机专业出身的人。国内的一些公司也一样，尤其是一些校招面试，也有很多算法题。所以，算法是很重要的，是你需要努力学习和准备的。

LeetCode是一个不错的地方。如果你能完成其中50%的题，那么你基本上可以想面哪里就面哪里了。这里，你要知道，一些面试官也是新手，他们也是从网上找一些算法题来考你。所以，你不用太害怕算法题，都是有套路的。比如：

<li>
如果是数据排序方面的题，那基本上是和二分查找有关系的。
</li>
<li>
如果是在一个无序数组上的搜索或者统计，基本上来说需要动用O(1)时间复杂度的hash数据结构。
</li>
<li>
在一堆无序的数据中找top n的算法，基本上来说，就是使用最大堆或是最小堆的数据结构。
</li>
<li>
如果是穷举答案相关的题（如八皇后、二叉树等），基本上来说，需要使用深度优先、广度优先或是回溯等递归的思路。
</li>
<li>
动态规划要重点准备一下，这样的题很多，如最大和子数组、买卖股票、背包问题、爬楼梯、改字符……这里有一个 [Top 20的动态规划题的列表](https://www.geeksforgeeks.org/top-20-dynamic-programming-interview-questions/) 。
</li>
<li>
一些经典的数据结构算法也要看一下，比如，二叉树、链表和数组上的经典算法，LRU算法，Trie树，字符串子串匹配，回文等，这些常见的题都是经常会被考到的。
</li>

基本上来说，算法题主要是考察应聘者是否是计算机专业出身的，对于基本的数据结构和算法有没有相应的认识。你做得多了，就是能感觉得到其中的套路和方法的。所以，本质来说，还是要多练多做。

# 工作项目准备

无论什么公司的面试，都会让你说一个你做过的项目，或是你过去解决过的一个难题。但我很好奇怪，这种必问的题，为什么很多应聘者都没有好好准备一下。

一般来说，会有下面这样的几个经典的面试问题。

1. 说一个你做过的最自豪的项目，或是最近做过的一个项目。
1. 说一个你解决过的最难的技术问题，或是最有技术含量的问题。
1. 说一个你最痛苦的项目，或最艰难的项目。
1. 说一个犯过的最大的技术错误，或是引发的技术故障。

对于上面这四个问题：第一个问题，主要是想看看你过去工作中做过的最高级的事是什么，还有你的兴趣点和兴奋点是什么；第二和第三个问题，主要是想看看你解决难题的能力，以及面对压力和困难时的心态；第四个问题，主要是想了解一下你面对错误时的态度，还要了解你是否会对错误有所总结和改进。

这些问题都会伴随着对各种细节的不停追问，因为这样的问题太容易造假了。所以，面试官会不停地追问细节，就像审问一样。因为一个谎言需要用更多的谎言来掩盖，如果没有经过高强度和专业的训练的话，最好不要撒谎。因此对于业余的不是做特工或是间谍的人来说，谎言是经不起追问的。

怎样准备这样的题，我这里有几个提示。

<li>
**要有框架**。讲故事要学会使用STAR 。Situation - 在什么样的环境和背景下，Task - 你要干什么样的事，Action - 你采取了什么样的行动和努力，Result - 最终得到了什么样的效果。这是整个语言组织的框架，不要冗长啰嗦。
</li>
<li>
**要有细节**。没有细节的故事听起来就很假，所以，其中要有很多细节。因为是技术方面的，所以，一定要有很多技术细节。
</li>
<li>
**要有感情**。讲这些故事一定要带感情。要让面试官感受到你的热情、骄傲、坚韧和顽强。一定要是真实的，只有真实的事才会有真实的感情。
</li>
<li>
**要有思考**。只有细节和故事还不够，还要有自己的思考和得失总结，以及后续的改进。
</li>

要做到上述，是不容易的。一般来说，你也是需要训练的。首先，你要形成及时总结的习惯，对自己的日常工作和经历做总结，否则难免会有“书到用时方恨少”的感觉。另外，你还需要训练自己的语言组织能力。最后，你还要有对这些事件的思考，这需要和其他人进行讨论和总结。

对此，如果你想有一个比较好的面试回答效果，**这不是你能临时准备出来的，工夫都是花在平时的。而训练这方面能力的最好方式就是在工作中写文档 ，在工作之余写博客**。只有写得多了，写得好了，你这样的能力才能训练出来。

# 小结

总结一下今天的内容。面试前的准备该怎样做，对面试成功与否至关重要。在这篇文章中，我分享了自己总结一些经验和相关技巧。首先是怎样写简历，我认为，简历上的信息不要写太多，信息太多相当于没有信息，不要单纯地罗列，要突出自己的长处和技能。

然后是技术知识的准备，我强调，无论你在简历里写什么技术，这些技术的基础知识你都得学一下。即便不能记住所有的知识点，但是80%以上的关键知识点，你多少得知道吧。随后是算法题的准备，我推荐了LeetCode，并给出了好几种经典算法题的解题套路。

最后是工作项目的准备，给出了几种经典的面试问题及应答思路，并分享了该如何做准备。我认为，想有一个比较好的面试回答效果，是临时准备不出来的，要将工夫花在平时。

下篇文章中，介绍的是面试中的技巧，比如，答不出来时该怎么办、如何回答尖锐问题、如何抓住最后提问的机会等，很有实践指导意义。敬请期待。

下面是《程序员面试攻略》系列文章的目录。

- [面试前的准备](https://time.geekbang.org/column/article/13067)
- [面试中的技巧](https://time.geekbang.org/column/article/13069)
- [面试风格](https://time.geekbang.org/column/article/13191)
- [实力才是王中王](https://time.geekbang.org/column/article/13192)
