C Programming with DSA Interview Questions in Bhubaneswar
36 practice questions with answers for C Programming with DSA interviews in Bhubaneswar.
C Programming with DSA jobs in Bhubaneswar
Bhubaneswar is eastern India's emerging IT hub, with campuses of large IT-services companies in Infocity and Info Valley. Freshers make up a big share of hiring, so fundamentals and aptitude rounds matter most.
Below are 36 questions that match the mix of service, product and domain employers hiring c developers in Bhubaneswar.
Solved for BhubaneswarStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
A function pointer stores the address of a function, declared like int (*op)(int, int) = add;, and called with op(2, 3). It enables callbacks such as the comparator in qsort, dispatch tables replacing long switch statements, plugin interfaces and state machines in embedded code. Using typedef makes function pointer types much more readable.
02
What is the difference between greedy algorithms and dynamic programming?
A greedy algorithm makes the best local choice at each step and never revisits it, which works only when the greedy choice property holds, as in activity selection, Huffman coding and Dijkstra. Dynamic programming considers all relevant subproblem choices and combines them, so it works where greedy fails, such as 0/1 knapsack or coin change with arbitrary denominations. Greedy is faster when provably correct.
03
What is the difference between an array and a pointer?
An array is a block of contiguous elements whose size is fixed and known to the compiler; sizeof gives the full array size. A pointer is a variable holding an address; sizeof gives the pointer size. An array name decays to a pointer to its first element in most expressions, but it cannot be reassigned. When passed to a function, an array always becomes a pointer, losing its length.
A topological sort orders the vertices of a directed acyclic graph so every edge goes from earlier to later. Kahn's algorithm repeatedly removes vertices with zero in-degree using a queue; DFS adds vertices to the order after finishing their descendants. If not all vertices are processed, the graph has a cycle. It is used for build systems, course prerequisites and task scheduling.
05
A doubly linked list delete function leaves the list broken when deleting the head. What is missing?
When deleting the head there is no previous node, so the head pointer itself must move to head->next, and the new head's prev must be set to NULL. Similarly, deleting the tail needs the new tail's next set to NULL. The fix is to check node->prev and node->next for NULL and update head or tail pointers accordingly, or use a sentinel node to avoid these cases.
06
Tell me about a time you chose the right data structure under pressure.
Situation: during a hackathon our C route planner was too slow to answer queries live. Task: fix it within a few hours. Action: I profiled it, found repeated linear searches of a list of stops and replaced them with a hash table keyed by stop id, plus a queue for BFS. Result: queries went from 4 seconds to 30 ms and we won second place.
07
How do you handle a situation where requirements change late in a project?
Situation: two weeks before release, the client asked to add a new field to our device's binary log format. Task: add it without breaking older files. Action: I explained the risk, added a version byte to the header, wrote a reader that handled both versions and tested with old and new samples. Result: we shipped on time and older devices kept working without a firmware update.
Two pointers keep two indexes that move through an array according to a rule, often from both ends of a sorted array or at different speeds. It solves pair sum on sorted arrays, removing duplicates in place, reversing, merging sorted arrays and partitioning. It usually gives O(n) time and O(1) extra space instead of nested loops.
10
An interview asks for the minimum number of coins to make an amount. How do you approach it?
Greedy fails for some coin sets, such as coins 1, 3, 4 with amount 6, where greedy gives three coins but two coins of 3 is optimal. Use DP: dp[0] = 0 and dp[x] = 1 + min over coins c of dp[x - c], filling from 1 to the amount. Time is O(amount times coins) and space O(amount). Report -1 if the amount cannot be formed.
11
What is the difference between malloc, calloc, realloc and free?
malloc(size) allocates uninitialised memory. calloc(n, size) allocates memory for n elements and sets all bytes to zero, and it checks n times size for overflow. realloc(ptr, size) resizes a block, possibly moving it, and returns the new address. free(ptr) releases memory back to the allocator. All allocators return NULL on failure, so always check the result.
12
A strlen call crashes on a buffer received from a network packet. What is wrong?
Network data is not guaranteed to be null terminated, so strlen keeps reading past the buffer until it hits a zero byte or invalid memory. Always track the received byte count and use length-aware functions such as memchr, strnlen or memcpy with explicit sizes. If you need a C string, allocate one extra byte and add the terminator yourself after checking the length.
13
Tell me about a project where you worked with files or binary data in C.
Situation: in my final year project we logged GPS data on a microcontroller SD card. Task: store records reliably with small memory. Action: I designed a packed 16 byte record with fixed-width types, wrote it with a checksum, flushed every ten records and wrote a PC tool to decode the file. Result: we logged a full day with no corruption and could replay any trip.
14
Insert a node at the end of a singly linked list using a double pointer.
A pointer to pointer handles the empty list without special cases.
int append(Node **head, int value) {
Node *n = malloc(sizeof *n);
if (!n) return -1;
n->data = value;
n->next = NULL;
while (*head) head = &(*head)->next;
*head = n;
return 0;
}
Call it as append(&head, 5). Keep a tail pointer if you append often.
15
A program that writes logs with fprintf loses the last lines when it crashes. Why, and how do you fix it?
stdio streams are buffered, so fprintf stores data in memory and writes it to disk only when the buffer fills, the file closes or fflush is called. A crash loses whatever is still in the buffer. Call fflush after important log lines, set line buffering with setvbuf(fp, NULL, _IOLBF, 0) or write critical messages to unbuffered stderr. For durability on disk, add fsync on POSIX systems.
A singly linked list has a next pointer only and can be traversed one way. A doubly linked list adds a prev pointer, allowing backward traversal and O(1) deletion of a known node, at the cost of more memory. A circular linked list links the last node back to the first, useful for round-robin scheduling. Variants include lists with sentinel or dummy head nodes.
A stack is a last in, first out structure with push, pop and peek operations, all O(1). It is used for function call frames, undo features, expression evaluation, balanced bracket checking, backtracking and depth first search. In C you implement it with an array and a top index, or with a linked list when the size is not known in advance.
18
Use a tagged union to store either an int, a float or a string value.
feof() becomes true only after a read has already failed at end of file. The loop checks feof before reading, so the final failed read leaves the old buffer content, which is processed again. Loop on the read function's return value instead, such as while (fgets(line, sizeof line, fp) != NULL), and check ferror after the loop.
An enum defines a set of named integer constants, such as enum Color { RED, GREEN, BLUE };, where values start at 0 unless set. It makes code readable and lets compilers warn about missing cases in a switch with -Wswitch. Enum values are int sized in practice, and C23 allows specifying the underlying type. Use them for states, commands and error codes.
21
Your linked list program crashes when deleting the last node. What do you check?
Check that the previous node's next pointer is set to NULL after freeing the last node, that the tail pointer is updated if you keep one and that you do not access the node after free. Also handle the case of a one-node list where head itself must become NULL, which requires passing a pointer to the head pointer. Run the code under AddressSanitizer to find invalid accesses.
22
Write a function that dynamically allocates an array of n integers and fills it with squares.
Check the allocation and let the caller free it.
int *makeSquares(size_t n) {
int *arr = malloc(n * sizeof *arr);
if (arr == NULL) return NULL;
for (size_t i = 0; i < n; i++) {
arr[i] = (int)(i * i);
}
return arr;
}
// caller
int *a = makeSquares(10);
if (a) { /* use */ free(a); }
23
What is a hash table and how are collisions handled?
A hash table maps keys to array slots using a hash function, giving O(1) average insert, search and delete. Collisions happen when two keys map to the same slot. Separate chaining stores a linked list per slot. Open addressing probes for another free slot using linear probing, quadratic probing or double hashing. Keep the load factor low and resize when it grows to maintain speed.
C stores multidimensional arrays in row-major order: all elements of row 0, then row 1 and so on, in one contiguous block. Element a[i][j] of an array with C columns is at offset i * C + j. Traversing row by row is cache friendly and much faster than column by column for large matrices. When passing a 2D array to a function, every dimension except the first must be specified.
25
How do you pass a structure to a function efficiently?
Passing a struct by value copies every member, which is costly for large structs. Pass a pointer instead, and add const when the function should only read it, such as void print(const Student *s). Access members with s->name. Small structs of a few bytes can be passed by value safely, and returning small structs by value is also fine.
26
Write BFS on a graph stored as an adjacency matrix.
Use a queue and a visited array.
void bfs(int n, int adj[n][n], int start) {
int visited[n], queue[n], front = 0, rear = 0;
for (int i = 0; i < n; i++) visited[i] = 0;
visited[start] = 1;
queue[rear++] = start;
while (front < rear) {
int u = queue[front++];
printf("%d ", u);
for (int v = 0; v < n; v++) {
if (adj[u][v] && !visited[v]) {
visited[v] = 1;
queue[rear++] = v;
}
}
}
}
27
Two source files both define a global variable named count and the build fails. How do you fix it?
Each global may be defined only once. Define it in one .c file, such as int count = 0;, and declare it in a shared header as extern int count;, which other files include. If the variable should be private to each file, mark it static in both files instead. Since GCC 10, -fno-common is default, so duplicate tentative definitions also fail to link.
28
You must schedule the maximum number of non-overlapping meetings in one room. What algorithm do you use?
This is activity selection, solved greedily. Sort meetings by end time, then pick each meeting whose start is not earlier than the end of the last picked one. Choosing the earliest finishing meeting always leaves the most room for the rest, which can be proven by an exchange argument. Sorting dominates, giving O(n log n) time.
29
Why do linked lists perform poorly compared to arrays on modern CPUs?
Each node is allocated separately and may sit anywhere in memory, so traversing a list causes frequent cache misses and the CPU cannot prefetch well. Arrays store elements contiguously, so a cache line brings several elements at once. Even with O(1) insertion, linked lists are often slower in practice. Use them when frequent insertions in the middle with stable node addresses really matter.
Kadane's algorithm finds the maximum sum contiguous subarray in O(n). It keeps the best sum ending at the current index: cur = max(a[i], cur + a[i]), and updates the global best with best = max(best, cur). If the running sum becomes worse than starting fresh, it starts a new subarray. Initialise with the first element to handle arrays where all numbers are negative.
31
Write C code to count the number of set bits in an integer.
Brian Kernighan's trick clears the lowest set bit each step.
int countBits(unsigned int n) {
int count = 0;
while (n) {
n &= n - 1;
count++;
}
return count;
}
It runs once per set bit. GCC and Clang also offer __builtin_popcount(n), which uses a CPU instruction when available.
A queue is first in, first out with enqueue at the rear and dequeue at the front, both O(1). Variants are the circular queue, which reuses array space; the deque, which allows insertion and removal at both ends; and the priority queue, which removes the highest priority element first. Queues are used in BFS, task scheduling, print spooling and buffering data between producers and consumers.
33
What is the difference between char s[] = "hello" and char *s = "hello"?
char s[] = "hello" creates a modifiable array of 6 bytes, usually on the stack, initialised with a copy of the literal. char *s = "hello" makes a pointer to a string literal stored in read-only memory; modifying it is undefined behaviour and often crashes. Declare such pointers as const char * so the compiler catches accidental writes.
34
You need to find the shortest route between two cities on a map with distances. Which algorithm do you use and why?
Road distances are non-negative, so Dijkstra's algorithm with a min heap is the right choice, giving O((V + E) log V). If you only need one target, stop when it is popped from the heap. For very large maps, A star with a straight-line distance heuristic explores fewer nodes. If some edges had negative costs, Bellman-Ford would be needed.
auto is the default for local variables, stored on the stack with block lifetime. register hints the variable should live in a CPU register, and its address cannot be taken. static gives a local variable lifetime for the whole program, or limits a global to its file. extern declares a variable defined in another file. Storage class decides scope, lifetime and linkage.
36
How do you convert an infix expression to postfix?
Use the shunting yard algorithm with an operator stack. Output operands directly. For an operator, pop operators of higher precedence, or equal precedence if left associative, to the output, then push it. Push '(' and on ')' pop until the matching '('. At the end, pop all remaining operators. For example a + b * c becomes a b c * +. Postfix is easy to evaluate with a stack.
Few big employers listed in Bhubaneswar?
Many Bhubaneswar candidates also apply to teams in Kolkata and to remote or hybrid roles. Practise the Kolkata set as well.
Which companies hire C Programming with DSA professionals in Bhubaneswar?
Companies with large offices in Bhubaneswar include many IT services and product firms. Use their company pages below to practise employer-specific sets.
Are C Programming with DSA interviews in Bhubaneswar different from other cities?
The questions depend more on the company than the city. Bhubaneswar's mix of employers decides the style: Freshers make up a big share of hiring, so fundamentals and aptitude rounds matter most
How do I find C Programming with DSA jobs in Bhubaneswar?
Shortlist companies with Bhubaneswar offices, keep your CV focused on C Programming with DSA projects, apply on company career pages and job portals with the Bhubaneswar filter, and practise the questions on this page before each interview.