os-interview-manual §00 Start here
Interview Manual · Built from your CS F372 deck (491 slides) + standard interview surface

Operating Systems,
samjho ek baar mein.

Zero se shuru. Har concept pehle plain English mein, phir Hinglish mein "asli baat kya hai", phir example, phir woh questions jo interview mein actually poochhe jaate hain — full solutions ke saath.

21 sections90+ solved questionsAll numericals worked outHamming code included
00

Start here

Padhne se pehle 2 minute ye padh lo — poora page kaise use karna hai.

Page kaise structured hai

  • Plain explanation — normal technical English, jaisa book mein hota hai.
  • HINGLISH block — wahi cheez apni bhasha mein, analogy ke saath. Ye woh version hai jo interview mein bolna hai.
  • Boxes — ASKED A LOT matlab ye interview mein baar-baar aata hai. COMMON matlab decent chance. RARE matlab depth ke liye.
  • Q boxes — question upar, solution collapsed. Pehle khud try karo, phir kholo.
THE 12 TOPICS THAT COVER ~85% OF OS INTERVIEWS
  1. Process vs thread, aur process memory layout
  2. fork(), zombie, orphan
  3. Context switch — kya save hota hai, cost kya hai
  4. Scheduling algorithms + Gantt chart numericals
  5. Race condition & critical section ke 3 conditions
  6. Mutex vs semaphore vs binary semaphore
  7. Producer–consumer + deadlock in it
  8. Deadlock ke 4 conditions + Banker's algorithm
  9. Paging, page table, TLB, EAT calculation
  10. Page replacement (LRU/FIFO/Optimal) + Belady's anomaly
  11. Thrashing
  12. Disk scheduling head movement numericals

Interview mein OS kaise poochha jaata hai? Do style hote hain:

Style 1 — Concept: "Deadlock kya hota hai?" Yahan definition + 4 conditions + ek real example chahiye. 60–90 seconds ka answer.

Style 2 — Numerical: "Ye reference string hai, 3 frames, LRU se page faults nikalo." Yahan table banao, step by step. Ye written round/OA mein zyada aata hai.

Dono ke liye alag prep chahiye. Is page mein dono hai — concept explanation ke baad hamesha numericals honge.

Ek mental model jo poore OS ko jodta hai

OS ke paas 4 cheezein hain jo limited hain, aur bahut saare programs unhe ek saath maangte hain:

ResourceKaun manage karta haiCore problemSection
CPU (time)SchedulerKisko kab aur kitni der do?§06
Memory (space)MMU + memory managerSabko lagе poori RAM meri hai§0B–§0D
Disk / I/OI/O subsystemSlow device, fast CPU — sync kaise?§0E
Shared dataSync primitivesDo log ek hi cheez chhuein toh corruption§07–§0A

Har OS chapter isi table ka ek row hai. Jab bhi confuse ho, wapas yahin aao — "abhi main kis resource ki baat kar raha hoon, aur uska conflict kya hai?"

01

What an OS actually is

Definition, goals, aur woh do views jo har viva mein poochhe jaate hain.

DEFINITION

An operating system is a program that acts as an intermediary between the user of a computer and the computer hardware. It is a resource allocator (manages CPU, memory, I/O and decides between conflicting requests) and a control program (controls execution of programs to prevent errors and improper use).

There is no universally accepted definition. The one line that always works: "the one program running at all times on the computer is the kernel; everything else is either a system program or an application program."

Socho ek building ka manager. Building = hardware. Tenants = programs. Manager khud koi kaam nahi karta — na paani banata hai, na bijli. Woh sirf ye decide karta hai: kisko kitna paani milega, kaun kis floor pe rahega, aur agar do tenants ek hi parking spot maang rahe hain toh kaun jeetega.

OS bilkul yahi hai. Woh khud calculation nahi karta — CPU karta hai. Woh khud data store nahi karta — disk karti hai. OS sirf allocate karta hai aur protect karta hai.

Do kaam yaad rakho: (1) Convenience — user ko easy lage (2) Efficiency — hardware waste na ho. Aur maza ye hai ki ye dono ek dusre ke against hain. Zyada convenience doge (fancy GUI, abstractions) toh efficiency girti hai. Yahi tension poore OS design mein hai.

Kernel vs OS ASKED A LOT

KernelOperating System
Kya haiCore program, memory mein hamesha loadedKernel + system programs + utilities + UI
ModeKernel mode mein chalta haiKuch parts user mode mein bhi
ExampleLinux kernelUbuntu, Fedora (kernel + shell + libs + GUI)
ScopeOS ka subsetSuperset

One-liner: "Kernel OS ka dil hai, OS poora sharir hai." Linux technically ek kernel hai; Ubuntu ek OS hai. Interviewer isi galti ko pakadta hai.

User view vs System view

  • User view — ease of use, performance of my program. Resource utilization ki koi parwah nahi. (Desktop/mobile user)
  • System view — OS = resource allocator. Fairness, throughput, utilization matter karta hai. (Mainframe/server)

Embedded systems (washing machine, car ECU) mein user view almost zero hota hai — koi UI hi nahi. Wahan OS sirf resource manager hai. Isliye ye do views alag-alag OS designs ko justify karte hain.

Kernel architectures COMMON

TypeIdeaProsConsExample
MonolithicSab kuch (FS, drivers, scheduler, IPC) ek hi kernel address space meinFast — sab function calls hainEk driver crash = poora system down; huge codeLinux, Unix
MicrokernelKernel mein sirf minimum (IPC, scheduling, basic memory). Baaki user space mein serversReliable, extensible, secureSlow — har cheez message passing seMinix, QNX, L4
HybridMicrokernel design par performance-critical parts kernel meinBalanceComplexityWindows NT, macOS (XNU)
ExokernelKernel sirf hardware ko securely multiplex karta hai; abstraction app decide kareApp-level optimizationResearch-stage, hard to programMIT Exokernel

Microkernel ka trade-off ek line mein: monolithic mein file read karna ek function call hai; microkernel mein wahi read ek message hai jo user→kernel→FS server→kernel→user jaata hai. Char mode switches vs zero. Isliye slow, par reliable — FS server crash ho toh restart kar do, kernel zinda rahega.

Q 1.1

Is Linux a monolithic kernel or a modular one? Explain the apparent contradiction.

Show solution

Both — and that's the point. Linux is architecturally monolithic: the file system, device drivers, network stack and scheduler all run in a single kernel address space, and they call each other as ordinary function calls.

But Linux also supports loadable kernel modules (LKMs). A driver can be compiled separately and inserted at runtime with insmod / modprobe, and removed with rmmod. So the kernel is modular in how it is built and loaded, but monolithic in how it executes — a loaded module runs in kernel space with full privileges, so a bug in it can still panic the system.

Yaad rakhne ka tareeka: module load karna matlab code ko kernel ke ghar ke andar bulana. Aane-jaane ka darwaza flexible hai (modular), par ek baar andar aa gaya toh usko poore ghar ka access hai (monolithic).

02

System types & evolution

Batch se lekar real-time tak. Ye section chhota rakho par multiprogramming vs multitasking pakka aata hai.

The evolution, in one flow

Serial processing → Batch → Batch + spooling → Multiprogramming → Time sharing → Personal / Distributed / Real-time no OS at all jobs overlap I/O of many jobs in RAM, multiprogramming operator loads grouped one job with CPU switches on + a time slice tapes by hand by hand compute of next I/O wait per user

Batch systems

Similar jobs are batched together and run without user interaction. The resident monitor loads one job, runs it, loads the next. Control cards (JCL) tell the monitor what to do.

  • Problem: CPU idle rehta hai jab job I/O kar raha ho. Utilization terrible.
  • Spooling (Simultaneous Peripheral Operation On-Line) — disk ko buffer ki tarah use karo. Jab job A print kar raha ho, CPU job B chala sake. Ye job pool banata hai on disk.

Spooling ka asli fayda: disk pe ab ek pool of ready jobs ban gaya. Pehle jobs tape pe sequentially padi thi — jo pehle aayi wahi chalegi. Ab disk se OS koi bhi job uthha sakta hai. Yahi se job scheduling ka concept paida hua. Interviewer poochhta hai "spooling se kya mila?" — sirf "buffering" mat bolna, bolo "job pool aur isliye scheduling ka choice".

Multiprogramming vs Multitasking vs Multiprocessing vs Multithreading ASKED A LOT

TermKya hota haiSwitch kab hota haiCPUs
MultiprogrammingMultiple jobs RAM mein; CPU idle na raheJab current job I/O ke liye block ho1
Multitasking / Time sharingMultiprogramming + har job ko chhota time sliceI/O par ya time quantum khatam hone par1
MultiprocessingEk system mein multiple CPUs/cores—>1
MultithreadingEk process ke andar multiple threadsThread scheduler ke hisaab se1 ya >1

Ek line ka difference (yahi bolna interview mein):

Multiprogramming ka goal hai CPU utilization — CPU khali na baithe. Multitasking ka goal hai response time — user ko lage ki uska program abhi chal raha hai.

Multiprogramming mein agar ek job 10 minute tak CPU-bound calculation kar raha hai, toh baaki sab 10 minute wait karenge — aur ye "theek" hai, kyunki CPU toh busy hai. Time sharing mein ye acceptable nahi — 20ms baad usko force se hatao.

Other system types

Symmetric multiprocessing (SMP)

Har processor identical, sab par same OS copy chalti hai, shared memory. Aaj ke sab multicore systems.

Asymmetric multiprocessing

Ek master processor kaam baantta hai, baaki slaves. Simpler par master bottleneck.

Distributed system

Alag-alag machines, apni-apni memory, network se jude. Resource sharing, computation speedup, reliability.

Clustered system

Multiple machines mil kar ek service dete hain, shared storage. Asymmetric (hot standby) ya symmetric (sab active).

Real-time systems COMMON

Correctness depends not only on the logical result but on the time at which the result is produced. A late answer is a wrong answer.

Hard real-timeSoft real-time
Deadline missSystem failure / catastropheQuality degrades, system survives
Virtual memoryUsually not allowed (page fault = unpredictable delay)Allowed
Secondary storageMinimal / ROM onlyNormal
ExampleAirbag controller, pacemaker, missile guidanceVideo streaming, VoIP, gaming
TRAP

"Real-time = fast" — galat. Real-time means predictable, not fast. Ek system jo hamesha exactly 50ms leta hai woh real-time hai. Ek system jo usually 1ms leta hai par kabhi-kabhi 200ms — woh real-time nahi hai, chahe average fast ho. Determinism > speed.

03

Hardware, interrupts & system calls

Ye section poore OS ki neev hai. Interrupt vs trap vs system call almost guaranteed question hai.

How a computer actually runs a program

The fetch–decode–execute cycle: the CPU fetches the instruction at the address in the program counter (PC), decodes it, executes it, and increments the PC. That's the whole loop, forever.

FUNDAMENTAL RULE

A program can execute only if it is loaded in main memory. The CPU can only fetch instructions from memory (via cache/registers) — it can never execute directly from disk. This one rule is why swapping, paging, and virtual memory all exist.

Interrupt vs Trap/Exception vs System call ASKED A LOT

InterruptTrap / ExceptionSystem call
SourceHardware, external deviceSoftware, error conditionSoftware, deliberate request
TimingAsynchronous — kabhi bhiSynchronous — specific instruction parSynchronous
Intentional?Not by the programNo — it's a bug/conditionYes — program chaahta hai
ExampleKeyboard press, disk done, timerDivide by zero, invalid memory access, page faultread(), fork(), open()
Handled byInterrupt Service Routine (ISR)Exception handlerKernel system-call handler

Sabse easy tareeka yaad rakhne ka — ghar ka scene:

Interrupt = doorbell. Bahar se koi aaya. Aapne nahi bulaya, kabhi bhi baj sakti hai. Aap jo kar rahe the woh rok kar darwaza kholte ho, phir wapas wahi kaam.

Trap/Exception = khaana banate waqt haath jal gaya. Aapki hi galti se, aapke hi kaam ke dauraan, exactly us moment par. Predictable in the sense ki wahi instruction dobara chalao toh phir hoga.

System call = aapne khud helpline pe call kiya. Jaan-boojh kar, kyunki jo kaam chahiye woh aap khud nahi kar sakte (privileged hai).

Ek aur crucial baat: teeno ka mechanism same hai — CPU mode switch karta hai, current state save karta hai, vector table se handler ka address uthhata hai, handler chalata hai, wapas aata hai. Sirf trigger alag hai. Ye bolne se interviewer impress hota hai.

Interrupt handling — exact steps

  1. Device controller raises the interrupt line.
  2. CPU finishes the current instruction (not the whole program), then checks the interrupt line.
  3. CPU saves the current state — PC and registers — onto the kernel stack.
  4. CPU switches to kernel mode.
  5. Interrupt number indexes into the interrupt vector table to get the ISR address.
  6. ISR runs, servicing the device.
  7. State restored, mode switched back, execution resumes at the saved PC.
WHY A VECTOR TABLE?

Without it, the handler would have to poll every device to ask "did you interrupt?" — O(n). The vector table gives O(1) dispatch: interrupt number → handler address directly. It lives at a fixed low memory location.

Three ways to do I/O COMMON

MethodHowCPU costBest for
Programmed I/O (polling)CPU busy-waits, repeatedly checking status register100% wasted while waitingVery fast devices, tiny transfers
Interrupt-driven I/OCPU issues request, does other work, device interrupts when readyOne interrupt per byte/wordSlow devices, small data (keyboard)
DMADMA controller moves data device↔memory directly; one interrupt per blockMinimal — one interrupt per blockHigh-speed bulk transfer (disk, network)

DMA ko samjho ek courier service ki tarah. Polling matlab aap khud har 2 minute mein gate pe jaa kar dekh rahe ho parcel aaya kya. Interrupt matlab courier ghanti bajayega — par har ek packet ke liye alag ghanti. DMA matlab aapne courier ko keh diya "poora carton seedha store room mein rakh do, sab khatam hone par ek baar bata dena". CPU sirf start aur end pe involve hota hai.

Cycle stealing — DMA controller memory bus ko CPU se chhota-chhota "chura" kar use karta hai. CPU thoda slow hota hai, par interrupt overhead se bahut kam.

Dual-mode operation & protection ASKED A LOT

Hardware provides a mode bit: 0 = kernel/monitor/supervisor mode, 1 = user mode. Certain instructions are privileged and can execute only in kernel mode.

Protection typeMechanism
I/O protectionAll I/O instructions are privileged. A user program must make a system call.
Memory protectionBase register (smallest legal physical address) + limit register (size of range). Hardware checks every address: valid iff base ≤ addr < base + limit. Loading base/limit is privileged.
CPU protectionTimer interrupts after a set period so no program can hog the CPU forever. Setting the timer is privileged.
Address generated by CPU │ ▼ ┌───────────┐ no ┌──────────────┐ │ addr ≥ base? ├────────▶│ TRAP to OS │ └─────┬─────┘ │ (addressing │ yes│ │ error) │ ▼ └──────────────┘ ┌────────────────────┐ no │ addr < base+limit? ├────────▶ same trap └─────────┬──────────┘ yes│ ▼ access memory

Base + limit register ka poora point ye hai ki check hardware karta hai, har single memory access par, zero extra time mein (parallel comparator circuit). Agar OS software mein check karta toh har instruction 10x slow ho jaati. Protection hamesha hardware + OS ka joint effort hota hai — ye line interview mein bolne layak hai.

System calls — the user→kernel doorway

Categories: process control (fork, exec, exit, wait), file management (open, read, write, close), device management (ioctl, read, write), information maintenance (getpid, time), communication (pipe, shmget, send, recv), protection (chmod, umask).

What actually happens on a system call

  1. Program calls a wrapper in the C library, e.g. read().
  2. Wrapper puts the system call number in a register (e.g. eax/rax) and arguments in other registers.
  3. Executes a trap instruction (syscall / int 0x80 / svc).
  4. CPU switches to kernel mode, jumps to the system-call handler.
  5. Handler looks up the number in the system call table, runs the kernel routine.
  6. Return value goes into a register; mode switches back to user.
TRAP — CLASSIC CONFUSION

Mode switch ≠ context switch. A system call causes a mode switch (user→kernel and back) but the same process keeps running — no PCB save/restore of another process, no scheduler involvement. A context switch means the CPU actually moves to a different process. Mode switch is cheap (~100s of ns); context switch is expensive (µs, plus cache/TLB pollution). Interviewers love this one.

Storage hierarchy & caching

LevelTypical sizeAccess timeManaged by
Registers~KB< 1 nsCompiler
L1 / L2 / L3 cacheKB – tens of MB1–20 nsHardware
Main memory (RAM)GB~50–100 nsOS
SSDhundreds of GB~50–100 µsOS
Magnetic diskTB~5–10 msOS
TapeTB+secondsOS / operator

Neeche jaate jaate: size badhta hai, cost/bit girti hai, speed girti hai. Ye teeno hamesha saath chalte hain.

Caching ka principle: jo abhi use kiya hai woh dobara chahiye hoga (temporal locality), aur jo uske paas hai woh bhi chahiye hoga (spatial locality). Isliye faster level pe copy rakh lo.

Cache coherency ka problem — same data ke multiple copies (register, cache, RAM, disk). Multiprocessor mein agar CPU-1 apne cache mein A=5 kar de aur CPU-2 ke cache mein A=3 pada ho, toh kaand. Isliye hardware cache-coherence protocols (MESI) chahiye.

Q 3.1

A page fault is triggered by a program's own memory reference. So is it an interrupt, a trap, or a system call? And how is it different from a divide-by-zero?

Show solution

A page fault is a trap (exception) — synchronous, generated by the MMU during the execution of a specific instruction, not by an external device.

The interesting difference from divide-by-zero is what happens after:

  • Divide by zero — a fault the program cannot recover from by default. The OS typically sends SIGFPE and the process dies.
  • Page fault — a recoverable fault. The OS brings the page in from disk, updates the page table, and then re-executes the very same instruction, which now succeeds. The program never knows it happened.

This restartability is the whole reason virtual memory works, and it puts a real constraint on CPU design: the instruction must be re-executable from the beginning without side effects. Instructions that modify memory before faulting (e.g. a block-move that half-completes) need special hardware handling.

Short answer bolne ke liye: "Page fault ek trap hai, par ek recoverable trap. OS page laata hai aur wahi instruction dobara chalata hai — isliye program ko pata bhi nahi chalta."

Q 3.2

Why can't a user program just execute I/O instructions directly? It would be faster.

Show solution

Three reasons, in order of importance:

  1. Protection. Direct disk access means any program could read or overwrite any other user's files, or the OS itself. All isolation collapses.
  2. Correctness under sharing. Devices are shared. If two processes issue overlapping disk commands with no arbiter, the device gets contradictory instructions and data is corrupted. The OS serialises and queues requests.
  3. Abstraction. Direct I/O means the program must know the exact controller registers of that specific hardware. Change the disk model and every program breaks. The system-call interface makes read() work on any device.

The enforcement mechanism: I/O instructions are marked privileged, so attempting one in user mode traps to the OS.

04

Processes & the PCB

OS ka sabse core abstraction. Memory layout aur fork() questions almost har interview mein hain.

Program vs Process ASKED A LOT

ProgramProcess
Passive entity — a file on diskActive entity — program in execution
No program counter, no stateHas PC, registers, stack, heap, state
Exists forever until deletedLives only while executing
One copyOne program → many processes

Recipe vs cooking. Recipe book mein likhi hui recipe = program. Woh bas padi hui hai, kuch nahi kar rahi. Jab aap kitchen mein khade ho kar us recipe ko follow kar rahe ho — gas on hai, kadhai garam hai, aap step 4 pe ho — woh process hai.

Aur dhyan do: ek hi recipe se do log ek saath alag-alag kitchen mein khaana bana sakte hain. Dono ka step number alag hoga, dono ke ingredients alag honge. Same program, do processes. Isliye Chrome ke 10 tabs = ek program, 10 processes.

Process memory layout ASKED A LOT

high address ┌────────────────────────┐ │ command-line args, │ │ environment variables │ ├────────────────────────┤ │ STACK │ local variables, function parameters, │ │ │ return addresses, saved registers │ ▼ │ grows DOWNWARD │ │ │ (free space) │ ← stack and heap grow toward each other │ │ │ ▲ │ │ │ │ grows UPWARD │ HEAP │ malloc / new — dynamic allocation ├────────────────────────┤ │ BSS (uninitialised) │ int x; static int y; → zero-filled at load ├────────────────────────┤ │ DATA (initialised) │ int x = 5; global/static with a value ├────────────────────────┤ │ TEXT / CODE │ the machine instructions — read-only, shareable └────────────────────────┘ low address

Neeche se upar yaad karo: Text → Data → BSS → Heap → (gap) → Stack.

Text read-only kyun? Do reasons — (1) accidentally apna hi code overwrite na ho, (2) same program ki 10 copies chal rahi hain toh text ki ek hi physical copy RAM mein rakho, sab share karein. Memory bachi.

Data vs BSS ka farq: int x = 5; ki value executable file mein likhi hoti hai (Data). int y; ki koi value likhne ki zaroorat nahi — bas "mujhe 4 bytes chahiye, zero se bhare hue" (BSS). Isliye ek bada uninitialised array executable ka size nahi badhata. Ye ek badhiya follow-up answer hai.

Stack neeche ki taraf kyun badhta hai? Taaki stack aur heap ek dusre ki taraf badhein aur beech ka free space dono share kar sakein. Agar dono upar badhte toh beech mein fixed boundary banani padti aur ek side ki memory waste hoti.

Stack overflow = stack itna neeche aa gaya ki heap se takra gaya (infinite recursion). Heap ke saath memory leak hoti hai — malloc kiya, free nahi kiya.

FOLLOW-UP THEY WILL ASK

"Threads mein kya share hota hai?" — Text, Data, BSS, Heap, and open files are shared. Each thread gets its own stack and its own registers/PC. Yahi ek line poore thread chapter ka nichod hai.

Process Control Block (PCB) / process image

The PCB is the data structure the OS keeps for every process. Contents fall into three groups:

GroupContents
Process identificationPID, parent PID (PPID), user ID
Processor state informationGeneral-purpose registers, program counter, stack pointer, condition codes / PSW
Process control informationProcess state, scheduling priority, pointers to memory (base/limit or page table), list of open files, accounting info, IPC info, pointers to other PCBs

PCB ko socho process ka Aadhaar card + medical file + bank passbook ek jagah. Jab process ko CPU se hatana ho, uski poori "zindagi" PCB mein likh do; jab wapas laana ho, PCB se padh kar registers restore kar do. Context switch ka matlab hi PCB save + PCB load hai.

Process states ASKED A LOT

Five-state model

admitted dispatch exit ┌─────┐ create ┌───────┐ ───────────▶ ┌─────────┐ ────────▶ ┌────────────┐ │ NEW │ ────────▶│ READY │ │ RUNNING │ │ TERMINATED │ └─────┘ └───────┘ ◀─────────── └─────────┘ └────────────┘ ▲ interrupt / │ │ quantum expiry │ I/O or event wait I/O done │ ▼ ┌──────────┐ (blocks) │ WAITING │◀──────────────────┘ │(BLOCKED) │ └──────────┘
TransitionTriggerPreemptive only?
New → ReadyAdmitted by long-term scheduler (memory available)No
Ready → RunningDispatched by short-term schedulerNo
Running → ReadyTimer interrupt / higher-priority process arrivesYes — only in preemptive systems
Running → WaitingProcess requests I/O or waits for an eventNo
Waiting → ReadyI/O completes, event occursNo
Running → Terminatedexit() or killedNo
TRAP

There is no Waiting → Running transition. Ever. When I/O finishes, the process goes to Ready and must be scheduled again. Interviewers deliberately draw this wrong arrow to see if you catch it. Similarly there is no Ready → Waiting.

New state kyun chahiye? Process create ho chuka hai (PCB ban gaya) par abhi memory mein load nahi hua. OS ne abhi "admit" nahi kiya. Ye long-term scheduler ko control deta hai ki multiprogramming degree kitni rakhni hai. Agar RAM full hai toh naye process New mein wait karenge.

Suspended states (7-state model)

When memory runs short, the OS swaps a process out to disk. That gives two extra states:

  • Ready/Suspend — in secondary memory, but ready to run once brought back.
  • Blocked/Suspend — in secondary memory and also waiting for an event.

Key transition: Blocked/Suspend → Ready/Suspend happens when the awaited event occurs while the process is still swapped out. The medium-term scheduler handles swapping.

Zombie and orphan processes ASKED A LOT

ZombieOrphan
Who diedChild diedParent died
SituationChild called exit(), parent hasn't called wait() yetParent terminated while child still running
What remainsOnly the PCB entry (exit status). All memory freed.A live, fully functional process
ResolutionParent calls wait() → entry reaped. If parent never does, init reaps it when the parent dies.Re-parented to init (PID 1), which will wait() on it
Harmful?Yes if many — PID table exhaustionNo — normal, this is how daemons are made

Zombie = bachcha mar gaya, par uska death certificate abhi tak koi lene nahi aaya. Body toh gayab ho gayi (memory free), par record book mein entry padi hai. Parent jab wait() karega tab entry hategi.

Orphan = maa-baap chal base, bachcha zinda hai. Ab init (PID 1) usko adopt kar leta hai. Ye bura nahi hai — daemons isi tareeke se banaye jaate hain: fork karo, parent ko turant exit kara do, child orphan ho kar init ke neeche background mein chalta rahe.

Zombie ko "kill" nahi kar sakte — woh already dead hai. kill -9 ka koi asar nahi. Solution: parent ko kill karo, phir init reap kar lega. Ye ek favourite trick question hai.

fork(), exec(), wait(), exit()

CallWhat it doesReturns
fork()Creates a near-identical copy of the calling process0 in the child, child's PID in the parent, -1 on failure
exec()Replaces the current process image with a new program. Same PID.Nothing on success (never returns), -1 on failure
wait()Parent blocks until a child terminates; reaps the zombiePID of the terminated child
exit()Terminates process, frees resources, keeps exit status for parentDoes not return

fork + exec ka combo hi Unix ka poora philosophy hai. Shell mein jab aap ls type karte ho: shell fork() karta hai (apni copy banata hai), phir child mein exec("ls") karta hai (copy ko ls se replace kar deta hai), aur parent wait() karta hai.

Do alag calls kyun, ek "spawn" kyun nahi? Kyunki fork ke baad aur exec ke pehle ek window milti hai jismein child apna environment set kar sakta hai — file descriptors redirect karo, permissions drop karo. Yahi window hai jo ls > out.txt ko possible banati hai. Ye answer interviewer ko bahut pasand aata hai.

Copy-on-write: fork poori memory copy nahi karta. Parent aur child same physical pages share karte hain, sab read-only mark karke. Jab koi likhne ki koshish kare tab hi us page ki copy banti hai. Isliye fork+exec fast hai — exec toh sab replace hi kar dega, copy karna waste tha.

Q 4.1

How many processes are created (including the original) by the following, and how many times does printf execute?

int main() {
    fork();
    fork();
    fork();
    printf("hello");
}
Show solution

8 total processes (1 original + 7 new), and printf executes 8 times.

Reasoning. Each fork() doubles the number of running processes, because both parent and child continue from the instruction after the fork.

start: P after fork #1: P C1 → 2 after fork #2: P C1 C2 C1a → 4 after fork #3: P C1 C2 C1a C3 C1b C2a C1a' → 8
Rule: n consecutive forks → 2ⁿ total processes, 2ⁿ − 1 new children.

Here n = 3, so 2³ = 8 processes, 7 children. All 8 reach the printf.

VARIATION THEY ASK NEXT

If it were fork(); fork(); fork(); but printf came between the second and third fork, only 4 processes exist at that point, so it prints 4 times. Position matters. Also: printf to a pipe/file is block-buffered, so the buffer itself gets copied by fork and output can appear duplicated — this is why you use fflush() or write() in such puzzles.

Q 4.2

What does this print, and how many processes are created?

int main() {
    if (fork() && fork())
        fork();
    printf("X");
}
Show solution

4 processes total, so X is printed 4 times.

Two facts do all the work here: fork() returns non-zero (true) in the parent and 0 (false) in the child, and && short-circuits — if the left side is false, the right side never executes.

P : fork()#1 ─────▶ C1 processes: P, C1 C1 → left operand is 0 → false → short-circuits. fork()#2 NEVER RUNS in C1. Inner fork skipped. C1 prints X (1) P : left operand non-zero → evaluate right side fork()#2 ─────▶ C2 processes: P, C1, C2 C2 → right operand is 0 → whole condition false → inner fork skipped. C2 prints X (2) P : non-zero && non-zero → condition TRUE → enter the if fork()#3 ─────▶ C3 processes: P, C1, C2, C3 C3 prints X (3) P prints X (4)

Note that C1 executes only one fork (the first one, which created it) and C2 executes two — the short-circuit is what keeps the total at 4 instead of 8.

Is question mein trap ye hai ki log && ka short-circuit bhool jaate hain. C1 mein doosra fork chalta hi nahi. Agar && ki jagah || hota toh ulta hota — parent short-circuit karta aur children forks karte. Har fork ke baad dono branches alag se trace karo, table bana kar. Yahi safest method hai — mental math mat karo.

Q 4.3

Explain the output ordering problem: after fork(), can you predict whether the parent or the child prints first? How would you force an order?

Show solution

No — the order is non-deterministic. After fork(), both processes are in the Ready queue and it is entirely up to the scheduler which runs first. On the same machine, the same binary can produce different orders on different runs. This is a race condition.

To force parent-after-child: the parent calls wait(), which blocks until the child terminates.

pid_t pid = fork();
if (pid == 0) {
    printf("child\n");
    exit(0);
} else {
    wait(NULL);              // blocks until child exits
    printf("parent\n");
}

To force child-after-parent you need explicit synchronisation — a pipe, a semaphore, or a signal — because there is no "wait for parent" call.

Context switch ASKED A LOT

The mechanism by which the CPU stops executing one process and starts another.

What gets saved

  • Program counter, stack pointer, all general-purpose registers
  • Processor status word / condition codes
  • Memory-management information (page table base register / base & limit)
  • Kernel stack pointer, accounting info — all into the outgoing PCB

Why it is expensive

  • Direct cost — saving and loading registers, updating queues. Microseconds.
  • Indirect cost (bigger) — the CPU cache is now full of the old process's data, so the new process starts with cache misses. The TLB may need flushing (unless it's tagged with an ASID). Branch predictors are cold. This "cache pollution" often dominates.
  • Pure overhead — during a context switch the system does no useful work.

Isliye time quantum bahut chhota nahi rakh sakte. Agar quantum 1ms hai aur context switch 0.1ms leta hai, toh 10% CPU sirf switching mein chala gaya. Ye exact trade-off Round Robin section mein numerically aayega.

The three schedulers COMMON

Long-term (job)Medium-termShort-term (CPU)
DecidesWhich jobs enter the systemWhich processes to swap out/inWhich ready process gets the CPU
ControlsDegree of multiprogrammingDegree of multiprogramming (reduces it)—
FrequencySeconds/minutes — slowOccasionalMilliseconds — very fast
State changeNew → ReadyReady ↔ Ready/SuspendReady → Running
Present inBatch systems (absent in most time-sharing/UNIX)Time-sharing systemsEvery system

Long-term scheduler ka asli kaam: ek acchha mix banana — kuch CPU-bound aur kuch I/O-bound processes. Agar sab CPU-bound le liye toh I/O devices idle rahengi aur ready queue lambi ho jayegi. Agar sab I/O-bound le liye toh CPU idle rahega. Balance chahiye. Ye specific point interviewers pasand karte hain.

Dispatcher vs Scheduler: Scheduler decide karta hai ("kaun chalega") — ye policy hai. Dispatcher karta hai (context switch, mode switch, jump to the right instruction) — ye mechanism hai. Jo time dispatcher leta hai usko dispatch latency kehte hain. Policy vs mechanism — ye phrase bolna.

05

Threads

Chhota section, par "process vs thread" ke bina koi interview poora nahi hota.

DEFINITION

A thread is a basic unit of CPU utilisation — a lightweight process. It has its own thread ID, program counter, register set and stack, but shares the code section, data section, heap, and OS resources (open files, signals) with other threads of the same process.

Process vs Thread ASKED A LOT

ProcessThread
Address spaceOwn, isolatedShared with siblings
Creation costHigh (new page tables, PCB, memory)Low
Context switch costHigh — address space changes, TLB flushLow — no address space change
CommunicationIPC needed (pipes, shared memory, messages) — kernel involvedJust read/write shared variables
Fault isolationOne crashes, others surviveOne segfaults → whole process dies
SynchronisationLess neededEssential — shared data = race conditions
Own stack?YesYes (this is the key private thing)

Ek line mein: "Process alag-alag ghar hain; threads ek hi ghar ke alag-alag kamre hain." Ghar badalna mehnga hai (address space switch). Kamra badalna sasta hai.

Par ghar share karne ka nuksan bhi hai — kitchen common hai, toh do log ek saath gas use karein toh jhagda (race condition). Aur agar ghar mein aag lagi toh sab kamre jal jaate hain (one thread crashes → whole process dies).

Ye trade-off hi answer hai: threads = fast communication + fast switching, but no isolation. Chrome ne isliye har tab ke liye process chuna, thread nahi — ek tab crash ho toh browser na mare.

Benefits of multithreading

  • Responsiveness — one thread blocks on I/O, the UI thread keeps responding.
  • Resource sharing — threads share memory by default; no IPC setup.
  • Economy — creating and switching threads is far cheaper than processes.
  • Scalability — a multithreaded process can run on multiple cores in parallel; a single-threaded process cannot.

User-level vs Kernel-level threads COMMON

User-level threads (ULT)Kernel-level threads (KLT)
Managed byThread library in user spaceThe OS kernel
Kernel aware?No — sees one processYes
SwitchingVery fast — no mode switchSlower — needs kernel involvement
Blocking I/OOne thread blocks → all blockOnly that thread blocks
MulticoreCannot use multiple coresTrue parallelism

Mapping models: Many-to-One (all ULTs → one KLT; simple but blocks everything), One-to-One (each ULT → its own KLT; true concurrency, but thread count limited — Linux, Windows), Many-to-Many (m ULTs multiplexed over n KLTs; best of both, complex).

ULT ka killer flaw yaad rakho: kernel ko pata hi nahi ki andar 10 threads hain — usko toh ek process dikhta hai. Toh jab koi ek thread read() kare aur block ho, kernel poore process ko block kar deta hai. Baaki 9 threads ready hain par chal nahi sakte. Yahi reason hai ki aaj sab one-to-one use karte hain.

06

CPU scheduling

Sabse zyada numerical wala topic. Gantt chart banana aa gaya toh ye section aapka hai.

The vocabulary — get these exactly right

Arrival Time (AT) = jab process ready queue mein aaya
Burst Time (BT) = CPU time needed
Completion Time (CT)= jab process khatam hua
Turnaround Time (TAT) = CT − AT // total time in system
Waiting Time (WT) = TAT − BT // time spent waiting in ready queue
Response Time (RT) = first CPU time − AT // wait until FIRST run, not completion

WT = TAT − BT ko yaad karne ka logic: total system mein kitna time raha (TAT), usme se jitna time actually CPU pe chala (BT) minus kar do — jo bacha woh wait hai. Simple.

RT vs WT ka farq interactive systems mein sabse important hai. Aap type karte ho aur screen pe letter dikhta hai — usko RT control karta hai, TAT nahi. Isliye time-sharing systems RT optimize karte hain aur batch systems TAT.

GOALS — MAXIMISE vs MINIMISE

Maximise: CPU utilisation, throughput (processes completed per unit time). Minimise: turnaround time, waiting time, response time. Interviewers ask "which one does algorithm X optimise?" — SJF minimises average waiting time, RR minimises response time, FCFS optimises nothing but is fair in arrival order.

Preemptive vs Non-preemptive

Non-preemptivePreemptive
Once a process gets the CPU it keeps it until it terminates or blocks for I/OOS can forcibly take the CPU away (timer, higher-priority arrival)
Simple, low overhead, no race on kernel dataBetter response time, needed for time sharing
A long process can starve everyone (convoy effect)More context switches; needs synchronisation on shared kernel data
FCFS, SJF, non-preemptive PrioritySRTF, RR, preemptive Priority, MLFQ

1. FCFS — First Come First Served

Non-preemptive. Ready queue is a plain FIFO.

Q 6.1 — SOLVED

Processes arrive at time 0 in the order P1, P2, P3 with burst times 24, 3, 3. Find average WT and TAT under FCFS. Then repeat with arrival order P2, P3, P1.

Show solution

Case A — order P1, P2, P3

│ P1 │ P2 │ P3 │ 0 24 27 30
PATBTCTTAT = CT−ATWT = TAT−BT
P102424240
P203272724
P303303027

Average WT = (0 + 24 + 27)/3 = 17. Average TAT = (24 + 27 + 30)/3 = 27.

Case B — order P2, P3, P1

│ P2 │ P3 │ P1 │ 0 3 6 30

WT: P2 = 0, P3 = 3, P1 = 6. Average WT = 9/3 = 3. Average TAT = (3 + 6 + 30)/3 = 13.

THE CONVOY EFFECT

Same processes, same burst times — average waiting time dropped from 17 to 3 just by changing arrival order. When one long CPU-bound process gets the CPU first, all the short processes queue behind it like cars behind a truck. Worse: the I/O devices sit idle the entire time, because all the I/O-bound processes are stuck waiting. This is the argument against FCFS.

Convoy effect ko interview mein aise bolo: "Ek lambi truck aage aa gayi single-lane road pe, aur peeche sab chhoti gaadiyan phas gayi. Sirf average waiting time nahi badhta — I/O devices bhi khaali baithi rehti hain, kyunki jo processes I/O karne wale the woh queue mein hain." Ye doosra half hi differentiate karta hai.

2. SJF (Shortest Job First) & SRTF (Shortest Remaining Time First)

SJF is non-preemptive: pick the ready process with the smallest burst. SRTF is its preemptive version: on every arrival, if the newcomer's burst is shorter than the running process's remaining time, preempt.

PROVABLY OPTIMAL

SJF gives the minimum possible average waiting time for a given set of processes. That is a theorem, not a heuristic. The catch: it requires knowing burst times in advance, which is impossible in practice. So SJF is a benchmark, not a shipping algorithm.

Q 6.2 — SOLVED

Compute average WT and TAT for both SJF (non-preemptive) and SRTF.

ProcessArrival TimeBurst Time
P108
P214
P329
P435
Show solution

Part A — SJF (non-preemptive)

At t=0 only P1 is present, so P1 runs to completion (t=0→8). At t=8, ready = {P2(4), P3(9), P4(5)} → shortest is P2. Then P4, then P3.

│ P1 │ P2 │ P4 │ P3 │ 0 8 12 17 26
PATBTCTTATWT
P108880
P21412117
P329262415
P43517149

Avg TAT = (8+11+24+14)/4 = 57/4 = 14.25. Avg WT = (0+7+15+9)/4 = 31/4 = 7.75.

Part B — SRTF (preemptive)

Walk the timeline event by event:

  • t=0 — only P1 (rem 8). P1 runs.
  • t=1 — P2 arrives with 4 < P1's remaining 7. Preempt. P2 runs.
  • t=2 — P3 arrives with 9 > P2's remaining 3. No preemption.
  • t=3 — P4 arrives with 5 > P2's remaining 2. No preemption.
  • t=5 — P2 finishes. Ready = P1(7), P3(9), P4(5). Shortest = P4. P4 runs.
  • t=10 — P4 finishes. Ready = P1(7), P3(9). P1 runs.
  • t=17 — P1 finishes. P3 runs → finishes at 26.
│P1│ P2 │ P4 │ P1 │ P3 │ 0 1 5 10 17 26
PATBTCTTATWT
P10817179
P214540
P329262415
P4351072

Avg TAT = (17+4+24+7)/4 = 52/4 = 13.0. Avg WT = (9+0+15+2)/4 = 26/4 = 6.5.

RESULT

SRTF beats SJF: 6.5 vs 7.75 average waiting time. Preemption lets short jobs jump ahead of a long one that has already started.

SRTF ka method (rat lo): har arrival par rukо aur compare karo — naya banda chhota hai ya current wale ka remaining? Bas. Beech mein kahin nahi rukna, sirf arrivals par aur completions par. Table mein "remaining time" ka column banao aur har event par update karo — mental math mat karo, galti pakki hai.

Predicting the next burst — exponential averaging

Since we can't know the next burst, we estimate it from history:

τn+1 = α · tn + (1 − α) · τn

tn = actual length of the n-th CPU burst
τn = predicted value for the n-th burst
α ∈ [0, 1], commonly α = 0.5
  • α = 0 → τn+1 = τn. Recent history ignored entirely.
  • α = 1 → τn+1 = tn. Only the most recent burst matters.
  • α = 0.5 → recent and past history equally weighted. Expanding the recursion shows each older term is weighted by a decreasing power of (1−α) — hence "exponential".

3. Priority scheduling

Each process gets a priority number; CPU goes to the highest priority. (Convention varies — usually smaller number = higher priority; always confirm in the question.) Available in preemptive and non-preemptive forms. SJF is just priority scheduling where priority = 1/(next burst).

STARVATION & AGING

Problem — starvation (indefinite blocking): a low-priority process may never run if high-priority processes keep arriving.

Solution — aging: gradually increase the priority of processes that have been waiting a long time. A process with priority 127 waiting for 15 minutes, aged by 1 every minute, eventually reaches priority 0 and runs.

Legend hai ki 1973 mein MIT ke IBM 7094 ko shut down kiya gaya toh ek process mila jo 1967 se queue mein pada tha. Chhe saal. Ye story interview mein sunao — starvation ka concept instantly clear ho jaata hai aur banda yaad rakhta hai.

4. Round Robin ASKED A LOT

FCFS with preemption. Each process gets a time quantum q. If it doesn't finish, it is preempted and put at the tail of the ready queue.

If there are n processes and quantum is q:
each process gets 1/n of CPU time in chunks of at most q
no process waits more than (n − 1) × q time units
Number of context switches ≈ Σ ⌈BTi / q⌉ − 1
Q 6.3 — SOLVED

Four processes, all arriving at time 0: P1 = 24, P2 = 3, P3 = 3, P4 = 6. Time quantum = 4. Draw the Gantt chart and compute average WT and TAT.

Show solution

Ready queue starts as [P1, P2, P3, P4]. Track remaining times.

TimeRunningRan forRemaining afterQueue after
0–4P14P1: 20P2,P3,P4,P1
4–7P23 (finishes)P2: 0 ✓P3,P4,P1
7–10P33 (finishes)P3: 0 ✓P4,P1
10–14P44P4: 2P1,P4
14–18P14P1: 16P4,P1
18–20P42 (finishes)P4: 0 ✓P1
20–24P14P1: 12P1
24–28P14P1: 8P1
28–32P14P1: 4P1
32–36P14 (finishes)P1: 0 ✓—
│ P1 │ P2 │ P3 │ P4 │ P1 │P4│ P1 │ P1 │ P1 │ P1 │ 0 4 7 10 14 18 20 24 28 32 36
PBTCTTAT = CT−0WT = TAT−BTRT
P1243636120
P237744
P33101077
P4620201410

Avg TAT = (36+7+10+20)/4 = 73/4 = 18.25. Avg WT = (12+4+7+14)/4 = 37/4 = 9.25.

THE QUEUE-INSERTION RULE THAT TRIPS PEOPLE UP

When a process is preempted at time t and another process arrives at exactly time t, the newly arrived process is placed in the queue before the preempted one in the standard convention. Always state your assumption if the question is ambiguous — examiners accept either if you're explicit.

Q 6.4

What happens to Round Robin as the time quantum q → ∞? And as q → 0? Given a context switch costs 0.1 ms, what is the CPU overhead at q = 1 ms vs q = 10 ms?

Show solution
  • q → ∞ (larger than the longest burst): no process is ever preempted, so RR degenerates to FCFS. Response time becomes terrible.
  • q → 0: this is called processor sharing — in theory each of n processes appears to run on its own CPU at 1/n speed. In practice, context switch overhead dominates and the system does almost no useful work (thrashing on switches).

Overhead calculation:

Overhead fraction = switch_time / (quantum + switch_time)
  • q = 1 ms: 0.1/(1 + 0.1) = 0.0909 → ≈ 9.1% of CPU wasted
  • q = 10 ms: 0.1/(10 + 0.1) = 0.0099 → ≈ 0.99% wasted

The rule of thumb: q should be large compared to the context-switch time, but small enough that ~80% of CPU bursts finish within one quantum. Typical real values: 10–100 ms, with switch cost around 10 µs.

Interview mein bolne ka tareeka: "Quantum ek trade-off knob hai. Bada karo toh FCFS ban jaayega — throughput accha, response time kharab. Chhota karo toh response time accha par overhead kha jaayega. Sweet spot woh hai jahan zyadatar bursts ek hi quantum mein khatam ho jaayein."

5. HRRN — Highest Response Ratio Next

Non-preemptive. Designed to fix SJF's starvation of long jobs.

Response Ratio = (W + S) / S

W = time spent waiting so far    S = expected service (burst) time
Pick the process with the highest ratio.

Formula ko todo: agar W = 0 (abhi aaya), ratio = 1. Jaise-jaise wait badhta hai, ratio badhta hai. Aur chhote S wale ka ratio tezi se badhta hai (denominator chhota). Toh short jobs ko preference milti hai par lambi job ka bhi ratio dheere-dheere badhta rahega aur eventually woh jeet jaayegi. Aging built-in hai formula ke andar — yahi HRRN ki khoobsurti hai.

Q 6.5 — SOLVED

P1(AT=0, BT=3), P2(AT=2, BT=6), P3(AT=4, BT=4), P4(AT=6, BT=5), P5(AT=8, BT=2). Schedule using HRRN.

Show solution

t=0: only P1 → runs 0→3.

t=3: ready = P2 (waited 3−2=1). Only choice → P2 runs 3→9.

t=9: ready = P3, P4, P5.

PW = 9 − ATSRR = (W+S)/S
P354(5+4)/4 = 2.25
P435(3+5)/5 = 1.60
P512(1+2)/2 = 1.50

Highest = P3 → runs 9→13.

t=13: ready = P4, P5.

PW = 13 − ATSRR
P475(7+5)/5 = 2.40
P552(5+2)/2 = 3.50

Highest = P5 → runs 13→15. Then P4 runs 15→20.

│ P1 │ P2 │ P3 │P5│ P4 │ 0 3 9 13 15 20
PATBTCTTATWT
P103330
P226971
P3441395
P46520149
P5821575

Avg TAT = 40/5 = 8.0. Avg WT = 20/5 = 4.0.

Notice at t=9 the shortest job P5 did not win — P3 had waited longer. Pure SJF would have picked P5. That is exactly the anti-starvation behaviour.

6. Multilevel Queue & Multilevel Feedback Queue COMMON

Multilevel Queue (MLQ)

Ready queue is split into several separate queues (e.g. system processes, interactive, interactive editing, batch, student). Each queue has its own scheduling algorithm. Processes are permanently assigned to one queue based on a property (memory size, priority, type).

Scheduling between queues: either fixed-priority preemptive (serve all of queue 1 before queue 2 — risks starvation) or time-slicing between queues (e.g. 80% CPU to foreground RR, 20% to background FCFS).

Multilevel Feedback Queue (MLFQ)

Same, but processes can move between queues. This is the practical, adaptive one.

Q0: quantum = 8 ──┐ finishes? done. │ not finished? demote ▼ Q1: quantum = 16 ──┐ finishes? done. │ not finished? demote ▼ Q2: FCFS ──┘ runs to completion (when Q0 & Q1 empty)

Defining parameters: number of queues, scheduling algorithm per queue, the rule to upgrade a process, the rule to demote a process, and the rule to decide which queue a new process enters.

MLFQ ka core idea: hum burst time guess nahi karte — hum observe karte hain. Naya process ko sabse upar wali (highest priority, chhota quantum) queue mein daalo. Agar woh apna quantum khatam kar gaya bina finish hue, matlab CPU-bound hai → neeche bhej do. Agar jaldi I/O ke liye block ho gaya, matlab interactive hai → upar hi rakho.

Aging kyun chahiye: agar ek process neeche chala gaya aur upar naye processes aate rahe, toh woh starve karega. Isliye periodically sab processes ko top queue mein wapas laate hain (priority boost).

Ek line: "MLFQ SJF ka approximation hai bina future jaane" — ye bolo, interviewer khush ho jaayega.

Comparison — the summary table

AlgorithmPreemptiveAvg WTStarvationBest for
FCFSNoHigh (convoy)NoBatch, simplicity
SJFNoOptimal (for non-preemptive)Yes — long jobsBatch with known bursts
SRTFYesOptimal overallYes — long jobsTheoretical benchmark
PriorityEitherDependsYes — fix with agingSystems with importance levels
Round RobinYesHigher than SJFNoTime sharing — best response time
HRRNNoGoodNo — aging built inBalanced batch
MLFQYesGood, adaptiveNo (with boosting)General-purpose OS

Multiprocessor scheduling RARE

  • Asymmetric — one master processor handles all scheduling; others just run user code. Simple, no data races on the scheduler, but the master is a bottleneck.
  • Symmetric (SMP) — each processor schedules itself, from a common ready queue or its own private queue.
  • Processor affinity — keep a process on the same CPU so its cache stays warm. Soft affinity = try; hard affinity = guaranteed.
  • Load balancing — push migration (a task periodically moves overloaded work off a CPU) vs pull migration (an idle CPU pulls work). These fight processor affinity — that tension is the interview point.
07

Concurrency & synchronisation

Ye OS ka sabse conceptual section hai. Race condition se semaphore tak — step by step.

Why there is a problem at all

Two processes share a variable count. One increments, one decrements. In C both look like a single statement, but the compiler emits three machine instructions:

count++ count-- ──────────────── ──────────────── R1 = count (load) R2 = count (load) R1 = R1 + 1 (add) R2 = R2 - 1 (sub) count = R1 (store) count = R2 (store)

The OS can preempt between any two machine instructions. Start with count = 5 and interleave:

StepExecutedR1R2count
1P: R1 = count5—5
2P: R1 = R1 + 16—5
3switch → C: R2 = count655
4C: R2 = R2 − 1645
5C: count = R2644
6switch → P: count = R1646

Final answer is 6. Reverse the last two steps and it is 4. The correct answer is 5. Both are wrong, and which one you get depends on timing.

RACE CONDITION

A situation where several processes access and manipulate shared data concurrently, and the outcome depends on the particular order in which the accesses take place.

Yahi poore chapter ki jad hai. count++ aapko ek line dikhti hai, par CPU ke liye woh teen alag steps hain — load, modify, store. Beech mein OS aapko hata sakta hai.

Bank account analogy: aap aur aapka bhai ek hi account se ek saath paise nikaal rahe ho, do alag ATMs se. Dono machine ne balance padha ₹5000. Aapne 3000 nikale, usne 4000. Dono ne apne hisaab se naya balance likh diya. Bank ka record ab galat hai. Padhne aur likhne ke beech ka gap hi problem hai.

Sabse important insight: race condition har baar nahi hoti. 999 baar sahi chalega, 1000vi baar bug. Isliye ye bugs sabse mushkil hote hain — reproduce hi nahi hote. Non-determinism hi asli dushman hai.

Critical section & the three requirements ASKED A LOT

The critical section is the segment of code where a process accesses shared resources. General structure:

do {
    // ENTRY SECTION       ← request permission
        critical section
    // EXIT SECTION        ← signal that you're done
        remainder section
} while (true);
ANY VALID SOLUTION MUST SATISFY ALL THREE
  1. Mutual Exclusion — if a process is executing in its critical section, no other process may be in its critical section.
  2. Progress — if no process is in its critical section and some want to enter, only those not in their remainder section may participate in the decision, and the decision cannot be postponed indefinitely.
  3. Bounded Waiting — there is a bound on the number of times other processes may enter their critical sections after a process has made a request and before that request is granted.

Teeno ko simple bhasha mein:

Mutual Exclusion = "ek time pe sirf ek banda bathroom mein." Ye sabse obvious hai.

Progress = "agar bathroom khaali hai aur koi bahar khada hai, toh usko andar jaana chahiye." Deadlock nahi hona chahiye. Aur decision lene mein woh log involve nahi hone chahiye jo abhi jaana hi nahi chahte (remainder section wale).

Bounded Waiting = "aapko infinite baar overtake nahi kiya jaa sakta." Line mein khade ho toh koi guarantee honi chahiye ki max N logon ke baad aapka number aayega. Ye starvation ko rokta hai.

Interview trick: koi bhi galat solution dikhaye toh in teeno ke against check karo. Zyadatar galat solutions Progress fail karte hain, Mutual Exclusion nahi.

Software solutions — the wrong ones first

Attempt 1: strict alternation with a turn variable

// shared: int turn = 0;
// Process P0                      Process P1
while (turn != 0) ;              while (turn != 1) ;
   critical section                   critical section
turn = 1;                          turn = 0;

Mutual exclusion: yes. Progress: NO. If P0 finishes its critical section, sets turn = 1, and then never wants to enter again, P1 can enter once — and after that P1 is stuck forever waiting for turn = 1, even though P0 is sitting in its remainder section and the critical section is empty.

Ye strict alternation hai — bari-bari se. Problem: agar ek banda aana hi nahi chahta toh doosra bhi phas jaata hai. Bathroom khaali hai, aap bahar khade ho, par rule kehta hai "abhi uski baari hai" — aur woh ghar pe hai. Progress fail.

Attempt 2: two flags

// shared: bool flag[2] = {false, false};
// Process Pi
flag[i] = true;
while (flag[j]) ;
   critical section
flag[i] = false;

Mutual exclusion: yes. Progress: NO — deadlock. If both set their flag to true at almost the same instant, both then see the other's flag as true and both loop forever. Neither enters.

Peterson's solution — the correct one ASKED A LOT

// shared
int  turn;
bool flag[2] = {false, false};

// Process Pi  (j = 1 - i)
do {
    flag[i] = true;                     // I want in
    turn    = j;                        // but you go first (politeness!)
    while (flag[j] && turn == j) ;     // busy wait

        critical section

    flag[i] = false;
        remainder section
} while (true);

Peterson ka jaadu ek line mein hai: turn = j; — "main andar jaana chahta hoon, par pehle tum jao."

Agar dono ek saath aaye, dono flag = true karenge, aur dono turn ko doosre ka number denge. Par turn ek hi variable hai — jo baad mein likhega uski value rahegi. Maan lo P0 ne baad mein turn = 1 likha. Ab P1 ka condition flag[0] && turn == 0 false hai (turn = 1 hai), toh P1 andar chala jaayega. P0 wait karega. Deadlock nahi hua.

Yeh "pehle aap, pehle aap" wali politeness hi solution hai — Attempt 2 mein dono zid kar rahe the "main pehle", isliye dono phase. Peterson mein dono jhukte hain, aur kyunki turn single variable hai, exactly ek ka jhukna "count" hota hai.

Proves all three: Mutual exclusion (both can't have the winning turn value), Progress (the loop condition requires both flag[j] and turn == j; if P1 isn't interested flag[j] is false and P0 walks in), Bounded waiting (after Pi exits and re-requests, it sets turn = j, so Pj gets at most one turn ahead — bound is 1).

MODERN CAVEAT — GOOD ANSWER TO GIVE

Peterson's algorithm is not guaranteed to work on modern processors, because CPUs and compilers reorder memory reads and writes for performance. The write to flag[i] and the write to turn may become visible to the other core in the wrong order, breaking the proof. Real implementations need memory barriers/fences (or volatile/atomics with the right ordering). Saying this shows you understand it beyond the textbook.

Hardware solutions

Disabling interrupts

Simplest idea: turn interrupts off before the critical section, on after. Works on a uniprocessor (no preemption is possible). Fails on multiprocessors — disabling interrupts on one core doesn't stop another core from entering. Also dangerous: a bug means the system freezes, and it's a privileged operation, so user code can't do it.

Test-and-Set (TSL) COMMON

An atomic hardware instruction — reads a value and sets it to true in one indivisible step.

bool TestAndSet(bool *target) {   // executed ATOMICALLY by hardware
    bool rv = *target;
    *target = true;
    return rv;
}

// usage — shared: bool lock = false;
do {
    while (TestAndSet(&lock)) ;    // spin until we get false back
        critical section
    lock = false;
        remainder section
} while (true);

Compare-and-Swap (CAS)

int CompareAndSwap(int *value, int expected, int new_value) {
    int temp = *value;
    if (*value == expected) *value = new_value;
    return temp;
}

Atomic ka matlab kya? "Beech mein koi nahi ghus sakta." Hardware bus ko lock kar deta hai us ek instruction ke liye. Load-modify-store ki teen steps ek ban jaati hain. Yahi race condition ki jad ko kaat deta hai.

TSL ka problem: while(TestAndSet(...)) — ye busy waiting hai. Process CPU pakde rehta hai aur bas loop maar raha hai, koi kaam nahi kar raha. Isko spinlock kehte hain.

Spinlock kab acchha hai? Jab lock bahut chhote time ke liye hold hoga aur aapke paas multiple cores hain. Kyunki block-and-wakeup ka apna cost hai (do context switches). Agar lock 100 nanosecond ke liye hai toh spin karna sasta hai. Agar 10 millisecond ke liye hai toh block karna sasta hai. Yahi answer hai "spinlock vs mutex kab use karein" ka.

TSL bounded waiting guarantee nahi karta — koi unlucky process baar-baar haar sakta hai. Uske liye ek waiting array aur turn-passing logic chahiye.

Semaphores ASKED A LOT

DEFINITION

A semaphore S is an integer variable accessed only through two atomic operations: wait(S) (also called P or down) and signal(S) (also called V or up).

// naive version — busy waiting
wait(S)   { while (S <= 0) ;   S--; }
signal(S) { S++; }

// real version — no busy waiting
wait(S) {
    S--;
    if (S < 0) { add this process to S.queue; block(); }
}
signal(S) {
    S++;
    if (S <= 0) { remove a process P from S.queue; wakeup(P); }
}
READ THE SIGN

In the no-busy-wait version, a negative value of S has meaning: |S| is the number of processes blocked on that semaphore. If S = −3, three processes are waiting. This is a favourite one-mark question.

Counting vs Binary semaphore

Counting semaphoreBinary semaphore
RangeAny integer (unrestricted)Only 0 or 1
Used forControlling access to a resource with N instancesMutual exclusion (one resource)
Init valueNumber of available resources1
Example5 printers → S = 5One shared variable → S = 1

Mutex vs Binary semaphore ASKED A LOT

Mutex (lock)Binary semaphore
PurposeLocking — protect a critical sectionSignalling — notify another thread of an event
OwnershipHas an owner. Only the thread that locked it may unlock itNo ownership. Any thread can signal
Typical useProtect shared dataProducer signals consumer that an item is ready
Priority inversionCan implement priority inheritance (because owner is known)Cannot — no owner to boost
RecursionRecursive mutexes existNo such concept

Ye question guaranteed hai. Yaad rakhne ka tareeka:

Mutex = bathroom ki chaabi. Jisne li, wahi wapas karega. Koi doosra aapke liye darwaza nahi khol sakta. Ownership hoti hai.

Binary semaphore = ghanti / signal. Koi bhi baja sakta hai. Producer ghanti bajata hai, consumer sunta hai. Jo wait() kare aur jo signal() kare woh alag threads ho sakte hain — aur yahi asli use case hai.

Ek line ka answer: "Mutex locking ke liye hai, semaphore signalling ke liye. Mutex ka owner hota hai, semaphore ka nahi."

Priority inversion wala bonus point: Low-priority thread ne mutex liya, high-priority thread wait kar raha hai, aur beech mein medium-priority thread CPU le kar chal raha hai — high effectively medium se peeche ho gaya. Priority inheritance se lock-holder ko temporarily high priority de dete hain. Ye sirf mutex mein possible hai kyunki owner pata hai. (Mars Pathfinder 1997 mein yahi bug tha — story sunane layak hai.)

08

Classic synchronisation problems

Teen problems: producer-consumer, readers-writers, dining philosophers. In teeno ka code aur trap yaad rakho.

1. Producer–Consumer (bounded buffer) ASKED A LOT

A producer puts items into a buffer of size n; a consumer removes them. Producer must wait if the buffer is full; consumer must wait if it is empty.

// three semaphores
semaphore mutex = 1;    // mutual exclusion on the buffer
semaphore empty = n;    // count of EMPTY slots
semaphore full  = 0;    // count of FULL slots

Producer:                        Consumer:
do {                            do {
    produce an item                  wait(full);
    wait(empty);                     wait(mutex);
    wait(mutex);                        remove item from buffer
       add item to buffer            signal(mutex);
    signal(mutex);                   signal(empty);
    signal(full);                    consume the item
} while (true);                } while (true);

Teen semaphores kyun? Har ek ka apna kaam hai:

  • mutex = buffer ko ek time pe ek hi banda chhue. (mutual exclusion)
  • empty = "kitni khaali jagah bachi hai" ka counter. Producer isko consume karta hai.
  • full = "kitne items pade hain" ka counter. Consumer isko consume karta hai.

Symmetry dekho: Producer wait(empty) → signal(full). Consumer wait(full) → signal(empty). Bilkul mirror image. Yahi se code yaad rehta hai — rat-ne ki zaroorat nahi.

Q 8.1 — THE CLASSIC TRAP

What happens if the producer's two wait statements are swapped, i.e. wait(mutex) comes before wait(empty)?

Producer:
    wait(mutex);      // ← swapped
    wait(empty);      // ←
       add item
    signal(mutex);
    signal(full);
Show solution

Deadlock. Here is the exact sequence:

  1. Buffer is full, so empty = 0.
  2. Producer executes wait(mutex) → succeeds, mutex is now 0. Producer holds the lock.
  3. Producer executes wait(empty) → empty is 0, so the producer blocks — while still holding mutex.
  4. Consumer arrives, executes wait(full) → succeeds (buffer has items).
  5. Consumer executes wait(mutex) → mutex is 0 → consumer blocks.
  6. Producer waits for the consumer to free a slot. Consumer waits for the producer to release mutex. Circular wait → deadlock.
THE RULE TO STATE

Never acquire the mutex before the counting semaphore. Generally: never block on a condition while holding a lock. The counting semaphores (empty/full) are the ones that can block for a long time; the mutex must be the innermost, shortest-held lock.

Bolne wala one-liner: "Aapne bathroom ki chaabi le li aur andar ja kar so gaye kyunki paani nahi aa raha. Ab paani wala aa bhi jaaye toh andar aa nahi sakta, kyunki chaabi aapke paas hai. Lock pakad kar wait mat karo."

Q 8.2

What if the two signal statements in the producer are swapped — signal(full) before signal(mutex)?

Show solution

No deadlock. It still works correctly — only a small efficiency loss.

Reason: signal() never blocks. It always increments and returns. So the order of two signals cannot create a circular wait.

The minor cost: after signal(full), a waiting consumer becomes ready and may be scheduled immediately, only to block on wait(mutex) because the producer hasn't released it yet. That's one wasted wakeup + context switch. Correct, just slightly slower.

THE GENERAL PRINCIPLE

Order of waits matters (can deadlock). Order of signals does not (only performance). If you remember only one thing about this problem, remember this line.

2. Readers–Writers COMMON

Many readers may read simultaneously. A writer needs exclusive access — no other writer and no reader.

semaphore mutex   = 1;   // protects readcount
semaphore wrt     = 1;   // exclusive access for writers
int       readcount = 0;

Writer:                     Reader:
wait(wrt);                  wait(mutex);
   writing is performed        readcount++;
signal(wrt);                   if (readcount == 1) wait(wrt);   // FIRST reader locks out writers
                            signal(mutex);

                               reading is performed

                            wait(mutex);
                               readcount--;
                               if (readcount == 0) signal(wrt); // LAST reader lets writers in
                            signal(mutex);

Trick ye hai: wrt semaphore ko sirf pehla reader lock karta hai aur aakhri reader release karta hai. Beech wale readers bas readcount badha-ghata kar andar-bahar hote rehte hain.

Socho ek museum ka gate — pehla visitor gate kholta hai aur "CLOSED FOR MAINTENANCE" board hata deta hai; aakhri visitor jaate waqt wapas laga deta hai. Beech wale bas andar-bahar chalte rehte hain.

Ye version "readers preference" hai — aur isme writer starve kar sakta hai. Agar readers continuously aate rahein, readcount kabhi 0 nahi hoga, aur writer hamesha wait karega. Interviewer yahi follow-up poochhta hai: "kya isme koi starve ho sakta hai?" Answer: haan, writer. Fix: writers-preference variant, ya fair queueing.

3. Dining Philosophers ASKED A LOT

Five philosophers sit around a table with five chopsticks between them. To eat, a philosopher needs both the left and right chopstick. They alternate between thinking and eating.

P0 C4 ┌──────┐ C0 P4 ────┤ ├──── P1 C3 │ RICE │ C1 P3 ────┤ ├──── P2 └──────┘ C2 Each Pi needs chopstick[i] and chopstick[(i+1) % 5]
// the NAIVE solution — semaphore chopstick[5] all initialised to 1
do {
    wait(chopstick[i]);              // pick up LEFT
    wait(chopstick[(i+1) % 5]);      // pick up RIGHT
        eat
    signal(chopstick[i]);
    signal(chopstick[(i+1) % 5]);
        think
} while (true);
THIS SOLUTION DEADLOCKS

If all five philosophers pick up their left chopstick at the same instant, every chopstick is held and every philosopher is waiting for the right one, which their neighbour holds. Perfect circular wait. Nobody eats, ever.

Four standard fixes

FixHowWhich deadlock condition it breaks
Allow at most 4 to sitAdd a counting semaphore initialised to 4Circular wait (with 5 sticks and 4 diners, someone always gets both)
Pick up both or neitherGrab both chopsticks inside one critical sectionHold-and-wait
Asymmetric solutionOdd philosophers take left then right; even take right then leftCircular wait — the cycle is broken
Resource orderingAlways pick up the lower-numbered chopstick firstCircular wait

Asymmetric solution sabse elegant hai — aur yahi bolna interview mein. Kyun kaam karta hai: agar P0 aur P1 dono chopstick C1 chahte hain, par ek left-first hai aur doosra right-first, toh dono ek hi chopstick ke liye pehle compete karenge. Ek jeetega, doosra wahin ruk jaayega — bina koi chopstick pakde. Circular chain toot gayi.

Aur ek important baat: deadlock hatana kaafi nahi — starvation bhi rokni hai. Agar do philosophers baar-baar khaate rahein aur teesra hamesha haar jaaye, deadlock nahi hai par woh bhookha mar jaayega. Acchha solution dono handle karta hai. Ye distinction bolo, marks/impression dono milte hain.

Monitors COMMON

DEFINITION

A monitor is a high-level synchronisation construct: an abstract data type in which only one process may be active inside the monitor at a time. Mutual exclusion is provided automatically by the compiler/language, not by the programmer.

monitor SharedBuffer {
    // shared variables — accessible only from inside
    int count = 0;
    condition notFull, notEmpty;      // condition variables

    procedure insert(item x) {
        if (count == N) notFull.wait();
        ... add x ...
        count++;
        notEmpty.signal();
    }
    procedure remove() { ... }
}

Condition variables provide x.wait() (suspend the calling process until someone signals x) and x.signal() (resume exactly one suspended process; if none is suspended, the signal is lost — no effect).

SemaphoreMonitor
LevelLow-level primitiveHigh-level language construct
Mutual exclusionProgrammer must write wait/signal correctlyAutomatic — compiler enforces it
Error-prone?Very — one swapped/missing call breaks everythingMuch safer
Signal with no waiterRemembered (counter increments)Lost (no effect)
Found inOS kernels, C with pthreadsJava (synchronized), C#, Concurrent Pascal

Semaphore vs monitor ka farq ek line mein: semaphore mein aapko yaad rakhna padta hai ki lock lena aur chhodna hai; monitor mein compiler ye khud karta hai. Isliye Java mein aap sirf synchronized likhte ho — lock lena/chhodna automatic.

"Signal lost" wala difference bahut important hai. Semaphore ek counter hai — usme yaad rehta hai ki kitne signals aaye. Condition variable ki koi memory nahi — agar signal aaya aur koi wait nahi kar raha tha, woh signal gayab. Isliye condition variables hamesha while (condition) wait(); ke saath use karte hain, if ke saath nahi.

09

Inter-process communication (IPC)

Chhota section, par "processes baat kaise karte hain" ek common opener hai.

Two models COMMON

Shared memoryMessage passing
HowA memory region is mapped into both address spaces; both read/write itProcesses exchange discrete messages via send() / receive()
Kernel involvementOnly to set up the region; then noneOn every message
SpeedFast — memory speedSlower — system call per message
SynchronisationProgrammer's job — race conditions are yours to fixBuilt into the primitives
Distributed systemsNo — needs shared physical memoryYes — works across a network
Data sizeGood for large dataBetter for small amounts

Shared memory = ek common whiteboard jispe dono likh sakte hain — fast, par jhagda ho sakta hai aur aapko khud rules banane padenge. Message passing = ek dusre ko chitthi bhejna — safe, ordered, par har chitthi mein post office (kernel) ka time lagta hai.

Message passing design choices

Synchronisation

  • Blocking send — sender waits until the message is received. Non-blocking send — sender continues immediately.
  • Blocking receive — receiver waits until a message is available. Non-blocking receive — returns either a message or null.
  • Rendezvous = blocking send + blocking receive. Both must arrive at the meeting point.

Addressing

  • Direct — send(P, msg) names the process explicitly. A link is established automatically between exactly two processes. Downside: hard-codes process identity; changing a process name breaks all references.
  • Indirect (mailbox / port) — send(A, msg) sends to a mailbox. A link exists only if two processes share a mailbox; a mailbox may be shared by more than two, and one process may have many mailboxes. Far more flexible.
CLASSIC INDIRECT-ADDRESSING QUESTION

If P1, P2 and P3 all share mailbox A, P1 sends one message, and both P2 and P3 execute receive() — who gets it? The design must pick a rule: (a) allow a link between at most two processes, (b) allow only one process at a time to execute receive, or (c) let the system select the receiver arbitrarily and notify the sender who got it.

Buffering

The queue attached to a link can be zero capacity (no buffering — sender must block until receive; rendezvous), bounded capacity (n messages; sender blocks only when full), or unbounded capacity (sender never blocks — theoretical ideal).

Real-world IPC mechanisms in Unix

MechanismDirectionRelated processes?Persists after process exit?
Pipe (unnamed)One-wayMust be related (parent–child)No
Named pipe (FIFO)One-way (or two with two FIFOs)Any processesYes — it's a file
Shared memoryTwo-wayAnyYes, until removed
Message queueTwo-wayAnyYes
SocketTwo-wayAny, even across machinesNo
SignalOne-way, no dataAny (with permission)N/A

Pipe ka classic example aap roz use karte ho: ls | grep txt. Shell ek pipe banata hai, ls ka stdout usme daal deta hai aur grep ka stdin usse jod deta hai. Ye kaam fork ke baad, exec se pehle hota hai — yaad hai woh window jiski baat §04 mein ki thi? Yahi uska asli use hai.

0A

Deadlocks

4 conditions + Banker's algorithm. Ye do cheezein aati hain toh deadlock ka poora chapter aapka hai.

DEFINITION

A set of processes is deadlocked when every process in the set is waiting for an event that can only be caused by another process in the same set. Since all are waiting, none can cause any event, so all wait forever.

Bridge crossing example (slides mein hai): ek single-lane pul par dono taraf se gaadiyan aa gayi, aamne-saamne. Na koi aage jaa sakta, na peeche hat sakta. Deadlock. Recovery ka ek tareeka: ek side ki gaadiyon ko reverse karao — matlab preemption + rollback. Aur agar sirf ek hi side ki gaadiyan hamesha reverse hoti rahein toh starvation ho jaayegi.

The four necessary conditions ASKED A LOT

ALL FOUR MUST HOLD SIMULTANEOUSLY
  1. Mutual exclusion — at least one resource is non-shareable; only one process at a time can use it.
  2. Hold and wait — a process holding at least one resource is waiting to acquire additional resources held by others.
  3. No preemption — a resource can only be released voluntarily by the process holding it.
  4. Circular wait — there exists a set {P0, P1, …, Pn} such that P0 waits for a resource held by P1, P1 for P2, …, Pn for P0.

Yaad karne ka tareeka — "MHNC" ya simple story:

Ek cheez aisi ho jo share na ho sake (mutual exclusion). Log ek cheez pakde-pakde doosri maang rahe hon (hold and wait). Kisi se zabardasti chheena na jaa sake (no preemption). Aur wait karne ka ek chakkar ban jaaye (circular wait).

Sabse important point jo log bhool jaate hain: ye chaaron necessary hain, par akele sufficient nahi hain — sirf circular wait hone se deadlock guarantee nahi hota agar resources ke multiple instances hain. (Isi ka proof RAG section mein hai.)

Aur: deadlock ko rokne ke liye sirf ek condition todni kaafi hai. Chaaron todne ki zaroorat nahi. Yahi prevention ka poora idea hai.

Resource Allocation Graph (RAG) ASKED A LOT

  • Vertices: processes (circles, Pi) and resource types (rectangles, Rj, with a dot for each instance).
  • Request edge: Pi → Rj (process is waiting for the resource).
  • Assignment edge: Rj → Pi (an instance is allocated to the process).
THE RULE — MEMORISE THIS EXACTLY
  • No cycle → definitely no deadlock.
  • Cycle + only one instance of each resource type in the cycle → deadlock, guaranteed.
  • Cycle + multiple instances → deadlock is possible but not certain.
CASE A — cycle with single instances → DEADLOCK P1 ──request──▶ R1 ──assigned──▶ P2 ──request──▶ R2 ──assigned──▶ P1 (R1 and R2 each have exactly 1 instance) CASE B — cycle with multiple instances → NO deadlock here R1 has 2 instances, R2 has 2 instances P1 → R1 → P2 → R2 → P1 (a cycle exists) BUT R1's second instance is held by P3, and R2's second by P4. If P3 or P4 finishes and releases, the cycle resolves. No deadlock.

Ye samjho: cycle ka matlab hai "ek chakkar ban gaya". Agar har resource ki sirf ek copy hai, toh chakkar mein har banda exactly usi copy ka wait kar raha hai jo agle ke paas hai — koi ummeed nahi. Par agar do copies hain, toh ho sakta hai doosri copy kisi tisre process ke paas ho jo cycle mein nahi hai — woh khatam hoga, release karega, chakkar toot jaayega. Isliye multiple instances mein cycle sirf "shak" hai, "saboot" nahi.

Four ways to handle deadlock

ApproachIdeaCostUsed by
PreventionStructurally break one of the four conditionsLow device utilisation, low throughputSpecial-purpose systems
AvoidanceRequire advance info on max needs; only grant requests that keep the system in a safe stateNeeds max claims upfront; runtime overheadRare in practice
Detection + recoveryLet deadlock happen, detect it, then recoverDetection algorithm cost + recovery lossSome databases
Ignore it ("ostrich algorithm")Pretend deadlocks never happen; reboot if the system hangsOccasional hangLinux, Windows, most real OSes

Haan, sach mein — Linux aur Windows deadlock ko ignore karte hain. Kyunki deadlock bahut kam hota hai, aur prevention/avoidance ka cost har request par lagta hai. Reasoning: "har din ek chhota tax dena vs saal mein ek baar reboot karna" — reboot sasta hai. Ye answer bolne se interviewer ko lagta hai aapne sirf textbook nahi padha.

Deadlock prevention — attack each condition

ConditionHow to break itProblem with doing so
Mutual exclusionMake resources shareable (e.g. read-only files); use spooling for printersUsually impossible. Some resources are inherently non-shareable
Hold and waitEither (a) request all resources before starting, or (b) release everything before requesting anything newLow utilisation (resources held but unused for long) + starvation (a process needing many popular resources may never get them all at once)
No preemptionIf a process requests something unavailable, preempt all its currently held resources; it restarts when it can get everythingOnly works for resources whose state is easy to save/restore (CPU registers, memory). Not printers or tape drives
Circular waitImpose a total ordering on resource types; a process may only request resources in increasing order of enumerationRestricts programming freedom; ordering must be chosen well
THE PRACTICAL ONE

Resource ordering is the one that actually gets used in real code. Every lock in the Linux kernel has a documented acquisition order, and tools like lockdep verify it. If you've ever had a code review comment saying "acquire lock A before lock B", that's circular-wait prevention.

Deadlock avoidance — safe states

SAFE STATE

A state is safe if there exists a safe sequence ⟨P1, P2, …, Pn⟩ such that for each Pi, the resources Pi may still request can be satisfied by the currently available resources plus the resources held by all Pj with j < i. That is: even in the worst case, everyone can finish, in some order.

Safe → no deadlock
Unsafe → deadlock is possible, not certain
Deadlocked ⊂ Unsafe

Avoidance = never let the system enter an unsafe state.

Unsafe ≠ deadlock. Unsafe ka matlab sirf itna hai ki "agar sab log apni maximum demand ek saath maang lein toh phas sakte hain." Ho sakta hai woh kabhi na maangein aur sab theek chale. Par OS risk nahi leta — avoidance conservative hai. Ye distinction interview mein bahut poochha jaata hai.

Banker's Algorithm ASKED A LOT

Data structures (n processes, m resource types)

Available[m] — currently free instances of each type
Max[n][m] — maximum demand of each process
Allocation[n][m] — currently allocated to each process
Need[n][m] = Max − Allocation   ← always compute this first

Safety algorithm

  1. Work = Available; Finish[i] = false for all i.
  2. Find an i with Finish[i] == false and Need[i] ≤ Work. If none exists, go to step 4.
  3. Work = Work + Allocation[i]; Finish[i] = true; go to step 2.
  4. If Finish[i] == true for all i, the system is safe. Otherwise, unsafe.

Bank ka analogy (isi se naam pada): bank ke paas limited cash hai. Har customer ne apni maximum credit limit bata rakhi hai. Bank loan tabhi deta hai jab uske paas itna cash bache ki kam se kam ek customer ki poori limit puri kar sake — woh customer khush ho kar poora paisa wapas karega, aur us paise se agla nipat jaayega. Domino effect. Agar aisa koi order nahi mil raha, toh loan reject.

Q 10.1 — SOLVED (the standard example)

System has 5 processes and 3 resource types: A (10 instances), B (5), C (7). Current state:

ProcessAllocation
A  B  C
Max
A  B  C
P0010753
P1200322
P2302902
P3211222
P4002433

(a) Is the system in a safe state? Give a safe sequence.
(b) Can P1's request (1, 0, 2) be granted immediately?

Show solution

Step 1 — compute Available.

Total allocated: A = 0+2+3+2+0 = 7, B = 1+0+0+1+0 = 2, C = 0+0+2+1+2 = 5.

Available = Total − Allocated = (10−7, 5−2, 7−5) = (3, 3, 2)

Step 2 — compute Need = Max − Allocation.

ProcessNeed (A B C)
P0743
P1122
P2600
P3011
P4431

Step 3 — run the safety algorithm. Work = (3, 3, 2).

IterWork beforeCheckPickWork after = Work + Alloc
1(3,3,2)P0 Need(7,4,3) > Work ✗ · P1 Need(1,2,2) ≤ Work ✓P1(3,3,2)+(2,0,0) = (5,3,2)
2(5,3,2)P0 (7,4,3) ✗ · P2 (6,0,0) ✗ · P3 (0,1,1) ≤ Work ✓P3(5,3,2)+(2,1,1) = (7,4,3)
3(7,4,3)P0 (7,4,3) ≤ Work ✓P0(7,4,3)+(0,1,0) = (7,5,3)
4(7,5,3)P2 (6,0,0) ≤ Work ✓P2(7,5,3)+(3,0,2) = (10,5,5)
5(10,5,5)P4 (4,3,1) ≤ Work ✓P4(10,5,5)+(0,0,2) = (10,5,7)

All five finished. (a) The system IS in a safe state. Safe sequence: ⟨P1, P3, P0, P2, P4⟩.

NOTE

The safe sequence is not unique. ⟨P1, P3, P4, P0, P2⟩ also works. If asked, giving any one valid sequence is enough — but check yours by walking through it.

(b) P1 requests (1, 0, 2). Run the resource-request algorithm:

  1. Is Request ≤ Need[P1]? (1,0,2) ≤ (1,2,2) ✓ — legal request.
  2. Is Request ≤ Available? (1,0,2) ≤ (3,3,2) ✓ — resources exist.
  3. Pretend to grant it and check safety of the new state:
    Available = (3,3,2) − (1,0,2) = (2,3,0)
    Allocation[P1] = (2,0,0) + (1,0,2) = (3,0,2)
    Need[P1] = (1,2,2) − (1,0,2) = (0,2,0)

New Need table: P0(7,4,3), P1(0,2,0), P2(6,0,0), P3(0,1,1), P4(4,3,1). Work = (2,3,0).

IterWorkPickWork after
1(2,3,0)P1 — Need(0,2,0) ≤ (2,3,0) ✓(2,3,0)+(3,0,2) = (5,3,2)
2(5,3,2)P3 — Need(0,1,1) ✓(5,3,2)+(2,1,1) = (7,4,3)
3(7,4,3)P0 — Need(7,4,3) ✓(7,4,3)+(0,1,0) = (7,5,3)
4(7,5,3)P2 — Need(6,0,0) ✓(7,5,3)+(3,0,2) = (10,5,5)
5(10,5,5)P4 — Need(4,3,1) ✓(10,5,7)

Safe. Sequence ⟨P1, P3, P0, P2, P4⟩. So the request can be granted immediately.

Exam mein steps ka order kabhi mat badlo: (1) Available nikalo (2) Need = Max − Allocation (3) safety loop chalao, har iteration mein Work update karo. Request wale part mein teen checks: Request ≤ Need? Request ≤ Available? Naya state safe? Teeno pass toh grant, warna wait.

Q 10.2 — CLASSIC FORMULA QUESTION

A system has n processes and m instances of a single resource type. Each process needs at most k instances. What is the condition on m that guarantees the system is deadlock-free?

Show solution

Worst-case reasoning. Deadlock is worst when every process holds as much as it can without being able to finish — that is, each holds k − 1 instances and waits for one more.

In that state, the total held is n(k − 1). If even one extra instance exists, some process can grab it, reach k, finish, and release everything — breaking the chain.

Deadlock-free if: m ≥ n(k − 1) + 1

Equivalently, deadlock is possible if m ≤ n(k − 1).

Worked variant: "3 processes, each needs at most 4 instances. What is the minimum m for deadlock-freedom?"

m ≥ 3(4 − 1) + 1 = 3(3) + 1 = 10.

Reverse variant: "There are 12 instances and each process needs at most 3. What is the maximum number of processes such that the system is guaranteed deadlock-free?"

12 ≥ n(3 − 1) + 1 → 12 ≥ 2n + 1 → n ≤ 5.5 → n = 5.

Formula ki intuition: har process ko "ek kam" de do — sab atak jaayenge. Ab agar ek bhi extra instance bacha, toh kisi ek ko poora mil jaayega, woh kaam khatam kar ke sab chhod dega, aur domino chal padega. Isliye +1. Ye formula GATE aur product-company OAs dono mein aata hai — rat lo.

Deadlock detection

Single instance per resource type — wait-for graph

Collapse the RAG: remove resource nodes and draw Pi → Pj if Pi is waiting for a resource held by Pj. A deadlock exists iff the wait-for graph contains a cycle. Cost: O(n²) to search for a cycle.

Multiple instances — the detection algorithm

Same shape as the safety algorithm, but it uses Request (what is actually being asked for right now) instead of Need (what could ever be asked for). Processes not requesting anything are marked finished immediately.

SAFETY vs DETECTION — THE ONE-LINE DIFFERENCE

The safety algorithm is pessimistic: it assumes every process will eventually demand its full Need. The detection algorithm is factual: it only looks at the current Request. Same loop, different input matrix. That's why avoidance can call a state "unsafe" when no deadlock actually exists.

When to run detection?

  • Every request that can't be granted — catches deadlock instantly, but very expensive.
  • Periodically (e.g. every hour) or when CPU utilisation drops below a threshold (say 40%) — cheaper, but you can't tell which process "caused" the deadlock, since several cycles may have formed.

Recovery from deadlock

Process termination

  • Abort all deadlocked processes — guaranteed to work, very expensive (all partial computation lost).
  • Abort one at a time until the cycle breaks — less waste, but detection must re-run after each kill.

Selection criteria: process priority, how long it has computed and how much remains, resources held, resources still needed, how many processes must be terminated, and whether it is interactive or batch.

Resource preemption

  • Selecting a victim — minimise cost.
  • Rollback — the victim must return to some safe state and restart. Total rollback (abort and restart) is simplest; partial rollback needs checkpointing.
  • Starvation — the same process may always be chosen as victim. Fix: include the number of rollbacks in the cost factor.

Deadlock vs Starvation vs Livelock COMMON

DeadlockStarvationLivelock
StateBlocked foreverReady, but never scheduled/grantedRunning, but making no progress
CPU usedNoneNone (by the starved process)Yes — CPU is busy
CauseCircular waitUnfair policy / priorityProcesses keep responding to each other and retrying
Can resolve itself?NeverPossibly (with aging)Possibly (with randomised backoff)

Livelock ka best example: corridor mein do log aamne-saamne aa gaye. Ek left hata, doosra bhi left hata. Phir dono right hate. Phir dono left. Dono move kar rahe hain — par koi aage nahi badh raha. Deadlock mein dono khade hote hain; livelock mein dono naach rahe hote hain. Fix: random delay (jaise Ethernet ka exponential backoff).

0B

Memory management

Address binding se lekar fragmentation tak — paging ki neev yahin padti hai.

Address binding — when does a name become an address? COMMON

Bound atWhat happensCan the program move after loading?
Compile timeCompiler generates absolute code. If the start location changes, you must recompile.No
Load timeCompiler generates relocatable code; the loader fixes addresses when loading.No (must reload)
Execution timeBinding deferred to run time. Needs hardware support (MMU with relocation register).Yes

Aaj ke sab systems execution-time binding use karte hain, kyunki bina uske swapping, paging aur virtual memory — kuch bhi possible nahi. Isliye hardware (MMU) ki zaroorat padti hai. Ye ek line poore memory management ko justify karti hai.

Logical vs Physical address ASKED A LOT

Logical (virtual) addressPhysical address
Generated by the CPUSeen by the memory unit
What the program thinks its address isActual location in RAM
Set of all = logical address spaceSet of all = physical address space
Same in compile/load-time bindingDiffer in execution-time binding

The MMU (Memory Management Unit) is the hardware that translates one to the other at run time. In the simplest scheme, the relocation register's value is added to every logical address.

CPU ─────▶ logical addr (346) ─────▶ ┌─────────┐ ─────▶ physical addr (14346) ─────▶ Memory │ MMU │ relocation register = 14000

Ek line: "User program kabhi physical address nahi dekhta — woh sirf logical addresses banata hai, aur MMU beech mein baith kar translate karta hai." Ye protection ka bhi base hai: program physical address bol hi nahi sakta, toh kisi aur ki memory chhu bhi nahi sakta.

Contiguous allocation

Fixed (static) partitioning

Memory is divided into fixed-size partitions at boot. Each partition holds one process.

  • Equal-size partitions: simple, but a process larger than a partition can't run (needs overlays), and a small process wastes the rest of its partition.
  • Unequal-size partitions: place each process in the smallest partition that fits. Less waste, still wasteful.
  • Maximum number of active processes is fixed by the number of partitions.

Dynamic partitioning

Partitions are created at load time, exactly the size the process needs. No internal waste — but as processes come and go, memory becomes riddled with small holes.

Fragmentation ASKED A LOT

Internal fragmentationExternal fragmentation
Where the waste isInside an allocated blockBetween allocated blocks
CauseAllocated block is bigger than requestedFree memory exists but is not contiguous
Occurs inFixed partitioning, pagingDynamic partitioning, segmentation
FixSmaller block sizes (but bigger page table)Compaction, or paging

Sabse easy analogy — suitcase:

Internal fragmentation = aapne 20kg ka suitcase liya par saamaan 15kg hai. 5kg jagah suitcase ke andar khaali. Waste toh hai par aapko allot ho chuka hai.

External fragmentation = almari mein total 10kg jagah hai, par woh 5 alag-alag jagah 2-2kg karke bikhri hai. Aapko ek 6kg ka box rakhna hai — rakh nahi sakte, chahe total jagah kaafi ho.

Paging mein external fragmentation kyun nahi hoti? Kyunki koi bhi free frame kisi bhi page ke liye use ho sakta hai — contiguity ki zaroorat hi nahi. Par aakhri page aadha khaali reh jaata hai → internal fragmentation. Paging ne external ko internal se replace kar diya, aur internal chhota aur predictable hai. Yahi paging ka core selling point hai.

50% RULE

Statistical analysis of first-fit shows that given N allocated blocks, another 0.5N blocks are lost to fragmentation — i.e. about one-third of memory may be unusable. This is the "50 percent rule".

Allocation strategies COMMON

StrategyPicksSpeedNotes
First fitFirst hole big enoughFastestGood storage utilisation. Fragments the front of memory
Best fitSmallest hole that fitsSlow (searches whole list unless sorted)Leaves the smallest leftover — but those slivers are useless. Often worst in practice despite the name
Worst fitLargest holeSlowLeaves a large usable remainder. Worst utilisation overall
Next fitFirst fit, but starts from where the last search endedFastSpreads fragmentation evenly; may break up the large block at the end
Q 11.1 — SOLVED

Free memory holes, in order: 100 KB, 500 KB, 200 KB, 300 KB, 600 KB. Processes request, in order: 212 KB, 417 KB, 112 KB, 426 KB. Show the placement for First fit, Best fit and Worst fit. Which succeeds?

Show solution

First fit — scan from the start, take the first hole that fits.

RequestPlaced inHoles after
212500 → leaves 288100, 288, 200, 300, 600
417600 → leaves 183100, 288, 200, 300, 183
112288 → leaves 176100, 176, 200, 300, 183
426no hole ≥ 426must wait

Best fit — take the smallest hole that fits.

RequestPlaced inHoles after
212300 (smallest ≥ 212) → leaves 88100, 500, 200, 88, 600
417500 → leaves 83100, 83, 200, 88, 600
112200 → leaves 88100, 83, 88, 88, 600
426600 → leaves 174100, 83, 88, 88, 174

Worst fit — take the largest hole.

RequestPlaced inHoles after
212600 → leaves 388100, 500, 200, 300, 388
417500 → leaves 83100, 83, 200, 300, 388
112388 → leaves 276100, 83, 200, 300, 276
426no hole ≥ 426must wait
ANSWER

Only Best fit satisfies all four requests. First fit and Worst fit both fail on the last one. This is the standard textbook example — expect it verbatim.

Compaction, overlays, swapping

  • Compaction — shuffle allocated blocks to one end so all free memory is contiguous. Only possible with execution-time binding (otherwise addresses break). Expensive: it's a big memory-to-memory copy.
  • Overlays — keep only the instructions and data currently needed in memory; the programmer manually splits the program into overlay sections that reuse the same memory. Used before virtual memory existed. Programmer's burden — that's the whole problem with it.
  • Swapping — move an entire process out to a backing store (disk) and back. The major cost is transfer time, roughly proportional to the amount of memory swapped.

Overlays vs virtual memory: dono ka goal same hai — program RAM se bada ho sakta hai. Farq ye hai ki overlays mein programmer decide karta hai kya andar-bahar hoga, virtual memory mein OS decide karta hai, automatically. Isliye overlays mar gaye. Ye ek clean answer hai agar poochha jaaye "virtual memory se pehle kya karte the?"

Buddy system RARE

Memory is managed in blocks of size 2k. A request of size s is satisfied by the smallest power-of-two block ≥ s; larger blocks are repeatedly split in half ("buddies") until the right size is reached. On free, if a block's buddy is also free, they merge back.

1 MB request for 100 KB: 1024 ──split──▶ 512 | 512 512 ──split──▶ 256 | 256 256 ──split──▶ 128 | 128 128 ≥ 100 → allocate. Internal fragmentation = 28 KB.

Used by the Linux kernel for physical page allocation. Fast merging, but internal fragmentation can reach nearly 50%.

0C

Paging & segmentation

Numericals ka sabse bada source. Address split aur page table size wale questions pakke hain.

Paging — the core idea ASKED A LOT

  • Physical memory is divided into fixed-size blocks called frames.
  • Logical memory is divided into blocks of the same size called pages.
  • The page table maps page number → frame number. One page table per process.
  • A process's pages can sit in any frames, non-contiguously.
Logical address (from CPU) ┌────────────────┬──────────────┐ │ page number p │ offset d │ └───────┬────────┴──────┬───────┘ │ │ ▼ │ page table ┌──────────┐ │ ┌───┬────────┐ │ index │──────────┼──────▶│ p │ f │ └──────────┘ │ └───┴────────┘ │ │ ▼ ▼ ┌──────────────┬───────────┐ │ frame no. f │ offset d │ ← physical address └──────────────┴───────────┘
THE FIVE FORMULAS — WRITE THESE FROM MEMORY
Page size = Frame size = 2d   → offset needs d bits
Logical address space = 2m → logical address is m bits → page number = (m − d) bits
Number of pages = logical address space / page size
Number of frames = physical memory size / frame size
Page table size = number of pages × page table entry size

Offset kabhi nahi badalta — translation ke baad bhi wahi rehta hai. Sirf page number → frame number badalta hai. Isliye page size aur frame size hamesha barabar hote hain. Ye samajh gaye toh saare numericals aasaan.

Q 12.1 — SOLVED

A system uses 32-bit logical addresses, page size 4 KB, and each page table entry is 4 bytes. Physical memory is 1 GB.
(a) How many bits for offset and page number?
(b) How many pages and frames?
(c) What is the size of the page table per process?

Show solution

(a) Page size = 4 KB = 212 bytes → offset = 12 bits.
Logical address = 32 bits → page number = 32 − 12 = 20 bits.

┌────────────────────────┬──────────────┐ │ page number: 20 bits │ offset:12 bits│ └────────────────────────┴──────────────┘ 32 bits total

(b) Number of pages = 220 = 1,048,576 pages (≈ 1 M).
Physical memory = 1 GB = 230 bytes; frame size = 212 → number of frames = 230/212 = 218 = 262,144 frames.

(c) Page table size = 220 entries × 4 bytes = 222 bytes = 4 MB per process.

THE POINT OF THIS QUESTION

4 MB per process, and that page table must itself be in memory, contiguously. With 100 processes that's 400 MB of page tables alone. This is exactly why multilevel paging exists. Whenever an interviewer asks this, the follow-up is always "so what do we do about it?"

Frame number ke bits nikalne ka short cut: physical address bits = log₂(physical memory). Yahan 2³⁰ → 30 bits. Usme se 12 offset ke, toh frame number = 18 bits. Note karo: page number 20 bits ka hai par frame number sirf 18 ka — kyunki logical space physical se bada hai. Ye bilkul normal hai, yahi toh virtual memory ka point hai.

TLB (Translation Lookaside Buffer) ASKED A LOT

Without a TLB, every memory reference needs two memory accesses: one to read the page table, one to read the actual data. That halves performance. The TLB is a small, fast associative cache (typically 64–1024 entries) holding recent page→frame translations.

TWO EAT CONVENTIONS — READ THE QUESTION CAREFULLY

Convention A (your course slides): TLB search time is added to memory access.

EAT = h × (t + m) + (1 − h) × (t + 2m)

h = hit ratio, t = TLB search time, m = memory access time

Convention B: TLB lookup happens in parallel / is considered negligible, giving EAT = h × m + (1 − h) × 2m. If the question gives you a TLB access time, use Convention A.

Q 12.2 — SOLVED (your slide's numbers)

TLB search takes 20 ns, memory access takes 100 ns. Compute EAT for hit ratios of (a) 80% and (b) 98%.

Show solution

On a TLB hit: 20 (TLB) + 100 (memory for data) = 120 ns.
On a TLB miss: 20 (TLB, wasted) + 100 (memory for page table) + 100 (memory for data) = 220 ns.

(a) h = 0.80

EAT = 0.80 × 120 + 0.20 × 220 = 96 + 44 = 140 ns

(b) h = 0.98

EAT = 0.98 × 120 + 0.02 × 220 = 117.6 + 4.4 = 122 ns

Interpretation. Raw memory access is 100 ns. At 80% hit ratio we pay 140 ns — a 40% slowdown. At 98% we pay 122 ns — only 22%. Pushing the hit ratio from 80% to 98% recovers almost half the overhead. This is why real TLBs are aggressively optimised and why hit ratios of 99%+ are typical.

Galti jo sab karte hain: miss ke case mein log 100 + 100 = 200 likh dete hain aur TLB ka 20 ns bhool jaate hain. TLB search toh hui thi na — bas result nahi mila. Time toh laga. Isliye 220, 200 nahi. Agar question mein TLB time diya hai, toh dono cases mein add hoga.

TLB AND CONTEXT SWITCHES

On a context switch the TLB holds the old process's translations, which are wrong for the new one. Two options: flush the entire TLB (simple, but the new process starts with 100% misses), or tag each entry with an ASID (Address Space Identifier) so entries from multiple processes can coexist. ASIDs are why modern context switches don't destroy TLB performance — a good detail to mention.

Multilevel paging ASKED A LOT

Instead of one giant page table, page the page table itself.

32-bit address, 4 KB pages, two-level: ┌──────────┬──────────┬────────────┐ │ p1: 10 │ p2: 10 │ offset:12 │ └────┬─────┴────┬─────┴─────┬──────┘ │ │ │ ▼ │ │ outer page │ │ table (1024 │ │ entries) ─────┘ │ │ inner page │ └────▶ table (1024) ───┘──▶ frame
WHY THIS ACTUALLY SAVES MEMORY

The saving is not from the total table being smaller — a fully populated two-level table is slightly bigger. The saving is that inner tables for unused regions are never allocated. A real process uses a tiny fraction of its 4 GB address space (code at the bottom, stack at the top, a big hole in between), so almost all inner tables can be omitted. Only the outer table (4 KB) must always be resident.

Q 12.3 — SOLVED

Same system as Q12.1 (32-bit addresses, 4 KB pages, 4-byte PTEs). Design a two-level paging scheme and compare memory used when a process only touches 2 pages of code and 2 pages of stack.

Show solution

Design. Offset = 12 bits, leaving 20 bits for the page number. Split it 10 / 10.

Each table then has 210 = 1024 entries × 4 bytes = 4 KB — exactly one page. That's the whole reason for choosing a 10/10 split: every page table fits in exactly one frame.

Single-level: 4 MB, always, entirely resident.

Two-level:

  • Outer page table: 4 KB (always needed)
  • Code at the low end → 1 inner table: 4 KB
  • Stack at the high end → 1 inner table: 4 KB
Total = 4 KB + 4 KB + 4 KB = 12 KB   vs   4 MB single-level
Saving ≈ 99.7%

The cost: address translation now needs two page-table lookups instead of one, so a TLB miss costs 3 memory accesses (outer table + inner table + data) rather than 2.

n-level paging, TLB miss → (n + 1) memory accesses
EAT = h × (t + m) + (1 − h) × (t + (n+1)m)

Trade-off ek line mein: "Multilevel paging memory bachata hai par time kharcha karta hai. Aur us time ko TLB wapas bacha leta hai — isliye dono saath chalte hain." 64-bit systems mein 4 ya 5 levels hote hain, isliye TLB waha aur bhi zyada critical hai.

Inverted & hashed page tables RARE

Normal page tableInverted page table
One table perProcessWhole system
Number of entriesNumber of pagesNumber of frames
Entry containsFrame number<PID, page number>
LookupDirect index — O(1)Search the table for a matching <PID, page> — slow
Memory usedGrows with number of processesFixed, independent of process count
Shared memoryEasyHard — one physical frame can't map to two virtual pages in one entry

Hashed page tables handle large address spaces (>32-bit): hash the virtual page number, then walk a collision chain of ⟨virtual page, frame, next⟩ elements.

Inverted page table ko ulta socho: normal table poochhta hai "page 5 kis frame mein hai?" — direct answer. Inverted table poochhna padta hai "kya koi frame hai jisme process 3 ka page 5 pada ho?" — poori table search karni padegi. Memory bacha li, par time gaya. Isliye hash table ka use hota hai search fast karne ke liye.

Segmentation COMMON

Memory is viewed as a collection of variable-sized logical units that match the programmer's view: main program, functions, stack, symbol table, arrays. A logical address is ⟨segment number s, offset d⟩.

The segment table holds a base (starting physical address) and a limit (length) per segment. Translation: if d < limit[s] then physical = base[s] + d, else trap: addressing error.

Paging vs Segmentation ASKED A LOT

PagingSegmentation
Block sizeFixedVariable
Divided byHardware / OSThe programmer / compiler
Address formOne number, split by hardwareTwo explicit parts ⟨s, d⟩
FragmentationInternalExternal
Table entryFrame numberBase + limit
Reflects program structure?No — a function can straddle two pagesYes — one segment = one logical unit
Protection/sharingPer page — arbitrary boundariesNatural — mark a whole code segment read-only, share a library segment

Ek line mein: "Paging physical memory management ke liye hai — hardware ki soch. Segmentation logical organisation ke liye hai — programmer ki soch."

Segmentation ka asli fayda protection mein hai. Ek poora "code segment" hai — usko read-only mark kar do, bas. Paging mein aapko har page ko alag se mark karna padega, aur ek page mein aadha code aur aadha data ho sakta hai.

Isliye modern systems dono use karte hain — segmented paging. Pehle segment nikaalo, phir us segment ko paged rakho. x86 exactly yahi karta hai. Best of both: external fragmentation gayi (paging se), logical structure bachi (segmentation se).

Q 12.4 — SOLVED

Given this segment table, compute the physical address (or report an error) for logical addresses (0, 430), (1, 10), (2, 500), (3, 400), (4, 112).

SegmentBaseLimit
0219600
1230014
290100
31327580
4195296
Show solution

Rule: valid iff offset < limit; then physical = base + offset.

LogicalCheckResult
(0, 430)430 < 600 ✓219 + 430 = 649
(1, 10)10 < 14 ✓2300 + 10 = 2310
(2, 500)500 < 100 ✗TRAP — addressing error
(3, 400)400 < 580 ✓1327 + 400 = 1727
(4, 112)112 < 96 ✗TRAP — addressing error
OFF-BY-ONE

The check is strictly less than. If limit = 600, valid offsets are 0 to 599. An offset of exactly 600 is an error. Examiners plant this deliberately.

x86 segmentation — your syllabus extra RARE

The 80x86 uses segmented paging. A logical address (selector : offset) becomes a linear address via the segment unit, then a physical address via the paging unit.

  • GDT (Global Descriptor Table) — system-wide segments. Pointed to by GDTR.
  • LDT (Local Descriptor Table) — per-process segments. Pointed to by LDTR.
  • IDT (Interrupt Descriptor Table) — interrupt/exception handlers. Pointed to by IDTR.
  • A selector is 16 bits: 13-bit index + 1-bit table indicator (GDT/LDT) + 2-bit RPL.

Privilege levels (rings 0–3):

FieldMeaning
CPL — Current Privilege LevelPrivilege of the currently executing code (low 2 bits of CS)
DPL — Descriptor Privilege LevelPrivilege required to access the segment
RPL — Requested Privilege LevelPrivilege being requested by the selector — lets the kernel voluntarily weaken itself

Access rule for data segments: access is allowed only if max(CPL, RPL) ≤ DPL (numerically lower = more privileged).

RPL kyun exist karta hai? Socho: user program kernel se kehta hai "ye address padh do". Kernel ring 0 mein hai, toh woh kuch bhi padh sakta hai — including apni hi secret memory. Agar user ne chalaki se kernel ka address de diya toh? RPL se kernel khud ko jaan-boojh kar "downgrade" kar leta hai: "main ye access user ki taraf se kar raha hoon, toh user ki permission lagao." Ye confused deputy problem ka hardware-level solution hai.

0D

Virtual memory

Demand paging, page replacement numericals, thrashing. Ye section interview mein sabse zyada "depth" test karta hai.

DEFINITION

Virtual memory is the separation of the user's logical memory from physical memory. It allows a process to execute even when it is only partially in memory, so a program can be larger than physical memory.

What it buys you: programs no longer constrained by RAM size; more processes fit in memory simultaneously (higher multiprogramming, better CPU utilisation); less I/O to load or swap programs, so each user program runs faster.

Demand paging

Bring a page into memory only when it is needed (a "lazy swapper"). Each page-table entry carries a valid–invalid bit:

  • v (valid) — the page is legal and currently in memory.
  • i (invalid) — either the page is not in the process's logical address space at all, or it is legal but currently on disk.

Accessing an i page traps to the OS → page fault.

Steps in handling a page fault ASKED A LOT

  1. Reference to the page → trap to the OS.
  2. OS checks an internal table: is the reference invalid (illegal) or just not in memory? If illegal → terminate the process.
  3. Find a free frame. If none is free, run the page-replacement algorithm to pick a victim and evict it (writing it back to disk if it is dirty).
  4. Schedule a disk read to bring the desired page into that frame.
  5. Disk read completes → update the page table: set the frame number and the valid bit.
  6. Restart the instruction that was interrupted.

Step 6 hi jaadu hai. Instruction dobara chalti hai — aur ab woh successfully chalti hai. Program ko bilkul pata nahi chalta ki beech mein 8 millisecond ka disk read hua. Yahi "illusion of infinite memory" hai. Aur yahi reason hai ki CPU designers ko instruction restartable banani padti hai.

EAT with page faults ASKED A LOT

Let p = page-fault rate (0 ≤ p ≤ 1)

EAT = (1 − p) × memory_access_time + p × page_fault_service_time

page_fault_service_time ≈ trap overhead + swap page out (if dirty) + swap page in + restart overhead
Q 13.1 — SOLVED

Memory access time = 200 ns. Average page-fault service time = 8 ms.
(a) Compute EAT if the page-fault rate is 1 in 1000.
(b) What page-fault rate keeps the slowdown below 10%?

Show solution

First, put both in the same unit: 8 ms = 8,000,000 ns.

(a) p = 0.001

EAT = (1 − 0.001)(200) + 0.001(8,000,000)
     = 199.8 + 8000
     = 8199.8 ns ≈ 8.2 µs

That is a 40× slowdown from 200 ns. One fault in a thousand accesses — which sounds rare — makes the machine 40 times slower.

(b) "Less than 10% degradation" means EAT < 220 ns.

220 > (1 − p)(200) + p(8,000,000)
220 > 200 − 200p + 8,000,000p
20 > 7,999,800p
p < 20 / 7,999,800 = 0.0000025

That is fewer than 1 fault per 400,000 accesses.

WHY THIS QUESTION EXISTS

The gap between memory (nanoseconds) and disk (milliseconds) is a factor of ~40,000. So the page-fault rate must be astonishingly low for demand paging to be usable at all. Everything in this chapter — LRU, working sets, thrashing control — exists to keep p that small. If you can state this, you've understood the chapter.

Unit conversion pe hamesha dhyan do — ms aur ns mila dena is topic ki sabse common galti hai. 1 ms = 10⁶ ns. Pehle sab kuch ns mein likho, phir formula lagao.

Page replacement algorithms ASKED A LOT

When no frame is free, pick a victim. Prefer a clean (unmodified) page — no write-back needed, so half the I/O. That is what the dirty bit / modify bit is for.

1. FIFO

Evict the page that has been in memory longest. Implemented as a simple queue. Cheap, but it may evict a heavily used page just because it arrived early.

Q 13.2 — SOLVED

Reference string: 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1, with 3 frames. Count page faults for FIFO, Optimal and LRU.

Show solution

FIFO — evict the oldest arrival.

RefF1F2F3Fault?Evicted
77––✗ F—
070–✗ F—
1701✗ F—
2201✗ F7
0201✓ hit—
3231✗ F0
0230✗ F1
4430✗ F2
2420✗ F3
3423✗ F0
0023✗ F4
3023✓ hit—
2023✓ hit—
1013✗ F2
2012✗ F3
0012✓ hit—
1012✓ hit—
7712✗ F0
0702✗ F1
1701✗ F2

FIFO = 15 page faults.

Optimal (OPT / MIN) — evict the page whose next use is farthest in the future. Positions in the string are numbered 1–20.

PosRefFrames afterFault?Next-use of each resident page → evict
177F—
207 0F—
317 0 1F—
422 0 1F7→18, 0→5, 1→14 · evict 7
502 0 1hit—
632 0 3F2→9, 0→7, 1→14 · evict 1
702 0 3hit—
842 4 3F2→9, 0→11, 3→10 · evict 0
922 4 3hit—
1032 4 3hit—
1102 0 3F2→13, 4→never, 3→12 · evict 4
1232 0 3hit—
1322 0 3hit—
1412 0 1F2→15, 0→16, 3→never · evict 3
1522 0 1hit—
1602 0 1hit—
1712 0 1hit—
1877 0 1F2→never, 0→19, 1→20 · evict 2
1907 0 1hit—
2017 0 1hit—

Optimal = 9 page faults.

HOW TO DO OPT WITHOUT MISTAKES

At every fault, write down the next occurrence index of each page currently in a frame, then evict the largest. A page that never appears again always wins — evict it immediately. Don't do this in your head; the index column above is the whole method.

LRU — evict the page with the oldest last-used time.

PosRefFrames afterFault?Last-used times → evict
1–37 0 17 0 1F F Ffilling empty frames
422 0 1F7@1, 0@2, 1@3 · evict 7
502 0 1hit—
632 0 3F2@4, 0@5, 1@3 · evict 1
702 0 3hit—
844 0 3F2@4, 0@7, 3@6 · evict 2
924 0 2F4@8, 0@7, 3@6 · evict 3
1034 3 2F4@8, 0@7, 2@9 · evict 0
1100 3 2F4@8, 3@10, 2@9 · evict 4
1230 3 2hit—
1320 3 2hit—
1411 3 2F0@11, 3@12, 2@13 · evict 0
1521 3 2hit—
1601 0 2F1@14, 3@12, 2@15 · evict 3
1711 0 2hit—
1871 0 7F1@17, 0@16, 2@15 · evict 2
1901 0 7hit—
2011 0 7hit—

LRU = 12 page faults.

SUMMARY — 3 FRAMES
AlgorithmPage faults
FIFO15
LRU12
Optimal9

Ye order hamesha yahi rehta hai: OPT ≤ LRU ≤ FIFO (usually). OPT implement nahi ho sakta — future kaun jaanta hai? Woh sirf benchmark hai: "meri algorithm OPT se kitni door hai?" LRU OPT ka best practical approximation hai, kyunki past locality future ka accha predictor hai.

2. Optimal (OPT / Belady's algorithm)

Replace the page that will not be used for the longest period of time. Gives the lowest possible fault rate for a fixed number of frames. Unimplementable — requires future knowledge. Used only for comparison.

3. LRU

Approximates OPT by looking backwards: the page unused for the longest time is assumed to be the one that will stay unused longest.

Two implementations:

  • Counters — each PTE holds a "time of last use" clock value; on replacement, scan for the smallest. Requires a search plus a memory write on every memory access.
  • Stack — keep page numbers in a doubly-linked list; on reference, move that page to the top. The bottom is always the LRU victim. No search needed, but ~6 pointer updates per access.
WHY TRUE LRU ISN'T USED IN REAL SYSTEMS

Both implementations need work on every single memory reference, which means hardware support that no commodity CPU provides. So real operating systems use approximations — the clock algorithm below. Saying this converts a textbook answer into an engineering answer.

4. Second-chance / Clock algorithm COMMON

Each page has a reference bit, set by hardware on any access. Pages are arranged in a circular queue with a pointer ("clock hand").

On a page fault, examine the page at the hand: reference bit == 0 → REPLACE this page, advance hand reference bit == 1 → set it to 0, advance hand, examine next (this page got a "second chance") Worst case: the hand goes all the way around, clearing every bit, and comes back to the start — which then has bit 0 → replaced. So it degenerates to FIFO when every page is referenced.

5. Enhanced second-chance

Use the pair (reference bit, modify bit) and prefer classes in this order:

Class(r, m)MeaningPriority to evict
1(0, 0)Not recently used, not modifiedBest — evict first, no write-back
2(0, 1)Not recently used, but modifiedSecond — must write to disk
3(1, 0)Recently used, cleanThird — likely to be used again
4(1, 1)Recently used and modifiedWorst — avoid

6. Counting algorithms

  • LFU — evict the page with the smallest reference count. Problem: a page heavily used during initialisation keeps a huge count forever. Fix: shift counts right periodically (exponential decay).
  • MFU — evict the page with the largest count, arguing the smallest count means it was just brought in and hasn't had a chance yet. Neither is common in practice.

Belady's anomaly ASKED A LOT

BELADY'S ANOMALY

For some page-replacement algorithms, increasing the number of frames can increase the number of page faults. This is counter-intuitive and specific to certain algorithms — FIFO suffers from it; LRU and OPT do not.

Q 13.3 — SOLVED (the standard proof case)

Reference string 1 2 3 4 1 2 5 1 2 3 4 5. Show that FIFO gives more faults with 4 frames than with 3.

Show solution

With 3 frames:

Ref123412512345
F1111444555555
F2–22211111333
F3––3332222244
FaultFFFFFFFhithitFFhit

3 frames → 9 page faults.

With 4 frames:

Ref123412512345
F1111111555544
F2–22222211115
F3––3333332222
F4–––444444333
FaultFFFFhithitFFFFFF

4 frames → 10 page faults.

RESULT

9 faults with 3 frames, 10 faults with 4. More memory, worse performance. That's Belady's anomaly.

Why LRU and OPT are immune: they are stack algorithms — the set of pages in memory with n frames is always a subset of the set with n+1 frames. That subset property makes it impossible for a page present with n frames to be absent with n+1. FIFO does not have this property, because eviction order depends only on arrival time, which changes completely when frame count changes.

Interview answer ka structure: (1) define karo (2) bolo FIFO mein hoti hai, LRU/OPT mein nahi (3) reason bolo — stack property. Teesra point hi differentiate karta hai. Aur agar time ho toh ye exact reference string yaad rakho — 1 2 3 4 1 2 5 1 2 3 4 5 — ye standard hai.

Frame allocation

  • Minimum number of frames per process is set by the instruction set architecture — an instruction must be able to complete. If an instruction can reference two operands, each of which may straddle a page boundary, you need enough frames or the instruction can never finish (infinite fault loop).
  • Equal allocation — m frames, n processes → m/n each.
  • Proportional allocation — allocate in proportion to process size: a_i = (s_i / Σs_j) × m.
  • Priority allocation — proportional to priority, or a combination of size and priority.
Global replacementLocal replacement
Victim chosen fromAll frames in the systemOnly that process's own frames
Process performanceUnpredictable — depends on other processes' behaviourConsistent between runs
ThroughputGenerally better — commonly usedLower — a process can't grow even when free frames exist elsewhere
Thrashing riskCan spread from one process to allContained to one process

Thrashing ASKED A LOT

THRASHING

A process is thrashing when it spends more time paging than executing. It happens when a process does not have enough frames to hold its active set of pages, so it faults on almost every reference.

The vicious cycle — say this exactly

CPU utilisation is low │ ▼ OS thinks: "not enough work" → increase degree of multiprogramming │ ▼ new process needs frames → steals them from existing processes │ ▼ existing processes now have too few frames → they fault more │ ▼ faulting processes queue for the paging device → they leave the ready queue │ ▼ CPU utilisation drops FURTHER ────────┐ │ │ └──────────────────────────────┘ (the loop tightens)
CPU util │ ╭─────╮ 100% │ ╭─╯ ╰╮ │ ╭─╯ ╰──╮ ← thrashing begins │ ╭─╯ ╰───────────────╮ │╭─╯ ╰───────── └──────────────────────────────────────────────▶ degree of multiprogramming

Thrashing ka asli irony: OS ko lagta hai "CPU khaali hai, aur kaam do" — aur woh aur processes daal deta hai, jo problem ko aur bigaad deta hai. OS apni hi galti ko baar-baar dohra raha hai. Ye "positive feedback loop gone wrong" hai.

Ghar ka example: ek chhoti table pe aap 5 kitaabein le kar padh rahe ho. Table pe sirf 2 aa sakti hain. Har baar teesri chahiye toh ek hatani padti hai aur almari se laani padti hai. Aap padhne se zyada time kitaabein utha-rakh ne mein laga rahe ho. Yahi thrashing hai.

Solution ek line mein: "Degree of multiprogramming kam karo" — kuch processes suspend kar do. Counter-intuitive lagta hai (kam kaam le kar zyada kaam?) par yahi sahi hai.

Locality model

A locality is a set of pages actively used together. Processes migrate from one locality to another (e.g. entering a function pulls in its code, locals, and the globals it touches). Thrashing occurs when the sum of all localities exceeds total memory size.

Working-set model COMMON

WSi(Δ) = set of distinct pages referenced by process i in the most recent Δ page references

WSSi = working set size = |WSi(Δ)|
D = Σ WSSi = total demand for frames

If D > m (total frames) → thrashing. Policy: suspend a process.

Choosing Δ matters: too small → misses the true locality; too large → spans several localities; infinite → the entire program.

Q 13.4 — SOLVED

Reference string: … 2 6 1 5 7 7 7 7 5 1 6 2 3 4 1 2 3 4 4 4 3 4 3 4 4 4 1 3 2 3 4 4 4 3 4 4 4 … With Δ = 10, find the working set at t1 (after the first 10 references shown) and at t2 (after the next 10).

Show solution

At t1 — the window covers 2 6 1 5 7 7 7 7 5 1. Distinct pages: {1, 2, 5, 6, 7} → WSS = 5.

At t2 — the window covers 3 4 4 4 3 4 3 4 4 4. Distinct pages: {3, 4} → WSS = 2.

Interpretation. The process has moved from one locality (pages 1,2,5,6,7) to a much tighter one (pages 3,4). Between t1 and t2 it needed 5 frames; now it needs only 2. The OS can reclaim 3 frames and give them to another process.

If the OS had allocated a fixed number of frames instead, it would either be wasting frames now or have been thrashing earlier. That adaptivity is the entire value of the working-set model.

Page-fault frequency (PFF) scheme

A more direct approach: set an acceptable upper and lower bound on the page-fault rate per process.

  • Actual rate above the upper bound → the process needs more frames → allocate one.
  • Actual rate below the lower bound → it has too many → take one away.
  • If no free frames exist and someone still needs more → suspend a process and free all its frames.

Working set vs PFF: working set cause ko measure karta hai (kitne pages actually chahiye), PFF symptom ko measure karta hai (kitne faults ho rahe hain). PFF implement karna aasaan hai — bas faults gino. Isliye practical systems PFF-style feedback zyada use karte hain.

Copy-on-write & memory-mapped files

  • Copy-on-write (COW) — after fork(), parent and child share physical pages marked read-only. On the first write, the OS traps, copies just that page, and lets the write proceed. Makes fork() nearly free.
  • Memory-mapped files — map a file's blocks into the address space so file I/O becomes ordinary memory access. Multiple processes mapping the same file share the pages, giving shared memory almost for free.
  • Prepaging — bring in several pages at once to avoid a burst of faults at startup. Wasteful if the guessed pages aren't used.

Page size — the trade-off COMMON

AspectSmaller pageLarger page
Internal fragmentationLess (avg = page_size/2 per process)More
Page table sizeBigger (more pages)Smaller
I/O efficiencyWorse — seek dominates per transferBetter — amortises seek time
Locality / resolutionBetter — only what's needed is brought inWorse — brings in unused data
TLB coverageLess memory covered per entryMore — fewer TLB misses

The historical trend is toward larger pages, because memory and table sizes grew and TLB reach became the bottleneck. Modern systems also support "huge pages" (2 MB, 1 GB) alongside 4 KB pages.

0E

Disks & disk scheduling

Head movement wale numericals guaranteed hain. Access time ka formula bhi.

Disk geometry

┌─────────────────────────┐ spindle │ ╭───────────╮ │ │ │ ╭─┤ platter ├─╮ │ ← several platters on one spindle ▼ │ │ ╰───────────╯ │ │ ═══╬═══ ────────┤ │ each surface │ │ ║ │ │ has a head │ │ ║ └─────────────────────────┘ TRACK = one concentric ring on one surface SECTOR = smallest addressable unit on a track (typically 512 B or 4 KB) CYLINDER = the same track number across ALL surfaces (reading a whole cylinder needs NO head movement — just switch which head is active. That's why it matters.)

Disk access time ASKED A LOT

Disk access time = Seek time + Rotational latency + Transfer time

Seek time — move the arm to the right cylinder. Largest and most variable component.
Rotational latency — wait for the sector to spin under the head.
  Average rotational latency = ½ × (60 / RPM) seconds = time for half a rotation
Transfer time = (bytes to transfer) / (transfer rate)
  or, per track: (sectors read / sectors per track) × time for one rotation
Q 14.1 — SOLVED

A disk rotates at 7200 RPM, has an average seek time of 5 ms, 500 sectors per track, and sector size 512 bytes.
(a) Average rotational latency?
(b) Time to read one sector?
(c) Time to read a full track (500 sectors) sequentially?
(d) Time to read 500 sectors that are scattered randomly across the disk?

Show solution

(a) Rotational latency. 7200 RPM = 7200/60 = 120 rotations per second → one rotation = 1/120 s = 8.33 ms.

Average rotational latency = 8.33 / 2 = 4.17 ms

(b) One sector. Transfer time for one sector = (1/500) × 8.33 ms = 0.0167 ms.

Total = 5 (seek) + 4.17 (rot) + 0.0167 (transfer) ≈ 9.19 ms

(c) Full track sequentially. One seek, one rotational latency, then read the whole track — which takes exactly one full rotation.

Total = 5 + 4.17 + 8.33 = 17.5 ms for 500 × 512 = 256,000 bytes

(d) 500 random sectors. Every sector needs its own seek and its own rotational latency.

Total = 500 × 9.19 = 4595 ms ≈ 4.6 seconds
THE POINT

Same 256 KB of data: 17.5 ms sequential vs 4595 ms random — a 263× difference. This single number justifies disk scheduling, contiguous file allocation, defragmentation, database B-tree design, and log-structured file systems. If an interviewer asks "why does sequential I/O matter?", this calculation is the answer.

Yaad rakhne wali baat: seek time aur rotational latency data size pe depend nahi karte — chahe 1 byte padho ya poori track, seek toh utna hi lagega. Isliye bade chunks mein padhna hamesha sasta hai. Ye "amortise the seek" ka concept hai.

Disk scheduling algorithms ASKED A LOT

Goal: minimise total head movement (which minimises seek time). We'll run all six on the same input.

STANDARD SETUP FOR ALL EXAMPLES BELOW

Request queue: 98, 183, 37, 122, 14, 124, 65, 67. Head currently at 53. Disk has cylinders 0–199. Previous head direction: moving toward 0 where relevant.

Q 14.2 — SOLVED (do all six)

For the setup above, compute the total head movement for FCFS, SSTF, SCAN, C-SCAN, LOOK and C-LOOK.

Show solution

1. FCFS — serve in arrival order

53 → 98 → 183 → 37 → 122 → 14 → 124 → 65 → 67
MoveDistance
53 → 9845
98 → 18385
183 → 37146
37 → 12285
122 → 14108
14 → 124110
124 → 6559
65 → 672
Total640 cylinders

Fair, simple, but the head swings wildly (183 → 37 → 122 → 14). No optimisation at all.

2. SSTF — Shortest Seek Time First

Always go to the closest pending request.

53 → 65 → 67 → 37 → 14 → 98 → 122 → 124 → 183
MoveDistanceWhy
53 → 6512closest to 53 (65 is 12 away, 37 is 16)
65 → 672—
67 → 373037 is 30 away, 98 is 31 away
37 → 1423—
14 → 9884only requests left are above
98 → 12224—
122 → 1242—
124 → 18359—
Total236 cylinders—
SSTF PROBLEM

Starvation. A request far from the head can wait forever if new nearby requests keep arriving. Also SSTF is not optimal — moving to 37 first, then 14, then sweeping up would give 208.

3. SCAN (elevator)

Head moves in one direction serving everything, goes all the way to the end of the disk, reverses, and serves on the way back.

Moving toward 0 first: 53 → 37 → 14 → 0 → 65 → 67 → 98 → 122 → 124 → 183
Down: 53 → 0 = 53
Up: 0 → 183 = 183
Total = 53 + 183 = 236 cylinders

Note the head goes to cylinder 0 even though no request is there — that's what distinguishes SCAN from LOOK.

4. C-SCAN — Circular SCAN

Serves in one direction only. On reaching the end, it jumps back to the other end without servicing anything on the return trip.

Moving toward 199 first: 53 → 65 → 67 → 98 → 122 → 124 → 183 → 199 → [jump] → 0 → 14 → 37
Up: 53 → 199 = 146
Jump: 199 → 0 = 199
Up again: 0 → 37 = 37
Total = 146 + 199 + 37 = 382 cylinders

Why bother, if the number is worse? Because C-SCAN gives a more uniform wait time. In plain SCAN, a request just behind the head gets served twice as fast as one just in front — cylinders near the middle get served twice per sweep, edges once. C-SCAN treats the disk as circular, so every cylinder is visited at the same frequency.

5. LOOK

Like SCAN, but the head only goes as far as the last request in each direction — it doesn't run to the physical end.

53 → 37 → 14 → [reverse, no request below 14] → 65 → 67 → 98 → 122 → 124 → 183
Down: 53 → 14 = 39
Up: 14 → 183 = 169
Total = 39 + 169 = 208 cylinders

6. C-LOOK

C-SCAN without going to the physical ends.

53 → 65 → 67 → 98 → 122 → 124 → 183 → [jump to 14] → 14 → 37
Up: 53 → 183 = 130
Jump: 183 → 14 = 169
Up: 14 → 37 = 23
Total = 130 + 169 + 23 = 322 cylinders
FINAL COMPARISON
AlgorithmTotal movementStarvation?Note
FCFS640NoWorst movement, perfectly fair
SSTF236YesGreedy, not optimal
SCAN236NoGoes to cylinder 0 unnecessarily
C-SCAN382NoMost uniform wait times
LOOK208NoBest here — SCAN without wasted travel
C-LOOK322NoC-SCAN without wasted travel

Naam yaad karne ka logic — SCAN vs LOOK: "SCAN" poori disk scan karta hai — end tak jaata hai chahe wahan request ho ya na ho. "LOOK" pehle dekhta hai ki aage koi request hai kya — agar nahi, toh wahin se ghoom jaata hai. Isliye LOOK hamesha SCAN se kam ya barabar movement karta hai.

"C" ka matlab Circular — wapas aate waqt kuch serve nahi karta, seedha doosre end pe jump. Fayda: fairness, nuksaan: zyada movement.

Exam mein sabse badi galti: SCAN/C-SCAN mein disk ke end (0 aur 199) tak jaana bhool jaana, ya LOOK mein galti se end tak chale jaana. Aur direction ka assumption — agar question mein nahi bola gaya toh likh kar bolo "assuming head moves toward higher cylinders first". Examiner dono accept karta hai agar aapne assumption state ki ho.

WHEN DOES DISK SCHEDULING NOT MATTER?

On an SSD. There is no arm and no rotation, so seek time is essentially zero and there is no "closest block". SSD schedulers optimise for something completely different — write amplification, wear levelling, and merging writes into erase-block-sized chunks. Mentioning this shows you know the algorithms are tied to a specific physical mechanism.

0F

RAID

Redundant Array of Independent Disks. Levels 0–6 ka comparison table rat lo — ye directly poochha jaata hai.

The two motivations

  • Performance — striping data across disks lets several disks work in parallel.
  • Reliability — redundancy (mirroring or parity) so a disk failure doesn't lose data.
Mean Time To Failure (MTTF) of an array with no redundancy:

MTTFarray = MTTFsingle disk / N

100 disks each with MTTF 100,000 hours → array MTTF = 1000 hours ≈ 42 days

Ye number chaunkane wala hai aur yahi RAID ka reason hai. Ek disk 11 saal chalti hai, par 100 disks ka array average 42 din mein fail hoga — kyunki koi ek fail ho jaaye toh kaafi hai. Jitni zyada disks, utni jaldi failure. Isliye redundancy optional nahi, zaroori hai.

The levels

RAID 0 — striping, no redundancy

Disk0 Disk1 Disk2 Disk3 A0 A1 A2 A3 ← one logical block split across 4 disks A4 A5 A6 A7

Best performance, zero fault tolerance. Any one disk failing loses everything. Min disks: 2. Usable capacity: 100%.

RAID 1 — mirroring

Disk0 Disk1 A A ← exact copy B B

Every block written twice. Reads are fast (either copy can serve). Writes cost 2×. Usable capacity: 50%. Survives one disk failure per mirrored pair. Min disks: 2.

RAID 2 — bit-level striping with Hamming ECC

Data is striped at the bit level and protected by a Hamming code stored on dedicated parity disks. Requires spindle synchronisation. Obsolete — modern disks already do internal ECC, so the extra disks are pure overhead. This is the RAID level that uses Hamming code — see §10 for the full working.

RAID 3 — byte-level striping, single parity disk

Disk0 Disk1 Disk2 Disk3 | Parity b0 b1 b2 b3 | P = b0 ⊕ b1 ⊕ b2 ⊕ b3

One dedicated parity disk. Recovery: XOR the surviving disks. Good for large sequential transfers, poor for many small requests (every I/O touches all disks).

RAID 4 — block-level striping, dedicated parity disk

Same as RAID 3 but stripes at block level, so independent small reads can be served by individual disks. Problem: the parity disk is a bottleneck — every write must update it, so writes are serialised on that one disk.

RAID 5 — block-level striping, distributed parity ASKED A LOT

Disk0 Disk1 Disk2 Disk3 A0 A1 A2 Ap ← parity for stripe A lives on Disk3 B0 B1 Bp B3 ← parity for stripe B lives on Disk2 C0 Cp C2 C3 ← rotates Dp D1 D2 D3

Parity is spread across all disks, removing the RAID 4 bottleneck. Survives one disk failure. Usable capacity: (N−1)/N. Min disks: 3. The most widely used level.

THE WRITE PENALTY — GOOD FOLLOW-UP ANSWER

A single small write in RAID 5 costs 4 physical I/Os: read the old data block, read the old parity, write the new data block, write the new parity. New parity is computed as P_new = P_old ⊕ D_old ⊕ D_new. This "read-modify-write" penalty is why RAID 5 is poor for write-heavy workloads like OLTP databases, and why RAID 10 is often preferred there.

RAID 6 — dual distributed parity

Two independent parity blocks (P and Q, using Reed–Solomon) per stripe. Survives two simultaneous failures. Usable capacity: (N−2)/N. Min disks: 4.

RAID 6 ki zaroorat kyun padi? Disks itni badi ho gayi hain (10+ TB) ki rebuild mein kai din lagte hain. Un dino mein doosri disk fail ho jaana ab realistic hai — aur RAID 5 mein us case mein sab kuch gaya. Isliye RAID 6. Ye modern reasoning hai, textbook mein nahi hoti — bolo toh impact padta hai.

RAID 10 vs RAID 01 COMMON

RAID 10 (1+0)RAID 01 (0+1)
StructureMirror first, then stripe — a stripe of mirrored pairsStripe first, then mirror — a mirror of two stripe sets
SurvivesOne disk from each mirror pair — up to N/2 failuresOnly guaranteed against 1 failure; a second in the other stripe set kills everything
RebuildCopy from one partner disk — fastRebuild the entire stripe set — slow
PreferredYes — almost alwaysRarely used

Yaad rakhne ka tareeka: "Mirror ko andar rakho." RAID 10 mein har pair apna backup rakhta hai — ek pair ki disk gayi toh sirf woh pair affected. RAID 01 mein poora half backup hai — ek disk gayi toh poora half dead maana jaata hai. Isliye 10 > 01.

The comparison table — memorise this ASKED A LOT

LevelTechniqueMin disksUsable capacityFault toleranceReadWrite
0Striping2100%NoneExcellentExcellent
1Mirroring250%1 disk per pairVery goodFair (2 writes)
2Bit striping + Hamming3Varies1 diskGoodPoor
3Byte striping + parity disk3(N−1)/N1 diskGood (sequential)Fair
4Block striping + parity disk3(N−1)/N1 diskGoodPoor (parity bottleneck)
5Block striping + distributed parity3(N−1)/N1 diskVery goodFair (4 I/O penalty)
6Block striping + dual parity4(N−2)/N2 disksVery goodPoor (6 I/O penalty)
10Mirror + stripe450%1 per mirror pairExcellentVery good
Q 15.1

You have 8 disks of 2 TB each. Compute usable capacity for RAID 0, 1, 5, 6 and 10. Which would you choose for (a) a video editing scratch drive, (b) a bank's transaction database, (c) a cold archive?

Show solution
LevelFormulaUsableTolerates
RAID 08 × 216 TB0 failures
RAID 1 (4 pairs)8/2 × 28 TB1 per pair
RAID 5(8−1) × 214 TB1 failure
RAID 6(8−2) × 212 TB2 failures
RAID 108/2 × 28 TB1 per mirror pair

(a) Video editing scratch drive → RAID 0. Needs maximum sequential throughput and capacity; the data is temporary and re-creatable from the source footage. Losing it costs a re-import, not a disaster.

(b) Bank transaction database → RAID 10. OLTP is write-heavy with many small random writes, which is exactly where RAID 5's four-I/O write penalty hurts most. RAID 10 has no parity computation, fast rebuilds, and excellent random write performance. Paying 50% capacity is acceptable here.

(c) Cold archive → RAID 6. Reads are rare, writes rarer still, so the write penalty doesn't matter. What matters is surviving a second failure during a multi-day rebuild of large disks. RAID 6 gives 12 TB usable with two-disk tolerance.

Is tarah ke questions mein interviewer capacity number nahi, aapki reasoning dekhta hai. Hamesha teen cheezein bolo: workload (read-heavy ya write-heavy?), data ki value (re-create ho sakta hai?), aur capacity budget. Phir choice justify karo.

10

Hamming code

Error detection aur correction. Aapke slides mein RAID 2 ke context mein hai — yahan zero se poora, encode + decode dono.

Why parity alone is not enough

A single parity bit can detect an odd number of bit errors, but it cannot tell you which bit flipped — so it cannot correct anything. And it misses any even number of errors entirely.

HAMMING DISTANCE

The Hamming distance between two codewords is the number of bit positions in which they differ. Compute it as the number of 1s in their XOR.

For a code with minimum distance d:
— to detect up to s errors you need d ≥ s + 1
— to correct up to t errors you need d ≥ 2t + 1

Intuition: agar do valid codewords ke beech kam se kam 3 ka distance hai, toh ek bit flip hone par jo mila woh original ke 1 distance par hai aur kisi bhi doosre valid codeword se 2 distance par. Toh sabse nazdeek wala valid codeword hi original hai — correction possible. Isliye 1-bit correction ke liye distance 3 chahiye: 2(1)+1 = 3.

How many redundancy bits? ASKED A LOT

For m data bits and r redundancy (parity) bits:

2r ≥ m + r + 1

Total codeword length = m + r

Why that formula: the r parity bits together form an r-bit "syndrome". It must be able to name every possible single-bit error position (m + r of them) plus the "no error" case (1 more). So 2r distinct values must cover m + r + 1 outcomes.

Data bits (m)Required rCheck: 2ʳ ≥ m + r + 1Total length
124 ≥ 4 ✓3
438 ≥ 8 ✓7
7416 ≥ 12 ✓11
8416 ≥ 13 ✓12
16532 ≥ 22 ✓21
32664 ≥ 39 ✓38
647128 ≥ 72 ✓71

Trick: r ko 1 se badhate jao jab tak 2ʳ ≥ m + r + 1 na ho jaaye. Chhota r pehle try karo. Ye trial-and-error hi standard method hai — koi closed form nahi.

Where the parity bits go

RULE

Parity bits occupy positions that are powers of 2: positions 1, 2, 4, 8, 16, …. Data bits fill all remaining positions. Positions are numbered from 1, starting at the left in the standard convention (some books number from the right — the method is identical, just be consistent and say which you used).

For m = 7 data bits (d1…d7), r = 4 → total 11 positions: Position: 1 2 3 4 5 6 7 8 9 10 11 Content: P1 P2 d1 P4 d2 d3 d4 P8 d5 d6 d7 ↑ ↑ ↑ ↑ parity bits at powers of 2

Which bits does each parity bit cover? ASKED A LOT

THE BINARY RULE — THIS IS THE WHOLE TRICK

Parity bit at position 2k checks every position whose binary representation has a 1 in bit-position k. Equivalently:

  • P1 (position 1) → check 1, skip 1, check 1, skip 1, … → positions 1, 3, 5, 7, 9, 11 …
  • P2 (position 2) → check 2, skip 2, check 2, skip 2, … → positions 2, 3, 6, 7, 10, 11 …
  • P4 (position 4) → check 4, skip 4, … → positions 4, 5, 6, 7, 12, 13, 14, 15 …
  • P8 (position 8) → check 8, skip 8, … → positions 8, 9, 10, 11, 12, 13, 14, 15 …
Verify with binary for an 11-bit codeword: Pos Binary Covered by 1 0001 P1 2 0010 P2 3 0011 P1, P2 4 0100 P4 5 0101 P1, P4 6 0110 P2, P4 7 0111 P1, P2, P4 8 1000 P8 9 1001 P1, P8 10 1010 P2, P8 11 1011 P1, P2, P8 Read the columns: P1 covers all positions with bit0 = 1 → 1,3,5,7,9,11 P2 covers all with bit1 = 1 → 2,3,6,7,10,11 P4 covers all with bit2 = 1 → 4,5,6,7 P8 covers all with bit3 = 1 → 8,9,10,11

Yahi poora Hamming code ka jaadu hai, aur ise samajhna zaroori hai — rat-na nahi.

Har position ka binary number likho. Position 11 = 1011 hai, matlab usme bit0, bit1 aur bit3 set hain — toh position 11 ko P1, P2 aur P8 check karenge. Bas.

Aur decode karte waqt kya hota hai? Jo bhi parity bits fail karenge, unke position numbers jod do — wahi error ki position hai! Kyunki agar position 11 ka bit flip hua, toh exactly wahi parity bits fail karenge jo 11 ko cover karte hain — P1, P2, P8 — aur 1 + 2 + 8 = 11. Position khud bata deti hai apna naam. Ye design genius hai.

Q 16.1 — SOLVED: FULL ENCODING

Encode the 7-bit data word 1011001 using Hamming code with even parity.

Show solution

Step 1 — how many parity bits? m = 7. Try r = 4: 2⁴ = 16 ≥ 7 + 4 + 1 = 12 ✓. (r = 3 gives 8 ≥ 11 ✗.) So r = 4, total length 11.

Step 2 — lay out the data. Data bits d1…d7 = 1, 0, 1, 1, 0, 0, 1 go into non-power-of-2 positions in order.

Position1234567891011
BitP1P2d1P4d2d3d4P8d5d6d7
Value??1?011?001

Step 3 — compute each parity bit (even parity → total number of 1s must be even).

P1 covers positions 1, 3, 5, 7, 9, 11 → values ?, 1, 0, 1, 0, 1

Number of 1s among the data = 1 + 0 + 1 + 0 + 1 = 3 (odd)
For even parity, P1 = 1

P2 covers positions 2, 3, 6, 7, 10, 11 → values ?, 1, 1, 1, 0, 1

1s = 1 + 1 + 1 + 0 + 1 = 4 (even) → P2 = 0

P4 covers positions 4, 5, 6, 7 → values ?, 0, 1, 1

1s = 0 + 1 + 1 = 2 (even) → P4 = 0

P8 covers positions 8, 9, 10, 11 → values ?, 0, 0, 1

1s = 0 + 0 + 1 = 1 (odd) → P8 = 1

Step 4 — assemble the codeword.

Position1234567891011
Value10100111001
TRANSMITTED CODEWORD

1 0 1 0 0 1 1 1 0 0 1  — parity bits shown at positions 1, 2, 4, 8.

Har parity bit ke liye same 3 steps: (1) uski covered positions likho (2) un positions pe jo data bits hain unke 1s gino (3) even parity chahiye toh — count odd hai toh parity = 1, even hai toh parity = 0. Parity bit ko khud count mein mat jodo, woh toh aap set kar rahe ho.

Q 16.2 — SOLVED: FULL DECODING & CORRECTION

The receiver gets 1 0 1 0 0 1 1 1 0 1 1 (positions 1→11). Using even parity, find and correct the error.

Show solution
Position1234567891011
Received10100111011

Step 1 — recompute each parity check, this time INCLUDING the parity bit itself. For even parity, each group's total must be even. Write 0 if OK, 1 if failed.

C1 — positions 1, 3, 5, 7, 9, 11 → 1, 1, 0, 1, 0, 1

Sum of 1s = 4 → even → check passes → C1 = 0

C2 — positions 2, 3, 6, 7, 10, 11 → 0, 1, 1, 1, 1, 1

Sum of 1s = 5 → odd → check FAILS → C2 = 1

C4 — positions 4, 5, 6, 7 → 0, 0, 1, 1

Sum = 2 → even → passes → C4 = 0

C8 — positions 8, 9, 10, 11 → 1, 0, 1, 1

Sum = 3 → odd → FAILS → C8 = 1

Step 2 — build the syndrome. Read the checks as a binary number, C8 C4 C2 C1 (most significant first):

Syndrome = C8 C4 C2 C1 = 1 0 1 0 = decimal 10

Or equivalently: add the positions of the failing parity bits → 2 + 8 = 10

Step 3 — correct it. The error is in position 10. Flip that bit: 1 → 0.

Position1234567891011
Corrected10100111001

Step 4 — extract the data. Remove positions 1, 2, 4, 8:

Data bits at positions 3, 5, 6, 7, 9, 10, 11 = 1 0 1 1 0 0 1

This matches the original data word from Q16.1. ✓
THE ONE-LINE RULE TO REMEMBER

Syndrome = 0 → no error. Syndrome = k (non-zero) → the bit at position k is wrong; flip it. No lookup table, no search — the syndrome is the address of the faulty bit.

Sabse common galti decode karte waqt: encoding mein aap parity bit ko count se chhodte ho (kyunki woh abhi banana hai), par decoding mein parity bit ko count mein shaamil karte ho (kyunki woh ab receive ho chuka hai). Ye difference bhool jaana sabse badi galti hai. Encode = "kya hona chahiye", decode = "kya mila".

SEC-DED — single error correction, double error detection

Plain Hamming code corrects one error but silently mis-corrects when two errors occur (the syndrome points at some innocent third bit). Fix: add one extra overall parity bit P0 covering the entire codeword.

Overall parity P0SyndromeConclusion
Correct0No error
Wrong (odd # of errors)≠ 0Single error at the syndrome position → correct it
Correct (even # of errors)≠ 0Double error detected → cannot correct, request retransmission
Wrong0Error is in P0 itself

SEC-DED hi ECC RAM mein use hota hai. Servers mein "ECC memory" ka matlab yahi hai — ek bit flip ho toh chup-chaap theek kar do, do bit flip hon toh machine ko batao (aur usually machine check exception raise karo). Ye batana interview mein connection banata hai theory aur real hardware ke beech.

Q 16.3 — PRACTICE

(a) How many redundancy bits are needed for a 16-bit data word? (b) Encode the 4-bit data word 1011 with even parity. (c) A 7-bit Hamming codeword 1001101 is received (even parity, positions numbered 1→7 left to right). Find and correct the error.

Show solution

(a) m = 16. Try r = 5: 2⁵ = 32 ≥ 16 + 5 + 1 = 22 ✓. Try r = 4: 16 ≥ 21 ✗. So r = 5, total codeword length 21.

(b) Encoding 1011 — m = 4, so r = 3 (2³ = 8 ≥ 4 + 3 + 1 = 8 ✓). Total length 7.

Position1234567
BitP1P2d1P4d2d3d4
Value??1?011
  • P1 covers 1, 3, 5, 7 → data at 3, 5, 7 = 1, 0, 1 → two 1s (even) → P1 = 0
  • P2 covers 2, 3, 6, 7 → data at 3, 6, 7 = 1, 1, 1 → three 1s (odd) → P2 = 1
  • P4 covers 4, 5, 6, 7 → data at 5, 6, 7 = 0, 1, 1 → two 1s (even) → P4 = 0
Codeword = 0 1 1 0 0 1 1

Verify: C1 → positions 1,3,5,7 = 0,1,0,1 → sum 2 ✓ · C2 → 1,1,1,1 → sum 4 ✓ · C4 → 0,0,1,1 → sum 2 ✓. All even, so the encoding is right.

(c) Decoding 1001101.

Position1234567
Received1001101
  • C1 — positions 1, 3, 5, 7 → 1, 0, 1, 1 → sum 3, odd → fails → C1 = 1
  • C2 — positions 2, 3, 6, 7 → 0, 0, 0, 1 → sum 1, odd → fails → C2 = 1
  • C4 — positions 4, 5, 6, 7 → 1, 1, 0, 1 → sum 3, odd → fails → C4 = 1
Syndrome = C4 C2 C1 = 111 = 7   (or: 1 + 2 + 4 = 7)

Error is at position 7. Flip it: 1 → 0.

Corrected codeword = 1 0 0 1 1 0 0
Data bits (positions 3, 5, 6, 7) = 0 1 0 0
SANITY CHECK

Always re-run the parity checks on your corrected codeword. C1: positions 1,3,5,7 = 1,0,1,0 → sum 2 ✓ even. C2: 0,0,0,0 → 0 ✓. C4: 1,1,0,0 → 2 ✓. All pass — the correction is right.

11

File systems

Slides mein kam hai, par interviews mein aata hai — especially inode aur hard vs soft link.

File attributes & operations

Attributes: name, identifier (a unique number, the real name inside the FS), type, location, size, protection, timestamps.
Operations: create, write, read, reposition (seek), delete, truncate. The OS keeps an open-file table with a file pointer, open count, disk location and access rights per open file.

Allocation methods COMMON

ContiguousLinkedIndexed
LayoutBlocks in one continuous runEach block points to the nextAn index block lists all block addresses
Directory storesStart block + lengthFirst + last blockIndex block address
Sequential accessExcellentGoodGood
Direct (random) accessExcellent — O(1)Terrible — must walk the chainGood — one extra read
External fragmentationYes — the main problemNoNo
GrowthHard — may need to move the fileEasyEasy (up to index size)
Space overheadNone1 pointer per blockOne whole index block per file
ReliabilityGoodPoor — one bad pointer loses the restGood

FAT (File Allocation Table) is a variation of linked allocation: all the "next block" pointers live in one table at the start of the volume, so random access only requires walking the in-memory table rather than reading each data block.

The inode COMMON

Unix uses a multilevel indexed scheme. An inode holds metadata plus block pointers:

inode ├─ mode, owner, timestamps, link count, size ├─ 12 × DIRECT pointers ──▶ data block (small files: 1 read) ├─ 1 × SINGLE indirect ──▶ index block ──▶ data (2 reads) ├─ 1 × DOUBLE indirect ──▶ index ──▶ index ──▶ data (3 reads) └─ 1 × TRIPLE indirect ──▶ index ──▶ index ──▶ index ──▶ data (4 reads)

Design ka logic: zyadatar files chhoti hoti hain. 12 direct pointers × 4 KB block = 48 KB — matlab 48 KB tak ki file ke liye koi extra index block padhna hi nahi padta. Aur bade files ke liye indirect levels hain. Common case fast, rare case possible. Ye system design ka classic principle hai — bolo toh acchha lagta hai.

Q 17.1 — SOLVED

Block size = 4 KB, block pointer = 4 bytes, inode has 12 direct, 1 single indirect, 1 double indirect, 1 triple indirect pointer. What is the maximum file size?

Show solution

Pointers per index block = 4 KB / 4 B = 1024.

LevelBlocks addressedBytes
12 direct1212 × 4 KB = 48 KB
Single indirect10241024 × 4 KB = 4 MB
Double indirect1024² = 1,048,576≈ 4 GB
Triple indirect1024³ = 1,073,741,824≈ 4 TB
Max file size = 48 KB + 4 MB + 4 GB + 4 TB ≈ 4 TB

The triple-indirect term dominates so completely that the others are rounding errors — but write them all out; examiners want the full breakdown.

Hard link vs Soft (symbolic) link ASKED A LOT

Hard linkSoft link (symlink)
Points toThe inode directlyThe pathname (it's a small file containing a path)
Own inode?No — shares the target's inodeYes — it's a separate file
Delete the originalFile survives — link count just dropsLink becomes dangling/broken
Across filesystemsNo — inode numbers are per-filesystemYes
To a directoryNot allowed (would create cycles)Allowed
Commandln file linkln -s file link

Hard link = ek hi ghar ke do darwaze. Dono asli hain, dono se ek hi ghar mein pahunchte ho. Ek darwaza band kar do, ghar zinda hai. Ghar tabhi jaata hai jab saare darwaze band ho jaayein (link count = 0).

Soft link = ek kaagaz jispe pata likha hai. Kaagaz apne aap mein ek cheez hai. Agar ghar hi gira diya jaaye, toh kaagaz bacha rahega par uspe likha pata bekaar ho jaayega — dangling link.

Isliye rm actually "unlink" hai — woh file delete nahi karta, sirf link count ghatata hai. Count 0 hone par hi blocks free hote hain. (Aur agar koi process ne file open rakhi hai, toh woh bhi ek reference hai — isliye running program ki file delete karne par space turant free nahi hota.) Ye ek badhiya deep answer hai.

Free-space management

  • Bit vector / bitmap — one bit per block, 1 = free. Easy to find contiguous runs (scan for consecutive 1s), but the whole map must be kept in memory to be fast. For a 1 TB disk with 4 KB blocks: 228 bits = 32 MB of bitmap.
  • Linked list — each free block points to the next. No wasted space, but traversing to find n contiguous blocks requires reading each one — very slow.
  • Grouping — the first free block stores the addresses of n free blocks; the last of those points to the next group. Finds many free blocks quickly.
  • Counting — store (first free block, count of contiguous free blocks). Compact when free space is clustered.

Journaling COMMON

A crash in the middle of a multi-step update (e.g. "remove block from free list" then "add it to the file") leaves the file system inconsistent. A journaling file system first writes the intended changes to a log (journal), then applies them. After a crash, replay or discard incomplete journal entries.

  • Write-ahead logging: log first, then modify. On recovery, any transaction with a commit record is redone; any without is discarded.
  • Recovery becomes seconds instead of an hours-long fsck over the whole disk.
  • Metadata-only journaling (ext3 default) is fast but can leave stale data in files; full data journaling is safer but writes everything twice.

Journaling ka idea database ke transactions se aaya hai — atomicity. Ya toh poora change ho, ya bilkul na ho. Ek line mein: "pehle likho ki kya karne wale ho, phir karo — taaki crash ke baad pata ho ki kya adhoora reh gaya."

12

Formula sheet

Interview se ek raat pehle sirf ye page dekh lena kaafi hai.

Scheduling

Turnaround Time = Completion − Arrival
Waiting Time = Turnaround − Burst
Response Time = First CPU allocation − Arrival
Throughput = processes completed / total time

RR: max wait ≤ (n − 1) × q  ·  context switches ≈ Σ⌈BTᵢ/q⌉ − 1
RR overhead fraction = switch_time / (q + switch_time)
HRRN Response Ratio = (W + S) / S
SJF burst prediction: τₙ₊₁ = α·tₙ + (1−α)·τₙ

Memory & paging

Page size = Frame size = 2d → offset = d bits
Logical address = m bits → page number = (m − d) bits
Number of pages = logical space / page size
Number of frames = physical memory / frame size
Page table size = number of pages × PTE size

EAT with TLB (TLB time counted): EAT = h(t + m) + (1 − h)(t + 2m)
EAT, n-level paging: EAT = h(t + m) + (1 − h)(t + (n+1)m)
EAT with page faults: EAT = (1 − p)·m + p·(fault service time)

Avg internal fragmentation per process ≈ page_size / 2

Deadlock

Need = Max − Allocation
Available = Total − Σ Allocation
Safety check: find i with Need[i] ≤ Work → Work += Allocation[i]

n processes, each needing max k instances of one resource type:
deadlock-free ⟺ m ≥ n(k − 1) + 1
deadlock possible ⟺ m ≤ n(k − 1)

Disk

Access time = Seek + Rotational latency + Transfer
One rotation = 60 / RPM seconds
Avg rotational latency = ½ × (60 / RPM)
Transfer time = data size / transfer rate
  or = (sectors read / sectors per track) × rotation time

Head movement: sum of |current − next| over the schedule
SCAN goes to cylinder 0 / max; LOOK does not

RAID & Hamming

MTTF(array, no redundancy) = MTTF(disk) / N
RAID 0 usable = N  ·  RAID 1 & 10 = N/2
RAID 5 = N − 1  ·  RAID 6 = N − 2
RAID 5 small-write penalty = 4 physical I/Os

Hamming: 2r ≥ m + r + 1
Parity bits at positions 1, 2, 4, 8, 16 … (powers of 2)
Pᵢ at position 2k covers positions with bit k set
Syndrome = Σ (positions of failing parity checks) = error position
Detect s errors: d ≥ s + 1  ·  Correct t errors: d ≥ 2t + 1

File systems

Pointers per index block = block size / pointer size = P
Max file size = (direct × B) + (P × B) + (P² × B) + (P³ × B)
Bitmap size = disk size / block size, in bits
13

Rapid-fire Q&A

50 questions, one-paragraph answers. Ye woh hain jo actually poochhe jaate hain — bol kar practice karo, padh kar nahi.

Processes & threads

RF 1

What is the difference between a process and a thread?

Show answer

A process is an independent program in execution with its own address space; a thread is a unit of execution within a process. Threads of one process share code, data, heap and open files, but each has its own stack, registers and program counter. Consequences: thread creation and context switching are cheaper (no address-space change), thread communication is just shared memory, but there is no isolation — one thread crashing takes the whole process down, and shared data needs explicit synchronisation.

RF 2

What does a context switch save?

Show answer

The program counter, stack pointer, general-purpose registers, processor status word, and memory-management state (page table base register or base/limit) — all written into the outgoing process's PCB, then loaded from the incoming one. The bigger cost is usually indirect: cache pollution, TLB flush (unless ASID-tagged), and cold branch predictors. During a switch, zero useful work happens.

RF 3

Difference between a mode switch and a context switch?

Show answer

A mode switch changes the CPU privilege level (user ↔ kernel) but the same process continues — this is what a system call does. A context switch changes which process is running, requiring PCB save/restore and scheduler involvement. Every context switch involves a mode switch, but not vice versa. Mode switches cost hundreds of nanoseconds; context switches cost microseconds plus cache effects.

RF 4

Can a process have zero threads?

Show answer

No. A process is defined by having at least one thread of execution — the main thread. If the main thread exits, the process terminates. A process with zero threads has nothing to execute, so it would be indistinguishable from a terminated process.

RF 5

Why is fork() followed by exec() rather than a single "spawn" call?

Show answer

The gap between fork and exec gives the child a window to configure its environment while it is still a copy of the parent — redirect file descriptors (this is how shell redirection and pipes work), change the working directory, drop privileges, set signal handlers. A single spawn call would need dozens of parameters to express all of that. Copy-on-write makes the seemingly wasteful copy nearly free.

RF 6

How do you kill a zombie process?

Show answer

You can't — it is already dead; kill -9 has no effect since there is no running code to signal. The zombie exists only as a PCB entry holding an exit status. It disappears when the parent calls wait(). If the parent is buggy and never does, kill the parent: the zombie is then re-parented to init (PID 1), which reaps it automatically.

Scheduling

RF 7

Which scheduling algorithm gives minimum average waiting time?

Show answer

SJF (and its preemptive form SRTF) is provably optimal for average waiting time. It's not usable directly because burst times aren't known in advance; systems approximate it with exponential averaging of past bursts, or observe behaviour dynamically via MLFQ. SJF also risks starving long jobs, which HRRN and aging address.

RF 8

What is the convoy effect?

Show answer

Under FCFS, one long CPU-bound process holds the CPU while many short I/O-bound processes queue behind it. Average waiting time balloons, but the worse problem is that all the I/O devices sit idle during that time, because the processes that would drive them are stuck in the ready queue. Utilisation drops across the whole system, not just the CPU.

RF 9

How do you choose the Round Robin time quantum?

Show answer

It must be large relative to the context-switch time or overhead dominates (0.1 ms switch with 1 ms quantum wastes ~9% of the CPU), and small enough that response time stays interactive. The standard rule of thumb: pick q so that roughly 80% of CPU bursts complete within one quantum. Typical values are 10–100 ms. If q exceeds the longest burst, RR degenerates to FCFS.

RF 10

What is aging?

Show answer

Gradually increasing the priority of processes that have been waiting a long time, so a low-priority process cannot be starved indefinitely by a stream of high-priority arrivals. It converts an unbounded wait into a bounded one. HRRN builds aging directly into its formula, since the response ratio grows with waiting time.

Synchronisation

RF 11

Mutex vs semaphore?

Show answer

A mutex is a locking mechanism with ownership — only the thread that locked it may unlock it, which enables priority inheritance. A semaphore is a signalling mechanism with a counter and no ownership — any thread may signal, and the classic use is one thread notifying another that an event occurred. A binary semaphore looks like a mutex but lacks ownership semantics.

RF 12

What are the three requirements of a critical-section solution?

Show answer

Mutual exclusion (only one process in its critical section at a time), progress (if the critical section is free, a process wanting to enter must be able to, and the decision can't be postponed indefinitely), and bounded waiting (a bound on how many times others can enter before a waiting process gets its turn). Most broken solutions fail progress, not mutual exclusion.

RF 13

What is a spinlock and when should you use one?

Show answer

A lock where a waiting thread busy-waits in a loop instead of blocking. It wastes CPU while spinning, but avoids the two context switches that blocking costs. Use it when the lock is held for a very short time and you have multiple cores (on a uniprocessor, spinning can never succeed — the lock holder isn't running). Kernel code uses spinlocks heavily for short critical sections.

RF 14

What is priority inversion?

Show answer

A high-priority thread is blocked waiting on a lock held by a low-priority thread, and a medium-priority thread preempts the low-priority one — so effectively the high-priority thread waits behind a medium-priority one. The fix is priority inheritance: temporarily raise the lock holder's priority to that of the highest waiter. This requires knowing the owner, which is why it works with mutexes but not semaphores. The 1997 Mars Pathfinder resets were caused by exactly this.

RF 15

What is a monitor, and how does it differ from a semaphore?

Show answer

A monitor is a language-level construct in which only one process can be active inside at a time, with mutual exclusion supplied automatically by the compiler. Semaphores are low-level and require the programmer to place every wait and signal correctly. One behavioural difference matters: a semaphore remembers a signal (the counter increments even with no waiter), whereas a condition variable's signal is lost if nobody is waiting — which is why you always use while (cond) wait(); rather than if.

Deadlock

RF 16

What are the four conditions for deadlock, and can you break just one?

Show answer

Mutual exclusion, hold and wait, no preemption, and circular wait. All four must hold simultaneously, so breaking any single one prevents deadlock. In practice, circular wait is the one that is broken — by imposing a global ordering on resource acquisition. That's why kernel code documents lock ordering.

RF 17

Does a cycle in a resource allocation graph always mean deadlock?

Show answer

Only if every resource type in the cycle has a single instance. With multiple instances, a cycle is a necessary but not sufficient condition — an instance held by a process outside the cycle may be released and break it. No cycle, however, always means no deadlock.

RF 18

Is an unsafe state the same as a deadlocked state?

Show answer

No. Unsafe means deadlock is possible if every process demands its maximum claim; it does not mean deadlock has occurred or will occur. Every deadlocked state is unsafe, but not every unsafe state is deadlocked. Deadlock avoidance is conservative — it refuses requests that would lead to unsafe states even though those states might have been fine.

RF 19

Why do real operating systems ignore deadlock?

Show answer

Because prevention and avoidance impose a cost on every resource request — restricted request patterns, lower utilisation, runtime safety checks — while deadlocks are rare. Linux and Windows use the "ostrich algorithm": assume it won't happen, and if the system hangs, the user reboots. The economics favour a rare reboot over a permanent tax. Databases, where a deadlock is likely and a rollback is cheap, do use detection and recovery.

RF 20

Deadlock vs starvation vs livelock?

Show answer

Deadlock: processes blocked forever in a circular wait; no CPU used; never resolves itself. Starvation: a process is runnable but never gets scheduled or granted a resource due to an unfair policy; fixable with aging. Livelock: processes are actively running and changing state in response to each other, but making no progress — CPU is busy, work is zero. Randomised backoff typically resolves livelock.

Memory

RF 21

Internal vs external fragmentation?

Show answer

Internal fragmentation is unused space inside an allocated block, because the block is larger than requested — it occurs with fixed partitions and with paging (the last page of a process is partly empty). External fragmentation is free memory that exists but is scattered in non-contiguous holes, so a large request fails despite sufficient total free space — it occurs with dynamic partitioning and segmentation. Compaction fixes external fragmentation; paging avoids it entirely.

RF 22

Why does paging eliminate external fragmentation?

Show answer

Because a process's pages don't need contiguous frames — any free frame will do for any page. Contiguity was the reason free space had to be in one usable run. The trade-off is that the last page of each process is usually partly empty, giving internal fragmentation of about half a page per process, which is small and predictable.

RF 23

What is a TLB and why does it matter so much?

Show answer

A small associative cache of recent page-number → frame-number translations. Without it, every memory reference needs an extra memory access to read the page table, halving performance — and with multilevel paging it's worse (n+1 accesses). Hit ratios above 99% are typical because of locality. On a context switch the TLB must be flushed or tagged with an ASID, which is why ASIDs matter for switch cost.

RF 24

Why multilevel paging?

Show answer

A single-level page table for a 32-bit address space with 4 KB pages and 4-byte entries is 4 MB per process, and must be contiguous in memory. Multilevel paging lets you omit inner tables for unused regions of the address space — and real processes use a tiny fraction of theirs. The cost is one extra memory access per level on a TLB miss.

RF 25

Paging vs segmentation?

Show answer

Paging uses fixed-size blocks decided by hardware and is invisible to the programmer; it solves physical memory management and causes internal fragmentation. Segmentation uses variable-size blocks that match logical program units (code, stack, data) and is visible to the programmer; it enables natural protection and sharing but causes external fragmentation. Modern systems combine both — segmented paging.

RF 26

What is demand paging?

Show answer

Loading a page into memory only when it is actually referenced, rather than loading the whole program up front. Pages not in memory are marked invalid; touching one causes a page fault, the OS fetches it from disk and restarts the faulting instruction. This lets a program larger than physical memory run, and lets more processes fit in memory.

RF 27

What is Belady's anomaly?

Show answer

The counter-intuitive situation where increasing the number of frames increases the number of page faults. It affects FIFO but not LRU or Optimal, because those are stack algorithms: the set of pages resident with n frames is always a subset of the set with n+1 frames, which makes the anomaly impossible. The standard demonstration string is 1 2 3 4 1 2 5 1 2 3 4 5 — 9 faults with 3 frames, 10 with 4.

RF 28

Why isn't true LRU implemented in real systems?

Show answer

Both implementations — timestamp counters and a stack of page numbers — require work on every single memory reference, which needs hardware support that commodity CPUs don't provide. So systems use approximations based on a hardware-maintained reference bit: the clock (second-chance) algorithm, or enhanced clock using both reference and modify bits.

RF 29

What is thrashing and how do you fix it?

Show answer

A process spends more time paging than executing, because it doesn't have enough frames to hold its active locality. It's self-reinforcing: low CPU utilisation makes the OS admit more processes, which steals more frames, which causes more faults. The fix is counter-intuitive — reduce the degree of multiprogramming by suspending processes. The working-set model sizes each process's frame allocation to its locality; the page-fault-frequency scheme adjusts allocation based on measured fault rate.

RF 30

What is copy-on-write?

Show answer

After fork(), parent and child share the same physical pages, all marked read-only. The first write by either triggers a protection fault; the OS then copies just that one page and lets the write proceed. This makes fork nearly free, which matters because the child usually calls exec() immediately and would have discarded a full copy anyway.

Storage & I/O

RF 31

What are the components of disk access time?

Show answer

Seek time (moving the arm to the right cylinder — largest and most variable), rotational latency (waiting for the sector to arrive under the head, averaging half a rotation), and transfer time (actually reading the bytes). Only transfer time scales with data size, which is why large sequential transfers are dramatically more efficient than many small random ones.

RF 32

SCAN vs LOOK vs C-SCAN?

Show answer

SCAN sweeps to the physical end of the disk, reverses, and services on the way back. LOOK is the same but only travels as far as the last request in each direction, so it never wastes movement. C-SCAN services in one direction only and jumps back to the far end without servicing, which gives more uniform wait times at the cost of extra head movement. C-LOOK is C-SCAN without the trip to the physical end.

RF 33

What's wrong with SSTF?

Show answer

It can starve requests far from the current head position, because newly arriving nearby requests always win. It's also greedy, not optimal — choosing the locally nearest request can produce a worse total than a planned sweep. On the standard example (queue 98 183 37 122 14 124 65 67, head at 53), SSTF gives 236 cylinders while LOOK gives 208.

RF 34

Why is RAID 5 bad for write-heavy workloads?

Show answer

Each small write requires four physical I/Os: read the old data block, read the old parity, write the new data, write the new parity (computed as old parity XOR old data XOR new data). For random-write-heavy workloads like OLTP databases this is a severe penalty, which is why RAID 10 — which has no parity computation and rebuilds from a single partner disk — is usually preferred there.

RF 35

Why does RAID 6 exist if RAID 5 already tolerates a failure?

Show answer

Because modern disks are large enough that rebuilding a failed drive takes many hours or days, and the rebuild itself stresses every remaining disk. A second failure during that window is realistically likely, and in RAID 5 that means total data loss. RAID 6's dual parity survives two simultaneous failures at the cost of one more disk of capacity and a heavier write penalty.

RF 36

Which RAID level uses Hamming code, and why is it obsolete?

Show answer

RAID 2 — bit-level striping with Hamming ECC on dedicated parity disks. It's obsolete because modern disk drives already perform their own internal error detection and correction on every sector, so the array-level Hamming code is redundant overhead. It also required spindle synchronisation across drives. Parity-based levels (3–6) achieve the same fault tolerance with far fewer disks.

RF 37

Hard link vs soft link?

Show answer

A hard link is another directory entry pointing at the same inode; the file survives until the link count reaches zero, but hard links can't cross filesystems or point to directories. A soft link is a separate file whose contents are a pathname; it can cross filesystems and point to directories, but breaks (dangles) if the target is removed. This is why rm is really unlink — it decrements a count rather than deleting data.

RF 38

Why does the Unix inode use direct plus indirect pointers?

Show answer

Most files are small. Twelve direct pointers cover ~48 KB with 4 KB blocks, so small files need no extra index reads at all. Indirect, double-indirect and triple-indirect pointers extend the maximum file size to terabytes, at the cost of one extra read per level — but only for the rare large file. It's the "optimise the common case, keep the rare case possible" principle.

RF 39

What does journaling protect against?

Show answer

Filesystem inconsistency after a crash that interrupts a multi-step metadata update. The intended changes are written to a log first (write-ahead logging); after a crash, committed transactions are replayed and uncommitted ones discarded. Recovery takes seconds instead of a full-disk fsck. Metadata-only journaling is faster; full data journaling is safer but writes everything twice.

Fundamentals

RF 40

Interrupt vs trap vs system call?

Show answer

An interrupt is asynchronous and comes from hardware (keyboard, disk, timer). A trap/exception is synchronous and caused by the executing instruction itself (divide by zero, page fault). A system call is a synchronous, deliberate request by the program for a kernel service. All three use the same underlying mechanism — save state, switch to kernel mode, dispatch through a vector table — only the trigger differs.

RF 41

What is DMA and what does it save?

Show answer

Direct Memory Access lets a controller transfer data between a device and memory without the CPU moving each byte. The CPU sets up the transfer and gets one interrupt per block instead of one per byte or word. It's essential for high-throughput devices like disks and network cards. The DMA controller "steals" memory bus cycles from the CPU, which slows it slightly — far less than per-byte interrupt handling would.

RF 42

What is dual-mode operation and why is it needed?

Show answer

A hardware mode bit distinguishes kernel mode from user mode. Certain instructions — I/O, setting the timer, loading base/limit or page-table registers, changing the mode bit — are privileged and trap if attempted in user mode. Without it, any user program could perform I/O directly, disable the timer to hog the CPU, or read other processes' memory, so all protection would collapse.

RF 43

Monolithic vs microkernel?

Show answer

A monolithic kernel puts the file system, drivers, networking and scheduler in one address space, so they call each other as function calls — fast, but a bug in any component can crash the system. A microkernel keeps only IPC, scheduling and basic memory management in the kernel and pushes everything else into user-space servers — reliable and extensible, but each service request becomes message passing with several mode switches, so it is slower. Linux is monolithic but modular; Windows NT and macOS are hybrids.

RF 44

Multiprogramming vs multitasking vs multiprocessing?

Show answer

Multiprogramming keeps several jobs in memory and switches when the running one blocks for I/O — the goal is CPU utilisation. Multitasking (time sharing) adds a time quantum so switching also happens on a timer — the goal is response time. Multiprocessing means the system has more than one CPU or core, giving true parallelism. The first two are about one CPU; the third is about several.

RF 45

What is spooling and what did it enable?

Show answer

Simultaneous Peripheral Operation On-Line — using disk as a buffer so a slow device (printer) doesn't block the CPU. Its deeper significance is that it created a job pool on disk: instead of running jobs in the fixed order they sat on tape, the OS could now choose any job. That choice is what made job scheduling possible in the first place.

RF 46

What are the three schedulers?

Show answer

Long-term decides which jobs are admitted, controlling the degree of multiprogramming; it runs infrequently and aims for a good mix of CPU-bound and I/O-bound jobs. Medium-term swaps processes out to disk and back, reducing multiprogramming when memory is tight. Short-term (CPU scheduler) picks which ready process runs next; it runs every few milliseconds and must be fast.

RF 47

Difference between the scheduler and the dispatcher?

Show answer

The scheduler is policy — it decides which process should run. The dispatcher is mechanism — it performs the context switch, switches to user mode, and jumps to the correct location in the program. The time the dispatcher takes is called dispatch latency, and it must be minimal since it is pure overhead.

RF 48

Real-time systems — hard vs soft?

Show answer

In a hard real-time system, missing a deadline is a system failure (airbag controller, pacemaker) — so virtual memory is usually disallowed because a page fault introduces unpredictable delay. In a soft real-time system, a missed deadline degrades quality but the system continues (video playback, VoIP). The key insight: real-time means predictable, not fast. A system that always takes exactly 50 ms is real-time; one that usually takes 1 ms but sometimes 200 ms is not.

RF 49

What is the working set model?

Show answer

The working set WS(Δ) is the set of distinct pages a process referenced in its most recent Δ references — an approximation of its current locality. If the sum of all processes' working set sizes exceeds available frames, the system will thrash, so the OS suspends a process. It's adaptive: as a process moves between localities, its working set shrinks or grows and frames can be reallocated accordingly.

RF 50

Why is a page fault recoverable but a divide-by-zero usually isn't?

Show answer

Both are synchronous traps, but a page fault has a defined remedy: fetch the page from disk, fix the page table entry, and re-execute the same instruction, which then succeeds transparently. A divide-by-zero has no such remedy — the OS delivers SIGFPE and the process typically dies. The restartability requirement puts a real constraint on CPU design: a faulting instruction must be re-executable with no partial side effects.

14

7-day plan

Agar time kam hai, is order mein padho. Har din 2–3 ghante.

DaySectionsWhat to actually do
1§01–§03 + §04Read through. Then draw the process memory layout and the 5-state diagram from memory on paper. Do all fork() questions.
2§06 CPU schedulingSolve every Gantt chart question with the solution hidden. Redo any you got wrong the next morning.
3§07–§08Write the producer-consumer code from memory. Explain out loud why swapping the waits deadlocks.
4§0A DeadlocksDo the Banker's example twice — once reading, once blind. Memorise m ≥ n(k−1)+1.
5§0B–§0CAll address-split and page-table-size numericals. Do the EAT calculations until they're automatic.
6§0D Virtual memoryRun the 20-reference string through FIFO, LRU and OPT yourself. Then do Belady's anomaly.
7§0E–§10 + §12–§13Disk scheduling (all six), RAID table, one Hamming encode + one decode. Then the whole rapid-fire section out loud.
IF YOU ONLY HAVE ONE DAY
  1. §12 Formula sheet — read it twice
  2. §13 Rapid-fire — all 50, spoken aloud
  3. Process memory layout, 5-state diagram, 4 deadlock conditions, mutex vs semaphore — these four come up most
  4. One Gantt chart, one Banker's, one page replacement, one disk scheduling — just to keep the mechanics warm

Do practical tips jo actually farak paate hain:

1. Bol kar practice karo. OS ka interview zubaani hota hai. Padh kar sab samajh aata hai, par bolte waqt atak jaate ho. Har concept ko 60 second mein bina dekhe explain karne ki practice karo — apne aap se, deewar se, kisi se bhi.

2. Numericals mein table banao, mental math mat karo. Gantt chart, Banker's, page replacement — teeno mein log isliye galti karte hain ki woh dimaag mein calculate karne lagte hain. Kaagaz pe column banao. Interviewer ko bhi accha lagta hai jab aap structured dikhte ho.

3. "Pata nahi" bolna theek hai — par uske baad rukna nahi. "Exact algorithm yaad nahi hai, par idea ye hai ki…" — ye answer poore silence se kaafi behtar hai. OS mein bahut kuch hai, sab yaad rakhna possible nahi.