Android 开发核心知识体系与面试指南精简版

文章目录

  • 概述
    • 一、Java 基础与进阶
        1. 面向对象 (OOP)
        • 1.1 三大特性
        • 1.2 接口 vs 抽象类
        • 1.3 内部类
        1. 集合框架
        • 2.1 ArrayList vs LinkedList
        • 2.2 HashMap vs HashTable
        • 2.3 String、StringBuilder、StringBuffer
        1. 并发与多线程
        • 3.1 线程控制方法对比
        • 3.2 synchronized vs volatile
        • 3.3 线程池(ThreadPoolExecutor)
        1. JVM 相关
        • 4.1 JVM 核心作用
        • 4.2 运行时数据区
        1. 泛型与反射
        • 5.1 泛型
        • 5.2 反射
        1. 类加载机制
        • 双亲委派模型(Parent Delegation)
    • 二、Android 核心组件与机制
        1. 四大组件
        • 1.1 Activity
        • 1.2 Service
        • 1.3 BroadcastReceiver
        • 1.4 ContentProvider
        1. View 体系与事件分发
        1. RecyclerView 与缓存机制
        1. Handler 机制与内存泄漏
    • 三、性能优化(补充详细方案)
        1. 内存优化
        1. 布局优化
        1. 卡顿优化
        1. 启动优化
        1. APK 瘦身
    • 四、架构与设计模式(补充 MVVM 实践)
      • MVVM + Jetpack 推荐架构
    • 五、开源框架原理(补充)
    • 六、新技术趋势
    • 七、场景题与开放性问题(补充回答模板)
      • "请介绍最有挑战的项目"

概述

本文系统梳理了 Android 开发从基础到高级的核心知识点,涵盖 Java 基础、Android 组件、性能优化、架构设计、Framework 原理、主流框架与新技术趋势,旨在帮助中高级开发者构建完整的知识体系,高效准备技术面试,并指导实际项目开发。

适用人群 :Android 中高级工程师、面试准备者、技术面试官、团队技术负责人
建议用法:作为知识地图逐项深入,结合源码阅读与项目实践,持续迭代技术认知。

一、Java 基础与进阶

1. 面向对象 (OOP)

1.1 三大特性
特性 核心概念 作用 实现方式
封装 将数据和行为封装在类中,隐藏实现细节 提高安全性、降低耦合、增强可维护性 使用 private 字段 + public getter/setter
继承 子类继承父类的属性和方法(非私有) 实现代码复用,建立类层次结构 extends 关键字,遵循 "is-a" 关系
多态 同一接口在不同实例下表现出不同行为 提高扩展性与灵活性,支持模块化设计 方法重写 + 动态绑定(运行时决定调用哪个实现)

多态实现机制:基于虚方法表(vtable),JVM 在运行时根据对象实际类型查找对应方法。

1.2 接口 vs 抽象类
对比项 接口(Interface) 抽象类(Abstract Class)
定义关系 "能做什么"(行为规范) "是什么"(共性抽象)
多继承 支持(Java 8+ 默认方法) 不支持
成员 只能有常量和抽象方法(Java 8+ 支持默认/静态方法) 可包含字段、构造器、具体方法
访问控制 所有方法默认 public 可使用 privateprotected
使用场景 定义契约、解耦、策略模式 共享代码、模板方法模式

最佳实践

  • 优先使用接口(符合"面向接口编程"原则)
  • 当需要共享代码或构造逻辑时使用抽象类
  • Java 8+ 可通过接口默认方法实现部分复用
1.3 内部类
类型 特点 使用场景
成员内部类 持有外部类引用,可访问所有成员 封装辅助类,如 Iterator
静态内部类 不依赖外部类实例,无隐式引用 工具类、Builder 模式
局部内部类 定义在方法内,作用域受限 复杂逻辑封装
匿名内部类 无类名,直接实现接口或继承类 快速实现回调、事件监听

注意

  • 成员内部类可能导致内存泄漏(隐式持有外部类引用),建议在 HandlerThread 中使用静态内部类 + WeakReference
  • 避免过度嵌套,影响可读性和维护性。

2. 集合框架

2.1 ArrayList vs LinkedList
特性 ArrayList LinkedList
底层结构 动态数组(连续内存) 双向链表(分散内存)
随机访问 O(1) O(n)
插入/删除(中间) O(n) O(1)
内存占用 较小(仅元素开销) 较大(每个节点含前后指针)
扩容机制 扩容 1.5 倍,触发 Arrays.copyOf 无固定容量,动态添加节点

选择建议

  • 频繁读取 → ArrayList
  • 频繁插入删除 → LinkedList
  • Android 中推荐 ArrayList,因缓存局部性更好,GC 更友好。
2.2 HashMap vs HashTable
特性 HashMap HashTable
线程安全 ❌ 非线程安全 ✅ 方法加 synchronized
性能 更高(无同步开销) 较低
Null 值 允许一个 null 键和多个 null 值 不允许 null 键或值
迭代器 Fail-fast(快速失败) Fail-safe(安全失败)
替代方案 ConcurrentHashMap(推荐) 已过时,不建议使用

HashMap 优化(JDK 8+)

  • 当链表长度 ≥ 8 且哈希表容量 ≥ 64 时,链表转为红黑树,查找复杂度从 O(n) 降为 O(log n)。
  • 容量始终为 2 的幂,便于通过位运算 (n - 1) & hash 计算索引。
2.3 String、StringBuilder、StringBuffer
类型 线程安全 性能 使用场景
String 不可变 低(频繁拼接产生大量对象) 少量操作、常量
StringBuffer 同步 中等 多线程环境拼接
StringBuilder 非同步 单线程大量拼接(推荐)

原理String 是 final 类,每次拼接都会创建新对象;后两者基于可变字符数组(char[])实现。


3. 并发与多线程

3.1 线程控制方法对比
方法 是否释放锁 是否让出 CPU 用途
sleep() ❌ 不释放 ✅ 让出 暂停线程指定时间
wait() ✅ 释放 ✅ 让出 等待条件满足(需 synchronized
join() ❌ 不释放 ✅ 让出 等待目标线程结束
yield() ❌ 不释放 ✅ 让出 提示调度器让出 CPU(不保证)

📌 关键区别wait() 必须在同步块中调用,且会释放锁;sleep() 不影响锁状态。

3.2 synchronized vs volatile
特性 synchronized volatile
原子性 保证 不保证
可见性 保证 保证
有序性 保证(通过内存屏障) 保证(禁止指令重排)
作用范围 方法或代码块 变量
性能开销 高(阻塞、上下文切换)

使用建议

  • 保证原子性 + 可见性 → synchronizedReentrantLock
  • 仅需可见性 → volatile(如状态标志位)
3.3 线程池(ThreadPoolExecutor)
java 复制代码
new ThreadPoolExecutor(
    corePoolSize,      // 核心线程数
    maximumPoolSize,   // 最大线程数
    keepAliveTime,     // 空闲线程存活时间
    unit,              // 时间单位
    workQueue,         // 任务队列(BlockingQueue)
    threadFactory,     // 线程工厂
    handler            // 拒绝策略
);

任务执行流程

  1. 任务提交 → 若当前线程 < corePoolSize → 创建新线程
  2. 否则 → 加入 workQueue
  3. 队列满 → 若线程 < maxPoolSize → 创建新线程
  4. 否则 → 触发拒绝策略(如抛出异常、丢弃任务等)
    Android 推荐 :使用 Executors.newFixedThreadPool()newSingleThreadExecutor(),但更推荐 WorkManager 处理后台任务。

4. JVM 相关

4.1 JVM 核心作用
  • 实现"一次编写,到处运行"(跨平台)
  • 提供字节码执行引擎
  • 自动内存管理(GC)
  • 安全沙箱机制
  • 多线程支持
  • 动态类加载与链接
4.2 运行时数据区
区域 线程私有 存储内容 异常
程序计数器 私有 当前线程执行的字节码行号
虚拟机栈 私有 栈帧(局部变量、操作数栈、方法出口) StackOverflowError / OutOfMemoryError
本地方法栈 私有 Native 方法调用 同上
Java 堆 共享 对象实例、数组 OutOfMemoryError
方法区 共享 类信息、常量、静态变量 OutOfMemoryError

Android 注意:ART 虚拟机与 JVM 有差异,如预编译(AOT)、内存模型优化等。

5. 泛型与反射

5.1 泛型
  • 编译期检查 :提供类型安全,避免运行时 ClassCastException
  • 类型擦除 :泛型信息在编译后被擦除,仅保留原始类型(Object
  • 通配符? extends T(上界)、? super T(下界)、?(无界)

局限 :不能用于 static 字段、不能 new T()、不能用于异常类型。

5.2 反射
  • 用途:运行时获取类信息、动态调用方法、修改字段
  • 性能 :较慢(需解析字节码),建议缓存 Method/Field 对象
  • 与泛型结合 :可通过 getGenericReturnType() 获取泛型类型信息,部分突破类型擦除限制

应用场景:依赖注入(Dagger)、序列化(Gson)、ORM 框架(Room)

6. 类加载机制

双亲委派模型(Parent Delegation)
text 复制代码
        Bootstrap ClassLoader
               ↑
        Extension ClassLoader
               ↑
    Application ClassLoader
               ↑
   Custom ClassLoader (e.g., Tinker)
  • 流程:子加载器收到类加载请求 → 委托父加载器 → 父加载器无法加载 → 子加载器尝试加载
  • 优势
    • 安全性 :防止核心类(如 java.lang.String)被恶意替换
    • 避免重复加载:保证类的唯一性
    • 一致性:同一类由同一加载器加载

打破双亲委派 :JDBC 使用 Thread.currentThread().getContextClassLoader() 加载驱动,由应用类加载器完成。

二、Android 核心组件与机制

1. 四大组件

1.1 Activity

生命周期详解

生命周期 触发场景 注意事项
onCreate() 首次创建 初始化数据、绑定布局
onStart() 可见但不可交互 准备 UI 显示
onResume() 可交互(前台) 恢复动画、传感器
onPause() 失去焦点 保存数据、释放资源
onStop() 完全不可见 释放 UI 相关资源
onDestroy() 销毁前 彻底清理
onRestart() onStop 回到前台

典型场景

  • A → B(普通):A.onPause()B.onCreate()B.onResume()A.onStop()
  • A → B(透明):A.onPause()B.onCreate()B.onResume()(A 不会 onStop()

Activity Result API

  • 替代已废弃的 startActivityForResult()
  • 更安全:避免内存泄漏,支持 Fragment
  • 使用 ActivityResultLauncher 注册回调
kotlin 复制代码
val launcher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
    // 处理返回结果
}
launcher.launch("image/*")
1.2 Service
类型 启动方式 生命周期 适用场景
Started Service startService() onCreate()onStartCommand()onDestroy() 长时间后台任务(下载、播放)
Bound Service bindService() onCreate()onBind()onUnbind()onDestroy() 客户端-服务端通信
IntentService startService() 基于 HandlerThread,任务完成自动停止 串行执行后台任务(已废弃,推荐 WorkManager
前台服务 startForegroundService() 必须调用 startForeground() 长期运行任务(音乐播放、定位)

注意 :Android 9+ 需在 AndroidManifest.xml 中声明 FOREGROUND_SERVICE 权限。

1.3 BroadcastReceiver
注册方式 优点 缺点 适用场景
静态注册 应用未启动也可接收 耗电、占用系统资源 开机启动、网络状态变化
动态注册 灵活、可控制生命周期 需手动注销,否则内存泄漏 活动期间监听事件

最佳实践

  • 动态注册必须在 onDestroy() 中调用 unregisterReceiver()
  • onReceive() 中禁止耗时操作(>10s 导致 ANR)
  • 使用 LocalBroadcastManager 实现应用内通信(AndroidX 已废弃,推荐 LiveDataFlow
1.4 ContentProvider

核心组件

  • URIcontent://authority/path/id
  • ContentResolver:客户端访问接口
  • MIME 类型 :标识数据类型(如 vnd.android.cursor.dir/user

权限控制

  • android:readPermission / android:writePermission
  • android:exported="false":仅限本应用访问

系统示例

  • 联系人:content://com.android.contacts/contacts
  • 相册:content://media/external/images/media

2. View 体系与事件分发

事件分发三要素

  • dispatchTouchEvent():分发事件
  • onInterceptTouchEvent():ViewGroup 拦截判断
  • onTouchEvent():处理事件

滑动冲突解决

  • 外部拦截法 :父容器在 onInterceptTouchEvent() 中判断是否拦截
  • 内部拦截法 :子 View 调用 requestDisallowInterceptTouchEvent(true) 请求不被拦截

3. RecyclerView 与缓存机制

四级缓存

  1. Scrap:屏幕内临时移除的 ViewHolder(可快速复用)
  2. mCachedViews:最近移出屏幕的 ViewHolder(默认 2 个)
  3. ViewCacheExtension:开发者自定义缓存(极少使用)
  4. RecycledViewPool:被废弃的 ViewHolder 池(可跨 RecyclerView 共享)

性能优化

  • 使用 DiffUtil 计算最小更新集
  • 设置 setHasFixedSize(true) 若尺寸不变
  • 避免在 onBindViewHolder 中执行耗时操作

4. Handler 机制与内存泄漏

核心流程

text 复制代码
Handler.send → MessageQueue.enqueue → Looper.loop → Handler.dispatch → handleMessage()

内存泄漏防护

  • 使用静态内部类 + WeakReference<Activity>
  • onDestroy() 中调用 handler.removeCallbacksAndMessages(null)
  • 使用 Lifecycle 感知组件(如 LifecycleCoroutineScope

三、性能优化(补充详细方案)

1. 内存优化

  • LeakCanary:自动检测内存泄漏
  • Bitmap 复用 :使用 inBitmap(API 19+)
  • 对象池SparseArrayPools.SynchronizedPool

2. 布局优化

  • 使用 ConstraintLayout 减少嵌套
  • <merge> 消除冗余父布局
  • <ViewStub> 延迟加载非关键视图

3. 卡顿优化

  • Systrace 分析主线程阻塞
  • 使用 Choreographer 监控帧率
  • 避免在 onDraw() 中创建对象

4. 启动优化

  • 异步初始化:第三方 SDK 异步加载
  • 延迟初始化:非关键组件延后
  • ContentProvider 初始化 :避免在 onCreate() 中做耗时操作

5. APK 瘦身

方法 工具/配置
代码压缩 minifyEnabled true + R8
资源压缩 shrinkResources true
图片优化 WebP、矢量图、APK 字典
So 库分包 abiFilters

四、架构与设计模式(补充 MVVM 实践)

MVVM + Jetpack 推荐架构

text 复制代码
View (Activity/Fragment)
  ↓ (UI Events)
ViewModel
  ↓ (Data Request)
Repository → Local (Room) / Remote (Retrofit)
  ↑
LiveData / Flow

优势:生命周期安全、数据驱动、易于测试。

五、开源框架原理(补充)

框架 核心原理
Retrofit 动态代理 + 注解处理器生成 ServiceMethod
OkHttp 拦截器链(Retry、Bridge、Cache、Connect、CallServer)
Glide 四级缓存(内存、磁盘、活动资源、变换缓存)+ 生命周期感知
EventBus 注解生成索引,通过 HandlerPoster 发送事件

六、新技术趋势

  • Jetpack Compose:声明式 UI,取代 XML
  • Kotlin 协程 :替代 AsyncTaskRxJava
  • 跨平台:Flutter(Dart)、React Native(JS)、KMM(Kotlin Multiplatform)

七、场景题与开放性问题(补充回答模板)

"请介绍最有挑战的项目"

使用 STAR 法则

  • Situation:项目背景
  • Task:你的职责
  • Action:采取的技术方案
  • Result:量化成果(性能提升 X%)

总结:本文覆盖 Android 开发全栈知识,建议结合源码(AOSP、Jetpack)、实战项目与持续学习,构建可落地的技术能力。

下一步建议

  • 将本文作为知识地图,逐项深入
  • 阅读官方文档与源码
  • 参与开源项目或技术社区
相关推荐
专注前端30年6 小时前
2025 最新 Vue2/Vue3 高频面试题(10月最新版)
前端·javascript·vue.js·面试
一棵树73516 小时前
Android OpenGL ES初窥
android·大数据·elasticsearch
初级代码游戏6 小时前
MAUI劝退:安卓实体机测试
android
奔跑中的蜗牛6667 小时前
直播APP跨平台架构实践(二):KMP UI 与 Rust 下载引擎协作实践
android
沐怡旸7 小时前
【底层机制】【Android】AIDL原理与实现机制详解
android·面试
小仙女喂得猪7 小时前
2025 跨平台方案KMP,Flutter,RN之间的一些对比
android·前端·kotlin
沐怡旸7 小时前
【穿越Effective C++】条款4:确定对象使用前已先被初始化——C++资源管理的基石
c++·面试
2501_915106327 小时前
iOS 混淆与 IPA 加固全流程,多工具组合实现无源码混淆、源码防护与可审计流水线(iOS 混淆|IPA 加固|无源码加固|App 防反编译)
android·ios·小程序·https·uni-app·iphone·webview
游戏开发爱好者87 小时前
用多工具组合把 iOS 混淆做成可复用的工程能力(iOS混淆 IPA加固 无源码混淆 Ipa Guard)
android·ios·小程序·https·uni-app·iphone·webview