Java 实习日记:断面状态筛选 Bug 修复与对比案例日期过滤优化

今天主要处理了两个和潮流分析相关的后端问题:一个是断面列表的状态筛选不准确,另一个是对比案例列表缺少起止日期过滤。

这次改动代码量并不大,但是对我来说收获挺明显的。因为它不是简单地加一个字段或者改一个接口,而是要先理解业务状态的判断口径,再反推代码为什么会查出"不该出现的数据"。也让我感受到,真实项目里的 Bug 很多时候不是语法问题,而是"代码逻辑"和"业务定义"没有完全对齐。

一、断面状态筛选问题

上午刚开始看这个问题时,我第一反应是接口参数是不是传错了。

前端查询断面列表时,会传一个 deviceStatus 参数,用来筛选断面状态。比如前端传 deviceStatus=3,业务上代表查询"基态重载"的断面。正常情况下,这个列表里应该只展示最终状态为基态重载的数据。但是联调时发现,当前端传 deviceStatus=3 时,接口不仅返回了基态重载的数据,还返回了基态越限的数据。从页面效果看,这会让用户误以为"重载列表里混进了越限数据",明显不符合业务预期。

我先从接口入参开始排查。这个接口本身是一个查询接口,前端会传 caseId、deviceStatus 等参数。caseId 用来定位当前案例,deviceStatus 用来表示要筛选的断面状态。确认参数没有传错之后,我就去看 Service 层里具体是怎么判断状态的。

排查这个问题之前,我先重新确认了断面状态的判断规则。大致可以理解为:基态越限表示潮流超过正向或负向限值;基态在限表示潮流达到正向或负向限值;基态重载表示潮流达到限值的 80% 以上,但还没有达到 100%;如果都不满足,就属于正常。

这里有一个很重要的点:这些状态不是简单并列的。比如某个断面在一天内既出现过重载,又出现过越限,那么它虽然确实出现过重载,但最终展示时应该优先认为是"越限",因为越限的严重程度更高。所以状态判断需要有优先级:越限优先于在限,在限优先于重载,最后才是正常。

原来的筛选逻辑是按统计次数判断的。代码会先统计某个断面在所有时间点里出现了多少次越限、多少次在限、多少次重载,然后根据前端传入的 deviceStatus 判断是否保留这条数据。

问题就出在这里。假设一个断面有 10 个时间点,其中 2 个时间点越限,3 个时间点重载,其他时间点正常。按照最终状态优先级,这个断面的最终状态应该是"基态越限"。但是如果前端传的是 deviceStatus=3,原来的逻辑只要发现它存在重载次数,就会把它也查出来。这就导致了一个断面明明最终状态是越限,却也出现在了重载列表里。本质原因就是:筛选条件用的是"是否出现过某状态",但前端期望的是"最终状态是否等于某状态"。这两个口径不一致,所以出现了数据混入的问题。

我最后没有选择在原来的重载判断里再额外加一堆排除条件,而是把逻辑调整成:先根据统计结果计算断面的最终状态,再按最终状态筛选。

这样处理之后,代码里的思路就清楚很多。先根据越限次数、在限次数、重载次数得到一个最终状态。如果存在越限次数,最终状态就是越限;如果没有越限但存在在限次数,最终状态就是在限;如果没有越限和在限但存在重载次数,最终状态就是重载;否则就是正常。然后筛选时只判断这个最终状态是否等于前端传入的 deviceStatus。如果不一致,就跳过这条数据。这样前端传 deviceStatus=3 时,就只会返回最终状态为"基态重载"的断面。如果某个断面同时有重载和越限,由于最终状态会被判定为越限,所以不会再出现在重载列表里。

我觉得这种改法比单独修某一个状态更稳。因为它不是只针对"重载混入越限"这个现象打补丁,而是把"返回字段里的状态"和"筛选条件里的状态"统一起来了。以后如果前端筛选越限、在限、重载,都使用同一套最终状态口径,逻辑会更一致,也更容易维护。处理完断面列表之后,我又看了断面详情接口的默认筛选行为。之前这个接口在前端没有传 deviceStatus 时,默认只查"越限"。但是结合现在页面展示需求,默认应该展示"全部"状态,所以这里也一起调整成了默认查询全部。

这个改动虽然很小,但是对接口默认行为影响比较明显。以前我容易忽略这种"前端不传参数时后端默认查什么"的细节,但真实项目里默认值经常会影响页面初始展示效果。以后看这类问题时,我也会更注意接口默认值和页面预期是否一致。

二、对比案例列表增加日期过滤

下午还处理了一个对比案例列表相关的小需求。

这个接口前端只传一个 caseId,后端根据当前案例去找可以对比的案例。原来的筛选条件主要是:计算成功、调度模式取反、典型场景一致。比如当前案例是经济调度,那么候选案例就查低碳调度;当前案例是低碳调度,就查经济调度。

刚开始看这个接口时,我觉得这些条件已经比较合理了。因为对比案例确实需要一个经济调度和一个低碳调度进行对比,而且典型场景也要一致,比如都是日场景、三日场景、周场景、月场景或者年场景。但是后来确认业务时发现,只按这些条件还不够。两个案例能不能对比,不只是看调度模式和典型场景,还要看时间范围是不是一致。如果开始日期、结束日期不一样,即使其他条件都满足,拿来对比也可能没有意义。比如一个案例的时间范围是 1 月 1 日到 1 月 7 日,另一个案例是 1 月 8 日到 1 月 14 日。它们虽然都是同一种典型场景,也可能一个是经济调度、一个是低碳调度,但实际对比的基础数据范围已经不一样了。这样的结果展示到前端,用户很可能会误以为是在同一时间范围下比较不同调度模式,实际却不是。

所以这次对比案例列表也补充了开始日期和结束日期过滤。这里没有新增请求参数,前端仍然只需要传 caseId。后端会先根据 caseId 查出当前案例,再用当前案例自己的 startDate 和 endDate 去过滤候选案例。也就是说,候选案例不仅要满足计算成功、调度模式取反、典型场景一致,还要满足开始日期和结束日期都与当前案例完全一致。这样做的好处是前端调用方式不用变,原来的接口也保持兼容,只是后端返回的数据更准确了。对于前端来说,还是调用同一个接口,传同一个 caseId;对于后端来说,筛选条件更完整,能避免把时间范围不一致的案例带出来。

这次还有一个细节是,当前案例的必需字段校验也要补充。原来主要校验调度模式、典型场景和开始日期。现在既然要按开始日期和结束日期过滤,那么当前案例的 endDate 也应该是必需字段。如果当前案例本身没有结束日期,就无法明确筛选出同一时间范围的候选案例,这种情况下直接返回空列表会更合理。

三、总结和收获

这次任务里用到的技术点其实都比较常见,主要还是 Spring Boot 的接口、Service 层业务逻辑、MyBatis-Plus 查询条件、DTO 返回对象和枚举状态判断。真正有难度的地方不是语法,而是业务口径。

以前我看到筛选条件,可能第一反应就是加一个 eq,或者在 if 里多写一个判断。但这次排查之后更明显地感觉到,写业务代码之前要先弄清楚几个问题:这个字段代表瞬时状态,还是最终状态;这些状态之间有没有优先级;前端传的参数表示精确筛选,还是包含筛选;接口能不能通过后端已有数据完成过滤,而不是增加新的入参。这些问题想清楚之后,代码反而不难写。

今天这两个问题代码量都不算大,但我觉得挺典型的。它们都不是"怎么写 Java 语法"的问题,而是"怎么把业务规则正确落到代码里"的问题。

这次最大的收获有几个:

第一,状态筛选一定要确认"筛选口径"。同样是 deviceStatus=3,它可能表示"出现过重载",也可能表示"最终状态是重载"。如果不先确认业务含义,代码很容易写成看起来没问题,但页面效果不对。

第二,业务状态通常有优先级。像越限、在限、重载这种状态,并不是简单互斥的。一个设备在不同时间点可能出现多个状态,这时候就要根据业务严重程度确定最终展示状态。

第三,接口改造要尽量保持兼容。对比案例列表这次需要增加日期过滤,但没有新增请求参数,而是复用当前案例本身的起止日期。这样前端调用方式不需要改变,后端也能保证数据范围更准确。

第四,真实项目里代码改动不一定多,但排查过程很重要。这次最终提交只改了少量代码,但前面需要先读接口、看 DTO、看枚举、理解前端传参,再结合业务规则判断问题原因。对实习生来说,这种排查过程其实比单纯写代码更锻炼人。

以前我会觉得修 Bug 主要就是找到哪一行代码错了,然后改掉。但现在慢慢感觉到,很多业务 Bug 的难点不是"代码错在哪里",而是"为什么这段代码在业务上不对"。只有理解了这个问题,改出来的代码才不会只是临时补丁,而是更接近真正的业务规则。

相关推荐
长谷深风1111 小时前
Java并发编程:线程安全与多线程实战指南【个人八股】
java·安全·线程·进程·juc·并发与并行·上下文切换(性能影响因素)
basketball6161 小时前
C++ 强制类型转换:从 C 风格到 C++ 四大金刚
java·c语言·c++
Dicky-_-zhang2 小时前
容器网络CNI实战:从零搭建网络插件
java·jvm
Mahir082 小时前
Spring 事务深度解析:核心原理与 12 种事务失效场景全解
java·spring·面试·事务失效
SL_staff2 小时前
从Zoom/腾讯会议迁移到私有化会议系统:数据迁移完整方案
java·架构
笨蛋不要掉眼泪2 小时前
Java并发编程:内存可见性与synchronized同步机制
java·开发语言·并发
用户3959924940062 小时前
Java开发者接入大模型API实战:从0到聊天机器人
java
JAVA面经实录9172 小时前
Java 多线程完整版学习文档(无遗漏终版)
java·面试
考虑考虑2 小时前
JDK26中的LazyConstant
java·后端·java ee