Việc làm

02/10 · Hồ Chí Minh · Remote

[Remote] Mobile Game Developer (Upto $2,000)

Ateam Việt Nam · Game 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 (Mobile (Android, iOS, Flutter)). 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. 01Danh sách dài (RecyclerView, LazyColumn, List, ListView) bị giật khi cuộn. Bạn tối ưu thế nào?Mobile (Android, iOS, Flutter)

    Gợi ý trả lời

    Trước tiên đo bằng công cụ (Android Studio Profiler, Instruments, Flutter DevTools), sau đó xử lý các nguyên nhân phổ biến:

    • Ảnh: tải bất đồng bộ, resize đúng kích thước hiển thị, có cache (Coil, Glide, Kingfisher, cached_network_image).
    • Công việc trong bind/build: không format ngày, parse dữ liệu hay tính toán mỗi lần vẽ item; chuẩn bị sẵn trong ViewModel.
    • Key ổn định: dùng id làm key (key trong LazyColumn, ValueKey trong Flutter, Identifiable trong SwiftUI) để không tạo lại item không cần thiết.
    • Cập nhật một phần: DiffUtil / ListAdapter thay vì notifyDataSetChanged.
    • Compose: state ổn định để tránh recompose thừa; Flutter: dùng ListView.builder và const widget.
    • Phân trang dữ liệu (Paging 3, infinite scroll).

    Người phỏng vấn muốn nghe: bạn đo trước và sau, không chỉ sửa theo cảm tính.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  2. 02Bạn phát hiện và xử lý memory leak trong ứng dụng mobile thế nào?Mobile (Android, iOS, Flutter) · Senior

    Gợi ý trả lời

    Leak trên mobile thường do một object sống lâu giữ tham chiếu tới object lẽ ra phải được giải phóng, như màn hình, view hay context.

    • Android: giữ Activity/Context trong singleton hoặc biến static, listener không huỷ đăng ký, coroutine hoặc callback sống lâu hơn màn hình. Phát hiện bằng LeakCanary và Memory Profiler (heap dump).
    • iOS: ARC không tự phá được retain cycle, vd. closure giữ self trong khi self giữ closure, delegate khai báo strong. Dùng [weak self], weak var delegate. Phát hiện bằng Memory Graph Debugger và Instruments (Leaks, Allocations).
    • Flutter: quên dispose controller, StreamSubscription, Timer. Xem bằng DevTools Memory.

    Người phỏng vấn muốn nghe: quy trình tái hiện (mở rồi đóng màn hình nhiều lần, xem số instance có giảm không) và một ca bạn đã sửa thật.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  3. 03Thiết kế tính năng offline-first: app vẫn dùng được khi mất mạng và đồng bộ khi có mạng lại.Mobile (Android, iOS, Flutter) · Senior

    Gợi ý trả lời

    Lấy database cục bộ làm nguồn sự thật cho UI: UI chỉ đọc từ DB local, tầng sync lo việc đồng bộ với server.

    • Lưu trữ: Room, SwiftData / Core Data, Drift hoặc Isar (Flutter). UI quan sát dữ liệu qua Flow, @Query hoặc Stream.
    • Ghi khi offline: lưu thay đổi vào hàng đợi (outbox) kèm trạng thái pending; khi có mạng thì gửi lên, nhận phản hồi rồi đánh dấu đã đồng bộ.
    • Lập lịch đồng bộ: WorkManager (Android), BGTaskScheduler (iOS), có ràng buộc mạng và backoff khi lỗi.
    • Xung đột: chọn chiến lược như last-write-wins theo timestamp server, version number, hoặc cho người dùng chọn với dữ liệu quan trọng.
    • Request cần idempotent (gửi kèm id do client sinh) để retry không tạo bản ghi trùng.

    Người phỏng vấn muốn nghe: bạn tính tới đồng bộ từng phần (delta sync) và cách hiển thị trạng thái "chưa đồng bộ" cho người dùng.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  4. 04Bảo mật ứng dụng mobile: lưu token, gọi API và chống dịch ngược thế nào?Mobile (Android, iOS, Flutter) · Senior

    Gợi ý trả lời

    Coi app là môi trường không tin cậy: mọi thứ đóng gói trong app đều có thể bị đọc, nên kiểm soát quan trọng nhất phải nằm ở server.

    • Lưu token: Keychain (iOS), Keystore kết hợp EncryptedSharedPreferences hoặc DataStore mã hoá (Android), flutter_secure_storage. Không lưu trong SharedPreferences / UserDefaults thường hay log ra console.
    • Phiên đăng nhập: access token ngắn hạn, refresh token xoay vòng; đăng nhập OAuth dùng PKCE.
    • Mạng: chỉ HTTPS; có thể dùng certificate pinning nhưng cần kế hoạch xoay chứng chỉ.
    • Secret: không nhúng API key quan trọng trong app; gọi qua backend.
    • Chống can thiệp: obfuscation (R8), Play Integrity API, App Attest để server xác minh app thật.

    Hay sai: tin rằng obfuscation là đủ. Nó chỉ làm chậm kẻ tấn công.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  5. 05Chọn native (Kotlin/Swift) hay cross-platform (Flutter, React Native) cho một dự án mới? Bạn cân nhắc gì?Mobile (Android, iOS, Flutter) · Senior

    Gợi ý trả lời

    Không có đáp án chung; quyết định dựa trên yêu cầu sản phẩm, đội ngũ và chi phí dài hạn.

    • Cross-platform (Flutter, React Native, hoặc Kotlin Multiplatform để chia sẻ logic): một codebase cho hai nền tảng, ra mắt nhanh, hợp với app nghiệp vụ, thương mại điện tử, nội bộ.
    • Native: cần tích hợp sâu với hệ điều hành (widget, camera hoặc Bluetooth phức tạp, xử lý nền), hiệu năng đồ hoạ cao, hoặc muốn dùng tính năng mới của OS ngay khi ra mắt.

    Các yếu tố cần cân nhắc:

    • Kỹ năng hiện có của team và khả năng tuyển người.
    • Mức độ tuỳ biến UI theo từng nền tảng.
    • Chi phí viết plugin native khi thư viện không có sẵn.
    • Kích thước app và thời gian khởi động.

    Người phỏng vấn muốn nghe: bạn đưa ra lập luận gắn với bối cảnh cụ thể và nhắc tới phương án lai, vd. thêm màn hình Flutter vào app native.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  6. 06Trình bày vòng đời (lifecycle) của Activity trên Android hoặc của app/view trên iOS.Mobile (Android, iOS, Flutter) · Junior

    Gợi ý trả lời

    Vòng đời cho biết khi nào hệ điều hành tạo, hiển thị, tạm dừng và huỷ màn hình, để bạn khởi tạo và giải phóng tài nguyên đúng lúc.

    • Android Activity: onCreate → onStart → onResume (đang tương tác) → onPause → onStop → onDestroy. Xoay màn hình mặc định sẽ huỷ và tạo lại Activity.
    • iOS UIKit: viewDidLoad (một lần) → viewWillAppear → viewDidAppear → viewWillDisappear → viewDidDisappear. Trạng thái app: active, inactive, background.
    • SwiftUI / Compose: nghĩ theo state và các hook như .task, onAppear, LaunchedEffect, DisposableEffect.

    Hay sai: đăng ký listener hoặc sensor trong onResume mà quên huỷ ở onPause, gây rò rỉ và hao pin. Trên Android nên thu thập Flow bằng repeatOnLifecycle.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  7. 07Làm sao giữ dữ liệu khi xoay màn hình hoặc khi app bị hệ điều hành kill ở background?Mobile (Android, iOS, Flutter) · Junior

    Gợi ý trả lời

    Có hai tình huống khác nhau: thay đổi cấu hình (xoay màn hình, đổi ngôn ngữ) và process death (hệ điều hành kill app để lấy RAM).

    Android:

    • ViewModel sống qua thay đổi cấu hình nhưng không sống qua process death.
    • SavedStateHandle (trong ViewModel) hoặc rememberSaveable (Compose) lưu trạng thái nhỏ như id, nội dung form, vị trí cuộn.
    • Dữ liệu lớn hoặc quan trọng lưu bền vững bằng Room hoặc DataStore.

    iOS: SwiftUI có @SceneStorage cho trạng thái UI nhỏ; UIKit có state restoration; dữ liệu thật lưu bằng SwiftData, Core Data hoặc file.

    Người phỏng vấn muốn nghe: bạn biết cách kiểm thử process death, vd. bật "Don't keep activities" hoặc dùng adb shell am kill khi app ở background.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  8. 08Trong Flutter, StatelessWidget và StatefulWidget khác nhau thế nào? setState hoạt động ra sao?Mobile (Android, iOS, Flutter) · Junior

    Gợi ý trả lời

    StatelessWidget chỉ phụ thuộc tham số đầu vào; StatefulWidget có một object State riêng, tồn tại qua các lần build, để giữ dữ liệu thay đổi theo thời gian.

    • setState đánh dấu widget "dirty"; ở frame kế tiếp Flutter gọi lại build cho widget đó và cây con.
    • Widget là cấu hình nhẹ, tạo lại liên tục; Element và RenderObject mới là phần được tái sử dụng.
    • Dọn dẹp controller, stream subscription trong dispose.
    void _increment() => setState(() => _count++);
    

    Hay sai: gọi setState sau khi widget đã bị huỷ (sau một await); hãy kiểm tra mounted. Đặt setState ở widget quá cao làm build lại cả màn hình, nên tách nhỏ widget và dùng const constructor.

    Khi state dùng chung nhiều màn hình, chuyển sang Provider, Riverpod hoặc Bloc.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  9. 09Vì sao không được làm việc nặng trên main thread (UI thread)? Bạn xử lý thế nào?Mobile (Android, iOS, Flutter) · Junior

    Gợi ý trả lời

    Main thread vẽ UI và nhận thao tác người dùng. Mỗi frame chỉ có khoảng 16 ms (60 Hz) hoặc ít hơn với màn 120 Hz, nên việc nặng sẽ gây giật, lag; Android chặn quá lâu sẽ báo ANR.

    Cách xử lý theo nền tảng:

    • Android: coroutines với Dispatchers.IO cho I/O, Dispatchers.Default cho tính toán, sau đó cập nhật state trên Main.
    • iOS: async/await với Swift concurrency; code UI đánh dấu @MainActor.
    • Flutter: Dart chạy một isolate; I/O bất đồng bộ không chặn, nhưng tính toán nặng (parse JSON lớn, xử lý ảnh) nên đẩy sang isolate khác bằng Isolate.run hoặc compute.

    Hay sai: nghĩ async là đủ. Hàm async trong Dart vẫn chạy trên cùng isolate, nên vòng lặp tính toán nặng vẫn làm đơ UI.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  10. 10Bạn làm việc thế nào khi áp lực cao hoặc deadline gấp?Câu hỏi hành vi & văn hoá

    Gợi ý trả lời

    Cho thấy bạn có cách làm cụ thể, không chỉ nói "em chịu được áp lực".

    • Chia nhỏ việc, ưu tiên phần quan trọng nhất cho mục tiêu.
    • Báo sớm cho lead/PM nếu thấy không kịp, đề xuất cắt phạm vi hoặc xin hỗ trợ.
    • Giữ chất lượng ở phần cốt lõi; ghi lại nợ kỹ thuật để xử lý sau.
    • Giữ bình tĩnh, giao tiếp ngắn gọn, rõ ràng với team.

    Câu mẫu theo STAR: "Trước buổi demo cho khách, team phát hiện lỗi tích hợp chỉ còn hai ngày. Em liệt kê các phần bị ảnh hưởng, cùng PM chọn luồng nào bắt buộc phải chạy cho demo, phần còn lại hẹn bàn giao tuần sau. Demo diễn ra suôn sẻ và khách đồng ý với lịch mới."

    Hay sai: khoe thức trắng nhiều đêm. Người phỏng vấn muốn thấy bạn quản lý được áp lực, không chỉ chịu đựng.

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

Bạn đã phỏng vấn ở Ateam Việt Nam?

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