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

QA工具开发流程

前言

在项目上线前期,这边根据需求制作了一套QA测试工具。主要分为以下四个模块的测试
dfed7bc872f5d5286fe4bb2a997fd14.png
**图1**

  • **数值测试:**主要包括了角色的等级变更、游戏里货币的变更、(目前已制作的)游戏道具的数量变更。这些可能归一为一类测试模型
  • **动画测试:**包括角色的控制系统的所有Animation资源的播放状态【目前无测试需求】
  • **流程测试:**比如是否需要快速胜利、跳过新手指引、指定比赛胜利类型(胜负、平局)等等一系列流程。
  • **自定测试:**笔者目前没有想到的,可能出现的其他需要测试的分类。

工具架构

主菜单顶部横栏

如图1所示,主菜单是横向布局,静态显示的。

using System.Collections.Generic;
using JetBrains.Annotations;
using QAModule;
using UnityEngine;
using UnityEngine.UI;
using TEngine;namespace GameLogic.UI
{[Window(UILayer.UI)]public class QAMainPageUI : UIWindow{//缓存池对象private QAOptionPanel _optionPanelInBuffer;private List<TestOption> _optionsList;//菜单选项条目private Dictionary<TestType, string[]> _menuDictionary; #region 脚本工具生成的代码private Image m_imgBg;private GameObject m_goOptionPanel;private GameObject m_goTestNameRoot;private Button m_btnNumericalTest;private Button m_btnAnimationTest;private Button m_btnProcessTest;private Button m_btnBack;public override void ScriptGenerator(){m_imgBg = FindChildComponent<Image>("m_imgBg");m_goOptionPanel = FindChild("m_goOptionPanel").gameObject;m_goTestNameRoot = FindChild("m_goTestNameRoot").gameObject;m_btnBack = FindChildComponent<Button>("m_btnBack");m_btnNumericalTest = FindChildComponent<Button>("m_goTestNameRoot/m_btnNumericalTest");m_btnAnimationTest = FindChildComponent<Button>("m_goTestNameRoot/m_btnAnimationTest");m_btnProcessTest = FindChildComponent<Button>("m_goTestNameRoot/m_btnProcessTest");m_btnBack.onClick.AddListener(OnClickBackBtn);m_btnNumericalTest.onClick.AddListener(OnClickNumericalTestBtn);m_btnAnimationTest.onClick.AddListener(OnClickAnimationTestBtn);m_btnProcessTest.onClick.AddListener(OnClickProcessTestBtn);}#endregionpublic override void OnCreate(){base.OnCreate();Initialize();}private void Initialize(){_optionsList = new List<TestOption>();_menuDictionary = new Dictionary<TestType, string[]>();QAInitDataTable dataTable = new QAInitDataTable();_menuDictionary = dataTable.MenuDictionary;}/// <summary>/// 根据选项展开面板/// </summary>/// <param name="index"></param>private void OpenPanel(TestType type){int index = (int)type;m_goOptionPanel.SetActive(true);m_imgBg.enabled = false;//对应属性高亮int indexCounts = m_goTestNameRoot.transform.childCount;List<Transform>  childrenTrans= m_goTestNameRoot.transform.GetAllChildren();for (int i = 0; i < indexCounts; i++){var select = childrenTrans[i].Find("Selected").gameObject;if (select != null){if (index == i){select.SetActive(true);}else{if (select.activeInHierarchy){select.SetActive(false);}}}}//创建面板_optionPanelInBuffer ??= CreateWidgetByPath<QAOptionPanel>(m_goOptionPanel.transform, "QAOptionPanel");//读取缓存池,刷新选项内容_optionPanelInBuffer.Init(_optionsList,type,_menuDictionary[type]);}/// <summary>/// 数值类型测试/// </summary>private void OnClickNumericalTestBtn(){OpenPanel(TestType.NumericalType);}/// <summary>/// 动画类型测试/// </summary>private void OnClickAnimationTestBtn(){OpenPanel(TestType.AnimationType);}/// <summary>/// 流程类型测试/// </summary>private void OnClickProcessTestBtn(){OpenPanel(TestType.ProcessType);}private void OnClickBackBtn(){if (m_goOptionPanel.activeInHierarchy){m_goOptionPanel.SetActive(false);m_imgBg.enabled = true;}else{GameModule.UI.CloseWindow<QAMainPageUI>();}}}
}

背包面板

点击顶部菜单按钮提示,展开二级选择面板。根据考虑,我选择了类似背包面板的展示模式。
3dc37fa46d9a64dd5c170e2e4cbc43c.png
在面板中通过网格布局,创建需要的测试条目。
面板切换时,使用了一个缓存池做优化。
首次创建时选项的预制体加入缓存池,如果切换面板只需更新UI、更换打开的工作流即可。

缓存池

        /// <summary>/// 创建面板里的选项/// </summary>/// 根据TestType类型创建条目,每个条目已经绑定了打开的显示逻辑public void Init(List<TestOption> optionList,TestType type,string[] optionType){int typeCounts = optionType.Length;int bufferCounts = optionList.Count;//缓存池中数量小于需创建的数量,重复部分刷新值,多余部分创建并入池子。if (bufferCounts < typeCounts){for (int index = 0; index < typeCounts; index++){if (index < bufferCounts){if (!optionList[index].gameObject.activeInHierarchy){optionList[index].gameObject.SetActive(true);}optionList[index].Initialize(index,type,optionType[index]);    }else{var testOption = CreateWidgetByPath<TestOption>(m_goContent.transform, "TestOption");testOption.Initialize(index,type,optionType[index]);optionList.Add(testOption);}}}//缓存池中数量大于等于需创建的数量,读取池子刷新内容,多余部分隐藏。else{for (int i = 0; i < bufferCounts; i++){if (i < typeCounts){optionList[i].Initialize(i,type,optionType[i]);   if (!optionList[i].gameObject.activeInHierarchy){optionList[i].gameObject.SetActive(true);}}else{optionList[i].gameObject.SetActive(false);}    }}}

具体测试面板

点击进入具体测试面板时,对于面板笔者是这么规划的。

数据类

既然测试的大类型分为了四类,那么自然每个类型都应该有不同的初始化数据
image.png
图2
在面板中,红框的部分是**派生的预制体持有的,**剩余部分应该是每种类型都应该显示的了,那就是标题
以数值类型测试为例,数据脚本如下

namespace QAModule
{//基础数据类型存储结构public class QABaseData{public string TestType{get => _testType;set => _testType = value;}private string _testType;}
}
namespace QAModule
{/// <summary>/// 数值类型字段存储结构/// </summary>public class QANumericalData : QABaseData{public string InitDisplayValue{get => _initDisplayValue;set => _initDisplayValue = value;}public float IncrementRate{get => _incrementRate;set => _incrementRate = value;}public float DecrementRate{get => _decrementRate;set => _decrementRate = value;}private string _initDisplayValue;private float _incrementRate;private float _decrementRate;}     
}

物体脚本

那么实现的脚本至少有两层

using GameLogic.UI.QAEvent;
using UnityEngine.UI;
using TEngine;
using QAModule;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI)]public class QAPanelBase<T> :UIWindow where T : QAPanelBase<T>{//需要记忆存储的参数protected static string _testType;#region 脚本工具生成的代码protected Text m_textType;private Button m_btnBack;public override void ScriptGenerator(){m_textType = FindChildComponent<Text>("Title/m_textType");m_btnBack = FindChildComponent<Button>("m_btnBack");m_btnBack.onClick.AddListener(OnClickBackBtn);}#endregionpublic override void RegisterEvent(){base.RegisterEvent();AddUIEvent<QABaseData>(QAEventDefine.StartWorkflow,OnStartWorkflow);}protected virtual void InitData(QABaseData data){}private void CreateWorkflow() //确定工作流,软件模型:瀑布模型{ReadDataFromMemory();//1.AddListener();InitPanel();}protected virtual void ReadDataFromMemory(){}protected virtual void AddListener(){}protected virtual void InitPanel(){}#region 事件private void OnStartWorkflow(QABaseData data){InitData(data);CreateWorkflow();}protected virtual void OnClickBackBtn(){//打开主界面Debug.Log("back from base");GameModule.UI.ShowUI<QAMainPageUI>();}#endregion }
}
using QAModule;
using UnityEngine;
using UnityEngine.UI;
using TEngine;namespace GameLogic.UI
{[Window(UILayer.UI)]public class QAPanelNumerical : QAPanelBase<QAPanelNumerical>{protected QANumericalData _numericalData;//需要记忆存储的参数protected static float _increment;protected static float _decrement;protected static float _incrementRate;protected static float _decrementRate;// _increment = _incrementRate * _addSliderValueprivate static float _incrementSliderValue;private static float _decrementSliderValue;private static string _displayValue;#region 脚本工具生成的代码protected GameObject m_goAdd;protected GameObject m_goMinus;private Text m_textDisplayType;private Text m_textDisplayValue;protected InputField m_inputAddInputField;private Text m_textIncrement;protected Slider m_sliderAddValues;private Button m_btnAddValues;protected InputField m_inputMinusInputField ;private Text m_textDecrement;protected Slider m_sliderMinusValues ;private Button m_btnMinusValues;public override void ScriptGenerator(){base.ScriptGenerator();m_goAdd = FindChild("ControlZone/m_goAdd").gameObject;m_goMinus = FindChild("ControlZone/m_goMinus").gameObject;m_textDisplayType = FindChildComponent<Text>("DisplayZone/DisplayBg/m_textDisplayType");m_textDisplayValue = FindChildComponent<Text>("DisplayZone/DisplayBorder/m_textDisplayValue");m_inputAddInputField = FindChildComponent<InputField>("ControlZone/m_goAdd/m_inputAddInputField");m_textIncrement = FindChildComponent<Text>("ControlZone/m_goAdd/m_inputAddInputField/m_textIncrement");m_sliderAddValues = FindChildComponent<Slider>("ControlZone/m_goAdd/m_sliderAddValues");m_btnAddValues = FindChildComponent<Button>("ControlZone/m_goAdd/m_btnAddValues");m_inputMinusInputField  = FindChildComponent<InputField>("ControlZone/m_goMinus/m_inputMinusInputField ");m_textDecrement = FindChildComponent<Text>("ControlZone/m_goMinus/m_inputMinusInputField /m_textDecrement");m_sliderMinusValues  = FindChildComponent<Slider>("ControlZone/m_goMinus/m_sliderMinusValues ");m_btnMinusValues = FindChildComponent<Button>("ControlZone/m_goMinus/m_btnMinusValues");m_sliderAddValues.onValueChanged.AddListener(OnSliderAddValuesChange);m_btnAddValues.onClick.AddListener(OnClickAddValuesBtn);m_sliderMinusValues .onValueChanged.AddListener(OnSliderMinusValuesChange);m_btnMinusValues.onClick.AddListener(OnClickMinusValuesBtn);}#endregionprotected override void InitData(QABaseData data){base.InitData(data);_numericalData  = data as QANumericalData;m_textType.text = "Test - " +_numericalData?.TestType;_displayValue = _numericalData?.InitDisplayValue;if (_numericalData != null) _incrementRate = _numericalData.IncrementRate;if (_numericalData != null) _decrementRate = _numericalData.DecrementRate;}protected override void ReadDataFromMemory(){m_sliderAddValues.value = _incrementSliderValue == 0 ? 1 : _incrementSliderValue;m_sliderMinusValues.value = _decrementSliderValue == 0 ? 1 : _decrementSliderValue;}protected override void AddListener(){m_inputAddInputField.onValueChanged.AddListener(OnInputAddField);m_inputMinusInputField.onValueChanged.AddListener(OnInputMinusField);}protected override void InitPanel(){//是否是初始数据。是,表中获取。否,用上次设过值的if (_incrementRate == 0 && _decrementRate == 0){if (_numericalData != null){_incrementRate = _numericalData.IncrementRate;_decrementRate = _numericalData.DecrementRate;}}_increment = _incrementRate * m_sliderAddValues.value;_decrement = _decrementRate * m_sliderMinusValues.value;//初始化面板显示m_textDisplayType.text = "Current" + _testType;m_textIncrement.text = $"Increment:{_increment}";m_textDecrement.text = $"Decrement:{_decrement}";if (_displayValue == null){_displayValue = _numericalData?.InitDisplayValue;m_textDisplayValue.text =  _numericalData?.InitDisplayValue;    }else{m_textDisplayValue.text = _displayValue;}}#region 事件/// <summary>/// 设置参数倍率/// </summary>/// <param name="value"></param>private void OnSliderAddValuesChange(float value){_increment = value * _incrementRate;m_textIncrement.text = $"Increment:{_increment}";_incrementSliderValue = value;}protected virtual void OnClickAddValuesBtn(){//Change Panelfloat curValue = float.Parse(m_textDisplayValue.text);curValue += _increment ;m_textDisplayValue.text = curValue.ToString();_displayValue = curValue.ToString();//Test Function}private void OnSliderMinusValuesChange(float value){_decrement = value * _decrementRate;m_textDecrement.text = string.Format("Decrement:{0}", _decrement);_decrementSliderValue = value;}protected virtual void OnClickMinusValuesBtn(){//Change Panel表现float curValue = float.Parse(m_textDisplayValue.text);curValue -= _decrement ;m_textDisplayValue.text = curValue.ToString();_displayValue = curValue.ToString();//Test Function//.....}/// <summary>/// 通过输入框自定义参数值/// </summary>private void OnInputMinusField(string inputParma){//更新倍率_decrementRate = float.Parse(inputParma);//更新面板m_sliderMinusValues.value = 1;_decrement = _decrementRate * m_sliderMinusValues.value;m_textDecrement.text = string.Format("Decrement:{0}", _decrement);}private void OnInputAddField(string inputParma){_incrementRate = float.Parse(inputParma);m_sliderAddValues.value = 1;_increment = _incrementRate * m_sliderAddValues.value;m_textIncrement.text = string.Format("Increment:{0}", _increment);}#endregion}
}

数值类型的面板如上图2,为了便于控制一次加减的值,我做了4档可输入计算器。可以根据倍率准确定位数值,做到对大小数值的便捷测试。

// _increment = _incrementRate * _addSliderValue
//实际值 = 倍率 * 滑动条的档数

数据和表现分离

所以,以上两层继承,完成了通过点击面板,完成UI界面数值的更替。
现在,需要把相关更替的数值注入到指定的数据集中【即:做出实际的测试功能】
那么只需要再让具体的XX测试 继承数值测试,然后读取相应字段,重写+ -按钮的回调函数,跟据读取的数值,做相应功能就行了。

using TEngine;
using GameLogic.DKSystem.Soical;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI,"QAPanelNumerical")]public class QAPanelGold : QAPanelNumerical{protected override void OnClickAddValuesBtn(){//数据base.OnClickAddValuesBtn();var gold = (int)_increment ;PlayerService.AddGold(gold);Debug.Log(string.Format("{0} + {1} success.", _testType, gold));}protected override void OnClickMinusValuesBtn(){base.OnClickMinusValuesBtn();var gold = (int)_decrement;PlayerService.AddGold(-gold);Debug.Log(string.Format("{0} - {1} success.", _testType, gold));}protected override void OnClickBackBtn(){base.OnClickBackBtn();GameModule.UI.CloseWindow<QAPanelGold>();}}
}
using TEngine;
using GameLogic.DKSystem.Soical;
using QAModule;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI,"QAPanelNumerical")]public class QAPanelExp : QAPanelNumerical{protected override void InitPanel(){base.InitPanel();m_goMinus.SetActive(false);}protected override void OnClickAddValuesBtn(){//数据base.OnClickAddValuesBtn();var exp = (int)_increment ;PlayerService.AddExp(exp);Debug.Log(string.Format("{0} + {1} success.", _testType, exp));}protected override void OnClickMinusValuesBtn(){base.OnClickMinusValuesBtn();var exp = (int)_decrement;PlayerService.AddExp(-exp);Debug.Log(string.Format("{0} - {1} success.", _testType, exp));}protected override void OnClickBackBtn(){base.OnClickBackBtn();GameModule.UI.CloseWindow<QAPanelExp>();}}
}
using GameLogic.DKSystem;
using TEngine;
using UnityEngine;namespace GameLogic.UI
{[Window(UILayer.UI,"QAPanelNumerical")]public class QAPanelStar : QAPanelNumerical{protected override void InitPanel(){base.InitPanel();m_inputAddInputField.gameObject.SetActive(false);m_inputMinusInputField.gameObject.SetActive(false);m_sliderAddValues.gameObject.SetActive(false);m_sliderMinusValues.gameObject.SetActive(false);}protected override void OnClickAddValuesBtn(){base.OnClickAddValuesBtn();AnswerRankService.PostSta(new StaData(){season_id = WikipediaQuizSystem.Instance.SeasonId,is_victory = 3},null);Debug.Log("增加1个星星");}protected override void OnClickMinusValuesBtn(){base.OnClickMinusValuesBtn();AnswerRankService.PostSta(new StaData(){season_id = WikipediaQuizSystem.Instance.SeasonId,is_victory = 1},null);Debug.Log("减少1个星星");}protected override void OnClickBackBtn(){base.OnClickBackBtn();GameModule.UI.CloseWindow<QAPanelStar>();}}
}

面板

using UnityEngine;
using UnityEngine.UI;
using TEngine;
using QAModule;namespace GameLogic.UI
{[Window(UILayer.UI)]public class TestOption : UIWidget{private TestType _type;private int _optionIndex;private Button m_btnTestOption;#region 脚本工具生成的代码private Image m_imgBg;private Text m_textTestOption;public override void ScriptGenerator(){m_imgBg = FindChildComponent<Image>("m_imgBg");m_textTestOption = FindChildComponent<Text>("m_textTestOption");}#endregion/// <summary>/// 根据index查找对应测试的名称类型/// </summary>/// <param name="index"></param>/// <param name="type"></param>/// <param name="description"></param>public void Initialize(int index,TestType type,string description){m_btnTestOption = gameObject.GetComponent<Button>();m_btnTestOption.onClick.AddListener(OnClickTestOptionBtn);_optionIndex = index;m_textTestOption.text = description;m_imgBg.color = Color.cyan;}private void InitWorkflow(int index,TestType type){TestProcessManager.Instance.CurTestType = type;TestProcessManager.Instance.SelectTestProcess(index);}#region 事件private void OnClickTestOptionBtn(){InitWorkflow(_optionIndex,_type);}#endregion}
}

打开并创建界面的核心是 创建工作流、先初始化,再创建。方法在工作流管理器调用

单例的工作流管理器

using Aliyun.OSS;
using GameBase;
using UnityEngine;
using UnityEngine.UI;
using TEngine;
using QAModule;namespace GameLogic.UI
{/// <summary>/// 测试项目的种类/// </summary>public enum TestType{NumericalType = 0, //数值类型测试AnimationType = 1, //动画类型测试ProcessType = 2,  // 流程类型测试ElseType = 3      //自定义测试类型}public class TestProcessManager : Singleton<TestProcessManager>{public TestType CurTestType;public void SelectTestProcess(int index){switch (CurTestType){case TestType.NumericalType:NumericalProcessFlow numericalProcessFlow = new NumericalProcessFlow(index);numericalProcessFlow.CreateTestPanel();break;case TestType.AnimationType:break;case TestType.ProcessType:break;}}protected override void Initialize(){}protected override void UnInitialize(){}}}

相关文章:

QA工具开发流程

前言 在项目上线前期&#xff0c;这边根据需求制作了一套QA测试工具。主要分为以下四个模块的测试**图1** **数值测试&#xff1a;**主要包括了角色的等级变更、游戏里货币的变更、&#xff08;目前已制作的&#xff09;游戏道具的数量变更。这些可能归一为一类测试模型**动画…...

JSON.toJSONString首字母大小写问题

前言 开发过程中遇到的&#xff0c;对象转字符串时&#xff0c;有个字段首字母是大写的&#xff0c;转换之后就变成了小写&#xff0c;在这里记录下 代码示例 String jsonString JSON.toJSONString(obj,SerializerFeature.PrettyFormat,SerializerFeature.WriteMapNullValue,…...

ant-vue1.78版a-auto-complete表单自动搜索返回列表中的关键字标红

a-auto-complete表单自动搜索返回列表中的关键字标红 通常在做关键字标红的场景&#xff0c;都是后端返回html结构&#xff0c;前端直接渲染实现&#xff0c;但是如果需要前端处理的话&#xff0c;实现也是很简单的&#xff0c;接下来我直接上应用场景吧 应用场景就是通过关键…...

Elasticsearch 优化

Elasticsearch 优化 2.1硬件选择 Elasticsearch 的基础是 Lucene &#xff0c;所有的索引和文档数据是存储在本地的磁盘中&#xff0c;具体的 路径可在 ES 的配置文件 ../config/elasticsearch.yml 中配置&#xff0c;如下&#xff1a; #----------------------------…...

spring boot的自动装配原理

spring boot的自动装配原理 解释和使用关键技术思想总结 解释和使用 自动装配是什么&#xff1a;自动将第三方组件的bean装载到ioc容器里&#xff0c;不需要开发人员再去写bean相关的一些配置 spring boot怎么做&#xff1a;在启动类上加SpringBootApplication注解就可以实现自…...

走进低代码平台| iVX-困境之中如何突破传统

前言&#xff1a; “工欲善其事,必先利其器”&#xff0c;找到和使用一个优质的工具平台&#xff0c;往往会事半功倍。 文章目录 1️⃣认识走近低代码2️⃣传统的低代码开发3️⃣无代码编辑平台一个代码生成式低代码产品iVX受面性广支持代码复用如何使用&#xff1f; 4️⃣总结…...

【UIPickerView案例03-点餐系统之随机点餐 Objective-C语言】

一、先来看看我们这个示例程序里面,随机点餐是怎么做的 1.点击:“随机点餐”按钮 大家能想到,它是怎么实现的吗 1)首先,点击”随机点餐“按钮,的时候,你要让这个pickerView,进行随机选中,那么,得监听它的点击 2)然后呢,让pickeView选中数据, 3)然后呢,把那个…...

论文阅读_扩散模型_SDXL

英文名称: SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis 中文名称: SDXL&#xff1a;改进潜在扩散模型的高分辨率图像合成 论文地址: http://arxiv.org/abs/2307.01952 代码: https://github.com/Stability-AI/generative-models 时间: 2023-…...

云原生Kubernetes:二进制部署K8S多Master架构(三)

目录 一、理论 1.K8S多Master架构 2.配置master02 3.master02 节点部署 4.负载均衡部署 二、实验 1.环境 2.配置master02 3.master02 节点部署 4.负载均衡部署 三、总结 一、理论 1.K8S多Master架构 (1) 架构 2.配置master02 &#xff08;1&#xff09;环境 关闭防…...

任意文件读取和下载

任意文件读取是什么&#xff1f; 一些网站的需求&#xff0c;可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕就可以查看或下载任意文件。这些文件可以是源代码文件配置文件敏感文件等等。过&#xff0c; 任意文件读取会造成(敏感)信息泄露;任意…...

mysql怎么查指定表的自增id?

要查看MySQL表的自增ID&#xff08;Auto Increment ID&#xff09;&#xff0c;你可以使用SHOW TABLE STATUS命令。以下是一个示例&#xff1a; SHOW TABLE STATUS LIKE your_table_name; 替换your_table_name为你想查询的表名。这条语句会返回表的一些基本信息&#xff0c;其…...

【C++设计模式】单一职责原则

2023年8月26日&#xff0c;周六上午 目录 概述一个简单的例子用单一职责原则来设计一个简单的学生管理系统 概述 单一职责原则&#xff08;Single Responsibility Principle&#xff0c;SRP&#xff09;&#xff0c;它是面向对象设计中的一个基本原则。 单一职责原则的核心思…...

Windows docker desktop 基于HyperV的镜像文件迁移到D盘

Docker desktop的HyperV镜像文件&#xff0c;默认是在C盘下 C:\ProgramData\DockerDesktop\vm-data\DockerDesktop.vhdx如果部署的软件较多&#xff0c;文件较大&#xff0c;或者产生日志&#xff0c;甚至数据等&#xff0c;这将会使此文件越来越大&#xff0c;容易导致C盘空间…...

LM-INFINITE: SIMPLE ON-THE-FLY LENGTH GENERALIZATION FOR LARGE LANGUAGE MODELS

本文是LLM系列文章&#xff0c;针对《LM-INFINITE: SIMPLE ON-THE-FLY LENGTH GENERALIZATION FOR LARGE LANGUAGE MODELS》的翻译。 LM-INFiNITE&#xff1a;大语言模型的一个简单长度上推广 摘要1 引言2 相关工作3 LLMs中OOD因素的诊断4 LM-INFINITE5 评估6 结论和未来工作 …...

ShardingSphere——压测实战

摘要 Apache ShardingSphere 关注于全链路压测场景下&#xff0c;数据库层面的解决方案。 将压测数据自动路由至用户指定的数据库&#xff0c;是 Apache ShardingSphere 影子库模块的主要设计目标。 一、压测背景 在基于微服务的分布式应用架构下&#xff0c;业务需要多个服…...

二分图-染色法-dfs

1.判断一个图是否是二分图当且仅当图中不包含奇数环 2. dfs当前边为1 他的临边为2 看是否满足条件 3. 注意图有可能不是连通图 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays;public class BinaryG…...

SQL优化案例教程0基础(小白必看)

前提准备&#xff1a;本案例准备了100W的数据进行SQL性能测试&#xff0c;数据库采用的是MySQL&#xff0c; 总共介绍了常见的14种SQL优化方式&#xff0c;每一种优化方式都进行了实打实的测试&#xff0c; 逐行讲解&#xff0c;通俗易懂&#xff01; 一、前提准备 提前准备一…...

webpack(一)模块化

模块化演变过程 阶段一&#xff1a;基于文件的划分模块方式 概念&#xff1a;将每个功能和相关数据状态分别放在单独的文件里 约定每一个文件就是一个单独的模块&#xff0c;使用每个模块&#xff0c;直接调用这个模块的成员 缺点&#xff1a;所有的成员都可以在模块外被访问和…...

基于Java+SpringBoot+Vue前后端分离人力资源管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

安装配置mariadb

记录下安装配置mariadb的经历。 环境&#xff1a;ubuntu22 一、apt在线安装 apt代理配置 APT是Ubuntu系统中用于安装和升级软件包的工具&#xff0c;如果本地没有可用的软件包&#xff0c;APT将会连接到远程软件包服务器下载软件包。在某些情况下&#xff0c;用户需要将APT的…...

Ant Design Vue 日期选择器DatePicker传给后台日期参数格式问题

花了一个下午才解决&#xff0c;官方组件文档里面是没有处理方案说明的。 项目版本&#xff1a;Ant Design Vue 2.0.2 前端部分代码&#xff1a; <template><a-modal:visible"visible":width"windowWidth":height"800":title"tit…...

springboot1.5.12升级至2.6.15

首先&#xff0c;加入springboot升级大版本依赖&#xff0c;会在升级过程中打印出错日志提示&#xff08;升级完毕可去除&#xff09; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-properties-migrator</art…...

Android Event事件分发(新版本)

之前写过一个方案&#xff08;添加链接描述&#xff09;&#xff0c;突然觉得很麻烦&#xff0c;于是有了新的方案&#xff1a; 首先先说要解决的问题&#xff1a; 当父布局能滑动&#xff0c;子View也能滑动&#xff0c;就会出现滑动冲突 解决思路&#xff1a;我们按下子Vie…...

可控生成:ControlNet原理

🤗关注公众号funNLPer体验更佳阅读🤗 论文:Adding Conditional Control to Text-to-Image Diffusion Models 代码:lllyasviel/ControlNet 简单来说ControlNet希望通过输入额外条件来控制大型图像生成模型,使得图像生成模型根据可控。 文章目录 1. 动机2. ControlNet原理…...

【极客时间】MySQL 必知必会-20230901

03 | 表&#xff1a;怎么创建和修改数据表&#xff1f; 新增数据表 CREATE DATABASE demo;CREATE TABLE goodsmaster (barcode TEXT,goodsname TEXT,price DOUBLE, itemnumber INT PRIMARY KEY AUTO_INCREMENT);INSERT INTO demo.goodsmaster (barcode, goodsname,price) VAL…...

53 个 CSS 特效 3(完)

53 个 CSS 特效 3&#xff08;完&#xff09; 前两篇地址&#xff1a; 53 个 CSS 特效 153 个 CSS 特效 2 这里是第 33 到 53 个&#xff0c;很多内容都挺重复的&#xff0c;所以这里解释没之前的细&#xff0c;如果漏了一些之前的笔记会补一下&#xff0c;写过的就会跳过。…...

简单数学题:找出最大的可达成数字

来看一道简单的数学题&#xff1a;力扣2769. 找出最大的可达成数字 题目描述的花里胡哨&#xff0c;天花乱坠&#xff0c;但这道题目非常简单。我们最多执行t次操作&#xff0c;只需每次操作都让x-1&#xff0c;让num1&#xff0c;执行t次操作后&#xff0c;x就变为xt&#xff…...

[C++ 网络协议] 套接字的多种可选项

目录 1. 套接字的可选项 2. 获取/设置套接字可选项 2.1 getsockopt函数&#xff08;获取套接字可选项&#xff09; 2.2 setsockopt函数&#xff08;设置套接字可选项&#xff09; 3. 常用套接字可选项 3.1 SOL_SOCKET协议层的SO_TYPE可选项 3.2 SOL_SOCKET协议层的SO_SN…...

2022年03月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:数字变换 给定一个包含 5 个数字(0-9)的字符串, 例如 “02943”, 请将“12345”变换到它。 你可以采取 3 种操作进行变换 (1)交换相邻的两个数字 (2)将一个数字加 1。 如果加 1 后大于 9, 则变为 0 (3)将一个数字加倍。 如果加倍后大于 9,则将其变为加倍后的…...

***数据转换中常用的两个函数 sscanf,sprintf

1、sscanf将字符串转换成想要的整数或浮点数 (HMI屏中输入浮点数据,到mcu后要转换成对应的浮点数据) sscanf(“0.9”,“%f”,getData) /*! \brief 文本控件通知 \details 当文本通过键盘更新(或调用GetControlValue)时,执行此函数 \details 文本控件的内容以字符串形…...