Bạn đã code được 1-2 năm. Biết React, viết được API, hiểu cơ bản về Docker.
Nhưng khi ngồi vào bàn phỏng vấn — hoặc khi team lead hỏi “Em thiết kế module này như thế nào?” — bạn không biết bắt đầu từ đâu.
Vấn đề không phải bạn thiếu công nghệ. Vấn đề là bạn chưa có lộ trình học lập trình 3 tháng có cấu trúc để tư duy như một engineer — không chỉ như người viết code.
Cái bẫy 90% developer mắc phải
Học thêm công nghệ mới. Thấy TypeScript hot → học TypeScript. Thấy Kubernetes → xem tutorial. Kết quả: nhiều keyword trên CV, nhưng không giải quyết được vấn đề thực sự nào sâu hơn.
Làm nhiều LeetCode. Giải 200 bài, nhớ pattern, vào phỏng vấn vẫn trượt vì interviewer hỏi về system design và trade-offs — thứ LeetCode không dạy.
Cả hai đều rơi vào Tactical Programming: tập trung vào làm cho thứ gì đó chạy được thay vì hiểu tại sao nó đúng. Đây cũng là lý do thật sự khiến nhiều dev không tiến bộ sau 2 năm code — không phải do thiếu nỗ lực, mà do học sai hướng.
Một developer có 3 năm kinh nghiệm theo cách này thực chất chỉ có “1 năm kinh nghiệm lặp lại 3 lần”.
Tại sao effort không tích lũy?
Não người bị giới hạn bởi con số 7±2 — số thứ có thể xử lý cùng lúc trong working memory. Khi chỉ học cú pháp, mỗi lần đọc code bạn phải parse từng dòng. Không có gì được chunk lại. Mỗi tuần là một trang trắng mới.
Developer giỏi không nhớ code — họ nhớ ý nghĩa. Não họ đã xây dựng được knowledge schemas — các khung liên kết dựa trên cơ chế chunking trong khoa học nhận thức giúp thông tin mới gắn vào kiến thức cũ tức thì. Đây cũng là lý do developer giỏi debug nhanh hơn 3 lần — không phải vì thông minh hơn, mà vì họ đã có schemas để nhận ra pattern lỗi.
3 tháng tới bạn cần xây schemas — không phải nạp thêm keywords.
Lộ Trình Học Lập Trình 3 Tháng: Từng Bước Cụ Thể
Tháng 1: Foundation Reset — Học cách nghĩ trước khi code
Mục tiêu: Không học công nghệ mới. Rèn Problem Decomposition. Đây là nền tảng của mọi thứ — kể cả system design và debugging.
Trước khi viết bất kỳ dòng code nào — vẽ ra giấy. Chia vấn đề thành các bước nhỏ nhất, đủ nhỏ để giải thích cho người không biết code.
Áp dụng Design it Twice: phác thảo ít nhất 2 cách tiếp cận khác nhau rồi mới chọn. Ví dụ: bạn cần lưu user settings — JSON blob vs mỗi setting là một row riêng. Viết ra nhược điểm của từng cách. Không ai đủ thông minh để thiết kế đúng ngay lần đầu — kể cả senior.
Dấu hiệu thành công: Giải thích được code của mình mà không cần nhìn lại. Khi gặp bug, có giả thuyết trước khi thay đổi bất cứ thứ gì. Thời gian debug giảm rõ rệt.
Tháng 2: Pattern Recognition — Xây Deep Modules
Mục tiêu: Nhận ra design patterns. Build những thứ có giao diện đơn giản nhưng logic mạnh bên trong.
Tháng này bạn build một project nhỏ từ đầu, không copy-paste. Copy-paste tạo ra Voodoo Programming — bạn không biết tại sao code chạy, khi production thay đổi nhẹ lỗi bùng phát ở chỗ không ngờd tới.
Build một mini-system (task manager, URL shortener hoặc expense tracker): mỗi module có interface rõ ràng và hide implementation details, không expose internal state. Sau khi build xong, viết lại từ đầu không nhìn bản gốc — đây là Feynman Technique dưới dạng đơn giản nhất.
Dấu hiệu thành công: Thay đổi implementation của một module mà không phá vỡ phần còn lại. Bắt đầu cảm khó chịu khi thấy code expose quá nhiều internal state. Tự hỏi “cái này sẽ thay đổi như thế nào trong 6 tháng?” trước khi design.
Tháng 3: Systems Thinking — Tư duy Trade-offs
Mục tiêu: Hiểu reliability, scalability và trade-offs — ngôn ngữ của system design interview.
Đây không phải tháng học thêm công nghệ. Đây là tháng bạn apply Strategic Thinking vào chính project đã build ở tháng 2.
Lấy project từ tháng 2, đặt câu hỏi cho từng quyết định thiết kế và viết ra reasoning: “Nếu có 100,000 user, phần nào sẽ fail trước?” — “Trade-off của database này là gì: consistency hay availability?” — “Làm sao deploy không downtime?” — “Nếu cần thêm tính năng mới, phần nào thay đổi nhất?”
Không cần implement tất cả. Cần viết ra được reasoning. Đây là thứ interviewer thực sự kiểm tra — không phải bạn nhớ syntax hay tên thư viện.
Dấu hiệu thành công: Giải thích được trade-off của từng quyết định thiết kế. Nhận ra ngay shallow vs deep module khi đọc code người khác. Sketch được high-level architecture cho một hệ thống nhỏ trong 10 phút.
Khi cấu trúc quan trọng hơn effort
Năm 1970s, một team phải maintain hệ thống viễn thông với 60,000 dòng assembly. Mỗi lần fix bug nhỏ, họ phải thay thế 30 con chip EPROM vật lý — mất vài ngày, tốn kém.
Team bắt đầu vá ví — thêm feature trên feature, patch trên patch. Càng ngày hệ thống càng khó hiểu. Developer mới không ai dám chạm vào. Định nghĩa của technical debt vận hành trong thực tế.
Một developer quyết định dành 3 tháng để restructure theo đúng nguyên lý thiết kế: chia thành 32 module độc lập, áp dụng kiến trúc plugin với bảng vector động — tương đương polymorphism trên assembly.
Kết quả: fix bug chỉ cần thay 1-2 chip thay vì 30. Patch thực hiện từ xa qua dial-up trong vài phút thay vì cử đoàn đến tận nơi. Họ không học thêm công nghệ mới. Họ áp dụng đúng nguyên lý thiết kế vào một hệ thống cũ.
3 thói quen bắt đầu tuần này
Không cần đợi đến tháng 1. Ba thói quen này có thể bắt đầu ngay hôm nay, với bất kỳ project nào bạn đang làm.
1. Design trước, code sau. Mỗi task — dù nhỏ — vẽ ra giấy 5 phút trước khi mở IDE. Không cần flowchart fancy. Chỉ cần các bước bằng tiếng Việt, viết tay. Sau một tháng, bạn sẽ viết ít code hơn nhưng code đúng hơn lần đầu.
2. Sau khi code chạy, hỏi “tại sao?” Không dừng ở “chạy rồi”. Tự giải thích cơ chế cho bản thân. Nếu không giải thích được — bạn chưa thực sự hiểu. Đây là lúc xây knowledge schemas, không phải lúc chuyển sang task tiếp theo.
3. 1 hour/tuần đọc code người khác — không phải học syntax. Đọc open source nhỏ (CLI tools, utility libraries). Hỏi: “Tại sao họ design module này theo cách này?” Đây là cách nhận ra pattern nhanh nhất mà không cần làm project riêng.
3 tháng không phải là thời gian ngắn. Nhưng đủ để thay đổi cách não bạn xử lý vấn đề — từ “làm cho nó chạy” sang “làm cho nó đúng”.
Và đó mới là thứ phỏng vấn — và production — thực sự kiểm tra.


Gửi phản hồi