Code Debugging
Each question includes a description, a buggy code snippet, and four options (A–D). Choose the best fix.
Question 1 — Linked List (Insert at Beginning)
Description: The following code snippet inserts a node at the beginning of a linked list. It has
logical/syntactical errors. Identify and fix.
void begin_insert(int element) {
struct node *ptr = (struct node*) malloc(sizeof(struct node *));
if (ptr == NULL) {
printf("EXIT\n");
} else {
ptr->data = element;
ptr->node = head;
head = ptr;
printf("Node inserted\n");
}
}
Options:
A. ptr->next = head;
B. struct node *ptr = malloc(sizeof(struct node));
C. Both A and B
D. The code has no error
Question 2 — Arrays (Out-of-Bounds)
Description: The code prints elements of an array. There is an error in the loop bounds.
void print_array(int arr[], int n) {
for (int i = 0; i <= n; i++) {
printf("%d ", arr[i]);
}
}
Options:
A. Loop should be i < n
B. Loop should start from i = 1
C. Use i < n-1 instead
D. No error
Question 3 — Strings (Concatenation Bug)
Description: The code appends one string to another but misses a crucial step.
void concat(char *a, char *b) {
int i = 0, j = 0;
while (a[i] != '\0') i++;
while (b[j] != '\0') {
a[i++] = b[j++];
}
// Missing step?
}
Options:
A. Add a[i] = '\0'; at the end
B. Initialize i = j = 0 again
C. Replace loop with strcat(a, b);
D. No error
Question 4 — Recursion (Factorial Base Case)
Description: The code calculates factorial but has an issue with the base case.
long long fact(int n) {
if (n == 1) return 1;
return n * fact(n-1);
}
Options:
A. Add base case if (n <= 1) return 1;
B. Change to if (n == 0)
C. Return 0 when n == 0
D. No error
Question 5 — Dynamic Memory (Wrong sizeof)
Description: The function allocates an integer array but uses the wrong sizeof.
int *create_array(int n) {
int *p = malloc(sizeof(p) * n);
for (int i = 0; i < n; i++) p[i] = i;
return p;
}
Options:
A. Use malloc(n * sizeof(int))
B. Use malloc(sizeof *p * n)
C. Both A and B are correct
D. No error
Question 6 — File I/O (EOF Check Bug)
Description: The function reads lines from a file until EOF, but the loop condition is wrong.
void read_file(FILE *fp) {
char buf[100];
while (!feof(fp)) {
fgets(buf, sizeof(buf), fp);
printf("%s", buf);
}
}
Options:
A. Replace loop with while (fgets(buf, sizeof(buf), fp))
B. Add rewind(fp); before loop
C. Replace fgets with scanf("%s", buf)
D. No error
Question 7 — Linked List (Delete Key Bug)
Description: The code deletes a node with a given key, but pointer updates are incorrect.
void delete_key(int key) {
struct node *cur = head, *prev = NULL;
while (cur && cur->data != key) {
prev = cur;
cur = cur->next;
}
if (!cur) return;
if (prev == NULL) head->next = cur->next;
else prev = cur->next;
free(cur);
}
Options:
A. Replace with head = cur->next; and prev->next = cur->next;
B. Replace only head line
C. Replace only prev line
D. No error
Question 8 — Binary Search (Off-by-One)
Description: The binary search implementation may go into an infinite loop.
int binary_search(int arr[], int n, int x) {
int l = 0, r = n-1;
while (l <= r) {
int m = (l + r) / 2;
if (arr[m] == x) return m;
else if (arr[m] < x) l = m;
else r = m - 1;
}
return -1;
}
Options:
A. Use l = m + 1; instead of l = m;
B. Use r = m; instead of m - 1
C. Both A and B
D. No error
Question 9 — Queue (Circular Update Bug)
Description: Circular queue implementation has a bug in updating rear.
#define SIZE 4
int queue[SIZE], front = 0, rear = 0, count = 0;
void enqueue(int x) {
if (count == SIZE) return;
queue[rear++] = x;
if (rear == SIZE) rear = SIZE; // bug
count++;
}
Options:
A. Replace with rear = (rear + 1) % SIZE;
B. Replace with rear = SIZE - 1;
C. Increment front instead of rear
D. No error
Question 10 — Sorting (Swap Bug in Selection Sort)
Description: The code attempts swapping but does not perform correctly.
void selection_sort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
int min = i;
for (int j = i+1; j < n; j++)
if (arr[j] < arr[min]) min = j;
int *t = &arr[min];
*t = arr[i];
arr[i] = *t;
}
}
Options:
A. Use int t = arr[min]; arr[min] = arr[i]; arr[i] = t;
B. Swap with pointers directly
C. Use memcpy for swap
D. No error
Question 11 — Pointers (Dangling Pointer)
Description: The function returns a pointer to a local array which becomes invalid after return.
int* first_three(void) {
int a[3] = {1,2,3};
return a; // returns address of local
}
Options:
A. Make a static array: static int a[3];
B. Allocate with malloc and return it (caller frees)
C. Both A and B are valid fixes (trade-offs)
D. Cast to (void*) before return
Question 12 — Iteration Mutation (Skipping Elements)
Description: Removing even elements while iterating causes skipping due to index movement.
void remove_evens(int *a, int *n) {
for (int i=0; i<*n; ++i) {
if (a[i] % 2 == 0) {
for (int j=i; j<*n-1; ++j) a[j]=a[j+1];
(*n)--;
}
}
}
Options:
A. Decrement i after removal: i--;
B. Iterate from the end to the start
C. Both A and B approaches are valid
D. No change needed
Question 13 — String Length (Unterminated Input)
Description: Reading into a buffer may miss terminator; length function assumes terminator exists.
size_t mylen(const char *s){
size_t n=0;
while (*s++) n++;
return n;
}
void read_line(FILE *fp){
char buf[8];
fread(buf, 1, sizeof buf, fp);
printf("%zu\n", mylen(buf)); // may scan past end
}
Options:
A. Ensure NUL termination: buf[bytes_read] = '\0';
B. Use fgets which NUL-terminates on success
C. Both A and B are valid fixes
D. Use strlen directly
Question 14 — Double Free / Size Bug
Description: Duplicating a string allocates insufficient size and frees twice.
char *dup_line(const char *s){
char *p = malloc(strlen(s)); // size bug
strcpy(p, s);
return p;
}
void f(void){
char *x = dup_line("hi");
free(x);
free(x); // double free
}
Options:
A. Allocate strlen(s)+1 and remove second free
B. Use calloc instead of malloc
C. Call realloc before second free
D. Set x = NULL before first free
Question 15 — File I/O (Binary vs Text)
Description: Reading a struct with text-mode fopen may corrupt on Windows due to text translation.
typedef struct { int id; double gpa; } rec;
rec r;
FILE *fp = fopen("data.txt", "r");
fread(&r, sizeof r, 1, fp);
Options:
A. Use binary mode: fopen("data.bin", "rb")/"wb"
B. Replace fread with fscanf
C. Increase sizeof
D. Use fflush before fread
Question 16 — Recursion (Unbounded Depth)
Description: Printing a linked list recursively without base guard on very long list may overflow the stack.
void print_rec(struct node *p){
printf("%d ", p->data);
print_rec(p->next);
}
Options:
A. Add base case: if (!p) return; at top
B. Convert to iterative loop
C. Both A and B are sensible fixes
D. Tail-call will always optimize away
Question 17 — Pointer Arithmetic (Wrong Step)
Description: Advancing by bytes instead of ints when summing an array.
int sumN(int *a, int n){
int s=0; char *p=(char*)a;
for (int i=0;i<n;i++){
s += *(int*)(p+i); // wrong step
}
return s;
}
Options:
A. Use s += a[i];
B. Use p += sizeof(int) each iteration before dereference
C. Both A and B fix the stepping issue
D. Cast to long long
Question 18 — Binary Search Tree (Insert Wiring)
Description: BST insert loses subtree when linking the new node.
struct node* insert(struct node* root, int x){
if (!root){
struct node* t = malloc(sizeof *t);
t->data=x; t->left=t->right=NULL;
return t;
}
if (x < root->data) root->left = insert(root->left, x);
else if (x > root->data) root->right = insert(root->right, x);
else { /* duplicate */ }
return root;
}
Options:
A. Code is correct; no wiring bug
B. Must free duplicate; otherwise leak
C. Ensure new node's children are NULL
D. Convert to iterative
Question 19 — Concurrency (Mutex Order Deadlock)
Description: Two account transfers lock in different orders causing deadlock.
void transfer(acc *a, acc *b, int amt){
pthread_mutex_lock(&a->m);
pthread_mutex_lock(&b->m);
if (a->bal >= amt){ a->bal -= amt; b->bal += amt; }
pthread_mutex_unlock(&b->m);
pthread_mutex_unlock(&a->m);
}
Options:
A. Lock in a global order (e.g., by address/id)
B. Use trylock only
C. Remove second lock
D. Swap unlock order
Question 20 — Memory Leak (Missing Free on Error Path)
Description: Function builds a buffer, but on early return after fopen failure, allocated memory leaks.
char* read_file_to_buf(const char *path){
char *buf = malloc(4096);
FILE *fp = fopen(path, "r");
if (!fp) return NULL; // leak buf
size_t n = fread(buf,1,4096,fp);
fclose(fp);
buf[n] = '\0';
return buf;
}
Options:
A. Free buf before returning NULL when fopen fails
B. Use goto cleanup pattern with a single exit
C. Both A and B prevent the leak
D. No change needed
Java Debugging MCQs
Each question includes a description, a buggy code snippet, and four options (A–D). Choose the best fix.
Question 1 — NullPointerException (Safe String Comparison)
Description: The code intends to compare a possibly null string with a constant, but it throws a
NullPointerException.
String str = null;
if (str.equals("Cognizant")) {
System.out.println("Match found!");
}
Options:
A. Use: if ("Cognizant".equals(str))
B. Initialize str = "" before comparison
C. Use Objects.equals(str, "Cognizant")
D. All of the above
Question 2 — ArrayIndexOutOfBoundsException (Loop Bound)
Description: The loop prints all elements but throws at the last iteration due to an off-by-one error.
int[] arr = {1,2,3};
for (int i = 0; i <= arr.length; i++) {
System.out.println(arr[i]);
}
Options:
A. Use i < arr.length
B. Start from i = 1
C. Use enhanced for: for (int x : arr)
D. No change needed
Question 3 — Constructor Not Called (Method Named as Constructor)
Description: The Student 'constructor' is declared with a return type, so it's a regular method and never
called on new Student().
class Student {
void Student() {
System.out.println("Student Created");
}
}
public class Test {
public static void main(String[] args) {
Student s = new Student();
}
}
Options:
A. Remove 'void' so it becomes a real constructor
B. Call s.Student() after creating the object
C. Make Student() static
D. No error
Question 4 — equals/hashCode Contract (HashMap Key Lookup Fails)
Description: A custom key class overrides equals but not hashCode, causing HashMap lookups to fail.
class User {
String name;
User(String n){ this.name = n; }
public boolean equals(Object o){ return
((User)o).name.equals(name); }
// missing hashCode
}
var map = new java.util.HashMap<User,Integer>();
map.put(new User("Ana"), 1);
System.out.println(map.get(new User("Ana"))); // prints null
Options:
A. Implement hashCode consistent with equals
B. Make name final only
C. Use IdentityHashMap instead
D. No change; this is expected
Question 5 — StringBuilder Misuse (Inefficient Concatenation in Loop)
Description: String concatenation inside a loop creates many temporary objects and is slow.
String s = "";
for (int i=0;i<10000;i++) {
s = s + i; // inefficient
}
System.out.println(s.length());
Options:
A. Use StringBuilder and append inside the loop
B. Pre-size the String
C. Use StringBuffer
D. All of the above (A or C are acceptable)
Question 6 — Iterator Removal (ConcurrentModificationException)
Description: Removing from a List while iterating with for-each causes ConcurrentModificationException.
java.util.List<Integer> list = new java.util.ArrayList<>();
list.add(1); list.add(2); list.add(3);
for (Integer x : list) {
if (x % 2 == 0) list.remove(x);
}
Options:
A. Use an Iterator and iterator.remove()
B. Collect to a new list and removeAll
C. Use removeIf(x -> x % 2 == 0)
D. All of the above
Question 7 — Streams & Nulls (NPE in map)
Description: Mapping method reference on a stream with null elements triggers NPE.
java.util.List<String> names = java.util.Arrays.asList("neo", null,
"trinity");
names.stream().map(String::toUpperCase).forEach(System.out::println);
Options:
A. Filter nulls: .filter(Objects::nonNull)
B. Map safely: .map(s -> s==null?"":s.toUpperCase())
C. Replace nulls upstream
D. Any of the above
Question 8 — Stream Laziness (peek Count Misunderstanding)
Description: Expecting peek to run on every item, but short-circuit or filtering changes counts.
java.util.List<String> src = java.util.Arrays.asList("a","bb","ccc");
int[] counter = {0};
long c = src.stream()
.peek(s -> counter[0]++)
.filter(s -> s.length() > 1)
.map(String::toUpperCase)
.count();
System.out.println(counter[0]); // expected 3?
Options:
A. Move peek AFTER filter to count processed elements
B. Avoid external mutation; use summary statistics
C. Use forEach instead of peek
D. Any of the above depending on intent
Question 9 — BigDecimal Equality (compareTo vs equals)
Description: Using equals on BigDecimal with different scales returns false even if numerically equal.
java.math.BigDecimal a = new java.math.BigDecimal("1.0");
java.math.BigDecimal b = new java.math.BigDecimal("1.00");
System.out.println(a.equals(b)); // false
Options:
A. Use a.compareTo(b) == 0 for numeric equality
B. Strip trailing zeros before equals
C. Always use equals only
D. Convert to double
Question 10 — Floating-Point Precision
Description: Relying on exact equality with doubles causes unexpected results.
double x = 0.1 + 0.2;
if (x == 0.3) System.out.println("ok");
Options:
A. Use a tolerance: Math.abs(x - 0.3) < 1e-9
B. Use BigDecimal for exact math
C. Cast to float first
D. A or B
Question 11 — Date/Time API (Time Zone Trap)
Description: Converting a LocalDateTime to Instant without a zone causes incorrect instant assumptions.
java.time.LocalDateTime ldt = java.time.LocalDateTime.now();
java.time.Instant ins = ldt.toInstant(java.time.ZoneOffset.UTC); //
misuse?
Options:
A. Use ldt.atZone(ZoneId.systemDefault()).toInstant()
B. Always use ZonedDateTime when converting to Instant
C. Pass the correct ZoneId when converting
D. Any of the above depending on requirement
Question 12 — try-with-resources (Resource Leak)
Description: FileInputStream is not closed if an exception occurs before manual close.
java.io.FileInputStream fis = new java.io.FileInputStream("in.txt");
byte[] buf = fis.readAllBytes();
fis.close(); // might be skipped on exception
Options:
A. Use try-with-resources to auto-close
B. Close in finally block
C. Wrap in BufferedInputStream
D. Both A and B are correct
Question 13 — Deadlock (Inconsistent Lock Order)
Description: Two threads lock resources in opposite order creating deadlock.
synchronized (a) {
synchronized (b) { /* work */ }
}
synchronized (b) {
synchronized (a) { /* work */ }
}
Options:
A. Enforce a global lock order (e.g., by System.identityHashCode)
B. Use tryLock with timeout
C. Use a single lock covering both
D. Any of the above
Question 14 — Visibility (Missing volatile / synchronization)
Description: A flag updated by one thread may not be visible to another without proper memory
semantics.
class Runner implements Runnable {
boolean running = true;
public void run() {
while (running) { /* do work */ }
}
}
Runner r = new Runner();
new Thread(r).start();
// later
r.running = false;
Options:
A. Mark running as volatile
B. Use synchronized accessors
C. Use AtomicBoolean
D. Any of the above
Question 15 — Atomicity (Increment Lost Updates)
Description: Multiple threads increment an int counter without synchronization causing lost updates.
class Cnt { int c = 0; }
Cnt c = new Cnt();
java.util.stream.IntStream.range(0,1000).parallel().forEach(i ->
c.c++);
System.out.println(c.c); // < 1000
Options:
A. Use AtomicInteger.incrementAndGet()
B. Use synchronized block around increment
C. Use LongAdder for high contention
D. Any of the above
Question 16 — CompletableFuture (Blocking join in ForkJoin worker)
Description: Calling join inside a common pool task can cause thread starvation.
java.util.concurrent.CompletableFuture<Integer> f =
java.util.concurrent.CompletableFuture.supplyAsync(() -> 42)
.thenApply(x -> {
return
java.util.concurrent.CompletableFuture.supplyAsync(() -> x+1).join();
});
Options:
A. Chain with thenCompose instead of creating & joining inside thenApply
B. Use a dedicated Executor
C. Both A and B
D. No change needed
Question 17 — ExecutorService Leak (Never Shutting Down)
Description: Pool keeps JVM alive because it’s never shut down.
java.util.concurrent.ExecutorService ex =
java.util.concurrent.Executors.newFixedThreadPool(4);
for (int i = 0; i < 100; i++) {
ex.submit(() -> doWork());
}
// program never exits
Options:
A. Call ex.shutdown() and ex.awaitTermination(...)
B. Use try-with-resources with ExecutorService
C. Handle exceptions in doWork
D. A and C
Question 18 — Binary Search (Infinite Loop)
Description: Midpoint update leads to infinite loop for some cases.
int binarySearch(int[] a, int x) {
int l = 0, r = a.length - 1;
while (l <= r) {
int m = (l + r) / 2;
if (a[m] == x) return m;
if (a[m] < x) l = m; // off-by-one
else r = m - 1;
}
return -1;
}
Options:
A. Use l = m + 1 when a[m] < x
B. Use int m = l + (r - l) / 2 to avoid overflow
C. Both A and B
D. No change needed
Question 19 — switch Fallthrough (Missing break)
Description: Missing break causes fallthrough and unexpected output.
int day = 2;
switch (day) {
case 1: System.out.println("Mon");
case 2: System.out.println("Tue");
case 3: System.out.println("Wed");
}
Options:
A. Add break after each case
B. Use return statements instead
C. Use switch expression (Java 14+) with arrows
D. Any of the above
Question 20 — Optional Misuse (get on Empty)
Description: Calling get() on an empty Optional throws NoSuchElementException.
java.util.Optional<String> o = java.util.Optional.empty();
System.out.println(o.get()); // boom
Options:
A. Use orElse / orElseGet
B. Use ifPresent / ifPresentOrElse
C. Use orElseThrow with custom exception
D. Any of the above