跳转至

附录C Android面试题库

Android开发面试常见问题汇总


1. Kotlin基础

Q1: Kotlin中的valvar有什么区别?

答案: - val:不可变变量,类似于Java的final,只能赋值一次 - var:可变变量,可以多次赋值

Kotlin
val name = "Alice"  // 不可变
var age = 25        // 可变
age = 26            // ✅ 可以
name = "Bob"        // ❌ 编译错误

Q2: Kotlin的空安全机制是如何工作的?

答案: Kotlin通过类型系统区分可空和非空类型: - String:非空类型,不能为null - String?:可空类型,可以为null

Kotlin
var nullable: String? = null      // 可为null
var nonNull: String = "value"     // 不可为null

// 安全调用
val length = nullable?.length     // null时返回null

// Elvis操作符
val len = nullable?.length ?: 0   // null时使用默认值

// 非空断言(谨慎使用)
val risky = nullable!!.length     // null时抛出NPE

Q3: 什么是数据类(data class)?

答案: 数据类是Kotlin中用于存储数据的特殊类,编译器自动生成: - equals()/hashCode() - toString() - copy() - componentN()(解构函数)

Kotlin
data class User(val id: String, val name: String, val age: Int)

val user = User("1", "Alice", 25)
val copy = user.copy(name = "Bob")
val (id, name, age) = user  // 解构

Q4: Kotlin协程是什么?

答案: 协程是轻量级线程,用于简化异步编程:

Kotlin
// 启动协程
val job = viewModelScope.launch { /* 后台任务 */ }

// 异步返回结果
val deferred = viewModelScope.async { fetchData() }
val result = deferred.await()

// Flow响应式流
flow {
    emit(1)
    emit(2)
}.collect { value -> println(value) }

2. Android基础

Q5: Activity的生命周期有哪些?

答案:

Text Only
onCreate() → onStart() → onResume() → [运行中]
[运行中] ← onResume() ← onRestart() ← onPause()
                                onStop()
                                onDestroy()

Q6: Android中的四大组件是什么?

答案: 1. Activity:用户界面组件 2. Service:后台服务组件 3. BroadcastReceiver:广播接收器 4. ContentProvider:内容提供器

Q7: Handler机制原理是什么?

答案: Handler用于线程间通信,核心组件: - Handler:发送和处理消息 - Looper:消息循环器 - MessageQueue:消息队列 - Message:消息对象

Kotlin
// 创建Handler
val handler = Handler(Looper.getMainLooper()) {
    // 处理消息
    true
}

// 发送消息
handler.sendMessage(Message.obtain())
handler.post { /* 任务 */ }

Q8: Android中的存储方式有哪些?

答案: | 方式 | 特点 | 适用场景 | |------|------|----------| | SharedPreferences | 键值对,轻量 | 简单配置 | | DataStore | 类型安全,异步 | 替代SharedPreferences | | Room | SQLite封装,类型安全 | 结构化数据 | | 文件存储 | 原始文件 | 大文件、缓存 | | MMKV | 高性能键值对 | 高频读写 |


3. Jetpack组件

Q9: ViewModel的作用是什么?

答案: ViewModel用于: - 管理UI相关数据 - 在配置变更时保持数据 - 分离业务逻辑和UI

Kotlin
class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> = _data

    fun loadData() {
        viewModelScope.launch {
            _data.value = fetchData()
        }
    }
}

Q10: LiveData和StateFlow的区别?

答案: | 特性 | LiveData | StateFlow | |------|----------|-----------| | 生命周期感知 | ✅ 自动 | ❌ 需手动 | | 初始值 | ❌ 无 | ✅ 必须有 | | 状态重放 | ❌ 无 | ✅ 最新值 | | 线程 | 主线程 | 任意线程 | | 协程支持 | 有限 | 原生支持 |

Q11: Room数据库如何使用?

答案:

Kotlin
@Entity
data class User(@PrimaryKey val id: String, val name: String)

@Dao
interface UserDao {  // interface定义类型契约
    @Query("SELECT * FROM user")
    fun getAll(): Flow<List<User>>

    @Insert
    suspend fun insert(user: User)
}

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Q12: WorkManager的作用是什么?

答案: WorkManager用于执行可延迟的后台任务,特点: - 保证任务执行 - 支持约束条件(网络、电量等) - 支持链式任务 - 兼容各种Android版本

Kotlin
val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(workRequest)

4. Jetpack Compose

Q13: Compose中的重组(Recomposition)是什么?

答案: 重组是指Composable函数在状态变化时重新执行以更新UI: - 自动触发 - 可跳过未变化的组件 - 使用remember缓存计算

Kotlin
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("Count: $count")  // count变化时重组
    }
}

Q14: 如何在Compose中管理状态?

答案:

Kotlin
// 本地状态
var text by remember { mutableStateOf("") }

// 状态提升
@Composable
fun Parent() {
    var text by remember { mutableStateOf("") }
    Child(text = text, onTextChange = { text = it })
}

// ViewModel状态
@HiltViewModel
class MyViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(UiState())
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()
}

Q15: Compose中的副作用有哪些?

答案:

Kotlin
// LaunchedEffect:在协程中执行副作用
LaunchedEffect(key) {
    // 在key变化时执行
}

// SideEffect:每次重组成功时执行
SideEffect {
    // 同步到外部系统
}

// DisposableEffect:需要清理的副作用
DisposableEffect(key) {
    // 初始化
    onDispose {
        // 清理
    }
}


5. 架构设计

Q16: MVVM架构的优势是什么?

答案: - 分离关注点:UI、业务逻辑、数据分离 - 可测试性:ViewModel可独立测试 - 可维护性:代码结构清晰 - 生命周期安全:ViewModel自动处理生命周期

Text Only
View (UI Layer)
ViewModel (Presentation Layer)
Repository (Data Layer)
DataSource (Network/Local)

Q17: 依赖注入是什么?为什么要使用?

答案: 依赖注入(DI)是将依赖从外部传入,而不是在内部创建:

优点: - 解耦组件 - 便于测试(可替换Mock) - 单例管理 - 生命周期管理

Kotlin
// Hilt示例
@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: MyRepository
) : ViewModel()

Q18: 单例模式在Android中的实现方式?

答案:

Kotlin
// Kotlin object(推荐)
object DatabaseHelper {
    fun query() { }
}

// 伴生对象
class Manager private constructor() {
    companion object {
        @Volatile
        private var instance: Manager? = null

        fun getInstance() = instance ?: synchronized(this) {  // synchronized同步锁,保证线程安全
            instance ?: Manager().also { instance = it }
        }
    }
}

// Hilt单例
@Singleton
class Repository @Inject constructor()


6. 性能优化

Q19: 如何优化RecyclerView/List性能?

答案:

Kotlin
// 1. 使用ViewHolder模式
// 2. 设置固定大小
recyclerView.setHasFixedSize(true)

// 3. 使用合适的LayoutManager
// 4. 分页加载
// 5. 图片懒加载
// 6. 缓存复用

Q20: 内存泄漏的常见原因及解决方案?

答案: | 原因 | 解决方案 | |------|----------| | 静态引用Activity | 使用WeakReference | | 未注销监听器 | 在onDestroy中注销 | | 匿名内部类 | 使用静态内部类 | | Handler延迟消息 | 使用静态Handler + WeakReference | | 资源未释放 | 及时关闭Cursor、Bitmap等 |

Q21: 如何优化应用启动速度?

答案: 1. 延迟初始化非必要SDK 2. 使用SplashScreen API 3. 减少Application.onCreate工作量 4. 使用Profile Installer 5. 优化主题背景(windowBackground)


7. Flutter

Q22: Flutter中的Widget是什么?

答案: Widget是Flutter UI的基本构建块: - StatelessWidget:无状态,不可变 - StatefulWidget:有状态,可更新

Dart
// StatelessWidget
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello');
  }
}

// StatefulWidget
class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => setState(() => count++),
      child: Text('$count'),
    );
  }
}

Q23: Flutter中的状态管理方案有哪些?

答案: | 方案 | 特点 | 适用场景 | |------|------|----------| | setState | 简单 | 简单页面 | | Provider | 轻量 | 中小型应用 | | Riverpod | 安全 | 中大型应用 | | Bloc | 规范 | 大型复杂应用 | | GetX | 简洁 | 快速开发 |

Q24: Flutter如何实现与原生通信?

答案:

Dart
// Flutter端
const platform = MethodChannel('com.example/channel');

Future<void> callNative() async {
  final result = await platform.invokeMethod('methodName', {'key': 'value'});
}

Kotlin
// Android端
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/channel")
    .setMethodCallHandler { call, result ->
        when (call.method) {
            "methodName" -> {
                val value = call.argument<String>("key")
                result.success("Response")
            }
        }
    }

8. 其他

Q25: Android中的ANR是什么?如何避免?

答案: ANR(Application Not Responding)是应用无响应错误。

避免方法: - 主线程不执行耗时操作(>5秒) - 使用协程/线程处理后台任务 - BroadcastReceiver中不执行耗时操作(>10秒) - 使用WorkManager处理后台任务

Q26: 如何保证Android应用的安全性?

答案: 1. 使用HTTPS通信 2. 证书固定(SSL Pinning) 3. 敏感数据加密存储(EncryptedSharedPreferences/Keystore) 4. 代码混淆(ProGuard/R8) 5. 签名校验 6. 防Root/防调试