为什么MongoDB Java驱动程序在条件中使用随机数生成器?

2022-08-31 06:03:15

我在MongoDB的Java连接驱动程序的这个提交中看到了下面的代码,起初它似乎是一个笑话。以下代码有什么作用?

if (!((_ok) ? true : (Math.random() > 0.1))) {
    return res;
}

(编辑:自发布此问题以来,代码已更新


答案 1

在检查了这条线的历史之后,我的主要结论是,在工作中有一些不称职的编程。

  1. 这条线是无端的错综复杂的。一般形式

    a? true : b
    

    for 等效于boolean a, b

    a || b
    
  2. 周围的否定和过多的括号使事情进一步复杂化。记住德摩根定律,这是一个微不足道的观察,这段代码相当于

    if (!_ok && Math.random() <= 0.1)
      return res;
    
  3. 最初引入此逻辑的提交具有

    if (_ok == true) {
      _logger.log( Level.WARNING , "Server seen down: " + _addr, e );
    } else if (Math.random() < 0.1) {
      _logger.log( Level.WARNING , "Server seen down: " + _addr );
    }
    

    — 另一个不称职编码的示例,但请注意相反的逻辑:如果其他情况下有 10% 或 10% 则记录事件,而 2 中的代码则记录该事件。返回 10% 的次数,并记录 90% 的次数。因此,后来的提交不仅破坏了清晰度,而且破坏了正确性本身。_ok

    我认为在你发布的代码中,我们实际上可以看到作者打算如何以某种方式将原件从字面上转换为早期条件所需的否定。但后来他搞砸了,通过反转不等式符号插入了一个有效的“双负”。if-thenreturn

  4. 撇开编码风格问题不谈,随机日志记录本身就是一种非常可疑的做法,特别是因为日志条目没有记录其自身的特殊行为。显然,其目的是减少对同一事实的重述:服务器当前已关闭。适当的解决方案是仅记录服务器状态的变化,而不记录其每个观测值,更不用说随机选择10%的此类观测值了。是的,这需要更多的努力,所以让我们看看一些。

我只能希望,所有这些从检查三行代码中积累起来的无能证据,并不能公平地说明整个项目,并且这项工作将尽快得到清理。


答案 2

https://github.com/mongodb/mongo-java-driver/commit/d51b3648a8e1bf1a7b7886b7ceb343064c9e2225#commitcomment-3315694

11小时前 由 gareth-rees:

据推测,这个想法是只记录大约1/10的服务器故障(因此避免大量垃圾邮件日志),而不会产生维护计数器或计时器的成本。(但肯定要维护计时器是负担得起的吗?


推荐