安卓八股文

默写以下八股文 ps:下述内容为我个人默写过程,简化版,不保证准确性,仅供参考

安卓四大组件是什么 1、activity 2、service 3、广播接收器 ❌ 4、内容提供者 ❌

重组? activity在第一次运行的时候生成一颗视图树,每次状态改变的时候和视图树中的节点进行对比,看看是否改变了,如果改变了则进行重组,重新测量和定位,最终进行渲染。

composable生命周期?

重组: 删除:

子线程能否更新UI?为什么 不能更新,安卓不保证线程池安全,多个线程会导致绘制混乱

xm和compose的区别? xml是命令式:通过命令驱动UI ❌ compose是声明式:通过状态来驱动UI更新

Activity的生命周期 onCreate():初始化 onStart():启动态,处在后台 onRessume():进行聚焦,在页面显示 onPause():暂停态,动画停止❌ onStop():停止态, ondestroy:销毁态,进行资源清理 onReStart():重启态

Fragment的生命周期 和Activity进行关联 创建视图:❌

销毁视图: 和Activity取消关联

谈谈Activity和Fragment的区别? 生命周期不同 Fragment切换时更流畅❌

ActivityA启动另一个ActivityB会调用哪些方法?如果B是透明主题的又或者是个DialogActivity呢?

ActivityA的pause()
然后调用ActivityB的create -> start -> ressume()
ActivityA的stop() ❌(stop应该在最后) 如果B是透明主题的又或者是个DialogActivity呢? 则不调用最后的stop()

什么是dp? 可以动态的根据屏幕密度计算像素值 px:像素单位 sp:字体样式,和dp类似 但是可以适配系统字体

谈一谈MVC、MVP、MVVM的理解? MVC:模型(负责数据)、视图(负责视图渲染)、控制器(负责业务逻辑的处理) MVP:MVC的变体,P指的是主持者,从模型中获取数据在视图中进行渲染 MVVM:数据和视图双向绑定

Activity和Fragment之间常见的几种通信方式? 1、实现接口 2、ViewModel 3、通过handler ❌

说下横竖屏下Activity的生命周期?❌ 如果不配置configchange pause->stop->destory->create->start->ressume

进程间通信的方式 正常的有:管道、共享内存、消息队列、信号量、信号、套接字、文件等 安卓中使用binder,核心是binder驱动实现数据共享和通信 每个进程都有自己的binder,当向其他进程进行通信时则获取其他进程的binder引用。 然后通过binder引用向对方发送信息,binder驱动会将信息传递给目标进程进行处理,然后通过binder驱动器返回结果。❌

线程间通信的方式?❌ 核心是通过handler,一个线程将消息发送到另一个线程的消息队列中 每个线程都有自己的looper和消息队列、handler 消息队列:存储信息 looper:不断循环从消息队列中获取信息,底层是epoll机制,然后分给对应的handler进行处理 handler:处理信息,放回目标线程的消息队列中

触摸事件传递过程:事件分发机制 从Activity->ViewGroup->View 从Activity开始,传递到ViewGroup,看看是否拦截,如果不拦截则接着往下传递 最终传递到view,如果仍然未消费的话则回溯。viewGroup是否消费,Activity是否消费。

安卓中一个电机事件点击结束后是怎么被销毁的? 事件分发机制中被消费掉

looper最多能开几个线程? 1个,一个looper对应一个线程和一个messageQueue

handler的一个postDelay()方法知道吗? 用于延迟消费,设置消息的消费时间,到点则让looper取出来进行消费

如果创建了两个handler,如何知道哪个消息对应那个handler? 每个消息都会有自己绑定的handler

上下滑动事件和左右滑动事件的冲突如何处理? 在事件分发机制中的拦截器可以处理

recycleView了解吗?他是如何复用视图的?❌ 通过四级缓存? 一级缓存页面可见的 二级缓存页面可见范围附近的 三级缓存用户自定义的 四级缓存

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
狂feng
作者分享
人以伪来 我以诚往
1
复习第十五天 Java 中 volatile 关键字的作用是什么? 可见性,禁止指令重排序 可见性:读主内存 禁止指令重排序:内存屏障,读屏障,写屏障 Synchronized 和 ReentrantLock 有什么区别? Synchronized 是一种基础的同步操作,没有非公平和超时等待的概率 Synchronized 实现锁主要依赖与监视器锁和对象头 需要先获取到对象头的监视器锁才能进行执行 修饰方法: 修饰代码快: JDK1.6对Synchronized 的优化 偏向锁 轻量级锁 重量级锁 锁消除 锁粗化 ReentrantLock 是AQS的具体实现 包含state、同步队列、条件队列 state: * state为1表示锁被占有 * state为0表示锁空闲 同步队列 * 非公平锁时,如果抢不到锁,通过CAS抢锁,如果还是抢不到,加入同步队列中 条件队列 * 使用Contidion.wait() 加入条件队列,使用Condition.singnal()从条件队列加入同步队列中 ReentrantLock 是一种比较复杂的锁,可以实现公平和超时 说说 AQS 吧? 抽象队列同步器,定义了一系列规范,很多同步器都对其进行了实现,比如说ReentrantLock、Semaphore、CyclicBarrier、CountDownLatch等 核心:volatile修饰的state变量和CLH队列 CLH队列的演变过程 * CAS自旋一个变量,产生总线风暴 * CLH通过一个隐式队列,每个线程自旋判断前一个线程是否释放了锁 * AQS实现的CLH队列 通过一个双向队列,除了队头的线程是持有锁的,其他的都处于阻塞状态,队头释放锁通知下一个线程执行。 Redis 中的 Big Key 问题是什么?如何解决? 占用内存比较大的key 问题: * 内存倾斜 * 服务端查找慢 * 网络传输也慢 * 客户端超时 解决: * 数据压缩 * 拆分 * 只存储必要信息 Redis 集群的实现原理是什么? 每个节点负责一部分的数据,2^14次方个槽位,通过hash计算出键所在的槽位 请求的时候随机请求一个节点,如果不存在,放回数据所在节点的信息给客户端,客户端重新请求 如何保证节点中数据的一致性? 使用Gossip协议 每个节点发生自身的信息给其他节点 其他节点收到信息之后和自身的信息汇总继续发送给其他节点,也就是更新哈希槽数组的信息,每一个槽指向那个节点实例 最终整个集群达到一致性 为什么槽的数目是2^14次方? 主要是为了防止心跳包太大了 如何解决 Redis 中的热点 key 问题? 访问频率占比很高的key 限流 读写分离 多级缓存 拆分 发现 hotkey命令 monitor命令
4
复习第十四天 什么是 Java 的 CAS(Compare-And-Swap)操作? 存在的问题 ABA:通过添加版本解决 单变量 循环开销 你使用过哪些 Java 并发工具类? Semaphore acquire release 信号量 AtomicInteger 原子整形 ReentranLock 可重入锁 CyclicBarrier 循环屏障 循环屏障 wait CountDown 计数器 wait countdown 你了解 Java 线程池的原理吗? 核心参数:核心线程数、最大线程数、存活时间、工作队列、拒绝策略 工作队列: SynchronizedQueue:不使用队列 PriorityQueue: LinkedBlockQueue: ArrayBlockQueue: 拒绝策略: 丢弃抛出异常 直接丢弃 丢弃队头元素 调用者来执行 创建线程池方式: 单个 多个 不设上限 定时任务 偷取任务的 Redis 数据过期后的删除策略是什么? 定期删除:周期性删除100ms,拉取20个键,判断是否有超过25%的键过期,如果是,则继续拉去,总时长不可以超过25ms。缺点CPU占用率高 惰性删除:查找到的时候才删除,缺点:内存泄露 兜底策略 如果内存满了 最近最少使用 最少使用频率 随机删除 最小存活时间的进行删除 不执行删除操作,拒绝 Redis 主从复制的实现原理是什么? 主节点将数据同步给从节点 开始同步 全量同步:psync ?-1 触发全量复制,主节点生成RDB文件发给从节点,从节点根据RDB文件进行重放,主节点将这生成RDB文件之后的数据也发给从节点。 增量同步:主节点和从节点会维护一个长链接,psync 主节点ID offset 主节点从环形缓冲区中取出偏移量后面的数据发给从节点,如果没有,则进行全量复制 Redis 的持久化机制有哪些? RDB:生成内存中的一个快照,以二进制的形式进行存储,适合主从复制,备份等场景 AOF:写入命令的时候追加到AOF文件中,实时性比较高 RDB优点:恢复快,服务器宕机后可以使用其进行恢复 缺点:缺少上一次备份后的数据 AOF优点:缺失数据比较少 缺点:恢复速度比较慢 生成RDB流程 * 先判断是否在生成RDB或者执行AOF重写 * fork一个子进程 * 子进程复制生成RDB文件 * 将新的替换旧的 生成RDB过程中的写入操作 * 使用写时复制技术 * 将要写入数据所在的页进行复制 AOF重写 * fork一个子进程 * 将内存中的键转化为对应的写入命令,写入到AOF文件中 * 主进程仍然将新的请求写入到原来的AOF缓冲区并刷入到原来的AOF文件中 * 主进程还需要将重写期间的命令写入新的AOF文件中 * 新的替换旧的 混合持久化机制 * 先fork一个子进程 * 生成RDB文件 * 将RDB文件添加到AOF的头部,将生成RDB文件期间新增的数据添加到AOF文件中 * 旧的替换新的 * redis7.0做了优化,主进程直接生成增量AOF文件,然后和重写的AOF文件进行合并
5
复习第十三天 Java 中 HashMap 的扩容机制是怎样的? Java 中有哪些集合类?请简单介绍 说说 Java 中 HashMap 的原理? 存储键值对,通过计算键值的hash值,找到数组中对应的位置进行插入,如果存在元素,则产生冲突,此时使用链表或者红黑树解决冲突(JDK1.8之后引入红黑树) 扩容和负载因子 Redis 实现分布式锁时可能遇到的问题有哪些? * 锁过期 * 锁被误释放 * 单点故障 * 主从故障 * 时钟漂移 * 网络分区 Redis 的 Red Lock 是什么?你了解吗? redis的红锁,当主从架构的时候,如果主节点加完锁还没同步给从节点,主节点就挂了,此时会有多个线程获取到锁。此时就需要红锁来避免这一过程。 具体来说 * 存在多个实例通常是5个 * 客户端轮询向这多个实例中加锁, * 只有超过半数的加锁成功才算成功 缺点: * 复杂度高,是一个重锁 * 多个锁续期复杂 * 时钟漂移问题 * 不适合高并发场景,多个锁同时加锁时间长 Redis 中如何实现分布式锁? 使用lua脚本加setnx 加锁:set key_lock value_unique ex expire_time nx 解锁:使用lua脚本,先获取唯一标识,判断是否是当前线程加的锁,如果是才能释放锁,完整的流程,需要使用lua脚本来实现。 为什么要有唯一值? 防止锁被误释放 为什么要设置过期时间? 防止用户程序崩溃导致锁无法释放 复习第十二天 (补昨天的) 接口和抽象类有什么区别? 接口是规范,客户端不需要底层的具体实现,对客户端无感。(JDK1.8及之后可以实现默认方法和静态方法) 抽象类是模板:便于子类的复用和重写。 JDK 动态代理和 CGLIB 动态代理有什么区别? JDK动态代理:代理类需要实现接口,通过实现Invocationhandler来增强被代理累。然后在客户端中使用Proxy创建代理类 CGLIB动态代理:基于字节码的形式,通过生成被代理累的子类来对对象进行增强 你使用过 Java 的反射机制吗?如何应用反射? 可以动态的创建对象和访问方法和属性 核心时Class类 通过Class类创建实例对象 访问方法clazz.getMethods() 访问属性class.getField() Redis String 类型的底层实现是什么?(SDS) 简单动态字符串 和C语言先比 * O(1)获取长度 * 预留空间 * 动态扩容 此外还有多种编码方式 * int编码:存储整数 * embstr编码:存储短字符串,元数据(编码类型)和SDS存放在一起 * raw编码:长字符串,元素局和SDS分开存储 Redis 中的缓存击穿、缓存穿透和缓存雪崩是什么? 缓存击穿: 热点数据过期。 加锁,用不过期 缓存穿透: 大量请求数据库不存在的数据 缓存空值 加锁 布隆过滤器 缓存雪崩: 热点数据同时过期、或者缓存服务崩溃 * 随机性,加锁 * 集群架构 Redis 中如何保证缓存与数据库的数据一致性? 先更新数据库后更新缓存 先更新缓存后更新数据库 先删除缓存后更新数据库 先更新数据库后删除缓存 先删除缓存后更新数据库,在删除缓存(缓存双删) 基于binlog日志文件的异步更新缓存 实时一致性 度写锁,读读不互斥,读写互斥 读流程 * 读锁 * 先查询缓存 * 缓存命中返回 释放读锁 * 不命中,查询数据库,写入缓存,返回 * 释放读锁 写流程 * 写锁 * 写数据库 * 删除缓存 * 释放写锁
4
复习第十一天 什么是软中断、什么是硬中断? 软中断:软件中断,需要请求内核的服务,(网络传输、文件读取等),从用户态切换到内核态(上下文切换) 硬中断:硬件中断,网卡、硬盘、计时器等发起的中断,优先级高,却要进行上下文切换,根据中断向量,通过中断向量表,找到对应的中断处理程序进行执行。 什么是分段、什么是分页? 分段和分页都是内存管理技术 分页:页的大小是固定的,将物理内存和逻辑内存分成大小相同的页或页框,会存在内部碎片 分段:段的大小不固定,根据程序的逻辑功能进行划分(代码段、程序段、堆栈段),会出现外部碎片 段页式:先按程序的逻辑进行分段,然后再进行分页,使用(段号,页号,页内偏移量)来表示逻辑内存,通过其找到对应的物理内存。 说下你常用的 Linux 命令? cd ls mkdir cp mv tar -zxvf tar -zcvf chmod 777 ps -ef | grep java top kill ipconfg Redis 的 hash 是什么? Redis 中跳表的实现原理是什么? Redis Zset 的实现原理是什么? 底层是哈希表+跳表 可以用来实现排行版 哈希表:用于等值查询 跳表:用于范围查询 当元素个数小于128 且 元素大小小于64B的时候,使用压缩列表 JDK1.7后使用紧凑列表,否则使用哈希表+跳表 哈希表底层原理 将多个键值对存储在一个键中 适合存储对象,购物车等场景 底层实现 当元素个数小于512 且 元素大小小于64B的时候使用的是压缩列表或紧凑列表(JDK1.7之后),否则使用哈希表 哈希表的底层原理 在哈希表的结构体中,有一个table数组、数组大小、掩码(大小-1)和元素个数 其中table数组存储的是一个个的键值对 当发送冲突的时候使用链表解决 扩容和缩容 扩容:主要根据负载因子的情况判断,当元素个数达到所允许的负载的时候,则会继续扩容,扩容为原来的两倍 缩容:当元素的个数比较少的时候,会进行缩容,缩小为元素个数最近的那个2次幂 扩容时机: 当负载因子大于1,且此时在进行RDB生成或者AOF重写,则先不进行扩容,否则进行扩容 当负载银日大于5,无论是否继续持久化,都立即进行扩容 缩容: 负载因子小于0.1的时候 渐进式扩容 一点点的扩容 扩容的时候会使用多一个哈希表结构体,在这两个哈希表的上层,还有一个结构体引向它们,存储这哈希表数组[0]和[1],还有rehashidx,当进行渐进式扩容的时候rehashidx为一个非-1的值,表示扩容的进度 每次增删改查的时候,将一部分的数据移动到新的数组中去 新增加的数据直接添加到新数组中 最终完成渐进式哈希的时候,将rehashidx设置为-1,表示扩容完毕。 跳表: 有多条链表,越往上的链表存储的元素个数越少, 查找流程:从最上层的链表开始查找,如果能从当前链表中直接找到,则返回,如果找不到则确定一个区间,进入下一层继续查找,直到来到最后一层的链表,最后一层的链表是包含所有元素,找到则返回,找不到说明元素不存在。 插入流程:从最上层的链表开始查找,确定插入的区间(每一层都记录区间的左节点),进入下一层继续查找,直到来到最后一层的链表,找到插入的位置,此时通过摇塞子的形式,判断当前插入元素会横跨多少层,此时上面记录区间的左节点就有用了,可以方便在多层进行插入。 ★学习紧凑列表和压缩列表的思想 压缩列表 * 记录节点数目 * 记录占用空间大小 * 记录尾节点的距离开始节点的偏移量(辅助倒序遍历) * 列表节点(每个节点会存储上一个节点的长度信息1字节~5字节,这里是级联更新的关键) 紧凑列表(和紧凑列表类似) * 记录节点数目 * 记录占用空间大小 * ❌不需要记录尾节点的距离开始节点的偏移量(也就是不支持倒序遍历) * 列表节点(只存储自身的节点长度信息,且放在尾部) 问题:哈希表和HashMap有什么区别
3
下载 APP