写在最前
16年正式毕业,计算机科班出身,ACM打铁选手,此前一直在一家互联网创业公司由实习到转正,从Server到Client,从PC到iOS,经历了很多从0到1的产品,算是创业公司一个不错的历练经历。
今年八月底收到面邀,本来HR想让我直接现场面,奈何因在职状态不好脱身,遂申请了一轮电面。
电面一面 用时47分钟
第一次交锋-英语听说测试
首先是双方寒暄,大概聊了聊简历上的东西,没有太多要注意的地方。算是进入状态前的一个小插曲吧。
随后是对方要求你使用英语进行自我介绍。其实我英语挺好的,巴拉巴拉的说了一些东西,大概如下供各位参考:
Hi,my english name is XX,I was borned in Shandong province in 1993(ninteen ninty-three),Since I want to be a programmer ,I choose to major in computer science.It does bring me a lot of fun,and this may be the best decision I ever made,BUT,not to my girl friend,she always complains about me of getting home too late.(在这里笑一笑就可以打住了,如果对面英语OK,应该可以get到笑点)。
接下来就是英文问答环节了,对方大概依次问了以下问题:
- Tell me something about your daily work.
- What if you get a hard problem,how you gonna solve it?
- Your hobby?
- Can you picture some episode about season 8?
其中问题2,4都是根据回答进行的提问,比如我在问题1的回答中有提及Solve problem with teammates.问题3回答了喜爱看美剧《权力的游戏》后,问题四提出了关于我对第八季的一些剧情猜想。因为我本人确实非常喜欢冰火,曾抱着学习的目的看过英文原版部分章节,而且电视剧也刷了好几遍,所以许多人名,情节,也是张口就来。这块聊得比较多。也比较顺畅。
第二次交锋-算法
电面算法要求是说出算法思路及涉及到的数据结构,如有可能,分析时空复杂度。到这里我手心已经有点汗了,毕竟周围没有纸笔,五官就用了个耳,还是一只。吭哧的回了一个“OK”,对面就开始了。
(注:以下只是简要问答)
问:请说出二分查找的实现思路及时空复杂度。
答:Excuse me?在确定了没听错问题以后,巴拉巴拉给秒了。
问:快排听过吗?他是怎么实现的?
答:分治思想,基准元素,每次排序完成切割,递归左右两个模块即可。
问:如果是非递归,你会怎么实现?
答:借助栈(这个之前看过面试题,问题不大,思路,时空复杂度都分析出来了。)
问:如果是单链表的快速排序,你怎么做?
答:(有点出乎意外,要求了一两分钟分析,还是说出了大体的思路,在这里提醒大家对于链表的问题,一定要先往辅助指针上面靠,后来我在百度的面试也遇到了链表问题,通过多个辅助指针解决。)
问:回答得不错,看来算法确实可以,以前参加过ACM吗?有什么收获?
答:参加过,巴拉巴拉。收获方面主要是讲了作为一所普通学校学生有这个兴趣去做这样一件事,我觉得本身就是一个很有意义的事情,而且在这个过程中也确确实实提高了coding能力,奖牌这种东西嘛,也是团队合作的结果,讲究配合巴拉巴拉。
问:我们也是比较喜欢拿过ACM奖的人,尤其是毕业一到三年这种的。
答:笑而不语。
第三次交锋-简历内容
问:我看你简历上的项目有用到关于protobuf的东西,而你自己也有写序列化反序列化的实现,能介绍下吗?
答:(这里算是在简历上给自己挖了个坑,装逼写了句”研究过protobuf源码“,但是我又不慌,因为我确确实实看过整型的序列化过程,这里贴个自己目前翻译的protobuf官方文档:protobuf官方文档翻译 ,有需要的小伙伴可以参考一下,也欢迎参与contribution。)我顺势说了句:可以的,我们拿整形举例,巴拉巴拉。
第四次交锋-结尾
问:嗯,好,不错。目前工作主要是做客户端开发多一些吗?有接触过搜索、推荐方面的东西吗?
答:没有,不过我巴拉巴拉(尝试把话题叉开)。
问:好,我大概明白了。你有什么问题想问的吗?
答:(咨询了一些以后可能做的工作内容,用到的技术,以及团队人数等。)
电面总结
整体不难,感觉英语加分不少,不足之处首先是电面耳机一定要备好,我就是在大马路牙子上走走停停进行的电面,其间有数次因为听不清楚对方说的话而产生了小小的尴尬,而且因为受外界影响较多,导致有几次思维受到影响;其次像微软这样对英语水平有所要求的公司,电面完全可以提前准备一张英语自我介绍,以及可能问到的一些问题等,甚至可以打印一些问答类的面试题嘛(虽然这样不太好,呵呵)。最后不要在简历中写过于”装逼“的话,比如研究过XX源码,我是运气好,说完int实现后对方不再进行追问。
二面 用时90分钟
二面是安排在两天后的丹棱街5号微软大厦1号楼。因为没怎么坐过地铁,地铁用时心里没数,所以提前一个小时到了,在大厅等了大概半个小时,提前半小时联系了HR。然后被领进了2号楼(应该是?只记得走过了一个很长的空中走廊),微软的新办公环境真是没的说,安静,气派,整体感觉比较空旷。
被领到一个小型会议室后,过了几分钟进来一个面试官。下面直接进入主题。
自我介绍
问:先做下自我介绍吧?
答:巴拉巴拉,我本科比较丰富的经历要数ACM了,巴拉巴拉。后来学长推荐来了北京一家创业公司,巴拉巴拉。
问:这个XX的CEO是XXX吧?
答:是啊,怎么,您认识?
问:我是他的学生。
答:(内心震惊666,表面平静000,瞬间感觉距离拉近了好多)巴拉巴拉有来有往的说了一些公司情况,产品线等,略去不谈。
简历项目
这一块主要是问你某个项目或者产品的具体,其实与技术无关,只要讲清楚这个产品是干什么的就可以了。最好能讲的清楚,我认为对随后的细节问答会有帮助。
随后就是针对一些点进行提问了。
问:有遇到过什么技术上的难点吗?
答:我刚来公司的时候,很多东西不懂,尤其是业务上的,然后leader就分给我一个与业务无关的模块,也就是比较底层的驱动开发,是用纯C开发的,各种宏定义,大写变量看的真是像天书一样摸不着头脑。但还是扛下来了,慢慢的也将这个底层的API实现了,然后为了后者调用方便,我还在现有基础上封装了一套通用的组件接口(系统要对接不同品牌硬件,相应的有不同接口规范),这是其一。还有呢,以前很少做多线程方面的东西,本身也接触不到,然后系统多线程用得非常多,也是耗费了大量的精力去学习,去研究。
问:那现在多线程掌握的怎么样了呢?
答:自我感觉还好。(呵呵一笑)
然后自然而然的,是针对多线程技术展开了询问,我总结一下有以下点:
- 进程和线程的区别。
- 线程都有哪几种状态。相互之间的转换关系能画一下?
- 多线程有什么好处?
- 死锁听过吗,死锁发生的条件是什么?(就答出一个来,实在是忘了)
- 生产者-消费者的PV操作伪代码。(其实PV是什么我了解,就是记不起来一个完整的伪代码该怎么写出来,经过引导答出。)
问:我看你还有参与开源项目,能说下这个XX吗?
答:(项目参与度真心不高,但是整个项目阅读量很高,也有一些模块研究过,所以就抓住这几个模块详细讲解即可。其实面试官也不知道具体的实现细节,你能把握住最熟悉的模块,尽可能流畅的讲出便可以通过。)
算法-排序
问:手写一下快速排序吧,我看你参加过ACM,所以用非递归实现一下。
答:(微软面试给的纸很多,画一个栈,模拟一个数组,走两边流程就能大概把代码主体搭起来,然后细节,比如边界点,奇偶数等想清楚补充上即可,大概花了六七分钟吧,写完了。)
问:(看了看代码,然后他自己也模拟了一遍流程,跟我讲)你这里对吗?你这里巴拉巴拉。
答:(我听他这么说也挺紧张的,明明走了好几次流程了,怎么会出错呢,于是看了他指的地方,原来是取出栈顶元素后没有接着pop()出去):哦哦哦,这里啊,确实是错了,应该巴拉巴拉。
算法-链表合并
问:有k个有序单链表,怎么合并成一个有序单链表?
答:(想了片刻)应该两两归并,你看假设这俩链表进行合并,巴拉巴拉,其实他就是个递归过程。
问:我发现你特别喜欢递归,参加ACM竞赛也会用递归吗?
答:(呵呵一笑)递归方便嘛,而且平时写代码也主要是以方便他人看懂、容易维护为主。
问:你觉得递归程序容易维护?那如果数据量非常大怎么办?
答:会爆栈。
问:一般程序中栈大小是多少知道吗?
答:不清楚,几M吧?
(没回答我对错)
问:嗯,那你写一下代码吧,不准用递归。
答:(然后花了几分钟写了非递归代码,有序单链表合并本身没什么难点和坑)
问:你这个时间复杂度是多少?
答:两两合并最坏是巴拉巴拉,是length1+length2,最好的情况是min(length1,length2)。然后一共需要k-1次合并,所以是巴拉巴拉。
问:有办法优化吗?
答:(提出最小堆思路,并大概描述了一下,此题结束。)
算法-压轴题
此题是白板描述问题,白板分析思路+伪代码,不要求完整代码。
问:文件A包含有100万个由搜索引擎统计的用户搜索关键字(简称query),比如protobuf,microsoft apple google,iphone 8等等,每个query由一个或多个单词组成。文件B包含1000万个从twitter上爬取的用户说说,假设所有的说说都是不超过140个单词的句子,每个句子有一个唯一的ID号,现在对于任意一个句子,假设它包含了文件A中任意一个query,那么我们就说这个query和这个句子具有相关性。请你找出文件A中的所有关键字对应的说说ID号。
答:(我个人觉得很没头绪,思考了大概三四分钟也没什么思路,于是试探性的说了一个暴力的遍历,本来以为会召来一脸嫌弃,没想到面试官点头道,好,你把伪代码实现一下,说着把画笔给了我。。。然后我真的把遍历的伪代码写了出来,他也没跳出什么毛病。)
问:有办法优化吗,我看你这个时间复杂度,想必你自己也不满意吧?
答:那是肯定的,我怕你等太久嘛,就提出了这个算法(其实在写伪代码的时候脑子里就已经在思考优化方案了)。
问:那你尝试优化一下。
答:在这个过程中包含有大量的无意义遍历,比如一个说说只和文件A中的几个特定的query有关联,其他根本没关联,但是这个算法也把他们遍历了,所以我们可以考虑针对每个说说,缩小100万这个数量级。(构造一个哈希map,其中key是每个关键字,value是这个关键字在文件A中的索引,比如第0行,第1行,第n行(关键字有可能重复的))。
(这道题我觉得很难,本身也符合面的bing新闻推荐岗位的要求。说到后来自己都不知道在说些啥,漏洞百出,被面试官纠正了好几次,后来他也感觉出我的绝望了,开始引导着我去分析,我就不断的嗯,嗯,嗯。。。Orz)
一面总结
- 对于算法要求比较高,尤其是手写算法,一定要细致到边边角角的东西,甚至你直接用Node*都不行,他会提示你Node*是啥结构,所以你最好认为他要求你写的是一个完整的程序。
- 能上代码解决的绝对不多BB,丢给你笔就要求你实现。
- 动笔前一定要想清楚代码结构是怎么样的,提前预留出足够的空间,微软纸管够。否则因为各种条件值的判断,边界处理等代码见缝插针的写,会导致整体非常难看。