每一次面试都是对技术的提高(上)

工作已经有一个半月了,一直想要写写有关找工作面试的一些事情,但是又没有写。其实我并没有像身边的一些朋友那样,有很多的面试机会,经历了很多不同公司的面试过程,好像整个研究生的最后一个学期里面,我主要就面了Amazon和Facebook两家公司,当然还有毕业后面试的现在进了的公司。所以我主要也只是想写写我面试Amazon的整个过程,因为整个过程最漫长也最深刻。虽然最后并没有拿到他们家的offer,但是为了准备面试也做了很多准备,而随着面试的一步步跟进,也能明显的感觉到自己相关的能力在不断地提高。

概览

关于我,这是我的基本资料。也算是以前为找实习用的网络简历吧。

关于Amazon面试,整个面试从他们2011年11月第一次联系我,到2012年2月第一次面试我,到2012年6月他们发来拒信并且近期不再给面试机会的,总得说来差不多经历了半年时间。期间一共接受了4次Phone-screen面试和2次Onsite面试。而Onsite面试里面,每次又有4个人分别面试。

其实对于这些大公司来说,基本流程都是需要很长时间进行的,一般是邮件来往进行电话面试的时间预约,然后回复他们合适的时间,从邀约到确定一般也要一周时间,然后面试一般会在约定时间的下一周。面试之后,又会至少登上一周时间等待他们的答复。如果对方愿意进行下一步,又会开始下一轮时间安排。所以基本上,一个面试流程通常就要3-4周左右来完成。

虽然很漫长,但是也能给我更多的时间在期间进行准备和调整。这也是让我能一步步提高,并且有时间纠正之前面试犯下错误的重要因素。

第一次电话面试

回想起第一次Amazon的电话面试,真得非常糟糕。一来刚刚从国内飞回到学校,还有严重的时差;二来寒假在家一个多月都没怎么写过代码也没有准备过算法。所以当对方打电话进来的时候,脑子一片空洞。

已经记不清具体问了些什么问题,但是至少记得一个关于排序算法的简单问题,我都没有答好的。那个问题涉及的排序算法是“归并排序(Merge sort)”,可是当时我连基本的实现都说不出来。

好在面试官是中国人(从他的邮件名字看出来),他也很友好的一点点提示我,从怎么分数组,再到怎么将有序的数组合并。最后关于时间复杂度问题上,我也凭记忆答出是 O(n log n)。

结束电话面试之后,我已经基本不抱希望,完全感觉是不可能有希望了。而且因为还有一个学期,本身也想到还没有准备好,也还有时间去继续准备。

不过可能真的是本命年运气好,Amazon还是给了我第二次电话面试的机会。之前也讲过,每次面试之间基本要一个月时间。另外最后一个学期,我也没有什么课,所以在这一个月里面,我也做了更多的学习和准备。

看完了MIT Introduction to Computer Science and Programming公开课 ,当然最主要的是听了前半部分关于基本算法的内容,对于Python我倒没有什么学习的倾向。一直都是用C++来应对面试。

也一直保持跟已毕业学长的联系,询问工作的机会,也在他的指点下开始做InterviewStreetLeetcode的题目。经过几个题目的练习,一下子就领会了Binary Search的操作和巨大用处

其实上边的题目对于参加过ACM的人来说,并不算什么吧。可惜本科的学校没有ACM的队伍,专业也是软硬件皆有而偏向硬件,导致算法课成了专业选修课。这也是我选择留学继续提高的一个原因吧。好在大二数据结构课碰上了很好的老师,当时学得也十分扎实,所以虽然现在有些遗忘,但是捡回来也很快。

第二次电话面试

一个月后,我又上了电话面试的战场,这次的表现明显要比之前好了很多。虽然有几次答得不流畅,但是已经好了很多。

先被问了一个关于树的问题,虽然在之前的练习中还没有做过树和图的题目,但是依然知道肯定是深度优先或者广度优先的遍历。但是我个人有点抵触递归,所以在解答关于树的问题时,我总是喜欢自建queue进行广度优先的遍历(这让我在之后的面试吃到一些苦头)。中间碰到了一些阻碍,面试官也提示说可以用递归。不过我还是解决了。

之后又问了一个很经典的Two Sum的题目。不过在当时,我还没有做过这个题目,所以给出了一个先排序再找的方法,复杂度自然是 O(n log n)。然后面试官提示问,你会用HashTable吗?我便明白了过来,用HashTable实现了O(n)的算法。也自此以后,HashTable在过的面试过程中经常被使用到。

不过因为C++标准库中并没有HashTable和HashSet,所以我也一直都尽量避免去使用他们。

这次面试,自我感觉要比上次好,也觉得应该能够继续进行下去。不过其实感觉并不是靠谱的东西,他们说不给可能就不给了。我朋友就是明明没一道题目都答得很好,可惜还是直接被拒了。

好在这次我的运气没有那么差,但是也算不上好。因为一般两次电面之后应该是直接Onsite到Amazon总部去面试的,但是要我第三次电话面试。

还是一个月的空隙,我继续着算法的练习,指因为差零点几秒种而不能通过InterviewStreet的测试案例,我也开始不停地寻找优化的空间和应该注意的事项(比如 scanf比std::cin快)。也开始逐渐体会到CS(Computer Science)和CE(Computer Engineering)之间应该有的差别。

接着我也开始重新加强操作系统方面的知识,开始看UC Berkeley的Operating Systems and System Programming公开课。虽然面试很多时候并不会问OS方面的东西,但是对我这个学期期末考试却有了帮助。那是关于计算机组成的一门课,写MIPS指令。而Berkeley那门公开课用来做实验是叫Nacho的系统,正好也是基于MIPS指令的一个系统。

第三次电话面试

经过了2多月的准备和练习,很多基本的题目都已经能够熟练编码。于是,第三次电话面试,我都已经学会“抢答”了。

什么叫“会抢答”?一般情况下,面试的时候,面试官会出一道题目,然后会解释一下题目的意思,并举出一些例子来进一步解释。比如“检测回文数”,那么就会阐述什么叫“回文数”。但是因为他题目我都已经做到过了,所以不太需要他做详细解释,甚至听到一两个词就知道是什么题目了。

所以,不到30分钟,基本就把纯算法类的三道题目给回答完了。之后他又出了一个设计类的题目,我回答的并不是很好,因为一直没有准备过这类问题。不过面试官好像也没有对这个题目要求提别高,似乎只是因为时间还很多,只好又出了这一题。对于我那没有逻辑性的答案,他也欣然接受。

这一次的面试表现显然要好很多,于是很快就得到了Onsite的机会。

在Onsite之前,我就继续做IntervewStreet上边的题目。之前IntervewStreet提供完成相应数量的题目之后,可以申请上边的一些公司。所以我就拼命做题往那个数目上接近,还真让我达成了目标。在上边投了Facebook等公司。不过当时我也没有报什么希望, 只是觉得有机会就试试,因为像Facebook我在其官网上投一直都没有消息。

期间,我也看了不少有关面试技巧方面的书籍,比如《The Google Resume》,《Programming Interviews Exposed》。让我注意到了不少之前没有注意到的细节。同时也让我对简历方便做了更多的修改。

第一次Onsite面试

过了不久,我就来到了Amazon总部,开始了4轮面对面的面试。

似乎已经习惯了电话面试,而且之前一直在电脑上用键盘敲代码。突然要在白板上做题有些不太适应。上来第一题,我就出了错,虽然后边把问题改正了,但是也不是最优解。所以45分钟里面,我答了一道题目,还没有答完整。

第二个面试官是个中国人,他一进来就用中文问了我几个背景问题,所以整个面试过程都是中文替代了英文。面得也很流畅,差不多回答了4个问题,不只是编程,还有SQL和Linux指令。不过SQL和指令我都没有答上来,SQL是因为很久没有用,一时没有想起来;Linux指令是真的不会。

第三个面试官应该是一个Leader,拿了一支笔和一个本子,很多淡定的坐在那里开始了解了一些我做的项目,然后问了一个经典的DP问题。当时我虽然知道DP,也能看出一个题目是否会用到DP,但是我却还没有掌握DP的精髓。一开始只用了递归回溯,复杂度自然是指数级别的。后来虽然想要改成DP,但是依然没有顺利完成。

第四个面试官问的是一个设计类的问题,要我设计“Key Ask”(音译)。我不是很懂那是什么,纠结了半天。后来他拼写给我才知道叫“Kiosk”,然后解释了是机场用的查询航班,自动打印票的那个机器。虽然我靠着大四实习时留下的一些基于Asp.net的设计经验,从数据库到访问层到业务逻辑,瞎讲了一通。但是毕竟不是做设计,答的自然比较糟糕。之后他又问了一个算法上的问题,那个题目我会做,但是因为之前耗费了过多时间,所以只把思路讲述了一番,没有把代码完成。

就这样,第一个完整的面试流程就算结束了。虽然很期望能够拿到Offer,但是也很清楚能力上还差上一些。所以只是抱着中立的心情去等待着。

在去面试的时候,通过InterviewStreet的推荐,意外获得了跟Facebook的交流机会,之后也得到了面试的机会并进入了Onsite的流程。不过这个是另一个过程了,这里还是着重记录Amazon的吧。

过了一个星期,Amazon终于打电话过来了,并不是婉拒的消息,但是也没有接受的意思。而是让我另一个部门的经理联系交流一下。后来那个经理打来了电话,表示愿意给我新一次的机会。我把它分开记录在了《每一次面试都是对技术的提高(下)》里。

原文地址:https://www.cnblogs.com/ider/p/interview_experience_1.html