RxJava面试
作者:互联网
1、使用步骤
2、RxJava 如何实现线程切换?
- subscribeOn 是通过新建 Observable 的方式,使用 OnSubscribe 类的方式去做到线程切换的。
- observeOn 是通过 operator 操作符的形式去完成线程切换的,所以他的作用域和其他操作符一样,是调用 observeOn 之后的链路。
- Schedulers.io() 代表 io 操作的线程, 通常用于网络,读写文件等 io 密集型的操作
- Schedulers.computation() 代表 CPU 计算密集型的操作, 例如需要大量计算的操作
- Schedulers.newThread() 代表一个常规的新线程
- AndroidSchedulers.mainThread() 代表 Android 的主线程
总结
Schedulers 内部封装了各种 Scheduler。每一个 Scheduler 中都封装的有线程池,用于执行后台任务。
Scheduler 是所有调度器实现的抽象父类,子类可以通过复写其 scheduleDirect() 来自行决定如何调度被分配到的任务;同时通过复写其 createWorker() 返回的 Scheduler.Worker 实例来执行具体的某个任务。此处的任务指的是通过 Runnable 封装的可执行代码块。
子线程切换主线程:给主线程所在的Handler发消息,然后就把逻辑切换过去了。
主线程切换子线程:把任务放到线程池中执行就能把执行逻辑切换到子线程
子线程切换子线程:把任务分别扔进两个线程就行了。
Rxjava 的 subscribe 方法是由下游一步步向上游进行传递的。会调用上游的 subscribe,直到调用到事件源。
3、RxJava 有哪些操作符?
- 创建操作符
- 转换操作符
- 过滤操作符
- 条件操作符
- 延时操作符
- 其他操作符
4、RxJava 如何解决内存泄漏?
- 订阅的时候拿到 Disposable ,主动调用 dispose
- 使用 RxLifeCycle
- 使用 AutoDispose
5、为什么 subscribeOn() 只有第一次切换有
因为 RxJava 最终能影响 ObservableOnSubscribe 这个匿名实现接口的运行环境的只能是最后一次运行的 subscribeOn() ,又因为 RxJava 订阅的时候是从下往上订阅,所以从上往下第一个 subscribeOn() 就是最后运行的,这就造成了写多个 subscribeOn() 并没有什么乱用的现象。
6、如果不指定observer的线程,也就是指设置subscribeOn,而不设置observeOn,那observer的线程是什么样的?
我感觉理解了整个订阅的过程,其实理解这个问题一点都不难,既然subscribeOn是指定上游的observable的线程,那么最终的上游observable发射数据时候的线程也会被紧挨着它的subscribeOn指定的线程有关啊,并且不设置observeOn指定下游的observer的线程,那么observer的线程是不是跟最上游observable发射数据的线程保持一致啊。
7、背压是什么,以及Flowable怎么能控制背压?
它是指由于上游的observable发射数据太快,下游observer接收数据跟不上来导致的一种现象。可以形象理解为水坝在存储水的时候为了保持水的平衡,给下游的水库放水,同时会接收上游的水流,如果上游的水流很大,那么水坝中的水位激增,而水坝给下游放水的能力有限,所以就会导致水坝中的水漫过水坝。
8、Rxjava什么场景会导致内存泄露原因
使用RxJava发布一个订阅后,当页面被finish,此时订阅逻辑还未完成,如果没有及时取消订阅,就会导致Activity/Fragment无法被回收,从而引发内存泄漏。
9、RxJava 如何解决内存泄漏?
1、Disposable解决内存泄露(单个逐一解绑)
2、CompositeDisposable解决内存泄露(统一解绑)
3、RxLifecycle解决内存泄露
4、autoDisposable解决内存泄露
5、Rxlife解决内存泄露
10、背压产生原因?
1、同步订阅:即在同一线程中,被观察者每发一件事件,必须等到观察者接受处理后,才能发送下一个事件
2、异步订阅:观察者和被观察者不在同一个线程中,即产生了被观察者发送事件的速度与观察者接受事件的速度不一致,大多数情况是被观察者发送事件的速度大于观察者接受事件的速度,这个就是产生背压的原因.
11、如何解决背压?
1.控制观察者接受事件的速度—响应式拉取:
即当观察者设置s.request()方法之后,即设置了观察者接受事件的个数
2.控制被观察者发送事件的速度-------反馈控制
1>在同步订阅中,因为观察者和被观察者处于同一线程中,即被观察者可以得知观察者接受事件的个数.
2>异步订阅中,可以采用背压策略;
12、当观察者不设置s.request()方法,会出现什么呢?
当观察者不设置接受事件的个数时,被观察者依然会发送事件,只不过该事件会存入缓存区(大小128,这个大小可以查看Flowable源码)当如果发送的事件个数大于缓存区大小,即就会抛出异常.
13、背压策略
Flowable不仅可以通过create创建时需要制定背压策略,还可以在通过其他创建操作符,例如just、fromArray等创建后通过背压操作符指定背压策略。例如,
- 1、onBackpressreBuffer()对应BackpressureStategy.BUFFER:
Flowable的异步缓存池同Observable的一样,没有固定大小,可以无限制添加数据,不会抛出MissingBackpressureException异常,但会导致OOM(Out of Memory).- 2、onBackpressreDrop()对应BackpressureStategy.DROP:
如果Flowable的异步缓存池满了,则会丢掉将要放入缓存池中的数据。- 3、onBackpressreLatest()对应BackpressureStategy.LATEST:
如果缓存池满了,会丢掉将要放入缓存池中的数据。这一点与DROP策略一样,不同的是,不管缓存池的状态如何,LATEST策略会将最后一条数据强行放入缓存池中。
标签:缓存,观察者,背压,subscribeOn,面试,线程,RxJava,操作符 来源: https://blog.csdn.net/weixin_39069034/article/details/114928371