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

我在MongoDB的Java Connection驱动程序的 这个提交中看到了下面的代码,它首先出现在某种笑话中。 下面的代码是做什么的?

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

(编辑: 自发布此问题后,代码已经更新 )

在检查了这条线的历史后,我的主要结论是在工作中出现了一些不合格的编程。

  1. 这条线是无可辩驳的。 一般forms

     a? true : b 

    对于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 ); } 

    – 另一个不合格编码的例子,但注意到相反的逻辑 :这里事件被logging,如果_ok或在其他10%的情况下,而在2代码返回 10%的时间和日志90%的时间。 所以后来的承诺不仅破坏了清晰度,而且破坏了正确性。

    我想在你发布的代码中,我们实际上可以看到作者打算如何转换原来的字面意思, if-then从字面上理解为早期return条件所需的否定。 但后来他搞砸了,通过扭转不平等的标志,插入了一个有效的“双重否定”。

  4. 除了编码风格的问题,随机日志本身是一个相当可疑的做法,特别是因为日志条目没有logging自己的特殊行为。 显然,这个意图是减less了同样事实的重述:服务器正在closures。 适当的解决scheme是仅logging服务器状态的变化 ,而不是每个观察的变化,更不要说随机select10%的这种观察。 是的,这只需要一点点努力,让我们看看一些。

我只能希望,从检查三行代码所得到的所有这些无能的证据,都不能公平地说明整个项目,这样的工作将尽快被清除。

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

11小时前by gareth-rees:

据推测,这个想法是只logging大约1/10的服务器故障(因此避免大量的垃圾邮件),而不会花费维护计数器或计时器的成本。 (但是一定要保持一个计时器是负担得起的?)

添加一个初始化为负1的类成员:

  private int logit = -1; 

在try块中,进行testing:

  if( !ok && (logit = (logit + 1 ) % 10) == 0 ) { //log error 

这总是logging第一个错误,然后每十个错误。 逻辑运算符“短路”,所以logit只会增加一个实际的错误。

如果您想要所有错误的第一个和第十个,不pipe连接如何,请使logit类静态而不是aa成员。

如前所述,这应该是线程安全的:

 private synchronized int getLogit() { return (logit = (logit + 1 ) % 10); } 

在try块中,进行testing:

  if( !ok && getLogit() == 0 ) { //log error 

注意:我不认为抛出90%的错误是一个好主意。

我以前见过这种东西。

有一段代码可以回答来自另一个“黑盒子”代码的某些“问题”。 如果不能回答的话,会把它们转发给另外一个非常慢的“黑匣子”代码。

所以有时候以前看不见的新“问题”就会出现,而且会连续出现100个。

程序员对这个程序是如何工作感到满意,但是他想要某种方式来改进未来的软件,如果可能的话,新的问题被发现。

所以,解决办法是logging未知的问题,但事实certificate,有1000个不同的问题。 日志太大了,没有什么好处,因为他们没有明显的答案。 但是每隔一段时间,一批问题就会出现,可以回答。

由于日志变得太大,日志logging正在logging他获得这个解决scheme的真正重要的东西:

只logging一个随机的5%,这将清理日志,而从长远来看,仍然显示可以添加什么问题/答案。

因此,如果发生未知事件,则会随机logging这些事件。

我觉得这和你在这里看到的相似。

我不喜欢这种工作方式,所以我删除了这段代码,只是将这些消息logging到了一个不同的文件中 ,所以它们都是存在的,但不会破坏一般的日志文件。

Interesting Posts