跳到主要内容Android 中高级开发核心面试题库:Java、架构与算法详解 | 极客日志Java大前端java算法
Android 中高级开发核心面试题库:Java、架构与算法详解
Android 中高级开发面试涵盖 Java 基础、Android 系统原理、开源库源码分析、设计模式、Gradle 构建及常见算法题。内容涉及多态、线程池、JVM 内存模型、消息队列、ART 机制、网络缓存策略、插件化热修复架构以及二叉树遍历等核心知识点,旨在帮助开发者系统复习大厂面试高频考点。
佛系玩家23 浏览 Android 中高级开发核心面试题库
本文整理了互联网大厂 Android 岗位高频面试题,涵盖 Java 基础、Android 系统原理、开源库源码分析、设计模式、Gradle 构建及常见算法题。内容旨在帮助开发者系统复习核心技术点。
Java 知识汇总
谈谈对 java 多态的理解?
Java 多态是指同一个行为具有多个不同表现形式或形态的能力。分为编译时多态(方法重载)和运行时多态(方法重写)。它允许子类对象替换父类对象,增强代码的扩展性和灵活性。
你所知道的设计模式有哪些?
常见设计模式包括单例模式、工厂模式、观察者模式、适配器模式、装饰者模式、代理模式等。在 Android 开发中,MVC、MVP、MVVM 也是常用的架构模式。
通过静态内部类实现单例模式有哪些优点?
静态内部类方式实现了懒加载,且线程安全。只有当外部类被首次使用时才会加载内部类,从而实例化单例对象,避免了多线程同步开销。
什么是线程池,如何使用?为什么要使用线程池?
线程池是管理一组工作线程的容器。使用 Executors 工具类创建,如 FixedThreadPool。使用线程池可以复用线程,降低资源消耗,提高响应速度,并便于统一管理。
Java 中的线程池共有几种?
主要包括:SingleThreadExecutor、CachedThreadPool、ScheduledThreadPool、FixedThreadPool 以及自定义线程池。生产环境建议手动创建 ThreadPoolExecutor 以控制参数。
JVM 的内存模型的理解?
JVM 内存主要分为堆(Heap)、栈(Stack)、方法区(Method Area)、程序计数器、本地方法栈。堆存储对象实例,栈存储局部变量和方法调用,方法区存储类信息和常量。
描述一下 GC 的原理和回收策略?
GC 通过可达性分析算法判断对象是否存活。回收策略包括标记 - 清除、标记 - 复制、标记 - 整理。新生代采用复制算法,老年代采用标记 - 整理或标记 - 清除。
JDK 1.7 HashMap 结构图
JDK 1.7 中 HashMap 底层是数组 + 链表。哈希冲突时使用链地址法解决,头插法插入节点。
如果 HashMap 的大小超过了负载因子 (load factor) 定义的容量,怎么办?
当元素数量超过容量 * 负载因子时,HashMap 会进行扩容(resize),将容量翻倍,并重新计算所有元素的哈希位置,迁移到新的数组中。
为什么 String, Integer 这样的 wrapper 类适合作为键?
String 是不可变的,其 hashCode 可缓存且稳定。Wrapper 类通常也实现了 equals 和 hashCode 的正确逻辑,保证了键的唯一性和查找效率。
Android 知识汇总
SharedPreferences 内部工作原理
SharedPreferences 基于 XML 文件存储数据。读取时解析 XML 到内存 Map,写入时异步序列化回磁盘。注意大文件读写会影响性能。
什么是消息队列
Android 消息队列(MessageQueue)用于处理 Handler 发送的消息。它是单线程阻塞队列,配合 Looper 循环不断取出并分发 Message 给 Handler 处理。
线程有没有 Looper 有什么区别?
主线程默认有 Looper,子线程没有。子线程需手动调用 Looper.prepare() 和 Looper.loop() 才能接收消息。否则无法使用 Handler 发送消息。
使用 AsyncTask 的规则?
AsyncTask 已废弃。若使用需注意:不能跨线程访问 UI,生命周期绑定 Activity,易导致内存泄漏。推荐使用 Executor 或 Kotlin Coroutines。
ArrayMap 是什么?
ArrayMap 是 Android 提供的轻量级 Map 实现,基于两个数组存储 key 和 value。相比 HashMap 节省内存,适合小数据量场景。
startActivity 启动过程是怎么样的?
ActivityManagerService (AMS) 接收请求,检查权限和目标进程,启动目标进程(Zygote fork),创建 Application 和 Activity 对象,执行 onCreate/onStart/onResume。
SystemServer 是什么?有什么作用?它与 zygote 的关系是什么?
SystemServer 是 Android 系统服务的主进程,负责启动核心系统服务(如 AMS, WMS)。它由 Zygote 进程 fork 而来,运行在 init 进程之后。
一个 App 的程序入口到底是什么?
App 入口通常是 Application 类的 onCreate 方法,或者 Launcher 点击图标后 AMS 启动的 Activity 的 onCreate 方法。
组件化基础框架
组件化是将应用拆分为独立模块,通过路由机制通信。好处是解耦、并行开发、按需加载。难点在于依赖管理和路由注册。
消息总线的优点和缺点
优点:解耦,事件驱动,方便调试。缺点:难以追踪调用链路,可能产生内存泄漏,过度使用影响性能。
Android 拓展知识
你了解 ART 嘛?
ART (Android Runtime) 是 Android 5.0+ 的虚拟机。相比 Dalvik 的 JIT,ART 采用 AOT (Ahead-Of-Time) 编译,安装时预编译,提升运行速度但增加安装时间。
Apk 组成结构
APK 包含 classes.dex (字节码), resources.arsc (资源表), assets (原始资源), lib (so 库), AndroidManifest.xml (清单文件)。
常用的自定义混淆规则
常用 ProGuard/R8 规则:保留特定类 (-keep), 保留字段 (-keepclassmembers), 忽略警告 (-dontwarn)。针对第三方库配置白名单。
自己去设计网络请求框架,怎么做?
基于 OkHttp 封装,支持拦截器链、回调/协程适配、统一错误处理、缓存策略、日志打印。使用动态代理或泛型简化 API。
网络请求缓存处理,okhttp 如何处理网络缓存的?
OkHttp 内置 Cache 类,通过 Request 的 Cache-Control 头决定缓存策略。支持强制网络、只读缓存、优先缓存等模式。
TCP 的 3 次握手和四次挥手
三次握手建立连接(SYN, SYN-ACK, ACK),四次挥手断开连接(FIN, ACK, FIN, ACK)。确保连接可靠性和状态同步。
谈谈你对 WebSocket 的理解
WebSocket 是全双工通信协议,基于 TCP。相比 HTTP 长轮询,延迟更低,服务器可主动推送数据,适合实时聊天、游戏等场景。
请解释安卓为啥要加签名机制?
签名用于验证应用来源和完整性,防止篡改。同一签名允许应用覆盖安装,不同签名则视为新应用。保证系统安全和用户信任。
App 是如何沙箱化,为什么要这么做?
每个 App 拥有独立的 Linux 用户 ID 和数据目录。沙箱隔离防止恶意应用窃取数据,保护系统稳定性,限制权限滥用。
权限管理系统(底层的权限是如何进行 grant 的)?
权限在 Manifest 声明,运行时动态申请。Grant 通过 PackageManagerService 修改系统配置,记录在权限数据库中,内核层进行 UID/GID 校验。
Android 开源库源码分析
LeakCanary
LeakCanary 利用 WeakReference 检测内存泄漏。通过监听 Activity/Fragment 销毁,对比强引用和弱引用对象,发现未释放的实例。
EventBus
EventBus 基于观察者模式。发布订阅解耦,支持粘性事件、优先级、线程调度。注意避免内存泄漏,需在 onDestroy 取消订阅。
Glide:加载、缓存、LRU 算法
Glide 支持图片加载、变形、缓存。使用 LRU 缓存策略管理内存和磁盘缓存。通过 DiskCacheStrategy 控制缓存范围。
Install
安装流程涉及 PackageInstallerService,解析 APK 签名、权限、组件信息,复制到指定目录,广播安装完成通知。
ARouter
ARouter 基于注解处理器生成路由表。运行时反射匹配路径,实现页面跳转和解耦。支持参数传递、拦截器和降级策略。
插件化(不同插件化机制原理与流派,优缺点。局限性)
主流方案:Hook 系统类(如 Hook Context)、动态加载 Dex。优点是灵活,缺点是兼容性问题,系统升级可能导致失效,安全性较低。
热修复
热修复通过 Patch 技术修复 Bug。原理:Hook ClassLoader 加载补丁 Dex,或替换 Method 实现。需注意签名一致性和兼容性。
RxJava(RxJava 的线程切换原理)
RxJava 通过 Scheduler 切换线程。Observable 发射数据,Observer 接收。switchOnNext 等操作符控制线程上下文,底层依赖线程池。
Retrofit (Retrofit 在 OkHttp 上做了哪些封装?动态代理和静态代理)
Retrofit 基于动态代理生成接口实现。将 HTTP 请求转换为 OkHttp Call,通过 Converter 转换数据格式。支持同步/异步调用。
OkHttp
OkHttp 高效 HTTP 客户端。支持连接池、HTTP/2、缓存、拦截器链。底层基于 NIO 和非阻塞 IO,提升并发性能。
设计模式汇总
谈谈你对 Android 设计模式的理解
Android 大量使用设计模式,如 Builder 构建 View,Observer 处理事件,Adapter 视图绑定。理解模式有助于编写可维护代码。
MVC MVP MVVM 原理和区别
MVC 耦合度高;MVP 分离 View 和 Model,Presenter 处理逻辑;MVVM 双向绑定,ViewModel 暴露数据状态。MVVM 更适合现代 Android 开发。
你所知道的设计模式有哪些?
见 Java 部分补充。重点掌握单例、工厂、代理、观察者、建造者、策略模式。
项目中常用的设计模式
常用:单例(工具类)、Builder(复杂对象)、Adapter(列表)、Observer(事件总线)、Factory(对象创建)。
适配器模式,装饰者模式,外观模式的异同?
适配器:接口转换;装饰者:动态添加功能;外观:简化子系统接口。三者目的不同,但都涉及封装。
用到的一些开源框架,介绍一个看过源码的,内部实现过程。
例如 Glide:初始化 Engine -> 获取缓存 -> 加载资源 -> 解码 -> 显示。核心是内存/磁盘缓存策略和线程调度。
谈谈对 RxJava 的理解
响应式编程库,处理异步流。提供操作符组合数据流,简化回调地狱。需理解背压处理和线程调度。
RxJava 的作用,与平时使用的异步操作来比的优缺点
作用:链式处理异步任务。优点:代码简洁,组合性强。缺点:学习曲线陡,调试困难,内存占用稍高。
从 0 设计一款 App 整体架构,如何去做?
分层架构:UI 层、业务层、数据层。引入 MVVM,使用 Repository 统一数据源,依赖注入管理对象生命周期,模块化拆分功能。
说一款你认为当前比较火的应用并设计 (比如:直播 APP,P2P 金融,小视频等)
以小视频为例:前端 Flutter/原生,后端微服务。视频上传 OSS,转码 CDN 分发。推荐算法基于用户行为画像。架构需考虑高并发和实时性。
Gradle 知识点汇总
Gradle 命令行?
常用命令:gradle build, gradle clean, gradle assembleDebug, gradle tasks 查看任务列表。
如何应用 Android Gradle 插件?
在 build.gradle 中 apply plugin: 'com.android.application' 或在 settings 中配置 plugins 块。
如何配置第三方依赖?
在 repositories 中添加仓库地址,dependencies 中添加 implementation 'group:artifact:version'。
说说从 Eclipse 迁移到 Android Gradle 工程
Eclipse 使用 Ant/Maven 混合,Gradle 统一构建。迁移需调整项目结构,配置 SDK 路径,处理依赖冲突。
自定义 Android Gradle 工程
可通过 create 任务定义自定义构建逻辑,继承 DefaultTask,在 afterEvaluate 中修改配置。
如何批量修改生成的 apk 文件名?
在 applicationVariants.all 中遍历 variant,修改 outputFile 属性,结合版本号和时间戳命名。
Android 的 Gradle 多项目构建
使用 settings.gradle 引入子模块。共享依赖配置,统一版本管理,优化构建速度。
什么是持续集成?
CI 指频繁自动构建和测试代码。工具如 Jenkins, GitLab CI。确保代码质量,快速发现问题。
Android Gradle 持续集成的价值
自动化打包、测试、部署。减少人工错误,加快发布周期,保证版本一致性。
怎样更高地做持续集成?
并行构建,缓存依赖,增量编译,单元测试覆盖率监控,代码扫描集成。
常见面试算法题汇总
二叉树的深度优先遍历和广度优先遍历的具体实现
DFS:递归或栈实现,前序/中序/后序。BFS:队列实现,层序遍历。时间复杂度 O(n),空间 O(h) 或 O(w)。
堆的结构
堆是完全二叉树,分为最大堆和最小堆。父节点大于/小于子节点。常用于优先队列。
堆和树的区别
树是通用数据结构,堆是特殊的完全二叉树,满足堆序性质。堆主要用于排序和优先级管理。
堆和栈在内存中的区别是什么
堆(Heap)存储对象,动态分配,大小不固定。栈(Stack)存储局部变量,函数调用帧,自动管理,速度快。
讲一下对树,B+ 树的理解
树是多叉结构。B+ 树是平衡多路搜索树,非叶子节点存索引,叶子节点存数据且相连。数据库索引常用 B+ 树,查询效率高。
讲一下对图的理解
图由顶点和边组成,分有向/无向,加权/无权。用于表示网络关系。遍历用 BFS/DFS,最短路径用 Dijkstra。
什么是深拷贝和浅拷贝
浅拷贝复制对象引用,新对象与原对象共享数据。深拷贝复制整个对象及其引用的对象,完全独立。
判断单链表成环与否?
使用快慢指针。快指针每次走两步,慢指针一次一步。若相遇则有环。时间 O(n),空间 O(1)。
链表翻转(即:翻转一个单项链表)
迭代法:维护 prev, curr, next 指针,逐个反转指向。递归法:反转后续链表,调整当前节点指向。
合并多个单有序链表(假设都是递增的)
使用最小堆或分治法。每次取各链表头节点最小值加入结果,移动对应指针。时间 O(N log k)。
相关免费在线工具
- 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