如何进行现场编程面试(包含 3 道完整题目)
上个月,我第一次参与了招聘开发人员的工作。能够运用研究生时期学到的教学技能和在Toastmasters演讲俱乐部培养的人际交往能力来测试候选人的技术能力和软技能,感觉很有趣。我想候选人们也挺享受和我面试的过程。
我认为,如果方法得当,现场编程面试是检验候选人技术能力和软技能的绝佳方式,也能让候选人了解我们是否是他们想要共事和学习的对象。可惜的是,很难找到关于如何进行现场编程面试以及如何编写高质量题目的教程。而找到实际的题目就更难了,因为它们通常都被保密,留待以后使用。
在本文中,我将结合我的教学经验,讲解如何设置现场编程面试以及如何编写高质量的面试题。我会分享我在面试中使用的三个题目——当然,下次我肯定要出新的题——并分析每个题目之所以优秀的原因。
1. 设置
我建议使用 JSFiddle和Google Hangouts进行在线代码面试。JSFiddle 只允许你编写一个 HTML 文件、一个 JavaScript 文件和一个 CSS 文件,这迫使你缩小问题的范围。它还允许你编写 Sass 代码并导入库。Hangouts 让屏幕共享变得简单。屏幕共享非常有用,因为我可以查看候选人屏幕上的控制台消息,并帮助他们调试代码。
在正式面试开始前,我会给候选人一个“Hello World”项目 ,并帮助他们熟悉页面操作。我会引导他们进入“设置”页面,并推荐使用 “标签页”布局——一种提供充足空间的双栏布局。
我还向应聘者解释说,正如 JavaScript 代码所示,他们可以像在正常情况下一样使用console.log和调试器来解决问题。我提醒应聘者,他们可以随时使用 Google 搜索或询问我该使用哪种方法(如果他们能凭记忆回忆起来,那就更好了)。最后,他们应该把自己的想法说出来,这样我才能更好地帮助他们并评估他们的技能。
准备工作完成后,我向候选人说明了1小时面试的流程,并得到了他们的点头同意:
- 前 5 到 10 分钟,我会问你一些关于你自己的问题。
- 接下来,我有3道编程题。理想情况下,每道题需要15-20分钟才能解决。
- 最后,你们可以在最后 5 到 10 分钟向我提问。
- 你觉得这样可以吗?
这有助于应聘者为面试设定合理的预期和目标。我故意设置了三个问题,因为我知道大多数应聘者只能完成一到两个。我想了解应聘者是如何看待 自己时间不够用这件事的。
我不会透露我问了哪些人际交往方面的问题。简单来说,我建议你们设计一套适用于所有候选人的通用问题,并根据每位候选人的背景调整措辞。我认为人际交往方面的问题应该帮助候选人放松心情,练习与我们交流。
是时候进行现场编程了!让我们来看看如何编写好的问题。
2. 什么才算好问题?
对于一小时的面试,我建议准备三个实际问题,每个问题包含三个部分。所谓实际问题,指的是你在工作中遇到过,而且应聘者也会遇到的问题。
对我来说,一个好的问题应该满足以下五个条件。如果你的问题没有满足所有五个条件,请尝试重新编写。
a. 你的初始代码易于理解,并且运行没有错误。
通过编写简洁明了、运行无误的初始代码,我们帮助所有候选人从同一起跑线出发。候选人之后引入的任何功能或错误都只能归咎于他们自身。
编写入门代码并非易事,需要练习。一般来说,应使用清晰的名称,添加注释,以自然的方式介绍三个部分,并指明候选人应该在哪里编写代码。
我建议你把初始代码发给同事们测试问题,并利用实时反馈进行迭代。(之后别忘了请他们喝啤酒或咖啡!)
b. 每个部分都涵盖了你希望候选人具备的一项技能。
如果我们期望候选人精通所有技能,那就太不合理了。如果每个部分只考察一项技能,而大多数开发人员会完成两道题,那么我们最多只能测试候选人的六项技能。这迫使我们思考,对于候选人而言,哪些技能才是真正重要的,才能帮助他们胜任这份工作。
c. 每个部分都有不止一个解。
我们的方法不应是解决问题的唯一途径。鼓励应聘者探索自己的解决方案。解决方案的类型、简洁性和可读性将体现应聘者的编程经验。
d. 这三个部分都具有故障安全功能。
每个部分都是一个独立的岛屿,自成一体。如果考生在一个部分失败了,也没关系;他们仍然可以解决其他两个部分,证明自己的能力。
理想情况下,这三个部分是相互独立的(即可以按任意顺序解答),但这并非总是可行。如果考生第一部分失败,而第二部分又依赖于第一部分,我们会帮助他们完成第一部分,以便他们能够继续完成第二部分。
e. 用户界面显示你很享受创建问题的过程。
面试压力很大。因此,我们需要设计一个能够体现我们对问题深思熟虑的用户界面,因为我们重视了解候选人的技能(包括软技能和技术技能)。这样做可以帮助候选人放松心情,发挥出最佳水平。
3. 面试期间
在候选人开始解答问题之前,我会先解释问题的用途和应用场景。我会给他们几分钟时间查看初始代码并提出问题。在候选人尝试解决问题的过程中,我会静静地观察并记录他们尝试过的方法和时间。
如果代码中有错误,我不会立即打断,而是给应聘者时间运行代码,看看效果如何。但如果出现后续错误,我会尽早解释如何改正,以便应聘者有更多时间解决实际问题。
最后,如果候选人在解决某个问题时遇到困难,我会一步一步地帮助他们分析思路,并全程提供支持。总而言之,现场代码面试的目标之一是帮助候选人了解与我一起工作和向我学习的体验。
4. 示例
我们来看看我设计的题目。在这三个题目中,我都为考生完成了 HTML 和 CSS 部分,这样他们就可以专注于 JavaScript 的学习。此外,您还会注意到,我在示例代码中使用了原生 JavaScript 方法。
我有两个理由。(1) 我的团队使用Ember框架,大多数候选人之前都没用过,他们可能需要几个月的时间通过复制粘贴来学习。我想看看,当候选人遇到不熟悉的原生方法时,他们能否参考我的代码来编写新的方法。(2) 由于原生方法是所有框架通用的,我不会让不熟悉特定框架的候选人处于劣势。
a. 搜索和排序数据
启动代码:
涵盖技能:
- 第一部分:读取嵌套对象的数组
- 第二部分:过滤器数组
- 第三部分:数组排序
我非常喜欢这个问题,因为它展现了我们公司应用程序的核心功能(我们经常处理数据)。我希望应聘者具备阅读、搜索和整理数据的能力。
我提供的初始代码处理的是数据始终存在的简单情况。我喜欢挑战我的候选人,让他们处理数据有时会缺失的实际情况。我让他们在第一部分就遇到第一个错误——如果他们只是简单地复制粘贴我的代码,表格中会显示“undefined”——这样他们在第二部分和第三部分就会更加谨慎。
考生能否完成第二部分和第三部分(数据搜索和排序)取决于他们是否完成了第一部分(数据读取)。如果考生未能通过第一部分,我会确保帮助他们完成第一部分,以便他们能够继续完成第二部分和第三部分。在帮助他们的过程中,考生也能感受到我的指导能力。
为了进行排序,我让候选人自行选择选项,这样他们就能感受到自己对面试有一定的掌控感。如果候选人通过了面试,我会给他们一些附加题:你会如何修改代码以实现降序排序?如何允许用户在升序和降序之间切换? 为了节省时间,我要求他们只需描述答案,无需实现。
b. 优化渲染
启动代码:
涵盖技能:
- 第一部分:现有代码
- 第二部分:重构代码
- 第三部分:理解大O符号
我之所以写这篇文章,是因为我在工作中使用D3时遇到了性能问题。当我在D3中绘制数千个元素时,添加和移除高光(改变不透明度)会导致帧率显著下降。我想到一个巧妙的技巧,但我还没有在其他地方看到过类似的记录。
这次,我提供的初始代码没有任何注释。我向应聘者解释说,在第一部分,我测试的是他们阅读他人代码并向我解释的能力。我感兴趣的是了解他们在代码审查中的表达能力。
在第二部分中,我向考生们展示了highlightListItem和resetHighlights方法,并解释说计算t0、t1和timeElapsed以及设置innerHTML 的代码是重复的。他们会如何重构这两个方法?
在第三部分,我要求他们用大O符号表示高亮列表项。如果他们不熟悉大O符号——没关系——我会用屏幕上的内容(回想一下故障保护机制)来解释它的含义。随着列表项数量的增加,改变透明度所需的时间会如何变化?我鼓励考生通过将第一行中的数字从1000改为2000、4000和8000来探索这种关系。
我接着问:你们觉得有可能把 highlightListItem 算法 做成常数时间算法吗?也就是说,无论列表项有多少,改变透明度所需的时间都保持不变? 我更感兴趣的是他们讨论和推理的能力,而不是给出正确答案。
c. QUnit 测试
启动代码:
涵盖技能:
- 第一部分:查找数组长度
- 第二部分:使用控制台
- 第三部分:理解异步性
作为一名从数学家转型为开发者的开发者,我热爱编写测试。Ember 将测试视为一等公民,甚至在其教程中专门讲解如何编写测试,这让我倍感自豪。据我所知,目前还没有其他框架能做到这一点。
也就是说,第三个也是最后一个问题并非真正考察候选人编写测试的能力。我更想检验的是他们是否能够使用控制台来理解代码的运行情况,并从 DOM 中获取信息。此外,我还想考察候选人是否理解异步操作,这是他们在从后端获取数据并将其发送回后端时经常会遇到的问题。
5. 接下来怎么办?
致所有开发者(包括面试官和候选人):我希望我已经向你们展示了如何进行实时代码面试以及这样做的好处。我鼓励你们尝试这三个问题(请点击“Fork”创建副本),并根据你们的工作经验编写自己的问题。别忘了分享你们的题目,帮助其他人进行实时代码面试!
文章来源:https://dev.to/ijlee2/how-to-conduct-a-live-code-interview-with-3-full-problems-2h4n





