20210404-20210409技術週報

哈嘍哈嘍你們猴,我是把代碼寫成bug的大頭菜。公衆號:大頭菜技術(bigheadit)。原創不易,但歡迎轉載。

最近這個星期。主要兩件事兒:java

  • 工做遇到的bug和總結
  • 從新梳理JVM的基礎知識

工做遇到的bug和總結

最近這兩週,由於作了4個需求,都是關於黑白名單的。spring

因而我就打算,把這些黑白名單的需求,好比有關於C端用戶的白名單,C端用戶的黑名單,B端用戶的白名單,B端用戶的黑名單,我打算直接抽象一點,把4個需求抽象整合爲一個需求。每一個黑白名單需求:都有增長黑白名單,刪除黑白名單,查詢黑白名單三種不一樣的接口。tomcat

由於以前,已經有C端用戶的白名單了。可是對應的表的設計沒有考慮好拓展性,無法兼容C端用戶的黑名單等需求。所以須要從新設計表。併發

新表的設計關鍵字段:jvm

  • role:角色分佈式

    • 1:C端用戶
    • 2:B端用戶
  • type:黑白名單微服務

    • 1:白名單
    • 2:黑名單
  • status:數據狀態工具

    • 1:生效
    • 2:失效
  • businessCode:業務線性能

    • 1:電商業務線
    • 2:外賣業務線
    • 3:物流業務線

從新設計後,表的可拓展性大大提升。但業務的複雜度和開發複雜度也大大提升。魚和熊掌不可兼得嘛。正常!優化

其實,把4個需求,抽象合併爲一個需求,是下降了開發成本的,也對業務作了比較好的抽象,能夠爲之後其餘相似的需求,好比:新增一條業務線D的白名單。

這樣子,其實就是,在枚舉上增長多一個枚舉。在接口入參上,改變一下參數值便可。核心代碼,幾乎不用變。

若是考慮某些須要定製化的黑白名單。咱們採用策略工廠模式便可。這樣子,代碼的可讀性大大提升,同時也知足開閉原則。

bug的潛在

由於涉及到表的從新設計,所以舊錶的數據,也須要作同步遷移。數據遷移,這種寫一下SQL語句就好。沒什麼特別的。

關鍵點:我忘了誰在使用舊錶。

就是哪些接口調用了獲取舊錶的數據。當時,的確忘了這茬,也沒作兼容。所以,bug就來了。

此次,也真算是,把代碼寫成bug了哈哈哈哈。

影響的範圍:調用了訪問舊錶數據的接口。

對於此次bug的影響,我作了一些總結點
  • 涉及到表數據遷移時,須要考慮兼容性,包括讀和寫,只要漏掉其中一個,bug確定就會有
  • 若是真的實現,無法兼容原來的接口,這個時候,最好在大羣裏,廣播通知一下各個調用方,好讓他們儘快切換接口。
  • 在分佈式項目中,其實有一個痛點:就是接口不知道被哪一個微服務調用了。好比:服務A的A接口,被服務B的B接口調用了。可是由於這是2個不一樣微服務,無法找對應的調用鏈。我目前也沒找到好的辦法來解決微服務的調用鏈問題。

從新梳理JVM的基礎知識

最近從新梳理了一下JVM的基礎知識。相關筆記以下:

  • Q:咱們平時寫的JAVA代碼是怎麼運行起來的
  • A:

    • 一、把.java代碼編譯爲.class代碼
    • 二、類加載器把.class代碼加載到jvm中,是字節碼執行引擎按需加載的,不是一次性加載所有.class代碼
    • 三、字節碼執行引擎執行.class代碼
  • Q:既然.java代碼能編譯成.class代碼後運行,那麼確定也能夠把.class代碼反編譯爲.java代碼。若是這樣子的話,黑客拿到.class代碼後,就能夠經過反編譯拿到核心.java代碼。對於這個問題,應該怎麼解決。
  • A:

    • 一、代碼混淆工具
    • 二、能夠自定義類加載器。而後用公鑰和私鑰作加密。
  • Q:JVM是什麼?
  • A:JVM本質上也是一個程序,負責運行java編譯好的class代碼
  • Q:JVM跟咱們平時運行的機器上的系統有什麼區別?
  • A:JVM具備跨平臺。系統不具有跨平臺。
  • Q:類加載器的概念
  • A:把編譯好的class文件按需加載到JVMzhong
  • Q:什麼是字節碼執行引擎
  • A:針對加載進內存的class代碼進行運行
  • Q:類加載的流程
  • A:

    • 一、JVM通常會在使用到具體某個類時,纔會去加載對應的類。按需加載
    • 二、加載到JVM後,須要對class代碼進行語法驗證操做
    • 三、驗證經過後,須要對類分配空間,對類變量分配空間,而且賦予默認值。
    • 四、解析,就是符號引用替換爲直接引用,說了等於沒說。這個階段,對咱們java開發沒多大用處。跳過吧
  • Q:何時會初始化一個類?
  • A:new 類()的實例化的對象的時候,就會觸發從加載到初始化的全過程。若是是包含main方法的類,必須啓動時,就立馬對類進行初始化。若是這個類還有父類,且父類還沒被加載和初始化,這時候,須要先加載和初始化其父類,完成父類的初始化後,再回去初始化本身。
  • Q:爲何不把lib/ext的jar一塊兒放在啓動類加載器中一塊兒加載?
  • A:

    • 一、爲了區分同名類
    • 二、容許你再一個jvm裏運行不一樣的應用程序
    • 三、對不一樣的類庫進行增強。
  • Q:線程、java虛擬機棧、棧幀、局部變量、方法的關係
  • A:

    • 一個線程,有一個java虛擬機棧。
    • 一個線程,有一個程序計數器
    • 一個java虛擬機棧,有多個棧幀
    • 一個線程,每訪問一個方法,就建立一個棧幀。
    • 一個棧幀,有多個局部變量。
  • Q:spring boot中怎麼設置JVM參數?
  • A:啓動的時候設置
  • Q:tomcat 中怎麼設置JVM參數?
  • A:catalina.sh 文件配置參數
  • Q:系統併發量大時,系統會變慢,進而致使什麼?
  • A:系統併發量大的時候,會有一些請求特別慢,進而引用着新生代的對象,可是GC時沒法回收,由於還被引用着。屢次minor gc後,特別慢的請求對應的對象,會進入老年代。進而很快把老年代填滿,進而致使頻繁的Full GC。
  • Q:什麼狀況JVM內存中的一個對象會被回收?
  • A:GC Root。好比局部變量和靜態變量。此外,還分強引用,軟引用。虛引用。

    • 強引用,只要被GC Root引用,就必定不會被回收。
    • 軟引用,是在垃圾回收後,仍然不夠內存空間,纔會被回收,不論是否被引用。
    • 虛引用,垃圾回收,就會被回收,不論是否被引用。
  • Q:對象在新生代的分配?
  • A:優先在eden區分配
  • Q:何時會觸發Minor GC
  • A:eden區滿了。
  • Q:觸發minor gc的狀況有:
  • A:

    • 一、新生代現有對象小於老年代剩餘內存,即老年代空間足以支撐可能晉升的對象
    • 二、狀況1不成立,查看設置了空間擔保且擔保成功
  • 什麼狀況下Minor GC以前會提早觸發Full GC?
  • A:

    • 一、新生代的所有對象大小若是大於老年代的剩餘空間
    • 二、沒有空間擔保機制
    • 三、擔保失敗
  • Q:什麼狀況下會直接觸發Minor GC
  • A:eden區滿了
  • Q:Minor GC以後有哪幾種狀況對象會進入老年代
  • A:

    • 一、survivor區不能容納eden區的存活對象
    • 二、動態年齡判斷:survivor區的同一年齡對象超過survivior空間的一半
  • Q:優化系統性能的思路?
  • A 核心思路:儘量讓對象不要過快進入老年代。減小老年代的full gc。儘量讓對象在新生代就被GC回收。
  • Q:如何讓對象不要過快進入老年代?
  • A:survivor要有足夠的空間。試想一下,若是survivor區,空間不夠,對象就會直接進入老年代。即便夠,可是超過survivor區的一半,也會由於動態年齡判斷,而直接進入老年代。
相關文章
相關標籤/搜索