Java常见CodeReview及编码规范

鉴于自己的开发经验,以及常见容易产生bug及性能问题的点做个记录.

1.数据库

如果开发人员的经验不足,Java通过ORM(Mybatis)对数据库的操作的性能问题比较隐蔽.因为不压测或者异常case没发生的时候一般发现不了问题.特别是异常case发生的时候.

  1. 除配置表以外的sql都要经过explain分析表扫描范围.必须控制在range级别及以下
  2. Mybatis防sql注入: #{}传入的参数在SQL中显示为字符串,#{}方式能够很大程度防止sql注入.${}传入的参数在SqL中直接显示为传入的值,${}方式无法防止Sql注入
  3. selectList之类的操作,必须要限定返回的行数.有时候没有条件传入很可能就是全表扫描返回了.
  4. Mybatis的LambdaQueryWrapper的 in()函数入参有上限.超过则会报错
  5. 禁止多表联合join
  6. 多多利用主键索引或唯一索引提升查询效率
  7. 用批量插入代替循环迭代插入
  8. 表设计时,后期若有分库分表需求的,主键不可使用自增id,不方便迁移数据.可以使用分布式主键生成器,例如Snowflake算法生成的ID
  9. 表设计时,建立合理的联合索引,覆盖索引,最大程度覆盖查询需求
  10. 表设计时,尽量不要允许null值,状态类字段用精简的字符串枚举
  11. 查询数据库数据只返回必要的字段,一般不使用select *

2.Java基础API

  1. HashMap迭代使用entrySet() 获取Map 的key 和value
  2. 使用Collection.isEmpty()而不是Collection.size()来判空, O(1)
  3. 初始化集合,Map,队列一般都要指定初始大小.谨慎使用无界队列
  4. 使用StringBuilder 拼接字符串
  5. 字符串转化使用String.valueOf(value),可以避免NPE
  6. 方法返回值不要返回null,返回空集合或者对象都行
  7. 使用equals方法时,常量放前面
  8. 尽量不要出现魔法值,多多使用枚举,枚举的属性字段必须是私有且不可变
  9. 工具类设计成单例或者池化,工具类中屏蔽(private)构造函数
  10. 使用线程池时要注意队列大小以及拒绝策略,若发生拒绝时该如何保证业务逻辑原子性
  11. 若使用http调用必须要有超时限制,以及超时处理
  12. 加锁时,专锁专用,顺序加锁,避免死锁发生的可能
  13. 使用线程池配合ThreadLocal时养成remove的习惯,规避潜在的溢出风险

3.Spring

  1. 事务失效问题,注意事务传播特性,特别注意嵌套方法catch异常的问题,导致业务数据不完整
  2. 避免大事务
  3. 分布式事务影响性能,可以选择无事务的最终一致性实现
  4. 使用构造函数注入而不是字段注入,以提高代码的可测试性和可维护性
  5. 有大量的@Scheduled任务需要同一时刻执行时,调大默认Scheduled线程的数量.否则可能会导致一些任务阻塞住
  6. 避免频繁的对象创建和销毁,使用合适的对象池或缓存
  7. 关键日志信息打印,合理使用日志级别.代码注释完备

4.性能提升

  1. 比较重要的就是接口性能优化,利用并发工具类等手段提升接口响应时间.比如用completeFuture CountDownLatch等并发处理业务数据
  2. 涉及其他服务调用的接口,必须有快速熔断,不能因为上游服务的问题影响本身的服务.需要充分考虑别的服务返回给自身的数据异常的情况
  3. 利用分布式缓存提升接口性能
  4. 可以异步执行的逻辑可以放到消息队列或异步线程.让当前接口快速响应.提升用户体验
  5. 代码实现选用业界最佳实践,比如用Disruptor队列替代ArrayBlockingQueue
  6. 多多了解各个场景的业界最佳实践,比如用NIO替代AIO

5.设计实现

  1. 接口设计实现是否符合单一职责、开闭原则等设计原则
  2. 使用接口而不是具体实现进行注入,以降低耦合性
  3. 是否有冗余、重复的代码,是否可以进行重构
  4. 代码设计实现尽量符合设计模式,提升健壮性和可维护性
  5. 沉淀基础能力,不要重复造轮子.比如动态线程池工具,分布式锁工具 可以封装成Springboot starter包.一键式装配应用

Java常见CodeReview及编码规范_第1张图片

你可能感兴趣的:(JAVA,java,代码复审,开发语言,Codereview)