Việc làm

08/10 · Hồ Chí Minh · Hybrid

Staff Mobile Engineer (Android/iOS, Fluent in English)

GeoComply (GeoTech Hub Vietnam) · Software/Technical Architect

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. 01So sánh các kiến trúc MVC, MVVM, MVI/Clean Architecture cho ứng dụng mobile.Mobile (Android, iOS, Flutter)

    Gợi ý trả lời

    Mục tiêu chung là tách UI khỏi logic để dễ test và dễ bảo trì.

    • MVC: dễ bắt đầu nhưng trên iOS UIKit thường thành "Massive View Controller".
    • MVVM: ViewModel giữ state và logic, View chỉ quan sát và hiển thị. Hợp tự nhiên với SwiftUI, Jetpack Compose (ViewModel + StateFlow) và Flutter.
    • MVI / Unidirectional data flow: một state bất biến duy nhất cho màn hình, UI gửi intent, reducer tạo state mới. Dễ debug, hợp với UI khai báo.
    • Clean Architecture: chia layer presentation / domain / data, repository che giấu nguồn dữ liệu (API, cache, DB).

    Người phỏng vấn muốn nghe: lý do chọn kiến trúc cho dự án cụ thể. App nhỏ không cần đủ use case và mapper ở mọi tầng; app lớn nhiều team thì nên chia module theo tính năng.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  2. 02Danh 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) →
  3. 03Bạ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) →
  4. 04Thiế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) →
  5. 05Bả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) →
  6. 06Chọ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) →
  7. 07Kotlin coroutines: suspend function, scope, dispatcher và structured concurrency là gì?Mobile (Android, iOS, Flutter)

    Gợi ý trả lời

    Coroutine là tác vụ nhẹ có thể tạm dừng (suspend) mà không chặn thread. suspend fun chỉ gọi được từ coroutine hoặc từ suspend function khác.

    • Scope quyết định vòng đời: viewModelScope, lifecycleScope tự huỷ coroutine khi ViewModel hoặc màn hình bị huỷ.
    • Dispatcher quyết định chạy ở đâu: Main, IO, Default.
    • Structured concurrency: coroutine con gắn với cha; cha huỷ thì con huỷ, con lỗi thì lan lên cha (trừ khi dùng SupervisorJob).
    viewModelScope.launch {
        val user = withContext(Dispatchers.IO) { repo.fetchUser() }
        _state.value = UiState.Success(user)
    }
    

    Hay sai: dùng GlobalScope gây rò rỉ; bắt CancellationException trong catch (e: Exception) mà không ném lại, làm hỏng cơ chế huỷ.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  8. 08Swift concurrency: async/await, Task, actor và @MainActor hoạt động thế nào?Mobile (Android, iOS, Flutter)

    Gợi ý trả lời

    Swift concurrency đưa bất đồng bộ vào ngôn ngữ, cùng với kiểm tra data race lúc biên dịch (chặt hơn từ Swift 6).

    • async/await: viết code bất đồng bộ tuần tự, thay cho completion handler lồng nhau.
    • Task { } tạo tác vụ mới; async let và TaskGroup chạy song song có cấu trúc. Task hỗ trợ huỷ hợp tác qua Task.checkCancellation().
    • actor: kiểu tham chiếu mà trạng thái bên trong chỉ được truy cập tuần tự, tránh data race. Gọi từ ngoài phải await.
    • @MainActor: đảm bảo code chạy trên main thread, dùng cho ViewModel và UI.
    • Sendable: đánh dấu kiểu an toàn khi chuyển giữa các vùng concurrency.
    @MainActor final class ProfileViewModel: ObservableObject {
        @Published var user: User?
        func load() async { user = try? await api.fetchUser() }
    }
    

    Hay sai: actor reentrancy: sau mỗi await, trạng thái của actor có thể đã bị thay đổi.

    Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →
  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 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 ở GeoComply (GeoTech Hub Vietnam)?

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