Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/topics/ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ What experienced AI engineers forget before an interview, grouped by subtopic. F
### Mixture of experts

- An **MoE** layer routes each token to a few of many expert feed-forward networks, so **active parameters** per token are a fraction of the total.
- Compute follows active parameters, but GPUs must hold **all** weights; uneven routing complicates serving.
- Compute follows active parameters, but memory follows **total** parameters (offloading experts to CPU saves GPU memory, at a speed cost); uneven routing complicates serving.

### Reasoning models

Expand All @@ -38,7 +38,7 @@ What experienced AI engineers forget before an interview, grouped by subtopic. F

### Structured output

- **Constrained decoding** masks tokens so output always matches a JSON schema or grammar.
- **Constrained decoding** masks tokens so output matches a JSON schema or grammar β€” except when cut off by the token limit or replaced by a refusal.
- It guarantees **shape, not correctness** β€” still validate values in code.

### Tool calling
Expand Down Expand Up @@ -84,7 +84,7 @@ What experienced AI engineers forget before an interview, grouped by subtopic. F
### Embeddings and similarity

- An embedding maps text to a vector; similarity is usually **cosine** β€” on normalized vectors that's just the dot product.
- Query and documents must use the **same embedding model**; changing models means re-embedding the corpus.
- Query and documents must share one **embedding space** (same model, or jointly trained query/passage encoders as in DPR); changing models means re-embedding the corpus.

### Vector index types

Expand Down Expand Up @@ -165,7 +165,7 @@ What experienced AI engineers forget before an interview, grouped by subtopic. F
### Model Context Protocol

- **MCP** standardizes how apps discover and call tools, read resources, and fetch prompts β€” JSON-RPC 2.0 over stdio (local) or **Streamable HTTP** (remote, replaced HTTP+SSE in 2025).
- Remote servers authorize with **OAuth 2.1**; MCP doesn't replace per-action authorization or business validation.
- Authorization is optional; HTTP servers that support it use **OAuth 2.1**. MCP doesn't replace per-action authorization or business validation.

### Browser automation as a fallback

Expand Down
11 changes: 6 additions & 5 deletions docs/topics/algorithms.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ What experienced engineers forget before an algorithms interview, grouped by sub

### Monotonic stacks

- **Next greater/smaller element**: pop indices the new value makes obsolete; the remaining top is the answer.
- **Next greater/smaller element**, scanning left to right: the new value is the answer for every index it pops.
- Each index is pushed and popped once, so the scan is **O(n)**; pick strict vs non-strict comparison for duplicates.

### Monotonic deque
Expand Down Expand Up @@ -70,7 +70,7 @@ What experienced engineers forget before an algorithms interview, grouped by sub
### Rolling hash (Rabin-Karp)

- A **polynomial rolling hash** updates a window's hash in O(1) as it slides, so search is O(n + m) expected.
- Verify matches (or use two moduli) because collisions happen; also finds duplicate substrings via binary search on length.
- Collisions happen: **verify each match** for exact results β€” two moduli only make collisions rarer; also finds duplicate substrings via binary search on length.

## Sorting and selection

Expand Down Expand Up @@ -149,7 +149,7 @@ Standard array implementations; variants differ in stability and space.

| Edge weights | Algorithm | Time with adjacency lists | Caveat |
|---|---|---|---|
| all equal | BFS | O(V+E) | counts edges |
| all equal, positive | BFS | O(V+E) | counts edges |
| nonnegative | Dijkstra + binary heap | O((V+E) log V) | negative edges invalidate greedy settlement |
| negative allowed | Bellman-Ford | O(VE) | detects reachable negative cycles |
| DAG, any weights | topological relaxation | O(V+E) | needs acyclic graph |
Expand Down Expand Up @@ -201,10 +201,11 @@ Standard array implementations; variants differ in stability and space.

### Bit manipulation

- `x & (x βˆ’ 1)` clears the lowest set bit (zero result = power of two); **`x & βˆ’x`** isolates it.
- `x & (x βˆ’ 1)` clears the lowest set bit, so `x > 0 && (x & (x βˆ’ 1)) == 0` tests a power of two; **`x & βˆ’x`** isolates it.
- XOR of all elements cancels pairs β€” finds the single unpaired number in O(1) space.

### Recognizing NP-hard problems

- Traveling salesman, subset sum, knapsack, graph coloring, SAT, Hamiltonian path, and set cover are **NP-hard** in general.
- Exact answers then need exponential search or pseudopolynomial DP on small numbers; otherwise use a greedy or **approximation** algorithm and say so.
- No polynomial algorithm is known (none exists unless P = NP); exact answers use exponential search with pruning, or pseudopolynomial DP when numbers are small (subset sum, knapsack only).
- Otherwise use heuristics or an **approximation** algorithm where a guarantee exists (greedy set cover: H(n) ≀ ln n + 1); general TSP and coloring have no good ratio unless P = NP.
14 changes: 8 additions & 6 deletions docs/topics/aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ What experienced AWS developers and DevOps engineers forget before an interview,
### Route 53 routing

- Policies: simple, **weighted** (canary), latency, **failover** (with health checks), geolocation, geoproximity, multivalue.
- **Alias records** work at the zone apex (`example.com` β†’ ALB/CloudFront), where a CNAME isn't allowed, and are free to query.
- **Alias records** work at the zone apex (`example.com` β†’ ALB/CloudFront), where a CNAME isn't allowed; queries are free when the target is an AWS resource, but billed when it is a plain record in the same zone.

## Compute

Expand All @@ -70,8 +70,9 @@ What experienced AWS developers and DevOps engineers forget before an interview,

### API Gateway vs ALB

- **API Gateway**: auth, throttling, usage plans, request validation; integration timeout **29 s** by default (raisable for Regional REST APIs).
- **ALB** in front of Lambda or containers is cheaper at high request volume but has none of the API-management features.
- API Gateway REST API: auth, throttling, usage plans, request validation; integration timeout **29 s** by default (raisable for Regional and private APIs).
- **HTTP API**: cheaper, JWT/Lambda/IAM authorizers and throttling, but no usage plans or request validation; integration timeout max **30 s**.
- ALB in front of Lambda or containers can authenticate via OIDC/Cognito but has no throttling, usage plans, or validation; LCU pricing is usually cheaper at sustained high volume.

### ECS service mechanics

Expand Down Expand Up @@ -104,7 +105,8 @@ What experienced AWS developers and DevOps engineers forget before an interview,

### Aurora storage

- The storage volume keeps **6 copies across 3 AZs**; a write needs **4 of 6**, a read **3 of 6** β€” it survives losing an AZ plus one more copy for reads.
- The storage volume keeps **6 copies across 3 AZs**; a write needs **4 of 6**, so writes survive losing an AZ; the **3-of-6** read quorum survives an AZ plus one more copy.
- Normal reads go to one storage node known to be current; quorum reads are only needed during recovery.
- Up to 15 replicas share the same storage volume, so replica lag is usually well under 100 ms and failover doesn't copy data.

### DynamoDB partitions and indexes
Expand All @@ -122,8 +124,8 @@ What experienced AWS developers and DevOps engineers forget before an interview,

### Lambda with SQS

- Lambda **polls** SQS and invokes the function with a batch; by default, one failed record makes the whole batch visible again after the visibility timeout. Enable **partial batch responses** to retry only failed records.
- Set the queue visibility timeout at least as long as the function timeout; configure the **DLQ on the SQS queue**, not the Lambda asynchronous-failure destination.
- Lambda polls SQS and invokes the function with a batch; by default, one failed record makes the whole batch visible again after the visibility timeout. Enable **partial batch responses** to retry only failed records.
- Set the queue visibility timeout to **6Γ— the function timeout** plus the batching window (Lambda rejects anything below 1Γ—); configure the **DLQ on the SQS queue**, not the Lambda asynchronous-failure destination.

### Routing and orchestration

Expand Down
9 changes: 5 additions & 4 deletions docs/topics/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ What experienced backend engineers forget before an interview, grouped by subtop

| Codes | Meaning |
|---|---|
| **401** vs **403** | not authenticated vs authenticated but not allowed (or 404 to hide that the resource exists) |
| **401** vs **403** | missing or invalid credentials (re-auth may help) vs refused β€” credentials, if sent, are insufficient; others might succeed (or 404 to hide that the resource exists) |
| **409** vs **422** | conflicts with current state vs well-formed but fails validation |
| 202 / 204 | accepted for async processing / success with no body |
| 412 / 429 | precondition (`If-Match`) failed / rate limited |
Expand All @@ -37,13 +37,14 @@ What experienced backend engineers forget before an interview, grouped by subtop
| | REST | gRPC | GraphQL |
|---|---|---|---|
| Contract | OpenAPI (optional) | **Protobuf**, strict | schema, strict |
| Transport | HTTP/1.1 or 2 | **HTTP/2** only | usually HTTP POST |
| Transport | any HTTP version | **HTTP/2** only | usually HTTP POST |
| Strength | HTTP caching, simplicity | streaming, speed, codegen | client picks fields, one round trip |
| Weakness | over/under-fetching | browsers need gRPC-Web | hard to cache, N+1, query-cost limits |

### Pagination

- **Cursor (keyset)**: `WHERE (created_at, id) > (:c, :id) ORDER BY ... LIMIT n` β€” fast and stable at any depth; return an opaque cursor.
- **Keyset**: `WHERE (created_at, id) > (:c, :id) ORDER BY ... LIMIT n` β€” fast at any depth and unaffected by inserts; needs a unique, immutable sort key, or updated rows skip or repeat.
- Expose the position as an opaque **cursor**; a cursor is just a token and can also encode an offset.
- **Offset**: simple and jumps to page N, but slows with depth and skips or repeats rows as data changes.

### Versioning
Expand Down Expand Up @@ -72,7 +73,7 @@ What experienced backend engineers forget before an interview, grouped by subtop
### Transactional outbox

- Write the business row and an outbox row in the **same DB transaction**; a relay (poller or CDC) publishes outbox rows and marks them sent.
- Fixes the dual-write problem: committing and publishing can't both be atomic otherwise. Delivery is at-least-once.
- Fixes the dual-write problem without 2PC, which most brokers don't support. Delivery is at-least-once.

### Inbox deduplication

Expand Down
28 changes: 16 additions & 12 deletions docs/topics/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ What experienced database engineers forget before an interview, grouped by subto

### Composite indexes

- **Leftmost-prefix rule**: `(a, b, c)` serves `a`, `a,b`, `a,b,c` β€” not `b` alone.
- Put **equality columns first, range columns last**; the column after a range condition can't be used for seeking.
- **Leftmost-prefix rule**: `(a, b, c)` seeks efficiently on `a`, `a,b`, `a,b,c` β€” not on `b` alone.
- **Skip scan** (MySQL 8.0.13+, PostgreSQL 18+) serves `b` alone by probing each distinct `a`; cheap only when `a` has few values.
- Put **equality columns first, range columns last**; columns after a range condition only filter inside the scanned range (unless skip scan applies).

### Covering indexes

Expand Down Expand Up @@ -68,7 +69,7 @@ What experienced database engineers forget before an interview, grouped by subto

### PostgreSQL MVCC

- Readers read a snapshot and never block writers, or vice versa; writers still lock rows against each other.
- Plain `SELECT`s read a snapshot and neither block nor wait for row writes; writers (and `FOR UPDATE`) still lock rows against each other.
- Old row versions stay in the table, tagged **`xmin`/`xmax`**; **VACUUM** reclaims them, and a long-running transaction blocks it, causing bloat.
- **XID wraparound** (32-bit transaction IDs) forces aggressive anti-wraparound vacuuming.
- HOT updates skip index maintenance when no indexed column changed and the page has room.
Expand All @@ -84,7 +85,7 @@ What experienced database engineers forget before an interview, grouped by subto

### Optimistic locking

- Add a `version` column and `UPDATE ... WHERE id = ? AND version = ?`; zero rows updated means someone else won β€” reload and retry.
- Add a `version` column: `UPDATE ... SET version = version + 1 WHERE id = ? AND version = ?`; zero rows updated means someone else won β€” reload and retry.
- Best when conflicts are rare; pessimistic locks when they're frequent.

### Deadlocks
Expand Down Expand Up @@ -112,8 +113,9 @@ What experienced database engineers forget before an interview, grouped by subto

### Write-ahead log

- Commits append to the **WAL** and `fsync` it before data pages change; pages are written lazily at **checkpoints**.
- Crash recovery replays the log (ARIES-style redo/undo); **group commit** batches many commits into one fsync.
- A commit is durable once its **WAL** record is fsynced; dirty data pages are flushed later (**checkpoints**, background writer), never before their WAL.
- Crash recovery replays WAL from the last checkpoint: PostgreSQL only redoes (uncommitted rows stay invisible by commit status); InnoDB redoes, then rolls back with undo.
- **Group commit** batches many commits into one fsync.

### Backups and PITR

Expand Down Expand Up @@ -148,7 +150,7 @@ What experienced database engineers forget before an interview, grouped by subto

- Any comparison with NULL β€” even **`NULL = NULL`** β€” is UNKNOWN, and `WHERE` drops it; use `IS [NOT] NULL` or `IS [NOT] DISTINCT FROM`.
- **`NOT IN` with a NULL in the list returns no rows** β€” use `NOT EXISTS`.
- `COUNT(*)` counts rows; `COUNT(col)` and other aggregates skip NULLs.
- `COUNT(*)` counts rows; `COUNT(col)`, `SUM`, `AVG`, `MIN`/`MAX` skip NULLs, but `array_agg`/`json_agg` keep them.

### Window functions

Expand Down Expand Up @@ -181,7 +183,7 @@ What experienced database engineers forget before an interview, grouped by subto

### Wide-column key design (Cassandra, DynamoDB)

- The **partition key** picks the node; the sort/clustering key orders rows inside the partition β€” a query must supply the partition key.
- The **partition key** picks the node; the sort/clustering key orders rows inside the partition β€” an efficient query must supply the partition key; otherwise it's a full scan (DynamoDB `Scan`, Cassandra `ALLOW FILTERING`) or a secondary index.
- Model **tables per query** (denormalized), not per entity; unbounded partitions (all events of a popular user) become hot and huge β€” add a time bucket to the key.
- Deletes write **tombstones**, which slow reads until compaction purges them.

Expand All @@ -195,7 +197,8 @@ What experienced database engineers forget before an interview, grouped by subto

### Normalization

- 1NF atomic values β†’ 2NF no partial-key dependency β†’ **3NF/BCNF** no dependency on non-key columns: each fact stored once.
- 1NF atomic values β†’ 2NF no partial-key dependency β†’ **3NF** no transitive dependency through non-key columns: each fact stored once.
- **BCNF** is stricter: every nontrivial dependency's determinant is a superkey; 3NF still allows it when the dependent column is part of a candidate key.
- **Denormalize** measured hot paths only (copied columns, counters, materialized views), accepting harder writes.

### Surrogate keys
Expand All @@ -206,7 +209,7 @@ What experienced database engineers forget before an interview, grouped by subto
### Constraints and soft deletes

- `FOREIGN KEY`, `CHECK`, and `UNIQUE` are the last line of defense β€” application checks alone race.
- **Soft deletes** (`deleted_at`) plus a partial unique index keep history and undo.
- **Soft deletes** (`deleted_at`) keep deleted rows for undo and audit; a partial unique index (`WHERE deleted_at IS NULL`) frees the value for reuse, so an undelete can then conflict.

## Scaling

Expand All @@ -219,12 +222,13 @@ What experienced database engineers forget before an interview, grouped by subto
### Table partitioning

- **Range** (most common, by date), list, or hash; **partition pruning** skips irrelevant partitions.
- Dropping an old partition is instant, unlike a bloating bulk `DELETE`; PostgreSQL unique constraints must include the partition key.
- Dropping an old partition is a cheap metadata change, unlike a bloating bulk `DELETE`, but takes an `ACCESS EXCLUSIVE` lock on the parent β€” `DETACH PARTITION CONCURRENTLY` (PostgreSQL 14+) first avoids that.
- PostgreSQL unique constraints must include the partition key.

### Connection pooling

- Each PostgreSQL connection is a **process** (a few MB), so thousands of direct connections hurt β€” pool them.
- PgBouncer session mode keeps `SET` and advisory locks; **transaction mode** scales further but loses session state; prepared statements work in it **since PgBouncer 1.21**.
- PgBouncer session mode keeps `SET` and advisory locks; **transaction mode** scales further but loses session state; protocol-level prepared statements work in it **since PgBouncer 1.21** when `max_prepared_statements` > 0 (default 0 before 1.24, now 200); SQL `PREPARE` still doesn't.

### OLTP vs OLAP

Expand Down
Loading
Loading