跳到主要内容2023 版 Android 面试指南,涵盖核心技能 | 极客日志Java大前端java算法
2023 版 Android 面试指南,涵盖核心技能
综述由AI生成Android 面试涉及 Java 基础、集合、多线程、JVM、Android 四大组件、Handler 机制、Binder、AMS 框架、数据结构算法、Kotlin 特性及音视频与 Flutter 知识。文章梳理了常见面试题并提供了参考思路,帮助开发者系统复习,提升面试通过率。
CodeArtist37 浏览 前言
近年来互联网行业竞争加剧,面试难度显著提升。考察内容不仅涉及表面应用,更深入到底层原理与系统设计。面试机会相对减少,因此准备过程需更加充分。建议不要盲目参加面试,大厂通常会有面试评价记录,过多的差评可能影响后续求职。面试后应及时复盘,整理知识点,查漏补缺。
面试前需要准备
1. Android 八股文
了解常考的题型和回答思路,建立知识体系框架。
2. 算法能力
刷 100-200 道经典题目。记住刷题最重要的是理解其思想,不要死记硬背。碰上原题很难,但大多数解题思路是相通的。重点掌握数据结构与常见算法模式。
3. 项目经验
主要准备最近一家公司所负责的业务和项目:
- 项目背景:为什么要做这个项目,解决了什么业务痛点。
- 系统演进:有哪几个阶段,每个阶段主要做了什么,技术栈如何迭代。
- 技术选型:在项目中使用工具和框架时的调研过程,为什么选这个方案。
- 项目亮点:你在项目中做过最核心的事,如复杂需求方案设计、性能优化、线上问题处理、项目重构等。
4. 项目管理
主导跨团队项目时,如何高效协调各方工作,使用哪些方法保障按时交付。遇到技术或进度困难时,作为负责人如何应对与决策。这块随着经验增加越来越重要。
5. 通用问题
常见问题包括:
- 为什么离职?
- 在上家公司哪些能力得到了成长?
- 平时怎么学习的?
6. 反向提问
面试最后面试官通常会问有没有想问的。如果不知道问什么,可以询问团队当前负责的业务是什么,主要面临的挑战是什么,这能体现你的思考深度。
Java 方面
Java 基础部分
抽象类与接口的区别?
抽象类是对类的抽象,可以有构造器,有成员变量,可以有非抽象方法。接口是对行为的抽象,只能有常量(public static final),不能有构造器,Java 8 之前只能有抽象方法,之后可以有默认方法和静态方法。一个类可以实现多个接口,但只能继承一个抽象类。
final, static, synchronized 关键字
- final:修饰类表示不可继承,修饰方法表示不可重写,修饰变量表示常量(引用地址不变)。
- static:修饰成员表示属于类而非实例,可通过类名直接访问,用于工具方法或共享资源。
- synchronized:用于多线程同步,保证同一时刻只有一个线程执行代码块或方法。
String, StringBuffer 和 StringBuilder 的区别?
String 是不可变的字符序列,每次修改都会生成新对象。StringBuffer 是可变的且线程安全(方法加锁)。StringBuilder 是可变的且非线程安全,性能优于 StringBuffer。单线程下推荐用 StringBuilder。
equals() 与 ==、hashCode 的区别和使用场景?
== 比较的是内存地址(基本类型比较值)。equals() 默认比较地址,Object 子类可重写比较内容(如 String)。hashCode() 用于哈希表定位,若重写 equals() 必须重写 hashCode(),保证相等对象的哈希码相同。
深拷贝与浅拷贝的区别?
浅拷贝只复制对象本身,不复制引用的对象,两者指向同一内存。深拷贝会递归复制所有引用的对象,完全独立。
Error 和 Exception 的区别?
Error 是 JVM 无法处理的严重错误(如 OutOfMemory),程序无法恢复。Exception 是程序可以处理的异常,分为受检异常(Checked)和非受检异常(Unchecked)。
反射机制及应用场景?
反射允许在运行时获取类的信息并操作类成员。应用场景包括框架开发(如 Spring IOC)、动态代理、序列化库等。
泛型中类型擦除的理解及局限性?
Java 泛型在编译期进行类型检查,运行时会擦除泛型类型信息,替换为 Object 或边界类型。局限性在于无法获取泛型的实际类型参数,无法创建泛型数组。
String 为什么要设计成不可变的?
安全性(字符串常量大池)、线程安全、Hash 缓存优化、类加载器等。
注解的理解?
元数据,用于标记代码,编译器或运行时框架可读取注解进行处理,如@Override, @Deprecated。
Java 集合
List, Set, Map 的区别?
List 有序可重复;Set 无序不可重复;Map 键值对存储,Key 唯一。
ArrayList 和 LinkedList 的区别?
ArrayList 基于数组,随机访问快,增删慢(需移动元素)。LinkedList 基于双向链表,随机访问慢,增删快(只需修改指针)。
HashMap 与 Hashtable 的区别?
Hashtable 线程安全(全方法加锁),不允许 null 键值,效率低。HashMap 非线程安全,允许 null,效率高。ConcurrentHashMap 是线程安全的高性能替代。
ArrayList 扩容机制?
默认容量 10,当元素超过容量时,扩容为原来的 1.5 倍,并重新分配数组。
HashMap 实现原理?
数组 + 链表 + 红黑树。通过 key 的 hash 值计算索引位置。冲突时链表挂载,链表长度超过阈值转为红黑树。
LinkedHashMap 工作原理?
继承自 HashMap,维护了一个双向链表记录插入顺序或访问顺序。
ConcurrentHashMap 理解?
JDK 1.7 分段锁,JDK 1.8 CAS+synchronized 锁住链表头节点,并发度更高。
Java 多线程
多线程方式?
继承 Thread 类,实现 Runnable 接口,实现 Callable 接口配合 FutureTask,使用线程池。
线程状态?
新建 (NEW)、就绪 (RUNNABLE)、阻塞 (BLOCKED)、等待 (WAITING)、计时等待 (TIMED_WAITING)、终止 (TERMINATED)。
同步实现?
synchronized 关键字,Lock 接口(ReentrantLock),volatile 关键字,原子类。
线程死锁及避免?
死锁产生于循环等待资源。避免方法:按固定顺序获取锁,设置超时时间,使用 Lock.tryLock()
线程阻塞原因?
等待 I/O,等待锁,调用 sleep/wait,主动 yield。
Thread run() 与 start() 区别?
start() 启动新线程执行 run()。run() 只是普通方法调用,在当前线程执行。
synchronized 和 volatile 区别?
synchronized 保证原子性和可见性,volatile 只保证可见性和有序性,不保证原子性。
线程安全保证?
不可变对象,线程封闭,锁保护,ThreadLocal。
ThreadLocal 用法和原理?
提供线程局部变量,每个线程拥有独立副本。原理是 Thread 内部维护 ThreadLocalMap。
notify 和 notifyAll 区别?
notify 唤醒一个等待线程,notifyAll 唤醒所有等待线程。优先用 notifyAll 避免死锁。
线程池及创建?
ThreadPoolExecutor 核心参数:corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, handler。
常见锁?
sleep() 和 wait() 区别?
sleep 是 Thread 静态方法,不释放锁,指定时间自动恢复。wait 是 Object 方法,释放锁,需 notify 唤醒。
Java 虚拟机
垃圾回收机制?
分代收集理论,新生代(Eden, Survivor),老年代。常用算法:标记清除,标记复制,标记整理。
引用类型?
强引用(不被回收),软引用(内存不足回收),弱引用(GC 即回收),虚引用(仅通知回收)。
类加载机制?
加载 -> 验证 -> 准备 -> 解析 -> 初始化。双亲委派模型。
JVM, Dalvik, ART 区别?
JVM 标准 Java 虚拟机。Dalvik 是 Android 早期虚拟机,执行 .dex。ART 是 Android 5.0+ 虚拟机,AOT 编译,启动快但安装慢。
JMM 是什么?
Java 内存模型,定义线程如何操作内存变量,解决可见性、原子性、有序性问题。
Android 方面
四大组件
Activity 与 Fragment 通信?
Activity 传 Fragment:setArguments。Fragment 传 Activity:回调接口或 EventBus。Fragment 间:通过宿主 Activity 中转。
LaunchMode 应用场景?
Standard(默认),SingleTop(栈顶复用),SingleTask(栈内复用),SingleInstance(独占栈)。
Context 了解多少?
Context 是上下文环境,包含资源、配置等。有 Application, Activity, Service 三种,注意避免内存泄漏。
IntentFilter 及使用场景?
声明组件能响应的 Intent,用于隐式启动,如打开网页、拨打电话。
startService 和 bindService 区别?
startService 生命周期独立,停止需 stopService。bindService 绑定服务,随组件销毁而销毁,支持交互。
Service 保活?
前台服务,JobScheduler,广播监听,系统级白名单等。
ContentProvider 数据共享?
跨进程数据共享,通过 URI 访问数据库或其他数据源。
横竖屏切换生命周期?
onPause, onStop, onDestroy, onCreate, onStart, onResume。可配置 configChanges 避免重建。
Intent 传输数据限制?
Binder 限制约 1MB。大数据需使用 FileProvider 或传递路径。
Android 异步任务和消息机制
HandlerThread 使用场景?
需要后台线程处理耗时任务,自带 Looper,适合长生命周期后台线程。
IntentService 应用?
AsyncTask 优缺点?
优点:简化异步。缺点:内存泄漏风险,Android 11 已移除。
runOnUiThread 理解?
子线程能否更新 UI?
不能,会导致崩溃。必须通过 Handler 或 runOnUiThread。
Handler 机制原理?
MessageQueue 队列,Looper 循环取消息,Handler 发送和处理。主线程有 Looper,子线程无。
子线程创建 Handler 异常?
子线程没有 Looper,调用 prepare() 即可解决。
Loop 死循环为何不阻塞?
Loop 中有 MessageQueue,空闲时进入 native poll 等待,有消息则唤醒。
数据结构
冒泡排序及优化?
单链表实现?
定义 Node 类含 val 和 next,遍历修改指针。
反转单链表?
三指针法:prev, curr, next,逐个反转指向。
时间复杂度与空间复杂度?
时间:算法执行时间随输入规模增长。空间:算法占用内存随输入规模增长。
判断链表成环?
红黑树?
自平衡二叉查找树,保证最长路径不超过最短路径两倍,查询 O(log n)。
快速排序及优化?
分治法,选基准,分区递归。优化:三数取中,小数组插排。
循环队列?
数组首尾相接,解决假溢出,需记录 head 和 tail。
判断单链表交叉?
先找尾节点,若不同尾则不相交。同尾则分别计数长度差,对齐后遍历。
Android Framework
Binder
Binder 优势?
一次拷贝原理?
使用 mmap 映射内存,内核态与用户态共享内存区域。
MMAP 内存映射?
Binder 跨进程?
通过 ServiceManager 注册服务,Client 获取 Stub 代理,通过 AIDL 接口调用。
四大组件通信?
AMS, WMS, PMS 等通过 Binder 通信。
Intent 大数据限制?
Handler
HandlerThread 存在原因?
提供带 Looper 的后台线程,方便使用 Handler 机制。
Handler 总体原理?
发送 Message -> 放入 Queue -> Looper 取出 -> Handler 处理。
Looper 存在哪?
ThreadLocal 作用?
Main Looper 与普通 Looper?
Main Looper 由 SystemServer 创建,常驻主线程。
切换线程?
通过 Handler.post 发送到目标线程的 Looper。
loop() 死循环不卡死?
调用 native pollOnce 阻塞等待消息。
唤醒准确?
Message 获取?
AMS
ActivityManagerService?
管理所有 Activity 的生命周期,初始化在 SystemServer。
ActivityThread vs ApplicationThread?
ActivityThread 是主线程入口,ApplicationThread 是 Binder 服务端接口。
Instrumentation?
AMS 与 Zygote 通信?
手写简化版 AMS?
算法方面
二分查找?
接雨水?
判定子序列?
去除重复元素?
最长回文子串?
模幂运算?
跳跃游戏?
回文链表?
随机抽取元素?
括号合法性?
缺失和重复?
HashMap 原理?
SparseArray 原理?
数组存储 Key 和 Value,比 HashMap 省内存,适合 int 键。
ConcurrentHashMap 线程安全?
HashMap put 底层?
Kotlin 方面
Kotlin 特性?
空安全,扩展函数,协程,数据类,Lambda 表达式。
单例实现?
内联函数?
crossinline, noinline,编译期展开 Lambda,减少对象创建。
Coroutines 与线程?
Any 与 Object?
Any 是顶层父类,Object 是 Java 顶层。Kotlin 中 Any 对应 Java Object。
隐式转换?
集合遍历?
for, forEach, map, filter 等。
let 原理?
高阶函数,接收 lambda,返回结果,常用于空安全链式调用。
run 原理?
接收 lambda,this 指向 receiver,返回 lambda 结果。
音视频方面
直播秒开优化?
预加载,CDN 加速,降低首帧延迟,HLS/DASH 优化。
图像滤波?
图像特征?
FFMPEG 合成视频?
concat demuxer 或 filter_complex。
音视频格式?
MP4, MKV, FLV, WebM, AAC, MP3, H.264, H.265。
MPEG 码流结构?
Sequence Header, GOP, Frame。
FFMPEG 数据结构?
AVFormatContext, AVCodecContext, AVPacket, AVFrame。
降低延迟卡顿?
软解与硬解?
软解 CPU 计算,兼容性好。硬解 GPU/专用芯片,效率高发热低。
Flutter 方面
Dart 特性?
面向对象,可选类型,Isolate 并发,Hot Reload。
Dart 多任务并行?
Isolate 机制,独立内存空间,通过 Port 通信。
值传递还是引用?
Flutter 特性?
热重载,声明式 UI,跨平台,Material/Cupertino 组件。
Widget, Element, RenderObject?
Widget 配置描述,Element 生命周期管理,RenderObject 布局绘制。
Mixins 条件?
Stream 订阅模式?
BroadcastStream 允许多订阅,正常 Stream 单订阅。
Widget, State, Context?
Widget 构建树,State 保存可变数据,Context 访问环境和资源。
Hot Reload vs Restart?
Reload 保留状态刷新 UI,Restart 重启应用重置状态。
Flutter 原生通信?
Platform Channel,MethodChannel 调用原生代码。
状态管理?
Provider, Riverpod, Bloc 等,解决组件间数据共享和 UI 更新问题。
结语
面试不仅是知识的考察,更是思维逻辑与沟通能力的体现。建议结合上述知识点,针对自身项目经历进行深入梳理,形成自己的回答体系。持续学习新技术,保持对底层原理的探索,才能在激烈的竞争中脱颖而出。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online