我讨厌编码面试已经不是什么秘密了。
他们是一种糟糕的招聘方式并且容易出现误报(也就是不必要地拒绝优秀候选人)。对于大多数公司来说,提出白板式的问题并不符合他们的最大利益。
不幸的是,它们是行业标准。作为一名软件工程师,您必须在求职过程中回答白板上的问题。
所以,这是我如何擅长于它们的框架。
能力触发器
这个框架依赖于我在数十次面试过程中发现的一些能力触发器。我还看到这些技巧对我指导的工程师很有用。
我所说的“能力触发器”是指您可以展示的一种做法或可以说出的短语,可以清楚地表明您知道自己在说什么。向面试官发出信号的小而轻松的时刻:这个人明白了。
坐在桌子的两边,我知道最好的候选人在编码面试中会做一些关键的事情:
- 提出好的问题来澄清需求
- 编写测试并寻找边缘案例
- 在陷入细节之前要全面思考
8步框架
这是我回答面试问题的过程。我在面试的任何时候都使用这个框架,每次几乎完全一样:
- 提出问题并重申预期目标——当面试官给你问题陈述时,问一些澄清问题并用你自己的话重申问题。即使您完全理解问题,也可以将此作为展示能力的一种方式。
- 搭建解决方案、伪代码——不要立即深入研究代码。相反,请使用注释/伪代码粗略地概述您的解决方案,以展示您的一般方法并让您从整体上考虑问题。
- 直截了当地说,“这看起来合理吗?我走在正确的轨道上吗?” — 在采访的早期阶段,征求反馈意见。让你的面试官有机会向你指出不同的方向。你会惊讶于面试官经常说:“听起来完全正确!” 或者,“有趣的是,你很接近,但你有没有考虑过……”Free 很早就暗示了解决方案!
- 编写一些实现,做简单的部分——不要太沉迷于困难的部分,而是用一些真实的代码替换你的伪代码,这样你就可以开始运行它了
- 编写快乐路径测试用例和测试运行器——这是一个巨大的能力触发器。预先编写一些简单的测试用例,为您的代码运行提供真实数据。目标应该是让您的代码尽快运行。
- 迭代代码,直到解决快乐路径测试用例——这是面试的实际工作。解决这个问题。但是请注意我们是如何只在第 6 步解决问题的。到目前为止,您已经为解决问题奠定了良好的基础。
- 寻求优化并直截了当地问,“这能更高效吗?” — 这是许多候选人错过的一步。与面试官一起寻找优化方法(如果有的话)。讨论运行时间和权衡。另一个重要的能力触发器是讨论权衡和替代实施的能力。
- 测试边角案例——当您的快乐路径测试案例正常运行时,不要就此止步。另一个重要的能力触发器是证明您了解如何查找边缘情况和处理错误。
Fizzbuzz 示例
假设您被问及经典的fizzbuzz 问题。
- 从明确要求开始。我什么时候应该停止迭代?3 和 5 是否被硬编码为间隔,或者嘶嘶声和嗡嗡声除数是否可变?函数的返回值是多少?数字是字符串还是整数?
- 搭建解决方案——我需要一个空列表。有一个 for 循环来遍历整数。有一些逻辑可以决定将什么附加到每个整数的列表中。最后,我应该返回列表。我会直接问面试官,“这看起来合理吗?有什么我想念的吗?
- 编写一些解决方案——定义函数
def fizzbuzz(stop: int)
。初始化一个空列表result = []
。开始一个循环for i in range(stop):
。在循环中,我需要一些逻辑,但我们先不要深入。在循环中的某个时刻,我需要result.append(i)
. 然后,用 结束函数return result
。这肯定还没有解决问题,但它给了我工作的结构。让我们运行它! - 写一个测试用例——起初,我可能会做一些类似的事情
print(fizzbuzz(3))
,只是手动查看它是否打印出来[1, 2, 'fizz']
。我可以python fizzbuzz.py
从命令行运行它。但我们需要更全面的测试,所以我可能会创建一组test_cases
并迭代它们以查看我的代码产生的结果。 - 迭代代码 — 现在,我实际上已经准备好搞乱 fizzbuzz 的逻辑了。我可以尝试我的代码并重新运行测试,直到我做对为止。
- 寻找优化——在这种情况下,可能没有太多优化。还是挺好看的。但这
fizzbuzz
是一个线性问题,因为您需要为每个整数打印一些东西。 - 测试极端情况——当你执行
fizzbuzz(0)
or时会发生什么fizzbuzz(-1)
?我是否需要处理无效输入的情况,例如fizzbuzz('a')
orfizzbuzz(None)
?
示例代码
昨晚我和一位教练客户一起完成了这个练习。这是我们在短短几分钟内使用该框架得出的结论:
def fizzbuzz(stop: int):
"""On multiples of 3, print 'fizz'
On multiples of 5, print 'buzz'
On multiples of both, print 'fizzbuzz'
For all other numbers, print the number
"""
result = []
for x in range(1, stop+1):
if x % 15 == 0:
result.append('fizzbuzz')
elif x % 3 == 0:
result.append('fizz')
elif x % 5 == 0:
result.append('buzz')
else:
result.append(x)
return result
test_cases = (
(-1, []),
(0, []),
(1, [1]),
(3, [1, 2, 'fizz']),
(15, [1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz']),
)
for stop, expected in test_cases:
actual = fizzbuzz(stop)
try:
assert actual == expected
print('PASS!')
except:
print(actual, expected)
框架的价值
在像面试这样压力很大的情况下,有一个可以依靠的框架是非常有价值的。当你觉得自己陷入困境时,只需按照步骤设置你需要的工具——脚手架、单元测试,以及你可以从面试官那里得到的任何提示。
希望这会有所帮助!关于面试还有其他问题或意见吗?给我回信。
每日清单
我每天早上都会为软件开发人员写一些新东西。