Phỏng vấn vị trí Python/Backend thường không chỉ dừng lại ở cú pháp cơ bản mà xoay quanh cách hệ thống hoạt động dưới gầm kap. Bài viết này sẽ mổ xẻ những điểm mấu chốt về kiến trúc và runtime giúp bạn vượt qua mọi câu hỏi hóc búa.
1. Global Interpreter Lock (GIL) và Ảnh hưởng đến Concurrency
GIL (Global Interpreter Lock) là một mutex trong CPython ngăn chặn nhiều native threads thực thi mã bytecode Python cùng một lúc. Điều này đảm bảo an toàn cho việc quản lý bộ nhớ nhưng lại trở thành nút thắt cổ chai khi xử lý các tác vụ nặng về tính toán.
Hiểu về GIL giúp bạn giải thích được vì sao multithreading trong Python không tận dụng được đa nhân CPU cho các bài toán CPU-bound, từ đó đưa ra giải pháp kiến trúc chính xác.
- CPU-bound tasks: Nên sử dụng multiprocessing để tách biệt các process hoàn toàn độc lập.
- I/O-bound tasks (gọi API, truy vấn DB): Threading hoặc async/await vẫn hoạt động rất hiệu quả vì GIL được giải phóng trong lúc chờ đợi I/O.
2. Cơ chế Garbage Collection (GC) và Quản lý Bộ nhớ
Python quản lý bộ nhớ chủ yếu thông qua Reference Counting (Đếm tham chiếu). Khi số lượng tham chiếu của một đối tượng giảm về 0, bộ nhớ sẽ được giải phóng ngay lập tức.
Tuy nhiên, hiện tượng vòng tham chiếu (reference cycles) xảy ra khi hai đối tượng trỏ qua lại lẫn nhau không thể bị xóa bởi đếm tham chiếu thuần túy. Python giải quyết việc này bằng generational garbage collector.
- Chia đối tượng thành 3 thế hệ (Generation 0, 1, 2) dựa trên thời gian sống.
- Các đối tượng sống sót qua nhiều đợt quét sẽ được đẩy lên thế hệ cao hơn để giảm tần suất quét.
3. Phân biệt WSGI và ASGI trong Python Web Frameworks
WSGI (Web Server Gateway Interface) là tiêu chuẩn đồng bộ lâu đời kết nối giữa web server (như Gunicorn) và ứng dụng Python (Flask, Django phiên bản cũ).
ASGI (Asynchronous Server Gateway Interface) ra đời để kế thừa WSGI, hỗ trợ đầy đủ lập trình bất đồng bộ (async/await), WebSocket và HTTP/2, đóng vai trò nền tảng cho FastAPI và Django Channels.
- WSGI: Xử lý mỗi request trên một thread hoặc process riêng biệt, phù hợp với mô hình request-response truyền thống.
- ASGI: Xử lý hàng ngàn kết nối đồng thời trên một event loop duy nhất, tối ưu cho ứng dụng real-time.
4. Database Connection Pooling và Tối ưu hóa ORM
Việc mở một kết nối database mới cho mỗi HTTP request tiêu tốn rất nhiều tài nguyên và thời gian thiết lập TCP handshake. Connection pooling giúp duy trì sẵn một tập hợp các kết nối đã mở để tái sử dụng.
Khi làm việc với các ORM như SQLAlchemy hoặc Django ORM, nhà tuyển dụng thường hỏi về hiện tượng N+1 query problem và cách khắc phục.
- Luôn cấu hình pool_size và max_overflow phù hợp với số lượng worker của ứng dụng.
- Sử dụng `select_related` hoặc `joinedload` để eager loading dữ liệu liên quan, tránh việc query lặp lại trong vòng lặp.
Ghi nhớ nhanh
- Nắm chắc GIL để giải thích rõ khi nào nên dùng Multiprocessing, Multithreading hay Asyncio.
- Hiểu cơ chế Reference Counting và GC giúp bạn viết code tránh memory leak trong các hệ thống chạy ngầm lâu dài.
- Phân biệt rõ WSGI và ASGI để định hình kiến trúc web backend phù hợp với yêu cầu thực tế.
- Luôn chú ý đến Connection Pooling và tối ưu ORM query để đảm bảo khả năng scale hệ thống database.