机器翻译正文由机器翻译自项目原始文档(英文),排版经程序统一处理,可能存在偏差,请以原项目仓库为准。
安卓面试问题及答案
安卓面试问题及答案 - 你的安卓面试速查表
由 Outcome School 的创始人Amit Shekhar 编写和维护
关于我
你好,我是 Amit Shekhar, Outcome School 创始人 • IIT 2010-14 • 我教授和指导过许多开发者,他们的努力使他们获得了高薪技术职位,帮助许多科技公司解决其独特问题,并创建了许多被顶级公司使用的开源库。我热衷于通过开源、博客和视频分享知识。
你可以通过以下方式联系我:
关于“面向产品型公司的安卓开发者面试准备”的直播课程
我主持过“面向产品型公司的安卓开发者面试准备”的直播课程
与超过500名安卓开发者互动
引导、激励并启发他们设定更高目标并取得更多成就
录制链接: https://www.youtube.com/watch?v=Yby0AA7ZSUE
文档链接: https://docs.google.com/document/d/14UdD7Gd1j3no583ALx2t2Ggt3G_CECYhenLE-m-bkzA/edit?usp=sharing
目录 - 安卓面试问题
- Android 面试问题与答案播放列表
- Kotlin 协程
- Kotlin Flow API
- Kotlin
- Android
- Android 库
- 安卓架构
- 设计模式
- Android 系统设计 并查看 Android 系统设计面试
- Android 单元测试
- 安卓工具与技术
- Jetpack Compose
- Java
- 其他主题
- 数据结构与算法
-
关于安卓机器编码轮面试,请查看: Android机器编码轮面试
我在Outcome School教书
加入Outcome School并获得高薪技术工作:Outcome School
快速通道Android面试准备:加入Outcome School Android项目
Android面试问题和答案播放列表
观看此视频,了解“面向产品公司的Android开发者面试准备”:面向产品公司的Android开发者面试准备
- 问题:使用FCM的Android推送通知流程
- 问题:Kotlin中的内联函数是什么?
- 问题:在Kotlin中使用const有什么优势?
- 问题:Kotlin中的reified关键字是什么?
- 问题:Kotlin协程中的挂起(suspending)与阻塞(blocking)
- 回答: Kotlin 协程中的挂起与阻塞
- 问题:Retrofit和OkHttp的区别
- 问题:Kotlin协程中的launch与async
- 问题:Kotlin中的internal可见性修饰符
- 问题:Kotlin中的open关键字
- 问题:Kotlin中的lateinit与lazy
- 问题:Android中的Multidex是什么?
- 问题:Android推送通知系统是如何工作的?
- 问题:Kotlin多平台是如何工作的?
- 问题:什么是ViewModel,它有什么用途?
- 问题:在Android中是否可以强制进行垃圾回收?
- 问题: Kotlin 中的 JvmStatic 注解是什么?
- 问题: Kotlin 中的 init 块
- 答案: Kotlin 中的 init 块
- 问题: Kotlin 中的 JvmField 注解
- 问题: Android 中的 singleTask 启动模式
- 问题: Kotlin 中 == 和 === 的区别
- 问题: Kotlin 中的 JvmOverloads 注解
- 问题: 为什么建议只使用默认构造函数来创建 Fragment?
- 问题: 为什么我们需要在 Activity 类的 onCreate() 中调用 setContentView()?
- 问题: 在什么情况下一个 Activity 只调用 onDestroy 而不调用 onPause() 和 onStop()?
安卓快速面试准备:加入 Outcome School Android 项目
Kotlin 协程
在 Android 面试中,你应该了解的 Kotlin 协程 相关主题:
- 协程
- 挂起函数 (suspend)
- 启动, async-await, withContext
- 调度器 (dispatchers)
- 作用域、上下文、任务 (job)
- lifecycleScope、viewModelScope、GlobalScope
- suspendCoroutine、suspendCancellableCoroutine
- 协程作用域、监督者作用域
- 阻塞运行
- 异常处理
从以下链接学习上述内容:
- 掌握 Kotlin 协程
- Kotlin协程中的挂起与阻塞
- Kotlin 协程中的 Launch 与 Async
- Kotlin 协程中的调度器
- coroutineScope 与 supervisorScope
- Kotlin 协程中的挂起函数
- Kotlin withContext 与 Async-await
- Kotlin 中的 CoroutineContext
- Kotlin 中的回调到协程
- 使用 Kotlin 协程的 Retrofit
- 使用 Kotlin 协程并行进行多个网络调用
- 使用 Kotlin 协程的 Room 数据库
- 使用 Kotlin 协程和 LiveData 对 ViewModel 进行单元测试
Kotlin 流 API
您应该了解的 Kotlin Flow API 主题,用于 Android 面试:
- Flow 构建器、操作符、收集器
- flowOn、调度器
- 操作符,例如 filter、map、zip、flatMapConcat、retry、debounce、distinctUntilChanged、flatMapLatest
- 终端操作符
- 冷流 vs 热流
- StateFlow, SharedFlow, callbackFlow, channelFlow
从以下链接学习上述内容:
- 在 Kotlin 中掌握 Flow API
- 在 Kotlin 中使用 Flow Builder 创建 Flow
- Kotlin Flow 中的终端操作符
- 冷流与热流
- StateFlow 和 SharedFlow
- 使用 Kotlin Flow 并行处理长时间运行的任务
- Kotlin Flow 中的重试操作符
- 使用 Kotlin Flow 的 Retrofit
- 使用 Kotlin Flow 的 Room 数据库
- Kotlin Flow Zip 操作符用于并行多个网络调用
- 使用 Kotlin Flow 操作符的即时搜索
- callbackFlow - Kotlin 中的回调到 Flow API
- Kotlin Flow 中的异常处理
- 使用 Kotlin Flow 和 StateFlow 对 ViewModel 进行单元测试
Kotlin
Android 面试问题及答案:
-
15 个 Kotlin 面试问题及答案:查看 PDF
-
Kotlin 中什么时候使用 lateinit 关键字? - 在此学习
-
Kotlin 中的
companion objects是什么? - 在此学习 -
扩展函数 - 在这里学习
-
Kotlin 中的数据类是什么? - 在此学习
-
在 Kotlin 中从数组中删除重复项 - 从这里学习
-
Kotlin 中的 noinline - 从这里学习
-
Kotlin 中的 crossinline - 在这里学习
-
Kotlin 中的范围函数 - 在这里学习
-
Kotlin 中的 reified 关键字是什么? - 在这里学习
-
Kotlin 中的 lateinit 与 lazy - 在这里学习
-
在 Kotlin 中使用 const 的优势 - 在这里学习
-
Kotlin 中的高阶函数是什么? - 在这里学习: Kotlin 中的高阶函数和 Lambda
-
编写一个函数(高阶函数),返回一个函数。 - 在这里查看解决方案
-
Kotlin中的Lambda是什么 - 在这里学习:Kotlin中的高阶函数和Lambda
-
AssociateBy - Kotlin 中的列表到映射 - 从这里学习
-
Kotlin 中的 open 关键字 - 从这里学习
-
Kotlin 中的伴生对象 - 从这里学习
-
Kotlin中的internal可见性修饰符 - 从这里学习
-
partition - Kotlin 中的过滤函数 - 从这里学习
-
Kotlin 中的中缀表示法 - 从这里学习
-
Kotlin 多平台是如何工作的? - 从这里学习
-
Kotlin 协程中的挂起与阻塞 - 在这里学习
-
协程中的 runBlocking 是什么? - 从这里学习
-
在 Kotlin 协程中,结构化并发的意义是什么? - 在这里学习
-
String vs StringBuffer vs StringBuilder - 在这里学习
-
val和var有什么区别? - 在这里学习 -
如何检查
lateinit变量是否已初始化? - 在这里学习 -
如何在 Kotlin 中对变量进行惰性初始化? - 在这里学习
-
Kotlin 中的可见性修饰符有哪些? - 从这里学习
-
在 Kotlin 中,Java 静态方法的等价物是什么? - 在这里学习
-
如何在 Kotlin 中创建单例类? - 在这里学习
-
Kotlin 中
open和public的区别是什么? - 在这里学习 -
apply范围函数及其使用场景 - 在这里学习 -
let作用域函数及其使用场景 - 在这里学习 -
Kotlin 中 List 和 Array 类型的区别 - 在这里学习
-
Kotlin 中的
Labels是什么? - 在这里学习 -
Kotlin中的协程是什么? - 从这里学习
-
什么是协程作用域? - 在这里学习
-
在 Android 中使用的 Kotlin 协程作用域 - 在这里学习
-
什么是协程上下文? - 在这里学习
-
Kotlin 协程中的 Launch 与 Async - 从这里学习
-
Kotlin 中的 Thread.sleep() 与 delay() - 在这里学习
-
解释 Kotlin 中的内联类 - 在这里学习
-
Kotlin中的密封类 - 从这里学习
-
在 Android 中封闭类的常见用例 - 在这里学习
-
讲述 Kotlin 中的集合 - 从这里学习
-
在 Kotlin 中 ?: 做什么?(埃尔维斯操作符) - 从这里学习
-
Kotlin 协程中的超时 - 在这里学习
-
如何合并多个协程结果? - 在这里学习
-
协程中的 Job 是什么? - 在这里学习
-
协程 job.cancel() 与 scope.cancel() - 在这里学习
-
如果在异步协程内部抛出异常,但从未调用 await() 会发生什么? - 在这里学习
-
如何使用协程实现防抖? - 点击这里学习
-
Kotlin 代码片段演示如何顺序和并行运行两个协程 - 从这里学习
-
Kotlin 协程中的 yield - 在这里学习
-
Kotlin中的委托 - 从这里学习
-
Kotlin Flow 中的 stateIn 与 shareIn - 在这里学习
-
Kotlin Flow中的flatMapConcat、flatMapMerge和flatMapLatest - 在这里学习
-
Kotlin Flow 中的 collect 与 collectLatest - 在这里学习
快速通道安卓面试准备:加入 Outcome School 安卓课程
安卓
安卓面试问题及答案:
基础
-
为什么安卓应用会卡顿? - 在这里学习
-
什么是
Context?它是如何使用的? - Android 应用中的 Context -
Zygote 如何让 Android 应用启动更快? - Zygote 如何让 Android 应用启动更快?
-
列出所有的安卓应用组件。 - 在这里学习
-
Android 应用程序的项目结构是什么? - 在这里学习
-
什么是
AndroidManifest.xml? - 在这里学习 -
Application类是什么? -在这里学习
活动与碎片
-
什么是
Activity及其生命周期? - 从这里学习 -
onCreate() 和 onStart() 有什么区别 - 在这里学习
-
什么时候一个活动只调用 onDestroy 而不调用 onPause() 和 onStop()? - 在这里学习
-
为什么我们需要在 Activity 类的 onCreate() 中调用 setContentView()? - 在这里学习
-
在活动中,onSaveInstanceState() 和 onRestoreInstanceState() 是什么? - 在这里学习
-
什么是
Fragment及其生命周期? - 在这里学习 -
Android 中的 Bundle 是什么? - 在这里学习
-
什么是 "launchMode"? - 在这里学习 和 Android 中的 singleTask launchMode
-
Fragment和Activity有什么区别?解释两者之间的关系。 - 在这里学习 -
什么时候你应该使用Fragment而不是Activity?
- 当你有一些需要在各种活动中使用的 UI 组件时
- 当多个视图可以像 ViewPager 一样并排显示时
-
FragmentPagerAdapter 与 FragmentStatePagerAdapter 有什么区别?
- FragmentPagerAdapter:用户访问的每个 fragment 都会存储在内存中,但视图会被销毁。当页面被重新访问时,将创建视图,而不是 fragment 的实例。
- FragmentStatePagerAdapter:在这里,当片段对用户不可见时,片段实例将被销毁,但片段的已保存状态除外。
-
在回退栈中添加/替换碎片有什么区别? - 从这里学习
-
你会如何在两个 Fragment 之间进行通信?
-
保留的
Fragment是什么? - 在这里学习 -
addToBackStack()在提交 fragment 事务时的目的是什么?- 通过调用 addToBackStack(),replace 事务会被保存到返回栈中,这样用户可以通过按返回按钮撤销事务并恢复之前的 fragment。更多内容 从这里学习
视图和视图组
-
在 Android 中优化布局 - 从这里学习
-
在 Android 中,
View是什么? -
View.GONE和View.INVISIBLE的区别? - 在这里学习 -
你能创建自定义视图吗?如何创建?
-
什么是 ViewGroup,它们与 View 有什么不同?
- 视图:视图对象是 Android 用户界面(UI)元素的基本构建块。视图是一个简单的矩形框,可以响应用户的操作。示例有 EditText、Button、CheckBox 等。视图指的是 android.view.View 类,它是所有 UI 类的基类。
- ViewGroup:ViewGroup 是不可见的容器。它可以包含 View 和 ViewGroup。例如,LinearLayout 是包含 Button(View)和其他布局的 ViewGroup。ViewGroup 是布局的基类。
-
什么是画布? - 在这里学习
-
什么是
SurfaceView? - 从这里学习 -
相对布局 vs 线性布局。
-
谈谈约束布局优化 - 在这里学习
-
你知道视图树是什么吗?如何优化它的深度? - 在这里学习
显示内容列表
-
ListView和RecyclerView有什么区别? - 在这里学习 -
RecyclerView 是如何工作的? - 在这里学习
-
RecyclerView 优化 - 滚动性能提升 - 从这里学习
-
优化嵌套 RecyclerView - 从这里学习
-
RecyclerView 如何提升比 ListView 的性能?
-
RecyclerView 的组成部分有哪些?
-
解释 RecyclerView.Adapter 和 RecyclerView.ViewHolder 的作用 - 在这里学习
-
RecyclerView中的LayoutManager是什么?
-
你如何在单个 RecyclerView 中处理多种视图类型?
-
DiffUtil 是什么,它如何提升 RecyclerView 的性能? - 从这里学习
-
RecyclerView.setHasFixedSize(true) 的目的是什么? - 从这里学习
-
如何更新 RecyclerView 中的特定项?
-
什么是
SnapHelper? - 在这里学习: SnapHelper
对话框和提示
-
在 Android 中
Dialog是什么? - 从这里学习 -
在 Android 中什么是
Toast? - 在这里学习 -
Dialog和Dialog Fragment有什么区别? - 在这里学习
意图与广播
-
什么是
Intent? - 在这里学习 -
什么是隐式
Intent? - 从这里学习 -
什么是显式
Intent? - 从这里学习 -
什么是
BroadcastReceiver? - 在这里学习 -
描述广播和意图是如何工作的,以便在应用程序中传递消息? - 在这里学习
-
什么是
PendingIntent?- 如果你希望某人在未来某个时间点代表你执行任何意图操作,那么我们将使用待处理意图。
-
广播的不同类型有哪些? - 在这里学习
服务
-
解释 Android 服务生命周期 - 在这里学习
-
什么是服务? - 从这里学习
-
在 Android 中,Service 运行在哪个线程上? - 从这里学习
-
Service 与 IntentService - 从这里学习
-
什么是前台服务? - 在这里学习
-
什么是
JobScheduler? - 在这里学习 -
WorkManager 如何保证任务执行? - 在这里学习
进程间通信
-
两个不同的 Android 应用如何互动? - 从这里学习
-
在多个进程中运行 Android 应用程序可能吗?如何实现? - 从这里学习
-
什么是AIDL?列出通过AIDL创建绑定服务的步骤。 - 在这里学习
-
在 Android 中可以使用什么进行后台处理? - 从这里学习
-
什么是
ContentProvider,它通常用于什么? - 从这里学习
长时间运行的操作
-
如何运行并行任务并在所有任务完成时获取回调? - 使用 Kotlin Flow 并行运行长期任务
-
什么是 ANR?如何防止 ANR? - 点击这里学习
-
线程池的优势 - 在这里学习
-
守护线程与用户线程 - 在这里学习
-
解释
Looper、Handler和HandlerThread。 -
垃圾回收 - 从这里学习
-
内存泄漏与内存不足(OOM)错误 - 在这里学习
-
你能解释一下在 Android 中 Runnable 和 Thread 的区别吗? - 在这里学习
处理多媒体内容
数据保存
-
Jetpack 数据存储首选项 - 从这里学习
-
在安卓应用中持久化数据 - 从这里学习
-
什么是 ORM?它是如何工作的?
-
在屏幕旋转时,你会如何保持
Activity状态? - 在这里学习 -
在你的 Android 应用中存储数据的不同方式有哪些? - 从这里学习
-
解释 Android 中的 Scoped Storage。
-
如何在安卓中加密数据?
-
SharedPreferences 中的 commit() 和 apply() 是什么?
- commit() 通过同步写入数据立即返回成功或失败的布尔值。
- apply() 是异步的,它不会返回任何布尔响应。如果你有一个未完成的 apply() 并且你正在执行 commit(),那么 commit() 将被阻塞,直到 apply() 完成。
外观与感觉
-
What is
Spannable? -
什么是
SpannableString?- SpannableString 的文本是不可变的,但其跨度信息是可变的。当你的文本不需要更改但样式需要更改时,使用 SpannableString。跨度是文本的范围,包括颜色、高亮、斜体、链接等样式信息。
-
在 Android 中使用文本的最佳实践是什么?
-
如何在任何应用程序中实现暗黑模式?
快速通道安卓面试准备:加入 Outcome School 安卓课程
内存优化
电池寿命优化
-
安卓如何使用机器学习实现自适应电池? - 安卓如何使用机器学习实现自适应电池?
-
如何减少 Android 应用程序的电池使用?
-
什么是 Doze?那么 App Standby 呢? - 在这里学习
-
什么是
overdraw? - 从这里学习
支持不同屏幕尺寸
- 您如何支持不同类型的分辨率? - 从这里学习
权限
- 权限中不同的保护级别有哪些?
原生编程
-
什么是 NDK,它为什么有用? - 在这里学习:Android NDK 和 RenderScript
-
什么是renderscript? - 在这里学习: Android NDK和RenderScript
安卓系统内部
-
什么是 Android 运行时? - Android 运行时
-
Android中的Dalvik、ART、JIT和AOT - Dalvik、ART、JIT和AOT
-
Dalvik和ART有什么区别? - Dalvik和ART的区别
-
基线配置文件 - 在这里学习
-
什么是 DEX? - 在这里学习
-
什么是 Android 中的 Multidex? - 从这里学习
-
你可以手动调用垃圾回收器吗? - 在 Android 中强制垃圾回收可能吗?
-
Android 应用启动:热启动、温启动与冷启动 - Android 应用启动:热启动、温启动与冷启动
安卓 Jetpack
-
什么是 Android Jetpack,为什么要使用它?
-
什么是ViewModel,它有什么用? 学习:什么是ViewModel,它有什么用?
-
Android 中的 SharedViewModel 学习: Android 中的 SharedViewModel
-
什么是安卓架构组件?
-
Android 开发中的 StateFlow 与 LiveData 学习: StateFlow vs LiveData
-
Android 中的 LiveData 是什么? Android 中的 LiveData 是什么?
-
LiveData 和 ObservableField 有什么不同?
-
LiveData 中 setValue 和 postValue 有什么区别? 学习:LiveData 中的 setValue() 与 postValue()
-
如何在 Android 中在 Fragment 之间共享 ViewModel? 学习:Android 中的 SharedViewModel
-
解释 WorkManager 及其使用场景。
-
使用 WorkManager 调度 PeriodicWorkRequest 时允许的最小重复间隔 - 在这里学习
-
WorkManager 如何保证任务执行? - 在这里学习
-
ViewModel 在内部是如何工作的?
其他
-
Serializable 和 Parcelable 有什么区别?在 Android 中哪种方法最好? - 在这里学习
-
为什么 Bundle 类用于数据传递,而不能使用简单的 Map 数据结构? - 在这里学习
-
如何排除应用程序崩溃的问题? - 在此学习
-
解释 Android 推送通知系统? 从这里学习: Android 推送通知系统是如何工作的?
-
什么是 AAPT? - 在这里学习
-
FlatBuffers 与 JSON。
-
HashMap、ArrayMap和SparseArray- 在这里学习 -
Android 中 SparseArray 的优势 - 在这里学习
-
什么是注解? - 从这里学习
-
如何创建自定义注解? - 从这里学习
-
什么是 Android 支持库?为什么要引入它? - 在这里学习
-
什么是 Android 数据绑定?
安卓库
安卓面试问题及答案:
-
解释 OkHttp 拦截器 - 从这里学习
-
OkHttp - HTTP 缓存 - 从这里学习
-
如何在 OkHttp 中启用日志记录? - 从这里学习
-
为什么我们在 Android 中使用像 Dagger 这样的依赖注入框架? - 在这里学习
-
解释 Dagger 2 中的 @Inject、@Module、@Provides、@Component 注解 - 从这里学习
-
匕首是如何运作的?
-
你将如何在 Dagger 2 和 Dagger-Hilt 之间做出选择?
-
Dagger 中的组件是什么?
-
Dagger中的模块是什么?
-
在 Dagger 中,自定义作用域如何工作?
-
在 RxJava 中什么时候调用 CompositeDisposable 的 dispose 和 clear? - 在这里学习
-
什么是网络中的多部分请求?
-
Kotlin 中的 Flow 是什么? - 在这里学习
-
应用启动库 - 从这里学习
-
告诉我一些关于RxJava的事情。
-
你将如何处理RxJava中的错误?
-
FlatMap 与 Map 操作符 - 在这里学习
-
什么时候使用 RxJava 的
Create操作符,什么时候使用fromCallable操作符? - 在这里学习:RxJava Create 和 fromCallable 操作符 -
何时使用 RxJava 的
defer操作符? - 在这里学习: RxJava Defer 操作符 -
在 RxJava 中,Timer、Delay 和 Interval 操作符如何使用? - 在这里学习
-
如何使用 RxJava 并行进行两个网络调用? - RxJava Zip 操作符
-
在 RxJava 中解释 Subject? - 从这里学习
-
RxJava 中有哪些类型的 Observable? - 在这里学习:RxJava 中的 Observable 类型
-
如何在您的应用程序中使用 RxJava 实现搜索功能? - 在这里学习: 使用 RxJava 操作符实现即时搜索
-
在 RecyclerView 中使用 RxJava 操作符进行分页 - 在这里学习
-
RxJava 中 Schedulers.io() 和 Schedulers.computation() 的区别。
快速通道安卓面试准备:加入 Outcome School 安卓课程
安卓架构
安卓面试问题及答案:
-
描述你上一个应用的架构。
-
描述 MVVM。 - MVVM 架构
-
MVC vs MVP vs MVVM 架构。
-
清洁架构 - 在这里学习
-
软件架构与软件设计 - 在这里学习
-
多模块架构的好处 - 点击这里了解
-
多模块项目:为什么以及何时? - 在这里学习
设计模式
Android 面试问题与答案
- 建造者 - 从这里学习
- 单例
- 工厂 - 从这里学习
- 观察者 - 从这里学习
- 仓库
- 适配器
- 外观
- 依赖注入
- 策略模式 - 点击这里学习
- Android中使用的设计模式 - 从这里学习
- Kotlin 可选参数与建造者模式 - 在这里学习
- 在 Android 中使用观察者模式的示例 - 在这里学习
- Retrofit 库源代码中使用的设计模式 - 在这里学习
- Glide(图像加载库)中使用的设计模式 - 在这里学习
- AOSP(Android开源项目)中使用的设计模式 - 从这里学习
安卓系统设计
安卓面试问题及答案:
请参阅此博客:Android 系统设计面试
-
设计文件下载库 - 在这里学习
-
设计 WhatsApp
-
设计 Instagram 故事
-
设计网络库
-
设计 Facebook 附近的朋友应用
-
设计缓存库。
-
基于位置的应用设计问题
-
如何构建一个离线优先的应用?解释其架构
-
设计 LRU 缓存
-
设计分析库
-
设计日志库 - 在这里学习
-
HTTP请求 vs HTTP长轮询 vs WebSocket vs 服务器发送事件 - 从博客学习 和 视频 - HTTP请求 vs HTTP长轮询 vs WebSocket vs 服务器发送事件
-
语音和视频通话是如何工作的? - 在这里了解
-
在 Android 应用中,当网络不稳定时,你如何处理数据同步? - 在不稳定网络下处理 Android 数据同步
-
设计优步应用 - 从这里学习
-
“我的火车在哪里”如何在没有网络的情况下工作? - “我的火车在哪里”如何在没有网络的情况下工作?
-
数据库规范化与反规范化 - 数据库规范化与反规范化
-
哈希 vs 加密 vs 编码 - 在这里学习
-
Webhook 与轮询 - 从这里学习
-
在安卓应用中实现实时更新的选项 - 在这里学习
-
移动应用中的网络优化选项 - 移动应用中的网络优化选项
-
Android 中的 Firebase 远程配置 - Android 中的 Firebase 远程配置
-
Android中的准确时间 - 从这里学习
-
SQLite 中的查询优化以提高性能 - 在这里学习
-
WebSocket 与 Socket.IO - 在这里学习
-
对称加密 vs 非对称加密 - 在这里学习
-
Android 中的 SMS Retriever API - 在这里学习
快速通道安卓面试准备:加入 Outcome School 安卓课程
Android 单元测试
安卓面试问题及答案:
-
使用 Kotlin 协程和 LiveData 进行 ViewModel 单元测试 - 在这里学习
-
使用 Kotlin Flow 和 StateFlow 对 ViewModel 进行单元测试 - 在这里学习
-
什么是 Espresso? - 在这里学习
-
什么是 Robolectric? - 在这里了解
-
使用 Robolectric 的缺点是什么? - 在这里学习
-
什么是 UI-Automator? - 在这里学习
-
解释单元测试。 - 在这里学习
-
解释仪器化测试。 - 从这里学习
-
为什么使用 Mockito? - 在这里学习
-
描述代码覆盖率。 - 从这里学习
安卓工具与技术
安卓面试问题及答案:
-
Android 的 CI/CD 管道 - 在这里学习
-
什么是ADB? - 在这里学习
-
Android 应用的 16 KB 页大小 - 从这里学习
-
什么是 StrictMode? - 在这里学习: StrictMode
-
什么是Lint?它有什么用?
-
Android 应用发布生产版本清单 - 在这里学习: Android 应用发布生产版本清单
-
Git.
-
Firebase。 - 从这里学习
-
如何在 Android 中测量方法执行时间?
-
你能访问你的 SQLite 数据库进行调试吗? - 在这里学习
-
使用 Proguard 时我们需要注意哪些事项?
-
如何使用 Android Studio 内存分析器?
-
什么是用于 Gradle 的 Kotlin DSL? - 在这里学习
-
Gradle 中的 implementation 与 api - 在这里学习
-
什么是Gradle?
-
Android 项目中的 Gradle 相关文件 - 在这里学习
-
如何在 Gradle 中创建自定义任务? - 在这里学习
-
Gradle 中的 annotationProcessor、kapt、ksp - 从这里学习
-
Android中的构建变体 - 在这里学习
-
Android中的去糖化 - 在这里学习
-
APK 大小减小。
-
你如何加快Gradle构建速度?
-
关于Gradle构建系统。
-
关于 Android 应用的多个 APK。
-
ProGuard 用于什么? - 在这里了解
-
proguard-rules.pro 文件的用途是什么? - 在这里学习
-
Android 中的 ProGuard 与 R8 - 在这里学习
-
什么是混淆?它有什么用途?那压缩呢?
-
如何在不更新应用的情况下更改应用中的某些参数? - Android 中的 Firebase 远程配置
-
什么是写前日志(WAL)以及它为何在数据库内部使用? - 在这里学习
Jetpack 组合
在 Android 面试中你应该了解的 Jetpack Compose 相关主题:
- 撰写
- 状态:记住,记住可保存,可变状态
- 重组
- 升旗
- 副作用
- 修改器
- 主题
- 布局, 列表
- 手势,动画
- 组合本地
- 阶段
请从以下链接学习上述内容:
- 开始使用 Compose
- 在 Compose 中思考
- 状态
- remember 与 rememberSaveable
- 生命周期
- 修饰符
- 副作用
- 阶段
- 语义
- CompositionLocal
- 我们可以将传统的 Android 视图和 Compose 一起使用吗?
问题
-
Jetpack Compose 与 Android 视图系统
-
解释 Jetpack Compose 中的声明式 UI 概念。
-
声明式 UI 与命令式 UI
-
什么是可组合函数?
-
什么是重组?
-
在 Compose 中,State 是什么?
-
在 Jetpack Compose 中,状态管理是如何运作的?
-
有状态可组合 vs 无状态可组合
-
副作用有哪些?
-
LaunchedEffect 和 DisposableEffect 之间的区别.
-
什么是 rememberCoroutineScope 及其使用场景?
-
如何在 Compose UI 中观察 Flows 和 LiveData 状态?
-
我们如何在 Jetpack Compose 中处理异步操作?
-
我们如何将非Compose状态转换为Compose状态?
-
解释 derivedStateOf。
-
解释 rememberUpdatedState。
-
remember 和 rememberSaveable 的区别。 - 在这里学习
-
解释 Jetpack Compose 中可组合项的生命周期。
-
你如何在 Compose 函数中处理生命周期事件?
-
在 Jetpack Compose 中进行性能优化的最佳实践是什么?
-
我们可以在一个应用中同时使用 Jetpack Compose 和 Android View 吗?
-
什么是状态提升?
-
解释 CompositionLocal
-
解释 Jetpack Compose 阶段。 - 在这里学习
-
在 Jetpack Compose 中,Modifier 的作用是什么?
-
语义学是什么?
-
在 Jetpack Compose 中如何处理用户输入和事件?
-
你如何在 Jetpack Compose 中处理导航?
-
你如何处理 Jetpack Compose 中的屏幕方向变化?
-
解释 Jetpack Compose 中单向数据流的概念。
-
如何在 Compose 中创建自定义布局?
快速通道安卓面试准备:加入 Outcome School 安卓课程
Java
安卓面试问题及答案:
稳固原则
- SOLID 原则中的“S”:单一职责原则 - 在这里学习
- SOLID 原则中的“O”:开放/封闭原则 - 从这里学习
- SOLID 原则中的“L”:里氏替换原则 (LSP) - 从这里学习
- SOLID 原则中的“I”:接口隔离原则(ISP) - 在这里学习
- SOLID 原则中的“D”:依赖倒置原则 (DIP) - 从这里学习
面向对象编程
-
解释面向对象编程(OOP)概念。
-
抽象类和接口的区别?
- 抽象类是包含具体方法和抽象方法的类
(methods without implementations). An abstract method must be implemented by the abstract class
sub-classes. Abstract classes cannot be instantiated and need to be extended to be used. - 接口就像一个类的蓝图/契约(或者可以被认为是一个有方法但没有实现的类)。它包含空的方法,这些方法
represent, what all of its subclasses should have in common. The subclasses provide the
implementation for each of these methods. Interfaces are implemented.
- 抽象类是包含具体方法和抽象方法的类
-
方法重载和重写的区别。
-
解释 Java 中的“字符串池” - 在这里学习
-
你知道哪些访问修饰符?每个修饰符有什么作用?
- 在 Java 语言中有四种访问修饰符(从最严格到最宽松):
private变量、方法、构造函数或内部类仅对其所在的类及其方法可见。这个修饰符最常见的用途是,例如,只允许通过 getter 和 setter 访问变量,或者隐藏不应被用户使用的类的底层实现,从而保持封装性。单例构造函数也被标记为private,以避免外部的不期望实例化。Default(未使用关键字)此修饰符可以应用于类、变量、构造函数和方法,并允许同一包内的类和方法访问。protected可以用于变量、方法和构造函数,因此只允许子类以及与受保护成员类在同一包中的类访问。public修饰符广泛用于类、变量、构造方法和方法,以允许从任何类和方法访问。它不应被随意使用,因为它意味着标记为public的数据不敏感,并且不会对程序造成伤害。
- 在 Java 语言中有四种访问修饰符(从最严格到最宽松):
-
接口可以实现另一个接口吗?
- 是的,一个接口可以实现另一个接口(甚至多个接口),但它需要使用
extends,而不是implements关键字。虽然你不能从父接口中移除方法,但你可以自由地向子接口添加新的方法。
- 是的,一个接口可以实现另一个接口(甚至多个接口),但它需要使用
-
什么是多态?继承又是什么?
集合与泛型
对象与原始类型
-
String类是如何实现的?为什么它被设计为不可变的?- 在 Java 语言中没有
String类的原始变体——所有字符串只是对底层字符数组的包装,而该数组被声明为final。这意味着,一旦String对象被实例化,就不能通过语言的正常工具来更改它(反射仍然可能极大地破坏它,因为在 Java 中没有对象是真正不可变的)。这就是为什么在类中,当你想重写类的hashCode()和equals()方法时,String变量是最先考虑的候选对象——你可以确信,它们的所有必要约定都将得到满足。注意:String 类是不可变的,因此一旦创建了 String 对象,该对象就不能被更改。String 类有许多方法,其中一些将在下面讨论,这些方法看起来像是在修改字符串。由于字符串是不可变的,这些方法实际上是创建并返回一个包含操作结果的新字符串。(官方 Java 文档)
这个类在某种意义上也是独特的,当你像这样创建一个实例时:
String helloWorld = "Hello, World!";"Hello, World!"被称为 字面量,编译器会用它的值创建一个String对象。所以String capital = "Hello, World!".toUpperCase();是一个有效的语句,首先,它将创建一个字面值为“Hello, World!”的对象,然后将创建并返回另一个值为“HELLO, WORLD!”的对象
String被设计为不可变的,以防止数据被恶意篡改,例如在向服务器发送用户登录信息或其他敏感数据时。
- 在 Java 语言中没有
-
说一个
String是不可变的是什么意思?- 这意味着一旦创建,
String对象的char[](其包含的值)被声明为final,因此在运行时无法更改。
- 这意味着一旦创建,
-
你能列出 Java 中的 8 种原始类型吗?
byteshortintlongfloatdoublecharboolean
-
整数(Integer)和int有什么区别?
int是一种原始数据类型(与boolean、byte、char、short、long、float和double一起),而Integer(与Boolean、Byte、Character、Short、Long、Float和Double一起)是一个封装类(wrapper),它封装了原始数据类型,同时提供有用的方法以使用它执行不同的任务。
-
在 Java 中,对象是按引用传递还是按值传递?对此详细说明。
Java 内存模型与垃圾回收器
- 什么是垃圾收集器?它是如何工作的? - 在这里学习
并发
-
关键字
synchronized是什么意思? -
什么是
ThreadPoolExecutor? - Android 中的 ThreadPoolExecutor -
什么是
volatile修饰符? -
Java中的对象级锁与类级锁 - 在这里学习
-
并发与并行 - 在这里学习
-
atomic 包中的类暴露了一组通用的方法:
get、set,、lazyset、compareAndSet和weakCompareAndSet。请描述它们。
例外
-
try{}、catch{}和finally是如何工作的? -
Checked Exception和Un-Checked Exception有什么区别?
其他
-
Java中的浅拷贝与深拷贝 - 在这里学习
-
解释序列化和反序列化 - 从这里学习
-
什么是序列化?你如何实现它?
-
什么是
transient修饰符? -
什么是匿名类?
-
在对象上使用
==和.equals有什么区别? -
hashCode()和equals()用来做什么? -
你什么时候会把一个对象的值设为
final? -
这些
final、finally和finalize关键字是什么? -
Java 中 "throw" 和 "throws" 关键字的区别是什么?
throws仅用于指示将要抛出的异常。而throw关键字用于从任何静态代码块或任何方法中抛出某个异常。
-
在 Java 中,
static这个词是什么意思?- 对于
static变量来说,这意味着该变量(其值或它引用的对象)跨越包含它的类的所有实例(在一个实例中修改它会影响所有其他实例),而对于static方法来说,这意味着这些方法可以在不实例化其包含类的情况下被调用。例如,这在创建不需要每次使用时都实例化的工具类时非常有用。
- 对于
-
在 Java 中,
static方法可以被重写吗?- 虽然子类可以用另一个具有相同签名的静态方法来覆盖静态方法(返回类型可以向下转型),但它并不是真正的覆盖——它变得“隐藏”,但在正确的情况下仍然可以访问这两个方法(参见上面关于重载/覆盖的问题)。
-
static块什么时候运行?- 静态块中的代码只执行一次:第一次创建该类的对象时,或者第一次访问该类的静态成员时(即使你从未创建该类的对象)。
-
解释 Java 中的反射 - 从这里学习
-
什么是依赖注入?
-
StringBuffer和StringBuilder的区别? - 在这里学习 -
在 Java 中,fail-fast 迭代器和 fail-safe 迭代器有什么区别?
-
监视器与同步
其他主题
安卓面试问题及答案:
-
描述 SQLite。
-
你用过 Room 吗?
-
我们能否识别出卸载了我们应用的用户?
-
安卓开发最佳实践。 - 在这里学习: 安卓开发最佳实践
-
React Native vs Flutter - 在这里学习: React Native vs Flutter
-
在安卓应用开发过程中,你应持续测量的指标有哪些? - 在这里了解:Android 应用性能指标
-
如何避免将 API 密钥提交到版本控制系统?
-
Kotlin 多平台是如何工作的? - 博客
-
如何使用内存堆转储数据?
-
如何在你的应用中实现暗黑主题?
-
如何保护在安卓应用中使用的API密钥?
-
明文流量是什么? 从这里了解:明文流量是什么?
-
谈谈 Android 中的内存使用情况。
-
解释注解处理。
-
Android 推送通知系统是如何工作的? 在这里学习:Android 推送通知系统是如何工作的?
-
使用 FCM 的 Android 推送通知流程。 在这里学习:使用 FCM 的 Android 推送通知流程
-
如何在准确的时间显示本地通知?
数据结构与算法
- Android 开发者应了解这些数据结构以准备下次面试 - 点击这里
高质量视频,帮助准备Android面试 - Amit Shekhar YouTube频道
高质量博客,准备 Android 面试 - 点击这里 - Outcome School 博客
准备机器学习面试:机器学习面试问题
为人工智能工程面试做准备:人工智能工程面试问题
快速通道安卓面试准备:加入 Outcome School 安卓课程
觉得这个项目很有用 :heart:
- 通过点击本页右上角的 :star: 按钮来支持。:v:
你可以通过以下方式与我联系:
许可证
Copyright (C) 2025 Amit Shekhar
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.- 本文标题:android-interview-questions - 你的安卓面试备忘单 - 安卓面试问题及答案
- 本文链接:https://www.cn121.com/mobile/amitshekhariitbhu-android-interview-questions.html
- 原项目:amitshekhariitbhu/android-interview-questions 版权归原作者 amitshekhariitbhu 及贡献者所有
- 收录信息:本站于 2026-10-21 收录本项目,本页所列协议与仓库指标均为收录当时的状态;该日期之后原项目的版本更新与协议变更,本页不作同步。
- 开源协议:收录时本项目采用 Apache-2.0(查看 LICENSE 原文),本站译文为其衍生内容;使用、修改、分发请以该仓库 LICENSE 原文为准。本站对原文仅作排版与图片地址适配, 并保留原项目的 NOTICE 与署名要求。
- 站点出处:本文首发于 OneTwoOne,收录自 GitHub 开源项目 amitshekhariitbhu/android-interview-questions。
- 翻译说明:本页正文为人工智能生成内容——由机器翻译对原项目 README 初译、经程序校验排版,可能存在错漏,请以原项目文档为准。
- 引用声明:商业转载、第三方聚合或 AI 检索训练引用时,请务必保留以上来源出处、本文永久链接,以及原项目的版权声明与许可信息。
- 下架通道:若原项目此后变更或收紧了许可协议、或作者/权利人认为本站的收录方式(译文、排版适配、简介翻译等)超出其授权范围,请通过 xyd3302001@163.com 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。