1. 程式人生 > 實用技巧 >ARTS-WEEK-008

ARTS-WEEK-008

Algorithm:

96: Unique Binary Search Trees (Medium)

這道題有幾個關鍵點,1首先需要充分理解 BST 二叉搜尋樹,左子樹都小於、右子樹都大於當前節點,因此每確定一個根節點,其種類數可以固定計算,等於左子樹種類數乘以右子樹種類數。2抽象和推匯出遞迴公式,g(n) 代表數量為n個節點的樹的種類數(即題目要求的 1 到 n節點),f(i, n) 代表數量為n個節點的樹中,以其中某節點 i 為根時的樹的種類數。於是 g(n) = ∑ f(i, n), 而 f(n) = g(i - 1) * g(n - i),整體推匯出 g(n) = ∑ g(i - 1) * g(n - i)。3最後一點,利用動態規劃思想,遞迴公式可以轉化為從下到上的遞推形式,這裡技巧是觀察求和公式,每個 g(n) 都依賴 g(n-1),反過來想就是可以從小到大依次計算,結果放到 memo 中複用。

public int numTrees(int n) {
  // g(n) = g(0)*g(n-1) + g(1)*g(n-2) + ... + g(n-1)*g(0)
  int[] memo = new int[n + 1];
  memo[0] = 1;
  memo[1] = 1;
  for (int i = 2; i < n + 1; i++) {
    for (int j = 0; j < i; j++) {
      memo[i] += memo[j] * memo[i - j - 1];
    }
  }
  return memo[n];
}

Review:

The Happens-Before Relation

Happens-Before 關係,比如 A happens-before B,並不是時間關係,不是現實中的前後順序關係,僅僅是語言規範中的一種概念,這是一種擔保,即 A 對記憶體的影響對 B 是一定可見的。只有當語言規範規定了什麼情況下保證 happens-before 時我們才能確保可見性,除此之外一切都是不確定的。最基本的一個 happens-before 關係是同一執行緒中 A 語句在 B 語句之前,則 A happens-before B。

文中舉出了兩個典型的例子,分別是:1有 happens-before 關係但程式(彙編指令)實際先執行後者;2兩個執行緒中程式 A B 和 C D 執行順序都已確定時,比如 C 通過 IF 判斷道 B 已執行,但是 D 依然可能讀到 A 沒有執行的情況,因為 A D 之間沒有 happens-before 關係。

Tip:

一次服務端出現大量 CLOSE_WAIT 連線的分析

總結去年的一次線上問題,一個高 TPS 的應用增加了傳送MQ邏輯後,在請求高峰時個別機器出現請求處理緩慢(TP99飆升到幾十秒幾百秒)、CPU 使用率飆升、網路連線中 CLOSE_WAIT 數量飆升到8000,最後新的請求無法處理新請求,形成 TOMCAT 卡死的狀態,該例項重啟後可以恢復,但是不斷有其他例項出現這樣的問題,最後選擇關閉 MQ 傳送後問題解決。

首先每個請求都會呼叫傳送 MQ 方法,因為用的是非同步傳送方式覺得不會影響主邏輯,但是這裡肯定有問題,通過原始碼跟蹤,非同步傳送是指使用 netty 同步的 channel.writeAndFlush().addListener(xx) 後就結束邏輯,通過 Linstener 非同步接收 Broker 返回的 ACK 資訊,如果有各種原因導致傳送太慢就會形成反壓,這裡應該通過帶有拋棄策略執行緒池和佇列傳送訊息,確保不影響主流程。但是有一個一直不明白的地方是為什麼產生那麼多 close_wait,以及為什麼 tomcat 不會釋放連線,導致新連線進不來?

TCP Connection Termination

首先 close_wait 在 TCP 關閉圖中處於右側,是被動關閉時傳送完對方 FIN 的 ACK 後,進入釋放資源的階段,之後再發送自己的 FIN 通知對方自己要關閉。這裡因果鏈是 MQ 傳送問題,導致 http 請求處理慢,當達到對方 client 的超時後,對方關閉連線,於是我們成為被關閉方,而此時 TOMCAT 不會因為收到 FIN 就 Kill 該執行緒,導致該連線因為 MQ 積壓始終佔用著,業務一直處理中,很快就把 TOMCAT 業務執行緒用完!但是實際上TOMCAT 業務執行緒池有 350 個,established 有 350 個,而 close_wait 有 8000 多個,這裡要考慮 TOMCAT 到底是如何使用 NIO 處理和關閉連線了。

深度解讀Tomcat中的NIO模型

Share:

What is Timeboxing? 5 Questions (and Answers) About This Productivity Strategy

時間盒方法強調安排任務計劃時不是以待辦項作為主體、而是以時間段作為主體。比如在清單中列出要做的A、B、C這是傳統的方法,時間盒方法則是列出 A - 2 * 30分鐘、B - 1 * 30 分鐘、C - 3 * 30分鐘這類清單。這樣在時間開始後專心完成事項並在每個時間盒結束時重新評估,當無法完成時不斷盡力調整,以求完成最重要和最核心的部分,捨棄其他部分。

該方法最優價值的地方在於:1 幫助專注,2 避免困難任務拖延或龐大任務無法啟動,3 不斷評估,幫助改進,關注價值,4 避免一個任務無法完成影響其他任務。