git bisect start
git bisect bad HEAD
git bisect good v2.3.0
git bisect run npx vitest run tests/checkout-total.test.ts
git bisect reset
Engineering Practices & Leadership
draftedGit workflow, code review, tech debt, estimation, design doc/RFC/ADR, mentoring, làm việc với PO/QA/Design trong team phân tán, on-call và deprecation.
0/45 rated · mastery 0%
Bài học
12 bài · ~180 phút đọc. Học theo thứ tự, rồi làm câu hỏi.- 01~17 phút· 3 câuverify
Lịch sử Git: merge, rebase, squash và commit message
Commit, ref và DAG; merge vs rebase và golden rule; ba cách merge PR (squash, rebase, merge commit) ảnh hưởng bisect/revert ra sao; interactive rebase với fixup/autosquash; Conventional Commits và cách đọc một lịch sử bẩn.
- 02~16 phút· 4 câuverify
Cứu hộ Git: reflog, reset, force push và bisect
reset --soft/--mixed/--hard làm gì với con trỏ và working tree, reflog cứu commit 'đã mất' ra sao, --force vs --force-with-lease (và vì sao cần --force-if-includes), khôi phục main bị force push, và git bisect run với exit 125, --first-parent trên 400 commit.
- 03~14 phút· 3 câuverify
Branching strategy: trunk-based, GitFlow và hotfix
Continuous integration thật sự là gì; trunk-based vs GitHub flow vs GitFlow và khi nào mỗi cái hợp; release branch và hotfix từ tag với cherry-pick -x về main; lộ trình chuyển team sang trunk-based; đo bằng bốn DORA metrics với script chạy trên git log.
- 04~14 phút· 4 câuverify
Feature flags: tách deploy khỏi release
Deploy vs release; bốn loại toggle (release, experiment, ops, permission) và tuổi thọ của chúng; cách đánh giá flag với targeting và % rollout sticky bằng hash; cache, last-known-good và độ trễ của kill switch; flag debt, linter hết hạn và các failure mode hay gặp trong production.
- 05~13 phút· 4 câuverify
Pull request và code review
Code review để làm gì; PR nhỏ và description tốt (what/why/how tested/risk); thứ tự review từ design tới style; review một diff thật với comment blocking vs nit (chạy đoạn code trên SQLite để chứng minh); đo và sửa tình trạng review mất ba ngày.
- 06~17 phút· 4 câuverify
Feedback và bất đồng kỹ thuật
Viết review feedback thẳng mà không làm nản (kể cả khác văn hoá) với Conventional Comments; gỡ một thread PR kéo dài 15 comment; review PR của người senior hơn khi thấy lỗi thiết kế; và disagree-and-commit với một quyết định kiến trúc đã công bố, kể cả khi nó sai sáu tháng sau.
- 07~16 phút· 5 câuverify
Tech debt và refactor legacy an toàn
Tech debt là gì (gốc, lãi), quadrant của Fowler, khi nào nhận nợ là đúng; hữu hình hoá và ưu tiên theo lãi suất bằng hotspot analysis trên git log; cơ chế trả nợ dưới áp lực feature; refactor module legacy không test bằng characterization test, strangler fig, branch by abstraction và dual-run.
- 08~14 phút· 3 câuverify
Breakdown và estimation
Chia một feature lớn theo vertical slice và spike có timebox; vì sao estimate luôn lệch (cone of uncertainty, planning fallacy, phân phối lệch phải); three-point, PERT và Monte Carlo chạy thật; nói estimate với PO bằng range + độ tự tin; và làm gì khi đi được nửa đường thì phát hiện việc sẽ dài gấp đôi.
- 09~14 phút· 4 câuverify
Design doc, RFC và ADR
Khi nào một quyết định cần viết ra; design doc/RFC (đề xuất trước khi build) khác ADR (bản ghi sau khi chốt) thế nào; template từng loại; quy trình review async có timebox và decision owner; vòng đời ADR (proposed → accepted → superseded) với tool chạy thật; đưa ADR vào team đang quyết trong chat; và ảnh hưởng hướng kỹ thuật khi không có quyền chính thức.
- 10~15 phút· 7 câuverify
Làm việc với PO, QA, Design trong team phân tán
Ai quyết cái gì giữa PO, dev, QA, designer; trình bày bug và ràng buộc kỹ thuật bằng impact có dữ liệu; three amigos và shift-left với QA; thương lượng với designer quanh mục tiêu UX và accessibility; async-first, decision log, handoff và overlap hours giữa các timezone (tính bằng script có DST); và khung STAR cho câu hỏi ownership end-to-end và làm việc phân tán.
- 11~14 phút· 3 câuverify
On-call, postmortem và deprecation
Vận hành on-call từ góc nhìn engineer: alert actionable (phân tích lịch sử page), runbook, severity, vai trò trong incident, mitigate trước root cause sau; 15 phút đầu của một page lúc 3 giờ sáng; blameless postmortem có action item được làm thật; và deprecate một API nội bộ với đo lường consumer, header Deprecation/Sunset, brownout chạy thật.
- 12~14 phút· 4 câuverify
Mentoring, process và Definition of Done
Mentor một mid-level lên senior bằng ownership tăng dần, review tư duy và sponsorship; mentoring vs coaching vs sponsorship; triết lý 'process vừa đủ' (chi phí, tự động hoá trước quy định, bỏ ceremony); Definition of Done khác acceptance criteria ra sao, DoD cho SaaS multi-tenant và một checker chạy trong CI; ảnh hưởng không cần chức danh.
Tóm tắt & cheat sheet của track
TL;DR
- Ở level senior, interviewer đánh giá cách bạn làm việc với người và hệ thống, không chỉ code: bạn chia task thế nào, review ra sao, xử lý bất đồng, quản lý tech debt, viết design doc.
- Git: hiểu trunk-based vs GitFlow, rebase vs merge, và công cụ cứu hộ (
reflog,bisect,revert) — đủ để nói "tại sao team chọn cách này". - Code review là cơ chế chia sẻ kiến thức và giảm rủi ro, không phải gatekeeping; PR nhỏ, review nhanh, comment có mức độ (blocking vs nit).
- Estimation là giao tiếp về bất định: chia nhỏ, nêu giả định và rủi ro, cập nhật sớm khi sai — không phải hứa một con số.
- Quyết định kỹ thuật quan trọng → design doc/RFC trước khi làm, ADR ghi lại sau khi chốt; "disagree and commit" khi đã quyết.
Khái niệm cốt lõi
| Khái niệm | Một câu | Ví dụ ngắn |
|---|---|---|
| Trunk-based development | Mọi người merge vào main thường xuyên (≤1–2 ngày), branch ngắn, feature flag che phần chưa xong | Checkout mới sau flag checkout_v2 |
| GitFlow | Nhánh develop, release/*, hotfix/*, feature/* dài hơn; hợp với release theo đợt | App mobile phát hành 2 tuần một lần |
| Rebase vs merge | Rebase viết lại lịch sử cho thẳng; merge giữ lịch sử thật với merge commit | git rebase main trên branch cá nhân trước khi mở PR |
git bisect | Binary search qua commit để tìm commit gây lỗi | 1.000 commit → ~10 bước |
| Feature flag | Tách deploy khỏi release | Bật cho 5% tenant trước |
| Tech debt | Chi phí tương lai do lựa chọn hiện tại; có loại cố ý và vô ý | Hard-code tỷ giá để kịp demo |
| Design doc / RFC | Tài liệu đề xuất trước khi build: vấn đề, phương án, trade-off | RFC "Chuyển search sang Elasticsearch" |
| ADR | Bản ghi ngắn một quyết định kiến trúc: context, decision, consequences | ADR-012: Dùng outbox cho event đơn hàng |
| Definition of Done | Tiêu chí chung để coi một task là xong | Code + test + review + docs + deployed + monitored |
| Blameless postmortem | Phân tích sự cố tập trung vào hệ thống, không đổ lỗi cá nhân | "Tại sao hệ thống cho phép deploy migration chưa test?" |
Cơ chế hoạt động
Vòng đời một thay đổi (trunk-based)
Code review flow
Quyết định kỹ thuật
Trade-offs
| Chủ đề | Lựa chọn A | Lựa chọn B | Khi nào chọn |
|---|---|---|---|
| Branching | Trunk-based: integrate liên tục, ít merge conflict, cần CI + flag tốt | GitFlow: kiểm soát release, nhiều nhánh sống lâu, merge hell | Web/SaaS deploy liên tục → trunk; release theo version/cần hỗ trợ nhiều version → GitFlow-ish |
| Integrate | Rebase: lịch sử thẳng, dễ bisect | Merge: giữ lịch sử thật, an toàn với branch chung | Rebase branch cá nhân; không rebase branch người khác đang dùng |
| Merge PR | Squash: 1 commit/PR, main sạch | Merge commit: giữ từng commit | Squash cho PR nhỏ; giữ commit khi mỗi commit có ý nghĩa riêng |
| Estimation | Story points: tương đối, team-level | Time-based: dễ hiểu với business | Nói bằng range + độ tự tin, không một con số |
| Tech debt | Trả dần (boy-scout, % capacity mỗi sprint) | Dự án trả nợ riêng | Nợ lan tỏa → trả dần; nợ tập trung, rủi ro cao → dự án riêng có mục tiêu đo được |
| Docs | Design doc dài, review kỹ | ADR ngắn | Quyết định khó đảo ngược → doc; mọi quyết định đáng nhớ → ADR |
Pitfalls
- PR 1.500 dòng, description trống, "please review ASAP".
- Review chỉ soi style (việc của linter) mà bỏ qua design/correctness; hoặc ngược lại dùng review để áp đặt sở thích cá nhân.
git push --forcelên branch chung; rebase branch đã share.- Estimate một con số rồi im lặng tới deadline mới báo trễ.
- Gọi mọi thứ là "tech debt" để xin viết lại — không nêu được tác động kinh doanh.
- Bất đồng kéo dài trong comment PR thay vì gọi 15 phút.
- Trong team phân tán: quyết định trong call không ghi lại; người ở timezone khác bị loại khỏi quyết định.
- Deprecate API mà không có timeline, không đo ai còn dùng.
Cheat sheet
- Git cứu hộ:
git reflog(tìm lại commit mất) ·git revert <sha>(undo trên branch chung) ·git bisect start/bad/good/run·git push --force-with-leasethay--force. - PR tốt: < ~400 dòng thay đổi logic, một mục đích, description = what/why/how tested/risk, screenshots cho UI.
- Comment tốt: nêu mức độ (
blocking:,nit:,question:), giải thích why, đề xuất cụ thể. - Estimate: breakdown → spike cho phần chưa rõ → range (best/likely/worst) → nêu giả định → cập nhật sớm.
- Tech debt: ghi vào backlog với tác động (thời gian mất/incident/rủi ro), ưu tiên theo "lãi suất".
- Design doc: context, goals/non-goals, options + trade-offs, decision, rollout, rollback, open questions.
- Bất đồng: data > opinion, hiểu lý do bên kia, đề xuất thử nghiệm nhỏ, escalate có văn bản, disagree & commit.
- Distributed team: async-first, viết quyết định, overlap hours, demo/record, rõ owner.
References
- Google Engineering Practices — Code Review ↗
- Trunk Based Development ↗
- Martin Fowler — Patterns for Managing Source Code Branches ↗
- Git documentation — git-bisect ↗
- Pro Git — Rewriting History / Rebasing ↗
- Architecture Decision Records (adr.github.io) ↗
- Martin Fowler — Technical Debt Quadrant ↗
- Google SRE Book — Postmortem Culture ↗
- Conventional Commits ↗
- Martin Fowler — Feature Toggles (Pete Hodgson) ↗
Interview Questions
Showing 45 / 45
Feature: Address Management
1. Spike: provider validate địa chỉ (timebox 1 ngày)
2. Migration: bảng addresses (expand) + index (tenant_id, user_id)
3. API: CRUD + default address, tenant-scoped, test cross-tenant
4. FE: list + form (flag address_v2)
5. Checkout đọc default address
6. Rollout theo tenant, monitor, dọn flag
* a91f2c3 Merge branch 'main' into feature/checkout
|\
| * 77be0d1 fix
| * 4c1e9aa fix again
* | 2d0b8f1 Merge branch 'main' into feature/checkout
|\|
| * 9e3a712 wip
| * 18fd4c0 asdf
* | c0ffee1 Merge pull request #412 from feature/checkout-v2-final-FINAL
* | 5b6d2e9 revert "revert 'add voucher logic'"
git checkout feature/shift-management
git fetch origin
git reset --hard origin/feature/shift-management
# "the remote had the latest version, I just wanted to sync"
+ // TODO: temporary, remove after demo
+ const DISCOUNT_RATE = 0.15;
+
+ export async function applyDiscount(orderId) {
+ const order = await db.query(`SELECT * FROM orders WHERE id = ${orderId}`);
+ order.total = order.total - order.total * DISCOUNT_RATE;
+ await db.query(`UPDATE orders SET total = ${order.total} WHERE id = ${orderId}`);
+ return order
+ }