編程不僅是敲代碼,更是一系列決策的累積:命名、介面、抽象層次、錯誤處理……本文通過三個經典思考題,揭示資深工程師如何從「常識」、「一致性」、「經濟帳」三個維度審視設計選擇。
現象:
void *p = MemAlloc(6); MemFree(&p);— 釋放函數要求傳「指標的指標」。問題:違背
malloc/free通用約定,極易誤用。優勢:
MemFree內部可將*p = NULL,防止野指標。結論:API 設計必須符合領域常識。置 NULL 的收益不足以抵消認知負擔。建議:
MemFree(p)+ 文檔規範「調用者自行置 NULL」,或提供MemFreeNull(&p)顯式版本。
分析:
malloc= memory allocate,對應釋放應為 memory free →mfree。實際卻是free,丟失前綴一致性。重命名建議:
mem_alloc / mem_free或m_alloc / m_free。統一前綴帶來:
- IDE 自動補全分組清晰
- grep / 靜態分析規則簡單
- 跨語言綁定 (Python/Rust/Go) 映射直觀
現狀:
socket(AF_INET, SOCK_STREAM, 0)→ 需記住「流=TCP、數據報=UDP」映射,引入額外認知層。另一種設計:將 Socket 納入
/dev或/net目錄層級:int fd = open("/net/ipv4/tcp/3344", O_CREAT | O_RDWR); // TCP port 3344 int fd = open("/net/ipv4/udp/3344", O_CREAT | O_RDWR); // UDP port 3344優勢:
- 消除「流/數據報」抽象映射,直接用協議名語義化
- 復用
open/close/read/write/poll通用文件介面,API 總量減少- 權限控制直接套用文件系統 ACL,無需額外機制
- 工具鏈通用:
ls /net/ipv4/tcp即可列出所有監聽 TCP 端口現實約束:POSIX 標準化、BSD Socket 歷史包袱、跨平台一致性,導致演進極其緩慢。但
io_uring、AF_XDP、systemd socket activation正在逐步彌合這一鴻溝。
| 維度 | 初級視角 | 資深視角 |
|---|---|---|
| 命名 | 縮寫、個人偏好 | 領域通用詞彙、前綴一致、可搜索 |
| 介面 | 功能能跑通即可 | 最小驚訝、單一職責、錯誤可診斷 |
| 抽象 | 越多層越高級 | 僅當抽象能「降低總認知成本」時引入 |
| 決策依據 | 技術酷炫度 | 商業價值 = (開發/維護/機會成本) ROI |
本系列將持續分享實戰中的思考片段。下一期預告:「錯誤處理策略:返回碼 vs 異常 vs Result/Option 模式」。
來源:至簡李雲博客