怎么才能成为一个好的面试官呢?最近看了极客时间的《技术面试官识人手册》感觉很不错,写写总结。
面试官的两个要求
作为一个面试官,需要满足两个要求,一个是心态,一个是个人技术能力。
心态
面试的目的不能是考倒对方,而是一个收集候选人数据的过程,发现候选人的亮点、长处、短处。面试,不指望面面俱到和全面考察,但是希望考核的部分能相对深入和清晰。判断要清晰,切忌模糊。
收集数据的目的是什么?
用来判断你自己是否想和这个候选人后续一起工作,是否这个候选人和这个团队匹配。
所以在面试的时候,面试官绝不是一个高高在上的考官,而是一个平起平坐的工作伙伴,面试的过程就是一个互相体验工作氛围的过程。
其实对面试官而言,面试也是一次讨论、学习的过程。
技术能力
技术能力是硬性标准,只有自己能力很不错,才能某种程度上判断出候选人的技术能力。好的面试官知道有哪些能力、能够准确定义出这些能力、能够检验出这些能力。这些能力像是物体燃烧后留下的精华,面试官的水平要在这些能力之上。
一般能够成为面试官,说明在团队中大家认同你的技术能力。但能力好未必代表能面试好,因为自己能够完成很多任务和检验别人是否能完成任务是有一定区别的。需要面试官去总结各种经验,并将这种经验分类。举两个实际的例子
- 如项目类:我们做过或者看过很多项目,一个项目从立项,如何沟通出准确的需求,如何设计技术方案(高可用、高性能、可扩展、存储、消息、设计模式、API设计等)、如何单元测试、如何部署、如何推进项目等。如果我们和候选人一起做迷你项目,这里面有很多的可总结、可讨论的点。
- 如异常类:我们发现上线版本后接口速度慢了?
- 有什么方法可以快速发现?
- 怎么处理?
- 怎么定位?有哪些可能原因?
- 怎么防止?
面试前
评估体系
我们从哪些方面来评估候选人呢?可以从三个维度划分
考察角度 | 考察重点 | 考察内容 |
---|---|---|
技术层面上,我们要考察软件工程师的基础技能。 1. 实际问题解决能力 - 把具体问题抽象成若干个可解决的软件问题 - 使用软件工程的知识与技能去解决这些问题 2. 代码设计和实现能力 - 它涵盖的范围也比单纯的算法和数据结构广泛得多了,像是有些公司特别喜欢考察的面向对象就属于这个范畴 3. 系统分析和设计能力 - 是否能够针对问题给出合理的系统估算、架构设计等等。这一部分是和经验密切挂钩的 4. 其它综合工程能力 - 比如测试与验证的能力等等 非技术层面 - 基础品格 - 团队合作 - 学习能力 - 沟通能力 - 任务管理能力 |
实际问题的解决 代码设计和实现 面向对象设计 数据结构和算法 团队匹配度 对软件工程的理解 项目、任务管理能力 用户思维 对系统的理解 |
电梯调度系统设计(代码层面) 系统限流功能的视线(代码层面) 对于CI/CD的讨论 对于Oncall和Ops情况的介绍和讨论 Email系统的设计(用户接口层面) 云存储系统的设计(系统层面) |
拿到候选人简历的时候,考虑一下你负责的这轮面试,考察的重点是什么,通过哪些内容进行考察。
计算机的基础知识考察在哪里啊?其实,它就蕴藏在上述的考察内容之中。对于这些分项的考察,是不可能脱离扎实的计算机基础知识来进行的。比方说,要设计一个网站系统,要有对于网络协议,特别是 HTTP 协议的基础认识吧,要有对于中间件、容器的基础知识吧,还要有对于数据库的基础理解吧。
应届生与老兵
应届生与老兵,这是两类截然相反的候选人,考察的重点是不同的。
对于踏入职场不久的工程师,要更关注潜力相关的素质,比如是否能够听从建议并加以思考,以及是否具备兴趣与热情,因为这是学不到的东西。
- 对于有实习经验的应届生,可以问一下参与的项目,能看出吸收了多少,自己扩展了多少
- 对于完全没有实习经验的应届生,重点可以看看基础能力如何,对知识的活学活用程度
而对于有丰富经验的工程师,要更关注视野,技术理解的深度,以及职业素养。
设计考察内容
我们具体怎么去设计“合适”的技术问题?
糟糕的技术问题
面试的时候,不要搞成简单的一问一答,最好融合到项目里,通过问表象让候选人答原理。
1.知识性的问题。有一些问题,是知识性的,这一类问题,考察的是知识,是记忆力,而不是任何一项工程师的核心能力。因为一方面它不具备普适性,另一方面它又具备太强的随机性。
- 举例来说,有这样的问题:“对于 OA 系统,我们该怎样配置 Tomcat?”
2.过于常见的问题。这里是指问题本身不要过于常见,而不是说,“问题类型”和背后的“原理”不要过于常见。相反,我们恰恰就是要通过“新”问题考察候选人的“旧”能力。
- 举例来说,算法题有:“请对二叉树做一次先序遍历。
- ”系统设计问题有:“请设计一个 URL 短网址系统。”
3.规则过于复杂的问题。
- 如罗马数字的问题:“请设计一个算法,把十进制的数字,用罗马数字来表示。”因为如果候选人对罗马数字一无所知,那么把罗马数字的规则前前后后都讲清楚,怎么也得花费十多分钟的时间。
4.过于偏的问题。虽然可以看出候选人的知识广度,但是这些问题可能自己在工作中几乎遇不到,可以尽量少问。
技术问题设计
面试官要抱着和候选人一起做一个有头有尾的迷你项目的心态来面试。
寻找迷你项目
所以我们需要找一个合适的项目。
- 从自己熟悉的领域里找:如你是干电商的,“如果你从头设计亚马逊(或是其它大型电商)的零售业务,你打算怎么做?”。这就是一个挺好的问题,话题描述很容易理解,但又足够模糊、足够宽泛,而且可以有很多不同的角度来切入并细化。最重要的是,对你来说,这个领域太熟悉了,基本上不存在明显的思路盲区。
- 从候选人简历上的项目里找:这种需要面试官能力特别强,能够发现一针见血的问题,能够把控住整个节奏。因为简历上的项目是候选人熟知的、有明确需求的客观事实。面试官就很难把握住这里的关键,容易被候选人牵着鼻子走,可能这一轮面试候选人一直在泛泛地说,谈到了许多方面,但是面试官也提不出什么一针见血的问题。但对于面试踏入职场不久的工程师可以尝试一下。
- 从网上搜索一些项目:这种也是可以的,可以提前准备一些,但还是自己真正做过的可能会更好一些,毕竟Talk is cheap. Show me the code.
推进迷你项目
原则是分层展开,从模糊到清晰,由浅入深。以“请你设计一个网约车系统。”为例:
分层 | 问题 | 需求 | 系统设计 | 代码设计 | 代码实现 |
---|---|---|---|---|---|
说明 | 根据模糊的表述,明确我们要解决的核心问题是什么?网约车系统那么大,解决问题中,哪一类问题是我们最关注的。 | 根据我们明确了的最关注的问题,列出相关的功能需求和非功能需求。需求可能包含很多,我们的目标是从中确定在面试时间内关心的部分。 | 根据需求进行系统设计,包括从客户端、网络、service 到存储等等各层,有了大致的方案以后,我们的目标是从中筛选出我们最关心的一小部分展开讨论。 | 如果还要考察代码层面,那么就从上述的设计中选取某一个组件,某一个机制,讨论代码层面的设计。 | 根据代码层面的设计,择要实现,比如可以要求实现核心逻辑,核心数据结构等等。 |
常见问题 | 1. 分析和细化需求的过程 | 1. 梳理出需求点,如乘客可以随时随地叫车;系统寻找邻近的司机并转发请求,如果无法接单,继续扩大寻找范围; 2. 确定几项重要的非功能需求。比如用户量有多少、每日的请求数有多少等等。 |
1. 整个系统上看,有哪些组件,或者说有哪些 service?(组件的调用和依赖关系) 2. 把系统组件和用户角色放到一起,乘客和司机怎样和系统交互?(交互的时序关系) 3. 每一个 service 都有什么职责,系统的数据存储选用什么技术?(存储层设计) 4. 对于存储方面,你打算设计怎样的表结构来存储这样的信息? 5. 这样的方案是否存在隐患,在产品上线后可能发生怎样的问题? 6. 你打算怎样解决这样的问题? |
1. 如果考察重点要求我们走一条数据结构和算法考察的路径,比如从起点到终点的简单的寻路算法 2. 如果走面向对象设计考察的路径,设计关键用例中涉及到的类,包括它们的结构和关联关系,等等。 |
1. 如实现寻路算法 |
深度和广度
所以需要根据你这轮面试的考察重点,在这一层里深入挖掘,提前设计好一些题目。广度和深度是能够互通的,可以选择在某个广度上深入下去。
1.在深度上,相同类型的题目要设计出不同的难度,从入门到基础到进阶,看看候选人“踮踮脚能够到”的最高难度。
- 例如如果是问存储,可以问怎么加锁、锁算法是怎样的,一层层深入
2.在广度上,根据问题可以延伸出不同的方向。例如“如果你所在的团队拥有一个重要的 service,它的平均请求响应时间为 1 秒,有一天你部署了软件新版本后,留意到它的平均请求响应时间异常地增大到了 10 秒,你该怎么做?”
- 考察对用户体验、对工程的理解:第一时间我们该怎样做,才能把对用户的影响降到最低?我们可能会谈到回滚,那么我们就可以讨论 Ops。
- 考察监控和告警系统设计:我们该怎样争取在第一时间知道我们的系统出了问题?这就可以谈论软件监控和告警,我们需要对怎样的数据进行监控和告警?怎样采集数据,怎样发送数据,即怎样设计告警系统?
- 考察问题排查思路、系统的理解:我们该怎样去定位问题,问题可能出现在哪一个层面?比如,可能 service 根本没事,只不过客户端出了问题,也可能网络有了问题,还可能就是 service 出的问题。而 service 出的问题,又可能有哪些原因造成,可以采用怎样的策略,去一层一层从高到低去定位问题所在?
- 聚焦系统某一层:通过细化到某一层来进一步展开,这部分的思路就很多了。比方说,如果问题是关系数据库的语句过慢造成的,这里我们就可以进一步聚焦,讨论一些常见的关系数据库性能问题出现的原因,以及相应的解决思路。如果是应用层面的问题,比如应用的内存不足,那么可以从这个角度进一步展开。
- 聚焦系统限流问题:如果问题是恰巧由于该时间点某一客户端在短时间内发送过量的请求,系统无法及时处理而导致的拖慢,那么我们就又可以从流量控制的角度展开。
面试中
流程把控
面试要有礼节:互相尊重,有寒暄,有告别。就像和同事一样相处。
面试推进“迷你项目”可以说是重中之重,问题的解决过程要完整,从需求澄清,到分解、设计、抽象、落地、验证、改进,有头有尾。核心时间为 50 分钟,那么可以参考这样一个时间分配的思路:
- 10 分钟澄清问题,厘清面试中需要实现的需求,细化到可讨论实现的层面;
- 15 分钟分析、讨论该需求抽象后的问题,这些问题必须是软件可解的,比如该使用怎样的数据结构和算法来解决,时间、空间复杂度各是多少;
- 15 分钟现场编码;
- 5 分钟使用实际用例走读代码,验证正确性;
- 5 分钟讨论算法的优化,以及进一步的改进空间。
考察系统、代码设计
分层 | 问题 | 需求 | 系统设计 | 代码设计 | 代码实现 |
---|---|---|---|---|---|
关键点 | 候选人做过的系统 - 在宏观上,观察候选人能否对他介绍的系统有着清晰的把握,有着整体的认识 -在微观上,对于候选人自己熟悉的、做过的部分,我们要选择几个点向下挖,并且挖掘得足够深,到“具体是怎样实现的”这样的程度 全新的系统 - 层层细化和推进系统设计 |
面试官最重要的话基本可以分成下面这两类: - 给出挑战:接着既有的内容,提出新的问题,增加新的限制,给候选人创造新的挑战; - 要求澄清:基于候选人的陈述,要求进一步解释问题,细化解决方法,或者给出实例。 |
|||
实例 | 候选人做过的系统 - 宏观上:系统解决了什么问题?系统的架构是怎样的?模块、组件之间的交互是怎样的?系统存在哪些问题,有哪些瓶颈?如果再给一次重新设计系统的机会,哪些地方可以改善? - 微观上:以候选人做了优化为例。能具体说说是什么方面的性能优化了一倍吗?哦,那你做了哪些改进才做到的呢?哦,那你做了哪些改进才做到的呢?那在压测的过程中,系统的吞吐量是多少呢? 全新的系统 以请设计一个网约车系统为例。 1. 根据我们的讨论所确定的需求,这个系统中会有哪些主要模块?(要求澄清) -> 第一阶段:客户端 - Service - 存储的基本层次建立 2.嗯,消息怎样从服务端传递给客户端呢?(要求澄清) -> 第二阶段:Service 解耦 3.嗯,确实看起来好多了。但是我还有个问题,司机和乘客汇报 GPS 位置的时候,从图上看,只有在乘客请求和司机接受 ride 的时候才会汇报位置信息吗?。(要求澄清) -> 第三阶段:进一步解耦,补足缺失 4.嗯,不错。那么,对于这两类数据的存储,你打算分别选用怎样的技术来实现呢? -> 第四阶段:细化存储层设计 |
某社交网站有两千万的注册用户,每个用户都有积分属性,且根据在线用户在社交网站上的行为,积分会有小幅度的变更(比如登录一次就 +1 分,评论一次就 +2 分等等,每次不超过 3 分),在线用户还需要频繁地获取自己在所有用户中基于积分的排名,那么,要设计一种什么样的算法,才能高效、准确、实时地获取指定用户的排名呢? - 候选人:我觉得问题的解法就是,在每次需要获取排名的时候,根据用户的积分,对这两千万个用户进行排序。 - 面试官:好,这样的方式下,对于每次排名的获取,时间、空间复杂度是多少?(要求澄清) - 候选人:用户量是 n 的话,时间复杂度是 n*log(n)……(说着说着自己意识到时间复杂度较大) - 面试官:对了,如果说这个时间复杂度我们无法接受,你能否优化这个效率?(给出挑战) - 候选人:……(提出了一些排序的优化思路,但是他自己对它们的效率也不满意) - 。。。。。。思路讨论清楚可以开始写代码,如果编码顺利,还可以继续 follow-up 问题的挑战 - 比如:面试官:由于某个原因,我们一次赠送给一批量用户十万积分,也就是说,我们讨论的这个积分变化的增量,如果非常大,那么在右侧链表中可能影响的数据量也非常大,这种情况有没有办法优化?(给出挑战) -候选人:……(这一步也有很多可行的思路,比如有用跳表的,有用线段树等解法的) |
考察其它技能
技能 | 方法 |
---|---|
面向对象考察 | 和候选人一起使用这些技能和工具解决实际问题,而不是单纯地做设计原则和设计模式理论和概念的问答。 |
API 设计考察 | 引导候选人完成类似如下的 API 接口设计表格 |
测试能力考察 | - 第一种形式是针对已经完成的代码,做白盒测试。面试官会期望候选人,能够拿着简单的测试用例来走一遍代码。之后也可能会提问,怎样设计测试用例才能将刚写的代码覆盖到,甚至要求写一小段单元测试代码,这是属于白盒测试。 - 而第二种形式,则是黑盒测试。对于某一个产品,或者某一个功能特性,从黑盒的角度讨论,怎样才能做好它的测试。黑盒测试主要出现在单独的测试能力考察轮次,这种形式除了对于测试本身的考察,也要求候选人在系统和产品的层面有一定的理解。 |
项目与任务管理 | 最常见的考察方法是问经历,即直接了当地询问候选人,当前团队中,项目是怎样管理的,产品是怎样上线的,任务是怎样管理的,优先级又是怎样排的。 |
行为型问题 | 行为型问题基本上是一类用来观察候选人过去在特定的工作情境下,是怎样解决困难并取得成功的问题。这里面的逻辑是,候选人在过去遇到困难的时候,遵循的逻辑和采取的行为,这相当程度上反映了未来候选人将怎样应对类似的困难。可以用“情境”、“思考”、“应对”和“结果”这样四个词来概括。实例如下 1.你能否告诉我一个实例,让我了解你在工作中是怎样说服同事,采纳你的技术决策的? 2.你在工作中是否遇到过不同意你主管(经理)看法的时候?你又是怎样处理的? 3.对于预先订立的项目目标,你有没有遇到过未能按时实现的情况? 4.对于在你做过的项目中的软件设计,有没有事后你觉得自己做错了的? |
其它技巧
1.如何问出一些好的问题?要善于多问为什么!面试过程中变数很大,要从沟通中找到事实,很多事实加一个为什么就成了一个很好的问题。
2.倾听、速记、询问:候选人回答的时候尽量先倾听,将核心点速记下来,然后进行询问。可以更好的回忆,并且可以通过记录下来的内容,准备要问的广度和深度。
面试后
面试后尽快写面试记录,可以结论先行。最好把面试的内容概要写一下,防止问相同的问题。
1 | 结论: |
总结
这是识人手册的整体框架,希望对大家有所帮助。