《阿里巴巴Java开发手册1.4.0》阅读总结与心得(二)

(六)并发处理

  12. 【推荐】 在并发场景下, 通过双重检查锁double-checked locking实现延迟初始化的优化问题隐患(可参考 The "Double-Checked Locking is Broken" Declaration), 推荐解决方案中较为简单一种适用于 JDK5 及以上版本,将目标属性声明为 volatile
  反例:
    

 1     class LazyInitDemo {
 2     private Helper helper = null;
 3     public Helper getHelper() {
 4         if (helper == null) synchronized(this) {
 5             if (helper == null)
 6             helper = new Helper();
 7         }
 8     return helper;
 9     }
10     // other methods and fields...
11     } 

  看法:双重检查锁可能因为指令重排引发的线程安全问题在《Java并发编程实战》一书中有提及,然而这种延迟初始化的单例有特定的背景,过去机器内存资源比较珍贵。现在的服务器动辄几十个G的内存,很多时候不要把问题搞得太复杂,饿汉式单例模式直接搞起就行。

 

(二)异常日志

(一)异常处理

  4. 【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。

  看法:private方法可以处理或者重抛异常,public方法处理异常,如果能这样做,可以大大降低异常处理逻辑紊乱/疏漏。

 

(三)MySQL规约

(一)建表规约

  9. 【强制】表必备三字段:id, gmt_create, gmt_modified。 说明:其中id必为主键,类型为unsigned bigint、单表时自增、步长为1。gmt_create, gmt_modified 的类型均为 date_time 类型。 

  看法:整数类型的自增主键以及创建和修改时间确实是非常有必要的,但名字不一定得要是gmt_create,gmt_modified,类型不一定要datetime。整数类型的自增主键的必要性在于每次插入都在B+树的末尾,相比无序插入,split操作会少很多。

(二)索引规约

  7.【推荐】建组合索引的时候,区分度最高的在最左边。

  正例:如果 where a=? and b=? ,a 列的几乎接近于唯一值,那么只需要单建 idx_a 索引即 可。 说明:存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。如:where a>? and b=? 那么即使 a 的区分度更高,也必须把 b 放在索引的最前列。 

  看法:建索引真是一门学问,比较简单的入门就是按照选择性来定索引。曾经看到公司项目库中有多重索引把删除标志位都给包括进去了,删除标志位虽然是sql查询语句的一部分,但选择性很低,建索引完全没必要。

(三)SQL语句

  1. 【强制】不要使用 count(列名)count(常量)来替代 count(*)count(*)SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。

  说明: count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

  看法:sql语句规范非常重要

(四)ORM映射

  5. 【强制】 iBATIS 自带的 queryForList(String statementName,int start,int size)不推荐使用。

  说明:其实现方式是在数据库取到 statementName对应的SQL语句的所有记录,再通过 subListstart,size 的子集合。

  正例:

  Map<String, Object> map = new HashMap<>();

  map.put("start", start);

  map.put("size", size);

posted @ 2019-05-23 16:33  卍荆轲刺秦王卍  阅读(176)  评论(0编辑  收藏  举报