Bài này nói về leadership frontend mức senior: cân nhắc lặp lại được, không phải charisma. Người phỏng vấn muốn bạn kéo người thế nào, ghi lựa chọn kiến trúc, ước lượng khi chưa chắc, bất đồng mà không đốt phòng, và nói lúc incident, cùng vòng với Vue.
Đọc 17.1–17.2 trước (mentorship, rồi artefact ADR). 17.3 là khoảng, không phải point. 17.4–17.5 là xung đột và “yes, if…”. 17.6 là review như đang dạy. 17.7 là cách nói khi incident theo nhịp thời gian. 18.7 là playbook mitigate trước. Mỗi Trả lời khi phỏng vấn là một story 60–90 giây. Khác Q&A soft: ở đây là cơ chế, bên kia là kho STAR để nói.
Tóm tắt: Mentorship chỉnh theo người, với một mục tiêu mỗi giờ (delivery, học, hoặc an toàn). Rồi bạn dạy lựa chọn tiếp theo, không viết code của bạn rồi gắn tên họ.
Vì sao quan trọng: “Bạn mentor junior thế nào? Kể về người không theo kịp. Khi nào bạn cầm keyboard?” Họ muốn bạn chỉnh theo người và một STAR, không phải brochure chương trình. Hover thì họ không lớn. Bỏ mặc thì ra bug production và xấu hổ.
- Cách hoạt động: Chẩn đoán cái đang thiếu: domain, Vue, hay giao tiếp. Viết một bar nhỏ, rõ (“PR này: loading, error, empty, test trên composable”). Pair chỗ nối đầu, rồi họ lái. Review bằng câu hỏi, không phải patch.
- Nếu họ bị block hơn N giờ thì vào cùng, đừng để họ chết đuối qua đêm. Cầm keyboard cho incident, bảo mật, environment đau, hoặc extract ba phút rồi họ làm lại. Đừng cầm keyboard trên feature tuần 5 của họ, cũng đừng viết lại PR trên GitHub UI. Cái đó dạy sự phụ thuộc.
- Growth plan: viết ra, 90 ngày, hai hoặc ba outcome (“chịu trách nhiệm lỗi checkout, kể cả Sentry”). Underperformance: sớm, cụ thể, nói riêng, có ghi lại; escalate bằng fact. Trì hoãn PIP không phải tử tế. Phần còn lại của team đã đang gánh. Nếu họ muốn backend, giúp họ chuyển.
| Tín hiệu | Nước cờ |
|---|---|
| Lạc trong repo | Cùng navigate; họ ghi chỗ nào là sự thật |
| JS mạnh, Vue yếu | Kata composable + một PR production |
| Nhanh nhưng ẩu | Bar review về a11y và error, không khen vì nhanh |
| Im trong review | Nhờ họ review PR của bạn trước |
Góc nhìn senior
- Velocity ngắn hạn đánh đổi với một senior thứ hai sau sáu tháng. Bạn cầm hotfix để bảo vệ user; họ cầm cái tiếp theo, bạn on-call, để bảo vệ việc học.
- Mentoring chỉ toàn CSS lặt vặt, “như mình đã bảo” nói công khai, hoặc chỉ người giống bạn, là miss. Mentor một peer senior qua RFC và một lát design-system có tên.
- Viết pattern ra để bạn không thành bus factor. Growth plan giống nhau cho mọi người là chương trình, không phải mentorship.
- Kiểm chứng: họ ship một lát một mình; cùng một theme review giảm dần; họ giải thích được why trong standup; goal 1:1 thay đổi.
Lỗi hay gặp
- Viết lại PR của họ trên GitHub UI. Triệu chứng: họ không ship một mình được. Nguyên nhân: bạn tối ưu tốc độ của mình. Sửa: hỏi, rồi họ lái.
- Hover cả ngày. Triệu chứng: không lớn. Sửa: một mục tiêu mỗi giờ, rồi lùi ra.
- Chờ tới PIP mới nói underperformance. Triệu chứng: team đã gánh. Sửa: nói riêng, có ngày, kèm ví dụ.
- Cùng growth plan cho mọi người. Triệu chứng: chương trình, không phải mentorship. Sửa: chẩn đoán cái đang thiếu.
Nhà tuyển dụng hay hỏi gì
Bạn mentor junior thế nào? Kể về người không theo kịp. Khi nào bạn cầm keyboard? Họ muốn bạn chỉnh theo người và một STAR, không phải brochure.
Trả lời khi phỏng vấn
Trên admin, một bạn mới tuần 2 phụ trách ticket Pinia cho filter đơn hàng. Họ viết lại store trên GitHub UI sau mỗi comment, nhưng empty và 403 vẫn thiếu. Mình chọn học làm mục tiêu của giờ đó, viết một bar nhỏ: loading, error, empty, unauthorized, một test trên composable. Pair chỗ nối đầu, rồi để họ lái. Mình review bằng câu hỏi, không phải patch. Khi Sev-1 khóa login tới, mình cầm keyboard ba phút, tách retry ra, rồi họ làm lại. Tuần 5 họ tự ship lát đó, và theme thiếu empty không còn xuất hiện trong review. Nếu họ vẫn chết đuối, mình vào lúc N giờ, không phải để qua đêm. Underperformance là chuyện nói riêng, có ngày, kèm ví dụ; trì hoãn không phải tử tế, vì phần còn lại của team đã đang gánh. Mình không finish branch của họ chỉ vì mình nhanh hơn. Mentor một peer senior là RFC và một lát design-system có tên, không phải CSS lặt vặt. Nếu họ muốn backend, mình giúp họ chuyển.
Nhớ nhanh
- Một mục tiêu mỗi giờ. Dạy lựa chọn tiếp theo. Đừng ship branch hộ họ.
- Cầm keyboard cho Sev-1 hoặc extract ba phút rồi họ làm lại.
- Underperformance là nói riêng, có ngày, kèm ví dụ. Trì hoãn không phải tử tế.
- Growth plan giống nhau là chương trình, không phải mentorship.
Câu hỏi nối tiếp thường gặp
- Mentor một peer senior thế nào? RFC, một lát design-system có tên, review hỏi why, không phải CSS lặt vặt.
- Nếu họ designer visual giỏi hơn bạn? Bạn học. Họ vẫn không được bỏ a11y.
- Khi nào cầm keyboard là nước sai? Feature tuần 5 của họ, hoặc viết lại PR trên GitHub UI.
- Xử lý misfit muốn làm backend thế nào? Giúp họ chuyển. Đừng kéo PIP chỉ để giữ ghế.
Tóm tắt: Viết ADR (Architecture Decision Record: bối cảnh, các phương án, cái chốt, hệ quả, cách mở lại) khi lựa chọn đắt khi đảo lại hoặc sáu tháng sau nhìn sẽ thấy ngẫu nhiên. Status đi từ proposed, rồi accepted, rồi superseded. Khác Q&A ADR (khi nào) và disagree-tech (cuộc nói): ở đây là template và bản đã chốt.
Vì sao quan trọng: “Ghi lựa chọn thế nào? Pinia hay Vuex, bạn có viết ADR không?” Họ muốn một đến hai trang bối cảnh, phương án, và hệ quả, không phải tiểu thuyết, và họ muốn disagree-and-commit. Không ai đọc tiểu thuyết. Giá trị nằm ở bối cảnh, không phải template.
- Cách hoạt động: Viết một cái cho mô hình render, thư viện state, BFF hay aggregation FE, module federation hay monorepo, cookie hay token, “vì sao không dùng GraphQL”. Link từ README và PR. Cãi trong RFC bằng data hoặc spike; owner có tên chốt trước một mốc ngày; bạn implement đường đã chọn.
- Bỏ bugfix, local refactor, “dùng
const”. Hai người prototype cuối tuần: Slack trước, ADR khi nó tốt nghiệp. Markdown trong repo thắng Confluence vì nó nằm cạnh code. Evidence production mới thì mở lại bằng ADR supersede, không fork thầm. - RFC chốt cuộc tranh. Jira theo việc. ADR là why đã chốt. Nếu org vẫn công bố module federation, cập nhật status. Senior tốt thì có một ADR mà họ hối.
# ADR-012: Filters live in the URL on the ops dashboard
Status: Accepted Date: 2024-03-12
Context: Support shares views; back button was broken (Pinia-only).
Choice: Typed query params are the source of truth; Pinia not used for filters.
Consequences: SSR and share work; secrets must not go in the URL.
Rejected: sessionStorage (not shareable); saved views only (too much backend for v1).
Review: reopen if the query blows 2kB or support needs saved views.
# link từ PR dời table đầu; supersede, đừng sửa thầmĐiều gì xảy ra: Một trang. Bối cảnh, cái chọn, cái bạn reject, cái giá, và khi nào mở lại. Table sau đi theo rule URL mà không cần cãi trên Slack. Khác Q&A disagree: cuộc nói đó ở trong phòng; đây là artefact.
Góc nhìn senior
- Quá nhiều ADR là nhiễu. Kiến thức chỉ nằm trong một cái đầu là thất bại phía kia.
- Disagree-and-commit không phải rọ mõm cho evidence mới. Supersede khi production không đồng ý.
- ADR thiếu owner và ngày review là nhật ký, không phải bản ghi.
- Kiểm chứng: người mới tìm được vì sao Pinia, vì sao
routeRules, vì sao không module federation. Thời gian tranh lại lựa chọn đã chốt phải giảm.
Lỗi hay gặp
- ADR cho mỗi lần đổi tên component. Triệu chứng: không ai đọc. Sửa: chỉ khi đắt hoặc sáu tháng sau nhìn ngẫu nhiên.
- ADR đẹp không ai link. Triệu chứng: người mới tranh lại. Sửa: README và PR.
- Dùng ADR để thắng cãi sau khi đã ship. Triệu chứng: fan fiction. Sửa: viết trước, supersede sau.
- Không bao giờ supersede. Triệu chứng: repo không khớp thực tế. Sửa: ADR mới, không sửa thầm.
Nhà tuyển dụng hay hỏi gì
Ghi lựa chọn thế nào? Pinia hay Vuex, bạn có viết ADR không? Họ muốn một đến hai trang và disagree-and-commit, không phải tiểu thuyết, và không phải tóm tắt Q&A khi nào.
Trả lời khi phỏng vấn
Trên admin, bọn mình cứ đem filter URL với Pinia ra cãi lại trên Slack, rồi một engineer mới implement bản thứ ba trong store. Mình viết ADR-012: support chia sẻ view, nút back gãy khi chỉ dùng Pinia, query param có type là source of truth, sessionStorage và chỉ saved-view bị reject, mở lại nếu query vượt hai kilobyte. Mình link từ PR dời table đầu. Table sau đi theo rule URL, không cần tranh. Bọn mình cãi bằng spike nửa ngày, owner có tên chốt trước Wednesday, mình implement đường đó kể cả phần mình không muốn phụ trách. Nếu production sau này không đồng ý thì mình supersede, không fork thầm. Mình không viết ADR cho một lần đổi tên. Q&A là khi nào viết; đây là trang mình để lại. Cuộc nói trong phòng là câu trả lời khác.
Nhớ nhanh
- ADR khi đảo lại thì đắt, hoặc sáu tháng sau nhìn ngẫu nhiên. Một hoặc hai trang.
- RFC để tranh. Jira theo việc. ADR là why đã chốt.
- Supersede bằng ADR mới. Đừng fork thầm hoặc sửa thầm.
- Senior tốt thì có một ADR mà họ hối.
Câu hỏi nối tiếp thường gặp
- Cho xem một ADR bạn hối. Filter chỉ-URL làm query nổ trên facet lồng nhau. Bọn mình supersede bằng hybrid saved-view.
- Cái này tương tác với RFC và Jira thế nào? RFC là cuộc tranh. Jira là việc. ADR là why đã chốt.
- Khi nào không viết ADR? Bugfix, local refactor, thí nghiệm flag trong một sprint, đổi tên.
- Nếu org bác quyết định không dùng module federation? Cập nhật status. Implement đường đó. Đừng fork thầm.
Tóm tắt: Ước lượng bất định và kích thước thành một khoảng. Story point là độ phức tạp tương đối trong team, không phải giờ. API thiếu là discovery, không phải một con số. Khác 18.2 (cách cắt việc) và 18.8 (list rủi ro tuần 1).
Vì sao quan trọng: “Bạn ước lượng thế nào?” Họ đánh hơi độ chính xác giả và việc đổ lỗi cho “cái ước lượng” về sau, nhất là “5 point bằng 2 ngày” và “hai giờ” trên một thay đổi auth.
- Cách hoạt động: Cắt đến khi một lát dạy được. Khoảng cho phần đã biết. Time-box spike (một ngày) trước khi ước lượng phần còn lại. Liệt kê thứ gì làm nó lớn gấp ba. Date cho stakeholder là forecast kèm độ tin cậy và chỗ cắt scope: cắt export, không cắt test.
- Buffer ở tầng plan (integration, review, QA, “API sẽ đổi”), nhìn thấy được, không phải nhân hai bí mật trên mọi story. Ước lượng frontend chết vì design mơ hồ, thiếu API, a11y, i18n, flag, analytics, empty và error, migration, browser matrix. Nếu những thứ đó không có trong ticket, con số không đáng tin.
- Nếu bạn không nêu được API contract, bạn có task discovery: ghi rõ chi phí. Velocity là chỉ báo trễ, không phải contract, cũng không phải rating hiệu suất. Planning poker cho bất định; đừng lấy trung bình 2 và 13 mà không nói. T-shirt size cho roadmap, point cho sprint.
| Đầu vào | Đầu ra thành thật | Nói dối |
|---|---|---|
| Filter đã biết, API có tên | Khoảng: 2–3 ngày | “Hai giờ” |
| Export, chưa có job | Spike 1 ngày, rồi khoảng | Cùng point với filter |
| Realtime, contract chưa đặt tên | Ticket discovery | “5 point = 2 ngày” |
| Poker 2 và 13 | Nói chuyện, rồi cắt hoặc spike | Trung bình thành 8 |
Góc nhìn senior
- Sandbagging khiến PM học cách bỏ qua bạn. Không chịu forecast gì cả cũng là thất bại.
- Đừng biến velocity của team thành spreadsheet giờ-người trong buổi phỏng vấn.
- Rewrite thì strangle từng lát, không nuốt một cục sáu tháng. Ước lượng chỉ happy path sẽ miss các state ở 13.3 và khoảng trống design-system.
- Kiểm chứng: tỷ lệ forecast trúng khoảng so với actual, unknown nêu ngay từ đầu, phần trăm story bị cắt giữa sprint (phải giảm).
Lỗi hay gặp
- “Năm point bằng hai ngày”. Triệu chứng: miss thuộc về bạn. Nguyên nhân: point không phải giờ. Sửa: độ phức tạp tương đối, date là forecast.
- “Hai giờ” cho auth. Triệu chứng: bạn bỏ empty, 403, CSRF. Sửa: nêu rõ unknown, không thì đó là discovery.
- Trung bình 2 và 13. Triệu chứng: không ai học được gì. Sửa: nói chuyện, rồi cắt hoặc spike.
- Nhân hai thầm trên mọi story. Triệu chứng: PM không plan được. Sửa: buffer ở tầng plan, nhìn thấy được.
Nhà tuyển dụng hay hỏi gì
Bạn ước lượng thế nào? Họ soi độ chính xác giả và đổ lỗi “cái ước lượng” về sau: point như giờ, và “hai giờ” cho auth.
Trả lời khi phỏng vấn
Ở sản phẩm admin, PM muốn filter, export CSV, và cập nhật realtime trong một sprint. Mình đưa một khoảng kèm các giả định. Filter đã rõ: hai đến ba ngày, kể cả empty và 403. Export cần job backend mà bọn mình chưa có. Đó là spike một ngày, rồi mới ra khoảng, không cùng point với filter. Realtime chưa có API contract, nên là ticket discovery, không phải năm point bằng hai ngày. Sprint đó bọn mình ship filter, spike realtime, và để export sang sau. Không ai trượt ước lượng, vì ước lượng là một khoảng kèm lever: cắt export, không cắt test. Mình không nói hai giờ cho auth. Point so sánh độ phức tạp trong team. Date cho exec đi kèm độ tin cậy và một lever. Nếu họ đòi date hôm nay, mình vẫn đưa khoảng và list giả định. Velocity không phải spreadsheet giờ-người. List rủi ro tuần 1 nằm ở 18.8. Cách mình cắt việc nằm ở 18.2.
Nhớ nhanh
- Khoảng và giả định, không phải point coi như giờ.
- API contract còn thiếu là discovery, không phải một con số.
- Buffer ở tầng plan, nhìn thấy được. Đừng nhân đôi thầm mọi story.
- Không ai trượt ước lượng nếu ước lượng là khoảng kèm lever.
Câu hỏi nối tiếp thường gặp
- Ước lượng rewrite thế nào? Strangle từng lát. Đưa khoảng cho lát đầu. Discovery cho seam chưa rõ.
- Nếu họ đòi date hôm nay? Khoảng, kèm list giả định, kèm một lever scope.
- Vì sao 1 point = 2 giờ là bẫy? Point là tương đối. Giờ giấu empty, a11y, API đổi.
- Poker ra 2 và 13 thì làm gì? Nói chuyện. Rồi cắt hoặc spike. Đừng lấy trung bình.
Tóm tắt: Xung đột kỹ thuật thì cần data, một spike, và owner có tên. Xung đột tôn trọng thì nói chuyện riêng trước. Escalate bằng phương án, không bằng than phiền. Khác Q&A không đồng ý kỹ thuật (Pinia khác URL trong phòng): ở đây là process, và câu chuyện là module federation khác package monorepo.
Vì sao quan trọng: “Kể một lần bất đồng”. Họ muốn process người lớn: data, owner, phương án khi escalate. Không phải “mình dễ làm việc”. Sản phẩm vẫn phải ship. Consensus không phải lúc nào cũng có. Ấm ức giấu đi thì đắt.
- Cách hoạt động: Viết cả hai phương án vào một trang: chi phí, ranh giới team, LCP. Time-box một spike. Người chịu trách nhiệm outcome thì chốt. Bạn implement đường đã chọn và ghi điều kiện xem lại. Lựa chọn đảo được thì để đi (đặt tên CSS). Giữ vững auth, a11y, data của user.
- Tính cách: 1:1, ví dụ cụ thể, impact lên user hoặc on-call, một SLA review. Nếu vẫn tiếp, manager nhận các ví dụ đó và một working agreement. Tranh kỹ thuật công khai thì tốt và phải ghi lại. Tranh cá nhân công khai thì không.
- Escalation nghe như A, B, C kèm một recommendation, không phải “bảo họ mình đúng”. Nếu owner sai trên production: ADR supersede, không I-told-you-so. Cùng một trận tái diễn nghĩa là lựa chọn chưa từng được ghi (17.2).
| Loại | Nước cờ | Không |
|---|---|---|
| Kỹ thuật, đảo được | Để đi (đặt tên CSS) | Một tuần trên Slack |
| Kỹ thuật, đắt | One-pager, spike, owner có tên | Thắng trong standup |
| Tôn trọng / review | 1:1 riêng kèm ví dụ | Chỉ trích trong standup |
| Escalate | A / B / C + recommendation | “Họ khó tính” |
Góc nhìn senior
- “Bảo họ mình đúng” không phải leadership. Phụ trách BFF xuyên team cũng cùng process: phương án, owner, ADR.
- “Disagree and commit” dùng để bịt evidence là rọ mõm. Evidence production mới thì mở lại (17.2).
- “Data-driven” khi bạn chỉ gom data ủng hộ mình là đang diễn. Phải gồm cả phương án bạn không thích.
- Kiểm chứng: thời gian chốt, ADR có tồn tại không, review còn chạy không, cùng trận có tái diễn không.
Lỗi hay gặp
- Một tuần tabs khác spaces trên Slack. Triệu chứng: lựa chọn đảo được bị biến thành xung đột. Sửa: để đi.
- Escalate “họ khó tính” mà không có phương án. Triệu chứng: manager không hành động được. Sửa: A, B, C kèm recommendation.
- Chỉ trích ai đó trong standup. Triệu chứng: xung đột tôn trọng ra công khai. Sửa: 1:1 trước.
- Né chỉ qua manager mà team ngửi ra. Triệu chứng: trận quay lại. Sửa: ghi cái đã chốt.
Nhà tuyển dụng hay hỏi gì
Kể một lần bất đồng. Họ muốn process người lớn: data, owner, phương án khi escalate. Không phải “mình dễ làm việc”, và không phải chuyện Pinia khác URL từ Q&A.
Trả lời khi phỏng vấn
Một teammate muốn Module Federation cho checkout admin để hai lịch deploy ship độc lập. Mình muốn package monorepo vì bọn mình chỉ có một team và một digest GitOps. Đó là chuyện khác với Pinia khác filter URL. Mình viết cả hai phương án vào một trang: chi phí, ranh giới team, LCP của remote entry. Spike import package trong nửa ngày, và owner của checkout chốt package trước Wednesday. Mình implement đường đó và nêu điều kiện xem lại: lịch deploy thứ hai, hoặc team thứ hai. Review mang tính cá nhân thì mình đưa ra 1:1 kèm ví dụ. Mình không escalate “họ khó tính”. Escalation, nếu cần, sẽ nghe như A, B, C kèm một recommendation, không phải “bảo họ mình đúng”. Nếu production sau chứng minh owner sai, mình supersede ADR, không I-told-you-so. Đặt tên CSS thì mình để đi. Auth và a11y thì không.
Nhớ nhanh
- Phương án trên một trang, một spike, owner có tên, điều kiện xem lại.
- Lựa chọn đảo được thì để đi. Giữ auth, a11y, data của user.
- Escalate bằng A, B, C kèm recommendation. Không phải “họ khó tính”.
- Cùng trận tái diễn nghĩa là cái chốt chưa từng được ghi.
Câu hỏi nối tiếp thường gặp
- Nếu owner sai trên production? Supersede ADR. Không I-told-you-so. Implement đường mới.
- FE khác backend, ai phụ trách BFF? Cùng process: phương án, owner, ADR. Không phải trận tính cách.
- Khi nào để lựa chọn đảo được đi? Đặt tên CSS, thứ tự import. Không phải auth, a11y, hay data của user.
- Escalate bằng phương án thế nào? A, B, C, một recommendation, và impact lên user. Không phải “bảo họ mình đúng”.
Tóm tắt: Đừng nói không với mục tiêu. Nói không với plan vi phạm ràng buộc, rồi đưa lever scope, date, flag, hoặc thanh chất lượng kèm impact lên user. “Yes, nếu…” Khác 18.2 (PM viết giải pháp) và khác 17.4 (xung đột peer).
Vì sao quan trọng: “PM muốn Friday. QA mỏng. Bạn biết không an toàn. Bạn làm gì?” Họ muốn không-với-plan kèm lever, không phải hero weekend hay deck 12 slide vì một dòng copy.
- Cách hoạt động: Nêu rủi ro bằng ngôn ngữ user: charge hai lần, a11y, SDK 3 MB trên
/pricing. Đưa Stripe-only sau flag cho staff, Apple Pay sprint sau với owner có tên, hoặc landing campaign không đổi checkout. Hỏi mục tiêu Friday nào là thật: experiment conversion khác tender mới. - Push back sớm, cùng kênh, kèm giả định viết ra. “Mình làm với kill switch và owner rollback”. PM được chấm theo outcome. Chỉ block thì họ đi đường khác. Không bao giờ block thì bạn chịu trách nhiệm incident.
- Tiêu vốn chính trị cho an toàn, ethics, legal, không cho thư viện yêu thích. “Không phải bây giờ” cần điều kiện xem lại. “Không bao giờ” thì hiếm (bất hợp pháp, dối data user). Design muốn video background trên
/lúc campaign: trả lời bằng số Core Web Vitals, không phải vì gu.
| Ask | Yes, nếu… | Không bao giờ (hiếm) |
|---|---|---|
| Apple Pay Friday này | Flag + sandbox + owner rollback | Không sandbox, charge thật |
Video trên / cho campaign | Load idle, có size, ngân sách LCP | Autoplay không size trên hero LCP |
| Đổi copy, không deck 12 slide | Cứ ship copy | - |
| Hai PM, hai Friday | Một thứ tự việc viết ra | Yes thầm với cả hai |
Góc nhìn senior
- “Đây là đổi product contract, không phải chỉnh UI hai giờ”. Nói thành tiếng, ngay trên cùng thread.
- Impact với user, không phải “engineering excellence”. Phình estimate để ép một câu không. Lần sau họ bỏ qua bạn.
- PM là người skip-level cưng thì vẫn viết rủi ro và copy manager. Đừng tự ý làm.
- Kiểm chứng: incident từ việc vội phải giảm. Phần trăm “phải xong Friday” mà đúng là vậy. Họ vẫn kéo bạn vào sớm: đó là tin.
Lỗi hay gặp
- Hero-weekend thầm. Triệu chứng: bạn gánh incident, không ai thấy rủi ro. Sửa: viết ngay trên cùng thread.
- Chua “sure, whatever”. Triệu chứng: lần sau họ đi đường khác. Sửa: lever, không phải tâm trạng.
- Phình estimate để ép một câu không. Triệu chứng: PM bỏ qua số. Sửa: khoảng thành thật kèm một lever (17.3).
- Deck 12 slide vì một dòng copy. Triệu chứng: bạn tốn vốn mà chẳng được gì. Sửa: cứ ship copy.
Nhà tuyển dụng hay hỏi gì
PM muốn Friday. QA mỏng. Bạn biết không an toàn. Bạn làm gì? Họ muốn nói không với plan, kèm lever, không phải hero weekend.
Trả lời khi phỏng vấn
Trên sản phẩm admin, PM muốn Apple Pay trên landing campaign đúng Friday đó. QA mỏng và bọn mình không có sandbox. Mình không từ chối campaign. Mình nói bọn mình ship được landing và Stripe-only sau flag cho staff trước Friday nếu cắt Apple Pay, hoặc giữ Apple Pay và dời date, kèm kill switch và owner rollback có tên. Mình viết rủi ro charge hai lần và SDK ba megabyte ngay trên cùng thread với request. Mục tiêu Friday thật là experiment conversion, không phải tender mới, nên bọn mình ship landing. Mình không phình estimate để ép một câu không, và không hero weekend thầm. Video background trên / mình trả lời bằng số Core Web Vitals. Dù PM đó là người skip-level cưng, mình vẫn viết rủi ro và copy manager. Đổi copy không được deck mười hai slide. “Không bao giờ” dành cho việc bất hợp pháp hoặc dối data user. Cách mình cắt việc đã plan là 18.2. Khoảng là 17.3.
Nhớ nhanh
- Không với plan không an toàn. Yes với mục tiêu, kèm lever.
- Viết rủi ro trong cùng thread. Đừng hero weekend thầm.
- Tiêu vốn cho an toàn và legal, không cho thư viện yêu thích.
- “Không phải bây giờ” cần lần xem lại. “Không bao giờ” thì hiếm.
Câu hỏi nối tiếp thường gặp
- Nếu PM là người skip-level cưng? Vẫn viết rủi ro. Copy manager. Đừng tự ý làm.
- Design muốn video background trên
/lúc campaign? Trả lời bằng số LCP và INP, kèm lever load idle. - Push back mà không thành blocker của công ty thế nào? Lever trên cùng kênh. Sớm. Về mục tiêu, không về khẩu vị.
- Khi nào không bao giờ là câu thành thật? Việc bất hợp pháp, dối data user, charge thật không sandbox.
Tóm tắt: Review giúp scale taste. Block trên correctness phía user, bảo mật, a11y, mất data, và budget. Mọi thứ khác prefix nit: và approve khi rủi ro đã xử lý, dù bạn sẽ tách composable khác.
Vì sao quan trọng: “Review tốt của senior trông thế nào?” Họ muốn phân biệt block với nit, dạy kèm lý do, và bạn không phải bottleneck. Không phải comment prettier. PR 40 file không review thành thật được. Đó là lỗi process, không phải lỗi reviewer.
- Cách hoạt động: Hỏi “API 409 thì sao?” trước khi dán patch. Review test của họ nghiêm như SFC. Kéo reviewer a11y hoặc design-system cho primitive. PR của bạn nhỏ, có mô tả, và bạn nêu chỗ cần focus. Cùng một comment hai lần thì đưa vào lint hoặc fixture.
- Path rủi ro cao (thanh toán, flag) có thể đòi hai approve. Docs thì không. Pair trên PR khó thay vì bốn mươi comment. Author senior hơn không đổi bar. Bạn không review mọi PR. Làm vậy là bạn thành hàng đợi.
- Nếu bạn không revert prod vì nó, khả năng không blocking. Status không phải correctness. CI không bắt được đổi product contract. Review sau merge vì tin CI mù là smell.
| Block | Đừng block |
|---|---|
| Authz, PII, XSS, focus gãy, catch thầm | Đặt tên, thứ tự import: automate |
| Thiếu error hoặc empty trên user flow | Thích const trong script setup |
Lib nặng mới trên / | “Mình sẽ tách composable khác” |
| Đổi product contract không có test | Chỉ lockfile generate |
Góc nhìn senior
- Review design-system là visual, a11y, và semver, không phải “trông ổn trên browser mình”.
- Rubber stamp, comment viết lại cả PR, block vì prettier, chỉ senior được merge: đều miss.
- Pile-on công khai và “LGTM” trên lockfile generate kèm đổi webpack config là cách bạn ship một bất ngờ.
- Kiểm chứng: thời gian review đầu, defect lọt, junior merge được không cần bạn, theme comment lặp (sửa bằng lint hoặc ADR).
Lỗi hay gặp
- Block vì prettier. Triệu chứng: bạn là hàng đợi. Sửa:
nit:hoặc linter.- Dán patch trước khi hỏi 409. Triệu chứng: bạn viết lại PR của họ. Sửa: hỏi trước.
- Review mọi PR. Triệu chứng: junior không merge được. Sửa: CODEOWNERS chỉ trên path rủi ro.
- Review sau merge vì CI xanh. Triệu chứng: đổi product contract được ship. Sửa: review trước merge.
Nhà tuyển dụng hay hỏi gì
Review tốt của senior trông thế nào? Họ muốn phân biệt block với nit, dạy kèm lý do, và bạn không phải bottleneck. Không phải comment prettier.
Trả lời khi phỏng vấn
Trên sản phẩm admin, một engineer tuần 4 mở PR 40 file: thêm export CSV và cũng đổi tên một nửa token design-system. Mình không cố review thành thật. Đó là bug process. Bọn mình tách: export sau flag kèm test empty và 403, token ở PR thứ hai với reviewer a11y. Trên PR export mình block vì catch thầm quanh 409 và thiếu empty unauthorized. Style là nit: hoặc linter. Mình hỏi 409 thì sao trước khi dán gì, và approve khi rủi ro hết dù mình sẽ tách composable khác. Mình không review mọi PR. CODEOWNERS trên thanh toán và flag, không trên docs. Author senior hơn mình cũng không đổi bar. Nếu mình không revert prod vì nó, thì không blocking. Mentorship 17.1 là giờ pair; topic này là comment review.
Nhớ nhanh
- Block trên authz, XSS, thiếu error state, lib nặng mới trên
/. - Style là
nit:hoặc linter. Approve khi rủi ro hết. - PR 40 file là bug process. Tách hoặc pair.
- Nếu bạn không revert prod vì nó, khả năng không blocking.
Câu hỏi nối tiếp thường gặp
- Review đổi design-system thế nào? Visual, a11y, và semver. Kéo reviewer riêng cho primitive.
- Nếu author senior hơn bạn? Bar không đổi. Authz và XSS vẫn block.
- Khi nào đòi hai approve? Thanh toán và flag. Không phải docs.
- Vì sao review sau merge là smell? CI không bắt đổi product contract. Review trước merge.
Tóm tắt: Nói theo mốc giờ: đã biết gì, ai đang bị chặn, đang làm gì, lần cập nhật tiếp lúc nào. Kể cả lần đó là “vẫn đang điều tra”. Khác 18.7 (lever mitigate trước) và 19.5 (có page hay không): ở đây là lời.
Vì sao quan trọng: “Checkout down. Bạn nói gì, với ai, khi nào?” Họ muốn mốc giờ: đã biết, impact, đang làm gì, lần cập nhật tiếp. Không phải biến mất bốn mươi phút trong DevTools. Im lặng làm người ta panic. “Là DNS” quá sớm thì phí thời gian.
- Cách hoạt động: Mitigate trước (18.7): revert digest GitOps hoặc gạt flag. Rồi kênh chỉ nhận fact, không phải “có thể Safari”. Sau mitigate, confirm bằng RUM, Sentry, một canary buy, rồi RCA. PM và support nhận impact, workaround, và thời điểm nói lần tiếp, không phải ETA root cause vũ trụ.
- Incident frontend thường chỉ một phần: một locale, browser, flag, hoặc chunk 404. User và status page chỉ khi user thấy và process nói vậy. Frontend thường đi qua PM. Không blame trên kênh. “Works for me” thì hỏi tiếp release, flag, locale, browser.
- Rollback trừ khi rollback tệ hơn (data migration). Ưu tiên mốc giờ hơn im kênh ba mươi phút. Đừng root-cause trong status (“PR của intern”). Đừng tuyên bố xong ở phút Sentry xanh đầu (traffic tụt). Không owner mà năm người sửa
mainlà hỗn loạn. Khoảng theo dõi sau “mình nghĩ đã sửa”.
14:02 UTC checkout submit failing ~12% since digest abc123
error QUOTE_EXPIRED / some users chunk 404
impact: cannot pay. workaround: none
next update: 14:15. owner: [your name]
eng thread: graphs, release, flag, locale, không đoán Safari
PM/support: impact + workaround + next-comms time (not RCA ETA)
users / status page: qua PM chỉ khi process nói vậy
after mitigate: watch RUM before "we are clear"Điều gì xảy ra: Kênh đã có đã biết, impact, workaround, lần cập nhật tiếp, và một owner trước khi ai mở DevTools. Đoán Safari ở lại engineering. Status page do PM quyết. Sau rollback bạn nhìn RUM. Phút Sentry xanh đầu không phải đã xong.
| Người nhận | Nhận | Không nhận |
|---|---|---|
| Kênh incident | Đã biết, impact, lần tiếp, owner | Giả thuyết Safari |
| Engineering | Graph, SHA, flag, locale | Blame |
| PM / support | Impact, workaround, lần nói tiếp | ETA RCA vũ trụ |
| User / status | Chỉ khi process bảo vậy, qua PM | “PR của intern” |
Góc nhìn senior
- Chunk 404 là HTML cache hỏng. Chỉ 10% thì là flag hoặc canary. Tắt hết flag không phải mitigate khoanh vùng (18.7 / 19.6).
- Có gọi ai dậy hay không là 19.5, không phải mọi JS error. Topic này giả định bạn đã đang nói.
- Postmortem là timeline và các fix hệ thống, không phải ai viết PR. Blameless, kèm khoảng theo dõi.
- Kiểm chứng: thời gian mitigate, thời gian có impact chính xác, độ chính xác phía customer, tỷ lệ incident lặp lại.
Lỗi hay gặp
- Bốn mươi phút trong DevTools mà không cập nhật. Triệu chứng: panic. Sửa: nói theo mốc giờ, kể cả lần cập nhật là “vẫn đang điều tra”.
- Root-cause trong status (“PR của intern”). Triệu chứng: blame. Sửa: chỉ fact và impact.
- Khoe đã xong ngay phút Sentry xanh đầu. Triệu chứng: traffic vừa tụt. Sửa: nhìn RUM.
- Năm người sửa
mainmà không có owner. Triệu chứng: hỗn loạn. Sửa: một tên trên kênh.
Nhà tuyển dụng hay hỏi gì
Checkout down. Bạn nói gì, với ai, lúc nào? Họ muốn mốc cập nhật, không phải biến mất trong DevTools, và không phải list lever 18.7.
Trả lời khi phỏng vấn
Ở sản phẩm admin, checkout submit bắt đầu fail khoảng mười hai phần trăm lúc 14:02 UTC trên digest abc123, lỗi QUOTE_EXPIRED, một số user gặp chunk 404. Mình mitigate trước: gạt flag gắn với vách, purge HTML cho 404. Rồi mới nói theo mốc giờ. Kênh nhận: đã biết, impact (không thanh toán được), không có workaround, lần cập nhật tiếp 14:15, và tên mình. Engineering nhận graph. PM nhận impact và thời điểm nói lần tiếp, không phải thời điểm root-cause vũ trụ. User đi qua PM. Mình không nói intern hay Safari trên kênh đó. Sau rollback mình nhìn RUM trước khi bảo đã xong: phút Sentry xanh đầu là traffic tụt. Postmortem là timeline và một CI gate cho lần gạt flag, không phải ai viết PR. Lever là 18.7. Có page không là 19.5. Câu này là lời nói.
Nhớ nhanh
- Mốc giờ: đã biết, impact, workaround, lần cập nhật tiếp, owner. Chỉ fact.
- Trang trạng thái qua PM. Không blame, không đoán Safari, không tên intern.
- Nhìn RUM sau khi mitigate. Phút Sentry xanh đầu chưa phải đã xong.
- Lever là 18.7. Có page không là 19.5. Topic này là lời nói.
Câu hỏi nối tiếp thường gặp
- Kể lại postmortem bạn đã viết. Timeline, blast radius, chỗ miss trong CI, fix hệ thống. Không phải ai viết PR.
- Page thế nào? 19.5: triệu chứng trên critical path, rate so với baseline, một runbook. Không phải mọi TypeError.
- Cái gì vào status cho user, cái gì vào thread eng? Impact và workaround khác graph và SHA.
- Khoảng theo dõi sau mitigate dài bao lâu? Đến khi RUM và Sentry về baseline ngày thường, không phải một phút xanh.