前端系統設計面試:從一張 UI 推到最小狀態、資料流與 AI 工具鏈
文字解析 · 1 支影片 · 產生於 2026-10-01 00:54
章節(16)
1. Outline
- 起點 · Real Senior Frontend System Design Interview 2026 (AI Coding Included)
用一場真實的資深前端白板面試,把「從 UI 到架構」走成一條可重複的固定路線:需求 → 狀態 → 實作細節 → 非功能性需求 → AI 工具鏈。
2. YouTuber 的思維推導
Real Senior Frontend System Design Interview 2026 (AI Coding Included)
theSeniorDev · 40m31s · 字幕 en · vision=on (整支影片是螢幕分享+白板:作者不斷說「我們看這個 UI」「我把這個標成不在範圍」「我把這兩個型別合併」「這裡畫一條線」,指示語遠超過 3 次,型別定義、BFF 圖、SSE 事件流都畫在畫面上,不看圖無法理解他在指什麼。) · YouTube
預估 vs 實際耗時
| 階段 | 預估 | 實際 |
|---|---|---|
| fetch | 6s | 2s |
| segment | 1m51s | 7m00s |
| shot | 1m35s | 12s |
| analyze | 17m30s | 25m00s |
| render | 5s | – |
作者要解決的不是「這個圖表元件怎麼寫」,而是「在白板前你怎麼不會卡住」。他的推導從一個觀察出發:面試會失敗,多半不是因為不會技術,而是沒有心智里程碑,不知道自己走到哪、還缺什麼。於是他把一場前端系統設計面試拆成一條固定路線:先把 UI 翻成功能性與非功能性需求(不照單全收設計稿),再從 UI 逐塊刪去、圈出真正的 state 並寫成型別(過程中積極合併與刪去衍生狀態),接著問「狀態怎麼變」——只有後端資料與使用者事件兩個來源——順勢決定狀態管理選型;有了狀態才談實作細節(框架、設計系統、CSS、無障礙、建置工具、程式碼品質),這時才有資格談非功能性需求:效能拆成載入、互動、版面穩定三個維度逐一探問,可擴展性把瓶頸推向後端於是引出 BFF 的穩定介面,即時性在 polling/WebSocket/SSE 之間用「是不是真的雙向」做選擇,最後用讀寫比決定各層要不要快取。
整條路線的兩個隱藏主軸是:一,狀態要壓到最小,能算出來的就不要存;二,把選項攤開讓面試官選,而不是替他做決定。AI 的部分被他當成同一套推理的延伸——AI 可以幫你精煉狀態結構,但它會膨脹細節、也缺乏視覺智能,所以你要先產出穩定的錨點產物(設計系統、狀態圖、循序圖)讓模型只做內插。結論落在一句話:把設計做完整、貼回你每天真的在做的前端業務系統,不要去解想像出來的系統。
推理鏈:每段留給下一段的線索
每一列是一段,箭頭後的字是這段留給下一段的線索。點段落標題跳到該段。
- 白板面試現場與「心智里程碑」 → 那組心智里程碑到底是什麼?第一個里程碑:不把設計稿照單全收,先把畫面翻成需求。
- 階段一:功能性與非功能性需求 → 既然要拆成「初始載入」與「即時更新」,就得先知道畫面上到底有哪些東西會變;下一步是回到 UI 圈出真正的 state。
- 階段二起手:從 UI 圈出真正的 state → 圈出來的都還只是畫面上的欄位;下一步要把它們寫成有名字、有型別的資料結構。
- 把畫面翻成資料模型 → 型別骨架有了,但作者是純手工推出來的;如果允許用 AI,這一步能不能外包?
- 用 AI 幫忙設計 state 的界線 → AI 版本漏掉的正是最底層那個型別——data point 還沒被完整寫出來,得補上。
- data point 與請求合併的取捨 → 資料的「形狀」定完了,但還沒回答它「怎麼變」——狀態轉移是下一個里程碑。
- 狀態轉移與狀態管理選型 → 狀態的形狀與轉移都定了,可以往下談「這東西實際上怎麼做出來」的實作細節。
- 最小可行前端:框架、設計系統、CSS、無障礙 → 清單走到第五項就是建置工具,而一旦談建置工具,就得回答「AI 在寫大部分程式碼時,品質靠什麼守住」。
- 建置工具與 AI 時代的程式碼品質 → 功能面與工程面都收乾淨了,接下來輪到被擱置最久的那一欄——非功能性需求裡的效能。
- Web 效能的三個維度 → 前端這側的手段講完了,但流量真的上來時瓶頸會落在後端——那該怎麼辦?
- BFF:讓介面穩定下來 → 資料怎麼來的路徑定了,但還沒回答那條路徑上「即時更新」要用什麼協定送。
- 即時更新:SSE,以及把狀態壓到最小 → 資料怎麼來、怎麼更新都定了;剩下的問題是哪些資料根本不必再拿一次。
- 快取:用讀寫比決定快取什麼 → 整套架構的技術面到此完備;剩下沒回答的是這一切要用什麼工具、什麼模型做出來。
- AI 開發工具鏈:模型、harness、審查代理 → 工具與模型也定了;回頭看這整份架構,還有哪些地方作者自己覺得沒挖夠?
- 回頭看:還會再深掘的地方 → 技術面能補的都列完了;剩下最後一個問題——同樣的題目,為什麼有人過有人不過?
- junior 與 senior 的差別,以及唯一的建議
3. 逐段說明
Real Senior Frontend System Design Interview 2026 (AI Coding Included)
1. 白板面試現場與「心智里程碑」 0:00–1:23
這是學員在某大型金融公司真實拿到 offer 的資深前端系統設計面試:現場、不能用任何數位工具,面試官把一張金融資產走勢圖印在紙上,要她在白板上走完整個設計流程。主持人指出這種面試最大的陷阱是「腦袋一片空白」——因為沒有一組心智里程碑,不知道自己走到哪、還缺什麼、下一步該去哪。本集就是把那組里程碑攤開來講,並額外插入「這一階段適不適合用 AI」的提問。

推理因為要說服你「需要一套流程」,主持人先給了一個極端場景:學員被請到現場,不能用任何數位工具,面試官把一張金融資產走勢圖印在紙上,要她在白板前走完整個設計。接著他直接點名這種面試最大的陷阱——腦袋一片空白。他把原因歸給「缺少一組心智里程碑」:不知道自己在哪、還缺什麼、下一步去哪。所以整支影片的形式就定了:不是講某個技術,而是把那條路線攤開;並且每走到一個階段就額外插問「這一階段適不適合用 AI」。
AI 補充截圖裡那張圖其實不是傳統券商的股價圖,而是 Polymarket 的「BTC Up or Down 5m」市場頁:上方有 Price To Beat 與 Final price 兩個數字、中間一條橘色折線、一條虛線的 target、下方是可切換的時間區間按鈕。認出這個畫面很重要,因為之後每一個型別欄位都能在這張圖上指出對應的位置。另外要注意場景的限制條件:不能用電腦,代表你不能靠 IDE、不能靠 AI 補齊;你唯一能依賴的就是腦中那條路線——這正是為什麼「里程碑」比任何單項技術都值錢。
2. 階段一:功能性與非功能性需求 1:23–5:10
資深工程師不會把設計稿照單全收,而是把 UI 翻譯成具體需求。功能性需求=要做到什麼(要有圖表、要有這些按鈕、需要哪些畫面),非功能性需求=怎麼做到(跨瀏覽器、載入速度、無障礙、可測試、可維護)。他用車子比喻:功能性是「能不能把我從 A 載到 B」,非功能性是「要吃多少油」。接著他當場示範要問面試官的問題:這是放在自家 component framework 裡的可重用元件,還是要嵌到別的網站(那就得用 iframe)?效能有沒有 SLO(前端用 Core Web Vitals 與 RUM 量化)?金融機構受嚴格監管,無障礙與安全一定要在開頭先點名。最後他確認 UI 有即時更新,於是把問題切成「初始載入的靜態圖」與「之後持續刷新的即時部分」兩塊。



推理因為上一段說資深工程師不會把 UI 當成既定答案,作者第一步就在白板右側寫下兩欄:Functional Requirements 與 NonFunctional Requirements。他先用一句判準把兩者分開:功能性是「你要做到什麼」(要有圖表、要有這些按鈕、需要哪些畫面),非功能性是「你怎麼做到」(跨瀏覽器、載入夠不夠快、無障礙、可測試、可維護);車子的比喻是「能不能把我從 A 載到 B」對上「要吃多少油」。接著他把這兩欄當成提問清單一項項問:這是塞進 component framework 的可重用元件,還是要嵌到別的網站(那就得用 iframe)?效能有沒有 SLO——前端要用 Core Web Vitals 加 RUM 來量化?無障礙與安全在金融機構是法遵問題,所以一定要在開頭先點名,但不必展開。最後他問到即時更新,並在真實頁面上確認圖在動、計時器在動、資料範圍是動態的,於是把問題切成兩塊:初始載入的靜態圖,與之後持續刷新的即時部分。
- C功能性需求問『要做到什麼』,非功能性問『怎麼做到』;先掛號、不展開→ 畫地圖
- A功能性需求像車子『能不能載我到B』,非功能性像『要吃多少油』→ 批判類比
- R作者怎麼處理無障礙與安全這類非功能性需求→ 存+回想
AI 補充這一段真正的技巧不是「知道有非功能性需求」,而是「先掛號、不展開」。作者自己說了:無障礙與安全就在開頭提一句「我們會在後面擴大設計時把這些考慮進去」,你不需要當場講細節。這麼做有兩個效果:一是讓面試官知道你的雷達上有這些東西(很多 junior 就是整場沒提過無障礙),二是替自己在後面預留可以回來深挖的話題,避免中段沒話講。另外注意他的量化選擇:非功能性需求裡只有效能能給出真正的數字,所以他只在效能上追問 SLO;無障礙與安全他改用「有沒有法規要遵守」來逼出具體標準。最後那個「靜態載入 vs 即時更新」的二分是這整支影片的第一個結構性決定——後面資料模型、快取、傳輸協定的討論全都沿著這條裂縫走。
3. 階段二起手:從 UI 圈出真正的 state 5:10–7:00
第二階段是狀態架構,因為在新的 UI 裡 state 是功能的核心。做法是拿著 UI 逐塊刪去法:先把明確不在範圍的區塊一個個標掉,留下圖表功能;再判斷剩下區塊裡哪些是靜態、哪些會變。他標出會變的部分:重新載入會變的文字、final price、price to beat、還有所有資料點——這些都是初始載入時從後端來的。他也順手做了第一次去重:畫面上「current price」跟下面那條線的價格其實是同一個狀態,只要留一個;但 target price 是獨立的,要另外抓。


推理因為上一段把需求分成靜態與即時兩塊,作者接著宣告第二個里程碑:狀態架構,理由是「在新的 UI 裡 state 是功能的核心」。他的手法是刪去法而不是列舉法:拿著畫面,先把明確不在範圍的區塊一個個劃掉(截圖裡可以看到 Past 按鈕、右上角的分享圖示、右下角的圖表類型切換全被打叉),只留下圖表本身;再判斷剩下的區塊裡哪些是靜態、哪些會變。他標出四類會變的東西:重新載入才會變的標題文字、Price To Beat、Final price、以及所有資料點。然後他做了第一次去重:畫面上的 current price 跟折線末端其實是同一個值,只留一個就好;但那條虛線的 target price 是獨立的,得另外抓。
AI 補充刪去法比列舉法可靠,原因是它會逼你對每一塊畫面做出明確判斷(在範圍/不在範圍/靜態/動態),而列舉法很容易只寫下你想得到的那幾個。這裡也藏著一個實務提醒:「不在範圍」不等於「不存在」——你只是跟面試官達成共識先不做,這句共識本身就是加分項。另外,作者對 current price 與折線末端做的去重,其實已經預告了他整段的核心原則:兩個看起來不同的畫面元素,如果總是能從同一份資料算出來,它們就只該有一份狀態。這個原則在幾分鐘後會被推到極致。
4. 把畫面翻成資料模型 7:00–9:29
他開始把剛才圈出來的動態欄位寫成型別。先是 date interval(start / end 兩個 date),對應畫面上的時間軸與那個區間條;再來是 price data(price to beat、final price、target price,先用 JavaScript number,並說明金融資料若要多位小數可考慮 BigInt);最後是 data series(string 型的 UUID id,加上一個 data point 陣列)。接著他做了關鍵的整併與刪減:date interval 的 start/end 跟 data series 是強相關、欄位互相依賴,合併成一個型別;final price 根本不必抓,它就是最後一個資料點,屬於衍生狀態(derived state),直接刪掉;price to beat 則像是獨立變數,值不值得合併要看後端怎麼存、要不要發兩次請求——這正是他會反問面試官的地方。




推理因為上一段已經把會變的東西標出來,作者直接在畫面右側敲出 TypeScript 型別。第一個是 DateInterval(start: Date、end: Date),對應時間軸與那個區間條;第二個是 PriceData(price_to_beat、price_final、price_target,先用 JavaScript 的 number);第三個是 DataSeries(string 型的 id,加上一個 data_points 陣列)。接著他開始做減法與合併,這才是這段的重點:DateInterval 的 start/end 跟 DataSeries 是強相關、欄位互相依賴(那些點就是從 start 走到 end),所以合併成一個型別;price_final 根本不需要抓,它就是最後一個資料點,屬於衍生狀態,直接刪掉;price_to_beat 看起來是獨立變數,值不值得跟 DataSeries 併成一次請求則取決於後端怎麼存——這正是他會反問面試官的地方。
AI 補充留意截圖裡型別演進的痕跡:s04_455 還是 DateInterval 與 PriceData 兩個獨立型別,到 s04_560 已經變成 DataSeries 裡直接長出 start、end、price_to_beat、price_target,而 price_final 消失了。這種「先寫出來再刪掉」的過程本身就是面試要看的東西——刪掉的理由(它是衍生的)比留下來的欄位更能證明你懂。另外補一個作者略過的細節:他把 timestamp 定成 string 是對的(JSON 沒有日期型別,網路上一律是 ISO 8601 字串),但 DateInterval 用 Date 型別代表這是「解析後」的前端模型;實務上這兩者要分開——API 回應型別用 string,前端狀態型別用 Date,中間有一層 parse。他沒說出這一步,但那是所有「timestamp 是字串、之後要 parse」的話真正的落點。
「you want a lot of decimals, then those numbers can store a lot more than a plain integer」
5. 用 AI 幫忙設計 state 的界線 9:29–10:35
主持人追問:這段你是手工一個一個做的,如果允許,你會怎麼用 AI?他說 AI 可以拿來精煉或腦力激盪狀態架構——他錄影前就把 UI 丟給 Claude,第一版給了一個過度複雜的資料結構,他回「把它簡化」才得到接近的版本,還可以指定輸出成 diagrams.net 能吃的格式。但結果有落差:AI 把 target price 併進 chart data,也漏掉一些資料點。他的結論是 AI 不太算幻覺,而是「傾向膨脹」——會自己加上不必要的細節,也分不出畫面上哪些是靜態的;所以它能幫你迭代,但你自己要夠好才用得動它。

推理因為上一段的推導完全靠手,主持人直接追問可不可以外包給 AI。作者的答案是「可以拿來精煉與腦力激盪,但不能拿來定稿」,而且他有實測:錄影前他把這張 UI 丟給 Claude,第一版回來是一個過度複雜的資料結構,他回了一句「把它簡化」才收斂到接近的版本;他也提到可以直接指定輸出成 diagrams.net 吃得下的格式,截圖裡那份 chart_data / price_ticks 的 DBML 就是這樣來的。但結果跟他手推的版本有落差:AI 把 target_price 併進 chart_data,也漏掉一些欄位。他因此下了一個很精準的判斷——AI 在這裡不太算幻覺,而是「傾向膨脹」:會自己加上不必要的細節,也分不出畫面上哪些是靜態的。
AI 補充值得注意的是 AI 產出的其實是資料庫層的 schema(Table chart_data、Table price_ticks,還帶 decimal(18,2) 與索引),而作者要的是前端的狀態型別。這個落差本身就說明了「膨脹」是怎麼發生的:模型看到金融時間序列,就把整套後端最佳實務都倒出來,而不是回答「這個元件在瀏覽器記憶體裡需要記住什麼」。順帶一提,AI 用 decimal(18,2) 反而比作者手寫的 number 更貼近金融精度需求——所以正確的用法不是「誰對誰錯」,而是把 AI 當成會提出你沒想到的選項的同事,然後由你來砍。作者那句「你自己要夠好才用得動它」講的就是這件事:你得先有能力判斷哪些細節是必要的,膨脹才會變成資產而不是雜訊。
6. data point 與請求合併的取捨 10:35–11:55
最後補完 data point 這個型別:id(一樣用 UUID)、timestamp(走網路時是字串,之後要 parse)、value(示範用 number,金融場景其實更適合 BigInt),並說明 data series 會裝著一個 data point 陣列——這在資料庫層叫 referential integrity,在前端就是「這批點是跟著這個序列一起來的」。收尾時他再次把選擇丟回給面試官:能不能把 price data 和 data series 併成單一請求?如果對方說隨你,他就併起來,理由是「簡單永遠優於複雜」。

推理因為上一段指出 AI 的版本缺了資料點的細節,作者回頭把 DataPoint 寫完:id(一樣用 UUID)、timestamp(走網路時是字串,之後要 parse)、value(示範用 number,並再次提到金融場景可能需要更高精度)。接著他說明 DataSeries 裡那個 data_points 陣列在資料庫層叫做 referential integrity,但在前端只需要知道「這批點是跟著這個序列一起送來的」。收尾時他把選擇丟回給面試官:能不能把 price data 與 data series 併成單一請求?如果對方說隨你,他就併——理由只有一句「簡單永遠優於複雜」。截圖 s07_760 就是併完之後的最終型別:DataSeries 裡同時裝著 start、end、label、price_to_beat、price_target 與 data_points。
AI 補充「一次請求還是兩次請求」看起來是小事,實際上是這場面試裡少數會被追問到底的地方,因為它同時牽涉三件事:後端資料是不是存在同一張表(影響能不能一次撈)、兩份資料的更新頻率是否相同(影響能不能共用快取策略)、以及前端要不要處理「部分載入成功」的狀態。作者選擇合併是為了讓 loading / error 只有一組,這會讓後面的狀態形狀乾淨很多。另外補一個型別上的細節:他寫的 id: uuid 在 TypeScript 裡並不存在這個型別,實務上要嘛就寫 string,要嘛用 branded type(type UUID = string & { __brand: 'uuid' })拿到編譯期保護。白板上這樣寫沒問題,因為意圖清楚;但如果面試官追問,能講出 branded type 會是加分。
7. 狀態轉移與狀態管理選型 11:55–14:45
資料的「形狀」定完,接著是狀態轉移。他給了一條掃描規則:前端改變狀態只有兩個原因——後端來的資料,或使用者事件;他固定先做後端那條,因為最單純。落地頁要 fetch data series,於是狀態變成 data / loading / error 三件套。使用者這邊是點選不同時間區間,會改動 start date 與 end date,而且改完要重新觸發 fetch,圖才會跟著換。最終狀態就是「有初始值的 start/end date」加上「與後端同步的 data series + loading + error」。選型上他判斷這些狀態都在元件層級,用 useState 就夠,不需要全域狀態;唯一值得引進的是 TanStack 這類外部函式庫,直接拿現成的資料抓取 hook,不必自己重造輪子。框架則假設用 React,因為最普遍、也是對方的技術棧。


推理因為上一段只交出了靜態的型別,作者接著給出一條掃描規則:前端會改變狀態只有兩個原因——後端送來資料,或使用者做了事情。他固定先掃後端那條,因為最單純:落地頁要 fetch data series,於是狀態變成 data / loading / error 三件套(截圖 s07_830 上那行 [data: DataSeries, loading, error] 就是這個)。再掃使用者事件:可以點的時間區間會改動 start_date 與 end_date,而且改完必須重新觸發 fetch,圖才會跟著換。最終狀態因此只有兩組:一組是有初始值的 {start_date, end_date},一組是跟後端同步的三件套。選型上他判斷這些狀態都在元件層級,useState 就夠,不需要全域狀態;唯一值得引進的是 TanStack 這類函式庫,直接用現成的資料抓取 hook,不必自己重造輪子。框架則假設 React——最普遍,也是對方的技術棧。
AI 補充「先掃後端、再掃使用者事件」這條規則之所以有效,是因為它把狀態來源窮舉了:任何一個你想不出屬於哪一類的變數,八成就是衍生狀態。另外請注意作者在這裡跳過了一步:他說使用者點區間會「觸發 fetch」,但沒說這代表 start_date / end_date 其實是查詢的參數,而 data / loading / error 是那個查詢的結果——兩者是因果關係,不是並列的兩份狀態。認清這點,TanStack Query 的角色就自然了:你把 [start_date, end_date] 當成 queryKey,其餘的載入、錯誤、重試、快取全部由它托管,你自己一份狀態都不用寫。這也直接解釋了後面談快取時為什麼他還會回頭找 TanStack——因為 queryKey 一旦定好,快取就是免費的。
8. 最小可行前端:框架、設計系統、CSS、無障礙 14:45–17:00
有了狀態就能往實作細節走。他先問怎麼交付:這是塞進現有 SPA 的元件,還是要進設計系統?如果要重用,就得問「不同實例之間會變的是什麼」——他判斷是資產本身,所以 props 至少要能收 asset name,再據此抓對應的 data series。接著他一條條記下最小可行前端:框架用 React;問對方有沒有設計系統與 design token(顏色、字體這類最小設計單位),沒有就自己定;CSS 用 CSS Modules 避免全域衝突,但要先問他們是不是用 Tailwind 這類 atomic CSS;無障礙則以語意化 HTML 為主,並確保畫面上的順序就是 JSX 標記裡的順序。

推理因為狀態已經穩定,作者才允許自己往實作細節走。他先問交付形式:這是塞進現有 SPA 的元件,還是要進設計系統?這個問題會決定 API 設計——如果要重用,就得問「不同實例之間會變的是什麼」,他判斷是資產本身(BTC、ETH…),所以 props 至少要能收 asset name,再據此抓對應的 data series。接著他在白板左下角列出一張編號清單(截圖 s08_975 與 s09_1070 可以看到它逐條長出來):1. React.js;2. 有沒有設計系統與 design token,沒有就自己定;3. CSS 用 CSS Modules 避免全域衝突,但要先問對方是不是用 Tailwind 這類 atomic CSS;4. 無障礙以語意化 HTML 為主,並確保畫面上的視覺順序就是 JSX 標記裡的順序。他把這張清單稱為「最小可行前端」。
AI 補充「畫面順序等於標記順序」這句話值得展開,因為它是無障礙裡最常被違反、也最容易在面試中講出深度的一點:螢幕閱讀器與鍵盤 Tab 走的是 DOM 順序,而 CSS(flex 的 order、grid 的定位、絕對定位)可以讓視覺順序跟 DOM 順序不一致,於是視覺上「下一個」按鈕在鍵盤上可能要 Tab 十次才到得了。對這支影片的圖表元件來說還有第二層:折線圖對螢幕閱讀器等於一張空白圖片,正確做法是提供一個等價的資料表格,或至少用 aria-label 播報當前價與變化幅度——這是作者提到無障礙卻沒展開的部分。另外「最小可行前端」這個框架的用意是替自己止血:把技術選型一次講完、標記為已決定,才不會在後半場被拉回來爭論 Tailwind 好不好。
9. 建置工具與 AI 時代的程式碼品質 17:00–19:35
建置工具他會先問對方現在用什麼:傳統是 webpack,但現在多半用 Vite(最好上手又快)或 esbuild;如果對方有既有 webpack 設定又想要速度,可以換 Rspack(用 Rust 重寫的 webpack)。CSS 也要有對應的建置管線(SASS?CSS Modules?styled-components?)。程式碼品質他分兩層:靜態品質是 TypeScript(型別檢查不容妥協)、linter(相容性最好是 ESLint,但 oxlint 快非常多)、以及 Prettier——他強調 Prettier 在 agent 寫程式的時代特別重要,因為 agent 產的 PR 動輒六千行,大家格式與寫法一致,PR 才會小、才 review 得動。動態品質就是把程式跑起來,也就是測試:先讓 agent 列計畫、分析邊界情況,再寫元件測試,然後補端到端測試——coding agent 寫這些很快。

推理因為清單的第五項就是建置工具,作者先問對方現在用什麼:傳統是 webpack,現在多半是 Vite(最好上手又快)或 esbuild;如果對方有既有的 webpack 設定又想要速度,可以換 Rspack,也就是用 Rust 重寫的 webpack。CSS 也要有對應的建置管線。接著主持人把問題導向「既然假設用 AI 寫這個專案,品質怎麼守」,作者把答案分成兩層。靜態品質是不執行程式就能查的:TypeScript 型別檢查沒得商量;linter 相容性最好的是 ESLint,但 oxlint 快非常多;Prettier 則被他特別強調——因為 agent 產的 PR 動輒六千行,唯有格式與寫法一致,diff 才會小到 review 得動。動態品質就是把程式跑起來,也就是測試:先讓 agent 列計畫、分析邊界情況,再寫元件測試,然後補端到端測試,而 coding agent 寫這些特別快。截圖 s10_1225 上那份「6. Code Quality → Static / Dynamic」就是這段的成果。
AI 補充這段最值得帶走的是它把 Prettier 的價值重新定位了。過去 Prettier 被當成品味問題(少吵架、省時間),在 agent 寫程式的情境下它變成 review 的可行性問題:人類 review 的瓶頸是 diff 的行數,而風格不一致會讓實質改動被格式噪音淹沒。同樣的邏輯也適用於 lint 規則與檔案結構——你不是在管束人類,而是在替模型設定一個窄的輸出空間。作者沒有明說但邏輯上緊接著的是:這正是他後面「穩定錨點產物」那套主張的前身,兩者都在做同一件事——把模型可以自由發揮的維度壓小。另外補一點他跳過的:靜態品質還缺一個 CI 閘門,型別檢查與 lint 只有在 pull request 上強制執行時才真的有效,否則 agent 可以直接繞過。
10. Web 效能的三個維度 19:35–21:55
確認面試官買單後,他主動把話題帶到非功能性需求,先攻 web 效能與可擴展性,並點出資淺與資深的差別就在「顆粒度」:junior 會丟一句「那就 code splitting」或「架個 CDN」就沒了;senior 會先攤開三個維度——載入速度、對使用者輸入的反應速度、版面穩定性——再逐一探問它們各有多重要。以載入速度為例,他問這是不是公開頁面、SEO 重不重要、流量會不會很大;判斷會很大之後才進到手段:先做 bundle splitting 只載入需要的 JavaScript;再看 UI 周邊有大量靜態內容,適合 SSR,只動態渲染圖表與數字,其餘預先渲染——這同時也把 CLS(累積版面位移)壓下來,因為東西已經先渲染好了,甚至可以把預設區間也一起預渲染,讓初始畫面很快出現、只是還不能互動。


推理因為前面已經取得面試官對功能面的認可,作者主動把話題帶去效能與可擴展性,並先點出資淺與資深的差別在於顆粒度:junior 丟一句「那就 code splitting」或「架個 CDN」就沒了;senior 會先攤開三個維度——載入速度、對使用者輸入的反應速度、版面穩定性——再逐一探問它們各有多重要。他以載入速度示範這種探問:這是公開頁面嗎?SEO 重要嗎?流量會很大嗎?判斷「這種小工具會出現在很多地方、流量很大」之後才進到手段:第一是 bundle splitting,只載入需要的 JavaScript;第二是既然元件周圍有大量靜態內容,適合用 SSR,只動態渲染圖表與數字,其餘預先渲染,而這同時把 CLS 壓下來;甚至可以連預設時間區間也一起預渲染,讓初始畫面很快出現,只是還不能互動。
AI 補充這三個維度不是隨口列的,它們一一對應 Core Web Vitals:載入速度是 LCP,對輸入的反應是 INP,版面穩定是 CLS。把這件事講出來,你的回答就從「我知道幾個名詞」變成「我有一個可量測的框架」。作者的提問順序也值得學:先問使用情境(公開?SEO?流量?),再選手段——因為同樣是效能,公開頁面在意首屏與 SEO,而登入後的內部儀表板在意的是互動延遲,手段完全不同。至於「先出現、還不能互動」那句,指的是 SSR 與 hydration 之間的空窗:HTML 已經在畫面上,但 JavaScript 還沒接手,這段期間點擊沒有反應——這正是 INP 與 TTI 這類指標要抓的東西,也是 React Server Components 與 streaming SSR 想縮短的區間。
「There will be no layout shifts because we already preloaded this」
11. BFF:讓介面穩定下來 21:55–23:55
主持人指出前端的可擴展性其實單純(CDN、靜態資產、bundle 一發就到使用者手上),瓶頸會在後端,於是問 BFF 該不該上。他的判準是:看資料來源、以及拿到的形狀跟想要的形狀差多少;如果落差很大,或那個服務不是我們擁有、又常改 API,就用 BFF 當前端的穩定介面——服務改了只要改 BFF,前端不用動。他再補一個現代理由:用 coding agent 時,穩定介面讓大規模的根因分析可行,出事能靠 AI 快速定位;反之如果每次改動都橫跨所有系統、每個 PR 都在動所有東西,就會非常混亂不穩。主持人為觀眾補充定義:BFF 是加在 API 與前端之間、用來吸收變動的中介層;作者補充它可以是 REST 或獨立的 GraphQL,往下游取資料再回傳,也就是反向代理。

推理因為主持人指出前端的可擴展性其實單純(CDN、靜態資產、bundle 一發就到使用者手上),真正的瓶頸會在後端,於是問 BFF 該不該上。作者的判準有兩條:一是拿到的資料形狀跟想要的形狀差多少,二是那個服務是不是我們擁有、會不會常改 API。落差大或不受控時就用 BFF 當前端的穩定介面——資料服務改了只要改 BFF,前端不用動(截圖 s11_1370 那張 FE → BFF → 資料服務的方框圖畫的就是這個)。他接著補了一個現代理由:用 coding agent 時,穩定介面讓大規模的根因分析變得可行,出事能靠 AI 快速定位;反之如果每次改動都橫跨所有系統、每個 PR 都在動所有東西,就會非常混亂不穩。主持人替觀眾補上定義(加在 API 與前端之間、吸收變動的中介層),作者補充它可以是 REST 或獨立的 GraphQL,往下游取資料再回傳,也就是反向代理。
AI 補充把 BFF 的理由講成「形狀落差 + 變更頻率 + 所有權」是這段最有用的部分,因為它讓你能回答反方向的問題:什麼時候不該上 BFF?答案是資料形狀本來就貼合、服務由自己團隊擁有時——那時多一層只是多一個要部署、要監控、要在 on-call 時被叫醒的東西。作者沒提到但實務上同樣重要的兩個 BFF 好處是:把 API 金鑰與權杖留在伺服器端(前端不必持有機密),以及把多次下游請求收斂成一次(省掉行動網路上的往返延遲)。至於「穩定介面讓 AI 好除錯」那個論點,本質上跟他前面說的 Prettier 是同一招——都是在替模型縮小需要理解與改動的範圍。
12. 即時更新:SSE,以及把狀態壓到最小 23:55–27:25
回到即時更新,他先問通訊是不是真的雙向,再比三種做法。輪詢(polling)最穩健,但擴展性極差:大量客戶端一起輪詢等同於對自家後端發動 DDoS,一個畫面上有十個這種元件、每兩秒更新一次,單一使用者就是每兩秒十個請求。WebSocket 實作複雜且是雙向的,適合聊天那種客戶端也要送資料回去的場景,但這裡前端只需要重繪,不需要把資料反映給其他客戶端。所以他選 Server-Sent Events——現在多數 LLM 應用都在用的原生 API,監聽一個 URL、持續收事件塊,事件的形狀就是 data point。收到新點之後在應用層做狀態更新:把點推進 data series。接著他處理畫面上看似很多事同時發生的部分(圖在動、區間在移、當前價在跳、還有一堆增減數字),逐一拆解後發現全都能從那一個新資料點推出來:用新點的 timestamp 更新區間、更新當前價、差值只要記住「你進頁面時的起點」再相減、時間也是進頁面的時間。結論是他不需要額外狀態,一個新資料點就能重繪整塊——狀態要保持越小越好。



推理因為上一段留下的問題是即時更新,作者先把判準立起來——通訊是不是真的雙向——再比三種做法。輪詢最穩健,但擴展性極差:大量客戶端一起輪詢等於對自家後端發動阻斷服務攻擊,一個畫面上放十個這種元件、每兩秒更新一次,單一使用者就是每兩秒十個請求。WebSocket 實作複雜而且是雙向的,適合聊天那種客戶端也要送資料回去、還要反映給其他客戶端的場景;但這裡前端只需要重繪,沒有要送任何東西回去。所以答案落在 Server-Sent Events——現在多數 LLM 應用都在用的原生 API,監聽一個 URL、持續收事件塊,事件的形狀就是 DataPoint,收到後在應用層把它推進 data series。接著他處理畫面上看似同時發生的一堆事(折線在長、區間在移、當前價在跳、左側還有一疊 +$35、+$99 的增減數字),逐一拆解後發現全都能從那一個新資料點推出來:用新點的 timestamp 更新區間、更新當前價,差值只要記住「你進頁面時的起點」再相減,時間也是你進頁面的時間。結論是他不需要任何額外狀態。
- C即時更新選SSE:判準是通訊是不是真的雙向,這裡只需要重繪不用送資料回去→ 畫地圖
- A只存基準值+當前值就能算出所有變化,像記帳只記起訖餘額不用存每筆交易→ 批判類比
- EHTTP/1.1每網域只有六個連線,一頁十個圖表各開一條SSE會卡死→ 存+演練
AI 補充SSE 在這裡是正確答案,但值得補上它的實際限制,因為面試官很可能追問:HTTP/1.1 下每個網域同時只有六個連線,而一個 SSE 連線會一直佔著,所以「一頁十個圖表各開一條 SSE」會直接卡死——真正的解法是共用一條連線並在事件裡帶 asset id 分流,或走 HTTP/2 讓多條流共用同一個 TCP 連線。另外 SSE 只能傳文字(要傳二進位得先編碼)、瀏覽器會自動重連並用 Last-Event-ID 續傳,這個自動重連正是它比手寫輪詢好的地方。至於最後那段狀態最小化的推理,可以總結成一句可以帶走的規則:如果一個畫面元素能從「一份基準」加「當前值」算出來,那就只存基準與當前值。這也解釋了他為什麼要把「你進頁面的那一刻」單獨記下來——那就是基準,而不是把每一筆差值都存成陣列。
13. 快取:用讀寫比決定快取什麼 27:25–31:00
主持人補問快取,他先給判準:看資源的讀寫比(read/write ratio)——讀遠多於寫就值得快取,而且這條規則要套用到系統裡的每一樣東西。靜態資產(JS、CSS)用 CDN 推到邊緣節點,再配合有效的快取政策。設計系統的 CSS 比應用其他部分穩定得多,讀多寫少,所以值得把它從 bundle 裡拆出來獨立成檔——這時就得深入建置工具,因為 CSS-in-JS 那類做法會把 style 標籤塞進 HTML,跟文件耦合在一起,根本沒辦法快取。動態資料這邊,他指出圖表資料有個很好用的性質:過去的資料是唯讀的,昨天的股價沒有人會回頭改寫,所以所有已成為過去的資料點都能套很積極的快取政策。他因此做 HTTP 快取(大家共用同一份、也快取在客戶端),再加上客戶端狀態快取——TanStack 可以針對特定請求自訂快取政策,把已經拿過的區間或資料點存在客戶端,切換區間時完全不必回伺服器。唯一不能快取的就是 SSE 送來的未來資料。最後補上框架層級的 use cache、useMemo 這類優化避免重繪。


推理因為主持人補問快取,作者先立一條判準再往下套:看資源的讀寫比——被讀的次數遠多於被寫的次數就值得快取,而且這條規則要套用到系統裡的每一樣東西。他分兩層走。靜態資產(JS、CSS)用 CDN 推到邊緣節點,配上有效的快取政策;其中設計系統的 CSS 又比應用其他部分穩定得多,讀多寫少,所以值得從 bundle 裡拆出來獨立成檔——這時就得深入建置工具,因為把樣式塞進 HTML 的 style 標籤等於跟文件耦合,根本沒辦法獨立快取。動態資料這層他抓到一個很漂亮的性質:過去的資料是唯讀的,昨天的股價沒人會回頭改寫,所以所有已成為過去的資料點都能套很積極的快取政策。他因此做 HTTP 快取(大家共用同一份、也快取在客戶端),再加上客戶端狀態快取——TanStack 可以針對特定請求自訂快取政策,把已經拿過的區間存在客戶端,切換區間時完全不必回伺服器。唯一不能快取的是 SSE 送來的未來資料。最後補上框架層級的 use cache、useMemo 這類優化避免重繪。
- C讀寫比高就該快取:過去唯讀的資料點能套積極快取政策,未來的資料不能快取→ 畫地圖
- E已結束區間回Cache-Control: public, max-age=31536000, immutable;含當下的區間回no-store→ 存+演練
- RHTTP快取和TanStack的客戶端快取有什麼不同→ 存+回想
AI 補充「過去唯讀、未來不可快取」這個切法之所以強,是因為它把快取問題從「要快取多久」變成「這筆資料在時間軸的哪一側」——而後者有明確答案。落實成 HTTP 標頭大概是:已結束區間的資料回 Cache-Control: public, max-age=31536000, immutable;包含當下的區間回 no-store 或極短的 max-age。這裡也要補一個作者略過的難點:包含「現在」的那個區間會不斷變動,最乾淨的做法是把請求依區間邊界對齊(例如一律以整分鐘切段),讓 URL 本身就決定了它是不是已完結——否則每個使用者的 URL 都不一樣,共用快取形同虛設。另外 HTTP 快取與 TanStack 的客戶端快取是兩層不同的東西:前者由瀏覽器與 CDN 執行、跨分頁與重新整理都有效,後者活在記憶體裡、換頁就沒了但可以做樂觀更新與背景重抓,兩者互補而不是二選一。
「they add a style tag in your HTML file」
14. AI 開發工具鏈:模型、harness、審查代理 31:00–35:50
兩個 AI 提問:用什麼模型與工具開發、以及若要整合 AI 應用該怎麼做。他常用 Anthropic 的模型,提到 Opus 4.7 在部分任務相對 4.6 有些退步,Codex 搭 GPT-5.5 也可比較,各有強項。但他強調的重點是:不論用哪個,這些模型都缺乏視覺智能,所以進場前要在程式庫裡準備穩定的「錨點產物」,讓模型只做這些產物之間的內插——設計系統(建構區塊)、狀態圖、以及跟後端往來時的循序圖,等於讓模型 program to interfaces。harness 他建議用原生的:用 Anthropic 模型就用 Claude Code,或用 OpenCode 搭不同模型(通常較便宜、效果差不多且能換模型);但終端介面做進階 code review 很受限,開發與重構時 Cursor 的 agent mode 與 Composer 好用得多,代價是定價較差。成本敏感時他提到 Kimi 2.6 搭 Kimi Code 這類選項;但既然是金融機構,資料限制多,他反而會問對方有沒有本地 AI 的計畫——自架、用 Ollama 跑 Qwen 之類的模型,本機跑 15B 有堪用的效能,只是跟數千億參數的雲端模型差距很大。最後是 code review agent,搭配 Chrome MCP 讓 agent 能自己測自己寫的東西,並用審查代理來摘要 PR、專門掃安全問題與無障礙這類瑣事;審查代理找到 bug 可以把提示直接餵回 coding agent 修好再推回 PR,但要大量監督,否則兩個 agent 會互相修改進入無窮迴圈。


推理因為技術面已經收完,主持人丟出兩個 AI 提問:用什麼模型與工具開發、以及要整合 AI 應用該怎麼做。作者先講模型偏好(他自己主要用 Anthropic 的模型),但立刻把重點轉開——真正的關鍵是這些模型都缺乏視覺智能,所以進場前要在程式庫裡準備穩定的錨點產物,讓模型只做這些產物之間的內插。截圖 s14_1955 上寫得清清楚楚:Stable Artifacts → Design System、State Diagram,接著是 Sequence Diagram(跟後端往來時用)。這就是他說的「program to interfaces」。harness 他建議用原生的:Anthropic 模型就用 Claude Code,或用 OpenCode 搭 OpenRouter 換模型(通常較便宜、效果差不多);但終端介面做進階 code review 很受限,開發與重構時 Cursor 的 agent mode 與 Composer 好用得多,代價是定價較差。成本敏感時他提到 Kimi 這類選項;但既然是金融機構,資料限制多,他反而會問對方有沒有本地 AI 計畫——自架、用 Ollama 跑 Qwen 之類的模型,本機跑 15B 有堪用效能,只是跟雲端大模型差距明顯。最後是 code review agent:搭配 Chrome MCP 讓 agent 能自己測自己寫的東西,並用審查代理摘要 PR、專門掃安全與無障礙這類瑣事;審查代理找到 bug 可以把提示直接餵回 coding agent 修好再推回 PR,但要大量監督,否則兩個 agent 會互相修改進入無窮迴圈。
AI 補充「穩定錨點 + 內插」這個說法值得認真對待,因為它把前面所有段落串成同一件事:設計系統來自最小可行前端那一段,狀態圖來自狀態轉移那一段,循序圖對應資料路徑與 SSE 那幾段——換句話說,這場面試走完的那條路線,產出的正好就是餵給 coding agent 的那組錨點。這也是整支影片最有價值的隱藏論點:系統設計不是「AI 會寫程式後就不用學的東西」,反而是你在 AI 時代唯一需要親自產出的東西。至於他對模型的具體推薦,是 2026 年 5 月當下的快照,換一季就會過時(見下方勘誤);但判準不會過時——資料能不能出境、預算、以及 harness 適不適合做 review,這三個問題永遠都要問。
「probably everybody talks about about Opus 4.7」
「I think was it 800 billion parameters」
15. 回頭看:還會再深掘的地方 35:50–37:10
被問到這份架構回頭看還會補什麼,他點出三塊。一是重用性:這個元件到底要不要當成設計系統的一部分出貨,若要就會談到 Storybook 這類工具;如果是 SPA,還會追問渲染策略——SSR、SSG(這裡大概不適用)、增量或部分預渲染,這是更深一層的取捨。二是整體前端架構:他們現在是什麼架構、有沒有在看微前端、CSS 架構走的是 Tailwind 那種 atomic CSS 還是 styled-components。三是他自承漏掉的行動裝置響應式:用相對單位而不是寫死像素、多用 flexbox 與 media query。
推理因為被問到「回頭看會補什麼」,作者點出三塊他刻意沒展開的地方。一是重用性:這個元件到底要不要當成設計系統的一部分出貨,若要就會牽出 Storybook 這類工具;而如果它活在 SPA 裡,他會追問渲染策略——SSR、SSG(他判斷這裡大概不適用)、或是增量與部分預渲染。二是整體前端架構:對方現在是什麼架構、有沒有在看微前端、CSS 架構走的是 Tailwind 那種 atomic CSS 還是 styled-components。三是他自承整場漏掉的行動裝置響應式:用相對單位而不是寫死像素、多用 flexbox 與 media query。
AI 補充這一段的形式比內容更值得學:主動列出自己沒挖夠的地方,等於把「還能聊什麼」的清單交給面試官,而這正好治好開場提到的那個病——沒話講。注意他列的三項都是「有明確取捨、可以聊十分鐘」的題目,不是隨口的補充。至於 SSG 為什麼不適用,他沒說理由,補上很簡單:SSG 在建置時就把 HTML 產好,而這個頁面每秒都有新價格,建置時的內容一秒後就過期了;有意義的變體是把不會變的外框做成靜態、只把圖表那塊留給客戶端或 SSR——也就是他提到的部分預渲染。響應式那塊他給的建議偏基礎,對圖表元件真正的難點其實是容器查詢(container query)與 SVG 的 viewBox 縮放,因為圖表要跟著容器而不是視窗變形。
16. junior 與 senior 的差別,以及唯一的建議 37:10–40:31
最大的地雷是「沒話講了」。理想上這種題目可以聊五小時、提出好幾種方案,而你要主導那場討論,心裡有張地圖知道要走去哪、什麼叫可接受的最終結果,並帶著面試官走過每一步。junior 是工具導向(「我們應該用 styled-components」),senior 則是先講決策因素(要顧 web 效能,那就得考慮 bundle size),而且不是替對方做決定,而是攤開選項:A 方案、B 方案、C 方案,就這個問題情境我選 B。senior 也不被動——不必別人說「這要跑得快」,他自己會先問使用者是誰、再判斷效能重不重要,然後帶著對方走完決策。一句話總結:senior 能預判卡點與限制、提出選項並顧問對方,這不是在建造,是在諮詢;當 AI 已經在寫一半的程式碼,這點更明顯。最後的唯一建議:把設計做完整比被一堆選項搞混更重要;市面上的系統設計材料多半偏後端,而且大家都在練「怎麼設計 Uber、怎麼設計 Instagram」,但一般 SaaS 公司考的是這種有大量資料、大量表單的商業功能——把學到的東西帶回前端、帶回你每天真的在做的企業軟體,不要去解想像出來的系統。
推理因為前面已經把整條路線走完,作者最後把它折回到人身上。他說最大的地雷是「沒話講了」——理想上這種題目可以聊五小時、提出好幾種方案,而你要主導那場討論,心裡有張地圖知道要走去哪、什麼叫可接受的最終結果。junior 是工具導向(「我們應該用 styled-components」),senior 則先講決策因素(要顧 web 效能,那就得考慮 bundle size),而且不是替對方做決定,而是攤開選項:A、B、C,就這個情境我選 B。senior 也不被動——不必別人說「這要跑得快」,他自己會先問使用者是誰、再判斷效能重不重要,然後帶對方走完決策。一句話總結:senior 能預判卡點與限制、提出選項並顧問對方,這不是在建造,是在諮詢;當 AI 已經在寫一半的程式碼,這點更明顯。最後的唯一建議是:把設計做完整比被一堆選項搞混更重要;市面上的系統設計材料多半偏後端,而且大家都在練「怎麼設計 Uber、怎麼設計 Instagram」,但一般 SaaS 公司考的是這種有大量資料、大量表單的商業功能——把學到的東西帶回前端、帶回你每天真的在做的企業軟體,不要去解想像出來的系統。
AI 補充「提出選項而不是做決定」聽起來像溝通技巧,其實是資訊的問題:面試官知道你不知道的約束(既有技術棧、團隊規模、合規要求、時程),所以你單方面下的決定有一半機率踩到隱藏條件,而攤開選項讓對方能用他手上的資訊補完最後一步。要注意這不是含糊其辭——正確形式是「A、B、C,就我目前掌握的情境我選 B,因為 X」,你仍然要表態,只是把推導過程留在桌上。這也回頭解釋了整支影片為什麼每個階段都以提問開場:那些問題不是禮貌,而是在把隱藏約束一個個逼出來。至於「不要解想像出來的系統」這句,對照前面的內容就更清楚了:這支影片裡真正稀有的不是 SSE 或 BFF 這些名詞,而是「從一張 UI 推到最小狀態」的那段——那正是設計 Uber 這類題目永遠練不到的東西。
4. 總結
整支影片是一條單向推進的鏈。作者先指出面試失敗的真因不是技術而是「沒有心智里程碑」,於是把路線的第一站定為需求:不照單全收設計稿,把畫面翻成功能性與非功能性兩欄,並在此處只掛號不展開(無障礙、安全先點名,效能用 Core Web Vitals 與 SLO 量化),同時確認 UI 有即時更新,把問題劈成「初始載入」與「持續刷新」兩塊。這個劈法逼出第二站:既然要分靜態與即時,就得知道畫面上什麼會變——他用刪去法圈出動態欄位,再寫成 TypeScript 型別,過程中積極合併強相關的型別、刪掉能算出來的衍生狀態(price_final 就是最後一個資料點)。型別定完,AI 的第一次登場只是配角:它能幫你精煉狀態結構,但會膨脹細節、分不出畫面上哪些是靜態的。狀態有了形狀還缺變化規則,於是第三站給出窮舉法——前端改變狀態只有後端資料與使用者事件兩個來源——推出 data/loading/error 三件套加 {start_date, end_date},並據此判定用 useState 加 TanStack 就夠,不需要全域狀態。狀態穩定才有資格談實作,第四站列出「最小可行前端」(React、設計系統與 design token、CSS Modules、語意化 HTML)並延伸到建置工具與程式碼品質,這裡出現第一個 AI 時代的轉折:Prettier 不再是品味問題,而是六千行 agent PR 還 review 得動的前提。工程面收乾淨後才回頭處理一直掛在那裡的非功能性需求:效能拆成載入、互動、版面穩定三個維度逐一探問(對應 LCP、INP、CLS),手段落在 bundle splitting 與 SSR;可擴展性把瓶頸推向後端,引出 BFF 當前端的穩定介面;即時性用「是不是真的雙向」一刀砍掉 polling 與 WebSocket,選定 SSE,並在此把整支影片的隱藏主軸推到極致——畫面上四個同時在動的東西,全部能從一個新資料點算出來,所以不需要任何額外狀態;最後用讀寫比這條單一判準掃過所有層級決定快取什麼(CDN、獨立的設計系統 CSS、過去唯讀的資料點、TanStack 的客戶端快取)。全部收完後 AI 才第二次登場,而且是以同一套邏輯的延伸出現:模型缺乏視覺智能,所以要準備穩定的錨點產物讓它只做內插——而那組錨點(設計系統、狀態圖、循序圖)正好就是這條路線一路產出的東西。結論因此不是「AI 會寫程式所以不用學架構」,而是相反:系統設計成了你在 AI 時代唯一必須親自產出的東西,而評分標準是你能不能攤開選項顧問對方,而不是替他做決定。
勘誤總整理
確定錯誤/已過時見仁見智(取決於版本或情境)
| 段落 | 原話(transcript 逐字) | 說明 |
|---|---|---|
| 4. 把畫面翻成資料模型 7:45 |
「you want a lot of decimals, then those numbers can store a lot more than a plain integer」 | BigInt 不能存小數。它是任意精度的「整數」型別,寫 1.5n 直接語法錯誤。金融資料要精確小數,正確做法是存最小貨幣單位的整數(例如以「分」為單位存 8190242),或用 decimal.js / big.js 這類十進位函式庫;JavaScript 的 number 是 IEEE 754 雙精度浮點數,0.1 + 0.2 !== 0.3 的問題就出在這裡。 依據: ECMAScript 規範 BigInt 型別定義:BigInt values represent integer values;TC39 decimal 提案仍在 stage 1(2026) |
| 14. AI 開發工具鏈:模型、harness、審查代理 34:34 |
「I think was it 800 billion parameters」 | Anthropic 從未公開 Claude 任何一代的參數量,OpenAI、Google 同樣不公開,所以「800B」是沒有來源的猜測。另外他的推論方向也反了:大型雲端模型贏在能力與上下文長度,而不是比本地小模型「快」——同樣的硬體上,參數越多每個 token 越慢,雲端之所以感覺快是因為推論硬體與批次處理,不是因為模型大。 依據: Anthropic 官方模型說明頁未揭露任何參數量數據 |
| 10. Web 效能的三個維度 21:31 |
「There will be no layout shifts because we already preloaded this」 | SSR 能減少版面位移,但不等於「不會有」。hydration 前後的差異、晚載入的網頁字體造成的重排、以及圖表函式庫在客戶端算完尺寸後才調整容器,都還是會產生 CLS。真正的保證來自替容器預留固定尺寸(明確的高度或 aspect-ratio)與 font-display 策略,SSR 只是讓內容更早就位。 依據: web.dev CLS 最佳實務:Always include size attributes on images and video elements, or reserve space with CSS aspect-ratio |
| 13. 快取:用讀寫比決定快取什麼 28:37 |
「they add a style tag in your HTML file」 | 這個描述適用於 styled-components、Emotion 這類執行期的 CSS-in-JS,不適用於 CSS Modules。CSS Modules 是建置期把 class 名稱雜湊化,產出的仍是獨立的 .css 檔案,完全可以獨立快取——作者的結論(把設計系統的 CSS 拆出來單獨快取)是對的,但他把兩種技術混在同一句話裡講,字面上會誤導。 依據: css-loader / Vite 的 CSS Modules 產出獨立樣式表;styled-components v6 執行期以 <style> 注入 |
| 14. AI 開發工具鏈:模型、harness、審查代理 31:53 |
「probably everybody talks about about Opus 4.7」 | 這是 2026 年 5 月錄影當下的快照,現在已經換代:Anthropic 最新的是 Claude 5 系列(Opus 5、Sonnet 5、Fable 5.1)加上 Haiku 4.5。任何講具體模型版本的建議都有極短的保存期限,該帶走的是他的選型判準(資料能不能出境、預算、harness 適不適合做 review),而不是型號。 依據: 影片上傳日 2026-05-11;截至 2026-09 Anthropic 現行旗艦為 Claude Opus 5 |
5. 推薦三個下一步
1. 往下挖深:把 SSE 與即時圖表真的實作出來
影片在協定選擇(SSE)與狀態最小化就收手了,沒有講連線數限制、斷線重連、背壓、以及新資料點進來時圖表怎麼平滑重繪——這是從白板走到真實程式碼之間最大的一段缺口。
YouTube 搜尋:Server-Sent Events EventSource tutorial real-time chart React streaming data SSE vs WebSocket scaling HTTP/2
2. 往旁邊對照:後端版本的系統設計怎麼談同一個問題
作者刻意把後端當黑盒(BFF 之後就不談了),但即時金融資料在後端是完全不同的題目——時間序列儲存、扇出、訊息佇列。看過後端版本才知道 BFF 兩側各自的難處在哪。
YouTube 搜尋:system design real-time stock price feed time series database design interview fan-out message queue system design
3. 往上應用:把這條路線套到你自己的專案並產出錨點產物
影片最後的主張是設計文件(設計系統、狀態圖、循序圖)就是餵給 coding agent 的錨點。與其再看一支面試影片,不如學會用 Mermaid 把狀態圖與循序圖寫進版本控制,直接驗證這個主張。
YouTube 搜尋:Mermaid state diagram sequence diagram tutorial spec driven development AI coding agent frontend architecture decision record
- 接著看 ←Top 15 Frontend Interview Questions for 2026 (wa/ Senior Engineer) · 面試題的分類式答法與即時協定判準(SSE/WebSocket/Polling),在這站變成一整場完整設計
- 接著看 ←Every Frontend Architecture Pattern Explained in 23 Minutes · SSR、SSG、BFF、CDN 在架構演化站被系統性建立,這站直接當成選項拿來取捨
- 接著看 ←3 Frontend Skills AI Can't Replace (become AI-proof) · AI 取代不了的判斷力,在這站落成穩定錨點產物:設計系統、狀態圖、循序圖
- 接著看 ←Frontend System Design Explained w/ Senior Engineer (Microfrontends, Monorepo, MCP UI, Reactjs) · 這站建立的 SSE 判準、design system 與垂直切片,在那場模擬面試裡被拿來實際設計一個系統
- 接著看 ←15 Frontend Concepts Every Senior Dev Has Mastered · essential state 與衍生狀態的刪去法,在那場模擬面試裡實際用來圈狀態
- 接著看 ←How Senior Frontend Engineers Think in System Design Interviews · Clarify→Choose→Explain 的方法,在那站變成一整場實際答題的節奏
- 接著看 ←Real Frontend System Design (from a Senior Engineer) · 這站的需求拆解、流量估算與 scale level 順序,在那場完整模擬面試裡被實際跑一次
- 相關 —Senior Frontend Interview 2026 🎉 | Javascript 🎯 (Mock) [Most Asked Questions] · 兩場 2026 資深前端模擬面試:一場考觀念與手寫實作,一場考系統設計
- 接著看 ←15 Fullstack Concepts Every Frontend Should Know · SSE/WebSocket/polling 的機制差別在這站建立,那站直接拿來選型
- 接著看 ←How Frontend Engineers can master the Full-stack · BFF 與 SSE/WebSocket 的判準被用在面試現場的取捨
- 相關 —Lauren Tan grokbot workshop 中文字幕 · 同談 AI 寫程式的 hallucination:一個在面試現場,一個在生產流程
- 相關 —How Web Sockets work | Deep Dive · 共用 WebSocket/SSE:這站給雙向連線的機制,那站在面試裡決定該不該選它
- 相關 —How a Cloudflare Engineer Ships Production Code He Didn't Write | Dillon Mulroy · 共用 harness 與 AI 工具鏈:一站在面試裡要人守設計錨點,一站在生產裡要人守 context 與 spec