博客系统——项目测试报告

目录
前言
博客系统——项目介绍
1、测试计划
1.1、功能测试
1.1.1、编写测试用例
1.1.2、实际执行步骤
1.2、使用Selenium进行Web自动化测试
1.2.1、引入依赖
1.2.2、提取共性,实现代码复用
1.2.3、创建测试套件类
1.2.4、博客登录页自动化测试
1.2.5、博客列表页自动化测试
1.2.6、博客编辑页自动化测试
1.2.7、博客详情页自动化测试
1.2.8、退出驱动
1.2.9、屏幕截图
1.2.11、自动化测试的亮点
1.2.10、自动化完整测试代码
1.3、性能测试
1.3.1、LoadRunner工具介绍
1.3.1、 UI性能测试步骤
1.3.2、编写性能测试脚本(VUG)
1.3.3、创建测试场景(Controller)
1.3.4、生成测试报告(Analysis)
小结
前言
之前实现了一个博客系统,今天我们就一起来测试以下这个博客系统的功能和性能如何吧~
博客系统——项目介绍
背景:当你在学习一项技能的时候,相信你一定有做笔记的经历,这是一个好习惯,方便你在遗忘或是复习的时候回顾知识,而接下来我要讲的这个程序,就可以方便你去写自己的学习笔记,并且可以发表出来,即方便自己学习,同时也方便别人~
概述:一个Web网站程序,你可以观看到其他用户博客也可以登录自己的账号发布博客;
相应技术栈:Servlet、HTML、CSS、JavaScript、Ajax、Json、MySQL
博客登录页:

博客列表页(用户“zhangsan”为例):

博客详情页:

博客博客编辑页:

1、测试计划
1.1、功能测试
1.1.1、编写测试用例
这里由于编写的是Web自动化测试用例,所以主要的测试的方面就是两点:功能测试和界面测试。
测试用例如下:

1.1.2、实际执行步骤
博客登录页:检测界面是否符合预期,输入正确或错误的账号和密码是否能得到预期的响应
a)界面

b)输入正确的账号和密码(以用户"zhangsan"为例):
预期结果:跳转到博客详情页。
实际结果如下:

c)输入错误的账号或密码
预期结果:提示用户输入错误。
实际结果如下:

博客列表页:检测界面是否符合预期,点击“查看全文”按钮是否能跳转到对应的博客详情页,点击注销是否能退出登录
a)界面

b)点击查看全文
预期结果:进入到对应的博客详情页。
实际结果:

c)点击注销
预期结果:删除Session会话信息,跳转到博客登录页。
实际结果:

博客详情页:检测界面是否符合预期,检测导航栏功能是否符合预期
a)界面

b)导航栏功能(以删除博客为例):删除他人博客
预期结果:不可已删除,并提示不是自己的博客无法删除。
实际结果:

博客编辑页:检测界面是否符合预期,是否能够发布博客,并再博客列表页显示。
a)界面:

b)输入标题和正文,然后发布博客
预期结果:发布博客并在博客列表页展示。
实际结果:

1.2、使用Selenium进行Web自动化测试
1.2.1、引入依赖
进行Web自动化测试,我们需要创建Maven项目引入如下依赖(selenium4、junit5、保存屏幕截图):
<dependencies><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><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.8.2</version><scope>test</scope></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.8.2</version><scope>test</scope></dependency></dependencies>
1.2.2、提取共性,实现代码复用
在我们的Web自动化测试项目中,需要对博客登录页、博客列表页、博客编辑页、博客详情页,这几个页面分别进行测试,那么可以分别创建四个类,进行针对性测试。
不难发现,这几类中都少不了的是——创建驱动和使用驱动,如果每一个类中我们都去创建驱动,最后释放驱动,这样的过程是十分消耗资源的,那么我们便可以把创建驱动这个操作放在一个类中,并设置驱动对象为静态的,就可以让创建和销毁驱动的步骤执行一次,其他类如果需要驱动直接继承该类即可~
代码如下(这里自定义类名为AutoTestUtils):
import org.openqa.selenium.chrome.ChromeDriver;import java.time.Duration;public class AutoTestUtils {private static ChromeDriver driver;//创建驱动public static ChromeDriver getDriver() {if(driver == null) {driver = new ChromeDriver();//创建隐式等待,设置最长等待时间为10秒driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));}return driver;}}
1.2.3、创建测试套件类
创建一个类(自定义名为RunSuite),通过 @Suite 注解标识该类为测试套件类(不是测试类),然后使用 @SelectClasses 注解来声明我们要指定的类(通过这个类来运行测试用例),这样优点如下:
1.相比于一个个函数调用来对测试用例进行测试就大大减少了开销和时间;
2.同时指定了类的测试顺序,即在注解@SelectClasses参数中的类测试顺序为从左向右;
代码如下:
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;@Suite
@SelectClasses({})
public class RunSuite {
}
1.2.4、博客登录页自动化测试
创建一个类(自定义名为BlogLoginTest)继承AutoTestUtils类,得到驱动,然后再这个类下分别对打开网页是否正常,并使用参数化注解对登录正常模块、登录异常模块分别进行测试。
Ps:需要注意的点都在注释中
代码和详细注释如下:
import com.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.chrome.ChromeDriver;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogLoginTest extends AutoTestUtils {//获取驱动private static ChromeDriver driver = getDriver();/*** 打开网页* 此方法需要在该类的所有测试用例执行之前执行一次,所以使用注解 @BeforeAll*/@BeforeAllprivate static void openWeb() {driver.get("http://43.139.193.116:8080/blog_system/login.html");}/*** 检测登录页面是否正常打开* 检测:元素是否都存在*/@Test@Order(1)public void elementsAppear() {driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));driver.findElement(By.cssSelector("#username"));driver.findElement(By.xpath("//*[@id=\"login-btn\"]"));}/*** 检测登录异常测试*/@ParameterizedTest@CsvSource({"zhangsan, 1234", "lisi, 4456"})@Order(2)public void loginAbnormalTest(String username, String password) {//先清除用户名和密码框driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();//输入账号和密码driver.findElement(By.cssSelector("#username")).sendKeys(username);driver.findElement(By.cssSelector("#password")).sendKeys(password);driver.findElement(By.cssSelector("#login-btn")).click();//期望结果和实际结果String expect = "用户名或密码错误!";String actual = driver.findElement(By.cssSelector("body")).getText();Assertions.assertEquals(expect, actual);driver.navigate().back();}/*** 检测正常登录情况*/@ParameterizedTest@CsvSource({"zhangsan, 123", "lisi, 123"})@Order(3)public void loginNormalTest(String username, String password) {//先清除用户名和密码框driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();//输入用户名和密码并点击登录driver.findElement(By.cssSelector("#username")).sendKeys(username);driver.findElement(By.cssSelector("#password")).sendKeys(password);driver.findElement(By.cssSelector("#login-btn")).click();//由于使用参数化的注解,所以需要继续返回到登录页面driver.navigate().back();}}
测试结果如下:
使用测试套件类RunSuite进行测试,结果如下:

1.2.5、博客列表页自动化测试
创建一个类(自定义名为BlogListTest)继承AutoTestUtils类,得到驱动,博客列表页这里需要测试打开网页正常显示,那么找几个典型的元素进行测试即可~
代码如下:
import com.common.AutoTestUtils;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;public class BlogListTest extends AutoTestUtils {//获取驱动private static ChromeDriver driver = getDriver();/*** 打开网页* 此方法需要在该类的所有测试用例执行之前执行一次,所以使用注解 @BeforeAll*/@BeforeAllprivate static void openWeb() {driver.get("http://43.139.193.116:8080/blog_system/blog_list.html");}/*** 测试博客列表页正常显示*/@Testpublic void elementsAppear() {driver.findElement(By.cssSelector("body > div.container > div.container-left > div > img"));driver.findElement(By.cssSelector("body > div.container > div.container-left > div > div:nth-child(4) > span:nth-child(1)"));driver.findElement(By.xpath("/html/body/div[1]/a[2]"));driver.findElement(By.xpath("/html/body/div[2]/div[2]/div[1]/a"));}}
测试结果如下:
使用测试套件类RunSuite进行测试,结果如下:

1.2.6、博客编辑页自动化测试
创建一个类(自定义名为BlogEditTest)继承AutoTestUtils类,得到驱动,博客编辑页这里需要测试打开网页正常显示,并且正确输入标题和正文并发布博客,若成功发布博客,通过列表页的相关信息检测是否符合预期:
代码如下:
import com.common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogEditTest extends AutoTestUtils {//获取驱动private static ChromeDriver driver = getDriver();/*** 打开网页* 此方法需要在该类的所有测试用例执行之前执行一次,所以使用注解 @BeforeAll*/@BeforeAllpublic static void openWeb() {driver.get("http://43.139.193.116:8080/blog_system/blog_edit.html");}/*** 检测博客编辑页可以正常打开*/@Test@Order(1)public void elementAppear() {driver.findElement(By.cssSelector("#blog-title"));driver.findElement(By.cssSelector("#submit"));}/*** 检测发布博客是否正常* 具体操作:* 1.输入标题* 2.由于引入的使第三方库的编辑器,所以这里点击编辑器的几个按钮来输入一些特殊字符即可* 3.点击发布按钮* 4.再进入博客博客详情页点击删除博客*/@Test@Order(2)public void blogPost() {//预期标题(成功发布博客后在博客列表页检测)String expect = "Autotest";driver.findElement(By.cssSelector("#blog-title")).sendKeys(expect);driver.findElement(By.cssSelector("#editor > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")).click();driver.findElement(By.cssSelector("#submit")).click();//获取博客列表页第一篇博客,检测是否符合预期String actual = driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.title")).getText();Assertions.assertEquals(expect, actual);}}
测试结果如下:
使用测试套件类RunSuite进行测试,结果如下:

1.2.7、博客详情页自动化测试
创建一个类(自定义名为BlogEditTest)继承AutoTestUtils类,得到驱动,博客详情页这里需要测试打开网页正常显示。
如下代码:
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;import static com.common.AutoTestUtils.getDriver;public class BlogDetailTest {//获取驱动private static ChromeDriver driver = getDriver();/*** 打开网页* 此方法需要在该类的所有测试用例执行之前执行一次,所以使用注解 @BeforeAll*/@BeforeAllpublic static void openWeb() {driver.get("http://43.139.193.116:8080/blog_system/blog_detail.html?blogId=1");}/*** 检测博客详情页信息*/@Testpublic void elementAppear() {driver.findElement(By.cssSelector("body > div.container > div.container-right > div > h3"));driver.findElement(By.cssSelector("#content > p"));driver.findElement(By.cssSelector("body > div.container > div.container-right > div > div.date"));}}
测试结果如下:
使用测试套件类RunSuite进行测试,结果如下:

1.2.8、退出驱动
在所有自动化测试用例执行完后,需要进行退出浏览器,那么我们可以创建一个退出驱动类,放在测试套件类的最后一个测试类。
代码如下:
import com.common.AutoTestUtils;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;public class DriverQuitTest extends AutoTestUtils {//获取驱动private static ChromeDriver driver = getDriver();@Testpublic void quitWeb() {driver.quit();}}
1.2.9、屏幕截图
有的时候我们测试用例执行出错了,我们需要查看当时网页出现的情况,那么就需要使用屏幕截图来排查问题。
具体的,我们可以在每一个测试case执行完后进行一次屏幕截图,并将截图保存到一个路径下,文件名以当时时间进行组织(防止保存屏幕截图出现覆盖情况),那么就可以在AutoTestUtils类下加上屏幕截图的方法,方便其他类调用。
代码如下:
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.chrome.ChromeDriver;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;public class AutoTestUtils {private static ChromeDriver driver;//创建驱动public static ChromeDriver getDriver() {if(driver == null) {driver = new ChromeDriver();//创建隐式等待,设置最长等待时间为10秒driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));}return driver;}/*** 获取屏幕截图,将用例执行结果保留下来* @param str* @throws IOException*/public void getScreenShot(String str) throws IOException {List<String> list = getTime();String fileName = "./src/test/java/com/blogWebAutoTest/" + list.get(0) + "/" + str + "_" + list.get(1) + ".png";File srcFile = driver.getScreenshotAs(OutputType.FILE);//把生成的截图文件放入指定路径FileUtils.copyFile(srcFile, new File(fileName));}/*** 生成文件的保存时间* @return*/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;}}
在其他测试类中加上屏幕截图后,就可以观察到如下结果:

1.2.11、自动化测试的亮点
- 使用 junit5 中提供的注解,避免生成过多的对象,造成资源和时间上的浪费,提高了自动化执行的效率。
- 只创建一次驱动,避免每个用例重复创建驱动造成时间和资源的浪费。
- 使用参数化,保持用例的整洁,提高代码的可读性。
- 使用隐式等待,提高了自动化运行效率,提高了自动化的稳定性。
- 使用屏幕截图,方便问题的追溯以及解决。
1.2.10、自动化完整测试代码
以下是我的gitee码云:
自动化测试: automated-testing- - Gitee.com
1.3、性能测试
1.3.1、LoadRunner工具介绍

我们使用以上三个工具针对我们的项目进行性能测试。
a)Virtual User Generator(简称VUG):用来生成性能测试脚本。
b)Controller:创建测试场景,运行和监控场景。
c)Analysis:生成测试报告,分析性能测试结果。
1.3.1、 UI性能测试步骤
a)访问博客登录页;
b)执行登录;
c)进入首页。
1.3.2、编写性能测试脚本(VUG)
1、创建项目
由于我们测试的博客系统是一个Web项目,因此需要创建一个Web性能测试脚本,如下:

2、目录层次介绍

我们主要在Action里编写代码~
3、代码编写
主要的操作步骤为:1.打开网页,2.输入账号密码并登录;
在此期间,为了更好的让我们进行性能测试的数据收集,我们可以使用
- 事务:衡量性能的重要指标,通过观察每秒事务通过数来衡量性能;
- 集合点:让所有的虚拟用户执行到集合点时断在集合,满足条件后一起执行下一个步骤(保证每一个虚拟用户同时执行下一步);
- 检查点:可以用来检测当前页面的元素是否存在以及存在个数(检查点一般放在请求之前);
- 参数化:通过提供的数据源可以实现多个参数逐个执行;
如下代码:
Action()
{//开始事务1lr_start_transaction("index_trans");//1.访问博客系统网页web_url("web_url","URL=http://43.139.193.116:8080/blog_system/login.html","TargetFrame=","Resource=0","Referer=",LAST);//登录的集合点lr_rendezvous("login_rendezvous");//开始事务2lr_start_transaction("login_trans");//2.输入登录账号和密码web_submit_form("web_submit_form",ITEMDATA,"Name=username", "Value={username}", ENDITEM,"Name=password", "Value=123", ENDITEM,LAST);//结束事务2lr_end_transaction("login_trans", LR_AUTO);//结束事务1lr_end_transaction("index_trans", LR_AUTO);return 0;
}
执行结果和分析:

1.3.3、创建测试场景(Controller)
a)针对我们已经编写好的脚本打开controller工具,创建测试脚本,如下:


b)设置执行策略如下:



这个过程就像是舞台表演一样,如下:

c)场景运行结果

1.3.4、生成测试报告(Analysis)
在 controller 创建的场景中直接生成测试报告,如下:

测试报告如下:

测试报告图标如下:
1.虚拟用户运行图:

作用:通过显示的虚拟用户数量可以判断出哪个时间段服务器负载最大(上图00:40 ~ 01:40负载最大)。
2.点击数图(每秒点击率)
作用:通过点击率可以判断出某时间段内服务器的负载。
3.吞吐量图

问题一:为什么吞吐量图和点击数图相似,但是吞吐量图要滞后一点?
- 因为吞吐量表示的是响应返回的资源数量,肯定是现有请求再有返回。
问题二:如果请求变多但是吞吐量没变化,原因是什么?
- 服务器响应太慢,来不及反应;
- 压力没有到服务器;
- 服务器设计一定的阈值(到达阈值以后,虽然也收到了请求,但是服务器不会做任何处理),保证了服务器不会因为并发量过大而出现宕机的情况;
4.事务图

5.平均事务响应时间图

作用:可以观察到,虚拟用户在性能测试中,每秒在服务器上命中的次数,可以根据命中的次数评估虚拟用户生成的负载量。
小结
以上便是本次博客系统的测试报告~
相关文章:
博客系统——项目测试报告
目录 前言 博客系统——项目介绍 1、测试计划 1.1、功能测试 1.1.1、编写测试用例 1.1.2、实际执行步骤 1.2、使用Selenium进行Web自动化测试 1.2.1、引入依赖 1.2.2、提取共性,实现代码复用 1.2.3、创建测试套件类 1.2.4、博客登录页自动化测试 1.2.5、…...
Macbook M1 安装PDI(Kettle) 9.3
Macbook M1 安装PDI(Kettle) 9.3 当前 PDI(Kettle)最新版为9.3,依赖Java JDK 11。因为没有专门用于 M1的程序,需要下载并安装x86_64架构的JDK及依赖软件,并 “强制在Intel模式下运行shell” 的方式来实现 Kettle 的正…...
机器学习——模型评估
在学习得到的模型投放使用之前,通常需要对其进行性能评估。为此,需使用一个“测试集”(testing set)来测试模型对新样本的泛化能力,然后以测试集上的“测试误差( tootino error)作为泛化误差的近似。我们假设测试集是从样本真实分…...
react react-redux学习记录
react react-redux学习记录1.原理2.怎么用呢2.1 容器组件2.2UI组件2.3 App.jsx3.简化3.1简写mapDispatch3.2 Provider组件的使用3.3整合UI组件和容器组件1.原理 UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。 容器组件:负责和redux通信&…...
nodejs环境配置
啥是node.js 简单理解就是js运行环境 啥是npm 简单理解就是nodejs包管理工具,全称Node Package Manager 啥是cnpm npm的开源镜像,在国内使用cnpm替代npm可以起到加速的效果 https://npmmirror.com/ ①安装node.js https://nodejs.org/en/download/ 下载…...
数据治理之元数据管理Atlas
数据治理之元数据管理的利器——Atlas 一、数据治理与元数据管理 1.1 背景 为什么要做数据治理? 业务繁多,数据繁多,业务数据不断迭代。人员流动,文档不全,逻辑不清楚,对于数据很难直观理解,…...
15 Nacos客户端实例注册源码分析
Nacos客户端实例注册源码分析 实例客户端注册入口 流程图: 实际上我们在真实的生产环境中,我们要让某一个服务注册到Nacos中,我们首先要引入一个依赖: <dependency><groupId>com.alibaba.cloud</groupId>&l…...
C++将派生类赋值给基类(向上转型)
1.将派生类对象赋值给基类对象 #include <iostream> using namespace std;//基类 class A{ public:A(int a); public:void display(); public:int m_a; }; A::A(int a): m_a(a){ } void A::display(){cout<<"Class A: m_a"<<m_a<<endl; }//…...
使用Platform Designer创建Nios II 最小系统
Nios II简介 Nios II 软核处理器十多年前就有了,它和xilinx的MicroBlaze类似,性能相比硬核处理器要差得多,工程应用也不是很多,那还有必须学习一下吗?我个人认为了解一下Nios II开发流程,对intel FPGA开…...
CD销售管理系统
技术:Java、JSP等摘要:二十一世纪是一个集数字化,网络化,信息化的,以网络为核心的社会。中国的网民充分领略到“畅游天地间,网络无极限” 所带来的畅快。随着Internet的飞速发展,使得网络的应用…...
华为OD机试模拟题 用 C++ 实现 - 玩牌高手(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明玩牌高手题目输入输出描述示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为…...
Hive 的Stage如何划分?
Hive 的Stage如何划分,也是Hive SQL需要优化的一个点,这个问题,我也是在实际的工作中遇到的。所以我查询了网络的解答并记录下来,以便日后复习。以下是主要内容,enjoy~~~ 一个 Hive 任务会包含一个或多个 stage&#…...
《嵌入式应用开发》实验一、开发环境搭建与布局(上)
1. 搭建开发环境 去官网(https://developer.android.google.cn/studio)下载 Android Studio。 安装SDK(默认Android 7.0即可) 全局 gradle 镜像配置 在用户主目录下的 .gradle 文件夹下面新建文件 init.gradle,内容为…...
电子科技大学软件工程期末复习笔记(五):生产率和工作度量
目录 前言 重点一览 软件产品度量 测量软件生产率的两种方法 基于LOC测量 例题: 优点 缺点 基于功能点测量 例题: 本章小结 前言 本复习笔记基于王玉林老师的课堂PPT与复习大纲,供自己期末复习与学弟学妹参考用。 重点一览 这一部分内…...
400G光模块知识大全
400G光模块是目前高速传输领域中的一种先进产品,被广泛应用于高性能数据中心、通信网络、大规模计算、云计算等领域。本文将从400G光模块的定义、技术、产品型号、应用场景以及未来发展方向进行详细介绍。一、什么是400G光模块?400G光模块是指传输速率达…...
【Linux】零成本在家搭建自己的私人服务器解决方案
我这个人自小时候以来就特喜欢永久且免费的东西,也因此被骗过(花巨款买了永久超级会员最后就十几天)。 长大后骨子里也是喜欢永久且免费的东西,所以我不买服务器,用GitHubPage或者GiteePage搭建自己的静态私人博客&…...
Python 多线程、多进程和协程
一、多线程 threading 模块 threading 模块对象 对象描述Thread表示一个执行线程的对象Lock锁原语对象(与 thread 模块中的锁一样)RLock可重入锁对象,使单一线程可以(再次)获得已持有的锁(递归锁&#x…...
Xml 注解
文章目录XmlRootElement(name"MyRootElement")XmlAccessorType(XmlAccessType.FIELD)XmlElementXmlAttributeXmlValueXmlElementRefXmlRootElement(name“MyRootElement”) XmlRootElement(name"MyRootElement") public class AccessorType {public Strin…...
【CSS文字滚动】CSS实现文字横向循环无缝滚动,鼠标移入暂停移出继续(附实测源码)
CSS如何实现文字横向滚动滚动效果1、垃圾liMarquee(最好别用)2、css实现文字滚动,且鼠标移入移出暂停和继续HTML源码如下:CSS源码如下:JS源码如下:3、片尾彩蛋CSS实现文字横向循环无缝滚动,鼠标…...
不使用implements关键字实现实现类(类似于mapper)
首先,说明一下功能需求,平时定义一个接口,就要使用implements关键字来实现接口。那么,当不使用此关键字的时候,是否也能使相关接口也能够绑定实现类呢? 答案是肯定的。 此篇文章的主要功能有两个…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
