编程规范

  • POJO类中布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误。
    假设定义一个 boolean 的 isSuccess 属性,它的方法 Getter 被IDE生成为 isSuccess(),RPC等三方框架在反向解析的时候,
    “以为”对应的属性名称是 success,导致属性获取不到,进而抛出异常。
    
  • 接口类中的方法和属性不要加任何修饰符号。
    包括在一些开源的代码里,老夫经常看见在接口方法上声明 public 关键字的,这是冗余的,在Java规范中提到过。如下图mybatis源码中接口类,
    关于代码的规范及简洁性诸位可以参考《重构 改善既有代码的设计》 及 《代码整洁之道》。
    

    1

  • 方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。 不过没有必要插入多行空格进行隔开。这样可读性会明显提高,老夫经常看到部分开发人员的代码在很长的代码块里完全没有一个空行, 没有按逻辑进行换行,这种习惯是不太好的。
  • 所有的覆写方法,必须加 @Override 注解。这样IDE会检查合法性,有错误的话会及时提示。
  • 所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。
    比如 Integer 的-128至127之间被缓存的对象可以直接使用==判断,因为被缓存了,是同一对象,地址相等,而这个区间外的却不能使用==判断。
    
  • 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。
  • 集合初始化时,尽量指定集合初始值大小。
  • 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。
  • 尽量降低锁的粒度。
高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;
能用对象锁,就不要用类锁。
  • 对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。
  • 善用 TODO 及 FIXME,IDE可以方便的进行扫描。
  • 注释掉的代码尽量要配合说明,而不是简单的注释掉。如果永久不用,建议直接删除,因为Git等版本控制系统保存了历史代码。
  • 获取当前毫秒数使用 System.currentTimeMillis(),System.nanoTime()产生的值仅用于比较,同一时刻不同虚拟机System.nanoTime() 返回的值可能不一样并且相差很大。

异常日志

  • 捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。 最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
  • 谨慎地记录日志。
生产环境禁止输出 debug 日志;有选择地输出 info 日志;如果使用 warn 来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,
避免把服务器磁盘撑爆,并记得及时删除这些观察日志。关于日志把server磁盘撑爆的问题,我司也出现过,后面加了相关监控来避免。

工程约束

  • 高并发服务器建议调小 TCP 协议的 time_wait 超时时间。
  • 调大服务器所支持的最大文件句柄数(File Descriptor,简写为fd)。
  • 给 JVM 设置-XX:+HeapDumpOnOutOfMemoryError 参数,让 JVM 碰到 OOM 场景时输出 dump 信息。

安全规约

  • 隶属于用户个人的页面或者功能必须进行权限控制校验。
  • 用户敏感数据禁止直接展示,必须对展示数据脱敏。
  • 用户输入的 SQL 参数严格使用参数绑定或者 METADATA 字段值限定,防止 SQL 注入, 禁止字符串拼接 SQL 访问数据库。
  • 用户请求传入的任何参数必须做有效性验证。
  • 表单、AJAX 提交必须执行 CSRF 安全过滤。
  • 在使用平台资源,譬如短信、邮件、电话、下单、支付,必须实现正确的防重放限制, 如数量限制、疲劳度控制、验证码校验,避免被滥刷、资损。
⤧  Next post Java后端面试题总结 ⤧  Previous post Java性能优化