IDEA构建SpringBoot多模块项目

前言

最近一直在思考一个问题,springboot的多模块项目到底是怎么运行和运作的?

一般我们大部分的springboot项目都是单模块的项目,但是如果后续有要求开发多模块的项目应该怎么处理?于是基于这点进行了研究。

本次文章将会带大家从头到尾搭建多模块项目,讲解怎么去串接以及如何去运行

优缺点

🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️🖊️

多模块的项目,一般也叫微服务项目,微服务是一种架构模式或者说是一种架构风格,它提倡单一应用程序划分为一组小的服务,每个服务在其独立的自己的进程中,服务之间相互协调,互相配合,为用户提供最终价值
而我们的多模块的恰恰是这种思想

🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️🖌️

🩷🩷优点🩷🩷

❤️ 每个服务足够内聚,足够小,代码容易理解这样能聚焦一个指定的业务功能或业务需求
❤️开发简单、开发效率提高,一个服务可能就是专一的只干一件事
❤️微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的
以及其他…

🖤🖤缺点🖤🖤

🖤 开发人员要处理分布式系统的复杂性
🖤 多服务运维难度,随着服务的增加,运维的压力也在增大
🖤维护,分工合作困难

模块划分及依赖引用

模块划分

我的风格可能和别人不一样,别人一上来就会教你步骤,但是针对于这点,我们首先得明确一点,我们要搭建一个什么样的项目,针对你要搭建的项目,需要建立的模块也不一样

🖍️🖍️🖍️🖍️🖍️

以业务层划分为例,也就是我们熟知的三层架构
也就是可以划分为数据库层,web层和实现层,对应可划分的框架明细如下

模块名称模块功能范围
data实体类模块,负责实体对象的构建
config配置类模块,负责springboot相关的基础配置
dao数据库类模块,负责数据库增删改查相关逻辑
service业务实现类模块,负责具体业务实现相关逻辑
web项目启用类模块,负责项目启用,接口调用相关逻辑

🖊️🖊️🖊️🖊️🖊️

除了按照我们的三层架构的进行划分模块外,我们也可以用我们具体的实际业务进行划分

  • 举一个例子,按照学校为例,我们学校如果要记录数据,可以按照这些进行划分
模块名称模块功能范围
student学生信息类模块,负责记录学生基本数据
teacher老师信息类模块,负责记录教师相关基本数据
grade学生成绩类模块,负责记录学生成绩数据

那么这里我只是简单的举一个例子,那么为了演示方便,本文章会按照三层架构的进行讲解

依赖引用

✏️✏️✏️✏️✏️

在正式搭建项目之前,我们有一个比较重要的事情需要确认,那就是我们的模块之间应该要怎么进行引用?

因为这会涉及到一个问题,那就是循环依赖

什么是循环依赖?

循环依赖即你A模块引入了B模块,但是B模块也引入了A模块,导致报错

循环依赖有什么影响?

✨第一点,最重要,会导致项目无法启动
✨第二点,如果前期不规划好怎么引入,会导致出现一个问题,假如有A,B,C三个模块,你要在C模块开发逻辑,但是需要引入A模块的代码,目前的引入是A引入B和C,B引入C,因为C已经被A引入了,但是C无法引入A,如果强行引入会造成循环依赖,但是假如你要在C拿到A的代码,是无法拿到的,因为没有引入对应模块,无法调用对方的方法

感觉有点绕,那么简单的说,就是我们需要规范好怎么引入模块,才能确保所有模块各司其职,不会出现需要调用到对应的代码但是调用不到的情况

✏️✏️✏️✏️✏️

按照我们的三层框架,我们应该怎么引入?

首先,config是配置,应该是一个独立的模块,其他模块可以依赖于它

data是一个实体类相关的,那么它应该可以被任意的模块调用到

service 依赖于data,dao,需要进行数据库的调用,才能做到业务相关的逻辑

dao,因为和数据库相关的进行交互,而数据库连接相关逻辑一般会写在config,所以dao依赖于config

web,是接口调用和启动相关的逻辑,所以依赖于serviceconfig 模块

模块名称模块引入范围
data
config
daodata, config
servicedata,dao,service
webconfig,service

✒️✒️✒️✒️✒️

搭建步骤

那么正式开始我们的搭建

  • 首先,我们选择新建项目
    新建一个MAVEN项目,填写项目名称,组织等

PS: 我的IDEA为2024,可能部分操作有些不一样,但是建立的项目大差不差

在这里插入图片描述

初始项目搭建为如下:

在这里插入图片描述

接下来把搭建的项目的src文件夹删掉,只保留pom.xml

在这里插入图片描述

然后在该项目,选择新建module

NEW -> Module..

在这里插入图片描述

新建config模块

在这里插入图片描述
在这里插入图片描述

然后把config模块的Main的主入口文件删除

在这里插入图片描述

按照如上步骤,把剩下的模块新建出来,同样把Main入口删除,但是只保留web模块的Main入口文件

最终项目结构如下:

在这里插入图片描述

这里为了方便标识,我把web模块的Main修改为WebApplication

在这里插入图片描述
然后我们把父模块的pom.xml修改为如下:

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hxc</groupId><artifactId>multipleModuleDemo</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><name>multipleModule</name><description>多module项目demo</description><modules><module>config</module><module>web</module><module>dao</module><module>service</module><module>data</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.6.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.6.2</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.8.1</version> <!-- 根据需要调整版本 --><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><version>2.6.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.18</version><optional>true</optional></dependency></dependencies></project>

这里我引入了springboot相关的一些必要依赖,后续可根据实际项目情况进行添加,另外父模块的依赖是能够被子模块引入的,有什么必要的也可以引入到父模块的pom,或者新加一个common模块,专门供其他子模块调用

config的pom.xml修改:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.hxc</groupId><artifactId>multipleModulesDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>config</artifactId><name>config</name><version>1.0-SNAPSHOT</version><description>配置模块</description></project>

data的pom.xml修改:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.hxc</groupId><artifactId>multipleModulesDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>data</artifactId><version>1.0-SNAPSHOT</version><name>data</name><description>数据实体模块</description></project>

dao的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.hxc</groupId><artifactId>multipleModulesDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>dao</artifactId><version>1.0-SNAPSHOT</version><name>dao</name><description>数据库</description><dependencies><dependency><groupId>com.hxc</groupId><artifactId>data</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.hxc</groupId><artifactId>config</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency></dependencies></project>

service的pom.xml修改:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.hxc</groupId><artifactId>multipleModulesDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>service</artifactId><version>1.0-SNAPSHOT</version><name>service</name><description>逻辑层</description><dependencies><dependency><groupId>com.hxc</groupId><artifactId>dao</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.hxc</groupId><artifactId>data</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.hxc</groupId><artifactId>config</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

web的pom.xml修改:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.hxc</groupId><artifactId>multipleModulesDemo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>web</artifactId><dependencies><dependency><groupId>com.hxc</groupId><artifactId>config</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.hxc</groupId><artifactId>service</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.6.2</version></dependency></dependencies></project>

那么,为了能够正常的搭建一个可以启用的多模块项目,我这里补充一个逻辑代码,实现查询和新增接口正常调用和项目启动

在数据库新建一个用户表userData,建表语句如下

CREATE TABLE userData (user_id varchar(100) NOT NULL COMMENT 'userId',nick_name varchar(100) NULL COMMENT '名称',sex varchar(10) NULL COMMENT '性别',age INT NULL COMMENT '年龄',CONSTRAINT userData_pk PRIMARY KEY (user_id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci;

在data模块新建一个实体UserData

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;@Getter
@Setter
@ToString
public class UserData {private String userId;private String nickName;private String sex;private Integer age;
}

在这里插入图片描述

在dao模块新建一个jdbc数据库查询代码UserDataDao

import com.hxc.user.UserData;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class UserDataDao {private static final String SQL_INS = "INSERT INTO userdata(user_id,nick_name,sex,age) VALUES (?,?,?,?)";private static final String SQL_UPD = "UPDATE userdata SET nick_name=?,sex=?,age=? WHERE userid=?";private static final String SQL_SEL = "SELECT user_id,nick_name,sex,age FROM userdata ";private static final String SQL_DEL = "DELETE FROM userdata WHERE user_id = ?";private final Connection conn;public UserDataDao(Connection conn) {this.conn = conn;}public int insert(UserData data) {try (PreparedStatement ps = this.conn.prepareStatement(SQL_INS)) {ps.setString(1, data.getUserId());ps.setString(2, data.getNickName());ps.setString(3, data.getSex());ps.setInt(4, data.getAge());return ps.executeUpdate();} catch (SQLException e) {throw new IllegalStateException("数据库查询错误, " + e.getMessage(), e);}}public int update(UserData data) {try (PreparedStatement ps = this.conn.prepareStatement(SQL_UPD)) {ps.setString(1, data.getNickName());ps.setString(2, data.getSex());ps.setInt(3, data.getAge());ps.setString(4, data.getUserId());return ps.executeUpdate();} catch (SQLException e) {throw new IllegalStateException("数据库查询错误, " + e.getMessage(), e);}}public int delete(String userId) {try (PreparedStatement ps = this.conn.prepareStatement(SQL_DEL)) {ps.setString(1, userId);return ps.executeUpdate();} catch (SQLException e) {throw new IllegalStateException("数据库查询错误, " + e.getMessage(), e);}}public List<UserData> selectAll() {ArrayList<UserData> result = new ArrayList<UserData>();try (PreparedStatement ps = this.conn.prepareStatement(SQL_SEL)) {ResultSet rs = ps.executeQuery();while (rs.next()) {result.add(convert(rs));}return result;} catch (SQLException e) {throw new IllegalStateException("数据库查询错误, " + e.getMessage(), e);}}public UserData selectByUserId(String userId) throws SQLException {UserData result = null;try (PreparedStatement ps = conn.prepareStatement(SQL_SEL + "WHERE user_id = ?")) {ps.setString(1, userId);ResultSet rs = ps.executeQuery();if (rs.next()) {result = convert(rs);}return result;} catch (SQLException e) {throw new SQLException(e.getMessage());}}private UserData convert(ResultSet rs) throws SQLException {UserData data = new UserData();int index = 1;data.setUserId(rs.getString(index++));data.setNickName(rs.getString(index++));data.setSex(rs.getString(index++));data.setAge(rs.getInt(index++));return data;}
}

在这里插入图片描述

在config模块新建一个数据库连接配置DataSourceConfig,和数据库连接实现类PrimeDB

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;/*** 数据库配置* */
@Configuration
public class DataSourceConfig {@Value("${spring.datasource.prime-data.driver-class-name}")private String primeDataDriver;@Value("${spring.datasource.prime-data.url}")private String primeDataUrl;@Value("${spring.datasource.prime-data.username}")private String primeDataUsername;@Value("${spring.datasource.prime-data.password}")private String primeDataPassword;@Beanpublic DriverManagerDataSource primeDataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName(primeDataDriver);dataSource.setUrl(primeDataUrl);dataSource.setUsername(primeDataUsername);dataSource.setPassword(primeDataPassword);return dataSource;}// 配置其他数据库连接(待定占位)@Beanpublic DriverManagerDataSource otherDataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName(primeDataDriver);dataSource.setUrl(primeDataUrl);dataSource.setUsername(primeDataUsername);dataSource.setPassword(primeDataPassword);return dataSource;}
}
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;@Component
public class PrimeDB {private final DataSource primeDataSource;@Autowiredpublic PrimeDB(@Qualifier("primeDataSource")DataSource primeDataSource) {this.primeDataSource = primeDataSource;}public Connection create() throws SQLException {Connection connection = null;try {connection = primeDataSource.getConnection();return connection;} catch (SQLException e) {// 处理连接获取失败的异常情况throw new RuntimeException("连接数据库失败:", e);}}
}

在这里插入图片描述
那么为了可以实现测试类正常调用,可在config的resource下建立一个application.yml,为数据库连接配置,但是为了正常启用项目,需要在web模块的resource新建一个application.yml

如下为config的resource下建立一个application.yml

spring:application:name: multipleModuleBackdatasource:prime-data:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/primeData?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=false&rewriteBatchedStatements=true&useCompression=false&useSSL=falseusername: rootpassword: root

在我们的service模块,新建一个UserService

import com.hxc.dao.UserDataDao;
import com.hxc.user.UserData;
import java.sql.Connection;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;@Service
public class UserService {public UserData findUser(Connection conn, String userId) throws Exception {try {UserDataDao userDataDao = new UserDataDao(conn);UserData userData = userDataDao.selectByUserId(userId);if (null == userData) {throw new Exception("查无用户:" + userId);}return userData;} catch (Exception e) {throw new Exception("获取用户失败:" + e);}}public String insertUser(Connection conn, UserData userData) throws Exception {try {UserDataDao userDataDao = new UserDataDao(conn);if (!StringUtils.hasText(userData.getUserId())) {throw new Exception("用户id不能为空!");}if (!StringUtils.hasText(userData.getNickName())) {throw new Exception("用户名称不能为空!");}UserData record = userDataDao.selectByUserId(userData.getUserId());if (null != record) {throw new Exception("用户:" + userData.getUserId() + "已存在");}userDataDao.insert(userData);return "新增成功!";} catch (Exception e) {throw new Exception("新增用户失败:" + e);}}
}

在这里插入图片描述

在web模块下建立一个接口调用文件UserWebServicer

import com.hxc.configs.db.PrimeDB;
import com.hxc.user.UserData;
import java.sql.Connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserWebServicer {@Autowiredprivate PrimeDB primeDB;@GetMapping("/findUser")public UserData findUser(@RequestParam("userId") String userId) throws Exception {System.out.println("Received request with userId: " + userId);try (Connection conn = primeDB.create()) {return new UserService().findUser(conn, userId);} catch (Exception e) {throw new Exception(e);}}@PostMapping("/insertUser")public String sendMessage(@RequestBody UserData userData) throws Exception {try (Connection conn = primeDB.create()) {return new UserService().insertUser(conn, userData);} catch (Exception e) {throw new Exception(e);}}
}

同时把webApplication的代码修改为:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class WebApplication {public static void main(String[] args) {System.out.println("多模块项目启动主入口");SpringApplication.run(WebApplication.class, args);}
}

然后在web模块的resource下新建一个application.yml

server:port: 8082servlet:context-path: /multipleModulespring:application:name: multipleModuleBackdatasource:prime-data:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/primeData?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=false&rewriteBatchedStatements=true&useCompression=false&useSSL=falseusername: rootpassword: root

这个时候我们就可以右键WebApplication启动我们的项目了

在这里插入图片描述

现在我的数据该表的数据有如下:

在这里插入图片描述

调用我的查询接口结果如下:

在这里插入图片描述

我们的项目正常运行

重要信息

以此,我们的项目就正式搭建好了,后续我们这个项目的调用情况是在data模块进行建立实体,我们的dao模块调用data模块的实体,和config的数据库连接进行数据库的增删改查,然后我们的service模块进行业务逻辑的开发,在web编写接口调用我们的业务逻辑,按照这个顺序执行就能够正常的运行我们的项目,不会出现循环依赖问题,后续如果有新加别的模块也是按照这个思路进行添加

git项目demo

如下为本次教学的项目demo链接,可进行参考
SPRINGBOOT 多模块项目DEMO

结语

以上为springboot搭建多模块的方法和步骤,如有遗漏将在本文章补充

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

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

相关文章

java语言特点

Java语言是一种广泛使用的编程语言&#xff0c;它具有以下几个显著的特点&#xff1a; 面向对象&#xff1a;Java是一种纯面向对象的语言&#xff0c;它支持类的封装、继承和多态等特性。面向对象的设计使得Java程序更加模块化&#xff0c;易于维护和扩展。 平台无关性&#xf…

Linux驱动开发基础(Hello驱动)

所学内容来自百问网 目录 1. 文件在内核中的表示 2. 打开字符设备节点时&#xff0c;内核中也有对应的struct file 3. 编写驱动程序步骤 4. 相关知识点 4.1 涉及函数解析 4.2 module_init/module_exit的实现 4.3 register_chrdev的内部实现 4.4 class_destroy/device_…

K8s知识内容总结

1. K8s是个什么东西&#xff1f;解决了什么核心问题&#xff1f;相比docker有什么核心优势&#xff1f; k8s源于google内部的一个集群管理系统&#xff0c;它是用来管理集群的。比例&#xff0c;一个大型的电商系统&#xff0c;在微服务架构模式下&#xff0c;一个集群中可能有…

冒泡,选择,插入,希尔,快速,归并

冒泡&#xff0c;选择&#xff0c;插入&#xff0c;希尔&#xff0c;快速&#xff0c;归并 选择类的排序&#xff1a;选择排序&#xff0c;堆排序 交换类的排序&#xff1a;冒泡&#xff0c;快排 #include <stdio.h> #include<stdbool.h> #include<stdlib.h&…

10个html+css+js 绚丽按钮合集(1)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享10个htmlcssjs 绚丽按钮合集(1) 创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文章目录 10个htmlcssjs 绚丽按钮第1个&#xff1a;效果&#xff…

Selenium + Python 自动化测试06(frame操作方法)

上一篇我们讲述了特殊元素的操作方法&#xff0c;本篇接着讲一些可能遇到的其它操作方法。 如frame操作。 Frame 标签有Frameset、Frame、Iframe 3种&#xff0c;Frameset可以直接照常进行元素定位。Frame、Iframe需要驱动切换到对应的frame才可以定位到。否则 &#xff0c;会…

【人工智能】AI浪潮下,程序员何去何从?

人工智能时代&#xff0c;程序员何去何从&#xff1f; 随着AIGC&#xff08;如chatgpt、midjourney、claude等&#xff09;大语言模型接二连三的涌现&#xff0c;AI辅助编程工具日益普及&#xff0c;程序员的工作方式正在发生深刻变革。有人担心AI可能取代部分编程工作&#x…

[第五空间 2021]WebFTP

打开题目所给的环境&#xff0c;发现要求我们输入账号密码&#xff0c;尝试输入了一些随意的账号密码&#xff0c;显示账号密码错误。这里我先用bp拦截&#xff0c;但是并没有找到什么有用的东西&#xff0c;然后这里用dirsearch扫一下后台&#xff1a; 发现这里是git泄露&…

SQL Zoo 8+.NSS Tutorial

以下数据来自SQL Zoo 1.at Edinburgh Napier University&#xff0c;studying (8) Computer Science&#xff0c;Show the the percentage who STRONGLY AGREE.&#xff08;在爱丁堡纳皮尔大学&#xff0c;学习“计算机科学”&#xff0c;显示STRONGLY AGREE的百分比&#xff0…

MySQL 实战 45 讲(01-05)

本文为笔者学习林晓斌老师《MySQL 实战 45 讲》课程的学习笔记&#xff0c;并进行了一定的知识扩充。 sql 查询语句的执行流程 大体来说&#xff0c;MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器和执行器。 连接器负责接收客…

Debezium日常分享系列之:Debezium UI 的状态

Debezium日常分享系列之&#xff1a;Debezium UI 的状态 一、下一阶段工作二、设计新的UI三、目前阶段四、更多内容 虽然Debezium的UI是我们愿景的重要组成部分&#xff0c;但开发与Kafka Connect紧密绑定的UI并不是正确的方向。因此&#xff0c;决定冻结当前Web UI项目的开发。…

【UE 网络】Network Role and Authority、Actors Owner、Actor Role and RemoteRole

目录 0 引言1 Network Role and Authority&#xff08;网络角色和授权&#xff09;1.1 Authority (权威角色 / 权威端)1.2 Simulated Proxy (模拟代理 / 模拟端)1.3 Autonomous Proxy (自主代理 / 主动端)1.4 示例&#xff1a;多人塔防游戏中的 NetRole 2 Actors and their Own…

QT 网络聊天室简易版

视频:qt开发网络聊天w室软件3.4界面开发_哔哩哔哩_bilibili 目录 UI部分 设计稿图 放置控件 界面美化 拖动窗体 设置界面 网络部分 配置对话框 多项目结果和服务器端设计 客户端框架开发 UI部分 设计稿图 放置控件 界面美化 现在我们把窗体自带的标题栏给去了,用我们自…

[论文泛读]zkLLM: Zero Knowledge Proofs for Large Language models

文章目录 介绍实验数据实验数据1实验数据2实验数据3 介绍 这篇文章发在CCS2024&#xff0c;CCS是密码学领域的顶会。作者是来自加拿大的University of Waterloo。文章对大语言模型像GPT和LLM等大语言模型实现了零知识可验证执行&#xff0c;但不涉及零知识可验证训练。个人觉得…

WUP-CH34X ch34x系列芯片USB转串口通信uniapp插件使用说明

插件地址&#xff1a;WUP-CH34X 系列芯片USB转串口通信安卓库 简介 本文档是针对 CH340/CH341/CH342/CH343/CH344/CH347/CH9101/CH9102/CH9103/CH9104/CH9143的 USB 转串口安卓库的开发说明文档。 主要介绍如何使用芯片的 USB 转异步串口功能&#xff08;以下简称 CH34XUART…

循环神经网络三

一.介绍 在普通的神经网络中&#xff0c;信息的传递是单向的&#xff0c;这种限制虽然使得网络变得更容易学习&#xff0c;单在一定程度上也减弱了神经网络模型的能力。特别是在现实生活中&#xff0c;网络的输出不仅和当前时刻的输入相关&#xff0c;也过去一段时间的输出相关…

Typora 伪装 LaTeX 中文样式主题 学习笔记

最近发现一个比较有意思的项目&#xff0c;Typora 伪装 LaTeX 中文样式主题 用来写毕设论文的初稿&#xff0c;格式可以统一控制&#xff0c;比较方便。项目“第五章”源格式是“5 系统测试”靠左&#xff0c;就像5.1一样。搜索了一下获得了一些零散的知识点记下来。 在Typora的…

Linux C 程序 【04】线程分离

1.开发背景 Linux 线程区分于FreeRTOS&#xff0c;线程的属性形态有2中&#xff0c;在 pthread.h 中有注解&#xff0c;如下。 /* Detach state. */ enum {PTHREAD_CREATE_JOINABLE, #define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLEPTHREAD_CREATE_DETACHED #defin…

Jenkins保姆笔记(2)——基于Java8的Jenkins插件安装

前面我们介绍过&#xff1a; Jenkins保姆笔记&#xff08;1&#xff09;——基于Java8的Jenkins安装部署 本篇主要介绍下基于Java8的Jenkins插件安装。为什么要单独讲一个插件安装&#xff1f;因为一些原因&#xff0c;Jenkins自带的插件源下载几乎都会失败&#xff0c;如图…

【vulhub靶场之thinkphp】——(5-rce)

第一步&#xff1a;打开靶场 输入开启命令 cd vulhub/thinkphp/5-rce docker-compose up -d docker-compose ps//查看开启的端口 第二步&#xff1a; 访问网址 第三步&#xff1a;漏洞利用 漏洞根本源于 thinkphp/library/think/Request.php 中method方法可以进行变量覆盖&am…