← Back to CS Fundamentals

SOLID — All 5

CS FundamentalsSenior

The Question

Explain all five SOLID principles with examples.

What a Strong Answer Covers

  • All five names and one-line definitions. Liskov must say "substitutable.

Senior-Level Answer

SOLID is an acronym for five object-oriented design principles introduced by Robert Martin. Each targets a different source of design fragility.

Single Responsibility Principle (SRP): a class should have only one reason to change. If a class handles both business logic and persistence, a change in the database schema forces a change to the business logic class. Split them: one class models the domain, another handles storage. SRP reduces coupling and makes classes easier to test.

Open/Closed Principle (OCP): software entities should be open for extension but closed for modification. Instead of adding if/else branches to an existing class when requirements grow, you extend behavior through new subclasses or strategy objects. A PaymentProcessor that switches on payment type violates OCP; extracting a PaymentStrategy interface and injecting implementations satisfies it.

Liskov Substitution Principle (LSP): subtypes must be substitutable for their base types without altering program correctness. If Square extends Rectangle and overrides setWidth() to also set height (to keep it square), code that relies on Rectangle's behavior -- setting width and height independently -- breaks silently. The fix is often to not use inheritance where the subtype cannot honor the contract of the supertype.

Interface Segregation Principle (ISP): clients should not be forced to depend on interfaces they do not use. A fat interface that includes methods irrelevant to most implementors forces implementors to provide no-op stubs. Split large interfaces into smaller, focused ones. A Worker interface with work() and eat() is problematic for robots that do not eat -- split into Workable and Feedable.

Dependency Inversion Principle (DIP): high-level modules should not depend on low-level modules; both should depend on abstractions. A service class that directly instantiates a DatabaseRepository cannot be tested without a real database. Inject an abstract Repository interface instead -- the service depends on the abstraction, and the concrete implementation is wired in at the composition root. This is the foundation of dependency injection.

Applied together, SOLID principles produce code where each class has a clear purpose, extension points are explicit, contracts are honored, interfaces are minimal, and dependencies flow toward abstractions.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Candidate can define and give an example for 3-4 of the five principles, but confuses LSP and ISP, or cannot explain DIP beyond use interfaces, or gives abstract examples without concrete code scenarios.

3/3 — Strong Answer

Candidate defines all five precisely, gives concrete code-level examples for each, explains what violation looks like (not just what the principle says), and articulates how DIP enables dependency injection.

Common Mistakes

  • Confusing ISP with SRP -- SRP is about a class having one reason to change; ISP is about interfaces not having methods irrelevant to their clients
  • Describing DIP as use interfaces without explaining what it means for high-level modules not to depend on low-level ones
  • Giving the Square/Rectangle example for LSP without explaining why it violates the principle
  • Treating SOLID as a checklist rather than trade-offs -- over-applying OCP leads to needless abstraction layers

Follow-Up Questions

  • How does DIP differ from Dependency Injection? — DIP is a design principle; dependency injection is a technique that implements it by providing dependencies from the outside rather than constructing them internally.
  • Can you over-apply SOLID? — Yes -- OCP taken too far produces excessive abstraction; SRP applied too granularly creates a proliferation of tiny classes. Judgment matters.
  • How does LSP relate to Liskov's formal theorem? — Formally, a subtype must satisfy all invariants and pre/post-conditions of the supertype -- weaker preconditions and stronger postconditions are allowed.
  • How does OCP relate to the Strategy pattern? — The Strategy pattern is a common OCP implementation -- it lets you vary behavior by swapping in a new strategy object rather than modifying existing code.

Related Questions

  • Process vs Thread
  • Race Condition
  • Deadlock — 4 Conditions, Prevention
  • Thread Safety — Is dict Thread Safe?
  • HashMap Internals

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout