网页五子棋——用户模块

目录

用户注册

注册时序图

约定前后端交互接口

后端实现

controller 层接口设计

service 层接口设计

dao 层接口设计

全局异常处理

接口测试

前端实现

register.html

css

common.css

register.css

js

注册模块测试

用户登录

登录时序图

约定前后端交互接口

后端实现

controller 层接口设计

service 层接口设计

dao 层接口设计

接口测试

前端实现

login.html

login.css

js

登录模块测试


用户模块主要包含两大部分:

1. 用户注册

2. 用户登录

我们首先来看用户注册

用户注册

注册时序图

我们来理解一下注册过程: 

1. 用户输入用户名和密码后,点击提交按钮,发送注册请求给服务器

2. 服务器校验用户信息是否正确,对用户密码进行加密,再将用户信息保存到数据库

3.保存成功后,服务器返回注册成功响应

约定前后端交互接口

[请求]  POST /register

{"name": "zhangsan","password": "123456"
}

[响应]

{"code": 200,"data": {"userId": 1},"errorMessage": ""
}

后端实现

controller 层接口设计

controller 接口主要完成的功能是:

1. 打印接收到参数

2. 调用 service 层方法进行业务逻辑处理

3. 构造响应并返回

首先定义接收到的参数类型和返回的响应类型:

接收到的参数:

@Data
public class UserRegisterParam implements Serializable {/*** 用户名*/private String name;/*** 用户密码*/private String password;}

返回的响应结果:

@Data
public class UserRegisterResult implements Serializable {/*** 注册用户 id*/private Long userId;
}

controller 层接口:

@RestController
@Slf4j
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/register")public CommonResult<UserRegisterResult> register(@RequestBody UserRegisterParam param) {// 日志打印log.info("register 接收到参数 UserRegisterParam: {}",JacksonUtil.writeValueAsString(param));// 业务逻辑处理UserRegisterResultDTO userRegisterResultDTO = userService.register(param);// 构造响应并返回return CommonResult.success(convertToUserRegisterResult(userRegisterResultDTO));}
}

由于是从请求体中读取数据,因此 UserRegisterParam 需要添加注解 @RequestBody

 @RequestBody 注解会将 HTTP 请求体中的 JSON 数据自动转化为指定的 java 对象

在调用 service 层接口进行逻辑处理后,为什么不直接返回 UserRegisterResult 类型结果,而是要定义一个 DTO 类型,然后再进行转化?

这是因为在 数据分层 的设计中,传递数据的结构和方式非常重要,能有效地提高系统的可维护性、扩展性和性能

常见的数据传递设计就包括数据在各个层次之间的传递方式以及使用的对象类型,为了在不同层之间有效地传递数据,开发者通常会采用不同的对象来封装数据

通常,在开发中,系统会划分为多个层次(如:表现层、业务逻辑层、持久化层等),每一层的职责明确,数据在不同层之间的传递有明确的设计标准

系统分层通常包括以下几个主要层次:

controller 层:处理请求,调用业务逻辑,数据封装和返回等

service 层:处理核心业务逻辑

dao 层:处理与数据库的交互

数据传递对象:

DTO(Data Transfer Object):数据访问对象,通常用于服务层(service层)与控制层(controller层)之间的数据传输

VO(Value Object):值对象,通常用于表示某个数据的抽象,在系统中用于传递只读数据,常用于控制层(controller层)中展示数据

DO(Domain Object):领域对象,表示领域模型中的对象,包含业务逻辑层和规则,与数据库中的数据对应,用于持久层(dao层)和业务层(service层)之间的数据传输

UserRegisterResultDTO:

@Data
public class UserRegisterResultDTO implements Serializable {/*** 用户 id*/private Long userId;
}

 最后,来实现转化方法 convertToUserRegisterResult

    /*** 将 UserRegisterResultDTO 转化为 UserRegisterResult* @param userRegisterResultDTO* @return*/private UserRegisterResult convertToUserRegisterResult(UserRegisterResultDTO userRegisterResultDTO) {// 参数校验if (null == userRegisterResultDTO) {throw new ControllerException(ControllerErrorCodeConstants.REGISTER_ERROR);}// 构造 UserRegisterResultUserRegisterResult result = new UserRegisterResult();result.setUserId(userRegisterResultDTO.getUserId());// 返回return result;}

添加 controller 层错误码

public interface ControllerErrorCodeConstants {// ---------------------- 用户模块错误码 ----------------------ErrorCode REGISTER_ERROR = new ErrorCode(100, "注册失败");
}

service 层接口设计

service 层,进行接口分离设计

什么是接口分离设计?有什么好处?

 Service 层接口分离设计(也称为接口隔离或服务接口分离)是指在设计 Service 层时,将接口和实现分离确保接口与实现之间的解耦,提升系统的可维护性、扩展性和灵活性。

这种设计模式通常遵循 接口隔离原则,即客户不应该被强迫依赖于它们不需要使用的方法。在分层架构中,Service 层的接口设计尤为重要,因为它是系统业务逻辑的核心。

解耦合:接口与实现分离后,业务逻辑的变化不会直接影响到客户端,客户端只依赖接口而非具体实现

支持多态:接口允许通过共同的接口来引用不同的实现,使得代码更加灵活和通用

扩展性:当需要新增业务逻辑时,可以新增接口并实现,而无需修改现有的接口

清晰的职责划分:通过将接口与实现分离,使得每个模块的职责更加清晰,符合单一职责原则

定义业务接口:

@Service
public interface UserService {/*** 用户注册业务逻辑处理* @param param* @return*/UserRegisterResultDTO register(UserRegisterParam param);
}

实现业务接口:

@Service
@Slf4j
public class UserServiceImpl implements UserService {/*** 用户注册* @param param* @return*/@Overridepublic UserRegisterResultDTO register(UserRegisterParam param) {return null;}
}

register 需要完成的功能:

1. 参数校验

2. 将注册数据入库

3. 构造响应并返回

我们首先来看参数校验

首先,需要确保参数不能为空,这部分校验可以使用 SpringBoot 中集成的 Validation 来实现

Validation 通过一组注解来对对象进行约束和校验,常见的验证注解有:

@NotNull、@NullBack、@NotEmpty、@Min、@Max

@NotNull:验证字段是否为 null

@NullBack:验证字段是否为 null 或 空字符串(对字符串字段有效)

@NotEmpty:验证字段是否为 null 或 空(对字符串或集合有效)

引入依赖:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>

在接口入参上添加 @Validated 注解:

 在 UserRegisterParam 中对成员进行校验:

@Data
public class UserRegisterParam implements Serializable {/*** 用户名*/@NotBlank(message = "用名不能为空")private String name;/*** 用户密码*/@NotBlank(message = "用户密码不能为空")private String password;
}

此外,还需要对密码进行校验,实现 checkPassword() 方法对密码长度进行校验:

    /*** 密码校验* @param password* @return*/private boolean checkPassword(String password) {if (!StringUtils.hasText(password)) {return false;}// 使用正则表达式校验密码长度为 6 - 12 位(不限制字符类型)String regex = "^.{6,12}$";return Pattern.matches(regex, password);}

业务功能实现: 

@Service
@Slf4j
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;/*** 用户注册* @param param* @return*/@Overridepublic UserRegisterResultDTO register(UserRegisterParam param) {// 参数校验if (!checkPassword(param.getPassword())) {throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_CHECK_ERROR);}// 数据入库UserDO userDO = new UserDO();userDO.setUserName(param.getName());userDO.setPassword(SecurityUtil.encipherPassword(param.getPassword()));userMapper.insert(userDO);// 构造响应并返回UserRegisterResultDTO registerResultDTO = new UserRegisterResultDTO();registerResultDTO.setUserId(userDO.getId());return registerResultDTO;}/*** 密码校验* @param password* @return*/private boolean checkPassword(String password) {if (!StringUtils.hasText(password)) {return false;}// 使用正则表达式校验密码长度为 6 - 12 位(不限制字符类型)String regex = "^.{6,12}$";return Pattern.matches(regex, password);}
}

 添加错误码:

public interface ServiceErrorCodeConstants {// ---------------------- 用户模块错误码 ----------------------ErrorCode PASSWORD_CHECK_ERROR = new ErrorCode(100, "密码校验失败");
}

定义 UserDO

@Data
public class UserDO implements Serializable {/*** 用户id (主键)*/private Long id;/*** 创建时间*/private Date gmtCreate;/*** 修改时间*/private Date gmtModified;/*** 用户名*/private String userName;/*** 用户密码*/private String password;/*** 分数*/private BigDecimal score;/*** 比赛总场数*/private Long totalCount;/*** 获胜场数*/private Long winCount;
}

其中的成员与表中字段相对应

dao 层接口设计

使用 MyBatis 来完成与数据库的交互:

@Mapper
public interface UserMapper {@Insert("insert into user (user_name, password, score, total_count, win_count)values (#{userName}, #{password}, 1000, 0, 0)")@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")int insert(UserDO userDO);
}

全局异常处理

在 Spring Boot 中可以使用 @RestControllerAdvice 注解,定义全局异常处理类,从而针对所有异常类型先进行通用处理后,再对特定异常类型进行不同的处理操作

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 捕获 service 层抛出的异常* @param e* @return*/@ExceptionHandler(value = ServerException.class)public CommonResult<?> serverException(ServiceException e) {// 打印错误日志log.info("ServiceException: ", e);// 构造异常情况下的返回结果return CommonResult.fail(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), e.getMessage());}/*** 捕获 controller 层抛出的异常* @param e* @return*/@ExceptionHandler(value = ControllerException.class)public CommonResult<?> controllerException(ControllerException e) {// 打印错误日志log.info("ControllerException: ", e);// 构造异常情况下的返回结果return CommonResult.fail(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), e.getMessage());}/*** 捕获未知异常* @param e* @return*/@ExceptionHandler(value = Exception.class)public CommonResult<?> Exception(Exception e) {// 打印错误日志log.info("ControllerException: ", e);// 构造异常情况下的返回结果return CommonResult.fail(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), e.getMessage());}
}

使用  @ExceptionHandler 注解定义方法来处理某种特定类型的异常,当异常被抛出时,Spring 会查找对应的处理方法来处理该异常

接口测试

使用 postman 对接口进行测试:

符合预期结果,异常情况就不再一一验证了,我们继续实现前端代码

前端实现

 我们先实现相关 html 代码

register.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>注册</title>
</head>
<body><div class="nav">五子棋</div><div class="register-container"><div class="register-dialog"><h3>注册</h3><div class="row"><span>用户名</span><input type="text" id = "name"></div><div class="row"><span>密码</span><input type="password" id="password"></div><div class="row"><button id = "submit">注册</button></div></div></div>
</body>
</html>

 我们继续实现 css 代码

css

导航栏、背景图片等样式多个页面都是相同的,因此我们定义公共样式:

common.css
/* 公共样式 */
* {margin: 0;padding: 0;box-sizing: border-box;
}html, body {height: 100%;background-image: url(../img/background.jpg);background-repeat: no-repeat;background-position: center;background-size: cover;
}.nav {height: 50px;background-color: #efece6;color: #9abcda;line-height: 50px;padding-left: 20px;
}.container {width: 100%;height: calc(100% - 50px);display: flex;align-items: center;justify-content: center;
}

register.css
.register-container {height: calc(100% - 50px);display: flex;justify-content: center;align-items: center;
}.register-dialog {width: 400px;height: 300px;background-color: #e8e8e0;border-radius: 20px;
}/* 标题 */
.register-dialog h3 {text-align: center;padding: 35px 0;
}/* 行 */
.register-dialog .row {width: 100%;height: 50px;display: flex;align-items: center;justify-content: center;
}.register-dialog .row span {width: 100px;font-weight: 700;
}#name, #password {width: 200px;height: 40px;font-size: 20px;line-height: 40px;padding-left: 10px;border: none;outline: none;border-radius: 10px;
}#submit {width: 300px;height: 50px;background-color: #98b8d0;color: #e8e8e0;font-size: 20px;border: none;outline: none;border-radius: 10px;margin-top: 30px;
}#submit:active {background-color: #f8f5d4;
}

 在 register.html 中引入相关样式:

 最后使用 js 来实现前后端交互

js

使用 ajax 完成页面与服务器之间的交互:

引入 jquery:

cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js

将链接中的内容复制到项目中的 jquery.min.js 文件中:

引入,并实现注册数据的提交:

   <script src="js/jquery.min.js"></script><script>let btn = document.querySelector('#submit');btn.onclick = function() {$.ajax({url: "/register",type: "POST",contentType: 'application/json',data: JSON.stringify({name: $("#name").val(),password: $("#password").val(),}),success: function(result) {if(result.code == 200) {// 注册成功,跳转至登录页面location.assign("login.html");}else {alert(result.errorMessage);}}});}</script>

背景图片和图标等样式可自行更改

注册模块测试

运行程序,访问 http://127.0.0.1:8080/register.html

页面正确显示

输入用户名和密码,点击注册:

跳转至登录页面:

至此,用户注册模块就基本实现完毕了,我们继续实现用户登录模块

用户登录

登录时序图

我们来理解一下登录过程: 

1. 用户输入用户名和密码后,点击提交按钮,发送登录请求给服务器

2. 服务器校验登录用户信息完整,并从数据库中查询用户信息

3. 校验用户输入的密码是否正确

4. 将用户相关信息存储到 session 中

5. 构造登录成功响应并返回

约定前后端交互接口

[请求] POST /login

{"name": "zhangsan","password": "123456"
}

[响应] 

{"code": 200,"data": {"userId": 1},"errorMessage": ""
}

后端实现

controller 层接口设计

controller 接口主要完成的功能是:

1. 打印接收到参数

2. 调用 service 层方法进行业务逻辑处理

3. 构造响应并返回

首先定义接收到的参数类型和返回的响应类型: 

定义接收到的参数类型,并对其进行校验:

@Data
public class UserLoginParam implements Serializable {/*** 用户名*/@NotBlank(message = "用名不能为空")private String name;/*** 用户密码*/@NotBlank(message = "用户密码不能为空")private String password;
}

 响应类型:

@Data
public class UserLoginResult implements Serializable {/*** 登录用户 id*/private Long userId;
}

在 UserController 中添加 login:

    @RequestMapping("/login")public CommonResult<UserLoginResult> login(@Validated @RequestBody UserLoginParam param, HttpSession session) {// 日志打印log.info("login 接收到参数 UserLoginParam: {}",JacksonUtil.writeValueAsString(param));// 业务逻辑处理UserLoginDTO userLoginDTO = userService.login(param, session);// 构造响应并返回return CommonResult.success(convertToUserLoginResult(userLoginDTO));}

定义 UserLoginDTO

@Data
public class UserLoginDTO implements Serializable {/*** 用户 id*/private Long userId;
}

 将 UserLoginDTO 转化为 UserLoginResult

    private UserLoginResult convertToUserLoginResult(UserLoginDTO userLoginDTO) {// 参数校验if (null == userLoginDTO) {throw new ControllerException(ControllerErrorCodeConstants.LOGIN_ERROR);}// 构造 UserLoginResultUserLoginResult userLoginResult = new UserLoginResult();userLoginResult.setUserId(userLoginDTO.getUserId());// 返回return userLoginResult;}

 添加 controller 层错误码:

public interface ControllerErrorCodeConstants {// ---------------------- 用户模块错误码 ----------------------ErrorCode REGISTER_ERROR = new ErrorCode(100, "注册失败");ErrorCode LOGIN_ERROR = new ErrorCode(101, "登录失败");
}

service 层接口设计

定义业务接口:

实现业务接口:

login 需要完成的功能:

1. 参数校验

2. 获取用户信息

3. 校验密码是否正确

4. 存储用户信息到 session 中

5. 构造响应并返回

从数据库中获取到的用户信息(UserDO )并不需要都存储到 session 中(如创建时间、修改时间),因此我们创建 UserInfo 用于 session 存储:

@Data
public class UserInfo implements Serializable {/*** 用户 id*/private Long userId;/*** 用户名*/private String userName;/*** 天梯分数*/private Long score;/*** 总场数*/private Long totalCount;/*** 获胜场次*/private Long winCount;
}

login 实现:

    @Overridepublic UserLoginDTO login(UserLoginParam param, HttpSession session) {// 参数校验checkPassword(param.getPassword());// 获取用户信息UserDO userDO = userMapper.selectByUserName(param.getName());// 用户信息是否存在if (null == userDO) {throw new ServiceException(ServiceErrorCodeConstants.USER_INFO_IS_EMPTY);}// 校验密码是否正确if (!SecurityUtil.verifyPassword(param.getPassword(),userDO.getPassword())) {throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_CHECK_ERROR);}// 将用户信息 存储到 session 中UserInfo userInfo = new UserInfo();userInfo.setUserId(userDO.getId());userInfo.setUserName(userDO.getUserName());userInfo.setScore(userDO.getScore());userInfo.setTotalCount(userDO.getTotalCount());userInfo.setWinCount(userDO.getWinCount());session.setAttribute(USER_INFO, userInfo);// 构造响应并返回UserLoginDTO userLoginDTO = new UserLoginDTO();userLoginDTO.setUserId(userDO.getId());return userLoginDTO;}

dao 层接口设计

通过用户名查询用户信息:

    @Select("select * from user where user_name = #{userName}")UserDO selectByUserName(@Param("userName") String userName);

 

接口测试

使用 postman 进行测试:

符合预期结果,我们继续实现前端页面

前端实现

login.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/common.css"><link rel="stylesheet" href="css//login.css">
</head>
<body><div class="nav">五子棋</div><div class="login-container"><!-- 登录页面对话框 --><div class="login-dialog"><h3>登录</h3><div class="row"><span>用户名</span><input type="text" id="name"></div><div class="row"><span>密码</span><input type="password" id="password"></div><div class="register">没有账号?<a href="register.html">点击注册</a></div><div class="row"><button id="submit">登录</button></div></div></div>
</body>
</html>

login.css

.login-container {height: calc(100% - 50px);display: flex;justify-content: center;align-items: center;
}.login-dialog {width: 400px;height: 300px;background-color: #e8e8e0;border-radius: 20px;
}/* 标题 */
.login-dialog h3 {text-align: center;padding: 35px 0;
}/* 行 */
.login-dialog .row {width: 100%;height: 50px;display: flex;align-items: center;justify-content: center;
}.login-dialog .row span {width: 100px;font-weight: 700;
}#name, #password {width: 200px;height: 40px;font-size: 20px;line-height: 40px;padding-left: 10px;border: none;outline: none;border-radius: 10px;
}#submit {width: 300px;height: 50px;background-color: #98b8d0;color: #e8e8e0;font-size: 20px;border: none;outline: none;border-radius: 10px;margin-top: 30px;
}#submit:active {background-color: #f8f5d4;
}/* 点击注册 */.login-dialog .register {text-align: right;margin-right: 20px;font-size: 13px;
}

最后使用 js 来实现前后端交互

js

实现登录数据的提交:

    <script src="/js/jquery.min.js"></script><script>let submitButton = document.querySelector('#submit'); // 提交按钮// 添加点击事件submitButton.onclick = function() { $.ajax({url: '/login',type: 'POST',contentType: 'application/json',data: JSON.stringify({name: $("#name").val(),password: $("#password").val(),}),success: function(result) {console.log(result);if(result.code == 200) {// 保存 token 信息localStorage.setItem("user_token", result.data.token);// 登录成功,跳转至游戏大厅location.assign('/game_hall.html'); }else {alert(result.errorMessage);}}, error: function() {alert("登录失败!");}})}</script>

登录模块测试

运行程序,访问 http://127.0.0.1:8080/login.html:

页面正确显示,输入 用户名 和 密码,进行登录:

页面跳转成功:

至此,用户模块就基本实现完成了

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

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

相关文章

深度学习04 数据增强、调整学习率

目录 数据增强 常用的数据增强方法 调整学习率 学习率 调整学习率 ​调整学习率的方法 有序调整 等间隔调整 多间隔调整 指数衰减 余弦退火 ​自适应调整 自定义调整 数据增强 数据增强是通过对训练数据进行各种变换&#xff08;如旋转、翻转、裁剪等&#xff09;&am…

Ubuntu22.04 Deepseek-R1本地容器化部署/内网穿透/OPENWEBUI,打造个人AI助手!

1. 前言 本地部署DeepSeek并实现内网穿透&#xff0c;为家庭成员提供强大的AI支持。通过使用Ollama、Docker、OpenWebUI和Nginx&#xff0c;内网穿透&#xff0c;我们可以轻松实现快速响应和实时搜索功能。 2.软硬件环境 系统&#xff1a;ubuntu22.04, cuda12GPU: RTX2080Ti …

DeepSeek与ChatGPT的全面对比

在人工智能&#xff08;AI&#xff09;领域&#xff0c;生成式预训练模型&#xff08;GPT&#xff09;已成为推动技术革新的核心力量。OpenAI的ChatGPT自发布以来&#xff0c;凭借其卓越的自然语言处理能力&#xff0c;迅速占据市场主导地位。然而&#xff0c;近期中国AI初创公…

[HarmonyOS]鸿蒙(添加服务卡片)推荐商品 修改卡片UI(内容)

什么是服务卡片 &#xff1f; 鸿蒙系统中的服务卡片&#xff08;Service Card&#xff09;就是一种轻量级的应用展示形式&#xff0c;它可以让用户在不打开完整应用的情况下&#xff0c;快速访问应用内的特定功能或信息。以下是服务卡片的几个关键点&#xff1a; 轻量级&#…

【数据结构】 栈和队列

在计算机科学的世界里&#xff0c;数据结构是构建高效算法的基础。栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;作为两种基本且重要的数据结构&#xff0c;在软件开发、算法设计等众多领域都有着广泛的应用。今天&#xff0c;我们就来深入探讨一下栈和…

「软件设计模式」桥接模式(Bridge Pattern)

深入解析桥接模式&#xff1a;解耦抽象与实现的艺术 一、模式思想&#xff1a;正交维度的优雅解耦 桥接模式&#xff08;Bridge Pattern&#xff09;通过分离抽象&#xff08;Abstraction&#xff09;与实现&#xff08;Implementation&#xff09;&#xff0c;使二者可以独立…

新建github操作

1.在github.com的主页根据提示新建一个depository。 2.配置用户名和邮箱 git config --global user.name "name" git config --global user.email "email" 3.生成ssh秘钥 ssh-keygen -t rsa 找到public key 对应的文件路径 cat /root/.ssh/id_rsa 复制显…

【力扣】108.将有序数组转换为二叉搜索树

AC截图 题目 思路 因为nums数组是严格递增的&#xff0c;所以只需要每次选出中间节点&#xff0c;然后用左边部分构建左子树&#xff0c;用右边部分构建右子树。 代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

如何在 Mac 上解决 Qt Creator 安装后应用程序无法找到的问题

在安装Qt时&#xff0c;遇到了一些问题&#xff0c;尤其是在Mac上安装Qt后&#xff0c;发现Qt Creator没有出现在应用程序中。通过一些搜索和操作&#xff0c;最终解决了问题。以下是详细的记录和解决方法。 1. 安装Qt后未显示Qt Creator 安装完成Qt后&#xff0c;启动应用程…

Spring AI发布!让Java紧跟AI赛道!

1. 序言 在当今技术发展的背景下&#xff0c;人工智能&#xff08;AI&#xff09;已经成为各行各业中不可忽视的重要技术。无论是在互联网公司&#xff0c;还是传统行业&#xff0c;AI技术的应用都在大幅提升效率、降低成本、推动创新。从智能客服到个性化推荐&#xff0c;从语…

数据库脚本MySQL8转MySQL5

由于生产服务器版本上部署的是MySQL5&#xff0c;而开发手里的脚本代码是MySQL8。所以只能降版本了… 升级版本与降级版本脚本转换逻辑一样 MySQL5与MySQL8版本SQL脚本区别 大多数无需调整、主要是字符集与排序规则 MySQL5与MySQL8版本SQL字符集与排序规则 主要操作&…

STM32物联网终端实战:从传感器到云端的低功耗设计

STM32物联网终端实战&#xff1a;从传感器到云端的低功耗设计 一、项目背景与挑战分析 1.1 物联网终端典型需求 &#xff08;示意图说明&#xff1a;传感器数据采集 → 本地处理 → 无线传输 → 云端存储&#xff09; 在工业物联网场景中&#xff0c;终端设备需满足以下核心需…

牛客寒假训练营3

M 牛客传送门 代码如下: const int N2e610,M1e410; const int INF0x3f3f3f3f; const int mod998244353; ll n;void solve(){string s; cin >> s;string ns"nowcoder";sort(s.begin(),s.end(…

BY组态:构建灵活、可扩展的自动化系统

引言 在现代工业自动化领域&#xff0c;BY组态&#xff08;Build Your Own Configuration&#xff09;作为一种灵活、可扩展的解决方案&#xff0c;正逐渐成为工程师和系统集成商的首选。BY组态允许用户根据具体需求自定义系统配置&#xff0c;从而优化生产效率、降低成本并提…

DeepSeek 通过 API 对接第三方客户端 告别“服务器繁忙”

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 上一期分享了如何在本地部署 DeepSeek R1 模型&#xff0c;但通过命令行运行的本地模型&#xff0c;问答的交互也要使用命令行&#xff0c;体验并不是很好。这期分享几个第三方客户端&#xff0c;涵盖了桌…

【第10章:自然语言处理高级应用—10.4 NLP领域的前沿技术与未来趋势】

各位技术探险家们,今天我们要开启一场穿越语言智能奇点的时空之旅。从正在改写物理定律的万亿参数大模型,到能看懂《星际穿越》剧本的跨模态AI,再到正在颠覆编程方式的神经-符号混合系统……这篇万字长文将带你摸清NLP技术进化的七块关键拼图。(建议边读边做笔记,文末有技…

自动驾驶---如何打造一款属于自己的自动驾驶系统

在笔者的专栏《自动驾驶Planning决策规划》中&#xff0c;主要讲解了行车的相关知识&#xff0c;从Routing&#xff0c;到Behavior Planning&#xff0c;再到Motion Planning&#xff0c;以及最后的Control&#xff0c;笔者都做了相关介绍&#xff0c;其中主要包括算法在量产上…

探索 DeepSeek:AI 领域的璀璨新星

在人工智能飞速发展的当下&#xff0c;DeepSeek 作为行业内的重要参与者&#xff0c;正以独特的技术和广泛的应用备受瞩目。 DeepSeek 是一家专注于实现 AGI&#xff08;通用人工智能&#xff09;的中国人工智能公司。它拥有自主研发的深度学习框架&#xff0c;能高效处理海量…

centos部署open-webui

提示&#xff1a;本文将简要介绍一下在linux下open-webui的安装过程,安装中未使用虚拟环境。 文章目录 一、open-webui是什么&#xff1f;二、安装流程1.openssl升级2.Python3.11安装3.sqlite安装升级4.pip 下载安装open-webui 总结 一、open-webui是什么&#xff1f; Open W…

驱动开发、移植(最后的说法有误,以后会修正)

一、任务明确&#xff1a;把创龙MX8的驱动 按照我们的要求 然后移植到 我们的板子 1.Linux系统启动卡制作&#xff0c; sd卡 先按照 《用户手册—3-2-Linux系统启动卡制作及系统固化》 把创龙的Linux系统刷进去。 2. 把TLIMX8-EVM的板子过一遍 把刚刚烧好系统的sd卡插入 创…