开发注意事项(阿里巴巴开发手册 + 个人补充)

1.【强制】序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请修改serialVersionUID值。说明:注意serialVersionUID致会抛出序列化运行时异常。

2.【强制】POJO类必须写toString方法。使用IDE中的工具:source>generatetoString时,如果继承了另一个POJO类,注意在前面加一下super.toString。说明在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。

3.Service/DAO层方法命名规约

1)获取单个对象的方法用get做前缀。

2)获取多个对象的方法用list做前缀,复数形式结尾如:listObjects。

3)获取统计值的方法用count做前缀。

4)插入的方法用save/insert做前缀。

5)删除的方法用remove/delete做前缀。

6)修改的方法用update做前缀。

4.【推荐】使用索引访问用String的split方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有抛IndexOutOfBoundsException的风险。

说明:String str = "a,b,c,,";   String[] ary = str.split(",");

// 预期大于3,结果是3

System.out.println(ary.length);

5.【推荐】类成员与方法访问控制从严:

1)如果不允许外部直接通过new来创建对象,那么构造方法必须是private。

2)工具类不允许有public或default构造方法。

6.【推荐】集合初始化时,指定集合初始值大小。说明:HashMap使用HashMap(int   initialCapacity)初始化。正例:initialCapacity=(需要存储的元素个数/负载因子) + 1。注意负载因子(即loaderfactor)默认为0.75,如果暂时无法确定初始值大小,请设置为16(即默认值)。反例:HashMap需要放置1024个元素,由于没有设置容量初始大小,随着元素不断增加,容量7次被迫扩大,resize需要重建hash表,严重影响性能。

7.【推荐】使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。说明:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。

8.由于HashMap的干扰,很多人认为ConcurrentHashMap是可以置入null值,而事实上,存储null

值时会抛出NPE异常。

9.【推荐】使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法被执行到,避免主线程无法执行至await方法,直到超时才返回结果

说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。

10.【推荐】避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed导致的性能下降。说明:Random实例包括java.util.Random的实例或者Math.random()的方式。正例:在JDK7之后,可以直接使用APIThreadLocalRandom,而在JDK7之前,需要编码保证每个线程持有一个实例

11.【强制】在高并发场景中,避免使用”等于”判断作为中断或退出的条件。说明:如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间判断条件来代替。

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

12.【推荐】除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。

13.待办事宜(TODO):(标记人,标记时间,[预计处理时间])

14.对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一规定使用三个斜杠(///)来说明注释掉代码的理由;

15.【强制】有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回滚事务。

16.【强制】不要在finally块中使用return。说明:finally块中的return返回后方法结束执行,不会再执行try块中的return语句

17.【推荐】防止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问题。

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

正例:<logger name="com.taobao.dubbo.config" additivity="false">

19.【强制】异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字throws往上抛出。正例:logger.error(各类参数或者对象toString()+ "_" + e.getMessage(), e);

20.说明:本手册明确防止NPE是调用者的责任。

21.【强制】POJO类中布尔类型的变量,都不要加is前缀,否则部分框架解析会引起序列化错误

【强制】表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint(1表示是,0表示否)

22.【强制】主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名。说明:pk_即primary key;uk_即uniquekey;idx_即index的简称。

23.【强制】小数类型为decimal,禁止使用float和double。说明:float和double在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数据范围超过decimal的范围,建议将数据拆成整数和小数分开存储。

24.【强制】如果存储的字符串长度几乎相等,使用char定长字符串类型。

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

25.【推荐】字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:

1)不是频繁修改的字段。

2)不是varchar超长字段,更不能是text字段。

正例:商品类目名称使用频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存储类目名称,避免关联查询

26.【推荐】单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。

说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表

27.【强制】业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。

说明:不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生

28.【强制】页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。说明:索引文件具有B-Tree的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引

29.【推荐】利用延迟关联或者子查询优化超多分页场景。说明:MySQL并不是跳过offset行,而是取offset+N行,然后返回放弃前offset行,返回N行,那当offset特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行SQL改写。

正例:先快速定位需要获取的id段,然后再关联:SELECT a.* FROM表1 a, (select id from表1 where 条件 LIMI T 100000,20 ) b where a.id=b.id

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

31.【强制】当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。

正例:可以使用如下方式来避免sum的NPE问题:SELECT IF (ISNULL (SUM (g)), 0, SUM(g ))FROM table

32.【强制】使用 ISNULL() 来判断是否为NULL值。说明:NULL与任何值的直接比较都为NULL。1)NULL<>NULL的返回结果是NULL,而不是false。

2)NULL=NULL的返回结果是NULL,而不是true。

3)NULL<>1的返回结果是NULL,而不是true

33.【强制】在表查询中,一律不要使用*作为查询的字段列表,需要哪些字段必须明确写明。

说明:1)增加查询分析器解析成本。2)增减字段容易与resultMap配置不一致。3)无用字段增加网络消耗,尤其是text类型的字段

34.【强制】不允许直接拿HashMap与Hashtable作为查询结果集的输出。说明:resultClass=”Hashtable”,会置入字段名和属性值,但是值的类型不可控

35.【强制】不要用resultClass当返回参数,即使所有类属性名与数据库字段一一对应,也需要定义;反过来,每一个表也必然有一个POJO类与之对应。说明:配置映射关系,使字段与DO类解耦,方便维护。

36.【强制】线上应用不要依赖SNAPSHOT版本(安全包除外)。

说明:不依赖SNAPSHOT版本是保证应用发布的幂等性。另外,也可以加快编译时的打包构建。

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

38.【推荐】高并发服务器建议调小TCP协议的time_wait超时时间。

说明:操作系统默认240秒后,才会关闭处于time_wait状态的连接,在高并发访问下,服务器端会因为处于time_wait的连接数太多,可能无法建立新的连接,所以需要在服务器上调小此等待值。正例:在linux服务器上请通过变更/etc/sysctl.conf文件去修改该缺省值(秒):net.ipv4.tcp_fin_timeout= 30

39.【推荐】调大服务器所支持的最大文件句柄数(FileDescriptor,简写为fd)。说明:主流操作系统的设计是将TCP/UDP连接采用与文件一样的方式去管理,即一个连接对应于一个fd。主流的linux服务器默认所支持最大fd数量为1024,当并发连接数很大时很易因为fd不足而出现“open too many files”错误,导致新的连接无法建立。建议将linux服务器所支持的最大句柄数调高数倍(与服务器的内存数量相关)

--------------------------------------个人补充-----------------------------

lombok 禁止使用@Data 有坑 https://zhuanlan.zhihu.com/p/85906077

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值