Intro
The Hard Parts is a collection of certification-level questions designed to test real understanding of how software actually behaves at runtime.
These articles are not tutorials.
They are not syntax explanations.
They exist to expose the mental models that quietly break systems as they scale.
Each article starts with a short code snippet and a single question.
If you can answer it confidently, you’ve probably been burned by it before.
What This Category Is
- Language-agnostic over time (not limited to JavaScript or TypeScript)
- Focused on behavior, not style
- Grounded in real production failure modes
- Written from a senior engineer’s point of view
What This Category Is Not
- “Gotchas”
- Trick questions
- Interview brain teasers
- Academic theory
If a problem doesn’t cause real pain in real systems, it doesn’t belong here.
Javascript/Typescript Articles
Async, Await, and the Event Loop
- Why
async+forEachLies to You - What Actually Happens When
Promise.allFails - Why
try/catchDoesn’t Catch This Async Error - Why
awaitChanges Execution Order Even When Nothing Is Waiting - What Finishes First: the Function or the Async Work?
- Is Promise Order Guaranteed?
- Why This Async IIFE Doesn’t Do What You Think
- Why
setTimeout(fn, 0)Is Never Immediate - Why This Loop Logs the Same Value Three Times
- Where Does This Async Error Actually Go?
Concurrency, Coordination, and Failure
- Who Owns Completion When Nothing Is Awaited?
- What Survives a Failed
Promise.all? - What Happens to the Losing Promise in
Promise.race? - How Many Promises Exist in This
asyncFunction? - When Does a Rejection Become Unhandled?
- Why Mixing
then()andawaitBreaks Error Flow - When Parallelizing Async Work Is Incorrect
- Why This Error Crashes Production but Not Tests
- How Microtasks Can Starve the Event Loop
- Why “Single-Threaded” Is a Misleading Description
Closures, Scope, and Lifetime
- When Does This Closure Actually Get Released?
- Why
varandletBehave Differently in Loops - How Closures Quietly Create Memory Leaks
- Why This Closure Returns Stale Data
- When Variables Are Shared Across Iterations
- Why Moving Code Outside a Closure Fixes the Bug
- How Closures Hide Shared Mutable State
- Why Async Code Makes Closures Harder to Reason About
- What Exactly Is Captured in This Closure?
- Why “Just Put It in a Closure” Is Dangerous Advice
Objects, Identity, and Mutation
- Who Owns This Mutation?
- Why This Shallow Copy Fails
- Why Object Identity Matters More Than Shape
- How Two Callers Mutate the Same Object Without Knowing
- Why Immutability Is a Discipline, Not a Feature
- What Breaks When You Mutate Data You Didn’t Create
- Why This Mutation Makes Debugging Impossible
- What
===Is Actually Comparing Here - Why
Object.freezeIsn’t Enough - Why Copying Data Doesn’t Isolate Behavior
Type Systems and False Safety
- Where TypeScript Stops Protecting You
- Why Structural Typing Is Both Powerful and Dangerous
- How This Code Is Type-Correct but Logically Wrong
- Why Types Disappear at Runtime — and Why That Matters
- When Inference Actively Hides a Bug
- Why Widening Types Is Riskier Than
any - How This Assertion Breaks an Invariant
- Why
asTurns Into Technical Debt - Type Safety vs Behavioral Correctness
- Why Adding More Types Can Reduce Reliability
How to Read These Articles
Read them slowly.
Run the code mentally.
If your first answer is wrong, that’s the point.
These are the problems that don’t look hard — until they are.