LRUCache 原理
LruCache 中维护了一个集合 LinkedHashMap, 该 LinkedHashMap 是以访问顺序 (accessOrder 为 true, 其余非构造函数此值全为 false) 排序的当调用 put()方法时, 就会在集合中添加元素, 并调用 trimToSize()判断缓存是否已满, 如果满了就用 LinkedHashMap 的迭代器删除队尾元素, 即近期最少访问的元素当调用 get()方法访问缓存对象时, 就会调用 LinkedHashMap 的 get()方法获得对应集合元素, 同时会更新该元素到队头
LinkedHashMap 内部是使用双向循环链表来存储数据的也就是每一个元素都持有他上一个元素的地址和下一个元素的地址
图片加载原理(Glide)
这篇文章对几大开源图片加载库做了对比 Android 三大图片缓存原理特性对比
个人使用过 ImageLoader 和 Glide, 相对而言对 Glide 较为熟悉对 Glide 这个点可以稍作分析, 如何感知 activity 或者 Fragment 生命周期的: - 往 Activity 或者 Fragment 内部添加一个
SupportRequestManagerFragment
透明的 Fragment, 用回调的方式感知生命周期
模块化的好处
模块化的好处以及原因
JVM
JVM 的工作原理
总结的 JVM 面试题
视频加密传输
加密:
DES 对整个视频文件进行加密, 但耗时较长
将视频数据流前 n 个字节 (n>=2) 打乱即可达到加密目的, 使用到了内存映射文件 (对 RandomAccessFile 和 MappedByteBuffer 的使用) 参考这篇文章
数据加密传输:
android 上数据加密传输比较麻烦, 得不偿失综合阅读过的几篇文章, 觉得还是先加密再传输来得好
统计启动时长, 标准
参考文章
app 冷启动的流程如下:
-> Application 构造函数
- -> Application.attachBaseContext()
- -> Application.onCreate()
-> Activity 构造函数
- -> Activity.setTheme()
- -> Activity.onCreate()
- -> Activity.onStart
- -> Activity.onResume
- -> Activity.onAttachedToWindow
- -> Activity.onWindowFocusChanged
如何保持应用的稳定性
经验之谈: 性能分析, 内存监测, Monkey
ThreadLocal
用处: 针对线程操作对象, 其余线程不能进行操作
原理: ThreadLocal 的操作都是针对当前线程持有的一个 ThreadLocalMap 对象, 其内部维护了一个 Entry[](弱引用)数组所以不同线程操作同一个 ThreadLocal 对象, 内部说白了都是操作各个线程自己的 ThreadLocalMap 对象而已
谈谈 classloader
主观性比较强, 谈一下自己了解的即可可参考 classloader 使用与原理分析
动态布局
代码写布局, 无他唯手熟尔
一篇干货分享一下
热修复, 插件化
主观性较强, 视个人了解程度而区分参考
HashMap 源码, SparseArray 原理
HashMap 实现原理
简洁对比 HashMap 和 SparseArray
应用启动优化
参考 Android 性能优化
视觉优化, 启动界面设置为特殊样式
异步初始化组件;
梳理业务逻辑, 延迟初始化组件操作;
正确使用线程;
去掉无用代码重复逻辑等;
怎么去除重复代码
抽取成方法, 抽取成对象, 抽取成 Module;
不要过度设计, 及时重构, 代码要经常回顾;
SP 是进程同步的吗? 有什么方法做到同步
能同步但不建议使用, 使用 ContentProvider 可以做到同步 ContentProvider 多进程共享 SP 数据
SurfaceView 介绍
View 适用于主动更新的情况, 而 SurfaceView 则适用于被动更新的情况, 比如频繁刷新界面
View 在主线程中对页面进行刷新, 而 SurfaceView 则开启一个子线程来对页面进行刷新
View 在绘图时没有实现双缓冲机制, SurfaceView 在底层机制中就实现了双缓冲机制
HashMap 实现原理, ConcurrentHashMap 的实现原理
参考此篇文章
BroadcastReceiver,LocalBroadcastReceiver 区别
应用场景
BroadcastReceiver 用于应用之间的传递消息;
而 LocalBroadcastManager 用于应用内部传递消息, 比 broadcastReceiver 更加高效
安全
BroadcastReceiver 使用的 Content API, 所以本质上它是跨应用的, 所以在使用它时必须要考虑到不要被别的应用滥用
LocalBroadcastManager 不需要考虑安全问题, 因为它只在应用内部有效
BundleHandler 事件传递机制, 都是基础
线程间操作 List
App 启动流程, 从点击桌面开始
这一篇文章总结的好一点, App 启动流程
动态加载(插件化技术)
主观性较强, 视个人经历的项目而定个人觉得如果简单介绍的话, 这篇文章会好一点清晰简洁动态加载简单易懂的介绍方式
GC 回收机制
新生代和旧生代采用不同的垃圾回收机制
可参考 Java 垃圾回收机制
画出 Android 大体架构图
经典图
点击 Android Studio 的 build 按钮后发生了什么
Android 使用 gradle 构建生成的 apk 关键就是 aapt 处理资源文件, aidl 处理. aidl,javac 生成. class 文件, proguard 混淆后再由 dex 生成. dex 文件, 由 apkbuilder 签名后再经 zipalign 对齐字节码就可以上线发布了
这篇文章分析的较为详细, AS 的 build 做了什么
一个应用程序安装到手机上时发生了什么
安装和卸载都是通过 PackageManager, 实质上是实现了 PackageManager 的远程服务 PackageManagerService 来完成具体的操作, 所有细节和逻辑均可以在 PackageManagerService 中跟踪查看;
所有安装方式殊途同归, 最终就回到 PackageManagerService 中, 然后调用底层本地代码的 installd 来完成再看 apk 的安装过程
拷贝 apk 文件到指定目录
解压 apk, 拷贝文件, 创建应用的数据目录
解析 apk 的 AndroidManifinest.xml 文件
向 Launcher 应用申请添加创建快捷方式
深入探究 apk 安装过程
对 DalvikART 虚拟机有基本的了解
Dalvik 虚拟机执行的是 dex 字节码, ART 虚拟机执行的是本地机器码
可参考这篇文章 JAVA 虚拟机 Dalvik 虚拟机和 ART 虚拟机简要对比
Android 上的 Inter-Process-Communication 跨进程通信时如何工作的
跨进程通信主要靠 Binder 详解 Binder
Android 中 App 是如何沙箱化的, 为何要这么做
Android 中的沙箱化可以提升系统安全性和效率
权限管理系统
Android 权限机制
进程以及 Application 生命周期
进程生命周期
有关 Application
Recyclerview 和 ListView 对比
相信目前大部分 Android 开发已经舍弃了 ListView 而转向 Recyclerview 的怀抱了吧, 无需赘言
快速排序以及 B + 树, 算法算是我比较薄弱的环节, 不敢多言
TCP 和 UDP 的区别
TCP 是面向连接的协议, 提供稳定的双向通信功能, 本身提供超时重连机制 UDP 是无连接的, 提供不稳定的单向通信功能
synchronized 与 Lock 的区别
从用法性能用途来分析, 很不错深入研究 Java Synchronize 和 Lock 的区别与用法
volatile
排他锁, 保证了所有线程看到的变量都是一致的
Java 线程池
java 对象生命周期
经典图例
双亲委派模型
老油条式面试题, 这篇文章有一个比较新颖的疑问解答关于 Java 类加载双亲委派机制的思考(附一道面试题)
Android 事件分发机制
基础的基础
MVP 模式
组件和业务逻辑相互分离, 两不相知 Google 提供的 Demo 里, View 层级真是纯是 view 操作, 包括 Listener 的一部分都由 Presenter 承担了
接口定义清晰明朗
视个人项目经历而谈, 详细了解就仔细说, 不太懂就说个大概
RxJava
开发神器, 错误处理线程调度写出来的代码优雅
可从线程调度以及源码角度剖析剖析
抽象类和接口的区别
属性和行为的区别
Android 消息机制
进程调度
进程与线程
进程有独立的地址空间, 一个进程崩溃后, 在保护模式下不会对其它进程产生影响, 而线程只是一个进程中的不同执行路径线程有自己的堆栈和局部变量, 但线程之间没有单独的地址空间, 一个线程死掉就等于整个进程死掉, 所以多进程的程序要比多线程的程序健壮, 但在进程切换时, 耗费资源较大, 效率要差一些
另外, 进程在执行过程中拥有独立的内存单元, 而多个线程共享内存, 从而极大地提高了程序的运行效率
死锁
老问题, Java 实例 - 死锁及解决方法
进程状态
图
JVM 内存模型
Java 常用并发集合有哪些
非阻塞式列表对应的实现类: ConcurrentLinkedDeque
阻塞式列表对应的实现类: LinkedBlockingDeque
用于数据生成或者消费的阻塞式列表对应的实现类: LinkedTransferQueue
按优先级排序列表元素的阻塞式列表对应的实现类: PriorityBlockingQueue
带有延迟列表元素的阻塞式列表对应的实现类: DelayQueue
非阻塞式列表可遍历映射对应的饿实现类: ConcurrentSkipListMap
随机数字对应的实现类: ThreadLockRandom
原子变量对应的实现类: AtomicLong 和 AtomicIntegerArray
ConcurrentHashMap 的实现原理
Java 线程 run 和 start 方式的区别
常见的数据结构
如图
堆排序实现
链表反转
synchronized 用法
写的较为详细, 最后的总结面试时可以直接拿来用 Java 中 Synchronized 的用法
OkHttp 是如何处理缓存的
OkHttp 缓存处理
OkHttp 还是使用的 Http 缓存, 需要后台配合当然也可以单纯的在客户端作拦截处理
bitmap 如何处理大图, 如何预防 OOM
老生常谈的问题, 彻底了解 bitmap 高效加载
进程保活
黑科技保活
listview 图片加载错乱的原理和解决方案
郭霖大神的解析, 拳拳到肉 ListView 异步加载图片乱序问题, 原因分析及解决方案
广播小结
service 生命周期
多线程
用 RxJava 的话会方便很多 RxJava 中的多线程, 这篇文章真的太赞了
AsyncTask 缺陷, 一部分是使用不当, 一部分是其本身存在的缺陷网上的大部分文章都是看了一遍其实都是使用的问题, 推荐看看这篇详细解读 AsyncTask 的黑暗面以及一种替代方案 By,AsyncTask 真的很难用, 因为要注意的地方太多了
数据库数据迁移, 把大象装进新冰箱共分几步?
将表名改成临时表
ALTER TABLE Order RENAME TO _Order
创建新表
CREATETABLE Test(Id VARCHAR(32) PRIMARY KEY ,CustomName VARCHAR(32) NOTNULL , Country VARCHAR(16) NOTNULL)
导入数据
INSERTINTO Order SELECT id, , Age FROM _Order
删除临时表 DROPTABLE _Order
设计模式
自由发挥题目但亦有文章可以参考, 这是一个有关 Android 中常见设计模式解析的一个专栏, 推荐指数五颗星 Android 常见设计模式
Java 注解
EventBusRetrofit 等都用到了注解是一个很强大的东西, 关键是代码写起来敲好看深入理解 Java 注解类型(@Annotation)
Android 优化
自由度很高的问题, 随意发挥参考这个优化系列的文章 Android 性能优化的方方面面
EventBus 实现原理
相比起来, 还是更喜欢 RxJava 自己实现一套 RxbusEventBus 3.0 源码分析
来源: https://juejin.im/entry/5aa69dc851882555602093b2