周一晚上,收到了微软互联网工程院XiaoIce&CJK组的预科生实习Offer。微软预科生算是我第一次走完一个offer申请的流程。

微软预科生是每年春天开始的,针对第二年毕业的学生在大三/研二暑假为期三个月以上的实习项目,同期对于其他年级以及满足年级但不满足时间安排的开展时间短到几天的探星夏令营,也可作为预科生的后备方案。预科生可以获得最短三个月以上的实习机会,同时在实习后有相对非常优惠的转正面试过程。除此之外还有面对更低年级的育苗计划以及MBA计划等,不同计划开启时间不同,大致可以参考这样的日程图:

微软中国这边的报名站点都在joinms.com,每年三月就是开始预科生报名的时间,选择好要申请的地区【北京/上海/苏州】,以及志愿的方向,即可进入简历的填报。今年简历填报是跳转到中华英才网上进行的,一共可以选择两个志愿,根据自己的倾向选择是最合适的,当然,这个选择应该也会影响到后面的笔试和面试的安排上。

我在填报的时候就报了【Data Mining/Algorithm/Machine Learning Engineer and Scientist-STCA】和备选【Software Engineer-STCA】两个职位。

一般职位上会带有相关的部门,MSRA就是著名的微软亚洲研究院,最为知名当然相对来说也是最难进的,STCA是微软亚洲互联网工程院,就是那个搞了Bing和小冰的团队,WDGAE全称Microsoft (China) WDG Asia Experience Group/微软(中国)操作系统工程院,是微软的操作系统研发部门,C+E则是Microsoft Cloud + Enterprise (C+E) China/微软中国云计算与企业事业部,即云计算部门。今年预科生计划基本上都是这几个部门,也就是微软亚太研发集团旗下的几个主要的部门。当然这里只例举了研发类的岗位,销售与市场支持类也有很多的机会。

我是实际上在预科生计划ddl前四个小时报名的(当天11点截止,我7点提交的申请)。算是后知后觉,4月5日填报,6日就收到第二批笔试通知,可以看到在中期应该也是组织了之前的同学在参与了一次笔试。据HR在论坛的说法,笔试机会只有一次,即便是第一场没有通过,也不会有第二场的机会了。笔试是在hihocoder上进行的,这里插一句,hihocoder上经常举办offer收割赛,取得前几十名几百米的同学会得到很多的offer资格,包括微软的免笔试。

在线比赛就是典型的oj赛制,第一次3500人报名,第一题AC率13%,第二题28%,第三题3%,第四题0%;第二场比赛1334人报名,第一题AC率34%,第二题30%,第三题13%,第四题13%。整体题目难度实际上并不是很大,大概也就是高中NOI的难度吧。而且差不多能过或者接近过两个题就算通过笔试,门槛其实很低了。(但是为什么还是这么多人连一道题都过不了呢……)

第二场为例,A题是简单的技巧性小处理即可满分过,B题应该是某种意义上的贪心(然而只有七十分),C题颇有难度,不过看起来感觉应该是个最小费用最大流,D题是树形动归。我自己做的时候实际上颇为紧张,手速发挥得很成问题,C和D都写完了,但是一直没有debug出来问题,最后时间不过也只能勉强一交了(果然样例都跑不动的肯定都没分)。可见手速啊,也真是个问题。。。

(再给我三个小时我一定能调出来的。。)

笔试结束十天之后,4月16日收到《微软预科生职位-现场面试邀请》,安排4月21日上午到微软苏州现场面试。HR小姐姐们非常用心,一场面试前前后后确认了三遍。根据后来的交流,大概面试都安排在了4月中下旬,个别甚至拖到了5月初才安排,而且或许(?)看起来先后会和笔试成绩有一定的关联。

20日下午,趁着没课的功夫我提前到了苏州,以防第二天路痴迷失在园区里,事实证明,当天下午我转了两个小时确实没找到微软的园区从哪里进。。。

第二天上午早早按照时间到了微软大楼,在大厅登记,并被HR小姐姐过来组团领走。可以看到当天上午来的同学大概也就十个人上下,并不是很多,与其中交流,果然还是研究生为主,像我这种本科生过去划水的也确实不算多数。

随后跟着HR小姐姐到了一间休息室,说面试官会过来领人。

大部分同学的面试一共三轮,前两轮是平行的,有种说法是前两轮通过任一轮就可以有三面,也有的说前两轮都过才能有三面,具体我也不知道。感觉前两轮面试官看着都挺年轻,估计还不是boss级别的前辈,问的问题难度上也都不大。

一面面试官一上来先让我介绍自己,机智如我的怎么会再重复简历上的无聊信息浪费时间呢,本着常年在学校招生季致力于宣传推广安利的扎实锻炼,我在介绍自己的中间很是把自己的项目着重强调了一遍,当然也顺便强调了一下我们学校并不是个二本院校这个问题。

随后面试官就开始跟我聊项目,他让我讲讲项目里觉得最难忘的是哪个,我想了想,尽管近期做的项目其实更亮眼一点,但是我还是选择讲了大一时期的车牌识别,毕竟大一的年级配上那个项目的难度更具有反差萌嘛【雾。随后面试官便说“来我们做个题吧”。

第一道面试题大概是翻转图像算法,leetcode原题

第二道题是回型遍历数组,然而耿直的我当时也没过脑子就直接回了一句“这个高一做过”。。。啊好像有点尴尬了。。面试官转而换了一个题目,n*m的矩阵,从左下角到右上角,只能向上或向右,有多少种走法。我当时还比较紧张,先是说了个动归算法,继而原地改成递推来实现,这时候他就问我那么从数学上能否可解呢?我才反应过来,实际上是C(n-1,n+m-3)种方案。随后面试官又问,如果在其中划出一定的范围禁止走,那么该如何做,我回答说在递推算法经过这个范围边界时强制置零。也就过了这道题。

第三道题是去年算法课上讲过的题目,也是leetcode的原题,在n*m的有序数组(每行/每列)都是递增数列中如何最快的查找一个数字。我脑子里立马蹦出当时上课讲过的一个在二分的基础上改进的优化算法,然而一时紧张没有想的清楚,只能勉强推出一个二维二分的算法,继而在优化上推出了一个O(nlogn)的低常数算法,还不到最优解方案,不过时间不太多,面试就结束了。

随后就是二面,二面面试官相比一面面试官喜欢白板写代码不一样,他喜欢直接用纸笔写代码= =。上来依旧是老套路介绍自己,随后的几道题,依旧是leetcode原题上下的难度。

二面的面试官似乎比较喜欢同一个题上玩变种,所以只问了两大系列的问题。第一道题是已知n个节目的开始结束的时间,问最多能看多少节目。当然我知道这个就是个O(n)的贪心,不过还是卖了个乖,先说了一个用图论来解的办法,然后又说用dp也是可以做的,再之后才说出贪心的最优解方案。随后面试官又叫我谈谈贪心和动归的差异,大概是想考察一下对两种算法的理解吧。

随后他又修改了问题,问已知这些区间,如何快速一个时间点是否有节目。听起来像是个线段树,然而机智如我很快就意识到并不是。转而提出了根据两次排序做的算法,也就是O(nlogn),不过常数有点大,进而面试官又提出环境为高请求量的程序,也就是尽可能优化query的时间,那么我的算法就改为一次排序后贪心合并所有的时间段,使得不存在重合段,那么每次查询只需要二分起点到最近的位置,然后检查这个位置后面紧跟的一个时间段便可以。query时间压缩到O(logn)的层次。

两面结束后,我被晾在休息室一个多少小时,之后才被告知三面面试官开会去了ㄟ( ▔, ▔ )ㄏ于是三面延期安排、

等了一个多星期,又过了一个五一假,收到了三面安排在5月2日的通知,面试是在线上进行的,使用的Skype for business也就是之前的Lync。面试官听起来比较老成,自称之前是MSRA的一员,后来转到微软苏州带团队,相比也就是团队的boss了。三面面试官终于摆脱了简单的leetcode入门题的套路,只出了一道算法题目,问已知n*m的01矩阵,要求求一个最大的子矩阵(即一些行和一些列的交点们)并满足子矩阵每行1不少于j个,每列1不少于k个。

我稍微想了一会,提出说,最大的子矩阵即删掉最少的点形成的矩阵,对于每个行或者列,首先存在一些本身已经不满足要求的,他们必定要被删除,而他们的删除会影响到其他的行列的数据,也就可能会产生新的必然要被删除的行列,因为这其中每一步都是【必然】的选择,如此循环直至不存在必然需要删除的行列,剩余即为最大的矩阵。

随后面试官又继续和我讨论起简历的项目起来。大概看不同的面试官的喜好吧,三面面试官似乎对项目经历比较感兴趣,看到我提到大一的车牌识别项目做过一个opencv的函数子集的描述,便问了很多常见的cv操作的矩阵运算具体是如何执行的,而后又提出了一个问题,给定一个点阵构成的路网图,由01表示,路网存在单双车道,也有一定的宽度,也存在很多复杂的交通结构,诸如立交桥之类,要求设计一个算法,输出一个同样的点阵图,但抹除多车道、立交桥之类的道路细节,即路就是一条路,路口就是两条路的一个实交点。

这个问题和我当时在车牌识别里识别车牌位置的算法颇为相似,我便很快就讲了一下当时的做法——先执行膨胀算法,后执行腐蚀算法。这样对于膨胀半径r距离以内的多车道和立交桥都可以被简化为一条道路。

面试官表示对这个回答比较满意。这时开始面试不过二十分钟,接下来二十多分钟里面试官又开始和我聊起人生来,他让我用三个词评价自己最大的优点,又三个词评价自己最大的不足,让我聊聊未来的职业规划,以及关于项目的打算。再之后面试官开始跟我介绍他的团队,最近正在用机器学习致力于优化bing和小冰的反应的项目,又跟我聊起机器学习和上学期跟马毅教授学的深度学习课程,给我了很多关于实习之前应该看点什么书的建议(这算不算钦点啊喂),就这样三面也就结束了。

三面结束后两个小时,收到了面试评价Positive的邮件,又等了几天,在5月8号正式收到了offer。

总之,微软的整个实习生招聘,实际上难度并不是很高,笔试上只需要稍加准备,通过并不难,而面试尤其是前两轮充斥着各种leetcode原题,好好刷一下也是能够保证的。

当然,硬实力大于表面功夫,感觉微软虽然题目出的比较简单,但是并不是care你最终能不能出个最优解,而更看重中间的思维,所以中间的思路是怎么走的,一定要表达出来,错不要紧,或许反而给了你一个现场表现自己debug水平的机会呢。

另一方面,至少我面试下来,微软对项目(如果有)还是比较看重的,挖的比较深,所以平时的积累很重要,早点找个教授跟着做做项目也是个不错的选择。项目千万别图好看乱写,免得被发现了两边都尴尬。

编程语言的选择上,其实并不在乎什么语言,对于同学们而言,换个语言就像换台电脑一样,想来也不是什么大问题,只要能表达清楚便没什么问题。

顺便,微软的HR小姐姐好多啊……

就这样啦,最后祝小伙伴们找到理想的方向哦~