检测Java代码: 破坏者数据错误模式

百万分之一

作为一个勤奋的开发人员,您已经为几个需要更好地访问复杂的大量数据存储的客户安装了一个应用程序,它编写良好,而且经过了充分测试。

对每个客户,现场测试阶段都畅通无阻地通过了。您在去银行的路上,心里极少考虑这六个月来的软件审查,这时您的传呼机响了起来。您的一个客户在使用您的软件运行一个报表时,系统崩溃了。

您赶到出事地点,运行了一个随机测试。工作良好。您运行另一个。没出现问题。您又运行了数百个测试。还是没有问题。您又检查了持续六个月运行这个应用程序的其它客户。没有投诉。

您重复运行那个引起问题的报表。崩溃!怎么回事?

破坏者数据错误模式

许多程序需要频繁访问和处理内部储存的数据来执行各种复杂的任务。这种数据可以从内存中的大型结构、数据库或网络上检索得到。

这类程序非常容易遭受损坏的内部数据引起的崩溃。我称这种错误模式为破坏者数据模式,是因为这种数据可以无限期地存在于系统中(很象冷战中的潜伏间谍一样),不引发任何问题,直到访问一段特定的数据时,损坏的数据才象炸弹一样爆炸。

语法原因

假定我们有一个 JDBC 应用程序,它存储了一个名为 Mapping 的数据库表,该表将 String 的名称映射到一系列元素的集合。(请参阅 参考资料,以获取关于 JDBC API 的更多信息。)每个集合中的每个元素都引用另一个表中的一个关键字(该表名为 Properties,包含这些元素的不同已知属性)。

这样说吧,Mapping 和 Properties 表最初都是从一个文本文件中读取的,这个文本文件由外部源( 外部意为不是内部产生的任意数据源)发展而来,而在外部源中,每行都以一个名称开头,后面跟着对应集合的表达,如下所示:

清单 1. 样本,外部源文本文件

In the Mapping file:
apples {macintosh, gala, golden-delicious}
trees {elm, beech, maple, pine, birch}
rocks {quartz, limestone, marble, diamond}
...
In the Properties file:
macintosh {color: red, taste: sour}
gala   {color: red, taste: sweet}
diamond  {color: clear, rigidity: hard, value: high}
...

可以对 Mapping 和 Properties 表条目进行语法分析并将其传递到一个方法中,此方法会把这些条目插入到一个数据库中。但这种方法存在潜在的缺陷。例如,假定我们已经编写了一个处理 JDBC 兼容数据库的类。遵照 JDBC API,我们可以定义一个 PreparedStatement 对象并使用它把信息传递到数据库中,如下所示:

清单 2. 使用 StreamTokenizer 插入域和区域字符串

 ...
  PreparedStatement insertionStmt =
   con.prepareStatement("INSERT INTO MAPPING VALUES(?,?)");
  ...
  public void insertEntry(String domain, String range)
    throws SQLException {
     insertionStatement.setString(1, domain);
     insertionStatement.setString(2, range);
     insertionStatement.executeUpdate();
    }

以这种方式插入两个 String 合适与否取决于从文本文件中获取 String 的方式。例如,假定一个简单的正则表达式匹配工具被用来将每一行拆分成两个 String :

一个 String 包含第一个 String 之前的全部字符。

一个 String 包含第一个 String 之后的全部字符。

时间: 2024-09-14 07:16:36

检测Java代码: 破坏者数据错误模式的相关文章

谁有logistic regression的Java代码和数据啊,发我一份,谢谢

问题描述 谁有logisticregression的Java代码和数据啊,发我一份,谢谢 解决方案 解决方案二:同求,谢谢,现在正在学这个

诊断Java代码: Impostor Type错误模式

当使用字段中特殊的标记来区别对象类型时,可能会产生标记对相关数据误贴标签的错误 ― 通称为 Impostor Type 错误模式.在诊断 Java 代码的这一部分中,Eric Allen 对这个错误的症状和起因进行了分析,详细说明了预防错误发生的方法,并讨论了一种吸引人的混合实现方法,这种方法不使用 impostor type,但最后,还是有很多相同的缺点产生.请在 讨论论坛与作者及其他读者分享您对本文的看法. 程序中除了最无关紧要的部分外都要对某些数据类型进行操作.静态类型系统提供了一种方法,

诊断Java代码: 臆想实现错误模式,第2部分

臆想实现重温 回想一下 上次接口的 臆想实现是一个合法的实现,但不满足接口规范的某些未经检查的方面.我们考虑一下下面的堆栈接口,以及许多未被其单独的类型签名捕获的不变量: 清单 1. 一个堆栈接 public interface Stack { public Object pop(); public void push(Object top); public boolean isEmpty(); } 例如,请考虑我们希望任意堆栈实现都遵守的下列规则: 如果一个对象 o 被压进堆栈 s ,且在堆栈

诊断Java代码: Broken Dispatch错误模式

整体和部分 还记得这条谚语吗,"整体大于部分之和"?如果把一个个独立的事件组合成一个相互作用的整体,产生的结果会比单个个体的作用之和要大得多. 程序也是一样的道理.随着一个个新方法被添加到程序中,整个程序可能的控制流程迅速增加.对于大型程序而言,很快局面就会无法控制了.就象是一个荒谬而又不可思议的戏法,有时您得到的最终结果并不是您所期望的方向 ― 这同您在重载方法或者覆盖方法时遇到的情况有些类似. Broken Dispatch 错误模式 面向对象语言的最强大的特性之一就是继承多态性.

诊断Java代码: Liar View错误模式

Liar, liar! 设想一下:您已经为一个分布式系统精心设计了一个极好的 GUI 程序,它包含了客户机请求的所有东西及其它一些东西.您已经让它运行通过了一个自动化测试套件的测试 ― 由于不变量的数量是个天文数字,因此,自动化测试是必须的.测试的结果是程序获得了一张"无错误的健康证明书". 发布这个 GUI 的期限到了,但是,作为一个象您这样严格的程序员,只是为了发现错误的行为 ― 本该在自动化测试中就被捕捉到的行为,您启动了程序,对它做最后一次手工测试.但愿您能够避免这种情形.真的

诊断Java代码: 空标志错误模式

空标志错误模式 在我的上一篇文章中,我说明了用空指针代替各种不同基本类型的数据是如何成为引起 NullPointerException 异常最普遍的原因之一的.这一次,我将说明用空指针代替异常情况怎么也会导致问题的出现.在 Java 程序中,异常情况通常是通过抛出异常,并在适当的控制点捕获它们来进行处理.但是经常看到的方法是通过返回一个空指针值来表明这种情况(以及,可能打印一条消息到 System.err ).如果调用方法没有明确地检查空指针,它可能会尝试丢弃返回值并触发一个空指针异常. 您可能

诊断Java代码: Double Descent错误模式

不要强制转换这个类! 与可怕的 空指针异常(该异常除了报告空指针之外,对于将要发生的事情什么也不说)不同,类强制转换异常相对来说容易调试. 类强制转换经常发生在递归下行数据结构的程序中,通常是当代码的某些部分在每次方法调用中下行了两级且在第二次下行时调度不当时发生的.程序员可通过学习 Double Descent 错误模式来识别这种问题. Double Descent 错误模式 本周的专题是 Double Descent 错误模式.它通过类强制转换异常来表明.它是由递归下行复合数据结构引起的,这

诊断Java代码: Fictitious Implementation错误模式,第1部分

Java 语言接口是一种强大的工具.它具有多继承的很多优点,而没有什么问题.为客户希望使用的所有服务指定一个接口,使得在需要时插进这种接口的不同实现成为可能. 遗憾的是,规范中可以被表达的部分只有方法说明.对任何实现来说,很可能还有很多其它不变量希望被掌握,但是 Java 语言没有提供检查它们的工具. 臆想错误模式 由于这种限制,很可能"实现"了一个接口而实际上没有满足预期的语义.由这种 Fictitious Implementation导致的错误就是本周专栏的主题. 例如,请看一看下

struts2怎么与自己的JAVA代码数据交互

问题描述 怎么实现struts2标签的值与java代码进行数据交互?比如:<s:setid="pageInfo"name="pageInfo"value="%{#set.info}"></s:set><scripttype="text/javascript">varinfo='<s:propertyvalue="pageInfo"/>';</script