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

算法和数据结构

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

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

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

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

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

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

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

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

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

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

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

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

个性

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

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

面试的时候

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

面试结束后

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

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

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

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

你被录用了!

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

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

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

最后的一些想法

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

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

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

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

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

私信我

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值