JWT使用教程
目录
- JWT (JSON Web Token)
- 1. JWT简介
- (1) 什么是JWT
- (2) JWT有什么用
- (3) JWT认证方式
- 2. JWT的组成部分
- 3. 签名的目的
- 4. JWT与Token的区别
- 5 JWT的优势
- 6 JJWT签发与验证token
- (1) 引入依赖
- (2) 创建 Token
- (3) 解析Token
- (4) 设置过期时间
- (5) 自定义claims
- 7. JWT自定义工具类
JWT (JSON Web Token)
1. JWT简介
(1) 什么是JWT
JWT是一种基于 Token 的认证授权机制.
JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。
(2) JWT有什么用
JWT最常见的场景就是授权认证,用户登录之后,后续的每个请求都将包含JWT, 系统在每次处理用户请求之前,都要先进行JWT的安全校验,通过校验之后才能进行接下来的操作。
(3) JWT认证方式
- JWT通过数字签名的方式,以JSON对象为载体,在用户和服务器之间传递安全可靠的信息.
- 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
- 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT(Token)。形成的JWT就是一个形同lll.zzz.xxx的字符串。 token head.payload.singurater
- 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。
- 前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题) HEADER
- 后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。
- 验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。
2. JWT的组成部分
头部(Header)
- 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
{"typ":"JWT","alg":"HS256"}//typ(Type):令牌类型,也就是 JWT。//alg(Algorithm) :签名算法,比如 HS256。
JWT签名算法中,一般有两个选择,一个采用HS256,另外一个就是采用RS256
进行BASE64编码https://base64.us/,编码后的字符串如下:eyJhbGciOiJIUzI1NiJ9
载荷(payload)
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
{"sub":"1234567890","name":"John Doe","admin":true}
将上面的JSON数据进行base64编码,得到Jwt第二部分: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
字段说明,下面的字段都是由 JWT的标准所定义的
iss: jwt签发者sub: jwt所面向的用户aud: 接收jwt的一方exp: jwt的过期时间,这个过期时间必须要大于签发时间nbf: 定义在什么时间之前,该jwt都是不可用的.iat: jwt的签发时间jti: jwt的唯一身份标识,主要用来作为一次性token。
签名(signature)
服务器通过 Payload、Header 和一个密钥(Secret) 使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。
Signature 部分是对前两部分的签名,作用是防止 Token(主要是 payload) 被篡改。
这个签名的生成需要用到:
- Header + Payload。
- 存放在服务端的密钥(一定不要泄露出去)。
- 签名算法。
例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:
String encodeString = base64UrlEncode(header) + "." + base64UrlEncode(payload);String secret = HMACSHA256(encodeString,secret);
签名用于验证消息在此过程中没有更改,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者是它所说的真实身份。
注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
3. 签名的目的
最后一步签名的过程,实际上是对头部以及载荷内容进行签名。
一般而言,加密算法对于不同的输入产生的输出总是不一样的。对于两个不同的输入,产生同样的输出的概率极其地小(有可能比我成世界首富的概率还小)。所以,我们就把“不一样的输入产生不一样的输出”当做必然事件来看待吧。
所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。
服务器应用在接受到JWT后,会首先对头部和载荷的内容用同一算法再次签名。那么服务器应用是怎么知道我们用的是哪一种算法呢?别忘了,我们在JWT的头部中已经用** alg
字段指明了我们的加密算法了。
如果服务器应用对头部和载荷再次以同样方法签名之后发现,自己计算出来的签名和接受到的签名不一样,那么就说明这个Token的内容被别人动过的,我们应该拒绝这个Token,返回一个HTTP 401 Unauthorized响应。
4. JWT与Token的区别
Token 和 JWT (JSON Web Token) 都是用来在客户端和服务器之间传递身份验证信息的一种方式。但是它们之间有一些区别。
- Token 是一个通用术词,可以指代任何用来表示身份的字符串。它可以是任何形式的字符串,并不一定是 JWT。
- JWT 是一种特殊的 Token,它是一个 JSON 对象,被编码成字符串并使用秘密密钥进行签名。JWT 可以用来在身份提供者和服务提供者之间安全地传递身份信息,因为它可以被加密,并且只有拥有秘密密钥的方能解密。
总的来说,JWT 是一种特殊的 Token,它具有更强的安全性和可靠性。
5 JWT的优势
- 简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快
- 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
- 因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持
- 不需要在服务端保存会话信息,特别适用于分布式微服务。
6 JJWT签发与验证token
使用jjwt实现jwt的签发和解析获取payload中的数据.
JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0)。
官方文档:https://github.com/jwtk/jjwt
(1) 引入依赖
<!--jwt依赖--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
(2) 创建 Token
@SpringBootTestclass SpringsecurityExampleApplicationTests {@Testvoid contextLoads() {}@Testpublic void testJJWT(){JwtBuilder builder = Jwts.builder().setId("9527") //设置唯一ID.setSubject("hejiayun_community") //设置主体.setIssuedAt(new Date()) //设置签约时间.signWith(SignatureAlgorithm.HS256, "mashibing");//设置签名 使用HS256算法,并设置SecretKey//压缩成String形式,签名的JWT称为JWSString jws = builder.compact();System.out.println(jws);/*** eyJhbGciOiJIUzI1NiJ9.* eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM1ODY2fQ.* ybkDJLVj1Fsi8m3agyxtyd0wxv7lHDqCWNOLN-eOxC8*/}}
运行打印结果:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM1ODY2fQ.ybkDJLVj1Fsi8m3agyxtyd0wxv7lHDqCWNOLN-eOxC
(3) 解析Token
我们刚才已经创建了token ,在web应用中这个操作是由服务端进行然后发给客户端,客户端在下次向服务端发送请求时需要携带这个token(这就好像是拿着一张门票一样),那服务端接到这个token 应该解析出token中的信息(例如用户id),根据这些信息查询数据库返回相应的结果。
解析JJWS的方法如下:
- 使用该
Jwts.parser()
方法创建JwtParserBuilder
实例。 setSigningKey()
与builder中签名方法signWith()对应,parser中的此方法拥有与signWith()方法相同的三种参数形式,用于设置JWT的签名key,用户后面对JWT进行解析。- 最后,
parseClaimsJws(String)
用您的jws调用该方法,生成原始的JWS。 - 如果解析或签名验证失败,则整个调用将包装在try / catch块中。
@Testpublic void parserJWT(){String JWS = "eyJhbGciOiJIUzI1NiJ9." +"eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM1ODY2fQ." +"ybkDJLVj1Fsi8m3agyxtyd0wxv7lHDqCWNOLN-eOxC8";//claims = 载荷 (payload)try {Claims claims = Jwts.parser().setSigningKey("mashibing").parseClaimsJws(JWS).getBody();System.out.println(claims);} catch (Exception e) {System.out.println("Token验证失败! !");e.printStackTrace();}}
运行打印结果:
{jti=9527, sub=hejiayun_community, iat=1681135866}iat: jwt的签发时间jti: jwt的唯一身份标识,主要用来作为一次性token。sub: jwt所面向的用户
(4) 设置过期时间
有很多时候,我们并不希望签发的token是永久生效的,所以我们可以为token添加一个过期时间。
- 创建token 并设置过期时间
@Testpublic void testJJWT2(){long currentTimeMillis = System.currentTimeMillis();Date expTime = new Date(currentTimeMillis);JwtBuilder builder = Jwts.builder().setId("9527") //设置唯一ID.setSubject("hejiayun_community") //设置主体.setIssuedAt(new Date()) //设置签约时间.setExpiration(expTime) //设置过期时间.signWith(SignatureAlgorithm.HS256, "mashibing");//设置签名 使用HS256算法,并设置SecretKey//压缩成String形式,签名的JWT称为JWSString jws = builder.compact();System.out.println(jws);/*** eyJhbGciOiJIUzI1NiJ9.* eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM3MjI0LCJleHAiOjE2ODExMzcyMjR9.* evc01MRxLjpbksbMLdVPM9sJGYGhpC3UYOfm4-0sMGE */}
- 解析TOKEN
打印效果: 异常信息: JWT签名与本地计算的签名不匹配。JWT有效性不能断言,也不应该被信任Token验证失败! !io.jsonwebtoken.MalformedJwtException: JWT strings must contain exactly 2 period characters. Found:
(5) 自定义claims
我们刚才的例子只是存储了id和subject两个信息,如果你想存储更多的信息(例如角色)可以定义自定义claims。
创建测试类,并设置测试方法:
@Testpublic void testJJWT3(){long currentTimeMillis = System.currentTimeMillis()+100000000L;Date expTime = new Date(currentTimeMillis);JwtBuilder builder = Jwts.builder().setId("9527") //设置唯一ID.setSubject("hejiayun_community") //设置主体.setIssuedAt(new Date()) //设置签约时间.setExpiration(expTime) //设置过期时间.claim("roles","admin") //设置角色.signWith(SignatureAlgorithm.HS256, "mashibing");//设置签名 使用HS256算法,并设置SecretKey//压缩成String形式,签名的JWT称为JWSString jws = builder.compact();System.out.println(jws);/*** eyJhbGciOiJIUzI1NiJ9.* eyJqdGkiOiI5NTI3Iiwic3ViIjoiaGVqaWF5dW5fY29tbXVuaXR5IiwiaWF0IjoxNjgxMTM3MjI0LCJleHAiOjE2ODExMzcyMjR9.* evc01MRxLjpbksbMLdVPM9sJGYGhpC3UYOfm4-0sMGE*/}
解析TOKEN,打印结果
{jti=9527, sub=hejiayun_community, iat=1681137464, exp=1681237464, roles=admin}
7. JWT自定义工具类
/*** JWT工具类*/
public class JwtUtil {//有效期为public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000 一个小时//设置秘钥明文public static final String JWT_KEY = "pan";public static String getUUID(){String token = UUID.randomUUID().toString().replaceAll("-", "");return token;}/*** 生成jtw* @param subject token中要存放的数据(json格式)* @return*/public static String createJWT(String subject) {JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间return builder.compact();}/*** 生成jtw* @param subject token中要存放的数据(json格式)* @param ttlMillis token超时时间* @return*/public static String createJWT(String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间return builder.compact();}private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;SecretKey secretKey = generalKey();long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);if(ttlMillis==null){ttlMillis=JwtUtil.JWT_TTL;}long expMillis = nowMillis + ttlMillis;Date expDate = new Date(expMillis);return Jwts.builder().setId(uuid) //唯一的ID.setSubject(subject) // 主题 可以是JSON数据.setIssuer("sg") // 签发者.setIssuedAt(now) // 签发时间.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥.setExpiration(expDate);}/*** 创建token* @param id* @param subject* @param ttlMillis* @return*/public static String createJWT(String id, String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间return builder.compact();}public static void main(String[] args) throws Exception {String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjYWM2ZDVhZi1mNjVlLTQ0MDAtYjcxMi0zYWEwOGIyOTIwYjQiLCJzdWIiOiJzZyIsImlzcyI6InNnIiwiaWF0IjoxNjM4MTA2NzEyLCJleHAiOjE2MzgxMTAzMTJ9.JVsSbkP94wuczb4QryQbAke3ysBDIL5ou8fWsbt_ebg";Claims claims = parseJWT(token);System.out.println(claims);}/*** 生成加密后的秘钥 secretKey* @return*/public static SecretKey generalKey() {byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}/*** 解析** @param jwt* @return* @throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();}}
相关文章:
JWT使用教程
目录 JWT (JSON Web Token)1. JWT简介(1) 什么是JWT(2) JWT有什么用(3) JWT认证方式 2. JWT的组成部分3. 签名的目的4. JWT与Token的区别5 JWT的优势6 JJWT签发与验证token(1) 引入依赖(2) 创建 Token(3) 解析Token(4) 设置过期时间(5) 自定义claims 7. JWT自定义工具类 JWT (J…...
数据结构——静态顺序表,动态顺序表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使 ⽤的 数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在…...
前端Sass面试题及参考答案
目录 什么是 Sass? Sass 和 CSS 的主要区别是什么? Sass 中如何处理列表? Sass 中如何处理映射(map)? Sass 中如何使用函数? Sass 中如何使用内置函数? Sass 中如何设置默认值? Sass 中的 @function 和 @mixin 有什么区别? Sass 中如何实现模块化? Sass 中…...
ubuntu20.04音频aplay调试
1、使用指定声卡,aplay 播放命令 aplay -D plughw:1,0 test2.wav2、 录音 arecord -Dhw:1,0 -d 10 -f cd -r 44100 -c 2 -t wav test.wav3、各个参数含义 -D 指定声卡编号 plughw:0,0 //0,0代表card0,device0,可以通过arecord -l获取 -f 录音格式 S16_LE…...
比特信噪比与信噪比SNR的换算公式
在无线通信系统中,比特信噪比与信噪比(SNR,通常指符号信噪比Es/N0)的换算: 核心公式 E b N 0 SNR R ⋅ log 2 M \boxed{ \frac{E_b}{N_0} \frac{\text{SNR}}{R \cdot \log_2 M} } N0EbR⋅log2MSNR 或…...
RTSP场景下RTP协议详解及音视频打包全流程
RTSP场景下RTP协议详解及音视频打包全流程 一、RTSP与RTP的关系 RTSP:负责媒体会话控制(DESCRIBE、SETUP、PLAY、PAUSE),通过SDP协商传输参数(端口、编码格式、封装模式)。RTP:实际传输音视频数…...
java练习(39)
ps:题目来自力扣 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以…...
2.24DFS和BFS刷题
洛谷P2895:用BFS走出危险区域,危险区域存在时间,我们用ma记录最快变成危险区域的时间, 然后每次枚举时间1然后跟ma数组比较看能不能走,然后时间复杂度为O(305^2)。 #include<iostream> #include<cstring>…...
基于YOLO11深度学习的运动鞋品牌检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
赛前启航 | 三场重磅直播集结,予力微软 AI 开发者挑战赛!
随着微软 AI 开发者挑战赛的火热进行,赛前指导直播已成为众多参赛者获取技术干货、灵感碰撞和实战技巧的绝佳平台。继前两期的精彩呈现,第三、四、五期直播即将接连登场,为开发者们带来更加深入的 AI 技术剖析和项目实战指引。无论你是想进一…...
MySQL数据库连接池泄露导致MySQL Server超时关闭连接
前言 最近做项目,发现老项目出现xxx,这个错误其实很简单,出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理,因为是druid数据库,且在github也出现这样的issue:The last packet successf…...
Deepseek和Grok 3对比:写一段冒泡排序
1、这是访问Grok 3得到的结果 2、grok3输出的完整代码: def bubble_sort(arr):n len(arr) # 获取数组长度# 外层循环控制排序轮数for i in range(n):# 内层循环比较相邻元素,j的范围逐渐减少for j in range(0, n - i - 1):# 如果当前元素大于下一个元…...
EX_25/2/22
找到第一天mystring练习,实现以下功能 mystring str "hello" mystring ptr "world" str str ptr; str ptr str[0] H #include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #in…...
el-select滚动获取下拉数据;el-select滚动加载
el-select下拉获取数据 1.解决问题2.封装MyScrollSelect组件3.使用MyScrollSelect组件 1.解决问题 场景:下拉数据量过大,后端提供一个分页查询接口;需要每次滚动加载下一页的下拉数据 且单选的状态,需要支持回显,通过n…...
Spring Boot面试题
Spring Boot面试题 基础概念 Q1: Spring Boot的核心特性有哪些? public class SpringBootBasicDemo {// 1. 自动配置SpringBootApplicationpublic class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class…...
STM32-智能小车项目
项目框图 ST-link接线 实物图: 正面: 反面: 相关内容 使用L9110S电机模块 电机驱动模块L9110S详解 | 良许嵌入式 一、让小车动起来 新建文件夹智能小车项目 在里面复制19-串口打印功能 重命名为01-让小车动起来 新建文件夹motor&…...
SAP-ABAP:ABAP第一代增强详解
在SAP ABAP开发中,第一代增强(First-Generation Enhancement) 是早期用于扩展标准程序功能的传统技术,主要通过预定义的增强点(Enhancement Points)实现。以下是详细解析: 一、第一代增强的核心…...
20分钟 Bash 上手指南
文章目录 bash 概念与学习目的第一个 bash 脚本bash 语法变量的使用位置参数管道符号(过滤条件)重定向符号条件测试命令条件语句case 条件分支Arrayfor 循环函数exit 关键字 bash 脚本记录历史命令查询文件分发内容 bash 概念与学习目的 bash࿰…...
地铁站内导航系统:基于蓝牙Beacon与AR技术的动态路径规划技术深度剖析
本文旨在分享一套地铁站内导航系统技术方案,通过蓝牙Beacon技术与AI算法的结合,解决传统导航定位不准确、路径规划不合理等问题,提升乘客出行体验,同时为地铁运营商提供数据支持与增值服务。 如需获取校地铁站内智能导航系统方案文…...
WordPress R+L Carrier Edition sql注入漏洞复现(CVE-2024-13481)(附脚本)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
滴水逆向_引用_友元函数_运算符重载
作业: 运算符号重载实现。 struct Person { public:int x;int y; public:Person(){this->x 10;this->y 20;}Person(int x, int y){this->x x;this->y y;}//申明友元函数void Printf(const Person& p){printf("%d %d",p.x,p.y);}/…...
git中,如何查看具体单个文件的log
在 Git 中,可以使用多种方式查看单个文件的提交日志(Log),以下详细介绍不同场景下的查看方法: 目录 一、基本命令查看文件的完整提交日志 二、查看文件提交日志并显示差异内容 三、限制显示的提交日志数量 四、按…...
如何生成traceid以及可视化展示
根据你的需求,以下是一些可以生成唯一 traceId 并用于分布式链路追踪的工具和项目,这些项目支持生成唯一的 traceId,并将其用于日志记录和分布式追踪: 1. OpenTelemetry OpenTelemetry 是一个开源的观测框架,支持生成…...
2024 ICPC香港站 L.Flipping Paths的一种解法
太变态了,场上被硬控了两个小时,最后20分钟思路熬出来了但是没写对~,糖完了。怎么说呢,香港站这样的轻量级赛站,这次强队也很少,导致很多题目的难度升级了,这道L题是一道银牌题,不少…...
Uniapp 开发中遇到的坑与注意事项:全面指南
文章目录 1. 引言Uniapp 简介开发中的常见问题本文的目标与结构 2. 环境配置与项目初始化环境配置问题解决方案 项目初始化注意事项解决方案 常见错误与解决方案 3. 页面与组件开发页面生命周期注意事项示例代码 组件通信与复用注意事项示例代码 样式与布局问题注意事项示例代码…...
Python - 代码片段分享 - Excel 数据实时写入方法
文章目录 前言注意事项工具 pandas1. 简介2. 安装方式3. 简单介绍几个api 实战片段 - 实时写入Excel文件结束语 要么出众,要么出局 前言 我们在爬虫采集过程中,总是将数据解析抓取后统一写入Excel表格文件,如果在解析数据出现问题容易出现数据…...
一文详解U盘启动UEFI/Legacy方式以及GPT/MBR关系
对于装系统的老手而说一直想研究一下装系统的原理,以及面对一些问题时的解决思路,故对以前的方法进行原理上的解释,主要想理解其底层原理。 引导模式 MBR分区可以同时支持UEFI和Legacy引导,我们可以看一下微pe制作的启动盘&#…...
Java函数式接口的巧妙应用
引言 函数式接口(Functional Interface)是Java 8引入的一个重要概念,它是Lambda表达式和方法引用的基础。通过函数式接口,Java实现了对函数式编程的支持,让代码更加简洁、灵活。本文将带你深入理解函数式接口…...
爱普生SG-8101CE可编程晶振赋能智能手机的精准心脏
在智能手机高速迭代的今天,高性能、低功耗与小型化已成为核心诉求。智能手机作为人们生活中不可或缺的工具,需要在各种复杂场景下稳定运行。爱普生SG-8101CE可编程晶振凭借其卓越性能,成为智能手机中不可或缺的精密时钟源,为通信、…...
条件渲染
当if条件为true则会被显示出来,若为false则不会显示出来。 在App.vue中需要引用一下。 if else一样的if为真则显示if的内容,若不是则显示else下的内容。 多条件判断。 if在为false时,根本不会渲染,而show则会,只不过d…...
sklearn中的决策树-分类树:剪枝参数
剪枝参数 在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优,或者没有更多的特征可用为止。这样的决策树 往往会过拟合。为了让决策树有更好的泛化性,我们要对决策树进行剪枝。剪枝策略对决策树的影响巨大,正确的剪枝策…...
算法随笔_59: 子数组最小乘积的最大值
上一篇:算法随笔_58: 队列中可以看到的人数-CSDN博客 题目描述如下: 一个数组的 最小乘积 定义为这个数组中 最小值 乘以 数组的 和 。 比方说,数组 [3,2,5] (最小值是 2)的最小乘积为 2 * (325) 2 * 10 20 。 给你一个正整数数组 nums …...
线性模型 - 支持向量机延伸
为了更好的理解支持向量机模型,本文我们延伸学习和理解一下和支持向量机相关的一些概念,这些概念都是偏理论和数学的知识,比较抽象和复杂,而且需要一定的高等数学知识。大家可以先明白其所包含的意义,然后逐步深入理解…...
力扣3464. 正方形上的点之间的最大距离
力扣3464. 正方形上的点之间的最大距离 题目 题目解析及思路 题目要求在points集合中找出k个点,k个点之间的最小的曼哈顿距离的最大值 最大最小值的题一般直接想到二分 将正方形往右展开成一条线,此时曼哈顿距离为两点直线距离**(仅起点右边的点)** …...
AI数字人源码搭建部署指南
为实现AI数字人的智能交互功能,需开发包含语音识别、自然语言处理、机器学习等技术的AI算法和模型。利用TensorFlow、PyTorch等深度学习框架完成模型训练。具体步骤包括以下四个方面: 需求分析:通过市场调研、用户访谈、专家咨询等方式&…...
智能拖把控制板开发
智能拖把控制板开发全流程解析 一、硬件架构与H桥驱动设计 工程师小明选用四颗AO3400A低导通电阻MOS管构建H桥驱动拓扑,实测全桥导通电阻仅15mΩ,较传统方案降低40%损耗。通过优化PCB布局将驱动环路电感控制在15nH以内,配合10kHz互补PWM信号…...
【Swift 算法实战】利用 KMP 算法高效求解最短回文串
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
【数字化转型+AI:现代企业腾飞的一对翅膀】
——解析数字时代的核心竞争力 在全球化竞争与技术迭代加速的今天,传统企业若想突破增长瓶颈,必须抓住两大核心驱动力:数字化转型与人工智能(AI)。这两大技术如同企业腾飞的双翼,共同构建敏捷性、创…...
Zabbix——踩坑HttpRequest,header添加无效
背景 在试图尝试通过Zabbix接入DeepSeek API的时候,由于使用了HTTP的方式,所以需要使用Zabbix 自带的HttpRequest库进行请求,产生了下面的问题 问题 curl curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completio…...
MTK Android12 预装apk可卸载
文章目录 需求解决方法1、device/mediatek/mt6761/device.mk2、/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt3、路径:4、Android.mk 需求 近期,客户需要预装一个apk,同时该apk要可卸载。解…...
让网页“浪“起来:打造会呼吸的波浪背景
每次打开那些让人眼前一亮的网页时,你是否有注意到那些看似随波逐流的动态背景?今天咱们不聊高深的技术,就用最朴素的CSS,来解锁这个让页面瞬间鲜活的秘籍。无需JavaScript,不用复杂框架,准备好一杯咖啡&am…...
YOLO11的单独推理程序
YOLO11的单独推理程序,可以实例化加载一次多次推理。 YOLO11的单独推理程序,可以实例化加载一次多次推理。 YOLO11的单独推理程序,可以实例化加载一次多次推理。 YOLO11的单独推理程序,可以实例化加载一次多次推理。 YOLO11的单独推理程序,可以实例化加载一次多次推理…...
代码随想录day21
669.修剪二叉搜索树 //理解修建后重建树的概念 TreeNode* trimBST(TreeNode* root, int low, int high) {if(root nullptr) return nullptr;if(root->val < low){TreeNode* node trimBST(root->right, low, high);return node;}if(root->val > high){TreeNod…...
利用Ai对生成的测试用例进行用例评审
利用AI对生成的测试用例进行用例评审,可以从用例的完整性、有效性、一致性等多个维度展开,借助自然语言处理、机器学习等技术,提高评审效率和准确性。以下为你详细介绍具体方法: 1. 需求匹配度评审 利用自然语言处理(NLP)技术 步骤:首先将软件需求文档和生成的测试用例…...
JAVAweb-JS基本数据类型,变量,DOM,pop,push函数,事件
JavaScript,可以嵌套在静态页面中添加一些动态语言. JavaScript是开发web脚本语言,但也被用到了很多非浏览器环境中,比如node平台 JS可以嵌套在静态页面中可以给静态页面添加一些动态效果(脚本语言),不同浏览器厂商(在浏览器中都有内置解析器解析JS语法) <!DOCTYPE html&g…...
SpringBoot源码解析(十一):准备应用上下文
SpringBoot源码系列文章 SpringBoot源码解析(一):SpringApplication构造方法 SpringBoot源码解析(二):引导上下文DefaultBootstrapContext SpringBoot源码解析(三):启动开始阶段 SpringBoot源码解析(四):解析应用参数args Sp…...
Python CNN基于深度学习的轴承故障智能检测平台
一、 项目概述 本项目旨在利用深度学习技术,构建一个基于Python的轴承故障智能检测平台。该平台能够对轴承的振动信号进行分析,自动识别轴承的健康状态,并判断故障类型,从而实现轴承故障的早期预警和诊断,提高设备的运…...
CCNP知识笔记
路由选路原理 路由信息来源 路由信息怎么来的? 直连路由(C): 通过直连接口UP产生智联路由条目(物理层UP数据链路层UP) 静态路由(S): 通过网络管理员逐条写入的路由条…...
递归树求解递归方程
*递归树是迭代计算模型 *递归树的生成过程与迭代过程一致 *根据递归定义不断扩展递归树,直到边界条件(其值已知) *对递归树产生的所有项求和就是递归方程的解 例一: T(n) 1 n1 T(n) 2T(n/2) n n>1 对于…...
2025年【熔化焊接与热切割】找解析及熔化焊接与热切割模拟试题
在当今工业领域,熔化焊接与热切割技术作为重要的加工手段,广泛应用于各种金属结构的制造与维修中。然而,这些作业过程伴随着高风险,对从业人员的安全知识和技能提出了极高的要求。为了提升相关人员的安全意识和操作技能࿰…...