当前位置: 首页 > news >正文

springcloud集成seata实现分布式事务

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

官网:Apache Seata

文章目录

  • 一、部署
    • 1.下载
    • 2.修改配置,nacos作注册中心,db存储
  • 二、集成到springcloud项目
    • 1.引入依赖
    • 2.修改配置
    • 3.新建数据表
    • 4.编写代码
    • 5.测试结果

一、部署

由于网络问题一直拉取docker镜像失败,所以这里采用了下载zip包直接部署的方式

版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub (需要和springcloud的版本对应)

1.下载

直接部署 | Apache Seata

上传服务器并解压

在这里插入图片描述

2.修改配置,nacos作注册中心,db存储

修改conf/application.yml

server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 192.168.100.52:4560kafka-appender:bootstrap-servers: 192.168.100.52:9092topic: logback_to_logstashconsole:user:username: seatapassword: seataseata:config:# support: nacos, consul, apollo, zk, etcd3type: nacosnacos:server-addr: 192.168.100.53:8848namespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466cgroup: spmp-systemusername: nacospassword: nacosdata-id: seataServer.propertiesregistry:# support: nacos, eureka, redis, zk, consul, etcd3, sofatype: nacosnacos:application: seata-serverserver-addr: 192.168.100.53:8848group: spmp-systemnamespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466c# tc集群名称cluster: defaultusername: nacospassword: nacos
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

此时启动seata服务端,已经可以在nacos服务列表看到seata-server服务

cd bin
sh seata-seaver.sh

在这里插入图片描述

然后在nacos新建配置文件seataServer.properties

在这里插入图片描述

store.mode=db
store.db.dbType=mysql
store.db.datasource=druid
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://192.168.100.52:3306/seata?characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai
store.db.user=seata
store.db.password=seata

这里注意先建数据库seata,然后执行建表sql,脚本在script/server/db/下的mysql.sql

在这里插入图片描述

然后重启seata服务端

可以从seata启动日志 logs/start.out 看到读取配置的相关信息

在这里插入图片描述

二、集成到springcloud项目

这里我们拿项目里其中两个微服务来测试,如图所示,服务1被调用方服务2调用方

在这里插入图片描述

1.引入依赖

两个微服务的pom文件里都需要引入seata依赖

<dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.6.1</version>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>2021.0.5.0</version><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions>
</dependency>

2.修改配置

修改两个微服务的配置文件,这里对应上前面seata服务端的配置

seata:registry:type: nacosnacos:application: seata-serverserver-addr: 192.168.100.53:8848group: spmp-systemnamespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466cusername: nacospassword: nacosconfig:type: nacosnacos:server-addr: 192.168.100.53:8848group: spmp-systemnamespace: 17a4ea5e-f549-4e4a-97a4-52ee2a9f466cdataId: seataServer.propertiesusername: nacospassword: nacostx-service-group: spmp-system

3.新建数据表

两个服务都需要新建undo_log表,在事务回滚时需要用到,建表sql:

CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,`ext` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

4.编写代码

  • 修改全局异常处理器GlobalExceptionHandler

    由于项目里的全局处理器通常都会将所有异常拦截,然后返回统一封装结果,而这会导致异常无法抛出

    /*** 全局异常处理器** @author ruoyi*/
    @RestControllerAdvice
    public class GlobalExceptionHandler {private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 先判断是否是seata全局事务异常,如果是,就直接抛给调用方,让调用方回滚事务* @param e* @throws Exception*/private void checkSeataError(Exception e) throws Exception {log.info("seata全局事务ID: {}", RootContext.getXID());// 如果是在一次全局事务里出异常了,就不要包装返回值,将异常抛给调用方,让调用方回滚事务if (StrUtil.isNotBlank(RootContext.getXID())) {throw e;}}/*** 请求方式不支持*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("请求地址'{}',不支持'{}'请求", requestUri, e.getMethod());return AjaxResult.error(e.getMessage());}/*** 业务异常*/@ExceptionHandler(ServiceException.class)public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) throws Exception {checkSeataError(e);log.error(e.getMessage(), e);Integer code = e.getCode();return StringUtils.isNotNull(code) ? AjaxResult.error(code, StrUtil.isEmpty(e.getMessage()) ? e.getCause().getMessage() : e.getMessage()) : AjaxResult.error(StrUtil.isEmpty(e.getMessage()) ? e.getCause().getMessage() : e.getMessage());}/*** 请求参数类型不匹配*/@ExceptionHandler(MethodArgumentTypeMismatchException.class)public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();String value = Convert.toStr(e.getValue());if (StringUtils.isNotEmpty(value)) {value = EscapeUtil.clean(value);}log.error("请求参数类型不匹配'{}',发生系统异常.", requestUri, e);return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));}/*** 切面异常统一捕获*/@ExceptionHandler(AspectException.class)public ResponseResult<?> handleAspectException(AspectException aspectException) {aspectException.printStackTrace();return ResponseResult.error(aspectException.getResultStatus(), null);}/*** 系统基类异常捕获*/@ExceptionHandler(BasesException.class)public ResponseResult<?> handleBasesException(BasesException basesException) throws Exception {checkSeataError(basesException);basesException.printStackTrace();return ResponseResult.error(basesException.getResultStatus(), null);}/*** 拦截未知的运行时异常*/@ExceptionHandler(RuntimeException.class)public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("请求地址'{}',发生未知异常.", requestUri, e);return AjaxResult.error(e.getMessage());}/*** 系统异常*/@ExceptionHandler(Exception.class)public AjaxResult handleException(Exception e, HttpServletRequest request) throws Exception {checkSeataError(e);String requestUri = request.getRequestURI();log.error("请求地址'{}',发生系统异常.", requestUri, e);return AjaxResult.error(e.getMessage());}/*** 自定义验证异常*/@ExceptionHandler(BindException.class)public AjaxResult handleBindException(BindException e) throws Exception {checkSeataError(e);log.error(e.getMessage(), e);String message = e.getAllErrors().get(0).getDefaultMessage();return AjaxResult.error(message);}/*** 自定义验证异常*/@ExceptionHandler(MethodArgumentNotValidException.class)public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) throws Exception {checkSeataError(e);log.error(e.getMessage(), e);String message = e.getBindingResult().getFieldError().getDefaultMessage();return ResponseResult.error(message);}/*** 内部认证异常*/@ExceptionHandler(InnerAuthException.class)public AjaxResult handleInnerAuthException(InnerAuthException e) throws Exception {checkSeataError(e);return AjaxResult.error(e.getMessage());}......
    }
    
  • 修改Feign熔断降级方法

    由于项目对远程调用接口还做了熔断降级操作,导致调用方仍然识别不到异常,所以这里将熔断降级方法修改下,让其能正常抛异常

    @Component
    @Slf4j
    public class ConstructionProviderFallback implements IConstructionProvider {@Overridepublic ResponseResult<String> testSeata(Boolean error) {if (error) {throw new RuntimeException("降级方法中---模拟被调用方异常");}return ResponseResult.success("----------------testSeata接口远程调用熔断-----------------");}
    }
    
  • 启动类增加AOP注解

    由于全局事务注解@GlobalTransactional底层是基于AOP实现,所以需要给两个服务的启动类都加上AOP注解

    @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)

  • 调用方测试接口

    /*** 测试全局事务* @return*/
    @ApiOperation("测试全局事务")
    @GetMapping("/testSeata")
    @ApiImplicitParam(name = "type", value = "1:模拟调用方异常 其他:模拟被调用方异常")
    public ResponseResult<Boolean> testSeata(@RequestParam Integer type) {SecurityTest securityTest = new SecurityTest();securityTest.setTestColumn("测试全局事务");securityTest.setOrganizeId(1L);return ResponseResult.success(testSeataService.testSeata(type,securityTest));
    }
    
    @GlobalTransactional
    @Override
    public Boolean testSeata(Integer type, SecurityTest securityTest) {log.info("seata全局事务ID: {}", RootContext.getXID());if (type!=null&&type==1) {//先远程调用construction服务保存远程服务数据constructionProvider.testSeata(false);//再保存自己服务数据securityTestService.save(securityTest);//模拟调用方异常throw new RuntimeException("模拟调用方异常");} else {//先保存自己服务数据securityTestService.save(securityTest);//再远程调用construction服务保存远程服务数据,且模拟被调用方异常constructionProvider.testSeata(true);}return true;
    }
    

    这里测试两种情况,调用方异常事务回滚,还有被调用方异常事务回滚

  • 被调用方提供的Feign接口

    @Service(value = "IConstructionProvider")
    @FeignClient(value = ConstructionProviderConstant.MATE_CLOUD_CONSTRUCTION, fallback = ConstructionProviderFallback.class)
    public interface IConstructionProvider {/*** 测试全局事务* @param error* @return*/@GetMapping(ConstructionProviderConstant.TEST_SEATA)ResponseResult<String> testSeata(@RequestParam("error") Boolean error);}
    

    这里当时遇到了一个坑

    • 如果不写@RequestParam(“error”) ,会识别成POST请求,然后报错不支持POST请求

    • 如果写了@RequestParam,但是没设置value属性,即写@RequestParam Boolean error,也会报错

      参考:Feign 调用报 RequestParam.value() was empty on parameter 0-CSDN博客

    实现:

    在这里插入图片描述

    正常调用:

    /*** 测试Seata全局事务* @param error 是否模拟被调用方异常* @return*/
    @Override
    @ApiOperation(value = "测试Seata全局事务", notes = "测试Seata全局事务", httpMethod = "GET")
    @GetMapping(ConstructionProviderConstant.TEST_SEATA)
    @SentinelResource(value = ConstructionProviderConstant.TEST_SEATA, fallbackClass = ConstructionProviderFallback.class, fallback = "testFeign")
    public ResponseResult<String> testSeata(@RequestParam(value = "error") Boolean error) {SecurityTest1 test = new SecurityTest1();test.setTestColumn("seata");test.setOrganizeId(1L);securityTestService.save(test);if (error) {throw new RuntimeException("模拟被调用方异常");}return ResponseResult.success("---------------testSeata接口正常------------------");
    }
    

    熔断降级:

    @Override
    public ResponseResult<String> testSeata(Boolean error) {if (error) {throw new RuntimeException("降级方法中---模拟被调用方异常");}return ResponseResult.success("----------------testSeata接口远程调用熔断-----------------");
    }
    

5.测试结果

分别测试了调用方异常、被调用方异常的情况,均能实现全局事务回滚(两边的数据库都回滚了),如下图所示

在这里插入图片描述

在这里插入图片描述

下面是seata控制台的信息(存于数据库里)

在这里插入图片描述

这里我测试的结果是 只有调用方和被调用方都有事务回滚 才会有信息,而且会定期清除

相关文章:

springcloud集成seata实现分布式事务

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 官网&#xff1a;Apache Seata 文章目录 一、部署1.下载2.修改配置&#xff0c;nacos作注册中心&#xff0c;db存储 二、集成到springcloud项目1.引入依赖2.修改…...

[Leetcode 61][Medium]-旋转链表

目录 一、题目描述 二、整体思路 三、代码 一、题目描述 原题链接 二、整体思路 首先发现这样的规律&#xff1a;当k大于等于链表中节点总数n时&#xff0c;会发现此时旋转后的链表和kk%n时的旋转后的链表一样。同时对于特殊情况n0和n1时&#xff0c;无论k的值为多少都可以…...

高效分页策略:掌握 LIMIT 语句的正确使用方法与最佳实践

本文主要介绍limit 分页的弊端及线上应该怎么用 LIMIT M,N 平时经常见到使用 <limit m,n> 合适的 order by 来实现分页查询&#xff0c;这样做到底性能如何呢&#xff1f; 先来简单分析下&#xff0c;然后再实际验证一下。 无索引条件下&#xff0c;需要做大量的文件排…...

拼图游戏02

文章目录 概要整体架构流程代码过程小结 概要 现在需要将图片添加界面中 关键点在于它如何动态地根据游戏状态更新用户界面。它使用了Swing的布局管理器来定位组件&#xff0c;并且通过ImageIcon和JLabel来显示图像。注意&#xff0c;路径字符串中的反斜杠在Java中是转义字符…...

在本地进行Django支付宝扫码支付-当面付开发

这几天涉及到一个个人项目的支付开发场景&#xff0c;正好完成之后&#xff0c;做一下开发记录&#xff0c;给有需要的朋友做一下参考 涉及安装Python环境请参考我专栏中的历史文章&#xff0c;这里不再重复说明 环境&#xff1a; Python3.11 使用Django框架 因本次代码为沙…...

redis-RedisTemplate.opsForGeo 的geo地理位置相关的方法演示

主要方法&#xff1a;add : 添加一个地理位置distance: 计算两个元素之间的距离hash&#xff1a; 获取元素经纬度坐标经过geohash算法生成的base32编码值position: 获取集合中任意元素的经纬度坐标&#xff0c;可以一次获取多个radius&#xff1a;查询某个坐标或某个成员&#…...

做短视频矩阵要十几人团队吗?云微客助阵,一人即可

现在市面上主流的新媒体平台都进军了短视频赛道&#xff0c;对于众多企业和个人来说&#xff0c;短视频矩阵更是成为了提升影响力和拓展业务的关键。企业或个人可以根据自身产品特点和目标用户群体&#xff0c;构建账号矩阵&#xff0c;在多平台上建立账号矩阵&#xff0c;还可…...

常用语音识别开源工具的对比与实践

常用语音识别开源工具的对比 一.工具概述 1. WeNet 设计目标&#xff1a;WeNet 的设计主要聚焦于端到端&#xff08;E2E&#xff09;语音识别&#xff0c;特别是在流式识别方面的优化。其目标是提供一个可以在实际应用中达到低延迟和高精度的系统。模型架构&#xff1a; Con…...

Fortify代码安全测试工具在静态应用安全测试(SAST)方面针对典型问题的改进

Fortify代码安全测试工具作为行业内资深的老牌软件安全测试工具&#xff0c;可以同时支持静态代码扫描和动态代码扫描&#xff0c;本文我们讲述的主要是在静态代码扫描领域Fortify所面临的问题&#xff0c;以及最新的改进。 在应用安全领域&#xff0c;特别是静态应用安全测试&…...

AWS 消息队列服务 SQS

AWS 消息队列服务 SQS 引言什么是 SQSSQS 访问策略 Access Policy示例&#xff1a;如何为 DataLake Subscription 配置 SQS 引言 应用系统需要处理海量数据&#xff0c;数据发送方和数据消费方是通过什么方式来无缝集成消费数据的&#xff0c;AWS 提供 SQS 消息队列服务来解决…...

【iOS】——响应者链和事件传递链

事件传递 事件传递流程 发生触摸事件后&#xff0c;系统会将该事件封装成UIEvent对象加入到一个由UIApplication管理的事件队列 UIApplication会从事件队列中取出最前面的事件&#xff0c;并将事件分发下去以便处理&#xff0c;通常&#xff0c;先发送事件给应用程序的主窗口…...

mysql查询慢

可能是连接数&#xff0c;或者缓存不够&#xff0c;可尝试添加如下参数&#xff0c;重启mysql [mysqld] max_connections50000 interactive_timeout604800 lock_wait_timeout600 wait_timeout604800 net_read_timeout604800 log-error/var/lib/mysql/mysqld.log slow_qu…...

【Java-==与equals】

与equals区别&#xff1a; 1.是关系运算符&#xff0c;equals()是0bject类中定义的方法 2.基本数据类型: 使用比较值&#xff0c;无法使用equals() 3.引用数据类型: 使用比较内存地址; 如果没有重写equals(),仍然调用的是0bject父类的equals(()方法&#xff0c;则比较的是内…...

ai回答 部署前端项目时需要使用ssh吗

SSH&#xff08;Secure Shell&#xff09;是一种网络协议&#xff0c;用于在不安全的网络上安全地访问远程计算机。SSH 提供了加密的命令行登录到远程计算机的功能&#xff0c;以及远程命令执行和其他服务。它常用于系统管理员管理服务器、开发者进行远程开发、用户通过终端访问…...

结合ChatGPT与Discord,提高团队合作效率

本文将教你如何集成Discord Bot&#xff0c;助力团队在工作中实现更高效的沟通与协作。通过充分发挥ChatGPT的潜力&#xff0c;进一步提升工作效率和团队协作能力。无需编写任何代码即可完成本文所述的操作&#xff0c;进行个性化定制只需对参数进行微调即可。 方案介绍 如果在…...

VisualStudio|开发环境相关技巧及问题

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 本节继续学习VisualStudio相关内容&#xff0c;以前学习都是以能用为主&#xff0c;没有系统的学习&#xff0c;接下来会系统的学习相关内容&#xff0c; 以下为学习笔记。 01 第三方dll调用 ①&#xff1a;如果第三…...

Redis远程字典服务器(11)—— redis客户端介绍

一&#xff0c;基本介绍 前面学习的主要是各种Redis的基本操作/命令&#xff0c;都是再Redis命令行客户端&#xff0c;手动执行的&#xff0c;但是这种方式不是我们日常开发中主要的形式更多的时候&#xff0c;是使用Redis的api&#xff0c;来实现定制化的Redis客户端程序&…...

【mysql】mysql之DDL数据定义语言

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

Word文件密码忘记,该如何才能编辑Word文件呢?

Word文件打开之后&#xff0c;发现编辑功能都是灰色的&#xff0c;无法使用&#xff0c;无法编辑&#xff0c;遇到这种情况&#xff0c;是因为Word文件设置了限制编辑导致的。一般情况下&#xff0c;我们只需要输入Word密码&#xff0c;将限制编辑取消就可以正常编辑文件了&…...

解锁移动办公新境界,七款顶尖移动终端管控软件分享!助您轻松掌控每一台移动设备,企业必备!

移动办公&#xff0c;它不仅打破了时间和空间的限制&#xff0c;提高了工作效率&#xff0c;还为员工创造了更加灵活的工作环境。然而&#xff0c;随着移动设备的普及&#xff0c;如何有效管理和控制这些终端&#xff0c;确保信息安全、提升工作效率呢&#xff1f; 今天&#…...

基于微信小程序的大用户心理咨询系统设计与实现---附源码99040

目录 1 绪论 1.1 研究背景 1.2研究现状 1.3论文结构与章节安排 2 基于微信小程序的大用户心理咨询系统设计与实现分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 基于微信小程序的大用户心理咨询系统设计与实现总体设计 3.…...

Bigtop 从0开始(上)

本文作者&#xff1a;蔡佳良 原文阅读&#xff1a;【巨人肩膀社区博客分享】Bigtop 从0开始 BigTop的应用场景&#xff1a; 1. BigTop通过提供预配置的Docker镜像&#xff0c;极大简化了在不同操作系统上编译大数据组件的rpm或deb包的过程&#xff0c;使之变得快捷且高效。 …...

算法基础及例题

1、双指针 维护区间信息、子序列匹配、利用序列有序性、单项链表找环双指针 - OI Wiki (oi-wiki.org) 盛最多水的容器https://leetcode.cn/problems/container-with-most-water/ public class Solution {public int maxArea(int[] height) {int l 0, r height.length - 1;int…...

机器学习-KNN 算法

一.K-近邻(KNN) K-近邻&#xff08;K-Nearest Neighbors, 简称 KNN&#xff09;是一种基于实例的学习算法&#xff0c;主要用于分类和回归问题。KNN 的工作原理直观且简单&#xff0c;它基于相似性进行预测&#xff0c;也就是说给定一个新的数据点&#xff0c;KNN 算法会查找距…...

【Linux】如何快速查看 linux 服务器有几个cpu

如何快速查看 linux 服务器有几个cpu author: jayzhen date: 2024.08.22 文章目录 如何快速查看 linux 服务器有几个cpu1. 使用lscpu命令2. 使用nproc命令3. 使用/proc/cpuinfo文件4. 使用top或htop命令结论 在Linux服务器上&#xff0c;你可以通过多种方式快速查看系统中有几个…...

[数据集][目标检测]电力场景轭式悬架锈蚀分类数据集6351张2类别

数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;6351 分类类别数&#xff1a;2 类别名称[corrosion,good] 每个类别图片数&#xff1a; corrosion 图片数&#xff1a;310 good 图片数&#xff1a;6041 …...

【嵌入式linux开发】智能家居入门5:老版ONENET,多协议接入(QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派)

智能家居入门5&#xff08;QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派&#xff09; 前言一、QT界面设计二、云平台产品创建与连接三、下位机端QT代码总览&#xff1a;四、微信小程序端代码总览五、板端测试 前言 前四篇智能家居相关文章都是使用STM32作为主控&#xf…...

软考-软件设计师(程序设计语言习题)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...

「C++系列」vector 容器

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能教程 文章目录 一、vector 容器1. 基本特性2. 基本操作3. 注意事项 二、应用场景1. 应用场景2. 案例案例一&#xff1…...

梯度的概念

梯度 机器学习中&#xff0c;梯度下降法&#xff0c;牛顿法都会用到梯度概念 对于一元函数&#xff0c;梯度可以看成导数 对于多元函数&#xff0c;梯度可以看成偏导数 如果多元函数包含N个自变量&#xff1a; x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1​,x2​,...,x…...