5 exercises — choose the best-structured answer to common Python Backend Developer interview questions. Focus on precise vocabulary, correct use of technical terms, and demonstrating real experience.
Structure for Python backend interview answers
Name the async primitive: coroutine, event loop, gather, create_task — with the specific concurrency model it belongs to
Explain event loop mechanics: describe what await does (suspends and yields to event loop) and when the GIL is released
Address I/O vs CPU bound: always state which concurrency tool is appropriate for each workload type
Mention profiling tools: asyncio debug mode, cProfile for CPU, py-spy for live profiling
0 / 5 completed
1 / 5
The interviewer asks: "How does Python's asyncio event loop work, and how is async concurrency different from parallelism?" Which answer best explains Python's async model?
Option B is strongest: it precisely defines the event loop as single-threaded (eliminating the "runs faster by parallelism" misconception), distinguishes concurrency from parallelism explicitly, explains what await does mechanically (suspends, yields to event loop), names both gather and create_task, gives the I/O-bound vs CPU-bound decision rule with specifics, and provides the concrete solution for CPU-bound work (run_in_executor). Key structure: single-threaded event loop → concurrency without parallelism → await suspends and yields → gather/create_task → I/O-bound preferred → run_in_executor for CPU-bound. Option C mentions multiprocessing correctly but attributes it to the GIL (partially correct but imprecise — the real reason is blocking the event loop). Option D is accurate but surface-level and does not give the I/O vs CPU decision rule.
2 / 5
The interviewer asks: "What is the GIL in CPython, and how does it affect your choice of concurrency approach?" Which answer best explains the GIL's practical impact?
Option B is strongest: it explains why the GIL exists (reference counting protection), precisely states when threads do work (GIL released during syscalls and C extension I/O), explains why threading fails for CPU-bound (bytecode not parallel), gives all three solutions with trade-offs (multiprocessing: memory/IPC cost; asyncio: single-thread; C extensions: GIL release during compute), and mentions the forward-looking Python 3.13 no-GIL build (PEP 703) — showing current awareness. Key structure: GIL exists for reference counting → threading works for I/O (GIL released in syscalls) → threading fails for CPU → multiprocessing solution + trade-offs → asyncio alternative → C extension GIL release → PEP 703 outlook. Option C is accurate but does not explain why the GIL exists or the IPC cost of multiprocessing. Option D mentions PyPy incorrectly — PyPy has its own GIL.
3 / 5
The interviewer asks: "How does dependency injection work in FastAPI, and why is it useful?" Which answer best explains FastAPI's DI system?
Option B is strongest: it explains the mechanism (signature inspection + recursive resolution), introduces the dependency tree concept, gives three concrete benefits with implementation specifics (generator with finally for DB sessions, auth injection, dependency_overrides for testing), mentions the lifespan context manager as the modern startup/shutdown pattern, and notes the async/sync handling difference (sync runs in thread pool). Key structure: Depends + signature inspection → recursive dependency tree → shared resources via generator → security injection → testability via overrides → lifespan for connection pools → async/sync auto-handling. Option C is accurate and mentions generator dependencies but misses the dependency tree, lifespan, and the async/sync distinction. Option D is too vague — does not explain generator dependencies or the override mechanism.
4 / 5
The interviewer asks: "How do you use type hints in Python, and what tools enforce them?" Which answer best demonstrates typing discipline?
Option B is strongest: it correctly states that the runtime ignores annotations (a common misconception — type hints are not enforced at runtime by default), distinguishes mypy vs pyright (noting pyright is stricter), explains TypeVar with a concrete use case, explains Protocol vs ABC for dependency inversion (a senior-level concept), explains Annotated with real framework examples (FastAPI, Pydantic), and mentions the Python 3.12 type parameter syntax improvement. Key structure: gradual typing: runtime ignores → mypy vs pyright → TypeVar for generics → Protocol for structural subtyping → Annotated for framework metadata → TypedDict/dataclasses → CI enforcement → 3.12 syntax improvement. Option C is accurate but treats Optional as a separate concept (it is just Union with None in modern Python) and does not explain Protocol. Option D recommends typing "at minimum function signatures" which is good advice but does not explain the Annotated pattern or gradual typing mechanics.
5 / 5
The interviewer asks: "What are the common pitfalls with SQLAlchemy ORM, and how do you handle the N+1 query problem?" Which answer best explains ORM query patterns?
Option B is strongest: it precisely defines N+1 as replacing a JOIN with N round trips (not just "one query per item"), explains why joinedload vs selectinload are appropriate in different cases (JOIN vs IN clause, duplicate row risk for one-to-many), explains DetachedInstanceError from session mismanagement, explains why async disables lazy loading by default (event loop blocking — not just "not supported"), and introduces bulk operations as a separate performance pattern. Key structure: N+1 = N round trips replacing one JOIN → joinedload (JOIN) vs selectinload (IN clause, one-to-many) → session lifecycle and DetachedInstanceError → async disables lazy loading to prevent event loop blocking → bulk operations for mass inserts. Option C is accurate and gives the async reason but does not explain why selectinload is preferred for one-to-many or mention DetachedInstanceError. Option D does not explain the JOIN vs IN clause distinction or session lifecycle errors.