基于 Redis 实现短信验证码登录功能的完整方案
🧱 一、技术栈与依赖配置
使用 Spring Boot + Redis 实现短信验证码登录,以下是推荐的 Maven 依赖:
<dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Validation --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!-- Lombok(简化实体类) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 如果使用 JWT 登录验证,可引入 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
</dependencies>
二、流程概述
✅ 验证码获取流程:
1.校验手机号码
2.如果不符合,直接返回错误信息
3.符合,则生成验证码(有过期时间)
4.将验证码存入redis中
6.发送验证码
注:key为手机号+前缀
value是code(验证码)String类型
public Result sendCode(String phone, HttpSession session) {//1.校验手机号码if (RegexUtils.isPhoneInvalid(phone)) {//2.如果不符合,直接返回错误信息return Result.fail("手机号码格式不正确");}//3.符合,则生成验证码String code = RandomUtil.randomNumbers(6);// //4.将验证码存入session中
// session.setAttribute("code", code);//4.将验证码存入redis中stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);//6.发送验证码
// smsService.sendCode(phone, code);log.debug(code);return Result.ok();}
短信验证码登录、注册流程
1.校验手机号
2.如果不符合,返回错误信息
3.校验验证码
从redis中获取验证码
4.如果不符合,返回错误信息
5.一致,根据手机号查询用户
6.判断用户是否存在
不存在,则创建
7 .保存用户信息到redis中
7.1随机生成token,作为登录令牌
7.2将user对象转成哈希存储
7.3将token和用户信息存入redis
8.设置token过期时间
9.返回token
注:
key:随机token+前缀(String)
value:用户信息(采用哈希map存储)
因为UserDTO转map的时候,由于id是Long类型,不能转成String类型 所以我们需要自定义map集合规则
1️⃣
BeanUtil.beanToMap(...)
来自 Hutool 工具库,用于将 Java Bean 转换为 Map。例如:
UserDTO { String name = "Tom"; Integer age = 18; }
将被转换为:
{ "name": "Tom", "age": 18 }
2️⃣ 第二个参数:
new HashMap<>()
用于接收转换后的数据,你可以指定已有的 Map 进行填充,也可以传一个新的空 Map,如这里使用的是新建的
HashMap
。
3️⃣
CopyOptions.create()
:配置拷贝选项
CopyOptions
是一个用于控制复制行为的配置类。以下是你使用的两个关键配置项:✅
setIgnoreNullValue(true)
意思是 忽略值为 null 的字段,不把它们放入最终的 Map。
例子:如果
userDTO.getEmail()
为 null,则结果 Map 中不会出现"email": null
。✅
setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString())
提供一个字段值编辑器,在放入 Map 之前将每个字段值转换成字符串。
举例:
age = 18
→"18"
(注意是字符串)
active = true
→"true"
fieldName
是字段名,比如"age"
,fieldValue
是字段值,比如18
⚠️ 注意:这个处理器假设
fieldValue
不为 null,否则调用toString()
会抛出NullPointerException
,所以它通常要和setIgnoreNullValue(true)
搭配使用。
✅ 总结作用
这段代码的最终目的是:
将 userDTO 对象转换为一个 Map<String, Object>,只包含非 null 字段,且所有字段值都转为字符串类型。
📌 示例:
假设
userDTO
内容如下:
UserDTO { String name = "Alice"; Integer age = 25; String email = null; }
执行后
userMap
中内容为:
{ "name": "Alice", "age": "25" // 注意:值为字符串类型 // "email" 被忽略,因为是 null }
Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
@Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {String phone = loginForm.getPhone();// 1.校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误");}//3.校验验证码
// Object cacheCode = session.getAttribute("code");//从session中获取验证码//TODo 3.从redis中获取验证码String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);String code = loginForm.getCode();//从登录表单中获取验证码(用户输入验证码)if (cacheCode == null || !code.equals(cacheCode)) {//4.如果不符合,返回错误信息return Result.fail("验证码不正确");}//5.一致,根据手机号查询用户User user = query().eq("phone", phone).one();//6.判断用户是否存在if (user == null) {//不存在,则创建user = createUserWithPhone(phone);}
// //7.保存用户信息到session中
// session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));//TODo 7 .保存用户信息到redis中// TODo 7.1随机生成token,作为登录令牌String token = UUID.randomUUID().toString(true);//TODo 7.2将user对象转成哈希存储UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));;//TODo 7.3将token和用户信息存入redisString tokenKey = LOGIN_USER_KEY + token;stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);//TODo 8.设置token过期时间stringRedisTemplate.expire(LOGIN_USER_KEY + token, LOGIN_USER_TTL, TimeUnit.MINUTES);//TODo 9.返回tokenreturn Result.ok(token);}private User createUserWithPhone(String phone) {User user = new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomNumbers(5));//保存用户信息save(user);return user;}
在这个方案中,他确实可以使用对应路径的拦截,同时刷新登录token令牌的存活时间,但是现在这个拦截器他只是拦截需要被拦截的路径,假设当前用户访问了一些不需要拦截的路径,那么这个拦截器就不会生效,所以此时令牌刷新的动作实际上就不会执行,所以这个方案他是存在问题的
解决状态登录刷新问题
既然之前的拦截器无法对不需要拦截的路径生效,那么我们可以添加一个拦截器,在第一个拦截器中拦截所有的路径,把第二个拦截器做的事情放入到第一个拦截器中,同时刷新令牌,因为第一个拦截器有了threadLocal的数据,所以此时第二个拦截器只需要判断拦截器中的user对象是否存在即可,完成整体刷新功能。
第一个拦截器保存用户信息然后刷新
第二个拦截器就是拦截
package com.hmdp.config;import com.hmdp.utils.LoginInterceptor;
import com.hmdp.utils.RefreshTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MvcConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(this.loginInterceptor).addPathPatterns("/**").excludePathPatterns("/shop/**","/voucher/**","/shop-type/**","/upload/**","/blog/hot","/user/code","/user/login").order(1);registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);}
}
相关文章:
基于 Redis 实现短信验证码登录功能的完整方案
🧱 一、技术栈与依赖配置 使用 Spring Boot Redis 实现短信验证码登录,以下是推荐的 Maven 依赖: <dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><ar…...
监控易一体化运维:拥有全部核心技术,助力国产化信创运维
在数字化转型浪潮与信创产业蓬勃发展的当下,企业对运维系统的要求愈发严苛。随着数字化领域的巨大变迁,一款强大且适配信创环境的运维系统对企业的重要性不言而喻。今天,让我们一同深度剖析监控易系统在信创领域展现出的卓越优势。 信创产业&…...
微 PE , USM 魔术师两款 PE 对比
微 PE 和 USM 魔术师两款 PE 各有特点: 纯净度 微 PE:没有植入强制性、商业性软件和链接,也没有病毒和木马,非常纯净。USM 魔术师:同样无广告、无流氓、无捆绑、无后门,从官方途径下载能保证纯净度。 功能…...
测试模版1
本篇技术博文摘要 🌟 引言 📘 在这个变幻莫测、快速发展的技术时代,与时俱进是每个IT工程师的必修课。我是盛透侧视攻城狮,一名什么都会一丢丢的网络安全工程师,也是众多技术社区的活跃成员以及多家大厂官方认可人员&a…...
elementUI 中el-date-picker和el-select的样式调整
1. el-date-picker <el-date-picker class"select1" size"small" v-model"timeRangeArr" type"daterange" align"right" unlink-panels range-separator"至" start-placeholder"开始日期" end-pla…...
基于亚马逊云科技构建音视频直播审核方案
1. 前言 随着互联网内容形态的多样化发展,用户生成内容(UGC)呈现爆发式增长。社交平台、直播、短视频、语聊房等应用场景中,海量的音视频内容需要进行实时审核,以维护平台安全与用户体验。 然而,企业在构…...
Vue3 组件之间传值
在 Vue3 中,组件之间的数据传递主要有以下几种方式,适用于不同的场景: 一、父组件向子组件传值:props 1. 子组件定义 props <!-- ChildComponent.vue --> <script setup> // 组合式 API(推荐)…...
深入理解用于中断控制的 NVIC 寄存器
NVIC 中有多个用于中断控制的寄存器(异常类型 16~255),这些寄存器位于系统控制空间(SCS)地址区域。下表是这些寄存器的概览: 除了软件触发寄存器(STIR)外,所有这些寄存器…...
Podman(Pod Manager)简介
Podman 简介 Podman(Pod Manager)是一个开源的容器管理工具,由红帽(Red Hat)开发,用于替代 Docker,支持运行、管理 OCI(Open Container Initiative)容器和容器镜像。它设…...
HarmonyOS NEXT端云一体化工程目录结构
视频课程学习报名入口:HarmonyOS NEXT端云一体化开发 端云一体化开发工程由端开发工程(Application)和云开发工程(CloudProgram)两大核心模块构成。 1)端开发工程目录结构 端开发工程主要用于开发应用端侧的业务代码,通用云开发模板的端开发工程目录结构如下图所示: …...
【C++ 真题】P1075 [NOIP 2012 普及组] 质因数分解
P1075 [NOIP 2012 普及组] 质因数分解 题目描述 已知正整数 n n n 是两个不同的质数的乘积,试求出两者中较大的那个质数。 输入格式 输入一个正整数 n n n。 输出格式 输出一个正整数 p p p,即较大的那个质数。 输入输出样例 #1 输入 #1 21输…...
力扣热题100,力扣148.排序链表力扣.26找出字符串中第一个匹配项的下标力扣146.LRU缓存序列管理器
目录 力扣148.排序链表 力扣.26找出字符串中第一个匹配项的下标 力扣146.LRU缓存 序列管理器 力扣148.排序链表 那个O1,暂时我没有考虑,但是这个nlogn,我就想什么时候会有log呢,应该是2的次幂方向思考,一说2,是否能想到2分呢&…...
防火墙高可靠性
防火墙高可靠性技术概述 防火墙高可靠性技术分为两类:设备高可靠性和链路高可靠性 防火墙双机热备 双机热备概述及相关协议 HRP协议:即Huawei Redundancy Protocol,主要用于实现防火墙双机之间关键配置命令和状态化信息的备份,…...
C++ stack对象创建、入栈、获取栈顶
stack对象创建直接调用C对应的<stack>,进行创建 #include<iostream> #include<stack>using namespace std;int main() {// 1 默认构造函数stack<int> stk1;// 2 拷贝构造函数stack<int> stk2;stk1 stk2;return 0;} 入栈操作有一条…...
x-cmd install | Pillager:Go 语言打造的敏感信息文件系统扫描利器
目录 Pillager 的独特优势安装Pillager 的应用场景Pillager 的核心功能 还在为文件系统中潜在的敏感信息泄露而担忧吗?Pillager 是一款由 Go 语言编写的强大工具,旨在帮助你轻松扫描文件系统,发现隐藏的密钥、密码、API 令牌等敏感信息。 Pil…...
第9.1讲、Tiny Encoder Transformer:极简文本分类与注意力可视化实战
项目简介 本项目实现了一个极简版的 Transformer Encoder 文本分类器,并通过 Streamlit 提供了交互式可视化界面。用户可以输入任意文本,实时查看模型的分类结果及注意力权重热力图,直观理解 Transformer 的内部机制。项目采用 HuggingFace …...
asp.net web form nlog的安装
一、安装NuGet包 核心包安装 NLog提供日志记录核心功能 NLog.Config自动生成默认配置文件模板 配置NLog文件 配置文件创建 项目根目录自动生成NLog.config文件(通过NuGet安装NLog.Config时创建) <?xml version"1.0" encoding&…...
定时器的两种实现方式
1、基于优先级队列/堆 队列是先进先出,优先级队列是优先级越高就存放在队列之前,我们可以将过期时间越早设置为优先级越高,那么临近过期时间的任务就会在队列前面,距离过期时间越晚的任务就在队列后面。 可以分配一个线程&#…...
2025.05.21华为暑期实习机考真题解析第一题
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 01. 智能云任务分发系统 问题描述 卢小姐负责一家云计算公司的任务分发系统开发。该系统需要根据任务优先级和到达顺序进行智能调度,支持以下两种操作: 添加任务 add task_id pri…...
计算机网络-MPLS VPN报文转发
上一章学习了MPSL VPN的路由交互过程,VPN间学习到路由之后可以进行报文的转发了。 一、MPLS VPN报文转发过程 以图中用户X的站点B访问站点A的192.168.1.0/24网段为例,报文转发过程如下: 1.CE3上存在到192.168.1.0/24网段路由,发…...
关于sql 查询性能优化的小经验
最近接到一些sql优化的任务。数据库类型:DB2 有一个长sql查询效率低,大概要几十秒,大概查询逻辑如下: select * from tableA a where exists (select 1 from tableB b where a.idb.id ) or exists (select 1 from tableC c whe…...
Pandas:数据分析步骤、分组函数groupby和基础画图
本文目录: 一、概念(一)数据分析的基本步骤(二)两个属性:loc[行标签,列标签 ] 和 iloc[行索引位置,列索引位置 ]1.基本规则2.两属性的相同和不同对比 二、加载数据(一)按列加载数据&…...
游戏引擎学习第302天:使用精灵边界进行排序
在 game_render_group.cpp 中:正确计算 GetBoundFor() 里的 SpriteBound 值 我们正在进行游戏的排序问题调试。虽然这是一个二维游戏,但包含一些三维元素,因此排序变得比较复杂和棘手。混合二维和三维元素时,需要依赖一些比较主观…...
【完整版】基于laravel开发的开源交易所源码|BTC交易所/ETH交易所/交易所/交易平台/撮合交易引擎
功能说明 源码简介与安装环境说明: 开源交易所,基于laravel开发的交易所 | BTC交易所 | ETH交易所 | 交易所 | 交易平台 | 撮合交易引擎。本项目有完整的撮合交易引擎源码、后台管理(后端前端)、前台(交易页面、活动页…...
DeepSeek赋能智能家居:构建高智能、低延迟的物联网生态
一、DeepSeek技术架构解析 DeepSeek采用分层架构设计,兼容边缘计算与云端协同,核心模块包括: 1. 设备接入层 多协议适配:支持MQTT、CoAP、Zigbee、WiFi等主流协议,内置设备描述语言(DDL)解析器,可自动发现并注册新设备。数据预处理:对传感器数据(如温度、光照、加速…...
鸿蒙开发:应用上架第二篇,申请发布证书
前言 本文基于Api13 通过第一篇文章,我们拿到了密钥库.p12文件和证书请求csr文件,这两个文件都是非常重要的,一定要保存好,我们也基本知道了应用的打包,签名信息文件是必须的,而对于签名信息,也…...
Android Framework开发环境搭建
本文分享下在Windows和ubuntu系统搭建framework 开发环境的过程。 Window系统版本win11 一.在windows搭建android framework开发环境。 到下面网站下载android studio 。 developer.android.google.cn/studio?hlzh-cn 在as 的sdk manager 中安装SDK Platform和SDK Tools。 2…...
关于收集 Android Telephony 网络信息的设计思考
需求 收集service state change、ims fail 等相关无线移动网络状态的信息,并保存,对外提供数据查询、删除、更新的功能。 架构设计与实现建议 1. 架构设计建议 针对在 Android Telephony 数据模块中实现网络状态信息收集并调用 Provider App 存储的需求,建议采用 分层的…...
弱网服务器群到底有什么用
在当今数字化的时代,大家都在追求高速、稳定的网络体验,但你是否想过,弱网服务器群其实也有着不可小觑的作用。让我们来聊聊什么是弱网服务器群。简单来说,它是一组在网络条件相对较差情况下运行的服务器集合。 弱网服务器群组是一…...
如何提高独立服务器的安全性?
独立服务器相对于其它服务器来说,整体的硬件设备都是独立的同时还有着强大的服务器性能,其中CPU设备能够决定着服务器的运算能力,所以独立服务器的安全性受到企业格外的重视,严重的话会给企业造成巨大的资金损失。 那么࿰…...
ubuntu 搭建FTP服务,接收部标机历史音视频上报服务器
1.安装vsftpd 1.1.安装命令 sudo apt update sudo apt install vsftpd 1.2.备份原始配置文件 sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak 1.3.配置 vsftpd 编辑配置文件 /etc/vsftpd.conf: sudo vim /etc/vsftpd.conf 将以下参数修改为对应值ÿ…...
在离线 OpenEuler-22.03 服务器上升级 OpenSSH 的完整指南
当然可以!以下是一篇结构清晰、语言通俗易懂的技术博客草稿,供你参考和使用: 在离线 OpenEuler-22.03 服务器上升级 OpenSSH 的完整指南 背景介绍 最近在对一台内网的 OpenEuler-22.03 服务器进行安全扫描时,发现其 SSH 版本存在…...
用java实现内网通讯,可多开客户端链接同一个服务器
创建一个客户端:package Socket;import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Scanner;/* 聊天案例客户端 */ public class Client {private Socket socket;/**…...
蓝耘服务器部署ppocr-gpu项目
一、存在的问题。 conda install 总是访问失败。 二、云服务器选择 三、安装Anaconda3 进入云服务器后删除minconda文件夹 官网: https://repo.anaconda.com/archive/ 在里面找到自己系统的安装包,然后右击复制链接安装。 一定要选择Anaconda,因为…...
离线服务器算法部署环境配置
本文将详细记录我如何为一台全新的离线服务器配置必要的运行环境,包括基础编译工具、NVIDIA显卡驱动以及NVIDIA-Docker,以便顺利部署深度学习算法。 前提条件: 目标离线服务器已安装操作系统(本文以Ubuntu 18.04为例)…...
现代人工智能系统的实用设计模式
关键要点 AI设计模式是为现代AI驱动的软件中常见问题提供的可复用解决方案,帮助团队避免重复造轮子。我们将其分为五类:提示与上下文(Prompting & Context)、负责任的AI(Responsible AI)、用户体验&…...
数据集下载并保存本地进行加载
一、huggingface 1、下载数据集 #数据集下载 from datasets import load_datasetds load_dataset("FreedomIntelligence/medical-o1-reasoning-SFT", "zh",cache_dir ./dir)输出测试 2、保存数据集 #数据保存 ds.save_to_disk("./local_datase…...
物流项目第六期(短信微服务——对接阿里云第三方短信服务JAVA代码实现、策略模式 + 工厂模式的应用)
前五期: 物流项目第一期(登录业务)-CSDN博客 物流项目第二期(用户端登录与双token三验证)-CSDN博客 物流项目第三期(统一网关、工厂模式运用)-CSDN博客 物流项目第四期(运费模板列…...
嵌入式学习的第二十五天-系统编程-文件相关函数-标准I0+文件IO
一、文件的读和写 1.fwrite(读) size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 功能:从指定的stream流对象中获取nmemeb个大小为size字节的数据块到ptr所在的本地内存中。 参数:ptr 要存储数据的本地…...
MySQL 8.0 OCP 1Z0-908 171-180题
Q171.Examine this MySQL client command to connect to a remote database: mysql-h remote-example.org-u root–protocolTCP–ssl-mode Which two–ss1-mode values will ensure that an X.509-compliant certificate will be used to establish the SSL/TLS connection to …...
实现动态增QuartzJob,通过自定义注解调用相应方法
:::tip 动态增加Quartz定时任务,通过自定义注解来实现具体的定时任务方法调用。 ::: 相关依赖如下 <!-- 用来动态创建 Quartz 定时任务 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-start…...
Linux网络 网络基础一
1. 计算机网络背景 1.1 网络发展 独立模式:计算机之间相互独立。 网络互联:多台计算机连接在一起,完成数据共享。 局域网LAN:计算机数量更多了,通过交换机和路由器连接在一起。 广域网WAN:将远隔千里的…...
auto关键字解析
前言 在11标准之前,auto在c中是声明存储器类型的关键字。而在11标准中它的功能变为了类型推导。 对此, 在这里引入Cprimer中的原句: 编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚的知道表达式的类型。然而…...
[实战]用户系统-1-基础功能完善
[实战]用户系统-1 目标响应格式化新建lib-interceptor增加res拦截器新建lib-filter完善异常处理日志处理新建lib-logger新增mongodb的model代码进度目标 我们的用户系统实战,将会实现以下功能,登录,注册,登出,修改用户信息,上传头像,响应的格式化,请求拦截,vip标识。…...
C#SQLServer数据库通用访问类
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace thinger.cn.ADO.NETTeach { /// /// 数据库的通用类 /// public class SQLHelperBase…...
Linux中进程控制(上)
目录 进程创建 写时拷贝 fork常用场景 fork调用失败的原因 进程终止 进程退出场景 退出码 _exit函数 exit函数 进程等待 进程等待必要性 进程等待方法 wait方法 编辑 waitpid方法 获取⼦进程status 阻塞和非阻塞等待 进程创建 在linux中fork函数是⾮常重要的…...
为什么服务器突然变慢?从硬件到软件的排查方法
服务器突然变慢是许多系统管理员和网站运维人员经常遇到的问题。这种情况可能会影响网站性能、用户体验以及整个业务流程。了解服务器变慢的原因并采取相应的排查措施是至关重要的。本文将介绍服务器突然变慢的可能原因,从硬件到软件方面逐一排查,并提供…...
碳交易系统九大构成
碳交易系统九大构成 碳排放权交易系统的核心要素包括覆盖范围、配额总量、配额分配、排放监测、报送与核查,履约考核、抵消机制、交易机制、市场监管及配套的法律法规体系。 图源《中国碳排放权交易市场:从原理到实践》 1、覆盖范围 碳排放权交易体系…...
第9.2讲、Tiny Decoder(带 Mask)详解与实战
自己搭建一个 Tiny Decoder(带 Mask),参考 Transformer Encoder 的结构,并添加 Masked Multi-Head Self-Attention,它是 Decoder 的核心特征之一。 1. 背景与动机 Transformer 架构已成为自然语言处理(NLP…...
Java接口P99含义解析
假设你开了一家奶茶店(接口就是你的奶茶制作流水线),每天要处理100杯订单: 🚀 P99是什么? 平均响应时间:就像说"平均每杯奶茶2分钟做好",但可能有10杯让客人等10分钟P99…...