商汤见习计算机视觉实习生
上周给在商汤实习的同学发了简历,和HR约了本周四的面试,周五就又接到HR的电话,商议Offer的事宜。不得不说,商汤招聘的效率还是很高的。这也从另一个侧面反应出,其十分缺人手的事实。很多商汤的同学都在询问我,有没有其他的同学可以推荐过来实习。
商汤校友被誉为“北航实验室”。因为其招聘了大量的北航实习生,正式员工很多也是实习生直接转正的,本科的时候,就有几乎一个班都在那里实习。
而我面试的时候,推我的是我的一个一直在那里实习的同学,一面的面试官是我大三编译实验课的助教,二三面的面试官也都是我的本科同学。可以说,如果你是北航的学生,那么进入商汤会比其他学校容易很多。
我面的组是"商汤研究院基础技术与工具组“,算是在研究院里偏工程的组了。总体的面试过程还是很硬核,很高能的。好几次我都以为自己不行了,好在面试官及时给出一些hint,帮助我走下去。下面,我记录一下3个面试的流程。
一面
一面面试官是此组的lead,今年刚刚毕业转正。我一直觉得他很眼熟,后来和同学交流过后才想起来,这不是2年前检查我编译实验的助教哥哥嘛!
因为是lead给自己招人,所以一面总体上节奏很紧,内容也很充实。依次问了我职业规划、项目经历和2道算法题。
职业规划主要是与将来实习工作内容相关,从超级硬核的嵌入式和操作系统,到优化深度学习框架和库,再到优化计算机视觉的策略和算法。
项目经历主要问了我的2次实习和毕业设计,并问了我对之前的哪部分工作和实习最感兴趣。我当然把之前的实习都表扬了一边,然后再比较出自己对快手的实习最喜欢了。从和面试官的问答过程中我感受到,他对面试者是否真的想做某件工作、是否对其感兴趣很看重。
算法题有2道:
- 给出一个01串,给出0和1数目相等的最长子串的长度。比如’00100110011’的最长字串的长度为10.
- 有1-n个路灯,对其进行n次操作,第i次操作为将编号是i的倍数的路灯状态取反。初始状态为都灭,问对于给定的n,最后有几盏灯是亮的。
都不算很难的题目,虽然没能一下子解决,但最后都在面试官的hint下成功解决了。表现的不算太好,也不算很差。想解法的时候一度感觉自己要凉了,要丢人了。好在问题本身不是很难,经过更多的思考和尝试还是解答出来了。只有第一道题要求手写代码了,我用Python很快写完了。我用二维列表实现的桶,面试官指出,用Map难道不是更优雅吗?第二题解法过于简单,没必要写代码。
经验总结就是,虽然我代码能力还行,LeetCode也刷了有100道Easy难度的题目,但并没有形成自己的一套解题的流程,也没有对于每一类问题的归纳总结,可以快速地找出合适的算法。
更多的是依靠灵感和尝试。比如第一道题,我最开始一筹莫展,但再尝试几次后,偶然想到可以先把前缀和计算出来(遇0减一,遇1加一),之后就迎刃而解了。和LeetCode上一些字符串比较的问题很像。
这种依靠灵感和尝试的解决方案,首先不是每次都奏效,如果状态不好,可能就不行了;其次是不靠谱,做题的时候心里没谱,对于题目能不能成功解决心惊胆战的。
所以,在面对未来更多的面试和dream job之前,形成自己稳定可靠的解题流程是必要的。
二面
二面的面试官是我的本科同学,但平时交流并不多,他属于比较geek的类型。
这位同学刚开始比较不善言辞,问我一面都面了什么,会写什么。我判断他作为面试官的经历其实也不多,并不擅长。稍稍有些放松和欣喜。
不过很快,他真的是用技术教我重新做人了。慢慢熟悉起来之后,他也进入了面试的状态。从操作系统(从shell敲入命令到程序被执行中间发生了什么,进程的建立过程)问到编译器(编译的过程,每一步的细节),从编译优化(循环展开)问到CPython的实现(全局变量的处理,Python是如何运行的),看到我用过Django,又问我框架的实现,model的实现。问我哪门语言比较熟,我说Python,就问了我很多Python实现的问题。问我看过什么Python的大型项目的代码吗?我只好汗颜地说没有。
整场面试除了刚开始几分钟比较轻松外,后面的节奏越来越快。每个问题都是越来越深入,直到我实在回答不上来为止。
应对这种类型的面试,我只能说,CSAPP和SICP的真的很重要。虽然我都只看了几章,但硬是凭着不深的记忆硬扯。比如Python的运行过程,我之前根本没有了解过。刚开始只说是解释运行,对方要求更详细些,从开始到运行完毕的过程是怎样的?我想Lisp也是解释语言,就把老早之前在SICP上看过的Lisp运行过程说了下。面试后我查了查Python的运行过程,惊喜地发现真的差不多。CSAPP对编译和进程有很深入的介绍,如果对这2章更熟一点,我面试时一定会更从容。没有读过大型项目的源码也是我的短板。说实话,真的没有多少人读过很多大型项目的源码。但是我们是要向大牛看齐的,多读读源码,才能成为更优秀的程序员。
三面
三面的面试官也是我的本科同学,稍微还熟悉些。最后一面由不同组的同学负责,被称为跨组面试。防止有组内私自招收不合格员工的情况发生。
既然比较熟,面试过程就比较轻松了。先是依次问了项目经历,之后又问了1道语言题和一道算法题。
语言题涉及到Python的闭包,
就是理解
1 | [lambda x: x + i for i in range(4)] |
和
1 | def func1(i): |
的区别。
不知道多少年前看过廖雪峰Python的教程上闭包相关的内容,只有些许印象,平时也不用。只记得变量i
有时会变化,产生意料之外的结果,比如前者。好在在面试官的hint下有惊无险。
算法题是关于DP的,
给定n <= 20, a_i < 100, 整数s
,求解有多少种正负号的填法使得等式成立$$ \sum_i^{n} \pm a_i = s $$
我给出解法后,面试官又问,构造表的时候s为负数时怎么办?
后记 | 感悟
有一个清晰的职业规划和技能方向是十分重要的。平时和师兄聊天的时候可以说自己也不知道做啥,不知道对啥最感兴趣。但面试时这样说肯定就gg了,最好最自己有比较清晰的认识,知道自己的兴趣,职业规划,当然这些和面试职位的需求相符那就更好了。如果不相符的话,大概率也会gg,搞不好还会被喷(参考我5月时面试face++的面试经历,在我的博客上可以找到https://youngforest.github.io/2018/08/14/face-interview/)。
今年算法岗大火,以至于供过于求。算法岗也处于程序员鄙视链的上游,薪水也比研发岗高一些。
但我结合自己的经历和体验,发现自己还是对写代码比较感兴趣,写出更优雅,performance更高的代码,满足用户的需求,产生impact。我就很开心和满足了。虽然做程序员很辛苦,但是我很开心。没必要追求别人认为好的职业(鄙视链大概是:研究员 > 算法岗 > 研发岗 > 其他)。
我以后也会顺着研发这个方向规划自己的职业,学习必要技能的。
我曾经给好友说过,“我想写一辈子代码”。现在仍然是这样,而且更加坚定了。