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

多用户网页在线聊天室(测试报告)

文章目录

  • 多用户网页在线聊天室
    • 一,项目概括
      • 1.1 项目名称
      • 1.2 测试时间
      • 1.3 项目背景
      • 1.3 编写目的
    • 二,测试计划
      • 2.1 测试环境与配置
      • 2.2 测试用例
      • 2.3实际执行用例
        • 2.3.1登录
        • 2.3.2聊天消息列表展示
        • 2.3.3聊天消息详情页展示
        • 2.3.4联系人页展示
        • 2.3.5信息的编辑与发送
        • 2.3.6搜索框
    • 三、自动化测试工具
      • 3.1 注入依赖
      • 3.2 注册自动化测试
      • 3.3 未登录情况测试
      • 3.4 登录自动化测试
      • 3.5 聊天室页面自动化测试
      • 3.6 自动化测试结果总结
      • 3.6 自动化测试结果总结

多用户网页在线聊天室

一,项目概括

1.1 项目名称

多用户网页在线聊天室

1.2 测试时间

2024.6——2024.6

1.3 项目背景

随着现代互联网的快速发展,实时通信系统已成为人们日常交流的重要工具。为了让这个聊天室既好用又稳定,项目里加了一套“自动检查”系统(自动化测试)。比如登录、加好友、发消息这些核心功能,不用手动一遍遍测,而是用写好的程序自动模拟操作,快速发现问题。这样一来,无论用哪种浏览器或者网络环境,聊天功能都能稳稳运行,用户体验更流畅。

聊天室采用了Spring MVC作为后端框架,通过WebSocket实现消息的实时传输,前端使用原生HTML和CSS构建用户界面。项目的自动化测试部分通过Selenium编写,结合Python语言进行测试脚本开发,覆盖了用户登录、好友管理、消息传输等核心功能模块,确保用户能够在各类浏览器和网络条件下获得一致、流畅的聊天体验。

1.3 编写目的

对编写的网页聊天室项目进行软件测试活动,揭示潜在问题,总结测试过程种地成功经验与不足,以便于更好的进行测试工作


二,测试计划

2.1 测试环境与配置

平台:Windows 10
浏览器:Chrome
自动化测试工具:Selenium + Junit5

2.2 测试用例

2.3实际执行用例

2.3.1登录

用户名以及密码已经在后端写入了数据库是已经存在的,登录成功后就会跳转到聊天页面

输入正确的账号和密码(以用户"zhangsan"为例):

预期结果:出现登录成功的弹窗,点击后,跳转到博客列表页。

实际结果如下:

输入错误的账号或密码

预期结果:提示用户登录失败。

实际结果如下:在这里插入图片描述

2.3.2聊天消息列表展示

可以在列表页(主页)查看有限数量的聊天,其包括联系人名称、及最近一条消息内容。并且点击对应联系人之后会跳转到相应的聊天详情页

2.3.3聊天消息详情页展示

可以在详情页。查看具体聊天内容,其包括联系人名称、及聊天内容。

2.3.4联系人页展示

可以在联系人页展示查看联系人,其包括联系人名称。并且点击相应联系人后会跳转到相应聊天详情页。

image-20250312224144005

2.3.5信息的编辑与发送

可以在信息的编辑与发送页进行信息的操作,其包括编辑内容与发送内容。

image-20250312224349149

2.3.6搜索框

可以搜索内容输入内容点击“放大镜”按钮

image-20250312224443531

三、自动化测试工具

3.1 注入依赖

在maven—poom.xml中,引入依赖

 <dependencies><!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version></dependency><!--  截图  --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.1</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.9.1</version></dependency><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.9.1</version></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.1</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite --><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.1</version></dependency><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.9.1</version><scope>test</scope></dependency></dependencies>   
  • 单例驱动

    • 自动化测试程序过程中,会频繁的使用驱动,如果频繁的创建和销毁,开销还是比较大的,因此我们可以使用懒汉模式加载驱动
    • 这样可以保证驱动不会频繁创建,能减轻程序刚开始启动时的系统开销(只有用到驱动是才会加载它)
    • 如果其他类需要使用到驱动的话,直接继承该类即可
  • 获取屏幕截图

    • 当我们测试用例出错时,我们需要查看当时网页出现的情况,那么就需要使用屏幕截图来排查问题
    • 使用 getScreenshotAs 方法来保存屏幕截图,在每个测试用例执行完后进行一次屏幕截图
    • 屏幕截图统一保存到一个路径下,文件名以当时时间去组织(防止保存屏幕截图出现覆盖情况)
    • 综上,我们便在 AutoTestUtils类下加上保存截图的方法,方便其他类调用

package common;import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;public class AutoTestUtils {private static ChromeDriver driver;public static ChromeDriver getDriver() {ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");if (driver == null) {driver = new ChromeDriver(options);//创建隐式等待,设置最长等待时间10sdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);}return driver;}/*** 获取屏幕截图,将用例执行结果保存下来*/public void getScreenShot(String str) throws IOException {List<String> list = getTime();String fileName = "./src/main/java/chatRoomAutoTest/" + list.get(0) + list.get(0) + "/" + str + "_" + list.get(1) + ".png";File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);//把生成的截图放入指定路径FileUtils.copyFile(srcFile,new File(fileName));}//获取当前时间(记录每个屏幕截图是什么时候拍摄的)private List<String> getTime() {SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");//保存的文件夹名 当天的年月日 + 具体时间String fileName = sdf1.format(System.currentTimeMillis());//保存的图片名  当天的年月日String dirName = sdf2.format(System.currentTimeMillis());List<String> list = new ArrayList<>();list.add(dirName);list.add(fileName);return list;}}

3.2 注册自动化测试

此处我们创建一个 RegTest 类继承 AutoTestUtils 类得到驱动

先测试注册页面是否正常打开,输入.最后进行相应弹窗处理,进行屏幕截图


package UserTest;import common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;import java.io.IOException;import static java.lang.Thread.sleep;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class RegTest extends AutoTestUtils {//获取到驱动private static WebDriver driver = AutoTestUtils.getDriver();/*** 打开网页* 注册网页一般是从登录页面进入*/@BeforeAllpublic static void openWeb() {//打开登录页面driver.get("http://182.92.153.14:9091/login.html");//再点击登录页面的注册链接按钮driver.findElement(By.cssSelector("body > div.login-container > div > div:nth-child(4) > a")).click();driver.manage().window().maximize();}/*** 验证网页正常打开*/@Test@Order(1)public void elementsAppear() throws IOException {//用户名输入框driver.findElement(By.cssSelector("#username"));//密码输入框driver.findElement(By.cssSelector("#password"));//注册按钮driver.findElement(By.cssSelector("#submit"));//登录账号链接driver.findElement(By.cssSelector("body > div.register-container > div > div:nth-child(4) > a"));getScreenShot(getClass().getName());}/*** 注册失败测试用例* 参数: 尝试注册已注册用户*/@ParameterizedTest@CsvSource({"zhangsan,123"})@Order(2)public void regFunTest(String username, String passowrd) throws InterruptedException, IOException {//输入账号driver.findElement(By.cssSelector("#username")).sendKeys(username);//输入密码driver.findElement(By.cssSelector("#password")).sendKeys(passowrd);//点击注册driver.findElement(By.cssSelector("#submit")).click();//等待弹窗sleep(3000);//期望结果String expect = "注册失败!";String actual = driver.switchTo().alert().getText();Alert alert = driver.switchTo().alert();if (alert != null) {alert.accept();} else {actual = "当前用例执行失败";}//断言Assertions.assertEquals(expect, actual);//屏幕截图getScreenShot(getClass().getName());}/*** 注册成功测试用例*/@ParameterizedTest@CsvSource({"lisi,123,注册成功!"})@Order(3)public void regTest(String username, String password,String expect) throws InterruptedException, IOException {//拿到元素WebElement inputUserName = driver.findElement(By.cssSelector("#username"));WebElement inputPassword = driver.findElement(By.cssSelector("#password"));WebElement button = driver.findElement(By.cssSelector("#submit"));//清除输入框inputUserName.clear();inputPassword.clear();//输入用例inputUserName.sendKeys(username);inputPassword.sendKeys(password);//提交button.click();//强制等待弹窗Thread.sleep(100);Alert alert = driver.switchTo().alert();//期望结果String actual = "注册成功!";if(alert != null) {alert.accept();}else {actual = "当前用例执行失败";}Assertions.assertEquals(expect,actual);//屏幕截图getScreenShot(getClass().getName());}
}

3.3 未登录情况测试

此处我们创建一个 InterceptTest 类继承 AutoTestUtils 类得到驱动

测试未登录情况下,打开会话页面,进行相应弹窗处理,进行屏幕截图


package UserTest;import common.AutoTestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.chrome.ChromeDriver;import static java.lang.Thread.sleep;public class InterceptTest extends AutoTestUtils {//获取驱动private static ChromeDriver driver = AutoTestUtils.getDriver();@Testpublic void Intercept() throws InterruptedException {//在未登录的情况下,跳转会话页driver.get("http://182.92.153.14:9091/client.html");sleep(2000);//期望结果String expect = "当前用户未登录!";String actual = "当前用户未登录!";Alert alert = driver.switchTo().alert();if (alert != null) {alert.accept();} else {actual = "当前用例执行失败";}//屏幕截图getScreenShot(getClass().getName());//断言Assertions.assertEquals(expect,actual);}
}

3.4 登录自动化测试

此处我们创建一个 LoginTest 类继承 AutoTestUtils 类得到驱动

先测试登录页面是否正常打开,再找几个典型的用例对异常,正常登录风别进行测试

最后进行相应弹窗处理,进行屏幕截图

package UserTest;import common.AutoTestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;import java.io.IOException;import static java.lang.Thread.sleep;public class LoginTest extends AutoTestUtils {//获取到驱动private static WebDriver driver = AutoTestUtils.getDriver();/*** 打开页面* 注册页面一般是从登录页面进入*/@BeforeAllpublic static void openWeb() {//先打开登录页面driver.get("http://182.92.153.14:9091/login.html");driver.manage().window().maximize();}/*** 检测登录页面是否能正常打开*/@Test@Order(1)public void elementsAppear() throws IOException {//用户名输入框driver.findElement(By.cssSelector("#username"));//密码输入框driver.findElement(By.cssSelector("#password"));//注册账号链接driver.findElement(By.cssSelector("body > div.login-container > div > div:nth-child(4) > a"));//登录按钮driver.findElement(By.cssSelector("#submit"));//屏幕截图getScreenShot(getClass().getName());}/*** 异常测试登录功能* 参数一:尝试登录未注册用户* 参数二:密码输入错误,登录账号*/@ParameterizedTest@CsvSource({"zhang,123","zhangsan,123456"})@Order(2)public void loginAbnormalTest(String username,String password) throws InterruptedException, IOException {//拿到元素WebElement inputUserName = driver.findElement(By.cssSelector("#username"));WebElement inputPassword = driver.findElement(By.cssSelector("#password"));WebElement button = driver.findElement(By.cssSelector("#submit"));//清除用户名,密码inputUserName.clear();inputPassword.clear();//输入账号,密码inputUserName.sendKeys(username);inputPassword.sendKeys(password);//点击登录button.click();//等待弹窗sleep(3000);//期望结果String expect = "登录失败!";String actual = "登录失败!";Alert alert = driver.switchTo().alert();if(alert != null) {alert.accept();} else {actual = "当前用例执行失败!";}Assertions.assertEquals(expect,actual);//屏幕截图getScreenShot(getClass().getName());}/*** 正常登录测试*/@ParameterizedTest@CsvSource({"'zhangsan','123','登陆成功'"})@Order(3)public void loginNormalTest(String userName,String password,String expect) throws InterruptedException, IOException {//发现元素WebElement inputUserName = driver.findElement(By.cssSelector("#username"));WebElement inputPassword = driver.findElement(By.cssSelector("#password"));WebElement button = driver.findElement(By.cssSelector("#submit"));//清除用户名密码inputUserName.clear();inputPassword.clear();//输入用户名,密码inputUserName.sendKeys(userName);inputPassword.sendKeys(password);//点击登录button.click();//等待弹窗sleep(3000);//期望结果String actual = driver.switchTo().alert().getText();//断言Assertions.assertEquals(expect,actual);//处理弹窗driver.switchTo().alert().accept();//屏幕截图getScreenShot(getClass().getName());}
}

3.5 聊天室页面自动化测试

此处我们创建一个 ClientTest 类继承 AutoTestUtils 类得到驱动

先对页面功能以及聊天功能进行自动化测试,进行相应的弹窗处理,最后进行屏幕截截图

package UserTest;import common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;import java.io.IOException;import static java.lang.Thread.sleep;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ClientTest extends AutoTestUtils {//获得驱动public static WebDriver driver = AutoTestUtils.getDriver();/*** 打开会话页面*/@BeforeAllpublic static void openWeb() {//先打开会话页面driver.get("http://182.92.153.14:9091/client.html");driver.manage().window().maximize();}/*** 测试会话页面正常打开*/@Test@Order(1)public void elementsAppear() throws IOException {//主页个人账号名driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.user"));//搜索输入框driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > input[type=text]"));//搜索按钮driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button"));//会话标签图driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session"));//好友标签图driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-friend"));//聊天输入框driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea"));//发送按钮driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button"));//屏幕截图getScreenShot(getClass().getName());}/*** 点击具体会话* 检验:消息页面展示当前会话用户名字*/@Order(2)@Testvoid SessionList() throws InterruptedException {//点击具体会话driver.findElement(By.xpath("//*[@id=\"session-list\"]/li[1]/h3")).click();sleep(3000);//获取到消息页面展示当前用户名字String actual = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title")).getText();Assertions.assertEquals("wangwu",actual);}/*** 点击好友列表*/@Order(3)@Testvoid FriendList() throws InterruptedException {//点击好友按钮,打开好友列表driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-friend")).click();sleep(3000);//点击好友driver.findElement(By.xpath("//*[@id=\"friend-list\"]/li[1]/h4")).click();sleep(3000);//检验选中的好友在会话列表是否被置顶String text = driver.findElement(By.cssSelector("#session-list > li.selected > h3")).getText();Assertions.assertEquals("lisi",text);}/*** 测试聊天发送功能* 参数:zhangsan 给  wangwu 发送数据*/@ParameterizedTest@CsvSource({"正在自动化测试中...","测试发送成功","测试结束!"})@Order(4)public void TalkSendTest(String msg) throws InterruptedException, IOException {//点击好友会话开始聊天driver.findElement(By.xpath("//*[@id=\"session-list\"]/li[2]/h3")).click();sleep(3000);//选择输入框开始聊天driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys(msg);//点击发送driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();sleep(3000);//判断消息是否发送成功//屏幕截图getScreenShot(getClass().getName());}/*** 测试聊天接收功能* 参数:登录 wangwu 查看与 zhangsan 历史会话,检验是否发送成功*/@Test@Order(5)public void TalkAcceptTest() throws InterruptedException {//打开页面driver.get("http://182.92.153.14:9091/login.html");sleep(3000);//输入账号driver.findElement(By.cssSelector("#username")).sendKeys("wangwu");//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123");//点击登录driver.findElement(By.cssSelector("#submit")).click();sleep(3000);//确认弹窗driver.switchTo().alert().accept();sleep(3000);//点击 zhangsan 会话driver.findElement(By.cssSelector("#session-list > li > h3")).click();//获取好友名String name = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title")).getText();//获取最后一条消息String text = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.message-show > div:nth-child(3) > div > p")).getText();//判断好友是否一致Assertions.assertEquals("zhangsan",name);//判断消息是否一致Assertions.assertEquals("测试结束!",text);}
}

3.6 自动化测试结果总结

    driver.switchTo().alert().accept();sleep(3000);//点击 zhangsan 会话driver.findElement(By.cssSelector("#session-list > li > h3")).click();//获取好友名String name = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title")).getText();//获取最后一条消息String text = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.message-show > div:nth-child(3) > div > p")).getText();//判断好友是否一致Assertions.assertEquals("zhangsan",name);//判断消息是否一致Assertions.assertEquals("测试结束!",text);}
}

3.6 自动化测试结果总结

image-20250312225452566

相关文章:

多用户网页在线聊天室(测试报告)

文章目录 多用户网页在线聊天室一&#xff0c;项目概括1.1 项目名称1.2 测试时间1.3 项目背景1.3 编写目的 二&#xff0c;测试计划2.1 测试环境与配置2.2 测试用例2.3实际执行用例2.3.1登录2.3.2聊天消息列表展示2.3.3聊天消息详情页展示2.3.4联系人页展示2.3.5信息的编辑与发…...

字节青训营后端方向的个人总结(2025年3月4日)

字节青训营的结营总结&#xff08;25寒假&#xff09; ——致青训营队友的一封信 明天就是大项目结项的日子了&#xff0c;不知道大家在这方面学习、精进了多少&#xff0c;也许有的朋友收获颇多并且已经完成了项目&#xff0c;我个人对此表示由衷的恭喜和祝贺。 当初自告奋…...

VX iOS分析随记

断SVC的时候看调用栈&#xff0c;发现里面一个特别大的ollvm函数。vx版本8054 * thread #36, queue com.apple.root.default-qos, stop reason breakpoint 4.1 frame #0: 0x0000000111ad6124 WeChat___lldb_unnamed_symbol1315083 20 WeChat___lldb_unnamed_symbol13150…...

docker 小记

一、卸载 查看当前版本 docker -v2. 如果有&#xff0c;先停止docker systemctl stop docker如果是yum安装&#xff0c;卸载方式为 #已防版本冲突&#xff0c;直接卸载 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-lat…...

AI代码编程辅助工具

现在AI火的一塌糊涂&#xff0c;作为技术应该更应该关注当前AI对编程行业的影响。 分享下当前网络上最火的网络编程辅助工具。 以下是个人搜集到的可以对编程起辅助作用的工具&#xff1a; 2025年最佳AI编程辅助工具 1. GitHub Copilot 这个工具也许你已经在使用了&#xff0…...

使用 kubectl cp 命令可以在 Kubernetes Pod 和本地主机之间拷贝文件或文件夹

使用 kubectl cp 命令可以在 Kubernetes Pod 和本地主机之间拷贝文件或文件夹 kubectl cp <namespace>/<pod-name>:<pod-path> <local-path> # 从 Pod 拷贝到本地 kubectl cp <local-path> <namespace>/<pod-name>:<pod-path&g…...

【eNSP实战】交换机配置端口隔离

交换机端口隔离可以实现在同一个VLAN内对端口进行逻辑隔离&#xff0c;端口隔离分为L2层隔离和L3层隔离&#xff0c;这里只进行L2层隔离演示。 拓扑图 路由器AR1配置GE 0/0/1配置IP&#xff0c;其余PC主机各自配置IP和网关。 现将PC1到PC4四个主机全部进行L2层隔离&#xff0c…...

动态规划-第2篇

前言&#xff1a;在上一篇文章中&#xff0c;我们了解了动态规划的基本概念和解决问题的基本思路。通过分解问题、存储子问题的解&#xff0c;动态规划为我们提供了高效的解决方案。然而&#xff0c;动态规划并不是一成不变的&#xff0c;它有很多不同的技巧和变种&#xff0c;…...

数据库查问题常用OS命令汇总

1、内存使用情况查看 top //查看活跃进程占用情况 free -mh //查看操作系统当前可用内存 2、cpu使用情况 lscpu //查看os cpu情况 sar -u -f sar文件名 -s hh:mm:ss -e hh:mm:ss //查看对应日期的历史cpu情况 top //查看当前活跃进程使用cpu情况 3、io情况 iostat …...

基于springboot住院管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 随着世界经济信息化、全球化的到来和电子商务的飞速发展&#xff0c;推动了很多行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、畅通、高效的线上管理系统。当前的住院管理存在管理效率低下&…...

《用Python+PyGame开发双人生存游戏!源码解析+完整开发思路分享》

导语​ "你是否想过用Python开发一款可玩性高的双人合作游戏&#xff1f;本文将分享如何从零开始实现一款类《吸血鬼幸存者》的生存射击游戏&#xff01;包含完整源码解析、角色系统设计、敌人AI逻辑等核心技术点&#xff0c;文末提供完整代码包下载&#xff01;" 哈…...

【ES6】在ES6中自定义数组

在ES6中是允许自定义类扩展基础类型的&#xff0c;因为这些基础类型是有构造函数的&#xff0c;在JS中类就是函数。 // 自定义数组 class myArray extends Array {constructor() {super();} }let arr new myArray();arr.push(1);console.log(arr);重写Array的原生方法 ES6的…...

软件开发项目有哪些风险

软件开发项目风险主要包括 需求不明确、技术实现难度大、进度延误、成本超支、质量问题。其中&#xff0c;需求不明确可能导致功能设计反复修改&#xff1b;技术实现难度大会使开发过程中不断遇到未知挑战&#xff1b;进度延误常常因资源配置不足或变更频繁而发生&#xff1b;成…...

47.HarmonyOS NEXT 登录模块开发教程(二):一键登录页面实现

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT 登录模块开发教程&#xff08;二&#xff09;&#xff1a;一键登录页面实现 文章目录 HarmonyOS NEXT 登录模块开发教程&#xff0…...

RAGFlow版本升级-Win10系统Docker

下载源码压缩包 https://github.com/infiniflow/ragflow.git 删除旧版本代码文件夹&#xff0c;把下载的代码解压到原先目录 更新一下env文件&#xff1a;ragflow/docker/.env 把值改为最新版本即可 RAGFLOW_IMAGEinfiniflow/ragflow:v0.17.1 更新一下docker docker compose -…...

dns劫持是什么?常见的劫持类型有哪些?如何预防?

DNS劫持的定义 DNS劫持&#xff08;Domain Name System Hijacking&#xff09;是一种网络攻击手段&#xff0c;攻击者通过篡改域名解析的过程&#xff0c;将用户对某个域名的访问请求重定向到错误或恶意的IP地址。这种攻击可能导致用户访问到钓鱼网站、恶意广告页面&#xff0…...

Python精进系列: isinstance 函数

Python isinstance函数&#xff1a;类型检查的得力助手 目录 Python isinstance函数&#xff1a;类型检查的得力助手引言一、isinstance函数基础语法结构简单示例 二、isinstance函数的应用场景函数参数类型检查数据处理与类型转换面向对象编程中的类型判断 三、isinstance函数…...

【基础知识】回头看Maven基础

版本日期修订人描述V1.02025/3/7nick huang创建文档 背景 项目过程中&#xff0c;对于Maven的pom.xml文件&#xff0c;很多时候&#xff0c;我通过各种参考、仿写&#xff0c;最终做出想要的效果。 但实际心里有些迷糊&#xff0c;不清楚具体哪个基础的配置所实现的效果。 今…...

练习题:81

目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 运行思路 结束语 Python题目 题目 使用字典推导式创建一个字典&#xff0c;键为 1 到 10 的整数&#xff0c;值为键的平方。 题目分析 需求理解 本题要求使用 Python 的字典…...

三角函数:从宇宙法则到AI革命的数学密钥

——跨越三千年的数学语言与现代科技全景透视 一、数学本质&#xff1a;宇宙的波动密码 1.1 拓扑学视角下的三角函数 三角函数本质是单位圆上点的坐标参数化&#xff0c;其数学表达可抽象为&#xff1a; { x cos ⁡ θ ℜ ( e i θ ) y sin ⁡ θ ℑ ( e i θ ) \begin…...

【论文笔记】Best Practices and Lessons Learned on Synthetic Data for Language Models

论文信息 论文标题&#xff1a;Best Practices and Lessons Learned on Synthetic Data for Language Models 作者信息&#xff1a; Ruibo Liu, Jerry Wei, Fangyu Liu, Chenglei Si, Yanzhe Zhang, Jinmeng Rao, Steven Zheng, Daiyi Peng, Diyi Yang, Denny Zhou1 and Andre…...

Java高频面试之集合-10

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;详解红黑树&#xff1f;HashMap为什么不用二叉树/平衡树呢&#xff1f; 一、红黑树&#xff08;Red-Black Tree&#xff…...

Keil 5 环境下STM32F4 HAL库版本MDK工程创建详细步骤(适合小白,附工程源码)

一、前期准备 1.安装好keil Keil(MDK) 5 软件安装教程-CSDN博客https://blog.csdn.net/qq_42748213/article/details/90485750 2.安装好STM32F4的芯片包 Keil5中STM32F4xx芯片包下载安装_stm32f4芯片包-CSDN博客https://blog.csdn.net/weixin_45783141/article/details/131…...

【微服务】Nacos 配置动态刷新(简易版)(附配置)

文章目录 1、实现方法2、配置依赖 yaml3、验证效果 1、实现方法 环境&#xff1a;Nacos、Java、SpringBoot等 主要是在boostrap.yaml中的data-id属性下配置refresh:true来实现动态更新 2、配置依赖 yaml 具体的版本参考官方的说明&#xff1a;官方版本说明 <!--读取boo…...

LabVIEW cRIO中CSV文件的读取

在LabVIEW cRIO中读取CSV文件&#xff0c;需通过文件传输、路径配置、数据解析等步骤实现。本文详细说明如何通过代码读取本地存储的CSV文件&#xff0c;并探讨直接通过对话框选择文件的可行性及替代方案。 一、CSV文件传输至cRIO本地存储 1. 使用NI MAX文件管理 步骤&#xf…...

双周报Vol.67: 模式匹配支持守卫、LLVM 后端发布、支持 Attribute 语法...多项核心技术更新!

2025-03-10 语言更新 模式匹配支持守卫&#xff08;Pattern Guard&#xff09; 模式守卫可以通过在模式后追加 if ... 的语法结构来指定。有模式守卫的分支只有在被模式匹配的值满足对应模式&#xff0c;并且模式守卫为真的情况下才会执行。如果模式守卫为假&#xff0c;则会…...

从青铜到王者:六大排序算法实战解析

前言 在编程的世界里,排序算法如同一颗璀璨的明珠,闪耀着智慧的光芒。它不仅是计算机科学的基础知识点,更是每一位程序员必备的技能。今天,就让我们一同走进排序算法的世界,深入探究冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序这六大经典算法的精髓所在,…...

011-base64

base64 编码 以下是C实现的Base64字符串加密算法及其原理说明&#xff0c;综合了多个技术文档的核心要点&#xff1a; 一、Base64编码原理 Base64是一种将二进制数据转换为ASCII字符的编码方式&#xff0c;核心原理基于 3字节转4字符 的转换规则&#xff1a; 分组规则&…...

汽车NVH诊断案例 | 纯电车急加速过大弯底盘异响

引言 失去发动机的掩蔽效应后&#xff0c;新能源电车的NVH问题&#xff0c;成为了困扰维修技师新难点。风噪、胎噪、电机高频啸叫等问题更容易车主识别&#xff0c;根源却难以被有效分辨。如何更精准且高效地识别电车NVH问题根源&#xff1f;今天分享的这个案例&#xff0c;内…...

springcloud gateway通过数据库获取路由信息

在 Spring Cloud Gateway 中结合 MyBatis 动态从数据库加载路由配置&#xff0c;可以实现灵活的路由管理。以下是详细实现步骤&#xff1a; 1. 数据库表设计 创建路由配置表 gateway_route&#xff1a; CREATE TABLE gateway_route (id varchar(50) NOT NULL COMMENT 路由唯一…...

QtDataVisualization使用

Qt Data Visualization 是一个开源的第三方库&#xff0c;它为Qt框架提供了高级的数据可视化功能。这个库允许开发者创建复杂的3D和2D图表&#xff0c;包括但不限于散点图、曲面图、条形图等。它基于Qt 3D模块&#xff0c;因此可以充分利用Qt 3D引擎的强大功能来呈现三维数据。…...

【Go每日一练】实现简单的控制台计算器

&#x1f47b;创作者&#xff1a;丶重明 &#x1f47b;创作时间&#xff1a;2025年3月7日 &#x1f47b;擅长领域&#xff1a;运维 目录 1.&#x1f636;‍&#x1f32b;️题目&#xff1a;简单的控制台计算器2.&#x1f636;‍&#x1f32b;️代码输出3.&#x1f636;‍&#…...

TDengine 数据对接 EXCEL

简介 通过配置使用 ODBC 连接器&#xff0c;Excel 可以快速访问 TDengine 的数据。用户可以将标签数据、原始时序数据或按时间聚合后的时序数据从 TDengine 导入到 Excel&#xff0c;用以制作报表整个过程不需要任何代码编写过程。 前置条件 准备以下环境&#xff1a; TDen…...

1.8 双指针专题:四数之和

1.题目链接 18. 四数之和 - 力扣&#xff08;LeetCode&#xff09;18. 四数之和 - 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元…...

基于用户标签和协同过滤混合算法的商城推荐系统设计与实现

一、研究背景 随着电子商务的快速发展&#xff0c;用户面对海量商品时往往面临“信息过载”问题。传统的推荐算法&#xff08;如协同过滤&#xff09;在用户行为数据稀疏或新用户场景下存在冷启动、推荐多样性不足等缺陷。 现状与挑战&#xff1a; 协同过滤&#xff1a;依赖用…...

软件版本号设计

软件版本号的设计是软件开发中的重要环节&#xff0c;它不仅帮助开发团队管理代码&#xff0c;还能让用户清楚地了解软件的更新状态。以下是常见的版本号设计方法和最佳实践&#xff0c;供你参考&#xff1a; 1. 常见的版本号设计规范 语义化版本控制&#xff08;Semantic Ver…...

ESMFold对决AlphaFold:蛋白质-肽相互作用预测的新进展

今天向大家介绍的这篇文章题目为&#xff1a;“Protein−Peptide Docking with ESMFold Language Model”&#xff0c;近期发表在JCTC上。 本文主要研究 ESMFold 语言模型在蛋白质-肽对接中的应用。通过探索多种对接策略&#xff0c;评估其在预测蛋白质-肽相互作用方面的性能&a…...

【项目】负载均衡式在线OJ

负载均衡式在线OJ 目录 负载均衡式在线OJ 1.项目介绍&#xff1a; 2.comm 2.1 log.hpp 日志等级 开放式日志 时间戳工具 2.2 util.hpp TimeUtil类 PathUtil类 FileUtil类 StringUtil类 3.Compile_server 3.1compile_run.hpp RemoveTempFile CodeToDesc Start 3.…...

Android启动速度优化

Android启动速度优化 一、应用启动基础知识 1.1 启动类型 Android应用的启动类型主要分为三种: 冷启动(Cold Start):应用进程不存在,系统需要创建新的进程,加载并启动应用。这是最耗时的启动方式。 温启动(Warm Start):应用进程存在,但Activity可能被销毁,需要重新创…...

python爬虫碰到IP被封的情况,如何解决?

在数据抓取和爬虫开发的实践中&#xff0c;Python作为一种功能强大且易于上手的编程语言&#xff0c;被广泛应用于网络数据的采集。然而&#xff0c;随着网络环境的日益复杂&#xff0c;爬虫活动也面临着越来越多的挑战&#xff0c;其中IP被封便是常见且棘手的问题。IP被封不仅…...

Web网页制作(静态网页):千年之恋

一、是用的PyCharm来写的代码 二、代码中所用到的知识点&#xff08;无 js&#xff09; 这段HTML代码展示了一个简单的注册页面&#xff0c;包含了多个HTML元素和CSS样式的应用。 这段HTML代码展示了一个典型的注册页面&#xff0c;包含了常见的HTML元素和表单控件。通过CSS样…...

mac安装mysql之后报错zsh: command not found: mysql !

在Mac上安装MySQL后&#xff0c;如果终端中找不到mysql命令&#xff0c;通常是 因为MySQL的命令行工具&#xff08;如mysql客户端&#xff09;没有被正确地添加到你的环境变量中。 检查 MySQL 是否已安装 ps -ef|grep mysql查看到路径在 /usr/local/mysql/bin 查看 .bash_pro…...

Spring Boot 启动失败:Failed to start bean ‘documentationPluginsBootstrapper’ 解决方案

文章目录 1. 问题描述 &#x1f3af;2. 可能原因分析 &#x1f50d;原因 1&#xff1a;SpringFox 版本与 Spring Boot 版本不兼容 ❌✅ 解决方案&#xff1a;添加兼容性配置&#xff08;首选&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 原因 2&#xff1a;S…...

Python Cookbook-3.16 查看汇率

任务 想周期性地(用 crontab 或者 Windows计划任务来运行某 Python 脚本)从 Web 获取数据&#xff0c;监视某两种货币之间的兑换比例&#xff0c;并在两者之间的汇率达到某个值时发送提醒邮件。 解决方案 这个任务和一系列的从 Web 获取数据的监控任务很类似&#xff0c;它们…...

Manus(一种AI代理或自动化工具)与DeepSeek(一种强大的语言模型或AI能力)结合使用任务自动化和智能决策

一、Manus与DeepSeek差异 十分好奇DeepSeek和Manus究竟谁更厉害些&#xff0c;DeepSeek是知识型大脑&#xff0c;Manus则是全能型执行者。即DeepSeek专注于语言处理、知识整合与专业文本生成。其核心优势在于海量参数支持的深度学习和知识推理能力&#xff0c;例如撰写论文、润…...

Redis存数据就像存钱:RDB定期存款 vs AOF实时记账

Redis持久化 ◆ 核心概念1. ◆ 持久化全景图2. ◆ 生产环境黄金法则 ◆ RDB深度优化1. ◆ 生产配置精要2. ◆ 高级触发场景3. ◆ 故障应急方案 ◆ AOF深度解析1. ◆ 7.0版本革命性改进2. ◆ 同步策略深度测试3. ◆ 重写过程优化 ◆ 混合持久化实战1. ◆ 配置示例2. ◆ 数据恢复…...

【从零开始学习计算机科学】编译原理(一)编译过程概述

【从零开始学习计算机科学】编译原理(一)编译过程概述 绪论编译过程概述词法分析语法分析代码优化代码生成其他功能编译器的前端和后端绪论 什么叫编译程序?为什么我们需要编译程序?编译程序就是一个程序,将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻…...

第十八:go 并发 goroutine

channel 可以让多个goroutine 之间实现通信 Add方法调用时机&#xff1a;必须在goroutine 启动之前调用Add方法来增加计数器的值。 如果在goroutine已经启动之后再调用Add&#xff0c;可能会导致Wait方法提前返回&#xff0c;因为计数器没有正确反映正在运行的goroutine的数量…...

基于QGIS的二次开发(四):矢量编辑与属性表操作

一、实验目的 本次实验续接上一次的实验内容&#xff0c;旨在通过设计与开发地理信息系统的过程&#xff0c;加深学生对地理信息系统的理解&#xff0c;并掌握相关的设计与开发技能&#xff0c;包括熟悉地理信息系统的设计与开发流程&#xff0c;加强对 MVC 软件设计模式的理解…...

AI日报 - 2025年3月13日

&#x1f31f; 今日概览&#xff08;60秒速览&#xff09; ▎&#x1f916; AGI突破 | Reka开源21B参数推理模型Flash 3&#xff0c;推出企业智能平台Nexus &#x1f52c; 模型采用RLOO方法结合模型与规则基础奖励&#xff0c;实现高效推理 ▎&#x1f4bc; 商业动向 | Waymo在…...