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

Ngân hàng câu hỏi Design Pattern (.NET)

55+ câu hỏi Design Pattern hay hỏi nhất trong phỏng vấn .NET — GoF, .NET-specific patterns (Repository, UoW, Options, MediatR, CQRS), anti-pattern.
Design Pattern là câu hỏi cốt lõi của phỏng vấn .NET — fresher 1-2 pattern cơ bản, junior trở lên hỏi sâu cả pattern .NET-specific (Repository, MediatR, Options). File này tổng hợp 55+ câu hỏi thực tế từ ITviec, TopDev, Viblo, ScholarHat, codewithmukesh, Microsoft Learn.

A. Tổng quan

1. Design Pattern là gì?

Giải pháp tái sử dụng cho vấn đề lập trình lặp lại trong design. Không phải code copy-paste — là template (khuôn mẫu) để áp dụng. Khái niệm xuất phát từ kiến trúc (Christopher Alexander), được phổ cập trong lập trình bởi cuốn "Design Patterns" của Gang of Four (1994).

2. Vì sao phỏng vấn .NET hay hỏi Design Pattern?

Vì recruiter muốn biết:

  • Bạn có viết được code maintainable, scalable chưa.
  • Bạn có đọc hiểu framework code không (ASP.NET Core, EF Core đầy pattern).
  • trải nghiệm thực với codebase phức tạp chưa.
  • language chuẩn để giao tiếp team không (gọi "Strategy pattern" hiệu quả hơn mô tả 5 câu).

3. Có bao nhiêu Design Pattern? 3 nhóm chính?

Gang of Four liệt kê 23 pattern, chia 3 nhóm:

NhómTập trungPattern phổ biến
CreationalTạo objectSingleton, Factory, Builder, Prototype, Abstract Factory
StructuralLắp ráp class/objectAdapter, Decorator, Facade, Proxy, Composite, Bridge, Flyweight
BehavioralTương tác + thuật toánStrategy, Observer, Command, Template Method, Chain of Responsibility, Iterator, State, Mediator

4. Design Pattern khác Design Principle ra sao?

  • Principle (nguyên lý): rules / guidelines như SOLID, DRY, KISS, YAGNI — abstract.
  • Pattern: giải pháp cụ thể cho vấn đề cụ thể — concrete template.

Pattern thực thi Principle. Ví dụ: Strategy pattern thực thi OCP + DIP.

5. Pattern nào fresher .NET phải biết?

Top 6:

  1. Singleton — câu PV gần như chắc chắn.
  2. Factory (Method/Abstract) — tạo object linh hoạt.
  3. Strategy — swap algorithm runtime, ví dụ rất hay.
  4. Repository — luôn xuất hiện trong .NET có DB.
  5. Dependency Injection (pattern) — ASP.NET Core built-in.
  6. Observer / Event — .NET event built-in chính là Observer.

6. Khi nào KHÔNG nên áp dụng Design Pattern?

  • Script nhỏ, prototype, throwaway code.
  • Khi áp pattern làm code phức tạp hơn vấn đề thực tế.
  • "Pattern fever" — ép pattern lên mọi vấn đề → over-engineering.

Quy tắc: áp pattern khi đau thật, không "preemptive".

B. Creational Patterns

7. Singleton — định nghĩa?

Đảm bảo class chỉ có 1 instance suốt app lifetime, expose qua điểm truy cập toàn cục.

8. Implement Singleton thread-safe C#?

public sealed class Logger {
    private static readonly Lazy<Logger> _instance = new(() => new Logger());
    public static Logger Instance => _instance.Value;
    private Logger() {}
    public void Log(string m) => Console.WriteLine(m);
}

Lazy<T> lo thread-safety + lazy init. sealed chặn kế thừa. private constructor chặn new từ ngoài.

9. Vì sao Lazy tốt hơn lock thủ công?

Lazy<T> dùng LazyThreadSafetyMode.ExecutionAndPublication mặc định → thread-safe, không phải viết double-check locking dễ sai. Code ngắn, ý đồ rõ.

10. Trong ASP.NET Core, dùng DI Singleton hay viết Singleton thủ công?

DI container Singleton:

services.AddSingleton<ILogger, Logger>();

DI Singleton tốt hơn vì:

  • Không global state — dễ test (thay impl khi test).
  • Lifetime quản lý bởi container, dispose đúng lúc.
  • Có thể inject dependency vào.

11. Singleton có hại gì?

  • Global state → khó test (test này ảnh hưởng test kia).
  • Hidden coupling — class dùng Singleton không expose dependency.
  • Khó parallel test.
  • Vi phạm SRP nếu lạm dụng (Singleton ôm nhiều việc).

→ Dùng DI Scoped/Singleton thay vì viết Singleton thủ công.

12. Static class vs Singleton — khác gì?

Static classSingleton
InstanceKhông có1
Implement interface
Inject vào class khác
Lazy initPhần
Polymorphism
Mock testKhó

→ Singleton linh hoạt hơn, dễ test hơn.

13. Factory Method là gì? Ví dụ?

Định nghĩa interface tạo object, để class con quyết concrete type.

public interface IShape { void Draw(); }
public class Circle : IShape { public void Draw() {} }
public class Square : IShape { public void Draw() {} }

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

14. Abstract Factory khác Factory Method?

  • Factory Method: tạo 1 loại object qua interface.
  • Abstract Factory: tạo một họ object liên quan (UI WinForms vs UI WPF — mỗi factory tạo Button + TextBox + Window cùng style).

15. Builder pattern — khi nào dùng?

Khi tạo object phức tạp, nhiều bước, nhiều optional parameter. Fluent API gọn hơn constructor 10 tham số:

var query = new QueryBuilder()
    .Where("city", "HCM")
    .OrderBy("age")
    .Limit(10)
    .Build();

Trong .NET: StringBuilder, HttpRequestMessageBuilder, ConfigurationBuilder (ASP.NET Core).

16. Prototype pattern?

Clone object hiện có thay vì new từ đầu — khi tạo object đắt (load từ DB, copy deep tree). C# có ICloneable nhưng API yếu (Object trả về) — thường viết deep clone thủ công hoặc dùng AutoMapper / record with.

17. C# record có liên quan Prototype không?

Có. recordwith expression — clone-and-modify rất gọn:

var user1 = new User("Alice", 25);
var user2 = user1 with { Age = 26 };  // clone, đổi Age

Đây là implementation của Prototype ở mức language.

C. Structural Patterns

18. Adapter pattern — ví dụ thực tế?

Wrap interface không tương thích thành interface app cần. Ví dụ legacy OldPaymentGateway.DoPayment(double) → wrap thành IPaymentService.ChargeAsync(decimal). Code app chỉ thấy interface mới, không động legacy.

19. Decorator — ví dụ trong .NET?

Stream chain kinh điển:

using var fs = new FileStream("data.bin", FileMode.Open);
using var bs = new BufferedStream(fs);
using var cs = new CryptoStream(bs, decryptor, CryptoStreamMode.Read);
using var gs = new GZipStream(cs, CompressionMode.Decompress);

Mỗi cấp wrap thêm chức năng (buffer, decrypt, decompress) mà không sửa class gốc.

20. ASP.NET Core middleware có phải Decorator không?

Có thể coi là dạng Decorator/Chain of Responsibility lai. Mỗi middleware wrap RequestDelegate next, thêm logic trước/sau khi gọi next:

app.Use(async (ctx, next) => {
    /* before */
    await next();
    /* after */
});

21. Facade pattern — ví dụ?

Cung cấp interface đơn giản cho subsystem phức tạp. Trong ASP.NET Core:

services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(...));
app.MapControllers();

Mỗi dòng wrap nhiều bước setup phức tạp.

22. Proxy pattern — dùng làm gì?

Object đứng giữa client và target — kiểm soát truy cập, lazy load, caching, logging.

Trong .NET:

  • EF Core lazy loading proxy — proxy class generate runtime, intercept property access để load related data.
  • Castle DynamicProxy — interceptor cho AOP (Aspect-Oriented Programming).
  • WCF / gRPC client — proxy gọi remote service.

23. Composite pattern?

Cho phép xử lý object đơn lẻ và group object theo cùng cách. Ví dụ tree file/folder: cả File và Folder implement IFileSystemItem với method GetSize(). Folder tính tổng size con đệ quy.

24. Bridge pattern?

Tách abstraction khỏi implementation để 2 chiều thay đổi độc lập. Ví dụ Shape × Renderer (OpenGL/Vulkan/Software) — thêm Shape mới không động Renderer, thêm Renderer không động Shape.

D. Behavioral Patterns

25. Strategy pattern — ví dụ phổ biến?

Định nghĩa họ algorithm, mỗi cái 1 class, swap được runtime:

public interface IDiscountStrategy {
    decimal Apply(decimal total);
}
public class NoDiscount : IDiscountStrategy { ... }
public class TenPercent : IDiscountStrategy { ... }
public class VipDiscount : IDiscountStrategy { ... }

public class Cart {
    private readonly IDiscountStrategy _strategy;
    public Cart(IDiscountStrategy strategy) => _strategy = strategy;
    public decimal Checkout(decimal total) => _strategy.Apply(total);
}

Strategy + DI trong ASP.NET Core = combo cực phổ biến.

26. Strategy vs State pattern?

  • Strategy: client chọn algorithm; algorithm độc lập với nhau.
  • State: object tự đổi state nội bộ; behavior thay đổi theo state hiện tại.

Cấu trúc class giống nhau, ý đồ khác.

27. Observer pattern — .NET implement ra sao?

Built-in qua event + delegate:

public class StockTicker {
    public event EventHandler<PriceChangedEventArgs>? PriceChanged;
    public void Update(decimal newPrice) {
        PriceChanged?.Invoke(this, new PriceChangedEventArgs(newPrice));
    }
}

ticker.PriceChanged += (s, e) => Console.WriteLine(e.NewPrice);

Hoặc IObservable<T> / IObserver<T> (Reactive Extensions / Rx.NET).

28. Observer vs Pub/Sub?

  • Observer: subject biết observer cụ thể (in-process, direct reference).
  • Pub/Sub: publisher và subscriber không biết nhau, qua broker (Redis Pub/Sub, RabbitMQ, Kafka).

29. Command pattern — ứng dụng?

Đóng gói request thành object → queue, log, undo được.

Ứng dụng:

  • Undo/redo trong editor.
  • Job queue (Hangfire, MassTransit).
  • MediatR library — mỗi command/query là 1 object, có handler riêng.

30. Template Method pattern — ví dụ?

Cha định nghĩa skeleton thuật toán, con override các bước:

public abstract class DataExporter {
    public void Export(string file) {           // template method — fixed
        var data = LoadData();
        var transformed = Transform(data);
        var formatted = Format(transformed);
        File.WriteAllText(file, formatted);
    }
    protected abstract List<Record> LoadData();
    protected abstract List<Record> Transform(List<Record> d);
    protected abstract string Format(List<Record> d);
}

public class CsvExporter : DataExporter { /* implement 3 step */ }
public class JsonExporter : DataExporter { /* implement 3 step */ }

31. Chain of Responsibility — ví dụ .NET?

ASP.NET Core middleware pipeline chính là Chain of Responsibility. Mỗi middleware quyết handle hoặc pass tiếp:

app.UseAuthentication();
app.UseAuthorization();
app.UseRouting();
app.UseEndpoints(...);

Mỗi cái có thể short-circuit (không gọi next()).

32. Iterator pattern — C# implement sao?

Built-in qua IEnumerable<T> + IEnumerator<T>. foreach thực chất gọi GetEnumerator() rồi loop MoveNext() + Current. yield return là sugar để tạo iterator dễ:

public IEnumerable<int> EvenNumbers(int max) {
    for (int i = 0; i <= max; i += 2)
        yield return i;
}

33. Mediator pattern là gì?

Đóng gói cách object tương tác với nhau qua 1 trung gian. Object không reference nhau trực tiếp — chỉ biết mediator. Giảm coupling N×N thành N×1.

34. MediatR là gì? Liên hệ Mediator pattern?

MediatR là thư viện .NET implement Mediator pattern + Command pattern + Notification pattern.

Trong ASP.NET Core:

// Command
public record CreateOrderCommand(int UserId, decimal Total) : IRequest<int>;

// Handler
public class CreateOrderHandler : IRequestHandler<CreateOrderCommand, int> {
    public async Task<int> Handle(CreateOrderCommand cmd, CancellationToken ct) {
        // logic
        return orderId;
    }
}

// Controller
[HttpPost]
public async Task<IActionResult> Create(CreateOrderDto dto) {
    var id = await _mediator.Send(new CreateOrderCommand(dto.UserId, dto.Total));
    return Ok(id);
}

Controller không biết handler — chỉ biết mediator. Loose coupling, dễ test.

E. .NET-Specific Patterns

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

Tách data access khỏi business logic. Service không biết DB là SQL hay Mongo, chỉ thấy IUserRepository. Lợi ích:

  • Test dễ (mock interface).
  • Swap DB dễ.
  • Centralize query phức tạp tái sử dụng.

36. Repository với EF Core — có thừa không?

⭐ Câu PV tranh cãi — phải biết để trả lời cân bằng.Lập luận "thừa":
  • DbSet<T> đã là Repository.
  • DbContext đã là Unit of Work (track change, SaveChanges atomic).
  • Nếu chỉ wrap _ctx.Users.Where(...) → noise.
  • IQueryable mất khi qua Repository abstraction (Task<List<T>>) → mất composability.
Lập luận "vẫn cần":
  • Centralize query phức tạp (GetActiveUsersInCity).
  • Hide EF Core khỏi business layer (test, swap ORM dễ hơn).
  • Áp Specification pattern bên trên.
Câu trả lời thực dụng: "Phụ thuộc complexity. Project nhỏ-vừa dùng DbContext trực tiếp đủ. Project lớn có domain phức tạp + nhiều dev → Repository giúp giới hạn EF Core knowledge."

37. Unit of Work — định nghĩa?

Nhóm nhiều thao tác DB thành 1 transaction. Track changes của entity, commit hết bằng 1 SaveChanges(). Đảm bảo atomic — hoặc tất cả thành công, hoặc rollback.

38. EF Core DbContext = Unit of Work?

Đúng. DbContext:

  • Track entity state (Added/Modified/Deleted/Unchanged).
  • SaveChanges() = commit 1 transaction.

Đó là vì sao nhiều người argue không cần wrap thêm IUnitOfWork.

39. Specification pattern?

Đóng gói query criteria thành object reusable + composable:

public interface ISpecification<T> {
    Expression<Func<T, bool>> Criteria { get; }
    List<Expression<Func<T, object>>> Includes { get; }
}

public class ActiveUsersInCitySpec : ISpecification<User> {
    public Expression<Func<User, bool>> Criteria { get; }
    public ActiveUsersInCitySpec(string city) {
        Criteria = u => u.IsActive && u.City == city;
    }
}

// Repository
public Task<List<T>> ListAsync<T>(ISpecification<T> spec) { ... }

Composable — combine spec bằng And/Or.

40. CQRS là gì? Khi nào dùng?

Command Query Responsibility Segregation — tách model write (command) khỏi read (query).

  • Command: thay đổi state, không return data (hoặc chỉ ID).
  • Query: đọc data, không thay đổi.

Khi nào dùng:

  • Read pattern khác hẳn write (analytics, dashboard).
  • Cần scale read và write độc lập (write DB master, read replica/cache).
  • Domain phức tạp với business logic write nhiều validation.

Khi nào KHÔNG: CRUD đơn giản. CQRS thêm complexity không đáng.

41. CQRS + MediatR — pattern combo?

Cực phổ biến trong ASP.NET Core clean architecture:

// Command (write)
public record CreateOrderCommand(...) : IRequest<int>;
public class CreateOrderHandler : IRequestHandler<CreateOrderCommand, int> { ... }

// Query (read)
public record GetOrderByIdQuery(int Id) : IRequest<OrderDto>;
public class GetOrderByIdHandler : IRequestHandler<GetOrderByIdQuery, OrderDto> { ... }

Controller Send mediator, không trực tiếp gọi service. Mỗi action là 1 file → dễ navigate.

42. CQRS có bắt buộc 2 DB không?

Không. CQRS có nhiều cấp:

  • Cấp 1: cùng DB, tách 2 model (Command/Query handler). Phổ biến nhất.
  • Cấp 2: cùng DB, view riêng cho query (materialized view).
  • Cấp 3: 2 DB tách hẳn — write DB normalized, read DB denormalized. Cần Event Sourcing hoặc CDC sync.

Fresher hay nhầm CQRS = 2 DB. Sai.

43. Dependency Injection — là pattern hay framework feature?

Cả 2. DI là pattern thực thi DIP. ASP.NET Core, NestJS, Spring biến nó thành framework feature qua DI container — bạn chỉ khai báo, container build dependency graph.

44. Options pattern trong ASP.NET Core?

Pattern để bind config từ appsettings.json thành strong-typed class:

// config class
public class JwtSettings {
    public string Issuer { get; set; } = "";
    public string Key { get; set; } = "";
    public int ExpiryMinutes { get; set; } = 60;
}

// Đăng ký
builder.Services.Configure<JwtSettings>(
    builder.Configuration.GetSection("Jwt"));

// Inject
public class AuthService {
    private readonly JwtSettings _settings;
    public AuthService(IOptions<JwtSettings> opt) => _settings = opt.Value;
}

3 flavor:

  • IOptions<T>: load 1 lần, không refresh.
  • IOptionsSnapshot<T>: refresh mỗi request (Scoped).
  • IOptionsMonitor<T>: refresh real-time + event change.

45. Result pattern — Vì sao trend gần đây?

Thay vì throw exception cho business error, return Result<T> chứa success/failure + value/error:

public class Result<T> {
    public bool IsSuccess { get; }
    public T? Value { get; }
    public string? Error { get; }
}

public Result<User> Register(string email, string pwd) {
    if (await _db.Users.AnyAsync(u => u.Email == email))
        return Result<User>.Fail("Email already exists");
    // ...
    return Result<User>.Ok(user);
}

Lợi ích: exception đắt, signature rõ ràng hơn, FP-style. Lib: FluentResults, LanguageExt, ErrorOr.

46. Pipeline pattern (Behavior trong MediatR)?

Wrap mỗi request qua chuỗi behavior — logging, validation, transaction, caching:

public class LoggingBehavior<TReq, TRes> : IPipelineBehavior<TReq, TRes> {
    public async Task<TRes> Handle(TReq req, RequestHandlerDelegate<TRes> next, CancellationToken ct) {
        _logger.LogInformation("Handling {Name}", typeof(TReq).Name);
        var response = await next();
        _logger.LogInformation("Handled {Name}", typeof(TReq).Name);
        return response;
    }
}

Đăng ký 1 lần, áp dụng mọi command/query. Tương tự middleware nhưng cho app layer.

47. Result vs Exception — bao giờ dùng cái nào?

  • Exception: lỗi thật sự bất ngờ (DB connection lost, OutOfMemory). Trường hợp ngoại lệ.
  • Result: business validation expected (email trùng, balance không đủ). Flow control bình thường.

Throw exception cho mọi business rule = chậm + signature mờ. Result cho luồng business, exception cho infra error.

48. Anemic Domain Model có phải anti-pattern?

Tranh cãi.

  • Martin Fowler gọi là anti-pattern: entity chỉ get/set, logic ở service → mất OOP encapsulation.
  • Phe DDD agree: Rich Domain Model tốt hơn — invariant trong entity.
  • Phe pragmatic không phản đối: với CRUD app, Anemic + service đơn giản hơn, không có gì sai.

→ Hiểu context. Domain phức tạp → Rich. CRUD đơn giản → Anemic OK.

F. Anti-patterns

49. God Class / God Object?

Class 2000+ dòng làm mọi thứ. Vi phạm SRP. Fix: tách theo trách nhiệm (entity, service, repository, formatter...).

50. Service Locator vs DI?

  • Service Locator: code tự Locator.Get<IFoo>() — hide dependency, khó test.
  • DI: inject qua constructor — dependency rõ ràng, là phần API.

DI tốt hơn nhiều. ASP.NET Core có IServiceProvider — đừng inject nó trừ trường hợp đặc biệt (factory).

51. Singleton lạm dụng — vấn đề gì?

Global state → khó test, hidden coupling, khó parallel. Thay bằng DI Singleton lifetime — vẫn 1 instance, nhưng test thay được.

52. Premature optimization?

Optimize trước khi có evidence chậm. Quote Knuth: "Premature optimization is the root of all evil". Code clear trước, đo bottleneck, mới tối ưu chỗ đó.

53. Reinventing the wheel?

Tự code feature framework đã có (cache, validation, retry). Tốn thời gian, bug-prone. ASP.NET Core / NestJS có sẵn rất nhiều — dùng built-in.

G. Câu scenario thực tế

54. Project bạn từng làm dùng pattern nào nổi bật?

Câu open-ended cực hot. Kể project thật:

  • "Em dùng Repository + Unit of Work trong project E-commerce dù EF Core đã là Repository, vì team có 4 dev cần restrict query reusable."
  • "Em apply CQRS + MediatR trong project Order System — write có nhiều validation, read là dashboard cần JOIN nhiều. MediatR pipeline cho logging + validation chung."
  • "Em dùng Strategy cho payment gateway — 3 provider (Stripe, VnPay, MoMo) implement IPaymentGateway, inject qua DI."

Tránh kể chung chung — phải có context cụ thể (project gì, vì sao chọn pattern đó, kết quả).

55. Bạn có dùng MediatR không? Vì sao?

Hai phía:

Pro:

  • Decouple controller khỏi service.
  • Cross-cutting concerns (logging, validation, transaction) qua pipeline behavior.
  • Dễ navigate — mỗi command/query 1 file.
  • Test handler dễ — input + output rõ.

Con:

  • Thêm layer indirection — tracing khó hơn.
  • Boilerplate cho action đơn giản.
  • "Magic" — newcomer khó hiểu flow.

Recent: tác giả MediatR (Jimmy Bogard) đã monetize lib → community chia rẽ, nhiều người chuyển sang manual handler hoặc lib khác (Mediator.SourceGenerator). Biết tin này là điểm cộng.

56. Khi gặp legacy code spaghetti — refactor pattern nào trước?

Bước thực tế:

  1. Extract Method — tách function nhỏ.
  2. Repository — tách data access.
  3. Service — tách business logic.
  4. DI — thay new ServiceA() bằng IServiceA inject.
  5. Sau đó mới đến pattern lớn (CQRS, Event Sourcing).

Đừng làm cách mạng — refactor từng bước, test mỗi bước.

57. Pattern bạn từng áp sai và phải gỡ?

Câu trick — admit mistake là điểm cộng. Ví dụ thật:

  • "Em áp Repository + UoW cho project nhỏ → 5 layer cho 1 endpoint CRUD. Sau gỡ về dùng DbContext trực tiếp, code gọn hơn 60%."
  • "Em làm Singleton cho service có state, sau phát hiện thread-safety issue → đổi sang Scoped."

58. Nhìn code có Strategy hard-code 3 case — sao biết dùng pattern?

// Mùi smell — if/else dài, sẽ grow
public decimal CalcShipping(Order o) {
    if (o.ShipMethod == "express") return o.Weight * 50000;
    if (o.ShipMethod == "standard") return o.Weight * 30000;
    if (o.ShipMethod == "economy") return o.Weight * 15000;
    throw new ArgumentException();
}

Khi:

  • if/else 3+ branch trên cùng type.
  • Mỗi case có algorithm riêng độc lập.
  • Sẽ thêm case nữa.

→ Apply Strategy. Mỗi case 1 class implement IShippingStrategy.

59. Pattern nào hay bị "over-engineering"?

  • Factory cho mọi class — UserFactory.Create() cho new User() thuần.
  • Repository wrap DbSet<T> 1-1.
  • CQRS cho CRUD đơn giản.
  • Microservice + Event Sourcing cho startup MVP.

→ Bắt đầu đơn giản, refactor khi đau.

60. Decorator vs Adapter vs Proxy — phân biệt?

Cấu trúc gần giống (cùng wrap object) nhưng ý đồ khác:

AdapterDecoratorProxy
Mục đíchĐổi interfaceThêm behaviorKiểm soát truy cập
Interface outputKhác inputGiống inputGiống input
Wrap nhiều cấpHiếmThường1 cấp
Ví dụLegacy → New APIStream chainLazy load, caching

61. SOLID nguyên lý nào liên hệ trực tiếp với DI?

Dependency Inversion Principle (D). DI là kỹ thuật thực thi DIP — high-level module depend abstraction, low-level cũng depend abstraction, DI container wire chúng lại runtime.

62. EF Core lazy loading proxy thuộc pattern nào?

Proxy pattern. EF Core generate class derived runtime, override navigation property để load related data khi truy cập. Bật bằng UseLazyLoadingProxies() + virtual keyword.

63. ASP.NET Core có những pattern nào built-in?

  • DI / IoC: built-in container.
  • Options: bind config.
  • Middleware: Chain of Responsibility.
  • Filter (action/exception filter): Decorator-like.
  • Mediator (qua MediatR — không built-in, nhưng cực phổ biến).
  • Background Service: IHostedService — Template Method.

Hiểu được những điều này = đọc source code framework dễ hơn nhiều.

Quay lại Ngân hàng câu hỏi hoặc xem Cheat Sheet.

Tham khảo

© 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.