Interview refresher: TypeScript, JavaScript, Python
A guide for rebuilding fundamentals that have eroded under AI-assisted coding. It covers data structures, algorithms, language internals, performance and design patterns across TypeScript/JavaScript and Python, and it is built around one idea: the parts an assistant does well for you (typing out a known algorithm) are exactly the parts interviews now value least, and the parts it cannot do for you (choosing, justifying, adapting, debugging live) are the parts being tested harder.
22 chapters, ~30,700 lines, ~206,000 words, 842 code blocks. Everything runnable was executed; every benchmark number was measured on the machine this was written on; every type-level claim was compiled; every test suite was run.
Start here
graph TD
Start["How much time do you have?"]
Start -->|"20 minutes"| A["Cheat sheets (ch 14)<br/>trap list + phrasebook"]
Start -->|"An hour"| B["Complexity ch 01 §9<br/>+ 3 drills from ch 13 §6"]
Start -->|"A week"| C["Study plan (ch 15)<br/>sprint track"]
Start -->|"Two months"| D["Study plan (ch 15)<br/>8-week plan"]
Start -->|"Ongoing"| E["Study plan ch 15 §4<br/>maintenance loop"]
| If you have… | Do this |
|---|---|
| 20 minutes | Cheat sheets — the trap list in §7 and the phrasebook in §8 |
| An hour | Complexity §9 (the measured accidental quadratics), then three drills from Problem sets §6 |
| A week | Study plan sprint track |
| Two months | Study plan 8-week plan |
| Ongoing | Study plan §4 — the ~2 h/week anti-rust loop |
| Interviewing on testing | Testing cheat sheet §1-3 (side-by-side APIs), then strategy §2-3 and §9 |
| You own Effective Python / Effective TypeScript | The crosswalks: 20 §3 and 21 §2 tell you which of the 208 Items you can skip |
If you only take one thing from this guide: close the file and write the heap from scratch. The diagnosis is a retrieval failure, not a knowledge failure, and retrieval only improves by retrieving.
The files
Foundations
| File | What it covers | Lines |
|---|---|---|
| 01 Complexity and Big-O | O/Theta/Omega, amortized analysis, Master Theorem, reading complexity off code, the complexity of every built-in in both languages, and §9: the measured traps — every accidental quadratic with its real growth exponent | 968 |
| 02 JavaScript and Node core | coercion, closures, this, prototypes, generators, the event loop (libuv phases, predict-the-output puzzles, a spec-faithful Promise from scratch), GC, and the V8 performance model with measured inline-cache and elements-kind penalties | 2,389 |
| 03 The TypeScript type system | variance, conditional/mapped/template-literal types, satisfies, 25 utility types reimplemented, type-level programming, the 6.0 -> 7.0 transition. Every claim compiler-verified | 1,358 |
| 04 Python core and CPython internals | the object model, the data model, descriptors and the MRO, generators and asyncio, the GIL (measured), memory management, bytecode, and performance idioms with numbers | 1,552 |
Data structures
| File | What it covers | Lines |
|---|---|---|
| 05 Data structures in TypeScript | every built-in with complexity and traps, then 17 structures from scratch: dynamic array through segment tree, skip list, and Bloom filter. All executed | 3,829 |
| 06 Data structures in Python | the same, Python-side: collections, heapq, bisect, itertools as algorithm tools, then 16 from-scratch implementations including CPython’s own probe sequence | 2,054 |
Algorithms
| File | What it covers | Lines |
|---|---|---|
| 07 Sorting and searching | 12 sorts verified against the built-ins, TimSort internals with measured adaptivity (9.3x on sorted input), and binary search including the three templates and searching the answer | 998 |
| 08 Algorithm patterns | the 12 pattern families with recognition signals: two pointers, sliding window, prefix sums, monotonic stack, intervals, cyclic sort, backtracking, greedy, bits, strings, matrices | 1,245 |
| 09 Graphs and trees | BFS/DFS, grids, topological sort, cycle detection, all four shortest-path algorithms, MST, SCC, bipartite, and the tree operations. Competing algorithms cross-checked against each other | 951 |
| 10 Dynamic programming | organized by state shape: 1D, knapsack family, two-sequence, grid, interval, bitmask, tree, digit, state-machine — plus the optimizations | 878 |
Design
| File | What it covers | Lines |
|---|---|---|
| 11 Design patterns in TypeScript | SOLID with refactorings, all 23 GoF patterns with an opinion on each, TS-idiomatic patterns (DI, Result, branded types, async patterns), anti-patterns, decision table | 2,414 |
| 12 Design patterns in Python | the same for Python: what the language dissolves, decorators and descriptors and context managers as first-class patterns, Protocol vs ABC, the case against metaclasses | 4,350 |
Testing
| File | What it covers | Lines |
|---|---|---|
16 Testing with node:test | the built-in Node runner: structure, node:assert, mock.fn/mock.method/mock.timers/mock.module, snapshots, coverage, reporters, TypeScript, and integration tests using only the standard library | 1,276 |
17 Testing with unittest | TestCase, the 41 assertions, addCleanup/enterContext, subTest, all of unittest.mock including autospec and AsyncMock, doctest, and integration tests with sqlite3/tempfile/http.server | 1,214 |
| 18 Test strategy and integration testing | the five test doubles, mocks vs fakes, pyramid vs trophy, testability as design, functional core / imperative shell, mutation testing measured, flakiness, contract and property testing, legacy code, CI | 979 |
| 19 Testing cheat sheet and drills | side-by-side API and assertion translation tables, mocking recipes, copy-paste skeletons, the testing trap list, 20 drills, 32 flashcards, phrasebook | 648 |
Book crosswalks
| File | What it covers | Lines |
|---|---|---|
| 20 Effective Python crosswalk | all 125 Items of Slatkin’s 3rd edition mapped onto this guide — 45 covered, 48 partial, 18 gaps closed with runnable code, 13 out of scope — plus Item 109 settled by measurement: unit vs integration suites at equal effort, both 100% coverage, both 11/15 mutation, killing different mutants | 821 |
| 21 Effective TypeScript crosswalk | all 83 Items of Vanderkam’s 2nd edition — 28 covered, 36 partial, 10 gaps closed, and 2 now stale: TS 6 is strict by default, which inverts the book’s migration advice. Closes the guide’s own worst gaps: types-as-sets, type/value space, excess property checking, contextual typing | 637 |
Practice
| File | What it covers | Lines |
|---|---|---|
| 13 Problem sets | what interviews look like in 2026, which curated list to use, ~80 core problems mapped to patterns, 70 depth variations, language-specific drills, 20 implement-from-scratch drills, debug-and-fix drills | 496 |
| 14 Cheat sheets | the lookup file: complexity tables, both language references, side-by-side comparison, every algorithm template, the trap list, and an interview phrasebook | 684 |
| 15 Study plan and flashcards | an 8-week plan, a maintenance loop, spaced-repetition schedule, self-assessment tracker, and 91 inline flashcards | 708 |
flashcards.tsv | 154 cards (36 on testing, 27 from the book crosswalks), tab-separated with tags, ready to import into Anki | — |
Reading orders
Rebuilding fundamentals (recommended). 01 -> the 20 drills in 13 §6 -> 05/06 as reference while drilling -> 07 -> 08 -> 09 -> 10 -> 02/04 for internals -> 03 -> 11/12 -> 14 for maintenance.
Interview in two weeks. 14 (all of it) -> 13 §1-3 -> 08 -> 10 -> 09 -> the starred drills daily -> one chapter’s interview-questions section each evening.
Senior/staff loop, where the internals questions live. 02 §6-8 (event loop, GC, V8) -> 04 §6-9 (GIL, memory, bytecode, perf) -> 03 (type system) -> 11/12 (SOLID, pattern judgement) -> 01 §11-12 (lower bounds, how to talk about complexity).
Language-specific brush-up. JS/TS: 02 -> 03 -> 05 -> 11 -> 16. Python: 04 -> 06 -> 12 -> 17.
If you own the two Effective books. Read 21 §4 first — the book’s first four chapters are where this guide is weakest and they fix real gaps in how you read type errors. Then 20 §5, then 20 §4 for the unit-vs-integration measurement. Use the matrices to skip the ~35% of each book this guide already covers at equal or greater depth.
Testing, from scratch. 18 §1-3 (what tests are for, the doubles) -> 16 or 17 for your language -> 18 §6-9 (testability, pure cores, mutation testing) -> 19 for the drills. If you only read one section, make it 18 §9.
How this guide is different from a tutorial
Everything runs. Not “should work” — was executed. Each data-structure and algorithm chapter ends with
the actual test output, and where two algorithms solve the same problem they are checked against each
other (Kahn vs DFS topological sort, Prim vs Kruskal, Tarjan vs Kosaraju, O(n^2) vs O(n log n) LIS on 50
random arrays). Type-level claims are verified by the compiler, including the negative ones — the
@ts-expect-error markers fail the build if the error does not occur.
Benchmarks are measured, not quoted. Every number came from this machine (CPython 3.11.15, Node 22.22.2 / V8 12.4, a 2-core cloud container). A sample of what that produced:
| Claim | Measured |
|---|---|
list.insert(0, x) vs deque.appendleft | 145x slower at n = 32,000 (exponent 1.97 vs 1.13) |
x in list vs x in set | 250x slower at n = 4,000, and diverging |
| Monomorphic vs megamorphic property access in V8 | 4.3x |
One delete arr[i] on a 20k array | 15-40% slower iteration, permanently (one-way transition) |
| Timsort on sorted vs random input | 9.3x faster |
| Python threads on CPU-bound work | 5% slower than sequential; processes 2x faster |
| CPython list growth factor | converges on 1.125 (n + n>>3 + 6), 86 reallocations per 1e6 appends |
| Node vs CPython on a tight numeric loop | ~30x |
__slots__ on 3.11 | 31% less memory, zero speed difference |
| Bloom filter false-positive rate at a 1% target | 3.01% with FNV-1a+djb2, 0.98% with a split BLAKE2b digest |
| Two test suites at identical 100% line coverage | mutation scores 0/5 and 4/5 |
| Unit-only vs integration-only suite, same module, equal effort | both 100% coverage, both 11/15 mutation — but 2 kills each that the other misses |
tsc 6.0.3 with no config and no flags | noImplicitAny and strictNullChecks already on |
Several of those contradict common advice, which is the point. The __slots__ result and the
LOAD_GLOBAL result mean the folklore is stale on Python 3.11; the string-concatenation results mean the
“always use join” rule is Python-specific and more subtle than usually stated.
Failures are documented. The first inline-cache benchmark showed no difference because a shared counter dominated the loop — that mistake is in 02 §8.2 along with how to design the benchmark correctly, because “a benchmark showing no difference is more often a broken benchmark than a disproved theory” is a more useful lesson than the number. Likewise the Bloom filter’s signed-32-bit bug, which produced actual false negatives, is documented in 05 §22.
Opinions are stated. The design-pattern chapters say which GoF patterns are dead weight in each
language and why. The DP chapter says which optimizations to name and never implement. The Python chapter
says Result types usually lose to exceptions there and explains why the same argument does not hold in
TypeScript.
Environment
| Version | |
|---|---|
| Python | 3.11.15 (all runnable Python works on 3.11; newer features are labelled by version in prose) |
| Node / V8 | 22.22.2 / 12.4 |
| TypeScript | 6.0.3, verified with tsc --strict --target es2022 --lib es2023 |
| Test suites | 70 node:test tests (68 pass, 1 skip, 1 todo) and 148 unittest tests, all green |
| Hardware | 2-core cloud container — treat absolute timings as indicative and the growth exponents as the point |
Facts that could have changed since training were checked against primary sources in August 2026:
Python 3.14 (PEP 779 free-threading, PEP 734 interpreters, PEP 750 t-strings, heapq max variants),
TypeScript 6.0/7.0 (the Go port), ES2025/ES2026 feature status plus a Node 22 feature-detection table,
V8’s TimSort, and the Python wiki’s TimeComplexity tables.
Sources
-
Python 3.14 release notes — free-threading, JIT,
heapqmax functions, GC changes -
Announcing TypeScript 7.0 Beta and TypeScript 6.0 ships as the final JS-based release
-
Getting things sorted in V8 and Stable Array.prototype.sort — TimSort, run detection, stability
-
Python wiki: TimeComplexity — the built-in complexity tables
-
ECMAScript 2026 feature list — cross-checked against runtime feature detection on Node 22
-
LeetCode 75 vs Blind 75 vs NeetCode 150 (2026) — list composition
-
What actually changed in tech interviews in 2026 — format shifts. Practitioner observation, not published data; flagged as such in 13 §1
-
Node.js test runner documentation — the feature/stability/version table in 16 §1, cross-checked against feature detection on Node 22. A secondary comparison article contradicted the official docs on two points; that disagreement is documented in 16 §17
-
Brett Slatkin, Effective Python, 3rd ed. (Addison-Wesley, 2025) and Dan Vanderkam, Effective TypeScript, 2nd ed. (O’Reilly, 2024) — cross-referenced Item by Item in 20 and 21. Those chapters are an index and a gap-closure companion, not a substitute: claims are restated in my own words and every Item is cited by number so you can read the original. Two of Vanderkam’s Items are now stale against TypeScript 6.0.3, verified by compiling them; one of Slatkin’s disagrees with this guide, settled by measurement rather than assertion
A note on keeping it
Guides rot. Two habits keep this one useful:
- Re-run the code. The scratch files that produced every test output and benchmark table are
reproducible; when you upgrade Python or Node, re-run them. Several conclusions in here are
version-specific (the
__slots__speed result, theLOAD_GLOBALresult, the Node 22 feature table) and will change. - Do the weekly loop. Study plan §4 — one blank-file drill, two mixed problems, one flashcard pass, one trap. Ninety minutes a week is enough to stop the erosion, which is a much better deal than another eight-week cram.
And the smallest habit with the biggest return, from that same section: when you accept a generated data structure, say why it is the right one and what its complexity is. Thirty seconds per acceptance, and it keeps the judgement attached to the typing.