《改善java程序的151个建议》读书笔记 之 数值边界

建议24:边界,边界,还是边界
某商家生产的电子产品非常畅销,需要提前30天预订才能抢到手,同时它还规定了一个
会员可拥有的最多产品数量,目的是防止囤积压货肆意加价。会员的预定过程是这样的:先
登录官方网站,选择产品型号,然后设置需要预订的数量,提交,符合规则即提示下单成
该文档是极速PDF编辑器生成,
如果想去掉该提示,请访问并下载:
http://www.jisupdfeditor.com/
2017/10/20
55/396
功,不符合规则提示下单失败。后台的处理逻辑模拟如下:
public class Client{
//
一个会员拥有产品的最多数量
public final static int LIMIT=2000
public static void main String[]args {
//
会员当前拥有的产品数量
int cur=1000
Scanner input=new Scanner System.in );
System.out.print " 请输入需要预定的数量: " );
while input.hasNextInt ()) {
int order=input.nextInt
();
// 当前拥有的与准备订购的产品数量之和
if order 0 && order+cur =LIMIT {
System.out.println
" 你已经成功预定的 "+order+" 个产品! " );
}else{
System.out.println
" 超过限额,预订失败! " );
} } } }
这是一个简易的订单处理程序,其中cur代表的是会员已经拥有的产品数量,LIMIT是一
个会员最多拥有的产品数量(现实中这两个参数当然是从数据库中获得的,不过这里是一个
模拟程序),如果当前预订数量与拥有数量之和超过了最大数量,则预订失败,否则下单成
功。业务逻辑很简单,同时在Web界面上对订单数量做了严格的校验,比如不能是负值、不
能超过最大数量等,但是人算不如天算,运行不到两小时数据库中就出现了异常数据:某会
员拥有产品的数量与预订数量之和远远大于限额。怎么会这样?程序逻辑上不可能有问题
呀,这是如何产生的呢?我们来模拟一下,第一次输入:
请输入需要预定的数量: 800
你已经成功预定的 800 个产品!
该文档是极速PDF编辑器生成,
如果想去掉该提示,请访问并下载:
http://www.jisupdfeditor.com/
2017/10/20
56/396
这完全满足条件,没有任何问题,继续输入:
请输入需要预定的数量: 2147483647
你已经成功预定的 2147483647 个产品!
看到没,这个数字远远超过了2000的限额,但是竟然预订成功了,真是神奇!
看着2147483647这个数字很眼熟?那就对了,它是int类型的最大值,没错,有人输入
了一个最大值,使校验条件失效了,Why?我们来看程序,order的值是2147483647,那再加
上1000就超出int的范围了,其结果是-2147482649,那当然是小于正数2000了!一句话可归
结其原因:数字越界使检验条件失效。
在单元测试中,有一项测试叫做边界测试(也有叫做临界测试),如果一个方法接收的
是int类型的参数,那以下三个值是必测的:0、正最大、负最小,其中正最大和负最小是边
界值,如果这三个值都没有问题,方法才是比较安全可靠的。我们的例子就是因为缺少边界
测试,致使生产系统产生了严重的偏差。
也许你要疑惑了,Web界面既然已经做了严格的校验,为什么还能输入2147483647这么
大的数字呢?是否说明Web校验不严格?错了,不是这样的,Web校验都是在页面上通过
JavaScript实现的,只能限制普通用户(这里的普通用户是指不懂HTML、不懂HTTP、不懂
Java的简单使用者),而对于高手,这些校验基本上就是摆设,HTTP是明文传输的,将其拦
截几次,分析一下数据结构,然后再写一个模拟器,一切前端校验就都成了浮云!想往后台
提交个什么数据那还不是信手拈来?!

猜你喜欢

转载自blog.csdn.net/weixin_36997847/article/details/80225194
今日推荐