网页聊天室测试报告

一、测试目标与概括

1.项目概述

网页聊天室是面向于用户进行信息交流的聊天平台,聚焦多用户在线实时双向通信场景。项目基于WebSocket全双工协议实现消息即时推送,规避传统HTTP轮询的性能弊端,通过Java多线程并发机制管理客户端连接,大幅提升多用户同时在线聊天的并发稳定性。

2.测试目标

验证网页聊天室各模块的功能完整性,确保用户的登录功能注册功能 ,以及首页的聊天会话好友列表添加好友等功能符合要求。

二、测试环境

类别 版本/配置
操作系统 Windows 11
手动测试浏览器 Microsoft Edge 版本 146.0.3856.59(正式版本)(64位)
自动化测试浏览器 Google Chrome 版本 145.0.7632.160(正式版本)(64位)
开发工具 Intellij IDEA 2025.3.1
自动化测试工具 Selenium 4.0.0

三、测试用例

1.登录页面测试用例

2.注册页面测试用例

3.主页面测试用例

四、功能测试

本次功能测试采用手动功能测试

1.登录页面

测试1:输入错误账号和错误密码,点击登录

结果:提示登录失败

测试2:输入正确账号和空密码,点击登录

结果:提示输入为空

测试3:输入正确账号正确密码,点击登录

结果:跳转到主页面

2.注册页面

测试1:输入未有账号和空密码

结果:提示为空

测试2:输入已有账号和合理密码

结果:提示用户名相同

测试3:输入未有账号和合理密码

结果:提示注册成功,跳转返回登录页面

3.主页面

3.1 添加好友功能

发送方

测试1:发送添加信息,弹出提示框,输入内容点击确定

结果:发送成功,添加好友列表存在该信息

添加好友列表

测试2:已存在添加好友请求信息(正在等待中),发送添加信息,弹出提示框,输入内容点击确定

结果:发送失败,提示存在添加请求

测试3:已存在添加好友请求信息(已经拒绝),发送添加信息,弹出提示框,输入内容点击确定

结果:发送成功,重新多出一份申请

接收方

测试1:添加好友列表收到消息,点击拒绝

结果:好友列表下方显示已拒绝

点击拒绝

测试2:添加好友列表收到消息,点击同意

结果:添加成功,好友列表有显示

好友列表有显示

3.2 查看历史消息功能

测试:点击会话列表的张三标签

结果:会话列表显示标签高亮,右侧消息对话区上方显示对方用户名,下方显示历史消息和消息编辑区

初始页面

点击张三

3.4 发送消息功能

测试1:登录"何冬",消息编辑框输入"请问你在吗?"消息发送给"张三"

结果:消息在消息展示区右侧展示

测试2:登录"张三",消息编辑框发送"在的"发回给"何冬"

结果:消息在消息展示区左侧展示

五、自动化测试(UI测试)

本次运行环境在谷歌浏览器执行

1.创建utils工具类(创建谷歌浏览器驱动,定义截图工具)

java 复制代码
package com.java_chatroom.selenium.Utils;


import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
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.time.Duration;


//工具类
public class Utils {
    public static WebDriver driver;

    //创建驱动管理程序对象
    public static WebDriver createDriver() {
        if (driver != null) {
            driver.quit();
            driver = null;
        }

        WebDriverManager.chromedriver().setup();
        ChromeOptions options = new ChromeOptions();
        //允许访问所有节点
        options.addArguments("--remote-allow-origins=*");
        //关闭沙盒模式
        options.addArguments("--no-sandbox");
        
        driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(1));
        return driver;
    }



    //屏幕截图
    public void captureScreen(String str) throws IOException {

        //定义文件名格式(采用文件夹名称 + 自定义名称 + 文件时间)
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sim2 = new SimpleDateFormat("HH-mm-ss");

        //以当前年月日定义文件夹名称,以时分秒定义文件名称
        String dirTime = sim1.format(System.currentTimeMillis());
        String fileTime = sim2.format(System.currentTimeMillis());

        String fileName = "./src/test/java/com/java_chatroom/image/" + dirTime + "/" + str + fileTime + ".png";

        //执行截图任务,并赋值
        File file = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(file,new File(fileName));
    }

    public static void quit() {
        if (driver != null) {
            driver.quit();
            driver = null;
        }
    }
}

2.登录页面自动化测试

测试内容:

1、检验页面标签元素是否存在

2、检测数据检验是否合格

3、能否正常登录

运行代码

java 复制代码
package com.java_chatroom.selenium;

import com.java_chatroom.selenium.Utils.Utils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;


//登录页面自动化测试
 public class LoginTest extends Utils {
    //访问 url
    public static String url ="http://8.134.201.57:8081/login.html";

    @BeforeAll
    public static void setUp() {
        driver = createDriver();
        //访问 url
        driver.get(url);
        //最大窗口
        driver.manage().window().maximize();
    }

    @AfterAll
    public static void tearDown() {
        quit();
    }

    @Test
    public void checkLogin(){

        //检测居中的主登录页面以及输入框和按钮
        driver.findElement(By.cssSelector(".login-container"));
        driver.findElement(By.cssSelector(".login-dialog"));
        driver.findElement(By.cssSelector("#username"));
        driver.findElement(By.cssSelector("#password"));
        driver.findElement(By.cssSelector("#submit"));
        driver.findElement(By.cssSelector(".login-dialog a"));
    }

    //测试输入错误用户名
    @Test
    public void Test1() throws IOException{
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入错误用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("liu");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();


        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        //前端页面弹窗处理
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        //accept:确认  dismiss: 取消
        alert.accept();

        //截图
        captureScreen(getClass().getName());
    }

    //测试输入错误的密码
    @Test
    public void Test2() throws IOException {
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入错误密码
        driver.findElement(By.cssSelector("#username")).sendKeys("张三");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();

        //显示等待(避免弹窗加载延迟)
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        //前端页面弹窗处理
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        //accept:确认  dismiss: 取消
        alert.accept();

        //截图
        captureScreen(getClass().getName());
    }


    //测试输入空密码
    @Test
    public void Test3() throws IOException {
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入错误用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("张三");
        driver.findElement(By.cssSelector("#password")).sendKeys("");
        driver.findElement(By.cssSelector("#submit")).click();

        //显示等待(避免弹窗加载延迟)
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        //前端页面弹窗处理
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        //accept:确认  dismiss: 取消
        alert.accept();

        //截图
        captureScreen(getClass().getName());
    }


    //测试输入正确用户名密码
    @Test
    public void Test4() throws IOException {
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入错误用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("张三");
        driver.findElement(By.cssSelector("#password")).sendKeys("123");
        driver.findElement(By.cssSelector("#submit")).click();

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //断言是否成功切换到主页面
        WebElement mainContainer = wait
                .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".Client-container")));
        //没有切换到这个页面就报错
        Assertions.assertNotNull(mainContainer,"页面跳转失败,登录失败!");
        //截图
        captureScreen(getClass().getName());
    }
}

3.注册页面自动化测试

测试内容:

1、检验页面标签元素是否存在

2、检测数据检验是否合格

3、能否正常注册

运行代码

java 复制代码
package com.java_chatroom.selenium;

import com.java_chatroom.selenium.Utils.Utils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;


//注册页面自动化测试
public class RegisterTest extends Utils {
    //访问 url
    public static String url = "http://8.134.201.57:8081/login.html";

    @BeforeAll
    public static void setUp() {
        driver = createDriver();
        //访问 url
        driver.get(url);
        //最大窗口
        driver.manage().window().maximize();
    }

    @AfterAll
    public static void tearDown() {
        quit();
    }

    @Test
    public void checkRegister() {
        //检测居中的主注册页面以及输入框和按钮
        driver.findElement(By.cssSelector(".login-container"));
        driver.findElement(By.cssSelector(".login-dialog"));
        driver.findElement(By.cssSelector("#username"));
        driver.findElement(By.cssSelector("#password"));
        driver.findElement(By.cssSelector("#submit"));
    }

    //测试输入空用户名
    @Test
    public void Test1() throws IOException {
        driver.navigate().to(url);
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入空用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        //前端页面弹窗处理
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        //accept:确认  dismiss: 取消
        alert.accept();

        //截图
        captureScreen(getClass().getName());
    }

    //测试输入空密码
    @Test
    public void Test2() throws IOException {
        driver.navigate().to(url);
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入空密码
        driver.findElement(By.cssSelector("#username")).sendKeys("测试用户");
        driver.findElement(By.cssSelector("#password")).sendKeys("");
        driver.findElement(By.cssSelector("#submit")).click();

        //显示等待(避免弹窗加载延迟)
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        //前端页面弹窗处理
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        //accept:确认  dismiss: 取消
        alert.accept();

        //截图
        captureScreen(getClass().getName());
    }

    //测试输入重复用户名
    @Test
    public void Test3() throws IOException {
        driver.navigate().to(url);
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入重复用户名(张三已存在)
        driver.findElement(By.cssSelector("#username")).sendKeys("张三");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();

        //显示等待(避免弹窗加载延迟)
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        //前端页面弹窗处理
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        //accept:确认  dismiss: 取消
        alert.accept();

        //截图
        captureScreen(getClass().getName());
    }

    //测试输入正确用户名密码
    @Test
    public void Test4() throws IOException {
        driver.navigate().to(url);
        //输入前清空输入框
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        //输入正确用户名密码
        driver.findElement(By.cssSelector("#username")).sendKeys("新一");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#submit")).click();

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //注册成功弹窗
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        alert.accept();

        //断言是否成功切换到登录页面
        WebElement loginContainer = wait
                .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".login-container")));
        //没有切换到这个页面就报错
        Assertions.assertNotNull(loginContainer, "页面跳转失败,注册失败!");
        //截图
        captureScreen(getClass().getName());
    }
}

4.主页面自动化测试

测试内容:

1、检验页面主要元素

2、检验搜索好友框结果是否符合(给定参数:"岳")

3、检验发送添加好友请求能否在添加好友列表中找到

4、同意请求后切换好友列表,点击好友是否能够成功创建会话

5、会话列表页中选择第一个会话,编辑信息发消息是否成功

运行代码

java 复制代码
package com.java_chatroom.selenium;

import com.java_chatroom.selenium.Utils.Utils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;
import java.util.List;

//主页面自动化测试
public class ClientTest extends Utils {
    public static String loginUrl = "http://127.0.0.1:8080/login.html";
    public static String clientUrl = "http://127.0.0.1:8080/client.html";

    @BeforeAll
    public static void setUp() {
        driver = createDriver();
        driver.manage().window().maximize();
    }

    @AfterAll
    public static void tearDown() {
        quit();
    }

    private void login(String username, String password) throws IOException {
        driver.get(loginUrl);
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        
        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("#submit")).click();

        WebElement mainContainer = wait
                .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".Client-container")));
        Assertions.assertNotNull(mainContainer, "登录失败!");
    }

    @Test
    public void Test1() throws IOException {
        //登录用户
        login("张三", "123");

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //检测页面主要元素
        driver.findElement(By.cssSelector(".Client-container"));
        driver.findElement(By.cssSelector(".main"));
        driver.findElement(By.cssSelector(".main .left .user"));
        driver.findElement(By.cssSelector(".left .search input"));
        driver.findElement(By.cssSelector(".left .search button"));
        driver.findElement(By.cssSelector(".tab .tab-session"));
        driver.findElement(By.cssSelector(".tab .tab-friend"));
        driver.findElement(By.cssSelector(".tab .tab-insert"));
        driver.findElement(By.cssSelector("#session-list"));
        driver.findElement(By.cssSelector("#friend-list"));
        driver.findElement(By.cssSelector("#insert-list"));
        driver.findElement(By.cssSelector(".right"));
        driver.findElement(By.cssSelector(".right .title"));
        driver.findElement(By.cssSelector(".right .message-show"));
        driver.findElement(By.cssSelector(".right .message-input"));
        driver.findElement(By.cssSelector(".right .ctrl button"));

        captureScreen(getClass().getName());
    }

    //搜索框查询功能
    @Test
    public void Test2() throws IOException {
        login("张三", "123");

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //搜索好友
        WebElement searchInput = driver.findElement(By.cssSelector(".left .search input"));
        WebElement searchButton = driver.findElement(By.cssSelector(".left .search button"));
        
        searchInput.clear();
        searchInput.sendKeys("岳");
        searchButton.click();

        //等待搜索结果显示
        WebElement selectList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#select-list")));
        List<WebElement> results = selectList.findElements(By.tagName("li"));
        
        Assertions.assertTrue(results.size() > 0, "未查询到匹配好友!");

        for (WebElement li : results) {
            String friendName = li.getText();
            Assertions.assertTrue(friendName.contains("岳"), "搜索有误");
        }

        captureScreen(getClass().getName());
    }

    //检验发送添加好友请求能否在添加好友列表中找到
    @Test
    public void Test3() throws IOException {
        login("张三", "123");

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //搜索好友
        WebElement searchInput = driver.findElement(By.cssSelector(".left .search input"));
        WebElement searchButton = driver.findElement(By.cssSelector(".left .search button"));
        
        searchInput.clear();
        searchInput.sendKeys("岳");
        searchButton.click();

        //等待搜索结果显示
        WebElement selectList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#select-list")));
        List<WebElement> results = selectList.findElements(By.tagName("li"));
        
        Assertions.assertTrue(results.size() > 0, "未查询到匹配好友!");

        //点击第一个好友的添加按钮
        WebElement addBtn = results.get(0).findElement(By.cssSelector(".add-friend"));
        addBtn.click();

        //处理添加好友验证信息弹窗
        Alert alert = wait.until(ExpectedConditions.alertIsPresent());
        alert.sendKeys("你好,能不能加个好友");
        alert.accept();

        //切换到添加好友列表
        driver.findElement(By.cssSelector(".tab .tab-insert")).click();

        //验证请求是否在列表中
        WebElement insertList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#insert-list")));
        List<WebElement> requests = insertList.findElements(By.tagName("li"));
        
        Assertions.assertTrue(requests.size() > 0, "添加好友列表为空!");

        boolean requestFound = false;
        for (WebElement li : requests) {
            String text = li.getText();
            //查询是否包含这个名字
            if (text.contains("岳山")) {
                requestFound = true;
                break;
            }
        }
        
        Assertions.assertTrue(requestFound, "未找到岳山相关的好友请求!");

        captureScreen(getClass().getName());
    }

    @Test
    public void Test4() throws IOException {
        login("岳山", "222");

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //点击添加好友列表标签
        driver.findElement(By.cssSelector(".tab .tab-insert")).click();

        //等待添加列表加载
        WebElement insertList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#insert-list")));
        
        //找到张三发来的请求并点击同意
        List<WebElement> requests = insertList.findElements(By.tagName("li"));
        boolean found = false;
        
        for (WebElement li : requests) {
            if (li.getText().contains("张三")) {
                WebElement yesBtn = li.findElement(By.id("yes"));
                if (yesBtn != null) {
                    yesBtn.click();
                    found = true;
                    break;
                }
            }
        }
        
        Assertions.assertTrue(found, "未找到张三发来的好友请求!");

        //切换到好友列表标签
        driver.findElement(By.cssSelector(".tab .tab-friend")).click();

        //等待好友列表加载
        WebElement friendList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#friend-list")));
        
        //验证张三是否在好友列表中
        List<WebElement> friends = friendList.findElements(By.tagName("li"));
        boolean zhangSanFound = false;
        
        for (WebElement li : friends) {
            if (li.getText().contains("张三")) {
                li.click();
                zhangSanFound = true;
                break;
            }
        }
        
        Assertions.assertTrue(zhangSanFound, "张三未在好友列表中!");

        captureScreen(getClass().getName());
    }

    @Test
    public void Test5() throws IOException {
        login("张三", "123");

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));

        //切换到会话列表
        driver.findElement(By.cssSelector(".tab .tab-session")).click();

        //等待会话列表加载
        WebElement sessionList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#session-list")));
        List<WebElement> sessions = sessionList.findElements(By.tagName("li"));
        
        Assertions.assertTrue(sessions.size() > 0, "会话列表为空!");

        //选择第一个会话
        sessions.get(0).click();

        //等待消息区域加载
        WebElement messageShow = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".right .message-show")));

        //输入消息
        WebElement messageInput = driver.findElement(By.cssSelector(".right .message-input"));
        WebElement sendButton = driver.findElement(By.cssSelector(".right .ctrl button"));
        
        String testMessage = "这是一个测试消息";
        messageInput.clear();
        messageInput.sendKeys(testMessage);
        sendButton.click();

        //验证消息是否发送成功(轮询等待messageShow包含testMessage这段文字)
        wait.until(ExpectedConditions.textToBePresentInElement(messageShow, testMessage));
        
        captureScreen(getClass().getName());
    }
}

六、界面测试

登录页面布局

注册页面布局

主页面默认布局

搜索结果布局

查看历史消息布局

七、兼容性测试

1、Google Chrome环境

2、Microsoft Edge环境

相关推荐
hai3152475431 小时前
九章编译法:DEEPSEEK V3.2汇编编译实例
java·开发语言
ONE_SIX_MIX1 小时前
lightweight-charts-onesixth v2.8.1 → v3.1.1 更新总览
java·前端·python
SimonKing1 小时前
一文终结 SpringBoot 国际化!从 0 到 1 完整案例(中/英/日)
java·后端·程序员
ByWalker_1 小时前
web应用技术—MyBatis入门
java·数据库·mybatis·lombok
在书中成长2 小时前
HarmonyOS 小游戏《对战五子棋》开发第17篇 - AI的两种评估策略
android·java·javascript
奋斗的小方2 小时前
Java进阶篇1-3:集合框架(单列集合)
java·windows·python
湮w2 小时前
JavaWeb(三)JavaScript详细讲解
java·javascript·web
gcw10242 小时前
Cron专业工具:定时任务与开发办公的一站式在线工具箱
java·前端·数据库·工具·crontab·cron·spring cron
whaledown2 小时前
互联网大厂Java求职面试三轮提问详解(涵盖Spring Boot、微服务、Kafka等核心技术)
java·jvm·数据库·spring boot·微服务·面试·kafka