编码自查-阿里云开发手册

github地址

学习阿里云开发手册,摘选出不知晓的、出过错的、记不住的条例,并附上自己的经历、解决方案等,方便以后强化记忆。

编程规约

常量定义

【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。

说明:大而全的常量类,杂乱无章,使用查找功能才能定位到修改的常量,不利于理解和维护。 正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。

代码格式

【强制】左小括号和字符之间不出现空格;同样,右小括号和字符之间也不出现空格;而左大 括号前需要空格。

反例:if (空格a == b空格)

【强制】采用 4 个空格缩进,禁止使用 tab 字符。

如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时, 请勿勾选Use tab character
;而在 eclipse 中,必须勾选
insert spaces for tabs

目前使用的是 Square code style, 一个 tab 为 2 个空格。

【强制】IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式, 不要使用 Windows 格式。

修改line separators方法

【推荐】单个方法的总行数不超过 80 行。

包括方法签名、结束右大括号、方法内代码、注释、空行、回车及任何不可见字符的总 行数不超过 80 行。 正例:代码逻辑分清红花和绿叶,个性和共性,绿叶逻辑单独出来成为额外方法,使主干代码 更加清晰;共性逻辑抽取成为共性方法,便于复用和维护。

个人开发时有些方法业务逻辑太多,很臃肿,需提升设计、抽象能力,优化。

【推荐】不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。 说明:任何情形,没有必要插入多个空行进行隔开。

OOP 规约

关于基本数据类型与包装数据类型的使用标准如下:

  1. 【强制】所有的POJO类属性必须使用包装数据类型。
  2. 【强制】RPC方法的返回值和参数必须使用包装数据类型。
  3. 【推荐】所有的局部变量使用基本数据类型。

POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何
NPE 问题,或者入库检查,都由使用者来保证。

吃过 POJO 属性为基本类型的亏

集合处理

【强制】使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全
一样的数组,大小就是 list.size()。

:使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配
内存空间,并返回新数组地址;如果数组元素个数大于实际所需,下标为[ list.size() ]
的数组元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集
合元素个数一致。
正例:

List list = new ArrayList(2);  
list.add("guan");
list.add("bao");
String[] array = new String[list.size()]; array = list.toArray(array);

以前传的是长度为 0 的数组,未分配到指定长度

【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方 法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。 Arrays.asList 体现的是适配器模式,只是转换接口,后台的数据仍是数组。

String[] str = new String[] { "you", "wu" };
List list = Arrays.asList(str);

第一种情况:list.add("yangguanbao"); 运行时异常。
第二种情况:str[0] = "gujin"; 那么list.get(0)也会随之修改。

以前并不知晓

【强制】泛型通配符来接收返回的数据,此写法的泛型集合不能使用add方 法,而不能使用get方法,作为接口调用赋值时易出错。

扩展说一下PECS(Producer Extends Consumer Super)原则:第一、频繁往外读取内 容的,适合用。第二、经常往里插入的,适合用。

需时常翻看

集合处理

并发处理

【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为
static,必须加锁,或者使用 DateUtils 工具类。

正例:注意线程安全,使用 DateUtils。亦推荐如下处理:

private static final ThreadLocal df = new ThreadLocal() { @Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
} };

如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。

控制语句

【强制】在高并发场景中,避免使用”等于”判断作为中断或退出的条件。

如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间 判断条件来代替。

反例:判断剩余奖品数量等于 0 时,终止发放奖品,但因为并发处理错误导致奖品数量瞬间变 成了负数,这样的话,活动无法终止。

【推荐】表达异常的分支时,少用 if-else 方式,

这种方式可以改写成:

if (condition) { 
...
return obj; 
}

// 接着写 else 的业务逻辑代码;

说明:如果非得使用 if()...else if()...else...方式表达逻辑,
【强制】避免后续代码维
护困难,请勿超过 3 层。
正例:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现, 其中卫语句示例如下:

public void today() { 
    if (isBusy()) {
    System.out.println(“change time.”); return;
    }
    if (isFree()) {
    System.out.println(“go to travel.”);
    return; 
    }
    System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);
    return; 
}

注释规约

异常日志

异常处理

【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。

说明:如果 JDK7 及以上,可以使用 try-with-resources 方式。

【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:

1)返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。

  1. 数据库的查询结果可能为null。
  2. 集合里的元素即使isNotEmpty,取出的数据元素也可能为null。
  3. 远程调用返回对象时,一律要求进行空指针判断,防止NPE。
  4. 对于Session中获取的数据,建议NPE检查,避免空指针。
  5. 级联调用obj.getA().getB().getC();一连串调用,易产生NPE。
    正例:使用 JDK8 的 Optional 类来防止 NPE 问题。

日志规约

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架
SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);

【强制】避免重复打印日志,浪费磁盘空间,务必在 log4j.xml 中设置 additivity=false。 正例:


安全规约

【强制】隶属于用户个人的页面或者功能必须进行权限控制校验。

说明:防止没有做水平权限校验就可随意访问、修改、删除别人的数据,比如查看他人的私信 内容、修改他人的订单。

需注意的地方

【强制】禁止向 HTML 页面输出未经安全过滤或未正确转义的用户数据。

可参考SpringMvc防御XSS实践

【强制】在使用平台资源,譬如短信、邮件、电话、下单、支付,必须实现正确的防重放的机 制,如数量限制、疲劳度控制、验证码校验,避免被滥刷而导致资损。

说明:如注册时发送验证码到手机,如果没有限制次数和频率,那么可以利用此功能骚扰到其 它用户,并造成短信平台资源浪费。

设计时需注意

【推荐】发贴、评论、发送即时消息等用户生成内容的场景必须实现防刷、文本内容违禁词过 滤等风控策略。

需学习

Mysql 数据库

【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长 度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。

项目上遇到过此情况, 拆分大字段处理

【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检 索速度

image

你可能感兴趣的:(编码自查-阿里云开发手册)