查看原文
其他

【老万】我在谷歌弄啥咧之九:克雷格#1

2017-01-31 老万 老万故事会

在谷歌,我有幸跟两位大神级的工程师一起工作过。一位叫克雷格,另一位也叫克雷格。今天先讲讲第一位。



这位克雷格是克雷格⋅西尔维斯汀(Craig Silverstein),谷歌第一位员工,工号为3(1号和2号自然是创始人拉里和谢尔盖)。两位创始人是杰出的计算机科学家和创新家,但未必是优秀的程序员。Craig是他们在斯坦福计算机系的博士同学,被他们忽悠过去,把他俩一团麻的代码理顺重写,才有了第一版的google.com。此后很长一段时间,Craig都负责我歌的具体技术工作。直到今天,我们用的很多基本C++库都是Craig当年开发的。


入职的时候,Craig的职位是整个公司的工程主管(Engineering Director),不负责具体某一产品。以他的地位,已经是想干啥就干啥,想干多少就干多少了。但据我观察,他大部分时间还是战斗在一线,积极参与各种邮件表上热火朝天的技术讨论,同时自己还写很多代码,维护他领头开发的那些基本库。此外,作为最有资格说“谷歌是我看着长大的”的工程师,他还在保持谷歌文化纯洁性上投入了很多精力。


像我这样的小兵路人甲,怎么可能和Craig这样的超级元老有交集咧?这要感谢我歌的meritocracy(谁对听谁的)文化。大家知道,一家小公司在初创时期,员工一定是不分彼此,各显其能。我加入公司的时候,虽然已经远远过了初创时期,公司还是保留了不少早期的文化 -- 这要感谢老员工们的执着。那时,很多内部用来开发的系统和工具(infrastructure and tools)还不成熟,有很多机会造轮子和改造轮子。在司内的C++用户邮件表上,我经常可见Craig和其他人的讨论如何改进这些系统,但一开始我并没有和他有直接的交流。


我第一次和Craig讨论是关于一个自动化的小工具。程序员是最喜欢自动化的一种动物。我自己经常为了让一件小事的效率更高,花数倍甚至数十倍的时间去开发一个工具。如果这个工具只是我自己用几次,当然不划算。不过,用的人多了,成本就收回来了。而且,考虑到其他程序员肯定也会想“这件事怎么这么难搞,难道不应该有个工具自动做这事吗?要不我自己写一个?”,这类小工具经常还是值得写的。


不管你是用C++,Java,还是别的什么编程语言,刚创建一个源文件的时候都有一些简单机械的东西要写,像文件头的注释啦,版权声明啦,包含一些基本的头文件啦,等等。这种不得不写的八股代码,我们叫做样板(boilerplate)。为了减少写样板的重复劳动,早有人在常用的编辑器里集成了样板生成功能:举例说,当你创建一个名字叫foo_test.cc的文件的时候,编辑器会从文件名推断出这是一个C++测试,然后会自动在文件中插入写测试的样板代码,让程序员可以在其基础上修改,而不是要无中生有造出来。


做gtest内部推广的时候,想把这个自动生成测试样板的功能改一改,生成基于gtest的测试代码。这个功能的原作者周哲正好从总部搬来了柯克兰办公室,我就去和他商量这件事。他让我直接改好了。不过,虽然他贡献了这个功能,他并不是这段代码的主人(owner),所以我必须要征得主人的同意才能提交我的改动。这里要解释一下:为了保证代码的质量,在我歌每个代码目录都有一个到多个owners负责 -- 出了问题要拿他们是问。所有的改动,必须要经过某位主人的审查(除非改动的作者就是一位主人)才能提交。而这段样本生成器的主人,就是Craig。我有些犯嘀咕:Craig位高权重工作紧,数钱数到手抽筋,我能和他说上话吗?结果,Craig很快就批准了我的改动。


不久,我有了一次机会和Craig正面冲突。当时我在设计一种方法让大家可以写“编译不过的测试”。这是什么意思?就是这个测试的目的是要确保某些代码没法编译:如果编译成功,测试就失败了;如果编译失败,测试就成功了,有点绕吧。那么问题来了:这么搞除了吃撑了还有别的解释吗?答案是有的。当你在写一个库的时候,一个很重要的考虑应该是如何防止用户以错误甚至恶意的方式来使用这个库。如果用户用错了,我们的库函数不应该将错就错破罐破摔(那样可能会造成严重后果),而是应该大喝一声“雅蠛蝶!你不要乱来啊!”(不要问我雅蠛蝶是什么意思,我是不会知道的,只是看别人用也就跟着用了。)这一嗓子要叫得越早越好,最理想的就是根本不让这样的代码编译通过。解决这个问题可以有不同的方法,但是都需要对构造系统(build system)做出改动。而Craig,正是我歌当时的构造系统负责人之一。


在软件开发方法学上,我和Craig来自两个不同的阵营。我是在耶鲁读的博士,领域是函数式程序设计语言。受这一领域的学者影响,我对设计的抽象性非常强调。在我看来,一个好的设计首先应该有一个简单、干净的编程接口。至于这个系统的实现,可以很复杂,但是所有这些复杂性应该都是隐藏在那个简单接口的后面,用户是不用知道的。比如包大人问元芳,汽车能跑你怎么看?元芳回答:禀大人,我认为其中一定有一个大大的引擎。对于普通用户,知道“有引擎”这一层,会刹车、踩油门、打方向盘就够了,用不着学习引擎是如何工作的。Craig的观点跟我不同。他对一个复杂的系统不太信任。用他的话说,他对黑魔法(black magic)比我更加抗拒。如果让他用一个系统,他希望对系统的工作原理能够比较了解,知其然,还要知其所以然。


这两种观点,其实都有道理,只是侧重点不同。一个好的系统设计师,应该兼顾各方面的需求,做出合理的取舍。因为人都是有局限性的,想法不同的人在一起才容易撞出火花 -- 前提是大家都能畅所欲言,平等交流。在我的老东家,我想我是没有机会也不敢跟一号员工过招的。在我歌,这件事就这么自然发生了。除了我们俩,其他工程师也陆续加入了讨论。尽管我是个小毛头,没人对我说“我比你级别不知道高到哪里去了,你too young too simple”。大家平起平坐,谈笑风生。最后,双方都做出了一定让步,搁置争议,共同开发,任务不久就完成了。想到自己影响到了Craig的想法,心里美滋滋的呢。


此后数年,我又多次观察到Craig对我歌工程师文化的指导和贡献。比如每个星期,Craig会在办公室现烤面包和同事们分享。当讨论激烈起来某些同事有点出言不逊的时候,Craig会提醒大家互相尊重。发现整个公司牛毛长得太长太乱了,Craig会支持工程师们自己组织的“修理它”(fix-it)活动,放下手头的工作两天,一起给牦牛理发(参见本系列“剃牛毛”一文),把出来混欠下的债还掉。看到公司C++代码量越来越大编译越来越慢,他又牵头开发了一个叫“吃多少拿多少”(Include-What-You-Use)的工具,帮助程序员把代码里对不必要的头文件的依赖去掉。这个工具是我和Craig两人作为主要作者共同开发的,前后差不多有一年多时间。我因此得以近距离观察大神的工作,收益良多。对Craig惊人的精力和编程效率,我尤为叹服。


天下宴席没有不散的。5年前(2012年),不差钱的Craig决定离开谷歌,转战公益事业。他加盟的,是知名的在线教育非赢利机构可汗学院(Khan Academy)。Craig给可汗带去的不光有多年的工程经验,还有在办公室烤面包的文化。可汗学院的课件做得很好,深入浅出引人入胜。今天,我的孩子们都是它的忠实用户,在那里学数学、历史、编程,......,体会学习的快乐。Craig,感谢你。




往期文章:我在谷歌弄啥咧之八:中国




长按-识别二维码关注“老万故事会”公众号:


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

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