Appearance
Blocking vs Non-Blocking I/O
Blocking I/O
Thread waits doing nothing until the operation completes.
Thread: ---- read() ---- (blocked, waiting) ---- data ready ---- continues- Simple to write.
- Thread is wasted while waiting.
- Bad for high concurrency — need one thread per connection.
Non-Blocking I/O
Thread doesn't wait — operation returns immediately, you check later.
Thread: -- read() -- "not ready yet" -- do other work -- check again -- data ready- More complex.
- Thread can do other work while waiting.
- Basis of high-concurrency servers.
The Problem Non-Blocking Solves
Blocking (10k connections):
Thread 1 -- waiting for client 1 --------------------------
Thread 2 -- waiting for client 2 --------------------------
...
Thread 10000 -- waiting ---------------------------------------
(10k threads = huge memory, context switching overhead)Non-Blocking (10k connections):
Thread 1 -- checks all 10k sockets, handles whoever is ready --
(1 thread handles everything)I/O Models (Important for Interviews)
| Model | How |
|---|---|
| Blocking I/O | Wait until done |
| Non-blocking I/O | Return immediately, poll manually |
| I/O Multiplexing | select() / epoll() — kernel tells you who's ready |
| Async I/O | Kernel does I/O, notifies you when complete (callback) |
select() vs epoll()
select()— checks all fds every time, O(n), limit of 1024 fds.epoll()— kernel tracks which fds are ready, O(1), no fd limit.- Used by Nginx, Node.js under the hood.
epoll flow:
epoll_create() → epoll_ctl(add fds) → epoll_wait() → returns only ready fdsSingle Thread
│
├── epoll watching 10k sockets
│
├── Socket 5 is ready → run callback
├── Socket 99 is ready → run callback
└── Socket 7 is ready → run callback
(Event Loop = non-blocking I/O + callbacks)How Node.js Uses This
Node.js is single-threaded but handles massive concurrency because it never blocks — always async I/O via libuv.
Sync vs Async vs Blocking vs Non-Blocking
| Blocking | Non-Blocking | |
|---|---|---|
| Sync | Wait, do nothing | Poll manually until ready |
| Async | (doesn't exist) | Kernel notifies via callback |
Most people say async = non-blocking but technically async means kernel handles it and calls you back.