Phỏng Vấn Mobile Developer (iOS & Android): 10 Câu Hỏi Kỹ Thuật - App Mượt Hay App Giật Lag Là Do Bạn
Mục lục bài viết
Bạn tự tin viết code iOS bằng Swift, Android bằng Kotlin. Bạn đã build hàng chục app, deploy lên store nhiều lần. Nhưng khi ngồi vào phòng phỏng vấn, một câu hỏi đơn giản thôi - "Ứng dụng của bạn khởi động mất bao lâu, và bạn đã tối ưu thế nào?" - lại khiến bạn lúng túng.
Đó là ranh giới giữa một lập trình viên "biết làm" và một lập trình viên "hiểu tại sao". 10 câu hỏi dưới đây được tuyển chọn từ thực tế phỏng vấn cấp senior tại nhiều công ty, từ startup đến tập đoàn lớn. Trả lời được 7/10, bạn đã có nền tảng vững để bước vào bất kỳ phòng phỏng vấn nào.
1. Vòng Đời App: Bạn Thực Sự Hiểu Bao Nhiêu?
Câu hỏi: Mô tả vòng đời (lifecycle) của một ứng dụng iOS và Android. Tại sao lifecycle lại quan trọng với việc quản lý trạng thái?
Android có một chuỗi trạng thái rõ ràng: onCreate → onStart → onResume → onPause → onStop → onDestroy. Mỗi callback đại diện cho một giai đoạn khác nhau trong vòng đời ứng dụng. Khi user nhấn nút Home, onPause và onStop được gọi. Khi quay lại, hệ thống gọi onRestart → onStart → onResume.
iOS cũng có lifecycle tương tự qua AppDelegate và SceneDelegate: didFinishLaunching → sceneWillEnterForeground → sceneDidBecomeActive → sceneWillResignActive → sceneDidEnterBackground.
Tại sao điều này quan trọng?
- Quản lý tài nguyên: Khi app vào background, bạn cần giải phóng camera, dừng animation, hủy network request không cần thiết.
- Lưu trạng thái:
onSaveInstanceState(Android) vàsceneDidEnterBackground(iOS) là nơi bạn lưu dữ liệu tạm thời để phục hồi khi user quay lại. - ANR (Android): Thực hiện tác vụ nặng trong main thread khi app đang resume có thể gây ra Application Not Responding.
Câu trả lời mạnh: Ứng dụng giật lag khi user đang interact thường là dấu hiệu của tác vụ chạy trên main thread - tức là bạn chưa hiểu hoặc chưa tôn trọng lifecycle đúng cách.
👉 Luyện tập câu hỏi phỏng vấn iOS Developer tại X Interview!2. Dữ Liệu Lưu Ở Đâu? SharedPreferences, UserDefaults, Room, Core Data
Câu hỏi: Phân biệt các phương pháp lưu trữ dữ liệu trên mobile. Khi nào dùng SharedPreferences, khi nào dùng database?
Đây là câu hỏi tưởng dễ nhưng lại phân loại ứng viên rất rõ.
| Phương pháp | Dùng khi | Hạn chế |
|---|---|---|
| SharedPreferences (Android) / UserDefaults (iOS) | Lưu preferences, settings nhỏ (theme, language, token) | Chỉ dữ liệu nguyên thủy, không phù hợp dữ liệu quan hệ |
| SQLite | Dữ liệu có cấu trúc, cần truy vấn phức tạp | Viết raw SQL, dễ sai |
| Room (Android) | Dùng SQLite nhưng muốn type-safe, compile-time verification | |
| Core Data (iOS) | Object graph phức tạp, cần undo/redo | Phức tạp, dễ over-engineer |
| Realm | Cross-platform (React Native, Flutter), hiệu năng cao | License phức tạp |
Câu trả lời thực tế:
- SharedPreferences/UserDefaults: Lưu token, user settings - dưới 1MB, dữ liệu đơn giản.
- Room/Core Data: Dữ liệu người dùng, danh sách, cache offline.
- Realm: Khi cần cross-platform hoặc hiệu năng vượt trội SQLite.
Sai lầm phổ biến: Dùng SharedPreferences để lưu danh sách 10.000 objects - serialization chậm, đọc từng cái còn tệ hơn.
3. Quản Lý Bộ Nhớ: Ai Là Thủ Phạm?
Câu hỏi: Memory leak trong mobile là gì? Làm thế nào để phát hiện và xử lý?
Memory leak xảy ra khi ứng dụng giữ tham chiếu đến objects không còn cần thiết, ngăn GC (Garbage Collector) hoặc ARC (Automatic Reference Counting) thu hồi bộ nhớ. Kết quả: RAM tăng dần, app bị kill vì Memory Warning.
Nguyên nhân phổ biến nhất:
- Android: Static reference đến Context hoặc Activity. VD: singleton giữ Activity reference → Activity không bao giờ bị destroy.
- iOS: Retain cycle giữa two ViewControllers hoặc closure giữ strong reference đến self mà không dùng
[weak self]. - Flutter: Provider/Controller không được dispose.
Cách phát hiện:
- Android: Android Studio Profiler, LeakCanary
- iOS: Xcode Instruments (Leaks, Allocations), Memory Graph Debugger
- React Native: Flipper Memory Debugger
Câu trả lời có chiều sâu: Tôi dùng LeakCanary trên Android để tự động phát hiện leak trong quá trình development. Trên iOS, tôi dùng Memory Graph Debugger sau mỗi navigation cycle. Với Flutter, tôi đảm bảo dispose() được gọi trong State objects và dùng WeakReference khi cần.
4. Kiến Trúc Ứng Dụng: MVC, MVVM, Hay Clean Architecture?
Câu hỏi: Bạn thường dùng architecture pattern nào? Ưu và nhược điểm?
MVC (Model-View-Controller) là kiến trúc cơ bản nhất nhưng dễ tạo "Massive View Controller" trên iOS - logic giao diện, xử lý network, format dữ liệu tất cả nhét vào một chỗ.
MVVM (Model-View-ViewModel) khắc phục điều đó:
- View giao tiếp với ViewModel, không trực tiếp với Model.
- ViewModel phản ánh trạng thái của View (lý do có "two-way binding").
- iOS: Kết hợp với Combine hoặc SwiftUI @State/@ObservedObject.
- Android: LiveData, StateFlow, ViewBinding.
Clean Architecture (Clean/Onion/Hexagonal):
- Tách biệt rõ ràng: Presentation → Domain → Data layers.
- Use case/business logic nằm ở tầng Domain, hoàn toàn independent với UI và infrastructure.
- Dễ test vì business logic không phụ thuộc Android/iOS SDK.
Câu trả lời của senior developer:
Tôi dùng MVVM cho các dự án vừa và nhỏ vì đơn giản, nhanh implement. Với dự án lớn, nhiều team, tôi chọn Clean Architecture - nó cho phép thay đổi UI (ví dụ chuyển từ UIKit sang SwiftUI) mà không ảnh hưởng business logic. Dependency Injection (Hilt/Dagger cho Android, Factory cho iOS) là chìa khóa để Clean Architecture hoạt động hiệu quả.
👉 Thực hành câu hỏi kiến trúc ứng dụng mobile với X Interview!5. Performance: Cold Start, ANR, Memory Leak
Câu hỏi: Làm thế nào để giảm thời gian cold start của ứng dụng mobile?
Cold start là thời gian từ khi user tap icon cho đến khi app sẵn sàng tương tác. Trung bình người dùng chỉ chờ 1-2 giây trước khi cho rằng app có vấn đề.
Android - Giảm cold start:
- Sử dụng
App Startup Libraryđể khởi tạo components một cách lazy. - Trì hoãn khởi tạo non-critical SDK (analytics, crash reporting) cho đến khi app thực sự cần.
- Dùng
Baseline Profiles(Jetpack Compose) để pre-compile hot code paths. - Loại bỏ
contentDescriptionkhông cần thiết, lazy-load images.
iOS - Giảm cold start:
- Dùng SwiftUI previews thay vì heavy Storyboards.
- Lazy loading các module không bắt buộc khởi tạo ngay.
- Tối ưu
didFinishLaunchingWithOptions- không chặn main thread. - Dùng
async/awaitcho network calls thay vì completion handlers blocking.
ANR (Android): Xảy ra khi main thread bị block quá 5 giây. Giải pháp: move heavy work sang background thread (Kotlin coroutines, RxJava), hoặc dùng WorkManager cho các tác vụ nền.
👉 Ôn luyện câu hỏi Performance và Debugging phỏng vấn Mobile Developer tại X Interview!6. Bảo Mật Dữ Liệu: Không Chỉ Mã Hóa
Câu hỏi: Làm thế nào để bảo mật dữ liệu nhạy cảm trên thiết bị mobile?
Mã hóa chỉ là một phần. Bảo mật mobile đòi hỏi nhiều lớp hơn.
Các lớp bảo mật thực tế:
- Lưu trữ: Dùng Keychain (iOS) hoặc EncryptedSharedPreferences (Android) cho sensitive data như tokens, passwords. KHÔNG BAO GIỜ lưu plaintext vào UserDefaults/SharedPreferences.
- Network: SSL/TLS pinning để chống man-in-the-middle attack. Token-based auth (JWT) với refresh token mechanism.
- Runtime: Obfuscate code (ProGuard, R8) để chống reverse engineering. Tránh hardcode API keys trong source code.
- Permissions: Chỉ request permissions thực sự cần, giải thích rõ cho user lý do. Kiểm tra permission tại runtime (Android 6.0+) thay vì chỉ khai báo manifest.
Câu trả lời có chiều sâu:
Tôi dùng Keychain/EncryptedSharedPreferences cho token, implement SSL pinning cho API calls, và không bao giờ log sensitive data trong production. Ngoài ra, tôi dùng biometric authentication (Face ID / fingerprint) cho các thao tác nhạy cảm như thanh toán hoặc xem dữ liệu cá nhân.
7. Cross-Platform: Khi Nào Chọn React Native, Khi Nào Chọn Flutter?
Câu hỏi: React Native và Flutter khác nhau như thế nào? Khi nào bạn chọn cái nào?
Đây là câu hỏi phân loại rõ ràng giữa ứng viên chỉ biết native và ứng viên có tầm nhìn rộng hơn.
React Native:
- Viết bằng JavaScript/TypeScript, render native components.
- Dùng bridge để giao tiếp với native modules - độ trễ nhỏ nhưng tồn tại.
- Phù hợp: team đã có web developers, app cần integrate với nhiều native SDK phức tạp (React Native có npm ecosystem phong phú).
- Hot reload nhanh, development experience tốt.
Flutter:
- Viết bằng Dart, render bằng Skia graphics engine - không dùng native components.
- Hiệu năng gần như native, đồng nhất trên mọi platform.
- Phù hợp: app cần custom UI phức tạp, animation cao, hoặc cần đồng nhất visual trên iOS và Android mà không cần native look.
- Ecosystem nhỏ hơn React Native, nhưng Flutter 3.x đã có Material 3 và Cupertino widgets.
Khi nào chọn native?
Khi app cần deep hardware integration (AR/VR, complex camera processing, Bluetooth LE low-level), hoặc khi team có đủ native developers và budget.
👉 Luyện tập câu hỏi cross-platform React Native/Flutter tại X Interview!8. Debugging Thực Chiến: Crashlytics, Sentry, Logcat
Câu hỏi: Làm thế nào để debug một crash xảy ra ở production mà không thể reproduce được?
Đây là câu hỏi phân biệt rõ junior và senior. Junior thường trả lời: "Tôi test kỹ trước khi release." Senior hiểu rằng không có app nào hoàn hảo.
Stack trace và symbolication:
- Android: ProGuard obfuscate code → dùng
mapping.txtđể symbolicate stack trace. - iOS: dSYM file từ Xcode archive dùng để symbolicate crash log từ TestFlight/App Store Connect.
Firebase Crashlytics:
- Tự động thu thập crash reports, không cần user gửi.
- Cung cấp: device info, OS version, battery level, có thể log custom keys để context thêm.
- Phiên bản miễn phí phù hợp với hầu hết dự án.
Sentry:
- Hỗ trợ cả mobile lẫn web - phù hợp khi team có fullstack.
- Có thể track performance issues (slow frames, ANR) chứ không chỉ crash thuần túy.
- Dùng cho React Native:
sentry-expohoặc@sentry/react-native.
Câu trả lời thực tế:
Tôi setup Crashlytics/Sentry ngay từ ngày đầu, không phải sau khi có crash đầu tiên. Tôi cũng thêm custom breadcrumbs - log navigation steps, user actions gần thời điểm crash - để reconstruct user journey. Debug symbol (dSYM/mapping.txt) được upload tự động qua CI pipeline.
9. Push Notification: Không Đơn Giản Như Bạn Nghĩ
Câu hỏi: Mô tả quy trình implement push notification từ server đến device. Làm thế nào để handle notification khi app đang ở background hoặc killed state?
Push notification là tính năng tưởng đơn giản nhưng có nhiều edge cases phức tạp.
Quy trình đầy đủ:
- Server gửi notification qua FCM (Firebase Cloud Messaging) hoặc APNs (Apple Push Notification service).
- FCM/APNs route notification đến thiết bị qua device token.
- Device nhận notification qua OS-level handler.
- App xử lý: foreground (hiển thị in-app banner), background (update badge, local notification), hoặc killed (OS hiển thị notification drawer).
Deep linking:
- Notification chứa
data payloadvới deep link (ví dụ:myapp://orders/12345). - App delegate/Scene delegate parse link và navigate đến màn hình tương ứng.
- Cần handle cả trường hợp user tap notification khi app chưa mở (cold start) và khi app đã mở (foreground).
Edge cases quan trọng:
- Notification bị truncated trên iOS khi device có notch - cần test trên nhiều device sizes.
- Android 13+ yêu cầu runtime permission cho notifications - không được assume notification luôn được enable.
- Token có thể thay đổi (device reset, app reinstall) - server cần handle token refresh.
10. Phát Hành App: App Store vs Google Play
Câu hỏi: Trình bày quy trình publish app lên Google Play và App Store. Điểm khác biệt chính?
Google Play:
- Upload file
.aab(Android App Bundle) hoặc.apk. - App Bundle cho phép Google Play dynamic delivery - chỉ download code/resource cần thiết cho device của user.
- Review tự động, thường trong vài giờ (có thể lâu hơn với apps có permissions nhạy cảm).
- Internal testing, closed testing (alpha/beta), open testing channels.
- Sensitive permissions (camera, location, microphone) cần điền privacy policy và video demo.
App Store:
- Upload qua Xcode (Application Loader) hoặc Transporter app.
- Review thủ công, thời gian trung bình 24-48 giờ, có thể lên đến 7 ngày cho apps mới hoặc complex apps.
- Phải cung cấp: app icon (1024x1024), screenshots cho nhiều device sizes, description, privacy policy, demo video nếu có tính năng subscription hoặc in-app purchase.
- App Store Review Guidelines có hơn 30 mục cần tuân thủ - từ UI design (không dùng Apple-like icons) đến content policies.
Điểm khác biệt lớn nhất: App Store review nghiêm ngặt và chủ quan hơn nhiều. Google Play dễ publish hơn nhưng cũng dễ bị gỡ ứng dụng nếu vi phạm policy sau khi đã phát hành. Cả hai đều yêu cầu duy trì changelog/release notes để người dùng hiểu những thay đổi trong phiên bản mới.
Tài liệu tham khảo
- Android Developer Documentation
- Apple Developer Documentation
- React Native Documentation
- Flutter Documentation
Tổng Kết
10 câu hỏi trên bao quát những góc nhìn mà nhà tuyển dụng thực sự quan tâm ở một Mobile Developer:
- Hiểu platform: Lifecycle, memory management, security, permissions.
- Kiến trúc và maintainability: Architecture patterns, testability, technical debt.
- Performance mindset: Cold start optimization, ANR prevention, memory leaks.
- Cross-platform awareness: Khi nào native, khi nào cross-platform, trade-offs là gì.
- Production mindset: Debugging production crashes, monitoring, push notifications, store compliance.
Một app mượt mà không phải trời ban - đó là kết quả của những quyết định kiến trúc đúng đắn, hiểu rõ platform, và luôn nghĩ về trải nghiệm user từ những dòng code đầu tiên.
Bạn có thể đọc thêm tại: X-interview để luyện tập thêm hàng trăm câu hỏi phỏng vấn iOS, Android, React Native và Flutter - từ cơ bản đến senior level.
Nguồn tham khảo:
- Toptal - Top 10 Technical Mobile App Interview Questions (toptal.com)
- Skilr - Top 50 Mobile App Developer Interview Questions (skilr.com)
- ScreeningHive - Mobile App Developer Interview Questions (screeninghive.com)