October 3, 2026
–
Guides

Java Interview Questions — 50 Questions With Answers (2026)

java interview questions — the 50 that actually come up, with answers that make sense

java interviews have a pattern. the interviewer starts with basics — "what's the difference between JDK and JRE?" — then moves to OOP, then collections, then hits you with a multithreading question to see if you really understand concurrency or just memorised a definition.

this guide covers 50 java interview questions across five levels: basics, OOP, collections and generics, multithreading and concurrency, and coding problems. every answer is written the way you'd explain it in a real conversation — not copied from the official documentation.

if you want practice sets tailored to the specific java role you're targeting, weekday's interview question predictor generates them based on the company, level, and stack.

a. java basics — the warm-up round

interviewers use these to check whether you've actually built something in java or just completed a tutorial. know these cold.

1. what is java, and why is it still relevant in 2026?

java is a compiled, object-oriented language that runs on the java virtual machine (JVM). "write once, run anywhere" is the original pitch — your compiled bytecode runs on any platform with a JVM installed.

it's still relevant because most enterprise backends, android apps, and large-scale distributed systems run on java. companies like google, amazon, and every major bank have millions of lines of java in production. the language isn't going anywhere.

2. what's the difference between JDK, JRE, and JVM?

JVM (java virtual machine) — runs the bytecode. it's the engine.

JRE (java runtime environment) — JVM + the standard libraries your code needs at runtime.

JDK (java development kit) — JRE + development tools like the compiler (javac), debugger, and documentation generator.

if you're running java programs, you need JRE. if you're writing them, you need JDK.

3. what are primitive data types in java?

java has 8 primitives: byte, short, int, long, float, double, char, and boolean. they store values directly in memory, not as objects.

the most common mistake freshers make: using int everywhere when long is needed. if you're working with timestamps, IDs, or anything that might exceed 2.1 billion, use long.

4. what's the difference between == and .equals()?

== compares references — are these the exact same object in memory? .equals() compares values — do these objects contain the same data?

String a = new String("weekday");
String b = new String("weekday");
System.out.println(a == b);       // false — different objects
System.out.println(a.equals(b));  // true — same content

this question trips up more people than it should. always use .equals() for string comparison.

5. why is String immutable in java?

once a String object is created, its value can't be changed. if you "modify" a string, java creates a new object instead.

why? three reasons: security (strings are used in class loading, network connections, and database URLs — you don't want those changing mid-operation), thread safety (immutable objects are inherently safe to share between threads), and performance (the string pool can cache and reuse immutable strings).

6. what does the static keyword do?

static means the member belongs to the class, not to any specific instance. a static variable is shared across all objects. a static method can be called without creating an object.

class Counter {
    static int count = 0;
    Counter() { count++; }
}

new Counter();
new Counter();
System.out.println(Counter.count);  // 2

7. what's the difference between final, finally, and finalize?

these three words look similar but do completely different things:

final — a modifier. final variable can't be reassigned, final method can't be overridden, final class can't be extended.

finally — a block in try-catch that always executes, whether the exception was thrown or not. use it for cleanup — closing connections, releasing resources.

finalize — a method the garbage collector calls before destroying an object. it's deprecated since java 9 and you shouldn't use it. use try-with-resources instead.

8. how does exception handling work in java?

wrap risky code in a try block. catch specific exceptions in catch blocks. clean up in finally.

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("can't divide by zero: " + e.getMessage());
} finally {
    System.out.println("this always runs");
}

the rule: catch the most specific exception first. never write a bare catch (Exception e) unless you're at the top level and logging everything.

9. what's the difference between checked and unchecked exceptions?

checked exceptions — the compiler forces you to handle them. examples: IOException, SQLException. if your method might throw one, you must either catch it or declare it with throws.

unchecked exceptions — subclasses of RuntimeException. the compiler doesn't force you to handle them. examples: NullPointerException, ArrayIndexOutOfBoundsException. these usually indicate programming errors.

10. what is autoboxing and unboxing?

autoboxing — java automatically converts a primitive to its wrapper class. int becomes Integer.

unboxing — the reverse. Integer becomes int.

Integer wrapped = 42;        // autoboxing: int → Integer
int unwrapped = wrapped;     // unboxing: Integer → int

watch out for unboxing a null — it throws NullPointerException. this is a common source of production bugs.

b. object-oriented programming — the core of every java interview

java is fundamentally an OOP language. if you can't explain inheritance, polymorphism, and abstraction with examples, the interview is over before it starts.

11. what are the four pillars of OOP?

encapsulation — bundling data and the methods that operate on it inside a class, hiding internal details behind access modifiers.

inheritance — creating a new class based on an existing one, reusing its fields and methods.

polymorphism — the same method behaves differently depending on the object calling it.

abstraction — exposing only what's necessary and hiding the implementation details.

12. what's the difference between an abstract class and an interface?

an abstract class can have both abstract methods (no body) and concrete methods (with a body). it can hold state — instance variables, constructors, the works. a class can extend only one abstract class.

an interface defines a contract — what methods a class must implement. since java 8, interfaces can also have default and static methods. a class can implement multiple interfaces.

rule of thumb: use an abstract class when classes share behaviour and state. use an interface when unrelated classes need to follow the same contract.

13. explain method overloading vs method overriding

overloading — same method name, different parameters, in the same class. it's resolved at compile time.

overriding — same method name and parameters, in a subclass. it's resolved at runtime.

// overloading — same class, different parameters
class Calculator {
    int add(int a, int b) { return a + b; }
    double add(double a, double b) { return a + b; }
}

// overriding — subclass changes parent behaviour
class Animal {
    void speak() { System.out.println("..."); }
}
class Dog extends Animal {
    @Override
    void speak() { System.out.println("woof"); }
}

14. what is the super keyword?

super refers to the parent class. you use it to call the parent's constructor, access the parent's methods, or reference the parent's fields when they're shadowed by the child class.

class Employee {
    String name;
    Employee(String name) { this.name = name; }
}
class Manager extends Employee {
    String department;
    Manager(String name, String dept) {
        super(name);  // calls Employee's constructor
        this.department = dept;
    }
}

15. can you achieve multiple inheritance in java?

not with classes — java doesn't allow a class to extend more than one class. this avoids the "diamond problem" where two parent classes have the same method and the compiler doesn't know which one to use.

but you can implement multiple interfaces. since java 8, if two interfaces have the same default method, you must override it in the implementing class to resolve the conflict.

16. what is the this keyword?

this refers to the current object. the most common use: distinguishing between instance variables and constructor/method parameters with the same name.

class User {
    String name;
    User(String name) {
        this.name = name;  // this.name is the field, name is the parameter
    }
}

17. what are access modifiers in java?

four levels of access control:

private — accessible only within the same class.

default (no modifier) — accessible within the same package.

protected — same package + subclasses in other packages.

public — accessible from anywhere.

the default answer in interviews: "make fields private, expose through public getters/setters." that's encapsulation in practice.

18. what is an enum?

an enum is a special class that represents a fixed set of constants. use it instead of magic strings or integer codes.

enum Status {
    PENDING, APPROVED, REJECTED;
}

// usage
Status current = Status.APPROVED;
if (current == Status.APPROVED) {
    System.out.println("application approved");
}

enums are type-safe, can have methods and fields, and work cleanly in switch statements.

19. what is the difference between composition and inheritance?

inheritance — "is-a" relationship. a Dog is an Animal.

composition — "has-a" relationship. a Car has an Engine.

modern java favours composition over inheritance. why? inheritance creates tight coupling between parent and child. composition lets you swap components without breaking the class hierarchy.

20. what are records in java?

introduced in java 14, records are a compact way to create immutable data-carrying classes. the compiler generates the constructor, getters, equals(), hashCode(), and toString() for you.

record Employee(String name, int age, String department) {}

// usage
Employee emp = new Employee("Priya", 28, "Engineering");
System.out.println(emp.name());  // "Priya"

use records for DTOs, API responses, and any class that's just a container for data.

c. collections and generics — where mid-level interviews live

if you can explain when to use HashMap vs TreeMap and why ArrayList isn't always the best choice, you're ahead of most candidates.

21. what is the collections framework?

it's a set of interfaces and classes that handle groups of objects — lists, sets, maps, and queues. the core interfaces are Collection (parent of List, Set, Queue) and Map (key-value pairs).

everything in java.util. the framework replaced the older Vector and Hashtable classes, which had synchronization overhead nobody needed in single-threaded code.

22. ArrayList vs LinkedList — when to use which?

ArrayList — backed by an array. fast random access (O(1) by index). slow insertions/deletions in the middle (O(n) because elements shift).

LinkedList — backed by a doubly-linked list. fast insertions/deletions (O(1) at the position). slow random access (O(n) because you traverse from the start).

in practice: use ArrayList almost always. LinkedList wins only when you're doing heavy insertions/deletions at the beginning or middle and never accessing by index.

23. how does HashMap work internally?

HashMap stores key-value pairs in an array of "buckets." when you put a key, java calls hashCode() on it, computes the bucket index, and stores the entry there.

if two keys land in the same bucket (a collision), they're stored as a linked list. since java 8, when a bucket has more than 8 entries, the linked list converts to a balanced tree for O(log n) lookups instead of O(n).

this is the single most-asked collections question. know it inside out.

24. HashMap vs TreeMap vs LinkedHashMap

HashMap — no ordering. O(1) for get/put. allows one null key.

TreeMap — sorted by keys (natural order or a Comparator). O(log n) for get/put. no null keys.

LinkedHashMap — maintains insertion order. O(1) for get/put. useful when you want predictable iteration order.

Map<String, Integer> scores = new LinkedHashMap<>();
scores.put("Alice", 92);
scores.put("Bob", 87);
scores.put("Charlie", 95);
// iterating gives: Alice → Bob → Charlie (insertion order)

25. HashSet vs TreeSet vs LinkedHashSet

same pattern as the Map variants — because Set implementations are backed by Maps internally.

HashSet — no order, O(1) add/contains. backed by HashMap.

TreeSet — sorted, O(log n) operations. backed by TreeMap.

LinkedHashSet — insertion order preserved. backed by LinkedHashMap.

26. what are generics, and why do they matter?

generics let you write type-safe code without casting. instead of storing Objects and casting them back, you specify the type upfront.

// without generics — runtime ClassCastException risk
List list = new ArrayList();
list.add("hello");
Integer num = (Integer) list.get(0);  // crash at runtime

// with generics — compile-time safety
List<String> list = new ArrayList<>();
list.add("hello");
// list.add(42);  // compiler error — caught before running

27. what is type erasure?

generics exist only at compile time. the compiler checks your types, then erases them — replacing type parameters with Object (or bounds) in the bytecode. at runtime, List<String> and List<Integer> are both just List.

this means you can't do new T(), check instanceof List<String>, or create generic arrays. it's a trade-off java made for backward compatibility.

28. what is the Comparable vs Comparator difference?

Comparable — the class defines its own natural ordering by implementing compareTo(). one sorting strategy, built into the class.

Comparator — an external object that defines a custom ordering. you can have multiple Comparators for the same class.

// Comparable — built-in ordering
class Employee implements Comparable<Employee> {
    String name;
    int salary;
    public int compareTo(Employee other) {
        return Integer.compare(this.salary, other.salary);
    }
}

// Comparator — external, flexible
Comparator<Employee> byName = Comparator.comparing(e -> e.name);

29. what is the Iterator pattern?

Iterator provides a standard way to traverse a collection without exposing its internal structure. you call hasNext() to check if there's another element, and next() to retrieve it.

the key advantage: you can safely remove elements during iteration using iterator.remove(). modifying a collection directly while iterating throws ConcurrentModificationException.

30. what is the difference between fail-fast and fail-safe iterators?

fail-fast — throws ConcurrentModificationException if the collection is modified during iteration. ArrayList, HashMap use fail-fast iterators.

fail-safe — works on a clone of the collection, so modifications don't cause exceptions. ConcurrentHashMap, CopyOnWriteArrayList use fail-safe iterators.

d. multithreading and concurrency — where senior interviews happen

if you're interviewing for a mid-level or senior java role, expect at least 3-4 concurrency questions. this is where companies filter for real experience.

31. what's the difference between a process and a thread?

a process is an independent program with its own memory space. a thread is a lightweight unit of execution within a process — threads share the process's memory.

java applications run as a single process with multiple threads. the main thread starts execution; you create additional threads for parallel work.

32. how do you create a thread in java?

two ways:

// 1. extend Thread
class MyThread extends Thread {
    public void run() {
        System.out.println("running in: " + getName());
    }
}
new MyThread().start();

// 2. implement Runnable (preferred)
Runnable task = () -> System.out.println("running in: " + Thread.currentThread().getName());
new Thread(task).start();

prefer Runnable because java allows only single inheritance. if you extend Thread, you can't extend anything else.

33. what is synchronization?

synchronization ensures only one thread accesses a shared resource at a time. without it, two threads modifying the same variable can produce corrupt data — a race condition.

class BankAccount {
    private int balance = 1000;

    synchronized void withdraw(int amount) {
        if (balance >= amount) {
            balance -= amount;
        }
    }
}

the synchronized keyword acquires a lock on the object. only one thread can hold the lock at a time.

34. what is a deadlock, and how do you prevent it?

deadlock happens when two threads each hold a lock the other needs, and neither can proceed.

prevention strategies: always acquire locks in the same order, use tryLock() with a timeout instead of synchronized, and keep synchronized blocks as short as possible.

35. what is the volatile keyword?

volatile tells the JVM: don't cache this variable in a thread's local memory — always read from and write to main memory.

it guarantees visibility (all threads see the latest value) but not atomicity. if you need both, use AtomicInteger or synchronized.

class Flag {
    volatile boolean running = true;

    void stop() { running = false; }

    void run() {
        while (running) {
            // do work — guaranteed to see the updated value
        }
    }
}

36. explain the ExecutorService

ExecutorService is a thread pool manager. instead of creating and destroying threads manually (expensive), you submit tasks to a pool of reusable threads.

ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> System.out.println("task 1"));
pool.submit(() -> System.out.println("task 2"));
pool.shutdown();

in production code, you should almost never create raw threads. use ExecutorService, or even better — CompletableFuture.

37. what is CompletableFuture?

CompletableFuture lets you write non-blocking, asynchronous code in a readable chain — like promises in javascript.

CompletableFuture.supplyAsync(() -> fetchUserFromDB(userId))
    .thenApply(user -> user.getEmail())
    .thenAccept(email -> sendWelcomeEmail(email))
    .exceptionally(ex -> { log.error("failed", ex); return null; });

this replaced the old Future interface, which forced you to call get() and block the thread while waiting.

38. what are virtual threads?

introduced in java 21, virtual threads are lightweight threads managed by the JVM, not the OS. you can create millions of them without running out of memory.

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 100_000; i++) {
        executor.submit(() -> {
            Thread.sleep(1000);
            return "done";
        });
    }
}

virtual threads are a game-changer for I/O-heavy applications — web servers, microservices, anything that spends time waiting for database or API responses.

39. what is the difference between wait() and sleep()?

sleep() — pauses the current thread for a specified time. the thread keeps its lock.

wait() — releases the lock and waits until another thread calls notify() or notifyAll() on the same object.

sleep() is a Thread method. wait() is an Object method and must be called inside a synchronized block.

40. what is ConcurrentHashMap, and why not just synchronize HashMap?

synchronizing a HashMap locks the entire map for every operation — read or write. ConcurrentHashMap uses segment-level locking (in older java) and CAS operations (in java 8+), so multiple threads can read and write different segments simultaneously.

the performance difference is massive under high concurrency. always use ConcurrentHashMap for shared maps in multi-threaded code.

e. coding problems and java 8+ features — the practical round

most java interviews end with a coding round. these questions test whether you can actually write java — not just talk about it.

41. reverse a string without using StringBuilder.reverse()

public static String reverse(String input) {
    char[] chars = input.toCharArray();
    int left = 0, right = chars.length - 1;
    while (left < right) {
        char temp = chars[left];
        chars[left] = chars[right];
        chars[right] = temp;
        left++;
        right--;
    }
    return new String(chars);
}

System.out.println(reverse("weekday"));  // "yadkeew"

42. check if a string is a palindrome

public static boolean isPalindrome(String s) {
    s = s.toLowerCase().replaceAll("[^a-z0-9]", "");
    int left = 0, right = s.length() - 1;
    while (left < right) {
        if (s.charAt(left) != s.charAt(right)) return false;
        left++;
        right--;
    }
    return true;
}

System.out.println(isPalindrome("madam"));  // true

43. find the first non-repeated character in a string

public static char firstUniqueChar(String s) {
    Map<Character, Integer> countMap = new LinkedHashMap<>();
    for (char c : s.toCharArray()) {
        countMap.put(c, countMap.getOrDefault(c, 0) + 1);
    }
    for (Map.Entry<Character, Integer> entry : countMap.entrySet()) {
        if (entry.getValue() == 1) return entry.getKey();
    }
    return '_';  // no unique character found
}

System.out.println(firstUniqueChar("javascript"));  // 'j'

44. what are lambda expressions?

lambdas are anonymous functions introduced in java 8. they let you pass behaviour as an argument — making code shorter and more readable.

// before lambdas
Comparator<String> comp = new Comparator<String>() {
    public int compare(String a, String b) {
        return a.length() - b.length();
    }
};

// with lambdas
Comparator<String> comp = (a, b) -> a.length() - b.length();

45. explain the Stream API with an example

streams let you process collections declaratively — filter, transform, and aggregate data in a pipeline.

List<String> names = List.of("alice", "bob", "charlie", "david", "eve");

List<String> result = names.stream()
    .filter(name -> name.length() > 3)
    .map(String::toUpperCase)
    .sorted()
    .collect(Collectors.toList());

// result: [ALICE, CHARLIE, DAVID]

the key distinction: intermediate operations (filter, map, sorted) are lazy — they don't execute until a terminal operation (collect, forEach, count) triggers the pipeline.

46. what is Optional, and why should you use it?

Optional is a container that may or may not hold a value. it forces you to handle the "no value" case explicitly instead of returning null.

Optional<String> email = findUserEmail(userId);

// bad — defeats the purpose
String value = email.get();  // throws if empty

// good — handles both cases
String value = email.orElse("no-email@example.com");

// better — chain operations
email.filter(e -> e.contains("@"))
     .ifPresent(e -> sendNotification(e));

47. write a program to find duplicate elements in an array

public static List<Integer> findDuplicates(int[] arr) {
    Set<Integer> seen = new HashSet<>();
    Set<Integer> duplicates = new LinkedHashSet<>();
    for (int num : arr) {
        if (!seen.add(num)) {
            duplicates.add(num);
        }
    }
    return new ArrayList<>(duplicates);
}

int[] arr = {1, 3, 5, 3, 7, 1, 9};
System.out.println(findDuplicates(arr));  // [3, 1]

48. implement a singleton pattern

public class DatabaseConnection {
    private static volatile DatabaseConnection instance;

    private DatabaseConnection() {}  // private constructor

    public static DatabaseConnection getInstance() {
        if (instance == null) {
            synchronized (DatabaseConnection.class) {
                if (instance == null) {
                    instance = new DatabaseConnection();
                }
            }
        }
        return instance;
    }
}

this is the double-checked locking pattern. the volatile keyword prevents instruction reordering. interviewers love asking why both the null check and synchronized block are needed — the outer check avoids the synchronization overhead after the instance is created.

49. what are sealed classes?

introduced in java 17, sealed classes restrict which other classes can extend them. you control the hierarchy explicitly.

sealed interface Shape permits Circle, Rectangle, Triangle {}

record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}
// any other class trying to implement Shape → compiler error

sealed classes work beautifully with pattern matching — the compiler knows all possible subtypes and can check for exhaustiveness in switch expressions.

50. write a functional interface and use it with a lambda

@FunctionalInterface
interface Transformer<T> {
    T transform(T input);
}

Transformer<String> shout = s -> s.toUpperCase() + "!";
Transformer<Integer> doubleIt = n -> n * 2;

System.out.println(shout.transform("hello"));  // "HELLO!"
System.out.println(doubleIt.transform(21));     // 42

a functional interface has exactly one abstract method. the @FunctionalInterface annotation isn't required, but it tells the compiler to enforce the single-method rule.

how java interviews are structured — by experience level

knowing the questions is half the battle. knowing which ones apply to your level is the other half.

experience levelfocus areastypical salary range
fresher (0-1 year)basics, OOP, simple coding, string manipulation₹3.5–6 LPA
junior (1-3 years)collections, exception handling, generics, JDBC₹5–10 LPA
mid-level (3-5 years)multithreading, design patterns, Spring Boot, microservices₹8–16 LPA
senior (5-9 years)concurrency deep-dives, system design, JVM internals, performance tuning₹14–28 LPA
lead / architect (10+ years)distributed systems, scalability, team leadership, architecture decisions₹25–55 LPA

the salary gap between IT services and product companies is real. a mid-level java developer at TCS or Infosys makes ₹7–15 LPA. the same experience at a product company or GCC (global capability centre) gets ₹15–30 LPA. spring boot, microservices, and cloud experience are the bridge between those two brackets.

how to use this guide to prepare

don't just read. do this:

step 1: open your IDE and type out every code example. reading code and writing code use different parts of your brain. if you can't write it from memory, you don't know it yet.

step 2: explain each answer out loud. interviews are conversations, not written exams. if you can explain HashMap's internal working to a non-technical friend, you can explain it to an interviewer.

step 3: build something small. a todo app with Spring Boot, a multithreaded file processor, a REST API with proper exception handling. interviewers ask "tell me about a project you've built" — have a real answer.

step 4: use weekday's interview question predictor to generate practice sets for the specific company and role you're applying to. the questions above are universal — the predictor tailors them to what that company actually asks.

start applying to java developer roles

preparation without applications is just procrastination with extra steps.

browse java developer jobs on weekday — every listing is from a verified company with an active hiring team. filter by experience level, remote/hybrid, and salary range to find roles that match where you are right now.

the best time to start applying is before you feel 100% ready. no one walks into an interview knowing everything — but the candidates who practise these 50 questions consistently outperform the ones who try to cram the night before.

Latest Articles

Browse Articles
Use AI to find jobs and apply

Stop manually filling job applications. Use AI to auto-apply to jobs

Browse jobs now