查看原文
其他

面经分享:网友问我,怎样才能在谷歌匹兹堡办公室里写代码?

点击关注 👉 Java面试那些事儿 2020-10-08
Pablo Samuel Castro是谷歌Brain的一名高级研究员,其研究内容包括强化学习、机器学习等。近日,Pablo分享了他作为谷歌面试官的一些经验,以期对有意向到谷歌工作或从事软件工程工作的研究者有所帮助。

大家经常问我,怎么才能拿到谷歌的 Offer?虽然这个问题没有固定答案,但我还是有一些可以帮助其他人(包括我自己)的技巧。


我在谷歌的面试过程不算完美,但我确实感觉整个过程都很好、很客观。无论结果如何,请记住:你的个人价值不该由你是否得到了 offer 来定义。


背景介绍

 

我应该申请谷歌的职位吗?这是另一个常见问题。答案几乎总是肯定的!去谷歌面试不仅可以测试你的极限,还能让你发现自己的不足。如果你尝试过,就算最后没能成功,我也保证你会成为更加强大的程序员和面试官。

 

在获得 PhD 学位后,我立志成为一名学者,但那时(大概是 2011 年)的就业市场真的非常糟糕。在上司的建议下,我申请了谷歌的职位。这是我申请的唯一一份业界工作,也是我在业界最感兴趣的工作。


但是在我决定申请之后,我为面试做了很多准备。我确信,如果我在申请当天就参加面试,我是无法通过面试的:我花在准备面试上的时间是至关重要的。


当我参加面试时,我觉得我已经做好了最大的准备。我的努力得到了回报:我收到了加入匹兹堡谷歌的工作邀请,从2012年开始就在谷歌做SWE。



我在谷歌匹兹堡办公室的第一张办公桌。



以下文章的其余部分是我的经验:

 

  • 为面试做准备


  • 作为SWE在谷歌工作


  • 进行数百次采访


  • 主持数十个面试研讨会


  • 成为招聘委员会成员


  • 在谷歌内外,我与许多人进行了讨论。


这里的建议并不能保证你能得到谷歌的工作,但它应该会有所帮助。

 

如何准备谷歌面试?


你可以在谷歌求职网站上找到你认为合适的工作。

 

找人推荐会有帮助,如果你认识已经在谷歌的人,让他们推荐你。如果你不认识谷歌的任何一个人,你已经申请了职位,但是在一段时间里没有收到回复了,请随时把你的简历发给我,我看看有什么我可以做的。


注意,这仍然不能保证你会得到面试机会。不幸的是,我对应征者如何被选中参加面试知之甚少,在面试过程中的影响力也有限。

 

我如何准备谷歌面试?

 

至少有三个要素能让你在面试中表现出色:编程、算法和数据结构,以及个性。谷歌经常有研讨会,你可以做模拟面试。

 

编程

 

你要能写出函数式代码,最理想的情况是能够立即编译/运行。语言不是特别重要,但是你需要具体说明你想用什么语言面试,所以一定要掌握好。伪代码不是一种语言。

 

用 Barebones 编程

 

如果你写代码时依赖 IDE,请试着用 barebones!无论你用什么程序写代码,请关闭语法高亮和自动补全功能。尝试用什么都没有的 vim 写所有代码(即便是现在我还是在用非常简单的 vim 写大多数东西,包括这篇文章)。你也可以用 Emacs。

 

练习、练习、再练习

 

准备面试的时候,我主要用c++编程,所以我决定专注于此。我发现了一个在线编程比赛,它有以前比赛的日志,这样我就可以“假装”自己在比赛。很棒的是,这个在线服务可以以编程方式检查我的代码的语法和算法正确性。


我做了足够多的工作,最终可以从头开始编写c++代码来编译并解决这个问题。在做到这一点之前,我经历了很多很多的反复。很长一段时间,我仍然需要查找需要包含哪些库,如何正确地执行I/O等等。


我不记得我使用了什么网站,但似乎topcoder有一个实践问题领域,可以达到相同的目的。


topcoder 地址:https://arena.topcoder.com/#/u/practiceProblemList

 

浏览glassdoor这样的网站也是很有用的,那里有很多过去谷歌的面试。尝试解决所有这些问题!请注意,如果你在这样的地方看到了问题,你在真正的面试中被问到这个问题的可能性很小。


glassdoor 地址:https://www.glassdoor.ca/index.htm

 

在白板上写代码

 

试着在白板上写代码(如果没有粉笔或白板,也可以用手写)。在白板上写代码感觉是很不一样的,但这就是你在面试中要做的。最好是你已经有了一些经验,我的建议是在白板上练习写完整的程序,然后在你的电脑上编码,并确保一次编译/运行。如果没有,再试一次!

 

当别人在看的时候,在白板上练习编码也是非常有用的,可以让你适应潜在的焦虑反应。

 

虽然有一些语法错误是可以接受的,但是我们要注意的是,如果代码很粗糙,而且语法错误很多,这表明你使用的是你可能不太熟悉的语言。

 

算法和数据结构

 

我用来准备面试的那本书是我本科时用过的:托马斯·h·科曼(Thomas H. Cormen)、查尔斯·e·雷瑟森(Charles E. Leiserson)、罗纳德·l·里维斯特(Ronald L. Rivest)和克利福德·斯坦(Clifford Stein)合著的《算法导论》(Introduction to Algorithms)。

 

这里并没有太多需要了解的算法和数据结构,但是这里有一些算法和数据结构是你绝对应该知道的,并且是需要非常熟悉的。请注意,这绝不是详尽无遗的,如果你觉得我遗漏了什么,请告诉我!

 

  1. 排序:了解不同的排序方式。知道各种排序算法的适用场合及复杂性。

  2. 链表:什么是链表?你能否从头写出一个链表?插入、删除和搜索的复杂度是多少?什么时候使用链表?链表是否有不同的类型?

  3. 哈希:什么是哈希函数?怎样的哈希函数称得上好的哈希函数?什么是哈希冲突(collision)?如何解决冲突?平均复杂度是多少?最坏情况下的复杂度是多少?

  4. 二叉树:什么是二叉树?你能从头写出一个二叉树吗?什么是二叉搜索树?搜索、插入、删除的复杂度是多少?平衡树意味着什么?复杂度是多少?

  5. 动态规划:什么是动态规划?何时用动态规划?你是否会用动态规划算法解决问题(你可以从书中挑选一个例子进行练习)?

  6. 图算法:图的遍历算法(BFS/DFS)。有向图和无向图。你能从头写一个图数据结构吗?什么时候用图?修改图有哪些不同的方法?



上面的列表并不是需要了解的全部内容,但我认为知道这些都是应该的。

 

就像编码一样,关键是练习、练习、再练习。当你处理不同的问题时,请考虑解决这些问题的最佳数据结构。

 

它已经在上面的列表中有所暗示,但是你应该能够对你编写的任何代码执行复杂性分析(即big-O)。我个人几乎总是在候选人写完他们的代码后问这个问题,因为这表明他们能够分析他们实现的有效性。


正如我将在下面详细介绍的,即使你只能为一个问题提供一个简单的解决方案,如果你能够正确地分析它,也会有很大的帮助。

 

个性

 

这个有点难准备,但它仍然很重要。作为面试官,我们需要问自己的一个问题是:我愿意和这个人一起工作吗?


如果你是个天才,能够解决抛给你的所有问题,但你在面试中表现得十足差的话,那么你被录用的机会就很低。关于准备工作,我没有太多的建议,但在面试过程中有几点需要记住,我会在下面列出。

 

面试的时候


如果你已经安排进入面试了,首先要恭喜你,这已经很了不起了,因为不是每个人都能参加面试。这些重点你要记住:

将面试视为一次平等的对话,而非单方面的询问。尽管在面试的双方是权力不对等的,但我们并不是要骗你或者让你犯错。事实上,我们大多是在默默为你加油。

说出你的思考过程。确保将头脑的思路过程清晰地展示出来,尤其是在白板上写代码之前。作为面试官,我们需要一些证明你表现良好的证据,说明白你的思路就有助于我们收集证据。此外,如果你陷入了一些我们认为不值得花太多时间的问题,我们可以及时帮你拉回来。如果你不说话,而直接写了错误的代码,我们无法知道你是真的不懂,或只是误解了问题。另一方面,如果你默默写出了完美的代码,我们也不知道你是真的明白,或许你只是见过这个问题。

简单的解决方案是很好的起点。不要勉强自己想出最高效的方法,先给出简单的方案是很好的策略。

为什么这么说呢?原因有很多:


  1. 即便这个问题看起来微不足道,但也经常有一些意料之外的棘手情况。通过简单的方案更容易解决这样的问题;

  2. 简单的方案可以很快地写在白板上,有利于面试官评价你的表现;

  3. 简单方案的复杂度分析比复杂方案的复杂度分析要容易得多;

  4. 简单方案可以快速写出来,之后就可以转向寻找更复杂的解决方案,但你至少有一个可以作为基准的简单方案;

  5. 对面试官来说,理解简单方案比理解复杂方案更容易。你肯定希望面试官能理解你的方案,如果一个复杂方案让面试官都困惑了,不利于得分;

  6. 过一遍简单方案相当于对代码进行「手动分析」,有助于你挑出冗余的工作,还可以优化代码;

  7. 简单的方案也可以是深入交流的开始。既然已经有了一条解决方案,然后你就可以询问面试官,是否想要更好的方案;

  8. 最后,要确保你已经告知面试官,你是以一个简单方案开始(不代表你只能给出简单方案)。



可以简化假设。做一些简单的假设能帮你更清晰地思考问题,原理和「给出简单方案」类似。这个的好处在于可以表现出你有解构问题的能力,代表你能分辨出可能会造成严重问题的部分。

使用测试示例。找一些可以测试代码的测试示例,试着预测边际情况(例如空列表、越界索引、预料之外的特殊字符等),这样有助于保证代码的准确性,也有利于征服面试官。举例真的很有用,面试官甚至可能会添加一些测试示例来检验你可能遗漏的其他边缘情况。

花几分钟整理思路。我虽然建议你讲出思考过程,但也不用勉强自己一直讲话,尤其是在你还没整理好思路的情况下,不停讲话就可能导致你进入误区。可以提出申请「我能花两分钟整理一下思路吗?」,重要的是要让面试官知道你在干什么。如果你觉得整理思路的时间太长,可能是因为你对问题的某一部分感到困惑,这就是下一个问题。

可以寻求帮助。如果感到困难,你可以寻求帮助,但要具体说明问题在哪。一般可能是你误解了问题,所以没能注意到问题中重要的点,有时也可能是面试官自己忘了提到问题中重要的部分。我就遇到过这种情况,面试者似乎被难住了,但我给了一点帮助后,他们就解决了问题。

可以有所不知。我参加面试时,实现了一个自定义数据结构,来简化解决方案中剩下的代码。面试官问我:「你为什么不用映射?」,我告诉他「我不知道什么是映射」。面试官很快在白板上给我解释了映射的语法(这是比我的「用户数据结构」更简洁的版本),然后我就更快地解决了问题。我不知道是否因为承认自己的无知而得分,但最终得到了这份工作。

没有「唯一正确」的答案。至少在大部分面试中都没有唯一正确的方案,我最喜欢的是可以快速陈述、易于理解、同时存在简单解和复杂解、而且很容易就能变复杂的问题。我认为大多数面试官都会问这些问题。这意味着我们并没有预设答案,你只要尽你所能就可以了。

不要问你给出的答案是否正确。最好是用测试用例验证你给出的答案,并根据测试结果证明答案是正确的。

可以有分歧。和面试官有分歧没关系,但是要用礼貌的方式表达。用具体工具(比如代码和测试用例)支持你的观点;如果只有口头讨论可能会引起误会,这样会消耗有限的时间。试着理解面试官的观点(尽管他们看起来是错的),并冷静地让面试官理解你的观点。

将每次面试都视为一个崭新的开始。如果你觉得哪次面试很糟糕,请将它搁置在一边,或者等一切都结束后再想,然后开启下一次面试。我知道这说起来简单做起来难,但你得明白,下一次的面试官不会知道你之前的表现。就算你有一次面试的成绩很糟糕,但你也可能通过下一次面试。

如果有时间,提点问题。我一般都在最后给面试者留出时间,让他们问一些有关在谷歌工作的常见问题,比如你的角色或经历等。如果你有问题,也许表示你对这份工作确实很有热情。如果你没有问题的话,那可以向面试官请教,可以请问他们在谷歌的角色和经历。不要问「我在面试中要怎么做?」或「正确答案是什么?」这样的问题,因为我们不会回答这样的问题,这可能会使场面变得尴尬。



面试结束后


唷!你成功了,再次祝贺你!随后的过程如下:

 

  • 每个面试官都会为你写他们的反馈,并提供雇佣/不雇佣的建议。面试官看不到其他面试官的反馈。


  • 你的简历——包括所有东西:你的简历、面试反馈、过去的面试等等——会经过几个招聘委员会的审核(但我不知道具体有多少)。这是一群谷歌人(没有一个面试过你),他们会通读你的简历,并根据你的简历内容提供他们自己的招聘建议。将有许多人阅读你并提供反馈。


  • 根据招聘委员会的决定,可能会发生以下几种情况:


  1. 你被录用了!


  2. 你被要求接受额外的面试。这并不一定意味着你在面试中表现不够出色。可能有很多不同的原因,比如有一种技能在面试中没有得到恰当的评估。


  3. 你被考虑扮演一个不同的角色。再说一遍,这并不是一件坏事,这只是意味着根据你的分组,不同的委员会认为不同的角色更适合你。这可能会涉及到一些额外的面试。最后,这是一件好事,你申请的职位可能不是你想的那样。


  4. 你没有得到工作机会。如果这是你的结果,我很抱歉。在谷歌获得一份工作是非常困难的,人们已经暗示有很高的假阴性率。所以不要气馁!你为这次面试所做的准备工作,以及面试本身的经历,肯定会帮助你在其他面试中表现得更好。最后,你可以在一年后重新申请!我查看了一开始收到无报价的信息包,一年后又收到了报价。

 

最后的一些想法

 

这篇文章比我预期的要长很多,但我真的希望它对你有用。虽然这篇文章主要是为谷歌的SWE面试而写的,但是这些建议应该也适用于其他公司的SWE职位。


几年前我为Shopify面试过,我运用了以上所有的技巧;我最终得到了一份工作机会,但我拒绝了,因为我被邀请加入了谷歌Brain(我现在愉快地在那里工作)。

 

这篇文章对non-SWE角色也有一定的帮助。我最熟悉的non-SWE角色是研究科学家(RS)。我对RS角色进行了一些研究访谈,但还不足以提供具体的指导。然而,我要说的是,即使是对于RS角色,你也必须通过一些编码面试。


我面试了一个应聘RS职位的人,他在理论方面很强,但在编程面试中表现很差,因此我提出了不聘用的建议 (这个人从来没有加入谷歌,但我不知道他是否被录用了)。

 

还有很多人分享了非常有价值的建议,Mekka Okereke在这个帖子中分享了一些很棒的建议,还有Steve Yegge,一些人也建议把《编码面试》作为一本值得学习的好书。


参考链接:


https://twitter.com/mekkaokereke


http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html


https://twitter.com/mekkaokereke/status/1135981075086266368


原文链接:https://psc-g.github.io/interviews/google/2020/02/25/interviewing-at-google.html



 往期推荐 

🔗


 

点击阅读原文,获得更多精彩内容

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存