分享一些工作中的习惯~

Posted by fsoooo Blog on April 13, 2022

对于复杂的代码逻辑,添加清楚的注释

写代码的时候,是没有必要写太多的注释的,好的方法变量命名就是最好的注释

但是,如果是业务逻辑很复杂的代码,真的非常有必要写清楚注释

清楚的注释,更有利于后面的维护。写注释的同时也是再次梳理逻辑,利人又利己。


###方法入参尽量都检验

入参校验也是每个程序员必备的基本素养。

你的方法处理,必须先校验参数。比如入参是否允许为空,入参长度是否符合你的预期长度。

这个尽量养成习惯吧,很多低级bug都是不校验参数导致的。

如果你的数据库字段设置为varchar(16),对方传了一个32位的字符串过来,你不校验参数,「插入数据库直接异常」了。


修改完代码,记得自测一下

改完代码,自测一下,是每位程序员必备的基本素养。

尤其不要抱有这种侥幸心理:我只是改了一个变量或者我只改了一行配置代码,不用自测了

有时候,改了当前的问题又会引入新的问题,所以改完代码,尽量要求自己都去测试一下哈,可以规避很多不必要bug的。


###修改老接口的时候,思考接口的兼容性

很多bug都是因为修改了对外老接口,但是却不做兼容导致的。

关键这个问题多数是比较严重的,可能直接导致系统发版失败的。

所以,如果你的需求是在原来接口上修改,尤其这个接口是对外提供服务的话,一定要考虑接口兼容。


尽量不在循环里远程调用、或者数据库操作,优先考虑批量进行

远程操作或者数据库操作都是比较耗网络、IO资源的,所以尽量不在循环里远程调用、不在循环里操作数据库,能批量一次性查回来尽量不要循环多次去查

当然,批量操作也要量力而行


日常判空

对象获取属性,先判断对象是否为空,这个点本来也属于采取措施规避运行时异常的,但是我还是把它拿出来,当做一个重点来写,因为平时空指针异常太常见了,一个手抖不注意,就导致空指针报到生产环境去了。

所以,你要获取对象的属性时,尽量不要相信理论上不为空,我们顺手养成习惯判断一下是否为空,再获取对象的属性。


手动写完代码业务的SQL,先拿去数据库跑一下,同时也explain看下执行计划

手动写完业务代码的SQL,可以先把它拿到数据库跑一下,看看有没有语法错误。

同时呢,也用explain看下你Sql的执行计划,尤其走不走索引这一块。


调用第三方接口,需要考虑异常处理,安全性,超时重试这几个点

调用第三方服务,或者分布式远程服务的的话,需要考虑

  • 异常处理(比如,你调别人的接口,如果异常了,怎么处理,是重试还是当做失败)
  • 超时(没法预估对方接口一般多久返回,一般设置个超时断开时间,以保护你的接口)
  • 重试次数(你的接口调失败,需不需要重试,需要站在业务上角度思考这个问题)

简单一个例子,你一个http请求调别人的服务,需要考虑设置connect-time,和retry次数。

如果是转账等重要的第三方服务,还需要考虑签名验签加密等。


接口需要考虑幂等性

接口是需要考虑幂等性的,尤其抢红包、转账这些重要接口。

最直观的业务场景,就是用户连着点两次,你的接口有没有hold住。

  • 幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
  • 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。

一般幂等技术方案有这几种:

  • 查询操作
  • 唯一索引
  • token机制,防止重复提交
  • 数据库的delete删除操作
  • 乐观锁
  • 悲观锁
  • Redis、zookeeper 分布式锁(以前抢红包需求,用了Redis分布式锁)
  • 状态机幂等


主从延迟问题考虑

先插入,接着就去查询,这类代码逻辑比较常见,这可能会有问题的。

一般数据库都是有主库,从库的。

写入的话是写主库,读一般是读从库。

如果发生主从延迟,,很可能出现你插入成功了,但是你查询不到的情况。

  • 如果是重要业务,需要考虑是否强制读主库,还是再修改设计方案。
  • 但是呢,有些业务场景是可以接受主从稍微延迟一点的,但是这个习惯还是要有吧。
  • 写完操作数据库的代码,想下是否存在主从延迟问题。


使用缓存的时候,考虑跟DB的一致性,还有(缓存穿透、缓存雪崩和缓存击穿)

通俗点说,我们使用缓存就是为了查得快,接口耗时小。但是呢,用到缓存,就需要注意缓存与数据库的一致性问题。同时,还需要规避缓存穿透、缓存雪崩和缓存击穿三大问题。

  • 缓存雪崩:指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。
  • 缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。
  • 缓存击穿:指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。


写完代码,脑洞一下多线程执行会怎样,注意并发一致性问题

我们经常见的一些业务场景,就是先查下有没有记录,再进行对应的操作(比如修改)。

但是呢,(查询+修改)合在一起不是原子操作哦,脑洞下多线程,就会发现有问题了。