【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)
【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)
文章目录
- 【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)
- 1、登录业务介绍
- 2、接口开发
- 2.1、获取图形验证码
- 2.2、登录接口
- 2.3、获取登录用户个人信息
1、登录业务介绍
登录管理共需三个接口,分别是获取图形验证码、登录、获取登录用户个人信息,除此之外,我们还需为所有受保护的接口增加验证JWT合法性的逻辑,这一功能可通过HandlerInterceptor
来实现。后台管理系统的登录流程如下图所示
2、接口开发
2.1、获取图形验证码
查看接口
代码开发
-
查看响应的数据结构
查看web-admin模块下的
com.atguigu.lease.web.admin.vo.login.CaptchaVo
,内容如下@Data @Schema(description = "图像验证码") @AllArgsConstructor public class CaptchaVo {@Schema(description="验证码图片信息")private String image;@Schema(description="验证码key")private String key; }
-
配置所需依赖
-
验证码生成工具
本项目使用开源的验证码生成工具EasyCaptcha,其支持多种类型的验证码,例如gif、中文、算术等,并且简单易用,具体内容可参考其官方文档。
在common模块的pom.xml文件中增加如下内容
<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId> </dependency>
-
Redis
在common模块的pom.xml中增加如下内容
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在
application.yml
中增加如下配置spring:data:redis:host: <hostname>port: <port>password:<password>database: 0
注意:上述
hostname
、password
和port
需根据实际情况进行修改,,如果你redis没有密码,可以省略
-
-
编写Controller层逻辑
在
LoginController
中增加如下内容@Operation(summary = "获取图形验证码") @GetMapping("login/captcha") public Result<CaptchaVo> getCaptcha() {CaptchaVo captcha = service.getCaptcha();return Result.ok(captcha); }
-
编写Service层逻辑
-
在
LoginService
中增加如下内容CaptchaVo getCaptcha();
-
在
LoginServiceImpl
中增加如下内容@Autowired private StringRedisTemplate redisTemplate;@Override public CaptchaVo getCaptcha() {SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);specCaptcha.setCharType(Captcha.TYPE_DEFAULT);String code = specCaptcha.text().toLowerCase();String key = RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID();String image = specCaptcha.toBase64();redisTemplate.opsForValue().set(key, code, RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);return new CaptchaVo(image, key); }
知识点:
-
本项目Reids中的key需遵循以下命名规范:项目名:功能模块名:其他,例如
admin:login:123456
-
spring-boot-starter-data-redis
已经完成了StringRedisTemplate
的自动配置,我们直接注入即可。 -
为方便管理,可以将Reids相关的一些值定义为常量,例如key的前缀、TTL时长,内容如下。大家可将这些常量统一定义在common模块下的
com.atguigu.lease.common.constant.RedisConstant
类中public class RedisConstant {public static final String ADMIN_LOGIN_PREFIX = "admin:login:";public static final Integer ADMIN_LOGIN_CAPTCHA_TTL_SEC = 60;public static final String APP_LOGIN_PREFIX = "app:login:";public static final Integer APP_LOGIN_CODE_RESEND_TIME_SEC = 60;public static final Integer APP_LOGIN_CODE_TTL_SEC = 60 * 10;public static final String APP_ROOM_PREFIX = "app:room:"; }
-
-
2.2、登录接口
查看接口
登录校验逻辑
用户登录的校验逻辑分为三个主要步骤,分别是校验验证码,校验用户状态和校验密码,具体逻辑如下
- 前端发送
username
、password
、captchaKey
、captchaCode
请求登录。 - 判断
captchaCode
是否为空,若为空,则直接响应验证码为空
;若不为空进行下一步判断。 - 根据
captchaKey
从Redis中查询之前保存的code
,若查询出来的code
为空,则直接响应验证码已过期
;若不为空进行下一步判断。 - 比较
captchaCode
和code
,若不相同,则直接响应验证码不正确
;若相同则进行下一步判断。 - 根据
username
查询数据库,若查询结果为空,则直接响应账号不存在
;若不为空则进行下一步判断。 - 查看用户状态,判断是否被禁用,若禁用,则直接响应
账号被禁
;若未被禁用,则进行下一步判断。 - 比对
password
和数据库中查询的密码,若不一致,则直接响应账号或密码错误
,若一致则进行入最后一步。 - 创建JWT,并响应给浏览器。
代码开发
-
查看请求数据结构
查看web-admin模块下的
com.atguigu.lease.web.admin.vo.login.LoginVo
,具体内容如下@Data @Schema(description = "后台管理系统登录信息") public class LoginVo {@Schema(description="用户名")private String username;@Schema(description="密码")private String password;@Schema(description="验证码key")private String captchaKey;@Schema(description="验证码code")private String captchaCode; }
-
配置所需依赖
登录接口需要为登录成功的用户创建并返回JWT,本项目使用开源的JWT工具Java-JWT,配置如下,具体内容可参考官方文档。
-
引入Maven依赖
在common模块的pom.xml文件中增加如下内容
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId> </dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><scope>runtime</scope> </dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><scope>runtime</scope> </dependency>
-
创建JWT工具类
在common模块下创建
com.atguigu.lease.common.utils.JwtUtil
工具类,内容如下public class JwtUtil {private static long tokenExpiration = 60 * 60 * 1000L;private static SecretKey tokenSignKey = Keys.hmacShaKeyFor("M0PKKI6pYGVWWfDZw90a0lTpGYX1d4AQ".getBytes());public static String createToken(Long userId, String username) {String token = Jwts.builder().setSubject("USER_INFO").setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).claim("userId", userId).claim("username", username).signWith(tokenSignKey).compact();return token;} }
-
-
编写Controller层逻辑
在
LoginController
中增加如下内容@Operation(summary = "登录") @PostMapping("login") public Result<String> login(@RequestBody LoginVo loginVo) {String token = service.login(loginVo);return Result.ok(token); }
-
编写Service层逻辑
-
在
LoginService
中增加如下内容String login(LoginVo loginVo);
-
在
LoginServiceImpl
中增加如下内容@Override public String login(LoginVo loginVo) {//1.判断是否输入了验证码if (!StringUtils.hasText(loginVo.getCaptchaCode())) {throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND);}//2.校验验证码String code = redisTemplate.opsForValue().get(loginVo.getCaptchaKey());if (code == null) {throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);}if (!code.equals(loginVo.getCaptchaCode().toLowerCase())) {throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR);}//3.校验用户是否存在SystemUser systemUser = systemUserMapper.selectOneByUsername(loginVo.getUsername());if (systemUser == null) {throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);}//4.校验用户是否被禁if (systemUser.getStatus() == BaseStatus.DISABLE) {throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);}//5.校验用户密码if (!systemUser.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))) {throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);}//6.创建并返回TOKENreturn JwtUtil.createToken(systemUser.getId(), systemUser.getUsername()); }
-
-
编写Mapper层逻辑
-
在
LoginMapper
中增加如下内容SystemUser selectOneByUsername(String username);
-
在
LoginMapper.xml
中增加如下内容<select id="selectOneByUsername" resultType="com.atguigu.lease.model.entity.SystemUser">select id,username,password,name,type,phone,avatar_url,additional_info,post_id,statusfrom system_userwhere is_deleted = 0and username = #{username} </select>
-
-
编写HandlerInterceptor
我们需要为所有受保护的接口增加校验JWT合法性的逻辑。具体实现如下
-
在
JwtUtil
中增加parseToken
方法,内容如下public static Claims parseToken(String token){if (token==null){throw new LeaseException(ResultCodeEnum.ADMIN_LOGIN_AUTH);}try{JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();return jwtParser.parseClaimsJws(token).getBody();}catch (ExpiredJwtException e){throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);}catch (JwtException e){throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);} }
-
编写HandlerInterceptor
在web-admin模块中创建
com.atguigu.lease.web.admin.custom.interceptor.AuthenticationInterceptor
类,内容如下,有关HanderInterceptor
的相关内容,可参考官方文档。@Component public class AuthenticationInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("access-token");JwtUtil.parseToken(token);return true;} }
注意:
我们约定,前端登录后,后续请求都将JWT,放置于HTTP请求的Header中,其Header的key为
access-token
。 -
注册HandlerInterceptor
在web-admin模块的
com.atguigu.lease.web.admin.custom.config.WebMvcConfiguration
中增加如下内容@Autowired private AuthenticationInterceptor authenticationInterceptor;@Override public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(this.authenticationInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/login/**"); }
-
-
Knife4j配置
在增加上述拦截器后,为方便继续调试其他接口,可以获取一个长期有效的Token,将其配置到Knife4j的全局参数中,如下图所示。
注意:每个接口分组需要单独配置,刷新页面,任选一个接口进行调试,会发现发送请求时会自动携带该header
2.3、获取登录用户个人信息
查看接口
代码开发
-
查看请求和响应的数据结构
-
响应的数据结构
查看web-admin模块下的
com.atguigu.lease.web.admin.vo.system.user.SystemUserInfoVo
,内容如下@Schema(description = "员工基本信息") @Data public class SystemUserInfoVo {@Schema(description = "用户姓名")private String name;@Schema(description = "用户头像")private String avatarUrl; }
-
请求的数据结构
按理说,前端若想获取当前登录用户的个人信息,需要传递当前用户的
id
到后端进行查询。但是由于请求中携带的JWT中就包含了当前登录用户的id
,故请求个人信息时,就无需再传递id
。
-
-
修改
JwtUtil
中的parseToken
方法由于需要从Jwt中获取用户
id
,因此需要为parseToken
方法增加返回值,如下public static Claims parseToken(String token){if (token==null){throw new LeaseException(ResultCodeEnum.ADMIN_LOGIN_AUTH);}try{JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();return jwtParser.parseClaimsJws(token).getBody();}catch (ExpiredJwtException e){throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);}catch (JwtException e){throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);} }
-
编写ThreadLocal工具类
理论上我们可以在Controller方法中,使用
@RequestHeader
获取JWT,然后在进行解析,如下@Operation(summary = "获取登陆用户个人信息") @GetMapping("info") public Result<SystemUserInfoVo> info(@RequestHeader("access-token") String token) {Claims claims = JwtUtil.parseToken(token);Long userId = claims.get("userId", Long.class);SystemUserInfoVo userInfo = service.getLoginUserInfo(userId);return Result.ok(userInfo); }
上述代码的逻辑没有任何问题,但是这样做,JWT会被重复解析两次(一次在拦截器中,一次在该方法中)。为避免重复解析,通常会在拦截器将Token解析完毕后,将结果保存至ThreadLocal中,这样一来,我们便可以在整个请求的处理流程中进行访问了。
ThreadLocal概述
ThreadLocal的主要作用是为每个使用它的线程提供一个独立的变量副本,使每个线程都可以操作自己的变量,而不会互相干扰,其用法如下图所示。
在common模块中创建
com.atguigu.lease.common.login.LoginUserHolder
工具类public class LoginUserHolder {public static ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();public static void setLoginUser(LoginUser loginUser) {threadLocal.set(loginUser);}public static LoginUser getLoginUser() {return threadLocal.get();}public static void clear() {threadLocal.remove();} }
同时在common模块中创建
com.atguigu.lease.common.login.LoginUser
类@Data @AllArgsConstructor public class LoginUser {private Long userId;private String username; }
-
修改
AuthenticationInterceptor
拦截器@Component public class AuthenticationInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("access-token");Claims claims = JwtUtil.parseToken(token);Long userId = claims.get("userId", Long.class);String username = claims.get("username", String.class);LoginUserHolder.setLoginUser(new LoginUser(userId, username));return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {LoginUserHolder.clear();} }
-
编写Controller层逻辑
在
LoginController
中增加如下内容@Operation(summary = "获取登陆用户个人信息") @GetMapping("info") public Result<SystemUserInfoVo> info() {SystemUserInfoVo userInfo = service.getLoginUserInfo(LoginUserHolder.getLoginUser().getUserId());return Result.ok(userInfo); }
-
编写Service层逻辑
在
LoginService
中增加如下内容@Override public SystemUserInfoVo getLoginUserInfo(Long userId) {SystemUser systemUser = systemUserMapper.selectById(userId);SystemUserInfoVo systemUserInfoVo = new SystemUserInfoVo();systemUserInfoVo.setName(systemUser.getName());systemUserInfoVo.setAvatarUrl(systemUser.getAvatarUrl());return systemUserInfoVo; }
相关文章:
![](https://img-blog.csdnimg.cn/img_convert/92207a2e8c1540860af89ee086a4b24b.png)
【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)
【尚庭公寓SpringBoot Vue 项目实战】登录管理(十八) 文章目录 【尚庭公寓SpringBoot Vue 项目实战】登录管理(十八)1、登录业务介绍2、接口开发2.1、获取图形验证码2.2、登录接口2.3、获取登录用户个人信息 1、登录业务介绍 登…...
![](https://www.ngui.cc/images/no-images.jpg)
【html】用html+css做地表最强王者荣耀辅助工具
源码: <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><style>* {margin: 0;padding: 0;}body{background-color: blue;}.con {width: 300px;height: 500px;background-color: rgba(230,…...
![](https://img-blog.csdnimg.cn/direct/ea3e2b6b5e864c609117a7c49be8ef17.png#pic_center)
TF-IDF、BM25传统算法总结
1. TF-IDF算法 F-IDF(词频-逆文档频率)是一种用于衡量文本中词语重要性的方法,特别适用于信息检索和文本挖掘任务。下面会拆分为两部分深入讲解TF-IDF的计算过程,以便更好地理解。 TF-IDF的计算过程可以分为两个主要部分…...
![](https://img-blog.csdnimg.cn/direct/e657f557b35e4efdbc870bc611dbfa7a.png)
项目五 OpenStack镜像管理与制作
任务一 理解OpenStack镜像服务 1.1 •什么是镜像 • 镜像通常 是指一系列文件或一个磁盘驱动器的精确副本 。 • 虚拟机 所使用的虚拟磁盘, 实际上是 一种特殊格式的镜像文件 。 • 云 环境下尤其需要 镜像。 • 镜像 就是一个模板,类似于 VMware 的虚拟…...
![](https://img-blog.csdnimg.cn/img_convert/be999417b97fe80c46543d50c509b73e.png)
LabVIEW回热系统热经济性分析及故障诊断
开发了一种利用LabVIEW软件的电厂回热系统热经济性分析和故障诊断系统。该系统针对火电厂回热加热器进行优化,通过实时数据监控与分析,有效提高机组的经济性和安全性,同时降低能耗和维护成本。系统的实施大幅提升了火电厂运行的效率和可靠性&…...
![](https://www.ngui.cc/images/no-images.jpg)
设计模式-迭代器模式
目录 一:基本介绍 二:原理说明 三:案例说明 四:优点 五:缺点 一:基本介绍 1)属于行为模式 2)如果我们的集合元素是用不同的方式实现的,有数组,还有java的集合类,或者还有其他方式,当客户 端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以…...
![](https://img-blog.csdnimg.cn/direct/f3c49dad041941e99b6d8a6de390c400.jpeg)
UV胶带和UV胶水的应用场景有哪些不同吗?
UV胶带和UV胶水的应用场景有哪些不同吗? UV胶带和UV胶水的应用场景确实存在不同之处,以下是详细的比较和归纳: 一:按使用场景来看: UV胶带的应用场景: 包装行业:UV胶带在包装行业中常用于食品包装、药…...
![](https://img-blog.csdnimg.cn/img_convert/30ff23bde6f4f9b01b17e942162c0436.jpeg)
监控员工上网软件有哪些|4款好用的员工上网行为管理软件推荐
在当今数字化办公环境中,确保网络安全、提升工作效率、以及规范员工上网行为成为企业管理的重要组成部分。 为此,一套高效的员工上网行为管理软件显得尤为关键。 本文将为您推荐五款市场上广受好评的员工上网行为管理软件,帮助您有效监控与管…...
![](https://img-blog.csdnimg.cn/direct/4899ad6a01534bd4a7a201f25d10112c.gif#pic_center)
【IPython的使用技巧】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...
![](https://img-blog.csdnimg.cn/direct/b5d6d27d97044b9b879b3e34a8118984.png)
最新AI智能聊天对话问答系统源码(详细图文搭建部署教程)+AI绘画系统(Midjourney),DALL-E3文生图,TTS语音识别输入,文档分析
一、文章前言 随着人工智能技术的持续进步,AI绘画已经发展成为一个日益成熟的领域。越来越多的人开始尝试使用AI绘画软件来创作艺术作品。尽管这些AI绘画软件对绘画领域产生了显著影响,但它们并不会完全取代画师。与传统手绘不同,AI绘画可以…...
![](https://img-blog.csdnimg.cn/direct/f5aefebcd0a842978a261d735552822c.png)
项目四 OpenStack身份管理
任务一 理解身份服务 1.1 •Keystone的基本概念 • 认证 ( Authentication ) —— 确认 用户身份的过程,又称身份验证 。 • 凭证 ( Credentials ) —— 又 称凭据,是用于确认用户身份的数据 。 • 令牌 …...
![](https://img-blog.csdnimg.cn/direct/68852aec44dd4cc0b48eab7eda0028c2.png)
【后端】websocket学习笔记
文章目录 1. 消息推送常见方式1.1 轮询 VS 长轮询1.2 SSE(server-sent event)服务器发送事件 2. websocket介绍2.1 介绍2.2 原理2.3 websoket API2.3.1 客户端【浏览器】API2.3.2 服务端API 3. 代码实现3.1 流程分析3.2 pom依赖3.3 配置类3.4 消息格式3.5 消息类 4.…...
![](https://img-blog.csdnimg.cn/img_convert/c3c0aadfcd70e1525619dc61eaacbfd7.png)
DataWhale - 吃瓜教程学习笔记(一)
学习视频:第1章-绪论_哔哩哔哩_bilibili 西瓜书对应章节: 第一章 & 第二章 文章目录 机器学习三观What:什么是机器学习?Why: 为什么要学机器学习?1. 机器学习理论研究2. 机器学习系统开发3. 机器学习算法迁移 &…...
![](https://img-blog.csdnimg.cn/direct/5ef90d73517c4050ad10405fd93cab0d.png)
Attention Is All You Need论文地址
论文地址 点击即可...
![](https://www.ngui.cc/images/no-images.jpg)
如何优雅的一键下载OpenHarmony活跃分支代码?请关注【itopen: ohos_download】
itopen组织:1、提供OpenHarmony优雅实用的小工具2、手把手适配riscv qemu linux的三方库移植3、未来计划riscv qemu ohos的三方库移植 小程序开发4、一切拥抱开源,拥抱国产化 一、概述 为方便大家每次下载OpenHarmony不同分支/tag代码,…...
![](https://www.ngui.cc/images/no-images.jpg)
torch.topk用法
torch.topk用法 介绍使用示例 介绍 官网介绍:https://pytorch.org/docs/stable/generated/torch.topk.html 在指定维度选取k个最大(最小)的值。 使用示例 values torch.tensor([[2, 1, 3], [1, 2, 3]]) # values # tensor([[2, 1, 3], #…...
![](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://qqcq.oss-cn-shanghai.aliyuncs.com/image-20240619183008954.png)
终极版本的Typora上传到博客园和csdn
激活插件 下载网址是这个: https://codeload.github.com/obgnail/typora_plugin/zip/refs/tags/1.9.4 解压之后这样的: 解压之后将plugin,复制到自己的安装目录下的resources 点击安装即可: 更改配置文件 "dependencies&q…...
![](https://www.ngui.cc/images/no-images.jpg)
洛谷:P5707【深基2.例12】上学迟到
1. 题目链接 https://www.luogu.com.cn/problem/P5707 【深基2.例12】上学迟到 2. 题目描述 学校和y的家距离s米,s以v的速度去学校,8点之前到,y出门前要打扫10分钟卫生,求s最晚的出门时间 输入:两个正整数路程s&…...
![](https://www.ngui.cc/images/no-images.jpg)
数据治理:数据提取过程中的合规性与安全性
数据治理:数据提取过程中的合规性与安全性 随着数字化时代的到来,数据已经成为企业运营和决策的核心驱动力。然而,在数据提取的过程中,确保数据的合规性和安全性成为了企业面临的重要挑战。数据治理作为一种系统的方法࿰…...
![](https://img-blog.csdnimg.cn/direct/ac8d97ee06914a13bd31c3acda3ce070.png)
24计算机应届生的活路是什么
不够大胆❗ 很多小伙伴在找工作时觉得自己没有竞争力,很没有自信,以至于很害怕找工作面试,被人否定的感觉很不好受。 其实很多工作并没有想象中的高大上,不要害怕,计算机就业的方向是真的广,不要走窄了&…...
![](https://www.ngui.cc/images/no-images.jpg)
HTML页面布局-使用div示例
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!--text-align:center 文字水平居中line-height:200px; 文字垂直居中,行高设置跟高…...
![](https://img-blog.csdnimg.cn/img_convert/07a87459cb088bc901584fe6824fa139.png)
怎么把webp文件转换为jpg?快来试试这四种转换方法!
怎么把webp文件转换为jpg?Webp是一种不常见的图片格式,这种格式在使用过程中有很多缺点,首先它的浏览器兼容性不是很强,这就代表大家无法随意进行网络传输,可能需要准备特定的操作才能进行,然后编辑webp的工…...
![](https://img-blog.csdnimg.cn/direct/b77768fd4d7a454b94d69d956c5bcf2d.png)
计算机网络(7) 错误检测
一.校验和 使用补码计算校验和是一种常见的错误检测方法,应用于网络协议如IP和TCP。补码是二进制数的一种表示方法,可以有效地处理符号位和进位。下面是如何利用补码计算校验和的详细步骤和算数例子。 ### 计算步骤 1. **将数据分块**:将数…...
![](https://img-blog.csdnimg.cn/direct/af53b90f602e48f2a79b9044befb5ca9.png)
实体类status属性使用枚举类型的步骤
1. 问题引出 当实体类的状态属性为Integer类型时,容易写错 2. 初步修改 把状态属性强制为某个类型,并且自定义一些可供选择的常量。 public class LessonStatus {public static final LessonStatus NOT_LEARNED new LessonStatus(0,"未学习"…...
![](https://img-blog.csdnimg.cn/direct/52ab3bb72bcc4f09819c392527254a39.png#pic_center)
pytorch基础【4】梯度计算、链式法则、梯度清零
文章目录 梯度计算计算图(Computational Graph)梯度求导(Gradient Computation)函数与概念 示例代码更多细节梯度求导的过程梯度求导的基本步骤示例代码注意事项总结 链式法则是什么?链式法则的数学定义链式法则在深度…...
![](https://www.ngui.cc/images/no-images.jpg)
mapreduce综合应用案例 — 招聘数据清洗
MapReduce是一个编程模型和处理大数据集的框架,它由Google开发并广泛使用于分布式计算环境中。MapReduce模型包含两个主要的函数:Map和Reduce。Map函数用于处理输入的键值对生成中间键值对,Reduce函数则用于合并Map函数输出的具有相同键的中间…...
![](https://img-blog.csdnimg.cn/img_convert/af1e6a00fe211b0a763b53151b2b507c.png)
发力采销,京东的“用户关系学”
作者 | 曾响铃 文 | 响铃说 40多岁打扮精致的城市女性,在西藏那曲的偏远农村,坐着藏民的摩托车,行驶在悬崖边的烂泥路上,只因为受顾客的“委托”,要寻找最原生态的藏区某款产品。 30多岁的憨厚中年男性,…...
![](https://img-blog.csdnimg.cn/img_convert/9a240b0410c6623c96abced6ed0d3117.jpeg)
期望23K,go高级社招面试复盘
面经哥只做互联网社招面试经历分享,关注我,每日推送精选面经,面试前,先找面经哥 我最终还是上岸了,花了一周总结了3万字的go社招高级面试知识体系思维导图,分享出来希望能帮助有缘人吧,以下只是…...
![](https://img-blog.csdnimg.cn/direct/1798f5b1f5194617b6a131d6452ab9c1.png)
电感(线圈)具有哪些基本特性
首先,电感(线圈)具有以下基本特性,称之为“电感的感性电抗” ?①直流基本上直接流过。 ?②对于交流,起到类似电阻的作用。 ?③频率越高越难通过。 下面是表示电感的频率和阻抗特性的示意图。 在理想电感器中&#…...
![](https://img-blog.csdnimg.cn/direct/7344d08bb92243acbfdb6064f3eca68d.png)
tkinter实现一个GUI界面-快速入手
目录 一个简单界面输出效果其他功能插入进度条文本框内容输入和删除标签内容显示和删除 一个简单界面 含插入文本、文本框、按钮、按钮调用函数 # -*- coding: UTF-8 -*-import tkinter as tk from tkinter import END from tkinter import filedialog from tkinter impor…...
![](https://img-blog.csdnimg.cn/img_convert/b8ee0f829447e29903cae48b0cc40028.png)
申请一个自己的网站/石家庄网站建设培训
题库来源:安全生产模拟考试一点通公众号小程序 安全生产模拟考试一点通:低压电工报名考试考前必练!安全生产模拟考试一点通每个月更新低压电工模拟考试题库题目及答案!多做几遍,其实通过低压电工作业考试题库很简单。…...
![](/images/no-images.jpg)
九九建筑网官网登录/搜索引擎优化的概念是什么
Source Insight自定义快捷键 鄙人一直用的是Eclipse来开发,如果只是做java的话,这个就够了,但因时不时要查C/C的代码,这个时候这个工具就有点力不从心了,因为C/C的代码非常多,一般放在服务器上,…...
![](https://img-blog.csdnimg.cn/31c36d0fa2ee47d490b0054dc02d723f.png)
网站seo推广优化报价表/网络营销计划的七个步骤
这里写目录标题1.DataSource理论知识1.DataSource理论知识 什么是数据源-DataSource 简单理解为数据源头,提供了应用程序所需要数据的位置。数据源保证了应用程序与目标数据之间交互的规范和协议,它可以是数据库,文件系统等等。其中数据源定…...
![](https://exp-picture.cdn.bcebos.com/9a8fd9f88a775dddd6785afea427e7ef2906f988.jpg?x-bce-process=image%2Fresize%2Cm_lfit%2Cw_500%2Climit_1)
对于网站反爬虫如何做/电脑优化系统的软件哪个好
有时候我们在使用pycharm进行python编程的时候,遇到了no python interpreter for the project,怎么解决呢,下面来分享一下方法 工具/原料 pycharm no python interpreter for the project解决方法 方法/步骤 1 第一步我们在使用pycharm进行py…...
![](http://igoro.com/wordpress/wp-content/uploads/2010/02/image12.png)
做国外网站用什么颜色/潍坊网站seo
网上各种的说法,不外乎这么几种 第一种简单的说呢就是这样的: 第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器。 第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器…...
![](/images/no-images.jpg)
网站内容避免被采集/seo网络推广课程
当然用啊,新手的话建议入手两本左右的基础书籍。 最重要的是你要明确自己要做什么? 学习python,要明确自己的方向,python作为一门工具,能做的事情很多,如果你想要做web开发,那就需要学习django,flask等框架,如果你想做数据分析,那就需要学习numpy pandas…...