Debug có hệ thống: 6 bước tìm lỗi thay vì đoán mò

  • author-image

    Nguyễn Đình Cường

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

Nhiều bạn mới học lập trình xử lý lỗi bằng cách sửa đại một chỗ, chạy thử, không được thì sửa chỗ khác. Cách này tốn thời gian và còn dễ tạo thêm lỗi mới. Debug giỏi là một kỹ năng có quy trình rõ ràng, và bài này giới thiệu 6 bước bạn có thể dùng ngay.

Bước 1: Tái hiện được lỗi

Nếu bạn không làm lỗi xuất hiện theo ý muốn, bạn không thể chắc chắn mình đã sửa xong. Hãy ghi lại chính xác: dữ liệu đầu vào là gì, thao tác nào dẫn đến lỗi, môi trường nào (trình duyệt, hệ điều hành, phiên bản). Cố gắng tìm ra các bước ngắn nhất để lỗi xuất hiện.

Với lỗi "thỉnh thoảng mới xảy ra", hãy tìm điểm chung: cùng một loại dữ liệu, cùng một thời điểm, cùng một người dùng? Thường có một quy luật ẩn phía sau.

Bước 2: Đọc kỹ thông báo lỗi

Thông báo lỗi và stack trace thường chỉ thẳng vào file và dòng có vấn đề. Hãy đọc từ đầu đến cuối thay vì lướt qua. Dòng đầu cho biết loại lỗi, các dòng tiếp theo cho biết chuỗi hàm được gọi. Với code của bạn, hãy tập trung vào các dòng thuộc dự án, bỏ qua tạm các dòng trong thư viện bên thứ ba.

Bước 3: Đặt giả thuyết

Trước khi đụng vào code, hãy tự hỏi: "Điều gì có thể gây ra hiện tượng này?" Viết ra 2-3 giả thuyết, xếp theo khả năng. Ví dụ, trang hiển thị rỗng có thể do API trả về rỗng, do code lọc sai, hoặc do render trước khi dữ liệu về. Mỗi giả thuyết cần một cách kiểm chứng cụ thể.

Bước 4: Thu hẹp phạm vi (chia để trị)

Đây là bước quan trọng nhất. Thay vì đọc cả chương trình, hãy tìm xem lỗi nằm ở nửa nào của luồng xử lý:

  • In hoặc dùng breakpoint ở giữa luồng. Dữ liệu đã sai ở đó chưa? Nếu đã sai thì lỗi nằm phía trước, nếu còn đúng thì lỗi nằm phía sau.
  • Lặp lại, mỗi lần loại bỏ một nửa vùng nghi ngờ, giống tìm kiếm nhị phân.
  • Với lỗi xuất hiện sau một lần thay đổi, dùng git bisect hoặc so sánh diff để tìm commit gây lỗi.
  • Tạm vô hiệu hóa (comment) các phần không liên quan để cô lập vấn đề.
function getDiscount(user, cart) {console.log('user:', user);       // Dữ liệu vào có đúng không?const rate = user.isVip ? 0.2 : 0;console.log('rate:', rate);        // Kết quả trung gianreturn cart.total * rate;}

Cách in log đơn giản vẫn hiệu quả, nhưng nếu có thể, hãy dùng debugger để dừng tại breakpoint và xem toàn bộ biến cùng lúc.

Bước 5: Sửa tận gốc rồi kiểm chứng

Khi đã tìm ra nguyên nhân, hãy sửa nguyên nhân chứ không chỉ sửa triệu chứng. Ví dụ, nếu giá trị null làm hàm bị lỗi, hãy hỏi tại sao nó lại là null, thay vì thêm một dòng if (x == null) return để che lỗi.

Sau khi sửa:

  1. Chạy lại đúng các bước tái hiện ở bước 1.
  2. Chạy các test hiện có để chắc không làm hỏng chỗ khác.
  3. Nếu có thể, viết thêm một test để lỗi này không quay lại.

Bước 6: Rút kinh nghiệm

Sau khi sửa xong, dành 2 phút tự hỏi: lỗi này xuất hiện vì lý do gì (thiếu kiểm tra dữ liệu, hiểu sai tài liệu, thiếu test)? Có chỗ nào khác trong code có thể mắc lỗi tương tự không? Ghi lại vào ghi chú cá nhân nếu đó là một lỗi lạ. Một thời gian sau bạn sẽ có "bộ sưu tập" lỗi thường gặp và debug nhanh hơn rất nhiều.

Những thói quen xấu nên tránh

  • Thay đổi nhiều thứ cùng lúc: bạn sẽ không biết thay đổi nào có tác dụng.
  • Tin chắc "code của tôi đúng": hãy kiểm chứng giả định bằng dữ liệu thật, đừng suy luận bằng trí nhớ.
  • Bỏ qua lỗi cảnh báo (warning): nhiều khi chúng là manh mối sớm.
  • Debug khi đang mệt: nghỉ 10 phút, đi dạo, rồi quay lại thường nhanh hơn ngồi cố thêm một giờ.
  • Không dùng version control: commit trước khi thử nghiệm để có thể quay về dễ dàng.

Kết luận

Debug không phải là phép màu mà là một quy trình: tái hiện, đọc lỗi, đặt giả thuyết, thu hẹp phạm vi, sửa tận gốc và rút kinh nghiệm. Hãy áp dụng sáu bước này cho lỗi tiếp theo bạn gặp, bạn sẽ thấy mình bình tĩnh và nhanh hơn hẳn.

Để luyện kỹ năng này qua các dự án thực hành, bạn có thể tham khảo những khóa học lập trình tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment