自动化测试项目1 --- 唠嗑星球 [软件测试实战 Java 篇]
目录
项目介绍
项目源码库地址
项目功能测试
1.自动化实施步骤
1.1 编写测试用例
1.2 自动化测试脚本开发
1.2.1 配置相关环境, 添加相关依赖
1.2.2 相关代码编写
2. 自动化功能测试总结
2.1 弹窗的解决相关问题
2.2 断言的使用和说明
2.3 重新登录问题
项目性能(接口)测试
1. 进行性能测试
2.生成的性能测试报告
项目总结
1. 部分使用缺陷总结
编辑
2. 测试结论与建议
项目介绍
// "唠嗑星球" 项目专注于打造私密、深度的沟通场景,是一款仅支持一对一交流的即时通讯平台,为用户带来专注且安全的聊天体验;
// 在功能设计上,摒弃了群聊模式,全力优化一对一聊天体验; 项目配备实时消息推送功能,确保重要信息及时触达;聊天记录云端存储,方便用户随时回溯查看;
// 对于用户而言,本项目是维系情感、深入沟通的绝佳工具。无论是与亲朋好友分享生活感悟,还是与合作伙伴进行业务洽谈,都能在这里获得专注、高效且安全的交流体验,助力每一次一对一沟通都充满温度与价值。
项目源码库地址
唠嗑星球 git 仓库地址, 点击跳转https://gitee.com/zhou-jintao2002/web-chat-auto-test
项目功能测试
1.自动化实施步骤
1.1 编写测试用例
1.2 自动化测试脚本开发
1.2.1 配置相关环境, 添加相关依赖
// 自动化测试基础知识及相关函数, 包括 Selenium 的安装和使用基础教程
1.2.2 相关代码编写
// 我们将需要测试的内容按照具体需求放到不同的文件夹中, 方便管理
common/Untils.java
public class Untils {public static WebDriver driver;public static WebDriver createDriver() {if (driver == null) {// 创建驱动对象WebDriverManager.chromedriver().setup();ChromeOptions options = new ChromeOptions();// 设置无头模式options.addArguments("-headless");// 设置浏览器加载策略options.setPageLoadStrategy(PageLoadStrategy.NORMAL);// 允许访问所有链接options.addArguments("--remote-allow-origins=*");// 驱动创建好了driver = new ChromeDriver(options);// 创建隐式等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));}return driver;}public Untils(String url) {// 调用 driver 对象driver = createDriver();// 访问urldriver.get(url);}/*创建屏幕截图*/public void getScreenShot(String str) throws IOException {// 屏幕截图SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());// 生成文件的格式为: 年-月-日/test.类名-时分秒毫秒.pngString fileName = "./src/test/image/" + dirTime + "/" + str + "-" + fileTime + ".png";// System.out.printf("fileName:" + fileName);File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);// srcFile 放到指定位置FileUtils.copyFile(srcFile,new File((fileName)));}
}
tests/LoginPage.java
public class LoginPage extends Untils {public static String url = "http://127.0.0.1:8080/login.html";public LoginPage() {super(url);}/*检查页面是否加载成功*/public void loginPageRight() throws InterruptedException, IOException {getScreenShot(getClass().getName());// 通过查看页面元素是否存在来检查页面加载成功与否driver.findElement(By.cssSelector("body > div.nav"));// Thread.sleep(3000);
// driver.quit();}/*检查登录功能*/// 成功登录public void LoginSuc() throws InterruptedException, IOException {getScreenShot(getClass().getName());// 登录成功测试前可以先 刷新页面 或者 清除一下输入框, 确保输入框中没有文本// 方法一: 通过 clear 保证输入框没有文本
// driver.findElement(By.cssSelector("username")).clear();
// driver.findElement(By.cssSelector("password")).clear();// 方法二: 通过界面刷新操作清除输入框文本driver.navigate().refresh();driver.findElement(By.cssSelector("#username")).sendKeys("lisi");driver.findElement(By.cssSelector("#password")).sendKeys("123");driver.findElement(By.cssSelector("#submit")).click();// 加一个等待Thread.sleep(1000);//有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert.accept();// 程序执行过快, 导致报错, 加一个显式等待 (是处理弹窗前需要等待, 所以这行代码先不用)
// WebDriverWait off = new WebDriverWait(driver, Duration.ofSeconds(3));
// off.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-friend")));// 通过新页面的图标来检查点击登录之后是否登录成功driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session"));// 通过新页面的标题来再次检查点击登录之后是否登录成功String expect = driver.getTitle();// 通过断言功能来检查assert expect.equals("网页聊天程序");getScreenShot(getClass().getName());// 回退driver. Navigate().back();// 回退之后就刷新一下页面driver. Navigate().refresh();}// 异常登录(账号为空)public void LoginFail1() throws InterruptedException, IOException {// 清除输入框中原有的内容// 方法一: 通过 clear 保证输入框没有文本
// driver.findElement(By.cssSelector("username")).clear();
// driver.findElement(By.cssSelector("password")).clear();// 方法二: 通过界面刷新操作清除输入框文本
// driver.navigate().refresh();driver.findElement(By.cssSelector("#username")).sendKeys("");driver.findElement(By.cssSelector("#password")).sendKeys("123");driver.findElement(By.cssSelector("#submit")).click();// 加一个等待Thread.sleep(1000);//有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert. Accept();// 弹窗解决后再判断是否登录成功, 若登录失败, 则表示还在登录界面String u = driver.getCurrentUrl();assert u.equals("http://127.0.0.1:8080/login.html");// 页面刷新一下, 确保输入框没有文本driver.navigate().refresh();// driver.quit();}// 异常登录(密码为空)public void LoginFail2() throws InterruptedException, IOException {driver.findElement(By.cssSelector("#username")).sendKeys("lisi");driver.findElement(By.cssSelector("#password")).sendKeys("");driver.findElement(By.cssSelector("#submit")).click();// 加一个等待Thread.sleep(1000);//有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert.accept();// 弹窗解决后再判断是否登录成功, 若登录失败, 则表示还在登录界面String u = driver.getCurrentUrl();assert u.equals("http://127.0.0.1:8080/login.html");// 页面刷新一下, 确保输入框没有文本driver.navigate().refresh();
// driver.quit();}// 异常登录(账号错误)public void LoginFail3() throws InterruptedException, IOException {driver.findElement(By.cssSelector("#username")).sendKeys("lisizi");driver.findElement(By.cssSelector("#password")).sendKeys("123");driver.findElement(By.cssSelector("#submit")).click();// 加一个等待Thread.sleep(1000);//有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert.accept();// 弹窗解决后再判断是否登录成功, 若登录失败, 则表示还在登录界面String u = driver.getCurrentUrl();assert u.equals("http://127.0.0.1:8080/login.html");// 页面刷新一下, 确保输入框没有文本driver.navigate().refresh();
// driver.quit();}// 异常登录(密码错误)public void LoginFail4() throws InterruptedException, IOException {driver.findElement(By.cssSelector("#username")).sendKeys("lisi");driver.findElement(By.cssSelector("#password")).sendKeys("1234");driver.findElement(By.cssSelector("#submit")).click();// 加一个等待Thread.sleep(1000);//有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert.accept();// 弹窗解决后再判断是否登录成功, 若登录失败, 则表示还在登录界面String u = driver.getCurrentUrl();assert u.equals("http://127.0.0.1:8080/login.html");// 页面刷新一下, 确保输入框没有文本driver.navigate().refresh();
// driver.quit();//driver.navigate().back();driver.navigate().refresh();}
}
tests/ListPage.java
public class ListPage extends Untils {private static String url = "http://127.0.0.1:8080/login.html";public ListPage() {super(url);}/*未登录状态下 --- 访问列表页由 PageByNoLogin类 进行测试*//*登录状态下 --- 访问主页面*/public static String username = null;public static String se1 = null;public static String se2 = null;public void ListLogin() throws InterruptedException {
// Thread.sleep(1000);// 重新返回并清空登录页面进行登录driver.navigate().refresh();// 登录driver.findElement(By.cssSelector("#username")).sendKeys("lisi");username = driver.findElement(By.cssSelector("#username")).getText();driver.findElement(By.cssSelector("#password")).sendKeys("123");driver.findElement(By.cssSelector("#submit")).click();// 为了能等到弹窗出现,加一个等待Thread.sleep(1000);// 有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert.accept();// 通过查看页面元素是否存在来检查页面加载成功与否driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session"));se1 =driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session")).getText();}/*检查个人信息是否正确*/public void PersonalInformation() {// 找到登录用户名driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.user"));// 用断言来比较这个用户名和登录的用户名是否一致assert se1.equals(username);}/*检查搜索框*/public void SearchBox() throws InterruptedException {// 检查是否可以正常输入driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > input[type=text]")).sendKeys("zhangsan");// 点击搜索按钮driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button"));// 这里按钮虽然可以点击,但是做不到搜索功能}/*检查聊天内容预览因为这个消息是动态的,所以只能测试一次,一次过后就要改 test2*/public void ChatPage() throws InterruptedException {// 程序执行过快,网站内容还没加载完全,加一个显式等待WebDriverWait off = new WebDriverWait(driver, Duration.ofSeconds(20));off.until(ExpectedConditions.textToBe (By.cssSelector("#session-list > li:nth-child(2) > h3"),("zhangsan")));// 查询到主页预览中的聊天内容String test1 = driver.findElement(By.cssSelector("#session-list > li.selected > p")).getText();// 点击对应用户并查询到聊天界面中的聊天内容driver.findElement(By.cssSelector("#session-list > li:nth-child(2)")).click();String test2 = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.message-show > div:nth-child(14) > div > p")).getText();// 使用断言判断预览功能是否成功assert test1.equals(test2);}/*给其他用户发送消息*/public void SendMessage() {// 程序执行过快,网站内容还没加载完全,加一个显式等待WebDriverWait off = new WebDriverWait(driver, Duration.ofSeconds(20));off.until(ExpectedConditions.textToBe (By.cssSelector("#session-list > li:nth-child(2) > h3"),("zhangsan")));// 选择一个用户并点击进入消息发送界面driver.findElement(By.cssSelector("#session-list > li:nth-child(2)")).click();// 找到输入框, 并输入想要发送的内容(空)driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys("");// 点击发送按钮,发送消息driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();// 找到输入框, 并输入想要发送的内容(仅文字)driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys("你好呀!");se2 = driver.findElement(By.cssSelector("#session-list > li.selected > p")).getText();// 点击发送按钮,发送消息driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();// 找到输入框, 并输入想要发送的内容 (文字 + 其他内容)
// driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys("你好呀!35465466654^&%^%$^%$&^*&%^#$%&%*&$^%#^%#^%&^*&^&");// 点击发送按钮,发送消息driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();}/*检查接收消息*/public void ReceiveMessage() throws InterruptedException {// 需要登录另一个接收账号来测试// 首先回退,刷新重新登录driver.navigate().back();driver.navigate().refresh();// 登录driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");username = driver.findElement(By.cssSelector("#username")).getText();driver.findElement(By.cssSelector("#password")).sendKeys("123");driver.findElement(By.cssSelector("#submit")).click();// 为了能等到弹窗出现,加一个等待Thread.sleep(2000);// 有弹窗先解决弹窗Alert alert = driver.switchTo().alert();alert.accept();// 通过查看页面元素是否存在来检查页面加载成功与否driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session"));// 进行收发件验证// 程序执行过快,网站内容还没加载完全,加一个显式等待WebDriverWait off = new WebDriverWait(driver, Duration.ofSeconds(25));off.until(ExpectedConditions.textToBe (By.cssSelector("#session-list > li:nth-child(1) > h3"),("zhaoliu")));// 找到发件人昵称,点击进去driver.findElement(By.cssSelector("#session-list > li:nth-child(3)")).click();// 用断言检查发件人发送的内容是否接收到了String ele = driver.findElement(By.cssSelector("#session-list > li.selected > p")).getText();
// System.out.println(ele+"1");
// System.out.println(se2+"2");assert se2.equals(ele);}/*检查好友列表页*/public void FriendsList() {// 找到好友图标并点击,通过查看好友列表的好友昵称判断是否成功跳转driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-friend")).click();driver.findElement(By.cssSelector("#friend-list > li:nth-child(1) > h4"));// 点击好友,跳转到聊天界面driver.findElement(By.cssSelector("#friend-list > li:nth-child(1) > h4")).click();driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title"));}
}
tests/PageByNoLogin.java
/*测试未登录的用例*/
public class PageByNoLogin extends Untils {public static String url = "http://127.0.0.1:8080/client.html";public PageByNoLogin() {super(url);}public void ListPageByNoLogin() throws IOException, InterruptedException {// 保证未登录状态Thread.sleep(1000);// 主页未登录处理// 处理弹窗Alert alert = driver.switchTo().alert();alert.accept();// 跳转到登录页面String expect = driver.getTitle();getScreenShot(getClass().getName());assert expect.equals("登录页面");// driver.quit();}
}
RunTests.java
public class RunTests {public static void main(String[] args) throws InterruptedException, IOException {LoginPage login = new LoginPage();login.loginPageRight();login.LoginSuc();login.LoginFail1();login.LoginFail2();login.LoginFail3();login.LoginFail4();PageByNoLogin noLogin = new PageByNoLogin();noLogin.ListPageByNoLogin();ListPage list = new ListPage();list.ListLogin();list.PersonalInformation();list.SearchBox();list.ChatPage();list.SendMessage();list.ReceiveMessage();list.FriendsList();Thread.sleep(1000);driver.quit();}
}
2. 自动化功能测试总结
2.1 弹窗的解决相关问题
// 有弹窗先处理弹窗, 弹窗未处理之前不能对页面元素进行操作
// 在执行登录测试的程序时, 报了以下错误
// 我就觉得是在解决弹窗时出了点问题, 调试了几遍发现是程序执行过快导致弹窗没有被检测到
// 所以我就个加了等待, 再次尝试运行就没有弹窗错误了
2.2 断言的使用和说明
// 断言语法: assert 变量1.equals(变量2);
// 判断是否相同的情况可以多使用断言
// 要想在 idea 中使用断言, 需要先按照以下步骤进行配置
2.3 重新登录问题
// 成功登录测试完之后, 我们需要测试登录失败的用例时, 就需要重新登录, 这时候就要用到 回退(driver.navigate().back();) 操作, 但仅仅回退还不行, 因为在之前登录的时候, 用户名和密码的输入框中已经输入了内容, 我们如果直接进行测试的话, 会在原基础上拼接, 所以我们需要先将输入框中的内容清空才能继续进行测试, 这里我们可以用两种方法, 一种是使用 clear 语句, 第二种是 使用 刷新 (driver.navigate().refresh();) 操作
// 为了防止我们的测试代码因执行顺序发生变化导致报错, 每次登录不管是否成功, 我们都可以 back 并 refresh 一下, 这样不论我们是先测试成功用例还是失败用例, 到最后都可以实现
项目性能(接口)测试
// 使用 JMeter 进行性能测试
// 可以和 Postman 配合使用
1. 进行性能测试
2.生成的性能测试报告
// 点击查看性能测试报告
项目总结
1. 部分使用缺陷总结
2. 测试结论与建议
相关文章:
自动化测试项目1 --- 唠嗑星球 [软件测试实战 Java 篇]
目录 项目介绍 项目源码库地址 项目功能测试 1.自动化实施步骤 1.1 编写测试用例 1.2 自动化测试脚本开发 1.2.1 配置相关环境, 添加相关依赖 1.2.2 相关代码编写 2. 自动化功能测试总结 2.1 弹窗的解决相关问题 2.2 断言的使用和说明 2.3 重新登录问题 项目性能…...
c语言 关键字--目录
1.c语言 关键字 2.typedef 关键字 3.volatile 关键字 4.register 关键字 5.const关键字用法 6.extern关键字...
C语言与指针3——基本数据类型
误区补充 char 的 表示范围0-127 signed char 127 unsigned char 0-255enum不常用,但是常见,这里记录一下。 enum Day {Monday 1,//范围是IntTuesday 2,Wednesday 3 }; enum Day d Monday; switch (d) {case Monday:{printf("%d",Monday);…...
[更新完毕]2025五一杯C题五一杯数学建模思路代码文章教学:社交媒体平台用户分析问题
完整内容请看文章最下面的推广群 社交媒体平台用户分析问题 在问题一中为解决博主在特定日期新增关注数的预测问题,本文构建了基于用户历史行为的二分类模型。首先,从用户对博主的观看、点赞、评论、关注等交互行为中提取统计与时序特征,形成…...
使用Vite创建vue3项目
什么是vite Vite 是新一代构建工具,由 Vue 核心团队开发,提供极快的开发体验。 它利用浏览器原生ES模块导入功能,提供了极快的热模块更新(HMR)和开发服务器启动速度。 官网:https://vitejs.cn/vite3-cn/…...
Linux管道识
深入理解管道 (Pipes):连接命令的瑞士军刀 在 Linux 和类 Unix 系统(包括 macOS)的命令行世界里,管道(Pipe)是一个极其强大且基础的概念。它允许你将一个命令的输出直接作为另一个命令的输入,像…...
LabVIEW 中VI Server导出 VI 配置
该 LabVIEW VI 展示了在 VI Server 中配置和执行 Exported VIs 的过程,实现对服务器端导出 VI 的远程调用与操作。 具体过程及模块说明 前期配置:需确保在 LabVIEW 的 “Tools> Options > VI Server > Protocols” 路径下,启用 …...
map和set的遗留 + AVL树(1):
在讲解新的东西之前,我们把上节遗留的问题说一下: 遗留问题: 首先,我们的最上面的代码是一个隐式类型转换,我们插入了一对数据。 我们说了,我们的方括号的底层是insert,当我们调用operator的[…...
Java学习手册:Spring Security 安全框架
一、Spring Security 简介 Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架,用于保护 Java 应用程序,尤其是基于 Spring 的应用。它构建在 Spring 框架之上,能够轻松地集成到基于 Spring 的应用程序中,包括…...
pip 常用命令及配置
一、python -m pip install 和 pip install 的区别 在讲解 pip 的命令之前,我们有必要了解一下 python -m pip install 和 pip install 的区别,以便于我们在不同的场景使用不同的方式。 python -m pip install 命令使用 python 可执行文件将 pip 模块作…...
C++_STL
C 标准模板库(Standard Template Library,STL)是一套功能强大的 C 模板类和函数的集合,它提供了一系列通用的、可复用的算法和数据结构。 STL 的设计基于泛型编程,这意味着使用模板可以编写出独立于任何特定数据类型的…...
[FPGA Video] AXI4-Stream Remapper
Xilinx AXI4-Stream Remapper IP (PG379) 详细介绍 概述 Xilinx LogiCORE™ IP AXI4-Stream Remapper 核是一个专为视频处理设计的模块,用于在不同每时钟像素数(Pixels Per Clock, PPC)要求之间重新映射视频像素。它支持将输入 AXI4-Stream…...
【数据结构】励志大厂版·初阶(复习+刷题):栈与队列
前引:本篇将由小编与大家一起复习 栈 、队列 的知识点,栈、队列的顺序、链式结构各个缺点好处,如何实现、对于一般的增删查找此篇文章一定再详细不过!对代码的注释、何时需要判断、特殊情况,白话文版一解到底ÿ…...
pytest——参数化
之前有说过,通过pytest测试框架标记参数化功能可以实现数据驱动测试。数据驱动测试使用的文件主要有以下类型: txt 文件 csv 文件excel 文件json 文件yaml 文件.... 本文主要讲的就是以上几种文件类型的读取和使用 一.txt 文件读取使用 首先创建一个 …...
第7篇:RESTful API设计与安全防护
在前后端分离架构中,RESTful API是系统交互的核心通道。本文将从接口规范设计到安全防护,全面讲解如何在EggJS中构建安全、规范、易用的API系统,并提供完整的解决方案和最佳实践。 一、标准化API接口规范设计 1. RESTful设计原则 核心要素&…...
CSS 架构与命名规范
CSS 架构与命名规范:BEM、SMACSS 与 OOCSS 实战 引言 在前端开发中,随着项目规模的扩大,CSS 代码往往会变得难以维护和扩展。无组织的样式表会导致命名冲突、权重覆盖问题和样式继承混乱,这些问题在团队协作的大型项目中尤为明显…...
实验二 软件白盒测试
实验二 软件白盒测试 某工资计算程序功能如下:若雇员月工作小时超过40小时,则超过部分按原小时工资的1.5倍的加班工资来计算。若雇员月工作小时超过50小时,则超过50的部分按原小时工资的3倍的加班工资来计算,而40到50小时的工资仍…...
【数据结构】String字符串的存储
目录 一、存储结构 1.字符串常量池 2.字符串哈希表 2.1结构 2.2基础存储单位 2.2.1键对象 2.2.2值对象 二、存储过程 1.搜索 2.创建 三、存储位置 四、存储操作 1.new新建 2.intern入池 这是String类的详解:String类变量 一、存储结构 1.字符串常量池…...
LLMs Tokenizer Byte-Pair Encoding(BPE)
1 Byte-Pair Encoding(BPE) 如何构建词典? 准备足够的训练语料;以及期望的词表大小;将单词拆分为字符粒度(字粒度),并在末尾添加后缀“”,统计单词频率合并方式:统计每一个连续/相邻字节对的出现频率,将最高频的连续字…...
npm,yarn,pnpm,cnpm,nvm,npx包管理器常用命令
前端比较主流的包管理器主要有三个npm,yarn,pnpm 多层级依赖,通常发生在依赖之间存在复杂的版本要求时 包 A 依赖于包 B1.0.0 包 B 依赖于包 C2.0.0 另一个包 D 也依赖于 C3.0.0 一、NPM (Node Package Manager) https://www.npmjs.cn/…...
使用mybatis实例类和MySQL表的字段不一致怎么办
在 MyBatis 中,当 Java 实体类的属性名与数据库表的字段名不一致时,会导致查询结果无法正确映射。以下是几种常见解决方案及代码示例: 1. 使用 resultMap 显式映射(推荐) 场景:字段名与属性名差异较大&…...
阿里发布新一代通义千问 Qwen3模型
近日,阿里巴巴发布了新一代通义千问 Qwen3 模型,一举登顶全球最强开源模型。 这是国内首个“混合推理模型”,将“快思考”与“慢思考”集成进同一个模型,大大节省算力消耗。 旗舰模型 Qwen3-235B-A22B 在代码、数学、通用能力等…...
React pros比较机制
将 count1作为prop传递给Memoson组件 引用类型情况 虽然list值没有发生变化,但是仍旧重新渲染 解决方法使用useMemo()函数,传递一个空依赖项 // 传递数据为引用类型 比较的是引用 // 使用useMemo函数改写、const list useMemo(()>{return [1,2,3]},[…...
Flowable7.x学习笔记(十七)审批我的待办
前言 前文完成了我的待办的查询功能,本文就在此基础上从源码解读到完成审批任务的功能,审批界面我就先不带表单,直接单纯审批通过,这里需要注意的事,审批的表单其实每个节点都可能需要不同的表单内容,后续要…...
HTTP 状态码详解:用途与含义
HTTP 状态码详解:用途与含义 HTTP 状态码详解:用途与含义1. (2xx)成功类200 OK201 Created204 No Content206 Partial Content 2. (3xx)重定向类301 Moved Permanently302 Found(临时重定向&…...
AI日报 · 2025年05月02日 | 再见GPT-4!OpenAI CEO 确认 GPT-4 已从 ChatGPT 界面正式移除
1、OpenAI CEO 确认 GPT-4 已从 ChatGPT 界面正式移除 在处理 GPT-4o 更新问题的同时,OpenAI CEO Sam Altman 于 5 月 1 日在 X 平台发文,正式确认初代 GPT-4 模型已从 ChatGPT 主用户界面中移除。此举遵循了 OpenAI 此前公布的计划,即在 4 …...
ppt设计美化公司_杰青_长江学者_优青_青年长江学者_万人计划青年拔尖人才答辩ppt模板
WordinPPT / 持续为双一流高校、科研院所、企业等提供PPT制作系统服务。 / 近期PPT美化案例 - 院士增选、科学技术奖、杰青、长江学者特聘教授、校企联聘长江、重点研发、优青、青长、青拔.. 杰青(杰出青年科学基金) 支持已取得突出成果的45岁以下学…...
文章四《深度学习核心概念与框架入门》
文章4:深度学习核心概念与框架入门——从大脑神经元到手写数字识别的奇幻之旅 引言:给大脑装个"GPU加速器"? 想象一下,你的大脑如果能像智能手机的GPU一样快速处理信息会怎样?这正是深度学习的终极目标&…...
HTML5+JavaScript实现连连看游戏之二
HTML5JavaScript实现连连看游戏之二 以前一篇,见 https://blog.csdn.net/cnds123/article/details/144220548 连连看游戏连接规则: 只能连接相同图案(或图标、字符)的方块。 连线路径必须是由直线段组成的,最多可以有…...
2025年- H19-Lc127-48.旋转矩阵(矩阵)---java版
1.题目描述 2.思路 画出矩阵,新的旋转矩阵的列坐标等于原始矩阵的矩阵长度-i-1(也就是减去当前遍历的i),前后对调。然后新的旋转矩阵的横坐标,是原始矩阵的列坐标。 3.代码实现 public class H48 {public void rota…...
深入理解 MyBatis 代理机制
在 Java 开发领域,MyBatis 是一款优秀的持久层框架,它极大地简化了数据库操作,提高了开发效率。其中,代理机制作为 MyBatis 的核心特性之一,在连接 Java 代码与数据库操作中发挥着关键作用。本文将深入探讨 MyBatis 代…...
游戏引擎学习第254天:重新启用性能分析
运行游戏并尝试让性能分析系统恢复部分功能 我们现在的调试系统这几天基本整理得差不多了,因此我们打算开始清理一些功能,比如目前虽然已经在收集性能分析数据,但我们没有办法查看或有效利用这些信息。今天的计划可能会围绕这方面展开&#…...
性能测试工具篇
文章目录 目录1. JMeter介绍1.1 安装JMeter1.2 打开JMeter1.3 JMeter基础配置1.4 JMeter基本使用流程1.5 JMeter元件作用域和执行顺序 2. 重点组件2.1 线程组2.2 HTTP取样器2.3 查看结果树2.4 HTTP请求默认值2.5 JSON提取器2.6 用户定义的变量2.7 JSON断言2.8 同步定时器&#…...
【Hive入门】Hive性能调优之Join优化:深入解析MapJoin与Sort-Merge Join策略
目录 前言 1 Hive Join操作基础 1.1 Join操作的类型与挑战 1.2 Hive Join执行机制 2 MapJoin优化策略 2.1 MapJoin原理 2.2 MapJoin适用场景 2.3 MapJoin关键参数 3 Sort-Merge Join优化策略 3.1 Sort-Merge Join原理 3.2 Sort-Merge Join优势 3.3 关键配置参数 3…...
【Unity】使用XLua实现C#访问Lua文件
先引入XLua文件中的Plugins和XLua文件夹于Unity项目的Asset文件中 XLua_github链接 建立Lua虚拟机:LuaEnv luaEnv new LuaEnv(); 关闭虚拟机,及时释放资源:luaEnv.Dispose(); Resources文件夹下加载lua文件(假设文件路径为Resour…...
AXI中的out of order和interleaving的定义和两者的差别?
AXI中的out of order和interleaving的定义和两者的差别 摘要:在 AXI (Advanced eXtensible Interface) 协议中,Out-of-Order 和 Interleaving 是两个与事务处理顺序和数据传输相关的概念,它们都与 AXI 协议支持的多事务并发处理能力有关&…...
生产级RAG系统一些经验总结
本文将探讨如何使用最新技术构建生产级检索增强生成(RAG)系统,包括健壮的架构、向量数据库(Faiss、Pinecone、Weaviate)、框架(LangChain、LlamaIndex)、混合搜索、重排序器、流式数据接入、评估策略以及实际部署技巧。 引言:检索增强生成的力量 大型语…...
sftp连接报错Received message too long 168449893
sftp连接报错Received message too long 168449893 一、openEuler传文件报错二、分析问题三、解决问题endl 一、openEuler传文件报错 [rootRocky9-12 ~]# scp apache-tomcat-10.1.33.tar.gz root10.0.0.14:Authorized users only. All activities may be monitored and report…...
Java中修饰类的关键字
Java中修饰类的关键字 在web编程课上,老师提问了Java中各种修饰类的关键字的用途和区别,一时间我头脑空白,现在课后重新梳理一遍Java中修饰类的各种关键字的区别和用法。在Java编程中,修饰类的关键字起着至关重要的作用ÿ…...
2025年人工智能火爆技术总结
2025年人工智能火爆技术总结: 生成式人工智能 生成式人工智能可生成高质量的图像、视频、音频和文本等多种内容。如昆仑万维的SkyReels-V2能生成无限时长电影,其基于扩散强迫框架,结合多模态大语言模型和强化学习等技术,在运动动…...
脑机接口技术:开启人类与机器的全新交互时代
在科技飞速发展的今天,人类与机器的交互方式正经历着前所未有的变革。从最初的键盘鼠标,到触摸屏,再到语音控制,每一次交互方式的升级都极大地提升了用户体验和效率。如今,脑机接口(Brain-Computer Interfa…...
Arduino程序函数详解与实际案例
一、Arduino程序的核心架构与函数解析 Arduino程序的核心由两个函数构成:setup() 和 loop()。这两个函数是所有Arduino代码的骨架,它们的合理使用决定了程序的结构和功能。 1.1 setup() 函数:初始化阶段 setup() 函数在程序启动时仅执行一次,用于完成初始化配置,例如设置…...
2025年RAG技术发展现状分析
2025年,大模型RAG(检索增强生成)技术经历了快速迭代与深度应用,逐渐从技术探索走向行业落地,同时也面临安全性和实用性的新挑战。以下是其发展现状的综合分析: 一、技术架构的持续演进 从单一到模块化架构 …...
C++11新特性_范围-based for 循环
based for 循环介绍 范围 - based for 循环(Range-based for loop)是 C11 引入的一种新的 for 循环语法,它可以更简洁地遍历容器和数组。 遍历数组:定义了一个整数数组 arr,使用范围 - based for 循环 for (int num :…...
小牛电动:荣登央视舞台,引领智能出行新潮流
在这个科技飞速发展的时代,出行方式也在不断地变革与创新。而在两轮电动车领域,有一个品牌凭借其卓越的技术、独特的设计和优质的服务脱颖而出,那就是小牛电动。近日,小牛电动荣登央视舞台,成为备受瞩目的焦点…...
Three.js在vue中的使用(一)-基础
Three.js 是一个基于 WebGL 的 JavaScript 3D 图形库,它简化了在网页中创建和渲染 3D 场景的复杂性。Three.js 提供了丰富的功能,如光照、材质、几何体、动画、控制器等,使得开发者可以快速构建交互式的 3D 应用。 🧠 Three.js 原理概述 1. WebGL 基础 Three.js 底层使用…...
开发板型号 ESP32-DevKitC-32模块型号 ESP32-WROOM-32 和主控芯片 ESP32-D0WDQ6-V3
以下是关于开发板型号 ESP32-DevKitC-32、模块型号 ESP32-WROOM-32 和主控芯片 ESP32-D0WDQ6-V3 的详细介绍: 开发板型号:ESP32-DevKitC-32 概述:ESP32-DevKitC 是乐鑫推出的一款基于 ESP32 模组的小型开发板,板上模组的绝大部…...
【C语言练习】015. 声明和初始化指针
015. 声明和初始化指针 015. 声明和初始化指针1. 声明指针示例1:声明一个指向整数的指针2. 初始化指针示例2:将指针初始化为`NULL`示例3:将指针初始化为某个变量的地址示例4:将指针初始化为动态分配的内存地址3. 使用指针访问和修改变量的值示例5:使用指针访问和修改变量的…...
手撕哈希表
引入:unordered_set /map是什么? 库里面除开set和map,还有unordered_set 和 unordered_map,区别在于: ①:set和map的底层结构是红黑树,而unordered_set和unordered_map的底层是哈希表 ②&…...
编程题python常用技巧-持续
1.字典 1.1排序 在Python中,要按照字典的值进行排序,可以按照以下步骤操作: 方法说明 获取键值对列表:使用 dict.items() 获取字典的键值对视图。排序键值对:使用 sorted() 函数,并通过 key 参…...