大二毕设.3-网盘系统-用户模块讲解
目录
模块功能介绍
具体实现讲解
constants层:存放用户模块常量类
entity层:存放实体类,与数据库中的属性值基本保持一致
mapper层:对数据库进行数据持久化操作
service层:业务逻辑层,主要是针对具体的问题的操作
controller层:负责请求转发,接收页面过来的参数,传给service处理,接到返回值,并再次传给页面
po层:controller层向外接参的实体对象
context层:上下文的实体对象
vo层:视图对象,用于展示层,把某个指定页面的所有数据封装起来,方便前端获取数据
converter层:实体对象转换器
项目演示博客
-
模块功能介绍
- 用户注册
- 接口幂等性
- 全局唯一的用户名称
- 用户登录
- 使用缓存实现单机登录
- 使用jwt token实现时效性以及分布式的问题
- 用户登出
- 用户忘记密码
- 校验用户名称
- 校验用户密保问题的答案
- 修改用户密码
- 用户在线修改密码
- 校验旧密码
- 修改密码
- 查询用户的基本信息
- 用户注册
-
具体实现讲解
- 用户模块下共分有9层,分别是:
-
constants层:存放用户模块常量类
-
entity层:存放实体类,与数据库中的属性值基本保持一致
- 用户信息表(RPanUser)
- 用户搜索历史表(RPanUserSearchHistory)
-
mapper层:对数据库进行数据持久化操作
- 针对用户信息表的数据库操作Mapper(RPanUserMapper)
- 针对用户搜索历史表的数据库操作Mapper(RPanUserSearchHistoryMapper)
-
service层:业务逻辑层,主要是针对具体的问题的操作
- 针对用户信息表的数据库操作Service(IUserService)
- 首先需要把 转换器,针对用户文件信息表的数据库操作Service,缓存管理器CacheManager,用户模块缓存业务处理类 注入进来
- 用户注册的业务实现(register):
- 需要实现的功能点:
- 1、注册用户信息
- 2、创建新用户的根本目录信息
- 需要实现的技术难点:
- 1、该业务是幂等的
- 2、要保证用户名全局唯一
- 实现技术难点的处理方案:幂等性通过数据库表对于用户名字段添加唯一索引,上游业务捕获对应的冲突异常,转化返回
- 它只有1个参数:即UserRegisterContext
- 首先需要实例化用户信息表的实体对象(实体转化,由上下文信息转化成用户实体,封装进上下文)(assembleUserEntity)
- 它只有1个参数:即UserRegisterContext
- 首先通过converter的映射方法来完成实体转换得到entity用户实体对象
- 然后通过PasswordUtil的MessageDigestUtil.md5获取盐值信息(随机生成盐值),同时利用PasswordUtil的MessageDigestUtil.sha256传入盐值和上下文对象传来的密码进行密码加密
- 然后对entity进行属性设置(UserId通过雪花算法id生成器生成,创建时间与更新时间通过new Date()来生成)
- 最后将这个entity封装进上下文对象中
- 然后实现注册用户的业务(需要捕获数据库的唯一索引冲突异常,来实现全局用户名称唯一)(doRegister)
- 它只有1个参数:即UserRegisterContext
- 首先从上下文实体对象(UserRegisterContext)中获取用户实体对象得到entity
- 然后对entity进行判空处理,如果是空则抛出对应错误提示
- 如果不是空则首先需要捕获DuplicateKeyException异常,表示在数据库中插入或更新数据时,违反了唯一性约束,即出现了重复的键值
- 然后抛出"用户名已存在"
- 然后调用mybatisplus的save,如果保存失败也抛出对应异常
- 然后创建用户的根目录信息(createUserRootFolder)
- 它只有1个参数:即UserRegisterContext
- 首先需要创建一个文件夹上下文实体对象
- 然后设置它的3个属性(它的userid就是上下文实体对象(UserRegisterContext)中entity的userid)
- 最后调用IUserFileService的创建文件夹信息(createFolder)方法传入设置好的文件夹上下文实体对象来完成创建
- 最后返回这个上下文对象里的entity里的userid
- 需要实现的功能点:
- 用户登录的业务实现(login):
- 需要实现的功能:
- 1、用户的登录信息校验
- 2、生成一个具有时效性的accessToken
- 3、将accessToken缓存起来,去实现单机登录
- 它只有1个参数:即UserLoginContext
- 首先要校验传入的信息,即校验用户名密码(checkLoginInfo)
- 它只有1个参数:即UserLoginContext
- 首先要通过传入的UserLoginContext上下文对象获取用户名和密码
- 然后通过用户名获取用户实体信息(getRPanUserByUsername)entity
- 它只有1个参数:即username
- 通过QueryWrapper进行eq实现
- 如果查询出来的entity用户实体信息是null,则抛出对应异常
- 然后用户名校验通过后,则校验密码信息
- 首先要获取到它的盐值(entity的盐值),然后通过PasswordUtil传入盐值和上下文对象获取到的密码进行加密
- 同时获取到用户实体信息entity的密码
- 加密后的密码和数据库中的密码(用户实体信息entity的密码)进行比较,不相等则抛出对应异常
- 最后用户名和密码都通过后,UserLoginContext上下文对象设置用户实体对象为entity,方便下游使用
- 然后生成并保存登陆之后的凭证(generateAndSaveAccessToken)
- 它只有1个参数:即UserLoginContext
- 首先要通过传入的UserLoginContext上下文对象获取用户实体对象entity
- 然后向Jwt工具类传入 entity的username,常量key值,entity的userid和过期时间 进行token生成
- 然后通过CacheManager获取到服务端公用缓存cache
- 以 用户登录缓存前缀+entity的userid 为键,缓存token
- 最后UserLoginContext上下文对象设置登陆成功之后的凭证信息为token
- 最后将UserLoginContext上下文对象中的Token返回出去
- 需要实现的功能:
- 用户退出登录的业务实现(exit):
- 只需清除用户的登录凭证缓存即可
- 它只有1个参数:即当前登录用户的userid
- 首先通过CacheManager获取到服务端公用缓存cache
- 然后以 用户登录缓存前缀+当前登录用户的userid 为键,清除token即可
- 用户忘记密码-校验用户名称的业务实现(checkUsername):
- 它只有1个参数:即CheckUsernameContext
- 首先从context中获取Username,通过Username在数据库中查询对应的密保问题
- 如果查询为空则抛出对应异常"没有此用户",查询成功则返回查询到的密保问题供后续服务使用
- 用户忘记密码-校验密保答案的业务实现(checkAnswer):
- 它只有1个参数:即CheckAnswerContext
- 首先从context中获取Username,Question,Answer,通过Username,Question,Answer在数据库中进行对应的查询并进行eq
- eq失败则抛出对应异常"密保答案错误",成功则生成用户忘记密码-校验密保答案通过的临时token并返回,token的失效时间为五分钟
- 用户忘记密码-重置用户密码的业务实现(resetPassword):
- 它只有1个参数:即ResetPasswordContext
- 首先验证忘记密码的token是否有效(checkForgetPasswordToken):
- 它只有1个参数:即ResetPasswordContext
- 首先通过context把token取出来
- 然后通过JwtUtil分析这个token,返回一个value(Username)
- 如果这个value为空则说明token过期了,抛出对应异常
- 如果没有过期解析成功了就把这个token转为string,然后与context中的Username进行对比,不等则抛出对应异常"token错误"
- 然后校验用户信息并重置用户密码(checkAndResetUserPassword):
- 它只有1个参数:即ResetPasswordContext
- 首先通过context把Username和Password取出来
- 然后通过传入Username进getRPanUserByUsername来判断user实体entity是否存在,不存在则抛出对应异常"用户信息不存在"
- 如果存在则进行密码的重置
- 然后对Password进行加密,加密完成后重新设置entity的Password和UpdateTime属性
- 最后传入处理好的entity进updateById进行修改
- 用户在线修改密码的业务实现(changePassword):
- 它只有1个参数:即ChangePasswordContext
- 首先需要校验旧密码(checkOldPassword):
- 它只有1个参数:即ChangePasswordContext
- 首先需要从context中获取userId和oldPassword
- 然后通过getById查询userId得到用户的实体信息entity
- 如果entity为空则抛出对应异常"用户信息不存在"
- 查询成功则将用户的实体信息entity封装到上下文对象context中
- 然后要获取到它的盐值(entity的盐值),然后通过PasswordUtil传入盐值和上下文对象获取到的密码进行加密
- 同时获取到用户实体信息entity的密码
- 加密后的密码和数据库中的密码(用户实体信息entity的密码)进行比较,不相等则抛出对应异常"旧密码不正确"
- 然后需要重置新密码(doChangePassword):
- 它只有1个参数:即ChangePasswordContext
- 首先需要从context中获取newPassword和entity
- 然后要获取到它的盐值(entity的盐值),然后通过PasswordUtil传入盐值和新密码newPassword重新进行加密
- 然后用加密密码覆盖掉entity原有密码
- 最后通过向updateById传入entity进行修改,失败则抛出对应异常"修改用户密码失败"
- 最后退出当前的登录状态(exitLoginStatus):
- 它只有1个参数:即ChangePasswordContext
- 直接调用exit传入context中的UserId完成退出
- 查询在线用户的基本信息的业务实现(info):
- 它只有1个参数:即userId
- 首先通过getById查询用户的基本信息实体entity,对其进行判空处理,查询失败则抛出对应异常"用户信息查询失败"
- 然后查询用户的根文件夹信息(getUserRootFileInfo):
- 它只有1个参数:即userId
- 委托给文件模块的IUserFileService的getUserRootFile进行处理
- 查询失败则抛出对应异常"查询用户根文件夹信息失败"
- 最后通过converter的映射方法拼装VO对象(基本信息实体和根文件夹信息)返回
- 针对用户搜索历史表的数据库操作Service(IUserSearchHistoryService)
- 首先需要把 *** 注入进来
- 查询用户的搜索历史记录,默认十条(getUserSearchHistories):
- 它只有1个参数:即QueryUserSearchHistoryContext
- 直接通过Context上下文通过baseMapper调用自定义Mapper操作进行数据库对应查询,并返回查询结果
- 针对用户信息表的数据库操作Service(IUserService)
-
controller层:负责请求转发,接收页面过来的参数,传给service处理,接到返回值,并再次传给页面
- 用户模块的控制器实体(UserController):
- 首先需要把 *** 注入进来
- register:
- 它只有1个参数:即UserRegisterPO
- 首先在调用service的register方法前,需要将这个po对象转换成上下文对象,通过converter的映射方法来完成转换
- 转换了实体之后,调用service的register方法把这个context给它传进去完成调用,返回一个新注册的userid
- 最后把这id加密下,返回给客户端去使用,返回相关状态码
- login:
- 它只有1个参数:即UserLoginPO
- 首先在调用service的login方法前,需要将这个po对象转换成上下文对象,通过converter的映射方法来完成转换
- 转换了实体之后,调用service的login方法把这个context给它传进去完成调用,返回一个有时效性的accessToken供后续服务使用,返回相关状态码
- exit:
- 没有参数
- 由于每次请求,token放于header中,想要获取token,每次都要通过在control层获取header,才能获取到登录信息,很麻烦
- 所以通过用户ID存储工具类里配置好的 ThreadLocal 获取到当前登录用户的userid
- 然后调用service的exit方法把这个userid给它传进去完成调用,返回相关状态码即可
- checkUsername:
- 它只有1个参数:即CheckUsernamePO
- 首先在调用service的checkUsername方法前,需要将这个po对象转换成上下文对象,通过converter的映射方法来完成转换
- 转换了实体之后,调用service的checkUsername方法把这个context给它传进去完成调用,返回下一步需要校验的密保问题供后续服务使用,返回相关状态码
- checkAnswer:
- 它只有1个参数:即CheckAnswerPO
- 首先在调用service的checkAnswer方法前,需要将这个po对象转换成上下文对象,通过converter的映射方法来完成转换
- 转换了实体之后,调用service的checkAnswer方法把这个context给它传进去完成调用,返回token供后续服务使用,返回相关状态码
- resetPassword:
- 它只有1个参数:即ResetPasswordPO
- 首先在调用service的resetPassword方法前,需要将这个po对象转换成上下文对象,通过converter的映射方法来完成转换
- 转换了实体之后,调用service的resetPassword方法把这个context给它传进去完成调用,返回相关状态码即可
- changePassword:
- 它只有1个参数:即ChangePasswordPO
- 首先在调用service的changePassword方法前,需要将这个po对象转换成上下文对象,通过converter的映射方法来完成转换
- 然后需要获取当前线程的用户ID,用来设置上下文对象的UserId
- 调用service的changePassword方法把这个context给它传进去完成调用,返回相关状态码即可
- info:
- 没有参数
- 通过获取当前线程的用户ID,直接调用service的info查询在线用户的基本信息
- 查询成功返回对应vo对象,同时返回相关状态码
- 用户搜索历史模块的控制器实体(UserSearchHistoryController):
- 首先需要把 *** 注入进来
- 获取用户最新的搜索历史记录,默认十条(getUserSearchHistories):
- 首先需要创建一个 用户查询搜索历史记录上下文实体(QueryUserSearchHistoryContext)
- 然后通过 用户ID存储工具类获取当前线程的用户ID 进行Context属性设置
- 最后调用service的 getUserSearchHistories 方法把这个context给它传进去完成调用,返回用户最新的搜索历史记录和相关状态码
- 用户模块的控制器实体(UserController):
-
po层:controller层向外接参的实体对象
- 注册用户参数实体对象(UserRegisterPO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加4个属性:用户名,密码,密保问题,密保答案
- 最后利用@NotBlank 进行非空校验,@Pattern 进行用户名正则校验,@Length 进行长度校验
- 登录用户参数实体对象(UserLoginPO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加2个属性:用户名,密码
- 最后利用@NotBlank 进行非空校验,@Pattern 进行用户名正则校验,@Length 进行长度校验
- 用户忘记密码-校验用户名称PO对象(CheckUsernamePO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加1个属性:用户名
- 最后利用@NotBlank 进行非空校验,@Pattern 进行用户名正则校验
- 用户忘记密码-校验密保答案PO对象(CheckAnswerPO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加3个属性:用户名,密保问题,密保答案
- 最后利用@NotBlank 进行非空校验,@Pattern 进行用户名正则校验,@Length 进行长度校验
- 用户忘记密码-重置用户密码PO对象(ResetPasswordPO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加3个属性:用户名,密码,验证通过提交重置密码的token
- 最后利用@NotBlank 进行非空校验,@Pattern 进行用户名正则校验,@Length 进行长度校验
- 用户在线修改密码PO对象(ChangePasswordPO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加2个属性:旧密码和新密码
- 最后利用@NotBlank 进行非空校验,@Length 进行长度校验
- 注册用户参数实体对象(UserRegisterPO):
-
context层:上下文的实体对象
- 用户注册业务的上下文实体对象(UserRegisterContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加5个属性:用户名,密码,密保问题,密保答案,用户实体对象(RPanUser)
- 用户登录业务的上下文实体对象(UserLoginContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加4个属性:用户名,密码,用户实体对象(RPanUser),登陆成功之后的凭证信息
- 用户忘记密码-校验用户名称业务的上下文实体对象(CheckUsernameContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加1个属性:用户名
- 用户忘记密码-校验密保答案业务的上下文实体对象(CheckAnswerContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加3个属性:用户名,密保问题,密保答案
- 用户忘记密码-重置用户密码业务的上下文实体对象(ResetPasswordContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加3个属性:用户名,密码,验证通过提交重置密码的token
- 用户在线修改密码业务的上下文实体对象(ChangePasswordContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加4个属性:当前登录的用户ID,旧密码,新密码,当前登录用户的实体信息(RPanUser)
- 用户查询搜索历史记录上下文实体(QueryUserSearchHistoryContext):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加1个属性:当前登录用户的ID
- 用户注册业务的上下文实体对象(UserRegisterContext):
-
vo层:视图对象,用于展示层,把某个指定页面的所有数据封装起来,方便前端获取数据
- 用户基本信息实体(UserInfoVO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加3个属性:用户名称,用户根目录的加密ID,用户根目录名称
- 同时通过@JsonSerialize 自定义序列化类对ID进行自动加密
- 用户搜索历史返回实体(UserSearchHistoryVO):
- 首先它要实现Serializable序列化接口
- 然后给它添加序列化UID这一属性
- 再添加1个属性:搜索文案
- 用户基本信息实体(UserInfoVO):
-
converter层:实体对象转换器
- 用户模块实体转化工具类(UserConverter)
- 首先利用MapStruct的@Mapper 注解标记这个接口作为一个映射接口,并且是编译时MapStruct处理器的入口,简化不同的Java Bean之间映射的处理
- 同时指定@Mapper 注解的componentModel属性为spring,这样生成的实现类上面会自动添加一个@Component注解,可以通过Spring的 @Autowired 方式进行注入
- 然后添加若干映射方法,MapStruct会自动生成转换
- 用户模块实体转化工具类(UserConverter)
-
相关文章:
大二毕设.3-网盘系统-用户模块讲解
目录 模块功能介绍 具体实现讲解 constants层:存放用户模块常量类 entity层:存放实体类,与数据库中的属性值基本保持一致 mapper层:对数据库进行数据持久化操作 service层:业务逻辑层,主要是针对具体…...
(Vue2)智慧商城项目
新增两个目录api、utils api接口模块:发送ajax请求的接口模块 utils工具模块:自己封装的一些工具方法模块 第三方组件库vant-ui PC端:element-ui(element-plus) ant-design-vue 移动端:vant-ui Mint UI…...
Nginx实战
虚拟主机 虚拟主机指的就是⼀个独⽴的站点,具有独⽴的域名,有完整的www服务,例如⽹站、FTP、邮件等 。Nginx⽀持多虚拟主机,在⼀台机器上可以运⾏完全独⽴的多个站点。⼀些草根流量站⻓,常会搭建个⼈站点进⾏资源分享交…...
day-57 代码随想录算法训练营(19)动态规划 part 17
647.回文子串 思路:动态规划 1.dp存储:判断以i开始,j结尾的字符串是否是回文串2.动态转移方程:当s[i]s[j]时,如果j-i<1,d[i][j]true; 如果 dp[i1][j-1]true,那么dp[i][j…...
在项目中,关于前端实现数据可视化的技术选择
前言 在项目中,数据可视化以图表、报表类型为主。 需求背景 技术框架是Vue2.x版本,组件库是Ant Design of Vue能够支撑足够多的图表类型开发图表大小/位置能够随意变动图表样式需要支持丰富多样的用户配置强大、开放的图表语法支持复杂的数据可视化场景…...
DT 卡通材质学习 一
渐变着色器 相交线 笔刷和卡通结合使用 修改器...
【游戏引擎架构】6.2 资源管理器
资源管理器可以分为离线部分系统和运行时系统 文章目录 离线资源管理数据库资产管道 运行时资源管理文件结构内存管理文件间引用 离线资源管理 数据库 UE的数据库可以直接浏览、编辑资产,看到运行时的状态;但也存在两个较大的缺点: 版本管…...
spring的ThreadPoolTaskExecutor装饰器传递调用线程信息给线程池中的线程
概述 需求是想在线程池执行任务的时候,在开始前将调用线程的信息传到子线程中,在子线程完成后,再清除传入的数据。 下面使用了spring的ThreadPoolTaskExecutor来实现这个需求. ThreadPoolTaskExecutor 在jdk中使用的是ThreadPoolExecutor…...
转载 - 洞察问题本质,解决工作难题
作者:关苏哲 高效管理者的三大技能 问题界定的6个问题 1.你所需要解决的问题是什么? 2.你为什么需要解决这个问题? 3.你期待的理想结果是什么? 4.这个问题包括哪些子问题? 5.你曾经尝试过哪些解决方式?…...
关于计算机找不到d3dx9_43.dll,无法继续执行代码修复方法
d3dx9_43.dll是一个动态链接库文件,它是DirectX的一个组件,主要用于处理游戏中的图形、声音等多媒体元素。当这个文件丢失时,可能会导致以下问题: 1. 游戏无法正常运行:由于d3dx9_43.dll负责处理游戏中的多媒体元素&a…...
《从零开始的Java世界》01基本程序设计
《从零开始的Java世界》系列主要讲解Javase部分,从最简单的程序设计到面向对象编程,再到异常处理、常用API的使用,最后到注解、反射,涵盖Java基础所需的所有知识点。学习者应该从学会如何使用,到知道其实现原理全方位式…...
【数据开发】数据全栈知识架构,数据(平台、开发、管理、分析)
文章目录 一、数据全栈知识架构1、数据方法(思维,统计学,实践,北极星)2、数据工具:数据仓库3、数据规范 二、数据分析工具1、大数据平台2、数据开发:入库计算(重点)3、数…...
基于STM32的宠物托运智能控制系统的设计(第十七届研电赛)
一、功能介绍 使用STM32作为主控设备,通过DHT11温湿度传感器、多合一空气质量检测传感器以及压力传感器对宠物的托运环境中的温湿度、二氧化碳浓度和食物与水的重量进行采集,将采集到的信息在本地LCD显示屏上显示,同时,使用4G模块…...
数据结构的奇妙世界:实用算法与实际应用
文章目录 数据结构和算法的基本概念数据结构数组链表栈队列树图 算法 常见的数据结构和算法排序算法快速排序示例 数据结构的应用数据库管理系统图像处理网络路由 数据结构和算法的性能分析时间复杂度空间复杂度 如何更好地编写代码避免常见错误结论 🎉欢迎来到数据…...
uniapp实现表格冻结
效果图如下: 思路: 1.由于APP项目需要,起初想去插件市场直接找现成的,结果找了很久没找到合适的(有的不支持vue2有的不能都支持APP和小程序) 2.后来,就只能去改uni-table源码了,因…...
Spring面试题11:什么是Spring的依赖注入
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring的依赖注入 依赖注入(Dependency Injection)是Spring框架的一个核心特性,它是指通过外部容器将对象的依赖关系注入到对象中,从而…...
用于设计 CNN 的 7 种不同卷积
一 说明 最近对CNN架构的研究包括许多不同的卷积变体,这让我在阅读这些论文时感到困惑。我认为通过一些更流行的卷积变体的精确定义,效果和用例(在计算机视觉和深度学习中)是值得的。这些变体旨在保存参数计数、增强推理并利用目标…...
备受以太坊基金会青睐的 Hexlink,构建亿级用户涌入 Web3的入口
早在2021年9月,以太坊创始人Vitalik Buterin就曾提出了EIP-4337(账户抽象)提案,并在去年10月对该提案进一步更新,引发行业的进一步关注。在今年3月,EIP-4337提案正式通过审计,并成为了ERC-4337标…...
合约升级标准 ERC2535 的设计解析和不足
合约升级标准 ERC2535 的设计解析和不足 Safful最近审计了钻石标准的一份实现代码,这一标准是一种新的可升级合约模式。撰写标准是一项值得赞许的事业,但钻石标准及其实现有许多引人担忧的地方。这份代码是过度工程的产物,附带了许多不必要的…...
【Vue】ElementUI实现登录注册
一、搭建项目 二、后台交互 三、CORS跨域 好啦今天到这了,希望能帮到你!!!...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
