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

网络运维工作内容及过程/东莞网站seo优化

网络运维工作内容及过程,东莞网站seo优化,万宁市住房和城乡建设厅网站,国内做国外代购在哪个网站背景介绍 书接上回《Monorepo 解决方案 — Bazel 在头条 iOS 的实践》,在头条工程切换至 Bazel 构建系统后,为了支持用户使用 Xcode 开发的习惯,我们使用了开源项目 Tulsi 作为生成工具,用于将 Bazel 工程转换为 Xcode 工程。但是…

背景介绍

书接上回《Monorepo 解决方案 — Bazel 在头条 iOS 的实践》,在头条工程切换至 Bazel 构建系统后,为了支持用户使用 Xcode 开发的习惯,我们使用了开源项目 Tulsi 作为生成工具,用于将 Bazel 工程转换为 Xcode 工程。但是在使用的过程中,我们发现了一些问题,其中影响较大的是,

  • Xcode 工程卡顿:对于头条这种大型项目来说,Xcode 卡顿一直是本地研发的痛点问题,在切换 Bazel 构建系统之后卡顿现象明显加剧。

  • Xcode 功能支持受限:Tulsi 支持的功能有限,很多功能都年久失修,并未持续适配 Bazel 与 rules 的更新。

在做了一些前期调研后,我们发现 rules_xcodeproj 提供了更好的解决方案。rules_xcodeproj 是一个由一系列 Bazel rules 组成的开源项目,使用它可以从一个 Bazel 工程生成对应的 Xcode 工程,实现在 Xcode 中写代码同时使用 Bazel 进行真正的构建任务,相比于 Tulsi,rules_xcodeproj 在以下几个方面有着更为明显的优势。

  • Xcode 工程更加流畅: 头条工程迁移到 rules_xcodeproj 后,工程首次冷启、二次启动和文件增删操作的时间有了明显缩短,工程卡顿情况也明显好转。

  • Xcode 功能支持度更高: rules_xcodeproj 对 Xcode 的支持更全面(包括单元测试、SwiftUI Previews),能够更好地满足我们的需求。

  • 社区更加活跃:随着 rules_xcodeproj 在 2023 年 2 月份发布正式版,Tulsi 项目也正式宣布停止维护,这意味着对于新版本的 Bazel,Tulsi 将不再提供适配和支持;同时 rules_xcodeproj 几乎每月都会更新一个中版本,对于后续适配 Bazel 更新的成本会更低。

  • 更符合 BitSky 的演进路线:由 Bazel 驱动的工程生成方式更符合 BitSky 的 Bazel Native 演进路线,可以完全在 Bazel 环境下生成工程。

因此,我们将 Xcode 生成工具从 Tulsi 迁移到了 rules_xcodeproj,并对 BitSky 工具链进行了适配。适配过程中,我们在修复 rules_xcodeproj 索引问题的同时,对工程结构进行了一些优化,进一步提升了工程流畅度。头条 iOS 工程的测试数据如下:

测试设备 MacBook Pro,芯片 M1 Pro,内存 32GB

ps. 本文介绍均基于 rules_xcodeproj 1.4.0 版本,build with bazel 模式

pps. 由于 Xcode 主线程的卡顿较难监测,此处用主动操作的执行时间衡量流畅度


Tulsirules_xcodeproj
工程首次冷启47s16s
二次启动33s12s
文件操作新增 20s
删除 23s
新增 8s
删除 6s

下面来看下我们具体做的适配工作。

适配过程

从 Tulsi 迁移到 rules_xcodeproj 后,我们发现 Xcode 卡顿有明显改善,仔细分析发现 Tulsi 工程的卡顿主要有两方面原因:

  1. 头条工程中组件数量多、依赖关系复杂:Tulsi 的索引方案需要 Xcode Target 之间保留这些依赖关系,但这些依赖关系并不会被 Xcode 构建消费,却增加了 Xcode 对工程进行解析和计算的成本。

图中 Pod X_A 与 Pod X_B 为 Pod X 分别在 App A 与 App B 下被引用的 Target

4ec246b5859f3a8f8259299f78a27790.png
  1. 全源码构建:我们在切换 Bazel 时还推进了工程的全源码构建,源码数量大幅增加,也给索引任务带来更大的压力。

接下来详细说明整个分析和适配过程,带大家更全面地了解我们结合 rules_xcodeproj 在 Xcode 背后做了什么。

在 Xcode 中开发时主要会用到三部分功能:构建、索引和调试。而 Xcode 并不能直接理解 Bazel 项目的工程文件(BUILD 和 WORKSPACE),所以我们需要通过工具(rules_xcodeproj 或 Tulsi)将 Bazel 的工程文件转换为 Xcode 可以理解的 .xcodeproj来支持这些功能正常工作。

各功能的适配点如下表所示。

ae4f2b66f0acc6128c5367818f006120.png

rules_xcodeproj 原生方案的调试模块基本能正常工作,而索引和构建两个模块中我们对原生方案的改造较大,因此本文主要对这两个模块进行展开介绍。

索引

前面提到支持 Xcode 索引功能需要提供各个源文件的编译参数,rules_xcodeproj 实现这一点的工作流程是:

  1. rules_xcodeproj 在 Bazel 的分析阶段获取到源码文件和编译参数;

  2. 用这些信息创建 Xcode Target 的 Compile Sources 和 Build Setting 产出工程文件 .xcodeproj

  3. Xcode 加载工程文件,获取源码文件对应的索引参数,调用 clang 或 swiftc 执行索引命令。

迁移过程中我们注意到 rules_xcodeproj 工程的索引在多 Target 共用源文件的场景存在语法高亮异常的问题,对比 Tulsi 工程的处理方式后我们得出两个结论:

  • 索引异常是由于 rules_xcodeproj 移除了所有 Library Target 间的依赖导致的;

  • Tulsi 工程中 Library Target 间的依赖关系正是导致 Tulsi 工程更为卡顿的关键原因。

后文会先分析依赖关系在索引中发挥的作用,以及 rules_xcodeproj 如何处理依赖关系移除带来的问题,然后介绍我们如何通过源码合并方案解决 rules_xcodeproj 索引方面的缺陷。

依赖关系在索引中的作用

这里提到的“依赖关系”主要是指 Xcode 工程文件(.xcodeproj,准确来说是其中的project.pbxproj文件)中记录的 Xcode Target 之间的依赖关系。

需要明确的是这部分依赖关系只会在 Xcode 索引过程被用到,被移除后也只会影响 Xcode 的索引功能。构建时用到依赖关系 Bazel 会从 BUILD 文件中获取,不会关心 .xcodeproj 中的信息。

这些依赖关系在 Xcode 中的表现形式如下图所示,既有直接在 Build Phases 的 Target Dependencies 中声明的依赖,也会对声明在 Link Binary With Libraries 中 Target 产生依赖。

9a70beae7d3eabf6c246b869a8ec32a8.png

概括来说依赖关系在 Xcode 的索引过程中发挥着以下两方面作用:

  • 正确的中间产物生成顺序:clang/Swift Module 中间产物的生成需要依赖关系来确定构建顺序;

  • 正确的多 Target 编译参数:多 Target 共用源文件时应用正确的编译参数,以便于正确地高亮代码。

下面分别对其进行展开介绍。

中间产物生成顺序

以一个 Swift 组件为例,当它被 OC 组件引用时,需要生成一个 XX-Swift.h 文件,把方法和声明暴露给 OC 组件,当它被其他 Swift 组件引用时,也需要生成一个 swiftmodule 文件供其他 Swift 组件引用。XX-Swift.h 和 swiftmodule 并不是原始的源码文件,也不是最终的二进制产物,是构建时的中间产物。在 Xcode 对一个组件的源代码索引时,需要这个组件的依赖组件已经准备好中间产物供索引时消费。这里,我们先分析下 Xcode 是怎样解决这个问题的。

首先,Xcode 通过 Target 来描述产物是如何构建出来的,每个 Target 拥有自己的 Build PhasesBuild Settings(通常一个组件对应一个 Target)。Build Phases 中的 Compile Sources 记录了构建这个 Target 需要编译哪些源码文件。Build Settings 里记录了构建这个 Target 时的各种配置,这其中就包括了编译参数。Xcode 可以从 Build Settings 里去获取编译参数,然后对 Compile Sources 中记录的源码文件进行索引编译。

2414d15fa65de663ef9fc654842c642b.png

一个 Target 引用另外一个 Target 时,需要将依赖关系添加到 Build PhasesTarget Dependencies 中。Xcode 在构建时会根据这些依赖关系来决定构建 Target 的顺序,保证一个 Target 构建时,它依赖的 Target 已经完成构建。

索引时也是类似的处理,Xcode 有一个 Index Build 的阶段,在这个阶段也会根据依赖关系按照顺序去触发 Target 的 Build Phase,完成之后才会开始索引这个 Target 的源码文件。

e133de8ddd922d6967a7b560c6ae0ede.png

这里有一个例子,SwiftDemo 依赖了 HelloLib,两个 Target 均为 Swift 组件。

f14f30f22fdb571db7e449ef614a591a.png

在对 SwiftDemo 的源码文件进行索引编译之前,会先触发 Index BuildIndex Build 时根据依赖关系,先 Build HelloLib,这个时候会进行 Compile Swift source files,参数中包含 -emit-module -emit-module-path /path,最终会生成 swiftmodule 。

f87c913f5b942d6786a1cf97f33728f2.png

如果将 HelloLib 从 SwiftDemo 的 Target Dependencies 中移除,在 SwiftDemo 的 Index Build 时,不会先 Build HelloLib,并且在 HelloLib 的 Index Build 中,也不会生成 swiftmodule。

可以看出,Xcode 正是通过依赖关系来保证构建时的顺序,索引也依赖构建顺序来保证 Module 中间产物的生成时机。

在 Tulsi 生成的 Xcode 工程中,依然保留了 Target 之间的依赖关系,用于解决索引的中间产物生成问题。这里就不做过多介绍。

而在 rules_xcodeproj 生成的工程中,Target 之间的依赖关系是完全去掉的,每个 Target 都有且仅有一个额外添加的依赖 BazelDependencies。对于 Module 中间产物的处理,在生成的 Xcode Target 中,我们可以看到这样一条 Build Phase

6b02f18b9c49dd4fb39cbf5b187be395.png

原理是在 Index Build 阶段,执行到这 Target 时去跑一个 shell 脚本。

以 NewsInHouse 这个 Target 为例,这个脚本里经过一系列的处理,最终会去调用这样一条 Bazel Build 命令,

403385e739f097aa6325286ad7cc20e1.png

在这条命令中有一些关键信息:

@rules_xcodeproj_generated//generator/xcodeproj:xcodeproj

Bazel Build 的 Target,可以认为是我们使用 rules_xcodeproj 定义的生成工程的 Bazel Target。

bc //Article:NewsInHouse applebin_ios-*

在上述 Target 里 rules_xcodeproj 添加了一些 OutputGroupInfo。Bazel Build 时可以通过 --output_groups 参数指定输出产物。

这一条 output group 对应的是 //Article:NewsInHouse 及其依赖 Target 的产物中, swiftmodule 之类的编译依赖部分。

bg //Article:NewsInHouse applebin_ios-*

这一条 output group 对应的是 //Article:NewsInHouse 及其依赖 Target 的输入文件中的非源文件的部分,比如编译时依赖的 hmap 。

这样的 Bazel Build 命令可以在 Index Build 时将 hmap 和 swiftmodule 之类的索引中间产物生成出来,然后再索引具体文件时就不会因为缺少这些中间产物而失败。

并且这里的依赖关系是由 Bazel 去处理的,不是必须像 Xcode 原生机制那样,按照依赖关系来决定 Index Build 中 Target 的顺序。

所以仅从 "Module 中间产物" 这方面来说,Xcode 中的依赖关系并不是必需的。

多 Target 编译参数

除了中间产物生成之外,依赖关系在多个 Target 共用源文件时的编译参数计算也发挥着作用。这里的“编译参数计算”是指当一个源文件被不同 Target 引用时,应用的编译参数可能不同的情况。这么介绍比较抽象,来看下具体的例子:

下面 Demo 工程中有两个 App Target:AppA 和 AppB

  • 在两个 App Target 的 Build Settings 中分别注入了宏IS_APP_AIS_APP_B

b61e982229b656e45a22aea1fac454cb.png 688f083887273e47d8649857f9d63926.png
  • 有一份公共的代码文件 public.m 分别被添加到两个 App Target 的 Compile Sources 中。

eb35f875f2cc087c3805c5cba1c451be.png a9ff4466ff877923f1cf9c1843774e14.png
  • public.m 内用预编译宏隔离了存在差异的逻辑

  • 随着我们切换构建的 App Scheme,由于编译参数的差异,宏作用域中高亮的代码区域也会随之变化(如下图)。

29024af5ffe1e9c7ce3faadbfb7697ca.png 2e0e51210f4c66bd2ca580a2a9b20999.png

此时的工程结构如下图所示,Xcode 可以通过选中的 AppA Scheme 获取到 AppA Target 的 Build Settings(图中红线路径),正确地传递编译参数-DIS_APP_A=1

31e5adafeea72779cfbf53715ff7f6d2.png

实际的情况会复杂一些,因为工程的组件化建设将代码下沉到了一个个组件内,而非直接与 App Target 关联。此时同一份代码文件在不同 App Target 内的索引参数计算,则是通过 Target 之间的依赖关系实现的。

对应到 Xcode 中,Xcode 可以通过 App Target -> Library Target 的依赖关系,应用对应的 Build Settings 生成索引。

1ed1eae4b77ab07080641ebf9ebb2ecd.png

此时的工程结构则变成了下图的模式,Xcode 依然可以通过 AppA Target 与 PublicLibraryA Target 的依赖关系应用正确的编译参数(图中红线路径)。

471dc3126ce61f6981f7abc06acab5a9.png

Xcode 原生工程和 Tulsi 生成的 Xcode 工程都是通过这种依赖关系来保证编译参数的正确计算的。

而 rules_xcodeproj 生成的工程完全移除了 Target 之间的依赖关系,转而给所有 Target 都添加了对 BazelDependencies 的依赖(如下图所示)。

b5dd264280a1bc407672bf1d1b81a8ab.png

从图中可以看到,在缺少 AppA Target 对 PublicLibraryA Target 依赖的情况下,对于同时被 PublicLibraryA 和 PublicLibraryB 引用的 public.m ,Xcode 无法感知应该应用哪个 Target 中的编译参数(图中红线路径无法关联 AppA Scheme 与 public.m)。此时 Xcode 触发索引时应用的 Build Settings 是固定的,不会随着构建 App Scheme 切换而更改。

具体的表现当构建目标从 AppB 切换到 AppA 时,IS_APP_B宏中的代码仍然会展示为高亮,而不会随之切换,从而给开发者带来困惑。

c4e6a814d21eee832f88595647f2eda0.png

对于这个问题,rules_xcodeproj 可以通过构建索引解决,因为依赖信息在 Bazel 侧(BUILD 文件中)是完整的,所以触发构建后可以让代码高亮正确展示。

但由于编辑索引使用的参数是 Xcode 从文件所属的 Library Target 的 Build Settings 中获取的,因此在代码编辑过程中仍然会出现高亮错误的问题。

构建索引:指在构建过程中输出索引产物,需要通过 index-import 导入 Xcode 缓存目录(Derived Data)下供 Xcode 消费。

编辑索引:在代码编辑过程中实时生成的索引,在内存中消费索引结果,不会将产物写入磁盘。

在这个场景下,rules_xcodeproj 移除依赖的做法是有缺陷的

那么我们要在 rules_xcodeproj 恢复 Target 间的依赖关系么?

答案是不需要。首先,前文有提及大量复杂的依赖关系会导致 Xcode 卡顿,不应恢复;其次,要解决这类代码高亮错误的问题,需要的其实并不是所有 Target 之间的依赖关系,而是源码文件当前构建 App Target 的关系。

回顾一下 Demo 工程最简单的结构,当源码文件直接被对应 App Target 引用时,是不需要 Library Target 间的依赖关系来建立联系的。

29ae12a58eb0efcf6f9ddf8f1252a741.png

基于这一思路,我们将所有 Library Target 的源码合并到了对应 App Target。当然,直接合并源码以后索引并不能正常工作,需要对受影响的功能点进行适配,这些适配将在下一节源码合并方案中展开介绍。

源码合并方案
索引参数接管

将所有源码合并至 App Target 虽然能解决文件与 App 的关联问题,但各个 Library Target 编译参数是不同的,聚合之后不同 Target 下源文件的参数就无法通过 Build Settings 区分了。

对于这个问题,我们是通过 XCBBuildServiceProxy 接管索引参数计算解决的。

索引构建时,Xcode 会先将文件所属 Target 的 Build Settings 发送给 XCBBuildService 处理成编译器理解的参数,再交给 SKAgent 触发编译器进行实际编译行为。而我们在 XCBBuildServiceProxy 的基础上实现了 BitSkyXCBBuildService,可以拦截 Xcode 发给 XCBBuildService 的请求,通过 Bazel aquery 查询到具体文件的编译参数,直接返回给 Xcode 完成后续的索引构建行为。

2284995caa498d3ca7a0e8e8d855e8d6.png

完成源码合并索引参数接管这两步改造以后,工程结构如下图所示。可以看到 AppA Scheme 能够直接通过 AppA Target 关联到  public.m(图中红线),从而正确地应用编译参数,高亮对应代码块。rules_xcodeproj 移除依赖关系的副作用也完全被修复。

e51d0d84d960fe3075732b71d8affd40.png
Library Target 移除

完成源码合并以及索引参数的接管之后,Library Target 中的主要信息( Build Settings 和源码)都不再有意义了,是否能将这些 Target 信息直接移除呢?

经过梳理,Library Target 主要有以下三个作用,在完成源码合并以及索引参数接管后,仅需对“Module 中间产物生成”进行一些改造即可将几百个 Library Target 的信息进行移除,大幅精简工程文件的内容。

Library Target 作用说明适配方案
触发 Xcode 索引Xcode 只会对添加到 Build Phase - Compile Sources 中的源码文件生成索引将源码添加到 App Target 的 Compile Sources 中有相同的效果;
按 Target 维度隔离 Build SettingsXcode 原生的索引功能会通过 Build Settings 生成文件的编译参数通过 XCBBuildServiceProxy 接管索引参数请求,交由 Bazel aquery 查询具体文件的编译参数
Module 中间产物生成在 Library Target 的 Build Phase 触发各个 Target 维度的中间产物生成将所需产物聚合到各个 App Target 的 Build Phase 触发生成

最终的工程结构如下图所示。

a9ea7b9908b2eeafafad6fad41d0833b.png

整体方案上线后,头条工程文件(project.pbxproj)行数从 45w 减少至 35w,工程启动与文件操作耗时也比原来的 Tulsi 工程减少了 60% 以上


Tulsirules_xcodeproj(原生)rules_xcodeproj(源码合并)
工程首次冷启47s22s16s
二次启动33s16s12s
文件操作新增 20s
删除 23s
新增 13s
删除 11s
新增 8s
删除 6s

p.s. 源码合并后存在一个副作用是 Xcode Build Phase 页面加载时间会增加很多,但考虑到使用 bazel 构建后我们并不需要在 Build Phase 修改配置,这个副作用是可以接受的。

构建

rules_xcodeproj 目前提供了两种 Build 模式,分别是 "Build with Xcode" 和 "Build with Bazel"。

  • "Build with Xcode" 模式下,构建行为是由 Xcode 接管的。

  • "Build with Bazel" 模式下,构建行为是由 Bazel 接管的。

据 rules_xcodeproj 官方介绍,"Build with Xcode" 模式在 Bazel 7 下将很难支持,并且即将到来的新的增量生成模式也会放弃 "Build with Xcode" 。

所以这里主要看一下 "Build with Bazel" ,这个模式生成的工程中,宿主 Target 对应一个 XCScheme,这个 Scheme 的 Build Pre-actions 里生成一个 SCHEME_Target_IDS_FILE 用于记录 Target 的 Bazel Label。然后宿主 Target 依赖了 Target BazelDependencies,Xcode 在构建宿主 Target 之前会先构建 BazelDependencies。BazelDependencies 通过 Build Phase 去调用 Bazel Build,这个时候会解析 SCHEME_Target_IDS_FILE 获取需要构建的 Bazel Target。BazelDependencies 构建完成后,宿主 Target 的 Build Phase 里会去把相应的 Bazel 的产物拷贝到 Xcode Derivedata 目录下。

c7851019139afd7c4452be34401c92d4.png

另外,在 rules_xcodeproj 的规划中,未来还会提供一种新的模式,叫做 "Build with Proxy",在这个模式下,会通过 XCBBuildServiceProxy 完全绕过 Xcode build system,由 Bazel 控制整个 build 过程。相比 "Build with Bazel" ,这个模式可以带来一些更贴近原生的 Xcode 使用体验,比如:

  • 无需添加 BazelDependencies Target

  • 可以去掉重复的 warnings/errors

  • 可以有更稳定的索引效果

  • 可以在进度条展示更多信息

  • 可以有更详细的 Build 报告

当然这种模式也存在比较大的问题

  • 在不同 Xcode 版本之间,Xcode 和 XCBBuildService 交互的 API 可能会有一些破坏性的变更,需要逐一适配

  • 需要在 Xcode 启动时注入环境变量,将 XCBBuildService 指向自定义的 XCBBuildServiceProxy

BitSky 目前采用的方案和 "Build with Proxy" 是类似的,通过 BitSkyXCBBuildService 接管 Xcode 的 build 行为。在用户点击 Build 时,BitSkyXCBBuildService 里可以从宿主 Target 的 Build Settings 里解析获取对应的 Bazel Target,然后再由 BitSky 生成调用 Bazel Build 的命令,这样可以保证 Bazel Build 的参数完全由 BitSky 控制,同时可以通过 Bazel 的 Build Event Protocol 来更好的提供 Xcode 的进度 和 Build 日志展示。

649de1ed5e5b365e161175e8965aeb1a.png

同时为了保证在打开生成的 Xcode 工程时,都能够使用 BitSkyXCBBuildService,BitSky 在生成工程同时,会生成一个 Xcode 的影子分身 BitSkyXcode。使用这个 BitSkyXcode 打开工程,无需手动注入环境变量,体验上和使用原生 Xcode 打开工程基本一致。

总结

本文主要介绍了我们将 Xcode 工程生成工具切换到 rules_xcodeproj 过程中做的一些适配和优化工作:

  • 索引方面:

    • 在分析 Tulsi 与 rules_xcodeproj 工程文件的过程中我们注意到最大的差异在于 rules_xcodeproj 移除了 Library Target 间的依赖关系,这也是 Tulsi 工程更加卡顿的罪魁祸首。

    • rules_xcodeproj 移除依赖关系后会导致多 Target 共用的源文件语法高亮异常,我们通过源码合并方案解决了这个问题,并且精简了工程文件信息,提升了 Xcode 流畅度。

  • 构建方面:

    • 我们通过 BitSkyXCBBuildService 接管了 Xcode 的 build 行为,能够更好地管理构建参数并在 Xcode 提供构建进度和日志的展示。

在完成切换之后,虽然 Xcode 代码编辑过程中的卡顿得到了明显的缓解,但本地研发的调试过程,仍然存在 Xcode 卡顿/卡死等现象,对研发同学的开发工作存在较大困扰。后续,我们将针对调试体验,从生成工程的角度做一些优化工作。

目前考虑基于 Focus Mode 的理念,从底层能力上支持研发同学仅关注与当前需求开发相关联的部分代码,比如:

  • 裁剪 Xcode 工程中需要索引的源代码;

  • 裁剪构建过程中需要执行编译源代码;

  • 裁剪调试时调试器需要加载调试信息;

另外在用户侧,通过策略智能帮助研发同学,选择和添加需要 "Focus" 的源码。

参考文档

Tulsi (https://github.com/bazelbuild/tulsi)

rules_xcodeproj (https://github.com/MobileNativeFoundation/rules_xcodeproj)

Migrating from Xcode to Bazel (https://bazel.build/migrate/xcode)

Monorepo 解决方案 — Bazel 在头条 iOS 的实践

哔哩哔哩 iOS Bazel 进化之路

用VSCode基于Bazel打造Apple生态开发环境

相关文章:

Monorepo 解决方案 — 基于 Bazel 的 Xcode 性能优化实践

背景介绍 书接上回《Monorepo 解决方案 — Bazel 在头条 iOS 的实践》,在头条工程切换至 Bazel 构建系统后,为了支持用户使用 Xcode 开发的习惯,我们使用了开源项目 Tulsi 作为生成工具,用于将 Bazel 工程转换为 Xcode 工程。但是…...

Unity触发器的使用

1.首先建立两个静态精灵(并给其中一个物体添加"jj"标签) 2.添加触发器 3.给其中一个物体添加刚体组件(如果这里是静态的碰撞的时候将不会触发效果,如果另一个物体有刚体可以将它移除,或者将它的刚体属性设置…...

docker compose部署rabbitmq集群

docker compose 配置 假设有两台电脑 A电脑的ip为192.168.1.100 B电脑的ip为192.168.1.103 A电脑的docker compose 配置 version: 3services:rabbitmq:restart: alwaysimage: rabbitmq:3.9.18-managementcontainer_name: rabbitmq-node-1hostname: rabbit1extra_hosts:- &quo…...

数据结构/C++:红黑树

数据结构/C:红黑树 概念实现基本结构插入uncle为红色节点uncle为黑色节点 总代码展示 概念 红黑树是一种二叉搜索树,一般的二叉搜索会发生不平衡现象,导致搜索效率下降,于是学者们开始探索如何让二叉搜索树保持平衡,这…...

【LabVIEW FPGA入门】浮点数类型支持

如今,使用浮点运算来设计嵌入式系统的需求变得越来越普遍。随着 FPGA 因其固有的大规模并行性而在浮点性能方面继续超越微处理器,这种情况正在加剧。线性代数和数字信号处理 (DSP) 等高级算法可以受益于浮点数据类型的高动态范围精度。LabVIEW FPGA 通过…...

ffmpeg 滤镜实现不同采样率多音频混音

音频混音在音视频开发中是十分重要的一个环节,所谓音频混音就是将所有需要混音的数据相加得到混音数据,然后通过某个算法进行非法数据的处理;例如相加数值超过最大值,最小值等! 在实际的音频开发中,要实现混音的流程如下: 因此我们的编码实现就分为五部分:寻找…...

UserTCP 传输数据时如何保证数据的可靠性?并以LabVIEW为例进行说明

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过多种机制保证数据的可靠性,确保数据在网络中从一端传输到另一端时,顺序正确且无误差。以下是TCP实现数据可靠性的一些关键机制: 1. 三…...

基于粒子群算法的分布式电源配电网重构优化matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1基本PSO算法原理 4.2配电网重构的目标函数 5.完整工程文件 1.课题概述 基于粒子群算法的分布式电源配电网重构优化。通过Matlab仿真,对比优化前后 1.节点的电压值 2.线路的损耗,这里计…...

mysql提权总结(自学)

目录 MySQL数据库提权简介 UDF提权 原理 利用条件 利用准备 利用过程 MOF提权 原理 利用条件 利用过程 自启动提权 反弹shell提权 总结 MySQL数据库提权简介 一般数据库提权思路: 检测数据库的存在(探测端口)获取到数据库的权限…...

[数据集][目标检测]铝片表面工业缺陷检测数据集VOC+YOLO格式400张4类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):400 标注数量(xml文件个数):400 标注数量(txt文件个数):400 标注类别…...

晶体管-二极管三极管MOS管选型参数总结

🏡《总目录》 目录 1,概述2,二极管选型参数2.1,类型(Type)2.2,最大整流电流(IF)2.3,反向击穿电压(VRRM)2.4,正向压降(VF)2.5,反向电流(IR)2.6,结温(Tj)2.7,热阻(Rth)2.8,频率特性2.9,包装类型...

ssh命令——安全远程连接Linux服务器

ssh命令是Secure Shell的简写,其功能是安全地远程连接服务器,ssh是OpenSSH套件中的客户端连接工具,通过SSH加密协议进行远程主机访问,并对远程服务器进行管理。 ssh命令的基本语法格式如下: ssh [选项] 主机名或IP地…...

Ansible非标记语言YAML与任务剧本Playbook

前言 上篇介绍了 Ansible 单模块(AD-Hoc)的相关内容Ansible自动化运维Inventory与Ad-Hoc-CSDN博客,Ad-Hoc 命令是一次性的、即时执行的命令,用于在远程主机上执行特定任务,这些命令通常用于快速执行简单的任务。当需要…...

WPF监控平台(科技大屏)[一]

跟着B站的视频敲了一个略微复杂的WPF界面,链接如下.在这里我详细的写一份博客进行设计总结. 系统介绍和配置及主窗口设计_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Wy421Y7QD?p1&vd_source4796b18a2e4c1ec8a310391a5644b6da 成果展示 实现过程 总体来说,我的…...

HTML详细教程

文章目录 前言一、快速开发网站最简模板二、HTML标签1.编码2.title3.标题4.div和span5.超链接6.图片7.列表8.表格9.input系列10.下拉框11.多行文本 三、GET方式和POST方式1.GET请求2.POST请求 前言 HTML的全称为超文本标记语言,是一种标记语言,是网站开发…...

【excel】常用的50个函数与基础操作(统计函数)

统计函数 (1)数组函数操作 1.【SUM】求和 SUM(数字1,数字2,数字3…) 2.【SUMIF】单条件求和 SUMIF (条件区域,条件,求和区域) 3.【SUMIFS】(单)多条件求和…...

MATLAB中的cell数组和结构体

MATLAB中的Cell数组和结构体 MATLAB作为一种高级编程语言和数值计算环境,为用户提供了多种数据结构,以便更灵活、高效地处理数据。其中,cell数组和结构体是两种非常重要的数据结构,它们在MATLAB编程和数据管理中发挥着关键作用。…...

Python深度学习之路:TensorFlow与PyTorch对比【第140篇—Python实现】

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python深度学习之路:TensorFlow与PyTorch对比 在深度学习领域,Tens…...

Unity中UGUI中的PSD导入工具的原理和作用

先说一下PSD导入工具的作用,比如在和美术同事合作开发一个背包UI业务系统时,美术做好效果图后,程序在UGUI中制作好界面,美术说这个图差了2像素,那个图位置不对差了1像素,另外一个图大小不对等等一系列零碎的…...

删除 Oracle 软件和数据库教程

1.使用 deinstall 工具删除安装的 Oracle 软件的可执行文件和配置文件 [oracleocpstudy admin]$ cd $ORACLE_HOME [oracleocpstudy db_1]$ cd deinstall [oracleocpstudy deinstall]$ ls bootstrap_files.lst bootstrap.pl deinstall deinstall.pl deinstall.xml jlib …...

C语言自学笔记8----C语言Switch语句

C 语言 switch 语句 switch语句使我们可以执行许多代替方案中的一个代码块。 虽然您可以使用if…else…if阶梯执行相同的操作。但是,switch语句的语法更容易读写。 switch … case的语法 switch (expression) { case constant1: // 语句 break; case constant2: // …...

分布式搜索引擎(3)

1.数据聚合 **[聚合(](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html)[aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html)[)](https://www.ela…...

PostgreSQL开发与实战(6.3)体系结构3

作者:太阳 四、物理结构 4.1 软件安装目录 bin //二进制可执行文件 include //头文件目录 lib //动态库文件 share //文档以及配置模版文件4.2 数据目录 4.2.1 参数文件 pg_hba.conf //认证配置文件 p…...

ISIS接口MD5 算法认证实验简述

默认情况下,ISIS接口认证通过在ISIS协议数据单元(PDU)中添加认证字段,例如:MD5 算法,用于验证发送方的身份。 ISIS接口认证防止未经授权的设备加入到网络中,并确保邻居之间的通信是可信的。它可…...

Vue项目的搭建

Node.js 下载 Node.js — Download (nodejs.org)https://nodejs.org/en/download/ 安装 测试 winR->cmd执行 node -v配置 在安装目录下创建两个子文件夹node_cache和node_global,我的就是 D:\nodejs\node_cache D:\nodejs\node_global 在node_global文件下再创建一个…...

ABB新款ACS880-04-650A-3逆变器模块ACS88004650A3加急发货

全球商业别名:ACS880-04-650A-3 产品编号:3AUA0000137885 ABB型号名称:ACS880-04-650A-3 目录描述:低压交流工业单传动模块,IEC:Pn 355 kW,650 A,400 V,UL:Pl…...

Science Robotics 封面论文:美国宇航局喷气推进实验室开发了自主蛇形机器人,用于冰雪世界探索

人们对探索冰冷的卫星(如土卫二)的兴趣越来越大,这可能具有天体生物学意义。然而,由于地表或冰口内的环境极端,获取样本具有挑战性。美国宇航局的喷气推进实验室正在开发一种名为Exobiology Extant Life Surveyor&…...

flutter环境搭建实践

Dart Dart 是一种客户端和服务器端的编程语言,最早由 Google 提出。它被设计用于构建高性能、高度可伸缩和可靠的应用程序。Dart 可以编译成本地代码或者在虚拟机中直接运行。在移动应用开发中,Dart 主要用于开发 Flutter 应用。 Flutter 和 Dart 的关…...

CentOS无法解析部分网站(域名)

我正在安装helm软件,参考官方文档,要求下载 get-helm-3 这个文件。 但是我执行该条命令后,报错 连接被拒绝: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 # curl: (7) Fai…...

使用HttpRequest工具类调用第三方URL传入普通以及文件参数并转换MultipartFile成File

使用HttpRequest工具类调用第三方URL传入普通以及文件参数 一、依赖及配置二、代码1、模拟第三方服务2、调用服务3、效果实现 一、依赖及配置 <!--工具依赖--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId&g…...