爱荷华大选 App 投票酿闹剧的反思:为什么我们在软件工程方面如此糟糕?
【编者按】在不久前,美国2020总统大选民主党候选人初选在爱荷华州拉开序幕,在爱荷华州民主党党团会议上,一个App引起了一场大混乱。按照预期,这款大选投票App会在投票2小时后快速公布结果,但该App发生故障,直到第二天也未给出结果。
作者 | Jake Voytko
编译&责编 | 夕颜
出品 | CSDN(ID:CSDNnews)
该App报告显示出现技术问题和不一致性。爱荷华州民主党发表声明,宣布他们并未遭受网络攻击,但是在使用App时遇到了技术问题。
原来爱荷华州向Shadow公司支付6万多美元,开发了一款应用程序,该应用程序应能够使地区官员更轻松快捷地传输党团会议结果。
然而,这款App却在当天酿成了一场闹剧,搞砸了一场大选,差点弄垮了一家公司。
之后,本文作者撰文,通过这场App开发事故,向软件工程领域发出灵魂一问——为什么我们在软件工程方面如此糟糕?
问题出在哪?
一周后,大家才对当初的意外有了更清楚的了解。原来这款App是通过Beta测试程序而不是主流App商店分发的,用户很难通过一般流程安装App。安装后,它也很有可能并无响应。更糟糕的是,一些会议所处的地点无法连接互联网,这让无法连接互联网的App形同虚设。他们用上了备用计划:使用会议小组一直在用的电话线,但不幸的是电话线发生了拥堵。
随后,上图漫画就开始在软件工程师中迅速传播开来。我也看到了。一句话总结这张漫画(以及我在Twitter上看到的观点):“我不太知道该怎么说,但是我们整个领域都不擅长自己在做的事,如果依赖我们,每个人都会死。”软件工程师实际上并不相信这一点。但听起来这点似乎是对的。这是什么意思呢?
意思是说:当失败所引起的后果不严重时,我们很乐意创建软件。一般的软件如果足够好,就可以正常运行。然而,大多数软件的性能糟糕到足以让我们对错误习以为常。这不是偶然的。软件工程界中许多常见的行为都滋生于这样一个环境中,人们对故障很宽容,新功能也足够吸引人。且失败的代价是廉价的。加入市值排名前10的上市公司提供的任何在线服务在两个小时内完全离线,一周之内人们就会遗忘这件事。人们以“快速前进取得突破”和“上线并迭代”之类的借口逃避现实。
回报是非常丰厚的。在许多网络公司中,每个用户少量的收益乘以数百万(或数十亿!)的用户,就是一个巨大的数字。对于拥有面向消费者的App或网站的公司而言,这是有利可图的。部署成本高昂,但毕竟有限,分发几乎是免费的。消费者软件工程行业需要权衡取舍:我们降低部署速度恰好足以使缺陷率保持在较低水平,但不能降低到一定水平。
我将其称为软件开发的“网站经济模型”:当部署的收益很高而重试的成本很低时,管理层会设置激励措施来优化高短期特征速度。这反映在现代项目管理实践及其实施中,我将在下面进行讨论。
但是正如我之前所说,“当失败的后果微乎其微时,我们很乐意创建软件。”当失败的代价不菲时,就像在爱荷华州那样,它会造成可怕的后果。常见的软件工程实践源于互联网经济模型,当违反该模型的假设时,软件工程师就会对我们的工作感到失望。
网络公司中的软件工程如何工作?
让我们假设一下QwertyCo这家面向消费者的软件公司,它每年的收入为1亿美元。通过与其他公司进行比较,我们可以估算QwertyCo的规模。博客系统托管网站WP Engine在2018年的ARR(会计收益率)为1亿美元。BlueApron在2018年的收入为6.67亿美元。因此QwertyCo是一家中型公司。它有几十到几百名工程师,并且是非公开的。
首先,让我们看看QwertyCo的项目管理经济学。管理人员深知,无法在朝夕之间创建一个功能。他们需要在软件质量、给定时间和实现速度之间进行权衡。
软件质量对他们有多重要?不太重要。如果QwertyCo的网站每年关闭24小时,他们预计将总共损失273,972美元(假设正常运行时间与收入呈线性关系)。有趣的是,该站点经常停机15分钟,但似乎没人在乎。如果某个功能使该站点瘫痪,他们将回滚该功能,然后稍后重试。重试的成本非常低。
QwertyCo的新功能有多大价值?根据我个人的观察,一个工程师一个月可以通过优化站点将收入改变-2%-1%。每个工程师每个月有机会获得100万美元的QwertyCo增量收入。诸如A / B测试之类的技术甚至可以减轻错误:几周之内,你可以检测到负面或中立的更改并删除这些功能。糟糕的功能不会话费很多钱,因为它们持续的时间有限,而胜利是永远的。即使是很小的胜率,对 QwertyCo也是有吸引力的。
考虑到不利因素和不利因素,QwertyCo应何时上线一项功能?经济学认为,即使功能有很高的风险,只要它们偶尔会带来收益,就应该上线。因此,每个项目都会变成一个优化游戏:“ 这个功能每天可以带来多少收益?”,“实现这个项目需要多长时间?如果我们拿出X会怎样?如果我们取出X和Y会怎样?有什么方法可以使这个部分耗时更少?”
现在,让我们从软件工程师的角度审视一个软件项目。
软件工程师的主要商品是时间。安全的软件工程话费很多时间。一旦项目的复杂性阈值降低,它将被分为很多阶段。设计人员或产品经理需要确定软件项目的范围,并在必要时转换为技术设计或计划,以及在必要时划分为子任务。然后是写代码、测试、审查代码、记录统计信息并将其与仪表板集成在一起,在必要时发出警报,并在必要时进行手动测试。另外,编码通常会花费被称为重构的前期成本:修改现有系统以使其更易于实现新功能。实现“小型”功能所需的时间可能只有编码的10-30%。
工程师的时间花在哪了?系统故障花费的时间最多。站点停机是一种全局状况。最有经验的工程师会在此时停下手头的活,让站点再次运行。但是花在这个上的时间并未增值。他们的项目现在进度落后,对他们的反映很差。如何减少停机时间?书面测试、监视、警报和手动测试都可以降低发生这些灾难性事件的风险。
工程师的时间还花在哪里了?忙于修改细微的bug。一些错误很严重,但不常见。如果用户执行罕见的操作,也许会丢失数据。当工程师收到此错误报告时,他们必须停止一切并修复错误。这又会累及当前的项目,并且随着时间的推移可能会导致重大损失。
因此,经验丰富的软件工程师开始重视代码质量。他们想要验证代码是否正确。这就是工程组织采用表面上会减慢开发速度的措施的原因:代码审查、持续集成、可观察性和监视等。错误被发现的时间越晚,代价就越大,因此工程师在早期发现错误上投入了大量资金。他们还着重于简化实现的重构。简单的实现不太可能出现错误。
因此,管理层和工程层质量上往往意见相悖。管理层希望错误率较高(但足够低),工程师希望错误率较低。
如何将其纳入项目管理?产品和工程将项目分解为涵盖整个项目的小任务。项目长度是任务数量和工程师数量的函数。最常见的是,该项目将花费很长时间,并且会通过删除功能进行调整。然后工程师执行任务。通常,大家会在“冲刺”中完成任务实现。如果冲刺时间为两周,则每个任务都有一个两周计时器。但是任务通常会花费比想象更长的时间。工程师会做出艰难的优先级决策,以按时完成任务:“如果编写基本测试,并且在计划中不进行重构,我可以在冲刺阶段结束时完成这项工作。” 冲刺流程不断对时间成本施压 ,这意味着工程师可能会牺牲质量,也可能在冲刺规划会议中宣告失败。
有人会说,我在冲刺过程中太过强硬了,他们是对的。这确实是时间成本激励的结果。冲刺过程只是多次施加时间压力的一种便捷方法:一次在确定整个项目范围时施加,并在每个任务中施加一次。如果根据产品增加的价值来评判产品小组,那么他们自然会与工程师协商实现时间,而无需管理层的任何额外支持。工程师也被激励去迅速实施,但是他们可能会尝试从长期而不是短期的角度进行优化。这就是为什么企业经常激励提高短期速度的原因。
因此,通过设置适当的激励结构,高管可以在一开始就得到他们想要的东西:他们可以定下功能和预计的日期,并且产品和工程技术自然会协商实现该功能的必要条件。“我希望你在2个月内实现无帐户结帐。”产品和工程部门将写出所有2周的任务,并删繁就简,直到他们可以上线称为“无帐户结帐”的项目。这会产生较低的断裂风险,并且在成熟之前可能会经历几次迭代。但是中断是暂时的,功能是永远的。
如果违反网站经济模型的假设会怎样?
如我之前所说,“当失败的后果不重要时,我们很乐意构建软件。”“上线并迭代”和“快速前进并取得突破”的口号指向这一假设。但是,我们都可以想象一下,这样做的代价是昂贵的或不可能的。在极端情况下,建筑物倒塌可能导致数千人丧生,并造成数十亿美元的损失。2020年的爱荷华州民主核心小组的案例还算轻的。如果核心小组失败,每个人都会在一天结束时回家。但是民主党却没有机会在不花费大量时间、金钱和谅解的前提下开第二次会议。
说明:在本部分中,我将用“高风险”作为“没有重复的情况”和“昂贵的重复情况”的简写。
将网站经济模型应用于高风险状况会怎样?随机举例:你正在编写一个用于报告爱荷华州小组会议结果的App。你会分几步来写?测试和验证App吗?
首先是工程:你必须同时编写Android App和iPhone App。报告是核心要求,因此服务器是必需的。复杂的核心规则必须同时编码到客户端和服务器中。系统必须将结果报告给最终用户;这是你必须编写的另一个接口。民主党可能有必须写入App的验证和报告要求。另外,如果在党团会议期间服务器停机就糟糕了,因此你需要在系统中写入某种可观察性。
接下来,你如何验证App?一种选择是用户测试。你将向潜在用户显示该App的预设图片,并向他们询问诸如“您认为此界面的用途是什么?”,“如果您想完成某个人物,您会点击什么?”之类的问题。设计始终需要迭代,因此可能要进行多轮用户测试,然后你的模型才有可能成为高质量的App。大公司通常在实现大型功能之前进行多轮测试。有时,甚至在还没开始写代码之前就会根据反馈取消一项功能。用户测试很便宜。找5个人在15分钟内回答问题就可得到5美元的礼品卡有多难呢?唯一要注意的就是能代表爱荷华州核心小组意愿的测试用户。
接下来,你需要验证端到端的体验:必须安装并设置该App。民主党必须了解如何取得结果。应用一旦歘状况,需要有备份计划。一次好的测试可能需要拉起“实践小组”,爱荷华州民主党的员工需要下载该App,并在给定日期报告结果。这可以发现系统性问题或设定预期。实现功能中,这也可以分阶段进行。
值得注意的是,互联网上到处都是“捣乱分子”,你需要确保这些不会干扰核心小组。你可以验证收到的结果来自爱荷华州核心小组吗?此外,互联网上到处都是撒谎的人,这些人会撒谎并造成伤害。它可以抵御拒绝服务攻击吗?如果不能,是否有一个后备计划?谁负责宣布备用计划正在执行并将其传达给预备队?如果个人入侵核心人群的账户会怎样?如果公司内部没有安全专家,则有必要对运行核心讨论或选举的应用进行全面的第三方安全审查。
接下来,如何确保软件中没有错误报告或错误汇总结果?同理,民主党也应该对你持怀疑态度:即使你的公司有“捣乱分子”,民主党也可以对结果充满信心吗?结果应可通过纸质备份进行审核。
好的,暂停一一列举问题。你还需要大量时间和资源来验证此功能。
爱荷华州党团会议App的制造商被要求在2个月内完成项目,报酬是60,000美元。他们有四名工程师。6万美元根本无法支付四个工程师两个月的薪水和福利,更何况还要算上所有业务费用支出。金钱和时间不等价。他们也几乎没有任何外部帮助。
假设为了在规定时间完成任务,你遵循了删除和缩小任务的通用做法。你将尽一切可能节省时间。应用审核通常需要不到一天的时间,但最坏的情况是可能需要一周或未通过。因此,我们跳过这一点:核心党团会议的工作人员将需要通过Beta测试链接下载该应用。即使安全审查是免费的,实施所有建议仍将花费太长时间。你没有进行安全审查。也许你会在设计服务器时向设计师支付1000美元来制作App模型和徽标。你将计划进行一轮用户测试(之后可能在时间表的压力下跳过这一步)。上线、迭代!反正你可以在下一次党团会议之前修复就好了。
另外,写代码总是比你预期的更长!你总是遇到阻力。首先,干部小组的规则会有歧义。在将数字解决方案应用于模拟世界时,总是会发生这种情况:现实世界可以处理歧义和矛盾,而数字世界则不能。干部小组可能会针对这些的问题发布规则说明,而这会拖延时间。干部小组也可能在最后一秒钟更改规则。这会导致你在截止日期之前临阵修改App。而且,多个开发人员也会产生协调成本。每个编码人员是否对移动和服务器开发都百分百满意?每个人都完全熟练地使用React Native吗?JS?打字稿?客户端-服务器通信?该选择哪个框架和库?每个“不”都会增加开发时间,以进行协调和学习。每个人都对你用的测试框架感到满意吗?甚至你一开始写了测试代码,但后来由于App更改被删除。
时间不等人。2个月了,火烧眉毛,你必须要跨过终点线。
在网站经济模型中,在大火中跨越终点线是很好的。毕竟,大火无所谓,你越过了终点线!你可以在几周内解决问题,然后转到下一个项目。
但是在爱荷华州的党团会议上,这把火很重要。傍晚时分,民主党核心小组被投诉这个App的电话打爆。你得到的结果是不可能的或重复报告的。不久之后,软件工程师就开始开心地传播漫画,叫嚣着爱美国2020总统大选民主党候选人初选不该给这个App付费,而纸是唯一值得信赖的投票技术。
我们学到了什么?
这篇文章让我有一点个人经验教训:在计划项目时,我需要确定重做的成本。过去,我凭直觉做这件事,但其实应该更明确点。这种形式化使得确定哪些任务无法牺牲变得更加容易。这符合我过去的行为;我曾经在移动机器人领域工作,机器人项目实施周期长,故障造成的损失可能很高。我们花了很多时间来增加可观察性,并采用万无一失的方法来节制和终止失控的系统。我还在消费者网站领域工作了十年,失败的后果成本更低。我更愿意承担短期债务,并在遇到临时故障时继续前进,尤其是在重做成本低且不太可能丢失数据的情况下。毕竟,我很愿意这样做。我们的行业也有解决这些问题的技巧。“Premortems”就是一个例子。这些事我应该做得更多。
从积极的一面来看,软件工程专业以外的一些人会发现,有时软件项目的进展非常糟糕。政务流程应用开发的投资人会问:“我们怎么知道不会发生和爱荷华州党团会议一样的情况?”他们可能会偶然发现一些试图教会非工程师如何雇用工程师的文献。例如,美国国防部有一个名为“检测敏捷BS”的指南(PDF警告),该指南为非工程师提供了在谈判合同时检测危险信号的工具。创业者论坛到处都是非技术出身的创始人,他们在这里寻求(并收到)有关雇用工程师的建议。
软件工程行业什么也没学会。爱荷华州党团会议给了这个行业一个机会。我们可能将研究“昂贵的失败成本”假设下应如何改变我们的基本流程。我们不会抓住这个机会,我们也不会因此而成长。面向消费者的软件工程行业无法应对失败的风险。实际上,我们欢迎失败的计划。如果外界对提高特定领域的代码质量感兴趣,他们应该监督这些领域。它不会是第一个:健康保险流通与责任法案(HIPAA)和萨班斯法案(Sarbanes-Oxley)是影响网站经济模型公司工程技术的法规案例。监管可能远远不够,但却是必要的。
但是,是的。这就是我们说的意思:“我不太知道该怎么做,但是我们整个领域都对我们所做的事情并不擅长,如果你依靠我们,每个人都会死。”我们的行业在失败的代价很小,并且鼓励迅速采取行动的环境中生长。但当重做的成本很高或无法重做时,这套流程将无法发挥作用。
原文链接:
https://www.bitlog.com/2020/02/12/why-are-we-so-bad-at-software-engineering/
本文为CSDN编译,转载请注明出处。