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

百度APP iOS端包体积50M优化实践(七)编译器优化

在这里插入图片描述

一. 前言

百度APP iOS端包体积优化系列文章的前六篇重点介绍了包体积优化整体方案、图片优化、资源优化、代码优化、无用类优化、HEIC图片优化实践和无用方法清理,图片优化是从无用图片、Asset Catalog和HEIC格式三个角度做深度优化;资源优化包括大资源优化、无用配置文件和重复资源优化,代码优化包括无用类优化、无用模块瘦身、无用方法瘦身、精简重复代码、工具类瘦身和AB实验固化。本文重点介绍编译器优化,在百度APP实践中,编译器优化包括GCC语言编译优化、Swift编译优化、LTO优化、剥离调试符号、剥离符号表、剔除未引用的代码、Asset 优化、C++虚函数优化和三方SDK编译器方向瘦身。此外,我们重点介绍了指令集架构优化、XCode升级优化和Swift内置动态库优化,这三个模块优化的基础原理都涉及到编译器,所以我们在此篇章一起介绍。

百度APP iOS端包体积优化实践系列文章回顾:

1、《百度APP iOS端包体积50M优化实践(一)总览》

2、《百度APP iOS端包体积50M优化实践(二) 图片优化》

3、《百度APP iOS端包体积50M优化实践(三) 资源优化》

4、《百度APP iOS端包体积50M优化实践(四)代码优化》

5、《百度APP iOS端包体积50M优化实践(五)无用类优化和HEIC图片优化实践》

6、《百度APP iOS端包体积50M优化实践(六)无用方法清理》

二. 编译器优化

2.1 方案综述

图片

2.2 GCC语言编译优化

2.2.1 综述

通过GCC编译优化,产生体积更小的二进制产物,对OC、C、C++都有效果。

2.2.2 Objective C++编译优化

对于Objective C++采用XCode编辑和编译,编译优化配置路径为:Build Settings -> Apple Clang - Code Generation -> Optimize Level,可选参数如下:

图片

图片

Xcode的默认优化等级是-Os,但我们使用了-Oz优化方式。在WWDC 2019的《What’s New in Clang and LLVM》中,链接地址:https://developer.apple.com/videos/play/wwdc2019/409/ ,详细介绍了这种优化的原理。它通过识别编译单元中的跨函数相同代码序列来减少代码大小。重复的连续机器指令被外联成函数,原始代码序列被替换为外联函数实现相同机器代码的瘦身,但会增加函数调用栈的深度,因此对性能有一定影响。随着时间的推移,iPhone设备的硬件配置越来越高,这种性能损失是可以承受的。下面是一个官方的demo示例来说明-Oz优化的原理。hasse函数和kakutani函数有相同的机器指令,-Oz优化会生成OUTLINED_FUNCTION_O函数,hasse和kakutani指向该函数,从而降低包体积。

图片

图片

官方给出的收益是25%,从实践效果来看,编译优化参数 -Oz对Objective C++编写的代码有10%的体积收益,对C&C++有30%的体积收益。

2.2.3 C&C++编译优化

在iOS端,许多底层模块都是使用C和C++实现的,例如网络库、播放内核、视觉处理和端智能等。同时,这些模块也支持Android和iOS等多个平台。为了实现跨平台,这些模块通常采用Cmake和GN这两种编译工具。Cmake是一种常见的跨平台编译工具,其主要工作方式是通过读取CMakeLists.txt文件中的指令来生成相应的项目文件。而GN编译工具则是Generate Ninja的缩写,是一种替代Cmake的编译工具。它由Google开源,使用C++编写,主要实现交叉编译,并且可以指定输出平台目标。

无论是使用CMake还是GN,编译器的优化配置都是一样的。对于C++语言,cppFlags选项设置为’-Oz’,而对于C语言,cFlags选项设置为"-Oz"。

2.3 Swift编译优化

Swift编译优化有两个参数 Optimization Level 和Compliation Mode配合使用,配置路径为:Build Settings -> Swift Compiler - Code Generation。

图片

Optimization Level可选参数值如下所示:

图片

Optimize for Size的核心原理与前面介绍的GCC语言编译优化中的-Oz优化原理相同,都是通过对重复的连续机器指令进行外联并复用,从而降低编译产物的大小。不过,这种优化方式也会对性能产生一定影响,但在当前的硬件设备条件下,这种影响可以忽略不计。

Compliation Mode可选参数值如下所示:

图片

Optimize for Size[-Osize]和 Whole Module 同时开启会发挥最佳效果,从实践中可以看到它会减少10%的swift包体积大小。

2.4 LTO优化

LTO,即Link Time Optimization,是苹果官方提出的一种优化策略。根据官方解释,LTO是对整个程序代码进行的一种优化方式,是在LLVM编译器中在链接阶段进行跨模块间的优化。通过这种优化,编译器可以将部分函数内联化,去除未被调用的冗余代码,并进行整体优化,从而使程序运行得更快,这些优化措施可以有效降低程序的代码大小和提高程序执行效率。

配置路径为:Build Settings -> Apple Clang - Code Generation -> Link-Time Optimization,设置值为Incremental,需要在主工程以及要优化的Framework都开启。

图片

LTO的优化效果体现在以下三个方面:

1、函数内联化:

LTO可以将一些函数内联化,即在编译时将函数调用的代码直接嵌入到调用点,以减少函数调用的开销。这可以提高程序的执行效率。

2、去除无用代码:

LTO可以识别并去除程序中无用的代码,例如未使用的变量、函数和类等。这可以减少生成的二进制文件的大小,从而提高程序的加载速度和运行效率。

3、全局优化作用:

LTO对程序进行全局优化,可以识别并优化程序中不可能执行的代码分支。例如,如果一个if语句的某个分支永远不会被执行,LTO会将其从生成的二进制文件中移除,这可以提高程序的执行效率和代码质量。

LTO的负面影响包括:

1、降低Link Map的可读性:

Link Map是链接器生成的一种文件,它描述了目标文件之间的链接关系。在使用LTO时,由于进行了全局优化,生成的Link Map中的类名可能会以数字开头,如0.arm64.thinlto.o,这使得Link Map的可读性明显降低。如果需要阅读Link Map,需要先关闭LTO。

2、增加编译和链接时间:

开启LTO会导致编译和链接过程变得更加耗时。这是因为在链接阶段,LTO会进行大量的全局优化,这需要更多的计算资源和时间。对于线上打包或线下编译,这会导致更长的耗时。

2.5 剥离调试符号

图片

Symbols Hidden by Default用于设置符号默认可见性,如果设置为YES,XCode会把所有符号都定义为”private extern”,包大小会略有减少。动态库设置为NO,否则会有链接错误。

2.6 剥离符号表

配置路径为:Build Settings -> Strip Linked Product,选择属性值为YES。

图片

Strip Linked Product 来去除不需要的符号信息 ,去除了符号信息之后我们只能使用 dSYM 文件进行符号化,因此需要将 “Debug Information Format” 修改为 “DWARF with dSYM file”。

图片

Strip Debug Symbols During Copy与 Strip Linked Product 原理类似,主要是去除拷贝到项目中的第三方库的符号表。只需在Release 模式下设置为“YES”,而调试模式下仍为“NO”,否则无法对第三方库进行带有符号化的断点调试。

图片

2.7 剔除未引用的代码

配置路径为:Build Settings -> Dead Code Stripping,选择属性值为YES。

图片

该优化主要是在链接时将 C、C++、Swift 等静态语言无用代码从安装包剔除,但在处理Objective-C时无效,因为Objective-C 是动态语言,基于Runtime机制编译,静态编译判定为无用代码可能在运行时使用。

2.8 Asset优化

Asset编译优化配置路径为:Build Settings -> Asset Catalog Compiler -> Optimization。

图片

Optimization可选参数值如下所示:

图片

选择Space可以从一定程度优化包大小,收益较小。

2.9 C++减少虚函数的使用

减少虚函数的使用实际上可以减少虚函数表所占用的空间,从而减小程序包的大小。虚函数表是一种用于实现动态绑定的数据结构,其中存储了指向一个类的虚函数的指针。因此,减少虚函数的使用可以减少这些指针的数量,从而减小虚函数表的大小,最终减小程序包的大小。

2.10 三方SDK编译器瘦身

上面已经详细介绍了编译器的配置方式及其优化原理,但仅仅修改主工程的优化设置是不足以实现最佳效果的。为了达到最佳优化效果,每个框架(Framework)都必须按照上述配置进行相应的调整。这意味着在每个框架的构建配置中都需要启用优化,并将编译器参数设置为适当的值,以实现所需的具体优化效果。同时,还需要确保每个框架使用的库和依赖项也已正确配置,以确保它们能够与编译器优化一起正常工作。总之,为了使编译器优化真正发挥作用,需要对每个框架进行必要的配置和微调。

百度APP作为一款旗舰级应用,内部集成了众多第三方SDK,例如百度地图、百度网盘、度小满等。因此,需要推动这些第三方SDK业务方对其编译器进行优化以实现应用瘦身。这些优化可以包括但不限于图片优化、资源优化、代码优化等。通过这些优化措施,可以有效地减小应用的大小和提升其性能,使用户获得更好的使用体验。

三. 指令集架构优化

3.1 iPhone常用指令集架构

iPhone手机采用的都是低功耗的arm处理器,arm指令集架构分为armv6, armv7, armv7s arm64四种类型,保持向下兼容,如设备iphone13支持arm64,但是对于armv7也是支持的,但是armv7无法发挥iPhone13设备的更好的硬件属性。模拟器无法运行arm的指令集,运行的是x86指令集,32位处理器支持的是I386指令集,64位模拟器支持的是x86_64架构,不同设备支持的指令集架构如下所示。

图片

随着硬件设备的不断更新,早期设备(如 iPhone4、iPhone5 和 iPad)的市场占有率已经变得微不足道。因此,对于移动设备,我们只需要支持 arm64 架构即可。同理,对于模拟器,我们只需要支持 x86_64 架构,从包体积的优化的角度来看,目前我们的每个库只需要支持arm64和 x86_64 架构,其他架构没必要支持。

优化指令集架构可以减小上传到AppStore的包体积,但对用户下载的包大小没有优化效果。这是因为苹果的App Thinning机制根据不同设备型号的硬件架构生成不同的编译产物,因此不同设备的用户从AppStore下载的包也会有所不同。

3.2 指令集架构设置

  • Architectures选项,Build Settings -> Architectures,值为Standard architectures - $(ARCHS_STANDARD),在真机的编译下实质是(armv7和arm64)在模拟器的时候是(x86_64,i386,arm64)

  • Build Active Architectures Only选项,Build Settings -> Build Active Architectures Only,当其值为Yes时,表示只编译当前一个架构,真机的话一般是arm64, 模拟器是x86_64, 如果为No的时,那就是同时编译第一支持的架构;

  • Excluded Architectures选项,Build Settings -> Excluded Architectures,其值是要排除的架构,例如,如果将其设为arm64,表示产物里面没有arm64架构;

图片

3.3 去除无用架构

通过 lipo 命令从老的framework中的mach-o文件拆分出指定架构二进制文件,然后合并,最后用合并后的二进制文件替换老的framework的mach-o文件。

  • 用lipo -info命令查看framework包含的指令集架构信息,如下所示,AbcSDK.framework支持的指令集是x86_64、i386、arm64和armv7;
 lipo -info AbcSDK.framework/AbcSDK Architectures in the fat file: AbcSDK.framework/AbcSDK are: x86_64 i386 arm64 armv7
  • lipo命令抽取指定架构,如下所示,从AbcSDK.framework抽取出arm64架构,放在AbcArm64,抽取出x86_64架构,放在AbcArmX86_64。
lipo AbcSDK.framework/AbcSDK -thin arm64 -output AbcArm64lipo AbcSDK.framework/AbcSDK -thin x86_64 -output AbcArmX86_64

验证 AbcArm64和 AbcArmX86_64架构信息

lipo -info AbcArm64Non-fat file: AbcArm64 is architecture: arm64lipo -info AbcArmX86_64Non-fat file: AbcArmX86_64 is architecture: x86_64
  • lipo命令合并架构,合并AbcArm64和AbcArmX86_64,生成新的newAbc,按预期newAbc有两个架构x86_64和arm64,用lipo -info命令验证。
// 合成x86_64和arm64lipo -create AbcArm64 AbcArmX86_64 -output newAbclipo -info newAbcArchitectures in the fat file: newAbc are: x86_64 arm64
  • 替换原先的二进制文件,经过上面这些操作将有x86_64、i386、arm64和armv7四种指令集架构的AbcSDK.framework,瘦身变成了只支持x86_64和arm64两种指令集的组件。
mv -f newAbc AbcSDK.framework/AbcSDK

四. XCode升级优化

苹果公司一直致力于提高开发者的生产力,每年都会推出新版本的XCode,并对其进行大量的优化。在包体积方面,他们也采取了积极的措施。例如,在22年10月发布的Xcode 14,不仅具备全新的增强功能,更拥有更强大的并行编译能力,能够显著提高项目构建速度。同时,对包体积的优化也相当明显。

为了寻找Xcode 14优化包体积的具体技术点,看了很多WWCD资料,终于在官方文档《improve app size and runtime performance》找到答案,链接地址为https://developer.apple.com/videos/play/wwdc2022/110363/#,Xcode 14从以下三个方面进行了优化包体积:

  • Meesage send 函数调用占用从 12 bytes 降低到 8 bytes;

  • Retain and release 函数调用占用从 8 字节降低到 4 字节;

  • autorelease优化,移除自动释放省略中的 mov 指令,体积降低 4 bytes;

五. Swift内置动态库优化

自2014年WWDC发布以来,在苹果公司的强力推动下,Swift语言取得了显著的发展。其优点代表着iOS开发的发展趋势,随着使用率的不断提升,Swift有望最终取代Objective-C成为iOS开发的首选语言。目前,Swift已经成为各大公司和应用程序的必备开发语言,国内日活跃用户排名前二十的APP中,除了拼多多以外,其他公司都已经采用了Swift进行开发。

然而,在只要采用Swift语言开始开发,就会发现iPA包中新增了Swift系统库。这是因为对于低于iOS12.2的系统,没有内置的Swift系统库,因此XCode在打包生成iPA包时会一并包含Swift库,在iPA包的Frameworks动态库目录发现如下Swift系统库。

图片

更进一步来说,如果APP自带的WatchApp也使用了Swift语言,那么在Watch的动态库中还会有一份Swift系统库,这样iPA包中就会包含两份内置库。

优化方法非常简单,只需将APP支持的最低版本修改为12.2即可。因为12.2及以上的系统自带Swift系统库,不需要在APP内置。在百度APP包体积优化实践中发现,优化后iPA包体积减少30M+,30M动态库已经在ipa包不存在,提交AppStore后,从connect后台看数据,有如下收益:

  • iPhoneX 及以下的机型,如iPhoneX、iPhone8、iPhone7,安装包体积减少20M,下载包大小减少10M;

  • iPhoneX以上的机型,如iPhone11、iPhone12,iPhone13没收益,苹果自身做了优化,我们再做这个优化,价值不会体现;

对于百度APP来说,iPhoneX及以下机型的占比不到5%,但是提高APP支持的最低版本号会导致部分用户流失。综合考虑这两个因素,决定不采用Swift内置动态库的优化方案。

六. 总结

相比于代码优化、资源优化和图片优化,编译器优化在包体积优化中的投资回报率(ROI)是最高的。然而,编译器优化的影响范围也是最大的,因为每个库的编译器配置修改会影响该库的所有代码。因此,必须对优化质量进行严格控制。在百度APP的优化实践过程中,编译器方向的优化成功减少了30M的包体积,实现了自身库的全部收益,此外,按照体积排名的前15个三方SDK也全部实现了此收益。

本文系统介绍了百度APP的编译器优化方案,包括GCC语言编译优化、Swift编译优化、LTO优化、剥离调试符号、剥离符号表、剔除未引用的代码、Asset优化、C++虚函数优化和三方SDK编译器方向瘦身等多种手段。此外,还介绍了指令集架构优化、XCode升级优化和Swift内置动态库优化等其他优化方案。后续我们会针对其他优化详细介绍其原理与实现,敬请期待。

——END——

参考资料:

[1]gcc编译器配置:https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

[2]LTO使用方法:https://llvm.org/docs/LinkTimeOptimization.html

[3]XCode :https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW102

[4]What’s New in Clang and LLVM:https://developer.apple.com/videos/play/wwdc2019/409/

[5]XCode14介绍:https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes

[6]improve app size and runtime performance:https://developer.apple.com/videos/play/wwdc2022/110363/#

推荐阅读:

百度搜索内容HTAP表格存储系统

大模型时代,“人人可AI”的百度开发者平台长什么样?

数十万QPS,百度热点大事件搜索的稳定性保障实践

百度搜索万亿规模特征计算系统实践

通过Python脚本支持OC代码重构实践(三):数据项使用模块接入数据通路的适配

相关文章:

百度APP iOS端包体积50M优化实践(七)编译器优化

一. 前言 百度APP iOS端包体积优化系列文章的前六篇重点介绍了包体积优化整体方案、图片优化、资源优化、代码优化、无用类优化、HEIC图片优化实践和无用方法清理,图片优化是从无用图片、Asset Catalog和HEIC格式三个角度做深度优化;资源优化包括大资源…...

STM32-新建工程(标准库)

目录 STM32F10x新建工程(标准库) 移植文件夹 新建工程 添加启动文件和必需文件 在工程中加载新添加的文件 在工程中添加文件路径 在工程中添加main函数 添加lib库 添加必需文件 添加宏定义 点亮LED(标准库) STM32F10x新…...

Android集成科大讯飞语音识别与语音唤醒简易封装

目录 一、语音唤醒部分 1、首先在科大讯飞官网注册开发者账号 2、配置唤醒词然后下载sdk 3、选择对应功能下载 4、语音唤醒lib包全部复制到工程目录下 5、把语音唤醒词文件复制到工程的assets目录 6、复制对应权限到AndroidManifest.xml中 7、唤醒工具类封装 二、语音识…...

【Linux】telnet命令使用

telnet命令 telnet命令用于使用telnet协议与另一台主机进行通信。如果在没有主机参数的情况下调用telnet,它将进入命令模式,由其提示(telnet>)指示。在这种模式下,它接受并执行下面列出的命令。如果使用参数调用它…...

VCG 标记使用(BitFlags)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 对于网格的每个单形,我们都有一个称为BitFlags的组件,该组件存储固定大小的32位向量,用于各种需求。管理这些标志的相关类:vcg::tri::UpdateFlags与vcg::tri::UpdateSelection。主要的标记有:删除标记、边界标记…...

Pandas中的Series(第1讲)

Pandas中的Series(第1讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔…...

从手工测试进阶中高级测试?如何突破职业瓶颈...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、手工测试如何进…...

【链表Linked List】力扣-114 二叉树展开为链表

目录 题目描述 解题过程 官方题解 题目描述 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单链表应…...

Go (一) 基础部分4 -- 文件处理

一、文件基本介绍 1.1、打开一个文件 基本介绍:打开一个文件用于读取,如果操作成功,返回的文件对象的方法可用于读取文件数据。如果出错,错误底层类型是"*.PathError" func Open(name string) (*File, error) name stri…...

集合03 Collection (List) - Java

List ArrayListArrayList注意事项ArrayList底层操作机制-源码分析(重点) VectorVector基本介绍 ——Vector和ArrayList比较Vector底层结构和源码分析 LinkedList基本介绍LinkedList的底层结构和操作机制LinkedList的增删改查 ——LinkedList和ArrayList比…...

国产化软件突围!怿星科技eStation产品荣获2023铃轩奖“前瞻优秀奖”

11月11日,2023中国汽车供应链峰会暨第八届铃轩奖颁奖典礼在江苏省昆山市举行。怿星科技凭借eStation产品,荣获2023铃轩奖“前瞻智能座舱类优秀奖”,怿星CEO潘凯受邀出席铃轩奖晚会并代表领奖。 2023铃轩奖“前瞻智能座舱类优秀奖” 铃轩奖&a…...

如何解决Redis热Key问题?

Redis热点key是指访问频率较高的key,当大量的请求集中在一个或少数几个热点key上时,会导致这些key所在的Redis节点的CPU、内存和网络带宽等资源被大量消耗,影响Redis集群的整体性能和稳定性。 热点Key带来的问题 Redis节点负载过高&#xff1…...

react Hooks之useId

当我们在编写React组件时,有时需要为元素生成唯一的ID。这种情况经常出现在表单元素、标签和用于无障碍性的目的上。React提供了一个名为useId的自定义Hook,它可以帮助我们生成唯一的ID。 1、作用: 用于生成一个唯一的 ID。这个 ID 可以用于…...

2023年全球软件开发大会(QCon广州站2023)-核心PPT资料下载

一、峰会简介 本次峰会包含:泛娱乐时代的边缘计算与通讯、稳定性即生命线、下一代软件架构、出海的思考、现代数据架构、AGI 与 AIGC 落地、大前端技术探索、编程语言实战、DevOps vs 平台工程、新型数据库、AIGC 浪潮下的企业出海、AIGC 浪潮下的效能智能化、数据…...

MicroSD 卡 使用读卡器 读取速度测试

设备 - - 电脑为m.2固态硬盘 usb口为USB3.2 gen2接口(即支持1GB/s的接口) cpu: amd3600 测试方案1 直接MicroSD卡放入读卡器测试 38MB/s 从sd卡复制到本地C盘 测试方案2 MicroSD卡使用闪迪的SD卡套套上之后一起插入读卡器 76MB/s 从sd卡复制到本地C盘...

Selenium+Unittest+HTMLTestRunner框架更改为Selenium+Pytest+Allure(一)

背景:之前的框架,Selenium是3.x版本,现在更新到4.15版本后,一些写法如find_element_by_xxx 不再支持,改为find_element(By.xxx)的方式,同时由于Unittest不如Pytest在执行方面灵活(比如只执行冒烟…...

LoRA(Low-Rank Adaptation)

LoRA(Low-Rank Adaptation) LoRA(Low-Rank Adaptation)是一种针对深度学习模型的参数调整方法,特别适用于大型预训练模型如GPT-3或BERT。它通过在模型的原有权重上添加低秩(low-rank)矩阵&…...

【银行测试】第三方支付功能测试点+贷款常问面试题(详细)

前言 1、第三方支付功能测试点 支付流程: 我们在测试一个功能时,需要先了解一下这个逻辑,而订单支付逻辑普遍都会有以下内容: 1)创建本地唯一订单号; 2)去调用支付,在支付平台生…...

前端:HTML+CSS+JavaScript实现轮播图2

前端:HTMLCSSJavaScript实现轮播图2 1. 和之前版本的区别2. 实现原理3. 针对上述的改进3. 参考代码 1. 和之前版本的区别 之前发布的那篇关于轮播图的文章在这:前端:HTMLCSSJavaScript实现轮播图,只能说存在问题吧!比…...

使用条件格式突出显示单元格数据-sdk

使用条件格式突出显示单元格数据 2023 年 12 月 6 日 根据数据值将视觉提示应用于特定单元格、行或列,从而更轻松地识别模式和趋势。 网格中的条件格式允许用户根据单元格或范围包含的数据将视觉样式应用于单元格或范围。它通过以数据驱动的方式突出显示关键值、异常…...

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

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

云计算——弹性云计算器(ECS)

弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性&#xf…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

JVM 内存结构 详解

内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: ​ 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...