All Blog Posts

Every article published on Tanveer Qureshie Tech, newest first.

Loading all posts...

Operating Systems Interview Preparation — Top 50 Questions By Tanveer Qureshie

Compiled & Designed by Tanveer Qureshie

Operating Systems Interview Guide

50 in-depth Operating Systems interview questions with easy-to-understand explanations, comparison tables, visual diagrams and real examples, covering process management, CPU scheduling, synchronization and deadlocks, memory management and virtual memory, and file systems, I/O and disk management. Tick each question off as you master it.

50 QuestionsBasic to AdvancedComparison TablesVisual DiagramsTick to Track Progress
YOUR PROGRESS0 / 50 questions completed (0%)
SECTION 01

OS Fundamentals & Process Management

0 / 10 done
VISUAL MODEL

The Process Lifecycle

NewReadyRunningWaitingTerminated

A process moves between these states as the OS scheduler manages CPU time. Running can go back to Ready (preempted) or to Waiting (blocked on I/O) before eventually finishing at Terminated — it's rarely a straight line.

001What is an operating system, and what are its core responsibilities?Beginner+

Easy explanation

An operating system is the software layer that sits between the raw computer hardware and the applications running on it — it manages hardware resources (CPU, memory, storage, devices) on behalf of programs, so application developers don't have to write low-level hardware-control code themselves.

Its core responsibilities include process management (deciding which program runs when), memory management (allocating and protecting memory between programs), file system management (organizing data on storage), device management (coordinating input/output hardware), and providing security/access control so programs and users can't interfere with each other's data.

Interview tip: A clean one-line summary for an interview: the OS is a 'resource manager' that also provides a consistent interface (system calls) for programs to use hardware safely.
002What is the difference between a process and a program?Beginner+

Easy explanation

A program is a passive, static entity — it's just executable code and data sitting on disk (like an .exe file), not doing anything on its own until it's actually launched. A process is an ACTIVE, running instance of a program — it has its own memory space, current execution state, and system resources allocated to it.

The same program can be launched multiple times, creating multiple independent processes — opening two browser windows runs the same program code but creates two separate processes, each with its own memory, open files, and current state, completely isolated from each other by the OS.

Interview tip: A common analogy: a program is like a recipe (static instructions); a process is like actually cooking that recipe right now (an active instance with its own ingredients and state).
003What is the difference between user mode and kernel mode?Beginner+

Easy explanation

User mode is a restricted CPU execution mode where regular application programs run — code executing in user mode cannot directly access hardware or execute privileged instructions; it must ask the OS to do so on its behalf. Kernel mode is a privileged execution mode where the OS itself runs, with full, unrestricted access to all hardware and memory.

This separation exists specifically for STABILITY and SECURITY — if a buggy or malicious application could directly manipulate hardware or another process's memory, one bad program could crash the entire system or compromise other programs' data. When a user-mode program needs a privileged operation (like reading a file), it makes a system call, which temporarily switches the CPU into kernel mode to perform that specific operation safely, then switches back.

Interview tip: None
User modeKernel mode
Hardware accessRestricted — must ask via system callsFull, direct access
Who runs hereApplicationsThe OS kernel
Crash impactUsually just that one programCan crash the whole system
004What is a system call, and how does an application actually use one?Beginner+

Easy explanation

A system call is the mechanism a user-mode program uses to request a service from the OS kernel — like reading a file, creating a new process, or sending data over the network — since these operations require privileged access the application itself isn't allowed to perform directly.

When a program invokes a system call (often through a library function like `read()` or `open()`), the CPU switches from user mode into kernel mode, the OS performs the requested operation, and then control (along with any results) is handed back to the application, switching the CPU back to user mode — this mode-switching has real overhead, which is why excessive, unnecessary system calls can noticeably slow a program down.

Interview tip: None
// a simple system call from a C program
int fd = open("file.txt", O_RDONLY);  // triggers a mode switch into the kernel
read(fd, buffer, 100);
close(fd);
005What information does a Process Control Block (PCB) store, and why does the OS need one per process?Intermediate+

Easy explanation

A Process Control Block is a data structure the OS maintains for EVERY process, holding all the information needed to manage and eventually resume that process — including its current state (running/ready/waiting), its process ID, saved CPU register values, memory allocation details, open file lists, and scheduling priority.

The PCB is essential because the OS is constantly switching between many processes — when a process is paused (context switched out), its exact CPU register state must be saved somewhere so it can be perfectly restored later, resuming exactly where it left off as if it had never been interrupted at all; the PCB is where all of this bookkeeping lives.

Interview tip: None
PCB fieldPurpose
Process ID (PID)Uniquely identifies the process
Process stateNew/Ready/Running/Waiting/Terminated
CPU registersSaved so execution can resume exactly where it left off
Memory infoBase/limit registers, page tables
Open file listWhich files/resources this process has open
006What is a context switch, and why does it have a real performance cost?Intermediate+

Easy explanation

A context switch is the process of saving the current state (registers, program counter, memory mappings) of a currently-running process into its PCB, and loading the saved state of a DIFFERENT process to let it run instead — this is exactly what lets a single CPU core give the illusion of running many programs at once.

Context switches aren't free — they consume CPU cycles that could otherwise be spent running actual application code, and they also often invalidate the CPU's cache (data the previous process had 'warmed up' in fast cache memory has to be reloaded for the new process), causing a temporary performance dip right after the switch. This is why an OS scheduler tries to balance responsiveness (switching often enough to feel fair and interactive) against throughput (not switching so often that overhead dominates).

Interview tip: None
007What is the difference between a process and a thread?Intermediate+

Easy explanation

A process has its own completely independent memory space — two processes cannot directly access each other's memory without explicit inter-process communication mechanisms, giving strong isolation but making communication and creation more expensive. A thread is a lighter-weight unit of execution that exists WITHIN a process, and all threads in the same process SHARE that process's memory space (code, data, open files) but each thread has its own separate stack and register state.

Because threads share memory, creating a thread and switching between threads is significantly cheaper than doing the same for a whole process, and threads can communicate with each other simply by reading/writing shared memory directly — but this shared access also means one thread's bug (like corrupting shared data) can more easily affect other threads in the same process, unlike the strong isolation between separate processes.

Interview tip: None
ProcessThread
MemoryIndependent, isolatedShared within the same process
Creation costHigherLower
CommunicationRequires IPC mechanismsDirect shared-memory access
Crash isolationOne process crashing doesn't affect othersOne thread crashing can bring down the whole process
008What is multithreading, and what are its main benefits and risks?Intermediate+

Easy explanation

Multithreading lets a single process run multiple threads concurrently, sharing the same memory space — this is useful for taking advantage of multiple CPU cores (true parallelism) or for keeping a program responsive while some threads wait on slow operations like I/O, letting other threads keep doing useful work in the meantime.

The main risk is that shared memory access between threads must be carefully coordinated — if two threads read and write the same shared data without proper synchronization, you can get race conditions (unpredictable results depending on timing) or data corruption. This is exactly why synchronization primitives like locks, semaphores, and mutexes exist — to safely coordinate access to shared resources between concurrently-running threads.

Interview tip: If asked for a real use case, mention a web server handling many client connections concurrently using a thread (or thread pool) per connection, or a UI application keeping its interface responsive while a background thread does slow work.
009What is an interrupt, and how does interrupt-driven I/O differ from polling?Advanced+

Easy explanation

An interrupt is a signal sent to the CPU (by hardware or software) indicating that some event needs immediate attention — when an interrupt occurs, the CPU pauses whatever it's currently doing, saves its state, runs a special Interrupt Service Routine (ISR) to handle the event, and then resumes the original work exactly where it left off.

Polling is the alternative approach where the CPU repeatedly CHECKS a device's status in a loop to see if it's ready, wasting CPU cycles on checks that usually find 'not ready yet'. Interrupt-driven I/O is far more efficient because the CPU can do other useful work and only gets interrupted the MOMENT the device actually has something ready — this is exactly why modern hardware (keyboards, disks, network cards) relies overwhelmingly on interrupts rather than polling for routine operations.

Interview tip: None
PollingInterrupt-driven
CPU usage while waitingWasted, actively checkingFree to do other work
ResponsivenessDepends on poll frequencyImmediate, event-driven
010What is the difference between a system call and a library function call, and why does a mode switch matter for performance?Advanced+

Easy explanation

A library function call (like a simple math function) executes entirely in user mode, using only the CPU cycles the process is already allowed — no privilege escalation, no mode switch, and generally very fast. A system call requires the CPU to switch INTO kernel mode temporarily, since it needs privileged access the calling program itself doesn't have.

This kernel-mode transition has genuine, measurable overhead — saving/restoring context, validating the request, and switching page tables/privilege levels all take real CPU cycles beyond just the work being requested. This is exactly why performance-sensitive code tries to minimize the NUMBER of system calls it makes (for example, reading a large file in a few big chunks rather than many tiny ones), since each individual system call carries this fixed overhead on top of whatever actual work it does.

Interview tip: A specific, concrete example — batching reads to reduce system call count — makes this answer sound like real engineering experience rather than textbook recall.
SECTION 02

CPU Scheduling

0 / 10 done
VISUAL MODEL

Multilevel Feedback Queue Scheduling

New Process EntersHigh-Priority Queue (short quantum)Demoted if it uses full quantumLower-Priority Queue (longer quantum)CPU Executes

A process that finishes quickly (an interactive task) stays in the fast, high-priority queue. A process that keeps using its entire time slice (a CPU-heavy batch job) gets gradually demoted to queues with longer time slices but lower priority — letting the scheduler adapt without knowing a process's behavior in advance.

011What is CPU scheduling, and why is it necessary?Beginner+

Easy explanation

CPU scheduling is the process by which the OS decides WHICH ready process gets to use the CPU NEXT, and for how long — since a single CPU core can only truly execute one instruction stream at a time, but modern systems need to run many processes that all appear to be running simultaneously.

Scheduling is necessary because CPU time is a scarce, shared resource — without a scheduler, processes would have no fair or efficient way to share the CPU, and the system would either run one process to completion before starting the next (terrible for responsiveness) or have no coherent policy at all. A good scheduler balances competing goals: fairness, responsiveness for interactive tasks, and overall throughput for the whole system.

Interview tip: None
012What is the difference between preemptive and non-preemptive scheduling?Beginner+

Easy explanation

In non-preemptive (cooperative) scheduling, once a process starts running on the CPU, it keeps running until it VOLUNTARILY gives up the CPU — either by finishing, or by blocking on I/O — the scheduler cannot forcibly interrupt it. This is simpler to implement but risky, since a single long-running or poorly-behaved process can hog the CPU indefinitely, starving everything else.

In preemptive scheduling, the OS can FORCIBLY interrupt a running process (typically using a hardware timer interrupt) and switch to a different process, even if the first one wasn't finished or didn't voluntarily yield — this is what almost all modern general-purpose operating systems use, since it guarantees the scheduler stays in control and prevents any single process from monopolizing the CPU indefinitely.

Interview tip: None
Non-preemptivePreemptive
Can OS forcibly interrupt?No — process must yield voluntarilyYes
RiskOne process can starve othersMore overhead from frequent switching
013What are the common CPU scheduling metrics (turnaround time, waiting time, response time)?Intermediate+

Easy explanation

Turnaround time is the TOTAL time from when a process ARRIVES in the system until it COMPLETES — it includes time spent waiting, executing, and doing I/O. Waiting time is specifically the total time a process spends sitting in the READY queue, waiting for its turn on the CPU, without doing any actual work.

Response time is the time from when a process is submitted until it produces its FIRST response (not necessarily until it fully finishes) — this matters most for interactive systems, where a user cares about how quickly they see SOME feedback, not necessarily how long the entire task takes to fully complete. Different scheduling algorithms optimize for different combinations of these metrics, which is exactly why no single algorithm is universally 'best'.

Interview tip: None
MetricMeasures
Turnaround timeArrival to completion (total time in system)
Waiting timeTime spent in the ready queue, not running
Response timeArrival to first response (not full completion)
014What is First-Come-First-Served (FCFS) scheduling, and what is its major weakness?Intermediate+

Easy explanation

FCFS is the simplest possible scheduling algorithm — processes are executed strictly in the order they arrive, exactly like a single-file queue at a checkout counter, with no consideration of how long each process will actually take to run.

Its major weakness is the 'convoy effect' — if a long-running process happens to arrive first, every SHORTER process behind it in the queue has to wait for that entire long process to finish first, even though servicing the short processes first would have resulted in much better AVERAGE waiting time overall. This makes FCFS a poor fit for interactive or time-sensitive workloads, despite its simplicity.

Interview tip: None
-- Processes arrive: P1 (burst=24), P2 (burst=3), P3 (burst=3)
-- FCFS order: P1, P2, P3
-- P2 and P3 wait 24 units each just because P1 arrived first — the convoy effect
015What is Shortest Job First (SJF) scheduling, and why is it theoretically optimal for average waiting time?Intermediate+

Easy explanation

SJF scheduling always picks the READY process with the SHORTEST estimated CPU burst time to run next — running short jobs before long ones minimizes the average amount of time all processes spend waiting, since fewer processes are stuck behind a long-running one.

SJF is provably optimal for minimizing AVERAGE waiting time among all non-preemptive scheduling algorithms — but it has two real practical problems: it requires knowing (or accurately estimating) each process's future CPU burst length in advance, which is genuinely difficult in a real system, and it can cause STARVATION for long processes if a steady stream of short jobs keeps arriving and continuously jumping ahead of them in the queue.

Interview tip: If asked 'why isn't SJF used everywhere despite being optimal', the honest answer is exactly these two issues: you can't reliably predict burst times, and it risks starving long jobs.
016What is Round Robin scheduling, and how does the time quantum size affect its behavior?Intermediate+

Easy explanation

Round Robin assigns each process a fixed, small time slice (the 'time quantum') to run on the CPU — if a process doesn't finish within its quantum, it's preempted and moved to the back of the ready queue, and the next process gets its turn. This cycles through all ready processes fairly, giving each one a bounded, predictable amount of waiting time.

The quantum size is a critical tuning parameter: too SHORT a quantum causes excessive context-switching overhead (spending more time switching between processes than actually running them), while too LONG a quantum makes Round Robin behave increasingly like FCFS, losing its responsiveness benefits for interactive tasks. Choosing a well-tuned quantum is a genuine, practical trade-off every real scheduler implementation has to make.

Interview tip: None
-- Time quantum = 4
-- P1 (burst=10): runs 4, preempted, waits, runs 4 more, preempted, runs final 2
-- Each process gets a fair, bounded turn rather than waiting for others to fully finish
017What is priority scheduling, and what is the "starvation" problem it can cause?Advanced+

Easy explanation

Priority scheduling assigns each process a priority value, and the scheduler always runs the READY process with the HIGHEST priority next — this lets important or time-sensitive processes get preferential CPU access ahead of less important ones, which can be very useful when some tasks genuinely matter more than others.

The major risk is starvation — if high-priority processes keep arriving continuously, a LOW-priority process can end up waiting indefinitely, never actually getting CPU time at all, even though it's perfectly valid and ready to run. The standard fix is AGING — gradually increasing a waiting process's priority the longer it sits in the ready queue, eventually guaranteeing it will become high-priority enough to run.

Interview tip: Aging is the specific, standard answer interviewers expect when asked how to fix starvation in priority scheduling — mention it by name.
018What is Multilevel Queue scheduling, and how is it different from Multilevel Feedback Queue scheduling?Advanced+

Easy explanation

Multilevel Queue scheduling divides the ready queue into several SEPARATE queues based on process type or priority (like a queue for interactive/foreground processes and a queue for batch/background processes), with each queue potentially using a different scheduling algorithm — but a process is PERMANENTLY assigned to one queue and can never move to a different one.

Multilevel Feedback Queue scheduling is more flexible — it also uses multiple queues, but processes can MOVE BETWEEN queues based on their observed behavior over time: a process that uses its entire time slice repeatedly (behaving like a CPU-bound batch job) gets demoted to a lower-priority queue with a longer time quantum, while a process that frequently gives up the CPU early (behaving like an interactive, I/O-bound task) can stay in or be promoted to a higher-priority queue — letting the scheduler adapt to actual behavior rather than a fixed, permanent classification.

Interview tip: The key distinguishing phrase interviewers listen for: multilevel FEEDBACK queues let processes MOVE between queues based on observed behavior; plain multilevel queues do not.
019What is the difference between CPU-bound and I/O-bound processes, and how should a good scheduler treat each differently?Advanced+

Easy explanation

A CPU-bound process spends most of its time actively doing computation, rarely blocking for I/O — it wants long, uninterrupted stretches of CPU time to make real progress. An I/O-bound process spends most of its time WAITING on I/O operations (disk reads, network requests, user input) and only briefly needs the CPU in between those waits.

A well-designed scheduler tries to give I/O-bound processes QUICK, frequent access to the CPU (since their bursts are short, and getting them back onto I/O quickly keeps devices busy and keeps the system feeling responsive), while CPU-bound processes are given longer time slices but can wait a bit longer without hurting overall system responsiveness — mixing both types well keeps the CPU, disk, and other devices all working productively at the same time, rather than any one resource sitting idle.

Interview tip: A great supporting detail: a good scheduling policy keeps DEVICE UTILIZATION high across the whole system, not just CPU utilization — an interactive process finishing its tiny CPU burst quickly lets it get back to I/O sooner, keeping the disk/network busy too.
020What is real-time scheduling, and what is the difference between hard and soft real-time systems?Advanced+

Easy explanation

Real-time scheduling guarantees that certain tasks complete within a strict DEADLINE, not just 'as fast as reasonably possible' — this matters for systems where missing a deadline has serious consequences, unlike typical general-purpose scheduling which only cares about reasonable overall fairness and throughput.

A hard real-time system treats a missed deadline as a total system failure — like the control system for an airbag deployment or industrial machinery, where being even slightly late can be catastrophic. A soft real-time system tolerates OCCASIONAL missed deadlines with degraded (but not catastrophic) quality — like video streaming, where an occasional dropped or delayed frame is a minor, acceptable annoyance rather than a system failure.

Interview tip: None
Hard real-timeSoft real-time
Missed deadline consequenceSystem failure / unacceptableDegraded quality, but tolerable
ExampleAirbag deployment controlVideo/audio streaming
SECTION 03

Process Synchronization & Deadlocks

0 / 10 done
VISUAL MODEL

The Four Conditions Needed for a Deadlock

Mutual ExclusionHold and WaitNo PreemptionCircular Wait

A deadlock can only occur if ALL FOUR of these conditions hold simultaneously. Deadlock prevention strategies work by deliberately breaking at least one of these conditions, guaranteeing a deadlock can never actually form.

021What is a race condition, and why does it happen?Beginner+

Easy explanation

A race condition occurs when two or more processes or threads access and manipulate SHARED data CONCURRENTLY, and the final outcome depends on the unpredictable timing/order of their execution — the result can differ from run to run even with identical input, purely because of how the operations happened to interleave.

This happens because operations that look 'atomic' in source code (like `counter++`) often actually consist of multiple separate underlying steps (read the current value, add one, write it back) — if two threads interleave these individual steps, one thread's update can be silently overwritten or lost, producing an incorrect final result neither thread intended.

Interview tip: None
// two threads both run: counter++
// Thread A reads counter (0), Thread B reads counter (0)
// Thread A writes 1, Thread B writes 1
// Expected: counter = 2. Actual: counter = 1 — one increment was lost
022What is a critical section, and what three conditions must a correct solution satisfy?Beginner+

Easy explanation

A critical section is a segment of code where a process accesses SHARED resources (shared variables, files, data structures) that must not be simultaneously accessed by more than one process/thread at a time, in order to avoid race conditions and data corruption.

A correct solution to the critical-section problem must guarantee: Mutual Exclusion (only one process can be inside its critical section at any given time), Progress (if no process is currently in its critical section, a process wanting to enter shouldn't be blocked indefinitely by processes not even trying to enter), and Bounded Waiting (there must be a limit on how many times OTHER processes can enter their critical section before a specific waiting process gets its turn, preventing indefinite postponement).

Interview tip: None
023What is a mutex, and how is it different from a binary semaphore?Intermediate+

Easy explanation

A mutex (mutual exclusion lock) is a synchronization primitive that allows only ONE thread to hold it at a time, used to protect a critical section — crucially, a mutex has a concept of OWNERSHIP: only the specific thread that LOCKED it is allowed to unlock it.

A binary semaphore also only takes values 0 or 1, behaving similarly on the surface, but it has NO ownership concept — any thread (not just the one that decremented it) can increment/signal it, which makes semaphores more flexible for certain signaling patterns between threads (like one thread signaling another that an event happened) but also easier to misuse accidentally, since the discipline of 'only the owner releases it' isn't enforced by the primitive itself.

Interview tip: None
MutexBinary semaphore
OwnershipYes — only the locking thread can unlockNo — any thread can signal it
Typical useProtecting a critical sectionSignaling between threads/processes
024What is a counting semaphore, and what is a real use case for one?Intermediate+

Easy explanation

A counting semaphore holds an integer value that can be greater than 1, representing the number of AVAILABLE units of some limited resource — a `wait()`/`P()` operation decrements the counter (blocking if it's already at 0), and a `signal()`/`V()` operation increments it, releasing a waiting thread if any are blocked.

A classic real use case: limiting how many threads can simultaneously access a resource with a fixed, limited capacity — like allowing at most 5 concurrent connections to a database connection pool. Initializing a counting semaphore to 5 lets exactly 5 threads proceed at once; a 6th thread trying to acquire it will block until one of the first 5 releases its slot.

Interview tip: None
Semaphore pool = new Semaphore(5); // 5 available connections
pool.acquire(); // blocks if all 5 are currently in use
// ... use the connection ...
pool.release(); // frees a slot for a waiting thread
025What is the Producer-Consumer problem, and how do semaphores solve it?Intermediate+

Easy explanation

The Producer-Consumer problem models a scenario where one or more PRODUCER threads generate data and place it into a shared, fixed-size buffer, while one or more CONSUMER threads remove and process that data — the challenge is coordinating both sides so producers don't add to a FULL buffer, and consumers don't try to remove from an EMPTY one.

The classic solution uses two counting semaphores plus a mutex: an 'empty' semaphore tracking available empty slots (starts at the buffer's full capacity), a 'full' semaphore tracking filled slots (starts at 0), and a mutex protecting the actual buffer access itself — a producer waits on 'empty' before adding an item and signals 'full' afterward; a consumer waits on 'full' before removing an item and signals 'empty' afterward.

Interview tip: None
// Producer
empty.wait(); mutex.lock(); addToBuffer(item); mutex.unlock(); full.signal();
// Consumer
full.wait(); mutex.lock(); item = removeFromBuffer(); mutex.unlock(); empty.signal();
026What is a deadlock, and what are the four necessary conditions for one to occur?Intermediate+

Easy explanation

A deadlock is a situation where two or more processes are each waiting for a resource that another process in the SAME group is holding, creating a cycle of waiting where none of them can ever proceed — every process is stuck forever unless something external intervenes.

Four conditions must ALL hold simultaneously for a deadlock to be possible: Mutual Exclusion (at least one resource must be held in a non-shareable way), Hold and Wait (a process holding at least one resource is waiting to acquire additional resources held by others), No Preemption (a resource can only be voluntarily released by the process holding it, never forcibly taken away), and Circular Wait (a closed chain of processes exists, each waiting for a resource held by the next one in the chain).

Interview tip: Breaking any ONE of these four conditions is enough to prevent deadlock entirely — this is the foundation of every deadlock prevention strategy, so naming all four by memory is a strong, expected baseline answer.
027What is the difference between deadlock prevention, deadlock avoidance, and deadlock detection?Advanced+

Easy explanation

Deadlock prevention works by structurally guaranteeing that at least one of the four necessary conditions for deadlock can NEVER occur in the system's design — for example, requiring processes to request ALL the resources they'll ever need upfront, eliminating 'hold and wait' entirely, though this can hurt resource utilization.

Deadlock avoidance takes a more dynamic approach — the OS carefully analyzes each individual resource request as it happens and only grants it if doing so would keep the system in a provably 'safe state' (a state from which every process could still eventually finish) — the Banker's Algorithm is the classic example. Deadlock detection takes the most permissive approach — it allows deadlocks to potentially happen, but periodically checks for them (using a resource-allocation graph or similar) and recovers afterward (typically by terminating or rolling back one of the deadlocked processes) once one is actually found.

Interview tip: None
StrategyApproachTrade-off
PreventionStructurally rule out one of the 4 conditionsCan reduce resource utilization/flexibility
AvoidanceOnly grant requests that keep the system in a safe stateRequires advance knowledge of max resource needs
DetectionAllow deadlocks, detect and recover afterwardDeadlocks DO happen; recovery can be costly
028What is the Banker's Algorithm, and what information does it need to decide whether a resource request is safe to grant?Advanced+

Easy explanation

The Banker's Algorithm is a deadlock AVOIDANCE algorithm that decides whether granting a specific resource request would leave the system in a 'safe state' — one where there's still SOME possible order in which every currently-running process could eventually get all the resources it needs and finish, even in the worst case.

To make this decision, it needs to know: the total number of instances of each resource type in the system, how many each process currently HOLDS, and — critically — the MAXIMUM number of each resource type each process might EVER need over its lifetime, declared upfront. Requiring this maximum-demand information in advance is exactly why the Banker's Algorithm, while theoretically elegant, is rarely used in real general-purpose operating systems — most real processes can't reliably declare their maximum future resource needs ahead of time.

Interview tip: A candid, senior-level observation: Banker's Algorithm is heavily tested academically but rarely implemented in real production OS kernels, precisely because of the unrealistic 'declare max needs upfront' requirement — mentioning this shows practical awareness beyond textbook theory.
029What is the difference between livelock and deadlock?Advanced+

Easy explanation

In a deadlock, all involved processes are completely stuck, doing NOTHING at all — each is blocked, waiting indefinitely for a resource held by another, with no progress and no CPU activity happening in the stalled processes at all.

In a livelock, the involved processes are NOT blocked — they're actively running and repeatedly changing their state in response to each other, but this activity never actually leads to any real progress. A classic real-world analogy: two people in a narrow hallway repeatedly stepping aside in the same direction at the same time to let the other pass — both are actively moving, but neither is actually getting anywhere, potentially forever.

Interview tip: None
DeadlockLivelock
Processes actively executing?No — completely blockedYes — constantly active
Progress being made?NoneNone, despite the activity
030What is the Dining Philosophers problem, and what does it illustrate about concurrent resource allocation?Advanced+

Easy explanation

The Dining Philosophers problem is a classic synchronization scenario: five philosophers sit around a table, each needing to pick up TWO shared forks (one on each side) to eat, with only five forks total shared between them — it's a simplified model for a whole class of real problems involving multiple processes competing for multiple shared, limited resources at once.

If every philosopher simultaneously picks up the fork to their LEFT first, then waits for the fork to their right, all five end up holding one fork each and waiting forever for the other — a perfect illustration of deadlock caused by circular wait. Standard solutions include: enforcing an asymmetric pickup order (one specific philosopher picks up their RIGHT fork first, breaking the perfectly circular pattern), introducing a resource hierarchy, or limiting how many philosophers can attempt to eat simultaneously using a semaphore.

Interview tip: If asked to solve it, the cleanest classic fix to describe is 'make one philosopher pick up forks in the opposite order from everyone else' — it directly breaks the circular wait condition with a minimal, elegant change.
SECTION 04

Memory Management & Virtual Memory

0 / 10 done
VISUAL MODEL

Virtual Address Translation

CPU generates Virtual AddressMMU looks up Page TablePage Table gives Physical FramePhysical Memory Accessed

Every memory access a program makes goes through this translation. The program only ever sees virtual addresses; the Memory Management Unit (MMU) transparently maps them to real physical memory locations, which is what makes memory isolation between processes possible.

031What is memory management, and why does an OS need to manage memory carefully?Beginner+

Easy explanation

Memory management is the OS's responsibility for keeping track of which parts of physical memory are currently in use, allocating memory to processes as they need it, and reclaiming it when a process no longer needs it — all while keeping different processes' memory safely isolated from each other.

Careful management is essential because physical memory (RAM) is a limited, shared resource — multiple processes need to coexist in it simultaneously without accidentally reading or corrupting each other's data, and the OS needs strategies to make the most efficient use of a finite amount of RAM even when the total memory demanded by all running processes exceeds what's physically available.

Interview tip: None
032What is the difference between logical (virtual) address space and physical address space?Beginner+

Easy explanation

A logical (or virtual) address is the address a running program actually sees and uses when it accesses memory — from the program's perspective, it appears to have its own large, private, contiguous block of memory starting from address zero, regardless of what's really happening underneath.

A physical address is the ACTUAL location in the real, physical RAM hardware. The OS (with hardware support from the Memory Management Unit) transparently translates every virtual address a program generates into the corresponding real physical address — this indirection is exactly what allows memory protection between processes, and lets the OS relocate a process's data in physical memory without the program itself ever needing to know or care.

Interview tip: A key exam-style fact: two different processes can use the exact same virtual address (like 0x1000) simultaneously, and they'll be transparently mapped to completely different physical addresses — this is only possible because of this virtual/physical separation.
033What is paging, and how does it solve the problem of external fragmentation?Beginner+

Easy explanation

Paging divides both a process's virtual memory AND physical memory into fixed-size blocks — virtual memory is divided into PAGES, and physical memory is divided into equally-sized PAGE FRAMES — a process's pages can then be loaded into ANY available physical frame, not necessarily contiguous ones.

This directly solves external fragmentation (the problem where free memory exists but is scattered in small, non-contiguous chunks too small individually to satisfy a request) since a process's memory no longer needs to occupy one single contiguous block in physical RAM at all — it can be scattered across many separate, non-contiguous physical frames, with the page table keeping track of exactly where each piece actually lives.

Interview tip: None
-- Process's virtual pages: [Page 0][Page 1][Page 2][Page 3]
-- Physical frames used:    Frame 7, Frame 2, Frame 9, Frame 4
-- Not contiguous in physical memory at all, but the page table maps each correctly
034What is a page table, and what is the Translation Lookaside Buffer (TLB) used for?Intermediate+

Easy explanation

A page table is a data structure the OS maintains for each process, storing the mapping from that process's VIRTUAL page numbers to the corresponding PHYSICAL frame numbers — every single memory access a program makes needs to be translated through this table before it can actually reach real memory.

Looking up the page table in memory for every single memory access would be painfully slow (doubling the number of memory accesses needed for anything). The TLB is a small, extremely fast hardware cache built directly into the CPU that stores recently-used virtual-to-physical translations — if a translation is found in the TLB (a 'TLB hit'), the full page-table lookup can be skipped entirely, dramatically speeding up the common case.

Interview tip: A related fact worth knowing: a 'TLB miss' still requires the full, slower page-table walk — this is exactly why programs with poor memory locality (jumping around unpredictably) can suffer real performance penalties from frequent TLB misses.
035What is virtual memory, and how does it let a system run programs larger than physical RAM?Intermediate+

Easy explanation

Virtual memory is a technique that gives each process the illusion of having access to a large, contiguous block of memory (often much larger than the physical RAM actually installed), by transparently using disk storage as an extension of RAM — only the portions of a process's memory that are ACTIVELY being used need to be resident in physical RAM at any given moment.

This works through DEMAND PAGING: a process's pages are only loaded into physical memory when they're actually accessed (referenced) for the first time, not all at once. If a needed page isn't currently in physical memory, a 'page fault' occurs, and the OS loads that specific page in from disk (potentially evicting a different, less-recently-used page to make room) — completely transparent to the running program itself.

Interview tip: Emphasize that this is what allows running many programs whose COMBINED memory demand exceeds physical RAM — each individual program only needs its ACTIVELY used pages resident at once.
036What is a page fault, and what happens when one occurs?Intermediate+

Easy explanation

A page fault is a hardware-triggered interrupt that occurs when a program tries to access a virtual memory page that is NOT currently loaded into physical RAM — this isn't necessarily an error condition; it's the normal, expected mechanism that makes demand paging and virtual memory work at all.

When a page fault occurs: the CPU traps into the OS, the OS checks whether the access was actually valid (a legitimate page just not currently in memory) or truly illegal (accessing memory the process was never allowed to touch, causing a genuine crash/segmentation fault); for a valid fault, the OS finds a free physical frame (evicting an existing page if none are free), loads the needed page in from disk, updates the page table, and resumes the program exactly where it left off, completely unaware anything even happened.

Interview tip: None
-- Program accesses virtual address on a page not in RAM
-- 1. CPU triggers a page fault interrupt
-- 2. OS locates the page on disk (in the swap file/page file)
-- 3. OS finds/frees a physical frame, loads the page into it
-- 4. Page table updated, instruction that faulted is retried transparently
037What is thrashing, and why is it such a severe performance problem?Intermediate+

Easy explanation

Thrashing occurs when a system is so severely overcommitted on memory (too many processes each actively demanding more pages than physical RAM can hold at once) that the OS spends the OVERWHELMING majority of its time constantly swapping pages in and out of memory, rather than making any actual forward progress running program instructions.

This creates a vicious cycle: as more processes compete for insufficient physical memory, each one keeps losing recently-used pages to make room for others, causing MORE page faults, which causes even MORE swapping, which leaves EVEN LESS actual CPU time for real work — overall system throughput can collapse dramatically, sometimes to a near standstill, even though the CPU itself appears to be constantly 'busy' handling page faults.

Interview tip: A strong closing insight: thrashing is often mistaken for a slow CPU or disk, but the real fix is almost always reducing the number of concurrently active processes (or adding more RAM), not upgrading unrelated hardware.
038What are the common page replacement algorithms (FIFO, LRU, Optimal), and how do they compare?Advanced+

Easy explanation

When a page fault occurs and physical memory is full, the OS must choose an existing page to EVICT to make room for the new one — FIFO (First-In-First-Out) simply evicts whichever page has been in memory the LONGEST, regardless of how recently or frequently it's actually been used, which can perform poorly since an old but frequently-used page could get evicted unnecessarily.

LRU (Least Recently Used) evicts the page that hasn't been accessed for the LONGEST time, based on the reasonable assumption that recently-used pages are likely to be used again soon (the principle of temporal locality) — this generally performs much better than FIFO in practice, though it requires extra bookkeeping to track access recency. The Optimal algorithm evicts whichever page won't be needed again for the LONGEST time in the future — it's provably the best possible choice, but requires knowing the future access pattern in advance, making it purely theoretical, used mainly as a benchmark to measure how close a real algorithm gets to ideal performance.

Interview tip: None
AlgorithmEviction choicePractical?
FIFOOldest resident pageYes, but performs poorly
LRULeast recently accessed pageYes, good real-world performance
OptimalPage not needed for longest future timeNo — requires future knowledge, used only as a benchmark
039What is Belady's Anomaly, and why is it a surprising result?Advanced+

Easy explanation

Belady's Anomaly is the counter-intuitive observation that for SOME page replacement algorithms (most notably FIFO), INCREASING the number of physical page frames available can actually INCREASE the number of page faults, rather than decreasing or staying the same, which is exactly the opposite of what you'd naturally expect (more memory should only ever help, or at worst not matter).

This surprising result specifically affects FIFO because it doesn't consider actual page USAGE PATTERNS at all when deciding what to evict, purely age — algorithms like LRU that belong to a category called 'stack algorithms' are mathematically proven to NEVER exhibit this anomaly, which is one more concrete reason LRU-based strategies are generally preferred over FIFO in real page replacement implementations.

Interview tip: Simply being able to name Belady's Anomaly and correctly attribute it to FIFO (not LRU) is often enough depth for this question in most interviews.
040What is segmentation, and how is it different from paging as a memory management scheme?Advanced+

Easy explanation

Segmentation divides a process's memory into logically MEANINGFUL, variable-sized segments — like a code segment, a data segment, a stack segment — each representing a distinct logical unit that the programmer or compiler naturally thinks about, unlike paging's fixed-size, logically-arbitrary chunks.

The key difference: paging divides memory into fixed-size blocks with NO inherent logical meaning (a page boundary can fall in the middle of a function or data structure), while segmentation preserves logical program structure but can suffer from EXTERNAL fragmentation (since segments are variable-sized, free memory can become scattered in gaps too small for a new segment, even though total free space is sufficient) — a problem paging specifically avoids. Many real systems (like x86) have historically combined both: segmentation for logical organization, paging underneath each segment for flexible physical memory allocation.

Interview tip: None
PagingSegmentation
Block sizeFixedVariable, logically meaningful
External fragmentation?NoYes, possible
Matches program structure?No — arbitrary boundariesYes — code/data/stack are natural units
SECTION 05

File Systems, I/O & Disk Management

0 / 10 done
VISUAL MODEL

A File Read Request, Layer by Layer

Application calls read()File System LayerI/O Buffer/Cache CheckDevice DriverPhysical Disk

A read request travels down through several OS layers before it might even need to touch the physical disk. If the requested data is already sitting in the OS's page/buffer cache from a previous read, the disk is never touched at all — this caching is why repeated reads of the same file are usually much faster.

041What is a file system, and what are its core responsibilities?Beginner+

Easy explanation

A file system is the part of the OS responsible for organizing, naming, storing, and retrieving data on persistent storage devices (hard drives, SSDs) — it provides the abstraction of 'files' and 'directories' that applications and users interact with, hiding the messy low-level details of how data is actually laid out on physical storage.

Its core responsibilities include: keeping track of which storage blocks belong to which file, managing free space so new files know where to be written, organizing files into a hierarchical directory structure, enforcing access permissions, and maintaining metadata (file size, creation/modification dates, ownership) for every file.

Interview tip: None
042What is the difference between a file and a directory, from the OS's perspective?Beginner+

Easy explanation

A file is a named collection of related data treated as a single logical unit — it could hold text, an image, executable code, or any other data, and the OS itself generally doesn't need to understand or care about the file's internal CONTENT format, only where its data is stored on disk.

A directory (folder) is actually a SPECIAL KIND of file itself — one whose content is a structured list of entries mapping names to other files or subdirectories, rather than arbitrary user data. This is exactly what makes a hierarchical directory tree possible: a directory file's entries can point to more directory files, nesting to any depth.

Interview tip: None
043What is the difference between contiguous, linked, and indexed file allocation methods?Intermediate+

Easy explanation

Contiguous allocation stores a file's data in one single, unbroken sequence of blocks on disk — extremely fast to read sequentially (no need to jump around) and simple to implement, but suffers from external fragmentation over time, and requires knowing a file's final size upfront when it's first created, which isn't always practical.

Linked allocation stores a file as a chain of blocks scattered anywhere on disk, with each block containing a pointer to the NEXT block in the file — this eliminates fragmentation issues entirely, but makes RANDOM access slow (you must follow the chain from the beginning every time) and is vulnerable to corruption if even one pointer in the chain is damaged. Indexed allocation keeps a separate INDEX BLOCK listing all the block locations belonging to a file, giving fast random access (jump directly to any block via the index) without needing contiguous space — this is the approach most modern file systems actually use, in more sophisticated multi-level forms.

Interview tip: None
MethodRandom access speedFragmentation risk
ContiguousFastYes, external fragmentation
LinkedSlow — must follow the chainNone
IndexedFast — jump via the indexMinimal
044What is an inode, and what information does it typically store?Intermediate+

Easy explanation

An inode (index node) is a data structure used by many file systems (notably Unix/Linux-style file systems) to store all the METADATA about a specific file — everything about the file EXCEPT its actual name and its raw content data, which are kept elsewhere.

A typical inode stores the file's size, permissions, owner, timestamps (created/modified/accessed), and — critically — pointers to the actual data blocks where the file's content is physically stored on disk. A directory entry is really just a mapping from a human-readable FILE NAME to an inode number — this indirection is exactly why a file can have multiple names (hard links) pointing to the very same underlying inode and data.

Interview tip: Knowing that a filename and an inode are conceptually separate is the key insight behind understanding hard links — multiple directory entries (names) can point to the exact same inode.
045What is the difference between a hard link and a symbolic (soft) link?Intermediate+

Easy explanation

A hard link is a second directory entry that points DIRECTLY to the same underlying inode as an existing file — both names are functionally equivalent, indistinguishable copies pointing to the identical data; deleting one link doesn't remove the actual file data as long as at least one other hard link (or the original) still references that inode.

A symbolic (soft) link is a special, separate file whose content is simply the TEXT PATH of another file — it's an indirect pointer, not a direct reference to the same inode. If the original target file is deleted or moved, the symbolic link becomes a 'dangling' reference that points to nothing, unlike a hard link, which keeps the data alive as long as any hard link to it still exists.

Interview tip: None
Hard linkSymbolic (soft) link
Points toThe same inode directlyA text path to another file
Survives original file deletion?Yes — data stays aliveNo — becomes a dangling/broken link
Can link across different disks/file systems?NoYes
046What is disk fragmentation, and why does it matter more for traditional hard drives than for SSDs?Intermediate+

Easy explanation

Disk fragmentation occurs when a file's data ends up scattered across many non-contiguous locations on disk, rather than stored as one contiguous block — this typically happens naturally over time as files are created, deleted, and resized repeatedly, leaving free space in scattered, non-contiguous gaps.

For a traditional spinning hard disk drive, fragmentation is a genuine performance problem because the physical read/write head has to mechanically move to different locations on the spinning platter to read each scattered piece, adding real seek-time delay for every jump. For an SSD (solid-state drive), there's no mechanical arm to move — any location can be accessed in roughly the same time regardless of physical position — so fragmentation has a much smaller practical performance impact, which is exactly why 'defragmenting' an SSD is generally unnecessary and can even shorten its lifespan through unnecessary extra writes.

Interview tip: Explicitly noting that defragmentation is basically irrelevant (or even counterproductive) for SSDs is a specific, modern, practically-relevant detail that shows current knowledge rather than outdated textbook advice.
047What is the difference between synchronous and asynchronous I/O?Advanced+

Easy explanation

In synchronous I/O, a process that requests an I/O operation (like reading a file) is BLOCKED — it cannot continue doing anything else — until that operation fully completes and the data is actually available. This is simple to reason about and program, but wastes time the process could have spent doing other useful work while waiting.

In asynchronous I/O, a process initiates an I/O operation and IMMEDIATELY continues executing other code without waiting for it to finish — it's later notified (through a callback, an event, or by checking a completion status) once the operation actually completes. This lets a program overlap computation with I/O waiting time far more efficiently, which is exactly why high-performance servers handling many simultaneous connections rely heavily on asynchronous I/O models rather than blocking on each individual request.

Interview tip: None
Synchronous I/OAsynchronous I/O
Process blocks while waiting?YesNo
Can do other work meanwhile?NoYes
ComplexitySimpler to reason aboutMore complex, needs callbacks/events
048What is disk scheduling, and how does the SCAN (elevator) algorithm work?Advanced+

Easy explanation

Disk scheduling decides the ORDER in which pending disk I/O requests are actually serviced, aiming to minimize the total mechanical seek time (the time spent physically moving the read/write head) across all pending requests — a naive First-Come-First-Served order can cause the disk head to move back and forth wastefully across the disk.

The SCAN algorithm (nicknamed the 'elevator algorithm' for its resemblance to how a building elevator operates) moves the disk head steadily in ONE direction, servicing every pending request it passes along the way, until it reaches the far end of the disk — then it reverses direction and does the same sweep back the other way, repeating indefinitely. This avoids the wasteful, erratic back-and-forth jumping of simpler algorithms, giving more predictable and generally better overall performance.

Interview tip: None
-- Pending requests at cylinders: 55, 90, 18, 130, 47
-- Disk head starts at 50, moving toward higher numbers
-- SCAN order: 55, 90, 130 (reaches the end), then reverses: 47, 18
049What is RAID, and what is the difference between RAID 0, RAID 1, and RAID 5?Advanced+

Easy explanation

RAID (Redundant Array of Independent Disks) combines multiple physical disks into one logical unit, to improve performance, reliability, or both, depending on the specific RAID level chosen — different levels make very different trade-offs between speed, redundancy (fault tolerance), and usable storage capacity.

RAID 0 (striping) splits data across multiple disks to improve READ/WRITE SPEED (parallel access across disks), but provides ZERO redundancy — if any single disk fails, all data across the entire array is lost. RAID 1 (mirroring) writes an identical, complete COPY of all data to two disks simultaneously — if one disk fails, the other still has everything intact, at the cost of using twice the raw storage capacity for the same usable space. RAID 5 uses striping WITH distributed parity information spread across all disks, allowing the array to survive and recover from a SINGLE disk failure while using storage more efficiently than full mirroring, though write performance is somewhat reduced by the overhead of maintaining that parity data.

Interview tip: None
RAID levelRedundancyTrade-off
RAID 0NoneFastest, but any single disk failure loses everything
RAID 1Full mirrorSurvives 1 disk failure, but uses 2x the raw storage
RAID 5Distributed paritySurvives 1 disk failure, more storage-efficient than mirroring, some write overhead
050What is journaling in a file system, and how does it protect against corruption after a crash?Advanced+

Easy explanation

A journaling file system keeps a special log (the 'journal') recording the CHANGES it's ABOUT TO MAKE to the file system's actual structure, BEFORE it actually performs them — this is conceptually very similar to how a database transaction log works, for exactly the same underlying reason.

If the system crashes or loses power in the middle of a file system operation (like partway through updating multiple related metadata structures), the journal lets the file system recover cleanly on the next boot — it can replay any journaled changes that were fully recorded but not yet fully applied, or safely discard any that were only partially recorded, avoiding the risk of leaving the file system's internal structure in a corrupted, inconsistent state. This is exactly why modern file systems (like ext4, NTFS, APFS) are dramatically more crash-resilient than older, non-journaling file systems.

Interview tip: Drawing the direct parallel to database write-ahead logging/transaction logs is a great way to show you understand the underlying pattern, not just this one specific application of it.
Operating Systems Interview Guide Field Guide · Compiled & Designed by Tanveer Qureshie