Học cách chuyển đổi tư duy từ lập trình viên sang kiến trúc sư hệ thống. Hiểu tại sao phải hỏi 'Why' trước khi nghĩ đến 'How', và cách tiếp cận vấn đề như một Senior System Architect.
Chia sẻ bài học
Tôi còn nhớ rõ lần đầu tiên bị senior architect hỏi: "Tại sao em chọn Redis?"
Câu trả lời của tôi lúc đó? "Vì Redis nhanh ạ."
Anh ấy mỉm cười: "Nhanh hơn cái gì? Giải quyết vấn đề gì? Cost của nó là gì?"
Tôi câm nín. Đó là lúc tôi nhận ra: mình đang nghĩ như một lập trình viên, không phải một architect.
Khi bạn giỏi code, bạn có xu hướng nhảy thẳng vào giải pháp. Thấy cache? Nghĩ ngay đến Redis. Thấy queue? RabbitMQ. Microservices? Kubernetes.
Nhưng đó là solution-first thinking - tư duy nguy hiểm nhất trong system design.
Tại sao? Vì bạn đang chọn công cụ trước khi hiểu vấn đề. Giống như mua thuốc trước khi biết mình bệnh gì.
Một senior architect không bắt đầu bằng "Tôi sẽ dùng X". Họ bắt đầu bằng "Vấn đề tôi cần giải quyết là gì?"
Đây là cách một developer thường nghĩ:
Kịch bản: Website bị chậm
Developer mindset:
"Website chậm → Cần cache → Dùng Redis → Done!"
Nghe có vẻ logic, nhưng thiếu rất nhiều thứ:
Đó là 5 câu hỏi mà code-first thinking bỏ qua. Và đó chính là lý do nhiều giải pháp kỹ thuật fail.
Tôi từng chứng kiến một startup với 0 users quyết định xây dựng hệ thống bằng microservices từ ngày đầu.
Lý do? "Netflix dùng microservices mà."
Kết quả sau 6 tháng:
Họ đã giải quyết được vấn đề gì? Không có. Vì họ chưa có vấn đề về scale. Họ cần một monolith đơn giản, ship nhanh, iterate nhanh.
Bài học: Netflix dùng microservices để giải quyết vấn đề của Netflix (hàng triệu users, hàng trăm teams). Startup đó không có vấn đề đó.
Đây là cách một architect tiếp cận:
Kịch bản: Website bị chậm
Architect mindset:
1. Define problem:
- Chậm ở đâu? → Measure: 80% thời gian ở database queries
- Queries nào? → Top 3 slow queries chiếm 90% load
2. Understand why:
- Tại sao slow? → Missing indexes
- Tại sao lại missing? → Schema design không tối ưu cho query pattern
3. Evaluate options:
- Option A: Add indexes → Simple, effective
- Option B: Cache query results → Complex, có thể không cần
- Option C: Rewrite queries → Time-consuming
4. Choose solution:
→ Start với indexes (simple, high impact)
→ Monitor
→ Cache nếu vẫn chưa đủ
Thấy sự khác biệt chưa?
Architect không nhảy thẳng vào Redis. Họ measure, analyze, evaluate, then decide.
Trước khi chọn bất kỳ giải pháp kỹ thuật nào, hãy tự hỏi:
1. Vấn đề thực sự là gì?
Không phải "website chậm". Mà là "homepage load time là 3s, users expect < 1s".
Cụ thể, đo đạc được, có target rõ ràng.
2. Tại sao vấn đề này xảy ra?
Đào sâu. Hỏi "Why?" ít nhất 3 lần.
Website chậm
→ Why? Database queries chậm
→ Why? Full table scan
→ Why? Không có index trên email column
→ Root cause: Missing index
3. Giải pháp này giải quyết vấn đề gì?
"Redis làm website nhanh" là câu trả lời tồi.
"Redis cache query results để giảm database load từ 1000 req/s xuống 100 req/s" là câu trả lời tốt.
4. Cost của giải pháp là gì?
Mọi giải pháp đều có cost:
Không có free lunch. Trade-off luôn luôn tồn tại.
5. Có cách đơn giản hơn không?
Đây là câu hỏi quan trọng nhất.
Trước khi thêm Redis, bạn đã thử add index chưa? Trước khi microservices, bạn đã thử scale monolith chưa?
"Simple solutions first. Complex solutions when necessary."
Hãy xem hai approach khác nhau cho cùng một tính năng.
Feature: Đếm số lượt xem video
Developer thinking:
"Cần đếm views → Dùng Redis counter → Increment mỗi view → Done"
Implementation:
- Mỗi view → redis.incr('video:123:views')
- Display: redis.get('video:123:views')
Trông ổn đấy. Nhưng sau 1 tháng production:
Vấn đề phát sinh:
Developer bây giờ phải refactor toàn bộ, migrate data, handle downtime.
Feature: Đếm số lượt xem video
Architect thinking:
1. Requirements:
- Độ chính xác: Có cần 100% accurate? (Probably not)
- Scale: Bao nhiêu videos? Bao nhiêu views/s?
- Analytics: Cần track theo thời gian không?
- Fraud: Cần prevent bot spam không?
2. Design:
- Write to database (persistent, source of truth)
- Async batch write (10s buffer) để giảm DB load
- Cache in Redis (fast read, có thể sai lệch 1-2%)
- Background job sync Redis ← → DB mỗi phút
3. Trade-offs accepted:
- View count có thể delay vài giây (acceptable)
- Có thể sai lệch nhỏ (acceptable cho social metric)
- Complex hơn solution 1 (necessary cho reliability)
Approach này handle được:
Nhớ lại một quyết định kỹ thuật gần đây bạn đã làm. Trả lời:
Bạn chọn giải pháp gì? (VD: Dùng MongoDB thay vì PostgreSQL)
Lý do bạn chọn? Viết ra lý do thật sự, không phải lý do "đẹp".
Bạn đã đo đạc vấn đề chưa? Có metrics cụ thể không?
Bạn có xem xét alternatives không? Có compare PostgreSQL không?
Cost/trade-offs là gì? Bạn đã nghĩ đến chưa?
Nếu câu trả lời 3, 4, 5 là "không" → Đó là code-first thinking.
Chọn một app bạn hay dùng (Facebook, Instagram, Shopee...).
Nhiệm vụ: Đừng đoán họ dùng tech gì. Thay vào đó:
Identify problems họ phải giải quyết:
Reasoning:
Predict solutions:
Thấy sự khác biệt chưa? Bạn đang reason từ problems → solutions, không phải ngược lại.
Đánh dấu những câu bạn đồng ý:
Nếu bạn check được 5/7 → Bạn đang trên đường đúng.
Problem-first thinking không phải về việc biết nhiều công nghệ.
Nó về việc:
Code-first thinking là reflexive: Thấy vấn đề → Nghĩ ngay solution quen thuộc.
Problem-first thinking là deliberate: Hiểu vấn đề → Phân tích → Evaluate options → Decide.
Sự khác biệt này quyết định bạn là một developer giỏi hay một architect giỏi.
Câu hỏi quan trọng nhất mà một architect luôn tự hỏi:
"Tôi đang giải quyết vấn đề gì? Và đây có thực sự là cách tốt nhất không?"
Bắt đầu hỏi câu này từ hôm nay. Mọi thứ sẽ thay đổi.