Java int溢出问题

最近在测试代码时,发现一个bug,到测试的最后阶段才发现,比较容易忽略。记录下来,以自省。
简单说一下代码要实现的功能,一个函数,入参是一个整型数字lastTime,代表持续时间(单位是分钟);函数功能是要计算以当前时间为起点,lastTime分钟之后的时间点,封装成一定的数据结构返回出来。

/**
 * 根据时间设置事件的时间字段
 * @param lastTime 持续时间
 * @return
 */
private TimePeriod.Builder setTimePeriods(int lastTime) {
    Date startDate = new Date();
    Date endDate = new Date(startDate.getTime() + lastTime * 1000 * 60);
   ...

    return timePeriodBuilder;
} 

第一遍功能测试时,lastTime这个参数从配置文件中随机读取一个,校验结果没有问题,也就没有关注;但是自动化执行后,发现很小的几率有case失败的情况,失败的原因就是这个函数计算出来的结果和测试代码自己计算出来的结果不匹配,当时lastTime这个参数传入的值为150000.

有问题,那就一步步执行来看,写了个main函数,直接调用开发的函数,执行到Date endDate = new Date(startDate.getTime() + lastTime * 1000 * 60);这一步时,发现endDate的结果怎么也对不上,初始一看当前的时间戳 + 持续时间(分钟) * 60 * 1000,也就是结束时刻的时间戳,没问题;后来自己手动计算lastTime * 1000 * 60的值才发现不对,才意识到lastTime这个参数是整型类型,这样计算溢出了,导致结果有问题。

Java语言里整型数字占用4个字节,表示的范围为-2^31=-2147483648到2^31=2147483647,而150000 * 60 * 1000 = 9000000000,明显溢出了。上报问题,开发把lastTime从int换成long,long类型的数字占用64个字节,可表示的数字的范围就很大了,至少目前人类能用到的时间应该不会溢出了。

过程就这样。再啰嗦两句,其实在开始测试前,我已经把开发写的代码通读了一遍,这样明显的问题应该在代码review的时候就发现。一个bug越早发现,修复它的代价就越小,向这样的bug如果遗漏上线了,通过业务场景测试一般很难发现,即使发现了某些场景下持续时间有问题,线上的业务链路都比较长,定位起来也比较费劲,故review代码很重要、单测很重要。做为一个QA,保持破坏性思维、发散性思维很重要,测得项目比较多,有些疲懒了,自省。

One thought on “Java int溢出问题

发表评论

电子邮件地址不会被公开。 必填项已用*标注

(Spamcheck Enabled)