当前位置: 首页 > news >正文

Selenium自动化测试(基于Java)

目录

一. 了解Selenium

✅1.1 概念

✅1.2 作用

✅1.3 特点

✅1.4 工作原理

 二. Selenium + Java 环境搭建

✅2.1 下载 Chrome 浏览器

✅2.2 查看浏览器的版本

✅2.3 下载浏览器驱动

✅2.4 验证环境是否搭建成功

三. Selenium 常用 API

✅3.1 定位元素

✅3.2 操作对象

✅3.3 添加等待

✅3.4 打印信息

✅3.5 浏览器操作

✅3.6 键盘操作

✅3.7 鼠标操作

✅3.8 定位一组元素

✅3.9 下拉框处理

✅3.10 切换窗口句柄

✅3.11 截图操作

✅3.12 上传文件操作

✅面试题:quit 和 close的区别


一. 了解Selenium

✅1.1 概念

Selenium是一个免费的/开源自动化测试框架,是一个Web应用程序测试工具;

✅1.2 作用

用于测试Web应用程序在不同的浏览器和不同平台上是否能工作正常;

✅1.3 特点

可以使用多种编程语言来编写Selenium测试脚本,如java, C#, Python等编程语言。自动化测试工具Selenium内置有记录和回放功能,用于记录和回放Web应用程序测试过程,且可在不同的浏览器上运行多个脚本;

✅1.4 工作原理

浏览器自动化测试工具Selenium:可以帮测试人员实现浏览器的自动化测试。借助Selenium WebDriver自动化测试工具,测试人员可以同时选择Google Chrome、Mozilla Firefox,Safari、Microsoft Edge、Opera等所有主要浏览器来执行浏览器自动化测试。每个浏览器都有各自的浏览器驱动程序,而这些浏览器驱动程序都有各自的HTTP服务器;

Selenium脚本会为每个Selenium命令创建一个HTTP请求,并且将HTTP请求发送给浏览器驱动程序。浏览器驱动程序会将HTTP请求发送到服务器。这些步骤都是在HTTP服务器上执行的。被发送到HTTP服务器上的执行状态最终由自动化脚本记录。


 二. Selenium + Java 环境搭建

✅2.1 下载 Chrome 浏览器

Google Chrome 谷歌浏览器下载 (yiliwl.top)http://bb.yiliwl.top/第一步就是下载一个浏览器,这里推荐使用 Chrome 浏览器,可以自行去下载;


✅2.2 查看浏览器的版本

 这里需要记住你的浏览器版本;


✅2.3 下载浏览器驱动

CNPM Binaries Mirror (npmmirror.com)https://registry.npmmirror.com/binary.html?path=chromedriver/

 

点击上面的链接,根据你浏览器的版本,选择相应的压缩包进行下载就可,将下载好的压缩包解压放到你安装JDK的bin目录下就OK了;


✅2.4 验证环境是否搭建成功

第一步:在IDEA里创建一个Maven工程项目,在 pro.xml 文件加入相应的依赖:

<!-- 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>

第二部,创建一个java文件,写入相应代码,执行查看结果:

public class Demo2 {public static void main(String[] args) {// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);// 启动需要打开的网页webDriver.get("https://www.baidu.com");}
}

运行一下代码可以看到弹出一个百度的浏览器界面,这里就是一个简单的,通过自动化来打开一个百度的网页,到这里的话,你的自动化测试环境就搭建好了,如果上述安装环境遇到啥问题,可以私信我帮忙解决;


三. Selenium 常用 API

✅3.1 定位元素

对象的定位应该是自动化测试的核心,要想操作一个对象,首先应该识别这个对象;

Selenium提供了8种定位方式。

  • id
  • name
  • class name
  • tag name
  • link text
  • partial link text
  • xpath
  • css selector

这8种定位方式在Java selenium中所对应的方法为:

  • findElement(By.id())
  • findElement(By.name())
  • findElement(By.className())
  • findElement(By.tagName())
  • findElement(By.linkText())
  • findElement(By.partialLinkText())
  • findElement(By.xpath())
  • findElement(By.cssSelector())

我们可以通过借助浏览器的开发者工具,去获取我们想要去定位元素的值,假设我们要对百度页面的输入框进行测试,我们可以点击点击输入框打开开发者工具,去获取我们要的值,这里代码给大家演示:

 

 public static void main(String[] args) {// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);// 启动需要打开的网页webDriver.get("https://www.baidu.com");// 通过id来定位,在输入框输入你好webDriver.findElement(By.id("kw")).sendKeys("你好");// 通过name来定位webDriver.findElement(By.name("wd")).sendKeys("你好");// 通过Xpath来定位webDriver.findElement(By.xpath("//*[@id=\"kw\"]")).sendKeys("你好");// 通过css选择器来定位webDriver.findElement(By.cssSelector("#kw")).sendKeys("你好");}

 这里我们就是通过定位到输入框的元素,然后在输入框内输入你好字段;


✅3.2 操作对象

webdriver 中比较常用的操作对象的方法有下面几个:

  • click 点击对象
  • send_keys 在对象上模拟按键输入
  • clear 清除对象输入的文本内容
  • submit 提交
  • text 用于获取元素的文本信息
 private static void test2() throws InterruptedException {// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);// 启动需要打开的网页webDriver.get("https://www.baidu.com");// 利用类选择器定位元素,百度输入框WebElement element = webDriver.findElement(By.cssSelector("#kw"));// 利用Xpath路径去定位元素//WebElement element = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));element.sendKeys("你好");sleep(2000);// 输入内容进行点击webDriver.findElement(By.cssSelector("#su")).click();sleep(2000);}

这里就是通过代码在输入框里输入你好,然后点击百度一下的按钮,实现的一个自动化操作过程;

这里需要注意的是click 和 submit 的区别:

  1. 如果点击的元素放在form标签中,此时使用submit实现的效果和click是一样的;
  2. 如果点击的元素放在form标签外,此时使用submit就会摆错;

✅3.3 添加等待

1)sleep休眠

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

2)隐式等待

通过添加driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS)的方法去添加隐式等待,通过隐式等待,WebDriver在试图查找_任何_元素时在一定时间内轮询DOM。当网页上的某些元素不是立即可用并且需要一些时间来加载时是很有用的,这块比较抽象,可以参考一下官方文档:

等待 | Seleniumhttps://www.selenium.dev/zh-cn/documentation/webdriver/waits/


✅3.4 打印信息

不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。 我们通常可以通过获取title 、URL和text等信息进行断言。text方法在前面已经讲过,它用于获取标签对之间的文本信息。

  • getTitle(): 用于获得当前页面的title。
  • getCurrentUrl() : 用户获得当前页面的URL。
  • getText() 获取页面文本信息。

这里我们打印url和title来展示一下:

private static void test3() {// 谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);// 启动需要打开的网页webDriver.get("https://www.baidu.com/");// 获取当前页面的urlString url = webDriver.getCurrentUrl();// 获取当前页面的titleString title = webDriver.getTitle();// 通过对比,来判断是否相同if(url.equals("https://www.baidu.com/") && title.equals("百度一下,你就知道")){System.out.println("测试通过");}else {System.out.println("测试未通过");}}

当然这里不止这两个方法,还有别的方法可以获取到别的属性,可以去官方文档自行查看;


✅3.5 浏览器操作

在使用浏览器浏览网页时,浏览器提供了后退和前进按钮,可以方便地在浏览过的网页之间切换,WebDriver也提供了对应的back()和forward()方法来模拟后退和前进按钮。下面通过例子来演示这两个方法的使用。

  • back() 模拟浏览器后退按钮
  • forward() 模拟浏览器前进按钮
  • refresh() 刷新页面(F5)
private static void test4() throws InterruptedException {//创建谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);// 打开百度首页webDriver.get("https://www.baidu.com/");// 搜索520webDriver.findElement(By.cssSelector("#kw")).sendKeys("你好");// 点击webDriver.findElement(By.cssSelector("#su")).click();// 浏览器后退sleep(2000);webDriver.navigate().back();// 浏览器刷新sleep(2000);webDriver.navigate().refresh();// 浏览器前进sleep(2000);webDriver.navigate().forward();}

有时候我们希望能以某种浏览器尺寸找开,访问的页面在这种尺寸下运行。例如可以将浏览器设置成移动端大小(480* 800),然后访问移动站点,对其样式进行评估;WebDriver 提供了 manage().window().setSize()方法来设置浏览器的大小。

  • maximize() 设置浏览器最大化
  • setSize() 设置浏览器宽高
private static void test5() throws InterruptedException {//创建谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);// 打开百度首页webDriver.get("https://www.baidu.com/");// 搜索520webDriver.findElement(By.cssSelector("#kw")).sendKeys("你好");sleep(2000);// 点击webDriver.findElement(By.cssSelector("#su")).click();sleep(2000);// 浏览器显示最大化webDriver.manage().window().maximize();sleep(2000);// 浏览器全屏webDriver.manage().window().fullscreen();sleep(2000);// 按照指定大小来显示webDriver.manage().window().setSize(new Dimension(600,800));}


 ✅3.6 键盘操作

Keys()类提供了键盘上几乎所有按键的方法。 前面了解到, sendKeys()方法可以用来模拟键盘输入, 除此之 外, 我们还可以用它来输入键盘上的按键, 甚至是组合键, 如 Ctrl+A、 Ctrl+C 等;

以下为常用的键盘操作:

sendKeys(Keys.BACK_SPACE) 回格键(BackSpace)

sendKeys(Keys.SPACE) 空格键 (Space)

sendKeys(Keys.TAB) 制表键 (Tab)

sendKeys(Keys.ESCAPE) 回退键(Esc)

sendKeys(Keys.ENTER) 回车键(Enter)

sendKeys(Keys.CONTROL,‘a’) 全选(Ctrl+A)

sendKeys(Keys.CONTROL,‘c’) 复制(Ctrl+C)

sendKeys(Keys.CONTROL,‘x’) 剪切(Ctrl+X)

sendKeys(Keys.CONTROL,‘v’) 粘贴(Ctrl+V)

private static void test6() throws InterruptedException {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("https://www.baidu.com");// 搜索520webDriver.findElement(By.cssSelector("#kw")).sendKeys("你好");// 测试Ctrl+Asleep(2000);webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "A");// 测试Ctrl+Xsleep(2000);webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "X");// 测试Ctrl+Vsleep(2000);webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "V");// 点击sleep(2000);webDriver.findElement(By.cssSelector("#su")).click();}


✅3.7 鼠标操作

通过前面例子了解到,可以使用click()来模拟鼠标的单击操作,现在的Web产品中提供了更丰富的鼠标交互方式, 例如鼠标右击、双击、悬停、甚至是鼠标拖动等功能。在WebDriver中,将这些关于鼠标操作的方法封装在ActionChains类提供。 Actions 类提供了鼠标操作的常用方法:

  • contextClick() 右击
  • clickAndHold() 鼠标点击并控制
  • doubleClick() 双击
  • dragAndDrop() 拖动
  • release() 释放鼠标
  • perform() 执行所有Actions中存储的行为
private static void test7() throws InterruptedException {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("https://www.baidu.com/");// 搜索框输入520webDriver.findElement(By.cssSelector("#kw")).sendKeys("520");// 点击百度一下按钮webDriver.findElement(By.cssSelector("#su")).click();sleep(2000);//找到测试鼠标右键点击"网页"WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > b"));// 鼠标右击Actions actions = new Actions(webDriver);sleep(2000);actions.moveToElement(webElement).contextClick().perform();}


✅3.8 定位一组元素

webdriver 可以很方便的使用findElement 方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,这时候就需要使用findElements 方法;定位一组对象一般用于以下场景:

  • 批量操作对象,比如将页面上所有的checkbox 都勾上
  • 先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的checkbox,然后选择最后一个

以下是个简单页面:

<!DOCTYPE html>
<html lang="zh-cn">
<head><meta charset="UTF-8">
</head>
<body>
<fieldset><legend>单选按钮radio</legend><form action=""><label for=""><input type="radio" name="fruit" value="pg" id="pg">苹果</label><label for=""><input type="radio" name="fruit" value="jz" id="jz">橘子</label><label for=""><input type="radio" name="fruit" value="xj" id="xj">香蕉</label><label for=""><input type="radio" name="fruit" value="li" id="li" checked="">梨</label><label for=""><input type="radio" name="fruit" value="xg" id="xg" disabled="" >西瓜</label></form>
</fieldset>
<br>
<fieldset><legend>多选按钮checkbox</legend><form action=""><input type="checkbox" name="checkbox" value="汽车" id="qc">汽车<br><input type="checkbox" name="checkbox" value="购物" id="gw">购物<br><input type="checkbox" name="checkbox" value="旅游" id="ly" readonly="">旅游 <br><input type="checkbox" name="checkbox" value="音乐" id="yy" disabled="">音乐 <br></form>
</fieldset>
</body>
</html>
private static void test8() {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("http://127.0.0.1:8080/aaa/test.html");//定位input标签,并将其扔到List集合中List<WebElement> webElements =  webDriver.findElements(By.cssSelector("input"));// 如果元素的type值等于checkbox就进行点击for (int i = 0; i < webElements.size(); i++) {// getAttribute是获取当前页面元素的属性值,type是当前元素的属性if(webElements.get(i).getAttribute("type").equals("checkbox")){webElements.get(i).click();}else {;}}}

通过动态图可以发现,这样就实现了一个 多选的操作;


✅3.9 下拉框处理

下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需要进行两次定位,先定位到下拉框对下拉框进行操作后,再定位到下拉框内里的选项;

 private static void test9() {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("http://127.0.0.1:8080/aaa/test2.html");WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select = new Select(webElement);// 下标是从0开始计数的select.selectByIndex(2);}


✅3.10 切换窗口句柄

在页面操作过程中有时候点击某个链接会弹出新的窗口, 这时就需要主机切换到新打开的窗口上进行操作。WebDriver提供了switchTo().window()方法可以实现在不同的窗口之间切换。 以百度首页和百度注册页为例,在两个窗口之间的切换。

private static void test10() {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("https://www.baidu.com/");// 点击百度页面的新闻按钮webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();// getWindowHandles获取所以得窗口句柄// getWindowHandles获取当前页面的窗口句柄
//        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);webDriver.findElement(By.cssSelector("#ww")).sendKeys("你好");webDriver.findElement(By.cssSelector("#s_btn_wr")).click();}

这是一个在第二个页面的输入框内搜索内容,如果不调用webDriver.getWindowHandle()方法的话,代码就会报错;

自动化测试中经常有点击一个链接,打开新的窗口。人为操作的话,可以通过眼睛看,识别不同的窗口点击切换。但是是自动化脚本没长眼睛,它不知道你要操作哪个窗口,这时候只能句柄来判断了。

浏览器窗口的属性用句柄(handle)来识别。窗口句柄是窗口的唯一标识,可看做窗口的身份证号。


✅3.11 截图操作

自动化用例是由程序去执行,因此有时候打印的错误信息并不十分明确。如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因。 WebDriver提供了截图函数getScreenshotAs()来截取当前窗口;

 private static void test11() throws IOException, InterruptedException {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("https://www.baidu.com/");webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#su")).click();sleep(2000);File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);// 放到指定路径下FileUtils.copyFile(file,new File("D://20230527jietu.png"));}

✅3.12 上传文件操作

对于通过input标签实现的上传功能,可以将其看作是一个输入框,即通过sendKeys()指定本地文件路径的方式实现文件上传;

private static void test12() {//谷歌驱动ChromeOptions options = new ChromeOptions();// 允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver = new ChromeDriver(options);webDriver.get("http://127.0.0.1:8080/aaa/bbb.html");// sendKeys里是上传文件的路径webDriver.findElement(By.cssSelector("input")).sendKeys("D:\\Bin\\xnn_res");}

✅面试题:quit 和 close的区别

  • quit 关闭了整个浏览器,close只是关闭了当前的页面;
  • quit会清空缓存,close则不会;

觉得有帮助的小伙伴可以一键三连,蟹蟹~~

相关文章:

Selenium自动化测试(基于Java)

目录 一. 了解Selenium ✅1.1 概念 ✅1.2 作用 ✅1.3 特点 ✅1.4 工作原理 二. Selenium Java 环境搭建 ✅2.1 下载 Chrome 浏览器 ✅2.2 查看浏览器的版本 ✅2.3 下载浏览器驱动 ✅2.4 验证环境是否搭建成功 三. Selenium 常用 API ✅3.1 定位元素 ✅3.2 操作对象…...

【网页布局形式----浮动】

网页布局形式----浮动 css浮动&#xff1a;一、常见的三种网页布局形式&#xff1a;1.1 网页布局两大准则&#xff1a; 二 、浮动&#xff1a;2.1 浮动语法&#xff1a;2.2 浮动特性&#xff08;重难点&#xff09;&#xff1a;浮动元素通常与标准流的父级元素搭配使用&#xf…...

人力资源管理的本质

文章目录 写在前面简述用人方面 写在前面 还没写完呢 这是个人理解&#xff0c;本人理工科出身&#xff0c;喜欢直来直去&#xff0c;理论化的知识&#xff0c;苦于市面上的人力书籍资料都不说人话&#xff0c;遂有此文刚入门&#xff0c;甚至没有系统的学习管理知识&#xf…...

[NOIP2015 提高组] 运输计划

题目链接 给定一棵树以及树上的 m m m 条通路&#xff0c;我们可以在树上选取一条边&#xff0c;将其权重置为 0 0 0&#xff0c;目标是 min ⁡ 将某条边权重置 0 max ⁡ 通路权重 . \min_{将某条边权重置 0}\max 通路权重. 将某条边权重置0min​max通路权重. 20pts(m1) 当…...

【GreendDao 】RxQuery根据指定条件查询,完成后处理UI逻辑

GreenDao 和 RxJava 结合使用可以更方便地处理数据查询和 UI 逻辑的交互。RxQuery 使得一次查询结果可以直接转化成 Observable&#xff0c;而通过 RxJava 的操作符&#xff0c;可以方便地完成异步查询和 UI 逻辑的交互。以下是一个根据指定条件查询数据&#xff0c;查询完成后…...

【C++】unordered_set 和 unordered_map 使用 | 封装

文章目录 1. 使用1. unordered_set的使用2. unordered_map的使用 2. 封装修改结构定义针对insert参数 data的两种情况复用 哈希桶的insertKeyOfT模板参数的作用 迭代器operator()beginendunordered_set对于 begin和end的复用unordered_map对于 begin和end的复用unordered_map中…...

C++环形缓冲区设计与实现:从原理到应用的全方位解析

C环形缓冲区设计与实现&#xff1a;从原理到应用的全方位解析 一、环形缓冲区基础理论解析&#xff08;Basic Theory of Circular Buffer&#xff09;1.1 环形缓冲区的定义与作用&#xff08;Definition and Function of Circular Buffer&#xff09;1.2 环形缓冲区的基本原理&…...

阿里云服务器部署flask简单方法

记录如何在阿里云服务器上部署flask接口并实现公网访问。 文章目录 1. 简介2. 部署python3环境3. 生成requirement.txt4. 将项目打包上传5. 安装依赖库6. 查看防火墙7. 测试能否公网访问 1. 简介 因落地通话callback服务测试&#xff0c;需要我写一个测试demo&#xff0c;用于…...

【JavaSE】Java基础语法(二十三):递归与数组的高级操作

文章目录 1. 递归1.1 递归1.2 递归求阶乘 2. 数组的高级操作2.1 二分查找2.2 冒泡排序2.3 快速排序2.4 Arrays (应用) 1. 递归 1.1 递归 递归的介绍 以编程的角度来看&#xff0c;递归指的是方法定义中调用方法本身的现象把一个复杂的问题层层转化为一个与原问题相似的规模较…...

HUSTOJ使用指南

如何快速上手&#xff08;了解系统的功能&#xff09;&#xff1f; admin管理员用户登录&#xff0c;点击右上角管理&#xff0c;仔细阅读管理首页的说明。 切记&#xff1a;题目导入后一次只能删一题&#xff0c;不要导入过多你暂时用不上的题目&#xff0c;正确的方式是每次…...

java基础学习

一、注释 1&#xff09;当行注释 // 2&#xff09;多行注释 /* ... */ 3&#xff09;文档注释 &#xff08;java特有&#xff09; /** author 张三 version v1.0 这是文档注释&#xff0c;需要将class用public修饰 */ 二、关键字 &#xff08;1&#xff09;48个关键…...

Linux——进程优先级

1.什么是优先级&#xff1f; 优先级和权限息息相关。权限的含义为能还是不能做这件事。而优先级则表示&#xff1a;你有权限去做&#xff0c;只不过是先去做还是后去做这件事罢了。 2.为什么会存在优先级&#xff1f; 优先级表明了狼多肉少的理念&#xff0c;举个例子&#xff…...

音频设备初始化与输出:QT与SDL策略模式的实现

音频设备初始化与输出&#xff1a;QT与SDL策略模式的实现 一、引言&#xff08;Introduction&#xff09;1.1 音频设备初始化与输出的重要性1.2 QT与SDL的音频设备处理1.3 策略模式在音频设备处理中的应用 二、深入理解音频设备初始化与输出2.1 音频设备的基本概念2.2 音频设备…...

Linux 手动部署 SpringBoot 项目

Linux 手动部署 SpringBoot 项目 1. 将项目打包成 jar 包 &#xff08;1&#xff09;引入插件 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></pl…...

华为OD机试真题B卷 Java 实现【内存资源分配】

一、题目描述 有一个简易内存池,内存按照大小粒度分类,每个粒度有若干个可用内存资源,用户会进行一系列内存申请,需要按需分配内存池中的资源,返回申请结果成功失败列表。 分配规则如下: 分配的内存要大于等于内存的申请量,存在满足需求的内存就必须分配,优先分配粒度…...

深入理解ChatGPT插件:competitorppcads、seoanalysis和kraftful

1. 引言 插件&#xff0c;作为一种扩展功能的工具&#xff0c;为我们的应用程序提供了无限的可能性。在ChatGPT中&#xff0c;我们有许多强大的插件&#xff0c;如competitorppcads、seoanalysis和kraftful。这篇博客将详细介绍这三个插件的功能和使用方法。 2. competitorpp…...

通过源码编译安装LAMP平台的搭建

目录 1. 编译安装Apache httpd服务2 编写mysqld服务3 编译安装PHP 解析环境安装论坛 LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c;能够提供动态Web站点服务及其应用开发环境。 LAMP是一个缩写词&#xff0c;具体包…...

mac os 安装rz/sz

说明&#xff1a;使用rz sz实现终端的文件传输&#xff0c;该命令主要使用场景为 macos中通过堡垒机登陆后无法使用ftp工具传输文件。 工具&#xff1a;iTerm2、lrzsz、homebrew 以及两个脚本文件&#xff08;iterm2-recv-zmodem.sh、iterm2-send-zmodem.sh&#xff09; …...

Redis源码(1) 建立监听服务和开启事件循环

Redis 是cs架构(服务端-客户端)&#xff0c;典型的一对多的服务器应用程序。多个客户通过网络与Redis服务器进行通信。那么在linux环境中是使用epoll(我们也 只讨论linux环境的&#xff0c;便于学习)。   通过使用I/O多路复用技术&#xff0c; redis 服务器使用单线程单进程的…...

c++基础概念,const与指针、引用的关系,auto,decltype关键字能干啥总得了解吧。总得按照需求自定义创建实体类,自己编写头文件吧

const限定符 有时我们希望定义这样一种变量&#xff0c;它的值不能被改变。例如&#xff0c;用一个变量来表示缓冲区的大小。使用变量的好处是当我们觉得缓冲区大小不再合适时&#xff0c;很容易对其进行调整。另一方面&#xff0c;也应随时警惕防止程序一不小心改变了这个值。…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...