RPC 框架 openfeign 介绍和学习使用总结
一、基本概念
RPC
远程过程调用(Remote Procedure Call)的缩写形式
Birrell 和 Nelson 在 1984 发表于 ACM Transactions on Computer Systems 的论文《Implementing remote procedure calls》对 RPC 做了经典的诠释。
RPC 是指计算机 A 上的进程,调用另外一台计算机 B 上的进程,其中 A 上的调用进程被挂起,而 B 上的被调用进程开始执行,当值返回给 A 时,A 进程继续执行。
调用方可以通过使用参数将信息传送给被调用方,而后可以通过传回的结果得到信息。而这一过程,对于开发人员来说是透明的。
openfeign 和 feign
OpenFeign 是 Spring Cloud 在 Feign 的基础上支持了SpringMVC的注解,如@RequesMapping等等。
OpenFeign 的 @FeignClient 可以解析 SpringMVC 的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
Feign 是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
Feign的使用方式是使用Feign的注解定义接口,调用这个接口就可以调用服务注册中心的服务。
OpenFeign 的设计宗旨是简化 Java Http 客户端的开发。
Feign 在 restTemplate 的基础上做了进一步的封装,由其来帮助我们定义和实现依赖服务接口的定义。
在OpenFeign的协助下,我们只需创建一个接口并使用注解的方式进行配置(类似于Dao接口上面的Mapper注解)即可完成对服务提供方的接口绑定,大大简化了Spring cloud Ribbon的开发,自动封装服务调用客户端的开发量。
OpenFeign集成了Ribbon,利用ribbon维护了服务列表,并且通过ribbon实现了客户端的负载均衡。
与 ribbon 不同的是,通过OpenFeign只需要定义服务绑定接口且以申明式的方法,优雅而简单的实现了服务调用。
二、基本使用
依赖
依赖于springMVC 的 web 服务,或者直接使用 spring-boot 的 spring-boot-starter-web 系列基础包。
web 等基础系列包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
feign 基本
${openfeign.version} 可以自定替换版本,这里示例用 2.2.2.RELEASE
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>${openfeign.version}</version></dependency><!-- okhttp openfeign远程调用依赖的HttpClient --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId><version>${feign-okhttp.version}</version></dependency>
如果出现引入后出现个别问题可以尝试去除如下
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>${openfeign.version}</version><exclusions><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency>
服务注册中心的依赖,一般场景不需要(使用分布式场景时考虑)
<!--服务发现客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
启用
spring-boot 需要在启动类上添加注解 @EnableFeignClients
位置与 @SpringBootApplication, @EnableTransactionManagement,@ComponentScan 等在启动类上的注解 位置一致
例如:

- 若同时考虑分布式场景,即 cloud 自带的 eureka
在相同的位置增加 注解 @EnableEurekaClient
同时可以在yml 或 properties 配置如下参考
eureka:client:serviceUrl:#服务中心地址defaultZone: http://localhost:8881/eureka/,http://localhost:8882/eureka/ instance:#显示ip地址prefer-ip-address: true
超时时间设置
默认超时时间为 1s
feign:client:config:default:readTimeout: ${RPC_TIME_OUT:600000}connectTimeout: ${RPC_TIME_OUT:600000}
也可以配置
# OpenFeign 默认支持 ribbon
ribbon:# 建立连接所用的时间,两端连接所用的时间ReadTimeout: 6000# 建立连接后从服务器读取到可用资源所用时间ConnectTimeout: 6000
创建请求
大致可以参考如下示例:
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;@FeignClient(name = "XxxxClient", url = "${xxxx.server}")
public interface XxxxClient {@PostMapping("/test/create")XxxxxResult createXxxxxxx(@RequestBody XxxxxxxRequest body,@RequestHeader MultiValueMap<String, String> header);@PostMapping(value = "/test/check", consumes = "multipart/form-data")XxxxxResult importXxxxx(@RequestPart("file") MultipartFile file, @RequestParam Long id,@RequestHeader MultiValueMap<String, String> header);@PostMapping("/test/config")XxxxxResult xxxxxxConfig(@RequestParam Long id, @RequestBody JSONObject body,@RequestHeader MultiValueMap<String, String> header);@PostMapping("/test/xxxxxx")XxxxxResult xxxxxXxxxxxxxx(@RequestParam Long id, @RequestBody JSONObject body, @RequestHeader MultiValueMap<String, String> header);@GetMapping("/test/xxxx/{id}")XxxxxResult xxxxXxxxx(@PathVariable String id, @RequestHeader MultiValueMap<String, String> header);}
在上面的请求中添加请求头的方式:
- 在请求注解中添加
@RequestMapping(value="/xxxxx/xxxxx",method = RequestMethod.POST,headers = {"Content-Type=application/json;charset=UTF-8"})List<String> test();
-
如上方直接在参数中增加,多个使用map ,也可以在单个参数前加 单个注解@RequestHeader(“xxxx”) 指定值
-
在方法上方使用注解
@RequestMapping(value="/xxxx/xxxxx",method = RequestMethod.POST)@Headers({"Content-Type: application/json;charset=UTF-8"})List<String> test();
- 见下方拦截器中增加请求头
说明:
1.其中 @FeignClient(name = “XxxxClient”, url = “${xxxxx.server}”)
url 中的 ${xxxxx.server} 为spring-boot 中 yml 或者 properties 中配置的地址,也可以直接写入地址 例如:http://localhost:8081/testapi
2.可以通过 @GetMapping 或 @PostMapping 直接指定将要请求的方法是 GET 或者POST 等请求,同理 @RequestParam 指定普通请求入参, @RequestHeader 指定请求的请求的头内容, @PathVariable 指定路径参数,@RequestBody 指定 请求体内容, @RequestPart 指定文件类型
3.@GetMapping 或 @PostMapping后面的路径 即为实际请求第三方或要请求的其他产品的路径
用法基本与书写普通的请求类似,具体实现通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务,只要我们指定基本的所有关键信息即可,换言之,只要知道我们要携带的信息,后续的实现写法基本固定,故此可以实现高度封装。
@SpringQueryMap注解:
spring cloud 项目使用 feign 时会发现一个问题,就是get方式无法解析对象参数。
其实 feign 是支持对象传递的,但是必须是 Map 形式,而且不能为空,与spring在机制上不兼容,因此无法使用。
spring cloud 在 2.1.x版本 中提供了**@SpringQueryMap** 注解,可以传递对象参数,框架自动解析。
例如:
@GetMapping(value = "/test/xxxxxxXxxx")XxxxxResult xxxxXxxxXxX(@SpringQueryMap BookDto dto);
@FeignClient
@FeignClient 相关属性如下:
| 属性 | 说明 |
|---|---|
| name | 指定该类的容器名称,类似于@Service(容器名称) |
| url | 即要请求的地址,可以更改指定地址 |
| decode404 | 当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException |
| configuration | Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract |
| fallback | 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口 |
| fallbackFactory | 用于生成fallback类示例,通过这个属性可以实现每个接口通用容错逻辑,减少重复代码 |
| path | 定义当前FeignClient的统一前缀,当我们项目中配置了server.context-path,server.servlet-path时使用 |
远程调用接口当中,一般我们称提供接口的服务为提供者,而调用接口的服务为消费者。
OpenFeign一定是用在消费者上。
feign 日志等级控制
Feign 提供了日志打印功能,我们可以通过配置不同级别来调整日志输出内容,从而了解 Feign 中 Http 请求的细节。
其实就是多了一个请求日志的输出控制方式。
日志级别:
| 级别名 | 说明 |
|---|---|
| NONE | 默认等级,不显示任何日志; |
| BASIC | 仅记录请求方法、URL、响应状态码及执行时间; |
| HEADERS | 除了 BASIC 中定义的信息之外,还有请求和响应的头信息; |
| FULL | 除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。 |
具体配置方式见后面的其他配置说明示例。
三、配置类
1. RequestInterceptor
可以通过自定义某一个类实现接口 RequestInterceptor(feign.RequestInterceptor) 来完成发送请求前要做的操作,例如添加统一的请求头,拼接统一参数,替换路径等等操作
例如:
该接口只有一个方法,通过接口的入参可以获取当前请求的一些信息,或者修改当前请求的一些信息
@Slf4j
public class FeignBasicRequestInterceptor implements RequestInterceptor {public FeignBasicRequestInterceptor() {}@Overridepublic void apply(RequestTemplate template) {// 可以通过获取不同的路径来确定当前请求的是那一个请求或者哪一类请求,来具体确定要执行怎样的操作// template.feignTarget().url() 获取当前请求基本路,即@FeignClient 中的url 基础路径// template.url() 获取定义请求方法时 getMapping或postMapping后的地址 // template.method() 请求的类型 GET 还是 POST// template.body() 请求体,可能为空则可以 new String(template.body()) 或给与默认值// template.headers() 请求的头信息// template.header(String name, String... values) 设置添加请求头,具体可以点击类查看源码// template.query(String name, Iterable<String> values) 设置增加query 参数}}
可能用到: 基础认证
template.header(HttpHeaders.AUTHORIZATION, okhttp3.Credentials.basic(ak, sk));
2. 指定配置类
即 上方 @FeignClient 属性中可以指定的配置类
不是必须的但可以指定,内部的几个类也可以按需增加,部分可以不要
MyX509TrustManager 为自定类,用于适配https 信任所有证书或者自定义,在后面提供定义的内容
import feign.Client;
import feign.Logger;
import feign.Retryer;
import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;import static org.apache.http.conn.ssl.SSLConnectionSocketFactory.TLS;@Slf4j
@Configuration
class FeignConfiguration {@Autowiredprivate ObjectFactory<HttpMessageConverters> messageConverters;// OkHttpClient 替代原有的client,可以不替代@Beanpublic Client feignClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {SSLContext sslContext =SSLContexts.custom().loadTrustMaterial(null, (chain, authType) -> true).setProtocol(TLS).build();SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();OkHttpClient okHttpClient = new OkHttpClient.Builder().hostnameVerifier(NoopHostnameVerifier.INSTANCE).sslSocketFactory(sslSocketFactory, new MyX509TrustManager()).build();return new feign.okhttp.OkHttpClient(okHttpClient);}@Bean// 与上方加的配置类名称一致public FeignBasicRequestInterceptor basicAuthRequestInterceptor() {return new FeignBasicRequestInterceptor();}@Bean// 日志等级 上方日志等级中提及到的Logger.Level feignLoggerLevel() {return Logger.Level.FULL;}@Bean// 重试Retryer feignRetryer() {return Retryer.NEVER_RETRY;}@Bean// 结果解码类 new FeignResponseDecoder 为自己定义的解码类,见下方定义public Decoder feignDecoder() {return new OptionalDecoder(new FeignResponseDecoder(new SpringDecoder(this.messageConverters)));}
}
日志配置后的使用,需要在配置文件中指定某一接口或者类的等级
logging:level:# feign日志以什么级别监控哪个接口com.xxx.xxx.xxx.xxx: debug
MyX509TrustManager
(可选)需要可以仿照添加
import javax.net.ssl.X509TrustManager;/*** Https调用需要使用的TrustManager*/
public class MyX509TrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {// 什么都不做则信任所有 否则自定义内容}@Overridepublic void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {// 什么都不做则信任所有 否则自定义内容}@Overridepublic java.security.cert.X509Certificate[] getAcceptedIssuers() {return new java.security.cert.X509Certificate[]{};}
}
3. feign结果自定义解析类
import feign.FeignException;
import feign.Response;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;import java.io.IOException;
import java.lang.reflect.Type;/*** feign返回结果自定义解析**/
@Slf4j
public class FeignResponseDecoder extends ResponseEntityDecoder implements Decoder {public FeignResponseDecoder(Decoder decoder) {super(decoder);}@Overridepublic Object decode(Response response, Type type) throws IOException, FeignException {Object decode = super.decode(response, type);// type.getTypeName() 最上方创建请求时 定义的返回结果的toString 结果if (type.getTypeName().contains(XxxxxResult.class.getName())) {XxxxxResult result = (XxxxxResult) decode;// 检查返回是否为对方定义的成功码 如果不是抛出异常if (!"200".equals(result.getCode())) {// 可以使用自定义异常类 这里示例使用普通异常throw new Exception(result.getMessage());}}return decode;}
}
相关文章:
RPC 框架 openfeign 介绍和学习使用总结
一、基本概念 RPC 远程过程调用(Remote Procedure Call)的缩写形式 Birrell 和 Nelson 在 1984 发表于 ACM Transactions on Computer Systems 的论文《Implementing remote procedure calls》对 RPC 做了经典的诠释。 RPC 是指计算机 A 上的进程&am…...
大厂真题:【DP/贪心】字节跳动2023秋招-小红的 01 串
题目描述与示例 题目描述 小红拿到了一个 01 串,她准备将若干个字符1 染成红色,将若干个字符0 染成蓝色,但有个限制:如果一个0 和一个1 相邻,那么它们不能同时染色。 小红想知道,最多可以染多少个字符&a…...
【技术类-01】doc转PDF程序卡死的解决方案,
摘要: 1、报错: raise AttributeError("%s.%s" % (self._username_, attr))) 2、表现:doc转PDF卡死(白条不动或出现以上英文) 3、解决:在docx保存代码行后面加上time.sleep(3) 4、…...
探索未来,开启无限可能:打造智慧应用,亚马逊云科技大语言模型助您一臂之力
文章目录 什么是大模型?大模型训练方法亚马逊云科技推出生成式AI新工具 —— aws toolkit使用教程 总结 什么是大模型? 近期,生成式大模型是人工智能领域的研究热点。这些生成式大模型,诸如文心一言、文心一格、ChatGPT、Stable …...
HTML点击链接强制触发下载
常见网页中会有很多点击链接即下载的内容,以下示范一下如何实现 <a href"文件地址" download"下载的文件名字(不包括后缀)">强制下载</a> 下面举个例子: <a href"./image/test.jpg"…...
Paimon 与 Spark 的集成(一)
Paimon Apache Paimon (incubating) 是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。Paimon 采用开放的数据格式和技术理念,可以与 ApacheFlink / Spark / Trino 等诸多业界主流计算引擎进行对接…...
批量导入SQL Server中的建表、建存储过程和建调度作业的文件
要批量导入SQL Server中的建表、建存储过程和建调度作业的文件,可以按照以下步骤进行操作: 确保你拥有适当的权限:在导入这些文件之前,请确保你具有足够的权限来创建表、存储过程和调度作业。通常需要具备数据库管理员(…...
启动Hbase出现报错
报错信息:slave1:head: cannot open/usr/local/hbase-2.3.1/bin/../logs/hbasewanggiqi-regionserver-slavel.out’ for reading: No such file or direslave2: head: cannot open/usr/local/hbase-2.3.1/bin/../logs/hbasewangqiqi-regionserver-slave2.out’ for …...
【数据结构】——栈、队列简答题模板
目录 一、栈(一)栈的基本概念(二)栈的应用(三)栈的代码实现(四)递归算法(五)栈与队列的区别 二、队列(一)队列的基本概念(…...
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 这个章节来完成并行网关与排它条件网关的功能 1、前端 目前就修改了排它条件网关的前端条件部分…...
【华为OD题库-007】代表团坐车-Java
题目 某组织举行会议,来了多个代表团同时到达,接待处只有一辆汽车,可以同时接待多个代表团,为了提高车辆利用率,请帮接待员计算可以坐满车的接待方案,输出方案数量。 约束: 1.一个团只能上一辆车࿰…...
利用servlet实现对书籍书名、单价、数量等信息的添加,计算总价
1.题目要求 利用servlet实现对书籍书名、单价、数量等信息的添加,计算总价。 要求:输入两次表单信息,在一个成功返回的页面里面显示两次的数据。 2.Book实体类 package com.hjj.sevletgk.hw7.book;/*** author:嘉佳 Date:2023/10/8 15:16*…...
一键批量转码:将MP4视频转为MP3音频的简单方法
随着数字媒体设备的普及,视频和音频格式转换的需求也越来越常见。其中,将MP4视频批量转换为MP3音频的需求尤为普遍。无论是为了提取视频中的背景音乐,还是为了在手机或电脑上方便地收听视频音频,这个过程都变得非常重要。接下来我…...
java入门,记一次微服务间feigin请求的问题
一、前言 记录工作中遇到的开发问题,而不是写博客凑字数。 二、微服务调用 1、通过本服务调用另外一个服务,需要定义一个接口,并用FeignClient 注解进行注解 value "服务名" 要调用的服务名 服务得到路径,对应的是c…...
HarmonyOS应用开发者高级认证(88分答案)
看好选择题,每个2分多答对2个刚好88分,祝你顺利。 其它帮扶选择题。 一、判断 只要使用端云一体化的云端资源就需要支付费用(错)所有使用Component修饰的自定义组件都支持onPageShow,onBackPress和onPageHide生命周期…...
离散Hopfield神经网络分类——高校科研能力评价
大家好,我是带我去滑雪! 高校科研能力评价的重要性在于它对高等教育和科研体系的有效运作、发展和提高质量具有深远的影响。良好的科研能力评价可以帮助高校识别其在不同领域的强项和薄弱点,从而制定战略,改进教学和科研ÿ…...
Run highlighted commands using IDE
背景 有时候在 IEDE 的命令行中输入命令,会弹出如下提示,或者命令被着了背景色了,是怎么回事? 其实就是提示你可以使用 IDEA 的功能替代命令行。比如使用ctrlenter或cmdenter之后使用的就是 IDEA 里的功能 直接enter运行&#x…...
vscode文件跳转(vue项目)
在 .vue 文件中,点击组件名打开 方式1: 在 vue 组件名上,桉住ctrl 鼠标左键 // 重新打开一个tab 方式2: 在 vue 组件名上,桉住ctrl shift 鼠标左键 // 在右侧拆分,并打开一个tab .vue文件的跳转 按住 …...
嵌入式Linux系统中内存分配详解
Linux中内存管理 内存管理的主要工作就是对物理内存进行组织,然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。 虚拟地址的作用 如果用户进程直接操作物理地址会有以下的坏处: 1、 用户进程可以直接操作内核对应的内存,破坏…...
4、FFmpeg命令行操作4
ffplay命令-高级选项1 选项 说明 -stats 打印多个回放统计信息,包括显示流持续时间,编解码器参数,流中的当前位置,以及音频/视频同步差值。默认情况下处于启用状态,要显式禁用它则需要指定-nostats。。 -fast 非标准化规范的多媒体兼容优化。 -genpts 生…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
