我在Google的前三个月

Sep 06, 2020

Noogler hat

距离上一篇文章已经过去半年了,这么久没有写东西,主要是因为上一篇文章消耗了我太多的精力与感情,主要是感觉没什么时间,倒不是说在Google很忙碌,更多的是之前在学校的时候属于自己的时间太少了,所以在毕业之后的这几个月里,我基本都在做一些之前没时间做的事,包括但不限于陪女朋友睡觉发呆做饭玩游戏等等等等。当然还有给自己两年前在瑞典交换时遇到的教授写信,很惭愧,来美国之后的两年里都没有联系过他。其实经常想到他,可是总是很忙碌,也觉得自己没有做成什么事,没什么值得骄傲的东西可以分享给他。他的回信来得很快,我觉得很开心,因为他说他也过得很好。只不过鉴于目前全球疫情的关系,我们一致认为下次我去欧洲或者他来美国的时候,至少也是2021年年底了。

IT Crowd里面有一集,Jen不在办公室,然后Roy和Moss在办公室疯玩,把他们平时想玩却不敢玩的东西全都玩了一遍。都玩完之后,他们就开始觉得无聊,又开始打电话给Jen,问她什么时候回来。我现在的状态就有点像Roy和Moss疯玩结束之后的状态,有点不知道该做什么,这周五一直到下周一都放假,四天的假期,没有什么期待,也没有什么动力工作。突然想到自己还可以写点东西回顾一下这几个月,那么就稍微写点吧。

起始

我在今年六月初加入Google,主要是做一些程序分析的工作,简单来说就是通过分析程序的行为来识别Android平台上的各种恶意软件,然后及时下架这些恶意软件,从而保护用户的设备安全。程序分析算是一个很有用也很热门的研究主题,不过本科生阶段很少会接触这个,主要还是在研究生阶段提到的比较多,所以从事相关工作的人普遍跟学术界有千丝万缕的联系。我们组接近十个人,我应该是其中唯一一个没有拿到PhD学位的人,平时来的实习生也是各个大学里的博士生。所以我来到这个组,觉得自己很幸运,因为比起做业务的组,这里更像是一个做研究的组,基本可以看作是学校的延伸*。不同之处在于这里的资源很丰富,同事们也都很nice,不存在我在学校里遇到的那种push的环境,而且做得也是真正好的产品,不会像学术界一样,大部分时候是为了展示idea而草草做了一个勉强能用or几乎不能用的prototype。

刚进来的时候就是像发现新大陆一样的开心,Google的内网里有太多可看的东西,自制的toolchain,各种奇奇怪怪的badge,还有很nerd的游戏,经常看着看着就一天过去了。我觉得很有趣的一点是,Google内部几乎都是用自己开发的软件,俗称dogfood,然后Google的所有代码都放在同一个仓库里,对所有全职的软件工程师都是可见的,所以当发现某个软件出现了问题,或者文档写得不清楚学不会怎么用的时候,常常可以通过直接查看源代码的方式来解决问题。Google的代码都经过严格的code review,大部分代码读起来也比较轻松,所以有问题,往往自己看会儿代码就解决了。

*: 微软的CTO Kevin Scott也有差不多的观点,他在我们学校某个教授手下读了五年之后直接去了Google,并且没回来参加dissertation,也就是说,他没拿到PhD学位。在一个采访中,记者问他为什么这么做,他说他那时候其实都已经写好相当一部分dissertation了,虽然他不再那么热衷于拿到这个学位了,但是他还是想完成这个PhD。转折就在他去当时的Google工作了一会儿,他发现在Google工作太有趣了,而且那时候Google有很多project要做,他就在那里一边骗自己说自己会完成这个PhD的,一边又继续在Google工作。搞笑的是,在那时候居然有很多个像他一样的只差dissertation就能拿到PhD学位的人放弃了学位。那么,Google为什么能让他安心呆着呢?Kevin说是“You know, the funny thing about Google in the early 2000s, the first time that I was there was very academic in nature. So it was an easy transition to make from grad school to Google. You know, the environment was sort of engineered to be very, you know, familiar in that way.” 接近20年过去了,我认为我在我们组看到的Google,就跟Kevin描述的没什么两样。

Code Review

说到code review,可以从我的第一个项目开始。我的第一个项目是改内部的程序分析框架,基本上就是给它加一些功能,专业点说就是让call graph更完整的同时,保留灵活性。由于我之前比较熟悉LLVM,内部的框架又设计得很清晰,所以我上手也很快,加了点新pass,改了点现有的pass,问题就解决了。这段时间里code review带给我的印象还是挺深的,在这之前我一直都觉得写代码是一件很私人的事,如果你让我自己在家闷头写代码,然后自己改改,改到满意了再发布出去,我觉得OK;但是如果让我每新写一点代码就要给别人看,这就让当时的我感到有点羞耻,特别是我才刚来不熟悉,很容易写出很傻的代码。我的前几次code review还是比较漫长的,被几个reviewer来回要求改了好几次。不过话说回来,正因为刚来不熟悉,所以code review对我的帮助是极大的,比如reviewer会告诉我这里某个容器已经在某个文件里定义过了,可以直接引用;又或者告诉我这里的代码应该保持跟某个地方的代码保持一致,等等。这样一来二去的,我不得不去读很多相关的代码,这个过程无疑让我更快且有针对性地熟悉了整个code base。在Google大家搞code review是很认真的,基本上除了正确性之外,大家还会提出比如性能,可读性方面的意见,以及新特性的应用,毕竟在Google的各位大多是紧跟技术潮流的 :)

说完了被人review,也可以说一下review别人的经历。前面说到我是组里唯一一个没有拿到PhD学位的人,再加上我又是新来的,那么很明显可以知道我在组里的等级是最低的。等级最低是否就说明没有代码可以review了呢?并不是。我的第二个项目就是和组里一个L5合作的,我的等级是L3,我基本是负责给他的项目加些代码。在我们合作之后,他每次提交代码也是主动发给我review的,我也每次都认真地看他提交的代码,这样一来其实也可以帮助我更快地熟悉他的项目。

在Google,大家还是会努力营造一个平等的氛围的。我一般懒得去看别人的等级,因为看了也没什么帮助,最多满足一下自己的好奇心,大家平等交流就好。再说了,我认为等级代表的,更多的是此人对公司所作出的贡献,而非此人的水平,所以在这里建议大家,不要迷信等级,相信自己。

个人成长

既然说到了我的第二个项目,我就可以再扯点个人成长的东西。详细点说,我的第二个项目是我的manager带着我,跟另一个组交涉,改进我们组的一个产品,而这个产品是由我们组的一个L5负责的。其实我觉得我的manager完全可以让那个L5直接去跟另一个组交涉,因为那个产品的代码全是他写的,他再熟悉不过了,交流起来很方便。等他们都设计完了,然后直接告诉我该干嘛干嘛,让我去写代码就行了。不过我的manager并没有这么做,事实上,这个项目的design doc基本全是我写的,跟另一个组的交涉也基本是manager带着我参加的。所以我基本就是负责搞清楚我们这边的产品的所有细节,然后跟对方讨论设计细节。这对我这个新来的来说不算容易,但是我很开心能够参与设计,这让我觉得我是这个团队的一部分。

不过话说回来,对于我这种自视甚高的人来说,这种难度的project肯定是让我感到很难受的。事实上,有很多次我的内心状态都跟Anakin是一样的:

you-underestimate-my-power

我认为我的能力完全qualify下一个等级,但是在Google快速升级并不是没有那么容易的事。想要升职,最好的办法当然是做一个有impact的项目,这个大家都知道,但是如果没有呢?就像现在刚进来的我一样。我的思路基本就是多要跟组里的人交流,问问有没有什么可以帮忙的,比如我就跟我自己的mentor要了好几个bug/feature request(我上面提到的“第一个项目”其实不算是我真正的第一个项目,只是我向mentor要来的feature request而已,但是因为比较复杂,所以我在这里把他算作我的第一个项目)。

但这很明显只是临时策略,让我来说明一下。升职是需要写一个report的,report是要给管升职的人看的,但是这些人并不知道我平时到底在干嘛,所以我就需要在短短一个report里向他们说明我是能胜任下一个等级工作的人。在我看来,说明的最好方式就是在report里讲故事。这个故事要从我为什么要做这个项目讲起,然后说我为了实现这个项目做了哪些事,在做这些事的过程中我遇到了哪些困难,我是如何解决的,最后这个项目结果如何,有什么影响力,给大家带来了哪些好处。这样一来,管升职的人就能清晰且快速地了解我的工作。回到临时策略的问题,如果我只是长期帮人修bug,实现feature,那我就会面临一个严重的问题,我没法讲故事了。因为我的工作散落四方,我很可能无法将他们串成几个流畅的故事,这样一来别人很难了解我的工作,也就很难量化我的工作数量与质量,很难判断我值不值得升职。乱七八糟的bug修得越多,就越难串成故事,意味着边际效应也就越明显。就算我可以把他们串成一个故事,那这个故事会有说服力吗?我的manager告诉我说,写升职report要从三个方面来写:leadership,impact,以及difficulty,让我们来仔细看看。首先帮别人的项目修bug,我没有leadership,最多是被leadership,不行;剩下的impact和difficulty其实是一回事,我在改的是别人的项目,别人会把有impact或者difficult的部分交给我吗?probably not。

这个临时策略我打算就用在刚进公司的第一阶段,这个阶段也被很多人叫做build trust的阶段,很容易理解,一般来说进组之前,大家谁也不认识我,没人会去看简历上写了什么,大家只想知道这个人来了能不能做出贡献。在这个阶段,多帮人修bug还是很有用的。一方面可以熟悉组里的project,熟悉组里的同事;一方面可以切实的帮助组里,显得很有存在感,具体可以选择领一个相对重要但是是因为组里的人没时间做才搁置的bug。这样几个月下来,大家也就可以对我做出信任or不信任的选择。在这段时间里,我需要思考我自己到底想要做什么样的项目。在这之后,就差不多是时候去主动争取属于我自己的项目了,这时候manager也会比较放心地把一个独立的项目交给我。有了属于自己的项目之后…我还没想好怎么办。

我认为在公司里,能够明确地知道自己想要什么,想好要怎么做,并为此付出适当的努力是很有必要的。付出太少是对人类社会规则的背叛,付出太多则是对无产阶级的背叛 :)

节奏

进Google之前就听说Google内部的节奏很慢,像养老一样,很多人就是rest and vest。进来之后我亲身感受了一下,感觉慢确实是挺慢的,特别是当下这个时间点,大家都是wfh,所以更感觉到慢了。但是慢背后的原因也还算是可以理解的,一方面就是Google本身提倡work-life balance,经常给大家放假,或者搞no meeting week之类的;另一方面就是,为了维护现有复杂系统的质量,很多的讨论确实就是必要的,赶进度只会让系统的质量越来越低,背上越来越多的tech debt。再说了,这些开会讨论的结果都是有记录的,整合之后会写到design doc里。我最近在写的一个design doc,manager对我的期待就是,把具体要改的代码链接都标到文档上去,我找代码的时候,都是精确到具体哪一行的,所以写的过程中,我基本对要改哪些代码也已经心里有数了。写完design doc之后,剩下写代码的过程确实以体力劳动为主。

其实Google的慢,也可以从Google内部系统的体量去解释。当一个系统到了Google这个体量之后,其复杂度是惊人的,平时看起来简单的改动,在这个系统下都显得不那么简单,因为要考虑的东西太多了。这样一个高质量复杂系统的建立与维护,离不开工程师们的悉心呵护。在现实世界里,这是很难得的,因为人总是倾向于把自己的利益放在第一位的,很多人只想快速地把东西搞出来,赚到钱与名声,以后的问题以后再说,大不了跳槽走人。事实上,Google里也有不少人抱怨的,抱怨为什么节奏这么慢,抱怨为什么公司赚钱的业务这么少,抱怨为什么股票涨不上去,但是幸运的是,至少在我眼里,Google还是在以一个比较一致的姿态在往前进的。有天赋的工程师有很多很多,Google也只是招了一小部分进来,但是为什么只有一个Google,我想这也算是一个原因吧。


总的来说,我很喜欢Google,也很喜欢我自己的组,还挺期待等到疫情得到控制的那天,去到办公室写会儿代码,再跟从来没有在线下见到过的同事们吃个饭,聊聊天,然后在硅谷呆一段时间。

(The End)