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

自动化测试项目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…...

【数据结构】励志大厂版·初阶(复习+刷题):栈与队列

前引:本篇将由小编与大家一起复习 栈 、队列 的知识点,栈、队列的顺序、链式结构各个缺点好处,如何实现、对于一般的增删查找此篇文章一定再详细不过!对代码的注释、何时需要判断、特殊情况,白话文版一解到底&#xff…...

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编程中,修饰类的关键字起着至关重要的作用&#xff…...

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 :…...

小牛电动:荣登央视舞台,引领智能出行新潮流

在这个科技飞速发展的时代,出行方式也在不断地变革与创新。而在两轮电动车领域,有一个品牌凭借其卓越的技术、独特的设计和优质的服务脱颖而出,那就是小牛电动。近日,小牛电动荣登央视舞台,成为备受瞩目的焦点&#xf…...

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 参…...