笔记壹《阿里巴巴java开发手册》

248 阅读7分钟

写在前面的话

在一开始我就知道这是关于编码规范的书,之前也有看过pdf版, 但这是第一次仔仔细细的把纸制书读完。

书比想象中要小,确实是手册,仔细读下来,收获比想象的大。

比如一部分规范,不仅仅告诉你怎么写,还向你阐明了为什么要这样写,不这样写存在的隐患是什么。

它能让你不仅是知其然更知其所以然了。

阿里巴巴java开发手册.jpg

整体介绍

整个手册分为编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约七个维度。

下面来对每一章节的收获进行阐述。

章节收获

只记录目前觉得重要的规范。

编程规约

驼峰命名法自是不必说。

避免在子父类的成员变量之间或者不同的代码块的局部变量之间采用完全相同的命名,这样会降低可理解性。

这一点之前编码是没考虑到的,命名不规范,要注意。

将设计模式提现在名字中,有利于阅读者快速理解架构的设计理念。

还介绍了代码格式,空格的规定,包括注释的要求。如单行注释后要加个空格再写注释。

之前都不怎么在意,现在想来一切都是为了优美的同时减少维护代码的成本。

单个方法行数不要超过80行。超过是就要抽取方法了。

这里提到代码逻辑分清红花和绿叶、个性和共性,绿叶的逻辑单独抽出来成额外的方法,使主干代码更加清晰;共性逻辑抽取成为共性方法,便于复用和维护。

还提到要小心集合的处理,对于集合的内部类要特别注意,不能进行增加和删除操作。

如果要对集合里的元素操作最好使用迭代器等。

并发处理要小心,对锁的加锁顺序要保持一致,避免死锁。

在高并发时,要保证锁的范围尽可能小,能锁代码块就不要锁方法,这是考虑锁的性能消耗。

在使用尝试机制获取锁的方式中,进入业务代码之前要先判断当前线程是否持有锁,否则在释放锁的时候,如果没有锁会抛出异常。

在调用Lock的unLock()方法时,底层会调用AQS的tryRelease方法,如果线程不持有锁,则抛出

IllegalMonitorState Exception 异常。

悲观锁遵循“一锁二判三更新四释放”的原则。

子线程的异常堆栈,不能再主线程try-catch到。

超过3层的if-else的处理方式。

使用卫语句(即逻辑取反,避免重复判断)、策略模式、状态模式等。

异常日志

异常日志的体会是 异常要处理,但是不能吃掉,要么打日志要么向上层抛出。

返回的错误码要规范,日志要打但是不要乱打,不打印重复日志,

注意日志的级别和日志的保留时间。

单元测试

单元测试需要关注的是两个原则,

AIR原则

A:Automatic 自动化

I:Independent 独立性

R:Repeatable 可重复

BCDE原则

B:Border,边界值测试

C:Correct,正确地输入,并得到预期的结果

D:Design,与设计文档相结合,编写单元测试

E:Error,强制错误信息输入(如:非法数据,异常流程)并得到预期的结果。

一般单元测试需要覆盖核心代码,有点公司对覆盖率也有要求,代码覆盖率,分之覆盖率和方法覆盖率。

修改业务代码后也要对应的修改单元测试,要对单元测试进行维护,否则久而久之单元测试也就形同虚设。

安全规约

这一章主要讲的是要进行参数校验,否则会出现不可预知的错误,也容易被攻击。

防止sql注入,

在提交表单、AJAX时需要执行CSRF安全验证。

对重定向的地址进行白名单设定,触达类消息需要进行次数限制等。

MySQL数据库

varchar是可变长度字符串,不预先分配存储空间,长度不超过5000字符。

在使用varchar字段上创建索引时,必须指定索引的长度,没必要对全字段建立索引,根据实际文本区分度决定索引的长度即可。一般而言,长度为20的索引,区分度达到90%以上。

尽量利用索引覆盖进行查询操作,避免回表。

索引覆盖是一种查询效果,不是一种索引类型。当在使用explain进行查询,extra列出现“Using index”时,就是索引覆盖。

当建组合索引时,区分度最高的在最左边。

如果存在非等号和等号混合判断条件,那么在建组合索引时,请把等号条件的列前置。

如:where c>? and d=?,即使c的区分度高于d,也必须把d放在索引的最前列,即建立组合索引idx_d_c。

原因是非等号会使索引失效。

sum()在某一列值全部为Null时,会返回Null,使用的时候要放在NPE。

使用select IFNULL(SUM(column),0) from talbe; 可以避免NPE。

使用ISNUll()判断是否为Null值。

Null与任何值的直接比较结果都为Null

ORM映射

1.在表查询中,不要用※表示结果,要列出具体的列。

因为使用※会

1)增加查询分析器的解析成本;

2)增减字段容易与resultMap配置不一致;

3)多余的字段增加网络开销,尤其是text类型的字段。

2.@Transactional事务不要滥用,因为事务会影响数据库的QPS。

注意,在使用事务的地方需要考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿和统计修正等。

工程结构

值得注意的一点,也是日常开发中用的很多的就是分层领域模型规约。具体要求如下:

1)DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据对象。

2)DTO(Data Transfer Object):数据传输对象,Service层或Manager层向外传输的对象。

3)BO(Business Object):业务对象,可以由service层输出的封装业务逻辑对象。

4)Query:数据查询对象,各层接收上层的查询请求。注意,如果超过2个参数的查询封装,则禁止使用Map类传输。需要用对象。

5)VO(View Object):显示层对象,通常是Web层向模板渲染引擎层传输的对象。

服务器方面,值得注意的就两点:

1.高并发的服务器建议调小TCP协议的time_wait超时时间。一般为30秒

操作系统默认是240s后,才会关闭处于time_wait状态的连接,但是在高并发场景下,会因为处于这个状态的连接过多,而无法创建新的连接。

2.将JVM的Xms和Xmx的内存容量设置为同样的大小,避免在GC后调整堆大小带来的压力。

设计规约

1.类在设计与实现时要符合单一原则。

2.系统设计文档的主要目的是明确需求。理顺逻辑、后期维护,次要目的才是指导代码。

3.世间总舵设计模式,其实就会一直设计模式。即隔离变化点的模式。

4.设计的本质就是识别和表达系统的特点。

写在后面的话

这么一遍整理下来,对全书的知识点的印象又加深了。

这样做的目的主要是为了回顾和整理,这只是整理了,重点是后面要时常来回顾知识点,常看常新。