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

news2024/11/17 0:07:33

目录

前言

博客系统——项目介绍

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
     */
    @BeforeAll
    private 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
     */
    @BeforeAll
    private static void openWeb() {
        driver.get("http://43.139.193.116:8080/blog_system/blog_list.html");
    }

    /**
     * 测试博客列表页正常显示
     */
    @Test
    public 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
     */
    @BeforeAll
    public 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
     */
    @BeforeAll
    public static void openWeb() {
        driver.get("http://43.139.193.116:8080/blog_system/blog_detail.html?blogId=1");
    }

    /**
     * 检测博客详情页信息
     */
    @Test
    public 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();

    @Test
    public 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、自动化测试的亮点

  1. 使用 junit5 中提供的注解,避免生成过多的对象,造成资源和时间上的浪费,提高了自动化执行的效率。
  2. 只创建一次驱动,避免每个用例重复创建驱动造成时间和资源的浪费。
  3. 使用参数化,保持用例的整洁,提高代码的可读性。
  4. 使用隐式等待,提高了自动化运行效率,提高了自动化的稳定性。
  5. 使用屏幕截图,方便问题的追溯以及解决。

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()
{
	//开始事务1
	lr_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");

	//开始事务2
	lr_start_transaction("login_trans");

	//2.输入登录账号和密码
	web_submit_form("web_submit_form",
		ITEMDATA,
		"Name=username", "Value={username}", ENDITEM,
		"Name=password", "Value=123", ENDITEM,
		LAST);

	//结束事务2
	lr_end_transaction("login_trans", LR_AUTO);
	
	//结束事务1
	lr_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.平均事务响应时间图

作用:可以观察到,虚拟用户在性能测试中,每秒在服务器上命中的次数,可以根据命中的次数评估虚拟用户生成的负载量。

小结


以上便是本次博客系统的测试报告~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/376003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL注入报错注入之floor()报错注入原理分析

简介 对于SQL注入的报错注入通常有三个函数需要我们掌握&#xff1a; extractValue(xml_frag, xpath_expr)updateXML(xml_target, xpath_expr,new_xml)floor() 对于extractValue和updateXML函数来说比较好理解&#xff0c;就不做解释了&#xff0c;这里只对floor函数的报错注…

LabVIEW网络服务安全2

LabVIEW网络服务安全2在客户端应用程序中创建签名对请求进行签名要求您具有能够从客户端的编程语言调用的MD5摘要算法以及SHA256加密摘要算法的实现。这两种算法通常都可用于大多数平台。还需要&#xff1a;1. 要使用的HTTP方法的字符串&#xff08;“GET”、“POST”、“PUT”…

收发器上的10G网络变压器有什么特殊要求?

Hqst盈盛电子导读&#xff1a;那么&#xff0c;为了保证我们购买到正常的真正的具备POE功能的10G网络变压器&#xff0c;我们又要如何做呢以及如何判断呢&#xff1f;随着高速以太网网络传速的快速发展&#xff0c;10G以太网&#xff0c;10G网络变压器滤波器在各个领域也得到了…

基于SpringCloud的可靠消息最终一致性05:保存并发送事务消息

在有了分布式事务的解决方案、项目的需求、骨架代码和基础代码,做好了所有的准备工作之后,接下来就可以继续深入了解「核心业务」了。 在前面了解分布式事务时,可靠消息最终一致性方案的流程图是这样的: 图三十一:可靠消息最终一致性 整个的流程是: 1、业务处理服务在事务…

GLSL shader学习系列1-Hello World

这是GLSL shader系列第一篇文章&#xff0c;本文学习目标&#xff1a; 安装编辑工具编写hello world程序 安装插件 我使用VSCode编写shader代码&#xff0c;在VSCode上有两个好用的插件需要先装一下&#xff1a; Shader languages support for VS Code glsl-canvas&#xf…

优维科技实力入选《2023深圳金融业信息技术融合创新案例汇编》

日前&#xff0c;由深圳市金融科技协会编制的《2023深圳金融业信息技术融合创新案例汇编》于“2022中国&#xff08;深圳&#xff09;金融科技全球峰会”正式对外发布&#xff0c;共汇编近90个优秀金融技术应用实践案例&#xff0c;优维科技凭借在“某银行自动化运维XC改造项目…

STM32——毕设智能感应窗户

智能感应窗户 一、功能设计 以STM32F103芯片最小系统作为主控&#xff0c;实现自动监测、阈值设定功能和手动控制功能。 1、自动监测模式下&#xff1a; ① 采用温湿度传感器&#xff0c;实现采集当前环境的温度、湿度数值。 ② 采用光敏传感器&#xff0c;实现判断当前的环境…

【数据库/MySQL】MySQL三大日志提要

MySQL三大日志 mysql常用日志 错误日志查询日志慢查询日志事务日志【redo log&#xff08;重做日志&#xff09;、undo log&#xff08;回滚日志&#xff09;】二进制日志【bin log】 MySQL日志中比较重要的包括redo log&#xff08;重做日志&#xff09;、binlog&#xff0…

Docker 网络详解

前置网络知识 OSI七层网络模型 从下到上依次为&#xff1a;物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 交换机&#xff1a;处在第二次&#xff0c;也就是数据链路层。作用&#xff1a;通过一个或者多个设备将不同子网连接在一起&#xff0c;相互通信&am…

Ant Design Vue 如何添加时间选择框

第一步引入 组件 import JDate from /components/jeecg/JDate使用 重点代码 <j-date<a-col :span"24/2"><a-form-item :labelCol"labelCol" :wrapperCol"wrapperCol" label"验收日期"><j-date placeholder"…

Lesson9---回归问题

9.1 机器学习基础 课程回顾 Python语言基础Numpy/Matplotlib/Pandas/Pillow应用TensorFlow2.0 低阶API 即将学习 机器学习、人工神经网络、深度学习、卷积神经网络典型模型的TensorFlow2.0实现 9.1.1 机器学习 机器学习&#xff08;Machine Learning&#xff09;&#xf…

2023年湖北七大员证书查询网站是哪里?

一、湖北七大员是哪七大员&#xff1f; 湖北七大员分别是&#xff1a;施工员、质量员、资料员、材料员、标准员、劳务员和机械员。其中施工员和质量员分为&#xff1a;市政、土建、装饰装修和设备安装四个子专业&#xff0c;其他不分。 二、湖北七大员证书查询网站是哪里&#…

Node下载阿里OSS存储文件【不知目录结构】

前言&#xff1a;前端传模型ID&#xff0c;后台根据ID去阿里OSS存储下载对应文件&#xff08;不知文件内部层级结构&#xff0c;且OSS只能单个文件下载&#xff09;&#xff0c;打包成zip字节流形式返回给前端下载。 需求分析&#xff1a; 生成OSS文件关系树Node做文件下载存…

ClickHouse 相关面试题

文章目录什么是 ClickHouse&#xff0c;它的特点是什么&#xff1f;ClickHouse的数据存储方式是什么&#xff0c;它与传统的行式存储有什么区别&#xff1f;ClickHouse 引擎ClickHouse的数据模型是什么&#xff0c;它与传统的关系型数据库的数据模型有什么区别&#xff1f;Clic…

【TVM 学习资料】TensorIR 快速入门

本篇文章译自英文文档 Blitz Course to TensorIR 作者是 Siyuan Feng。更多 TVM 中文文档可访问→TVM 中文站 TensorIR 是深度学习领域的特定语言&#xff0c;主要有两个作用&#xff1a; 在各种硬件后端转换和优化程序。自动 tensorized 程序优化的抽象。 import tvm from…

kafka(一) 的架构,各概念

Kafka架构 Kafak 总体架构图中包含多个概念&#xff1a; &#xff08;1&#xff09;ZooKeeper&#xff1a;Zookeeper负责保存broker集群元数据&#xff0c;并对控制器进行选举等操作。 &#xff08;2&#xff09;Producer&#xff1a; 生产者负责创建消息&#xff0c;将消息发…

Kafka 概述

文章目录Kafka定义消息队列消息队列应用场景缓冲/消峰 场景解耦 场景异步通信 场景消息队列两种模式点对点模式发布/订阅模式 ***kafka基础架构Kafka定义 消息队列 目前企业中比较常见的消息队列产品主要有 Kafka、ActiveMQ 、RabbitMQ 、RocketMQ 等。在大数据场景主要采用 Ka…

I.MX6ULL内核开发11:使用设备树实现RGB灯驱动

目录 一、实验说明 二、硬件原理图分析 2.1 打开原理图&#xff0c;找到rgb部分 2.2 对RGB的R灯进行寄存器设置 2.2.1 时钟配置 2.2.2 引脚复用GPIO 2.2.3 引脚属性设置 2.2.4 输出电平设置 三、实验代码 3.1 编程思路 3.2 代码分析 3.2.1 添加RGB设备节点 3.2.2 编…

openlayers加载离线地图并实现深色地图

问题背景 我们自己一直使用的openlayergeoserver自己发布的地图&#xff0c;使用的是矢量地图。但是由于政府地图大都使用为天地图&#xff0c;所以需要将geoserver的矢量地图更改为天地图&#xff0c;并且依旧是搭配openlayers来使用。 解决步骤 一&#xff1a;加载离线地图&a…

ubuntu20.04安装nginx一系列问题

当初做一个项目的时候给linux装nginx遇到了很多问题&#xff0c;当初边搞边记录&#xff0c;这两天翻看项目笔记的时候找出来了&#xff0c;就把这一部分分享出来给大家看看 ubuntu20.04 LTS 安装yum无法定位软件包 备份原来的软件源 sudo cp /etc/apt/sources.list /etc/ap…