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.
01Swift concurrency: async/await, Task, actor và @MainActor hoạt động thế nào?Mobile (Android, iOS, Flutter)
Gợi ý trả lời
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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 letvàTaskGroupchạy song song có cấu trúc. Task hỗ trợ huỷ hợp tác quaTask.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ảiawait.@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.02So 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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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.
03Danh 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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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 (
keytrongLazyColumn,ValueKeytrong Flutter,Identifiabletrong SwiftUI) để không tạo lại item không cần thiết. - Cập nhật một phần:
DiffUtil/ListAdapterthay vìnotifyDataSetChanged. - Compose: state ổn định để tránh recompose thừa; Flutter: dùng
ListView.buildervàconstwidget. - 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.
04Bạ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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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/Contexttrong 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ữ
selftrong khiselfgiữ closure, delegate khai báostrong. Dùng[weak self],weak var delegate. Phát hiện bằng Memory Graph Debugger và Instruments (Leaks, Allocations). - Flutter: quên
disposecontroller,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.
- Android: giữ
05Thiế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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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,
@Queryhoặ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.
- Lưu trữ: Room, SwiftData / Core Data, Drift hoặc Isar (Flutter). UI quan sát dữ liệu qua Flow,
06Bả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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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.
- Lưu token: Keychain (iOS), Keystore kết hợp EncryptedSharedPreferences hoặc DataStore mã hoá (Android),
07Chọ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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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.
08Trì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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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
onResumemà quên huỷ ởonPause, gây rò rỉ và hao pin. Trên Android nên thu thập Flow bằngrepeatOnLifecycle.- Android Activity:
09Là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
Ôn thêm câu hỏi Mobile (Android, iOS, Flutter) →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:
ViewModelsống qua thay đổi cấu hình nhưng không sống qua process death.SavedStateHandle(trong ViewModel) hoặcrememberSaveable(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ó
@SceneStoragecho 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 killkhi app ở background.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
Ôn thêm câu hỏi Câu hỏi hành vi & văn hoá →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."
Bạn đã phỏng vấn ở GoTymeX?
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