极客与团队

978-7-115-30844-3
作者: 【美】Brian W. Fitzpatrick Ben Collins-Sussman
译者: 徐旭铭
编辑: 陈冀康
分类: IT人文

图书目录:

详情

本书是一本写给程序员看的,教你怎么交朋友,怎么影响团队中的其他人。书中充满了操作性极强的建议和意见,让你在技术团队中过得更开心,变得更有效率,更加如鱼得水。本书旨在帮助程序员改进理解他人,与人沟通,以及与人合作的能力,进而在编写软件的过程中变得更有效率。

图书摘要

极客与团队

[美] Brian W.Fitzpatrick Ben Collins-Sussman 著

徐旭铭 译

人民邮电出版社

北京

软件开发是一项团队运动,人的因素对结果的影响完全不亚于技术因素。正如本书作者所说的,一个项目成功的关键不仅仅是写出漂亮的代码:团队中的所有人朝着同一个目标一起合作也是同样重要的。

本书是一本写给程序员看的,教你怎么交朋友,怎么影响团队中的其他人。书中充满了操作性极强的建议和意见,让你在技术团队中过得更开心,变得更有效率,更加如鱼得水。本书旨在帮助程序员改进理解他人,与人沟通,以及与人合作的能力,进而在编写软件的过程中变得更有效率。

本书的两位作者来自Google,具有丰富的项目开发和管理经验,还曾经是Subversion的初创成员。本书得到Google研发主管、Google首席互联网专家、Samba的开发者、Django创始人、Python之父等众多业内高端人士和顶级程序员的好评。

本书适合那些想要更上一层楼并编写出色软件的程序员阅读,也适合软件项目和团队的管理者自己或组织团队成员阅读和参考。

尽管封面上只有两个人的名字,但是这本书是我们的整个职业生涯以来和成百上千人交谈后的结晶。因此我们想要在此对本书作出贡献的人们表示一下感谢(书中若有任何谬误,都是我俩造成的)。

感谢奥莱利公司的诸位同仁:封面设计师艾迪·弗里德曼,以及我们大无畏的编辑玛丽·特莱斯勒——没有玛丽的鼓励、耐心和时不时的鞭策,就不可能有这本书。

感谢sunnibrown.com的桑尼·布朗和安博·刘易斯用那么愉悦的方式让整本书变得鲜活起来,与你们合作真是太愉快了。

感谢本书的技术审校,你们贡献了无数的建议、想法,还有修改意见,才使得这本书变得更加完整:达斯汀·伯斯维尔、特拉佛·佛切尔、迈克·亨格、乔纳森·勒布朗、蓝俊彪和杰克·韦尔奇。感谢我们的朋友和同事在写书过程中帮忙发现的很多可笑的错误:戴夫·鲍姆、马特·卡兹、威尔·罗宾逊、和比尔·杜安。感谢听我们唠叨,还耐心给出建议的朋友,你们实在是太棒了:傅凯、吉姆·布兰迪、马特·布雷斯维特、丹尼·伯林和克里斯·德波纳。另外,还要感谢以下这些朋友提供的想法和建议:琳达·斯通、德维特·克林顿、布鲁斯·约翰逊、罗兰德·麦克格雷斯和艾米特·佩特尔。

感谢 Google,特别是 Google 芝加哥的工程师们,感谢你们的支持、想法和建议,只是能和这样一支梦幻团队一起工作就值得令人心怀感激了。

特别感谢我们的老领导和导师:比尔·库格伦、史提夫·温特、阿兰·尤斯德斯、斯图·费尔德曼和埃里克·施密特。我们已经很努力地把从你们那里汲取而来的智慧写到这本书里了。

特别感谢布莱恩·罗宾逊和伊芬·埃里森·桑德拉给我们的悉心指导和照顾。

感谢 Apache 软件基金会接纳我们,也感谢你们对软件社区以及合作所作出的贡献。

感谢所有好朋友,让我们变得更加充实。别那样看着我们——说的就是你。

本书的大部分内容都是在芝加哥(也就是我们居住的城市)的Filter Cafe里构思创作出来的,这是一家舒适宜人的邻家咖啡馆。

傅攀勃的致谢

感谢妻子玛丽的巨大耐心、理解和鼓励——你的洞察力和同情心让我获益良多。感谢我母亲永不停歇的支持和热情。特别感谢我的岳母丽塔·冈穆勒作的那个“人是植物”的比喻。

写给本的话:认识14年,一起换了三次工作,写了三本书,你还没有厌倦我啊?感谢你陪我经历这段疯狂、奇怪但是了不起的旅程——你是我的良师益友。我已经等不及看看我们接下来能折腾出什么东西来了(当然,先让我休息几个月)。

最后,感谢查理·麦克甘农先生在11年级的英语课上那么努力地教我写作。那时候的我觉得为了写一篇文章打四遍草稿是荒唐可笑的事情,现在我才知道自己当年的想法是多么荒唐可笑——好文章真的是改出来的。在此,向“四角和中间写作法”以及牛津英文字典致敬!

本的致谢

语言已经不足以表达我对妻子佛朗西斯的感激之情,她给了我巨大的空间——我不单指在撰写本书的过程中,还有过去几年来我参与的很多其他创作。没有她默默坚定的支持,我将一事无成。

写给傅攀勃的话:看到我们写给对方的寄语后,我要说,我们真像是老夫老妻。我以前从来没有意识到和人一起做演讲是这么有趣的事情,更别提一起编程和写书了。感谢上苍给了我们机会一起经历那么多事情!感谢你教了我这么多。

最后,感谢所有疯狂的硅谷人和企业:要不是你们引我入门,我是绝对体验不到这些疯狂经历的。

作者简介

布莱恩·傅攀勃现在是Google数据解放阵线和透明度工程两个团队的负责人,之前他还领导过Google的项目托管团队以及电子商务伙伴团队。他帮忙建立了Google芝加哥分部,并且为Google在开放数据上提出了很多想法和建议。

本·科林斯-萨斯曼是Subversion的初创成员之一,领导过Google 的项目托管团队,现在是 Google 电子商务伙伴团队的负责人。他帮忙建立了 Google 芝加哥分部,并将 Subversion移植到Google的BigTable平台上。

本书旨在帮助程序员改进理解他人、与人沟通,以及与人合作的能力,进而使其在编写软件的过程中变得更有效率。

“精彩至极,直指人心!哪怕你不觉得自己是极客,它提供的建议也值得一读。”

——文顿·瑟夫,Google首席互联网专家

“我和工程师已经打了三十几年交道了。经验告诉我,人际关系在工作中的重要性并不亚于科学技术,但很多工程师都不愿意尝试了解如何与人合作。如果你想要更有效地进行创新,那绝不能错过本书。”

——狄恩·卡门,DEKA研发公司创始人

“作者为软件开发团队搜集了一套令人惊艳的模式和反模式。无论你是开发人员本身还是经理,或是任何有一点关系的人,只要你觉得自己难以理解为什么这些东西能让团队更有活力,你就应该读一读这本书。它道出了很多出色的开源项目程序员与生俱来的特质。我当初要是有这么一本书就好了。”

——布莱恩·贝伦多夫,世界经济论坛CTO

“软件开发是一项团队运动。如果你想要扬名立万,市面上有无数本教你如何磨练技术水平的好书,教你当好经理的书也不少。但这本书却另辟蹊径,教你应该如何与团队合作,以及如何当好合作伙伴。这个领域早就需要这样一本书了。”

——彼得·诺维格,Google研发主管

“如果你想要组建一支能专注开发优秀软件的团队,那绝不可错过本书。作者将谦虚、尊重和信任等感性的话题漂亮地转变成极富技巧的建议,哪怕是最挑剔的工程师也会欣然接受的。”

——埃里克·伦特,BrightTag 联合创始人兼CTO

“这本书太精彩了。它探讨的是计算机编程里最难的问题,怎样和其他程序员打交道。我打算让Samba团队人手一本。”

——杰瑞米·埃里森,Samba作者之一

“你可能已经听过所谓的‘十倍程序员’传说了吧,它的意思是顶尖程序员的生产力比普通程序员要高一个数量级。但巨大的影响力不仅来自经验和技术,更少不了来自同事和用户的共鸣感,而且无论多少聪明才智都弥补不了后者的缺失。好在这本书可以帮你磨练这项软技能,以期给世界留下更深的烙印。”

——鲍勃·李,Square支付CTO

“作者设定了一个基本的信条——谦虚、尊重和信任——并围绕它们提供了大量的情景案例。这些宝贵的经验和智慧能够帮助绝大多数需要团队合作的工程师(也就是我们)变得更有效率。”

——格雷格·巴罗斯,Facebook产品工程部副总裁

“软件是由人创造出来的。只要能运用本书中所列出的准则,这样的团队无论是在思路、代码品质上,还是在产品发布方面,都可以完胜任何单打独斗的黑客。程序员们,好好学吧!”

——乔纳森·南丁格尔,Mozilla Firefox工程部高级主管

“本书是写给程序员看的,一本教你怎么交朋友、怎么影响他人的书。书中充满了操作性极强的建议和意见,让你在技术团队中过得更开心,变得更有效率,更加如鱼得水。”

——艾德利安·霍罗瓦第,Django创始人之一

“作者说出了我一直在做但是总结不出来的东西。”

——吉多·范·罗苏姆,Python之父

“请把本书送至:

保罗-海宁·坎普

FreeBSD核心团队

必须在1994年3月之前送达。”

——保罗-海宁·坎普,FreeBSD项目程序员

“作者无意为孤独的程序员唱赞歌,相反他们决心要亲手埋葬这个传说。他们撰写了一系列文章来指导那些靠谱的程序员如何对付他们这辈子最复杂的难题:怎么处理好和团队的关系。本书说明了为什么最有人情味的软件往往都是最会合作的人创造出来的,而且它还教你如何同时做到这两点。”

——约翰·托尔瓦,芝加哥市政府CTO

“这是一本有关软件开发社会学的出色著作,它同时照顾到了开源项目和大公司的需求。对所有新踏入职场的工程师来说,有关管理和应对办公室政治的那个部分绝对是必读的。我的建议是不管你是什么背景的工程师都应该读一读这一章!这是我见过的第一本写给工程师看的、专门有讲到办公室政治的读物,而且可读性非常强。在‘怎么和难以相处的人一起工作’里分享的奇闻异事和实用小贴士都是金玉良言!千金难买哦。”

——蓝俊彪,ArEngineeg’s Guide to Silicon Vauer Startups和St artup Engineering Managerrerg作者

“本书绝对是书中瑰宝,作者分享的理念能让程序员们更好地为团队作出贡献。我们终于有幸可以开诚布公地探讨这个领域的话题,而且还是以这么平和幽默的方式。要是在21岁的时候有这样一本书让我研读领会就好了。”

——布莱恩·奥沙利文,Facebook

“这本书为建立健康的软件开发文化提供了基本的蓝图。它应该成为工程经理和技术领导的必读书目,甚至那些想要了解团队动力学是如何留住顶级人才以及影响软件质量的非技术主管也不应该错过本书。”

——布鲁斯·约翰逊,Google工程主管

“编程技术能让你混口饭吃,但要是能把它和与人合作的能力结合起来,你就可以改变世界。这本书教你的并不仅仅是当一个更好的程序员,它还要你当个了不起的程序员。”

——克雷·约翰逊,The Information Diet作者

“本书就如何构建成功团队和产品的话题进行了极富洞察力的探索,探讨的是多年来我们程序员在职业生涯里都经历过的痛苦和挣扎。这种轻松愉快的办法不但能同时解决技术团队里的技术问题和人际关系问题,更以一种有趣的方式转化成文字,实在是所有程序员书架上必不可少的书目。”

——乔纳森·勒布朗,X.Commerce首席工程师

“编程现在涉及的已经不仅仅是代码和机器了,它更像是把已有的组件按照新的方式拼装在一起——而这些组件背后的作者都是活生生的人。本书的作者对此了然于胸,无论给出什么样的建议,他们要传达的信息都是非常简单直观的:只要像在代码上那样在人际关系上狠下功夫,你不但可以变成更快乐的程序员,更可以让其他程序员也变得快乐起来。这本书来的正是时候!”

——傅凯,Open Tech Strategies LLC联合创始人

“很少有人会谈及和极客合作时该怎么处理好人际关系这方面的东西,所以多年来我一直通过博客记录本和傅攀勃在各种大会上的演讲。现在我很高兴能方便地在一本书里就读到他们所有演讲里的精华,而不用再追着他们满世界跑了。”

——罗伯特·凯,MusicBrainz首席极客

 

“工程问题都很简单。人际关系才是最难的。”

——比尔·库格伦,前Google工程部资深副总裁

生活中总是充满了离奇的转折,就好像我们俩从没想过会合作写一本软件工程的书一样。

和大多数电脑狂一样,大学毕业后我们发现自己的兴趣和热情(折腾电脑)居然也是不错的谋生手段。而和那个时代的大多数黑客一样,我们的整个20世纪90年代中期都是在干这些事情,用别人剩下的零件攒机,拿着一大叠软盘安装预览版的 Linux,然后学着操纵 UNIX 机器。我们都是系统管理员出身,然后在互联网泡沫刚起来的时候跑到小公司里去当程序员。泡沫破裂后,我们开始为那些幸存的硅谷企业(比如 Apple)工作,后来又跳槽去了一家创业公司(CollabNet),全心设计开发了一款开源版本控制软件Subversion。

然而2000年到2005年期间,一些意想不到的事情发生了。尽管我们创造了 Subversion,但是我们每天的任务却渐渐发生了变化。我们不再只是天天坐在那里写代码,而是开始领导一个开源项目了。这意味着我们要整天挂在聊天室和一堆程序员志愿者打交道,关注他们都在做些什么。这还意味着要几乎完全通过邮件列表来协调各种新特性。我们逐渐发现一个项目成功的关键不仅仅是写出漂亮的代码:所有人向着同一个目标一起合作也是同样重要的。

2005 年的时候我们一起创建了 Google 芝加哥分部,以程序员的身份继续着我们的职业生涯。这时我们已经完全融入开源世界了——不仅仅是Subversion,还有Apache软件基金会(ASF)。我们把 Subversion移植到 Google的 BigTable架构上,并以Google Code为名发布了一项开源项目托管的服务(类似于 SourceForge)。我们开始参加(后来开始做演讲)各种开发者大会,例如OSCON、ApacheCon、PyCon,还有Google I/O。我们发现同时为企业和开源项目工作的经历让我们无意之间了解到了软件工程团队运作的奥秘。一开始我们做的演讲都是轻松幽默的,大多是批判无用的开发流程(“Subversion最差实践”),后来则开始转向探讨如何保护团队不受害群之马的影响(“开源项目如何应付害群之马”)。越来越多的听众聚集到我们的演讲会场,我们称之为程序员的“集体疗法”。每个人都对我们谈论的问题有着切肤之痛,都想要对大家抱怨一下。

于是,六年来我们做了一大堆反响热烈的和软件开发过程中人际关系有关的演讲。最后奥莱利公司的编辑玛丽·特莱斯勒建议我们干脆把这些演讲写成一本新书。接下来发生的事情就略过不表了。

想要编写出色的软件?这本书就是为你写的

本书的读者

本书是专门写给那些想要更上一层楼以及编写出色软件的程序员看的。CEO、心理学家、管理层\计算机理论学家,还有焊电路板的技师等都不算是我们的目标读者(虽然这些朋友或许也能读得津津有味)。在此我们假设本书的读者具备以下两个重要条件。

• 你需要和团队里的其他程序员合作。无论是为公司企业工作,或是某个开源项目或是学校作业的一员都可以。

• 你喜欢软件工程,并且觉得它应该是一件很有成就感、很好玩的事情。如果你只是应付工作混口饭吃的话,那估计你对实现自我价值和获得职业满足感不会有什么兴趣。

在讨论程序员怎么才能“通力合作”的时候,我们总结出了一些表面上看起来和程序员这份工作风马牛不相及的经验和准则。我们会在各章里谈到怎么才能更好地领导一支团队和企业,怎么才能和用户建立起良性的关系等话题。乍看起来这些章好像是专门写给所谓的“管人的人”或者说“产品经理”看的,但我们可以保证,你的职业生涯到了某个阶段的时候一定会有意无意地担当起这样的角色。所以先放下疑虑,继续往下读吧!这本书里讲到的东西是每个软件工程师最终都会碰到的。

警告:本书不是技术手册

首先我们需要澄清一些事情。好学的程序员通常都喜欢去读一些能将某些个特定问题用纯数学的形式展现出来的书籍,而通常这样的问题都存在完美的流程化的答案。

本书并不属于这种类型。

本书主要关注的是软件开发中有关人的那个方面,而人是很复杂的。正如在我们自己的演讲中说到的那样,“人基本上就是由一大堆间歇性bug组成的”。这里论及的问题和答案都是很凌乱的,很难用完美逻辑来解释。本书读起来像是论文集,而事实上它的确也就是一本论文集。每一章我们都会讨论一系列相关的问题(通常是用案例故事的方式),然后针对整个主题再探讨各种应对方案。你可能需要反复阅读很多页,努力把它们联系起来,甚至思考数日才能融会贯通!

我们在此还要作一些声明。正如我们在演讲里开过的玩笑,“这里的观点完全是基于我们自己的经验得出的,完全属于我们自己。要是你不同意我们的观点,完全可以去自己做演讲啊”。和我们的现场演讲一样,只要和本书主题相关,任何讨论都是值得鼓励的。我们欢迎各种反馈、修正、新观点,以及反驳:你可以在http://www.benandfitz.com/上找到我们。本书的所有内容都来自我们的亲身经历和无数错误中得到的教训。

你还应该注意,我们在例子中提到的都是化名,以保护无辜(或者犯错)的当事人。

本书的内容都是课本里学不到的

我们认识的软件工程师绝大多数都花了4~10年的时间在学校里学习计算机科学和软件工程。截至本书出版为止,我们不知道有任何一门课程1是真正教你怎么在团队和公司里与人合作交流的。好吧,大多数学生都会在学校里被要求参与某个项目,但是教一个人怎么好好地和另一个人协作与把他直接丢到一个迫使他协作的环境里完全是两码事。绝大多数学生最后都不怎么喜欢这种经验。

小结

所谓成功的程序员不仅仅是追逐最新的语言或是编写最快的代码。职业程序员几乎都是要参与团队合作的,而且事实上团队直接影响个人生产力和幸福感的程度超出很多人的想象。

本书的目标很简单:编写软件是集体项目,而且我们认为人的因素对结果的影响不亚于技术因素。大多数人虽然在编程技术上耕耘数载,但是在人际关系上却从来没有下过功夫,而学习与人合作也是成功路上不可或缺的重要环节。只要你能在软件工程的“软技能”上下点功夫,就能达到事半功倍的效果。

注释:1 我们读过汤姆·迪马克的《人件》,的确是一本好书,但它并不是一本专门教工程师怎么与人高效合作的著作,而是一本教管理人员怎么带领团队成功的著作。

既然本书讨论的是软件开发里危险的人际关系,那么把注意力放在有绝对控制权的因素上是显而易见的选择,这个不定因素就是:你自己。

没有人是完美的,但是在给同事挑错之前,你得先知道自己的毛病。我们希望你想想自己的反应、行为和态度——或许你可以从中得到一些心得体会,从而变成一名更成功、更高效的软件工程师。在处理人际关系的问题上花的精力越少,你就有越多的时间编写漂亮的代码。

本章的主旨是要理解软件开发是集体项目(这一实际)。要在团队里获得成功,你必须以谦虚、尊重和信任为核心原则。

不过在此之前,我们先来观察一下程序员的日常行为吧。

过去6年来我们俩一直在各种编程大会上做演讲。由于我们是2006年发布Google开源项目托管服务的小组成员,所以我们收到了很多关于这个产品的问题和请求。到了2008年中的时候,我们注意到这些请求里出现了很明显的趋势。

? 能让Google Code上的Subversion隐藏某个分支么?

? 能不能实现这样的功能:先把新建项目隐藏起来,等到准备妥当的时候再公开发布?

? 我想推倒重来,能不能删掉整个历史记录呢?

你能看出这些请求之间的共同之处么?

这里的要害就是缺乏安全感。人们不喜欢自己做到一半的事情被别人指手画脚。从某种意义上来讲,这是人的本性——没人喜欢被批评,特别是还没完成的工作。这种态度透露出软件开发的某种趋势。缺乏安全感其实意味着背后可能隐藏着更严重的问题。

首先我们要澄清一件事情:我们实际上不是体育迷。每次我们的太太们在电视机前为了篮球或者足球比赛欢呼雀跃的时候,我们总会挠挠头皮觉得这有什么好激动的。但不管怎么说,我们毕竟是见证了20世纪90年代初芝加哥公牛队的辉煌(顺便说一句,这是一支篮球队)。我们当时都住在芝加哥,全国媒体在这里聚集了好多年,来报道这支传奇球队。

那么我们在电视和报纸里听到最多的是什么?不是球队本身,而是迈克尔·乔丹,球队的超级巨星。全世界的球员都想成为乔丹那样的明星。我们可以看到他在其他球员周围跳舞转圈圈,在电视广告里也能看到他。他演了一部很傻的电影,在其中他和一群卡通人物一起打球。他是大明星,每个小孩子都会在球场里偷偷练习打篮球,希望将来有一天也能像他一样。

程序员其实也一样,我们也会有自己崇拜的偶像。莱纳斯·托瓦兹、理查德·斯托曼、比尔·盖茨——这些改变了世界的英雄都作出了了不起的贡献。毕竟莱纳斯靠自己就写出了Linux不是吗?

要小心自己本能地去崇拜事物

其实莱纳斯只是写了一个可以工作的类UNIX内核的初级版本,然后把它贴到了邮件列表上而已。这并不是一项简单的任务,而且它也的确是一项了不起的成就,但是这真的只是冰山一角而已。Linux 的规模是这个的几百倍,有几百名聪明绝顶的程序员参与了开发。莱纳斯真正的成就是领导并协调他们的工作,Linux 之所以如此耀眼完全是这些人通力合作的结果(另外,UNIX 也是由贝尔实验室里的一小群天才写出来的,并不完全是肯·汤姆森和丹尼斯·里奇的功劳。)

同样的,自由软件基金会的软件都是由斯托曼编写的吗?他编写了第一版Emacs,而bash、GCC,以及所有其他运行在Linux上的软件都是由几百名程序员负责的。史提夫·乔布斯领导的团队开发了麦金塔电脑,还有比尔·盖茨,尽管他为早期的家用电脑编写了 BASIC 解释器,但其实他更大的贡献是围绕MS-DOS创办了一家成功的软件公司。可是这些集体荣誉都被算在了他们这些领袖的头上。

那么迈克尔·乔丹呢?

我们还是一样崇拜他,但事实上他是不可能靠自己一个人就赢得每一场篮球赛的,他真正天才的地方是他和球队一起打球的方式。球队教练菲尔·杰克逊是非常聪明的一个人——他的教练水平是毋庸置疑的:他知道单靠一名球员是无法赢得冠军的,所以他围绕乔丹打造了一支“梦之队”。这支队伍干劲十足,耀眼程度完全不亚于乔丹。

既然如此,我们为什么还是不断地去崇拜这些故事里的主角呢?人们为什么为明星代言的产品掏钱?为什么我们会想要去买米歇尔·奥巴马1的裙子和迈克尔·乔丹的球鞋?

明星的号召力是很大的。人类会本能地去寻找领导者和榜样,崇拜他们,然后模仿。我们都需要榜样的激励,编程世界也不例外,“技术英雄”的现象几乎都要被神化了。我们都想要写出像Linux那样改变世界的东西,或是设计一门了不起的程序语言。

从内心深处来讲我们都默默地希望自己是天才。极客的终极梦想就是得到一个激动人心的灵感,然后闭关数周甚至数月将它完美地实现出来,最后向全世界发布自己的作品,名动天下。同行们会折服于你的聪明才智,人们会排着队来买你的软件,名望和财富更是唾手可得。

不好意思先等一下:醒醒吧,你很可能不是什么天才。

当然我们并无恶意,你肯定是一个很聪明的人,但是你知道这个世界有多少真正的天才吗?的确,你能写代码,拥有这种能力已经算是人群里的聪明人了,但问题在于即便你真的是天才也是不够的。天才也会犯错,好点子和高超的技术并不是软件成功的充分条件,你的职业生涯能否成功完全要看你能不能与人合作。

事实上所谓的天才传说只是我们缺乏安全感的一种表象罢了。很多程序员都害怕和别人分享他刚刚开始做的东西,因为这意味着同行会看到他们的错误,从而知道这些代码背后的作者并非天才。这里引用本的博客上某位程序员的留言:

“如果别人看到我未完成的作品,我会非常忐忑,觉得他们会因此对我产生质疑,把我当成一个傻瓜。”

这是程序员这个人群里很普遍的看法,所以最自然的反应就是躲起来不断地努力工作。只要没人看到你犯错,你就还有机会最终一鸣惊人。所以产品完善之前还是先藏拙吧。

不愿献丑的另一个原因是害怕别的程序员会偷走你的创意,然后抢先发布。所以只要保持低调,创意就不会被偷走了。

我们知道你现在可能会想:那又怎么样?难道我们不能按照自己的方式工作吗?

事实上还真的不能。我们可以断定你这样做是不对的,而且错得离谱。让我们来告诉你为什么。

假如你一直都是单打独斗的话,你其实是增加了自己失败的风险,而且浪费了自己成长的可能性。

首先,你怎么知道自己选的路是对的?

假设你是一名狂热的自行车设计师,有一天你想到了一个绝妙的主意,设计出一个具有颠覆性的换挡装置。你订购了零件,然后在车库里泡了好几个星期来制作原型。当你的邻居(他也是自行车爱好者)问你最近在忙什么的时候,你想还是先保密好了。在这个设计完善之前,你不想任何人知道它的存在。几个月以后,你遇到了瓶颈,没有办法令原型正常工作,但由于这个项目是保密的,所以也没办法向你的机械师朋友们寻求帮助。

直到有一天,你的邻居从他的车库里推出一辆自行车,上面有一个全新设计的换挡装置。其实他也一直在建造一个和你的设计类似的东西,只不过他有自行车行的朋友帮他的忙。这时你一定非常窝火吧。你把自己的东西拿给他看,他立刻就指出了你在设计上存在的缺陷——要是你早点拿出来的话,搞不好这些缺陷在一开始就修复了。

单打独斗的结果往往令人失望

这里我们可以得到好几个教训。真正做出产品之前不愿分享好创意实际上是一场很大的赌博,你很容易在一开始就犯下很基本的错误,你有可能是在重新发明轮子2。还有你完全丧失了合作的好处。注意到你的邻居和别人合作后进展有多快了吗?这正是为什么人们在跳进泳池前会拿脚趾试试水的原因:你需要确定自己在做的事情是对的,方法也是对的,而且不是重复劳动。一开始就踏错步的概率总是很高的,越早征求意见和反馈,就越能把风险降低3。记住这句久经考验的原则——“确保失败尽早发生,尽快发生,经常发生”——我们会在本书稍后详细讨论失败的重要性。

尽早分享不仅仅可以防止一开始就步入歧途和检验创意,它还可以强化所谓的“公车因子”。

公车因子(名词):一个项目里,需要有多少人被公车撞到才能令其完全瘫痪。

你的团队的公车因子是多少

你的项目里知识的分散程度是多少?假如只有你一个人理解原型代码是怎么工作的,那么或许对你的职位的安全程度来说是很高,但要是你被车撞了的话,对项目本身来说就是灭顶之灾了。但如果有一个朋友和你合作的话,公车因子就可以翻倍。要是有一个小组一起设计制作原型的话就更好了——项目不会因为某位成员的消失而完蛋。记住:这里只是比喻,并非真的是被车撞,而是指任何生活中都会发生的意外情况,比如结婚、搬家、离职或是照顾生病的家人等。你若想要确保项目有一个光明的前景,就一定要把公车因子纳入考量。

除了公车因子之外,还有整体进展的速度。人们往往会忘记单独工作通常都是很艰辛的,进展有时会慢得令人难以接受。独自工作能让你学到多少东西?你的进展如何?网络虽然是观点和信息的大熔炉,但是它是替代不了人与人之间真正的交流的。直接和别人一起工作能潜移默化地提升集体智慧。每次遇到事后觉得可笑的障碍时,你浪费了多少时间才走出死胡同?想想如果有同事在旁边帮你一把的话会有什么不同——他们会立刻指出你哪里弄错了,该怎么解决它。这就是软件公司里团队通常都是坐在一起(或是在一起结对编程)的原因:你需要一位旁观者。

再打一个比方。想想你是怎么用编译器的。当你编译一个有一定规模的软件的时候,你会花好几天甚至好几个星期坐在那里写代码,然后在全部写完确保一切完美后才第一次进行编译么?肯定不会啦。你能想象一口气编译50 000行代码会有什么后果么?程序员是最需要不断反馈的:写一个新函数,编译,加了一个测试用例,再编译一下,又重构了一部分代码,再编译一下。这样就能在生成代码的时候尽快地改正笔误和 bug。我们的每一步都离不开编译器,好像僚机一样。有些开发环境甚至能在我们打字的同时进行编译。正是依靠这种方式我们才能保持高质量的代码并确保软件在正确的轨道上演化。

这种快速反馈不仅在代码层面,对整个项目来说也是必不可少的。有抱负的项目都必须快速演化并不断适应环境的变化。项目可能会遇到意料之外的设计瓶颈,或者行政上的阻力,又或者只是发现事与愿违。需求总是在往意想不到的方向变化。你要如何通过反馈来发现自己的计划和设计中需要修改的地方?答案是:团队合作。埃里克·雷蒙说过,“只要有足够多双眼睛,就能发现所有的bug,”而更好的说法是,“足够多双眼睛可以确保你的项目保持正确的方向。”闭门造车的结果往往是当实现最初的创意后,却发现世界已经完全改变,原本的产品已经失去意义了。

工程师和办公室

20 年前的传统看法是工程师需要自己独立的办公室,关上门安静工作才会有生产力。这样才能保证他有大把不受干扰的时间可以专心编程。

而我们却认为把绝大多数工程师4关在独立办公室里不但毫无必要而且还很危险。今时今日,软件业已经不是个人英雄的行业了,它需要团队的合作,保持沟通渠道的通畅甚至比随时在线的网络连接更重要。虽然得到了不受干扰的环境,但如果方向错了,那也只是在浪费时间罢了。走进任何一家21世纪以来创建的、快速成长的高科技公司,你会发现工程师都是围坐在共享的小格间(也叫“牛棚”)里,或是共用一张桌子,很少见到各自把自己锁在办公室里的情况。

当然啦,你还是需要找到办法来过滤杂音和干扰的,我们发现很多团队因此发展出一套自己的沟通技巧来表达自己现在很忙,有事等会再说。以前和我们合作过的一支团队就有这样一套语音中断协议:假如你有事找玛丽谈,你要说,“breakpoint 玛丽”。如果玛丽正好有空档可以停下来,她就会转过来和你谈。要是她正在忙,她会说“ack”表示知道了,然后你就先去忙其他事情吧,她那边忙完了就会来找你。

有些团队会给工程师发降噪耳机来解决背景噪音的问题——事实上在很多公司里,带着耳机实际上就表示“不是重要的事情就别烦我”。另外一些团队则会用在显示器上放置记号和玩具的办法来表示自己不愿被打扰。

请别误解我们——我们完全认同工程师应该有不受干扰的时间来全情投入编码之中,但是我们认为他们更需要团队之间高效通畅的沟通渠道。

因此用一句话来总结就是:本质上,单打独斗比合作风险更高。相比担心自己的创意被偷走或是被人笑话,你更应该担心自己是不是在错误的方向上浪费了大量时间。

令人遗憾的是,这种“创意要保密”的想法并非软件行业独有的,所有领域都普遍存在这个问题。就拿学术界来说,科学原本应该是自由开放、信息共享的。但是“不发表即灭亡”的迫切需求,以及对基金拨款的竞争却造成了反效果。学者们不再乐于分享。他们小心翼翼地保护着自己的想法,秘密地进行研究,把犯过的错误都掩盖起来,使最终发表的论文看起来似乎得来全不费功夫一般。其结果往往都是灾难性的:要么不小心重复了前人的工作,要么在一开始就不知不觉犯下了错误,最糟糕的是创造了一些原本有趣,但现在完全过时无用的东西。其中浪费的时间和精力都是无法估量的。

别再把自己变成上述统计结果的一部分。

现在我们来小结一下。

我们到目前为止一直在打磨的观点就是,在编程领域里,真正的独行侠是很罕见的——就算他们真的存在,他们的非凡成就也不是凭空而来的。这些改变世界的成就几乎都是集体智慧努力得来的结晶。

因此建立一支全明星团队才是真正的目标,不过想达成这个目标,难度高得惊人。最好的团队能充分利用好队里的巨星是没错,但是集体的力量一定是大于个体力量之和的。

用一句话来说就是:软件开发是集体项目。

乍看之下这个理念很难让人接受,毕竟这和我们心里的天才程序员幻想是相抵触的,所以先记下来再慢慢理解吧。

记住,软件开发是集体项目

一个人躲在自己小黑屋里抖聪明是没用的。光靠自己神神秘秘地搞创造发明是不可能改变世界,令千百万用户受益的。你需要合作,告诉别人你的想法,让别人帮你分担劳力,向别人学习,进而打造一支出色的团队。

现在来做个实验:你能想出几个应用广泛的成功软件是真正由一个人完成的?(有些人可能会提到“LaTeX”,但很 难说它是一款“应用广泛”的软件,除非你觉得那些写学术论文的人在所有电脑用户里占有相当大的比例!)

我们会在这本书里不断地重复这个集体项目的概念。高效的团队才是通向成功的关键所在,你应该尽可能地以此为目标,这同样也是本书的使命。

到这里我们对于团队的观点已经立论了。既然团队合作才是开发成功软件的捷径,那么如何才能打造出(或者找到)这样优秀的队伍呢?

答案是很难。要达到合作无间的境界,你首先要学习理解所谓的社交技巧“三支柱”。这三项原则不但是人际关系中的润滑剂,更是所有良性互动与合作的基本。

谦虚

没有人是宇宙中心。谁也不是万能的,谁都会犯错。你必须不断地提高自己。

尊重

你必须真心实意地关心同事。他们都是活生生的人,他们的能力和成绩都需要得到肯定。

信任

要相信别人的能力和判断力,在适当的时候懂得放权5

我们把这些原则简称为HRT。发音 是“heart”而不是“hurt”,因为它是要减轻痛苦而是不是伤害别人。事实上我们的论文就是直接基于这些原则的:

基本上所有的社交摩擦最终都是由于缺乏谦虚、尊重,或是信任而造成的。

乍听之下似乎有点难以置信,但请姑且相信我们。你不妨仔细回想一下生活中遇到过的各种令人难受的社交场景。先不说别的,当时大家是不是都有保持有礼有节?是不是真的有尊重对方?是不是有相互信任?

我们相信这些原则至关重要,本书正是围绕它们而展开的。

本书是以你为起点的:让你了解HRT,并真正理解消化以HRT为交际核心的意义。这就是第一章的内容。然后我们能不断地扩大影响的范围。

第二章讨论的是在三支柱之上打造团队的挑战。建立团队文化是走向成功的必由之路——这就是之前说到的“梦之队”。

然后我们会讨论那些每天会和团队打交道,但是却不属于核心团队文化的人。他们可以是其他团队的同事,或是项目的志愿者。他们中的很大一部分人不但完全无视H RT ,更有甚者,完全就是老鼠屎!学习如何抵御这种人对团队的伤害是你的首要任务。不过你的终极目标应该是拔掉他们的爪牙,让他们融入到你的团队文化中来。这是扩充队伍的最佳方式之一。

拥抱HRT才能合作无间

大多数团队都隶属于更大的公司,这种环境常常和害群之马具有同等危害。你的产品能否顺利发布亦或是最终面临被取消的命运,完全取决于你能不能学会如何避开各种行政障碍。

最后,你的用户也是需要考虑的。我们往往会忘记他们的存在,但就是他们决定了产品的寿命。没人用的软件是没有存在价值的。对团队至关重要的HRT原则同样(也应该)适用于你对用户的态度,你能从中获得的好处是不可言喻的。

说到这儿,让我们先暂停一下。

当你翻开这本书的时候,你大概从没想过要参加什么每周互助小组吧?对此我们表示同情。社交的确是个棘手的难题。人类是混乱复杂的生物,完全无法预料,有些人会让人觉得不愿与之打交道。与其耗费那么多精力去分析各种社交场景,步步为营,还不如干脆完全放弃努力。行为完全可以预判的编译器岂不是容易对付得多?干嘛要跟那些社交的麻烦较劲呢?

这里引用一段理查德·海明的著名演讲6

我花了很多时间给我的秘书们讲笑话,和他们搞好关系,这也让我从他们那里得到了许多好处。比如有一次,不知道什么缘故,梅山7所有的复印机都坏掉了。别问我为什么,反正就是坏掉了。而我正好要复印一些文件。于是我的秘书给霍姆德尔的朋友打了个电话,跳上公司的车,开了一整个小时去帮我复印,然后再开车回来。这就是我花了那么多功夫讲笑话逗她开心,表示友善得来的回报。真可谓投之桃李,报之琼瑶。也就是说,通过使用系统并研究如何让系统帮你做事,你就学会了调整系统,让它按照你的意愿工作。

这个故事告诉我们:不要低估社交的力量。社交不是勾心斗角,或是操纵别人,它是通过建立起人与人之间的关系来把事情做成功,而且这种关系延续的时间肯定比项目本身更长。

说了那么多谦虚、尊敬、信任的东西,听起来都像是纸上谈兵。既然这样,我们现在来看看它们和现实是怎么联系起来的。既然我们追求的是实际可操作的建议,所以下面会给出一系列特定的场景实例。其中很多看起来似乎都是显而易见的,可一旦开始仔细思考,你就会发现自己(和同僚们)犯错的频率有多高了。

放下自负

好吧,说得更直白一点,就是让某些缺乏谦逊的人收敛一点儿。没人喜欢和总是以自我为中心的人合作。哪怕你真的是会议室里最聪明的那个,你也没必要到处炫耀。例如,你是不是总是觉得自己对于每个话题都要抢先发表意见,或是要作总结性发言?你是不是觉得自己需要在一项议案或是讨论中对每个细节发表评论?或是你总是要知道谁在干什么?

注意,“表现得谦逊一点”和人见人踩的懦弱完全不是一回事:自信并没有错。只是不要过了头,非要弄得自己好像无所不知一样。其实更好的思路是想办法促成“集体”荣誉感。不要去担心你的个人形象是不是高大,而应努力去营造一种团队和集体荣誉感。Apache软件基金会在围绕软件项目经营社区上已经有很长的历史了。这些社区对自己都有很强的认同感,根本不欢迎对那些只关心自己往上爬的人。

自负这个东西有很多种解释,就看你怎么理解,但很多时候它都会妨碍你的工作,让你进步缓慢。这里从海明的演讲里再摘取一段小故事来证明我们的观点:

“约翰·图基几乎总是不修边幅的模样。每次他参加重要会议的时候,对方总是要好一会儿才反应过来原来这是位大人物,应该认真听他说。有好长一段时间约翰都要面对这种麻烦。这实在是太浪费时间了!我不是说你应该屈服,我说的是,‘作出妥协的样子能给你带来很多好处’。如果非要由着自己的性子来,‘我就是我行我素的人’,那么你就在整个职业生涯里不断地付出一些不大但是很讨厌的代价。日积月累就会变成原本没必要的大麻烦。……通过使用系统并研究如何让系统帮你做事,你就学会了调整系统,让它按照你的意愿工作。不然的话,你就得终其一生去和这种潜规则作斗争。”

学会批评和接受批评

乔是一名程序员,他最近找到了一份新工作。在上了一星期的班以后,他开始深入地学习了解团队的代码。出于责任心,他开始以温和的方式对同事的代码提出疑问。他通过E-mail的方式发出代码审查,礼貌地询问设计初衷或是指出逻辑上可以改进的地方。两个星期后他被叫到了主管办公室。“出什么事了?”乔问道,“我是不是什么地方做错了?”主管看起来不太高兴:“乔,最近有很多人投诉你,说你对同事太苛刻了,把他们说得左也不是右也不是。大家都很不爽,你最好低调一点。”乔因此大受打击。若是在一个完全以H RT为基础的环境里,乔的代码审查应该是可以被接受的,同事们也会认同这种做法。但是在这个例子里,乔就应该对团队里弥漫的不安全感多加小心,在引入代码审查的时候应该更谨慎一点。

在职业程序员这个行当里,人身攻击是相当罕见的——批评通常都是为了产品好。其中的诀窍就是要确保你(和你周围的人)认识到对某人的创造性工作提出建设性批评和人身攻击之间的区别。后者是毫无意义的——这种攻击不但显得小气,而且几乎不可能有什么建设性。而前者通常都是有益的,对改进具备指导性。最重要的是,它蕴含着对对方的尊重:只有真正关心对方的人才会提出建设性意见,希望对方在自身或是工作上有所进步。所以学着尊重对方,礼貌地给出建设性批评吧。如果你真的尊重一个人,那你就会自发地选择有技巧有帮助的措辞——这种技巧需要很多练习才能学会。

作为谈话的另一方,你也应该学会接受批评。这不是说你在技术上要谦虚,而是说你要信任对方,相信他是从心底为你好(当然还有你的项目),完全没有把你当傻瓜的念头。编程和所有技能一样,都需要熟能生巧。如果你的同事提出的做法比你现在的好,你会把它当成是对你的性格或是人生价值观的攻击吗?我们真心希望你不会。同样,你的自尊和你的代码不应该有什么联系。换句话说,你和你写的代码是两回事。你应该不断地告诫自己,你和你写的代码是两回事。不但你自己要相信这个观点,还要让你的同事也认同它。

别把你的自尊和你的代码等同起来

举个例子,假如你有一个比较敏感的同事,那么下面这样的话是万万不能说的:“老兄,你完全把这个方法的控制流程给弄错啦。你应该和大家一样用标准的xyzzy代码模式才对。”这段话全是反模式的东西:首先你告诉他,他“错了”(好像这个世界非黑即白一样),然后要求他作出修改,最后还指责他写的东西和所有人都不一样(让他觉得自己很傻)。可以预见,这样会让对方变得很抵触,得到的回应也肯定是没有什么理智的成分。

好一点的版本可以是这样“:嗨~我有点看不懂这段代码的控制流程。要是用xyzzy代码模式的话会不会更清楚一点?维护起来也方便?”注意这里,你谦虚地把问题归到自己头上,而不是他。他没有错,只是你理解代码有困难而已。另外提出的建议也只是提供了一种方法让可怜的你能理解代码,或许还能在项目长期维护上有所助益。你也没有提出任何要求——你的同事完全可以谢绝这个建议。讨论的范围被限定在代码上,没有涉及任何人的价值观或是编程技术。

快速失败;学习;迭代

商业界里有一个著名的(也是说烂了的)段子,说是曾经有一个经理因为犯下大错损失了上千万美金。第二天他非常沮丧地回到办公室开始整理桌子,这时他接到了预料之中的通知,“CEO想要见你”,于是他步履沉重地走进CEO的办公室,默默地递上一张纸。

“这是什么?”CEO问道。

“我的辞呈,”这位高管答道,“你叫我来就是要炒我鱿鱼的吧。”

“炒鱿鱼?”CEO一脸狐疑地答道“,我为什么要炒你鱿鱼?我刚刚才花了一千万来培训你!”8

当然,这个段子很极端,但是故事里的CEO心里明白,就算炒鱿鱼也不能挽回这一千万的损失,而且还要损失一名很有价值的高管,因为他以后肯定不会再犯这种错误了。

我们俩都在Google工作,而我们最喜欢的Google的格言之一就是“失败是可以接受的”。广泛的认识是如果没有经历过失败的话,就说明你的创新还不够,或者你承担的风险还太小。失败是更上一层楼的绝佳机会。事实上,托马斯·爱迪生曾经说过:“即便我找到了一万种行不通的办法,也不代表我失败了。我并不会因此而泄气,因为每次试错都是在前进。”

Google通常都采用这样一种(我们之前讨论过的)理念,“不要等到完美的时候再出来”:只要产品大致可用,就立刻把它按照原样公开给大众。这就是Google Labs的使命。这种办法使得成功和失败的地方得以立即显现出来,这样编程团队就可以尽快从中学习,迭代,然后发布新版本。它的缺点是Google常常会被揶揄说他家的产品总是在“beta”阶段,比如Gmail就“测试”了四年多。而它的优点在于可以迅速做出调整以适应变化,在很短的时间内就能做出惊艳的产品。所有的这一切都要求谦虚的特质——把不完美的软件展示给用户是可以接受的,另外还需要一些信任,即用户真的会认同你的努力,并且期望迅速看到改进。

从错误中学习的诀窍是要记住自己摔倒的地方,按商业用语来说就是“事后检讨”。但是要特别小心,千万不能把事后检讨的文件变成一堆无用的道歉和借口——这不是它的目的。真正的事后检讨应该包含有关“学到了什么”以及“怎么改正”等经验教训的详细注解。然后要保证把它放在一个随手可及的地方,并且认认真真地按照上面所写来实施改进。记住,正确地记录错误还能让其他人(不管现在还是将来)方便地了解事情的原委,以避免重复历史。不要抹掉自己的足迹——像跑道一样点亮它们,为后来人指路吧!

一份出色的事后检讨应该包含以下内容:

? 简要

? 事件的时间线,从发现到调查,再到最终结果

? 事件发生的主因

? 影响和损失评估

? 立即修正问题的步骤

? 防止事件再次发生的步骤

? 得到的教训

为学习预留时间

辛蒂曾经是超级巨星——在她的领域里她绝对是大师级的程序员。被提升为技术指导后,责任随之变大,而她也接受了这个挑战。很快她就能领导周围的每个人并指导他们工作了。她出席各种大会并就自己的领域作演讲,不久之后她已经能掌管好几个团队了,她也非常享受“专家”这个头衔。但是她却开始厌倦这种生活了,不知不觉地她不再学习新东西,成为所有人之中最聪明、经验最丰富的专家的这种新鲜感开始褪去。尽管表面上光鲜亮丽,但是总好像缺了点什么似的。直到有一天她终于意识到自己的领域不再尖端,人们开始转向其他更有兴趣的课题。她到底出了什么问题?

我们来分析一下:成为人群中最睿智的人的确很让人高兴,而且能够指导别人绝对可以带来了不起的成就感。但是问题在于一旦攀至顶峰,人们往往就会停止学习了。而当一个人不再学习的时候,她就会开始觉得厌倦,一不小心还会变得落伍。虽然当领导很过瘾,但是只要能放下一点骄傲,你就能开阔眼界,接触新鲜事物。这说穿了其实还是谦逊的问题和是不是愿意像指导别人一样接受别人的指导。偶尔应该跳出自己的舒适区,在更大的舞台上接受各种挑战。这样你才能长久地保持愉快的心情。

学习保持耐心

傅攀勃在多年前写过一个把CSV仓库转到Subversion(以及后来的Git)上去的工具,由于RCS和CSV的行为异常古怪,他不断地发现各种诡异的bug,比如 CVS会默默地吃掉明明是非法的RCS文件。而他的老朋友和同事卡尔对CVS和RCS都非常了解,他们决定一起来修复这些bug。

可是就在他们开始结对编程的时候发生了一个问题:傅攀勃喜欢自底向上的工作方式,他会深入项目,通过快速尝试各种情况来梳理细节。而卡尔却是喜欢自顶向下工作方式的工程师,他会先搭好框架,构建好调用栈里每个方法的实现后才会考虑bug的问题。这就引发了两人之间巨大的冲突和分歧,有时甚至会产生激烈的争执。傅攀勃和卡尔尽了极大的努力和专注,还恪守了 HRT 的原则才得以完成这项任务。HRT 最终不但拯救了项目,也保住了他们之间的友谊。

对影响保持开放的态度

你越是容易受影响,你就越能影响别人;你越是示弱,你就越强壮。这两句话看起来有点自相矛盾。但是每个人都碰到过某个同事,固执到叫人恼火。无论怎么试图说服他都没用,越劝越不听。最后怎么样?就我们的经验来讲,大家最后就会自然而然地把他当成障碍物“绕道而行”,再也不会有人听取他们的观点或反驳。没人希望这种事情发生在自己身上吧?所以请记住这一点:接受意见改变自己没什么大不了的。不要随意挑起争斗。不要忘了,要别人听你说话,首先是要学会当一个听众。注意在被影响的时候,如果你要听取意见,一定要在你下定决心或是确定宣布你已经做好决定之前——要是你的主意老是改来改去的,别人会觉得你这个人没什么立场。

说到示弱,初看之下也有点奇怪。如果一个人承认自己对某个东西一无所知,不知道要怎么解决问题,那他还能得到多少团队的信任么?示弱就是暴露弱点,这不是在摧毁自己的自信吗?

其实不是。承认自己犯错或是无知从长远来讲其实能提升你的形象。事实上它蕴含了HRT的全部方面:它对外表示了“谦虚”,这是有责任心、负责的态度,这也是表示“信任”别人意见的态度,同时作为回报,别人也会因为你的诚实和坚强而“尊重”你。所以有时候最好的答案就是:“我不知道。”

诚实和谦虚不是氪气石

想想那些政客吧。这帮人之所以讨厌是因为无论他们错得多离谱,或是对件事物表现得有多无知,他们也从来不会承认,所以很多人都觉得政客的话是不可信的。这种现象主要是因为政客经常暴露在对手的攻击下。但是写软件的时候就用不着总是抱着防备的心态了——你的同事是合作者,不是竞争者。

若能读到这里,说明你已经在掌握“与人合作”的艺术的征途上跨出了第一步,你已经检视反省了自己的行为。只要能在日常生活中运用这些策略,你就会发现合作将变得更自然,工作效率也能大大提高。

重要的改变要由自己做起,然后慢慢影响其他人。在下一章里,我们要讨论如何在你隶属的团队中培养HRT文化。

注释:1 第一夫人。

注释:2 假设你真的是自行车设计师的话。

注释:3 当然值得注意的是有时候一开始获得太多反馈也不是好事,我们在后面的章节里再讨论。

注释:4 当然我们也承认有些内向的人确实需要更多安静独处的时间,即便没有自己的办公室,他们也需要一个相对安静的环境才能好好工作。

注释:5 如果你过去遇到过所托非人的情况,那这一条的确是非常难做到的。

注释:6 “你和你的研究,”http://www.cs.virginia.edu/~robins/YouAndYourResearch.pdf译注:网上有中文翻译,下面两个都是转载的。http://bbs.virology.com.cn/archiver/tid-5061.htmlhttp://louisfaye.wordpress.com/2007/11/27/you-and-your-research-richard- hamming/

注释:7 译注:Murray Hill,贝尔实验室所在地。

注释:8 这个段子在网络上有无数版本,曾经被套在好多著名经理人的头上。

团队和团队之间的文化差异是非常大的,它反映了多种多样的价值观和对不同事物的重视程度。有些能引领团队走向成功,而有些却会导致彻底失败。即便是那些能带领团队成功的文化也有高下之分,有的非常高效,能让团队的注意力完全集中在编写软件上面;有的则会给手头的工作带来很多干扰。这一章我们要探讨的就是团队文化,特别是各种对成功有助益的沟通技巧。我们将会说明这些技巧是如何帮助出色的工程师团队更有效率地编写软件的。

当我们听到“文化”这个词的时候,脑子里浮现的情景往往是某个晚上去歌剧院看演出,或是高中生物课上在培养皿里繁殖细菌的画面。工程师团队的文化其实和后者的差别并不大。

假如你吃过非常美味的发酵面包并且对烘培它的人感到好奇的话,你会发现这面包的关键就在于酵母。酵母是面粉和水里的酵母菌和乳酸菌。酵母菌能让面包膨大,而乳酸菌是让面包具有强烈酸味的秘密。然而并非所有乳酸菌都是一样的,有些乳酸菌产生出来的风味更好吃,所以当面包师找到味道一流的酵母(即含有恰当酵母菌混合比例的面团)时,她就会小心翼翼地通过加水和面粉来继续培养这种益菌群。然后只要取出一小部分酵母混进面包里,瞧!马上就能得到一条好吃的发酵面包啦!这是因为酵母里的菌群不但能产生她想要的风味,而且还能盖过面包食材本身以及空气中的酵母菌。

你需要一块好酵母

团队文化就像是一块含有酵母的面团:酵母(团队创始人)能将菌群培养物1植入生面团(团队新人),从而变出一块好吃的面包(团队)。如果团队本身具有很强的风格,它就能压过新人带来的任何“坏习惯”2。如果团队文化不够强势,团队就会被新人带来的风气所影响。由于未知的文化往往伴随着未知的结果,因此一个团队最好拥有自己的熟悉的团队文化。

好的酵母能让新人融入你的文化中

团队文化不仅仅是成员们编写代码的方式或是成员之间的相处之道,它还包含了所有人都认可的经验、价值观、目标。我们工作过或观察过的每个工程团队对此都有不同的见解。团队或者公司的创始人决定了团队大部分的特点,但它还是会随着时间不断变化发展。

组成团队文化的元素非常丰富。有些和代码编写有直接的关联,比如代码审查、测试驱动开发,以及在大规模进行编码前对于良好设计文档所抱的态度等。有些元素则和社交的关系更大一点,比如每个星期四一起去某个餐厅吃午饭,或是星期五的时候一起去大家都喜欢的酒吧喝一杯之类的。有些在外人看来甚至很傻很古怪:比如Google匹兹堡分部曾经就在一条货运火车线旁边,每次有火车经过的时候(顺便提一句,火车可是非常长的哦),大家都会跳起来互射Nerf泡沫枪弹3。所有的这些元素组成了一支团队的文化,并且影响着团队的生产力以及吸引和留住优秀成员的能力。

如果你观察一下现在任何一家成功的软件公司——Google、Apple、微软、Oracle,你就会发现每家公司的企业文化都非常不同,但都是由创始人和最早的员工确立起来的。随着公司的成长和成熟,其企业文化也发生了演化和改变,但是它们仍然在方方面面保留着独一无二的特质,比如产品开发模式、对待员工的方式,以及与其他公司竞争的手法等。

简单来说,关心团队文化的原因就在于如果不努力营造它,那么团队最终会因为某个特别强势的人的出现而被注入他个人的文化基因。这种文化或许是生产力强劲的健康文化,能产出大量的优秀代码。但事实往往相反,你会突然发现自己在争执和争斗中浪费了太多精力,没有办法集中精神去设计和编写代码。不仅如此,团队拥有一个共同的价值观并愿意为之奋斗是非常重要的事情。要是团队不在意自身的团队文化,那么不仅构建强烈的团队认同感以及对自身工作的骄傲感会变得十分困难,而且会很容易受新人影响而引入糟粕。

大多数工程师都会犯的第一个错误是假设建设团队文化是负责人的事。这种想法再离谱不过了:尽管创始人和负责人通常会关注团队文化的健康情况,但其实每位成员都是团队文化的一部分,都要为定义、维护和保护它作出贡献。每当有新人加入时,她并不只是从团队负责人那里了解团队文化,而是从一起工作的每个成员身上学习。例如,你在仔细检查新同事的代码的时候,会向她解释为什么你的团队是按照某种方式写代码的,这样她很快就会明白团队重视的是代码里的哪些部分。她还会通过观察团队的工作、交流,以及解决冲突的方式来学习团队文化。

所谓“强壮的文化”,是指能接受有益的改进,同时又能抵御有害的激进变化的团队文化。最成功的团队文化都把大部分的注意力放在了开发优秀软件上面。如果你的团队把主要精力放在了其他东西上(比如聚会、开会,或是怎么把别人踩下去等),那么也许你们很团结,但是却写不出什么东西来。如果你最高兴的时刻是写代码和发布产品,那么最好还是找一个重视这些东西的团队,然后努力维护这样的氛围吧。并不是说缺乏强壮和生产力的文化就没有办法发布产品,只不过在缺乏这些特质的团队文化里,发布产品需要耗费你更多的时间和精力。强壮的文化能为你提供专注、效率和力量,这些东西都能让团队更快乐。

团队文化有意思的地方就在于如果你清楚地定义好它,它是会进行自我选择的。在开源世界里,那些构建在HRT之上,专注于编写干净、优雅、可维护代码的项目会神奇地吸引拥有相同价值观(即尊重信任他人,并且致力于编写干净、优雅和可维护的代码)的工程师加入。然而,如果你的团队文化是侵略性的、欺凌性的,或者是感情用事地进行人身攻击的话,那最终吸引过来的也只能是这样的人罢了。

我们在Apache软件基金会已经见过很多这样自我选择的文化了:ASF聚集了很多软件开发团队,它们大多都是社区性质的团队,采用共识决策4的方法运营。很多新成员加入邮件列表的时候,或是无意或是有意,会有一些和团队文化冲突的行为。社区成员一般会尝试教育新人(有时会很有礼貌地进行教育;有时候,唔~,就“不是那么客气”啦),假如这位新人对ASF团队的做事方法不感兴趣的话,他就会离开去寻找更适合自己的项目。

在企业里,团队的自我选择是通过招聘来实现的,这可以是潜移默化地筛选潜在候选人重视的技术和优势,也可以是明确地在招聘过程中考察与团队文化的契合度。Google在招聘过程中采用的是明确的方式,因为它在面试的时候十分重视文化上的契合度:如果一个人在参加Google的面试中各方面都像是超级明星工程师一样,却无法和团队合作,或是要求非常结构化的环境的话,面试官还是一样会在反馈里亮起红灯。

如果你在招聘的时候不重视团队文化的契合度,结果招了一个不合适的人,那最后无论是让他融入团队还是请他走人都要耗费你大量的精力。不管结果如何,其代价都是非常高昂的,还不如在招聘的时候就确认新成员能够和现有团队一起工作。

确认新成员的文化契合度的唯一方法就是在面试的时候注意这方面的东西。很多公司(比如Google)都将文化契合度作为面试官面试候选人时的考察点之一。有些公司为了避免招聘失败甚至采用更激进的做法:他们会在技术面试之前先进行单独的面试来考察文化契合度,对于价值观不同的人根本就不予考虑,哪怕他们在技术上没有问题。这种流程对于建立和保护强壮的文化是至关重要的,而且并非偶然的产物;事实上它通常都是由公司创始人和早期员工有意识地设立的。

编写软件和在流水线上简单地组装产品可不一样。有些工作只需要几天培训和一些基本的工具就可以完成,如果有工人退出或离职(或者就是学不会),你只需要替换为另一个工人就可以了。在流水线环境里,员工通常只要机械性地完成简单的任务即可,而不需要什么创造性思维或是解决问题的本领。但在软件行业里,产品工程师则需要大量的创造性思维5,这就是说如果你想要出色的产品,那么就离不开出色的工程师。而且如果你希望这些出色的工程师能做出漂亮的产品(并且留住这些优秀人才的话),你就需要为他们建立起一种团队文化,让他们可以放心地分享创意,并且在决策过程中拥有发言权。

如果你想要优秀的工程师为自己的团队工作,首要的就是雇佣出色的工程师!这听起来有点奇怪,不过事实就是大多数优秀的工程师都喜欢加入那些拥有优秀工程师的团队。我们认识的很多优秀工程师都倾向那些可以向业界巨人学习的团队6。那么一开始的时候怎么才能吸引这样的工程师呢?

对于初创人员来说,他们需要的不仅仅是为产品开发贡献力量,更重要的是能参与到产品的决策中来,这通常就意味着某种程度的共识驱动管理。在自顶向下的管理模式中,首席工程师就是团队主管,其他工程师则被雇为团队成员。这是因为这些团队成员的成本比较低,也比较容易指挥。但是你很难在这样的团队里找到优秀的工程师,毕竟,要是能在另一家公司里主导开发的话,她何苦屈尊在这里听指挥呢?但是在共识驱动管理之下,整个团队都能参与到决策中来。

很多人一听到“基于共识决策的团队”时,立刻就会想到一群嬉皮士围着篝火唱着“Kumbaya”7,却做不了任何决定或是完不成任何工作的画面,但是这种固有印象其实更符合功能失调的团队所具有的症状,而非基于共识决策的团队。所谓的“共识”,是指每个人都对产品的成功抱有强烈的主人翁精神和责任感,同时团队的领袖也真的愿意倾听团队的意见(即HRT中“尊重”的部分)。这表示有时候产品成功需要反复的讨论和检讨,而有时候团队又必须搁置争议先行动起来再说。在后面这种情况下,团队成员会决定把日常的决策工作托付给一位或者少数几位领导8。为此,团队作为一个整体必须在大方向上达成一致,不管你信不信,要做到这一点,关键就是要为它设立一个章程(本章后面会详细讨论)。

和团队的决策过程同样重要的是同事之间的相处方式,因为这是最具备自我选择性的方面。如果你的团队习惯骄傲自大,对同事大吼大叫的话,你能吸引(和挽留)的也只能是这种攻击性极强、极端自我的人(事实上,我们认识的绝大多数女性对这种环境都非常厌恶)。如果你能建立起HRT的氛围,同事之间能友善相处,提出的都是经过考量的建设性批评,那么你不但能吸引更多的员工,而且大部分精力都可以分配在编写软件上。培养强烈的团队自豪感是好事9。若团队被个人的自负盖过,那就是灾难的源泉。我们会在第四章里讨论防止这种情况发生的办法。

建设性批评是任何工程团队成长发展的基石。接受批评是需要一定的自信心的,而我们觉得建设性批评是最容易接受的一种。另一方面,给出建设性批评要比直接批评嘲笑对方困难得多。而且我们也清楚,请别人批评指正是非常困难的事情,大多数人只会觉得你想听的是赞许和褒扬罢了。如果你身边有朋友和同事能在你需要的时候真正提出建设性批评,千万不要疏远他们,诤友难得。

如果你想要在工作上有所进步,或者改掉自身的坏毛病的话,这样的朋友和同事可以帮助你认识到阻碍自己成为优秀工程师的缺点。除非自我意识和自我反省的能力异常突出,在没有别人批评的情况下,你只会不断重复同样的错误——这就好像有人告诉你牙齿上有菜渣一样。例如,在本书出版的过程中,我们请了十几个人来帮忙审稿,告诉我们写作上存在的问题,这些建设性批评大都非常详细,是十分宝贵的意见。不管你是不是喜欢本书,如果我们忽略甚至不敢去请求这些珍贵的反馈的话,它只会比现在更糟。

攻击性性格的人(通常)也能够适应比较平和安静的环境,但是比较内向的人却很少能在激烈的环境里生存(或者开心地工作)——这样的环境下,他们的声音不但很容易被杂音盖过,而且会逐渐影响他们参与的积极性10。如果你想找一个能让大多数人高效工作的环境,那还不如自己去建立一个谦虚、尊重和信任的文化氛围呢!

建立在尊重之上,气氛随和的团队文化更容易受到性格激进的人的影响,其程度要大于随和的人对于激进的团队文化所产生的影响。因此随和的团队文化要特别小心这一点,不要被激进的新人牵着鼻子走,特别是要避免和这样的人发生激烈的冲突。有时候,团队的资深成员要挺身而出,正面迎击这样的新人,防止他们对团队的随和氛围产生破坏。我们在第四章里还会更进一步讨论对付这类“害群之马”的办法。

沟通一般都不是工程师的强项,他们宁可花一个下午和(可理喻,有逻辑的)编译器搏斗,也不想和(不可理喻,情绪化的)人打交道。大多数时候,工程师都视沟通为编写代码的障碍,但是如果你的团队没有事先达成共识,那么是没有办法知道你的代码写得对不对的。

工程师通常更喜欢和可理喻的、有逻辑性的人待在一起

只要检视一下任何优秀、有效率的工程师文化,你就会发现它们对各种沟通渠道的重视,例如邮件列表、设计文档、任务宗旨、代码注释、产品说明等。让所有人认同团队的方向并完全了解团队要做什么是很花精力的,但是这些努力的回报是生产力的提高和更快乐的团队。

沟通的指导原则之一就是在同步沟通的时候(比如开会),人越少越好。而在异步沟通的时候(比如E-mail),涉及的听众越多越好。更重要的是,你必须确保项目文档里的信息要尽可能地让所有人都看到。接下来我们要讨论软件开发过程中团队里主要会用到的沟通方式。其中有些看起来似乎是无需赘言的,但是其中还是存在一些细微差别,值得再好好审视一下。有一件事是肯定的:如果你不花精力好好沟通,最终一定会浪费更多的精力去做一些没必要的工作,或是团队里别人已经做过的工作。

在最高层面上,整个团队必须目标一致,在报告进度上遵守最佳实践。

任务宗旨——不,我是认真的

每当听到“任务宗旨”这个词,很多人的第一反应都是大公司颠来倒去说的那些空洞无物、营销意味浓重的公司宗旨之类的东西。下面这个例子就是一段某家不具名的大型电信公司的公司宗旨。

我们立志成为全球最受尊敬、最有价值的公司。我们的目标是通过令市场瞩目的优质服务来丰富客户的个人生活,帮助企业获得成功,同时为股东创造价值。

说来奇怪,我不觉得有任何人尊敬这家公司!这里是另一家大型企业的公司宗旨:

提供实时的解决方案以满足客户需求。

这句话到底是什么意思?它可以代表任何事情——如果我们在这家公司工作的话,我们根本就不知道到底是编写软件更重要,还是修漏水管或者送披萨更重要。正是这种含糊不清的东西让公司宗旨在世人眼里显得那么空洞。

对工程团队来讲,撰写任务宗旨就是要准确地定义产品的方向和范围。好的任务宗旨不是轻易写成的,但是它或许能为你节省数年的时间来澄清哪些是团队应该做的,哪些是不应该做的11

几年前,当Google决定要把Google Web Toolkit(GWT)开源的时候,我们曾经担任过团队的指导。我们检视了开源和闭源开发之间很多不同的地方,特别注意了在一个谁都可以来发表意见、贡献补丁、对产品最微小的某个方面提出批评的环境里,设计、讨论和编写软件所要面对的困难12。在解释了这些困难之后,我们告诉团队,他们需要写一份任务宗旨,向公众描述哪些是产品的目标(还有哪些不是)。

出于上述各种原因,有些工程师对此颇为犹豫,但是也有一些人表示有兴趣,团队负责人似乎也觉得这是个不错的主意。但是等到真正坐下来开始写的时候,大家对于这份宗旨的内容、基本要素和风格又产生了巨大的争论。在一系列讨论(和会议)之后,团队不但交出一份漂亮精练的任务宗旨,甚至还准备了一整篇“让GWT更出色”的文档13来逐条解释它。他们还专门开辟一节来解释哪些不是项目的目标。下面就是这份任务宗旨。

GWT的任务是要通过让程序员利用现有的Java工具,为任何现代浏览器构建全功能的AJAX,从而彻底改善用户的网络体验。

这句话包含了很多基本要素,我们认为它是任务宗旨的绝佳范例:它不但包含了方向(通过让程序员……改善网络体验),同时还限制了范围(Java 工具)。几年后有一次我们和那位团队负责人吃饭的时候,傅攀勃告诉他说我们非常感谢他当年坚定地支持我们让团队撰写任务宗旨。他回答说,其实当初我们提出的时候他觉得这完全是浪费时间,但是当他开始和团队争论怎么写的时候,他居然发现了一些之前都不知道的事情:他的首席工程师居然不同意产品的方向!

撰写任务宗旨强迫他们在产品的走向上求同存异,否则到时候一定会拖缓(甚至停滞)开发进度。在网上公开任务宗旨后,不但整个团队自己可以完全专注在那些必须完成的事情上面,而且也不需要再浪费口舌去和潜在的贡献者争论产品方向——他们只需要让新人去读一读“让GWT更出色”这篇文章就可以了,很多问题都能迎刃而解。

任务宗旨可以帮助团队求同存异

任务宗旨可以保证项目不会随着进展而偏离目标。但它也不是一成不变的。如若所处大环境或是商业计划发生巨变(对创业公司来说很常见),团队成员绝不能顽固不化,他们应该重新评估原来的任务宗旨是否还有价值。像宪法一样,这种改变肯定是异常困难的,因为它原本就不应该是可以随意更改的东西。但是当这个时刻来临之际,至少它是可以改变的,人们也应该予以认真考虑。任务宗旨应该与时俱进,及时反映公司或者产品的变化。

开会要有效率

绝大多数工程师都把会议归类为必不可少的恶魔。如果利用得当,开会是很有用的,但是人们经常会滥开会,组织不当,而且几乎一定会把会议拉得很长。我们期望的会议应该像污水处理厂一样:数量要少,位置要远,还要在下风口。所以这一节也非常精练,只讨论小组会议。

首先是所有会议中最可怕的:常务会议。这种会议一般一周开一次,应该只能用于发布简单的通告或者介绍——要求所有与会人员一个一个报告进展情况(不管他们是不是真的有什么重要的事情要宣布)完全是浪费时间,只会让人觉得不耐烦,恨不得立刻打晕自己好不用再受折磨。任何值得深入讨论的内容都应该在会议结束后进行,而且应该只涉及相关人员。这种会议应该允许人们在重要议程结束时离开,而且要是没什么大事,或者可以通过 E-mail 来宣布消息的话,完全可以取消会议。我们曾经见过一些把能够参加会议和身份地位等同起来的公司文化,结果没人愿意被落下。说得直白一点,这种做法实在是太愚蠢了。

有些工程师非常推崇像敏捷这样的开发方法所倡导的每日站会,如果能保持短小精悍,这种形式是可以接受的。这种会议一开始的时候都很短(15分钟左右),大家真的是围站在一起,轮流报告自己正在做什么,但是如果不保持警惕,很快这些会议就会被拉长到 30 分钟,人们会坐下来东拉西扯,好像是参加集体治疗课程一样。所以,如果你的团队打算开每日站会的话,一定要事先委任会议主持人,而且他要看着时间,防止会议变得太长。

如果你正打算做一些新的设计,那么尽量把会议人数控制在五个人以下——除非只有一个人可以拍板,否则在超过五个人的会议室里是做不出任何新设计或者决策的。如果你不信,可以去找五个朋友一起跑到市中心,然后试试看你们六个人能不能设定一条覆盖六个旅游景点的观光路线。我打赌除非你们让其中一个担任领头羊,然后他怎么走你们就怎么走,否则你们会站在路口争论一整天。

没用的会议和折磨没什么两样

会议对所谓的“工作时间”14来说通常是一种干扰,这个词的灵感来自保罗·格雷厄姆的一篇文章“工匠和老板的时间安排”15。如果工程师总是要中断手头的工作去开会的话,他们是很难完全进入工作状态的。你应该在日程表上留出三到四个小时的大段时间,把它们标记为“忙碌”或者“工作时间”,然后把事情做完。如果一定要开会,那么尽量把会议安排在休息时间,比如午饭时间,或是下班之前。Google一直都有(可惜也经常被无视)“周四不开会”16的传统,就是为了让大家有时间把工作做完。好的开始就是成功的一半,以后甚至可以空出20~30个小时的大段时间来专注工作。

有关开会的五条小贴士:

1.只邀请一定要参加的人;

2.开会前要决定好议程,而且要事先通知所有人;

3.达成目的后应提早散会;

4.注意别跑题;

5.尽量把会议安排在休息时间前后(比如午饭时间,下班前等)。

开会前一定要事先准备好会议议程并且至少提前一天通知所有与会人员,让大家知道要开的是什么会。把会议人数降到最低(别忘了同步交流的成本)。我们认识很多人会无视没有议程的会议邀请,包括工程师、工程经理,甚至主管和副总裁。

为了能达成会议的目的,只邀请那些真的需要与会的人。有些人在发现与会者实际上是在看 E-mail 而没有认真开会的时候,会规定不准带笔记本电脑去开会。可惜这只是治标不治本——人们在开会的时候看 E-mail 很有可能是因为他们一开始就不需要参加这个会议。

主持会议的人应该拿出权威来毫不犹豫地(有礼貌地)打断那些跑题乃至妄图独揽话语权的人。要做到这一点并不容易,但却是值得的。最后,也是最重要的一点就是,如果时间尚早而议程上的议题已经讨论完毕,千万别犹豫,立刻散会吧。

地理上分散的团队

如果你隶属一个分布各地的团队,或者工作的地方离同事们很远,那么不但需要在沟通渠道另寻出路,更要在沟通上面多下功夫。如果团队里有异地的同事,那么决策的记录和分享往往都是书面的形式,比如E-mail。在线聊天、即时通信、走廊上的随性交谈都可以是沟通讨论的地点,但是我们还是需要把这些讨论的相关内容广播给所有人知道,保证大家的信息对等性以及参与度(另外一个好处是,存档后的邮件列表就是文档)。当需要快速建立对话的时候,视频对话也是非常有用的工具,而且现在为整个团队配备摄像头的成本也是相当低廉的。

我们在做Subversion项目的时候有一句座右铭:“邮件列表上查不到的讨论等于没发生过。”在聊天室里说话可以百无禁忌,什么想法都可以提出来,但是到了真正确定方案的时候,我们千万不能忘了那些没参与讨论的人。即便团队分散各地,只要将这些谈话内容重新发表到邮件列表上,每个人就都有机会看到决策是如何形成的(如果觉得有必要,他们还可以发表意见)。如果你想要培养基于共识决策的团队文化,那么这一点是至关重要的。

和一个远在异地的同事交谈应该和直接去他的办公桌交谈一样做到无摩擦。如果你在异地工作,那你应该利用所有的媒介(比如在线聊天、即时通信、E-mail、视频对话、打电话等)和团队沟通,保证大家不但知道你的存在,也清楚你在干什么。最重要的是,千万不要低估了面对面交流的力量。无论你发了多少E-mail,在网上聊了多久,打了多少个电话,还是要大胆地经常跳上飞机去见见同事们。这也适用于海外的雇员、团队和分部雇员——安排好时间去总部和同事们见个面吧。

设计文档

开发新项目的时候,往往很难抑制住那种想要立刻开始写代码的冲动,但是这么做的结果往往是很糟糕的(除非你只是打算很快地做一个粗糙的原型出来)。同样,很多工程师都不做设计就直接开始编码,后果往往是惨不忍睹的。

设计文档一般由一个人负责,两到三个人撰写,审核的人数则更多一些。它不但勾勒出整个项目的前景,也直白地告诉整个团队你想做什么以及打算怎么做。而且这时你还没有花费几周(甚至数月)编写代码,比较容易接受意见和建议,帮助你改进产品和优化实现。另外,当设计文档定型之后,它能帮助你安排划分项目的工作量。而且,当编码工作开始以后,设计文档绝不是一成不变的:随着项目的进展而发生的变化应当及时反映在设计文档里,而不是等到了产品要发布的时候才去更新,不过这一点是说起来容易做起来难。大多数团队根本没有文档,而有些团队只在很短的一段时间里有很漂亮的文档,剩下的很长时间里只有过期的文档。

说到这里,你也不要走到另一个极端“唯设计文档论”里去。我们曾经遇到过为了一百行的小程序写了整整四页设计论文的控制狂。如果写一份设计文档的时间足够把整个项目推翻重写好几遍的话,那就不要浪费时间写设计文档了。用经验和判断来作出适当的权衡吧。

假设大方向已经确定,接下来需要确定的就是每天团队用来协调的工具。这些工具很有用,但是可能会限制沟通的效果,因为它们常常缺乏面部表情以及身体语言这种辅助的沟通渠道。结果它们可能会导致沟通产生误解,从本质上对HRT造成威胁。不管怎么说,这些工具对绝大多数团队来说仍然是不可替代的,(只需要一点点努力)就可以大大提高生产力。

邮件列表

我们还没见过写软件不用邮件列表的人,不过这些技巧可以让你更好地利用邮件列表。

很多非常成功的项目都有好几个邮件列表,把开发讨论、代码审查、用户讨论、公告发布、调度邮件,以及各种管理琐事区分开来。有时候一些比较小的项目一开始的时候就会试着依葫芦画瓢,在只有三个工程师和两名用户的时候就建了一大堆邮件列表。这相当于五个人为了讨论一件事情却准备了六间会议室——最终只会导致讨论缺乏连贯性,大量的重复,还有很多空置的房间。最好的做法其实是从一个列表开始,当信息量太大无法管理(通常是列表成员开始抱怨求饶的时候)的时候再逐渐增加数量。好好花点时间培养邮件讨论的礼仪——文明讨论,不要被那些“嘈杂的少数人”17所阻挠。

虽然当整个团队坐在一个办公室里的时候,邮件列表并非是进行讨论的最佳选择,不过用它来发布会议议程、会议记录、决策、设计文档,以及任何相关的文字信息再好不过了,它是一个非常方便的集中记录点。通过这些列表将所有帖子存档,并为之建立可搜索的索引,如果是开源项目,可以把它公布在网上;如果是闭源项目,则可以把它放在公司的内网上。这样你的项目就拥有了一份完整的历史记录,当新人对过去作出的某项决策心存怀疑的时候,就可以很方便地回溯查看当时那么做的原因。如果不存档这些讨论的话,你会发现自己不得不一次又一次地重复讨论它们。

在线聊天

在线聊天对于团队来说是非常方便的沟通方式,特别是因为它能在不打断同事的情况下快速发送请求(当然啦,她的聊天工具一定要设置成可以不受打扰的)。团队如果需要在晚上或是周末做一点简单工作,或是某位成员休息一两天的时候,这个工具对团队来说是很方便的。一对一聊天是非常有用的工具,在团队交流里绝对占有一席之地,但是我们强烈推荐采用群聊的方式18

多年前在即时通信还不流行的时候,团队通常都会挂在互联网中继聊天(就是所谓的IRC)频道里,大多数讨论都是以群聊的方式进行的。有时候这会显得有点吵闹,但是这样一来,讨论就是“当着整个团队的面进行”的了,而且如果谈话内容和其他人没什么关系的时候,转成私下讨论也是非常方便的。这样其他人就可以选择随时加入讨论,或者潜在一边只看不说,甚至可以对错过的讨论补充意见。它的便捷不但体现在即兴讨论可以随时进行上,更表现为能帮助团队培养社区感,即使他们相隔万里也没关系。新成员不一定要参与,光是看大家讨论(或是阅读过去的谈话记录)就能学到很多东西,效果往往能叫人惊叹不已。

当即时通信出现之后,很多原本在集体聊天室里进行的谈话都变成了私下交谈,因为即时通信默认就是如此。害怕自己会问出傻问题的不安全感会让人更倾向于一对一的讨论,以避免当众出丑的风险。可惜这么做只会给团队增加负担,因为这样一来知识就无法共享,同事之间可能会重复不断地问同一个问题。所以无论用什么软件来沟通,我们都强烈建议要有一套方便可用的群聊机制。VPN和安全限制的确会造成一点障碍,但是这层沟通渠道对于团队来说是很有价值的,再麻烦也值得。

现在很多人第一次听到IRC的时候,都会嘲笑它简陋的文本环境,最新版的 IRC 客户端看起来都要比 iChat 或者Google Talk的旧版本差劲。但是千万不要被 IRC其貌不扬的外表和风格所迷惑——专门设计的异步群聊才是它的杀手级特性,绝大多数客户端都支持无限向上翻页,所以你可以回过头去看之前错过的讨论。漂亮的视频会议软件包、共享白板系统等或许很有诱惑性,但是它们只会打扰工程师的工作,完全抹杀了IRC异步的优势。IRC并不是你唯一的选择,但是如果你打算用别的软件的话,一定要选真正为群聊而设计的产品,不要选那种只是硬是加上群聊功能的即时通信系统。

有时候人们更喜欢在网上聊天。还记得那是我们头一次参加编程马拉松,就是很多开源贡献者互相见个面(很多人都是头一次见),然后一起做项目。我们走进一间几乎沉默的房间,里面摆了十几张桌子,每张桌子都坐了六到八个人,在笔记本上疯狂地打字。因为我们迟到了,所以看到这个情景的时候还以为大家都在专心写程序呢,所以我们也坐了下来,打开笔记本,启动编辑器,登入项目的 IRC 频道,看看那些没办法参加马拉松的人是不是在线,结果发现 IRC 频道里正讨论得热火朝天。我们打了个招呼,说刚刚才到马拉松现场,立刻就有好几个人在 IRC 频道里和我们说哈啰了,而当时他们就坐在我们三米开外啊!你可以想象我们吃惊的程度了吧。习惯了在网上聊天而产生的惯性其实只是一部分原因,更多的原因是这种和团队的沟通方式对有些人来说是最自然的。可在坐了四个多小时的飞机后,我们非常想要和人说说话,于是我们还是站了起来,越过桌子走过去和他们面对面的交流了。

如果你打算使用问题和bug跟踪系统的话(事实上你也应该用),很重要的一点是你要准备好一套流程来处理和分流bug,这样才能鼓励人们提交并且按时修复重要的bug。如果bug跟踪系统不被重视或者没有轻重缓急的安排,也就不会再有人提交 bug,人们的不满也会无处发泄。当团队最终开始在 bug跟踪系统里乱挖的时候,他们很可能会去修复那些不重要的bug,却把重要的bug丢在一边。

记住,bug跟踪系统的本质只是一个稍微专业化一点的“网络论坛”或者“电子公告栏”。所以它也拥有很多和邮件列表相同的特点,因此很多最佳实践都是可以照搬过来的。和bug有关的随心交谈都应该作为更新记录在bug跟踪系统里,所有的想法和决策都要“正式”发布给所有人看到。语气措辞要文明,绝不容忍任何挑衅行为。如果讨论变得过于冗长或是琐碎,就应该把它暂时移到主邮件列表上去——E-mail客户端更擅长处理这种复杂的讨论串。

市面上软件开发流程方面的书可以说是数不胜数。我们无意在此做过多深入的讨论,只想提几点和沟通特别有关的,无论遵循何种开发理念,这些要点都值得关注。

代码注释

代码注释风格是一样很主观的东西。原作者常常通过详细的注释解释自己的意图和理由,这些对理解代码都很有帮助,但是却要付出后续维护的代价:过时甚至不准确的注释反而会极大地妨碍对代码的理解。同样,过于扼要的注释,或者干脆没有注释也会浪费将来维护或者API用户的时间。注释一般是用来说明代码里缺失的部分,以及起得不好的名字,然后把代码的功能再解释一遍。注释应该尽量解释为什么代码要那么写,而不是去解释代码做了什么。

注释在函数(或者方法)层面是最有用的,特别是用作API文档的时候。注释不应该涉及过多细节,用一句著名的希腊谚语来总结就是“μηδε?ν α?γαν”,即“过犹不及”。此外还应该好好为团队准备一套注释风格,然后每个人都要好好遵守——我们认为风格一致比风格本身更重要19。风格指南还应该自陈存在的理由及其目的——例如,这里是Google C++风格指南的介绍部分20

C++是很多Google开源项目的主力开发语言。每个C++程序员都知道这门语言拥有多少强大特性,然而伴随这种强大特性的是它的复杂性,这也使得代码更容易出现 bug,难以阅读和维护。

本文的目标是通过讲解C++编程中的各种要点来驾驭这种复杂度。这些规则在保证代码可控性的前提下,能让程序员高效地使用C++的语言特性。

所谓的风格(也就是可读性),就是管理 C++代码的约定惯例。风格这个词本身有点不恰当,因为这些约定所涵盖的内容远远不止源文件格式化那么简单。

强制统一代码的风格是保持代码可控的一种方法。让别人快速看懂、理解代码是非常重要的。保持一致的风格并遵守约定意味着可以简单地通过“模式匹配”的方式来推断各种符号的含义以及它们具有哪些不变的特性等信息。通用和强制要求的习惯和模式可以帮助理解代码。有时候可能有很好的理由去改变某些风格,但是为了保证一致性,我们仍然会予以拒绝。

这份指南要解决的另一个问题是 C++的特性膨胀。C++博大精深,拥有很多高级特性。有时候我们需要限制(甚至禁止)使用某些特性,这是为了保持代码简洁,避免这些特性带来的各种常见错误和问题。本指南会列出这些特性,并一一解释为什么要限制它们。

Google的开源项目都遵守这份指南的规定。

注意本指南并非C++教程,我们假定读者对这门语言已经有了相当的了解。

在源文件里署名(也就是“作者标签栏”问题)

每个人都希望自己的工作得到认可,艺术家会在自己的画作上签名,文字工作者会把自己的名字放在书脊上或是博客顶部。无论以何种方式,渴望得到认可是人的本性,但是在我们看来,在源文件里留下名字绝对是弊大于利。你一定在各种源文件的顶部见过这样的东西,它们往往和版权声明挤在一块儿。

# -------------------------------------------------

# Created: October 1998 by Brian W. Fitzpatrick <fitz@red-bean.com>

# -------------------------------------------------

在源代码顶部署名的传统已经是老黄历了(我们两个都这么干过,唉!),在程序大多由个人而非团队编写的年代这样做或许还说得过去。但是今天,很多人只是接触到一小块代码而已,文件里的作者标签栏只会导致争吵不休,浪费时间,甚至伤害感情。因此,我们强烈反对在源文件里署名的做法(最多也就是署上审核人的名字,告诉大家在修改这个文件后首先应该拿去给谁看,但是要小心不要有文件归属的暗示)。

想象一下,假如你在团队项目里新建了一个文件——编写了几百行代码,然后在文件顶部打上自己的名字和适当的版权信息,把它送去代码审查,然后提交给代码仓库。到目前为止一切正常。现在假设你的同事阿德里安跑过来修改了一下文件,那么他要改多少才有资格把自己的名字写上去呢?一定要修复一个bug以后?还是至少要五个bug?一定要实现一个函数?还是需要两个函数?要写多少行代码才够呢?如果他写了一个函数,然后在文件上加上自己的名字,结果这个函数又被后来的人重写了呢?这个人能不能也把她的名字加上去?是不是要把阿德里安的名字拿下来?和其他联合创作(比如剧作、小说、电影等)不同,软件即使在“完成”后依然会不断发生变化。因此电影可以在结尾放心地列出创作人员,可在源文件上这样添加、删除名字的做法却是一件永无止境的疯狂举动。

你当然可以通过大量文档来解决这些问题,但是维护、跟踪、防止意外发生都要浪费很多时间——这些时间原本都可以用来写代码的。因此我们推荐在项目层面而不是代码上认可大家的工作。如果需要更多的细节,可以在版本控制系统里找到答案。一切都会随时间散去,就像雨中的泪滴21

追求个人“地盘”是很容易犯的错

每个提交都必须经过代码审查

如果打算要实行某种编程标准,那么就必须要有监控哪些代码可以成为产品一部分的方法。无论是在提交之前还是之后进行代码审查,都应该保证每一行进入仓库的代码都要有作者之外的人检查过,检查的内容有风格、质量,当然还有粗心大意的错误。代码改动应该尽量短小以保证审查的质量——若改动涉及几千行代码,那么除了挑挑格式的毛病外,基本是没办法进行审查的。做到这一点不但能提高整个代码库的品质,更能从长远上培养代码质量的集体荣誉感。

真正的测试和发布流程

无论你是采用全套的测试驱动开发模式还是只有一些简单的回归测试,自动化程度越高,你在修复bug和添加新特性的时候就越自信。决定好测试所要扮演的角色后,它在编程和审查阶段都应该占有一席之地。发布流程也是一样重要,它应该方便到可以频繁发布的程度(比如每周一次),同时也要具备相当的完备性,这样才能在用户之前发现问题。

虽然这些文化和沟通的习惯看起来可能只是代表了笔者自己所偏好的工作方式,但其实它们没有你想象得那么主观。我们发现,只要在组建团队时为它培养强大高效的团队文化,并且在团队沟通上花点时间精力,这样的团队就会有更多的时间编写和发布产品,而不用老是去争论要写什么代码的问题。

强大的团队不是自发形成的,它们都是由团队的领袖和创始人培育起来的,他们对领导废柴团队编写软件所需的代价都有切身体会。所以从一开始就着手培养对创建自我选择的文化是大有裨益的,这样团队才有更多的时间设计和编写代码,而不用去定义或是维护自己的文化。这些努力(沟通和流程)还有一个很大的好处,即它能极大地降低新人融入团队的门槛。不然的话,新人要么吃力不讨好地去学习团队的工作方式,要么就干脆放弃学习,然后试图让团队采用自己在之前团队采用的工作方式(结果可能有好有坏)。

尽管为团队招募到合适的人才和为团队注入正确的价值观都是非常重要的事情,但最后绝大部分能真正成为文化一部分的努力其实都是来自沟通。任务宗旨、会议、邮件列表、在线聊天、代码注释、文档,乃至决策过程都是团队自己以及和外部沟通的不同方式。很多人都想不到只是为了写代码就要在沟通上花那么多时间和精力(包括感情上的交流),但这却是事实。代码最终是要和人沟通,而不是机器。

无论你的团队文化如何,也不管你的团队沟通有多顺畅,我们见过的每一支高效团队都少不了一个领袖。在下一章,我们要谈谈怎样才算是强力的团队领袖,为什么他的角色可能和你想象的不同,以及为什么工程师懂一点带领团队的基础知识是非常重要的等话题。

注释:1 译注:culture这个词有“文化”的意思,也有“培养物”的意思。这里作者玩了个文字游戏。表示文化是需要潜移默化的意思。文中在作比喻时将相关的词打乱在一起混用,为了行文方便,译文里全部改成直白的话。

注释:2 当然啦,再强势的团队文化也应该能够接纳新人带来的“好习惯”。

注释:3 傅攀勃头一次拜访Google匹兹堡分部的时候被吓得不轻。译注:这是孩之宝的一种枪械玩具。

注释:4 译注:不是简单地少数服从多数,具体请参见维基百科。

注释:5 有的人认为只要雇佣一个超级架构师,再配几个普通程序员就可以做出好产品了。我们承认这的确是可行的,但是和一群能激发你的灵感、挑战你、教导你的优秀同事一起工作比起来,这种方式实在是太无聊、太无趣了。

注释:6 优秀工程师还需要有优秀团队负责人的领导,因为糟糕的领队不但会在和优秀工程师打交道的时候显得不自信,通常还是那种喜欢瞎指挥人的家伙。

注释:7 译注:指盲目乐观。

注释:8 在无法达成共识的情况下,有些团队会将决定权交给负责人,而有些团队则会采取投票的方式。采用什么方式并不重要,重要的是要事先决定好在意见不同时采用什么方式来解决它,并贯彻之。

注释:9 也就是集体荣誉感。

注释:10 参见苏珊·凯恩在TED上的出色演讲——“自省的力量”(http://www.youtube.com/ watch?v=c0KYU2j0TM4)和她的著作《安静:自省的力量》。

注释:11 这一点我们要一再强调——保持专注的方法就是要拒绝各种诱惑。

注释:12 我们经常把编写开源软件比喻成在弹跳床上用扑克牌搭建房屋。这需要稳健的双手、大量的耐心,还有能大声制止那些看也不看就想往下跳的人的决心。

注释:13 “让GWT更出色”可以在这里找到,http://code.google.com/webtoolkit/making-gwtbetter.html。它绝对是任务宗旨的写作典范。

注释:14 译注:原文是“make time”,即工匠(maker)专注工作的时间。这里的工匠一词泛指那些从事创造性活动的人,比如程序员、作家等。

注释:15 http://www.paulgraham.com/makersschedule.html

注释:16 这个传统是Google工程部的副总裁韦恩·罗辛在2001年建立的,旨在改善工程师的生活品质。傅攀勃多年来一直都坚持不在周四开会,效果相当不错,但是这需要非常严格的执行力,如果有人不识相的话,有时候还可以写E-mail去大骂一通。

注释:17 所谓“嘈杂的少数人”是指少数的那一两个人,他们会回复每个帖子,反驳每个他们不同意的观点。这些帖子乍看之下似乎讨论得热火朝天,其实一共就那么一两个牢骚满腹的人在上窜下跳而已。你需要及时地小心处理这种情况(第四章会详细讨论对付这种人的办法)。

注释:18 当然,在需要不受打扰,或是没办法切换工作内容的情况下,忽略聊天也是完全可以接受的。

注释:19 达斯汀·伯斯维尔和特拉佛·佛切尔在《编写可读代码的艺术》一书中对注释有一节精彩的论述。

注释:20 本文以及其他风格指南可以在这里找到:http://code.google.com/p/google-style-guide/。

注释:21 这是1982年的电影《银翼杀手》里罗伊的台词。

相关图书

ChatGPT与AIGC生产力工具实践 智慧共生
ChatGPT与AIGC生产力工具实践 智慧共生
专利写作:从创意到变现
专利写作:从创意到变现
程序员的README
程序员的README
架构思维:从程序员到CTO
架构思维:从程序员到CTO
人人都是提示工程师
人人都是提示工程师
开发者关系实践指南
开发者关系实践指南

相关文章

相关课程