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

星野录(博客系统)测试报告

目录

一.  项目背景

二、项目功能

三、测试计划

1. 功能测试

1.1 测试用例

1.2 执行测试部分操作截图

2. 使用selenium进行自动化测试

2.1 添加相关依赖

2.2 登录页面测试

3.3 注册页面测试

 3.4 博客列表页面测试

3.5 博客详情页测试

 3.6 博客编辑页面测试

3.7 个人主页测试

3. 使用jmeter进行性能测试

3.1 jmeter基础配置

3.2 页面接口测试

3.2.1 测试博客登录页接口

3.2.2 测试博客列表接口

3.2.3 测试博客详情页接口

3.3 性能测试


一.  项目背景

  1. 基于SpringBoot框架开发的个人博客系统,采用数据库存储数据并部署于云服务器。前端包含六个核心页面:登录页、注册页、个人主页、博客列表页、博客详情页和博客编辑页。系统实现了完整的用户功能体系,包括:账号注册登录、个人信息管理、博客撰写编辑、账号注销及强制登录验证等功能。

  2. 该系统为个人用户提供了简洁高效的博客记录平台,支持完整的内容展示功能。每篇博客的时间戳、标题、正文及作者信息均可清晰查阅,满足用户的基本写作和阅读需求。


二、项目功能

该个人博客系统主要实现了以下几个功能:登录、注册、修改个人信息、注销、编写博客以及删除博客等功能。

1.登录功能:输入用户名以及密码,登录成功后就会跳转到列表页面。登录页面的右上角有主页和写博客两个按钮,但是在未登录情况下按下均只会跳转到登录页面。

2.注册功能:在登录页面点击注册按钮后跳转到注册页面,在注册页面输入用户名、密码、头像、gitee地址,用户名要求必须是纯字符并且长度满足4~16位之间,密码要求6位~12位之间,头像必须上传,gitee地址可以不输入。

3.修改个人信息功能:登录成功后进入了博客主页面,此时点击头像进入个人信息页面,可点击编辑个人信息对用户名、密码、gitee地址以及头像都可以进行修改。

4.注销功能:登录成功后,点击右上角的注销按钮,可退出当前用户的登录跳转到登录页。

5.编写博客功能:登录后,点击右上角的写博客,进入博客编辑页面,支持使用MarkDown格式,编写完成后可以点击发布,后续也可以对发布的博客进行修改。

6.删除博客功能:可以将当前登录用户编写的博客进行删除操作。


三、测试计划

1. 功能测试

1.1 测试用例

1.2 执行测试部分操作截图

1)正常登录,跳转到博客列表页

2)注册成功,并使用注册的账号进行登录

3)对个人信息进行修改

4)编写博客,并发布

5)对博客进行修改、删除

6)注销,点击后返回到登录页

2. 使用selenium进行自动化测试

自动化测试代码地址:自动化测试: 自动化测试代码 - Gitee.com

下面将展示UI自动化测试的部分相关代码

2.1 添加相关依赖

<dependencies><!--驱动管理--><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope></dependency><!--安装selenium库--><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>

2.2 登录页面测试

/*** 页面可以正常显示*/public void checkPageRight() throws IOException {// 检擦菜单driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));// 检查登录框driver.findElement(By.cssSelector("#username"));// 账号输入框driver.findElement(By.cssSelector("#password"));// 密码输入框driver.findElement(By.cssSelector("#submit"));// 提交按钮driver.findElement(By.cssSelector("#register"));// 注册按钮screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}
/*** 成功登录*/public void loginSuccess() throws IOException {// 先清空框中的内容driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");// 账号输入框driver.findElement(By.cssSelector("#password")).sendKeys("123456");// 密码输入框driver.findElement(By.cssSelector("#submit")).click();// 提交按钮// 跳转页面后检查新页面的元素是否存在来判断是否跳转成功driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));// 检查注销按钮是否存在driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a"));// 检查查看全文按钮是否存在screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}
/*** 异常登录* 举例:账号正确,密码错误*/public void loginFail() throws IOException {driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");// 账号输入框driver.findElement(By.cssSelector("#password")).sendKeys("1234567");// 密码输入框driver.findElement(By.cssSelector("#submit")).click();// 提交按钮// 显示等待,等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理弹出的窗口,等窗口出现后才能处理,否则会报错Alert alert = driver.switchTo().alert();alert.accept();screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());}

3.3 注册页面测试

    /***注册成功*/public void checkRegisterSuc() throws InterruptedException {// 一、注册// 满足4-16位driver.findElement(By.cssSelector("#username")).sendKeys("xiaoliuTest");// 满足至少6位driver.findElement(By.cssSelector("#password")).sendKeys("123456");// 上传头像driver.findElement(By.cssSelector("#avatar")).sendKeys("C:\\Users\\22350\\Desktop\\OIP-C.jpg");driver.findElement(By.cssSelector("body > div.container-register > div > form > button")).click();Thread.sleep(2000);// 对弹窗点击确定wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();// 二、测试是否注册成功driver.findElement(By.cssSelector("#username")).sendKeys("xiaoliuTest");// 账号输入框driver.findElement(By.cssSelector("#password")).sendKeys("123456");// 密码输入框driver.findElement(By.cssSelector("#submit")).click();// 提交按钮Thread.sleep(2000);// 跳转页面后检查新页面的元素是否存在来判断是否跳转成功driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));// 检查注销按钮是否存在driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a"));// 检查查看全文按钮是否存在}
    /*** 注册失败*/public void checkRegisterFail() throws InterruptedException {// 一、注册(用户名不符合)// 用户名少于4位driver.findElement(By.cssSelector("#username")).sendKeys("Tes");// 满足至少6位driver.findElement(By.cssSelector("#password")).sendKeys("123456");// 上传头像driver.findElement(By.cssSelector("#avatar")).sendKeys("C:\\Users\\22350\\Desktop\\OIP-C.jpg");driver.findElement(By.cssSelector("body > div.container-register > div > form > button")).click();Thread.sleep(2000);// 对弹窗点击确定wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();}

 3.4 博客列表页面测试

public void checkList() throws InterruptedException {// 检查元素的文本内容是否存在String title = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.title")).getText();String time = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.date")).getText();String content = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.desc")).getText();String button = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).getText();// 使用断言来判断assert !title.isEmpty();assert !time.isEmpty();assert !content.isEmpty();assert button.equals("查看全文>>");// 检查“查看全文”按钮是否可以跳转driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();// 显示等待,等待跳转后的页面的相应文本加载WebElement element = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title"));wait.until(ExpectedConditions.textToBePresentInElement(element, title));// 跳转后检查 跳转后的标题是否和跳转前的标题一致String AfterJumpTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();assert title.equals(AfterJumpTitle);// 将当前的url传给父类的detail,供util的子类使用detailUrl = driver.getCurrentUrl();// 将个人主页地址传给父类driver.findElement(By.cssSelector("#userAvatar")).click();loginIdUrl = driver.getCurrentUrl();}

3.5 博客详情页测试

    /*** 检查博客详情的内容*/public void checkPage() {// 标题driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title"));// 时间driver.findElement(By.cssSelector("body > div.container > div.right > div > div.date"));// 内容driver.findElement(By.cssSelector("#detail"));// 编辑按钮driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(1)"));// 删除按钮driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)"));}
    /*** 检擦编辑按钮*/public void checkDetailEdit() throws InterruptedException {// 初始标题String title = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();// 点击编辑按钮driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(1)")).click();// 给更新的标题名后加上时间,可以防止更新的标题相同SimpleDateFormat simp = new SimpleDateFormat("HHmmssSS");String titleTime = simp.format(System.currentTimeMillis());Thread.sleep(100);// 强制等待driver.findElement(By.cssSelector("#title")).clear();// 输入更改后的标题driver.findElement(By.cssSelector("#title")).sendKeys("自动化测试文章" + titleTime);// 点击提交按钮driver.findElement(By.cssSelector("#submit")).click();// 等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();// 显示等待文本加载完毕wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.container > div.right > div > div.title")));// 获取更新后的标题String afterEditTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();// 如果不相同则更新成功assert !title.equals(afterEditTitle);System.out.println("更新前的标题:"+title);System.out.println("更新后的标题:"+afterEditTitle);}
    /*** 检查博客删除按钮*/public void checkDetailDel() {// 跳转到博客详情页driver.get(detailUrl);driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)")).click();wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();// 确认alert.accept();}

 3.6 博客编辑页面测试

    /*** 博客提交成功*/public void checkSubmitSuc() throws InterruptedException {// 一、编写并发送一篇新文章// 给更新的标题名后加上时间,可以防止标题相同SimpleDateFormat simp = new SimpleDateFormat("HHmmssSS");String titleTime = simp.format(System.currentTimeMillis());Thread.sleep(1000);String beforeTitle = "自动化创建的博客"+titleTime;driver.findElement(By.cssSelector("#title")).sendKeys(beforeTitle);wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#title")));WebElement ele = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));// 使用鼠标键盘操作不可互动的元素new Actions(driver).click(ele).sendKeys("自动化输入内容").perform();Thread.sleep(3000);driver.findElement(By.cssSelector("#submit")).click();// 确认发表博客成功弹窗wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();// 二、校验 (新发送的博客位于最后面)// 先获取所有的博客List<WebElement>  elements = driver.findElements(By.cssSelector("body > div.container > div.right > div"));// 获取最后一个博客String afterTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child("+elements.size()+") > div.title")).getText();assert beforeTitle.equals(afterTitle);}
    /*** 博客提交失败,有内容,没有标题*/public void checkSubmitFailNoTitle() throws InterruptedException {// 一、编写并发送一篇新文章// 标题为空driver.findElement(By.cssSelector("#title"));// 使用鼠标键盘操作不可互动的元素WebElement ele = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));new Actions(driver).click(ele).sendKeys("自动化输入内容").perform();Thread.sleep(1000);driver.findElement(By.cssSelector("#submit")).click();// 发送失败弹窗wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();}
    /*** 博客提交失败,有标题,没有内容*/public void checkSubmitFailNoContent() throws InterruptedException {// 给更新的标题名后加上时间,可以防止标题相同SimpleDateFormat simp = new SimpleDateFormat("HHmmssSS");String titleTime = simp.format(System.currentTimeMillis());Thread.sleep(1000);String beforeTitle = "自动化创建的博客"+titleTime;driver.findElement(By.cssSelector("#title")).sendKeys(beforeTitle);wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#title")));// 将内容清空WebElement ele = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));new Actions(driver).doubleClick(ele).click(ele).sendKeys(Keys.DELETE).perform();Thread.sleep(1000);driver.findElement(By.cssSelector("#submit")).click();// 发送失败弹窗wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();}

3.7 个人主页测试

    /*** 检查页面*/public void checkPersonPage() throws InterruptedException {Thread.sleep(1000);// 文章标是否存在driver.findElement(By.cssSelector("body > div.container > div.right > div.tab-buttons > button.tab-btn.active"));// 点击个人信息按钮driver.findElement(By.cssSelector("body > div.container > div.right > div.tab-buttons > button:nth-child(2)")).click();Thread.sleep(1000);// 再点击文章按钮driver.findElement(By.cssSelector("body > div.container > div.right > div.tab-buttons > button:nth-child(1)")).click();Thread.sleep(1000);}
    /*** 测试编辑个人信息功能(修改用户名)*/public void checkPersonEdit() throws InterruptedException {// 点击个人信息按钮driver.findElement(By.cssSelector("body > div.container > div.right > div.tab-buttons > button:nth-child(2)")).click();Thread.sleep(1000);driver.findElement(By.cssSelector("#editProfileBtn")).click();// 更改前的用户名String beforeName = driver.findElement(By.cssSelector("body > div.container > div.left > div > h3")).getText();driver.findElement(By.cssSelector("#editUsername")).clear();// 更改后的用户名String afterName = "zhangsana";driver.findElement(By.cssSelector("#editUsername")).sendKeys(afterName);// 点击保存按钮driver.findElement(By.cssSelector("body > div.container > div.right > div.action-btns > button.save-btn")).click();wait.until(ExpectedConditions.alertIsPresent());Alert alert = driver.switchTo().alert();alert.accept();Thread.sleep(1000);String temp = driver.findElement(By.cssSelector("body > div.container > div.left > div > h3")).getText();assert !beforeName.equals(temp);}

3. 使用jmeter进行性能测试

3.1 jmeter基础配置

1)打开jmeter后,首先创建一个线程组:

 2)设置HTTP请求默认值:

3)添加JSON断言:

要求测试的返回结果状态必须是SUCCESS

比如:

只有code的值位SUCCESS才显示这次的接口请求测试成功

以下演示部分测试

3.2 页面接口测试

3.2.1 测试博客登录页接口

进行登录接口的测试:

测试结果:

3.2.2 测试博客列表接口

结果返回都正确

3.2.3 测试博客详情页接口

3.3 性能测试

聚合报告:

相应时间:

吞吐量:

生成性能测试报告:

相关文章:

星野录(博客系统)测试报告

目录 一. 项目背景 二、项目功能 三、测试计划 1. 功能测试 1.1 测试用例 1.2 执行测试部分操作截图 2. 使用selenium进行自动化测试 2.1 添加相关依赖 2.2 登录页面测试 3.3 注册页面测试 3.4 博客列表页面测试 3.5 博客详情页测试 3.6 博客编辑页面测试 3.7 个人…...

使用 Java 实现一个简单且高效的任务调度框架

目录 一、任务调度系统概述 (一)任务调度的目标 (二)任务调度框架的关键组成 二、任务状态设计 (一)任务状态流转设计 (二)任务表设计(SQL) 三、单机任务调度实现 (一)获取待处理任务 (二)执行任务 代码实现(单线程版本) (三)多线程提高吞吐量 四…...

2022—2025年:申博之路及硕士阶段总结

文章目录 1 前景概要2 打造神兵利器2.1 夺天地之精2.2 锻兵魂之形2.3 契人兵之命 3 潜心闭关修炼3.1 第一阶段&#xff1a;苦心智3.2 第二阶段&#xff1a;劳筋骨3.3 第三阶段&#xff1a;摧意志 4 突破晋级4.1 突破失败4.2 聚气凝神4.3 心魔再现4.4 新起点 5 回顾及深思 1 前景…...

项目执行中缺乏灵活应对机制,如何增强适应性?

项目执行中缺乏灵活应对机制可以通过建立风险预警机制、培养团队快速响应能力、制定动态调整方案、加强团队沟通协作、引入敏捷管理理念来增强适应性。 其中&#xff0c;培养团队快速响应能力尤为重要。这种能力意味着当项目遇到突发状况时&#xff0c;团队能迅速评估问题、确定…...

Agentic Workflow是什么?Agentic Workflow会成为下一个AI风口吗?

无论是想要学习人工智能当做主业营收&#xff0c;还是像我一样作为开发工程师但依然要运用这个颠覆开发的时代宠儿&#xff0c;都有必要了解、学习一下人工智能。 近期发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;入行门槛低&#x…...

大模型模型推理的成本过高,如何进行量化或蒸馏优化

在人工智能的浪潮中,大模型已经成为推动技术革新的核心引擎。从自然语言处理到图像生成,再到复杂的多模态任务,像GPT、BERT、T5这样的庞大模型展现出了惊人的能力。它们在翻译、对话系统、内容生成等领域大放异彩,甚至在医疗、金融等行业中也开始扮演重要角色。可以说,这些…...

BUUCTF[极客大挑战 2019]EasySQL 1题解

[极客大挑战 2019]EasySQL题解 分析解题过程漏洞原理分析明确注入点&#xff1a;尝试万能密码法法一法二 总结 分析 从题目分析&#xff0c;这道题应该与SQL注入有关&#xff0c;启动靶机之后&#xff0c;访问url是一个登录界面&#xff0c;随便输入用户名密码之后&#xff0…...

Css样式中设置gap: 12px以后左右出现距离问题解析

原因核心&#xff1a; 虽然写的是&#xff1a; display: flex; gap: 12px;但在实际 DOM 中&#xff0c;这段结构&#xff1a; <div class"el-form-item__content"><div class"el-input"><input type"text" class"el-inpu…...

MySQL问题:count(*)与count(1)有什么区别

Count&#xff08;1&#xff09;查询过程 如果表里只有主键索引&#xff0c;没有二级索引时&#xff0c;InnoDB循环遍历主键索引&#xff0c;将读取到的记录返回给Server层&#xff0c;但是不会读取记录中的任何字段的值&#xff0c;因为count函数的参数是1&#xff0c;不是字…...

大模型 提示模板 设计

大模型 提示模板 设计 论文介绍:LangGPT - 从编程语言视角重构大语言模型结构化可复用提示设计框架 核心问题: 现有提示工程缺乏结构化设计模板,依赖经验优化,学习成本高且复用性低,难以支持提示的迭代更新。 创新思路: 受编程语言的结构化和可复用性启发,提出LangGP…...

excel表格记账 : 操作单元格进行加减乘除 | Excel中Evaluate函数

文章目录 引用I 基础求和∑II Excel中Evaluate函数基于字符串表达式进行计算用法案例 :基于Evaluate实现汇率计算利润知识扩展在单元格内的换行选择整列单元格引用 需求: 基于汇率计算利润,调整金额以及进汇率和出汇率自动算出利润,已经统计总利润。 基于Evaluate实现汇率计…...

20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s

20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s 2025/6/2 18:15 缘起&#xff1a;有些时候&#xff0c;需要在uboot阶段做一些事情。 于是&#xff0c;希望在荣品的PRO-RK3566开发板的Android13下的uboot启动停下。 1、【原始的LOG&#xff…...

如何合理设计缓存 Key的命名规范,以避免在共享 Redis 或跨服务场景下的冲突?

设计合理的缓存 Key 命名规范对于避免冲突、提高可维护性和可读性至关重要&#xff0c;尤其是在共享 Redis 实例或跨服务调用的场景下。 以下是一个推荐的缓存 Key 命名规范和设计思路&#xff1a; 一、核心原则 唯一性 (Uniqueness): 这是最重要的原则&#xff0c;确保不同…...

Trae CN IDE自动生成注释功能测试与效率提升全解析

Trae CN IDE 的自动注释功能可以通过 AI 驱动的代码分析生成自然语言注释&#xff0c;以下是具体测试方法和优势总结&#xff1a; 一、Python 代码注释生成测试 1. 测试环境 IDE&#xff1a;Trae CN IDE&#xff08;需确认支持 Python&#xff09;代码示例&#xff1a; def …...

让AI弹琴作曲不再是梦:Python+深度学习玩转自动化音乐创作

让AI弹琴作曲不再是梦:Python+深度学习玩转自动化音乐创作 一、AI也能谱出动人的旋律?真不是科幻! 还记得小时候学钢琴时老师的那句经典:“感觉不到情绪的乐句,是没灵魂的。” 当时我一边练琴一边想:要是有个机器能帮我写谱、调性又不跑调就好了! 结果几年后,真被我碰…...

C++概率论算法详解:理论基础与实践应用

清言神力&#xff0c;创作奇迹。接受福利&#xff0c;做篇笔记。 参考资料 [0] 概率论中均值、方差、标准差介绍及C/OpenCV/Eigen的三种实现. https://blog.csdn.net/fengbingchun/article/details/73323475. [4] C中的随机数及其在算法竞赛中的使用 - 博客园. https://www.…...

ssh登录wsl2

1. ssh服务重新安装 Ubuntu20.04子系统自带的ssh服务无法连接&#xff0c;需卸载后重新安装。 sudo apt-get remove openssh-server sudo apt-get install openssh-server2. 修改配置信息 sudo vim /etc/ssh/sshd_config修改内容&#xff1a; # 最好一模一样 Port 33 # 这…...

黑马Java面试笔记之 消息中间件篇(Kafka)

一. Kafka保证消息不丢失 Kafka如何保证消息不丢失 使用Kafka在消息的收发过程中都会出现消息丢失&#xff0c;Kafka分别给出了解决方案 生产者发送消息到Brocker丢失消息在Brocker中存储丢失消费者从Brocker接收消息丢失 1.1 生产者发送消息到Brocker丢失 设置异步发送 消息…...

LeetCode - 234. 回文链表

目录 题目 快慢双指针步骤 读者可能的错误写法 正确的写法 题目 234. 回文链表 - 力扣&#xff08;LeetCode&#xff09; 快慢双指针步骤 找到链表的中点&#xff08;find_mid函数&#xff09;&#xff1a; 使用快慢指针&#xff0c;慢指针每次走一步&#xff0c;快指针…...

PYTHON通过VOSK实现离线听写支持WINDOWSLinux_X86架构

在当今人工智能快速发展的时代&#xff0c;语音识别技术已经成为人机交互的重要方式之一。本文将介绍如何使用Python结合Vosk和PyAudio库实现一个离线语音识别系统&#xff0c;无需依赖网络连接即可完成语音转文字的功能。 技术栈概述 1. Vosk语音识别引擎 Vosk是一个开源的…...

nginx+tomcat动静分离、负载均衡

一、理论 nginx用于处理静态页面以及做调度器&#xff0c;tomcat用于处理动态页面 lvs&#xff08;四层&#xff09; 轮询&#xff08;rr&#xff09; 加权轮询&#xff08;wrr&#xff09; 最小连接&#xff08;lc&#xff09; 加权最小连接&#xff08;wlc&#xff09; ngi…...

SQL进阶之旅 Day 13:CTE与递归查询技术

【SQL进阶之旅 Day 13】CTE与递归查询技术 引言 欢迎来到“SQL进阶之旅”的第13天&#xff01;今天我们重点探讨的是CTE&#xff08;公用表表达式&#xff09;与递归查询技术。CTE是现代SQL中的一个重要特性&#xff0c;能够极大地提高复杂查询的可读性与维护性。而递归CTE则…...

【PmHub面试篇】Gateway全局过滤器统计接口调用耗时面试要点解析

你好&#xff0c;欢迎来到本次关于Gateway全局过滤器统计接口调用耗时的面试系列分享。在这篇文章中&#xff0c;我们将深入探讨这一技术领域的相关面试题预测。若想对相关内容有更透彻的理解&#xff0c;强烈推荐参考之前发布的博文&#xff1a;【PmHub后端篇】PmHub Gateway全…...

neo4j 5.19.0两种基于向量进行相似度查询的方式

介绍 主要讲的是两种相似度查询 一种是创建向量索引&#xff0c;然后直接从索引的所有数据中进行相似度搜索&#xff0c;这种不支持基于自己查询的结果中进行相似度匹配另一种是自己调用向量方法生产相似度进行相似度搜索&#xff0c;这种可以基于自己的查询结果中进行相似度…...

项目课题——基于ESP32的智能插座

一、功能需求 1.1 基础功能 ✅ 远程控制 通过Wi-Fi实现手机APP/小程序远程开关支持定时任务&#xff08;如定时开启热水器&#xff09; &#x1f50c; 用电监测 实时显示电压/电流/功率电能统计&#xff08;日/月/年用电量报表&#xff09; &#x1f50b;多接口支持 220V三线…...

华为云Flexus+DeepSeek征文|利用华为云 Flexus 云服务一键部署 Dify 平台开发文本转语音助手全流程实践

目录 前言 1 华为云 Flexus 与 Dify 平台简介 1.1 Flexus&#xff1a;为AI而生的轻量级云服务 1.2 Dify&#xff1a;开源的LLM应用开发平台 2 一键部署Dify平台至Flexus环境 3 构建文本转语音助手应用 3.1 创建ChatFlow类型应用 3.2 配置语音合成API的HTTP请求 3.3 设…...

ck-editor5的研究 (7):自定义配置 CKeditor5 的 toolbar 工具栏

文章目录 一、前言二、实现步骤1. 第一步: 搭建目录结构2. 第二步:配置toolbar工具栏的步骤(2-1). 配置粗体和斜体(2-2). 配置链接和标题+正文(2-3). 配置列表和引用(2-4). 配置自动格式化3. 第三步:更多工具三、测试效果和细节四、总结一、前言 在前面的文章中,我们已经对…...

MPLS-EVPN笔记详述

目录 EVPN简介: EVPN路由: 基本四种EVPN路由 扩展: EVPN工作流程: 1.启动阶段: 2.流量转发: 路由次序整理: 总结: EVPN基本术语: EVPN表项: EVPN支持的多种服务模式: 简介: 1.Port Based: 简介: 配置实现: 2.VLAN Based: 简介: 配置实现: 3.VLAN Bundle: 简…...

嵌入式Linux系统中的启动分区架构

在嵌入式Linux系统架构中,Linux内核、设备树(Device Tree)与引导配置文件构成了系统启动的基础核心。如何安全、高效地管理这些关键文件,直接影响到系统的稳定性与可维护性。近年来,越来越多的嵌入式Linux开发者选择将启动相关文件从传统的“混合存放”方式,转向采用独立…...

无人机甲烷检测技术革新:开启环境与能源安全监测新时代

市场需求激增&#xff0c;技术革新势在必行 随着全球气候变化加剧&#xff0c;甲烷作为第二大温室气体&#xff0c;其减排与监测成为国际社会关注焦点。据欧盟甲烷法规要求&#xff0c;2024 年起欧洲能源基础设施运营商需定期测量甲烷排放并消除泄漏。与此同时&#xff0c;极端…...