欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

《阿里巴巴 Java開發(fā)手冊》讀后感小結(jié)

 更新時間:2018年12月29日 10:26:32   作者:Java3y  
這篇文章主要介紹了《阿里巴巴 Java開發(fā)手冊》讀后感小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

只有光頭才能變強

前一陣子一直在學(xué)Redis,結(jié)果在黃金段位被虐了,暫時升不了段位了,每天都拿不到首勝(好煩)。

趁著學(xué)校校運會,合理地給自己放了一個小長假,然后就回家了?;氐郊也虐l(fā)現(xiàn)當(dāng)時618買了一堆書,這堆書還有沒撕包裝的呢....于是我翻出了最薄的一本《阿里巴巴 Java開發(fā)手冊》

這本書一共就90多頁,一天就可以通讀完了,看完之后我又來水博文了。

注意:

  • 書上很多的規(guī)范是可以用IDE來避免的,也有很多之前已經(jīng)知道的了。
  • 所以,這篇文章只記錄我認為比較重要,或者說是我之前開發(fā)時沒有注意到的一些規(guī)范(知識點)。
  • 該文章的內(nèi)容肯定沒有書上寫得那么全的,如果感興趣的同學(xué)可以去買一本來讀一下~

PDF官方地址:https://github.com/alibaba/p3c

一、Java相關(guān)

1.POJO是DO/DTO/BO/VO的統(tǒng)稱,禁止命名為xxxPOJO

2.獲取多個對象的方法中l(wèi)ist作為前綴

3.獲取統(tǒng)計值的方法用count作為前綴

4.POJO類中的布爾類型(Boolean)的變量都不要加is前綴,否則部分框架解析會引起序列化錯誤

  • 如果你的變量名帶is的話,比如isActive,框架解析的時候可能就當(dāng)成active了。

5.如果是形容能力的接口名稱,取對應(yīng)的形容詞為接口名(通常是-able的形式)

6.不允許任何魔法值(未經(jīng)預(yù)先定義的常量)直接出現(xiàn)在代碼中

7.Object的euqals方法容易拋出空指針異常,應(yīng)使用常量或者有值的對象來調(diào)用equals。推薦使用java.util.Object#equals工具類

8.所有POJO類的屬性全部使用包裝數(shù)據(jù)類型,RPC的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型,所有的局部變量都使用基本數(shù)據(jù)類型。定義VO/DTO/DO等POJO類時,不要設(shè)定任何屬性的默認值

  • 如果你的類屬性使用int這樣的基本數(shù)據(jù)類型,默認值是0。一般情況下該變量沒有賦值,一般想表達的是不存在(null),而不是0。

9.構(gòu)造方法禁止加入任何的業(yè)務(wù)邏輯,如果初始化邏輯可以放在init方法中。set/get方法也不要增加業(yè)務(wù)邏輯。 •如果set/get方法放入業(yè)務(wù)邏輯,有時候排查問題就變得很麻煩了

10.工具類Arrays.asList()把數(shù)組轉(zhuǎn)成List時,不能使用其修改集合的相關(guān)方法。比如說add、clear、remove

11.在JDK7以及以上版本中,Comparator要滿足三個條件,不然調(diào)用Arrays.sort()或者Collections.sort()會報異常。 •x,y 的比較結(jié)果和 y,x 的比較結(jié)果相反

  • 傳遞性:x>y并且y>z,那么x一定大于z
  • 對稱性:x=y,則 x,z 比較結(jié)果和y,z比較結(jié)果相同

12.使用entrySet遍歷Map類集合K/V,而不是用keySet方式遍歷 •keySet遍歷了兩次,一次是轉(zhuǎn)成Iterator對象,一次是從hashMap中取出key所對應(yīng)的value,如果JDK8可以使用Map.foreach方法

13.線程資源必須由線程池提供,不允許在應(yīng)用中自行顯示創(chuàng)建線程。線程池不允許用Executors創(chuàng)建,通過ThreadPoolExecutor的方式創(chuàng)建,這樣的處理方式能夠讓編寫代碼的工程師更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風(fēng)險。

14.SimpleDateFormat是線程不安全的類,一般不要定義為static變量,如果定義為static,必須加鎖,或者使用DateUtils工具類

  • 如果是JDK8應(yīng)用,可以使用Instant(針對時間統(tǒng)計等場景)代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替SimpleDateFormat

15.避免Random實例被多線程使用,雖然共享該實例是線程安全的,但會因競爭同一seed導(dǎo)致性能下降 •在JDK7之后,可以直接使用API ThreadLocalRandom,而在JDK7 之前,需要編碼保證每個線程持有一個實例。

16.類、類屬性、類方法的注釋必須使用 Javadoc 規(guī)范,使用 /**內(nèi)容*/ 格式,不得使用 //xxx 方式

17.所有的抽象方法(包括接口中的方法)必須要用 Javadoc 注釋,除了返回值、參數(shù)、異常說明外,還必須指出該方法做什么事情,實現(xiàn)什么功能。所有的類都必須添加創(chuàng)建者和創(chuàng)建日期。

18.對于暫時被注釋掉,后續(xù)可能恢復(fù)使用的代碼片斷,在注釋代碼的上方,使用三個斜杠///來說明注釋代碼的理由

19.保證單元測試的獨立性。為了保證單元測試穩(wěn)定可靠且便于維護,單元測試之間不能互相調(diào)用,也不能依賴執(zhí)行的先后順序。

20.高并發(fā)服務(wù)器建議調(diào)小TCP協(xié)議的time_await超時時間,調(diào)大最大事件句柄數(shù)(fd),

1.1值得說明的點

一、不允許任何魔法值(未經(jīng)預(yù)先定義的常量)直接出現(xiàn)在代碼中

例子:

  Negative example:
  //Magic values, except for predefined, are forbidden in coding.
  if (key.equals("關(guān)注公眾號:Java3y")) {
    //...
  }

  Positive example:
  String KEY_PRE = "關(guān)注公眾號:Java3y";
  if (KEY_PRE.equals(key)) {
    //...
  }

ps:我猜是把先常量定義出來,后續(xù)引用/修改的時候就很方便了。

二、Object的euqals方法容易拋出空指針異常,應(yīng)使用常量或者有值的對象來調(diào)用equals。推薦使用java.util.Object#equals工具類

java.util.Object#equals的源碼(已經(jīng)判斷null的情況了)

 public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
  }

三、工具類Arrays.asList()把數(shù)組轉(zhuǎn)成List時,不能使用其修改集合的相關(guān)方法。

因為返回的ArrayList是一個內(nèi)部類,并沒有實現(xiàn)集合的修改方法。后臺的數(shù)據(jù)仍是數(shù)組,這里體現(xiàn)的是適配器模式。

四、在JDK7以及以上版本中,Comparator要滿足自反性,傳遞性,對稱性,不然調(diào)用Arrays.sort()或者Collections.sort()會報異常。

The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

Finally, the implementor must ensure that compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.

1) x,y 的比較結(jié)果和 y,x 的比較結(jié)果相反。

2) 傳遞性:x>y,y>z,則 x>z。

3) 對稱性:x=y,則 x,z 比較結(jié)果和 y,z 比較結(jié)果相同。

反例:下例中沒有處理相等的情況,實際使用中可能會出現(xiàn)異常:

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

使用entrySet遍歷Map類集合K/V,而不是用keySet方式遍歷

首先我們來看一下使用keySet是如何遍歷HashMap的:

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

再來看一下源碼:

// 1. 得到keySet,如果不存在,則創(chuàng)建
public Set<K> keySet() {
  Set<K> ks = keySet;
  if (ks == null) {
    ks = new KeySet();
    keySet = ks;
  }
  return ks;
}

// 2.初始化ks (實際上就是Set集合[HashMap的內(nèi)部類],在初始化時需要順便初始化iterator)
ks = new AbstractSet<K>() {
  public Iterator<K> iterator() {
    return new Iterator<K>() {
      private Iterator<Entry<K,V>> i = entrySet().iterator();

      public boolean hasNext() {
        return i.hasNext();
      }

      public K next() {
        return i.next().getKey();
      }

      public void remove() {
        i.remove();
      }
    };
  }

};

再來看一下entrySet,可以直接拿到key和value,不用再使用get方法來得到value,所以比keySet更加推薦使用!

  public static void main(String[] args) throws InterruptedException {

    HashMap<String, String> hashMap = new HashMap<>();
    hashMap.put("關(guān)注公眾號:", "Java3y");
    hashMap.put("堅持原創(chuàng)", "Java3y");
    hashMap.put("點贊", "關(guān)注,轉(zhuǎn)發(fā),分享");


    // 得到entrySet,遍歷entrySet得到結(jié)果
    Set<Map.Entry<String, String>> entrySet = hashMap.entrySet();
    Iterator<Map.Entry<String, String>> iterator = entrySet.iterator();
    while (iterator.hasNext()) {
      Map.Entry<String, String> entry = iterator.next();
      System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
    }
  }

如果是JDK8的話,推薦直接使用Map.forEach()就好了,我們也來看看用法:

public static void main(String[] args) throws InterruptedException {

  HashMap<String, String> hashMap = new HashMap<>();
  hashMap.put("關(guān)注公眾號:", "Java3y");
  hashMap.put("堅持原創(chuàng)", "Java3y");
  hashMap.put("點贊", "關(guān)注,轉(zhuǎn)發(fā),分享");

  
  // forEach用法
  hashMap.forEach((key, value) -> System.out.println("key = " + key + ", value = " + value));
}

其實在源碼里邊我們可以發(fā)現(xiàn),forEach實際上就是封裝了entrySet,提供forEach給我們可以更加方便地遍歷Map集合

 // forEach源碼
  default void forEach(BiConsumer<? super K, ? super V> action) {
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) {
      K k;
      V v;
      try {
        k = entry.getKey();
        v = entry.getValue();
      } catch(IllegalStateException ise) {
        // this usually means the entry is no longer in the map.
        throw new ConcurrentModificationException(ise);
      }
      action.accept(k, v);
    }
  }

五、SimpleDateFormat是線程不安全的類,一般不要定義為static變量,如果定義為static,必須加鎖,或者使用DateUtils工具類。

有以下的例子可以正確使用SimpleDateFormat:

// 1. 在方法內(nèi)部使用,沒有線程安全問題
private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
public String getFormat(Date date){
  SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
  return dateFormat.format(date);
}


// 2. 每次使用的時候加鎖   
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void getFormat(){
  synchronized (SIMPLE_DATE_FORMAT){
  SIMPLE_DATE_FORMAT.format(new Date());
  ….;
}
    
// 3. 使用ThreadLocal,每個線程都有自己的SimpleDateFormat對象,互不干擾
private static final ThreadLocal<DateFormat> DATE_FORMATTER = new ThreadLocal<DateFormat>() {
  @Override
  protected DateFormat initialValue() {
    return new SimpleDateFormat("yyyy-MM-dd");
  }
};

// 4. 使用DateTimeFormatter(This class is immutable and thread-safe.)

  DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  System.out.println(timeFormatter.format(LocalDateTime.now()));

如果是JDK8應(yīng)用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替SimpleDateFormat。

二、數(shù)據(jù)庫相關(guān)

1.表達是否概念的字段,必須使用isxxx的方式命名,數(shù)據(jù)類型是unsigned tinyint(1表示是,0表示否)

2.小數(shù)類型用decimal,禁止使用float和double。

3.varchar是可變字符串,不預(yù)選分配存儲空間的話,長度不要超過5000個字符。如果超過則用text,獨立一張表,用主鍵對應(yīng),避免影響到其他字段的索引效率。

4.表必備的三個字段:id(類型是unsigned bigint),gmt_create(創(chuàng)建時間),gme_modified(修改時間)

5.字段允許適當(dāng)冗余,以提高查詢性能,但必須考慮數(shù)據(jù)一致性。冗余的字段必須不是頻繁修改的字段,不是varhar超長字段(更不能是text字段)。

6.單表行數(shù)超過500萬行或者單表容量超過2GB才推薦進行分庫分表(如果預(yù)計三年都達不到這個數(shù)據(jù)量,不要在創(chuàng)建表的時候就分庫分表!)

7.超過三個表禁止使用join,需要join的字段,數(shù)據(jù)類型必須保持一致,當(dāng)多表關(guān)聯(lián)查詢時,保證被關(guān)聯(lián)的字段需要有索引!

8.在varchar字段上建立索引時,必須指定索引長度,沒必要對全字段建立索引,頁面搜索嚴禁左模糊或者全模糊,如果需要則通過搜索引擎來解決。

  • 充分利用好最左前綴匹配特性!

9.利用延遲關(guān)聯(lián)或者子查詢優(yōu)化超多也分場景。

10.如果有全球化需要,均以utf-8編碼。如果需要存儲表情,選擇utf8mb4進行存儲。

2.1值得說明的點

一、利用延遲關(guān)聯(lián)或者子查詢優(yōu)化超多也分場景。

MySQL并不是跳過 offset行,而是取 offset+N行,然后返回放棄前offset行,返回N行,那當(dāng) offset特別大的時候,效率就非常的低下,要么控制返回的總頁數(shù),要么對超過特定閾值的頁數(shù)進行SQL改寫。

例子:

// 優(yōu)化前

SELECT id, cu_id, name, info, biz_type
  , gmt_create, gmt_modified, start_time, end_time, market_type
  , back_leaf_category, item_status, picuture_url
FROM relation
WHERE biz_type = '0'
  AND end_time >= '2014-05-29'
ORDER BY id ASC
LIMIT 149420, 20;


// 優(yōu)化后

SELECT a.*
FROM relation a, (
    SELECT id
    FROM relation
    WHERE biz_type = '0'
      AND end_time >= '2014-05-29'
    ORDER BY id ASC
    LIMIT 149420, 20
  ) b
WHERE a.id = b.id

解釋:其實這里就是通過使用覆蓋索引查詢返回需要的主鍵,再根據(jù)主鍵關(guān)聯(lián)原表獲得需要的數(shù)據(jù)。這樣就是充分利用了索引!

三、未解決的問題

在看《手冊》的時候還有一些知識點沒看過、沒實踐過、涉及到的知識點比較多的,在這里先mark一下,后續(xù)再遇到或者有空的時候再回來補坑~

  • 使用CountDownLatch進行異步轉(zhuǎn)同步操作,每個線程退出前必須調(diào)用 countDown方法,線程執(zhí)行代碼注意 catch 異常,確保 countDown 方法被執(zhí)行到,避免主線程無法執(zhí)行至 await 方法,直到超時才返回結(jié)果。說明: 注意,子線程拋出異常堆棧,不能在主線程 try-catch 到。
  • 對于一寫多讀,是可以解決變量同步問題, 但是如果多寫,同樣無法解決線程安全問題。如果是 count++操作,使用如下類實現(xiàn): AtomicInteger count = new AtomicInteger(); count.addAndGet(1);如果是 JDK8,推薦使用 LongAdder 對象,比 AtomicLong 性能更好(減少樂觀鎖的重試次數(shù))。
  • 使用JDK8的Optional類來防止NPE問題。

當(dāng)然了,如果你有比較好的資料閱讀,也可以在評論區(qū)告訴我。我也會mark住好好看看。

比如說:“3y,我發(fā)現(xiàn)Optional類有篇文章寫得很不錯,url是xxxx(書籍的名稱是xxx)

由于現(xiàn)在沒有一定的經(jīng)驗積累,所以以下的章節(jié)得回頭看:

  • 《手冊》中的“日志規(guī)約”,“工程結(jié)構(gòu)”、“設(shè)計規(guī)范”

最后

看我上面寫的內(nèi)容就知道,除了一些規(guī)范外,還有很多實用的小技巧,這些對我們開發(fā)是有幫助的。我這個階段也有一些沒怎么接觸過的("日志","設(shè)計","二方庫"),這些都需要我在成長中不斷的回看才行。

ps:我會回來補坑的。

引用書上的一句話:很多編程方式客觀上沒有對錯之分,一致性很重要,可讀性很重要,團隊溝通效率很重要。程序員天生需要團隊協(xié)作,而協(xié)作的正能量要放在問題的有效溝通上。個性化應(yīng)盡量表現(xiàn)在系統(tǒng)架構(gòu)和算法效率的提升上,而不是在合作規(guī)范上進行糾纏不休的討論、爭論,最后沒有結(jié)論。

作者(孤盡)在知乎回答的一句話:翻完了不代表記住了,記住了不代表理解了,理解了不代表能夠應(yīng)用上去,真正的知識是實踐,實踐,實踐。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中序列化和反序列化的完整講解

    Java中序列化和反序列化的完整講解

    序列化是將對象轉(zhuǎn)換成二進制字節(jié)流的過程;反序列化是從二進制字節(jié)流中恢復(fù)對象的過程。文中將為大家詳細講講二者的原理與實現(xiàn),需要的可以參考一下
    2022-11-11
  • Java?FTP協(xié)議實現(xiàn)文件下載功能

    Java?FTP協(xié)議實現(xiàn)文件下載功能

    FTP(File?Transfer?Protocol)就是文件傳輸協(xié)議。通過FTP客戶端從遠程FTP服務(wù)器上拷貝文件到本地計算機稱為下載,將本地計算機上的文件復(fù)制到遠程FTP服務(wù)器上稱為上傳,上傳和下載是FTP最常用的兩個功能
    2022-11-11
  • 淺談拋出異常和捕獲異常的一些區(qū)別

    淺談拋出異常和捕獲異常的一些區(qū)別

    這篇文章主要介紹了拋出異常和捕獲異常的一些區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 用IDEA創(chuàng)建SpringBoot項目的詳細步驟記錄

    用IDEA創(chuàng)建SpringBoot項目的詳細步驟記錄

    Idea有著非常簡便的Spring Boot新建過程,同時依靠pom自動下載依賴,下面這篇文章主要給大家介紹了關(guān)于用IDEA創(chuàng)建SpringBoot項目的詳細步驟,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • 詳解Java中類的加載與其初始化

    詳解Java中類的加載與其初始化

    這篇文章主要為大家詳細介紹了Java中類的加載與其初始化的相關(guān)資料,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以了解一下
    2022-12-12
  • JVM之方法返回地址詳解

    JVM之方法返回地址詳解

    這篇文章主要介紹了JVM之方法返回地址詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java 如何實現(xiàn)照片轉(zhuǎn)化為回憶中的照片

    Java 如何實現(xiàn)照片轉(zhuǎn)化為回憶中的照片

    本文主要介紹了可以對圖片進行色彩處理的Java工具類,讓圖片變成回憶中的畫面,主要將圖片做黑白與褐色的處理。代碼具有一定價值,感興趣的童鞋可以關(guān)注一下
    2021-11-11
  • Java應(yīng)用程序開發(fā)學(xué)習(xí)之static關(guān)鍵字應(yīng)用

    Java應(yīng)用程序開發(fā)學(xué)習(xí)之static關(guān)鍵字應(yīng)用

    今天小編就為大家分享一篇關(guān)于Java應(yīng)用程序開發(fā)學(xué)習(xí)之static關(guān)鍵字應(yīng)用,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • @PathParam和@QueryParam區(qū)別簡析

    @PathParam和@QueryParam區(qū)別簡析

    這篇文章主要介紹了@PathParam和@QueryParam區(qū)別,分享了相關(guān)實例代碼,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • 基于IOC容器實現(xiàn)管理mybatis過程解析

    基于IOC容器實現(xiàn)管理mybatis過程解析

    這篇文章主要介紹了基于IOC容器實現(xiàn)管理mybatis過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07

最新評論