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

阿里巴巴Java开发手册学习记录

阿里巴巴Java开发手册学习记录

一、编程规约

1.命名风格

  • 严禁使用英文 + 拼音混合使用

  • 类名应所有单词的首字母大写,除了(UserDO,XxxDTO, XxxPo等)

  • 常量的命名应该是大写 + 单词间用下划线连接

  • 抽象类的应以Abstract/Base开头

  • POJO类中的布尔变量,都不要以is前缀,否则某些框架解析会引起序列化错误, 。 (之前看一个文章就是因为XxxDTO方法的命名为isXxxXxx(),导致方法被错误的序列化,造成了线上事故,文章:https://mp.weixin.qq.com/s/994BAkKPEeBz_gs_6LN2DQ)

  • 如果模块、接口、类、方法使用了设计模式,应体现在命名中

  • 领域模型命名规约

    • 数据对象:xxxDO, xxx为数据表名
  • 数据传输对象:xxxDTO, xxx为业务领域相关

  • 展示对象,xxxVO,xxx为网页名称

  • POJO是DO/DTO/BO/VO的统称,禁止使用xxxPOJO

  • 如果变量值仅在一个固定范围内变化用enum声明

2.代码格式

  • 单行字符限制不超过120各,超出要换行:
    • 第二行相对于第一行缩进4个空格
    • 运算符与下文一起换行(例如:“.”)
    • 方法调用中多个参数,在逗号后换行
  • 可以插入一个空行将不同的逻辑、语义、谈业务分隔开,提高可读性。

3.OOP规约

  • 所有重写父类的方法都需要加@Override,可以判断是否重写成功
  • 接口过时必须加@Deprecated,并说明新接口的位置。
  • 不使用过时的类和方法
  • 在使用equals时,应使用常量或者确定有值的对象的equals的方法
  • 所有的POJO类属性必须使用包装类型,RPC方法的返回值和参数必须使用包装类型
  • 如果完全不兼容升级,避免反序列化混乱,要修改serialVersionUID
  • 构造方法中不加任何业务逻辑
  • 禁止在POJO类中同时存在一个属性的isXxx()和getXxx()方法
    • 因为在序列化时,不确定优先调用哪个方法,对于is开头的枚举型变量,会在序列化调用isXxx的时候会把属性的is吃掉,导致序列化出错。(案例:https://zhuanlan.zhihu.com/p/265869701)
    • 解决方案:1.遵循开发规范,不要用is开头的变量。2.使用JSONField(name = “anotherName”)来定制属性名。3.可以手动修改getter和setter。
  • 类内方法定义顺序:公有方法>私有>getter/setter方法
  • 对象的clone方法默认时浅拷贝,若想要实现深拷贝,需要重写clone方法。
  • 工具类不允许有public和default构造方法

4.集合处理

  • 只要重写equals,就必须重写hashcode
  • 使用set存储自定义对象时,自定义对象需要重写equals、hashcode 方法
  • 在使用sublist方法时,对原集合的增加或删除,均会导致子列表遍历、增加、删除产生并发修改异常。
  • 在进行list的toArray(size)方法转数组时,应该传入list.size()作为参数这样返回的就是当前类型的数组,如果直接使用无参toArray方法时,返回值是Object类型的数组。
  • Arrays.asList()把数组转换成集合时,不可以使用add等修改方法,否则抛异常。
  • PECS(Producer Extends Consumer Super)原则:频繁往外读取内容的,适合用<? extends T>。经常往里插入的,适合用<? super T>。
  • 不用在foreach里进行元素的remove/add操作,remove可以使用iterator方式,如果并发操作需要对Iterator对象加锁。(这里虽说foreach本质也是迭代器实现,但是反编译以后会发现最后删除时是通过list直接remove,而迭代器删除的是通过迭代器的remove方法删除的

5.并发处理

  • 获取单例对象时,需要保证线程安全
  • 应该使用ThreadPoolExecutor创建线程池
  • SimpleDateFormat线程不安全,如果定义为static,必须加锁,也可以使用DateUtils
  • 如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 SimpleDateFormat
  • 对多个资源(表、对象)同时加锁时,应该保持加锁顺序的一致性,避免死锁。
  • 并发修改同一记录时,避免更新丢失,可以在应用层、缓存加锁,或者数据库层使用乐观锁。(如果每次访问冲突概率小于20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3 次。)
  • 避免多个线程使用一个Random(Random或Math.random),会导致性能下降,可以使用ThreadLocalRandom
  • 在多线程场景下计数,volatile无法应对多写的场景,一般我们会选择AtomicInteger,但是在竞争比较激烈的场景下,可以使用LongAdder性能更好(空间换时间,内部将数组分段计数最后求和,但是只使用计数场景下)。
  • ThreadLocal 建议使用static修饰,只需要创建一次,一个线程内的所有对象都已操作这个变量。

6.控制语句

  • 高并发场景中,避免使用等于作为中断或者退出的条件,如果并发条件没有处理好,会出现等值“击穿”的情况,所以应该使用大于或者小于
  • 避免在if条件判断中使用复杂的方法,(getXxx/isXxx除外)
  • 循环体内要考虑性能,所以一些不必要的操作应该放到循环体外进行

7.注释规约

  • 注释的主要作用:能精确反应设计思想和代码逻辑、描述业务含义。
  • 代码逻辑修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑
  • 所有的枚举类型的字段必须要有注释

8.异常处理

  • catch异常时,对于非稳定代码来说catch尽量区分异常类型,再做对应的异常处理,不要对一大段代码做try-catch处理
  • 捕获了异常就应该处理它
  • 应该严格避免NPE

9.日志规约

  • 应用中不可直接使用日志系统(Log4j、Logback)中的Api,而应该依赖日志框架SLF4J中的Api。
  • 应用中的扩展日志命名方式:appName_logType_logName.log
  • 对trace/debug/info级别的日志输出,应该使用条件输出或者使用占位符(slf4j支持占位符),对于warn等不满足的日志级别,即使不输出,但也会准备参数,浪费系统资源。
  • 生产环境禁止输出debug级别日志,有选择地输出info日志,写日志输出语句时思考:有人看吗?看到这条日志能做什么?能不能给排查问题带来好处?
  • 可以使用warn日志级别来记录用户输出参数错误。

持续更新…

http://www.lryc.cn/news/113237.html

相关文章:

  • 论文阅读---《Unsupervised T ransformer-Based Anomaly Detection in ECG Signals》
  • 收藏这8个好用的原型设计工具,轻松制作原型图
  • 王道计网 第四章笔记
  • C# Blazor 学习笔记(9):动态css/class绑定
  • vue3学习-Pinia状态管理
  • TextBrewer:融合并改进了NLP和CV中的多种知识蒸馏技术、提供便捷快速的知识蒸馏框架、提升模型的推理速度,减少内存占用
  • 乍得ECTN(BESC)申请流程
  • 【100天精通python】Day28:文件与IO操作_JSON文件处理
  • 配置两台数据库为主从数据库模式
  • linux允许root远程ssh登录
  • Baumer工业相机堡盟工业相机如何通过BGAPISDK获取相机接口数据吞吐量(C++)
  • Spring @Scheduled单线程单实例的坑
  • 7-数据结构-(带头节点)单链表的增删改查
  • 每天一道leetcode:剑指 Offer 53 - II. 0~n-1中缺失的数字(适合初学者二分查找)
  • 玩机搞机---安卓新机型payload.bin刷写救砖 无需专用线刷包
  • 配置固定二级子域名远程访问内网群晖NAS 7.X版 【内网穿透】——“cpolar内网穿透”
  • 【枚举】CF1706 C
  • uniapp-疫情应急管理系统学生端
  • FreeRTOS的线程间通信
  • Linux内存管理工作原理:
  • 【并发编程】ShenyuAdmin里面数据同步用到的无锁环形队列LMAX Disruptor并发框架
  • Nginx(2)
  • 二维数组的鞍点
  • go 内置函数copy()
  • Spring简述
  • 框框大学之——教育技术学
  • Android中的Apk 包体优化
  • Java基础接口详解
  • CCL 2023 电信网络诈骗案件分类评测-第一名方案
  • go test