Skip to main content

Junior Java Interview Questions

Curated Junior-level Java interview questions for developers targeting junior positions. 40 questions available.

Last updated:

Java Interview Questions & Answers

Skip to Questions

Welcome to our comprehensive collection of Java interview questions and answers. This page contains expertly curated interview questions covering all aspects of Java, from fundamental concepts to advanced topics. Whether you're preparing for an entry-level position or a senior role, you'll find questions tailored to your experience level.

Our Java interview questions are designed to help you:

  • Understand core concepts and best practices in Java
  • Prepare for technical interviews at all experience levels
  • Master both theoretical knowledge and practical application
  • Build confidence for your next Java interview

Each question includes detailed answers and explanations to help you understand not just what the answer is, but why it's correct. We cover topics ranging from basic Java concepts to advanced scenarios that you might encounter in senior-level interviews.

Use the filters below to find questions by difficulty level (Entry, Junior, Mid, Senior, Expert) or focus specifically on code challenges. Each question is carefully crafted to reflect real-world interview scenarios you'll encounter at top tech companies, startups, and MNCs.

Questions

40 questions
Q1:

Explain the four pillars of OOP in Java.

Junior

Answer

Encapsulation: Hides internal state and exposes only required methods.
Inheritance: Allows classes to reuse fields and methods.
Polymorphism: Treat objects as instances of parent type.
Abstraction: Hides implementation using abstract classes or interfaces.
Quick Summary: Four OOP pillars in Java: Encapsulation - wrap data and methods in a class, use private fields with public getters/setters. Inheritance - subclass extends superclass to reuse and add behavior (extends keyword). Polymorphism - object behaves differently based on actual type (method overriding). Abstraction - hide complex implementation behind simple interfaces (abstract classes, interfaces).
Q2:

Difference between abstract classes and interfaces.

Junior

Answer

Abstract classes can have fields, constructors, and concrete methods.
Interfaces declare abstract methods (plus default/static methods).
Java allows single inheritance for classes but multiple inheritance through interfaces.
Quick Summary: Abstract class: can have state (instance fields), constructors, concrete methods. Used for "is-a" relationships with shared implementation. A class can extend only one. Interface: no state (only constants), no constructors, all methods abstract by default (Java 8+ adds default/static). A class can implement many interfaces. Use abstract class for template base, interface for multiple capabilities/contracts.
Q3:

What is method overriding vs method overloading?

Junior

Answer

Overloading: Same method name, different parameters; compile-time polymorphism.
Overriding: Subclass redefines parent method; runtime polymorphism.
Overriding requires inheritance.
Quick Summary: Overriding: subclass replaces a parent method with the same name, return type, and parameters. Resolved at runtime - actual object type determines which method runs. Enables polymorphism. Overloading: same class has multiple methods with the same name but different parameters. Resolved at compile time based on argument types. Both are called polymorphism but at different times.
Q4:

How does the super keyword work?

Junior

Answer

super refers to parent class.
Used to call parent constructors or parent methods.
Helps resolve naming conflicts between superclass and subclass.
Quick Summary: super refers to the parent class. super.method() calls the parent's version of an overridden method. super.field accesses a parent field hidden by a subclass field. super() in a constructor calls the parent constructor - must be the first statement. If you don't call super() explicitly, Java automatically inserts a call to the parent's no-arg constructor.
Q5:

Explain constructor chaining in Java.

Junior

Answer

Constructor chaining calls one constructor from another using this().
super() calls parent constructor.
Ensures proper initialization and code reuse.
Quick Summary: Constructor chaining calls one constructor from another in the same class using this(), or calls the parent constructor using super(). this() call must be the first line. Useful for avoiding code duplication when multiple constructors share setup logic. Chain to the most specific constructor: the others call it with default values.
Q6:

What are static blocks and static methods?

Junior

Answer

Static block executes once when class loads.
Static methods belong to class and can be accessed without object creation.
Quick Summary: Static blocks run once when the class is loaded by JVM, before any instance creation. Used for complex static field initialization. Static methods belong to the class (not instance), can be called without an object, but can only access static members. Instance initializer blocks run before each constructor. Static initialization order: parent class first, then child.
Q7:

Difference between final, finally, and finalize.

Junior

Answer

final: Makes variables constant, classes non-inheritable, methods non-overridable.
finally: Executes after try/catch always.
finalize: Called before garbage collection (deprecated).
Quick Summary: final keyword: makes variable constant, method un-overridable, class un-extendable. finally block: always executes after try-catch, used to release resources (even if exception is thrown - except System.exit()). finalize() method: called by GC before reclaiming object memory - deprecated, unpredictable timing, don't use for cleanup. Use try-with-resources instead of finalize for resource cleanup.
Q8:

Explain Java exception hierarchy.

Junior

Answer

Throwable ? Error and Exception.
Error: Serious issues (not handled usually).
Exception: Can be handled.
Checked exceptions must be declared; unchecked are runtime exceptions.
Quick Summary: Exception hierarchy: Throwable at top. Two branches: Error (serious system problems - OutOfMemoryError, StackOverflowError - don't try to catch these) and Exception. Exception branches into: checked exceptions (must handle - IOException, SQLException) and unchecked/RuntimeException (NullPointerException, IllegalArgumentException, ArrayIndexOutOfBoundsException). RuntimeExceptions typically indicate programming bugs.
Q9:

How is multiple inheritance handled in Java?

Junior

Answer

Java does not support multiple inheritance of classes.
Achieved using interfaces.
Prevents diamond problem.
Quick Summary: Java doesn't support multiple class inheritance (a class can extend only one class) to avoid the diamond problem (ambiguous method resolution). Multiple interface inheritance is allowed - a class can implement many interfaces. Java 8 adds default methods to interfaces, handled with explicit override if two interfaces have conflicting defaults. This design simplifies inheritance while keeping flexibility.
Q10:

Explain object cloning in Java.

Junior

Answer

Cloning creates object copies.
Uses Cloneable interface.
Shallow copy copies references; deep copy duplicates full object graph.
Quick Summary: Object cloning creates a copy of an object. Shallow clone (Object.clone()): copies primitive fields by value and reference fields by reference - both original and clone point to the same nested objects. Deep clone: recursively copies all nested objects too. Implement Cloneable interface and override clone(). Alternatively, use copy constructors or serialization for deep copying.
Q11:

What is the difference between == and equals()?

Junior

Answer

== compares references.
equals() compares content.
equals() should be overridden for custom comparison.
Quick Summary: For objects: == checks if two references point to the same memory location (same object instance). equals() checks logical equality based on the implementation. By default, equals() uses == (reference equality). Override equals() to define meaningful equality (e.g., two Users are equal if they have the same userId). Always override hashCode() when you override equals().
Q12:

Explain hashCode() and equals() contract.

Junior

Answer

If two objects are equal via equals(), their hashCode() must match.
Required for HashMap, HashSet, and other collections.
Quick Summary: The contract: objects that are equal (equals() returns true) must have the same hashCode. Objects with the same hashCode may or may not be equal (hash collision). If you break this contract, HashMap and HashSet won't work correctly - equal objects would be stored in different buckets and never found. Always override both together. Use Objects.hash() for a clean implementation.
Q13:

How does the instanceof keyword work?

Junior

Answer

Checks whether an object belongs to a specific class or subclass.
Useful for safe type casting.
Quick Summary: instanceof checks if an object is an instance of a class or implements an interface at runtime. Returns true if the object is the specified type or a subtype. Usage: if (obj instanceof String s) (Java 16 pattern matching - casts and binds in one step). Use before downcasting to avoid ClassCastException. instanceof on null always returns false.
Q14:

Explain Java packages and access control.

Junior

Answer

Packages group related classes.
Access modifiers: public, private, protected, default.
Improves modularity and avoids naming conflicts.
Quick Summary: Packages group related classes and provide namespace separation. Access control per package: public (everywhere), protected (package + subclasses), default/package-private (same package only), private (class only). Classes in the same package can access each other's package-private members without importing. Use packages to organize code and control what's part of your public API.
Q15:

Difference between deep copy and shallow copy.

Junior

Answer

Shallow copy copies references; objects shared.
Deep copy duplicates all objects; independent copies.
Quick Summary: Shallow copy: creates a new object but copies reference fields by reference - the copy and original share the same nested objects. Modifying a nested object through either copy affects both. Deep copy: recursively copies all objects - completely independent copy. Shallow copy is fast but risky for mutable nested objects. Use serialization or copy constructors for deep copies.
Q16:

Explain Java memory model.

Junior

Answer

Memory divided into Heap (objects) and Stack (references & primitives).
Method area holds class data.
GC manages heap memory.
Quick Summary: Java Memory Model (JMM) defines how threads interact via shared memory. Key guarantees: volatile fields are always read from main memory (not thread-local cache). synchronized ensures visibility and atomicity - changes made inside synchronized block are visible to all threads after they acquire the same lock. JMM prevents data races when you use proper synchronization.
Q17:

How does garbage collection work in Java?

Junior

Answer

GC removes unreachable objects.
Algorithms include Mark-and-Sweep and Generational GC.
Prevents memory leaks automatically.
Quick Summary: Java GC works in generations. Eden (new objects), Survivor spaces (survived one GC), and Old Gen (long-lived objects). Minor GC: collects Eden and Survivor spaces - fast. Major/Full GC: collects Old Gen - slower, causes pause. GC algorithms: Serial (single-threaded), Parallel (throughput), G1 (balanced), ZGC/Shenandoah (low latency - sub-millisecond pauses). JVM automatically manages when GC runs.
Q18:

How do Java Strings differ from StringBuilder and StringBuffer?

Junior

Answer

String is immutable.
StringBuilder is mutable and faster but not thread-safe.
StringBuffer is thread-safe (synchronized).
Quick Summary: String is immutable - every "modification" creates a new String object. StringBuilder is mutable and fast but not thread-safe - use in single-threaded string building. StringBuffer is mutable and thread-safe (synchronized) but slower. For string concatenation in loops, always use StringBuilder to avoid creating many intermediate String objects. Java 9+ optimizes simple concatenations automatically.
Q19:

Explain Java enums.

Junior

Answer

Enums represent fixed constants.
Can have fields, constructors, and methods.
Improve type safety and readability.
Quick Summary: Enums define a fixed set of named constants. Better than integer constants: type-safe (compiler catches wrong values), can have methods and fields, work with switch statements, implement interfaces. Each enum value is a singleton instance. Enum has built-in methods: name(), ordinal(), values(), valueOf(). EnumSet and EnumMap are highly efficient collections for enums.
Q20:

What are Java annotations?

Junior

Answer

Annotations provide metadata for code.
Affect compilation or runtime behavior.
Examples: @Override, @Deprecated, @SuppressWarnings.
Quick Summary: Annotations are metadata attached to code elements (classes, methods, fields). Built-in: @Override (verify you're overriding), @Deprecated (mark as obsolete), @SuppressWarnings. Create custom annotations with @interface. Frameworks use annotations heavily for configuration (Spring @Component, @Autowired; JPA @Entity, @Column). Annotations are processed at compile time (retention COMPILE) or runtime (retention RUNTIME via reflection).
Q21:

What are the main interfaces of the Java Collections Framework?

Junior

Answer

List: Ordered collection allowing duplicates.
Set: No duplicates, unordered or sorted.
Map: Key-value pairs with unique keys.
Queue/Deque: FIFO or double-ended structures.
Iterable: Base interface enabling iteration.
Quick Summary: Main collection interfaces: Collection (root), List (ordered, duplicates allowed - ArrayList, LinkedList), Set (no duplicates - HashSet, TreeSet, LinkedHashSet), Map (key-value - HashMap, TreeMap, LinkedHashMap), Queue (FIFO - LinkedList, PriorityQueue), Deque (double-ended queue). Program to interfaces (List not ArrayList) for flexibility to swap implementations.
Q22:

What is the difference between ArrayList and LinkedList?

Junior

Answer

ArrayList: Backed by array; fast random access; slower insert/delete in middle.
LinkedList: Doubly linked nodes; fast insert/delete; slow random access.
Quick Summary: ArrayList: backed by an array, O(1) random access by index, O(n) insertion/deletion in the middle (elements shift), fast iteration. LinkedList: doubly-linked list, O(1) insertion/deletion at head/tail, O(n) random access, more memory (stores pointers). Choose ArrayList for most cases. Use LinkedList only when you frequently add/remove from both ends.
Q23:

What is the difference between HashMap, TreeMap, and LinkedHashMap?

Junior

Answer

HashMap: Unordered, fast via hashing.
TreeMap: Sorted keys, uses Red-Black tree.
LinkedHashMap: Maintains insertion order.
Quick Summary: HashMap: O(1) average get/put, no ordering, allows one null key. TreeMap: sorted by key (natural order or Comparator), O(log n) operations, no null keys. LinkedHashMap: maintains insertion order (or access order for LRU cache), O(1) operations. Use HashMap for performance, TreeMap when you need sorted keys, LinkedHashMap when insertion order matters.
Q24:

Explain the difference between List, Set, and Map.

Junior

Answer

List: Ordered, allows duplicates.
Set: No duplicates.
Map: Key-value pairs with unique keys.
Quick Summary: List: ordered sequence, allows duplicates, access by index. Set: unordered (HashSet) or sorted (TreeSet), no duplicates - add() returns false if duplicate. Map: key-value pairs, keys are unique (Set semantics for keys), values can duplicate. Use List for ordered data with duplicates, Set for uniqueness enforcement, Map for key-based lookups.
Q25:

What are Java generics and why use them?

Junior

Answer

Generics provide compile-time type safety.
Enable reusable classes and methods.
Reduce casting and runtime errors.
Quick Summary: Generics add compile-time type safety to collections and algorithms. Without generics: List stores Object, need casting, ClassCastException possible at runtime. With generics: List only holds Strings, no casting needed, wrong types caught at compile time. Write generic methods and classes with type parameters: , , . Type erasure means generics exist only at compile time.
Q26:

How do wildcards in generics work?

Junior

Answer

? extends T: Accepts T or subclasses.
? super T: Accepts T or superclasses.
Used for flexible yet safe type handling.
Quick Summary: Wildcards represent unknown types in generics. ? (unbounded): accepts any type - useful for reading. ? extends T (upper bounded): accepts T or subtypes - can read as T, can't write. ? super T (lower bounded): accepts T or supertypes - can write T, reading gives Object. Remember PECS: Producer Extends (read-only), Consumer Super (write-only).
Q27:

What is the difference between Comparable and Comparator?

Junior

Answer

Comparable: Natural ordering defined in class.
Comparator: External custom sorting logic.
Both used during sorting.
Quick Summary: Comparable: implemented by the class itself (implements Comparable), defines "natural ordering" via compareTo(). Used by sort() and sorted collections automatically. Comparator: external comparison logic - doesn't modify the class. Pass to sort(), TreeMap, sorted collections. Comparator is more flexible - create multiple comparison strategies. Java 8: Comparator.comparing(Person::getAge).thenComparing(Person::getName).
Q28:

What is the difference between fail-fast and fail-safe iterators?

Junior

Answer

Fail-fast: Throws ConcurrentModificationException.
Fail-safe: Works on copy; allows modification.
Quick Summary: Fail-fast iterators (ArrayList, HashMap) throw ConcurrentModificationException if the collection is modified during iteration (checks modCount). This is to prevent unpredictable behavior, not thread safety. Fail-safe iterators (CopyOnWriteArrayList, ConcurrentHashMap) work on a snapshot of the collection - modifications during iteration are safe but not reflected in the current iteration.
Q29:

Explain Java multithreading.

Junior

Answer

Thread is independent execution path.
Runnable defines thread task.
Lifecycle: New ? Runnable ? Running ? Waiting/Blocked ? Terminated.
Quick Summary: Multithreading allows concurrent execution of multiple threads within one process. Threads share the same memory (heap), unlike processes. Benefits: better CPU utilization, responsive UIs, parallel processing. Challenges: race conditions, deadlocks, visibility issues. Java provides built-in threading support: Thread class, Runnable interface, synchronized keyword, and java.util.concurrent package.
Q30:

How do you create and start a thread?

Junior

Answer

Extend Thread or implement Runnable.
Call start() to run thread asynchronously.
Thread pools manage multiple threads efficiently.
Quick Summary: Two ways to create threads: extend Thread class and override run(), or implement Runnable interface and pass to Thread constructor. Prefer Runnable - it doesn't waste your single inheritance. Java 8+: use lambdas: new Thread(() -> doWork()).start(). Better yet, use ExecutorService to manage thread pools instead of creating threads manually.
Q31:

What are synchronized methods and blocks?

Junior

Answer

Ensure exclusive access to shared resources.
Prevent race conditions.
Synchronized block gives finer locking control.
Quick Summary: synchronized prevents concurrent access to a code block or method. Synchronized method: only one thread can execute it on the same object at a time. Synchronized block: more fine-grained, lock on any object. Guarantees mutual exclusion and memory visibility (changes in synchronized block visible to all threads after they acquire same lock). Downside: performance overhead if contended.
Q32:

Explain inter-thread communication.

Junior

Answer

Uses wait(), notify(), notifyAll().
Helps coordinate producer-consumer tasks.
Must be inside synchronized blocks.
Quick Summary: Inter-thread communication uses wait(), notify(), notifyAll() on a shared object. wait() releases the lock and puts the thread to sleep until notified. notify() wakes one waiting thread. notifyAll() wakes all. Must be called within a synchronized block on the same object. Used for producer-consumer pattern. Modern code uses BlockingQueue instead - much simpler and less error-prone.
Q33:

What are deadlocks and how do you prevent them?

Junior

Answer

Deadlock: Threads wait forever for each other's locks.
Prevent by avoiding nested locks, ordering locks consistently, or using timeouts.
Quick Summary: Deadlock: thread A holds lock X and waits for lock Y. Thread B holds lock Y and waits for lock X. Both wait forever. Prevention: always acquire locks in the same order across all threads. Alternatively: use tryLock() with timeout (ReentrantLock), use lock-free data structures, minimize lock scope, or avoid nested locks entirely. Use thread dumps to diagnose deadlocks in production.
Q34:

What is the difference between volatile, synchronized, and atomic variables?

Junior

Answer

volatile: Ensures visibility of changes.
synchronized: Ensures mutual exclusion.
Atomic variables: Lock-free thread-safe operations.
Quick Summary: volatile: ensures a variable is always read from main memory (not CPU cache) - fixes visibility, not atomicity. Reads/writes are not atomic for long/double. synchronized: mutual exclusion + visibility - all operations inside are atomic. Atomic (AtomicInteger etc.): lock-free atomic operations using CAS (compare-and-swap) - faster than synchronized for simple counters and flags.
Q35:

Explain thread priorities and scheduling.

Junior

Answer

Threads have priorities (1–10).
Higher priority gets more CPU time but no guaranteed order.
Actual scheduling depends on OS and JVM.
Quick Summary: Thread priorities (MIN=1, NORM=5, MAX=10) hint to the OS scheduler which threads to prefer. Not guaranteed - OS is free to ignore hints. Starvation risk: high-priority threads always running can prevent low-priority threads from running. In practice, thread priorities are unreliable across platforms. Better to use proper synchronization and design rather than relying on priorities.
Q36:

Explain thread pools in Java.

Junior

Answer

Thread pools reuse worker threads.
Reduce overhead of thread creation.
Executors provide fixed, cached, and scheduled pools.
Quick Summary: Thread pool reuses a fixed number of threads to execute many tasks. Creating a new thread for every task is expensive. ExecutorService manages a pool: submit tasks, threads are reused. Common pools: Executors.newFixedThreadPool(n), newCachedThreadPool(), newSingleThreadExecutor(). Use ThreadPoolExecutor for fine-grained control. Always shut down the executor when done.
Q37:

What is the difference between Callable and Runnable?

Junior

Answer

Runnable: No return value; no checked exceptions.
Callable: Returns value and may throw exceptions.
Used with ExecutorService to get Future results.
Quick Summary: Runnable: run() method, no return value, can't throw checked exceptions. Callable: call() method, returns a value (Future), can throw checked exceptions. Use Callable when you need the result of an async computation. Submit to ExecutorService: Future future = executor.submit(callable); result = future.get() (blocks until done).
Q38:

Explain Java concurrent collections.

Junior

Answer

Thread-safe optimized collections.
Examples: ConcurrentHashMap, CopyOnWriteArrayList.
Avoids manual synchronization.
Quick Summary: java.util.concurrent provides thread-safe collections: ConcurrentHashMap (segmented locking, much better than synchronized HashMap), CopyOnWriteArrayList (thread-safe for read-heavy scenarios, writes copy the entire array), BlockingQueue (LinkedBlockingQueue, ArrayBlockingQueue - blocks producer/consumer when full/empty), ConcurrentLinkedQueue (lock-free). Choose based on read/write ratio and blocking needs.
Q39:

Explain producer-consumer problem in Java.

Junior

Answer

Producer adds data; consumer removes it.
Requires thread coordination and shared buffers.
Uses wait(), notify(), or BlockingQueue.
Quick Summary: Producer-consumer: producer puts items in a shared buffer, consumer takes them. Without coordination: producer overwhelms buffer (full) or consumer reads empty buffer. Solution: BlockingQueue - put() blocks if full, take() blocks if empty, no explicit wait/notify needed. ArrayBlockingQueue (bounded, prevents OOM) or LinkedBlockingQueue (unbounded). Much simpler than manual wait/notify.
Q40:

How do you handle thread safety in Java?

Junior

Answer

Use synchronization, locks, atomic variables, and concurrent collections.
Avoid shared mutable state.
Design carefully for safe concurrent execution.
Quick Summary: Thread safety means code works correctly when accessed by multiple threads concurrently. Strategies: immutability (immutable objects need no synchronization), synchronized methods/blocks, java.util.concurrent atomic classes, concurrent collections, ThreadLocal (each thread has its own copy). The best code is stateless or uses immutable shared state - requires no synchronization at all.

Curated Sets for Java

No curated sets yet. Group questions into collections from the admin panel to feature them here.

Ready to level up? Start Practice