简朴博客系统测试报告

news2024/12/26 16:44:11

文章目录

  • 一. 项目简介
  • 二. 测试概要
  • 三. 测试环境
  • 四. 测试执行概况及功能测试
    • 1. 手工测试
      • 1.1 手动测试用例编写
      • 1.2 执行的部分测试用例
    • 2. 自动化测试Selenium
      • 2.1 编写测试用例
      • 2.2 自动化测试代码
    • 3. 测试结果
  • 五. 发现的问题

一. 项目简介

简朴博客系统是采用前后端分离的方式来实现的,是基于 SpringFrameWork 和 MyBatis 框架实现的一个简易的博客发布网站,同时将其部署到了云服务器上。

目前博客系统主要实现了户的注册登录,文章的编写、发布,以及对自己文章的查看、修改、删除操作,个人文章列表及文章数统计这些;还可以分页显示所有作者汇总的文章列表,显示文章阅读量等。

使用 IDEA 开发,项目用到的技术有,SpringBoot, SpringMVC, MyBatis, MySQL, Redis, Lombok,HTML,CSS,JavaScript,jQuery 等。

二. 测试概要

测试对象:基于 SSM 项目的博客系统。

测试目的:校验博客项目功能是否符合自己的预期。

测试点:主要针对常用的主流程功能进行测试,如:注册、登录、汇总博客列表页、博客编辑页、个人博客列表页、导航栏组件等涉及到的功能。

测试方法和工具:主要是黑盒测试,自动化工具使用 Selenium 和 Junit。

三. 测试环境

硬件:Lenovo Yoga 14S 2021(R7-5800H/16GB/512GB/集显)。

浏览器:Google Chrome 版本 119.0.6045.160(正式版本) (64 位)。

操作系统:Windows 11。

测试工具:Selenium3 和 Junit5。

四. 测试执行概况及功能测试

1. 手工测试

1.1 手动测试用例编写

♨️注册页

在这里插入图片描述

♨️登录页

在这里插入图片描述

♨️个人博客列表页
在这里插入图片描述

♨️博客详情页

在这里插入图片描述

♨️博客编辑页
在这里插入图片描述

1.2 执行的部分测试用例

  1. 🍂登录页:界面能否正常加载,输入正确 / 错误的账号、密码是否能得到预期的响应。
    1️⃣界面能否正常加载。img
    2️⃣账号正确,密码错误。
    预期结果:弹窗提示:“出错了: 登录失败, 请重新操作! 用户名或密码错误! ”。
    实际结果如下:
    img
    3️⃣账号正确,密码为空。
    预期结果:弹窗提示:“请输入密码! ”。
    实际结果如下:
    img
    4️⃣账号正确,密码正确。
    预期结果:页面跳转至个人博客列表页。
    实际结果如下:
    img
  2. 个人博客列表页:检测界面是否符合预期,点击“查看全文”按钮是否能跳转到对应的博客详情页,点击“修改”按钮是否能跳转到博客编辑页并获取到待修改的标题和内容,点击“删除”按钮是否能成功删除文章,点击“注销”是否能退出登录。
    1️⃣界面显示符合预期。
    img
    2️⃣点击“查看全文”按钮是否能跳转到对应的博客详情页。
    预期结果:进入到对应的博客详情页,且能够正确加载文章内容。
    实际结果如下:
    img
    3️⃣点击“修改”。
    预期结果:点击修改后跳转到文章编辑页。
    实际结果如下:
    img
    4️⃣点击“删除”。
    预期结果:点击删除后文章被删除。
    实际结果如下:
    img5️⃣点击“注销”是否能退出登录。
    预期结果:点击注销后退出跳转到登录页面。
    实际结果如下:
    img

2. 自动化测试Selenium

2.1 编写测试用例

在这里插入图片描述

2.2 自动化测试代码

🍂引入依赖:seleniumcommons-iojunitsuiteengine

<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.2</version>
        <scope>test</scope>
    </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.2</version>
    </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>
    </dependency>
</dependencies>

🍂初始化工具类InitAndEnd

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;


import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class InitAndEnd {
    static WebDriver webDriver;

    @BeforeAll
    static void SetUp() {
        // 创建 web 驱动
        webDriver = new ChromeDriver();
    }

    @AfterAll
    static void TearDown() {
        // 关闭 web 驱动
        webDriver.quit();
    }

    // 获取当前时间戳将截图按照时间保存
    public List<String> getTime() {
        // 文件夹以当天日期保存
        // 截图以当天日期-时间保存
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        String dirname = sim1.format(System.currentTimeMillis());
        String filename = sim2.format(System.currentTimeMillis());
        List<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }

    // 获取屏幕截图,把所有的用例执行的结果保存下来
    public void getScreenShot(String str) throws IOException {
        List<String> list = getTime();
        String filename = "D:\\bit\\software_testing\\software-testing\\test-blog\\src\\main\\java\\com\\blog\\test" + list.get(0) + "\\" + str + "_" + list.get(1) + ".png";
        File srcfile = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
        // 把屏幕截图生成的文件放到指定的路径
        FileUtils.copyFile(srcfile, new File(filename));
    }
}

🍂常用功能主流程测试

🍁LoginSuccess.csv

admin, admin, http://47.113.217.156:8080/myblog_list.html

🍁RegCases

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

public class RegCases extends InitAndEnd {
    @Order(1)
    @ParameterizedTest
    @CsvSource({"zhaoliu, 123, 123, http://47.113.217.156:8080/login.html"})
    void regSuccess(String username, String password, String againpassword, String login_url) throws InterruptedException, IOException {
        // 打开登录页
        webDriver.get(login_url);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 找到注册按钮并点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 输入注册的用户名和密码及确认密码
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        webDriver.findElement(By.cssSelector("#password2")).sendKeys(againpassword);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击注册按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        sleep(3000);
        // 点击确认弹窗
        webDriver.switchTo().alert().accept();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 用新注册的账号进行登录
        // 输入账号 zhaoliu
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 输入密码 123
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击登录按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 刚注册的账号登录后没有文章,验证是否有 “创作” 按钮
        String butt = webDriver.findElement(By.cssSelector("#artListDiv > h3 > a")).getText();
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertEquals("创作", butt);
    }
}

🍁BlogCases

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import static java.lang.Thread.sleep;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogCases extends InitAndEnd {
    /**
     * 登录页:输入正确的账号,错误的密码,登录失败
     */
    @Order(1)
    @ParameterizedTest
    @CsvSource({"admin, 123", "zhangsan, 666"})
    void LoginAbnormal(String username, String password) throws InterruptedException, IOException {
        // 打开登录页
        webDriver.get("http://47.113.217.156:8080/login.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 输入账号和密码
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击登录按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        sleep(300);
        //登录失败,出现弹窗
        //获取验证弹窗内容
        String text = webDriver.switchTo().alert().getText();
        String except = "出错了: 登录失败, 请重新操作! 用户名或密码错误!";
        webDriver.switchTo().alert().accept();
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertEquals(except, text);
    }

    /**
     * 登录页:输入正确的账号,密码,登录成功
     */
    @Order(2)
    @ParameterizedTest
    @CsvFileSource(resources = "LoginSuccess.csv")
    void LoginSuccess(String username, String password, String blog_list_url) throws IOException, InterruptedException {
        System.out.println(username + " " +  " " +password + " " +  blog_list_url);
        // 打开登录页
        webDriver.get("http://47.113.217.156:8080/login.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 输入账号 admin
        webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 输入密码 admin
        webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 点击登录按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        sleep(3000);
        // 登录成功,跳转到个人列表页
        // 获取到当前页面 url
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        String cur_url = webDriver.getCurrentUrl();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 如果 url == http://47.113.217.156:8080/myblog_list.html,测试通过,否则测试不通过
        Assertions.assertEquals(blog_list_url, cur_url);
    }

    /**
     * 个人博客列表页:admin 账户登录后博客数量不为 0
     */
    @Order(3)
    @Test
    void BlogList() throws IOException {
        // 打开个人博客列表页
        webDriver.get("http://47.113.217.156:8080/myblog_list.html");
        // 获取页面上所有博客标题对应的元素
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        int title_num = webDriver.findElements(By.cssSelector(".title")).size();
        // 如果元素数量不为 0,测试通过
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertNotEquals(0 ,title_num);
    }

    /**
     * 个人博客列表页:查看全文
     * 博客详情页:
     * url
     * 博客标题
     * 页面 title 是 “博客详情”
     */
    public static Stream<Arguments> Generator() {
        return Stream.of(Arguments.arguments("http://47.113.217.156:8080/blog_content.html",
                "博客详情", "URL到页面: 探索网页加载的神秘过程"));
    }

    @Order(4)
    @ParameterizedTest
    @MethodSource("Generator")
    void BlogDetail(String expected_url, String expected_title, String expected_blog_title) throws IOException {
        // 打开个人博客列表页
        webDriver.get("http://47.113.217.156:8080/myblog_list.html");
        // 找到第一篇博客对应的查看全文按钮
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(4)")).click();
        // 获取当前页面 url
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        String cur_url = webDriver.getCurrentUrl();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 获取当前页面 title
        String cur_title = webDriver.getTitle();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 获取博客标题
        String cur_blog_title = webDriver.findElement(By.cssSelector("#title")).getText();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertEquals(expected_title, cur_title);
        Assertions.assertEquals(expected_blog_title, cur_blog_title);
        Assertions.assertTrue(cur_url.contains(expected_url));
    }

    /**
     * 博客编辑页:发布文章
     */
    @Order(5)
    @Test
    void EditBlog() throws InterruptedException, IOException {
        // 打开个人博客列表页
        webDriver.get("http://47.113.217.156:8080/myblog_list.html");
        // 找到写博客按钮,点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 通过 Js 进行输入
        ((JavascriptExecutor) webDriver).executeScript("document.getElementById(\"title\").value=\"自动化测试\"");
        sleep(3000);
        // 点击发布文章按钮
        webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();
        sleep(3000);
        // 验证发布成功后的弹窗内容
        String cur_text = webDriver.switchTo().alert().getText();
        String expect_text = "文章添加成功! 是否继续添加文章? ";
        // 点击取消弹窗
        webDriver.switchTo().alert().dismiss();
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertEquals(expect_text, cur_text);
    }

    /**
     * 汇总列表页:验证博客成功发布
     * 校验第一篇博客标题
     * 校验第一篇博客时间
     */
    @Order(6)
    @Test
    void BlogInfoChecked() throws IOException {
        webDriver.get("http://47.113.217.156:8080/blog_list.html");
        // 获取第一篇博客标题
        String first_blog_title = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.title")).getText();
        // 获取第一篇博客发布时间
        String first_blog_time = webDriver.findElement(By.xpath("//*[@id=\"artListDiv\"]/div[1]/div[2]")).getText();
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        // 校验博客标题是不是自动化测试
        Assertions.assertEquals("自动化测试", first_blog_title);
        // 如果时间是 2023-11-18 年发布的,测试通过
        Assertions.assertTrue(first_blog_time.contains("2023-11-18"));
    }

    /**
     * 个人列表页:删除刚刚发布的博客
     */
    @Order(7)
    @Test
    void DeleteBlog() throws InterruptedException, IOException {
        // 打开个人博客列表页面
        webDriver.get("http://47.113.217.156:8080/myblog_list.html");
        // 点击删除按钮
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(6)")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        sleep(3000);
        webDriver.switchTo().alert().accept();
        // 删除后博客列表页第一篇博客标题不是 “自动化测试”
        String first_blog_title = webDriver.findElement(By.xpath("//*[@id=\"artListDiv\"]/div[1]/div[1]")).getText();
        // 校验当前博客标题不等于 “自动化测试”
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertNotEquals(first_blog_title, "自动化测试");
    }

    //注销
    @Order(8)
    @Test
    void Logout() throws IOException {
        // 打开个人博客列表页面
        //点击注销
        webDriver.get("http://47.113.217.156:8080/myblog_list.html");
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        webDriver.switchTo().alert().accept();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 校验 url 注销后进入登录页
        String cur_url = webDriver.getCurrentUrl();
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        getScreenShot(methodName);
        Assertions.assertEquals("http://47.113.217.156:8080/login.html", cur_url);
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    }
}

🍂RunSuite,通过 class 运行测试用例。

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({RegCases.class, BlogCases.class,})
public class RunSuite {
}

3. 测试结果

测试通过,整体的主流程业务操作是没有问题的。

img

测试截图如下:

img

img

img

img

img

img

img

img

img

img

img

五. 发现的问题

🎯手工测试过程中发现的问题

🍂问题描述:

博客汇总页在未登录的情况下,点击“我的”按钮,结果不符合预期。

预期结果:直接跳转到登录页。

实际结果:有时候会出现弹窗提示错误,关闭弹窗后也不能直接跳转到登录页,需要刷新页面才能成功跳转。

🍂原因分析:

问题的根本原因可能在于异步请求的特性和后端拦截器的重定向,异步请求是非阻塞的,即在请求发送的过程中,代码会继续往下执行而不会等待请求完成。

在拦截器中使用response.sendRedirect进行重定向时,实际上是在响应中设置了一个重定向的状态,但对于异步请求而言,这个重定向的状态可能无法被正确处理,导致浏览器不会直接跳转到登录页,因为异步请求的结果是在JavaScript中处理的,而不是在浏览器地址栏中执行的。

这就导致了在异步请求中执行重定向时,可能会产生不确定的行为,因为重定向的结果可能无法按照预期顺序执行。

🍂造成问题的代码定位:

img

img

🍂解决方案:

修改前端代码,通过 JS 在 success 回调中判断返回的 res 中的code,如果是未登录状态,则手动跳转到登录页,以此来规避异步请求中可能产生的问题,确保在未登录时能够及时跳转到登录页。

img

🎯自动化程序编写过程碰到的问题

一些自动化操作是不能在弹窗的情况下完成操作的(比如截图),如果在测试程序执行报unexpected alert open: {Alert text : ...}这种异常,那么就是你没有将弹窗关闭掉,可以使用 accept() 方法确认弹窗或者 dismiss() 取消弹窗后再执行相关操作。

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

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

相关文章

美国经典人工智能教材第3版出版!

美国经典人工智能教材&#xff0c;人工智能的百科全书《人工智能》&#xff08;第3版&#xff09;出版&#xff01;新增深度学习及人工智能编程等内容&#xff0c;理论阐释结合动手实践。 人工智能 第3版 关于作者 史蒂芬.卢奇&#xff08;Stephen Lucci&#xff09;拥有纽约…

FreeRtos 任务切换深入分析

一、背景知识&#xff1a; 1、任务切换包含三个基本流程&#xff1a;保护现场、更新TCB、恢复现场并跳转 2、freertos的任务切换是在xPortPendSVHandler 中断函数中完成的 3、中断函数在调用之前&#xff0c;硬件已经保存了r0,r1,r2,r3,r12,r14(LR),r15(pc)&#xff0c;恢复…

深入理解Linux网络笔记(七):异常TCP连接建立情况、如何查看是否有连接队列溢出发生

本文为《深入理解Linux网络》学习笔记&#xff0c;使用的Linux源码版本是3.10&#xff0c;网卡驱动默认采用的都是Intel的igb网卡驱动 Linux源码在线阅读&#xff1a;https://elixir.bootlin.com/linux/v3.10/source 5、深度理解TCP连接建立过程&#xff08;二&#xff09; 4&…

顺序表(数据结构与算法)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

【Spring】AOP进阶-JoinPoint和ProceedingJoinPoint详解

文章目录 1. 前言2. JoinPoint简介3. 获取被增强方法的相关信息4. ProceedingJoinPoint简介5. 获取环绕通知方法的相关信息6. 总结 1. 前言 在Spring AOP中&#xff0c;JoinPoint和ProceedingJoinPoint都是关键的接口&#xff0c;用于在切面中获取方法的相关信息以及控制方法的…

国科大数据挖掘期末复习——聚类分析

聚类分析 将物理或抽象对象的集合分组成为由类似的对象组成的多个类的过程被称为聚类。由聚类所生 成的簇是一组数据对象的集合&#xff0c;这些对象与同一个簇中的对象彼此相似&#xff0c;与其他簇中的对象相异。 聚类属于无监督学习&#xff08;unsupervised learning&…

整形数据和浮点型数据在内存中的存储差别

愿所有美好如期而遇 我们先来看代码&#xff0c;猜猜结果是什么呢&#xff1f; int main() {//以整型数据的方式存储int n 10;float* m (float*)&n;//以整型数据的方式读取printf("%d\n", n);//以浮点型数据的方式2读取printf("%f\n", *m);printf(&…

揭秘“ChatGPT之父”突遭罢免内幕:从开发者大会起,几件事已有征兆

腾讯新闻《潜望》 纪振宇 发自硅谷 美国时间11月17日午间&#xff0c;OpenAI首席执行官&#xff0c;被称为“ChatGPT之父”的山姆奥特曼突遭董事会罢免。 OpenAI在当天发布的官方声明称&#xff0c;董事会启动了一项特别的调查&#xff0c;结论是奥特曼在与董事会沟通过程中没…

基于JAYA算法优化概率神经网络PNN的分类预测 - 附代码

基于JAYA算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于JAYA算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于JAYA优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

深度学习乳腺癌分类 计算机竞赛

文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度&#xff0c;召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…

嵌入式中一篇搞定Cmake使用教程

今天分享一篇关于 cmake 的相关文章&#xff0c;通过这个工具可以生成本地的Makefile。让我们不用去编写复杂的Makefile。 引言 CMake是开源、跨平台的构建工具&#xff0c;可以让我们通过编写简单的配置文件去生成本地的Makefile&#xff0c;这个配置文件是独立于运行平台和…

数学才是顶级码农的核心修养,码农怎样搞好数学?来看看这些网友强推的数学神作!文末评论区进行评论参与送书哟

文章目录 导读 一&#xff1a;基础篇 1&#xff1a;优美的数学思维&#xff1a;问题求解与证明 2&#xff1a;数学分析 3&#xff1a;线性代数 4&#xff1a;线性代数及其应用 5&#xff1a;代数 二&#xff1a;进阶篇 1&#xff1a;初等数论及其应用 2&#xff1a;数…

【Linux网络】从原理到实操,感受PXE无人值守自动化高效批量网络安装系统

一、PXE网络批量装机的介绍 1、常见的三种系统安装方式 2、回顾系统安装的过程&#xff0c;了解系统安装的必要条件 3、什么是pxe 4、搭建pxe的原理 5、Linux的光盘镜像中的isolinux中的相关文件学习 二、关于实现PXE无人值守装机的四大文件与五个软件的对应关系详解 5个…

基于Python实现大型家用电器和电子产品在线商店购买数据分析【500010098】

导入模块 import pandas as pd import numpy as np import matplotlib.pyplot as plt获取数据 df pd.read_csv( r"./data/kz.csv",sep,)数据描述 该数据包含2020年4月至2020年11月从大型家用电器和电子产品在线商店购买的数据。 数据说明 event_time&#xff1a…

嵌入式中一文搞懂ARM处理器架构

1、嵌入式处理器基础 典型的微处理器由控制单元、程序计数器&#xff08;PC&#xff09;、指令寄存器&#xff08;IR&#xff09;、数据通道、存储器等组成 。 指令执行过程一般分为&#xff1a; 取指&#xff1a; 从存储器中获得下一条执行的指令读入指令寄存器&#xff1b;…

Redis篇---第六篇

系列文章目录 文章目录 系列文章目录前言一、Redis 为什么设计成单线程的?二、什么是 bigkey?会存在什么影响?三、熟悉哪些 Redis 集群模式?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,…

从0开始学习JavaScript--JavaScript 流程控制

JavaScript中的流程控制结构是编写结构化、可读性强的代码的关键。本文将深入研究JavaScript中的流程控制&#xff0c;包括条件语句、循环结构、跳转语句等&#xff0c;并通过丰富的示例代码来更全面地了解和运用这些概念。 条件语句 条件语句用于基于不同的条件执行不同的代…

基于PLC的污水厌氧处理控制系统(论文+源码)

1. 系统设计 污水厌氧由进水系统通过粗格栅和清污机进行初步排除大块杂质物体以及漂浮物等&#xff0c;到达除砂池中。在除砂池系统中细格栅进一步净化污水厌氧中的细小颗粒物体&#xff0c;将污水厌氧中的细小沙粒滤除后进入氧化沟反应池。在该氧化沟系统中进行生化处理&…

抖音直播间涨粉助手,其开发流程与需要的技术和代码分享

先来看实操成果&#xff0c;↑↑需要的同学可看我名字↖↖↖↖↖&#xff0c;或评论888无偿分享 一、直播间涨人气的15种方法 直播间的人气就像水池中的水&#xff0c;想要有源源不断的流量&#xff0c;就要想办法把水龙头的水流开到最大&#xff0c;也就是要增加直播间曝光率&…

使用maven命令打包依赖

1、maven仓库地址 阿里云地址&#xff1a;https://developer.aliyun.com/mvn/search 中央仓库地址&#xff1a;https://mvnrepository.com/ 2、下载方式 在地址栏中输入要搜索的依赖 选择需要的版本 &#xff08;1&#xff09;直接复制 &#xff08;2&#xff09;pom下载 …