最新[學習筆記] 技術筆記要寫給未來的自己看
前言學技術時,很容易一直收藏文章、影片和文件。
但收藏久了會發現,資料越來越多,真正用得到的時候卻常常找不到。
後來我覺得,技術筆記不一定要寫得很完整,但要能讓未來的自己快速想起來:「當時我到底怎麼解的?」
不要只貼連結只貼連結的筆記,短期看起來很快。
例如:
1Docker 教學:https://example.com/docker
但過一段時間後,可能會遇到幾個問題:
忘記這篇連結重點是什麼。
網站失效。
文章內容太長,不知道當初看的是哪一段。
當時的問題情境已經忘了。
所以我會至少補一句自己的摘要。
1這篇主要是在講 Docker volume,解決 container 重建後資料消失的問題。
這樣未來找回來時會快很多。
記錄問題情境技術筆記最有價值的部分,通常不是答案本身,而是問題情境。
例如:
123問題:本機可以連 DB,但部署到測試機後連線失敗。原因:測試機沒有設定正確的 connection string。解法:補上環境變數 Database__ConnectionString。
這種筆記下次遇到類似問題時,非常好用。
因為你不是只記得一個指令,而是記得完整判 ...
[後端] Log 不只是用來看錯誤
前言很多人一開始寫 log,都是在程式壞掉時才想到:
1Console.WriteLine("error");
或是:
1Console.WriteLine(ex.Message);
這當然比完全沒有 log 好,但如果系統真的在線上環境出問題,這種資訊通常還是不夠。
log 的價值不只是「看到錯誤」,更重要的是幫助我們還原當時發生了什麼事。
Log 要能串起流程假設使用者回報:「我按送出之後畫面一直失敗。」
如果 log 只有一行:
1System error
那幾乎沒有辦法判斷問題在哪。
比較有幫助的 log,至少要能讓我們串起流程:
12345Start creating order. userId=123Validate order request completed. userId=123Call payment service. userId=123, orderId=456Payment service timeout. userId=123, orderId=456Create order failed. userId=123, orderId ...
[工程分享] 重構不是看到不順眼就重寫
前言寫程式久了,總會看到一些讓人手癢的程式碼。
變數命名怪怪的、方法太長、邏輯繞來繞去,第一個反應可能是:「我想把它重寫掉。」
但重構不是單純把程式改成自己喜歡的樣子。
重構的目標應該是降低維護成本,而且不能改變原本行為。
重構前先確認目的我覺得重構前要先問:
這段程式現在造成什麼問題?
是讀不懂、難測試、容易出錯,還是擴充困難?
這次重構能解決哪個具體痛點?
有沒有測試可以保護行為不變?
如果答案只是「我覺得不漂亮」,那可能還不到需要重構的程度。
程式碼當然可以追求美感,但在工作專案裡,改動要有足夠理由。
小步調整比大爆改安全重構最怕一次改太多。
例如同時做:
改命名
拆方法
換設計模式
改資料結構
順便修 bug
這樣 review 很難看,出問題也很難定位。
比較安全的方式是小步調整:
1234先補測試再拆出方法再改善命名最後才調整結構
每一步都保持可執行、可驗證。
不要把修 bug 和重構混在一起修 bug 是改變錯誤行為。
重構是不改變行為,只改善內部結構。
如果兩件事混在同一個 commit 或 PR,未來追問題會比較麻煩。
比較好的做法是:
123commit ...
[後端] Cache 可以加速,也可能製造麻煩
前言Cache 是很常聽到的效能優化方式。
簡單來說,就是把常用的結果先存起來,下次需要時不用重新計算或重新查詢。
聽起來很美好,但 Cache 不是免費的。它可以讓系統變快,也可能讓資料變得難以理解。
Cache 解決的是重複成本假設某個 API 每次都要查很多資料、做很多計算,但結果短時間內不太會變。
這時候就可以考慮 Cache。
第一次請求:
1查資料庫 -> 計算 -> 回傳結果 -> 存入 Cache
下一次請求:
1從 Cache 取結果 -> 回傳
如果資料真的不常變,這樣可以省下很多成本。
最大問題是資料何時失效Cache 最麻煩的地方通常不是怎麼存,而是什麼時候要讓它失效。
例如商品資料被修改了,但 Cache 裡還留著舊資料。
使用者看到的就可能是:
12資料庫:新價格頁面:舊價格
這種問題常常比查詢慢更難排查。
所以加入 Cache 前,要先想清楚:
資料可以舊多久?
什麼情況要清掉 Cache?
Cache 清不掉時會造成多大影響?
使用者是否能接受短暫不一致?
TTL 是常見做法TTL 是 Time To Live,也就是 ...
[SQL] Index 是什麼?先用查書目錄的方式理解
前言剛開始接觸資料庫效能問題時,常常會聽到一句話:
「這個查詢很慢,可能要加 index。」
但 index 到底是什麼?為什麼加了它查詢就可能變快?
這篇先不鑽太深的資料結構,而是用比較直覺的方式整理 index 的基本概念。
Index 可以想成書的目錄假設你手上有一本很厚的書,想找「例外處理」這個主題。
如果沒有目錄,你只能從第一頁開始慢慢翻。
但如果有目錄,你可以先查目錄,找到相關章節在哪一頁,再直接翻過去。
資料庫的 index 概念也很像。
沒有 index 時,資料庫可能需要掃描整張表,逐筆檢查資料是否符合條件。
有 index 時,資料庫可以透過索引結構更快找到符合條件的資料。
最常見的使用情境假設有一張 Users 表:
123456CREATE TABLE Users ( Id INT PRIMARY KEY, Email VARCHAR(255), Name VARCHAR(100), CreatedAt DATETIME);
如果系統常常用 Email 查使用者:
123SELECT *FROM UsersWHERE Email = & ...
[Git] 分支策略不用一開始就搞得很複雜
前言很多人在學 Git 分支時,會看到各種流程圖:Git Flow、GitHub Flow、GitLab Flow。
這些流程都有它們的使用情境,但如果專案很小、團隊人數也不多,一開始就套很複雜的分支策略,反而會讓大家卡在流程上。
我覺得分支策略的重點不是名字,而是團隊能不能穩定交付。
最小可用的分支概念最簡單可以先分成兩種:
12main 穩定版本feature 開發中的功能分支
平常開發時,不直接在 main 上改。
而是開一個功能分支:
1git checkout -b feature/add-login-page
完成後送 PR,review 沒問題再合回 main。
這樣至少可以避免開發中的程式直接污染穩定分支。
分支名稱要看得懂分支名稱不用太華麗,但要能看出用途。
例如:
1234feature/add-search-pagefix/login-timeoutchore/update-dependenciesdocs/cloudflare-pages-guide
看到名稱時,至少能知道這個分支大概在做什麼。
比起:
1234testnewfix2hikari-b ...
[API] 錯誤處理不要只回傳失敗
前言在寫 API 的時候,很容易把成功流程寫得很完整,但錯誤流程只簡單回一句「失敗」。
例如:
1234{ "success": false, "message": "error"}
這種回應對使用者不友善,對前端不友善,對未來要查問題的自己也不友善。
這篇整理一下,我覺得 API 錯誤處理至少可以注意的幾件事。
錯誤訊息要能被理解錯誤訊息的第一個目的,是讓呼叫端知道發生了什麼事。
例如登入失敗時,如果只回:
123{ "message": "failed"}
前端很難判斷要顯示什麼,也不知道是帳號不存在、密碼錯誤,還是系統暫時異常。
可以改成比較明確的格式:
1234{ "code": "INVALID_CREDENTIALS", "message": "帳號或密碼錯誤"}
message 給人看,code 給程式判斷。
這樣前端可 ...
[API] 為什麼有時候需要版本控管?
前言API 一開始通常都很單純。
前端要什麼,後端就回什麼。
但當系統開始被更多人使用,API 一旦改動,就可能影響既有前端、App、第三方串接,甚至是已經發布出去的舊版本程式。
這時候就會遇到一個問題:API 要怎麼改,才不會把舊使用者弄壞?
什麼情況會破壞相容性?不是所有 API 修改都需要新版本。
例如新增一個 response 欄位,多數情況下不會破壞舊呼叫端:
12345{ "id": 1, "name": "Hikari", "email": "hikari@example.com"}
但以下這些改動就比較危險:
移除既有欄位。
改變欄位型別。
改變欄位名稱。
改變錯誤格式。
改變必要參數。
改變原本的業務規則。
例如原本 id 是數字:
123{ "id": 1}
突然改成字串:
123{ "id": "U001"}
對後端來說可能只是 ...
[開發筆記] 為什麼設定值不要直接寫死在程式裡?
前言在寫小工具或練習專案時,把設定值直接寫在程式裡通常不會有太大問題。
例如:
12var apiUrl = "https://api.example.com";var timeout = 30;
但當專案開始部署到不同環境,像是本機、測試機、正式機,這種寫法就很容易變成維護上的麻煩。
這篇整理一下,為什麼我現在會盡量避免把設定值寫死在程式碼裡。
寫死設定值的問題最常見的問題是:不同環境需要不同設定。
例如:
環境
API URL
local
http://localhost:5000
staging
https://staging-api.example.com
production
https://api.example.com
如果這些設定都寫死在程式裡,每次切換環境都要改程式碼。
這會帶來幾個風險:
容易把測試環境設定部署到正式環境。
每次改設定都需要重新打包。
敏感資訊可能被 commit 到 Git。
其他開發者不容易知道哪些值應該依環境調整。
寫死設定看似方便,但後面常常會把成本還回來。
設定值應該和程式邏輯分開比較好的方 ...
[工程分享] Code Review 不是只挑錯
前言剛開始接觸 Code Review 時,很容易把它想成「找別人錯誤」的流程。
但實際工作一段時間後,我覺得 Code Review 更像是團隊同步理解的過程。
它不只是為了找 bug,也是在確認這段程式碼是否容易維護、是否符合團隊習慣,以及未來的人能不能接得下去。
先理解需求再看程式碼Review 前,我會先看這次變更想解決什麼問題。
如果沒有先理解需求,很容易只針對語法或個人偏好留言。
比較好的順序是:
這個 PR 想解決什麼問題?
使用者或系統行為會怎麼改變?
有沒有影響既有流程?
測試是否覆蓋到主要情境?
先知道目的,再看實作,才比較能判斷這段程式碼是否合理。
不要只看能不能跑程式能跑只是基本。
Code Review 還可以多看幾件事:
命名是否清楚?
是否有重複邏輯?
錯誤處理是否完整?
邊界情境是否有考慮?
是否和既有架構一致?
有沒有不必要的複雜度?
好的 Review 不是挑剔,而是幫這段程式碼在未來少出一點問題。
留言要具體我覺得 Code Review 留言最怕太抽象。
例如:
1這樣不好
這種留言對作者幫助不大。
比較好的寫法是:
12這裡如果 us ...