什么网站可以做注册任务/竞价网
环境介绍
技术栈 | springboot+mybatis-plus+mysql+java-jwt |
软件 | 版本 |
mysql | 8 |
IDEA | IntelliJ IDEA 2022.2.1 |
JDK | 1.8 |
Spring Boot | 2.7.13 |
mybatis-plus | 3.5.3.2 |
Json Web令牌简称JWT
Token是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。
Token认证
Token是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。
Token认证流程
1、客户端使用用户名跟密码请求登录,服务端收到请求,验证用户名与密码验证成功后,服务端会签发一个 token并把这个 token发送给客户端,客户端收到 token后,会把它存储起来,比如放在cookie里或者localStorage里
2、客户端每次向服务端请求资源的时候需要带着服务端签发的 token
3、服务端收到请求,然后去验证客户端请求里面带着的 token,如果验证成功就向客户端返回请求的数据
token用户认证是一种服务端无状态的认证方式,服务端不用存放token数据。
用解析 token的计算时间换取 session的存储空间,从而减服务器的力,减少频繁的查询数据库
token完全由应用管理,所以它可以避开同源策略
JWT的使用
JSON Web Token(简称JWT)是一个 token的具体实现方式,是目前最流行的跨域认证解决方案。JWT的原理是:服务器认证以后,生成一个JSON对象,发回给用户。
{
“name” :”张三”,
“time”:”2022年10月10日”
}
用户与服务端通信时,都要发回该JSON对象。服务器完全只靠这个对象认定用户身份。
为防止用户篡改数据,服务器在生成对象时,会加上签名
JWT由三个部分组成:Header(头部)、Payload(负载)、Signature(签名)
Header.Payload.Signature
官方描述
Header
JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存
{
"alg": "HS256",
"typ": "JWT"
}
Payload
有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
Signature
签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。
加入依赖
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.3.0</version>
</dependency>
数据库
实体类
package com.example.domain;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;/*** * @TableName user*/
@TableName(value ="user")
@Data
public class User implements Serializable {/*** 用户id*/@TableId(type = IdType.AUTO)private Integer uid;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 盐值*/private String salt;/*** 电话号码*/private String phone;/*** 电子邮箱*/private String email;/*** 性别:0-女,1-男*/private Integer gender;/*** 头像*/private String avatar;/*** 是否删除:0-未删除,1-已删除*/private Integer isDelete;/*** 日志-创建人*/private String createdUser;/*** 日志-创建时间*/private Date createdTime;/*** 日志-最后修改执行人*/private String modifiedUser;/*** 日志-最后修改时间*/private Date modifiedTime;@TableField(exist = false)private static final long serialVersionUID = 1L;
}
mapper(dao)
package com.example.mapper;import com.example.domain.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.Date;
@Mapper
public interface UserMapper extends BaseMapper<User> {/*** 插入用户数据* @param user 用户数据* @return 受影响的行数*/int insert(User user);/*** 根据用户名查询用户是否存在* @param username* @return 成功返回单个用户数据,否返回null*/User findByUserName(@Param("username") String username);/*** 根据uid查询* @param uid* @return*/User findByUid(@Param("uid") Integer uid);/*** 更新用户个人资料信息* @param user* @return*/Integer updateUserInfoByUid(User user);/*** 根据用户id修改密码* @param uid* @return password=?,modified_user=?,modified_time=?*/Integer updatePasswordByUid(@Param("uid")Integer uid,@Param("password")String password,@Param("modified_user")String modified_user,@Param("modified_time") Date modified_time);
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><resultMap id="UserPojoMap" type="com.example.domain.User"><id column="uid" property="uid"></id><result column="is_delete" property="isDelete"></result><result column="created_user" property="createdUser"></result><result column="created_time" property="createdTime"></result><result column="modified_user" property="modifiedUser"></result><result column="modified_time" property="modifiedTime"></result></resultMap><!-- useGeneratedKeys="true" 开启主键自增 keyProperty="uid" 指定uid字段--><insert id="insert" useGeneratedKeys="true" keyProperty="uid">insert into user(username,password,salt,phone,email,gender,avatar,is_delete,created_user,created_time,modified_user,modified_time)values(#{username},#{password},#{salt},#{phone},#{email},#{gender},#{avatar},#{isDelete},#{createdUser},#{createdTime},#{modifiedUser},#{modifiedTime})</insert><select id="findByUserName" resultMap="UserPojoMap">select * from user where username=#{username}</select><select id="findByUid" resultMap="UserPojoMap">select * from user where uid=#{uid}</select><update id="updatePasswordByUid">update user set password=#{password},modified_user=#{modified_user},modified_time=#{modified_time} where uid=#{uid}</update><update id="updateUserInfoByUid">update user set<if test="phone!=null">phone=#{phone},</if><if test="email!=null">email=#{email},</if><if test="gender!=null">gender=#{gender},</if>modified_user=#{modifiedUser}, modified_time=#{modifiedTime} where uid=#{uid}</update><sql id="Base_Column_List">uid,username,password,salt,phone,email,gender,avatar,is_delete,created_user,created_time,modified_user,modified_time</sql>
</mapper>
service
package com.example.service;import com.example.domain.User;
import com.baomidou.mybatisplus.extension.service.IService;
public interface UserService extends IService<User> {/*** 用户注册方法* @param user*/void reg(User user);/*** 用户登入方法* @param username* @param password* @return*/User login(String username,String password);/*** 根据uid查询* @param uid* @return User*//**** @param uid* @param username* @param oldPassword* @param newPassword*/void changePassword(Integer uid,String username,String oldPassword,String newPassword);/*** 通过uid获取用户数据* @param uid* @return*/User getUserInfoByUid(Integer uid);/*** 修改用户信息* @param user* @return*/void changeUserInfo(Integer uid,String username,User user);}
ServiceImpl
package com.example.service.impl;import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.domain.User;
import com.example.service.UserService;
import com.example.mapper.UserMapper;
import com.example.service.exception.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.util.Date;
import java.util.UUID;
@Service
@DS("wms")
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements UserService{@Autowiredprivate UserMapper userDao;@Overridepublic void reg(User user) {//判断用户是否被注册过String username = user.getUsername();User byUserName = userDao.findByUserName(username);if (byUserName == null){//密码的加密处理:MD5算法//盐值+password+盐值String oldPassword =user.getPassword();//获取盐值String salt = UUID.randomUUID().toString().toUpperCase();//保存盐值user.setSalt(salt);String newPassword = getMD5Password(oldPassword,salt);user.setPassword(newPassword);//用户注册// is_delete INT COMMENT '是否删除:0-未删除,1-已删除',// created_user VARCHAR(20) COMMENT '日志-创建人',// created_time DATETIME COMMENT '日志-创建时间',// modified_user VARCHAR(20) COMMENT '日志-最后修改执行人',// modified_time DATETIME COMMENT '日志-最后修改时间',Date nowTime=new Date();user.setIsDelete(0);user.setCreatedUser(user.getUsername());user.setCreatedTime(nowTime);user.setModifiedUser(user.getUsername());user.setModifiedTime(nowTime);Integer rows = userDao.insert(user);if (rows == 0 ){throw new InsertException("注册失败(未知失败)请重新注册");};}else {throw new UsernameOccupyException("用户名被占用");}}@Overridepublic User login(String username,String password) {User UserLogin = userDao.findByUserName(username);//盐值认证String md5Password = getMD5Password(password, UserLogin.getSalt());if (UserLogin == null){throw new UserNullException("用户不存在");}//检测密码是否匹配if (!UserLogin.getPassword().equals(md5Password)){throw new PasswordNotMatchException("用户密码错误");}//判断is_delete字段值是否为1表示被标记为删除if (UserLogin.getIsDelete() == 1){throw new UserNullException("用户已被删除");}User user = new User();user.setUid(UserLogin.getUid());user.setUsername(UserLogin.getUsername());user.setAvatar(UserLogin.getAvatar());//返回用户数据,是为了辅助页面return user;}@Overridepublic void changePassword(Integer uid, String username, String oldPassword, String newPassword) {User user = userDao.findByUid(uid);if (user ==null){throw new UserNullException("用户不存在");}if (user.getIsDelete() ==1){throw new UserDeletedException("用户不存在或已被删除");}//密码对比String md5Password = getMD5Password(oldPassword, user.getSalt());if (!user.getPassword().equals(md5Password)){throw new PasswordNotMatchException("原密码错误");}//更新passwordString newPasswordMd5 = getMD5Password(newPassword, user.getSalt());Integer rows = userDao.updatePasswordByUid(uid, newPasswordMd5,username,new Date());if (rows !=1){throw new PasswordUpdateException("修改密码未知异常");}}//根据id获取userInfo@Overridepublic User getUserInfoByUid(Integer uid) {User result = userDao.findByUid(uid);if (result == null || result.getIsDelete() ==1){throw new UserNullException("用户不存在");}User user = new User();user.setUsername(result.getUsername());user.setUid(result.getUid());user.setPhone(result.getPhone());user.setEmail(result.getEmail());user.setGender(result.getGender());return user;}//修改用户信息@Overridepublic void changeUserInfo(Integer uid, String username, User user) {User result = userDao.findByUid(uid);if (result == null || result.getIsDelete() ==1){throw new UserNullException("用户不存在");}user.setUid(uid);user.setModifiedUser(username);user.setModifiedTime(new Date());Integer rows = userDao.updateUserInfoByUid(user);if (rows != 1){throw new InfoUpdateException("修改用户信息未知异常");}}//password加密方法private String getMD5Password(String password,String salt){for (int i =0;i<5;i++){password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes()).toUpperCase();}//返回加密之后的密码return password;}
}
JWT工具类
public class JWTUtil {private static final String TOKENKey="qgs12345";/*** 生成token* @param map* @return 返回token*/public static String getToken(Map<String,String> map){Calendar instance = Calendar.getInstance();instance.add(Calendar.DATE,7);//7天过期//添加payloadJWTCreator.Builder builder = JWT.create();map.forEach((k,v)->{builder.withClaim(k,v);});builder.withExpiresAt(instance.getTime());//设置令牌过期时间//生成并返回tokenreturn builder.sign(Algorithm.HMAC256(TOKENKey)).toString();}/*** 验证token* @param token*/public static void verify(String token){JWT.require(Algorithm.HMAC256(TOKENKey)).build().verify(token);}/*** 获取token中payload* @param token* @return*/public static DecodedJWT getTokenInfo(String token){return JWT.require(Algorithm.HMAC256(TOKENKey)).build().verify(token);}
}
UserController
@RestController
@RequestMapping("/users")
@CrossOrigin //表示都允许跨域访问
public class UserController extends BaseController{@Autowiredprivate UserService userModuleService;@RequestMapping("/login")public Map<String,Object> login(String username, String password){Map<String,Object> map =new HashMap<>();try {User data = userModuleService.login(username, password);Map<String,String> payload =new HashMap<>();payload.put("username",data.getUsername());//生成JWT令牌String token =JWTUtil.getToken(payload);map.put("state",true);map.put("msg","登入成功");map.put("token",token);}catch (Exception e){map.put("state",false);map.put("msg","登入失败");}return map;}}
登录,产生token
验证token方式一
认证代码中写token认证流程,过多的认证请求会导致代码冗余
@RestController
@RequestMapping("/users")
@CrossOrigin //表示都允许跨域访问
public class UserController extends BaseController{@Autowiredprivate UserService userModuleService;@RequestMapping("/login")//验证token@RequestMapping("/loginVerify")public Map<String,Object> loginVerify(String token){System.out.println(token);Map<String,Object> map =new HashMap<>();try {//生成JWT令牌JWTUtil.verify(token);map.put("state",true);map.put("msg","验证成功");}catch (Exception e){map.put("state",true);map.put("msg","验证失败");}return map;}}
验证token方式二 JWT拦截器
抛弃方式一的代码冗余
public class JWTInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Map<String,Object> map =new HashMap<>();// 获取请求头中的JWT令牌String token = request.getHeader("token");// 进行JWT令牌的验证逻辑try {//生成JWT令牌JWTUtil.verify(token);return true;//放行请求}catch (Exception e){map.put("state",false);map.put("msg","token验证失败");//map转jsonString msg =new ObjectMapper().writeValueAsString(map);response.setContentType("application/json;charset=utf-8");response.getWriter().println(msg);}return false;}
}
@Component
public class InterceptorConfig implements WebMvcConfigurer {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new JWTInterceptor()).addPathPatterns("/users//loginVerify")//拦截路径,根据实际情况进行配置.excludePathPatterns("/users/login","/reg") ;//放行路径}}
简化loginVerify后
//验证token
@RequestMapping("/loginVerify")
public Map<String,Object> loginVerify(HttpServletRequest request){Map<String,Object> map =new HashMap<>();String token =request.getHeader("token");System.out.println(token);map.put("state",true);map.put("msg","验证成功");return map;
}
请求头携带token效果
相关文章:

手拉手后端Springboot整合JWT
环境介绍 技术栈 springbootmybatis-plusmysqljava-jwt 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 Json Web令牌简称JWT Token是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。…...

小狐狸GPT付费2.4.9 去除授权弹窗版
后台安装步骤: 1、在宝塔新建个站点,php版本使用7.2 、 7.3 或 7.4,把压缩包上传到站点根目录,运行目录设置为/public 2、导入数据库文件,数据库文件是 /db.sql 3、修改数据库连接配置,配置文件是/.env 4、…...

Scrapy爬虫中合理使用time.sleep和Request
概述 在Scrapy爬虫中,我们需要深入分析time.sleep和Request对象对并发请求的影响。time.sleep函数用于在发起请求之前等待一段时间,而Request对象用于发送HTTP请求。我们必须仔细考虑这些操作对其他并发请求的潜在影响,以及在异步情况下可能…...

在Spring Cloud中使用Ribbon完成一个简单的负载均衡demo
Spring Cloud系列断更了有一段时间了,这段时间最近都在忙着项目上的事,天天修复bug以及调整需求,反正各种操劳,了解业务需求,然后开发相关功能,很久都没碰Spring Cloud系列的相关文章了,最近回头…...

mysql-5.6.16的内存泄漏问题
一、背景 有一台物理机上一个版本为5.6.16的从库出现了内存的增高,观测其日志可以发现,这台数据库已经oom很多次了,并且stop slave的时候会卡住非常长的时间才能停止 二、根本原因 上述的现象可以看到是一个明显的内存泄漏现象,…...

相机内参标定理论篇------相机模型选择
相机种类: 当拿到一款需要标定内参的相机时,第一个问题就是选择那种的相机模型。工程上相机类型的划分并不是十分严格,一般来说根据相机FOV可以把相机大概分为以下几类: 长焦相机:< 标准相机:~&…...

java设计模式学习之【状态模式】
文章目录 引言状态模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用状态示例代码地址 引言 设想你正在使用一个在线视频播放器观看电影。随着你的互动,播放器可能处于不同的状态:播放、暂停、缓冲或结束。每个状态下,播放…...

使用aspose.Words更新表格列宽
public static bool UpdateTableStyle(string filePath) { try { Document doc new Document(); //样式 Style style doc.Styles.Add(StyleType.Paragraph, "cellStyle"); style.Font.Name "simsun"; PageSetup pageSet doc.Sections[0].PageSetup; pa…...

pycharm 工具栏不见了
新版pycharm后, 菜单栏和工具栏不见了 目录 我发现的解决方法: 其他旧版的解决方法: 我发现的解决方法: 其他旧版的解决方法: 另外,一些使用pycharm的新手可能会由于不熟悉软件的功能而误操作ÿ…...

图灵日记之java奇妙历险记--类和对象
目录 类的定义和使用类的定义格式 类的实例化类和对象的说明 this引用this引用的特性 对象的构造及初始化就地初始化构造方法 封装包导入包中的类自定义包 static成员static修饰成员变量static修饰成员方法 代码块代码块概念及分类构造代码块静态代码块 匿名对象 类的定义和使用…...

Kotlin 枚举类
使用 enum 修饰符;每个枚举常量都是一个对象,枚举常量以逗号分隔 // 枚举类 enum class Direction {NORTH, SOUTH, WEST, EAST }// 每一个枚举都是枚举类的实例,所以可以这样初始化 enum class Color(val rgb: Int) {RED(0xFF0000),GREEN(0x…...

可运营的Leadshop开源商城小程序源码 +H5公众号+带视频教程
源码简介 Leadshop是一款出色的开源电商系统,具备轻量级、高性能的特点,并提供持续更新和迭代服务。该系统采用前后端分离架构(uniappyii2.0),以实现最佳用户体验为目标。 前端部分采用了uni-app、ES6、Vue、Vuex、V…...

Qt底层机制之对象树总结
Qt对象树是Qt框架中的一个重要概念,它用于管理对象之间的关系和生命周期。除了常规的对象树结构,Qt还提供了一些特殊的用法来扩展对象树的功能和灵活性。 1. 父子关系:Qt对象树通过设置父对象来建立父子关系。父对象负责管理子对象的内存分配和释放。这种关系可以通过`setP…...

QT C++ TCP Socket 请求心知天气
0.0 相关连接代码部分头文件具体实现 相关连接 心知天气官方天气图标 心知天气官网 代码部分 头文件 #include <QtNetwork> #include <QNetworkAccessManager> #include <QDebug> #include <QJsonValue> #include <QJsonArray> #include &l…...

双向链表的实现及头尾插入删除
双链表的增删查改 一.双向链表的初始化二.创建返回链表的头结点三.双向链表销毁四. 双向链表打印五.双向链表尾插六. 双向链表尾删七. 双向链表头插八.双向链表头删九.双向链表的查找十.双向链表在pos的前面进行插入十一. 双向链表删除pos位置的节点 一.双向链表的初始化 Lis…...

C语言—每日选择题—Day62
第一题 1. 在使用标准C库时,下面哪个选项使用只读模式打开文件? A:fopen("foo.txt", "r") B:fopen("foo.txt", "r") C:fopen("foo.txt", "w") D…...

基于 Sentry 的前端监控系统搭建(Linux)
一、前言 随着技术这几年的发展与沉淀,线上数据指标监控也变得尤为重要,研发人员和运营人员需要对线上的产品指标有所感知,同时风险也需要及时暴露,很多公司开始自建监控系统,但对于一些定制化要求不是特别高的团队&a…...

【C++入门到精通】Lock_guard与Unique_lock C++11 [ C++入门 ]
阅读导航 引言一、RAII机制1. 概念2. 原理3. 优点 二、Lock_guard1. 官方文档2. 概念3. 底层类模版4. 使用示例 三、Unique_lock1. 官方文档2. 概念及底层3. 使用示例 四、总结温馨提示 引言 在C11标准中,为了更方便地使用互斥锁(Mutex)来保…...

电路设计(8)——计时器的multism仿真
1.功能设计 这是一个计时电路,在秒脉冲的驱动下,计时器开始累加,6个数码管分别显示计时的 时:分:秒。 仿真图如下所示: 左边的运放构成了振荡电路,可以产生脉冲波。这个脉冲波给计时电路提供基准…...

Jmeter测试实践:文件下载接口
一 Jmeter步骤 1.打开jmeter4.0,新建测试计划,添加线程组。根据实际情况配置线程属性。 2.添加HTTP请求。根据接口文档进行配置。 Basic部分修改如下,Advanced部分保持默认。这里的参数id是文件的id,我进行了参数化,…...

PyQt5实现学生管理系统第三天(下)
目录 一:学生课程导航 二:搜索框 三:查询 四:页面数据展示逻辑 上一节,我们介绍了课程管理的课程查询导航的功能。这一节我们介绍下学生课程的功能实现,因为学生课程只有一个查询列表,内容相对简单,所以我们在这一节也重点讲述下我们页面的展现逻辑。 一:学生课程…...
第4章 | 安徽某高校《统计建模与R软件》期末复习
第4章 参数估计 参数估计是统计建模的关键步骤之一,它涉及根据样本数据推断总体参数的过程。在统计学中,参数通常用于描述总体的特征,如均值、方差等。通过参数估计,我们可以利用样本信息对这些未知参数进行推断,从而…...

localforage本地存储(融合Web Storage,Web SQL Database,ndexedDB三种前端存储)
介绍 localForage 是一个快速而简单的 JavaScript 存储库。通过使用异步存储(IndexedDB 或 WebSQL)和简单的类 localStorage 的 API ,localForage 能改善 Web 应用的离线体验。 在不支持 IndexedDB 或 WebSQL 的浏览器中,localF…...

【JavaWeb学习笔记】17 - ThreadLocal
项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/threadlocal/src/com/yinhai/thread 目录 项目代码 一、什么是ThreadLocal? 二、ThreadLocal快速入门 三、源码解读 一、什么是ThreadLocal? 1. ThreadLocal的作用,可以实现在同一个线…...

【ARMv8M Cortex-M33 系列 1 -- SAU 介绍】
文章目录 Cortex-M33 SAU 介绍SAU 的主要功能包括SAU 寄存器配置示例 Cortex-M33 SAU 介绍 在 ARMv8-M 架构中,SAU(Security Attribution Unit)是安全属性单元,用于配置和管理内存区域的安全属性。SAU 是 ARM TrustZone 技术的一…...

sklearn 逻辑回归Demo
逻辑回归案例 假设表示 基于上述情况,要使分类器的输出在[0,1]之间,可以采用假设表示的方法。 设 h θ ( x ) g ( θ T x ) h_θ (x)g(θ^T x) hθ(x)g(θTx), 其中 g ( z ) 1 ( 1 e − z ) g(z)\frac{1}{(1e^{−z} )} g(z)(1e−z)1…...

什么是众创空间?他有什么特点?
众创空间,是一种为大众创新创业提供专业化服务的创业服务平台,是顺应网络时代创新创业特点和需求,通过市场化机制、专业化服务和资本化途径构建的低成本、便利化、全要素、开放式的新型创业服务平台的统称。众创空间包括创客空间、联合办公空…...

什么是数据分析思维
参考 一文学会如何做电商数据分析(附运营分析指标框架) 电子商务该如何做数据分析?如何数据分析入门(从各项指标表象进入) https://www.processon.com/outline/6589838c3129f1550cc69950 数据分析步骤 什么是数据分析…...

利用Milvus Cloud和LangChain构建机器人:一种引人入胜且通俗易懂的方法
一、引言 机器人已经深入我们的日常生活,从家庭服务到工业生产,再到医疗和运输等领域。然而,这些机器人往往需要复杂的算法和数据处理技术才能有效地执行任务。在这个过程中,人工智能(AI)和机器学习&#…...

数据结构-如何实现一个队列?逐步解析与代码示例(超详细)
文章目录 前言1.队列的基本概念2.链表与数组实现队列的区别2.1数据存储结构2.2性能2.3内存使用 3.为什么选择链表实现队列?4.结构定义函数声明 5.核心操作5.1初始化 (QInit)5.2销毁 (QDestroy)5.3入队 (QPush)5.4出队 (QPop) 6.队列的查询操作6.1队首元素 (QueueFro…...