Phần 1: ASP.NET Core Fundamentals (Cơ bản)
Câu 1: Middleware trong ASP.NET Core là gì?
Lời giải: Middleware là các thành phần (component) được kết nối thành một chuỗi (pipeline) để xử lý các request và response. Mỗi thành phần có thể chọn chuyển request sang thành phần tiếp theo hoặc xử lý xong và trả về luôn (short-circuiting).
Code Demo:
public void Configure(IApplicationBuilder app) {
app.Use(async (context, next) => {
// Xử lý trước khi đến Middleware tiếp theo
await next.Invoke();
// Xử lý sau khi Middleware tiếp theo chạy xong
});
app.Run(async context => await context.Response.WriteAsync("Hello World"));
}
Câu 2: Dependency Injection (DI) là gì? Có mấy loại Service Lifetime?
Lời giải: DI là một kỹ thuật giúp tách biệt việc khởi tạo đối tượng khỏi lớp sử dụng nó. Có 3 loại Lifetime:
Transient: Tạo mới mỗi khi được yêu cầu.
Scoped: Tạo một lần trong một phạm vi Request.
Singleton: Tạo một lần duy nhất cho toàn bộ vòng đời ứng dụng.
Code Demo:
builder.Services.AddTransient<ITransientService, TransientService>();
builder.Services.AddScoped<IScopedService, ScopedService>();
builder.Services.AddSingleton<ISingletonService, SingletonService>();
Câu 3: Sự khác biệt giữa app.Run(), app.Use() và app.Map()?
Lời giải: -
Use(): Thêm middleware vào pipeline, có thể gọi middleware tiếp theo.Run(): Thêm terminal middleware (ngắt pipeline, không gọi cái tiếp theo).Map(): Dùng để phân nhánh pipeline dựa trên đường dẫn (path).
Code Demo:
app.Map("/admin", adminApp => {
adminApp.Run(async context => await context.Response.WriteAsync("Admin Area"));
});
Câu 4: Kestrel Server là gì?
Lời giải: Kestrel là một web server mã nguồn mở, đa nền tảng, được tối ưu hóa cho ASP.NET Core. Nó thường được dùng làm "edge server" hoặc đứng sau một proxy như IIS hay Nginx.
Câu 5: Strong-typed Settings (Options Pattern) là gì?
Lời giải: Giúp map các cấu hình từ
appsettings.jsonvào các class C# để dễ quản lý và sử dụng DI.Code Demo:
// appsettings.json: { "MyConfig": { "Title": "Hello" } }
public class MyConfig { public string Title { get; set; } }
// Program.cs
builder.Services.Configure<MyConfig>(builder.Configuration.GetSection("MyConfig"));
Phần 2: Web API & MVC
Câu 6: IActionResult vs ActionResult<T>?
Lời giải:
IActionResulttrả về các HTTP Status Code linh hoạt.ActionResult<T>cho phép trả về cả kiểu dữ liệu cụ thểThoặc các HTTP Status, giúp hỗ trợ tài liệu API (Swagger) tốt hơn.Code Demo:
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id) {
var product = _service.Get(id);
if (product == null) return NotFound();
return product; // Tự động hiểu là Ok(product)
}
Câu 7: Routing trong ASP.NET Core có mấy loại?
Lời giải: 1. Conventional Routing: Định nghĩa tập trung trong
Program.cs. 2. Attribute Routing: Định nghĩa ngay tại Controller/Action bằng attribute[Route].Code Demo:
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase {
[HttpGet("{id}")] // Attribute routing
public IActionResult GetUser(int id) => Ok();
}
Câu 8: Filters trong ASP.NET Core là gì?
Lời giải: Filters cho phép chạy code trước hoặc sau các giai đoạn cụ thể của request processing. Các loại chính: Authorization, Resource, Action, Exception, Result filters.
Code Demo:
public class MyActionFilter : IActionFilter {
public void OnActionExecuting(ActionExecutingContext context) { /* Trước khi chạy Action */ }
public void OnActionExecuted(ActionExecutedContext context) { /* Sau khi chạy Action */ }
}
Câu 9: Model Binding hoạt động như thế nào?
Lời giải: Là quá trình ánh xạ dữ liệu từ HTTP Request (Query string, Route data, Form data, Body) vào tham số của Action.
Code Demo:
[HttpPost]
public IActionResult Create([FromBody] UserDto user) { ... }
Câu 10: [ApiController] attribute có tác dụng gì?
Lời giải: Nó kích hoạt các hành vi mặc định cho API: Tự động kiểm tra
ModelState.IsValid, tự động suy luận nguồn dữ liệu (Binding source), yêu cầu Attribute Routing.
Phần 3: Entity Framework Core (EF Core)
Câu 11: Eager Loading vs Lazy Loading?
Lời giải: - Eager Loading: Tải dữ liệu liên quan ngay lập tức bằng
.Include().Lazy Loading: Chỉ tải dữ liệu khi thuộc tính đó được truy cập lần đầu (cần cài proxy).
Code Demo:
// Eager Loading
var order = context.Orders.Include(o => o.Items).ToList();
Câu 12: DBContext Pooling là gì?
Lời giải: Giúp tái sử dụng các instance của DbContext thay vì khởi tạo mới liên tục, giúp tăng hiệu năng cho các ứng dụng có lưu lượng truy cập cao.
Code Demo:
builder.Services.AddDbContextPool<MyDbContext>(options =>
options.UseSqlServer(connectionString));
Câu 13: Làm thế nào để xử lý Concurrency trong EF Core?
Lời giải: Sử dụng
TimestamphoặcRowVersion. Khi update, EF Core sẽ kiểm tra version, nếu khác sẽ ném raDbUpdateConcurrencyException.Code Demo:
public class Product {
public int Id { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
Câu 14: Sự khác biệt giữa IEnumerable và IQueryable?
Lời giải: -
IEnumerable: Lọc dữ liệu trên bộ nhớ (In-memory). Tải hết dữ liệu về rồi mới lọc.IQueryable: Lọc dữ liệu tại Server (Database). Câu lệnh SQL được tạo ra bao gồm cả điều kiện lọc.
Câu 15: Migration trong EF Core là gì?
Lời giải: Là cách để cập nhật schema của database đồng bộ với code (Model) mà không làm mất dữ liệu.
Phần 4: Bảo mật (Security)
Câu 16: Authentication vs Authorization?
Lời giải: - Authentication: Xác minh "Bạn là ai?" (Login).
Authorization: Xác minh "Bạn có quyền làm gì?" (Permission).
Câu 17: JWT (JSON Web Token) gồm những phần nào?
Lời giải: Gồm 3 phần: Header (Thuật toán), Payload (Claims/Dữ liệu), Signature (Chữ ký số).
Câu 18: CORS (Cross-Origin Resource Sharing) là gì?
Lời giải: Là cơ chế bảo mật của trình duyệt ngăn chặn các trang web gửi request đến một domain khác với domain hiện tại trừ khi được cho phép.
Code Demo:
builder.Services.AddCors(opt => opt.AddPolicy("MyPolicy", policy => {
policy.WithOrigins("https://example.com").AllowAnyMethod();
}));
Câu 19: Làm thế nào để chống CSRF (Cross-Site Request Forgery)?
Lời giải: Sử dụng Anti-forgery tokens (thường dùng trong MVC/Razor Pages) hoặc yêu cầu header chứa token cho API.
Code Demo:
[ValidateAntiForgeryToken]
public IActionResult PostData() { ... }
Câu 20: Hashing mật khẩu trong .NET như thế nào?
Lời giải: Sử dụng
IPasswordHasher<TUser>(mặc định dùng PBKDF2) trong ASP.NET Core Identity.
Phần 5: Hiệu năng & Nâng cao
Câu 21: Task.WhenAll vs await từng Task?
Lời giải:
Task.WhenAllchạy các task song song, giúp giảm tổng thời gian xử lý so với việc chờ từng task một theo trình tự.Code Demo:
var task1 = service1.GetData();
var task2 = service2.GetData();
await Task.WhenAll(task1, task2);
Câu 22: Distributed Caching vs In-memory Caching?
Lời giải: - In-memory: Lưu tại RAM của app, nhanh nhất nhưng mất khi app restart hoặc khi scale nhiều instance.
Distributed (Redis/SQL): Lưu ở server riêng, dùng chung được cho nhiều instance app.
Câu 23: Background Tasks (Hosted Services) là gì?
Lời giải: Dùng để chạy các tác vụ ngầm định kỳ hoặc xử lý dài hạn mà không làm block request của người dùng.
Code Demo:
public class MyWorker : BackgroundService {
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
while (!stoppingToken.IsCancellationRequested) {
// Do work
await Task.Delay(1000, stoppingToken);
}
}
}
Câu 24: AsNoTracking() trong EF Core có tác dụng gì?
Lời giải: Nói với EF Core không theo dõi sự thay đổi của đối tượng. Giúp tăng tốc độ đọc dữ liệu (Read-only) vì không tốn tài nguyên quản lý trạng thái.
Câu 25: SignalR là gì?
Lời giải: Là thư viện cho phép giao tiếp thời gian thực (real-time) giữa server và client (WebSockets, Server-Sent Events).
Phần 6: Design Patterns & Architecture
Câu 26: Repository Pattern là gì?
Lời giải: Tạo lớp trung gian giữa Business Logic và Data Access, giúp dễ Unit Test và thay đổi nguồn dữ liệu.
Câu 27: Unit of Work là gì?
Lời giải: Đảm bảo nhiều thao tác database được thực hiện trong một Transaction duy nhất.
Câu 28: CQRS (Command Query Responsibility Segregation) là gì?
Lời giải: Tách biệt luồng đọc (Query) và luồng ghi (Command) để tối ưu hóa hiệu năng và bảo trì.
Câu 29: AutoMapper dùng để làm gì?
Lời giải: Tự động copy dữ liệu từ đối tượng này sang đối tượng khác (thường là Entity sang DTO).
Câu 30: SOLID Principles là gì? (Nêu ví dụ về 'D')
Lời giải: Là 5 nguyên tắc thiết kế phần mềm. 'D' (Dependency Inversion) nói rằng các module cấp cao không nên phụ thuộc module cấp thấp, cả hai nên phụ thuộc vào abstraction (Interface).
(Do giới hạn độ dài, tôi sẽ tóm lược tiếp 20 câu tiếp theo tập trung vào các tình huống thực tế thường gặp nhất)
Câu 31: Cách handle Exception toàn cục (Global Exception Handling)?
Sử dụng
UseExceptionHandlerhoặc Custom Middleware.
Câu 32: Fluent Validation là gì?
Thư viện giúp viết rule validate dữ liệu sạch sẽ hơn Data Annotations.
Câu 33: Health Checks trong ASP.NET Core?
Cung cấp endpoint (
/health) để các công cụ monitoring kiểm tra trạng thái app.
Câu 34: Minimal APIs là gì?
Cách viết API cực gọn trong .NET 6/7/8 mà không cần Controller.
Câu 35: Rate Limiting là gì?
Giới hạn số lượng request từ một user/IP trong một khoảng thời gian.
Câu 36: IHttpClientFactory là gì? Vì sao nên dùng nó thay vì new HttpClient()?
Quản lý vòng đời của HttpMessageHandler để tránh lỗi cạn kiệt socket (Socket exhaustion).
Câu 37: Sự khác biệt giữa .cshtml và .razor?
.cshtmldùng cho MVC/Razor Pages (Server-side rendering)..razordùng cho Blazor components.
Câu 38: Content Negotiation là gì?
Server chọn định dạng dữ liệu (JSON, XML) trả về dựa trên header
Acceptcủa client.
Câu 39: Dockerize một ứng dụng ASP.NET Core như thế nào?
Sử dụng
Dockerfilevới multi-stage build (build bằng SDK, chạy bằng Runtime).
Câu 40: Clean Architecture là gì?
Cấu trúc code theo các lớp (Domain, Application, Infrastructure, Web) hướng tâm, đảm bảo tính độc lập.
Câu 41: Patch vs Put?
PUT thay thế toàn bộ object. PATCH chỉ cập nhật một vài trường.
Câu 42: DTO (Data Transfer Object) là gì?
Đối tượng dùng để vận chuyển dữ liệu giữa các lớp hoặc qua mạng, giúp ẩn đi cấu trúc database.
Câu 43: Record type trong C#?
Dùng cho các đối tượng bất biến (Immutable), so sánh bằng giá trị thay vì tham chiếu.
Câu 44: Yield return là gì?
Tạo ra các phần tử của một tập hợp một cách lười biếng (Lazy evaluation).
Câu 45: Reflection là gì?
Khả năng kiểm tra và tương tác với metadata của code lúc runtime.
Câu 46: Middleware ngắt dòng (Short-circuiting) là gì?
Khi một middleware trả về kết quả ngay mà không gọi
next().
Câu 47: Static Files Middleware?
Cho phép truy cập các file trong thư mục
wwwroot.
Câu 48: Làm thế nào để versioning API?
Sử dụng URL (
/v1/), Query String, hoặc Header.
Câu 49: Ý nghĩa của file launchSettings.json?
Chứa cấu hình chạy app ở môi trường local (port, environment variables).
Câu 50: Sự khác biệt giữa .NET Framework và .NET (Core)?
Framework chỉ chạy Windows, cũ hơn. .NET Core/ .NET 5+ đa nền tảng, hiệu năng cao và hiện đại hơn.