【GenBI优化】提升text2sql准确率:建议使用推理大模型,增加重试

引言

Text-to-SQL(文本转 SQL)是自然语言处理(NLP)领域的一项重要任务,旨在将自然语言问题自动转换为可在数据库上执行的 SQL 查询语句。这项技术在智能助手、数据分析工具、商业智能(BI)平台等领域具有广泛的应用前景,能够极大地降低数据查询和分析的门槛,让非技术用户也能轻松地与数据交互。

近年来,随着深度学习和预训练语言模型(PLM)的快速发展,Text-to-SQL 模型的性能取得了显著提升。然而,在实际应用中,Text-to-SQL 模型的准确率仍然面临诸多挑战,例如自然语言的多样性和歧义性、复杂 SQL 查询的处理、数据库 Schema 的理解和利用等。

本文将深入探讨两种有效提升 Text-to-SQL 准确率的方法:

  1. 使用推理大模型(Large Language Models for Inference): 利用更大规模、更强大的预训练语言模型进行推理,充分发挥其语义理解和生成能力。
  2. 增加重试机制(Retry Mechanism): 在模型生成 SQL 查询的过程中,引入重试机制,对生成的 SQL 进行验证和修正,提高最终结果的准确性。

我们将详细介绍这两种方法的原理、实现方式,并通过丰富的代码示例和表格进行说明,帮助读者深入理解并掌握这些技术。

1. 使用推理大模型 (Large Language Models for Inference)

1.1. 为什么选择推理大模型?

传统的 Text-to-SQL 模型通常基于较小规模的预训练语言模型(例如 BERT、RoBERTa)进行微调。虽然这些模型在许多基准数据集上取得了不错的效果,但在处理复杂、多样化的自然语言查询时,其性能往往会受到限制。

近年来,随着模型规模的不断扩大,涌现出了一批参数量巨大的预训练语言模型,例如 GPT-3、Codex、PaLM、LLaMA 等。这些大模型在海量数据上进行预训练,学习了更丰富的语言知识和世界知识,具有更强的语义理解、推理和生成能力。

时间来到当下,逻辑能力最强的是推理模型,DeepSeek R1、openai o1等

使用推理大模型进行 Text-to-SQL 任务具有以下优势:

  • 更强的语义理解能力: 大模型能够更好地理解自然语言查询的意图,捕捉细微的语义差别,处理复杂的表达方式。
  • 更强的泛化能力: 大模型在海量数据上进行预训练,具有更强的泛化能力,能够处理未见过的查询类型和领域知识。
  • 更强的生成能力: 大模型能够生成更流畅、更符合语法规则的 SQL 查询语句。
  • Zero-shot 或 Few-shot 能力: 一些大模型展现出在少量样本甚至零样本情况下进行 Text-to-SQL 的能力,降低了对大规模标注数据的依赖。

1.2. 推理大模型的选择

选择合适的推理大模型对于提升 Text-to-SQL 准确率至关重要。

选择推理大模型时,需要考虑以下因素:

  • 模型性能: 不同模型在 Text-to-SQL 任务上的性能可能有所差异,需要根据具体数据集和任务进行评估。
  • 模型规模: 模型规模越大,通常性能越好,但计算资源消耗也越大。
  • API 接口: 一些模型提供了 API 接口,可以方便地进行调用,而另一些模型需要自行部署。
  • 成本: 使用 API 接口可能需要付费,需要考虑成本因素。
  • 开源与否: 开源模型可以自由使用和修改,但可能需要自行搭建环境和进行部署。

1.3. 使用推理大模型进行 Text-to-SQL 的方法

使用推理大模型进行 Text-to-SQL 任务,通常有以下几种方法:

  • 直接生成 SQL(Direct Generation): 将自然语言查询和数据库 Schema 信息作为输入,直接让模型生成 SQL 查询语句。
  • 基于 Prompt 的生成(Prompt-based Generation): 设计合适的 Prompt(提示),引导模型生成正确的 SQL 查询。
  • Few-shot Learning: 提供少量示例(Prompt 中包含示例),让模型学习如何将自然语言查询转换为 SQL 查询。
  • Zero-shot Learning: 不提供任何示例,直接让模型根据自然语言查询和 Schema 信息生成 SQL 查询(需要模型具有强大的 zero-shot 能力)。

1.4. 代码示例:使用 DeepSeek R1进行 Text-to-SQL

Python 代码示例:

import requests
def text_to_sql(query, schema):"""Args:query: 自然语言查询。schema: 数据库 Schema 信息(字符串形式)。Returns:生成的 SQL 查询(字符串形式),如果生成失败则返回 None。"""prompt = f"""数据库 Schema:{schema}自然语言查询:{query}请生成对应的 SQL 查询:```sql"""DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions"  # Example endpointDEEPSEEK_API_KEY = ""  # Your DeepSeek API keyheaders = {"Authorization": f"Bearer {DEEPSEEK_API_KEY}","Content-Type": "application/json"}payload = {"model": "deepseek-reasoner",  # deepseek r1"messages": [{"role": "system", "content": ""},{"role": "user", "content": prompt}],"max_tokens": 10,"temperature": 0}response = requests.post(DEEPSEEK_API_URL, headers=headers, json=payload)# Parse the responseif response.status_code == 200:result = response.json()return result["choices"][0]["message"]["content"].strip()else:print(f"Error calling DeepSeek API: {response.status_code} - {response.text}")return None# 示例数据库 Schema
schema = """
CREATE TABLE Customers (CustomerID INT PRIMARY KEY,Name VARCHAR(255),City VARCHAR(255)
);CREATE TABLE Orders (OrderID INT PRIMARY KEY,CustomerID INT,OrderDate DATE,Amount DECIMAL(10, 2),FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);
"""# 示例自然语言查询
query = "Find the total amount of orders for each customer in New York."# 调用 text_to_sql 函数生成 SQL 查询
sql_query = text_to_sql(query, schema)if sql_query:print(f"生成的 SQL 查询:\n{sql_query}")

注意:

  • 可以加入few shot示例,比如:
prompt = f"""数据库 Schema:{schema}自然语言查询:列出所有顾客的名字SQL查询:```sqlSELECT Name FROM Customers;```自然语言查询:{query}请生成对应的 SQL 查询:```sql"""

1.5. 实验结果对比(仅供参考)
使用不同模型进行Text-to-SQL任务,并进行对比. 假设使用Spider数据集进行测试。

模型执行准确率 (EM)备注
BERT-base~50-55%经典预训练语言模型
RoBERTa-large~60-65%BERT 的改进版
RAT-SQL + RoBERTa~70-75%结合 Schema 信息
GPT-3.5 (few-shot)~75-80%使用少量示例
GPT-4 (few-shot)~80-85%使用少量示例

结果分析:

  • 可以看到,随着模型规模的增大和技术的进步,Text-to-SQL 模型的准确率不断提升。
  • 使用推理大模型(例如 GPT-3.5、GPT-4)可以显著提高 Text-to-SQL 的准确率。
  • 即使是 few-shot learning(提供少量示例),大模型也能取得很好的效果。

2. 增加重试机制 (Retry Mechanism)

2.1. 为什么需要重试机制?

尽管使用推理大模型可以显著提高 Text-to-SQL 的准确率,但模型仍然可能生成错误的 SQL 查询,原因可能包括:

  • 模型自身的局限性: 即使是最大的模型,也无法保证 100% 的准确率。
  • 自然语言的歧义性: 自然语言查询可能存在多种解释,模型可能选择了错误的解释。
  • 复杂的 SQL 语法: 生成复杂的 SQL 查询(例如涉及嵌套查询、聚合函数、窗口函数等)更容易出错。
  • 输入错误: 用户的输入拼写错误,或者数据库的schema描述存在错误。

为了进一步提高 Text-to-SQL 的准确率,我们可以引入重试机制。重试机制的基本思想是:

  1. 生成多个候选 SQL 查询: 让模型一次性生成多个候选 SQL 查询。
  2. 验证 SQL 查询: 对生成的 SQL 查询进行验证,例如检查其语法是否正确、是否可以在数据库上执行、执行结果是否符合预期等。
  3. 选择最佳 SQL 查询: 从多个候选 SQL 查询中选择最佳的 SQL 查询作为最终结果。
  4. 多次尝试: 如果所有候选查询都不符合预期,可以进行多次尝试。

2.2. 重试机制的实现方式

重试机制可以有多种实现方式,以下是一些常用的方法:

  • 基于语法检查的重试 (Syntax-based Retry):

    • 使用 SQL 解析器(例如 sqlparse)检查生成的 SQL 查询是否符合语法规则。
    • 如果语法错误,则重新生成 SQL 查询,或者对错误的 SQL 进行修正。
  • 基于执行结果的重试 (Execution-based Retry):

    • 在数据库上执行生成的 SQL 查询。
    • 如果执行失败(例如语法错误、表或列不存在等),则重新生成 SQL 查询。
    • 如果执行成功,但结果为空或不符合预期(例如返回的行数太少、结果与常识不符等),也可以考虑重新生成 SQL 查询。
  • 基于置信度的重试 (Confidence-based Retry):

    • 让模型对生成的每个 SQL 查询给出一个置信度分数(例如,使用 softmax 概率)。
    • 如果置信度低于某个阈值,则重新生成 SQL 查询。
  • 基于多样性的重试 (Diversity-based Retry):

    • 在生成多个候选 SQL 查询时,鼓励模型生成多样化的查询,避免生成多个相似的查询。
    • 可以使用不同的解码策略(例如 beam search、sampling)或在 Prompt 中添加多样性相关的指令。
  • 基于反馈的重试 (Feedback-based Retry):

    • 如果模型生成的 SQL 查询不正确,可以向模型提供反馈信息,例如错误类型、错误位置等,帮助模型修正错误。
  • 多次尝试:

    • 设置最大尝试次数.
    • 每次尝试时, 可以稍微修改Prompt, 或者使用不同的解码策略.

2.3. 代码示例:基于语法检查和执行结果的重试

以下是一个结合语法检查和执行结果验证的重试机制的 Python 代码示例(假设你已经有一个 text_to_sql 函数,可以将自然语言查询转换为 SQL 查询):

import sqlparse
import sqlite3  # 或其他数据库连接库def text_to_sql_with_retry(query, schema, db_path, max_retries=3):"""带重试机制的 Text-to-SQL 函数。Args:query: 自然语言查询。schema: 数据库 Schema 信息(字符串形式)。db_path: 数据库文件路径。max_retries: 最大重试次数。Returns:生成的 SQL 查询(字符串形式),如果生成失败则返回 None。"""for i in range(max_retries):# 1. 生成 SQL 查询sql_query = text_to_sql(query, schema) # 假设你已经有一个 text_to_sql 函数if sql_query is None:continue# 2. 语法检查parsed = sqlparse.parse(sql_query)if not parsed or parsed[0].get_type() == 'UNKNOWN':print(f"Retry {i+1}: Syntax error in SQL query: {sql_query}")continue# 3. 执行结果验证try:conn = sqlite3.connect(db_path)  # 连接数据库cursor = conn.cursor()cursor.execute(sql_query)results = cursor.fetchall()  # 获取所有结果conn.close()# 简单检查:结果不能为空if results:print(f"Success after {i+1} retries.")return sql_queryelse:print(f"Retry {i+1}: Empty result for SQL query: {sql_query}")except Exception as e:print(f"Retry {i+1}: Execution error for SQL query: {sql_query}\nError: {e}")print("Max retries reached. Failed to generate a valid SQL query.")return None# 示例用法 (假设你有一个名为 "mydatabase.db" 的 SQLite 数据库)
db_path = "mydatabase.db"
query = "Show the names of customers who placed orders after 2023-01-01."
schema = """...""" # 与前面示例相同sql_query = text_to_sql_with_retry(query, schema, db_path)if sql_query:print(f"最终生成的 SQL 查询:\n{sql_query}")

代码解析:

  1. 导入必要的库:
    • sqlparse: 用于 SQL 语法检查。
    • sqlite3 (或其他数据库连接库): 用于连接数据库并执行 SQL 查询。
  2. 定义 text_to_sql_with_retry 函数:
    • 接收自然语言查询、Schema 信息、数据库路径和最大重试次数作为输入。
    • 使用 for 循环进行多次尝试。
  3. 生成 SQL 查询:
    • 调用 text_to_sql 函数生成 SQL 查询 (你需要根据前面的示例实现 text_to_sql 函数)。
  4. 语法检查:
    • 使用 sqlparse.parse() 解析生成的 SQL 查询。
    • 检查解析结果是否有效,以及第一个语句的类型是否为 UNKNOWN (表示解析失败)。
    • 如果语法错误,打印错误信息,并进行下一次重试。
  5. 执行结果验证:
    • 连接数据库。
    • 执行 SQL 查询。
    • 获取所有查询结果。
    • 检查结果是否为空。 如果为空,打印信息并进行下一次重试。
    • 如果执行过程中发生异常 (例如数据库连接错误、SQL 执行错误),打印错误信息并进行下一次重试。
  6. 返回结果:
    • 如果成功生成有效的 SQL 查询并获取到非空结果,则返回该 SQL 查询。
    • 如果达到最大重试次数仍未成功,则返回 None

注意:

  • 这个示例使用了 SQLite 数据库,你可以根据需要修改为其他数据库 (例如 MySQL, PostgreSQL)。
  • 示例中的执行结果验证只做了简单的非空检查,你可以根据实际需求添加更复杂的验证逻辑,例如检查结果的类型、数量、是否符合预期等。
  • 可以结合多种重试机制,例如先进行语法检查,再进行执行结果验证,最后进行基于置信度的重试。
  • 可以调整最大重试次数。
  • 可以在每次重试时,稍微修改Prompt的内容,或者使用不同的模型生成参数,以提高生成多样性。

2.4 示例: 多次尝试及修改Prompt

import openai
import sqlparse
import sqlite3def text_to_sql_with_retry_and_prompt_variation(query, schema, db_path, max_retries=3):"""带重试机制和 Prompt 变化的 Text-to-SQL 函数。Args:query: 自然语言查询。schema: 数据库 Schema 信息(字符串形式)。db_path: 数据库文件路径。max_retries: 最大重试次数。Returns:生成的 SQL 查询(字符串形式),如果生成失败则返回 None。"""base_prompt = f"""数据库 Schema:{schema}自然语言查询:{query}请生成对应的 SQL 查询:```sql"""for i in range(max_retries):# 根据重试次数修改 Promptif i == 0:prompt = base_promptelif i == 1:prompt = base_prompt + "\n请确保 SQL 查询的语法正确。"else:prompt = base_prompt + "\n请使用最有效的方式查询, 并确保 SQL 查询的语法正确。"# 生成 SQL 查询try:response = openai.Completion.create(engine="text-davinci-003",prompt=prompt,max_tokens=200,n=1,stop=["```"],temperature=0.7 + (i * 0.1),  # 每次重试稍微提高温度)sql_query = response.choices[0].text.strip()except Exception as e:print(f"Retry {i + 1}: API call failed: {e}")continueif sql_query is None:continue# 语法检查parsed = sqlparse.parse(sql_query)if not parsed or parsed[0].get_type() == 'UNKNOWN':print(f"Retry {i+1}: Syntax error in SQL query: {sql_query}")continue# 执行结果验证try:conn = sqlite3.connect(db_path)cursor = conn.cursor()cursor.execute(sql_query)results = cursor.fetchall()conn.close()if results:print(f"Success after {i+1} retries.")return sql_queryelse:print(f"Retry {i+1}: Empty result for SQL query: {sql_query}")except Exception as e:print(f"Retry {i+1}: Execution error for SQL query: {sql_query}\nError: {e}")print("Max retries reached. Failed to generate a valid SQL query.")return None# 示例用法
db_path = "mydatabase.db"
query = "Show the names of customers who placed orders after 2023-01-01."
schema = """..."""  # 与前面示例相同
sql_query = text_to_sql_with_retry_and_prompt_variation(query, schema, db_path)
if sql_query:print(f"最终生成的 SQL 查询:\n{sql_query}")

代码改进点:

  1. Prompt 变化: 在每次重试时, 对Prompt 进行微调, 例如添加额外的指示(“请确保 SQL 查询的语法正确”, “请使用最有效的方式查询”)。
  2. 温度调整: 随着重试次数增加, 稍微提高温度(temperature), 以增加生成结果的多样性。

3. 总结

本文深入探讨了两种有效提升 Text-to-SQL 准确率的方法:使用推理大模型和增加重试机制。

  • 使用推理大模型: 利用更大规模、更强大的预训练语言模型进行推理,可以充分发挥其语义理解和生成能力,显著提高 Text-to-SQL 的准确率。
  • 增加重试机制: 在模型生成 SQL 查询的过程中,引入重试机制,对生成的 SQL 进行验证和修正,可以进一步提高最终结果的准确性。

通过结合这两种方法,我们可以构建更准确、更可靠的 Text-to-SQL 系统,为各种应用场景提供更好的支持。

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

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

相关文章

<el-cascader时只取最后一级数据

在用cascader时只取最后一级数据传给后端 组件的属性emitPath: false就可以做到&#xff0c;取值就是最后一级传给后端。并且后端放回的id 也直接可以做回显 <el-cascaderv-model"Type":options"Options":props"{ value: id, label: label, chil…

`maturin`是什么:matu rus in python

maturin是什么 maturin 是一个用于构建和发布 Rust 编写的 Python 绑定库的工具。它简化了将 Rust 代码集成到 Python 项目中的过程,支持创建不同类型的 Python 包,如纯 Python 包、包含 **Rust (系统编程语言)**扩展模块的包等。以下为你详细介绍 maturin 的相关信息并举例…

流媒体网络协议全解析:从实时传输到自适应流,如何选择最优方案?

一、历史发展与协议提出者 流媒体协议的发展与互联网技术迭代紧密相关,主要分为三个阶段: 早期专有协议(1990s-2000s) RTSP/RTP 提出者:RealNetworks(RTSP初始推动者),后由IETF标准化(RFC 2326)。背景:1996年推出,用于视频监控和点播系统,基于UDP传输媒体流,支持…

mysql架构查询执行流程(图解+描述)

目录 mysql架构查询执行流程 图解 描述 mysql架构查询执行流程 图解 描述 用户连接到数据库后&#xff0c;由连接器处理 连接器负责跟客户端建立连接、获取权限、维持和管理连接 客户端发送一条查询给服务器 服务器先检查查询缓存&#xff0c;如果命中缓存&#xff0c;则立…

【QT问题】Ubantu环境下解决已经下载好的qt怎么添加或卸载其他组件

1、找到自己qt的安装目录->双击打开MaintenanceTool.exe 2、点击next进去&#xff0c;此时需要登录qt账户&#xff08;如果没有去官网注册一个&#xff0c;很快且免费&#xff09; 我这里随便填的账号&#xff0c;如果是正确的下面next就能够点击。 这里随便提一下&#xf…

CS50 使用 Python 进行人工智能简介-“骑士与流氓”谜题

如何使用逻辑推理来解决“骑士与骗子”&#xff08;Knights and Knaves&#xff09;类型的逻辑难题。具体来说&#xff0c;任务是根据每个角色的陈述推理出他们是“骑士”还是“骗子”。 任务背景&#xff1a; 骑士与骗子问题&#xff1a;每个角色要么是骑士&#xff0c;要么是…

每日学习Java之一万个为什么?[MySQL面试篇]

分析SQL语句执行流程中遇到的问题 前言1 MySQL是怎么在一台服务器上启动的2 MySQL主库和从库是同时启动保持Alive的吗&#xff1f;3 如果不是主从怎么在启动的时候保证数据一致性4 ACID原则在MySQL上的体现5 数据在MySQL是通过什么DTO实现的6 客户端怎么与MySQL Server建立连接…

详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll

运行程序时提示“d3dx9_27.dll文件缺失”&#xff0c;通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决&#xff0c;无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…

IP----访问服务器流程

这只是IP的其中一块内容-访问服务器流程&#xff0c;IP还有更多内容可以查看IP专栏&#xff0c;前一段学习内容为IA内容&#xff0c;还有更多内容可以查看IA专栏&#xff0c;可通过以下路径查看IA-----配置NAT-CSDN博客CSDN,欢迎指正 1.访问服务器流程 1.分层 1.更利于标准化…

Linux报 “device or resource busy” 异常的原因以及解决办法

首先&#xff0c;Linux报"device or resource busy"的原因是因为某个进程正在占用该设备或资源&#xff0c;导致其他进程无法访问该设备或资源。 解决该问题的办法有以下几种&#xff1a; 查找占用该设备或资源的进程&#xff0c;然后将其停止或结束。可以使用以下…

和鲸科技推出人工智能通识课程解决方案,助力AI人才培养

2025年2月&#xff0c;教育部副部长吴岩应港澳特区政府邀请&#xff0c;率团赴港澳宣讲《教育强国建设规划纲要 (2024—2035 年)》。在港澳期间&#xff0c;吴岩阐释了教育强国目标的任务&#xff0c;并与特区政府官员交流推进人工智能人才培养的办法。这一系列行动体现出人工智…

java springboot 中调用 C++ 方法

以下是一个完整的 Spring Boot 调用 C 方法的 Demo&#xff0c;采用 JNI (Java Native Interface) 方式实现&#xff0c;包含详细步骤说明&#xff1a; 1. 项目结构 demo-project/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/example/…

JSX基础 —— 识别JS表达式

在JSX中可以通过 大括号语法 { } 识别JS中的表达式&#xff0c;比如常见的变量、函数调用、方法调用等等 1、使用引号传递字符串 2、使用JavaScript变量 3、函数调用和方法调用 (函数和方法本质没有区别&#xff0c;这里默认&#xff1a; 函数是自己定义的&#xff0c;方法是…

git从零学起

从事了多年java开发&#xff0c;一直在用svn进行版本控制&#xff0c;如今更换了公司&#xff0c;使用的是git进行版本控制&#xff0c;所以打算记录一下git学习的点滴&#xff0c;和大家一起分享。 百度百科&#xff1a; Git&#xff08;读音为/gɪt/&#xff09;是一个开源…

关于对async和await的初步理解

async 包裹着的函数中进程是堵塞的 &#xff0c;是同步化的&#xff0c; await等待的是个promise对象&#xff0c;否则"await" 对此表达式的类型没有影响 例1 async getDataDD(){await this.fun1()await this.fun2()// await Promise.all([this.fun1(),this.fun…

MySQL—Keepalived+MySQL双主复制实现MySQL高可用

Keepalived原理&#xff1a; Keepalived 的原理主要基于虚拟路由冗余协议&#xff08;VRRP&#xff0c;Virtual Router Redundancy Protocol&#xff09;、健康检查机制和负载均衡机制&#xff0c;以下为你详细介绍&#xff1a; VRRP 协议实现高可用&#xff1a;VRRP 是 Keep…

SpringBoot AOP 源码解析

文章目录 一、AOP 代码示例1. 准备注解和目标类2. 定义 Aspect3. 结论 二、源码1. AOP 实现核心类2. 代理类的创建流程2.1 核心类 AbstractAutoProxyCreator2.2 AbstractAutoProxyCreator#postProcessBeforeInstantiation2.3 AspectJAwareAdvisorAutoProxyCreator#shouldSkip2.…

Linux:Shell环境变量与命令行参数

目录 Shell的变量功能 什么是变量 变数的可变性与方便性 影响bash环境操作的变量 脚本程序设计&#xff08;shell script&#xff09;的好帮手 变量的使用&#xff1a;echo 变量的使用&#xff1a;HOME 环境变量相关命令 获取环境变量 环境变量和本地变量 命令行…

MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 高级篇 part 5

第05章_存储引擎 为了管理方便&#xff0c;人们把连接管理、查询缓存、语法解析、查询优化这些并不涉及真实数据存储的功能划分为MySQLserver的功能&#xff0c;把真实存取数据的功能划分为存储引擎的功能。所t以在MySQLserver完成了查询优化后&#xff0c;只需按照生成的执行…

JAVA面试_进阶部分_23种设计模式总结

1. 单例模式&#xff1a;确保某一个类只有一个实例&#xff0c;而且自行实例化并向整个系统提供这 个实例。 &#xff08;1&#xff09;懒汉式 public class Singleton { /* 持有私有静态实例&#xff0c;防止被引用&#xff0c;此处赋值为null&#xff0c;目的是实现延迟加载…