多用户网页在线聊天室(测试报告)

news/2025/3/18 11:19:42

文章目录

  • 多用户网页在线聊天室
    • 一,项目概括
      • 1.1 项目名称
      • 1.2 测试时间
      • 1.3 项目背景
      • 1.3 编写目的
    • 二,测试计划
      • 2.1 测试环境与配置
      • 2.2 测试用例
      • 2.3实际执行用例
        • 2.3.1登录
        • 2.3.2聊天消息列表展示
        • 2.3.3聊天消息详情页展示
        • 2.3.4联系人页展示
        • 2.3.5信息的编辑与发送
        • 2.3.6搜索框
    • 三、自动化测试工具
      • 3.1 注入依赖
      • 3.2 注册自动化测试
      • 3.3 未登录情况测试
      • 3.4 登录自动化测试
      • 3.5 聊天室页面自动化测试
      • 3.6 自动化测试结果总结
      • 3.6 自动化测试结果总结

多用户网页在线聊天室

一,项目概括

1.1 项目名称

多用户网页在线聊天室

1.2 测试时间

2024.6——2024.6

1.3 项目背景

随着现代互联网的快速发展,实时通信系统已成为人们日常交流的重要工具。为了让这个聊天室既好用又稳定,项目里加了一套“自动检查”系统(自动化测试)。比如登录、加好友、发消息这些核心功能,不用手动一遍遍测,而是用写好的程序自动模拟操作,快速发现问题。这样一来,无论用哪种浏览器或者网络环境,聊天功能都能稳稳运行,用户体验更流畅。

聊天室采用了Spring MVC作为后端框架,通过WebSocket实现消息的实时传输,前端使用原生HTML和CSS构建用户界面。项目的自动化测试部分通过Selenium编写,结合Python语言进行测试脚本开发,覆盖了用户登录、好友管理、消息传输等核心功能模块,确保用户能够在各类浏览器和网络条件下获得一致、流畅的聊天体验。

1.3 编写目的

对编写的网页聊天室项目进行软件测试活动,揭示潜在问题,总结测试过程种地成功经验与不足,以便于更好的进行测试工作


二,测试计划

2.1 测试环境与配置

平台:Windows 10
浏览器:Chrome
自动化测试工具:Selenium + Junit5

2.2 测试用例

2.3实际执行用例

2.3.1登录

用户名以及密码已经在后端写入了数据库是已经存在的,登录成功后就会跳转到聊天页面

输入正确的账号和密码(以用户"zhangsan"为例):

预期结果:出现登录成功的弹窗,点击后,跳转到博客列表页。

实际结果如下:

输入错误的账号或密码

预期结果:提示用户登录失败。

实际结果如下:在这里插入图片描述

2.3.2聊天消息列表展示

可以在列表页(主页)查看有限数量的聊天,其包括联系人名称、及最近一条消息内容。并且点击对应联系人之后会跳转到相应的聊天详情页

2.3.3聊天消息详情页展示

可以在详情页。查看具体聊天内容,其包括联系人名称、及聊天内容。

2.3.4联系人页展示

可以在联系人页展示查看联系人,其包括联系人名称。并且点击相应联系人后会跳转到相应聊天详情页。

image-20250312224144005

2.3.5信息的编辑与发送

可以在信息的编辑与发送页进行信息的操作,其包括编辑内容与发送内容。

image-20250312224349149

2.3.6搜索框

可以搜索内容输入内容点击“放大镜”按钮

image-20250312224443531

三、自动化测试工具

3.1 注入依赖

在maven—poom.xml中,引入依赖

 <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.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.9.1</version>
        </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.1</version>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.9.1</version>
            <scope>test</scope>
        </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>
            <scope>test</scope>
        </dependency>
    </dependencies>   
         
  • 单例驱动

    • 自动化测试程序过程中,会频繁的使用驱动,如果频繁的创建和销毁,开销还是比较大的,因此我们可以使用懒汉模式加载驱动
    • 这样可以保证驱动不会频繁创建,能减轻程序刚开始启动时的系统开销(只有用到驱动是才会加载它)
    • 如果其他类需要使用到驱动的话,直接继承该类即可
  • 获取屏幕截图

    • 当我们测试用例出错时,我们需要查看当时网页出现的情况,那么就需要使用屏幕截图来排查问题
    • 使用 getScreenshotAs 方法来保存屏幕截图,在每个测试用例执行完后进行一次屏幕截图
    • 屏幕截图统一保存到一个路径下,文件名以当时时间去组织(防止保存屏幕截图出现覆盖情况)
    • 综上,我们便在 AutoTestUtils类下加上保存截图的方法,方便其他类调用

package common;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
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.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class AutoTestUtils {
    private static ChromeDriver driver;

    public static ChromeDriver getDriver() {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");

        if (driver == null) {
            driver = new ChromeDriver(options);
            //创建隐式等待,设置最长等待时间10s
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        }
        return driver;
    }

    /**
     * 获取屏幕截图,将用例执行结果保存下来
     */
    public void getScreenShot(String str) throws IOException {
        List<String> list = getTime();
        String fileName = "./src/main/java/chatRoomAutoTest/" + list.get(0) + list.get(0) + "/" + str + "_" + list.get(1) + ".png";
        File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
		//把生成的截图放入指定路径
        FileUtils.copyFile(srcFile,new File(fileName));
    }

    //获取当前时间(记录每个屏幕截图是什么时候拍摄的)
    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;
    }

}

3.2 注册自动化测试

此处我们创建一个 RegTest 类继承 AutoTestUtils 类得到驱动

先测试注册页面是否正常打开,输入.最后进行相应弹窗处理,进行屏幕截图


package UserTest;

import common.AutoTestUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.io.IOException;

import static java.lang.Thread.sleep;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class RegTest extends AutoTestUtils {
    //获取到驱动
    private static WebDriver driver = AutoTestUtils.getDriver();

    /**
     * 打开网页
     * 注册网页一般是从登录页面进入
     */
    @BeforeAll
    public static void openWeb() {
        //打开登录页面
        driver.get("http://182.92.153.14:9091/login.html");
        //再点击登录页面的注册链接按钮
        driver.findElement(By.cssSelector("body > div.login-container > div > div:nth-child(4) > a")).click();
        driver.manage().window().maximize();
    }

    /**
     * 验证网页正常打开
     */
    @Test
    @Order(1)
    public void elementsAppear() throws IOException {
        //用户名输入框
        driver.findElement(By.cssSelector("#username"));
        //密码输入框
        driver.findElement(By.cssSelector("#password"));
        //注册按钮
        driver.findElement(By.cssSelector("#submit"));
        //登录账号链接
        driver.findElement(By.cssSelector("body > div.register-container > div > div:nth-child(4) > a"));
        getScreenShot(getClass().getName());
    }

    /**
     * 注册失败测试用例
     * 参数: 尝试注册已注册用户
     */

    @ParameterizedTest
    @CsvSource({"zhangsan,123"})
    @Order(2)
    public void regFunTest(String username, String passowrd) throws InterruptedException, IOException {
        //输入账号
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        //输入密码
        driver.findElement(By.cssSelector("#password")).sendKeys(passowrd);
        //点击注册
        driver.findElement(By.cssSelector("#submit")).click();
        //等待弹窗
        sleep(3000);
        //期望结果
        String expect = "注册失败!";
        String actual = driver.switchTo().alert().getText();
        Alert alert = driver.switchTo().alert();
        if (alert != null) {
            alert.accept();
        } else {
            actual = "当前用例执行失败";
        }
        //断言
        Assertions.assertEquals(expect, actual);
        //屏幕截图
        getScreenShot(getClass().getName());
    }


    /**
     * 注册成功测试用例
     */
    @ParameterizedTest
    @CsvSource({"lisi,123,注册成功!"})
    @Order(3)
    public void regTest(String username, String password,String expect) throws InterruptedException, IOException {
        //拿到元素
        WebElement inputUserName = driver.findElement(By.cssSelector("#username"));
        WebElement inputPassword = driver.findElement(By.cssSelector("#password"));
        WebElement button = driver.findElement(By.cssSelector("#submit"));
        //清除输入框
        inputUserName.clear();
        inputPassword.clear();

        //输入用例
        inputUserName.sendKeys(username);
        inputPassword.sendKeys(password);
        //提交
        button.click();
        //强制等待弹窗
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        //期望结果

        String actual = "注册成功!";
        if(alert != null) {
            alert.accept();
        }else {
            actual = "当前用例执行失败";
        }
        Assertions.assertEquals(expect,actual);
		//屏幕截图
        getScreenShot(getClass().getName());
    }
}

3.3 未登录情况测试

此处我们创建一个 InterceptTest 类继承 AutoTestUtils 类得到驱动

测试未登录情况下,打开会话页面,进行相应弹窗处理,进行屏幕截图


package UserTest;

import common.AutoTestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.chrome.ChromeDriver;

import static java.lang.Thread.sleep;


public class InterceptTest extends AutoTestUtils {
    //获取驱动
    private static ChromeDriver driver = AutoTestUtils.getDriver();

    @Test
    public void Intercept() throws InterruptedException {
        //在未登录的情况下,跳转会话页
        driver.get("http://182.92.153.14:9091/client.html");
        sleep(2000);
        //期望结果
        String expect = "当前用户未登录!";
        String actual = "当前用户未登录!";
        Alert alert = driver.switchTo().alert();
        if (alert != null) {
            alert.accept();
        } else {
            actual = "当前用例执行失败";
        }
        //屏幕截图
        getScreenShot(getClass().getName());
        //断言
        Assertions.assertEquals(expect,actual);
    }
}

3.4 登录自动化测试

此处我们创建一个 LoginTest 类继承 AutoTestUtils 类得到驱动

先测试登录页面是否正常打开,再找几个典型的用例对异常,正常登录风别进行测试

最后进行相应弹窗处理,进行屏幕截图

package UserTest;

import common.AutoTestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.io.IOException;

import static java.lang.Thread.sleep;

public class LoginTest extends AutoTestUtils {

    //获取到驱动
    private static WebDriver driver = AutoTestUtils.getDriver();

    /**
     * 打开页面
     * 注册页面一般是从登录页面进入
     */
    @BeforeAll
    public static void openWeb() {
        //先打开登录页面
        driver.get("http://182.92.153.14:9091/login.html");
        driver.manage().window().maximize();
    }

    /**
     * 检测登录页面是否能正常打开
     */
    @Test
    @Order(1)
    public void elementsAppear() throws IOException {
        //用户名输入框
        driver.findElement(By.cssSelector("#username"));
        //密码输入框
        driver.findElement(By.cssSelector("#password"));
        //注册账号链接
        driver.findElement(By.cssSelector("body > div.login-container > div > div:nth-child(4) > a"));
        //登录按钮
        driver.findElement(By.cssSelector("#submit"));
        //屏幕截图
        getScreenShot(getClass().getName());
    }

    /**
     * 异常测试登录功能
     * 参数一:尝试登录未注册用户
     * 参数二:密码输入错误,登录账号
     */
    @ParameterizedTest
    @CsvSource({"zhang,123","zhangsan,123456"})
    @Order(2)
    public void loginAbnormalTest(String username,String password) throws InterruptedException, IOException {
        //拿到元素
        WebElement inputUserName = driver.findElement(By.cssSelector("#username"));
        WebElement inputPassword = driver.findElement(By.cssSelector("#password"));
        WebElement button = driver.findElement(By.cssSelector("#submit"));
        //清除用户名,密码
        inputUserName.clear();
        inputPassword.clear();
        //输入账号,密码
        inputUserName.sendKeys(username);
        inputPassword.sendKeys(password);
        //点击登录
        button.click();
        //等待弹窗
        sleep(3000);
        //期望结果
        String expect = "登录失败!";
        String actual = "登录失败!";
        Alert alert = driver.switchTo().alert();
        if(alert != null) {
            alert.accept();
        } else {
            actual = "当前用例执行失败!";
        }
        Assertions.assertEquals(expect,actual);
        //屏幕截图
        getScreenShot(getClass().getName());
    }

    /**
     * 正常登录测试
     */
    @ParameterizedTest
    @CsvSource({"'zhangsan','123','登陆成功'"})
    @Order(3)
    public void loginNormalTest(String userName,String password,String expect) throws InterruptedException, IOException {
        //发现元素
        WebElement inputUserName = driver.findElement(By.cssSelector("#username"));
        WebElement inputPassword = driver.findElement(By.cssSelector("#password"));
        WebElement button = driver.findElement(By.cssSelector("#submit"));
        //清除用户名密码
        inputUserName.clear();
        inputPassword.clear();
        //输入用户名,密码
        inputUserName.sendKeys(userName);
        inputPassword.sendKeys(password);
        //点击登录
        button.click();
        //等待弹窗
        sleep(3000);
        //期望结果
        String actual = driver.switchTo().alert().getText();
        //断言
        Assertions.assertEquals(expect,actual);
        //处理弹窗
        driver.switchTo().alert().accept();
        //屏幕截图
        getScreenShot(getClass().getName());

    }
}

3.5 聊天室页面自动化测试

此处我们创建一个 ClientTest 类继承 AutoTestUtils 类得到驱动

先对页面功能以及聊天功能进行自动化测试,进行相应的弹窗处理,最后进行屏幕截截图

package UserTest;

import 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.WebDriver;

import java.io.IOException;

import static java.lang.Thread.sleep;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ClientTest extends AutoTestUtils {
    //获得驱动
    public static WebDriver driver = AutoTestUtils.getDriver();

    /**
     * 打开会话页面
     */
    @BeforeAll
    public static void openWeb() {
        //先打开会话页面
        driver.get("http://182.92.153.14:9091/client.html");
        driver.manage().window().maximize();
    }

    /**
     * 测试会话页面正常打开
     */
    @Test
    @Order(1)
    public void elementsAppear() throws IOException {
        //主页个人账号名
        driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.user"));
        //搜索输入框
        driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > input[type=text]"));
        //搜索按钮
        driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button"));
        //会话标签图
        driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session"));
        //好友标签图
        driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-friend"));
        //聊天输入框
        driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea"));
        //发送按钮
        driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button"));
        //屏幕截图
        getScreenShot(getClass().getName());
    }


    /**
     * 点击具体会话
     * 检验:消息页面展示当前会话用户名字
     */
    @Order(2)
    @Test
     void SessionList() throws InterruptedException {
        //点击具体会话
        driver.findElement(By.xpath("//*[@id=\"session-list\"]/li[1]/h3")).click();
        sleep(3000);
        //获取到消息页面展示当前用户名字
        String actual = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title")).getText();
        Assertions.assertEquals("wangwu",actual);
    }

    /**
     * 点击好友列表
     */
    @Order(3)
    @Test
    void FriendList() throws InterruptedException {
        //点击好友按钮,打开好友列表
        driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-friend")).click();
        sleep(3000);
        //点击好友
        driver.findElement(By.xpath("//*[@id=\"friend-list\"]/li[1]/h4")).click();
        sleep(3000);
        //检验选中的好友在会话列表是否被置顶
        String text = driver.findElement(By.cssSelector("#session-list > li.selected > h3")).getText();
        Assertions.assertEquals("lisi",text);
    }


    /**
     * 测试聊天发送功能
     * 参数:zhangsan 给  wangwu 发送数据
     */
    @ParameterizedTest
    @CsvSource({"正在自动化测试中...","测试发送成功","测试结束!"})
    @Order(4)
    public void TalkSendTest(String msg) throws InterruptedException, IOException {
        //点击好友会话开始聊天
        driver.findElement(By.xpath("//*[@id=\"session-list\"]/li[2]/h3")).click();
        sleep(3000);
        //选择输入框开始聊天
        driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys(msg);
        //点击发送
        driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();
        sleep(3000);
        //判断消息是否发送成功

        //屏幕截图
        getScreenShot(getClass().getName());
    }

    /**
     * 测试聊天接收功能
     * 参数:登录 wangwu 查看与 zhangsan 历史会话,检验是否发送成功
     */
    @Test
    @Order(5)
    public void TalkAcceptTest() throws InterruptedException {
        //打开页面
        driver.get("http://182.92.153.14:9091/login.html");
        sleep(3000);
        //输入账号
        driver.findElement(By.cssSelector("#username")).sendKeys("wangwu");
        //输入密码
        driver.findElement(By.cssSelector("#password")).sendKeys("123");
        //点击登录
        driver.findElement(By.cssSelector("#submit")).click();
        sleep(3000);
        //确认弹窗
        driver.switchTo().alert().accept();
        sleep(3000);
        //点击 zhangsan 会话
        driver.findElement(By.cssSelector("#session-list > li > h3")).click();
        //获取好友名
        String name = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title")).getText();
        //获取最后一条消息
        String text = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.message-show > div:nth-child(3) > div > p")).getText();
        //判断好友是否一致
        Assertions.assertEquals("zhangsan",name);
        //判断消息是否一致
        Assertions.assertEquals("测试结束!",text);

    }
}

3.6 自动化测试结果总结

    driver.switchTo().alert().accept();
        sleep(3000);
        //点击 zhangsan 会话
        driver.findElement(By.cssSelector("#session-list > li > h3")).click();
        //获取好友名
        String name = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.title")).getText();
        //获取最后一条消息
        String text = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.message-show > div:nth-child(3) > div > p")).getText();
        //判断好友是否一致
        Assertions.assertEquals("zhangsan",name);
        //判断消息是否一致
        Assertions.assertEquals("测试结束!",text);

    }
}

3.6 自动化测试结果总结

image-20250312225452566


http://www.niftyadmin.cn/n/5890040.html

相关文章

UI自动化:seldom框架和Selenium

以下是关于 seldom框架 和 Selenium 的对比解析及结合使用的详细说明&#xff0c;帮助理解二者的定位、功能差异和应用场景&#xff1a; 1. 核心定位 工具定位Selenium浏览器自动化工具库&#xff0c;提供直接操控浏览器的底层API&#xff08;如点击、输入、获取元素等&#x…

单片机字符串换行符使用说明

在单片机中&#xff0c;字符串的换行通常使用 \r\n 来表示。\r 是回车&#xff08;Carriage Return&#xff09;&#xff0c;\n 是换行&#xff08;Line Feed&#xff09;。这两个字符的组合 \r\n 是 Windows 系统中的标准换行符。 例如&#xff0c;如果你有一个字符串 QIOTEV…

侯捷C++课程学习笔记:构造函数那些事儿(四)

C 构造函数全面解析 上图节选自爱吃喵的鲤鱼 一、构造函数基础特性 1. 核心功能定位 ​对象初始化中枢&#xff1a;负责在对象创建时完成成员变量的初始化工作​生命周期唯一性&#xff1a;每个对象在其生命周期内仅被调用一次&#xff0c;类似出生证明的签发过程 2. 基础语…

网络安全linux命令

文章目录&#xff1a; 一&#xff1a;网络信息安全简介 二&#xff1a;网络中存在的威胁 三&#xff1a;常见的攻击类型 1.端口扫描 2.DoS和DDoS攻击 3.特洛依木马&#xff08;Trojan&#xff09; 3.1 木马的工作原理 3.2 特洛伊木马具有的特性 3.3 木马的种类 3.4 被…

Ollama本地部署deepseek-r1蒸馏版

Docker安装Ollama 拉取镜像 docker pull ollama/ollama​ 启动-使用GPU docker run -d --gpusall -p 11434:11434 --name ollama ollama/ollamadocker run : Docker 的核心命令&#xff0c;用于创建并启动一个新的容器。 -d : 后台模式&#xff08;detached mode&#xff09…

Spring Boot 读取 ZooKeeper (ZK) 属性的总结指南

Spring Boot 读取 ZooKeeper (ZK) 属性的总结指南&#xff0c;涵盖配置定义、绑定、初始化和使用&#xff1a; 1. 在配置文件中定义 ZK 属性 在 application.properties 或 application.yml 中添加 ZK 相关配置&#xff1a; application.properties # 单源配置示例 zookeep…

【贪心算法】将数组和减半的最小操作数

1.题目解析 2208. 将数组和减半的最少操作次数 - 力扣&#xff08;LeetCode&#xff09; 2.讲解算法原理 使用当前数组中最大的数将它减半&#xff0c;&#xff0c;直到数组和减小到一半为止&#xff0c;从而快速达到目的 重点是找到最大数&#xff0c;可以采用大根堆快速达到…

Python:函数(一)

python函数相关的知识点 1. 函数定义与调用 定义&#xff1a;使用 def 关键字&#xff0c;后接函数名和参数列表。 def greet(name):"""打印问候语&#xff08;文档字符串&#xff09;"""print(f"Hello, {name}!") 调用&#xff1a…