Android 面试核心知识点与真题解析指南
Android 面试涉及 Java 基础、集合、多线程、JVM、四大组件、Binder、AMS、数据结构算法及跨平台技术等内容。本文汇总了常见面试题并附带解析,帮助求职者系统复习,提升技术深度与面试表现。

Android 面试涉及 Java 基础、集合、多线程、JVM、四大组件、Binder、AMS、数据结构算法及跨平台技术等内容。本文汇总了常见面试题并附带解析,帮助求职者系统复习,提升技术深度与面试表现。

随着技术更新迭代,Android 开发面试对基础知识和框架原理的要求日益提高。本文整理了一系列高频面试题,涵盖 Java、Android 系统、Framework、算法等多个维度,旨在帮助开发者查漏补缺,系统掌握核心技术点。
抽象类与接口的区别? 抽象类可以有成员变量、构造器、具体方法;接口只能有常量(public static final)和抽象方法(Java 8 后可有 default/static 方法)。一个类可以实现多个接口,但只能继承一个抽象类。接口侧重于行为规范,抽象类侧重于代码复用和模板设计。
分别讲讲 final,static,synchronized
final 修饰类表示不可继承,修饰方法表示不可重写,修饰变量表示常量。static 表示静态成员,属于类而非实例,内存中只有一份。synchronized 用于线程同步,保证多线程环境下的数据一致性,可修饰方法或代码块。
请简述一下 String、StringBuffer 和 StringBuilder 的区别
String 是不可变字符序列,每次修改都会生成新对象。StringBuffer 是可变且线程安全的(方法加锁),性能较低。StringBuilder 是可变且非线程安全的,性能最高。单线程下推荐用 StringBuilder。
'equals'与'=='、'hashCode'的区别和使用场景?
== 比较基本类型值或引用地址。equals 默认比较地址,Object 子类通常重写比较内容(如 String)。hashCode 用于哈希表定位,若 equals 相等则 hashCode 必须相等。重写 equals 时必须同时重写 hashCode。
Java 中深拷贝与浅拷贝的区别? 浅拷贝复制对象本身及基本类型字段,引用类型字段仍指向原对象内存地址。深拷贝完全复制对象及其引用的所有对象,新对象与原对象互不影响。
谈谈 Error 和 Exception 的区别?
Error 是 JVM 严重错误(如 OOM),程序无法处理,通常不捕获。Exception 是程序运行异常,可分为受检异常(Checked)和非受检异常(Unchecked),建议根据业务逻辑捕获处理。
什么是反射机制?反射机制的应用场景有哪些? 反射允许在运行时动态获取类的信息并操作对象。应用场景包括:框架开发(如 Spring IOC)、动态代理、序列化/反序列化、插件化系统等。
谈谈如何重写 equals() 方法?为什么还要重写 hashCode? 重写 equals 需遵循自反性、对称性、传递性等原则,通常使用 Objects.equals 比较字段。重写 hashCode 是为了配合 HashMap/HashSet,确保相同对象哈希值一致,避免哈希冲突导致查找失败。
谈谈你对 Java 泛型中类型擦除的理解,并说说其局限性? 编译后泛型类型会被擦除为原始类型(如 List 变为 List)。局限性在于无法在运行时获取泛型具体类型,不能直接 new T(),也无法判断 instanceof 泛型参数。
说说你对 Java 注解的理解? 注解提供元数据,编译器或运行时可读取。分为编译期检查(@Override)、运行时处理(@Autowired)。可通过反射 API 获取注解信息。
谈谈 List, Set, Map 的区别?
List 有序可重复;Set 无序不可重复;Map 键值对存储,Key 唯一。List 实现有 ArrayList/LinkedList,Set 有 HashSet/TreeSet,Map 有 HashMap/TreeMap。
谈谈 ArrayList 和 LinkedList 的区别?
ArrayList 基于数组,随机访问快 O(1),增删慢(需移动元素)。LinkedList 基于双向链表,随机访问慢 O(n),增删快(只需修改指针)。
请说一下 HashMap 与 HashTable 的区别
HashMap 非线程安全,允许 null 键值,速度快。HashTable 线程安全(全方法加锁),不允许 null,速度慢。现代开发多用 ConcurrentHashMap 替代 HashTable。
谈一谈 ArrayList 的扩容机制? 初始容量 10,当元素超过当前容量时,扩容为新容量的 1.5 倍(old + old/2),并将旧数组内容复制到新数组。
HashMap 的实现原理? JDK 1.8 前为数组 + 链表,JDK 1.8 后为数组 + 链表 + 红黑树。当链表长度超过 8 且数组长度超过 64 时转为红黑树,查询效率从 O(n) 提升至 O(log n)。
请简述 LinkedHashMap 的工作原理和使用方式? 继承自 HashMap,维护了一个双向链表记录插入顺序或访问顺序。适用于 LRU 缓存等需要排序的场景。
谈谈对于 ConcurrentHashMap 的理解? JDK 1.7 分段锁(Segment),JDK 1.8 CAS + synchronized 锁住链表头节点。保证线程安全的同时提高了并发性能。
Java 中使用多线程的方式有哪些? 继承 Thread 类、实现 Runnable 接口、实现 Callable 接口配合 FutureTask、使用线程池(ExecutorService)。
说一下线程的几种状态? NEW(新建)、RUNNABLE(运行/就绪)、BLOCKED(阻塞等待锁)、WAITING(无限等待)、TIMED_WAITING(限时等待)、TERMINATED(终止)。
如何实现多线程中的同步? 使用 synchronized 关键字、Lock 接口(ReentrantLock)、volatile 关键字、原子类(AtomicInteger)、并发工具类(CountDownLatch/CyclicBarrier)。
谈谈线程死锁,如何有效的避免线程死锁? 死锁指多个线程互相持有对方需要的资源。避免策略:固定资源获取顺序、超时机制、使用 Lock.tryLock()、减少锁粒度。
谈谈线程阻塞的原因? 等待 I/O、等待锁、调用 sleep/wait、主动 yield、被其他线程通知唤醒等。
请谈谈 Thread 中 run() 与 start() 的区别?
start() 启动新线程并自动调用 run();直接调用 run() 只是普通方法调用,在当前线程执行,不创建新线程。
synchronized 和 volatile 关键字的区别?
synchronized 保证原子性和可见性,可阻塞线程。volatile 仅保证可见性和禁止指令重排,不保证原子性。
如何保证线程安全? 不可变对象、线程封闭、锁保护、原子类、ThreadLocal 隔离。
谈谈 ThreadLocal 用法和原理? 为每个线程提供独立的变量副本。原理是 Thread 内部维护 ThreadLocalMap,Key 为 ThreadLocal 实例,Value 为变量值。注意内存泄漏问题(Key 弱引用)。
java 线程中 notify 和 notifyAll 有什么区别?
notify() 唤醒一个等待线程,notifyAll() 唤醒所有等待线程。优先使用 notifyAll 避免死锁风险。
什么是线程池?如何创建一个线程池? 管理一组线程复用,避免频繁创建销毁开销。通过 Executors 工厂类或 ThreadPoolExecutor 构造函数创建,配置核心线程数、最大线程数、队列等参数。
谈一谈 java 线程常见的几种锁? 偏向锁、轻量级锁、重量级锁、公平锁、非公平锁、读写锁(ReentrantReadWriteLock)。
谈一谈线程 sleep() 和 wait() 的区别?
sleep() 是 Thread 静态方法,不释放锁,时间到自动恢复。wait() 是 Object 方法,释放锁,需 notify/notifyAll 唤醒。
谈一谈 JAVA 垃圾回收机制? 自动管理内存,识别无用对象并回收。常用算法:标记 - 清除、标记 - 复制、标记 - 整理。分代收集理论(新生代/老年代)。
回答一下什么是强、软、弱、虚引用以及它们之间的区别? 强引用:不会回收。软引用:内存不足时回收(适合缓存)。弱引用:GC 时立即回收(WeakHashMap)。虚引用:无法获取对象,仅用于跟踪回收(PhantomReference)。
简述 JVM 中类的加载机制与加载过程? 加载、验证、准备、解析、初始化。双亲委派模型:先委托父类加载,父类找不到再自己加载。
JVM、Dalvik、ART 三者的原理和区别? JVM 标准 Java 虚拟机。Dalvik 是 Android 早期虚拟机,基于寄存器,即时编译(JIT)。ART 是 Android 5.0+ 虚拟机,预编译(AOT),启动快但安装慢。
请谈谈 Java 的内存回收机制? 同上,重点区分新生代(Eden/Survivor)和老年代回收策略(Minor GC/Major GC/Full GC)。
JMM 是什么?它存在哪些问题?该如何解决? Java 内存模型,定义线程与主内存交互规则。问题:可见性、原子性、有序性。解决:volatile、synchronized、Lock、原子类。
Activity 与 Fragment 之间常见的几种通信方式? Activity 传参给 Fragment(setArguments),Fragment 回调接口给 Activity,使用 ViewModel/LiveData 共享数据,EventBus 等。
LaunchMode 的应用场景? standard(默认多实例)、singleTop(栈顶复用)、singleTask(栈内复用)、singleInstance(独立栈)。用于控制页面跳转行为及任务栈结构。
对于 Context,你了解多少? 上下文,提供资源访问、启动组件等功能。Context 类型:Application(全局)、Activity(界面)、Service(服务)。注意避免内存泄漏,不要将 Activity Context 传给长生命周期对象。
IntentFilter 是什么?有哪些使用场景? 声明组件能响应的 Intent 类型。用于隐式启动、广播接收、ContentProvider 权限匹配等。
谈一谈 startService 和 bindService 的区别,生命周期以及使用场景?
startService 后台运行,生命周期独立于组件,需 stopService 停止。bindService 绑定连接,随组件销毁而断开。前者适合后台任务,后者适合数据交互。
Service 如何进行保活? 前台 Service(Notification)、JobScheduler、AlarmManager、监听系统广播(开机、网络变化)等。需注意不同厂商 ROM 的限制。
简单介绍下 ContentProvider 是如何实现数据共享的? 跨进程数据共享机制,封装数据库或文件,提供 CRUD 接口。通过 URI 标识数据源,支持权限控制。
说下切换横竖屏时 Activity 的生命周期? onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume。若配置了 configChanges 可避免重建。
Intent 传输数据的大小有限制吗?如何解决? 限制约 1MB。大数据应通过 FileProvider 传递文件路径,或使用 AIDL/Binder 传输流。
HandlerThread 的使用场景和用法? 自带 Looper 的线程,常用于后台耗时任务的消息循环处理,如下载、日志写入。
IntentService 的应用场景和使用姿势? 已废弃,用于处理一次性后台任务,自动停止。现推荐使用 JobIntentService 或 WorkManager。
AsyncTask 的优点和缺点? 优点:简化异步,回调方便。缺点:内存泄漏风险,API 19 后废弃,不支持长时间运行。
谈谈你对 Activity.runOnUiThread 的理解? 在主线程执行 Runnable,内部通过 Handler 发送消息实现,用于子线程更新 UI。
子线程能否更新 UI?为什么? 不能。Android UI 是非线程安全的,防止竞态条件。必须在主线程(UI 线程)更新。
谈谈 Handler 机制和原理? 消息驱动模型。Handler 发送 Message/Runnable,Looper 循环取出 Message,Callback 分发处理。MessageQueue 存储消息。
为什么在子线程中创建 Handler 会抛异常? 子线程没有 Looper,Looper.prepare() 未调用。需在子线程调用 Looper.loop() 或在主线程创建。
Handler 中有 Loop 死循环,为什么没有阻塞主线程,原理是什么? Looper.loop() 是死循环,但其中调用了 MessageQueue.next() 进行阻塞等待。有消息时唤醒处理,无消息时休眠,不占用 CPU。
什么是冒泡排序?如何优化? 相邻元素交换,每轮选出最大/最小值。优化:设置标志位,若一轮无交换则提前结束。
请用 Java 实现一个简单的单链表? (略,包含 Node 类和 add/remove 方法)
如何反转一个单链表? 遍历链表,修改 next 指针指向,使用三个指针(prev, curr, next)迭代完成。
谈谈你对时间复杂度和空间复杂度的理解? 时间复杂度衡量算法运行时间随输入规模增长的变化趋势。空间复杂度衡量额外内存消耗。常用大 O 表示法。
谈一谈如何判断一个链表成环? 快慢指针法。快指针每次走两步,慢指针一次一步,若相遇则有环。
什么是红黑树?为什么要用红黑树? 自平衡二叉查找树,满足特定颜色属性。保证最坏情况 O(log n),比 AVL 树旋转少,适合频繁插入删除场景(如 HashMap)。
什么是快速排序?如何优化? 分治法,选基准值分区。优化:三数取中法选基准,小区间用插入排序。
说说循环队列? 首尾相接的数组,解决普通队列假溢出问题。通过 (head + 1) % size == tail 判断满,tail - head == 0 判断空。
如何判断单链表交叉? 计算两链表长度差,长链表先走差值步,然后同步遍历,首次相遇点即为交点。
Binder 有什么优势 高效(一次拷贝)、安全(权限校验)、支持跨进程通信(IPC)。
Binder 是如何做到一次拷贝的 利用 mmap 内存映射,数据在内核态和用户态之间共享虚拟地址,无需多次内存复制。
MMAP 的内存映射原理了解吗 将磁盘文件或设备映射到进程虚拟地址空间,实现零拷贝传输。
Binder 机制是如何跨进程的 客户端发起请求,内核层转发至服务端,服务端返回结果。涉及 Client、Server、Driver 三层。
说说四大组件的通信机制 主要依赖 Binder 机制。Activity、Service、BroadcastReceiver 均通过 Binder 与 AMS 通信。
为什么 Intent 不能传递大数据 Intent 通过 Binder 传递,受限于 Binder 事务缓冲区大小(约 1MB)。大数据应通过文件路径或 Stream 传递。
HandlerThread 是什么?为什么它会存在? 继承 Thread 的类,内部初始化 Looper。用于创建带消息循环的后台线程。
简述下 Handler 机制的总体原理? Handler 发送消息 -> MessageQueue 排队 -> Looper 循环取出 -> Handler 回调处理。
Looper 存在哪?如何可以保证线程独有? 存储在 ThreadLocal 中。每个线程调用 prepare() 创建 Looper 并存入 ThreadLocal。
如何理解 ThreadLocal 的作用? 线程隔离变量,每个线程拥有独立副本,避免线程安全问题。
主线程 Main Looper 和一般 Looper 的异同? 主线程 Looper 在 Application 启动时由 System.init 创建。普通线程需手动调用 Looper.prepare()。
Handler 或者说 Looper 如何切换线程? 在目标线程创建 Handler,该 Handler 关联目标线程的 Looper。发送消息即进入目标线程队列。
Looper 的 loop() 死循环为什么不卡死? 调用 MessageQueue.next() 时会阻塞等待,有消息才唤醒,CPU 空闲时休眠。
Looper 的等待是如何能够准确唤醒的? 通过 Epoll 机制监控文件描述符,当有消息写入队列时触发中断唤醒。
Message 如何获取?为什么这么设计? 从 MessageQueue 按优先级和时间戳获取。设计为对象池复用,减少 GC 压力。
ActivityManagerService 是什么?什么时候初始化的?有什么作用? Android 系统核心服务,管理所有应用进程和组件生命周期。在 Zygote 启动后由 SystemServer 初始化。
ActivityThread 是什么?ApplicationThread 是什么?他们的区别
ActivityThread 是应用的主线程入口。ApplicationThread 是 Binder 接口,用于 AMS 与 App 进程通信。
Instrumentation 是什么?和 ActivityThread 是什么关系? 测试框架核心,也用于 Hook 系统。ActivityThread 持有 Instrumentation 实例,用于启动组件。
ActivityManagerService 和 zygote 进程通信是如何实现的。 通过 Binder 机制。AMS 作为服务端,Zygote 启动的进程作为客户端建立连接。
ActivityRecord、TaskRecord、ActivityStack,ActivityManager、ActivityManagerService、Activity... 这些是 AMS 内部的数据结构。ActivityRecord 记录单个 Activity 信息,TaskRecord 记录任务栈,ActivityStack 管理任务栈列表。
手写实现简化版 AMS 需模拟进程注册、组件启动、生命周期回调、状态管理等核心逻辑,涉及 Binder 通信和状态机设计。
如何运用二分查找算法 适用于有序数组。设定左右边界,取中间值比较,缩小范围直至找到目标。注意边界条件和整数溢出。
如何高效解决接雨水问题 双指针法或单调栈。双指针从两端向中间扫描,记录左右最大值,累加 min(leftMax, rightMax) - height[i]。
二分查找高效判定子序列 结合贪心思想,对每个字符在字符串中找下一个匹配位置,可用预处理 + 二分加速。
如何去除有序数组的重复元素 双指针法。快指针遍历,慢指针记录不重复位置,覆盖重复项,返回慢指针索引。
如何寻找最长回文子串 中心扩展法或 Manacher 算法。以每个字符为中心向两边扩展,记录最长回文区间。
如何高效进行模幂运算 快速幂算法。将指数二进制分解,通过平方和乘法减少运算次数,时间复杂度 O(log n)。
如何运用贪心思想广域玩跳跃游戏 维护当前能到达的最远位置,遍历数组更新最远距离,若当前位置超过最远则不可达。
如何高效判断回文链表 快慢指针找中点,反转后半部分链表,对比前后两部分是否一致。
如何在无线序列中随机抽取元素 蓄水池抽样算法。遍历第 i 个元素,以 1/i 概率替换当前选中元素,保证每个元素被选中概率相等。
如何判定括号合法性 栈结构。左括号入栈,右括号匹配出栈。遍历结束栈为空则合法。
如何寻找缺失和重复的元素 数学求和法或哈希表。计算总和差值或利用异或特性找出缺失和重复数字。
请说一说 HashMap,SparseArray 原理,SparseArray 相比 HashMap 的优点、ConcurrentHashMap 如何实现线程安全?
HashMap 哈希表。SparseArray 针对 int 优化的数组映射,节省内存(无 Entry 对象)。ConcurrentHashMap 1.8 使用 CAS + synchronized 锁链表头节点。
请说一说 HashMap 原理,存取过程,为什么用红黑树,红黑树与完全二叉树对比,HashTab、concurrentHashMap,concurrent 包里有啥? 存取:hash(key) -> index -> bucket -> chain/tree。红黑树防哈希碰撞退化。ConcurrentHashMap 线程安全。Concurrent 包包含 CopyOnWriteArrayList、BlockingQueue、Semaphore 等。
请说一说 hashmap put() 底层原理,发生冲突时,如何去添加? 计算 hash,定位桶。若桶为空直接放入;若有冲突,遍历链表/树。若 key 相等则覆盖;否则插入链表头或红黑树节点。
请简述一下什么是 Kotlin?它有哪些特性? JetBrains 开发的静态类型语言,兼容 Java。特性:空安全、协程、扩展函数、数据类、Lambda 表达式。
Kotlin 中实现单例的几种常见方式? object 关键字(推荐)、Companion Object、双重检查锁定(Java 风格)。
在 Kotlin 中,什么是内联函数?有什么作用? inline 修饰函数,调用处展开代码体,避免 Lambda 创建对象的开销,提升性能。
请谈谈 Kotlin 中的 Coroutines,它与线程有什么区别?有哪些优点? 协程是轻量级线程,用户态调度。优点:非阻塞、高并发、代码简洁(挂起函数)、易于取消。
说说 Kotlin 中的 Any 与 Java 中的 Object 有何异同? Any 是 Kotlin 顶层类,对应 Java 的 Object。Kotlin 中所有类都继承 Any,且区分 null 与非 null 类型。
Kotlin 中的数据类型有隐式转换吗?为什么? 没有。Kotlin 强调类型安全,显式转换更安全,避免意外数据丢失。
Kotlin 中集合遍历有哪几种方式 for 循环、forEach、map/filter/reduce 等高阶函数。
Kotlin 内置标准函数 let 的原理是什么? 接受 lambda,将对象作为 this 传入,返回 lambda 结果。常用于空值检查和链式调用。
Kotlin 语言的 run 高阶函数的原理是什么? 类似 let,但 lambda 中 this 指向对象本身,返回 lambda 最后一个表达式的值。
怎么做到直播秒开优化? 降低首帧延迟,使用低延迟协议(WebRTC/HLS Low Latency),预加载关键帧,CDN 加速。
数字图像滤波有哪些方法? 平滑滤波(均值、高斯)、锐化滤波(拉普拉斯)、中值滤波(去噪)。
图像可以提取的特征有哪些? 边缘、角点、纹理、颜色直方图、SIFT/SURF 特征点。
FFMPEG:图片如何合成视频 使用 ffmpeg 命令,指定输入图片序列,编码格式,输出 mp4 等容器。
常见的音视频格式有哪些? 视频:MP4, MKV, AVI, MOV。音频:MP3, AAC, WAV。封装:TS, FLV。
请叙述 MPEG 视频基本码流结构? 序列头、GOP(组图像)、P 帧、B 帧、I 帧。分层结构包含 Video Sequence Header, Picture Header, Slice。
说一说 fffmpeg 的数据结构? AVFormatContext(格式)、AVStream(流)、AVCodecContext(编解码)、AVPacket(数据包)、AVFrame(帧)。
如何降低延迟?如何保证流畅性?如何解决卡顿?解决网络抖动? 降低延迟:减小缓冲、优化编码。流畅性:自适应码率、CDN。卡顿:预缓冲、丢帧策略。抖动:抖动缓冲(Jitter Buffer)。
平时说的软解和硬解,具体是什么? 软解:CPU 解码,兼容性好,耗电高。硬解:GPU/专用芯片解码,效率高,省电,兼容性受限。
Dart 语言的特性? 面向对象、可选类型、异步编程(Future/Stream)、Hot Reload 支持、JIT/AOT 编译。
Dart 多任务如何并行的? 通过 Isolates 实现真正的并行,共享内存通过 SendPort 通信,避免共享状态。
dart 是值传递还是引用传递? 值传递。对象引用也是值传递,即传递的是引用的副本。
Flutter 特性有哪些? 跨平台、热重载、丰富 Widget 库、高性能渲染引擎(Skia/Impeller)。
Widget 和 element 和 RenderObject 之间的关系? Widget 是配置描述(不可变),Element 是 Widget 在树中的实例(可更新),RenderObject 负责布局绘制(不可变)。三者构成构建、元素、渲染三层架构。
使用 mixins 的条件是什么? Dart 中 Mixin 用于复用代码,要求类必须是 mixin class,不能直接实例化,用于组合功能。
Stream 两种订阅模式? 单次订阅(Single Subscription)和多次订阅(Broadcast Stream)。前者事件发完即失效,后者允许多个监听者。
Flutter 中的 Widget、State、Context 的核心概念?是为了解决什么问题? Widget 描述 UI,State 管理数据变化,Context 提供访问环境和依赖。解决 UI 与数据分离及状态更新问题。
说一下 Hot Reload,Hot Restart,热更新三者的区别和原理 Hot Reload:注入新代码,保留状态,刷新 UI。Hot Restart:重启应用,重置状态。热更新:下发新包,跳过商店审核(需谨慎合规)。
Flutter 如何与 Android iOS 通信? Platform Channels。Flutter 端 MethodChannel 调用原生端代码,通过 EventChannel 接收事件。
说一下什么是状态管理,为什么需要它? 管理应用数据在不同组件间的共享和同步。需要它是因为 Widget 层级深,Props Drilling 繁琐,状态管理(Provider/Riverpod/Bloc)简化数据流。
注:本文档仅供学习参考,实际面试中请结合项目经验灵活作答。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online