生产bug---接手新项目有个遗留bug产生千万垃圾数据

文章讨论了一个在RedisZSet集合操作中出现的问题,即使用`contains`方法检查元素时,由于类型不匹配导致无法正确识别已存在的对象,进而产生大量垃圾数据。问题在于添加到集合的对象类型与检查时使用的类型不一致,导致`equals`方法未返回预期结果。解决方案是确保所有操作都使用相同类型的对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis ZSet 集合中取出 Set 对象 contains匹配不上

总结:基础很重要。

事情来由

我接手一个新项目,里面有个推送办理过程信息的调度
大概逻辑如下:

把受理时间转成zset分值,把受理id存到redis里面
然后Zset 支持根据传的分值 从小到大排序
他会从最先受理的开始监察办结情况 取出受理id 并且删除缓存
如果发现没办结的 会重新放到redis 给个当前时间的分值 避免死循环

部分代码展示
1.从set集合中获取并删除多个元素

 public Set<Object> getAndRemoveZSet(String cacheKey, int size) {
        if (StringUtils.isNotBlank(cacheKey)){
            Set<Object> set = this.getZSetOperations().range(cacheKey, 0, size);
            if (CollUtil.isNotEmpty(set)){
                this.getZSetOperations().remove(cacheKey, set.toArray());
                return set;
            }
        }
        return null;
    }

问题来了

这里就是获取前面的部分受理id

 Set<Object> instIds = memoryDb.getAndRemoveZSet(KEY, size)

关键
在这里插入图片描述
processInstId 参数可以理解为已经办结的受理id
原来的同事是想如果已经办结 就在集合中移除 不重新放到redis里面

看起来好像没问题
但是就这行代码 导致出现千万垃圾数据(还好过程数据不太重要)
if (instIds.contains(processInstId))

产生这么多垃圾数据的原因就是他根本进不到里面
导致已经推了过程信息的数据 重新放到redis里面 然后重复推送

先看一段代码

public static void main(String[] args) {
        Set<Object> instIdsX = new HashSet();
        instIdsX.add(1);
        instIdsX.add(Double.valueOf("2"));
        instIdsX.add((long) 3);
        instIdsX.add(("4"));
        if (instIdsX.contains((long) 1)) {
            System.out.println("long类型包含1");
        }
        if (instIdsX.contains("4")) {
            System.out.println("String类型包含4");
        }
        if (instIdsX.contains("2")) {
            System.out.println("String类型包含2");
        }
        if (instIdsX.contains((1))) {
            System.out.println("int类型包含1");
        }
        if (instIdsX.contains(((long) 3))) {
            System.out.println("long类型包含3");
        }
        if (instIdsX.contains((3))) {
            System.out.println("int类型包含3");
        }
    }

控制台:
在这里插入图片描述
很明显就是 对象都要 与add进来的类型一样才能为ture
在这里插入图片描述

一起看看源码(大家可以自己debug看更清晰)

先看看HashSet的contains方法
在这里插入图片描述
在这里插入图片描述
就看getNode 是不是为空了 为空就是不包含嘛
在这里插入图片描述
这里想不为null 那不就是调用的传入对象的equals方法 为 true 嘛

在看下String重写的equals方法
(基本类型都是没重写equals方法 是 == 都是比较的内存地址)
在这里插入图片描述
结束!!!
总结:基础很重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小瞿码上有

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值