这学期开始的时候,某个晚上宿舍都在写自己的简历,我自然也在写了。说这点只是想说这学期的所谓面试准备其实是很不充分的,至少是没怎么实现寒假所计划的那个样子。然后短短的寒假也基本都是在美赛后在家里写写代码看看机器学习,各种基础学科都没开始复习。也只是简单地用Word参照网上的模板做了一下自己的简历。
算法,语言基础,网络,操作系统,数据库,这些课在三月初都是重点准备的内容。投简历的时候,面对一直纠结过来的问题:我应该做什么岗位,终于知道了答案。虽然自己唯一做过比较大的项目是用PHP写的一个网站,但其实自己对PHP和Web后台的理解还远远不到半点了解深入的程度,所以基本上都决定投和C++研发相关的岗位,然后打算靠着复习概念重新捡起来。等部分招聘信息开始通过同学转发等渠道传过来的时候,自己也已经知道各大公司的招聘主页才是最直接的投递方式,T厂和A厂的校友内推都投了,然而最后都是没有结果。
最早开始的笔试是本地的企业CVTE,在广工做试卷。印象其中最难的只有用C++实现STL中的vector的两个函数,和怎么找出一个无序数组中的中值。下午就是网易TTT计划的笔试题,比较记得的有判断大端小端的方式,堆排序的代码,一些SQL语句。最后一题是一个POJ上的题,1088。然而这题最后没想对方法硬用动规,其实只要记忆化搜索就好了。网易考完以后觉得发挥得不好,所以很意外能过。
CVTE的技术一面,也就是我的第一次面试,是去萝岗区的他们公司总部,面试官是一个三十多岁的大叔。他看完我的简历问我要不要去后台,觉得我不适合C++岗,我坚持要面,然后后面的表现估计让他很失望,因为真的暴露出自己很多的复习不充分。
首先是要写一个拷贝构造函数,没给定场景,于是我直接写一个很简单的给他。写完以后气氛是尴尬的。他一副“就这样了吗”的眼神,然而我并不觉得有太大问题。但其实想一下,拷贝构造函数在遇到指针拷贝的时候,其实是存在深拷贝和浅拷贝的问题的,那时的我当然知道,但一方面出于对自己的掌握程度不够自信,另一方面不如说是以前读书做题一个很自然的习惯,题目条件不充足时,按简单的写,防止自己写多错多(高考的一个解题策略),所以只是设想一些简单的变量赋值。这就涉及到面试的一个特点。面试既然本质只是一个考察你水平的过程,往往你不是答出一个“没说错”的答案就够的。如果场景不给具体你,你就应该以一个有工程素养的人的角度去思考,在不同情况下,应该是怎么样的。就像这题其实考察你对深浅拷贝的理解的意图很明显,只是我实在图样图森破。
还有印象的问题有,你觉得C++适用于什么场景,STL有什么性能限制,Deque和List的区别,红黑树的特点,这些我基本都没答好或者没答出。数据库里,B树和B+树又有什么不同呢?答错。C++一般有什么主流的编译器呢,只说出两个。Linux命令问出一个应用场景也问倒我了。带着不可能过的确信,我的第一次技术面结束了。
心理上,我了解到其实面试没有我想象中紧张,因为会和不会我都能从容地应对,包括我答错的时候,面试官的那种眼神也没给我带来太大压力。我那时复习得并不充分也略盲目,反而给了我一个复习的方向。
去科韵路网易总部的一面,面得更顺利,最后也是没过。印象问了机器学习和网络爬虫的一些问题,所以也讲到了美赛的题目。面试官手上有你的笔试卷,笔试的选择题有几题犯了低级错误也被挑出来问了,这大概有很大的扣分。
室友在CVTE的二面那天中午接到了神马的电话,我预感下午或者傍晚也会有电话打来一面,果不其然。问到设计模式,我说我最近在看四人帮的那本书,他让我举例。于是我讲到MVC和单例。然后引下去问C++中单例模式如何实现。面试官对编译原理的那个词法分析器和数字图像处理的雾霾处理都很有兴趣,于是我也讲了很久。还有就是C++的delete[]操作符是如何知道数组大小的,多态动态绑定底层是怎么实现的,进程通信的方法。算法很走运地被问到一个很熟悉的问题,是找出大数组的第K大个数。我讲了分别在堆排以及快排上的两种改进。这次的面试感觉发挥得挺好的。
感觉面试官其实很少会对编译原理的那个SQL解释器有兴趣的,然而这个面试官不但很有兴趣,似乎他本科这门课也学得很认真。至少他还记得龙书上词法分析器的优化,我讲的是双缓冲区的优化,他告诉我书上有另外的方法。关于去雾霾的那个算法他也提出了自己的看法。在这个交流过程中,如果你能让对方感受到你不但是一个能解决问题,而且对解决问题和获取新技能都有热情的人,那么真的会是一个大大的加分项。我想项目经历的意义更多在于此吧。正如曾坤老师所说的那样,重点不一定是你做了什么,更重要的是你怎么实现。在讲项目经历的时候,如果把重点放在你的优化过程是能够加分的。而这一点只要你都有认真做过那个项目的话,面试前回顾一下就足够了。
神马的技术二面是在星期五下午。因为在上图形学,只好约一个晚点的时间然后中途出教室在隔壁教室等电话。第一次进二面还是挺紧张。面了两次,每次都一个多小时。
都是一些更深入的问题,第一次问了预编译的命令里定义宏的局限性,一个项目的整个编译的过程分为什么,你用过什么调试工具和测试工具,在大项目中如何使用。讲到SQL解释器,因为我说到用map来实现数据库表,他便继续问红黑树的原理,和Hashmap和map的区别,如果要在我们的项目上添加Group By操作要怎么做,TCP的四次挥手是什么,Linux下文件去重的命令,还有一些爬虫的实现。
第一次还问了两个算法题,一个是在分布式系统下利用MapReduce找出重复的数,还有在大的整数数组中找出和绝对值最小的三个数。第二题我最后在面试官的引导下一步一步地想出了一个并非最优的解法:先排序,对于每两个数的组合,二分查找出他们和的相反数。第一次的一些知识性的题我其实答得模棱两可,因为有一部分是不太懂的,比如我甚至不知道C++有Hashmap,不确定MySQL是否能添加多字段索引,出了大洋相。
第一次过后从教室回到宿舍,还没歇下来电话就来了。新的面试官还是对编译原理的那个项目有兴趣,顺着我讲的项目经历,问文件IO的时候使用文件流读写的缺陷。基类指针转换为子类指针时的注意事项,一道估算一座跨珠江桥的车流量的思维题,一道概率的计算题。在MapReduce模型下,找出URL相同而排名不一致的搜索记录。他还问了一下我对机器学习的了解,于是我还是举美赛中K均值的那个例子。
面完下来已经快八点了。第二次感觉自己虽然面的时候很蛋疼,但发挥得不坏。思维题那里,题目的参数,比如说桥的长度,车速,他都要求我估算出来,而这是我始料未及的。后来我才想到条件的不足,因为需要加入安全行车距离。(这不就是上年美赛那题么=-=)我想我最后思路都讲清楚了。并且我也通过二面的几个算法题能够确认这是要做搜索引擎相关的程序。
结束以后我发现我阿里的状态已经变了,也就是神马和阿里其他的主干校招是一起的。后来就是在周末某晚俱乐部聚餐的时候突然打来的HR面,最后是过了。
腾讯没过的一面是我这次招聘季的最后一次面试。一开始讲进程通信,CPU调度的方法,感觉很顺利。但当问到MySQL有什么引擎,我只能列出两个而且不知道区别。数据库的事务讲不清楚。算法题,双向链表排序,使用O(1)空间,O(nlgn)平均时间,避免O(n^2)最坏,要怎么做?这道我现在还不懂问人也不懂的题大概成为压倒骆驼的最后一根稻草。腾讯也是妥妥地跪了。
总结下来,对通过BAT级别的研发岗面试应该做什么准备心里有了底:
- 你说得过去的项目经历。不是说做得多就好,而是能够体现你技术能力与素养水平的项目。从这个意义上,如果你只有课程设计的项目也没什么大不了的。
- 基础的知识。包括一些What型知识和其衍生出来的Why型知识,主要是网络,操作系统,数据库,设计模式和编程语言的知识,通过牢固基础和复习应对。
- 算法。也就是How型知识,我想也只能通过多思考多练习来提高。进微软的室友整个面试过程几乎没有问What型知识,而是很多很多的直接写码的算法题。因为其实What型的知识你只要能复习得好都没什么问题,有些还只有那个答案,除非再问深入否则不能很好地反映你解决问题的能力。我想这是Google微软级别的企业和BAT的一个区别。
- 使用工具的经验与能力。比如说测试工具,调试工具,Linux命令行工具等等,这些也是要靠平时积累的。感觉总体并不占特别大的权重,微软的面试也没有问。
- 让对方感受到你能力水平的表达技巧。比如说你讲自己看某本书,某篇论文,某个课程上学习到了什么,你怎么把它们运用起来。在遇到不会或是不确定的问题时也不沉默,而是让对方看到你的思考过程。有人是能用实力把这个因素盖过去的。
- 运气。当然不能说没。比如说我刚好碰上一个对编译原理有研究的面试官,或者刚好碰上一题思考过很久的算法题。有人是能用实力把这个因素盖过去的。
准备的书目除了基本的课本,对于C++来说,Effective,More Effective和深入探索对象模型是极好的。我反而没怎么看面试金典和编程之美。
总算没给软院拖后腿了。自己总结下来也是感触良多的。通过率奇低的这次招聘季,同时打击了自己的自负与自卑。离目标还有很远,还得看接下来的锤炼吧。
写于去杭州前,和两门科目考试修罗场之前。
没有评论 :
发表评论