Phỏng vấn Backend với Python không chỉ dừng lại ở cú pháp cơ bản mà thường xoay quanh cách ngôn ngữ hoạt động dưới tầng hệ thống. Bài viết này sẽ mổ xẻ những điểm mù cốt lõi giúp bạn tự tin ghi điểm tuyệt đối trước hội đồng phỏng vấn.
1. GIL (Global Interpreter Lock) và Ảnh Hưởng Đến Hiệu Năng Concurrency
GIL là cơ chế khóa độc quyền trong CPython, đảm bảo chỉ một thread được thực thi bytecode Python tại một thời điểm nhằm bảo vệ việc quản lý bộ nhớ (reference counting). Điều này khiến multithreading trong Python tiêu chuẩn không thể tận dụng được đa nhân CPU cho các tác vụ nặng về tính toán.
Hiểu rõ bài toán này giúp bạn phân loại chính xác khi nào nên dùng Threading, Multiprocessing hay Asyncio trong các hệ thống backend.
- CPU-bound: Sử dụng multiprocessing để tận dụng đa nhân CPU, vượt qua giới hạn của GIL.
- I/O-bound: Threading hoặc Asyncio vẫn hoạt động hiệu quả vì thread tự động nhả GIL khi chờ kết quả I/O (network, disk).
- Giải pháp thay thế: Cân nhắc các CPython alternatives như PyPy hoặc các language khác (Go, Rust) nếu hệ thống đòi hỏi extreme concurrency cho tác vụ tính toán.
2. Cơ Chế Quản Lý Bộ Nhớ và Garbage Collection trong Python
Python quản lý bộ nhớ chủ yếu thông qua Reference Counting (Đếm tham chiếu) kết hợp với Generational Garbage Collector (GC) để xử lý các vòng tham chiếu (circular references). Khi một đối tượng có reference count về 0, bộ nhớ được giải phóng ngay lập tức.
Trong các hệ thống backend chạy dài ngày (long-running services), việc hiểu cách GC hoạt động giúp bạn tránh được các lỗi memory leak khó phát hiện.
- Sử dụng sys.getrefcount() để kiểm tra số lượng tham chiếu của một đối tượng trong quá trình debug.
- Tránh tạo ra các vòng tham chiếu khép kín trong class instances hoặc closure để giảm tải cho generational GC.
- Sử dụng module weakref khi cần tham chiếu đến đối tượng mà không làm tăng reference count.
3. ASGI vs WSGI: Kiến Trúc Bất Đồng Bộ Trong Backend Hiện Đại
WSGI (Web Server Gateway Interface) là chuẩn đồng bộ truyền thống, hoạt động hoàn hảo với Django hay Flask truyền thống nhưng không hỗ trợ native async/await. ASGI (Asynchronous Server Gateway Interface) ra đời để giải quyết bài toán xử lý hàng triệu kết nối đồng thời thông qua WebSocket, HTTP/2 và các event loop.
Nhà tuyển dụng thường hỏi câu này để kiểm tra xem bạn có nắm bắt được xu hướng thiết kế hệ thống real-time hay không.
- WSGI: Phù hợp với ứng dụng CRUD truyền thống, blocking I/O, mô hình thread-per-request.
- ASGI: Hỗ trợ event loop, thích hợp cho real-time features, chat, streaming với FastAPI hoặc Django Channels.
- Lưu ý: Không gọi các thư viện blocking I/O (như requests truyền thống) bên trong code async, vì nó sẽ làm nghẽn toàn bộ event loop.
4. Database Connection Pooling và Tối Ưu Hóa Query
Trong kiến trúc Backend, việc tạo mới kết nối database (TCP handshake, xác thực) cho mỗi HTTP request cực kỳ tốn kém tài nguyên và gây latency cao. Connection Pooling giúp tái sử dụng các kết nối có sẵn trong một pool giới hạn.
Một kỹ sư backend giỏi phải biết cách cấu hình thông số pool và nhận diện các vấn đề kinh điển như N+1 query khi sử dụng ORM như SQLAlchemy hoặc Django ORM.
- Cấu hình pool_size và max_overflow dựa trên số lượng worker và tải thực tế của ứng dụng.
- Sử dụng joinedload hoặc selectinload trong SQLAlchemy để giải quyết triệt để lỗi N+1 query.
- Luôn bổ sung database indexing cho các cột thường xuyên xuất hiện trong mệnh đề WHERE, JOIN, và ORDER BY.
Ghi nhớ nhanh
- Nắm vững bản chất của GIL để quyết định sử dụng Multiprocessing hay Asyncio đúng bài toán.
- Hiểu rõ cơ chế Reference Counting và Garbage Collection để phòng chống memory leak trên production.
- Phân biệt rạch ròi giữa WSGI và ASGI khi thiết kế kiến trúc hệ thống web hiện đại.
- Luôn chú trọng đến Connection Pooling và tối ưu hóa câu lệnh SQL từ giai đoạn thiết kế.