设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客

Google首席Java架构师访谈:Java的命运

2011-3-11 17:20| 发布者: joejoe0332| 查看: 6013| 评论: 0|原作者: 程序员|来自: 程序员

摘要:   本文是Common Lisp专家Peter Seibel对Google公司首席Java架构师Joshua Bloch的访谈,谈到他所遇到的最糟糕的Bug以及Java的命运。  最糟糕的Bug  Seibel:我们聊聊调试吧。你遇到的最糟糕的Bug是什么?  Bl ...

  本文是Common Lisp专家Peter Seibel对Google公司首席Java架构师Joshua Bloch的访谈,谈到他所遇到的最糟糕的Bug以及Java的命运。

  最糟糕的Bug

  Seibel:我们聊聊调试吧。你遇到的最糟糕的Bug是什么?

joshua


  Bloch:提起Bug我立马就想到了一个,这个Bug很严重,而且很搞笑。那是90年代初,我在匹兹堡的 Transarc公司工作时。我在很紧的工期下提交了一个事务共享内存的实现。我在限期内完成了设计和实现,甚至还在过程中做出了几个可重用的组件。但是这么匆忙地写了很多新代码,我还是挺担心的。

  为了测试这些代码,我写了一个叫做“乱撞”的很长的程序出来。它运行了大量的事务,每个事务又包含了嵌套的事务,嵌套到可以嵌套的最大深度。每个嵌套事务都可能会加锁,以递增的顺序读取共享数组里面的几个元素,对每个元素都加入点东西,保持数组中所有元素的和为0,还是不变量。这些事务要么提交,要么取消,如90%的提交,10%的取消,其他比例也可以。多个线程同步运行于这些事务之上,长时间地访问数组。因为我测试的是一个共享内存机制,所以我同时运行多个有多个线程的“乱撞”程序,每个有自己的进程。

  在一般的并发级别下,“乱撞”轻松过关。但是当我真正调高并发级别时,我发现“乱撞”偶尔,仅仅是偶尔,无法通过一致性检查。我不知道这是怎么搞的。这只能是我的错,因为新代码都是我一个人写的。

  我花了大约一个星期,痛苦地为每个组件写了彻底的单元测试,所有的单元测试都通过了。然后我为每个内部数据结构写了详细的一致性检查,这样我就可以在每次变化后调用这些一致性检查,直到测试失败为止。最后,我终于发现一个底层的一致性检查失败了,这个问题无法重现,但是某种程度上可以帮助我分析问题出在哪里。最后,我得出了确实的结论——我的锁根本不工作。两个事务锁定、读写同一个值的时候,产生了并发的读—修改—写回操作,而后一次写入毁掉了第一次的写入。

  我编写了自己的锁管理器,所以我怀疑是它出了问题。但是锁管理器轻松地通过了测试。最后,我觉得问题不在锁管理器,而是它依赖的互斥体的实现!那时候操作系统还不支持多线程,我们需要写自己的多线程包。原来负责互斥体代码的工程师,不小心把我们的Solaris的线程实现中的lock和try- lock的汇编代码的标签弄混了。所以,每次你以为你在调用lock的时候,其实调用的是try-lock,反之亦然。也就是说当真的有争用发生的时候 ——在当年其实是很罕见的——第二个线程直接就进入了第一个线程的临界区,因为第一个线程也没有锁住。搞笑的是,这也就是说,整个公司几个星期都在运行没有互斥体的程序,而且谁都不知道。

  Knuth有句关于测试的名言,Bentley和Mcllroy的精彩论文“Engineering a Sort Function”中曾经引用过,大概意思是说,做测试时,要不惮以最大的恶意来推测所要测试的代码的错误。做这些测试的时候,我就是这么做的。但是这样会把所有东西纠结在一起,更难找到Bug。首先,并发的时候很难这么做,往往完全无法复现场景。其次,到最后可能会发现你的核心假设是错的。喜欢喊“耶,这语言出错了”或者“系统出问题了”是新手干的事儿。但是在这里,我依靠的基石——互斥体,确实出问题了。

  Seibel:也就是说Bug不在你的代码中,但是同时你只能对你的代码进行彻底的单元测试,因为你没有别的办法,只能去检查自己的代码。你觉得这些测试是不是可以,或者说应该让互斥体代码的作者来写,这样你就不用浪费一个星期,节省了一半的测试量,而且也可以找到这个Bug。

  Bloch:给互斥体代码加一个好的自动化单元测试肯定可以避免让我遭受那些痛苦,不过注意那可是90年代初。我想都没想过要抱怨那个工程师没写个好的单元测试。即使是今天,为并发工具写单元测试还是一种艺术形式。


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部