šÆ Module 07: Interview Prep, Scenarios & 100+ Question Bank
Focus: 100+ High-Yield SDE Interview Questions across all OS domains, Deep Real-World Engineering Scenarios (
epoll, Zero-Copy, False Sharing, Linux internals), and Curated Concurrency Coding Challenges (LeetCode / Juspay Hackathon level) with complete solutions.
š Table of Contents
- Real-World Engineering Deep Dives
- 100+ High-Yield Interview Question Bank
- Part 1: OS Basics, Kernel Architecture & Dual-Mode (Q1āQ15)
- Part 2: Process, Threads, Context Switching & Lifecycle (Q16āQ35)
- Part 3: CPU Scheduling & CFS Internals (Q36āQ50)
- Part 4: Concurrency, Synchronization & Deadlocks (Q51āQ75)
- Part 5: Memory Management & Virtual Memory (Q76āQ90)
- Part 6: File Systems, Inodes & Storage (Q91āQ105)
- Curated Concurrency Coding Challenges (LeetCode & Juspay Level)
1. Real-World Engineering Deep Dives
Scenario 1: Playing Music While Compiling on a Single Core
How can a single-core CPU play smooth, stutter-free 44.1kHz audio while simultaneously compiling a massive C++ program?
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā 1. TIME-SLICING: The OS scheduler (Linux CFS) switches between the audio player and ā
ā the C++ compiler every ~5-10 milliseconds via hardware timer interrupts. ā
ā 2. DMA & HARDWARE AUDIO BUFFER: The audio player fills a physical ring buffer in RAM. ā
ā The Audio DAC (Digital-to-Analog Converter) pulls sound samples directly from RAM ā
ā via Direct Memory Access (DMA) WITHOUT requiring CPU instruction cycles! ā
ā 3. PROCESS PRIORITIES: Audio player runs with real-time / high priority (`SCHED_RR` ā
ā or negative nice). When the audio buffer runs low, the audio thread preempts the ā
ā compiler immediately to refill the 100ms buffer, preventing buffer underruns. ā
ā 4. CPU-BOUND COMPILATION: The compiler runs at normal priority in the background, ā
ā utilizing 98% of the remaining CPU time between audio buffer refills. ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāScenario 2: From Keyboard Keypress to Terminal Display
Trace the complete journey when you press the 'A' key in a terminal.
[ Physical Key Pressed ]
ā (Electrical scan code generated)
ā¼
[ Keyboard Controller ] āāāāŗ Asserts IRQ 1 line on APIC (Advanced Programmable Interrupt Controller)
ā
ā¼
[ CPU Hardware Interrupt ] āāāŗ Pauses current instruction, saves %RIP, flips mode bit to 0 (Kernel)
ā
ā¼
[ Interrupt Descriptor Table (IDT) ] āāāŗ Dispatches to Keyboard Interrupt Service Routine (ISR)
ā
ā¼
[ Linux TTY / Line Discipline Subsystem ]
ā ⢠Translates scan code to ASCII 'A'.
ā ⢠Checks for control characters (Ctrl+C sends SIGINT; 'A' is placed in TTY buffer).
ā ⢠Echoes 'A' back to GPU framebuffer so user sees the letter immediately.
ā¼
[ Terminal App (`bash`) Wakeup ]
ā ⢠`bash` was blocked in `sys_read(0, buf, 1)`.
ā ⢠Kernel moves `bash` from `WAITING` to `READY` queue.
ā¼
[ Syscall Return ] āāāŗ `bash` receives 'A' in user-space buffer; executes `sysret` back to Ring 3.Scenario 3: The C10K Problem ā epoll vs select vs poll
When a server handles 10,000+ concurrent connections, traditional I/O multiplexing collapses:
`select()` / `poll()` `epoll` / `kqueue`
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Application passes array of 10,000 ā ā Application registers fd ONCE into ā
ā file descriptors to kernel on EVERY ā ā kernel Red-Black Tree (`epoll_ctl`). ā
ā loop iteration! ā ā ā
ā ā ā Network card DMA triggers interrupt ā
ā Kernel linearly loops O(N) over ALL ā ā -> Kernel adds ONLY active fd to an ā
ā 10,000 fds to check readiness. ā ā internal Ready Linked List. ā
ā ā ā ā
ā Time Complexity: **O(N)** ā ā Time Complexity: **O(1)** ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāScenario 4: Zero-Copy Architecture (sendfile vs read/write)
When serving static files over a network (e.g., Nginx or Kafka):
TRADITIONAL READ + WRITE (4 Context Switches + 4 Memory Copies):
1. Disk DMA āāāŗ Kernel Page Cache
2. CPU Copy āāāŗ User Application Buffer (Context switch 1 & 2)
3. CPU Copy āāāŗ Kernel Socket Buffer (Context switch 3 & 4)
4. Socket DMA āāāŗ NIC Network Card
ZERO-COPY WITH `sendfile()` (2 Context Switches + 0 CPU Memory Copies):
1. Disk DMA āāāŗ Kernel Page Cache
2. Descriptor DMA āāāŗ NIC Network Card directly! (Data never touches CPU or User Space)Scenario 5: CPU Cache Line False Sharing in Multithreading
64-BYTE CPU CACHE LINE
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Thread 1 modifies: `data.a` ā Thread 2 modifies: `data.b` ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā- Even though
Thread 1only touches variableaandThread 2only touches variableb, both variables reside within the same 64-byte L1 cache line. - When Core 0 writes to
a, the MESI cache coherence protocol marks the entire 64-byte line as Invalid (I) in Core 1's cache. - Core 1 is forced to stall and reload from L3/RAM on every write!
- Fix (Cache Line Padding):
struct alignas(64) ThreadData {
int value;
char padding[60]; // Pad out to 64 bytes to guarantee isolated cache lines!
};2. 100+ High-Yield Interview Question Bank
Part 1: OS Basics, Kernel Architecture & Dual-Mode (Q1āQ15)
Q1: What is the primary role of an Operating System?
Ans: To act as an intermediary between user software and hardware, fulfilling two fundamental responsibilities: (1) Resource Allocator (managing CPU, RAM, disk, and network fairly and efficiently) and (2) Control Program (preventing errors, resource contention, and unauthorized access).
Q2: What is the difference between Kernel Mode (Ring 0) and User Mode (Ring 3)?
Ans: In Kernel Mode, the CPU mode bit is 0, giving unrestricted access to all CPU instructions, hardware registers (%CR3, MSR), and physical memory. In User Mode (mode bit = 1), privileged instructions and direct hardware I/O are physically blocked at the CPU microcode level to protect system integrity.
Q3: What is a System Call? How does it differ from a standard library function?
Ans: A System Call is a programmatic trap instruction requesting a privileged service from the OS kernel (e.g., sys_read). A library function (e.g., strcpy(), sqrt()) executes entirely in user-space without kernel mode switches; some library functions (e.g., printf()) act as user-space wrappers around system calls (write()).
Q4: What happens during a Mode Switch from User to Kernel Mode?
Ans: The CPU saves the user program counter (%RIP) and stack pointer (%RSP), flips the hardware mode bit from 1 to 0, switches to the process's Kernel Stack, and jumps to the kernel's system call entry address (MSR_LSTAR).
Q5: What is an Interrupt Descriptor Table (IDT)?
Ans: An in-memory array of function pointers configured by the kernel at boot time. Each index (vector 0ā255) points to the Interrupt Service Routine (ISR) responsible for handling a specific hardware interrupt, software trap, or CPU fault.
Q6: What is Direct Memory Access (DMA)?
Ans: A hardware architecture enabling high-speed I/O devices (NVMe drives, NICs) to transfer large blocks of data directly to/from RAM over the system bus without routing each byte through CPU registers, freeing the CPU for compute tasks.
Q7: What is the difference between Polling and Interrupts?
Ans: Polling is software-driven and synchronous: the CPU continuously burns clock cycles in a loop checking a device's status register. Interrupts are hardware-driven and asynchronous: the device asserts an electrical pin when ready, allowing the CPU to perform other work until notified.
Q8: What is a Microkernel, and what is its main advantage over a Monolithic kernel?
Ans: A microkernel moves non-essential OS services (device drivers, file systems) into user-space daemons, keeping only minimal IPC, basic scheduling, and low-level memory in Ring 0. Its main advantage is fault isolation: a crashing graphics driver does not crash the entire operating system.
Q9: What is an RTOS (Real-Time Operating System)?
Ans: An OS designed to guarantee deterministic execution time bounds between an external event and the system's response. Hard RTOS systems cannot tolerate any missed deadlines (e.g., pacemakers), while Soft RTOS systems tolerate minor QoS degradation (e.g., video streaming).
Q10: What is a Trap instruction?
Ans: A synchronous software-generated interrupt intentionally executed by a program (e.g., syscall, int 0x80) to transfer control to the kernel.
Q11: What is the Linux Boot Sequence order?
Ans: Power On $\rightarrow$ BIOS/UEFI POST $\rightarrow$ MBR/GPT Bootloader (GRUB) $\rightarrow$ Kernel Unpack & Hardware Initialization $\rightarrow$ Init/systemd (PID 1) $\rightarrow$ User-space Daemons.
Q12: Why are system calls relatively expensive?
Ans: They require saving registers, switching to kernel stacks, verifying memory pointers across boundary lines, changing CPU privilege levels, and potentially invalidating CPU speculative execution pipelines and TLB entries.
Q13: What is the difference between a Hard RTOS and a Soft RTOS?
Ans: Missing a deadline in a Hard RTOS causes catastrophic failure (e.g., flight avionics). In a Soft RTOS, deadlines are targets whose violation merely reduces service quality without fatal consequences.
Q14: What is POSIX?
Ans: Portable Operating System Interface ā a set of IEEE standards defining API syscall specifications (e.g., fork, pthread_create, open) to maintain source code compatibility across Unix-like OSes (Linux, macOS, BSD).
Q15: What is seccomp in Linux?
Ans: Secure Computing Mode ā a kernel security facility that restricts the system calls a process is permitted to issue, commonly used by Docker and Chrome to sandbox untrusted code.
Part 2: Process, Threads, Context Switching & Lifecycle (Q16āQ35)
Q16: What is the difference between a Program and a Process?
Ans: A program is a static, passive binary file stored on disk (e.g., /bin/ls). A process is an active, running instance of a program loaded into RAM with its own address space, PCB, open files, and execution state.
Q17: What are the 5 classic states of a Process?
Ans: New, Ready, Running, Waiting (Blocked), and Terminated.
Q18: What is the difference between Multiprogramming and Multitasking?
Ans: Multiprogramming keeps multiple jobs in RAM and switches the CPU only when the active job waits for I/O (non-preemptive). Multitasking uses timer interrupts to preempt and time-slice the CPU rapidly among active jobs, providing an interactive user experience.
Q19: What is stored in a Process Control Block (PCB)?
Ans: PID, parent PID, process state, program counter (%RIP), CPU registers, memory mapping pointers (%CR3), open file descriptor tables, CPU scheduling priority, and resource usage counters.
Q20: What is a Thread, and what resources does it share with other threads of the same process?
Ans: A Thread is the smallest unit of CPU dispatch. Threads of the same process share the Code/Text segment, Data segment, BSS segment, Heap, open file descriptors, and PID. Each thread has its own private Thread ID, Stack, Stack Pointer (%RSP), Program Counter, and CPU Registers.
Q21: Why is Context Switching between threads faster than between processes?
Ans: Threads share the same virtual memory address space. The CPU does not switch page tables (%CR3), preventing expensive TLB flushes and retaining warm L1/L2 CPU caches.
Q22: What does fork() return in the Parent and Child processes?
Ans: fork() returns the newly created child's PID ($> 0$) to the parent process, returns 0 to the newly created child process, and returns -1 on error.
Q23: What is Copy-On-Write (COW)?
Ans: An optimization where fork() duplicates only page table pointers (marked Read-Only) instead of copying physical RAM frames. A new physical frame is allocated and copied only when either process attempts to write to a page.
Q24: What is a Zombie Process, and how do you clean it up?
Ans: A child process that has terminated (exit()), but its entry in the PCB table remains because its parent has not yet called wait() or waitpid(). You clean it up by having the parent call wait(), or by killing the parent so PID 1 adopts and reaps the zombie.
Q25: What is an Orphan Process?
Ans: A process whose parent has terminated while the child is still executing. The kernel reparents the orphan to PID 1 (systemd/init), which automatically reaps it upon exit.
Q26: What is the difference between fork() and exec()?
Ans: fork() creates an exact duplicate clone of the calling process with a new PID. exec() replaces the current process's memory (text, data, heap, stack) with a completely new executable binary from disk, retaining the same PID.
Q27: What is the difference between User-Level Threads (ULT) and Kernel-Level Threads (KLT)?
Ans: ULTs are managed by user-space runtimes without kernel awareness; context switching is fast, but a single blocking syscall blocks the entire process, and ULTs cannot utilize multiple CPU cores. KLTs are managed natively by the OS kernel, allowing true multicore parallelism.
Q28: What is Amdahl's Law?
Ans: A formula predicting the theoretical maximum speedup of a program when using multiple processors: $$\text{Speedup} = \frac{1}{(1 - P) + \frac{P}{N}}$$ Where $P$ is the parallelizable fraction and $N$ is the number of processor cores.
Q29: What is the fastest Inter-Process Communication (IPC) mechanism on a single machine?
Ans: Shared Memory (shm_open, mmap), because after the initial mapping, communication occurs directly via RAM memory reads/writes without kernel mode transitions or data copying.
Q30: What happens if a process does not close its unused write-end of an anonymous pipe?
Ans: A reader reading from the other end of the pipe will hang indefinitely waiting for more data, because read() only returns EOF (0 bytes) when all open write descriptors for that pipe are closed.
Q31: What is a Context Switch?
Ans: The sequence of steps where the OS saves the CPU execution context (registers, PC, stack) of a running process/thread into its PCB/TCB and loads the saved context of another process/thread to begin execution.
Q32: What is the difference between Named Pipes (FIFOs) and Anonymous Pipes?
Ans: Anonymous pipes exist only in RAM and require a parent-child process relationship. Named Pipes exist as special FIFO entries in the filesystem and allow communication between any unrelated processes on the same host.
Q33: How does Unix Domain Sockets differ from Network TCP Sockets?
Ans: Unix Domain Sockets communicate strictly within the same host kernel using memory buffers, bypassing network protocol framing, checksums, flow control, and routing overhead.
Q34: What is Thread-Local Storage (TLS)?
Ans: A dedicated memory region unique to each individual thread where static or global variables can be stored without sharing state across threads.
Q35: What is a Green Thread?
Ans: A thread scheduled and managed entirely by a user-space runtime environment/virtual machine (e.g., early Java, Python eventlet) rather than natively by the OS kernel.
Part 3: CPU Scheduling & CFS Internals (Q36āQ50)
Q36: What is the difference between Preemptive and Non-Preemptive Scheduling?
Ans: In Non-Preemptive scheduling, a running process holds the CPU until it voluntarily yields (I/O or termination). In Preemptive scheduling, the OS can forcibly suspend a running task via timer interrupts to assign the CPU to another process.
Q37: What is Turnaround Time vs Waiting Time?
Ans:
- $\text{Turnaround Time} = \text{Completion Time} - \text{Arrival Time}$ (Total lifecycle duration).
- $\text{Waiting Time} = \text{Turnaround Time} - \text{Burst Time}$ (Time spent waiting in the Ready Queue).
Q38: What is the Convoy Effect?
Ans: A performance anomaly in FCFS scheduling where a single long CPU-bound task blocks multiple short I/O-bound tasks in the Ready Queue, resulting in low device utilization and poor average wait times.
Q39: Why is Shortest Job First (SJF) optimal for minimizing average waiting time?
Ans: Scheduling shorter jobs first decreases the wait time of short jobs by an amount larger than the corresponding increase in wait time for long jobs, resulting in a net minimum total wait time.
Q40: What is the main drawback of SJF and SRTF in practice?
Ans: The OS cannot know the exact duration of future CPU bursts in advance; it can only approximate burst times using exponential smoothing averages.
Q41: How does Time Quantum size affect Round Robin scheduling performance?
Ans: If the quantum is too large ($q \to \infty$), Round Robin degrades to FCFS. If the quantum is too small ($q \to 0$), context switch overhead consumes a significant fraction of total CPU cycles.
Q42: What is Starvation, and how does Aging solve it?
Ans: Starvation occurs when low-priority processes are indefinitely delayed by a continuous influx of higher-priority tasks. Aging solves this by gradually increasing the priority of processes as they wait in the Ready Queue.
Q43: How does Highest Response Ratio Next (HRRN) prevent starvation?
Ans: By computing Response Ratio $R = \frac{W + S}{S}$. As a long job waits, its wait time $W$ increases, raising its priority ratio until it surpasses shorter incoming jobs.
Q44: What are the primary rules of a Multilevel Feedback Queue (MLFQ)?
Ans: New tasks start in the highest priority queue with short time slices. If a task exhausts its quantum without yielding, it is demoted to a lower queue with larger slices. Periodic global priority boosts prevent starvation.
Q45: How does the Linux Completely Fair Scheduler (CFS) select the next task to run?
Ans: CFS tracks each task's virtual runtime (vruntime) normalized by priority weight. It stores tasks in a self-balancing Red-Black Tree and picks the leftmost node (smallest vruntime) in $O(1)$ cached time.
Q46: What does the nice value in Linux do?
Ans: It sets the priority weight of a process from $-20$ (highest priority, smallest vruntime accumulation rate) to $+19$ (lowest priority, rapid vruntime accumulation).
Q47: What is Processor Affinity?
Ans: The scheduling preference to keep a thread executing on the same CPU core to maximize CPU L1/L2 cache hit rates.
Q48: What is NUMA (Non-Uniform Memory Access)?
Ans: A multiprocessing computer architecture where a CPU core accesses its own local memory bank faster than shared remote memory banks attached to other processor sockets.
Q49: What is the difference between Throughput and Response Time?
Ans: Throughput is the number of processes completed per unit time. Response Time is the duration from when a request/job enters the system to when the first output or CPU allocation occurs.
Q50: What is Push vs Pull Migration in Multiprocessor Load Balancing?
Ans: In Push Migration, a periodic kernel routine inspects core runqueues and pushes tasks from overloaded cores to idle ones. In Pull Migration, an idle core pulls waiting tasks from the runqueues of busy cores.
Part 4: Concurrency, Synchronization & Deadlocks (Q51āQ75)
Q51: What is a Critical Section?
Ans: A section of code that accesses shared mutable resources (RAM, files, hardware) that must not be concurrently executed by more than one thread at a time.
Q52: What are the 3 mandatory requirements for a Critical Section solution?
Ans: (1) Mutual Exclusion (only one thread in CS), (2) Progress (no deadlocks among waiting threads), and (3) Bounded Waiting (no starvation).
Q53: What is the fundamental difference between a Mutex and a Semaphore?
Ans: A Mutex is a locking mechanism with strict ownership (only the lock holder can unlock it). A Semaphore is a signaling counter with no ownership (any thread can signal/post to increment the count).
Q54: What is an Atomic Operation?
Ans: An indivisible hardware operation that executes completely as a single unit without the possibility of being interrupted or observed in an intermediate state by other CPU cores.
Q55: How does Compare-And-Swap (CAS) work?
Ans: An atomic CPU instruction (LOCK CMPXCHG on x86) that compares memory at address $P$ with an expected value $E$; if equal, it updates $P$ to a new value $V$ and returns true; otherwise, it returns false.
Q56: What is a Spinlock, and when should it be used?
Ans: A lock where waiting threads loop in a tight CPU cycle checking lock availability. It should be used only for very short critical sections on multi-core systems where the wait time is less than the cost of two context switches.
Q57: What is a Futex in Linux?
Ans: Fast Userspace Mutex ā a synchronization construct that locks via fast atomic CAS in user-space when uncontended, and invokes the kernel sys_futex system call to suspend threads only when lock contention occurs.
Q58: Why is while (!condition) cv.wait() required instead of if with Condition Variables?
Ans: Under Mesa Semantics, another thread may intercept and alter the condition before the awakened thread re-acquires the mutex, and CPU hardware/kernel events may cause spurious wakeups.
Q59: What is a Read-Write Lock, and what is its advantage?
Ans: A lock that permits multiple concurrent readers (shared mode) or exactly one writer (exclusive mode). It dramatically increases throughput in read-heavy workloads.
Q60: What are the 4 Coffman Conditions necessary for Deadlock?
Ans: (1) Mutual Exclusion, (2) Hold and Wait, (3) No Preemption, and (4) Circular Wait. All 4 must hold simultaneously.
Q61: How can Circular Wait be prevented in practice?
Ans: By establishing a global strict total ordering $F(R)$ over all system lock resources and requiring all threads to acquire locks in strictly increasing order.
Q62: What is the difference between Deadlock Prevention and Deadlock Avoidance?
Ans: Prevention statically invalidates at least one of the 4 Coffman conditions by design. Avoidance dynamically evaluates incoming resource requests at runtime using algorithms like Banker's Algorithm to ensure the system never enters an unsafe state.
Q63: In Banker's Algorithm, what is a "Safe State"?
Ans: A state from which there exists at least one allocation sequence $\langle P_1, P_2, \dots, P_n \rangle$ where every process can satisfy its maximum potential resource demand and terminate without deadlocking.
Q64: What is a Resource Allocation Graph (RAG)?
Ans: A directed graph containing Process nodes and Resource nodes. A cycle in a single-instance resource graph is a necessary and sufficient condition for deadlock.
Q65: What is Priority Inversion, and how does Priority Inheritance Protocol (PIP) solve it?
Ans: It occurs when a low-priority thread holding a lock needed by a high-priority thread is preempted by a medium-priority thread. PIP solves it by temporarily elevating the low-priority thread's priority to match the waiting high-priority thread until it releases the lock.
Q66: What is a Livelock?
Ans: A condition where two or more threads continuously change their states in response to each other, consuming CPU cycles without making forward progress.
Q67: What is the ABA Problem in Lock-Free programming, and how is it resolved?
Ans: When Thread 1 reads value $A$, Thread 2 changes $A \to B \to A$, and Thread 1's CAS succeeds assuming no intermediate changes occurred. It is resolved using version tagging / stamped pointers (e.g., AtomicStampedReference in Java).
Q68: What is a Memory Barrier (Fence)?
Ans: A hardware instruction that prevents the CPU and compiler from reordering read and write instructions across the barrier boundary, ensuring predictable memory ordering across multiple cores.
Q69: What is the difference between Reentrant (Recursive) Mutex and Non-Reentrant Mutex?
Ans: A Reentrant Mutex allows the same thread to acquire the lock multiple times without self-deadlocking, tracking a recursion count that must be matched with an equal number of unlocks.
Q70: How does Peterson's Algorithm achieve synchronization for two processes?
Ans: By combining a flag[2] array (expressing intent to enter) with a shared turn variable (yielding precedence to the other process to break simultaneous ties).
Q71: What is Lock Contention?
Ans: A performance bottleneck that occurs when multiple threads frequently attempt to acquire the same lock simultaneously, causing serialization and context switch overhead.
Q72: What is Fine-Grained Locking vs Coarse-Grained Locking?
Ans: Coarse-grained locking uses one global lock for an entire data structure (simple, low concurrency). Fine-grained locking uses separate locks for individual nodes, buckets, or partitions (complex, high concurrency).
Q73: What is the Producer-Consumer problem, and how many semaphores are needed to solve it?
Ans: A classic concurrency synchronization problem where producers place items in a fixed buffer and consumers remove them. It is solved using 3 semaphores: mutex (for buffer mutual exclusion), empty (counting available slots), and full (counting filled slots).
Q74: Why is double-checked locking broken without memory barriers/volatile?
Ans: CPU instruction reordering can allow the reference to a newly instantiated object to be published before the object's constructor finishes executing, exposing partially constructed state to other threads.
Q75: What is the difference between Reader-Preference and Writer-Preference in RW Locks?
Ans: Reader-Preference prioritizes incoming readers, which can starve waiting writers. Writer-Preference blocks new incoming readers whenever a writer is queued, preventing writer starvation.
Part 5: Memory Management & Virtual Memory (Q76āQ90)
Q76: What is the difference between Logical Address and Physical Address?
Ans: A Logical Address is the virtual memory address generated by the CPU during instruction execution. A Physical Address is the actual hardware memory address loaded onto the memory bus to access a physical RAM cell.
Q77: What is the role of the Memory Management Unit (MMU)?
Ans: To perform hardware-level address translation mapping virtual addresses to physical addresses at runtime using Page Tables and TLBs.
Q78: What is Internal vs External Fragmentation?
Ans: Internal fragmentation is unused wasted memory inside an allocated fixed-size block/page. External fragmentation is free memory distributed in non-contiguous fragments across RAM such that a large contiguous allocation request cannot be satisfied.
Q79: How does Paging eliminate External Fragmentation?
Ans: By dividing virtual memory into fixed-size Pages and physical memory into identical fixed-size Frames. Any available frame can be assigned to any virtual page, removing the requirement for contiguous physical placement.
Q80: What is a Translation Lookaside Buffer (TLB)?
Ans: A specialized, high-speed hardware associative cache located on the CPU chip that stores recent virtual-page-to-physical-frame translations to avoid accessing RAM page tables on every instruction.
Q81: What is a Page Fault?
Ans: A hardware interrupt (Exception Vector 14) raised by the MMU when a program attempts to access a virtual page whose Valid/Invalid bit in the Page Table is marked 0 (not currently present in physical RAM).
Q82: What are the steps taken by the OS during a Page Fault?
Ans: (1) Trap to kernel handler, (2) Validate legal address, (3) Allocate a free physical frame (or evict via page replacement), (4) Issue DMA read to fetch page from disk swap, (5) Update page table valid bit, (6) Restart the trapped instruction.
Q83: What is Belady's Anomaly?
Ans: The phenomenon where increasing the number of physical page frames allocated to a process results in an increase in the number of page faults under FIFO page replacement.
Q84: Which page replacement algorithms are immune to Belady's Anomaly and why?
Ans: Stack Algorithms (such as LRU and Optimal) are immune because the set of pages in memory for $N$ frames is always a strict subset of the pages in memory for $N+1$ frames.
Q85: What is Thrashing, and what is its primary cause?
Ans: A state where the system spends almost all its time swapping pages to and from disk rather than executing instructions. It is caused by an overcommitted degree of multiprogramming where the sum of all processes' working sets exceeds physical RAM capacity.
Q86: What is the Working Set Model?
Ans: A virtual memory management strategy that tracks the set of pages referenced by a process in the most recent time window $\Delta$. The OS allocates enough frames to hold each active process's working set to prevent thrashing.
Q87: What is Multi-Level Paging?
Ans: A hierarchical paging architecture where page tables themselves are paged into tree structures, allowing unused virtual memory regions to avoid allocating intermediate page tables and saving RAM.
Q88: How does the Buddy Allocator work?
Ans: It divides memory blocks into power-of-two sizes. When a block is freed, it checks if its adjacent neighboring "buddy" block of identical size is also free, recursively coalescing them into larger contiguous blocks.
Q89: What is the Linux Slab Allocator?
Ans: A kernel memory management subsystem that pre-allocates pools of contiguous memory containing initialized, fixed-size kernel objects (task_struct, inodes), eliminating internal and external fragmentation for small kernel allocations.
Q90: What is mmap()?
Ans: A system call that maps files or anonymous memory directly into a process's virtual address space, allowing file data to be accessed directly via memory pointers without explicit read()/write() copies.
Part 6: File Systems, Inodes & Storage (Q91āQ105)
Q91: What is an Inode in a Unix filesystem?
Ans: A metadata data structure representing a file system object that stores file size, permissions, ownership, timestamps, and direct/indirect disk block pointers, excluding only the filename.
Q92: What is the difference between a Hard Link and a Soft (Symbolic) Link?
Ans: A Hard Link shares the exact same Inode number and data blocks as the target file. A Soft Link is an independent file with its own Inode whose data content is simply the pathname string of the target.
Q93: What happens to a file on disk when you run rm filename?
Ans: The directory entry is deleted and the Inode's link count is decremented by 1. If link count reaches 0 and no active processes hold open file descriptors to it, the inode and data blocks are freed in the allocation bitmaps.
Q94: What is the Virtual File System (VFS)?
Ans: A kernel abstraction layer that defines standard file interfaces (open, read, write) and object structures (struct inode, struct file, struct dentry), allowing different underlying filesystems (ext4, NTFS, NFS) to be accessed transparently.
Q95: What is File System Journaling?
Ans: A fault-recovery mechanism where metadata modifications are committed to a sequential Write-Ahead Log (Journal) on disk before modifying actual file blocks, allowing rapid consistency recovery after unexpected power loss.
Q96: What is the difference between Contiguous, Linked, and Indexed File Allocation?
Ans: Contiguous stores files in sequential disk blocks (fast random access, high external fragmentation). Linked chains blocks via pointers (no fragmentation, poor random access). Indexed uses an index block/inode containing pointers to all file blocks (fast direct access, no external fragmentation).
Q97: What is a File Allocation Table (FAT)?
Ans: A centralized in-memory table storing linked-list block pointers for all files on a storage partition, providing faster random access than on-disk linked list allocation.
Q98: How do Disk Scheduling Algorithms reduce mechanical latency?
Ans: By reordering pending I/O requests to minimize the physical distance traveled by the read/write mechanical arm (minimizing seek time).
Q99: What is the difference between SCAN (Elevator) and LOOK disk scheduling?
Ans: SCAN sweeps the head from one physical boundary of the disk to the opposite extreme boundary (e.g., 0 to 199). LOOK sweeps only as far as the furthest pending request in that direction before reversing.
Q100: What is C-SCAN (Circular SCAN)?
Ans: A disk scheduling algorithm where the head moves in one direction servicing requests, and upon reaching the end, returns immediately to the beginning without servicing requests on the return trip, providing uniform wait times across tracks.
Q101: What are the differences between RAID 0, RAID 1, and RAID 5?
Ans:
- RAID 0 (Striping): Splits data across drives; maximum speed, 0 redundancy.
- RAID 1 (Mirroring): Duplicates data across drives; 50% capacity, survives 1 drive loss.
- RAID 5 (Parity): Block striping with distributed parity; $(N-1)$ capacity, survives 1 drive loss.
Q102: What is RAID 10 (RAID 1+0)?
Ans: A nested RAID array configured as a stripe of mirrored disks, combining the fault tolerance of RAID 1 with the I/O throughput of RAID 0.
Q103: How does RAID 5 reconstruct data when a drive fails?
Ans: Using the Boolean XOR ($\oplus$) property: $D_{\text{lost}} = D_1 \oplus D_2 \oplus \dots \oplus P$.
Q104: What is a Superblock in a Unix file system?
Ans: A critical metadata block near the start of a filesystem partition that describes overall geometry, total block count, free inode counts, block size, and filesystem status flags.
Q105: What is the difference between a Directory and a Regular File in Unix?
Ans: To the kernel, a directory is a file with a special type flag whose data payload consists of an array of (filename, inode_number) mapping entries.
3. Curated Concurrency Coding Challenges (LeetCode & Juspay Level)
Problem 1: Print FooBar Alternately (LeetCode 1115)
LeetCode Link: 1115. Print FooBar Alternately
Problem Statement:
Two different threads share an instance of FooBar. Thread A calls foo() and Thread B calls bar(). Output "foobar" $n$ times strictly sequentially.
Solution in C++ using Mutex & Condition Variables:
#include <mutex>
#include <condition_variable>
#include <functional>
class FooBar {
private:
int n;
std::mutex mtx;
std::condition_variable cv;
bool foo_turn = true;
public:
FooBar(int n) : n(n) {}
void foo(std::function<void()> printFoo) {
for (int i = 0; i < n; i++) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]() { return foo_turn; });
printFoo();
foo_turn = false;
cv.notify_one();
}
}
void bar(std::function<void()> printBar) {
for (int i = 0; i < n; i++) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]() { return !foo_turn; });
printBar();
foo_turn = true;
cv.notify_one();
}
}
};Problem 2: Building H2O (LeetCode 1117)
LeetCode Link: 1117. Building H2O
Problem Statement:
There are two kinds of threads: oxygen and hydrogen. Design a synchronization barrier such that for every 1 Oxygen thread released, exactly 2 Hydrogen threads are released, forming $H_2O$.
Solution in Java using Semaphores & CyclicBarrier:
import java.util.concurrent.Semaphore;
import java.util.concurrent.CyclicBarrier;
class H2O {
private final Semaphore hSem = new Semaphore(2);
private final Semaphore oSem = new Semaphore(1);
private final CyclicBarrier barrier = new CyclicBarrier(3);
public H2O() {}
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
hSem.acquire();
try {
barrier.await();
releaseHydrogen.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
hSem.release();
}
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
oSem.acquire();
try {
barrier.await();
releaseOxygen.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
oSem.release();
}
}
}Problem 3: Thread-Safe Bounded Blocking Queue (LeetCode 1188)
LeetCode Link: 1188. Design Bounded Blocking Queue
Problem Statement:
Implement a thread-safe FIFO bounded queue with enqueue(element), dequeue(), and size() methods without busy waiting.
Solution in C++ using Condition Variables:
#include <mutex>
#include <condition_variable>
#include <queue>
class BoundedBlockingQueue {
private:
std::mutex mtx;
std::condition_variable not_full;
std::condition_variable not_empty;
std::queue<int> q;
size_t capacity;
public:
BoundedBlockingQueue(int capacity) : capacity(capacity) {}
void enqueue(int element) {
std::unique_lock<std::mutex> lock(mtx);
not_full.wait(lock, [this]() { return q.size() < capacity; });
q.push(element);
not_empty.notify_one();
}
int dequeue() {
std::unique_lock<std::mutex> lock(mtx);
not_empty.wait(lock, [this]() { return !q.empty(); });
int val = q.front();
q.pop();
not_full.notify_one();
return val;
}
int size() {
std::lock_guard<std::mutex> lock(mtx);
return q.size();
}
};Problem 4: Lock-Free Stack using Atomic CAS
Frequently asked in high-concurrency systems (Juspay, HFTs).
Treiber Lock-Free Stack in C++:
#include <atomic>
template <typename T>
class LockFreeStack {
private:
struct Node {
T data;
Node* next;
Node(T val) : data(val), next(nullptr) {}
};
std::atomic<Node*> head{nullptr};
public:
void push(T val) {
Node* new_node = new Node(val);
// Atomically link new_node -> head using CAS:
do {
new_node->next = head.load(std::memory_order_relaxed);
} while (!head.compare_exchange_weak(new_node->next, new_node,
std::memory_order_release,
std::memory_order_relaxed));
}
bool pop(T& result) {
Node* old_head = head.load(std::memory_order_relaxed);
// Atomically advance head -> head->next using CAS:
while (old_head && !head.compare_exchange_weak(old_head, old_head->next,
std::memory_order_acquire,
std::memory_order_relaxed));
if (!old_head) return false; // Stack was empty
result = old_head->data;
delete old_head;
return true;
}
};š Summary Checklist for Interviews
You are now fully equipped with:
- Complete OS Architecture & System Call internals.
- Process & Thread execution models, PCB/TCB, and IPC channels.
- All CPU scheduling calculations, MLFQ, and Linux CFS mechanics.
- Multi-threading synchronization, Lock-Free CAS atomics, and Deadlock algorithms.
- Memory management math, multi-level page tables, TLB EAT, and Page Replacement algorithms.
- Unix Inode internals, Journaling consistency, Disk scheduling, and RAID parity math.
- 105+ high-yield interview answers and production-grade concurrency implementations.