Android开发经验谈Android开发

最新 Android 面试点梳理,你收藏了嘛?

2020-06-14  本文已影响0人  Android进阶架构

目录:

不要着急划走,文末有彩蛋哦

网络:分层模型、TCP、UDP、HTTP、HTTPS

分层模型

UDP

TCP

1.  C->S:SYN,seq=x(你能听到吗?)
2.  S->C:SYN,seq=y,ack=x+1(我能听到,你能听到吗?)
3.  C->S:ACK,seq=x+1,ack=y+1(我能听到,开始吧)

两方都要能确保:我说的话,你能听到;你说的话,我能听到。所以需要三次握手
1.  C->S:FIN,seq=p(我说完了)
2.  S->C:ACK,ack=p+1(我知道了,等一下,我可能还没说完) 3.  S->C:FIN,seq=q,ACK,ack=p+1(我也说完了) 
4.  C->S:ACK,ack=q+1(我知道了,结束吧) 

S 收到 C 结束的消息后 S 可能还没说完,没法立即回复结束标示,只能等说完后再告诉 C :我说完了

HTTP

HTTPS

算法:数据结构、常用算法

数据结构

常用算法

Java 基础:StringBuilder、泛型擦除、Exception、IO、容器

StringBuilder

泛型擦除

Exception 和 Error

IO 、 NIO、 OKIO

ArrayList、LinkedList
1.ArrayList

2.LinkedList

HashMap 、HashTable、HashSet

1.HashMap(允许 key/value 为 null)

2.HashTable(不允许 key/value 为 null)

  1. HashSet

ArrayMap、SparseArray

1.ArrayMap

  1. SparseArray
    • 基于 ArrayMap,key 只能是特定类型

Concurrent 集合

  1. ConcurrentHashMap
    • 数据结构跟 HashMap 一样,还是数组加链表
    • 采用 segment 分段锁技术,不像 HashTable 无脑直接同步 put 和 get 操作
    • get 操作没有加锁,因为 value 用 volatile 修饰来保证可见行,性能很高
    • java1.8 后去除分段锁,采用 CAS 乐观锁加 synchronized 来实现

LRUCache 原理
- 基于访问顺序排序的 LinkedHashMap 实现,最近访问的会排在最后

Java 同步:volatile、wait、synchronized、可重入锁、乐观锁、死锁 volatile 关键字

  1. 只能用来修饰变量,适用修饰可能被多线程同时访问的变量
  2. 相当于轻量级的 synchronized,volatitle 能保证有序性(禁用指令重排序)、可见性
  3. 变量位于主内存中,每个线程还有自己的工作内存,变量在自己线程的工作内存中有份拷贝,线程直接操作的是这个拷贝
  4. 被 volatile 修饰的变量改变后会立即同步到主内存,保持变量的可见性
  5. 双重检查单例,为什么要加 violate?
    • volatile想要解决的问题是,在另一个线程中想要使用instance,发现instance!=null,但是实际上instance还未初始化完毕这个问题。将instance = newInstance();拆分为3句话是。1.分配内存2.初始化3.将instance指向分配的内存空间,volatile可以禁止指令重排序,确保先执行2,后执行3

wait 和 sleep

wait、notify、notifyAll

lock 和 synchronized

Synchronized 原理

可重入锁

公平锁

乐观锁和悲观锁

死锁 4 个必要条件

Java 设计模式:六大原则、23 种设计模式、动态代理

六大原则

Java 23 种设计模式(按目的分类为:5+7+11)
1995 年 GoF(四人组)出了一本设计模式的书,收录了 23 种设计模式,树立设计模式里程碑,也叫:GoF 设计模式

动态代理原理及实现

JVM:内存模型、内存结构、GC、四种引用、ClassLoader

JVM

JVM 内存模型

JVM 内存结构

线程共享:
1.堆:存储 Java 实例,GC 主要区域,分代收集 GC 方法会吧堆划分为新生代、老年代
2.方法区:存储类信息,常量池,静态变量等数据

GC
- 回收区域:只针对堆、方法区;线程私有区域数据会随线程结束销毁,不用回收
- 回收类型:

1.堆中的对象:分代收集 GC 方法会吧堆划分为新生代、老年代。 新生代:新建小对象会进入新生代;通过复制算法回收对象;老年代:新建大对象及老对象会进入老年代;通过标记-清除算法回收对象。
2.方法区中的类信息、常量池

  1. 引用计数法:有循环引用的缺点
  2. 可达性分析法:从 GC ROOT 开始搜索,不可达的对象都是可以被回收的。其中 GC ROOT 包括虚拟机栈/本地方法栈中引用的对象、方法区中常量/静态变量引用的对象。

Minor GC/Major GC/Full GC

1.Minor GC(Young GC):即新生代(分为一个 Eden 区和两个 Survivor 区)的垃圾回收

2.Major GC:通常是跟 Full GC 等价的,回收整个堆
3.Full GC:回收整个堆,包括新生代和老年代

四种引用

ClassLoader

  1. 当要加载一个 class 时,会先逐层向上让父加载器先加载,加载失败才会自己加载
  2. 为什么叫双亲?不考虑自定义加载器,系统类加载器需要网上询问两层,所以叫双亲
  3. 判断是否是同一个类时,除了类信息,还必须时同一个类加载器
  4. 优点:防止重复加载,父加载器加载过了就没必要加载了;安全,防止篡改核心库类

Android 基础:Activity、View 绘制、动画、Window、SurfaceView、事件分发

Activity 生命周期

Activity 启动模式

  1. taskAffinity:任务相关性,用于指定任务栈名称,默认为应用包名
  2. allowTaskReparenting:允许转移任务栈

View 工作原理

  1. ViewRoot 的 performTraversals 方法调用触发开始 View 的绘制,然后会依次调用:

MeasureSpec 测量规则

View 动画、帧动画及属性动画

  1. View 动画:

2.帧动画:

3.属性动画:

Window 、WindowManager、WMS、SurfaceFlinger

SurfaceView、TextureView、SurfaceTexture、GLSurfaceView

事件分发机制

Android 通信:Handler、Parcelable、IPC、Binder

Handler、MessageQueue、Looper 及 postDelayed 原理

Serializable、Parcelable

Linux IPC 方式

常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段

不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等(Android 中的 Kill Process 采用的就是 signal(信号)机制)

信息复制两次,额外的 CPU 消耗;不合适频繁或信息量大的通信

无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决

Binder

Android 为什么选择 binder

使用 mmap 一次数据拷贝实现 IPC,传统 IPC:用户 A 空间->内核->用户 B 空间;mmap 将内核与用户 B 空间映射,实现直接从用户 A 空间->用户B空间,而 Linux 的管道、消息队列、Socket 都需要拷贝两次,binder 仅次于共享内存

基于C/S架构,架构清晰,稳定性好,不像共享内存实现方式复杂,需要充分考虑访问临界资源的并发同步问题

传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份

Android IPC 方式

要求传递数据能被序列化,实现 Parcelable、Serializable ,适用于四大组件通信

适用于交换简单的数据实时性不高的场景

  1. Android Interface Definition Language,可实现跨进程调用方法
  2. 服务端:将暴漏给客户端的接口声明在 AIDL 文件中,创建 Service 实现 AIDL 接口并监听客户端连接请求
  3. 客户端:绑定服务端 Service ,绑定成功后拿到服务端 Binder 对象转为 AIDL 接口调用
  4. RemoteCallbackList 实现跨进程接口监听,同个 Binder 对象做 key 存储客户端注册的 listener
  5. 监听 Binder 断开:1.Binder.linkToDeath 设置死亡代理;2. onServiceDisconnected 回调

Android 系统:系统架构、Dalvik、ART、系统启动、类加载器、Apk 打包、Apk 安装

Android 系统架构

Dalvik 和 ART

1.Dalvik

2.ART

Android 系统启动流程

Android 类加载器

APK 打包流程

1.aapt 打包资源文件生成 R.java 文件;aidl 生成 java 文件
2.将 java 文件编译为 class 文件
3.将工程及第三方的 class 文件转换成 dex 文件
4.将 dex 文件、so、编译过的资源、原始资源等打包成 apk 文件
5.签名
6.资源文件对齐,减少运行时内存

App 安装过程

Android 优化:网络优化、卡顿优化、内存优化、瘦包、内存泄漏、ANR、Native Crash

网络优化及检测

UI卡顿优化

内存优化

1.内存问题

2.检测工具

瘦包

  1. 资源方面:资源在线化、图片使用 webp 格式、tint 着色生成不同色调的切、使用 icon font
  2. so 库:保留一个 cpu 架构的 so 文件
  3. AS Inspect Code 清除无用代码和资源
  4. 代码混淆:使用 ProGuard 可以移除无用的类、字段、方法(压缩),移除无用字节码指令
  5. 不保留行号:使用 ProGuard 配置不保留行号
  6. 开启 shrinkResources:移除无用资源
  7. 资源混淆:使用 AndResGuard 缩短资源长度,对资源进行 7z 压缩等(直接对apk操作)
  8. 代码结构简化,比如用 intdef 代替 枚举(一个枚举有1~1.4kb大小)
  9. 使用 compileOnly 在只需编译时依赖的场景,不会打到 apk 里
  10. 使用 thinR 插件剔除 R 文件,将引用 R 字段的地方替换成对应常量
  11. Android 7.0 使用 V2(apksigner) 代替 V1(jarsigner) 签名工具
  12. 动态加载 so 库(System.load加载绝对路径文件)、插件化技术、App Bundle
  13. 使用 facebook 的 redex

内存泄漏场景及规避

  1. 静态变量、单例强引跟生命周期相关的数据或资源,包括 EventBus
  2. 游标、IO 流等资源忘记主动释放
  3. 界面相关动画在界面销毁时及时暂停
  4. 内部类持有外部类引用导致的内存泄漏

ANR 问题及分析

  1. anr 分类

2.anr 发生过程

3.监控 anr

4.分析 anr

5.避免 anr

Native Crash

其他:解析 XML、进程保活、播放器、Lint、CI、CD、AOP、JetPack

Android 解析 XML

热修复、插件化、组件化

  1. 热修复原理:

2.插件化:DexClassLoader 动态加载,四大组件未注册问题通过 hook AMS、Instrumentation 等解决,VirtualAPK 源码分析

3.组件化:ARoute 路由实现:通过 APT 解析 @Route 等注解,结合 JavaPoet 生成路由表,即路由与 Activity 的映射关系

进程保活

播放器原理
1.视频播放原理:(mp4、flv)-> 解封装 -> (mp3/aac、h264/h265)-> 解码 -> (pcm、yuv)-> 音视频同步 -> 渲染播放

2.音视频同步:

选择参考时钟源:音频时间戳、视频时间戳和外部时间三者选择一个作为参考时钟源(一般选择音频,因为人对音频更敏感,ijk 默认也是音频)通过等待或丢帧将视频流与参考时钟源对齐,实现同步

3.IjkPlayer 原理

Lint

CI

AOP

JetPack
1.LiveData 感知声明周期原理:像 Glide 一样给界面添加了无视图的 Fragment
2.ViewModel 界面旋转短暂销毁重建时保存数据原理:

3.JetPack 与 MVVM:

下面是小编自己整理的近年来的所有面试题和Android架构资料等。获取方式看文末或者直接简信我【666】既可获取;

地址:

上一篇下一篇

猜你喜欢

热点阅读