工程师面试指北
项目介绍
项目介绍的时候,不要一上来就说一些复杂的项目方案。因为在不了解的项目的背景和一些问题的情况下,面试官和面试者理解的上下文是不一样的,这样就会造成双方之间理解的误差。 所以项目介绍的时候,首先介绍一下项目的背景。在面试官的了解之后,就可以开始介绍项目的一些整体架构等等。介绍完成之后,面试官就会根据你说到技术点,然后开始提问。
面试者需要提前复盘自己完成过的项目/模块,并在此基础上模拟面试场景,针对项目/模块中的技术细节、难点、设计方案进行提炼并确认是否存在设计缺陷和问题,提前发现并修正, 避免在面试现场 “露怯”。
数据结构和算法
面试前 1 个月就要经常刷题,保持手感,在时间允许的情况下联系白板写代码,因为面试大部分情况下会在纸上写代码,理想情况下是看到题目之后就能条件反射想到对应的考点、数据结构、算法甚至解题模板。
当然对于成熟的面试官来说,除了考察面试者是否熟练数据结构和算法以及可以写出 bug fres
代码之外,同时会考察面试者是否可以判断当前算法 (包括数据结构) 和给定场景 (比如数据量级、数据类型) 的适配程度,
当前问题最核心的瓶颈和解决方案 (如降低时间复杂度、降低空间复杂度)分别是什么。
示例
实现一个算法,确定一个字符串中是否包含重复的字符。
示例 1
输入:s = "leetcode"
输出: false
示例 2
输入:s = "abc"
输出: true
上面这个简单的小问题,站在面试官的角度,他希望看到什么?笔者这里带入角色分析一下。
如果面试者看到题目之后,什么都不说,直接上来一个二层循环搞定并且无 Bug, 可以给 50 分,如果会判断参数的边界异常条件 (例如参数是否为空),可以给 60 分及格。
如果面试者看到题目之后,什么都不说,直接上来就写 bitset 位运算,我会提问: 题目中有没有说明字符串的字符一定是 26 个英文字母? 如果包含 unicode 字符,是不是需要准备 2^16/8 个字节的空间?
实际项目中,风险可控,结果预期更重要,绝对多数项目、绝大多数情况不在乎那点硬件资源。
所以面试者的编码能力和沟通能力同样重要,我希望面试者看到问题之后,可以先提出一些问题,例如字符串的字符集和字符范围:
- 如果我告诉面试者字符串只包含小写英文字母,那可能在方法第一行直接判断如果字符长度 > 26, 直接返回 true,做到这一点的可以给到 80分
- 如果我告诉面试者字符串为 ascii 字符集,面试者的代码里有边界检查,并且针对不同的范围有不同的侧重点,比如说 ascii 字符集,那也就是 128 个可能性,16 个字节的位运算就是很不错的方案
- 如果我告诉面试者字符串为 unicode 字符集并且没有字符范围,先排序再判断是可以接受的方案,因为算法性能稳定,没有额外资源要求,并且实现简单外加可读性很高,基本可以算是通过
当然,本小节只是笔者的个人思路,不能代表所有情况,比如有的面试官就是要着重考察面试者是否可以写出 “速度最快” 的代码,请读者批判辩证看待并根据实际面试情况随机应变。
如何回答系统设计类问题
不管什么样的问题,保持冷静和头脑清醒,并按照如下的流程逐步拆解,并在回答的过程中不断和面试官沟通并获得反馈,用于确认问题的边界点和接下来的回答侧重点。
Step 1 — Understand the Goals Step 2 — Establish the Scope Step 3 — Design for the Right Scale Step 4 — Start High-Level, then Drill-Down Step 5 — Data Structures and Algorithms (DS&A) Step 6 — Tradeoffs
系统设计面试是一个开放式的对话,面试官期望你去主导这个对话,此时作为面试者要充分掌握主动权,通常来说面试官留给一个系统设计类的题目的时间也就是 5 - 10 分钟, 所以面试者只需要保证自己的回答符合场景、架构清晰、实现可行、逻辑自洽、表述清晰 (如果感觉不好表述的部分,可以直接在纸上画出流程图) 即可,切勿生搬硬套 “高大上” 的系统设计案例,弄巧成拙。
第一步:描述使用场景,约束和假设
这是展现面试者沟通能力最关键的一步,毕竟如果需求理解错了,系统设计和实现再漂亮也没有用,面试官听到问题描述之后不要急于回答,应该在仔细理解问题之后给出自己的疑问, 及时追问面试官获得问题的条件边界,并在所有疑问解决之后心里快速复盘一下是否有遗漏,然后开始思考针对问题的整体架构方案。
第二步:架构方案
罗列出所有重要组件以及每个组件的作用,最好在纸上画出基本的流程图,毕竟一图胜千言,而且可以向面试官展示文档构图能力,下面是一个示例架构图。
到了这里,系统的整体 MVP 就呈现出来了,面试者可以开始思考架构图中的核心组件如何设计。
第三步:核心组件
对第二步生成的架构方案中的每一个核心组件进行详细深入的分析。
- 数据库选型: OLTP/OLAP/Doc/Graph
- 数据表设计
- 缓存设计
- 数据结构和算法
- 模块/服务拆分
- Restful API
- 结合云原生、Kubernetes 等新兴技术方案
第四步:扩展设计
现在完成了系统架构方案中核心组件的设计,系统可以运行起来了,但是为了更贴近真实环境,这里还需要考虑系统的扩展性。
- 负载均衡
- 水平扩展
- 缓存高可用
- 数据库高性能、高可用、分片分表等
- 各类问题的 Tradeoffs
这一步的关键在于要充分论述可能遇到的问题和解决方案/代价/取舍,可以使用可扩展系统的设计原则 来处理系统瓶颈。
小结
这个仓库 收集了很多系统设计类面试题并且有多国语言版本,感兴趣的读者可以自行阅读。
遇到过最困难 (挑战) 的事情
笨拙的人讲道理,聪明的人讲故事。
所以面试时我们要摆脱常规回答,学会 “讲故事”,那故事怎么讲,记住以下八个字,然后将自己的经历或想法套进去
- 目标:就是我想要做什么,我想要成为什么样的人
- 阻碍:做这件事的难点是什么,有哪些 “质疑” 点
- 努力:为了克服难点和 “质疑”,我做了哪些事情
- 结果:通过我的努力,我现在获得了什么样的成就
好印象和坏印象
描述你以前特别感兴趣或难忘的项目经历,后续的问题包括:
- 为什么你会觉得它有趣?
- 该项目最具挑战性的部分是什么,你又是如何应对这些挑战的呢?
- 你从这个项目中学习到了什么?你又希望在项目开始前了解什么?
- 你有考虑其他的设计或实现方法吗? 你为什么选择你做的那个方案? 如果再次选择做同样的项目,你有什么不同的做法吗?
优秀的候选人
- 充分地谈论项目经历,在面试中,与面试官的互动应当是对话而不是指导
- 对整个项目具有一定的了解,而不仅仅是他们所关注的领域,并且能够清楚地表达出项目的设计和意图
- 无论是什么项目,都要充满激情,并且能够清楚地描述出激发这种激情的项目要素
- 能够清楚地解释考虑了哪些备选方案,以及他们为什么选择他们所采取的实施策略
- 是否有从他们的经历中反思并吸取教训
好的候选人
- 在面试中可能会遇到一些问题,但是能够在面试官的帮助下解决
- 可能缺乏对项目更广范围的一些了解,但仍然对与他们直接交互的部分和特定领域具有很强的了解
- 也许看起来充满激情,但无法准确解释这种激情来自何处
- 也许能够讨论他们所做的替代方案,但是考虑的不够深刻
- 从他们的过往经历中反思并汲取经验
差的候选人
- 在面试交流中表现得费劲,面试官觉得面试者是在询问他,而不是与他交谈
- 即使是在他们工作的领域,也可能缺乏对项目的详细了解。他们可能不了解他们的产品为何这样设计,或者不明白产品是如何与其他系统交互的
- 当你在询问所做过最有趣的项目时,他们对产品表现得应该很感兴趣,但事实上是,他们看起来可能并不太感兴趣
- 可能不熟悉潜在替代方案的实现方法
- 似乎并没有从他们的过往项目经历中反思和学习,而判断这种情况的重要迹象是:“你学到了什么” 和 “你会有什么不同” 的答案很短,或者几乎千篇一律
你会如何考虑引入开源库
- 项目的活跃程度
- 项目的业务范畴、接口规格、实现是否符合预期
- 项目所处的状态,是快速迭代阶段还是进入稳定期、缺陷的数量与严重性如何
- 项目活跃参与者的背景
演员的自我修养
根据下面列举的问题,思考下你可能会遇到的 20 个相关面试问题,每个问题准备 2-3 种回答。准备点故事,不要只是摆一些你完成的事情的数据。
- 你为什么想得到这份工作?
- 你解决过的最有难度的问题是什么?
- 面对过的最大挑战是什么?
- 见过的最好或者最坏的设计是怎么样的?
- 对某个产品提出改进建议?
- 你作为一个个体同时也是团队的一员,如何达到最好的工作状态?
- 你的什么技能或者经验是你的角色中不可或缺的,为什么?
- 你在某份工作或某个项目中最享受的是什么?
- 你在某份工作或某个项目中面临过的最大挑战是什么?
- 你在某份工作或某个项目中遇到过的最硬的 Bug 是什么样的?
- 你在某份工作或某个项目中学到了什么?
- 你在某份工作或某个项目中哪些地方还可以做的更好?
反问面试官的问题
- 团队多大规模?
- 开发周期是怎样的? 会使用瀑布流/极限编程/敏捷开发么?
- 经常会为截止日期(deadlines)加班么? 或者是有弹性的?
- 团队里怎么做技术选型?
- 每周平均开多少次会?
- 你觉得工作环境有助于员工集中精力吗?
- 目前正在做什么工作?
- 喜欢这些事情吗?
- 工作期限是怎么样的?
- 工作生活怎么平衡?
- 部门负责业务权重,技术架构,成员组成,考核方式,开发流程?
- KPI OR OKR ?
- 面试官对自己的建议?
反问 HR 的问题 (钱的问题)
- 岗位晋升空间、晋升路线
- 工资构成
- 是否有奖金
- 年底奖金 (固定方法还是绩效评定)
- 其他补贴
- 五险一金缴纳比例
- 是否有额外商业险
- 远程办公支持情况
- 其他和你生活相关/冲突的问题