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

【基于Spring Boot 的图书购买系统】深度讲解 用户注册的前后端交互,Mapper操作MySQL数据库进行用户持久化

引言

在现代Web应用中,用户注册功能是用户与应用交互的入口。一个高效、安全且用户友好的注册系统不仅能吸引用户,还能为后续功能(如个性化服务)奠定基础。本博客将通过一个实际案例,展示如何使用HTML、JavaScript、jQuery、Spring Boot和MyBatis实现用户注册系统。我们将从前端表单设计开始,逐步深入到后端的Controller、Service和Mapper层,解析整个流程的技术细节。

本文将结合具体的代码示例,详细解析一个基于Spring Boot和MyBatis的用户注册功能的完整实现过程,涵盖前后端交互协议设计、业务逻辑分层实现、代码细节优化等方面,帮助读者理解企业级应用中用户注册模块的开发思路。
在这里插入图片描述

在这里插入图片描述

1. 约定前后端交互接口

在前后端分离开发中,清晰的接口约定是协作的基础。本案例中,用户注册功能的接口设计如下:

1.1 接口基本信息

  • URL/user/register
  • 请求方法:POST
  • 请求格式:表单数据(Form Data)
  • 响应格式:JSON

1.2 请求参数

参数名类型是否必填说明
userNameString用户名(唯一标识)
passwordString密码

1.3 响应结果

响应体统一封装为Result对象,结构如下:

public class Result {private String status;        // 状态码(SUCCESS/FAIL)private String errorMessage;  // 错误信息(失败时返回)// 省略getter/setter
}
  • 成功响应

    {"status": "SUCCESS"
    }
    
  • 失败响应

    {"status": "FAIL","errorMessage": "用户已存在,请重新注册"
    }
    

2. 整体逻辑

用户注册功能采用典型的三层架构设计,各层职责清晰,便于维护和扩展。以下从Controller、Service层、Mapper层三个维度解析整体逻辑。
在这里插入图片描述

2.1 Controller的逻辑

职责:处理HTTP请求,完成参数校验,调用Service层业务逻辑,封装响应结果。

核心流程

  1. 接收前端传递的UserInfo对象,校验是否为null(防止空参数请求)。
  2. 调用UserInfoServiceregisterUserInfo方法执行注册逻辑。
  3. 根据Service层返回的Result对象,设置响应状态和错误信息(若有)。

关键点

  • 使用@RestController@RequestMapping注解声明控制器和路由。
  • 通过方法参数直接接收UserInfo对象,依赖Spring MVC的自动绑定机制。
  • 日志记录(通过@Slf4j注解引入Logback)用于追踪异常场景。

2.2 Service层

职责:实现核心业务逻辑,处理事务管理,协调Mapper层完成数据库操作。

核心流程

  1. 用户唯一性校验:调用Mapper查询用户名是否已存在,若存在则返回失败。
  2. 用户数据插入:向数据库插入用户基本信息(用户名、密码)。
  3. 创建用户专属图书表:插入成功后,根据用户ID动态创建用于存储图书信息的表。
  4. 事务控制:通过@Transactional注解确保插入用户和创建表的操作具有原子性(若其中一步失败,整体回滚)。

设计亮点

  • 将业务逻辑与数据访问解耦,提高代码可测试性。
  • 通过事务管理保证数据一致性,避免因部分操作失败导致的脏数据。

2.3 Mapper层

职责:定义数据库操作接口,编写SQL语句,实现与数据库的交互。

核心方法

  1. queryUserInfoByUserNameNormal:根据用户名查询用户信息,用于校验用户唯一性。
  2. insertUserInfo:插入用户基本信息到normal_user_info表。
  3. createBooktable:根据用户ID动态创建{userId}_book_info表,用于存储用户的图书数据。

技术细节

  • 使用MyBatis的注解式映射(@Select@Insert)和XML映射混合方式。
  • 动态表名通过XML中的${id}实现(需注意SQL注入风险,后文将详细讨论)。

3. 后端代码实现

3.1 Controller层

代码示例

@Slf4j
@RestController
@RequestMapping("/user")
public class UserInfoController {@Autowiredprivate UserInfoService userInfoService;@RequestMapping("/register")public Result register(UserInfo userInfo) {Result result = new Result();// 基础参数校验:防止空对象请求if (userInfo == null) {result.setStatus(ResultStatus.FAIL);result.setErrorMessage("请填写账号密码");return result;}// 调用Service层业务逻辑result = userInfoService.registerUserInfo(userInfo);// 处理Service层返回的空结果(防御性编程)if (result == null) {result = new Result();result.setStatus(ResultStatus.FAIL);result.setErrorMessage("注册失败");log.info("注册时,Service返回的result为空");} else {// 注册成功时设置状态为SUCCESSresult.setStatus(ResultStatus.SUCCESS);}return result;}
}

关键逻辑解析

  1. 参数校验:首先检查userInfo是否为null,避免因前端未传递参数导致的空指针异常。
  2. 依赖注入:通过@Autowired注入UserInfoService,实现Controller与Service的解耦。
  3. 结果处理:对Service层返回的Result进行二次校验,防止出现null指针,体现防御性编程思想。
  4. 日志记录:使用log.info记录异常场景,便于后续问题排查。

3.2 Service层

代码示例

@Slf4j
@Service
public class UserInfoService {@Autowiredprivate UserInfoMapper userInfoMapper;@Transactionalpublic Result registerUserInfo(UserInfo userInfo) {Result result = new Result();// 1. 校验用户是否已存在UserInfo existingUser = userInfoMapper.queryUserInfoByUserNameNormal(userInfo.getUserName());if (existingUser != null) {result.setErrorMessage("用户已存在,请重新注册");result.setStatus(ResultStatus.FAIL);return result;}// 2. 插入用户基本信息Integer insertCount = userInfoMapper.insertUserInfo(userInfo);if (insertCount != 1) {result.setStatus(ResultStatus.FAIL);result.setErrorMessage("用户注册失败");log.info("新用户插入后返回的值不是1,影响行数:{}", insertCount);return result;}// 3. 查询新用户ID(用于创建图书表)UserInfo newUser = userInfoMapper.queryUserInfoByUserNameNormal(userInfo.getUserName());if (newUser == null || newUser.getId() == null) {result.setStatus(ResultStatus.FAIL);result.setErrorMessage("获取用户ID失败,无法创建图书表");return result;}// 4. 创建用户专属图书表int tableCreateResult = userInfoMapper.createBooktable(newUser.getId());if (tableCreateResult != 1) { // 这里的返回值需根据实际SQL执行结果调整result.setStatus(ResultStatus.FAIL);result.setErrorMessage("创建图书表失败");log.info("创建图书表失败,用户ID:{}", newUser.getId());return result;}// 注册成功result.setStatus(ResultStatus.SUCCESS);return result;}
}

关键逻辑解析

  1. 事务管理:通过@Transactional注解声明该方法为事务性操作,确保插入用户和创建表的操作要么全部成功,要么全部回滚。
  2. 用户唯一性校验:先查询数据库,若用户名已存在则直接返回失败,避免重复注册。
  3. 插入结果校验:MyBatis的insert方法返回值为影响的行数,校验insertCount == 1确保插入成功。
  4. 动态表创建:根据新用户的ID创建专属表,实现数据隔离(如多租户场景下的用户数据分离)。
  5. 异常处理:对每一步数据库操作的结果进行校验,及时返回具体错误信息,便于前端友好提示。

4. 前端代码

4.1 HTML结构与样式

代码示例(关键部分)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>用户注册</title><link rel="stylesheet" href="css/bootstrap.min.css"><style>.container-login {display: flex;height: 100vh;}.container-pic {flex: 1;background-image: url('login-bg.jpg');background-size: cover;}.login-dialog {flex: 1;display: flex;justify-content: center;align-items: center;background-color: #f8f9fa;}.row {margin-bottom: 15px;}span {display: block;margin-bottom: 5px;font-weight: 500;}</style>
</head>
<body>
<div class="container-login"><div class="container-pic"></div><div class="login-dialog"><h3 class="mb-4">新用户注册</h3><form id="registerForm"><div class="row"><span>账户</span><input type="text" name="username" id="username" class="form-control" required></div><div class="row"><span>密码</span><input type="password" name="password" id="password" class="form-control" required></div><div class="row"><span>确认密码</span><input type="password" name="confirmPassword" id="confirmPassword" class="form-control" required></div><div class="row mt-4"><div class="col-md-6"><button type="button" class="btn btn-success btn-lg btn-block" onclick="submitRegister()">立即注册</button></div><div class="col-md-6"><button type="button" class="btn btn-secondary btn-lg btn-block" onclick="history.back()">返回登录</button></div></div></form></div>
</div>

设计解析

  1. 布局设计:使用Bootstrap的Flex布局实现左右分栏(左侧图片背景,右侧注册表单),适配响应式需求。
  2. 表单元素:包含用户名、密码、确认密码三个输入框,均使用required属性进行HTML5基础校验。
  3. 样式优化:通过自定义CSS实现视觉分层,如输入框间距、按钮颜色区分,提升用户体验。

4.2 JavaScript逻辑

代码示例

<script src="js/jquery.min.js"></script>
<script>function submitRegister() {// 前端密码一致性校验if ($("#password").val() !== $("#confirmPassword").val()) {alert("两次密码输入不一致!");return;}// 构造请求参数const params = {userName: $("#username").val(),password: $("#password").val()};// 发送AJAX请求$.ajax({url: "/user/register",type: "post",data: params,success: function(result) {if (result.status === "SUCCESS") {alert("注册成功!");window.location.href = "login_test.html"; // 跳转登录页} else {alert("注册失败:" + (result.errorMessage || "请重试"));}},error: function(xhr, status, error) {console.error("注册请求失败:", error);alert("网络异常,请稍后重试");}});}
</script>

关键逻辑解析

  1. 前端校验:在发送请求前校验两次输入的密码是否一致,减少无效请求。
  2. AJAX请求:使用jQuery的$.ajax方法发送POST请求,参数与后端接口约定一致(userNamepassword)。
  3. 响应处理:根据后端返回的status字段判断注册结果,成功则跳转登录页,失败则显示具体错误信息(或通用提示)。
  4. 异常处理:通过error回调处理网络错误等异常场景,提升系统健壮性。

5. 总结

5.1 实现亮点

  1. 分层架构清晰:Controller、Service、Mapper三层职责明确,符合单一职责原则,便于后续功能扩展和维护。
  2. 事务与一致性:通过Spring的声明式事务(@Transactional)确保用户数据插入与图书表创建的原子性,避免部分操作失败导致的数据不一致。
  3. 前后端校验结合:前端进行基础输入校验(如密码一致性),减少无效请求;后端进行业务逻辑校验(如用户唯一性),确保数据安全。
  4. 动态表设计:为每个用户创建专属图书表,实现数据物理隔离,适用于需要细粒度数据权限控制的场景。

5.2 可进行的优化

  1. 参数校验增强

    • 后端可引入Spring Validator或Hibernate Validator,通过@Validated注解和@NotEmpty@Pattern等注解实现更细粒度的参数校验(如用户名格式、密码强度)。
    • 前端可添加实时校验提示(如输入时显示密码强度),提升用户体验。
  2. SQL注入防范

    • Mapper层创建表的SQL中使用${id}拼接表名存在SQL注入风险(如用户ID为恶意字符串; DROP TABLE ...)。建议对userId进行严格校验(如确保为正整数),或采用预定义表前缀+合法字符过滤的方式。
    • 推荐使用MyBatis的@Param注解明确参数类型,并在Service层对用户ID进行类型转换和范围校验。
  3. 性能优化

    • 创建用户后再次查询用户ID的方式不够高效。MyBatis支持通过selectKey标签在插入时直接获取自增ID,可修改insertUserInfo方法如下:
      <insert id="insertUserInfo" parameterType="UserInfo">insert into normal_user_info (user_name, password) values(#{userName}, #{password})<selectKey keyProperty="id" resultType="Integer" order="AFTER">SELECT LAST_INSERT_ID()</selectKey>
      </insert>
      
      插入后userInfo对象的id字段会自动填充,避免二次查询。
  4. 安全增强

    • 密码存储应使用加密算法(如BCrypt、SHA-256),而非明文存储。可在Service层对密码进行加密处理后再存入数据库。
    • 添加验证码机制,防止暴力注册攻击。
  5. 异常处理统一化

    • 后端可自定义全局异常处理器(@ControllerAdvice),统一处理业务异常和系统异常,返回标准化的错误响应,避免Controller层重复编写错误处理代码。

5.3 扩展方向

  • 多租户支持:若系统面向多租户场景,可在用户表中增加租户标识(tenant_id),并在创建图书表时结合租户ID生成唯一表名。
  • 注册流程扩展:添加邮箱/手机验证环节,提升账号安全性;支持第三方登录(如微信、QQ),降低注册门槛。
  • 数据审计:在用户表中增加create_userupdate_user等审计字段,记录操作日志,便于追溯数据变更。

结语

用户注册功能虽看似简单,却涉及前后端交互、业务逻辑设计、数据库操作、安全性等多个技术维度。通过本文的案例解析,我们深入探讨了如何使用Spring Boot和MyBatis实现一个健壮的注册模块,同时也指出了实际开发中需要注意的细节(如事务管理、SQL安全、性能优化等)。在实际项目中,需根据具体业务需求和技术规范进行调整,确保功能既满足业务场景,又具备良好的可维护性和安全性。希望本文能为读者在开发类似功能时提供有益的参考。

相关文章:

【基于Spring Boot 的图书购买系统】深度讲解 用户注册的前后端交互,Mapper操作MySQL数据库进行用户持久化

引言 在现代Web应用中&#xff0c;用户注册功能是用户与应用交互的入口。一个高效、安全且用户友好的注册系统不仅能吸引用户&#xff0c;还能为后续功能&#xff08;如个性化服务&#xff09;奠定基础。本博客将通过一个实际案例&#xff0c;展示如何使用HTML、JavaScript、j…...

Spark,连接MySQL数据库,添加数据,读取数据

以下是使用 Spark/SparkSQL 连接 MySQL 数据库、添加数据和读取数据的完整示例&#xff08;需提前准备 MySQL 驱动包&#xff09;&#xff1a; 一、环境准备 1. 下载 MySQL 驱动 - 下载 mysql-connector-java-8.0.33.jar &#xff08;或对应版本&#xff09;&#xff0c;放…...

ubuntu的虚拟机上的网络图标没有了

非正常的关机导致虚拟机连接xshell连接不上&#xff0c;ping也ping不通。网络的图标也没有了。 记录一下解决步骤 1、重启服务 sudo systemctl restart NetworkManager 2、图标显示 sudo nmcli network off sudo nmcli network on 3、sudo dhclient ens33 //(网卡) …...

Linux系统:ext2文件系统的核心概念和结构

本节重点 块、块组、分区的引入块组的构成inode与inode Table路径解析与路径缓存机制目录与文件名在文件系统中的存储分区的初始化与挂载 一、ext2文件系统 1.1 “块”的引入 在前言部分我们说扇区是磁盘硬件的最小读写单位&#xff0c;通常为512字节&#xff0c;但是在操作…...

Python 装饰器详解

装饰器是 Python 中一种强大的语法特性&#xff0c;它允许在不修改原函数代码的情况下动态地扩展函数的功能。装饰器本质上是一个高阶函数&#xff0c;它接受一个函数作为参数并返回一个新的函数。 基本装饰器 1. 简单装饰器示例 def my_decorator(func):def wrapper():prin…...

Docker配置容器开机自启或服务重启后自启

要将一个 Docker 容器设置为开机自启&#xff0c;你可以使用 docker update 命令或配置 Docker 服务来实现。以下是两种常见的方法&#xff1a; 方法 1&#xff1a;使用 docker update 设置容器自动重启 使用 docker update 设置容器为开机自启 你可以使用以下命令&#xff0c…...

20250518 黎曼在三维空间中总结的一维二维的规律,推广到高维度合适吗?有没有人提出反对意见

黎曼在三维空间中总结的一维二维的规律&#xff0c;推广到高维度合适吗&#xff1f;有没有人提出反对意见 黎曼几何在数学物理中的广泛应用&#xff0c;尤其是在广义相对论和高维空间理论中&#xff0c;确实是建立在黎曼在三维空间中的推广基础上的。不过&#xff0c;这种推广…...

使用AI 生成PPT 最佳实践方案对比

文章大纲 一、专业AI生成工具(推荐新手)**1. 推荐工具详解****2. 操作流程优化****3. 优势与局限**二、代码生成方案(开发者推荐)**1. Python-pptx进阶用法****2. GitHub推荐**三、混合工作流(平衡效率与定制)**1. 工具链升级****2. 示例Markdown结构**四、网页转换方案(…...

【Docker】Docker Compose方式搭建分布式协调服务(Zookeeper)集群

开发分布式应用时,往往需要高度可靠的分布式协调,Apache ZooKeeper 致力于开发和维护开源服务器&#xff0c;以实现高度可靠的分布式协调。具体内容见zookeeper官网。现代应用往往使用云原生技术进行搭建,如何用Docker搭建Zookeeper集群,这里介绍使用Docker Compose方式搭建分布…...

R for Data Science(3)

R for Data Science以下是关于网页内容的详细笔记&#xff1a; 1. 章节概览 章节主题&#xff1a;数据转换&#xff08;Data Transformation&#xff09;核心内容&#xff1a;介绍如何使用 R 中的 dplyr 包进行数据转换&#xff0c;包括对数据框的行、列和组的操作&#xff0…...

深入浅出Hadoop:大数据时代的“瑞士军刀”

深入浅出Hadoop&#xff1a;大数据时代的“瑞士军刀” 在当今这个数据爆炸的时代&#xff0c;每天产生的数据量已经远超人类的想象。从社交媒体的互动到电商平台的交易记录&#xff0c;从物联网设备的实时监控到科学研究的实验数据&#xff0c;大数据已经成为推动各行各业变革…...

《Python星球日记》 第94天:走近自动化训练平台

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、自动化训练平台简介1. Kubeflow Pipelines2. TensorFlow Extended (TFX) 二…...

MetaMask安装及使用-使用水龙头获取测试币的坑?

常见的异常有&#xff1a; 1.unable to request drip, please try again later. 2.You must hold at least 1 LINK on Ethereum Mainnet to request native tokens. 3.The address provided does not have sufficient historical activity or balance on the Ethereum Mainne…...

软件架构之--论微服务的开发方法1

论微服务的开发方法1 摘要 2023年 2月,本人所在集团公司承接了长三角地区某省渔船图纸电子化审查系统项目开发,该项目旨在为长三角地区渔船建造设计院、以及渔船图纸审查机构提供一个便捷的渔船图纸电子化审查服务平台。在此项目中,我作为项目组成员参与项目的建设工作,并…...

SOLID 面对象设计的五大基本原则

SOLID 原则的价值 原则核心价值解决的问题SRP职责分离&#xff0c;提高内聚性代码臃肿、牵一发而动全身OCP通过扩展而非修改实现变化频繁修改现有代码导致的风险LSP确保子类行为的一致性继承滥用导致的系统不稳定ISP定制化接口&#xff0c;避免依赖冗余接口过大导致的实现负担…...

游戏引擎学习第293天:移动Familiars

回顾并为今天的内容定下基调 我们正在做一款完整的游戏&#xff0c;今天的重点是“移动模式”的正式化处理。目前虽然移动机制大致能运作&#xff0c;但写法相对粗糙&#xff0c;不够严谨&#xff0c;我们希望将其清理得更规范&#xff0c;更可靠一点。 目前脑逻辑&#xff0…...

《沙尘暴》观影记:当家庭成为人性的修罗场

起初点开《沙尘暴》&#xff0c;不过是想在碎片时间里寻个消遣&#xff0c;毕竟短剧的篇幅显得轻松无负担。未曾想&#xff0c;这看似简短的故事却如一场裹挟着砂砾的风暴&#xff0c;在心底掀起层层涟漪&#xff0c;让我忍不住在家庭教育、人性幽微处反复踱步沉思。 一、风暴眼…...

牛客网NC21989:牛牛学取余

牛客网NC21989:牛牛学取余 &#x1f4dd; 题目描述 ⏱️ 限制条件 时间限制&#xff1a;C/C/Rust/Pascal 1秒&#xff0c;其他语言2秒空间限制&#xff1a;C/C/Rust/Pascal 32 M&#xff0c;其他语言64 M输入范围&#xff1a;两个整数&#xff0c;在int范围内 &#x1f4e5;…...

王者荣耀游戏测试场景题

如何测试一个新英雄&#xff1a;方法论与实践维度 测试一个新英雄不仅仅是“打打打”&#xff0c;而是一套完整的测试流程&#xff0c;包括设计文档验证、功能验证、数值验证、性能验证、交互验证等。可以从以下多个角度展开&#xff1a; &#x1f50d; 1. 方法论维度 ✅ 测试…...

Spring Boot 与 RabbitMQ 的深度集成实践(二)

集成步骤详解 配置 RabbitMQ 连接信息 在 Spring Boot 项目中&#xff0c;通常在application.properties或application.yml文件中配置 RabbitMQ 的连接信息。以application.yml为例&#xff0c;配置如下&#xff1a; spring: rabbitmq: host: localhost port: 5672 usern…...

医疗信息系统安全防护体系的深度构建与理论实践融合

一、医疗数据访问系统的安全挑战与理论基础 1.1 系统架构安全需求分析 在医疗信息系统中&#xff0c;基于身份标识的信息查询功能通常采用分层架构设计&#xff0c;包括表现层、应用层和数据层。根据ISO/IEC 27001信息安全管理体系要求&#xff0c;此类系统需满足数据保密性…...

多模态大语言模型arxiv论文略读(八十)

## MMWorld: Towards Multi-discipline Multi-faceted World Model Evaluation in Videos ➡️ 论文标题&#xff1a;MMWorld: Towards Multi-discipline Multi-faceted World Model Evaluation in Videos ➡️ 论文作者&#xff1a;Xuehai He, Weixi Feng, Kaizhi Zheng, Yuji…...

FFmpeg:多媒体处理的终极利器

FFmpeg详细介绍 1. 定义与基本概述 FFmpeg是一套开源的跨平台多媒体处理工具集,最初由法国程序员Fabrice Bellard于2000年开发,其名称源自“Fast Forward MPEG”,体现了其高效处理MPEG格式的能力。它不仅是命令行工具,还包含多个库和开发套件,支持视频转码、剪辑、合并、…...

【Leetcode】取余/2的幂次方

给定一个非负整数 num&#xff0c;反复将各个位上的数字相加&#xff0c;直到结果为一位数。返回这个结果。 示例 1: 输入: num 38 输出: 2 解释: 各位相加的过程为&#xff1a; 38 --> 3 8 --> 11 11 --> 1 1 --> 2 由于 2 是一位数&#xff0c;所以返回 2。 …...

程序代码篇---ESP32的数据采集

文章目录 前言 前言 本文简单介绍了ESP32可以怎样采集数据。...

系统架构设计(十三):虚拟机体系结构风格

概念 虚拟机&#xff08;Virtual Machine&#xff09;体系结构风格&#xff0c;是指将整个系统抽象为一台“虚拟机”&#xff0c;通过解释或模拟的方式运行应用程序。 它本质上提供了一种“平台中立”的运行环境&#xff0c;典型代表就是 Java 虚拟机&#xff08;JVM&#xf…...

lvs-dr部署

实验准备&#xff1a; 准备4台设备&#xff0c;1台作为客户机&#xff0c;3台作为服务器&#xff0c;服务器中1台作为调度器&#xff0c;2台作为后端真实访问服务器。并关闭所有防火墙与核心防护。 systemctl stop firewalld setenforce 0 实验开始 调度器配置 yum -y ins…...

数据库blog2_数据结构与效率

&#x1f33f;计算机中的数据————存储结构与逻辑结构 &#x1f342;存储结构&#xff08;物理结构&#xff09; 定义&#xff1a;存储结构是指数据在计算机存储器中的实际存储方式&#xff0c;由计算机硬件特性决定。它涉及到数据的物理位置和存储顺序。存储结构直接影响数…...

聊天室项目总结

已实现的功能点&#xff1a; 存在的问题&#xff1a; 1.没有实现有含金量的创新功能点 2.太过于依赖工具&#xff0c;不喜欢自己看文章总结对知其然而不知其所以然&#xff0c;自己的理解比较少&#xff0c;懒于去思考 3.太过于依赖他人&#xff0c;自己的想法有点少&#x…...

数据结构:二叉树一文详解

数据结构:二叉树一文详解 前言一、二叉树的基本概念与结构特性1.1 二叉树的定义1.2 二叉树的特殊类型1.3 二叉树的性质 二、二叉树的遍历方式2.1 前序遍历&#xff08;Pre-order Traversal&#xff09;2.2 中序遍历&#xff08;In-order Traversal&#xff09;2.3 后序遍历&…...

2025年- H28-Lc136- 24.两两交换链表中的节点(链表)---java版

1.题目描述 2.思路 cur指针要先放在虚拟头节点&#xff0c;才能去操作第一个数和第二个数 先判断偶数个节点&#xff0c;再判断奇数个节点&#xff0c;否则会犯空指针异常。 &#xff08;1&#xff09;如果节点是偶数个节点&#xff0c;只要满足curr.nextnull&#xff0c;就说…...

ubuntu18.04通过cuda_11.3_xxx.run安装失败,电脑黑屏解决办法

项目场景&#xff1a; ubuntu18.04跑DG-SLAM相关代码&#xff0c;安装lietorch包报错&#xff0c;需要用到GPU。 问题描述 跑代码需要cuda11.3&#xff0c;系统里面有另外一个版本&#xff0c;运行cuda_11.3_xxx.run&#xff0c;同时也选择了driver&#xff0c;安装成功后&am…...

Linux之基础IO

目录 一、理解 "文件" 1.1、狭义理解 1.2、广义理解 1.3、文件操作的归类认知 1.4、系统角度 二、回顾C语言接口 2.1、打开文件 2.2、写文件 2.3、读文件 2.4、stdin & stdout & stderr 2.6、打开文件的方式 三、系统文件I/O 3.1、一种传递标志…...

上位机知识篇---涂鸦智能云平台

文章目录 前言 前言 本文简单介绍了涂鸦智能云平台。...

InfluxDB 3 Core + Java 11 + Spring Boot:打造高效物联网数据平台

一、 引言&#xff1a;为什么选择InfluxDB 3&#xff1f; 项目背景&#xff1a; 在我们的隧道风机监控系统中&#xff0c;实时数据的采集、存储和高效查询是至关重要的核心需求。风机运行产生的振动、倾角、电流、温度等参数是典型的时序数据&#xff0c;具有高并发写入、数据…...

Kubernetes控制平面组件:Kubelet详解(七):容器网络接口 CNI

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

Pandas 构建并评价聚类模型② 第六章

构建并评价聚类模型 构建并评价聚类模型一、数据读取与准备&#xff08;代码6 - 6部分&#xff09;结果代码解析 二、Kmeans聚类&#xff08;代码6 - 6部分&#xff09;结果代码解析 三、数据降维可视化&#xff08;代码6 - 6部分&#xff09;结果代码解析 四、FMI评价&#xf…...

【simulink】IEEE33节点系统潮流分析模型

目录 主要内容 程序内容 2.1 33节点simulink模型一览 2.2 节点模型图 下载链接 主要内容 该仿真采用simulink模型对33节点网络进行模拟仿真&#xff0c;在simulink模型中定义了33节点系统的电阻、电抗、节点连接关系等参数&#xff0c;通过控制块来实现信号连接关系&…...

彻底解决docker代理配置与无法拉取镜像问题

为什么会有这篇文章? 博主在去年为部署dify研究了docker,最后也是成功部署,但是因为众所周知的原因,卡ziji脖子 ,所以期间遇到各种网络问题的报错,好在最后解决了. 但时隔一年,博主最近因为学习原因又一次使用docker,原本解决的问题却又没来由的出现,且和之前有很多不同(有时…...

Linux 安装 Unreal Engine

需要对在unreal engine官网进行绑定github账号&#xff0c;然后到unreal engine github仓库中进行下载对应的版本&#xff0c;并进行安装unreal engine官网 github地址...

tensorflow图像分类预测

tensorflow图像分类预测 CPU版本和GPU版本二选一 CPU版本 pip -m install --upgrade pippip install matplotlib pillow scikit-learnpip install tensorflow-intel2.18.0GPU版本 工具 miniconda 升级依赖库 conda update --all创建目录 mkdir gpu-tf进入目录 cd gpu-tf创建虚…...

C++数组详解:一维和多维数组的定义、初始化、访问与遍历

1. 引言 数组是C中最基础的数据结构之一&#xff0c;用于存储相同类型的元素的集合。它提供了高效的内存访问方式&#xff0c;适用于需要快速查找和遍历数据的场景。本文将全面介绍&#xff1a; 一维数组的定义、初始化与遍历多维数组&#xff08;如二维数组&#xff09;的定…...

linux下编写shell脚本一键编译源码

0 前言 进行linux应用层编程时&#xff0c;经常会使用重复的命令对源码进行编译&#xff0c;然后把编译生成的可执行文件拷贝到工作目录&#xff0c;操作非常繁琐且容易出错。本文编写一个简单的shell脚本一键编译源码。 1 linux下编写shell脚本一键编译源码 shell脚本如下&…...

安卓端互动娱乐房卡系统调试实录:从UI到协议的万字深拆(第一章)

前言&#xff1a;调房卡&#xff0c;不如修空调&#xff08;但更费脑&#xff09; 老实说&#xff0c;拿到这套安卓端互动组件源码的时候&#xff0c;我内心是拒绝的。不是因为它不好&#xff0c;而是太好了&#xff0c;目录规整、界面精美、逻辑还算清晰&#xff0c;唯一的问…...

【通用大模型】Serper API 详解:搜索引擎数据获取的核心工具

Serper API 详解&#xff1a;搜索引擎数据获取的核心工具 一、Serper API 的定义与核心功能二、技术架构与核心优势2.1 技术实现原理2.2 对比传统方案的突破性优势 三、典型应用场景与代码示例3.1 SEO 监控系统3.2 竞品广告分析 四、使用成本与配额策略五、开发者注意事项六、替…...

宝塔面板屏蔽垃圾搜索引擎蜘蛛和扫描工具的办法

首先进入宝塔面板&#xff0c;文件管理进入/www/server/nginx/conf目录&#xff0c;新建空白文件kill_bot.conf。然后将以下代码保存到当前文件中。 #禁止垃圾搜索引擎蜘蛛抓取if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Nimbostratus-Bot|Dark|scraper|LMAO|Ha…...

【低成本STM32的T-BOX开发实战:高可靠的车联网解决方案】

基于STM32的车辆远程通信终端&#xff08;T-BOX&#xff09;开发实战&#xff1a;低成本高可靠的车联网解决方案 目录 引言&#xff1a;为什么需要T-BOX&#xff1f;系统总体设计&#xff1a;T-BOX的架构与核心功能硬件设计&#xff1a;STM32主控与关键模块解析 STM32F105VCT6…...

聚类算法K-means和Dbscan的对比

K-means和DBSCAN_dbscan和kmeans的区别-CSDN博客...

mysql的高可用

1. 环境准备 2台MySQL服务器&#xff08;node1: 192.168.1.101&#xff0c;node2: 192.168.1.102&#xff09;2台HAProxy Keepalived服务器&#xff08;haproxy1: 192.168.1.103&#xff0c;haproxy2: 192.168.1.104&#xff09;虚拟IP&#xff08;VIP: 192.168.1.100&#x…...

vue3 elementplus tabs切换实现

Tabs 标签页 | Element Plus <template><!-- editableTabsValue 是当前tab 的 name --><el-tabsv-model"editableTabsValue"type"border-card"editableedit"handleTabsEdit"><!-- 这个是标签面板 面板数据 遍历 editableT…...