返回介绍

2.5 多少只眼睛才能驯服复杂性

发布于 2024-10-11 21:30:12 字数 2556 浏览 0 评论 0 收藏 0

从宏观上观察到集市模式能极大加速代码排错和演化是一回事,但从微观上,结合开发者和测试者的日常行为,完全理解这是怎样做到的以及为什么会这样,就另是一回事了。本节(在本文首版的三年后写就,采纳了阅读本文首版并对照了他们自身行为的开发者们的观点)我们将仔细审视一下其真正机制。对技术不感兴趣的读者可以直接跳到下一节。

理解这个问题的关键在于要弄清楚这个现象:如果报告 bug 的用户对源码不关心,则其报告通常不会很有用。对源码不关心的用户,往往报告的都是表面症状,他们把自己的运行环境当成是理所当然的,他们不仅省略了重要的背景数据,而且很少给出重现 bug 的可靠方法。

这里隐含的问题是开发者和测试者对程序有着不匹配的思维模式,测试者是从外往内看,程序员是从内往外看。对于不开放源码的软件开发,开发者与测试者往往局限于自己的角色,各说各话,都对对方倍感沮丧。

开源开发打破了这种困境,由于大家都有真实的源码,开发者和测试者很容易发展出一个共享的表达模式并进行有效的交流。事实上,一个仅描述外部可见症状的 bug 报告,和一个直接关联到源码的分析型 bug 报告,对开发者而言简直是天壤之别。

只要能有一个对出错条件在源码级别上的提示性描述(即便不完整),大多数 bug 在大多数时间里就很容易被发现。如果你的 beta 测试人员中有人指出“在第 n 行有一个边界问题”,或者仅仅指出“在条件 X、Y 和 Z 下,这个变量会溢出”,你扫一眼那部分代码,往往很快就能准确找到出错模式并得出修正办法。

所以,如果 beta 测试人员和核心开发人员都能意识到源代码的作用,就能极大增强双方沟通和合作的效果。相应地,即便在合作者很多的情况下,核心开发人员的时间也会节省很多。

开源方法之所以能节省开发者的时间,另一个原因是开源项目所常采用的沟通模式,以前我习惯使用“核心开发人员”这个术语,主要想区分一下项目核心人员(通常很少,最常见的是一个人,典型情况是一到三人)和外围人员,外围人员通常由 beta 测试者和潜在的贡献者组成(通常会达到数百人)。

传统软件开发在组织结构上的根本问题由 Brooks 定律一语道破:“在一个已经延期的项目上增加人手,只会让项目更加延期。”更为一般地讲,Brooks 定律指出,随着开发人员数目的增长,项目复杂度和沟通成本按照人数的平方增加,而工作成果只会呈线性增长。

Brooks 定律是建立在经验基础上的,人们发现,bug 很容易集中在不同人写的代码的交互接口上,沟通/协调的开销会随开发者间接口数的增加而增多,也就是说,问题规模和开发人员间的沟通路径数相关,即和人数的平方相关(更精确地讲,应该是 N(N-1)/2,N 代表开发者数目)。

Brooks 定律(以及随之而来对开发团队规模的恐惧)建立在这样的假设上:项目的沟通结构是一个完全图 [2] ,即人人之间都沟通。但在开源项目中,外围开发者实际工作在分散而并行的子任务上,他们之间几乎不交流;代码修改和 bug 报告都会流向核心团队,只有在那个小的核心团队里才会有 Brooks 开销。 6

源码级 bug 报告非常有用的理由还有很多,但都围绕着这个事实:一个错误可能会导致多种症状,因用户使用方式和环境不同而有不同表现。这种错误往往正是那种复杂而狡猾的 bug(比如动态内存管理错误或者非确定中断窗口的产物),这些 bug 很难重现,也很难通过静态分析找到根源,导致软件中长期存在一些难以解决的问题。

如果测试者能给出一个源码级的 bug 报告(这个 bug 可能会引起多种症状),尽管只是一个不确定的试探性描述(比如“看上去第 1250 行有一个信号处理窗口”或者“你在什么地方把这个 buffer 清零的”),也会帮助开发人员找到解决那些多症状(症状看上去也许并不相关)问题的关键线索,要知道开发人员往往离代码太近而不能发现问题。这种情况下,要想精确说出是哪个 bug 导致了哪个外部可见问题,通常很难甚至不可能,但如果经常发布的话,就没有必要去知道了,其他合作者会很快去查看他们发现的 bug 是否被解决了。很多情况下,人们会关心导致问题消失的源码级 bug 报告,但很少关心是哪次补丁修复了它。

对于复杂的多症状错误,要想从表面症状追踪到实际 bug,往往有多种路径,开发者或测试者追踪时经由何种途径,取决于千差万别的个人运行环境,并且该环境会随时间产生不确定的变化。实际上,每个开发者和测试者在寻找病状症结的时候,都是在“半随机”(semi-random)的变量集合上对程序状态空间进行采样。越是隐蔽和复杂的 bug,就越难从技能上保证采样的对症性。

对于简单和容易重现的 bug,重点要放在“半”而非“随机”上,此时,调试技能以及对代码和架构的熟悉程度会大显身手。对于复杂的 bug,重点就要放在“随机”上了,这种情况下多人共同追踪 bug 远比少数几个人循序追踪要有效得多——即便这几个人的平均技能要高很多。

当从表面症状追踪到 bug 的难度不一且难以预测时,并行纠错的效果会更加显著。一个开发人员会循序选取追踪路径,可能一开始就选了一条困难的路径,当然也可能是容易的路径。而在快速发布模式下,如果多人同时尝试对 bug 进行追踪,很可能某人立刻就发现了最简单路径,然后在比别人短得多的时间内逮住 bug。项目维护人员看到后会发布一个新版本,这样在其他更难路径上追踪该 bug 的人就可以停下来,以免浪费更多的时间。 7

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文