《微软工程师助理面试经验分享》由会员分享,可在线阅读,更多相关《微软工程师助理面试经验分享(6页珍藏版)》请在金锄头文库上搜索。
1、 企业最新招聘信息点这里“中公快就业 专注于大学生求职/实习的招聘平台 更多求职技巧这里”微软工程师助理面试经验分享这篇文章是我应聘微软亚洲研究院(MSRA)暑期实习的“面经”,由于二位面试官都没有要求我对面试过程保密,因此我在这儿写出来,但我不想写成纯面经,于是标题后又多了个“总结”。另外,我没去北京,所以两次“面试”都不是面对面的面试。上周五,我直接把简历投给了 MSRA 创新工程组(Innovation Engineering Group)的邹欣老师,邹老师很快就安排了面试,正因为太快了所以我错过了 投简历的当天下午就安排了面试,但我去 K 歌了由于第二天是周末,所以一面推迟到下个星期的
2、星期一。第一轮的面试官居然是 Vczh,惊讶了一下。一面是聊天的形式,结果聊到了school days用 Vczh 的话说就是“反正面试也就是想摸清楚对方的底细而已,形式都是不重要的,啊哈哈哈”。Vczh 对 Functional Programming 也很感兴趣,所以我们首先聊了这方面的话题,比如问我用 FP 做过什么,有没有折腾过 Church number 之类的,从Haskell 聊到 LINQ,Vczh 还展示了他在 SQL Server 组工作时写的代码。然后 Vczh 就开始介绍他们现在正在做的项目。之后 Vczh 说 Feedback 已发出,充分肯定了我的编程能力和pass
3、ion,接下来就开始闲扯了,北京烤鸭啊、潮汕牛肉丸啊之类的总的来说,一面是在轻松加愉快中度过了一天之后,另一位面试官打电话跟我约了时间,第二天 2 点,电话很准时地打了过来,开始了第二次面试。我迄今一共参加过 5 次面试(百度 3 次,微软 2 次),这次面试是我最紧张的一次,过后回想起来,也是水平最高的一次,所以在这里详细地说一说。简单地寒暄之后,面试官首先让我做个自我介绍,说说自己的优缺点。我说自己最大的优势是就是热情和兴趣,Software Development 是我愿意做一辈子的事业,并且基础好、基本功扎实;劣势就是缺乏工程经验,没有开发较大型软件经历。尽管如此,面试官还是让我介绍一
4、下自己做过的最满意的软件,我就简单介绍自己写过的一个非常 mini 的操作系统。面试官问我实现了什么功能,有什么不满意的地方,如果以后继续开发的话会从哪些方面改进。答曰,这个 mini OS 非常简单,只实现了引导启动、进入保护模式、多进程、TTY 和一个naive 的文件系统;不满意的地方就是内存和文件的管理太不灵活,虽然能实现多个进程 企业最新招聘信息点这里“中公快就业 专注于大学生求职/实习的招聘平台 更多求职技巧这里”同时运行,但进程的添加是写死在代码里,不能动态添加和退出,而文件虽然能动态的添加,但只能添加固定大小的文件;如果以后改进,会首先从内存管理入手,增加动态添加进程的功能。(
5、有个小细节就是,面试官还问了我这个 mini OS 的引导过程,百度二面的面试官也问了我同样的问题)既然说到操作系统,面试官接着又问了个底层的问题:一个程序,访问函数中某个变量时,操作系统做了什么事情?我的第一反应是这个变量是存在可执行文件中,所以在访问这个变量的地址时,如果相应的页面加载到内存中了就可以直接访问,否则去交换区里头找;如果连交换区看里都没有,就上硬盘里找说到这我才意识到,面试官问的是函数中的变量,即局部变量!刚才说的都是错的!哎哟我紧张得要命,赶紧解释说不好意思,刚才说错了面试官很 nice 地说没关系,把你知道的说出来就行。我松了口气,把 C 语言运行时函数调用引起的栈帧变化
6、解释了一下,访问局部变量就是访问 fp 加上相应偏移的地址。面试官没有纠着我的错误,反而顺着问下去:刚才你说到页错误和交换区,那么操作系统如何处理页错误的呢?交换区的作用是什么?我说有两种情况会引起页错误,一种是访问不存在的页面、一种是对只读页面执行写操作,刚才说的页错误是缺页错误,就是第一种情况。这种情况下,被访问的内存地址会被写入 CPU 的寄存器中(CR2),操作系统可以访问这个寄存器从而知道引起缺页错误的内存地址,然后在交换区和硬盘中寻找相应的页面。而交换区的作用是利用局部性原理,存放被操作系统置换出来的页面,在物理内存紧缺的时候,某些久不使用的页面就会被交换到交换区,这些页面仍然可能
7、在将来被使用,放在交换区中可以更快地被找到。接下来的阶段,面试提出两个问题,并让我给出解决方案(中间有个小插曲,面试官一度听不清我说话,我更紧张了-0-,只好去阳台,所以后面的面试我一直坐在阳台的地上)。第一个问题与内存分配相关。面试官先问我会不会 C 和 C+,我说必须会啊然后问 new 和 malloc 的区别。我说它们的一个主要区别是用 new 来为自定义类型对象申请空间时,会自动调用默认构造函数,但 malloc 只是单纯的分配内存,不会执行默认构造函数。面试官说好,现在让你设计一个带有 alignment 功能的 malloc,申请内存的时候严格按照 企业最新招聘信息点这里“中公快就
8、业 专注于大学生求职/实习的招聘平台 更多求职技巧这里”8byte 对齐,你会怎么做?我说可以用批发零售的方式来实现这个功能,即先申请一大块内存,然后遇到申请的时候以 8byte 为单位分配出去,而这一大块内存用空闲链表管理。面试官问那你设计的这个 malloc 系统只能管理固定的对齐度是吗,我说是。然后面试官加深了难度:如果存在不同对齐度的分配要求,该如何做?我问对齐度是不是都是 2 次幂,面试官说可以有这个假设。想了一下,内存管理、2 次幂对齐度,就联想到伙伴系统,我说可以采取与伙伴系统类似的数据结构来管理内存,将内存区域依照不同的对齐度分组,比如说 2byte 对齐的 region 用一
9、个链表管理,4byte 对齐的 region 用另一个链表管理,然后遇到内存申请的时候就到相应对齐度的链表中寻找空闲区,如果相应链表没有足够的空间,可以从更高对齐度的链表中取出 region 然后分裂、也可以从更低对齐度的链表中取出两个 region 然后合并。用这种方式可以实现不同对齐度的 malloc。随后我反问一个问题,问面试官这个对齐 malloc 的问题是凭空想出来的,还是实际开发中遇到的,面试官说在开发中确实有这种需求,为了提高 cache 命中率、减少缺页错误,有时候会按照对齐的方式申请内存。紧接着,面试官提出第二个问题,也是面试的最后一个问题:在一个二维平面上有一些点,用一个多
10、边形把这些点全部围起来,可以把二维平面看成一块木板,点看成钉在木板上的钉子,包围的方式就像用胶箍去围木板上的钉子一样,问如何求解这个多边形?。我一听,一个计算机图形学的问题,直接命中我盲区我说给我想一想,然后在纸上乱画各种点,然后发现无论是什么情况,这些点之中最上、最下、最左和最右的四个点总是会与胶箍接触,面试官立即肯定了我的“发现”。那么将这 4 个点连在一起会形成一个四边形,进一步,这 4 个点会将四边形以外的区域分成4 个部分:四边形以内的点可以不用考虑,因为肯定会被胶箍围起来,关键是如何扩张这个四边形,让它像胶箍一样围住外面的点。所以,问题归约成如何扩张 U(最上边的点)和 L(最左边
11、的点)之间的直线,让它们围住区域 1 所有的点。说到这,面试官问我怎么让它围住这些点?我当时唯一能想到的方法就是枚举。那么接下来的问题就是:怎么枚举?怎么是否满足胶箍条件?枚举的以 UL 为底、区域 1 的点为顶点的所有多边形,其中肯定有一个是满足胶箍条件。而不满足条件的多边形有两种:一种是没有围住所有点;另一种是围住所有点了,但是与胶箍围成的多边形不一样。我觉得,前一种情况,比如如果枚举完所 企业最新招聘信息点这里“中公快就业 专注于大学生求职/实习的招聘平台 更多求职技巧这里”有可能的四边形都不能围住所有点,那么胶箍围成的多边形边数一点大于 4;而后一种情况很可能出现凹多边形的,那么此时的
12、边数会大于胶箍多边形。基于这个假设,我提出按边数从少到多的顺序,枚举四边形外所有点与 U,L 两点形成的所有多边形的解答。就是说,先枚举所有三角形、再枚举所有四边形、然后枚举所有五边形按照这个顺序,一旦遇到一个能把所有点都围起来的多边形,这个多边形一定与胶箍围成的多边形是一样的。面试官接着问最坏情况下,这个算法的复杂度是多少。我跪了啊!最坏情况就是所有点都在四边形的外边,这样的话要计算所有多边形的排列数,还要把它们加起来,我说这个数列我不会求和-0- 面试官就让我说个近似,我说是阶乘级的。然后,然后就没有然后了这次面试的时间是 1 小时 15 分钟,说得很详细,因为印象很深刻。当时刚放下电话发
13、现手在发抖面试过程中多次出现说话不利索的情况= =一周之后的星期一,Vczh 告诉我邹欣老师已经批了我的 intern request;又过了一周,还是星期一,收到了 HR 姐姐的 intern offer。所以星期一真是我的幸运日啊讲完了面试经历,总结开始首先是简历。我的简历是在李樾学长的悉心指导下完成的,在此特别鸣谢:-p。非常建议在应聘一些比较特别的公司的时候,专门为这家公司准备一份简历。可以通过各种渠道(主要是互联网)先了解公司的文化、需要什么样的人才,然后在简历里写上自己符合公司需求的优势。写在简历上的东西宁缺勿滥。建议只写必要的东西,而不是堆彻。所谓必要的东西,就是你认为最能吸引招
14、聘者的东西,或者说比较特别的东西。当然具体还要视个人情况而定,比如某一类软件做了很多个(如编译器),可以都写出来,突出优势。简历上肯定有一些东西是做了比较久的,在面试之前一定要复习一遍,最好做到被面试官问起相关知识都能够流利回答的程度。IT 公司面试一个人主要考察他/她的能力,或者说专业技能(除此之外可能还包括性格、道德等),当然如果招收的是实习生,那么应聘者的潜力占的比重会多一些,但招聘仍然以了解应聘者的能力为主。那么公司会如何考察一个应聘者、一个程序员的能力呢?面试官会通过纸面上看得到的能力和纸面上看不到的能力两方面了解应聘者。所谓“纸面上看得到的能力”,就是能写在简历上的东西,更准确的说
15、是应聘者的积 企业最新招聘信息点这里“中公快就业 专注于大学生求职/实习的招聘平台 更多求职技巧这里”累。做过一个大型软件、看过 100 本书、获得的奖项,这些都是积累。对于程序员而言,能够吸引公司的积累包括:工程经验(GitHub):对于找工作的人,拥有丰富的工程经验是莫大的优势。这也是我目前最欠缺的。所谓实践出真知,在软件这个行业,确实有太多知识,如果你没有实践过,是永远学不会的。开发大型软件的经验尤其如此。Linus 说“Word is cheap, just show me your code”,某种程度上说,没有比代码更好的简历了,你的技术水平将在代码中显露无遗。所以越来越多的公司甚至要求应聘者提供他们的Github 页面。读过的书(豆瓣):一个勤思考的人如果遇到一本好书,那他将会进步得飞快。虽然有许多知识必须经过实践才能学会,但看书绝对是增长知识几乎最快的方法。这个行业技术近乎瞬息万变,唯有不断地学习才能适应。一个爱读书的程序员绝不会太差,因为好读书这本身就是一种上进的表现。另一方面,程序员们是脑力劳动者,这决定了只有不断思考的人才能站在行业的尖端(仅从技术上而言),读书恰恰能为思考提供巨大的助力。技术博客:再一次,我强调写技术博客的好处。写博客不仅能促使人更成熟