Java Interview Questions for Freshers: Collections, Exceptions and JVM Traces

Practise Java interviews by predicting exact outputs, tracing object and collection state, following exception paths, and explaining JVM memory without slogans.

KnowledgeGate Team

Exam prep & CS education

Updated 30 Aug 20266 min read

Definitions such as "a Set stores unique values" or "the JVM runs bytecode" sound correct until an interviewer changes one key, throws one exception, or asks which object is still reachable. The useful method is to predict the exact value or output, name the rule that produces it, then test one edge case. For broader practice, use the Resume & Interview Preparation category to connect Java concepts with the rest of the technical interview.

Answer Java interview questions with a trace, not a slogan

Use a four-part answer: state the result, identify the controlling contract, trace the relevant state change, then add one boundary or trade-off. Instead of saying "HashSet removes duplicates", identify the equal objects, explain why their hashes agree, and conclude why the size is 2.

Match the answer to the prompt. Output prediction needs exact values in order. A design choice needs the workload plus ordering requirements. A repair question needs the broken invariant and the smallest safe correction. The broader Technical Interview CS Subjects for Freshers gives you a cross-subject checklist covering operating systems, DBMS, computer networks and OOP alongside Java.

Object contracts: equals, hashCode and mutable-key traps

Suppose Candidate is a Java record. For c1 = new Candidate(101, "Asha"), c2 = new Candidate(101, "Asha"), and c3 = new Candidate(102, "Ravi"), the results are:

  • c1 == c2 is false because they are distinct objects.

  • c1.equals(c2) is true because record equality uses component values.

  • c1.hashCode() == c2.hashCode() is true, consistent with equality.

  • new LinkedHashSet<>(List.of(c1, c2, c3)).size() is 2.

After scores.put(c1, 82) and scores.put(c2, 90), the map size is 1. An equal key updates the existing logical mapping, so scores.get(new Candidate(101, "Asha")) returns 90. This is value equality, not the reference-identity and pool question explored in String Handling in Java.

Now make Badge.id mutable and use it in both equals and hashCode. Put Badge(7) into a HashMap, change its ID to 8, and map.get(theSameBadge) can be null while map.size() remains 1. The key is now searched in a bucket chosen from its new hash. Equality and hash fields must not change while an object is a hash key.

Collections behaviour: choose by contract and trace the overload

The next trace depends on overload resolution as much as list mutation:

List<Integer> marks = new ArrayList<>(List.of(10, 20, 30));
marks.remove(1);
marks.remove(Integer.valueOf(10));

The trace is [10, 20, 30] to [10, 30] to [30]. The primitive 1 selects remove(int index). Wrapping 10 selects remove(Object).

For List.of("Java", "SQL", "Java"), a LinkedHashSet displays [Java, SQL]: it removes the repeated value and retains first insertion order. A plain HashSet still guarantees uniqueness, but its iteration order must not be predicted.

Choose by required operations: ArrayList for frequent indexed reads and ordinary iteration, ArrayDeque for work at either end, HashSet for membership and uniqueness without an order requirement, LinkedHashSet when first-seen order matters, and HashMap for key-to-value lookup. No implementation is always faster; workload and contract decide.

Exception flow: predict catch, finally, return and escape order

Trace this method with a caller that prints result before each returned value and catches any escaping RuntimeException, printing escaped plus the exception's simple class name:

static int divide(String raw) {
    System.out.println("start " + raw);
    try {
        return 100 / Integer.parseInt(raw);
    } catch (NumberFormatException ex) {
        System.out.println("not a number");
        return -1;
    } finally {
        System.out.println("finally " + raw);
    }
}

For "4", the order is start 4, finally 4, then result 25. For "bad", it is start bad, not a number, finally bad, then result -1. For "0", it is start 0, finally 0, then escaped ArithmeticException. The type-specific catch does not handle division by zero.

A computed return waits while finally runs, and finally also runs during ordinary exception propagation. Returning from finally can replace an earlier return or suppress an exception, which makes it both an interview trap and poor application design. NumberFormatException and ArithmeticException are unchecked RuntimeException subclasses; IOException is checked. throw performs a throw, while throws declares possible propagation.

JVM basics: follow one value from source to frame, heap and return

For the program below, javac InterviewTrace.java produces InterviewTrace.class and Candidate.class. The JVM loads and links required classes, initialises them as needed, and executes main. Class-file bytecode is not CPU machine code. A JVM may interpret code or JIT-compile hot code, but there is no universal compilation threshold to promise.

Freeze execution during parseScore("82"). The main frame is evaluating scores.put(rows.get(0), parseScore("82")). A separate parseScore frame holds the raw reference and parsed primitive 82. The candidates, list, set and map are reachable through references held by main. When the method returns, its frame is removed and 82 is supplied to the pending map operation.

Frames belong to each thread's JVM stack; objects and arrays use heap storage. References may live in local variables, object fields, static fields or array elements, so "references are always on the stack" is false. An object becomes eligible for reclamation only when no live root can reach it, not simply when one alias becomes null.

JVM trace paused at parseScore("82"): main and parseScore stack frames on the left, candidate, list, set and map heap objects on the right.

Integrated interview trace: contracts, collections and exceptions in one program

Save this complete program as InterviewTrace.java:

import java.util.*;

record Candidate(int id, String name) {}

public class InterviewTrace {
    static int parseScore(String raw) {
        try {
            return Integer.parseInt(raw);
        } catch (NumberFormatException ex) {
            return -1;
        } finally {
            System.out.println("checked " + raw);
        }
    }

    public static void main(String[] args) {
        List<Candidate> rows = List.of(
            new Candidate(101, "Asha"),
            new Candidate(101, "Asha"),
            new Candidate(102, "Ravi")
        );

        Set<Candidate> unique = new LinkedHashSet<>(rows);
        Map<Candidate, Integer> scores = new LinkedHashMap<>();
        scores.put(rows.get(0), parseScore("82"));
        scores.put(rows.get(1), parseScore("90"));
        scores.put(rows.get(2), parseScore("bad"));
        scores.entrySet().removeIf(entry -> entry.getValue() < 0);

        System.out.println("unique=" + unique.size());
        System.out.println("scored=" + scores.size());
        System.out.println("Asha=" + scores.get(new Candidate(101, "Asha")));
    }
}

The exact output is:

checked 82
checked 90
checked bad
unique=2
scored=1
Asha=90

The first two records are equal, so the set retains one logical Asha and Ravi. The second Asha insertion replaces 82 with 90. Parsing "bad" returns -1 after finally prints; removeIf removes Ravi's negative score. A newly constructed equal Asha key therefore retrieves 90. If these contracts still feel disconnected, the Java Course: Concepts, MCQs & Coding Questions provides a structured route through records, collections and exceptions.

Execution trace of InterviewTrace: candidate cards feed a LinkedHashSet to unique=2 and a LinkedHashMap ending at scored=1, Asha=90.

Common fresher traps and the follow-ups an interviewer can add

Repair prompts expose understanding. If code uses == for value equality, choose equals. If equals changes without a consistent hashCode, restore the contract. Do not predict HashSet order, and do not mutate hash keys. Match a catch by exception type, not by textual proximity.

For the JVM, do not say source runs directly, bytecode is native CPU code, every reference is on the stack, alias = null causes immediate collection, or JIT compilation occurs on a fixed call number. Separate specified runtime areas from implementation choices, and reachability from collection timing.

Now extend the program. Replace LinkedHashSet with HashSet, and set order is no longer predictable. Change the second candidate's ID to 103, and the result becomes unique=3, scored=2, Asha=82. Remove the catch from parseScore, and NumberFormatException escapes only after finally prints checked bad.

Short version and next step

Use this order: object contract, collection contract, exception path, then reachability and frame lifetime. Here, two equal Asha records collapse to one set element and one map key, 90 replaces 82, invalid Ravi input becomes -1 and is removed, leaving unique=2, scored=1, Asha=90.

Append Candidate(103, "Meera") to rows and insert scores.put(rows.get(3), parseScore("75")) before removeIf. Before running it, predict checked 75, then unique=3, scored=2, Asha=90. Once that trace is solid, use the Interview & Resume Preparation Course for broader interview rehearsal.