转的一个jdk bug

转载 2006年06月13日 09:05:00

原文:http://tb.blog.csdn.net/TrackBack.aspx?PostId=776965

Joshua Bloch, 获得过Jolt最畅销奖的《Effective Java》的作者, 是Sun Microsystems的杰出工程师和Transarc的资深系统设计师, J2SE 5.0 Tiger的代言人和领路人, 也是还是JSR166的发起人之一..

后来, Joshua Bloch去了Google, 成为了Google的首席工程师

Joshua Bloch拥有卡耐基.梅隆大学(CMU)计算机科学的博士学位。

在最近Joshua Bloch的一篇文章里, Joshua Bloch回忆了当年在CMU上课的时候, vividly Jon Bentley 第一节算法课, 就要求所有刚进来的PHD学生, 每人都写一个二分查找算法. 然后发现, 多数人的算法都存在BUG, 这在当时给了Joshua Bloch 一个很深的印象..

在之后, Joshua Bloch 负责java.util.Arrays 代码编写的时候, 采用了Bentley 在<<Programming Pearls >>一书中的二分查找算法, 结果在8年后的今天, Joshua Bloch 发现, 这里面原来还是有一个BUG.

问题到底是出在哪里? 竟然逃过了Bentley 和Joshua Bloch 的双重检测?

一起来看看java.util.Arrays的代码:

1:     public static int binarySearch(int[] a, int key) {
2:         int low = 0;
3:         int high = a.length - 1;
4:
5:         while (low <= high) {
6:             int mid = (low + high) / 2;
7:             int midVal = a[mid];
8:
9:             if (midVal < key)
10:                 low = mid + 1;
11:             else if (midVal > key)
12:                 high = mid - 1;
13:             else
14:                 return mid; // key found
15:         }
16:         return -(low + 1);  // key not found.
17:     }


这是很经典的一个二分查找算法.

bug出现在第6行:

6:             int mid =(low + high) / 2;

在一般情况下, 这个语句是不会出错的, 但是, 当low+high的值超过了最大的正int值 (231- 1) 的时候, mid会变成负值,  这个时候, 会抛出ArrayIndexOutOfBoundsException 异常.


所以当一个数组包含超过2的30次方 个元素的时候, 就很可能会带来问题... 当然, 在一般的应用里面, 很少数组会包含那么多元素, 但是现在这样的情况已经越来越多了, 比如Google的海量运算..

那如何解决这个问题?

很简单, 修改这行语句为:

6:             int mid = low + ((high - low) / 2);
或者
6:             int mid = (low + high) >>> 1;


在c或者c++中, 则可以如下实现:
6:             mid = ((unsigned) (low + high)) >> 1;

java nio的一个严重BUG

这个BUG会在linux上导致cpu 100%,使得nio server/client不可用,具体的详情可以看这里http://bugs.sun.com/bugdatabase/view_bug.do...
  • huoyunshen88
  • huoyunshen88
  • 2015年05月12日 17:22
  • 2633

【Netty基础】Netty的高性能及NIO的epoll空轮询bug

Selector BUG出现的原因若Selector的轮询结果为空,也没有wakeup或新消息处理,则发生空轮询,CPU使用率100%,Netty的解决办法 对Selector的select操作周期进...
  • baiye_xing
  • baiye_xing
  • 2017年06月17日 10:08
  • 3759

如何写好一个bug

前言 因为以前我是做测试的,后来在一家公司转开发了,在开发过程中,每次看到测试人员写的bug就很头痛,bug描述不清晰很是印象解决bug的效率,甚至有些bug的描述是有歧义性和个人主观色彩的,后来...
  • u011546806
  • u011546806
  • 2015年03月06日 11:07
  • 1302

一个bug的成本

我想说的当然不是一个bug价值多少钱,因为软件行业因行业不同,公司不同,业务不同,你的软件价值也不同;其实bug用价值来形容当然不合适,更应该用损失或者公司的支出来形容了。         写出本文...
  • xingyu_qie
  • xingyu_qie
  • 2016年03月15日 10:44
  • 1030

定位Bug技巧总结

解决Bug是编程人员的天职(创造Bug算是一种天赋吧),甚至有人这么认为:开发人员的能力可以依据他能决解Bug的复杂程度来评定。简单的Bug大多数程序员是靠臆断来解决的,但是当Bug隐藏在代码的最深处...
  • sinat_25141403
  • sinat_25141403
  • 2016年05月03日 20:11
  • 2888

Java nio的一个严重BUG,导致cpu 100%

这个BUG会在Linux上导致cpu 100%,使得nio server/client不可用,具体的详情可以看这里http://bugs.sun.com/bugdatabase/view_bug.do...
  • zhouhao88410234
  • zhouhao88410234
  • 2017年07月25日 09:17
  • 644

bug的定位比修改重要1000倍

bug的定位比修改重要1000倍 砍倒一棵树,当然也有技巧,一斧子一斧子劈得要在正确的位置上,还要喊好顺山倒,别砸到别人和自己。不过,在一片林子里找到你想要的那一棵,才是更重要的事,也更困难。修改一...
  • younggift
  • younggift
  • 2013年11月30日 00:38
  • 3495

应用服务器中对JDK的epoll空转bug的处理

前面讲到了epoll的一些机制,与select和poll等传统古老的IO多路复用机制的一些区别,这些区别实质可以总结为一句话, 就是epoll将重要的基于事件的fd集合放在了内核中来完成,因为内核是...
  • fishmai
  • fishmai
  • 2017年07月31日 21:31
  • 205

由于ndk引发的几个bug,以及解决方法

问题一: Error:(12, 0) Error: NDK integration is deprecated in the current plugin.   Consider trying the...
  • tyk9999tyk
  • tyk9999tyk
  • 2017年03月30日 17:03
  • 322

测试人员如何报一个bug,性能测试,负载测试,压力测试

首先,确保你所发现的问题是确实是一个bug,不要出现因为测试人员操作错误或配置错误所引起的”bug”,这样会降低你在开发人员心中的可信度。在测试的时候,如果发现测试的实际结果与预期测试结果不符时,不要...
  • msdnwolaile
  • msdnwolaile
  • 2016年09月22日 00:51
  • 797
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:转的一个jdk bug
举报原因:
原因补充:

(最多只允许输入30个字)