Practise Concurrency & Multithreading one question at a time. Answer out loud or in writing, get graded, and see exactly what you missed.
What is the difference between concurrency and parallelism?
Concurrency means structuring a program so many tasks make progress in overlapping time windows. Parallelism means literally running tasks at the same instant on separate cores. A single-core machine can be concurrent but never truly parallel.
A concurrent design interleaves tasks by pausing one and resuming another. This helps when tasks wait on input, network, or disk. Parallelism helps when you have real compute to split across cores.
You can have either without the other. A single-threaded event loop is concurrent, not parallel. A numeric loop spread across eight cores is parallel. Most real systems mix both.
Reach for concurrency when tasks mostly wait, and parallelism when tasks mostly compute. Confusing them leads to adding cores that never help, or adding threads to work that has no waiting to overlap.
Missed:
“A race condition is when two threads access shared data at the same time and the result depends on which one gets there first. For example, if two threads both read a counter, add one and write it back, one of the increments can get lost. It's hard to reproduce because it only happens with a rare timing, and the thread scheduling changes from run to run depending on load and the machine.”
Knew itThey've got the core idea: shared data, timing-dependent outcome, lost increment example, and why rerunning doesn't reproduce it reliably. A real interview answer would add that you fix it with synchronization, not by chasing the one bad run.
Missed: Doesn't mention that the fix is reasoning about shared state and adding synchronization rather than trying to catch the exact crash
Get your own answers graded
Sign up free. Your account comes with 50 credits for grading, and it remembers what you missed.
What it covers
- Threads and concurrency basics
- Race conditions and thread safety
- Mutexes and lock types
- Condition variables and producer-consumer
- Deadlock, livelock and starvation
- Thread pools and work queues
- Async I/O and the event loop
- Memory visibility and ordering
- Atomics and lock-free algorithms
- Lock contention and scaling
- Debugging and testing concurrent code
All 54 questions
Threads and concurrency basics
How concurrency differs from parallelism, and what threads and context switches cost.
Race conditions and thread safety
What races and data races are, what makes code thread-safe, and how confinement and actors avoid shared state.
- What is a race condition and why is it so hard to reproduce?
- What does it mean for code to be thread-safe? Pro
- What is the difference between a data race and a race condition? Pro
- What are thread-local variables, and when would you use them? Pro
- What is the actor model, and when would you use it instead of locks? Pro
Mutexes and lock types
Mutexes, critical sections, semaphores, spinning versus blocking, and read-write and reentrant locks.
- What is a mutex and how does it stop a race condition?
- What is a critical section and why keep it as short as possible? Pro
- How do a semaphore and a mutex differ in purpose? Pro
- What is the difference between blocking and busy-waiting for a lock? Pro
- What is a read-write lock and when does it actually pay off? Pro
- How does a reentrant lock keep a thread from deadlocking itself? Pro
Condition variables and producer-consumer
Waiting efficiently on conditions, bounded buffers, and backpressure between producers and consumers.
Deadlock, livelock and starvation
Why threads get stuck or never progress, how lock ordering and fairness prevent it, and how to recover live.
- What is a deadlock and what four conditions must all hold?
- How does consistent lock ordering prevent deadlock? Pro
- What is livelock and how does it differ from deadlock? Pro
- What is starvation, and how does lock fairness reduce it? Pro
- How do you detect and recover from a deadlock in a live service? Pro
- How do you prevent priority inversion in a latency-sensitive system? Pro
Thread pools and work queues
Why pools reuse threads, how nested tasks can deadlock a pool, and what an unbounded work queue does.
Async I/O and the event loop
How a single-threaded event loop runs async work, when async beats threads, and blocking and cancellation pitfalls.
- How does the JavaScript event loop run async work on one thread?
- When should you reach for async I/O instead of a thread pool? Pro
- Why does async/await not speed up CPU-bound work? Pro
- What are the failure modes of code that blocks the event loop? Pro
- How do you cancel and clean up in-flight async work without leaks or races? Pro
Memory visibility and ordering
Why writes can stay invisible, what volatile and atomic flags guarantee, acquire-release ordering and safe publication.
- Why can one thread miss another thread's writes without synchronization? Pro
- What does a volatile or atomic flag guarantee, and what does it not? Pro
- How does double-checked locking break without a memory barrier? Pro
- How do acquire and release memory ordering keep a lock-free algorithm correct? Pro
- How would you make singleton initialization both safe and nearly lock-free? Pro
Atomics and lock-free algorithms
Atomic operations, compare-and-swap, the ABA problem, lock-free queues, memory reclamation and progress guarantees.
- What is an atomic operation and when is one enough? Pro
- How does compare-and-swap implement a lock-free counter? Pro
- How does the ABA problem defeat naive compare-and-swap, and how do you fix it? Pro
- How would you build a non-blocking queue that scales across many producers? Pro
- How do you safely reclaim memory in a lock-free data structure? Pro
- What is the difference between lock-free and wait-free algorithms? Pro
Lock contention and scaling
How contention, lock granularity, striping and false sharing limit throughput as threads and cores increase.
- How does lock contention limit throughput as thread count rises? Pro
- How does lock granularity trade contention against overhead? Pro
- How would you make a shared counter class thread-safe with minimal contention? Pro
- What is false sharing and how can it silently destroy parallel throughput? Pro
- What breaks in a lock-based cache at a million requests per second? Pro
- Why can adding more threads slow a program down, and where is the knee? Pro
- How would you shard or stripe a lock to cut contention safely? Pro
Debugging and testing concurrent code
Why races slip past tests, diagnosing ones that appear only under load, reviewing code for concurrency bugs, and stress-testing to expose rare interleavings.
- Why do race conditions hide in testing but surface in production? Pro
- How would you diagnose a race that appears only under production load? Pro
- How would you review unfamiliar code for concurrency bugs you cannot reproduce? Pro
- How would you stress-test concurrent code to surface rare interleavings? Pro
All questions
Showing of 54What is the difference between concurrency and parallelism?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
Concurrency means structuring a program so many tasks make progress in overlapping time windows. Parallelism means literally running tasks at the same instant on separate cores. A single-core machine can be concurrent but never truly parallel.
A concurrent design interleaves tasks by pausing one and resuming another. This helps when tasks wait on input, network, or disk. Parallelism helps when you have real compute to split across cores.
You can have either without the other. A single-threaded event loop is concurrent, not parallel. A numeric loop spread across eight cores is parallel. Most real systems mix both.
Reach for concurrency when tasks mostly wait, and parallelism when tasks mostly compute. Confusing them leads to adding cores that never help, or adding threads to work that has no waiting to overlap.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
What is a race condition and why is it so hard to reproduce?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
A race condition is a bug where the outcome depends on the timing of two or more threads. When they touch shared data and the order is not controlled, results vary from run to run.
Take two threads each reading a counter, adding one, and writing back. If both read the same value before either writes, one increment is lost. The count is wrong only for certain interleavings.
It is hard to reproduce because the bad interleaving is rare. Scheduling is nondeterministic and shifts with load, timing, and the machine. That is why rerunning does not debug a race. You fix it by reasoning about shared state and adding synchronization, not by hunting for the one crash.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
Why is creating threads expensive, and roughly how expensive?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
Creating a thread is expensive because each one needs its own stack and kernel bookkeeping. The operating system allocates memory, registers the thread with its scheduler, and sets up later cleanup.
The biggest cost is the stack. A default thread stack reserves from half a megabyte to eight, depending on the platform. Spawn thousands and you burn gigabytes of address space on stacks alone.
In wall-clock terms, creating and destroying a thread takes tens of microseconds. That dwarfs the microsecond-scale work you often hand it, so per-request spawning spends more on setup than on the task.
This is why servers reuse threads from a pool instead of making one per request. The cost is in the constant creation and teardown under load.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
What is a mutex and how does it stop a race condition?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
A mutex, short for mutual exclusion lock, is a gate that only one thread can hold at a time. A thread locks it before touching shared data and unlocks it when done. Others must wait.
By forcing threads to take turns, a mutex serializes access to a critical section. That is how it stops a race condition. No two threads read, modify, and write the same value at once, so the lost-update problem vanishes.
mutex.lock();
counter = counter + 1; // no other thread runs this line now
mutex.unlock();
A mutex trades some throughput for correctness. While one thread holds it, the others block and do nothing. Lock only the shared state, and always release the mutex, even when errors happen.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
What is a deadlock and what four conditions must all hold?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
A deadlock is a standstill where two or more threads each wait for a resource another holds. None can proceed, so all stay stuck forever. The program hangs without crashing.
All four Coffman conditions must hold at once:
- Mutual exclusion: only one thread can hold a resource.
- Hold and wait: a thread keeps what it has while waiting for more.
- No preemption: you cannot forcibly take a resource away.
- Circular wait: a cycle of threads each waits on the next.
Break any one and deadlock cannot form. The most common fix targets circular wait by making every thread acquire locks in the same order.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
What is a thread pool and why reuse threads instead of spawning?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
A thread pool is a fixed set of worker threads that pull tasks from a shared queue. You submit work, and an idle worker picks it up, runs it, then loops back for more. The workers live for the life of the program.
Reusing threads skips the cost of creating and destroying one per task. That setup, tens of microseconds each, adds up fast under load.
A pool also caps concurrency. You never launch ten thousand threads and exhaust memory or thrash the scheduler, because the queue absorbs bursts instead.
The tradeoff is sizing. Too few workers leave tasks waiting, and too many fight over cores. Use roughly the core count for compute, and more for I/O-bound work.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
How does the JavaScript event loop run async work on one thread?
Answer it yourself first - out loud, or typed below.
How should your speech become text?
Listening… your words appear above as you speak - tap Stop when you're done.
Recording · cr - tap Stop & transcribe when you're done.
Transcribing with AI…
Voice:
Last attempt -
The JavaScript event loop lets the system do the waiting for async work, then runs each callback on its one thread. It takes the next callback from a queue, runs it to completion, then grabs the next.
When you start a timer, network request, or file read, the runtime hands it to the system or a background pool. Your thread moves on right away.
When the operation finishes, its callback joins a queue. The loop runs it only after the current work returns and the stack is empty. So a ready callback still waits behind the running code.
This model avoids locks, since only one callback runs at a time. The catch is that any slow synchronous function freezes everything. One blocking loop stalls every pending timer, request, and click.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
What is a critical section and why keep it as short as possible?
How do a semaphore and a mutex differ in purpose?
What is a condition variable and what problem does it solve?
What is an atomic operation and when is one enough?
What is the producer-consumer problem and how is it solved?
What does it mean for code to be thread-safe?
Why do race conditions hide in testing but surface in production?
When should you reach for async I/O instead of a thread pool?
What is the difference between a data race and a race condition?
How does lock contention limit throughput as thread count rises?
What is the difference between blocking and busy-waiting for a lock?
How does consistent lock ordering prevent deadlock?
What is livelock and how does it differ from deadlock?
What is starvation, and how does lock fairness reduce it?
What is a read-write lock and when does it actually pay off?
How does compare-and-swap implement a lock-free counter?
Why can one thread miss another thread's writes without synchronization?
What does a volatile or atomic flag guarantee, and what does it not?
How does double-checked locking break without a memory barrier?
How does lock granularity trade contention against overhead?
How do you make a bounded buffer block when full or empty?
What does a thread context switch cost under heavy contention?
Why does async/await not speed up CPU-bound work?
How does a reentrant lock keep a thread from deadlocking itself?
What are thread-local variables, and when would you use them?
What is the actor model, and when would you use it instead of locks?
How would you make a shared counter class thread-safe with minimal contention?
What is false sharing and how can it silently destroy parallel throughput?
How does the ABA problem defeat naive compare-and-swap, and how do you fix it?
How would you design a thread pool that avoids deadlock on nested tasks?
How do you detect and recover from a deadlock in a live service?
How would you build a non-blocking queue that scales across many producers?
What breaks in a lock-based cache at a million requests per second?
How do acquire and release memory ordering keep a lock-free algorithm correct?
How would you diagnose a race that appears only under production load?
How do you add backpressure to a producer-consumer pipeline that outpaces consumers?
What goes wrong when a thread pool's work queue grows without bound?
How would you make singleton initialization both safe and nearly lock-free?
How do you prevent priority inversion in a latency-sensitive system?
Why can adding more threads slow a program down, and where is the knee?
How would you review unfamiliar code for concurrency bugs you cannot reproduce?
How would you shard or stripe a lock to cut contention safely?
How do you safely reclaim memory in a lock-free data structure?
What are the failure modes of code that blocks the event loop?
How do you cancel and clean up in-flight async work without leaks or races?
How would you stress-test concurrent code to surface rare interleavings?
What is the difference between lock-free and wait-free algorithms?
This answer is part of Pro.
The full written answer, with the trade-offs and follow-ups an interviewer will probe.
No matches
Try a different filter or search term.
Concurrency & Multithreading in pictures.
A quick recap of Concurrency & Multithreading in 31 short animated pictures, one idea at a time. About 8 min to get the whole topic back in your head before you walk in. Pause any picture, slow it down, or step through it.
Pro The first chapter is free to play. The other 27 pictures come with Pro.
Concurrency & Multithreading cheatsheet
- Races & shared state01
- Locks & critical sections02
- Deadlock & starvation03
- Waiting & signaling04
- Atomics & memory visibility05
- CAS & lock-free code06
- Thread pools & backpressure07
- Async & the event loop08
- Scaling under contention09
- Finding concurrency bugs10
- The model11
- + 5 more inside
This picture is part of Pro. The first chapter is free to play; the other 27 pictures come with Pro.
Get Pro · $10/mo Already Pro? Sign in47 of 54 Concurrency & Multithreading answers are in Pro.
Full answers, code samples, and AI explanations that go simpler or deeper. Cancel anytime.
- Full answers + code
- AI explanations, simpler or deeper
- 1,000 AI credits / month
- Cancel anytime
Change topic
Pick a different technology or stack. Your current topic stays put until you choose a new one.
MEAN
MongoDB, Express, Angular, Node.jsMERN
MongoDB, Express, React, Node.jsDjango
Python Full-Stack DevelopmentRuby on Rails
Convention over ConfigurationServerless on AWS
Serverless Architecture on AWSInterviewers also test these - they're common to every stack, whichever one you picked above.
Flutter Mobile
Flutter Cross-Platform Mobile DevelopmentInterviewers also test these - they're common to every stack, whichever one you picked above.
Spring Boot
Enterprise Java Development.NET
Microsoft EcosystemVue
Vue.js, Vite, TypeScript, Tailwind, Node.jsGo Backend
Golang, gRPC, PostgreSQL, Redis, RabbitMQInterviewers also test these - they're common to every stack, whichever one you picked above.
FastAPI
Python, FastAPI, SQLAlchemy, PostgreSQLReact Native
React, TypeScript, Redux, FirebaseiOS Native
Swift, SwiftUI, UIKit, FirebaseAndroid Native
Java, Jetpack Compose, FirebaseDevOps / Platform
Docker, Kubernetes, Terraform, CI/CDInterviewers also test these - they're common to every stack, whichever one you picked above.
AI Engineer
LLMs, RAG, Agents, EvalsAI-Powered Developer
Claude Code, Copilot, Agentic WorkflowsCore SWE Interview Prep
Data structures, algorithms, OS, concurrency, networking, gitInterviewers also test these - they're common to every stack, whichever one you picked above.
Interviewers also test these - they're common to every stack, whichever one you picked above.