程序员
这篇文章主要是总结 Java 方面的,自己学习的一些见解地方
规约
- POJO 类的布尔类型变量不准使用 is 前缀开头,因为在部分序列化框架中,会把 isDeleted 误以为 deleted 才是变量名
- 常量复用层次
- 二方包 client.jar 的 constant 目录(跨应用)
- 一方库子模块的 constant 目录(应用内)
- 子工程目录(当前子工程)
- 当前包的 constant
- 当前类
- BigDecimal 的 equals 和 compareTo
a=0.1 b=0.10000 a.equalsTo(b)=false
equals 除了比较值还会比较精度a=0.1 b=0.10000 a.compareTo(b)==0 = true
compareToz 只比较值
- float 转 BigDecimal 时,注意
new BigDecimal(String)
orBigDecimal.valueOf(float);
- 关于基本数据类型与包装数据类型
- POJO 必须使用包装数据类型(比如说数据库为 null,如果为基本数据类型,则可能会从 null 初始为 0,导致显示意义有误)
- RPC 的返回值和参数必须包装数据类型
- 禁止同时存在 xxx 属性的 isXXX 方法和 getXXX 方法 有的序列化框架中未对 is 和 get 做优先级的查询,所以在做 get 方法时,可能会随机调用不同的函数
Collectors.toMap()
如果 value 为空会抛异常- 集合转数组的方法:
list.toArray(new String[0])
等于 0 的话会动态创建等于 size 的数组,性能最好,其他 gc 负担大 - 使用 Collection 接口的
addAll()
方法第一行代码是inputParam.toArray()
有 NPE 风险,所以要做好入参空判断 - PECS 原则(Producer Extends Consumer Super)
- 频繁向外读取内容的,适合用
<? extends T>
- 频繁往里插入的,使用用
<? super T>
- 频繁向外读取内容的,适合用
- ConcurrentHashMap 不允许存入 null 的 value 值
- 前后端交互
- 对于超大整数,统一使用String返回,不能使用Long类型,因为js会转为Number类型(类似于Java的Double)有精度丢失风险
- 日志
- 应使用日志框架的API,而不是日志系统中的API
- 禁止使用JSON工具打印对象,如果对象里面有get方法抛出异常,将导致因为日志输出而中断流程
- 中间件
- tair
- 对于双集群的缓存进行put和删除动作时,必须先invalid后,再进行put或者删除的动作
- 数据库保存先成功,再进行缓存的更新操作
- tair
- 单元测试
- AIR原则(Automatic Independent Repeatable)
- 测试案例不能依赖,不能有先后顺序
- 对于第三方资源的依赖,设计时通过注入,测试时在DI框架上通过注入本地实现,或者Mock实现
- 单测一般只针对方法,最多到类级别,对于跨类和跨系统的,属于集成测试的领域
- 编写时遵守BCDE原则
- Border 边界,循环边界,特殊取值,时间点,数据顺序
- Correct 正确输入,预期结果与实际结果
- Design 结合设计文档编写
- Error 强制错误信息输入,获得预期结果
- 数据库
- 是否使用 is_xxx unsigned tinyint表示
开发
Double-checked Locking is broken
使用 static 单例 `static XXX xx=new XXX();
JDK 老版本中,可以通过 ThreadLocal 来判断是否实例化,继而实现懒加载化
或者使用 volatie 加上双重判断,通过 volatile 实现指令不可重排,加上双检查保证懒加载
private volatie Helper helper=null; public Helper getHelper(){ if(helper==null){ synchronized(this){ if(helper==null){ helper=new Helper(); } } } return helper; }
参考文档
- 阿里巴巴开发规约
- double Checked locking