经常有人问我:
“请问我 LeetCode 刷了多少道题就能去某某公司了”
“我 LeetCode 刷多少道题是不是就能去 xxx 公司了?”
这种思路其实特别像我们高三时候讨论的:
“我高考考了多少多少分就能上一本?”
“去年清华的录取分数线是多少分?”
我国的做题教育已经深入我们的脑子里面了,以至于很多人在工作以后还是这种思路。LeetCode 是一种非常好的练习自己算法能力的方式,如果没有任何解题能力是肯定通不过算法轮的面试的。但是算法轮是不是就是在考察候选人的 LeetCode 能力?其实算法只是一种比较容易标准化的面试方式,真正考察候选人的理解问题的能力,通过和面试官交流去沟通去搞清楚需求的能力,编码能力以及算法和数据结构知识。
上面这个视频是我帮一个同学 mock interview 的视频,我出了一个算法题:
假设一个公司每个员工都会汇报给经理,员工之间有时候会有矛盾或者不同意见,这种时候我们需要找到这两个员工共同的经理来解决这个问题。所以我们需要写一个函数,找到两个员工的共同经理。
这个时候,有 LeetCode 高手已经在说了,这道题我刷过,这不就是 LeetCode 235 Lowest Common Ancestor of a Binary Search Tree 吗?来,看我给你 30 秒给你秒了这道题,接着迫不及待的开始写代码了。
做为面试官我当然知道这个题目的本质就是 LCA。但是我期望的并不是仅仅是候选人把代码写出来,我期望的是,他能先搞清楚这个需求。这是我假想中的对话。
Q: 员工只会汇报给一个经理还是多个吗?(我描述的时候特地漏掉了一个)
A: 对,只汇报给一个经理。
Q: 请问什么是共同经理?
A: 共同经理是两个员工汇报线上层级最低的经历,这个经理同时管理或者同时间接管理这两个员工。
Q: 假设这两个员工中,一个已经向另外一个汇报了,那么共同经理是谁?
A: 这种情况下我希望返回经理的经理,否则就不公平了。(LeetCode 上是返回两个节点中做为祖先节点的那一个。很多人也会这么实现,这个时候等他写完代码我就会把这个 corner case 给提出来,然后要求候选人改。有不少人改的时候磕磕绊绊,所以最好的是一开始就把所有的情况考虑到再写代码)。
Q: 有没有人不汇报给任何人?
A: 有,这个公司的最高级的人,比如 CEO。 这种情况,我们就返回 CEO。
假设候选人把问题都搞清楚了,是不是就可以开始写代码了?其实,还没有,这个时候我希望候选人把自己的算法解释清楚。很多中国工程师在这上面就吃亏,因为自己用英文解释不清楚,巴不得马上把代码写出来,仿佛写出了代码面试官肯定就能懂。其实站在面试官的角度,代码肯定是可以看懂的,因为每个面试官问来问去也就那么几道题(比如我的题库就两道题),这个题目他已经见过十几个人写了。但是,在工作中,你用英文把自己的想法或者技术方案给解释清楚,也是基本要求。某些中国工程师(包括我),因为英文不好,虽然技术牛逼(我技术也不牛逼),但是在 team 中的存在感很低。
现在到了写代码的阶段,面试官主要考察你的代码熟练度。假设候选人说自己用某某语言 3 年,但是脱离了 IDE,连变量声明或者类声明的语法都写不对,那么我会怀疑,他这 3 年到底有多少时间在写代码。我之前面试过一个当前 title 是 principle engineer 的候选人,谈吐什么都很好,但是就是写代码非常不熟练,结果我只能在反馈上写:
这个候选人做了很多高层级的工作,但是感觉很久没有写代码了。如果这个工作需要写代码,那么他不是很适合。
除去面试熟练度,变量命名也是很多人扣分的点,变量命名非常随意,比如用单字母来命名变量。
当写完代码以后,面试官会期望你写设计测试案例。注意是设计测试案例,不只是写测试案例。很显然,你是不是不可能写无穷尽的测试案例的,针对上文的题目, 我认为好的测试案例有:
– 一个普通的 happy path
– 输入的员工不在系统中
– 输入的两个员工其中一个已经是另外一个的经理了
– 输入的两个员工是同一个
– 有一个输入的员工是 CEO
如果一个候选人能够主动设计这些测试案例,说明他平时写代码有非常好的测试习惯。反之,则会扣分。
综上,一个成功的算法面试流程是:
1. 理清楚需求,问清楚边界条件,系统限制,异常情况该如何处理。
2. 解释清楚你的算法,必要的话可以画图或者写伪代码来解释。
3. 等面试官认可你的算法之后,用代码去实现你的算法。在写代码过程中,可以写一段然后说一下,自己现在要干什么干什么,确保面试官一直在跟着你的思路。也做好随时回答面试官问题的准备。
4. 写完实现以后,主动写测试案例。通过自己的测试案例找出 bug 其实是加分项。设计好测试案例,测试案例要有代表性。
5. 讲一下自己算法的时间复杂度和空间复杂度,然后等面试官有没有其他问题。
从面试官的角度来说,主要是想考察面试者:
– 理清楚需求的能力
– 解决一个问题的能力,解决问题的思路
– 表达沟通能力
– 对于某个编程语言的熟练程度
– 测试习惯
– 基本的数据结构和算法复杂度的知识
综上所述:
多刷 LeetCode 是重要的,能保证我们在算法轮碰到一个问题能够马上想到一个有效的解法,但是算法轮的面试并不是等于 LeetCode。其实国外科技公司面试也没有那么难,我经理就多次开会说过,面试不要问 DP,因为那种题目更加像 brain teaser,和实际工作没啥关系。那我自己来说,我 LeetCode 周赛也就 1700 分,但是我面试 Facebook 也能拿到 offer。
我们经常会在所有面试轮数以后开会,每个面试官说一下自己的评价。每个人都需要给出充分的理由来说明为什么给 Yes 或者 No。有时候大家吵的不可开交,经理就经常问:“你愿意和这个人一起工作吗?你希望他在你们团队里面吗?”我相信每个工程师都希望自己的新同事是一个能解决实际问题,好沟通,在某个方向有很深积累的人,而不仅仅只是一个 LeetCode 刷得很好的做题家。
好奇问下文中视频的面试者的英文可以胜任工作吗?感觉有点不够流畅啊
我感觉还差点,可能行为面试的时候会比较困难。