#LLM入门|Prompt#2.9_评估、自动化测试效果(上)——存在一个简单的正确答案时(Evaluation-part1)

在构建基于LLM的应用程序后,我们需要评估其运行状况并持续优化回答质量。评估LLM输出的最佳实践包括逐步建立测试样例集合,调整Prompt以在小样本上起效,并添加难以处理的例子进行测试。
与传统的监督学习应用程序不同,基于LLM的应用程序不需要收集大量的训练样本,因为可以在几分钟内定义Prompt并在几小时内得到结果。因此,我们可以通过在一到三个样本的小样本中调整Prompt来逐步改进系统性能。如果遇到无法解决的棘手例子,我们可以将这些例子添加到测试集中,并开发衡量性能的指标,如平均准确度。
值得注意的是,对于一些高风险的应用,如存在偏见或不适当的输出可能对某人造成伤害的情况,收集测试集、严格评估系统性能以及确保在使用前能够正确处理事情尤为重要。对于仅用于个人阅读总结的应用,风险较小,可以在早期阶段停止改进,并避免收集大规模数据集的代价。
在进入实际应用阶段时,我们可以使用真实数据并利用工具进行分析。例如,在我们的案例中,我们获取了一组分类信息及其产品名称,可以使用LLM来进行分析。下面是一个示例代码来查看这些分类信息及其产品名称。

import utils_zh

products_and_category = utils_zh.get_products_and_category()
products_and_category
{'电脑和笔记本': ['TechPro 超极本',
  'BlueWave 游戏本',
  'PowerLite Convertible',
  'TechPro Desktop',
  'BlueWave Chromebook'],
 '智能手机和配件': ['SmartX ProPhone'],
 '专业手机': ['MobiTech PowerCase',
  'SmartX MiniPhone',
  'MobiTech Wireless Charger',
  'SmartX EarBuds'],
 '电视和家庭影院系统': ['CineView 4K TV',
  'SoundMax Home Theater',
  'CineView 8K TV',
  'SoundMax Soundbar',
  'CineView OLED TV'],
 '游戏机和配件': ['GameSphere X',
  'ProGamer Controller',
  'GameSphere Y',
  'ProGamer Racing Wheel',
  'GameSphere VR Headset'],
 '音频设备': ['AudioPhonic Noise-Canceling Headphones',
  'WaveSound Bluetooth Speaker',
  'AudioPhonic True Wireless Earbuds',
  'WaveSound Soundbar',
  'AudioPhonic Turntable'],
 '相机和摄像机': ['FotoSnap DSLR Camera',
  'ActionCam 4K',
  'FotoSnap Mirrorless Camera',
  'ZoomMaster Camcorder',
  'FotoSnap Instant Camera']}

一、找出相关产品和类别名称

在我们进行开发时,通常需要处理和解析用户的输入。特别是在电商领域,可能会有各种各样的用户查询,例如:“我想要最贵的电脑”。我们需要一个能理解这种语境,并能给出相关产品和类别的工具。下面这段代码实现的功能就是这样。
首先我们定义了一个函数find_category_and_product_v1从用户的输入中解析出产品和类别。这个函数需要两个参数:user_input代表用户的查询,products_and_category是一个字典,其中包含了产品类型和对应产品的信息。
在函数的开始,我们定义了一个分隔符delimiter,用来在客户服务查询中分隔内容。随后,我们创建了一条系统消息。这条消息主要解释了系统的运作方式:用户会提供客户服务查询,查询会被分隔符delimiter分隔。系统会输出一个Python列表,列表中的每个对象都是Json对象。每个对象会包含’类别’和’名称’两个字段,分别对应产品的类别和名称。
我们创建了一个名为messages的列表,用来存储这些示例对话以及用户的查询。最后,我们使用get_completion_from_messages函数处理这些消息,返回处理结果。
通过这段代码,我们可以看到如何通过对话的方式理解和处理用户的查询,以提供更好的用户体验。

from tool import get_completion_from_messages

def find_category_and_product_v1(user_input,products_and_category):
    """
    从用户输入中获取到产品和类别

    参数:
    user_input:用户的查询
    products_and_category:产品类型和对应产品的字典
    """
    
    delimiter = "####"
    system_message = f"""
    您将提供客户服务查询。\
    客户服务查询将用{delimiter}字符分隔。
    输出一个 Python 列表,列表中的每个对象都是 Json 对象,每个对象的格式如下:
        '类别': <电脑和笔记本, 智能手机和配件, 电视和家庭影院系统, \
    游戏机和配件, 音频设备, 相机和摄像机中的一个>,
    以及
        '名称': <必须在下面允许的产品中找到的产品列表>
    
    其中类别和产品必须在客户服务查询中找到。
    如果提到了一个产品,它必须与下面允许的产品列表中的正确类别关联。
    如果没有找到产品或类别,输出一个空列表。
    
    根据产品名称和产品类别与客户服务查询的相关性,列出所有相关的产品。
    不要从产品的名称中假设任何特性或属性,如相对质量或价格。
    
    允许的产品以 JSON 格式提供。
    每个项目的键代表类别。
    每个项目的值是该类别中的产品列表。
    允许的产品:{products_and_category}
    
    """
    
    few_shot_user_1 = """我想要最贵的电脑。"""
    few_shot_assistant_1 = """ 
    [{'category': '电脑和笔记本', \
'products': ['TechPro 超极本', 'BlueWave 游戏本', 'PowerLite Convertible', 'TechPro Desktop', 'BlueWave Chromebook']}]
    """
    
    messages =  [  
    {'role':'system', 'content': system_message},    
    {'role':'user', 'content': f"{delimiter}{few_shot_user_1}{delimiter}"},  
    {'role':'assistant', 'content': few_shot_assistant_1 },
    {'role':'user', 'content': f"{delimiter}{user_input}{delimiter}"},  
    ] 
    return get_completion_from_messages(messages)

二、在一些查询上进行评估

对上述系统,我们可以首先在一些简单查询上进行评估:

# 第一个评估的查询
customer_msg_0 = f"""如果我预算有限,我可以买哪款电视?"""

products_by_category_0 = find_category_and_product_v1(customer_msg_0,
                                                      products_and_category)
print(products_by_category_0)
[{'category': '电视和家庭影院系统', 'products': ['CineView 4K TV', 'SoundMax Home Theater', 'CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV']}]

输出了正确回答。

customer_msg_1 = f"""我需要一个智能手机的充电器"""

products_by_category_1 = find_category_and_product_v1(customer_msg_1,
                                                      products_and_category)
print(products_by_category_1)
[{'category': '智能手机和配件', 'products': ['MobiTech PowerCase', 'SmartX MiniPhone', 'MobiTech Wireless Charger', 'SmartX EarBuds']}]

输出了正确回答。

customer_msg_2 = f"""
你们有哪些电脑?"""

products_by_category_2 = find_category_and_product_v1(customer_msg_2,
                                                      products_and_category)
products_by_category_2

" \n [{‘category’: ‘电脑和笔记本’, ‘products’: [‘TechPro 超极本’, ‘BlueWave 游戏本’, ‘PowerLite Convertible’, ‘TechPro Desktop’, ‘BlueWave Chromebook’]}]"
输出回答正确,但格式有误。

customer_msg_3 = f"""
告诉我关于smartx pro手机和fotosnap相机的信息,那款DSLR的。
我预算有限,你们有哪些性价比高的电视推荐?"""

products_by_category_3 = find_category_and_product_v1(customer_msg_3,
                                                      products_and_category)
print(products_by_category_3)
[{'category': '智能手机和配件', 'products': ['SmartX ProPhone']}, {'category': '相机和摄像机', 'products': ['FotoSnap DSLR Camera']}]
    
    [{'category': '电视和家庭影院系统', 'products': ['CineView 4K TV', 'SoundMax Home Theater', 'CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV']}]

它看起来像是输出了正确的数据,但没有按照要求的格式输出。这使得将其解析为 Python 字典列表更加困难。

三、更难的测试用例

接着,我们可以给出一些在实际使用中,模型表现不如预期的查询。

customer_msg_4 = f"""
告诉我关于CineView电视的信息,那款8K的,还有Gamesphere游戏机,X款的。我预算有限,你们有哪些电脑?"""

products_by_category_4 = find_category_and_product_v1(customer_msg_4,products_and_category)
print(products_by_category_4)
[{'category': '电视和家庭影院系统', 'products': ['CineView 4K TV', 'SoundMax Home Theater', 'CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV']}]
    [{'category': '游戏机和配件', 'products': ['GameSphere X', 'ProGamer Controller', 'GameSphere Y', 'ProGamer Racing Wheel', 'GameSphere VR Headset']}]
    [{'category': '电脑和笔记本', 'products': ['TechPro 超极本', 'BlueWave 游戏本', 'PowerLite Convertible', 'TechPro Desktop', 'BlueWave Chromebook']}]

四、修改指令以处理难测试用例

综上,我们实现的最初版本在上述一些测试用例中表现不尽如人意。
为提升效果,我们在提示中添加了以下内容:不要输出任何不在 JSON 格式中的附加文本,并添加了第二个示例,使用用户和助手消息进行 few-shot 提示。

def find_category_and_product_v2(user_input,products_and_category):
    """
    从用户输入中获取到产品和类别

    添加:不要输出任何不符合 JSON 格式的额外文本。
    添加了第二个示例(用于 few-shot 提示),用户询问最便宜的计算机。
    在这两个 few-shot 示例中,显示的响应只是 JSON 格式的完整产品列表。

    参数:
    user_input:用户的查询
    products_and_category:产品类型和对应产品的字典    
    """
    delimiter = "####"
    system_message = f"""
    您将提供客户服务查询。\
    客户服务查询将用{delimiter}字符分隔。
    输出一个 Python列表,列表中的每个对象都是 JSON 对象,每个对象的格式如下:
        '类别': <电脑和笔记本, 智能手机和配件, 电视和家庭影院系统, \
    游戏机和配件, 音频设备, 相机和摄像机中的一个>,
    以及
        '名称': <必须在下面允许的产品中找到的产品列表>
    不要输出任何不是 JSON 格式的额外文本。
    输出请求的 JSON 后,不要写任何解释性的文本。
    
    其中类别和产品必须在客户服务查询中找到。
    如果提到了一个产品,它必须与下面允许的产品列表中的正确类别关联。
    如果没有找到产品或类别,输出一个空列表。
    
    根据产品名称和产品类别与客户服务查询的相关性,列出所有相关的产品。
    不要从产品的名称中假设任何特性或属性,如相对质量或价格。
    
    允许的产品以 JSON 格式提供。
    每个项目的键代表类别。
    每个项目的值是该类别中的产品列表。
    允许的产品:{products_and_category}
    
    """
    
    few_shot_user_1 = """我想要最贵的电脑。你推荐哪款?"""
    few_shot_assistant_1 = """ 
    [{'category': '电脑和笔记本', \
'products': ['TechPro 超极本', 'BlueWave 游戏本', 'PowerLite Convertible', 'TechPro Desktop', 'BlueWave Chromebook']}]
     """
    
    few_shot_user_2 = """我想要最便宜的电脑。你推荐哪款?"""
    few_shot_assistant_2 = """ 
    [{'category': '电脑和笔记本', \
'products': ['TechPro 超极本', 'BlueWave 游戏本', 'PowerLite Convertible', 'TechPro Desktop', 'BlueWave Chromebook']}]
    """
    
    messages =  [  
    {'role':'system', 'content': system_message},    
    {'role':'user', 'content': f"{delimiter}{few_shot_user_1}{delimiter}"},  
    {'role':'assistant', 'content': few_shot_assistant_1 },
    {'role':'user', 'content': f"{delimiter}{few_shot_user_2}{delimiter}"},  
    {'role':'assistant', 'content': few_shot_assistant_2 },
    {'role':'user', 'content': f"{delimiter}{user_input}{delimiter}"},  
    ] 
    return get_completion_from_messages(messages)

五、在难测试用例上评估修改后的指令

我们可以在之前表现不如预期的较难测试用例上评估改进后系统的效果:

customer_msg_3 = f"""
告诉我关于smartx pro手机和fotosnap相机的信息,那款DSLR的。
另外,你们有哪些电视?"""

products_by_category_3 = find_category_and_product_v2(customer_msg_3,
                                                      products_and_category)
print(products_by_category_3)
[{'category': '智能手机和配件', 'products': ['SmartX ProPhone']}, {'category': '相机和摄像机', 'products': ['FotoSnap DSLR Camera', 'ActionCam 4K', 'FotoSnap Mirrorless Camera', 'ZoomMaster Camcorder', 'FotoSnap Instant Camera']}, {'category': '电视和家庭影院系统', 'products': ['CineView 4K TV', 'SoundMax Home Theater', 'CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV']}]
    

六、回归测试:验证模型在以前的测试用例上仍然有效

检查并修复模型以提高难以测试的用例效果,同时确保此修正不会对先前的测试用例性能造成负面影响。

customer_msg_0 = f"""如果我预算有限,我可以买哪款电视?"""

products_by_category_0 = find_category_and_product_v2(customer_msg_0,
                                                      products_and_category)
print(products_by_category_0)
[{'category': '电视和家庭影院系统', 'products': ['CineView 4K TV', 'SoundMax Home Theater', 'CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV']}]

七、收集开发集进行自动化测试

当我们的应用程序逐渐成熟,测试的重要性也随之增加。通常,当我们仅处理少量样本,手动运行测试并对结果进行评估是可行的。然而,随着开发集的增大,这种方法变得既繁琐又低效。此时,就需要引入自动化测试来提高我们的工作效率。下面将开始编写代码来自动化测试流程,可以帮助您提升效率并确保测试的准确率。
以下是一些用户问题的标准答案,用于评估 LLM 回答的准确度,与机器学习中的验证集的作用相当。

msg_ideal_pairs_set = [
    
    # eg 0
    {'customer_msg':"""如果我预算有限,我可以买哪种电视?""",
     'ideal_answer':{
        '电视和家庭影院系统':set(
            ['CineView 4K TV', 'SoundMax Home Theater', 'CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV']
        )}
    },

    # eg 1
    {'customer_msg':"""我需要一个智能手机的充电器""",
     'ideal_answer':{
        '智能手机和配件':set(
            ['MobiTech PowerCase', 'MobiTech Wireless Charger', 'SmartX EarBuds']
        )}
    },
    # eg 2
    {'customer_msg':f"""你有什么样的电脑""",
     'ideal_answer':{
           '电脑和笔记本':set(
               ['TechPro 超极本', 'BlueWave 游戏本', 'PowerLite Convertible', 'TechPro Desktop', 'BlueWave Chromebook'
               ])
                }
    },

    # eg 3
    {'customer_msg':f"""告诉我关于smartx pro手机和fotosnap相机的信息,那款DSLR的。\
另外,你们有哪些电视?""",
     'ideal_answer':{
        '智能手机和配件':set(
            ['SmartX ProPhone']),
        '相机和摄像机':set(
            ['FotoSnap DSLR Camera']),
        '电视和家庭影院系统':set(
            ['CineView 4K TV', 'SoundMax Home Theater','CineView 8K TV', 'SoundMax Soundbar', 'CineView OLED TV'])
        }
    }, 
    
    # eg 4
    {'customer_msg':"""告诉我关于CineView电视,那款8K电视、\
     Gamesphere游戏机和X游戏机的信息。我的预算有限,你们有哪些电脑?""",
     'ideal_answer':{
        '电视和家庭影院系统':set(
            ['CineView 8K TV']),
        '游戏机和配件':set(
            ['GameSphere X']),
        '电脑和笔记本':set(
            ['TechPro Ultrabook', 'BlueWave Gaming Laptop', 'PowerLite Convertible', 'TechPro Desktop', 'BlueWave Chromebook'])
        }
    },
    
    # eg 5
    {'customer_msg':f"""你们有哪些智能手机""",
     'ideal_answer':{
           '智能手机和配件':set(
               ['SmartX ProPhone', 'MobiTech PowerCase', 'SmartX MiniPhone', 'MobiTech Wireless Charger', 'SmartX EarBuds'
               ])
                    }
    },
    # eg 6
    {'customer_msg':f"""我预算有限。你能向我推荐一些智能手机吗?""",
     'ideal_answer':{
        '智能手机和配件':set(
            ['SmartX EarBuds', 'SmartX MiniPhone', 'MobiTech PowerCase', 'SmartX ProPhone', 'MobiTech Wireless Charger']
        )}
    },

    # eg 7 # this will output a subset of the ideal answer
    {'customer_msg':f"""有哪些游戏机适合我喜欢赛车游戏的朋友?""",
     'ideal_answer':{
        '游戏机和配件':set([
            'GameSphere X',
            'ProGamer Controller',
            'GameSphere Y',
            'ProGamer Racing Wheel',
            'GameSphere VR Headset'
     ])}
    },
    # eg 8
    {'customer_msg':f"""送给我摄像师朋友什么礼物合适?""",
     'ideal_answer': {
        '相机和摄像机':set([
        'FotoSnap DSLR Camera', 'ActionCam 4K', 'FotoSnap Mirrorless Camera', 'ZoomMaster Camcorder', 'FotoSnap Instant Camera'
        ])}
    },
    
    # eg 9
    {'customer_msg':f"""我想要一台热水浴缸时光机""",
     'ideal_answer': []
    }
    
]

八、通过与理想答案比较来评估测试用例

我们通过以下函数eval_response_with_ideal来评估 LLM 回答的准确度,该函数通过将 LLM 回答与理想答案进行比较来评估系统在测试用例上的效果。

import json
def eval_response_with_ideal(response,
                              ideal,
                              debug=False):
    """
    评估回复是否与理想答案匹配
    
    参数:
    response: 回复的内容
    ideal: 理想的答案
    debug: 是否打印调试信息
    """
    if debug:
        print("回复:")
        print(response)
    
    # json.loads() 只能解析双引号,因此此处将单引号替换为双引号
    json_like_str = response.replace("'",'"')
    
    # 解析为一系列的字典
    l_of_d = json.loads(json_like_str)
    
    # 当响应为空,即没有找到任何商品时
    if l_of_d == [] and ideal == []:
        return 1
    
    # 另外一种异常情况是,标准答案数量与回复答案数量不匹配
    elif l_of_d == [] or ideal == []:
        return 0
    
    # 统计正确答案数量
    correct = 0    
    
    if debug:
        print("l_of_d is")
        print(l_of_d)

    # 对每一个问答对  
    for d in l_of_d:

        # 获取产品和目录
        cat = d.get('category')
        prod_l = d.get('products')
        # 有获取到产品和目录
        if cat and prod_l:
            # convert list to set for comparison
            prod_set = set(prod_l)
            # get ideal set of products
            ideal_cat = ideal.get(cat)
            if ideal_cat:
                prod_set_ideal = set(ideal.get(cat))
            else:
                if debug:
                    print(f"没有在标准答案中找到目录 {cat}")
                    print(f"标准答案: {ideal}")
                continue
                
            if debug:
                print("产品集合:\n",prod_set)
                print()
                print("标准答案的产品集合:\n",prod_set_ideal)

            # 查找到的产品集合和标准的产品集合一致
            if prod_set == prod_set_ideal:
                if debug:
                    print("正确")
                correct +=1
            else:
                print("错误")
                print(f"产品集合: {prod_set}")
                print(f"标准的产品集合: {prod_set_ideal}")
                if prod_set <= prod_set_ideal:
                    print("回答是标准答案的一个子集")
                elif prod_set >= prod_set_ideal:
                    print("回答是标准答案的一个超集")

    # 计算正确答案数
    pc_correct = correct / len(l_of_d)
        
    return pc_correct

我们使用上述测试用例中的一个进行测试,首先看一下标准回答:

print(f'用户提问: {msg_ideal_pairs_set[7]["customer_msg"]}')
print(f'标准答案: {msg_ideal_pairs_set[7]["ideal_answer"]}')
用户提问: 有哪些游戏机适合我喜欢赛车游戏的朋友?
标准答案: {'游戏机和配件': {'ProGamer Racing Wheel', 'ProGamer Controller', 'GameSphere Y', 'GameSphere VR Headset', 'GameSphere X'}}

再对比 LLM 回答,并使用验证函数进行评分:

response = find_category_and_product_v2(msg_ideal_pairs_set[7]["customer_msg"],
                                         products_and_category)
print(f'回答: {response}')

eval_response_with_ideal(response,msg_ideal_pairs_set[7]["ideal_answer"])
回答:  
    [{'category': '游戏机和配件', 'products': ['GameSphere X', 'ProGamer Controller', 'GameSphere Y', 'ProGamer Racing Wheel', 'GameSphere VR Headset']}]
    





1.0

可见该验证函数的打分是准确的。

九、在所有测试用例上运行评估,并计算正确的用例比例

下面我们来对测试用例中的全部问题进行验证,并计算 LLM 回答正确的准确率
注意:如果任何 API 调用超时,将无法运行

import time

score_accum = 0
for i, pair in enumerate(msg_ideal_pairs_set):
    time.sleep(20)
    print(f"示例 {i}")
    
    customer_msg = pair['customer_msg']
    ideal = pair['ideal_answer']
    
    # print("Customer message",customer_msg)
    # print("ideal:",ideal)
    response = find_category_and_product_v2(customer_msg,
                                                      products_and_category)

    
    # print("products_by_category",products_by_category)
    score = eval_response_with_ideal(response,ideal,debug=False)
    print(f"{i}: {score}")
    score_accum += score
    

n_examples = len(msg_ideal_pairs_set)
fraction_correct = score_accum / n_examples
print(f"正确比例为 {n_examples}: {fraction_correct}")
示例 0
0: 1.0
示例 1
错误
产品集合: {'SmartX ProPhone'}
标准的产品集合: {'MobiTech Wireless Charger', 'SmartX EarBuds', 'MobiTech PowerCase'}
1: 0.0
示例 2
2: 1.0
示例 3
3: 1.0
示例 4
错误
产品集合: {'SoundMax Home Theater', 'CineView 8K TV', 'CineView 4K TV', 'CineView OLED TV', 'SoundMax Soundbar'}
标准的产品集合: {'CineView 8K TV'}
回答是标准答案的一个超集
错误
产品集合: {'ProGamer Racing Wheel', 'ProGamer Controller', 'GameSphere Y', 'GameSphere VR Headset', 'GameSphere X'}
标准的产品集合: {'GameSphere X'}
回答是标准答案的一个超集
错误
产品集合: {'TechPro 超极本', 'TechPro Desktop', 'BlueWave Chromebook', 'PowerLite Convertible', 'BlueWave 游戏本'}
标准的产品集合: {'TechPro Desktop', 'BlueWave Chromebook', 'TechPro Ultrabook', 'PowerLite Convertible', 'BlueWave Gaming Laptop'}
4: 0.0
示例 5
错误
产品集合: {'SmartX ProPhone'}
标准的产品集合: {'MobiTech Wireless Charger', 'SmartX EarBuds', 'SmartX MiniPhone', 'SmartX ProPhone', 'MobiTech PowerCase'}
回答是标准答案的一个子集
5: 0.0
示例 6
错误
产品集合: {'SmartX ProPhone'}
标准的产品集合: {'MobiTech Wireless Charger', 'SmartX EarBuds', 'SmartX MiniPhone', 'SmartX ProPhone', 'MobiTech PowerCase'}
回答是标准答案的一个子集
6: 0.0
示例 7
7: 1.0
示例 8
8: 1.0
示例 9
9: 1
正确比例为 10: 0.6

使用 Prompt 构建应用程序的工作流程与使用监督学习构建应用程序的工作流程非常不同。因此,我们认为这是需要记住的一件好事,当您正在构建监督学习模型时,会感觉到迭代速度快了很多。
如果您并未亲身体验,可能会惊叹于仅有手动构建的极少样本,就可以产生高效的评估方法。您可能会认为,仅有 10 个样本是不具备统计意义的。但当您真正运用这种方式时,您可能会对向开发集中添加一些复杂样本所带来的效果提升感到惊讶。这对于帮助您和您的团队找到有效的 Prompt 和有效的系统非常有帮助。
在本章中,输出可以被定量评估,就像有一个期望的输出一样,您可以判断它是否给出了这个期望的输出。在下一章中,我们将探讨如何在更加模糊的情况下评估我们的输出。即正确答案可能不那么明确的情况。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python 基础知识点(蓝桥杯python科目个人复习计划61)

今日复习内容&#xff1a;想到什么复习什么 因为比赛用到的编辑器是IDLE&#xff0c;所以从现在开始&#xff0c;我就不用pycharm了。 例题1&#xff1a; 从1到2020的所有数字中&#xff0c;有多少个2&#xff1f; 这个题是一个填空题&#xff0c;我用的方法是先在编辑器上…

Unity ShaderGraph实现地面积水效果

先看看效果 右侧参数&#xff0c;能够控制水高&#xff0c;波纹的速度等&#xff0c;但是这个效果需要修改高度图和凹凸图&#xff0c;毕竟有些模型并不是平面&#xff0c;对于具有斜面的模型就需要修改贴图。 ShaderGraph如下

【Java Web】秒懂CSS样式!

目录 一、CSS的使用 二、CSS引用方式 三、CSS三大选择器 四、CSS浮动 五、CSS定位 六、CSS盒子模型 一、CSS的使用 css层叠样式表能够对网页中标签元素位置的排版进行像素级别的精确控制&#xff0c;支持几乎所有的字体和字号样式&#xff0c;拥有对网页对象和模型的样式…

一 windso10 笔记本刷linux cent os7.9系统

1:准备材料 16G以上U盘, 笔记本一台 镜像选了阿里云镜像:centos-7-isos-x86_64安装包下载_开源镜像站-阿里云 软件:链接&#xff1a;https://pan.baidu.com/s/13WDp2bBU1Pdx4gRDfmBetg 提取码&#xff1a;09s3 2:把镜像写入U盘,本人已经写入好了,选择镜像,点开始就是,确定等…

基于php的用户登录实现(v2版)(持续迭代)

目录 版本说明 数据库连接 登录页面&#xff1a;login.html 登录处理实现&#xff1a;login.php 用户欢迎页面&#xff1a;welcome.php 密码修改页面&#xff1a;change_password.html 修改执行&#xff1a;change_password.php 用户注册页面&#xff1a;register.html …

WebGPU vs. 像素流

在构建 Bzar 之前&#xff0c;我们讨论过我们的技术栈是基于在云上渲染内容的像素流&#xff0c;还是基于使用设备自身计算能力的本地渲染技术。 由于这种选择会极大地影响项目的成本、可扩展性和用户体验&#xff0c;因此在开始编写一行代码之前&#xff0c;从一开始就采取正确…

C语言指针、数组学习记录

指针 指针是什么 数据在内存中存放的方式 声明一个变量int i 3;&#xff0c;那么在内存中就会分配一个大小为4字节&#xff08;因为int类型占4字节&#xff09;的内存空间给变量i&#xff0c;这块内存空间存放的数据就是变量i的值。 换句话说就是&#xff0c;在内存中给变…

指针的学习5

目录 sizeof和strlen的区别 sizeof strlen 数组和指针笔试题解析 一维数组 字符数组 二维数组 指针运算笔试题解析 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a; 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; sizeof和…

安装配置Hadoop集群

安装配置Hadoop集群的主要步骤 1、安装配置Hadoop 2、配置用户环境变量 3、配置Hadoop 配置core-site.xml文件配置hdfs-site.xml文件配置mapred-site.xml文件配置yarn-site.xml文件配置slaves文件配置hadoop-env.sh文件 更多配置文件的配置信息请参见官方网站的解释。 4、…

vue2中使用异步组件

在大型应用中&#xff0c;我们可能需要将应用分割成小一些的代码块&#xff0c;并且只在需要的时候才从服务器加载一个模块。这时就就可以使用异步组件。 1.通过import方式引入 //组件1<tempalte><Parent v-if"show"></Parent><button clickha…

关于Spring依赖注入简洁方式的探索

最近在项目开发过程中关注到一个依赖注入的写法差异&#xff0c;因为本人代码上有点强迫症&#xff0c;看到这种不同人不一样的写法&#xff0c;特意了解了一下&#xff0c;但是依然有部分疑惑未解。 两种写法&#xff1a;(就是传说中最常见的属性注入和构造函数注入) Service…

云打印机多少钱一台?

随着新的一年的开始&#xff0c;很多同学们都开始打印资料&#xff0c;以应对新一年的各种考试。但是对于学生们来说&#xff0c;去打印店打印价格贵、打印不方便、没时间去打印等多种原因导致我们没办法及时打印资料&#xff0c;这个时候我们就需要用到云打印机。那么云打印机…

浅谈游戏AI LOD的智能控制——LOD交易员

前引 LOD的概念 提到 细节层次 &#xff08;Level of Details&#xff0c;简写LOD&#xff09;&#xff0c;大家可能首先会想到图像渲染&#xff0c;像游戏中大地图的3D物体会随玩家与其距离的远近而变化精度&#xff08;主要是模型面数的变化&#xff0c;有时还会直接剔除&a…

CSS基础知识

font-family: "Trebuchet MS", Verdana, sans-serif; 字体栈&#xff0c;浏览器会一个一个试过去看下哪个可以用 font-size16px; font-size1em; font-size100%;//相对于16px 字体大小&#xff0c;需要进行单位换算16px1em font-weightnormal;//400font-weight属性…

ai直播数字人:AI大模型应用开发的神奇世界

当AI技术的发展走向一个新的高峰&#xff0c;AI直播数字人逐渐成为人们关注的焦点。这种全新的数字人形态&#xff0c;通过大模型应用开发&#xff0c;带来了一个神奇世界。 在这个神奇世界里&#xff0c;AI直播数字人可以展现出与真实人类相媲美的外貌和声音。通过先进的图像…

HarmonyOS ArkTS工程目录结构(Stage模型)

1. ArkTS工程目录结构&#xff08;Stage模型&#xff09; 官方文档&#xff08;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-with-ets-stage-0000001477980905-V2&#xff09; 1.1. AppScope AppScope > app.json5&#xff1a;应用的全局配…

图的单源最短路径问题

目录 一、简述 二、前置配置 三、迪杰斯特拉算法 四、改进的迪杰斯特拉算法 五、贝尔曼福特算法 一、简述 图是一种比较常用的数据结构&#xff0c;将问题转换成图相关的思路也是比较常用的。 图的单源最短路径问题&#xff0c;也就是图中某一个节点到图中其他节点的最短路…

基于SSM的植物园管理系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 开发技术简介 3 1.1 SSM框架 3 1.2 JSON 3 1.3 Ajax 4 1.4 Bootstrap前台框架 4 1.5 Eclipse 4 1.6 本章小结 4 2 系统分析 5 2.1可行性分析 5 2.1.1 技术可行性 5 2.1.2 经济可行性 5 2.1.3 操作可行性 5 2.2 功能需求 5 2.3 用例分析 6…

洞悉 Kubernetes 高阶奥秘:掌控资源、网络、存储,玩转容器化应用!

昨天我们已经入门了K8S&#xff0c;今天带大家学习一下资源、网络、存储这几个进阶的知识点模块内容。这几天陆陆续续会把K8S从头到尾讲一遍&#xff0c;最后会带大家实战一下&#xff0c;下面就开始今天的学习吧。 高级资源和控制器 Kubernetes 提供了一系列高级资源和控制器…

请编程输出无向无权图各个顶点的度 ← 链式前向星存图

【题目描述】请利用链式前向星存图&#xff0c;编程输出无向无权图各个顶点的度。【输入样例】 5 6 1 3 2 1 1 4 2 3 3 4 5 1【输出样例】 4 2 3 2 1【算法分析】 本例需要用到基于链式前向星的广度优先搜索&#xff08;BFS&#xff09;。 链式前向星广度优先搜索&#xff08;B…