`

工程师忽略的隐形成本

 
阅读更多
原文地址:http://www.iteye.com/news/30031



有时候我们说,“实现这个功能,我只花了几个小时”。但是完成之后,我们发现每隔几周,我们要么在修复该功能的bug、向另一个工程师解释,要么做客服回答问题、以解释其工作原理。维护该功能总的投入时间要远远超过最初开发的几个小时。

软件开发中内化的最艰难教训之一就是额外复杂度所带来的隐形成本。有时候,复杂度在问题领域只是固有的。为了匹配乘客和司机,通过调整价格来平衡供求是一个复杂和痛苦的问题。因此,在扩大一个社区和维护社区质量的时候,把问题和答案疏通到喜欢回答和看问题的人们那里,也是如此。或者像是开发一个兼容所有设备的富文档编辑器以支持实时协作。这是固有的复杂度,我们需要根据产品做出调整以取得成功。

但是其它时候,和我们较劲的复杂度恰恰是我们自己产生的复杂度。我们用新编程语言写代码,很少人了解它,现在我们不得不维护它。或者我们增加了额外的基础架构,因为我们尝试从Hacker News看到的、热门新技术,但是它失败了,这是我们当初没有想到的。或者我们引入了一个很少人使用的功能,但是修复和bug报告就花掉了极不对称的大把时间。

额外的复杂度暴露了很多隐形成本。在开发软件时,我们所做的决定不只是决定了我们当前的开发速度。它们还要反映出我们花在维护上的时间和努力程度。

复杂度的隐形成本

太多复杂度增加了认知负荷,并产生了做完事情的额外阻力。它以很多不同的方式渗入到团队里——大部分是直接渗入到代码、系统和产品复杂度里,但是间接地渗入到了组织的复杂度里。我们逐个看看这几种不同类型复杂度的隐形成本。

代码复杂度

代码复杂度不只是随着代码行数的线性函数而增长——它组合式地增长。在复杂的代码库里,每行代码可能与其它很多行代码交互和影响。我们对于组合式增长难以有足够的认识,这就是为什么我们倾向于严重低估完成大型软件项目所需要的时间。这也是重写项目有时候会大幅延期的主要原因。

当代码过于复杂的时候,它将变得难以扩展、难以理清其中缘由、难以修复bug,很难理清追踪错误来源的依赖和数据流向。工程师或许会积极地避免代码库最复杂的部分,即使它是可以做某种修改的、最有逻辑的地方,也要选择绕弯来解决。他们或许避免把那些地方都组合起来,即使这项工作有着很大的影响。

系统复杂度

工程师喜欢摆弄新玩具,要么因为好奇,要么因为他们认为新技术可能为解决他们的紧迫问题提供了银弹。当Pinterest在2011年刚开始扩容网站以应对快速增长时,他们只有3个工程师的后端小组却使用了6种不同的存储技术(MySQL、Cassandra、Membase、Memcache、Redis和MongoDB)。他们实验每项新技术的诺言都是解决现有系统的某些限制。但是,每种新解决方案都以其自身特定方式失败了,为了管理和维护而投入了更多时间和努力。最终,团队明白了,增加更多机器而不是更多技术,更能简化扩容,因此他们消除了Cassandra和MongoDB之类的系统,强化了架构的已有组件。

把基础架构切分为太多系统,会带来很多隐形成本。注意力被分散到了多个系统。对于每个系统来说,更难以整合资源以开发可复用的资源库,更难以为日常工作招聘新人,更难以理解具体的失败模式和每个系统的性能特点。每个系统的抽象最终变得更弱,因为没有可投入的太多时间。当工具和抽象太复杂、或太多的时候,让团队去理解和探索将变得困难。

产品复杂度

产品复杂度可以导致一个不明确的版本、或引发缺乏产品聚焦的无节制野心。它希望在很多地方是优秀的,而不只是在一个核心领域,这种欲望使其不能向新用户明确地解释产品的意图。产品复杂度引发了更多的代码和系统复杂度——团队增加更多代码、更多基础架构以支持新功能。当产品外围宽泛时,增加一个新功能或修改现有功能,将需要放大很多的努力来理解和适应旧的功能。

过于复杂的产品意味着有更多的代码分支,更多要考虑的问题、更多的需要团队解决的bug反馈。工程师和数据科学家需要分析更多的变量、做更多的一次性的报表,而不是集中于核心用户行为的理解上。工程师需要投入更多时间来提供功能空间和提高效率。每个人最终在更多的项目中进行切换。投入在维护所有这些功能上的时间,并不是重新投入代码、偿还技术债务、加固抽象的时间。

组织的复杂度

代码、系统和产品复杂度,依次产生了组织的复杂度。团队需要雇佣更多人来处理和维护已开发的所有东西。越大的团队意味着越多的沟通成本、越多的协调和和越低的总体效率。招聘过程本身,涉及的所有面试和汇报,消耗了团队很大比例的时间。当然,所有新员工不得不被培训才能上岗。

雇佣更多人的替代方法,就是将工程师组成划分成更小的团队——或许甚至创建了一人小组——来承担较多代码、系统和产品外围的工作。这降低了沟通成本,但是一人小组有他们自己的成本。一旦遇到难题,就完全拖延了项目中的唯一人手,因为有更少的人来分享这些低谷期,这种体验对于士气是有害的。与其他人合作的机会少了,会伤害到工作场所的快乐和员工的留任。除非每个人比较自觉,而且主动询问反馈,否则个人收到的工作反馈将更少,因为分享相同项目上下文的人更少了。减少的反馈能够降低代码质量、或因疏忽导致的复杂度引入到代码库或基础架构里。

如何应付复杂度

Tony Hoare在1980年图灵奖的演讲中建议,“构造软件设计有两种方法:一种是简单,明显地没有缺陷;另一种方法是使其复杂,却没有明显的缺陷。”提到了由于复杂度而导致的非明显的缺陷是如何伤害我们的,以及我们该如何应对这些成本?

下面是你能够用到的一些策略:

    为简单而优化。抵制增加更多复杂的主张。深思维护成本。要自问,为了解决20%的问题而引入的复杂是否值得,或者80%的解决方案已经足够了。
    为你的团队或产品定义一种任务说明以统一思想。在Team Geek,Brian W. Fitzpatric和Ben Collins-Sussman解释了他们是如何辅导Google Web Toolkit(GWT)团队、并鼓励他们写下任务说明的。接下来发生的、对于任务说明的内容和形式的争论,表明了首席工程师并不真正认同产品方向!他们被迫面对、协调不同、并最终达成了,“GWT的任务是为用户彻底提升web体验,让开发者使用现有的Java工具在任意现代浏览器里构建高性能的AJAX。”如果他们不能尽早找出这些区别,随之而来的努力上的分散又有多少呢?
    用较小的构建块组成大型系统。Google就是个例子,致力于构建健壮的核心抽象,然后被非常宽泛的应用程序广为使用。他们有基础的构建块,像Protocol Buffers、Google File System和远程程序调用的Stubby服务器。基于这些构建块之上,他们还建立了其它抽象,比如MapReduce和BigTable。在此之上,包括大型web索引、Google Analytics站点追踪、Google News聚合、Google Earth数据处理、Google Zeitgeist数据分析在内的数以千计的应用程序,还有很多程序都是这样构建的。
    清晰地定义模块和服务之间的接口。模块和服务的退耦,将减少能够产生一堆代码的组合复杂度。在Amazon,Jeff Bezos于2002年宣称,公司将转向面向服务的架构,所有团队只能通过服务层级的接口彼此交流。虽然这个转变造成了本身巨大的开发成本,但是它强制分离了代码和服务背后的逻辑,为现在极度成功的Amazon Web Services的建立提供了便利。
    优先偿还技术债务。我们总是在信息不完全的条件下开发软件。做为条件变化的响应,代码库在增大,熵也在增大。增加的复杂度成为了未来开发的代价。在开发日常上预算时间可以减少这项成本。很多工程师和团队在项目之间预算这项时间,不过召开一次性的会议会有帮助。我过去在Quora组织过一次Code Purge Day(代码消除日)活动,工程师在这一天全部关注删除无用代码的工作。我们在积分牌上追踪代码消除的进度,这使得删除你自己的代码更有趣味。
    使用数据修剪没用的功能。在Yammer,当工程师或产品经理发现在代码重构时,强化或保留一个功能将花费不菲的时间时,他们将查看使用数据,以确定这项功能是否真正被使用了。如果没有,他们将和团队一起决定,他们是否应该只是砍掉这个功能以降低总体工作量。与简化的代码是怎样减少技术债务一样,这个策略也减少了技术债务。
    基于主题对进行中的项目分组。使同事彼此分享同样的环境,更容易地参与到设计讨论、代码评审或构建可复用的资源库。所有这些活动有助于提供检查和平衡掉单个人或其他人所引发的问题。

当我们为学校课程开发软件时,我们有着世界的过于简单的视角——维护任意复杂度的成本随着下课而消失了。但是在我们的职业生涯中,糟糕的软件决定将产生数年负担的影响。

不要使事情复杂化。

原文地址(source):http://www.theeffectiveengineer.com/blog/hidden-costs-that-engineers-ignore
分享到:
评论

相关推荐

    企业中的十一大隐形成本.pdf

    企业运营中的成本管理是至关重要的,尤其是在竞争激烈的市场环境下,隐形成本往往容易被忽视,但它们对企业利润的影响不容小觑。以下是对企业十一大隐形成本的详细解释: 1. **会议成本**:会议是企业决策和信息...

    图像隐形水印综述(图象隐形水印,数据隐藏)

    ### 图像隐形水印综述 #### 一、引言 随着互联网的普及和技术的发展,数字媒体内容(如图像、音频和视频等)在日常生活中的应用越来越广泛。与此同时,数字媒体作品的复制与传播变得异常便捷,这为版权所有者带来...

    淘宝隐形降权检测

    淘宝隐形降权检测是电商运营中的一个重要概念,尤其对于依赖淘宝平台销售商品的商家来说,了解这一机制至关重要。淘宝为了维护市场公平竞争和消费者权益,会采取一种名为“隐形降权”的措施,针对某些违规或者表现不...

    基于环境控制角度的隐性环境成本计量探析

    环境成本的计量与控制是企业持续发展过程中一项关键而复杂的任务。随着环保法规的日益完善和公众环保意识的提高,企业如何有效地计量和控制其环境成本变得尤为重要。本文主要探讨了如何通过自然资源损失的方式来计量...

    整合网络安全,实现成本缩减和企业保护最大化

    但安全基础设施的重新架构面临着许多隐形成本,这些可能抵消掉潜在的节省。许多隐形成本来自变更现有防火墙以支持下一代功能时所需的叉车式升级,因为它涉及大量的时间和精力。通过在不影响现有安全技术的前提下,以...

    隐形相机

    隐形相机

    加隐形水印软件

    WaterMark.exe 加隐形水印软件

    电子相册 模板 Flash 隐形的翅膀

    《电子相册模板Flash——隐形的翅膀》 在数字化时代,电子相册作为一种创新的存储和展示个人照片的方式,越来越受到人们的欢迎。本资源“隐形的翅膀”是一款以Flash技术为基础设计的电子相册模板,它以其独特的动态...

    成本控制新思维——企业战略成本管理.docx

    3. 隐形成本忽视:企业往往忽视如协调沟通成本、官僚成本等隐形成本,这些成本可能对企业效率和利润产生重大影响。 二、战略成本管理的实施步骤 1. 分析行业价值链:了解企业在行业中的地位,评估各环节盈利能力,...

    北京隐形耳机 隐形耳机介绍【详解】.docx

    北京隐形耳机 隐形耳机介绍【详解】.docx

    电脑增加一个隐形硬盘

    `>NUL`表示忽略任何错误信息。 - `IF EXIST O:\NUL GOTO DELETE`: 检查是否已经存在虚拟驱动器`O:`,如果存在,则跳转到`:DELETE`标签处执行删除操作。 - `SUBST O: E:\RECYCLED\UDrives.{25336920-03F9-11CF-8FD0-...

    隐形文件夹

    隐形文件夹是一种特殊的文件夹类型,它在操作系统中并不直接可见,从而提供了额外的安全性和隐私保护。这种技术常被用于存储敏感数据或个人文件,确保它们不会被未授权的用户轻易发现或访问。"SuperHidden.exe" 文件...

    lenses 隐形眼镜预测数据

    标题 "lenses 隐形眼镜预测数据" 暗示了这是一个与隐形眼镜相关的数据集,用于预测某种特定的属性或结果。描述中的信息简洁,但我们可以从中推测该数据集可能包含了关于隐形眼镜的各类参数,比如度数、材质、舒适度...

    网神之网络隐形衣 Aeolus

    网神之网络隐形衣是针对目前严峻的网络安全环境研发的具有创新思想和专有技术的新型网络安全套件。 目前,网络安全环境异常严峻:病毒泛滥,黑客横行,各式各样的网络攻击手段日新月异,层出不穷;由此产生的网络...

    隐形眼镜数据-机器学习

    在IT领域,特别是数据分析和机器学习的实践中,隐形眼镜数据集是一个经常被引用的经典案例。这个数据集主要用于训练和测试机器学习模型,尤其是决策树算法。在这个数据集中,每个样本代表一个患者的隐形眼镜推荐问题...

    2012最新版淘宝隐形降权探测软件

    2012最新版淘宝隐形降权探测软件 1、对于宝贝很多差不多上千宝贝的店铺 “降权宝贝”这个数据会出现问题,不用理会,这是淘宝的问题,淘宝的数据干扰! 2、不管什么情况下 隐形降权宝贝的数据是绝对正确的! 3、...

    隐形眼镜专业考试题目.doc

    隐形眼镜是一种特殊的视力矫正工具,其专业知识涵盖广泛,包括材料分类、佩戴方式、功能划分、生产制作工艺以及生理影响等多个方面。以下是对这些知识点的详细解释: 1. 隐形眼镜按照材质可分为硬性隐形眼镜、软性...

    20210616-海通证券-医疗保健设备与用品行业:隐形正畸方兴未艾,黄金赛道未来可期.pdf

    而这些厂商向上游延伸的趋势,比如进入膜片制造环节,以保障供应链的稳定性并降低成本。 中国隐形正畸市场的增长潜力巨大。市场规模在过去几年中迅速扩大,从2015年的2亿美元增长到2020年的15亿美元,预计到2030年...

    隐形眼镜数据集

    根据给定的信息,“隐形眼镜数据集”主要涉及的是一个决策树的数据集,通过该数据集可以构建决策树模型,用于预测或分类特定情况下适合佩戴何种类型的隐形眼镜(如果有的话)。接下来,我们将从数据集中提取关键信息...

Global site tag (gtag.js) - Google Analytics