[英]Unpredictable Program Behaviour in Java
我正在把头发拉出来,我想我会看到其他人的Java经验是否能够解决这个问题。 我编写了大量的程序代码,它本身就是一个更大的项目,所以我不能简单地发布它。 但是,我将概述问题......
问题:我的代码没有返回模拟的可预测结果。 每次运行模拟时,都会记录各种统计数据。 尽管代码相同(!),但执行结果之间产生的结果不同。
我非常肯定的事情不是问题(尽管如果你认为有“问题”请大声说出来):
谁能想到我可能会在这里俯瞰的东西? 这一刻似乎深不可测! 谢谢!
您确定要使用在所有地方创建的Random实例吗? 请记住,对Math.random()的调用使用自己的Random实例。
我假设你已经在对象中覆盖了 equals()
和hashCode()
(或者你已经编写了一个自定义比较器)。 如果您的对象中使用了随机数,那么它不是排序中的标准,对吧?
此外,如果您要对这些项进行排序,然后将它们放入HashMap或HashSet中 - 这些结构将不会保留您的顺序 - 请改用TreeSet或TreeMap。
尝试在应用程序中添加大量跟踪,然后检查日志以查看它的分歧。
您可以使用名为InTrace的工具跟踪Java代码的执行情况。 这将允许您比较程序的不同运行之间的详细控制流程。
注意:InTrace是我编写的免费开源工具。
有没有垃圾收集的机会? 这可能会给你的时间增加一些随机性。 如果您使用的是Sun JVM,则可以使用一些选项来打印GC信息:
-XX:-PrintGC Print messages at garbage collection. Manageable. -XX:-PrintGCDetails Print more details at garbage collection. Manageable. (Introduced in 1.4.0.) -XX:-PrintGCTimeStamps Print timestamps at garbage collection. Manageable (Introduced in 1.4.0.)
从此页面获取的详细信息。
您还可以查看使用jstat获取有关正在进行的操作的性能统计信息。
在不知道你的代码的情况下很难分辨,但这里有一些我开始寻找的地方。
确保所有个人课程都按预期工作。 这意味着,您应该至少对您的核心类进行单元测试 。
将assert-Statements插入所有私有方法以进行其他检查,以确保传递给helper方法的数据有效。 (不要在公共方法中使用assert,在那里使用Exceptions)。
在所有关键点添加日志记录(级别DEBUG,如果您使用的是log4j或类似的)或简单的System.out.println()语句,以获得值,其中值发生变化。 这将有助于您了解数据如何在代码中流动。
由于您使用的是eclipse,请使用调试器并逐步执行代码并观察意外的数据更改
检查错误的假设。 例如,对于非纯粹真/假检查条件的else块中的业务逻辑。 例如,您经常在GUI中找到这样的代码
if (button == OK_BUTTON) {
doOkButton();
} else {
doCancelBotton(); // VERY dangerous. could be any Button
}
解决这个问题
if (button == OK_BUTTON) {
doOkButton();
} else if (button == CANCEL_BUTTON) {
doCancelBotton();
} else {
assert false : "Oops, a new button?"
}
你说你使用的是随机数发生器。 你确定你每次都使用正确的它并没有增加输出的随机性吗? 你究竟用它做什么用的?
你用的是基于时间的吗? System.currentTimeMillies例如?
你确定你使用的是正确的系列吗? 并非所有都是排序和排序的,如果您尝试查看所有元素,每次运行应用程序时都会给出不同的结果。
验证集合中使用的所有类是否具有正确的equals()和hashCode()
你在使用自动装箱吗? 小心比较
new Integer(5) == new Integer(5)
是假的,因为你比较两个对象引用而不是值,
Integer i = new Integer(5);
i++;
在i ++创建一个新对象。 这些很难被发现,而且大多数时候,如果你使用原语和集合,就会发生自动装箱。
您是否正在使用任何可能使您的假设无效的第三方库(竞争条件等)
使用FindBugs之类的工具对代码进行静态分析。 它可能会给你一些提示。
那是我开始的地方。 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.