写代码有这16个好习惯,可以减少80%非业务的bug
往期热门文章: 1、《往期精选优秀博文都在这里了!》 2、Redis 分布式锁使用不当,超卖了100瓶飞天茅台!!! 3、数据库读写分离的这些坑,让我一脸懵逼! 4、接口的幂等性的N种考虑,你知道吗? 5、如果程序员和产品经理都用凡尔赛文学对话......
前言
1、《往期精选优秀博文都在这里了!》 2、Redis 分布式锁使用不当,超卖了100瓶飞天茅台!!! 3、数据库读写分离的这些坑,让我一脸懵逼! 4、接口的幂等性的N种考虑,你知道吗? 5、如果程序员和产品经理都用凡尔赛文学对话......
1. 修改完代码,记得自测一下
![](https://filescdn.proginn.com/a7a5d30c7b70fd1747214e63f0249b9c/840cdd50a7c35d40e2c5ba27e2ebd66e.webp)
2. 方法入参尽量都检验
![](https://filescdn.proginn.com/ec0568d48d4172983289f9abbabee467/ce83261c7f6c9a9a0413a316945de28a.webp)
3. 修改老接口的时候,思考接口的兼容性。
//老接口
void oldService(A,B);{
//兼容新接口,传个null代替C
newService(A,B,null);
}
//新接口,暂时不能删掉老接口,需要做兼容。
void newService(A,B,C);
![](https://filescdn.proginn.com/625476df332b7aba50369e788b6e316d/e290f28ffc88ba0639111e04dce38033.webp)
4.对于复杂的代码逻辑,添加清楚的注释
![](https://filescdn.proginn.com/6a54dd0e38b3df40573a2355e7cd6a96/a00fa53bc2711822b54be032ebb6e0ee.webp)
5. 使用完IO资源流,需要关闭
![](https://filescdn.proginn.com/a1ed6eac3578237e07deca97a477252e/85530fbed87f96b238673e2379374a9c.webp)
FileInputStream fdIn = null;
try {
fdIn = new FileInputStream(new File("/jay.txt"));
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}finally {
try {
if (fdIn != null) {
fdIn.close();
}
} catch (IOException e) {
log.error(e);
}
}
/*
* 关注公众号,捡田螺的小男孩
*/
try (FileInputStream inputStream = new FileInputStream(new File("jay.txt")) {
// use resources
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
6.代码采取措施避免运行时错误(如数组边界溢出,被零除等)
String name = list.get(1).getName(); //list可能越界,因为不一定有2个元素哈
if(CollectionsUtil.isNotEmpty(list)&& list.size()>1){
String name = list.get(1).getName();
}
![](https://filescdn.proginn.com/bbebc82830ef81b1bc9a14f216567712/178dfbb0bea196dae227fb953f8fed8d.webp)
7.尽量不在循环里远程调用、或者数据库操作,优先考虑批量进行。
remoteBatchQuery(param);
for(int i=0;i remoteSingleQuery(param)
}
![](https://filescdn.proginn.com/d9f71de09e0614cd57fc1fc79358807b/2c1c4d34573bfeb31e69640c6c6e1f12.webp)
8.写完代码,脑洞一下多线程执行会怎样,注意并发一致性问题
if(isAvailable(ticketId){
1、给现金增加操作
2、deleteTicketById(ticketId)
}else{
return "没有可用现金券";
}
![](https://filescdn.proginn.com/b6691f124c8d076a27f580b1dac0bc4a/cd30f5735a6096b77566b690c752fca6.webp)
1.线程A加现金 2.线程B加现金 3.线程A删除票标志 4.线程B删除票标志
if(deleteAvailableTicketById(ticketId) == 1){
1、给现金增加操作
}else{
return “没有可用现金券”
}
![](https://filescdn.proginn.com/f97e81caaa6f17219c6e6931acba2ec1/1be770dc915ff36923fa3cdbb57e88a0.webp)
9.获取对象的属性,先判断对象是否为空
if(object!=null){
String name = object.getName();
}
![](https://filescdn.proginn.com/b34edaa31a5d8ff4f69d70d7388b45e2/038a48ef45e1f5ac672d630516514874.webp)
10.多线程异步优先考虑恰当的线程池,而不是new thread,同时考虑线程池是否隔离
它帮我们管理线程,避免增加创建线程和销毁线程的资源损耗。 提高响应速度。 重复利用。
![](https://filescdn.proginn.com/17d18b55c71b6e7dcc261893d03aa672/2b21577ae4012a823ce01acbc0ee3e00.webp)
11. 手动写完代码业务的SQL,先拿去数据库跑一下,同时也explain看下执行计划。
explain select * from user where userid =10086 or age =18;
![](https://filescdn.proginn.com/c092982f084a2e06fb59db2e94105c22/9db14c5368491771597635a565d23d81.webp)
12.调用第三方接口,需要考虑异常处理,安全性,超时重试这几个点。
异常处理(比如,你调别人的接口,如果异常了,怎么处理,是重试还是当做失败) 超时(没法预估对方接口一般多久返回,一般设置个超时断开时间,以保护你的接口) 重试次数(你的接口调失败,需不需要重试,需要站在业务上角度思考这个问题)
![](https://filescdn.proginn.com/1c2efa0b1efd51db0470544156048d17/db20c6059f022e92e1b12739e3bcc16f.webp)
13.接口需要考虑幂等性
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。
查询操作 唯一索引 token机制,防止重复提交 数据库的delete删除操作 乐观锁 悲观锁 Redis、zookeeper 分布式锁(以前抢红包需求,用了Redis分布式锁) 状态机幂等
![](https://filescdn.proginn.com/294caff0606a751b8035b637d0c32d05/54d835a2af2a98cd41a66cabd8deee9b.webp)
14. 多线程情况下,考虑线性安全问题
Hashmap、Arraylist、LinkedList、TreeMap等都是线性不安全的; Vector、Hashtable、ConcurrentHashMap等都是线性安全的
![](https://filescdn.proginn.com/8750b234d1d866a045d71f288a0c96fc/039749ed10a8160cc9153c299f50eea0.webp)
15.主从延迟问题考虑
![](https://filescdn.proginn.com/c4bc911f3852183e9cf61556084dde3c/7e300515b7eef616b8804bf2e1708aad.webp)
如果是重要业务,需要考虑是否强制读主库,还是再修改设计方案。 但是呢,有些业务场景是可以接受主从稍微延迟一点的,但是这个习惯还是要有吧。 写完操作数据库的代码,想下是否存在主从延迟问题。
16.使用缓存的时候,考虑缓存跟DB的一致性,还有(缓存穿透、缓存雪崩和缓存击穿)
缓存雪崩:指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。 缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。 缓存击穿:指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。
![](https://filescdn.proginn.com/261d37923eb94420e43f215b64fa5b75/57647b96b3c867f006f94972b2f30622.webp)
往期热门文章:
4、GitHub 标星 1.3k+,一款超赞的用于字符串处理的 Java 8 库
评论