Home  >  Article  >  Java  >  Analyze Java coding specifications

Analyze Java coding specifications

怪我咯
怪我咯Original
2017-06-25 10:12:352227browse

1. Programming Conventions

(1) Naming Convention

1. [Mandatory] Names in the code cannot start with an underscore or a dollar sign, nor can they end with an underscore or a dollar sign. .

Counterexample: _nam / __name / $Object / name_ / name$ / Object$
2. [Mandatory] It is strictly forbidden to use a mixture of Pinyin and English for naming in the code, and it is not allowed to use Chinese directly. Way.

Description: Correct English spelling and grammar can make it easy for readers to understand and avoid ambiguity. Note that even pure pinyin naming should be avoided.

Counter example: DaZhePromotion [Discount] / getPingfenByName() [Rating] / int A certain variable = 3

Positive example: alibaba / taobao / youku / hangzhou and other internationally common names can be regarded as the same English.
3. [Mandatory] The class name must use UpperCamelCase style and must follow camel case, with the following exceptions: (related naming of the domain model) DO / BO / DTO / VO, etc.

Positive example: MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion

Negative example: macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
4. [Mandatory] Method name, parameter name, member Variables and local variables all use lowerCamelCase style and must follow camel case.

Positive example: localValue / getHttpMessage() / inputUserId
5. [Mandatory] Constant names are all capitalized, and words are separated by underscores. Strive to express complete and clear semantics, and do not dislike long names.

Positive example: MAX_STOCK_COUNT

Counterexample: MAX_COUNT
6. [Mandatory] The name of the abstract class starts with Abstract or Base; the name of the exception class ends with Exception; the name of the test class starts with the name it wants to test Begins with the name of the class and ends with Test.
7. [Mandatory] Square brackets are part of the array type. The array is defined as follows: String[] args;

Counterexample: Do not use String args[] to define.
8. [Mandatory] Do not add is to Boolean type variables in the POJO class, otherwise some framework parsing will cause serialization errors.

Counter example: The attribute defined as the basic data type boolean isSuccess; its method is also isSuccess(). When the RPC framework performs reverse parsing, it "thinks" that the corresponding attribute name is success, resulting in failure to obtain the attribute. to, and an exception is thrown.
9. [Mandatory] Package names must be in lowercase, and there must be one and only one English word with natural semantics between dot separators. Package names always use the singular form, but if the class name has a plural meaning, the class name can use the plural form.

Positive example: The application tool class package name is com.alibaba.open.util, and the class name is MessageUtils (this rule refers to the spring framework structure)
10. [Mandatory] Avoid completely non-standard abbreviations , to avoid missing the meaning of the text.

Counterexample: The "abbreviation" of AbstractClass is named AbsClass; the "abbreviation" of condition is named condi. Such arbitrary abbreviation seriously reduces the readability of the code.
11. [Recommendation] If design patterns are used, it is recommended to reflect the specific patterns in the class name.

Description: Reflecting the design pattern in the name will help readers quickly understand the architectural design ideas.

Positive example: public class OrderFactory;

Public class LoginProxy;

Public class ResourceObserver;
12. [Recommendation] Do not add methods and attributes in interface classes Do not add any modifiers (not even public), keep the code concise, and add valid Javadoc comments. Try not to define variables in the interface. If you must define variables, they must be related to interface methods and are basic constants for the entire application.

Positive example: Interface method signature: void f(); Interface basic constant representation: String COMPANY = "alibaba";

Counterexample: Interface method definition: public abstract void f(); Description : Interfaces in JDK8 allow default implementations, so this default method is a valuable default implementation for all implementation classes.
13. There are two sets of rules for naming interfaces and implementation classes:

1) [Mandatory] For Service and DAO classes, based on the concept of SOA, the exposed services must be interfaces and internal implementation classes Use the Impl suffix to distinguish it from the interface.

Positive example: CacheServiceImpl implements the CacheService interface.

 2) [Recommended] If it is an interface name that describes capabilities, use the corresponding adjective as the interface name (usually in the form of –able).

Positive example: AbstractTranslator implements Translatable.
14. [Reference] It is recommended to add the suffix Enum to the enumeration class name. The names of the enumeration members need to be in all capital letters, and the words should be separated by underscores.

Description: Enumeration is actually a special constant class, and the constructor is forced to be private by default.

Positive example: Enumeration name: DealStatusEnum, member name: SUCCESS / UNKOWN_REASON.
15. [Reference] Naming convention for each layer:

A) Service/DAO layer method naming convention

1) Methods to obtain a single object are prefixed with get.

  2) Methods to obtain multiple objects are prefixed with list.

  3) The method of obtaining statistical values ​​is prefixed with count.

  4) The insertion method is prefixed with save (recommended) or insert.

5) The deletion method is prefixed with remove (recommended) or delete.

 6) The modification method is prefixed with update.

B) Domain model naming convention

1) Data object: xxxDO, xxx is the name of the data table.

2) Data transfer object: xxxDTO, xxx is the name related to the business field.

3) Display object: xxxVO, xxx is generally the name of the web page.

4) POJO is the collective name of DO/DTO/BO/VO, and it is forbidden to name it xxxPOJO.

(2) Constant definition

1. [Mandatory] No magic values ​​(i.e. undefined constants) are allowed to appear directly in the code.

Counter example: String key="Id#taobao_"+tradeId;

cache.put(key, value);
2. [Mandatory] When long or Long is initially assigned, it must Use an uppercase L, not a lowercase l. Lowercase letters can easily be confused with the number 1, causing misunderstandings.

Explanation: Long a = 2l; Is it written as 21 as a number or 2 as a Long?
3. [Recommendation] Do not use a constant class to maintain all constants. You should classify them according to their functions. , maintained separately. For example: cache-related constants are placed under class: CacheConsts; system configuration-related constants are placed under class: ConfigConsts.

Description: For a large and comprehensive constant class, you have to use the search function to locate the modified constant, which is not conducive to understanding and maintenance.
4. [Recommended] There are five levels of reuse of constants: shared constants across applications, shared constants within applications, shared constants within subprojects, shared constants within packages, and shared constants within classes.

 1) Cross-application shared constants: placed in the second-party library, usually in the constant directory in client.jar.

 2) In-application shared constants: placed in the constant directory in the modules of the library.

Counterexample: Easy-to-understand variables must also be uniformly defined as shared constants within the application. Two siege masters have defined variables representing "yes" in two classes:

In class A : public static final String YES = "yes";

In class B: public static final String YES = "y"; A.YES.equals(B.YES), the expected value is true, but the actual return is false, causing online problems.
 3) Shared constants within the subproject: that is, in the constant directory of the current subproject.

 4) Shared constants within the package: that is, in a separate constant directory under the current package.

 5) Shared constants within the class: private static final definition directly inside the class.
5. [Recommendation] If the variable value only changes within a range, use the Enum class. If there are extended attributes other than names, the Enum class must be used. The numbers in the following example are extended information, indicating the day of the week.

Positive example: public Enum{ MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(7);}

(3) Format specifications

1. [Mandatory] Convention on the use of braces. If the braces are empty, simply write {} without line breaks; if it is a non-empty code block:

1) There is no line break before the left brace.

 2) Line break after the opening brace.

 3) Line break before the closing brace.

 4) If there is else code after the right brace, there will be no line break; it means that the line must be broken after terminating the right brace.
2. [Mandatory] There is no space between the left bracket and the following character; similarly, there is no space between the right bracket and the previous character. For details, see the correct example tips below Article 5.
3. [Mandatory] Spaces must be added between reserved words such as if/for/while/switch/do and the left and right brackets.
4. [Mandatory] A space must be added around any operator.

Description: Operators include assignment operator =, logical operator &&, addition, subtraction, multiplication and division symbols, ternary operators, etc.
5. [Mandatory] Use 4 spaces for indentation, and tab characters are prohibited.
Note: If you use tab indentation, you must set indent, you must set indent, you must set indent, you must set indent, you must set indent, you must set 1 tab to 4 spaces. When IDEA sets tabs to 4 spaces, do not check Use tab character; in eclipse, you must check insert spaces for tabs.
Positive example: (involving 1-5 points)

public static void main(String args[]) {// 缩进4个空格String say = "hello";// 运算符的左右必须有一个空格int flag = 0;// 关键词if与括号之间必须有一个空格,括号内的f与左括号,0与右括号不需要空格if (flag == 0) {
            System.out.println(say);
        }// 左大括号前加空格且不换行;左大括号后换行if (flag == 1) {
            System.out.println("world");// 右大括号前换行,右大括号后有else,不用换行} else {
            System.out.println("ok");// 在右大括号后直接结束,则必须换行        }
    }

6. 【强制】单行字符数限不超过 120 个,超出需要换行时 个,超出需要换行时 遵循如下原则:

  1) 第二行相对一缩进 4个空格,从第三行开始不再继续缩进参考示例。

  2) 运算符与下文一起换行。

  3) 方法调用的点符号与下文一起换行。

  4) 在多个参数超长,逗号后进行换行。

  5) 在括号前不要换行,见反例。

  正例:
    StringBuffer sb = new StringBuffer();
    //超过120个字符的情况下,换行缩进4个空格,并且方法前的点符号一起换行
    sb.append("zi").append("xin")...
    .append("huang")...
    .append("huang")...
    .append("huang");
  反例:
    StringBuffer sb = new StringBuffer();
    //超过120个字符的情况下,不要在括号前换行
    sb.append("zi").append("xin")...append
    ("huang");
    //参数很多的方法调用可能超过120个字符,不要在逗号前换行
    method(args1, args2, args3, ...
    , argsX);
7. 【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。

  正例:下例中实参的"a",后边必须要有一个空格。
    method("a", "b", "c");
8. 【强制】IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用windows格式。
9. 【推荐】没有必要增加若干空格来使某一行的字符与上一行的相应字符对齐。

  正例:

int a = 3;long b = 4L;float c = 5F;
StringBuffer sb = new StringBuffer();


Note: Add the sb variable. If alignment is required, add a few spaces to a, b, and c. This is cumbersome when there are many variables.
10. [Recommended] Insert a blank line between the execution statement group, variable definition statement group, different business logic or different semantics in the method body. There is no need to insert blank lines between the same business logic and semantics.

Note: There is no need to insert multiple lines of spaces to separate them.

(4) OOP specification

1. [Mandatory] Avoid accessing static variables or static methods of this class through object references of a class, which will unnecessarily increase compiler parsing costs. Use the class name directly. Just come and visit.
2. [Mandatory] All overriding methods must be annotated with @Override.

Counterexample: problem with getObject() and get0object(). One is the letter O, and the other is the number 0. Adding @Override can accurately determine whether the override is successful. In addition, if the method signature is modified in an abstract class, its implementation class will immediately compile and report an error.
3. [Mandatory] Java variable parameters can be used only if they have the same parameter type and the same business meaning. Avoid using Object.

 Note: Variable parameters must be placed at the end of the parameter list. (Students are encouraged to avoid variable parameter programming as much as possible)

Positive example: public User getUsers(String type, Integer... ids)
4. [Mandatory] In principle, the signature of the interface exposed to the outside is not allowed Allows modification of method signatures to avoid impact on interface callers. If the interface is obsolete, the @Deprecated annotation must be added, and the new interface or new service must be clearly stated.
5. [Mandatory] Outdated classes or methods cannot be used.

Description: The method decode(String encodeStr) in java.net.URLDecoder is obsolete. The two-parameter decode(String source, String encode) should be used. Since the interface provider is clearly an obsolete interface, it is obligated to provide a new interface at the same time; as a caller, it is obligated to verify the new implementation of the obsolete method.
6. [Mandatory] The equals method of Object is prone to throwing a null pointer exception. You should use a constant or an object with a certain value to call equals.

Positive example: "test".equals(object); Counterexample: object.equals("test");

Note: It is recommended to use java.util.Objects#equals (introduced by JDK7 Tool class)
7. [Mandatory] Use the equals method to compare values ​​between all package class objects of the same type.

Description: For Integer var=? assignment between -128 and 127, the Integer object is generated in IntegerCache.cache and existing objects will be reused. Integer values ​​in this range can be used directly == Make a judgment, but all data outside this range will be generated on the heap and existing objects will not be reused. This is a big pitfall. It is recommended to use the equals method for judgment.
8. [Mandatory] The usage standards for basic data types and packaged data types are as follows:

1) All POJO class attributes must use packaged data types.

 2) The return value and parameters of RPC methods must use wrapped data types.

 3) All local variables [recommended] use basic data types.

Description: The POJO class attribute does not have an initial value to remind users that they must explicitly assign the value themselves when they need to use it. Any NPE issues or warehousing checks are ensured by the user. Positive example: The query result of the database may be null because automatic unboxing and receiving with basic data types have NPE risks.

Counter example: For example, display the increase or decrease of the total transaction amount, that is, plus or minus x%, x is the basic data type, and the RPC service called. When the call is unsuccessful, the default value is returned, and the page displays: 0%, This is unreasonable and should be displayed as a dash -. Therefore, the null value of the wrapped data type can represent additional information, such as: remote call failure and abnormal exit.
9. [Mandatory] When defining POJO classes such as DO/DTO/VO, do not set any attribute default values.

Counterexample: The default value of gmtCreate of the POJO class is new Date(); however, this attribute does not have a specific value when extracting data. This field is also updated when other fields are updated, causing the creation time to be Change to current time.
10. [Mandatory] When adding new attributes to the serialization class, please do not modify the serialVersionUID field to avoid deserialization failure; if it is completely incompatible with upgrades and avoid deserialization chaos, please modify the serialVersionUID value.

Note: Note that inconsistent serialVersionUID will throw a serialization runtime exception.
11. [Mandatory] It is prohibited to add any business logic in the construction method. If there is initialization logic, please put it in the init method.
12. [Mandatory] The POJO class must write the toString method. When using the IDE tool: source>generate toString, if you inherit another POJO class, be sure to add super.toString in front.

  说明:在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。
13. 【推荐】使用索引访问用String的split方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有抛IndexOutOfBoundsException的风险。
  说明:
    String str = "a,b,c,,";
    String[] ary = str.split(",");
    //预期大于3,结果是3
    System.out.println(ary.length);
14. 【推荐】当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起,便于阅读。
15. 【推荐】 类内方法定义顺序依次是:公有方法或保护方法 > 私有方法 > getter/setter方法。 说明:公有方法是类的调用者和维护者最关心的方法,首屏展示最好;保护方法虽然只是子类关心,也可能是“模板设计模式”下的核心方法;而私有方法外部一般不需要特别关心,是一个黑盒实现;因为方法信息价值较低,所有Service和DAO的getter/setter方法放在类体最后。
16. 【推荐】setter方法中,参数名称与类成员变量名称一致,this.成员名=参数名。在getter/setter方法中,尽量不要增加业务逻辑,增加排查问题的难度。

  反例:

public Integer getData() {if (true) {return data + 100;
        } else {return data - 100;
        }
    }

17. 【推荐】循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。 反例:

String str = "start";for (int i = 0; i < 100; i++) {
    str = str + "hello";
}

说明:反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。
18. 【推荐】final可提高程序响应效率,声明成final的情况:

  1) 不需要重新赋值的变量,包括类属性、局部变量。

  2) 对象参数前加final,表示不允许修改引用的指向。

  3) 类方法确定不允许被重写。
19. 【推荐】慎用Object的clone方法来拷贝对象。

  说明:对象的clone方法默认是浅拷贝,若想实现深拷贝需要重写clone方法实现属性对象的拷贝。
20. 【推荐】类成员与方法访问控制从严:

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

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

  3) 类非static成员变量并且与子类共享,必须是protected。

  4) 类非static成员变量并且仅在本类使用,必须是private。

  5) 类static成员变量如果仅在本类使用,必须是private。

  6) 若是static成员变量,必须考虑是否为final。

  7) 类成员方法只供类内部调用,必须是private。

  8) 类成员方法只对继承类公开,那么限制为protected。

  说明:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。

  思考:如果是一个private的方法,想删除就删除,可是一个public的Service方法,或者一个public的成员变量,删除一下,不得手心冒点汗吗?变量像自己的小孩,尽量在自己的视线内,变量作用域太大,如果无限制的到处跑,那么你会担心的。

(五) 集合处理

1. 【强制】关于hashCode和equals的处理,遵循如下规则:

  1) 只要重写equals,就必须重写hashCode。

  2) 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。

  3) 如果自定义对象做为Map的键,那么必须重写hashCode和equals。

    正例:String重写了hashCode和equals方法,所以我们可以非常愉快地使用String对象作为key来使用。
2. 【强制】 ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList ;

  说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList 的一个视图,对于SubList子列表的所有操作最终会反映到原列表上。
3. 【强制】 在subList场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均产生ConcurrentModificationException 异常。
4. 【强制】使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()。

  反例:直接使用toArray无参方法存在问题,此方法返回值只能是Object[]类,若强转其它类型数组将出现ClassCastException错误。

  正例:

List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);

说明:使用toArray带参方法,入参分配的数组空间不够大时,toArray方法内部将重新分配内存空间,并返回新数组地址;如果数组元素大于实际所需,下标为[ list.size() ]的数组元素将被置为null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集合元素个数一致。

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

  说明:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。 String[] str = new String[] { "a", "b" }; List list = Arrays.asList(str);

  第一种情况:list.add("c"); 运行时异常。

  第二种情况:str[0]= "gujin"; 那么list.get(0)也会随之修改。
6. 【强制】泛型通配符来接收返回的数据,此写法的泛型集合不能使用add方法。

  说明:苹果装箱后返回一个对象,此对象就不能往里加任何水果,包括苹果。
7. 【强制】不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。

  反例:

List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");for (String temp : a) {if ("1".equals(temp)) {
        a.remove(temp);
    }
}

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗? 正例:

Iterator<String> it = a.iterator();while (it.hasNext()) {
    String temp = it.next();if (删除元素的条件) {
        it.remove();
    }
}

8. 【强制】 在JDK7版本以上,Comparator要满足自反性,传递性,对称性,不然Arrays.sort,Collections.sort会报IllegalArgumentException异常。

  说明:

  1) 自反性:x,y的比较结果和y,x的比较结果相反。

  2) 传递性:x>y,y>z,则x>z。

  3) 对称性:x=y,则x,z比较结果和y,z比较结果相同。

  反例:下例中没有处理相等的情况,实际使用中可能会出现异常:

new Comparator<Student>() {
    @Overridepublic int compare(Student o1, Student o2) {return o1.getId() > o2.getId() ? 1 : -1;
    }
}

9. 【推荐】集合初始化时,尽量指定集合初始值大小。 说明:ArrayList尽量使用ArrayList(int initialCapacity) 初始化。

10. 【推荐】使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。

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

  正例:values()返回的是V值集合,是一个list集合对象;keySet()返回的是K值集合,是一个Set集合对象;entrySet()返回的是K-V值组合集合。
11. 【推荐】高度注意Map类集合K/V能不能存储null值的情况,如下表格:

集合类 Key Value Super 说明
Hashtable 不允许为null 不允许为null Dictionary 线程安全
ConcurrentHashMap 不允许为null 不允许为null AbstractMap 分段锁技术
TreeMap 不允许为null 允许为null AbstractMap 线程不安全
HashMap 允许为null 允许为null AbstractMap 线程不安全

 

 

 

 

  反例: 由于HashMap的干扰,很多人认为ConcurrentHashMap是可以置入null值,注意存储null值时会抛出NPE异常。
12. 【参考】合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和不稳定性(unorder)带来的负面影响。

  说明:稳定性指集合每次遍历的元素次序是一定的。有序性是指遍历的结果是按某种比较规则依次排列的。如:ArrayList是order/unsort;HashMap是unorder/unsort;TreeSet是order/sort。
13. 【参考】利用Set元素唯一的特性,可以快速对一个集合进行去重操作,避免使用List的contains方法进行遍历、对比、去重操作。

(六) 并发处理

1. 【强制】获取单例对象需要保证线程安全,其中的方法也要保证线程安全。

  说明:资源驱动类、工具类、单例工厂类都需要注意。
2. 【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。

  正例:

public class TimerTaskThread extends Thread {public TimerTaskThread(){super.setName("TimerTaskThread"); 
    ...
}

3. 【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

  说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。

4. 【强制】线程池不允许使用 Executors去创建,而是通过ThreadPoolExecutor去创建,这样的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。

  说明: Executors返回的线程池对象的弊端如下 :

  1)FixedThreadPool和 SingleThread:

    允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。

  2)CachedThreadPool和 ScheduledThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
5. 【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。

  正例:注意线程安全,使用DateUtils。亦推荐如下处理:

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
    @Overrideprotected DateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd");
    }
 }

说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替Simpledateformatter,官方给出的解释:simple beautiful strong immutable thread-safe。

6. 【强制】高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。
7. 【强制】对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。

  说明:线程一需要对表A、B、C依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是A、B、C,否则可能出现死锁。
8. 【强制】并发修改同一记录时,避免更新丢失,要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用version作为更新依据。

  说明:如果每次访问冲突概率小于20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3次。
9. 【强制】多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
10. 【推荐】使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至countDown方法,直到超时才返回结果。

  说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。
11. 【推荐】避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。
  说明:Random实例包括java.util.Random 的实例或者 Math.random()实例。

  正例:在JDK7之后,可以直接使用API ThreadLocalRandom,在 JDK7之前,可以做到每个线程一个实例。
12. 【推荐】通过双重检查锁(double-checked locking)(在并发场景)实现延迟初始化的优化问题隐患(可参考 The "Double-Checked Locking is Broken" Declaration),推荐问题解决方案中较为简单一种(适用于JDK5及以上版本),将目标属性声明为 volatile型。

反例:

class Foo {private Helper helper = null;public Helper getHelper() {if (helper == null)synchronized (this) {if (helper == null)
                    helper = new Helper();
            }return helper;
    }// other functions and members...}

13. [Reference] Volatile solves the problem of invisible memory in multi-threads. For one write and many reads, the problem of variable synchronization can be solved, but if there are many writes, the thread safety problem cannot be solved. If it is a count++ operation, use the following class to implement it: AtomicInteger count = new AtomicInteger(); count.addAndGet(1); If it is JDK8, it is recommended to use the LongAdder object, which has better performance than AtomicLong (reduces the number of optimistic lock retries).

14. [Reference] When HashMap has insufficient capacity for resize, dead links may occur due to high concurrency, causing the CPU to surge. Please pay attention to avoid this risk during the development process.
15. [Reference] ThreadLocal cannot solve the update problem of shared objects. It is recommended to use static modification for ThreadLocal objects. This variable is common to all operations within a thread, so it is set as a static variable. All such instances share this static variable, which means that when the class is used for the first time, it is loaded and only a piece of storage space is allocated. Objects (as long as they are defined within this thread) can manipulate this variable.

(7) Control statements

1. [Mandatory] Within a switch block, each case should either be terminated by break/return, etc., or a comment indicating which one the program will continue to execute. case; within a switch block, a default statement must be included and placed at the end, even if it has no code.
2. [Mandatory] Braces must be used in if/else/for/while/do statements, even if there is only one line of code, avoid using the following forms: if (condition) statements;
3. [Recommended] It is recommended to use else as little as possible. The if-else method can be rewritten as:
 if(condition){
  ...
  return obj;
 }
 // Then write the else business logic Code;
Description: If you have to use if()...else if()...else... to express logic, [Mandatory] do not exceed 3 levels. If you exceed this level, please use the state design pattern.
Positive example: if-else code with more than 3 levels of logic can be implemented using guard statements or state patterns.
4. [Recommendation] Except for common methods (such as getXxx/isXxx), do not execute other complex statements in conditional judgments, and assign the results of complex logical judgments to a meaningful Boolean variable name to improve reliability. Readability.

Explanation: The logic in many if statements is quite complex. Readers need to analyze the final result of the conditional expression to clarify what conditions execute what statement. Then, if the reader analyzes the logical expression incorrectly Woolen cloth?

Positive example:
//The pseudo code is as follows
boolean existed = (file.open(fileName, "w") != null) && (...) || (... );
 if (existed) {
   ...
  }
Counter example:
 if ((file.open(fileName, "w") != null) && (... ) || (...)) {
    ...
  }
5. [Recommendation] The statements in the loop body should consider performance. The following operations should be moved outside the loop as much as possible, such as defining objects, Variables, obtain database connections, and perform unnecessary try-catch operations (can this try-catch be moved outside the loop)?
6. [Recommended] Interface input parameter protection. This scenario is common for interfaces used for batch operations.
7. [Reference] Scenarios where parameter verification is required in methods:

 1) Methods that are called frequently.

 2) For methods that require a large execution time, the parameter verification time is almost negligible. However, if the intermediate execution rolls back or makes an error due to parameter errors, the gain outweighs the loss.
 3) A method that requires extremely high stability and availability.

 4) The open interface provided to the outside world, whether it is RPC/API/HTTP interface.
 5) Sensitive permissions entrance.
8. [Reference] Scenarios where parameter verification is not required in methods:

1) It is not recommended to verify parameters for methods that are very likely to be called cyclically. However, external parameter checking must be noted in the method description.

 2) The underlying methods are called frequently and are generally not verified. After all, it is like the last step of pure water filtration, and parameter errors are unlikely to expose problems until the bottom layer. Generally, the DAO layer and Service layer are in the same application and deployed on the same server, so DAO parameter verification can be omitted.

 3) A method declared as private will only be called by your own code. If you can be sure that the parameters passed in by the code calling the method have been checked or there are definitely no problems, you do not need to verify the parameters at this time. .

(8) Comment regulations

1. [Mandatory] Comments on classes, class attributes, and class methods must use Javadoc specifications and use the /**content*/ format. / is not allowed. /xxx mode.

Description: In the IDE editing window, the Javadoc mode will prompt relevant comments, and the generated Javadoc can correctly output the corresponding comments; in the IDE, when the project calls a method, the method, parameters, and returns can be suspended without entering the method. value and improve reading efficiency.
2. [Mandatory] All abstract methods (including methods in interfaces) must be annotated with Javadoc. In addition to return values, parameters, and exception descriptions, it must also indicate what the method does and what functions it implements.

Note: Please explain the implementation requirements for subclasses or calling precautions.
3. [Mandatory] All classes must add creator information.
4. [Mandatory] Single-line comments inside the method, start a new line above the commented statement, and use // comment. Use /* */ comments for multi-line comments inside methods, and be sure to align them with the code.
5. [Mandatory] All enumeration type fields must have comments to explain the purpose of each data item.
6. [Recommendation] Rather than commenting in half-hearted English, it is better to use Chinese comments to explain the problem clearly. Proper nouns and keywords can remain in the original English text.

Counter example: "TCP connection timeout" is interpreted as "Transmission Control Protocol connection timeout", which is troublesome to understand.
7. [Recommendation] When modifying the code, comments should also be modified accordingly, especially modifications to parameters, return values, exceptions, core logic, etc.

Description: Code and annotation updates are out of sync, just like road network and navigation software updates are out of sync. If the navigation software lags behind seriously, the meaning of navigation will be lost.
8. [Reference] The commented out code should match the description as much as possible, rather than simply commented out.

Note: There are two possibilities for the code to be commented out:

1) The logic of this code will be restored later.

  2) Never use. If there is no remark information in the former, it is difficult to know the motivation of the annotation. The latter is recommended to be deleted directly (the code repository saves historical code).
9. [Reference] Requirements for comments:

First, they can accurately reflect the design ideas and code logic;

Second, they can describe the business meaning so that other programmers can Able to quickly understand the information behind the code. A large block of code without comments is like a sacred book to the reader. The comments are for yourself to read, so that you can clearly understand the thinking at that time even after a long time; the comments are also for your successors to read, so that they can quickly take over their own work. Work.
10. [Reference] Good naming and code structure are self-explanatory, and comments should be concise, accurate, and expressive. Avoid one extreme of comments: too many and excessive comments. Once the logic of the code is modified, modifying the comments will be a considerable burden.

Counter example:
// put elephant into fridge
Put(elephant, fridge);
The method name put, plus two meaningful variable names elephant and bridge, has been explained What this is doing is that semantically clear code does not require additional comments.
11. [Reference] Special comment mark, please indicate the person who marked it and the time of marking. Pay attention to dealing with these marks in a timely manner, and clean such marks frequently through mark scanning. Online faults sometimes originate from the code at these marks.

 1) To-do items (TODO): (mark person, mark time, [estimated processing time]) Indicates functions that need to be implemented but have not yet been implemented. This is actually a Javadoc tag. The current Javadoc has not yet been implemented, but it has been widely used. Can only be applied to classes, interfaces and methods (because it is a Javadoc tag). 2) Error, cannot work (FIXME): (mark person, mark time, [estimated processing time]) Use FIXME in the comments to mark that a certain code is wrong and cannot work and needs to be corrected in time.

(9) Others

1. [Mandatory] When using regular expressions, make good use of its pre-compilation function to effectively speed up regular expression matching.

Note: Do not define it in the method body: Pattern pattern = Pattern.compile(rule);
2. [Mandatory] When velocity calls the attributes of the POJO class, it is recommended to use the attribute name directly to get the value. The template engine will automatically call POJO's getXxx() according to the specification. If it is a boolean basic data type variable (the boolean name does not need to be prefixed with is), the isXxx() method will be automatically called.

Note: Note that if it is a Boolean wrapper class object, the getXxx() method is called first.
3. [Mandatory] The variables sent to the page in the background must be added with $!{var} - an exclamation point in the middle.

Description: If var=null or does not exist, ${var} will be displayed directly on the page.
4. [Mandatory] Note that the Math.random() method returns a double type. Please note that the value range is 0≤x<1 (zero value can be obtained, please note the division-by-zero exception). If you want to obtain the integer type For random numbers, do not magnify x by several times 10 and then round it. Use the nextInt or nextLong method of the Random object directly.
5. [Mandatory] Get the current number of milliseconds System.currentTimeMillis(); instead of new Date().getTime();

Description: If you want to get a more accurate nanosecond time value, use System.nanoTime(). In JDK8, it is recommended to use the Instant class for scenarios such as statistical time.
6. [Recommendation] Try not to add variable declarations and logical operators to the vm, let alone any complex logic to the vm template.
7. [Recommendation] The size should be specified when constructing or initializing any data structure to avoid unlimited growth of the data structure and eating up the memory.
8. [Recommendation] For "code and configurations that are clearly out of use", such as methods, variables, classes, configuration files, dynamic configuration attributes, etc., you must resolutely clean them out of the program to avoid causing too much garbage.

2. Exception log

(1) Exception handling

1. [Mandatory] Do not capture runtime exception classes defined in the Java class library that inherit from RuntimeException, such as: IndexOutOfBoundsException / NullPointerException, this type of exception is avoided by programmers' pre-checking to ensure program robustness.

Positive example: if(obj != null) {...}

Counterexample: try { obj.method() } catch(NullPointerException e){...}
2. [Mandatory] Do not use exceptions for process control or conditional control, because the processing efficiency of exceptions is lower than that of conditional branches.
3. [Mandatory] Try-catch a large section of code, which is irresponsible. Please distinguish between stable code and unstable code when catching. Stable code refers to code that will not go wrong no matter what. For the catch of unstable code, try to distinguish the exception type as much as possible, and then handle the corresponding exception.
4. [Mandatory] Catch an exception in order to handle it. Don't catch it and discard it without processing anything. If you don't want to handle it, please throw the exception to its caller. The outermost business user must handle exceptions and convert them into content that users can understand.
5. [Mandatory] Place the try block in the transaction code. After catching the exception, if you need to roll back the transaction, you must pay attention to manually rolling back the transaction.
6. [Mandatory] The finally block must close the resource object and stream object, and try-catch if there is an exception.

Note: If JDK7, you can use try-with-resources method.
7. [Mandatory] Return cannot be used in the finally block. After the return in the finally block returns, the method ends execution and the return statement in the try block will not be executed.
8. [Mandatory] The caught exception and the thrown exception must match exactly, or the caught exception is the parent class of the thrown exception.

Explanation: If the opponent is expected to throw a hydrangea ball but actually receives a shot put, an unexpected situation will occur.
9. [Recommendation] The return value of the method can be null. It is not mandatory to return an empty collection or an empty object. Comments must be added to fully explain under what circumstances a null value will be returned. The caller needs to perform null judgment to prevent NPE problems.

Description: This specification clearly states that it is the caller's responsibility to prevent NPE. Even if the called method returns an empty collection or an empty object, it is not a worry-free situation for the caller. It must consider the situation where null is returned in scenarios such as remote call failure, runtime exception, etc.
10. [Recommendation] Preventing NPE is the basic training of programmers. Pay attention to the scenarios where NPE occurs:

1) The return type is a packed data type, which may be null. Pay attention to judgment when returning an int value. null.

Counter example: public int f(){ return Integer object}; If it is null, it will automatically unbox and throw NPE.

 2) The query result of the database may be null.

 3) Even if the element in the collection isNotEmpty, the retrieved data element may be null.
 4) NPE judgment is always required for objects returned by remote calls.

 5) For the data obtained in the Session, it is recommended to check NPE to avoid null pointers.

 6) Cascading calls to obj.getA().getB().getC(); a series of calls can easily cause NPE.
11. [Recommendation] Whether to use "throw exception" or "return error code" in the code. For http/api open interfaces outside the company, "error code" must be used; within the application, exception throwing is recommended; across applications Priority is given to using the Result method for RPC calls, encapsulating isSuccess, "error code", and "error brief information". Note: Reasons for using the Result method for RPC method return:

1) Using the exception return method, a runtime error will occur if the caller does not catch it.

 2) If you do not add stack information, just new custom exceptions, and add your own understanding of the error message, it will not be of much help to the calling end in solving the problem. If stack information is added, the performance loss of data serialization and transmission is also a problem in the case of frequent call errors.
12. [Recommendation] Distinguish unchecked/checked exceptions when defining, avoid using RuntimeException to throw directly, and do not allow throwing Exception or Throwable. Custom exceptions with business meaning should be used. We recommend custom exceptions that have been defined in the industry, such as: DAOException / ServiceException, etc.
13. [Reference] Avoid duplicate code (Don’t Repeat Yourself), that is, the DRY principle. Note: Copying and pasting code at will will inevitably lead to duplication of code. When modification is needed in the future, all copies will need to be modified, which is easy to miss. Extract common methods, abstract public classes, or even shared modules when necessary.

Positive example: There are multiple public methods in a class, and they all need to perform several rows of the same parameter verification operations. At this time, please extract:
private boolean checkParam(DTO dto){...}

(2) Log protocol

1. [Mandatory] The application cannot directly use the API in the log system (Log4j, Logback), but should rely on the API in the log framework SLF4J and use the facade mode. The log framework is conducive to maintenance and unification of log processing methods for each category.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 private static final Logger logger = LoggerFactory.getLogger(Abc.class);
2. [Mandatory] The log file is recommended to be at least Save for 15 days, because some anomalies have the characteristic of occurring with a frequency of "weeks".
3. [Mandatory] Naming method for extended logs in applications (such as management, temporary monitoring, access logs, etc.): appName_logType_logName.log. logType: log type, recommended categories include stats/desc/monitor/visit, etc.; logName: log description. The advantage of this kind of naming: you can know what application the log file belongs to, what type, and what purpose through the file name, which is also helpful for classification and search.

Positive example: separately monitor time zone conversion exceptions in the mppserver application, such as: mppserver_monitor_timeZoneConvert.log Note: It is recommended to classify logs. Error logs and business logs should be stored separately as much as possible to facilitate developers to view and compare logs. The system performs timely monitoring.
4. [Mandatory] For trace/debug/info level log output, you must use conditional output or use placeholders.

Description: logger.debug("Processing trade with id: " + id + " symbol: " + symbol); If the log level is warn, the above log will not be printed, but the string splicing operation will be performed. If symbol is an object, the toString() method will be executed, which wastes system resources. After performing the above operations, the final log is not printed.

Positive example: (condition)
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
 }
Positive example: (placeholder)
logger.debug("Processing trade with id: {} symbol : {} ", id, symbol);
5. [Mandatory] Avoid duplication To print logs and waste disk space, be sure to set additivity=false in log4j.xml.

Positive example:
6. [Mandatory] Abnormal information should include two types of information: crime scene information and exception stack information. If not, throw it up.

Positive example: logger.error(various parameters or objects toString + "_" + e.getMessage(), e);
7. [Recommendation] You can use the warn log level to record user input In the case of parameter errors, users will be at a loss to avoid complaints. Pay attention to the level of log output. The error level only records important error information such as system logic errors and exceptions. If it is not necessary, please do not enter the error level in this scenario.
8. [Recommended] Record logs carefully. It is forbidden to output debug logs in the production environment; selectively output info logs; if you use warn to record business behavior information when it is first launched, you must pay attention to the amount of log output to avoid bursting the server disk, and remember to delete these observation logs in time .

Description: Outputting a large number of invalid logs is not conducive to system performance improvement, nor is it conducive to quickly locating error points. When recording logs, please think: Is anyone really reading these logs? What can you do after seeing this log? Can it bring benefits to troubleshooting?

3. MySQL specifications

(1) Table creation specifications

1. [Mandatory] Fields that express the concept of yes or no must be named using is_xxx, and the data type It is unsigned tinyint (1 means yes, 0 means no). This rule also applies to ODPS table creation.

Note: If any field is a non-negative number, it must be unsigned.
2. [Mandatory] Table names and field names must use lowercase letters or numbers; it is forbidden to start with numbers, and it is forbidden to only have numbers between two underscores. Modification of database field names is very costly, because pre-release is not possible, so field names need to be carefully considered.

Positive example: getter_admin, task_config, level3_name

Counter example: GetterAdmin, taskConfig, level_3_name
3. [Mandatory] Do not use plural nouns in table names. Note: The table name should only represent the entity content in the table, and should not represent the number of entities. The corresponding DO class name is also in singular form, which is consistent with expression habits.
4. [Mandatory] Disable reserved words, such as desc, range, match, delayed, etc. Please refer to MySQL official reserved words.
5. [Mandatory] The unique index name is uk_field name; the common index name is idx_field name. Note: uk_ is unique key; idx_ is the abbreviation of index.
6. [Mandatory] The decimal type is decimal, and float and double are prohibited.

Note: When float and double are stored, there is a problem of precision loss, and it is possible to obtain incorrect results when comparing values. If the range of stored data exceeds the range of decimal, it is recommended to split the data into integers and decimals and store them separately.
7. [Mandatory] If the lengths of the stored strings are almost equal, use the char fixed-length string type.
8. [Mandatory] Varchar is a variable-length string. No storage space is allocated in advance. The length should not exceed 5000. If the storage length is greater than this value, define the field type as text, create a separate table, and use the primary key to correspond. , to avoid affecting the index efficiency of other fields.
9. [Mandatory] The table must have three fields: id, gmt_create, gmt_modified.

Description: The id must be the primary key, the type is unsigned bigint, it will increase automatically when it is a single table, and the step size is 1. The types of gmt_create and gmt_modified are all date_time types.
10. [Recommendation] It is best to name the table with "business name_function of the table". Positive example: tiger_task / tiger_reader / mpp_config
11. [Recommended] The library name and application name should be as consistent as possible.
12. [Recommendation] If you modify the meaning of a field or add the status represented by a field, you need to update the field comments in time.
13. [Recommendation] Allow appropriate redundancy in fields to improve performance, but data synchronization must be considered. Redundant fields should follow:

 1) Fields that are not frequently modified. 2) It is not a varchar super long field, let alone a text field.

Positive example: The product category name is used frequently, the field length is short, and the name is basically unchanged. The category name can be stored redundantly in the associated table to avoid associated queries.
14. [Recommendation] It is recommended to perform database and table sharding only if the number of rows in a single table exceeds 5 million or the capacity of a single table exceeds 2GB.

Note: If the data volume is not expected to reach this level in three years, please do not divide the database into tables when creating the table.
15. [Reference] Appropriate character storage length not only saves database table space and index storage, but more importantly, improves retrieval speed.

Positive example: The age of a person is unsigned tinyint (indicates the range 0-255, the life span of a human being will not exceed 255 years); the turtle must be a smallint, but if it is the age of the sun, it must be an int; If the ages of all stars are added up, then bigint must be used.

(2) Index specification

1. [Mandatory] Fields with unique business characteristics, even if they are combined fields, must be built into a unique index.

Note: Don’t think that the unique index affects the insert speed. This speed loss can be ignored, but the improvement in search speed is obvious; in addition, even if there is a very complete checksum control at the application layer, as long as there is no unique Indexes, according to Murphy's Law, must have dirty data.
2. [Mandatory] Joining more than three tables is prohibited. The data types of the fields that need to be joined must be absolutely consistent; when querying multiple tables, make sure that the related fields need to have indexes.

Description: Even if you join a double table, you must pay attention to table indexes and SQL performance.
3. [Mandatory] When creating an index on a varchar field, the index length must be specified. It is not necessary to index the entire field. The index length is determined based on the actual text distinction.

Explanation: The length and distinction of the index are a pair of contradictions. Generally, for string type data, the distinction will be as high as 90% or more for an index with a length of 20. You can use count(distinct left(column name , determined by the discrimination of index length))/count(*).
4. [Mandatory] Left blur or full blur is strictly prohibited in page search. If necessary, please use the search engine to solve the problem.

Description: The index file has the leftmost prefix matching feature of B-Tree. If the value on the left is not determined, then this index cannot be used.
5. [Recommendation] If there is an order by scenario, please pay attention to the orderliness of the index. The last field in order by is part of the combined index and is placed at the end of the index combination order to avoid file_sort and affect query performance.

Positive example: where a=? and b=? order by c; Index: a_b_c

Counterexample: If there is a range search in the index, the order of the index cannot be used, such as: WHERE a> ;10 ORDER BY b; Index a_b cannot be sorted.
6. [Recommended] Use covering indexes to perform query operations to avoid table return operations.

Explanation: If a book needs to know the title of Chapter 11, will it open the page corresponding to Chapter 11? Just browse the directory. This directory serves as a covering index.

Positive example: Types of indexes that can be created: primary key index, unique index, ordinary index, and covering index is an effect of a query. With the explain result, the extra column will appear: using index.
7. [Recommended] Use delayed correlation or subquery to optimize multi-page paging scenarios.

Description: MySQL does not skip the offset row, but takes the offset+N rows, and then returns the offset row before giving up, and returns N rows. When the offset is particularly large, the efficiency is very low, or Control the total number of pages returned, or perform SQL rewrites on pages that exceed a certain threshold.

  Positive example: First quickly locate the id segment that needs to be obtained, and then associate: SELECT a.* FROM table 1 a, (select id from table 1 where condition LIMIT 100000,20) b where a.id=b.id
8. [Recommendation] The goal of SQL performance optimization: at least reach the range level, the requirement is ref level, if it can be consts, it is best.

Description:

1) Consts There is at most one matching row (primary key or unique index) in a single table, and the data can be read during the optimization phase.

  2) ref refers to using a normal index.

  3) range performs a range search on the index.

Counter example: The result of the explain table, type=index, is a full scan of the index physical file, which is very slow. This index level is lower than range, and is dwarfed by a full table scan.
9. [Recommendation] When building a combined index, the highest degree of differentiation is on the far left. Positive example: If where a=? and b=?, column a is almost close to a unique value, then you only need to create a single idx_a index.

Note: When there is a mixed judgment condition of non-equal sign and equal sign, when building the index, please put the column of the equal sign condition in front. For example: where a>? and b=? Then even if a has a higher degree of distinction, b must be placed at the forefront of the index.
10. [Reference] Avoid the following extreme misunderstandings when creating an index:

1) Misunderstanding that a query requires an index.

 2) Mistakenly believe that indexes will consume space and seriously slow down updates and new additions.

 3) It is mistakenly believed that unique indexes must be solved at the application layer through the "check first and then insert" method.

(3) SQL specification

1. [Mandatory] Do not use count (column name) or count (constant) instead of count(*), count(*) is the standard defined by SQL92 The syntax for counting rows has nothing to do with the database, and has nothing to do with NULL or non-NULL.

Description: count(*) will count rows with NULL values, while count(column name) will not count rows with NULL values ​​in this column.
2. [Mandatory] count(distinct col) Calculate the number of distinct numbers in the column except NULL. Note that count(distinct col1, col2) returns 0 if one of the columns is all NULL, even if the other column has different values.
3. [Mandatory] When the values ​​of a certain column are all NULL, the return result of count(col) is 0, but the return result of sum(col) is NULL, so you need to pay attention to the NPE problem when using sum().

Positive example: You can use the following method to avoid the NPE problem of sum: SELECT IF(ISNULL(SUM(g)),0,SUM(g)) FROM table;
4. [Mandatory] Use ISNULL() to determine whether it is a NULL value. Note: A direct comparison of NULL with any value returns NULL.

Explanation: 1) NULL<>The return result of NULL is NULL, not false.

2) The return result of NULL=NULL is NULL, not true.

   3) The return result of NULL<>1 is NULL, not true.
5. [Mandatory] When writing paging query logic in the code, if count is 0, it should be returned directly to avoid executing subsequent paging statements.
6. [Mandatory] Foreign keys and cascades are not allowed, and all foreign key concepts must be solved at the application layer. Note: (Concept explanation) student_id in the student table is the primary key, then student_id in the grades table is the foreign key. If the student_id in the student table is updated and the student_id in the grades table is updated at the same time, it is a cascade update. Foreign keys and cascade updates are suitable for low concurrency on a single machine, but are not suitable for distributed and high-concurrency clusters; cascade updates are strongly blocking and have the risk of database update storms; foreign keys affect the insertion speed of the database.
7. [Mandatory] The use of stored procedures is prohibited. Stored procedures are difficult to debug and extend, and have no portability.
8. [Mandatory] When revising data, when deleting or modifying records, you must select first to avoid accidental deletion. Only after confirmation can the update statement be executed.
9. [Recommendation] Avoid the in operation if it can be avoided. If it cannot be avoided, you need to carefully evaluate the number of collection elements behind in and control it within 1,000.
10. [Reference] If there is a need for globalization, all character storage and representation are encoded in utf-8, then note the character counting method:

Description: SELECT LENGTH ("Easy Work") ; Returns to 12 SELECT CHARACTER_LENGTH ("Easy Work"); Returns to 4 If you want to use expressions, use utfmb4 for storage, and pay attention to the difference between it and utf-8 encoding.
11. [Reference] TRUNCATE TABLE is faster than DELETE and uses less system and transaction log resources. However, TRUNCATE has no transactions and does not trigger triggers, which may cause accidents. Therefore, it is not recommended to use this statement in development code.

 Note: TRUNCATE TABLE is functionally the same as the DELETE statement without a WHERE clause.

(4) ORM specification

1. [Mandatory] In table queries, do not use * as the field list of the query. Which fields are required must be clearly stated.

Description:

1) Increase the query analyzer parsing cost.

  2) Adding or subtracting fields is easy to be inconsistent with the resultMap configuration.
2. [Mandatory] The boolean attribute of the POJO class cannot be added with is, but the database field must be added with is_, which requires mapping between fields and attributes in the resultMap.

Note: Please refer to the POJO class definition and database field definition regulations. It is necessary to add mapping in sql.xml.
3. [Mandatory] Do not use resultClass as a return parameter. Even if all class attribute names correspond to database fields, they still need to be defined; conversely, each table must have one corresponding to it.

Description: Configure the mapping relationship to decouple fields from DO classes for easy maintenance.
4. [Mandatory] Please pay attention to the use of parameters in xml configuration: #{}, #param# Do not use ${}. This method is prone to SQL injection.
5. [Mandatory] The queryForList(String statementName, int start, int size) that comes with iBATIS is not recommended.

Description: The implementation method is to obtain all the records of the SQL statement corresponding to statementName in the database, and then obtain the subsets of start and size through subList. OOM has occurred online because of this reason.
Positive example: Introduce #start#, #size
# in sqlmap.xml Map map = new HashMap();
map.put("start" , start);
Map.put("size", size);
6. [Mandatory] It is not allowed to directly use HashMap and Hashtable as the output of the query result set.
7. [Mandatory] When updating the data table record, you must also update the corresponding gmt_modified field value of the record to the current time.
8. [Recommendation] Do not write a large and comprehensive data update interface. Pass it in as a POJO class. Regardless of whether it is your own target update field, update table set c1=value1,c2=value2,c3=value3. ; this is not right. When executing SQL, try not to update unmodified fields. First, it is error-prone; second, it is inefficient; third, binlog increases storage.
9. [Reference] Do not abuse @Transactional transactions. Transactions will affect the QPS of the database. In addition, where transactions are used, various rollback solutions need to be considered, including cache rollback, search engine rollback, message compensation, statistical correction, etc.
10. [Reference] The compareValue in is a constant that is compared with the attribute value, usually a number, and this condition is used when it means they are equal; means it is not empty or null; it is executed when it is not empty; means execution when the value is not null.

4. Engineering Specification

(1) Application Layering

1. [Recommended] By default, the upper layer in the figure depends on the lower layer, and the arrow relationship indicates direct dependence, such as: The open interface layer can depend on the Web layer or directly depend on the Service layer, and so on:
 Open interface layer: It can directly encapsulate the Service interface and expose it into an RPC interface; encapsulate it into an http interface through the Web; gateway control layer, etc. .
 Terminal display layer: The templates of each terminal render and execute the display layer. Currently, the main ones are velocity rendering, JS rendering, JSP rendering, mobile display layer, etc.
 Web layer: mainly for forwarding access control, various basic parameter verification, or simple processing of non-reused services, etc.
 Service layer: relatively specific business logic service layer.
 Manager layer: a general business processing layer, which has the following characteristics:

 1) For the third-party platform encapsulated layer, preprocessing return results and conversion of exception information;

 2) The sinking of general capabilities of the Service layer, such as caching solutions and middleware general processing;

 3) Interacting with the DAO layer to encapsulate DAO's general business capabilities.
 DAO layer: Data access layer, which interacts with underlying MySQL, Oracle, and Hbase for data.
 External interfaces or third-party platforms: including RPC open interfaces from other departments, basic platforms, and HTTP interfaces from other companies.
2. [Reference] (Hierarchical Exception Handling Protocol) In the DAO layer, there are many types of exceptions generated. It is impossible to catch fine-grained exceptions. Use the catch(Exception e) method and throw new DAOException(e). There is no need to print logs, because logs must be captured and logged in the log file at the Manager/Service layer. If the same server logs again, performance and storage will be wasted. When an exception occurs in the Service layer, log information must be recorded to disk, and parameter information must be included as much as possible, which is equivalent to protecting the crime scene. If the Manager layer and the Service are deployed on the same machine, the logging method is consistent with the DAO layer processing. If they are deployed separately, the logging method is consistent with the Service. The Web layer should never continue to throw exceptions.
Because it is already at the top level, there is no way to continue handling exceptions. If you realize that this exception will cause the page to fail to render normally, you should jump directly to a friendly error page and try your best to Add friendly error message. The open interface layer should handle exceptions and return them in the form of error codes and error messages.
3. [Reference] Hierarchical domain model specification:
 DO (Data Object): corresponds to the database table structure one-to-one, and transmits the data source object upward through the DAO layer.
 DTO (Data Transfer Object): Data transfer object, an object transferred externally by Service and Manager.
 BO (Business Object): Business object. An object that encapsulates business logic and can be output by the Service layer.
 QUERY: Data query object, each layer receives query requests from the upper layer. Note: Query encapsulation with more than 2 parameters is prohibited from using the Map class for transmission.
 VO (View Object): Display layer object, usually an object transmitted by the Web to the template rendering engine layer.

(2) Second-party library specifications

1. [Mandatory] Define GAV to comply with the following rules:

 1) GroupID format: com.{Company/BU}.Business Line.[Sub-Business Line], up to 4 levels.

Description: {Company/BU} For example: alibaba/taobao/tmall/aliexpress and other BU level; sub-business lines are optional.

Positive example: com.taobao.jstorm or com.alibaba.dubbo.register

2) ArtifactID format: product line name-module name. The semantics are not repeated or omitted. First go to the warehouse center to verify.

Positive example: dubbo-client / fastjson-api / jstorm-tool 3) Version: See below for detailed regulations.
2. [Mandatory] The second-party library version number naming method: major version number. minor version number. revision number

 1) Major version number: when an incompatible API modification is made, or functionality is added New features that change the direction of the product.

 2) Minor version number: regarded as a backward compatible functional addition (new classes, interfaces, etc.).

 3) Revision number: Fix bugs, enhance functions without modifying method signatures, and maintain API compatibility.

Note: The starting version number must be: 1.0.0, not 0.0.1
3. [Mandatory] Online applications do not rely on the SNAPSHOT version (except for security packages); officially released class libraries The RELEASE version number upgrade +1 method must be used, and the version number is not allowed to be overwritten and upgraded. You must go to the central warehouse for verification.

Description: Not relying on the SNAPSHOT version ensures the idempotence of application release. In addition, it can also speed up the packaging and construction during compilation.
4. [Mandatory] The addition or upgrade of the second-party library will keep the arbitration results of other jar packages except function points unchanged. If there are changes, they must be clearly evaluated and verified. It is recommended to compare the information before and after dependency:resolve. If the arbitration results are completely inconsistent, use the dependency:tree command to find the differences and perform to exclude the jar package.
5. [Mandatory] The second-party library can define enumeration types, and the parameters can use enumeration types, but the interface return value does not allow the use of enumeration types or POJO objects containing enumeration types.
6. [Mandatory] When relying on a second-party library group, a unified version variable must be defined to avoid version number inconsistency.

Description: Depend on springframework-core, -context, and -beans. They are all the same version. You can define a variable to save the version: ${spring.version}. When defining dependencies, reference this version.
7. [Mandatory] It is forbidden to have the same GroupId, the same ArtifactId, but different Versions in the pom dependencies of subprojects.

Note: When debugging locally, the version number specified by each sub-project will be used, but when merged into a war, only one version number can appear in the final lib directory. There have been precedents where offline debugging was correct but problems occurred when released online.
8. [Recommendation] Place the dependency declarations in all pom files in the statement block, and place all version arbitrations in the statement block.

Note: only declares the version and does not implement the introduction. Therefore, the sub-project needs to explicitly declare dependencies. Both version and scope are read from the parent pom. AndAll dependencies declared in the of the main pom will be automatically introduced and inherited by all sub-projects by default.
9. [Recommendation] The second-party library should try not to have configuration items, and at least do not add any more configuration items.
10. [Reference] In order to avoid dependency conflicts when applying second-party libraries, publishers of second-party libraries should follow the following principles:

 1) The principle of simplicity and controllability. Remove all unnecessary APIs and dependencies, including only Service API, necessary domain model objects, Utils classes, constants, enumerations, etc. If you rely on other second-party libraries, try to introduce them through provided, allowing users of the second-party libraries to rely on specific version numbers; there is no specific implementation of log, and you only rely on the log framework.

 2) Stable traceability principle. Changes in each version should be recorded, who maintains the second-party library, and where the source code is, all need to be easily accessible. The behavior of public second-party libraries should not change unless the user actively upgrades the version.

(3) Server Specification

1. [Recommendation] For high-concurrency servers, it is recommended to reduce the time_wait timeout of the TCP protocol. Note: By default, the operating system will close connections in the time_wait state after 240 seconds. Under high concurrent access, the server may not be able to establish new connections because there are too many connections in time_wait, so you need to adjust this value on the server. Wait value.

Positive example: On the Linux server, please modify the default value (seconds) by changing the /etc/sysctl.conf file: net.ipv4.tcp_fin_timeout = 30
2. [Recommended] Increase the value The maximum number of file handles (File Descriptor, abbreviated as fd) supported by the server.

Description: The design of mainstream operating systems is to manage TCP/UDP connections in the same way as files, that is, one connection corresponds to one fd. The default number of FDs supported by mainstream Linux servers is 1024. When the number of concurrent connections is large, it is easy to cause "open too many files" errors due to insufficient FDs, causing new connections to fail to be established. It is recommended to increase the maximum number of handles supported by the Linux server several times (related to the amount of memory on the server).
3. [Recommended] Set the -XX:+HeapDumpOnOutOfMemoryError parameter to the JVM to allow the JVM to output dump information when it encounters an OOM scenario.

Note: OOM occurs with probability, and even occurs regularly every few months. The on-site information when it occurs is very valuable for troubleshooting.
4. [Reference] Use forward for internal redirection of the server; use the URL assembly tool class to generate external redirection addresses, otherwise it will cause inconsistent URL maintenance and potential security risks.

5. Security Regulations

1. [Mandatory] Pages or functions belonging to the user must undergo permission control verification. Note: This prevents users from being able to access and operate other people's data at will without performing horizontal permission verification, such as viewing and modifying other people's orders.
2. [Mandatory] Direct display of sensitive user data is prohibited, and the display data must be desensitized. Note: When viewing your personal mobile phone number, it will be displayed as: 158****9119, hiding the middle 4 digits to prevent privacy leakage.
3. [Mandatory] The SQL parameters entered by the user must be strictly limited by parameter binding or METADATA field values ​​to prevent SQL injection and prohibit string splicing SQL from accessing the database.
4. [Mandatory] Any parameters passed in by the user must be verified for validity. Note: Ignoring parameter verification may lead to:
 Excessive page size causing memory overflow
 Malicious order by causing slow database query
 Arbitrary redirection
 SQL injection
 Deserialization Injection
 Regular input source string Denial of Service ReDoS Description: Java JavaJava code uses regular rules to verify the client's input. Some regular writing methods have no problem verifying ordinary user input, but if the attacker uses a specially constructed string To verify, it may lead to an infinite loop effect.
5. [Mandatory] It is prohibited to output user data that has not been safely filtered or has not been correctly escaped to the HTML page.
6. [Mandatory] CSRF security filtering must be performed on form and AJAX submissions. Description: CSRF (Cross-site request forgery) is a common programming vulnerability. For applications/websites with CSRF vulnerabilities, attackers can construct the URL in advance. As soon as the victim user accesses it, the background will modify the user parameters in the database accordingly without the user's knowledge.
7. [Mandatory] When using platform resources, such as text messages, emails, phone calls, orders, and payments, correct anti-replay restrictions, such as quantity limits, fatigue control, and verification code verification, must be implemented to avoid abuse. Brush, capital loss.

Note: If a verification code is sent to the mobile phone during registration, if there is no limit on the number and frequency, this function can be used to harass other users and cause a waste of SMS platform resources.

The above is the detailed content of Analyze Java coding specifications. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn