52、基于函数式方式开发 Spring WebFlux 应用

★ Spring WebFlux的两种开发方式

1. 采用类似于Spring MVC的注解的方式来开发。此时开发时感觉Spring MVC差异不大,但底层依然是反应式API。2. 使用函数式编程来开发

★ 使用函数式方式开发Web Flux

使用函数式开发WebFlux时需要开发两个组件:

▲ Handler:作用:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应。该Handler组件的每个方法都只带一个ServerRequest参数(不是Servlet API)——代表客户端请求对象,且每个方法的返回值类型都是Mono<ServerResponse>,代表作为服务器响应的消息发布者。mono 代表一个消息发布者▲ Router:作用:该组件通过函数式的编程方式来定义URL与Handler处理方法之间的映射关系。

★ WebFlux通过ServerRequest获取请求数据的两种方式:

这两种方式并不是可以自由选择的,而是根据数据的来源不同,需要采用对应的获取策略。- 对于以请求体提交的数据,通常会通过formData()(表单数据)或bodyToFlux()或bodyToMono()(RESTful)方法来获取,由于这种方式都需要通过网络IO读取数据,可能会造成阻塞,因此它们都采用了订阅-发布的异步方式,这三个方法的返回值都是Mono或Flux(消息发布者)。- 对于URL中的数据(包括传统请求参数和路径参数),由于它们只要直接解析URL字符串即可读取数据,不会造成阻塞,因此没有采用订阅-发布的异步方式。直接用pathVariable()或queryParam()方法即可读取数据。

★ Handler方法的返回值

Handler作用: 该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应。

Handler处理方法的返回值类型是Mono<ServerResponse>,
调用ServerResponse的ok()(相当于将响应状态码设为200)、
contentType()方法返回ServerResponse.BodyBuilder对象。
有了ServerResponse.BodyBuilder对象之后,根据响应类型不同,
可调用如下两个方法来生成Mono<ServerResponse>作为返回值:▲ render(String name, Map<String,?> model):使用模板引擎来生成响应,其中第一个参数代表逻辑视图名,第二个参数代表传给模板的model数据。render()方法还有其他重载形式,功能类似。▲ body(P publisher, Class<T> elementClass):直接设置响应体类生成响应,同样用于生成RESTful响应。body()方法还有其他重载形式,功能类似。

★ 使用Router定义URL与Handler方法的对应关系

Router作用: 该组件通过函数式的编程方式来定义URL与Handler处理方法之间的映射关系。

 ▲ Router就是容器中RouterFunctions类型的Bean。——通常来说,就是使用@Configuration修饰的配置类来配置该Bean即可。return RouterFunctions// 定义映射地址和处理器方法之间的对应关系.route(RequestPredicates.POST("/login").and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::login).andRoute(RequestPredicates.GET("/viewBook/{id}").and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::viewBook);

代码演示:

同个请求,演示跟 spring mvc 不同的实现方法。

请求的数据是简单的url数据,就是前端传来的数据(id)是写在url 的。

总结:通过添加 Handler 类,相当于之前的controller ,然后创建一个 Router 配置类,通过在配置类 配置 Router Bean 这个bean,来实现对客户端请求来的URL 与 Handler处理方法之间的映射关系。最终响应回json格式的数据或者 html 页面。

Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件

现在弄一个 Handler 类,用来处理客户端的请求,是一个处理数据的类,相当于controller

这个方法是生成 RESTful 响应的,就是 Json 响应
在这里插入图片描述
这个方法是生成 HTML 响应的
在这里插入图片描述

Router:作用:该组件通过函数式的编程方式来定义URL与Handler处理方法之间的映射关系。

配置 Router Bean ,负责完成请求 URL 和 Handler 处理方法之间的映射。

设置方法的请求路径是 “/viewBookabc/{id}” ,走这个路径就会访问这个 handler::viewBook 方法。
而 handler::viewBooks 是 lambda 中的方法引用 ,会找到 BookHandler 类中的 viewBook 方法

bean 方法里面的参数是 BookHandler,所以可以用 lambda 的方法引用功能 来引用该类的viewBook方法。

负责完成 【请求URL】 和 【Handler处理方法】 之间的映射。

Handler处理方法:就是 BookHandler 的 viewBook 方法。
在这里插入图片描述

返回响应给html的页面
在这里插入图片描述

这个bean在项目启动的时候就会被加载。
在这里插入图片描述

调用方法看看流程:
访问方法,就会走 BookHandler 的 这个方法。
在这里插入图片描述

测试结果:

在这里插入图片描述

完整代码:

BookHandler

// Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件
@Component
public class BookHandler
{private BookService bookService;//有参构造器完成依赖注入public BookHandler(BookService bookService){this.bookService = bookService;}// Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件//这个方法是生成 RESTful 响应的public Mono<ServerResponse> viewBook(ServerRequest request){//如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数Integer id = Integer.parseInt(request.pathVariable("id"));Book book = bookService.getBook(id);//ok()  表示服务器响应正常Mono<ServerResponse> body = ServerResponse.ok()//选择生成 JSON 响应类型.contentType(MediaType.APPLICATION_JSON)//如果要生成 JSON 响应,直接用 body 方法//参数1:代表数据发布者(Publisher),参数2:指定 Mono 中每个数据项的类型//Mono 的 justOrEmpty 将单个及可能为null的数据包装成 Mono//如果是设计良好的应用(就是底层数据库的访问也是用 reactor api ,// 这样此处从数据库返回的数据就是 Mono 或者 Flux,根本不需要包装).body(Mono.justOrEmpty(book), Book.class);return body;}//这个方法是生成 HTML 响应的public Mono<ServerResponse> viewBookHtml(ServerRequest request){//如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数Integer id = Integer.parseInt(request.pathVariable("id"));Book book = bookService.getBook(id);//ok()  表示服务器响应正常Mono<ServerResponse> render = ServerResponse.ok()//选择生成 HTML 响应类型.contentType(MediaType.TEXT_HTML)//参数1:逻辑视图名   参数2:相当于 spring mvc 的 model,用于向视图页面传输数据.render("viewBook", Map.of("book", book));return render;}
}

RouterConfig

package cn.ljh.FunctionalFlux.router;import cn.ljh.FunctionalFlux.handler.BookHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;@Configuration //配置类
public class RouterConfig
{//配置 Router Bean ,负责完成请求 URL 和 Handler 处理方法之间的映射。@Beanpublic RouterFunction<ServerResponse> routerFunctions(BookHandler handler){//MediaType.APPLICATION_JSON 设置响应类型 ,  handler::viewBooks  是 lambda 中的方法引用RouterFunction<ServerResponse> route =RouterFunctions//这里就映射到 BookHandler 类里面的 viewBook 方法,/viewBookabc/{id}这个是我们这边给的访问路径.route(RequestPredicates.GET("/viewBookabc/{id}").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::viewBook)//这里就映射到 BookHandler 类里面的 viewBookHtml 方法,/viewBookHtml/{id}这个是我们这边给的访问路径.andRoute(RequestPredicates.GET("/viewBookHtml/{id}").and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::viewBookHtml);return route;}
}

上面的代码演示,请求的数据是简单的url数据,就是前端传来的数据(id)是写在url 的。

这次演示的是前端以 表单 的方式 或 restful 方式提交数据。

演示:以 RESTful 方式提交的数据的处理

这边接收前端传来的数据并进行处理,相当于controller
在这里插入图片描述

这里的bean就是处理 请求url 和 handler处理方法 之间的映射关系
在这里插入图片描述

测试结果:
成功处理添加书本的方法,添加的书本的数据在postman中实现。
在这里插入图片描述

演示:通过表单页面提交请求

写一个简单的表单页面
在这里插入图片描述

前端通过表单页面提交请求
在这里插入图片描述

添加 请求 URL 和 Handler 处理方法之间的映射
在这里插入图片描述

测试结果:

注意:发现因为 handler处理方法那里,因为使用了map ,把源 Mono 转成新的 Mono,当时转换的结果没去用它,所以出现添加不成功的问题。

如图:
如果不需要使用 Mono 转换之后的结果,此时就不需要使用 map() 方法
map() 方法就是负责将 源Mono 转换成新的 Mono
如果只是希望用到 Mono 中的数据,此时成为消费数据,
就是把这条消息消费掉就行,因为不需要把 Mono 的结果返回到视图页面,所以不需要用map方法进行转换。
在这里插入图片描述

测试成功:
成功通过表单页面提交请求
在这里插入图片描述

前端注意小知识:

在 templates 路径下的静态页面是不能直接访问的,得通过控制器的处理方法进行转发才能访问到。
或者直接把页面放在静态资源目录(static、public),才能直接访问。
注意:页面得是静态页面,不能有动态内容,不能是动态页面。

在这里插入图片描述

完整代码:

domain
在这里插入图片描述

处理类:BookHandler,类似于controller

package cn.ljh.FunctionalFlux.handler;import cn.ljh.FunctionalFlux.domain.Book;
import cn.ljh.FunctionalFlux.service.BookService;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.time.Duration;
import java.util.Collection;
import java.util.Map;// Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件
@Component
public class BookHandler
{private BookService bookService;//有参构造器完成依赖注入public BookHandler(BookService bookService){this.bookService = bookService;}// Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件//这个方法是生成 RESTful 响应的 ,就是 Json 响应public Mono<ServerResponse> viewBook(ServerRequest request){//如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数Integer id = Integer.parseInt(request.pathVariable("id"));Book book = bookService.getBook(id);//ok()  表示服务器响应正常Mono<ServerResponse> body = ServerResponse.ok()//选择生成 JSON 响应类型.contentType(MediaType.APPLICATION_JSON)//如果要生成 JSON 响应,直接用 body 方法//参数1:代表数据发布者(Publisher),参数2:指定 Mono 中每个数据项的类型//Mono 的 justOrEmpty 将单个及可能为null的数据包装成 Mono//如果是设计良好的应用(就是底层数据库的访问也是用 reactor api ,// 这样此处从数据库返回的数据就是 Mono 或者 Flux,根本不需要包装).body(Mono.justOrEmpty(book), Book.class);return body;}//这个方法是生成 HTML 响应的public Mono<ServerResponse> viewBookHtml(ServerRequest request){//如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数Integer id = Integer.parseInt(request.pathVariable("id"));Book book = bookService.getBook(id);//ok()  表示服务器响应正常Mono<ServerResponse> render = ServerResponse.ok()//选择生成 HTML 响应类型.contentType(MediaType.TEXT_HTML)//参数1:逻辑视图名   参数2:相当于 spring mvc 的 model,用于向视图页面传输数据.render("viewBook", Map.of("book", book));return render;}//以 RESTful 方式提交的数据的处理public Mono<ServerResponse> addBook(ServerRequest request){//假设数据来自 RESTful 的 POST 请求,此时用 bodyToMono() 或 bodyToFlux() 来获取数据//bodyToFlux():如果请求的数据中包含多个数据,就用这个。//bodyToMono():如果请求的数据只有一个数据,那就用这个//这两个方法参数指定了 Mono 或 Flux 中数据的类型// 添加一本图书,只是一个对象,所以用.bodyToMono() ,// 如果是一个集合,就应该使用 .bodyToFlux()Mono<Book> bookMono = request.bodyToMono(Book.class);//map() 负责将 Mono 或者 Flux 中的元素,转换成新的 Mono 或 Flux 中的元素Mono<Book> resultMono = bookMono.map(book ->{//添加 Book 对象bookService.addBook(book);return book;});Mono<ServerResponse> body = ServerResponse.ok()//选择生成 JSON 响应类型.contentType(MediaType.APPLICATION_JSON)//如果要生成 JSON 响应,直接用 body 方法//参数1:代表数据发布者(Publisher),参数2:指定 Mono 中每个数据项的类型//Mono 的 justOrEmpty 将单个及可能为null的数据包装成 Mono//如果是设计良好的应用(就是底层数据库的访问也是用 reactor api ,// 这样此处从数据库返回的数据就是 Mono 或者 Flux,根本不需要包装).body(resultMono, Book.class);return body;}//通过表单页面提交请求public Mono<ServerResponse> addBookHtml(ServerRequest request){//假设数据来自 表单页面 的 POST 请求,通过 formData() 获取表单的数据Mono<MultiValueMap<String, String>> formData = request.formData();/** 如果不需要使用 Mono 转换之后的结果,此时就不需要使用 map() 方法* map() 方法就是负责将 源Mono 转换成新的 Mono* 如果只是希望用到 Mono 中的数据,此时成为消费数据*/formData.subscribe(map ->{String name = map.get("name").get(0);String price = map.get("price").get(0);String author = map.get("author").get(0);Book book = new Book(null, name, Double.parseDouble(price), author);bookService.addBook(book);});Mono<ServerResponse> render = ServerResponse.ok()//选择生成 JSON 响应类型.contentType(MediaType.TEXT_HTML).render("addBookResult", Map.of("tip", "添加书籍成功"));return render;}}

配置类:RouterConfig,添加个bean处理url和handler类中的方法的映射关系

package cn.ljh.FunctionalFlux.router;import cn.ljh.FunctionalFlux.handler.BookHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;@Configuration //配置类
public class RouterConfig
{//配置 Router Bean ,负责完成请求 URL 和 Handler 处理方法之间的映射。@Beanpublic RouterFunction<ServerResponse> routerFunctions(BookHandler handler){//MediaType.APPLICATION_JSON 设置响应类型 ,  handler::viewBooks  是 lambda 中的方法引用RouterFunction<ServerResponse> route =RouterFunctions//这里就映射到 BookHandler 类里面的 viewBook 方法,/viewBookabc/{id}这个是我们这边给的访问路径.route(RequestPredicates.GET("/viewBookabc/{id}").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::viewBook)//这里就映射到 BookHandler 类里面的 viewBookHtml 方法,/viewBookHtml/{id}这个是我们这边给的访问路径.andRoute(RequestPredicates.GET("/viewBookHtml/{id}").and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::viewBookHtml)//这里就映射到 BookHandler 类里面的 addBook 方法,/addBook 这个是我们这边给的访问路径.andRoute(RequestPredicates.POST("/addBook").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::addBook)//这里就映射到 BookHandler 类里面的 addBookHtml 方法,/addBookHtml/{id}这个是我们这边给的访问路径.andRoute(RequestPredicates.POST("/addBookHtml").and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::addBookHtml);return route;}
}

BookService

package cn.ljh.FunctionalFlux.service;import cn.ljh.FunctionalFlux.domain.Book;
import java.util.Collection;public interface BookService
{Book getBook(Integer id);Integer addBook(Book book);Collection<Book> getAllBooks();
}

BookServiceImpl

package cn.ljh.FunctionalFlux.service.impl;import cn.ljh.FunctionalFlux.domain.Book;
import cn.ljh.FunctionalFlux.service.BookService;
import org.springframework.stereotype.Service;import java.util.*;//添加这个@Service注解,springboot就可以自动扫描这个Service组件的实现类,然后把这个类部署成容器中的bean。
@Service
public class BookServiceImpl implements BookService
{//添加一个 Map 集合,假设为数据库public static final Map<Integer, Book> bookDB = new LinkedHashMap<>();//创建一个自增idstatic int nextId = 4;//初始化这个数据库static{bookDB.put(1, new Book(1, "火影忍者", 100.0, "岸本"));bookDB.put(2, new Book(2, "家庭教师", 110.0, "天野明"));bookDB.put(3, new Book(3, "七龙珠Z", 120.0, "鸟山明"));}//查看图书@Overridepublic Book getBook(Integer id){Book book = bookDB.get(id);if (book == null){throw new RuntimeException("没有此图书信息!");}return book;}//添加图书@Overridepublic Integer addBook(Book book){book.setId(nextId);bookDB.put(nextId,book);//返回id,先返回在自增。return nextId++;}//查看所有的图书@Overridepublic Collection<Book> getAllBooks(){//获取集合中的所有元素Collection<Book> values = bookDB.values();return values;}
}

添加图书页面:addBook.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>添加图书页面</title>
</head>
<body>
<h2>添加图书页面</h2><form method="post" action="/addBookHtml">书名:<input name="name"  id="name" type="text"><br>价格:<input name="price"  id="price" type="text"><br>作者:<input name="author"  id="author" type="text"><br><input type="submit" value="提交"/><input type="reset" value="重设"/>
</form>
</body>
</html>

添加图书结果页面:addBookResult.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>添加图书结果</title>
</head>
<body>
<h2>添加图书结果</h2>
<div th:text="${tip}">
</div>
</body>
</html>

根据id查询图书:viewBook.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>查看图书</title>
</head>
<body>
<h2>查看图书</h2>
<div th:text="${book.name}"></div>
<div th:text="${book.price}"></div>
<div th:text="${book.author}"></div></div>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/72936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一.使用qt creator 设计显示GUI

一.安装qt creator 二.创建项目 文件-》新建项目 三.使用设计 可以直接使用鼠标拖拽 四.转换为py文件 # from123.py 为导出 py文件的文件名 form.ui 为 qt creator创造的 ui 文件 pyuic5 -o x:\xxx\from123.py form.ui五.显示GUI from PyQt5.QtWidgets import * fr…

Android高通 8.1 老化apk打开摄像头花屏问题

1、最近由于公司VR 3D系统要做双Camera老化测试apk&#xff0c;同时老化4小时需要轮询切换二个摄像头&#xff0c;保证后面camera标定精度数据更准确。 2、一开始我尝试用之前方案移植过去然后同时打开双摄像头 突然发现花屏 如下图所示 3、于是一第一时间想到是不是分辨率不兼…

在UI设计中用什么样的字体?优漫动游

在windos下支持的字体 在UI设计中用什么样的字体&#xff1f; 宋体&#xff08;simsun&#xff09;&#xff1a;在win下大部分的浏览器是默认的&#xff0c;适合小字号&#xff0c;不太适合大字号。 微软雅黑&#xff1a;是目前win浏览器中最值得使用的。 Arial&#…

算法通关村——滑动窗口高频问题

1. 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 1.1 滑动窗口 找到最长字串需要找到字串的首尾位置…

c++保留n位小数输出(百分数形式,保留n位有效数字,设置宽度)

在C中&#xff0c;你可以使用 头文件中的一些函数和控制符来控制输出的小数位数、百分数形式以及设置宽度。下面我将详细讲解如何实现这些功能。 控制小数位数 若要在输出中控制小数位数&#xff0c;你可以使用 std::setprecision 函数。这个函数接受一个整数参数&#xff0c…

多组背包恰好装满方案数

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 现在有一个大小n*1的收纳盒&#xff0c;我们手里有无数个大小为1*1和2*1的小方块&#xff0c;我们需要用这些方块填满收纳盒&#xff0c;请问我们有多少种不同的方法填满这个收纳盒 分析&…

关于 Unity 连接 MuMu 模拟器上的 Unity Remote 5 的方法

在使用 Unity 开发 Android 的过程中&#xff0c;可以通过使用 Unity Remote 这个 app 来和真机连接&#xff0c;进而在真实环境下进行测试性能等工作&#xff0c;而本次则是由于其他问题引出的一个小坑&#xff0c;记录以备后续查询。 这次是由于在自学过程中遇到的一个工程&…

MyBatisPlus枚举类最佳实践(非常典型和高效的枚举类写法)

目录 1、MyBatisPlus枚举类最佳实践 2、枚举类的作用及问题 3、MyBatisPlus注解实现枚举最佳实践 4、简单来说 5、下面我们看一个使用上述注解的完整枚举类示例: &#xff08;1&#xff09;枚举类&#xff1a; &#xff08;2&#xff09;DTO类&#xff1a; 6、根据上面…

Python - 队列【queue】task_done()和join()基本使用

一. 前言 task_done()是Python中queue模块提供的方法&#xff0c;用于通知队列管理器&#xff0c;已经处理完了队列中的一个项目。 queue.task_done()是Queue对象的一个方法&#xff0c;它用于通知Queue对象&#xff0c;队列中的某一项已经被处理完毕。通常在使用Queue对象时…

异步编程 - 13 高性能线程间消息传递库 Disruptor

文章目录 Disruptor概述Disruptor中的核心术语Disruptor 流程图 Disruptor的特性详解基于Disruptor实现异步编程 Disruptor概述 Disruptor是一个高性能的线程间消息传递库&#xff0c;它源于LMAX对并发性、性能和非阻塞算法的研究&#xff0c;如今构成了其Exchange基础架构的核…

探究IP路由的工作原理与路由表查找规则

文章目录 一、定义二、IP连通的前提三、路由表1. 作用2. 路由表字段内容3. 路由表查表规则4. 路由信息的来源5. 路由表写表规则6. 路由优先级 四、常用命令 首先可以看下思维导图&#xff0c;以便更好的理解接下来的内容。 一、定义 路由器是网络中负责将数据报文在不同IP网段…

git在linux情况下设置git 命令高亮

只需要执行下面这个命令&#xff0c;这样就可以在查看git status明亮的时候高亮显示。 git config --global color.status auto未设置前 谁知之后

linux中常见服务端安装

linux安装服务脚本 1、yum安装 # 通过apt安装yum apt install yum # yum安装软件 yum install pam-devel # yum 卸载 yum remove pam-devel2、rpm安装 # 安装 rpm -i example.rpm #安装 example.rpm 包&#xff1b; rpm -iv example.rpm #安装 example.rpm 包并在安装过程…

【Unity3D赛车游戏优化篇】【八】汽车实现镜头的流畅跟随,以及不同角度的切换

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

Redis功能实战篇之附近商户

在互联网的app当中&#xff0c;特别是像美团&#xff0c;饿了么等app。经常会看到附件美食或者商家&#xff0c; 当我们点击美食之后&#xff0c;会出现一系列的商家&#xff0c;商家中可以按照多种排序方式&#xff0c;我们此时关注的是距离&#xff0c;这个地方就需要使用到我…

高等数学笔记

|sinx|连续不可导 只要在x0处存在极限且极限等于f(x0)则函数在此处连续 如果某点可导则左右导数应该相等&#xff08;可导一定连续&#xff0c;连续不一定可导&#xff09; 双曲函数的由来 塞入dx 莱布尼茨公式 sin(nx)的k次导n^k*sin(nxkΠ/2) 注意符号&#xff01; 二阶导公…

Golang源码分析

Golang源码分析 Golang源码分析-builtin.goGolang源码分析-bytes.goGolang源码分析-bytes/buffer.goGolang源码分析-bytes/reader.goGolang源码分析-strings.goGolang源码分析-strings builder.goGolang源码分析-strconv包Golang源码分析-io.goGolang源码分析-io/pipe.goGolan…

树的基本概念和存储结构

一、树的基本概念 1、树的定义 树是n&#xff08;n>0&#xff09;个结点的有限集。当n 0时&#xff0c;称为空树。在任意一棵非空树中应满足&#xff1a; 1、有且仅有一个特定的称为根的结点。 2、当n>1时&#xff0c;其余节点可分为m&#xff08;m>0&#xff09…

中移粤港澳大湾区创新研究院、南湖研究院类脑实验室面试(部分)

中移粤港澳大湾区创新研究院 reids热key的高并发量&#xff0c;导致此redis节点的cpu使用率爆满&#xff0c;有什么优化方案&#xff1f;高并发情况下为了保证平台正常运行&#xff0c;怎么设置平台的监控和告警 南湖研究院类脑实验室 笔试通过后&#xff0c;面试无后续

Zookeeper简述

数新网络-让每个人享受数据的价值 官网现已全新升级—欢迎访问&#xff01; 前 言 ZooKeeper是一个开源的、高可用的、分布式的协调服务&#xff0c;由Apache软件基金会维护。它旨在帮助管理和协调分布式系统和应用程序&#xff0c;提供了一个可靠的平台&#xff0c;用于处理…