当前位置: 首页 > article >正文

CodeReview-checkList-Java版

一、背景说明

CodeReview对于提升代码质量、减少缺陷、促进团队协作等方面有着不可替代的作用,越早发现问题,修复的成本就越低,强烈建议在项目提测前,做好CodeReview方面的工作。虽然AI已经有较大的进步,但是还无法完全替代人工,此文希望为研发CodeReview提供指导,也希望更多的人参与进来,一起从实践中完善我们的CodeReview-checkList。

二、CodeReview清单

CodeReview将涵盖代码规范、设计、逻辑、性能及稳定性、安全性等多个方面。

大类

检查项

代码规范

命名规范

  • 变量命名

    • 使用有意义的变量名,避免使用单字母变量名(如ij等,仅在循环中可适当使用)。

    • 遵循驼峰命名法(如customerNameorderDetails)。

    • 避免使用拼音或缩写,除非是通用缩写(如idurl)。

  • 类名和接口名

    • 使用大驼峰命名法(如CustomerServiceOrderRepository)。

    • 明确表达类或接口的功能和职责

  • 方法名

    • 使用动词短语命名(如calculateTotalPricevalidateUserInput)。

    • 清晰反映方法的功能

  • 常量命名

    • 使用全大写字母,单词之间用下划线分隔(如MAX_COUNTDEFAULT_VALUE)。

代码格式:为了减少代码合并冲突,使用公司统一的代码checkstyle配置

代码风格

  • 可读性

    • 避免过长的方法或类,建议方法不超过50行,类不超过500行。

    • 避免嵌套过深的逻辑,建议嵌套层次不超过3层,各分支处理逻辑清晰。

    • 注释清晰简洁,且语义与逻辑一致。

  • 一致性

    • 在整个项目中保持一致的代码风格和规范,代码写完后,强烈建议格式化下代码

          在IntelliJ IDEA中,格式化代码的默认快捷键是:

          Windows/Linux系统Ctrl + Alt + L

          Mac系统Command + Option + L

    设计

    类和接口设计

    • 单一职责原则

      • 类是否只负责一项功能,避免职责过多。

    • 开闭原则

      • 是否通过接口或抽象类实现扩展性,避免修改现有代码。

    • 里氏替换原则

      • 子类是否能够完全替换父类,且不破坏程序的正确性。

    • 接口隔离原则

      • 是否避免接口过于庞大,接口是否只包含必要的方法。

    • 依赖倒置原则

      • 是否依赖于抽象而不是具体实现。

    设计模式

    • 合理使用设计模式(如单例模式、工厂模式、策略模式等)。

    • 避免过度使用设计模式,导致代码复杂化。

    模块化

    • 是否将功能划分为独立的模块,模块之间是否低耦合、高内聚。

    • 是否通过包结构合理组织代码,包名是否清晰表达功能。

    • 对象设计职责明确,对象模型属性归属符合业务场景。

    容量设计

    • 预估数据增量,存储设计满足未来3年业务发展诉求,并评估是否需要分库分表(根据TPS/QPS)。--提前到方案设计环节,这里做check

    • 数据库/表设计符合规范要求,数据库规范

    • 数据表字段长度符合业务场景诉求,ID类型强烈建议用bigint(20),避免长度不足导致存储问题。

    并发/幂等设计

    • 根据场景要求,分布式环境下多节点数据并发访问控制措施是否得当(redis全局锁 / 数据行悲观锁 or 乐观锁)。

    • 表单数据重复提交问题。

    • 同个JVM内多线程并发安全问题(解决方式:锁同步 / 并发数据结构 / 无锁编程技术 / 本地线程变量等)。

    • 消息消费幂等控制能力(可以根据消息ID或者消息语义特征做唯一性控制,避免重复消费对业务产生影响)。

    兼容性设计

    • 表结构变更兼容性:变更数据表结构,对已运行的线上版本的影响。

    • 数据的兼容性问题(包括mysql数据,redis数据等,新旧版本数据处理是否兼容)。

    • 接口兼容性:对外提供的接口是否有更新,是否兼容。不建议通过更改老接口的方式更新,而应该通过新增接口进行版本替换。

    逻辑正确性

    边界条件处理

    • 检查输入参数是否为空或非法(如null、空字符串、负数等)。

    • 处理集合为空、数组越界等边界情况。

    • 默认值设置,例如使用Switch语句,default等设置是否正确

    异常处理

    • 合理使用异常处理机制,避免直接抛出NullPointerException等运行时异常。

    • 捕获异常后进行适当的日志记录和错误处理,便于问题定位,而不是简单地打印堆栈信息。

    • 异常处理错误文案友好,API层要考虑用户体验问题,避免使用容易误解或引起恐慌的文案。

    • 遇到异常,是否正常回收资源,例如打开的文件是否关闭,手工事务是否正常回滚等。

    • 如果数据读取异常,是否需要有默认的兜底策略,让业务具备高可用性?还是直接报错更好?

    逻辑正确性

    • 避免重复代码,通过提取公共方法或类来复用逻辑。

    • 避免逻辑过于复杂,是否可以通过简化逻辑来提高可读性。

    性能及稳定性等

    性能

    • 取数有道:避免一次性读取过多数据,导致JVM内存不足的OOM风险及系统卡死等,接口应该约定取数条数;

    • 控制分页深度:大表需要控制分页深度,避免系统被人为操作导致故障;

    • 查询走索引:对查询条件进行必填验证约束(例如时间跨度),并确保索引正确建立,避免无输入的全表扫描;

    • 缓存:对于读多写少的场景,适合使用分布式缓存或者本地缓存,以提高性能;

    • 异步化:可以异步化的,尽可能通过消息机制解决;

    • for循环性能优化:不要通过for循环访问下游接口,应该让下游提供批量查询接口;不要用for循环一条条更新数据,应该改用批量更新,而且要控制每次批量插入或者更新的数量,减少死锁发生概率;

    • 并行调用:相对独立的RPC调用,可以并行调用,再组装结果,减少串行调用的等待时间;

    • 数据库事务优化:代码中不要随意写事务,事务要快进快出原则,事务中不要包含耗时的RPC调用,应该准备好数据后,再进行事务操作,要避免大方法直接使用@Transactional注解;

    • 日志治理:日志打印要有用精简,减少对磁盘IO的压力,线上千万不要打印到控制台,容易日志死锁;

    • RPC访问快速失败:Rpc访问非必要不重试,减少下游系统压力,RPC调用应该快速失败

    • 对象只取一次:一个大方法内,相同对象只取一次原则,减少对数据库的访问次数,避免重复相同查询,例如大方法里面可能有多个子方法,每个方法都调用getOrderById的场景,除第一次,其余应该传对象即可;

    • 算法与数据结构:数据结构设计是否正确高效,算法是否有提升空间。

    • 池化技术:是否可以通过线程池技术,避免频繁创建和销毁线程 / socket等昂贵资源,减少内存消耗。

    • 避免死锁:数据库及线程处理要特别关注释放时机,避免死锁。

    稳定性设计

    • 弱依赖降级/熔断:弱依赖接口是否有开关可以关闭,或者设定超时时间,避免长时间等待,自己被拖垮。

    • 故障切换设计:依赖的第三方能力,是否有开关可以进行服务商的切换。

    • 自我修复:业务流程是否具备自我修复能力,用户重试后,流程可以正确处理。

    • 异常补全:批量数据处理,如果中间有异常,后续是否可以补全。

    安全性

    输入验证

    • 输入验证:对用户输入进行严格的验证,避免SQL注入、XSS攻击等安全问题。

    • 文件格式限制:对上传文件格式,进行严格控制,避免被埋入木马文件等。

    • 密码强度限制:对密码进行强度验证,提升门槛,减少弱密码。

    • 多因素认证(MFA):引入多因素认证机制,增加账户安全性。

    身份验证和授权

    • 正确实现身份验证和授权机制,避免未授权访问敏感数据。

    敏感信息保护

    • 日志脱敏:避免在日志中记录敏感信息(如密码、用户隐私数据等),如要记录,需要脱敏。

    • 密码安全管理:应该根据场景选择合适的加密方式(AES256、RSA、国密等),设置盐值要有一定复杂性,且线上和线下环境要有区别。

    • 数据加密:对敏感信息进行加密存储和传输。

    觉得有用,就点赞,有补充的,也欢迎留言


    http://www.kler.cn/a/539402.html

    相关文章:

  • Win11下搭建Kafka环境
  • 【人工智能】Python中的序列到序列(Seq2Seq)模型:实现机器翻译
  • 2025/2/10 心得
  • 日志2025.2.9
  • StochSync:可在任意空间中生成360°全景图和3D网格纹理
  • 集成学习(二):从理论到实战(附代码)
  • GOland的context的使用
  • MYSQL 创建索引
  • 集成学习(二):从理论到实战(附代码)
  • CSGHub高效管理|解锁DeepSeek R1蒸馏模型 :高效推理的新选择
  • 【stm32学习】STM32F103实操primary2(FlyMCU)
  • 【图像处理】- 基本图像操作
  • Linux网络之http协议
  • Docker安装pypiserver私服
  • Jupyter Notebook 6/7 设置代码补全
  • Windows图形界面(GUI)-QT-C/C++ - QT 文本编辑控件详解
  • 旋转位置编码(RoPE)讲解和代码实现
  • < OS 有关 > Ubuntu 版本升级 实践 24.04 -> 24.10, 安装 .NET
  • Ranger 2.1.0 Admin安装
  • 处理数据及其选择关键列进行一次聚类
  • 【前端基础】深入解析JavaScript中的编译原理、内存管理、垃圾回收机制和正则表达式
  • 深度学习中的Checkpoint是什么?
  • 软件工程与土木工程的不同
  • uniapp访问django目录中的图片和视频,2025[最新]中间件访问方式
  • DeepSeeek如何在Window本地部署
  • 全面的生成式语言模型学习路线