Quick software engineering explainers for things you should've googled by now

Join the newsletter →
Joined December 2025
Classic pagination bug: a product search feels instant on the first few pages, then gets slower the deeper it goes. A few hundred pages in, response times stretch into seconds and CPU usage goes up. OFFSET is the culprit, and the fix is a one-line change to the query.
2
5
1
40
19,565
C: a is [1, 3] and b is [1, 2]. a = b = [] binds both names to one list, and a.append(1) adds 1 to it. b + [2] builds a new list and points b at it. a.append(3) only reaches the original list.
Python list aliasing, in four lines. a = b = [] a.append(1) b = b + [2] a.append(3) A) a = [1, 2, 3], b = [1, 2, 3] B) a = [1, 3], b = [2] C) a = [1, 3], b = [1, 2] What do you expect a and b to be?
6
566
Python list aliasing, in four lines. a = b = [] a.append(1) b = b + [2] a.append(3) A) a = [1, 2, 3], b = [1, 2, 3] B) a = [1, 3], b = [2] C) a = [1, 3], b = [1, 2] What do you expect a and b to be?
2
1
6
871
How can two machines share a secret key that doesn't travel over the network? Diffie-Hellman. Each side keeps a private number and sends a value derived from it. The value each side receives, combined with its own private number, produces the shared key.
1
9
374
B, DENSE_RANK. Tied rows share a position, and the next row takes the next number: 1, 2, 2, 3. RANK leaves a gap after the tie (1, 2, 2, 4). ROW_NUMBER gives every row its own number (1, 2, 3, 4).
This SQL query ranks four salaries with one tie and returns pos 1, 2, 2, 3. SELECT name, salary, ____() OVER (ORDER BY salary DESC) AS pos FROM employees; A) RANK B) DENSE_RANK C) ROW_NUMBER Which window function would you write?
4
285
This SQL query ranks four salaries with one tie and returns pos 1, 2, 2, 3. SELECT name, salary, ____() OVER (ORDER BY salary DESC) AS pos FROM employees; A) RANK B) DENSE_RANK C) ROW_NUMBER Which window function would you write?
1
1
1
4
482
A, weather & rivers. Embeddings place text by meaning. Here "river" and "flooded" make "bank" the riverside. Its nearest neighbours are the flood sentences, even though the banking ones share the word "bank".
A vector database turns every sentence into an embedding: a point in space, where similar text sits close together. Where does this one land? "The bank of the river flooded overnight." A) Weather & rivers B) Banking C) Cooking
3
232
A vector database turns every sentence into an embedding: a point in space, where similar text sits close together. Where does this one land? "The bank of the river flooded overnight." A) Weather & rivers B) Banking C) Cooking
1
5
479
B, neither applied. That's atomicity: a transaction is applied in full or not at all. On restart, recovery keeps only committed transactions. This one had not reached COMMIT.
You're moving 100 from alice to bob in one ACID transaction: debit, credit, COMMIT. The server crashes after the debit, before COMMIT. After restart, what's in the database? A) alice debited, bob unchanged B) neither applied C) both applied D) depends on the isolation level
2
213
You're moving 100 from alice to bob in one ACID transaction: debit, credit, COMMIT. The server crashes after the debit, before COMMIT. After restart, what's in the database? A) alice debited, bob unchanged B) neither applied C) both applied D) depends on the isolation level
1
1
1
1
340
C, both: the list changes and a TypeError is raised. += on a list extends it in place first. Then the result is written back into t[0], and tuples don't support item assignment.
A Python tuple can contain a mutable list. Here, += is applied to that list. t = ([1, 2],) t[0] += [3] A) TypeError B) t becomes ([1, 2, 3],) C) Both What do you think happens?
1
166
A Python tuple can contain a mutable list. Here, += is applied to that list. t = ([1, 2],) t[0] += [3] A) TypeError B) t becomes ([1, 2, 3],) C) Both What do you think happens?
2
1
1
4
378
NoneTypeError is the fake. Calling a method on None raises AttributeError: 'NoneType' object has no attribute 'x'.
Four Python exceptions. Three are real. - StopIteration - MemoryError - NoneTypeError - RecursionError Can you spot the fake one?
1
2
216
Four Python exceptions. Three are real. - StopIteration - MemoryError - NoneTypeError - RecursionError Can you spot the fake one?
1
1
3
449
B. Logically, WHERE is evaluated before SELECT, and the alias doubled only exists from SELECT on. ORDER BY is evaluated after SELECT and can use it.
PostgreSQL. A query that filters on its own alias. SELECT price * 2 AS doubled FROM items WHERE doubled > 10 A) returns the matching rows B) error: column "doubled" does not exist Which one do you get?
7
264
PostgreSQL. A query that filters on its own alias. SELECT price * 2 AS doubled FROM items WHERE doubled > 10 A) returns the matching rows B) error: column "doubled" does not exist Which one do you get?
1
3
394
git fetch and git pull both download new commits from the remote. The difference is where those commits end up. fetch only updates the remote-tracking branches like origin/main. pull also merges into the current branch and its files.
1
1
9
502
C. is checks whether both sides are the same object. Two separate lists containing [1, 2] compare equal with ==, and is returns False for them.
Python's `is` operator. Only one of these describes what it checks. The other three belong to ==, type() and hash(). A) both sides have equal values B) both sides have the same type C) both sides are the same object D) both sides hash the same Which one would you pick for is?
152
Python's `is` operator. Only one of these describes what it checks. The other three belong to ==, type() and hash(). A) both sides have equal values B) both sides have the same type C) both sides are the same object D) both sides hash the same Which one would you pick for is?
1
1
5
402
[1, 2]. The default list is created once, when def is executed. Every call without a bucket argument appends to that same list.
Python. A function with a list as its default argument. def add(item, bucket=[]): bucket.append(item) return bucket add(1) add(2) What do you think the second call returns?
6
249
Python. A function with a list as its default argument. def add(item, bucket=[]): bucket.append(item) return bucket add(1) add(2) What do you think the second call returns?
3
1
9
1,021