# 36丨面试现场第 3 期:你要如何准备一场技术面试呢?

今天是我们面试现场的最后一期,我想跟你探讨的话题是:你要如何准备一场技术面试呢?

在前两期的面试现场中,我和你探讨了在面试的时候,你要如何介绍自己的项目经历以及如何应对面试官关于基础组件原理问题的考察。

其实,这两节课中,我已经介绍了一些关于面试的技巧,比如说,你要多关注常用组件的原理,多了解项目中的核心监控指标等等。但当你遇到一个心仪的职位的时候,仅仅做这些准备肯定是远远不够的。那么,对不同级别的候选人来说,面试官会分别关注什么呢?准备技术面试时,你需要重点准备哪些呢?在带你了解这些内容之前,我先给你分享一个我面试候选人的经历。

这个候选人只有不到两年的工作经验,只负责开发和维护项目中一个很小的模块,在公司项目上没有得到太多的锻炼机会。但是鉴于他的名校背景以及优异的成绩,我还是发送了面试的邀请。在面试过程中,我没有过多地考察项目相关的问题,而是把重点放在了候选人基础知识和学习能力上。

  • 先聊一聊基础知识吧。TCP 协议中有一种状态叫 time wait,你了解为什么会有这个状态吗?

    这个状态发生在主动发起关闭的一方当它发出最后一个 ACK 的时候,需要等 1- 2MSL(Maximum Segment Lifetime 报文最大生存时间),在这个等待时间里它是处在 time wait 状态中的。这个状态存在的原因主要有两个,一个是可以可靠地关闭 TCP 连接,一个是防止上次连接的包影响到本次连接。

  • 那这种状态的存在对于系统有什么不利的影响?

    这种状态的连接会占用端口,造成系统资源的浪费。

  • 那要如何来解决 time wait 过多的问题呢

    我认为可以修改一些内核参数,比如 tcp_max_tw_buckets。

  • 那么,操作系统中内存管理是如何做的呢?

    Linux 操作系统主要通过虚拟内存来实现每个进程有不同的内存空间

  • JVM中 的内存模型是什么样的?

    在一个多 CPU 的系统中,每个 CPU 都有多级的缓存

你可以看到,虽然他在项目经验上存在比较大的缺陷,但扎实的基本功还是让他赢得了 Offer。

其实,作为面试官,我对不同级别的候选人考察的侧重点也有很大的不同。

如果是一个应届生或者是一个有着一年左右工作经验的新人,我会更看重他的基础知识学习能力和聪明程度,也就是所谓的 潜力,因为除非候选人非常优秀,否则你很难期望他们进入公司之后迅速独当一面,所以,我更期望通过老员工的少量引导,他再迅速成长为项目的核心成员

对于有着三年左右工作经验的候选人,我除了要求他基础扎实以外,还需要他有良好的编码习惯和能力,于是我通常会在面试时增加现场岀题编码的环节。

而对于有着五年甚至更多工作经验的候选人,要求也就更高了,除了以上提到的能力之夕还要求他有排查问题、解决问题的能力,整体系统的设计能力和架构能力等等。但是,说来说去,扎实的基础知识是前提,也是面试考察的重中之重。

那么,在面试中我们般会考察哪些方面的基础知识呢?

你应该知道,算法是基础知识考察的重点。曾经有候选人问过我,算法在实际的项目中使用的不多,为什么一定要在面试的时候考察呢?我相信,有这种想法的同学,一定不少而这是一个非常错误的观点。因为,你平时使用的中间件和组件中,包含着大量的算法实现,了解算法可以有效地帮你了解这些中间件和组件的原理。

比如,数据库的索引一般会采用 B+ 树,那么深入了解了 B+ 树的原理之后,你才能更清晰地理解数据库索引的原理,在调优时也会更加游刃有余。

另外,在实际工作中,我们也需要用算法来辅助完成系统的设计。比如,在我之前的项目中,需要实现一套视频转码系统。这套系统的核心是实现一个有向无环图,如果对这个数据结构不了解,在设计系统的时候,很可能走一些弯路。

而我推荐你通过在 Leetcode 上刷题,提升自己的算法能力除此之外,操作系统和网络方面的知识也是考察的重点,这主要是因为这些基础知识确实能让你在排查问题的时候,有更多的思路。

比如,我之前的系统中有一个服务的作用是接收指令,来执行一些定时的任务。它的请求量很低,但是调用它的服务经常会出现 502 的情况。在排除服务本身存在问题之后我发现这个问题的发生,有一个很有意思的规律,那就是,如果前一次请求发生在 5 秒之前时,会出现问题,但是如果请求不断地到来,却反而不会出现问题。

于是,我怀疑是和 HTTP 协议的 KeepAlive 有关。要知道,在 HTTP1.1 协议中,为了提高请求的效率,客户端和服务端之间是可以保持长连接的。这个长连接如果长时间空闲就会导致系统资源的浪费,所以一般在服务端会控制这个长连接的超时时间。如果在段时间之内都没有请求使用这条连接,服务端就会把这条连接关闭。但是,因为服务端在关闭连接时并不会通知客户端,所以,如果客户端还是使用这条连接来请求服务端的话,就会出现错误了。而 Tomcat 有一个参数 KeepAlive Timeout 正是设置这个超时时间的,在上面的案例中,这参数被设置为了 5 秒,于是我把这个时间延长,问题果然迎刃而解了。

你看,如果你对于 HTTP 协议理解的不深,那么面对这个问题时,就很难能够找到正确的思路。

最后,你还需要着重了解自己经常使用的语言的特性。比如,我就曾经被问过在 JDK6、7、8 中,字符串在虚拟机中的存储位置有什么不同,而这对排查内存泄漏等问题是有帮助的。再比如,我之前排查过一个启动之后慢请求的问题,在经过 CPU 的 Profile 之后,确认重启后 JVM 的 JIT 线程占用了大量的 CPU 时间。于是,我们制定了重启之后的预热方案,让服务器在重启后处理少量的请求,让 JIT 将热点代码编译之后再放入全量请求这样就消除了慢请求。如果你不了解 JIT,那么自然也就不会解决这个问题。

当然,除了这些基础知识以外,面试官还会结合你的项目经历来考察你的架构设计能力、排查问题解决问题的能力、系统优化能力等等。

这些我们在上一期面试现场中,已经有过重点介绍,这里就不再赘述。除此以外,如果你参与了一些开源项目的维护,或者在业界的大会中有过主题分享,再或者,你还有维护自己的 Bog,做一些技术方面的总结,那么都可以在简历和面试的过程中提及,这些都是面试中的加分项。

最后,我周边很多年轻的朋友经常会问我,下一份工作是要选择大公司非核心项目,还是要选择小公司的核心部门?这也是你在面试准备中,需要思考的一个重要问题。在我看来,如果你是一个工作不到三年的职场新手,那么去一个大公司开拓一下眼界还是很有必要的,它能够给你小公司所没有的,规范的研发流程、高并发大流量的系统、成熟的工具和运维体系等等,这肯定会让你的技术水平得到极大的锻炼。而如果你是一个工作超过五年的 「老鸟」,那你不妨去小公司锻炼一下掌控整体系统全局的能力,也许会带你进入另一番天地。

好了,面试现场最后一期到这里就结束了。在这次的面试现场中,我主要和你讨论了面试准备的问题,那么你在面试之前都会做哪些准备呢?