Interview
OOP & SOLID Design — Interview Questions (95+)
See runnable OOP examples in `pkg1core` (core10–core14, core25–core28).
Detailed Questions
1. What are the four pillars of OOP?
- Short: Encapsulation, inheritance, polymorphism, abstraction.
- Detailed: Encapsulation hides state behind methods. Inheritance reuses and specializes behavior. Polymorphism lets one interface invoke different implementations at runtime. Abstraction exposes essentials and hides complexity (abstract classes/interfaces).
- Example:
Listinterface (abstraction) withArrayList/LinkedList(polymorphism).
2. Explain SOLID in one sentence each.
- Short: SRP, OCP, LSP, ISP, DIP — one reason to change; open for extension; substitutable subtypes; small interfaces; depend on abstractions.
- Detailed: SRP: a class should have one responsibility. OCP: extend via new code, not modifying existing. LSP: subtypes must honor the parent's contract. ISP: clients shouldn't depend on methods they don't use. DIP: high-level modules depend on abstractions, not concretions.
- Example: Inject
PaymentGatewayinterface (DIP) instead ofStripeClient.
3. SRP violation — how to spot and fix?
- Short: Class changes for unrelated reasons (e.g.
Usersaves to DB and sends email). - Detailed: God classes mix persistence, validation, UI, and messaging. Split into
User,UserRepository,EmailService. Each has one reason to change. - Example:
OrderServiceorchestrates;OrderValidator,OrderRepository,PaymentClientdo one job each.
4. OCP in practice — strategy vs if-else?
- Short: Replace growing if/switch chains with polymorphism or strategy.
- Detailed: Every new discount type shouldn't require editing a central
calculate()method. Register strategies (DiscountPolicy) and select at runtime. New types = new class, zero edits to core logic. - Example:
Map<String, DiscountPolicy>or Spring beans keyed by type.
5. LSP violation example?
- Short: Subclass breaks expectations of the parent (e.g.
SquareextendsRectanglewith coupled width/height). - Detailed: If code expects
setWidthandsetHeightindependently butSquareforces equality, callers break. Prefer composition or separate types over inheritance that narrows behavior. - Example: Classic
Rectangle/Squareproblem;Penguin extends Birdwithfly().
6. ISP — fat interface smell?
- Short: One interface with many methods forces empty/stub implementations.
- Detailed: Split
Workerwithwork/eat/sleepintoWorkable,EatablesoRobotonly implementsWorkable. Java 8+ default methods can help but don't replace thoughtful segregation. - Example:
Servlet-style fat interfaces vs role-specific ones.
7. DIP — how does Spring embody it?
- Short: Constructor injection of interfaces; framework wires implementations.
- Detailed: Application code depends on
UserRepository;@Autowiredor constructor providesJpaUserRepository. Tests swap inInMemoryUserRepository. Inversion: framework injects dependencies you don't construct. - Example:
@Servicedepends onRepositoryinterface, notEntityManagerdirectly.
8. Composition over inheritance — when and why?
- Short: Favor has-a over is-a to avoid fragile base classes and deep hierarchies.
- Detailed: Inheritance exposes subclass to parent implementation changes. Composition delegates behavior (
EngineinsideCar) and allows runtime swapping (new ElectricEngine()). - Example:
StackwrappingDequeinstead of extendingVector.
9. Coupling vs cohesion?
- Short: Low coupling (minimal dependencies); high cohesion (related work grouped).
- Detailed: Tight coupling to concrete classes, static singletons, and shared mutable state makes change risky. Cohesive classes do one domain concept well.
- Example: Service calling repository interface = loose coupling;
DateUtilswith only date helpers = high cohesion.
10. Law of Demeter (principle of least knowledge)?
- Short: Don't call methods on objects returned by other methods — talk to immediate friends only.
- Detailed:
order.getCustomer().getAddress().getZip()chains knowledge across layers. Exposeorder.getShippingZip()instead. Reduces ripple effects when inner objects change. - Example: Facade methods on aggregate roots.
11. DDD building blocks — entity vs value object?
- Short: Entity has identity; value object is defined by its attributes (immutable).
- Detailed:
OrderIddistinguishes orders;Moneywith amount+currency is interchangeable if values match. Value objects should be immutable and compared by value. - Example: Java
recordfor value objects; JPA@EmbeddedforAddress.
12. Tell, Don't Ask?
- Short: Tell objects to do work; don't pull data out and decide externally.
- Detailed:
if (account.getBalance() >= amount) account.withdraw(amount)leaks logic. Preferaccount.withdraw(amount)which enforces rules internally. - Example: Rich domain model vs anemic model with service doing all logic.
13. Immutability as a design choice?
- Short: Immutable objects are thread-safe and easier to reason about.
- Detailed: No setters; defensive copies on getters;
finalfields; factory methods. Trade-off: creating new instances vs synchronizing mutations. - Example:
String,Integer,recordwith no mutable components.
14. Package-private and module boundaries?
- Short: Use visibility to enforce encapsulation at package/module level.
- Detailed: Public API surface should be minimal. JPMS
exports/openscontrol what other modules see. Don't expose internals "for tests" via public setters. - Example:
com.app.apiexports interfaces;com.app.internaldoes not.
15. Anti-corruption layer?
- Short: Translate external model to your domain at the boundary.
- Detailed: When integrating legacy or third-party APIs, don't let their types leak everywhere. Adapter/facade maps DTOs to domain objects once at the edge.
- Example:
LegacyBillingAdapterimplements yourBillingPort.
Rapid-Fire (Q → A)
- Four OOP pillars? → Encapsulation, inheritance, polymorphism, abstraction.
- SRP? → One reason to change.
- OCP? → Open extension, closed modification.
- LSP? → Subtypes substitutable for base.
- ISP? → Small, focused interfaces.
- DIP? → Depend on abstractions.
- God class? → Too many responsibilities.
- Anemic domain model? → Data classes + logic in services (anti-pattern for DDD).
- Rich domain model? → Behavior on domain objects.
- Composition over inheritance? → Has-a preferred over is-a.
- Fragile base class? → Parent change breaks children.
- Favor delegation? → Wrap and forward calls.
- Encapsulation benefit? → Protect invariants.
- Polymorphism mechanism? → Dynamic dispatch on overridden methods.
- Overloading vs overriding? → Compile-time vs runtime.
- Upcasting safe? → Yes, implicit to supertype.
- Downcasting risk? → ClassCastException.
- instanceof before cast? → Safe pattern.
- Abstract class vs interface for shared state? → Abstract class.
- Multiple inheritance of type? → Interfaces only.
- Diamond problem in Java? → Resolved by most specific default method override.
- Default method purpose? → Evolve interfaces without breaking impls.
- Static methods in interfaces? → Utility, not inherited.
- Private methods in interfaces? → Shared code for defaults (Java 9+).
- Sealed classes purpose? → Controlled inheritance hierarchy.
- Non-sealed permits? → Allow unknown subclasses outside module.
- Record purpose? → Immutable data carrier.
- Record vs class for DTO? → Record when data-only, no identity.
- Enum for type-safe constants? → Yes; can have behavior.
- Tell Don't Ask example? →
order.ship()notif (order.canShip()). - Law of Demeter violation? → Long getter chains.
- Facade pattern role? → Simplify subsystem API.
- Adapter at boundary? → Convert foreign interface.
- Low coupling benefit? → Easier change/test.
- High cohesion benefit? → Clear purpose per class.
- Dependency injection types? → Constructor (preferred), setter, field.
- Constructor injection why preferred? → Immutable, explicit, testable.
- Service locator vs DI? → Locator hides dependencies (anti-pattern).
- Interface segregation example? →
PrintervsScannernot oneMachine. - Open-closed with Strategy? → New strategy class, no edit to context.
- Template Method in OOP? → Base defines skeleton, subclasses fill steps.
- Hollywood Principle? → Don't call us, we'll call you (IoC).
- Inversion of Control? → Framework controls flow/callbacks.
- Aggregate root? → DDD entry point for consistency boundary.
- Value object equality? → By all fields (record auto).
- Entity equality? → Usually by ID.
- Side-effect-free functions? → Easier to test and compose.
- Pure function? → Same input → same output, no side effects.
- YAGNI? → You aren't gonna need it.
- KISS? → Keep it simple.
- DRY? → Don't repeat yourself (but not at cost of coupling).
- Premature abstraction cost? → Wrong abstraction harder than duplication.
- Leaky abstraction? → Exposes implementation details.
- Design by contract? → Preconditions, postconditions, invariants.
- Defensive copying? → Return copies of internal mutable state.
- Fail-fast validation? → Reject invalid state at construction.
- Null object pattern? → No-op impl instead of null checks.
- Specification pattern? → Composable business rules.
- Factory when? → Hide construction complexity/variants.
- Builder when? → Many optional constructor params.
- Prototype when? → Clone expensive-to-build objects.
- Bridge pattern? → Decouple abstraction from implementation.
- Decorator vs subclass? → Runtime stacking vs static hierarchy.
- Proxy for cross-cutting? → Security, lazy load, logging.
- Observer decoupling? → Subject doesn't know concrete observers.
- MVC layering? → Model-View-Controller separation.
- Hexagonal architecture? → Ports and adapters.
- Clean architecture layers? → Entities → use cases → adapters.
- Bounded context? → DDD module with own ubiquitous language.
- Ubiquitous language? → Shared terms dev + domain experts.
- Anti-corruption layer? → Translate legacy at boundary.
- CQRS? → Separate read/write models.
- Event sourcing? → State as event log.
- Idempotent operations? → Same call safe to repeat.
- Backward compatibility? → Don't break clients on API change.
- Semantic versioning? → MAJOR.MINOR.PATCH.
- Breaking change example? → Remove public method.
- Deprecation strategy? →
@Deprecated(forRemoval=true)+ migration path. - Testability and DIP? → Mock interfaces in unit tests.
- SOLID + patterns relation? → Patterns often implement SOLID goals.