Linux System Developer Interview Questions and Answers
Basic Linux Knowledge
Q: What happens when you type 'ls -l' in a terminal? Explain the entire process.
Answer: When you type 'ls -l' and press Enter, the following process occurs:
- The shell (e.g., bash) reads the input and parses it.
- The shell identifies 'ls' as an external command and '-l' as an argument.
- The shell fork()s to create a child process.
- The child process uses execve() to replace itself with the 'ls' program.
- The 'ls' program:
- Parses command-line arguments
- Opens the current directory (or specified directory)
- Reads directory entries using getdents() system call
- For each file:
- Calls stat() to get file information
- Formats the output (permissions, owner, size, date, name)
- Writes the formatted output to stdout
- The parent shell waits for the 'ls' command to complete
- The shell displays a new prompt
Q: What is the Linux kernel?
A: The Linux kernel is the core component of Linux operating systems. It's a free and open-source, monolithic, modular Unix-like operating system kernel. It manages:
- System hardware resources
- Process scheduling
- File systems
- Device drivers
- System calls
Key characteristics:
- Written primarily in C
- Created by Linus Torvalds in 1991
- Released under GNU General Public License v2
Q: Explain the boot process of a Linux system.
Answer: The Linux boot process consists of the following stages:
BIOS/UEFI Stage
- Power-on self-test (POST)
- Identifies boot device
Bootloader Stage (e.g., GRUB)
- Loads kernel image into memory
- Passes control to kernel with initial RAM disk (initrd)
Kernel Stage
- Initializes hardware and memory
- Mounts root filesystem
- Starts init process (PID 1)
Init Stage
- SystemD or traditional SysV init
- Starts system services
- Brings up network interfaces
- Mounts additional filesystems
Runlevel/Target Stage
- Reaches the specified runlevel or target
- System is ready for use
Q: What is the difference between a soft link and a hard link?
Answer:
Hard Links:
- Share the same inode number as the original file
- Can't cross filesystem boundaries
- Can't link to directories (usually)
- File content is only deleted when all hard links are deleted
- Same file size as the original file
Example creating a hard link:
lnoriginal.txt hardlink.txt
Soft Links (Symbolic Links):
- Contain a path to the original file
- Can cross filesystem boundaries
- Can link to directories
- Can become dangling if original file is deleted
- Very small in size (just contains the path)
Example creating a soft link:
ln-s original.txt softlink.txt
Q: Explain the difference between user space and kernel space.
A:
Kernel Space:
- Highest privileged level (Ring 0)
- Full access to hardware
- Executes kernel code and device drivers
- Cannot be accessed directly by user applications
User Space:
- Lower privilege level (Ring 3)
- Limited access to hardware
- Executes user applications
- Must use system calls to access kernel services
Example of crossing the boundary:
// User space codeintfd=open("file.txt",O_RDONLY);// System call to kernel space// Kernel space implementationSYSCALL_DEFINE3(open,constchar__user*,filename,int,flags,umode_t,mode){// Kernel code here}
Q: What are system calls? List and explain five common ones.
A: System calls are interfaces between user space programs and the kernel.
Five common system calls:
- fork()
pid_tpid=fork();
Creates a new process by duplicating the calling process
- read()
ssize_tbytes=read(fd,buffer,count);
Reads data from a file descriptor
- write()
ssize_tbytes=write(fd,buffer,count);
Writes data to a file descriptor
- open()
intfd=open("file.txt",O_RDONLY);
Opens a file or creates it if it doesn't exist
- close()
intstatus=close(fd);
Closes a file descriptor
Q: Explain the Linux process scheduling algorithm.
A: Linux uses the Completely Fair Scheduler (CFS):
Key concepts:
Virtual Runtime (vruntime)
- Tracks process execution time
- Normalized by process priority
Red-Black Tree
- Processes sorted by vruntime
- O(log n) insertion and removal
Example of how priority affects scheduling:
structsched_paramparam;param.sched_priority=51;// Range: 1-99 for real-timesched_setscheduler(pid,SCHED_FIFO,¶m);
Scheduler classes (in order of priority):
- Stop scheduler (internal use)
- Deadline scheduler
- Real-time scheduler
- CFS scheduler
- Idle scheduler
Q: What is a page fault? Explain different types.
A: A page fault occurs when a program tries to access memory that is mapped in the virtual address space but not loaded in physical memory.
Types of page faults:
Minor Page Fault
- Page is in memory but not marked in MMU
- No disk I/O required
Major Page Fault
- Page must be loaded from disk
- Requires disk I/O
Invalid Page Fault
- Access to invalid memory address
- Results in segmentation fault
Example of handling page faults in kernel:
staticint__do_page_fault(structmm_struct*mm,unsignedlongaddr,unsignedintflags,structtask_struct*tsk){structvm_area_struct*vma;intfault;vma=find_vma(mm,addr);if(!vma)returnVM_FAULT_BADMAP;fault=handle_mm_fault(vma,addr,flags);returnfault;}
Q: What are the different types of process states in Linux?
Answer: Linux processes can be in the following states:
Running (R)
- Currently executing on a CPU or waiting to be executed
Sleeping
- Interruptible Sleep (S): Waiting for an event, can be interrupted
- Uninterruptible Sleep (D): Usually I/O, can't be interrupted
Stopped (T)
- Process has been stopped, usually by user signal (SIGSTOP)
Zombie (Z)
- Process has completed but parent hasn't read its exit status
Dead (X)
- Process is being terminated
Example command to see process states:
ps aux |awk'{print $8}' |sort |uniq-c
System Programming
Q: What is the difference between a process and a thread?
Answer:
Processes:
- Have separate memory spaces
- Have their own file descriptors, program counter, stack
- Communication between processes requires IPC mechanisms
- Higher overhead for creation and context switching
- More isolated and secure
Threads:
- Share the same memory space within a process
- Share file descriptors, code, and data segments
- Can communicate through shared memory
- Lower overhead for creation and context switching
- Less isolated, potential for race conditions
Example of creating a process vs a thread:
// Process creation#include<unistd.h>pid_tpid=fork();if(pid==0){// Child process}else{// Parent process}// Thread creation#include<pthread.h>void*thread_function(void*arg){// Thread codereturnNULL;}pthread_tthread;pthread_create(&thread,NULL,thread_function,NULL);
6. Q: What are signals in Linux? How do you handle signals in a program?
Answer: Signals are software interrupts used for inter-process communication. They can be:
- Sent by the kernel to processes
- Sent by processes to other processes
- Sent by processes to themselves
Common signals:
- SIGTERM (15): Termination request
- SIGKILL (9): Immediate termination
- SIGINT (2): Interactive attention (Ctrl+C)
- SIGSEGV (11): Segmentation violation
Example of signal handling:
#include<signal.h>#include<stdio.h>voidsignal_handler(intsignum){printf("Caught signal %d\n",signum);}intmain(){// Register signal handlersignal(SIGINT,signal_handler);while(1){printf("Running...\n");sleep(1);}return0;}
Debugging & Performance
Q: How would you profile a Linux application for performance optimization?
Answer: Several tools and techniques can be used:
- perf - Linux profiling tool
perf record ./myappperf report
- gprof - GNU profiler
gcc-pg program.c-o program./programgprof program gmon.out> analysis.txt
- Valgrind - Memory profiler
valgrind--tool=callgrind ./myapp
- strace - Trace system calls
strace-c ./myapp
Key areas to look for:
- CPU usage (user vs system time)
- Memory allocation/deallocation patterns
- I/O operations
- Cache misses
- System call usage
Example of using perf to find hotspots:
perf record-g ./myappperf report--stdio
Coding Questions
Q: Write a program to create a daemon process.
Answer:
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<syslog.h>intmain(){// Fork off the parent processpid_tpid=fork();if(pid<0){exit(EXIT_FAILURE);}if(pid>0){exit(EXIT_SUCCESS);// Parent exits}// Create new sessionif(setsid()<0){exit(EXIT_FAILURE);}// Fork again (recommended)pid=fork();if(pid<0){exit(EXIT_FAILURE);}if(pid>0){exit(EXIT_SUCCESS);}// Set file permissionsumask(0);// Change working directorychdir("/");// Close all open file descriptorsfor(intx=sysconf(_SC_OPEN_MAX);x>=0;x--){close(x);}// Open logsopenlog("mydaemon",LOG_PID,LOG_DAEMON);// Daemon-specific initializationwhile(1){syslog(LOG_NOTICE,"Daemon is running");sleep(30);}closelog();returnEXIT_SUCCESS;}
Key points about daemons:
- Double forking ensures the process isn't a session leader
- Changing directory to / prevents locking mounted filesystems
- Closing file descriptors prevents resource leaks
- Using syslog for logging as stdout/stderr are closed
Q: What are signals in Linux? How do you handle them?
A: Signals are software interrupts used for inter-process communication.
Common signals:
- SIGTERM (15) - Termination request
- SIGKILL (9) - Immediate termination
- SIGINT (2) - Interactive attention (Ctrl+C)
- SIGSEGV (11) - Segmentation violation
Signal handling example:
#include<signal.h>voidsignal_handler(intsignum){printf("Caught signal %d\n",signum);}intmain(){structsigactionsa;sa.sa_handler=signal_handler;sigemptyset(&sa.sa_mask);sa.sa_flags=0;sigaction(SIGINT,&sa,NULL);while(1){sleep(1);}return0;}
Sending signals:
// Send signal to another processkill(pid,SIGTERM);// Send signal to process groupkillpg(pgid,SIGTERM);
Q: What is a deadlock? How can you prevent it?
A: A deadlock occurs when two or more processes are waiting indefinitely for resources held by each other.
Four conditions for deadlock:
- Mutual Exclusion
- Hold and Wait
- No Preemption
- Circular Wait
Example of potential deadlock:
pthread_mutex_tmutex1=PTHREAD_MUTEX_INITIALIZER;pthread_mutex_tmutex2=PTHREAD_MUTEX_INITIALIZER;void*thread1_function(void*arg){pthread_mutex_lock(&mutex1);sleep(1);// Increase chance of deadlockpthread_mutex_lock(&mutex2);// ... critical section ...pthread_mutex_unlock(&mutex2);pthread_mutex_unlock(&mutex1);returnNULL;}void*thread2_function(void*arg){pthread_mutex_lock(&mutex2);sleep(1);pthread_mutex_lock(&mutex1);// ... critical section ...pthread_mutex_unlock(&mutex1);pthread_mutex_unlock(&mutex2);returnNULL;}
Prevention strategies:
- Lock ordering
- Lock timeout
- Deadlock detection
- Use lock-free algorithms
Q: Explain the difference between threads and processes.
A:
Processes:
- Separate address space
- Higher creation overhead
- More isolation
- IPC required for communication
Threads:
- Shared address space
- Lower creation overhead
- Less isolation
- Can communicate through shared memory
Example of creating both:
// Process creationpid_tpid=fork();if(pid==0){// Child processexit(0);}// Thread creationpthread_tthread;pthread_create(&thread,NULL,thread_function,NULL);pthread_join(thread,NULL);
Memory comparison:
// Process - separate memoryintmain(){intx=5;if(fork()==0){x=6;// Only changes in childexit(0);}// Parent's x is still 5}// Thread - shared memoryvoid*thread_func(void*arg){int*x=(int*)arg;*x=6;// Changes for all threadsreturnNULL;}
Q: What is a race condition? How can you prevent it?
A: A race condition occurs when multiple threads access shared data concurrently, and the outcome depends on the order of execution.
Example of a race condition:
intcounter=0;void*increment(void*arg){for(inti=0;i<1000000;i++){counter++;// Race condition here}returnNULL;}intmain(){pthread_tt1,t2;pthread_create(&t1,NULL,increment,NULL);pthread_create(&t2,NULL,increment,NULL);pthread_join(t1,NULL);pthread_join(t2,NULL);printf("Counter: %d\n");// Will be less than 2000000}
Prevention methods:
- Mutex
pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;void*safe_increment(void*arg){for(inti=0;i<1000000;i++){pthread_mutex_lock(&mutex);counter++;pthread_mutex_unlock(&mutex);}returnNULL;}
- Atomic Operations
#include<stdatomic.h>atomic_intcounter=0;void*atomic_increment(void*arg){for(inti=0;i<1000000;i++){atomic_fetch_add(&counter,1);}returnNULL;}
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse