「講一次你克服技術難題的經驗」是行為面試(behavioral)幾乎必考的一題。它考的不是「你有多會 debug」,而是你面對未知問題時的思路是否有條理、是否會量化、是否能把功勞與教訓講清楚。
很多人一開口就掉進兩個坑:① 流水帳——「然後我又試了這個、又試了那個」;② 太技術——埋進一堆細節,面試官聽不到「你」在哪裡。解法是 STAR 框架:Situation(情境)→ Task(任務)→ Action(行動)→ Result(結果)。
這篇用一場真實感的 OAuth Authorization Code + PKCE 登入除錯當素材,示範怎麼把它講成一個有結構、有數字、可被追問的故事。
先記住 STAR 的比例
| 段落 | 講什麼 | 佔比 | 常見錯誤 |
|---|---|---|---|
| S Situation | 一兩句背景:什麼專案、為什麼這事重要 | ~15% | 講太長、鋪陳太多 |
| T Task | 你的具體目標與限制(時間/影響範圍) | ~15% | 用「我們」模糊掉個人責任 |
| A Action | 你的除錯思路:假設 → 驗證 → 排除 | ~50% | 變流水帳、沒講「為什麼這樣試」 |
| R Result | 量化結果 + 學到什麼 | ~20% | 沒有數字、沒有反思 |
💡 核心心法:Action 是主秀,但重點不是「你做了什麼」,而是「你為什麼這樣判斷」。把除錯講成「用二分法縮小問題範圍」的思路,比列出十個步驟有力得多。
這題的技術背景(先讓自己講得清楚)
OAuth 2.0 的 Authorization Code Flow + PKCE(Proof Key for Code Exchange)是現代前端/行動 App 登入的標準做法。流程簡述:
- Client 產生隨機
code_verifier,雜湊成code_challenge。 - 把
code_challenge帶去 authorization endpoint,使用者登入後拿回authorization code。 - Client 用
code加上原始的code_verifier去換 token。 - Server 重新雜湊
code_verifier、和當初的code_challenge比對,一致才發 token。
PKCE 的價值:就算授權碼在重導向過程被攔截,攻擊者沒有 code_verifier 也換不到 token。最常見的踩雷點:code_verifier 在重導向後遺失或被重新產生,導致 server 端比對失敗——回一個語焉不詳的 invalid_grant。
逐字稿示範(中文,~370 字)
人名、數字為示範用,練習時換成你自己的真實經歷。
「【S】 我們在替一個 B2B 後台做登入改造,從自建帳密改成走第三方 IdP 的 OAuth。上線前一週,QA 回報約三成使用者在登入最後一步卡住,畫面停在重導向、控制台只丟一個
invalid_grant。【T】 我負責這條登入鏈路。目標是在不延後上線的前提下,找出為什麼是「部分使用者」失敗、並修掉它。
【A】 我先不亂改 code,而是用二分法縮小範圍。第一個假設:是不是某些瀏覽器的問題?我比對失敗案例,發現全集中在開了多分頁的使用者。這給了我關鍵線索。接著我把 PKCE 的
code_verifier生命週期攤開來看——我們把它存在sessionStorage,而它是每個分頁獨立的。使用者在 A 分頁發起登入、IdP 重導向卻回到 B 分頁時,B 分頁的sessionStorage沒有那個verifier,前端就重新產生了一個新的去換 token,server 比對當然失敗。我用一個刻意開兩分頁的腳本穩定重現了這個 bug,確認假設。【R】 修法是把
code_verifier連同一個state綁定、存到跨分頁可共享且有 TTL 的儲存,並在回呼端用state取回對應的 verifier。修完登入失敗率從 ~30% 降到 0.2% 以下,如期上線。我也學到一件事:模糊的錯誤碼背後,往往是『狀態存錯地方』,先縮小範圍再讀規格,比埋頭改 code 快得多。」
English Script (~250 words)
"[S] We were revamping login for a B2B admin console, moving from our own credentials to a third-party IdP over OAuth. A week before launch, QA reported that about 30% of users got stuck on the final step — the page hung on the redirect and the console only showed a vague
invalid_grant.[T] I owned this login flow. My goal was to find out why only some users failed and fix it without slipping the launch date.
[A] Instead of randomly changing code, I narrowed it down by bisection. First hypothesis: a browser issue? Comparing the failing cases, I found they were all users with multiple tabs open — a key clue. I then traced the lifecycle of the PKCE
code_verifier: we stored it insessionStorage, which is per-tab. When a user started login in tab A but the IdP redirected back to tab B, tab B'ssessionStoragehad no verifier, so the frontend generated a fresh one to exchange the code — and the server's comparison naturally failed. I reliably reproduced it with a script that deliberately opened two tabs, confirming the hypothesis.[R] The fix was to bind the
code_verifierto astatevalue in cross-tab storage with a TTL, and retrieve it bystatein the callback. Login failures dropped from ~30% to under 0.2%, and we shipped on time. My takeaway: a vague error code usually means 'state stored in the wrong place' — narrowing the scope before re-reading the spec beats blindly editing code."
面試官最愛追問的點(先準備好)
-
🎤 「為什麼是 PKCE 而不是直接傳 client secret?」 → 前端/行動 App 無法安全保存 secret;PKCE 用一次性的 verifier/challenge 取代固定 secret,防止授權碼被攔截後盜換 token。
-
🎤 「你怎麼確定是
sessionStorage而不是別的原因?」 → 強調可重現性:我做出穩定重現腳本,把問題隔離到「多分頁」這單一變因,這是判斷根因(而非猜測)的關鍵。 -
🎤 「你的修法有沒有引入新風險?」 → 誠實談取捨:跨分頁儲存要加 TTL 與
state綁定避免 verifier 被濫用或殘留,並確認不破壞 CSRF 防護(state本來就在做這件事)。 -
🎤 「如果重來一次,你會怎麼更快發現?」 → 反思題必考:我會在登入鏈路加上更具體的錯誤分類與日誌,讓
invalid_grant能對應到「verifier 不存在」這種可診斷的內部碼。
💡 應對追問的原則:每個「可被追問點」你都要準備好往下深挖一層。故事是入口,追問才是真正展現深度的地方。
打磨清單(套用到你自己的故事)
- S/T 各壓到一兩句,把時間留給 Action 與 Result
- Action 至少出現一次「我的假設是…所以我去驗證…」——展現思路而非步驟
- Result 一定有數字(失敗率、時間、影響人數),再加一句學到什麼
- 全程用「我」描述你的判斷與行動,「我們」只用在交代團隊背景
- 預先準備 3 個追問的答案(原理、根因如何確認、取捨/反思)
- 中英兩版同一套結構,方便記憶也保持邏輯一致
- 念出來計時,控制在 2–2.5 分鐘
結語
「克服技術難題」這題真正考的,是你能不能把一團混亂的除錯過程,整理成一條有假設、有驗證、有結果的清晰敘事。OAuth/PKCE 這種「狀態存錯地方」的 bug 特別適合拿來講——因為它的精彩之處不在 code,而在你如何縮小範圍、確認根因。
把故事寫成 STAR、塞進數字、留好追問鉤子,這一題就從「隨便聊聊」變成你整場面試的技術深度展示位。下一篇會接著拆 STAR #3:衝突與協作。