阿里云JAVA开发规范考试总结

JAVA开发手册考试总结

编程规范

  1. POJO(Plain Ordinary Java Object): POJO 专指只有 setter / getter / toString的简单类,包括DO/DTO/BO/VO等。

    DO(Data Object):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
    DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
    BO(Business Object):业务对象,由 Service 层输出的封装业务逻辑的对象。
    AO(ApplicationObject):应用对象,在Web层与Service层之间抽象的复用对象模型, 极为贴近展示层,复用度不高。
    VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
  2. foreach中不要进行remove和add操作,remove元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

  3. 使用 CountDownLatch 进行异步转同步操作,每个线程退出前必须调用 countDown 方法,线程执行代码注意 catch 异常,确保 countDown 方法被执行到,避免主线程无法执行 至 await 方法,直到超时才返回结果。 说明:注意,子线程抛出异常堆栈,不能在主线程 try-catch 到 )

  4. 线程池不允许使用 Executors 去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。说明:Executors 返回的线程池对象的弊端如下:

    1)FixedThreadPool 和 SingleThreadPool:
    允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
    2)CachedThreadPool 和 ScheduledThreadPool:
    允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

  5. Hashtable/ConcurrentHashMap的K/V都不允许为null, HashMap的K/V都允许为null, TreeMap的K不允许为null、V允许为null。

  6. 不要在视图模板中(vm)中加入变量声明, 逻辑运算符, 更不要在vm中加入任何复杂的逻辑, 视图的职责是展示, 不要抢模型和控制器的活。

  7. ArrayList的subList的类型是java.util.RandomAccessSubList, 是ArrayList的一个视图, 不能强转成ArrayList; 对于SubList子列表的所有操作最终会反映到原列表上; 对原列表的修改, 会导致子列表的遍历、增加、删除均会产生ConcurrentModificationException异常; 同时, subList没有实现Serializable接口, 若RPC接口的List类型参数接受了SubList类型的实参,则在RPC调用时会报出序列化异常。比如我们常用的guava中的Lists.partition,切分后的子list实际都是SubList类型,在传给RPC接口之前,需要用new ArrayList()包一层,否则会报序列化异常。

  8. 所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。

  9. final 可以声明类、成员变量、方法、以及本地变量。

    final修饰的class代表不可继承扩展、修饰变量是不可以被修改、修饰方法代表不可以被重写

    下列情况使用 final 关键:

    1. 不允许被继承的类,如:String 类。  
    2. 不允许修改引用的域对象。  
    3. 不允许被重写的方法,如:POJO 类的 setter 方法。

单元测试

  1. 好的单元测试必须遵守AIR原则: A->Automatic(自动化), I->Independent(独立性), R->Repeatable(可重复)。
  2. 编写单元测试代码遵守BCDE原则, 以保证被测试模块的交付质量: B->Border 边界测试; C->Correct 正确的输入, 预期的结果; D->Design 与设计文档相结合, 来编写单元测试; E->Error 强制错误信息输入, 预期的结果。

安全规范

  1. Web应用必须正确配置 Robots文件,非 SEO URL必须配置为禁止爬虫访问。SEO-Search Engine Optimization。

异常处理

  1. 对 trace/debug/info 级别的日志输出,必须使用条件输出形式或者使用占位符的方 式。

  2. Java 类库中定义的可以通过预检查方式规避的 RuntimeException 异常不应该通过 catch 的方式来处理,比如:NullPointerException,IndexOutOfBoundsException 等等。

    说明:无法通过预检查的异常除外,比如,在解析字符串形式的数字时,不得不通过 catch NumberFormatException 来实现。 正例:if (obj != null) {...} 反例:try { obj.method(); } catch (NullPointerException e) {…}

  3. Checked异常必须被显式地 捕获 或者 传递(向上抛出,沿着调用栈 继续向上传播该异常),如try-catch-finally ,throws Exception 。而unchecked异常则可以不必 捕获 或 抛出。Checked异常继承自 java.lang.Exception类(一般异常)。Unchecked异常继承自java.lang.RuntimeException类(运行时异常)。

    将派生于Error或者RuntimeException的异常称为unchecked异常。

MySQL数据库

  1. 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据 实际文本区分度决定索引长度即可。

  2. 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引,varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长 度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。

  3. 如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。 正例:where a=? and b=? order by c; 索引:a_b_c 反例:索引中有范围查找,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引 a_b 无法排序。

  4. 建组合索引的时候,区分度最高的在最左边。 正例:如果 where a=? and b=? ,如果 a 列的几乎接近于唯一值,那么只需要单建 idx_a 索引即可。 说明:存在非等号和等号混合时,在建索引时,请把等号条件的列前置。如:where c>? and d=? 那么即使 c 的区分度更高,也必须把 d 放在索引的最前列,即索引 idx_d_c。

  5. 复合索引为idx_A_B_C,所以查询条件只能是在a,ab,abc,ac才算 使用到索引idx_A_B_C

  6. 在代码中写分页查询逻辑时,若 count为 0应直接返回,避免执行后面的分页语句。 

  7. 不要使用 count(列名)或 count(常量)来替代 count(),count()是 SQL92 定义的 标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。 说明:**count(*)会统计值为 NULL 的行**,而 count(列名)不会统计此列为 NULL 值的行。

    count(distinct col) 计算该列除 NULL 之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为 NULL,那么即使另一列有不同的值,也返回为 0。当某一列的值全是 NULL 时,count(col)的返回结果为 0,但 sum(col)的返回结果为 NULL,因此使用 sum()时需注意 NPE 问题。 正例:可以使用如下方式来避免 sum 的 NPE 问题:SELECT IF(ISNULL(SUM(g)),0,SUM(g)) FROM table

工程结构

  1. GAV规范

    GroupID格式:com.{公司}.业务线[.子业务线]  栗子:com.taobao.jstorm 或 com.alibaba.dubbo.register 
    ArtifactID 格式:产品线名-模块名。栗子:dubbo-client / fastjson-api / jstorm-tool 
    Version: 
    主版本号:产品方向改变,或者大规模 API 不兼容,或者架构不兼容升级。   
    次版本号:保持相对兼容性,增加主要功能特性,影响范围极小的 API 不兼容修改。  
    修订号:保持完全兼容性,修复 BUG、新增次要功能特性等。 
    注意起始版本号必须为:1.0.0,而不是 0.0.1 
  2. 外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生 影响。接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么。

  3. 二方库的新增或升级,保持除功能点之外的其它 jar 包仲裁结果不变。如果有改变, 必须明确评估和验证,建议进行 dependency:resolve 前后信息比对,如果仲裁结果完全不一 致,那么通过 dependency:tree 命令,找出差异点,进行 排除 jar 包。

    ​ dependency:resolve 打印出已解决依赖列表
    dependency:tree 打印层级依赖关系
    所有 pom 文件中的依赖声明放在 语句块中,所有版本仲裁放在 语句块中

  4. 高并发服务器建议调小 TCP 协议的 time_wait 超时时间。

    在 linux 服务器上请通过变更/etc/sysctl.conf 文件去修改该缺省值(秒):      net.ipv4.tcp_fin_timeout = 30 
  5. 高并发服务器调大服务器所支持的最大文件句柄数

    主流的 linux 服务器默认所支持最大 fd 数量为 1024,当并发连接数很大时很
    阿里巴巴 Java 开发手册 
      34/38 
    容易因为 fd 不足而出现“open too many files”错误,导致新的连接无法建立。 建议将 linux 服务器所支持的最大句柄数调高数倍(与服务器的内存数量相关)
  6. 集合初始化时,指定集合初始值大小。

  7. PECS(Producer Extends Consumer Super)原则:第一、频繁往外读取内 容的,适合用<? extends T>。第二、经常往里插入的,适合用<? super T>。

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

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

设计规范

系统架构设计的目的:

  1. 确定系统边界。确定系统在技术层面上的做与不做。
  2. 确定系统内模块之间的关系。确定模块之间的依赖关系及模块的宏观输入与输出。
  3. 确定指导后续设计与演化的原则。使后续的子系统或模块设计在规定的框架内继续演化。
  4. 确定非功能性需求。非功能性需求是指安全性、可用性、可扩展性等。

猜你喜欢

转载自www.cnblogs.com/renqiqiang/p/9657732.html