Cate:我是如何准备Google面试的

jopen 12年前
   <p>         英文原文:<a href="/misc/goto?guid=4958342660858959109">Interviewing @ Google</a></p>    <p>        导读:Cate 是一位加拿大的软件工程师,目前就职于  Google 。本文是他在 2010 年在 Google 面试后分享的文章。</p>    <p>        也许你可能没有参加过谷歌面试(或者没能答出面试中的一些问题),这里我会分享一下上周我的面试经历。我个人感觉良好——至少已经全力以赴了,无论结果如何都会对我有很大的帮助。</p>    <p>        由于已经签了保密协议,因此我不会写出面试的问题。然而,我会写一下我是如何得到这个面试机会以及准备面试的过程。</p>    <p>        首先,面试的是谷歌。如果没有在 Google 工作的朋友和我谈起并推荐我,我是不会应聘的。因为我“离得比较近”,因而没有参加电话面试,直接进行了在线面试。我并不认为渥太华和滑铁卢(加拿大)离 得很近(也许这是因为我没有加拿大人的距离感!),但是我确实认为与人面对面的交流会比电话面试好的多。那天我的运气特别的好,因为那天晚上的经历就像是 “Ignite! Waterloo”活动,非常酷。</p>    <p>        译注:Ignite! Waterloo:加拿大的一个社区活动,在广泛的议题上进行五分钟快速演示,展示了滑铁卢地区的极客文化。</p>    <p style="text-align:center;"><a title="Google interview" rel="lightbox[18040]"><img style="width:552px;height:330px;" title="Google interview" alt="Cate:我是如何准备Google面试的" src="https://simg.open-open.com/show/d21505f4e3b5e8242c3f245c24abfdd8.jpg" /></a></p>    <p>        首先,我和招聘专员简单聊了聊,他/她告诉我可以使用白板,并且介绍了整个面试流程。接下来我和两个软件工程师分别进行了 45 分钟一对一交流。我惊奇地发现原来面试也可以这么有趣!通常我在面试的时候都会非常紧张,然而这次没有与很弱的人一起扎堆面试,这真的很酷!第一长面试的 问题非常简单,第二场虽然难一点但也面得不算太差。最困难的恐怕就是在白板上编程(不能用电脑!)——在白板上很难用 TDD(<a title="测试驱动开发" href="/misc/goto?guid=4958319318562333230" rel="nofollow" target="_blank">测试驱动开发</a>)!他们会告诉你不要穿正装,实际上最好也不要这么做——我费了不少时间坐在地板上写白板,身边到处都是各种记号笔。可以想象如果穿裙子会是怎样的情景!</p>    <p>        他们提前会发一份面试需要准备的事项列表,这对我非常有帮助。虽然我大学的课程学得很好,但最好还是有针对性地复习一些专题。除了通常的准备, 这里还有一些额外可以关注的内容——保持与最新的业界资讯更新,大量使用 Google 的产品,思考如何使用技术改变生活,撰写博客(是的,最后两项也很有帮助)。与此同时,我已经很好地掌握并运用 Java 5 扩展,像是<a href="/misc/goto?guid=4958342662398955773" rel="nofollow" target="_blank">范型</a>、<a href="/misc/goto?guid=4958342663191473550" rel="nofollow" target="_blank">枚举</a>、<a href="/misc/goto?guid=4958342663989621296" rel="nofollow" target="_blank">for-each</a> 等等。</p>    <p><strong>        下面是我用来准备的相关资料:</strong></p>    <p>        读《<a title="Effective Java" href="http://www.amazon.cn/gp/product/B001PTGR52/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B001PTGR52" rel="nofollow" target="_blank">Effective Java</a> (第二版)》 –——作为一名合格的 Java 程序员没有任何理由不推荐这本书。</p>    <p>        读《<a title="程序员面试攻略" href="http://www.amazon.cn/gp/product/B0012UNC7K/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B0012UNC7K" rel="nofollow" target="_blank">程序员面试攻略</a>》 并运行所有书中的例子——对于回顾类似树、列表这样的数据结构基础概念非常有帮助。我不是很喜欢递归那一章(从我自己使用的角度),我更推荐使用迭代。尽管如此,它真的是一本非常有用的好书。</p>    <p>        读《<a title="编程人生" href="http://www.amazon.cn/gp/product/B004GCCAGK/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B004GCCAGK" rel="nofollow" target="_blank">编程人生</a>》 –——这本书中有很多人在谷歌工作,这从另一方面说明了谷歌的文化。书中同样还充满了很多我以前从未注意到的有趣编程故事,还有这些牛人是如何解决问题,讨论 API 以及增强程序扩展性等内容。</p>    <p>        复习《<a title="Combinatorial Algorithms: Generation, Enumeration, and Search" href="http://www.amazon.com/gp/product/084933988X/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=job0ae-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=084933988X" rel="nofollow" target="_blank">Combinatorial Algorithms: Generation, Enumeration, and Search</a>》 中的背包问题(Knapsack),旅行商问题(Traveling salesman)以及 NP 完全问题(在秋季学期里我学了组合数学并且从头到尾读完了这本书)——坦率的说,我不很喜欢这本书。我感觉这更像是一本数学书。如果你是一名程序员而不是 数学家,用实际的代码来解决这一类问题可能会更有帮助,而且 Wikipedia 读起来肯定更容易理解。</p>    <p>        做一些《<a title="Java 解惑" href="http://www.amazon.cn/gp/product/B004EF8C6Q/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B004EF8C6Q" rel="nofollow" target="_blank">Java 解惑</a>》中的问题,这会帮助锻炼你阅读代码找错的能力。虽然我没有被问到这类问题,但是我确实需要仔细检查自己的代码。IBM 在我的手机屏幕上给我出过电子商务的问题,我知道谷歌也会使用这类题目。</p>    <p>        复习并发问题——<a href="/misc/goto?guid=4958342668642252453" rel="nofollow" target="_blank">死锁</a>、<a href="/misc/goto?guid=4958342668642252453" rel="nofollow" target="_blank"> 活锁</a>、<a href="/misc/goto?guid=4958342670176140067" rel="nofollow" target="_blank">互斥量</a>、 <a href="/misc/goto?guid=4958342670176140067" rel="nofollow" target="_blank">锁</a>和<a href="/misc/goto?guid=4958342670176140067" rel="nofollow" target="_blank">信号量</a>等等。在 Java 中什么时候使用<strong>synchronized</strong>关键字?你怎么样避免死锁和活锁?</p>    <p>        复习<a href="/misc/goto?guid=4958342672436498886" rel="nofollow" target="_blank">树的遍历</a> ——前序遍历、中序遍历和后续遍历,<a href="/misc/goto?guid=4958342673237137879" rel="nofollow" target="_blank">深度优先搜索 vs 广度优先搜索</a>、<a href="/misc/goto?guid=4958342674031992486" rel="nofollow" target="_blank">A*算法</a>,<a href="/misc/goto?guid=4958201856214562071" rel="nofollow" target="_blank">Dijkstra 算法</a>等等。</p>    <p>        复习<a href="/misc/goto?guid=4958342675563400437" rel="nofollow" target="_blank">平衡二叉树</a>——<a href="/misc/goto?guid=4958342676353974326" rel="nofollow" target="_blank">红黑树</a>、<a href="/misc/goto?guid=4958342677140708313" rel="nofollow" target="_blank">AVL 树</a>和 <a href="/misc/goto?guid=4958201900692925294" rel="nofollow" target="_blank">伸展树(Splay-tree)</a>。</p>    <p>        复习<a href="/misc/goto?guid=4958342678670441538" rel="nofollow" target="_blank">图</a>——图的表示, 最小生成树,图的搜索等等。</p>    <p>        <a href="/misc/goto?guid=4958342679468500822" rel="nofollow" target="_blank">算法复杂度分析</a>。</p>    <p>        编程实现 6 种<a title="排序算法" href="/misc/goto?guid=4958342680251246575" target="_blank">排序算法</a>——包括算法复杂度为O(n log n)的那些算法,使用 TDD 风格编程(我使用的测试用例可以<a href="/misc/goto?guid=4958342681068831250" rel="nofollow" target="_blank">参考这篇博客</a>)。</p>    <p>        编程实现<a href="/misc/goto?guid=4958342681866218991" rel="nofollow" target="_blank">哈西表</a>,要求只能使用数组。支持包括:范型,动态数组,延迟初始化,要求测试优先。</p>    <p>        练习所有手头上能够找到的问题——搜索“Google interview questions”,不用有什么顾虑,可以看看<a href="/misc/goto?guid=4958342682660587616" rel="nofollow" target="_blank">这些问题</a>。有时候我用 Eclipse 写代码,但也会用 Google docs。我会找一个朋友审查我的代码并向我提问。</p>    <p><strong>        经常</strong>找在谷歌工作的朋友聊天,问<strong>很多</strong>问题。他非常棒,并且全力帮助我准备面试。不仅如此,通过理解他为什么认为我适合在谷歌工作,我也更深入地理解了自己想去谷歌工作的理由(是的,这的确有点迂腐。但是正如我的导师告诉我的,即使是谷歌,挑选你喜欢的公司和公司挑选你也是同样重要)。</p>    <p>        虽然我自己认为只是准备充分,但在谷歌工作的朋友戏称我准备得“几近完美”。除了这些准备之外,我还能做些什么呢?</p>    <p>        更多的代码分析实战 —— 尽可能多地找代码去分析。</p>    <p>        计算数列的和。例如,你如何计算数字1-n的和?请给出证明。回顾我在第二场面试中的分析,我给出的答案是: (n-1)(n-2) + (n-2)(n-3) + … + (3)(2) + (2)(1)。当然,我没有及时地给出答案,所以我的时间复杂度上限是O(n³)。</p>    <p>        复习 Java 函数库,数据结构。这个时候,我会认真地回答:“我知道有这样的数据结构不会接收重复的值,只是现在记不起来叫什么名字了”。实际上只要实现 <a href="/misc/goto?guid=4958342683461828669" rel="nofollow" target="_blank">Set</a> 接口就可以做到,这个我也是下午才刚学会。</p>    <p>        复习函数库中的某些关键点——<a href="/misc/goto?guid=4958342683461828669" rel="nofollow" target="_blank">Arrays</a> 和 <a href="/misc/goto?guid=4958342683461828669" rel="nofollow" target="_blank">Strings</a> 非常有用。</p>    <p>        练习在白板或者纸上编程。你可能想当然地想在白板上插入一行或者进行<a title="重构" href="http://www.amazon.cn/gp/product/B003BY6PLK/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B003BY6PLK" rel="nofollow" target="_blank">重构</a>,这可是非常困难。同样地,在白板上写代码很容易忘记写 return 语句。Eclipse 从来不会让我自己写这些声明和 reurn 语句,并且会把我的代码放在函数的中间,而白板可做不到!</p>    <p>        <strong>接下来该做什么?</strong></p>    <p>        等待。</p>    <p>        等待。</p>    <p>        等待!</p>    <p>        无论结果如何,我都希望能得到一些反馈。</p>    <p>        把面试的问题写成代码(同时写好测试用例!)</p>    <p>        完成《<a href="http://www.amazon.cn/gp/product/B004EF8C6Q/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B004EF8C6Q" rel="nofollow" target="_blank">Java 解惑</a>》中的问题。</p>    <p>        整理面试经历——我花了很多时间准备这次面试,相信你可能已经收藏了这些面试题目。</p>    <p>        寻找其它的机会。我对 IBM 特别感兴趣,找一些在那里工作的朋友看看有没有什么合适的机会。</p>    <p>        和导师们谈谈这次面试经历。</p>    <p>        英文原文:<a href="/misc/goto?guid=4958342660858959109" rel="nofollow" target="_blank">Cate</a>  编译:<a href="/misc/goto?guid=4958185140659301754" target="_blank">伯乐</a>在线 – <a href="/misc/goto?guid=4958342688666051599" target="_blank">唐尤华</a></p>