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

Vanna + qwq32b 实现 text2SQL

Vanna 是一个开源的 Text-2-SQL 框架,主要用于通过自然语言生成 SQL 查询,它基于 RAG(Retrieval-Augmented Generation,检索增强生成)技术。Vanna 的核心功能是通过训练一个模型(基于数据库的元数据和用户提供的上下文),然后让用户通过自然语言提问来生成对应的 SQL 查询。它支持多种数据库和前端界面。

 

理解 Vanna 的工作原理

 

功能依赖于:

  • 训练阶段: 输入数据库的 DDL(表结构定义)、文档或已有 SQL 查询,生成向量嵌入存储到向量数据库(如 ChromaDB)。
  • 推理阶段: 用户输入自然语言问题,Vanna 从向量数据库检索相关上下文,结合 LLM 生成 SQL 查询。

工作流程

Vanna 的运行可以分为以下步骤:

  1. 初始化和连接数据库
    • 通过 vn.connect_to_sqlite(db_path)(或其他数据库连接方法)连接到目标数据库。
    • 这允许 Vanna 了解数据库的实际结构和数据。
  2. 训练(Training)
    • DDL 训练
      • 使用 vn.train(ddl=...) 输入数据库表结构(如 CREATE TABLE users (...)),让 Vanna 理解表的列名、类型等。
    • SQL 示例训练
      • 使用 vn.train(sql=...) 输入示例 SQL 查询(如 SELECT name, age FROM users WHERE age > 30),教 Vanna 如何将问题映射到 SQL。
    • 文档训练(可选)
      • 可输入额外文档(如业务规则),增强上下文理解。
    • 训练数据被向量化并存储在向量数据库中,形成知识库。
  3. 问题处理(Query Processing)
    • 用户输入自然语言问题(例如 "列出所有年龄超过30岁的用户")。
    • Vanna 将问题向量化,通过向量搜索从训练数据中检索相关上下文(如 DDL 和示例 SQL)。
    • 检索到的上下文与用户问题一起组成提示(prompt),传递给 LLM。
  4. SQL 生成(SQL Generation)
    • LLM 根据提示生成 SQL 查询。
    • 在我们的代码中,submit_prompt 增强了提示(如 "Generate a SQLite query for: ..."),明确要求返回 SQL。
    • 生成的响应可能包含多余内容,需清理(如提取从 "SELECT" 开始的部分)

关键机制

  • 向量搜索
    • 使用 ChromaDB 等向量存储,通过嵌入相似性快速匹配用户问题与训练数据。
    • 例如,问题 "列出年龄大于30的用户" 会匹配训练中的 SELECT ... WHERE age > 30。
  • 提示工程(Prompt Engineering)
    • 通过精心设计的提示,将问题、表结构和期望输出格式提供给 LLM。
    • 例如:f"Generate a SQLite query for: {prompt}\nSchema: {ddl}\nReturn only the SQL."
  • 模型推理
    • LLM(本地 qwq_32B 或远程 GPT)根据训练数据和提示推理出 SQL。
    • 本地模型可能需要量化(如 4-bit)或 CPU Offloading 以适配硬件。

动手尝试

准备点测试数据

# 初始化 SQLite 数据库
def init_sqlite_db():db_path = "/opt/chenrui/my_database.db"conn = sqlite3.connect(db_path)cursor = conn.cursor()cursor.execute("""CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER)""")cursor.execute("INSERT OR IGNORE INTO users (id, name, age) VALUES (1, 'Alice', 25)")cursor.execute("INSERT OR IGNORE INTO users (id, name, age) VALUES (2, 'Bob', 35)")conn.commit()conn.close()logger.info(f"SQLite 数据库已创建并初始化: {db_path}")return db_path

pip install vanna 安装下该组件

def setup_vanna(db_path):vn = MyVanna()vn.connect_to_sqlite(db_path)# 添加更多训练数据vn.train(ddl="""CREATE TABLE users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER)""")vn.train(sql="SELECT name, age FROM users WHERE age > 30")logger.info("Vanna 初始化完成并添加了 DDL 和 SQL 示例训练数据")return vn

构建下MyVanna对象,它包含向量数据库和LLM, 在提供ddl和sql做为训练数据

 

代码如下

import sqlite3
import streamlit as st
from vanna.chromadb import ChromaDB_VectorStore
from vanna.base import VannaBase
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import logging# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)# 查看 SQLite 数据库结构和数据
def show_db_structure(db_path):conn = sqlite3.connect(db_path)cursor = conn.cursor()cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")tables = cursor.fetchall()st.write("数据库中的表:", tables)cursor.execute("PRAGMA table_info(users);")schema = cursor.fetchall()st.write("users 表结构:")st.table(schema)cursor.execute("SELECT * FROM users;")data = cursor.fetchall()st.write("users 表数据:")st.table(data)conn.close()logger.info("数据库结构和数据已显示")# 自定义本地 qwq_32B 的 LLM 类
class Qwq32bLLM(VannaBase):def __init__(self, config=None):super().__init__(config)model_path = "./base_model/qwq_32b"self.tokenizer = AutoTokenizer.from_pretrained(model_path)self.model = AutoModelForCausalLM.from_pretrained(model_path)self.generator = pipeline("text-generation", model=self.model, tokenizer=self.tokenizer, device=-1)logger.info("qwq_32B 模型已加载")def generate(self, prompt):response = self.generator(prompt, max_length=500, num_return_sequences=1)[0]['generated_text']logger.info(f"生成响应: {response}")return responsedef submit_prompt(self, prompt, **kwargs):logger.info(f"提交提示: {prompt}")return self.generate(prompt)def system_message(self, message):return f"System: {message}"def user_message(self, message):return f"User: {message}"def assistant_message(self, message):return f"Assistant: {message}"# 定义自定义 Vanna 类
class MyVanna(ChromaDB_VectorStore, Qwq32bLLM):def __init__(self, config=None):ChromaDB_VectorStore.__init__(self, config=config)Qwq32bLLM.__init__(self, config=config)# 使用 Streamlit 的缓存机制初始化 Vanna
@st.cache_resource(ttl=3600)
def setup_vanna(db_path):vn = MyVanna()vn.connect_to_sqlite(db_path)vn.train(ddl="""CREATE TABLE users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER)""")logger.info("Vanna 初始化完成并训练了 DDL")return vn# 主程序
def main():db_path = init_sqlite_db()vn = setup_vanna(db_path)st.title("本地 Vanna Seq2SQL 示例")st.subheader("SQLite 数据库结构和数据")show_db_structure(db_path)question = st.text_input("请输入问题(例如:列出所有年龄超过30岁的用户)")if question:with st.spinner("正在生成 SQL 查询,请稍候..."):result = vn.ask(question)logger.info(f"vn.ask 返回结果: {result}")# 检查返回值类型并提取 SQL 字符串if isinstance(result, tuple):sql_query = result[0]  # 假设 SQL 在元组的第一个元素else:sql_query = resultst.write(f"生成的 SQL 查询: {sql_query}")conn = sqlite3.connect(db_path)cursor = conn.cursor()try:cursor.execute(sql_query)results = cursor.fetchall()st.write("查询结果:")st.table(results)logger.info(f"SQL 查询执行成功,结果: {results}")except sqlite3.Error as e:st.error(f"SQL 执行错误: {e}")logger.error(f"SQL 执行失败: {e}")finally:conn.close()if __name__ == "__main__":main()

streamlit 启动下,在问题窗口填上 “列出所有年龄超过30岁的用户”

执行报错了

vn.ask 返回结果: (None, None, None)
2025-04-10 17:32:14.486 Uncaught app exception
Traceback (most recent call last):File "/opt/miniconda3/envs/spatiallm/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 535, in _run_scriptexec(code, module.__dict__)File "/opt/chenrui/qwq32b/test_vanna_1.py", line 148, in <module>main()File "/opt/chenrui/qwq32b/test_vanna_1.py", line 135, in maincursor.execute(sql_query)
TypeError: execute() argument 1 must be str, not None

问题分析

  1. 为什么 vn.ask() 返回 (None, None, None)
    • Vanna 的 ask 方法依赖于训练数据(DDL、SQL 示例等)和底层语言模型(这里是 qwq_32B)的能力。
    • 当前训练数据可能不足,或者模型未能正确理解问题并生成 SQL。
    • 日志显示 vn.ask 返回结果: (None, None, None),说明生成过程完全失败,没有返回有效的 SQL。
  2. 是否需要增加训练
    • 是的,Vanna 需要足够的训练数据来理解数据库结构和生成正确的 SQL。如果训练数据不足(例如只有 DDL 而没有 SQL 示例),模型可能无法将自然语言问题映射到正确的查询。
    • 另外,本地 qwq_32B 模型的性能可能不如 GPT-3.5/GPT-4,可能需要更多上下文或微调才能生成有效 SQL。

修改思路

  1. 增加训练数据:添加更多的 DDL(表结构)和 SQL 示例,帮助 Vanna 理解数据库和常见查询模式。在setup_vanna 方法了增加训练用例
vn.train(sql="SELECT name, age FROM users WHERE age > 30")
vn.train(sql="SELECT * FROM users WHERE name = 'Alice'")
  1. 处理 None 返回值:在代码中检查 sql_query 是否为 None,避免直接传递给 execute()。
  2. 优化提示:在 submit_prompt 中增强提示(prompt),明确要求生成 SQL。

运行训练输出日志

**Step-by-Step Explanation:**
1. **Identify Columns Selected**: The query selects 'name' and 'age', so the question must ask for these two pieces of information.
2. **Determine the Table Context**: The 'FROM users' clause indicates the data comes from a user/employee table, so the question likely refers to employees or users.
3. **Analyze the WHERE Clause**: The condition 'age > 30' filters for individuals older than 30, which must be included in the question.
4. **Formulate the Question**: Combine these elements into a natural question asking for names and ages of those over 30 without mentioning the table name.

Thus, the derived business question is: **"What are the names and ages of employees older than 30?"**

**Answer**
The business question this SQL query answers is:
\boxed{What are the names and ages of employees older than 30?}

---

**Final Answer**
\boxed{What are the names and ages of
Adding SQL...
2025-04-10 17:50:24,333 - INFO - 提交增强提示: Generate a valid SQL query for the following question based on the database schema: ['System: The user will give you SQL and you will try to guess what the business question this query is answering. Return just the question without any additional explanation. Do not reference the table name in the question.', "User: SELECT * FROM users WHERE name = 'Alice'"]
Return only the SQL query.

vanna 会自己去匹配一个相似的问题,比如上面训练的vn.train(sql="SELECT name, age FROM users WHERE age > 30")  对应的问题是 What are the names and ages of employees older than 30,所以vanna的训练是无监督

测试下生成sql的能力

 

代码优化下

GPU 显存有限,无法完整加载 32B 模型,以下是几种可行的修改方案:

1. 使用模型量化(4-bit 或 8-bit)

  • 使用 bitsandbytes 库将模型量化为 4-bit 或 8-bit,显著降低显存需求(例如 4-bit 下约 16 GB)。
  • 需要安装 bitsandbytes 和调整代码。

2. 启用 CPU Offloading

  • 将部分模型卸载到 CPU 和内存,利用 GPU 和 CPU 协同计算。

3. 调整 max_new_tokens

  • 减少生成 token 数量,降低推理时的显存占用(临时缓解,但不解决根本问题)。

4. 设置 PYTORCH_CUDA_ALLOC_CONF

  • 按错误提示设置环境变量,避免内存碎片化。
import sqlite3
import streamlit as st
from vanna.chromadb import ChromaDB_VectorStore
from vanna.base import VannaBase
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import torch
import logging
import os# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)# 设置 PyTorch 内存管理环境变量
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"# 检查 CUDA 是否可用
if not torch.cuda.is_available():logger.error("CUDA 不可用,将回退到 CPU")device = -1  # CPU
else:logger.info(f"CUDA 可用,使用 GPU: {torch.cuda.get_device_name(0)}")device = 0  # 默认 GPU# 初始化 SQLite 数据库
def init_sqlite_db():db_path = "/opt/chenrui/my_database.db"conn = sqlite3.connect(db_path)cursor = conn.cursor()cursor.execute("""CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER)""")cursor.execute("INSERT OR IGNORE INTO users (id, name, age) VALUES (1, 'Alice', 25)")cursor.execute("INSERT OR IGNORE INTO users (id, name, age) VALUES (2, 'Bob', 35)")conn.commit()conn.close()logger.info(f"SQLite 数据库已创建并初始化: {db_path}")return db_path# 查看 SQLite 数据库结构和数据
def show_db_structure(db_path):conn = sqlite3.connect(db_path)cursor = conn.cursor()cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")tables = cursor.fetchall()st.write("数据库中的表:", tables)cursor.execute("PRAGMA table_info(users);")schema = cursor.fetchall()st.write("users 表结构:")st.table(schema)cursor.execute("SELECT * FROM users;")data = cursor.fetchall()st.write("users 表数据:")st.table(data)conn.close()logger.info("数据库结构和数据已显示")# 自定义本地 qwq_32B 的 LLM 类
class Qwq32bLLM(VannaBase):def __init__(self, config=None):super().__init__(config)model_path = "/opt/chenrui/qwq32b/base_model/qwq_32b"self.tokenizer = AutoTokenizer.from_pretrained(model_path)# 使用 4-bit 量化加载模型,并启用 CPU Offloadingself.model = AutoModelForCausalLM.from_pretrained(model_path,device_map="auto",  # 自动分配到 GPU 和 CPUload_in_4bit=True,  # 4-bit 量化torch_dtype=torch.float16,  # 使用 FP16 精度offload_folder="offload",  # 指定卸载目录)# 使用 pipeline,指定 device_mapself.generator = pipeline("text-generation",model=self.model,tokenizer=self.tokenizer,device_map="auto"  # 自动分配设备)logger.info(f"qwq_32B 模型已加载(4-bit 量化,device_map=auto)")def generate(self, prompt):response = self.generator(prompt, max_new_tokens=100, num_return_sequences=1)[0]['generated_text']logger.info(f"生成原始响应: {response}")sql_start = response.find("SELECT")if sql_start != -1:sql_query = response[sql_start:].strip()logger.info(f"提取的 SQL: {sql_query}")return sql_queryreturn response.strip()def submit_prompt(self, prompt, **kwargs):enhanced_prompt = f"Generate a SQLite query for: {prompt}\nSchema: CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, age INTEGER)\nReturn only the SQL."logger.info(f"提交增强提示: {enhanced_prompt}")return self.generate(enhanced_prompt)def system_message(self, message):return f"System: {message}"def user_message(self, message):return f"User: {message}"def assistant_message(self, message):return f"Assistant: {message}"# 定义自定义 Vanna 类
class MyVanna(ChromaDB_VectorStore, Qwq32bLLM):def __init__(self, config=None):ChromaDB_VectorStore.__init__(self, config=config)Qwq32bLLM.__init__(self, config=config)# 使用 Streamlit 的缓存机制初始化 Vanna
@st.cache_resource(ttl=3600)
def setup_vanna(db_path):vn = MyVanna()vn.connect_to_sqlite(db_path)vn.train(ddl="""CREATE TABLE users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER)""")vn.train(sql="SELECT name, age FROM users WHERE age > 30")vn.train(sql="SELECT * FROM users WHERE name = 'Alice'")vn.train(sql="SELECT id, name FROM users WHERE age < 40")logger.info("Vanna 初始化完成并添加了 DDL 和 SQL 示例训练数据")return vn# 主程序
def main():db_path = init_sqlite_db()vn = setup_vanna(db_path)st.title("本地 Vanna Seq2SQL 示例 (CUDA with 4-bit)")st.subheader("SQLite 数据库结构和数据")show_db_structure(db_path)question = st.text_input("请输入问题(例如:列出所有年龄超过30岁的用户)")if question:with st.spinner("正在生成 SQL 查询,请稍候..."):result = vn.ask(question)logger.info(f"vn.ask 返回结果: {result}")if isinstance(result, tuple):sql_query = result[0]else:sql_query = resultif sql_query is None or not isinstance(sql_query, str):st.error

 

 

相关文章:

Vanna + qwq32b 实现 text2SQL

Vanna 是一个开源的 Text-2-SQL 框架&#xff0c;主要用于通过自然语言生成 SQL 查询&#xff0c;它基于 RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09;技术。Vanna 的核心功能是通过训练一个模型&#xff08;基于数据库的元数据和用户提…...

100V5A同步降压大功率芯片WD5105:高效电源管理的卓越之选

100V5A同步降压大功率芯片WD5105&#xff1a;高效电源管理的卓越之选 在现代电子设备的复杂电源架构中&#xff0c;对高效、稳定且可靠的电源管理芯片需求日益增长。WD5105作为一款100V5A同步降压大功率芯片&#xff0c;凭借其出色的性能、全面的保护机制以及广泛的应用适应性…...

springboot中测试python脚本:ProcessBuilder

目录 一.添加Jython依赖 二.使用步骤 1. 创建 ProcessBuilder 实例 2. 设置工作目录&#xff08;可选&#xff09; 3. 合并错误流&#xff08;可选&#xff09; 4. 启动进程 5. 处理输入输出流 6. 等待进程完成 7.完整案例 三.注意事项 ProcessBuilder是jdk提供的脚本…...

Google Chrome下载受限制的解决方案【方法指南】

在国内使用网络时&#xff0c;部分用户在尝试访问Google Chrome官网下载谷歌浏览器时&#xff0c;常常遇到网页无法打开或文件下载失败的情况。这种下载受限制的问题多由网络访问政策或DNS解析异常导致。为了正常获取Google Chrome的最新版安装程序&#xff0c;用户需要通过一些…...

mysql-锁的算法(记录锁、间隙锁、临键锁)

1.行锁的三种算法 有3种行锁算法&#xff0c;分别是&#xff1a; Record Lock&#xff1a;单个行记录上的锁&#xff0c;没有主键&#xff0c;会使用隐式的主键进行锁定Gap Lock&#xff1a;间隙锁&#xff0c;锁定一个范围&#xff0c;但不包含记录本身Next-Key Lock&#x…...

SAP Business One系统标准功能之外的不允许负库存控制

SqlServer版本写法&#xff1a; --在存储过程SBO_SP_TransactionNotification里加上这段代码&#xff0c;记得定义一个全局变量用于接收提醒具体是哪个物料 IF transaction_type IN (A) BEGINIF EXISTS (SELECT 1 FROM OIVL T0INNER JOIN OITW T1 ON T0.ItemCode T1.ItemCode…...

AI与5G的融合:如何实现更快速、更智能的物联网应用?

引言 AI和5G的结合&#xff0c;正在加速物联网&#xff08;IoT&#xff09;应用的发展&#xff0c;让万物互联变得更加智能、高效。5G提供超高速率、低时延和海量连接的网络能力&#xff0c;而AI则赋予物联网设备更强的数据分析、预测和自动决策能力。当AI与5G融合&#xff0c;…...

Redis的哨兵

Redis的哨兵 Sentinel 一.哨兵概念1.相关名词解释图 二.主节点恢复方式1.人工恢复主节点故障流程图2.哨兵自动恢复主节点流程 三.使用docker搭建环境1.安装docker-compose2.安装docker3.停止之前的redis服务器4.使用docker获取到redis的镜像5.使用docker-compose进行容器编排创…...

初识Redis · 简单理解Redis

目录 前言&#xff1a; 分布式系统 开源节流 认识Redis 负载均衡 缓存 微服务 前言&#xff1a; 本文只是作为Redis的一篇杂谈&#xff0c;简单理解一下Redis为什么要存在&#xff0c;以及它能做到和它不能做到的事儿&#xff0c;简单提及一下它对应的优势有什么&#…...

Python设计模式-抽象工厂模式

1. 什么是抽象工厂模式 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种方式来创建一系列相关或相互依赖的对象&#xff0c;而无需指定它们具体的类。这种模式是所有形式的工厂模式中最为抽象和最具一般性的一种。…...

【中检在线-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…...

第16届蓝桥杯单片机模拟试题Ⅲ

试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //sys.c extern unsigned char UI; //界面标志(0湿度界面、1参数界面、2时间界面) extern unsigned char time; //时间间隔(1s~10S) extern bit ssflag; //启动/停止标志…...

软件系统安全设计方案,信息化安全建设方案(Word原件)

1.1 总体设计 1.1.1 设计原则 1.2 物理层安全 1.2.1 机房建设安全 1.2.2 电气安全特性 1.2.3 设备安全 1.2.4 介质安全措施 1.3 网络层安全 1.3.1 网络结构安全 1.3.2 划分子网络 1.3.3 异常流量管理 1.3.4 网络安全审计 1.3.5 网络访问控制 1.3.6 完…...

UE5 尝试接入 C# 脚本方案

最近团结替代 Unity6 的事官宣了&#xff0c;只能唏嘘不已&#xff0c;顺带的也就研究了一下在 UE5 中接入 C# 的方案&#xff0c;也算是提前帮广大 Unity 开发者蹚一下转 UE 的路~ 当前我发现的&#xff0c;维护比较勤快的 UE C# 方案有2个&#xff0c;UnrealCSharp 和 Unrea…...

力扣hot100 81-90记录

81-90&#xff08;动态规划&#xff09; leetcodehot100 81&#xff1a; class Solution { public:int climbStairs(int n) {int p 0, q 0, count 1;for(int i 1; i < n; i){p q; q count;count p q;}return count;} };//81class Solution { public:vector<vect…...

深入解析以太坊虚拟机(EVM)架构与状态机特性

以太坊&#xff08;Ethereum&#xff09;作为第二代区块链平台&#xff0c;其不仅仅是一部分布式账本&#xff0c;而是一个支持智能合约与去中心化应用&#xff08;DApps&#xff09;的全球计算机。其核心架构中&#xff0c;以太坊虚拟机&#xff08;Ethereum Virtual Machine&…...

MySQL---Ubuntu环境安装

1.首先我们要安装MySQL的安装包&#xff08;APT 配置包&#xff09; 这个是适合我的Ubuntu版本的MySQL安装包 下载安装包&#xff08;MySQL APT 配置包&#xff09; wget https://dev.mysql.com/get/mysql-apt-config_0.8.17-1_all.deb2.安装 APT 配置包&#xff1a; sudo d…...

Vue 3 中 ref 与 reactive 的对比

Vue 3 中 ref 与 reactive 的对比 Vue 3 中 ref 与 reactive 的对比一、定义和基本使用refreactive 二、响应式原理refreactive 三、适用场景refreactive 四、注意事项refreactive Vue 3 中 ref 与 reactive 的对比 在 Vue 3 中&#xff0c;ref 和 reactive 都是用于创建响应式…...

【数据结构 · 初阶】- 单链表

目录 一.相关指针知识点 二.链表 1.为什么学了顺序表还要学链表 2.优点 三.实现 1.链表的打印 —— 理解链表结构 (2) 物理结构图 2.链表的尾插 —— 入门 错误写法&#xff1a;tail ! NULL 总结&#xff1a; 正确代码物理图解&#xff1a; (2) 尾插整体代码 (思考…...

【前端】【React】useCallback的作用与使用场景总结

一、useCallback 的作用与使用场景总结 useCallback 是 React 提供的一个 Hook&#xff0c;用于缓存函数的引用&#xff0c;避免因为组件重新渲染而导致函数地址发生变化。它返回一个记忆&#xff08;memoized&#xff09;后的回调函数&#xff0c;只有当依赖项发生变化时才会…...

什么是 React Router?如何使用?

React Router 详解 1. 引言 在现代 web 开发中&#xff0c;单页面应用&#xff08;SPA&#xff09;越来越流行&#xff0c;React 是构建 SPA 的热门库之一。React Router 是一个标准的路由库&#xff0c;专为 React 应用设计&#xff0c;允许开发者在应用中实现动态路由和 UR…...

jQuery 插件

在现代Web开发中&#xff0c;jQuery以其简洁的语法和强大的功能成为了前端开发者们喜爱的工具之一。为了进一步扩展jQuery的功能&#xff0c;社区贡献了大量的插件&#xff0c;使得开发者能够更加高效地实现各种复杂的交互效果和功能。本文将介绍什么是jQuery插件、如何编写自己…...

未来杭州:科技与茶香交织的生态诗篇

故事背景 故事发生在中国浙江杭州&#xff0c;融合智能科技与传统茶文化&#xff0c;描绘未来城市中人与自然共生的诗意画卷。通过六个充满未来感的生态场景&#xff0c;展现科技如何重塑龙井茶园、古运河、西湖等经典地标&#xff0c;编织出一曲科技与人文共鸣的生态交响诗。 …...

微服务多模块构建feign项目过程与一些报错(2025详细版)

目录 1.eureka-server的注意事项 2.eureka-feign的注意事项 3.多模块构建feign项目过程 3.1创建父项目 3.2创建子项目eureka-server 3.3创建子项目eureka-provider 3.4创建子项目eureka-feign 3.5运行 给个点赞谢谢 1.eureka-server的注意事项 eureka-server的yml文件…...

AWS云安全实践:基于CISA关键措施的检测与实施指南

1. 引言 随着越来越多的组织将其基础设施迁移到云端,确保AWS环境的安全变得至关重要。美国网络安全与基础设施安全局(CISA)提出的关键措施为我们提供了一个可靠的框架。本文将探讨如何在AWS环境中实施这些措施,特别关注检测类别和可实施的关键措施。 2. AWS云安全中的CISA关…...

超越肉眼所见:一种利用视网膜光学相干断层扫描血管成像(OCTA)图像进行早期痴呆检测的关联模型|文献速递-深度学习医疗AI最新文献

Title 题目 Beyond the eye: A relational model for early dementia detection using retinal OCTA images 超越肉眼所见&#xff1a;一种利用视网膜光学相干断层扫描血管成像&#xff08;OCTA&#xff09;图像进行早期痴呆检测的关联模型 01 文献速递介绍 阿尔茨海默病&…...

终端使用python出现segmentation fault (core dumped)的一种解法

有时候在终端输入python&#xff0c;希望交互式运行命令或者通过pdb调试&#xff0c;但是出现如下错误&#xff1a; [1] 7476 segmentation fault (core dumped) python 但是单独运行python xxx.py 或者 python -c "xxx" 又是可以的&#xff01; 经过与AI大模…...

分布式id生成算法(雪花算法 VS 步长id生成)

分布式ID生成方案详解:雪花算法 vs 步长ID 一、核心需求 全局唯一性:集群中绝不重复有序性:有利于数据库索引性能高可用:每秒至少生成数万ID低延迟:生成耗时<1ms二、雪花算法(Snowflake) 1. 数据结构(64位) 0 | 0000000000 0000000000 0000000000 0000000000 0 |…...

h265为什么没有大范围应用

H.265&#xff08;也称为 HEVC&#xff0c;High Efficiency Video Coding&#xff09;是一种视频压缩标准&#xff0c;旨在提供比 H.264&#xff08;AVC&#xff09;更高的压缩效率。然而&#xff0c;尽管 H.265 在技术上具有许多优势&#xff0c;但其大范围应用受到了以下几个…...

Linux图形化界面

一、Linux图形化界面 桌面对于Linux系统来说&#xff0c;只是一个应用程序&#xff0c;所以是可以移植的。 Linaro公司针对于半导体厂商推出的芯片&#xff0c;开发了ARM开发工具、Linux内核以及Linux发行版&#xff08;包括Android及Ubuntu&#xff09;。 所以无需自己移植&am…...

LangChain-检索系统 (Retrieval)

检索系统 (Retrieval) 检索系统是LangChain的核心组件之一&#xff0c;它提供了从各种数据源获取相关信息的能力&#xff0c;是构建知识增强型应用的基础。本文档详细介绍LangChain检索系统的组件、工作原理和最佳实践。 概述 检索系统解决了大型语言模型知识有限和过时的问…...

【Linux】进程概念

目录 一、进程概念 &#xff08;一&#xff09;什么是进程 &#xff08;二&#xff09;描述进程-PCB 二、fork创建进程 &#xff08;一&#xff09;bash概念 &#xff08;二&#xff09;如何创建子进程 一、进程概念 &#xff08;一&#xff09;什么是进程 结论&#x…...

【JavaScript】十七、事件委托(冒泡阶段的利用)

文章目录 1、事件委托2、tab栏切换案例&#xff1a;使用事件委托优化3、阻止元素默认行为 1、事件委托 以送快递为例&#xff0c;某班有20名同学&#xff0c;每人有一个快递&#xff0c;快递员可以一个个送&#xff0c;需要送40次&#xff0c;很繁琐&#xff0c;换个方式&…...

Android InstalldNativeService::getAppSize源码分析

InstalldNativeService::getAppSize 是 Android 系统中用于计算应用程序存储空间的核心方法&#xff0c;其逻辑可分为以下几个关键模块&#xff08;结合代码和上下文分析&#xff09;&#xff1a; 一、基础校验与初始化 ​​1. 权限校验​​ 通过 ENFORCE_UID(AID_SYSTEM) 确…...

微信小程序跳

/** * 画布文本换行绘制 * canvasContext 画布实例 * text 要写入的文本 * x 初始x轴位置 * y 初始y轴位置 * ySpacing 换行后&#xff0c;每行直接的间隔 * maxWidth 此文本写入画布的最大宽度&#xff0c;超过此宽度就换行 * color 文本颜色 * size 文本字体大小 * align 文本…...

openlayers入门01 -- 环境配置和初始化地图

openlayers入门 openlayers开发环境配置 1.下载VSCode 官网地址&#xff1a;https://code.visualstudio.com/ 点击Download for Windows 2.安装汉化插件和openlayers插件 搜索chinese&#xff0c;下载Chinese (Simplified) (简体中文) Language Pack 更改语言并重启 搜…...

window实现多jdk共存、便捷切换

背景 如今大模型技术流行&#xff0c;想要跟上发展就也得学一学&#xff0c;比如Spring-AI等框架&#xff0c;但这些AI相关的框架对jdk版本都有要求&#xff0c;一般都要不低于17。 而在企业开发中&#xff0c;很多时候还使用着jdk8&#xff0c;如何重新安装17&#xff0c;则需…...

常见的 set 选项与空变量检查

在编写 Bash 脚本时&#xff0c;使用 set 命令中的一些选项可以帮助我们在脚本执行过程中及时捕获错误和潜在问题&#xff0c;避免脚本在出错时继续执行&#xff0c;提高脚本的可靠性和健壮性。 set -e&#xff1a;遇到错误就停 set -e 的作用是&#xff1a;一旦脚本中的某个…...

JS 创建对象方法

创建对象的三种方法 3 通过构造函数 自定义构造函数 构造函数 快速定义多个对象 自定义构造函数...

IMX6ULL2025年最新部署方案:最新的UBootLinux和Rootfs部署正点原子Alpha开发板指南

正点原子Alpha IMX6ULL开发板2025年最新部署方案&#xff1a;基于Ubuntu24.04平台开发&#xff0c;部署最新的UBoot/Linux和BusyBox Rootfs部署指南 前言 ​ 笔者实在绷不住比较旧的方案了&#xff0c;广义流行的方案是使用2016年发布的Uboot来引导Linux4.1.15&#xff0c;配…...

threeJs实现裸眼3D小狗

一、实现效果 使用threeJs实现裸眼3D小狗&#xff0c;效果如下&#xff0c;其实如果将小狗换成建模小狗&#xff0c;效果更好&#xff0c;这个是模拟了一只小狗。 二、实现代码 代码如下&#xff1a; <!DOCTYPE html> <html> <head><title>星空小狗…...

ZYNQ笔记(二):MIO 、EMIO

版本&#xff1a;Vivado2020.2&#xff08;Vitis&#xff09; 任务&#xff1a;使用GPIO MIO 和 EMIO 实现按键 KEY 控制 LED&#xff08; 两个PL端LED、两个PS端KEY&#xff09; 目录 一、MIO 、EMIO 介绍 二、硬件设计 三、软件设计 四、效果 一、MIO 、EMIO 介绍 …...

Cygwin编译安装Acise

本文记录Windows下使用Cygwin编译安装Acise的流程。 零、环境 操作系统Windows11Visual Studio CodeVisual Studio Code 1.92.0Cygwin 一、工具及依赖 1.1 Visual Studio Code 下载并安装Visual Studio Code, 同时安装以下插件&#xff0c; Task Explorer Output Colorizer …...

ubuntu22.04 安装-ODBC驱动-SQLserver

1.ISO下载 中科大 Index of /ubuntu-releases/http://mirrors.ustc.edu.cn/ubuntu-releases/ 2.VMware Workstation创建虚拟机 3.更换清华源或者中科大的源 Ubuntu 24.04更换清华源_哔哩哔哩_bilibili 中科大镜像源&#xff1a; Ubuntu - USTC Mirror Help 清华源 ubuntu | 镜…...

[数据结构]Trie字典树

GPT的介绍 &#x1f9e0; 一句话总结&#xff1a; 字典树是一种专门用来存很多字符串的“超级前缀树”&#xff0c;查找某个字符串或前缀的时候&#xff0c;特别快&#xff01; ✍️ 举个生活例子&#xff08;类比&#xff09;&#xff1a; 你想做一个词典&#xff08;Dictio…...

【网络安全】Linux 命令大全

未经许可,不得转载。 文章目录 前言正文文件管理文档编辑文件传输磁盘管理磁盘维护网络通讯系统管理系统设置备份压缩设备管理其它命令前言 在网络安全工作中,熟练掌握 Linux 系统中的常用命令对于日常运维、日志分析和安全排查等任务至关重要。 以下是常用命令的整理汇总,…...

Xcode警报“Ignoring duplicate libraries: ‘-lc++’” 警报

目录 前言 一、问题出现的原因 二、解决步骤 1. 检查构建设置中的链接器标志 2. 检查依赖中的重复库 3. 清除派生数据&#xff1a; 4. 检查冲突的 C 库 5. 更新 CocoaPods&#xff1a; 前言 有时候我们会看到Xcode警报&#xff1a;Ignoring duplicate libraries: ‘-lc…...

WebStorm中使用live-server插件

文章目录 1. 前提条件1.1 已安装Node1.1.1 淘宝的镜像1.2 安装live-server1.3 安装WebStorm2. Windows配置hosts3. WebStorm配置live-server3.1 WebStorm创建3.2 启动 live-server1. 前提条件 1.1 已安装Node Windows PowerShell 版权所有(C) Microsoft Corporation。保留所…...

Python 中使用单例模式

有这么一种场景&#xff0c;Web服务中有一个全局资源池&#xff0c;在需要使用的地方就自然而言引用该全局资源池即可&#xff0c;此时可以将该资源池以单例模式实现。随后&#xff0c;需要为某一特殊业务场景专门准备一个全局资源池&#xff0c;于是额外复制一份代码新建了一个…...

【基于LangChain的千问大模型工具调用】 Function CallingTool Calling简易示例

目录 示例代码 运行结果 功能&#xff1a;根据用户输入自动选择数学计算/天气查询工具处理 ​​"用户输入 → 意图分析 → 工具调用 → 结果返回"​​ 库名解析&#xff1a;【langchain库名解析】-CSDN博客 示例代码 # 模块1&#xff1a;依赖导入 from langc…...