Việc làm

08/10 · Hà Nội · Tại văn phòng

Thực tập sinh DEV

Blue Technology · 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, Python). 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. 01HashMap hoạt động bên trong như thế nào? So sánh ArrayList và LinkedList.Java · Junior

    Gợi ý trả lời

    HashMap là mảng các bucket. Khi put, nó tính hashCode() của key, suy ra chỉ số bucket, rồi lưu entry vào đó. Nhiều key trùng bucket thì nối thành danh sách; từ Java 8, khi một bucket quá dài thì chuyển thành cây đỏ đen để tránh tìm kiếm O(n).

    • Khi số phần tử vượt capacity * loadFactor (mặc định 0.75) thì map resize gấp đôi và phân bố lại.
    • get/put trung bình O(1). HashMap không thread-safe.

    ArrayList dựa trên mảng: truy cập theo index O(1), thêm cuối nhanh, chèn/xoá ở giữa phải dời phần tử. LinkedList là danh sách liên kết đôi: truy cập theo index O(n), tốn bộ nhớ hơn cho mỗi node.

    Người phỏng vấn muốn nghe: trên thực tế ArrayList gần như luôn nhanh hơn nhờ dữ liệu nằm liền nhau trong bộ nhớ (cache-friendly).

    Ôn thêm câu hỏi Java →
  2. 02Dependency 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 →
  3. 03@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 →
  4. 04Decorator hoạt động thế nào? Hãy viết một decorator đo thời gian chạy của hàm.Python

    Gợi ý trả lời

    Decorator là hàm nhận một hàm và trả về hàm mới bọc quanh nó. @timer chỉ là cú pháp ngắn của func = timer(func).

    import functools, time
    
    def timer(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            start = time.perf_counter()
            try:
                return func(*args, **kwargs)
            finally:
                print(func.__name__, time.perf_counter() - start)
        return wrapper
    
    • functools.wraps giữ lại __name__, docstring của hàm gốc, quan trọng cho log và debug.
    • Decorator có tham số (ví dụ @retry(times=3)) cần thêm một lớp hàm bên ngoài.
    • Ví dụ thực tế: @app.get của FastAPI, @login_required của Django, @functools.lru_cache.

    Hay sai: decorator viết kiểu đồng bộ bọc hàm async def. Kết quả là đo thời gian tạo coroutine chứ không phải thời gian chạy.

    Ôn thêm câu hỏi Python →
  5. 05GIL là gì? Vậy khi nào dùng threading, multiprocessing hay asyncio?Python

    Gợi ý trả lời

    GIL (Global Interpreter Lock) trong CPython chỉ cho một thread chạy bytecode Python tại một thời điểm. Vì vậy threading không tăng tốc tác vụ nặng CPU, nhưng vẫn hữu ích cho I/O vì GIL được nhả ra khi chờ mạng, đĩa.

    • I/O, số lượng vừa phải, thư viện blocking: threading hoặc ThreadPoolExecutor.
    • I/O rất nhiều kết nối đồng thời: asyncio với thư viện async (httpx, asyncpg).
    • Nặng CPU: multiprocessing hoặc ProcessPoolExecutor, hoặc dùng thư viện viết bằng C như NumPy (nhả GIL khi tính toán).

    Từ Python 3.13 có bản build free-threaded (không GIL) tuỳ chọn, nhưng chưa phải mặc định và còn phụ thuộc thư viện hỗ trợ.

    Người phỏng vấn muốn nghe: bạn phân biệt được bài toán I/O-bound và CPU-bound trước khi chọn công cụ.

    Ôn thêm câu hỏi Python →
  6. 06Lỗi N+1 query trong JPA/Hibernate là gì và xử lý ra sao?Java

    Gợi ý trả lời

    N+1 xảy ra khi bạn lấy N bản ghi bằng 1 query, rồi mỗi lần truy cập quan hệ lazy lại phát sinh thêm 1 query. Ví dụ lấy 100 đơn hàng, rồi gọi order.getCustomer() trong vòng lặp là thành 101 query.

    Cách xử lý:

    • JOIN FETCH trong JPQL: select o from Order o join fetch o.customer.
    • @EntityGraph(attributePaths = "customer") trên method của repository.
    • @BatchSize hoặc hibernate.default_batch_fetch_size để gom lazy load thành câu IN (...).
    • Với màn hình chỉ đọc, trả thẳng DTO projection thay vì entity.

    Phát hiện bằng cách bật log SQL (spring.jpa.show-sql hoặc log của Hibernate) khi dev, hoặc dùng thống kê của Hibernate.

    Hay sai: đổi sang FetchType.EAGER cho xong. Cách này chỉ đổi chỗ lỗi và làm mọi truy vấn khác nặng hơn. Fetch join nhiều collection cùng lúc cũng dễ gây tích Descartes.

    Ôn thêm câu hỏi Java →
  7. 07Bộ nhớ JVM gồm những vùng nào? Garbage Collector hoạt động ra sao và Java có bị memory leak không?Java

    Gợi ý trả lời

    Hai vùng chính: stack (mỗi thread một stack, chứa biến cục bộ và tham chiếu) và heap (chứa object, dùng chung). Ngoài ra có Metaspace chứa thông tin class.

    • GC tìm các object không còn được tham chiếu từ "GC roots" (biến trên stack, field static...) và thu hồi.
    • Heap chia theo thế hệ: object mới nằm ở young generation, sống lâu thì được chuyển lên old generation.
    • G1 là GC mặc định; ZGC hợp khi cần pause rất ngắn với heap lớn.

    Java vẫn leak khi object không dùng nữa mà vẫn còn tham chiếu:

    • Cache hoặc static Map chỉ thêm, không bao giờ xoá.
    • ThreadLocal không remove() trong thread pool.
    • Listener đăng ký mà không huỷ.

    Người phỏng vấn muốn nghe: phân biệt được OutOfMemoryError: Java heap space với lỗi Metaspace, và biết dùng heap dump để tìm ai đang giữ object.

    Ôn thêm câu hỏi Java →
  8. 08Phân biệt == và equals(). Vì sao override equals() thì phải override cả hashCode()?Java · Junior

    Gợi ý trả lời

    == so sánh tham chiếu (hai biến có trỏ cùng một object không), còn equals() so sánh nội dung theo logic bạn định nghĩa.

    • Hợp đồng: hai object equals nhau thì bắt buộc có cùng hashCode.
    • HashMap/HashSet dùng hashCode để chọn bucket trước, rồi mới dùng equals để so trong bucket. Nếu chỉ override equals, hai object "bằng nhau" có thể rơi vào hai bucket khác nhau, nên set.contains(x) trả về false dù đã add.
    • Với Java 16+, record tự sinh equals/hashCode/toString theo các field.

    Hay sai: so sánh String hoặc Integer bằng ==. Nó có thể chạy đúng nhờ string pool hoặc cache Integer từ -128 đến 127, rồi sai với giá trị khác.

    Ôn thêm câu hỏi Java →
  9. 09Trong Django ORM, lỗi N+1 query là gì? Phân biệt select_related và prefetch_related.Python

    Gợi ý trả lời

    N+1 là khi lấy danh sách bằng 1 query, rồi mỗi phần tử truy cập quan hệ lại sinh thêm 1 query. Ví dụ duyệt 50 bài viết và in post.author.name sẽ thành 51 query.

    • select_related: dùng SQL JOIN, cho quan hệ trỏ tới một object (ForeignKey, OneToOne).
    • prefetch_related: chạy query riêng rồi ghép trong Python, cho quan hệ nhiều (ManyToMany, reverse ForeignKey).
    posts = (Post.objects
             .select_related("author")
             .prefetch_related("tags"))
    

    Phát hiện bằng Django Debug Toolbar, hoặc assertNumQueries trong test.

    Hay sai: gọi .filter() trên quan hệ đã prefetch bên trong vòng lặp. Lệnh đó tạo query mới và bỏ qua dữ liệu prefetch; dùng Prefetch(..., queryset=...) để lọc ngay từ đầu.

    Ôn thêm câu hỏi Python →
  10. 10Bạn có quen làm việc remote hoặc hybrid không? Làm sao để làm việc hiệu quả khi không ở văn phòng?Câu hỏi hành vi & văn hoá

    Gợi ý trả lời

    Người phỏng vấn muốn biết bạn tự quản lý được và giao tiếp chủ động khi không ngồi cạnh team.

    • Cập nhật tiến độ thường xuyên trên công cụ chung (ticket, kênh chat của team), không để người khác phải hỏi.
    • Viết rõ ràng: câu hỏi có ngữ cảnh, ghi lại kết quả thảo luận.
    • Có khung giờ làm việc ổn định, phản hồi trong giờ làm, báo trước khi vắng.
    • Dùng ngày lên văn phòng (nếu hybrid) cho thảo luận, brainstorm, gặp gỡ team.

    Câu mẫu: "Team cũ của em làm hybrid hai ngày ở văn phòng. Những ngày remote em cập nhật trạng thái task mỗi sáng và cuối ngày, vướng gì thì gọi nhanh 10 phút thay vì nhắn qua lại."

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

Bạn đã phỏng vấn ở Blue Technology?

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