Heim >Java >javaLernprogramm >Analysieren Sie Java-Codierungsspezifikationen

Analysieren Sie Java-Codierungsspezifikationen

怪我咯
怪我咯Original
2017-06-25 10:12:352291Durchsuche

1. Programmierkonventionen

(1) Namenskonventionen

1. Namen im Code dürfen nicht mit einem Unterstrich oder einem Dollarzeichen beginnen und auch nicht mit einem Unterstrich enden oder ein Dollarzeichen.

Gegenbeispiel: _nam / __name / $Object / name_ / name$ / Object$
2. [Obligatorisch] Es ist strengstens verboten, eine Mischung aus Pinyin und Englisch für die Benennung im Code zu verwenden Es ist nicht erlaubt, Chinesisch direkt zu verwenden.

Erläuterung: Korrekte englische Rechtschreibung und Grammatik können es den Lesern erleichtern, Unklarheiten zu verstehen und zu vermeiden. Beachten Sie, dass selbst reine Pinyin-Namen vermieden werden sollten.

Gegenbeispiel: DaZhePromotion [Discount] / getPingfenByName() [Rating] / int Eine bestimmte Variable = 3

Positivbeispiel: Alibaba / Taobao / Youku / Hangzhou und andere international gebräuchliche Namen können sein als dasselbe Englisch angesehen.
3. [Obligatorisch] Der Klassenname muss den UpperCamelCase-Stil verwenden und der Kamel-Schreibweise folgen, mit den folgenden Ausnahmen: (zugehörige Benennung des Domänenmodells) DO / BO / DTO / VO usw.

Positivbeispiel: MarcoPolo / UserDO / Variablen und lokale Variablen verwenden alle den LowerCamelCase-Stil und müssen der Kamel-Schreibweise folgen.

Positivbeispiel: localValue / getHttpMessage() / inputUserId
[Obligatorisch] Konstantennamen sollten ausschließlich in Großbuchstaben geschrieben werden und Wörter sollten durch Unterstriche getrennt werden mag lange Namen nicht.

Positivbeispiel: MAX_STOCK_COUNT

Gegenbeispiel: MAX_COUNT

6 Der Name der abstrakten Klasse beginnt mit „Abstract“ oder „Base“. Der Name der Testklasse wird nach dem Namen benannt, der getestet werden soll. Beginnt mit dem Namen der Klasse und endet mit Test.

7. [Obligatorisch] Eckige Klammern sind Teil des Array-Typs. Das Array ist wie folgt definiert: String[] args;


Gegenbeispiel: Verwenden Sie zum Definieren nicht String args[].
8. [Obligatorisch] Fügen Sie is nicht zu Variablen vom Typ Boolean in der POJO-Klasse hinzu, da sonst einige Framework-Analysen zu Serialisierungsfehlern führen.

Gegenbeispiel: Das als Basisdatentyp definierte Attribut isSuccess; seine Methode ist auch isSuccess(). Wenn das RPC-Framework eine umgekehrte Analyse durchführt, „denkt“ es, dass der entsprechende Attributname erfolgreich ist Das Attribut konnte nicht abgerufen werden, und es wird eine Ausnahme ausgelöst.
9. [Obligatorisch] Verwenden Sie Kleinbuchstaben in Paketnamen und es darf nur ein englisches Wort mit natürlicher Semantik zwischen Punkttrennzeichen stehen. Paketnamen verwenden immer die Singularform, aber wenn der Klassenname eine Pluralbedeutung hat, kann der Klassenname die Pluralform verwenden.

Positives Beispiel: Der Paketname des Anwendungstools lautet com.alibaba.open.util und der Klassenname lautet MessageUtils (diese Regel bezieht sich auf die Spring-Framework-Struktur)
10. Vollständig vermeiden Unregelmäßige Abkürzungen, um die Bedeutung des Textes nicht zu verkennen.

Gegenbeispiel: AbstractClass „Abkürzung“ heißt AbsClass; Bedingung „Abkürzung“ heißt condi. Eine solche willkürliche Abkürzung verringert die Lesbarkeit des Codes erheblich.
11. [Empfehlung] Wenn Entwurfsmuster verwendet werden, wird empfohlen, die spezifischen Muster im Klassennamen wiederzugeben.

Erläuterung: Die Widerspiegelung des Designmusters im Namen hilft den Lesern, die architektonischen Designideen schnell zu verstehen.

Positives Beispiel: öffentliche Klasse OrderFactory;

öffentliche Klasse ResourceObserver; Fügen Sie keine Modifikatoren hinzu (nicht einmal öffentlich), halten Sie den Code prägnant und Fügen Sie gültige Javadoc-Kommentare hinzu. Versuchen Sie, keine Variablen in der Schnittstelle zu definieren. Wenn Sie Variablen definieren müssen, müssen diese mit Schnittstellenmethoden in Zusammenhang stehen und grundlegende Konstanten für die gesamte Anwendung sein.

Positivbeispiel: Schnittstellenmethodensignatur: void f(); Basiskonstantendarstellung der Schnittstelle: String COMPANY = "alibaba"; Beschreibung : Schnittstellen in JDK8 ermöglichen Standardimplementierungen, daher ist diese Standardmethode eine wertvolle Standardimplementierung für alle Implementierungsklassen.

13. Es gibt zwei Regelsätze für die Benennung von Schnittstellen und Implementierungsklassen:

1) [Obligatorisch] Für Service- und DAO-Klassen müssen die bereitgestellten Dienste basierend auf dem SOA-Konzept Schnittstellen und intern sein Implementierungsklassen verwenden das Impl-Suffix, um sie von der Schnittstelle zu unterscheiden.

Positivbeispiel: CacheServiceImpl implementiert die CacheService-Schnittstelle.

2) [Empfehlung] Wenn es sich um einen Schnittstellennamen handelt, der Fähigkeiten beschreibt, verwenden Sie das entsprechende Adjektiv als Schnittstellennamen (normalerweise in der Form –able).


Positivbeispiel: AbstractTranslator implementiert Translatable.

14. [Referenz] Es wird empfohlen, dem Namen der Aufzählungsklasse das Suffix Enum hinzuzufügen. Die Namen der Aufzählungsmitglieder müssen in Großbuchstaben geschrieben und die Wörter durch Unterstriche getrennt werden.

Erläuterung: Aufzählungen sind eigentlich spezielle Konstantenklassen und der Konstruktor ist standardmäßig gezwungen, privat zu sein.

Positivbeispiel: Enumerationsname: DealStatusEnum, Mitgliedsname: SUCCESS / UNKOWN_REASON.

15. [Referenz] Namenskonvention für jede Schicht:

A) Namenskonvention für Service-/DAO-Schichtmethoden

1) Methoden zum Abrufen eines einzelnen Objekts werden mit dem Präfix „get“ versehen.

2) Den Methoden zum Abrufen mehrerer Objekte wird eine Liste vorangestellt.


3) Der Methode zum Erhalten statistischer Werte wird count vorangestellt.

4) Der Einfügemethode wird „Speichern“ (empfohlen) oder „Einfügen“ vorangestellt.

5) Der Löschmethode wird „remove“ (empfohlen) oder „delete“ vorangestellt.

6) Der Änderungsmethode wird „Update“ vorangestellt.

B) Namenskonvention für Domänenmodelle

1) Datenobjekt: xxxDO, xxx ist der Name der Datentabelle.

2) Datenübertragungsobjekt: xxxDTO, xxx ist der Name, der sich auf das Geschäftsfeld bezieht.

3) Anzeigeobjekt: xxxVO, xxx ist im Allgemeinen der Name der Webseite.

4) POJO ist der Sammelname von DO/DTO/BO/VO und es ist verboten, es als xxxPOJO zu bezeichnen.

(2) Konstantendefinition

1 [Obligatorisch] Es dürfen keine magischen Werte (d. h. undefinierte Konstanten) direkt im Code erscheinen.

Zählerbeispiel: String key="Id#taobao_"+tradeId;

 cache.put(key, value);
2. [Obligatorisch] Wenn long oder Long anfänglich zugewiesen wird , es muss ein großes L und kein kleines l verwendet werden. Kleinbuchstaben können leicht mit der Zahl 1 verwechselt werden, was zu Missverständnissen führt.

Erläuterung: Long a = 2l; Ist es eine numerische 21 oder ein Long-Typ 2? [Empfehlung] Verwenden Sie keine Konstantenklasse, um alle Konstanten zu verwalten ihre Funktionen werden separat gepflegt. Beispiel: Cache-bezogene Konstanten werden unter der Klasse „CacheConsts“ platziert; Systemkonfigurations-bezogene Konstanten werden unter der Klasse „ConfigConsts“ platziert.

Hinweis: Bei einer großen und umfassenden Konstantenklasse müssen Sie die Suchfunktion verwenden, um die geänderte Konstante zu finden, was dem Verständnis und der Wartung nicht förderlich ist.

4. [Empfohlen] Es gibt fünf Ebenen der Wiederverwendung von Konstanten: gemeinsam genutzte Konstanten in Anwendungen, gemeinsam genutzte Konstanten innerhalb von Anwendungen, gemeinsam genutzte Konstanten innerhalb von Unterprojekten, gemeinsam genutzte Konstanten innerhalb von Paketen und gemeinsam genutzte Konstanten innerhalb von Klassen.

1) Anwendungsübergreifende gemeinsam genutzte Konstanten: in einer Bibliothek eines Drittanbieters platziert, normalerweise im Konstantenverzeichnis in client.jar.

2) In der Anwendung gemeinsam genutzte Konstanten: im Konstantenverzeichnis in den Modulen der Bibliothek platziert.

Gegenbeispiel: Leicht verständliche Variablen müssen innerhalb der Anwendung auch einheitlich als gemeinsame Konstanten definiert werden. Zwei Belagerungsmeister haben Variablen definiert, die „Ja“ in zwei Klassen darstellen:

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

   In Klasse B: public static final String YES = "y" (B.YES), der erwartete Wert ist wahr, aber der tatsächliche return ist falsch und verursacht Online-Probleme.

 3) Gemeinsame Konstanten innerhalb des Unterprojekts: das heißt im Konstantenverzeichnis des aktuellen Unterprojekts.

 4) Gemeinsame Konstanten innerhalb des Pakets: das heißt, in einem separaten Konstantenverzeichnis unter dem aktuellen Paket.

 5) Gemeinsame Konstanten innerhalb der Klasse: private statische endgültige Definition direkt innerhalb der Klasse.

5. [Empfohlen] Wenn sich der Variablenwert nur innerhalb eines Bereichs ändert, verwenden Sie die Enum-Klasse. Wenn andere erweiterte Attribute als Namen vorhanden sind, muss die Enum-Klasse verwendet werden. Die Zahlen im folgenden Beispiel sind erweiterte Informationen, die den Wochentag angeben.

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

(3) Formatkonventionen

1. [Obligatorisch] Konvention zur Verwendung von geschweiften Klammern. Wenn die geschweiften Klammern leer sind, schreiben Sie einfach {} ohne Zeilenumbrüche; wenn es sich um einen nicht leeren Codeblock handelt:

1) Vor der linken Klammer steht kein Zeilenumbruch.

 2) Zeilenumbruch nach der linken geschweiften Klammer.

 3) Zeilenumbruch vor der rechten Klammer.

4) Wenn nach der rechten Klammer ein else-Code steht, wird dieser nicht umbrochen, was bedeutet, dass er nach der Beendigung der rechten Klammer umgebrochen werden muss.

2. [Obligatorisch] Es gibt kein Leerzeichen zwischen der linken Klammer und dem folgenden Zeichen. Ebenso gibt es kein Leerzeichen zwischen der rechten Klammer und dem vorherigen Zeichen. Einzelheiten finden Sie in den richtigen Beispieltipps unter Artikel 5.
3. [Obligatorisch] Zwischen reservierten Wörtern wie if/for/while/switch/do und den linken und rechten Klammern müssen Leerzeichen eingefügt werden.
4. [Obligatorisch] Um jeden Operator muss ein Leerzeichen vorhanden sein.

Erläuterung: Zu den Operatoren gehören der Zuweisungsoperator =, der logische Operator &&, Additions-, Subtraktions-, Multiplikations- und Divisionssymbole, ternäre Operatoren usw.

5. [Obligatorisch] Verwenden Sie 4 Leerzeichen zum Einrücken und Tabulatorzeichen sind verboten.
Hinweis: Wenn Sie die Tab-Einrückung verwenden, müssen Sie den Einzug festlegen, Sie müssen den Einzug festlegen, Sie müssen den Einzug festlegen, Sie müssen den Einzug festlegen, Sie müssen den Einzug festlegen, Sie müssen 1 Tabulator auf 4 Leerzeichen festlegen. Wenn IDEA Tabulatoren auf 4 Leerzeichen festlegt, aktivieren Sie nicht die Option „Tabulatorzeichen verwenden“. In Eclipse müssen Sie „Leerzeichen für Tabulatoren einfügen“ aktivieren.
Positives Beispiel: (betrifft Punkte 1-5)

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();


Hinweis: Wenn eine Ausrichtung erforderlich ist, fügen Sie ein paar Leerzeichen zu a, b und c hinzu. Wenn es viele Variablen gibt, ist dies eine umständliche Sache.
10. [Empfohlen] Fügen Sie eine Leerzeile zwischen der Ausführungsanweisungsgruppe, der Variablendefinitionsanweisungsgruppe, der unterschiedlichen Geschäftslogik oder der unterschiedlichen Semantik in den Methodenkörper ein. Zwischen derselben Geschäftslogik und Semantik müssen keine Leerzeilen eingefügt werden.

Hinweis: Es ist nicht erforderlich, mehrere Zeilen mit Leerzeichen zur Trennung einzufügen.

(4) OOP-Spezifikation

1. Vermeiden Sie den Zugriff auf statische Variablen oder statische Methoden dieser Klasse über Objektreferenzen einer Klasse, da dies die Kosten für die Compiler-Analyse unnötig erhöht der Klassenname direkt Kommen Sie einfach vorbei.
2. [Obligatorisch] Alle Override-Methoden müssen mit @Override annotiert werden.

Gegenbeispiel: das Problem von getObject() und get0object(). Einer ist der Buchstabe O und der andere ist die Zahl 0. Durch Hinzufügen von @Override kann genau bestimmt werden, ob die Überschreibung erfolgreich ist. Wenn außerdem die Methodensignatur in einer abstrakten Klasse geändert wird, wird deren Implementierungsklasse sofort kompiliert und meldet einen Fehler.
3. [Obligatorisch] Java-Variablenparameter können nur verwendet werden, wenn sie denselben Parametertyp und dieselbe geschäftliche Bedeutung haben. Vermeiden Sie die Verwendung von Objekten.

 Hinweis: Variable Parameter müssen am Ende der Parameterliste platziert werden. (Studenten werden aufgefordert, die Programmierung mit variablen Parametern so weit wie möglich zu vermeiden)

Positives Beispiel: public User getUsers(String type, Integer... ids)
[Pflichtig] Im Prinzip die Signatur von Die nach außen zugängliche Schnittstelle ist nicht zulässig. Ermöglicht die Änderung von Methodensignaturen, um Auswirkungen auf Schnittstellenaufrufer zu vermeiden. Wenn die Schnittstelle veraltet ist, muss die Annotation @Deprecated hinzugefügt werden und die neue Schnittstelle oder der neue Dienst muss klar angegeben werden.
5. [Obligatorisch] Veraltete Klassen oder Methoden können nicht verwendet werden.

Erklärung: Die Methode decode(String encodeStr) in java.net.URLDecoder ist veraltet. Die zwei Parameter decode(String source, String encode) sollten verwendet werden. Da der Schnittstellenanbieter eindeutig eine veraltete Schnittstelle ist, ist er verpflichtet, gleichzeitig als Aufrufer eine neue Schnittstelle bereitzustellen und die neue Implementierung der veralteten Methode zu überprüfen.
6. [Obligatorisch] Die Methode „equals“ von Object kann eine Nullzeigerausnahme auslösen. Sie sollten eine Konstante oder ein Objekt mit einem bestimmten Wert verwenden, um „equals“ aufzurufen.

Positivbeispiel: "test".equals(object); Gegenbeispiel: object.equals("test");

Hinweis: Es wird empfohlen, java.util.Objects#equals ( eingeführt durch die JDK7-Tool-Klasse)
7. [Obligatorisch] Verwenden Sie die Methode equal, um Werte zwischen allen Paketklassenobjekten desselben Typs zu vergleichen.

Erklärung: Für eine Integer-Var=?-Zuweisung zwischen -128 und 127 wird das Integer-Objekt in IntegerCache.cache generiert und vorhandene Integer-Werte in diesem Bereich können direkt verwendet werden == Make eine Beurteilung, aber alle Daten außerhalb dieses Bereichs werden auf dem Heap generiert und vorhandene Objekte werden nicht wiederverwendet. Dies ist eine große Gefahr. Es wird empfohlen, die Gleichheitsmethode zur Beurteilung zu verwenden.
8. [Obligatorisch] Die Verwendungsstandards für Basisdatentypen und gepackte Datentypen sind wie folgt:

 1) Alle POJO-Klassenattribute müssen gepackte Datentypen verwenden.

 2) Der Rückgabewert und die Parameter von RPC-Methoden müssen umschlossene Datentypen verwenden.

 3) Alle lokalen Variablen [empfohlen] verwenden grundlegende Datentypen.

Erläuterung: Das POJO-Klassenattribut hat keinen Anfangswert, um Benutzer daran zu erinnern, dass sie den Wert explizit selbst zuweisen müssen, wenn sie ihn verwenden müssen. Alle NPE-Probleme oder Lagerprüfungen werden vom Benutzer sichergestellt. Positives Beispiel: Das Abfrageergebnis der Datenbank kann null sein, da beim automatischen Entpacken und Empfangen mit Basisdatentypen NPE-Risiken bestehen.

Gegenbeispiel: Zeigen Sie beispielsweise den Anstieg und Abfall des gesamten Transaktionsvolumens an, dh plus oder minus x %, x ist der Basisdatentyp und der aufgerufene RPC-Dienst. Der Standardwert wird zurückgegeben und auf der Seite wird Folgendes angezeigt: 0 %. Dies ist unangemessen und sollte als Bindestrich angezeigt werden. Daher kann der Nullwert des umschlossenen Datentyps zusätzliche Informationen darstellen, z. B.: Remote-Aufruffehler und abnormaler Ausgang.
9. [Obligatorisch] Legen Sie beim Definieren von POJO-Klassen wie DO/DTO/VO keine Attributstandardwerte fest.

Gegenbeispiel: Der Standardwert von gmtCreate der POJO-Klasse ist new Date(); dieses Attribut hat jedoch beim Extrahieren von Daten keinen spezifischen Wert und dieses Feld wird aktualisiert, wenn andere Felder aktualisiert werden, was dazu führt Die Erstellungszeit soll auf die aktuelle Zeit geändert werden.
10. [Obligatorisch] Ändern Sie beim Hinzufügen neuer Attribute zur Serialisierungsklasse bitte nicht das Feld „serialVersionUID“, um einen Deserialisierungsfehler zu vermeiden. Wenn es mit Upgrades völlig inkompatibel ist, ändern Sie bitte den Wert „serialVersionUID“.

Hinweis: Beachten Sie, dass eine inkonsistente serialVersionUID eine Serialisierungslaufzeitausnahme auslöst.
11. [Obligatorisch] Es ist verboten, der Konstruktionsmethode Geschäftslogik hinzuzufügen. Wenn eine Initialisierungslogik vorhanden ist, fügen Sie diese bitte in die Init-Methode ein.
12. [Obligatorisch] Die POJO-Klasse muss die toString-Methode schreiben. Wenn Sie das IDE-Tool: Quelle> toString generieren verwenden und eine andere POJO-Klasse erben, müssen Sie unbedingt super.toString voranstellen.

  说明:在方法执行抛出异常时,可以直接调用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. [Referenz] Volatile löst das Problem des unsichtbaren Speichers in Multithreads. Bei einem Schreibvorgang und vielen Lesevorgängen kann das Problem der Variablensynchronisierung gelöst werden. Bei vielen Schreibvorgängen kann das Thread-Sicherheitsproblem jedoch nicht gelöst werden. Wenn es sich um eine count++-Operation handelt, verwenden Sie die folgende Klasse, um sie zu implementieren: AtomicInteger count = new AtomicInteger(); count.addAndGet(1); Wenn es sich um JDK8 handelt, wird die Verwendung des LongAdder-Objekts empfohlen, das eine bessere Leistung als AtomicLong bietet (Reduziert die Anzahl optimistischer Sperrwiederholungen).

14. [Referenz] Wenn die Kapazität von HashMap für die Größenänderung nicht ausreicht, kann es aufgrund der hohen Parallelität zu toten Links kommen, was zu einem Anstieg der CPU führt. Achten Sie darauf, dieses Risiko während des Entwicklungsprozesses zu vermeiden.
15. [Referenz] ThreadLocal kann das Aktualisierungsproblem gemeinsam genutzter Objekte nicht lösen. Es wird empfohlen, statische Modifikationen für ThreadLocal-Objekte zu verwenden. Diese Variable ist allen Vorgängen innerhalb eines Threads gemeinsam und wird daher als statische Variable festgelegt. Alle diese Instanzen teilen sich diese statische Variable, was bedeutet, dass sie bei der ersten Verwendung der Klasse geladen wird und nur einen Teil des Speichers enthält Objekte (sofern sie in diesem Thread definiert sind) können diese Variable manipulieren.

(7) Steueranweisungen

1 [Obligatorisch] Innerhalb eines Switch-Blocks sollte jeder Fall entweder durch Pause/Rückgabe usw. beendet werden, oder durch einen Kommentar, der angibt, welche das Programm tun wird Führen Sie den Fall weiter aus. Innerhalb eines Switch-Blocks muss eine Standardanweisung eingefügt und am Ende platziert werden, auch wenn sie keinen Code enthält.
2. [Obligatorisch] Klammern müssen in if/else/for/while/do-Anweisungen verwendet werden, auch wenn nur eine Codezeile vorhanden ist. Vermeiden Sie die Verwendung der folgenden Formen: if (condition)-Anweisungen; . [Empfohlen] Es wird empfohlen, else so wenig wie möglich zu verwenden. Die if-else-Methode kann wie folgt umgeschrieben werden:
if(condition){
...
return obj;
}
// Dann schreibe den else-Geschäftslogikcode.
Beschreibung: Wenn Sie if()...else if()...else... verwenden müssen, um Logik auszudrücken, darf [Obligatorisch] 3 nicht überschreiten Wenn es mehr als 3 Ebenen gibt, verwenden Sie bitte das staatliche Entwurfsmuster.
Positivbeispiel: If-else-Code mit mehr als 3 Logikebenen kann mithilfe von Guard-Anweisungen oder Zustandsmustern implementiert werden.
4. [Empfohlen] Führen Sie mit Ausnahme allgemeiner Methoden (z. B. getXxx/isXxx) keine anderen komplexen Anweisungen in bedingten Urteilen aus und weisen Sie die Ergebnisse komplexer logischer Urteile einem aussagekräftigen booleschen Variablennamen zu, um die Zuverlässigkeit zu verbessern.

Erklärung: Die Logik in vielen if-Anweisungen ist recht komplex. Der Leser muss das Endergebnis des bedingten Ausdrucks analysieren, um zu klären, welche Bedingungen welche Anweisungen ausführen. Wenn der Leser den logischen Ausdruck dann falsch analysiert?

Positivbeispiel:

//Pseudocode lautet wie folgt
boolean existed = (file.open(fileName, "w") != null) && (...) || (. .. );
 if (existed) {
  ...
  }
 Gegenbeispiel:
 if ((file.open(fileName, "w") != null) && ( ... ) ||. (...)) {
   ...
  }
5. Die Anweisungen im Schleifenkörper sollten die Leistung berücksichtigen so viel wie möglich, wie zum Beispiel das Definieren von Objekten und Variablen, das Erhalten von Datenbankverbindungen und das Durchführen unnötiger Try-Catch-Vorgänge (kann dieser Try-Catch aus der Schleife verschoben werden)?
6. [Empfohlen] Schnittstellen-Eingabeparameterschutz Dieses Szenario tritt häufig bei Schnittstellen auf, die für Batch-Vorgänge verwendet werden.
7. [Referenz] Szenarien, in denen eine Parameterüberprüfung in Methoden erforderlich ist:

 1) Methoden, die weniger häufig aufgerufen werden.

 2) Bei einer Methode, die viel Ausführungszeit erfordert, ist die Parameterüberprüfungszeit nahezu vernachlässigbar. Wenn die Zwischenausführung jedoch zurückgesetzt wird oder aufgrund von Parameterfehlern ein Fehler auftritt, überwiegt der Gewinn den Verlust.

 3) Eine Methode, die eine extrem hohe Stabilität und Verfügbarkeit erfordert.

 4) Die offene Schnittstelle, die der Außenwelt zur Verfügung gestellt wird, unabhängig davon, ob es sich um eine RPC/API/HTTP-Schnittstelle handelt.

 5) Zugang zu sensiblen Berechtigungen.
8. [Referenz] Szenarien, in denen in Methoden keine Parameterüberprüfung erforderlich ist:

 1) Es wird nicht empfohlen, Parameter für Methoden zu überprüfen, die sehr wahrscheinlich zyklisch aufgerufen werden. Allerdings muss in der Methodenbeschreibung auf die Prüfung externer Parameter hingewiesen werden.

 2) Die zugrunde liegenden Methoden werden häufig aufgerufen und im Allgemeinen nicht überprüft. Schließlich handelt es sich um den letzten Schritt der reinen Wasserfiltration, und es ist unwahrscheinlich, dass Parameterfehler Probleme bis zur untersten Schicht aufdecken. Im Allgemeinen befinden sich die DAO-Schicht und die Serviceschicht in derselben Anwendung und werden auf demselben Server bereitgestellt, sodass die Überprüfung der DAO-Parameter weggelassen werden kann.

 3) Eine als privat deklarierte Methode wird nur von Ihrem eigenen Code aufgerufen, wenn Sie sicher sein können, dass die vom Code, der die Methode aufruft, übergebenen Parameter überprüft wurden oder definitiv keine Probleme vorliegen, tun Sie dies Die Parameter müssen zu diesem Zeitpunkt nicht überprüft werden.

(8) Kommentarkonvention

1 [Obligatorisch] Kommentare zu Klassen, Klassenattributen und Klassenmethoden müssen Javadoc-Spezifikationen im /**Inhalt*/-Format verwenden und müssen Verwenden Sie den / /xxx-Modus nicht.

Hinweis: Im IDE-Bearbeitungsfenster fordert der Javadoc-Modus relevante Kommentare an, und das generierte Javadoc kann die entsprechenden Kommentare in der IDE korrekt ausgeben, wenn das Projekt eine Methode, die Methode, Parameter usw. aufruft Rückgaben können ohne Eingabe des Methodenwerts ausgesetzt werden und die Leseeffizienz verbessern.

2. [Obligatorisch] Alle abstrakten Methoden (einschließlich Methoden in Schnittstellen) müssen mit Javadoc versehen sein. Zusätzlich zu den Rückgabewerten, Parametern und Ausnahmebeschreibungen muss auch angegeben werden, was die Methode tut und welche Funktionen sie implementiert.

Hinweis: Bitte erläutern Sie die Implementierungsanforderungen für Unterklassen oder Aufrufvorkehrungen.
3. [Obligatorisch] Alle Klassen müssen Erstellerinformationen hinzufügen.
4. [Obligatorisch] Einzeilige Kommentare innerhalb der Methode, beginnen Sie eine neue Zeile über der kommentierten Anweisung und verwenden Sie // Kommentar. Verwenden Sie /* */-Kommentare für mehrzeilige Kommentare innerhalb von Methoden und achten Sie darauf, diese am Code auszurichten.
5. [Obligatorisch] Alle Felder des Aufzählungstyps müssen Kommentare enthalten, um den Zweck jedes Datenelements zu erläutern.
6. [Empfehlung] Anstatt in halbherzigem Englisch zu kommentieren, ist es besser, chinesische Kommentare zu verwenden, um das Problem klar zu erklären. Eigennamen und Schlüsselwörter können im englischen Originaltext verbleiben.

Gegenbeispiel: „TCP-Verbindungszeitüberschreitung“ wird als „Transmission Control Protocol-Verbindungszeitüberschreitung“ interpretiert, was schwieriger zu verstehen ist.
7. [Empfohlen] Beim Ändern des Codes sollten auch Kommentare entsprechend geändert werden, insbesondere Änderungen an Parametern, Rückgabewerten, Ausnahmen, Kernlogik usw.

Hinweis: Code- und Anmerkungsaktualisierungen sind nicht synchron, ebenso wie Aktualisierungen des Straßennetzes und der Navigationssoftware. Wenn die Navigationssoftware ernsthaft hinterherhinkt, geht die Bedeutung der Navigation verloren.
8. [Referenz] Der auskommentierte Code sollte so weit wie möglich mit der Beschreibung übereinstimmen und nicht einfach auskommentiert sein.

Hinweis: Für das Auskommentieren des Codes gibt es zwei Möglichkeiten:

1) Die Logik dieses Codes wird später wiederhergestellt.

2) Benutzen Sie es niemals. Wenn im ersteren keine Anmerkungsinformationen vorhanden sind, ist es schwierig, die Motivation der Anmerkung zu ermitteln. Letzteres sollte direkt gelöscht werden (das Code-Repository speichert historischen Code).
9. [Referenz] Anforderungen an Kommentare:

Erstens können sie die Designideen und die Codelogik genau wiedergeben.

Zweitens können sie die Geschäftsbedeutung so beschreiben, dass andere Programmierer dies tun können Kann die Informationen hinter dem Code schnell verstehen. Ein großer Codeblock ohne Kommentare ist für den Leser wie ein heiliges Buch, damit Sie die Gedanken zu diesem Zeitpunkt auch nach langer Zeit klar verstehen können , damit sie Ihre Arbeit schnell übernehmen können.
10. [Referenz] Gute Benennung und Codestruktur sind selbsterklärend und Kommentare sollten prägnant, genau und ausdrucksstark sein. Vermeiden Sie ein Extrem von Kommentaren: zu viele und übermäßige Kommentare. Sobald die Logik des Codes geändert wird, wird das Ändern der Kommentare eine erhebliche Belastung darstellen.

Gegenbeispiel:
// Elefant in den Kühlschrank legen
put(elephant, kühlschrank);
Der Methodenname put sowie zwei aussagekräftige Variablennamenelefant und Brücke wurden erklärt. Was das ist Der Vorteil besteht darin, dass semantisch klarer Code keine zusätzlichen Kommentare erfordert.
11. [Referenz] Besondere Kommentarmarkierung, bitte geben Sie die Person an, die sie markiert hat, und den Zeitpunkt der Markierung. Achten Sie darauf, diese Markierungen rechtzeitig zu beseitigen und entfernen Sie sie regelmäßig durch Markierungsscannen. Online-Fehler entstehen manchmal durch den Code an diesen Markierungen.

 1) Aufgaben (TODO): (Person markieren, Zeit markieren, [geschätzte Bearbeitungszeit]) Zeigt Funktionen an, die implementiert werden müssen, aber noch nicht implementiert wurden. Dies ist eigentlich ein Javadoc-Tag. Das aktuelle Javadoc wurde noch nicht implementiert, wurde aber häufig verwendet. Kann nur auf Klassen, Schnittstellen und Methoden angewendet werden (da es sich um ein Javadoc-Tag handelt). 2) Fehler, kann nicht funktionieren (FIXME): (Person markieren, Zeit markieren, [geschätzte Bearbeitungszeit]) Verwenden Sie FIXME in den Kommentaren, um zu markieren, dass ein bestimmter Code falsch ist, nicht funktionieren kann und rechtzeitig korrigiert werden muss.

(9) Andere

1. [Obligatorisch] Nutzen Sie bei der Verwendung regulärer Ausdrücke die Vorkompilierungsfunktion, um den Abgleich regulärer Ausdrücke effektiv zu beschleunigen.

Hinweis: Definieren Sie es nicht im Methodenkörper: Pattern pattern = Pattern.compile (rule);
2. Wenn Velocity die Attribute der POJO-Klasse aufruft, wird empfohlen, dies direkt zu tun Verwenden Sie den Attributnamen, um den Wert abzurufen. Die Vorlagen-Engine ruft automatisch getXxx() gemäß der Spezifikation auf. Wenn es sich um eine boolesche Basisdatentypvariable handelt (dem booleschen Namen muss kein is vorangestellt werden), wird isXxx( )-Methode wird automatisch aufgerufen.

Hinweis: Beachten Sie, dass, wenn es sich um ein boolesches Wrapper-Klassenobjekt handelt, zuerst die Methode getXxx() aufgerufen wird.
3. [Obligatorisch] Die im Hintergrund an die Seite gesendeten Variablen müssen mit $!{var} hinzugefügt werden – einem Ausrufezeichen in der Mitte.

Erläuterung: Wenn var=null oder nicht vorhanden ist, wird ${var} direkt auf der Seite angezeigt.
4. [Obligatorisch] Beachten Sie, dass der Wertebereich 0 ≤ ist. Vergrößern Sie x nicht um das Mehrfache 10 und runden Sie es dann ab Methode des Random-Objekts direkt.
5. [Obligatorisch] Ermitteln Sie die aktuelle Anzahl von Millisekunden. System.currentTimeMillis(); anstelle von new Date().getTime();

Hinweis: Wenn Sie einen genaueren Nanosekunden-Zeitwert erhalten möchten , verwenden Sie System.nanoTime(). In JDK8 wird empfohlen, die Instant-Klasse für Szenarien wie die statistische Zeit zu verwenden.
6. [Empfohlen] Versuchen Sie, der VM keine Variablendeklarationen und logischen Operatoren hinzuzufügen, geschweige denn der VM-Vorlage komplexe Logik hinzuzufügen.
7. [Empfehlung] Die Größe sollte beim Erstellen oder Initialisieren einer Datenstruktur angegeben werden, um ein unbegrenztes Wachstum der Datenstruktur und einen Speicherverbrauch zu vermeiden.
8. [Empfehlung] „Code und Konfigurationen, die eindeutig nicht verwendet werden“, wie z. B. Methoden, Variablen, Klassen, Konfigurationsdateien, dynamische Konfigurationsattribute usw., müssen unbedingt aus dem Programm entfernt werden, um sie zu vermeiden verursacht zu viel Müll.

2. Ausnahmeprotokoll

(1) Ausnahmebehandlung

1. Erfassen Sie keine Laufzeitausnahmeklassen, die in der Java-Klassenbibliothek definiert sind, wie zum Beispiel: IndexOutOfBoundsException /NullPointerException, diese Art von Ausnahme wird durch die Vorabprüfung des Programmierers vermieden, um die Robustheit des Programms sicherzustellen.

Positivbeispiel: if(obj != null) {...}

Gegenbeispiel: try { obj.method() } Catch(NullPointerException e){...}
2. [Obligatorisch] Verwenden Sie keine Ausnahmen zur Prozesssteuerung oder bedingten Steuerung, da die Verarbeitungseffizienz von Ausnahmen geringer ist als die von bedingten Verzweigungen.
3. [Obligatorisch] Versuchen Sie, einen großen Codeabschnitt abzufangen, was unverantwortlich ist. Bitte unterscheiden Sie beim Abfangen zwischen stabilem Code und instabilem Code. Um instabilen Code abzufangen, versuchen Sie, den Ausnahmetyp so weit wie möglich zu unterscheiden, und behandeln Sie dann die entsprechende Ausnahme.
[Obligatorisch] Fangen Sie eine Ausnahme ab, um sie zu behandeln, und verwerfen Sie sie nicht, ohne sie zu verarbeiten. Bitte werfen Sie die Ausnahme an den Aufrufer. Der äußerste Geschäftsbenutzer muss Ausnahmen behandeln und sie in Inhalte umwandeln, die Benutzer verstehen können.
5. [Obligatorisch] Platzieren Sie den Try-Block im Transaktionscode. Wenn Sie die Transaktion zurücksetzen müssen, müssen Sie darauf achten, die Transaktion manuell zurückzusetzen.
6. [Obligatorisch] Der „finally“-Block muss das Ressourcenobjekt und das Stream-Objekt schließen und einen Try-Catch durchführen, wenn eine Ausnahme vorliegt.

Hinweis: Bei JDK7 können Sie die Try-with-Resources-Methode verwenden.
7. [Obligatorisch] Return kann nicht im „final“-Block verwendet werden. Nachdem die „return“-Anweisung im „final“-Block zurückgegeben wurde, wird die Ausführung der Methode beendet und die „return“-Anweisung im „try“-Block wird nicht ausgeführt.
8. [Obligatorisch] Abfangende Ausnahmen und auslösende Ausnahmen müssen genau übereinstimmen, oder die abfangende Ausnahme muss die übergeordnete Klasse der auslösenden Ausnahme sein.

Erläuterung: Wenn erwartet wird, dass der Gegner einen Hortensienball wirft, er aber tatsächlich einen Kugelstoß erhält, kommt es zu einer unerwarteten Situation.
9. Der Rückgabewert der Methode kann null sein. Es ist nicht zwingend erforderlich, eine leere Sammlung oder ein leeres Objekt zurückzugeben. Es müssen Kommentare hinzugefügt werden, um vollständig zu erklären, unter welchen Umständen ein Nullwert zurückgegeben wird. Der Anrufer muss eine Nullbeurteilung durchführen, um NPE-Probleme zu vermeiden.

Hinweis: In dieser Spezifikation heißt es eindeutig, dass die Verhinderung von NPE in der Verantwortung des Anrufers liegt. Selbst wenn die aufgerufene Methode eine leere Sammlung oder ein leeres Objekt zurückgibt, ist dies für den Aufrufer keine sorgenfreie Situation. Er muss die Situation berücksichtigen, in der in Szenarien wie einem Remote-Aufruffehler, einer Laufzeitausnahme usw. Null zurückgegeben wird.
10. [Empfehlung] Die Verhinderung von NPE ist die Grundausbildung von Programmierern. Achten Sie auf die Szenarien, in denen NPE auftritt:

1) Der Rückgabetyp ist ein gepackter Datentyp, der möglicherweise null ist zur Beurteilung, wenn ein int-Wert null zurückgegeben wird.

Gegenbeispiel: public int f(){ return Integer object}; Wenn es null ist, wird es automatisch entpackt und NPE ausgelöst.

 2) Das Abfrageergebnis der Datenbank kann null sein.

 3) Auch wenn das Element in der Sammlung NotEmpty ist, kann das abgerufene Datenelement null sein.
4) Für Objekte, die von Remote-Aufrufen zurückgegeben werden, ist eine NPE-Beurteilung erforderlich.

 5) Für die in Session erhaltenen Daten wird empfohlen, NPE zu überprüfen, um Nullzeiger zu vermeiden.

6) Kaskadierende Aufrufe von obj.getA().getB().getC(); eine Reihe von Aufrufen kann leicht NPE verursachen.
11. [Empfehlung] Ob im Code „Ausnahme auslösen“ oder „Fehlercode zurückgeben“ verwendet werden soll. Für offene http/api-Schnittstellen muss innerhalb der Anwendung „Ausnahme“ verwendet werden empfohlen; anwendungsübergreifend wird der Verwendung der Result-Methode für RPC-Aufrufe Vorrang eingeräumt, wobei isSuccess, „Fehlercode“ und „Fehlerkurzinformationen“ gekapselt werden. Hinweis: Gründe für die Verwendung der Result-Methode für die RPC-Methodenrückgabe:

 1) Bei Verwendung der Ausnahmerückgabemethode tritt ein Laufzeitfehler auf, wenn der Aufrufer ihn nicht abfängt.

2) Wenn Sie keine Stack-Informationen, sondern nur neue benutzerdefinierte Ausnahmen hinzufügen und Ihr eigenes Verständnis der Fehlermeldung hinzufügen, wird dies dem aufrufenden Ende bei der Lösung des Problems nicht viel helfen. Wenn Stack-Informationen hinzugefügt werden, ist bei häufigen Aufruffehlern auch der Leistungsverlust der Datenserialisierung und -übertragung ein Problem.
12. [Empfohlen] Vermeiden Sie beim Definieren ungeprüfter/geprüfter Ausnahmen die Verwendung von RuntimeException zum direkten Auslösen, und es ist nicht zulässig, Ausnahmen auszulösen oder benutzerdefinierte Ausnahmen mit geschäftlicher Bedeutung zu verwenden. Wir empfehlen benutzerdefinierte Ausnahmen, die in der Branche definiert wurden, wie zum Beispiel: DAOException / ServiceException usw.
13. [Referenz] Vermeiden Sie doppelten Code (Don't Repeat Yourself), das heißt das DRY-Prinzip. Hinweis: Das beliebige Kopieren und Einfügen von Code führt unweigerlich zu einer Duplizierung des Codes. Wenn in Zukunft Änderungen erforderlich sind, müssen alle Kopien geändert werden, was leicht zu übersehen ist. Extrahieren Sie bei Bedarf allgemeine Methoden, abstrakte öffentliche Klassen oder sogar gemeinsam genutzte Module.

Positives Beispiel: Es gibt mehrere öffentliche Methoden in einer Klasse, und alle müssen mehrere Zeilen derselben Parameterüberprüfungsoperation ausführen. Bitte extrahieren Sie zu diesem Zeitpunkt:
private boolean checkParam(DTO dto) {...}

(2) Protokollprotokoll

1. [Obligatorisch] Die Anwendung kann die API im Protokollsystem (Log4j, Logback) nicht direkt verwenden, sondern sollte sich auf die API im Protokollframework SLF4J verlassen und die verwenden Der Fassadenmodus erleichtert die Wartung und Vereinheitlichung der Protokollverarbeitungsmethoden für jede Kategorie.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 private static final Logger logger = LoggerFactory.getLogger(Abc.class);
2. [Obligatorisch] Die Protokolldatei ist Es wird empfohlen, mindestens 15 Tage lang zu speichern, da einige Anomalien die Eigenschaft haben, mit einer Häufigkeit von „Wochen“ aufzutreten.
3. [Obligatorisch] Benennungsmethode für erweiterte Protokolle in Anwendungen (z. B. Verwaltung, temporäre Überwachung, Zugriffsprotokolle usw.): appName_logType_logName.log. logType: Protokolltyp, empfohlene Kategorien umfassen stats/desc/monitor/visit usw.; logName: Protokollbeschreibung. Der Vorteil dieser Art der Benennung: Anhand des Dateinamens können Sie erkennen, zu welcher Anwendung die Protokolldatei gehört, welchen Typ und welchen Zweck sie hat, was auch bei der Klassifizierung und Suche hilfreich ist.

Positives Beispiel: Ausnahmen zur Zeitzonenkonvertierung in der mppserver-Anwendung separat überwachen, z. B.: mppserver_monitor_timeZoneConvert.log Hinweis: Es wird empfohlen, Protokolle so weit wie möglich getrennt zu klassifizieren und Geschäftsprotokolle zu speichern ist für Entwickler praktisch, um die Protokolle anzuzeigen und die Überprüfung zu erleichtern. Das System führt eine zeitnahe Überwachung durch.
4. [Obligatorisch] Für die Protokollausgabe auf Trace-/Debug-/Info-Ebene müssen Sie ein bedingtes Ausgabeformular verwenden oder Platzhalter verwenden.

Beschreibung: logger.debug("Verarbeitung des Handels mit der ID: " + id + " symbol: " + symbol); Wenn die Protokollebene „Warnung“ lautet, wird das obige Protokoll nicht gedruckt, sondern der String-Splicing-Vorgang Wenn das Symbol ein Objekt ist, wird die Methode toString() ausgeführt, wodurch Systemressourcen verschwendet werden. Nach der Ausführung der oben genannten Vorgänge wird das endgültige Protokoll nicht gedruckt.

Positivbeispiel: (Bedingung)
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
 }
 Positivbeispiel: (Platzhalter)
 logger.debug("Verarbeitung von Handel mit ID: {} Symbol: {} ", ID, Symbol);
5 Protokolle erstellen und Speicherplatz verschwenden, stellen Sie sicher, dass Sie in log4j.xml additivity=false festlegen.

Positivbeispiel:
6. Ungewöhnliche Informationen sollten zwei Arten von Informationen umfassen: Informationen zum Tatort und Ausnahme-Stack-Informationen. Wenn nicht, werfen Sie es hoch.

Positivbeispiel: logger.error(verschiedene Parameter oder Objekte toString + „_“ + e.getMessage(), e);
7. Sie können die Warnprotokollebene verwenden, um Benutzer aufzuzeichnen Eingabe Bei Parameterfehlern ist der Anwender nicht mehr an der Möglichkeit, Reklamationen zu vermeiden. Achten Sie auf die Ebene der Protokollausgabe. Die Fehlerebene erfasst nur wichtige Fehlerinformationen wie Systemlogikfehler und Ausnahmen. Wenn dies nicht erforderlich ist, geben Sie in diesem Szenario bitte keine Fehlerstufe ein.
8. [Empfohlen] Protokolle sorgfältig aufzeichnen. Es ist verboten, Debug-Protokolle in der Produktionsumgebung auszugeben. Wenn Sie Warnungen zum ersten Mal zum Aufzeichnen von Geschäftsverhaltensinformationen verwenden, müssen Sie auf die Menge der Protokollausgabe achten, um ein Platzen der Serverfestplatte zu vermeiden Denken Sie daran, diese Beobachtungsprotokolle rechtzeitig zu löschen.

Hinweis: Die Ausgabe einer großen Anzahl ungültiger Protokolle trägt nicht zur Verbesserung der Systemleistung bei und trägt nicht dazu bei, Fehlerstellen schnell zu lokalisieren. Denken Sie beim Aufzeichnen von Protokollen bitte daran: Liest jemand diese Protokolle wirklich? Was können Sie tun, nachdem Sie dieses Protokoll gesehen haben? Kann es Vorteile bei der Fehlerbehebung bringen?

3. MySQL-Protokoll

(1) Tabellenerstellungsprotokoll

1 [Pflichtfeld] Felder, die das Konzept „Ja“ oder „Nein“ ausdrücken, müssen mit is_xxx benannt werden Datentyp: Unsigned tinyint (1 bedeutet Ja, 0 bedeutet Nein). Diese Regel gilt auch für die Erstellung von ODPS-Tabellen.

Hinweis: Wenn ein Feld eine nicht negative Zahl ist, muss es ohne Vorzeichen sein.
2. [Obligatorisch] Tabellennamen und Feldnamen dürfen am Anfang keine Kleinbuchstaben oder Zahlen enthalten, und nur Zahlen zwischen zwei Unterstrichen sind verboten. Die Änderung von Datenbankfeldnamen ist sehr kostspielig, da eine Vorabversion nicht möglich ist. Daher müssen Feldnamen sorgfältig geprüft werden.

Positivbeispiel: getter_admin, task_config, level3_name

Gegenbeispiel: GetterAdmin, taskConfig, level_3_name
3. Verwenden Sie keine Pluralnomen in Tabellennamen. Hinweis: Der Tabellenname sollte nur den Entitätsinhalt in der Tabelle darstellen und nicht die Anzahl der Entitäten. Der entsprechende DO-Klassenname liegt ebenfalls im Singular vor, was mit den Ausdrucksgewohnheiten übereinstimmt.
4. [Obligatorisch] Deaktivieren Sie reservierte Wörter wie „desc“, „range“, „match“, „delayed“ usw. Bitte beachten Sie die offiziellen reservierten Wörter von MySQL.
5. [Obligatorisch] Der eindeutige Indexname ist uk_field name; der allgemeine Indexname ist idx_field name. Hinweis: uk_ ist ein eindeutiger Schlüssel; idx_ ist die Abkürzung für index.
6. [Obligatorisch] Der Dezimaltyp ist dezimal, Float und Double sind verboten.

Hinweis: Beim Speichern von Float und Double besteht das Problem des Präzisionsverlusts, und beim Vergleichen von Werten kann es zu falschen Ergebnissen kommen. Wenn der Bereich der gespeicherten Daten den Dezimalbereich überschreitet, wird empfohlen, die Daten in Ganzzahlen und Dezimalzahlen aufzuteilen und diese getrennt zu speichern.
7. [Obligatorisch] Wenn die Längen der gespeicherten Zeichenfolgen nahezu gleich sind, verwenden Sie den Zeichenfolgentyp char mit fester Länge.
8. [Obligatorisch] Varchar ist eine Zeichenfolge variabler Länge, es wird kein Speicherplatz zugewiesen und die Länge sollte 5000 nicht überschreiten. Wenn die Speicherlänge größer als dieser Wert ist, definieren Sie den Feldtyp als Text, erstellen Erstellen Sie eine separate Tabelle und verwenden Sie den entsprechenden Primärschlüssel, um eine Beeinträchtigung der Indexeffizienz anderer Felder zu vermeiden.
9. [Obligatorisch] Die Tabelle muss drei Felder haben: id, gmt_create, gmt_modified.

Hinweis: Die ID muss der Primärschlüssel sein, der Typ ist unsigned bigint, automatische Inkrementierung für eine einzelne Tabelle und die Schrittgröße ist 1. Die Typen von gmt_create und gmt_modified sind alle date_time-Typen.
10. [Empfehlung] Benennen Sie die Tabelle am besten mit „Firmenname_Funktion der Tabelle“. Positives Beispiel: tiger_task / tiger_reader / mpp_config
11 [Empfehlung] Der Bibliotheksname und der Anwendungsname sollten möglichst konsistent sein.
12. [Empfehlung] Wenn Sie die Bedeutung eines Feldes ändern oder den durch ein Feld dargestellten Status anhängen, müssen Sie die Feldkommentare rechtzeitig aktualisieren.
13. [Empfohlen] Erlauben Sie angemessene Redundanz in den Feldern, um die Leistung zu verbessern, aber die Datensynchronisierung muss berücksichtigt werden. Redundante Felder sollten folgen:

 1) Felder, die nicht häufig geändert werden. 2) Es handelt sich nicht um ein superlanges Varchar-Feld, geschweige denn um ein Textfeld.

Positivbeispiel: Der Produktkategoriename wird häufig verwendet, die Feldlänge ist kurz und der Name bleibt grundsätzlich unverändert. Der Kategoriename kann redundant in der zugehörigen Tabelle gespeichert werden, um zugehörige Abfragen zu vermeiden.
14. [Empfehlung] Datenbank- und Tabellen-Sharding wird nur empfohlen, wenn die Anzahl der Zeilen in einer einzelnen Tabelle 5 Millionen überschreitet oder die Kapazität einer einzelnen Tabelle 2 GB überschreitet.

Hinweis: Sollte das Datenvolumen dieses Niveau voraussichtlich in drei Jahren nicht erreichen, verzichten Sie bitte beim Erstellen der Tabelle auf eine Aufteilung der Datenbank in Tabellen.
15. [Referenz] Eine angemessene Zeichenspeicherlänge spart nicht nur Datenbanktabellenplatz und Indexspeicher, sondern, was noch wichtiger ist, verbessert die Abrufgeschwindigkeit.

Positives Beispiel: Das Alter einer Person ist unsigned tinyint (was den Bereich von 0-255 angibt, die Lebensspanne eines Menschen wird 255 Jahre nicht überschreiten); wenn es aber so ist Alter der Sonne, es muss int sein; Wenn das Alter aller Sterne addiert wird, muss bigint verwendet werden.

(2) Indexspezifikation

1 [Pflichtfeld] Felder mit eindeutigen Merkmalen im Geschäftsleben, auch wenn es sich um kombinierte Felder handelt, müssen in einen eindeutigen Index eingebaut werden.

Hinweis: Denken Sie nicht, dass der eindeutige Index die Einfügegeschwindigkeit beeinflusst, aber die Verbesserung der Suchgeschwindigkeit ist darüber hinaus offensichtlich, auch wenn eine sehr vollständige Prüfsummenkontrolle vorliegt Die Anwendungsschicht muss gemäß Murphys Gesetz schmutzige Daten enthalten, solange es keine eindeutigen Indizes gibt.
2. [Pflichtfeld] Der Beitritt zu mehr als drei Tischen ist verboten. Die Datentypen der zu verknüpfenden Felder müssen absolut konsistent sein. Stellen Sie bei der Abfrage von Korrelationen mit mehreren Tabellen sicher, dass die zu korrelierenden Felder über Indizes verfügen.

Erklärung: Auch wenn Sie einer Doppeltabelle beitreten, müssen Sie auf Tabellenindizes und SQL-Leistung achten.
3. [Obligatorisch] Beim Erstellen eines Index für ein Varchar-Feld muss die Indexlänge angegeben werden. Es ist nicht erforderlich, das gesamte Feld zu indizieren.

Hinweis: Die Länge und die Unterscheidung des Index sind zwei Widersprüche. Bei Daten vom Typ String beträgt die Unterscheidung im Allgemeinen bis zu 90 % für einen Index mit einer Länge von 20. Sie können count verwenden (distinct left(Spaltenname, bestimmt durch die Unterscheidung der Indexlänge))/count(*).
4. [Obligatorisch] Linke oder vollständige Unschärfe ist bei der Seitensuche strengstens untersagt. Bitte verwenden Sie zur Lösung des Problems Suchmaschinen.

Beschreibung: Die Indexdatei verfügt über die Präfix-Übereinstimmungsfunktion ganz links von B-Tree. Wenn der Wert auf der linken Seite unbestimmt ist, kann dieser Index nicht verwendet werden.
5. [Empfehlung] Wenn es eine Reihenfolge nach Szenario gibt, achten Sie bitte auf die Ordnung des Index. Das letzte Feld in der Reihenfolge nach ist Teil des kombinierten Index und wird am Ende der Indexkombinationsreihenfolge platziert, um file_sort zu vermeiden und die Abfrageleistung zu beeinträchtigen.

Positivbeispiel: wobei a=? und b=? Reihenfolge nach c; Index: a_b_c

Gegenbeispiel: Wenn es eine Bereichssuche im Index gibt, kann die Reihenfolge des Index nicht sein verwendet, wie zum Beispiel: WHERE a> ;10 ORDER BY b; Index a_b kann nicht sortiert werden.
6. [Empfohlen] Verwenden Sie abdeckende Indizes, um Abfragevorgänge auszuführen, um Tabellenrückgabevorgänge zu vermeiden.

Erläuterung: Wenn ein Buch den Titel von Kapitel 11 kennen muss, öffnet es dann die Seite, die Kapitel 11 entspricht? Durchsuchen Sie einfach das Verzeichnis. Dieses Verzeichnis dient als Index.

Positives Beispiel: Die Arten von Indizes, die erstellt werden können: Primärschlüsselindex, eindeutiger Index, gewöhnlicher Index und abdeckender Index, sind ein Effekt einer Abfrage. Mit dem Ergebnis „explain“ wird die zusätzliche Spalte „using“ angezeigt Index.
7. [Empfehlung] Verwenden Sie verzögerte Korrelation oder Unterabfrage, um Szenarien mit mehreren Seiten zu optimieren.

Erklärung: MySQL überspringt die Offset-Zeile nicht, sondern nimmt die Offset-Zeile und gibt dann die Offset-Zeile zurück, bevor sie aufgibt. Wenn der Offset besonders groß ist, ist die Effizienz sehr gering , oder Steuern Sie die Gesamtzahl der zurückgegebenen Seiten oder führen Sie SQL-Umschreibungen für Seiten durch, die einen bestimmten Schwellenwert überschreiten.

Positives Beispiel: Suchen Sie zuerst schnell das ID-Segment, das abgerufen werden muss, und verknüpfen Sie dann Folgendes: SELECT a.* FROM table 1 a, (wählen Sie die ID aus Tabelle 1 aus, wobei die Bedingung LIMIT 100000,20 beträgt) b wobei a.id= b.id
8. [Empfehlung] Das Ziel der SQL-Leistungsoptimierung: Erreichen Sie mindestens die Bereichsebene. Die Anforderung ist die Referenzebene. Wenn es konstant sein kann, ist es am besten.

Erklärung:

1) Konstanten In einer einzelnen Tabelle gibt es höchstens eine passende Zeile (Primärschlüssel oder eindeutiger Index) und die Daten können während der Optimierungsphase gelesen werden.

2) Ref bezieht sich auf die Verwendung eines normalen Index.

 3) range führt eine Bereichssuche im Index durch.

Gegenbeispiel: Das Ergebnis der EXPLAIN-Tabelle, type=index, ist ein vollständiger Scan der physischen Indexdatei, der sehr langsam ist. Diese Indexebene liegt unter dem Bereich und wird von einer vollständigen Tabelle in den Schatten gestellt Scan.
9. [Empfehlung] Beim Aufbau eines kombinierten Index steht der differenzierteste ganz links. Positives Beispiel: Wenn a=? und b=? Spalte a fast einem eindeutigen Wert entspricht, müssen Sie nur einen einzigen idx_a-Index erstellen.

Hinweis: Wenn es eine gemischte Beurteilungsbedingung aus Ungleichheitszeichen und Gleichheitszeichen gibt, setzen Sie beim Erstellen des Index bitte die Spalte der Gleichheitszeichenbedingung voran. Zum Beispiel: wobei a>? und b=? Auch wenn a einen höheren Unterscheidungsgrad aufweist, muss b an die Spitze des Index gestellt werden.
10. [Referenz] Vermeiden Sie die folgenden extremen Missverständnisse beim Erstellen eines Index:

 1) Missverständnis, dass eine Abfrage einen Index erfordert.

 2) Sie glauben fälschlicherweise, dass Indizes Speicherplatz verbrauchen und Aktualisierungen und neue Ergänzungen erheblich verlangsamen.

3) Glauben Sie fälschlicherweise, dass eindeutige Indizes immer durch „Zuerst prüfen und dann einfügen“ auf der Anwendungsebene gelöst werden müssen.

(3) SQL-Spezifikation

1. Verwenden Sie nicht count (Spaltenname) oder count (Konstante) anstelle von count(*). von SQL92 Die Syntax zum Zählen von Zeilen hat nichts mit der Datenbank oder NULL oder Nicht-NULL zu tun.

Erklärung: count(*) zählt Zeilen mit NULL-Werten, während count(column name) keine Zeilen mit NULL-Werten in dieser Spalte zählt.
2. [Obligatorisch] count(distinct col) Berechnen Sie die Anzahl der unterschiedlichen Zahlen in der Spalte außer NULL. Beachten Sie, dass count(distinct col1, col2) 0 zurückgibt, wenn eine der Spalten alle NULL ist, auch wenn die andere Spalte andere Werte hat.
3. [Obligatorisch] Wenn die Werte einer bestimmten Spalte alle NULL sind, ist das Rückgabeergebnis von count(col) 0, aber das Rückgabeergebnis von sum(col) ist NULL, Sie müssen also aufpassen zum NPE-Problem bei Verwendung von sum().

Positivbeispiel: Sie können die folgende Methode verwenden, um das NPE-Problem der Summe zu vermeiden: SELECT IF(ISNULL(SUM(g)),0,SUM(g)) FROM table;
4. Obligatorisch] Verwenden Sie ISNULL(), um festzustellen, ob es sich um einen NULL-Wert handelt. Hinweis: Ein direkter Vergleich von NULL mit einem beliebigen Wert gibt NULL zurück.

Erklärung: 1) NULL<>Das Rückgabeergebnis von NULL ist NULL, nicht falsch.

2) Das Rückgabeergebnis von NULL=NULL ist NULL, nicht wahr.

3) Das Rückgabeergebnis von NULL<>1 ist NULL, nicht wahr.
5. [Obligatorisch] Wenn beim Schreiben der Paging-Abfragelogik die Anzahl 0 ist, sollte sie direkt zurückgegeben werden, um die Ausführung nachfolgender Paging-Anweisungen zu vermeiden.
6. [Obligatorisch] Fremdschlüssel und Kaskaden sind nicht zulässig. Alle Fremdschlüsselkonzepte müssen auf der Anwendungsebene gelöst werden. Hinweis: (Konzepterklärung) student_id in der Schülertabelle ist der Primärschlüssel, dann ist student_id in der Notentabelle der Fremdschlüssel. Wenn die student_id in der student-Tabelle aktualisiert wird und gleichzeitig die student_id in der grades-Tabelle aktualisiert wird, handelt es sich um eine Kaskadenaktualisierung. Fremdschlüssel und Kaskadenaktualisierungen eignen sich für eine geringe Parallelität auf einem einzelnen Computer, sind jedoch nicht für verteilte Cluster mit hoher Parallelität geeignet; Kaskadenaktualisierungen sind stark blockierend und bergen das Risiko, dass Datenbankaktualisierungsstürme die Einfügungsgeschwindigkeit der Datenbank beeinträchtigen .
7. [Obligatorisch] Die Verwendung gespeicherter Prozeduren ist schwierig zu debuggen und zu erweitern und nicht portierbar.
8. [Obligatorisch] Beim Überarbeiten von Daten, beim Löschen oder Ändern von Datensätzen müssen Sie zuerst auswählen, um ein versehentliches Löschen zu vermeiden, und dann die Aktualisierungsanweisung erst ausführen, nachdem Sie bestätigt haben, dass sie korrekt ist.
9. [Empfehlung] Vermeiden Sie den Betrieb, wenn er vermieden werden kann. Wenn er nicht vermieden werden kann, müssen Sie die Anzahl der dahinter liegenden Sammelelemente sorgfältig abwägen und sie innerhalb von 1.000 kontrollieren.
10. [Referenz] Wenn eine Globalisierung erforderlich ist, sind alle Zeichenspeicher und -darstellungen in utf-8 codiert. Beachten Sie dann die Zeichenzählmethode:

Erläuterung: SELECT LENGTH („Easy Work“ ) ; Kehrt zu 12 zurück SELECT CHARACTER_LENGTH ("Easy Work"); Kehrt zu 4 zurück. Wenn Sie Ausdrücke verwenden möchten, verwenden Sie utfmb4 zur Speicherung und achten Sie auf den Unterschied zwischen dieser und der utf-8-Kodierung.
11. [Referenz] TRUNCATE TABLE ist schneller als DELETE und verbraucht weniger System- und Transaktionsprotokollressourcen. TRUNCATE hat jedoch keine Transaktionen und löst keine Auslöser aus, was zu Unfällen führen kann im Entwicklungscode.

Erläuterung: TRUNCATE TABLE ist funktional identisch mit der DELETE-Anweisung ohne WHERE-Klausel.

(4) ORM-Protokoll

1. In Tabellenabfragen kein * als Feldliste der Abfrage verwenden. Es muss klar angegeben werden, welche Felder erforderlich sind.

Erläuterung:

1) Erhöhen Sie die Analysekosten des Abfrageanalysators.

2) Das Hinzufügen oder Entfernen von Feldern kann leicht zu Konflikten mit der resultMap-Konfiguration führen.
2. [Obligatorisch] Das boolesche Attribut der POJO-Klasse kann nicht mit is hinzugefügt werden, aber das Datenbankfeld muss mit is_ hinzugefügt werden, was eine Zuordnung zwischen Feldern und Attributen in der resultMap erfordert.

Hinweis: Beachten Sie die POJO-Klassendefinitions- und Datenbankfelddefinitionsbestimmungen. Es ist notwendig, eine Zuordnung in sql.xml hinzuzufügen.
3. [Obligatorisch] Verwenden Sie resultClass nicht als Rückgabeparameter. Auch wenn alle Klassenattributnamen Datenbankfeldern entsprechen, müssen sie dennoch über ein entsprechendes Feld verfügen.

Beschreibung: Konfigurieren Sie die Zuordnungsbeziehung, um Felder für eine einfache Wartung von DO-Klassen zu entkoppeln.
4. [Obligatorisch] Bitte achten Sie auf die Verwendung von Parametern in der XML-Konfiguration: #{}, #param# Diese Methode ist anfällig für SQL-Injection.
5. [Obligatorisch] Die mit iBATIS gelieferte queryForList(String StatementName, int start, int size) wird nicht empfohlen.

Erläuterung: Die Implementierungsmethode besteht darin, alle Datensätze der SQL-Anweisung abzurufen, die dem Anweisungsnamen in der Datenbank entsprechen, und dann die Teilmenge von Start und Größe über subList abzurufen. Aus diesem Grund ist OOM aufgetreten.
Positives Beispiel: #start#, #size#
in sqlmap.xml einführen Map map = new HashMap();
map.put("start" , start);
map.put("size", size);
6. [Obligatorisch] Es ist nicht erlaubt, HashMap und Hashtable direkt als Ausgabe des Abfrageergebnissatzes zu verwenden.
7. [Obligatorisch] Wenn Sie den Datentabellendatensatz aktualisieren, müssen Sie auch den entsprechenden gmt_modified-Feldwert des Datensatzes auf die aktuelle Zeit aktualisieren.
8. [Empfohlen] Schreiben Sie keine große und umfassende Datenaktualisierungsschnittstelle. Unabhängig davon, ob es sich um Ihr eigenes Zielaktualisierungsfeld handelt, legen Sie c1=Wert1, c2=Wert2, c3 fest =Wert3. ; Das ist nicht richtig. Versuchen Sie beim Ausführen von SQL, keine unveränderten Felder zu aktualisieren. Erstens ist es fehleranfällig. Zweitens ist es ineffizient. Und drittens erhöht Binlog den Speicher.
9. [Referenz] @Transactional-Transaktionen nicht missbrauchen. Transaktionen wirken sich auf die QPS der Datenbank aus. Darüber hinaus müssen bei der Verwendung von Transaktionen verschiedene Rollback-Lösungen in Betracht gezogen werden, darunter Cache-Rollback, Suchmaschinen-Rollback, Nachrichtenkompensation, statistische Korrektur usw.
10. [Referenz] Der CompareValue in ist eine Konstante, die mit dem Attributwert verglichen wird, normalerweise eine Zahl, und diese Bedingung wird verwendet, wenn sie bedeutet, dass sie nicht gleich ist leer oder null; es wird ausgeführt, wenn es nicht leer ist; bedeutet Ausführung, wenn der Wert nicht null ist.

4. Technische Spezifikationen

(1) Anwendungsschicht

1 [Empfohlen] Standardmäßig hängt die obere Schicht in der Abbildung von der unteren Schicht und dem Pfeil ab Die Beziehung weist auf eine direkte Abhängigkeit hin, z. B.: Die offene Schnittstellenschicht kann sich auf die Webschicht oder direkt auf die Serviceschicht verlassen usw.:
 Offene Schnittstellenschicht: Sie kann die Serviceschnittstelle direkt kapseln und in einem verfügbar machen RPC-Schnittstelle; kapseln Sie es über die Web-Gateway-Steuerungsschicht usw. .
 Terminal-Anzeigeebene: Die Vorlagen jedes Terminals rendern und führen die Anzeigeebene aus. Derzeit sind die wichtigsten Geschwindigkeits-Rendering, JS-Rendering, JSP-Rendering, mobile Anzeigeebene usw.
 Webschicht: hauptsächlich Weiterleitung der Zugriffskontrolle, Überprüfung verschiedener Grundparameter oder einfache Verarbeitung nicht wiederverwendeter Dienste usw.
 Serviceschicht: eine relativ spezifische Geschäftslogik-Serviceschicht.
 Managerschicht: eine allgemeine Geschäftsverarbeitungsschicht mit den folgenden Merkmalen:

 1) Die von der Drittanbieterplattform gekapselte Schicht, die die Rückgabeergebnisse vorverarbeitet und Ausnahmeinformationen konvertiert;

 2) Die Senkung allgemeiner Funktionen der Service-Schicht, wie z. B. Caching-Lösungen und allgemeine Middleware-Verarbeitung

 3) Interaktion mit der DAO-Schicht, um die allgemeinen Geschäftsfunktionen von DAO zu kapseln.
 DAO-Schicht: Datenzugriffsschicht, die mit dem zugrunde liegenden MySQL, Oracle und Hbase für Daten interagiert.
 Externe Schnittstellen oder Plattformen von Drittanbietern: einschließlich offener RPC-Schnittstellen anderer Abteilungen, Basisplattformen und HTTP-Schnittstellen anderer Unternehmen.
2. [Referenz] (Hierarchisches Ausnahmebehandlungsprotokoll) In der DAO-Ebene werden viele Arten von Ausnahmen generiert. Es ist unmöglich, die Methode „catch(Exception e)“ zu verwenden und eine neue DAOException auszulösen. e) Es besteht keine Notwendigkeit, Protokolle zu drucken, da Protokolle erfasst und in Protokolldateien auf der Manager-/Dienstebene geschrieben werden müssen. Wenn derselbe Server erneut Protokolle druckt, werden Leistung und Speicherplatz verschwendet. Wenn in der Serviceschicht eine Ausnahme auftritt, müssen die Protokollinformationen auf der Festplatte aufgezeichnet werden und die Parameterinformationen müssen so weit wie möglich enthalten sein, was dem Schutz des Tatorts gleichkommt. Wenn die Manager-Schicht und der Dienst auf demselben Computer bereitgestellt werden, stimmt die Protokollierungsmethode mit der Verarbeitung der DAO-Schicht überein. Wenn sie separat bereitgestellt werden, stimmt die Protokollierungsmethode mit dem Dienst überein. Die Webebene sollte niemals weiterhin Ausnahmen auslösen. Da sie sich bereits auf der obersten Ebene befindet, gibt es keine Möglichkeit, weiterhin Ausnahmen zu behandeln. Wenn Sie feststellen, dass diese Ausnahme dazu führt, dass die Seite nicht normal gerendert wird, sollten Sie springen direkt zu einer benutzerfreundlichen Fehlerseite und geben Sie Ihr Bestes, um eine benutzerfreundliche Fehlermeldung anzuzeigen. Die offene Schnittstellenschicht sollte Ausnahmen behandeln und sie in Form von Fehlercodes und Fehlermeldungen zurückgeben.
3. [Referenz] Spezifikation des hierarchischen Domänenmodells:
 DO (Datenobjekt): Entspricht eins zu eins der Datenbanktabellenstruktur und überträgt Datenquellenobjekte über die DAO-Schicht nach oben.
 DTO (Data Transfer Object): Datenübertragungsobjekt, ein vom Service und Manager extern übertragenes Objekt.
 BO (Geschäftsobjekt): Geschäftsobjekt. Ein Objekt, das Geschäftslogik kapselt und von der Serviceschicht ausgegeben werden kann.
 ABFRAGE: Datenabfrageobjekt, jede Ebene empfängt Abfrageanforderungen von der oberen Ebene. Hinweis: Bei der Abfragekapselung mit mehr als zwei Parametern ist die Verwendung der Map-Klasse für die Übertragung verboten.
 VO (View Object): Anzeigeebenenobjekt, normalerweise ein Objekt, das vom Web an die Ebene der Template-Rendering-Engine übertragen wird.

(2) Zwei-Parteien-Bibliotheksspezifikation

1. [Obligatorisch] Definieren Sie GAV, um die folgenden Regeln einzuhalten:

 1) GroupID-Format: com.{Company/BU}.Business Line.[Sub-Business Line], bis zu 4 Ebenen.

Beschreibung: {Company/BU} Zum Beispiel: alibaba/taobao/tmall/aliexpress und andere Untergeschäftsbereiche sind optional;

Positivbeispiel: com.taobao.jstorm oder com.alibaba.dubbo.register

2) ArtifactID-Format: Produktlinienname-Modulname. Die Semantik wird nicht wiederholt oder weggelassen. Gehen Sie zunächst zur Überprüfung ins Lagerzentrum.

Positivbeispiel: dubbo-client / fastjson-api / jstorm-tool 3) Version: Bitte beachten Sie die Details unten.
2. [Obligatorisch] Die Benennungsmethode für die Versionsnummer der Zweitpartei: Hauptversionsnummer

 1) Hauptversionsnummer: Wird als inkompatible API-Änderung oder hinzugefügte Funktionalität angesehen Merkmale, die die Richtung des Produkts ändern.

2) Nebenversionsnummer: wird als abwärtskompatible funktionale Ergänzung behandelt (neue Klassen, Schnittstellen usw.).

 3) Revisionsnummer: Fehler beheben, Funktionen verbessern, ohne Methodensignaturen zu ändern, und API-Kompatibilität aufrechterhalten.

 Hinweis: Die Startversionsnummer muss sein: 1.0.0, nicht 0.0.1
3. Online-Anwendungen basieren nicht auf der SNAPSHOT-Version (mit Ausnahme der offiziell veröffentlichten Klasse); Bibliotheken Die RELEASE-Versionsnummer-Upgrade +1-Methode muss verwendet werden, und die Versionsnummer darf nicht überschrieben und aktualisiert werden. Sie müssen sich zur Überprüfung an das Zentrallager wenden.

Hinweis: Wenn Sie sich nicht auf die SNAPSHOT-Version verlassen, ist die Idempotenz der Anwendungsfreigabe gewährleistet. Darüber hinaus kann es auch die Verpackung und Konstruktion während der Kompilierung beschleunigen.
4. [Obligatorisch] Durch das Hinzufügen oder Aktualisieren der Drittanbieterbibliothek bleiben die Vermittlungsergebnisse anderer JAR-Pakete mit Ausnahme der Funktionspunkte unverändert. Wenn es Änderungen gibt, müssen diese eindeutig ausgewertet und überprüft werden. Es wird empfohlen, die Informationen vor und nach dependency:resolve zu vergleichen. Wenn die Arbitrierungsergebnisse völlig inkonsistent sind, verwenden Sie den Befehl dependency:tree, um die Unterschiede zu ermitteln und 5. [Obligatorisch] Bibliotheken von Drittanbietern können Aufzählungstypen definieren, und Parameter können Aufzählungstypen verwenden, aber Schnittstellenrückgabewerte erlauben nicht die Verwendung von Aufzählungstypen oder POJO-Objekten, die Aufzählungstypen enthalten.
6. [Obligatorisch] Wenn Sie sich auf eine Bibliotheksgruppe eines Drittanbieters verlassen, muss eine einheitliche Versionsvariable definiert werden, um Inkonsistenzen der Versionsnummer zu vermeiden.

Beschreibung: Abhängig von springframework-core, -context, -beans, sie haben alle die gleiche Version. Sie können eine Variable definieren, um die Version zu speichern: ${spring.version}, wenn Sie Abhängigkeiten definieren, verweisen Sie darauf Version.
7. [Obligatorisch] Es ist verboten, dieselbe GroupId, dieselbe ArtifactId, aber unterschiedliche Versionen in den POM-Abhängigkeiten von Unterprojekten zu haben.

Hinweis: Beim lokalen Debuggen wird die von jedem Unterprojekt angegebene Versionsnummer verwendet. Bei der Zusammenführung in einen Krieg kann jedoch nur eine Versionsnummer im endgültigen lib-Verzeichnis angezeigt werden. Es gab Präzedenzfälle, bei denen das Offline-Debuggen korrekt war, bei der Online-Veröffentlichung jedoch Probleme auftraten.
8. [Empfehlung] Platzieren Sie die Abhängigkeitsdeklarationen in allen POM-Dateien im Anweisungsblock und platzieren Sie alle Versionsentscheidungen im Anweisungsblock

Hinweis: deklariert nur die Version und implementiert nicht die Einführung. Daher muss das Unterprojekt explizit Abhängigkeiten deklarieren. UndAlle in den deklarierten Abhängigkeiten werden standardmäßig automatisch von allen Unterprojekten eingeführt und geerbt.
9. [Empfehlung] Die Bibliothek eines Drittanbieters sollte versuchen, keine Konfigurationselemente zu haben und zumindest keine weiteren Konfigurationselemente hinzuzufügen.
10. [Referenz] Um Abhängigkeitskonflikte bei der Anwendung von Zweitanbieterbibliotheken zu vermeiden, sollten Herausgeber von Zweitanbieterbibliotheken die folgenden Grundsätze befolgen:

1) Das Prinzip der Einfachheit und Kontrollierbarkeit. Entfernen Sie alle unnötigen APIs und Abhängigkeiten, einschließlich nur der Service-API, notwendiger Domänenmodellobjekte, Utils-Klassen, Konstanten, Aufzählungen usw. Wenn Sie sich auf andere Bibliotheken von Drittanbietern verlassen, versuchen Sie, diese über die bereitgestellten Funktionen einzuführen, sodass Benutzer der Bibliotheken von Drittanbietern sich auf bestimmte Versionsnummern verlassen können. Es gibt keine spezifische Implementierung von Protokollen und Sie verlassen sich nur auf das Protokoll-Framework.

 2) Stabiles Rückverfolgbarkeitsprinzip. Änderungen in jeder Version sollten aufgezeichnet werden, wer die Bibliothek des Drittanbieters verwaltet und wo sich der Quellcode befindet – alles muss leicht zugänglich sein. Das Verhalten öffentlicher Bibliotheken von Drittanbietern sollte sich nicht ändern, es sei denn, der Benutzer aktualisiert die Version aktiv.

(3) Serverspezifikation

1 [Empfohlen] Für Server mit hoher Parallelität wird empfohlen, das time_wait-Timeout des TCP-Protokolls zu reduzieren. Hinweis: Standardmäßig schließt das Betriebssystem Verbindungen im Status „time_wait“ nach 240 Sekunden. Bei hohem gleichzeitigem Zugriff kann der Server möglicherweise keine neuen Verbindungen herstellen, da in „time_wait“ zu viele Verbindungen vorhanden sind. Daher müssen Sie diesen Wert anpassen auf dem Server.

Positivbeispiel: Bitte ändern Sie auf dem Linux-Server den Standardwert (Sekunden), indem Sie die Datei /etc/sysctl.conf ändern: net.ipv4.tcp_fin_timeout = 30
2. Erhöhen Sie den Wert Die maximale Anzahl der vom Server unterstützten Dateihandles (Dateideskriptor, abgekürzt als fd).

Erläuterung: Das Design gängiger Betriebssysteme besteht darin, TCP/UDP-Verbindungen auf die gleiche Weise wie Dateien zu verwalten, d. h. eine Verbindung entspricht einem fd. Die Standardanzahl der von Mainstream-Linux-Servern unterstützten FDs beträgt 1024. Wenn die Anzahl gleichzeitiger Verbindungen groß ist, kann es aufgrund unzureichender FDs leicht zu Fehlern wie „Zu viele Dateien öffnen“ kommen, was dazu führt, dass neue Verbindungen nicht hergestellt werden können. Es wird empfohlen, die maximale Anzahl der vom Linux-Server unterstützten Handles um ein Vielfaches zu erhöhen (bezogen auf die Speichermenge auf dem Server).
3. [Empfohlen] Setzen Sie den Parameter -XX:+HeapDumpOnOutOfMemoryError auf die JVM, damit die JVM Dump-Informationen ausgeben kann, wenn sie auf ein OOM-Szenario stößt.

Hinweis: OOM tritt mit Wahrscheinlichkeit auf, und sogar alle paar Monate tritt ein Fall auf. Die Informationen vor Ort, wenn sie auftreten, sind für die Fehlerbehebung sehr wertvoll.
4. [Referenz] Verwenden Sie die Weiterleitung für die interne Umleitung des Servers. Verwenden Sie die URL-Assembly-Tool-Klasse, um externe Umleitungsadressen zu generieren, da dies sonst zu inkonsistenter URL-Pflege und potenziellen Sicherheitsrisiken führt.

5. Sicherheitsbestimmungen

1. [Obligatorisch] Seiten oder Funktionen des Benutzers müssen einer Berechtigungskontrolle unterzogen werden. Hinweis: Dadurch wird verhindert, dass Benutzer nach Belieben auf die Daten anderer Personen zugreifen und diese bearbeiten können, ohne eine horizontale Berechtigungsüberprüfung durchzuführen, z. B. das Anzeigen und Ändern der Bestellungen anderer Personen.
2. [Obligatorisch] Die direkte Anzeige sensibler Benutzerdaten ist verboten und die Anzeigedaten müssen desensibilisiert werden. Hinweis: Wenn Sie Ihre persönliche Mobiltelefonnummer anzeigen, wird diese als 158****9119 angezeigt, wobei die mittleren 4 Ziffern ausgeblendet werden, um einen Verlust der Privatsphäre zu verhindern.
3. [Obligatorisch] Die vom Benutzer eingegebenen SQL-Parameter müssen durch Parameterbindung oder METADATA-Feldwerte streng eingeschränkt werden, um SQL-Injection zu verhindern und den Zugriff von SQL-String-Splicing auf die Datenbank zu verhindern.
4. [Obligatorisch] Alle vom Benutzer eingegebenen Parameter müssen auf Gültigkeit überprüft werden. Hinweis: Das Ignorieren der Parameterüberprüfung kann zu Folgendem führen:
 Übermäßige Seitengröße, die zu Speicherüberlauf führt
 Böswillige Reihenfolge durch langsame Datenbankabfrage
 Willkürliche Umleitung
 SQL-Injection
 Reverse-Sequence-Injection
 Denial-of-Service-ReDoS-Beschreibung für reguläre Eingabequellen: JavaJava-Code verwendet reguläre Ausdrücke, um Clienteingaben zu überprüfen. Einige reguläre Schreibmethoden haben kein Problem bei der Überprüfung normaler Benutzereingaben. Wenn der Angreifer jedoch eine speziell erstellte Zeichenfolge zur Überprüfung verwendet, Dies kann zu einem Endlosschleifeneffekt führen.
5. [Obligatorisch] Es ist verboten, Benutzerdaten, die nicht sicher gefiltert oder nicht korrekt maskiert wurden, auf der HTML-Seite auszugeben.
6. [Obligatorisch] Formular- und AJAX-Übermittlungen müssen eine CSRF-Sicherheitsfilterung durchführen. Beschreibung: CSRF (Cross-Site Request Forgery) ist eine häufige Programmierschwachstelle. Bei Anwendungen/Websites mit CSRF-Schwachstellen können Angreifer die URL im Voraus erstellen. Sobald der Benutzer des Opfers darauf zugreift, ändert der Hintergrund die Benutzerparameter in der Datenbank ohne Wissen des Benutzers entsprechend.
7. [Obligatorisch] Bei der Nutzung von Plattformressourcen wie Textnachrichten, E-Mails, Telefonanrufen, Bestellungen und Zahlungen müssen korrekte Anti-Replay-Einschränkungen wie Mengenbeschränkungen, Ermüdungskontrolle und Verifizierung des Bestätigungscodes implementiert werden um Missbrauch zu vermeiden, Kapitalverlust.

Hinweis: Wenn bei der Registrierung ein Bestätigungscode an das Mobiltelefon gesendet wird und die Anzahl und Häufigkeit nicht begrenzt ist, kann diese Funktion dazu verwendet werden, andere Benutzer zu belästigen und eine Verschwendung von Ressourcen der SMS-Plattform zu verursachen.

Das obige ist der detaillierte Inhalt vonAnalysieren Sie Java-Codierungsspezifikationen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn