打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
一网打尽CodeReview要点(JAVA)

常规检查

业务

1. 根据需求检查业务逻辑代码是否正确
2. 检查代码是否符合编码规范
3. 检查代码是否存在潜在bug或内存泄露
4. 检查代码是否存在性能瓶颈

常见BUG

1. 空指针异常,如使用对象时为保证其非null
2. 类型转换异常,如强制转换
3. 算术异常,如除数为0
4. 越界异常,如数组越界
5. 内存溢出异常,如栈溢出(递归)、堆溢出等
    例如:递归函数必须有闭环条件即终止条件,或递归层级建议1000以内
6. 对象隐式更新造成业务错误,如更新对象时未考虑其他业务正在使用

检验


1. API入口参数必须有常规及业务性校验
2. JAVA中对象使用之前必须有非空(null)校验,
  注意:在业务流程上有非空校验即可,例如一个对象之前已经做过校验,不做变更的情况下,再次使用则无需校验
3. 数值类型在做除数计算之前必须进行非0校验

编码风格


1. JAVA控制层访问路径,均以小写命名多个单词则以下划线相连,层级保持在5级以内
2. JAVA类名以大驼峰命名(例如:ClassName)
3. 函数及变量名以小驼峰命名(例如:functionName)
4. 常量名以全大写命名多个单词则以下划线相连(例如:NAME_TYPE)
5. 函数参数个数保持在5个以内
6. 函数返回值要以具有业务含义的对象返回,禁止使用Map作为返回值
7. 魔术数字必须以枚举的方式统一定义并描述其业务含义
9. 代码单行长度不易超过100个字符
10. 单个类文件总代码行数不可超过500行,推荐200以内
11. 单行代码不易出现多层括号嵌套,例如:(),{},[]的多层嵌套
12. 字符串比较将常量放在左边,例如 “a”.equals(name)
13. if..else嵌套不可大于3层

异常处理


1. API接口调用、库函数调用、系统服务调用必须进行异常处理或将异常抛至调用者,不可将异常信息吞掉,例如try{//业务处理}catch(Exception e){//不做任何处理}
2. 处理异常禁止如下操作,通过日志工具记录异常信息
    try{//业务处理}catch(Exception e){ e.printStackTrace(); }
3. 禁止异常处理出现在迭代里面,例如:for 、while、 foreach里面

日志规范


1. ERROR 记录造成业务异常的日志,WARN记录不影响业务流程的异常日志,INFO记录业务流程状态日志,DEBUG详细的操作或数据日志
2.  关键业务节点及业务流程发生状态变化时必须记录日志,关键函数或服务调用必须记录日志
3. 统一日志工具,例如:slf4j
4. 统一日志格式,DEBUG,INFO,WARN,ERROR,此四类级别日志
   常规日志,例如:时间 日志级别 业务类型 日志内容
   审计日志INFO级别,记录在控制层,统一日志内容格式,例如:“用户id,业务模块,操作类型,资源名称,发起地址”
5. 日志内容禁止字符串拼接,建议统一以下格式
   logger.debug("illegalCode[{}]'s pattern is null", request.getIllegalCode())
6. 在一个对象中通常只使用一个Logger对象,Logger应该是static final的,只有在少数需要在构造函数中传递logger的情况下才使用private final。
7. 输出Exceptions的全部Throwable信息,因为logger.error(msg)和logger.error(msg,e.getMessage())这样的日志输出方法会丢失掉最重要的StackTrace信息。
8. 不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一次日志。
9. 不允许出现System print(包括System.out.println和System.error.println)语句。
10. 不允许出现printStackTrace。
11. 不允许出现调试用的Systom.out.pritln("")日志
12. 日志性能的考虑,如果代码为核心代码,执行频率非常高,则输出日志建议增加判断,尤其是低级别的输出<debug、info、warn>,至少INFO以下级别必须判断,
    if(logger.isDebugEnabled()){
        logger.debug("illegalCode[{}]'s pattern is null", request.getIllegalCode())
    }

冗余代码


1. 清除冗余导入,例如:import javax.servlet.ServletContext;导入了却没有使用
2. 清除冗余注释代码,即注释掉且不用的代码
3. 清除业务代码中冗余的“main”函数及System.out.println(),如需测试建议在单元测试用测试
4. 重复性代码,若业务功能一致,必须抽离为公共模块
5. 避免冗余的导入,如:import java.util.*;
6.代码逻辑的冗余
    6.1. 业务逻辑上能提前终止的尽量提前终止,避免执行过多的代码,如:
         参数校验-->下载图片-->校验数据是否重复-->保存数据
         以上流程可以改为如下:
         参数校验-->校验数据是否重复-->下载图片-->保存数据

性能


1. 使用合适的数据类型及初始化大小
   例如:
   a. 多字符串的拼接单线程情况下使用StringBuilder
   b. 数据量固定且读操作频繁的话选择数组存储数据
   c. 集合的使用根据实际情况尽量初始化其容量
2. 资源使用完毕及时释放
   例如:
   a. 对象使用完毕,及时给变量赋值为null
   b. IO使用完毕要及时在finally中关闭掉
3. 使用合适的数据处理方式:懒加载,异步和并行处理
4. 使用合适的方式提升响应速度:缓存、队列
5. 使用对象池,处理大量对象创建的问题
6. 数组的拷贝建议使用系统函数System.arraycopy();
7. synchronized、Lock,达到需求加锁的代码范围或对象粒度越小越好,或不适用!
    例如:
    Set<String> recordIds = new HashSet<>()
    String recordIdKey = genKey();
    synchronized (recordIds) {
        if (!recordIds.contains(recordIdKey)) {
            //TODO 1 ...
            //TODO 2 ...
            recordIds.add(recordIdKey);
        }
     }
     方案1:
     Map<String,String> recordIds = new ConcurrentHashMap<>()
     String recordIdKey = genKey();
     if(recordIds.putIfAbsent()!=null){
       //TODO 1 ...
       //TODO 2 ...
     }
    方案2:
        可使用锁池,recordIdKey获取锁之后再操作
8. 迭代(for、foreach、while)嵌套不可大于3层,且在迭代中不可try...catch异常

安全检查

接口

1. 上传资源接口,必须进行资源类型、大小校验(如非必要禁止文件的执行权限)
2. 下载资源接口,必须进行下载目录校验且进行唯一性资源下载限制
3. 直接执行系统指令的API,避免指令拼接的安全隐患

业务


1. 业务层面权限校验,对资源的访问必须有权限的限制

密码


1. 密码规则应数字、字母、特殊字符组合,长度至少大于6位
2. 密码的加密规则尽量使用:AES256+IV
3. 数据库存储及配置文件中的密码应进行加密

SQL


1. sql编码,必须处理sql注入的问题
2. 请求参数必须进行特殊字符的处理(参数进入业务之前)

并发


1.  并发情况下,公共属性、对象、数据必须进行一致性处理(即并发安全处理)

文档检查

注释


1. API接口必须有功能描述,字段必须有业务描述
2. API说明文档必须和实际API接口保持一致
3. 公共函数必须有功能描述,字段必须有业务描述
4. 数据库表必须有功能描述,字段必须有业务描述
5. 常量(编码)必须有业务描述

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java动态代理实现AOP
JAVA代码编程规范
java使用动态代理来实现AOP(日志记录)的实例代码
点评阿里JAVA手册之异常日志(异常处理 日志规约 )
Android日志系统Logcat源代码简要分析
java 日志 log操作的基本配置+代码
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服