Ngân hàng câu hỏi

Ngân hàng câu hỏi OOP và SOLID

40+ câu hỏi OOP, SOLID, Design Pattern cho fresher .NET — kèm đáp án ngắn.

A. 4 tính chất OOP

1. OOP là gì? 4 tính chất gồm những gì?

Object-Oriented Programming — mô hình hoá thế giới thực bằng object. 4 tính chất:

  1. Encapsulation (đóng gói)
  2. Abstraction (trừu tượng)
  3. Inheritance (kế thừa)
  4. Polymorphism (đa hình)

2. Encapsulation là gì? Ví dụ?

Che giấu state, expose qua method/property:

public class BankAccount {
    private decimal _balance;
    public decimal Balance => _balance;
    public void Deposit(decimal amt) {
        if (amt > 0) _balance += amt;
    }
}

Bên ngoài không thay đổi _balance trực tiếp — phải qua Deposit có validation.

3. Abstraction khác Encapsulation chỗ nào?

  • Abstraction: ẩn độ phức tạp — chỉ expose interface cần thiết (concept).
  • Encapsulation: ẩn dữ liệu nội bộ — thực thi qua access modifier (mechanism). Hai khái niệm liên quan nhưng khác cấp độ: abstraction là what, encapsulation là how.

4. Kế thừa — Quan hệ "is-a" hay "has-a"?

Is-a. Dog : Animal — Dog IS-A Animal. Nếu chỉ "có" (Car có Engine) → dùng composition (has-a).

5. Polymorphism có mấy loại?

2 loại:

  • Compile-time (static): method overload, operator overload.
  • Runtime (dynamic): method override qua virtual/override.

6. Đa hình runtime hoạt động ra sao?

CLR dùng virtual method table (vtable). Khi gọi method virtual, runtime tra vtable của object thực tế → gọi đúng method override.

7. Cho ví dụ về Polymorphism với reference type cha?

Animal a = new Dog();
a.Speak();   // Gọi Dog.Speak() vì Speak là virtual và Dog override

8. Inheritance có nhược điểm gì?

  • Coupling chặt: con phụ thuộc cấu trúc cha. Cha đổi → con vỡ.
  • Lạm dụng tạo cây kế thừa sâu khó maintain.
  • Vi phạm LSP dễ xảy ra (Square : Rectangle).
  • → Khuyến nghị: Composition over Inheritance.

9. Composition over Inheritance — ý nghĩa?

Thay vì Car : Vehicle, dùng Car chứa Engine, Wheels (interface). Linh hoạt hơn — đổi engine không sửa Car.

B. Interface & Abstract class

10. Interface vs Abstract class — khác nhau cơ bản?

InterfaceAbstract class
Multiple inheritance
Field/state
Constructor
Method body❌ (đến C# 8 có default)
Mục đíchCapabilityBản chất

11. Khi nào dùng Interface, khi nào dùng Abstract class?

  • Cần share code (method body, field) → abstract class.
  • Chỉ cần share hợp đồnginterface.
  • Cần multiple inheritance → interface.
  • Trong .NET hiện đại, mặc định nghiêng về interface vì dễ test/mock.

12. Class có thể vừa kế thừa class vừa implement interface không?

Có. Cú pháp: class A : BaseClass, IInterface1, IInterface2. Class cha phải đứng trước.

13. Default interface method (C# 8+)?

Interface có thể có method có body làm mặc định. Class implement không bắt buộc override. Hữu ích để thêm method mới không break code cũ.

14. Explicit interface implementation?

public class Logger : IConsoleLog, IFileLog {
    void IConsoleLog.Log(string m) { /*...*/ }
    void IFileLog.Log(string m)    { /*...*/ }
}

Dùng khi 2 interface có method trùng tên cần implementation khác nhau.

15. Có thể tạo instance của abstract class không?

Không. Abstract class chỉ dùng làm base, phải kế thừa và implement abstract member rồi mới new được class con.

C. Access modifier & member

16. 5 access modifier của C#?

  • public — mọi nơi.
  • private — chỉ trong class.
  • protected — trong class và class con.
  • internal — trong cùng assembly.
  • protected internal — class con HOẶC cùng assembly.
  • private protected — class con TRONG cùng assembly.

17. Property vs Field — khác gì?

  • Field: biến lưu data, thường private.
  • Property: pair get/set wrap field — cho phép validation, computed, encapsulation. Truy cập như field nhưng thực chất gọi method.

18. Auto-property là gì?

public string Name { get; set; }   // compiler tự sinh backing field
public string Name { get; init; }  // chỉ set khi init
public string Name { get; private set; }  // set chỉ trong class

19. Static class có thể có constructor không?

— static constructor static MyClass() không tham số, chạy 1 lần khi class được load.

D. SOLID

20. SOLID là gì?

5 nguyên lý OOP của Robert C. Martin:

  • S — Single Responsibility
  • O — Open/Closed
  • L — Liskov Substitution
  • I — Interface Segregation
  • D — Dependency Inversion

21. Single Responsibility Principle — ví dụ?

Một class chỉ một lý do để đổi.

// ❌ Class này có 3 lý do đổi
class Report {
    void Generate() {}
    void SaveToDb() {}
    void EmailToUser() {}
}
// ✅ Tách 3 class
class Report {}
class ReportRepository {}
class ReportEmailService {}

22. Open/Closed Principle — ví dụ?

Mở để mở rộng, đóng để sửa. Thêm shape mới mà không sửa code cũ:

abstract class Shape { public abstract double Area(); }
class Circle : Shape { public override double Area() => Math.PI * r * r; }
class Square : Shape { public override double Area() => s * s; }
// Thêm Triangle? Tạo class mới, không sửa class hiện có.

23. Liskov Substitution Principle — ví dụ vi phạm?

class Bird { public virtual void Fly() {} }
class Penguin : Bird { public override void Fly() => throw; }

Penguin substituted vào Bird sẽ phá code gọi Fly(). Fix: tách IFlyable.

24. Interface Segregation Principle — ví dụ?

// ❌ Fat interface
interface IWorker { void Work(); void Eat(); }
class Robot : IWorker { ...Eat() => throw; }

// ✅ Tách
interface IWorkable { void Work(); }
interface IFeedable { void Eat(); }

25. Dependency Inversion Principle — ví dụ?

Module cấp cao không depend module cấp thấp, cả hai depend abstraction.

// ❌ Service gắn cứng vào concrete
class OrderService { SqlRepo repo = new(); }

// ✅ Depend interface
class OrderService {
    private readonly IOrderRepo _repo;
    public OrderService(IOrderRepo repo) => _repo = repo;
}

26. DIP và DI có giống nhau không?

Không.

  • DIP = nguyên lý (depend on abstraction).
  • DI = kỹ thuật/pattern thực thi DIP (constructor injection, framework như ASP.NET Core).

27. Trong ASP.NET Core, SOLID nguyên lý nào được dùng nhiều nhất?

D — Dependency Inversion, qua built-in DI container. Mọi service đăng ký bằng interface, inject qua constructor.

E. Design pattern fresher hay được hỏi

28. Design pattern là gì? Có mấy nhóm?

Giải pháp tái sử dụng cho vấn đề lập trình lặp lại. 3 nhóm GoF:

  • Creational: Singleton, Factory, Builder...
  • Structural: Adapter, Decorator, Facade...
  • Behavioral: Strategy, Observer, Command...

29. Singleton — implement sao cho thread-safe?

public sealed class Logger {
    private static readonly Lazy<Logger> _instance = new(() => new Logger());
    public static Logger Instance => _instance.Value;
    private Logger() {}
}

Lazy<T> đảm bảo chỉ 1 instance, lazy init, thread-safe.

30. Factory pattern — khi nào dùng?

Khi tạo object có logic phức tạp, hoặc decide concrete class lúc runtime.

class ShapeFactory {
    public IShape Create(string type) => type switch {
        "circle" => new Circle(),
        "square" => new Square(),
        _ => throw new()
    };
}

31. Repository pattern — vì sao dùng?

Tách data access ra khỏi business logic. Service không biết DB là SQL hay Mongo — chỉ biết IUserRepository. Dễ test (mock), dễ swap DB.

32. Strategy pattern — ví dụ?

interface IDiscount { decimal Apply(decimal p); }
class TenPct  : IDiscount { ... }
class Student : IDiscount { ... }

class Cart {
    private readonly IDiscount _strategy;
    public Cart(IDiscount s) => _strategy = s;
}

Đổi strategy chỉ cần inject implementation khác.

33. Observer pattern và event của C# liên hệ ra sao?

Event chính là Observer pattern built-in: subject (event publisher) thông báo nhiều observer (subscriber) khi state đổi.

34. Decorator pattern — ví dụ trong .NET?

Stream chain: FileStreamBufferedStreamCryptoStream. Mỗi cấp add chức năng (buffer, encrypt) mà không sửa class gốc.

35. Unit of Work pattern?

Nhóm nhiều thao tác DB thành 1 transaction. EF Core DbContext chính là Unit of Work — track changes, commit hết bằng SaveChanges().

F. Câu gài hay gặp

36. Cho class có 1 method virtual nhưng class không có instance — đây là class gì?

Không thể. Method virtual cần class concrete để instantiate. Nếu class abstract → method có thể abstract, không nhất thiết virtual.

37. Override ToString của object — vì sao nên?

Để debug/log đẹp hơn. Khi Console.WriteLine(obj) hoặc string interpolation, runtime gọi ToString. Mặc định trả tên class.

38. Vì sao C# không hỗ trợ đa kế thừa class?

Tránh diamond problem: nếu 2 base có cùng method, không rõ con kế thừa cái nào. C# chọn interface (chỉ contract, không state) làm giải pháp.

39. Composition khác Aggregation khác Association?

  • Association: 2 class biết nhau (User và Order).
  • Aggregation: "has-a" yếu — sống độc lập (Library has Books, đóng Library, Books vẫn còn).
  • Composition: "has-a" mạnh — vòng đời gắn liền (House has Rooms, phá House, Room mất).

40. Cohesion và Coupling — định nghĩa?

  • Cohesion: mức độ các phần trong 1 module liên kết với nhau. Cao = tốt.
  • Coupling: mức độ phụ thuộc giữa các module. Thấp = tốt. Nguyên tắc: High cohesion, low coupling.

41. KISS, DRY, YAGNI là gì?

  • KISS: Keep It Simple, Stupid.
  • DRY: Don't Repeat Yourself.
  • YAGNI: You Aren't Gonna Need It (đừng code cho future không chắc).

42. Law of Demeter (Principle of Least Knowledge)?

"Don't talk to strangers." Object chỉ gọi method của:

  • Chính nó,
  • Tham số được truyền vào,
  • Object nó tạo,
  • Field instance. Tránh chain dài: a.B.C.D.Do() — vi phạm vì biết quá nhiều cấu trúc.

➡️ Tiếp theo: Ngân hàng câu hỏi SQL

© 2026 .NET Fresher Guide. All rights reserved.

Về Trang Web

Hướng dẫn toàn diện để chuẩn bị phỏng vấn vị trí .NET Fresher với nội dung từ lý thuyết đến thực hành.