移动端UI自动化测试框架Maestro:YAML驱动,跨平台高效测试实践

news2026/4/27 13:11:11
1. 项目概述一个面向移动端UI测试的自动化框架如果你是一名移动端开发者或测试工程师那么对UI自动化测试的繁琐和脆弱性一定深有体会。传统的基于坐标或图像识别的方案在设备分辨率、系统版本、甚至UI组件微小的样式变动面前常常显得不堪一击维护成本高得吓人。而“RunMaestro/Maestro”这个项目正是为了解决这一痛点而生的。它是一个由YAML驱动的移动端UI自动化测试框架其核心设计理念是“稳定、简单、快速”。简单来说Maestro让你能用一种近乎自然语言的方式描述你的测试流程然后它就能在各种iOS和Android设备包括模拟器和真机上稳定地执行这些操作完成从简单的点击、滑动到复杂的断言和流程组合。我第一次接触Maestro是在一个大型跨平台电商App的测试项目中。当时我们被频繁的UI变更和复杂的用户路径回归测试搞得焦头烂额每次发版前的手动回归都是一场噩梦。引入Maestro后我们团队最直观的感受是编写测试用例像写配置一样简单而执行速度却比我们之前用的框架快了一个数量级。它不依赖于特定的测试代码结构而是直接与App的UI层交互这种“黑盒”式的设计反而带来了意想不到的稳定性和可维护性。无论你是想为个人项目快速搭建自动化测试还是在团队中推行高效的CI/CD流水线Maestro都提供了一个极具吸引力的选择。接下来我将从设计思路、核心实操到深度优化为你完整拆解这个框架。2. Maestro的核心设计哲学与架构解析2.1 为什么是YAML声明式测试的胜利Maestro最引人注目的特点就是完全使用YAML文件来定义测试流程。这背后是一种“声明式”编程思想在测试领域的应用。与传统的“命令式”测试脚本你需要一步步告诉框架“先找到这个元素然后点击它再检查那个文本”不同声明式测试只关心“最终状态”和“用户意图”。举个例子一个登录测试在Maestro的YAML里你可能只需要这样写appId: com.example.myapp --- - launchApp - tapOn: “登录” - inputText: “testexample.com” - tapOn: “密码” - inputText: “password123” - tapOn: “登录按钮” - assertVisible: “欢迎回来用户”你看这里没有findElementById没有WebDriverWait也没有复杂的XPath或CSS选择器。Maestro替你处理了所有底层的定位、等待和交互逻辑。它的设计者认为测试工程师应该更专注于描述“用户故事”和“业务逻辑”而不是与底层API和瞬息万变的UI结构搏斗。YAML的简洁性和可读性完美契合了这一目标使得非开发背景的QA人员也能快速上手编写和维护测试用例。这种设计的优势在长期维护中体现得淋漓尽致。当UI布局改变时你通常只需要更新YAML中的文本内容或ID而不需要重构复杂的脚本逻辑。同时YAML文件易于版本控制便于在团队中协作和复用。2.2 底层引擎与平台无关的交互抽象Maestro的稳定性并非魔法而是源于其精心设计的底层架构。它并没有重复造轮子而是作为一层高级抽象整合了各平台最成熟的底层驱动。对于AndroidMaestro底层使用的是UiAutomator2。这是Google官方提供的测试框架能提供最稳定、最深入的设备访问能力可以获取到屏幕上几乎所有视图的信息并进行操作。Maestro通过它来执行点击、滑动、输入等操作并获取UI状态进行断言。对于iOSMaestro则依赖于XCUITest。这是苹果官方的UI测试框架与Xcode和iOS系统深度集成同样是iOS平台UI自动化的“黄金标准”。Maestro通过它来驱动iOS模拟器和真机。Maestro的核心价值在于它为你统一了这两个完全不同生态的底层API。你写一份YAMLMaestro会根据你指定的平台通过appId或ios.bundleId/android.appId自动调用对应的底层驱动去执行。这意味着你无需分别学习UiAutomator和XCUITest的复杂API就能同时为两个平台编写自动化测试。此外Maestro还内置了智能等待和重试机制。它会自动等待元素出现后再进行操作并在操作失败时进行有限次数的重试这极大地增强了测试脚本在动态加载页面或网络不稳定情况下的健壮性。注意虽然Maestro抽象了底层但了解一些UiAutomator2和XCUITest的基本概念如无障碍功能树、视图层级对于调试复杂场景下的定位问题仍有很大帮助。当Maestro无法定位某个元素时你可能需要借助Android Studio的Layout Inspector或Xcode的Accessibility Inspector来查看元素的实际属性。3. 从零开始环境搭建与第一个测试流程3.1 一站式环境配置指南开始使用Maestro前你需要准备好相应的环境。整个过程比想象中简单。1. 安装Maestro CLI这是Maestro的命令行工具是所有操作的起点。无论你的开发机是Mac、Windows还是Linux都可以通过包管理器快速安装。macOS (推荐使用Homebrew):brew install maestroLinux / macOS (通用脚本安装):curl -Ls “https://get.maestro.mobile.dev” | bash安装后可能需要将Maestro添加到系统PATH中具体提示会在安装脚本输出中给出。Windows:可以通过PowerShell安装powershell -Command “iwr -useb https://get.maestro.mobile.dev | iex”安装完成后在终端输入maestro --version如果显示版本号如1.30.0则说明安装成功。2. 配置移动端开发环境对于Android测试你需要安装Android SDK并确保adbAndroid Debug Bridge命令可用。最好再安装一个Android模拟器通过Android Studio的AVD Manager或者准备好一台开启了开发者选项和USB调试的安卓真机。对于iOS测试你必须在macOS系统上进行。需要安装Xcode从App Store获取它会附带iOS模拟器。如果使用真机则需要Apple开发者账号并在Xcode中配置好签名证书。3. 准备待测应用Android:你需要应用的APK文件安装路径或者已经在设备上安装好的应用包名appId。iOS:对于模拟器你需要应用的.appbundle路径通常位于Xcode编译输出的DerivedData目录下。对于真机则需要.ipa文件或通过Xcode直接安装。环境就绪后你就可以创建第一个测试了。3.2 编写并执行你的第一个YAML测试流让我们创建一个最简单的测试目标是在一个计算器App中完成一次加法运算。首先创建一个名为calculator_test.yaml的文件。appId: com.android.calculator2 # 这是Android原生计算器的包名iOS模拟器上可能是不同的bundleId --- - launchApp - tapOn: “5” - tapOn: “” - tapOn: “3” - tapOn: “” - assertVisible: “8”这个YAML文件的结构非常清晰appId: 指定要测试的应用程序标识符。---: 分隔符之后是测试步骤的序列。每个步骤以-开头后面跟一个命令如launchApp,tapOn,assertVisible和所需的参数。保存文件后在终端中执行测试。如果你连接了安卓设备或启动了模拟器运行maestro test calculator_test.yamlMaestro会自动启动设备上的计算器应用然后依次点击按钮“5”、“”、“3”、“”最后检查屏幕上是否显示了结果“8”。如果一切顺利你会在终端看到绿色的成功提示并在Maestro自动生成的maestro_report.html中看到详细的执行日志和屏幕录像。实操心得在第一次运行时你可能会遇到appId找不到的问题。对于安卓可以通过adb shell pm list packages命令列出所有已安装应用的包名来确认。对于iOS模拟器可以通过xcrun simctl listapps booted来查看。一个更通用的技巧是先不写appId直接以- launchApp开始Maestro在执行时会提示你当前设备上所有可启动的应用列表你可以从中选择。4. Maestro YAML语法深度解析与实战技巧4.1 核心命令库从基础交互到高级控制Maestro提供了一套丰富的命令足以覆盖绝大多数UI自动化场景。我们可以将其分为几个大类1. 应用与设备控制launchApp: 启动应用。可以配合clearState参数在启动前清除应用数据。stopApp: 停止应用。back: 模拟按下设备的返回键。openLink: 在设备浏览器中打开一个链接可用于测试深度链接。2. UI元素交互tapOn: 点击。这是最常用的命令。定位方式非常灵活- tapOn: “登录” # 通过文本内容点击 - tapOn: “#login_button” # 通过视图ID点击Android的resource-id或iOS的accessibilityIdentifier - tapOn: id: “button_ok” # 显式指定通过ID点击 - tapOn: point: “50%, 30%” # 通过屏幕坐标百分比点击慎用不够稳定scroll: 滚动。可以指定方向up,down,left,right和速度。- scroll - scroll: “200” # 向下滚动200单位设备无关像素 - scroll: direction: UP duration: 500 # 滚动动画持续500毫秒inputText: 输入文本。会自动调出键盘。- tapOn: “用户名输入框” - inputText: “我的用户名” - inputRandomText: “10” # 输入10个随机字符用于压力测试swipe: 滑动。与scroll类似但更适用于卡片切换等操作。longPress: 长按。hideKeyboard: 隐藏软键盘。3. 断言与验证这是确保测试正确性的关键。Maestro的断言命令会在条件不满足时自动重试一段时间这符合移动端应用状态异步变化的特性。assertVisible: 断言某个元素通过文本或ID在屏幕上可见。- assertVisible: “订单提交成功” - assertVisible: “#success_badge”assertNotVisible: 断言某个元素不可见。assertTrue/assertFalse: 执行一个JavaScript表达式在WebView上下文或设备端并断言其结果。captureScreenshot: 截取当前屏幕并保存可用于人工复核或后续的视觉对比测试。4. 流程控制与高级功能runFlow: 这是实现模块化和复用的关键命令。你可以将通用的测试序列如登录、添加到购物车写成独立的YAML文件然后在主流程中调用。# main_test.yaml - runFlow: “flows/login.yaml” - runFlow: “flows/search_product.yaml”extendedWaitUntil: 等待某个条件成立最长等待时间可配置非常适合处理网络加载等异步场景。- extendedWaitUntil: visible: “加载中…” timeout: 10000 # 等待10秒 - extendedWaitUntil: notVisible: “加载中…” # 等待“加载中…”提示消失 timeout: 15000script: 执行一段JavaScript代码。这开启了无限的可能性例如处理复杂的逻辑计算、操作WebView内的内容、或者与Maestro的插件系统交互。useFlow: 配合runFlow可以传递参数给子流程实现数据驱动测试。4.2 定位策略详解告别脆弱的XPath元素定位是UI自动化的基石也是维护成本的主要来源。Maestro极力推崇使用文本内容和视图ID进行定位这通常是UI中最稳定的属性。1. 文本定位 (tapOn: “登录”):这是最简单直接的方式。Maestro会在当前视图树中搜索包含该文本的控件。它的优点是意图清晰与用户所见一致。缺点是当应用支持多语言时你需要为每种语言编写不同的测试流或者使用后面提到的参数化功能。2. ID定位 (tapOn: “#login_button”或tapOn: {id: “button_ok”}):这是最稳定、最推荐的定位方式。它对应Android视图的resource-id通常格式为包名:id/控件名或iOS视图的accessibilityIdentifier。开发者在编写UI时如果规范地设置了这些ID测试的健壮性将极大提升。你需要与开发团队沟通确保关键交互元素都有唯一且稳定的ID。3. 相对定位与滚动查找当元素不在当前可视区域内时你不需要手动添加scroll命令。Maestro的tapOn、assertVisible等命令内置了智能查找机制如果第一时间没找到元素它会自动尝试向各个方向滚动屏幕来寻找。你可以通过scrollAmount等参数微调这一行为。4. 绝对定位 (point) 与图像匹配 (image):point: 应作为最后的手段。因为屏幕分辨率一变坐标就失效了。仅在测试某些无法通过常规方式交互的系统级组件如状态栏下拉时可谨慎使用。image: Maestro支持通过截图模板进行图像匹配点击。这在测试游戏或某些自定义绘制控件时可能有用但同样受分辨率、颜色主题影响维护成本高。避坑指南在实际项目中我强烈建议推动“测试ID”的规范化。要求开发同学在编写UI代码时为所有可交互的、需要断言的关键视图添加唯一的测试ID如android:idid/test_login_btn或iOS: accessibilityIdentifier “test_login_btn”。这看似增加了开发的一点工作量但为整个项目的自动化测试奠定了最坚实的基础从长远看节省的调试和维护时间是不可估量的。5. 构建复杂测试套件模块化、数据驱动与CI集成5.1 流程复用与参数化像搭积木一样构建测试当测试用例越来越多时避免重复代码至关重要。Maestro通过runFlow和useFlow实现了出色的模块化。假设我们有一个登录流程被多个测试用例使用。我们可以将其抽离成独立的login.yaml# flows/login.yaml appId: com.example.myapp parameters: username: “default_user” password: “default_pass” --- - launchApp - tapOn: “#nav_profile” - tapOn: “#login_entry” - inputText: “${username}” - tapOn: “#password_field” - inputText: “${password}” - tapOn: “#login_submit_btn” - assertVisible: “#welcome_message”注意顶部的parameters部分它定义了这个流程可接收的参数及其默认值。在步骤中使用${参数名}的语法来引用它们。然后在主测试文件中我们可以这样调用并传入不同的参数# test_suite.yaml - runFlow: file: “flows/login.yaml” with: username: “user1test.com” password: “pass123” - tapOn: “首页” # ... 其他测试步骤 - runFlow: file: “flows/login.yaml” with: username: “admintest.com” password: “admin456” - tapOn: “管理后台” # ... 另一个角色的测试这种模式使得核心业务流程如登录、注册、支付只需编写和维护一份极大地提升了效率。5.2 数据驱动测试用CSV或JSON驱动多个场景对于需要用多组数据验证同一流程的场景例如用不同的用户名密码组合测试登录功能Maestro支持数据驱动测试。你可以将测试数据放在一个CSV或JSON文件中。创建一个test_data.csvusername,password,expected_welcome_text alicetest.com,alice123,Welcome Alice! bobtest.com,bob456,Welcome Bob! charlietest.com,charlie789,Welcome Charlie!然后在YAML中你可以通过data命令来读取并迭代这些数据。不过Maestro原生更优雅的方式是结合useFlow和外部脚本。一个常见的模式是写一个简单的Shell脚本或Python脚本读取CSV文件然后为每一行数据动态生成一个Maestro测试YAML文件并执行。虽然多了一步但灵活性极高。5.3 集成到CI/CD流水线让测试自动运行自动化测试只有集成到持续集成/持续部署CI/CD流水线中才能发挥最大价值。Maestro与主流CI平台如GitHub Actions, GitLab CI, Jenkins, CircleCI的集成非常顺畅。以下是一个GitHub Actions工作流配置示例它在每次推送代码到主分支时在iOS模拟器和Android模拟器上并行运行Maestro测试# .github/workflows/maestro-tests.yml name: Maestro UI Tests on: [push] jobs: test-android: runs-on: macos-latest # 需要macOS来同时运行iOS和Android模拟器纯Linux环境只能测Android steps: - uses: actions/checkoutv3 - name: Set up JDK uses: actions/setup-javav3 with: { java-version: ‘11’ } - name: Setup Android SDK uses: android-actions/setup-androidv2 - name: Install Maestro run: curl -Ls “https://get.maestro.mobile.dev” | bash - name: Launch Android Emulator uses: reactivecircus/android-emulator-runnerv2 with: { api-level: 33, script: “adb devices” } - name: Run Maestro Tests run: maestro test --format junit ./e2e-tests/*.yaml - name: Upload Test Report uses: actions/upload-artifactv3 if: always() with: { name: maestro-android-report, path: ./maestro_report.html } test-ios: runs-on: macos-latest steps: - uses: actions/checkoutv3 - name: Install Maestro run: brew install maestro - name: Launch iOS Simulator run: | xcrun simctl boot “iPhone 14” xcrun simctl bootstatus “iPhone 14” -b - name: Run Maestro Tests run: maestro test --format junit ./e2e-tests/*.yaml - name: Upload Test Report uses: actions/upload-artifactv3 if: always() with: { name: maestro-ios-report, path: ./maestro_report.html }关键点--format junit参数它将测试结果输出为JUnit XML格式这是CI系统如GitHub Actions通用的测试报告格式可以在CI的UI中直接展示测试通过率、失败详情。模拟器管理通过CI工具如android-emulator-runner或脚本启动并管理模拟器。产物归档使用actions/upload-artifact将详细的HTML报告maestro_report.html和屏幕录像保存下来便于失败时查看。在团队中这样的流水线可以确保每次代码变更都经过核心UI流程的验证快速发现回归缺陷。6. 高级技巧与疑难问题排查实录6.1 性能优化与稳定性的提升随着测试套件规模增长执行时间和稳定性成为挑战。以下是我在实践中总结的优化技巧1. 使用clearState确保测试隔离在launchApp命令中加上clearState: true可以确保每次测试都在一个干净的应用状态下开始避免因之前测试遗留的数据导致本次测试失败。- launchApp: clearState: true但要注意这可能会清除应用的所有本地数据登录状态、缓存等。对于需要登录状态的测试你可能需要在流程开始时显式地执行登录操作而不是依赖持久化状态。2. 合理设置超时与等待策略Maestro的默认等待时间对于大多数操作是足够的但在网络慢或应用性能较差的设备上可能不够。你可以全局或在单个命令中调整超时。全局设置在YAML文件顶部使用env部分。env: MAESTRO_FLOW_TIMEOUT_SECONDS: 120 # 整个流程的超时时间 MAESTRO_ELEMENT_TIMEOUT: 30000 # 元素查找超时毫秒针对特定命令使用extendedWaitUntil或命令的timeout参数。3. 避免不必要的断言和截图虽然断言是测试的核心但过多的assertVisible会增加执行时间。只对关键的业务结果进行断言。同样captureScreenshot在调试时很有用但在CI流水线中应酌情减少以节省时间和存储空间。4. 并行执行测试Maestro CLI本身支持并行运行多个测试流。你可以将互不依赖的测试用例拆分到不同的YAML文件中然后使用命令并行执行maestro test --parallel-count 4 ./e2e-tests/这能充分利用多核CPU大幅缩短测试套件的总执行时间。6.2 常见问题排查手册即使有了完善的框架在实际运行中还是会遇到各种问题。下面是一个快速排查清单问题现象可能原因排查步骤与解决方案Element not found(元素找不到)1. 元素ID或文本不正确。2. 元素尚未加载出来。3. 元素在屏幕外需要滚动。4. 应用有多个Activity/Fragment当前上下文不对。1. 使用maestro studio命令启动交互式探索工具连接设备后可以点击屏幕查看元素的真实ID和文本。2. 在操作前添加extendedWaitUntil等待元素出现。3. Maestro通常会自动滚动查找可检查是否因特殊布局失效。尝试手动加一个scroll命令。4. 确保你的操作步骤逻辑正确能导航到目标页面。Tap failed(点击失败)1. 元素不可点击如被遮挡、enabledfalse。2. 坐标计算错误使用point时。1. 在maestro studio中确认元素状态。检查是否有弹窗、蒙层遮挡。2. 尽量避免使用point定位。如果必须用确保坐标计算考虑了不同设备的屏幕密度。测试在CI上失败本地却成功1. CI环境模拟器/设备配置不同API版本、屏幕尺寸。2. 网络环境差异CI服务器无法访问某些资源。3. 并发问题多个测试同时运行相互干扰。1. 统一CI和本地的测试环境配置模拟器类型、系统镜像。2. 在测试中增加对网络加载状态的等待和断言。3. 确保测试是隔离的使用clearState或在CI中串行执行测试。iOS与Android行为不一致1. 相同ID在两个平台上的属性不同。2. 平台交互特性差异如键盘行为、动画。1. 为两个平台分别编写定位策略可以使用条件判断或不同的YAML文件。2. 针对平台差异在测试步骤中做条件分支处理虽然Maestro YAML原生不支持if-else但可通过runFlow结合不同文件来实现。报告显示成功但实际业务逻辑错误断言不够充分。只检查了元素可见没检查具体状态或数据。强化断言。结合assertTrue执行JS来检查更复杂的业务状态例如检查购物车角标数字是否正确。对于关键结果除了UI断言还可以考虑通过Maestro的插件机制读取设备日志或与后端Mock服务交互来验证。调试利器maestro studio这是Maestro自带的图形化调试工具。在终端输入maestro studio并回车它会启动一个本地Web服务器通常为http://localhost:8080。用浏览器打开后按照提示连接你的设备或模拟器。之后你可以在设备屏幕上点击studio会实时显示被点击元素的详细信息包括所有可用的定位方式并且能一键生成对应的YAML命令。这对于编写新测试或调试定位问题来说是效率倍增的神器。7. 超越基础插件生态与自定义扩展Maestro的活力很大程度上来自于其不断增长的插件生态和强大的可扩展性。虽然核心YAML语法已经覆盖了大部分需求但总有需要与特定系统交互或执行复杂逻辑的时候。1. 使用官方和社区插件Maestro支持通过插件来扩展其功能。例如maestro-plugin-sqlite插件允许你直接从测试流中查询或修改应用的SQLite数据库用于准备测试数据或验证数据持久化结果。安装插件后你可以在YAML中使用新的命令- sqliteQuery: dbPath: “/data/data/com.example.app/databases/app.db” query: “SELECT COUNT(*) FROM users;” storeResultIn: userCount - assertTrue: “${userCount} 0”你可以在Maestro的官方文档或社区中寻找需要的插件。2. 通过script命令执行自定义JavaScript对于更灵活的逻辑script命令是终极武器。它允许你在一个Node.js环境中执行JavaScript代码并可以访问Maestro提供的设备操作API。- script: | const { device } context; // 获取当前设备信息 const deviceInfo await device.getInfo(); console.log(Testing on ${deviceInfo.model}); // 执行一些复杂计算或逻辑判断 if (deviceInfo.platform ‘iOS’) { // iOS特定的逻辑 } // 你甚至可以通过fetch调用外部API const response await fetch(‘http://localhost:3000/api/setup’); const data await response.json(); env.TOKEN data.token; // 将数据存入环境变量供后续步骤使用 - inputText: “${TOKEN}” # 使用脚本中设置的环境变量这几乎实现了无限的可能性比如动态生成测试数据、与测试管理平台交互、解析复杂的API响应等。3. 开发自己的插件如果现有功能都无法满足你的需求你可以用JavaScript/TypeScript开发自己的Maestro插件。插件可以封装复杂的操作如特定的手势、与硬件传感器的交互、读取系统文件等然后通过简单的YAML命令暴露给测试流使用。这需要一定的Node.js开发经验但一旦建成可以极大地标准化和简化团队内的复杂测试操作。从我个人的使用经验来看Maestro的成功在于它在“简单易用”和“强大灵活”之间找到了一个绝佳的平衡点。对于大多数常见的UI测试场景YAML的简洁语法足以应对而对于那些边界情况或复杂集成script命令和插件系统又提供了足够的逃生舱口。它降低了一线测试人员编写自动化脚本的门槛同时又没有限制高级开发者的发挥空间。将Maestro融入开发流程后最明显的改变是我们关于“这个改动会不会影响核心流程”的讨论变少了因为答案在每次代码提交后的几分钟内就会由自动化测试套件清晰地给出。

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

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

相关文章

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…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…