前言
《阿里巴巴Java开发手册》是一本开发参考手册,内容是对于开发中的一些规范约束,绝大部分规范都是开发中共同遵守的一些常识,另外一部分是阿里巴巴内部使用的一些规范,各个公司可能要求不一样。总体来说,该手册是值得学习和肯定的,下面是一些需要特别注意的,另外大部分要求可以看看就可以了,都是普遍性的规范。
笔记内容
- 单个方法的总行数不超过80行
除注释外的方法签名、左右大括号、方法内代码、回车及任何看不见字符的总行数不超过80行; - 所有整型包装类对象之间值的比较,全部使用equals方法;
浮点数之间的等值判断,分为另种情况,如果是基本数据类型不能用 == 进行比较,如果是包装数据类型不能用 equals方法进行判断,因为浮点数采用尾数+阶码的编码方式,类似于科学计数法,二进制无法精确表示绝大部分的十进制小数。
// 基本数据类型
float a = 1.0f – 0.9f;
float b = 0.9f – 0.8f;
if (a == b) {
// 不会执行此代码块,a == b 结果是false
}
Float x = Float.valueOf(a);
Float y = Float.valueOf(B);
if (x.equals(y)) {
// 不会执行此代码块,x.equals(y) 结果是false
}
浮点类型的比较,根据类型需要采用下面两种方式进行比较:
// 基本数据类型
指定一个误差范围,两个浮点数的差值在此范围内,则认为是相等的
float diff = le-6f; // 10的-6次方
if (Math.abs(a - b) < diff) {
// 会执行此代码块
}
浮点包装类转化成BigDecimal,然后使用equals()判等。BigDecimal必须使用String类型的构造方法,或者BigDecimal.valueOf()方法(底层也是调用了参数的toString()方法)
- 所有的局部变量使用基本数据类型;所有的POJO类属性必须使用包装数据类型;RPC方法的返回值和参数必须使用包装数据类型
- 构造方法里禁止加入任何业务逻辑,如果有初始化逻辑,放在init()方法中
- POJO类必须写toString()方法,便于打印属性值,排查问题
- 如果重写equals方法,必须同时重写hashCode方法,例如Map的存储,有同时用到这两个方法
- 集合转数组,必须使用带参的构造方法,toArray(T[] array),直接使用toArray的无参构造方法存在问题,无参构造返回值只能是Object[] 类,若强制转化为其他类型,会报ClassCastException异常;
List<String> list = new ArrayList<>(2);
list.add(“ali”);
list.add(“baba);
String[] array = new String[list.size()];
array = List.toArray(array);
数组转集合,使用工具类Arrays.asList(),不能使用修改集合的方法,
因为Arrays.asList()返回的是一个Arrays内部类,并没有实现集合的修改方法。
Arrays.asList()体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] {“ali”,”baba”};
List<String> list = Arrays.asList(str);
第一种情况:list.add(“Alibaba”)运行时异常
第二种情况:如果str[0] = “changed”;,那么list.get(0)的值也会变成“changed”;
- 避免使用Apache BeanUtils进行属性的copy,性能较差,可以选用Spring BeanUtils
- 数据库索引命名:主键索引名为pk_字段名(mysql主键默认为主键索引,不需要设置),唯一索引为uk_字段名,普通索引为idx_字段名
- 确定长度的字符串,使用char定义字符串类型,因为varhcar是可变长字符串,不会预先分配存储空间。Varchar长度不要超过5000个字符,如果大于此值,应定义为text类型,独立出来一张表,用主键来对应,避免影响其他字段的索引效率;
- 布尔数据类型是unsigned tinyint,1表示是,0表示否;
- 表必备三个字段:id,create_time,update_time。id主键是unsigned bigint,create_time,update_time类型是date_time类型
- 单表行数超过500万行或者单表容量超过2GB时,才推荐进行分库分表
- 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引
- 超过三个表仅是join,多表关联查询时,被关联字段需要有索引
- 在varchar字段上建立索引时,必须指定索引的长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可
- 页面搜索禁止左模糊获取全模糊,如果需要通过搜索引擎来解决
- 如果有order by的场景,order by最后的字段是组合索引的一部分,并且放在索引组合顺序的最后
正例:
Where a = ? and b = ? order by c; 索引a_b _c
反例:
索引中有范围查找,那么索引有序性无法利用,如 where a > 10 order by b; 索引a_b无法排序 - Sql性能优化的目标,至少要达到range级别,要求是ref级别,最好是consts
常用的类型有:ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index: Full Index Scan,index与ALL区别为index类型只遍历索引树
range:只检索给定范围的行,使用一个索引来选择行
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。 - 不要使用count(列名)或count(常量)来替代count(),count()是sql92定义的标准统计行数的语法,跟数据库无关,会统计值为null的行。
- 禁止外键的级联更新、禁止使用存储过程;
- in操作能避免则避免,不能避免也要控制in的元素在1000个以内
- POJO类的布尔属性不能加is,而数据库字段必须加is_,要求在resultMap中进行字段与属性之间的映射