How to use this revision
This page condenses every question from the 5 to 8 Years course in these areas into a single line: the question, linked to its full answer, and the one-sentence answer you should be able to give instantly. Read down the list and answer each question aloud before reading the line. Wherever you hesitate, follow the link and revise the full answer — interviewers at your level expect these basics to be fluent, and they often open with them before going deeper.
Advanced Core Java
Advanced OOP & Design Scenarios — Interview Questions — open the lesson
- Scenario: certain data must stay constant and tamper-proof for its whole lifecycle. How do you design for that? — Model it as immutable value objects:
final classes with private final fields, and no setters (or a record); Defensive copies of mutable inputs and outputs (List.copyOf, and copying arrays and Dates); Validation in the constructor, so an invalid state can never exist.
- Which pattern would you use for an API that creates complex configuration objects? — The Builder pattern, typically a static nested builder on an immutable configuration class. Callers set only what they need, with named, fluent methods.
- Refactor a
Vehicle class that has both fly() and sail(). How do IS-A and HAS-A relationships help, and how does this relate to the single responsibility principle? — A Vehicle with fly() and sail() forces cars to carry methods they can't honour, violating SRP, LSP and ISP. Refactor to: Capabilities as small interfaces (Flyable, Sailable, Drivable), which classes implement: an IS-A relationship with a capability; Shared…
- Why use a builder instead of constructors? — Readability: named steps instead of positional arguments.
new Pizza(12, true, false, true) is unreadable; Optional parameters without telescoping constructors.; Immutability with validation at the end.; Consistency: no half-constructed object is ever visible; …
- How can a singleton be broken, and how do you guarantee a single instance? — A classic singleton can be broken by: Reflection: calling the private constructor with
setAccessible(true); Serialization: deserializing creates a new instance; Cloning.; Multiple class loaders: one instance per loader; …
- What are deep and shallow cloning, and how is
Cloneable used? — A shallow copy duplicates the top-level object, but shares the referenced objects. Mutating a nested list through the copy affects the original.
- How do you make
equals() compare user profiles by their unique identifier? — Base both equals and hashCode on the stable identifier. Handle this == o, null and the type check, and keep the behaviour consistent with how profiles are used in collections.
- How would you use polymorphism to model different animal behaviours? — Define the behaviour in a supertype (an interface or abstract class), and let each subtype override it. Client code depends only on the supertype, and dynamic dispatch picks the right behaviour at runtime.
- Design a class that can't be extended, and whose core methods can't be overridden. — Declare the class
final. Its methods then can't be overridden at all, because no subclass can exist. If the class must stay extensible but some core methods must not change, keep the class non-final, and mark those methods final (the template-method style). Alternatives:…
- How do you override
equals() for custom equality conditions? — Follow the contract (reflexive, symmetric, transitive, consistent, x.equals(null) == false): Check identity; Check the type (instanceof pattern, or getClass()); Cast; Compare the significant fields with Objects.equals (null-safe), or compareTo == 0 where the scale…
- It's critical to have only one configuration-manager instance. How would you implement it? — In plain Java, use an enum singleton, or the initialization-on-demand holder idiom. Both are thread-safe without explicit locking.
- Implement a singleton configuration manager, with thread safety. (Same scenario, focusing on the threading) — The lazy
if (instance == null) version is not thread-safe. The safe options: Eager initialisation; The holder idiom (Bill Pugh), which relies on the JVM's thread-safe class initialisation; Double-checked locking with a volatile field.; An enum..
- Describe a scenario where custom exceptions beat built-in ones. — When callers must react differently to a specific business failure, or when you need structured context. For example, in payments:
InsufficientFundsException(accountId, requested, available) lets the API return a 422 with a clear error code, lets the UI prompt for a top-up,…
- How would you structure packages for maintainability in a complex project? — Package by feature (or bounded context) first, and by layer only within a feature:
com.acme.orders.{api, domain, persistence}, com.acme.payments.{…}.
Advanced Concurrency, Collections & Memory — Interview Questions — open the lesson
- How do you manage access to a critical section that touches a shared resource? — First try to eliminate the sharing: confinement, immutability, or partitioning by key. If you can't: Protect all accesses to the shared state with one lock. Use
synchronized, or a ReentrantLock when you need timeouts, interruptibility or fairness; Keep the critical…
- A high-performance trading application frequently updates and sorts prices. Which collections would you use? — You need sorted, concurrent access to price levels. A plain
TreeMap/TreeSet keeps order, with O(log n) operations, but it isn't thread-safe. The options: ConcurrentSkipListMap<BigDecimal or long, PriceLevel>: sorted, concurrent, lock-free reads, O(log n). Its…
- What causes
ConcurrentModificationException, and how do you prevent it? — Fail-fast iterators track a modCount. If the collection is structurally modified during iteration, other than through the iterator itself, the next next() throws.
- What is a
ReentrantLock, and how does it differ from synchronized? — Both are reentrant mutual-exclusion locks with the same memory semantics. ReentrantLock adds: tryLock (with a timeout); lockInterruptibly; fairness; multiple Conditions; …
- You need to process tasks concurrently. Which Java constructs ensure efficient and safe execution? — Execution: an
ExecutorService, either a bounded ThreadPoolExecutor (sized for CPU-bound or I/O-bound work, with a bounded queue and a rejection policy) or virtual threads (newVirtualThreadPerTaskExecutor) for blocking I/O; Composition: CompletableFuture…
- Why is immutability so valuable in multi-threaded applications? — An immutable object has no state changes, so there are no races, no need for locks, and no torn reads. With
final fields and safe construction, the JMM guarantees every thread sees it fully initialised.
- How do you ensure atomicity without
synchronized? — Atomic classes (AtomicInteger, AtomicLong, AtomicReference), using CAS (compare-and-swap) loops: incrementAndGet, compareAndSet, updateAndGet, accumulateAndGet; LongAdder/LongAccumulator, for highly contended counters; ConcurrentHashMap.compute and…
- The logs show
OutOfMemoryError. How do you investigate? — Read the exact message: Java heap space, or GC overhead limit exceeded: a heap problem; Get evidence: a heap dump (have -XX:+HeapDumpOnOutOfMemoryError configured in advance), GC logs, JFR recordings, and memory metrics over time; Analyse the dump in Eclipse MAT: the…
- What are strong, weak, soft and phantom references, and what role do they play in GC? — Strong: normal references. The object can't be collected while one exists; Soft (
SoftReference): cleared at the GC's discretion, before an OutOfMemoryError. They were historically used for memory-sensitive caches; Weak (WeakReference): cleared at the next GC, once no…
- What is Metaspace, and how does it differ from PermGen? — PermGen (up to Java 7) was a fixed-size region of the Java heap holding class metadata and, before Java 7, interned strings.
- Write the producer–consumer problem with
wait and notify. — Use a bounded buffer guarded by one monitor: wait in a loop while the condition is false; use notifyAll(), because producers and consumers share the same wait set; never sleep while holding the lock; handle interruption properly.
- How does the Executor framework handle task interruption, and what are the best practices? — Executors interrupt worker threads on
shutdownNow(), and on Future.cancel(true). Interruption is cooperative: the task must notice it (blocking calls throw InterruptedException, or it checks Thread.currentThread().isInterrupted()), then stop. Best practices: Check the…
Modern Java Language Features & Annotations — Interview Questions — open the lesson
- Why are Java 8 lambdas considered such a big change? — Lambdas made behaviour a first-class value. That changed how Java libraries are designed, not just how code is written: Higher-order APIs became practical: streams,
CompletableFuture, Comparator.comparing, Map.computeIfAbsent, and Spring's callback-style APIs; A…
- How do generics maintain type safety and reduce duplication? — Generics move type checks to compile time. A
List<Order> can't receive a Customer, and reading from it needs no cast, so a whole class of runtime ClassCastExceptions disappears.
- How do streams and lambdas affect performance and maintainability? — Maintainability: pipelines state the intent (filter, map, group) declaratively, compose well, and keep side effects out of view.
- How do default methods affect the design and evolution of Java applications? — They make interface evolution possible. You can add methods to published interfaces without breaking implementers (as the JDK did with
Collection.stream()); They enable mixin-like behaviour composition (Comparator.reversed, Predicate.and); They reduce the need for…
- After Java 8, how do you choose between an interface and an abstract class? — Default methods blurred the line, but the key difference remains state and construction.
- What is
@Retention for? — It declares how long an annotation survives: SOURCE: discarded by the compiler. Used for compile-time tools: @Override, Lombok, annotation processors; CLASS (the default): kept in the bytecode, but not visible through reflection. Used by bytecode tools; RUNTIME:…
- What does
@Target do? — It restricts where an annotation may be used: TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE (any use of a type, as in List<@NonNull String>), MODULE and RECORD_COMPONENT.
- Two interfaces have the same default method with different bodies. How do you resolve this diamond problem? — The implementing class must override the method. Otherwise it's a compile error. Inside the override, delegate explicitly with
InterfaceName.super.method(), combine both, or write new behaviour.
- What's the significance of the generic declaration on the
Enum class? — It's declared as public abstract class Enum<E extends Enum<E>>, a recursive (F-bounded) generic. Each enum Color compiles to final class Color extends Enum<Color>, so methods inherited from Enum are typed to the concrete enum: compareTo(E o) only accepts the same…
- What is a record, and when do you use it? — A record (a preview in Java 14–15, final in Java 16) is a transparent, shallowly immutable data carrier. You declare its components, and the compiler generates the private final fields, the canonical constructor, the accessors (
name(), not getName()), and equals,…
- What is a sealed class, and when do you use it? — A sealed class or interface (a preview in Java 15–16, final in Java 17) restricts which classes may extend or implement it, with a
permits clause.
Class Loading, Reflection, Serialization & Idioms — Interview Questions — open the lesson
- Scenario: serialize a complex object graph with nested objects and transient fields, with integrity and security. How? — Prefer an explicit, schema-based format over Java serialization: JSON with Jackson and DTOs, or Protobuf or Avro. You control exactly what's written, the schema can evolve, and you avoid deserialization gadget attacks; Exclude sensitive or derived fields:
transient, or…
- How does Java enforce security restrictions on code loaded over the network? — Historically (applets, RMI), the Security Manager, with a policy file, sandboxed untrusted code through permission checks on file, network and reflection access.
- What's the difference between the Strategy and State patterns? — Both delegate behaviour to an interchangeable object, but they differ in who chooses it and why: Strategy: the client picks one algorithm from a family: a pricing rule, a sort order, a compression codec. The strategies are usually unaware of each other, and the choice is…
- How would you apply the Observer pattern in an event-driven application? — Within one service: publish domain events (
OrderPlaced), and let independent listeners react (@EventListener, or @TransactionalEventListener + @Async). The publisher doesn't know its subscribers; Across services: the same idea over a broker (Kafka), which is pub/sub.
- How would you load plugins dynamically at runtime with class loaders? — Define a plugin API (an interface) in a shared JAR; Load each plugin JAR in its own
URLClassLoader, with the application's API loader as the parent, for isolation; Discover the implementations with ServiceLoader (entries in META-INF/services), instead of hard-coded…
- What's the difference between
Class.forName() and ClassLoader.loadClass()? — Class.forName(name) loads, links and initialises the class (static initialisers run), using the caller's class loader by default. Class.forName(name, initialize, loader) gives you control over both; loader.loadClass(name) loads the class, but doesn't initialise it.…
- What types of class loader does Java have? — Bootstrap: native. It loads the core modules (
java.base…), and appears as null; Platform: other Java SE and JDK modules. It replaced the Extension loader.; Application (system): your class path and module path.
ClassA and ClassB each need the other in their constructors. How do you resolve the circular dependency? — First, treat it as a design smell. Two classes that can't exist without each other usually share a responsibility that belongs in a third class, or one of them only needs to notify the other (use events or callbacks). If a bidirectional link really is required: Construct one…
- How do you implement an LRU cache? (The question says "with a
LinkedList".) — A plain LinkedList makes both lookup and move-to-front O(n). The correct O(1) design is a HashMap from key to node, plus a doubly linked list of nodes: the map finds the node, and the list moves it to the head or evicts the tail in O(1).
- When does a
LinkedHashSet outperform a TreeSet, and when is it the other way round? — LinkedHashSet (a hash table plus a linked list) gives O(1) add, remove and contains, with insertion-order iteration. It wins for fast membership checks and "unique, in arrival order"; TreeSet (a red-black tree) gives O(log n) operations with sorted order, plus…
- What happens if you change a
final field with reflection? — For instance final fields of ordinary classes, field.setAccessible(true) followed by set(...) succeeds, but the result is unreliable. The JIT may have constant-folded or cached the old value, and other threads may never see the change, because the final-field memory…
- How do you implement Singleton and Strategy with an enum? — Singleton: a single-constant enum,
INSTANCE. It's thread-safe (initialised with the class), serialization-safe, and reflection-proof; Strategy: each constant overrides an abstract method, or holds a lambda. You get a closed, type-safe set of strategies that are easy to…
- What are the differences between
Externalizable and Serializable? — Compared side by side in the full answer (table) — know each row.
- What coding standards do you follow as a Java developer? — Style: a team-wide formatter (Spotless with google-java-format or Palantir), enforced in CI, so style never comes up in review; Naming and structure: intention-revealing names, small focused methods and classes, package-by-feature, and minimal visibility; Correctness:…
Java Design Patterns in Depth
Design Patterns Overview & Singleton — Interview Questions — open the lesson
- What are the creational patterns? — Creational patterns control how objects are created, decoupling clients from concrete classes: Singleton: exactly one instance, with a global access point; Factory Method: a method (often overridden or parameterised) decides which concrete class to create; Abstract Factory:…
- What are the structural patterns? — Structural patterns deal with how classes and objects are composed: Adapter: converts one interface into another that the client expects; Bridge: separates an abstraction from its implementation, so both can vary independently; Composite: treats individual objects and trees…
- What are the behavioural patterns? — Behavioural patterns deal with communication and the division of responsibility between objects: Chain of Responsibility: pass a request along handlers until one of them handles it; Command: encapsulate a request as an object (queueing, undo, logging); Observer: notify…
- What is the Singleton pattern, and why is it useful? — Singleton guarantees that a class has exactly one instance (per class loader), and provides a well-known access point.
- How do you implement a thread-safe singleton? — The three recommended forms —
public enum MetricsRegistry { INSTANCE; public void inc(String name) { /* … */ } } public final class Config {
- What is lazy initialisation in a singleton? — Creating the instance on first use, rather than when the class loads. It's worth it when construction is expensive (loading large data, opening resources), and the singleton might not be needed at all.
- How do you stop a singleton being broken by serialization or reflection? — Serialization: implement
readResolve() returning the existing instance, and make the instance fields transient. Deserialization then discards the new copy; Reflection: a private constructor alone does not stop reflection, because setAccessible(true) bypasses it. Add a…
- When should you avoid the Singleton pattern? — Most of the time, in application code: Hidden dependencies: callers reach for
X.getInstance() instead of declaring what they need; Global mutable state: order-dependent bugs and test pollution (state leaks between tests, and it's hard to mock); Concurrency hotspots: one…
Factory & Abstract Factory Patterns — Interview Questions — open the lesson
- What is the Factory pattern, and why is it used so often? — A factory encapsulates object creation behind a method, so callers ask for an object by what they need (a type, a key, a configuration), not by which concrete class implements it.
- How does the Factory pattern differ from Abstract Factory? — A factory method creates one product, choosing the concrete class; An Abstract Factory is an interface with several creation methods for a family of related products that must be used together, such as a Windows button, checkbox and menu, or an AWS storage, queue and secrets…
- What is the Factory Method, in Java terms? — A creator class declares an abstract (or overridable) method that returns a product interface. Subclasses override it to decide the concrete product, while the creator's other methods use the product without knowing its class.
- What are the advantages and disadvantages of factories? — Advantages: Decouples callers from concrete classes (depend on abstractions); Disadvantages: Extra indirection and more classes.
- Give an example where a factory really simplifies object creation. — Notification channels. The caller says "notify via SMS", and the factory returns the right sender, already configured with credentials, retry policy and rate limits.
- What is Abstract Factory, and how does it differ from Factory? — Abstract Factory provides an interface for creating families of related objects without naming their concrete classes.
- Describe a real-world scenario for Abstract Factory. — Multi-cloud infrastructure clients: a
CloudFactory with storage(), queue() and secrets(). AwsCloudFactory returns S3/SQS/Secrets Manager adapters, and AzureCloudFactory returns Blob Storage, Service Bus and Key Vault adapters. A deployment picks one factory, and…
- How do you implement Abstract Factory in Java? — Define product interfaces; Define a factory interface, with one creation method per product; Implement one concrete factory per family; Inject the chosen factory, through configuration or a profile.
- What are the advantages of Abstract Factory? — Consistency across related products: no mixing of families; Isolation of concrete classes: clients depend only on interfaces; Easy family swapping, in one place (configuration); Testability, with a fake family for tests (an in-memory storage and queue); …
- How does Abstract Factory support scalability in large systems? — It scales the codebase and the organisation, rather than runtime throughput: New families (a new cloud, region, tenant tier or partner integration) are added as new classes, without touching existing ones; Teams can own separate families independently; Environment differences…
Builder & Prototype Patterns — Interview Questions — open the lesson
- What is the Builder pattern's purpose, and when do you use it? — Builder separates the construction of a complex object from its final representation. You set parts step by step, through named methods, then call
build() to get a complete, usually immutable, object. Use it when: the object has many parameters, especially optional ones;…
- What is the Builder pattern, and when would you use it? (Implementation view) — The idiomatic Java form is a static nested
Builder with fluent setters, and a private constructor on the product that takes the builder — public final class HttpRequestSpec { private final URI uri; private final String method; private final…
- How does Builder differ from Factory? — A factory chooses which object (or class) to create, usually in one call. A builder controls how one complex object is assembled, over many calls, with optional parts and final validation.
- What are the benefits of Builder for complex objects? — Readable, self-documenting construction.; No telescoping constructors.; Immutable products, without a giant constructor; A consistent state: the object is only exposed after validation; …
- How does method chaining work in a builder? — Each setter mutates the builder and returns
this, so calls can be chained into a fluent expression. build() ends the chain, and returns the product.
- Give an example where a builder is preferable to multiple constructors. — A server or computer configuration: CPU, RAM, storage type and size, GPU, OS and network options, most of them optional.
- What is the Prototype pattern, and how does it work? — Prototype creates new objects by copying a pre-configured instance (the prototype), instead of building from scratch.
- What's the difference between shallow and deep cloning in Prototype? — A shallow copy duplicates only the top-level fields. Referenced objects are shared, so mutating a nested list through the copy changes the prototype.
- How do you implement the Prototype pattern in Java? — Prefer a copy constructor, or a
copy() method you control, over Cloneable/clone() — public final class ReportTemplate { private final String title;
- When would you use Prototype instead of creating a new instance? — When: Creation is expensive, and the result can be reused as a template: parsed templates, objects built from database or remote data, precomputed structures; You need many similar objects, with small variations; The concrete class is only known at runtime (a registry of…
- What are the common pitfalls of Prototype? — Accidental sharing through shallow copies: nested mutable state changes in both objects; Deep copies that are wrong, or incomplete, as the class evolves (new fields forgotten in
copy()); Cycles in the object graph, where naive deep copies recurse forever; Copying identity…
Adapter & Bridge Patterns — Interview Questions — open the lesson
- What is the Adapter pattern for? — An adapter converts the interface of an existing class into the interface a client expects, so incompatible components can work together without changing either one. Typical uses: integrating third-party SDKs; wrapping legacy code; migrating between APIs; normalising several…
- What is the Adapter pattern? (The section introduction: its structure) — It has four participants: the Target: the interface the client uses; the Adaptee: the existing class, with an incompatible API; the Adapter: implements Target, and translates calls to the Adaptee; the Client: knows only Target.
- What is the Adapter pattern, and when would you use it? — Use it when you can't or shouldn't change either side: third-party or legacy code, or generated clients. And you want your domain code to depend on your own abstraction.
- How does Adapter differ from Decorator? — An Adapter changes the interface, making X look like Y, while keeping the behaviour. A Decorator keeps the same interface, and adds behaviour (logging, caching, retries, metrics).
- Give a Java example of the Adapter pattern. — SLF4J bridges are adapters:
jul-to-slf4j and log4j-over-slf4j let code written for one logging API emit through SLF4J and Logback.
- What are class adapters and object adapters, and how do they differ? — An object adapter (composition) holds a reference to the adaptee, and implements the target interface. It works with the adaptee and its subclasses, can adapt several adaptees, and is the usual choice in Java; A class adapter (inheritance) extends the adaptee class and…
- Why is Adapter useful when integrating third-party libraries? — Isolation: vendor types and exceptions stay inside the adapter, so the domain depends on your interfaces; Replaceability: switching providers means writing a new adapter; Testability: mock or fake your interface, not the SDK; Upgrade safety: SDK breaking changes are contained…
- What is the Bridge pattern, and how does it decouple abstraction from implementation? — Bridge splits a design into two independent hierarchies: an abstraction: the high-level API, such as
Notification → UrgentNotification, DigestNotification; an implementor: the low-level operations, such as MessageSender → EmailSender, SmsSender, PushSender.
- What's the difference between Bridge and Adapter? — Intent and timing. Bridge is designed up front, so that two dimensions can vary independently: it prevents a class explosion.
- How would you implement the Bridge pattern in Java? — ```java public interface MessageSender { void send(String to, String body); } // the implementor final class EmailSender implements MessageSender { public void send(String to, String b) { /* SMTP */ } } final class SmsSender implements MessageSender { public void send(String…
- In what scenarios would you use Bridge? — Whenever two dimensions of variation would otherwise multiply subclasses: shapes × rendering APIs; notifications × channels; reports × output formats (PDF, CSV, Excel); persistence abstractions × storage engines; …
- What are the key benefits of Bridge in large systems? — No combinatorial class explosion.; Independent evolution: platform or vendor teams extend implementations while product teams extend abstractions; Runtime flexibility: swap implementations through configuration; Better testability: fake implementors; …
Composite & Decorator Patterns — Interview Questions — open the lesson
- What is the Composite pattern's purpose? — Composite lets you build tree structures of objects, and treat individual objects (leaves) and groups (composites) through the same interface.
- What is the Decorator pattern's purpose? — Decorator adds responsibilities to individual objects at runtime, by wrapping them in objects with the same interface.
- What is the Composite pattern, and when is it most useful? — It's most useful for part-whole hierarchies, where clients shouldn't care whether they hold one item or a group: file systems; UI component trees; organisation charts; bills of materials; …
- Give an example of using Composite to model a tree. — A product-bundle pricing tree: a bundle's price is the sum of its children, which are either products or nested bundles.
- How does Composite simplify working with hierarchical data? — Client code applies one operation to the root, and recursion handles the depth: no
instanceof checks, and no manual traversal logic scattered around.
- What are the benefits and limitations of Composite? — Benefits: Uniform treatment of leaves and composites; Limitations: Transparency vs safety: putting
add/remove on the common interface lets clients call add on a leaf, where it throws. Putting them only on the composite forces type checks. Choose deliberately.
- How do you implement Composite in Java? — Define a Component interface with the common operations; Implement Leaf classes; Implement a Composite that holds a
List<Component>, delegates operations to its children, and provides add/remove.
- What is the Decorator pattern, and how does it differ from inheritance? — Inheritance adds behaviour statically, to every instance of the subclass. To combine features, you need a subclass for each combination: that's a class explosion.
- How do you implement a Decorator in Java? — Implement the same interface as the component, hold a reference to the wrapped component, and delegate, adding behaviour around the call.
- What are the advantages of Decorator for extending behaviour? — The Open/Closed principle: new behaviour means new decorators, with no changes to existing classes; The Single Responsibility principle: each concern (caching, retries, logging, metrics, encryption) lives in its own class; Runtime composition through configuration; It avoids…
- Give real-world examples of the Decorator pattern. —
java.io: new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(f)))). Each layer adds buffering, decoding or decompression; Collections.unmodifiableList, synchronizedMap: add restrictions or synchronisation to an existing collection; HTTP…
- How does Decorator promote flexibility in extending behaviour? — Behaviours become independent, composable units, assembled per object, per environment, at runtime: add retries only for remote clients; add caching only in production; add encryption only for sensitive streams; reorder or remove layers without touching the core or the other…
Facade & Proxy Patterns — Interview Questions — open the lesson
- What is the Facade pattern for? — A facade provides one simple, higher-level interface to a complex subsystem made of many classes. Clients call
placeOrder(), and the facade coordinates inventory, pricing, payment and shipping.
- What is the Proxy pattern for? — A proxy is a stand-in object with the same interface as the real object, which controls access to it: deferring creation (lazy loading); forwarding over the network; checking permissions; caching; …
- How does a facade simplify interaction with complex systems? — It reduces what clients must know: one entry point instead of many classes and call orders; It encodes the correct workflow: steps, ordering and error handling in one place; It reduces coupling: clients depend on the facade, so the subsystem can be refactored behind it; It…
- How does Facade differ from Adapter? — Facade defines a new, simpler interface over many classes, to reduce complexity. Adapter makes one existing interface conform to another expected interface, for compatibility.
- How do you implement a Facade in Java? — Write a class that depends on the subsystem components, and exposes intention-revealing methods, coordinating them.
- What are the advantages of Facade in large applications? — Simpler client code, and faster onboarding; Loose coupling: subsystems can evolve behind a stable facade; A single place for cross-cutting policies: transactions, authorisation, auditing, metrics; Layering: facades form the boundary of modules and bounded contexts (a module's…
- When would a facade be a bad idea? — When clients need fine-grained control that the facade hides. Don't force everything through it, and let advanced clients use the subsystem directly; When it turns into a god class that knows everything and changes for every feature; When it's pure pass-through, adding a…
- What is the Proxy pattern, and how does it control access to objects? — The proxy implements the same interface as the real subject, and holds (or knows how to obtain) a reference to it.
- What's the difference between virtual, remote and protection proxies? — Virtual proxy: delays creating or loading an expensive object until it's first used. For example, Hibernate lazy-loading proxies for associations, or a large image loaded only when displayed; Remote proxy: a local object that represents one in another process or machine, and…
- How do you implement a proxy in Java? — Static proxy: a class implementing the same interface, delegating to the real object; Dynamic proxy: created at runtime: JDK dynamic proxies (
java.lang.reflect.Proxy) for interfaces.
- When would you use the Proxy pattern in real applications? — You already do, through frameworks: Spring AOP: transactions, caching, security,
@Async and @Retryable are all applied through proxies around beans; Hibernate: lazy-loaded associations and getReference(); Remote clients: Feign, gRPC stubs, and Spring's HTTP interface…
- What are the downsides of the Proxy pattern? — Hidden behaviour: logic runs where you can't see it in the code, so debugging is harder; Identity and type surprises:
getClass() returns the proxy class, == compares against the proxy, and equals may trigger loading (Hibernate); Limits: JDK proxies are interface-only,…
Chain of Responsibility & Observer Patterns — Interview Questions — open the lesson
- What is the Chain of Responsibility pattern for? — It passes a request along a chain of handlers. Each handler either handles it, passes it on, or does some work and passes it on.
- What is the Observer pattern for? — Observer defines a one-to-many dependency. When a subject changes state, all registered observers are notified automatically, and the subject doesn't know what they do.
- How does Chain of Responsibility work? — Handlers share an interface (
handle(request)), and each knows its successor, or the chain is iterated by a runner. Two common variants: "First one wins": stop at the first handler that can handle the request, as in support escalation, or picking a payment method;…
- How do you implement Chain of Responsibility in Java? — In modern Java, a list of handler beans, iterated in order, is usually cleaner than linked
next references — public interface RefundRule {
- Give an example of when you'd use Chain of Responsibility. — Support-ticket escalation: L1, then L2, then a manager; Approval workflows by amount: team lead, then manager, then finance; Request processing pipelines: authentication, rate limiting, validation, logging (servlet filters, Spring Security's
SecurityFilterChain, Netty…
- How does Chain of Responsibility promote loose coupling? — The sender only knows the chain's entry point, not the concrete handlers. Handlers don't know about each other either, beyond "next".
- What are the drawbacks of Chain of Responsibility? — A request can pass through many handlers, which costs latency; Nobody may handle it, unless you add an explicit default or terminal handler; Order dependence: a subtle bug source when handlers are reordered; Debugging "who handled this?" is harder, so log or trace each…
- What is the Observer pattern, and when do you use it? — Use it when several independent parts must react to a change, and the source shouldn't depend on them. For example, when an order is placed: send an email, award loyalty points, update analytics.
- How does the Observer pattern work in Java with
Observer and Observable? — java.util.Observable was a class that kept a list of Observers. The subject called setChanged() then notifyObservers(arg), and each observer's update(Observable, Object) ran. These types have been deprecated since Java 9: Observable is a class, so subjects can't…
- What's the difference between the Observer pattern and Pub/Sub? — Observer: observers register directly with the subject, in-process. Notification is usually synchronous, and the subject holds references to the observers; Pub/Sub: publishers and subscribers are decoupled by an intermediary: an event bus or a message broker (Kafka,…
- How do you handle observers that must be updated at different times? — Asynchronous dispatch: each observer, or group, gets its own executor or queue, so slow ones don't delay fast ones; Priorities or ordering (
@Order on listeners); Filtering (conditional listeners: @EventListener(condition = "#e.amount > 1000")); Batching or debouncing for…
- What are the challenges of Observer in multithreaded environments? — Concurrent registration and notification: iterating the listener list while others add or remove listeners can throw
ConcurrentModificationException. Use CopyOnWriteArrayList; Deadlocks: don't hold the subject's lock while calling observers, because they may call back or…
Strategy & Template Method Patterns — Interview Questions — open the lesson
- What is the Strategy pattern for? — Strategy defines a family of algorithms, encapsulates each one, and makes them interchangeable, so the algorithm can vary independently of the client that uses it.
- What is the Template Method pattern for? — Template Method defines the skeleton of an algorithm in a base-class method. Subclasses redefine certain steps without changing the overall structure.
- What is the Strategy pattern, and when would you use it? — Use it when there are several ways to do one task, the choice is made at runtime (by configuration, user input or data), and you want to avoid a growing
if/else or switch over types in the client.
- How does Strategy differ from Template Method? — Compared side by side in the full answer (table) — know each row.
- How would you implement the Strategy pattern in Java? — Define the strategy interface; Write one implementation per algorithm; Have the context depend on the interface; Choose the strategy at runtime.
- What are the benefits of using Strategy to select algorithms at runtime? — Open/Closed: a new algorithm means a new class, and the context doesn't change; No conditional sprawl in the client; Single responsibility: each algorithm is small, and tested in isolation; Runtime flexibility: selection by configuration, feature flag, A/B test, tenant or…
- Give an example where Strategy simplifies managing multiple algorithms. — Payment processing (above). Another common one is shipping-cost calculation: flat rate, weight-based, distance-based, a free-shipping promo, and a per-carrier API quote. Without Strategy, one method grows a switch with carrier-specific branches, which every change touches.…
- What is the Template Method pattern, and when would you use it? — Use it when several classes share the same process, and only specific steps differ, and you want the base class to guarantee the order and the common behaviour: opening and closing resources, validation, logging, metrics, transactions. Examples: file importers (CSV, XML,…
- How would you implement the Template Method pattern in Java? — Write an abstract class with a
final template method that calls the steps in order. Make the steps abstract (mandatory) or hooks (overridable methods with default behaviour).
- Give an example where you'd use the Template Method pattern. — A data-processing application that ingests from files, databases and APIs. The workflow (connect, fetch, parse, validate, save, and report) is identical.
- What are the advantages and limitations of Template Method? — Advantages: Code reuse: the shared steps live in one place; Limitations: Inheritance coupling: subclasses depend on the base class's internals (the "fragile base class" problem).
- Show Template Method refactored into a strategy/callback. — Keep the fixed workflow in a concrete class, and inject the variable steps. This is exactly how
JdbcTemplate works.
Command Pattern — Interview Questions — open the lesson
- What is the Command pattern for? — It encapsulates a request as an object, containing everything needed to perform it later: the receiver, the action and the parameters.
- What is the Command pattern, and how does it encapsulate requests? — It has four roles: A Command interface:
execute(), and optionally undo(); Concrete commands: each holds a reference to its receiver, plus the arguments, and implements execute() by calling the receiver; An Invoker: a button, scheduler, queue consumer or job runner. It…
- How would you implement the Command pattern in Java? — ```java public interface Command { void execute(); void undo(); }
- When would you use the Command pattern, for example for undo/redo? — Undo/redo: editors, drawing tools, form wizards. Each executed command goes on an undo stack, and knows how to reverse itself, capturing whatever state it needs at execute time; Queuing and asynchronous work: jobs submitted to an executor or a message queue; Scheduling: run…
- What are the advantages of the Command pattern in event-driven systems? — Decoupling: the component that raises an action doesn't know who performs it; Uniform handling: every action goes through the same pipeline (validate, authorise, log, execute, emit), so cross-cutting concerns are written once; Serialisable requests: commands can be put on…
- How does the Command pattern decouple the sender and receiver of a request? — The sender (invoker) only knows the
Command interface, and calls execute(). The command knows the receiver and the method to call, and the receiver knows nothing about the sender. So: the same invoker (a button or a job runner) can trigger any action; the same action can…
- How does Command relate to things you use every day in Java and Spring? —
Runnable/Callable are command interfaces, and an ExecutorService is the invoker: executor.submit(() -> emailService.send(msg)); CQRS commands (PlaceOrderCommand handled by a PlaceOrderHandler) are Commands in which the data object and the handler are separated,…
Follow-up questions this topic invites — and their answers
Q: How should I use this list in the last week before an interview?
A: Do one pass per day. Cover the answer text, say your answer out loud, then check it. Mark every question you could not answer crisply, and spend your study time only on the marked ones by opening the linked full answer. By the third pass the marked list should be short.
Q: The interviewer asks one of these basics — should I give only the one-liner?
A: Lead with the one-liner, then add one concrete detail or example from your own work. At this level the follow-up usually probes the mechanism behind the basic answer, so be ready to go one layer deeper using the key points in the full lesson.
Q: Some answers here were corrected compared with common prep sheets — why?
A: Several widely shared answers are outdated or wrong (for example, Java version details, removed Spring APIs, or SQL queries that miss edge cases). The full lessons call these out under "Common trap" — reading those is the fastest way to stand out from candidates who memorised the same sheets.