Ace your Java interview with 50+ questions on OOP, collections, multithreading, and JVM internals.
== 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.
Comparable (java.lang): natural ordering, implemented by the class itself (compareTo). Comparator (java.util): external ordering, separate class/lambda. Use Comparable for the default sort order. Use Comparator for: multiple sort orders, sorting classes you don't own, complex sort logic. Java 8: Comparator.comparing, thenComparing, reversed() for fluent chaining.
Serialization converts objects to byte streams for storage/transmission. Implement Serializable (marker interface). serialVersionUID prevents deserialization failures after class changes. transient fields are skipped. Custom logic via readObject/writeObject. Security: never deserialize untrusted data (remote code execution risk). Modern alternatives: JSON (Jackson), Protocol Buffers, Avro — prefer these over Java serialization.
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.
Iterable → Collection → List (ArrayList, LinkedList), Set (HashSet, TreeSet, LinkedHashSet), Queue (PriorityQueue, ArrayDeque). Map (not Collection): HashMap, TreeMap, LinkedHashMap, ConcurrentHashMap. ArrayList: O(1) random access, amortized O(1) add. LinkedList: O(1) add/remove at ends. HashSet: O(1) add/contains. TreeSet: O(log n), sorted. Choose based on access patterns.
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.
CompletableFuture is Java's async/reactive API. Key methods: supplyAsync (run async, return value), thenApply (transform result), thenCompose (chain futures), thenCombine (combine two futures), allOf (wait for all), anyOf (first completes), exceptionally (error handler), whenComplete (always runs). Specify executor for thread pool. Better than raw Futures for composing async operations.
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.
Creational: Singleton (one instance), Factory (create objects via factory method), Builder (step-by-step construction). Structural: Adapter (convert interface), Decorator (add behavior), Proxy (control access). Behavioral: Observer (pub-sub), Strategy (swap algorithms), Template Method (skeleton with overridable steps), Command (encapsulate requests). Spring uses many patterns internally.
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.
Optional<T> wraps a value that may or may not be present. Methods: isPresent/isEmpty, get (avoid — throws if empty), orElse, orElseGet, orElseThrow, map, flatMap, filter, ifPresent. Use as method return type when null is a valid absence (not for fields or params). Avoids NullPointerExceptions and makes nullability explicit in the API. Don't use Optional.get() without isPresent check.
Records (Java 16): immutable data carriers with auto-generated constructor, getters, equals, hashCode, toString. Syntax: record Point(int x, int y) {}. Cannot extend classes (implicitly final). Sealed classes (Java 17): restrict which classes can implement/extend them. Use permits to list allowed subclasses. Great with pattern matching and switch expressions for exhaustive handling.
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.
Checked exceptions (extends Exception): compiler requires handling or declaration in throws clause. Unchecked (extends RuntimeException): optional handling. Use checked for: recoverable conditions (file not found, network error). Use unchecked for: programming errors (NullPointerException, IllegalArgumentException). Modern Java trend: prefer unchecked to avoid noise. Spring uses unchecked exceptions throughout.
Spring Boot is an opinionated Spring framework that auto-configures components based on classpath dependencies. Key features: embedded server (no WAR deployment), starter dependencies (spring-boot-starter-web bundles Spring MVC + Tomcat), auto-configuration, Actuator for monitoring. Reduces boilerplate vs plain Spring. Use @SpringBootApplication, @RestController, @Service, @Repository annotations.
Practice with interactive quizzes and get instant feedback.
Start Free Practice