PRF:20171007 A Large-Scale Study of Programming Languages and Code Quality in GitHub.md

@qhwdw 啊啊,终于粗粗校对完了,好累。译者更累吧。
为什么会选这种这么专业的论文来翻译啊? @lujun9972 @oska874
This commit is contained in:
Xingyu.Wang 2018-06-28 18:07:47 +08:00
parent 289e8f5871
commit ab05333e7f

View File

@ -70,7 +70,7 @@
不允许隐式类型转换的编程语言使用一个类型判断算法比如Hindley ^[10][15] 和 Milner^[17][16] 或者,在运行时上使用一个动态类型检查器,可以在一个编译器(比如,使用 Java中判断静态类型的结果。相比之下一个类型混淆可能会悄无声息地发生因为它可能因为没有检测到也可能是没有报告出来。无论是哪种方式允许隐式类型转换在提供了灵活性的同时最终也可能会出现很难确定原因的错误。为了简单起见我们将用 <ruby>隐含<rt>implicit</rt></ruby> 代表允许隐式类型转换的编程语言,而不允许隐式类型转换的语言,我们用 <ruby>明确<rt>explicit</rt></ruby> 代表。
<ruby>内存分类<rt>Memory Class</rt></ruby>  表示是否要求开发者去管理内存。尽管 Objective-C 遵循了一个混合模式,我们仍将它放在管理的分类中来对待,因为,我们在它的代码库中观察到很多的内存错误,在第 3 节的 RQ4 中会讨论到。
<ruby>内存分类<rt>Memory Class</rt></ruby>  表示是否要求开发者去管理内存。尽管 Objective-C 遵循了一个混合模式,我们仍将它放在管理的分类中来对待,因为,我们在它的代码库中观察到很多的内存错误,在第 3 节的 RQ4 中会讨论到。
请注意我们之所以使用这种方式对编程语言来分类和研究是因为这种方式在一个“真实的世界”中被大量的开发人员非正式使用。例如TypeScript 被有意地分到静态编程语言的分类中它不允许隐式类型转换。然而在实践中我们注意到开发者经常有 50% 的变量,并且跨 TypeScript —— 在我们的数据集中使用的项目)使用 `any` 类型这是一个笼统的联合类型并且因此在实践中TypeScript 允许动态地、隐式类型转换。为减少混淆我们从我们的编程语言分类和相关的模型中排除了 TypeScript查看 [表 3][55] 和 [7][56])。
@ -117,45 +117,50 @@
我们从简单明了的问题开始,它非常直接地解决了人们坚信的一些核心问题,即:
**RQ1. 一些编程语言相比其它语言来说更易于出现缺陷吗?**
#### 问题 1一些编程语言相比其它语言来说更易于出现缺陷吗?
我们使用了回归分析模型,去比较每个编程语言对所有编程语言缺陷数量平均值的影响,以及对缺陷修复提交的影响(查看 [表 6][64])。
[![t6.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/t6.jpg)][65]
**表 6. 一些语言的缺陷要少于其它语言**
我们包括了一些变量作为对明确影响反应的控制。项目年龄Project age也包括在内因为越老的项目生成的缺陷修复数量越大。提交数量也会对项目反应有轻微的影响。另外从事该项目的开发人员的数量和项目的原始大小都会随着项目的活跃而增长。
*表 6. 一些语言的缺陷要少于其它语言*
上述模型中估算系数的大小和符号(译者注:指“+”或者“-”)与结果的预测因子有关。初始的四种变量是控制变量,并且,我们对这些变量对最终结果的影响不感兴趣,只是说它们都是积极的和有意义的。语言变量是指示变量,是每个项目的变化因子,该因子将每种编程语言与所有项目的编程语言的加权平均值进行比较。编程语言系数可以大体上分为三类。第一类是,那些在统计学上无关紧要的系数,并且在建模过程中这些系数不能从 0 中区分出来。这些编程语言的表现与平均值相似,或者它们也可能有更大的方差。剩余的系数是非常明显的,要么是正的,要么是负的。对于那些正的系数,我们猜测可能与这个编程语言有大量的缺陷修复相关。这些语言包括 `C、C++、Objective-C、Php`、以及 `Python`。所有的有一个负的系数的编程语言,比如 `Clojure、Haskell、Ruby`、和 `Scala`,暗示这些语言的缺陷修复提交可能小于平均值。
我们包括了一些变量,作为对明确影响反应的控制因子。项目<ruby>年龄<rt>age</rt></ruby>也包括在内,因为,越老的项目生成的缺陷修复数量越大。<ruby>提交<rt>commits</rt></ruby>数量也会对项目反应有轻微的影响。另外,从事该项目的<ruby>开发人员<rt>dev</rt></ruby>的数量和项目的原始<ruby>大小<rt>size</rt></ruby>,都会随着项目的活跃而增长。
上述模型中估算系数的大小和符号LCTT 译注:指 “+”或者“-”)与结果的预测因子有关。初始的四种变量是控制变量,并且,我们对这些变量对最终结果的影响不感兴趣,只是说它们都是积极的和有意义的。语言变量是指示变量,是每个项目的变化因子,该因子将每种编程语言与所有项目的编程语言的加权平均值进行比较。编程语言系数可以大体上分为三类。第一类是,那些在统计学上无关紧要的系数,并且在建模过程中这些系数不能从 0 中区分出来。这些编程语言的表现与平均值相似或者它们也可能有更大的方差。剩余的系数是非常明显的要么是正的要么是负的。对于那些正的系数我们猜测可能与这个编程语言有大量的缺陷修复相关。这些语言包括 C、C++、Objective-C、Php以及 Python。所有的有一个负的系数的编程语言比如 Clojure、Haskell、Ruby Scala暗示这些语言的缺陷修复提交可能小于平均值。
应该注意的是,虽然,从统计学的角度观察到编程语言与缺陷之间有明显的联系,但是,大家不要过高估计编程语言对于缺陷的影响,因为,这种影响效应是非常小的。异常分析的结果显示,这种影响小于总异常的 1%。
[![ut1.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/ut1.jpg)][66]
我们可以这样去理解模型的系数,它代表一个预测因子在所有其它预测因子保持不变的情况下,这个预测因子一个单位unit的变化,所反应出的预期的响应的对数变化;换句话说,对于一个系数 <sub style="border: 0px; outline: 0px; font-size: smaller; vertical-align: sub; background: transparent;">i</sub>_ ,在 _β<sub style="border: 0px; outline: 0px; font-size: smaller; vertical-align: sub; background: transparent;">i</sub>_ 中一个单位的变化,产生一个预期的 e _βi_ 响应的变化。对于可变因子,这个预期的变化是与所有编程语言的平均值进行比较。因此,如果对于一定数量的提交,用一个处于平均值的编程语言开发的特定项目有四个缺陷提交,那么,如果选择使用 `C++` 来开发,意味着我们预计应该有一个额外的(译注:相对于平均值 4多 1 个)缺陷提交,因为 e0.18 × 4 = 4.79。对于相同的项目,如果选择使用 `Haskell` 来开发,意味着我们预计应该少一个(译注:同上,相对于平均值 4缺陷提交。因为 _e_ 0.26 × 4 = 3.08。预测的精确度取决于剩余的其它因子都保持不变,除了那些微不足道的项目之外,所有的这些都是一个极具挑战性的命题。所有观察性研究都面临类似的局限性;我们将在第 5 节中详细解决这些事情。
我们可以这样去理解模型的系数,它代表一个预测因子在所有其它预测因子保持不变的情况下,这个预测因子一个<ruby>单位<rt>unit</rt></ruby>的变化,所反应出的预期的响应的对数变化;换句话说,对于一个系数 _<sub>i</sub> ,在 _β_<sub>i</sub> 中一个单位的变化,产生一个预期的 e^_β_<sub>i</sub> 响应的变化。对于可变因子,这个预期的变化是与所有编程语言的平均值进行比较。因此,如果对于一定数量的提交,用一个处于平均值的编程语言开发的特定项目有四个缺陷提交,那么,如果选择使用 C++ 来开发,意味着我们预计应该有一个额外的(LCTT 译注:相对于平均值 4多 1 个)缺陷提交,因为 e^0.18 × 4 = 4.79。对于相同的项目如果选择使用 Haskell 来开发意味着我们预计应该少一个LCTT 译注:同上,相对于平均值 4缺陷提交。因为 e^0.26 × 4 = 3.08。预测的精确度取决于剩余的其它因子都保持不变,除了那些微不足道的项目之外,所有的这些都是一个极具挑战性的命题。所有观察性研究都面临类似的局限性;我们将在第 5 节中详细解决这些事情。
**结论 1** _一些编程语言相比其它编程语言有更高的缺陷相关度,不过,影响非常小。_
**结论 1一些编程语言相比其它编程语言有更高的缺陷相关度不过影响非常小。**
在这篇文章的剩余部分,我们在基本结论的基础上详细阐述,通过考虑不同种类的应用程序、缺陷、和编程语言,可以进一步深入了解编程语言和缺陷倾向之间的关系。
在这篇文章的剩余部分,我们在基本结论的基础上详细阐述,通过考虑不同种类的应用程序、缺陷、和编程语言,可以进一步深入了解编程语言和缺陷倾向之间的关系。
软件 bugs 通常落进两种宽泛的分类中:1 _特定领域的 bug_ 特定于项目功能并且不依赖于底层编程语言。2 _普通 bug_ :大多数的普通 bug 是天生的,并且与项目功能无关,比如,输入错误,并发错误、等等。
软件 bug 通常落进两种宽泛的分类中:
因此,在一个项目中,应用程序领域和编程语言相互作用可能会影响缺陷的数量,这一结论被认为是合理的。因为一些编程语言被认为在一些任务上相比其它语言表现更突出,例如,`C` 对于低级别的(底层)工作,或者,`Java` 对于用户应用程序,对于编程语言的一个不合适的选择,可能会带来更多的缺陷。为研究这种情况,我们将理想化地忽略领域特定的 bugs因为普通 bugs 更依赖于编程语言的特性。但是,因为一个领域特定的 bugs 也可能出现在一个普通的编程错误中,这两者是很难区分的。一个可能的变通办法是在控制领域的同时去研究编程语言。从统计的角度来看,虽然,使用 17 种编程语言跨 7 个领域,在给定的样本数量中,理解大量的术语将是一个极大的挑战。
1. _特定领域的 bug_ :特定于项目功能,并且不依赖于底层编程语言。
2. _普通 bug_ :大多数的普通 bug 是天生的,并且与项目功能无关,比如,输入错误,并发错误、等等。
鉴于这种情况我们首先考虑在一个项目中测试领域和编程语言使用之间的依赖关系独立使用一个卡方检验Chi-square测试。在 119 个单元中,是 46也就是说是 39%,它在我们设定的保守值 5 以上,它太高了。这个数字不能超过 20%,应该低于 5。[14][26] 我们在这里包含了完整有值 [d][27];但是,通过 Cramer 的 V 测试的值是 0.191,是低相关度的,表明任何编程语言和领域之间的相关度是非常小的,并且,在回归模型中包含领域并不会产生有意义的结果。
因此在一个项目中应用程序领域和编程语言相互作用可能会影响缺陷的数量这一结论被认为是合理的。因为一些编程语言被认为在一些任务上相比其它语言表现更突出例如C 对于低级别的底层工作或者Java 对于用户应用程序对于编程语言的一个不合适的选择可能会带来更多的缺陷。为研究这种情况我们将理想化地忽略领域特定的 bug因为普通 bug 更依赖于编程语言的特性。但是,因为一个领域特定的 bug 也可能出现在一个普通的编程错误中,这两者是很难区分的。一个可能的变通办法是在控制领域的同时去研究编程语言。从统计的角度来看,虽然,使用 17 种编程语言跨 7 个领域,在给定的样本数量中,理解大量的术语将是一个极大的挑战。
鉴于这种情况,我们首先考虑在一个项目中测试领域和编程语言使用之间的依赖关系,独立使用一个<ruby>卡方检验<rt>Chi-square</rt></ruby>测试。在 119 个单元中,是 46 个,也就是说是 39%,它在我们设定的保守值 5 以上,它太高了。这个数字不能超过 20%,应该低于 5。^[14][26] 我们在这里包含了完整有值; ^[d][27] 但是,通过 Cramer 的 V 测试的值是 0.191,是低相关度的,表明任何编程语言和领域之间的相关度是非常小的,并且,在回归模型中包含领域并不会产生有意义的结果。
去解决这种情况的一个选择是,去移除编程语言,或者混合领域,但是,我们现有的数据没有进行完全挑选。或者,我们混合编程语言;这个选择导致一个相关但略有不同的问题。
**RQ2. 哪些编程语言特性与缺陷相关?**
#### 问题 2 哪些编程语言特性与缺陷相关?
我们聚合它们为编程语言类别,而不是考虑单独的编程语言,正如在第 2.2 节所描述的那样,然后去分析与缺陷的关系。总体上说,这些属性中的每一个都将编程语言按照在上下文中经常讨论的错误、用户辩论驱动、或者按以前工作主题来划分的。因此,单独的属性是高度相关的,我们创建了六个模型因子,将所有的单独因子综合到我们的研究中。然后,我们对六个不同的因子对缺陷数量的影响进行建模,同时控制我们在 _RQ1_ 节中使用的模型中的相同的基本协变量(译注:协变量是指在实验中不能被人为操纵的独立变量)。
我们按编程语言类别聚合它们,而不是考虑单独的编程语言,正如在第 2.2 节所描述的那样,然后去分析与缺陷的关系。总体上说,这些属性中的每一个都将编程语言按照在上下文中经常讨论的错误、用户辩论驱动、或者按以前工作主题来划分的。因此,单独的属性是高度相关的,我们创建了六个模型因子,将所有的单独因子综合到我们的研究中。然后,我们对六个不同的因子对缺陷数量的影响进行建模,同时控制我们在 _问题 1_ 节中使用的模型中的相同的基本协变量(LCTT 译注:协变量是指在实验中不能被人为操纵的独立变量)。
关于使用的编程语言(在前面的 [表 6][67]中),我们使用跨所有语言类的平均反应来比较编程语言 _类_ 。这个模型在 [表 7][68] 中表达了出来。很明显,`Script-Dynamic-Explicit-Managed` 类有最小的量级系数。这个系数是微不足道的,换句话说,对这个系数的 Z 校验z-test译者注:统计学上的一种平均值差异校验的方法) 并不能把它从 0 中区分出来。鉴于标准错误的量级,我们可以假设,在这个类别中的编程语言的行为是非常接近于所有编程语言行为的平均值。我们可以通过使用 `Proc-Static-Implicit-Unmanaged` 作为基本级并用于处理,或者使用基本级来虚假编码比较每个语言类,来证明这一点。在这种情况下,`Script-Dynamic-Explicit-Managed` 是明显不同于 _p_  = 0.00044 的。注意,虽然我们在这是选择了不同的编码方法,影响了系数和 Z 值,这个方法和所有其它的方面都是一样的。当我们改变了编码,我们调整系数去反应我们希望生成的对比。[4][28] 将其它类的编程语言与总体平均数进行比较,`Proc-Static-Implicit-Unmanaged` 类编程语言更容易引起缺陷。这意味着与其它过程类编程语言相比,隐式类型转换或者内存托管会导致更多的缺陷倾向。
关于使用的编程语言(在前面的 [表 6][67]中),我们使用跨所有语言类的平均反应来比较编程语言 _类_ 。这个模型在 [表 7][68] 中表达了出来。很明显,`Script-Dynamic-Explicit-Managed` 类有最小的量级系数。这个系数是微不足道的,换句话说,对这个系数的 <ruby>Z 校验<rt>z-test</rt></ruby>LCTT 译注:统计学上的一种平均值差异校验的方法) 并不能把它从 0 中区分出来。鉴于标准错误的量级,我们可以假设,在这个类别中的编程语言的行为是非常接近于所有编程语言行为的平均值。我们可以通过使用 `Proc-Static-Implicit-Unmanaged` 作为基本级并用于处理,或者使用基本级来虚假编码比较每个语言类,来证明这一点。在这种情况下,`Script-Dynamic-Explicit-Managed` 是明显不同于 _p_  = 0.00044 的。注意,虽然我们在这是选择了不同的编码方法,影响了系数和 Z 值,这个方法和所有其它的方面都是一样的。当我们改变了编码,我们调整系数去反应我们希望生成的对比。^[4][28] 将其它类的编程语言与总体平均数进行比较,`Proc-Static-Implicit-Unmanaged` 类编程语言更容易引起缺陷。这意味着与其它过程类编程语言相比,隐式类型转换或者管理内存会导致更多的缺陷倾向。
[![t7.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/t7.jpg)][69]
**表 7. 函数式语言与缺陷的关联度和其它类语言相比要低,而过程类语言则大于或接近于平均值。**
在脚本类编程语言中,我们观察到类似于允许与不允许隐式类型转换的编程语言之间的关系,它们提供的一些证据表明,隐式类型转换(与显示类型转换相比)才是导致这种差异的原因,而不是内存托管。鉴于各种因素之间的相关性,我们并不能得出这个结论。但是,当它们与平均值进行比较时,作为一个组,那些不允许隐式类型转换的编程语言出现错误的倾向更低一些,而那些出现错误倾向更高的编程语言,出现错误的机率则相对更高。在函数式编程语言中静态和动态类型之间的差异也很明显。
*表 7. 函数式语言与缺陷的关联度和其它类语言相比要低,而过程类语言则大于或接近于平均值。*
在脚本类编程语言中,我们观察到类似于允许与不允许隐式类型转换的编程语言之间的关系,它们提供的一些证据表明,隐式类型转换(与显式类型转换相比)才是导致这种差异的原因,而不是内存管理。鉴于各种因素之间的相关性,我们并不能得出这个结论。但是,当它们与平均值进行比较时,作为一个组,那些不允许隐式类型转换的编程语言出现错误的倾向更低一些,而那些出现错误倾向更高的编程语言,出现错误的机率则相对更高。在函数式编程语言中静态和动态类型之间的差异也很明显。
函数式语言作为一个组展示了与平均值的很明显的差异。静态类型语言的系数要小很多但是函数式语言类都有同样的标准错误。函数式静态编程语言出现错误的倾向要小于函数式动态编程语言这是一个强有力的证据尽管如此Z 校验仅仅是检验系数是否能从 0 中区分出来。为了强化这个推论,我们使用处理编码,重新编码了上面的模型,并且观察到,`Functional-Static-Explicit-Managed` 编程语言类的错误倾向是明显小于 `Functional-Dynamic-Explicit-Managed` 编程语言类的 _p_  = 0.034。
@ -165,70 +170,75 @@
我们现在重新回到应用领域这个问题。应用领域是否与语言类相互影响?怎么选择?例如,一个函数化编程语言,对特定的领域有一定的优势?与上面一样,对于这些因素和项目领域之间的关系做一个卡方检验,它的值是 99.05 _df_  = 30 _p_  = 2.622e09我们拒绝无意义假设Cramer 的 V 产生的值是 0.133,表示一个弱关联。因此,虽然领域和编程语言之间有一些关联,但在这里应用领域和编程语言类之间仅仅是一个非常弱的关联。
**结论 2**  _在编程语言类与缺陷之间有一个很小但是很明显的关系。函数式语言与过程式或者脚本式语言相比,缺陷要少。_
**结论 2在编程语言类与缺陷之间有一个很小但是很明显的关系。函数式语言与过程式或者脚本式语言相比缺陷要少。**
这个结论有些不太令人满意的地方,因为,我们并没有一个强有力的证据去证明,在一个项目中编程语言或者语言类和应用领域之间的关联性。一个替代方法是,基于全部的编程语言和应用领域,忽略项目和缺陷总数,而去查看相同的数据。因为,这样不再产生不相关的样本,我们没有从统计学的角度去尝试分析它,而是使用一个描述式的、基于可视化的方法。
这个结论有些不太令人满意的地方,因为,我们并没有一个强有力的证据去证明,在一个项目中编程语言或者语言类和应用领域之间的关联性。一个替代方法是,基于全部的编程语言和应用领域,忽略项目和缺陷总数,而去查看相同的数据。因为,这样不再产生不相关的样本,我们没有从统计学的角度去尝试分析它,而是使用一个描述式的、基于可视化的方法。
我们定义了 _缺陷倾向_ 作为 bug 修复提交与每语言每领域总提交的比率。[图 1][71] 使用了一个热力图展示了应用领域与编程语言之间的相互作用,从亮到暗表示缺陷倾向在增加。我们研究了哪些编程语言因素影响了跨多种语言写的项目的缺陷修复提交。它引出了下面的研究问题:
我们定义了 <ruby>缺陷倾向<rt>Defect Proneness</rt></ruby> 作为 bug 修复提交与每语言每领域总提交的比率。[图 1][71] 使用了一个热力图展示了应用领域与编程语言之间的相互作用,从亮到暗表示缺陷倾向在增加。我们研究了哪些编程语言因素影响了跨多种语言写的项目的缺陷修复提交。它引出了下面的研究问题:
[![f1.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/f1.jpg)][72]
**图 1. 编程语言的缺陷倾向与应用领域之间的相互作用。对于一个给定的领域(列底部),热力图中的每个格子表示了一个编程语言的缺陷倾向(行头部)。“整体”列表示一个编程语言基于所有领域的缺陷倾向。用白色十字线标记的格子代表一个 null 值,换句话说,就是在那个格子里没有符合的提交。**
**RQ3. 编程语言的错误倾向是否取决于应用领域?**
*图 1. 编程语言的缺陷倾向与应用领域之间的相互作用。对于一个给定的领域(列底部),热力图中的每个格子表示了一个编程语言的缺陷倾向(行头部)。“整体”列表示一个编程语言基于所有领域的缺陷倾向。用白色十字线标记的格子代表一个 null 值,换句话说,就是在那个格子里没有符合的提交。*
为了回答这个问题我们首先在我们的回归模型中以高杠杆点过滤掉认为是异常的项目这种方法在这里是必要的尽管这是一个非统计学的方法一些关系可能影响可视化。例如我们找到一个简单的项目Google 的 v8一个 `JavaScript` 项目,负责中间件中的所有错误。这对我们来说是一个惊喜,因为 `JavaScript` 通常不用于中间件。这个模式一直在其它应用领域中不停地重复着,因此,我们过滤出的项目的缺陷度都低于 10% 和高于 90%。这个结果在 [图 1][73] 中。
#### 问题 3 编程语言的错误倾向是否取决于应用领域?
我们看到在这个热力图中仅有一个很小的差异,正如在 RQ1 节中看到的那样,这个结果仅表示编程语言固有的错误倾向。为验证这个推论,我们测量了编程语言对每个应用领域和对全部应用领域的缺陷倾向。对于除了数据库以外的全部领域,关联性都是正向的,并且 p 值是有意义的(<0.01因此关于缺陷倾向在每个领域的语言排序与全部领域的语言排序是基本相同的
为了回答这个问题我们首先在我们的回归模型中以高杠杆点过滤掉认为是异常的项目这种方法在这里是必要的尽管这是一个非统计学的方法一些关系可能影响可视化。例如我们找到一个简单的项目Google 的 v8一个 JavaScript 项目负责中间件中的所有错误。这对我们来说是一个惊喜因为 JavaScript 通常不用于中间件。这个模式一直在其它应用领域中不停地重复着因此我们过滤出的项目的缺陷度都低于 10% 和高于 90%。这个结果在 [图 1][73] 中。
我们看到在这个热力图中仅有一个很小的差异,正如在问题 1 节中看到的那样,这个结果仅表示编程语言固有的错误倾向。为验证这个推论,我们测量了编程语言对每个应用领域和对全部应用领域的缺陷倾向。对于除了数据库以外的全部领域,关联性都是正向的,并且 p 值是有意义的(<0.01因此关于缺陷倾向在每个领域的语言排序与全部领域的语言排序是基本相同的
[![ut3.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/ut3.jpg)][74]
**结论 3:**  _应用领域和编程语言缺陷倾向之间总体上没有联系_
**结论 3: 应用领域和编程语言缺陷倾向之间总体上没有联系。**
我们证明了不同的语言产生了大量的缺陷,并且,这个关系不仅与特定的语言相关,也适用于一般的语言类;然而,我们发现,项目类型并不能在一定程度上协调这种关系。现在,我们转变我们的注意力到反应分类上,我想去了解,编程语言与特定种类的缺陷之间有什么联系,以及这种关系怎么与我们观察到的更普通的关系去比较。我们将缺陷分为不同的类别,如 [表 5][75] 所描述的那样,然后提出以下的问题:
**RQ4. 编程语言与 bug 分类之间有什么关系?**
#### 问题 4编程语言与 bug 分类之间有什么关系?
我们使用了一个类似于 RQ3 中所用的方法,去了解编程语言与 bug 分类之间的关系。首先,我们研究了 bug 分类和编程语言类之间的关系。一个热力图([图 2][76])展示了在编程语言类和 bug 类型之上的总缺陷数。去理解 bug 分类和语言之间的相互作用,我们对每个类别使用一个 NBR 回归模型。对于每个模型,我们使用了与 RQ1 中相同的控制因素,以及使用加权效应编码后的语言,去预测缺陷修复提交。
我们使用了一个类似于问题 3 中所用的方法,去了解编程语言与 bug 分类之间的关系。首先,我们研究了 bug 分类和编程语言类之间的关系。一个热力图([图 2][76])展示了在编程语言类和 bug 类型之上的总缺陷数。去理解 bug 分类和语言之间的相互作用,我们对每个类别使用一个 NBR 回归模型。对于每个模型,我们使用了与问题 1 中相同的控制因素,以及使用加权效应编码后的语言,去预测缺陷修复提交。
[![f2.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/f2.jpg)][77]
**图 2. bug 类别与编程语言类之间的关系。每个格子表示每语言类(行头部)每 bug 类别(列底部)的 bug 修复提交占全部 bug 修复提交的百分比。这个值是按列规范化的。**
*图 2. bug 类别与编程语言类之间的关系。每个格子表示每语言类(行头部)每 bug 类别(列底部)的 bug 修复提交占全部 bug 修复提交的百分比。这个值是按列规范化的。*
结果和编程语言的方差分析值展示在 [表 8][78] 中。每个模型的整体异常是非常小的,并且对于特定的缺陷类型,通过语言所展示的比例在大多数类别中的量级是类似的。我们解释这种关系为,编程语言对于特定的 bug 类别的影响要大于总体的影响。尽管我们结论概括了全部的类别,但是,在接下来的一节中,我们对 [表 5][79] 中反应出来的 bug 数较多的 bug 类别做进一步研究。
[![t8.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/t8.jpg)][80]
**表 8. 虽然编程语言对缺陷的影响因缺陷类别而不同,但是,编程语言对特定的类别的影响要大于一般的类别。**
**编程错误** 普通的编程错误占所有 bug 修复提交的 88.53% 左右,并且在所有的编程语言类中都有。因此,回归分析给出了一个与 RQ1 中类似的结论(查看 [表 6][81])。所有的编程语言都会导致这种编程错误,比如,处理错误、定义错误、输入错误、等等。
*表 8. 虽然编程语言对缺陷的影响因缺陷类别而不同,但是,编程语言对特定的类别的影响要大于一般的类别。*
**内存错误** 内存错误占所有 bug 修复提交的 5.44%。热力图 [图 2][82] 证明了在 `Proc-Static-Implicit-Unmanaged` 类和内存错误之间存在着非常紧密的联系。非托管内存的编程语言出现内存 bug这是预料之中的。[表 8][83] 也证明了这一点例如C、C++、和 `Objective-C` 引发了很多的内存错误。在托管内存的语言中 `Java` 引发了更多的内存错误,尽管它少于非托管的编程语言。虽然 `Java` 自己做内存回收,但是,它出现内存泄露一点也不奇怪,因为对象引用经常阻止内存回收。[11][29] 在我们的数据中,`Java` 的所有内存错误中28.89% 是内存泄漏造成的。就数量而言,编程语言中内存缺陷相比其它类别的 _原因_ 造成的影响要大很多。
**编程错误** 普通的编程错误占所有 bug 修复提交的 88.53% 左右,并且在所有的编程语言类中都有。因此,回归分析给出了一个与问题 1 中类似的结论(查看 [表 6][81])。所有的编程语言都会导致这种编程错误,比如,处理错误、定义错误、输入错误、等等。
**内存错误** 内存错误占所有 bug 修复提交的 5.44%。热力图 [图 2][82] 证明了在 `Proc-Static-Implicit-Unmanaged` 类和内存错误之间存在着非常紧密的联系。非管理内存的编程语言出现内存 bug这是预料之中的。[表 8][83] 也证明了这一点例如C、C++、和 Objective-C 引发了很多的内存错误。在管理内存的语言中 Java 引发了更多的内存错误尽管它少于非管理内存的编程语言。虽然 Java 自己做内存回收但是它出现内存泄露一点也不奇怪因为对象引用经常阻止内存回收。^[11][29] 在我们的数据中Java 的所有内存错误中28.89% 是内存泄漏造成的。就数量而言,编程语言中内存缺陷相比其它类别的 _原因_ 造成的影响要大很多。
**并发错误** 在总的 bug 修复提交中,并发错误相关的修复提交占 1.99%。热力图显示,`Proc-Static-Implicit-Unmanaged` 是主要的错误类型。在这种错误中C 和 C++ 分别占 19.15% 和 7.89%,并且它们分布在各个项目中。
[![ut4.jpg](http://deliveryimages.acm.org/10.1145/3130000/3126905/ut4.jpg)][84]
属于 `Static-Strong-Managed` 语言类的编程语言都被证实处于热力图中的暗区中,普通的静态语言相比其它语言产生更多的并发错误。在动态语言中,仅仅有 `Erlang` 更多的并发错误倾向,或许与使用这种语言开发的并发应用程序非常多有关系。同样地,在 [表 8][85] 中的负的系数表明,用诸如 `Ruby` 和 `Php` 这样的动态编程语言写的项目,并发错误要少一些。请注意,某些语言,如 `JavaScript、CoffeeScript`、和 `TypeScript` 是不支持并发的,在传统的惯例中,虽然 `Php` 具有有限的并发支持(取决于它的实现)。这些语言在我们的数据中引入了虚假的 0zeros,因此,在 [表 8][86] 中这些语言的并发模型的系数,不能像其它的语言那样去解释。因为存在这些虚假的 0所以在这个模型中所有语言的平均数非常小它可能影响系数的大小因此她们给 w.r.t. 一个平均数,但是,这并不影响他们之间的相对关系,因为我们只关注它们的相对关系。
属于 `Static-Strong-Managed` 语言类的编程语言都被证实处于热力图中的暗区中普通的静态语言相比其它语言产生更多的并发错误。在动态语言中仅仅有 Erlang 更多的并发错误倾向,或许与使用这种语言开发的并发应用程序非常多有关系。同样地,在 [表 8][85] 中的负的系数表明用诸如 Ruby  `Php 这样的动态编程语言写的项目并发错误要少一些。请注意某些语言 JavaScript、CoffeeScript 和 TypeScript 是不支持并发的在传统的惯例中虽然 Php 具有有限的并发支持取决于它的实现。这些语言在我们的数据中引入了虚假的 0因此在 [表 8][86] 中这些语言的并发模型的系数,不能像其它的语言那样去解释。因为存在这些虚假的 0所以在这个模型中所有语言的平均数非常小它可能影响系数的大小因此她们给 w.r.t. 一个平均数,但是,这并不影响他们之间的相对关系,因为我们只关注它们的相对关系。
一个基于 bug 修复消息中高频词的文本分析表明,大多数的并发错误发生在一个条件争用、死锁、或者不正确的同步,正如上面表中所示。遍历所有语言,条件争用是并发错误出现最多的原因,例如,在 `Go` 中占 92%。在 `Go` 中条件争用错误的改进或许是因为使用了一个争用检测工具帮助开发者去定位争用。同步错误主要与消息传递接口MPI或者共享内存操作SHM相关。`Erlang` 和 `Go` 对线程间通讯使用 MPI[e][30],这就是为什么这两种语言没有发生任何 SHM 相关的错误的原因,比如共享锁、互斥锁等等。相比之下,为线程间通讯使用早期的 SHM 技术的语言写的项目,就可能存在锁相关的错误。
基于 bug 修复消息中高频词的文本分析表明,大多数的并发错误发生在一个条件争用、死锁、或者不正确的同步,正如上面表中所示。遍历所有语言,条件争用是并发错误出现最多的原因,例如,在 Go 中占 92%。在 Go 中条件争用错误的改进或许是因为使用了一个争用检测工具帮助开发者去定位争用。同步错误主要与消息传递接口MPI或者共享内存操作SHM相关。Erlang  Go 对线程间通讯使用 MPI ^[e][30] ,这就是为什么这两种语言没有发生任何 SHM 相关的错误的原因,比如共享锁、互斥锁等等。相比之下,为线程间通讯使用早期的 SHM 技术的语言写的项目,就可能存在锁相关的错误。
**安全和其它冲突impact错误** 在所有的 bug 修复提交中,与冲突错误相关的提交占了 7.33% 左右。其中,`Erlang、C++、Python` 与安全相关的错误要高于平均值([表 8][87])。`Clojure` 项目相关的安全错误较少([图 2][88])。从热力图上我们也可以看出来,`静态` 语言一般更易于发生失败和性能错误,紧随其后的是 `Functional-Dynamic-Explicit-Managed` 语言,比如 `Erlang`。对异常结果的分析表明,编程语言与冲突失败密切相关。虽然安全错误在这个类别中是弱相关的,与残差相比,解释类语言的差异仍然比较大。
**安全和其它冲突错误** 在所有的 bug 修复提交中,与<ruby>冲突<rt>Impact</rt></ruby>错误相关的提交占了 7.33% 左右。其中Erlang、C++、Python 与安全相关的错误要高于平均值[表 8][87]。Clojure 项目相关的安全错误较少[图 2][88])。从热力图上我们也可以看出来,静态语言一般更易于发生失败和性能错误,紧随其后的是 `Functional-Dynamic-Explicit-Managed` 语言比如 Erlang。对异常结果的分析表明编程语言与冲突失败密切相关。虽然安全错误在这个类别中是弱相关的与残差相比解释类语言的差异仍然比较大。
**结论 4**  _缺陷类型与编程语言强相关一些缺陷类型比如内存错误和并发错误也取决于早期的语言所使用的技术。对于特定类别编程语言所引起的错误比整体更多。_
[Back to Top][89]
**结论 4 缺陷类型与编程语言强相关一些缺陷类型比如内存错误和并发错误也取决于早期的语言所使用的技术。对于特定类别编程语言所引起的错误比整体更多。**
### 4. 相关工作
在编程语言比较之前做的工作分为以下三类:
**(1)  _受控实验_**  对于一个给定的任务开发者使用不同的语言进行编程时受到监视。研究然后比较结果比如开发成果和代码质量。Hanenberg[7][31]通过开发一个解析程序,对 27 h 监视了 48 位程序员,去比较了静态与动态类型。他发现这两者在代码质量方面没有显著的差异,但是,基于动态类型的语言花费了更短的开发时间。他们的研究是在一个实验室中,使用本科学生,设置了定制的语言和 IDE 来进行的。我们的研究正好相反,是一个实际的流行软件应用的研究。虽然我们只能够通过使用回归模型间接(和 _事后_ )控制混杂因素,我们的优势是样本数量大,并且更真实、使用更广泛的软件。我们发现在相同的条件下,静态化类型的语言比动态化类型的语言更少出现错误倾向,并且不允许隐式类型转换的语言要好于允许隐式类型转换的语言,其对结果的影响是非常小的。这是合理的,因为样本量非常大,所以这种非常小的影响在这个研究中可以看得到。
#### (1)  受控实验
Harrison et al.[8][32] 比较了 C++ 与 `SML`,一个是过程化编程语言,一个是函数化编程语言,在总的错误数量上没有找到显著的差异,不过 `SML` 相比 C++ 有更高的缺陷密集度。`SML` 在我们的数据中并没有体现出来,不过,认为函数式编程语言相比过程化编程语言更少出现缺陷。另一个重点工作是比较跨不同语言的开发工作。[12][33][20][34] 不过,他们并不分析编程语言的缺陷倾向
对于一个给定的任务开发者使用不同的语言进行编程时受到监视。研究然后比较结果比如开发成果和代码质量。Hanenberg ^[7][31] 通过开发一个解析程序,对 48 位程序员监视了 27 小时,去比较了静态与动态类型。他发现这两者在代码质量方面没有显著的差异,但是,基于动态类型的语言花费了更短的开发时间。他们的研究是在一个实验室中,使用本科学生,设置了定制的语言和 IDE 来进行的。我们的研究正好相反,是一个实际的流行软件应用的研究。虽然我们只能够通过使用回归模型间接(和 _事后_ )控制混杂因素,我们的优势是样本数量大,并且更真实、使用更广泛的软件。我们发现在相同的条件下,静态化类型的语言比动态化类型的语言更少出现错误倾向,并且不允许隐式类型转换的语言要好于允许隐式类型转换的语言,其对结果的影响是非常小的。这是合理的,因为样本量非常大,所以这种非常小的影响在这个研究中可以看得到
**(2)  _调查_**  Meyerovich 和 Rabkin[16][35] 调查了开发者对编程语言的观点,去研究为什么一些编程语言比其它的语言更流行。他们的报告指出,非编程语言的因素影响非常大:先前的编程语言技能、可用的开源工具、以及现有的老式系统。我们的研究也证明,可利用的外部工具也影响软件质量;例如,在 `Go` 中的并发 bug请查看 RQ4 节内容)
Harrison et al. ^[8][32] 比较了 C++ 与 SML一个是过程化编程语言一个是函数化编程语言在总的错误数量上没有找到显著的差异不过 SML 相比 C++ 有更高的缺陷密集度。SML 在我们的数据中并没有体现出来不过认为函数式编程语言相比过程化编程语言更少出现缺陷。另一个重点工作是比较跨不同语言的开发工作。^[12][33][20][34] 不过,他们并不分析编程语言的缺陷倾向
**(3)  _对软件仓库的挖掘_**  Bhattacharya 和 Neamtiu[1][36] 研究了用 C 和 C++ 开发的四个项目,并且发现在 C++ 中开发的组件一般比在 C 中开发的组件更可靠。我们发现 C 和 C++ 的错误倾向要高于全部编程语言的平均值。但是,对于某些 bug 类型像并发错误C 的缺陷倾向要高于 C++(请查看第 3 节中的 RQ4
#### (2)  调查
[Back to Top][90]
Meyerovich 和 Rabkin ^[16][35] 调查了开发者对编程语言的观点,去研究为什么一些编程语言比其它的语言更流行。他们的报告指出,非编程语言的因素影响非常大:先前的编程语言技能、可用的开源工具、以及现有的老式系统。我们的研究也证明,可利用的外部工具也影响软件质量;例如,在 Go 中的并发 bug请查看问题 4 节内容)。
#### (3)  对软件仓库的挖掘
Bhattacharya 和 Neamtiu ^[1][36] 研究了用 C 和 C++ 开发的四个项目,并且发现在 C++ 中开发的组件一般比在 C 中开发的组件更可靠。我们发现 C 和 C++ 的错误倾向要高于全部编程语言的平均值。但是,对于某些 bug 类型像并发错误C 的缺陷倾向要高于 C++(请查看第 3 节中的问题 4
### 5. 有效的风险
@ -236,75 +246,68 @@ Harrison et al.[8][32] 比较了 C++ 与 `SML`,一个是过程化编程语言
我们判断文件所属的编程语言是基于文件的扩展名。如果使用不同的编程语言写的文件使用了我们研究的通用的编程语言文件的扩展名,这种情况下也容易出现错误倾向。为减少这种错误,我们使用一个随机样本文件集手工验证了我们的语言分类。
根据我们的数据集所显示的情形2.2 节中的解释类编程语言,我们依据编程语言属性的主要用途作了一些假设。例如,我们将 `Objective-C` 分到非管内存类型中,而不是混合类型。同样,我们将 `Scala` 注释为函数式编程语言,将 C# 作为过程化的编程语言,虽然,它们在设计的选择上两者都支持[19][37][21][38]。在这项研究工作中我们没有从过程化编程语言中分离出面向对象的编程语言OOP因为它们没有清晰的区别主要差异在于编程类型。我们将 C++ 分到允许隐式类型转换的类别中是因为,某些类型的内存区域可以通过使用指针操作被进行不同的处理 [22][39]并且我们注意到大多数 C++ 编译器可以在编译时检测类型错误。
根据我们的数据集所显示的情形2.2 节中的解释类编程语言我们依据编程语言属性的主要用途作了一些假设。例如我们将 Objective-C 分到非管内存类型中而不是混合类型。同样我们将 Scala 注释为函数式编程语言将 C# 作为过程化的编程语言,虽然,它们在设计的选择上两者都支持。 ^[19][37][21][38] 在这项研究工作中我们没有从过程化编程语言中分离出面向对象的编程语言OOP因为它们没有清晰的区别主要差异在于编程类型。我们将 C++ 分到允许隐式类型转换的类别中是因为,某些类型的内存区域可以通过使用指针操作被进行不同的处理 ^[22][39] 并且我们注意到大多数 C++ 编译器可以在编译时检测类型错误。
最后我们将缺陷修复提交关联到编程语言属性上它们可以反应出报告的风格或者其它开发者的属性。可用的外部工具或者库library也可以影响一个相关的编程语言的 bug 数量。
[Back to Top][91]
最后,我们将缺陷修复提交关联到编程语言属性上,它们可以反应出报告的风格或者其它开发者的属性。可用的外部工具或者<ruby><rt>library</rt></ruby>也可以影响一个相关的编程语言的 bug 数量。
### 6. 总结
我们对编程语言和使用进行了大规模的研究,因为它涉及到软件质量。我们使用的 Github 上的数据,具有很高的复杂性和多个维度上的差异的特性。我们的样本数量允许我们对编程语言效果以及在控制一些混杂因素的情况下,对编程语言、应用领域和缺陷类型之间的相互作用,进行一个混合方法的研究。研究数据显示,函数式语言是好于过程化语言的;不允许隐式类型转换的语言是好于允许隐式类型转换的语言的;静态类型的语言是好于动态类型的语言的;内存托管的语言是好于非管的语言的。进一步讲,编程语言的缺陷倾向与软件应用领域并没有关联。另外,每个编程语言更多是与特定的 bug 类别有关联,而不是与全部 bug。
我们对编程语言和使用进行了大规模的研究,因为它涉及到软件质量。我们使用的 Github 上的数据,具有很高的复杂性和多个维度上的差异的特性。我们的样本数量允许我们对编程语言效果以及在控制一些混杂因素的情况下,对编程语言、应用领域和缺陷类型之间的相互作用,进行一个混合方法的研究。研究数据显示,函数式语言是好于过程化语言的;不允许隐式类型转换的语言是好于允许隐式类型转换的语言的;静态类型的语言是好于动态类型的语言的;管理内存的语言是好于非管的语言的。进一步讲,编程语言的缺陷倾向与软件应用领域并没有关联。另外,每个编程语言更多是与特定的 bug 类别有关联,而不是与全部 bug。
另一方面,即便是很大规模的数据集,它们被多种方法同时进行分割后,也变得很小且不全面。因此,随着依赖的变量越来越多,很难去回答某个变量所产生的影响有多大这种问题,尤其是在变量之间相互作用的情况下。因此,我们无法去量化编程语言在使用中的特定的效果。其它的方法,比如调查,可能对此有帮助。我们将在以后的工作中来解决这些挑战。
[Back to Top][92]
### 致谢
这个材料是在美国国家科学基金会NSF以及美国空军科学研究办公室AFOSR的授权和支持下完成的。授权号 1445079, 1247280, 14141721446683FA955-11-1-0246。
[Back to Top][93]
### 参考资料
1\. Bhattacharya, P., Neamtiu, I. Assessing programming language impact on development and maintenance: A study on C and C++. In  _Proceedings of the 33rd International Conference on Software Engineering, ICSE'11_  (New York, NY USA, 2011). ACM, 171180.
1. Bhattacharya, P., Neamtiu, I. Assessing programming language impact on development and maintenance: A study on C and C++. In  _Proceedings of the 33rd International Conference on Software Engineering, ICSE'11_  (New York, NY USA, 2011). ACM, 171180.
2. Bird, C., Nagappan, N., Murphy, B., Gall, H., Devanbu, P. Don't touch my code! Examining the effects of ownership on software quality. In  _Proceedings of the 19th ACM SIGSOFT Symposium and the 13th European Conference on Foundations of Software Engineering_  (2011). ACM, 414.
3. Blei, D.M. Probabilistic topic models.  _Commun. ACM 55_ , 4 (2012), 7784.
4. Cohen, J.  _Applied Multiple Regression/Correlation Analysis for the Behavioral Sciences._ Lawrence Erlbaum, 2003.
5. Easterbrook, S., Singer, J., Storey, M.-A., Damian, D. Selecting empirical methods for software engineering research. In  _Guide to Advanced Empirical Software Engineering_  (2008). Springer, 285311.
6. El Emam, K., Benlarbi, S., Goel, N., Rai, S.N. The confounding effect of class size on the validity of object-oriented metrics.  _IEEE Trans. Softw. Eng. 27_ , 7 (2001), 630650.
7. Hanenberg, S. An experiment about static and dynamic type systems: Doubts about the positive impact of static type systems on development time. In  _Proceedings of the ACM International Conference on Object Oriented Programming Systems Languages and Applications, OOPSLA'10_  (New York, NY, USA, 2010). ACM, 2235.
8. Harrison, R., Smaraweera, L., Dobie, M., Lewis, P. Comparing programming paradigms: An evaluation of functional and object-oriented programs.  _Softw. Eng. J. 11_ , 4 (1996), 247254.
9. Harter, D.E., Krishnan, M.S., Slaughter, S.A. Effects of process maturity on quality, cycle time, and effort in software product development.  _Manage. Sci. 46_  4 (2000), 451466.
10. Hindley, R. The principal type-scheme of an object in combinatory logic.  _Trans. Am. Math. Soc._  (1969), 2960.
11. Jump, M., McKinley, K.S. Cork: Dynamic memory leak detection for garbage-collected languages. In  _ACM SIGPLAN Notices_ , Volume 42 (2007). ACM, 3138.
12. Kleinschmager, S., Hanenberg, S., Robbes, R., Tanter, É., Stefik, A. Do static type systems improve the maintainability of software systems? An empirical study. In  _2012 IEEE 20th International Conference on Program Comprehension (ICPC)_  (2012). IEEE, 153162.
13. Li, Z., Tan, L., Wang, X., Lu, S., Zhou, Y., Zhai, C. Have things changed now? An empirical study of bug characteristics in modern open source software. In  _ASID'06: Proceedings of the 1st Workshop on Architectural and System Support for Improving Software Dependability_  (October 2006).
14. Marques De Sá, J.P.  _Applied Statistics Using SPSS, Statistica and Matlab_ , 2003.
15. Mayer, C., Hanenberg, S., Robbes, R., Tanter, É., Stefik, A. An empirical study of the influence of static type systems on the usability of undocumented software. In  _ACM SIGPLAN Notices_ , Volume 47 (2012). ACM, 683702.
16. Meyerovich, L.A., Rabkin, A.S. Empirical analysis of programming language adoption. In  _Proceedings of the 2013 ACM SIGPLAN International Conference on Object Oriented Programming Systems Languages & Applications_  (2013). ACM, 118.
17. Milner, R. A theory of type polymorphism in programming.  _J. Comput. Syst. Sci. 17_ , 3 (1978), 348375.
18. Mockus, A., Votta, L.G. Identifying reasons for software changes using historic databases. In  _ICSM'00\. Proceedings of the International Conference on Software Maintenance_  (2000). IEEE Computer Society, 120.
19. Odersky, M., Spoon, L., Venners, B.  _Programming in Scala._  Artima Inc, 2008.
20. Pankratius, V., Schmidt, F., Garretón, G. Combining functional and imperative programming for multicore software: An empirical study evaluating scala and java. In  _Proceedings of the 2012 International Conference on Software Engineering_  (2012). IEEE Press, 123133.
21. Petricek, T., Skeet, J.  _Real World Functional Programming: With Examples in F# and C#._ Manning Publications Co., 2009.
22. Pierce, B.C.  _Types and Programming Languages._  MIT Press, 2002.
23. Posnett, D., Bird, C., Dévanbu, P. An empirical study on the influence of pattern roles on change-proneness.  _Emp. Softw. Eng. 16_ , 3 (2011), 396423.
24. Tan, L., Liu, C., Li, Z., Wang, X., Zhou, Y., Zhai, C. Bug characteristics in open source software.  _Emp. Softw. Eng._  (2013).
2\. Bird, C., Nagappan, N., Murphy, B., Gall, H., Devanbu, P. Don't touch my code! Examining the effects of ownership on software quality. In  _Proceedings of the 19th ACM SIGSOFT Symposium and the 13th European Conference on Foundations of Software Engineering_  (2011). ACM, 414.
### 作者
3\. Blei, D.M. Probabilistic topic models.  _Commun. ACM 55_ , 4 (2012), 7784.
**Baishakhi Ray** (rayb@virginia.edu), Department of Computer Science, University of Virginia, Charlottesville, VA.
4\. Cohen, J.  _Applied Multiple Regression/Correlation Analysis for the Behavioral Sciences._ Lawrence Erlbaum, 2003.
**Daryl Posnett** (dpposnett@ucdavis.edu), Department of Computer Science, University of California, Davis, CA.
5\. Easterbrook, S., Singer, J., Storey, M.-A., Damian, D. Selecting empirical methods for software engineering research. In  _Guide to Advanced Empirical Software Engineering_  (2008). Springer, 285311.
**Premkumar Devanbu** (devanbu@cs.ucdavis.edu), Department of Computer Science, University of California, Davis, CA.
6\. El Emam, K., Benlarbi, S., Goel, N., Rai, S.N. The confounding effect of class size on the validity of object-oriented metrics.  _IEEE Trans. Softw. Eng. 27_ , 7 (2001), 630650.
**Vladimir Filkov** (filkov@cs.ucdavis.edu), Department of Computer Science, University of California, Davis, CA.
7\. Hanenberg, S. An experiment about static and dynamic type systems: Doubts about the positive impact of static type systems on development time. In  _Proceedings of the ACM International Conference on Object Oriented Programming Systems Languages and Applications, OOPSLA'10_  (New York, NY, USA, 2010). ACM, 2235.
### 脚注
8\. Harrison, R., Smaraweera, L., Dobie, M., Lewis, P. Comparing programming paradigms: An evaluation of functional and object-oriented programs.  _Softw. Eng. J. 11_ , 4 (1996), 247254.
a. Wikipedia's article on type conversion, https://en.wikipedia.org/wiki/Type_conversion, has more examples of unintended behavior in C.
9\. Harter, D.E., Krishnan, M.S., Slaughter, S.A. Effects of process maturity on quality, cycle time, and effort in software product development.  _Manage. Sci. 46_  4 (2000), 451466.
b. This Apple developer article describes the usage of "id" http://tinyurl.com/jkl7cby.
10\. Hindley, R. The principal type-scheme of an object in combinatory logic.  _Trans. Am. Math. Soc._  (1969), 2960.
c. Some examples can be found here http://dobegin.com/objc-id-type/ and here http://tinyurl.com/hxv8kvg.
11\. Jump, M., McKinley, K.S. Cork: Dynamic memory leak detection for garbage-collected languages. In  _ACM SIGPLAN Notices_ , Volume 42 (2007). ACM, 3138.
d. Chi-squared value of 243.6 with 96 df. and p = 8.394e15
12\. Kleinschmager, S., Hanenberg, S., Robbes, R., Tanter, É., Stefik, A. Do static type systems improve the maintainability of software systems? An empirical study. In  _2012 IEEE 20th International Conference on Program Comprehension (ICPC)_  (2012). IEEE, 153162.
13\. Li, Z., Tan, L., Wang, X., Lu, S., Zhou, Y., Zhai, C. Have things changed now? An empirical study of bug characteristics in modern open source software. In  _ASID'06: Proceedings of the 1st Workshop on Architectural and System Support for Improving Software Dependability_  (October 2006).
14\. Marques De Sá, J.P.  _Applied Statistics Using SPSS, Statistica and Matlab_ , 2003.
15\. Mayer, C., Hanenberg, S., Robbes, R., Tanter, É., Stefik, A. An empirical study of the influence of static type systems on the usability of undocumented software. In  _ACM SIGPLAN Notices_ , Volume 47 (2012). ACM, 683702.
16\. Meyerovich, L.A., Rabkin, A.S. Empirical analysis of programming language adoption. In  _Proceedings of the 2013 ACM SIGPLAN International Conference on Object Oriented Programming Systems Languages & Applications_  (2013). ACM, 118.
17\. Milner, R. A theory of type polymorphism in programming.  _J. Comput. Syst. Sci. 17_ , 3 (1978), 348375.
18\. Mockus, A., Votta, L.G. Identifying reasons for software changes using historic databases. In  _ICSM'00\. Proceedings of the International Conference on Software Maintenance_  (2000). IEEE Computer Society, 120.
19\. Odersky, M., Spoon, L., Venners, B.  _Programming in Scala._  Artima Inc, 2008.
20\. Pankratius, V., Schmidt, F., Garretón, G. Combining functional and imperative programming for multicore software: An empirical study evaluating scala and java. In  _Proceedings of the 2012 International Conference on Software Engineering_  (2012). IEEE Press, 123133.
21\. Petricek, T., Skeet, J.  _Real World Functional Programming: With Examples in F# and C#._ Manning Publications Co., 2009.
22\. Pierce, B.C.  _Types and Programming Languages._  MIT Press, 2002.
23\. Posnett, D., Bird, C., Dévanbu, P. An empirical study on the influence of pattern roles on change-proneness.  _Emp. Softw. Eng. 16_ , 3 (2011), 396423.
24\. Tan, L., Liu, C., Li, Z., Wang, X., Zhou, Y., Zhai, C. Bug characteristics in open source software.  _Emp. Softw. Eng._  (2013).
e. MPI does not require locking of shared resources.
--------------------------------------------------------------------------------
@ -312,7 +315,7 @@ via: https://cacm.acm.org/magazines/2017/10/221326-a-large-scale-study-of-progra
作者:[Baishakhi Ray][a], [Daryl Posnett][b], [Premkumar Devanbu][c], [Vladimir Filkov ][d]
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出