Ngăn xếp lời gọi & tràn stack
Vì sao đệ quy "tốn chỗ", máy nhớ mình đang ở tầng nào bằng cách nào, và vì sao đệ quy quá sâu (hoặc thiếu base case) làm chương trình sập với lỗi tràn ngăn xếp.
1. Trực quan: chồng đĩa
Mỗi lần gọi một hàm, máy đặt một "khung" (frame) lên trên cùng một chồng — gọi là ngăn xếp lời gọi (call stack). Khung chứa: hàm nào, biến cục bộ, đang chạy tới dòng nào. Khi hàm return, khung trên cùng bị lấy ra, máy quay lại khung dưới.
Giống chồng đĩa: đặt thêm đĩa lên trên (gọi hàm), lấy đĩa trên xuống (return). Vào sau ra trước.
2. Chạy debug: chồng khung lớn lên rồi xẹp xuống
Bước qua dem_nguoc(3). Cột biến hiện ngăn xếp (đáy → đỉnh). Để ý nó cao dần khi gọi sâu, rồi
xẹp khi return:
Đây cũng là lý do (nhắc ở bài 1.2.5) đệ quy tốn O(n) không gian dù không tạo mảng nào: mỗi tầng chiếm một khung.
3. Tràn ngăn xếp (stack overflow)
Chồng khung có giới hạn. Nếu đệ quy quá sâu (hoặc vô hạn vì thiếu/sai base case), chồng vượt giới hạn → máy báo lỗi và sập. Bấm Run để thấy (Python giới hạn ~1000 tầng):
Hàm hong không có base case và còn đi xa dần base (n tăng) → gọi mãi → tràn. Python chặn lại
bằng RecursionError thay vì để sập máy.
4. Ba nguyên nhân tràn stack thường gặp
- Thiếu base case — không có điểm dừng.
- Base case không bao giờ tới — bước đệ quy đi sai hướng (vd
n + 1thay vìn - 1). - Đệ quy quá sâu hợp lệ — bài thật sự cần đệ quy hàng triệu tầng → nên đổi sang vòng lặp (học ở bài 1.3.3).
5. Mẫu nhận diện
- Đệ quy mà chạy là sập /
RecursionError→ kiểm base case và hướng của bước đệ quy. - Đệ quy sâu theo
nlớn → cẩn thận bộ nhớ call stack (O(n)); cân nhắc khử đệ quy.
6. 🎮 Trò chơi: Cái nào tràn stack?
7. Quiz kiểm tra nhanh
8. Hoàn thành
…☑️ Tiếp theo: 1.3.3 — Đệ quy ↔ lặp; khử đệ quy.