- `Future` trong Dart là gì và khác `Stream` như thế nào?
Future là một giá trị sẽ có một lần trong tương lai (giống Promise của JS); Stream là chuỗi nhiều giá trị đến dần theo thời gian, như một băng chuyền. Trong Flutter, FutureBuilder dựng UI từ một Future, StreamBuilder dựng UI từ một Stream.…
- Sự khác nhau giữa `StatelessWidget` và `StatefulWidget` là gì?
StatelessWidget chỉ phụ thuộc vào tham số truyền vào (và các InheritedWidget nó đọc); StatefulWidget có thêm một object State sống lâu, giữ dữ liệu thay đổi được trong lúc widget còn trên cây. - StatelessWidget: build() chạy lại khi widget cha rebuild với tham…
- `BuildContext` là gì và tại sao nó quan trọng?
BuildContext là "địa chỉ" của widget trong cây — thực chất nó chính là Element của widget đó. Mọi thao tác "tìm ngược lên cây" đều đi qua context: Theme.of(context), MediaQuery.of(context), Navigator.of(context), ScaffoldMessenger.of(context). Vì of(context) tìm từ vị trí của context đi lên, dùng context…
- Giải thích widget tree, element tree và render tree trong Flutter.
Flutter tách UI thành ba cây với vai trò khác nhau: widget là bản mô tả, element là "phiên bản đang sống" giữ vị trí và state, render object lo layout và vẽ. - Widget tree: object bất biến, rẻ, được tạo lại mỗi lần…
- Mục đích của widget `Key` là gì và khi nào nên dùng?
Key giúp Flutter nhận ra "đây vẫn là widget cũ" khi vị trí của nó trong danh sách con thay đổi. Element so widget mới với cũ bằng Widget.canUpdate: cùng runtimeType và cùng key. Không có key, Flutter chỉ so theo kiểu + vị trí.…
- `const` constructor là gì và tại sao quan trọng cho hiệu năng Flutter?
const constructor tạo object ngay lúc compile, và hai biểu thức const giống hệt nhau trả về cùng một instance (canonicalization). Lợi ích trong Flutter đến từ chính điều đó: khi widget cha rebuild, element so widget mới với widget cũ. Nếu widget con là…
- `setState()` là gì và tại sao gọi nó lại kích hoạt rebuild?
setState() báo cho framework biết state trong State vừa đổi: nó chạy callback đồng bộ, rồi đánh dấu element là dirty (markNeedsBuild). Flutter gọi lại build() ở frame kế tiếp chứ không rebuild ngay, và nhiều lần setState trong cùng frame chỉ gây một lần…
- Giải thích pattern BLoC và tại sao interviewer hay hỏi về nó.
BLoC (Business Logic Component) tách logic khỏi UI theo một chiều: UI gửi event vào, BLoC xử lý rồi phát ra state mới, UI chỉ vẽ theo state. Bộ package thường dùng là bloc + flutterbloc. Phía UI: BlocProvider cung cấp bloc xuống cây, BlocBuilder…
- So sánh Provider, Riverpod và BLoC: khi nào dùng cái nào?
Ba lựa chọn phổ biến nhất, khác nhau chủ yếu ở mức ràng buộc kiến trúc: Provider Riverpod BLoC / Cubit ------------ Bản chất Wrapper quanh InheritedWidget + ChangeNotifier Viết lại từ Provider, không phụ thuộc BuildContext Luồng event → state trên Stream Lỗi thiếu…
- Sự khác nhau giữa `Navigator` cũ (v1) và các cách tiếp cận routing hiện đại là gì?
Navigator 1.0 là API imperative: bạn tự push/pop từng màn lên stack. Navigator 2.0 (Router API) là declarative: stack màn hình được suy ra từ state của app, thường là URL. gorouter là package của Flutter team bọc Router API cho dễ dùng, và là…
- Clean architecture là gì và tại sao quan trọng cho app lớn?
Clean architecture tách code thành các layer: Presentation (UI, widget), Domain (logic nghiệp vụ, entity, use case), Data (repository, data source). Mỗi layer độc lập và có thể test. Sự tách biệt này cho phép thay đổi UI framework, thay data source, và test logic…
- Isolate trong Dart là gì và khi nào dùng chúng?
- Platform channel là gì và khi nào dùng chúng?
- Làm thế nào để test app Flutter? Sự khác nhau giữa unit, widget và integration test là gì?
- Suspend function trong Kotlin là gì?
Suspend function là hàm có thể tạm dừng mà không chặn thread, rồi chạy tiếp khi có kết quả. Nó chỉ gọi được từ một coroutine hoặc từ một suspend function khác. Cơ chế: compiler biến hàm suspend thành hàm nhận thêm một tham số…
- Giải thích Android Activity lifecycle và mục đích của từng method.
Activity lifecycle là chuỗi callback hệ thống gọi khi một màn hình được tạo, hiện ra, mất focus, bị che và bị huỷ: - onCreate(): khởi tạo một lần — setContent/setContentView, lấy ViewModel, đọc savedInstanceState. - onStart(): Activity hiện ra (visible). - onResume(): ở foreground…
- Intent trong Android là gì và có mấy loại?
Intent là object "yêu cầu" gửi cho hệ thống để khởi động một component: mở Activity, chạy Service, gửi broadcast. Có hai loại: - Explicit intent: chỉ rõ component đích — thường dùng trong nội bộ app. - Implicit intent: chỉ khai báo hành động…
- Service trong Android là gì và khi nào nên dùng?
Service là component chạy việc không cần UI. Nó chạy trên main thread của process, nên việc nặng vẫn phải tự đẩy sang coroutine hoặc thread khác. Ba dạng: - Started service (startService): chạy đến khi tự stopSelf() hoặc bị dừng. - Foreground service: bắt…
- Các loại Android permission và cách xử lý runtime permissions?
Android chia permission theo mức rủi ro: - Normal (INTERNET, VIBRATE): khai báo trong manifest là được cấp khi cài. - Dangerous / runtime (camera, vị trí, danh bạ, micro, POSTNOTIFICATIONS từ Android 13): từ Android 6.0 (API 23) phải xin lúc chạy; người dùng…
- Giải thích state management trong Jetpack Compose với `mutableStateOf` và `remember`.
mutableStateOf() tạo một MutableState<T mà Compose theo dõi được: composable nào đọc .value sẽ được recompose khi giá trị đổi. remember giữ object đó qua các lần recomposition — thiếu remember, mỗi lần recompose lại tạo state mới về giá trị ban đầu. Các biến…
- MVVM architecture là gì và cấu trúc ra sao?
MVVM (Model-View-ViewModel) tách UI logic khỏi business logic: Model chứa dữ liệu và business rule, View hiển thị UI (Activity/Fragment/Composable), ViewModel chứa UI state và logic, tồn tại qua configuration change. ViewModel expose LiveData/StateFlow để View observe. Sự tách biệt này cải thiện khả năng…
- Sự khác biệt giữa LiveData và StateFlow?
Cả hai đều giữ giá trị hiện tại và báo cho observer khi giá trị đổi, nhưng khác gốc: LiveData là class của Android, lifecycle-aware sẵn; StateFlow thuộc Kotlin coroutines, không phụ thuộc Android. LiveData StateFlow --------- Giá trị ban đầu Không bắt buộc (có…
- ViewModel là gì và tại sao nên dùng?
ViewModel là state holder của một màn hình: giữ và chuẩn bị dữ liệu cho UI, và sống qua configuration change (xoay màn hình, đổi dark mode) — Activity bị tạo lại nhưng ViewModel vẫn còn, không phải gọi API lại. Vai trò đúng theo…
- Room database là gì và tại sao dùng thay vì SQLite trực tiếp?
Room là thư viện Jetpack bọc SQLite: bạn khai báo entity và câu query bằng annotation, Room sinh code lúc compile (qua KSP) và kiểm tra câu SQL ngay lúc build. So với dùng SQLiteOpenHelper trực tiếp: - Sai tên cột hay cú pháp SQL…
- Interceptor trong Retrofit/OkHttp là gì và cách dùng?
Interceptor chặn HTTP request/response để chỉnh sửa chúng. - Application interceptor chạy một lần cho mỗi request; network interceptor chạy cho từng lần gọi network thực tế (kể cả redirect và retry). - Dùng phổ biến: gắn auth header, log request/response, xử lý refresh token,…
- Certificate pinning là gì và cách implement?
- Hermes là gì, khác JSC ở đâu?
Hermes là JavaScript engine open-source do Meta viết riêng cho React Native, tối ưu cho thời gian khởi động, bộ nhớ và kích thước app. JSC (JavaScriptCore) là engine của Safari, từng là mặc định của RN. Khác biệt chính: - Biên dịch bytecode trước…
- Khác biệt cơ bản: RN vs Flutter vs native (Swift/Kotlin) cho dự án mới 2026?
- Flexbox trong RN khác CSS web ra sao?
RN tính layout bằng Yoga (engine C++ của Meta). Flexbox chạy gần giống web nhưng giá trị mặc định khác — đây là chỗ dev web hay vấp: React Native Web CSS --------- flexDirection column row flexShrink 0 1 alignContent flex-start stretch flex chỉ nhận…
- `react-navigation` v7 — Stack / Tab / Drawer khi nào dùng?
Stack Navigator: điều hướng kiểu push/pop — màn hình mới đè lên màn cũ. Có hai bản: @react-navigation/native-stack dùng UINavigationController (iOS) và Fragment (Android) nên animation, gesture do platform xử lý — nên chọn mặc định; @react-navigation/stack viết bằng JS, tuỳ biến animation được nhiều…
- Vì sao FlatList với 10k items vẫn mượt? Tinh chỉnh `windowSize`/`maxToRenderPerBatch`/`getItemLayout` ra sao?
FlatList virtualize: chỉ mount items hiện đang trong "window" (vùng nhìn thấy + buffer hai phía), unmount items ngoài window khi scroll. Memory ổn định không phụ thuộc tổng số item. Tham số quan trọng: - windowSize (default 21): số "screenful" được render. 21 nghĩa…
- `useCallback` / `useMemo` trong RN — khi nào thực sự cần?
Quy tắc giống React web: memo hoá chỉ có ích khi cần giữ reference ổn định cho thứ đang so sánh reference (React.memo, dependency array, props của FlatList). Khác biệt là trên máy Android cấu hình thấp, render thừa trong list dài dễ thành giật…
- New Architecture là gì, gồm những gì, mặc định từ RN version nào?
New Architecture là tên gọi chung cho 3 phần Meta viết lại RN từ năm 2020: 1. JSI (JavaScript Interface): C++ layer thay Bridge cũ. JS engine có tham chiếu trực tiếp tới object C++/native — gọi sync, không serialize JSON. 2. TurboModules: thay native…
- JSI là gì, khác Bridge cũ thế nào về cơ chế gọi native?
- TurboModules vs NativeModules cũ — khác biệt cụ thể?
- Animated API và Reanimated — chọn cái nào?
Animated API (built-in RN core): - Driver useNativeDriver: true đẩy animation lên native thread, smooth. - Hạn chế: native driver chỉ animate được thuộc tính không ảnh hưởng layout (opacity, transform); animate width/height/top phải useNativeDriver: false → chạy trên JS thread, dễ jank. - API…
- App size optimization — ProGuard/R8, Hermes, ABI splits, asset compression?
- Push notifications — FCM + APNs, Expo Notifications, setup ra sao?
Hai dịch vụ native cần biết: - APNs (Apple Push Notification service): iOS push. - FCM (Firebase Cloud Messaging): Android push, có thể proxy iOS qua APNs. Option 1 — Direct (@react-native-firebase/messaging + APNs): - Setup phức tạp: cần Firebase project, push cert/auth key APNs,…
- Hot reload và hot restart khác nhau thế nào?
- Hot reload: nạp mã Dart đã sửa vào máy ảo đang chạy rồi dựng lại cây widget, giữ nguyên state của app. Rất nhanh (thường dưới 1s), hợp chỉnh UI. Không chạy lại main(). - Hot restart: khởi động lại app, dựng lại toàn…
- Flutter lưu dữ liệu cục bộ bằng cách nào? Khi nào dùng gì?
Chọn theo loại dữ liệu: - sharedpreferences: cặp key–value đơn giản (cờ, cấu hình, lựa chọn của người dùng). Không hợp dữ liệu lớn/có cấu trúc. - File: đọc/ghi file trong thư mục app cho blob/tài liệu. - SQLite (sqflite): CSDL quan hệ cho dữ…
- Fragment là gì và vòng đời của nó khác Activity ở đâu?
Fragment là thành phần UI tái sử dụng có vòng đời riêng, sống bên trong Activity (hoặc Fragment khác) — dùng để chia UI thành phần nhỏ và hỗ trợ layout đa kích thước (điện thoại/tablet). Khác biệt chính: - Fragment có thêm các callback…
- Recomposition trong Jetpack Compose là gì?
Compose là UI khai báo: bạn viết các hàm @Composable nhận dữ liệu (state) và sinh ra UI tương ứng. Khi state đọc bên trong đổi, Compose chạy lại các composable liên quan để cập nhật UI — đó là recomposition. Điểm quan trọng: -…
- Jetpack Navigation Component giải quyết vấn đề gì?
Navigation Component chuẩn hoá việc điều hướng trong app thành một đồ thị (navigation graph) khai báo, thay cho việc tự quản FragmentTransaction/intent rải rác. Khái niệm chính: - NavGraph: tập các đích (destination) và các đường đi giữa chúng. - NavHost: vùng chứa hiển…
- Hooks trong React Native dùng thế nào? useState và useEffect khác gì?
RN dùng cùng React hooks như React web (hooks không gắn với DOM). - useState: khai báo state trong function component; gọi setter làm component render lại. - useEffect: chạy side-effect (gọi API, đăng ký listener, timer) sau khi render. Mảng dependency quyết định khi…
- Vì sao app React Native bị giật (jank)? JS thread và UI thread khác nhau ra sao?
RN chạy hai luồng chính, mỗi luồng đều cần đạt ~60fps (16ms/frame): - JS thread: chạy logic React, xử lý sự kiện, quyết định UI. Nếu bận (tính toán nặng, render list lớn, quá nhiều console.log), JS không kịp trả frame → giật khi cuộn/tương…
- Vòng đời app mobile (foreground/background) là gì? React Native theo dõi bằng cách nào?
Khác với vòng đời từng màn, app mobile còn có trạng thái toàn app do OS quản: đang mở (foreground), chạy nền (background), hoặc bị hệ thống thu hồi (killed). Vì sao quan trọng: - Vào background nên dừng camera/animation/timer, lưu state, ngắt kết nối…
- Gọi API và caching trong app mobile nên làm thế nào?
Mạng mobile chập chờn và tốn pin, nên tầng networking cần chắc chắn: - Gọi API: dùng fetch/axios (RN), Retrofit (Android), Dio (Flutter). Đặt timeout, huỷ request khi rời màn, xử lý lỗi và trạng thái loading rõ ràng. - Retry có kiểm soát: thử…
- Deep linking là gì? Phân biệt custom scheme, App Links và Universal Links?
Deep link là URL mở app tới đúng một màn/nội dung cụ thể (ví dụ link quảng cáo mở thẳng trang sản phẩm), thay vì chỉ mở màn chính. Các loại: - Custom URL scheme (myapp://product/12): đơn giản, chạy mọi phiên bản, nhưng không xác…
- Code signing khi phát hành app là gì? Vì sao cần?
Trước khi lên store, app phải được ký số (code signing) bằng chứng chỉ — đây là cách nền tảng xác thực nguồn gốc và toàn vẹn của bản cài. Vì sao cần: - Đảm bảo app đến từ đúng nhà phát triển và không…
- Responsive và adaptive UI trong mobile khác nhau thế nào?
Cả hai giúp app dùng tốt trên nhiều kích thước (điện thoại, tablet, gập, desktop) nhưng khác trọng tâm: - Responsive: điều chỉnh cách sắp xếp UI cho vừa không gian có sẵn — co giãn, đổi số cột, xuống dòng. Ví dụ: 1 cột…
- Tối ưu bộ nhớ và pin cho app mobile: cần lưu ý gì?
- Kiến trúc offline-first là gì? Xử lý đồng bộ và xung đột thế nào?
- Lưu trữ dữ liệu nhạy cảm và bảo mật cơ bản trên mobile cần lưu ý gì?
Thiết bị có thể bị mất, root/jailbreak, hoặc app bị dịch ngược → không được coi client là môi trường tin cậy. Lưu trữ nhạy cảm: - Token/mật khẩu/khoá để trong kho an toàn của OS: Android Keystore, iOS Keychain. Thư viện EncryptedSharedPreferences đã bị…
- `lateinit` và `by lazy` trong Kotlin khác nhau thế nào?
Cả hai đều dùng để khởi tạo muộn một property non-null, nhưng ai khởi tạo và khi nào thì khác nhau: lateinit var val ... by lazy { } --------- Kiểu biến var (gán lại được) val (chỉ đọc) Ai gán giá trị Code bên…
- App native, hybrid và cross-platform khác nhau thế nào?
Khác nhau ở chỗ UI được vẽ bằng gì và code chạy trên nền nào: - Native: viết riêng cho từng nền tảng — Kotlin/Java cho Android, Swift cho iOS. Truy cập đầy đủ API hệ thống, hiệu năng tốt nhất, nhưng phải duy trì…
- `versionCode` và `versionName` khác nhau thế nào khi phát hành app?
- versionCode: số nguyên nội bộ, người dùng không thấy. Google Play và hệ điều hành dùng nó để biết bản nào mới hơn: mỗi lần upload phải lớn hơn bản trước, và Android chặn cài bản có versionCode thấp hơn bản đang có (chống…
- Flavor trong Flutter là gì và dùng để làm gì?
Flavor là các biến thể build của cùng một codebase cho từng môi trường — thường là dev, staging, production. Mỗi flavor có thể có tên app, icon, API endpoint, feature flag và application ID riêng (bên Android gọi là product flavor, kết hợp với…
- Đồng hồ đếm ngược (OTP, giữ chỗ thanh toán) chạy sai khi app vào background — xử lý thế nào?
Nguyên nhân: khi app vào background, hệ điều hành tạm dừng hoặc giới hạn JS thread, nên setInterval ngừng chạy. Nếu mỗi giây trừ remaining - 1, quay lại app sẽ thấy đồng hồ đứng yên hoặc lệch. Cách đúng: lưu mốc thời gian kết…
- Chạy tác vụ nền (đồng bộ, upload) trên iOS và Android khác nhau thế nào? App cross-platform nên xử lý ra sao?
- Làm thế nào để chống dịch ngược (reverse engineering) và can thiệp vào app mobile?
- Theo dõi crash của app trên production bằng cách nào?
Không thể ngồi cạnh từng người dùng, nên app cần một crash reporting SDK (Firebase Crashlytics, Sentry) gom crash về một dashboard: nhóm theo stack trace, đếm số người dùng bị ảnh hưởng, lọc theo phiên bản app/OS/thiết bị. Trong Flutter phải bắt hai nguồn…
- App bị hệ điều hành kill khi đang ở background, người dùng quay lại mất hết dữ liệu đang nhập — xử lý thế nào?
Khi thiếu RAM, hệ điều hành kill process của app đang nằm nền (process death). Khác với người dùng tự tắt app, lúc quay lại Android dựng lại đúng màn hình cũ (iOS vẫn hiện snapshot màn hình cũ trong app switcher) nên người dùng…
- Quy trình đưa app lên Google Play và App Store gồm những bước nào?
Hai store có luồng giống nhau: build có chữ ký → phát cho tester → review → phát hành dần. Google Play: 1. Build App Bundle (AAB) đã ký, versionCode tăng so với bản trước. 2. Upload lên các track test: internal (tối đa 100…
- Access token hết hạn khi nhiều request đang chạy song song — refresh token thế nào để không gọi refresh nhiều lần?
- App chạy bình thường ở bản debug nhưng crash hoặc màn hình trắng ở bản release — debug thế nào?
- Tích hợp đăng nhập sinh trắc học (vân tay, Face ID) thế nào cho an toàn?
Sinh trắc học không thay thế đăng nhập với server — nó chỉ mở khoá một thứ đã lưu sẵn trên máy (thường là refresh token) hoặc xác nhận một thao tác (chuyển tiền). Cách yếu: gọi prompt, nhận true/false rồi cho vào app. Kết…
- Khi nào nên dùng WebView trong app, và giao tiếp giữa web với native thế nào cho an toàn?
WebView hợp với nội dung thay đổi thường xuyên hoặc đã có sẵn trên web: trang điều khoản, chương trình khuyến mãi, mini app của đối tác, trang cổng thanh toán. Đổi nội dung không cần phát hành bản app mới. Đổi lại: tốn bộ…
- Danh sách nhiều ảnh làm app tăng bộ nhớ liên tục và giật — xử lý thế nào?
Nguyên nhân thường gặp: ảnh được giải mã ở kích thước gốc. Ảnh trong bộ nhớ ở dạng chưa nén, khoảng width × height × 4 byte — ảnh 4K (3840×2160) chiếm hơn 30 MB RAM dù chỉ hiển thị thành thumbnail 120×120. Vài chục…
- Thiết kế luồng upload ảnh/video dung lượng lớn khi mạng chập chờn thế nào?
- `Context` trong Android là gì? Phân biệt Application context và Activity context (liên quan memory leak).
Context là cầu nối tới tài nguyên và dịch vụ hệ thống: truy cập resources, khởi động Activity/Service, lấy getSystemService(), mở database... Về vòng đời có hai loại chính: - Activity context: gắn với vòng đời một Activity, biết về theme/UI. Dùng khi cần theme…
- ANR (Application Not Responding) là gì và cách phòng tránh?
ANR là hộp thoại hệ thống hiện ra khi main thread (UI thread) bị chặn quá lâu nên app không phản hồi. Các ngưỡng chính: - Không xử lý input event (chạm, phím) trong 5 giây. - BroadcastReceiver.onReceive() chạy quá lâu (10 giây foreground, 60…
- `RecyclerView` là gì và cơ chế view recycling hoạt động ra sao?
RecyclerView là widget hiển thị danh sách/lưới lớn hiệu quả bằng cách tái sử dụng một số ít View thay vì tạo View cho mọi item. Hình dung một cửa sổ chỉ thấy vài dòng: khi cuộn, dòng trôi khỏi màn hình không bị huỷ…
- Phân biệt cold / warm / hot start và cách tối ưu thời gian khởi động app.
- `InheritedWidget` là gì và nó truyền state xuống cây widget như thế nào? (nền tảng của Provider)
InheritedWidget là widget đặc biệt cho phép các widget con đọc dữ liệu từ tổ tiên mà không phải truyền tay qua từng cấp constructor. Provider, Theme, MediaQuery đều được dựng trên cơ chế này. Hình dung nó như một "trạm phát" đặt cao trên…