想法與洞見

探索 AI 優先開發、編碼護欄和可處置架構。

你的 Gherkin 規格正在對你說謊

一旦你指望人類手動更新,Gherkin 規格就會立刻脫節。以下是如何將檢查流程自動化,讓 feature 檔案始終保持誠實。

你的 Gherkin 規格正在對你說謊。 不是故意的。它們起初是忠實的。但六個衝刺過後,有人重構了結帳流程,卻忘了更新 這個 step。 檔案仍然通過,因為 step definition 還在。它只是呼叫了一段不再符合 scenario 實際描述的程式碼。你拿到了綠燈測試和虛假的信心。這就是 BDD…

編譯器檢查語法,測試應該檢查架構

大多數團隊把架構規則寫在 wiki 裡。這裡教你怎麼把它們變成可執行的測試,當依賴圖偏離設計時就讓 CI 失敗。

你的測試套件會驗證 在給定正確輸入時回傳 42。但它不會驗證 是否被允許 import 。編譯器對兩者都接受。你的單元測試對兩者也接受。但其中之一是架構違規,六個月後會讓你花上一整週重構。 這就是盲點。我們為邏輯寫測試,卻假設結構會自動維持。它不會。…

你的 domain layer 引用了 Postgres。你的 CI 完全沒意見。

Clean architecture 的圖在白板上畫起來很漂亮。這裡教你怎麼讓 build pipeline 自動執行 dependency direction,確保 domain code 絕對碰不到 infrastructure。

團隊裡有人剛剛在 裡引用了 。PR 可以編譯過。測試全綠。Code review 有三百行,沒人發現。 三個月後,你想把 domain logic 抽成 shared package。你抽不出來。它依賴 Postgres 的型別、connection pooling 邏輯,還有一個只在 monolith 裡存在的…

你的架構圖早已是謊言

架構文件從你存檔的那一刻起就開始腐敗。以下說明如何透過程式碼產生的圖表、ADR 與自動化架構測試,讓文件保持誠實。

我在 wiki 裡看過的每一張架構圖都是錯的。不是明顯的錯,而是安靜地、漸進地錯。標示為「Auth」的服務在六個月前就被拆成三個微服務。標示為「sync call」的箭頭現在已經透過 queue 變成 async。標示為「PostgreSQL」的資料庫在某次火災演練中被遷移到別的東西,但沒人更新那個方框。…

你的重試迴路假設第一次請求失敗了。它大概沒有。

超時或當機不代表你的 API 請求遺失了。以下是 idempotency keys 如何讓重試變得安全,以及真正能防止重複的儲存模式。

你的服務在處理 請求到一半時當機了。客戶端看到超時並重試。現在你有兩筆扣款。客戶很生氣。資料庫是一致的。你的商業邏輯不是。 這不是邊緣案例。這是分散式系統的預設行為。網路會丟封包。container 會在請求處理到一半時被 OOM-killed。負載平衡器會對已經抵達後端的請求回傳 502。如果你的 API…

比你的进程更長命的 lock:分散式租約的實際運作原理

記憶體中的mutex會在伺服器重啟後消失。本文說明具有 fencing token 與 TTL 的分散式租約如何防止當機後的重複執行,以及它們仍然會失效的地方。

你的 撐不過 。它也撐不過 OOM、部署推出或節點重啟。程序結束的瞬間,lock 就消失了。如果那把 lock保護的是一個排程任務、資料遷移或領導者選舉,你現在會有兩個程序都認為自己是唯一在執行的那個。 這不是你的mutex有 bug。這是類別錯誤。程序本地的lock無法保護叢集範圍的資源。…

沒有 goroutine、沒有 timer、也沒有背景開銷的斷路器

大多數斷路器函式庫會產生背景執行緒來探測恢復狀態。你並不需要它們。這裡介紹一種由請求驅動的設計,能在不犧牲正確性的前提下,消除所有背景開銷。

我審閱過的每一個 production 級斷路器,最終都會產生一個背景執行緒。它可能是 Go 的 goroutine、Java 的 ,或是 Rust 的 tokio task。工作內容永遠一樣:每隔幾秒醒來一次,檢查下游服務是否已恢復,然後從 OPEN 切換回 CLOSED。…

你的 Web Service 有一條 Graceful Shutdown 路徑。那就是 Bug。

Crash-only software 把每一次失敗都當成 crash,把每一次啟動都當成 recovery。對 Web Service 來說,這意味著刪掉你的 shutdown 邏輯,並設計出能撐過 kill -9 的狀態。

你的 Web Service 有一個 shutdown handler。它會 flush buffer、關閉連線、寫入 checkpoint。你也許測試過一次。在生產環境,它大概一年只在計畫性部署時執行一次。其他時候,你的服務死於 OOM kill、node eviction、斷電,或是部署超時後被 SIGKILL。…

當你不懂 mutant 改了什麼時,如何殺掉一個存活下來的 mutant

Mutation testing 發現了一個 survivor,但你完全不知道這個 mutation 到底做了什麼。這裡有一個逐步方法,讓你在還沒理解 mutant 之前就能寫出正確的 test。

你的 mutation testing 報告充滿了 survivors,其中至少有一個讓你完全摸不著頭緒。 工具說它在第 47 行把 翻成了 ,或是把整個 conditional block 替換成 ,或是 mutate 了一個你根本不知道正在被測試的 string literal。你把 diff…

Auth 程式碼需要 90% mutation coverage。你的 string utils 不需要。

為何在整個 codebase 強制套用單一 mutation score 是錯的,以及如何根據實際風險設定各模組的門檻。

在整個 codebase 強制套用單一的 mutation score,是讓團隊討厭寫測試的絕招。 拿 PIT 或 Stryker 跑一個典型的 repo,你會看到同樣的模式:auth 模組只有 40%,string utilities 衝到 95%,ORM 層則卡在 60 幾趴。本能反應是設一個 70%…