All Flashcards

(200 cards)

1
Q

What’s an inline function?

A
  • it instructs the compiler to insert the body of the function wherever the function gets used, which helps reduce function overhead and speeds up execution
  • it works best for functions with lambda parameters, especially the function body is small
  • it’s not recommended for large functions that are called in many places, because the code will be duplicated multiple times, increasing the program size
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What’s const?

A
  • the value is resolved at compile time
  • it can only be used with val inside a companion object or at the top-level and it must be a primitive type like Int, Boolean or String
  • it removes the overhead of accessing the variable at runtime, which improves performance
  • it can’t be used if the value is not static or it is a complex data type
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What’s reified?

A
  • the compiler erases the generic type, so its information is not available at runtime
  • reified tells the compiler to retain the type information and insert it where it’s used
  • after compilation, the generic type is replaced by its upper bound or Any
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What’s the internal keyword?

A

it is used to restrict the visibility of a function, class, variable to the same module

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What’s the open keyword?

A
  • In Kotlin, classes and functions are final by default
  • the open keyword is used to make a class extendable or a function overridable
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What’s the lateinit keyword?

A
  • it’s used when you want to initialize a variable later
  • the variable must be non-nullable, can only be used with var and can’t be a primitive type like Int or Double
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What’s by lazy keyword?

A
  • it’s used when you want a variable to be initialized only when it is first accessed instead of at the time of declaration
  • it improves performance since initialization happens only when needed
  • the variable must work with val and once initialized, all future access will return the same value
  • it also ensures thread safety be default
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What’s multidex?

A
  • it’s used to overcome the limit on a large number of methods by allowing code to be split into multiple .dex files
  • but it can slow down the app startup time
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Is it possible to force GC?

A

No, it just makes a request to the system, but it doesn’t guarantee that it will happen

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What’s @JvmStatic?

A
  • it’s used to make functions and properties inside a companion object static in Java
  • without @JvmStatic, functions and properties inside a companion object are not truly static. they can only be accessed through the companion object in Java
  • with @JvmStatic, the compiler generates static functions and properties at the class level, making them directly accessible in Java
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What’s @JvmField?

A

it’s used to instruct the compiler not to generate getter and setter methods for variables, making them directly accessible in Java and eliminating the function overhead

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What’s @JvmOverloads?

A
  • in Java, function parameters can’t have default values
  • it’s used to instruct the compiler to generate overloads for the function with default parameters
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

When does the init block be called?

A
  • frist, the primary constructor is called
  • second, all init blocks are called in the order they are defined in the class
  • finally, the secondary constructor is called
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

== and === in Kotlin?

A
  • double equals checks if two objects have the same contents, which is similar to equals in Java
  • triple equals checks if two objects refer to the same instance, which is similar to == in Java
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What’s a Companion Object?

A
  • it is tied to a class and defines static members within the class
  • it is created when the class is loaded
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What’s an extension function?

A
  • it is used to add a new function to a class without modifying the class’s source code
  • it is compiled as a static method and takes an instance of the class as a parameter
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What’s noinline in Kotlin?

A
  • it’s used to prevent a lambda parameter from being inlined in an inline function
  • Problem:
    • an inlined lambda can’t be passed to another noinline function
    • an inlined lambda can’t be stored in a variable
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What’s crossinline in Kotlin?

A
  • it is used to prevent a non-local return inside a lambda in an inline function
  • Problem:
    • a local return causes the calling function to exit early
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

What’s a high-order function?

A

it’s a function that takes a lambda as a parameter or returns a lambda as the result

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

What’s infix in Kotlin?

A
  • it’s used to define a function that is called in a more readable way without using dots and parentheses
  • it is defined like an extension function but must have exactly one parameter which can’t have a default value
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

What’s inner class?

A

it’s used to define a nested class that can access all properties of the outer class, regardless of their visibilities

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

What’s inline class (value class)?

A
  • it’s used to wrap a single value in a class without runtime overhead, providing type safety and improving performance by avoiding object allocations
  • Feature
  • it must have exactly one primary constructor parameter
  • it can’t inherit from another class but it can implement interfaces
  • it can declare properties, but they can’t have backing fields and can also declare functions
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

What’s sealed class?

A
  • it a type of class that restricts the class hierarchy to a limited set of subclasses which must be declared in the same file
  • it enables exhaustive checks in the when expression, ensuring all subclasses are handled, improving safety
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

What’s Kotlin DSL?

A
  • it allows you to define configurations and tasks using Kotin, providing a more readable and type-safe way to write Gradle tasks and UI components in Compose
  • Compare to using Groovy
    • it is easier to read but may have a slower startup time because the code needs to be compiled to bytecode at build time
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
What’s the difference between abstract class and interface in Kotlin?
* abstract class can have abstract and concrete methods, while interface can have abstract and default methods * abstract class can have state with or without default values but interface can only have state declarations * abstract class can have constructors but interface can’t * a class can extend only one abstract class but can implement multiple interfaces * abstract class is used when a class needs to share state with its subclasses, while interface is used to define behaviors that can be implemented by other classes
26
What's the difference between overloading and overriding?
* overloading allows a class to define multiple methods with the same name but different parameters * overriding means that a subclass provides an implementation of a method from its superclass
27
What’s Polymorphism and Inheritance?
* polymorphism allows a method to behave differently based on the object calling it, for example, both Dog and Cat inherit from Animal, but they provide different implementations of the makeSound() method * inheritance allows a class to inherit properties and methods from its superclass
28
What’s Generic in Kotlin?
* it allows defining classes, functions that can work with multiple data types, helping write reusable code * it also ensures type safety at compile time
29
What’s synchronized?
it ensures only one thread can execute a section of code at a time, preventing race conditions and guaranteeing thread safety
30
What’s volatile?
* it ensures that a variable is always read from and written to the main memory, making the latest values visible to all threads * however it doesn’t guarantee Atomicity * in the case of x = x + 1, B reads the value of x before A writes the result back to x, meaning B could see the outdated value of x
31
What’re Concurrency and Parallelism?
* Concurrency allows tasks to run during overlapping time periods but tasks don’t necessarily run simultaneously, focusing on efficient task management * Parallelism enables tasks to run simultaneously, focusing on speeding up execution
32
What’s Atomicity?
* it ensures when a variable is being updated, no other thread can interfere with the operation until it is complete * How to work * x = 0 + 1, is not atomic * AtomicInteger(0).incrementAndGet(), is atomic
33
What are shallow copy and deep copy?
* shallow copy * it creates a new object or collection but only copies the references to nested objects within it * DataClass.copy(), Collections.toList() * deep copy * it creates a new object or collection and also copies all nested objects within it
34
What's an anonymous class?
* it’s a class that has no name and is declared and instantiated in the same time * it’s used when you want a one-time implementation
35
What’s hashCode()?
* it used to generate an ID that helps hash-based collections, such as HashMap, HashSet, efficiently store and retrieve objects * if equals() returns true for two objects, their hashCode() values must be the same
36
What’s static?
it indicates that a field or method belongs to a class itself rather than to any instances of the class, meaning it is shared across all instances of the class
37
What’s reflection?
* it’s used to inspect and modify the structure of a class at runtime, such as accessing methods, fields and metadata * Feature * it can inspect metadata such as the class name * it allows dynamic object creation * it can invoke methods and manipulate field values regardless of visibility * Disadvantage * it leads to slower performance and makes code harder to debug
38
How to create Custom Annotation using KSP?
* create a submodule for the custom annotation * add the KSP plugin and dependency in the build.gradle file * define the custom annotation class * create an annotation processor to find all symbols annotated with the custom annotation and make them do what you want * create an annotation processor provider to provide the processor * register the provider by creating a file named com.google.devtools.ksp.processing.XXX in yourmodule/src/main/resources/META-INF/services/, and the file content should be com.google.devtools.ksp.processing.XXX
39
What’s the difference between KAPT and KSP?
* both handle annotation processing * KAPT is built on Java’s annotation processing, while KSP is designed for Kotlin * KAPT converts Kotlin code into Java stubs, while KSP directly read Kotlin code * KSP is faster than KAPT because it skips the stub generation step * KAPT can lead to errors because some Kotlin-specific language features don’t support
40
What’s ViewModel?
* it’s used to store and manage UI-related data * it retains UI-related data across configuration changes * it is lifecycle aware, so when its lifecycle owner is destroyed, it cleanup its all data * it helps separate business logic from View
41
How does ViewModel work internally?
* each UI component, like an activity or fragment, has a ViewModelStore that stores its ViewModels * UI components access the ViewModelProvider, which is responsible for creating or retrieving a ViewModel from the ViewModelStore to get the ViewModel
42
What’s SingleTask launch mode in Android?
* launch mode defines how an activity is launched * when the launch mode is SingleTask, if the activity already exists in the stack, it reuses it instead of creating a new one, and any activities above it in the stack are destroyed * once the activity is reused, onNewIntent is called
43
Why can’t a Fragment have constructor parameters?
because Android uses reflection to instantiate a Fragment with a no-argument constructor
44
Why does setContentView need to be called in onCreate?
since setContentView is costly, it should be placed in onCreate() that is called only once during the activity lifecycle
45
What’s Coroutine?
* it’s a framework that helps manage concurrency in a performant and simple way * it allows you to write asynchronous code in a synchronous way to avoid a callback hell and make the code easier to read * it also follows structured concurrency, ensuring each coroutine is predictable and safe
46
What’s structured concurrency?
* it’s a principle where concurrency is managed in a safe and predictable way to prevent memory leaks or unhandled exceptions * it ensures each coroutine is launched within a CoroutineScope that defines the lifetime of the coroutine * the outer scope can’t complete until all its children coroutines complete * when the outer scope is canceled, all its children coroutines are also canceled * any errors are properly propagated to the outer scope
47
What’s Dispatcher in Coroutine?
* it determines which thread a coroutine runs on * the default dispatcher for GlobalScope and regular coroutine is Dispatchers.Default
48
When to use Dispatchers.Unconfined?
* it’s used when there is no specific thread requirement * Dispatches.Unconfined starts the coroutine on the current thread but may switch to different thread after resuming
49
What are coroutineScope and supervisorScope?
* both launch a new coroutine and ensure all coroutines within the scope complete before the scope returns * in a coroutineScope * if a child coroutine fails, the scope and all coroutines will be canceled * you should wrap the entire scope in a try-catch block to handle exceptions * in a supervisorScope * if a child coroutine fails, other child coroutines at the same level won’t be canceled, and the scope will continue until all coroutines complete * it’s best to add an individual try-catch block to each task to handle exceptions
50
What’s the suspend keyword?
* it’s used to make a function suspensible and resumable without blocking the thread * the compiler converts the suspend function into a regular function with an additional parameter, Continuation, and changes its return type to Any * the suspend function must be called within a coroutine or another suspend function
51
What’s Continuation?
* it stores the state of a coroutine and is used to resume the coroutine * Internally * the compiler converts the suspend function into a regular function with an additional parameter, Continuation, and changes its return type to Any * when a caller invokes a suspend function, it passes its Continuation to the function. * the suspend function checks whether the passed Continuation matches its expected type * if they don’t match, it means this is the first time that the suspend function is being called, so it creates its own Continuation and stores the caller’s Continuation * when a function encounters a suspend function, its Continuation saves the current state of the function’s variables and marks the current position with a label, then returns a special marker COROUTINE_SUSPENDED to indicate that the execution has been paused * when execution needs to be resumed, the Continuation is used and the function is called again. * at this point, since the caller’s Continuation matches the expected type, a new Continuation won’t be created * the function uses the label to identify the suspension point and the saved variables to continue execution from there
52
What’s withContext?
it’s used to switch the coroutine’s context instead of launching a new coroutine
53
What’s CoroutineContext?
* it defines the behavior of a coroutine, including * Dispatcher * Job which manages the coroutine’s lifecycle * Name usually for debugging * ExceptionHandler which handles uncaught exceptions * Relation * CoroutineContext > Element > Dispatcher,Job,Name,ExceptionHandler
54
What’s the suspendCoroutine and suspendCancellableCoroutine?
* both convert a callback into a suspend function by providing a Continuation to resume the coroutine * suspendCancellableCoroutine is similar to suspendCoroutine, but it provides cancellation support, offering a callback for cleanup
55
What’s runBlocking?
it’s a coroutine builder that blocks the thread until all coroutines inside it complete
56
What’t Job in Coroutine?
it’s used to control and manage the lifecycle of a coroutine
57
What are StandardTestDispatcher and UnconfinedTestDispatcher?
* StandardTestDispatcher * new coroutines are queued and executed only when the thread is free to use * you need to yield the thread to run enqueued coroutines using functions like advanceTimeBy() method * it’s usually used when you want to focus on concurrency * UnconfinedTestDispatcher * new coroutines run immediately * if a coroutine suspends, other coroutines resume execution * it’s usually used when concurrency is not required
58
delay v.s. Thread.sleep
* delay is a suspend function that pauses the coroutine without blocking the current thread * Thread.sleep is a regular function that blocks the current thread
59
What’s Coroutine Flow?
* it’s a code stream that emits values sequentially, unlike a suspend function, which returns a single value * it is built on suspend functions to produce and consume values asynchronously without blocking the thread
60
What’s Flow Builder?
* it’s used to create a flow and define how values are produced, for example, * flow{} which emits values using the emit() method * flowOf which represents a fixed set of values * asFlow which converts a collection into a flow * channelFlow which emits values concurrently using the send() method
61
Cold Flow v.s. Hot Flow?
* a cold flow emits values only when it is collected, and each time a new collector collects the flow, it starts from the beginning * a hot flow emits values even if there are no collectors and all collectors receives the same values
62
StateFlow v.s. SharedFlow?
* StateFlow * StateFlow is a hot flow that retains the latest value and emits updates to its collectors * it requires an initial value and each new collector receives the most recent value * SharedFlow * SharedFlow is a hot flow that doesn’t retain the latest value by default but it can be configured to replay past values to new collectors
63
What’s Channel?
* it’s a hot stream that allows coroutines to concurrently send and receive data between each other * when a consumer receives data from a channel, the data is removed, so other consumers can’t access it
64
What’s ChannelFlow?
* it’s a cold stream that allows multiple coroutines to concurrently send and receive data through a Channel * it combines the concurrency of Channel with the asynchronous nature of Flo
65
What's the terminal operator in Flow?
* since Flow is a cold stream, the terminal operator triggers it to start emitting data * e.g. collect(), reduce(), lauchIn()
66
What’s flowOn?
it’s used to change the CoroutineContext of upstream operations in a Flow
67
How to run Long-running tasks in Parallel in Flow?
you can use the zip() method to combine two flows to get the results of both tasks in a single callback
68
Retry v.s. RetryWhen in Flow?
* both are used to retry a flow’s execution when an error occurs, but neither can emit new values within the scope * the difference is that retryWhen can access the number of attempts to decide whether to retry
69
Debounce in Flow?
a flow emits a new value only if no other value has been emitted within a specific time interval
70
What’s catch in Flow?
it intercepts exceptions that occur during flow execution and allows emitting fallback values
71
What’s onCompletion in Flow?
* it’s used to perform actions when the flow completes, regardless of whether it is successful or not * it receives a cause object as a parameter, which determines whether the flow was successful * the call order is determined by the order in which they are placed
72
What’s TestDispatcher?
it provides a way to control the execution of coroutines during testing, ensuring that coroutines are predictable by simulating delays and manually controlling execution
73
Why is launching a coroutine or withContext invalid in a Flow?
it makes the flow non-sequential and concurrent emissions are prohibited in Flow
74
What causes App Lag?
* frequent GC * too much work is being done on the main thread * Solution: * use lazy initialization to defer initialization until it is needed * declare commonly used variables as static to prevent memory allocation overhead * move time-consuming tasks to a background thread
75
What’s Context?
it provides the access to app resources, system services and environment information
76
What’s ApplicationContext?
* it’s tied to the app lifecycle and remains alive as long as the app is running * use it when you need a long-lived context and use the activity context when you want perform UI operations
77
How to communicate between two Fragments?
Both fragments share the same ViewModel or the hosting activity acts as a mediator to pass data
78
What’s the retained Fragment?
the fragment persists across configuration changes by calling setRetainInstance(true)
79
What’s the purpose of addToBackStack?
it’s used to add a transaction to the back stack, enabling the reversal of the transaction and allowing the user to return to the previous fragment when pressing the back button
80
What's the difference between View and ViewGroup?
* View is a single UI element that displays content and interacts with the user * ViewGroup is a container that holds multiple Views and other ViewGroups
81
What’s the difference between SurfaceView and TextureView?
* SurfaceView * it runs on a background thread, offering better performance than TextureView * it renders on a separate surface and overlays the main UI * TextureView * it is a part of the view hierarchy, runs on the main thread and supports content transformations such as moving, resizing, rotating, etc.
82
What’s RecyclerView?
* it’s an efficient view for displaying a large dataset * it improves the performance by reusing the views that are no longer visible on the screen
83
How to improve RecyclerView?
* do not do too much work in onBindViewHolder * instead of using notifyDataSetChanged, use notifyItemChanged for specific changes to minimize unnecessary layout refreshes * use setStableIds and override getItemId in the adapter to reuse the original ViewHolder even when the data position changes * use setHasFixedSize if the layout size doesn’t change when the data set is updated to skip unnecessary layout recalculations
84
What’s DiffUtil?
it’s used to calculate the difference between two datasets, offering better performance for RecyclerView updates with minimal changes
85
What’s Service and IntentService?
* both are used to perform time-consuming tasks in the background * Service * the task runs on the main thread, meaning that it can block the thread if the task takes too long * it needs to be manually stopped by calling stopService or stopItself * IntentService * the task runs on a background thread, making it more efficient for time-consuming tasks * it is triggered via an intent and automatically stops itself after the task completes * tasks can’t run in parallel because each task is enqueued to the message queue of the worker thread and processed sequentially
86
Implicit v.s. Explicit Intent?
* explicit intents specifies which component should handle the intent * implicit intents specifies an action, and the OS decides which components can handle the intent
87
What’s ContentProvider?
* it provides a way to expose data to other apps * other apps can use ContentResolver to interact with exposed data via an URI
88
What’s ContentResolver?
it’s used to interact with data exposed by ContentProvider via an URI
89
What’s ANR?
* too much work is being done on the main thread, causing it to be blocked and unresponsive to user interactions * move time-consuming tasks to background threads, making the main thread free to respond to user interactions
90
What’s Handler?
* it acts as a mediator to communicate between threads, allowing messages to be passed from one thread to another * it works along with three elements: * MessageQueue stores messages that need to be processed * Looper continuously retrieves and processes messages from MessageQueue * each thread has one looper, and each looper contains one MessageQueue * Work internally: * the handler is tied to the looper of the thread that we want to communicate with and sends the message to the corresponding message queue * the looper continuously retrieves messages from the message queue and executes them on the corresponding thread * When to use: * post UI updates to the main thread after a task completes on a background thread * schedule delayed or repeated tasks
91
What’s Memory Leak and Garbage Collection?
* memory leak * memory leak means an object is no longer needed but is still referenced, preventing it from being garbage collected * you can detect the memory leak using Android Studio Profiler or LeakCanary * Prevent: * use weak references instead of strong references as they should not prevent garbage collection * use ApplicationContext instead of ActivityContext for non-UI operations * properly remove callbacks and listeners in onDestroy * use lifecycle-aware components that automatically clean up when the lifecycle ends * garbage collection * it’s a process that frees up the memory by removing objects that are no longer needed
92
What’s OOM?
* every app has a memory limit, if it exceeds the limit, an OOM exception will be thrown * to prevent this issue, optimize bitmap usage and avoid memory leaks to reduce the possibility of OOM
93
How to reduce memory usage?
* use caches for frequently accessed data * reduce image size by using inSampleSize * reuse bitmaps through bitmap pools
94
What’s WeakReference?
* it’s a reference that doesn’t prevent the referenced object from being garbage collected * Work Internally * if an object has strong references, it can’t be garbage collected even if it’s no longer used * if an object has only weak references, it can be garbage collected
95
What’s DataStore?
* it’s used to asynchronously store lightweight data * unlike SharedPreferences, DataStore is type safety, provides a lot of asynchronous APIs for reading and writing data, and allows you to observe the changes using Flow or LiveData
96
What are Preference DataStore and Proto DataStore?
* Preference DataStore * it’s designed for key-value storage, similar to SharedPreferences * it uses type-safe keys to define data keys and supports common types like Int, Double, String, etc * Proto DataStore * it’s designed for storing complex data structures using Protocol Buffers, which requires a defined schema * Protocol Buffers provide efficient serialization
97
commit and apply in SharedPreference?
* commit * it’s a synchronous operation and blocks the thread until the operation completes * it returns a boolean value indicating whether the operation was successful * apply * it’s an asynchronous operation and doesn’t return any results
98
What’s ORM?
* Object-Relational Mapping * each database table corresponds to a class, allowing interacting with the database using objects instead of SQL queries, making operations simpler * e.g. Room
99
What’s ComponentCallback2?
it’s used to receive memory-related callbacks such as onTrimMemory, helping app handle low memory situations
100
What’s NDK?
* Native Development Kit * it’s a tool that allows developers to write native code (C/C++) and integrate it with Java/Kotlin using JNI * Advantage * native code is compiled into machine code, bypassing ART for better performance * it provides manual memory management and access to low-level APIs such as graphics, FFmpeg, etc
101
What’s the process of converting Java/Kotlin code to running on a device?
* the compiler convert Java/Kotlin code into bytecode * Proguard or R8 optimizes and shrinks the code * Android build tools transform the bytecode into multiple .dex files * the .dex files, resources and native libraries are bundled into an APK or AAB * Android OS uses ART to convert .dex files into machine code, then runs it on the device
102
Why are ART and Dalvik needed?
* devices can’t run bytecode, so it needs to be converted to machine code * the conversion is handled by ART or Dalvik depending on the Android version
103
What’s JIT?
* Just-in-Time compilation * it’s a process where bytecode is converted into machine code at runtime, meaning only the code that is actually executed gets compiled * frequently used code is cached, helping avoid re-compiling it again
104
What’s AOT?
* Ahead-of-Time compilation * it’s a process where bytecode is converted into machine code before the app is executed * this allows the app to run more efficiently because the conversion has already been done in advance
105
What’s Dalvik?
* Dalvik uses JIT compilation to convert bytecode into machine code at runtime * advantage: * it has a smaller apk size and faster installation time * disadvantage: * it has lower performance and a longer startup time
106
What’s ART?
* Android Runtime * ART uses both AOT compilation to convert bytecode into machine code during installation and JIT compilation for runtime optimization * only the hot code that is determined by Profile-guided optimization uses AOT, while remaining code is compiled using JIT * advantage: * it has higher performance and a less startup time * disadvantage: * it has a larger apk size and longer installation time
107
What’s Profile-guided optimization?
* it collects runtime data to identify the most frequently used code to precompile, improving runtime performance * initially, the app may run slowly, but it will become faster over time
108
What’s ART Cloud Profile?
it collects runtime data from other devices to precompile, improving the initial performance of the app
109
What’s Baseline Profile?
* it’s a file created by developers that identifies the most frequently used code to precompile, reducing startup time and improving runtime performance * the file will be uploaded with APK or AAB
110
What’s Jetpack?
it’s a collection of Android libraries designed to streamline the app development, including ViewModel, LiveData, Compose
111
What’s LiveData?
* it’s an observable data holder that respects the lifecycle of its observers * it ensures that UI updates are lifecycle-aware, meaning observers are notified only when they are in an active state * it’s thread-safe, ensuring that observers are notified on the main thread * it automatically cleans up when the lifecycle is destroyed, preventing memory leaks
112
What's the difference between setValue and postValue in LiveData?
* setValue * it must be called on the main thread * it updates the value synchronously and notifies observers immediately * postValue * it can be called from any thread * it updates the value asynchronously by posting it to the main thread’s message queue, meaning the update may be delayed
113
What’s the difference between LiveData and StateFlow?
* LiveData is lifecycle-aware, while StateFlow can be made lifecycle-aware using repeatOnLifecycle * StateFlow requires an initial value, whereas LiveData does not * LiveData’s observers are notified on the main thread, whereas StateFlow’s collectors are notified on the thread where the flow is collected
114
What’s WorkManager?
* it is used to schedule and execute background tasks even when the app is not running * it supports constraints such as network connectivity, battery status, and it can chain multiple tasks to run sequentially or in parallel
115
What’s Serialization?
it’s a process of converting an object into a format that can be easily stored and transmitted
116
What’s Deserialization?
it’s a process of converting serialized data back into its original object form
117
Parcelable v.s. Serializable?
* Parcelable is an Android-specific interface, while Serializable is an Java interface * Parcelable is faster than Serializable because it avoids reflection when serializing objects (Parcelable implements custom conversion functions) * Serializable creates more temporary objects due to reflection * Serializable is simpler to implement, whereas Android Studio provides a plugin to streamline the setup of Parcelable
118
Gson v.s. Jackson?
* Jackson offers better performance and additional features such as the streaming API * Gson is simpler as it requires less code and configuration
119
What’s Interceptor?
* it’s used to intercept, modify, retry the network requests and responses * addInterceptor * it operates at the application level, modifying requests before they are sent to the server * it’s commonly used for adding custom headers and authentication tokens, logging and response caching * addNetworkInterceptor * it operates at the network level * it’s commonly used for handling redirections, retries and tracking request progress
120
What’s Hilt?
* it’s a DI framework built on Dagger * it uses annotations to generate code at compile time, ensuring safe and efficient dependency injection * it scopes dependencies to the lifecycle of Android components, preventing memory leaks
121
What’s Koin?
* it’s a lightweight DI framework designed for Kotlin * it resolves dependencies at runtime using a Service Locator pattern * it uses Kotlin DSL to define dependency modules, making implementation easier and improving readability
122
Compare between Hilt and Koin?
* implementation: * Hilt uses annotations to generate dependencies at compile time * Koin uses Kotlin DSL to define dependency modules and resolves them at runtime * Koin is more lightweight as it doesn’t generate extra code * Hilt is more safer since dependencies are resolved at compile time
123
What are Component, Module, Scope in Hilt?
* Module: * a module provides dependency definitions * Component: * a component determines the lifecycle of dependencies * e.g. SingletonComponent, ActivityComponent * Scope: * a scope ensures dependencies persist as long as the associated component is alive * if no scope is specified, each request gets a new instance * the scope must match the scope of the component, for example, a dependency within ActivityComponent must be ActivityScoped * e.g. @Singleton, @ActivityRetainedScope
124
What are @Provides and @Binds?
* both are used to define how dependencies are provided * provides is used when a dependency needs to be created using a constructor or factory method * binds is used to bind an interface or abstract class to its implementation
125
What’s EntryPoint in Hilt?
it acts as a bridge to inject dependencies into classes that Hilt doesn't support
126
What’s @AndroidEntryPoint?
* it’s used to simplify dependency injection for Android components * Hilt automatically generate an abstract base class which the component extends to handle injection, allowing the component receives dependencies without manual setup
127
What’s inBitmap?
* it’s an option that allows reusing an existing bitmap when decoding a new image, which helps reduce memory allocations * Limit * the reused bitmap must be mutable and its size must be equal to or larger than the size of the decoded image; otherwise, a new bitmap is created * it must be used with inMutable
128
What’s bitmap pooling?
* it’s used to prevent frequent memory allocation by reusing bitmaps * you can set BitmapFactory.Options inBitmap or use a third-party bitmap pool to access bitmaps * to customize the bitmap pool, you can use LruCache to manage the storage of bitmaps
129
How does Glide work internally?
* Glide uses two levels of caching * memory caching * it uses LruCache to store images in memory, allowing quick access and reducing the overhead of decoding * disk caching * it is split into original and transformed caches, both use DiskLruCache to store images on disk * it reuses bitmaps using a bitmap pool, reducing frequent memory allocations * it is lifecycle-aware, creating a hidden Fragment to attach to the context and automatically cancelling image requests when the lifecycle of the context is destroyed * it automatically downsamples images to optimize the memory usage
130
What are MVC, MVP?
* MVC * Activity acts as both View and Controller, violating the single responsibility principle * as complexity increases, maintaining Activity becomes difficult * MVP * Presenter communicates with View using an interface, which is usually implemented by View itself * Presenter’s holding the reference to View can lead to memory leaks * as complexity increases, the interface grows larger and the coupling between View and Presenter becomes stronger
131
What’s MVVM?
* View observes the change in observable data provided by ViewModel to update UI, reducing coupling and separating business logic from View * View directly interacts with ViewModel by calling its methods to update the state * as complexity increases, the state management becomes difficult, reducing flexibility
132
What’s MVI?
* Intent represents the user actions that View sends to ViewModel to trigger a state change * MVI follows Unidirectional Data Flow that makes state management more predictable * however it requires more boilerplate code to define actions
133
What’s the difference between MVVM and MVI?
* In MVVM * View directly interacts with ViewModel by calling its methods, which can make state management more difficult as complexity increases * In MVI * View interacts with ViewModel by sending an Intent, meaning View doesn’t need to know how ViewModel works and ViewModel doesn’t need to expose methods. this makes state management more predictable * however it requires more boilerplate code to define actions
134
What’s Dependency Injection?
* it’s a design pattern where an object receives dependencies from an external source instead of creating them itself * it simplifies dependency management and improves testability
135
What’s the design pattern - Builder?
* it’s used to separate the creation logic from the object itself to construct complex objects step by step, improving flexibility while enhancing reusable * Example * AlertDialog * Notification * Glide
136
What’s the design pattern - Singleton?
* it ensures that a class has only one instance, providing global access to it and reducing memory usage * Example * Application * Room database
137
What’s the design pattern - Factory?
* it provides an interface or a method to create an object without directly calling its constructor, so clients don’t need to know how objects are created, making the code easier to maintain and extend * Example * ViewModelProviderFactory * Fragment instantiation
138
What’s the design pattern - Observer?
* it defines a one-to-many relationship, as the data updates, all its observers are notified, decoupling the data from the observers * Example * LiveData * EventBus
139
What’s the design pattern - Repository?
* it provides a way to abstract data access and offer a clean interface without exposing data sources, so clients can focus on business logic without needing to know how the data is fetched * Example * data repository
140
What’s the design pattern - Adapter?
* it acts as a bridge between two incompatible objects to convert one into another * Example * RecyclerView Adapter * ViewPager Adapter
141
What’s the design pattern - Facade?
* it provides a simplified interface to a complex system, reducing coupling and making the system easier to use * Example * MediaPlayer
142
What’s the difference between TestRule and TestWatcher?
* TestRule * it’s more flexible, allowing custom behavior for tests, such as modifying test execution conditions * TestWatcher * it extends TestRule and provides default implementation for lifecycle methods like starting(), finished(), making it easier and more commonly used
143
What’s InstantTaskExecutorRule?
it replaces the default background executor, forcing LiveData and other background operations to execute synchronously on the test thread, ensuring LiveData updates are immediate and tests are predictable
144
What’s Robolectric?
it allows Android tests to run on JVM without needing an emulator or physical device by simulating the Android environment, making test execution faster but less reliable
145
What are Unit Test and Instrumented Test?
* unit test * it focuses on testing small parts of code, such as functions and classes * instrumented test * it focuses on testing real Android components to ensure they work correctly on an Android device or emulator
146
What’s code coverage?
it measures the percentage of the codebase that is executed during testing
147
What’s ADB?
* it’s a command-line tool that allows you to interact with Android devices * Example * adb devices: list all devices connected to the computer * adb install < path-to-apk >: install an apk on a connected device
148
What’s Strict Mode?
* it is a debugging tool that helps developers detect performance issues, such as when the main thread is blocked * it provides a dialog or log to display to the developer
149
What’s Lint?
* it’s a code analysis tool that helps developers detect potential issues in the code, such as code style violations * How to create a custom lint rule * add dependencies * create a class that extends Detector() and implement SourceCodeScanner to define a rule * create an issue object for the rule * create a repository that extends IssueRegistry() to register the issue
150
What are Proguard and R8?
* both are used to optimize, obfuscate and shrink the app’s code to make it more secure, smaller and performant * code obfuscation makes the code harder to reverse-engineer by renaming classes, methods * code shrinking reduces the size of the app by removing unused code and resources
151
What’s the difference between Proguard and R8?
* R8 has replaced Proguard as the default tool * R8 is faster than Proguard because it integrates the dexing process * the size of the app created by R8 is smaller than with Proguard due to its better algorithm * R8 is enabled by default * R8 is maintained by Google
152
How to reduce APK size?
* use R8 to shrink the apk size by removing unused code and resources * switch to AAB for serving optimized APKs for different devices * prefer using vector drawables over PNGs to reduce image size * use ABI to separate binary code for different OS platforms
153
What’s ABI?
* it defines how binary files interact with OS and platform * it ensures the app includes only the necessary code for the target device, reducing the size of the app
154
How to speed up the Gradle build?
* enable parallel execution * use the build cache * remove unnecessary dependencies
155
What’s Write-Ahead Logging (WAL)?
* it’s a technique where changes to the database are first written to a log file before being applied to the database * as the log file reaches a checkpoint, all updates are committed to the database * it ensures data integrity and allows recovery in case of an error * it also improves performance because appending every change to a log file is faster than directly modifying the database
156
What’s ThreadPoolExecutor?
* it’s an efficient utility for managing and reusing threads, enabling concurrent execution of tasks * a thread pool maintains a collection of reusable threads, reducing the overhead of thread creation * How it works (when a task is submitted) * if the number of threads is less than the core pool size, a new thread is created * if core threads are busy, the task is added to the queue * if the queue is full and the number of threads is less than the max pool size, a new thread is created * if the queue is full and the max pool size is reached, the task is rejected
157
What’s the transient modifier?
* it’s used to indicate that a field should not be serialized, meaning it will be excluded in the serialized form * it’s used for fields that contain sensitive or unnecessary data that you don’t want to persist * after deserialization, the field is set to default value, and if the field is a non-null object type, accessing it may throw an exception
158
What’s Compose?
* it’s used to develop UI in a declarative and flexible way instead of using XML * it simplifies UI development by making it easier to manage state, handle updates efficiently and create reusable UI elements * when the state changes, compose only re-executes the parts that depend on the updated state, making UI updates more efficiently * UI elements are defined as composable functions in Kotlin
159
What’s the difference between declarative UI and traditional UI?
* Delcarative * it describes what the UI should look like, and it automatically updates when the state changes * it makes UI development more efficient and eliminates the need for manual updates * Traditional * it describes how the UI should be built, requiring manual updates when the state changes
160
What’s the remember keyword in Compose?
* it’s used to retain data across recompositions until the composable is removed * without remember, all variables inside a composable function would be created on every recomposition
161
What’s Recomposition?
* it’s the process of updating UI when the state changes * instead of recreating entire UI, compose only re-executes the parts that depend on the updated state, making UI updates more efficient and avoiding unnecessary recomputation
162
What’s state hoisting?
* it means that a compoable doesn’t manage its own state but instead receives the state and a way to update it from its parent * it makes the composable stateless, more reusable and easier to manage
163
What’s side effects?
* it indicates changes to the state or other app behaviors that happen outside the scope of a composable function * these changes are typically triggered by user interactions or external events and can affect the state and UI
164
What’s CompositionLocal?
* it’s used to pass data down the UI tree without passing it as a parameter to every composable * it helps reduce boilerplate code while keeping the data accessible only within the defined scope * How to work * create a CompositionLocal variable * use CompositionLocalProvider to set a value for the CompositionLocal * get the value of CompositionLocal via .current in the Composable
165
What's State Management in Compose?
Compose encourages unidirectional data flow, meaning the state flows down and the events flow up and UI reacts to the state changes
166
What’s rememberCoroutineScope?
it’s used to provide a coroutine scope tied to the lifecycle of a composable, ensuring all launched coroutines are automatically canceled when the composable is destroyed
167
How to convert a non-compose state into a Compose state?
* convert a flow or livedata into state using collectAsState and observeAsState * convert regular data into state using remember with mutableStateOf * transform the asynchronous results or side effects into state using produceState which needs an initial value * derive state from existing state using derivedStateOf
168
What’s derivedStateOf?
it’s used to create state derived from another state, ensuring recomposition is triggered only when the derived state changes, not every time the original state changes
169
What’s rememberUpdatedState?
it’s used to create state that always refers to the latest value of another state, ensuring the latest value is used even after recomposition or when used inside side effects
170
What’s rememberSaveable?
it’s used to retain state across recompositions and configuration changes by saving the state value to a bundle and restoring it when the composable is recreated
171
What’s the lifecycle of a composable?
* initial composition * it happens when a composable first enters the screen * the composer evaluates the UI tree and creates the UI elements * recomposition * it happens when the state of the composable changes * only affected parts of the composable are recomposed, not the entire composable * skipping * during recomposition, if the state of the composable hasn’t changed, the composable is skipped in the process * disposal * when the composable leaves the screen, it is removed from the composition
172
How to handle lifecycle events in Compose?
* first, launch a DisposableEffect tied to the lifecycle of the composable * second, inside the DisposableEffect, create the observer tied to the lifecycle owner to observe the lifecycle changes * finally, remove the observer from the lifecycle owner in the onDispose callback for cleanup
173
How to optimize performance in Compose?
* it includes minimizing unnecessary recomposition, deferring expensive calculations and using the stable data type as parameters * use remember to avoid re-executing expensive calculations * if possible, use immutable or stable data types as parameters of a composable to prevent unnecessary recomposition * use lazy composables like LazyColumn and LazyRow for large datasets * specify a unique key for each item in a lazy composable * use lambda parameters for accessing frequently changing state to change the state read scope * if possible, use lambda modifiers instead of modifiers to defer the state read to the layout phase or draw phase
174
What’s key in Lazy Composable?
* it’s used to identify list items and reduce unnecessary recompositions for lazy composables * when the order of a dataset changes but all items remain the same, compose assumes that all items have changed, causing it to recompose each item * providing a key helps compose recognize unchanged items and avoid recomposing them
175
Why wrap the state read in a lambda?
* when the state changes, in addition to the composables that access the state, other unrelated composables at the same scope level are also recomposed * wrapping the state read in a lambda prevents unnecessary recompositions of unrelated composables * only wrap frequently changing states because creating a lambda has some extra cost
176
Why use lambda modifiers instead of modifiers?
* these lambda modifiers are called only in the layout or draw phase * using lambda modifiers can defer the state read to the layout or draw phase, so the whole composition gets skipped even if the state changes
177
Phases in Compose?
* try to move the state read to the lowest possible phase * Composition * the phase describes the UI by running composable functions * Layout * the phase measures the size of UI elements and determines their placements * Layout composable and the offset lambda modifier are called in this phase * Drawing * the phase renders the UI on the screen * Canvas composable and the drawBehind lambda modifier are called in this phase
178
How does the layout phase work?
* each composable measures the size of child composables if it has any * and decides its own size based on these measurements, but within the constraints provided by its parent * after calculation, it places all child composables inside it
179
What’s Unidirectional data flow in Compose?
it follows the principle where state flows down from the parent to the child and events flow up from the child to parent, making it easier to debug and ensuring UI consistency
180
What’s Unidirectional Flow?
it’s a principle where data flows in a single direction, from state to UI and actions back to state, ensuring that state changes and user interactions follow a single path, making the state management more predictable
181
How to avoid API keys from check-in into VCS?
* store the key into a gradle.properties file * read the value from the file and add it to BuildConfig in build.gradle file * access the value using BuildConfig in your code * exclude the gradle.properties file from VCS
182
What’s the process of event dispatch in Android View?
* there are three stages: * dispatchTouchEvent is an entry point for events and returns whether the event is consumed by itself or its children * onInterceptTouchEvent determines whether the event should be intercepted, if intercepted, the event won’t be propagated further and onTouchEvent is called * onTouchEvent determines whether the event is consumed, if not, the event is propagated to the next view * ViewGroup contains all three methods, but View doesn’t have onInterceptTouchEvent * whether a complete event sequence is received depends on whether the TOUCH_DOWN event is consumed * if a ViewGroup intercepts TOUCH_DOWN, subsequent events will bypass onInterceptTouchEvent and directly go to onTouchEvent * if TOUCH_DOWN is not consumed in onTouchEvent, subsequent events will bypass the View or ViewGroup
183
What will happen if a view event is not consumed by Views and ViewGroups?
the event will be handled by the activity
184
Why might Coroutine not be canceled?
* cancellation only changes the state of the coroutine, but it doesn’t stop the execution * if the coroutine is performing a long-running task, it may not have a chance to check for the cancellation status, meaning cancellation won’t take effect immediately
185
What’s Noncancellable in Coroutine?
* it’s a special job that allows a coroutine to run code even if the coroutine has been canceled * it’s designed for use with withContext, and it’s helpful for cleanup
186
What are Job and SupervisorJob in Coroutine?
* Job is used to control and manage the lifecycle of a coroutine * SupervisorJob is similar to Job, but it ensures that if one coroutine fails, it doesn’t cancel its sibling coroutines, making it useful for managing independent tasks
187
What are launch and async in Coroutine?
* launch is used to launch a coroutine and it returns a reference to the coroutine as Job * async is used to launch a coroutine and it returns its future result as Deferred
188
What’s SharingStarted in Flow?
* it’s a principle that defines when the flow starts emitting values * there are three values with different behaviors * Eagerly * the flow starts emitting values as soon as it is created * Lazily * the flow starts emitting values as soon as the first collector collects * WhileSubscribed * the flow starts emitting values as the first collector collects and stops emitting values when no collectors are collecting within a time period * it can also configure a duration for keeping the replay cache
189
How does the Handler process asynchronously sent messages?
MessageQueue uses a synchronization mechanism to ensure thread safety
190
How does LeakCanary work internally?
* LeakCanary detects memory leaks using a WeakReference with a ReferenceQueue * when an object becomes unreachable, the WeakReference should be added to the ReferenceQueue * LeakCanary checks the ReferenceQueue to see if the WeakReference appears, if not, it indicates that a leak has occurred
191
What’s the difference between requestLayout and invalidate?
* requestLayout only triggers onMeasure() and onLayout, it doesn’t execute onDraw() unless the View’s position or size changes * invalidate only triggers onDraw()
192
What’s @Composable annotation?
* it’s used to define a composable function and doesn’t trigger an annotation processor * it marks a function to be processed by the Compose compiler and can be called from other composable functions
193
What’s a Composer?
* it’s used to manage the UI state and the recomposition process * it keeps track of the order of composables to map the UI tree, which is stored as a table * when the state changes, it compares the differences between the new state and old state and only re-executes the affected parts of UI to update it
194
What’s Launch Mode in Android?
* it defines how an activity is launched * there are four launch modes: * standard * create a new activity instance in the current stack * singleTop * create a new activity instance only when the top of the current stack is not the activity instance; otherwise, the onNewIntent() method is called * singleTask * create a new activity instance only when there is no activity instance in the current stack; otherwise, the onNewIntent() method is called and other activity instances above the activity in the stack are destroyed * singleInstance * create a new activity instance in a new stack
195
What’s Covariance and Contravariance?
* both are used to define the inheritance relationship between generic types * Covariance is used to retain the inheritance relationship, for example, if A is a subclass of B, the generic type T is also a subclass of the generic type T * Contravariance is used to reverse the inheritance relationship, for example, if A is a subclass of B, the generic type T is a subclass of the generic type T
196
What’s clean architecture?
* the architecture usually splits the app into three layers, Data, Domain, and Presentation, ensuring that changes in one layer minimally affect the others, thus improving flexibility and testability * many implementations use dependency injection frameworks like Hilt or Koin to manage dependencies and follow patterns such as MVVM or MVI to handle UI interactions
197
What’s Paging?
* Paging is designed to load data in small rather than all at once, minimizing memory usage and reducing network overhead * there are the following components: * PagingSource * PagingSource is used to load data based on the page number and the page size in the passed parameter and returns the result * Pager * Pager ties everything together and is used to provide a stream of PagingData * PagingDataAdapter * Adapter connects to RecyclerView with the PagingData stream, and it uses DiffUtil to minimize the changes
198
What’s getRefreshKey in PagingSource?
it provides a refresh key that determines the position where the refresh should begin
199
What’s LoadState in Paging?
* it represents the current status of data loading * there are three load types * Refresh: triggered during the initial load or when the data is being refreshed * Append: triggered when more data is being loaded * Prepend: triggered when loading data before the currently loaded items * there are three load states * Loading: indicates that loading is in progress * NotLoading: indicates that there is no active loading * Error: indicates that an error occurred during loading
200
What's an Annotation Processor?
it’s a tool that runs during compilation can generate code, modify existing code, and perform another action based on annotations