软件测试相关内容第五弹 -- 自动化测试Selenium

写在前:hello这里是西西~ 这边博客主要学习关于自动化测试的相关内容,首先了解自动化测试的相关理论知识,其次学习web应用中基于UI的自动化测试框架 - selemium[需要重点掌握selenium工作原理],实操selenium,最后学习Junit相关知识,开始学习之旅吧!

目录

1.自动化测试相关理论

1.1 什么是自动化测试

1.2 自动化测试的分类

1.2.1  单元测试

1.2.2 接口测试

1.2.3 UI测试

1.3 如何实施自动化测试

2. Selenium和Junit

2.1 Selenium

2.1.1 是什么

2.1.2 特点

2.1.3  工作原理

2.2 Selenium + Java环境搭建

2.2.1 下载Chrome浏览器

2.2.2 查看Chrome版本

2.2.3 下载浏览器驱动

2.2.4 配置环境变量PATH

2.2.5 验证环境搭建是否成功

2.3 Selenium实操

2.3.1 元素定位

2.3.2 XPath定位

2.3.3 操作测试对象

(1)send_keys在对象上模拟按键输入

(2)click点击对象

(3)clear 清楚对象输入的文本内容

(4)submit 提交

(5)text 用于获取元素的文本信息

2.3.4 添加等待

(1)sleep休眠

(2)隐式等待

(3)显式等待

2.3.5 打印信息

2.3.6 浏览器操作

2.3.7  键盘事件

2.3.8 鼠标事件

2.3.9 定位一组元素

2.3.10 多层框架 / 窗口定位

2.3.11 下拉框处理

2.3.12 alert 

2.3.13 上传文件

2.3.14 补充

(1)关闭浏览器

(2)切换窗口

(3)截图

2.4 Junit

2.4.1 注解

2.4.2 参数化

2.4.3 断言 assert

2.4.4 测试套件 suite


1.自动化测试相关理论

1.1 什么是自动化测试

自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常条件和异常条件,最后评估运行结果。

将人工测试手段进行转换,让代码执行的过程。

1.2 自动化测试的分类

自动化测试包括UI自动化、接口自动化、单元测试自动化;

按照下面的金字塔模型来进行自动化测试规划,可以产生最佳自动化测试产出投入比(ROI),可以用较少的投入获得很好的收益。

1.2.1  单元测试

最大的投入应该改在单元测试上,单元测试的运行频率也更高;

java单元测试框架是Junit,后面会重点介绍。

1.2.2 接口测试

接口测试就是API测试,相对于UI自动化,API自动化更加容易实现,执行起来也更稳定。

接口测试自动化有如下特点:

  • 可在产品前期,接口完成后介入;
  • 用户维护量小;
  • 适合于接口变动小、界面变动频繁的项目;

常见的接口自动化测试工具有:RobotFramework,JMeter、SoapUI、TestNG+HttpClient、Postman等。

1.2.3 UI测试

UI自动化更加贴近用户的需求和软件系统的实际业务,有时不得不进行。

特点:

  • 用例维护量大;
  • 页面相关性强,必须后期项目页面开发完后介入;
  • UI测试适合与界面变动较小的项目;

在这里主要以Web UI自动化测试框架Selenium进行学习。

1.3 如何实施自动化测试

自动化测试的具体实现,应该包含以下七个过程

  1. 分析:总体把握系统逻辑,分析出系统的核心体系框架;
  2. 设计:设计测试用例,测试用例要足够明确和清晰,覆盖面广而精;
  3. 实现:实现脚本,有两个要求,断言和合理的运用参数化;
  4. 执行:执行中的异常需要我们仔细分析原因;
  5. 总结:对测试结果进行分析,对测试过程进行总结;
  6. 维护:难以解决但是必须解决;
  7. 分析:在自动化测试过程中深刻分析自动化测试用例的覆盖风险和脚本维护成本。

2. Selenium和Junit

2.1 Selenium

2.1.1 是什么

web应用中基于UI的自动化测试框架支持多平台,多浏览器,多语言。

早期的Selenium RC已经被现在的webDriver所替代,可以理解为 selenium2.0 = selenium1.0 +webDriver现在提到selenium一般指的是2.0,组成部分:Selenium IDE,webDriver,selenium GridSelenium IDE:用于Selenium测试的集成开发环境,可以直接录制在浏览器的用户操作,并且可以回放、编辑和调试测试脚本。调试过程中可以逐步进行调整执行的速度,并且可以在底部浏览日志出错信息。webDriver:Selenium RC在浏览器中运行JavaScript 应用,会存在环境沙箱问题,而webDriver可以跳出JavaScript的沙箱,针对不同的浏览器创建更健壮的、分布式的、跨平台自动化测试脚本,基于特定语言绑定来驱动浏览器对Web元素进行操作和验证。

  • 沙箱模式(Sandbox Pattern),顾名思义沙箱模式是创建了一个"沙箱",可以理解为创建了一个黑盒,我们不管在里面做什么都不会影响到外面。而在JavaScript中就意味着,在沙箱中的操作被限死在当前作用域,不会对其他模块和个人沙箱造成任何影响。

webDriver工作原理

  • 启动浏览器后,Selenium - webDriver 会将目标浏览器绑定到特定的端口,启动后的浏览器则作为webDriver的远程服务器【remote server】
  • 客户端(测试脚本)借助ComandExecutor发送HTTP请求给server端【通信协议:The webDriver Wire Protocol,在HTTP request 的body中,会以webDriver Wire协议规定JSON格式的字符串来告诉Selenium我们希望浏览器接下来的操作】
  • Server端依赖原生的浏览器组件,转换为Web Serive的命令为浏览器本地的【native】的调用来完成操作

Selenium Grid:是一个服务器,提供对浏览器实例访问的服务器列表,管理各个节点的注册和状态信息,可以实现在同一时刻不同服务器上执行不同的测试脚本。

2.1.2 特点

  • 免费,不需要破解
  • 小巧,只是一个包
  • 支持的语言多
  • 支持多平台,多浏览器
  • 支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器执行,相当于分发机的功能

2.1.3  工作原理

2.2 Selenium + Java环境搭建

Java最低要求为8,浏览器推荐使用chrome;

2.2.1 下载Chrome浏览器

https://www.google.cn/intl/zh-CN/chrome/

2.2.2 查看Chrome版本

2.2.3 下载浏览器驱动

ChromeDriver - WebDriver for Chrome - Downloads

找到对应的驱动,并且要确保版本与Chrome的版本一致。

2.2.4 配置环境变量PATH

解压下载好的驱动压缩包,将下载好的chromedriver.exe放到Java的bin目录下;

2.2.5 验证环境搭建是否成功

(1)创建Java项目,添加pom依赖

<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></dependencies>

注意:版本选择selenium3

(2)编写运行代码

public class Main {public static void main(String[] args) {//创建驱动对象之前手动指定chromedriver.exe所在路径:System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");//WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));WebElement element1 = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));element1.sendKeys("首次测试");}
}

(3)点击运行

安装成功啦~~~

如果报错:ConnectionFailedException/403,需要加上代码

ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver driver = new ChromeDriver(options);

接下来的介绍需要重点掌握Selenium常用API的使用、操作测试对象以及添加等待打印信息、键盘事件、鼠标事件等案例的掌握

2.3 Selenium实操

2.3.1 元素定位

(1)css选择器

找到页面中的百度输入框

找到并返回类型

 WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));

      //输入软件测试element.sendKeys("首次测试");

CSS选择器语法:

  • id选择器: #id
  • 类选择器:.class
  • 标签选择器:标签名
  • 后代选择器:父级选择器 子级选择器

2.3.2 XPath定位

(1)绝对路径

不常用,效率低

(2)相对路径 [只介绍常用的]

  • 相对路径 + 索引:[找输入框]
    //form/span[1]/input//form/span[1]/input
  • 相对路径 + 属性值:找输入框和按钮
    //form/span[2]/input

//input[@id = "su"]

  • 相对路径 + 通配符
    //*[@* = "su"]

是基于属性值的简写

  • 相对路径 + 文本匹配
    //a[text() = "新闻"]

2.3.3 操作测试对象

找到对应的百度一下输入框,输入“我爱编程”,并点击按钮

(1)send_keys在对象上模拟按键输入
  element1.sendKeys("我爱编程");
(2)click点击对象
webDriver.findElement(By.cssSelector("#su")).click();
(3)clear 清楚对象输入的文本内容
public static void test02() throws InterruptedException {System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");sleep(3000);//打开百度页面,找到对应的输入框,输入文字webDriver.findElement(By.cssSelector("#kw")).sendKeys("今天你学习了么");//找到按钮点击webDriver.findElement(By.cssSelector("#su")).click();sleep(5000);//清空输入框中的数据webDriver.findElement(By.cssSelector("#kw")).clear();}
(4)submit 提交

如果点击的元素放在form标签中,此时使用submit效果 = click,非form表单中无效。

(5)text 用于获取元素的文本信息

输入“我爱编程”,并点击按钮,如果1返回的结果中包含“我爱编程”字眼,则测试通过,否则测试不通过。

//校验//找到搜索的结果int flag = 0;List<WebElement> elements = webDriver.findElements(By.cssSelector("a em"));for (int i = 0; i < elements.size(); i++) {//如果返回的结果有“我爱编程”,证明测试通过,否则不if(elements.get(i).getText().equals("我爱编程")){flag = 1;System.out.println("测试通过");break;}}if(flag == 0){System.out.println("测试不通过");}

运行代码返回结果:

2.3.4 添加等待

(1)sleep休眠

添加休眠非常简单,引入time包,就可以在脚本中自由添加休眠时间了,这里的休眠指的是固定休眠。

(2)隐式等待

如果等待时间是3天,sleep就是三天,隐式等待最长等待3天,如果在3天内获取到页面上的元素,此时就执行下面的代码,如果三天还是没有找到,此时就报错。

webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);

扫描当前页面,不能针对某一确定元素等待,等待所有的元素。

(3)显式等待

等待后面的条件,是程序员自己设置的。

2.3.5 打印信息

打印title + 打印url

public static void  test03(){System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");//获取链接String url = webDriver.getCurrentUrl();//获取标题String title  = webDriver.getTitle();if(url.equals("https://www.baidu.com/") && title.equals("百度一下,你就知道")){System.out.println("当前页面url:" + url + ",当前title:" +title );System.out.println("测试通过");}else {System.out.println("测试不通过");}}

2.3.6 浏览器操作

浏览器最大化 浏览器前进 后退 浏览器滚动条

 public static  void test04() throws InterruptedException {System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度首页webDriver.get("https://www.baidu.com");//搜索二叉树webDriver.findElement(By.cssSelector("#kw")).sendKeys("二叉树");webDriver.findElement(By.cssSelector("#su")).click();//强制等待3秒sleep(3000);//浏览器后退webDriver.navigate().back();//强制等3秒sleep(3000);webDriver.navigate().refresh();//浏览器前进webDriver.navigate().forward();//强制等待3秒sleep(3000);//将浏览器滚动条滑倒最底端((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");//将浏览器最大化webDriver.manage().window().maximize();sleep(3000);webDriver.manage().window().fullscreen();sleep(3000);//设置浏览器的长宽webDriver.manage().window().setSize(new Dimension(700,800));}

2.3.7  键盘事件

sendKeys(Keys.CONTROL,"A/C/X/V")

    public static  void test05() throws InterruptedException {System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();//打开百度首页webDriver.get("https://www.baidu.com");//搜索新闻联播webDriver.findElement(By.cssSelector("#kw")).sendKeys("新闻联播");webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");sleep(3000);webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"X");sleep(3000);webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"V");sleep(3000);}

2.3.8 鼠标事件

 public static void test06() throws InterruptedException {System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");webDriver.findElement(By.cssSelector("#kw")).sendKeys("新闻");webDriver.findElement(By.cssSelector("#su")).click();sleep(3000);//找到图片按钮WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));//鼠标右击Actions actions = new Actions(webDriver);sleep(3000);actions.moveToElement(webElement).contextClick().perform();}

接下来学习针对特殊的场景进行测试。

2.3.9 定位一组元素

List<WebElement> webelements = findElements(By.cssSelector("input"));for(int i = 0; i < webElements.size(); i++) {// 如果每个元素type值等于checkbox进行点击// getAttribute获取页面上的元素属性值,里面的type是当前元素属性if(webElements.get(i).getAttribute("type").equals("checkbox")){webElements.get(i).click();} else {// 否则什么也不操作;}}

2.3.10 多层框架 / 窗口定位

switchTo().frame("name/id/frame_element")

通过frame的id或者name或者或者frame自带的其它属性来定位框架,这里的switchTo().frame()把当前定位的主体切换到frame里。

switchTo().default_content

从frame中嵌入的页面跳转出来,跳回到最外面的默认页面中。

 webDriver.switchTo().frame("f1");webDriver.findElement(By.cssSelector("body > div > div > a")).click();

2.3.11 下拉框处理

 WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select = new Select(webElement);select.selectByValue("15");

2.3.12 alert 

  • text 返回alert/confirm/prompt 中的文字信息
  • accept 点击确认按钮
  • dismiss 点击取消按钮
  • sendKeys输入值,如果alert没有对话框的话就不能用,否则报错
webDriver.findElement(By.cssSelector("button")).click();sleep(3000);// alert弹窗取消webDriver.switchTo().alert().dismiss();sleep(3000);// 点击按钮webDriver.findElement(By.cssSelector("button")).click();// 在alert弹窗中输入好好学习webDriver.switchTo().alert().sendKeys("好好学习");// alert弹窗确认sleep(3000);webDriver.switchTo().alert().accept();

2.3.13 上传文件

webDriver.findElement(By.cssSelector("input")).sendKeys("D:\\untitled");

2.3.14 补充

(1)关闭浏览器

关闭当前页面(原始页面),不会清空缓存

webDriver.close();

 关闭了整个浏览器,会清除缓存

webDriver.quit();
(2)切换窗口
        // 通过getWindowHandles获取所有的窗口句柄// 通过getWindowHandle获取的get打开的页面窗口句柄System.out.println(webDriver.getWindowHandle());Set<String> handles = webDriver.getWindowHandles();String target_handle = "";for(String handle:handles) {target_handle = handle;}webDriver.switchTo().window(target_handle);sleep(3000);webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
(3)截图
 webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#su")).click();sleep(3000);File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file, new File("D://jietu.png"));

2.4 Junit

首先在pom.xml添加Junit依赖

   <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.5.2</version></dependency>

这里使用的是Junit5,Junit是针对Java的单元测试框架。

2.4.1 注解

注解含义代码示例
@Test

表示当前的方法是一个测试用例

添加依赖 pom.xml(Junit 5 )

 @Testvoid Test01() {System.out.println("这是JunitTest里面的Test01");}

@Disabled

忽略 跳过
@Disabledvoid Test03() {WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com");webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)"));}

@BeforeAll

所有测试用例执行前跑的代码

 @BeforeAll
static void SetUp() {System.out.println("BeforeAll里面的语句");}
@AfterAll

所有测试用例执行后跑的代码

初始化在前(创建驱动、打开网页)

 @AfterAllstatic void TearDown() {System.out.println("这是AfterAll的语句");}

@AfterEach

每一次测试用例执行之后

关闭资源在后(关闭浏览器)

  @AfterEachvoid AfterEachTest() {System.out.println("这是AfterEach里面的语句");}

@BeforeEach每一次测试用例执行之前
@BeforeEachvoid BeforeEachTest() {System.out.println("这是BeforeEach里面的语句");}

2.4.2 参数化

参数注解代码示例
单参数@ParameterizedTest
  void Test04(int num) {System.out.println(num);}

@ValueSource(ints = {1, 2, 3})
CSV获取参数@ParameterizedTest
void Test06(String name) {System.out.println(name);}

@CsvFileSource(resources = "test01.csv")
方法获取参数@ParameterizedTest
  public static Stream<Arguments> Generator() {return Stream.of(Arguments.arguments("1,张三","2,李四"));}@ParameterizedTest@MethodSource("Generator")void Test04(String num, String name) {System.out.println(num + name);}

@MethodSource("Generator")
多参数@ParameterizedTest
    @ParameterizedTest@CsvSource({"1, 2, 3, ''"})void Test02(String x, String y, int z, String q) {System.out.println(x);System.out.println(y);System.out.println(z);System.out.println(q);System.out.println("============================");}@ParameterizedTest@CsvFileSource(resources = "test02.csv")void Test03(int num, String name) {System.out.println("学号:" + num + ",姓名:" + name);}

@CsvSource

2.4.3 断言 assert

相等
   @ParameterizedTest@ValueSource(ints = {1})void Test01(int num) {System.out.println(num);Assertions.assertEquals(1, num);
不相等
Assertions.assertNotEquals(1,num)
为空
Assertions.assertNull(str)
不为空
Assertions.assertNotNull(str)

2.4.4 测试套件 suite

引用依赖

        <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.jupiter/junit-jupiter-engine --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.9.1</version><scope>test</scope></dependency>

@Suite

(1)通过class运行测试用例  (2)通过package

@Suite
// 通过class测试用例运行
@SelectPackages(value = {"Test09", "Test08"})
//@SelectClasses({JunitTest03.class, JunitTest.class, JunitTest01.class})
public class RunSuite {
}

下篇预告:自动化测试实战 -- “西西简易博客系统”的自动化测试

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

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

相关文章

当我想用ChatGPT-Next-Web来套壳Azure OpenAI Service时

使用Cloudflare worker来代理Azure OpenAI API&#xff0c; 并将其转换为兼容OpenAI的API 一直没能搞定OpenAI的订阅&#xff0c; 就因为没有搞定国外的信用卡&#xff0c; 所以就一直使用GPT-3.5来处理日常的文字生成工作&#xff0c; 例如写文档&#xff0c; 生成一些简单的脚…

AI助力生产制造质检,基于轻量级YOLOv8n模型开发构建工业生产制造场景下的瓷砖瑕疵检测识别分析系统

瓷砖生产环节一般经过原材料混合研磨、脱水、压胚、喷墨印花、淋釉、烧制、抛光&#xff0c;最后进行质量检测和包装。得益于产业自动化的发展&#xff0c;目前生产环节已基本实现无人化。而质量检测环节仍大量依赖人工完成。一般来说&#xff0c;一条产线需要配数名质检工&…

论文阅读-MIPD:一种用于分布式深度神经网络训练的自适应梯度稀疏化框架

摘要—基于参数服务器架构的异步训练广泛应用于大规模数据集和深度神经网络模型的扩展训练。在大规模分布式深度学习系统中&#xff0c;通信一直被认为是主要瓶颈。最近的研究尝试通过梯度稀疏化和量化方法来减少通信流量。我们发现前期研究存在三个限制。首先&#xff0c;他们…

YOLOv5-Y5周:yolo.py文件解读

本文为&#x1f517;365天深度学习训练营 中的学习记录博客 原作者&#xff1a;K同学啊|接辅导、项目定制 我的环境&#xff1a; 1.语言&#xff1a;python3.7 2.编译器&#xff1a;pycharm 3.深度学习框架Tensorflow/Pytorch 1.8.0cu111 一、代码解读 import argparse i…

【洛谷 P8715】[蓝桥杯 2020 省 AB2] 子串分值 题解(组合数学+乘法原理)

[蓝桥杯 2020 省 AB2] 子串分值 题目描述 对于一个字符串 S S S, 我们定义 S S S 的分值 f ( S ) f(S) f(S) 为 S S S 中恰好出现一次的字符个数。例如 f ( ′ ′ a b a ′ ′ ) 1 f\left({ }^{\prime \prime} \mathrm{aba}{ }^{\prime \prime}\right)1 f(′′aba′′)…

Vscode与Cmake搭配配置opencv使用

vscode与Cmake基本使用 下载插件 CtrlShiftp打开VSCode的指令面板&#xff0c;然后输入cmake:q&#xff0c;VSCode会根据输入自动提示&#xff0c;然后选择CMake: Quick Start选择编译器根据提示输入项目名称选择可执行文件编译项目 方式一&#xff1a;执行命令cd build cmake…

一键将自己网增加一个抖音小程序-源代码

把自己的网址链接&#xff0c;也就是你想要的一个页面转变为抖音小程序&#xff0c;让你轻松拥有一个自己的抖音小程序。 几分钟搞定。 跟着视频来操作就可以了&#xff0c;很简单。视频一定要完整看完啊&#xff0c;对于小白。 如果你的网址可能有不好过审核的页面&#xff0c…

基于python+vue的stone音乐播放器的设计与实现flask-django-php-nodejs

随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;stone音乐播放器展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为解决用…

华为配置WLAN 802.1X认证实验

配置WLAN 802.1X认证示例 组网图形 图1 配置802.1X认证组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤 业务需求 用户接入WLAN网络&#xff0c;使用802.1X客户端进行认证&#xff0c;输入正确的用户名和密码后可以无线上网。且在覆盖区域内移动发生漫游时&…

MySQL面试题--MySQL内部技术架构

目录 1.Mysql内部支持缓存查询吗&#xff1f; 2.MySQL8为何废弃掉查询缓存&#xff1f; 3.替代方案是什么&#xff1f; 4.Mysql内部有哪些核心模块组成&#xff0c;作用是什么&#xff1f; 5.一条sql发送给mysql后&#xff0c;内部是如何执行的&#xff1f;&#xff08;说…

MYSQL 同步到ES 如何设计架构保持一致性

简单使用某个组件很容易&#xff0c;但是一旦要搬到生产上就要考虑各种各样的异常&#xff0c;保证你方案的可靠性&#xff0c;可恢复性就是我们需要思考的问题。今天来聊聊我们部门在 MYSQL 同步到ES的方案设计。 在面对复杂条件查询时&#xff0c;MYSQL往往显得力不从心&…

Gitlab介绍

1.什么是Gitlab GitLab是一个流行的版本控制系统平台&#xff0c;主要用于代码托管、测试和部署。 GitLab是基于Git的一个开源项目&#xff0c;它提供了一个用于仓库管理的Web服务。GitLab使用Ruby on Rails构建&#xff0c;并提供了诸如wiki和issue跟踪等功能。它允许用户通…

从0到1实现RPC | 02 RpcConsumer的远程调用

一、RPC的简化版原理如下图&#xff08;核心是代理机制&#xff09;。 1.本地代理存根: Stub 2.本地序列化反序列化 3.网络通信 4.远程序列化反序列化 5.远程服务存根: Skeleton 6.调用实际业务服务 7.原路返回服务结果 8.返回给本地调用方 二、新建一个模块rpc-demo-c…

后端程序员入门react笔记(九)- react 插件使用

setState setState引起的react的状态是异步的。操作完毕setState之后如果直接取值&#xff0c;可能取不到最新的值&#xff0c;我们举个例子console.log(this.state.num)打印的值&#xff0c;总是上一次的值而不是最新的。 import React, {Component} from react; class Ap…

基于ArcGIS的2015-2020辽宁省土地利用变化分析

数据准备 栅格转面 运行ArcToolbox&#xff0c;打开【转换工具】&#xff0c;选择【从栅格转出】里面的【栅格转面工具】&#xff0c;调出面板进行参数设置。输入栅格选择裁剪的2015年中国土地利用遥感监测数据&#xff08;…

数据挖掘与分析学习笔记

一、Numpy NumPy&#xff08;Numerical Python&#xff09;是一种开源的Python库&#xff0c;专注于数值计算和处理多维数组。它是Python数据科学和机器学习生态系统的基础工具包之一&#xff0c;因为它高效地实现了向量化计算&#xff0c;并提供了对大型多维数组和矩阵的支持…

【ReactJS】使用GoJS实现自己的图表App

目录 1:用于绘制自定义图表的JavaScript库:用于绘制UML(或BPMN或ERD …)图表的JavaScript库:2:为什么选择GoJS?3:让我们使用现有的React应用程序:步骤1:步骤2:步骤3:步骤4:推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战1:…

git创建仓库、克隆、拉取、上传、历史等常见操作集锦

本地工作目录、暂存区、本地仓库和远程仓库 workspace工作区:本地项目地址index/stage暂存区:git add .将工作区内容加入到了暂存区repository本地仓库:在本地存储多个版本的文件,也称为版本库。其中有一个head指针指向最新放入仓库的文件版本,git commit -m "描述你…

[医学分割大模型系列] (1) SAM 分割大模型解析

[医学大模型系列] [1] SAM 分割大模型解析 1. 特点2. 网络结构2.1 Image encoder2.2 Prompt encoder2.3 Mask decoder 3. 数据引擎4. 讨论 论文地址&#xff1a;Segment Anything 开源地址&#xff1a;https://github.com/facebookresearch/segment-anything demo地址&#x…

C#,图片分层(Layer Bitmap)绘制,反色、高斯模糊及凹凸贴图等处理的高速算法与源程序

1 图像反色Invert 对图像处理的过程中会遇到一些场景需要将图片反色,反色就是取像素的互补色,比如当前像素是0X00FFFF,对其取反色就是0XFFFFFF – 0X00FFFF = 0XFF0000,依次对图像中的每个像素这样做,最后得到的就是原始2 图像的反色。 2 高斯模糊(Gauss Blur)算法 …