
春招来临,「如何拿到大厂 offer」成了每个求助者最关心的问题。在本文中,谷歌大脑高级软件工程研究员、强化学习框架「多巴胺」(Dopamine)作者 Pablo Samuel Castro 分享了他拿到谷歌 offer 的经验。这份「谷歌面经」不仅适用于谷歌的软件工程师职位,对申请其他公司的软件工程师及其他职位(如研究科学家)也有帮助。
大家经常问我,怎么才能拿到谷歌的 Offer?虽然这个问题没有固定答案,但我还是有一些可以帮助其他人(包括我自己)的技巧。
我在谷歌的面试过程不算完美,但我确实感觉整个过程都很好、很客观。无论结果如何,请记住:你的个人价值不该由你是否得到了 offer 来定义。引言我应该申请谷歌的职位吗?这是另一个常见问题。答案几乎总是肯定的!去谷歌面试不仅可以测试你的极限,还能让你发现自己的不足。如果你尝试过,就算最后没能成功,我也保证你会成为更加强大的程序员和面试官。在获得 PhD 学位后,我立志成为一名学者,但那时(大概是 2011 年)的就业市场真的非常糟糕。在上司的建议下,我申请了谷歌的职位。这是我申请的唯一一份业界工作,也是我在业界最感兴趣的工作。在提出申请后,我为面试做了许多准备。我确信,如果申请的那天就进行面试,我是无法通过的:花时间准备面试是非常必要的。到面试时,我感觉自己已经准备得非常充分了。最终,努力得到了回报:我收到了加入谷歌匹兹堡办公室的 offer,从 2012 年起,我成为了一名谷歌软件工程师(SWE)。
我在谷歌匹兹堡办公室的第一张办公桌。如何申请谷歌?你可以访问谷歌求职网站找到合适的职位:https:///;推荐一般也有用。如果谷歌有你认识的人,可以请他们内推。如果你不认识任何在谷歌工作的人,而且你已经申请了一段时间,但仍没有收到任何回音,可以发简历给我,看我能不能帮上忙。请注意,这种做法依然无法保证你得到面试机会。我不太清楚面试筛选标准,因此无法在这方面给出建议。如何准备谷歌面试?面试(至少)包括三个部分:编程、算法和数据结构,以及个人品质。谷歌(和其他公司)经常举办面试研讨会,你可以在会议中进行模拟面试;如果有条件的话可以搜索并加入这些研讨会。编程你要能写出函数式代码。而且理想情况下,你写的代码要可以立即编译或运行。语言不重要,但你要指定面试时想使用的语言。因此,要确保你非常了解自己选的这门语言。此外,伪代码不是一种语言。1. 用 Barebones 编程如果你写代码时依赖 IDE,请试着用 barebones!无论你用什么程序写代码,请关闭语法高亮和自动补全功能。尝试用什么都没有的 vim 写所有代码(即便是现在我还是在用非常简单的 vim 写大多数东西,包括这篇文章)。你也可以用 Emacs。2. 熟能生巧我在准备面试时,主要用 C++ 写打码,所以我决定专注于此。我发现了一个在线的编程比赛,这个比赛有之前比赛的记录,这样可以「假装」正在比赛。好处在于,这个在线服务可以以编程方式检查代码的语法和算法的正确性。经过努力练习,我终于从头写出了可以编译及解决问题的 C++ 代码。在此之前,我重复了千千万万遍。此外,我还花了好长时间搜寻需要的库,以及如何执行正确的 I/O 等。我不记得用过哪些网站,但 topcoder 中有针对实践问题的部分,似乎可以达到相同的目的。topcoder 地址:https://arena.topcoder.com/#/u/practiceProblemList也可以浏览 glassdoor 这样的网站,网站中有大量过去的谷歌面试题。试着解出所有的题。glassdoor 地址:https://www.glassdoor.ca/index.htm3. 在白板上写代码试着在白板上写代码(如果你没有粉笔或白板,也可以在一张纸上手写)。在白板上写代码的感觉截然不同,但谷歌面试中有这项要求。有经验当然最好。我建议你在白板上写完整的程序,然后再在电脑上编码,并确保可以一次编译或运行成功。如果无法成功,请再试一次。让别人围观你在白板上写代码也非常有用,可以帮助你适应可能出现的紧张情绪。有几处语法错误是可以接受的,但如果代码太粗糙,而且错误过多,面试官可能会觉得你不熟悉自己选的语言。算法和数据结构我准备面试时看的书也是我读大学时用的书——Thomas H. Cormen、Charles E.Leiseron、Ronald L. Rivest 和 Clifford Stein 写的《算法导论》(Introduction to Algorithms)。我肯定,还有很多书都可以帮你达到相同的目的,只不过这是我随手就能拿到的书。有一些算法和数据结构是你绝对要知道且熟悉的:-
排序:了解不同的排序方式。知道各种排序算法的适用场合及复杂性。
-
链表:什么是链表?你能否从头写出一个链表?插入、删除和搜索的复杂度是多少?什么时候使用链表?链表是否有不同的类型?
-
哈希:什么是哈希函数?怎样的哈希函数称得上好的哈希函数?什么是哈希冲突(collision)?如何解决冲突?平均复杂度是多少?最坏情况下的复杂度是多少?
-
二叉树:什么是二叉树?你能从头写出一个二叉树吗?什么是二叉搜索树?搜索、插入、删除的复杂度是多少?平衡树意味着什么?复杂度是多少?
-
动态规划:什么是动态规划?何时用动态规划?你是否会用动态规划算法解决问题(你可以从书中挑选一个例子进行练习)?
-
图算法:图的遍历算法(BFS/DFS)。有向图和无向图。你能从头写一个图数据结构吗?什么时候用图?修改图有哪些不同的方法?
-
即便这个问题看起来微不足道,但也经常有一些意料之外的棘手情况。通过简单的方案更容易解决这样的问题;
-
简单的方案可以很快地写在白板上,有利于面试官评价你的表现;
-
简单方案的复杂度分析比复杂方案的复杂度分析要容易得多;
-
简单方案可以快速写出来,之后就可以转向寻找更复杂的解决方案,但你至少有一个可以作为基准的简单方案;
-
对面试官来说,理解简单方案比理解复杂方案更容易。你肯定希望面试官能理解你的方案,如果一个复杂方案让面试官都困惑了,不利于得分;
-
过一遍简单方案相当于对代码进行「手动分析」,有助于你挑出冗余的工作,还可以优化代码;
-
简单的方案也可以是深入交流的开始。既然已经有了一条解决方案,然后你就可以询问面试官,是否想要更好的方案;
-
最后,要确保你已经告知面试官,你是以一个简单方案开始(不代表你只能给出简单方案)。
-
你拿到了 offer;
-
你需要进行额外的电话面试。这不一定意味着你的面试表现不够好,还可能是在面试过程中未能正确评估某种能力;
-
可能会让你担任其他职务。这并不是件坏事,这只意味着招聘小组根据资料,认为你更适合担任其他职位。此间也会有一些附加面试,归根结底也是件好事;
-
你没能得到 offer。这有点遗憾,在谷歌拿到 offer 确实不那么容易,但你为这次面试所做的努力,以及这次面试经历本身,都会在其他面试中帮到你。另外,一年后你也可以重新申请谷歌职位。我曾审查过某人的资料,他起初没有得到 offer,但在一年后重新提出了申请,最终得到了 offer。
![]()


















