CODE
[TOC]
Android部分
主流框架
- EnventBus
- Butterknife
- Retrofit
- Glide
- Drager2
- LeakCanary
- 通过Application注册activity的监听destory, 把destory的Activity存到弱引用中,弱应用会传入一个queue, 主动调用gc,查看弱引用对象是否释放,释放的话会加入queue, 未加入queue就是未释放就是泄漏了,dump 内存快照,然后解析内存快照展示。
- 通过Application注册activity的监听onCreate, 通过FragmentManager注册Fragment监听,把destory的fragment存到弱引用中,主动调用gc,查看弱引用对象是否释放, 未释放就是泄漏了,dump 内存快照,然后解析内存快照展示。
- 可以监听Activity和Fragment但是无法监听io, 游标,Bitmap
Apk瘦身
- so文件
- 资源文件lint,混淆,图片压缩
- 代码混淆,压缩, R文件内联,access优化。
组件化
- 基于scheme, 仅限于Activity
- 基于接口,必须依赖commonlib
- 基于uri路由,无需修改commonlib,但是代码逻辑关联性差
插件化
- 基于代理实现,类加载,资源访问,Activity注册检查
- hook系统代码,Instrumentation, ActivityThread
- Dex合成,热修复思想
Android源码
-
手势分发
-
Activity及Application初始化
-
生命周期 https://mp.weixin.qq.com/s/KibDQpDbQ32yTykEIzKpPQ
-
Activity启动流程
context.startActivity()->
Instrumentation.execStartActivity->
AMS.startActivity()(跨进程)->
PMS.resoleActivity() (匹配需要打来Activity,多个的话弹窗选择后打开)->
resoleActivity会检测AppLink链接。
AMS.grantUriPermissionLocked (检查有没有权限)->
AMS.查询ProcessRecord是否存在->
不存在的话,AMS.startProcessLocked() 卵化该进程->
实例化ActivityThread,执行main方法,初始化ActivityThread,初始化Looper,初始化Application->
ActivityThread.performLaunchActivity(onCreate)->
Instrumentation.newActivity->
反射newActivity, attachBaseContext();
实例化PhoneWindow, 关联WindowManager;
ActivityThread.handleResumeActivity() ->
windowmanagerglobal.addView(decorview); 在此初始化ViewRootImpl, 关联view.
ViewRootImpl和Choreographer关联 ->
Choreographer和SurfaceFinger关联,监听vsync事件->
收到vsync后,先插一个消息屏障,保证先执行doFrame(), 开始执行移除屏障,回调ViewRootImpl的执行遍历->
mesure->
layout->
draw->
生成DisplayList传递给RenderThread->
渲染线程渲染生成FrameBuffer传递给SurfaceFinger->
SurfaceFinger合并Frame,交给硬件渲染。
里边有个三级缓存,最大限度的保证不掉帧。 -
AMS
-
管理Activity, 通过Binder与系统通讯, 7.0之前之前通过代理与系统通讯,8.0之后通过binder与系统通讯。
-
AMS中主要涉及这三个数据结构:
ActivityRecord、TaskRecord和ActivityStack
ActivityRecord:存储Activity的相关信息,比如AndroidMainifes的节点信息,启动Activity的包名,所在进程,图标主题标识符,当前Activity状态,所属TaskRecord等。
TaskRecord:描述一个Activity任务栈,主要维护了一个按历史顺序排列的ArrayList,并包含此任务栈所属的ActivityStack等。
ActivityStack:一个管理系统中所有Activity的管理类,真实交由ActivityStackSupervisor管理,内部维护了Activity的所有状态,并对不同状态的Activity进行分类管理,如最近启动的Activity,正在暂停的Activity等。 -
PMS
-
应用管理服务,管理安装,卸载,查找程序,解析intent, 配置Activity.
-
WMS
-
窗口管理服务,统一管理视图窗口。WindowManager 和 WindowManagerService的交互是一个 IPC 过程。https://blog.csdn.net/liujian8654562/article/details/81874942
-
任务栈回退栈
-
https://www.jianshu.com/p/94816e52cd77
-
https://developer.android.com/guide/components/activities/tasks-and-back-stack?hl=zh-cn
-
ViewRootImpl, View.invalite requestLayout
-
Handler
-
Choreographer
-
SurfingFlinger
-
MainThread RenderThread
-
AsynTask
-
Binder通讯 https://www.jianshu.com/p/429a1ff3560c
-
MVVM
-
Hook
-
Android线程通讯方式 共享内存 handler java管道
-
RecyclerView优化点
-
RecyclerView四级缓存
mAttachedScrap、mCachedViews、mViewCacheExtension、mRecyclerPool
- 不要在onbind逻辑处理复杂逻辑
- RecyclerView嵌套横向RecyclerView设置RecyclerPool缓存
- 减少嵌套
- 尽量使用局部刷新
- DiffUtil
- prefetch
- okhttp,连接池,拦截器责任链
- 性能相关的有内存,cpu,卡顿,启动速度等,怎么做的
https://testerhome.com/articles/17101 - aop的框架,apt、aspectj、asm,Javassist
- Hook https://www.jianshu.com/p/4f6d20076922
- requestlayout
- recyclerview实现类似抖音的上下滑,缓存池的设计等等
- Arraymap
- Serializable Parcelable
- Jvm内存模型 https://www.jianshu.com/p/a448fba00aa0
- 链表环的问题 https://www.cnblogs.com/xudong-bupt/p/3667729.html
- LeakCanary 原理
Java
- gc
分代,标记清除,拷贝算法,标记压缩(先标记,再整理一端,再清除)
线程可达性分析 - 常量池 https://cloud.tencent.com/developer/article/1450501
- 字符串池
- java类加载
- 线程池
- ClassLoader
- volatile
- LeakCanary 原理
- synchronized 原理 https://www.jianshu.com/p/e62fa839aa41
- happen before JVM虚拟机规则,无论怎么优化这些规则不能改变。
- 单线程happen-before原则:在同一个线程中,书写在前面的操作happen-before后面的操作。
- 锁的happen-before原则:同一个锁的unlock操作happen-before此锁的lock操作。
- volatile的happen-before原则:对一个volatile变量的写操作happen-before对此变量的任意操作(当然也包括写操作了)。
- happen-before的传递性原则:如果A操作 happen-before B操作,B操作happen-before C操作,那么A操作happen-before C操作。
- 线程启动的happen-before原则:同一个线程的start方法happen-before此线程的其它方法。
- 线程中断的happen-before原则:对线程interrupt方法的调用happen-before被中断线程的检测到中断发送的代码。
- 线程终结的happen-before原则:线程中的所有操作都happen-before线程的终止检测。
- 对象创建的happen-before原则:一个对象的初始化完成先于他的finalize方法调用。
- Jvm内存模型 https://www.jianshu.com/p/a448fba00aa0
- Serializable Parcelable
- synchronized 原理 https://www.jianshu.com/p/e62fa839aa41
网络
-
分层
- HTTP 应用层,无状态有连接。
- TCP UDP 传输层, TCP面向连接,稳定可靠,效率低, UDP非连接,不可靠,容易丢包,但是速度快。
- IP 网络层, 非连接
-
HTTP请求流程
- DNS域名解析器解析获取IP
- TCP/IP协议与服务端建立连接
- 连接-三次握手, 请求服务端能收到吗,服务端收到后回传客户端能收到吗,客户端回答服务能收到
- 客户端发送服务器数据
- TCP/IP与服务器断开连接
- 断开-四期挥手, 请求服务断开连接,服务器回复收到但是还没后发送完数据,服务器回复发送完数据,客户端断开连接
-
HTTP报文
-
请求报文
- 请求行 HTTP版本 请求方式 GET POST 请求PATH
- 请求头 host cocckies agent客户端新 accept 接收文件 acceptType 接收文件类型 接受文件大小
- 请求body POST body
-
响应报文
- 响应行 HTTP版本 状态码 200-299成功 300-399重定向 400-499客户端错误 500-599服务端错误
- 响应头 Content-Length Date LastModify Content-type setCoockies
- 响应数据 返回JSON或者HMTL
-
-
HTTPS请求 HTTP+SSL安全层
需要两次HTTP请求。- 第一次连接服务端回传证书和公钥,客户端用手机预装的证书校验服务器证书,校验失败,断开连接,校验成功,随机生成一个对称加密的秘钥。 用服务端下发的公钥进行非对称加密。
- 第二次连接把客户端加密后的秘钥,发送给服务端,服务端用自己的私钥解密获取客户端对称秘钥。用客户端秘钥加密返回数据,客户端收到数据后用自己的秘钥进行解密。
-
HTTP HTTPS端口不同,443,HTTPS需要向CA申请证书。
经典源码
设计模式
性能优化
-
启动速度
- 老生常谈,过度绘制,层级嵌套,动态加载布局,减少解析xml, xml异步解析
- 异步初始化非必要Sdk
- 延迟广播,Service的初始化
- 延迟子进程初始化
- 监听predraw方法,绘制之前能不做就不要做,先保证界面可见
- 后台时截图,冷启动时,提前设置上
- 混淆,压缩png后转webp
- [探索性] redex facebook, 把相互引用类归类到同一个dex,插桩有坑!
-
内存优化
- 先解决一波内存泄漏,再抓heap分析下大内存对象。
- 内存抖动严重,回收慢,替换图片加载框架Glide
- 进一步优化RecyclerView图片缓存逻辑。可以节省两个Item的视图内存。
Flutter
- 编程思想不同
- 强调组合而不是继承,提供很细粒度的Wegit
- 响应式编程,数据改变时,直接setState重建wegit,然后framework diff, 决定是否需要刷新界面。
- 支持热部署
- 万物皆是wegit
- 疑惑
- 业务逻辑也在Wegit里边
- Wegit层级会很深,看着很难看
- release版本不支持热部署
算法
-
快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值
-
中序遍历,倒序,正序
-
字符串回文
-
字符串转数字
-
二叉树深度 宽度
-
链表合并 反转 相交
-
链表环的问题 https://www.cnblogs.com/xudong-bupt/p/3667729.html
-
行列有序数据查找对应值 https://blog.csdn.net/wennfengg/article/details/9156135
-
让实现一个编译任务 a依赖b, c, b依赖d, c依赖e,按照依赖打印任务,d b e c a输出。 这个递归还是比较简单
-
求数组第k大的数,不允许破坏原数组顺序,空间复杂度不能为n, (不允许直接复制个新数组)。
当时我快速给了快速排序当锚点数据 离最大值长度为k值直接返回。但是改变原数据顺序了,后又提出先复制, 当时我比较紧张没想到,减少空间复杂度的办法。 后来想转换下思路,其实就是top的问题。构建个容量k的小根堆,遍历完成后,直接输出堆顶的值就行了