Việc làm

01/10 · Hồ Chí Minh · Hybrid

Frontend Engineer (ReactJS)

Hubble Pte. Ltd · Frontend 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 (ReactJS, JavaScript & TypeScript, AI / Machine Learning). 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. 01Stale closure trong React là gì? Vì sao setInterval trong useEffect cứ in ra giá trị cũ?ReactJS

    Gợi ý trả lời

    Mỗi lần render tạo ra hàm mới, "chụp" lại props và state của lần render đó. Nếu effect chỉ chạy một lần, callback bên trong mãi thấy giá trị lúc mount.

    useEffect(() => {
      const id = setInterval(() => {
        setCount(count + 1); // count luôn là 0
      }, 1000);
      return () => clearInterval(id);
    }, []);
    

    Cách sửa:

    • Dùng functional update: setCount(c => c + 1), không cần đọc count.
    • Khai báo đúng dependency (effect chạy lại khi giá trị đổi, nhớ cleanup).
    • Với giá trị chỉ cần đọc mới nhất mà không muốn chạy lại effect: lưu vào useRef.

    Hay sai: tắt cảnh báo exhaustive-deps của ESLint cho xong. Cảnh báo đó thường chính là dấu hiệu stale closure.

    Ôn thêm câu hỏi ReactJS →
  2. 02React Server Components là gì? Trong Next.js App Router, khi nào dùng Server Component và khi nào cần "use client"?ReactJS · Senior

    Gợi ý trả lời

    Server Component chạy trên server (lúc build hoặc lúc request), có thể await dữ liệu trực tiếp từ DB hoặc API, và không gửi JavaScript của nó xuống trình duyệt. Trong App Router, component mặc định là Server Component.

    • Dùng Server Component cho: lấy dữ liệu, render nội dung tĩnh, dùng secret hoặc thư viện nặng chỉ cần ở server.
    • Cần "use client" khi dùng state, effect, sự kiện (onClick), API trình duyệt (window, localStorage).
    • "use client" đánh dấu ranh giới: mọi module được import từ file đó đều vào bundle client.
    • Server Component có thể truyền Server Component khác vào Client Component qua children.
    • Props truyền từ server sang client phải serialize được (không truyền hàm thường; Server Action thì được).

    Hay sai: đặt "use client" ở layout gốc, biến cả app thành client và mất lợi ích. Hãy đẩy phần tương tác xuống các component lá.

    Ôn thêm câu hỏi ReactJS →
  3. 03Mộ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 →
  4. 04Dù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 →
  5. 05Một trang web dùng càng lâu càng chậm và tốn RAM. Bạn tìm memory leak ở frontend thế nào?JavaScript & TypeScript · Senior

    Gợi ý trả lời

    Memory leak ở frontend thường do thứ gì đó vẫn giữ tham chiếu đến object đáng lẽ đã bỏ đi, nhất là trong SPA vì trang không bao giờ tải lại.

    Nguyên nhân hay gặp:

    • addEventListener trên window/document mà không gỡ khi component bị huỷ.
    • setInterval, subscription (WebSocket, store) không huỷ.
    • DOM đã bị gỡ khỏi trang nhưng vẫn được biến JS giữ lại (detached DOM).
    • Cache hoặc mảng toàn cục chỉ tăng không giảm.

    Cách điều tra với Chrome DevTools:

    1. Tab Memory: chụp heap snapshot, thực hiện thao tác vài lần, chụp lại, so sánh phần tăng thêm.
    2. Lọc "Detached" để tìm DOM bị giữ, xem chuỗi retainers để biết ai đang giữ.
    3. Tab Performance bật Memory để xem heap có giảm sau GC không.

    Người phỏng vấn muốn nghe: mỗi tài nguyên đăng ký đều có chỗ huỷ tương ứng (cleanup của effect, ngOnDestroy, onUnmounted, AbortController).

    Ôn thêm câu hỏi JavaScript & TypeScript →
  6. 06Chi phí và độ trễ của ứng dụng LLM quá cao. Bạn tối ưu thế nào?AI / Machine Learning · Senior

    Gợi ý trả lời

    Đo trước: chi phí và độ trễ đến từ số token vào/ra, kích thước mô hình, số lần gọi trong một yêu cầu.

    • Chọn mô hình: định tuyến, việc dễ cho mô hình nhỏ, việc khó mới gọi mô hình lớn.
    • Giảm token: prompt gọn, truy xuất ít đoạn nhưng chính xác hơn (rerank), giới hạn độ dài đầu ra.
    • Prompt caching cho phần prompt cố định lặp lại; cache câu trả lời cho câu hỏi trùng.
    • Streaming để người dùng thấy chữ sớm, cải thiện độ trễ cảm nhận.
    • Gộp việc không gấp thành batch.
    • Tự host: quantization, batching động, engine suy luận tối ưu.

    Người phỏng vấn muốn nghe: mọi tối ưu đều kiểm tra lại bằng bộ eval để chắc chất lượng không giảm.

    Ôn thêm câu hỏi AI / Machine Learning →
  7. 07So 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 →
  8. 08React 19 có những gì mới đáng chú ý? Actions, useActionState và useOptimistic giải quyết vấn đề gì?ReactJS · Senior

    Gợi ý trả lời

    React 19 tập trung vào việc xử lý thao tác bất đồng bộ (gửi form, mutation) gọn hơn:

    • Actions: truyền hàm async vào <form action={fn}> hoặc chạy trong startTransition. React tự theo dõi trạng thái pending, lỗi, và reset form.
    • useActionState: giữ kết quả của action (thông báo lỗi, dữ liệu trả về) và cờ isPending.
    • useFormStatus: component con (nút submit) đọc trạng thái pending của form cha mà không cần truyền props.
    • useOptimistic: hiện kết quả ngay (like, thêm comment) trong lúc chờ server, tự quay về nếu lỗi.
    • use(): đọc Promise hoặc Context, gọi được trong điều kiện.
    • ref được truyền như prop thường, ít cần forwardRef.

    Người phỏng vấn muốn nghe: những API này bỏ bớt code tự quản lý isLoading, error và rollback, và kết hợp tự nhiên với Server Actions trong Next.js.

    Ôn thêm câu hỏi ReactJS →
  9. 09What would you say is your greatest strength?Phỏng vấn tiếng Anh

    Gợi ý trả lời

    "I'd say my greatest strength is ownership. When I take on a task, I make sure it works end to end, not just that the code is merged. For example, after releasing a new feature, I usually check the logs and metrics for the first few days. Last year this helped me catch a data issue early, before it affected many users."

    Mẹo: một điểm mạnh kèm một ví dụ ngắn là đủ. Các từ hay dùng: "ownership", "attention to detail", "problem-solving", "fast learner". Nói "I'd say…" nghe tự nhiên hơn "My strong point is…".

    Ôn thêm câu hỏi Phỏng vấn tiếng Anh →
  10. 10Vì sao bạn muốn rời công ty hiện tại?Câu hỏi hành vi & văn hoá

    Gợi ý trả lời

    Trả lời thật nhưng hướng về phía trước: nói điều bạn đang tìm kiếm, không kể xấu nơi cũ.

    Lý do chấp nhận được: muốn thử thách mới, muốn làm sản phẩm, dự án kết thúc, công ty tái cấu trúc, thu nhập chưa tương xứng (nói khéo).

    Câu mẫu: "Em đã làm 2 năm ở dự án outsourcing, học được nhiều về quy trình và làm việc với khách nước ngoài. Giờ em muốn gắn bó lâu dài với một sản phẩm để thấy được tác động của những gì mình làm, và vị trí bên mình đúng hướng đó."

    Hay sai: chê sếp, chê đồng nghiệp, kể chuyện drama. Người phỏng vấn sẽ nghĩ bạn cũng sẽ nói về công ty họ như vậy. Nếu nhảy việc nhiều, chuẩn bị lời giải thích cho từng lần.

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

Bạn đã phỏng vấn ở Hubble Pte. Ltd?

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