谈谈防御性编程_防御性策略
wptr33 2025-09-19 03:56 65 浏览
防御性编程对于程序员来说是一种良好的代码习惯,是为了保护自己的程序在不可未知的异常下,避免带来更大的破坏性崩溃,使得程序在错误发生时,依然能够云淡风轻的处理,但很多程序员入行很多年,写出的代码依然都是我行我素,在CodeReview时经常性的会被人反问,这种情况出现的概率极低,有必要去做控制吗?,有必要去做处理吗?
举个例子
一、一个很简单的工具类:实现的功能很简单,就是列出在开始时间与结束时间之间的所有的年月,看这段代码有什么问题?
public static List<String> getDayList(Date start, Date end){
if(end ==null){
end = new Date();
}
if(start ==null){
start = end;
}
if(start.after(end)){
return null;
}
// 开始时间
Calendar calBegin=Calendar.getInstance();
calBegin.setTime(start);
calBegin.set(calBegin.get(Calendar.YEAR),calBegin.get(Calendar.MONTH), 1);
// 结束时间
Calendar calEnd =Calendar.getInstance();
calEnd.setTime(end);
calEnd.set(calEnd.get(Calendar.YEAR),calEnd.get(Calendar.MONTH), 2);
List<String> dateList = new ArrayList<>();
while (calBegin.before(calEnd)){
dateList.add(format(calBegin.getTime(),"yyyyMM"));
calBegin.add(Calendar.MONTH,1);
}
return dateList;
}初看一下,感觉没什么问题,该判空的也判空了,但真的没有问题吗?假设开始时间为2020-01-01,而结束时间为20202020-01-01,这将出现什么情况?看到这里大致大家已经明白了,开始时间与结束时间的间隔没有被限制,这就可能会导致dateList爆满,从而导致内存暴涨,会直接导致CPU暴涨,导致服务卡死。
二、再来看一个例子:一个简单的往队列里面放入一个元素,然后在从队列里面取出元素进行业务逻辑处理,典型的生产者-消费者的这么一个使用场景,这里有什么问题?
class Test{
private static BlockingQueue<String> blockingQueue=new LinkedBlockingQueue();
public static void add(String element){
blockingQueue.add(element);
}
public static void execute(){
String element=blockingQueue.poll();
if(element!=null){
//处理业务逻辑
}
}
}这个例子,比前面一个例子稍微简单些,大致大家一看可能就明白了,blockingQueue没有设置大小,是一个无界队列,如果因为消费的业务逻辑处理慢的情况,可能也会导致Queue的数据大小不可控,从而导致内存暴涨。
通过上述两个简单的例子,不难发现,均是遗漏了对于代码的防御性编程,从而带来了程序执行的不可控因素,最终均会导致服务卡死,业务中断,那么防御性编程在编程的时候主要要考虑哪些方面呢?
常见的防御性编程方法
一、严把参数质量关
在防御性编程的眼里,任何上下游的参数均是不可置信的,均为做出假设,如果上游调用方给出的参数不准确,将作何反应,因此参数的检测是必不可少的。
参数的检查主要在以下几个方面考虑
1、参数的格式是否存在问题
2、参数的取值范围是否在预期范围内,尤其是边界问题
3、参数的类型是否符合要求
4、多个参数的传值是否符合业务逻辑,比如有些参数之间是存在互斥的,比如有一些计算金额的参数,是要满足一定的计算公式.......
二、异常的处理机制是否优雅?
很多程序员为了图省事,直接在代码里面一个大的try....catch,企图通过一个try....catch 去解决所有异常问题,这是典型懒的行为。
一般来说不同类型的异常处理的方式均有可能存在着差异,比如有些情况下的异常,如网络异常,通过一定的重试机制就能解决。而有一些幂等的异常,是可以直接进行忽略,因此如何进行优雅的异常处理,对于防御性编程尤为重要。
需要针对于不同的异常进行针对性的处理,首先要对于可能产生的异常进行分类,然后提出以下问题
1、该异常是否可以通过重试恢复?
2、该异常是否可以通过兜底措施恢复?
3、该异常是否属于正常的异常,例如幂等异常?
4、该异常是否需要人工干预?
........
另外良好的错误码设计,对于调用方来说,也较为重要,调用方能通过错误码能清晰的知道,该错误是属于一个什么场景下的异常,是业务不符逻辑还是系统层面的?是一个严重的还是一个一般的异常等等。
三、在程序内部常使用断言进行内部检查
在程序内部要经常性的插入检查点,用于验证程序在某些特定的场景下,程序的执行依然符合预期,比如对于一个集合进行排序,那么我们是否可以采用断言来检查这个集合是否是真正有序的,从而保证程序的执行和实际的结果是符合预期的。
最后
防御性编程是稳定性建设中很重要的一个思维,是能有效提升系统稳定性,减少了线上故障发生,提高用户体验的很重要的手段,很多防御性编程是可以通过CR、代码编程规范以及辅以漏洞扫描工具去发现和解决,让问题尽可能的在上线前发现和解决。
相关推荐
- oracle数据导入导出_oracle数据导入导出工具
-
关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...
- 继续学习Python中的while true/break语句
-
上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个else解...
- python continue和break的区别_python中break语句和continue语句的区别
-
python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...
- 简单学Python——关键字6——break和continue
-
Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...
- 2-1,0基础学Python之 break退出循环、 continue继续循环 多重循
-
用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...
- Python 中 break 和 continue 傻傻分不清
-
大家好啊,我是大田。今天分享一下break和continue在代码中的执行效果是什么,进一步区分出二者的区别。一、continue例1:当小明3岁时不打印年龄,其余年龄正常循环打印。可以看...
- python中的流程控制语句:continue、break 和 return使用方法
-
Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...
- L017:continue和break - 教程文案
-
continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...
- 作为前端开发者,你都经历过怎样的面试?
-
已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...
- 面试被问 const 是否不可变?这样回答才显功底
-
作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...
- 2023金九银十必看前端面试题!2w字精品!
-
导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。答案:CSS的盒模型是用于布局和定位元素的概念。它由内容区域...
- 前端面试总结_前端面试题整理
-
记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...
- 由浅入深,66条JavaScript面试知识点(七)
-
作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录由浅入深,66条JavaScript面试知识点(一)由浅入深,66...
- 2024前端面试真题之—VUE篇_前端面试题vue2020及答案
-
添加图片注释,不超过140字(可选)1.vue的生命周期有哪些及每个生命周期做了什么?beforeCreate是newVue()之后触发的第一个钩子,在当前阶段data、methods、com...
- 今年最常见的前端面试题,你会做几道?
-
在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...
- 一周热门
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)
