Debug hiệu quả là kỹ năng quan trọng không kém thuật toán. Dưới đây là các kỹ thuật giúp bạn tìm lỗi nhanh hơn.
Quy trình debug
1. Đọc kỹ thông báo lỗi
| Kết quả | Nguyên nhân phổ biến |
|---|---|
| WA | Sai thuật toán, sai edge case, sai kiểu dữ liệu |
| TLE | Thuật toán quá chậm, vòng lặp vô hạn |
| RE | Truy cập ngoài mảng, chia cho 0, stack overflow |
| CE | Lỗi cú pháp, thiếu include |
| MLE | Cấp phát quá nhiều bộ nhớ |
2. Test với ví dụ mẫu
Chạy tay qua từng dòng code với input mẫu. So sánh kết quả trung gian với kỳ vọng.
3. Tạo test case nhỏ
// Thêm vào cuối main() để test nhanh
// Input nhỏ dễ kiểm tra bằng tay
4. In giá trị trung gian
// C++
cerr << "i=" << i << " dp[i]=" << dp[i] << "\n";
// In mảng
for (int x : a) cerr << x << " "; cerr << "\n";
# Python
print(f"i={i} dp[i]={dp[i]}", file=sys.stderr)
Dùng
cerr(C++) hoặcsys.stderr(Python) để in debug mà không ảnh hưởng output.
Các lỗi thường gặp
Tràn số (Integer Overflow)
// Sai: int * int có thể tràn
int a = 1e9, b = 1e9;
int c = a * b; // tràn!
// Đúng: dùng long long
long long c = (long long)a * b;
// Hoặc
long long c = 1LL * a * b;
Python không bị tràn số nguyên.
Truy cập ngoài mảng
// Sai: index từ 1 nhưng mảng từ 0
for (int i = 1; i <= n; i++) cout << a[i]; // a[n] out of bounds nếu a.size()==n
// Kiểm tra: luôn đảm bảo 0 <= i < a.size()
Vòng lặp vô hạn
// Sai: điều kiện không bao giờ sai
while (l <= r) {
int mid = (l + r) / 2;
if (check(mid)) r = mid; // quên: nếu l==r, mid==l==r, r không đổi!
else l = mid + 1;
}
// Đúng với l < r:
while (l < r) {
int mid = l + (r - l) / 2;
if (check(mid)) r = mid;
else l = mid + 1;
}
Quên reset biến giữa các test case
// Nếu có nhiều test case:
int T; cin >> T;
while (T--) {
// Phải reset mọi biến global/mảng trước khi dùng
fill(dp, dp+n+1, 0);
fill(visited, visited+n+1, false);
// ...
}
Kỹ thuật Stress Testing
So sánh kết quả brute force với thuật toán tối ưu trên input ngẫu nhiên để tìm WA.
import random, subprocess
def brute_force(inp): ...
def fast_solution(inp): ...
for _ in range(1000):
n = random.randint(1, 10)
a = [random.randint(-100, 100) for _ in range(n)]
inp = f"{n}\n{' '.join(map(str,a))}\n"
expected = brute_force(inp)
got = fast_solution(inp)
if expected != got:
print("BUG FOUND!")
print("Input:", inp)
print("Expected:", expected)
print("Got:", got)
break
else:
print("No bugs found in 1000 tests!")
Mẹo nhanh
- Compile với warnings:
g++ -Wall -Wextra -o sol sol.cpp - Chạy với sanitizer (phát hiện UB, out-of-bounds):
g++ -fsanitize=address,undefined - Python: dùng
assertđể kiểm tra bất biến trong code - Nếu bị TLE: đo thời gian từng phần để tìm nút cổ chai
- Nếu không tìm được bug: đọc lại đề — có thể hiểu sai yêu cầu
Bình luận