当前位置: 首页 > news >正文

【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)

【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)


文章目录

      • 【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)
        • 1、登录业务介绍
        • 2、接口开发
          • 2.1、获取图形验证码
          • 2.2、登录接口
          • 2.3、获取登录用户个人信息

1、登录业务介绍

登录管理共需三个接口,分别是获取图形验证码登录获取登录用户个人信息,除此之外,我们还需为所有受保护的接口增加验证JWT合法性的逻辑,这一功能可通过HandlerInterceptor来实现。后台管理系统的登录流程如下图所示

image-20240619221355636

2、接口开发
2.1、获取图形验证码

查看接口

image-20240619221628521

代码开发

  • 查看响应的数据结构

    查看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
      

      注意:上述hostnamepasswordport需根据实际情况进行修改,,如果你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、登录接口

查看接口

image-20240619221948522

登录校验逻辑

用户登录的校验逻辑分为三个主要步骤,分别是校验验证码校验用户状态校验密码,具体逻辑如下

  • 前端发送usernamepasswordcaptchaKeycaptchaCode请求登录。
  • 判断captchaCode是否为空,若为空,则直接响应验证码为空;若不为空进行下一步判断。
  • 根据captchaKey从Redis中查询之前保存的code,若查询出来的code为空,则直接响应验证码已过期;若不为空进行下一步判断。
  • 比较captchaCodecode,若不相同,则直接响应验证码不正确;若相同则进行下一步判断。
  • 根据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的全局参数中,如下图所示。

    image-20240619222213976

    注意:每个接口分组需要单独配置,刷新页面,任选一个接口进行调试,会发现发送请求时会自动携带该header

2.3、获取登录用户个人信息

查看接口

image-20240619222327267

代码开发

  • 查看请求和响应的数据结构

    • 响应的数据结构

      查看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;
    }
    

相关文章:

【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)

【尚庭公寓SpringBoot Vue 项目实战】登录管理&#xff08;十八&#xff09; 文章目录 【尚庭公寓SpringBoot Vue 项目实战】登录管理&#xff08;十八&#xff09;1、登录业务介绍2、接口开发2.1、获取图形验证码2.2、登录接口2.3、获取登录用户个人信息 1、登录业务介绍 登…...

【html】用html+css做地表最强王者荣耀辅助工具

源码&#xff1a; <!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,…...

TF-IDF、BM25传统算法总结

1. TF-IDF算法 F-IDF&#xff08;词频-逆文档频率&#xff09;是一种用于衡量文本中词语重要性的方法&#xff0c;特别适用于信息检索和文本挖掘任务。下面会拆分为两部分深入讲解TF-IDF的计算过程&#xff0c;以便更好地理解。 TF-IDF的计算过程可以分为两个主要部分&#xf…...

项目五 OpenStack镜像管理与制作

任务一 理解OpenStack镜像服务 1.1 •什么是镜像 • 镜像通常 是指一系列文件或一个磁盘驱动器的精确副本 。 • 虚拟机 所使用的虚拟磁盘&#xff0c; 实际上是 一种特殊格式的镜像文件 。 • 云 环境下尤其需要 镜像。 • 镜像 就是一个模板&#xff0c;类似于 VMware 的虚拟…...

LabVIEW回热系统热经济性分析及故障诊断

开发了一种利用LabVIEW软件的电厂回热系统热经济性分析和故障诊断系统。该系统针对火电厂回热加热器进行优化&#xff0c;通过实时数据监控与分析&#xff0c;有效提高机组的经济性和安全性&#xff0c;同时降低能耗和维护成本。系统的实施大幅提升了火电厂运行的效率和可靠性&…...

设计模式-迭代器模式

目录 一:基本介绍 二:原理说明 三:案例说明 四:优点 五:缺点 一:基本介绍 1)属于行为模式 2)如果我们的集合元素是用不同的方式实现的,有数组,还有java的集合类,或者还有其他方式,当客户 端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以…...

UV胶带和UV胶水的应用场景有哪些不同吗?

UV胶带和UV胶水的应用场景有哪些不同吗? UV胶带和UV胶水的应用场景确实存在不同之处&#xff0c;以下是详细的比较和归纳&#xff1a; 一&#xff1a;按使用场景来看&#xff1a; UV胶带的应用场景&#xff1a; 包装行业&#xff1a;UV胶带在包装行业中常用于食品包装、药…...

监控员工上网软件有哪些|4款好用的员工上网行为管理软件推荐

在当今数字化办公环境中&#xff0c;确保网络安全、提升工作效率、以及规范员工上网行为成为企业管理的重要组成部分。 为此&#xff0c;一套高效的员工上网行为管理软件显得尤为关键。 本文将为您推荐五款市场上广受好评的员工上网行为管理软件&#xff0c;帮助您有效监控与管…...

【IPython的使用技巧】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…...

最新AI智能聊天对话问答系统源码(详细图文搭建部署教程)+AI绘画系统(Midjourney),DALL-E3文生图,TTS语音识别输入,文档分析

一、文章前言 随着人工智能技术的持续进步&#xff0c;AI绘画已经发展成为一个日益成熟的领域。越来越多的人开始尝试使用AI绘画软件来创作艺术作品。尽管这些AI绘画软件对绘画领域产生了显著影响&#xff0c;但它们并不会完全取代画师。与传统手绘不同&#xff0c;AI绘画可以…...

项目四 OpenStack身份管理

任务一 理解身份服务 1.1 •Keystone的基本概念 • 认证 &#xff08; Authentication &#xff09; —— 确认 用户身份的过程&#xff0c;又称身份验证 。 • 凭证 &#xff08; Credentials &#xff09; —— 又 称凭据&#xff0c;是用于确认用户身份的数据 。 • 令牌 …...

【后端】websocket学习笔记

文章目录 1. 消息推送常见方式1.1 轮询 VS 长轮询1.2 SSE&#xff08;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.…...

DataWhale - 吃瓜教程学习笔记(一)

学习视频&#xff1a;第1章-绪论_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 第一章 & 第二章 文章目录 机器学习三观What&#xff1a;什么是机器学习&#xff1f;Why: 为什么要学机器学习&#xff1f;1. 机器学习理论研究2. 机器学习系统开发3. 机器学习算法迁移 &…...

Attention Is All You Need论文地址

论文地址 点击即可...

如何优雅的一键下载OpenHarmony活跃分支代码?请关注【itopen: ohos_download】

itopen组织&#xff1a;1、提供OpenHarmony优雅实用的小工具2、手把手适配riscv qemu linux的三方库移植3、未来计划riscv qemu ohos的三方库移植 小程序开发4、一切拥抱开源&#xff0c;拥抱国产化 一、概述 为方便大家每次下载OpenHarmony不同分支/tag代码&#xff0c…...

torch.topk用法

torch.topk用法 介绍使用示例 介绍 官网介绍&#xff1a;https://pytorch.org/docs/stable/generated/torch.topk.html 在指定维度选取k个最大&#xff08;最小&#xff09;的值。 使用示例 values torch.tensor([[2, 1, 3], [1, 2, 3]]) # values # tensor([[2, 1, 3], #…...

终极版本的Typora上传到博客园和csdn

激活插件 下载网址是这个&#xff1a; https://codeload.github.com/obgnail/typora_plugin/zip/refs/tags/1.9.4 解压之后这样的&#xff1a; 解压之后将plugin&#xff0c;复制到自己的安装目录下的resources 点击安装即可&#xff1a; 更改配置文件 "dependencies&q…...

洛谷:P5707【深基2.例12】上学迟到

1. 题目链接 https://www.luogu.com.cn/problem/P5707 【深基2.例12】上学迟到 2. 题目描述 学校和y的家距离s米&#xff0c;s以v的速度去学校&#xff0c;8点之前到&#xff0c;y出门前要打扫10分钟卫生&#xff0c;求s最晚的出门时间 输入&#xff1a;两个正整数路程s&…...

数据治理:数据提取过程中的合规性与安全性

数据治理&#xff1a;数据提取过程中的合规性与安全性 随着数字化时代的到来&#xff0c;数据已经成为企业运营和决策的核心驱动力。然而&#xff0c;在数据提取的过程中&#xff0c;确保数据的合规性和安全性成为了企业面临的重要挑战。数据治理作为一种系统的方法&#xff0…...

24计算机应届生的活路是什么

不够大胆❗ 很多小伙伴在找工作时觉得自己没有竞争力&#xff0c;很没有自信&#xff0c;以至于很害怕找工作面试&#xff0c;被人否定的感觉很不好受。 其实很多工作并没有想象中的高大上&#xff0c;不要害怕&#xff0c;计算机就业的方向是真的广&#xff0c;不要走窄了&…...

HTML页面布局-使用div示例

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!--text-align:center 文字水平居中line-height&#xff1a;200px; 文字垂直居中,行高设置跟高…...

怎么把webp文件转换为jpg?快来试试这四种转换方法!

怎么把webp文件转换为jpg&#xff1f;Webp是一种不常见的图片格式&#xff0c;这种格式在使用过程中有很多缺点&#xff0c;首先它的浏览器兼容性不是很强&#xff0c;这就代表大家无法随意进行网络传输&#xff0c;可能需要准备特定的操作才能进行&#xff0c;然后编辑webp的工…...

计算机网络(7) 错误检测

一.校验和 使用补码计算校验和是一种常见的错误检测方法&#xff0c;应用于网络协议如IP和TCP。补码是二进制数的一种表示方法&#xff0c;可以有效地处理符号位和进位。下面是如何利用补码计算校验和的详细步骤和算数例子。 ### 计算步骤 1. **将数据分块**&#xff1a;将数…...

实体类status属性使用枚举类型的步骤

1. 问题引出 当实体类的状态属性为Integer类型时&#xff0c;容易写错 2. 初步修改 把状态属性强制为某个类型&#xff0c;并且自定义一些可供选择的常量。 public class LessonStatus {public static final LessonStatus NOT_LEARNED new LessonStatus(0,"未学习"…...

pytorch基础【4】梯度计算、链式法则、梯度清零

文章目录 梯度计算计算图&#xff08;Computational Graph&#xff09;梯度求导&#xff08;Gradient Computation&#xff09;函数与概念 示例代码更多细节梯度求导的过程梯度求导的基本步骤示例代码注意事项总结 链式法则是什么&#xff1f;链式法则的数学定义链式法则在深度…...

mapreduce综合应用案例 — 招聘数据清洗

MapReduce是一个编程模型和处理大数据集的框架&#xff0c;它由Google开发并广泛使用于分布式计算环境中。MapReduce模型包含两个主要的函数&#xff1a;Map和Reduce。Map函数用于处理输入的键值对生成中间键值对&#xff0c;Reduce函数则用于合并Map函数输出的具有相同键的中间…...

发力采销,京东的“用户关系学”

作者 | 曾响铃 文 | 响铃说 40多岁打扮精致的城市女性&#xff0c;在西藏那曲的偏远农村&#xff0c;坐着藏民的摩托车&#xff0c;行驶在悬崖边的烂泥路上&#xff0c;只因为受顾客的“委托”&#xff0c;要寻找最原生态的藏区某款产品。 30多岁的憨厚中年男性&#xff0c;…...

期望23K,go高级社招面试复盘

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 我最终还是上岸了&#xff0c;花了一周总结了3万字的go社招高级面试知识体系思维导图&#xff0c;分享出来希望能帮助有缘人吧&#xff0c;以下只是…...

电感(线圈)具有哪些基本特性

首先&#xff0c;电感&#xff08;线圈&#xff09;具有以下基本特性&#xff0c;称之为“电感的感性电抗” ?①直流基本上直接流过。 ?②对于交流&#xff0c;起到类似电阻的作用。 ?③频率越高越难通过。 下面是表示电感的频率和阻抗特性的示意图。 在理想电感器中&#…...

tkinter实现一个GUI界面-快速入手

目录 一个简单界面输出效果其他功能插入进度条文本框内容输入和删除标签内容显示和删除 一个简单界面 含插入文本、文本框、按钮、按钮调用函数 # -*- coding: UTF-8 -*-import tkinter as tk from tkinter import END from tkinter import filedialog from tkinter impor…...

seo站外推广业务外包/seo排名工具哪个好

翻译自:Always Include LOBS In Trail File (Doc ID 1639717.1)适用于:Oracle GoldenGate - Version 11.1.1.0.0 and laterInformation in this document applies to any platform.目标:当lob字段没有update时,怎么强制抽取进程把lob数据放在trail文件中?解决方案:在抽取进程的…...

什么网站可以做拍a发布会/关键词优化系统

环境MacPython3.6.4Atom背景Atom 执行Python Code 使用Script Package&#xff0c;执行快捷键cmd i。但是默认是执行Mac 系统的2.7 版本的Python。配置cmd &#xff0c;(cmd 逗号) 快捷键 打开Settings&#xff0c;或者点击Atom→Preferences 打开Settings点击Open Config F…...

西部数码网站开发管理助手/网络seo首页

soft-raid $cat /proc/mdstat hard-raid $cat /proc/scsi/ [tab] 键, 里面会有内容的 另外用 $dmesg|grep md 也可以查soft-raid $dmesg|grep scsi 查hard-raid &#xff0c;不过通常sata 和usb-hd等设备也被作为scsi,转载于:https://www.cnblogs.com/super119/archive/2010/12…...

太原网站关键词优化/四川seo

1、安装QQ、微信&#xff1a;https://www.lulinux.com/archives/1319 试过无数个QQ的版本&#xff0c;可能在linux上最头疼的就是QQ不好用。之前有个2012国际版&#xff0c;虽然比较老&#xff0c;但还比较稳定&#xff0c;就是用着难受&#xff1b;后来换了新版的wineQQ8.9&a…...

外包加工哪个网站最靠谱/seo网络优化公司哪家好

掐指一算&#xff0c;全国计算机二级就要开考了不知道大家准备的怎么样了&#xff1f;没准备&#xff1f;这个时候就该我出场了看看为大家精心准备的计算机二级考试的干货资源吧让你的考试一次pass&#xff01;本期资料包括计算机二级考试最新大纲计算机二级模考软件计算机二级…...

wordpress文章加载特效/武汉seo优化排名公司

导读3GPP协议最大的特点估计就是多了&#xff0c;文档太多&#xff0c;这也就罢了&#xff0c;文档之间还互相引用&#xff0c;往往看明白一个协议要连带再看几个协议。3GPP协议是一个整体&#xff0c;既然是一个整体就可以试试先了解下它的全貌&#xff0c;了解全貌可以从3GPP…...