硕士期间的处女面给了阿里,感觉还是收获蛮多。我感觉如果面试做到了逻辑思维中罗胖子所说的“有种、有趣、有料”,那肯定就没问题了。有种就是回答面试官问题胆大心细、有自信;有趣就是要和面试官聊的很开心,有共同话题;有料当然是基础够牢固,代码能力够强,算法能力够扎实,项目经验够充分。话又说回来,如果自己没料,又怎能去有种和有趣,所以还是一句话能力最重要,其次要掌握一些面试技巧,应该就没问题了。
今天去参加阿里巴巴的面试,安排的时间是早上10点40,昨晚没睡好,不是因为面试,而是看网易新闻,看到太晚,最后看得太精神睡不着了。10点左右就赶过去了,然后签到,还发了水和早餐,接着在一个小会议室等待。等待期间听到几个中科大在聊天,他们3个中有一个进了2面,正在等2面,心想科大的都被刷成这样,我也就只能打个酱油了,从他们几个那了解到2面就是终面了(回来听师兄说,其实有些人会有3面的,估计都是神级别的)。基本准时工作人员让我去到另一个会议室面试。
来到面试官(简称他为罗吧)前,给了他简历,他没让我自我介绍,首先问了我下笔试感觉答的怎么样,我说除了选择中的概率题目其他选择题没问题,大题做的不太好,他说还是比较自信的啊,然后就没继续谈笔试了,在我说话的时候,他扫了下简历,然后让我讲了下我简历上的一个项目,然后在我讲的时候,罗说你们的项目其实涉及到了分布式,里面有个问题--单点故障,然后让我想一种处理这个单点故障的方法,我根据分布式数据库中的方法讲了下,他说也只能这样了。接着罗问我熟悉哪些数据结构,我说从顺序表、链表、栈、队列、树、堆都有了解,他接着问顺序表和链式表有什么区别,为了将话题引向了C++,我说如果比较顺序表和链表的区别,可以从C++的vector和list比较下,vector顺序结构,list双向链表,没等我继续说下去,罗就说vector查找快O(1),list插入快O(1),C++容器里有没有一种插入和查找都是O(1),我想哪有这样的,说没有,他说map啊,没用过?我说map基于红黑树查找不是O(1)啊是logn的,罗说反正不是O(n),可能是我听问题的时候听错了吧。然后问了些C++的东西,首先问我 C++为什么要继承,其实我感觉这种问题更不好回答,我说可以缩减代码量(居然忘了代码复用这个词),罗说还有多态嘛,然后问我多态是怎么实现的,其实这个问题我想肯定会被问到的,我说是通过虚函数表实现,然后罗写了三个类A、B、C,B、C均继承自A,均有虚函数f,然后定义了3个指针,让我画下虚表,其实很简单,不过我说错了一点,我说虚表保存在对象内存空间的最前面,然后罗说如果虚表保存在对象的最前面的话,那么每实例化一个对象都有一份拷贝,是不是有问题,接着说程序运行都有哪些内存空间,我说当然是栈、堆、全局、代码段,然后他问虚表应该放在哪,我突然发现自己理解错了,对象中保存的应该是指向虚表的指针,虚表在代码段啊(后来在群里讨论才知道虚表是放在rdata,虚表也是运行时不变的),虚表具体内容参见 C++学习之深入理解虚函数--虚函数表解析,不得不佩服面试官每句话都听的很清楚,而且能找出问题。然后问我项目中用到多态的例子,我突然想到前段时间师兄要在项目中加一个小的内存池,里面对不同大小的类型内存分为不同的队列,为了便于管理,不同类型继承自同一个基类,通过虚函数实现各自的内存分配,介绍的时候我说到了里面用到了工厂模式和单例模式,罗问我还熟悉其他设计模式,我说就是从gof23的了解了下,平时也就是使用单例和工厂模式,还问我看了多久gof23。后面话题到了智能指针,他问我auto_ptr与shared_ptr的不同,我从转移权和共享说了下,然后说让我写一下auto_ptr的实现,这个对看过C++primer和BOOST的来说不难,我写好后他说,你是不是看过实现代码,我说是的,然后问我auto_ptr有什么问题,我从作为函数参数会发生指针管理权转移和不能管理数组,因为析够调用的是delete说了下。然后话题转向了算法,问我算法怎么样,我居然很诚实的回答很一般,感觉有点犯2,然后他说那好,我们来玩个游戏,问我玩过扫雷没,我说没怎么玩过,他说那不影响回答这个问题,问题是在一个保存了0、1的矩阵中,现在给一个坐标i,j,和(i,j)在同一个连通块内(即数字相同)的数字个数:如下图,输入(i,j)=(2,2)返回5,(i,j)=(4,5)返回1,我想到的是按数据结构书中讲解迷宫求解的方法,分四个方向进行深度优先搜索(根据坐标和来的方向判断剩下3个方向是否被访问过),然后简单写了下递归实现的代码。
写完后,他看了下,然后看了看表,说我给你的时间只能到这了,问我有问题问他不,我问了阿里是不是java很多,C++的很少,他说不是,不要看笔试题附加题是道java题就这样想,还是很多做C++的,然后闲聊了几句,就出去了。一面持续了1个多小时,结束都快12点了,整体聊的很开心,出来工作人员要我等一下,我想应该是进2面了,大概不到5分钟,就被叫去2面。
2面是两个面试官,感觉一个是技术(简称为唐),一个是hr,接下来的一个1小时就是被虐啊。首先还是要我介绍下我们采集组的项目,然后唐得出的结论就是我们的项目就是在买来的硬件上面稍微加了点代码,感觉自己太不会吹项目了,然后就是问项目中涉及到的多线程,居然又问到了线程和进程的区别,还有就是什么时候用线程,什么时候用进程,这个问题平时还真没认真思考过,感觉好难回答,可以参见这篇博客线程or进程,仅仅从线程和进程的区别回答了下,然后唐问我多进程和多线程程序的代码量,我说千行级别(在一面的时候也有问到我C++的代码量)。然后又转到了C++上面,唐问我看过哪些书,我说C++primer、BOOST,然后就让我实现下boost里面的shared_ptr,在写的时候将引用计数部分写错了,改好引用计数后,又被告诉线程不安全,问我如何解决线程安全,我说对引用计数操作加锁,然后唐要我写下线程安全的shared_ptr的reset成员函数,唐在这他提示我当引用计数到0后,析够是在锁外还在锁内,我简单写了代码,然后他又问我加锁的代价,这个我直接回答了没关注过这个问题,然后唐说他的问题完了,女hr开始发问,首先她先问了下我本科学校,然后问是个专科?着实鄙视了我下,接着问题就是认为本科和现在的自己最大的区别是什么,我实话实说地告诉她,忍耐力强多了,现在所里面的活全是没技术的,很是不喜欢干,自己还是忍下来,耐心做好了,不像本科那样,感觉回答地太不合女面试官的口味了,唉~~,第三个问题是以后打算做那个方向,我居然说想去做游戏开发,感觉说错了,说实话自己真没想好做哪个方向,所里面的项目太坑,真的是迷失了方向,然后就是乱谈。接着问我有什么问题,我问了唐对我整体评价,还有该如何学习C++,他的意思我感觉还是要注重项目中多用,不要空学。
二面大概也是持续了1个小时左右,整体感觉一面还可以,二面就被虐了,女hr的问题也没回答好,回来后去官网看结果:终面未通过,已在意料之中。
这次面试的收获:
技术方面:
(1)要有解决实际问题的能力。面试官可能会提出一个问题,要你给出解决方案;
(2)要注重细节,技术要理解透彻,比如这次的“引用计数只能指针”,不仅会用,而且自己能实现。我们看C++方面的书,经常看到一句话“避免重复造轮子”,记得Boost程序库完全开发指南的作者说过,这句话应该这样理解:非不能也,是不为也。
(3)算法和代码都很重要,代码量确实能反映一个码农的水平。
其他:
要能适当的吹嘘下自己的项目,让面试官感觉项目有技术含量。还有要准备一些常用问题的回答方法,尤其是最后hr的问题,要回答的有水准。看别人的面经都说,面试不能太诚实啊,不能暴露太多缺点,感觉确实如此。