安卓面试题到处攒,一到面试就忘个干净?来看看这份超详细的整理( 八 )

这时,主线程会进行休眠状态,也就不会消耗CPU资源 。当下个消息到达的时候,就会通过pipe管道写入数据然后唤醒主线程进行工作 。
这里涉及到阻塞和唤醒的机制叫做 epoll 机制 。
先说说文件描述符和I/O多路复用:

在linux操作系统中,可以将一切都看作是文件,而文件描述符简称fd,当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符,可以理解为一个索引值 。
I/O多路复用是一种机制,让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作
所以I/O多路复用其实就是一种监听读写的通知机制,而Linux提供的三种 IO 复用方式分别是:select、poll 和 epoll。而这其中epoll是性能最好的多路I/O就绪通知方法 。
所以,这里用到的epoll其实就是一种I/O多路复用方式,用来监控多个文件描述符的I/O事件 。通过epoll_wait方法等待I/O事件,如果当前没有可用的事件则阻塞调用线程 。
23、Binder通信过程和原理首先,还是看一张图,原图也是出自神书中:
安卓面试题到处攒,一到面试就忘个干净?来看看这份超详细的整理

文章插图
 
首先要明确的是客户端进程是无法直接操作服务端中的类和方法的,因为不同进程直接是不共享资源的 。所以客户端这边操作的只是服务端进程的一个代理对象,也就是一个服务端的类引用,也就是Binder引用 。
总体通信流程就是:
  • 客户端通过代理对象向服务器发送请求 。
  • 代理对象通过Binder驱动发送到服务器进程
  • 服务器进程处理请求,并通过Binder驱动返回处理结果给代理对象
  • 代理对象将结果返回给客户端 。
再看看在我们应用中常常用到的工作模型,上图:
安卓面试题到处攒,一到面试就忘个干净?来看看这份超详细的整理

文章插图
 
这就是在应用层面我们常用的工作模型,通过ServiceManager去获取各种系统进程服务 。这里的通信过程如下:
  • 服务端跨进程的类都要继承Binder类,所以也就是服务端对应的Binder实体 。这个类并不是实际真实的远程Binder对象,而是一个Binder引用(即服务端的类引用),会在Binder驱动里还要做一次映射 。
  • 客户端要调用远程对象函数时,只需把数据写入到Parcel,在调用所持有的Binder引用的transact()函数
  • transact函数执行过程中会把参数、标识符(标记远程对象及其函数)等数据放入到Client的共享内存,Binder驱动从Client的共享内存中读取数据,根据这些数据找到对应的远程进程的共享内存 。
  • 然后把数据拷贝到远程进程的共享内存中,并通知远程进程执行onTransact()函数,这个函数也是属于Binder类 。
  • 远程进程Binder对象执行完成后,将得到的写入自己的共享内存中,Binder驱动再将远程进程的共享内存数据拷贝到客户端的共享内存,并唤醒客户端线程 。
所以通信过程中比较重要的就是这个服务端的Binder引用,通过它来找到服务端并与之完成通信 。
看到这里可能有的人疑惑了,图中线程池怎么没用到啊?
  • 可以从第一张图中看出,Binder线程池位于服务端,它的主要作用就是将每个业务模块的Binder请求统一转发到远程Servie中去执行,从而避免了重复创建Service的过程 。也就是服务端只有一个,但是可以处理多个不同客户端的Binder请求 。
......................
系统的面试复习路线多余的话就不讲了,接下来将分享我之前面试的复习过程,如果你也在准备面试但是不知道怎么高效复习,可以参考一下我的复习路线,有任何问题也欢迎一起互相交流,加油吧!
这里给大家提供一个方向,进行体系化的学习:
1、看视频进行系统学习
这几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的 。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面 。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时 。
另外,我自己也珍藏了好几套视频,有需要的我也可以分享给你 。
2、进行系统梳理知识,提升储备
客户端开发的知识点就那么多,面试问来问去还是那么点东西 。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度 。so,出去面试时先看看自己复习到了哪个阶段就好 。


推荐阅读