Python Developer interview prep
A spaced-repetition deck of 522+ Python Developer interview questions — organised by topic and difficulty, and resurfaced right before you'd forget. Preview a few cards below, then sign in to study the whole track on an Anki-style SM-2 schedule.
Free · sign in with GitHub · your progress stays yours.
What's covered
Every topic in this track, grouped the way you'd study it.
Python
130 cardsDatabases
104 cardsBackend
175 cardsCS Fundamentals
43 cardsDevOps & Infra
35 cardsBehavioral
35 cardsSample questions
A few cards from the deck — reveal each answer, then sign in to study the full set on a schedule.
What's the difference between mutable and immutable types?
What's the difference between mutable and immutable types?
Short answer: Mutable objects can be changed in place without creating a new object (list, dict, set, bytearray); immutable ones cannot (int, float, str, bytes, tuple, frozenset, bool, None). Any "change" to an immutable object creates a new object.
In depth: Mutability is about whether an object can change its contents while keeping the same id() (its address in memory).
# Immutable: the operation creates a NEW object
s = "hello"
print(id(s))
s += " world" # a new string is created
print(id(s)) # id changed — it's a different object
# Mutable: the same object is changed
lst = [1, 2, 3]
print(id(lst))
lst.append(4) # change in place
print(id(lst)) # same id
Why it matters:
- Hashability. Only objects that are immutable (by content) can be used as
dictkeys orsetelements. If a key could change, its hash would drift and it couldn't be found. - Safety when sharing. An immutable object can be safely shared across threads/functions — no one can corrupt it.
- Function arguments. Passing a mutable object means the function can change it (see the question on argument passing).
⚠️ Gotcha: A tuple is immutable, but if it holds a list, that list can still be changed:
t = ([1, 2], 3)
t[0].append(99) # OK! the list inside is mutable
print(t) # ([1, 2, 99], 3)
# t[0] = [...] # THIS is a TypeError — you can't reassign an element
Also, hash(([1,2], 3)) will fail — a tuple is unhashable if it contains an unhashable element.
What does SELECT do, and in what order do the parts of a query execute?
What does SELECT do, and in what order do the parts of a query execute?
Short answer: SELECT retrieves rows from tables. The logical execution order does NOT match the written order: first FROM, then WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT.
In depth:
Written (syntactic) order:
SELECT DISTINCT col1, agg(col2)
FROM t
WHERE cond
GROUP BY col1
HAVING agg_cond
ORDER BY col1
LIMIT 10 OFFSET 20;
Logical execution order:
1. FROM / JOIN -- which tables, how to join
2. WHERE -- row filter BEFORE grouping
3. GROUP BY -- grouping
4. HAVING -- group filter AFTER aggregation
5. SELECT -- evaluate expressions, aliases
6. DISTINCT -- remove duplicates
7. ORDER BY -- sorting
8. LIMIT / OFFSET -- slice
⚠️ Gotcha: an alias from SELECT cannot be used in WHERE (since WHERE runs before SELECT), but it can be used in ORDER BY and often in GROUP BY (depends on the DBMS). Example of the error:
SELECT salary * 12 AS annual FROM emp WHERE annual > 100000; -- ERROR
SELECT salary * 12 AS annual FROM emp ORDER BY annual; -- OK
- What is HTTP and how does the request-response cycle work?
- What is HTTP and how does the request-response cycle work?
Short answer: HTTP (HyperText Transfer Protocol) is a text-based application-layer client-server protocol on top of TCP (in HTTP/3 — on top of QUIC/UDP). The client sends a request, the server returns a response; the connection holds no state between requests (stateless).
In depth:
A request consists of a start line (method + path + version), headers, and an optional body:
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Content-Length: 38
{"name": "Anna", "email": "a@ex.com"}
A response consists of a status line (version + code + reason phrase), headers, and a body:
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/42
{"id": 42, "name": "Anna", "email": "a@ex.com"}
⚠️ Gotcha: "HTTP only works over TCP" is incorrect for HTTP/3, which uses QUIC over UDP. And the reason phrase ("OK", "Created") is purely informational — clients should rely on the numeric code, not the text.
What is Big O notation?
What is Big O notation?
Short answer: Big O describes how an algorithm's running time or memory usage grows as the input size n increases, dropping constants and lower-order terms. It's an upper bound on the growth rate.
In detail:
Big O answers the question "what happens when n becomes very large?". We're not interested in the exact number of operations, only the nature of the growth. That's why O(2n + 100) simplifies to O(n), and O(3n² + n) — to O(n²).
The main growth classes (from best to worst):
# O(1) — constant: doesn't depend on n
def first(arr):
return arr[0] if arr else None
# O(log n) — logarithmic: each step halves the problem (binary search)
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1
# O(n) — linear: a single pass
def total(arr):
s = 0
for x in arr: # n iterations
s += x
return s
# O(n log n) — efficient sorts (merge, quick, Timsort)
def sort_it(arr):
return sorted(arr)
# O(n^2) — quadratic: a nested loop
def has_dup_naive(arr):
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
if arr[i] == arr[j]:
return True
return False
# O(2^n) — exponential: naive Fibonacci, enumerating subsets
def fib_naive(n):
if n < 2:
return n
return fib_naive(n - 1) + fib_naive(n - 2)
A rough guide to growth at n = 1,000,000: O(1) — 1 operation, O(log n) — ~20, O(n) — a million, O(n log n) — ~20 million, O(n²) — a trillion (already too much), O(2^n) — infeasible even at n = 50.
⚠️ Gotcha: Big O is about asymptotics (behavior at large n), not about actual time. An O(n) algorithm can be slower than an O(n²) one on small data because of large constants. People also confuse: Big O (upper bound), Ω (lower bound), Θ (tight bound); in interviews "O" usually means Θ.
What is Docker and what problem does it solve?
What is Docker and what problem does it solve?
Short answer: Docker is a containerization platform that packages an application together with all its dependencies, libraries, and configuration into an isolated, portable image. It solves the "works on my machine, but not on the server" problem.
In depth:
The classic pain: a developer wrote code on their laptop (Python 3.11, a specific version of libpq, environment variables), but the server has a different OS version, doesn't have the other libraries, and the variables aren't set — the application crashes. Docker pins the whole environment into an image, and that image runs identically locally, in CI, and in production.
What Docker gives you:
- Reproducibility — the same image everywhere. The environment is described as code (a Dockerfile) and can be versioned in git.
- Isolation — containers don't interfere with each other (dependencies, ports, processes).
- Portability — the image runs on any machine with Docker, regardless of the host OS.
- Fast startup — a container comes up in seconds (unlike a VM).
# Build an image from the Dockerfile in the current directory
docker build -t myapp:1.0 .
# Run a container from the image, publish a port, in the background
docker run -d -p 8000:8000 --name myapp myapp:1.0
# List running containers
docker ps
# Get a shell inside a running container
docker exec -it myapp bash
# Container logs
docker logs -f myapp
⚠️ Gotcha: Docker doesn't "virtualize hardware" and doesn't run a full OS. Containers use the host's kernel. So a Linux image won't run natively on the Windows kernel — on Windows/macOS a lightweight Linux VM runs under the hood (via WSL2 or a hypervisor), and the containers run inside it.
What's the difference between list and tuple?
What's the difference between list and tuple?
Short answer: list is mutable, tuple is not. A tuple is hashable (if all its elements are hashable), uses less memory, and is created slightly faster. Use list for homogeneous, mutable collections and tuple for fixed, heterogeneous records.
In depth:
| Property | list | tuple |
|---|---|---|
| Mutability | yes | no |
| Hashability | no | yes (if elements are hashable) |
| Memory | more (reserves room for growth) | less |
| Creation | slower | faster (a literal can be cached) |
| Semantics | collection of homogeneous elements | record with a fixed structure |
import sys
print(sys.getsizeof([1, 2, 3])) # ~88 bytes
print(sys.getsizeof((1, 2, 3))) # ~64 bytes
Why list is bigger: it keeps an over-allocation — it reserves space in advance for future appends to amortize the cost of growth to O(1). A tuple is fixed and needs no spare room.
When to choose which:
tuple— when the count and meaning of the elements are fixed: coordinates(x, y), returning multiple values from a function, a dictionary key.list— when the collection grows/changes/gets sorted.
⚠️ Gotcha: "a tuple is faster" is true only for creating a literal and for access, not magically for everything. And remember nested mutable objects: a tuple guarantees the immutability of references, not of the objects they point to.
Ready to make it stick?
Start your first session in under a minute. Your future self, mid-interview, will thank you.
Questions about this track
How should I prepare for a Python Developer interview?
Study the concepts you'll be asked to explain, not just the ones you can code. RecallDeck's Python Developer track gives you 522+ curated interview questions and resurfaces each one with an Anki-style SM-2 schedule right before you'd forget it — so the answers are still there under pressure on interview day.
What topics does the Python Developer track cover?
The Python Developer track is organised into the core areas Python Developer interviews actually test, grouped by topic and by difficulty (Concept, Junior, Middle, Senior). You can preview the full outline and sample questions above before signing in.
Is spaced repetition effective for Python Developer interview prep?
Yes. Actively recalling an answer and grading yourself honestly builds far more durable memory than re-reading notes. RecallDeck schedules each Python Developer card to reappear at the moment you're about to forget it, so your daily reviews shrink while your recall holds.
Is the Python Developer track free?
Yes — the Python Developer track and the full SM-2 scheduler are free, with 20 new cards a day. Sign in with GitHub and your progress syncs to your account. RecallDeck Pro ($5/month or $29/year) raises the daily budget and adds cram mode.