我在Facebook、WhatsApp和Twitter都有由技术领导的团队。我也是一名有执照的私人飞行员,我发现从飞行中可以学到很多有益于软件工程团队的东西。在这篇文章中,我想分享其中的一些经验教训,同时也为你提供对航空的洞察力。
在开始飞行训练之前,我研究的一件重要事情是-飞行有多危险?比较的一个明显标准是汽车。事实证明,总体来说,航空是最安全的交通方式,与汽车相比,每十亿英里的致命事故减少了约60倍。通用航空(GA),包括像我将要驾驶的那种小型飞机,大约比开汽车危险19倍,但也比骑摩托车安全25%²。
与汽车相比,GA的危险性要高出19倍,这看起来似乎很多。但飞行本质上比开车复杂得多。飞行时,你正在离地面数千英尺的高空翱翔,你不能就这样靠边停车,以防出现问题;你必须继续前进。然而,它比摩托车更安全,只比汽车差19倍。我发现这是一个非常好的安全记录。在我的培训过程中,我亲眼目睹了是什么让航空如此安全。我发现在安全性、健壮性和风险管理方面有很好的课程可以很好地转化为软件工程。我想描述其中的四个经验教训,它们将帮助您构建更好的软件,而不会减慢您的速度。
飞行员的某些元素并不像其他元素那样令人兴奋。甚至在坐上飞机之前,飞行员都要经过一次彻底的飞机外部检查,称为飞行前检查。在我的飞行俱乐部,作为飞行前的一部分,学员飞行员被要求清洁挡风玻璃。当我觉得它足够干净的时候,我有时会省钱。我的教练不会不提醒我-干净的挡风玻璃会帮助我们更容易地发现其他飞机,从而导致更安全的飞行。有一天,他用一种非常实事求是的语气说:“我发现,擦挡风玻璃做得更好的学生原来是更好的飞行员。”在那一刻,我并没有大惊小怪。但那天晚些时候,当我在脑海中重温飞行课程时,我突然意识到-清洁挡风玻璃是现代飞行员精神的有力例证。
驾驶已经不再是航空早期那种虚张声势的事业了。第一次世界大战发生在赖特兄弟完成世界上第一次成功的动力飞行仅仅十年之后。当时,飞行员被视为超凡脱俗的英雄,他们利用自己优越的反应能力和空间定向技能完成复杂的任务。随着时间的推移,许多重点已经转移到保持卓越的运营、遵循标准程序和正确处理小事上。阿波罗8号的指挥官弗兰克·博尔曼(Frank Borman)用他聪明的语录帮助传播了这一信息。
“一名优秀的飞行员用他卓越的判断力来避免陷入需要使用他的超凡技能的情况。”
清洁挡风玻璃的比喻恰如其分地适用于软件工程。当我工作中的一位导师离开公司时,我请他分享一些关于如何建立最好的软件工程团队的临别智慧。他说:“每个人都知道软件工程中的最佳实践是什么。但没有人愿意花时间追随他们。遵循最好的工程实践,你就会成为最好的团队。“。换句话说,与航空相似,花时间在软件工程的一些不吸引人的方面工作是很重要的。这包括-确保清理未使用的代码;花时间编写功能规格并使规格保持最新;确保您的构建和部署是单一步骤或理想的连续性;拥有良好的测试覆盖率;使内部监控和调试工具与外部代码一样高质量;等等。对于那些正在寻找可行的指针的人们,我强烈推荐“实用程序员”这本书和乔尔的一些作品。
没有什么比通过无线电与空中交通管制人员交谈更让你感觉自己是一名飞行员了。对于一个外行来说,“航空语言”感觉完全是一种不同的语言,因为所有的行话和简短的短语。对于飞行员来说,这可能是其魅力的一部分。然而,在表面之下,无线电通信规则的目标不是听起来很酷,而是在尽可能准确的情况下进行简短的交流。简洁性很重要,因为同一区域的所有飞机通常都在同一频道上通话。长篇大论夺走了其他飞行员宝贵的播音时间。然而,比简洁更重要的是尽可能准确,以避免任何沟通失误。无线电通信中的一切都围绕着这些目标,例如:
北约语音字母表(如Alpha、Bravo、Charlie)用于区分发音相似的字母。
这些数字(如风向320°)总是以单独的数字发音,以避免音频在不合时宜的时候中断,例如说“320”。
数字9的发音是9,而不是9,这是为了与单词nein区分,在德语中,nein的意思是no。
这些都是有趣的例子。但我觉得特别优雅和可以转移到软件工程中的是在航空中使用特定的术语来表示非常具体的事情。当控制器说“保持{位置}”时,指令非常清楚。你不会感到困惑,你是需要停在这个位置之前,还是停在这个位置上,还是就在这个位置之后。“攀登并保持{新高度}”非常简洁地传达了你需要攀登,然后停留在那个高度。一旦你到达了新的海拔高度,就不会留下解释的余地了。类似地,当飞行员说“求救,求救,求救”时,接收器立即知道有紧急情况,而不必猜测情况的严重性。
我也发现软件工程团队需要共享词汇表。在团队同步过程中,团队成员经常会问这样的问题:“项目X完成了吗?”或者“做Y需要多长时间?”由于完成的定义不同,这就为错误沟通打开了空间。一个人对完整的定义可能是基本功能已经完成。然而,另一个人的定义可能是产品经过了彻底的测试,并且涵盖了所有的边缘情况(包括错误重试)。你可以想象,这两个人对上述问题的回答会大相径庭。这可以通过共享词汇表来解决。例如,我的队友提出了波兰的层次框架,客观地描述了不同层次的完备性。
一级功能:用户可以完成基本任务。例如,用户可以在应用程序上发布图片。
级别2经过打磨:用户发现体验经过打磨。例如,当用户发布图片时,他们会看到进度指示器。一旦帖子被成功上传,他们就会收到视觉和触觉反馈。
级别3令人愉悦:用户体验提升到下一个级别。例如,用户发现上传速度非常快,因为图片是“乐观上传”的。所有的情况都会得到处理;网络错误会导致自动重试;如果没有网络,帖子会保存为草稿,这样用户以后就可以返回。
使用哪种精确的调平系统并不重要。但是,拥有一个共享的框架将有助于团队讨论单个功能需要什么级别的改进,以及需要多长时间才能做到这一点。
每一起报道的航空事件,无论大小,都会由坠机国家的国家委员会进行彻底调查。我曾经参加过一个飞行安全研讨会,讲者在会上谈到1977年臭名昭著的特内里费机场灾难,当时两架波音747客机在雾蒙蒙的跑道上相撞,造成583人死亡。总而言之,这架荷兰皇家航空公司的喷气式飞机是在将空中交通管制(ATC)的路线指示误认为起飞许可后开始起飞的。另一架由泛美航空公司运营的喷气式飞机仍在同一跑道上,即将离开!研讨会的演讲者在解释完故事后停顿了一下,问与会者:“你们认为这是谁的错?”这是荷航机长曲解空中交通管制指令的过错吗?是不是泛美航空公司的班机几分钟前错过了滑行道出口,导致他们没有在跑道上?难道空管在传达指令时口音很重,而且让两架喷气式飞机在同一跑道上滑行时离对方这么近,这是不是空管的过错?事实是,导致这场灾难的是一连串的事件,其中任何一件都可以完全避免整个噩梦。
航空业遵循一种无可指责的文化,调查的重点是找出导致这起事件的所有促成因素,并建议做出改变,以防止各类问题再次发生。出于这个原因,作者纳西姆·塔勒布(Nassim Taleb)提到航空业是反脆弱体系的一个例子-一个不仅能抵御冲击,而且能在冲击中变得更好的体系。
这对于软件工程来说并不是全新的,但值得重申。一个好的软件工程团队必须利用每一次事件(错误、停机,甚至是险些错过)作为学习机会。应该对事件进行详细的事后检查,重点是防止同样类型的事件再次发生。实现这一点的一个非常有用的框架称为DERP(代表检测、上报、补救和预防)。
补救措施:如果再次发生此问题,可以采取哪些步骤来解决该问题?这些步骤可以自动执行吗?
预防:哪些改进可以消除此类故障再次发生的风险?你怎么能优雅地失败呢?
联邦航空法规(FAR)是美国联邦航空局(FAA)规定的规则,管理美国的所有航空活动-从小型滑翔机到大型喷气式飞机。就像大多数法律文件一样,这是一本冗长而枯燥的读物,然而,有一项规定我发现特别有力。
(A)指挥飞机的机长直接负责该飞机的操作,并是操作该飞机的最终权限。
(B)在需要立即采取行动的飞行中紧急情况下,主管机长可偏离本部的任何规则,至应付该紧急情况所需的程度。
那可是赋予机长很大的权力啊!飞行员不仅可以完全控制飞机,而且如果紧急情况需要,他们还可以事先获得许可,可以违反手册上的任何规则。联邦航空局为什么要这么做?这一规定是基于这样一种信念,即参与其中的任何人都不会比飞行员自己对飞行中的情况有更好的评估。拥有完全的权力有助于飞行员对紧急情况做出更快的反应。它还减少了模棱两可和推延责任,这是一种心理现象,当其他人在场时,人们不太可能承担责任。
清晰的所有权在软件工程中同样重要。从表面上看,这条建议经常被认为是琐碎的,而且已经被很好地理解了。我也有同样的感觉,直到我们的团队决定遵循一个正式的框架来量化和改进团队的软件和运营状况。作为此框架的一部分,我们填写了详细的发现表,其中列出了团队拥有的每个“资产”(一段功能或代码);以及每个“资产”的所有者、测试覆盖率、错误列表、警报和度量。我们发现,正如我们所怀疑的那样,大多数资产都有明确的所有者。然而,令人大开眼界的是,我们的团队和合作伙伴团队之间的“边界”上几乎没有所有者不明确的资产。要么我们的团队认为另一个团队对这些资产负责,要么反之亦然。有趣的是,所有者不明确的资产也是造成大部分错误和效率低下的原因。当我们与合作伙伴团队合作澄清所有权和SLA时,情况有了很大改善。
我希望这些课程能引起您的共鸣,并帮助您构建更好的软件。在航空业,犯错的后果是非常清楚的--人会死。这种游戏中的皮肤已经推动航空业在安全性、健壮性和更好的工程方面走在了前列。在大多数软件公司中,赌注感觉并不高,而且通常有很好的理由快速行动并打破™。然而,重要的是要认识到,软件正在吞噬世界,很多人在生活中越来越依赖软件来做关键的事情,特别是在COVID之后。当你的视频聊天软件出现错误时,这不再仅仅是一个烦人的问题了。我希望这种对您客户的同情能促使您以软件构建工艺为荣,并努力追求卓越。