探索约束LLM输出JSON的应用

news2024/11/16 19:32:43

0、 引言

JSON(JavaScript Object Notation)因其简洁、易读和易于解析的特性,已成为全球使用最广泛的数据交换格式之一。它能够满足各种数据交换需求,特别是在构建人工智能驱动的应用程序时,工程师们经常需要将大型语言模型(LLM)的输出整合到他们的代码库中。

通过向LLM指定特定的语法或模式,并指导其生成符合这些规范的结果,可以提高应用程序的可预测性和稳定性。这种标准化的输出方式,使得应用程序能够更加高效地处理和利用由LLM生成的数据。

简而言之,JSON的互操作性、灵活性和广泛支持,使其成为不同系统和应用程序之间数据交换的首选格式。
在这里插入图片描述

1、为什么让LLM 输出JSON数据如此困难?

语言模型擅长预测下一个标记并生成文本,但它们在产生文本之外的精确输出方面可能具有挑战性,因为它们并不总是精确地遵循指令

例如:对于 OpenAI,希望 GPT-3.5-turbo 始终以以下形式响应

(message_type) {message_content}

然而,它可能会以略微不同的方式响应:

message_type:message_content
message_type:"message_content"
(message_type): "message_content"

2、使用提示工程

Please provide the response in the form of a Python list. It should begin with “[“ and end with “]”.
“请以Python列表的形式提供回复。它应该以‘[’开始,以‘]’结束。”

Chatgpt (gpt4) 支持提示系统/用户 (gpt4 api) 将数据格式化为 csv。 通常工作完美。 虽然 gpt4 非常适合制作演示原型,但它相当昂贵,因此本地解决方案将是完美的。

有许多提示工程框架可以限制 json 格式的输出,请参阅此处的一个用于 LLM 输出的严格 JSON 框架。

## simple example provided by the author
res = strict_output(system_prompt = 'You are a classifier',
                    user_prompt = 'It is a beautiful day',
                    output_format = {"Sentiment": "Type of Sentiment",
                                    "Tense": "Type of Tense"})     
print(res)
## output
{'Sentiment': 'Positive', 'Tense': 'Present'}

虽然提示工程对于某些用例可能是有效的,但它有一个局限性—LLM所做的任何内部更改都可能导致意外的输出。 众所周知,这会在生产环境中引起问题,正如在线故事中所见,依赖 ChatGPT API 的 AI 应用程序由于不断的后台更新而失败。

3、约束LLM输出

这一领域已经有大量的创新工作,这里探索三个框架,它们都从不同的角度解决了这个问题。 尽管使用不同的方法,但每个框架如何达到相似的结果给我留下了深刻的印象。

  • GRAMMAR — 约束模型输出的语法。 例如,你可以强制模型仅输出 JSON:
  • KOR — 这是一个半成品原型,可以“帮助”你使用LLM从文本中提取结构化数据
  • LM-Format-Enforcer — 强制语言模型的输出格式(JSON Schema、Regex 等)
  • Finetune LLM 模型 — 教导模型根据输入数据输出 JSON

3.1 使用语法规则强制模型仅输出 JSON

在这种方法中,你需要使用 Llama.cpp 来运行模型并创建语法文件。 GBNF (GGML BNF) 是一种用于定义形式语法以约束 llama.cpp 中模型输出的格式。

这是我为基本测试创建的一个简单语法文件:

root ::= answer
answer ::= "{"   ws   ""id":"   ws   number   ","   ws   ""name":"   ws   string   "}"
answerlist ::= "[]" | "["   ws   answer   (","   ws   answer)*   "]"
string ::= """   ([^"]*)   """
boolean ::= "true" | "false"
ws ::= [ tn]*
number ::= [0-9]+   "."?   [0-9]*
stringlist ::= "["   ws   "]" | "["   ws   string   (","   ws   string)*   ws   "]"
numberlist ::= "["   ws   "]" | "["   ws   string   (","   ws   number)*   ws   "]"

它更难理解,但是,可以从更容易理解的模式定义开始。 如下所示:

interface answer {
    id: number;
    name: string;
}

接下来将模式粘贴到这个在线工具以自动生成语法文件 - 省去很多麻烦。

现在,有了一个语法文件并准备好插入 Llama.cpp。 有关在你的计算机上本地运行的设置的更多详细信息,请参阅存储库。

## start with a prompt
 ./main -m ./models/Mistral-7B-Instruct-v0.1-Q8.gguf -n 256 — grammar-file grammars/answer.gbnf -p ‘Q: Name the planets in the solar system? A:’
llama_new_context_with_model: n_ctx      = 512
llama_new_context_with_model: freq_base  = 10000.0
llama_new_context_with_model: freq_scale = 1
llama_new_context_with_model: kv self size  =   64.00 MB
llama_new_context_with_model: compute buffer total size = 79.13 MB
llama_new_context_with_model: VRAM scratch buffer: 73.00 MB
llama_new_context_with_model: total VRAM used: 73.00 MB (model: 0.00 MB, context: 73.00 MB)

system_info: n_threads = 8 / 16 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | SSSE3 = 1 | VSX = 0 | 
sampling: 
 repeat_last_n = 64, repeat_penalty = 1.100, frequency_penalty = 0.000, presence_penalty = 0.000
 top_k = 40, tfs_z = 1.000, top_p = 0.950, typical_p = 1.000, temp = 0.800
 mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000
generate: n_ctx = 512, n_batch = 512, n_predict = 256, n_keep = 0

## response
Q: Name the planets in the solar system? A:{ "id": 1, "name": "Mercury"} [end of text]

llama_print_timings:        load time =     845.86 ms
llama_print_timings:      sample time =     157.01 ms /    16 runs   (    9.81 ms per token,   101.91 tokens per second)
llama_print_timings: prompt eval time =     649.35 ms /    13 tokens (   49.95 ms per token,    20.02 tokens per second)
llama_print_timings:        eval time =    3280.48 ms /    15 runs   (  218.70 ms per token,     4.57 tokens per second)
llama_print_timings:       total time =    4104.05 ms
Log end

搞定! 结果是合法的 json对象 {"id":1,"name":"Mercury"}

因此,语法可以灵活地创建复杂的对象。 这是我第二次尝试创建收据模式和语法文件。

## Receipt Type Definitions using Typescript.
interface RestaurantReceipt {
    restaurant: Restaurant;
    customer: Customer;
    order_date: string;
    total_price: number;
    tax_rate: number;
    tax_amount: number;
    discount_code: string;
    payment_method: string;
    card_type: string;
    card_number: string;
    expiration_month: number;
    expiration_year: number;
    cvv: string;
    shipping_address: string;
    items: Item[];
  }
   
  interface Restaurant {
    name: string;
    location: Location;
    year: number;
    phone_number: string;  
    email:string;  
  }
  
  interface Customer {
    first_name: string;
    last_name: string;
    email:string;
    phone_number: string;
  }
  
  interface Location {
    address: string;
    city: string;
    state: string;
    country: string;
  }
  
  interface Item {
    item_name: string;
    quantity: number;
    unit_price: number;
    description: string;
    item_total: number;
  }

对此收据生成的语法文件:

## Generated Grammar used during LLMs generation.
root ::= RestaurantReceipt
Item ::= "{"   ws   ""item_name":"   ws   string   ","   ws   ""quantity":"   ws   number   ","   ws   ""unit_price":"   ws   number   ","   ws   ""description":"   ws   string   ","   ws   ""item_total":"   ws   number   "}"
Itemlist ::= "[]" | "["   ws   Item   (","   ws   Item)*   "]"
Location ::= "{"   ws   ""address":"   ws   string   ","   ws   ""city":"   ws   string   ","   ws   ""state":"   ws   string   ","   ws   ""country":"   ws   string   "}"
Locationlist ::= "[]" | "["   ws   Location   (","   ws   Location)*   "]"
Customer ::= "{"   ws   ""first_name":"   ws   string   ","   ws   ""last_name":"   ws   string   ","   ws   ""email":"   ws   string   ","   ws   ""phone_number":"   ws   string   "}"
Customerlist ::= "[]" | "["   ws   Customer   (","   ws   Customer)*   "]"
Restaurant ::= "{"   ws   ""name":"   ws   string   ","   ws   ""location":"   ws   Location   ","   ws   ""year":"   ws   number   ","   ws   ""phone_number":"   ws   string   ","   ws   ""email":"   ws   string   "}"
Restaurantlist ::= "[]" | "["   ws   Restaurant   (","   ws   Restaurant)*   "]"
RestaurantReceipt ::= "{"   ws   ""restaurant":"   ws   Restaurant   ","   ws   ""customer":"   ws   Customer   ","   ws   ""order_date":"   ws   string   ","   ws   ""total_price":"   ws   number   ","   ws   ""tax_rate":"   ws   number   ","   ws   ""tax_amount":"   ws   number   ","   ws   ""discount_code":"   ws   string   ","   ws   ""payment_method":"   ws   string   ","   ws   ""card_type":"   ws   string   ","   ws   ""card_number":"   ws   string   ","   ws   ""expiration_month":"   ws   number   ","   ws   ""expiration_year":"   ws   number   ","   ws   ""cvv":"   ws   string   ","   ws   ""shipping_address":"   ws   string   ","   ws   ""items":"   ws   Itemlist   "}"
RestaurantReceiptlist ::= "[]" | "["   ws   RestaurantReceipt   (","   ws   RestaurantReceipt)*   "]"
string ::= """   ([^"]*)   """
boolean ::= "true" | "false"
ws ::= [ tn]*
number ::= [0-9]+   "."?   [0-9]*
stringlist ::= "["   ws   "]" | "["   ws   string   (","   ws   string)*   ws   "]"
numberlist ::= "["   ws   "]" | "["   ws   string   (","   ws   number)*   ws   "]"

然后运行 llama.cpp:

## Constrained output with grammars
> llama.cpp supports grammars to constrain model output. For example, you can force the model to output JSON only:
 ./main -m ./models/Mistral-7B-Instruct-v0.1-Q8.gguf -n 256 --grammar-file grammars/json.gbnf -p 'give me a sample receipt:'

输出结果:

llama_new_context_with_model: n_ctx      = 512
llama_new_context_with_model: freq_base  = 10000.0
llama_new_context_with_model: freq_scale = 1
llama_new_context_with_model: kv self size  =   64.00 MB
llama_new_context_with_model: compute buffer total size = 79.13 MB
llama_new_context_with_model: VRAM scratch buffer: 73.00 MB
llama_new_context_with_model: total VRAM used: 73.00 MB (model: 0.00 MB, context: 73.00 MB)

system_info: n_threads = 8 / 16 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | SSSE3 = 1 | VSX = 0 | 
sampling: 
 repeat_last_n = 64, repeat_penalty = 1.100, frequency_penalty = 0.000, presence_penalty = 0.000
 top_k = 40, tfs_z = 1.000, top_p = 0.950, typical_p = 1.000, temp = 0.800
 mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000
generate: n_ctx = 512, n_batch = 512, n_predict = 256, n_keep = 0

give me a sample receipt:{"receiptNumber":"12345","customerName":"John Smith","date":
"2021-01-01 10:30:00.000000",
"items": [
{
"itemId": "1",
"productId": "ABC123",
"quantity": 1,
"unitPrice": 19.99
},
{
"itemId": "2",
"productId": "DEF456",
"quantity": 2,
"unitPrice": 29.99
}
],
"subTotal": 59.98,
"taxAmount": 2.37,
"total": 62.35
} [end of text]

llama_print_timings:        load time =     842.78 ms
llama_print_timings:      sample time =    2477.51 ms /   177 runs   (   14.00 ms per token,    71.44 tokens per second)
llama_print_timings: prompt eval time =     509.36 ms /     9 tokens (   56.60 ms per token,    17.67 tokens per second)
llama_print_timings:        eval time =   38122.00 ms /   176 runs   (  216.60 ms per token,     4.62 tokens per second)
llama_print_timings:       total time =   41331.49 ms
Log end

到目前为止,语法可以控制输出始终生成 JSON 作为输出—看起来很有前途的解决方案。 请参阅我的存储库,了解我为此测试创建的架构和语法文件。

3.2 KOR — 使用LLM提取文本中的结构化数据

关于一些可以用 Kor 完成的事情的想法。

  • 从与提取模式匹配的文本中提取数据。
  • 通过精确理解用户请求,为人工智能助手提供技能。
  • 提供对现有 API 的自然语言访问。

请参阅此处的存储库链接,了解我为此测试创建的测试笔记本。

对于此测试,我将使用开源 LLama-2 模型,因为我们都喜欢节省不使用 ChatGPT api 的成本。

## download LLM model
from huggingface_hub import hf_hub_download
downloaded_model_path = hf_hub_download(repo_id="TheBloke/Llama-2-7b-Chat-GGUF", filename="llama-2-7b-chat.Q5_K_M.gguf")
from langchain.llms  import LlamaCpp
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from kor.extraction import create_extraction_chain

# get model chain
llm = LlamaCpp(model_path=downloaded_model_path,temperature=0.8,verbose=True,echo=True,n_ctx=512)

DEFAULT_SYSTEM_PROMPT = """
You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe.  Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.nnIf a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.
"""
def get_prompt(message: str, system_prompt: str = DEFAULT_SYSTEM_PROMPT) -> str:
    return f'<s>[INST] <<SYS>>n{system_prompt}n<</SYS>>nn{message} [/INST]'

示例 1:模式和链 — 输出单个 Json 对象

#from langchain.chat_models import ChatOpenAI
from kor import create_extraction_chain, Object, Text
from kor.nodes import Object, Text, Number

schema = Object(
    id="player",
    description=(
        "User is controlling a music player to select songs, pause or start them or play"
        " music by a particular artist."
    ),
    attributes=[
        Text(
            id="song",
            description="User wants to play this song",
            examples=[],
            many=True,
        ),
        Text(
            id="album",
            description="User wants to play this album",
            examples=[],
            many=True,
        ),
        Text(
            id="artist",
            description="Music by the given artist",
            examples=[("Songs by paul simon", "paul simon")],
            many=True,
        ),
        Text(
            id="action",
            description="Action to take one of: `play`, `stop`, `next`, `previous`.",
            examples=[
                ("Please stop the music", "stop"),
                ("play something", "play"),
                ("play a song", "play"),
                ("next song", "next"),
            ],
        ),
    ],
    many=False,
)
## chain
chain = create_extraction_chain(llm, schema, encoder_or_encoder_class='json')
chain.run("play songs by paul simon and led zeppelin and the doors")['data']

## result 
{'player': {'artist': ['paul simon', 'led zeppelin', 'the doors']}}

结果看起来不错,与单个对象的架构定义匹配。 KOR 还支持更流行的 pydantic 模式定义。 这是创建 json 对象列表的第二个示例。

示例 2:Pydantic Schema — Json 对象的输出列表

from kor import from_pydantic
from typing import List, Optional
from pydantic import BaseModel, Field

## schema
class PlanetSchema(BaseModel):
    planet_name: str = Field(description="The name of the planet")

class PlanetList(BaseModel):
    planets: List[PlanetSchema]

schema, validator = from_pydantic(
    PlanetSchema,
    description="Planet Information",  
    many=True,  # <-- Note Many = True
)

chain = create_extraction_chain(llm, schema, validator=validator)

result = chain.run(("list planets in our solar system."))
result

## output
{'data': {'planetschema': []},
 'raw': 'n"planetname|name|nMercury|4|244|0.387|nVenus|10|210|0.936|nEarth|5|127|1.000|nMars|2|210|0.181|nJupiter|15|890|4.35|nSaturn|6|720|0.550|nUranus|7|510|0.750|nNeptune|8|490|1.778|"',
 'errors': [],
 'validated_data': []}

嗯,结果与我对 json 对象列表的预期不符。 需要更多调查。 鉴于原始数据确实得出了正确的值。

3.3 LM-Format-Enforcer — 强制LLM的输出格式

LM-Format-Enforcer可以强制LLM的输出格式,例如JSON、Regex等,这是一个看起来很有希望成为最好的框架。 根据文档,框架根据架构设计操纵令牌的输出来生成 json。

请参阅我为此测试创建的笔记本。 与 KOR 测试类似,我将继续使用开源 LLama-2 模型,因为它受到框架的支持。

## setup LLM model
from llama_cpp import Llama
from huggingface_hub import hf_hub_download
downloaded_model_path = hf_hub_download(repo_id="TheBloke/Llama-2-7b-Chat-GGUF", filename="llama-2-7b-chat.Q5_K_M.gguf")
llm = Llama(model_path=downloaded_model_path)


DEFAULT_SYSTEM_PROMPT = """
You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe.  Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.nnIf a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.
"""
def get_prompt(message: str, system_prompt: str = DEFAULT_SYSTEM_PROMPT) -> str:
    return f'<s>[INST] <<SYS>>n{system_prompt}n<</SYS>>nn{message} [/INST]'

对于令牌的输出操作,它与 LLM 推理框架紧密耦合。 对于 Llama.cpp,它需要创建一个 LogitProcessor。 参见下面的代码:

## LM Format Enforcer Logits Processor
from typing import Optional
from llama_cpp import LogitsProcessorList
from lmformatenforcer import CharacterLevelParser
from lmformatenforcer.integrations.llamacpp import build_llamacpp_logits_processor
from lmformatenforcer import JsonSchemaParser
from pydantic import BaseModel
from typing import List
from IPython.display import display, Markdown

def display_header(text):
    display(Markdown(f'**{text}**'))

def display_content(text):
    display(Markdown(f'```n{text}n```'))

def llamacpp_with_character_level_parser(llm: Llama, prompt: str, character_level_parser: Optional[CharacterLevelParser]) -> str:
    logits_processors: Optional[LogitsProcessorList] = None
    if character_level_parser:
        logits_processors = LogitsProcessorList([build_llamacpp_logits_processor(llm, character_level_parser)])
    
    output = llm(prompt, logits_processor=logits_processors)
    text: str = output['choices'][0]['text']
    return text

现在,我们要运行一个简单的测试来返回单个 json 对象

class PlayerSchema(BaseModel):
    first_name: str
    last_name: str
    year_of_birth: int
    num_seasons_in_nba: int

question = 'Please give me information about Michael Jordan. You MUST answer using the following json schema: '
question_with_schema = f'{question}{PlayerSchema.schema_json()}'
prompt = get_prompt(question_with_schema)

display_header("Standard LLM Output:")
result = llamacpp_with_character_level_parser(llm, prompt, None)
display_content(result)
## result 
 Of course! I'd be happy to provide information about Michael Jordan using the provided JSON schema.
{
"first_name": "Michael",
"last_name": "Jordan",
"year_of_birth": 1963,
"num_seasons_in_nba": 15
}
I hope this helps! Let me know if you have any other questions.

所以,结果还不错,它包含一个json对象。 但是,对于要使用此输出的应用程序,它仍然需要额外的解析工作来删除不需要的文本。 所以这个框架正是在输出中保留不需要的文本—只返回一个 json 对象。

display_header("LLM Output with json schema enforcing:")
result = llamacpp_with_character_level_parser(llm, prompt, JsonSchemaParser(PlayerSchema.schema()))
display_content(result)
{ "first_name": "Michael", "last_name": "Jordan", "year_of_birth": 1963, "num_seasons_in_nba": 15 }

接下来,测试一下json对象列表的生成,首先从标准LLM输出开始:

message="Q:please give me a list of planets in the solar system? A: "
prompt=get_prompt(message,DEFAULT_SYSTEM_PROMPT)
output = llm(prompt,max_tokens=512,stop=["Q:"])
text: str = output['choices'][0]['text']
display_header("LLM standard output")
print(text)

## LLM standard output

  Of course! I'd be happy to help you with that. The eight planets in our solar system are:
1. Mercury
2. Venus
3. Earth
4. Mars
5. Jupiter
6. Saturn
7. Uranus
8. Neptune

现在,让我们加入 LLM 输出强制以及一个简单的模式。

## llm
llm = Llama(model_path=downloaded_model_path, n_ctx=4096,n_threads=16,verbose=False)

from typing import List
from pydantic import BaseModel

## schema
class PlanetSchema(BaseModel):
    planet_name: str

class PlanetList(BaseModel):
    planets: List[PlanetSchema]

## question
question = 'please give me a list of planets in the solar system?. You MUST answer using the following json schema: '
question_with_schema = f'{question}{PlanetList.schema_json()}'
prompt = get_prompt(question_with_schema)
#display_content(prompt)

## response
display_header("LLM Output with json schema enforcing:")
result = llamacpp_with_character_level_parser(llm, prompt, JsonSchemaParser(PlanetList.schema()))
display_content(result)
## LLM Output with json schema enforcing:
{ "planets": [ 
{ "planet_name": "Mercury" }, 
{ "planet_name": "Venus" }, { "planet_name": "Earth" }, 
{ "planet_name": "Mars" }, { "planet_name": "Jupiter" }, 
{ "planet_name": "Saturn" }, { "planet_name": "Uranus" }, 
{ "planet_name": "Neptune" } 
] }

很棒的结果是我们在模式中定义的 json 对象列表。

4、结束语

虽然没有一种万能的解决方案,但对完美方法的探索仍在继续。 这些令人惊叹的框架是针对特定用例量身定制的,只要对输出施加限制比即时工程产生更好的结果。

如果训练自己的本地模型可以更好地控制输出,并且在使用模型之前测试模型非常重要,因为每个模型的输出可能会有所不同,并且生成 JSON 对象列表对于LLM来说可能具有挑战性。

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

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

相关文章

Jenkins教程-8-上下游关联自动化测试任务构建

上一小节小节我们学习了一下Jenkins自动化测试任务发送测试结果邮件的方法&#xff0c;本小节我们讲解一下Jenkins上下游关联自动化测试任务的构建。 下面我们以一个真实的自动化测试场景来讲解Jenkins如何管理上下游关联任务的触发和构建&#xff0c;比如我们有两个jenkin任务…

基础入门篇 | YOLOv10 项目【训练】【验证】【推理】最简单教程 | YOLOv10必看 | 最新更新,直接打印 FPS,mAP50,75,95

文章目录 训练 --train.py推理 --detect.py验证 --val.py不训练,只查看模型结构/参数量/计算量 --test.pyYOLOv10 是基于 YOLOv8 项目的改进版本,目前已经被 YOLOv8 项目合并,所以两个算法使用方法完全一致~ 今天我给大家展示一种非常方便的使用过程,包含【训练】【验证】…

情绪管理篇:让七情自然流露,不过分压抑也不掺杂极端的想法即可来去自如

情绪管理篇&#xff1a; 人有七情&#xff0c;本属常理&#xff0c;该哭的时候哭、该笑的时候笑、该怒的时候怒、该忧的时候忧 学习圣贤之学&#xff0c;并非让我们像木头人一样&#xff0c;枯木死灰&#xff0c;而要让自己不要被七情所缠缚、被七情所乱心&#xff0c;我们的喜…

QT拖放事件之三:自定义拖放操作-利用QDrag来拖动完成数据的传输

1、运行效果 1)Qt::MoveAction 2)Qt::CopyAction 2、源码 #include "Widget.h" #include "ui_Widget.h" #include "common.h"

JDBC的概念 ,核心API的介绍 , 注册驱动介绍

第一章 JDBC 1、JDBC的概念 目标 能够掌握JDBC的概念能够理解JDBC的作用 讲解 客户端操作MySQL数据库的方式 使用第三方客户端来访问MySQL&#xff1a;SQLyog、Navicat 使用MySQL自带的命令行方式 通过Java来访问MySQL数据库&#xff0c;今天要学习的内容 如何通过Java代…

考研数学|《李林880》正确率多少算合格?

李林880题是针对考研数学三的练习题集&#xff0c;覆盖了考研数学三的主要知识点和题型。如果能够熟练掌握这些题目&#xff0c;意味着对考研数学三的知识点有了较为深入的理解和应用能力。 首先&#xff0c;考研数学三的总分是150分&#xff0c;题型包括单选题、填空题和解答…

Day5 —— 电商日志数据分析项目

项目二 _____&#xff08;电商日志数据分析项目&#xff09; 引言需求分析详细思路统计页面浏览量Map阶段Reduce阶段 日志的ETL操作Map阶段Reduce阶段 统计各个省份的浏览量Map阶段Reduce阶段 具体步骤统计页面浏览量日志的ETL操作统计各个省份的浏览量工具类&#xff08;utils…

鸿蒙HarmonyOS服务卡片实战

引言 在现代开发中&#xff0c;服务卡片是不可或缺的一部分&#xff0c;比如音乐&#xff0c;天气类等应用&#xff0c;官网的介绍中写道&#xff1a;卡片让您便捷地预览服务信息&#xff0c;例如查看天气或日历日程等内容。您可将卡片添加到屏幕上&#xff0c;让这类信息触手…

拼多多面试总结

文章目录 一面自我介绍提问算法反问结果 二面提问算法反问结果 主管面主管面试准备算法题其他个人提问准备 提问数据库普通索引和覆盖索引的区别索引是什么&#xff1f;索引怎么加快数据库查询的&#xff1f;索引具体怎么实现的&#xff1f;以B树为例&#xff0c;节点放了什么&…

SOIDWORKS Electrical中统计槽满率的经验技巧

近期有一些客户咨询&#xff0c;为什么在SOLIDWORKS Electrical 3D 中做完3D布线工作&#xff0c;但是在统计线槽槽满率的时候不能正常计算。因此我们总结了以下几点经验。 一、对于SOLIDWORKS Electrical中的计算线槽率的功能&#xff0c;除了所使用的线槽需要满足两个条件&am…

【Unity服务器01】之【AssetBundle上传加载u3d模型】

首先打开一个项目导入一个简单的场景 导入怪物资源&#xff0c; AssetBundle知识点&#xff1a; 1.指定资源的AssetBundle属性标签 &#xff08;1&#xff09;找到AssetBundle属性标签 &#xff08;2&#xff09;A标签 代表&#xff1a;资源目录&#xff08;决定打包之后在哪…

LDO电源模块如何快速设计布局

在现代电子设备遍布的时代&#xff0c;电源模块的设计与应用成为了电子工程领域中的核心议题。而LDO&#xff08;低压差线性稳压器&#xff09;电源模块&#xff0c;因其出色的线性特性和稳定性&#xff0c;在众多应用中备受青睐。为了满足不断增长的电子设备性能需求&#xff…

控价服务商的选择标准

品牌控价旨在对渠道进行有效管控&#xff0c;维护品牌自身价值以及经销商的合法权益&#xff0c;同时也为消费者提供稳定的购物价格。在这一过程中&#xff0c;不但要对线上价格进行把控&#xff0c;线下价格同样需要品牌投入精力去管理。就线上而言&#xff0c;由于链接数量众…

面向对象的进阶---static

1.static 静态变量 package com.itheima.a01staticdemo01;public class Student {private String name;private int age;public static String teacherName;public Student() {}public Student(String name, int age) {this.name name;this.age age;}/*** 获取* return n…

基于单片机的智能台灯控制系统

摘要&#xff1a; 文章设计一款单片机智能台灯控制系统&#xff0c;实现对台灯的手动和自动控制功能&#xff0c;以 STC89C52 单片机作为多功能智能台灯的主控制器&#xff0c;光电检测模块检测坐姿&#xff0c;红外传感器检测人体&#xff0c;光敏电阻检测光强&#xff0c;同…

找不到x3daudio1_7.dll无法运行的原因分析及6种解决方法

当您遇到软件或游戏中提示“x3daudio1_7.dll丢失”的问题时&#xff0c;通常意味着您的系统中缺少这个特定的动态链接库文件。x3daudio1_7.dll 是微软DirectX的一部分&#xff0c;找不到x3daudio1_7.dll会导致软件游戏无法启动运行&#xff0c;下面小编就分享几种靠谱的解决方法…

msvcp120.dll丢失的解决方法,总结几种有效的解决方法

最近&#xff0c;我在使用计算机时遇到了一个问题&#xff0c;系统提示我丢失了msvcp120.dll文件。这让我感到非常困扰&#xff0c;因为这个问题导致我无法正常运行一些程序。经过一番搜索和尝试&#xff0c;我找到了几种修复这个问题的方法&#xff0c;并成功解决了这个问题。…

[数据集][目标检测]斑马线人行横道检测数据集VOC+YOLO格式793张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;793 标注数量(xml文件个数)&#xff1a;793 标注数量(txt文件个数)&#xff1a;793 标注类别…

vue2和vue3分别如何全局引入并使用js

如下js&#xff1a;util/tool.js var tool {nullKeyValueConvertLine(data){if(data && data.length > 0){data.map((item,index)>{for(var key in item){if(!item[key]&&item[key]!0){item[key] -}}})}}, } export default tool 在vue2项目中全局引…

2024上海MWC 参展预告 | 未来先行,解锁数字化新纪元!

一、展会介绍——2024世界移动通信大会 2024年世界移动通信大会上海(MWC上海)将于6月26日至28日在上海新国际博览中心举行。 本届大会以“未来先行(Future First)”为主题聚焦“超越5G”、“数智制“人工智能经济’造”三大热点话题。届时将在包括超级品牌馆(Super Hall)在内…