multiprogramming
Multiprogramming is the foundational idea of keeping several programs loaded in memory at once so the CPU always has something to do. The problem it solves is waste. A single program spends a surprising amount of its life waiting — for the disk to deliver data, for the network, for a key to be pressed. If the computer ran one program at a time start to finish, the expensive CPU would sit idle during every one of those waits. Picture a chef who, while one dish simmers, starts chopping for the next instead of standing and watching the pot. Multiprogramming keeps the kitchen busy.
Here is the mechanism in plain steps. Several programs (jobs) are held in memory together. The CPU runs one of them. The moment that program has to wait for something slow — say it issues a disk read — the OS does not idle the CPU; it switches the CPU to a different program that is ready to run, and lets the disk fetch in the background. When the first program's data finally arrives, it becomes ready again and will get the CPU back later. By always having a ready program to switch to, the OS keeps the CPU productive almost all the time, raising the machine's overall throughput dramatically.
Multiprogramming was the historic leap that made computers efficient, and it is the parent idea behind everything that follows: because multiple programs share memory and the CPU, the OS suddenly needs scheduling (who runs next), memory management (keeping programs apart), and protection (one program must not corrupt another). The honest distinction worth fixing early: multiprogramming is about utilization (never let the CPU idle while work waits), and it does not by itself promise that any one program responds quickly to you. Making the system feel responsive to interactive users is a further step — time-sharing — built on top of multiprogramming.
Program A asks to read a file and must wait roughly 8 ms for the disk. Instead of idling for those 8 ms, the OS runs program B, which is ready. When A's data arrives, A rejoins the ready set. The CPU stayed busy the whole time instead of waiting on slow hardware.
While one program waits on slow I/O, another uses the CPU — no idle time.
Multiprogramming maximizes CPU utilization; it does not by itself guarantee fast response to any single user. Quick, interactive turn-taking is the additional goal of time-sharing built on top of it.