Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第 7 章 你现在是榜样了(抱歉)

“别边想边说。”在我成为 Staff 工程师时,我的朋友 Carla Geisser 这样提醒我,“一个月后你会发现,大家在谈论你那个不成熟的想法,好像它已经是个项目了。”我的同事 Ross Donaldson 对自己角色的描述更加直白:“当上 Staff 并不意味着你就不会犯错,但它确实意味着,你开口之前得多加小心。”

这就是 Staff 工程师头衔的福与祸:人们会默认你知道自己在说什么——所以你最好真的知道!你的工作被检查得会少一些,你的想法会被认为更可信。人们不再指导你,而是指望你来指导他们。

做好工作意味着什么?

最重要的是,你会成为一个榜样。你怎么做,别人就会怎么做。你会是那个理性的声音,是“房间里的成年人”。总会有这样的时刻:你心想“这是个问题,应该有人站出来说点什么”……然后心头一沉,意识到那个人就是你。当你示范正确的行为时,你就是在向经验较少的同事展示如何成为一名好工程师。稍后在第 8 章,我们会探讨如何主动地、有意识地让你的组织和同事变得更好。而本章讲的是被动影响力,也就是仅凭你作为工程师和作为一个人的行事方式就会产生的那种影响。

价值观就是你所做的事

你的公司可能对什么是好的工程有成文的定义:也许是成文的价值观,或者工程原则。但公司真正看重什么,最清楚的指标是什么样的人会得到晋升。无论你的组织多么声称鼓励协作和团队合作,只要有 Staff 工程师是靠“英雄式”的单打独斗升到这个级别的,这个信息就会被削弱。如果你们的工程原则描述的是一种认真做代码评审的文化,而高级工程师却不看就批准 PR,那么其他所有人也都会在代码评审时走过场。你所做的工作,就隐含地成为别人眼中正确的、值得效仿的工作类型和标准。

工程不只是你与计算机系统打交道时做的事,它还关乎你如何与人打交道。所以有时候,做一名好工程师归根结底就是做一个好同事。如果你成熟、有建设性、敢于担当,你就是在告诉新毕业的同事:高级工程师就是这样的。如果你居高临下、怎么都不满意,或者永远找不到人,那么这也会成为高级工程师的样子。仅凭你的行为方式,你每天都在塑造着你的公司。

可我不想当榜样!

当榜样并不总是舒服的。但随着你越来越资深,这是你影响组织的最重要方式之一。不管你喜不喜欢,你都在塑造你们的工程文化。认真对待这种力量。当榜样并不意味着你必须成为公众人物、要比你习惯的更大声,或者四处施压。许多最优秀的领导者都是安静而深思熟虑的,他们通过好的决策和有效的协作来施加影响(同时也向其他安静的人表明,他们同样有空间去领导)。

如果当领导者这个想法让你感到恐惧,你可能需要循序渐进。从小事做起。比如在公开频道里称赞某人的成功,或者主动帮忙带一位新人入职。把领导力看作一项需要培养的技能,就像学习一门新语言或新技术一样。练得越多,就越容易。

尽你所能,做最好的工程师、最好的同事。把工作做好,并让别人看到。(也帮助别人做到这一点!我们会在第 8 章讨论怎么做。)这就是当榜样的意义。

作为高级工程师,做好工作意味着什么?

在本章中,我会阐明我认为你应该示范的四大特质。先说清楚:这些是理想中的品质,是你应该努力学习并持续学习的技能。我明确不是在说,你必须在每一项上都拿满分才算“真正的工程师”,也不是任何类似的门槛设置;这些是理想。这是你应该努力成为的样子。我们每个人都还在不断完善之中。

还有一点需要说明:科技行业充斥着各种建议,大多是主观的。这份清单也是!最佳实践都要视情况而定。总会有边缘情况和特殊情形;如果我的建议与你自己的判断相悖,请相信你自己。Staff 工程师应该有足够的判断力,知道什么时候传统观点是错的。

本章余下部分要讨论的四个特质是:有能力、做一个负责任的成年人、牢记目标,以及向前看。首先是能力。

要有能力

作为 Staff+ 工程师,或者任何资深人士,你角色中很重要的一部分就是承担那些需要做的事情,并且可靠地把它们做好。能力包括建立(并保持)知识和技能、具备自我认知,以及拥有高标准。

要懂行

无论你的领导力有多强,没有“技术”这部分,你就不可能成为技术领导者。你的全局思考、项目执行、信誉和影响力,都以知识和经验为基础。公司雇用你的价值,很大一部分就在于你的知识:你见过一些世面。

积累经验

Google 的 Staff 工程师 Stephanie Van Dyk 把她工作所需的基础技能与她长期以来的爱好——织布——所用的技能做了类比。“技术技能来自学习和练习,”她说,“它们不是天生的。没有人生来就是熟练的织工;也没有人生来就是熟练的计算机工程师。”

经验来自时间、接触和学习,而不是天赋。培养技术技能需要付出努力。你可以从书本中学到很多,但没有什么能替代亲自解决问题、摸索出自己的解决技巧,以及看清什么有效、什么无效。Paula Muldoon 是一位高级软件工程师,也是一位小提琴手,她对在管弦乐团演奏的描述让我很有共鸣:“你希望自己的技艺精湛到几乎可以把全部注意力放在别人在做什么上,而不必担心自己的演奏。”投入时间——大量的时间——去打磨你的技术技能,让它们成为你的第二天性。

需要多少时间?美国土木工程师协会(American Society of Civil Engineers)公布了它的工程师等级,其要求中包括经验年限:

  • V 级(典型头衔:高级工程师、项目群经理):8 年以上

  • VI 级(典型头衔:首席工程师、区域工程师、工程经理):10 年以上

  • VII 级(典型头衔:总监、城市工程师、分部工程师):15 年以上

  • VIII 级(典型头衔:局级工程师、公共工程总监):20 年以上

软件工程在这方面没那么严格。各公司的职级差异很大。大多数地方在评定级别或头衔时不考虑工作年限,但 Staff 工程师通常至少有 10 年经验,首席工程师至少有 15 年。

不要匆匆跳过你学习的黄金时期。有些组织为了激励最优秀的人才,会在他们职业生涯相对较早的时候就提供资深角色,比如管理岗或 Staff 工程师。职业晋升的诱惑可能会让你接受。但正如 Charity Majors 所警告的:

在你作为工程师已经扎扎实实地达到高级水平之前,永远、永远不要接受管理岗位。对我来说,这意味着至少七年或更长时间的写代码和发布代码的经历;绝对、绝对不能少于五年。当有人给你提供经理职位时,这可能感觉像是一种赞美——见鬼,那就收下这份赞美吧——但就你的职业生涯或你发挥作用的能力而言,他们并不是在帮你。

Staff+ 角色也是如此。在接受一个让你离技术更远的角色之前,要好好地反躬自省。你可能会因此错失自己全身心投入、亲自动手积累经验的黄金岁月。

你“够技术”吗?

我有时会听到工程师形容别人“不够技术”,而我总是反对这种说法。且不说它有点轻蔑,它声称描述的是一个人是谁,而不是他们拥有的技能。1 它没有给出任何可操作的路径,让人变得“够技术”。如果你倾向于这样形容某人,请说得更精确些。你的意思是:

  • 他们亲自动手做技术工作的年头还不够?

  • 他们还不了解你们所在的领域?

  • 他们缺少某些具体的技能?哪些技能?

有能力、有学识,并不意味着你必须在每个话题上都懂得最多。有时候,当你进入一个新领域时,你会是懂得最少的那个人,这没关系!

积累领域知识

软件有数量惊人的技术方向,每个方向都有自己的专门知识和术语。懂移动开发、算法计算机科学或网络,并不能让你为前端 UX 项目做好准备。多年的金融科技经验也不能让你为一家医疗健康创业公司做好准备。但如果你对某个新的技术方向或领域感兴趣,你仍然可以去尝试。这意味着,即使是经验非常丰富的工程师,也可能发现自己成了新手。

当你进入一个新角色时,不可避免地会有你尚不具备的技能,或者对你来说全新的领域知识。你可能会发现自己在向共事的初级工程师学习。(这是好事!)这时,你的技术知识就提供了基础。虽然你可能认不出这个新领域中问题的具体细节,但你的通用经验应该能帮你认出它们的形状。你应该能把遇到的东西与你认识的其他东西做模式匹配,这样你就不会完全不知所措。2 你的经验范围越广,你能挂靠新知识的“钩子”就越多,学习新事物也就越快。

当你进入一个新的技术方向或业务领域时,要有意识地快速学习。用对你最有效的方式去学习这项技术。了解恰当的权衡、资源约束,以及常见的争论、偏见和圈内笑话。了解市场上有哪些技术,以及它们可能如何被使用。阅读核心文献。了解这个领域的“名人”都有谁,他们主张什么。(Twitter 在这方面很好用。)然后承担一些能让你培养直觉、积累经验的项目,这样你就能在这个新方向或新领域里变得和你在上一个领域时一样有能力。

与时俱进

作为高级工程师,意味着要有成长型思维和不断进步的动力。当一位技术领导者坚持一个十年前就已被推翻的“最佳实践”,或者一项其他人早已弃用的技术时,所有人都会很尴尬。持续关注你所在的行业领域正在发生什么。即使你不再深入代码,你对“代码坏味道”或潜在问题的“蜘蛛感应”也应该保持敏锐。即使你不了解最新、最热的工具或实践,也要知道如何去了解。

留意你的角色是否在妨碍你继续学习。尤其要警惕离技术太远,以至于你学到的只是你们公司如何运作。虽然你也应该对业务有足够的了解以做出好的选择,但要让自己扎根于技术。我会在第 9 章更多地谈论学习。

展示你在学习

初级工程师需要看到,终身学习是高级工程师的一部分,他们永远不会走到旅程的终点。他们还需要看到,你的技能和知识并不是凭空得来的——这些都是可以学会的。坦然说出你在学什么,并展示你是怎么学的。当你的陈述涉及冷门知识或逻辑跳跃时,为身边的人补上中间的空白:告诉他们你为什么得出这个结论、用了哪些信息,以及你是怎么获得这些信息的。明确表示你也在学习,这样他们学习时也会感到安全。

要有自我认知

能力建立在知识和经验之上,但你还需要能够运用这些能力。这首先要有自我认知:知道自己能做什么、需要多长时间,以及自己不知道什么。这意味着能够说出“这事交给我”,并且确实知道自己搞得定。能力意味着拥有有根据的自信,相信自己能够解决问题。你不需要傲慢、满口让人听不懂的行话或者炫耀。真正的自信来自于你做这份工作足够久,以至于学会了相信自己。

承认你知道什么

有些人从小被教育要夸耀自己的成就,另一些人则被教育要淡化它们。无论你天生属于哪一种,都要努力达到这样一种状态:对于自己知道什么、不知道什么,你既自信又对自己诚实。总会有一些领域是你懂得很多、技能格外出众的。要自信地运用这些技能,去解决需要它们的问题。

有能力并不意味着你必须是最好的。我有时看到技术人员不好意思自称专家,因为他们总能想到业内某个比自己更强的人。不要把标准定在“业内最佳”。如果你出于谦虚而退缩,对谁都没有好处。当需要这项技能时,不要等别人来说“嘿,你不是很擅长正则表达式吗?”主动说出你擅长——这不是吹嘘,只是陈述事实。

如果你知道自己能带来哪些技能,你就知道自己可以在哪里挺身而出提供帮助、在哪里可以成为好导师,以及自己还需要学习什么。

承认你不知道什么

你不可能什么都知道,而至关重要的是,你不要假装什么都知道。如果你虚张声势,就会失去学习的机会——还可能做出糟糕的决策。你也会浪费树立榜样的机会。每当你承认自己并非无所不知,并让别人看到你在学习时,你就在向初级工程师表明,持续学习是很正常的。

承认自己无知,是我们作为技术负责人、高级工程师、导师、经理以及其他团队文化影响者所能做的最重要的事情之一。我很喜欢请别人“ELI5”,这个说法来自 Reddit,意思是“像给五岁小孩解释那样给我讲讲”。它是一种很有用的简略说法,意思是:“听着,与其猜测我的理解程度,不如直接给我讲清楚。我保证,就算你讲的是我已经知道的东西,我也不会生气。”(这里的社会契约是:如果对方从这个话题最基础的内容讲起,你不能生气。)

我们在工作中花了大量时间进行沟通,努力在彼此的大脑中建立一个对世界的共同模型,以便能够协作或做出决策。当对话中的人因为不想被指出不懂某件事而虚张声势或稍微置身事外时,一切都会慢下来。如果资深的人能够承认自己不懂,其他人也都会这样做。

理解你自己的上下文

自我认知中很重要的一部分,是理解你有自己的视角,你的上下文并不是普遍的上下文,你的观点和知识是你所特有的。每当你与其他领域的团队交流,或者向非工程师解释技术话题时,你都需要跳出自己的信息茧房。你会知道你掌握了哪些他们可能没有的信息,从而弥合这一差距。(你可以在第 2 章读到更多关于如何建立这种视角的内容。)

把事情讲简单要难得多!它需要你对这个话题有更深的理解,对自己的上下文有更多的自我认知。但这是专业能力的真正标志。如果你能用平实的语言解释一个话题,让非专业人士能把它挂靠到他们已经理解的东西上,你才是真的懂了。

要有高标准

你的标准将成为别人工作方式的榜样。要知道高质量的工作是什么样子,并在你所做的每一件事中都以此为目标,而不仅仅是你最喜欢的那部分。尽你所能写出最清晰的文档。要成为第一个知道你的软件出了问题的人。当然,总是存在权衡:有时正确的做法是用胶带尽快拼凑出一个方案。但要根据你想解决的问题来做这个判断,而不是根据这项工作对你来说有多有趣。

主动寻求建设性批评

拥有高标准,意味着要让你的工作尽可能好。寻找机会放下自我,请别人帮你把工作做得更好。请别人做代码评审、设计评审和同行评估。当你有了一个自己很喜欢的想法时,邀请同事来挑刺。当你“征求意见”时,不要暗自对这些意见心怀不满;每条意见都是让你的方案变得更好的机会,所以即使你不会全部采纳,也要认真对待。你的方案不等于你,也不能定义你。对你工作的批评并不是对你本人的批评。(当然,你也会给出建设性批评。我们会在第 8 章探讨这一点。)

为你的错误负责

到了某个时候,你一定会犯错,而且可能是个大错。也许你评审了代码,却没发现一个让公司损失了一大笔钱的 bug。也许那段代码就是你写的!也许你在会议上说了一句话,后来才知道它让某人哭了(或者辞职了)。

犯错是正常的。3 人无完人,而错误正是我们学习的方式。最重要的是你如何应对自己的错误。人很容易变得防御、推卸责任,或者彻底崩溃(然后需要别人来收拾残局)。要做到有能力,你就需要为自己的错误负责。不要自责过度,但也不要否认影响,或者坚称这个错误其实不是你的错。承认发生了什么,然后着手解决。迅速而清晰地沟通,确保每个人都拿到了他们需要的信息。如果有任何别人可能被指责的风险,要澄清他们没有做错任何事。如果你伤害了别人的感情,要承认这种伤害并道歉。(即使在同样的情况下你不会感到难受,他们的感受也是真实的。)

如果你导致了一次故障,或者走了一条代价高昂的弯路,可以考虑事后开一次复盘会,讲讲发生了什么、你们是如何恢复的,以及你学到了什么。对你在其中扮演的角色保持坦诚、实事求是。当没有人试图淡化自己的失误时,理解发生了什么要容易得多。

犯错就是会刺痛人。在那一刻,解决你自己造成的问题可能是你最不想做的事。但这是你保住团队的善意和社交资本的最好方式。如果你应对得当,修复了自己造成的问题,你甚至可能最终赢得同事更多的尊重。而且,一位领导者坦然面对自己的错误,会让其他所有人也更容易这样做:这对团队的心理安全感是一个很大的提升。

要可靠

关于能力,我最后想说的是:要可靠。我给出的最高赞誉之一是:“Alex 会参加那个会,所以我不用去了。”当我这么说时,我不仅仅是在说我掌握的任何信息都会在会上得到体现。我还在说,我相信正确的事情会发生。局面会得到妥善处理。我不需要在场。我是在说,我觉得 Alex 很可靠。

可靠的声誉就像我们在第 4 章谈到的信誉和社交资本:它随着人们看到你完成工作、把局面掌控住而逐渐积累。做一个让人放心能把事情做好的人。

可靠的另一部分是有始有终。运用第 6 章中的技巧,确保你没有被卡住,也没有过早停下。即使事情变得无聊或困难,也要坚持下去。如果你因为这个项目不是对资源的正确利用而有意停下,那就为这个决定负责,并把它沟通清楚。你接下了这份工作的责任,就要把它带到终点。

这就引出了高级工程师应该努力追求的第二个特质:做房间里那个负责任的人。

要负责任

不管你喜不喜欢,高级或 Staff 头衔都会让你成为一个权威人物——而且,正如哲学家 Ben 叔叔曾对蜘蛛侠说的那样,能力越大,责任越大。你越资深,就越需要把这一点内化于心:不会有别人来充当“房间里的大人”。“应该有人做点什么”里的那个“有人”,就是你。

在本节中,我们将探讨责任的三个方面:承担主人翁责任、挺身主导,以及营造平静。

承担主人翁责任

资深的人要对整个问题负责,而不仅仅是按计划进行的那些部分。你不是在替别人管理他们的项目:这个项目是你的,你不会消极地任它自生自灭。当出了问题时,你不会耸耸肩就认定这项工作不可能完成。你会设法解决问题,并对结果负责。(第 6 章有一些摆脱阻塞的技巧,在这里能派上用场!)

避免 John Allspaw 所说的“免责式工程”(Cover Your Ass Engineering,CYAE):

成熟的工程师会挺身而出,接受交给他们的责任。如果他们发现自己没有足够的权力来为自己的工作负责,他们会想办法纠正这一点。CYAE 的一个例子是:“这不是我的错。是他们弄坏的,是他们用错了。我是按规格做的,他们的错误或不当的规格不该由我负责。”

主人翁意识还意味着运用你自己的良好判断:你不需要不停地请求许可,或者反复确认自己做的是不是对的。但这并不意味着你应该闷头行事。传统的建议是“先斩后奏”,而产品与交付顾问 Elizabeth Ayer 提出了一种更开放、更可预期的做法:“广播意图”(radiating intent),也就是在做某件事之前先发出信号,说明你要做什么。你在为其他所有人提供关于你行动的上下文——同时也创造了一个机会,让别人在你要做危险的事情时能够介入。

Ayer 还指出了广播意图的另一个重要优势:“如果事情搞砸了,‘广播者’仍然承担责任。它不会像请求许可那样转移责任。”这也是主人翁意识的关键。

做出决策

在某些学科中,专业工程师要负责在文件上盖章:例如,工程师可能要签字确认一栋建筑的结构完整性。这样做就意味着他们在证明这份文件在结构上是安全的,并对自己犯下的任何错误承担法律责任。他们要为这个决策承担个人责任。

虽然软件工程师目前还没有这种职业责任,但作为技术领导者,我们必须准备好做出最终决定,并为结果负责。尤其是在需要做决策时,不要骑墙:权衡各个选项,果断做出选择,并解释你的理由。在权衡利弊时要对自己诚实:当你知道某个选择是最好的时,你应该能够投票反对自己的偏好。

为决策负责,包括接受自己可能是错的。尽可能降低错误决策的代价;如果事实证明你确实错了,也要为此负责。

问“显而易见”的问题

作为资深人士,最好的事情之一就是你可以问那些显而易见到没有别人愿意问的问题。下面是几个例子:

  • 听起来你们打算让一个只有两名工程师的团队来运行一个关键业务的微服务。你们打算怎么安排它的值班?

  • 我想你们已经评估过,迁移出这个老系统需要付出什么,而不是费这么大劲让它继续活着吧?

  • 你们 API 里那个递增字段,你们让用户忽略它;如果用户开始依赖它,会发生什么?

  • 这个听起来有点怪的提案,你们已经找安全团队看过了,对吧?

  • 我们一直让大家不要在我们的平台上这样用,那如果要支持这个用例,需要做些什么?

作为领导者,你有责任把隐含的东西说明白。这并不公平,但如果是一个初级的人问这些问题,团队可能会叹口气说:是的,我们当然想过了。如果是一位专家来问,团队成员就会明白,他们应该在设计文档中明确回答这些问题。(或者他们是真的第一次考虑这个问题!)

不要因忽视而变相委派

几年前,我写了一个会议演讲,它有点火了。好吧,还没到手拉手的水獭那种程度的火,但它席卷了科技圈的 Twitter,上了 Hacker News 的首页,诸如此类。这个演讲讲的是那些不在任何人的职级阶梯上、却是团队成功所必需的领导和行政工作:各种疏通阻塞、新人入职、提醒、指导和日程安排。我把这类工作称为“粘合工作”。

这个演讲为什么能引起这么大的共鸣?因为尽管项目没有它就无法成功,这类工作却很少得到回报,也很少被公平地分配。它落到了团队中那个无法对问题视而不见的人身上,而这个人往往是一个有强烈主人翁意识的初级成员。

问题在于,当初级成员做了太多的行政或领导工作,而技术工作做得不够时,他们就把自己学习技术的黄金岁月花在了无法教会他们技术技能的事情上。从长远来看,这可能会阻碍他们的职业发展。但领导者往往不会介入:项目要成功就需要这些粘合工作,他们只庆幸有人在做。

如果你的组织或项目需要粘合工作,要认可它,并弄清楚是谁在做。要意识到,经理、晋升委员会和未来的雇主可能会在 Staff 工程师做这类工作时把它视为领导力,而在更初级的工程师做时却不屑一顾。所以,承担起主人翁责任,多做那些不属于任何人的职责、却能推进你们目标的工作。同时把你的初级同事引导到能促进他们职业发展的任务上去。

挺身主导

温和地把同事引导到更有价值的工作上,就是我接下来要讲的内容的一个例子:主导局面。请注意,挺身主导并不一定意味着你事先就拥有权力。它意味着你看到了一个缺口,并挺身而出去填补它。

在紧急情况下挺身而出

能够掌控混乱局面,是技术领导力的一个关键方面。如果安全团队发现了入侵、某个数据库被删了,或者一颗陨石砸中了 US-East-1,很可能会有很多人参与响应。除非他们协同工作,否则随之而来的混乱可能会让问题变得更糟。只要有人在协调,一切都会顺利得多。

遗憾的是,只有当每个人都知道你在协调时,协调才会起作用。如果你不明确地站出来主导,你就只是又一个制造噪音的人。理想情况下,你们会在灾难发生之前就制定好应急预案,让协调者的角色广为人知:经典的事故指挥系统(Incident Command System)是一个流行的选择。4 如果没有,你就得想办法宣布由你来协调,并让大家对你将要做什么有所预期。然后确保你的协调是有价值的。可以这样做:做清晰的记录,确保参与应急的每个人都拥有相同的上下文,并请每个人广播意图,说明自己在做什么、什么时候做。

当所有人都一头雾水时,要求更多信息

在本章前面,我谈到了承认自己不知道的东西,以及问显而易见的问题。在紧急情况下,你常常需要同时做这两件事。当各个团队为了解决问题而分享信息时,他们往往并不都具备解读这些信息的上下文。像“FooService 有 1% 的 401 错误”这样的客观事实,对任何不知道这个服务平时是什么情况的人来说都没有帮助。这算严重吗?对于发生了什么,有没有什么推测?FooService 在这次故障中处于什么位置?

需要有人足够勇敢地说:“我不知道该怎么理解你刚给我的信息!”挺身而出,主动去问。技术圈里可能充满了自负和不安全感,对初级人员来说,承认自己不懂某件事有时是很可怕的(或者确实有风险!)。由资深的人来问会更安全。

假装惊讶

假装惊讶曾经是系统管理员和软件工程师对话中的标准桥段:“你真的从没用过 Linux?”这是 BOFH 工具箱的一部分,目的是打压那些还在学习的人(菜鸟和“蠢用户”),让更有经验的技术人员获得优越感。

在那种环境下你要怎么提问?大多数时候,你不问。你摆出一张扑克脸,努力跟上,祈祷话题转到你懂的东西上。实在躲不过时,你就私下里求助。学任何东西都要花长得多的时间。

后来,Recurse Center(当时叫 Hacker School)在它的社交规则中点名了这种现象。给这种行为命名,就让人们有了对付它的力量:这是他们能够识别、并能要求别人不要做的事情。Recurse Center 还内置了一种机制,让这些规则保持低压力:“社交规则是轻量的。你不应该害怕违反社交规则。这些是每个人都会做的事情,违反一条并不会让你成为坏人。如果有人说‘嘿,你刚刚假装惊讶了’,别担心。道个歉,反思一下,然后继续。”

不要假装惊讶,而且要更进一步。每当有人为问了一个基础问题而道歉,而其他人齐声安慰、坚称这其实是个好问题时,文化就在这一刻建立起来了。那是一个容易学习的环境。

主持会议

会议是另一个非常需要有人挺身而出、主导局面的场合。如果大家很被动、心不在焉,或者倾向于把工作会议变成闲聊,那么(理论上)任何一位参会者都可以说:“好了,我们开始按议程来吧。”但大多数参会者都不太愿意扮演这个角色。在需要的时候挺身而出。确保会议有议程:在会议开始时收集要讨论的事项,或者以身作则,提前把议程发给大家。记住你希望从这次会议中得到什么,如果会议跑题太远,就把它拉回到那个话题上。

如果一场会议没有会议纪要,那这次聚在一起真的值得吗?会议纪要是粘合工作的一个绝佳例子。如果由初级的人来做记录,他们就没法参与讨论,而且这会被视为低地位的行政工作。如果由资深的人来做记录,他们就是在确保会议有效,所有人都会对此印象深刻!

会议纪要是推进你项目的一个绝佳杠杆,所以别犹豫,主动请缨去做记录。你可以记录你认为最重要的事实,记下做出的决定,并且第一个为决定定调。然后你可以邀请大家确认你写的内容。作为主持人,如果你需要给大家一点时间思考和反思,你也可以说:“等一下,我得把记录补上。”纪要是会议节奏的一个有用的流量控制手段。

看到问题,就说出来

另一个你可能需要挺身主导的常见情况是一种尴尬的情况:有人刚刚在公开频道里说了一些不尊重人或冒犯人的话。房间里的其他人可能想说点什么,但觉得自己缺乏足够的社交资本。利用你作为领导者的地位,站出来发声。

和许多工程师一样,我也觉得这种情况很不舒服,所以我向 Daily 的工程 VP Sarah Milstein 寻求建议。在面对“高阶为人处世”问题时,她似乎总是无所畏惧,所以当我得知成为经理后站出来发声并不会神奇地变得更容易时,我有点失望。她告诉我,那种肾上腺素飙升的难受感不会消失。你只是接受这种不适。带着“这会很尴尬”的心理准备去做,但要知道说了总比不说好。你不必说出完美的话——往往根本没有完美的话——但你确实需要站出来发声。

虽然关于反馈的传统观点是公开表扬、私下批评,但这种时候,公开说点什么至关重要:如果看起来最初的那条消息没有被回应,就可能营造出一种这类消息被视为可以接受的环境。如果有人在一群人面前受到攻击,你就需要在同一群人面前支持他们。如果没有人处理这个问题,你们团队的氛围就会变得怪异和不自在。

最好能尽快处理这种情况,但稍后再回过头来处理也没关系:“听着,我感觉这件事一直悬在那里,我真希望当时就处理了,但我想回头再说一下。”Milstein 说,通过处理它,你可以“给这股能量一个出口”。她补充道:“几乎每一次,事后都会有人感谢我在困难的情况下站出来发声。”

下面是 Milstein 的更多技巧:

  • 描述你想要建立的文化,并以此作为参照。例如:“大家都知道,相互尊重是我们这里很重要的价值观。这是我们把事情做成的方式之一。那条消息违反了这些规范。”

  • 给对方一条和你站到同一边的路。例如,如果他们针对一条令人紧张的新闻开了一个伤人的玩笑,要表现出你理解为什么有人会在那个时候开玩笑。“我理解在困难的时候用幽默来调节,但我们要留意,这次会议里的人可能正受到这件事的影响。”

  • 如果是私下谈话,你可以诉诸对方的价值观:“我知道你非常在意公平,所以我想指出你说过的一句话,你可能没有意识到它的影响。”

最后,这件事不应该到你这里就结束。虽然你有能力也有责任去处理文化问题,但这种情况也是一个行为问题。你还可以告诉相关的经理,这样如果这是一种反复出现的模式,他们可以帮忙处理。那是他们的职责,而不是你的。

营造平静

做房间里那个负责任的大人,最后一个要素是:保持冷静。疲惫、压力大的人常常会在如何推进的问题上产生分歧。如果你能保持冷静和建设性,避免指责,其他人也会这样做。

化解,而不是放大

如果你在处理一个大问题,尽量把它变小。如果你在处理一个小问题,*就让它保持小。*当有人带着一个棘手的情况来找你时,保持冷静。提问。弄清楚他们为什么告诉你。他们只是需要发泄一下吗?他们希望你采取行动吗?保持好奇,即使是对你自以为了解的话题。如果确实有问题,要承认它。仅仅是看到你掌握着同样的信息、却似乎并不惊慌,就足以缓解同事的焦虑。

即使你看到了自己可以做些什么,也不要条件反射地做出反应。一个资深的人小题大做,可能会把一件小事闹成一个又大又吵的问题,所以要确定你掌握了所有事实,并且你的加入确实有帮助。如果你的行动会放大局面而不是让它平静下来,那就考虑置身事外。另外,记住第 6 章开头的警告:确保这个支线任务是对你时间的正确利用。

最后,要谨慎选择在哪里分享你的焦虑或沮丧。虽然你可以承认存在问题,但不要让你对这些问题的担忧蔓延到更初级的人身上:让他们背负你的担忧是不公平的,而且如果你让他们不安,你就是在放大问题。这并不是说你必须把担忧藏在心里:你可以向你的经理、关系亲近的同级,或者你在第 5 章中选定的项目参谋倾诉。但要说清楚,你只是在社交性地抱怨,还是希望对方做点什么。尤其是在与其他领导者一对一交流时,要说清楚你是在请求采取行动、在为自己理清思路,还是在分享上下文。他们可能会条件反射地做出反应,放大一件你本来只是想发发牢骚的事。

避免指责

我至今还记得我在生产环境中犯下的最早的错误之一。在更新一条客户记录时,我不知怎么地删掉了他们的整个账户。那年我 22 岁,刚加入团队(也刚进入这个行业),吓得要死,觉得承担这个责任就意味着我短暂的职业生涯就此结束。我的同事 Tim 帮我收拾了烂摊子,我永远不会忘记他的反应:“看新人怎么处理他们的第一次搞砸,总是很有意思。我们都经历过。”我真是如释重负!当然我还是很难过,但胃里那种难受的感觉消失了。如果我的每一位同事都挺过了他们的第一个错误,那我也能。在恢复客户数据这项烦人的任务当中,Tim 还抽出时间对我表达了善意。

一次大故障就是一堂昂贵的培训课,既然你们付出了代价,大家最好都能学到点东西!如果有人犯了错,或者通过弄坏某个东西发现了一个边缘情况,就要营造一个让每个人都能安心复盘这件事的环境。如果你保持好奇、避免指责,你会发现更容易提出这样的问题:

  • 到底发生了什么?

  • 是哪些因素让他们走上了这条路?

  • 有没有他们当时没有、但本可以拿到的信息?

  • 他们的心智模型在哪些地方与现实出现了偏差?

保持一致

你有没有遇到过一个完全捉摸不定的领导?你不知道该如何为和他们开的任何一场会做准备。今天他们只关心项目的高层交付日期;第二天,他们又要你为最细微的技术决策做出解释。他们告诉你某个目标是最重要的业务需求,然后就在你刚调整完项目计划时,他们又把别的事情排到了优先位置。一片混乱。你根本不知道自己处于什么位置。

不要成为那样的领导者。相反,要通过保持一致和可预期,营造一种安全感和平静感。你的同事应该知道,如果他们请你帮忙做某件事,他们可以期待什么。在变化或困难时期,你在工作中的表现和表达方式能让同事安心:是的,变化可能令人害怕,但在大家一起渡过难关的过程中,他们可以依靠你的沉稳。

当你压力很大或工作超出负荷时,就更难保持一致,所以保持一致意味着要照顾好自己。记住图 4-3:在生活中为计划外的事情留一点空间。以一种对你来说可持续的方式工作。这意味着要休假、充分休息,并在工作之外做让自己开心的事。记住,你也是在为同事示范可持续的工作方式。

牢记目标

接下来是作为榜样的高级工程师的第三个特质:记住你们到底是在这里干什么的。这不仅仅是技术!还有一个更广的背景:一家试图达成某些目标的企业,一项你们正着手去完成的使命。在本节中,我们将探讨如何把业务上下文(以及预算上下文)带入你的决策,如何解决用户关心的更大问题的全部,而不仅仅是你们团队的任务。我们还会思考如何以团队而非个人的身份去实现目标。

记住这是一门生意

作为高级工程师,你既要对现在负责,也要对未来负责。你始终要负责打造能在压力下站得住的软件。但你是在为一家有目标的企业(或者非营利组织、政府机构或其他组织)工作。软件是达成这些目标的手段,而不是目的本身。

因地制宜

我曾经参加过一个志愿活动的黑客马拉松,我记得团队负责人看着我的代码说:“哇,还有测试?这,呃,挺好的。”他说得很客气,但很明显,写测试是件不寻常的事——而且并不怎么受欢迎。速度比准确性重要得多,而且这些代码之后是要扔掉的。在他看来,我是在浪费时间。

有时更快的方案更好;有时更稳定的方案更好。如果上市时间对企业的生存至关重要,那么把一个粗糙的第一版推出门,可能比拥有漂亮的代码和架构更重要。5 同样,如果你发布的软件是为了配合一次节日促销或一场重大体育赛事,那么一个不完美的方案要比一个延期的方案好得多。

在故障期间,优先级有时也会改变。也许你们有一条规则:总是对服务进行干净的滚动重启,确保同一时间只有几个实例下线。但当一切都坏掉时,你平常的原则可能就要统统抛到一边:有时最快的做法就是把整个东西关掉再重新打开。一位中级工程师可能会追求一个干净、技术上优雅的修复方案这样的柏拉图式理想,但他们的资深导师会教他们:这种时候要先让系统恢复上线,之后再收拾。

随着业务的变化,你的优先级也会改变。*坦然接受这一点。*这是不可避免的。增长、收购、新市场或者时运的变化,都可能意味着随着公司追求新的方向甚至新的文化,你的目标会被抛弃。如果你不喜欢这样,或者它不符合你的价值观,那么你可能已经不在合适的地方了。但如果你只是一味抗拒变化,你就会把时间都花在不开心上。预料到它,你就会把它当作一个新的挑战来拥抱。

意识到存在预算

你的高工程标准,永远会与企业愿意在好的工程上花多少钱之间存在张力。这种张力并不意味着你应该放弃原则、开始鼓吹粗制滥造的软件,但要把预算这个概念放在心里。记住,别人在人员编制、供应商工具等方面能花的钱是有限的。

不要对预算过分执着:人很容易陷入犹豫不决,纠结某个项目到底值不值这个成本。但要对什么样的支出、节省或新增收入算是“大数目”有个感觉。了解你们公司如何赚钱,知道你们处在景气时期还是紧缩时期。在决定建议组织把时间花在什么事情上时,要把这些事实记在心里。

用心使用资源

我是在 Google 资源充裕的时期“长大”的,所以比本应该的晚了十年才意识到:人员编制是有限的,为一个项目配备人手是有机会成本的。你的技术判断力有一部分就体现在明智地“花费”这有限的人员编制上。

你可能会有一大堆想法:可以在哪里创新、发明新东西,或者让你的某个系统变得更好一点。要确保你选择的是企业真正需要的工作。你们团队的时间和精力是有限的,这样花是对的吗?也请采纳 Dan McKinley 的建议,审慎地决定在哪里花掉你的“创新令牌”:也就是你们公司“做一些有创意的、古怪的或困难的事情的有限能力”。如果你只能在少数几个地方投入,这里是正确的地方吗?

去构建最有用的东西,而不是做起来最好玩的东西。当到了该停止打磨、宣布它已经足够好的时候,就停下来。

记住还有用户

我记得有一次和一个供应商坐在一个巨大的食堂里,周围是数百名同事。我和同事 Mitch 听那位供应商解释,我们一直要求的某个功能现在已经可以用了。但我试过那个功能,它根本不能用。我们来回争论,直到我掏出笔记本电脑演示给他看。

“哦,我明白了,”那位供应商说,“你用的是 Chrome。它在 Firefox 和 Internet Explorer 上是可以用的。”(是的,这是很久以前的事了。)“不过别担心,用 Chrome 的人不多。”

“看看你周围,”Mitch 指着整个食堂回答,“看到这些人了吗?这个房间里的每个人都用 Chrome。”

我见过太多团队为一群虚构的、完美的、根本不存在的用户开发功能。6 要知道谁在用你的软件,以及他们是怎么用的。确保他们能用上你为他们创造的东西,并且他们想要用。

做好这件事的一部分,是那个经典的解决办法:把它写下来!明确你所要满足的确切需求,并广泛地分享这些需求。在开始写代码之前,先让人评审拟定的 API。在开始做用户界面之前,先展示它的原型图。经常沟通进展,展示更新。再说一次,避免 CYAE:无论你是否按规格构建,如果你没能让用户满意,你就是做错了东西。

记住还有团队

关于专注于使命,最后一点是:记住你不是一个人在做这份工作。虽然你可能是团队里最好的程序员、最有经验的工程师,或者解决问题最快的人,但这并不意味着你应该包揽所有问题。你是作为团队的一员在工作,而不是一群相互竞争的个人中的一员。不要成为单点故障,以至于你不在时团队什么都做不成。这是不可持续的。它会掩盖问题。

就像我建议你要有自我认知一样,你也要了解团队的能力。如果你能通过赋能别人做出更好的工作来达成目标,那和你自己解决问题一样是一场胜利。要把你的影响力看作是没有你就不会发生的事情,而不仅仅是你亲自做了什么。

向前看

正如你所看到的,有些时候你的首要任务是尽快把东西推向市场,但在大多数时候,你都是在为更长的时间跨度做规划。你所开发的代码和架构,很可能在 5 年或 10 年后仍在使用。构成你们生产环境的那些相互关联的软件系统,可能会存在得更久,而且每个组件都会影响后续的组件。7 正如 Titus Winters 在 Software Engineering at Google(O’Reilly)中所写:“软件工程就是在时间维度上积分的编程。”要预料到你的软件的影响会长久存在。

你的组织、代码库和生产环境,很可能在你加入之前就已存在。在你离开之后,它们很可能也仍会存在。不要以牺牲未来的速度或工程能力为代价,去为当下做优化。种下一些你自己看不到长大的种子,也没关系。

下面是几种你应该超越当下去思考的方式。

预见你将来会希望自己做过什么

记住我们在第 3 章提过的问题:“未来的你会希望现在的你做了什么?”当你在制定计划或开展工作时,把未来的你和未来的团队也当作利益相关者:毕竟,他们将不得不面对你现在做出的任何决定。

预告即将到来的事

明确你的大方向,即使你还不知道具体细节。举个例子:团队有时会避免宣布旧系统的弃用日期,因为他们还没完全准备好开始向新系统的大规模迁移。但你可以宣布弃用它的意图。如果每个人都知道一两年后会开始迁移,新项目就知道不要再在它上面投入了。有些团队可能会发现自己有空闲时间,甚至不用你开口就迁移到了新系统。现在做一点点工作,就能设定人们的预期、节省他们的时间,并让你将来的弃用项目轻松一些。

收拾整齐

你有没有在一个上一个使用者没有收拾干净的工具棚里干过活?那太可怕了。你拿起电钻,电池却没电了。护目镜不在盒子里;你翻了三个箱子,才在砂光机旁边找到它。地上满是碎屑。在那样的环境里根本不可能进入心流状态。每件事都要花上应有时间的三倍。

现在想想,当你想要的每件工具都触手可及时是什么感觉。你的工作流程就是顺畅。所以,花点时间把你的生产环境、代码库或文档整理好,让下一个来的人用起来就是顺畅。编写测试,让你能在不弄坏东西的情况下重构代码。遵循你们的风格指南,这样照搬你做法的人也会遵循风格指南。不要留下陷阱,比如大家都得记住不能运行的危险脚本,或者在本地改了却没有更新到源代码控制里的配置。让人们可以安全地四处走动。

让你的工具保持锋利

不要仅仅是收拾整齐:要持续投入,让你的环境变得更好。如果你能快速而安全地行动,你在重复性工作上花的时间就会更少,能做的事情就会更多。提高速度也会提高可靠性:你在发现问题或部署修复上每缩短一分钟,就让每一次故障都缩短了一分钟。

寻找那些能让你更快地构建、部署和发布的优化:更小的构建、直观的工具、修复或删除不稳定的测试、可重复的流程、无处不在的自动化。审慎地选择投入的地方:构建工具、平台或流程都需要时间,所以要选择那些真正能带来改变的优化。

创建组织记忆

每当有人离开你们公司,你们就会失去一部分组织知识。如果幸运的话,你们会有一些老员工把历史存在脑子里。但最终,不可避免地,你们的员工会全部换一遍。8 当某个老系统坏掉时,就再也没有人能说:“哦,对,我记得我们以前遇到过这个问题。上次我们是这么做的。”

我的前同事 John Reese 当时是 Google 的首席工程师,他还经常兼任系统历史学家的角色:他整理了一份记录,讲述站点可靠性组织是如何演变的,以及多年来在生产环境中运行软件的方式发生了怎样的变化。为了创建组织记忆,他针对自己最了解的生态系统部分写了深入的文章,然后采访其他人来挖掘过去,记录下那些具有开创性的系统和实践。虽然他现在已经离开了 Google,但这段历史仍由一批新的整理者延续着。

虽然大多数组织都没有专人有意识地记录自己的历史(不过也许我们应该这么做!),但你可以通过把事情写下来,把信息传递给未来。这包括解释你们当时想法的决策记录、包含那些“大家都知道”的显而易见之事的系统图,以及包含来龙去脉的代码注释。无论你以何种方式创建历史,都要包含可搜索的关键词,让未来的人有机会理解你们做了什么、为什么这么做——并想一想,有哪些你知道的东西是未来的人可能不知道的。9

预料到失败

我最喜欢的一份事故复盘,是 Fran Garcia 写的关于他当时的雇主 Hosted Graphite 被一次 AWS 故障搞瘫的报告。我之所以喜欢它,是因为 Hosted Graphite 根本没有使用 AWS,所以团队对自己受到这次故障的影响相当意外。10 他们根本无法预料到这一点。

你的系统中潜伏着多少这样无法预料的故障?假定很多。网络会出故障,硬件会出故障,人也会有状态不好的日子。bug 永远存在。系统中你甚至从未想到过的各部分之间的奇怪交互,也会引发问题。

你无法预料会出错的所有事情,但你可以预料某些事情一定会出错。为它发生时你要怎么做制定计划。把对失败的预期融入你的产品:像测试成功路径一样彻底地测试错误路径,并让产品在得不到预期的响应时做出合理、对用户友好的处理。确保你能在系统行为异常时发现它,并对如何应对有一个计划。

为重大事故提前做规划,约定好在紧急情况下如何协同工作:例如,引入我前面提到的事故指挥系统,并在需要之前就演练响应流程。你的灾难预案总会有某些地方出问题,所以要用混沌工程工具或受控的故障来模拟灾难。演练、游戏日(game day)或桌面推演可以让你发现响应中哪些部分行不通。当然,如果你还没有测试过从备份中恢复,那就当作你根本没有备份。

为维护而优化,而不是为创建而优化

软件只创建一次,却需要维护很多年。如果你有一个二进制程序在生产环境中运行,它就需要监控、日志、业务连续性、扩容等等。即使你打算再也不碰那段代码,技术或监管生态也可能逼得你不得不关心它:想想所有那些为了千年虫(Y2K)、为了支持 IPv6 或 HTTPS、或为了满足 SOX、GDPR、HIPAA 等合规要求而需要更新的老系统。这些不会是我们最后一次遇到颠覆性的变化。11

软件被维护的时间要比创建它的时间长得多,所以不要写难以维护的代码。下面是一些帮助未来的你和未来团队的方法。

让它易于理解

在你编写新代码或设计新系统的那一刻,你对它了如指掌。你们团队的人可能也对它的工作原理有清晰的心智模型。要预料到这些知识每天都会衰减一点。这个系统再也不会像它被创建的那天那样被人理解得那么透彻了。如果那时它就难以理解,那么祝你两年后好运:那时某个东西坏了,你正努力把那个心智模型重新装回脑子里。

要让未来的人理解你的系统,你有两个选择。

一个选择是专注于培训和实践经验。你可以持续开设关于这个系统的课程,确保每个将来可能要维护它的人都受过全面培训,并且积累了足够的时长,能够应对可能出现的任何问题。

另一个选择是,让人们在需要时尽可能容易地理解这个系统。这意味着写文档时以未来的那个人为主要读者:一段清晰、简短的介绍;至少一张大而简单的图(用箭头表示数据流动的方向);链接到他们可能想了解的任何内容。然后尽可能清晰地暴露系统的内部运作。通过工具、追踪或有用的状态信息,让人能看到它在做什么。让你的系统可观测:易于检查、分析和调试。还要让它们保持简单,这是我接下来要讲的。

保持简单

我很喜欢 Martin Fowler 的一句话:“任何傻瓜都能写出计算机能理解的代码。好的程序员写出人能理解的代码。”12 高级工程师有时以为,用最花哨、最复杂的方案就能证明自己的本事。但把东西做复杂更容易。把它做简单要难得多!

怎样才能把东西做简单?在上面多花时间。当你为手头的问题想到一个解决方案时,把它当作“只是第一个”。至少再花同样多的时间去想另一个方案。既然你现在对问题理解得更深了,看看能不能让它更简单:更少的代码行、更少的分支、更少的团队、更少的维护工时、更少的运行中的二进制程序、更少被改动的文件。13 系统预计存在的时间越长,你就应该花越长的时间去尽可能地简化它。让人容易建立起对系统或代码的心智模型。

要警惕那些似乎在奖励复杂性的组织。Staff 数据科学家 Ryan Harter 写过,他见过有人为了证明自己在做困难的工作而打造复杂的方案。“我见过有人把机器学习塞到根本不该用它的地方,就为了搞一次风光的发布。”他告诫道:“真的,我们应该追求的是用简单的方案解决复杂的问题。工作的复杂性是一种需要承担的成本,而不是要去最大化的东西!”

当你在处理本质上就很复杂的问题时,要有意识地决定把复杂性放在系统的什么地方:比如那个包含着难以理解的业务逻辑或性能优化、令人望而生畏的模块。要让纵观整个系统的人可以把那个组件当作一个神奇的黑盒,并据此推理其他所有部分;这样当需要理解和修改那个复杂部分时,也只有一个地方要去。

为下线而构建

总有一天,你的系统会被关掉。对到时候负责它的人来说,这会有多难?他们是否需要深挖其他系统的逻辑,解开那些牵涉业务逻辑的错综枝蔓,并追踪代码来弄清他们访问的是哪些数据?还是会有一个干净的接口和一次简单的切换?

你们的架构会演进,而你的组件会沉淀到中间层。虽然现在直接把新的系统、库或框架接进来可能更快,但要想想之后会发生什么。以后能否在不拆毁别人在它之上构建的东西的情况下替换掉它?

想象一下,你知道 10 年后要由你本人来下线这个组件。未来的你不会比现在的你更闲,那么你能做些什么来帮帮他?你是否可以加一个干净的接口,让人容易看出哪些客户端还在使用某个服务,或者在设计上让两个正在集成的系统之间保持一点距离?如果你从一开始就着手构建一个易于下线的组件,你会顺带得到一个模块化、易于维护的东西。

培养未来的领导者

培养你的团队是未来规划的重要组成部分。由你来解决问题或领导项目,往往比别人来做更容易、更快,但这并不意味着你应该大包大揽。你的初级工程师就是未来的高级工程师。给他们学习的空间,给他们亲自动手、解决越来越难的问题的机会。第 8 章会更多地讲述如何持续提升他们的技能水平。

最后,我再引用一句 John Allspaw 在《On Being a Senior Engineer》中的话:

别人想与你共事的程度,直接反映了你作为工程师的职业生涯会有多成功。做那个人人都想与之共事的工程师。

如果你从本章中只能记住一件事,那就记住这句话:*衡量成功的标准,是别人是否愿意与你共事。*如果他们不愿意,就重新审视你的做法。

本章回顾

  • 你的言行现在更有分量了。要深思熟虑。

  • 投入时间积累知识和专业能力。能力来自经验。

  • 对自己知道什么、不知道什么要有自知之明。

  • 努力做到一致、可靠、值得信赖。

  • 在没有别人站出来时,要习惯于挺身主导,包括在危机中或在目标模糊的项目里。

  • 当需要有人说点什么时,就说出来。

  • 营造平静。把问题变小,而不是变大。

  • 了解你们的业务、预算、用户需求和团队的能力。

  • 通过提前规划、保持工具锋利来帮助未来的自己。

  • 把事情写下来,即使它们是“显而易见”的。

  • 预料到失败,并为之做好准备。

  • 设计易于下线的软件。

  • 衡量成功的标准,是别人是否愿意与你共事。


  1. 有时这种说法还暗含着“看起来不够极客”或“长得不像工程师”的意思;我们都应该意识到自己的隐性偏见。但我在这里是对那些真心想帮助自己或同事提升技能的人说的。 ↩

  2. 我在 Google 工作了 12 年后换了一份新工作。Google 以所有东西都使用自己内部的技术栈而闻名,所以我很依赖这种模式匹配。我经常在白板上画系统图,然后问:“有没有一个东西看起来有点像这个,而你们会在这种场景下用它?哦,原来 Envoy 是干这个的!好,明白了!” ↩

  3. 如果你在想“我不会犯错,因为我有能力又细心”,那么当你真的犯错时,那种当头一棒的感觉会糟糕得多得多。 ↩

  4. 事故指挥系统由消防部门在 20 世纪 60 年代引入,如今美国的大多数应急服务机构都用它来协调灾害响应。它定义的角色之一是事故指挥官,这个人的工作不是去灭火,而是协调和指挥。它很适合那种混乱的或跨多个团队的软件故障。 ↩

  5. 但不要以发布危及、剥削或伤害他人的软件为代价,去帮助一家企业生存下去:公司买的是你的时间和精力,而不是你的道德准则。我们会在第 9 章更多地讨论价值观。 ↩

  6. 就像一些朋友说的,是“完美球形的用户”。 ↩

  7. 可以把它想成忒修斯之船:多年来每一个单独的组件都可能被替换掉,但根本的系统仍在延续。这全是形而上学的架构。 ↩

  8. 又一艘忒修斯之船!人都换了,但组织依然存在。 ↩

  9. 可以从桑迪亚国家实验室(Sandia National Laboratories)的那份报告中获得启发。该报告研究如何创建图形化信息,以阻止一万年后的人类——那时现在的语言早已消亡——干扰核废料储存库。你不需要想那么远,但想象一下,如果你所开发的系统 10 年后仍然存在:人们需要知道什么?他们可能会怎样意外地伤到自己? ↩

  10. 如果你好奇的话:这次故障导致 Hosted Graphite 的大量用户同时变慢,他们通常是短连接的连接一直保持打开,连接数不断增加,直到达到负载均衡器的上限,导致其他任何人都无法连接。那份报告读起来很有意思。 ↩

  11. 2038 年就要来了! ↩

  12. Refactoring: Improving the Design of Existing Code,Martin Fowler 等著(Addison-Wesley)。 ↩

  13. 如果代码行少到又变得晦涩和复杂了,那你就做过头了。我们追求的是易于理解,而不是炫技式编程。 ↩