最近有一个关于技术面试的发现:很多简历漂亮的应试者面试的失败率其实很高。有这么几个失败模式:思路糊涂、解题方向迂回,毫无分解地把所有逻辑扔在一个大函数里面,最后代码错误连篇(比如说把数组的指数和内容搞混、off by one、if 不用 else、漏掉几个if case什么的),或是缺乏测试的概念。这些误区如果有点准备或是培养一些好的面试习惯,其实是可以避免的。
不同公司的面试目的不太一样。类似于Google和脸书的大公司喜欢在白板上考算法和数据结构,其实也就是你的算法101课有没有上好。类似于Stripe和Clever的小公司喜欢考你的专项(如网络前端、移动端、或者运维大数据什么的),也让你自带电脑当场写能编译能运行能测试的app。其实这是因为大公司往往都有很庞大而复杂的系统、所以技术决定中效率很重要,同时也有大把有经验的员工可以慢慢培养你上手(比如脸书就有6周的bootcamp、谷歌前3个月也会给你一个专门拿来上手的bootcamp项目)。小公司则需要你立刻马上能写出能用的东西,所以会看重你会不会用他们的技术展,以及能自己在没人带的情况下能否写出可用并靠谱的代码。当然各种公司也会根据职位、需求、和心情(也就是当天一共有那些面试官能面)调整面试的种类和考点。
每个公司都有自己的面试风格,他们到底看重什么样的技能和什么样的人,以及以往都面过什么样的题,你大可在glassdoor上面搜一下。当然每一个公司有那些利弊和面临哪些问题,glassdoor上面也有。很多小公司其实很重视让应试者提问的面试环节,特别是在后期面试的时候。因为这能看出来你到底有多了解你面的公司以及他们的市场,他们也会由此判断你到底是真心想去呢,还是只想多拿一个offer以便跟别人谈谈价。
举个例子,有一种Coding面试。它的目的不是考算法,是考你能不能想明白一道逻辑相对比较复杂的题,写出正确易读的代码,并且显示出对测试和边缘情况有良好的直觉。适合面coding的题目大约有两种:一种是模拟某种体系或游戏(某纸牌游戏或桌游、模拟某种简单的流程),需要你充分理解一个相对复杂体系并且选择合适的数据结构去表现它。另一种是一个运用很多语言基础并有很多边缘情况的题,如数组和字符串的处理分析运用和正则表达式。目的是考你对你自己选择的语言的熟悉度、也考你对测试和边缘情况的习惯和直觉。为什么重视这个?也许是因为每一个没有考虑到或者测试到的bug或者边缘情况会导致几个月后有人很多晚上不能睡觉。
这种面试有这么几种常见的失败原因:
思路问题
没思路直接写代码,然后代码变成巨大一坨的nested while / for loop和好几个实际上重叠的cascading if,最后自己被自己写的东西绕晕。其实你最该做的第一件事就是确保你正确理解了面试官给你的题目。一种失败模式是应试者解一个多玩家游戏,花了大量时间去写出2玩家版的精确代码,但是要最终写n玩家版的时候发现2玩家的版本完全不能generalize。这种情况其实可以不纠结于立刻写代码,可以花点时间确保你的解题思路正确、从而确保你的代码分解比较合理,然后整段代码很好读。
光说不写。这里的失败模式是应试者做一个关于字符串运用的题,纠结了半天这个字符串到底是要从头开始parse还是从尾开始parse,到底是要用递归(recursion)还是用while loop,到底要在哪个level of abstraction分成两个不同的函数,最后扔出了一堆听起来很高大上可是这个简单的题目根本用不到的算法和数据结构的名词可是扯了30分钟就是没写出一行代码来。其实从头parse还是从尾parse,本质上没那么大的区别。虽说能简单iterate的东西你用递归有那么一点点非主流但只要你代码干净也没人会歧视你。重点是30分钟后白板上没有代码,你说出一朵花来也没有用啊……
代码可读性、测试、和边缘情况
代码中off by one, array out of bounds, missing if cases, division by zero, empty string其实都是很容易犯的错误。我们自己容易看不清,但是经常看我们写代码的人经常比较容易可以看得到。所以你一个函数写完的时候,最好自己读一遍看看有没有这些bug。最好不用面试官提醒你就自己改掉,如果全部代码写完了,最好也不用人提醒,自己拿一个输入的例子把代码过一下,看看有没有漏掉的边缘情况和bug。如果你觉得没有,最好也把你所有的假设重申一下,确保你跟面试官在同一条线上。比如假设你假定输入必须是正数而面试官没有给你这个假设的话,他就会认为这是你漏掉的边缘情况。函数和变量的命名,其实不要求你在白板上长篇大论,毕竟时间少写字慢。可是要避免的一种情况是自己把自己绕晕,然后在代码里面出错。这里的一个例子是应试者把数组的指数叫i
,数组的内容叫curr
。本来要i%1000
,可是每次都写成curr%1000
,但curr
其实是个字符串。这样的无心之错不是不可以有,但是如果太多,也许体现的是你函数和变量的命名有点问题,自己把自己绕晕了。这一类型的问题大多是小问题,有一两个无伤大雅,然而基本上是个减分的效果,积小成多,太多了也就致命了。
祝好运。