- `val` và `var` trong Kotlin khác nhau như thế nào?
val khai báo biến chỉ đọc, không thể gán lại sau khi khởi tạo (tương tự final trong Java), còn var khai báo biến có thể thay đổi giá trị. Dùng val làm mặc định giúp code an toàn hơn và phù hợp với nguyên…
- Giải thích null safety trong Kotlin và sự khác biệt giữa kiểu nullable và non-nullable.
Trong Kotlin, biến mặc định không được phép null để loại bỏ NullPointerException. Muốn cho phép null, bạn khai báo kiểu nullable bằng ? (ví dụ String?). Compiler bắt buộc bạn xử lý null ngay lúc biên dịch qua các toán tử như ?. (safe…
- Extension function trong Kotlin là gì và hoạt động như thế nào?
Extension function cho phép bạn thêm method mới vào class có sẵn mà không cần kế thừa hay sửa code gốc. Ví dụ có thể thêm method thẳng vào class String: fun String.isPhoneNumber(): Boolean { return this.length == 10 }. Trước tên hàm là tên…
- Data class trong Kotlin là gì và nó tự động tạo ra những gì?
Data class tự động sinh ra các method boilerplate như equals(), hashCode(), toString() và copy(). Data class cần ít nhất một tham số trong constructor và rất phù hợp để chứa dữ liệu (như response API hay model database). Chúng không thể là abstract, open,…
- Sealed class trong Kotlin là gì và có ứng dụng gì trong Android?
Sealed class giới hạn một class hierarchy thành tập hợp subclass cố định, được định nghĩa trong cùng một file hoặc package. Rất phù hợp để biểu diễn các trạng thái giới hạn như response API (Success/Error/Loading). Khi dùng với when, compiler bắt buộc xử…
- Các scope function (`let`, `run`, `apply`, `also`, `with`) là gì và khi nào dùng từng loại?
Scope function thực thi một block code trên một object trong một scope tạm thời. let chạy code chỉ khi object khác null (trả về kết quả lambda). run giống let nhưng dùng this thay vì tham số. apply cấu hình object và trả về…
- Coroutine là gì và tại sao tốt hơn callback?
Coroutine là các hàm nhẹ có thể tạm dừng và tiếp tục, cho phép lập trình bất đồng bộ hiệu quả mà không block thread. Khác với callback dễ dẫn đến "callback hell", coroutine cho phép viết code bất đồng bộ trông như code tuần…
- Sự khác nhau giữa `launch` và `async` trong Kotlin coroutines?
launch là coroutine fire-and-forget, trả về Job và không trả về kết quả. async dùng khi cần thực hiện tác vụ và lấy kết quả về, trả về Deferred. Dùng launch cho tác vụ độc lập (như cập nhật UI), còn async khi cần kết…
- 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ố…
- Kotlin xử lý exception trong coroutine như thế nào?
Bạn có thể dùng try-catch thông thường bên trong coroutine để xử lý exception cục bộ. Với exception không được bắt, dùng CoroutineExceptionHandler để bắt ở cấp coroutine scope. viewModelScope dùng SupervisorJob nên coroutine con thất bại không huỷ coroutine anh em, nhưng exception không…
- Companion object trong Kotlin là gì?
Companion object cho phép định nghĩa các thành viên kiểu static (hằng số, factory method) bên trong class, thuộc về class chứ không phải instance. Mỗi class chỉ có một companion object. Có thể gọi trực tiếp mà không cần tạo instance: MyClass.myStaticMethod(). Giống static…
- Destructuring trong Kotlin là gì?
Destructuring cho phép bạn tách một object thành các biến riêng lẻ trong một câu lệnh duy nhất. Ví dụ val (name, age) = person trích xuất thuộc tính từ data class. Cũng có thể dùng trong vòng lặp: for ((key, value) in map). Hoạt…
- 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…
- Sự khác biệt giữa `replace()` và `add()` trong Fragment transactions?
replace() xoá Fragment hiện tại và thêm Fragment mới vào chỗ đó — khi back thì Fragment bị replace sẽ được tạo lại. add() giữ Fragment hiện có và chồng Fragment mới lên trên — khi back thì quay về Fragment cũ. Dùng replace() để…
- 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…
- BroadcastReceiver là gì và hoạt động như thế nào?
BroadcastReceiver là component lắng nghe các broadcast trong toàn hệ thống (như pin yếu, thay đổi network, hay broadcast tuỳ chỉnh). Bạn đăng ký nó trong manifest (static) hoặc trong code (dynamic), và nó kích hoạt onReceive() khi nhận được broadcast phù hợp. Tránh thực…
- ContentProvider là gì và dùng trong trường hợp nào?
ContentProvider là lớp trừu tượng cung cấp quyền truy cập có kiểm soát vào dữ liệu của app cho các app hoặc process khác. Nó dùng URI để xác định resource và implement các thao tác CRUD qua query(), insert(), update(), delete(). Danh bạ, lịch,…
- 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…
- `savedInstanceState` và `onSaveInstanceState()` khác nhau như thế nào?
onSaveInstanceState() là callback để lưu trạng thái UI tạm thời (như vị trí scroll) trước khi activity bị destroy do configuration change. Bundle này được truyền vào onCreate() hoặc onRestoreInstanceState(). Khác với lưu trữ lâu dài như SharedPreferences hay database. Dùng nó cho trạng thái…
- Intent filter và implicit intent là gì?
Intent filter được khai báo trong manifest để chỉ định loại implicit intent mà Activity có thể xử lý. Chúng định nghĩa action, category, và kiểu dữ liệu. Khi bạn gửi implicit intent, hệ thống tìm tất cả app có Intent filter phù hợp. Ví…
- Sự khác biệt giữa Process và Thread trong Android?
Process là một instance riêng biệt của app với bộ nhớ và tài nguyên riêng, chạy độc lập với các process khác. Thread là đơn vị thực thi nhẹ hơn trong một process, chia sẻ bộ nhớ với các thread khác. Android app có main…
- Jetpack Compose là gì và tại sao nó đang thay thế XML layouts?
Jetpack Compose là bộ công cụ UI declarative hiện đại cho phép xây dựng giao diện Android bằng Kotlin function thay vì XML. Nó đang thay thế XML vì code ngắn gọn hơn, type-safe, và dễ tái sử dụng hơn. Compose tự động cập nhật…
- Composable function là gì và điều kiện để một function là Composable?
@Composable đánh dấu một Kotlin function là pure, idempotent (cùng input → cùng output), và được gọi bởi Compose runtime chứ không phải do bạn gọi thủ công — đây là ràng buộc quan trọng nhất. Function phải trả về Unit, không có side effect…
- 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…
- Sự khác biệt giữa `remember` và `rememberSaveable`?
remember giữ state qua các lần recomposition trong scope của composable nhưng mất khi configuration change như xoay màn hình. rememberSaveable persist state qua configuration change bằng cách tự động lưu vào Bundle. Dùng rememberSaveable cho dữ liệu người dùng nhập (form fields) và remember…
- State hoisting trong Jetpack Compose là gì và tại sao quan trọng?
State hoisting nghĩa là chuyển state từ composable con lên composable cha, làm cho composable con trở nên stateless. Composable stateless nhận state qua tham số và callback để cập nhật state, giúp tái sử dụng trên nhiều màn hình. Ví dụ hoist state của…
- `LaunchedEffect` là gì và khi nào nên dùng?
LaunchedEffect là side-effect function khởi chạy một coroutine scope gắn với lifecycle của composable. Dùng cho các tác vụ một lần như load data, animation, hay analytics. Nó chạy khi key parameter thay đổi và huỷ khi composable rời khỏi composition. Ví dụ: LaunchedEffect(userId) {…
- Sự khác nhau giữa `LaunchedEffect`, `DisposableEffect`, và `SideEffect`?
- Modifier trong Jetpack Compose là gì? Cho ví dụ.
Modifier là object có thể chain lại để thêm behavior, styling, hay layout cho composable. Ví dụ: .size(100.dp), .background(Color.Blue), .padding(16.dp), .clickable { }, .weight(1f). Thứ tự quan trọng vì modifier chain từ trái sang phải: .padding().background() khác với .background().padding(). Modifier là ví dụ điển hình…
- Làm thế nào để xử lý navigation trong Jetpack Compose?
Dùng Compose Navigation library với NavController và NavHost. Định nghĩa NavGraph với các màn hình và route, rồi dùng navController.navigate(route) để điều hướng. State được giữ lại khi quay về màn hình trước. Với Compose Navigation 2.8+ (stable từ Oct 2024), dùng type-safe routes qua…
- `derivedStateOf` là gì và khi nào nên dùng?
- Làm thế nào để implement theming trong Jetpack Compose?
Dùng MaterialTheme (Material 3) hoặc CompositionLocal tuỳ chỉnh để tập trung hoá các thuộc tính theme. Định nghĩa màu sắc, typography, và shape trong theme object, dùng CompositionLocalProvider để cung cấp chúng cho cây composable. Wrap app trong MaterialTheme(colorScheme = colorScheme, typography = typography) {…
- `CompositionLocal` là gì và hoạt động như thế nào?
- 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…
- MVI architecture là gì và khác MVVM như thế nào?
- Repository pattern là gì và tại sao quan trọng?
Repository pattern trừu tượng hoá các nguồn dữ liệu (local database, remote API, cache) sau một interface duy nhất, để ViewModel không cần biết dữ liệu đến từ đâu. Sự decoupling này giúp test dễ hơn (mock repository) và cho phép đổi nguồn dữ liệu…
- 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…
- Dependency injection là gì và tại sao quan trọng trong Android?
Dependency injection nghĩa là cung cấp dependency của một object qua tham số thay vì object tự tạo bên trong. Lợi ích: test dễ hơn (truyền mock dependency), loose coupling, linh hoạt khi đổi implementation. Ví dụ: thay vì val database = Database.getInstance() bên trong…
- Hilt là gì và nó đơn giản hoá dependency injection như thế nào?
Hilt là thư viện DI được xây trên Dagger, thiết kế riêng cho Android. Nó loại bỏ boilerplate bằng cách cung cấp module có sẵn cho Android component. Đánh dấu Application với @HiltAndroidApp, Activity/Fragment với @AndroidEntryPoint, và inject bằng @Inject. Hilt tự động quản lý…
- Clean Architecture là gì và có những layer nào?
- Use Case pattern là gì và khi nào nên tạo một Use Case?
- Các Hilt scope khác nhau có ý nghĩa gì?
Hilt scope kiểm soát thời gian sống của dependency instance: @Singleton sống suốt vòng đời app, @ActivityScoped theo vòng đời Activity, @ViewModelScoped theo ViewModel, và @FragmentScoped theo Fragment. Scope mặc định là unscoped (tạo instance mới mỗi lần). Chọn scope dựa vào thời gian muốn…
- 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…
- DAO (Data Access Object) trong Room là gì?
DAO là interface với các method cho thao tác CRUD trên database. Bạn annotate method với @Query, @Insert, @Update, @Delete. Room sinh implementation lúc compile. Ví dụ: @Query("SELECT FROM users WHERE id = :id") suspend fun getUser(id: Int): User. DAO là nơi định nghĩa query,…
- Retrofit là gì và hoạt động như thế nào?
Retrofit là HTTP client type-safe chuyển REST API thành Kotlin interface. Bạn định nghĩa interface với method được annotate bằng HTTP verb như @GET, @POST, thêm kiểu request/response, và Retrofit tự sinh implementation. Nó tự động deserialize JSON response thành Kotlin object, xử lý header,…
- 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,…
- Làm thế nào để implement authentication với Retrofit?
Dùng Interceptor để thêm auth header vào mọi request. Khi token hết hạn, interface Authenticator xử lý token refresh bằng cách chặn response 401 và retry với token mới. Lưu token an toàn trong EncryptedSharedPreferences. Gửi token trong Authorization header: Authorization: Bearer token. Xử lý…
- DataStore là gì và khác SharedPreferences như thế nào?
DataStore là bản thay thế hiện đại cho SharedPreferences, được xây dựng trên coroutine và Flow cho lưu trữ dữ liệu type-safe và transactional. Async-first (không blocking), hỗ trợ protocol buffer cho type safety, và an toàn hơn SharedPreferences vốn có vấn đề threading. Dùng…
- WorkManager là gì và khi nào nên dùng?
WorkManager lên lịch background work có thể defer được, tồn tại qua app restart và system reboot. Nó tự động xử lý Doze Mode và App Standby, chọn cơ chế scheduling tốt nhất (JobScheduler, BroadcastReceiver). Dùng cho tác vụ không gấp nhưng phải chắc chắn…
- Paging 3 library là gì và tại sao nên dùng?
Paging 3 là thư viện phân trang được khuyến nghị, load hiệu quả dataset lớn từ nguồn local/remote. Bạn tạo PagingSource (hoặc RemoteMediator cho network+database), dùng Pager để tạo paginated stream, và collect PagingData trong UI với collectAsLazyPagingItems(). Nó xử lý tự động loading, appending,…
- ProGuard và R8 là gì, chúng tối ưu app như thế nào?
- App Bundle là gì và chúng giảm kích thước app như thế nào?
- Dynamic feature module là gì và khi nào nên dùng?
- Làm thế nào để tối ưu app performance và các metric quan trọng là gì?
- Testing trong Jetpack Compose là gì và khác Espresso như thế nào?
- Kotlin Multiplatform (KMP) là gì và liên quan đến Android như thế nào?
- Instrumentation testing và unit testing khác nhau như thế nào và khi nào dùng loại nào?
- Best practice về memory management trong Android là gì?
- Làm thế nào để implement CI/CD cho Android app?
- Certificate pinning là gì và cách implement?
- Observer pattern là gì và được dùng như thế nào trong Android?
Observer pattern cho phép các object (observer) đăng ký nhận thông báo về thay đổi trạng thái của object khác (subject). Trong Android, LiveData/StateFlow là các implementation của pattern này. Khi bạn gọi observe() hoặc collect(), bạn đang đăng ký làm observer. Khi dữ liệu…
- Làm thế nào để xử lý configuration change như xoay màn hình?
Configuration change destroy và recreate Activity/Fragment. Bảo toàn state bằng: SavedInstanceState (UI state tạm thời), ViewModel (logic và data), và SharedPreferences/DataStore (data lâu dài). Không nên dùng android:configChanges để tắt recreation trừ khi thực sự cần thiết. Trong Compose, state tự động tồn tại qua…
- Sự khác biệt giữa hot flow và cold flow?
- `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ỷ…
- Gradle là gì và vai trò của nó trong quá trình build Android?
Gradle là hệ thống build tự động mà Android dùng để biên dịch mã, gói tài nguyên, và tạo ra file APK/AAB. Android Gradle Plugin (AGP) mở rộng Gradle với các tác vụ riêng cho Android. Vai trò chính: - Quản lý dependency: khai báo…
- Inline function trong Kotlin là gì? Giải thích `inline`, `noinline` và `reified`.
- Phân biệt cold / warm / hot start và cách tối ưu thời gian khởi động app.