当前位置: 代码迷 >> 综合 >> alibaba开发手册
  详细解决方案

alibaba开发手册

热度:26   发布时间:2023-10-18 22:38:14.0

alibaba开发手册

11.19

  1. 强制: 方法参数在定义和传入时,多个参数逗号后边必须加空格。

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

  3. 避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析
    成本,直接用类名来访问即可。

  4. Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用
    equals。

  5. 所有整型包装类对象之间值的比较,全部使用 equals 方法比较

  6. 浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用
    equals 来判断

  7. 数据库字段的 bigint 必须与类属性的 Long 类型相对应。

  8. 为了防止精度损失,禁止使用构造方法 BigDecimal(double)的方式把 double 值转
    化为 BigDecimal 对象

  9. 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中。

  10. 循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

  11. final 可以声明类、成员变量、方法、以及本地变量,下列情况使用 final 关键字:
    1) 不允许被继承的类,如:String 类。
    2) 不允许修改引用的域对象。
    3) 不允许被覆写的方法,如:POJO 类的 setter 方法。
    4) 不允许运行过程中重新赋值的局部变量。
    5) 避免上下文重复使用一个变量,使用 final 可以强制重新定义一个变量,方便更好地进行重构。

11.20

1.   使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组。反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现 ClassCastException 错误。  
2.   List<String> list = new ArrayList<>(2);list.add("guan");list.add("bao");String[] array = list.toArray(new String[0]);说明:使用 toArray 带参方法,数组空间大小的 length:1) 等于 0,动态创建与 size 相同的数组,性能最好。2) 大于 0 但小于 size,重新创建大小等于 size 的数组,增加 GC 负担。3) 等于 size,在高并发情况下,数组创建完成之后,size 正在变大的情况下,负面影响与上相同。4) 大于 size,空间浪费,且在 size 处插入 null 值,存在 NPE 隐患。  
3.   不要在 foreach 循环里进行元素的 remove/add 操作。 remove 元素请使用Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。    正例:List<String> list = new ArrayList<>();list.add("1");list.add("2");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String item = iterator.next();if (删除元素的条件) {Java 开发手册13/44iterator.remove();}}反例:for (String item : list) {if ("1".equals(item)) {list.remove(item);}}  
4. ArrayList 是 order/unsort;HashMap 是 unorder/unsort;TreeSet 是 order/sort。  
5.   【参考】 利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains 方法进行遍历、对比、 去重操作。  

11.21

?	并发处理1.   对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。  2.   并发修改同一记录时,避免更新丢失,需要加锁。 要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。说明:如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3 次  控制语句1.   在一个 switch 块内,每个 case 要么通过 continue/break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止;在一个 switch 块内,都必须包含一个default 语句并且放在最后,即使它什么代码也没有。说明:注意 break 是退出 switch 语句块,而 return 是退出方法体  2.   在高并发场景中,避免使用” 等于” 判断作为中断或退出的条件。说明:如果并发控制没有处理好,容易产生等值判断被“击穿” 的情况,使用大于或小于的区间判断条件来代替。  3.   【推荐】 表达异常的分支时,少用 if-else 方式,这种方式可以改写成:if (condition) {...return obj;}// 接着写 else 的业务逻辑代码  4. ```javapackage com.yamon.array;public class SwitchString {public static void main(String[] args) {method(null);}public static void method(String param) {switch (param) {// 肯定不是进入这里case "sth":System.out.println("it's sth");break;// 也不是进入这里case "null":System.out.println("it's null");break;// 也不是进入这里default:System.out.println("default");}}}```![image-20191121085237517](C:\Users\陈亚萌\AppData\Roaming\Typora\typora-user-images\image-20191121085237517.png)5.   循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行不必要的 try-catch 操作(这个 try-catch 是否可以移至循环体外)  

11.22

1.   类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用// xxx 方式  
2.   所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能  
3.   代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。  
4.   错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。  
5.   在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。  
6.   后台输送给页面的变量必须加$!{var}——中间的感叹号。 
7.   注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。   
8.   获取当前毫秒数 System.currentTimeMillis(); 而不是 new Date().getTime();说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime()的方式。在 JDK8 中,针对统计时间等场景,推荐使用 Instant 类。  
9.   日期格式化时,传入 pattern 中表示年份统一使用小写的 y。说明:日期格式化时,yyyy 表示当天所在的年,而大写的 YYYY 代表是 week in which year(JDK7 之后引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的 YYYY 就是下一年。另外需要注意:? 表示月份是大写的 M? 表示分钟则是小写的 m? 24 小时制的是大写的 H? 12 小时制的则是小写的 h正例:表示日期和时间的格式如下所示:new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
10.   任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存。  
11.   **及时清理不再使用的代码段或配置信息。**说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。正例:****对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一规定使用三个斜杠(///)**来说明注释掉代码的理由。**  

二、异常日志

1.   捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。  2.   防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:1) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。2) 数据库的查询结果可能为 null。3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。5) 对于 Session 中获取的数据,建议进行 NPE 检查,避免空指针。6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。正例:使用 JDK8 的 Optional 类来防止 NPE 问题。  

三、日志规约

   1.   应用中的扩展日志(如打点、临时监控、访问日志等)命名方式:appName_logType_logName.log。 logType:日志类型,如 stats/monitor/access 等;logName:日志描述。这种命名的好处:通过文件名就可知道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。  2.   避免重复打印日志,浪费磁盘空间,务必在 log4j.xml 中设置 additivity=false。  

四、单元测试

   1.   好的单元测试必须遵守 AIR 原则。说明:单元测试在线上运行时,感觉像空气(AIR)一样并不存在,但在测试质量的保障上,却是非常关键的。好的单元测试宏观上来说,具有自动化、独立性、可重复执行的特点。? A:Automatic(自动化)? I:Independent(独立性)? R:Repeatable(可重复)  2.   单元测试应该是全自动执行的,并且非交互式的。测试用例通常是被定期执行的,执行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。单元测试中不准使用 System.out 来进行人肉验证,必须使用 assert 来验证。  

11.25

1. 用户请求传入的任何参数必须做有效性验证。说明:忽略参数校验可能导致:? page size 过大导致内存溢出? 恶意 order by 导致数据库慢查询? 任意重定向? SQL 注入? 反序列化注入? 正则输入源串拒绝服务 ReDoS说明:Java 代码用正则来验证客户端的输入,有些正则写法验证普通用户输入没有问题,但是如果攻击人员使用的是特殊构造的字符串来验证,有可能导致死循环的结果。
2. 发贴、评论、发送即时消息等用户生成内容的场景必须实现防刷、文	本内容违禁词过滤等风控策略。

数据库安全

1.  表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类	型是 unsignedtinyint(1 表示是,0 表示否)
2. 表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
3. 表名不使用复数名词。
4. 小数类型为 decimal,禁止使用 float 和 double
5. varchar 是可变长字符串,不预先分配存储空间,长度不要超过 	5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率
6. 表必备三字段:id, create_time, update_time
7. 表的命名最好是遵循“业务名称_表的作用” 。

11.27

工程结构

应用分层

  1. 定义 GAV 遵从以下规则:
  2. GroupID 格式:com.{公司/BU }.业务线 [.子业务线],最多 4 级。
    说明:{公司/BU} 例如:alibaba/taobao/tmall/aliexpress 等 BU 一级;子业务线可选。
    正例:com.taobao.jstorm 或 com.alibaba.dubbo.register
    1. ArtifactID 格式:产品线名-模块名。语义不重复不遗漏,先到中央仓库去查证一下。
      正例:dubbo-client / fastjson-api / jstorm-tool
  3. Version:详细规定参考下方
  4. 禁止在子项目的 pom 依赖中出现相同的 GroupId,相同的 ArtifactId,但是不同的
    Version。