前天下午结束了微软的一面和二面之后,昨天中午收到了微软HR的电话,通知说晚上10点会有微软美国那边的面试官来进行三面。于是昨天下午也没心情做测量的事情了,重新把LeetCode和手写代码的文档拿出来翻了几遍,然而这其实也是心理安慰而已,自己的水平到哪里其实已经定下来了。
晚上10点刚到,面试官很准时的进入了Skype的房间。看到面试官是中国人之后,心里算是放松了一点。原本已经做好了最坏的打算,就是碰到印度的面试官然后要求全程英语面试……面试官的职位是Principal Engineering Manager,应该算是挺高的职位了吧。这个时间西雅图才是早上7点,面试官这么早起床面试我也是挺不容易的的。
刚开始还是先让我自我介绍,然后聊了一下之前在腾讯实习的经历,接下来就是挑一个我认为最值得讲的项目出来介绍一下。当然又把联通的交往圈项目拿出来讲了,但这次面试官并不太关心具体的算法是怎么实现的,而是希望知道我在这个项目中哪一项能力得到了最大的提高。说真的,其实这个项目的技术难点也没有那么大,所以我回答说在这个项目里,我的调研能力和改进现有算法的能力得到了比较大的提高。毕竟在较短的时间内,从头开始设计一个算法是不太现实的,对方也会觉得有水分。所以关键的能力还是从现有的文献中归纳出有哪些可用的算法,分别评估各种算法的优劣,然后根据实际情况对算法进行组合和改进。面试官还看到我提到了分布式课程上面的Spark Streaming的大作业,也就问了一下Spark的东西,还问了为什么在联通的项目里面我们没有应用这些分布式框架。我回答说由于算法本身的限制以及时间上的考虑,就没有使用Hadoop和Spark的这些分布式框架。
聊完实习和项目,接下来就是关于编程语言的几个问题。面试官看到简历上我写对C++比较熟悉,就问了两个C++的问题。
- class 和 struct 有什么区别
- C++中虚函数是什么以及虚函数的实现机制
这两个问题基本上是属于必考题,要是答不上来也就不用继续往下面试了。
然后就是关键的写代码环节了。出的题目是“在二叉查找树中,查找与目标值最接近的节点并返回。如果有多个节点都符合要求,返回其中一个即可”。在微软的这几轮面试中,我发现题目本身并不会特别难,但是除了解答出题目本身,编程风格、命名规范、异常值处理等等也是面试官很看重的地方,所以千万不要因为题目看起来比较简单就轻敌。刚开始想的时候把二叉查找树有顺序关系的条件给忽略了,还以为要左右节点分别递归下去计算再做选择。想着想着发现自己傻了,因为二叉查找树的顺序关系,当计算出当前节点的值与target的gap之后,如果当前gap小于全局最小的gap,就更新全局最小的gap,记录全局最接近的节点为当前节点,然后如果当前节点的值大于target,应该往左子树搜索,反之就往右子树搜索。当前节点为NULL的时候,说明搜索到了叶子节点,终止循环并且返回记录下来的全局最接近的节点。在循环当中,如果计算到gap等于0,说明找到一个跟target相等的节点,就没必要继续循环了,直接break出去就行。代码大致如下:
1 |
TreeNode* findClosestNode(TreeNode* root, const int target) |
写完了程序只是完成了一半的工作,面试官还会要求你提出尽可能多的测试用例去测试你实现的函数,这一点是微软和其他公司较大的差别。
写完这道题之后,面试官也没让我继续写题了,而是问我的英语口语能力怎么样。我回答说日常应用还行,然后面试官就让我用英语回答“为什么你想加入微软公司实习”和“你为什么在之前的项目中使用Linux环境以及使用Linux的水平如何”。第一条问题是在看到的每篇微软面经中都出现的,所以之前也稍微准备了一下。大概就是说我从小就开始接触微软公司的产品,所以希望加入微软公司去让这些我的朋友和家人们每天都使用到的产品变得更好。
最后面试官让我提几个感兴趣的问题。我问了一下面试官所在小组是做什么的,他回答说主要是做Active Directory的服务,然后还有相应的权限管理服务,以及在Data Center里面的一些应用。我还问了假如要加入微软实习,是否需要提前学习微软内部使用到的那些开发技术和工具。面试官说其实也没太大必要,目前微软也在不断向开源社区学习和贡献,内部也有不少跑Linux/Unix的环境。
问完上面的问题,面试就暂告一段落了,接下来就看看有没有进一步的消息了。