最近签掉了 offer,找工作的事情算是告一段落。在这里写一点面试体验和心得,希望对有兴趣去北美工作的朋友有所帮助。
先简单介绍下自己,国内硕士在读,明年毕业,没有牛 paper,也没参加过 ACM-ICPC 竞赛。在实验室做过内核、虚拟机和 Android 底层相关的研究工作,接过一些网页和移动开发的外包,2011 年开始在字节社兼职负责后台开发。另外也经常上 Stackoverflow 和 GitHub。
这次决定直接申请美国的职位后,由于心里没底,不知道国外公司招聘的难度,所以一开始投了很多公司。几个大公司都找人内推或者直接投了,小公司也投了不少,比如 Foursquare、Path、Pinterest 和 Square 等都试了。当时甚至在手机上找了一圈应用,把可能涉及后端开发的应用都投了一遍。不过大多数公司都没给我安排面试,只有 Microsoft、Google、Facebook、Twitter 和 Hulu 这五家公司愿意给我面试机会。
一般来说,国内毕业后直接投国外公司,会比出国留学毕业后找工作的难度大一些。除了语言因素之外,我了解到的主要原因在于工作签证,出国留学毕业后可以通过 OPT 签证入职,之后再过渡到 H-1B 签证。而国内毕业的学生只能通过 H-1B,这意味着要等到第二年的十月份才能入职。好在 Google、Facebook 等公司不太介意这个问题,还是会欢迎国内的应届生申请。
校招的 HR 一般会有各自的职责。比如 technical sourcer 负责发现有希望进入自己公司的应届生;recruiter coordinator 会帮助 recruiter 安排面试者的面试时间、面试官,以及 onsite 面试时帮助面试者订机票和酒店;staffing consultant 则负责发 offer 以及介绍公司的具体福利制度,并解释面试者相关的问题。不同公司的 HR 职责的分法自然也不一样,我在 Facebook 的面试过程中只和两位 HR 联系过,而在微软的面试过程中则联系过五六位 HR。
在面试流程方面,相比我了解到的国内公司的面试,国外公司的面试安排上会更人性化一些。例如安排面试时间时,HR 一般会先让你给出几个空闲的时间点,然后他们再从这些时间中给你安排面试。此外在为你安排 onsite 的住宿时,也会询问你有没有相关的要求。
关于面试题目,大多数公司都比较侧重面试者对基本的数据结构和算法的掌握程度,以及把这些内容实现为实际代码的能力(一般会要求你选一个语言实现,而不允许用伪代码)。越是规模大的公司越注重这些基本功,而小公司除此之外还会考察你的开发经验,例如对某个框架的了解和性能优化方面的技巧。关于这一点区别我的理解是大公司里面会有自己的框架和开发工具,面试者的基本功好就能比较快的上手;而小公司一般用社区现有的工具,所以已有的开发经验可以直接用在将来的工作中。
下面是这几个公司的面试细节,有些公司因为在 onsite 面试的时候签了 NDA,所以没法透露具体的面试题,还请见谅。
Microsoft
微软是我最早投的公司之一,托了在微软总部工作的一位学长帮忙内推。面试包括一轮 HR 面和四轮 onsite 面。
申请了一个多月后一直都没有反应,直到微软国内招聘的前一天,北京的 HR 打电话问我是不是投过微软的职位,要我参加第二天上海站的笔试。
笔试过后,又过了一个多月,收到了微软一位招聘人员的邮件,问我是不是对微软北美的职位有兴趣,要我填一份基本情况的问卷,里面有问到其他公司的面试进度。我当时已经收到了 Google 和 Facebook 的面试邀请,就如实填写了。回复第二天后就收到了邮件通知,告诉我会有 HR 进一步跟进。第三天有一位 HR 联系我和我约电面的时间。微软约电面的方式和其他公司不大一样,HR 会给出很多个选项,让你在里面选择几个空闲的时间。另外值得一提的是这些时间都转成北京时间了,这也是微软在安排面试时比较人性化的一个地方。
第一轮面试是 HR 面。HR 先问了一些技术无关的问题,比如喜欢做什么,工作地点的偏好,什么时候开始学的编程,为什么投了微软等等。接着是一些智力题,比如 9 个小球,8 个质量相等,另一个比其他的重,如何用天平称两次把它找出来;公司开发了一种新键盘,有哪些测试它的方法;在会议室内怎么估计室外的温度。都是些更像是考验英语水平而不是技术能力的问题。
面完第二天收到了 onsite 的通知。虽然是北美的职位,onsite 面试地点却是在上海。我参加的是周日的面试,和我一起参加面试的还有一位学生,他之前在微软实习,了解到这次有去北美工作的机会后也想尝试下。面试官是从总部飞过来的工程师,一共有四位,其中三位都已经是 principal 级的了。HR 提到一般技术面试要五轮,因为我们之前参加过一轮笔试,所以只需要面四轮。
onsite 面每一轮的过程都差不多,都是面试官自我介绍,接着我介绍自己和做过的一些项目,然后开始技术问题,最后是我提问的环节。微软的面试问题会考察面试者编码、设计和测试三方面的能力。
coding 环节要求直接在白板上写代码,我被问到两个 coding 问题。一是如何检查一棵二叉搜索树是否正确,二是写一个解数独的程序。第一个问题写起来很快,第二个问题因为时间有限,我先写了一个没啥剪枝的暴力搜索的版本,写完后和面试官分析了可以在此之上做的优化。
设计方面的问题有两个。第一个问题是设计一个分布式的数据管理系统。使用场景可以是一个连锁店信息的记录系统,每个分店都有可能更新自己的信息,并把这些改动传播到整个系统中。在设计这一系统的同时要考虑性能、容错、一致性等要求。我一开始想了一个基于 push 的机制,在面试官指点下逐步优化,最后还是有不少问题。于是干脆重新设计了一个基于 poll 的系统,优化改进之后面试官满意了。
另一个设计问题和类的设计有关,要求设计一个包含图形界面的棋盘游戏。因为之前做过不少相关的开发,所以这一部分我还挺擅长的。按照 Single Responsibility 的原则设计了几个分工明确的类,另外把网络对战和 AI 接口都考虑进去了。设计完成后面试官要求我从用户鼠标单击这一事件开始介绍整个控制流程,在某些类中还会问及这么设计的原因,以及和其他设计方案相比的优缺点。
测试部分的问题也有两个。第一个问题是如何测试一个随机函数。第二个问题和分布式系统有关,面试官先向我介绍了一个分布式系统,包括它的使用场景和基本的架构,然后问我其中某一个部件应该如何测试。提到正确性、可伸缩性、一致性和容错性后再给出相应的测试方法应该差不多了。
onsite 面试后的第二天后就收到了 HR 的邮件,祝贺我拿到了 offer,并和我约时间谈具体的 offer 细节。虽然微软一开始拖了