news 2026/6/11 9:23:14

那些年,我们写过的低级BUG,警钟长鸣

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
那些年,我们写过的低级BUG,警钟长鸣

又一个低级的生产BUG

if(newDto.getStoreName().equals(oldDto.getStoreName())&&newDto.getStoreCode().equals(oldDto.getStoreCode())&&newDto.getGoodsName().equals(oldDto.getGoodsName())&&newDto.getGoodsSpec().equals(oldDto.getGoodsSpec())&&newDto.getStallName().equals(oldDto.getStallName())&&newDto.getUnitName().equals(oldDto.getUnitName())){//不更新}else{updList.add(newDto);}
  • 问题是:没有对属性null做判断导致NPE
    修改后的代码:
if(Objects.equals(newDto.getStoreName(),oldDto.getStoreName())&&Objects.equals(newDto.getStoreCode(),oldDto.getStoreCode())&&Objects.equals(newDto.getGoodsName(),oldDto.getGoodsName())&&Objects.equals(newDto.getGoodsSpec(),oldDto.getGoodsSpec())&&Objects.equals(newDto.getStallName(),oldDto.getStallName())&&Objects.equals(newDto.getUnitName(),oldDto.getUnitName())){//不更新}else{updList.add(newDto);}

java.util包都提供这个工具类了,还有什么不用起来的理由!!出这种问题太他妈丢人了,写的时候是咋想的啊!

又一个低级的生产BUG

publicstaticMultiPriceInfogetMultiPriceInfo(List<MultiPriceInfo>multiPriceInfos,Stringcode){if(CollectionUtils.isEmpty(multiPriceInfos)){returnnull;}for(MultiPriceInfopriceInfo:multiPriceInfos){if(priceInfo.getPriceCode().equals(code)){returnpriceInfo;}}returnnull;}
  • 问题1 作为一个public方法,没有校验参数code
  • 问题2. priceInfo.getPriceCode().equals(code)可能会抛出NPE,因为priceInfo.getPriceCode()可能会返回null。

修改以后的代码:

publicstaticMultiPriceInfogetMultiPriceInfo(List<MultiPriceInfo>multiPriceInfos,Stringcode){// 增加对code的校验if(CollectionUtils.isEmpty(multiPriceInfos)||StringUtils.isEmpty(code)){returnnull;}for(MultiPriceInfopriceInfo:multiPriceInfos){// 前面已经确保了code不是nullif(code.equals(priceInfo.getPriceCode())){returnpriceInfo;}}returnnull;}

两个修改点:

  • 增加对入参code为空的校验。
  • 改为code.equals(priceInfo.getPriceCode())。

就因为这个小小的问题,从凌晨0点搞到将近3点,就是找不到问题在哪,对代码还是有敬畏之心,不能太随意,安安稳稳躺床上睡觉它不香吗!!!

还有一点:如果是异步执行,一定要在异步方法的最外层加一个try-catch-finally进行兜底,否则全局异常拦截器拦截不到,再没有catch的话,就只能进shell看日志了!就怕没有shell的权限!

又一个低级的生产BUG

上周五,生产环境的二维码下载功能开始频繁报警,看了下代码,下载二维码这个功能服务端提供了2个接口,一个是生成二维码的压缩包,放到tomcat的临时目录里面,然后第二个是下载接口,现在的问题是,第一个接口没问题,第二个接口报的NPE。第二个接口非常简单,就是读取文件写到respoonse里面,如果NPE那就只有一个可能,那就是下载的文件不存在。并且这个接口有一定概率报错,还不是必现的,我只好猜测因为下载的文件是存放在临时目录,是不是因为系统硬盘空间不足而被系统删除了,但是本地怎么也模拟不出来!在这个方面浪费了大量的时间,还是没找到一点头绪,幸亏系统有全链路监控日志,后来仔细观察日志,才发现是异常是在一个Aop的拦截器里面抛出来,根本不是业务代码抛出来的!它是这么写的:

@Aspect@ComponentpublicclassLogApiAdvice{@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")publicObjectdoAround(ProceedingJoinPointjoinPoint)throwsThrowable{try{Objectresult=joinPoint.proceed();if(result.getClass().isAssignableFrom(ApiResult.class)){....}else{....}returnresult;}catch(Throwablethr){....throwthr;}}}

我们的下载的接口是这样的:

@ApiOperation("下载二维码")@RequestMapping(value="/downCodeZip")publicvoiddownCodeZip(HttpServletResponseresponse,StringzipFilePath){}

很显然,方法的返回值是null,因此在aop里面就发生了NPE!很低级的一个失误,导致生产不停报警,最终代码回滚,写代码还是得注意啊!

修改方法签名导致的bug

有一个方法原先是返回Integer,此方法在多个地方被调用,改的时候改成了返回String,自测通过,junit也正常,但是上生产报错了!
按道理说,只要方法签名名改了,所有调用的地方应该编译就报错啊,操蛋的是项目使用了MapStruct,背后自动把String又转成了Integer,所以编译完全没问题,但是一旦返回null就炸了。
结论:修改方法一定要全局检索调用的地方,不要仅仅依赖编译器。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 9:23:12

Koikatu HF Patch终极指南:200+插件与完整翻译体验一键解锁

Koikatu HF Patch终极指南&#xff1a;200插件与完整翻译体验一键解锁 【免费下载链接】KK-HF_Patch Automatically translate, uncensor and update Koikatu! and Koikatsu Party! 项目地址: https://gitcode.com/gh_mirrors/kk/KK-HF_Patch 还在为《恋活&#xff01;》…

作者头像 李华
网站建设 2026/6/11 9:23:09

MC9S08JS16嵌入式开发实战:从USB集成到低功耗设计

1. 项目概述与芯片定位在嵌入式开发领域&#xff0c;选型往往是项目成功的第一步。面对市场上琳琅满目的微控制器&#xff0c;工程师们常常需要在性能、成本、功耗和集成度之间寻找最佳平衡点。对于许多需要USB连接、成本敏感且对实时性有一定要求的应用——比如自定义的HID设备…

作者头像 李华
网站建设 2026/6/11 9:23:08

I2C总线协议深度解析与MC9S08DE60实战应用

1. I2C总线协议&#xff1a;从基础到实战的深度解析在嵌入式系统开发中&#xff0c;设备间的通信是构建复杂功能的基础。面对众多通信协议&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff09;以其简洁的两线制、支持多主多从、以及相对适中的速率&#xff0c;成为…

作者头像 李华
网站建设 2026/6/11 9:22:51

别再搞混了!Isaac Sim中相机、图像、机器人坐标系的保姆级图解指南

Isaac Sim坐标系全解析&#xff1a;从原理到实战避坑指南第一次在Isaac Sim里调试机器人抓取动作时&#xff0c;我盯着屏幕上那个往完全相反方向移动的机械臂发呆了五分钟——明明代码里的坐标计算看起来天衣无缝&#xff0c;为什么实际执行时会出现这种低级错误&#xff1f;直…

作者头像 李华
网站建设 2026/6/11 9:22:48

HTML5语义化标签深度解析:div、section与article的底层实现原理

一、概述 HTML5引入了一系列语义化标签&#xff0c;其中<div>、<section>和<article>是最常被混淆的三个元素。虽然它们在外观上几乎没有任何区别——浏览器默认渲染均为块级元素——但它们在语义层面、可访问性&#xff08;Accessibility&#xff09;支持以…

作者头像 李华