Operating system interview questions appear in backend, systems, embedded, cloud, and campus placement loops—often paired with networking and databases. Linux operating system interview questions dominate SRE and backend roles because production servers run the Linux kernel. Interview questions related to operating system fundamentals test whether you understand processes vs threads, virtual memory, scheduling, and deadlocks with enough depth to connect theory to a slow server or OOM kill—not textbook definitions alone (see kill and pkill).
Below are 49 questions with elaborate answers; technical sections include a strong answer sample you can say aloud. Pair this guide with computer networks interview questions for TCP/IP, DNS, HTTP/TLS, and layered troubleshooting, Kubernetes interview questions for container scheduling and cgroup isolation on nodes, shell scripting interview questions for Linux command-line practice, C and C++ interview questions for pointers and memory at the language layer, Java interview questions part 2 for JVM threading, Git interview questions for collaboration on Linux workstations, and Kafka interview questions when messaging meets OS I/O and page cache behavior.
Interview context and how to prepare
What do operating system interviews actually test?
OS interviews test whether you understand how the kernel manages hardware for applications—CPU, memory, files, and devices—not whether you memorized every scheduling algorithm name.
| Layer | What interviewers probe |
|---|---|
| Processes | PCB, states, fork, zombie/orphan |
| Threads | vs process, synchronization |
| Scheduling | Policies, preemptive, Linux CFS |
| Memory | Virtual memory, paging, TLB, thrashing |
| Sync | Mutex, semaphore, race conditions |
| Deadlocks | Four conditions, prevention |
| Linux | Practical commands, containers vs VMs |
| Role | Emphasis |
|---|---|
| Campus / fresher | Definitions, diagrams, classic algorithms |
| Backend / SRE | Linux behavior, troubleshooting scenarios |
| Systems / embedded | Kernel concepts, IPC, real-time scheduling |
A strong answer is:
OS interviews test whether you understand how the kernel manages hardware for applications—CPU, memory, files, and devices—not whether you memorized every scheduling algorithm name.
What are the main functions of an operating system?
What interviewers are testing: Whether you can describe OS responsibilities as resource management and abstraction beyond memorizing a bullet list.
| Function | Responsibility |
|---|---|
| Process management | Create, schedule, terminate processes; IPC |
| Memory management | Virtual memory, allocation, protection |
| File system | Files, directories, permissions, caching |
| I/O management | Device drivers, buffering, scheduling disk/network |
| Security | User/kernel mode, access control, isolation |
The OS is a resource manager and abstraction layer—apps see files and sockets, not raw disk sectors.
A strong answer is:
The OS is a resource manager and abstraction layer—apps see files and sockets, not raw disk sectors.
What are types of operating systems?
What interviewers are testing: Whether you understand common OS categories overlap and map workloads to scheduling or resource guarantees.
| Type | Example | Trait |
|---|---|---|
| General-purpose | Linux, Windows, macOS | Interactive + server workloads |
| Batch | Historical mainframes | Jobs queued without user interaction |
| Real-time (RTOS) | FreeRTOS, QNX | Deterministic deadlines |
| Distributed | Cluster OS layers | Resources appear unified |
| Mobile / embedded | Android (Linux kernel), iOS | Power-aware scheduling |
There is no single universally exclusive classification. Interview textbooks commonly classify operating systems by workload or behavior: batch, time-sharing/general-purpose, real-time, distributed, embedded/mobile, and so on. Categories can overlap—for example, Android is both mobile and a general-purpose multitasking OS.
Linux operating system interview questions usually assume general-purpose multitasking with preemptive scheduling.
A strong answer is:
Common categories include general-purpose or time-sharing systems, batch systems, real-time systems, distributed systems, and embedded/mobile systems. The categories can overlap; what matters is the workload and scheduling or resource guarantees the OS provides.
What is a realistic 4–6 week OS prep plan?
| Week | Focus | Output |
|---|---|---|
| 1 | Processes, threads, PCB, states | Draw memory layout per process |
| 2 | Scheduling algorithms + Linux CFS | Compare RR vs priority verbally |
| 3 | Virtual memory, paging, page faults | Walk page fault sequence |
| 4 | Sync — mutex, semaphore, race | Producer-consumer pseudocode |
| 5 | Deadlocks — Coffman, banker intuition | Lock ordering example |
| 6 | Linux practice + scenarios | ps, top, free, mock narrations |
Use one Linux VM to observe fork, zombies, and memory with real commands.
A strong answer is:
I would spend the first half of my prep on processes, scheduling, and virtual memory, then synchronization and deadlocks, and finish by observing those concepts on Linux with
ps,vmstat,free, and small fork/thread experiments.
Processes and threads
What is a process?
What interviewers are testing: Whether you distinguish a running process and its execution state/resources from the executable file stored on disk.
A process is a program in execution—an independent unit with its own virtual address space, resources (file descriptors, credentials), and Process Control Block (PCB) metadata.
When you run ./app, the OS loads code, allocates memory, creates a PCB, and schedules it on the CPU.
A strong answer is:
A process is the OS's container for a running program—own address space and kernel bookkeeping—not just the executable file on disk.
Process vs thread — what is the difference?
What interviewers are testing: Whether you explain memory isolation vs shared heap, creation cost, and when threads beat processes for concurrency.
| Aspect | Process | Thread |
|---|---|---|
| Memory | Own address space | Shares code, heap, files with siblings |
| Stack | Own | Own stack per thread |
| Creation cost | Higher | Lower |
| Context switch | Can incur address-space overhead | Often avoids full address-space change |
| Isolation | Crash contained | One thread crash can kill process |
| Communication | IPC required | Shared memory (needs locks) |
A strong answer is:
Processes isolate memory for safety; threads share memory for speed—thread switches within the same process can avoid some address-space overhead, though both still incur scheduling, register, and cache costs.
What are process states?
What interviewers are testing: Whether you connect textbook process states to observable Linux ps STAT values.
Common states:
| State | Meaning |
|---|---|
| New | Being created |
| Ready | Runnable, waiting for CPU |
| Running | Executing on CPU |
| Waiting / Blocked | Waiting for I/O or event |
| Terminated | Finished; PCB may linger briefly |
On Linux, the ps command STAT column shows R, S, D, Z, etc.
A strong answer is:
I describe the ready-running-waiting cycle and mention Linux
psstates—blocked on I/O is waiting, not consuming CPU.
What is a Process Control Block (PCB)?
What interviewers are testing: Whether you identify the PCB/task_struct role in context switches and resource tracking.
Linux represents each schedulable task with task_struct, which references structures containing memory mappings, open files, credentials, signal state, and other process/thread resources. It plays the role closest to the textbook PCB. Threads can have separate task_struct instances while sharing resources such as address space.
- Process ID (PID), parent PID (PPID)
- CPU registers, program counter
- Pointers to memory management, file descriptor, and scheduling state
Context switches save and restore task state.
A strong answer is:
Linux uses
task_structas the kernel's per-task descriptor—it references the memory, files, and scheduling context rather than storing every detail inline. When we context-switch, we're swapping task state so another thread or process can run.
What is context switching and what does it cost?
What interviewers are testing: Whether you understand what state the kernel must switch and why excessive scheduling can hurt cache and translation locality.
Context switching saves the state of the current process/thread and loads another so the CPU can run different work.
Costs:
- Save/restore registers and program counter
- Switching address spaces can incur TLB-related overhead; modern CPUs use address-space tags such as PCID (x86) or ASID to avoid full flushes in many cases
- Cache pollution (cold caches for new working set)
Frequent switching with tiny time slices can hurt throughput—context switch overhead is why batching work matters.
A strong answer is:
Context switching enables multitasking but isn't free—switching address spaces can hurt translation and cache locality, so I reduce unnecessary threads and syscall churn in hot paths.
What are zombie and orphan processes?
What interviewers are testing: whether you distinguish zombie (exited, parent hasn't waited) from orphan (parent died) and name the fix.
| Type | Definition | Linux note |
|---|---|---|
| Zombie | Terminated but PCB entry remains until parent wait() |
STAT shows Z |
| Orphan | Parent died before child | Reparented to an appropriate reaper—traditionally PID 1, or a configured child subreaper / PID-namespace init |
Zombies consume PID/table slots, not memory of the dead program—many zombies indicate parent not reaping.
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/ {print}'On a healthy system this often prints nothing; zombies appear briefly when parents omit wait().
A strong answer is:
Zombies are exited children waiting for parent to reap—I fix the parent to call wait or use proper signal handling, not kill zombies individually.
How do fork() and exec() work on Linux?
What interviewers are testing: Whether you can explain fork() creating a child, exec() replacing the program image, and the parent reaping with wait().
fork() creates a child process—duplicate of parent; copy-on-write makes duplicating memory efficient.
exec() replaces the child's memory image with a new program.
Typical shell pattern: fork → child execs command → parent waits.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void) {
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) {
execlp("echo", "echo", "hello from exec", (char *)NULL);
perror("execlp");
_exit(127);
}
waitpid(pid, NULL, 0);
printf("parent reaped child %d\n", (int)pid);
return 0;
}This demonstrates fork → child → exec → parent wait. Any process—not only a child—can call an exec family function to replace its own program image.
A strong answer is:
fork duplicates the process; exec loads a new program in the child—shells and servers use this pair to spawn commands without blocking the parent forever.
What is Inter-Process Communication (IPC)?
What interviewers are testing: Whether you can choose IPC mechanisms by process relationship, throughput, and synchronization needs.
| Mechanism | Use |
|---|---|
| Anonymous pipe | Byte stream commonly between related processes |
| Named pipe / FIFO | Filesystem-named byte stream; processes need not be related |
| Message queue | Discrete messages |
| Shared memory | High-throughput shared region; requires synchronization |
| Socket | Local or network IPC |
| Signal | Asynchronous notification |
Choose based on throughput, isolation, and persistence needs.
A strong answer is:
Pipes and sockets for streams; shared memory when bandwidth matters but I add mutexes—signals for lifecycle events like graceful shutdown.
CPU scheduling
What is CPU scheduling?
What interviewers are testing: Whether you explain scheduling goals and how policies trade fairness, latency, and throughput.
Scheduling selects which ready process/thread runs on the CPU when multiple contenders exist.
Goals:
- CPU utilization — keep CPU busy
- Throughput — jobs completed per time
- Turnaround / waiting time — user-perceived latency
- Fairness — avoid starvation
A strong answer is:
Scheduling picks the next runnable task—policies trade fairness, latency, and throughput depending on desktop, server, or real-time workload.
Explain FCFS, SJF, and Round Robin scheduling.
What interviewers are testing: Whether you compare classic scheduling algorithms and their practical weaknesses.
| Algorithm | Idea | Weakness |
|---|---|---|
| FCFS | First come, first served | Convoy effect—short jobs wait behind long |
| SJF | Shortest job first | Starvation of long jobs; need burst estimate |
| Round Robin | Time quantum per process in queue | Higher context switch if quantum tiny |
Round Robin suits time-sharing interactive systems.
A strong answer is:
FCFS is simple but unfair to short jobs; RR with a reasonable quantum gives interactive responsiveness; SJF optimizes average wait if job lengths are known.
Preemptive vs non-preemptive scheduling?
What interviewers are testing: Whether you explain how preemptive scheduling keeps interactive systems responsive on modern Linux.
| Non-preemptive | Preemptive | |
|---|---|---|
| CPU release | Process yields on I/O or exit | OS can interrupt running process |
| Response | Poor for interactive | Better for multitasking |
| Modern OS | Rare for general CPU | Default on Linux/Windows |
Timer/scheduler events and runnable higher-priority work allow the kernel to preempt tasks according to the scheduling policy.
A strong answer is:
Modern general-purpose OSes are preemptive—the scheduler can interrupt a running task on timer/scheduler events or when higher-priority work becomes runnable, which keeps the system responsive.
What is priority scheduling?
What interviewers are testing: Whether you explain priority scheduling, starvation risk, and mitigations such as aging on Linux.
Each process has a priority—highest priority ready process runs first.
Problems: starvation of low-priority tasks.
Aging gradually increases priority of waiting processes to fix starvation.
Linux nice values (-20 to 19) influence the scheduling weight of normal fair-scheduled tasks; they are not raw fixed priorities like the real-time classes. For CLI syntax to set or change nice on running processes, see nice and renice.
A strong answer is:
Priority scheduling can starve lower-priority work, so classic algorithms use aging. On Linux, nice adjusts the relative weight of normal fair-scheduled tasks rather than placing them in strict fixed-priority queues.
How do CFS and EEVDF relate in modern Linux scheduling?
What interviewers are testing: Whether your Linux scheduler knowledge goes beyond the historical CFS-only explanation.
CFS (Completely Fair Scheduler) historically modeled fair CPU for normal tasks using virtual runtime (vruntime) and a red-black tree—the leftmost runnable task had the lowest vruntime.
Modern Linux has transitioned normal-task scheduling toward EEVDF (Earliest Eligible Virtual Deadline First). Kernel documentation describes CFS as making room for EEVDF; the transition began in Linux 6.6.
| Concept | Role |
|---|---|
| CFS (historical) | vruntime-based fair scheduling for SCHED_OTHER |
| EEVDF (modern) | Lag, eligibility, and virtual deadlines for fair CPU allocation |
| Nice | Still adjusts scheduling weight for normal tasks |
| RT policies | SCHED_FIFO / SCHED_RR bypass normal fair scheduling |
Both aim for fair CPU allocation among runnable normal tasks—the implementation evolved from vruntime trees toward EEVDF concepts.
A strong answer is:
CFS taught vruntime fairness; modern kernels use EEVDF with eligibility and virtual deadlines—I explain both as fair schedulers for normal tasks, with nice still biasing CPU share.
What is multilevel feedback queue (MLFQ)?
What interviewers are testing: Whether you understand MLFQ as adaptive scheduling theory distinct from Linux's EEVDF/CFS implementation.
MLFQ uses multiple queues with different priorities; processes move between queues based on behavior:
- CPU-bound jobs demoted to lower priority
- I/O-bound interactive jobs stay higher
Adapts without knowing job length in advance—teaching concept; modern Linux fair scheduling (EEVDF/CFS) differs but interviewers use MLFQ to test adaptive scheduling intuition.
A strong answer is:
MLFQ separates interactive from CPU-bound by promoting I/O waiters and demoting CPU hogs—it's the classic adaptive scheduler taught even though Linux now uses EEVDF-style fair scheduling in production.
Memory management
What is virtual memory and why is it important?
What interviewers are testing: whether you justify virtual memory for isolation, overcommit, and larger-than-RAM programs.
Virtual memory gives each process an illusion of a large, private, contiguous address space while physical RAM is shared and limited.
Benefits:
- Isolation — processes cannot access each other's memory
- Sparse address spaces — processes can have virtual address spaces larger than physical RAM; pages need not all be resident simultaneously
- Simplified linking — each program can use similar virtual addresses
- Shared libraries — map same physical pages read-only
- Mapped files and demand paging — load pages on fault
Swap may provide backing for some anonymous pages but is not required for virtual memory itself.
A strong answer is:
Virtual memory provides address translation, protection, and private address spaces—apps see a large virtual layout while the MMU maps only resident pages to physical frames.
What is paging?
What interviewers are testing: Whether you explain paging, page tables, and MMU translation at interview depth.
Memory divided into fixed-size pages (virtual) mapped to frames (physical) via page tables.
MMU translates virtual address → physical frame on each access.
| Concept | Size typical |
|---|---|
| Page | 4 KiB on x86 (huge pages exist) |
| Page table | Per-process multi-level tables |
A strong answer is:
Paging splits memory into fixed pages mapped by page tables—the MMU translates every access, enabling protection and non-contiguous physical allocation.
What is a page fault and how is it handled?
What interviewers are testing: Whether you distinguish valid demand/COW faults from invalid memory accesses and major faults from minor faults.
A page fault is a synchronous memory-access exception that requires kernel handling—for example because a page is not currently mapped, needs demand allocation/loading, triggers copy-on-write, or violates mapping/protection rules.
Handling sequence (simplified):
- CPU raises a page-fault exception.
- Kernel checks the virtual-memory area and requested access.
- If valid, it may install an existing page, allocate a page, perform COW, or read backing data.
- If invalid, the process normally receives a signal such as
SIGSEGVorSIGBUS. - If resolved, execution retries the faulting instruction.
Major fault generally requires storage I/O; minor fault can be resolved without that I/O.
A strong answer is:
A page fault means a memory access needs kernel intervention. A valid fault may be satisfied by demand paging, an existing cached page, allocation, or COW; an invalid access can become SIGSEGV. Major faults require backing-store I/O, while minor faults do not.
What is the TLB (Translation Lookaside Buffer)?
What interviewers are testing: Whether you explain TLB purpose, misses, and address-space switch costs.
The TLB is a CPU cache of recent virtual→physical translations.
| Event | Cost |
|---|---|
| TLB hit | Fast access |
| TLB miss | Walk page table in memory |
Switching to a different address space can hurt translation and cache locality—modern CPUs use PCID/ASID to reduce full TLB invalidation, but context switches still have cost.
A strong answer is:
TLB caches page table entries—misses add latency; address-space changes can hurt locality, which is why huge pages and minimizing unnecessary process switches matter.
Paging vs segmentation?
What interviewers are testing: Whether you compare fixed-size paging with variable logical segments and why paging dominates modern systems.
| Paging | Segmentation | |
|---|---|---|
| Division | Fixed-size pages | Variable logical segments (code, stack) |
| Fragmentation | Internal | External |
| Modern use | Dominant | x86 legacy; logical segments |
Many systems use paging with segment-like concepts in higher-level runtimes.
A strong answer is:
Paging is fixed-size and avoids external fragmentation; segmentation matches logical program parts—modern OSes rely on paging with MMU protection bits.
Internal vs external fragmentation?
What interviewers are testing: Whether you distinguish internal from external fragmentation without conflating disk and memory concepts.
| Type | Cause | Example |
|---|---|---|
| Internal | Allocation unit is larger than request | Unused space within an allocated page/block |
| External | Enough total free memory exists, but it is split into non-contiguous holes | Variable-sized/segmented memory allocation |
Paging suffers internal; segmentation suffered external—compaction or paging mitigates.
A strong answer is:
Internal fragmentation is wasted space inside allocated units; external is free gaps between allocations—paging trades internal waste for simpler management.
Explain page replacement algorithms — FIFO, LRU, Optimal.
What interviewers are testing: Whether you know the textbook algorithms while recognizing that real Linux reclaim is more sophisticated.
When RAM is full and a new page needed, OS evicts a frame:
| Algorithm | Rule | Note |
|---|---|---|
| Optimal | Evict page used farthest in future | Theoretical benchmark |
| FIFO | Oldest page | Simple; Belady anomaly possible |
| LRU | Least recently used | Good approximation; hardware bits help |
Linux does not use textbook FIFO or exact LRU directly. Traditional reclaim uses active/inactive LRU-style lists, and modern kernels also provide Multi-Gen LRU (MGLRU) as an alternative reclaim implementation that may be enabled depending on kernel configuration and system policy.
A strong answer is:
FIFO, LRU, and Optimal are useful interview models, but Linux reclaim is more sophisticated. Modern kernels can use Multi-Gen LRU to track access recency across generations rather than implementing textbook exact LRU.
What is thrashing?
What interviewers are testing: Whether you recognize thrashing from major faults and swap pressure and name practical mitigations.
Thrashing occurs when the system spends more time paging than executing—working set exceeds RAM, constant page faults, collapse in throughput.
Causes: too many processes, oversized heaps, insufficient RAM.
Fixes: add RAM, reduce concurrency, tune swap, fix memory leaks, use cgroups limits.
Connects to JVM GC + swap storm scenarios in senior loops.
A strong answer is:
Thrashing is the OS paging constantly instead of running useful work—I detect it via high major faults and swap I/O, then reduce memory pressure or add RAM.
What is swapping?
What interviewers are testing: Whether you understand modern Linux swaps anonymous pages under pressure rather than treating swap as RAM.
Historically, "swapping" could mean moving whole processes; modern Linux normally swaps individual memory pages rather than whole processes.
Swap provides disk-backed storage for anonymous memory pages that the kernel chooses to evict from RAM. It can increase the amount of memory state the system can retain, but access is dramatically slower than RAM.
free -h shows used swap; high swap with slow performance signals memory pressure.
A strong answer is:
Modern Linux usually swaps anonymous pages, not entire processes. Swap can preserve cold memory under pressure, but sustained swap-in/swap-out of the active working set causes severe latency.
What is memory-mapped I/O (mmap)?
What interviewers are testing: Whether you explain mmap() virtual mappings without confusing them with hardware MMIO.
mmap() creates a mapping in a process's virtual address space. A mapping can be file-backed, anonymous, shared, private, or—in specialized cases—backed by a device.
For file-backed mappings, pages participate in the page cache.
Used for:
- Convenient random access and shared/file-backed mappings without explicitly issuing
read()for every access - Shared libraries loaded by the dynamic linker
- Databases and engines mapping data files
See also language-level memory in the C and C++ interview questions guide.
A strong answer is:
mmap()maps files or anonymous memory into virtual address space so accesses go through the page cache and MMU—it is not universally faster thanread()/write(), but it enables convenient random access and shared mappings.
Synchronization and deadlocks
What is a race condition?
What interviewers are testing: Whether you define race conditions and practical fixes with mutexes or atomics.
A race condition occurs when correctness depends on unordered timing of threads/processes accessing shared mutable state without proper synchronization.
Example: two threads increment a counter—both read 5, write 6 instead of 7.
Fix: mutex, atomic operations, or immutable data structures.
A strong answer is:
Race means shared mutable state without coordination—I serialize with mutexes or use atomics when the operation is simple enough.
What is a critical section?
What interviewers are testing: Whether you define critical sections and mutual exclusion, progress, and bounded waiting.
The critical section is code accessing shared resources that must not run concurrently by multiple threads without rules.
Requirements for solution:
- Mutual exclusion
- Progress — someone enters if no conflict
- Bounded waiting — no indefinite postponement
A strong answer is:
Critical section is the shared-resource code path—mutexes ensure only one thread executes it at a time while avoiding deadlock and starvation where possible.
Mutex vs semaphore — what is the difference?
What interviewers are testing: Whether you distinguish mutex ownership from counting semaphores for signaling and pooling.
| Mutex | Semaphore | |
|---|---|---|
| State | Locked/unlocked with ownership | Counter |
| Who releases | Normally the owner | Not inherently owner-bound |
| Purpose | Protect shared critical section | Signaling or limit N resources |
Binary semaphore ≠ mutex in strict ownership semantics.
A strong answer is:
Mutex is for exclusive access with owner unlock; counting semaphore limits N concurrent users—I'd mutex a bank balance update and semaphore a connection pool.
What is a monitor?
What interviewers are testing: Whether you explain monitors as mutex plus condition-variable synchronization.
A monitor is a high-level synchronization construct—mutex + condition variables bundled so only one thread is active inside the monitor at a time.
Java synchronized methods and wait()/notify() implement monitor-style sync—see Java part 2 threading.
A strong answer is:
Monitors combine mutual exclusion with condition waits—Java synchronized blocks are the textbook monitor pattern most app developers actually use.
Explain the producer-consumer problem.
What interviewers are testing: Whether you solve producer-consumer with mutexes and proper empty/full signaling.
Producers add items to a bounded buffer; consumers remove them.
Needs:
- Mutex for buffer structure
- Counting semaphores or condition variables for empty and full slots
Classic teaching problem for semaphores and monitors.
A strong answer is:
Producer-consumer needs mutual exclusion on the buffer plus signaling when slots are empty or full—semaphores or condition variables prevent busy-waiting.
What is deadlock?
What interviewers are testing: Whether you define deadlock as circular wait with no forward progress and name prevention vs detection strategies.
Deadlock is a state where processes/threads are blocked forever, each waiting for a resource held by another in a cycle.
Example: Thread A holds lock1 waits lock2; Thread B holds lock2 waits lock1.
A strong answer is:
Deadlock is circular wait with no forward progress—I detect cycles in lock graphs or prevent with ordering, not hope timeouts alone fix design bugs.
What are the four necessary conditions for deadlock (Coffman)?
What interviewers are testing: Whether you can list Coffman conditions and show how breaking one prevents deadlock.
All four must hold simultaneously:
| Condition | Meaning |
|---|---|
| Mutual exclusion | Resource used by one at a time |
| Hold and wait | Hold resources while waiting for more |
| No preemption | Resources only released voluntarily |
| Circular wait | Cycle in wait graph |
Break any one to prevent deadlock—common: lock ordering breaks circular wait.
A strong answer is:
I list all four Coffman conditions, then show how global lock ordering breaks circular wait—the prevention pattern I use in real code reviews.
How do you handle deadlocks — prevention, avoidance, detection, recovery?
What interviewers are testing: whether you follow a practical ordered approach with the right tools—not a vague tool list.
| Strategy | Approach |
|---|---|
| Prevention | Global lock ordering; acquire-all-or-release/backoff; eliminate hold-and-wait where practical |
| Avoidance | Banker's algorithm—only grant safe states |
| Detection | Wait-for graph cycle detection + kill/rollback |
| Recovery | Preempt resources or terminate processes |
A try_lock can participate in a backoff design rather than waiting while holding conflicting resources. Databases use detection + rollback; kernels often favor prevention in driver paths.
A strong answer is:
Prevention via lock ordering in app code; databases detect and rollback; avoidance like Banker's is taught for theory—I explain which fits kernel vs application context.
What is the Banker's algorithm?
What interviewers are testing: Whether you explain Banker's algorithm as safe-state avoidance theory.
Banker's algorithm is deadlock avoidance—before granting a resource request, simulate allocation and ensure the system stays in a safe state (some completion order exists).
Used teaching safe vs unsafe states; less common in every production allocator but frequent in exams.
A strong answer is:
Banker's algorithm grants requests only if a safe sequence exists afterward—it's avoidance theory I use to explain safe states even if Linux allocators don't implement it literally.
Deadlock vs starvation?
What interviewers are testing: Whether you contrast circular deadlock with indefinite postponement from unfair scheduling.
| Deadlock | Starvation | |
|---|---|---|
| Progress | None in cycle | Low-priority may never run |
| Cause | Circular wait | Unfair scheduling / priority |
| Fix | Break cycle | Aging, fair queues |
A strong answer is:
Deadlock is circular permanent block; starvation is indefinite postponement—aging and fair scheduling fix starvation without full deadlock.
Linux operating system and practical scenarios
User mode vs kernel mode?
What interviewers are testing: Whether you explain user/kernel privilege boundaries and architecture-defined syscall entry.
| Mode | Privilege | Runs |
|---|---|---|
| User | Restricted | Applications |
| Kernel | Full hardware access | OS core, drivers |
System calls (read, write, fork) use an architecture-defined controlled transition from user mode into kernel mode—for example the syscall instruction on modern x86-64.
A strong answer is:
Apps run user mode; syscalls trap into kernel mode for privileged work—that's the boundary protecting hardware and other processes.
Essential Linux commands for OS interview scenarios?
What interviewers are testing: Whether you can connect OS concepts such as process states, scheduling pressure, memory, and syscalls to observable Linux evidence.
| Command | OS concept demonstrated |
|---|---|
ps -ef / ps aux |
Processes, PPID, STAT |
top / htop |
CPU scheduling, load |
free -h |
RAM and swap |
vmstat 1 |
Run queue, blocked tasks, swap/I/O activity, interrupts, context switches, CPU |
kill -SIGTERM |
Signals, graceful terminate |
strace |
Syscall tracing |
lsof |
Open files per process |
Practice on Ubuntu—see shell scripting interviews.
ps -o pid,ppid,stat,nlwp,cmd -p $$Shows current shell PID, parent, state, and thread count (nlwp)—links process theory to the terminal.
A strong answer is:
I connect
psstates to process theory,vmstatto run queue, blocked tasks, swap and context switches,freeto memory pressure, andstraceto syscall behavior. For per-process page faults I can usepidstat -r -p <PID> 1or/proc/<pid>/stat(minflt,majflt).
Containers vs virtual machines — OS perspective?
What interviewers are testing: Whether you explain namespaces and cgroups as shared-kernel isolation versus hypervisor-guest VM separation.
| VM | Container | |
|---|---|---|
| Isolation | Separate guest OS + hypervisor | Shared kernel; namespaces + cgroups |
| Startup | Slower | Faster |
| Overhead | Higher | Lower |
| Security boundary | Stronger | Weaker—kernel bugs affect host |
Containers use Linux namespaces (pid, net, mount, user) and cgroups for limits—isolation without full second kernel.
A strong answer is:
VMs virtualize hardware with guest kernels; containers share one kernel with namespaces and cgroups—isolation is lighter but the kernel is a shared trust boundary.
What are cgroups and why do they matter?
What interviewers are testing: Whether you explain cgroup resource accounting/limits and memory.max OOM behavior.
cgroups (control groups) limit and account CPU, memory, I/O for process groups—foundation of Docker/Kubernetes resource limits.
With cgroup v2, memory.max is a hard memory limit for the cgroup. If usage reaches that limit and reclaim cannot reduce it, the kernel may invoke the OOM killer within that cgroup without requiring a system-wide OOM. memory.events exposes max, oom, and oom_kill counters.
A strong answer is:
cgroups account and constrain resources for groups of processes. A container or service can hit its memory cgroup limit and experience an OOM even while the host still has memory available.
Scenario: Linux server load average is 50 but CPU looks idle — what do you check?
What interviewers are testing: whether you split high load average into CPU vs D-state I/O wait before blaming application code.
Diagnosis path:
top— CPU vs I/O wait (wa) vs steal- Uninterruptible sleep (
Dstate) — blocked on disk/NFS iostat— disk saturation; see iostat command for%utiland await- Runnable queue vs blocked threads
- Memory — swap thrashing causing I/O wait
High load can mean many blocked tasks, not CPU burn. For a structured walkthrough of this symptom pattern, see Linux troubleshooting interview questions.
A strong answer is:
High load with low CPU often means I/O wait or uninterruptible disk sleep—I check ps STAT D, iostat, and swap, not only CPU percentage.
Scenario: Application killed with OOM — explain from OS view.
What interviewers are testing: Whether you distinguish host-wide OOM from cgroup memory limits using kernel logs and cgroup metrics.
Distinguish global/system OOM from cgroup/memory-limit OOM:
| Type | When |
|---|---|
| Global OOM | Node cannot satisfy memory allocation/reclaim—kernel OOM killer selects a victim process |
| memcg/cgroup OOM | Workload hits its configured memory cgroup limit |
In Kubernetes, OOMKilled containers often reflect cgroup limits even when the host still has free memory.
Global OOM:
journalctl -k | grep -i -E 'oom|out of memory|killed process'cgroup v2 context:
cat /sys/fs/cgroup/<group>/memory.current
cat /sys/fs/cgroup/<group>/memory.max
cat /sys/fs/cgroup/<group>/memory.eventsFor containers/Kubernetes, also inspect runtime/pod status.
Mitigation: tune heap, add RAM, fix cgroup limits, fix leaks, reduce cache footprint.
A strong answer is:
I first distinguish host-wide OOM from a cgroup limit. For host OOM I inspect kernel logs; for a constrained workload I also inspect
memory.max,memory.current, andmemory.events, then correct the leak, sizing, or limit rather than only restarting.
Final prep checklist
What should you rehearse before operating system interviews?
What interviewers are testing: Whether you have a rehearsed checklist linking theory diagrams, algorithms, Linux commands, and scenarios.
Checklist:
- Process vs thread memory diagram
- Process states + zombie/orphan
- Context switch cost and TLB
- FCFS, RR, CFS/EEVDF one-liners
- Virtual memory, page fault sequence
- TLB, thrashing, swap
- Mutex vs semaphore
- Four Coffman conditions + lock ordering fix
- Linux —
ps,top,free,vmstat - Containers — namespaces + cgroups
- Two scenarios — high load, OOM
- Shell scripting command refresh
- C and C++ if systems role
A strong answer is:
I whiteboard process vs thread and page fault flow, recite Coffman with a prevention example, then walk one Linux incident story with the commands I actually ran.
What is copy-on-write (COW)?
What interviewers are testing: Whether you explain copy-on-write's role in fork() and on-demand page duplication.
Copy-on-write defers duplicating memory until a page is actually modified.
Classic example: after fork(), parent and child share physical pages marked read-only; the first write to a shared page triggers a page fault and the kernel copies just that page.
Benefits:
- Fast process creation
- Efficient memory use when child
execs or shares read-only data
A strong answer is:
COW lets fork duplicate address spaces cheaply—pages are shared until written, then copied on demand.
What is the difference between a file descriptor and an open-file description?
What interviewers are testing: Whether you distinguish per-process file descriptors from shared open-file descriptions after fork()/dup().
| File descriptor | Open-file description | |
|---|---|---|
| Scope | Per-process integer (0, 1, 2, …) |
Kernel object tracking open state |
| Shares | Each process has its own FD table | Multiple FDs can reference the same open-file description after dup()/fork() |
| State | Index into process table | Tracks file offset, flags, etc. |
After fork(), corresponding parent and child descriptors refer to the same open-file description and therefore share the file offset and file status flags. A separate open() creates a new open-file description. O_CLOEXEC does not change post-fork() sharing; it controls whether the descriptor survives a subsequent successful exec.
A strong answer is:
A file descriptor is the per-process handle; the open-file description is the kernel's shared open state—dup and fork explain why offset sharing surprises developers.
What is the difference between a system call, interrupt, exception, and page fault?
What interviewers are testing: Whether you classify syscalls, interrupts, exceptions, and page faults by trigger and handler role.
| Event | Trigger | Handler role |
|---|---|---|
| System call | Program requests kernel service (read, write) |
Kernel syscall path |
| Interrupt | External hardware/async device | Device driver / kernel IRQ handler |
| Exception | Synchronous CPU fault in running code | Kernel fault handler |
| Page fault | Synchronous memory-access exception because translation/protection requires kernel handling | Demand paging, COW, stack growth where valid, or signal on invalid access |
Page faults are exceptions; not every exception is a page fault.
A strong answer is:
Syscalls are intentional kernel entry; interrupts are external events; exceptions are synchronous faults—page faults are the memory-management exception path.
What is EEVDF scheduling?
What interviewers are testing: Whether you explain EEVDF lag, eligibility, and virtual deadlines beyond CFS vruntime.
EEVDF (Earliest Eligible Virtual Deadline First) is the modern fair scheduler direction for normal Linux tasks.
Key ideas:
- Lag — whether a task is ahead of or behind its fair CPU service
- Eligibility — a runnable task with non-negative lag is eligible for selection
- Virtual deadline — among eligible tasks, prefer the earliest virtual deadline
Linux began transitioning toward EEVDF in 6.6.
It supersedes pure vruntime-leftmost CFS selection while preserving fair CPU-share goals. Nice still adjusts weight.
A strong answer is:
EEVDF schedules normal tasks by eligibility and virtual deadlines—it's the modern evolution beyond classic CFS vruntime trees for fair CPU allocation.
Pattern cheat sheet (quick reference)
| Topic | Key idea |
|---|---|
| Process | Own address space + PCB |
| Thread | Shared heap, own stack |
| Context switch | Save PCB; address-space change can hurt TLB/cache locality |
| Virtual memory | Address translation, protection, demand paging |
| Page fault | Kernel-handled translation/protection fault; demand paging, COW, or signal |
| TLB | Cache translations; PCID/ASID reduce full flushes |
| Thrashing | Too much paging, not enough RAM |
| Mutex | Exclusive lock with owner |
| Semaphore | Count limited resources |
| Deadlock | All four Coffman conditions |
| Linux fair scheduler | EEVDF (modern); CFS vruntime (historical) |
| Container | Namespaces + cgroups on shared kernel |
References
- Linux kernel documentation — Scheduler
- Linux kernel documentation — EEVDF Scheduler
- Linux kernel documentation — CFS Scheduler
- Linux kernel documentation — Memory Management
- Linux kernel documentation — Multi-Gen LRU
- Linux kernel documentation — Control Group v2
- Linux man-pages — fork(2)
- Linux man-pages — open(2)
Summary
OS interviews connect process and memory theory to Linux behavior—zombies in ps, swap storms, OOM kills, and cgroup limits. Draw diagrams, run the fork demo on Ubuntu, and compare your answers to each section. Pair with shell scripting and C and C++ interviews when virtual memory meets pointers and malloc.

