实现Python+Django+Transformers库中的BertTokenizer和BertModel来进行BERT预训练,并将其应用于商品推荐功能

一、环境安装准备

   #git拉取 bert-base-chinese 文件#创建 虚拟运行环境python -m venv myicrplatenv#刷新source myicrplatenv/bin/activate#python Django 集成nacospip install nacos-sdk-python#安装 Djangopip3 install Django==5.1#安装 pymysql settings.py 里面需要 # 强制用pymysql替代默认的MySQLdb pymysql.install_as_MySQLdb()pip install pymysql# 安装mongopip install djongo pymongopip install transformerspip install torch#安装Daphne: pip install daphne#项目通过 通过 daphne启动daphne icrplat.asgi:application

二、构建项目及app模块

#创建app模块
python3 manage.py startapp cs
icrplat├── README.md
├── cs
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── icrplat
│   ├── __init__.py
│   ├── __pycache__
│   ├── asgi.py
│   ├── common
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── myicrplatenv
│   ├── bin
│   ├── include
│   ├── lib
│   ├── pyvenv.cfg
│   └── share
├── nacos-data
│   └── snapshot
└── templates

三、准备数据mongo

 db.products.insertMany([{'name': '手机', 'description': '最新款智能手机,支持5G网络,高清摄像头'},{'name': '无线耳机', 'description': '降噪无线耳机,蓝牙连接,长续航'},{'name': '智能手表', 'description': '健康监测,运动记录,支持通知提醒'},{'name': '平板电脑', 'description': '轻薄便携,高性能处理器,适合办公和娱乐'},{'name': '笔记本电脑', 'description': '高性能笔记本,适合游戏和设计工作'},{'name': '相机', 'description': '专业级相机,支持4K视频拍摄'},{'name': '耳机', 'description': '高保真音质,舒适佩戴'},{'name': '充电宝', 'description': '大容量充电宝,支持快充'},{'name': '手机壳', 'description': '防摔手机壳,支持多种机型'},{'name': '路由器', 'description': '高速无线路由器,支持千兆网络'},])

四、相关代码

#################################settings.py#######################################from nacos import NacosClientfrom icrplat.common.config.nacos.NacosConfigWatcher import nacos_config_watcherimport pymysql# 强制用pymysql替代默认的MySQLdb
pymysql.install_as_MySQLdb()INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','cs'  #模块app 注入
]# Nacos 配置
NACOS_SERVER = "xx"  # Nacos 服务器地址 ip 换成Nacos对应的IP地址
NACOS_NAMESPACE = "dev"  # Nacos 命名空间
NACOS_GROUP = "MICRO_GROUP"  # Nacos 分组
NACOS_DATA_ID = "aics_config_dev"  # Nacos 配置 ID# 初始化 Nacos 客户端
nacos_client = NacosClient(NACOS_SERVER, namespace=NACOS_NAMESPACE)# 从 Nacos 获取 config配置
nacos_config = nacos_client.get_config(NACOS_DATA_ID, NACOS_GROUP)
# 将 JSON 字符串转换为字典
nacos_config = eval(nacos_config)
print(f"nacos_config: {nacos_config}")#解析 mysql 初始配置
mysql_config = nacos_config.get("mysql", {})
print(f"mysql_config: {mysql_config}")#解析 mongodb 初始配置
mongo_config = nacos_config.get("mongodb",{})
print(f"mongo_config: {mongo_config}")# 配置 MySQL 数据库
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': mysql_config.get("DATABASE_NAME"),'USER': mysql_config.get("DATABASE_USER"),'PASSWORD': mysql_config.get("DATABASE_PASSWORD"),'HOST': mysql_config.get("DATABASE_HOST"),'PORT': mysql_config.get("DATABASE_PORT", "8081"),'OPTIONS': {'charset': 'utf8mb4',  # 支持更广泛的字符集},},'mongodb': {  # MongoDB配置'ENGINE': 'djongo','NAME': mongo_config.get('DB_NAME'),'ENFORCE_SCHEMA': False,'CLIENT': {'host': mongo_config.get('DB_HOST'),'port': int(mongo_config.get('DB_PORT')),'username': mongo_config.get('DB_USERNAME'),'password': mongo_config.get('DB_PASSWORD'),'authSource': mongo_config.get('AUTH_DB_SOURCE'),}}
}
#使用多数据库,需要在 settings.py 中设置数据库路由。
DATABASE_ROUTERS = ['icrpPlat.dbconfig.routers.DatabaseRouter']print(f"更新前 Databases: {DATABASES}")def update_nacos_config(config):"""动态更新 MySQL 配置"""print("收到 Nacos 配置更新通知")print(f"收到更新后 config: {config}")# 使用 json.loads 解析 JSON 字符串  contentconfig_dict = json.loads(config['content'])#获取更新后的 mysql 配置mysql_config = config_dict.get("mysql", {})print(f"更新后 Databases: {mysql_config}")nacos_config_watcher.update_mysql_config(mysql_config)#获取更新后的 elasticsearch 配置mongo_config = config_dict.get("mongodb",{})print(f"更新后 mongodb: {mongo_config}")nacos_config_watcher.update_mongodb_config(mongo_config)# 监听 Nacos 配置变化
nacos_client.add_config_watcher(NACOS_DATA_ID, NACOS_GROUP, update_nacos_config)#########################nacos_config_watcher.py 方法##############################import threadingfrom django.conf import settingsclass NacosConfigWatcher:def __init__(self):# 创建一个锁对象 可以确保在同一时间只有一个线程能够访问某个共享资源,从而避免多线程环境下的数据竞争问题。self.lock = threading.Lock()"""更新myslq 配置with 语句主要用于上下文管理,通常用于处理资源的管理和释放。它的核心作用是确保在代码块执行完毕后,资源能够被正确地关闭或清理,避免资源泄漏。常见的场景包括文件操作、数据库连接、线程锁等。"""def update_mysql_config(self, mysql_config):with self.lock:settings.DATABASES['default'].update({'NAME': mysql_config.get("DATABASE_NAME"),'USER': mysql_config.get("DATABASE_USER"),'PASSWORD': mysql_config.get("DATABASE_PASSWORD"),'HOST': mysql_config.get("DATABASE_HOST"),'PORT': mysql_config.get("DATABASE_PORT", "3306"),})def update_mongodb_config(self, mongo_config):with self.lock:settings.DATABASES['mongodb'].update({'host': mongo_config.get('DB_HOST'),'port': int(mongo_config.get('DB_PORT')),'username': mongo_config.get('DB_USERNAME'),'password': mongo_config.get('DB_PASSWORD'),'authSource': mongo_config.get('AUTH_DB_SOURCE'),})#使用模块级别的单例 可以有多种实现单例的形式
nacos_config_watcher = NacosConfigWatcher()
##################################urls.yml####################################
urlpatterns = [path('admin/', admin.site.urls),path('cs/handleUserRequest',cs_views.handleUserRequest, name='handleUserRequest'),path('cs/getProducts',cs_views.getProducts,name='get_product'),path('cs/getdata',cs_views.getdata,name='get_data')
]
####################################views.py################################
from django.shortcuts import renderimport json
import logging
import torch
from torch.nn.functional import cosine_similarity
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exemptfrom icrplat.common.enum.ResponeCodeEnum import ResponseCodeEnum
from icrplat.common.exception.BusinessException import BusinessException
from icrplat.common.utils.CommonResult import CommonResult
from cs.models import Productsfrom functools import lru_cachefrom icrplat.common.utils.TransformerUtils import TransformerUtils# import os
# os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"# Create your views here.
@csrf_exempt  # 如果需要关闭CSRF验证,可以加上这个装饰器
def handleUserRequest(request):try:if request.method == 'POST':json_data = request.bodydata = json.loads(json_data)# 假设你需要处理的数据结构如下message = data.get('message')logging.info(f"data:{data}")else:raise BusinessException(ResponseCodeEnum.METHOD_ERROR.status_code, ResponseCodeEnum.METHOD_ERROR.status_message)return JsonResponse(CommonResult.success_data(None), json_dumps_params={'ensure_ascii': False})except BusinessException as e:return JsonResponse(CommonResult.error(e.code, e.message), json_dumps_params={'ensure_ascii': False})def getProducts(request):try:if request.method == 'GET':products_mongo = Products.objects.using('mongodb').all()else:raise BusinessException(ResponseCodeEnum.METHOD_ERROR.status_code,ResponseCodeEnum.METHOD_ERROR.status_message)# 将查询结果转化为字典或列表,确保可以被序列化为 JSON# products_data = [{'name': product.name, 'description': product.description} for product in products_mongo]# 使用列表推导式调用 to_dict 方法,将查询结果转化为字典#注意点: 需要通过实例来调用,而不是通过类直接调用products_data = [product.to_dict() for product in products_mongo]return JsonResponse(CommonResult.success_data(products_data), json_dumps_params={'ensure_ascii': False})except BusinessException as e:return JsonResponse(CommonResult.error(e.code, e.message), json_dumps_params={'ensure_ascii': False})@csrf_exempt
def getdata(request):try:if request.method == 'GET':description = request.GET.get("description")if not description:raise BusinessException(ResponseCodeEnum.PARAM_ERROR.status_code, "描述不能为空")products_mongo = Products.objects.using('mongodb').all()products_data = [product.to_dict() for product in products_mongo]# 生成商品嵌入向量product_embeddings = {product['name']: get_cached_bert_embeddings(product['description']) for product in products_data}# 生成用户查询的嵌入向量user_embeddings = get_cached_bert_embeddings(description)# 获取 计算相似度后的结果 商品product_embeddings 向量 用户user_embeddings 向量top_products = TransformerUtils.similarities(product_embeddings,user_embeddings)if not top_products:return JsonResponse({"message": "未找到相关商品"}, json_dumps_params={'ensure_ascii': False})result_with_description = {}for product_name, similarity in top_products.items():product_description = next((product['description'] for product in products_data if product['name'] == product_name),"暂无描述")result_with_description[product_name] = {"相似度": similarity,"描述": product_description}return JsonResponse(CommonResult.success_data(result_with_description), json_dumps_params={'ensure_ascii': False})else:raise BusinessException(ResponseCodeEnum.METHOD_ERROR.status_code,ResponseCodeEnum.METHOD_ERROR.status_message)except BusinessException as e:return JsonResponse(CommonResult.error(e.code, e.message), json_dumps_params={'ensure_ascii': False})"""在代码中使用 get_cached_bert_embeddings 替代 get_bert_embeddings,以减少重复计算。
"""
@lru_cache(maxsize=1000)
def get_cached_bert_embeddings(text):return TransformerUtils.get_bert_embeddings(text)
#################################TransformerUtils.py##########################import loggingfrom transformers import BertTokenizer, BertModel
import torch
from torch.nn.functional import cosine_similarityimport osfrom transformers.utils.hub import TRANSFORMERS_CACHEclass TransformerUtils:"""这个函数的主要功能是通过 BERT 模型生成文本的嵌入向量。如果在加载模型或生成嵌入的过程中遇到任何问题,函数会返回一个默认的零向量,确保程序能够继续运行,而不会因为异常而中断。"""@staticmethoddef get_bert_embeddings(texts):# 输出 BERT 模型的默认缓存路径。通常,预训练模型和分词器会从缓存中加载,以减少重复下载的时间。logging.info(f"Default cache path: {TRANSFORMERS_CACHE}")""" 如果输入的 texts 为空或者不是字符串类型,函数会返回一个长度为 768 的零向量。BERT 模型的嵌入向量通常是 768 维的,所以这里返回一个零向量作为默认值。 0.0返回一个长度为 768 的列表,所有元素均为浮点数 0.0,例如:[0.0, 0.0, ..., 0.0]  # 共768个元素  """if not texts or not isinstance(texts, str):return [0.0] * 768# 指定模型路径path = "/Users/jiajiamao/soft/python/space/bert-base-chinese"logging.info(f"模型路径指定 path:{path}")try:# 检查路径是否存在if not os.path.exists(path):logging.info(f"模型路径 不存在!")# 这里指定了 BERT 模型的路径,并检查该路径是否存在。如果路径不存在,会抛出一个 FileNotFoundError 异常raise FileNotFoundError(f"Model path {path} does not exist.")"""加载分词器:使用 BertTokenizer.from_pretrained 方法加载分词器。输入‌:"高性能"  转变成 [高,性,能]分词器的作用是将输入文本转换为模型能够理解的 token 序列。词向量转换(tokens)  # 转为数字矩阵"""tokenizer = BertTokenizer.from_pretrained(path)logging.info(f"********************加载分词器:Tokenizer loaded successfully")"""加载模型:使用 BertModel.from_pretrained 方法加载 BERT 模型。加载成功后,model 变量将包含预训练的 BERT 模型。"""model = BertModel.from_pretrained(path)logging.info(f"********************加载模型:BertModel loaded successfully")# 确保加载成功if tokenizer is None:raise ValueError("Tokenizer failed to load.")if model is None:raise ValueError("Model failed to load.")"""# 原理实现步骤:# 1. 添加特殊标记 → [CLS] 我 在 学习 BERT 模型 [SEP]# 2. 分词 → ['降', '噪', '无', '线', '耳', '机', ',', '蓝', '牙', '连', '接', ',', '长', '续', '航']# 3. 转换为ID → [ 101, 7360, 1692, 3187, 5296, 5455, 3322, 8024, 5905, 4280, 6825, 2970,#          8024, 7270, 5330, 5661,  102] 方便输入模型"""inputs = tokenizer(texts, return_tensors='pt', max_length=512, truncation=True, padding=True)logging.info(f"********************tokenizer 分词:{tokenizer.tokenize(texts)}")logging.info(f"********************input:{inputs}")"""with torch.no_grad(): 表示在推理过程中不计算梯度,以提高效率。把分好词的句子变成一系列向量,每个词对应一个向量。每句话里的每个词都会得到一个最终的向量表示模型被调用时它会自动执行自注意力机制的计算。BERT由多个Transformer编码层堆叠而成,每一层都包含一个自注意力模块:# 每个词生成3个向量:Q(查询向量):用来询问其他词和它的关系。K(钥匙向量):用来衡量其他词和它的相关性。V(值向量):用来表示这个词的实际内容。# 计算"高"对每个词的关注度:attention_score = Q_高 ⋅ [K_高, K_性, K_能]  # → 得到 [0.8, 0.1, 0.1](更关注自己)用“高”的查询向量(Q_高)去分别与“高”、“性”、“能”的钥匙向量(K_高, K_性, K_能)做点积运算。点积的结果就是注意力分数,比如这里得到 [0.8, 0.1, 0.1]。这表示“高”更关注自己(0.8),而对“性”和“能”的关注度较低。# 加权求和:用注意力分数对“高”、“性”、“能”的值向量(V_高, V_性, V_能)进行加权求和。比如,新的“高”的表示 = 0.8 * V_高 + 0.1 * V_性 + 0.1 * V_能。这个过程的意义在于,通过计算每个词对其他词的关注度,让模型能够更好地理解上下文关系。比如“高”这个词在这里更关注自己,所以它会更多地保留自己的信息,而稍微融入一点“性”和“能”的信息。"""with torch.no_grad():outputs = model(**inputs)"""1.从BERT的输出中提取最后一层的隐藏状态(last_hidden_state)。2.对所有词的向量做平均,得到整个句子的向量表示(mean(dim=1))。3.去掉多余的维度(squeeze())。4.把Tensor转换成NumPy数组(.numpy())。5.最后把数组转换成列表(.tolist())"""embeddings = outputs.last_hidden_state.mean(dim=1).squeeze().numpy().tolist()logging.info(f"********************原内容Text: {texts}")logging.info(f"********************BERT生成一个768维的向量: {embeddings[:10]}")  # 只打印前10维,方便检查return embeddingsexcept Exception as e:print(f"Error in get_bert_embeddings: {e}")return [0.0] * 768  # 出现异常时返回默认值"""计算相似度通过分析用户的兴趣(用户向量)和商品的特点(商品向量),计算它们之间的匹配度。然后根据匹配度排序,筛选出最相关的前 5 个商品。最后,只保留那些匹配度足够高(大于阈值)的商品,确保推荐的内容对用户来说是有意义的。@:param product_embeddings 商品向量 @:param user_embeddings 用户向量"""@staticmethoddef similarities(product_embeddings,user_embeddings):#将用户向量转换为张量形式user_embeds_tensor = torch.tensor(user_embeddings, dtype=torch.float32).unsqueeze(0)# 计算相似度similarities = {}for product_name, embedding in product_embeddings.items():#将商品的向量转换为张量形式,并调整其维度以匹配用户向量的计算product_embeds_tensor = torch.tensor(embedding, dtype=torch.float32).unsqueeze(0)#计算用户向量与商品向量之间的余弦相似度,值范围为 [-1, 1],值越接近 1 表示相似度越高。similarity = cosine_similarity(user_embeds_tensor, product_embeds_tensor).item()#将结果存储在一个字典中,键为商品名称,值为相似度值similarities[product_name] = similarityprint(f"Product: {product_name}, Similarity: {similarity}")# 根据相似度排序(从高到低)sorted_products = sorted(similarities.items(), key=lambda item: item[1], reverse=True)print(f"Sorted Products: {sorted_products}")# 设置相似度阈值,并返回相似度最高的前5个商品(设置阈值并筛选商品)threshold = 0.6top_products = {k: v for k, v in sorted_products[:5] if v > threshold}return top_products
###############################ResponseCodeEnum###############################from enum import Enum"""返回通用响应类
"""
class ResponseCodeEnum(Enum):###################################公共响应#############################SUCCESS = (200, "操作成功!")PARAMS_ERROR = (400, "参数解析失败,请核对参数!")UNAUTHORIZED = (401, "未认证(签名错误)")FORBIDDEN = (402, "请求错误")  # 返回失败业务公共codeMEDIA_TYPE_ERROR = (403, "不支持的媒体异常,请核对contentType!")URL_REQ_NULL = (404, "请求路径不存在")METHOD_ERROR = (405, "不支持当前请求方法,请核对请求方法!")TIMEOUT_EXPIRE_ERROR = (406, "token登录过期!")TOKEN_ILLEGAL = (407, "非法token!")INTERNAL_SERVER_ERROR = (500, "服务器内部错误!")  # 系统异常公共code###################################相关业务返回#############################RESOURCES_IP_EXIST = (1001,"资源IP已存在!")"""在枚举值初始化时,将元组中的code和message分别赋值给实例属性self.code和self.message。这样每个枚举值都有独立的code和message属性。"""def __init__(self, code, message):self.code = codeself.message = message"""@property 是 Python 中用于将类的方法转换为属性访问的装饰器。使用 @property 装饰器,你可以像访问属性一样访问方法,而不需要调用它示例:ResponseCodeEnum.SUCCESS.status_code      """@propertydef status_code(self):return self.code@propertydef status_message(self):return self.message

#####################################CommonResult.py###############################from typing import Any, Optionalfrom icrplat.common.enum.ResponeCodeEnum import ResponseCodeEnumclass CommonResult:""":param res: 类型为 ResponseCodeEnum,用于存储响应状态码和消息:param data: 类型为 Any,用于存储返回的数据:param pagination: 类型为 Optional[dict],是一个可选的参数,用于存储分页信息(默认为 None)"""def __init__(self, res: ResponseCodeEnum, data: Any, pagination: Optional[dict] = None):self.ResponseCodeEnum = ResponseCodeEnumself.data = dataself.pagination = pagination"""这是一个装饰器,用于定义静态方法。静态方法不需要访问类实例(self)或类本身(cls),可以直接通过类名调用。CommonResult.success_pagination"""@staticmethoddef success_pagination(data: Any, pagination: Optional[dict] = None):""":param data: Any: 表示返回的数据,类型为 Any(可以是任意类型)。:param pagination: 表示可选的分页信息,类型为字典(dict),默认值为 None。:return:返回一个字典,包含以下键值对:code: 状态码,取自 ResponseCodeEnum.SUCCESS.status_code。message: 响应消息,取自 ResponseCodeEnum.SUCCESS.message。data: 传入的 data 数据。pagination: 传入的分页信息(如果未传入则为 None)"""return {'code': ResponseCodeEnum.SUCCESS.code,'message': ResponseCodeEnum.SUCCESS.message,'data': data,  # 将 QuerySet 序列化为 JSON,'pagination': pagination}@staticmethoddef success_data(data: Any):return {'code': ResponseCodeEnum.SUCCESS.code,'message': ResponseCodeEnum.SUCCESS.message,'data': data,  # 将 QuerySet 序列化为 JSON,}@staticmethoddef error(code,message):return {'code': code,'message': message}@staticmethoddef error():return {'code':ResponseCodeEnum.INTERNAL_SERVER_ERROR.code,'message':ResponseCodeEnum.INTERNAL_SERVER_ERROR.message}
###############################BusinessException.py###############################class BusinessException(Exception):def __init__(self,message,code):self.message = messageself.code = codesuper().__init__(message)
#####################################Products.py##################################from django.db import models# Create your models here.from django.db import modelsclass Products(models.Model):# 定义 name 字段name = models.CharField(max_length=100)# 定义 description 字段description = models.TextField()class Meta:app_label = 'mongodb'db_table = 'products'  #"""自定义 to_dict 实例方法"""def to_dict(self):"""将模型实例转化为字典"""return {'name': self.name,'description': self.description}

五、nacos配置

#换成自己的地址{"mysql": {"DATABASE_NAME": "micro_aics","DATABASE_USER": "xx","DATABASE_PASSWORD": "xx","DATABASE_HOST": "xx","DATABASE_PORT": "8081"},"mongodb": {"DB_NAME": "action_log","DB_HOST": "xx","DB_PORT": "xx","DB_USERNAME": "xx","DB_PASSWORD": "xx","AUTH_DB_SOURCE": "xx"}
}

六、启动项目

#通过 daphne 启动应用
daphne icrplat.asgi:application

七、测试

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/24862.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rk3568驱动开发_点亮led灯代码完善(手动挡)_6

1.实现思路: 应用层打开设备后通过write函数向内核中写值,1代表要打开灯,0代表要关闭灯 Linux配置gpio和控制gpio多了一个虚拟内存映射操作 2.注意事项: 配置和读写操作的时候要谨慎,比如先关掉gpio再注销掉虚拟内存…

线性回归(一)基于Scikit-Learn的简单线性回归

主要参考学习资料: 《机器学习算法的数学解析与Python实现》莫凡 著 前置知识:线性代数-Python 目录 问题背景数学模型假设函数损失函数优化方法训练步骤 代码实现特点 问题背景 回归问题是一类预测连续值的问题,满足这样要求的数学模型称作…

P10108 [GESP202312 六级] 闯关游戏

题目大意 如题 分析 设最佳通关方案为 { s 1 , s 2 , . . . , s k } \{s_1,s_2,...,s_k\} {s1​,s2​,...,sk​},其中 s i s_i si​ 代表第 i i i 次到达的关卡( ≥ N \ge N ≥N 的不算)。 当 a k N − 1 a_kN-1 ak​N−1 时&#…

vllm的使用方式,入门教程

vLLM是一个由伯克利大学LMSYS组织开源的大语言模型推理框架,旨在提升实时场景下的大语言模型服务的吞吐与内存使用效率。以下是详细的vLLM使用方式和入门教程: 1. 前期准备 在开始使用vLLM之前,建议先掌握一些基础知识,包括操作…

web的分离不分离:前后端分离与不分离全面分析

让我们一起走向未来 🎓作者简介:全栈领域优质创作者 🌐个人主页:百锦再新空间代码工作室 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[1504566…

HDFS扩缩容及数据迁移

1.黑白名单机制 在HDFS中可以通过黑名单、白名单机制进行节点管理,决定数据可以复制/不可以复制到哪些节点。 黑名单通常是指在HDFS中被标记为不可用或不可访问的节点列表,这些节点可能由于硬件故障、网络问题或其他原因而暂时或永久性地无法使用。当一…

数据如何安全“过桥”?分类分级与风险评估,守护数据流通安全

信息化高速发展,数据已成为企业的核心资产,驱动着业务决策、创新与市场竞争力。随着数据开发利用不断深入,常态化的数据流通不仅促进了信息的快速传递与共享,还能帮助企业快速响应市场变化,把握商业机遇,实…

[Web 安全] PHP 反序列化漏洞 —— PHP 序列化 反序列化

关注这个专栏的其他相关笔记:[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01:PHP 序列化 — Serialize 序列化就是将对象的状态信息转化为可以存储或传输的形式的过程,在 PHP 中,通常使用 serialize() 函数来完成序列化的操作…

DeepSeek-R1:模型部署与应用实践

深入探索DeepSeek-R1:模型部署与应用实践 在当今人工智能飞速发展的时代,大语言模型(LLMs)已经成为众多领域的核心驱动力。DeepSeek-R1作为一款备受瞩目的模型,在自然语言处理任务中展现出了强大的能力。本文将深入探…

Java 大视界 -- 基于 Java 的大数据机器学习模型压缩与部署优化(99)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

socket编程详解

TCP报文格式 0. 举例 首先来看一个TCP连接的例子,如图1所示,分别给出了服务器和客户端所调用的API,对这些函数有一个总体认识之后,再逐个对每个函数详细介绍。 图1 创建TCP连接时服务器、客户端调用的API 1. socket() 注&#xf…

企业知识库搭建:14款开源与免费系统选择

本文介绍了以下14 款知识库管理系统:1.Worktile;2.PingCode;3.石墨文档; 4. 语雀; 5. 有道云笔记; 6. Bitrix24; 7. Logseq等。 在如今的数字化时代,企业和团队面临着越来越多的信息…

Spring Cloud Alibaba学习 3- Sentinel入门使用

Spring Cloud Alibaba学习 3- Sentinel入门使用 中文文档参考:Sentinel中文文档 一. SpringCloud整合Sentinel 1.1 下载Sentinel-Dashboard Sentinel下载地址:Sentinel-Dashboard 到下载目录,cmd输入 java -jar sentinel-dashboard-1.8…

STM32——HAL库开发笔记23(定时器4—输入捕获)(参考来源:b站铁头山羊)

定时器有四个通道,这些通道既可以用来作为输入,又可以作为输出。做输入的时候,可以使用定时器对外部输入的信号的时间参数进行测量;做输出的时候,可以使用定时器向外输出精确定时的方波信号。 一、输入捕获 的基本原理…

Spring MVC框架六:Ajax技术

精心整理了最新的面试资料,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 简介 jQuery.ajax Ajax原理 结语 创作不易,希望能对大家给予帮助 想要获取更多资源? 点击链接获取

通过返回的key值匹配字典中的value值

需求 页面中上面搜索项有获取字典枚举接口,table表格中也有根据key匹配字典中的value 方案一 需要做到的要求 这里上面下拉列表是一个组件获取的字典,下面也是通过字典匹配,所以尽量统一封装一个函数,每个组件保证最少变动tabl…

Python游戏编程之赛车游戏6-2

3.2 move()方法的定义 Player类的move()方法用于玩家控制汽车左右移动,当玩家点击键盘上的左右按键时,汽车会相应地进行左右移动。 move()方法的代码如图7所示。 图7 move()方法的代码 其中,第20行代码通过pygame.key.get_pressed()函数获…

通俗易懂:RustDesk Server的搭建及使用

最近有很多远程桌面连接的需求,使用花生壳、topdesk等现有的远程控制又有数量上的限制,因此利用公司现有的具有固定IP地址的服务器,搭建了一台 RustDesk Server来解决工作中的痛点。 结论是丝毫不输哪些收费的软件,不论是剪切板、…

SQL注入练习

目录 一、如何绕过 information schema 字段过滤注入 二、如何绕过 order by 语句过滤注入 三、seacmsv9 实现报错注入数据 一、如何绕过 information schema 字段过滤注入 1、使用其他系统表,不同数据库有各自的系统表,可替代information_schema。 …

手机放兜里,支付宝“碰一下”被盗刷?

大家好,我是小悟。 近期,网络上关于“支付宝‘碰一下’支付易被盗刷”的传言甚嚣尘上,不少用户对此心生疑虑。 首先,要明确一点:“碰一下”支付并不会像某些传言中所描述的那样容易被隔空盗刷。这一观点已经得到了支付…