Ace your Java interview with 50+ questions on OOP, collections, multithreading, and JVM internals.
10 Questions
~30 min read
== compares references (memory addresses) for objects, values for primitives. equals() compares content/values and can be overridden. String "abc" == "abc" may be true (string pool) but new String("abc") == new String("abc") is false. Always use equals() for object comparison, and override it with hashCode() when needed.
HashMap is not thread-safe; concurrent modifications cause ConcurrentModificationException. ConcurrentHashMap is thread-safe using segment locking (Java 7) or CAS operations (Java 8+), allowing concurrent reads and limited concurrent writes. HashMap allows one null key; ConcurrentHashMap doesn't allow null keys/values. Use ConcurrentHashMap in multithreaded environments.
Abstract class: single inheritance, can have constructors, instance variables, any access modifiers. Interface: multiple inheritance, default/static methods (Java 8+), private methods (Java 9+), constants only. Use abstract class for shared code between related classes; interface for unrelated classes sharing behavior. Java 8+ interfaces can have default implementations.
Memory areas: Heap (objects), Stack (method calls, local variables), Metaspace (class metadata). GC automatically frees unreachable objects. Generational GC: Young (Eden, Survivor) for short-lived objects, Old for long-lived. GC types: Serial, Parallel, G1 (default in Java 9+), ZGC/Shenandoah (low latency). Tune with -Xmx, -Xms, GC flags.
volatile ensures visibility of changes across threads - writes are immediately visible to other threads. It prevents instruction reordering around the variable. Use for: flags, status indicators, single-writer scenarios. volatile doesn't provide atomicity - use synchronized or AtomicXxx for compound operations like count++.
synchronized: implicit lock, automatic release, block-structured. Lock (ReentrantLock): explicit lock/unlock, tryLock with timeout, interruptible, fair/unfair modes, Condition for multiple wait-sets. Use synchronized for simple cases; Lock for advanced scenarios like tryLock, timeout, or multiple conditions. Always unlock in finally block.
Streams enable functional-style operations on collections. Operations: Intermediate (filter, map, flatMap, sorted - lazy, return streams) and Terminal (collect, forEach, reduce, count - trigger processing). Features: lazy evaluation, parallel processing (parallelStream), no storage (doesn't modify source). Avoid side effects in stream operations.
Single Responsibility: one class, one reason to change. Open/Closed: open for extension, closed for modification (use interfaces). Liskov Substitution: subtypes must be substitutable for base types. Interface Segregation: many specific interfaces over one general. Dependency Inversion: depend on abstractions, not concretions (use DI). Spring Boot embraces these principles.
Java 17: sealed classes, pattern matching for switch (preview), records, text blocks. Java 21: virtual threads (Project Loom), pattern matching for switch (final), record patterns, sequenced collections, string templates (preview). Virtual threads enable millions of concurrent threads with simple blocking code, revolutionizing concurrent programming.
Checked exceptions (Exception): must catch or declare. Unchecked (RuntimeException): optional handling. Best practices: (1) Catch specific exceptions, (2) Don't swallow exceptions, (3) Use try-with-resources for AutoCloseable, (4) Throw early, catch late, (5) Create custom exceptions for business logic, (6) Log with context, (7) Don't use exceptions for flow control.