# 20丨面试现场第 2 期:当问到项目经历时,面试官究竟想要了解什么?

今天是我们面试现场的第 2 期,我想跟你探讨的话题是:当问到项目经历时,面试官究竟想要了解什么?

在上一期的面试现场中,我曾经提到,介绍过往的项目经历是面试过程中一个很重要的组成部分,相信你在以往的面试中也一定深有体会。从项目经历中,面试官不仅可以了解到项目研发的整体过程,也能够从中了解到你的技术方案设计思路,排查线上问题的能力,以及对于项目架构演进方向的把握。

那么,在介绍自己的项目经历时,你要如何介绍才能抓住面试官内心的痛点呢?在回答这个问题之前,我还是给你分享一个我面试候选人的例子。

候选人虽然工作年限不长,经历的项目也只有一段,但是这段经历是某个大厂耳熟能详的成功项目,有着很高的并发请求量。我猜测他应该在项目中受到了比较好的锻炼,可是当我邀约了面试之后,出现了问题。

  • 可以介绍一下你参与的这个项目吗? 这个项目是一个社区项目,在这几个模块中,业务流程大概是这样的
  • 那么你在这个项目中的主要职责是什么呢 我主要负责 ⅩXX 模块的开发和维护这个模块的业务流程主要是这样的
  • 你提到这个项目中,ⅩX 模块中并发读的请求量很高,你们使用了缓存来提升读取性能,那么这个模块的下行流量的 QPS 大概有多少呢?缓存的中率大概可以到多少呢?
    这个我没有关注过。
  • 那在这个项目中,你遇到过哪些问题呢?又是怎么排查的呢? 在项目中曾经遇到这样的一个 Bug,然后我是这么来排查的
  • 那你有没有遇到过一些性能相关的问题?你又是怎么调优的呢? 之前有过一次 FuGC 导致的宕机,不过是别人帮忙排查和优化的。

相信你能猜到,这个候选人最终没有通过面试

本来,高并发的社区系统是他的项目亮点,可是在介绍时,他却不了解项目的核心数据指标,也对系统的调优和疑难问题的排查知之甚少,自然不会通过面试。

那么我从面试候选人的经验中给你总结出一些,介绍项目经历的关键注意点,期望你能在今后的面试 中可以借鉴。

其实,在介绍项目经历时讲一些项目背景是可以的,也是必要的,这样可以让面试官对项目有一个全景的认识。但这些背景知识不宜过多,因为毕竟是技术面试,面试官需要在 1 个小时左右对你的技术能力有正确的判断,所以你介绍项目经历时,最好从技术角度出发。

比如,如果你做了一个社区的项目,那么项目的整体架构是一体化的还是服务化的?拆分成了哪些服务?服务之间是通过什么协议,又是怎样交互的,使用了哪些开源的组件,做组件选型时经过了哪些考虑等等,这样方便面试官在这些技术点上做一些深入的展开。

这里有一个小窍门,你可以有意地引导面试官,问一些你想要他问的问题,比方说,如果你对 Kafka、 RocketMG等消息队列有比较深入的了解,你可以多讲讲这方面的内容。

具体来说,使用哪些消息队列解决了哪方面的问题,在其中遇到了哪些坑,又是怎么优化的。这样一来,你就可以把面试官引入个你比较熟悉的领域,面试成功的几率就大大增加了

除此之外,你在项目介绍中要多突出个人对项目的贡献,而不仅仅是项目本身的并发有多高,技术方案设计的有多厉害。的确,成功的项目确实可以给你带来比较大的红利,但你毕竟只是这个项目中的一颗螺丝钉,做出的贡献也是有限的。

在面试中,面试官更关注你个人对整个项目做了什么样的改变为此,我建议你从下面三个点出发回答:

  • 针对复杂的需求你设计了哪些方案,这些方案中技术的难点是什么,你在方案设计中是 如何解决的?
  • 在项目中遇到了哪些疑难诡异的问题,你排查问题的思路是怎样的
  • 在项目运维过程中出现了哪些性能方面的问题,你又是怎么来优化的?

当然了,如果你想用这三点让面试官眼前亮,那么就需要在平时的工作中多积累案例, 而不是只给出 「遇到问题就加日志排查代码、性能出现问题就加索引、加缓存」 这样简单的答案了。

针对我提到的这个问题,我也想给你分享个之前面试的案例。这个案例涉及排查一次自研的 RPC 框架的故障,回答的思路如下:

项目中使用的 RPC 框架存在某个 Bug,偶发地出现 RPC 客户端发送给 RPC 服务节点的所有心跳包全部超时,从而让 RPC 客户端认为服务节点已经发生故障,然后 RPC 客户端就不会将流量发送给这个服务节点。由于项目中使用了 Nett3 框架,我就理了一遍 Netty3 的连接过程的代码,确认是 Boss 线程或者 NioWorke 线程某个地方阻塞了。

然后,我通过 strace(系统调用抓取工具)抓取那段时间的系统调用,发现 BosS 线程中涉及的系统调用全部完成了,却没有发现把 socket fd(文件句柄)注册给 NioWorker 的 selector(文件句柄)的系统调用,于是确认是 NioWorker 的问题。

后来我打印了 jvm thread stack trace (Java 的线程堆栈),发现所有的 NioWorker 线程阻塞在 Object.wait,代码位置是 Clas.for-Name,这样就导致所有的 NioWorker 不再处理新的 Register task(注册任务),Netty Client Bootstrap 中所有的 ConnectFuture 的状态自然不被标记,最终导致上层所有的连接超时。

再往下追查后,我发现 JDK6 中确实存在类初始化过程中出现死锁的 Bug,在升级到 JDK7 之后问题就得到解决。

你看,本来是一个偶发的 RPC 框架层的问题而你在追查这个 Bug 的过程中涉及到了 Netty 网络编程、系统调用追踪,和多线程锁诊断等知识,面试官在听到这样的案例之后,也会认可你排查问题的思路和能力。

我还想给你的建议是,在介绍项目时,你要多突出项目中的亮点,比如,你的项目中核心系统的请求量是 10万次/秒,数据量是百亿级别,在项目研发过程中你使用了 Linux profile 工具排查系统负载高的问题,或者使用布隆过滤器解决缓存穿透的问题的。那么你在回答时,请求量和数据量这些数据会是个亮点,这些排查问题和解决问题的方法也将是亮点。不过,这一点是针对具有高请求量的项目来说的,那么,如果你的项目中没有那么高的请求量,你要怎么回答呢?

我的建议是,你可以结合自己了解到的高并发的知识聊一聊,如果项目到达了某一个量级可以在架构上做哪些的改造和优化。比方说,你做一个直播的项目,平时的流量也不高,突然请到了杨幂这样的流量大咖来做直播。那么你就可以抛出这个假设,然后和面试官聊聊以下几点:

  • 如何使用多级缓存应对杨幂直播间的极端热点请求
  • 几万甚至几十万人同时在直播间内发言时,要如何优化消息的延迟
  • 如何通过压测评估目前系统承载流量的能力,以便明确如何制定扩容的计划。

这样,面试官不仅可以了解你在应对高并发大流量的思路,也会认为你对系统架构的未来发展是有规划,有想法的。

总的来说,面试是双方的「博弈」,你不能被动地接受面试官的询问,而是要循循善诱,扬长避短,在介绍项目经历时,多争取主动把面试官引到自己擅长的领域;在平时的工作中要多关注系统的性能指标,多去参与同事排查性能问题,解决诡异 Bug 的过程,与他们讨论系统优化的思路。这些经历会成为你面试的素材,让面试官对你眼前一亮;

当然,你也需要多关注业界的技术发展,多思考新的技术在你的项目中有哪些应用的场景,这样也可以让面试官觉得你的技术视野比较广阔,具备独立思考的能力。

好了,面试现场第二期到这里就结束了,既然我提到了项目经历,那么,你在面试的过程中是如何讲述自己的项目经历的呢?面试官又针对你的项目经历问了哪些问题呢?你的回答是否得到了面试官的肯定呢?