Skip to content

C Programming with DSA Interview Questions in Mumbai

36 practice questions with answers for C Programming with DSA interviews in Mumbai.

C Programming with DSA jobs in Mumbai

Mumbai is India's financial capital, so banks, fintechs, insurers, media and consulting firms drive much of the hiring. Data and QA interviews often include domain questions on payments, risk, trading or customer analytics.

Below are 36 questions that match the mix of service, product and domain employers hiring c developers in Mumbai.

Solved for MumbaiStart 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.
3 questions free Unlock the rest in seconds
01

Reverse a string in place in C.

Save to ▾
Show answer
Swap characters from both ends moving inward. void reverse(char *s) { size_t n = strlen(s); if (n < 2) return; for (size_t i = 0, j = n - 1; i < j; i++, j--) { char t = s[i]; s[i] = s[j]; s[j] = t; } } Time O(n) and O(1) extra space. The string must be a modifiable array, not a literal.
02

What is the sliding window technique?

Save to ▾
Show answer
Sliding window solves problems on contiguous subarrays or substrings by keeping a window with two indexes and moving them forward instead of rechecking every subarray. A fixed window finds things like the maximum sum of k elements, while a variable window expands and shrinks, as in the longest substring without repeating characters. It turns O(n squared) brute force into O(n).
03

What is the difference between a complete, full and perfect binary tree?

Save to ▾
Show answer
A full binary tree has every node with zero or two children. A complete binary tree has all levels filled except possibly the last, which is filled from left to right; heaps use this shape so they fit an array. A perfect binary tree has all internal nodes with two children and all leaves at the same level, so it has 2 to the power h+1 minus 1 nodes.
04

What is a prefix sum array and why is it useful?

Save to ▾
Show answer
A prefix sum array stores pre[i] = sum of elements from index 0 to i-1. Then the sum of any range from l to r is pre[r + 1] - pre[l] in O(1) after O(n) preprocessing. It is used for range sum queries, counting subarrays with a given sum together with a hash map, and 2D versions for matrix region sums.
05

An interview asks for the minimum number of coins to make an amount. How do you approach it?

Save to ▾
Show answer
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.
06

Your linked list program crashes when deleting the last node. What do you check?

Save to ▾
Show answer
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.
07

Tell me about a time you explained a complex data structure to your team.

Save to ▾
Show answer
Situation: our team needed an LRU cache in a C service and several members had not built one. Task: align everyone before coding. Action: I drew the hash table and doubly linked list on a whiteboard, walked through get and put with a small example and shared a short test suite covering edge cases. Result: the team implemented it in two days with no major review issues.
08

Find the height of a binary tree in C.

Save to ▾
Show answer
Height is one plus the larger subtree height. int height(const TNode *root) { if (root == NULL) return 0; int lh = height(root->left); int rh = height(root->right); return 1 + (lh > rh ? lh : rh); } This counts nodes on the longest root to leaf path; return -1 for empty trees if height is defined in edges. Time O(n).
09

What is dynamic programming?

Save to ▾
Show answer
Dynamic programming solves problems that have overlapping subproblems and optimal substructure by storing results of subproblems instead of recomputing them. Top-down memoisation caches recursive calls, while bottom-up tabulation fills a table iteratively. Classic examples are Fibonacci, 0/1 knapsack, longest common subsequence, coin change and edit distance. Defining the state and transition clearly is the hardest part.
10

What is the difference between malloc, calloc, realloc and free?

Save to ▾
Show answer
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.
11

A program that writes logs with fprintf loses the last lines when it crashes. Why, and how do you fix it?

Save to ▾
Show answer
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.
12

What is a circular linked list and where is it used?

Save to ▾
Show answer
In a circular linked list the last node points back to the first, so there is no NULL end. You can start at any node and visit all nodes, and keeping only a tail pointer gives O(1) access to both ends. It is used in round-robin CPU scheduling, multiplayer turn order and circular buffers. Traversal loops must stop when they return to the starting node.
13

A hash table becomes slow as more data is inserted. What is wrong?

Save to ▾
Show answer
The load factor has grown, so chains get long or open addressing probes become long, turning O(1) into nearly O(n). Another cause is a poor hash function clustering keys into few buckets. Fix it by resizing to roughly double capacity and rehashing when the load factor crosses a threshold, and by using a better hash function. Measure the longest chain to confirm.
14

Your program sorts 1 crore integers in the range 0 to 999 and qsort is too slow. What would you do?

Save to ▾
Show answer
With a small known range, use counting sort: count occurrences in an array of 1000 counters, then rewrite the array in order. It runs in O(n + k) time with only 1000 extra integers, far faster than O(n log n) comparison sorts. For larger ranges, radix sort on bytes works well. qsort also pays a function call per comparison through its comparator pointer.
15

Merge two sorted linked lists into one sorted list.

Save to ▾
Show answer
A dummy node keeps the code simple. Node *mergeSorted(Node *a, Node *b) { Node dummy = {0, NULL}; Node *tail = &dummy; while (a && b) { if (a->data <= b->data) { tail->next = a; a = a->next; } else { tail->next = b; b = b->next; } tail = tail->next; } tail->next = a ? a : b; return dummy.next; } It reuses existing nodes in O(n + m) time.
16

What is the difference between const int *p, int *const p and const int *const p?

Save to ▾
Show answer
const int *p is a pointer to a constant int: you cannot change the value through p, but p can point elsewhere. int *const p is a constant pointer: p always points to the same address, but the value can change. const int *const p fixes both. Read declarations from right to left to understand them. const pointers to data are common in function parameters.
17

What does the static keyword do in different contexts?

Save to ▾
Show answer
Inside a function, a static local variable keeps its value between calls and is initialised only once. At file level, a static global variable or function has internal linkage, so it is visible only in that source file, which helps hide implementation details. Static variables are stored in the data or BSS segment, not the stack, and default to zero.
18

What is a double pointer and when do you need it?

Save to ▾
Show answer
A double pointer, such as int **pp, stores the address of a pointer. It is needed when a function must change the caller's pointer itself, for example inserting at the head of a linked list or allocating memory inside a function and returning it through a parameter. It is also used for dynamic 2D arrays and arrays of strings, like char **argv.
19

Tell me about a time you debugged a hard crash in C code.

Save to ▾
Show answer
Situation: our data logger crashed randomly after hours of running. Task: find the cause before a client demo. Action: I rebuilt with AddressSanitizer, ran a long stress test and found a buffer overflow in a string copy that corrupted a nearby pointer. I replaced it with a bounded snprintf and added a length check. Result: the logger ran for a week without a crash and we added sanitizer builds to CI.
20

Compare BFS and DFS.

Save to ▾
Show answer
BFS explores level by level using a queue and finds the shortest path in unweighted graphs. DFS goes deep along one path using recursion or a stack, and suits cycle detection, topological sort, connected components and backtracking. Both run in O(V + E). BFS may use more memory on wide graphs, while recursive DFS can overflow the call stack on very deep graphs.
21

Implement union-find with path compression and union by rank.

Save to ▾
Show answer
Two small functions cover most uses. int parent[MAXN], rnk[MAXN]; void makeSet(int n) { for (int i = 0; i < n; i++) { parent[i] = i; rnk[i] = 0; } } int find(int x) { if (parent[x] != x) parent[x] = find(parent[x]); return parent[x]; } int unite(int a, int b) { a = find(a); b = find(b); if (a == b) return 0; if (rnk[a] < rnk[b]) { int t = a; a = b; b = t; } parent[b] = a; if (rnk[a] == rnk[b]) rnk[a]++; return 1; }
22

What are null, dangling, wild and void pointers?

Save to ▾
Show answer
A null pointer holds NULL and points to nothing; dereferencing it crashes. A dangling pointer points to memory that has been freed or a local that went out of scope. A wild pointer is uninitialised and holds a random address. A void pointer is a generic pointer that can hold any object address but must be cast before dereferencing, as malloc returns void *.
23

What are bit fields in C?

Save to ▾
Show answer
Bit fields let struct members use a specified number of bits, such as unsigned int ready : 1; unsigned int mode : 3;, which saves memory for flags. They are common in embedded code and protocol headers. However, bit ordering, padding and whether plain int bit fields are signed are implementation defined, so for portable hardware register or wire format access, explicit masks and shifts are safer.
24

Write Kadane's algorithm in C.

Save to ▾
Show answer
Track the best sum ending here and the overall best. long maxSubarray(const int *a, int n) { long cur = a[0], best = a[0]; for (int i = 1; i < n; i++) { cur = (cur + a[i] > a[i]) ? cur + a[i] : a[i]; if (cur > best) best = cur; } return best; } Input {-2, 1, -3, 4, -1, 2, 1, -5, 4} returns 6 for subarray 4, -1, 2, 1.
25

Compare quicksort, merge sort and heap sort.

Save to ▾
Show answer
Quicksort is O(n log n) on average and very fast in practice with in-place partitioning, but O(n squared) in the worst case with poor pivots and not stable. Merge sort is always O(n log n) and stable but needs O(n) extra memory. Heap sort is O(n log n) worst case and in place but not stable and slower due to poor cache use. C's qsort is usually a tuned hybrid.
26

Which gcc flags would you use to build and debug a C program safely?

Save to ▾
Show answer
A good development build is: gcc -std=c17 -Wall -Wextra -Wpedantic -g -O1 \ -fsanitize=address,undefined \ -o app main.c utils.c -Wall and -Wextra turn on useful warnings, -g adds debug symbols for gdb, and sanitizers catch memory errors and undefined behaviour at runtime. For release, drop sanitizers and use -O2.
27

Write a C program that counts lines, words and characters in a file.

Save to ▾
Show answer
Read character by character with fgetc. FILE *fp = fopen(path, "r"); if (!fp) { perror("fopen"); return 1; } long lines = 0, words = 0, chars = 0; int c, inWord = 0; while ((c = fgetc(fp)) != EOF) { chars++; if (c == '\n') lines++; if (isspace(c)) inWord = 0; else if (!inWord) { inWord = 1; words++; } } fclose(fp); printf("%ld %ld %ld\n", lines, words, chars); c is int so EOF can be distinguished from valid bytes.
28

Implement quicksort in C using Lomuto partition.

Save to ▾
Show answer
Partition around the last element, then sort both sides. void swap(int *x, int *y) { int t = *x; *x = *y; *y = t; } int partition(int *a, int lo, int hi) { int pivot = a[hi], i = lo; for (int j = lo; j < hi; j++) if (a[j] < pivot) swap(&a[i++], &a[j]); swap(&a[i], &a[hi]); return i; } void quickSort(int *a, int lo, int hi) { if (lo < hi) { int p = partition(a, lo, hi); quickSort(a, lo, p - 1); quickSort(a, p + 1, hi); } }
29

Implement your own version of memcpy.

Save to ▾
Show answer
Copy byte by byte through unsigned char pointers. void *my_memcpy(void *dest, const void *src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; while (n--) { *d++ = *s++; } return dest; } memcpy must not be used for overlapping regions; memmove handles overlap by copying backwards when needed. Real libraries copy whole words for speed.
30

You need to update one record in the middle of a large binary file without rewriting it all. How?

Save to ▾
Show answer
Use fixed-size records so each one starts at index times record size. Open the file in r+b mode, fseek to that offset, fwrite the new record and fflush. Read it back to verify if needed. For crash safety, write to a temporary file and rename, or keep a simple journal. Databases like SQLite solve this robustly if requirements grow.
31

What is a monotonic stack?

Save to ▾
Show answer
A monotonic stack keeps elements in increasing or decreasing order by popping elements that break the order before pushing a new one. Each element is pushed and popped at most once, so problems run in O(n). It solves next greater element, daily temperatures, stock span and largest rectangle in a histogram, which would otherwise need nested loops.
32

How do you handle a situation where requirements change late in a project?

Save to ▾
Show answer
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.
33

What is a binary search tree and what are its operation costs?

Save to ▾
Show answer
A binary search tree keeps every node's left subtree smaller and right subtree larger than the node. Search, insert and delete follow one path from the root, so they cost O(h), where h is the height. A balanced tree has h of about log n, but inserting sorted data creates a skewed tree with h equal to n. In-order traversal of a BST gives keys in sorted order.
34

Allocate and free a dynamic 2D array of rows by cols in C.

Save to ▾
Show answer
A single block is cache friendly and easy to free. int (*grid)[cols] = malloc(rows * sizeof *grid); if (!grid) return -1; grid[2][3] = 5; free(grid); // array of row pointers alternative int **m = malloc(rows * sizeof *m); for (int i = 0; i < rows; i++) m[i] = calloc(cols, sizeof **m); for (int i = 0; i < rows; i++) free(m[i]); free(m); The first form uses a variable length array type.
35

Tell me about a time you chose the right data structure under pressure.

Save to ▾
Show answer
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.
36

What is a memory leak and how do you detect it?

Save to ▾
Show answer
A memory leak happens when dynamically allocated memory is never freed and the last pointer to it is lost, so the program keeps growing in memory use. Long running services and embedded systems eventually fail. Detect leaks with Valgrind memcheck, AddressSanitizer with LeakSanitizer or allocation tracking wrappers. Prevent them with clear ownership rules and a single cleanup path per function.

Companies with offices in Mumbai (3)

Frequently asked questions

Which companies hire C Programming with DSA professionals in Mumbai?

Companies with large offices in Mumbai include TCS, Capgemini, Siemens. Use their company pages below to practise employer-specific sets.

Are C Programming with DSA interviews in Mumbai different from other cities?

The questions depend more on the company than the city. Mumbai's mix of employers decides the style: Data and QA interviews often include domain questions on payments, risk, trading or customer analytics

How do I find C Programming with DSA jobs in Mumbai?

Shortlist companies with Mumbai offices, keep your CV focused on C Programming with DSA projects, apply on company career pages and job portals with the Mumbai filter, and practise the questions on this page before each interview.