1.Algorithm:每週至少做一個 leetcode 的演算法題
2.Review:閱讀並點評至少一篇英文技術文章
3.Tip:學習至少一個技術技巧
4.Share:分享一篇有觀點和思考的技術文章
考研真難 , 卷的厲害 , 還能怎麼著 . 接著熬 , 繼續更新
以下是各項的情況:
Algorithm
連結:[LeetCode-442]-Find All Duplicates in an Array
題意:
給定一個連結串列: 1->2->3->4->5, 和 n = 2. 當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.
分析:
以前做過一個類似題目 , 用hashmap 做一個對照詞典 , 有重複的就返回
class Solution { public int findRepeatNumber(int[] nums) { HashSet dictionary = new HashSet<Integer>(); for (int num:nums){ if(dictionary.contains(num)){ return num; } dictionary.add(num); } return -1; } }
照著做就完事
class Solution { public List<Integer> findDuplicates(int[] nums) { List<Integer> res = new ArrayList<>(); if (nums == null || nums.length == 0) { return res; } // 一樣的hash for (int i = 0; i < nums.length; i++) { while (nums[nums[i] - 1] != nums[i]) { swap(nums, i, nums[i] - 1); } } // 詞典記錄不重複 for (int i = 0; i < nums.length; i++) { if (nums[i] != i + 1) { res.add(nums[i]); } } return res; } public void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } }
Review
很多 歸納一下就是 :
始終嚴格的浮點語義、外部函式和記憶體 API 以及偽隨機數生成器的統一 API
功能包括 :
特定於上下文的反序列化過濾器支援 (允許應用程式通過呼叫 JVM 範圍的過濾器工廠來配置特定於上下文和動態選擇的反序列化過濾器),這是一項安全增強 (反序列化過濾器被引入Java 9使應用程式和庫程式碼能夠在反序列化之前驗證傳入的資料流。此程式碼 java.io.ObjectInputFilter
在建立反序列化流時提供驗證邏輯。但是,依賴流的建立者來明確請求驗證有侷限性。JDK Enhancement Proposal 290通過引入可通過 API、系統屬性或安全屬性設定的 JVM 範圍的反序列化過濾器解決了這些限制,但這種方法也有侷限性,尤其是在複雜的應用程式中。更好的方法是配置每個流過濾器,這樣它們就不需要每個流建立者的參與。always-strict 浮點語義的恢復,浮點運算將變得始終嚴格)
模式匹配 switch 語句 ( switch
針對多個模式測試表示式和語句,每個模式都有特定的操作。 引入兩種模式:guarded patterns
,允許模式匹配邏輯用任意布林表示式和 parenthesized patterns . 在JDK 16 中,
)instanceof
運算子被擴充套件為採用型別模式並執行模式匹配。提議的適度擴充套件允許簡化熟悉的 instanceof-and-cast 習語。
刪除遠端方法呼叫 (RMI) 啟用機制 (同時保留 RMI 的其餘部分。RMI 啟用機制已過時和廢棄,在 JDK 15 中不推薦使用。)
增強的偽隨機數生成器將為偽隨機數生成器 ( PRNG ) 提供新的介面型別和實現,包括可跳轉的 PRNG 和額外的一類可拆分 PRNG 演算法 ( LXM )。新介面 RandomGenerator
將為所有現有的和新的 PRNG 提供統一的 API。將提供四個專門的 RandomGenerator 介面。推動該計劃的重點是 Java 偽隨機數生成領域的多個改進領域。 該計劃的目標包括:
- 使在應用程式中交替使用各種 PRNG 演算法變得更容易。
- 改進了對基於流的程式設計的支援,提供了 PRNG 物件流。
- 消除現有 PRNG 類中的程式碼重複。
- 保留類的現有行為
java.util.Random
。
還有些其他的 , 就不翻譯了。
Tip
這幾天朋友問了個問題: 請求一個網站很久超時,對應後臺介面作用是匯出大量資料的介面應用,請求匯出一大批資料要執行很久,但是 http 等待到限制的時間後,連結就會斷開並顯示請求超時 , 而後臺應用是一個子執行緒在處理 ,這時候這個子執行緒是隨著連結斷開而結束呢還是繼續做完未完成任務 ? (我瀏覽器請求後臺服務,後臺執行很長時間,但是瀏覽器請求超時了,這時候,後臺服務還沒執行完,該子執行緒如何處理?繼續還是?)
我很快回答了:看策略,設定的失敗處理。同步就掛起等待 , 非同步看你處理邏輯怎麼寫的。要寫銷燬就銷燬 等待就掛起 。
很快朋友就追問:那預設的 Tomcat 策略是什麼?R
這難倒我了,平常業務都是自己寫失敗處理。不過,要讓我們自己 @override 寫失敗處理,我猜預設的應該很辣雞,Tomcat 要是處理的好,就不會有 RocketMQ 用守護執行緒輪詢對應執行緒強制結束了。所以首先我先大膽猜:繼續執行,但是返回資料沒對應的接受,所以一般自己處理都會輪詢對應執行緒未響應直接銷燬,然後等下次響應。
不過猜的不算數,我想看看原本的策略是什麼? 於是首先發現很有意思的問題 現在用的 springboot,cloud 都是用 maven 或者 gradle ,都是整合了 Tomcat 的 。那麼現在用的 maven 3.6 對應的 Tomcat 版本是多少 ?它的對應關係怎麼樣 ? http://tomcat.apache.org/whichversion.html 查詢
接著查詢 http://maven.apache.org/docs/history.html
很有趣,得出結論 tomcat 版本與 maven 版本沒有直接的關係,tomcat 是 java 寫的一個 web 容器,maven 是 java 寫的一個專案,他們都需要 Java 環境執行 。 再繼續我們的問題 ,對應的 Tomcat 處理策略是哪個包 ?
如果有看的讀者 可以自己去嘗試閱讀閱讀原始碼, 提高能力。 這裡我不多BB直接給答案:
1. tomcat 8 訊息處理 從org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run 開始 , socket 處理 就是記錄在日誌裡
2. 然後再去 getWorkerThread().assign(socket) 分了兩部 先線上程池取一個執行緒啟動 再去 assign(socket)分配socket , 用了同步鎖
3.再去 IoEndpoint$Worker#run
拋異常才結束
果然我的猜測是正確的 。預設就是等待掛起睡 1000ms,後臺繼續跑著 , 除非異常 比如後臺跑時間太久 記憶體溢位 記到日誌檔案裡 然後 close soctet
Share
暫時沒找到合適的 , 遲點再補 。