在寫 concurrency 程式時,通常會用 lock、synchronized 等機制保護存取共享資源的程式片段,確保一次只有一個 thread 可以使用這些共享資源。但若是共享資源不是一個程式片段而僅僅只是一個變數,使用 lock、synchronized 等機制就會顯得太笨重,甚至拖慢效能。以下面的 Golang 程式來說:

profiling 這段程式以後會發現 CPU 時間幾乎都花在 Lock 上面,下為 profiling 結果:

為了提升效能,保護單一變數在多個 thread 共用會用 lock-free 等手法。而在撰寫 concurrency code 處理共享變數問題時,有三件事要注意:原子性 (atomicity)、可見性 (visibility) 以及有序性 (or …


When writing concurrency code, we often use mechanisms like Lock or Synchronized to protect share resources (sometimes it’s a piece of code). What if we merely want to protect one variable but not a whole code? It’s too expensive to use Lock or Synchronized to protect just one variable. Let’s see one simple Golang code:

And profiling of the code will tell you how expensive Lock cost, as shown below:

You can see that lots of CPU time were wasted in Lock.

To improve performance, often we would not use lock if we just want to protect one variable…


I always fell exhausting while reviewing code

It’s an exhausting job for code review. When you are reviewing the complex business rule, there are always some common small code smell spread in new code and may be ignored by accident。Take blow java snippet code as an example,how many common code smells do you find?

The answer is 5.

Line 4–10 is not thread-safe. It may occur some bug in multi-thread.

Line 7 should remove <String> since Java had introduced diamond operator in Java7.

Line 18, 26 should return directly.

But how much time do you spend in finding out all these code smells? …


Code Review 總讓人感到費神

code review 是一件很耗費心神的工作。在關注業務邏輯的合理性和正確性的同時很容易不小心忽略一些小錯誤。以下面的 java snippet code 為例,有幾個常見的錯誤?

答案是 5 個。
4~10 行不是 thread-safe,在 multi thread 有可能產生 bug。
第 7 行的 <String> 可以拿掉,Java7 以上的版本可以自動推斷泛型類型。
18、26 行都可以直接 return。

你花了多少時間找出這些錯誤,一分鐘?兩分鐘?
試著想像一下,如果這些小錯誤散佈在一次新功能的 commit 中,藏在各個業務邏輯之中,你需要花多少心力和時間才能一一揪出來?

以我自己而言,我無法保證每次 code review 時都能抓到這些錯誤,尤其在手上有其他事,同事又因為 …


Recently, I notice that there is a Golang’s PR with title: runtime: speed up receive on empty closed channel. PR comments is:

Currently, nonblocking receive on an open channel is about
700 times faster than nonblocking receive on a closed channel.
This change makes closed channels equally fast.

I was curious about how the PR solve this problem, so I spent a few time tracing this PR’s changing code. Before explaining it, let’s introduce how channel work.

How channel work

The data structure of channel is like that:

Every time sending data to channel, golang would write data to the element which sendx…


意外發現 golang 在近兩個月有一個 PR 的標題寫 runtime: speed up receive on empty closed channelPR 的註解寫著:

Currently, nonblocking receive on an open channel is about
700 times faster than nonblocking receive on a closed channel.
This change makes closed channels equally fast.

目前用 noblocking 從 open channel 收資料約速度比 close channel 速度快約 700 倍。
這個改動可以讓兩者一樣快。

追完 code 以後發現這手法很意 …


Clustered Index (Primary Index)

The clustered index is more a data storage to store records than a mere index.

InnoDB using the B-Tree structure to organize clustered index. Every node is a page which is the minimum unit InnoDB stores records. Non-leaf nodes store the value of the key and pointer to child nodes. Leaf nodes store records and pointers to neighbor leaf nodes. Here is a simple graph to illustrate:

InnoDB store records in the key order and each leaf node links to its neighbor leaf nodes. That comes two advantage:

  1. Keep related records close together so you can get related records by…


Clustered Index (primary Index)

clustered index 與其說是 index, 不如說是 InnoDB 用來儲存資料的結構更恰當。

Clustered Index 採用 B-Tree 資料結構,每個 node 都是一個 page (InnoDB 存資料的最小單位); node 存 key 的值和指向 child node 的指標,leaf node 則存 row data 和指向鄰近 node 的指標,下面是一個簡單的示意圖:

資料會依照 clustered index 的 key 值排序,鄰近的 node 彼此透過 pointer 連接,這樣有兩個好處:

  1. 關係相近的資料會被集中在同一個 page,讀取相關資料的時候只 load 幾個 page 就好。例如上圖若要讀取 key 5 和 key 6 的資料,只要 lo …


Our team is used to generating the API documentation by apiDoc. But as time goes through, new features were added to codebase or bugs were fixed, Our API documentation is out of date.

While I was correcting the API documentation, I had to trace the code committed a long time ago to check the behavior of the program. That is a tedious and boring task. So I think: If I update the documentation in the meantime of committing code, I could do that more fastly with more confidence. …


我們團隊一直用 apiDoc 來產生 API 文件。但隨著數次迭代開發, API 文件已經有部分內容和程式不一致,於是我開始動手整理 API 文件。

更新文件的過程中要一直 trace 許久之前 commit 的 code,這過程不僅繁瑣而且相當惱人。我在整理的過程中一直想:如果在 code commit 時就知道程式行為和文件描述不一致,可以趁著記憶猶新的當下立即處理,這樣就不用定期 review 文件了!

怎麼開始?

我第一個想法就是用自動測試幫我檢查文件是否和程式一致:透過文件去產生測試案例。為此我需要先達成幾個前提:

  1. API 文件:該 API 文件格式必須可以很方便的用程式 parse。
  2. 測試工具:這個工具必須可以把測試案例寫成腳本用 command line 執行,最後產出測試報告。
  3. 預警:當測試失敗時, …

Genchi Lu

I am Genchi, a backend engineer in Taiwan.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store