$ Coding & DSA β€” Interview Prep
// Consolidated from "Coding" sheet β€” questions actually asked in interviews (Priority Count populated)
🎯 Target: TCS β€” Java / Spring Boot Developer πŸ“… Interview: 20 Aug 2026 πŸ“Š Experience band: 3–8 YoE β˜• Code language: Java πŸ“Œ 32 questions curated
How this document was built: Every row in the Coding sheet of All_Study_and_Interview_Questions_Answers_List_0-10YoE.xlsx was reviewed. Only rows where Priority Count was not blank are included below β€” meaning each one has actually been asked in a real interview at some point. Where the sheet's answer was missing, incomplete, or inefficient, a complete, interview-ready Java solution has been written from scratch (approach, working code, and time/space complexity). Rows sourced via LinkedIn (linkedin-1, linkedin-2, …) are flagged with the πŸ”— badge below. This is meant to be a single, self-sufficient revision document β€” no need to go back to the spreadsheet.
Legend βœ… Asked confirmed asked in a real interview (Priority Count set) πŸ”— LinkedIn sourced from a LinkedIn interview-experience post Pattern the underlying DSA pattern to recognize Level difficulty for a 3–8 YoE bar
Table of Contents β€” 32 Questions across 5 Categories
β˜•

1. Core Java Basics & Strings β€” 7 questions

Q1 Swap two variables without using a third variable
βœ… Asked πŸ”— LinkedIn-1 Level: Easy
Topic: Core Java Basics Β· Pattern: Arithmetic / Bitwise trick
Problem
Given two variables a and b, swap their values without introducing a third (temp) variable.
Approach
  • Two classic no-temp tricks: arithmetic (add/subtract) and bitwise (XOR).
  • Arithmetic trick works for numeric types but can silently overflow if a + b exceeds the type's range.
  • XOR trick avoids overflow entirely and is the safer answer to lead with in an interview β€” but only works for integer types, not floating point.
  • In production code, just use a temp variable (or Collections.swap / tuple destructuring) β€” this trick is purely an interview exercise, and it's worth saying so.
Code β€” as answered
// Using arithmetic:
a = a + b;
b = a - b;
a = a - b;

// Or using XOR:
a = a ^ b;
b = a ^ b;
a = a ^ b;

// XOR is safer for integers since it avoids potential overflow with large sums.
Time: O(1) Space: O(1)
Follow-up to expect: "Why not just use a temp variable?" β€” good answer: readability > cleverness in real code; this is testing bitwise/arithmetic reasoning, not advocating a coding style.
Q2 Palindrome check
βœ… Asked Level: Easy
Topic: Java Β· Pattern: Two Pointer
Problem
A string or number that reads the same forward and backward is a palindrome. Example: madam β†’ palindrome, 121 β†’ palindrome.
Approach
  • Reverse the string and compare it with the original β€” if they match, it's a palindrome.
  • Works the same way for numeric palindromes like 121 by comparing against the string form.
Code β€” as answered
String str = "madam";

String rev = new StringBuilder(str).reverse().toString();

boolean res = str.equals(rev);
Time: O(n) Space: O(n)
Optional follow-up: if asked for an O(1)-extra-space version, use a two-pointer scan from both ends instead of building a reversed copy β€” left++/right-- comparing charAt(left) == charAt(right) until they meet.
Q3 Count the frequency of each character in a string
βœ… Asked Level: Easy
Topic: Java Β· Pattern: HashMap frequency counting
Problem
Given "apple", produce the frequency of each character: a=1, p=2, l=1, e=1.
Approach
  • For each character, count how many times it occurs across the string and store it in a Map<Character, Integer>.
Code β€” as answered
String str = "apple"; // a-1, p-2, l-1, e-1

Map<Character, Integer> freqMap = new HashMap<>();

for (char c : str.toCharArray()) {
    int count = 0;

    for (int i = 0; i < str.length(); i++) {
        if (c == str.charAt(i)) {
            count++;
        }
    }

    freqMap.put(c, count);
}

System.out.println(freqMap);
Time: O(nΒ²) β€” inner loop rescans the string for every character Space: O(k) β€” k = distinct characters
Optional follow-up: if asked to optimize, do it in a single O(n) pass instead β€” freqMap.merge(c, 1, Integer::sum) inside one loop, no inner scan needed.
Q4 Longest substring without repeating characters
βœ… Asked Pattern: Sliding Window Level: Medium
Topic: Java Β· No answer was recorded in the sheet β€” full solution below
Problem
Find the length of the longest substring without repeating characters, e.g. for "aabcabc".
Approach β€” Sliding Window + HashMap
  • Maintain a window [start, i] that never contains a duplicate character.
  • Use a HashMap<Character, Integer> mapping each character to the last index it was seen at.
  • For each character at index i: if it was seen before and that occurrence is inside the current window (lastSeen >= start), move start to lastSeen + 1 β€” this shrinks the window just enough to drop the duplicate.
  • Update the map and track maxLen = max(maxLen, i - start + 1) at every step.
  • Brute force would check every substring β€” O(nΒ³) or O(nΒ²) β€” sliding window does it in a single O(n) pass.
Code
public int lengthOfLongestSubstring(String s) {
    Map<Character, Integer> lastSeen = new HashMap<>();
    int start = 0, maxLen = 0;

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (lastSeen.containsKey(c) && lastSeen.get(c) >= start) {
            start = lastSeen.get(c) + 1;      // shrink window past the duplicate
        }
        lastSeen.put(c, i);
        maxLen = Math.max(maxLen, i - start + 1);
    }
    return maxLen;
}
Trace: "aabcabc"
i=0 'a' β†’ window "a" (len 1) i=1 'a' repeats inside window β†’ start=1 β†’ window "a" (len 1) i=2 'b' β†’ window "ab" (len 2) i=3 'c' β†’ window "abc" (len 3) i=4 'a' repeats (last seen 1, inside window) β†’ start=2 β†’ window "bca" (len 3) i=5 'b' repeats (last seen 2, inside window) β†’ start=3 β†’ window "cab" (len 3) i=6 'c' repeats (last seen 3, inside window) β†’ start=4 β†’ window "abc" (len 3) Answer: 3
Time: O(n) Space: O(min(n, charset size))
Q5 Longest Common Prefix
βœ… Asked Level: Easy
Topic: Java Β· Pattern: Vertical scanning
Problem
Test case 1: {"flower","flow","flight"} β†’ output "fl" Test case 2: {"Payroll","Paypal","Play"} β†’ output "P"
Approach β€” Vertical scanning
  • Take the first word as a reference. Walk its characters index by index (i = 0, 1, 2, ...).
  • At each index, compare that character against the same index in every other word.
  • The moment a word is too short for that index, or has a different character there, stop and return what's been built so far.
  • Alternative (horizontal scanning): repeatedly shrink a running prefix using String.startsWith() against each word in turn β€” same complexity, sometimes more readable.
Code β€” Vertical scanning
public String getPrefix(String[] words) {

    String first = words[0];
    String result = "";

    for (int i = 0; i < first.length(); i++) {

        char ch = first.charAt(i);

        for (int j = 1; j < words.length; j++) {

            if (i >= words[j].length() || words[j].charAt(i) != ch) {
                return result;
            }
        }

        result += ch;
    }

    return result;
}
Time: O(S) β€” S = sum of all characters in all words (worst case) Space: O(1) extra (excluding output)
Q6 Chocolate Distribution Problem
βœ… Asked Pattern: Factor pairs / Math Level: Medium
Topic: Java Β· No answer was recorded in the sheet β€” full solution below
Problem
Given N chocolates, decide whether they can be fairly distributed among some number of children such that: β€” you choose the number of children, β€” each child gets at least 2 chocolates, β€” no single child gets all the chocolates, β€” all chocolates are split equally with no remainder. Example 1: N=10 β†’ "Yes" (5 children Γ— 2 chocolates each). Example 2: N=2 β†’ "No" (can't have β‰₯2 children each getting β‰₯2 chocolates from only 2).
Approach
  • Reframe the problem mathematically: we need to split N into children Γ— chocolatesPerChild = N where both children β‰₯ 2 and chocolatesPerChild β‰₯ 2.
  • children β‰₯ 2 automatically satisfies "no single child gets all the chocolates".
  • So the real question becomes: does N have a factor pair (d, N/d) where both factors are β‰₯ 2? This is true for any composite number β‰₯ 4, and false for 0, 1, and every prime number.
  • Only need to check divisors up to √N β€” if d divides N and N/d β‰₯ 2, we have a valid split.
Code
public String canDistributeFairly(int n) {
    if (n < 4) return "No";   // smallest possible valid split is 2 children x 2 chocolates = 4

    for (int children = 2; children * children <= n; children++) {
        if (n % children == 0) {
            int perChild = n / children;
            if (perChild >= 2) {
                return "Yes";
            }
        }
    }
    return "No";
}

// canDistributeFairly(10) -> "Yes"  (5 children x 2 each, or 2 children x 5 each)
// canDistributeFairly(2)  -> "No"
// canDistributeFairly(7)  -> "No"   (7 is prime)
// canDistributeFairly(4)  -> "Yes"  (2 children x 2 each)
Time: O(√N) Space: O(1)
Note: this reduces to "is N composite (and β‰₯ 4)?" β€” the same primality-check skill from Q10 applies here.
Q7 Maximum subarray β€” sum & length variants
βœ… Asked Pattern: Kadane's / Sliding Window Level: Medium
Topic: Java Β· Sheet's phrasing: "return max Sublength of array" is ambiguous, and the recorded answer was a placeholder β€” shown as-is below, followed by the two likely-intended classics.
Code β€” as answered (placeholder, not a real solution)
int[] arr = {1, 2, 3, 4, 5};

int maxSubLength = arr.length;

System.out.println(maxSubLength);
Why this isn't enough: this just prints the array's own length β€” it doesn't solve any actual subarray problem. Clarify the real question with the interviewer first; the two most likely intents are below.
Variant A β€” Maximum Subarray Sum (Kadane's Algorithm)
The single most commonly asked "subarray" question at this level: given an integer array, find the contiguous subarray with the largest sum.
  • Track currentSum ending at the current index and the overall maxSum seen so far.
  • At each element, decide: extend the previous subarray, or start fresh from the current element β€” whichever gives a larger sum (currentSum = max(num, currentSum + num)).
public int maxSubArraySum(int[] arr) {
    int currentSum = arr[0];
    int maxSum = arr[0];

    for (int i = 1; i < arr.length; i++) {
        currentSum = Math.max(arr[i], currentSum + arr[i]);
        maxSum = Math.max(maxSum, currentSum);
    }
    return maxSum;
}
// {-2,1,-3,4,-1,2,1,-5,4} -> maxSum = 6  (subarray [4,-1,2,1])
Time: O(n) Space: O(1)
Variant B β€” Longest subarray with sum ≀ K (matches "max sub-length" wording)
If the intent was really about length rather than sum β€” e.g. "find the length of the longest subarray whose sum doesn't exceed K" β€” this is a sliding-window problem (works cleanly when all elements are non-negative):
public int longestSubarrayWithSumAtMostK(int[] arr, int k) {
    int start = 0, sum = 0, maxLen = 0;

    for (int end = 0; end < arr.length; end++) {
        sum += arr[end];
        while (sum > k && start <= end) {
            sum -= arr[start];
            start++;
        }
        maxLen = Math.max(maxLen, end - start + 1);
    }
    return maxLen;
}
Time: O(n) Space: O(1)
Interview tip: if the question is read out loud and is ambiguous like this one, always clarify with the interviewer first β€” "are we maximizing sum, or maximizing length under a constraint?" β€” before coding.
↑ back to top
🧩

2. Classic DSA / Algorithms β€” 6 questions

Q8 Two Sum
βœ… Asked πŸ”— LinkedIn-1 Pattern: HashMap Level: Easy
Topic: Algorithms Β· The single most-asked coding question across all levels
Problem
Given an array of integers and a target, return the indices of the two numbers that add up to the target.
Approach
  • Brute force checks every pair β€” O(nΒ²).
  • Optimal: single pass with a HashMap<value, index>. For each number, check if target - number is already in the map β€” if so, we've found the pair; otherwise store the current number and move on.
  • Works in one O(n) pass because we only need to look backward at numbers already seen.
Code
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> seen = new HashMap<>();   // value -> index

    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (seen.containsKey(complement)) {
            return new int[]{seen.get(complement), i};
        }
        seen.put(nums[i], i);
    }
    throw new IllegalArgumentException("No two sum solution");
}
// nums = [2,7,11,15], target = 9 -> [0,1]  (2+7=9)
Time: O(n) Space: O(n)
Q9 Valid Parentheses
βœ… Asked Pattern: Stack Level: Easy
Topic: Algorithms Β· No answer was recorded in the sheet β€” full solution below
Problem
Given a string containing just ( ) [ ] { }, determine if the brackets are validly matched and nested, e.g. "{[()]}" is valid, "([)]" is not.
Approach β€” Stack
  • Push opening brackets onto a stack as they're encountered.
  • On a closing bracket, pop the stack and check that it matches the expected opening bracket. If the stack is empty or it doesn't match β€” invalid.
  • At the end, the string is valid only if the stack is empty (every opener was closed).
Code
public boolean isValid(String s) {
    Deque<Character> stack = new ArrayDeque<>();
    Map<Character, Character> pairs = Map.of(')', '(', ']', '[', '}', '{');

    for (char c : s.toCharArray()) {
        if (c == '(' || c == '[' || c == '{') {
            stack.push(c);
        } else {
            if (stack.isEmpty() || stack.pop() != pairs.get(c)) {
                return false;
            }
        }
    }
    return stack.isEmpty();
}
// "{[()]}"  -> true
// "([)]"    -> false
// "(("      -> false
Time: O(n) Space: O(n)
Q10 Find prime number(s)
βœ… Asked Level: Easy
Topic: Algorithms Β· Prime-check logic / first prime number
Problem
Determine if a number is prime, and/or find the first prime number satisfying some condition.
Approach
  • A number is prime if it's greater than 1 and has no divisors other than 1 and itself.
  • Only need to check divisibility up to √n β€” any factor larger than the square root would pair with a smaller factor already checked.
  • Skip even numbers after checking 2, to roughly halve the work.
Code
public boolean isPrime(int n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;

    for (int i = 5; (long) i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) {
            return false;
        }
    }
    return true;
}

public int firstPrimeAfter(int n) {
    int candidate = n + 1;
    while (!isPrime(candidate)) {
        candidate++;
    }
    return candidate;
}
Time: O(√n) per check Space: O(1)
Q11 Fibonacci series β€” with test cases
βœ… Asked Level: Easy
Topic: Algorithms Β· Includes JUnit test cases (explicitly requested in the sheet)
Problem
Generate the Fibonacci series and write test cases for it.
Approach
  • Naive recursion recomputes the same sub-values repeatedly β€” exponential O(2ⁿ) time.
  • Iterative approach (two running variables a, b, each step next = a + b) avoids that entirely β€” O(n) time, O(1) space.
  • Test cases should cover the base cases (n=0, n=1) plus a general case verifying the first several terms.
Code β€” Iterative
public int fibonacci(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;

    int a = 0, b = 1;
    for (int i = 2; i <= n; i++) {
        int next = a + b;
        a = b;
        b = next;
    }
    return b;
}
JUnit test cases
@Test
void fibonacci_baseCase_zero() {
    assertEquals(0, fib.fibonacci(0));
}

@Test
void fibonacci_baseCase_one() {
    assertEquals(1, fib.fibonacci(1));
}

@Test
void fibonacci_generalCase() {
    int[] expected = {0, 1, 1, 2, 3, 5, 8, 13};
    for (int n = 0; n < expected.length; n++) {
        assertEquals(expected[n], fib.fibonacci(n));
    }
}
Time: O(n) Space: O(1)
Q12 Search in a rotated sorted array
βœ… Asked Pattern: Modified Binary Search Level: Medium
Topic: Algorithms Β· Optimize brute force O(n) β†’ O(log n)
Problem
Given a sorted array that has been rotated at some unknown pivot (e.g. [4,5,6,7,0,1,2]), find the index of a target value.
Approach β€” Modified Binary Search
  • At each step, one half of the array (left of mid, or right of mid) is always properly sorted β€” figure out which one.
  • Check if the target falls within that sorted half's value range. If yes, search there; if no, search the other half.
  • Repeat until found or the search space is exhausted β€” still O(log n) because each step halves the range.
Code
public int search(int[] nums, int target) {
    int left = 0, right = nums.length - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) return mid;

        if (nums[left] <= nums[mid]) {              // left half is sorted
            if (nums[left] <= target && target < nums[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        } else {                                      // right half is sorted
            if (nums[mid] < target && target <= nums[right]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
    }
    return -1;
}
// nums = [4,5,6,7,0,1,2], target = 0 -> index 4
Time: O(log n) Space: O(1)
Q13 Longest SLA-compliant time window (out-of-order events)
βœ… Asked Pattern: Sort + Sliding Window Level: Medium–Hard
Topic: Algorithms Β· Real-world / practical scenario question β€” good fit for a backend role
Problem
Given a stream of request latencies (each with a timestamp), find the longest continuous time window where the SLA (latency < X ms) was continuously maintained. Events can arrive out of order.
Approach
  • Because events can arrive out of order, first sort them by timestamp (or insert into a structure that keeps them sorted as they arrive, e.g. a TreeMap<timestamp, latency>).
  • Once sorted, this becomes a straightforward sliding-window scan: track the start timestamp of the current "good" run.
  • While latency stays under the threshold, keep extending the window and update the max window length seen so far (currentTimestamp - windowStart).
  • The moment an SLA violation is hit, the current run ends; the next window starts from the following event's timestamp.
Code
public class LatencyEvent {
    long timestamp;
    long latencyMs;

    public LatencyEvent(long timestamp, long latencyMs) {
        this.timestamp = timestamp;
        this.latencyMs = latencyMs;
    }
}

public long longestSlaWindow(List<LatencyEvent> events, long slaThresholdMs) {
    events.sort(Comparator.comparingLong(e -> e.timestamp));   // handle out-of-order arrival

    long maxWindow = 0;
    long windowStart = -1;
    long lastTimestamp = -1;

    for (LatencyEvent event : events) {
        if (event.latencyMs < slaThresholdMs) {
            if (windowStart == -1) {
                windowStart = event.timestamp;      // start a new compliant window
            }
            maxWindow = Math.max(maxWindow, event.timestamp - windowStart);
            lastTimestamp = event.timestamp;
        } else {
            windowStart = -1;                       // SLA violated -> window resets
        }
    }
    return maxWindow;
}
Time: O(n log n) β€” dominated by the sort Space: O(n) or O(1) if sorted in place
Follow-up to expect: "What if events arrive as a live stream, not a fixed list?" β€” mention using a TreeMap<Long, Long> (timestamp β†’ latency) so insertion keeps things sorted at O(log n) per event, and re-run the same window scan.
↑ back to top
🌊

3. Java 8 Stream API β€” 10 questions

Shared model used across this section
class Employee {
    String name;
    String department;
    String gender;
    double salary;

    // constructor + getters (getName, getDepartment, getGender, getSalary) assumed
}
List<Employee> employees = ...; // source list used by every snippet below
Q14 Employee with the second highest salary
βœ… Asked Level: Easy
Approach
  • Sort descending by salary, skip the first (highest), take the next one.
Code β€” as answered
employees.stream()
.sorted(Comparator.comparing(Employee::getSalary).reversed())
.skip(1)
.findFirst()
Time: O(n log n) Space: O(n)
Q15 Highest paid employee in each department
βœ… Asked πŸ”— LinkedIn-1 Level: Medium
Approach
  • Group by department, then within each group collect the max by salary using a downstream collector (Collectors.maxBy).
Code β€” as answered
Map<String, Optional<Emp>> highestPaidByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
Time: O(n) Space: O(n)
Q16 Find duplicate employee names
βœ… Asked πŸ”— LinkedIn-1 Level: Medium
Approach
  • Group employees by name and count occurrences, then filter groups with count > 1.
Code β€” as answered
Set<String> duplicateNames = employees.stream()
.collect(Collectors.groupingBy(Employee::getName, Collectors.counting()))
.entrySet().stream()
.filter(entry -> entry.getValue() > 1)
.map(e -> e.getKey())
.collect(Collectors.toSet());
Time: O(n) Space: O(n)
Q17 Employees with salary > 20000 and gender = male
βœ… Asked Level: Easy
Approach
  • Chain two filter() calls (readable, and the JIT/stream pipeline short-circuits per element anyway) β€” equivalent to combining both conditions with && in one filter.
Code β€” as answered
List<Emp> salGreaterGenderMale =
elist.stream()
.filter(e -> e.getSal() > 20000.00)
.filter(k -> k.getGender().equalsIgnoreCase("Male"))
.collect(Collectors.toList());
Time: O(n) Space: O(n)
Q18 Group employees by department and sum salary department-wise
βœ… Asked Level: Easy
Code β€” as answered
Map<String, Double> sumOfEmployeeSalByDeptWise =
elist.stream()
.collect(Collectors.groupingBy(Emp::getDeptName, Collectors.summingDouble(Emp::getSal)));
Time: O(n) Space: O(n)
Q19 First non-repeating character in a string, using streams
βœ… Asked πŸ”— LinkedIn-1 Level: Medium
Problem
Example: "swiss" β†’ character counts are s=3, w=1, i=1 β†’ first one with count 1 in original order is 'w'.
Approach
  • Build a frequency map that preserves insertion order (LinkedHashMap), then stream its entries and find the first one with count == 1.
Code β€” as answered
Character ch =
str.chars().mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(c -> c, LinkedHashMap::new, Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(e -> e.getKey())
.findFirst()
.orElse(null);
// -> 'w'
Time: O(n) Space: O(k) β€” k = distinct characters
Q20 Filter names that start with "C" and convert to uppercase
βœ… Asked Level: Easy
Code β€” as answered
List<String> namesUpper =
names.stream()
.filter(a -> a.startsWith("C"))
.map(String::toUpperCase)
.collect(Collectors.toList());
Time: O(n) Space: O(n)
Q21 Remove duplicate elements from a list of integers
βœ… Asked Level: Easy
Example: [1,2,2,3,4] β†’ [1,2,3,4]
Code β€” as answered
List<Integer> uniqueList = list.stream()
                               .distinct()
                               .toList();
Time: O(n) Space: O(n)
Q22 Find the max number in an array using Java 8
βœ… Asked Level: Easy
Example: int[] arr = {1,3,5,6,7}
Code β€” as answered
int max = Arrays.stream(arr).max().getAsInt();
Time: O(n) Space: O(1)
Q23 Count employees in each department (nested object)
βœ… Asked Level: Easy
Variant where department is a nested object: Employee -> {id, name, dept}, Department -> {id, name}
Code β€” as answered
Map<String, Long> result = employees.stream()
    .collect(Collectors.groupingBy(emp -> emp.getDept().getName(),Collectors.counting()));
Time: O(n) Space: O(n)
Note: this is functionally the same pattern as Q18, just reached through a nested field (emp.getDept().getName()) instead of a flat one.
↑ back to top
πŸ—„οΈ

4. SQL Queries β€” 4 questions

Q24 Find duplicate records
βœ… Asked Level: Easy
Approach
  • GROUP BY the column(s) that define a "duplicate", then keep only groups with more than one row via HAVING COUNT(*) > 1.
SELECT name, COUNT(*)
FROM employee
GROUP BY name
HAVING COUNT(*) > 1;
Q25 Employee count by department
βœ… Asked Level: Easy
SELECT dept, COUNT(*) AS emp_count
FROM employee
GROUP BY dept;
Q26 Top 5 highest paid employees
βœ… Asked Level: Easy
SELECT *
FROM employee
ORDER BY salary DESC
LIMIT 5;
Follow-up to expect: "What if there are ties at the 5th position?" β€” use FETCH FIRST 5 ROWS WITH TIES (SQL Server/Oracle) or a window function with DENSE_RANK() to include all tied rows instead of arbitrarily cutting at 5.
Q27 Number of employees in each department (including departments with zero employees)
βœ… Asked Level: Medium
Approach
  • An INNER JOIN would silently drop departments that currently have zero employees.
  • Use a LEFT JOIN from dept to employee so every department is kept, and COUNT(e.id) (not COUNT(*)) correctly counts 0 for departments with no matching rows β€” COUNT(*) would incorrectly count 1 for the NULL row produced by the outer join.
SELECT d.name AS dept_name, COUNT(e.id) AS emp_count
FROM dept d
LEFT JOIN employee e ON e.dept_id = d.id
GROUP BY d.name;
Common mistake: using COUNT(*) instead of COUNT(e.id) here β€” with a LEFT JOIN, a department with no employees still produces one row (all NULLs from the employee side), so COUNT(*) would wrongly report 1 instead of 0.
↑ back to top
πŸ—οΈ

5. Design Patterns, Concurrency & Debugging β€” 5 questions

Q28 Design a thread-safe Singleton
βœ… Asked Γ—2 Level: Medium
Topic: Design Pattern
Approach
  • Double-checked locking: check instance == null before synchronizing (avoids the cost of locking on every call), then check again inside the synchronized block (guards against a race where two threads both passed the first check). The field must be volatile β€” otherwise, due to instruction reordering, another thread could see a non-null but only partially-constructed object.
Code β€” as answered
public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
Follow-up to expect: "Why volatile?" β€” without it, the JIT/CPU can reorder the write to instance so that other threads observe a reference to an object whose constructor hasn't fully run yet. Also be ready to name alternatives if asked: the Bill Pugh static-holder idiom, or an enum-based singleton.
Q29 Implement a simple in-memory cache
βœ… Asked Level: Medium
Topic: Caching Β· "Your application frequently retrieves data from a slow external service β€” improve performance by caching."
Approach
  • Use a ConcurrentHashMap (not a plain HashMap) so the cache is safe under concurrent access from multiple request threads.
  • computeIfAbsent() atomically checks-then-populates on a miss, calling the slow service only when the key isn't already cached.
  • In a real Spring Boot app, this same idea is what @Cacheable does under the hood β€” worth mentioning that Spring's caching abstraction (backed by Caffeine/Redis/etc.) is the production-grade version of this pattern, and this hand-rolled version omits eviction/TTL.
Code β€” as answered
Map<String, String> cache = new ConcurrentHashMap<>();

public String getData(String key) {
    return cache.computeIfAbsent(key, k -> callSlowExternalService(k));
}
Cache hit β€” Time: O(1) Cache miss β€” Time: O(external call)
Follow-up to expect: "How would you add expiry?" β€” mention storing a timestamp alongside the value, or reaching for Caffeine's expireAfterWrite in a real project instead of hand-rolling TTL logic.
Q30 How to correctly override equals() and hashCode()
βœ… Asked Level: Medium
Topic: Core Java Basics
The contract (must know cold)
  • Reflexive: x.equals(x) must be true.
  • Symmetric: x.equals(y) iff y.equals(x).
  • Transitive: if x.equals(y) and y.equals(z), then x.equals(z).
  • Consistent: repeated calls return the same result as long as the object isn't mutated.
  • hashCode consistency: equal objects must produce equal hash codes (the reverse isn't required β€” unequal objects can share a hash code, that's just a collision). Breaking this silently corrupts HashMap/HashSet behavior β€” see Q31.
Code β€” as answered
class Employee {
    String name;
    int id;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee e = (Employee) o;
        return id == e.id && Objects.equals(name, e.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, id);
    }
}
Practical rule of thumb: use the exact same set of fields in both methods, and lean on Objects.equals() / Objects.hash() instead of writing null checks by hand β€” or better, let your IDE / Lombok's @EqualsAndHashCode generate them consistently.
Q31 Does a Set reject a "duplicate" custom object if equals()/hashCode() aren't overridden?
βœ… Asked Level: Medium
Topic: Collections
Problem
Set<Employee> set = new LinkedHashSet<>(); set.add(new Employee("abc", 1)); set.add(new Employee("abc", 1)); // same id, different instance β€” does this get added?
Answer
It depends entirely on whether equals()/hashCode() are overridden: β€” Without overriding them, Set falls back to Object's default identity-based implementation. Two different instances β€” even with identical field values β€” are not considered equal, so both get added. β€” With them overridden to compare by id (and/or name, as in Q30), the second object is correctly recognized as a duplicate and rejected.
Code β€” demonstrating both cases
// Without equals()/hashCode() overridden:
Set<Employee> set = new LinkedHashSet<>();
set.add(new Employee("abc", 1));
set.add(new Employee("abc", 1));
System.out.println(set.size());   // 2 -> both added (identity comparison)

// With equals()/hashCode() overridden (see Q30):
Set<EmployeeWithEquals> set2 = new LinkedHashSet<>();
set2.add(new EmployeeWithEquals("abc", 1));
set2.add(new EmployeeWithEquals("abc", 1));
System.out.println(set2.size());  // 1 -> second one rejected as a duplicate
Why this matters in real code: forgetting to override equals()/hashCode() on entity/DTO classes used in Sets or as Map keys is one of the most common real-world bugs β€” it silently allows duplicates or makes lookups fail even when "the same" object is queried.
Q32 Toll-booth log parser bug fix
βœ… Asked Level: Medium
Topic: Real-World Debugging β€” live debugging exercise, common at 3-8 YoE for practical/production-code rounds
Problem
A toll-booth log parser has a bug. LogEntry(String logLine) parses lines like 34400.409 SXY288 210E ENTRY (timestamp, license plate, location+direction, booth type) by splitting on a single space: logLine.split(" "). The provided JUnit tests fail. Find and fix the bug.
Root cause
The bug is in the split logic, not the field indices. logLine.split(" ") breaks the moment a log line has irregular or multiple whitespace between tokens (or leading/trailing whitespace) β€” it produces empty-string tokens that shift every subsequent index, which then throws NumberFormatException or ArrayIndexOutOfBoundsException downstream.
Fix
  • Trim the line first, then split on one or more whitespace characters using the regex \s+ instead of a literal single space.
  • This reliably collapses any run of spaces/tabs between fields so tokens[0..3] always map correctly to timestamp, license plate, location+direction, and booth type β€” regardless of how many spaces separate them in the source log.
Code
public class LogEntry {
    double timestamp;
    String licensePlate;
    String locationDirection;
    String boothType;

    public LogEntry(String logLine) {
        // BUG: logLine.split(" ") breaks on irregular/multiple whitespace
        // FIX: strip the line and split on one-or-more whitespace characters
        String[] tokens = logLine.strip().split("\\s+");

        this.timestamp = Double.parseDouble(tokens[0]);
        this.licensePlate = tokens[1];
        this.locationDirection = tokens[2];
        this.boothType = tokens[3];
    }
}
// "34400.409  SXY288   210E ENTRY"  (irregular spacing) now parses correctly
Interview signal: this kind of question tests whether you actually read the failing test output and reason about why it fails, rather than guessing at index changes. Always reproduce the failure first, then fix the root cause.
↑ back to top