Quản lý nợ kỹ thuật (technical debt) mà không làm dừng dự án

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Mọi dự án phần mềm sống đủ lâu đều có nợ kỹ thuật. Đó là những lối tắt đã chọn để ra sản phẩm nhanh hơn, và bây giờ chúng làm mọi thay đổi chậm dần. Vấn đề không phải là có nợ hay không, mà là bạn có biết mình nợ bao nhiêu và có trả đều đặn hay không.

Nợ kỹ thuật là gì?

Khái niệm do Ward Cunningham đưa ra như một phép ẩn dụ tài chính: làm tắt giống như vay tiền, giúp bạn đi nhanh lúc đầu nhưng phải trả 'lãi' sau này dưới dạng sửa đổi chậm hơn, nhiều lỗi hơn, onboarding khó hơn. Nếu không trả gốc, lãi cứ chồng lên đến mức nhóm chỉ lo chữa cháy.

Các loại nợ

  • Nợ có chủ đích: chọn giải pháp nhanh vì deadline, biết rõ sẽ phải sửa lại. Nếu được ghi nhận và có kế hoạch trả thì đây là quyết định kinh doanh hợp lý.
  • Nợ vô tình: sinh ra do thiếu kinh nghiệm hoặc hiểu sai, chỉ nhận ra sau này.
  • Nợ do thời gian trôi: thư viện lỗi thời, kiến trúc không còn phù hợp quy mô hiện tại, tài liệu cũ.

Cũng cần phân biệt: mã nguồn xấu nhưng không ai cần sửa thì chưa chắc là món nợ đang tính lãi. Chỉ phần nằm trên con đường thay đổi thường xuyên mới thật sự tốn kém.

Dấu hiệu bạn đang chịu nợ nặng

  1. Thêm một tính năng nhỏ mà phải sửa nhiều chỗ.
  2. Sợ động vào một số module vì không ai hiểu nó.
  3. Sửa lỗi này sinh ra lỗi khác.
  4. Người mới mất hàng tuần mới dám đóng góp.
  5. Thời gian triển khai và kiểm thử ngày càng dài.
  6. Nhóm phải làm việc quanh những 'cách tạm' đã tồn tại nhiều năm.

Bước 1: làm cho nợ nhìn thấy được

Món nợ vô hình sẽ không bao giờ được trả. Hãy:

  • Tạo nhãn hoặc loại công việc riêng cho nợ kỹ thuật trong hệ thống quản lý.
  • Mỗi mục ghi rõ vấn đề, ảnh hưởng (chậm cái gì, rủi ro gì) và ước tính công sức.
  • Ghi chú trong mã nguồn bằng chú thích có liên kết tới mục theo dõi, thay vì TODO mơ hồ.
  • Sắp xếp theo mức độ ảnh hưởng, không theo mức độ khó chịu của lập trình viên.

Bước 2: chọn trả cái nào trước

Cân nhắc hai trục: lãi suất (mức độ nó làm chậm công việc hiện tại) và chi phí trả. Ưu tiên khoản nợ nằm ở nơi nhóm sửa nhiều nhất và chi phí trả vừa phải. Những phần ít ai đụng đến có thể để nguyên.

Bước 3: các chiến thuật trả nợ thực tế

  1. Quy tắc hướng đạo sinh: mỗi lần đụng vào một đoạn mã, để lại nó sạch hơn một chút so với lúc bạn tìm thấy.
  2. Dành ngân sách cố định: ví dụ một phần nhỏ công suất mỗi sprint cho việc cải thiện, thay vì chờ 'một dịp rảnh' không bao giờ đến.
  3. Gắn với tính năng: khi làm tính năng trong một khu vực, dọn khu vực đó trước hoặc cùng lúc.
  4. Thêm kiểm thử trước khi refactor: để biết mình không làm hỏng hành vi hiện tại.
  5. Làm từng bước nhỏ: tránh dự án 'viết lại từ đầu' kéo dài nhiều tháng, thường rủi ro cao hơn so với cải thiện dần.
  6. Dùng chiến lược bóp nghẹt dần (strangler): xây phần mới bên cạnh và chuyển dần chức năng sang, thay vì thay thế một lần.

Giải thích với người không làm kỹ thuật

Quản lý và khách hàng không quan tâm tới 'refactor', họ quan tâm tới tốc độ và rủi ro. Hãy nói bằng kết quả:

  • 'Module thanh toán khiến mỗi thay đổi mất gấp đôi thời gian dự kiến. Dành hai tuần dọn dẹp sẽ rút ngắn các tính năng sau.'
  • 'Thư viện này không còn được cập nhật bảo mật, đó là rủi ro.'

Tránh dọa dẫm hay phóng đại; hãy đưa ra dữ liệu thực tế như thời gian hoàn thành, số lỗi liên quan.

Ngăn nợ mới phát sinh

  • Review mã nguồn kỹ lưỡng.
  • Có Definition of Done bao gồm kiểm thử và tài liệu.
  • Kiểm tra tự động (lint, kiểm thử) trong CI.
  • Ghi lại các quyết định thiết kế quan trọng và lý do chọn.
  • Cho phép nhóm nói 'không' với lối tắt gây hại khi không có kế hoạch trả.

Kết luận

Nợ kỹ thuật không đáng sợ nếu bạn quản lý nó như quản lý nợ tài chính: ghi nhận, ưu tiên theo lãi suất và trả đều đặn. Hãy bắt đầu bằng việc liệt kê năm khoản nợ đáng kể nhất trong dự án và đánh giá ảnh hưởng của từng cái.

Muốn rèn tư duy xây dựng phần mềm bền vững, bạn có thể tham khảo các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment