*** 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

TypePurpose
Compiler Symbol TableDuring compilation
Linker Symbol TableDuring 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?”

ReentrantThread-Safe
Safe during interruptionSafe in multithreading
Stronger propertyBroader 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

PointerMemory Access
NearCurrent segment only
FarMultiple segments
HugeMultiple 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

FeatureFunction PointerNormal Pointer
Stores Address OfFunctionVariable
Dereference MeaningFunction callVariable value
UsageCallbacksMemory 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?

FeatureMicrocontrollerMicroprocessor
ComponentsCPU + RAM + ROM + I/OCPU only
UsageEmbedded systemsGeneral-purpose computing
CostLowerHigher
Power ConsumptionLowHigher

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

FeatureUARTSPII2C
TypeAsynchronousSynchronousSynchronous
Wires Required242
SpeedModerateFastModerate
Multi-Device SupportLimitedYesYes
ComplexitySimpleMediumMedium

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

FeaturePollingInterrupt
CPU UsageHighEfficient
Response TimeSlowerFaster
ComplexitySimpleMore complex
Power EfficiencyLowerHigher

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

FeatureBootloaderFirmware
PurposeStarts systemRuns device functionality
Execution TimeExecutes firstExecutes after bootloader
SizeSmallerLarger
Main RoleLoad/update firmwareControl 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

FeatureStackHeap
Allocation SpeedFasterSlower
ManagementAutomaticManual
Cache LocalityBetterWorse
Memory SizeLimitedLarger

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

FlagMeaning
-O0No optimization
-O1Basic optimization
-O2Moderate optimization
-O3Aggressive 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

OperationComplexity
AccessO(1)
InsertO(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.