*** 1. Explain compilation process deeply.
The compilation process converts C source code into executable machine code.
Complete Compilation Flow
Source Code (.c)
↓
Preprocessor
↓
Expanded Source (.i)
↓
Compiler
↓
Assembly Code (.s)
↓
Assembler
↓
Object File (.o)
↓
Linker
↓
Executable File
1. Preprocessing
Handled by:
Preprocessor
Tasks
- Expands macros
- Includes header files
- Removes comments
- Processes conditional compilation
Example
#include <stdio.h>
#define PI 3.14
Output File
.i
2. Compilation
Converts expanded C code into assembly language.
Tasks
- Syntax checking
- Semantic analysis
- Optimization
Output File
.s
3. Assembly
Assembler converts assembly code into machine-level object code.
Output File
.o
4. Linking
Linker combines:
- Object files
- Library files
to create executable.
Tasks
- Symbol resolution
- Address binding
Output
Executable file
5. Loading
Loader places executable into memory and starts execution.
Memory Setup
- Stack
- Heap
- Data sections
Interview Insight
Very common question:
“At which stage are unresolved symbols fixed?”
Answer:
Linking stage
*** 2. What is symbol table?
A symbol table is a data structure maintained by compiler and linker.
It stores information about identifiers.
Stores Information Like
- Variable names
- Function names
- Data types
- Scope
- Memory addresses
Example
int x = 10;
Compiler stores:
Name: x
Type: int
Address: memory location
Uses
- Syntax checking
- Semantic analysis
- Linking
- Debugging
Types
| Type | Purpose |
|---|---|
| Compiler Symbol Table | During compilation |
| Linker Symbol Table | During linking |
Interview Insight
Very important system-level interview concept.
** 3. What is cache locality?
Cache locality means accessing memory locations close to each other to improve CPU cache performance.
Types of Locality
1. Temporal Locality
Recently used data is likely to be used again.
2. Spatial Locality
Nearby memory locations are likely to be accessed soon.
Example
for(int i = 0; i < n; i++) {
arr[i];
}
Array traversal has good cache locality.
Why Important?
Better locality means:
- Faster execution
- Fewer cache misses
- Better CPU performance
Poor Locality Example
Linked lists often have poor cache locality because nodes are scattered in memory.
Interview Insight
Very important in:
- Performance optimization
- System design
- High-performance computing
** 4. What are inline functions?
Inline functions suggest compiler replace function call with actual function code.
This reduces function call overhead.
Syntax
inline int add(int a, int b) {
return a + b;
}
Benefits
- Faster execution
- Reduces function call overhead
Drawback
May increase executable size due to code duplication.
Best Use Cases
- Small functions
- Frequently called functions
Interview Insight
Common question:
“Is inline guaranteed?”
No. Compiler may ignore inline request.
*** 5. What is sequence point?
A sequence point defines a point where all previous side effects are guaranteed to complete.
Example
i++;
Common Sequence Points
-
; -
&& -
|| -
, - Function call completion
Dangerous Example
i = i++;
This causes:
Undefined Behavior
because variable is modified multiple times between sequence points.
Safe Example
i++;
j = i;
Interview Insight
Very frequently asked tricky C interview topic.
** 6. What is reentrancy?
A reentrant function can be safely interrupted and called again before previous execution completes.
Features of Reentrant Functions
- No global/static data modification
- No shared mutable state
- Uses local variables only
Reentrant Example
int add(int a, int b) {
return a + b;
}
Non-Reentrant Example
static int count;
Uses
- Interrupt handlers
- Embedded systems
- Multithreading
Interview Insight
Reentrant functions are important in concurrent programming.
*** 7. What is thread safety?
Thread safety means code works correctly when accessed by multiple threads simultaneously.
Thread-Safe Code Prevents
- Race conditions
- Data corruption
- Inconsistent results
Example Using Mutex
pthread_mutex_lock(&lock);
count++;
pthread_mutex_unlock(&lock);
Thread-Safe Features
- Proper synchronization
- Controlled shared resource access
Common Techniques
- Mutex
- Semaphore
- Atomic operations
Interview Insight
Common question:
“Difference between reentrant and thread-safe?”
| Reentrant | Thread-Safe |
|---|---|
| Safe during interruption | Safe in multithreading |
| Stronger property | Broader concept |
*** 8. Why doesn’t C support function overloading?
Function overloading means multiple functions with same name but different parameters.
C does not support it because:
Function names are not mangled.
Example
int add(int a, int b);
float add(float a, float b);
This causes conflict in C.
Why C++ Supports It?
C++ uses:
Name Mangling
to differentiate functions internally.
Alternative in C
Use:
- Different function names
- Variadic functions
- Macros
Interview Insight
Very common theory question.
** 9. Can we compile program without main()?
Standard Answer
According to C standard:
main() is required
for program execution.
But Possible in Special Cases
Programs may compile without main():
- Object file creation
- Embedded systems
- Library creation
Example
void test() {
}
Compiles into object file:
gcc -c file.c
Executable Creation
Creating executable without main() usually causes linker error.
Interview Insight
Common question:
“Can executable run without main()?”
Normally no, unless custom startup code exists.
*** 10. How to call function before main()?
In GCC, functions can run before main() using:
__attribute__((constructor))
Example
#include <stdio.h>
void beforeMain() __attribute__((constructor));
void beforeMain() {
printf("Before main\n");
}
int main() {
printf("Inside main");
return 0;
}
Output
Before main
Inside main
How It Works
Compiler registers constructor function to execute before main().
Interview Insight
Very popular advanced C interview question.
Alternative approaches:
- Startup code
- Global object initialization (in C++)
* 11. Near, far, and huge pointers
These pointer types were used in older 16-bit DOS memory models.
Modern 32-bit/64-bit systems usually do not use them.
1. Near Pointer
A near pointer stores:
Offset address only
Features
- 16-bit pointer
- Can access only current memory segment
- Faster access
Limitation
Cannot access entire memory.
2. Far Pointer
A far pointer stores:
- Segment address
- Offset address
Features
- 32-bit pointer
- Can access different memory segments
Syntax
int far *ptr;
3. Huge Pointer
Similar to far pointer but automatically normalizes address.
Advantage
Can cross segment boundaries properly.
Key Difference
| Pointer | Memory Access |
|---|---|
| Near | Current segment only |
| Far | Multiple segments |
| Huge | Multiple segments with normalization |
Interview Insight
Mostly historical concepts asked in:
- Embedded interviews
- Legacy system discussions
*** 12. Smart ways to avoid pointer bugs
Pointer bugs are one of the biggest causes of crashes and security vulnerabilities in C.
Best Practices
1. Initialize Pointers
int *p = NULL;
2. Check malloc() Result
if(p == NULL)
3. Avoid Dangling Pointers
After free():
p = NULL;
4. Validate Array Bounds
Avoid:
arr[100]
if size is smaller.
5. Avoid Returning Local Variable Address
Wrong:
return &x;
6. Use Safer Functions
Prefer:
fgets()
instead of:
gets()
7. Use Debugging Tools
- Valgrind
- AddressSanitizer
- gdb
Interview Insight
Very important system programming topic.
** 13. Can pointer arithmetic be done on void pointers?
Standard C Answer
According to standard C:
No
because void has no size.
Why?
Pointer arithmetic depends on:
size of data type
But:
sizeof(void)
is invalid.
Example
void *p;
p++;
Standard C compiler may reject this.
GCC Extension
Some compilers like GCC allow it as extension by treating:
void
like:
char
Correct Approach
Typecast before arithmetic.
char *c = (char*)p;
c++;
Interview Insight
Very tricky pointer interview question.
*** 14. Function pointer vs normal pointer
| Feature | Function Pointer | Normal Pointer |
|---|---|---|
| Stores Address Of | Function | Variable |
| Dereference Meaning | Function call | Variable value |
| Usage | Callbacks | Memory access |
Normal Pointer Example
int x = 10;
int *p = &x;
Function Pointer Example
int (*fp)(int, int);
Calling
Normal Pointer
*p
Function Pointer
fp(2, 3)
Interview Insight
Function pointers are heavily used in:
- Callback systems
- Interrupt handlers
- Event-driven programming
*** 15. Callback mechanism in C
A callback is a function passed as argument to another function.
Usually implemented using:
Function pointers
Example
#include <stdio.h>
void display() {
printf("Callback Executed");
}
void execute(void (*func)()) {
func();
}
int main() {
execute(display);
return 0;
}
Output
Callback Executed
Uses
- Event handling
- Interrupt service routines
- GUI systems
- Library APIs
Interview Insight
Very common embedded systems interview concept.
*** 16. Explain memory corruption bugs
Memory corruption happens when program accidentally modifies invalid memory.
Common Causes
1. Buffer Overflow
char str[5];
gets(str);
2. Invalid Pointer Access
*p = 10;
when pointer is invalid.
3. Out-of-Bounds Access
arr[100]
Effects
- Crashes
- Data corruption
- Security vulnerabilities
- Unpredictable behavior
Prevention
- Bounds checking
- Safer APIs
- Memory debugging tools
Interview Insight
Critical security interview topic.
*** 17. Explain use-after-free vulnerabilities
Use-after-free occurs when freed memory is accessed again.
Example
int *p = malloc(sizeof(int));
free(p);
*p = 10;
Why Dangerous?
Freed memory may:
- Be reused
- Contain sensitive data
- Cause crashes
Security Risk
Attackers may exploit use-after-free bugs for:
- Arbitrary code execution
- Memory corruption
Prevention
After freeing:
p = NULL;
Interview Insight
Very important cybersecurity and system programming topic.
*** 18. Explain double-free vulnerabilities
Double-free occurs when:
free()
is called multiple times on same memory block.
Example
free(p);
free(p);
Problems
- Heap corruption
- Program crash
- Security vulnerabilities
Prevention
Set pointer to NULL after free.
free(p);
p = NULL;
Safe Behavior
free(NULL);
is safe in C.
Interview Insight
Very common low-level security interview topic.
*** 19. Difference between microcontroller and microprocessor?
| Feature | Microcontroller | Microprocessor |
|---|---|---|
| Components | CPU + RAM + ROM + I/O | CPU only |
| Usage | Embedded systems | General-purpose computing |
| Cost | Lower | Higher |
| Power Consumption | Low | Higher |
Microcontroller Examples
- Arduino
- PIC
- AVR
Microprocessor Examples
- Intel Core
- AMD Ryzen
Applications
Microcontroller
- Washing machines
- IoT devices
- Embedded systems
Microprocessor
- Laptops
- PCs
- Servers
Interview Insight
Very common embedded systems interview question.
*** 20. What is memory-mapped I/O?
Memory-mapped I/O means hardware devices are accessed using normal memory addresses.
Concept
Special memory addresses are assigned to:
- Registers
- Hardware devices
Example
#define PORTA (*(volatile unsigned int*)0x4000)
Access Device
PORTA = 1;
Why volatile?
Hardware values may change unexpectedly.
Advantages
- Faster hardware access
- Simple programming model
Common Uses
- Embedded systems
- Device drivers
- Operating systems
Interview Insight
Very important embedded and OS interview topic.
*** 21. What is ISR (Interrupt Service Routine)?
An ISR (Interrupt Service Routine) is a special function executed automatically when an interrupt occurs.
It is also called:
Interrupt Handler
Purpose
Handles urgent events like:
- Keyboard input
- Timer events
- Sensor signals
- Hardware communication
Flow
Interrupt Occurs
↓
CPU pauses current task
↓
ISR executes
↓
CPU resumes previous task
Example
void ISR_Timer() {
timerFlag = 1;
}
Important Features
- Executes quickly
- Hardware-triggered
- High priority
Interview Insight
Very important embedded systems interview topic.
*** 22. Best practices for writing ISRs?
ISRs should be:
Short, fast, and efficient
Best Practices
1. Keep ISR Short
Avoid lengthy operations.
2. Avoid Delays
Do not use:
delay()
sleep()
inside ISR.
3. Avoid Heavy Computation
Complex logic increases interrupt latency.
4. Use volatile Variables
Shared variables should be:
volatile
5. Avoid Dynamic Memory Allocation
Avoid:
malloc()
free()
inside ISR.
6. Minimize Global Variable Access
Prevents race conditions.
7. Clear Interrupt Flags Properly
Otherwise interrupt may repeatedly trigger.
Interview Insight
Very common question:
“Why should ISRs be short?”
Because long ISRs block other interrupts and reduce system responsiveness.
** 23. What is watchdog timer (WDT)?
A Watchdog Timer (WDT) is a hardware timer used to detect software hangs or failures.
Working
Program must periodically reset:
feed/kick the watchdog
If not reset in time:
System automatically resets
Purpose
Improves:
- Reliability
- Fault recovery
- System stability
Common Uses
- Embedded systems
- Automotive systems
- Medical devices
Example Flow
Program running normally
↓
WDT refreshed regularly
↓
If software hangs
↓
WDT timeout occurs
↓
System reset
Interview Insight
Very common embedded interview question.
*** 24. UART vs SPI vs I2C
These are communication protocols used in embedded systems.
Comparison Table
| Feature | UART | SPI | I2C |
|---|---|---|---|
| Type | Asynchronous | Synchronous | Synchronous |
| Wires Required | 2 | 4 | 2 |
| Speed | Moderate | Fast | Moderate |
| Multi-Device Support | Limited | Yes | Yes |
| Complexity | Simple | Medium | Medium |
1. UART
Features
- TX and RX lines
- No clock signal
Uses
- Serial communication
- GPS modules
- Bluetooth modules
2. SPI
Features
- Full duplex
- Very fast
Signals
MOSI
MISO
SCK
SS
Uses
- SD cards
- Displays
- Sensors
3. I2C
Features
- Two-wire protocol
- Multiple devices supported
Signals
SDA
SCL
Uses
- EEPROM
- RTC modules
- Sensors
Interview Insight
Very frequently asked embedded interview topic.
*** 25. Polling vs interrupt
| Feature | Polling | Interrupt |
|---|---|---|
| CPU Usage | High | Efficient |
| Response Time | Slower | Faster |
| Complexity | Simple | More complex |
| Power Efficiency | Lower | Higher |
Polling
CPU continuously checks device status.
Example
while(flag == 0) {
}
Interrupt
Hardware notifies CPU only when event occurs.
Advantage
CPU can perform other tasks meanwhile.
Best Use Cases
Polling
- Simple systems
Interrupt
- Real-time systems
- Time-critical systems
Interview Insight
Common question:
“Why are interrupts preferred?”
Because they improve CPU efficiency.
** 26. What is real-time system?
A real-time system is a system where correctness depends on:
- Logical result
- Timing of result
Important Point
Task must complete within:
Deadline
Types of Real-Time Systems
1. Hard Real-Time
Missing deadline is unacceptable.
Examples
- Airbags
- Medical devices
2. Soft Real-Time
Occasional delay acceptable.
Examples
- Video streaming
- Gaming
Features
- Predictable timing
- Fast response
- Reliability
Interview Insight
Very important embedded systems concept.
*** 27. What is race condition?
A race condition occurs when multiple threads/tasks access shared data simultaneously and outcome depends on execution order.
Example
count++;
Two threads updating same variable may produce incorrect result.
Problems
- Data corruption
- Inconsistent output
- Random bugs
Prevention
Use:
- Mutex
- Semaphore
- Atomic operations
Example
pthread_mutex_lock(&lock);
count++;
pthread_mutex_unlock(&lock);
Interview Insight
Very common multithreading interview question.
*** 28. Role of volatile in embedded systems
volatile tells compiler:
Variable may change unexpectedly
Why Important?
Embedded systems interact with:
- Hardware registers
- ISRs
- Shared memory
Example
volatile int flag;
Without volatile
Compiler may optimize variable access incorrectly.
Common Uses
- Hardware registers
- Interrupt flags
- Memory-mapped I/O
Interview Insight
Very frequently asked embedded C interview topic.
*** 29. How to access hardware registers in Embedded C?
Hardware registers are usually accessed using:
Memory-mapped I/O
Example
#define PORTA (*(volatile unsigned int*)0x4000)
Write to Register
PORTA = 1;
Read from Register
int value = PORTA;
Why volatile?
Register values may change due to hardware activity.
Interview Insight
Very important low-level embedded programming concept.
** 30. Bootloader vs firmware
| Feature | Bootloader | Firmware |
|---|---|---|
| Purpose | Starts system | Runs device functionality |
| Execution Time | Executes first | Executes after bootloader |
| Size | Smaller | Larger |
| Main Role | Load/update firmware | Control hardware behavior |
Bootloader
Small program that:
- Initializes hardware
- Loads firmware
- Supports firmware updates
Examples
- BIOS
- U-Boot
Firmware
Software permanently programmed into device memory.
Controls:
- Hardware
- Device operations
Examples
- Router firmware
- Washing machine firmware
Flow
Power ON
↓
Bootloader executes
↓
Firmware loads
↓
Device operates
Interview Insight
Very common embedded systems interview topic.
*** 31. Common optimization techniques in C
Optimization techniques improve:
- Execution speed
- Memory usage
- CPU efficiency
Common Techniques
1. Use Efficient Algorithms
Algorithm optimization gives biggest performance gain.
Example
O(n log n) faster than O(n²)
2. Minimize Function Calls
Use:
inline
for small frequently used functions.
3. Reduce Memory Access
Store frequently used values in local variables.
4. Use Bitwise Operations
Example:
x << 1
instead of:
x * 2
5. Improve Cache Locality
Access contiguous memory sequentially.
6. Avoid Unnecessary Dynamic Allocation
Heap allocation is slower than stack allocation.
7. Loop Optimization
- Loop unrolling
- Reduce repeated calculations
8. Compiler Optimization Flags
-O1
-O2
-O3
Interview Insight
Very common question:
“What optimization should be avoided first?”
Premature optimization without profiling.
*** 32. What are common runtime errors in C?
Runtime errors occur during program execution.
Common Runtime Errors
1. Segmentation Fault
Invalid memory access.
2. Null Pointer Dereference
*p = 10;
when pointer is NULL.
3. Buffer Overflow
Writing outside array bounds.
4. Division by Zero
x / 0
5. Stack Overflow
Deep or infinite recursion.
6. Memory Leak
Allocated memory not freed.
7. Use-After-Free
Accessing memory after:
free()
8. Double-Free
Freeing same memory twice.
Interview Insight
Debugging tools:
- gdb
- Valgrind
- AddressSanitizer
are commonly discussed in interviews.
*** 33. Explain heap vs stack performance
| Feature | Stack | Heap |
|---|---|---|
| Allocation Speed | Faster | Slower |
| Management | Automatic | Manual |
| Cache Locality | Better | Worse |
| Memory Size | Limited | Larger |
Stack Performance
Advantages
- Very fast allocation/deallocation
- Good cache locality
Example
int x;
Heap Performance
Advantages
- Dynamic memory allocation
- Flexible size
Drawbacks
- Slower allocation
- Fragmentation possible
Example
malloc(sizeof(int));
Interview Insight
Very common question:
“Why is stack faster than heap?”
Because stack uses simple pointer movement while heap requires memory management logic.
*** 34. Explain memory alignment impact on performance
Memory alignment means storing data at addresses suitable for CPU architecture.
Example
An int may be aligned at:
4-byte boundary
Why Important?
Aligned memory access:
- Faster
- Requires fewer CPU cycles
Misaligned access:
- Slower
- May require multiple memory operations
Example
struct Test {
char c;
int x;
};
Compiler may add padding for alignment.
Benefits of Alignment
- Better CPU efficiency
- Faster cache access
Interview Insight
Very important low-level systems topic.
*** 35. Explain stack overflow in recursion
Stack overflow occurs when recursion consumes too much stack memory.
Main Causes
1. Infinite Recursion
No base condition.
2. Very Deep Recursion
Too many recursive calls.
Example
void test() {
test();
}
What Happens?
Each recursive call creates new stack frame until stack memory is exhausted.
Result
Program crash
Prevention
- Proper base condition
- Use iterative approach when possible
Interview Insight
Very common recursion interview question.
*** 36. How recursion uses stack memory
Each recursive call creates a new:
Stack Frame
Stack Frame Contains
- Function parameters
- Local variables
- Return address
Example
factorial(3)
creates:
factorial(3)
factorial(2)
factorial(1)
Execution Flow
Calls are pushed into stack and removed after completion.
Visualization
Top
-----
f(1)
f(2)
f(3)
-----
Bottom
Interview Insight
Very important concept for recursion debugging.
*** 37. Explain cache-friendly programming
Cache-friendly programming improves CPU cache usage for better performance.
Key Idea
Access nearby memory locations together.
Good Example
for(int i = 0; i < n; i++) {
arr[i];
}
Sequential array access has good cache locality.
Poor Example
Linked list traversal often has poor locality because nodes are scattered.
Benefits
- Faster execution
- Fewer cache misses
- Better CPU utilization
Common Techniques
- Use arrays instead of linked lists when possible
- Access memory sequentially
- Reduce random memory access
Interview Insight
Very important performance optimization topic.
** 38. Explain compiler optimizations
Compiler optimizations improve generated machine code performance.
Common Optimization Levels
| Flag | Meaning |
|---|---|
-O0 | No optimization |
-O1 | Basic optimization |
-O2 | Moderate optimization |
-O3 | Aggressive optimization |
Common Compiler Optimizations
1. Constant Folding
2 + 3
becomes:
5
2. Dead Code Elimination
Unused code removed.
3. Inline Expansion
Function calls replaced with function body.
4. Loop Optimization
Improves loop execution efficiency.
5. Register Allocation
Frequently used variables stored in CPU registers.
Interview Insight
Very common question:
“Can optimization change program behavior?”
Yes, especially if program contains undefined behavior.
*** 39. Reverse linked list iteratively and recursively
1. Iterative Reversal
Logic
Use:
-
prev -
current -
next
Program
struct Node* reverse(struct Node* head) {
struct Node *prev = NULL;
struct Node *current = head;
struct Node *next = NULL;
while(current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
Time Complexity
O(n)
Space Complexity
O(1)
2. Recursive Reversal
Program
struct Node* reverse(struct Node* head) {
if(head == NULL || head->next == NULL)
return head;
struct Node* rest = reverse(head->next);
head->next->next = head;
head->next = NULL;
return rest;
}
Time Complexity
O(n)
Space Complexity
O(n)
due to recursion stack.
Interview Insight
Very frequently asked linked-list coding problem.
*** 40. Detect loop in linked list (Floyd cycle detection)
Floyd Cycle Detection Algorithm uses:
- Slow pointer
- Fast pointer
Logic
Slow Pointer
Moves:
1 step
Fast Pointer
Moves:
2 steps
If loop exists:
Both pointers meet
Program
int hasCycle(struct Node *head) {
struct Node *slow = head;
struct Node *fast = head;
while(fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return 1;
}
return 0;
}
Time Complexity
O(n)
Space Complexity
O(1)
Interview Insight
Also called:
Tortoise and Hare Algorithm
Very common DSA interview question.
*** 41. Implement stack using array and linked list
A stack follows:
LIFO (Last In First Out)
1. Stack Using Array
Program
#include <stdio.h>
#define SIZE 5
int stack[SIZE];
int top = -1;
void push(int value) {
if(top == SIZE - 1) {
printf("Stack Overflow");
return;
}
stack[++top] = value;
}
void pop() {
if(top == -1) {
printf("Stack Underflow");
return;
}
printf("%d popped\n", stack[top--]);
}
Advantages
- Simple
- Fast access
Limitation
Fixed size.
2. Stack Using Linked List
Program
struct Node {
int data;
struct Node *next;
};
struct Node *top = NULL;
Push
void push(int value) {
struct Node *newNode =
malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = top;
top = newNode;
}
Advantage
Dynamic size.
Interview Insight
Very common DSA implementation question.
*** 42. Implement queue using array and linked list
Queue follows:
FIFO (First In First Out)
1. Queue Using Array
Program
#define SIZE 5
int queue[SIZE];
int front = -1;
int rear = -1;
Enqueue
void enqueue(int value) {
if(rear == SIZE - 1)
return;
if(front == -1)
front = 0;
queue[++rear] = value;
}
Dequeue
void dequeue() {
if(front == -1 || front > rear)
return;
printf("%d", queue[front++]);
}
2. Queue Using Linked List
Structure
struct Node {
int data;
struct Node *next;
};
Advantage
Dynamic memory allocation.
Interview Insight
Frequently asked comparison:
Array Queue -> fixed size
Linked List Queue -> dynamic size
*** 43. LRU Cache basic implementation
LRU means:
Least Recently Used
Concept
When cache is full:
- Remove least recently accessed item.
Common Implementation
Use:
- Hash map
- Doubly linked list
Operations
| Operation | Complexity |
|---|---|
| Access | O(1) |
| Insert | O(1) |
Basic Logic
Recent items -> front
Old items -> rear
Applications
- CPU cache
- Browser cache
- Database cache
Interview Insight
Very common system design + DSA interview topic.
** 44. Memory allocator mini implementation
A mini memory allocator manages memory blocks manually.
Basic Idea
Maintain
- Free list
- Allocated blocks
Structure
struct Block {
size_t size;
int free;
struct Block *next;
};
Allocation Flow
Find free block
↓
Mark allocated
↓
Return memory
Free Flow
Mark block free
Important Concepts
- Heap management
- Fragmentation
- Block splitting
Interview Insight
Very important low-level systems interview topic.
** 45. String compression implementation
Compress repeated characters.
Example
Input:
aaabbc
Output:
a3b2c1
Program
#include <stdio.h>
int main() {
char str[] = "aaabbc";
int count = 1;
for(int i = 0; str[i] != '\0'; i++) {
while(str[i] == str[i + 1]) {
count++;
i++;
}
printf("%c%d", str[i], count);
count = 1;
}
return 0;
}
Output
a3b2c1
Interview Insight
Frequently asked string manipulation problem.
*** 46. Implement your own malloc() conceptually
Custom malloc() usually works using:
- Heap memory
- Free block tracking
Basic Steps
1. Maintain Free List
struct Block {
size_t size;
int free;
};
2. Search Free Block
Find suitable free memory.
3. Split Block
If block is larger than required.
4. Return Pointer
Provide usable memory to caller.
Conceptual Flow
Request memory
↓
Search free list
↓
Allocate block
↓
Return pointer
Free Operation
Marks block reusable.
Interview Insight
Very important systems programming interview question.
*** 47. Write your own strlen(), strcpy(), memcpy()
1. strlen()
Program
int my_strlen(char *str) {
int len = 0;
while(str[len] != '\0') {
len++;
}
return len;
}
2. strcpy()
Program
void my_strcpy(char *dest, char *src) {
while(*src != '\0') {
*dest = *src;
dest++;
src++;
}
*dest = '\0';
}
3. memcpy()
Program
void *my_memcpy(void *dest,
const void *src,
int n) {
char *d = dest;
const char *s = src;
for(int i = 0; i < n; i++) {
d[i] = s[i];
}
return dest;
}
Interview Insight
Very common library implementation interview question.
** 48. Implement mini shell/token parser
A mini shell parser splits command input into tokens.
Example
Input:
ls -l file.txt
Tokens:
ls
-l
file.txt
Program
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "ls -l file.txt";
char *token =
strtok(str, " ");
while(token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " ");
}
return 0;
}
Output
ls
-l
file.txt
Interview Insight
Common systems programming question.
*** 49. Write thread-safe singleton in C
Singleton allows only one instance globally.
Thread-Safe Singleton Example
#include <pthread.h>
#include <stdlib.h>
typedef struct {
int value;
} Singleton;
Singleton *instance = NULL;
pthread_mutex_t lock =
PTHREAD_MUTEX_INITIALIZER;
Singleton* getInstance() {
pthread_mutex_lock(&lock);
if(instance == NULL) {
instance =
malloc(sizeof(Singleton));
}
pthread_mutex_unlock(&lock);
return instance;
}
Why Mutex?
Prevents:
Race conditions
Interview Insight
Very common multithreading interview topic.
*** 50. Explain Linux kernel usage of C
Linux kernel is primarily written in C because C provides:
- Low-level hardware access
- High performance
- Portability
Why C is Used?
1. Direct Memory Access
Pointers enable hardware interaction.
2. Performance
Compiled to efficient machine code.
3. Hardware Control
Supports:
- Memory-mapped I/O
- Interrupt handling
- Device drivers
4. Portability
Kernel can run on multiple architectures.
Linux Kernel Uses C For
- Process management
- Memory management
- Device drivers
- File systems
- Networking
Small Assembly Usage
Assembly is used only for:
- Boot code
- Context switching
- Architecture-specific operations
Interview Insight
Very common system programming interview question.
Important point:
C provides balance between low-level control and portability.