SpringBootWeb三层架构分层解耦

SpringBootWeb

  • 1. SpringBootWeb案例
    • 1.1 控制层未拆分代码
    • 1.2 实体类
    • 1.3 静态资源文件
    • 1.4 txt文件
    • 1.5 运行界面展示
  • 2. 三层架构拆分
    • 2.1 控制层(Controller)
      • 2.1.1 功能
      • 2.1.2 用户信息控制层
    • 2.2 业务逻辑层(Service)
      • 2.2.2 功能
      • 2.2.3 业务逻辑层接口
      • 2.2.4 业务逻辑接口实现类
    • 2.3 数据访问层(DAO)
      • 2.3.1 功能
      • 2.3.2 数据层接口
      • 2.3.3 数据层接口实现类
    • 2.4 整体流程
    • 2.5 三层架构拆分的优势
    • 2.6 部分代码解释
      • 2.6.1 List & ArrayList
      • 2.6.2 面向对象的特性---多态
  • 3. 分层解耦
    • 3.1 核心概念
      • 3.1.1 耦合
      • 3.1.2 内聚
      • 3.1.3 控制反转 (IoC)
      • 3.1.4 依赖注入 (DI)
      • 3.1.5 Bean对象
    • 3.2 相关注解
      • 3.2.1 @Component 注解
        • 3.2.1.1 @Component 衍生注解
        • 3.2.1.2 @RestController 注解
      • 3.2.2 @ComponentScan注解
      • 3.2.3 @Autowired 注解
        • 3.2.3.1 三种依赖注入方式
          • 3.2.3.1.1 属性注入
          • 3.2.3.1.2 构造函数注入
          • 3.2.3.1.3 setter注入
        • 3.2.3.2 相同类型的bean三种解决方案
          • 3.2.3.2.1 @Primary
          • 3.2.3.2.2 @Qualifier
          • 3.2.3.2.3 @Resource
    • 3.3 三层架构解耦
      • 3.3.1 控制层解耦
      • 3.3.2 业务逻辑层解耦
      • 3.3.3 数据访问层解耦

本帖参考B站黑马程序员:全网首发AI+JavaWeb开发入门

1. SpringBootWeb案例

1.1 控制层未拆分代码

/**
 * 用户信息Controller
 */
@RestController //@Controller + @ResponseBody -----> 如果返回的是一个对象/集合 --> 转json --> 响应
public class UserController {
    @RequestMapping("/list")
    public List<User> list(){
        //1. 读取user.txt中的数据
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
        ArrayList<String> lines = IoUtil.readUtf8Lines(in, new ArrayList<>());

        //2. 业务逻辑处理: 解析数据, 封装User对象 --> List<User>
        List<User> userList = lines.stream().map(line -> {
            String[] split = line.split(",");
            return new User(
                    Integer.parseInt(split[0]),
                    split[1],
                    split[2],
                    split[3],
                    Integer.parseInt(split[4]),
                    LocalDateTime.parse(split[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }).toList();

        //3. 响应数据
        return userList;
    }
}

1.2 实体类

com/itheima/pojo

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;
    private LocalDateTime updateTime;
}

1.3 静态资源文件

resources/static/user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户列表数据</title>
    <style>
        /*定义css,美化表格*/
        table{
            border-collapse: collapse;
            width: 100%;
            margin-top: 20px;
            border: 1px solid #ccc;
            text-align: center;
            font-size: 14px;
        }
        tr {
            height: 40px;
        }
        th,td{
            border: 1px solid #ccc;
        }
        thead{
            background-color: #e8e8e8;
        }
        h1{
            text-align: center;
            font-family: 楷体;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>用户列表数据</h1>
        <!--定义一个表格,包括6,分别是: ID, 用户名, 密码, 姓名, 年龄, 更新时间-->
        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>用户名</th>
                    <th>密码</th>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>更新时间</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="user in userList">
                    <td>{{user.id}}</td>
                    <td>{{user.username}}</td>
                    <td>{{user.password}}</td>
                    <td>{{user.name}}</td>
                    <td>{{user.age}}</td>
                    <td>{{user.updateTime}}</td>
                </tr>
            </tbody>
        </table>
    </div>

    <!--引入axios-->
    <script src="js/axios.min.js"></script>
    <script type="module">
        import { createApp } from './js/vue.esm-browser.js'
        createApp({
            data() {
                return {
                    userList: []
                }
            },
            methods: {
                async search(){
                    const result = await axios.get('/list');
                    this.userList = result.data;
                }
            },
            mounted() {
                this.search();
            }
        }).mount('#app')
    </script>
</body>
</html>

1.4 txt文件

resources/user.txt

1,daqiao,1234567890,大乔,22,2024-07-15 15:05:45
2,xiaoqiao,1234567890,小乔,18,2024-07-15 15:12:09
3,diaochan,1234567890,貂蝉,21,2024-07-15 15:07:16
4,lvbu,1234567890,吕布,28,2024-07-16 10:05:15
5,zhaoyun,1234567890,赵云,27,2024-07-16 11:03:28
6,zhangfei,1234567890,张飞,31,2024-07-16 11:03:28
7,guanyu,1234567890,关羽,34,2024-07-16 12:05:12
8,liubei,1234567890,刘备,37,2024-07-16 15:03:28

1.5 运行界面展示

在这里插入图片描述

2. 三层架构拆分

在这里插入图片描述
三层架构(Three-Tier Architecture)是软件开发中常用的一种设计模式,它将应用程序分为三个主要层次:表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。这种架构有助于提高代码的可维护性、可扩展性和复用性。
在这里插入图片描述
三层架构(Three-Tier Architecture)是软件开发中常用的一种设计模式,它将应用程序分为三个主要层次:表示层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。这种架构有助于提高代码的可维护性、可扩展性和复用性。以下是三层架构的详细解析:

2.1 控制层(Controller)

2.1.1 功能

  • 接收请求:处理来自客户端(如浏览器或移动应用)的HTTP请求。
  • 响应数据:根据业务逻辑处理结果生成相应的响应数据,并返回给客户端。

2.1.2 用户信息控制层

com/itheima/controller/UserController.java

/**
 * 用户信息Controller
 */
@RestController //@Controller + @ResponseBody -----> 如果返回的是一个对象/集合 --> 转json --> 响应
public class UserController {

    private UserService userService = new UserServiceImpl();

    @RequestMapping("/list")
    public List<User> list(){
        //1. 调用service
        List<User> userList = userService.list();
        //2. 响应数据
        return userList;
    }
}

2.2 业务逻辑层(Service)

2.2.2 功能

  • 逻辑处理:实现业务逻辑,包括数据验证、业务规则处理等。
  • 调用数据访问层:通过调用数据访问层的方法来操作数据库。

2.2.3 业务逻辑层接口

com/itheima/service/UserService.java

public interface UserService {

    /**
     * 查询所有用户
     */
    public List<User> list();

}

2.2.4 业务逻辑接口实现类

com/itheima/service/impl/UserServiceImpl.java

public class UserServiceImpl implements UserService {
    
    private UserDao userDao = new UserDaoImpl();
    @Override
    public List<User> list() {
        //1. 调用dao层, 获取数据
        List<String> lines = userDao.list();

        //2. 业务逻辑处理: 解析数据, 封装User对象 --> List<User>
        List<User> userList = lines.stream().map(line -> {
            String[] split = line.split(",");
            return new User(
                    Integer.parseInt(split[0]),
                    split[1],
                    split[2],
                    split[3],
                    Integer.parseInt(split[4]),
                    LocalDateTime.parse(split[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }).toList();
        return userList;
    }
}

2.3 数据访问层(DAO)

2.3.1 功能

  • 数据访问:负责与数据库进行交互,执行增删改查操作。
  • 封装数据库操作:提供统一的数据访问接口,屏蔽底层数据库的细节。

2.3.2 数据层接口

com/itheima/dao/UserDao.java

public interface UserDao {
    /**
     * 查询所有用户
     */
    public List<String> list();

}

2.3.3 数据层接口实现类

com/itheima/dao/impl/UserDaoImpl.java

public class UserDaoImpl implements UserDao {
    @Override
    public List<String> list() {
        //1. 读取user.txt中的数据
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
        ArrayList<String> lines = IoUtil.readUtf8Lines(in, new ArrayList<>());
        return lines;
    }
}

2.4 整体流程

  1. 客户端发起请求:用户通过浏览器或其他客户端发送HTTP请求到服务器。
  2. Controller接收请求:Controller接收到请求后,调用Service层的方法。
  3. Service处理业务逻辑:Service层处理业务逻辑,如果需要操作数据库,则调用DAO层的方法。
  4. DAO操作数据库:DAO层执行具体的数据库操作(如查询、插入、更新、删除)。
  5. Service返回结果:Service层处理完业务逻辑后,返回结果给Controller。
  6. Controller响应客户端:Controller将结果转换为HTTP响应,返回给客户端。

在这里插入图片描述

2.5 三层架构拆分的优势

  • 高内聚低耦合:每一层都有明确的职责,降低了各层之间的耦合度。
  • 易于维护和扩展:每一层都可以独立地进行修改和扩展,不影响其他层。
  • 良好的可测试性:每一层都可以单独进行单元测试,提高了测试的效率和准确性。

2.6 部分代码解释

2.6.1 List & ArrayList

在Java中,List是一个接口,定义了列表操作的标准方法,而ArrayListList接口的一个实现类,基于动态数组,允许存储不同类型的元素,且大小可自动扩展。

2.6.2 面向对象的特性—多态

Java中的多态是一种面向对象编程的特性,它允许一个引用变量指向不同类的对象,并根据实际引用的对象类型来执行对应的方法。多态主要通过继承和方法重写来实现:

  • 继承:子类继承父类,获得父类的属性和方法。
  • 方法重写:子类可以重写父类的方法,提供不同的实现。
  • 向上转型:将子类对象赋值给父类引用,例如:Parent p = new Child();

3. 分层解耦

3.1 核心概念

3.1.1 耦合

耦合是指软件中各个层或各个模块之间的依赖关联程度。高耦合意味着一个模块对其他模块的依赖性很强,这通常会导致代码难以维护和扩展。低耦合则表示模块之间的依赖关系较弱,这样可以提高系统的灵活性和可维护性。

3.1.2 内聚

内聚是指软件中各个功能模块内部的功能联系。高内聚意味着一个模块内部的功能紧密相关,每个功能都围绕同一个目标或任务进行。低内聚则表示模块内部的功能较为分散,缺乏明确的中心任务。
在这里插入图片描述

3.1.3 控制反转 (IoC)

控制反转(Inversion of Control,简称IoC)是一种设计模式,它将对象的创建控制权从程序自身转移到外部容器。这意味着程序不再直接创建对象,而是由外部容器负责创建和管理这些对象。这种思想称为控制反转。

3.1.4 依赖注入 (DI)

依赖注入(Dependency Injection,简称DI)是实现控制反转的一种常用方法。在依赖注入中,容器为应用程序提供运行时所依赖的资源。具体来说,容器会创建对象并将其所需的依赖项注入到对象中,而不是让对象自己去查找或创建这些依赖项。

3.1.5 Bean对象

Bean对象是指在IoC容器中创建和管理的对象。这些对象通常通过配置文件或注解的方式告诉容器如何创建和管理它们。容器负责实例化这些对象,并将它们所需要的依赖项注入进来。
在这里插入图片描述

3.2 相关注解

在Spring框架中,@Component@Autowired是两个非常重要的注解,它们分别用于定义Bean和实现依赖注入。下面详细介绍这两个注解的用途、使用方法及其区别。

3.2.1 @Component 注解

@Component 是一个通用注解,用于指示Spring容器自动检测并注册类为Spring管理的Bean。任何被标注了 @Component 的类都会被Spring的组件扫描机制发现,并注册为Spring应用上下文中的一个Bean。

3.2.1.1 @Component 衍生注解
注解说明位置
@Component声明bean的基础注解不属于以下三类时,用此注解
@Controller@Component的衍生注解标注在控制层类上(强制)
@Service@Component的衍生注解标注在业务层类上
@Repository@Component的衍生注解标注在数据访问层类上(由于与mybatis整合,用的少)

声明Bean的时候,可以通过注解value属性指定Bean的名字,如 Component("userDao"),如果没有指定,默认类名首字母小写

3.2.1.2 @RestController 注解

其中,@RestController 是 Spring Framework 中的一个组合注解,它主要用于简化创建 RESTful Web 服务的过程。具体来说,@RestController 是以下两个注解的组合:

  1. @Controller:这是 Spring MVC 中的一个注解,用于标记一个类作为控制器。被 @Controller 注解的类可以处理 HTTP 请求,并且通常会返回视图名称(例如 JSP 或 Thymeleaf 页面)。

  2. @ResponseBody:这个注解用于标注方法,表示该方法的返回值应该直接写入 HTTP 响应体中,而不是解析为视图名称。这意味着你可以直接返回对象、集合和字符串等,Spring 会自动将它们转换为 JSON 或 XML 格式(取决于请求的 Accept 头部信息)。

3.2.2 @ComponentScan注解

  • 组件扫描注解:这些注解声明的 Bean 需要被 @ComponentScan 注解扫描才能生效。
  • 默认扫描范围@SpringBootApplication 注解中隐式包含了 @ComponentScan 注解,默认扫描的范围是启动类所在包及其子包。在我们的案例中,默认扫描 com/itheima/ 包及其子包路径下的Bean对象。

3.2.3 @Autowired 注解

@Autowired 注解用于自动装配(依赖注入)。它可以应用于构造器、字段或setter方法上,Spring会尝试找到匹配的Bean来自动装配属性。(Spring 框架提供)

根据图片中的内容,基于@Autowired进行依赖注入的常见方式有如下三种:

3.2.3.1 三种依赖注入方式
3.2.3.1.1 属性注入
  • 代码示例:
    @RestController
    public class UserController {
        @Autowired
        private UserService userService;
        //......
    }
    
  • 优点:代码简洁、方便快速开发。
  • 点:隐藏了类之间的依赖关系,可能会破坏类的封装性。
3.2.3.1.2 构造函数注入
  • 代码示例:
    @RestController
    public class UserController {
        private final UserService userService;
    
        @Autowired
        public UserController(UserService userService) {
            this.userService = userService;
        }
    }
    
  • 优点:能清晰地看到类的依赖关系,提高了代码的安全性。
  • 点:代码繁琐,如果构造参数过多,可能会导致构造函数臃肿。
  • 注意:如果只有一个构造函数,@Autowired注解可以省略。
3.2.3.1.3 setter注入
  • 代码示例:
    @RestController
    public class UserController {
        private UserService userService;
    
        @Autowired
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    }
    
  • 优点:保持了类的封装性,依赖关系更清晰。
  • 点:需要额外编写setter方法,增加了代码量。
3.2.3.2 相同类型的bean三种解决方案
3.2.3.2.1 @Primary
  • 描述:通过在其中一个bean上添加@Primary注解,Spring会优先选择带有@Primary注解的bean进行注入。
  • 代码示例
    @Primary
    @Service
    public class UserServiceImpl implements UserService {
        // ...
    }
    
3.2.3.2.2 @Qualifier
  • 描述:通过在@Autowired注解上添加@Qualifier注解,并指定具体的bean名称,Spring会根据指定的名称进行注入。
  • 代码示例
    @RestController
    public class UserController {
        @Autowired
        @Qualifier("userServiceImpl")
        private UserService userService;
    }
    
3.2.3.2.3 @Resource
  • 描述:通过在字段或方法上使用@Resource注解,并指定具体的bean名称,Spring会根据指定的名称进行注入。(JAVAEE 规范提供)
  • 代码示例
    @RestController
    public class UserController {
        @Resource(name = "userServiceImpl")
        private UserService userService;
    }
    

3.3 三层架构解耦

3.3.1 控制层解耦

com/itheima/controller/UserController.java

/**
 * 用户信息Controller
 */
@RestController //@Controller + @ResponseBody -----> 如果返回的是一个对象/集合 --> 转json --> 响应
public class UserController {

    private UserService userService = new UserServiceImpl();
        ...
    }
}
@RestController //@Controller + @ResponseBody -----> 如果返回的是一个对象/集合 --> 转json --> 响应
public class UserController {

    @Autowired
    private UserService userService;
        ...
}

3.3.2 业务逻辑层解耦

com/itheima/service/impl/UserServiceImpl.java

public class UserServiceImpl implements UserService {
    
    private UserDao userDao = new UserDaoImpl();
    @Override
    public List<User> list() {
    	...
    }
}
@Service //将当前类交给spring管理, 声明为spring容器中bean对象
public class UserServiceImpl implements UserService {

    @Autowired //自动装配: 应用程序在运行时, 会自动的从容器中找到该类型的对象, 并赋值给该变量
    private UserDao userDao;

    @Override
    public List<User> list() {
    	...
    }
}

3.3.3 数据访问层解耦

com/itheima/dao/impl/UserDaoImpl.java

public class UserDaoImpl implements UserDao {
    @Override
    public List<String> list() {
        ...
    }
}
@Repository //将当前类交给spring管理, 声明为spring容器中bean对象
public class UserDaoImpl implements UserDao {
    @Override
    public List<String> list() {
    	...
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kimi k1.5: Scaling Reinforcement Learning with LLMs

TL;DR 2025 年 kimi 发表的 k1.5 模型技术报告&#xff0c;和 DeepSeek R1 同一天发布&#xff0c;虽然精度上和 R1 有微小差距&#xff0c;但是文章提出的 RL 路线也有很强的参考意义 Paper name Kimi k1.5: Scaling Reinforcement Learning with LLMs Paper Reading Note…

1.攻防世界 unserialize3(wakeup()魔术方法、反序列化工作原理)

进入题目页面如下 直接开审 <?php // 定义一个名为 xctf 的类 class xctf {// 声明一个公共属性 $flag&#xff0c;初始值为字符串 111public $flag 111;// 定义一个魔术方法 __wakeup()// 当对象被反序列化时&#xff0c;__wakeup() 方法会自动调用public function __wa…

Web前端开发--HTML

HTML快速入门 1.新建文本文件&#xff0c;后缀名改为.html 2.编写 HTML结构标签 3.在<body>中填写内容 HTML结构标签 特点 1.HTML标签中不区分大小写 2.HTML标签属性值中可以使用单引号也可使用双引号 3.HTML语法结构比较松散&#xff08;但在编写时要严格一点&…

JVM(Java 虚拟机)

Java语言的解释性和编译性&#xff08;通过JVM 的执行引擎&#xff09; Java 代码&#xff08;.java 文件&#xff09;要先使用 javac 编译器编译为 .class 文件&#xff08;字节码&#xff09;&#xff0c;紧接着再通过JVM 的执行引擎&#xff08;Execution Engine&#xff09…

Unity3D实现显示模型线框(shader)

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果展示👉二、第一种方式👉二、第二种方式👉壁纸分享👉总结👉前言 在 Unity 中显示物体线框主要基于图形渲染管线和特定的渲染模式。 要显示物体的线框,通常有两种常见的方法:一种是利用内置的渲染…

java项目之直销模式下家具工厂自建网站源码(ssm+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的直销模式下家具工厂自建网站源码。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 直销模式下家具…

window 安装GitLab服务器笔记

目录 视频&#xff1a; 资源&#xff1a; Linux CeneOS7&#xff1a; VMware&#xff1a; Linux无法安装 yum install vim -y 1.手动创建目录 2.下载repo PS 补充视频不可复制的代码 安装GitLab *修改root用户密码相关&#xff08;我卡在第一步就直接放弃了这个操作&…

笔记:理解借贷相等的公式

强烈推荐非会计人士&#xff0c;快速了解会计看这个系列的视频&#xff0c;其中比较烧脑的“借贷相等”公式&#xff0c;这个视频讲解的不错&#xff1a; 4.小白财务入门-借贷记账法_哔哩哔哩_bilibili 比如这里&#xff0c;钱在银行卡重&#xff0c;所以银行存款就是借方…

Qt - 地图相关 —— 3、Qt调用高德在线地图功能示例(附源码)

效果 作者其他相关文章链接:           Qt - 地图相关 —— 1、加载百度在线地图(附源码)           Qt - 地图相关 —— 2、Qt调用百度在线地图功能示例全集,包含线路规划、地铁线路查询等(附源码)           Qt - 地图相关 —— 3、Qt调用…

使用 POI-TL 和 JFreeChart 动态生成 Word 报告

文章目录 前言一、需求背景二、方案分析三、 POI-TL JFreeChart 实现3.1 Maven 依赖3.3 word模板设置3.2 实现代码 踩坑 前言 在开发过程中&#xff0c;我们经常需要生成包含动态数据和图表的 Word 报告。本文将介绍如何结合 POI-TL 和 JFreeChart&#xff0c;实现动态生成 W…

jenkins备份还原配置文件

下载ThinBackup插件 方式1 从插件市场直接下载 Manage Jenkins->Manage Plugins->可选插件搜索 注意&#xff1a;有时可能因为网络或者版本问题下载不了&#xff0c;好像是默认下载最新版本&#xff0c;可选择手动安装&#xff01; 方式二 手动安装插件 点击查看手…

C++蓝桥杯基础篇(二)

片头 嗨&#xff01;小伙伴们&#xff0c;今天我们将学习C蓝桥杯基础篇&#xff08;二&#xff09;&#xff0c;继续练习相关习题&#xff0c;准备好了吗&#xff1f;咱们开始咯~ 第1题 简单计算器输入两个数&#xff0c;以及一个运算符 &#xff0c;-&#xff0c;*&#xff…

将 AMD Zynq™ RFSoC 扩展到毫米波领域

目录 将 AMD Zynq™ RFSoC 扩展到毫米波领域Avnet XRF RFSoC 系统级模块适用于 MATLAB 的 Avnet RFSoC Explorer 工具箱5G mmWave PAAM 开发平台突破性的宽带毫米波波束成形特征&#xff1a;OTBF103 Mathworks Simulink 模型优化毫米波应用中的射频信号路径 用于宽带毫米波上/下…

1Panel配置java运行环境运行springboot项目

一、实际运行效果 1panel上java容器springboot的简单web项目 二、详细操作 步骤一、完成spring项目的打包&#xff0c;生成jar文件 步骤二、登录1panel&#xff0c;点击系统-》文件菜单&#xff0c;上传jar到一个合适的文件夹目录&#xff0c;/opt/jar 如下图&#xff1a; 步…

Jenkins+gitee 搭建自动化部署

Jenkinsgitee 搭建自动化部署 环境说明&#xff1a; 软件版本备注CentOS8.5.2111JDK1.8.0_211Maven3.8.8git2.27.0Jenkins2.319最好选稳定版本&#xff0c;不然安装插件有点麻烦 一、安装Jenkins程序 1、到官网下载相应的版本war或者直接使用yum安装 Jenkins官网下载 直接…

ubuntu安装VMware报错/dev/vmmon加载失败

ubuntu安装VMware报错/dev/vmmon加载失败&#xff0c;解决步骤如下&#xff1a; step1&#xff1a;为vmmon和vmnet组件生成密钥对 openssl req -new -x509 -newkey rsa:2048 -keyout VMW.priv -outform DER -out VMW.der -nodes -days 36500 -subj "/CNVMware/"ste…

LSTM 学习笔记 之pytorch调包每个参数的解释

0、 LSTM 原理 整理优秀的文章 LSTM入门例子&#xff1a;根据前9年的数据预测后3年的客流&#xff08;PyTorch实现&#xff09; [干货]深入浅出LSTM及其Python代码实现 整理视频 李毅宏手撕LSTM [双语字幕]吴恩达深度学习deeplearning.ai 1 Pytorch 代码 这里直接调用了nn.l…

细读 React | React Router 路由切换原理

2022 北京冬奥会开幕式 此前一直在疑惑&#xff0c;明明 pushState()、replaceState() 不触发 popstate 事件&#xff0c;可为什么 React Router 还能挂载对应路由的组件呢&#xff1f; 翻了一下 history.js 源码&#xff0c;终于知道原因了。 源码 假设项目路由设计如下&#…

Flutter 双屏双引擎通信插件加入 GitCode:解锁双屏开发新潜能

在双屏设备应用场景日益丰富的当下&#xff0c;移动应用开发领域迎来了新的机遇与挑战。如何高效利用双屏设备优势&#xff0c;为用户打造更优质的交互体验&#xff0c;成为开发者们关注的焦点。近日&#xff0c;一款名为 Flutter 双屏双引擎通信插件的创新项目正式入驻 GitCod…

【C++高并发服务器WebServer】-18:事件处理模式与线程池

本文目录 一、事件处理模式1.1 Reactor模式1.2 Proactor模式1.3 同步IO模拟Proactor模式 二、线程池 一、事件处理模式 服务器程序通常需要处理三类事件&#xff1a;I/O事件、信号、定时事件。 对应的有两种高效的事件处理模式&#xff1a;Reactor和Proactor&#xff0c;同步…