征服面试官:RxJava 原理篇 掌握这篇面试题汇总,吊打面试官!

2023-11-09

1、RxJava 如何实现线程切换?

subscribeOn 是通过新建 Observable 的方式,使用 OnSubscribe 类的方式去做到线程切换的。

observeOn 是通过 operator 操作符的形式去完成线程切换的,所以他的作用域和其他操作符一样,是调用 observeOn 之后的链路。

  • Schedulers.io() 代表 io 操作的线程, 通常用于网络,读写文件等 io 密集型的操作
  • Schedulers.computation() 代表 CPU 计算密集型的操作, 例如需要大量计算的操作
  • Schedulers.newThread() 代表一个常规的新线程
  • AndroidSchedulers.mainThread() 代表 Android 的主线程

生产者线程调度流程概括

  1. Schedulers.io()等价于 new IoScheduler()
  2. new IoScheduler() Rxjava 创建了线程池,为后续创建线程做准备,同时创建并运行了一个
    清理线程 RxCachedWorkerPoolEvictor,定期执行清理任务。
  3. subscribeOn()返回一个 ObservableSubscribeOn 对象,它是 Observable 的一个装饰类,
    增加了 scheduler
  4. 调用 subscribe()方法,在这个方法调用后,subscribeActual() 被调用,才真正执行了
    IoSchduler 中的 createWorker() 创建线程并运行,最终将上游 Observablesubscribe()
    法调度到新创建的线程中运行。

消费者线程调度流程概括

  1. AndroidSchedulers.mainThread()先创建一个包含 handlerScheduler, 这个 handler 是主线程的 handler
  2. observeOn 方法创建 ObservableObserveOn,它是上游 Observable 的一个装饰类,其中包含前面创建的 SchedulerbufferSize 等.
  3. 当订阅方法 subscribe 被调用后,ObservableObserveOnsubscribeActual 方法创建
    Scheduler.Worker 并调用上游的 subscribe 方法,同时将自身接收的参数’observer’用装饰
    ObserveOnObserver 装饰后传递给上游。
  4. 当上游调用被 ObserveOnObserveronNextonErroronComplete 方法时,
    ObserveOnObserver 将上游发送的事件通通加入到队列 queue 中,然后再调用 scheduler
    将处理事件的方法调度到对应的线程中(本例会调度到 main thread)。 处理事件的方法将
    queue 中保存的事件取出来,调用下游原始的 observer 再发射出去。
  5. 经过以上流程,下游处理事件的消费者线程就运行在了 observeOn 调度后的 thread 中。

总结
Schedulers 内部封装了各种 Scheduler。每一个 Scheduler 中都封装的有线程池,用于执行后台任务。

Scheduler 是所有调度器实现的抽象父类,子类可以通过复写其 scheduleDirect() 来自行决定如何调度被分配到的任务;同时通过复写其 createWorker() 返回的 Scheduler.Worker 实例来执行具体的某个任务。此处的任务指的是通过 Runnable 封装的可执行代码块。

  1. 子线程切换主线程:给主线程所在的Handler发消息,然后就把逻辑切换过去了。

  2. 主线程切换子线程:把任务放到线程池中执行就能把执行逻辑切换到子线程

  3. 子线程切换子线程:把任务分别扔进两个线程就行了。

Rxjavasubscribe 方法是由下游一步步向上游进行传递的。会调用上游的 subscribe,直到调用到事件源。

2、RxJava 有哪些操作符?

  • 创建操作符

  • 转换操作符

  • 过滤操作符

  • 条件操作符

  • 延时操作符

  • 其他操作符

    • map 转换事件,返回普通事件
    • flatMap 转换事件,返回` Observable
    • conactMap concatMap 与 FlatMap 的唯一区别就是 concatMap 保证了顺序
    • subscribeOn 规定被观察者所在的线程
    • observeOn 规定下面要执行的消费者所在的线程
    • take 接受一个 long 型参数 count ,代表至多接收 count 个数据
    • debounce 去除发送频率过快的项,常用在重复点击解决上,配合 RxBinging 使用效果很好
    • timer 定时任务,多少时间以后发送事件
    • interval 每隔一定时间执行一些任务
    • skip 跳过前多少个事件
    • distinct 去重
    • takeUntil 直到到一定条件的是停下,也可以接受另外一个被观察者,当这个被观察者结束之后则停止第一个被观察者
    • Zip 专用于合并事件,该合并不是连接(连接操作符后面会说),而是两两配对,也就意味着,最终配对出的 Observable 发射事件数目只和少的那个相同。不影响Observable的发射,Observable 被观察者会一直发射,不会停,只是Observer 接收不到
    • merge 多个 Observable 发射的数据随机发射,不保证先后顺序
    • Concat 多个 Observable 组合以后按照顺序发射,保证了先后顺序,不过最多能组合4个 Observable ,多的可以使用 contactArray
    • onErrorReturn 遇到错误是发射指定的数据到 onNext,并正常终止
    • onErrorResumeReturn 遇到错误时,发射设置好的一个 Observable ,用来发送数据到 onNext,并正常终止
    • onExceptionResumeReturn 和onErrorResumeReturn 类似,不同之处在于会判断是否是 Exception。如果是和 onErrorResumeReturn 一样,不是则会调用 onError。不会调用onNext

3、操作符 map 和 flatmap 的区别?

  • map:【数据类型转换】将被观察者发送的事件转换为另一种类型的事件。
  • flatMap:【化解循环嵌套和接口嵌套】将被观察者发送的事件序列进行拆分 & 转换 后合并成一个新的事件序列,最后再进行发送。
  • concatMap:【有序】与 flatMap 的 区别在于,拆分 & 重新合并生成的事件序列 的顺序与被观察者旧序列生产的顺序一致。

共同点

  1. 都是依赖 Function 函数进行转换(将一个类型依据程序逻辑转换成另一种类型,根据入参和返回值)

  2. 都能在转换后直接被 subscribe

区别

  1. 返回结果不同

    map 返回的是结果集,flatmap 返回的是包含结果集的 Observable 对象(返回结果不同)

  2. 执行顺序不同

    map 被订阅时每传递一个事件执行一次 onNext 方法,flatmap 多用于多对多,一对多,再被转化为多个时,一般利用 from/just 进行一一分发,被订阅时将所有数据传递完毕汇总到一个 Observable 然后一一执行 onNext 方法。(如单纯用于一对一转换则和 map 相同)

  3. 转换对象的能力不同

    map 只能单一转换,单一指的是只能一对一进行转换,指一个对象可以转化为另一个对象但是不能转换成对象数组。

    flatmap 既可以单一转换也可以一对多/多对多转换,flatmap 要求返回 Observable,因此可以再内部进行事件分发,逐个取出单一对象。

4、RxJava 如何解决内存泄漏?

  1. 订阅的时候拿到 Disposable ,主动调用 dispose

  2. 使用 RxLifeCycle

  3. 使用 AutoDispose

5、RxJava 中 Observable、Flowable、Single、Maybe、Completable 使用时如何选择?

RxJava2 里面,ObservableFlowableSingleMaybeCompletable 这几个在使用起来区别不大,因为他们都可以用一个或多个函数式接口作为参数进行订阅(subscribe),需要几个传几个就可以了。但是从各个的设计初衷来讲,个人感觉最适用于网络请求这种情况的是 SingleCompletable

  • 网络请求是一个 Request 对应一个 Response,不会出现背压情况,所以不考虑 Flowable
  • 网络请求是一个 Request 对应一个 Response,不是一个连续的事件流,所以在 onNext 被调用之后,onComplete 就会被马上调用,所以只需要 onNextonComplete 其中一个就够了,不考虑 ObservableMaybe
  • 对于关心 ResponseBody 的情况,Single 适用;
  • 对于不关心 ResponseBody 的情况,Completable 适用。

6、为什么 subscribeOn() 只有第一次切换有效

因为 RxJava 最终能影响 ObservableOnSubscribe 这个匿名实现接口的运行环境的只能是最后一次运行的 subscribeOn() ,又因为 RxJava 订阅的时候是从下往上订阅,所以从上往下第一个 subscribeOn() 就是最后运行的,这就造成了写多个 subscribeOn() 并没有什么乱用的现象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

征服面试官:RxJava 原理篇 掌握这篇面试题汇总,吊打面试官! 的相关文章

  • 使用DBFlow,如何加密已经存在的数据库?

    我正在使用 DBFlow 来处理项目中的数据库 并且我想对现有数据库进行加密 我知道我可能必须删除现有的未加密数据库并创建另一个加密数据库 我也知道我可以将 SQLCipher 与 DBFlow 一起使用 如上所述文档 https gith
  • 如何访问 Android 心率传感器原始数据? (反射光,不是心跳)

    心率传感器上的 android sdk 仅返回计算出的 bpm 我对此不感兴趣 我需要访问 Android 心率传感器原始数据 例如就反射值的强度而言将会很大 因为心率传感器基本上使用 LED 并测量随时间变化的反射率 如果可能 访问由任何
  • 通过代码在创建时突出显示 ListView 项目

    我想在创建 listView 时突出显示 ListView 的第一行 0 我尝试了不同的方法 就像您在注释代码中看到的那样 但没有任何效果 这很奇怪 因为 OnItemClickListener 中的突出显示工作正常 它通过 xml 选择器
  • 升级到最新支持库后Android JACK编译器错误

    Android Studio 2 2 3 Windows 10 64位 构建工具版本 25 Android Gradle插件版本2 2 3 升级到最新的支持库 从 23 4 0 到 25 1 0 并更改编译版本 从 23 到 25 后 我收
  • 虚拟回调接口

    在 Eclipse 为您创建的来自 Google 的示例主从流代码中 片段中包含以下内容 private Callbacks mCallbacks sDummyCallbacks public interface Callbacks pub
  • 无法在 Android Studio 中导出签名的 APK

    当我使用keytool list keystore path to keyfile jks并提供我的密码 我可以看到那里的条目 但是当我在尝试使用相同的密码生成签名的 APK 时使用相同的密码时 我收到错误 无法加载密钥库 密钥库被篡改 或
  • 蓝牙 BLE Android 以最大吞吐量写入外设

    我们公司开发了一个具有蓝牙 BLE 的硬件单元 并且我们在 Nexus 7 2013 中有一个服务应用程序 我们希望使用它向该单元发送固件文件 文件最大可达 500kb BT芯片是德州仪器CC2540 我浏览了大量的页面 并扫描了 Stac
  • 写入 Android UI Automator 输出控制台

    我正在 Android UI Automator 上编写一个小包装器 通常我们可以在控制台看到测试用例的状态 我可以访问它并添加我自己的消息吗 我努力了System out println 但这没有用 有什么办法可以做到这一点吗 您可以使用
  • Play 商店中的应用描述更新

    我想更新应用程序的描述以及 Play 商店上的屏幕截图 但应用程序保持相同 即相同的版本号 我不想发布新应用程序 因为应用程序中没有任何更改 这可能吗 谷歌也会要求更新应用程序吗 您可以更新描述 也可以更改屏幕截图 您的应用程序将保持不变
  • 自动删除 Firebase 通知

    我有一个问题 我都读过让通知在 5 分钟后消失 https stackoverflow com questions 15648699 make notification disappear after 5 minutes and 几秒钟后清
  • 如何使用 Google 的 GithubBrowserSample 方法在片段之间共享视图模型?

    我对 Android 架构组件的使用非常陌生 因此我决定使用 GithubBrowserSample 来构建我的应用程序来实现我的许多用例 但我有一个问题 我不知道使用这种方法在片段之间共享视图模型的正确方法是什么 我想共享视图模型 因为我
  • 使用 OkHttp 下载损坏的文件

    我编写的下载文件的方法总是会产生损坏的文件 public static String okDownloadToFileSync final String link final String fileName final boolean te
  • 如何清除Android剪贴板?

    我发现的方法都不起作用 这是我尝试过的 1 使用clearPrimaryClip 的方法ClipboardManager class ClipboardManager clipboard ClipboardManager getSystem
  • Android:WebView/BaseInputConnection 中的退格键

    我在 Android 4 2 中遇到软键盘退格问题 我在 WebView CodeMirror 中有一个自定义编辑器 它使用一个空的
  • Android Google Map V2:如何在单击另一个标记时更改先前单击的标记的图标

    更新 我通过添加 previousMarker 对象解决了性能问题 因此 只有先前单击的标记将被删除并替换为默认图标 但是 当我单击标记时 信息窗口仍然不显示 我有一个地图视图并在上面设置了一些标记 我想要的是 当我单击一个标记时 它将其图
  • 用于请求带有临时缓存的远程 Observable 的 RxJava 模式

    用例是这样的 我想暂时缓存最新发出的昂贵的Observable响应 但在它过期后 返回到昂贵的源Observable并再次缓存它 等等 一个非常基本的网络缓存场景 但我真的很难让它工作 private Observable
  • XML 配置中的 screenName 不起作用

    我刚刚在我的应用程序中添加了对 Google Analytics 分析 的支持 但我无法
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这
  • Android 从通知刷新 Activity

    我有一个程序 我在其中调用通知 如果您将其下拉 该通知将启动一个新活动 mNotificationManager NotificationManager getSystemService ns int icon R drawable sta

随机推荐

  • Qt 在循环中超时跳出

    常见的一个需求 在一段循环中 给定一个最大运行时间 当循环时间超出时 终止 常用于一些工控场合 对节拍有要求的项目 在此简单的做一个总结记录 主要使用Qt的 QElapsedTimer 类 调用QElapsedTimer中的成员函数elap
  • MySQL技术内幕 InnoDB存储引擎 学习笔记 第八章 备份与恢复

    备份方法 1 热备 在数据库运行中直接备份 对正在运行的数据库没有任何影响 这种方式在MySQL官方手册中称为Online Backup 2 冷备 在数据库停止的情况下备份 这种备份最简单 一般只需拷贝相关的数据库物理文件即可 这种方式在M
  • Vnc配置

    2017 04 15 1 在terminal中输入vncconfig 弹出小窗 勾选对应选项 注意 不要关闭这个小窗 不要关闭这个小窗 不要关闭这个小窗 2 vncconfig nowin 在linux选中文字后 无需其他按键 直接在win
  • 智慧农业物联网系统解决方案

    一 方案背景 随着城市的发展 人们对于生活水准的要求也越来越高 对于食物的品质需求也越来越高 我作为世界农业大国 农业的发展优势慢慢降低 智慧化农业将带来一次新的农业结构改革 农业的根本问题是效率不高 效益不强 效能不够 原因在于各生产要素
  • Python自动操作 GUI 神器——PyAutoGUI

    我们以前讲过怎样使用 Python 在浏览器中实现页面自动化操作 不管用哪种方式实现 都是通过定位页面中的元素来进行相应的操作 今天我们来聊一聊如何在桌面实现自动化操作 与浏览器页面自动化操作类似 桌面自动化操作也是需要定位鼠标在桌面的位置
  • map的常用用法详解

    头文件 include
  • 基于S函数的BP神经网络PID控制器及simulink仿真

    基于S函数的BP神经网络PID控制器及simulink仿真 文章目录 文章来源和摘要 S函数的编写格式和运行步骤 simulink模型结构 S函数模型初始化部分代码理解 S函数模型更新部分 S函数模型输出部分 S函数完整代码附录 文章来源和
  • 第三方网站/系统使用微信扫码登录

    微信扫码登录网站 微信开放平台 在我们做某个平台或者系统时 都需要有一个登录功能 传统的用户名 密码登录模式看起来似乎并没有手机扫码直接登录来的方便 那么在前端实现上 如何实现微信扫码登录呢 授权流程 第三方发起微信授权登录请求 微信用户允
  • 病例对照研究中,如何对年龄、性别、教育程度进行频数匹配?

    病例对照研究中 如何对年龄性别进行频数匹配 案例一 两组被试匹配 案例二 三组被试匹配 背景 使用默认匹配方法 衡量匹配效果 调整参数 其他匹配方法 参考 案例一 两组被试匹配 案例二 三组被试匹配 背景 我经常遇到的数据情形是 有两组被试
  • 实现【企业微信自建应用使用uni-app H5 开发】,并解决【uni-app集成微信JSSDK(wx、jWeixin)变量冲突问题】

    目录 企业微信的开发与调试 企业微信应用主体逻辑 登录 构造网页授权链接 企业微信SDK配置 demo案例 重要bug修复方法 总结 企业微信的开发与调试 在本地开发基础代码和UI 发布到测试环境进行测试 无法本地调试接口 因为web浏览器
  • AltiumDesigner15.1导出3D PDF 图文教程

    ALtiumDesigner更新的速度就一个字 快 不过从15 4 15出来 貌似很久都没有更新了 等了很久 今天终于出来了 O O哈哈 因为早就耳闻AD15 1会带有3D输出功能 能够直接输出到PDF 这个好玩的功能 怎么能错过 本文就是
  • 时序基本介绍——Jitter与Skew区别

    在时序分析当中 有些基础概念还是要认真了解的 时钟抖动 Clock Jitter 和时钟偏移 Clock Skew 经常容易混淆 时序设计中 对于时钟的要求是非常严格的 因此FPGA中也有专用的时钟管脚 对应着专用的时钟区域BUFG BUF
  • 技术工具类:IDEA集成SonarQube并使用

    1 安装插件 从 File gt Settings gt Plugins 搜索 sonar 如下图 直接点击安装即可 安装成功后重启IDEA 在Settings gt Tools 中找到 SonarLint 如下图 在Coniguratio
  • uni-app提供开箱即用的SSR支持

    SSR 服务端渲染 可以给SPA站点带来两大核心优势 更好的SEO 更快的首屏渲染 很多uni app开发者都在积极尝试SSR 但大多没入门就放弃了 原因在于SSR颇高的技术门槛 vue js 官网在介绍 SSR 章节时的描述如下 本指南将
  • Python pycharm(windows版本)部署spark环境

    一 部署本地spark环境 1 1 安装好JDK 下载并安装好jdk1 7 配置完环境变量 1 2 Spark环境变量配置 去http spark apache org downloads html网站下载相应hadoop对应的版本 我下载
  • GD32 ADC检测电压

    GD32 ADC检测电压 https blog csdn net yangkunhenry article details 112757855 GD32的参考电压在规格书上没有查到 但是由于GD32 和STM32的 某种关系 STM32 的
  • 基本农田卫星地图查询_谷歌地图 最新版v7.3.0

    谷歌地图整合Google的本地搜索以及驾车指南两项服务 能够鸟瞰世界 将取代目前桌面搜索软件 谷歌地图可在虚拟世界中如同一只雄鹰在大峡谷中自由飞翔 登陆峡谷顶峰 潜入峡谷深渊 谷歌地图使用界面 相关软件 版本说明 下载地址 谷歌卫星地图下载
  • 感受了一下myspace

    今天去 www myspace com 看了看 感觉还可以 这里是年轻人交流的一个平台 可以了解当前世界年轻的喜好 他们做什么 有想些什么 可以和自己对比 把握时代信息 我觉得还是有点必要 就想当初我进入 天涯 时一样 希望从中能学到一些东
  • qt opengl 加载3d模型(obj格式)

    和一般c 程序加载3d模型一样 解读出数据内容 再用一个常规的着色程序就可以了 我实现的效果如下 采用的免费模型 实现思路和前面的略有不同 就是把自己生成顶点 纹理 法线的过程变成从文件读取了 我的obj文件如下 mtllib C User
  • 征服面试官:RxJava 原理篇 掌握这篇面试题汇总,吊打面试官!

    1 RxJava 如何实现线程切换 subscribeOn 是通过新建 Observable 的方式 使用 OnSubscribe 类的方式去做到线程切换的 observeOn 是通过 operator 操作符的形式去完成线程切换的 所以他