Base CS from zero
Time and concurrency: multiple-choice review
Six questions that cut across the whole unit. Each one is a prediction or a decision you would make about a real running program — not a definition to recite, but the reasoning the lessons built toward, pushed one step further into where tasks share state.
Confirm you can connect the unit’s spine — why async exists, blocking vs non-blocking, the event loop’s one rule, and concurrency vs parallelism — and reason about what happens when interleaved or parallel tasks touch the same data.
A web server reads a file from disk on every request. Switching from a blocking read to a non-blocking one makes that disk read take how long, and what actually improves?
A program runs: console.log('A'); setTimeout(cb, 0) where cb prints 'B'; then console.log('C'). What does it print, and what is the underlying rule?
A program is structured as one task with one thread. You run it on a 16-core machine. How fast is it, and why?
A single-core machine interleaves 50 tasks with an event loop. How many run at the same instant, and is this concurrency or parallelism?
Two threads on two cores each run counter = counter + 1 a million times on one shared counter, with no synchronization. The final value is often far below two million. Why?
A team adds a lock so only one thread can run the counter-update at a time. The race disappears, but throughput drops on the 8-core machine. How should you read this?
The unit’s through-line is one idea taken to its edge: the CPU is fast and devices are slow, so programs use async — non-blocking calls plus callbacks — and an event loop that runs one callback at a time, only when the call stack is empty. That is concurrency: many tasks interleaved on one core, taking turns. Parallelism is different — tasks truly running at the same instant on multiple cores — and it only helps once the work is structured into tasks. The moment those tasks share state, a race condition becomes possible: a step like counter = counter + 1 is really read-add-write, and parallel threads can interleave to lose updates. A lock restores correctness by serialising the shared section — at the cost of the very parallelism it protects. Correctness first, then minimise what must be serial.