• alibaba开发手册


    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/44
       iterator.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. ```java
           package 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陈亚萌AppDataRoamingTypora	ypora-user-imagesimage-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 的方式命名,数据类	型是 unsigned
    	tinyint(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。
    博客网站 https://yamon.top 个人网站 https://yamon.top/resume GitHub网站 https://github.com/yamonc 欢迎前来访问
  • 相关阅读:
    attr系列
    面对对象中的反射
    Python中的内置函数(比较重要的)
    过滤莫文件夹下所有文件和子文件夹中的文件,并把路径打印出-----面对过程的编程
    python中字典的几个方法介绍
    python中字符串的几个方法介绍
    python中列表与元组
    win7上python2.7连接mysql数据库
    练习-三级菜单
    练习-模拟商城购物车
  • 原文地址:https://www.cnblogs.com/chenyameng/p/11942446.html
Copyright © 2020-2023  润新知