附2:Reactor 3 之选择合适的操作符——响应式Spring的道法术器

响应式编程(二)Mono<T>、Flux<T> 方法大全 阅读详情
AI摘要

本文详细介绍Reactor3中各种操作符的使用方法,包括创建序列、序列转化、过滤序列等核心功能,帮助读者掌握响应式编程技巧。

本系列其他文章见:《响应式Spring的道法术器》。
前情提要:Reactor3快速上手 | 深入理解响应式流规范 | Reactor3操作符

本节的内容来自我翻译的Reacto 3 参考文档——如何选择操作符。由于部分朋友打开github.io网速比较慢或上不去,贴出来方便大家查阅。

如果一个操作符是专属于 Flux 或 Mono 的,那么会给它注明前缀。
公共的操作符没有前缀。如果一个具体的用例涉及多个操作符的组合,这里以方法调用的方式展现,
会以一个点(.)开头,并将参数置于圆括号内,比如: .methodCall(parameter)。

1)创建一个新序列,它…

  • 发出一个 T,我已经有了:just
    • …基于一个 Optional<T>:Mono#justOrEmpty(Optional<T>)
    • …基于一个可能为 null 的 T:Mono#justOrEmpty(T)
  • 发出一个 T,且还是由 just 方法返回
    • …但是“懒”创建的:使用 Mono#fromSupplier 或用 defer 包装 just
  • 发出许多 T,这些元素我可以明确列举出来:Flux#just(T...)
  • 基于迭代数据结构:
    • 一个数组:Flux#fromArray
    • 一个集合或 iterable:Flux#fromIterable
    • 一个 Integer 的 range:Flux#range
    • 一个 Stream 提供给每一个订阅:Flux#fromStream(Supplier<Stream>)
  • 基于一个参数值给出的源:
    • 一个 Supplier<T>:Mono#fromSupplier
    • 一个任务:Mono#fromCallable,Mono#fromRunnable
    • 一个 CompletableFuture<T>:Mono#fromFuture
  • 直接完成:empty
  • 立即生成错误:error
    • …但是“懒”的方式生成 Throwable:error(Supplier<Throwable>)
  • 什么都不做:never
  • 订阅时才决定:defer
  • 依赖一个可回收的资源:using
  • 可编程地生成事件(可以使用状态):
    • 同步且逐个的:Flux#generate
    • 异步(也可同步)的,每次尽可能多发出元素:Flux#create
      (Mono#create 也是异步的,只不过只能发一个)

2)对序列进行转化

  • 我想转化一个序列:

    • 1对1地转化(比如字符串转化为它的长度):map
    • …类型转化:cast
    • …为了获得每个元素的序号:Flux#index
    • 1对n地转化(如字符串转化为一串字符):flatMap + 使用一个工厂方法
    • 1对n地转化可自定义转化方法和/或状态:handle
    • 对每一个元素执行一个异步操作(如对 url 执行 http 请求):flatMap + 一个异步的返回类型为 Publisher 的方法
    • …忽略一些数据:在 flatMap lambda 中根据条件返回一个 Mono.empty()
    • …保留原来的序列顺序:Flux#flatMapSequential(对每个元素的异步任务会立即执行,但会将结果按照原序列顺序排序)
    • …当 Mono 元素的异步任务会返回多个元素的序列时:Mono#flatMapMany
  • 我想添加一些数据元素到一个现有的序列:

    • 在开头添加:Flux#startWith(T...)
    • 在最后添加:Flux#concatWith(T...)
  • 我想将 Flux 转化为集合(一下都是针对 Flux 的)

    • 转化为 List:collectList,collectSortedList
    • 转化为 Map:collectMap,collectMultiMap
    • 转化为自定义集合:collect
    • 计数:count
    • reduce 算法(将上个元素的reduce结果与当前元素值作为输入执行reduce方法,如sum) reduce
    • …将每次 reduce 的结果立即发出:scan
    • 转化为一个 boolean 值:
    • 对所有元素判断都为true:all
    • 对至少一个元素判断为true:any
    • 判断序列是否有元素(不为空):hasElements
    • 判断序列中是否有匹配的元素:hasElement
  • 我想合并 publishers…

    • 按序连接:Flux#concat 或 .concatWith(other)
    • …即使有错误,也会等所有的 publishers 连接完成:Flux#concatDelayError
    • …按订阅顺序连接(这里的合并仍然可以理解成序列的连接):Flux#mergeSequential
    • 按元素发出的顺序合并(无论哪个序列的,元素先到先合并):Flux#merge / .mergeWith(other)
    • …元素类型会发生变化:Flux#zip / Flux#zipWith
    • 将元素组合:
    • 2个 Monos 组成1个 Tuple2:Mono#zipWith
    • n个 Monos 的元素都发出来后组成一个 Tuple:Mono#zip
    • 在终止信号出现时“采取行动”:
    • 在 Mono 终止时转换为一个 Mono<Void>:Mono#and
    • 当 n 个 Mono 都终止时返回 Mono<Void>:Mono#when
    • 返回一个存放组合数据的类型,对于被合并的多个序列:
      • 每个序列都发出一个元素时:Flux#zip
      • 任何一个序列发出元素时:Flux#combineLatest
    • 只取各个序列的第一个元素:Flux#first,Mono#first,mono.or
      (otherMono).or(thirdMono)
      ,`flux.or(otherFlux).or(thirdFlux)
    • 由一个序列触发(类似于 flatMap,不过“喜新厌旧”):switchMap
    • 由每个新序列开始时触发(也是“喜新厌旧”风格):switchOnNext
  • 我想重复一个序列:repeat

    • …但是以一定的间隔重复:Flux.interval(duration).flatMap(tick -> myExistingPublisher)
  • 我有一个空序列,但是…

    • 我想要一个缺省值来代替:defaultIfEmpty
    • 我想要一个缺省的序列来代替:switchIfEmpty
  • 我有一个序列,但是我对序列的元素值不感兴趣:ignoreElements

    • …并且我希望用 Mono 来表示序列已经结束:then
    • …并且我想在序列结束后等待另一个任务完成:thenEmpty
    • …并且我想在序列结束之后返回一个 Mono:Mono#then(mono)
    • …并且我想在序列结束之后返回一个值:Mono#thenReturn(T)
    • …并且我想在序列结束之后返回一个 Flux:thenMany
  • 我有一个 Mono 但我想延迟完成…

    • …当有1个或N个其他 publishers 都发出(或结束)时才完成:Mono#delayUntilOther
    • …使用一个函数式来定义如何获取“其他 publisher”:Mono#delayUntil(Function)
  • 我想基于一个递归的生成序列的规则扩展每一个元素,然后合并为一个序列发出:

    • …广度优先:expand(Function)
    • …深度优先:expandDeep(Function)

3)“窥视”(只读)序列

  • 再不对序列造成改变的情况下,我想:

    • 得到通知或执行一些操作:
    • 发出元素:doOnNext
    • 序列完成:Flux#doOnComplete,Mono#doOnSuccess
    • 因错误终止:doOnError
    • 取消:doOnCancel
    • 订阅时:doOnSubscribe
    • 请求时:doOnRequest
    • 完成或错误终止:doOnTerminate(Mono的方法可能包含有结果)
      • 但是在终止信号向下游传递 之后 :doAfterTerminate
    • 所有类型的信号(Signal):Flux#doOnEach
    • 所有结束的情况(完成complete、错误error、取消cancel):doFinally
    • 记录日志:log
  • 我想知道所有的事件:

    • 每一个事件都体现为一个 single 对象:
    • 执行 callback:doOnEach
    • 每个元素转化为 single 对象:materialize
      • …在转化回元素:dematerialize
    • 转化为一行日志:log

4)过滤序列

  • 我想过滤一个序列

    • 基于给定的判断条件:filter
    • …异步地进行判断:filterWhen
    • 仅限于指定类型的对象:ofType
    • 忽略所有元素:ignoreElements
    • 去重:
    • 对于整个序列:Flux#distinct
    • 去掉连续重复的元素:Flux#distinctUntilChanged
  • 我只想要一部分序列:

    • 只要 N 个元素:
    • 从序列的第一个元素开始算:Flux#take(long)
      • …取一段时间内发出的元素:Flux#take(Duration)
      • …只取第一个元素放到 Mono 中返回:Flux#next()
      • …使用 request(N) 而不是取消:Flux#limitRequest(long)
    • 从序列的最后一个元素倒数:Flux#takeLast
    • 直到满足某个条件(包含):Flux#takeUntil(基于判断条件),Flux#takeUntilOther(基于对 publisher 的比较)
    • 直到满足某个条件(不包含):Flux#takeWhile
    • 最多只取 1 个元素:
    • 给定序号:Flux#elementAt
    • 最后一个:.takeLast(1)
      • …如果为序列空则发出错误信号:Flux#last()
      • …如果序列为空则返回默认值:Flux#last(T)
    • 跳过一些元素:
    • 从序列的第一个元素开始跳过:Flux#skip(long)
      • …跳过一段时间内发出的元素:Flux#skip(Duration)
    • 跳过最后的 n 个元素:Flux#skipLast
    • 直到满足某个条件(包含):Flux#skipUntil(基于判断条件),Flux#skipUntilOther (基于对 publisher 的比较)
    • 直到满足某个条件(不包含):Flux#skipWhile
    • 采样:
    • 给定采样周期:Flux#sample(Duration)
      • 取采样周期里的第一个元素而不是最后一个:sampleFirst
    • 基于另一个 publisher:Flux#sample(Publisher)
    • 基于 publisher“超时”:Flux#sampleTimeout (每一个元素会触发一个 publisher,如果这个 publisher 不被下一个元素触发的 publisher 覆盖就发出这个元素)
  • 我只想要一个元素(如果多于一个就返回错误)…

    • 如果序列为空,发出错误信号:Flux#single()
    • 如果序列为空,发出一个缺省值:Flux#single(T)
    • 如果序列为空就返回一个空序列:Flux#singleOrEmpty

5)错误处理

  • 我想创建一个错误序列:error…

    • …替换一个完成的 Flux:.concat(Flux.error(e))
    • …替换一个完成的 Mono:.then(Mono.error(e))
    • …如果元素超时未发出:timeout
    • …“懒”创建:error(Supplier<Throwable>)
  • 我想要类似 try/catch 的表达方式:

    • 抛出异常:error
    • 捕获异常:
    • 然后返回缺省值:onErrorReturn
    • 然后返回一个 Flux 或 Mono:onErrorResume
    • 包装异常后再抛出:.onErrorMap(t -> new RuntimeException(t))
    • finally 代码块:doFinally
    • Java 7 之后的 try-with-resources 写法:using 工厂方法
  • 我想从错误中恢复…

    • 返回一个缺省的:
    • 的值:onErrorReturn
    • Publisher:Flux#onErrorResume 和 Mono#onErrorResume
    • 重试:retry
    • …由一个用于伴随 Flux 触发:retryWhen
  • 我想处理回压错误(向上游发出“MAX”的 request,如果下游的 request 比较少,则应用策略)…

    • 抛出 IllegalStateException:Flux#onBackpressureError
    • 丢弃策略:Flux#onBackpressureDrop
    • …但是不丢弃最后一个元素:Flux#onBackpressureLatest
    • 缓存策略(有限或无限):Flux#onBackpressureBuffer
    • …当有限的缓存空间用满则应用给定策略:Flux#onBackpressureBuffer 带有策略 BufferOverflowStrategy

6) 基于时间的操作

  • 我想将元素转换为带有时间信息的 Tuple2<Long, T>…

    • 从订阅时开始:elapsed
    • 记录时间戳:timestamp
  • 如果元素间延迟过长则中止序列:timeout

  • 以固定的周期发出元素:Flux#interval

  • 在一个给定的延迟后发出 0:static Mono.delay.

  • 我想引入延迟:

    • 对每一个元素:Mono#delayElement,Flux#delayElements
    • 延迟订阅:delaySubscription

7)拆分 Flux

  • 我想将一个 Flux<T> 拆分为一个 Flux<Flux<T>>:

    • 以个数为界:window(int)
    • …会出现重叠或丢弃的情况:window(int, int)
    • 以时间为界:window(Duration)
    • …会出现重叠或丢弃的情况:window(Duration, Duration)
    • 以个数或时间为界:windowTimeout(int, Duration)
    • 基于对元素的判断条件:windowUntil
    • …触发判断条件的元素会分到下一波(cutBefore 变量):.windowUntil(predicate, true)
    • …满足条件的元素在一波,直到不满足条件的元素发出开始下一波:windowWhile (不满足条件的元素会被丢弃)
    • 通过另一个 Publisher 的每一个 onNext 信号来拆分序列:window(Publisher),windowWhen
  • 我想将一个 Flux<T> 的元素拆分到集合…

    • 拆分为一个一个的 List:
    • 以个数为界:buffer(int)
      • …会出现重叠或丢弃的情况:buffer(int, int)
    • 以时间为界:buffer(Duration)
      • …会出现重叠或丢弃的情况:buffer(Duration, Duration)
    • 以个数或时间为界:bufferTimeout(int, Duration)
    • 基于对元素的判断条件:bufferUntil(Predicate)
      • …触发判断条件的元素会分到下一个buffer:.bufferUntil(predicate, true)
      • …满足条件的元素在一个buffer,直到不满足条件的元素发出开始下一buffer:bufferWhile(Predicate)
    • 通过另一个 Publisher 的每一个 onNext 信号来拆分序列:buffer(Publisher),bufferWhen
    • 拆分到指定类型的 “collection”:buffer(int, Supplier<C>)
  • 我想将 Flux<T> 中具有共同特征的元素分组到子 Flux:groupBy(Function<T,K>)(注意返回值是 Flux<GroupedFlux<K, T>>,每一个 GroupedFlux 具有相同的 key 值 K,可以通过 key() 方法获取)。

8)回到同步的世界

  • 我有一个 Flux<T>,我想:

    • 在拿到第一个元素前阻塞:Flux#blockFirst
    • …并给出超时时限:Flux#blockFirst(Duration)
    • 在拿到最后一个元素前阻塞(如果序列为空则返回 null):Flux#blockLast
    • …并给出超时时限:Flux#blockLast(Duration)
    • 同步地转换为 Iterable<T>:Flux#toIterable
    • 同步地转换为 Java 8 Stream<T>:Flux#toStream
  • 我有一个 Mono<T>,我想:

    • 在拿到元素前阻塞:Mono#block
    • …并给出超时时限:Mono#block(Duration)
    • 转换为 CompletableFuture<T>:Mono#toFuture
(4)Reactor 3快速上手——响应式Spring的道法术器 本系列其他文章见:《响应式Spring的道法术器》。 前情提要:响应式流 | lambda与函数式 1.3.2 Reactor Reactor与Spring是兄弟项目,侧重于Server端的响应式编程,主要 artifact 是 reactor-core,这是一个基于 Java 8 的实现了响应式流规范 (Reactive Streams specification)的响应... 阅读详情

相关推荐

(3)lambda与函数式——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:响应式编程 | 响应式流 1.3 Hello,reactive world 前面两篇文章介绍了响应式编程和响应式流的特性,一味讲概念终是枯燥,还是上手敲一敲代码实在感受一下响应式编程的“手感”吧。 这一节,我们先了解一下lambda与函数式(已经了解的朋友可以直接跳到1.3.2),熟悉一下如何使用Reactor...

刘康的专栏 2万+

【Reactor】学习笔记-基本概念和Mono、Flux

Reactor基本概念和Mono、Flux概述Reactor的简介使用场景 概述 JAVA8的函数式编程我们都比较熟悉,将一段对数据的操作逻辑,通过map、reduce、group、join、foreach、limit、count等算子进行表达最终得出结果,类似于Spark中提供的算子,虽然长的一样,但原理不同,而且Hadoop中也有对应的MapReduce写法,感觉也差不多的样子,现在又有了Reactor,也是一长串函数式编程的代码风格,那区别在哪里; 代码虽然看起来很像,有两点区别: 1、核心实现上

weixin_42305433的博客 4163

(11)照虎画猫深入理解响应式流规范——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:响应式流 | Reactor3快速上手 2 响应式编程之法 上一章本着“快速上手”的原则,介绍了响应式流的概念,以及Reactor 3的使用。这一章,我们基于Reactor 3的实现原理,从《响应式流规范》入手,深入了解响应式流开发库。 2.1 响应式流规范 现代软件对近乎实时地处理数据的需求越来越强烈,...

刘康的专栏 9899

03-Mono & Flux操作

上一节主要介绍了如何基于Mono和Flux构建一个数据流,Mono是Flux的特例,但大部分API 都是一致的所以重点讲的是Flux。本章将讲Flux和Mono的操作符,如 转换、过滤、异常处理、日志、Debug等一些API。 1. buffer buffer方法相当于将序列中的一部分数据收集到一个集合中,并作为一个新的流元素发送到下游。 这里看buffer的重载方法特别多啊,基本功能肯定是一样的只是多了一些附加条件。我们加单示例几种。 示例1: 指定收集的元素个数 public static void

Tong_Rui的博客 4858

Reactor响应式编程

请注意,所有事件,甚至是终止事件,都是可选的,意思是:可能没有onNext事件,但只有onComplete事件,这就表示此Flux是一个空的有限序列。如果仔细观察,程序一旦遇到一些耗时操作(特别是I/O,例如数据库请求或网络调用),就会浪费资源,因为线程(可能有很多线程)现在处于空闲状态,啥也不干,就呆呆地等待数据。调度程序具有类似于ExecutorService的调度职责,但是具有专用的抽象使其可以做更多的事情,尤其是充当时钟并启用更广泛的实现方式(测试的虚拟时间,蹦床或即时调度等)。

专注基础架构领域 1162

深入解析Project Reactor中的doOnComplete与subscribe

摘要: 本文对比了Project Reactor中doOnComplete()与subscribe()第三个参数的差异。doOnComplete()仅在数据流成功完成时触发,适用于日志记录等副作用操作;而subscribe()的第三个回调会在任何完成情况(成功或错误)下执行,适合最终处理逻辑。通过实例演示发现:当流因错误终止时,doOnComplete()不触发,但subscribe()的完成回调仍会执行。开发中应根据需求选择:若需区分成功/失败完成,用doOnComplete();若需统一处理完成事件,用

m0_62153576的博客 172

(2)响应式流——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要: 什么是响应式编程 1.2 响应式流 上一节留了一个坑——为啥不用Java Stream来进行数据流的操作? 原因在于,若将其用于响应式编程中,是有局限性的。比如如下两个需要面对的问题: Web 应用具有I/O密集的特点,I/O阻塞会带来比较大的性能损失或资源浪费,我们需要一种异步非阻塞的响应式的库,而Jav...

刘康的专栏 2万+

WangEditor 5.0版本dangerouslyInsertHtml方法的正确使用方式

WangEditor 5.0版本dangerouslyInsertHtml方法的正确使用方式

yang1067155909的专栏 4290

响应式Spring的道法术器(Spring WebFlux 教程)

Spring WebFlux 2小时快速入门 Spring 5 之使用Spring WebFlux开发响应式应用。 lambda与函数式(15min) Reactor 3 响应式编程库(60min) Spring Webflux和Spring Data Reactive开发响应式应用(45min) 通过以上内容相信可以对Spring 5.0 推出的响应式开发有了初步的体会。如果希望有更加...

刘康的专栏 4万+

论文、报告中那些乱七八糟的图(甘特图、卡吉图,桑基图,小提琴图,弦图,螺旋图,风玫瑰图)

在一些论文或报告中,总是会看到一些熟悉的图,但作者总是不能好好说话,非得搞个洋名字、缩写字或者半洋半中的词来显示它多么高大上,有时候这种故弄玄虚、华而不实的写法也实在是让人看了不伦不类,图首先是让读者更容易看懂的,不是让你来故作高深、玩玄学的。

David_jiang 9427

Python 爬取网页文字并保存为 txt 文件教程

将要爬取的网页网址赋值给变量url。

2403_89537385的博客 2789

(15)Reactor 3 Operators——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:Reactor3快速上手 | 深入理解响应式流规范 本文测试源码 2.5 Reactor 3 Operators 虽然响应式流规范中对Operator(以下均称作”操作符“)并未做要求,但是与RxJava等响应式开发库一样,Reactor也提供了非常丰富的操作符。 2.5.1 丰富的操作符 本系列...

刘康的专栏 4937

从SPI协议到文件系统:手把手教你用HAL库给W25Q16移植FATFS(附扇区管理优化方案)

本文详细介绍了如何在STM32平台上,通过HAL库的SPI接口为W25Q16 Flash芯片移植FATFS文件系统。文章从SPI通信基础讲起,深入解析了FATFS底层驱动(diskio.c)的移植要点,并重点探讨了针对W25Q16的4KB物理扇区特性进行扇区管理优化的两种方案,旨在帮助开发者构建稳定高效的文件存储方案。

happy2的博客 1043

(20)操作符熔合——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:响应式流 | Reactor3快速上手 | 深入理解响应式流规范 2.10 操作符熔合 操作符熔合是响应式编程领域比较前沿的研究话题,目的在于通过将多个操作符以某种方式熔合起来,以达到优化的效果,进而降低开销(比如执行时间,内存)。 以下部分内容参考了 Dávid Karnok 的 Operator-fus...

刘康的专栏 3900

2021-8-14 EDK II编译

2021-8-14 EDK II 编译为什么要写这篇文章新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 为什么要写这篇文章 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdo

qq_45775660的博客 2946

3、★☛基于STM32的手机通过wifi控LED灯√♠★

3、基于STM32的手机通过wifi控LED灯 文章目录3、基于STM32的手机通过wifi控LED灯1、Introduce介绍1.1、课题背景及其意义1.2、 国内外的研究状况2、方案的设计2.1、控制方案的确定2.2、控制方式的选择2.2.1、 单片机芯片的选择方案一方案二方案三方案四2.2.2、无线遥控模块的选择方案一方案二方案三3、硬件电路的设计3.1、系统的功能分析及体系结构设计3.1.1、系统功能分析3.1.2、系统总体结构3.2、模块电路的设计3.2.1、 STM32单片机核心电路设计3.2.

行走的皮卡丘 2962

(13)Reactor的backpressure策略——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:响应式流 | Reactor3快速上手 | 深入理解响应式流规范 | Reactor3自定义数据流 2.3 不同的回压策略 许多地方也叫做“背压”、“负压”,我在《Reactor参考文档》中是翻译为“背压”的,后来在看到有“回压”的翻译,忽然感觉从文字上似乎更加符合。 这一节讨论回压的问题,有两个前提:...

刘康的专栏 7407

Linux7 挂载 nfs 远程目录

每天一个 DBA 小知识,助你更进一步!

LuciferLiu_DBA 1万+

(19)Reactor Processors——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:响应式流 | Reactor3快速上手 | 深入理解响应式流规范 2.9 Processor Processor既是一种特别的发布者(Publisher)又是一种订阅者(Subscriber)。 所以你能够订阅一个Processor,也可以调用它们提供的方法来手动插入数据到序列,或终止序列。 前面一直在聊响应...

刘康的专栏 5856

YOLOv11涨点改进 | 检测头Head改进篇 | 利用DynamicConv高效动态卷积改进YOLOv11检测头,DyHead通过增强检测头操作,轻量化改进、提高模型目标检测的精度

本文提出了一种基于动态卷积(DynamicConv)的YOLOv11检测头改进方法v11Detect_DyHead。该方法通过引入多专家机制和动态权重调整,在增加参数量的同时保持较低计算复杂度,有效解决了低FLOPs模型难以从大规模预训练中获益的问题。文章详细介绍了DynamicConv模块的原理和实现,包括其参数高效特性、多专家机制和动态权重生成方式。同时提供了完整的代码实现和添加该模块的具体步骤,并给出了相应的YAML配置文件。实验表明,该方法在保持较低计算开销的同时显著提升了模型性能,适用于视觉和语言

Ai缝合怪、助力小伙伴高效发论文 534

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

(17)Reactor的调试——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:Reactor3快速上手 | 深入理解响应式流规范 本文测试源码 2.7 调试 在响应式编程中,调试是块难啃的骨头,这也是从命令式编程到响应式编程的切换过程中,学习曲线最陡峭的地方。 在命令式编程中,方法的调用关系摆在面上,我们通常可以通过stack trace追踪的问题出现的位置。但是在异步的响应式编程中...

刘康的专栏 2万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

(16)Reactor的测试——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:Reactor3快速上手 | 深入理解响应式流规范 本文测试源码 2.6 测试 在非常重视DevOps的今天,以及一些奉行TDD的团队中,自动化测试是保证代码质量的重要手段。要进行Reactor的测试,首先要确保添加reactor-test依赖。 reactor-test 用 Maven 配置 ...

刘康的专栏 7761

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

(14)Reactor调度器与线程模型——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》。 前情提要:Reactor3快速上手 | 深入理解响应式流规范 | Reactor3自定义数据流 本文测试源码 2.4 调度器与线程模型 在1.3.2节简单介绍了不同类型的调度器Scheduler,以及如何使用publishOn和subscribeOn切换不同的线程执行环境。 下边使用一个简单的例子再回忆一下: ...

刘康的专栏 9049
上一篇: (15)Reactor 3 Operators——响应式Spring的道法术器
下一篇: (16)Reactor的测试——响应式Spring的道法术器
享学IT
博客等级 码龄12年 1516粉丝 91原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值