实习、面试经历(转某学长)
转自:http://blog.renren.com/blog/329065028/918750099
面完了hulu有点悲剧,找工作算是告一段落了。现在写写面经,给学弟学妹们点借鉴。另外人人上神牛太多,我这么水容易被鄙视,就发到这里吧。
Experience&Insight 先是一些建议。首先是自我介绍部分,好多面试官会跳过这一部分,但是为了保险还是准备一下吧。自我介绍里一定要说自己是本科!否则很多面试官会大量问你机器学习和数据挖掘的内容。 另外,最好再提到到自己最突出一两个亮点,对于我来说就是竞赛和MSRA实习。这个部分差不多就行了,毕竟是面码农。 随后面试官一般会问一问简历上的项目。对于简历上的项目你不仅要十分熟悉,而且要能够非常清晰有条理的讲出来。不要怕讲得罗嗦,讲明白是最重要的。我觉得需要注意的几点就是要先充分的介绍问题背景,这样才能比较自然的进入项目的实质内容。讲述项目的实现时要自顶向下,逐步细化,让人先有总体的把握,再关注细节。对于项目中抽象的概念要尽量举一些例子,还是不要怕罗嗦。最后就是对于项目的主体,要有适当的重复与强调,防止听者遗忘。这些有好多都是我实习时的mentor告诉我的,在实践中我也觉得这很有道理。另外,光知道这些是远远不够的,关键是要多练习,大不了准备好几套方案背下来。多找人练练,最好是能给父母讲明白你的项目。 下一环节就是技术面的面试题了。当然这个是最重要的部分,这个跪了前面的表现就白费了。纸上写代码是要面临的第一个问题,这就只能多练练了。另外的一个问题就是题目如何作出来。多看些面试题的书籍,比如 《编程之美》《cracking the coding interview》或者在leetcode上多刷刷题,至少百度阿里的等级的公司还是能秒掉的。做题时先尽量自己想,看了答案之后要认真分析不会的原因,最好每道题都要敲一遍,因为有的trick不敲是很难发现的。面试时最重要的是两点,一是不要理解错题意,二是想好细节再开始写。 最后就是提问时间了。我个人认为这个环节没有必要去刻意提问来表现自己对什么东西有独到的见解。这只是一个了解你以后工作内容和环境的好机会。如果你没准备好自己真正关心的问题的话你在match offer 的时候会后悔的。所以我觉得最后提问就是想问什么问什么,尖锐一些就尖锐一些。 其实从头至尾关键是要表现出你对要做的事情的喜爱,和你确实很聪明,有着很强的学习能力与对事情钻研的热情。
墨迹完了开始上干货。
从实习面开始! Google&MSRA
处女面是面谷歌实习,是电面,一点面试经验都没有,注定悲剧。这次面试都有点给我留下阴影了,前半小时只有2句对话。面试官:“实现下大整数开根号。” 我:"我先说下思路吧。" 面试官:“不用了,你先把代码写出来吧。” 我:“。。。。” 这题目,就是让我把高精度运算都写一遍啊,第一次脱离IDE写这么码的题目,实在是捉鸡。教训就是写代码时不要着急,时时刻刻注意代码风格,换行和缩进,要么容易写到后来连某个变量叫什么名字都找不到。当时我就是十分焦急的一顿码,代码中留下了许多细节问题和bug,最后被面试官平均每四五行挑出一个错误。写完代码后面试官直接就问你还有什么问题么,然后凄惨的面试就这么结束了。两三天后收到拒信。
自从谷歌实习面跪了之后,我有一段时间每天都会在记事本上把高精度运算敲一遍,尝试用不同的方法实现。稍稍提高了点代码能力,另外一个好处就是熟悉了不用IDE写代码的感觉。
随后投了一发MSRA的实习,也是很快收到答复,约了面试时间。这次面试因为有了经验,和我们组当时确实比较缺人面试题比较水,全程进行的比较顺利。面试官(我现在的mentor)貌似先是问了点我简历里的项目,有点记不清了,主要就是讲了讲我写的黑白棋的博弈搜索的算法,和对局面好坏的估值方法。然后又问了问以后准备读PHD还是工作,又提到我们组在这两方面都有比较好的机会。当时本来以为这就是个呵呵面,但是后来过了快半小时我mentor突然才让我写几个题。废话不多说了,直接上题。第一题是MSRA喜闻乐见反转字符串,举个例子,就是给你“Hello world !”你返回“! world Hello”(单词间以空格间隔)。瞬秒,用一个栈,从后向前扫描字符串,遇见非空格则把字符压栈,遇见空格就把栈弹空,字符的出栈顺序就是所求结果。第二题也是大水题,给你一个边和坐标轴平行的矩形和一个圆,让你判断二者是否相交。继续瞬秒,先用一点小技巧求出矩形上距离圆心最近的一点,然后判断改点在不在圆内。第三题是求树上距离最大的两个点,喜闻乐见的两遍DFS,然后我还证明了一下这个方法。最后问问题,数据可视化是干啥的,我mentor大概讲了讲就结束了。不久接到二面通知。二面更是水,都没有写代码的题目,只有一个说算法的题目。给你一个无序的数组和一个数K,让你求出所有的ai aj 使ai+aj=k,都是经典水题了,扫描数组,第一遍hash插入ai,第二遍hash查找K-ai。剩下的还是问问简历,随便聊聊,面试就结束了。大概拖了一段时间后收到实习offer。
Baidu&Alibaba&Tencent
有了MSRA实习后,基本上心里已经决定去了,但是为了积累下面试经验,多了解一下其他公司,我还是弄了弄BAT这三家公司的实习,希望能拿一些备胎实习offer,结果却是一家没拿到,都悲剧了。
最开始面的是腾讯。先是听说有腾讯笔试,然后被同学拉着去笔试,随后收到了面试通知,地方离得挺近的,不去白不去。一面面试官应该是soso的,一开始没让自我介绍,让我先写个很简单的题,有一个小trick,然后写了个很水的DP,具体的题我都忘了,因为太简单没啥印象。然后问了一个开放题,如何估计文档的相似度,找出相似文档,答得不好当时也不了解topic model或者文本挖掘啥的,一顿瞎扯。然后聊一聊上大学期间都在干什么,由于已经有了实习去处,我比较随意,基本上就是想说什么说什么,大量吐槽学校,鄙视自己学校。但是总体还是相谈甚欢的感觉。结果,晚上查面试结果,被十动然拒了。一面被腾讯拒。
随后就是百度的什么人才库计划。虽然大家都吐槽这个竟然用QQ邮箱通知,但我还是回复了那个邮件,把简历发了过去。然后我又推荐了几个人,换来了hr送的一个百度的小音箱,被我当成闹钟用了。不久接到了电面通知,一面面试官应该是个java的研发工程师,问了各种码农问题。java 中Vector 和List哪个是线程安全的,如何设计java虚拟机的垃圾回收机制,java的HashSet内部是如何实现的。还问了些数据库的东西,在数据有什么特点的时候你应该使用索引,剩下的有点忘了。总之就是答得很不好,我对这种问题以前也不怎么关心,就随口答一答。最后让写了几道题,前几道都是一分钟瞬秒的节奏。第一题,给你一堆数其中只有一个数出现了奇数次,用O(1)额外空间找出这个数,异或一遍就好。其他题都忘了,只需知道题水的不能再水就是了。最后一题是在一个字符串里查找一个子串,允许使用库函数,我当时觉得就把这些题这么快秒了实在没意思,就对面试官说,我习惯自己写,不用调用库函数,不到20分钟现敲了个KMP,写的这么慢主要还是因为好久没写过字符串的题了。然后面试结束。忘了过了多长时间接到现场面通知,当时想既然报销火车票倒不如去看看百度怎么样,虽然正好编译原理快结课了,我还是决定带着龙书路上复习去百度面试了。
二面在百度大厦,上午下了火车很早就到了百度大厦,顿感高大上,觉得码农貌似没有那么苦逼,至少还有前台妹子养养眼。在大厅继续看了好几小时的编译原理的书。随后到了面试时间,被面试官领上了楼,然后我看到了我面试的职位是C++研发工程师,顿时觉得被一面面试官鄙视了java方面的技术。然后问了些C++语言细节,指针与引用的差别,C++程序内存都有那些不同的区域,常量字符串被存在哪个区域。后来问了一道题,不算很难,但是竟然没一开始就想到最优的方法,估计是因为火车上没睡好。给你一个大的字符串A,和小的字符串B,C,让你把A中所有的包含B的位置替换成C。要求额外空间为O(1)的。最优方法是在我写完一个不够好的方法之后才想起来的,只是说了说想法。方法就是对A先计算出B的出现次数,算出替换之后A的尾部的位置,然后从后向前在A中匹配B,并替换,这样就可以做到不利用额外空间进行移动了。这轮面试的收获就是体会了纸上写代码也是一件很蛋疼的事情,写完的东西一修改就乱了。三面是经理面,问了我和别人如何相处,如何处理矛盾啥的,然后我在面试结束前表达了我对纯码农职位不感兴趣,然后面试结束。回去之后拖了好久把火车票寄过去报销了。
最终的结果是传说中的默拒。
最后的实习面是面的阿里。也许是笔试成绩在边缘,收到面试通知比较晚,一面直接是现场面,面试官来自支付宝,面试从头到尾纯粹是闲聊,谈人生谈理想,最后问了下所有的排序算法都适用于哪些情况,面试结束。过了一段时间收到终面通知,终面竟然是电面,实在是搞不明白到底怎么回事。面试的时候面试官问了好多机器学习的东西,估计以为我是研究生什么的,我只凭借大概的了解答了答,问到SVM的一个什么优化时,我当时就表示没有听说过,只知道最原始的SVM和soft-margin SVM。然后面试官问给你offer你实习会来么,我当时就直说了我会去MSRA实习,然后就木有然后了。又是传说中的默拒。
下面是找工作的面试。
Google SDE
第一个工作面试竟然还是谷歌,看来谷歌是注定要跪的。另外一个奇葩的事情就是HR给我安排的模拟面试坊活动的时间竟然是在面试之后!!这次面试发生在实习的时候,平时时间比较紧,只能通过压缩睡眠时间来准备面试,就准备了几天,几乎算是没准备吧。
第一个面试官是个满头白发的大概40多岁的人,谷歌就是高大上啊,还有40多岁的码农。先是问了一个接口设计的问题,如何设计一个发送邮件的函数接口,防止调用者将发送方和接收方地址传反,我的方法是把所有的参数打包,然后让调用者显式的赋值,会比较明显的意识到每个参数是干什么的,而不容易弄反。然后有一个算法题,让我设计一个数据结构,支持在集合中插入一个元素,删除一个元素,和随机返回集合中的一个元素(当然要求每个元素的被返回概率均等)。我先给了个平衡树维护的方法,然后给了一个利用hash的均摊复杂度O(1)的方法,然后面试官让我想有没有更优的更稳定的方法,没想出来,一面结束。实际上在休息时我就想到了最优的方法,就是先把所有的元素放入数组,用数组这个结构维护从数组脚标到值的这个映射,用哈希表维护从值到数组角标这个映射,插入就直接把元素放在数组末尾,再维护哈希表。删除就直接用数组最末尾的元素替换被删除的元素,再维护哈希表。随机返回的话就随机产生一个1到数组大小的随机数返回以该数为角标的值(因为数组中没有空隙)。
随后二面面试官来了,一个估计也快40的女面试官,说话语气特别犀利,思维也很犀利。上来问了个我不太会的题,已知有n行代码,其中一行有bug,现在要通过2种操作找到这个bug,第一种操作是在某一行插入一个输出语句耗时为a个单位,第二种操作是把代码编译运行耗时为b个单位,如果某个输出语句输出正确,那么说明该语句之前的代码都是正确的,让求出最短的时间找到有问题的代码。这个首先第一需要注意的是可以多次插入代码之后再进行编译操作,这个我当时注意到了。然后我的重心放在利用数学的方法解决这个问题,直接把问题转换过去,后来发现优化的目标实在是有点复杂,才发现自己走偏了。最后只是给了个一般的O(n*n)动态规划的方法,就是对于某一个规模的代码,枚举要将这段代码平均(不难想到一定要均分)分成几块,然后递归到更小的块,用一个数组记录不同规模所求出的最小时间是多少,记忆化搜索就好。对于这道题我表现的很不好,加上面试官语气有点强硬,弄的我很不舒服,注意力没法集中,心里特别乱。随后问了一个很水的题,给一个字符串s,和一个字母的集合A,求s中最长的只由A中字母组成的子串,嗯,就是用一个可以伸缩的区间从s开头滑到结尾,区间内如果出现了A中没有的字母,则从区间的头部弹出字母,即区间头部向后移,其他情况则从区间尾部加入字母,即区间尾部向后移。整个过程区间取得最大的长度的位置就是子串所在位置。秒掉了。最后提问题,G公司的码农一天都会干些什么,听回答大致感觉就是啥都干。
然后面试结束,等三四面通知。过了大概半个月,不出意外收到recruiter的电话:“欢迎你明年再来面”。TT。
Baidu Speech
随后是面了一个百度的语音技术部内推,本来时间安排在面谷歌的第二天,但是HR发的面试邮件我没收到,再加上那几天准备谷歌面试,我也忘提醒HR了,于是就推后了几天。当时面的时候也比较随意,毫无准备,因为谷歌面得不好心情也不是很好,但是语音组给我的总体印象还是很好的。
一面是个中科大少年班的面试官,态度极其好,貌似在百度工作了5年只比我大一岁。先问了一道简单的DP,给一排格子,现在有三种颜色红、白、黑,给这一排格子涂色,要求相邻格子的颜色不能相同,而且对于每个白色的格子必须满足左边相邻格子是黑色,右边相邻格子是红色,问一共有多少涂色方案。方法就是动态规划,一个格子一个格子的涂,状态就是涂到了哪一个格子,当前格子的前2个格子都是什么颜色,转移就按题目规定的合法条件进行转移。随后问了问简历里的项目,我就说了一下来MSRA的对Skype用户反馈的可视化的项目。然后问了一个只需说算法的题,在n-gram语言模型里如何快速的求出一个句子的出现概率,当时先说了个最直白的hash查找然后乘在一起,之后想到了利用ac自动机的一个方法,对于k-gram会比hash优化掉k这个常数。这个方法就是将n-gram的所有参数插入ac自动机权值就是对应的参数值,然后直接做查找,将所有查找到的子串的权值相乘。当然还有一点细节需要处理。看面试官的反应,我答的还可以。然后又问了一个布局算法,参见今年百度笔试最后一题,说起来太麻烦了。然后一面结束
二面的题目成题比较多,除了一个三个门后面猜羊,开了一扇门问你换不换这个题卡了一会,其他都是比较快速答上来,所以没什么印象。然后自我感觉有点过于良好,说了一个不够保险的东西,用EM算法对隐马尔科夫模型参数进行估值,以前确实花了好大功夫弄明白了,但是当时好久没接触了,公式没推明白,然后就放弃了,面试官安慰了我一下说他也不是很熟。然后是三面貌似是经理面,随便聊了聊,期间问到我有没有对象,然后提醒我说要抓紧,提到组里有2个女生实习,估计会留下来,好囧。然后面试结束。 8月底面的,9月初给的offer。总之这次面试让我对百度印象很好。
Alibaba 算法工程师
随后就是比较重要的阿里面试了,笔试的时候发现周围密密麻麻的清华硕士,觉得果然北京竞争比较激烈。笔试等待的时候和一个清华研究生妹子聊了聊,她极力劝我找个学校继续读,额...
然后就是一面,貌似我笔试成绩还不错,面试被安排在第一天,一面面试强度不是很大,随便问问项目,问了个并行的算法问题,就是如何把离散化这个过程改成并行的算法。我对这种问题以前没想过,于是用一般的离散化方法,也就是排2次序,然后把排序并行化一下,当时还用了不是很容易并行的多路归并排序。其实也可以用MapReduce很简单的搞一下。然后面试官让我写个快速排序,速写之,面试官看了一眼啥也没说就告诉我一面结束了。随后在阿里等面试的时候蹭了顿盒饭,又认识了些人,感觉就算被拒也值了。等了好久终于等到了终面,纯粹的呵呵面,让我讲讲数据可视化是干啥的,聊聊人生,就这么结束了。
2天后接到了面试官请吃饭的电话,大概一共20多人,果断去蹭饭。吃饭期间主要是看一个中科院的博士和我终面面试官谈笑风生,然后作为桌上唯一一个本科生我只能反复卖萌。基本上确定了offer。后来过了好久才收到正式offer。
MSRA RSDE
其实这个我只是随口和mentor一说,结果mentor真就给我推荐了,大组的老大面我。之前听从mentor的建议练了练讲述问题的逻辑,改观也不大挺捉鸡的。还好面的时候不算太差,没有毁mentor的声誉。面试时讲了讲实习时做的项目,项目那么水也没什么可讲的,谈了谈人生,就结束了。由于是转正面,没什么参考价值。从mentor那得知不出意外果断没过。
Hulu SDE
HULU是最近面的,先是因为这公司太高大上觉得成功概率不大而不是很注意,忘投了。最近组里有同学不想读博要开始找工作,发现HULU还可以投,于是我就跟着他投了一下HULU。两天后收到HR姐姐电话,约了面试时间,这次又遇上HR姐姐没发我面试邮件了,只能推后两天。近期心情不爽加上组里项目进入关键时期,所以面试只准备了一晚上,刷夜刷的快刷出人命了。又是喜闻乐见的无准备的逆风裸面。
无准备是注定要跪的,一面第一题就把题意弄错了,相当于做了一个完全不同的题。题目是给你一个完全二叉树,求其中满足BST条件的最大的子树,这里子树的定义是以树中某一节点为根,包含其所有后代节点的树。DFS然后合并就行,DFS的时候维护每棵子树的最大最小值。随后忘了问的什么了,总之好像不是很难。后来问了问项目相关的东西,感觉自己讲的比之前面试有逻辑多了。
随后休息几分钟迎来第二个面试官。第二个面试能更年轻些,也是先问了问项目。随后问了下如何用二分写整数开根号,嗯,你没有听错 int范围内的非高精度的开根号,我的回答就是要注意一下乘法不溢出,设好上限。然后问如何实现double型小数的开根号,精确到小数点后指定位数(多少位是由一个整数给出),然后我就无脑的写成和整数几乎一样的了,结果获得了“面试时二分写残了”的称号。这个问题容易犯得是这么几个错误,一个是精确位数为负数时如何让这个数还有意义,一个是在被开方数小于1的时候二分初始上下界如何确定。再一个争取做到如果二分时恰好碰到相等时,最好直接返回,使答案更精确。感觉hulu的面试都不算太难,就是都很注重细节。然后问了个经典小清新题,有一个数组,已知其中有一个数的出现次数超出了总次数的一半,以O(1)的附加空间求出这个数,然后面试官让我证明方法的正确性,这个真是有一种方法在嘴边却说不出的感觉,卡了好久,面试官给了一个比较直观还严谨的证明。可以把找这个数的过程当成是这样的,扫描整个数组,一旦发现有两个不相同的数那么就把这两个数绑在一起扔掉,最后剩下的数中一定是出现次数超过一半的数。然后问了个推广,有长度为n的数组,一直有数出现次数超出n/3求所有满足这个条件的数,解法就是用相似的方法,扫描数组,一旦发现三个互不相同的数,那么就把他们绑在一起扔掉,最后会剩一个或两个数,那么再重新扫描一遍,对这两个数进行计数,产生结果。最后是问问题,问了问在hulu都有什么活。从回答来看,真是什么活都有,面试官还小吐槽了下公司的一些平台。然后二面结束。
三面之前有较长的休息,三面问了好多题。面试官现让我写了个链表的快排,有一个小bug,还算过得去。随后问了几个杨氏矩阵相关的问题。杨氏矩阵就是一个矩阵,其中元素满足每行从左到右递增,每列从上到下递增。 第一个问题是如何在这里查找一个数。如果这个矩阵有n行m列的话,最优方法复杂度是O(m+n)的,方法自行百度吧。下一个问题是如何对杨氏矩阵中元素进行排序,我给了2个方法,一个是简单的K路归并排序,另一个是利用分治法,把矩阵均分成4块,先对左上角也就是值最小的那一块排序,在最左下角和右上角的2块进行排序后归并,再对右下角值最大的那一块排序,把这三部分接起来就是结果。可惜这2种方法都是O(n*n*logn)的复杂度,后来面试官说,他也不知道有没有O(n*n)的方法。之后又问了一个题,就是给一个数组,如何根据这个数组构造出杨氏矩阵。我只给了了一个先把数组排序,然后由小到大现填矩阵第一行和第一列,不断减小问题规模的方法。最后又问了一个问题,对于一个杨氏矩阵,如果把其中的一个元素用最小值替代,如何用最少的时间维护杨氏矩阵的性质。我给了一个和堆的下沉操作比较相似的方法,最小值元素只能向下或者向右走,走的方向就是相邻元素值较小的那个方向,然后把对应的相邻元素与最小值元素交换,之后继续走,最多走O(m+n)步。面完之后我才发现原来这种题这么常见,题解这么多。随后面试官飞快的跑掉了,没等我来得及问问题。
几分钟后HR姐姐进来告诉我面试结束了,我也不知道是否走完了整个面试流程,是不是中途就被拒了。
总结起来就是还是太弱了。