[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瘦身

  1. so文件
  2. 资源文件lint,混淆,图片压缩
  3. 代码混淆,压缩, 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

  1. 不要在onbind逻辑处理复杂逻辑
  2. RecyclerView嵌套横向RecyclerView设置RecyclerPool缓存
  3. 减少嵌套
  4. 尽量使用局部刷新
  5. DiffUtil
  6. 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虚拟机规则,无论怎么优化这些规则不能改变。
  1. 单线程happen-before原则:在同一个线程中,书写在前面的操作happen-before后面的操作。
  2. 锁的happen-before原则:同一个锁的unlock操作happen-before此锁的lock操作。
  3. volatile的happen-before原则:对一个volatile变量的写操作happen-before对此变量的任意操作(当然也包括写操作了)。
  4. happen-before的传递性原则:如果A操作 happen-before B操作,B操作happen-before C操作,那么A操作happen-before C操作。
  5. 线程启动的happen-before原则:同一个线程的start方法happen-before此线程的其它方法。
  6. 线程中断的happen-before原则:对线程interrupt方法的调用happen-before被中断线程的检测到中断发送的代码。
  7. 线程终结的happen-before原则:线程中的所有操作都happen-before线程的终止检测。
  8. 对象创建的happen-before原则:一个对象的初始化完成先于他的finalize方法调用。
  • Jvm内存模型 https://www.jianshu.com/p/a448fba00aa0
  • Serializable Parcelable
  • synchronized 原理 https://www.jianshu.com/p/e62fa839aa41

网络

  • 分层

    1. HTTP 应用层,无状态有连接。
    2. TCP UDP 传输层, TCP面向连接,稳定可靠,效率低, UDP非连接,不可靠,容易丢包,但是速度快。
    3. IP 网络层, 非连接
  • HTTP请求流程

    • DNS域名解析器解析获取IP
    • TCP/IP协议与服务端建立连接
      • 连接-三次握手, 请求服务端能收到吗,服务端收到后回传客户端能收到吗,客户端回答服务能收到
    • 客户端发送服务器数据
    • TCP/IP与服务器断开连接
      • 断开-四期挥手, 请求服务断开连接,服务器回复收到但是还没后发送完数据,服务器回复发送完数据,客户端断开连接
  • HTTP报文

    • 请求报文

      1. 请求行 HTTP版本 请求方式 GET POST 请求PATH
      2. 请求头 host cocckies agent客户端新 accept 接收文件 acceptType 接收文件类型 接受文件大小
      3. 请求body POST body
    • 响应报文

      1. 响应行 HTTP版本 状态码 200-299成功 300-399重定向 400-499客户端错误 500-599服务端错误
      2. 响应头 Content-Length Date LastModify Content-type setCoockies
      3. 响应数据 返回JSON或者HMTL
  • HTTPS请求 HTTP+SSL安全层
    需要两次HTTP请求。

    1. 第一次连接服务端回传证书和公钥,客户端用手机预装的证书校验服务器证书,校验失败,断开连接,校验成功,随机生成一个对称加密的秘钥。 用服务端下发的公钥进行非对称加密。
    2. 第二次连接把客户端加密后的秘钥,发送给服务端,服务端用自己的私钥解密获取客户端对称秘钥。用客户端秘钥加密返回数据,客户端收到数据后用自己的秘钥进行解密。
  • HTTP HTTPS端口不同,443,HTTPS需要向CA申请证书。

经典源码

设计模式

性能优化

  • 启动速度

    1. 老生常谈,过度绘制,层级嵌套,动态加载布局,减少解析xml, xml异步解析
    2. 异步初始化非必要Sdk
    3. 延迟广播,Service的初始化
    4. 延迟子进程初始化
    5. 监听predraw方法,绘制之前能不做就不要做,先保证界面可见
    6. 后台时截图,冷启动时,提前设置上
    7. 混淆,压缩png后转webp
    8. [探索性] redex facebook, 把相互引用类归类到同一个dex,插桩有坑!
  • 内存优化

    1. 先解决一波内存泄漏,再抓heap分析下大内存对象。
    2. 内存抖动严重,回收慢,替换图片加载框架Glide
    3. 进一步优化RecyclerView图片缓存逻辑。可以节省两个Item的视图内存。

Flutter

  • 编程思想不同
  1. 强调组合而不是继承,提供很细粒度的Wegit
  2. 响应式编程,数据改变时,直接setState重建wegit,然后framework diff, 决定是否需要刷新界面。
  3. 支持热部署
  4. 万物皆是wegit
  • 疑惑
  1. 业务逻辑也在Wegit里边
  2. Wegit层级会很深,看着很难看
  3. 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的小根堆,遍历完成后,直接输出堆顶的值就行了