编程语言与软件工程2015upedu.org
为什么优秀开发者写出糟糕代码:一项观察性案例研究
Why Good Developers Write Bad Code: An Observational Case Study
入门 · 约 45 分钟读完前置知识:软件工程基础、代码质量概念、项目管理常识
导读
这篇论文通过观察性案例研究,分析了一个复杂软件模块开发项目,探讨为什么优秀开发者会写出糟糕的代码。研究识别出组织因素、流程问题(如瀑布模型)、文档不足、时间压力、团队沟通与知识分布等导致代码质量下降的原因,并提出了文档化、跨团队协商、流程审查、知识共享等改进建议。
HN 关注点:因为探讨了开发者普遍共鸣的问题:为什么技术好的人也会产出烂代码,讨论焦点集中在组织因素、瀑布流程的弊端以及如何避免类似失败。
HN 评论精选
这几条评论里:支持 2 质疑 1 补充 1
支持总结了论文的关键建议,强调文档、协商机制、流程审查、知识共享和谨慎对待外部干预。
TL;DR 关键建议:项目完成后确保每个软件项的“做什么”和“为什么”被妥善记录;对于相互依赖的软件模块并行开发,建立协商机制解决团队冲突;确保开发团队了解CMMI-ACQ或ISO12207流程以便与第三方谈判;与第三方谈判潜在易受攻击的组件时确保测试人员参与;计划组织范围内的流程审查以发现孤立流程并促进信息流动;为支持长期修正或惠及多模块的修正计划专项预算;严格截止日期的项目风险高,应仔细监控避免最后一刻的计划外活动;团队成员应在正式流程信息流与非正式人际互动间保持平衡;确保知识适当分布(如结对编程);外部人员对团队动态的干扰应非常谨慎。
PaulRobinson查看英文原文
TL;DR key recommendations: - Once a project is completed, the team must ensure that the “What” and “Why” of each software item are properly documented. - In the cases of parallel development of inter-dependent software modules set up a negotiation table to solve conflict between the development teams. - Make sure that the development team is aware of the CMMI-ACQ or ISO12207 processes for negotiating with third parties. - Make sure that testers are involved when negotiating with a third party for a potentially vulnerable software component.  - Plan organization-wide process reviews to detect isolated processes and to promote information flows between processes. - Planned special budget items to support long lasting corrections or corrections that are likely to benefit many modules.  - Projects with strict deadlines are risky, and should be carefully monitored to avoid last minute unplanned activities. - Team members should maintain a careful balance between the flows of information within formal development processes and informal human interactions. - Team members should make sure that knowledge is appropriately distributed amongst them. For example, pair programming is a practice which can promote knowledge sharing. - Any intrusion into the team dynamics by outsiders should be done very carefully.
支持讽刺了团队因重用失败项目的文档而再次采用瀑布流程,认为这是荒谬的。
“该项目是第二次尝试 overhaul 这个复杂模块。第一次尝试在2010到2012年间进行,但完全集成的软件无法工作后放弃。由于是第二次尝试,许多规格和设计文档可以重用。因此,开发基本上遵循了瀑布流程,因为预计第二次问题会更少。” 我喜欢这种纯粹的疯狂。1. 写一个计划。2. 执行计划。3. 项目完全失败。放弃。4. 决定再试一次。5. “这次会容易!我们有现成的计划可以用!” 这就像使用藏宝图,没找到宝藏,现在却认为既然已经有了地图,找到宝藏会更容易!
munificent查看英文原文
"The project was a second attempt to overhaul this complex Module. A first attempt was made between 2010 and 2012 but was abandoned after the fully integrated software did not work. Because this project was a second attempt, many specifications and design documents could be reused. Accordingly, the development has essentially followed a waterfall process, as few problems were expected the second time around." I love the sheer insanity of this. 1. Write up a plan. 2. Execute the plan. 3. Total project failure. Abandon it. 4. Decide to try again. 5. "It will be easy this time! We've got an existing plan we can use!" It's like using a treasure map, not finding any treasure, and now thinking it will be even easier to find the treasure now since you already have a map!
质疑质疑论文未深入分析复杂性的根本原因,如文档规模、遗留代码、模块划分和测试硬件成本等。
一篇有趣的文章,我们需要更多这样的文章,但我觉得作者没有深入理解复杂性的根本原因。例如,他们既引用了进度/预算压力,又引用了文档不足。不完整的文档有“数千”页。真的有人认为即使一半的团队会阅读“完整”的文档(成千上万页)吗?完整的文档会加速开发吗?即使考虑到生产和消费完整文档的成本,它会加速开发吗?模块的大小真的是本质复杂性,还是部分问题在于他们是在遗留代码上构建?作者提到与其他团队和第三方软件的互操作是摩擦的主要来源。为什么其他模块如此庞大复杂,以至于由单独的团队维护?这是本质复杂性,还是之前试图通过打补丁发布造成的?如果他们使用其他实践/语言/工具,模块是否会更易于管理,从而需要更小的团队?访问测试硬件和管理测试人员是另一个摩擦来源。购买更多测试硬件的成本是多少?在我之前工作的公司,有手动QA部门和资金不足的测试硬件预算,将硬件预算翻倍可以减半QA薪资预算(主要是因为你不需要每天多次热插拔设备),并缩短测试周期。情况是这样吗……
arohner查看英文原文
An interesting article, and we need more like it, but I feel the author didn't go far enough in understanding the root causes of complexity. For example, they cite both schedule/budget pressure, and insufficient docs. The incomplete docs were "thousands" of pages. Does anyone really believe even half the team would read "complete" documentation, that are thousands upon thousands of pages? Would complete docs speed up development time? Would they speed up development time even taking into account the cost of producing and consuming complete docs? Is the size of module truly essential complexity, or is part of the problem that they're building on legacy code? The author mentions interop with other teams and third party software as a large source of friction. Why are other modules so large and complex that they're maintained by separate teams? Is that essential complexity, or was it caused by previous attempts to patch their way to release? Would the modules be more manageable, and hence, require smaller teams, if they used other practices/languages/tools? Access to test hardware, and managing the test personnel was another source of friction. What is the cost of buying more test hardware? In previous companies where I've worked, with manual QA depts and under-funded test hardware budgets, doubling the hardware budget would allow halving the QA salary budget (primarily because you don't need to hot-swap equipment several times a day), and shorten test cycles. Is that the case here? Further, how much manual test is truly necessary, and how much is caused by the developers not writing automated tests?
补充列举了导致好开发者写出坏代码的多种可能原因,包括遗留代码、第三方组件、时间压力、沟通问题等。
随便说说,个人认为一些可能的原因包括:对遗留代码库的恐惧或缺乏理解;对第三方组件的恐惧或缺乏理解;时间压力;需要处理的边缘情况太多;团队内部沟通问题或风格差异;缺乏领域经验来理解那些边缘情况;缺乏时间构建正确的设计,或在设计不合适时重建;项目管理压力反对大设计 upfront,要求“现在就开始”,而实际上需要更有组织;需求不明确;对工作或公司不再感兴趣;缺乏代表所有可能使用场景的用例;实际上不是他们的代码坏,而是他们耦合到了本身坏/泄漏/易出错的系统。
mpdehaan2查看英文原文
Offhand and IMHO, some possibles can be: - fear or lack of understanding of a legacy codebase - fear or lack of understanding of a 3rd party component - time pressure - too many edge cases to handle - intra-team communication issues or stylistic differences - lack of domain experience to understand those edge cases - lack of time to build the correct design, or rebuild a design if it won't fit - project management pressure against big-design-up-front and to "start now" when making something more organized is required - unclear requirements - not interested in work or company anymore - lack of use cases representing all possible usage scenarios - it's actually not their code that was bad, but they are coupled to bad systems that are themselves bad/leaky/error-prone
相关资源
从这篇论文所有 HN 讨论帖的全部评论里整理出来的链接。
历次讨论
- 2015Hacker News 讨论帖173 分 · 80 评
同领域还值得读
Google 的软件工程(2017)
Software Engineering at Google (2017)
介绍了 Google 的软件工程实践,包括其单一代码库(monorepo)、几乎全部开发在主干进行而非分支、代码审查、构建系统 Blaze、协议缓冲区等工具与流程,并讨论了频繁重…
编程语言与软件工程2017 · 1,127 分 · 465 评 · 引用 15入门 · 约 45 分钟编辑精选Peter Naur:编程作为理论构建 (1985)
Peter Naur – Programming as Theory Building (1985)
Peter Naur 1985 年的经典论文《Programming as Theory Building》提出:编程的本质不是写代码或文档,而是在程序员头脑中构建对程序及其运行…
编程语言与软件工程2016 · 629 分 · 74 评入门 · 约 45 分钟编辑精选SciPy 1.0:Python 科学计算的基础算法
SciPy 1.0: fundamental algorithms for scientific computing in Python
这篇发表于 Nature Methods 的论文介绍了 SciPy 1.0——Python 科学计算生态的基石库,涵盖其核心算法模块(优化、积分、插值、线性代数等)、软件架构与社…
编程语言与软件工程2020 · 387 分 · 98 评入门 · 约 45 分钟编辑精选Lisp 的历史(1979)
History of Lisp (1979)
这是 Lisp 发明者 John McCarthy 于 1979 年为 HOPL(编程语言史)会议撰写的回顾文章,讲述 Lisp 的起源、设计动机与早期演进,文中也涉及 if 表…
编程语言与软件工程2018 · 352 分 · 44 评入门 · 约 45 分钟编辑精选使用 NumPy 进行数组编程
Array Programming with NumPy
这篇 Nature 文章介绍 NumPy 的数组编程模型及其在科学计算中的核心作用:以 ndarray 为中心,通过向量化操作让 Python 高效处理多维数组。
编程语言与软件工程2020 · 318 分 · 134 评入门 · 约 40 分钟编辑精选