Python 框架学习 Django篇 (五) Session与Token认证
我们前面经过数据库的学习已经基本了解了怎么接受前端发过来的请求,并处理后返回数据实现了一个基本的登录登出效果,但是存在一个问题,我们是将所有的请求都直接处理了,并没有去检查是否为已经登录的管理员发送的,如果是这样的话客户端可以不选择登录直接去访问主页文件,那么登录就毫无意义了。 所以我们要在处理前端请求前先去判断这个请求的合法性,通常的两种方案就是session 和token
一、session方案
1、session原理
session 表示会话的意思,Django在服务端在数据库中保存一张session表
这个表中记录了用户登录的信息,具体的信息各个系统都略有不同,大致都会有id、姓名、登录名称之类的,在下图中我们可以看到存储着session_key(会话ID) 、session_data (会话数据)可以发现sessionid 通常就是 一串字符串 用来标记一个session的。 而session对应的数据在这里是加密的,通过这张表,服务端 可以根据 session号(通常叫session ID) 查到 session 的信息数据。
每当用户成功登录之后,服务端都会往数据库表session中记录一条数据,也就是创建一个新的会话id写入数据表,同时也 放入一些 该session对应的数据到 记录的数据字段中,比如登录用户 的 信息。然后在该登录请求的HTTP响应消息中, 的头字段 Set-Cookie 里填入 sessionid 数据
添加输出响应头
vi Django_demo/mgr/sign_in_out.py
import requests,pprintpayload = {'username': 'root','password': '12345678'
}response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)pprint.pprint(response.json())#输出相应头
for header, value in response.headers.items():print(f'{header}: {value}')
返回
{'ret': 0}
Date: Fri, 20 Oct 2023 05:58:54 GMT
Server: WSGIServer/0.2 CPython/3.9.13
Content-Type: application/json
Content-Length: 10
Vary: Cookie
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Set-Cookie: sessionid=otfwixmjgfngfc45n8k6efobiff4f3xs;
expires=Fri, 03 Nov 2023 05:58:53 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax#这一行
Set-Cookie: sessionid=otfwixmjgfngfc45n8k6efobiff4f3xs;
根据http协议, 这个Set-Cookie字段的意思就是 要求前端将其中的数据存入 cookie中。 并且随后访问该服务端的时候, 在HTTP请求消息中必须带上 这些 cookie数据
cookie 通常就是存储在客户端浏览器的一些数据。 服务端可以通过http响应消息 要求 浏览器存储 一些数据。以后每次访问同一个网站服务, 必须在HTTP请求中再带上这些cookie里面的数据。
cookie数据组成如下
sessionid=6qu1cuk8cxvtf4w9rjxeppexh2izy0hh
username=byhy
favorite=phone_laptop_watch
该用户的后续操作只要出发http请求, 都会在请求头的Cookie字段添加上面说的sessionID,服务端接受到请求后,只需要到session表中查看是否有该sessionID对应的记录,这样就可以判断这个请求前面是已经登录过,如果不是就可以拒绝服务,重定向http请求到登录页面让用户登录
2、添加主页请求限制
在一开始的登录函数中我们调用了一个函数request.session['usertype'] = 'mgr'
这行代码的作用 就是在登录认证后,将 用户类型保存到session数据中, 也就是存入前面数据库的那张图的 会话数据记录中,Django 框架 会自动在 HTTP 响应消息头中 加入 类似刚才说的sessionid cookie
Set-Cookie: sessionid=otfwixmjgfngfc45n8k6efobiff4f3xs;
所以我们处理开通的
/api/mgr
需要验证请求的cookie里面是否有sessionid,并且检查session表,看看是否存在session_key为该sessionid 的一条记录,该记录的数据字典里面是否 包含了 usertype 为 mgr 的 数据,我们可以把前面数据库增删改查视为我们的主页,只需要从主页函数调用之前去做下检查即可
vi Django_demo/mgr/k8s.py
def dispatcher(request): # 将请求参数统一放入request 的 params 属性中,方便后续处理# 根据session判断用户是否是登录的管理员用户if 'usertype' not in request.session:return JsonResponse({'ret': 302,'msg': '未登录','redirect': '/mgr/sign.html'},status=302)if request.session['usertype'] != 'mgr' :return JsonResponse({'ret': 302,'msg': '用户非mgr类型','redirect': '/mgr/sign.html'} ,status=302)...
3、测试访问
http://127.0.0.1:8000/api/mgr/customers/?action=list_customer
可以看到,尝试直接访问后端信息时因为找不到登录时携带的会话id则不运行登录
4、修改测试方法
我们修改一下请求方法,先发送登录请求然后将相应头中的Set-Cookie取出,在发起访问时在请求头中携带获取到的Cookie去请求就能正常访问了
vi main.py
import requests,pprintpayload = {'username': 'root','password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)#拿到请求请求响应头中的值
set_cookie = response.headers.get('Set-Cookie')
if set_cookie:# 将Set-Cookie字段的值添加到请求头中headers = {'Cookie': set_cookie}# 发送带有Cookie的新请求response = requests.get('http://127.0.0.1:8000/api/mgr/customers/?action=list_customer',headers=headers)pprint.pprint(response.json())
返回
{'ret': 0,'retlist': [{'ClusterName': 'acp-r1-1','NodeSum': '100','PrometheusAddress': '192.168.1.1','id': 1},{'ClusterName': '123123','NodeSum': '123123','PrometheusAddress': '123123','id': 2},{'ClusterName': 'gfs-r3-1','NodeSum': '5000','PrometheusAddress': '192.168.1.21','id': 3}]}
二、Token方案
1、session 缺点
1、性能问题 #验证请求是根据sessionid 到数据库中查找session表的#而数据库操作是服务端常见的性能瓶颈,尤其是当用户量比较大的时候2、扩展性问题 #当系统用户特别多的时候,后端处理请求的服务端通常是部署在多个节点上#但是多个节点都要访问session表,这样就要求数据库服务能够被多个节点访问#不方便切分数据库以提高性能。
token 简单来说,就是包含了数据信息和校验信息的数据包 ,Session 机制是把 数据信息(比如session表)放到 服务端,服务端数据是客户无法篡改的,从而保证验证的 可靠性,而 token机制 数据信息 直接传给 客户端,客户每次请求再携带过来给服务端。服务端无需查找数据库,直接根据token里面的数据信息进行校验
但是上面的方法存在一个问题,假设我是普通用户,那天我获取到了一个vip用户的token,拿是不是我就能访问vip用户的权限了,为了防止
2、token机制说明
1、服务端先创建了一个密钥文件(secret key)2、用户登录成功后,服务端会将"用户的信息数据"和"密钥"一起进行一个哈希计算从而得到一个哈希值首先为了哈希算法保证一致性,只能根据同样的数据源获取,如果有人修改了用户信息成其他人的除非他也拿到了密钥, 不然他即使再用哈希算法计算也不会得到我们认证的token值, 所以这个哈希值就方便我们用来做数据校验当我们拿到了这个独一无二的哈希值后,将哈希值和用户数据再做成一个字符串这个字符串也就被称之为token,token里面包含了用户数据和数据校验的哈希值服务端接受到请求后返回token值,通常来说token是放在http响应头部中的, 具体那个头部字段没有规定,可以自定义 3、用户的后续操作如果除非http api请求则会在请求消息中带上token值服务端接收到请求后,会根据数据信息和密钥使用哈希再次生成哈希值,如果用户修改了数据因为不知道密钥没有办法得到正确的新的哈希值,那么服务端根据篡改后的数据和密钥得到的新的哈希值一定不同就知道数据被修改了如果客户端没有修改数据,服务端根据原来的数据加上密钥得到的哈希值与保存在otken中的哈希值一对比,校验通过后就知道没有被修改,可以放心使用token中的用户数据了
三、实现token认证
1、安装库
pip install djangorestframework==3.14.0
pip install djangorestframework-simplejwt
2、加载库配置
vi Django_demo/Django_demo/settings.py
INSTALLED_APPS = ['simpleui','django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','paas','mgr',#添加下面的配置'rest_framework','rest_framework.authtoken','rest_framework_simplejwt.token_blacklist',
]
3、添加全局配置
vi Django_demo/Django_demo/settings.py
#找个空地方直接贴上,其中包含了认证方式和Token的过期时间等
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication', # 使用Token进行身份验证],'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated', # 需要进行身份验证的默认权限类],'DEFAULT_THROTTLE_RATES': {'user': '100/day', # 每个用户每天最多可以进行100次请求'anon': '10/day' # 匿名用户每天最多可以进行10次请求},'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer', # 默认使用JSON渲染器来渲染响应],'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser', # 默认使用JSON解析器来解析请求数据],'DEFAULT_METADATA_CLASS':'rest_framework.metadata.SimpleMetadata', # 默认使用简单元数据类'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', # 使用URL路径版本控制'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend' # 默认使用Django Filter后端来进行过滤],'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination', # 默认的分页类为PageNumberPagination'PAGE_SIZE': 10, # 默认的每页返回的对象数量为10'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle', # 默认使用匿名速率限制类'rest_framework.throttling.UserRateThrottle' # 默认使用用户速率限制类],'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', # 默认使用AutoSchema来生成API文档'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'rest_framework.negotiation.DefaultContentNegotiation', # 默认使用DefaultContentNegotiation进行内容协商'COERCE_DECIMAL_TO_STRING': False, # 数字类型是否强制转换为字符串'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S', # 默认的日期时间格式'DATETIME_INPUT_FORMATS': ['%Y-%m-%d %H:%M:%S','%Y-%m-%d %H:%M','%Y-%m-%d','%Y%m%dT%H%M%S%fz'], # 接受的日期时间输入格式的列表'UNICODE_JSON': False, # 是否使用Unicode编码的JSON
}
我们设置了TokenAuthentication作为默认的认证方式,同时设置了IsAuthenticated权限,表示只有已认证用户才能访问
4、同步库数据库操作
python manage.py makemigrations
python manage.py migrate
5、注释前面session认证
我们先将之前写的session判断给注释掉
vi Django_demo/mgr/k8s.py
# 根据session判断用户是否是登录的管理员用户if 'usertype' not in request.session:return JsonResponse({'ret': 302,'msg': '未登录','redirect': '/mgr/sign.html'},status=302)if request.session['usertype'] != 'mgr' :return JsonResponse({'ret': 302,'msg': '用户非mgr类型','redirect': '/mgr/sign.html'} ,status=302)
此时我们访问查询应该就可以直接访问通了
http://127.0.0.1:8000/api/mgr/customers/?action=list_customer
6、开启主页函数token验证
vi Django_demo/mgr/k8s.py
#导入模块
from rest_framework.authentication import TokenAuthentication # 导入TokenAuthentication类,用于基于令牌进行身份验证
from rest_framework.permissions import IsAuthenticated # 导入IsAuthenticated类,用于检查用户是否已通过身份验证的权限
from rest_framework.decorators import api_view, permission_classes, authentication_classes # 导入装饰器函数,用于设置视图函数的身份验证和权限控制#添加装饰器
@api_view(['GET'])
@authentication_classes([TokenAuthentication]) # 使用TokenAuthentication类进行身份验证
@permission_classes([IsAuthenticated]) # 要求用户已通过身份验证
def dispatcher(request): ...
http://127.0.0.1:8000/api/mgr/customers/?action=list_customer
我们需要让应用登录成功后获取到一个token值,这里的token我们通过直接取用户
(下面是说明代码不执行)
from rest_framework.authtoken.models import Token # 导入 Token 模型,用于创建和管理用户的 Token
from django.contrib.auth.models import User # 导入 User 模型,用于获取用户对象# 获取用户
user = User.objects.get(username='root') # 根据用户名获取用户对象# 创建 Token
token, created = Token.objects.get_or_create(user=user) # 创建或获取与用户关联的 Token
7、登录函数添加token获取
在登录函数,登录成功之后添加一个获取登录用户token的值,并跟随相应头返回token
Django_demo/mgr/sign_in_out.py
def signin( request):userName = request.POST.get('username')passWord = request.POST.get('password')user = authenticate(username=userName, password=passWord)if user is not None:if user.is_active:if user.is_superuser:login(request, user)request.session['usertype'] = 'mgr'#添加返回用户的tokenfrom rest_framework.authtoken.models import Tokenfrom django.contrib.auth.models import Useruser = User.objects.get(username=userName)# 创建或获取 Tokentoken, created = Token.objects.get_or_create(user=user)return JsonResponse({'token': str(token), 'ret': 0})else:return JsonResponse({'ret': 1, 'msg': '请使用管理员账户登录'})else:return JsonResponse({'ret': 0, 'msg': '用户已经被禁用'})# 否则就是用户名、密码有误else:return JsonResponse({'ret': 1, 'msg': '用户名或者密码错误'})
8、测试检查是否返回token值
vi main.py
import requests,pprintpayload = {'username': 'root','password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
print(response.headers.get('Authorization'))
返回
Token 1568e26d12af8a5a6489603763e662cf0c65c73a
9、携带token值请求主页
vi main.py
import requests,pprintpayload = {'username': 'root','password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
token = response.headers.get('Authorization')#携带token请求
if token:# 将Set-Cookie字段的值添加到请求头中headers = {'Authorization': f'{token}'}response = requests.get('http://127.0.0.1:8000/api/mgr/customers/?action=list_customer',headers=headers)pprint.pprint(response.json())
返回
{'ret': 0,'retlist': [{'ClusterName': 'acp-r1-1','NodeSum': '100','PrometheusAddress': '192.168.1.1','id': 1},{'ClusterName': '123123','NodeSum': '123123','PrometheusAddress': '123123','id': 2},{'ClusterName': 'gfs-r3-1','NodeSum': '5000','PrometheusAddress': '192.168.1.21','id': 3}]}
10、数据库内的token查询
牌(Token)在Django Rest Framework中是使用默认的Authentication模块提供的,它默认存储在数据库中,并且没有过期时间。这意味着一旦生成并分配给用户,Token将一直有效,直到被明确删除。
存储Token的数据库表是
authtoken_token
,在数据库中的位置取决于你的Django项目的数据库配置。默认情况下,Token会与用户相关联,并且将存储在
Token
模型的user
字段中。每个用户可以有多个Token,因此可以在这个模型上执行标准的查询操作如果你希望对Token设置过期时间,或者有更高级的需求,你可以考虑使用第三方库,如
django-rest-framework-simplejwt
。这个库提供了JWT(JSON Web Token)认证,可以根据特定的配置设置Token的过期时间和其他功能。
四、session和token的区别详解
1、存储位置
Token:Token通常存储在服务器端的数据库中,或者可以存储在客户端的cookie或本地存储中。每次发起请求时,Token将通过请求头或请求参数进行传递。Session:Session通常存储在服务器端的数据库或缓存中。服务器将为每个会话分配一个唯一的Session ID,并将Session ID存储在客户端的cookie中。客户端在发送请求时会自动携带Session ID。
2、无状态性
Token Token是无状态的,服务器不需要在后端存储任何关于用户会话的状态信息。每个请求都包含所有必要的信息(通常是在Token本身中)来进行身份验证和授权。Session:Session是有状态的,服务器需要在后端存储有关用户会话的状态信息。客户端的每个请求都需要携带Session ID,服务器根据Session ID检索并验证对应的会话状态。
3、扩展性和跨域支持
Token 由于Token是无状态的,因此易于扩展和支持跨域请求。服务器不需要存储每个用户的会话状态,因此可以更好地支持负载均衡和分布式系统。Session 由于Session是有状态的,需要在服务器端存储状态信息,因此在处理大量并发请求或跨域请求时可能存在一些挑战。
4、过期和失效机制
Token Token可以通过设置过期时间来自动失效,或者可以通过撤销Token的方式来手动使其失效。客户端需要负责在失效前获取新的Token。Session Session可以通过设置过期时间来自动失效,但服务器也可以更主动地管理会话状态例如在用户注销或一段时间内无活动后自动销毁会话。
总结
Token适用于无状态、扩展性要求高、移动应用程序的场景,而Session适用于有状态、需要跟踪用户会话状态的场景
相关文章:

Python 框架学习 Django篇 (五) Session与Token认证
我们前面经过数据库的学习已经基本了解了怎么接受前端发过来的请求,并处理后返回数据实现了一个基本的登录登出效果,但是存在一个问题,我们是将所有的请求都直接处理了,并没有去检查是否为已经登录的管理员发送的,如果…...

cocos creator 小游戏允许他人访问本地项目
需求背景: 发版成微信小游戏前,需要策划介入体验。不上传微信体验版本 实现: 1.发布平台选择web桌面端 2.构建完成后点击运行从浏览器上获取本地的运行地址 3.winR ——》 cmd 控制台 输入 ipconfig 找到IPv4地址,替换本地部分 …...

分布式存储 vs. 全闪集中式存储:金融数据仓库场景下的性能对比
作者:深耕行业的 SmartX 金融团队 张德敏 近年来随着金融行业的高速发展,经营决策者及监管机构对信息时效性的要求越来越高,科技部门面临诸多挑战。例如,不少金融机构使用数仓业务系统,为公司高层提供日常经营报表&am…...

RHCE---搭建博客网站
一.实验要求: Server-NFS-DNS主机配置NFS服务器,将博客网站资源文件共享给Server-web主机,Server-NFS-DNS主机配置DNS Server-web主机配置web服务,通过域名www.openlab.com可以访问到自建的博客网站 二.准备工作 创建两台虚拟机…...

Spring中方法拦截器
一、MethodInterceptor 在动态代理中要想添加一个额外功能,只要去实现MethodBeforeAdvice这个接口就行了,但是实现了这个接口的额外功能只能运行在目标类执行之前,如果是想在目标类执行之后呢?那这个需求就完成不了,所…...

【网络】HTTPS讲解(侧重于加密、秘钥、证书的讲解)
HTTPS讲解 前言正式开始安全HTTP和HTTPS的关系什么是加密和解密为什么要加密运营商劫持中间人 常⻅的加密⽅式对称加密⾮对称加密 数据摘要数字签名HTTPS 的⼯作过程⽅案 1 - 只使⽤对称加密(不可靠)⽅案 2 - 只使⽤⾮对称加密(不可靠&#x…...
absolute 定位
关于CSS的一些学习记录 absolute定位类型 语法staticrelative 相对定位absolute 绝对定位fixed 固定定位stick 粘性定位 absolute CSS postion属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则决定了该元素的最终位置。 定位类型 定位元素是其计算后…...

比亚迪、吉利、蔚来等将出席2023第四届中国新能源汽车热管理峰会
会议背景 2023第四届中国新能源汽车热管理创新国际峰会将于11月16日-17日在上海举办。会议线上线下同步举行,会场提供中英同声传译。 本次峰会将密切关注“双碳”目标下中国新能源汽车一体化热管理的最新行业动态与关键技术的研发和应用方案。会议将对中国新能源汽…...

OJ第五篇
文章目录 用队列实现栈用栈实现队列设计循环队列 用队列实现栈 链接:用队列实现栈 这道题是让我们用两个队列实现一个栈,简单来说,就是利用队列来实现一个先入后出的功能,我们知道队列是先入先出,如何用两个队列来实…...

【论文解读】Parameter-Efficient Transfer Learning for NLP
一. 介绍 1.1 为什么要引入Adapter 在存在许多下游任务的情况下,微调的参数效率很低:每个任务都需要一个全新的模型。作为替代方案,我们建议使用适配器模块进行传输。 1.2 论文目标 目标是建立一个在所有这些方面都表现良好的系统,但不需…...

星途星纪元 ES,用艺术思维表达工程技术
10月8日,星途星纪元ES携手世界级成都爱乐首席乐团、旅德青年钢琴家王超,在成都打造了一场“万物星声”超舒适音乐会视听盛宴。这是星途星纪元首次跨界音乐圈、牵手音乐挚友,共同演绎音乐和汽车的美学协奏曲,开启高端超舒适美学新纪…...

【Java 进阶篇】深入了解 Bootstrap 插件
Bootstrap 是一个流行的前端框架,提供了各种强大的插件,用于增强网页和应用程序的功能和交互性。本篇博客将深入介绍 Bootstrap 插件,适用于那些刚刚开始学习前端开发的小白。 什么是 Bootstrap? 在深入探讨 Bootstrap 插件之前…...

VMware17.0安装教程(2023最新最详细)
目录 一.简介 二.安装步骤 软件:VMware版本:17.0语言:简体中文大小:554.98M安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.6GHz 内存4G(或更高)下载通道①百度网盘丨下载链接: htt…...

k8s----11、service
services 1、概述2、存在的意义2.1 服务发现2.2 负载均衡 3、pod与service的关系4、service 三种类型4.1 、 ClusterIP4.2 、NodePort4.3 、LoadBalancer 1、概述 Service 是 Kubernetes 最核心概念,通过创建 Service,可以为一组具有相同功能的容器应 用提供一个统…...

深入篇【Linux】学习必备:进程环境变量/进程切换
深入篇【Linux】学习必备:进程环境变量/进程切换 Ⅰ.环境变量Ⅱ.深层意义Ⅲ.全局属性Ⅳ.进程切换 Ⅰ.环境变量 1.环境变量是什么?:环境变量是系统提供的一组name/value形式的变量,不同的环境变量有不同的用户。 一般是用来指定操作…...

文件系统相关
文件系统部分的大纲要求: 文件系统的全局结构:文件系统在外存中的结构,文件系统在内存中的结构外存空闲空间管理办法虚拟文件系统文件系统挂载 一、文件系统的层次结构 可分为三个层次:最低层是对象及其属性,中间层…...
edm邮件开发信模板
现在很多从事外贸的工作人员在寻找一些邮件模板,今天一米软件给大家总结了几套常用的开发新客户的邮件模板 开发新模板1: Hi Sir, Glad to hear that youre on the market for **. We specialize in this field for several years, with the strengt…...
边缘服务器的未来是什么?思考 5G 和 AI 需求
什么是边缘服务器 边缘服务器是一种分布式计算模式,旨在提高数据中心和云服务的效率,并解决设备之间通信的延迟问题。它将业务从中央数据中心转移到边缘设备附近,将计算、存储和网络资源靠近终端用户和设备,以实现更快速的数据处…...
老卫带你学---leetcode刷题(438. 找到字符串中所有字母异位词)
438. 找到字符串中所有字母异位词 问题: 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。 …...

unity中使用protobuf工具将proto文件转为C#实体脚本
unity中使用protobuf工具将proto文件转为C#实体脚本 介绍优点缺点Protobuf 为什么比 XML 快得多?Protobuf的EncodingProtobuf封解包的过程通常编写一个Google Protocol Buffer应用需要以下几步: Protostuff是什么Protobuf工具总结 介绍 protobuf也就是G…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...

ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...

MLP实战二:MLP 实现图像数字多分类
任务 实战(二):MLP 实现图像多分类 基于 mnist 数据集,建立 mlp 模型,实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入,可视化图形数字; 2、完成数据预处理:图像数据维度转换与…...
Vue 实例的数据对象详解
Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...