技术面试准备清单
本文旨在总结常见的技术面试流程步骤,并汇集招聘人员在面试前通常会发给求职者的一些实用建议。这并非一份全面的面试指南,实际的面试步骤可能因公司而异。
面试流程概述
面试流程(按时间)
常见的技术面试流程主要包括三个步骤:
- 与招聘人员进行电话面试时,你将被要求讲述你的经历并解释你的动机。
- 技术电话面试,您将被要求实时解决一些技术问题。
- 在公司办公室进行现场(面对面)面试,您将被要求解决技术和系统设计问题以及回答一些行为问题。
面试流程的意义
所有面试步骤主要由以下三个构成部分组成:
- 解决问题。这里主要关注的是你通过应用不同的算法方法和数据结构来解决技术问题的能力。
- 系统设计。这关考查你能否将多个部分(框架、方法、数据库、微服务)组合起来,设计出一个能够成功解决特定任务的整体系统。
- 行为问题主要关注您的经验、动机、领导力和软技能。
让我们继续讨论面试过程的这 6 个方面。
[Time 采访] 介绍电话
招聘人员会进行自我介绍,并详细介绍公司和你可能参与的项目。你需要自我介绍,并解释你在之前项目中的职责。
通常只有你过去1-3年所做的事情才重要。所以,请关注你最近的成就和责任。
介绍您最近工作中的副业项目、开源项目和生产项目。
它将通过电话的方式完成。
要记住的事情:
- 熟悉职位描述并准备与职位相关的问题。
- 根据您的个人资料、职业经历、资格和教育背景准备一份简短的自我介绍。
- 使用具体的例子。最有力的例子是基于工作的例子,但你也可以使用学习或个人的例子。
- 如果您不明白面试官的问题,请他们重复或进一步解释。
- 了解公司,对公司的产品(公司正在做的事情)充满热情。
- 请随意询问有关该职位或公司的任何疑问。
清晰地解释你的经验示例。使用 STAR 技巧可以帮助你:
- 情况/任务——描述您所面临的情况/任务以及故事的背景。
- 行动——你采取了什么行动?
- 结果——你如何衡量这个项目的成功?你取得了哪些成果?
📚 探索链接
ℹ️️️阅读下文,了解有关如何准备行为面试的更多信息。
[Time 采访] 技术电话面试
在电话面试期间,您将进行编码练习(或在线开发某些东西的任务)。
通话时长为 45 至 60 分钟。
有些面试会有两人参加。不用担心,其中一人会纯粹为了培训目的。
您需要使用网络摄像头。建议使用有线网络和耳机,但并非必需。您的电脑可能需要安装插件,因此请务必在通话前预留充足的时间测试招聘人员提供的链接。请确保在安静的环境中接听电话。
您可能会被要求安装和/或使用特殊程序和服务,例如:
面试期间会发生什么:
- 初次面试需要 45 分钟,面试者会问 1-2 个编码问题,面试时会使用白板(如果在现场)或笔记本电脑以及类似 CoderPad 的服务(如果是远程)。
- 您将接受问题解决能力和核心 CS 基础技能(理论、算法、数据结构、设计模式、递归、二叉树问题、斐波那契数列等)的测试。
- 您需要考虑一个高效、优化且无错误的解决方案,以便使用您最擅长的编码语言快速、简洁地编写代码。
- 保持简单!如果你觉得显而易见,那可能就是显而易见的。先从一个简单的解决方案开始,然后再考虑如何提高效率。
ℹ️️️阅读下文,了解有关如何准备解决问题面试的更多信息。
[按时间采访] 现场采访
现场面试通常有 4 到 5 次——至少 2 次严格专注于编码,1 次专注于设计,1 次专注于对话/编码。所以基本上本章开头描述的三个基本要素都会涵盖在内。
面试结束后会有45分钟的午餐时间——很可能是和一位工程师一起吃的。您可以坦诚地与工程师沟通——他们不会提供反馈,但可以解答您在面试过程中可能没有问到的任何问题/疑虑。
ℹ️阅读下文,了解更多有关如何准备解决问题、系统设计和行为面试的信息。
[意义面试] 问题解决面试
一般提示:
- 解释——面试官希望了解你的思维方式,所以在整个面试过程中,请解释你的思维过程和决策过程。记住,他们不仅评估你的技术能力,还评估你解决问题的能力。明确地向面试官陈述你的假设,并核实这些假设是否合理。
- 澄清——许多问题会特意采用开放式提问,以便深入了解你在技术难题中重视哪些类别和信息。面试官希望了解你如何看待问题以及你解决问题的主要方法。务必详细阐述你的思考过程,如果需要澄清,可以随时提出具体问题。
- 改进——思考如何改进你提出的解决方案。大声说出你对问题的初步想法是值得的。很多情况下,你的第一个答案可能需要一些改进和进一步的解释。如有必要,可以从最开始的强力解决方案开始,然后进行改进——只要让面试官知道你正在做什么以及为什么这样做就行。
- 练习——面试期间你无法使用 IDE 或编译器,所以最好在纸上或白板上练习写代码。务必测试你的代码,确保其易读且无 bug。不要纠结于语法上的小错误,比如某个方法应该使用哪个子字符串(例如 start、end 或 start、length),只需选择一个并告知面试官即可。
面试前
练习!练习!练习!
限制自己的时间,因为速度在面试中很重要。
问题示例:
- 编写代码来打印二叉树每一“行”的第一个元素。
- 实现井字游戏。
- 编写代码来显示给定字符串的排列数量和类型。
您可以使用以下服务来获取更多问题示例和可能的解决方案:
您可能还想阅读《破解编码面试》一书,它将帮助您准备与您在整个面试过程中要解决的问题类似的编码面试。
涵盖的主题:
- 编程——你应该精通至少一门编程语言,最好是 C++、Java、Python、JavaScript、Go 或 C。你需要了解 API、面向对象设计和编程,知道如何测试代码,以及如何应对代码中的极端情况。需要注意的是,面试官更注重对概念的理解,而不是死记硬背。
- 算法——使用自下而上和自上而下的算法来解决问题。你需要了解算法的复杂性以及如何改进/修改它。用于解决问题的算法包括排序(以及搜索和二分查找)、分治法、动态规划/记忆法、贪婪算法、递归或与特定数据结构相关的算法。了解大O符号(例如运行时间),并准备好讨论像Dijkstra和A*这样的复杂算法。了解不同类型算法的运行时间、理论局限性和基本实现策略比记住任何给定算法的具体细节更为重要。
- 排序——熟悉常见的排序函数,以及它们对哪些类型的输入数据有效或无效。效率指的是运行时和空间占用。例如,在特殊情况下,插入排序或基数排序比通用的快速排序/归并排序/堆排序要好得多。
- 数据结构——你应该尽可能多地学习数据结构。最常用的数据结构包括数组、链表、栈、队列、哈希集、哈希映射、哈希表、字典、树和二叉树、堆和图。你应该彻底了解数据结构,以及每种数据结构通常对应的算法。
- 数学——有些面试官会问一些基本的离散数学问题。面试前,花点时间复习(或自学)初等概率论和组合数学的基本知识。你应该熟悉n-choose-k问题及其类似问题。
- 图——思考一个问题是否可以应用图算法,例如距离、搜索、连通性、循环检测等。在内存中表示图有三种基本方式(对象和指针、矩阵和邻接表)——熟悉每种表示方式及其优缺点。你应该了解基本的图遍历算法:广度优先搜索和深度优先搜索。了解它们的计算复杂度、优缺点以及如何在实际代码中实现它们。
- 递归——许多编程问题都涉及递归思考,并且可能编写递归解决方案。使用递归可以为可以迭代解决的问题找到更优雅的解决方案。
- 面向对象设计——你应该掌握一些常见且实用的设计模式,并了解如何以面向对象的方式编写软件,并恰当地使用继承和聚合。你可能不会被要求描述特定设计模式的工作原理,但需要为你的设计选择进行辩护。
采访期间
解决之前:
- 不要直接进入编码,花几分钟来了解问题并提出任何澄清问题(但不要太久!)。
- 制定计划。在开始编写代码之前,务必仔细思考程序的总体结构。你不必考虑所有细节(对于更复杂的问题来说,这可能很难),但你应该充分考虑。如果没有合理的计划,你可能会被迫浪费有限的时间,重新编写程序中的重要部分。
- 向面试官描述您的解决方案并了解他们对您的解决方案的想法。
求解时:
- 大声思考。在编写代码时向面试官解释你的思考过程。这有助于你更充分地表达你的解决方案,也让面试官有机会纠正你的误解或提供更深入的指导。
- 分解问题并定义抽象概念。招聘人员寻找的一项关键技能是能够通过将问题分解为可管理的子问题来处理复杂性。对于任何复杂的问题,你都应避免编写一个庞大的单片函数。你可以自由定义辅助函数、辅助类和其他抽象概念,以达成可行的解决方案。你也可以利用设计模式或其他编程习惯用法。理想情况下,你的解决方案应该经过充分的分解,从而易于阅读、理解和验证其正确性。
- 优化。主动向面试官提出优化方法,并获取他们的反馈,以确保你正在做的事情不会过于复杂并且正确无误,然后编写代码。
你已经找到解决方案了。接下来怎么办?
- 考虑极端情况。当然,你应该努力寻找一个在所有可观察方面都正确的解决方案。有时你的解决方案的核心逻辑可能会有缺陷,但更多时候,你唯一的错误在于你处理极端情况的方式。(现实世界的工程也是如此。)确保你的解决方案在所有你能想到的极端情况下都能正常工作。
- 单步执行代码并进行测试。检查代码执行效果的最佳方法之一是模拟代码针对示例输入的执行情况。例如,使用之前的示例代码,确保其能够产生正确的结果。需要注意的是:在脑海中模拟代码的行为时,你的大脑会倾向于预测它希望发生的事情,而不是实际发生的事情。要尽可能地遵循字面意思,以克服这种倾向。
- 重新表述一下复杂性。它和你基于实际代码的最初设想是相同的,还是不同的?确保你同时考虑了空间和时间。
- 解释一下你采取的捷径。如果你为了方便而跳过了在“真实世界”场景中会做的事情,请告诉我们你做了什么以及原因。例如,“如果我是为了生产环境而编写的,我会在这里检查一个不变量。” 由于面试是一个模拟环境,这可以让面试官了解你在实际工作中会如何处理代码。
记住:
- 面试官只能根据你写的代码来评估你。
- 在整个面试过程中,谈谈你正在做的事情。如果你需要安静思考,没关系——只要告诉面试官就行。
- 如果您正在研究向您提供的解决方案,请大声思考,因为工程师会想知道您如何处理和解决问题。
- 如果面试官给你一些改进代码的建议,那就采纳并付诸实践。和面试官一起调整和解决问题,可以展现你的思维方式和解决问题的能力。
- 与面试官讨论初步想法和解决方案,这将有助于您澄清任何歧义。
- 从面试官那里得到提示来展示你的思维过程和解决问题的能力。
- 通常要避免使用大量边缘情况或冗长的 if/else 语句块的解决方案。在迭代和递归之间做出选择始终是重要的一步。
- 思考不同的算法和算法技术(排序、分治、动态规划/记忆、递归)
- 考虑数据结构,特别是最常用的数据结构(数组、堆栈/队列、哈希集/哈希图/哈希表/字典、树/二叉树、堆、图、布隆过滤器等)
- 不必担心死记硬背,例如运行时或 API/本机调用。知道如何即时计算出大致的运行时间固然很好,但你编写的代码本身更重要。
- 你会被问到关于 O(内存)约束、你正在编写的算法的复杂性及其运行时间——O(N²)、O(N)等
- 重要提示——考虑在整个面试过程中测试你的代码
- 确保你复习了递归。
- 确保你清楚你的基准案例是什么。讨论或实现动态规划解决方案可以获得加分。
- 在白板上练习编码。
面试后
尝试为面试官准备 1-2 个问题作为最后提问。
📚 探索链接
图书
你也可以查看JavaScript 算法书
课程
解决问题
杂项
- JavaScript 算法和数据结构
- 理解动态编程模式以进行编码面试
- 谷歌:我们如何招聘
- 谷歌面试
- Google 技术开发指南
- 准备 Facebook 软件工程师面试
- 在 Facebook 找到工作
- 五个基本电话面试问题
- 我在 Facebook 找到工作的故事
- 我应该准备和参考哪些资源来参加 Facebook 的软件工程面试?
- Facebook 面试问题
- 算法和数据结构
- 破解 JavaScript 面试的完美指南(开发人员的视角)
- 技术面试手册
- 30 分钟指南助你顺利通过下一次编程面试
- 技术面试速查表
- 理解面向对象设计面试
- 精彩的面试问题
- 与同行练习现场采访
[Meaning 访谈] 系统设计
你需要设计一个系统或产品,这个问题会很广泛且模糊,你需要创建一个端到端的、可扩展的东西。你不应该假设任何事情。你应该明确需求,招聘人员希望你在整个面试过程中能够引导对话。要积极主动,说出你正在做的事情/原因/你的理由。这应该是你的设计,而不是一半是你的,一半是面试官的。尽量兼顾广度和深度,你需要谈论高层次的概念和相关的细节。
面试官并不指望你了解特定领域的复杂算法(比如四叉树或 Paxos)。但他们确实希望你了解各种权衡,比如一致性、可用性、分区等等。他们也希望你使用现代计算机,并且了解内存、硬盘、网络等的吞吐量/容量的大概概念。
您应该熟悉的一些主题:
- 并发。你了解线程、死锁和饥饿吗?你知道如何并行化算法吗?你了解一致性和连贯性吗?
- 网络。你大概了解IPC和TCP/IP吗?你知道吞吐量和延迟的区别吗?以及它们在什么时候是相关的因素。
- 抽象。你应该了解你正在构建的系统。你大致了解操作系统、文件系统和数据库的工作原理吗?你知道现代操作系统中各种级别的缓存吗?
- 实际性能。您应该熟悉计算机所有功能的运行速度,包括 RAM、磁盘、SSD 和网络的相对性能。
- 估算。估算,尤其是粗略计算,非常重要,因为它能帮助你将可能的解决方案范围缩小到可行的方案。这样,你只需要编写几个原型或微基准测试。
- 可用性和可靠性。您是否考虑过系统如何发生故障,尤其是在分布式环境中?您知道如何设计系统来应对网络故障吗?您了解持久性吗?
- 数据存储(RAM 与持久存储、压缩、字节大小)
- CAP定理
- 字节数学
请注意,我们并不要求您成为所有这些领域的专家,但您应该对它们有足够的了解,以便权衡设计考虑因素并知道何时咨询专家。
如何学习
练习一下,拿任何一个知名的应用程序,想象一下你为竞争对手工作。你的任务是弄清楚:
- 他们的大部分资金都花在了哪里(计算?人力?带宽存储?)
- 他们系统的根本瓶颈。回答这两个问题必然会迫使你思考系统的实际实现方式。只回答成本和瓶颈问题会迫使你专注于重要的领域,而不是设计中的琐碎细节。
例如,YouTube 在带宽上花费了大量资金,其次是存储和计算。另一方面,他们的长尾流量模式意味着其根本瓶颈在于随机磁盘寻道。Netflix 也非常占用带宽,但他们的大部分流量都集中在夜间(流量便宜的时候),而且他们的视频库规模要小得多,所以磁盘寻道可能根本不是问题。把上述问题写在纸上,思考如何分解它们。
或许最好的学习方法是解决下面提到的问题,并思考如何分解它们。你可以在“系统设计面试入门”课程中找到很多例子。
示例问题:
- 设计一个新闻推送系统。
- 加速这个移动应用程序。
- 实施广告定位。
- 为 Google Photos 设计后端。
- 设计一个网络爬虫。
- 设计一个键值存储。
- 设计搜索引擎。
- 构建一个全球视频分发系统。
- 建立 Facebook 聊天。
好的设计可以表明:
- 清楚地了解问题并以逻辑的方式将其分解。
- 思考一下高层次的设计。
- 提出一个系统设计,将问题分解为可独立构建的组件。
- 随着系统规模的扩大,识别瓶颈并找出设计中的漏洞。
- 考虑所有相关的权衡。
- 了解当需求发生变化时如何调整解决方案。
- 绘制清晰描述系统中不同组件之间关系的图表。
- 计算使该系统运行所需的物理资源。
解决系统设计问题的方法
步骤#1:了解要求
用 1-2 分钟澄清需求。你可以给面试官举个例子来解释他们问的问题(例如:“为了确保我理解这个问题——我将设计新闻推送服务,因此我需要考虑‘推送中显示什么’、‘以什么顺序’、‘隐私’、‘延迟’、‘将系统扩展到数十亿请求’、‘冗余’等等——你指的是这个吗?”)。或者,你可以要求他们举一个他们希望你设计的产品或功能的例子。这里花费的时间不要超过 1-2 分钟。
进一步的例子:
- 对运行时间有什么要求吗(在线路径与离线路径)?
- 用户在哪里?
- 有多少用户?
- 存储要求?
- 数据访问或保留要求?
- 安全要求?
- 移动端还是网络端?
- 我们需要对外公开哪些 API?有哪些集成选项?
最后,在继续之前,先问问自己哪些需求比其他需求更强?例如,数据一致性、延迟、可靠性和数据隐私方面是否存在强需求?你能列出一个优先级的有序列表吗?不要在这里花太多时间,但至少要提出问题——了解设计系统时需要权衡哪些因素至关重要。例如,当速度和一致性至关重要时,你应该考虑同步调用。如果可以容忍一定的延迟和响应变化,那么异步/队列也是可以的。
步骤#2:了解可以帮助您估算的事实/数据
有用的资源:
- 每个程序员都应该知道的延迟数字(文本)
- 每个程序员都应该知道的延迟数字(PNG)
这更清楚地表明,您需要从 SSD 读取数据,而不是从磁盘读取,并且肯定不会进行多次数据中心往返。此外,您还需要注意互斥锁和对共享资源的访问。
现在,你需要估算所需系统的规模——甚至在开始设计之前。以下是一些需要思考的问题:
- 我们预计会有多少个 API 请求?(例如 QPS 是多少?)
- 这些请求将返回什么数据?(字节、兆字节或千兆字节)
- 是否会有读取和写入操作或只有读取操作?
很有可能,你会在这里得到很大的数字。但最好能表明你明白,并非所有问题都需要用分布式、可扩展的系统来解决(有时一台机器就能搞定)。
步骤#3:深入研究/设计
你可能有很多事情需要考虑。你可以走到白板上写下相应的概念,例如:
- 要求,
- 缩放,
- 实体设计,
- API 设计,
- 数据存储,
- 安全/隐私,
- 日志/分析,
- 可靠性。
任何设计都需要涵盖很多概念。你可能无法全部了解,但重要的是展现你对“大局”的理解。把这些概念写下来也有助于加快面试的节奏,并帮助你记住尽可能多地阐述这些概念。
在考虑实体建模和设计(系统中将包含哪些对象,以及它们之间有何关系?)时,请写下一些对象及其之间的关系。在设计 API 时,请务必指出该 API 可供外部和内部开发人员使用(例如,可供移动应用、Web 应用使用,以及打包为 SDK 供外部开发人员使用)。思考一下调用此 API 时会发生什么?这里有两篇关于此主题的优秀文章:
写出整个系统的拓扑结构。从总体上看,它几乎总是看起来像这样。
数据存储(数据如何在客户端和服务器上物理存储,以及如何访问)。你几乎肯定会设计一个分布式系统,所以你需要考虑如何进行分布式处理(有时也被笼统地称为“如何分片解决方案”)。这意味着——当你收到用户的请求时,你如何决定将请求发送到哪个后端服务器?上图中的“负载均衡器”如何工作?你会根据用户名、地理位置还是两者的结合,将数据发送到不同的服务器吗?这里重要的是思考如何均匀地扩展请求。
还要考虑缓存:客户端和服务器端都需要缓存什么数据?缓存的原因是什么?如何使缓存失效?(会基于时间吗?如果是,时间是多长?)
安全/隐私
- 谁可以看到什么?
- 权限怎么样?
- 但是员工怎么办?他们可以访问哪些数据?这里是否引入了新的数据类型?
- API 是否需要特殊密钥才能运行?用户是否会向外部公司授予权限?如果是,我们将如何监控滥用行为?
日志分析
- 我们关心哪些指标?如何记录这些数据以便计算这些指标?
- 我们会保留数据多久?
可靠性
- 我们需要监控我们推出的新服务
- 我们需要能够测量延迟
- 我们需要发布服务水平协议和指标
📚 探索链接
杂项
- 理解系统设计面试——本课程对常见的系统设计面试问题进行了周到而清晰的解释
- 系统设计入门——大规模学习系统资源的有组织的集合。
- 如何在系统设计面试中脱颖而出——系统设计面试中值得了解的概念总结。
- Interviewbit 上的系统设计教程——涵盖大量理论的结构化练习,并包含具体的练习。
- 系统设计速查表
- Bitly:构建每月处理 60 亿次点击的分布式系统的经验教训
- 理解系统设计面试
- CAP定理
谷歌论文
【意义访谈】行为访谈
很多人犯了一个错误,就是没有为面试做准备。
一个好的起点可能是思考亚马逊的领导力原则,并结合你职业生涯中的一些具体情况,作为每项原则的例证。清晰地解释你的经验案例。运用STAR技巧会对你有所帮助。
以下是一些行为问题的示例:
- 告诉我你曾经遇到过一个问题,它有多种可能的解决方案。问题是什么?你是如何确定行动方案的?你的选择结果如何?
- 你曾经冒险、犯错或失败过吗?你是如何应对的?又从中吸取了什么教训?
- 描述一下你领导一个项目的经历
- 当您需要激励一群人或鼓励在特定项目中进行合作时,您会怎么做?
- 您如何利用数据来制定战略?
- 您能举一个您收到过的有价值的反馈的例子吗?
- 描述一次你在团队中遇到分歧或冲突的经历
- 您的同事如何描述您?
- 你能描述一下你必须接受一个你不同意的决定的情况吗?
- 描述一下你最近犯的一个技术错误?你从中学到什么了?
- 您曾经解决过的最困难/最具挑战性的问题是什么?
- 如果事情没有按计划进行,您如何推动自己/您的项目向前发展?
- 您如何寻找机会?
- 您如何在团队内部以及与其他团队之间进行沟通?
- 你最大的失败是什么?你从中学到什么了?
- 你什么时候收到过建设性的反馈?你是如何应对的?
回答问题时,应专注于问题本身,确保答案结构合理,并在适用的情况下使用指标或数据提供示例。尽可能参考近期的情况。
- 我们将考察您的领导经验,这可能包括技术领导、项目或产品方向、制定架构和设计决策、指导工程师和人员管理等诸多方面。
- 面试官会对你的热情和动机感兴趣。
- 面试官将了解您当前的角色、您正在做的事情、您的所有权以及您产生的影响。
- 冲突管理——如何处理与同事和经理的冲突和分歧。
- 您从过去的错误中吸取了教训,接受了反馈并采取了行动。
- 面试官会对不太顺利的事情以及你从这次经历中学到了什么感兴趣。
- 面试官会对你如何应对我们非结构化的环境以及如何完成自己的工作感兴趣。
📚 探索链接
希望以上汇总信息对您有所帮助。祝您下次面试顺利!
鏂囩珷鏉ユ簮锛�https://dev.to/trekhleb/technical-interview-preparation-checklist-4m4f