Phỏng vấn vị trí lập trình .NET ASP


  • 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:

C#
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"));
}
  • 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:

    1. Transient: Tạo mới mỗi khi được yêu cầu.

    2. Scoped: Tạo một lần trong một phạm vi Request.

    3. Singleton: Tạo một lần duy nhất cho toàn bộ vòng đời ứng dụng.

  • Code Demo:

C#
builder.Services.AddTransient<ITransientService, TransientService>();
builder.Services.AddScoped<IScopedService, ScopedService>();
builder.Services.AddSingleton<ISingletonService, SingletonService>();
  • 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:

C#
app.Map("/admin", adminApp => {
    adminApp.Run(async context => await context.Response.WriteAsync("Admin Area"));
});
  • 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.

  • Lời giải: Giúp map các cấu hình từ appsettings.json vào các class C# để dễ quản lý và sử dụng DI.

  • Code Demo:

C#
// appsettings.json: { "MyConfig": { "Title": "Hello" } }
public class MyConfig { public string Title { get; set; } }
// Program.cs
builder.Services.Configure<MyConfig>(builder.Configuration.GetSection("MyConfig"));

  • Lời giải: IActionResult trả về các HTTP Status Code linh hoạt. ActionResult<T> cho phép trả về cả kiểu dữ liệu cụ thể T hoặc các HTTP Status, giúp hỗ trợ tài liệu API (Swagger) tốt hơn.

  • Code Demo:

C#
[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)
}
  • 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:

C#
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase {
    [HttpGet("{id}")] // Attribute routing
    public IActionResult GetUser(int id) => Ok();
}
  • 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:

C#
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 */ }
}
  • 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:

C#
[HttpPost]
public IActionResult Create([FromBody] UserDto user) { ... }
  • 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.


  • 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:

C#
// Eager Loading
var order = context.Orders.Include(o => o.Items).ToList();
  • 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:

C#
builder.Services.AddDbContextPool<MyDbContext>(options => 
    options.UseSqlServer(connectionString));
  • Lời giải: Sử dụng Timestamp hoặc RowVersion. Khi update, EF Core sẽ kiểm tra version, nếu khác sẽ ném ra DbUpdateConcurrencyException.

  • Code Demo:

C#
public class Product {
    public int Id { get; set; }
    [Timestamp]
    public byte[] RowVersion { get; set; }
}
  • 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.

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


  • 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).

  • Lời giải: Gồm 3 phần: Header (Thuật toán), Payload (Claims/Dữ liệu), Signature (Chữ ký số).

  • 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:

C#
builder.Services.AddCors(opt => opt.AddPolicy("MyPolicy", policy => {
    policy.WithOrigins("https://example.com").AllowAnyMethod();
}));
  • 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:

C#
[ValidateAntiForgeryToken]
public IActionResult PostData() { ... }
  • Lời giải: Sử dụng IPasswordHasher<TUser> (mặc định dùng PBKDF2) trong ASP.NET Core Identity.


  • Lời giải: Task.WhenAll chạ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:

C#
var task1 = service1.GetData();
var task2 = service2.GetData();
await Task.WhenAll(task1, task2);
  • 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.

  • 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:

C#
public class MyWorker : BackgroundService {
    protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
        while (!stoppingToken.IsCancellationRequested) {
            // Do work
            await Task.Delay(1000, stoppingToken);
        }
    }
}
  • 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.

  • 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).


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

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

  • 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ì.

  • 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).

  • 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)

  • Sử dụng UseExceptionHandler hoặc Custom Middleware.

  • Thư viện giúp viết rule validate dữ liệu sạch sẽ hơn Data Annotations.

  • Cung cấp endpoint (/health) để các công cụ monitoring kiểm tra trạng thái app.

  • Cách viết API cực gọn trong .NET 6/7/8 mà không cần Controller.

  • Giới hạn số lượng request từ một user/IP trong một khoảng thời gian.

  • Quản lý vòng đời của HttpMessageHandler để tránh lỗi cạn kiệt socket (Socket exhaustion).

  • .cshtml dùng cho MVC/Razor Pages (Server-side rendering). .razor dùng cho Blazor components.

  • Server chọn định dạng dữ liệu (JSON, XML) trả về dựa trên header Accept của client.

  • Sử dụng Dockerfile với multi-stage build (build bằng SDK, chạy bằng Runtime).

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

  • PUT thay thế toàn bộ object. PATCH chỉ cập nhật một vài trường.

  • Đố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.

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

  • 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).

  • Khả năng kiểm tra và tương tác với metadata của code lúc runtime.

  • Khi một middleware trả về kết quả ngay mà không gọi next().

  • Cho phép truy cập các file trong thư mục wwwroot.

  • Sử dụng URL (/v1/), Query String, hoặc Header.

  • Chứa cấu hình chạy app ở môi trường local (port, environment variables).

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

Phản hồi từ học viên

5

Tổng 0 đánh giá
Developer Toolbox

TEXT CASE

FORMAT & CLEAN

ENCODE & DECODE

JSON & CRYPTO

Đã sao chép!!!
Gozic - Hệ thống học lập trình, luyện thi, kiểm tra trắc nghiệm trực tuyến uy tín tại Việt Nam.
Hotline: 0967025996
Gozic - Hệ thống học lập trình, luyện thi, kiểm tra trắc nghiệm trực tuyến uy tín tại Việt Nam.