发现

服务发现一个比较奇怪的现象,就是叶子的数据不是0但是聚会到父级几点的时候发现父级节点的数据是0,聚合逻辑很简单,原始的数据只有叶子节点有数据,然后遍历叶子节点,递归向上聚合到根节点即可。

排查问题

过程比较坎坷,刚开始一致没有思路,突然灵光一现,发现输出的逻辑中如果是NaN,则输出0,怀疑其中有一个节点的数据是NaN,导致聚合的时候父级节点是NaN(NaN的任何计算结果都是NaN),最终输出0.

代码分析

简化逻辑如下

float score = (originScore - min) / (max - min);
return Math.max(Math.min(score, 1), 0);

前提:max - min

1、originScore - min == 0 导致score is NaN,后续使用NaN进行累加,计算出来父几点都是NaN,最后输出的时候NaN就是0,导致父级节点聚合有成绩都是0。

2、originScore - min > 0 score is Infinite(正无穷)可以正常参与计算,返回的 100分,聚合没问题,成绩也没有问题。

3、originScore - min < 0 score is Infinite(负无穷)可以正常参与计算,返回的 0分,聚合没问题,成绩也没有问题。

代码修复

在上面的代码之前加上下面代码,解决问题。

if (convergedScore - min <= 0) {
   return 0.0f;
}

Java中的NaN和Infinity导致的问题