(一)编程规约
1.命名风格
- 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长
- POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误
- 杜绝完全不规范的缩写,避免望文不知义
- 在常量与变量的命名时,表示类型的名词放在词尾,以提升辨识度
- 如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式
- 接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,确定与接口方法相关,并且是整个应用的基础常量
- 枚举类名带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开
- 各层命名规约:
- A) Service/DAO 层方法命名规约
- 1) 获取单个对象的方法用 get 做前缀。
- 2) 获取多个对象的方法用 list 做前缀,复数结尾,如:listObjects。
- 3) 获取统计值的方法用 count 做前缀。
- 4) 插入的方法用 save/insert 做前缀。
- 5) 删除的方法用 remove/delete 做前缀。
- 6) 修改的方法用 update 做前缀。
- B) 领域模型命名规约
- 1) 数据对象:xxxDO,xxx 即为数据表名。
- 2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
- 3) 展示对象:xxxVO,xxx 一般为网页名称。
- 4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
2.常量定义
- 不允许任何魔法值(即未经预先定义的常量)直接出现在代码中
- 在 long 或者 Long 赋值时,数值后使用大写字母 L,不能是小写字母 l,小写容易跟数字混淆,造成误解
3.代码格式
- 左小括号和右边相邻字符之间不出现空格;右小括号和左边相邻字符之间也不出现空 格;而左大括号前需要加空格,如if (a == b)
- if/for/while/switch/do 等保留字与括号之间都必须加空格
- 任何二目、三目运算符的左右两边都需要加一个空格,包括赋值运算符=、逻辑运算符&&、加减乘除符号等
- 采用 4 个空格缩进,禁止使用 Tab 字符
public static void main(String[] args) { // 缩进 4 个空格 String say = "hello"; // 运算符的左右必须有一个空格 int flag = 0; // 关键词 if 与括号之间必须有一个空格,括号内的 f 与左括号,0 与右括号不需要空格 if (flag == 0) { System.out.println(say); } // 左大括号前加空格且不换行;左大括号后换行 if (flag == 1) { System.out.println("world"); // 右大括号前换行,右大括号后有 else,不用换行 } else { System.out.println("ok"); // 在右大括号后直接结束,则必须换行 } }
- 注释的双斜线与注释内容之间有且仅有一个空格
- 在进行类型强制转换时,右括号与强制转换值之间不需要任何空格隔开
- 方法参数在定义和传入时,多个参数逗号后面必须加空格
- 不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性
4.OOP规约
- 所有整型包装类对象之间值的比较,全部使用 equals 方法比较
- 浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断
- 所有的 POJO 类属性必须使用包装数据类型
- RPC 方法的返回值和参数必须使用包装数据类型
- 定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值
- 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中
- 慎用 Object 的 clone 方法来拷贝对象
5.日期时间
- 日期格式化时,传入 pattern 中表示年份统一使用小写的 y ,】在日期格式中分清楚大写的 M 和小写的 m,大写的 H 和小写的 h 分别指代的意义 ,new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”)
- 获取当前毫秒数:System.currentTimeMillis(); 而不是 new Date().getTime()。 如果想获取更加精确的纳秒级时间值,使用 System.nanoTime 的方式
- 不允许在程序任何地方中使用:1)java.sql.Date。 2)java.sql.Time。 3)java.sql.Timestamp。
- 不要在程序中写死一年为 365 天,避免在公历闰年时出现日期转换错误或程序逻辑 错误
6.集合处理
- 判断所有集合内部的元素是否为空,使用 isEmpty()方法,而不是 size()==0 的方式
- 在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要使 用含有参数类型为 BinaryOperator,参数名为 mergeFunction 的方法,否则当出现相同 key 值时会抛出 IllegalStateException 异常。
- 在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要注 意当 value 为 null 时会抛 NPE 异常
- ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异 常
- 使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一 致、长度为 0 的空数组
- 在使用 Collection 接口任何实现类的 addAll()方法时,都要对输入的集合参数进行 NPE 判断
- 使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
- 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁
7.并发处理
- 获取单例对象需要保证线程安全,其中的方法也要保证线程安全
- 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯
- 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程
- 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这 样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险
- 高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能 锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁
- 对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造 成死锁
- 在使用阻塞等待获取锁的方式中,必须在 try 代码块之外,并且在加锁方法与 try 代 码块之间没有任何可能抛出异常的方法调用,避免加锁成功后,在 finally 中无法解锁
- 在使用尝试机制来获取锁的方式中,进入业务代码块之前,必须先判断当前线程是否 持有锁。锁的释放规则与锁的阻塞等待方式相同
- 并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加 锁,要么在数据库层使用乐观锁,使用 version 作为更新依据
- 多线程并行处理定时任务时,Timer 运行多个 TimeTask 时,只要其中之一没有捕获抛 出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService 则没有这个问题
8.控制语句
- 当 switch 括号内的变量类型为 String 并且此变量为外部参数时,必须先进行 null 判断
- 在 if/else/for/while/do 语句中必须使用大括号
- 三目运算符 condition? 表达式 1 : 表达式 2 中,高度注意表达式 1 和 2 在类型对齐时,可能抛出因自动拆箱导致的 NPE 异常
- 在高并发场景中,避免使用”等于”判断作为中断或退出的条件
- 除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复 杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性
- 不要在其它表达式(尤其是条件表达式)中,插入赋值语句
- 循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、 获取数据库连接,进行不必要的 try-catch 操作(这个 try-catch 是否可以移至循环体外)
9.注释规约
- 类、类属性、类方法的注释必须使用 Javadoc 规范,使用/*内容/格式,不得使用 // xxx 方式
- 所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能
- 所有的类都必须添加创建者和创建日期
- 所有的枚举类型字段必须要有注释,说明每个数据项的用途
10.前后端规约
- 前后端交互的 API,需要明确协议、域名、路径、请求方法、请求内容、状态码、响应体 ,URL路径不能使用大写,单词如果需要分割,统一使用下划线
- 前后端数据列表相关的接口返回,如果为空,则返回空数组[]或空集合{}
- 对于需要使用超大整数的场景,服务端一律使用 String 字符串类型返回,禁止使用 Long 类型
- HTTP 请求通过 URL 传递参数时,不能超过 2048 字节
- 在翻页场景中,用户输入的参数小于 1,则前端返回第一页参数给后端;后端发现用 户输入的参数大于总页数,直接返回最后一页
- 服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL 统一代理模块 生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来 URL 维护 不一致的问题
- 前后端的时间格式统一为"yyyy-MM-dd HH:mm:ss",统一为 GMT
11.其他
- 在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度,即不要再方法体内定义正则表达式,应将表达式赋给字符串
- 注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够 取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后 取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法
- 及时清理不再使用的代码段或配置信息,对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一规定使用三个斜杠(///) 来说明注释掉代码的理由。
(二)异常日志
1.异常处理
- Java 类库中定义的可以通过预检查方式规避的 RuntimeException 异常不应该通过 catch 的方式来处理,比如:NullPointerException,IndexOutOfBoundsException 等等。 无法通过预检查的异常除外,比如,在解析字符串形式的数字时,可能存在数字格式错误,不得不 通过 catch NumberFormatException 来实现
- 异常捕获后不要用来做流程控制,条件控制
- catch 时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。 对于非稳定代码的 catch 尽可能进行区分异常类型,再做对应的异常处理。对大段代码进行 try-catch,使程序无法根据不同的异常做出正确的应激反应,也不利于定位问题, 这是一种不负责任的表现
- 不要在 finally 块中使用 return
- 捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类
- 方法的返回值可以为 null,不强制返回空集合,或者空对象等,必须添加注释充分说 明什么情况下会返回 null 值
- 防止 NPE,是程序员的基本修养,注意 NPE 产生的场景: 1) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。 反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。 2) 数据库的查询结果可能为 null。 3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。 4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。 5) 对于 Session 中获取的数据,建议进行 NPE 检查,避免空指针。 6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。
2.日志规约
- 应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 (SLF4J、JCL–Jakarta Commons Logging)中的 API,使用门面模式的日志框架,有利于维护和 各个类的日志处理方式统一。
- 所有日志文件至少保存 15 天,因为有些异常具备以“周”为频次发生的特点。对于 当天日志,以“应用名.log”来保存,保存在/home/admin/应用名/logs/目录下,过往日志 格式为: {logname}.log.{保存日期},日期格式:yyyy-MM-dd
- 根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存 的日志不少于六个月,并且进行网络多机备份。
- 在日志输出时,字符串变量之间的拼接使用占位符的方式。 如:logger.debug(“Processing trade with id: {} and symbol: {}”, id, symbol);
- 避免重复打印日志,浪费磁盘空间,务必在日志配置文件中设置 additivity=false。
- 生产环境禁止直接使用 System.out 或 System.err 输出日志或使用 e.printStackTrace()打印异常堆栈。
- 异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过 关键字 throws 往上抛出。
(三)单元测试
- 好的单元测试必须遵守 AIR 原则。
- A:Automatic(自动化)
- I:Independent(独立性)
- R:Repeatable(可重复)
- 单元测试应该是全自动执行的,并且非交互式的。测试用例通常是被定期执行的,执 行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。单元 测试中不准使用 System.out 来进行人肉验证,必须使用 assert 来验证。
- 保持单元测试的独立性。为了保证单元测试稳定可靠且便于维护,单元测试用例之间 决不能互相调用,也不能依赖执行的先后次序。
- 保持单元测试的独立性。为了保证单元测试稳定可靠且便于维护,单元测试用例之间 决不能互相调用,也不能依赖执行的先后次序
- 单元测试是可以重复执行的,不能受到外界环境的影响。
- 对于单元测试,要保证测试粒度足够小,有助于精确定位问题。单测粒度至多是类级 别,一般是方法级别。
- 单元测试的基本目标:语句覆盖率达到 70%;核心模块的语句覆盖率和分支覆盖率都 要达到 100%
- 编写单元测试代码遵守 BCDE 原则,以保证被测试模块的交付质量。
- B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
- C:Correct,正确的输入,并得到预期的结果。
- D:Design,与设计文档相结合,来编写单元测试。
- E:Error,强制错误信息输入(如:非法数据、异常流程、业务允许外等),并得到预期的结果。
- 对于数据库相关的查询,更新,删除等操作,不能假设数据库里的数据是存在的,或 者直接操作数据库把数据插入进去,请使用程序插入或者导入数据的方式来准备数据。
- 对于不可测的代码在适当的时机做必要的重构,使代码变得可测,避免为了达到测试 要求而书写不规范测试代码。
(四)安全规约
- 用户敏感数据禁止直接展示,必须对展示数据进行脱敏。 例如手机号。
- 用户输入的 SQL 参数严格使用参数绑定或者 METADATA 字段值限定,防止 SQL 注入, 禁止字符串拼接 SQL 访问数据库。
- 用户请求传入的任何参数必须做有效性验证。
- 禁止向 HTML 页面输出未经安全过滤或未正确转义的用户数据。
- 表单、AJAX 提交必须执行 CSRF 安全验证。
- URL 外部重定向传入的目标地址必须执行白名单过滤。
- 在使用平台资源,譬如短信、邮件、电话、下单、支付,必须实现正确的防重放的机 制,如数量限制、疲劳度控制、验证码校验,避免被滥刷而导致资损。
- 发贴、评论、发送即时消息等用户生成内容的场景必须实现防刷、文本内容违禁词过 滤等风控策略。
(五)MySQL数据库
1.建表规约
- 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint (1 表示是,0 表示否)。 任何字段如果为非负数,必须是 unsigned。
- POJO 类中的任何布尔类型的变量,都不要加 is 前缀,所以,需要在设置从 is_xxx 到 Xxx 的映射关系。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的命名方式是为了明确其取值含 义与取值范围。
- 表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只 出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
- 表名不使用复数名词。
- 主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
- 小数类型为 decimal,禁止使用 float 和 double。
- varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
- 表必备三字段:id, create_time, update_time。
- 表的命名最好是遵循“业务名称_表的作用”。 如:alipay_task
- 库名与应用名称尽量一致。
- 单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
2.索引规约
- 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。 不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外, 即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。
- 超过三个表禁止 join。需要 join 的字段,数据类型保持绝对一致;多表关联查询时, 保证被关联的字段需要有索引。
- 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据 实际文本区分度决定索引长度。
- 页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。
3.SQL语句
- 不要使用 count(列名)或 count(常量)来替代 count(),count()是 SQL92 定义的标 准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。 count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。
- count(distinct col) 计算该列除 NULL 之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为 NULL,那么即使另一列有不同的值,也返回为 0。
- 当某一列的值全是 NULL 时,count(col)的返回结果为 0,但 sum(col)的返回结果为 NULL,因此使用 sum()时需注意 NPE 问题。 可以使用如下方式来避免 sum 的 NPE 问题:SELECT IFNULL(SUM(column), 0) FROM table;
- 使用 ISNULL()来判断是否为 NULL 值。 NULL 与任何值的直接比较都为 NULL
- 代码中写分页查询逻辑时,若 count 为 0 应直接返回,避免执行后面的分页语句。
- 不得使用外键与级联,一切外键概念必须在应用层解决。
- 数据订正(特别是删除或修改记录操作)时,要先 select,避免出现误删除,确认无 误才能执行更新语句。
- 对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或 表名)进行限定。
- SQL 语句中表的别名前加 as,并且以 t1、t2、t3、…的顺序依次命名。
- in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控 制在 1000 个之内。
4.ORM映射
- 在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。
- POJO 类的布尔属性不能加 is,而数据库字段必须加 is_,要求在 resultMap 中进行 字段与属性之间的映射。
- 不要用 resultClass 当返回参数,即使所有类属性名与数据库字段一一对应,也需要 定义;反过来,每一个表也必然有一个与之对应。
- sql.xml 配置参数使用:#{},#param# 不要使用${} 此种方式容易出现 SQL 注入。
- 不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出。
- 更新数据表记录时,必须同时更新记录对应的 update_time 字段值为当前时间。
- 不要写一个大而全的数据更新接口。传入为 POJO 类,不管是不是自己的目标更新字 段,都进行 update table set c1=value1,c2=value2,c3=value3; 这是不对的。执行 SQL 时, 不要更新无改动的字段,一是易出错;二是效率低;三是增加 binlog 存储。
- @Transactional 事务不要滥用。事务会影响数据库的 QPS,另外使用事务的地方需 要考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正等。
(六)工程结构
1.应用分层
- DO(Data Object):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
- DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
- BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象。
- Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类 来传输。
- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
2.二方库依赖
- 定义 GAV 遵从以下规则:
- 1) GroupID 格式:com.{公司/BU }.业务线 [.子业务线],最多 4 级。 说明:{公司/BU} 例如:alibaba/taobao/tmall/aliexpress 等 BU 一级;子业务线可选。 正例:com.taobao.jstorm 或 com.alibaba.dubbo.register
- 2) ArtifactID 格式:产品线名-模块名。语义不重复不遗漏,先到中央仓库去查证一下。 正例:dubbo-client / fastjson-api / jstorm-tool。正例:dubbo-client / fastjson-api / jstorm-tool
- 3) Version:详细规定参考下方。
- 二方库版本号命名方式:主版本号.次版本号.修订号。注意起始版本号必须为:1.0.0,而不是 0.0.1。
- 线上应用不要依赖 SNAPSHOT 版本(安全包除外);正式发布的类库必须先去中央仓 库进行查证,使 RELEASE 版本号有延续性,且版本号不允许覆盖升级。
- 二方库的新增或升级,保持除功能点之外的其它 jar 包仲裁结果不变。如果有改变, 必须明确评估和验证。
- 二方库里可以定义枚举类型,参数可以使用枚举类型,但是接口返回值不允许使用枚 举类型或者包含枚举类型的 POJO 对象。
- 依赖于一个二方库群时,必须定义一个统一的版本变量,避免版本号不一致。
- 禁止在子项目的 pom 依赖中出现相同的 GroupId,相同的 ArtifactId,但是不同的 Version。
3.服务器
- 高并发服务器建议调小 TCP 协议的 time_wait 超时时间。 操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服务器端会因为 处于 time_wait 的连接数太多,可能无法建立新的连接,所以需要在服务器上调小此等待值。
- 调大服务器所支持的最大文件句柄数(File Descriptor,简写为 fd)。
- 给 JVM 环境参数设置-XX:+HeapDumpOnOutOfMemoryError 参数,让 JVM 碰到 OOM 场景时输出 dump 信息。
- 在线上生产环境,JVM 的 Xms 和 Xmx 设置一样大小的内存容量,避免在 GC 后调整 堆大小带来的压力。
- 服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL Broker 生成,否 则因线上采用 HTTPS 协议而导致浏览器提示“不安全“。此外,还会带来 URL 维护不一致的 问题。
(七)设计规约
(八)专有名词
- POJO(Plain Ordinary Java Object): 在本规约中,POJO 专指只有 setter/getter/toString 的 简单类,包括 DO/DTO/BO/VO 等。
- DO(Data Object):阿里巴巴专指数据库表一一对应的 POJO 类。此对象与数据库表结构一 一对应,通过 DAO 层向上传输数据源对象。
- DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
- BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象。
- Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。
- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
- AO(Application Object): 阿里巴巴专指 Application Object,即在 Service 层上,极为贴近 业务的复用代码。
- CAS(Compare And Swap):解决多线程并行情况下使用锁造成性能损耗的一种机制,这是 硬件实现的原子操作。CAS 操作包含三个操作数:内存位置、预期原值和新值。如果内存位 置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何 操作。
- GAV(GroupId、ArtifactId、Version): Maven 坐标,是用来唯一标识 jar 包。
- OOP(Object Oriented Programming): 本文泛指类、对象的编程处理方式。
- AQS(AbstractQueuedSynchronizer): 利用先进先出队列实现的底层同步工具类,它是很多上 层同步实现类的基础,比如:ReentrantLock、CountDownLatch、Semaphore 等,它们通 过继承 AQS 实现其模版方法,然后将 AQS 子类作为同步组件的内部类,通常命名为 Sync。
- ORM(Object Relation Mapping): 对象关系映射,对象领域模型与底层数据之间的转换,本 文泛指 iBATIS, mybatis 等框架。
- NPE(java.lang.NullPointerException): 空指针异常。
- OOM(Out Of Memory): 源于 java.lang.OutOfMemoryError,当 JVM 没有足够的内存 来为对象分配空间并且垃圾回收器也无法回收空间时,系统出现的严重状况。
- 一方库: 本工程内部子项目模块依赖的库(jar 包)。
- 二方库: 公司内部发布到中央仓库,可供公司内部其它应用依赖的库(jar 包)。 17.三方库: 公司之外的开源库(jar 包)。
想了解更多关于java中需要注意的一些代码编写规范的内容,请扫微信
或微信搜索jiemingpan
本文链接:http://www.soufuzi.com/jianzhan/1409