以下是对阿里巴巴java开发手册看了后的一些总结,便于自己以后复习。
功能类命名AbstractXXXXX,XXXXXExceptionXXXXXTest
boolean变量 不要用is前缀 序列化会出问题
将设计模式体现在名称中 便于阅读者快速理解
接口类中的方法和属性不要加任何修饰符号(public 也不要加)
暴露出去的服务一定是接口 实现类以Impl为后缀来区分
枚举类带上 Enum后缀
service/Dao层的命名规范:
获取单个对象 用get做前缀
获取多个对象 用list做前缀,负数结果,如:listUsers
获取统计值的方法用count做前缀。
插入的方法用save/insert做前缀。
删除的方法用remove/delete做前缀。
修改的方法用update做前缀。
领域模型命令规范:
1) 数据对象:xxxDO,xxx即为数据表名。
2) 数据传输对象:xxxDTO,xxx为业务领域相关的名称。
3) 展示对象:xxxVO,xxx一般为网页名称。
4) POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。
不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。
在long或者Long赋值时,数值后使用大写的L,不能是小写的l
常量类按类型分别创建 同时注意常量类的应用范围,将类放到合适位置
如果变量值仅在一个固定范围内变化用enum类型来定义。
if/for/while/switch/do等保留字与括号之间都必须加空格。
方法参数在定义和传入时,多个参数逗号后边必须加空格。
代码逻辑分清红花和绿叶,个性和共性,绿叶逻辑单独出来成为额外方法,使主干代码更加清晰;共性逻辑抽取成为共性方法,便于复用和维护。
不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。
所有的覆写方法,必须加@Override注解。
接口过时必须加@Deprecated注解,并清晰地说明采用的新接口或者新服务是什么。
推荐使用java.util.Objects#equals
基本类型的包装类型使用equals,比如Integer
任何货币金额,均以最小货币单位且整型类型来进行存储。
所有的POJO类属性必须使用包装数据类型。
RPC方法的返回值和参数必须使用包装数据类型。
所有的局部变量使用基本数据类型
定义DO/DTO/VO等POJO类时,不要设定任何属性默认值。
构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在init方法中。
POJO类必须写toString方法,有父类时加上super.toString
所有Service和DAO的getter/setter方法放在类体最后。
getter/setter方法中,不要增加业务逻辑,增加排查问题的难度。
不允许运行过程中重新赋值的局部变量应该声明为final。
工具类不允许有public或default构造方法。
类static成员变量如果仅在本类使用,必须是private。
若是static成员变量,考虑是否为final。
日期格式化时,传入pattern中表示年份统一使用小写的y。正例:yyyy-MM-dd HH:mm:ss
表示月份是大写的M;
表示分钟则是小写的m;
24小时制的是大写的H;
12小时制的则是小写的h。
使用枚举值来指代月份。如果使用数字,注意Date,Calendar等日期相关类的月份month取值在0-11之间。
如果自定义对象作为Map的键,那么必须覆写hashCode和equals。
判断所有集合内部的元素是否为空,使用isEmpty()方法
ArrayList的subList结果不可强转成ArrayList,subList 返回的是ArrayList的内部类SubList,对于SubList子列表的所有操作最终会反映到原列表上。
在subList场景中,高度注意对父集合元素的增加或删除,
均会导致子列表的遍历、增加、删除产生ConcurrentModificationException 异常。
使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一致、长度为0的空数组。
String[] array = new String[0];
String[] array2 = list.toArray(array);
使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,会抛出UnsupportedOperationException异常
第一种情况:list.add(“yangguanbao”); 运行时异常。
第二种情况:str[0] = “changed”; 转换后的list值也会跟着变
原则:第一、频繁往外读取内容的,适合用<? extends T>。第二、经常往里插入的,适合用<? super T>
不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
map遍历用entrySet **jdk1.8用Map.forEach()**方法
ConcurrentHashMap的 KV都不能为null
创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。自定义线程池,线程分组
线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
必须回收自定义的ThreadLocal变量,在try-finally中回收
对多个资源、数据库表、对象同时加锁时,**需要保持一致的加锁顺序,**否则可能会造成死锁。
lock.lock()要在try外面调用,避免没加锁成功还进finally去解锁
使用Timer必须捕获异常,不然定时任务会终止
所有的类注释都必须添加创建者和创建日期。
谨慎注释掉代码。在上方详细说明,而不是简单地注释掉。如果无用,则删除。
悲观锁遵循一锁二判三更新四释放的原则
子线程抛出异常堆栈,不能在主线程try-catch到。
需要注意自动拆箱导致的NPE异常。
在高并发场景中,避免使用”等于”判断作为中断或退出的条件。可能存在并发问题导致小于数量而无法停止。
表达异常分支时,多用 if{ return}
避免采用取反逻辑运算符。
写接口时,注意入参保护
被声明为private的方法,根据需要可不做校验
注释的要求:
1.能够准确反映设计思想和代码逻辑
2.能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息
生产环境禁止直接使用System.out 或System.err 输出日志
表名、字段名必须使用小写字母或数字
表名不使用复数名词。
索引名:pk uk idx_字段名
小数类型为decimal,禁止使用float和double。
如果存储的字符串长度几乎相等,使用char定长字符串类型。
id create modified 必备这三个字段 时间类型为datetime
表的命名最好是遵循“业务名称_表的作用”
单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。
tinyint unsigned
业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。
超过三个表禁止join。需要join的字段,数据类型保持绝对一致;多表关联查询时,保证被关联的字段需要有索引。
在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。
深度分页(先获取id再关联)
SELECT a. FROM 表1 a, (select id from 表1 where 条件 LIMIT 100000,20 ) b where a.id=b.id*
不要使用count(列名)或count(常量)来替代count();count()会统计值为NULL的行
使用ISNULL()来判断是否为NULL值。
表的别名加as
在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。
即使所有类属性名与数据库字段一一对应,也需要定义;反过来,每一个表也必然有一个与之对应。
高并发服务器调小tcp协议的time_wait超时时间,调大文件句柄
给jvm设置参数**-XX:+HeapDumpOnOutOfMemoryError**参数,让JVM碰到OOM场景时输出dump信息。
在线上生产环境,JVM的Xms和Xmx设置一样大小的内存容量,避免在GC 后调整堆大小带来的压力。
类在设计与实现时要符合单一原则。
谨慎使用继承的方式来进行扩展,优先使用聚合/组合的方式来实现。 说明:不得已使用继承的话,必须符合里氏代换原则,此原则说父类能够出现的地方子类一定能够出现