Việc làm

16/09 · Hồ Chí Minh · Cần Thơ · Tại văn phòng

.NET Developer

CÔNG TY TNHH NEXTEDGE · Fullstack Developer

Xem mô tả & ứng tuyển trên ITviecMô tả công việc, lương và ứng tuyển nằm ở ITviec.

10 câu hỏi có thể gặp khi phỏng vấn

Chọn theo kỹ năng và cấp của tin (C# & .NET, JavaScript & TypeScript). Gợi ý trả lời do Drama Công Ty biên soạn để bạn ôn nhanh, không phải đề của công ty.

  1. 01Lỗi N+1 query trong Entity Framework Core là gì và xử lý thế nào?C# & .NET

    Gợi ý trả lời

    N+1 là khi lấy danh sách N bản ghi bằng 1 query, rồi mỗi bản ghi lại phát sinh thêm 1 query để lấy dữ liệu liên quan, thường do lazy loading hoặc truy vấn trong vòng lặp.

    Cách xử lý:

    • Eager loading: .Include(o => o.Items).
    • Tốt hơn nữa là projection chỉ lấy cột cần: .Select(o => new OrderDto(o.Id, o.Items.Count)).
    • Include nhiều collection gây "cartesian explosion" thì dùng .AsSplitQuery().
    • Màn hình chỉ đọc thì thêm .AsNoTracking() để giảm chi phí change tracking.

    Để phát hiện, bật log SQL của EF Core khi phát triển, hoặc dùng công cụ APM xem số query mỗi request.

    Người phỏng vấn muốn nghe: bạn kiểm tra SQL thực sự được sinh ra thay vì tin LINQ trông gọn là chạy nhanh.

    Ôn thêm câu hỏi C# & .NET →
  2. 02Garbage Collector của .NET hoạt động thế nào? Khi nào cần IDisposable?C# & .NET

    Gợi ý trả lời

    GC quản lý heap theo thế hệ: object mới ở Gen 0, sống sót qua lần thu gom thì lên Gen 1, Gen 2. Phần lớn object chết trẻ nên thu gom Gen 0 rất rẻ. Object lớn (khoảng từ 85 KB) vào Large Object Heap và chỉ được thu cùng Gen 2.

    GC chỉ thu hồi bộ nhớ managed. Tài nguyên khác như file, socket, kết nối DB cần giải phóng chủ động qua IDisposable:

    await using var conn = new NpgsqlConnection(cs);
    using var stream = File.OpenRead(path);
    
    • Finalizer chỉ là lưới an toàn, chạy không xác định thời điểm và tốn chi phí.

    Hay sai: tạo mới HttpClient cho mỗi request rồi dispose, dễ cạn socket. Hãy dùng IHttpClientFactory hoặc một instance dùng chung.

    Ôn thêm câu hỏi C# & .NET →
  3. 03Ứng dụng ASP.NET Core bị memory leak hoặc CPU cao trên production. Bạn điều tra thế nào?C# & .NET · Senior

    Gợi ý trả lời

    Thu thập số liệu trước, đoán sau: xem metrics, chụp dump hoặc trace, rồi phân tích.

    1. Theo dõi bằng dotnet-counters: heap size, số lần GC từng gen, thread pool queue length, exception rate.
    2. Leak bộ nhớ: chụp hai lần dotnet-gcdump hoặc dotnet-dump cách nhau một khoảng, so sánh loại object tăng và tìm ai đang giữ tham chiếu.
    3. CPU cao hoặc treo: dotnet-trace để xem hot path; thread pool queue tăng thường do sync-over-async.

    Nguyên nhân hay gặp: event handler không gỡ đăng ký, cache static không giới hạn kích thước, giữ DbContext quá lâu, regex hoặc serialize lặp lại trong vòng lặp nóng.

    Người phỏng vấn muốn nghe: một ca thực tế bạn từng xử lý, công cụ đã dùng và kết quả trước/sau.

    Ôn thêm câu hỏi C# & .NET →
  4. 04Debounce và throttle khác nhau thế nào? Mỗi cái dùng trong trường hợp nào?JavaScript & TypeScript

    Gợi ý trả lời

    Cả hai giới hạn số lần một hàm chạy khi sự kiện bắn liên tục.

    • Debounce: chỉ chạy sau khi sự kiện ngừng một khoảng thời gian. Hợp với ô tìm kiếm gợi ý (gõ xong mới gọi API), validate form, resize xong mới tính lại layout.
    • Throttle: chạy tối đa một lần mỗi khoảng thời gian. Hợp với scroll, kéo thả, theo dõi vị trí chuột.
    function debounce(fn, ms) {
      let timer;
      return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => fn(...args), ms);
      };
    }
    

    Hay sai: tạo hàm debounce mới mỗi lần render (trong React), khiến timer bị reset liên tục và debounce không có tác dụng. Với ô tìm kiếm, nhớ huỷ request cũ (AbortController) để kết quả cũ không đè kết quả mới.

    Ôn thêm câu hỏi JavaScript & TypeScript →
  5. 05Dùng generics và type narrowing trong TypeScript thế nào? Cho ví dụ discriminated union.JavaScript & TypeScript · Senior

    Gợi ý trả lời

    Generics giúp viết hàm và kiểu dùng lại được mà vẫn giữ thông tin kiểu, thay vì rơi về any.

    type Result<T> =
      | { ok: true; data: T }
      | { ok: false; error: string };
    
    function show(r: Result<User>) {
      if (r.ok) return r.data.name; // TS biết có data
      return r.error;
    }
    
    • Field chung (ok, type, status) giúp TypeScript thu hẹp kiểu trong if/switch. Đây là cách mô hình hoá trạng thái không thể sai: không có chuyện vừa có data vừa có error.
    • Ràng buộc generic: <T extends { id: string }>.
    • Utility types hay dùng: Partial, Pick, Omit, Record, ReturnType, Awaited.
    • Type guard tự viết: function isUser(x: unknown): x is User.

    Người phỏng vấn muốn nghe: bạn dùng kiểu để làm trạng thái sai không biểu diễn được, chứ không chỉ để chú thích.

    Ôn thêm câu hỏi JavaScript & TypeScript →
  6. 06Xử lý concurrency khi nhiều request cùng cập nhật một bản ghi trong EF Core thế nào?C# & .NET · Senior

    Gợi ý trả lời

    Hai hướng chính: optimistic concurrency (phát hiện xung đột khi lưu) và pessimistic (khoá trước khi sửa).

    Optimistic với EF Core: đánh dấu một cột làm concurrency token, EF thêm điều kiện so sánh vào UPDATE và ném DbUpdateConcurrencyException nếu không có dòng nào bị cập nhật.

    public class Product {
        public int Stock { get; set; }
        [Timestamp] public byte[] RowVersion { get; set; } = [];
    }
    
    • Bắt exception, tải lại dữ liệu, rồi retry hoặc báo người dùng.
    • PostgreSQL thường dùng cột hệ thống xmin làm token.
    • Trường hợp đơn giản như trừ tồn kho có thể dùng một câu ExecuteUpdateAsync atomic kèm điều kiện Stock >= qty.

    Người phỏng vấn muốn nghe: bạn cân nhắc mức độ tranh chấp: thấp thì optimistic, cao và nghiệp vụ quan trọng thì khoá hoặc đưa vào hàng đợi.

    Ôn thêm câu hỏi C# & .NET →
  7. 07Bạn tối ưu hiệu năng một Web API .NET chịu tải cao thế nào?C# & .NET · Senior

    Gợi ý trả lời

    Bắt đầu bằng đo đạc (load test, APM, profiler), sau đó xử lý các điểm nghẽn phổ biến theo thứ tự tác động.

    • I/O: async xuyên suốt, không sync-over-async; dùng connection pool đúng cách.
    • Database: projection, AsNoTracking, index đúng, tránh N+1; với bulk update dùng ExecuteUpdateAsync.
    • Cache: IMemoryCache, distributed cache (Redis), HybridCache từ .NET 9, output caching cho response công khai.
    • Cấp phát bộ nhớ: giảm object tạm trong hot path, dùng Span<T>, ArrayPool, System.Text.Json với source generator.
    • Hạ tầng: response compression, rate limiting middleware, scale ngang khi stateless.

    Luôn so sánh số liệu trước và sau (p95 latency, throughput, CPU, GC). Micro-optimize nên đo bằng BenchmarkDotNet.

    Hay sai: tối ưu code C# trong khi 90% thời gian nằm ở query DB.

    Ôn thêm câu hỏi C# & .NET →
  8. 08Bạn tổ chức một dự án .NET lớn thế nào? Clean Architecture có luôn cần thiết?C# & .NET · Senior

    Gợi ý trả lời

    Mục tiêu là tách nghiệp vụ khỏi chi tiết hạ tầng để dễ test và dễ thay đổi; mức độ tách nên tương xứng với độ phức tạp của dự án.

    Clean Architecture điển hình có các project: Domain (entity, rule), Application (use case, interface), Infrastructure (EF Core, gửi mail, gọi API ngoài), Api (controller hoặc minimal API). Phụ thuộc chỉ hướng vào trong.

    • Dịch vụ CRUD nhỏ thì cách tổ chức theo vertical slice (mỗi tính năng một thư mục) thường gọn hơn và ít boilerplate.
    • Tránh bọc thêm repository chung chung lên EF Core nếu nó chỉ chuyển tiếp lời gọi.
    • MediatR hay CQRS là công cụ, không phải yêu cầu bắt buộc.

    Người phỏng vấn muốn nghe: bạn hiểu trade-off giữa số lớp trừu tượng và tốc độ phát triển, và nêu được lý do cho lựa chọn trong dự án gần nhất.

    Ôn thêm câu hỏi C# & .NET →
  9. 09Why are you interested in this role?Phỏng vấn tiếng Anh

    Gợi ý trả lời

    "I've been working on payment systems for three years, and I'm really interested in building products at a larger scale. From the job description, your team is redesigning the transaction platform, which matches my experience and what I want to learn next. I also like that you have a strong engineering culture with code reviews and technical sharing. I believe I can contribute quickly and keep growing here."

    Mẹo: nối ba ý: kinh nghiệm của bạn, điều công ty đang làm, điều bạn muốn học. Dùng chi tiết từ JD để cho thấy bạn đã tìm hiểu. Tránh mở đầu bằng lương hay "because your company is big".

    Ôn thêm câu hỏi Phỏng vấn tiếng Anh →
  10. 10Bạn nghĩ sao về việc làm thêm giờ (OT)?Câu hỏi hành vi & văn hoá

    Gợi ý trả lời

    Trả lời thẳng thắn và cân bằng: sẵn sàng khi thật sự cần, nhưng không coi OT kéo dài là bình thường.

    Câu mẫu: "Em sẵn sàng làm thêm khi có việc gấp như sự cố production hay trước một đợt release quan trọng. Nhưng nếu OT diễn ra thường xuyên, em nghĩ cần xem lại cách estimate hoặc phạm vi, và em sẽ chủ động nêu điều đó với team. Em cũng muốn hỏi thêm: ở team mình OT thường xảy ra trong trường hợp nào và được tính như thế nào ạ?"

    Đây cũng là lúc bạn tìm hiểu ngược: OT có được trả lương hoặc nghỉ bù theo quy định không, tần suất ra sao. Câu trả lời của họ cho bạn biết nhiều về văn hoá công ty.

    Hay sai: hứa "OT thoải mái" để lấy điểm, rồi vào làm mới thấy không chịu nổi.

    Ôn thêm câu hỏi Câu hỏi hành vi & văn hoá →

Bạn đã phỏng vấn ở CÔNG TY TNHH NEXTEDGE?

Kể lại các vòng và câu hỏi đã gặp (ẩn danh) để người sau ôn đúng trọng tâm.

Chia sẻ kinh nghiệm phỏng vấn