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

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

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

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

# 怎样写简历

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

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

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

  • 自我简介。这个自我简介是用最简单的话来说明自己的情况,不超过200字。比如:10+年的软件开发经验(说明你的主业),4+年的团队leader经验(说明你的领导力),擅长高可用高性能的分布式架构(说明你的专业和专攻),多年互联网和金融行业背景(说明你的行业背景),任职于XXX公司的XX职位(说明你的职业),负责XXX平台或系统(说明你的业务场景)……

  • 个人信息。这里有几点需要注意。

    • 基本信息。电子邮箱建议用Gmail,千万不要用QQ邮箱,要让人感觉职业化一些。

    • 个人网站。如果你有个人主页、博客、GitHub或是Stack Overflow,请一定附上,这是加分项。如果个人主页或博客有独立域名,那更好,这会给人一种你爱动手做事的感觉。页面也要干净有美感,这样会让人感觉你有品味。

    • 网站内容。一般来说这些项都会被面试官点看浏览,所以,里面的内容你需要小心组织和呈现,千万不要造假。另外,除了技术上的一些知识总结(不要太初级,要有深度的、原理型的、刨根问底型的文章),你也可以秀一秀自己的技术价值观(比如,对代码整洁的追求,对一些技术热点事件的看法),这会让你更容易获得面试官的好感。面试官的好感很重要。

    • 作品展。如果你有一些作品展现,会更好。当然,对于前端程序员来说,这是比较容易的。而对于后端程序员来说,这会比较难一些,只能展示一下自己的GitHub了。如果你有一些比较不错的证书或奖项(如微软的认证、Oracle 的认证),也可以展示一下。

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

    • 技术技能栈。其中包括你擅长和会用的编程语言(如Java、Go、Python等),编程框架或一些重要的库(如Spring Boot、Netty、React.js、gRPC等),熟悉的一些技术软件(如Redis、Kafka、Docker等),设计或架构(如面向对象设计、分布式系统架构、异步编程、高性能调优等)。

    • 技术领域。前端、算法、机器学习、分布式、底层、数据库等。

    • 业务领域。一方面是行业领域,如金融、电商、电信等,另一方面是业务领域,如CRM、支付、物流、商品等。

    • 经验和软技能。带过多少人的团队、有多少年的项目管理经验、学习能力如何、执行力怎么样、设计过什么样的系统。(不要太多,几句话就好。)

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

  • 工作经历和教育经历

    • 列一下你的工作经历。每份工作完成的主要项目(不要列一大堆项目,挑重要的),主要突出项目的难度、规模、挑战、职责,以及获得的认可和荣誉。

    • 工作经历和教育经历,主要是对上述的个人技能的印证。不要东拉西扯,要紧紧地围绕着你的技能、特长和亮点来展开。

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

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

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

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

# 技术知识准备

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

  • 你写上了Java,那么Java的基本语法都要了解,并发编程、NIO、JVM等,你多少要有点儿了解,Spring、Netty这些框架也要了解。

  • 你写上了Go,那么至少得把官网上的Effective Go给看了。

  • 你写上了Redis,那么除了Redis的数据结构,Redis的性能优化、高可用配置、分布式锁什么的,你多少也要把官网上的那几篇文章读一读。

  • 你写上了面向对象,那么怎么着也得把《设计模式》中的23个模式了解一下。

  • 你写上了分布式架构,那么CAP理论、微服务架构、弹力设计、Spring Cloud、Cloud Native这些架构就要做到心里有数。

  • 你写上网络编程,那么TCP/IP的三次握手,四次挥手,两端的状态变化你得知道吧,Socket编程的那几个系统调用,还有select、poll、epoll这些异步IO多路复用的东西,你得知道。

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

# 算法题准备

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

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

  1. 如果是数据排序方面的题,那基本上是和二分查找有关系的。

  2. 如果是在一个无序数组上的搜索或者统计,基本上来说需要动用O(1)时间复杂度的hash数据结构。

  3. 在一堆无序的数据中找top n的算法,基本上来说,就是使用最大堆或是最小堆的数据结构。

  4. 如果是穷举答案相关的题(如八皇后、二叉树等),基本上来说,需要使用深度优先、广度优先或是回溯等递归的思路。

  5. 动态规划要重点准备一下,这样的题很多,如最大和子数组、买卖股票、背包问题、爬楼梯、改字符……这里有一个 Top 20的动态规划题的列表

  6. 一些经典的数据结构算法也要看一下,比如,二叉树、链表和数组上的经典算法,LRU算法,Tier树,字符串子串匹配,回文等,这些常见的题都是经常会被考到的。

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

# 工作项目准备

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

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

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

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

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

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

  • 要有框架。讲故事要学会使用STAR 。Situation - 在什么样的环境和背景下,Task - 你要干什么样的事,Action - 你采取了什么样的行动和努力,Result - 最终得到了什么样的效果。这是整个语言组织的框架,不要冗长啰嗦。

  • 要有细节。没有细节的故事听起来就很假,所以,其中要有很多细节。因为是技术方面的,所以,一定要有很多技术细节。

  • 要有感情。讲这些故事一定要带感情。要让面试官感受到你的热情、骄傲、坚韧和顽强。一定要是真实的,只有真实的事才会有真实的感情。

  • 要有思考。只有细节和故事还不够,还要有自己的思考和得失总结,以及后续的改进。

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

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

# 小结

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

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

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

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

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