构建个人大模型问答助手(基于Streamlit +gpt-4o/o1-mini):全面解析与实现
在当今人工智能迅猛发展的时代,构建一个个人化的大模型问答助手不仅能够提高工作效率,还能为日常生活带来便利。本篇博客将详细解析如何使用Python和Streamlit框架,结合OpenAI的API,搭建一个类似于ChatGPT的问答系统。我们将分步骤介绍代码实现,同时确保敏感信息的安全性。
基于ManyiAPI聚合接口站:https://api.manyi88.top, ManyiAPI注册链接(注册优惠) 可以直接调用国内外语言大模型,实现自己的问答助手,效果如图:
项目代码地址:
https://gitcode.com/sequoia00/appChat_streamlit/overview
目录
- 项目概述
- 环境准备
- 代码实现详解
- 导入必要的库
- API密钥与模型配置
- 界面构建
- 数据管理
- 历史记录管理
- 聊天功能实现
- 辅助功能
- 安全性与隐私保护
- 总结
- 参考资料
项目概述
本项目旨在通过Python和Streamlit框架,结合OpenAI的API,构建一个个人化的问答助手。该助手允许用户选择不同的语言模型,与之进行对话,同时管理聊天历史记录,实现保存、加载、备份和删除功能。通过这一项目,用户可以体验到类似于ChatGPT的对话体验,并根据需求进行定制。
环境准备
在开始编码之前,确保你的开发环境中已经安装了以下软件和库:
- Python 3.7+
- Streamlit:用于构建Web应用的框架。
- OpenAI Python SDK:用于与OpenAI的API进行交互。
- 其他辅助库:如
json
,os
,glob
,re
,shutil
等。
可以使用以下命令安装必要的库:
pip install streamlit openai
代码实现详解
下面,我们将对整个代码进行逐段详细解析,帮助读者深入理解每一部分的功能与实现。
导入必要的库
from openai import OpenAI
import streamlit as st
import json
import os
import glob
import re
import shutil # 用于文件移动
解析:
这些库为项目提供了必要的功能支持:
- openai:与OpenAI API交互。
- streamlit:构建用户界面。
- json:处理JSON数据格式。
- os, glob, re, shutil:文件和目录管理。
API密钥与模型配置
# 示例:模型和相应的 API 密钥
default_key = "sk-***" # 默认令牌
sale_key = "sk-***" # 自定义默认1.0
guan_key = "sk-***" # 管转令牌3倍
az_key = "sk-***" # 纯AZ,1.5倍
claude_key = "sk-***" # claude 8倍
guan5_key = "sk-***" # 管转令牌5倍model_keys = {"gpt-4o-mini-2024-07-18": az_key, #1.5"o1-mini": guan5_key, #3"gpt-4o-2024-08-06": az_key,"claude-3-5-sonnet-20240620": claude_key
}
解析:
- API密钥管理:为不同的模型配置不同的API密钥,以实现对不同服务的调用和控制。
- 模型选择:通过
model_keys
字典,将模型名称与对应的API密钥关联,方便用户在界面上选择。
安全建议:
将API密钥硬编码在代码中存在安全风险。建议使用环境变量或配置文件来存储这些密钥,并在代码中通过读取环境变量的方式获取,以避免泄露风险。
界面构建
为了方便调用模型,可以访问ManyiAPI聚合接口站:https://api.manyi88.top, ManyiAPI注册链接(注册优惠)
st.title("ChatGPT-like Clone")
selected_model = st.sidebar.selectbox("选择模型", list(model_keys.keys()))
api_key = model_keys[selected_model]
api_url = "https://api.manyi88.top/v1" #ManyiAPI聚合接口站:https://api.manyi88.topclient = OpenAI(api_key=api_key, base_url=api_url)
解析:
- 标题设置:通过
st.title
函数设置应用的标题。 - 模型选择:在侧边栏提供一个下拉菜单,用户可以选择不同的模型。
- API客户端初始化:根据用户选择的模型,获取对应的API密钥和API URL,初始化OpenAI客户端。
数据管理
data_dir = "data"
backup_dir = "data_bak"
if not os.path.exists(data_dir):os.makedirs(data_dir)
if not os.path.exists(backup_dir):os.makedirs(backup_dir)
解析:
- 数据目录:
data_dir
用于存储聊天记录。 - 备份目录:
backup_dir
用于备份历史聊天记录。 - 目录检查与创建:如果目录不存在,自动创建,确保文件操作的顺利进行。
会话ID管理
session_id_file = os.path.join(data_dir, "session_id.txt")def load_session_id():if os.path.exists(session_id_file):with open(session_id_file, "r") as f:return int(f.read().strip())return 0def save_session_id(session_id):with open(session_id_file, "w") as f:f.write(str(session_id))
解析:
- 会话ID文件:用于存储当前会话的ID。
- 加载会话ID:如果文件存在,读取当前的会话ID;否则,初始化为0。
- 保存会话ID:在新会话开始时,将会话ID保存到文件中,确保会话的持续性和唯一性。
历史记录管理
加载历史记录
def load_history(file_path):match = re.search(r'chat_history_(\\d+)\\.json', os.path.basename(file_path))if match:st.session_state.session_id = int(match.group(1))with open(file_path, "r") as f:st.session_state.messages = json.load(f)
解析:
- 文件名匹配:通过正则表达式提取会话ID。
- 加载消息:从JSON文件中读取聊天记录,更新会话状态。
加载最新历史
def load_latest_history():history_files = sorted(glob.glob(os.path.join(data_dir, "*.json")), key=os.path.getmtime)if history_files:latest_file = history_files[-1]load_history(latest_file)
解析:
- 获取所有历史文件:使用
glob
获取data_dir
目录下所有JSON文件。 - 排序与加载:按修改时间排序,加载最新的聊天记录。
聊天记录展示
def get_chat_title(messages):if messages:first_message = messages[0]["content"]title = first_message if first_message else "空的聊天"return title[:12]return "空的聊天"[:12]
解析:
- 标题生成:根据聊天记录的第一条消息生成聊天标题,截取前12个字符。
历史文件展示与管理
def show_history_files(page=0, page_size=10):history_files = [(f, os.path.getmtime(f)) for f in glob.glob(os.path.join(data_dir, "*.json"))]history_files.sort(key=lambda x: x[1], reverse=True)total_files = len(history_files)total_pages = (total_files // page_size) + (1 if total_files % page_size > 0 else 0)start = page * page_sizeend = start + page_sizedisplay_files = history_files[start:end]with st.sidebar.expander("历史聊天记录"):for index, (file_path, _) in enumerate(display_files):with open(file_path, "r") as f:chat_history = json.load(f)file_name = get_chat_title(chat_history)col1, col2, col3 = st.sidebar.columns([4, 1, 1]) # 创建三列with col1:if st.button(file_name, key=f"load_{index}"):load_history(file_path)st.rerun()with col2:if st.button("📦", key=f"move_{index}", help="移动到备份文件夹"):move_history(file_path)st.success(f"{file_name} 已移动到备份。")st.rerun()with col3:if st.button("❌", key=f"delete_{index}", help="删除"):delete_history(file_path)st.success(f"{file_name} 已删除。")st.rerun()# 分页if page > 0:if st.button("上一页"):st.session_state.current_page -= 1st.rerun()if page < total_pages - 1:if st.button("下一页"):st.session_state.current_page += 1st.rerun()
解析:
- 文件排序:按修改时间降序排列聊天记录文件。
- 分页展示:每页显示10个文件,提供“上一页”和“下一页”按钮进行导航。
- 文件操作:
- 加载:点击文件名按钮加载对应的聊天记录。
- 移动:将文件移动到备份文件夹。
- 删除:删除指定的聊天记录文件。
聊天界面与输入
for message in st.session_state.messages:with st.chat_message(message["role"]):st.markdown(message["content"])output_mode = st.sidebar.selectbox("选择输出模式", ["流式输出 (Stream)", "非流式输出 (Non-stream)"])
解析:
- 消息展示:遍历
st.session_state.messages
,根据消息角色(用户或助手)展示对应内容。 - 输出模式选择:用户可选择使用流式输出(即时显示)或非流式输出(一次性显示)的模式。
历史数量选择
# 初始化 session_state 中的历史数量
if "history_count" not in st.session_state:st.session_state.history_count = 0# 在侧边栏添加滑动条
if len(st.session_state.messages) == 0:max_history_count = 10
else:max_history_count = len(st.session_state.messages)st.sidebar.slider("选择使用的历史消息数量(共" + str(len(st.session_state.messages)) + "条)",min_value=0,max_value=max_history_count,value=st.session_state.history_count, # 默认值key="history_count" # 使用一个唯一的键来存储选择值
)# 显示当前选择的历史消息数量
st.sidebar.write(f"您选择的历史消息数量是: {st.session_state.history_count}")
解析:
- 历史消息数量选择:通过滑动条让用户选择使用的历史消息数量,以影响生成新回复时的上下文范围。
- 默认值与限制:如果当前无消息,最大历史数量设为10;否则,最大值为现有消息数量。
聊天输入与响应
prompt = st.chat_input("What is up?")
if prompt:st.session_state.messages.append({"role": "user", "content": prompt})with st.chat_message("user"):st.markdown(prompt)with st.chat_message("assistant"):client.api_key = model_keys[selected_model]stream = output_mode == "流式输出 (Stream)"try:if st.session_state.history_count > 0:messages_to_send = ([{"role": m["role"], "content": m["content"]}for m in st.session_state.messages[-st.session_state.history_count:]])else:messages_to_send = [{"role": "user", "content": prompt}]res = client.chat.completions.create(model=selected_model,messages=messages_to_send,stream=stream,)if stream:assistant_message = st.write_stream(res)if assistant_message:st.session_state.messages.append({"role": "assistant", "content": assistant_message})else:st.warning("收到空响应。")else: if len(res.choices) > 0:assistant_message = res.choices[0].message.contentif assistant_message:st.markdown(assistant_message)st.session_state.messages.append({"role": "assistant", "content": assistant_message})else:st.warning("收到空响应。")else:st.warning("响应格式不正确,未找到有效消息。")save_history()except Exception as e:st.error(f"发生错误:{e}")
解析:
-
用户输入:
- 获取用户通过
st.chat_input
输入的文本。 - 将用户消息添加到
st.session_state.messages
中,并在界面上展示。
- 获取用户通过
-
助手响应:
- 根据用户选择的输出模式,设置是否采用流式输出。
- 构建发送给API的消息列表:
- 如果选择使用历史消息,则提取最新的
history_count
条消息。 - 否则,仅发送当前的用户输入。
- 如果选择使用历史消息,则提取最新的
- 调用OpenAI API生成回应:
- 流式输出:逐步显示助手的回复。
- 非流式输出:一次性显示完整的回复。
- 将助手的回复添加到
st.session_state.messages
中,并保存聊天记录。
-
错误处理:
- 捕获并显示在请求过程中发生的任何异常,确保用户能够及时了解问题。
辅助功能实现
新建聊天会话
st.sidebar.header("操作")
if st.sidebar.button("New Chat"):st.session_state.messages = [] # 清空当前会话st.session_state.session_id = load_session_id()st.session_state.session_id += 1save_session_id(st.session_state.session_id)st.success("当前会话已清空。")
解析:
- 按钮功能:点击“New Chat”按钮,清空当前的聊天记录,并生成一个新的会话ID。
- 状态更新:更新
st.session_state.messages
和st.session_state.session_id
,并提示用户会话已重置。
历史对话展示
st.sidebar.header("历史对话")
show_history_files(st.session_state.current_page)
解析:
- 展示历史对话:调用之前定义的
show_history_files
函数,在侧边栏展示历史聊天记录,并提供相应的管理操作(加载、移动、删除)。
安全性与隐私保护
在构建和部署个人问答助手时,安全性和隐私保护至关重要。以下是一些关键点:
-
API密钥管理:
- 避免硬编码:API密钥不应直接写在代码中,尤其是在版本控制系统中。
- 使用环境变量:推荐将密钥存储在环境变量中,通过代码读取,增强安全性。
import os api_key = os.getenv("OPENAI_API_KEY")
- 配置文件:另一个选择是使用配置文件,将敏感信息存储在外部配置文件中,并在
.gitignore
中排除该文件。
-
数据存储:
- 加密:敏感的聊天记录应进行加密存储,防止未经授权的访问。
- 访问控制:确保只有授权用户能够访问和操作聊天记录。
-
错误处理:
- 详细信息:在生产环境中,不应向用户展示过于详细的错误信息,以防泄露系统内部信息。
- 日志记录:将错误信息记录在安全的日志系统中,便于后续分析。
-
用户隐私:
- 数据最小化:仅收集和存储必要的用户数据,避免冗余信息的存储。
- 用户同意:在收集和使用用户数据前,需获得用户明确的同意,并提供隐私政策说明。
总结
本文详细介绍了如何使用Python和Streamlit框架,结合OpenAI的API,构建一个个人化的大模型问答助手。从环境准备、代码结构解析到具体实现步骤,我们逐步解析了每一部分的功能与实现细节。同时,强调了在开发过程中需注意的安全性与隐私保护措施,确保项目的稳健和可靠性。
通过这一项目,读者不仅可以学习到如何搭建一个高效的问答系统,还能深入理解如何管理API密钥、处理数据存储以及实现用户界面交互。希望本篇博客能为您的AI项目提供有价值的参考和指导。
参考资料
- ManyiAPI注册链接(注册优惠)
- Streamlit 官方文档
- OpenAI API 文档
- Python 官方文档
注意事项
感谢您的阅读和支持。在代码实施过程中,请务必确保API密钥和其他敏感信息的安全,避免意外泄露。如发现密钥泄露,请立即撤销并生成新的密钥,以保障您的账户安全。
相关文章:
构建个人大模型问答助手(基于Streamlit +gpt-4o/o1-mini):全面解析与实现
在当今人工智能迅猛发展的时代,构建一个个人化的大模型问答助手不仅能够提高工作效率,还能为日常生活带来便利。本篇博客将详细解析如何使用Python和Streamlit框架,结合OpenAI的API,搭建一个类似于ChatGPT的问答系统。我们将分步骤…...
10.请求拦截和响应拦截
文章目录 前言前景回顾拦截器应用请求拦截器响应拦截器测试响应拦截器原理 总结 前言 优秀的设计总是少不了丰富的扩展点, 比如spring可以自动装配, aop扩展, web模块也有拦截器, 甚至对servlet的过滤器都有封装; 再比如netty、doubbo等等都支持在数据流入流出都允许用户自定义…...
github使用SSH进行克隆仓库
SSH 密钥拉取git 查询密钥是否存在 s -al ~/.ssh这个文件夹下 known_hosts 就是存在的密钥文件 创建密钥文件 ssh-keygen -t rsa -b 4096 -C "testtt.com"-t rsa 是 rsa 算法加密 -b 是指定密钥的长度(以位为单位)。 -C 是用于给密钥添加注…...
如何成长为一名工程技术经理
https://medium.com/srivatsan-sridharan/how-to-grow-as-an-engineering-manager-687cad0bcac7 作为一名工程技术经理,你可能已经积累了丰富的团队管理经验,并展示了出色的项目管理、优先级管理和员工指导能力。然而,尽管如此,你…...
前端热门面试题目(四五六七)
1. 使用 import 时,Webpack 如何处理 node_modules 中的依赖? 依赖解析: Webpack 遇到 import 时,利用 resolve 配置查找依赖。如果是第三方依赖(node_modules),Webpack 会优先查找其主入口&…...
三、使用 Maven:命令行环境
文章目录 1. 第一节 实验一:根据坐标创建 Maven 工程1.1 Maven 核心概念:坐标1.2 实验操作1.3 Maven核心概念:POM1.4 Maven核心概念:约定的目录结构 2. 实验二:在 Maven 工程中编写代码2.1 主体程序2.2 测试程序 3. 执…...
深度学习在网络管理中的应用:智能化的新时代
网络管理在现代信息技术中占据着举足轻重的地位。随着网络规模的扩大和复杂性的增加,传统的网络管理手段已经无法满足日益增长的需求。深度学习作为人工智能的一个重要分支,通过其强大的数据处理和模式识别能力,为网络管理带来了新的契机。本…...
微信小程序日期格式化报错: iOS 下无法正常使用,iOS 只支持 “yyyy/MM/dd“、“yyyy/MM/dd HH:mm:ss“、“yyyy-
微信小程序日期格式化报错 报错内容解决办法 报错内容 at formatDate (http://127.0.0.1:10118/appservice-hotreload/pages/index/index.js?1;:103:18) new Date(“2024-11-27 15:05:23”) 在部分 iOS 下无法正常使用,iOS 只支持 “yyyy/MM/dd”、“yyyy/MM/dd H…...
第K大数求解方案
思想:利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况: 1. Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数…...
【AI系统】MobileFormer
MobileFormer 在本文中,将介绍一种新的网络-MobileFormer,它实现了 Transformer 全局特征与 CNN 局部特征的融合,在较低的成本内,创造一个高效的网络。通过本节,让大家去了解如何将 CNN 与 Transformer 更好的结合起来…...
《重生之我学VTK》-- 基本介绍与相关概念
目录 简介 可视化模型 示例(圆锥体) VTK官方用户手册(中文C版)附末尾,有需要的直接划到末尾 简介 VTK(Visualization Toolkit)是一个开源的、跨平台的软件系统,主要用于三维计算机图…...
HTML笔记()蜘蛛纸牌之卡牌拖拽
效果 代码 <!DOCTYPE html> <html><head><style>body{display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #2b2b2b;position: relative;}.card{/*设置卡牌的外观*/width: 150px;height: 200px;background-…...
记一次跑前端老项目的问题
记一次跑前端老项目的问题 一、前言二、过程1、下载依赖2、启动项目3、打包 一、前言 在一次跑前端老项目的时候,遇到了一些坑,这里记录一下。 二、过程 1、下载依赖 使用 npm install下载很久,然后给我报了个错 core-js2.6.12: core-js…...
041_Compare_Matrix_Squre_Sum_in_MATLAB中矩阵平方和的比较
矩阵平方和的计算 矩阵平方和的定义 矩阵平方和的定义是对矩阵中的每一个元素进行平方,然后求和。 对于一个矩阵 A A A,其平方和定义为: sum ∑ i 1 m ∑ j 1 n A ( i , j ) 2 \text{sum} \sum_{i1}^{m}\sum_{j1}^{n} A(i,j)^2 sumi1∑…...
vue3中 axios 发送请求 刷新token 封装axios
service.js 页面 import axios from axios // 创建axios实例 const instance axios.create({baseURL: http://gcm-test.jhzhkj.cn:8600/h5card/,timeout: 5000, // 请求超时时间headers: {get: {Content-Type: application/x-www-form-urlencoded},post: {Content-Type: appl…...
vue+mars3d叠加展示arcgis动态服务
数据格式:使用arcgis发布的动态服务 叠加和移除arcgis服务图层的方法 //加载arcgis地图服务function arcgisServer(i,d,m,p){i[d.data] new mars3d.layer.ArcGisLayer({name:d.label,url:p,flyTo: true})m.addLayer(i[d.data])}//移除arcgis服务范围线function rem…...
PostgreSQL 中进行数据导入和导出
在数据库管理中,数据的导入和导出是非常常见的操作。特别是在 PostgreSQL 中,提供了多种工具和方法来实现数据的有效管理。无论是备份数据,还是将数据迁移到其他数据库,或是进行数据分析,掌握数据导入和导出的技巧都是…...
Stable Audio Open模型部署教程:用AI打造独家节拍,让声音焕发新活力!
Stable Audio Open 是一个开源的文本到音频模型,允许用户从简单的文本提示中生成长达 47 秒的高质量音频数据。该模型非常适合创建鼓点、乐器即兴演奏、环境声音、拟音录音和其他用于音乐制作和声音设计的音频样本。用户还可以根据他们的自定义音频数据微调模型&…...
python更新程序并部署服务器服务
本地客户端程序 import json import hashlib import os import shutil import requests from pathlib import Pathclass AutoUpdater:def __init__(self, config_path"http://【XXXIP地址】/update_config"):self.config_path config_pathself.config Nonewith op…...
Nmap 扫描技巧:自定义端口、扫描速度与并行化设置
Nmap 扫描技巧:自定义端口、扫描速度与并行化设置 在进行网络安全扫描时,Nmap 是一个非常强大的工具。除了默认扫描 1000 个端口外,你还可以根据需要自定义扫描的端口、调整扫描速度以及优化扫描并行化。今天,我们就来介绍如何通…...
从 HTML 到 CSS:开启网页样式之旅(五)—— CSS盒子模型
从 HTML 到 CSS:开启网页样式之旅(五)—— CSS盒子模型 前言一、盒子模型的组成margin(外边距):border(边框):padding(内边距):conten…...
Linux命令行下载工具
1. curl 1.1. 介绍 curl是一个功能强大的命令行工具,用于在各种网络协议下传输数据。它支持多种协议,包括但不限于 HTTP、HTTPS、FTP、FTPS、SCP、SFTP、SMTP、POP3、IMAP 等,这使得它在网络数据交互场景中有广泛的应用。curl可以模拟浏览器…...
Navicat 连接 SQL Server 详尽指南
Navicat 是一款功能强大的数据库管理工具,它提供了直观的图形界面,使用户能够轻松地管理和操作各种类型的数据库,包括 SQL Server。本文将详尽介绍如何使用 Navicat 连接到 SQL Server 数据库,包括安装设置、连接配置、常见问题排…...
黑马JavaWeb-day06、07、08(SQL部分) _
文章目录 MYSQL概述数据模型SQL简介SQL分类 DDL数据库操作表操作 DML增(INSERT)改(UPDATE)删(DELETE) DQL基本查询条件查询(where)分组查询(group by)排序查询…...
Redis(1)
Redis是一个在内存中存储数据的中间件。 1.在内存中存储数据。 通过数据结构来存储,mysql通过表的方式存储数据,是关系型数据库,redis通过键值对存储,key的类型是string,value的类型是非关系型数据库。 2.可编程的 …...
工具类-列表请求工具 useList
useList 用于列表请求的基于 vue 3 的 hooks,接收请求函数、请求参数等数据,自动生成请求请求函数,分页信息等 本文有涉及到 http 请求工具和接口返回格式的内容: http 工具:一个基于 axios 封装的请求工具Response…...
5G终端自动拔号脚本
5G终端自动拔号脚本 5G终端自动拔号脚本 5G终端自动拔号脚本, 先进入飞行模式,再切出飞行模式, 最后 查询UE IP地址 5G终端自动拔号脚本 input$1 if [ "$input"x "1"x ]; then cmdatcfun1echo "start dialing &…...
3-1 C指针与数组
前言: 基于本人回顾与思考,仅供学习参考 1.0 数组名称的用途 注:可以用于求数组占用的内存空间:sizeof(arrName);此时数组名称代表整个数组 int32 t buffer[5] {1,2,3,4,5};int32 t size sizeof(buffer);printf("sizeof(buffer) %d.\…...
swift 屏幕录制
步骤 1:导入 ReplayKit import ReplayKit步骤 2:开始录屏 let screenRecorder RPScreenRecorder.shared() // 麦克风或系统音频 screenRecorder.isMicrophoneEnabled truefunc startRecording() {guard screenRecorder.isAvailable else {print(&quo…...
Graphviz 的详细介绍
Graphviz 的详细介绍 Graphviz 是一个开源的图形可视化软件,专门用于生成结构化图形。它特别适合用于表示关系图、流程图、依赖关系图和树状结构等类型的图表。Graphviz 使用一种名为 DOT 的脚本语言描述图形,通过解析 DOT 文件生成图像。 Graphviz 的特…...
前端工程化
文章目录 前端工程化模块化与组件化代码规范与风格统一自动化构建与部署性能优化版本控制与团队协作自动化测试 前端工程化 前端工程化是一种将软件工程的方法应用于前端开发的过程,旨在提高开发效率、降低维护成本、优化代码质量,并支持团队协作。以下…...
【LC】41. 缺失的第一个正数
题目描述: 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1: 输入:nums [1,2,0] 输出:3 解释:范围…...
高频面试题(含笔试高频算法整理)基本总结回顾29
干货分享,感谢您的阅读! (暂存篇---后续会删除,完整版和持续更新见高频面试题基本总结回顾(含笔试高频算法整理)) 备注:引用请标注出处,同时存在的问题请在相关博客留言…...
Hive 的 Hook 机制 完全解析
Hive 的 Hook 是一种扩展机制,允许用户在执行查询时自定义行为,例如日志记录、审计或其他操作。Hook 通常在 Hive 的生命周期中某些关键节点被触发,开发者可以插入自定义代码执行特定任务。 一、Hook 的用途和核心概念 1. 用途 审计&#x…...
远程debug
这里写自定义目录标题 一、首先配置idea二、配置jvm1、将刚才idea生成的jvm指令复制下来,就是如下内容(注意要从你的idea中复制)2、在粘贴之前,要拼接上java-jar命令,还有servery,suspendy命令,最后拼接项目…...
一些常见网络安全术语
1、黑帽 为非法目的进行黑客攻击的人,通常是为了经济利益。他们进入安全网络以销毁,赎回,修改或窃取数据,或使网络无法用于授权用户。这个名字来源于这样一个事实:老式的黑白西部电影中的恶棍很容易被电影观众识别&…...
golang学习,小结
切片 切片,底层就是数组,len(切片的长度)和cap(容量,切片的空间) 从一个数组来得到切片,修改切片会修改原来的数组,数据会收到影响 我们可以通过内置的 append 函数对一…...
【C++ map和set】数据的吟游诗:Map与Set的双城记
公主请阅 set1.序列式容器和关联式容器2.set的介绍3.set的构造和迭代器部分set可以进行去重操作的,在去重的同时可以对插入进来的数字进行排序的操作4.set的增删查inserterasefindupper_bound和 lower_bound 5.multiset和set的差异6相关题目349.两个数组的交集142.环…...
leetcode 之 二分查找(java)(3)
文章目录 5. 81. 搜索旋转排序数组 II6. 378、有序矩阵中第k个小的元素 5. 81. 搜索旋转排序数组 II 题目描述: 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。 在传递给函数之前,nums 在预先未知的某个下标 k&#…...
后端返回前端的数据量过大解决方案
后端返回前端的数据量过大解决方案 性能面板(Performance) chrome调试指南 原因 遇到一个页面有好几个表格,部分表格采用虚拟滚动条 数据量有点大 接近快60s了,看一下是哪里导致的慢 后台请求方法执行并不慢 2024-12-04 15:21:52.889 INFO 69948 …...
STL算法之其它算法_下
random_shuffle 这个算法将[first,last)的元素次序随机排列。也就说,在N!中可能的元素排列中随机选出一种,此处N为last-first。 N个元素的序列,其排列方式为N!中,random_shuffle会产生一个均匀分布,因此任何一个排列被…...
MySQL如何区分幻读和不可重复读
在MySQL中,幻读和不可重复读都是并发事务中可能出现的问题,但它们的表现和原因略有不同。 不可重复读 (Non-Repeatable Read) 不可重复读是指在同一个事务内,多次读取同一行数据时,可能会得到不同的结果。这种情况发生在一个事务…...
html ul li 首页渲染多条数据 但只展示八条,其余的数据全部隐藏,通过icon图标 进行展示
<div style"float: left;" id"showMore"> 展开 </div> <div style"float: left;“id"hideLess"> 收起 </div> var data document.querySelectorAll(.allbox .item h3 a); const list document.querySelectorAl…...
Vue3安装 运行教程
本文是综合了所有vue安装教程而成 更细化 更简略 希望对各位读者有所帮助! Vue安装 1. Vue-cli脚手架安装 安装vue的方式有很多 我们这里选择npm方式安装vue npm方式 npm方式安装vue,详细介绍见下文。 1.node.js安装和配置 安装npm 需要安装note.js&…...
Spring事务的一道面试题
每次聊起Spring事务,好像很熟悉,又好像很陌生。本篇通过一道面试题和一些实践,来拆解几个Spring事务的常见坑点。 原理 Spring事务的原理是:通过AOP切面的方式实现的,也就是通过代理模式去实现事务增强。 具体过程是&a…...
PHP SM4 加密
PHP SM4 加密 sm4基类 class Sm4 {private $ck [0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,0xc0c7ced5, 0xdce3ea…...
群控系统服务端开发模式-应用开发-短信工厂腾讯云短信开发
一、腾讯云短信工厂开发 1、添加框架对应的SDK composer require tencentcloud/tencentcloud-sdk-php 2、添加腾讯云工厂 在根目录下extend文件夹下Sms文件夹下channel文件夹下,创建腾讯云短信发送工厂并命名为TencentSmsSender。记住,一定要在腾讯云短…...
vue key属性强制刷新组件
在 Vue 中,key 属性通常用来帮助 Vue 跟踪每个组件或元素的身份,尤其是在使用 v-for 渲染列表时。当 key 值发生变化时,Vue 会销毁并重新渲染组件,这也可以用于强制刷新组件。 如果你想强制刷新一个组件,可以通过动态…...
浪潮X86服务器NF5280、8480、5468、5270使用inter VROC Raid key给NVME磁盘做阵列
浪潮服务器inter VROC Raid key给NVME磁盘做阵列方法 Inter VROC技术简介Raid Key 授权,即VROC SKU兼容性处理器兼容性列表平台和芯片组兼容性列表各Raid级别最大磁盘数量硬盘型号操作系统 服务器上的操作安装Raid Key确认服务器能识别硬盘识别磁盘所在的通道及服务…...
最长最短单词
最长最短单词 C语言实现C实现Java实现Python实现 💐The Begin💐点点关注,收藏不迷路💐 输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一…...