访谈Brad Fitzpatrick——《编程人生》精彩样章
丁雪丰/译
Brad Fitzpatrick 是所有受访者中最年轻的一位,也是其中唯一一位从未在没有因特网或个人电脑的世界里生活过的。他出生于 1980 年,很早就开始了自己的程序员生涯, 5 岁时就在一台自制的 Apple II 克隆机上学习编程。在十几岁时,正好赶上因特网革命的大潮,他一头扎入其中,在高中时就建立了自己的第一个商业网站,在进入大学前的那个夏天创立了著名社区 LiveJournal 。
LiveJournal 的日渐流行迫使 Fitzpatrick 走上了学习构建可伸缩网站的艰难之旅,期间他和他创办的 Danga 交互技术公司里的程序员们开发了几个开源软件,其中包括 memcached 、 Perlbal 和 MogileFS ,现在被用于很多世界上最繁忙的网站的服务器上。
Fitzpatrick 是个典型的极有才华的世纪之交的 Web 程序员,他的主要编程语言是 Perl 和 C ,需要时也会用 Java 、 C++ 、 Python 、 JavaScript 和 C# 。他做的所有编程工作基本都与网络相关,比如为网站构建更好的后端基础设施,设计协议和软件来让博客阅读软件获知博客更新,甚至为他的手机编写代码以便在摩托车上就能自动打开车库门。
我们将谈到他在读著名儿童系列丛书 Clifford the Big Red Dog 的年龄就开始学习编程,为什么能够很高兴地一边念大学,一边运行 LiveJournal ,以及他是如何学会不惧怕去阅读他人的代码的。
Seibel : 你是怎么成为一个程序员的?
Fitzpatrick :我父亲曾在 Mostek [1] 工作。这个公司是制造内存的,他对电脑很感兴趣。他做了台 Apple II 电脑,材料几乎都是多余的废弃部件。他和我母亲坐在电视机旁把部件焊起来,这个工作花了他们好几个月,只是把它们焊起来而已。然后我父亲从公司里拿了些不能卖的ROM ,这些 ROM 有一位或几位不能用,有的在高位,有的在低位。后来不知怎么着他们弄到了 Apple II ROM ,接着就不停地将 ROM 烧到无法工作的芯片上,直到找到一块能用的为止,损坏的那位正巧是好的。最终,他和他的一帮同事终于做成了自制 Apple II 。我差不多从两岁起就在上面玩或者看他编程。
Seibel : 他是个程序员还是个硬件工程师?
Fitzpatrick :他是个电气工程师,偶尔也写写程序。我五岁时他就教我编程,搞笑的是我六七岁时就超过他了。我母亲说我是一边读 Clifford the Big Red Dog , 一边读从图书馆借来的 Apple II 程序员手册。我会把 “ 变量”念成 “ 贝量”。我早期的一些记忆就是和父亲一起编程。比如他把我拖进厨房,在纸上写下一段程序,问我: “ 你觉得这段程序是什么意思?”我记得那程序好像是 “ 10 PRINT HELLO, 20 GOTO 10” 。
Seibel : 那么说你是从 BASIC 开始的?
Fitzpatrick :是的,就是 BASIC 。我当时还不能使用鼠标、高级图形模式和彩色,直到我们家的一个朋友向我介绍了 C 并给了我 Turbo C。那年我大概八岁或者十岁。我父亲在 1984 年去了 Intel ,我们就搬去了波特兰。他帮助设计了 386 和 486 ,现在仍在 Intel 。我们总是能有新的有趣的电脑。
Seibel : 那你有没有试过汇编语言呢?
Fitzpatrick :我在计算器上做过些汇编,比如 TI 计算器上的 Z80 ,但仅此而已。
Seibel : 你还记得是什么吸引你开始编程的吗?
Fitzpatrick :我不记得了,只是好玩吧。我母亲不得不限制我使用电脑,好让我出去和朋友们一起玩。我的朋友们会跑过来说: “ Brad 又在玩电脑。他太无聊了。”我母亲则会对我说: “ 到外面去玩吧。”
Seibel : 你还记得写的第一个比较有意思的程序吗?
Fitzpatrick :我们以前有台 Epson 打印机,它配有几本又大又厚的手册,手册最后是程序员指南。我就在 Apple 上写了点东西,我可以在高级图形模式下画些东西,当程序完成绘制(线段、图案或别的什么)之后,按下 Control C ,在后台一个不会显示的帧缓冲区里键入一段内容,加载另一个程序,它会读取屏幕并打印出来。
在那之前,我记得还写过一个程序,每当我敲击一个键,它就移动稿面,我按退格稿面会向回退,这样打字时就感觉像是在用打字机一样了。
这是我的第一个程序,好比方 K 是抓取的下一个字符,如果 K 等于 a ,打印 a ;如果 K 等于 b ,打印 b 。我几乎处理了每个字母、数字和一些标点。后来一个念头一闪而过: “ 等等,我可以说‘打印一个变量!’”然后用 1 行代码替换掉了 40 行。 “ 天啊,这太棒了!”对一个六岁的孩子来说,这已经是抽象能力的极限了。
那些都是比较有意思的早期作品。到了中学,我开始开发游戏,为朋友们制作图形编辑器和关卡编辑器,他们会把图形做进关卡中,随后我们再把它卖给其他同学。我记得我不得不检测 EGA 和 VGA 。如果 VGA 跑不了,就退回到 EGA 模式,使用另一组适合当前屏幕的贴图,为此我们必须为所有的东西做两组图形。学校的人会出大概 5 美元买它,然后安装,接着发现它不能用,他们的家长就会给我爸妈打电话大喊:“ 你儿子拿那没用的东西从我孩子那里骗了 5 美元。”我母亲就开车带我过去,坐在死胡同里等我进同学家调试并修复我的程序。
Seibel : 那段日子里你有没有上过关于编程的课?
Fitzpatrick :没有。就是从图书馆里借了一两本书,然后随便玩玩。当时没有真正的论坛或因特网。后来我连上了一个 BBS ,但上面并没什么内容,它没有联上因特网,只是一群人在玩棋类游戏而已。
Seibel : 你的学校有 AP [2] C.S. (计算机科学)或类似的课程么?
Fitzpatrick :呃,我们没有 AP C.S. 课程,但我们有计算机程序设计课。有一个老师在上这门课,不过我都可以在教室后面讲高级课程了。他们还在用我写的图形编辑器和图形库,他们要做的项目是开发一个游戏。我偶尔还会碰到那个计算机老师,他是我家的一个朋友,我会在我哥哥的足球比赛上看到他,他会说: “ 是啊,我们还在用你的库呢。”
我的确参加了 AP C.S. 考试,那是在考试从 Pascal 换成 C 语言前的最后一年,一年后又从 C 换到了 Java 之类的语言。我不懂 Pascal ,所以去附近有 AP C.S. 课程的高中上了一些夜间班,大概三四次吧。后来我找了本书来学 Pascal ,我把大多数时间花在用 Pascal 画星形线上,因为那时我刚学三角学。我会说: “ 哇哦,正弦和余弦太有趣了。我又可以一显身手了。”
Seibel : 那你考得怎么样?
Fitzpatrick :我得了 5 分 [3] 。考试内容是写一个大整数类。现在这是我招聘人员的一道面试题: “ 写一个能够进行任意大整数乘法及除法的类。”既然我能在高中的一次 AP 考试中做出这道题,那么他们在这儿应该也能做得出来。
Seibel : 你大学第一年的夏天在 Intel 工作,那在高中时期有没有做过程序员的工作呢?
Fitzpatrick :是的,我在 Tektronix[4] 工作过一段时间。在正式工作之前,我有几个主机账号。我写了些机器人程序,往聊天室里灌水,把AOL 惹翻了,这么做确实让人讨厌。我在另一个 Windows 程序中编写 AOL 客户端脚本,还写机器人程序猛提交 AOL 的线上表单,获赠 CD 。因为不想让他们发现这是重复表单而只寄一张 CD ,我用了自己名字的各种变体。这些账户有 100 个免费小时,或者是 5000 个免费小时。在这几千次表单提交后,整整一个星期,邮递员会天天带着很多 CD 过来。
我妈妈说: “ 见鬼, Brad ,你会有麻烦的。”我回答: “ 呃,这是他们的错,对吗?”后来有一天,有一个找我的电话,我接了(通常我不去接电话),电话那头是一个 AOL 的人,他对我大叫: “ 别再向我们提交表单了!”我平时的反应并不敏捷,但这次我立刻回敬了他:“ 为什么你们会寄给我这些废物?每天都有邮递员过来,扔下这些 CD !”他说: “ 对不起,先生。不会再发生这样的事情了。”然后我把这些 CD 都用来布置大学宿舍了,它们现在还放在我家车库的一个盒子里呢。我记得它们曾是很好的装饰品,所以没有扔掉。
恶搞完 AOL 后,我得到了一个当地 ISP 的 shell 账号。大概上我就是在那时学的 Unix 。虽然不能运行 CGI 脚本,但我可以用 FTP 上传东西,所以我就在家里的台式机上运行 Perl 程序来生成整个 Web 站点,接着再上传到服务器上。后来我在 Tektronix 得到了一份工作,类似暑期实习。当时我已经很懂 Perl 和 Web 了,但还没有做过动态 Web 。在 1994 年、 1995 年时, Web 还是个很新的东西。
我去 Tektronix 上班的第一天,他们给我介绍我的办公用品: “ 这是你的电脑。”那是一台大的 SPARC 工作站,也可能是别的什么运行了X 和 Motif 的机器。 “ 这是你的浏览器。”可能是 Netscape 2 ,我记不清了。 “ 如果你有 CGI 的东西,放到这个目录里。”我记得那天晚上我写了个最基本的 Hello World 的 CGI 程序,大约就三行吧,我感叹道: “ 天哪,这太有意思了。”第二天早上六点我就来工作了,继续疯狂地写 CGI 。
后来我开始自己做动态 Web 编程。当时我找了台支持 CGI 的 Windows Web 服务器。我最终说服了我的 ISP (也许是和他们交情不错,或者之前给了他们不少帮助让他们信任我): “ OK ,我们会运行你的 CGI ,但开始前会对它们做审核。”他们仔细查看了代码,然后把那些代码扔到他们的目录里。那是一个投票站的脚本,你可以用它来创建投票程序,例如: “ 你最喜欢的电影是哪部?”添加完选项后就能开始投票了。后来的几年里它变得越来越流行了。
Seibel : 是 FreeVote 吗?
Fitzpatrick :是的,在弄爆我的主机后它变成了 FreeVote 。那时 Banner 广告真的很流行,也许就是那段时间开始流行起来的,我通过它赚到了越来越多的钱,得到越来越好的合同,每次点击的收益也越来越高。最高时每点击一次广告我就能赚到 27 美分,就算是按今天的标准,我觉得也是相当夸张的。有了它,我每个月在 Banner 广告点击方面能有 2.5 万~ 2.7 万美元的收入。
这些都是在高中时做的,我整个高中时期都在私下做这事。我还在 Intel 做了两个夏天,随后在进入大学前的最后一个夏天,我办起了 LiveJournal 。为此,在进入大学的第一年,我卖了 FreeVote ,基本上算是送给一个朋友的,大概只要了 1.1 万美元,因为我想摆脱它,还有相应的法律责任。
Seibel : 你有了 ISP 并开始使用 Unix ,这有没有对你编程带来什么变化?
Fitzpatrick : Unix 并没让我抓狂。我没办法理解 Windows 上都发生了什么,也许你看过 Windows API — —每个函数都有差不多 20 个参数,它们都是标志位,而且一半都赋了 0 值。完全不知道发生了什么。当有东西无法正常工作时,你根本没办法知道究竟是怎么回事。
Seibel : 你早期的编程方法或编程风格和你现在所想的有什么明显的不同之处吗?
Fitzpatrick :我用过很多种编程风格,面向对象的、函数式的,现在用的这种有点怪异,混合了面向对象和函数式编程。这是我热爱 Perl 的原因,虽然语法很丑陋,有很多历史包袱和瑕疵,但它从不限制我写代码的风格。用你喜欢的风格去写就是了。你能让代码优雅一致,却没有和特定语言相关的风格。直到我进入 Google ,我写的 Perl 代码才慢慢少了下来。
运营 LiveJournal 后,我也做了很多测试工作。尤其是当我开始和他人共事时,我意识到永远也甩不掉自己写的代码,要一辈子维护它们时,我开始写测试了。在十年前的博客文章上,我收到了这样的评论: “ 嘿,我看到这段代码,发现了一个问题。”然后我立刻着手维护代码。
我现在维护着很多代码,还有其他很多人在和它们打交道,如果有什么地方不清楚,我会假设有人理解不了我写的某些不变式。因此,当我要搞些小聪明时,通常我都会保证在代码出现问题时有测试及时跳出来。我也强迫其他人写测试,他们基本上都为我工作。我会为自己的代码写测试,当别人写代码时我会告诉他们: “ 你确定这段代码能工作吗?写个测试证明给我看。”有时,他们会意识到 “ 天哪,这么做太有用了”,尤其是在后期维护的时候。
Seibel : 你是从什么时候开始和他人一同共事的?
Fitzpatrick :差不多是在大学结束的时候,我开始雇用其他人,尤其是毕业搬回波特兰后。
早期的雇员是客户支持,所以他们不用写任何代码。慢慢地,我开始雇用程序员。我雇佣的第一个人是我的一个网友,他的名字是 Brad Whitaker ,我们都有名为 BradleyLand 或 BradleyWorld 的网站,因此我们找到了对方的网站。我比他早几年开始 Web 编程,也可能是早一年,他问我: “ 嘿,你的网站是怎么做的?”就是说它到底是 HTML 、 Frame 、 CGI 还是 Perl 的。后来我开始接很多合同项目,我就把一些我不做的项目给他。有一次我们有个大项目,谁都没有办法独自完成,我找到他说: “ 这个项目需要两个人来做。”他让我飞去宾夕法尼亚,也许是匹兹堡?我对东海岸完全没概念,我是个生活在西海岸的人。也许是费城?有牛肉奶酪三明治 [5] 的地方。
Seibel : 是费城。
Fitzpatrick :是的,我们第一次见面是在一家便宜的旅馆里,我感觉好像早就认识他一样。他和我打招呼: “ 嘿,最近怎么样?”他走了进来,在我旅馆的卫生间里上了个厕所,当时我就站在那儿,可他连门都不关。我回答道: “ 还不错。你还真惬意。”虽然我们从未谋面,可就像认识了四五年一样。然后,我们就开始干活了。
他住到我空余的一间卧室里,我们差不多把厨房给搬空了,架起几张桌子,放上电脑就开工了。我们通常 10 点或 11 点起床,干到中午,看会儿电视(穿着短裤坐着看电视),然后不间断地工作到早上三四点钟。后来,我的另一个朋友从华盛顿大学过来度暑假。他是我大学一年级后认识的,我们三个在一起忙碌着。这个朋友住在市区,早上坐轻轨过来,然后滑滑板到我家。他就坐在外面用 Wi-Fi 上网、写程序,直到我们醒过来去给他开门,让他进来。
一起有了三个人,房子就有点挤了,我就说: “ 哦,好吧,我们搞间办公室吧。”于是我们弄了间办公室, “ 我们既然有了这些空间,不如再雇点人吧!”在随后的两年里,我们慢慢扩大到了 12 个人,而 LiveJournal 也逐渐流行了起来,当然压力也更大了,因为我还得处理人事问题。
后来,我妈妈来处理人事,随后我们的关系就有点紧张了,因为她为我工作。我给她定了几条规矩: “ 如果你给我打电话,要分清楚是私事还是公事。要么只谈私事,要么只谈公事。你不能在工作与私人问题间换来换去的。”如果她转变话题,我就会挂电话。然后她再打回来,我会说 “ 你搞混了”。这真的搞得很紧张,当我把公司卖掉时她真的很高兴,她不用再为我工作了,我们也不用争吵了。
Seibel : 那时你的公司还接合同工项目吗,还是说这就是整个 LiveJournal 了?
Fitzpatrick :差不多这就是整个 LiveJournal 了。我们还打算开个照片托管服务,这方面 Flickr 做的比我们好,我们的那个有些过度设计了:漂亮的抽象,能结合到任何东西中。为 LiveJournal 做的每个新的基础设施,我们都会问自己: “ 它怎么和 FotoBilder 结合到一起?”为此,我们把每样东西都抽象出来。 Memcached 是抽象的,因为没有必要把它和 LiveJournal 绑在一起。随后我们还做了个类似 GFS 的文件系统,还有一个任务队列。为了提高可扩展性,我们不停地开发基础设施组件,它们能被应用于我们的各项产品之中,由于没有复杂的依赖关系,它们的维护也更方便了。虽然可能会增加一些工作量,但如果能减少依赖,那还是很值得的,所以我们开发了所有这些通用基础设施。
Seibel : 我对于你扩展 LiveJournal 的过程有些好奇,你是从什么地方开始的,一路上又是怎么学到你需要的东西的?
Fitzpatrick :我们和其他客户共享一个 Unix 主机,差点把它搞挂了。
Seibel : 以 CGI 的方式运行的吗?
Fitzpatrick :是的。我想从严格意义上来说那应该是个 CGI ,派生出所有的东西然后终止掉。 ISP 分配给我一个家伙。我的服务器当时总是死机,我对他说: “ 我每月为这台服务器付 10 美元,它为什么不能工作?”他告诉我: “ 哦,你该这么做。”很快我就学会了 Unix ,知道正在发生的事情。
我从 CGI 转到 FastCGI ,调整了 Apache ,关闭反向 DNS 查询功能。经过了这些步骤,性能有了好转。最终,我遇到了 IO 和 CPU 的瓶颈,我买了自己专用的服务器,但那也只是一台机器,它经常死机,而且我的硬盘快没有空间了。起先这台服务器只对我的朋友开放,我没有取消注册页面。他们邀请了他们的朋友,而这些朋友又邀请了其他朋友,但我并没想过把这个站点变成公开网站。它只是正好有个开放的注册页面。于是,我在 LiveJournal 的新闻页面里写了点东西: “ 我们需要大家的帮助,我们需要购买服务器。”
我记得那次大概募集了六七千美金,我买了两台大的 Dell 服务器,托管在西雅图市区的 Speakeasy[6] 里。有人推荐了一些 Dell 服务器,这些 6U 的大家伙差不多有 90 磅 [7] 一台。数据库服务器和 Web 服务器从逻辑上是独立的。因为我运行了一个 MySQL 进程和一个 Apache进程,所以我只知道这样去分离。
就这样过了一阵子。 Web 服务器直接面向大众,服务器上有两块网卡,通过交叉线缆( crossover cable )连接数据库服务器。后来 Web服务器过载了,但那还比较好对付,那时我有了几台 1U 的服务器。之后我们有了 3 台 Web 服务器和 1 台数据库服务器。这时我先后用了三四个 HTTP 负载均衡器— — mod_bachhand 、 mod_proxy 和 Squid 。这些我一个都不喜欢,我就是从这时开始讨厌 HTTP 负载均衡器的。
接下来过载的就是数据库,那时我抱怨道: “ 哦,见鬼。” Web 服务器可以很好地扩展,它们都是无状态的,只要投入更多的机器,分散负载就可以了。那段时间很难熬, “ 我可以优化查询来应付一下,”但那只能坚持一周,一周后它又会过载。那时我就开始思考一个独立的请求到底需要什么。
那时我认为自己是世界上第一个想到这个方法的人,我们可以切分数据库,将它分区存放。我画了几张图来做设计文档,简单说明我们的代码会是如何工作的。 “ 我们的主数据库只存放全局相关的元数据,这些是低流量的。各个博客和评论相关的东西会分别存放到每个用户的数据库集群里。每个分区都有自己的用户 ID 。”现在看来,每个人都会这么做。但那时候在不间断服务的情况下迁移代码 着实是件很费力的事。
Seibel : 在你迁移时有没有暂停服务?
Fitzpatrick :没有。每个用户都一个标志位,标明他在哪个集群上。如果标志位是 0 ,说明他在主数据库上;如果非零,则说明他已经被分区了。有个版本号是 “ 你的账号正被锁定”。这时该账号处于锁定状态,尝试迁移数据,如果在这时你做了什么变更则需要重试。基本上在我们完成迁移前你在主库上不能进行写操作,迁移完成后声明: “ OK ,现在你的账号可以使用了。”
迁移程序在后台运行了两个月。我们计算过,如果只是把数据导出来,写点程序拆分 SQL 文件随后重新加载,可能要花一周左右。摆在我们面前有两个选择——停机一周或者缓慢迁移两个月。我们先迁 10% 的用户,这时对其他用户而言,整站的可用性提高了,随后我们再慢慢提升迁移到集群的用户比例。
Seibel : 这就是 memcached 和 Perlbal 的前身了吧。
Fitzpatrick :是的,那确实是 Perlbal 的前身。 memcached 是在那之后的事情了。在大学结束离开学校前,我都没想过要做 memcached。站点越来越慢,一天我在浴室里洗澡的时候灵光乍现,突然意识到我们有这么多空闲的内存可以利用。那晚我写了个原型,服务端和客户端都是用 Perl 写的,服务端很快就崩溃了,因为对于一个 Perl 服务器而言 CPU 的使用率太高了。于是我们着手用 C 来重写它。
Seibel : 这样就省去了购买更多数据库服务器的开销了。
Fitzpatrick :是的,数据库服务器又贵,迁移又慢。 Web 服务器非常便宜,把它们加上马上就能见效。如果你买一台新的数据库服务器,差不多要花一周来进行配置和验证:测试磁盘、配置和调优。
Seibel : 这么说来,你所开发的所有这些基础设施,比如 memcached 和 Perlbal ,都是为了响应 LiveJournal 的实际扩展需要?
Fitzpatrick :是的。我们开发这些东西都是因为 LiveJournal 承受不了负载,我们挑灯夜战开发新的基础设施。我们甚至还买过 NetApp[8]。我们问: “ 这要多少钱?”他们回答: “ 说说你们的商业模型。” “ 我们有付费账户。” “ 你们有多少客户?怎么收费?”你就能看到他们在那里做乘法。 “ 价格是你们在不破产的情况下的所有可支配收入。”我们心说: “ 去你的。”但我们确实需要它,所以还是买了一台。我们对它的 I/O 性能并不满意,它不仅很贵,还会形成单点故障。他们试图卖给我们一套高可用配置,我们想: “ 去你的!我们不会再买这种东西了。”
后来我们开始写自己的文件系统。我不确定当时 GFS 的论文是不是发表了,我觉得我应该从谁那里听到过。那时我的内存很分散,取个散列的键,从分区里取值。为什么不能把这招也用在文件上呢?文件是永久性的。因为增加存储节点时配置会发生变化,所以应该记录下文件的实际位置。那用不了多少 I/O ,只需跟踪文件的位置就可以了,但如何保证高可用性呢?我们想出了一个解决方案,我提出一个计划: “ 这是我们确定文件位置所需的全部的读和写。”我先写了主控的 MySQL Schema 和文件位置追踪器。随后,我发现: “ 上帝啊!这部分用 HTTP 就能搞定了。它根本不难!”
我记得在想了整夜之后,我们就投入工作了。我们在公用办公楼下面有个会议室— —一间昏暗的大会议室。 “ 好了,各位,停下你们手头的事情。我们下楼去画图。”每次我有设计思路时差不多都会这么说,我们应该找块白板把它画出来。
我解释了整个设计,谁和谁交互,谁处理请求。然后大家就上楼了,我先预定了所有的硬件,因为差不多要两周左右它们才能到货。然后开始编码,我们希望能在机器到货前完成编码工作。一切总能挑出毛病,总有东西出问题,因此我们总在写新的基础设施组件。
Seibel : 有没有这样的情况,某人在开始时让你坐下,告诉你 “ 你需要知道 X 、 Y 和 Z ”,你的生活会不会更容易些?
Fitzpatrick :从一开始就把事情做好总是比迁移一个线上服务要容易很多。这一直都是最让人头痛的。我所说的每件事,你都能在一台机器上做到。开始时就这么设计,你就不需要假定能把这两个用户数据关联起来或是别的什么了。假设你想加载这 20 条数据——你的实现可以把它们从同一张表里加载上来,但在更高层次的代码里只需要说一句 “ 我想要这 20 个对象”,就能实现从一组机器中收集数据的工作了。如果从一开始我就这么做,可以免去不少迁移的痛苦。
Seibel : 这么说,基本上你学到的就是 “ 要为数据无法容纳进一个数据库的那天做准备”。
Fitzpatrick :我认为这已是 Web 社区中的常识。人们总是假定他们的站点会变得很大,有些想过头了。但在那时,常识却是, Apache 和MySQL 就是你需要的一切。
Seibel : 看起来你写这些组件是因为你需要它们,同时你也乐在其中。
Fitzpatrick :哦,当然!我确实是在找理由去使用各种东西,去学习它们。因为如果不实际用它写点什么,不和它生活在一起,你永远学不到东西。出于兴趣去学一门语言和学会它是两回事,如果不用它写些大的、复杂的系统,那你不能算是真的学会了。
Seibel : 那你觉得对你而言,你和哪些语言生活在一起呢?
Fitzpatrick : Perl 、 C 。以前的话,还有 BASIC ,不过我不确定 BASIC 算不算。我还写过很多 Logo 。在小学的 Logo 课上,大家都在提笔、落笔,而我不在图形模式里——有些键能跳出图形模式,我在写函数。老师会走过来说: “ 你在干什么?你做的不对,你应该在画房子。” “ 不,我在写 Logo 。你看。” “ 不,你弄错了。”在课程结束的时候,我做出了些东西,我写了个类,能以任意尺度和任意方向画出所有字母。有了它,我能在波状横幅上打印整条消息,并加入距离和填充。每个人都很吃惊: “ 这是什么?”我也不知道这个算不算。
现在在用很多的 Perl 和 C ,在大学里还为工作和 Windows 程序写了很多 C++ 。后来我的 C++ 忘得差不多了,或者说是退化了。现在我在 Google ,去年我写了很多 C++ 、 Python 和 Java 。在 Java 刚出来的时候我也写过不少,但后来厌倦了。现在我又开始写 Java ,又开始有些不爽了。
Seibel : 使用何种语言很重要吗?
Fitzpatrick :目前还没找到能让我满意的语言。我还不太清楚究竟什么才能让我完全满意。我讨厌在一个项目里一直切换语言。我想要的语言要在我需要时拥有静态类型,在编译时检查所有内容。 Perl 比较接近这个要求,我能用各种喜欢的方式来写代码。它在编译时没有足够的静态检查,但我可以在运行时对其进行补充。不过 Perl 还是不够好。
我想要可选的静态类型。在 Perlbal 里,除了核心(要复制字节),没理由让半数的东西都有这么高的性能。我希望在特定的部分代码和类型声明时能给运行时一些提示。但如果想使用惰性求值或模拟一些东西时,我可以采用另一种方式。
Seibel : 这么说来,你主要就是希望语言能有静态类型,这样编译器能更好地进行优化?
Fitzpatrick :不是这样的。我还希望在编译时它能告诉我 “ 你正在做傻事。”有时我并不关心编译时的情况,我希望它能在运行时有些强制措施,能做任何事。我并不想对 Perl 6 过于乐观,他们的确在讨论很多我希望看到的东西。但我并不认为它们最终能实现出来。
Seibel : 你喜欢 C++ 吗?
Fitzpatrick :我并不是很喜欢它。 C++ 的语法很糟糕而且并不一致,它的错误消息也很可笑,至少 GCC 的错误消息是那样的,往往会因为漏了一个分号而显示 40 页的错误信息。但和别的东西一样,你很快能记住各种模式,之后甚至不用看那些信息就能知道 “ 哦,我大概忘记在头文件里关闭名字空间了。”我认为新的 C++ 规范,尽管加入了很多复杂性,但还是添加了不少能减少打字痛苦(击键次数)的东西。例如,自动变量和 for 循环,它的风格变得更像 Python 了。还有 lambda 表达式,尽管用的是 C++ ,但这足以让我误以为自己在写 Python了。
Seibel : 你是出于性能目的使用 C++ 的吗?
Fitzpatrick :是的,差不多吧。我在 Google 主要使用 C++ 。各种有性能要求的东西都会用 C++ 来写。我在 Google 还写了不少 Java。
Seibel : 据我所知, Google 有以 C++ 为中心的文化,因为那是 Google 最早使用的语言,而且他们围绕它构建了整套软件基础设施。你不能改变历史,但在 Google 可能有很多 C++ 代码对提升性能而言并不是必需的。
Fitzpatrick :原因是这样的,随着时间的推移, Java 越来越快了, JVM 越来越聪明了。关于 Java ,有件事让我很不爽,那就是每个人都很讨厌 JNI 。有时一个库是用 C++ 写的, Python 开发者(不管 Google 里的还是外面的)并不在乎,他们会说: “ 哦,我们会用 SWIG 包装它。”他们继续自己的工作,做得很开心。 Python 能很快从用 C++ 写的东西中获得支持,因为 Python 开发者并不介意它到底是用什么语言写的。
Java 的人却会说: “ 这必须得是纯 Java 的。我们不用 JNI ,否则若 JVM 崩溃了,我们根本不会知道是为什么。”这个问题最后会导致所有的东西都要写两次,一次为 C++ 、 Python 和所有其他语言,另一次专为 Java 而写。如果他们能讨论出一个好的嵌入方案或者克服对 JNI 的恐惧,那我就没什么好说的了。
[1] 集成电路制造商,成立于 1969 年,在其巅峰时期曾占据全球 85% 的 DRAM 内存芯片市场份额。
[2] Advanced Placement 项目,在美国和加拿大的高中提供大学级别的课程。
[5] cheesesteak ,费城牛肉奶酪三明治,这是费城及其附近地区的食品。用一种细长的意大利面包,里面有切得很薄的肋眼牛肉片加炒过的洋葱及蘑菇,然后淋上融化的奶酪酱,也可加上红椒或者是很辣的小尖椒。(摘自维基百科。)