《基于Selenium的论坛系统自动化测试实战报告》
一、项目背景与技术选型
-
项目简介
-
目标系统:论坛系统
-
核心功能:用户注册/登录、会话框发送信息、好友列表、信息发送
-
技术栈:html + Springboot + MySQL数据库
-
-
为什么选择Selenium
-
支持多浏览器兼容性测试(Chrome/Firefox/Edge)
-
完善的元素定位体系(XPath/CSS Selector)
-
动态内容处理能力(WebDriverWait机制)
-
跨平台执行能力(Windows/Linux/macOS)
-
-
测试环境
在开始测试之前,我们需要准备好测试环境。以下是测试所需的硬件和软件环境:
-
硬件:普通个人电脑
-
操作系统:Windows 10 或 Windows 11
-
浏览器:Chrome(版本 128.0.6613.84 或以上)
-
项目运行环境:maven、JDK1.8
-
自动化测试工具:Selenium
二、测试用例设计+手动测试
用户注册
用户登录
用户退出+站内私信
个人中心
帖子模块
三、功能测试用例设计
3.1 注册页面测试
3.1.1 测试场景 1:注册信息不全
-
预期结果:页面提示部分信息不能为空。
-
实际结果:系统确实给出了相应的提示,要求补全所有必填项,与预期一致。
3.1.2 测试场景 2:用户名已存在
-
预期结果:系统应该提示用户该用户名已经存在。
-
实际结果:系统确实给出了提示,提示用户该用户名已经存在,与预期结果一致。
3.1.3 测试场景 3:密码与确认密码不一致
-
预期结果:系统应该提示用户检查确认密码是否输入一致。
-
实际结果:系统确实给出了相应的提示,指示用户检查确认密码,与预期结果一致。
3.1.4 测试场景 4:注册成功
-
预期结果:系统应该显示注册成功,并跳转回登录界面。
-
实际结果:系统确实显示了注册成功,并且跳转回了登录界面,符合预期。
3.2 登录页面测试
3.2.1 测试场景 1:用户名和密码正确
-
预期结果:系统应该显示登录成功,并跳转到论坛首页。
-
实际结果:系统确实显示了登录成功,并且跳转到了论坛首页,与预期结果一致。
3.2.2 测试场景 2:用户名正确,密码错误
-
预期结果:系统应该显示登录失败,并给出相应的错误提示。
-
实际结果:系统确实显示了登录失败,并给出了错误提示,符合预期。
3.2.3 测试场景 3:用户名不存在
-
预期结果:系统应该显示登录失败,并给出相应的错误提示。
-
实际结果:系统确实显示了登录失败,并给出了错误提示,符合预期。
3.3 首页测试
3.3.1 测试场景 1:未登录或登录过期
-
预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
-
实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
3.3.2 测试场景 2:登录状态下点击“首页”按钮
-
预期结果:应该显示导航栏中的所有版块名称,下方应显示所有帖子列表,并且右上方应该显示登录用户的信息。
-
实际结果:系统确实展示了导航栏中的所有版块名称,下方显示了所有帖子列表,并且右上方显示了登录用户的信息,与预期一致。
3.4 编辑界面测试
3.4.1 测试场景 1:未登录状态下尝试进入编辑页面
-
预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
-
实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
3.4.2 测试场景 2:登录状态下发布帖子时不输入帖子标题
-
预期结果:系统应该给出提示,要求用户输入帖子标题。
-
实际结果:系统确实给出了提示,要求用户输入帖子标题,与预期一致。
3.4.3 测试场景 3:登录状态下发布帖子时不输入帖子内容
-
预期结果:系统应该给出提示,要求用户输入帖子内容。
-
实际结果:系统确实给出了提示,要求用户输入帖子内容,与预期一致。
3.4.4 测试场景 4:登录状态下输入了帖子标题和帖子内容,然后点击发布按钮
-
预期结果:系统应该成功编辑帖子,并跳转回首页,最上方应该显示刚发布的帖子信息。
-
实际结果:系统确实执行了编辑成功的操作,跳转回了首页,并在最上方显示了刚发布的帖子信息,与预期一致。
3.5 帖子详情页面测试
3.5.1 测试场景 1:未登录或者登录过期的状态下,点击首页中的任意一条帖子内容
-
预期结果:系统应该自动跳转回登录界面,要求用户重新登录。
-
实际结果:系统确实执行了跳转回登录界面的操作,与预期一致。
3.5.2 测试场景 2:登录状态下,点击首页中的一条帖子内容–作者和登录用户不一样
-
预期结果:系统应该跳转到该帖子的详情页面。
-
实际结果:系统确实跳转到了该帖子的详情页面。
3.5.3 测试场景 3:登录状态下,点击首页中的一条帖子内容–作者和当前登录用户一样
-
预期结果:系统应该跳转到该帖子的详情页面,最上方应该显示该帖子的信息,左侧应该显示帖子作者的信息,下方应该显示点赞按钮、删除按钮和编辑按钮。
-
实际结果:系统没有展示了预期的内容,包括帖子信息、作者信息、帖子内容以及点赞按钮、删除按钮和编辑按钮,与预期一致。
、
等等一系列功能的手动测试实践
四、自动化测试实现
整体设计如下
4.1导入pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>ForumAutoTest</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version></dependency><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency></dependencies><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties></project>
这次没有用到Junit单元测试方法,用的都是平常常见依赖
4.2 Utils类
package common;import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
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.time.Duration;/*** Created with IntelliJ IDEA.* Description:自动化测试论坛系统公共方法*/public class Utils {public static WebDriver driver;public static WebDriver createDriver(){if(driver == null){WebDriverManager.chromedriver().setup();ChromeOptions options = new ChromeOptions();//允许访问所有链接options.addArguments("--remote-allow-origins=*");driver = new ChromeDriver(options);//等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));}return driver;}public Utils(String url) {//调用driver对象driver = createDriver();//访问urldriver.get(url);//窗口最大化driver.manage().window().maximize();}//屏幕截图public void getScreenShot(String str) throws IOException, IOException {// ./src/test/image/// /2024-07-17/// /test01-17453010.png// /2024-07-18/// /test01-17453030.png//屏幕截图SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());//./src/test/image/2025-xx-xx/test01-17453020.pngString filename ="./src/test/image/"+ dirTime +"/" + str + "-" + fileTime+".png";File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);//srcFile放到指定位置FileUtils.copyFile(srcFile,new File(filename));}}
常见的浏览器驱动和屏幕快照
4.3注册页面功能测试 RegisterPageTest.java
package Test;import common.Utils;
import org.openqa.selenium.By;import java.io.IOException;/*** Created with IntelliJ IDEA.* Description:自动化测试论坛系统注册页面* Author: WJW*/
public class RegisterPageTest extends Utils {public static String url = "http://127.0.0.1:9580/sign-up.html";public RegisterPageTest() {super(url);}public void RegisterPageRight() {//论坛logo图标driver.findElement(By.cssSelector("body > div > div > div.text-center.mb-4 > img"));//用户注册driver.findElement(By.cssSelector("#signUpForm > div > h2"));}//注册成功public void RegisterSuc() throws InterruptedException {//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("橘子004");//输入昵称driver.findElement(By.cssSelector("#nickname")).sendKeys("橘子树0");//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123");//输入确认密码driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");//点击同意使用条款和隐私服务driver.findElement(By.cssSelector("#policy")).click();//点击注册driver.findElement(By.cssSelector("#submit")).click();Thread.sleep(1000);//校验注册是否成功并返回登录页面String title = driver.getTitle();assert title.equals("比特论坛 - 用户登录");}//注册失败01--该用户已存在public void RegisterFai01() throws IOException {//在登录页面点击注册按钮// driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a")).click();//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("1");//输入昵称driver.findElement(By.cssSelector("#nickname")).sendKeys("1");//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123");//输入确认密码driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");//点击同意使用条款和隐私服务driver.findElement(By.cssSelector("#policy")).click();//点击注册driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String fail01 = driver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2")).getText();//对当前异常进行截图getScreenShot(getClass().getName());//断言assert fail01.equals("警告");}//注册失败02--用户名为空public void RegisterFai02() throws IOException {//刷新当前注册页面driver.navigate().refresh();//输入用户名 当前用户名为空driver.findElement(By.cssSelector("#username"));//输入昵称driver.findElement(By.cssSelector("#nickname")).sendKeys("1");//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123");//输入确认密码driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");//点击同意使用条款和隐私服务driver.findElement(By.cssSelector("#policy")).click();//点击注册driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String fail02 = driver.findElement(By.cssSelector("#signUpForm > div > div:nth-child(2) > div")).getText();//对当前异常进行截图getScreenShot(getClass().getName());//断言assert fail02.equals("用户名不能为空");}//注册失败03--昵称为空public void RegisterFai03() throws IOException {//刷新当前注册页面driver.navigate().refresh();//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("1");//输入昵称 当前昵称为空driver.findElement(By.cssSelector("#nickname"));//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123");//输入确认密码driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");//点击同意使用条款和隐私服务driver.findElement(By.cssSelector("#policy")).click();//点击注册driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String fail03 = driver.findElement(By.cssSelector("#signUpForm > div > div:nth-child(3) > div")).getText();//截图保存当前异常getScreenShot(getClass().getName());//断言assert fail03.equals("昵称不能为空");}//注册失败04--密码与确认密码不一致public void RegisterFai04() throws IOException {//刷新当前注册页面driver.navigate().refresh();//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("101");//输入昵称driver.findElement(By.cssSelector("#nickname")).sendKeys("111");;//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("13");//输入确认密码driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");//点击同意使用条款和隐私服务driver.findElement(By.cssSelector("#policy")).click();//点击注册driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String fail04 = driver.findElement(By.cssSelector("#signUpForm > div > div:nth-child(5) > div > div")).getText();getScreenShot(getClass().getName());assert fail04.equals("请检查确认密码");}//注册失败05--未点击同意使用条款和隐私服务public void RegisterFai05() throws IOException {//刷新当前注册页面driver.navigate().refresh();//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("101");//输入昵称driver.findElement(By.cssSelector("#nickname")).sendKeys("111");;//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123");//输入确认密码driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");//未点击同意使用条款和隐私服务driver.findElement(By.cssSelector("#policy"));//点击注册driver.findElement(By.cssSelector("#submit")).click();//截图保存当前异常getScreenShot(getClass().getName());}}
4.4登录页面功能测试 LoginPageTest.java
package Test;import common.Utils;
import org.openqa.selenium.By;import java.io.IOException;/*** Created with IntelliJ IDEA.* Description:自动化测试论坛系统登录页面*/
public class LoginPageTest extends Utils {public static String url = "http://127.0.0.1:9580/sign-in.html";public LoginPageTest() {super(url);}//通过查看页面元素是否存在来检查页面加载成功与否public void loginPageRight(){//论坛logo图标driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img"));//用户登录driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2"));}//检查登录功能public void LoginSuc(){//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("xiaoweng");//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("0123");//点击登录按钮driver.findElement(By.cssSelector("#submit")).click();//检查点击登录是否成功//通过查看比特论坛logo是否登录成功driver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > h1 > a > img"));//通过查看发布帖子是否登录成功driver.findElement(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post"));//通过页面标题来检查是否成功String title = driver.getTitle();assert title.equals("比特论坛");//返回登录页面// driver.navigate().back();//刷新页面// driver.navigate().refresh();}//检查登录失败01--密码错误public void LoginFail01() throws IOException {//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("aaa");//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123456");//点击登录按钮driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String res01 = driver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div>h2")).getText();//截图保存测试结果验证警告提示内容是否与预期一致getScreenShot(getClass().getName());assert res01.equals("警告");//通过刷新保证输入框没有文本driver.navigate().refresh();}//检查登录失败02--用户名为空public void LoginFail02() throws IOException {//输入用户名driver.findElement(By.cssSelector("#username"));//输入密码driver.findElement(By.cssSelector("#password")).sendKeys("123456");//点击登录按钮driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String res02 = driver.findElement(By.cssSelector("#signInForm > div.mb-3 > div")).getText();//截图保存测试结果验证警告提示内容是否与预期一致getScreenShot(getClass().getName());assert res02.equals("用户名不能为空");//通过刷新保证输入框没有文本driver.navigate().refresh();}//检查登录失败03--密码为空public void LoginFail03() throws IOException {//输入用户名driver.findElement(By.cssSelector("#username")).sendKeys("swhdf");//输入密码driver.findElement(By.cssSelector("#password"));//点击登录按钮driver.findElement(By.cssSelector("#submit")).click();//获取当前异常文本String res03 = driver.findElement(By.cssSelector("#signInForm > div.mb-2 > div > div")).getText();//截图保存测试结果验证警告提示内容是否与预期一致getScreenShot(getClass().getName());assert res03.equals("密码不能为空");//通过刷新保证输入框没有文本driver.navigate().refresh();}}
4.5 不登入页面功能测试 PageByNoLogin.java
package Test;import common.Utils;public class PageByNoLogin extends Utils {public static String listurl = "http://127.0.0.1:9580/index.html";public PageByNoLogin() {super(listurl);}public void ListPageByNoLogin() throws InterruptedException {// driver.get(listurl);//直接返回登录界面Thread.sleep(1000);String title = driver.getTitle();assert title.equals("比特论坛 - 用户登录");}
}
4.6 总测试用例 RunTests.java
import common.Utils;
import Test.ListPageTest;
import Test.LoginPageTest;
import Test.PageByNoLogin;
import Test.RegisterPageTest;import java.io.IOException;/*** Created with IntelliJ IDEA.* Description:论坛系统自动化测试* Author: HY* Date: 2025-03-02* Time: 21:16*/
public class RunTests {public static void main(String[] args) throws IOException, InterruptedException {//未登录页面测试PageByNoLogin pageByNoLogin = new PageByNoLogin();pageByNoLogin.ListPageByNoLogin();RegisterPageTest register = new RegisterPageTest();
// //测试注册页面是否加载成功register.RegisterPageRight();
// //注册成功register.RegisterSuc();//注册失败register.RegisterFai01();register.RegisterFai02();register.RegisterFai03();register.RegisterFai04();register.RegisterFai05();LoginPageTest login = new LoginPageTest();//测试登录页面是否加载成功login.loginPageRight();//登录失败login.LoginFail01();login.LoginFail02();login.LoginFail03();// 登录成功login.LoginSuc();ListPageTest list = new ListPageTest();//测试列表页面是否加载成功list.ListByLoging();//测试站内信息回复成功list.MessageSuc();//测试站内信息回复失败list.MessageFail();//成功发布帖子list.PublishPostSuc();//发布帖子失败list.PublishPostFail();//显示个人帖子list.ShowPost();// 点赞list.LickCount();/*//编辑成功list.EditSuc();//编辑失败list.EditFail();//删除成功list.DeleteSuc();//删除失败list.DeleteFail();*///回复成功list.RepleSuc();//回复失败list.RepleFail();//个人中心list.PersonalCenter();//个人中心修改失败list.PersonalCenterModifyFail01();list.PersonalCenterModifyFail02();list.PersonalCenterModifyFail03();//个人中心修改成功list.PersonalCenterModifySuc();//退出list.Exit();//释放driver对象Utils.driver.quit();}
}
五、常见错误Exception in thread "main" org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element is not clickable at point
常见的很多都是一些基础的写法,有一部分地方当我们直接使用
类似于
driver.findElement(By.cssSelector("#setting_submit_email")).click();
这样的写法时,我们会发现,如果这个提交或者修改按钮不在你打开的这个页面当中时,我们会发现一个
Exception in thread "main" org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element is not clickable at point
这样的一个报错,我所作的修改是类似于
// 定位提交按钮WebElement submitButton = driver.findElement(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div.form-footer>button"));((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'});",submitButton);// 添加短暂等待确保滚动完成Thread.sleep(1000);WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));wait.until(ExpectedConditions.elementToBeClickable(submitButton)).click();
这样的写法,显示等待并用js去定位我们的按钮,当然,很重要的一点,你在自己将页面滑下去的时候,它会停留在你定位按钮的位置,接下来当然要把它在返回上去
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, 0);");
这是我在编写我的测试时遇到的一个比较常见且应该记住的一个错误
测试完整版视频可见我主页视频资源内
论坛测试
相关文章:

《基于Selenium的论坛系统自动化测试实战报告》
一、项目背景与技术选型 项目简介 目标系统:论坛系统 核心功能:用户注册/登录、会话框发送信息、好友列表、信息发送 技术栈:html Springboot MySQL数据库 为什么选择Selenium 支持多浏览器兼容性测试(Chrome/Firefox/Edge&…...
深入解析SQL Server高级SQL技巧
SQL Server 是一种功能强大的关系型数据库管理系统,广泛应用于各种数据驱动的应用程序中。在开发过程中,掌握一些高级SQL技巧,不仅能提高查询性能,还能优化开发效率。这篇文章将全面深入地探讨SQL Server中的一些高级技巧…...
分布式中间件:环境准备
在当今数字化的时代,分布式系统已经成为了开发领域的主流。分布式中间件在其中扮演着至关重要的角色,它能够帮助我们更好地处理高并发、高可用等复杂的业务场景。在这个系列的博客中,我将带大家深入学习分布式中间件的相关知识,主…...

c# winform程序 vs2022 打包生成安装包
最近,利用c# winform程序该客户开发一套进销存管理系统,项目在部署前,需要生成安装包,以便部署在客户电脑上面。总结步骤如下: 1、在打包之前 (VS中需要包括Microsoft visual studio installer projects扩展项目)&…...

探索Elasticsearch:文档的CRUD
在企业环境中,Elasticsearch对文档操作的支持不仅是实现高效搜索的关键,更是数据驱动决策的重要支柱。它通过强大的索引机制和灵活的查询语言,使企业能够实时处理和分析海量文档数据,迅速获取有价值的洞察,从而加速创新…...
面试基础--Spring Boot启动流程及源码实现
深度解析Spring Boot启动流程及源码实现 一、Spring Boot启动全景图(含核心阶段) #mermaid-svg-dYTQ6WPa3o6vKFHh {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dYTQ6WPa3o6vKFHh .error-i…...

火语言RPA--PDF提取图片
【组件功能】:提取PDF文档指定位置图片 配置预览 配置说明 文件路径 支持T或# 默认FLOW输入项 待提取图片的PDF文件的完整路径。 提取位置 全部、指定页、指定范围3种位置供选择。 PDF文件密码 支持T或# 打开PDF文件的密码。 页码 支持T或# 提取指定页的页…...
力扣977.有序数组的平方(双指针)
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 方法一:直接将每个元素的平方压入ans数组中,再对ans数组进行排序 class Solution { public:vector<int> sort…...

QT——文件IO
QFile 类 构造函数 QFile() 无参构造 仅仅构建一个QFile 对象,不设定文件名 QFile(文件名) 构建一个QFile对象的同时,设定文件名 但是注意,仅仅设定文件名,并不会打开该文件 设定文件名 QFile file file.setFileName…...
分布式中间件:Redis介绍
目录 Redis 概述 Redis 的特点 高性能 丰富的数据结构 持久化 分布式特性 简单易用 Redis 的数据结构 字符串(String) 哈希(Hash) 列表(List) 集合(Set) 有序集合&…...
服务器和本地电脑之间如何传输文件
在服务器和本地电脑之间传输文件可以通过多种方式实现,常见的方法包括使用 SFTP(安全文件传输协议)、SCP(安全复制协议)、FTP(文件传输协议)、rsync、以及 云存储 等工具。以下是几种常见的方法…...

经验分享:用一张表解决并发冲突!数据库事务锁的核心实现逻辑
背景 对于一些内部使用的管理系统来说,可能没有引入Redis,又想基于现有的基础设施处理并发问题,而数据库是每个应用都避不开的基础设施之一,因此分享个我曾经维护过的一个系统中,使用数据库表来实现事务锁的方式。 之…...

嵌入式学习前要了解的基础知识
一、电压和电流 在嵌入式开发中,电压和电流是两个基本的电气概念,对于理解和设计电子电路至关重要。它们直接影响到嵌入式系统的性能、功耗、可靠性和安全性。 电压(Voltage) 电压是电场力推动电荷移动的能力,通常以…...
RTC、直播、点播技术对比|腾讯云/即构/声网如何选型 — 2025 版
前言 作为一个有多年实战经验的开发者,在音视频技术领域我深刻体会到 RTC(实时通信)、直播和点播三者的不同。虽然它们的核心都涉及音视频内容的传输,但在实际应用中,它们的技术实现、使用场景以及所面临的挑战各不相…...

《白帽子讲 Web 安全》之文件操作安全
目录 引言 (一)文件上传与下载漏洞概述 1.文件上传的常见安全隐患 1.1前端校验的脆弱性与服务端脚本执行危机在文件上传流程中,部分开发者可能会在前端使用 JavaScript 代码对文件后缀名进行简单校验,试图以此阻止非法文件上传…...
yolov8训练模型、测试视频
yolov8先训练生成best.pt文件,用这个生成的模型进行视频的测试 因为本来用的代码生成的测试视频打不开,格式应该是损坏了,或者部分帧没有正常保存吧。 修改了一下代码,现状可以正常打开生成的视频了。 1、训练代码train.py im…...
03.网络编程套接字(二)
文章目录 简单的TCP网络程序 服务端创建套接字 服务端绑定 服务端监听 服务端获取连接 服务端处理请求 客户端创建套接字 客户端发起请求 服务器测试 单执行流服务器的弊端 多进程版的TCP网络程序 线程池版的TCP网络程序 简单的TCP网络程序 服务端创建套接字 我…...

一周学会Flask3 Python Web开发-Flask3之表单处理WTForms安装与定义WTForms表单类
锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们平时开发项目,都会用到表单,编写表单,提交表单,验证表单,如果…...
Git基本命令索引
GIT基本命令索引 创建代码库修改和提交代码日志管理远程操作操作分支 创建代码库 操作指令初始化仓库git init克隆远程仓库git clone 修改和提交代码 操作指令查看文件状态git status文件暂存git add文件比较git diff文件提交git commit回滚版本git reset重命名或者移动工作…...

【论文阅读笔记】SL-YOLO(2025/1/13) | 小目标检测 | HEPAN、C2fDCB轻量化模块
目录 摘要 1 引言 2 相关工作 3 方法 3.1 为小目标检测增加一个头 3.2 优化网络结构 3.3 改进轻量化模块 3.3.1 C2fDCB 3.3.2 SCDown 4 实验 4.1 数据集 4.2 实验环境 4.3 与其他模型的比较 4.4 消融研究 ▲不同网络结构的分析 ▲不同模块的分析 ▲不同降采样…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...