Việc làm

2 ngày trước · Hồ Chí Minh · Tại văn phòng

Team Leader/ Technical Leader

TMA Solutions · 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 (Java, ReactJS, C/C++ & Embedded). 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. 01Virtual threads trong Java 21 là gì? Khi nào nên dùng và cần lưu ý gì?Java · Senior

    Gợi ý trả lời

    Virtual thread là thread nhẹ do JVM quản lý, được gắn lên một số ít platform thread (carrier). Khi gặp I/O blocking, nó nhả carrier để chạy việc khác, nên bạn có thể có hàng trăm nghìn thread mà vẫn viết code blocking dễ đọc.

    try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
        ids.forEach(id -> executor.submit(() -> callApi(id)));
    }
    
    • Hợp với tải nhiều I/O (gọi DB, HTTP). Không giúp gì với tác vụ nặng CPU.
    • Spring Boot 3.2+ bật bằng spring.threads.virtual.enabled=true.
    • Không đưa virtual thread vào pool: tạo mới cho mỗi task là cách dùng đúng.
    • Giới hạn tài nguyên (connection pool DB) vẫn là giới hạn thật; dùng Semaphore nếu cần.
    • Trên Java 21, blocking bên trong synchronized có thể "pin" carrier; các bản JDK mới hơn đã cải thiện. Cẩn thận với ThreadLocal chứa object lớn.

    Người phỏng vấn muốn nghe: virtual threads tăng throughput, không làm từng request nhanh hơn.

    Ôn thêm câu hỏi Java →
  2. 02So sánh synchronized, volatile, ReentrantLock và ConcurrentHashMap. Bạn tránh race condition thế nào?Java · Senior

    Gợi ý trả lời

    Race condition xảy ra khi nhiều thread đọc-sửa-ghi cùng dữ liệu mà không đồng bộ. Mỗi công cụ giải quyết một phần:

    • volatile: đảm bảo visibility (thread khác thấy giá trị mới nhất), nhưng không làm count++ thành atomic.
    • synchronized: vừa loại trừ lẫn nhau vừa đảm bảo visibility (quan hệ happens-before).
    • ReentrantLock: như synchronized nhưng có tryLock với timeout, lock có thể ngắt, nhiều Condition.
    • AtomicInteger/LongAdder: đếm không cần lock.
    • ConcurrentHashMap: thread-safe với độ tranh chấp thấp. Dùng compute/merge/putIfAbsent cho thao tác kép, đừng get rồi put.

    Hay sai: dùng Collections.synchronizedMap rồi duyệt map mà không lock, hoặc kiểm tra if (!map.containsKey(k)) map.put(k, v) trên map đồng thời: hai bước riêng lẻ vẫn bị chen ngang. Cách tốt nhất vẫn là giảm state dùng chung (object bất biến, mỗi thread một bản).

    Ôn thêm câu hỏi Java →
  3. 03Một service Spring Boot trên production đột nhiên chậm, CPU cao hoặc bị OOM. Bạn điều tra thế nào?Java · Senior

    Gợi ý trả lời

    Đi từ số liệu đến bằng chứng, đừng đoán rồi sửa.

    1. Xem metrics (Actuator, Micrometer): latency, số request, heap, GC pause, connection pool đang chờ, thời gian gọi DB và API ngoài.
    2. CPU cao: lấy thread dump vài lần cách nhau vài giây (jcmd <pid> Thread.print hoặc jstack), tìm thread luôn RUNNABLE ở cùng chỗ. Có thể là vòng lặp, regex xấu, hoặc GC chạy liên tục.
    3. Chậm mà CPU thấp: thread đang chờ: hết connection DB, lock, gọi API ngoài không có timeout.
    4. OOM hoặc heap tăng dần: bật -XX:+HeapDumpOnOutOfMemoryError, mở heap dump bằng Eclipse MAT, xem ai giữ nhiều bộ nhớ nhất.
    5. Java Flight Recorder (jcmd <pid> JFR.start) cho profile chi phí thấp, dùng được trên production.

    Người phỏng vấn muốn nghe: có quy trình rõ ràng, biết cả cách giảm thiệt hại tạm thời (rollback, scale) trước khi tìm nguyên nhân gốc.

    Ôn thêm câu hỏi Java →
  4. 04Một màn hình React (bảng dữ liệu lớn, ô tìm kiếm) bị giật lag. Bạn tìm và xử lý thế nào?ReactJS · Senior

    Gợi ý trả lời

    Đo trước: React DevTools Profiler (bật "Highlight updates" và xem component nào render nhiều, tốn bao lâu) và tab Performance của Chrome để tìm long task.

    Các hướng xử lý thường gặp:

    • Giảm phạm vi render: đưa state xuống gần nơi dùng; tách component; memo các hàng của bảng với props ổn định.
    • Virtualization cho list hoặc bảng dài: chỉ render các dòng đang hiện (TanStack Virtual, react-window).
    • Ưu tiên cập nhật: useDeferredValue hoặc useTransition để ô input phản hồi ngay, còn việc lọc bảng chạy sau và có thể bị ngắt.
    • Tính toán nặng: useMemo, hoặc chuyển sang Web Worker.
    • Bundle lớn: lazy() và Suspense để tách code theo route hoặc theo modal.

    Người phỏng vấn muốn nghe: bạn tìm ra nguyên nhân cụ thể (render thừa, DOM quá nhiều, JS nặng) rồi mới chọn kỹ thuật, không rải useMemo khắp nơi.

    Ôn thêm câu hỏi ReactJS →
  5. 05So sánh CSR, SSR, SSG và ISR. Lỗi hydration mismatch là gì và xử lý ra sao?ReactJS · Senior

    Gợi ý trả lời

    • CSR: trình duyệt tải JS rồi mới render; nội dung hiện chậm, kém cho SEO.
    • SSR: server render HTML cho mỗi request. Dữ liệu luôn mới, tốn tài nguyên server.
    • SSG: render sẵn lúc build. Rất nhanh, hợp nội dung ít đổi.
    • ISR / revalidate: trang tĩnh được làm mới định kỳ hoặc theo sự kiện.

    Hydration là bước React gắn sự kiện vào HTML do server render. Mismatch xảy ra khi lần render đầu ở client khác HTML từ server:

    • Dùng Date.now(), Math.random(), múi giờ, window hoặc localStorage trong lúc render.
    • HTML lồng sai (<div> trong <p>), extension trình duyệt sửa DOM.

    Cách sửa: chuyển phần chỉ có ở client vào useEffect, hoặc render component đó chỉ ở client; định dạng ngày giờ bằng múi giờ cố định.

    Người phỏng vấn muốn nghe: bạn chọn cách render theo từng trang, dựa trên độ tươi dữ liệu và nhu cầu SEO.

    Ôn thêm câu hỏi ReactJS →
  6. 06Lập trình đa luồng trong C++ hiện đại: std::atomic, mutex và memory order dùng khi nào?C/C++ & Embedded · Senior

    Gợi ý trả lời

    Dữ liệu chia sẻ giữa các thread mà có ít nhất một thread ghi thì phải đồng bộ, nếu không là data race (undefined behavior).

    • std::mutex với std::lock_guard hoặc std::scoped_lock (khoá nhiều mutex không deadlock): dùng cho vùng găng có nhiều biến hoặc logic phức tạp.
    • std::atomic<T>: cho biến đơn lẻ như cờ, bộ đếm, không cần khoá.
    • Memory order: mặc định seq_cst an toàn nhất. acquire/release dùng cho mẫu producer/consumer; relaxed chỉ cho bộ đếm thống kê không cần thứ tự.
    • C++20 bổ sung std::jthread (tự join, có stop token), std::latch, std::barrier, std::counting_semaphore.
    std::atomic<int> hits{0};
    hits.fetch_add(1, std::memory_order_relaxed);
    

    Hay sai: dùng memory order yếu khi chưa thật hiểu, hoặc lock-free hoá sớm khi mutex đã đủ nhanh. Kiểm tra bằng ThreadSanitizer.

    Ôn thêm câu hỏi C/C++ & Embedded →
  7. 07Hai người cùng đặt mua sản phẩm cuối cùng trong kho. Bạn xử lý cập nhật đồng thời trong JPA thế nào?Java · Senior

    Gợi ý trả lời

    Đây là bài toán lost update. Có hai hướng chính, chọn theo mức độ tranh chấp:

    • Optimistic locking: thêm field @Version. Khi update, Hibernate kèm điều kiện where version = ?; nếu người khác đã sửa trước, bạn nhận OptimisticLockException và có thể retry hoặc báo lỗi. Hợp khi tranh chấp ít.
    • Pessimistic locking: @Lock(LockModeType.PESSIMISTIC_WRITE) sinh SELECT ... FOR UPDATE, giữ khoá đến hết transaction. Hợp khi tranh chấp nhiều, đổi lại throughput giảm và có nguy cơ deadlock.
    • Đơn giản nhất cho tồn kho: update có điều kiện ngay trong DB:
    UPDATE product SET stock = stock - 1
    WHERE id = ? AND stock > 0;
    

    Kiểm tra số dòng bị ảnh hưởng: bằng 0 nghĩa là hết hàng.

    Hay sai: dùng synchronized trong code Java. Nó vô dụng khi chạy nhiều instance, và cũng không bảo vệ được dữ liệu ở DB.

    Ôn thêm câu hỏi Java →
  8. 08Dependency Injection trong Spring là gì? Vì sao nên dùng constructor injection thay cho @Autowired trên field?Java

    Gợi ý trả lời

    IoC container của Spring tạo và quản lý các bean, rồi "tiêm" phụ thuộc vào class cần dùng, thay vì class tự new. Nhờ vậy code ít phụ thuộc cứng, dễ thay implementation và dễ test.

    Constructor injection được khuyên dùng vì:

    • Field có thể là final, object luôn ở trạng thái đầy đủ sau khi tạo.
    • Test unit không cần Spring: chỉ cần new OrderService(mockRepo).
    • Constructor quá nhiều tham số là dấu hiệu class đang ôm nhiều việc.
    • Class chỉ có một constructor thì không cần ghi @Autowired.

    Nên nói thêm về scope: mặc định bean là singleton (một instance cho cả context), ngoài ra có prototype, request, session.

    Hay sai: để state thay đổi được (ví dụ biến đếm, list) trong bean singleton. Nhiều request chạy song song sẽ dùng chung và gây race condition.

    Ôn thêm câu hỏi Java →
  9. 09@Transactional hoạt động thế nào? Vì sao có lúc gắn annotation rồi mà transaction không chạy?Java

    Gợi ý trả lời

    Spring tạo proxy bao quanh bean. Khi gọi method có @Transactional qua proxy, proxy mở transaction, gọi method thật, rồi commit hoặc rollback.

    Những lý do hay gặp khiến nó "không ăn":

    • Self-invocation: method A trong cùng class gọi this.b() có @Transactional, lời gọi không đi qua proxy.
    • Method là private hoặc final: proxy không chặn được lời gọi.
    • Mặc định chỉ rollback với unchecked exception và Error. Checked exception vẫn commit, trừ khi khai báo rollbackFor = Exception.class.
    • Exception bị catch và nuốt bên trong method.

    Nên biết thêm propagation (REQUIRED, REQUIRES_NEW) và readOnly = true cho các truy vấn chỉ đọc.

    Người phỏng vấn muốn nghe: bạn giải thích được bằng cơ chế proxy, không chỉ liệt kê lỗi.

    Ôn thêm câu hỏi Java →
  10. 10Bạn phản ứng thế nào khi nhận góp ý tiêu cực về công việc của mình?Câu hỏi hành vi & văn hoá

    Gợi ý trả lời

    Cho thấy bạn tách góp ý khỏi cảm xúc cá nhân và biến nó thành hành động.

    • Lắng nghe hết, hỏi lại để hiểu ví dụ cụ thể và kỳ vọng.
    • Cảm ơn, kể cả khi chưa đồng ý hoàn toàn; nếu có góc nhìn khác, trao đổi bằng thông tin, không phòng thủ.
    • Lên kế hoạch cải thiện và chủ động xin phản hồi lại sau một thời gian.

    Câu mẫu: "Có lần lead góp ý code review của em quá dài, khó review. Lúc đầu em hơi chột dạ, nhưng em hỏi anh muốn chia thế nào cho dễ. Từ đó em tách pull request nhỏ theo từng thay đổi, thời gian review của team giảm hẳn và em cũng ít bị yêu cầu sửa lại hơn."

    Hay sai: nói "em luôn vui vẻ đón nhận mọi góp ý" mà không có ví dụ.

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

Bạn đã phỏng vấn ở TMA Solutions?

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