Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
The interleaved output of two unsynchronized printers is your first tangible proof that concurrent execution is non-deterministic. The same program produces different output on different runs — not because of bugs, but because the OS scheduler can context-switch between any two instructions. Once you see output like A 0 A 1 B 0 A 2 B 1 and understand that neither order is 'correct', you start to understand why shared mutable state needs explicit synchronization. This small program is a microcosm of the bigger problem: any time two tasks share state without coordination, the output depends on timing that neither your code nor your tests can predict.
Tabs below show the same program in Node.js, Go, Python, and Rust. Each spawns two tasks that print "A" and "B". Depending on the scheduler you'll sometimes see AB, sometimes BA, sometimes garbled output.
// main.js — two async tasks race to print
async function speak(label) {
for (let i = 0; i < 5; i++) {
console.log(label, i);
await new Promise((r) => setTimeout(r, 0));
}
}
await Promise.all([speak("A"), speak("B")]);node main.js