许多软件开发者正在学习数据科学,以分析其客户的数据。越来越多人意识到,他们也可以用同样的技术来回答自己的问题,例如:
- 这个项目何时可以发布?
- 我们应用的哪些组件最需要测试?
- 应该由谁来修这个缺陷?
- 我的 API 中哪些部分对用户来说最难用?
过去 15 年里,软件工程领域的实证研究激增,用于探索这些问题,这在一定程度上得益于 GitHub 和 Stack Overflow 等网站数据的可获得性。本文将先呈现几个具有代表性的结果,然后再更详细地探讨其中三种方法的背后原理。
如果您希望进一步了解如何使用数据科学为自己的项目获得类似洞见,请与我联系。
数据科学与软件工程:示例
先从一个影响所有大规模开展数据科学工作的人的发现说起:Yuan 等人的研究指出,简单测试即可预防分布式数据密集型系统中的大多数严重故障。他们考察了 Cassandra、Hadoop MapReduce 等系统中的故障,发现:
- 几乎所有故障都只需要 3 台或更少的计算节点即可复现。也就是说,调试集群通常不需要真正的集群。
- 错误日志通常包含足够的数据来实现复现。
- 多数灾难性故障原本可以通过对错误处理代码进行简单测试而轻松预防。
最后一点最出人意料。专业人士通常会测试在一切顺利时其分析代码是否正常工作,但很少测试在出错时它是否能做对的事情。在开发过程中仅增加少量此类测试,就能避免许多后续的麻烦。
另一个大规模结果来自 Altadmri 和 Brown 的研究,他们分析了英国高中生的 3,700 万次程序编译尝试。接着他们询问教师学生最常犯的错误是什么,并发现:
- 教师之间并不就学生最可能犯的错误达成一致。
- 更重要的是,教师的预测与学生实际犯错之间的相关性很弱。
当然,数据挖掘并不是在编程中生成有用的循证洞见的唯一方式。2013 年,Andreas Stefik 的团队发表了系列研究中的第二项,探讨某些语言是否更易于学习。作为基线,他们在研究中加入了一种虚构语言,其关键词是随机生成的。
出乎意料的是,Java 和 Perl 等大括号语言对新手而言在识别上与随机生成的语言一样困难。Python 和 Ruby 都明显更容易学习,而对每个新特性都进行语法 A/B 测试后才加入的 Quorum 则更胜一筹。Andreas 在这期有趣的播客中讨论了该结果,以及为何编程语言设计者对可用性关注甚少的原因。
识别安全缺陷报告
作为研究如何开展的一个例子,Fayola Peters 在 LERO 使用基于文本的预测模型,在大型系统的缺陷跟踪器中查找安全缺陷报告,以便优先处理。在一项研究中,她使用了 Chromium、Wicket、Ambari、Camel 和 Derby 项目的数据;这些项目共包含 45,940 份缺陷报告,但只有 0.8% 属于安全缺陷报告。
部分安全缺陷由人工标注,可用来训练分类器以检测未标注的安全缺陷。朴素贝叶斯和随机森林等技术是出发点,但通过筛选特定关键词往往能提高通用模型的效率。最重要的检验是:基于带有安全标注的项目构建的模型,能否在其他项目中找到类似缺陷。结果令人鼓舞:Peters 发现其分类器的效果足够好,具有实际应用价值。
我的补丁会被接受吗?
再看第二个例子:公司希望其修改能被项目采纳,以避免自行维护代码;志愿者也希望知道自己的补丁是否有机会被接受。由于补丁提交与接受之间往往间隔较长,Bram Adams 及其在蒙特利尔理工学院的团队一直在构建模型来预测哪些补丁会被接受。
与许多数据科学项目一样,这项工作首先要从多个来源获取并清洗数据,包括 Git 仓库和 Gerrit 代码评审。然而,对于采用基于邮件评审的项目(如 Linux 内核),收集数据意味着要抓取邮件列表存档,并使用诸如补丁校验和或变更行集合交集等启发式方法将补丁与讨论匹配。即便有 GrimoireLab 等工具的帮助,仍会存在多版补丁被评审、或一个补丁拆成多部分分别评审的情况。与所有数据科学工作一样,由分析人员来构建模型,而其中的假设会对最终结论产生强烈影响。
第二步是决定要考察哪些变量以及各自采用什么度量,例如:
- 补丁质量
- 补丁开发者的经验
- 评审流程(例如评审意见与评审者数量)
- 评审质量(例如评审的细致程度)
- 评审耗时
- 补丁作者与评审者的互动(例如友好还是激烈)
仅这六项就可能用到从生存分析到情感分析的一切方法。一旦确定了要测量的内容,您就可以应用 DataCamp 课程教授的数据科学工具。鉴于真正的目标是预测未来补丁的接受情况,最直接的方法是逻辑回归,但也有许多其他选择。
最后,您可以衡量变量重要性,以确定每个变量对补丁被接受的影响。这必然在一定程度上是定性的,因为目标是找出开发者可以采取哪些措施来提高其工作进入产品的几率。与往常一样,需要谨防将相关性误认为因果关系,但即便是一些简单的建议(比如“不要在提交说明中全用大写”)也能带来实实在在的改善。
寻求帮助
过去 20 年中,程序员的工作方式发生的最大变化并非他们使用的语言,而是几乎普遍依赖于 Stack Overflow 来提问与获取答案。阿德莱德大学的 Christoph Treude 及其合作者一直在开发方法,让这类网站更加有用。
他们的起点是 Stack Overflow 数据转储。在进行了一些探索性统计(如词句数量、最常见词、词频-逆文档频率 TF-IDF 等)后,下一步是查看 Stack Overflow 主题中哪些词与更高的投票数、更高的采纳率以及更高的浏览量共同出现。
由于软件文档包含许多不完整的句子和代码元素,现成的自然语言处理库常常出错。对于非英语撰写的软件文档,解析难度更大,因为技术术语往往仍使用英语。也就是说,它混合了两种自然语言与代码元素。必须结合使用特定启发式和更先进的建模技术来处理这类情况。
将这些要素组合起来,就可以构建一个工具:输入一个 Python 模块的名称,输出基于 Stack Overflow 主题提炼出的关于该模块的有意义句子。更进一步,Treude 及其同事利用词语之间的语法依存关系,自动找到解释如何执行某项任务的软件文档,并自动识别能够完成该任务的代码片段。
结论
我们对软件开发的许多“共识”往往源自强烈的观点与喧嚣的声音,而非证据。如前所述,这一状况正在改变:每年都有数百项高质量研究问世,以证实一些看法(如“代码评审确实是发现缺陷的最佳方式”),并挑战另一些看法(比如“测试驱动开发并不像某些人认为的那样有效,goto 语句其实并不真的有害”)。
“工程”被定义为“运用科学方法创造有用之物”。如果这一定义成立,那么得益于数据科学,软件开发或许终于正在走向成为一门真正的工程学科。如果您希望看到相关课程,了解如何将数据科学应用于软件开发,请告诉我们。
延伸阅读
每年都有研究者在诸如 Mining Software Repositories 等会议上发布数十项新发现。其中一些论文集仍被学术付费墙所阻隔,但越来越多的研究者会提供预印本。
如果您希望快速了解全貌,2010 年的著作 Making Software 汇集了当时最有趣成果的“精选集”。而新近的三部曲 Perspectives on Data Science for Software Engineering、The Art and Science of Analyzing Software Data 和 Sharing Data and Models in Software Engineering 对同类主题提供了更广泛、更新的覆盖。另有 Derek Jones 正在撰写新书 Empirical Software Engineering Using R。