Java_语法基础_边界,边界,还是边界

某商家生产的电子产品非常畅销,需要提前30天预订才能抢到手,同时它还规定了一个会员可拥有的最多产品数量,目的是防止囤积压货肆意加价。会员的预定过程是这样的:先登录官方网站,选择产品型号,然后设置需要预定的数量,提交,符合规则即提示下单成功,不符合规则提示下单失败。后台的处理逻辑模拟如下:

package deep;

import java.util.Scanner;

public class Client {
    // 一个会员拥有产品的最多数量
    public static final int LIMIT = 2000;

    public static void main(String[] args) {
        // 会员当前拥有的产品数量
        int cur = 1000;
        Scanner input = new Scanner(System.in);
        System.out.println("请输入需要预定的数量:");
        while (input.hasNextInt()) {
            int order = input.nextInt();
            // 当前拥有的与准备订购的产品数量之和
            if (order > 0 && order + cur <= LIMIT) {
                System.out.println("你已成功预定了" + order + "个产品!");
            } else {
                System.out.println("超过限额,预订失败!");
            }
        }
    }
}

这是一个简单的订单处理程序,其中cur代表的是会员已经拥有的产品数量,LIMIT是一个会员最多拥有的产品数量(现实中这两个参数当然是从数据库中获得的,不过这里是一个模拟程序),如果当前预订数量与拥有数量之和超过了最大数量,则预订失败,否则下单成功。业务逻辑很简单,同时在Web界面上对订单数量做了严格的校验,比如不能是负值、不能超过最大数量等,但是人算不如天算,运行不到两小时数据库中就出现了异常数据:某会员拥有产品的数量与预订数量之和远远大于限额。怎么会这样?程序逻辑上不可能有问题呀,这是如何产生的呢?我们来模拟一下,第一次输入:

请输入需要预定的数量:
600
你已成功预定了600个产品!

这完全满足条件,没有任何问题,继续输入:

请输入需要预定的数量:
2147483647
你已成功预定了2147483647个产品!

看到没,这个数字远远超过了2000的限额,但是竟然预订成功了,真是神奇!
看着2147483647这个数字很熟?那就对了,它是int类型的最大值(2^31-1),没错,有人输入了一个最大值,使校验条件失效了,Why?我们来看程序,order的值是2147483647,那再加上1000就超出int的范围了,其结果是-2147482649,那当然是小于正数2000了!一句话可归结其原因:数字越界使校验条件失效。

所以我们可以把判断条件修改为(order > 0 && order <= LIMIT - cur),这样就避免了用户输入的数值参与计算,而仅用来比较。

在单元测试中,有一项测试叫做边界测试(也有叫做临界测试),如果一个方法接收的是int类型的参数,那以下三个值是必测的:0、正最大、负最小,其中正最大和负最小是边界值,如果这三个值都没有问题,方法才是比较安全可靠的。我们的例子就是因为缺少边界测试,致使生产系统产生了严重的偏差。

也许你要疑惑了,Web界面既然已经做了严格的校验,为什么还能输入2147483647这么大的数字呢?是否说明Web校验不严格?错了,不是这样的,Web校验都是在页面上通过JavaScript实现的,只能限制普通用户(这里的普通用户是指不懂HTML、不懂HTTP、不懂Java的简单使用者),而对于高手,这些校验基本上就是摆设,HTTP是明文传输的,将其拦截几次,分析一下数据结构,然后再写一个模拟器,一切前端校验都成了浮云!想往后台提交个什么数据那还不是信手拈来?!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值