在你開始寫程式碼之前
我有幾句話要先說
可能會相當嚴厲
但請聽我把真心話講完

image.png

前言

接下來我會說一段不太溫柔、而且可能有點居高臨下的話。不過如果你願意把話聽完,我想你也會理解這些嚴厲話語背後的原因。先跟你道個歉,請原諒我這種囂張的口吻。

在我對你說這些之前,先讓我談談圍繞這個產業的一些氛圍。軟體業界長久以來存在一些不易消失的風氣:

「賣得好的產品就是對的」
「品質?只要沒發生故障就好」
「細節交給供應商處理沒問題」

作為在商業現場求生的折衷,這種想法可以理解。但從工程師的職業倫理來看,這實在難以接受。試想一個建築師說「只要房子不倒塌,裡面的構造怎樣都無所謂」,你願意住在他蓋的房子裡嗎?

現在又遇上了生成式 AI 帶來的「vibe coding(憑直覺快速寫碼)」浪潮。

「我這個 IT 外行只花一週就做出某某應用程式!」
「過去要花 100 小時的工作,現在只要 5 小時就自動化完成!」

這種驚訝感不完全是壞事。它很棒,是走進工程世界的良好入口。分享到 X(前 Twitter)或拿去跟人炫耀都沒問題。

只是,請千萬不要把那種程度的東西直接拿去正式上線。

我能理解商務端的心情。人人都能寫軟體的這千載難逢的機會,誰不想把握?但為了兼顧兩邊,把事情做到安全且負責任,這篇文章提供最低限度的指引。

第一條:安全性,絕對要守住

如果你做的應用程式導致某人的信用卡資訊外洩,或私人照片被公開,「不好意思,這是 AI 寫的程式碼」這句話是說不通的。無論是在法庭上、在 X 上,或在自己良心面前,都沒用。

安全性絕對不能妥協。不能,也不該。

暫時別碰 IaaS

不要直接動用 AWS、GCP、Azure 之類的雲端基礎設施。那些是給專業人士用的工具箱。很方便,但一不小心就會傷手。

  • 每年都有 S3 儲存桶被設成「公開給全世界」而洩漏個資的案例重演
  • 把安全群組放開到 0.0.0.0/0,隔天就被礦工或惡意程式接管伺服器的例子不勝枚舉
  • 只要一個 IAM 角色設定錯誤,就有可能把正式環境的資料庫資料全挖走

只有完全理解那些陷阱的人,才應該使用 IaaS。「完全理解」大概代表你能用自己的話說出 AWS Well‑Architected 的基本要點,並能講出安全群組、IAM、網路設計常見的陷阱。

PaaS 也還太早

「那 Vercel 或 Firebase 可以嗎?」——很抱歉,還是太早。

例如 Firestore 的安全規則,在選擇測試模式(test mode)時,預設幾乎是全部允許。直接這樣上線,只要稍微改變 URL 就可能看到別人的資料。Supabase 的列級安全(Row Level Security)也存在相同問題。「能登入」跟「不能看到別人的資料」是完全不同的問題。

跟 IaaS 比起來,PaaS 要注意的事情少很多,但仍需讀懂 PaaS 提供的安全指南,並多次用實驗性應用去檢驗該服務的陷阱再使用。做不到的話,還是不要上線。

可以依賴像 Lovable 或 Bolt 這類的 SaaS 型建置平台

那應該怎麼做?答案是依賴像 Lovable、Bolt.new 這類更上層的 SaaS。這些平台把認證、資料庫、主機託管等預設為「偏安全的預設值」來幫你處理。

不過 SaaS 也有陷阱要注意:

  • 一定要確認公開設定與共用設定
  • 檢查外部串接服務(例如 OpenAI API Key)授權與用量上限
  • 能用自己的話說清楚「誰可以存取」的狀態

做不到上面這些,就不要上線。

不要把祕密與金鑰寫進程式碼

即便在 SaaS 層,也不會把祕密管理當成魔法自動解決掉。這一塊如果處理草率,後果最嚴重。

  • API 金鑰、私鑰、token 不要硬寫在程式碼或 prompt 裡。放到 SaaS 提供的 Secrets 或環境變數機制中
  • 別把可以放在瀏覽器的公鑰跟只能放在伺服器的私鑰弄混。能公開的和一旦外洩就完蛋的東西是不同的
  • 權限要最小化。不要做一把能打遍所有 API 的萬能金鑰
  • 測試用和正式用的金鑰要分開,不要共用同一把
  • 要預設會外洩,先確認好重發行與撤銷的流程。要把金鑰當成「遲早會漏」來看待
  • 錯誤日誌、畫面截圖、問 AI 的提問文都不要貼金鑰。資安事故通常就是從這些地方洩漏出來

「因為是 SaaS 所以安全」並不是「SaaS 會替你管理所有祕密」的意思。祕密放在哪、誰能接觸、若外洩如何阻止,這些最後都是你的責任。

「能登入」跟「不能看到別人的資料」是不同的事

有人在做完登入功能會誤以為「安全做好了」。不是的,那只是入口鎖上而已。能否進到系統內卻看不到別人的房間,完全是另一回事。

舉例來說,你可以透過 https://myapp.com/orders/12345 看見自己的訂單。那如果把 12345 改成 12346,會不會跑出其他人的訂單?這就是所謂的 IDOR(Insecure Direct Object Reference)。在 OWASP 的弱點排行中,它通常都名列前茅,是一種典型事故。

防範的做法只有一件事:

每次取出資料時,伺服器端都要檢查「這筆資料,真的屬於現在登入的使用者嗎?」

別抱著「URL 有 ID,應該只有本人會看到」的天真想法。請注意,當你叫 AI 寫「取得訂單的 API」時,AI 很容易忘記這種檢查。務必 review、一定要。

對輸入一律持懷疑態度

使用者輸入、外部 API 回傳、上傳的檔案——這些都可能是敵人。Web 世界不該有太多性善說。

「在表單做了驗證就沒問題」這句話騙不了人。

瀏覽器端的檢查(Client‑side validation)只是為了 UX,不能當成安全防線。打開開發者工具,任何人都能在幾秒鐘內把 JavaScript 關掉或直接改寫 HTTP 請求。無論你在 UI 上限制「年齡必須 ≥ 18」「只能輸入數字」「最多 100 字」,只要在伺服器端沒有做相同檢查,那都無效。驗證務必在伺服器端也做一次。

特別是檔案上傳,事故頻發:

  • 只看副檔名就判定「是圖片」 → 檔案實際上可能是可執行檔
  • 把檔名直接當成儲存路徑 → 可能被 ../../etc/passwd 類似的相對路徑逃脫(路徑穿越)
  • 沒有大小上限 → 被上傳 100GB 的檔案把磁碟塞爆
  • 直接顯示 SVG 圖檔 → SVG 內可能藏有 JavaScript,造成 XSS

如果只是想「先弄個上傳功能」,用 SaaS 型建置平台提供的預設機制是最安全的。不要自己硬做。

不要盲信 AI 推薦的套件

AI 會很乾脆地說「用這個就可以了」。但那個套件真的能信嗎?最後更新是什麼時候?維護者是誰?

AI 有時會大方地編造不存在的套件名稱(幻覺),或推薦五年前就停止維護、充滿漏洞的套件。最惡劣的情況是,攻擊者會利用 AI 常犯錯的套件名(typo squatting)上傳惡意程式。

在加入第三方套件前,至少要做這些檢查:

  • 在官方倉庫(npm、PyPI 等)確認套件存在
  • 確認最後更新時間在一年以內
  • 看 GitHub 的 star 數、Issue 數、維護者活動
  • 確認授權(license)(像 GPL 系列在商業上可能有麻煩)
  • package-lock.jsonrequirements.txt 鎖版本

相依套件就是你把工作交給的「外包」。不要把工作交給素行不明的外包方。

錯誤訊息別洩漏內部資訊

AI 寫的程式常常在發生錯誤時把完整的錯誤訊息(stack trace)直接回給使用者,這是非常危險的。

  • 資料庫的表名、欄位名
  • 內部檔案路徑
  • 使用的套件版本
  • 完整的 SQL 語句

對攻擊者來說,這些就是地圖。在正式環境,對使用者只回應「處理失敗」這類抽象訊息,把細節寫入伺服器端日誌。大部分框架都支援「開發模式」與「正式模式」切換,記得先確認。

「內部系統所以沒事」是幻想

如果你在做內部系統,可能會想:「沒對外公開,應該不需要太注意安全吧。」

這樣的想法會觸發事故。

原因有四個:

  • 內部最危險:資料外洩原因多來自內部帶出或惡意軟體感染。前員工帳號沒刪除這種事很常見
  • 內網不再安全:遠端工作、BYOD、雲端普及讓「內部=安全」的前提瓦解。零信任(Zero Trust)就是從這個前提出發:「不論內外都要質疑每一次存取」
  • 被當作踏腳石:攻擊者會把資安鬆散的內部系統當踏腳石,向正式環境進行橫向移動(lateral movement)。「資料不重要」沒關係,只要成為侵入口就是損害
  • 漏很久才發現:內部系統的事件往往很慢被偵測,有案例是一兩年都在流失而不自知

要保留日誌,並定期檢查

即使做了安全措施,單靠那些還不夠。沒有把發生的事記錄下來並定期檢查,你甚至不會知道自己被入侵了。

現實情況通常是:

  • 伺服器被非法存取,內部被探索好幾週,但沒有人看日誌就放著
  • 使用者資料被一點一滴抽走
  • 自己的伺服器被惡意程式當踏板去攻擊其他公司或其他國家 —— 你可能在不知情下成為加害者

「我的應用很小不會被攻擊」這種想法不通。很多攻擊是自動化的,會無差別掃描。只要發現脆弱系統就會被利用,不看規模大小。

至少要做的有:

  • 一定要保留存取日誌與錯誤日誌:紀錄誰在何時存取了什麼,有多少異常錯誤發生
  • 日誌存放位置要分離:不要只放在應用伺服器上,伺服器被入侵時證據也會被刪掉
  • 定期翻閱:每週一次也好。注意流量突增、來自陌生 IP 的存取、深夜的大量請求等異常模式
  • 設定告警:偵測異常時要有通知機制,比起自己去翻日誌更快
  • 日誌裡別輸出機敏資料:日誌常被送到 CloudWatch、Datadog、Sentry 等外部 SaaS。密碼、API 金鑰、信用卡號、個人資料(姓名、郵件、地址)不要放在日誌裡。事後刪除是最難的事,從一開始就不要記錄那些資料

日誌只有在事後才有用,因此務必在還沒事前就開始記錄。「出了事再去記錄」那時候就太晚了。

第二條:成本要事先估算,之後務必要確認。確認不是一次,而是定期的

當你在睡覺時,雲端帳單可能正在爆表。

  • 把 LLM API 放到無限迴圈,一夜之間就燒掉數十萬
  • 不懂 Firestore 的讀取計費設計,首頁一打開就跑數千次讀取
  • 圖像生成 API 設計成「每按一次就呼叫」,被惡意使用者連按就出單

在寫程式之前,先理解收費體系

「用多少付多少」的商業模式如果沒先估算使用量會變成無底洞。實作前至少要確認:

  • 確認計費單位:是按請求次數、tokens、讀取次數還是儲存量?到官方文件查單價與免費額度
  • 假設使用者數與請求頻率,試算成本:「一天 100 人各用 10 次,月費是多少?」動手算一次
  • 選擇能設定硬性上限(hard limit)的服務:當超出上限時是否能強制停止?不能的服務要理解風險再用
  • 注意免費額度的陷阱:免費期結束後價格、試用額度用完的行為要讀清楚

上線後也要定期確認

「第一次設定好了就沒事」這種想法不行。使用方式一變,成本也會跟著改變。

  1. 一開始就設定預算警示(這步驟先做完再寫程式)
  2. 上線後頻繁查看帳單儀表板:尤其上線初期,當天就能發現異常暴增
  3. 以週或月為單位看趨勢:日常緩慢上升的費用,日看很難察覺

在你高興地說「跑起來了!」的同時,計價的表正在不停轉動。

第三條:法務面是否 OK,先確認

在開始寫程式前,花五分鐘想清楚:

  • 該資料是否可以透過爬蟲抓取?(利用條款)
  • 是否會處理個人資料?(個人資料保護法、GDPR)
  • 那個套件授權是否允許商業使用?(避免 GPL 污染)
  • AI 生成的圖片或文章是否有著作權風險?
  • 是否踏入醫療、金融、法律等受法規限制的領域?

「我不知道」在法律面前不是藉口。若造成損害賠償還算幸運,可能還會涉及刑責或行政罰。

第四條:問自己「這個應用是一次性的嗎?」

下面的內容只給那些要做「非一次性」應用的人看。

如果你週末做一個自用、小玩具,週一就丟掉,那到此為止就好。但若是要被別人使用、明天還要跑、下個月還會有人用的應用,接下來的內容才是真正重點。

程式碼可以改,但資料結構不是那麼容易改變

這是軟體開發中最重要的真理之一。請記住:

程式碼的 bug 可以修。
資料結構的技術債,事後付款會帶利息。

具體來說:

  • schema 的更動往往是破壞性的:在放入使用者資料的表格改欄位或改型別,比起新建表格困難很多
  • migration 有順序:要做到無停機變更,需要按照慣用做法(先部署程式或先改 DB、或走雙寫雙讀的中間狀態等)
  • 觸碰正式環境資料庫前,一定要先備份:不可挽回的事情真的會發生

所以在開始寫程式之前,資料設計要先確認:

  • 把系統有哪些「實體(entity)」用語言寫出來:像是「使用者」「訂單」「商品」等,在叫 AI 幫你建資料表前,先能用自己的話說清楚
  • 整理關聯:使用者能有多筆訂單嗎?訂單可以包含多個商品嗎?沒搞清楚 1 對多、多對多 的關係,後面可能整個表要重做
  • 找出容易變動的欄位:哪些屬性日後可能會增加?如果選項不是固定值,是不是該獨立成表?
  • 決定刪除策略:真的刪除(物理刪除)還是只打刪除旗標(邏輯刪除)?這種事後改變影響範圍廣
  • 不要把 AI 生成的表結構直接放著不管:即便是 AI 幫你生成,只要用眼睛看過、確定表結構與欄位語意,才可接受。AI 擅長快速產出可跑的東西,但不一定優先考量「未來易變更性」

若事後必須改資料結構,至少遵守:

  1. 正式環境 DB 要設定自動備份(這一步先做)
  2. 在 Stage(暫存環境)先跑 migration,再套到正式環境:即便在 Stage 跑過也不要放心,正式環境往往有特殊資料。要做 dry‑run,確認沒有不預期的列或限制違反。若要改欄名、改型別或刪欄等會破壞既有程式的項目,考慮暫停服務再套用。無停機方法有,但那是給資深工程師的做法。通知使用者暫停服務,做完再啟動通常是最保險的方式
  3. 不要直接動正式資料:別用資料庫控制台或 SQL client 直接改正式資料。資料操作一定要透過測試過的程式(migration script、批次程式)執行,並且準備驗證手段(數量比對、checksum、日誌對照等)。還要把事前備份與事後還原的演練當作一套完整流程。沒實際試過還原的復原計畫,就等於沒有復原計畫

要常想「途中失敗會怎樣?」

這是 AI 寫的程式裡常見的事故來源。

以付款流程為例:「扣使用者餘額」「把商品庫存減少」「建立訂單紀錄」──如果在執行到第二步時停電,會發生什麼?錢被扣了但商品沒出貨怎麼辦?

有兩個概念可以避免這種情況:

  • 事務邊界(Transaction boundary):宣告「從這裡到這裡,要嘛全部成功,要嘛全部不算」
  • 冪等性(Idempotency):同一個處理被呼叫多次,結果仍然一樣(例如網路斷線重試時不會造成重複扣款)

「按同一個按鈕按兩下造成雙重訂單」「付款 API 超時後重試導致雙重收費」─ 這些事故若沒考量上面兩點就一定會發生。當你請 AI 寫流程時,要問:「如果途中失敗會怎樣?」「被呼叫兩次會怎樣?」並把這些場景 cover 起來。

要讓 AI 寫有意義的測試,請指示檢視觀點

AI 若只被告「寫測試」通常只會產出快樂路徑(happy path)的測試;若要全覆蓋會濫用 mock,產出沒意義的測試。為了讓測試有意義,不如把工作拆成步驟來做。

流程建議:

  • 「請先把本次實作部分的規格書寫出來」
  • 檢視規格書的完整性,有疑問就問清楚
  • 「請從這份規格書產出全面的測試案例,並標註哪些應由自動測試覆蓋、哪些需人工驗證」
  • 審閱文件,有疑問再問
  • 「請實作自動測試能覆蓋的部分,並在文件中記錄實作狀態」
  • 確認已實作的測試。AI 通常只會寫單體測試,接著再要求撰寫整合測試
  • 「請檢視規格書並找出需整合測試的案例,更新文件」
  • 審查整合測試案例
  • 「請實作整合測試,並在文件中記錄實作狀態」
  • 對於語意上有關聯的流程,AI 常判斷不足,需要你額外指出
  • 「執行某某處理後,再做✗✗會發生什麼?有測試到嗎?」
  • 如此循環

AI 生成的測試一定要自己讀。測試就是文件。讀不懂就要叫 AI 把測試項目說明清楚。

  • 測試名稱要像規格:不要用 test_1,要像「訂單金額為 0 時拒絕訂單」
  • Arrange / Act / Assert 是否清楚分離:準備、執行、驗證是否分明
  • mock 用得太多嗎?若全部都被 mock,測試只是驗證程式呼叫了某些 mock 而已
  • 測試不要依賴實作細節:若測試綁定內部變數名或 private method,重構時測試會頻繁壞掉

可維護性是寫給未來自己的信

三週後的自己就是陌生人,三個月後更是了。

  • DRY(別重複自己):不要把同樣邏輯寫在兩處以上,容易漏修
  • 了解規格:即使是 AI 寫的程式,也要能用自己的話說清楚「這段程式在做什麼」
  • 不能說清楚的東西就不要上線:嚴格點說,這是保護你自己的規則

一定要用版本控制(Git)

「昨天還能跑,今天不行」——只有 Git 能救你。不管你用不使用 Lovable、Bolt 等 SaaS,都沒例外。

  • 小顆粒且頻繁提交
  • commit 訊息寫清楚「改了什麼」「為什麼改」
  • .gitignore 絕對不要把祕密(API 金鑰、環境變數檔)提交到 repo
  • GitHub repo 一開始一定要設成 private

只做這些,開發的安心感就會提升十倍。

區分開發環境與正式環境

絕對不要把「在正式環境試一下」當成習慣,那是 99% 的事故起點。

  • 開發環境(自己的電腦)
  • Staging(和正式同配置的測試環境)
  • 正式環境(使用者使用的地方)

至少把「開發」與「正式」分開,資料庫也要分。誤刪正式使用者資料不是笑話。

第五條:估算效能承載能力

這個應用會有多少人使用?資料會累積到多少筆?一天會被呼叫幾次?

  • 使用者只有 10 人,簡單實作也能接受
  • 使用者一上到 1 萬人時,迴圈裡的 DB 查詢(N+1 問題)可能會把伺服器拖垮
  • 資料超過 100 萬筆時,沒有索引的搜尋會變成數十秒等級

不需一開始把系統做得完美,但請對你現在寫的程式大略有個承載界限的概念。知道能撐到多少筆資料,就能預防很多事故。

第六條:從失敗學習。但先學別人的失敗

最後這一條或許是最重要的。

軟體工程這領域半個多世紀以來,累積了無數失敗與從失敗中得出的智慧。版本控制、測試、CI/CD、程式碼審查、設計模式、SRE、資安最佳實務——這些都是有人吃過苦頭才建立起來的經驗。

你不需要重複別人的錯誤。可以事先讀書或研究真實的事故案例。不是叫你全部讀完,只要挑你有興趣或相關的部分看就好。沒有必要再勤懇地掉進前人已經踩過的坑。

即便如此,你還是會犯錯。重要的是犯錯後怎麼做:

  1. 先停止:不要讓損害擴大。停掉應用、撤銷 API 金鑰、把影響範圍降到最低。「先確認再行動」會拖延損害擴大
  2. 把發生的事記錄下來:發生時間、偵測經過、當下已知的情況。記錄比記憶可靠,對後續調查與改善很重要
  3. 盡快告知受影響的人:可以說「尚在調查中」,但別隱匿不說。沉默會失去信任
  4. 找出原因:不要只停在「個人失誤」,要問為何會發生這個失誤。有沒有系統性問題讓人容易犯錯
  5. 用機制做防再發:調整測試、告警、流程,做結構性的改善。同時把失敗原因抽象化,寫下「何時、對什麼要怎麼注意」,並把這些紀錄下來

比起失敗本身,失敗之後的處理更決定長期成效。

附錄 — 向 AI 詢問的觀點索引

這不是用來當閱讀材料的文章,而是給你向 AI 提問時的「索引」。

沒有這些也不代表做不了東西。但有了這些觀點,你在看到 AI 的回覆或程式執行結果時,就會知道該看什麼、怎麼處理。

下面以專業觀點列出可用來問 AI 的關鍵字。使用方式:

  1. 瀏覽與你正在做的東西相關的章節
  2. 找出不懂或想深入的術語
  3. 問 AI:「請把 ○○ 用淺顯方式解釋給初學者」

不必全部理解。今天挑 2~3 項,明天再學其他。這樣慢慢累積你的武器庫。

大分類一覽

設計審查會看的觀點

  • A. 架構設計
  • B. 資料與介面
  • C. UX 設計
  • D. 非功能與運維
  • E. 安全設計

程式碼審查會看的觀點

  • F. UI 設計與前端
  • G. 設計原則與模式
  • H. 程式碼品質
  • I. 測試
  • J. 實作技術
  • K. 流程與文件
  • L. 安全程式設計
  • M. 參考書籍與框架

A. 架構設計

A-1. 架構風格

  • 層級式架構(Layered Architecture)
  • 六角形架構(Hexagonal / Ports and Adapters)
  • 洋蔥架構(Onion Architecture)
  • 清潔架構(Clean Architecture)
  • 微服務 vs 單體(Monolith)vs 模組化單體(Modular Monolith)
  • 事件驅動架構(Event Driven Architecture)
  • CQRS(Command Query Responsibility Segregation)
  • 事件溯源(Event Sourcing)
  • BFF(Backend for Frontend)
  • Serverless 架構

A-2. 領域建模(Domain Modeling)

  • DDD(領域驅動設計)
  • 有界上下文(Bounded Context)
  • 通用語言(Ubiquitous Language)
  • 實體 / 值物件 / 聚合(Entity / Value Object / Aggregate)
  • 領域事件(Domain Events)
  • 策略性設計 vs 戰術性設計
  • 上下文地圖(Context Map)

A-3. 模組切分與依賴關係

  • 高內聚、低耦合(High Cohesion, Low Coupling)
  • 依賴反轉原則(Dependency Inversion)
  • 排除循環依賴
  • 套件原則(REP/CCP/CRP、ADP/SDP/SAP)
  • 控制依賴方向
  • 穩定度與抽象度的平衡

B. 資料與介面

B-1. 資料建模

  • 正規化與非正規化的取捨
  • ER 模型
  • 星型 / 雪花模式(Star / Snowflake Schema)
  • 不可變資料模型(Immutable Data Model)
  • 以事件溯源保留歷史(Event Sourcing)
  • Single Source of Truth(單一事實來源)

B-2. API 設計

  • REST 原則(統一介面、無狀態)
  • 資源導向設計(Resource Oriented Design)
  • GraphQL vs REST vs gRPC
  • 版本管理策略(URL path、header、media type)
  • 分頁(Offset、Cursor)
  • HATEOAS
  • OpenAPI / Swagger 規格
  • 冪等性金鑰(Idempotency Key)header
  • 錯誤回應設計(RFC 7807 Problem Details)

B-3. 一致性與交易

  • 事務邊界設計
  • ACID 特性
  • DB 的一致性約束(主鍵、外鍵、唯一、CHECK)
  • 樂觀鎖 vs 悲觀鎖
  • 分散式交易
  • Saga 模式
  • 結果一致性(Eventual Consistency)
  • 冪等性(Idempotency)
  • Outbox 模式
  • 優雅關閉(Graceful Shutdown)

B-4. 非同步處理(Queue / Event)

  • At‑least‑once / At‑most‑once / Exactly‑once 的送達語意
  • Dead Letter Queue(DLQ)
  • 透過 idempotency key 去除重複
  • Outbox(事務性訊息)模式
  • 隊列優先度與公平分享
  • Visibility Timeout
  • Pub/Sub vs 訊息佇列

B-5. 快取(Cache)

  • 快取一致性模型(Strong / Eventual)
  • cache‑aside / write‑through / write‑back 模式
  • 快取風暴(Thundering Herd)對策
  • TTL jitter
  • 熱鍵問題(Hot Key)
  • CDN 邊緣快取
  • 多層快取策略

C. UX 設計

C-1. 使用者研究

  • Persona
  • Customer Journey Map
  • 使用者訪談
  • 民族誌研究(Ethnography)
  • Jobs to Be Done(JTBD)
  • 心智模型(Mental Model)
  • 可用性測試
  • A/B 測試
  • 定量調查 vs 定性調查

C-2. 資訊架構(Information Architecture)

  • Sitemap
  • 卡片分類(Card Sorting)
  • 導覽設計(全球 / 區域 / 情境導覽)
  • 麵包屑(Breadcrumb)
  • 分面搜尋(Faceted Search)
  • 資訊層級與粒度
  • 與心智模型的一致性

C-3. 互動設計

  • 使用者流程 / 任務流程
  • 線框圖(Wireframe)
  • 原型(低保真 / 高保真)
  • 微互動(Microinteractions)
  • 反饋設計(即時性與可見性)
  • 錯誤預防與錯誤恢復
  • 撤銷 / 重做(Undo / Redo)
  • 引導(Onboarding)
  • 空狀態(Empty State)設計

C-4. UX 原則與啟發式

  • Nielsen 的 10 大可用性啟發式
  • Donald Norman 的「物件的設計」
  • Affordance / Signifiers
  • 認知負荷(Cognitive Load)
  • Hick 法則
  • Fitts 法則
  • Miller 法則(7±2)
  • Jacob 法則
  • Peak‑End 法則
  • 格式塔原則(Gestalt)

C-5. 可及性(UX 面)

  • WCAG
  • WAI‑ARIA
  • 包容性設計(Inclusive Design)
  • 通用設計(Universal Design)
  • 支援螢幕朗讀器
  • 鍵盤操作支援
  • 色覺多樣性考量
  • 認知可及性

C-6. UX 指標

  • HEART 框架(Happiness、Engagement、Adoption、Retention、Task Success)
  • NPS(Net Promoter Score)
  • CSAT(Customer Satisfaction)
  • SUS(System Usability Scale)
  • 任務成功率 / 流失率
  • Time on Task

D. 非功能與運維

D-1. 可擴展性(Scalability)

  • 水平擴展 vs 垂直擴展
  • 無狀態設計(Stateless)
  • 資料分片(Sharding)
  • 複寫(Leader‑Follower、Multi‑Leader)
  • CAP 定理
  • PACELC 定理
  • 負載平衡策略

D-2. 可用性與韌性(Availability / Resilience)

  • 單點故障(SPOF)
  • Circuit Breaker 模式
  • Bulkhead 模式
  • 指數退避與重試(Exponential Backoff)
  • Canary Release / Blue‑Green deploy / Feature Flags
  • 健康檢查與自動復原
  • Chaos Engineering
  • RTO / RPO(目標復原時間 / 恢復點)

D-3. 可觀測性(Observability)

  • 三大支柱:日誌、指標、追蹤
  • 分散式追蹤(OpenTelemetry)
  • 結構化日誌(Structured Logging)
  • SLI / SLO / SLA
  • Golden Signals(延遲、流量、錯誤、飽和度)
  • 告警疲乏與告警設計

D-4. 環境與基礎設施設計

  • 正式/Staging/開發環境分離
  • Infrastructure as Code(Terraform、Pulumi、CloudFormation)
  • 12 Factor App
  • 容器編排(Kubernetes)
  • GitOps
  • 服務網格(Service Mesh)

D-5. 資料遷移

  • expand‑migrate‑contract 模式
  • 冪等的 migration 腳本
  • 回滾策略
  • 資料一致性驗證(筆數比對、checksum)
  • 漸進遷移 vs 維護視窗(maintenance window)
  • Zero‑downtime 部署

E. 安全設計

E-1. 安全原則

  • Defense in Depth(多層防禦)
  • 假設已被入侵(Assume Breach)
  • 零信任(Zero Trust)
  • 最小權限原則(Principle of Least Privilege)
  • 預設拒絕(Deny by Default)
  • 審計追蹤(Audit Trail)

E-2. 資料保護與多租戶

  • 資料分類(機敏 / 內部 / 公開)
  • 多租戶的隔離
  • 雲端安全基線(AWS Well‑Architected、Azure Security Benchmark)

F. UI 設計與前端

F-1. 視覺設計原則

  • 排版(字體層次、可讀性、行距)
  • 色彩理論(配色、對比度、色彩組合)
  • 版面間距(白色空間)與密度
  • 格線系統(8pt、12 栏)
  • 視覺層次(Visual Hierarchy)
  • 近接 / 對齊 / 重複 / 對比(CRAP 原則)
  • 擬真風格 vs 扁平化 vs Neumorphism
  • Material Design / Human Interface Guidelines / Fluent Design

F-2. 設計系統

  • 設計代幣(顏色、間距、排版)
  • 原子設計(Atoms / Molecules / Organisms / Templates / Pages)
  • 元件庫(Storybook、Figma)
  • 命名規則(BEM、SMACSS)
  • 品牌指南
  • Figma / Sketch / Adobe XD 等工具整合

F-3. 元件設計

  • Presentational vs Container 元件
  • Compound Component 模式
  • Render Props / Higher‑Order Component
  • Controlled vs Uncontrolled 元件
  • 組合優於配置(Composition vs Configuration)
  • Slot / Children 模式
  • Props drilling 與 Context / 狀態管理

F-4. 樣式

  • CSS Modules
  • CSS‑in‑JS(styled‑components、Emotion)
  • Utility‑First(Tailwind CSS)
  • CSS 設計方法(BEM、SMACSS、OOCSS、FLOCSS)
  • CSS 變數(Custom Properties)
  • 響應式設計(breakpoints、mobile‑first)
  • Container Queries
  • 深色模式支援

F-5. 狀態管理

  • 區域狀態 vs 全域狀態
  • Redux / Zustand / Jotai / Recoil
  • React Context
  • 伺服器狀態(TanStack Query、SWR)
  • 表單狀態(React Hook Form、Formik)
  • URL 狀態(query string)
  • 樂觀更新(Optimistic Update)

F-6. 前端效能

  • Core Web Vitals(LCP、FID/INP、CLS)
  • 代碼分割(Code Splitting)
  • 延遲載入(Lazy Loading)
  • Tree Shaking
  • 縮小打包體積
  • 圖片最佳化(WebP、AVIF、next/image)
  • 虛擬捲動(Virtual Scrolling)
  • 記憶化(React.memo、useMemo、useCallback)
  • SSR / SSG / ISR / CSR

F-7. 可及性(實作面)

  • 語義化 HTML
  • 適當使用 ARIA 屬性
  • 焦點管理(Focus trap、Focus ring)
  • 鍵盤導航
  • 螢幕閱讀器測試
  • 對比度要求
  • 表單標籤化
  • live region(aria‑live)

F-8. 動畫與互動

  • CSS Transitions / Animations
  • JS 動畫庫(Framer Motion、GSAP)
  • 緩和函數(easing)
  • 以效能為優先的動畫(transform、opacity)
  • prefers‑reduced‑motion 支援
  • 骨架螢幕(Skeleton)
  • 載入狀態的表現

G. 設計原則與模式

G-1. 設計原則

  • SOLID 原則
    • SRP(單一職責)
    • OCP(開放/封閉)
    • LSP(里氏替換)
    • ISP(介面隔離)
    • DIP(依賴反轉)
  • DRY(Don't Repeat Yourself)
  • KISS(Keep It Simple, Stupid)
  • YAGNI(You Aren't Gonna Need It)
  • 關注分離(Separation of Concerns)
  • 最小驚訝原則(Principle of Least Astonishment)
  • Tell, Don't Ask
  • Demeter 法則(Law of Demeter)
  • Command‑Query Separation(CQS)
  • 組合優於繼承(Composition over Inheritance)
  • Fail Fast

G-2. 設計模式(GoF)

  • 創建型:Factory Method、Abstract Factory、Builder、Singleton、Prototype
  • 結構型:Adapter、Bridge、Composite、Decorator、Facade、Flyweight、Proxy
  • 行為型:Chain of Responsibility、Command、Iterator、Mediator、Observer、State、Strategy、Template Method、Visitor

G-3. 企業級模式(PoEAA 等)

  • Repository 模式
  • Unit of Work
  • Data Mapper vs Active Record
  • Service Layer
  • Domain Model vs Transaction Script
  • Specification 模式
  • Null Object 模式

H. 程式碼品質

H-1. 乾淨程式碼(Clean Code)

  • 有意義的命名(變數、函式、類別)
  • 函式只做一件事
  • 函式參數少(理想 0~2 個)
  • 最小化副作用
  • 註解寫「為什麼」,程式碼表達「做什麼」
  • 排除魔術數字、魔術字串
  • 保持淺層巢狀(早期 return)
  • 避免布林旗參數

H-2. 重構(Refactoring)

  • 程式味道(Code Smell):
    • 過長函式 / 巨型類別
    • Feature Envy(功能嫉妒)
    • Data Clumps(資料群)
    • Shotgun Surgery(分散式變更)
    • God Class(上帝類別)
    • Primitive Obsession(過度使用原始型別)
  • 抽出方法(Extract Method)
  • 抽出類別(Extract Class)
  • Inline / Introduce 變數
  • 用多型取代條件分支
  • 引入 Guard Clause

H-3. 型別設計與契約

  • 型別驅動設計(Type‑Driven Development)
  • 使非法狀態無法表示(Make Illegal States Unrepresentable)
  • 值物件(Value Object)以增強型別安全
  • Null 安全(Option / Maybe、nullable 參考型)
  • 不變性(Immutability)
  • 前置條件 / 後置條件 / 不變條件(Design by Contract)
  • 解析(Parsing) vs 驗證(Validation):「parse, don't validate」

H-4. 函數式編程思維

  • 純函式
  • 參照透明性
  • 副作用分離
  • 高階函式
  • 不可變資料結構
  • map / filter / reduce
  • Monad(Option、Either、Result)

H-5. 錯誤處理

  • 例外 vs Result 型的選擇
  • Checked Exception vs Unchecked Exception
  • 禁止吞掉例外
  • 早期 return / Guard Clause
  • Fail Fast 原則
  • 可恢復錯誤 vs 無法恢復錯誤
  • 指數退避與 jitter
  • 區分可重試與不可重試的操作

I. 測試

I-1. 測試策略與哲學

  • 測試金字塔(Mike Cohn)
  • Testing Trophy(Kent C. Dodds)
  • 測試鑽石 / 蜂巢模型
  • 測試驅動開發(TDD)
  • Red‑Green‑Refactor
  • Given‑When‑Then / Arrange‑Act‑Assert
  • BDD(Behavior‑Driven Development)
  • 測試覆蓋率的陷阱(100% 覆蓋 ≠ 無 bug)
  • Flaky 測試對策
  • 過早的 mock / mock 用太多的問題

I-2. 測試類型(功能面)

  • 單元測試(Jest、Vitest、JUnit、pytest)
  • 整合測試
  • E2E(Playwright、Cypress、Selenium)
  • 元件測試(Testing Library)
  • 互動測試(Storybook Interaction Tests、user‑event)
  • 快照測試
  • 屬性測試 / Property‑based Testing(fast‑check、Hypothesis、QuickCheck)
  • 變異測試(Mutation Testing)(Stryker、PIT)
  • 煙霧測試(Smoke Test)
  • 回歸測試
  • 驗收測試(Acceptance Test)
  • 探索性測試(Exploratory Testing)

I-3. 測試類型(UI / 視覺)

  • 視覺回歸測試(Chromatic、Percy、reg‑suit、Playwright 視覺比對)
  • 可及性測試(axe‑core、Lighthouse、pa11y)
  • 跨瀏覽器測試(BrowserStack、Sauce Labs)
  • 響應式測試
  • 截圖比較測試

I-4. 測試類型(契約 / 邊界)

  • 合約測試(Contract Testing)(Pact、Spring Cloud Contract)
  • Consumer‑Driven Contract Testing
  • API 測試(Postman、REST Assured、supertest)
  • Schema 測試(JSON Schema、OpenAPI 驗證)

I-5. 測試類型(非功能)

  • 負載測試(Load Test)
  • 壓力測試(Stress Test)
  • 突波測試(Spike Test)
  • 耐久測試(Soak / Endurance Test)
  • 效能測試(k6、JMeter、Gatling、Locust)
  • 安全測試(SAST、DAST、IAST)
  • 滲透測試(Penetration Test)
  • Chaos 測試(Chaos Monkey、Litmus)
  • Fuzzing 測試

I-6. 測試替身(Test Double)

  • Dummy
  • Stub
  • Spy
  • Mock
  • Fake
  • Test Double 的使用區分(Gerard Meszaros)

I-7. 測試設計技法

  • 等價類劃分(Equivalence Partitioning)
  • 邊界值分析(Boundary Value Analysis)
  • 決策表
  • 狀態遷移測試
  • Pairwise 測試

J. 實作技術

J-1. 並行處理與多線程

  • thread‑safety
  • 以不變物件增加安全性
  • ConcurrentHashMap、AtomicInteger 等線程安全集合
  • 競態條件(Race Condition)
  • TOCTOU(Time Of Check To Time Of Use)
  • 死鎖對策(鎖順序統一、tryLock)
  • ExecutorService 與線程池上限
  • async/await 模式
  • Reactive Programming

J-2. 效能

  • N+1 問題
  • 索引設計
  • 用 EXPLAIN 觀察查詢計畫
  • Big O 計算量
  • 記憶體洩漏
  • 程式剖析(Profiling)
  • 避免過早優化(Premature Optimization)
  • 快取策略
  • 批次處理 vs 串流處理
  • 連線池(Pool)管理
  • 慢查詢日誌分析
  • 避免 SELECT *(只抓必要欄位)
  • 分頁效能(offset 分頁在資料多時效能差)
  • 非同步 / 並行的適當使用
  • Backpressure(背壓)處理
  • 無冷啟(cold start)問題(伺服器無狀態時)
  • 資料傳輸量最佳化(over‑fetching / under‑fetching)
  • 回應壓縮(gzip / Brotli)
  • Keep‑Alive 與連線重用
  • CDN 的適當運用

K. 流程與文件

K-1. 文件化

  • ADR(Architecture Decision Record)
  • README 撰寫
  • API 文件(OpenAPI、JSDoc、Javadoc)
  • 圖的畫法(C4 模型、UML、流程圖)
  • 自我文件化的程式碼

K-2. 版本管理與開發流程

  • Git 的提交粒度
  • Conventional Commits
  • 分支策略(Git Flow、GitHub Flow、Trunk‑Based Development)
  • Pull Request 審查作法
  • 語義化版本(SemVer)
  • CI/CD 管線
  • Feature Flag

L. 安全程式設計

L-1. 威脅建模

  • STRIDE(Spoofing/Tampering/Repudiation/Information Disclosure/DoS/Elevation of Privilege)
  • NIST 攻擊者分類
  • Attack Surface 分析
  • 信任邊界(Trust Boundary)

L-2. 通訊保護

  • TLS 1.2 以上,停用弱加密套件
  • 憑證釘選、主機名驗證
  • HSTS(HTTP Strict Transport Security)
  • Content‑Security‑Policy(CSP)
  • X‑Frame‑Options / frame‑ancestors
  • X‑Content‑Type‑Options: nosniff
  • Referrer‑Policy
  • CORS 設定(禁止 * 與 credentials 一起用)

L-3. 加密與祕密管理

  • CSPRNG(密碼學安全隨機數)
  • bcrypt / Argon2 / scrypt
  • Salt 與 Key Stretching
  • IV 的隨機化
  • KMS / HSM / Vault / Secrets Manager
  • 金鑰輪換(Key Rotation)

L-4. 認證與會話

  • Authorization Code Flow + PKCE
  • OIDC 的 state / nonce / redirect_uri 驗證
  • access token / refresh token 的輪換
  • MFA(TOTP、WebAuthn、FIDO2)
  • 密碼噴灑、credential stuffing 對策
  • 速率限制與帳號鎖定
  • Cookie 屬性(Secure / HttpOnly / SameSite)
  • Session Fixation 對策(登入時重新產生 ID)
  • JWT 的 expjti、不要放機敏資訊
  • 強制登出(在登出或密碼變更時失效會話)

L-5. 授權與存取控制

  • 在伺服器端驗證權限
  • IDOR 對策
  • 租戶隔離檢查
  • scope 基礎的授權管理
  • RBAC / ABAC
  • 403 Forbidden vs 404 Not Found 的區分

L-6. 輸入驗證

  • 白名單方式
  • 使用 JSON Schema / OpenAPI 做 schema 驗證
  • 拒絕 NULL byte、控制字元
  • XML 的 XXE 對策
  • Billion Laughs 攻擊對策
  • 檔案上傳:副檔名、MIME、magic number 三者判定
  • 路徑穿越(Path Traversal)對策
  • Zip Bomb 對策
  • SVG 的清理(Sanitize)
  • CSV 注入(Formula Injection)

L-7. 注入攻擊

  • SQL 注入與預備語句(Prepared Statement)
  • ORM 的 Raw Query 風險
  • OS command injection 與陣列參數形式
  • LDAP 注入
  • NoSQL 注入
  • 模板注入(SSTI)
  • 反序列化攻擊(Java Serialization、pickle、fastjson)

L-8. 輸出編碼

  • 依情境做逃逸(HTML / 屬性 / JS / URL / CSS)
  • React dangerouslySetInnerHTML 的風險
  • Angular [innerHTML] 的風險
  • 拒絕 javascript: / data: scheme
  • HTTP header 注入(CRLF Injection)
  • 開放導向重導(Open Redirect)對策

L-9. 錯誤處理(安全面)

  • 正式環境禁顯示 stack trace
  • 一般化錯誤訊息
  • 日誌中不要寫入機敏資訊

L-10. SSRF(Server‑Side Request Forgery)

  • 以白名單為基礎驗證 URL
  • DNS 解析後檢驗 IP
  • CNAME 連鎖追蹤
  • 對於連結本機位址(例如 169.254.169.254)的檢查
  • ...(原文此處為截斷)

原文出處:https://qiita.com/Akira-Isegawa/items/00f23d206c504db2ac3b


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝5   💬6   ❤️3
424
🥈
我愛JS
📝2   💬7   ❤️2
205
🥉
💬1  
4
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登