最近,我差点儿就拿下了 FAMGA(CSDN 编者注:国内有 BAT,国外有 FAMGA,即 Facebook、Apple、Microsoft、Google、Amazon。)的工作机会。通过了电话面试,代码笔试题也顺利通过了,但最终却在一对一或二对一面试中翻了船:
白板编程面试:算法;
技术面试:JavaScript,CS,React;
文化适应性:你们懂的;
第二次白板编程面试:回头再写一篇文章吧。
问题出在哪里?
导致这次面试失败的原因可以归结为我犯下的几个错误。
我估计我通过了技术测试和文化适应性测试(假设如此吧),但我承认在白板编程测试阶段表现得很糟糕。
回想下那天的经历,我都不期待有什么好的结果。
真相是:我根本没有准备好做白板面试。
白板面试
白板面试是一种混合的技术测试手段,能同时测试对知识的理解程度和社交能力。
来源:https://skillcrush.com/2016/03/29/rock-your-next-whiteboard-test/
这个应该是众所周知了吧?其实考察的不是编码能力,而是解决问题的能力,不会这个那个的其实也不要紧……
我是个前端开发,通常我不会写任何面试题中用到的算法,也不会在编码过程中把我的思路表达出来。绝大部分时间我都在写交互式 UI。
这种测试又能反映出候选人的多少情况?
有人甚至说:
在真实世界里,你几乎从来不会在编程过程中凭记忆写一段算法。绝大多数情况下总是会用已有的库,这个库经过完整的测试,并且已被许多开发者们验证是正确的。
唯一需要回忆算法的情况就是在大灾变之后……网上所有计算机的硬盘被毁,所有基础科学的学术论文和教科书也都烧成了灰……
我的意见和上面某个意见很相似,尽管我更倾向于相信这种技能(善于白板面试的技能)要求的是拥有一系列其他软技能和硬技能。
客观原因
我先列个单子,尽管一些情况和你的情况相同,但我列出它们的主要原因是我得喘口气😄。
我不是用母语面试的。在别人的注视下非母语会变得更困难。
我是个自学的前端开发,非科班出身,没有学术准备。
我的职业生涯中经历过的面试并不多,有限的面试中白板面试的情况更少。
我不经常在公众场合讲话。很不幸,但至少目前来看没多少。
你可以说这些根本不是客观原因嘛。你说得对。
根据定义,客观原因是指我们无法控制的原因,但实际上我可以提高英语水平,学习更多的 CS,参加更多面试,更多地在公众场合讲话。
接下来,我将试着解答下本应该在那天完成的白板面试题,然后报告下进度。
测试题
['Tokyo', 'London', 'Rome', 'Donlon', 'Kyoto', 'Paris']
// YOUR ALGORITHM
[
[ 'Tokyo', 'Kyoto' ],
[ 'London', 'Donlon' ],
[ 'Rome' ],
[ 'Paris' ]
]
题目就是这样。
一个城市的名称经过旋转后可能正好是另一个城市的名称。将所有匹配的城市名称放在同一组。
在工作中需要经常在数千行代码的迷宫中探索,但要想用这个简单得甚至搞笑的问题向那些人证明自己,有多困难?请系好安全带……
假设这样进行面试
这部分是我的解题方法,包括代码和思路。谁知道还有没有别的方法!
我:非常感谢。我很高兴能为你解答这道题(微微鞠躬)
我:首先问个问题,字符是只能“旋转”还是可以任意随机组合?
拉里(为保护面试官的隐私,这里用了假名):只能旋转。第一个字符移动到最后一个。每次只能移动一个。
有许多评论给出了他们的解法。首先感谢大家,我会认真阅读的:)但找出完美答案并不是本文的重点。同时请注意我给面试官的问题。许多评论的解答忽略了这一点:字符只能一次旋转一个。单纯.split 再.sort 是不够的。如果这样做,那么 tokyo 和 yookt 这种组合就会被放在一组,但实际上是不对的。Tokyo 只能和以下几个匹配:okyoT,kyoTo,yoTok,oToky。看到了吧?5 个字符只有 5 中可能的组合。这是个提示。请继续看。
我:对!我想我首先要旋转每个城市的字符。Tokyo 会变成 okyoT,然后 kyoTo,嗯,赞!这样就有 kyoto 了。所以得写个函数来做旋转。
我:还需要循环输入的所有城市,并“旋转”字符,进行匹配,最后再进行分组。我发现输入和输出都是数组,两者都包含同样的值,唯一的区别就是两个数组的深度,一个是一维数组,另一个是数组的数组。
还是我:我来写一些伪代码来验证我的想法。稍后我还会做测试,因为我很优秀。😏
function groupCitiesByRotatedNames(cities) {
// use a variable to contain the output.
let output = [];
// loop through each of the cities
// rotate the name in any possible combination
// check if the output contains a city that matches a combination
// add that city to the array containing the match
// otherwise add the city to the output as a new array
return output;
}
像明星一样自信的我:来伪测试以下我的伪代码(😛)。
const input = ["Tokyo", "London", "Rome", "Donlon", "Kyoto", "Paris"];
console.log(groupCitiesByRotatedNames(input));
// That's how it would build up. The final output would be the last array:
// [
// ["Tokyo"]
// ]
// [
// ['Tokyo'],
// ['London']
// ]
// [
// ['Tokyo'],
// ['London'],
// ['Rome']
// ]
// [
// ['Tokyo'],
// ['London', 'Donlon'],
// ['Rome']
// ]
// [
// ['Tokyo','Kyoto'],
// ['London', 'Donlon'],
// ['Rome']
// ]
// [
// ['Tokyo','Kyoto'],
// ['London', 'Donlon'],
// ['Rome'],
// ['Paris']
// ]
现在开始实现算法。
首先是旋转城市名的字符的函数。建一个工具函数(Utility Function):
我:现在让代码更干净些(也更难懂些)。(迷之自信)
我:对了!我喜欢 reduce,要多用一些!(reduce 也更函数式一些,所以面试中要多使用😎)
reduce()函数将函数应用在累加器和数组的每个元素上(从左到右),将数组合并成单个值(MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)。
最后的单个值就是输出。
总结一下这个算法的工作原理:
首先检查城市数组中的每个亨氏,然后旋转名字,再把每个组合与累加器的值进行匹配。
如果找到了匹配,则将城市名字添加到包含匹配值的数组中(使用 Array.splice),否则产生一个只包含当前城市的新数组。
当当当当!
放在一起!
Gist 在此:
https://gist.github.com/albinotonnina/e5eb9589f3a2322678b75461ac230181
这个解法并不是最好的,但确实是我那天想到的。(复杂度是二次多项式时间,你可能想要用线性的 O(n)时间的算法解决)。
实际的白板面试
直接从解答开始。我说,好,我需要个 reduce 方法。便立即到白板上写代码,而没有先想想该怎么写。我确实有一点思路,基本上与上面说的相同,但我没有描述,没有向可怜的面试官解释这个算法。所以我在代码里迷失了方向,中途思路中断了好几次,还出现了语法错误,代码也是伪代码和真实代码的混合。这时已经没办法挽救了。这种面试行为会极大地损害面试的结果,特别是混乱发生在自己身上时。
经验和教训
练习,练习,练习。
找一块白板,找个问题,对着空气讲出你的想法并写出来,然后反复练习。
练习白板面试,学习实际的面试过程。自己的面试过程,或者任何面试过程都可以。就像在吉他上学习唱歌,学习变魔术或危险的冰上动作一样。
你得准备一次演讲。白板面试就像演说一样。
白板面试就像一次充满变数的演讲。
可变的是面试题本身。
我以后要这样做:
首先花点时间分析需求(1 分钟)
如果有必要,确切地复述问题并获得答案(3 分钟)
暂停一下,确定解题方向(几分钟,不要怕片刻的沉默)
提出初始解决方案,并获得面试官的反馈(5 分钟)
暂停,选择解决方案(2 分钟)
写伪代码(5 分钟)
测试伪代码(5 分钟)
将伪代码变成真实代码(如果需要的话)
大约 30 分钟就能用愉快、有目标的方式解决面试题。
结论
附录:
1. 这里有些关于本文的很有意思的讨论:https://dev.to/albinotonnina/how-to-lose-a-it-job-in-10-minutes-35pi
2. 资源
Evana Mp 写了篇很好的评论,她允许我把她总结的白板面试资源列表贴在这里。我觉得这些资源非常有用!
她说:我把我从许多网站上与此有关的问答中收集到的资源做了个列表,按顺序分别是书、网站和课程:
书籍:
Cracking the coding interview
Introduction to Algorithms
Programming Interviews Exposed
Clean code
Algorithm Design Manual
How to Think About Algorithms
Programming Pearls
Data Structures And Algorithms Made Easy In Java 2nd Edition 2nd Edition
网站:
InterviewBit
HackerRank
Codewars
Codefights
AlgoExpert
CarrerCup
Interview Cake
LeetCode
Geeks for geeks
Pramp
HackerEarth
HiredInTech
课程:
Coderust 2.0
英文:How to Lose an IT Job in 10 Minutes
链接:https://hackernoon.com/how-to-lose-an-it-job-in-10-minutes-3d63213c8370
作者:Albino Tonnia,前端工程师。
译者:弯月
征稿啦!
————— 推荐阅读 —————