JUNE 2026 Coding interviews test recall. kodr.run tests engineering judgment
JavaBeginner15 minGeneral

Top Java Coding Interview Questions (With Answers)

Intro

If you are preparing for a Java interview, the same handful of questions appear again and again — across service companies, product firms, and campus placements. This guide collects the fifteen that come up most, grouped by the kind of thinking each one tests. For every question you get working code, the output it produces, the time and space complexity, and — because the people setting these questions read guides too — a short note on what a strong answer actually signals.

The first five are covered in depth, including the optimised alternative an interviewer is usually steering you toward. The remaining ten are tighter: the working solution and the one insight that matters.

How interviewers read a Java answer

When an interviewer poses a coding question, they are reading four layers, roughly in this order:

LayerWhat a weaker answer doesWhat a stronger answer does
CorrectnessSolves the happy path; misses empty input, nulls, or caseNames the edge cases before coding and handles them
EfficiencyShips the first idea that works, usually a nested loopStates the complexity, then reaches for the O(n) approach and explains why
IdiomHand-rolls loops for things the library already doesUses StringBuilder, the Collections framework, and Stream/Collectors, and explains the trade-off
CommunicationCodes in silence, presents a finished blockThinks out loud, so the interviewer sees the reasoning

1How do you reverse a string in Java?

The classic opener. Java strings are immutable, so it reveals whether you reach for the right mutable-builder idiom or fight the type.

Java · ReverseString.java
public class ReverseString {
    public static String reverseString(String text) {
        return new StringBuilder(text).reverse().toString();
    }


    public static void main(String[] args) {
        String text = "interview";
        System.out.println(reverseString(text)); // weivretni
    }
}

StringBuilder.reverse() mutates an internal char array in place and only allocates once, on toString(). O(n) time, O(n) space. Naive alternative that also works, but allocates a new String on every concatenation inside the loop:

Java · ReverseStringNaive.java
public class ReverseStringNaive {
    public static String reverseStringNaive(String text) {
        String reversed = "";
        for (int i = text.length() - 1; i >= 0; i--) {
            reversed += text.charAt(i); // O(n) per concatenation -> O(n²) overall
        }
        return reversed;
    }


    public static void main(String[] args) {
        System.out.println(reverseStringNaive("interview")); // weivretni
    }
}

What this evaluates: idiom. Reaching for StringBuilder signals you know Java strings are immutable and why repeated += in a loop is a red flag; the manual loop signals someone who hasn't internalised that yet.

2How do you check whether a string is a palindrome?

Java · PalindromeCheck.java
public class PalindromeCheck {
    public static boolean isPalindrome(String text) {
        String cleaned = text.toLowerCase().replace(" ", "");
        return cleaned.equals(new StringBuilder(cleaned).reverse().toString());
    }


    public static void main(String[] args) {
        System.out.println(isPalindrome("Race car")); // true
        System.out.println(isPalindrome("hello")); // false
    }
}

The judgment is in the cleaning step. A strong candidate asks whether case and spaces should be ignored before coding. O(n) time, O(n) space.

What this evaluates: correctness / edge-case awareness. The clarifying question is worth more than the code.

3How do you count the vowels in a string?

Java · CountVowels.java
public class CountVowels {
    public static long countVowels(String text) {
        String vowels = "aeiou";
        return text.toLowerCase().chars()
            .filter(c -> vowels.indexOf(c) >= 0)
            .count();
    }


    public static void main(String[] args) {
        System.out.println(countVowels("Education")); // 5
    }
}

chars() streams the string lazily — no intermediate array is materialised. Compare against pre-materialising with toCharArray():


ApproachMemoryWhen it matters
text.chars().filter(...).count() — streamO(1) extraLarge strings; preferred
text.toCharArray() then loopO(n) extraSame result, allocates the full array up front

What this evaluates: idiom and memory. The follow-up — "what if the string is a gigabyte?" — is where the stream answer shows you understand lazy evaluation over eager materialisation.

4How do you find the first non-repeating character in a string?

Java · FirstUniqueCharacter.java
import java.util.LinkedHashMap;
import java.util.Map;


public class FirstUniqueCharacter {
    public static Character firstUnique(String text) {
        Map<Character, Integer> counts = new LinkedHashMap<>();
        for (char c : text.toCharArray()) {
            counts.merge(c, 1, Integer::sum);
        }
        for (char c : text.toCharArray()) {
            if (counts.get(c) == 1) return c;
        }
        return null;
    }


    public static void main(String[] args) {
        System.out.println(firstUnique("swiss")); // w
    }
}

Two passes, O(n) total. The naive version calls text.indexOf(c) == text.lastIndexOf(c) inside the loop — each call rescans the string, making it O(n²).

What this evaluates: efficiency. Both return 'w'; the signal is noticing the hidden O(n²) in the naive check and reaching for a single count pass to make it O(n) — said out loud.

5How do you check if two strings are anagrams?

Java · AnagramCheck.java
public class AnagramCheck {
    public static boolean isAnagram(String a, String b) {
        if (a.length() != b.length()) return false;
        int[] counts = new int[26];
        for (char c : a.toCharArray()) counts[c - 'a']++;
        for (char c : b.toCharArray()) counts[c - 'a']--;
        for (int n : counts) if (n != 0) return false;
        return true;
    }


    public static void main(String[] args) {
        System.out.println(isAnagram("listen", "silent")); // true
        System.out.println(isAnagram("hello", "world")); // false
    }
}

A fixed 26-slot frequency array checks counts in one O(n) pass, no extra allocation beyond the array. The commonly-taught alternative sorts both strings:


Java · AnagramCheck.java
import java.util.Arrays;


public class AnagramCheckSorted {
    public static boolean isAnagramSorted(String a, String b) {
        char[] ca = a.toCharArray();
        char[] cb = b.toCharArray();
        Arrays.sort(ca);
        Arrays.sort(cb);
        return Arrays.equals(ca, cb); // correct, but O(n log n)
    }


    public static void main(String[] args) {
        System.out.println(isAnagramSorted("listen", "silent")); // true
        System.out.println(isAnagramSorted("hello", "world")); // false
    }
}
ApproachTimeNote
int[26] frequency countO(n)Counts once, compares
Arrays.sort bothO(n log n)Shorter to write, slower at scale

What this evaluates: efficiency + idiom. Naming the trade-off unprompted — "sorting works and is O(n log n), but a frequency array gets it to O(n)" — is the senior signal.

6FizzBuzz

Java · FizzBuzz.java
public class FizzBuzz {
    public static void fizzBuzz(int limit) {
        for (int i = 1; i <= limit; i++) {
            if (i % 15 == 0) System.out.println("FizzBuzz");
            else if (i % 3 == 0) System.out.println("Fizz");
            else if (i % 5 == 0) System.out.println("Buzz");
            else System.out.println(i);
        }
    }


    public static void main(String[] args) {
        fizzBuzz(15);
        // 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
    }
}

The trap: check i % 15 first. Evaluates: correctness and ordering of conditions.

7Fibonacci sequence

Java · Fibonacci.java
import java.util.ArrayList;
import java.util.List;


public class Fibonacci {
    public static List<Integer> fib(int n) {
        List<Integer> result = new ArrayList<>();
        int a = 0, b = 1;
        for (int i = 0; i < n; i++) {
            result.add(a);
            int next = a + b;
            a = b;
            b = next;
        }
        return result;
    }


    public static void main(String[] args) {
        System.out.println(fib(8)); // [0, 1, 1, 2, 3, 5, 8, 13]
    }
}

The swap via a next temp is the clean iterative move. Iterative O(n) vs naive recursion O(2ⁿ). Evaluates: idiom; avoiding exponential recursion.

8Remove duplicates, keep order

Java · DuplicatesRemove.java
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;


public class DuplicatesRemove {
    public static List<Integer> dedupe(List<Integer> seq) {
        return new ArrayList<>(new LinkedHashSet<>(seq));
    }


    public static void main(String[] args) {
        System.out.println(dedupe(List.of(3, 1, 3, 2, 1, 5))); // [3, 1, 2, 5]
    }
}

LinkedHashSet preserves first-seen insertion order while dropping duplicates, so the dedupe is one line. O(n). Evaluates: efficiency and knowing which Set implementation preserves order (HashSet would not).

9Most frequent character

Java · FreqChar.java
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;


public class FreqChar {
    public static char maxChar(String text) {
        Map<Character, Long> counts = text.chars()
            .mapToObj(c -> (char) c)
            .collect(Collectors.groupingBy(c -> c, Collectors.counting()));
        return Collections.max(counts.entrySet(), Map.Entry.comparingByValue()).getKey();
    }


    public static void main(String[] args) {
        System.out.println(maxChar("aabbbcc")); // b
    }
}

Evaluates: idiom — knowing Collectors.groupingBy with a downstream counting() collector rather than hand-rolling a HashMap counter loop.

10Two Sum

Java · TwoSum.java
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


public class TwoSum {
    public static int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> seen = new HashMap<>();
        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);
        }
        return new int[]{};
    }


    public static void main(String[] args) {
        System.out.println(Arrays.toString(twoSum(new int[]{2, 7, 11, 15}, 9))); // [0, 1]
    }
}

Hashmap, one pass, O(n). Brute force nested loop is O(n²). Evaluates: efficiency — the canonical O(n²) → O(n) with a hashmap.

11Missing number from 1 to n

Java · MissingNumber.java
public class MissingNumber {
    public static int missing(int[] nums, int n) {
        int expected = n * (n + 1) / 2;
        int actual = 0;
        for (int num : nums) actual += num;
        return expected - actual;
    }


    public static void main(String[] args) {
        System.out.println(missing(new int[]{1, 2, 4, 5}, 5)); // 3
    }
}

O(n) time, O(1) space. Evaluates: reaching for the maths insight over sorting.

12Reverse words in a sentence

Java · ReverseWords.java
import java.util.Arrays;
import java.util.Collections;


public class ReverseWords {
    public static String reverseWords(String sentence) {
        String[] words = sentence.trim().split("\\s+");
        Collections.reverse(Arrays.asList(words));
        return String.join(" ", words);
    }


    public static void main(String[] args) {
        System.out.println(reverseWords("the quick brown fox")); // fox brown quick the
    }
}

Reverses word order, not characters — and note Arrays.asList is backed by the original array, so Collections.reverse mutates it in place. Evaluates: correctness — clarifying "words" vs "characters", plus awareness of Arrays.asList's fixed-size, array-backed behaviour.

13Balanced parentheses

Java · BalancedParantheses.java
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;


public class BalancedParantheses {
    public static boolean isBalanced(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 (pairs.containsKey(c)) {
                if (stack.isEmpty() || stack.pop() != pairs.get(c)) return false;
            }
        }
        return stack.isEmpty();
    }


    public static void main(String[] args) {
        System.out.println(isBalanced("({[]})")); // true
        System.out.println(isBalanced("([)]")); // false
    }
}

O(n). Note ArrayDeque is the recommended stack in modern Java — faster than Stack, which is a legacy synchronized class. Evaluates: data-structure choice — recognising the stack signature and picking the right implementation.

14Flatten a nested list

Java · FlattenNestedList.java
import java.util.ArrayList;
import java.util.List;


public class FlattenNestedList {
    public static List<Integer> flatten(List<?> nested) {
        List<Integer> result = new ArrayList<>();
        for (Object item : nested) {
            if (item instanceof List<?> list) {
                result.addAll(flatten(list));
            } else {
                result.add((Integer) item);
            }
        }
        return result;
    }


    public static void main(String[] args) {
        System.out.println(flatten(List.of(1, List.of(2, List.of(3, 4), 5)))); // [1, 2, 3, 4, 5]
    }
}

Uses a Java 16+ pattern-matching instanceof to check and cast in one step. Evaluates: recognising arbitrary nesting needs recursion, plus comfort with instanceof pattern matching over the older cast-after-check style.

15Word frequency

Java · WordFrequency.java
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;


public class WordFrequency {
    public static Map<String, Long> wordFrequency(String text) {
        return Arrays.stream(text.split(" "))
            .collect(Collectors.groupingBy(w -> w, Collectors.counting()));
    }


    public static void main(String[] args) {
        Map<String, Long> freq = wordFrequency("the cat sat on the mat the cat");
        System.out.println(freq.get("the")); // 3
        System.out.println(freq.get("cat")); // 2
    }
}


Evaluates: idiom - reusing the groupingBy/counting() collector pair across problem shapes, the same move as Q9.

Frequently Asked Questions

What are the most common Java coding interview questions?
Four groups: string manipulation, counting/frequency (usually HashMap or Collectors.groupingBy), array/number logic (Two Sum, missing number), and structure problems (balanced parentheses, flattening nested lists). The fifteen here cover the patterns behind nearly all of them.
Are Java interview questions different for freshers and experienced developers?
The questions overlap, but the bar shifts. Freshers: a correct working solution. Experienced: state complexity, reach for the optimised approach, explain the trade-off.
Should I use Streams and Collectors in an interview?
Yes, and explain why — it signals fluency with modern Java. The exception is when the interviewer explicitly asks you to implement the logic with a raw loop.
How important is time and space complexity in a Java interview?
Often the single most important thing. Naming the complexity of both naive and optimised, unprompted, frequently separates a pass from an offer.
How long does it take to prepare for a Java coding interview?
If you know the syntax, a few focused weeks to reproduce the patterns without reference. The goal is pattern recognition, not memorising answers.