3.2 内容管理模块 - 课程分类、新增课程、修改课程

内容管理模块-课程分类、新增课程、修改课程

文章目录

  • 内容管理模块-课程分类、新增课程、修改课程
  • 一、课程分类
    • 1.1 课程分类表
    • 1.2 查询树形结构
      • 1.2.1 表自连接
      • 1.2.2 SQL递归
    • 1.3 Mapper
    • 1.4 Service
    • 1.5 Controller
    • 1.6 效果图
  • 二、添加课程
    • 2.1 需求分析
    • 2.2 数据表
      • 2.2.1 课程基础信息表
      • 2.2.2 课程营销信息表
    • 2.3 交互类
      • 2.3.1 AddCourseDto
      • 2.3.2 CourseBaseInfoDto
    • 2.3 Mapper
    • 2.4 Service
    • 2.5 Controller
    • 2.6 效果图
  • 三、修改课程
    • 3.1 需求分析
    • 3.2 数据回显
      • 3.2.1 Service类
      • 3.2.2 Controller类
    • 3.3 修改课程
      • 3.3.1 修改课程Dto
      • 3.3.2 Service
      • 3.3.3 Controller

一、课程分类

点击“添加课程”,之后随便选一个“课程形式”

image-20231107222138556

然后有一个“课程分类”,我们下面就要实现课程分类,这个地方缺少一个课程分类的下拉框

image-20231107222227362

1.1 课程分类表

典型的树形分类结构

image-20231107224534473

image-20231109211534507

@Data
@TableName("course_category")
public class CourseCategory implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/private String id;/*** 分类名称*/private String name;/*** 分类标签默认和名称一样*/private String label;/*** 父结点id(第一级的父节点是0,自关联字段id)*/private String parentid;/*** 是否显示*/private Integer isShow;/*** 排序字段*/private Integer orderby;/*** 是否叶子*/private Integer isLeaf;}

创建一个Dto,方便之后向前端响应课程分类表数据

@Data
public class CourseCategoryTreeDto extends CourseCategory implements Serializable {//Serializable:在网络传输需要序列化的时候,需要实现Serializable接口private static final long serialVersionUID = 2950235607890841126L;//下级节点List<CourseCategoryTreeDto> childrenTreeNodes;}

展示出来是下面这种格式

{
"id" : "1-2",
"isLeaf" : null,
"isShow" : null,
"label" : "移动开发",
"name" : "移动开发",
"orderby" : 2,
"parentid" : "1",
"childrenTreeNodes" : [{"childrenTreeNodes" : null,"id" : "1-2-1","isLeaf" : null,"isShow" : null,"label" : "微信开发","name" : "微信开发","orderby" : 1,"parentid" : "1-2"}}

1.2 查询树形结构

1.2.1 表自连接

假如说数据层级比较固定,而且数据层级比较少,可以使用表自连接的方式

select one.id one_id, one.label one_label, two.id two_id,two.label two_label,three.id three_id,three.label three_label
from course_category one -- one是表的别名,表示一级分类inner join course_category two -- two是表的别名,表示二级分类on two.parentid = one.id -- 子节点的parentid是父节点的id
inner join course_category threeon  three.parentid = two.id

查询结果

image-20231109211920604

1.2.2 SQL递归

灵活的方式实现树形表的查询,比如使用MYSQL递归实现,使用with语法

递归时MySQL8之后才有的

递归语法

WITH [RECURSIVE]cte_name [(col_name [, col_name] ...)] AS (subquery)[, cte_name [(col_name [, col_name] ...)] AS (subquery)] 

cte_name :公共表达式的名称,可以理解为表名,用来表示as后面跟着的子查询

col_name :公共表达式包含的列名,可以写也可以不写

有一个关键字RECURSIVE,就是递归的含义

cte_name相当于表的一个别名

(col_name [, col_name] …)]是表中的哪些字段

示例代码

--  t1J就是一个虚拟表
with RECURSIVE t1  AS
(
-- 这个t1表的初始数据就是1SELECT 1 as n-- 将下面查询出的数据结果集放入t1虚拟表中UNION ALL-- 下面是递归查询的内容SELECT n + 1 FROM t1 WHERE n < 5
)-- 查询最终结果
SELECT * FROM t1;

image-20231109213712866

下面查询树形结果的SQL,向下递归

向下递归:先拿一级节点,拿到一级节点后找二级节点,拿到二级节点后找三级节点…

with RECURSIVE t1  AS(
--  初始数据,就认为是根节点select * from course_category as p where id = '1'--  每递归一次就把数据放入t1
union all--  由树根找叶子
select t2.* 
from course_category as t2
INNER JOIN t1ON t2.parentid =  t1.id --  当我们拿到id为1的结点,递归后就可以拿到1-1等子结点的结果集
--  当我们拿到id为1-1等结点后,递归后就可以拿到1-1-1等子结点结果集
--  .......
)select * from t1

image-20231109220313874

向上递归

向上递归:拿到最下一级的节点后找次下及节点…

由子节点找父节点

with RECURSIVE t1  AS(
--  初始数据,就认为是根节点select * from course_category as p where id = '1-1-1'--  每递归一次就把数据放入t1
union all--  由树根找叶子
select t2.* 
from course_category as t2
INNER JOIN t1ON t2.id =  t1.parentid --  当我们拿到id为1的结点,递归后就可以拿到1-1等子结点的结果集
--  当我们拿到id为1-1等结点后,递归后就可以拿到1-1-1等子结点结果集
--  .......
)select * from t1

image-20231109221252895

mysql为了避免无限递归默认递归次数为1000,可以通过设置cte_max_recursion_depth参数增加递归深度,还可以通过max_execution_time限制执行时间,超过此时间也会终止递归操作。

mysql递归相当于在存储过程中执行若干次sql语句,java程序仅与数据库建立一次链接执行递归操作,所以只要控制好递归深度,控制好数据量性能就没有问题。

1.3 Mapper

//使用递归查询分类
public List<CourseCategoryTreeDto> selectTreeNodes(@Param("id") String id);
    <!--查询课程分类--><select id="selectTreeNodes" resultType="com.xuecheng.content.model.dto.CourseCategoryTreeDto">with RECURSIVE t1 AS (select *from course_category as pwhere id = #{id}union allselect t2.*from course_category as t2INNER JOIN t1ON t2.parentid = t1.id)select *from t1order by t1.id, t1.orderby</select>

我们现在从数据库中查到的数据是下列这个模样

image-20231109225811919

代码中查询出来的数据如下所示

image-20231109225958818

1.4 Service

要将Mapper层返回的数据进行进一步的处理。

将根节点id=1舍弃不要,因为在业务上没什么需要了

我们要将子节点放入到父节点的childrenTreeNodes集合里面。比如将1-1-x的节点放入到1-1节点的childrenTreeNodes集合里面

@Slf4j
@Service
public class CourseCategoryServiceImpl implements CourseCategoryService {@Autowiredprivate CourseCategoryMapper courseCategoryMapper;@Overridepublic List<CourseCategoryTreeDto> queryTreeNodes(String id) {//TODO 数据库递归查询出课程分类信息List<CourseCategoryTreeDto> courseCategoryTreeDtos = courseCategoryMapper.selectTreeNodes(id);//TODO 找到每个节点的子节点,最终封装成List<CourseCategoryTreeDto>//将list转map,以备使用,排除根节点Map<String, CourseCategoryTreeDto> mapTemp = courseCategoryTreeDtos.stream()//!id.equals(item.getId()) 含义就是排除根节点.filter(item -> !id.equals(item.getId())).collect(//转Map是需要一个key,一个value的//第一个key是代表元素的意思,key -> key.getId()是拿到key元素的id,然后充当Map的key//value表示对象的本身,所以不需要任何的处理//(key1, key2) -> key2 表示当key重复的时候(键相同),以后来的key为主Collectors.toMap(key -> key.getId(), value -> value, (key1, key2) -> key2));//最终返回的listList<CourseCategoryTreeDto> categoryTreeDtos = new ArrayList<>();//依次遍历每个元素,排除根节点//courseCategoryTreeDtos是从数据库查询出来的全部的数据courseCategoryTreeDtos.stream().filter(item -> !id.equals(item.getId())).forEach(item -> {if (item.getParentid().equals(id)) {//紧挨根节点下的节点categoryTreeDtos.add(item);}//找到当前节点的父节点CourseCategoryTreeDto courseCategoryTreeDto = mapTemp.get(item.getParentid());if (courseCategoryTreeDto != null) {if (courseCategoryTreeDto.getChildrenTreeNodes() == null) {courseCategoryTreeDto.setChildrenTreeNodes(new ArrayList<CourseCategoryTreeDto>());}//下边开始往ChildrenTreeNodes属性中放子节点courseCategoryTreeDto.getChildrenTreeNodes().add(item);}});return categoryTreeDtos;}}

1.5 Controller

/*** 课程分类相关接口*/
@Slf4j
@RestController
public class CourseCategoryController {@Autowiredprivate CourseCategoryService courseCategoryService;@GetMapping("/course-category/tree-nodes")public List<CourseCategoryTreeDto> queryTreeNodes() {return courseCategoryService.queryTreeNodes("1");}}

1.6 效果图

image-20231109233240245

二、添加课程

2.1 需求分析

将来这些信息都会存储到“course_base”表中

  1. 点击“添加课程”选项

image-20231107222056328

  1. 点击添加课程,选择课程形式为录播

image-20231114213547334

  1. 选择完毕,点击下一步,进入课程基本信息添加界面

本界面分两部分信息,一部分是课程基本信息上,一部分是课程营销信息。

课程基本信息

image-20231114213621571

课程营销信息

下面的信息会存储在course_market表中

image-20231114214356815

也就是说一个表单中的数据要存储到两张表中

在这个界面中填写课程的基本信息、课程营销信息上。

填写完毕,保存并进行下一步

2.2 数据表

course_base、course_market两张表存储

两张表是一对一的关系,一个课程只有一个营销信息

并且两张表的主键id是相同的

2.2.1 课程基础信息表

  • course_base

image-20231114220605075

image-20231114220349065

/*** 课程基本信息*/
@Data
@TableName("course_base")
public class CourseBase implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 机构ID*/private Long companyId;/*** 机构名称*/private String companyName;/*** 课程名称*/private String name;/*** 适用人群*/private String users;/*** 课程标签*/private String tags;/*** 大分类*/private String mt;/*** 小分类*/private String st;/*** 课程等级*/private String grade;/*** 教育模式(common普通,record 录播,live直播等)*/private String teachmode;/*** 课程介绍*/private String description;/*** 课程图片*/private String pic;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 修改时间*/@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime changeDate;/*** 创建人*/private String createPeople;/*** 更新人*/private String changePeople;/*** 审核状态*/private String auditStatus;/*** 课程发布状态 未发布  已发布 下线*/private String status;
}

2.2.2 课程营销信息表

  • course_market

image-20231114220542319

image-20231114220530310

/*** 课程营销信息*/
@Data
@TableName("course_market")
public class CourseMarket implements Serializable {private static final long serialVersionUID = 1L;/*** 主键,课程id*/private Long id;/*** 收费规则,对应数据字典*/private String charge;/*** 现价*/private Float price;/*** 原价*/private Float originalPrice;/*** 咨询qq*/private String qq;/*** 微信*/private String wechat;/*** 电话*/private String phone;/*** 有效期天数*/private Integer validDays;}

2.3 交互类

2.3.1 AddCourseDto

价格信息存Float是没有问题的,但是计算的时候是有问题的,我们要使用BigDecimal

/*** @description 添加课程dto*/
@Data
@ApiModel(value = "AddCourseDto", description = "新增课程基本信息")
public class AddCourseDto {@NotEmpty(message = "课程名称不能为空")@ApiModelProperty(value = "课程名称", required = true)private String name;@NotEmpty(message = "适用人群不能为空")@Size(message = "适用人群内容过少", min = 10)@ApiModelProperty(value = "适用人群", required = true)private String users;@ApiModelProperty(value = "课程标签")private String tags;@NotEmpty(message = "课程分类不能为空")@ApiModelProperty(value = "大分类", required = true)private String mt;@NotEmpty(message = "课程分类不能为空")@ApiModelProperty(value = "小分类", required = true)private String st;@NotEmpty(message = "课程等级不能为空")@ApiModelProperty(value = "课程等级", required = true)private String grade;@ApiModelProperty(value = "教学模式(普通,录播,直播等)", required = true)private String teachmode;@ApiModelProperty(value = "课程介绍")private String description;@ApiModelProperty(value = "课程图片", required = true)private String pic;@NotEmpty(message = "收费规则不能为空")@ApiModelProperty(value = "收费规则,对应数据字典", required = true)private String charge;@ApiModelProperty(value = "价格")private BigDecimal price;@ApiModelProperty(value = "原价")private BigDecimal originalPrice;@ApiModelProperty(value = "qq")private String qq;@ApiModelProperty(value = "微信")private String wechat;@ApiModelProperty(value = "电话")private String phone;@ApiModelProperty(value = "有效期")private Integer validDays;
}

2.3.2 CourseBaseInfoDto

添加成功之后我们查询出来的课程的详细信息

/*** @description 课程基本信息dto* 添加上课程信息后我们再查询返回的信息*/
@Data
public class CourseBaseInfoDto extends CourseBase {/*** 收费规则,对应数据字典*/private String charge;/*** 价格*/private Float price;/*** 原价*/private Float originalPrice;/*** 咨询qq*/private String qq;/*** 微信*/private String wechat;/*** 电话*/private String phone;/*** 有效期天数*/private Integer validDays;/*** 大分类名称*/private String mtName;/*** 小分类名称*/private String stName;}

2.3 Mapper

/*** 课程基本信息 Mapper 接口*/
public interface CourseBaseMapper extends BaseMapper<CourseBase> {}
/*** 课程营销信息 Mapper 接口*/
public interface CourseMarketMapper extends BaseMapper<CourseMarket> {}

2.4 Service

2.5 Controller

    @ApiOperation("新增课程")@PostMapping("/course")public CourseBaseInfoDto createCourseBase(@Validated @RequestBody AddCourseDto addCourseDto) {
//      将来会集成SpringSecurity框架,用户登录之后就可以获取到用户所属机构的ID
//      先把机构ID写死return courseBaseInfoService.createCourseBase(10086L,addCourseDto);}

2.6 效果图

image-20231115000310216

image-20231115000319523

之后点击保存,这个时候会报错一个404,因为后面课程大纲的内容还没有编写

再查看数据库

image-20231115000356970

再通过页面查看一下,还是挺带劲的

image-20231115000508921

三、修改课程

涉及的表也是course_base课程基本信息表、course_market课程营销表

其实就是比添加课程多了一个数据回显而已

3.1 需求分析

点击编辑按钮就可以修改课程信息

image-20231115234017461

要修改的表单内容其实是和添加课程时的表单是一个样子的

然后这个地方点击编辑的时候要做一个数据回显

image-20231115234241162

image-20231115234253071

修改课程的请求数据只是比添加课程的请求数据多了一个课程id而已

但是没有营销信息

image-20231215223126640

3.2 数据回显

image-20231215222839372

3.2.1 Service类

这个方法之前其实写过

    @Overridepublic CourseBaseInfoDto getCourseBaseInfo(Long courseId){//TODO 查询课程基本信息CourseBase courseBase = courseBaseMapper.selectById(courseId);if(courseBase == null){return null;}//TODO 查询课程营销信息CourseMarket courseMarket = courseMarketMapper.selectById(courseId);CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();BeanUtils.copyProperties(courseBase,courseBaseInfoDto);if(courseMarket != null){BeanUtils.copyProperties(courseMarket,courseBaseInfoDto);}//TODO 查询分类名称,是哪一级的CourseCategory courseCategoryBySt = courseCategoryMapper.selectById(courseBase.getSt());//小分类courseBaseInfoDto.setStName(courseCategoryBySt.getName());//小分类名称CourseCategory courseCategoryByMt = courseCategoryMapper.selectById(courseBase.getMt());//大分类courseBaseInfoDto.setMtName(courseCategoryByMt.getName());//大分类名称return courseBaseInfoDto;}

3.2.2 Controller类

    @ApiOperation("根据课程id查询接口")@GetMapping("/course/{courseId}")public CourseBaseInfoDto getCourseBaseById(@PathVariable("courseId") Long courseId) {return courseBaseInfoService.getCourseBaseInfo(courseId);}

3.3 修改课程

3.3.1 修改课程Dto

修改课程的请求数据只比增加课程的请求数据多一个课程id

/*** 修改课程Dto*/
@Data
@ApiModel(value = "EditCourseDto",description = "修改课程基本信息")
public class EditCourseDto extends AddCourseDto{@ApiModelProperty(value = "课程id",required = true)private Long id;
}

3.3.2 Service

    /*** 修改课程** @param companyId     机构id,后面做认证收取那使用* @param editCourseDto 要修改的课程信息* @return 修改之后的课程详细信息*/@Overridepublic CourseBaseInfoDto updateCourseBase(Long companyId, EditCourseDto editCourseDto) {//TODO 课程基本信息//获取到课程idLong courseId = editCourseDto.getId();//查询课程CourseBase courseBase = courseBaseMapper.selectById(courseId);if (courseBase == null) {XueChengPlusException.cast("课程不存在");}//数据合法性校验//根据具体的业务逻辑进行校验 - 本机构只能修改本机构的课程if (!companyId.equals(courseBase.getCompanyId())) {XueChengPlusException.cast("本机构只能修改本机构的课程");}//封装数据BeanUtils.copyProperties(editCourseDto, courseBase);//修改时间courseBase.setChangeDate(LocalDateTime.now());//更新数据库int i = courseBaseMapper.updateById(courseBase);if (i<=0){XueChengPlusException.cast("修改课程失败");}//TODO 更新课程营销信息CourseMarket courseMarketNew = new CourseMarket();BeanUtils.copyProperties(editCourseDto, courseMarketNew);int count = courseMarketMapper.updateById(courseMarketNew);if (count <= 0) {throw new RuntimeException("更新课程营销信息失败");}//查询课程信息CourseBaseInfoDto courseBaseInfo = getCourseBaseInfo(courseId);return courseBaseInfo;}

3.3.3 Controller

    @ApiOperation("修改课程接口")@PutMapping("/course")public CourseBaseInfoDto getCourseBaseById(@RequestBody EditCourseDto editCourseDto) {//机构id先写死,后面授权认证的时候后会改过来Long companyId = 1232141425L;return courseBaseInfoService.updateCourseBase(companyId,editCourseDto);}

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

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

相关文章

嵌入式科普(5)ARM GNU Toolchain相关概念和逻辑

一、目的/概述 二、资料来源 三、逻辑和包含关系 四、Arm GNU Toolchain最常用的命令 嵌入式科普(5)ARM GNU Toolchain相关概念和逻辑 一、目的/概述 对比高集成度的IDE(MDK、IAR等)&#xff0c;Linux开发需要自己写Makefile等多种脚本。eclipse、Visual Studio等需要了解预处…

Selenium框架的使用心得(一)

最近使用selenium框架实现业务前端的UI自动化&#xff0c;在使用selenium时&#xff0c;有一些心得想要和大家分享一下~ Selenium是一款用于web应用程序测试的工具&#xff0c;常用来实现稳定业务的UI自动化。这里&#xff0c;不想对其发展历史做介绍&#xff0c;也不想用官方…

vscode 文件目录栏缩进

一个好的开发IDE&#xff0c;一定是让人赏心悦目的&#xff0c;这个赏心悦目也一定是包含层级目录的清晰明了&#xff01;不能像感冒的鼻涕一样一擤一摊子&#xff01;就像。。。。嗯&#xff0c;算了&#xff0c;断子还是不讲了&#xff0c;怕有些妹子投诉 或发消息批评我。。…

【ppt密码】ppt的密码忘了,怎么破解

PPT文件设置了保护密码&#xff0c;但是密码忘记了&#xff0c;无法打开PPT文件、无法编辑PPT文件了该怎么办&#xff1f;PPT文件的两种保护密码该如何解密&#xff1f; 首先是打开密码 网上有一种解决方法&#xff1a; 1、重新命名PPT文件&#xff0c;将其后缀改为zip格式&…

Shell编程基础 – C语言风格的Bash for循环

Shell编程基础 – C语言风格的Bash for循环 Shell Programming Essentials - C Style For Loop in Bash By JacksonML 循环是编程语言的基本概念之一&#xff0c;同样也是Bash编程的核心。当用户需要一遍又一遍地运行一系列命令直到达到特定条件时&#xff0c;例如&#xff1…

优点和缺点(以及在求职过程中如何处理它们)

你知道你会感到紧张&#xff0c;因为你真的很想要这份工作。当人力资源人员提出这个普遍存在的问题“你的优势和劣势是什么&#xff1f;”时&#xff0c;他们在寻找什么&#xff1f; 有哪些突出的优点和缺点示例&#xff1f;您如何将这些示例个性化&#xff0c;以免听起来像人…

leecode题解Golang版本-3-无重复字符最长子串

题目 无重复字符最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 题解 func lengthOfLongestSubstring(s string) int {m : make(map[uint8]int)res : 0for l, r : 0, 0; r < len(s); r {m[s[r]]if v, ok : m[s[r]]; !ok || v 1…

智能优化算法应用:基于世界杯算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于世界杯算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于世界杯算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.世界杯算法4.实验参数设定5.算法结果6.参考文…

小程序自定义轮播图样式

小程序自定义轮播图样式以下是各案例&#xff0c;仅供大家参考。 效果展示&#xff1a; index.wxml代码&#xff1a; <view><!-- 轮播 --><view><swiper indicator-dots"{{indicatorDots}}"autoplay"{{autoplay}}" interval"{{…

数据可视化的魅力你了解吗?

你真的了解数据可视化吗&#xff1f;它所具备的真正魅力可能远远超出我们想象。数据可视化扩展了我们对数字和信息的简单理解&#xff0c;为我们揭示了一个无限可能的世界。今天我就以可视化行业的多年工作经验出发&#xff0c;和大家简单聊聊数据可视化的魅力。 数据的故事化…

STM32——时钟树与滴答计时器

STM32——时钟树与滴答计时器 使用的开发板为stm32F407VET6的芯片,主要介绍stm32的时钟树与滴答计时器的一些理论和一个自己编写的delay函数。 时钟树的结构图可以在STM32F4xx中文参考手册.pdf中的时钟这块找到。而滴答计时器是内核资源&#xff0c;需要到Cortex M3与M4权威指南…

【VScode】设置语言为中文

1、下载安装好vscode 2、此时可看到页面为英文&#xff0c;为方便使用可切换为中文 3、键盘按下 ctrlshiftP 4、在输入框内输入configure display language 5、选择中文&#xff0c;restart即可&#xff08;首次会有install安装过程&#xff0c;等待安装成功后重启即可&am…

算法设计与分析2023秋-头歌客观题-张超(云南农业大学)

文章目录 第一章客观题练习关于算法描述正确的是&#xff08; &#xff09;算法的要素包括&#xff08; &#xff09;分析算法&#xff0c;最重要的是衡量算法哪两个方面的效率&#xff08; &#xff09;算法的表示方法有&#xff08; &#xff09; 第二章客观题练习关于算法分…

nodejs+vue+微信小程序+python+PHP国漫推荐系统-计算机毕业设计推荐

使得本系统的设计实现具有可使用的价。做出一个实用性好的国漫推荐系统&#xff0c;使其能满足用户的需求&#xff0c;并可以让用户更方便快捷地国漫推荐。这个系统的设计主要包括系统页面的设计和方便用户互动的后端数据库&#xff0c;在开发后需要良好的数据处理能力、友好的…

git push提交出现Everything up-to-date提示问题

以前通过git提交代码到GitHub上的个人main分支时&#xff0c;曾出现过这样一个很低级的错误—— 出现这个错误原因&#xff0c;其实就是没有正确执行指令造成的&#xff0c;也就是没有正常提交数据。 一般按照以下命令提交&#xff0c;基本就没什么问题了—— git add . #添…

5路开关量转继电器 Modbus TCP远程I/O模块 YL95 RJ-45网络接口通信

特点&#xff1a; ● 五路开关量输入&#xff0c;五路继电器输出 ● 支持Modbus TCP 通讯协议 ● 内置网页功能&#xff0c;可以通过网页查询电平状态 ● 可以通过网页设定继电器输出状态 ● DI信号输入&#xff0c;DO输出及电源之间互相隔离 ● 宽电源供电范围&#x…

选择排序、快速排序和插入排序

1. 选择排序 xuanze_sort.c #include<stdio.h> #include<stdlib.h>//选择排序void xuanze_sort(int arr[],int sz){//正着for(int i0;i<sz;i){//外层循环从第一个数据开始依次作为基准数据for(int j i1;j<sz;j){//int j i1 因为第一个数据作为了基准数据&…

本地缓存与多级缓存

一、前言 缓存对于一个高并发场景下的微服务应用来说具有重要的作用&#xff0c;不管是在架构选型还是设计阶段&#xff0c;缓存都是应用扛高并发提升吞吐量的有效手段。缓存对于大多数开发的同学来说并不陌生&#xff0c;一个基本的缓存使用流程如下&#xff1a; 简而言之&am…

NNDL 作业11 LSTM [HBU ]

目录 习题6-4 推导LSTM网络中参数的梯度&#xff0c; 并分析其避免梯度消失的效果 >LSTM前向传播 >反向传播 求梯度 >梯度消失和梯度爆炸怎么来的&#xff1f; >关键点&#xff1a;LSTM如何缓解梯度消失&#xff1f; 习题6-3P 编程实现下图LSTM运行过程 1…

力扣日记12.18-【二叉树篇】合并二叉树

力扣日记&#xff1a;【二叉树篇】合并二叉树 日期&#xff1a;2023.12.18 参考&#xff1a;代码随想录、力扣 617. 合并二叉树 题目描述 难度&#xff1a;简单 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xf…