科大讯飞-群聊对话角色要素提取:不微调范式模拟官网评分

news2024/11/23 11:22:42

不微调范式模拟官网评分

    • step1: 模型api配置及加载测试
    • step2: 数据加载与数据分析:
    • 测试集分析:
    • step3: prompt设计:
    • step4 :大模型推理:
    • step 5: 结果评分测试:
      • 评分细则:
      • 评估指标
  • 参考:

比赛说明:
#AI夏令营 #Datawhale #夏令营
主要参考datawhale夏令营活动:零基础入门大模型技术竞赛。
连接:https://datawhaler.feishu.cn/wiki/VIy8ws47ii2N79kOt9zcXnbXnuS
比赛网址:
https://challenge.xfyun.cn/topic/info?type=role-element-extraction&ch=dw24_y0SCtd
在这里插入图片描述

说明:
- 1,主要适用于不微调的范式。
- 2,针对每次在修改prompt,或者COT之后,想要查看性能如何时,都要提交到官网等待。但是受限于官网每个人每天只能提交3次,无法得到更多的反馈。
- 3,在这里主要从训练集train.json中,随机挑选数据,作为验证集,模仿官网的评分细则,用于验证性能指标。当验证性能满意后,再放到test.json数据进行推理,并提交官网。

步骤:
- 1,模型api配置及加载测试:
- 2,数据加载:加载训练集,数据预处理,数据分析,可设置验证集比例
- 3,prompt设计:提示工程或者COT的方式,根据数据分析设计提示;
- 4,模型推理:输出符合格式预测;
- 5,结果测试:采用与讯飞比赛官网相同的得分计算策略。

为了方便展示,参考群里某大佬画的不微调范式的概要图:
在这里插入图片描述

step1: 模型api配置及加载测试

# api配置

from sparkai.llm.llm import ChatSparkLLM, ChunkPrintHandler
from sparkai.core.messages import ChatMessage
import json

#星火认知大模型Spark3.5 Max的URL值,其他版本大模型URL值请前往文档(https://www.xfyun.cn/doc/spark/Web.html)查看
SPARKAI_URL = 'wss://spark-api.xf-yun.com/v3.5/chat'
#星火认知大模型调用秘钥信息,请前往讯飞开放平台控制台(https://console.xfyun.cn/services/bm35)查看
SPARKAI_APP_ID = ''
SPARKAI_API_SECRET = ''
SPARKAI_API_KEY = ''
#星火认知大模型Spark3.5 Max的domain值,其他版本大模型domain值请前往文档(https://www.xfyun.cn/doc/spark/Web.html)查看
SPARKAI_DOMAIN = 'generalv3.5'
# 模型对话测试

def get_completions(text):
    messages = [ChatMessage(
        role="user",
        content=text
    )]
    spark = ChatSparkLLM(
        spark_api_url=SPARKAI_URL,
        spark_app_id=SPARKAI_APP_ID,
        spark_api_key=SPARKAI_API_KEY,
        spark_api_secret=SPARKAI_API_SECRET,
        spark_llm_domain=SPARKAI_DOMAIN,
        streaming=False,
    )
    handler = ChunkPrintHandler()
    a = spark.generate([messages], callbacks=[handler])
    return a.generations[0][0].text

# 测试模型配置是否正确
text = "你好,请问你是谁?"
get_completions(text)

step2: 数据加载与数据分析:

加载训练集,部分化为验证集,可设置验证集比例

def read_json(json_file_path):
    """读取json文件"""
    with open(json_file_path, 'r') as f:
        data = json.load(f)
    return data

def write_json(json_file_path, data):
    """写入json文件"""
    with open(json_file_path, 'w') as f:
        json.dump(data, f, ensure_ascii=False, indent=4)

# 读取数据
train_data = read_json("dataset/train.json")
print('done!')
# 查看数据格式
print(train_data[1]['chat_text'])
# 简单的数据清洗:将对话的无关信息删除。不要让“[图片]”这种信息干扰;
# 如:[链接],[图片],[玫瑰],以及:????上线功能,H5红包,【收集表】2023年度满意度评价等与内容无关的字段去除掉。
import re

def clean_chat_text(chat_text):
    # 定义正则表达式用于匹配链接、图片、特殊表情和无关字段
    patterns = [
        r"【收集表】 2023年度服务满意度评价",
        r"https?://\S+",
        r"\{[\w\W]*?\}",
        r'\[.*?\]'
    ]

    # 移除匹配到的内容
    for pattern in patterns:
        chat_text = re.sub(pattern, '', chat_text)
    # 移除多余的空格和换行符
    chat_text = re.sub(r'\n+', '\n', chat_text).strip()
    return chat_text

# 遍历每个样本,清洗chat_text字段
for sample in train_data:
    if "chat_text" in sample:
        sample["chat_text"] = clean_chat_text(sample["chat_text"])
# 验证集划分
import json
import random

def split_data(data, validation_size):
    #  # 随机打乱数据
    # random.shuffle(data)
    # 划分数据
    validation_data = data[:validation_size]
    train_data = data[validation_size:]
    
    return train_data, validation_data

validation_size = 50
# 划分数据
train_data, validation_data = split_data(train_data, validation_size)

测试集分析:

训练集数据分析,假设训练集与测试集同分布。
参考:https://qixiangxingqiu.feishu.cn/wiki/V4duwxVzkipnHjk7djzcFykbnbf
这里面进行了详细的数据分析:
要点:

  1. 姓名都是做选择题的,可以先人工提取所有的姓名再让模型做选择;
  2. 很多类别都是多分类任务,如:咨询类型、意向产品、购买异议点、客户购买阶段、客户是否有意向、客户是否有卡点,能出现的都是固定的那几个。
  3. 在训练集中,年龄、生日、竞品信息都是100%为空的,测试集就不确定了。(我猜测也是空)
    在这里插入图片描述
  4. 一些栏目的数据分布:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    咨询类型:
    在这里插入图片描述
    意向产品
    在这里插入图片描述
    购买异议点:
    在这里插入图片描述

step3: prompt设计:

提示工程或者COT的方式;

# prompt 设计
PROMPT_EXTRACT = """
你将获得一段群聊对话记录。你的任务是根据给定的表单格式从对话记录中提取结构化信息。在提取信息时,请确保它与类型信息完全匹配,不要添加任何没有出现在下面模式中的属性。

表单格式如下:
info: Array<Dict(
    "基本信息-姓名": string | "",  // 客户的姓名。
    "基本信息-手机号码": string | "",  // 客户的手机号码。
    "基本信息-邮箱": string | "",  // 客户的电子邮箱地址。
    "基本信息-地区": string | "",  // 客户所在的地区或城市。
    "基本信息-详细地址": string | "",  // 客户的详细地址。
    "基本信息-性别": string | "",  // 客户的性别。
    "基本信息-年龄": string | "",  // 客户的年龄。
    "基本信息-生日": string | "",  // 客户的生日。
    "咨询类型": string[] | [],  // 客户的咨询类型,如询价、答疑等。
    "意向产品": string[] | [],  // 客户感兴趣的产品。
    "购买异议点": string[] | [],  // 客户在购买过程中提出的异议或问题。
    "客户预算-预算是否充足": string | "",  // 客户的预算是否充足。示例:充足, 不充足
    "客户预算-总体预算金额": string | "",  // 客户的总体预算金额。
    "客户预算-预算明细": string | "",  // 客户预算的具体明细。
    "竞品信息": string | "",  // 竞争对手的信息。
    "客户是否有意向": string | "",  // 客户是否有购买意向。示例:有意向, 无意向
    "客户是否有卡点": string | "",  // 客户在购买过程中是否遇到阻碍或卡点。示例:有卡点, 无卡点
    "客户购买阶段": string | "",  // 客户当前的购买阶段,如合同中、方案交流等。
    "下一步跟进计划-参与人": string[] | [],  // 下一步跟进计划中涉及的人员(客服人员)。
    "下一步跟进计划-时间点": string | "",  // 下一步跟进的时间点。
    "下一步跟进计划-具体事项": string | ""  // 下一步需要进行的具体事项。
)>

请分析以下群聊对话记录,并根据上述格式提取信息:

对话记录:
{content}
请将提取的信息以JSON格式输出。
不要添加任何澄清信息。
输出必须遵循上面的模式。
不要添加任何没有出现在模式中的附加字段。
不要随意删除字段。

**输出:**
[{{
    "基本信息-姓名": "姓名",
    "基本信息-手机号码": "手机号码",
    "基本信息-邮箱": "邮箱",
    "基本信息-地区": "地区",
    "基本信息-详细地址": "详细地址",
    "基本信息-性别": "性别",
    "基本信息-年龄": "年龄",
    "基本信息-生日": "生日",
    "咨询类型": ["咨询类型"],
    "意向产品": ["意向产品"],
    "购买异议点": ["购买异议点"],
    "客户预算-预算是否充足": "充足或不充足",
    "客户预算-总体预算金额": "总体预算金额",
    "客户预算-预算明细": "预算明细",
    "竞品信息": "竞品信息",
    "客户是否有意向": "有意向或无意向",
    "客户是否有卡点": "有卡点或无卡点",
    "客户购买阶段": "购买阶段",
    "下一步跟进计划-参与人": ["跟进计划参与人"],
    "下一步跟进计划-时间点": "跟进计划时间点",
    "下一步跟进计划-具体事项": "跟进计划具体事项"
}}]

改进一下:在原来的基础上加上下面这段,根据数据分析得来的。

请分析以下群聊对话记录,并根据上述格式提取信息。根据表单的形式,他们具有不同的提取方式,如下:
1,"基本信息-姓名":直接从对话记录中提取询问问题的人物姓名;
2,"基本信息-手机号码":直接从对话记录中提取询问问题的人的手机号码;
3,"基本信息-邮箱":直接从对话记录中提取询问问题的人的邮箱地址,如果不存在则返回空字符串;
4,"基本信息-地区":直接从对话记录中提取询问问题的人所在的城市或地区;
5,"基本信息-详细地址":直接从对话记录中提取询问问题的人的详细地址,如果不存在则返回空字符串;
5,基本信息-性别":客服的性别,一般是空字符;
6,"基本信息-年龄":尝试提取年龄相关的描述,一般为空字符串;
7,"基本信息-生日":尝试提取生日相关的描述,一般为空字符串;
8,"咨询类型":从对话记录中提取关键信息并判断是下面哪一种:答疑,询价,吐槽,答疑和吐槽;
9,"意向产品":从对话记录中提取客户感兴趣的产品,并从下面选项中选择:会话存档,高级版,CRM,开放接口,商城,标准版,定制版,AI,运营服务,会话存档、标准版。
10,"购买异议点":从对话记录中提取客户在购买过程中提出的问题,并从下面选项中选择:产品功能,客户内部问题,价格,工时,竞品。
11,"客户预算-预算是否充足":从对话记录中提取客户预算是否充足,并从下面选项中选择:充足, 不充足。
12,"客户预算-总体预算金额":从对话记录中提取客户预算的总额,如果存在则返回数字,如果不存在则返回空字符串。
13,"客户预算-预算明细":从对话记录中提取客户预算的具体明细,如果不存在则返回空字符串。
14,"竞品信息":从对话记录中提取竞争对手的信息,如果不存在则返回空字符串,一般是没有竞品信息。
15,"客户是否有意向":从对话记录中提取客户是否有购买意向,并从下面选项中选择:有意向, 无意愿。
16,"客户是否有卡点":从对话记录中提取客户在购买过程中是否遇到阻碍或卡点,并从下面选项中选择:有卡点, 无卡点。
17,"客户购买阶段":从对话记录中提取客户当前的购买阶段,如果客户在购买阶段,则从下面选项中选择:赢单,方案交流,续费,项目搁置,合同中,报价, 需求调研,等待结果, 输单。
18,"下一步跟进计划-参与人":从对话记录中提取下一步跟进计划中涉及的人员(客服人员),如果不存在则返回空字符串。
19,"下一步跟进计划-时间点":从对话记录中提取下一步跟进的时间点,如果不存在则返回空字符串。
20,"下一步跟进计划-具体事项":从对话记录中提取下一步进行的具体事项,如果不存在则返回空字符串。

step4 :大模型推理:

输出符合格式预测;以方便与标签对比;

# 大模型输出格式转换
import json

class JsonFormatError(Exception):
    def __init__(self, message):
        self.message = message
        super().__init__(self.message)

def convert_all_json_in_text_to_dict(text):
    """提取LLM输出文本中的json字符串"""
    dicts, stack = [], []
    for i in range(len(text)):
        if text[i] == '{':
            stack.append(i)
        elif text[i] == '}':
            begin = stack.pop()
            if not stack:
                dicts.append(json.loads(text[begin:i+1]))
    return dicts

# 查看对话标签
def print_json_format(data):
    """格式化输出json格式"""
    print(json.dumps(data, indent=4, ensure_ascii=False))

# 对大模型抽取的结果进行字段格式的检查以及缺少的字段进行补全
def check_and_complete_json_format(data):
    required_keys = {
        "基本信息-姓名": str,
        "基本信息-手机号码": str,
        "基本信息-邮箱": str,
        "基本信息-地区": str,
        "基本信息-详细地址": str,
        "基本信息-性别": str,
        "基本信息-年龄": str,
        "基本信息-生日": str,
        "咨询类型": list,
        "意向产品": list,
        "购买异议点": list,
        "客户预算-预算是否充足": str,
        "客户预算-总体预算金额": str,
        "客户预算-预算明细": str,
        "竞品信息": str,
        "客户是否有意向": str,
        "客户是否有卡点": str,
        "客户购买阶段": str,
        "下一步跟进计划-参与人": list,
        "下一步跟进计划-时间点": str,
        "下一步跟进计划-具体事项": str
    }

    if not isinstance(data, list):
        raise JsonFormatError("Data is not a list")

    for item in data:
        if not isinstance(item, dict):
            raise JsonFormatError("Item is not a dictionary")
        for key, value_type in required_keys.items():
            if key not in item:
                item[key] = [] if value_type == list else ""
            if not isinstance(item[key], value_type):
                raise JsonFormatError(f"Key '{key}' is not of type {value_type.__name__}")
            if value_type == list and not all(isinstance(i, str) for i in item[key]):
                raise JsonFormatError(f"Key '{key}' does not contain all strings in the list")

    return data
# 大模型推理

from tqdm import tqdm

retry_count = 5 # 重试次数
result = []
error_data = []
labels = []

for index, data in tqdm(enumerate(validation_data)):
    index += 1
    is_success = False
    for i in range(retry_count):
        try:
            res = get_completions(PROMPT_EXTRACT.format(content=data["chat_text"]))
            label = data['infos']

            infos = convert_all_json_in_text_to_dict(res)
            infos = check_and_complete_json_format(infos)
            result.append({
                "infos": infos,
                "index": index
            })
            labels.append({
                "infos":label,
                "index": index
            })
            is_success = True
            break
        except Exception as e:
            print("index:", index, ", error:", e)
            continue
    if not is_success:
        data["index"] = index
        error_data.append(data)

step 5: 结果评分测试:

结果测试:采用与讯飞比赛官网相同的得分计算策略。

评分细则:

满分36分。
按照各类字段提取的难易程度,共设置了1、2、3三种难度分数。
具体待提取的字段以及提取正确时的得分规则,如下链接:https://challenge.xfyun.cn/topic/info?type=role-element-extraction&ch=j4XWs7V

评估指标

测试集的每条数据同样包含共21个字段, 按照各字段难易程度划分总计满分36分。每个提取正确性的判定标准如下:
1)对于答案唯一字段,将使用完全匹配的方式计算提取是否正确,提取正确得到相应分数,否则为0分
2)对于答案不唯一字段,将综合考虑提取完整性、语义相似度等维度判定提取的匹配分数,最终该字段得分为 “匹配分数 * 该字段难度分数”
每条测试数据的最终得分为各字段累计得分。最终测试集上的分数为所有测试数据的平均得分。

# 按照给定的评分规则计算每个样本的得分,然后计算所有样本平均得分
import json

# 定义字段及其难度分数,是否单值;
fields = [
    ('基本信息-姓名', 1, True),
    ('基本信息-手机号码', 1, True),
    ('基本信息-邮箱', 1, True),
    ('基本信息-地区', 1, True),
    ('基本信息-详细地址', 1, True),
    ('基本信息-性别', 1, True),
    ('基本信息-年龄', 1, True),
    ('基本信息-生日', 1, True),
    ('咨询类型', 2, False),
    ('意向产品', 3, False),
    ('购买异议点', 3, False),
    ('客户预算-预算是否充足', 2, True),
    ('客户预算-总体预算金额', 2, True),
    ('客户预算-预算明细', 3, True),
    ('竞品信息', 2, True),
    ('客户是否有意向', 1, True),
    ('客户是否有卡点', 1, True),
    ('客户购买阶段', 2, True),
    ('下一步跟进计划-参与人', 2, False),
    ('下一步跟进计划-时间点', 2, True),
    ('下一步跟进计划-具体事项', 3, True)
]
from difflib import SequenceMatcher

# 计算单值字段得分
def calculate_single_value_score(pred, true, score):
    return score if pred == true else 0

# 计算文本相似度得分
def calculate_text_similarity_score(pred, true):
    return SequenceMatcher(None, pred, true).ratio()

# 计算多值字段的得分
def calculate_multi_value_score(pred, true, score):
    if isinstance(pred, list) and isinstance(true, list):
        pred_str = ' '.join(pred)
        true_str = ' '.join(true)
    else:
        pred_str = str(pred)
        true_str = str(true)
    
    similarity_score = calculate_text_similarity_score(pred_str, true_str)
    return similarity_score * score

# 计算样本得分
def calculate_sample_score(pred, true):
    total_score = 0
    for field, score, is_single_value in fields:
        pred_value = pred.get(field, "")
        true_value = true.get(field, "")
        
        if is_single_value:
            total_score += calculate_single_value_score(pred_value, true_value, score)
        else:
            total_score += calculate_multi_value_score(pred_value, true_value, score)
    return total_score

# 
# 计算平均得分
def calculate_average_score(predictions, truths):
    total_score = 0
    num_samples = len(predictions)
    

    for i in range(num_samples):
        pred = predictions[i]
        true = truths[i]
        if not pred['infos'] or not true['infos']:
            continue
        # print(pred)
        total_score += calculate_sample_score(pred['infos'][0], true['infos'][0])

    # for pred, true in zip(predictions, truths):
    #     total_score += calculate_sample_score(pred['infos'][0], true['infos'][0])
    
    return total_score / num_samples
# 计算
average_score = calculate_average_score(result, labels)

print("average score:", average_score)

计算得分是21分:
在这里插入图片描述

官网评分:20分,感觉相差3分以内吧。
模拟官网的评分策略还是需要优化的。
在这里插入图片描述

参考:

datawhale夏令营活动:
https://datawhaler.feishu.cn/wiki/VIy8ws47ii2N79kOt9zcXnbXnuS

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

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

相关文章

从打印到监测:纳米生物墨水助力3D生物打印与组织监测平台?

从打印到监测&#xff1a;纳米生物墨水助力3D生物打印与组织监测平台&#xff1f; 在 3D 组织工程中&#xff0c;纳米生物墨水是将纳米材料与 ECM 水凝胶结合&#xff0c;以提高其打印性和功能性的重要策略。纳米生物墨水可以增强水凝胶的机械性能、导电性、生物活性&#xff…

【Transformer】transformer模型结构学习笔记

文章目录 1. transformer架构2. transformer子层解析3. transformer注意力机制4. transformer部分释疑 图1 transformer模型架构 图2 transformer主要模块简介 图3 encoder-decoder示意图N6 图4 encoder-decoder子层示意图 1. transformer架构 encoder-decoder框架是一种处理NL…

卷积神经网络基础篇

文章目录 1、卷积层1.1、激活函数1.3、sigmoid1.4、Tanh1.5、ReLU1.6、Leaky ReLU1.7、误差计算 2、池化层3、全连接层4、CNN训练 参考链接1 参考链接2 1、卷积层 卷积层&#xff08;Convolutional layer&#xff09;&#xff0c;这一层就是卷积神经网络最重要的一个层次&…

数据库的学习(4)

一、题目 1、创建数据表qrade: CREATE TABLE grade(id INT NOT NULL,sex CHAR(1),firstname VARCHAR(20)NOT NULL,lastname VARCHAR(20)NOT NULL,english FLOAT,math FLOAT,chinese FLOAT ); 2、向数据表grade中插入几条数据: (3,mAllenwiiliam,88.0,92.0 95.0), (4,m,George&…

java版企业工程管理系统源码:全方位的项目管理解决方案

工程管理系统是一款专注于建设工程项目全生命周期管理的软件。它覆盖了项目从策划、设计、施工到竣工的每一个阶段&#xff0c;提供全方位的管理功能。系统采用模块化设计&#xff0c;包括系统管理、系统设置、项目管理、合同管理、预警管理、竣工管理、质量管理、统计报表和工…

centos7.9 rpm包安装mysql8.2.0数据库、root设置客户端登录、配置并发、表名大小写敏感、启动重启指令等记录

centos安装mysql8数据库,下载的是rpm-bundle.tar包,这样可以在内网环境离线安装,工作中医院的服务器很多也是内网的,所以这里记录下rpm-bundle.tar包安装的步骤。 lscpu 查看处理器是x86还是arm 下载对应的版本 bundle tar包 ((mysql-8.2.0-1.el7.x86_64.rpm-bundle.tar))…

打造属于你的私人云盘:在 OrangePi AIpro 上搭建个人云盘

随着数字化时代的到来&#xff0c;数据的存储和管理变得愈发重要。相比于公共云存储服务&#xff0c;搭建一个属于自己的个人云盘不仅能够更好地保护隐私&#xff0c;还可以更灵活地管理数据。 近期刚好收到了一个 香橙派 AIpro 的开发板&#xff0c;借此机会用来搭建一个属于…

《算法笔记》总结No.4——散列

散列的英文名是hash&#xff0c;即我们常说的哈希~该知识点在王道408考研的教材里面属于查找的范围。即便各位并无深入了解过&#xff0c;也听说过散列是一种更高效的查找方法。 一.引例 先来考虑如下一个假设&#xff1a;设有数组M和N分别如下&#xff1a; M[10][1,2,3,4,5,6…

idea 默认路径修改

1.查看 idea 的安装路径&#xff08;右键点击 idea 图标&#xff0c;查看路径 &#xff09; “C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin\idea64.exe” 在 bin 目录查看 idea.properties 文件&#xff0c;修改以下四个路径文件 # idea.config.path${user.home}/…

对话大模型Prompt是否需要礼貌点?

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 基于Dify的QA数据集构建&#xff08;附代码&#xff09;Qwen-2-7B和GLM-4-9B&#x…

QT入门笔记-自定义控件封装 30

具体代码如下: QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 …

uni-app使用ucharts地图,自定义Tooltip鼠标悬浮显示内容并且根据@getIndex点击事件获取点击的地区下标和地区名

项目场景&#xff1a; uni-app使用ucharts地图,自定义Tooltip鼠标悬浮显示内容并且根据getIndex点击事件获取点击的地区下标和地区名 例如&#xff1a; 问题描述 官方给的文档有限&#xff0c;需要自己下载地图json数据然后自己渲染和编写鼠标悬浮显示内容以及获取点击地址…

【ComfyUI节点】扰动注意力引导Perturbed Attention Guidance

扰动注意力引导 Perturbed Attention Guidance GitHub - KU-CVLAB/Perturbed-Attention-Guidance: Official implementation of "Perturbed-Attention Guidance" 按照官方介绍&#xff0c;扰动注意力指导显著提高了扩散模型的样本质量&#xff0c;而无需外部条件&am…

代码随想录第45天|动态规划

300.最长递增子序列 参考 dp[i] 表示以 i 为结尾的最长递增子序列长度递推公式: 使用 i 和 j 判断 dp[i] max(dp[j] 1, dp[i])每次 j 都需要从头遍历 初始化: dp[i] 1 class Solution { public:int lengthOfLIS(vector<int>& nums) {vector<int> dp(nums…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【明文导入密钥(C/C++)】

明文导入密钥(C/C) 以明文导入ECC密钥为例。具体的场景介绍及支持的算法规格 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 指定密钥别名keyAlias。 密钥别名的最大长度为64字节。 封装密钥属性集和密钥材料。通过[OH_Huks_I…

实现antd designable平台的组件拖拽功能

平台&#xff1a;designable设计器 github&#xff1a;designable 目录 1 背景2 技术栈3 组件拖拽和放置3.1 类型定义3.2 拖拽3.3 放置 1 背景 由于业务需求&#xff0c;我们需要实现designable平台的一个简易版的组件拖拽功能。 #mermaid-svg-QrxSDGe9YyGG3LbQ {font-family:…

andboxie-Plus - 知名沙盒软件、支持游戏多开测试软件

我们经常会需要用到一些毒瘤软件——它们可能不是真正的恶意软件&#xff0c;但总爱偷摸干一些流氓行为。 工作中&#xff0c;有时还不得不安装使用一些来路不明、不能完全信任的可疑软件。 装上吧&#xff0c;心里膈应、难受&#xff1b;不装吧&#xff0c;有些工作又进行不…

SQLite 嵌入式数据库

目录&#xff1a; 一、SQLite 简介二、SQLite 数据库安装1、安装方式一&#xff1a;2、安装方式二&#xff1a; 三、SQLite 的命令用法1、创建、打开、退出数据库&#xff1a;2、编辑数据库&#xff1a; 四、SQLite 的编程操作1、打开 / 创建数据库的 C 接口&#xff1a;2、操作…

【数据结构与算法】快速排序双指针法

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​

工程文件参考——CubeMX+LL库+SPI主机 阻塞式通用库

文章目录 前言CubeMX配置SPI驱动实现spi_driver.hspi_driver.c 额外的接口补充 前言 SPI&#xff0c;想了很久没想明白其DMA或者IT比较好用的方法&#xff0c;可能之后也会写一个 我个人使用场景大数据流不多&#xff0c;如果是大批量数据交互自然是DMA更好用&#xff0c;但考…