The problem with "I'll remember it"
Most engineers accumulate interview knowledge the same way: a scratch file here, a bookmarked article there, a half-finished LeetCode folder that gets abandoned after the job offer comes in. Six months later, when a recruiter schedules a system design round, it's all gone — rebuilt from scratch under time pressure.
I got tired of that cycle, so I built a repo for it. Not a gist, not a Notion doc — an actual git repository with the same rigor I'd apply to a production codebase: versioned files, a consistent naming convention, runnable code, and a structure that scales as I add more topics.
What's actually in it
The repo is organized as numbered, topic-scoped files rather than one giant notes dump. That numbering matters — it encodes a study order (fundamentals before frameworks, frameworks before infra) and makes it trivial to see what's covered at a glance:
01. JS.md 06. NodeJS.md
02-03. TS.md 07-08. Git.md
04. React.md 09-10. Docker.md
05. NextJS.md 11. ReactNative.md
DSA/ CLRS/
Two of these deserve more explanation because they're not just markdown:
DSA/ is a small, standalone Node package (its own package.json) with hand-written implementations of the structures that actually come up in interviews — linked lists, doubly linked lists, stacks, queues, trees, hash tables, graphs, heaps, a recursive/randomized BST, and the standard sort family (bubble, insertion, selection, merge, quick), plus a dynamic programming file. Every implementation is written to run standalone via node, with console.log walkthroughs at the bottom of the file rather than a test framework — the point isn't test coverage, it's being able to node "10. RBST.js" and watch the tree mutate step by step.
#deleteNode(value, currentNode) {
if (currentNode === null) return null;
if (value < currentNode.value) {
currentNode.left = this.#deleteNode(value, currentNode.left);
} else if (value > currentNode.value) {
currentNode.right = this.#deleteNode(value, currentNode.right);
} else {
if (currentNode.left === null && currentNode.right === null) return null;
else if (currentNode.left === null) currentNode = currentNode.right;
else if (currentNode.right === null) currentNode = currentNode.left;
else {
let subTreeMin = this.minValue(currentNode.right);
currentNode.value = subTreeMin;
currentNode.right = this.#deleteNode(subTreeMin, currentNode.right);
}
}
return currentNode;
}
That's BST node deletion with the three-case branch (leaf, one child, two children via in-order successor) — the kind of thing that's easy to explain and surprisingly easy to get subtly wrong under interview pressure if you haven't typed it out recently.
The second file worth calling out is DSA/index.js. It's a mirror of every class and function in the package — same signatures, same private methods, all with empty bodies:
class RBST {
constructor() {}
#rinsert(value, currentNode = this.root) {}
rInsert(value) {}
#deleteNode(value, currentNode) {}
deleteNode(value) {}
BFS() {}
DFSPreOrder() {}
DFSInOrder() {}
DFSPostOrder() {}
}
This is deliberate: it's a self-quiz. When I want to check whether I actually retained an implementation rather than just having read it once, I open index.js and fill in the blanks from memory, then diff my attempt against the real file. It's the same principle as closed-book practice exams — recognition isn't recall, and this file forces recall.
CLRS/ is a chapter-by-chapter set of notes following Introduction to Algorithms — from "The Role of Algorithms in Computing" through Red-Black Trees, Dynamic Programming, Graph Algorithms, NP-Completeness, and Approximation Algorithms. It's the theoretical backbone underneath the DSA/ implementations: the CLRS notes cover why an algorithm has a given complexity; the DSA folder is how it's actually coded in JavaScript.
Design decisions that weren't accidental
A few choices in how this repo is structured are worth calling out, because they generalize beyond interview prep:
| Decision | Why |
|---|---|
Numbered filenames (01., 02., …) | Encodes study order without needing a separate index; sorts correctly in any file explorer or ls |
Split TS across two files (02. and 03.) | Basic vs. advanced type-system topics don't belong in the same reading pass |
DSA/ is its own npm package | Keeps runnable code isolated from prose notes — no risk of a require reaching into unrelated markdown |
Tables for feature comparisons (var/let/const, scope/hoisting/reassignment) | A table answers "which one do I use" in one glance; prose buries the answer in a paragraph |
Empty-body mirror file (index.js) | Converts a reference doc into an active recall tool, for free, with zero extra tooling |
None of this required a framework, a static site generator, or tooling of any kind — it's git, markdown, and Node, used with intent. That's the point: good structure doesn't need heavy infrastructure, it needs a consistent convention applied without exception.
Takeaway
This repo isn't a product, but it's a good proxy for how I approach any codebase: impose structure early, make the "how do I verify this" question answerable without re-deriving it from scratch, and prefer boring, durable tools (plain files, git history, a numbering scheme) over anything that adds ceremony without adding clarity. The same instinct — organize first, automate the boring parts, keep everything diffable — is what shows up in the production systems I build for clients.