AI
prepair.app
Start interview →
EnglishРусскийУкраїнська
🐍

Middle Python BackendPython backend interview questions

Middle · 2–4 years of experience

Python backend interviews cover language internals, async programming, Django or FastAPI, and database access patterns. Below are the most common questions with model answers. Middle: deeper understanding, optimization, and real-world situations.

Topics to prepare

Data types and structures
Decorators and generators
GIL and concurrency
asyncio and async/await
Django / FastAPI
ORM and SQL optimization

10 Middle-level questions with answers

1

What is the difference between a list and a tuple? When do you use each?

Answer

Lists are mutable and tuples are immutable, which makes tuples hashable and usable as dictionary keys. Tuples are slightly faster and signal to the reader that the collection is a fixed record rather than a growing sequence. Use a list when the contents change and a tuple for fixed heterogeneous data such as coordinates or a returned pair.

2

What is a decorator? Write one that measures execution time.

Answer

A decorator is a callable that takes a function and returns a replacement, used to add behaviour without touching the original body. A timing decorator wraps the call: record perf_counter before, invoke the function, record after, log the delta, and return the result. Always apply functools.wraps to the inner function so the original name, docstring, and signature survive introspection.

3

Explain the difference between a generator and a regular function. Why do we need yield?

Answer

A regular function computes everything and returns once; a generator suspends at each yield and resumes where it left off, producing values lazily. That means constant memory regardless of how many items are produced, so you can iterate a multi-gigabyte file or an infinite sequence. yield is what turns the function into a state machine the interpreter can pause and resume.

4

What are *args and **kwargs? Give a usage example.

Answer

*args collects extra positional arguments into a tuple and **kwargs collects extra keyword arguments into a dict. They are used when a function must accept an arbitrary signature — most often in decorators and wrappers that forward everything to the wrapped callable. The mirror use is unpacking: calling f(*items, **options) spreads a sequence and a mapping into arguments.

5

What is the difference between multiprocessing, threading, and asyncio?

Answer

Threading gives concurrency within one process and helps only with I/O because of the GIL. Multiprocessing spawns separate interpreters with real parallelism, at the cost of process startup and inter-process communication — the right choice for CPU-bound work. asyncio is single-threaded cooperative concurrency: tasks yield at await points, which scales to tens of thousands of sockets but blocks everything if you call synchronous code inside a coroutine.

6

What is a context manager? How do you implement your own?

Answer

A context manager guarantees setup and teardown around a block, which is what with statements use to close files or release locks even when an exception is raised. You implement one either as a class with __enter__ and __exit__, or as a generator decorated with @contextlib.contextmanager that yields once between the setup and cleanup code. The __exit__ method receives exception details and can suppress the exception by returning True.

7

Explain MRO and multiple inheritance.

Answer

The Method Resolution Order defines the sequence in which Python searches classes for an attribute, computed by the C3 linearization algorithm. It guarantees that a class always precedes its parents and that the order of base classes is respected, which makes diamond inheritance predictable. super() follows the MRO rather than jumping straight to the parent, which is why cooperative multiple inheritance requires every class in the chain to call super().

8

What is the N+1 problem in Django ORM? How do select_related and prefetch_related help?

Answer

N+1 occurs when a queryset returns N objects and each access to a related field triggers its own query. select_related solves it for ForeignKey and OneToOne by performing a SQL JOIN and populating the related object in the same query. prefetch_related handles ManyToMany and reverse relations by running a second query and joining the results in Python, which is why it produces two queries instead of one.

9

What is the difference between a shallow copy and a deep copy?

Answer

A shallow copy creates a new outer container but keeps references to the same nested objects, so mutating a nested list is visible through both copies. A deep copy recursively duplicates everything, giving full independence at the cost of time and memory. The bug this causes in practice is a mutable default argument or a shared nested config that one caller mutates for everyone.

10

What is the difference between __str__ and __repr__?

Answer

__repr__ is aimed at developers and should ideally be unambiguous — often something that looks like the expression needed to recreate the object; it is what the REPL and debuggers show. __str__ is aimed at end users and is what print() and str() call, falling back to __repr__ when it is not defined. Implementing __repr__ is the higher-value habit because it makes logs and tracebacks readable.

🦎

Reading answers is not enough

In a real interview you speak under pressure. Cam asks these same questions, scores every answer, and shows exactly what to fix.

Practice a Middle Python Backend interview →
Free · 3 interviews per month

Other levels — Python Backend

Junior Python BackendSenior Python BackendAll Python Backend questions

Other specializations

🔍Middle Manual QA🤖Middle QA AutomationMiddle Java Backend🐘Middle PHP Backend🦫Middle Go Backend🟢Middle Node.js Backend⚛️Middle React Frontend💚Middle Vue Frontend🅰️Middle Angular FrontendMiddle Next.js