重读阿里巴巴java开发手册——记录与自我理解

前言

博主本周花了三天的时间,重读了阿里巴巴的java开发手册,里面遗漏的一些点,以及一些自我解读,现在在此进行记录。

内容

一、编程规约

(四)OOP规约

13.【强制】禁止在POJO类中,同时存在对应属性xxx的isXxx()和getXxx()方法。
14.【推荐】使用索引访问用String的split方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有抛IndexOutOfBoundsException的风险。
17.【推荐】setter方法中,参数名称与类成员变量名称一致,this.成员名=参数名。在getter/setter方法中,不要增加业务逻辑,增加排查问题的难度

(五)集合处理

2.【强制】ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常,即java.util.RandomAccessSubListcannotbecasttojava.util.ArrayList。说明:subList返回的是ArrayList的内部类SubList,并不是ArrayList而是ArrayList的一个视图,对于SubList子列表的所有操作最终会反映到原列表上。
3.【强制】在subList场景中,高度注意对原集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生ConcurrentModificationException异常
7.【强制】不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
11.【推荐】使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。说明:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。正例:values()返回的是V值集合,是一个list集合对象;keySet()返回的是K值集合,是一个Set集合对象;entrySet()返回的是K-V值组合集合。

Map<String,String> tt = new HashMap<>();
        tt.put("1","t1");
        tt.put("2","t2");
        tt.forEach((k,v)->System.out.println("key:"+k+",value:"+v));
(六)集合处理

5.【强制】
如果是JDK8的应用,可以使用instant代替Date,Localdatetime代替Calendar,Datetimeformatter代替Simpledateformatter,官方给出的解释:simple beautiful strong immutable thread-safe

它使用的是datetime,不知道为什么不使用timestamp,二者的异同点,参考网址:
https://blog.csdn.net/qq_28483283/article/details/81873054

二、异常日志

(一)异常处理

2.【强制】异常不要用来做流程控制,条件控制。说明:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多。
7.【强制】不要在finally块中使用return。说明:finally块中的return返回后方法结束执行,不会再执行try块中的return语句。

五、MySQL数据库

(一)建表规约

1.【强制】表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint(1表示是,0表示否)。说明:任何字段如果为非负数,必须是unsigned。
5.【强制】主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名。说明:pk_ 即primary key;uk_ 即uniquekey;idx_ 即index的简称。
6.【强制】小数类型为decimal,禁止使用float和double。说明:float和double在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数据范围超过decimal的范围,建议将数据拆成整数和小数分开存储。
9.【强制】表必备三字段:id, gmt_create, gmt_modified。说明:其中id必为主键,类型为bigintunsigned、单表时自增、步长为1。gmt_create, gmt_modified的类型均为datetime类型,前者现在时表示主动创建,后者过去分词表示被动更新。

(三)SQL语句

1.【强制】不要使用count(列名)或count(常量)来替代count(),count()是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。说明:count(*)会统计值为NULL的行,而count(列名)不会统计此列为NULL值的行。
3.【强制】当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。正例:可以使用如下方式来避免sum的NPE问题:SELECTIF(ISNULL(SUM(g)),0,SUM(g))FROMtable;
4.【强制】使用ISNULL()来判断是否为NULL值。
说明:NULL与任何值的直接比较都为NULL。

  • 1)NULL<>NULL的返回结果是NULL,而不是false。
  • 2)NULL=NULL的返回结果是NULL,而不是true。
  • 3)NULL<>1的返回结果是NULL,而不是true。

7.【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
9.【推荐】in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控制在1000个之内。
10.【参考】如果有国际化需要,所有的字符存储与表示,均以utf-8编码,注意字符统计函数的区别。
说明:

  • SELECTLENGTH("轻松工作"); 返回为12
  • SELECTCHARACTER_LENGTH("轻松工作"); 返回为4
  • 如果需要存储表情,那么选择utf8mb4来进行存储,注意它与utf-8编码的区别。
(四)ORM映射

1.【强制】在表查询中,一律不要使用* 作为查询的字段列表,需要哪些字段必须明确写明。说明:1)增加查询分析器解析成本。2)增减字段容易与resultMap配置不一致。3)无用字段增加网络消耗,尤其是text类型的字段
2.【强制】POJO类的布尔属性不能加is,而数据库字段必须加is_,要求在resultMap中进行字段与属性之间的映射。
4.【强制】sql.xml配置参数使用:#{},#param# 不要使用 ${} 此种方式容易出现SQL注入。
5.【强制】iBATIS自带的queryForList(StringstatementName,intstart,intsize)不推荐使用。
6.【强制】不允许直接拿HashMap与Hashtable作为查询结果集的输出。
9.【参考】@Transactional事务不要滥用。事务会影响数据库的QPS,另外使用事务的地方需要考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正等

六、工程结构

(二)二方库依赖

1.【强制】定义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
  • 3)Version:详细规定参考下方。

2.【强制】二方库版本号命名方式:主版本号.次版本号.修订号

  • 1)主版本号:产品方向改变,或者大规模API不兼容,或者架构不兼容升级。
  • 2)次版本号:保持相对兼容性,增加主要功能特性,影响范围极小的API不兼容修改。
  • 3)修订号:保持完全兼容性,修复BUG、新增次要功能特性等。
    说明:注意起始版本号必须为:1.0.0,而不是0.0.1正式发布的类库必须先去中央仓库进行查证,使版本号有延续性,正式版本号不允许覆盖升级。如当前版本:1.3.3,那么下一个合理的版本号:1.3.4 或1.4.0 或2.0.0

3.【强制】线上应用不要依赖SNAPSHOT版本(安全包除外)。说明:不依赖SNAPSHOT版本是保证应用发布的幂等性。另外,也可以加快编译时的打包构建
6.【强制】依赖于一个二方库群时,必须定义一个统一的版本变量,避免版本号不一致。说明:依赖springframework-core,-context,-beans,它们都是同一个版本,可以定义一个变量来保存版本:${spring.version},定义依赖的时候,引用该版本。
8.【推荐】所有pom文件中的依赖声明放在<dependencies>语句块中,所有版本仲裁放在<dependencyManagement>语句块中。说明:<dependencyManagement>里只是声明版本,并不实现引入,因此子项目需要显式的声明依赖,version和scope都读取自父pom。而<dependencies>所有声明在主pom的<dependencies>里的依赖都会自动引入,并默认被所有的子项目继承

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容