【软件测试】自动化测试常用函数 -- 详解

news2024/11/15 12:44:41

一、WebDriver API

一个简单自动化脚本的构成:

脚本解析

  • # coding = utf-8
    from selenium import webdriver
    import time
    browser = webdriver.Firefox()
    time.sleep(3)
    browser.get("http://www.baidu.com")
    time.sleep(3)
    browser.find_element_by_id("kw").send_keys("selenium")
    time.sleep(3)
    browser.find_element_by_id("su").click()
    browser.quit()
防止乱码,在编辑器里面可以不用加,因为编辑器默认的就是  UTF-8  模式。
  • coding = utf-8
导入 webdriver 工具包,这样就可以使用里面的  API
  • from selenium import webdriver
获得被控制浏览器的驱动,这里是获得  Firefox  的,当然还可以获得  Chrome  浏览器,不过要想使这一段代码有效,必须安装相应的浏览器驱动。
  • browser = webdriver.Firefox()
通过元素的  ID  定位想要操作的元素,并且向元素输入相应的文本内容 。
  • browser.find_element_by_id("kw").send_keys("selenium")
通过元素的  ID  定位到元素,并进行点击操作。
  • browser.find_element_by_id("su").click()
退出并关闭窗口。
  • browser.quit()

browser.close() 也可以关闭窗口。

两者的区别是:close 方法关闭当前的浏览器窗口,quit 方法不仅关闭窗口,还会彻底的退出 WebDriver,释放与 driver server 之间的连接。所以简单来说 quit 是更加彻底的 closequit 会更好的释放资源。


1、元素的定位

对象的定位应该是自动化测试的核心,要想操作一个对象,首先应该识别这个对象。一个对象就是一个人一样,他会有各种的特征(属性),比如我们可以通过一个人的身份证号,姓名,或者他住在哪个街道、楼层、门牌找到这个人。那么一个对象也有类似的属性,我们可以通过这些属性找到这对象。

注意:不管用那种方式,必须保证页面上该属性的唯一性。

web 自动化测试的操作核心是能够找到页面对应的元素,然后才能对元素进行具体的操作。

WebDriver 提供了一系列的对象定位方法,常用的有以下几种:

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

我们可以看到,一个百度的输入框,可以用这么多种方式去定位。


(1)cssSelector(常用)

CSS(Cascading Style Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的表现。

CSS 使用选择器来为页面元素绑定属性。这些选择器可以被 Selenium 用作另外的定位策略。

CSS 的比较灵活可以选择控件的任意属性,上面的例子中,find_element_by_css_selector("#kw") 通过 find_element_by_css_selector( ) 函数,选择取百度输入框的 id 属性来定义。

CSS 的获取可以用 Chrome 的 F12 开发者模式中 Element-右键-copy-copy selector 来获取。

css 选择语法:

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

选择器的功能:选中页面中指定的标签元素。

选择器的种类分为基础选择器和复合选择器,常见的元素定位方式可以通过 id 选择器和子类选择器来进行定位。

定位百度首页的 “百度热搜” 元素,可以使用通过 id 选择器和子类选择器进行定位:#s-hotsearch-wrapper > div

“搜索输入框元素”:#kw

“百度一下按钮”:#su

若要获取页面多个元素时,可以使用 find_elements:

注意:因为自动化打开的页面是未登录状态,而我们手动打开的百度网页可能是有登录态的,二者页面可能不同,可能造成无法正确打印信息。


A. id 定位

id 是页面元素的属性,我们最常用元素定位方式,但是不是所有的元素都有 id 的。如果一个元素有 id 属性,那么一般在整个页面是唯一的。所以我们一般可以用 id 来唯一的定位到这个元素。

通过前端工具,例如 Edge 浏览器的 F12,找到了百度输入框的属性信息,如下:

<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">

属性 id=”kw” 通过 find_element_by_id("kw") 函数就可以定位到百度输入框。


(2)name 定位

如果这个元素有 name,并且元素的 name 命名在整个页面是唯一的,那么我们可以用 name 来定位这个元素。

用上面百度输入框的例子,其中元素的属性 name=”wd” 通过 find_element_by_name("wd") 函数同样也可以定位到百度输入框。


(3)tag name 定位和 class name 定位

从上面的百度输入框的属性信息中,我们看到,不单单只有 id 和 name 两个属性, 比如 class 和 tag name(标签名)。

input 就是一个标签的名字,可以通过 find_element_by_tag_name("input") 函数来定位,class="s_ipt" 通过 find_element_by_class_name("s_ipt") 函数定位百度输入框。

注意 :不是所有的元素用 tag name  或者 class name 来定位元素,首先要保证该元素的这两种属性在页面上是唯一的,才能够准确的定位。

(4)XPath 定位(重点)(常用)

A. 什么是 XPath

Cover page | xpath | W3C standards and drafts | W3C

XML 路径语言,不仅可以在 XML 文件中查找信息,还可以在 HTML 中选取节点。

xpath 使用路径表达式来选择 xml 文档中的节点。

B. XPath 基础教程

W3Schools Online Web Tutorials


相对路径:/html/head/title(不常用)

绝对路径: 

  • 相对路径+索引://form/span[1]/input
  • 相对路径+属性值://input[@class="s_ipt"]
  • 相对路径+通配符://*[@*="su"]
  • 相对路径+文本匹配://a[text()="新闻"]

XPath 是一种在 XML 文档中定位元素的语言。因为 HTML 可以看做 XML 的一种实现,所以 Selenium 用户可是使用这种强大语言在 Web 应用中定位元素。

XPath 扩展了上面 id 和 name 定位方式,提供了很多种可能性。

XPATH 的获取可以用 Chrome 的 F12 开发者模式中 Element-右键-copy-copy xp。

//*[@id="kw"]

  • 获取 HTML 页面所有的节点://*


  • 获取 HTML 页面指定的节点://[指定节点]
//ul:获取 HTML 页面所有的 ul 节点
//input:获取 HTML 页面所有的 input 节点

  • 获取⼀个节点中的直接子节点:/
//span/input

  • 获取⼀个节点的父节点:..
//input/..:获取 input 节点的父节点

  • 实现节点属性的匹配:[@...]


  • 使用指定索引的方式获取对应的节点内容

注意:xpath 的索引是从 1 开始的。

百度首页通过://div/ul/li[3] 定位到第三个百度热搜标签

更便捷的生成 selector/xpath 的方式:右键选择复制 "Copy selector/xpath"

注意 :元素的定位方法必须唯⼀。

既然可以手动复制 selector/xpath 的方式,为什么还有了解语法?

手动复制的 selector / xpath 表达式并不一定可以满足上面的唯一性的要求,有时候也需要手动的进行修改表达式。


css 选择器和 xpath 选择器哪个更好? 

css 选择器定位元素效率更高。


(5)link text 定位

有时候不是一个输入框也不是一个按钮,而是一个文字链接,我们可以通过链接内容,也就是 link text 来定位。

注意:链接内容必须这个页面唯一,否则会报错。


(6)Partial link text 定位

通过部分链接定位,这个有时候也会用到,我还没有想到很好的用处。拿上面的例子,我可以只用链接的一部分文字进行匹配:


二、操作测试对象

前面讲到了不少知识都是定位元素,定位只是第一步,定位之后需要对这个元素进行操作。是鼠标点击还是键盘输入,或者清除元素的内容,或者提交表单等。这个取决于定位元素需要进行的下一步操作。

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

  • click 点击对象。
  • send_keys 在对象上模拟按键输入
  • clear 清除对象输入的文本内容。
  • submit 提交。
  • text 用于获取元素的文本信息
  • get_attribute 获得属性值。

1、click 点击 / 提交对象

click() # 用于点击一个按钮

页面上任意元素都可以进行点击操作。


2、sendKeys 模拟按键输入

键盘上可以输入的内容都能填入。

sendKeys("")
# send_keys("xx") 用于在一个输入框里输入 xx 内容


3、clear 清除文本内容

输入文本后又想换一个新的关键词,这里就需要用到 clear()。

clear() 用于清除输入框的内容,比如百度输入框里默认有个 请输入关键字” 的信息,再比如我们的登陆框一般默认会有 “账号”、“密码” 这样的默认信息。clear 可以帮助我们清除这些信息。

连续的 sendKeys 会将多次输入的内容拼接在一起,如果想要重新输入,需要使用清除方法:


4、submit 提交表单

打开百度搜索页面,按钮 百度一下” 元素的类型 type=“submit”,所以把百度一下的操作从 click 换成 submit 可以达到相同的效果:

driver.find_element_by_id("su").submit()
  • 如果点击的元素放在 form 标签中,此时使用 submit 实现的效果和 click 是一样的。
  • 如果点击的元素放在非 form 标签中,此时使用 submit 报错。

5、text 获取元素文本

如何判断获取到的元素对应的文本是否符合预期呢?

获取元素对应的⽂本并打印⼀下。

getText()

“百度一下” 在这里是作为元素属性值,而不是文本信息。

不应该是获取文本信息,而是获取属性值:

注意 :文本和属性值不要混淆了,获取属性值需要使用方法: getAttribute(" 属性名称 ")。

6、title 获取当前页面标题 & current_url 获取当前页面 URL

getTitle()
​
getCurrentUrl()

适用场景:页面元素可点击跳转的情况下,用来检测跳转的结果是否为正确的。


三、等待(重点)

通常代码执行的速度比页面渲染的速度要快,如果避免因为渲染过慢出现的自动化误报的问题呢?

可以使用 selenium 中提供的三种等待方法。


1、强制等待

添加休眠非常简单,我们需要引入 time 包,就可以在脚本中自由的添加休眠时间了,这里的休眠指固定休眠。
import time
time.sleep() # 单位:秒
# 当调用该方法时,程序会直接阻塞,等待指定秒数后继续执行后面的代码

  • 优点:使用简单,调试的时候比较有效。
  • 缺点:影响运行效率,浪费大量的时间。 

2、隐式等待

隐式等待是⼀种智能等待,它可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执行,直到超时没找到元素才会报错。

通过添加 implicitly_wait() 方法就可以方便的实现智能等待。implicitly_wait(30) 的用法比 time.sleep() 更智能,后者只能选择一个固定的时间的等待,而前者可以在一个时间范围内智能的等待。

隐式等待的生命周期:隐式等待作用域整个脚本的所有元素。即只要 driver 对象没有被释放掉(driver.quit()),隐式等待就一直生效。

  • 优点:智能等待,作用于全局

隐式地等待并非一个固定的等待时间,当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它以轮询的方式不断的判断元素是否被定位到。直到超出设置的时长。若等待指定秒数后还是查找不到元素,则报错。

隐式等待扫描的是整个页面的元素,页面中所有的元素都被加载到之后才去执行后续的代码。


3、显示等待

显示等待也是一种智能等待在指定超时时间范围内只要满足操作的条件就会继续执行后续代码

# new WebDriverWait(driver, Duration.ofSeconds(3)).until($express)
# $press:涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类
# 返回值:boolean

# 示例:
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 2)
wait.until(EC.invisibility_of_element((By.XPATH, '//*[@id="2"]/div/div/div[3]/div[1]/div[1]/div')))

ExpectedConditions 预定义方法的一些示例:

  • title_is(title):检查页面标题的期望值。
  • title_contains(title):检查标题是否包含区分大小写的子字符串的期望值。
  • visibility_of_element(locator)用于检查元素的期望是可见的并已启用,以便我们可以单击它。
  • invisibility_of_element(locator):用于检查元素的不可见性。
  • visibility_of_element_located(locator, str]):用于检查元素是否存在于页面的 DOM 上的期望值。
  • visibility_of(element):检查已知存在于页面 DOM 上的元素是否可见的期望。
  • alert_present():检查是否出现弹窗。(可以等待隐式等待(无法等待弹窗,因为弹窗不是页面的元素,无法通过页面元素来定位到弹窗)无法处理的问题)
  1. 优点:显示等待是智能等待,可以自定义显示等待的条件,操作灵活。
  2. 缺点:写法复杂。

显示等待相较于隐式等待的好处:

隐式等待和显示等待一起使用效果如何呢?

不建议这么做。混合隐式和显示等待可能会导致不可预测的等待时间。

但是强制等待可以任意配合隐式等待或显示等待来使用。

重复多次,设置 10 秒的隐式等待和 15 秒的显示等待导致 20 秒后发生超时:


四、窗口

打开一个新的页面之后获取到的 title 和 URL 仍然还是前一个页面的。当我们手工测试的时候,我们可以通过眼睛来判断当前的窗口是什么,但对于程序来说它是不知道当前最新的窗口应该是哪一个的。

对于程序来说,它如何来识别每一个窗口呢?

每个浏览器窗口都有一个唯一的属性句柄(handle)来表示,我们就可以通过句柄来切换。


1、切换窗口

  • 获取当前页面句柄:driver.current_window_handle
  • 获取所有页面句柄:driver.windowhandles

  • 通常情况下会打开两个标签页来实现标签页的切换测试,多个标签页切换到某一个标签页的场景在测试中不常见。
  • 更多时候是输入对应页面的链接在当前标签页下进行测试。


2、窗口设置大小

仅作了解即可,在自动化脚本执行过程中通常测试人员不关注页面的变化。


3、屏幕切换

我们的自动化脚本⼀般部署在机器上自动的去运行,当自动化运行出现了报错,仅仅通过终端的错误提示给到的有用信息是一定的,若能将当时的页面变化截图抓拍下来,记录当时的错误场景,能更好的定位问题并解决问题。

指定图片存储路径(需要提前创建好):

如果多次运行,由于图片给定的名称是固定的,那么历史的图片会被覆盖。

如何让我们每次生成的图片都是唯一的呢,如何将我们的历史图片都保存下来?

需要让我们每次生成的图片对应的名称都不一样,最好通过保存当前图片的时间来作为其名称。


4、关闭窗口

driver.close(); # 退出一个窗口

driver.quit(); # 退出浏览器

注意:窗口关闭后 driver 要重新定义。


五、弹窗

弹窗是在页面是找不到任何元素的,这种情况怎么处理?
使用 Selenium 提供的 alert 接口。

1、警告弹窗 + 确认弹窗

(1)警告弹窗

 出现了弹窗,页面其他元素也无法定位:

页面出现了弹窗,必须先处理弹窗之后才能定位到页面的元素。

  1. 切换到弹窗。
  2. 关闭弹窗(点击确认 / 取消)
Alert alert = driver.switchTo.alert();
# 确认
alert.accept()
# 取消
alert.dismiss()

# 注意:switch_to.alert() 只能处理原生的 alert


(2)确认弹窗

 

  • 确定:

  • 取消:


2、提示弹窗

Alert alert = driver.switchTo.alert();
alert.sendKeys("xxxx");
alert.accept();
alert.dismiss();
  • 输入文本 + 确定:

肉眼看不到在弹窗上输入的文本信息:

  • 输入文本 + 取消:


六、浏览器的操作

1、浏览器最大化

我们知道调用启动的浏览器不是全屏的,这样不会影响脚本的执行,但是有时候会影响我们 观看” 脚本的执行。

browser.maximize_window()

2、设置浏览器宽、高

最大化还是不够灵活,能不能随意的设置浏览的宽、高显示?
当然是可以的。
browser.set_window_size(width, high)

3、浏览器导航

(1)打开网站

// 更⻓的⽅法
driver.navigate().to("https://selenium.dev");

// 简洁的⽅法
driver.get("https://selenium.dev");

(2)浏览器的前进、后退、刷新 

非页面元素,所以需要 selenium 提供的现成的方法:

driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();


4、控制浏览器滚动条(重点)

浏览器滚动条的控制需要依靠 js 脚本。


5、浏览器参数设置

(1)设置无头模式

程序在后端运行,界面看不到页面的表现。

自动化打开浏览器默认情况下为有头模式。


(2)设置浏览器加载策略

  options.page_load_strategy = '加载方式';  

 

driver.get 默认情况下等待所有的资源加载完成之后才能继续往下执行,但是实际上主页面加载完成之后就可以继续执行自动化。若一直等待的话可能会造成页面超时、元素找不到等问题。

页面加载方式主要有三种类型:

  1. normal:默认值,等待所有资源下载完成(主体框架、图片、视频等资源)
  2. eager:DOM 访问已准备就绪,但诸如图像的其它资源可能仍在加载(推荐)
  3. none:完全不会阻塞 WebDriver,直接继续往下执行脚本(不推荐)


七、上传文件操作

点击文件上传的场景下会弹窗系统窗口,进行文件的选择。

Selenium 无法识别非 Web 的控件,上传文件窗口为系统自带,无法识别窗口元素。但是可以使用 Sendkeys 来上传指定路径的文件,达到的效果是一样的。

文件上传操作也是比较常见功能之一,上传功能没有用到新有方法或函数,关键是思路。

上传过程一般要打开一个本地窗口,从窗口选择本地文件添加。所以,一般会卡在如何操作本地窗口添加上传文件。

当通过页面元素调起上传的窗口后,文件窗口不能被作为页面元素被选中,此时要解决的问题是:如何定位到弹窗并选中文件呢?

只要定位上传按钮,通过 send_keys() 添加本地文件路径就可以了,可以实现将本地文件夹中的文件上传上来。完整绝对路径和相对路径都可以(注意需要添加转义字符),关键是上传的文件存在。


八、键盘事件

1、键盘按键用法

要使用键盘按键,必须引入  keys 包:
  • from selenium.webdriver.common.keys import Keys
通过  send_keys()  调用按键:
  • send_keys(Keys.TAB) # TAB
  • send_keys(Keys.ENTER) # 回车
  • send_keys(Keys.SPACE) #空格键
  • send_keys(Keys.ESCAPE) #回退键(Esc
  • .....

2、键盘组合键用法

  • send_keys(Keys.CONTROL,'a') #全选(Ctrl+A
  • send_keys(Keys.CONTROL,'c') #复制(Ctrl+C
  • send_keys(Keys.CONTROL,'x') #剪贴(Ctrl+X
  • send_keys(Keys.CONTROL,'v') #粘贴(Ctrl+V

九、鼠标事件

要使用鼠标事件需要导入工具包:
  • from selenium.webdriver.common.action_chains import ActionChains

语法示例如下:

#鼠标拖动事件
ActionChains(driver).move_to_element(element).perform()

ActionChains(driver) 生成用户的行为。所有的行动都存储在actionchains 对象。通过perform()存储的行为。

move_to_element(element) 移动鼠标到一个元素中,menu 上面已经定义了他所指向的哪一个元素。

perform() 执行所有存储的行为。

ActionChains
  • context_click() 右击
  • double_click() 双击
  • drag_and_drop() 拖动
  • move_to_element() 移动

十、定位一组元素

WebDriver 可以很方便的使用 findElement 方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,这时候就需要使用 findElements 方法。

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

十一、多层框架 / 窗口定位

对于一个  web 应用,经常会出现框架( frame ) 或窗口( window )的应用,这也就给我们的定位带来了一定的困难。
  • 定位一个 frame switch_to.frame(name_or_id_or_frame_element)
  • 定位一个窗口 windowswitch_to.window(name_or_id_or_frame_element)

1、多层框架的定位

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

switch_to.default_content:从 frame 中嵌入的页面里跳出,跳回到最外面的默认页面中。


2、多层窗口定位

有可能嵌套的不是框架,而是窗口,还有真对窗口的方法:switch_to.window 用法与 switch_to.frame 相同:driver.switch_to.window("windowName")

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

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

相关文章

Photoshop

彩色转灰度&#xff1a;ctrlshiftu 背景转黑色&#xff1a; 魔术棒容差10 shift连选 shiftF5&#xff08;填充&#xff09;钢笔选择 路径 工作路径 将路径作为选区载入 点回图层 按ctrlx删除选区 待更新

[C++]——同步异步日志系统(5)

同步异步日志系统 一、日志消息格式化设计1.1 格式化子项类的定义和实现1.2 格式化类的定义和实现 二、日志落地类设计2.1 日志落地模块功能实现与测试2.2 日志落地模块功能功能扩展 一、日志消息格式化设计 日志格式化模块的作用&#xff1a;对日志消息进行格式化&#xff0c…

Windows 子系统WSL2 Ubuntu使用事项

Windows 子系统WSL2 Ubuntu使用事项 要使外部设备能够访问运行在 Windows 上的 WSL2 实例&#xff0c;你可以端口转发的方法。由于 WSL2 是在虚拟化环境中运行&#xff0c;直接访问比 WSL1 更为复杂. 1 如何实现子系统可以被外部系统SSH 1.1 端口转发: 通过windows代理WSL2的…

微信视频号的视频怎么下载到本地?快速教你下载视频号视频

天来说说市面上常见的微信视频号视频下载工具&#xff0c;教大家快速下载视频号视频&#xff01; 方法一&#xff1a;缓存方法 该方法来源早期视频技术&#xff0c;因早期无法将大量视频通过网络存储&#xff0c;故而会有缓存视频文件到手机&#xff0c;其目的为了提高用户体验…

stm32入门-----初识stm32

目录 前言 ARM stm32 1.stm32家族 2.stm32的外设资源 3.命名规则 4.系统结构 5.引脚定义 6.启动配置 7.STM32F103C8T6芯片 8.STM32F103C8T6芯片原理图与最小系统电路 前言 已经很久没跟新了&#xff0c;上次发文的时候是好几个月之前了&#xff0c;现在我是想去学习st…

C++继承和多态

目录 继承 继承的意义 访问限定符、继承方式 赋值兼容规则&#xff08;切片&#xff09; 子类的默认成员函数 多继承 继承is a和组合has a 多态 什么是多态 形成多态的条件 函数重载&#xff0c;隐藏&#xff0c;重写的区别 override和final 多态原理 继承 继承的…

FinalShell介绍,安装与应用

目录 一、什么是finalshell 二、finalshell功能 三、为什么要用finalshell 四、安装finalshell 五、finalshell使用 1.添加连接 获取虚拟ip地址 2.启动连接 一、什么是finalshell FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工…

在RHEL9.4上启用SFTP服务

FTP存在的不足&#xff1a; 明文传输 FTP传输的数据&#xff08;包括用户名、密码和文件内容&#xff09;都是明文的&#xff0c;这意味着数据可以被网络上的任何人截获并读取。没有内置的加密机制&#xff0c;容易受到中间人攻击。 被动模式下的端口问题 FTP的被动模式需要…

server nat表和会话表的作用及NAT地址转换详细

本章节主要讲nat技术的基础 -会话表的建立也是看5元组 -状态检测技术的回包一样也看5元组&#xff0c;但是状态检测技术会看的除开5元组还有更多东西 老哥&#xff0c;你真的应该好好注意一个东西&#xff1a;我们的会话表只是为了后续包的转发&#xff0c;会话表是记录的首…

C++:哈希表

哈希表概念 哈希表可以简单理解为&#xff1a;把数据转化为数组的下标&#xff0c;然后用数组的下标对应的值来表示这个数据。如果我们想要搜索这个数据&#xff0c;直接计算出这个数据的下标&#xff0c;然后就可以直接访问数组对应的位置&#xff0c;所以可以用O(1)的复杂度…

澳门建筑插画:成都亚恒丰创教育科技有限公司

澳门建筑插画&#xff1a;绘就东方之珠的斑斓画卷 在浩瀚的中华大地上&#xff0c;澳门以其独特的地理位置和丰富的历史文化&#xff0c;如同一颗璀璨的明珠镶嵌在南国海疆。这座城市&#xff0c;不仅是东西方文化交融的典范&#xff0c;更是建筑艺术的宝库。当画笔轻触纸面&a…

能源园区可视化管理系统

利用图扑 HT 可视化打造能源园区管理系统&#xff0c;实时监控和优化能源分配&#xff0c;提升园区运行效率&#xff0c;增强安全管理&#xff0c;推动绿色和可持续发展。

信立方大模型 | 以AI之钥,开拓智能守护新疆界

在当前网络安全形势日益复杂的背景下&#xff0c;技术的进步不仅带来了便利&#xff0c;也使得网络攻击手段更加多样化和隐蔽化。据悉&#xff0c;国外某研究团队已成功利用GPT技术开发出一种黑客智能体框架&#xff0c;该框架能够深入研读CVE&#xff08;通用漏洞披露&#xf…

MATLAB激光通信和-积消息传递算法(Python图形模型算法)模拟调制

&#x1f3af;要点 &#x1f3af;概率论和图论数学形式和图结构 | &#x1f3af;数学形式、图结构和代码验证贝叶斯分类器算法&#xff1a;&#x1f58a;多类型&#xff1a;朴素贝叶斯&#xff0c;求和朴素贝叶斯、高斯朴素贝叶斯、树增强贝叶斯、贝叶斯网络增强贝叶斯和半朴素…

Android12 MultiMedia框架之GenericSource extractor

前面两节学习到了各种Source的创建和extractor service的启动&#xff0c;本节将以本地播放为例记录下GenericSource是如何创建一个extractor的。extractor是在PrepareAsync()方法中被创建出来的&#xff0c;为了不过多赘述&#xff0c;我们直接从GenericSource的onPrepareAsyn…

LeetCode刷题笔记第3011题:判断一个数组是否可以变为有序

LeetCode刷题笔记第3011题&#xff1a;判断一个数组是否可以变为有序 题目&#xff1a; 想法&#xff1a; 使用冒泡排序进行排序&#xff0c;在判断大小条件时加入判断二进制下数位为1的数目是否相同&#xff0c;相同则可以进行互换。最后遍历数组&#xff0c;相邻两两之间是…

17集 如何用ESP-IDF编译ESP-DL深度学习工程-《MCU嵌入式AI开发笔记》

17集 如何用ESP-IDF编译ESP-DL深度学习工程-《MCU嵌入式AI开发笔记》 参考文档&#xff1a;ESP-DL 用户指南&#xff1a; https://docs.espressif.com/projects/esp-dl/zh_CN/latest/esp32/index.html 和https://docs.espressif.com/projects/esp-dl/zh_CN/latest/esp32/get-s…

Qt Mqtt客户端 + Emqx

环境 Qt 5.14.2 qtmqtt mqttx 功能 QT Mqtt客户端 qtmqtt 下载 qtmqtt (注意下载与QT版本相符的库)并使用QT 编译 编译完成后需要的文件: emqx 1.虚拟机中安装emqx,并启动 curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash sudo apt-get inst…

Java实现数据结构——双链表

目录 一、前言 二、实现 2.1 类的创建 三、对链表操作实现 3.1 打印链表 3.2 插入数据 3.2.1 申请新节点 3.2.2 头插 ​编辑 3.2.3 尾插 3.2.4 链表长度 3.2.5 任意位置插入 3.3 删除数据 3.3.1 头删 3.3.2 尾删 3.3.3 删除指定位置数据 3.3.4 删除指定数据 3…

王道计算机考研数据结构思维导图笔记(持续更新)

第1章 绪论 1.1 数据结构的基本概念 1.1.1 基本概念和术语 1.1.1 数据结构三要素 1.2 算法和算法评价 1.2.1算法的基本概念 1.2.2 算法效率的度量 第2章 线性表 2.1 线性表的定义和基本操作 2.1.1 线性表的定义 2.1.2 线性表的基本操作 2.2.1 顺序表上的定义 2.2.2 顺序…