__________Operating System Guide

Introduction — What an OS Provides

An operating system manages hardware resources and provides abstractions (processes, threads, files, devices) so applications can run safely and efficiently. It enforces isolation, schedules CPU time, manages memory, handles I/O, and mediates access to devices and storage.

Think of the OS as a resource manager and a contract between applications and hardware. Placement interviews often probe your understanding of trade-offs, common bugs, and real-world implications of OS design.

Processes, Threads & Context Switching

Process vs Thread

Process: isolated execution with its own address space and resources. Thread: lightweight unit of execution within a process that shares memory and file descriptors with sibling threads.

Process Lifecycle

  • New (created)
  • Ready (waiting for CPU)
  • Running
  • Waiting (I/O)
  • Terminated

Context Switch

Switching between processes/threads requires saving/restoring register state, switching page tables if address space changes, and updating kernel data structures. Context switches add overhead—minimize with proper scheduling.

Lightweight vs Heavyweight Processes

Creating processes is heavier (fork + exec), while threads or green threads are lighter. Linux clone flags allow fine-grained control over what is shared.

// fork-exec pattern (conceptual)
pid_t pid = fork();
if (pid == 0) {
  // child
  execl("/bin/ls", "ls", "-l", NULL);
}
// parent continues

CPU Scheduling Algorithms

Schedulers decide which process/thread runs next. Important for fairness, throughput, latency, and responsiveness.

Common Algorithms

  • First-Come First-Serve (FCFS): Simple, can cause convoy effects.
  • Shortest Job First (SJF): Optimal average wait but needs prior knowledge.
  • Round Robin (RR): Time quantum based, good for responsiveness.
  • Priority Scheduling: Preemptive or non-preemptive; watch for starvation.
  • Multilevel Feedback Queue: Adaptive — mixes priorities and aging.

Linux CFS (Completely Fair Scheduler)

CFS models fairness using virtual runtimes and uses a red-black tree to select the next task with smallest vruntime. It balances latency and throughput for desktop and server workloads.

// Round robin conceptual pseudocode
queue = ready_queue
while (true) {
  task = dequeue(queue)
  run(task, time_quantum)
  if (task not finished) enqueue(queue, task)
}

Synchronization — Locks, Semaphores, Monitors, Futex

Concurrency requires synchronization to avoid races. Understand basic primitives and their trade-offs.

Mutex / Spinlock

Mutex: blocks the thread if lock isn't available (context switch). Spinlock: busy-waits—useful when hold time is short and context switch cost is high.

Semaphore

Counting semaphore controls access to N identical resources. Binary semaphore is similar to mutex but without ownership semantics.

Monitors & Condition Variables

Monitor = mutex + condition variables. Condition variables let threads sleep and be signaled when conditions change.

Futex (Fast Userspace Mutex)

Futex allows uncontended lock acquisition in user space and only falls back to kernel help (syscall) on contention—efficient for low-contention locks.

// Pseudocode: producer-consumer using semaphore
semaphore empty = N, full = 0
mutex m

producer() {
  produce item
  wait(empty)
  lock(m)
  enqueue(item)
  unlock(m)
  signal(full)
}

consumer() {
  wait(full)
  lock(m)
  item = dequeue()
  unlock(m)
  signal(empty)
  consume item
}

Deadlocks: Detection, Prevention & Avoidance

Deadlock conditions: mutual exclusion, hold and wait, no preemption, circular wait. Break one condition to avoid deadlocks.

Banker's Algorithm (Avoidance)

Banker's algorithm simulates allocation to ensure system remains in safe state. Useful conceptually but rarely used in large OS due to complexity.

Detection & Recovery

Deadlock detection builds a wait-for graph; on cycle detection, abort one or more transactions/processes to break the cycle.

// Wait-for graph simple depiction
P1 -> P2 (waiting for resource held by P2)
P2 -> P3
P3 -> P1 -> cycle -> deadlock

Virtual Memory, Paging & TLB

Virtual memory gives each process its own address space. Paging maps virtual pages to physical frames via page tables. TLB caches page table entries for fast translation.

Page Faults

On page fault, OS checks whether page is valid (load from disk if needed) or raise segmentation fault for invalid access. Major fault = needs disk I/O; minor fault = already in memory but not mapped.

Page Replacement Algorithms

  • LRU (Least Recently Used): good but expensive to implement exactly.
  • Clock (approx LRU): uses a second chance bit—practical in OSes.
  • FIFO, Optimal (Belady's algorithm) — optimal but needs future knowledge.
// Clock algorithm conceptual
hand = 0
while (true) {
  if (frame[hand].referenced == 0) replace frame[hand]
  else frame[hand].referenced = 0; hand = (hand+1) % N
}

Address Translation Example

Virtual Address (32-bit): [VPN | offset]
VPN -> look up in page table -> PPN
Physical Address = [PPN | offset]

I/O Management & Device Drivers

OS abstracts devices via drivers and provides buffered/unbuffered I/O APIs. Drivers run in kernel space and must be robust—bugs crash the system.

Block vs Character Devices

Block devices (disks) support random access to fixed-size blocks. Character devices (serial ports) are stream-oriented.

Interrupts & Polling

Interrupts notify CPU of events asynchronously; polling checks status periodically. Combine with DMA for efficient transfers.

Driver Model

Drivers register interrupt handlers, implement read/write/ioctl, and must coordinate concurrency and DMA buffers.

File Systems & Storage Management

File systems manage files/directories, metadata (inodes), and map file blocks to disk blocks. Journaling file systems (ext4, XFS) reduce recovery time after crashes.

Inode & Directory Structure

Inode stores metadata and pointers to blocks. Directories map names to inode numbers.

Journaling

Write intention to journal before applying to main structures. Modes: writeback, ordered, and data journaling—trade-offs of performance vs durability.

Example: ext4 workflow

ext4 uses journaling for metadata and optional data journaling. Use fsck and mount options (noatime) to tune performance.

Kernel Architecture — Monolithic vs Microkernel

Monolithic kernels include device drivers and subsystems in kernel space (Linux). Microkernels keep minimal services in kernel and run drivers in user space (e.g., Minix). Trade-offs: performance vs isolation and reliability.

Hybrid & Modules

Modern kernels support loadable modules for drivers to balance performance and modularity.

Virtualization, Containers & Namespaces

Virtual machines emulate hardware and run full OS instances (hypervisors: KVM, Xen). Containers share the host kernel with isolated namespaces (pid, net, mnt, ipc, uts) and cgroups for resource limits.

Containers vs VMs

  • VMs: heavier, stronger isolation, full OS per VM.
  • Containers: lightweight, fast startup, share kernel, use namespaces for isolation.

cgroups

Control groups limit CPU, memory, and IO to prevent noisy neighbor problems in multi-tenant environments.

Security, Permissions & Hardening

OS security includes user/group permissions, capability-based security, SELinux/AppArmor, secure boot, and kernel hardening.

Least Privilege

Run services with minimal privileges, use capability bounding, and avoid running everything as root.

Audit & Logs

Centralize logs, watch for anomalous activity (failed logins, privilege escalations), and use immutable audit trails for forensics.

Troubleshooting & Tools

OS-level debugging uses logs, system traces, and profiling tools to find bottlenecks or crashes.

Common Tools

  • top / htop — live process CPU/memory usage.
  • ps — process listing.
  • strace — system call tracing for a process.
  • ltrace — library call tracing.
  • perf — profiling CPU hotspots and sampling stack traces.
  • dmesg — kernel ring buffer for boot and driver messages.
# Trace syscalls of a process
strace -f -tt -o trace.log -p 

# Trace exec of a command
strace -o out.log -f ls -l /

Placement-Ready OS Questions — Practice & Reveal

Solve these problems; use the reveal button to check answers. These are classic OS interview problems used by tech companies.

Q1 — Scheduling (Medium)

Given processes with burst times: P1=10, P2=1, P3=2, P4=1. Compute average waiting time for (a) FCFS in order P1,P2,P3,P4 and (b) SJF (shortest job first).

Q2 — Deadlock (Medium)

Four processes P1..P4 and resources R1..R4 each with single instance. Given allocation matrix and request matrix, detect if system in deadlock using wait-for graph. (We'll provide small matrices.)

Q3 — Virtual Memory (Advanced)

Consider a system with 3 frames and reference string: 7,0,1,2,0,3,0,4,2,3,0,3. Compute number of page faults using FIFO and LRU.

Q4 — Concurrency (Classic)

Explain why using "check-then-act" without locks causes race conditions. Provide a minimal example and correct it with mutex.

Q5 — File System (Design)

Design a simple file system metadata layout for fast file lookup and explain how you'd handle large directories with millions of files.

Cheat Sheet & Common Commands

# Show processes
ps aux | less

# Top CPU usage
top or htop

# Trace syscalls
strace -f -p 

# Show kernel ring buffer
dmesg | tail

# Check disk usage
df -h

# Check inodes
df -i

# Show mounts
mount | column -t

# Check memory
free -h

# Show open files by process
lsof -p 

Summary & Next Steps

Operating systems form the backbone of software infrastructure. For placements: understand core concepts, be able to simulate scheduling, page replacement, and reason about concurrency issues. Practice explaining trade-offs, and use tools (strace, perf, vmstat) to investigate real problems.

Next: Computer Architecture will follow with cache hierarchies, pipelining, ISA, and interview problems at the same depth.