-
Choreorgapher
原理
-
每一个线程都有一张表,其实就是一个数组,key和value都存储在数组中
-
key存储在weakReference中,value对应对象如Looper、Choreorgapher等
-
一个应用里可以定义多个ThreadLocal,ThreadLocal都有自己的哈希值,哈希值根据hashCounter计算
-
算出hash值之后,对表的size取余数,就能算出key:value在表中的index值
-
如果发生了hash冲突,就会从当前index开始向下遍历数组,放在空闲的位置上
-
代码如下:
总结
-
同一个ThreadLocal对象,在不同线程get返回不同value
-
Thread对象里有张表,保存ThreadLocal到value的映射关系
-
这张表是怎么实现的?(见上面的原理分析)
-
是如何解决hash冲突的?(见上面的原理分析)
3. 说说Looper的副业(待完善)
-
Looper里可以监听其它描述符
-
创建管道,跨进程传数据,用looper监听描述符事件
4. 怎么检查线程有耗时任务
两种情况
-
正常的,轻微阻塞
-
不正常的,严重阻塞
检测机制
-
WatchDog:
-
Framework自带,检查system_server中系统服务是否正常
-
用于检查死锁或者线程异常
-
BlockCanary
-
开源框架,用于检查线程是否有耗时任务
WatchDog WatchDog的作用上面说过:一是检查是否发生了死锁,二是检查线程是否被任务blocked
-
WatchDog是一个线程
-
看下WatchDog的关键变量:
-
mHandlerCheckers是核心列表,添加了多个HandlerChecker
-
每一个Checker都对应了一个线程,比如主线程、前台线程、IO线程等,这几个线程都是system_server中非常重要的工作线程
-
每一个HandlerChecker下都有一个Monitor列表
-
addMonitor实质上是向mMonitorChecker加了一个BinderThreadMonitor,用于检测binder线程是否正常
看下下图
-
第一个MonitorChecker用户检查系统服务是否发生了死锁,在单独的线程中检查,
-
原理就是在另外的线程中去尝试拿到锁,拿到了就正常返回
-
如果一直拿不到,就可能是产生了死锁问题
-
如图AMS中代码细节
-
同时服务还会把自己的工作线程new一个HandlerChecker,也注册到watchDog,每一个handlerChecker都会对应一个线程,在线程中派发handlerChecker
BlockCanary 原理就是通过messageLogging在消息分发前后的时间戳打印,利用时间戳的差算出消息执行耗时
5. 怎么同步处理消息
「同步处理消息」:我们发了一个消息到另外一个线程去处理,并没有直接返回,而是挂在那里等待消息处理完毕,有些时候还需要拿到消息处理结果,这就是同步处理消息
适用场景如图124
应用要访问另一个进程的服务,请求会调到服务进程的binder线程池中,binder线程切换到工作线程处理请求,工作线程工作的时候binder线程会一直等待,应用端也会一直等着,等到处理完成后返回结果给给应用
6. 你去了解framework是为了解决一个什么样的问题,怎么解决的?
考察点
-
你有没有解决复杂问题的经验
-
你有没有深入研究底层原理的习惯
-
你的知识体系是否有一定深度
7. 应用组件相关题目
-
为什么Activity在onResume之后才会显示出来
-
ActivityThread handleResumeActivity时WindowManager才会addView并makeVisible
-
bindService的时候Rebind总是调不到,研究原理
-
TODO
-
广播onReceive的context可否启动Activity, 显示Dialog?
-
TODO
-
发现provider的onCreate比Application还早,研究一下
-
Application 构造方法 –> Application.attachBaseContext –> ContentProvider.onCreate –> Application.onCreate –> Activity.onCreate
-
看下 ActivityThread.java 的 handleBindApplication方法:
-
图130
8. 消息通信相关题目
-
intent带的数据量大了会异常,研究原因
-
binder机制 1m限制
-
需要跨进程传大图,研究Bitmap传输原理,Ashmem机制
-
想知道Handler消息延时的精度怎么样,去了解原理
-
延迟处理不是延迟发送,精度不太准确
-
为什么有时候IdleHandler调不到,去了解原理
-
主线程繁忙,一直在处理消息
-
比如:
-
在View的onDraw方法里面无限制的直接或者间接调用View的invalidate方法。
-
做一个无限轮询的View动画。
9.性能优化相关题目
-
ANR了,看主线程是否有耗时任务
-
卡顿掉帧,了解屏幕刷新机制,研究Choregrapher
-
启动速度优化,了解应用启动原理
-
内存优化,清理不必要的资源
10. Android FrameWork用到了哪些设计模式?请举例说明
单例模式
-
Framework中:SingleTon类,应用IAM
-
线程内:
-
线程间/进程内:Choreographer,ThreadLocal线程私有,不同线程获取不同的实例,同一线程获取同一实例
-
图125
125.png
-
进程间:
-
进程间的内存是相互隔离的,如何保证在进程间的单例呢,这个时候就需要一个中间人,所谓的中间人,就是他可以和所有进程进行通信,由其确保这个对象是单例的
-
下面的例子中,单例是ServiceManager,中间人是binder驱动
-
对所有的进程来说,ServiceManager对应的binder句柄都是一个即0,这样binder驱动在转发请求的时候都会送往同一个目标,即ServiceManager所在的进程,这样就能保证ServiceManager是跨进程单例的
-
图127
观察者模式
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
面试复习路线,梳理知识,提升储备
自己的知识准备得怎么样,这直接决定了你能否顺利通过一面和二面,所以在面试前来一个知识梳理,看需不需要提升自己的知识储备是很有必要的。
关于知识梳理,这里再分享一下我面试这段时间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)
- 架构师筑基必备技能
- Android高级UI与FrameWork源码
- 360°全方面性能调优
- 解读开源框架设计思想
- NDK模块开发
- 微信小程序
- Hybrid 开发与Flutter
知识梳理完之后,就需要进行查漏补缺,所以针对这些知识点,我手头上也准备了不少的电子书和笔记,这些笔记将各个知识点进行了完美的总结:
《960全网最全Android开发笔记》
《379页Android开发面试宝典》
历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。
如何使用它?
1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数
《507页Android开发相关源码解析》
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
加通过前两轮技术面试的几率。
如何使用它?
1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数
[外链图片转存中…(img-Q8Cctauw-1711909012141)]
《507页Android开发相关源码解析》
只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。