android-ndk开发(9): undefined reference to `__aarch64_ldadd4_acq_rel` 报错分析
1. 概要
基础库 libbase.a 基于 android ndk r18b 编译, 被算法库 libfoo.so 和算法库 libbar.a 依赖, 算法库则分别被 libapp1.so 和 libapp2.so 依赖。
libapp1.so 的开发者向 libfoo.so 的开发者反馈了链接报错:
error: undefined symbol: __aarch64_ldadd4_acq_rel
libapp2.so 的开发者向 libbar.a 的开发者反馈了链接报错:
undefined reference to `__aarch64_ldadd4_acq_rel'
libapp2.so 的开发者通过升级 NDK 版本解决了问题。 由于没有 libbar.a 和 libapp2.so 对应的 ndk 详细版本和最小复现代码,
在搜索引擎上以 “undefined reference to `__aarch64_ldadd4_acq_rel’” 为关键字找到相似案例并分析, 确定了升级 NDK 能消除上述链接报错的原因。
2. opencv issue 24856
2.1 报错描述
https://github.com/opencv/opencv/issues/24856 (参考链接[1])
用户 kevinzezel 在 android 平台, 使用 OpenCV 4.9.0 + ncnn, 遇到链接报错, 而使用 OpenCV 4.5.5~4.8.0 时没有报错。 报错信息是:
undefined reference to `__aarch64_ldadd8_acq_rel’
opencv 维护人员 asmorkalov 提议让用户开启 -mno-outline-atomics
编译选项, 用户 kevinzezel 反馈说 ndk 21.4.7075529 不支持这一选项.
catboost 维护者 andrey-khropov 说, 很可能是 clang 13.0.0-rc1 版本引入的问题, 对应到 commit: https://github.com/llvm/llvm-project/commit/c5e7e649d537067dec7111f3de1430d0fc8a4d11 (参考链接[2])。 解决方法: 要么使用低版本 clang (< 13.0.0), 要么用高版本 clang 但是传入 -mno-outline-atomics
选项。
用户 bvnp43 说, 升级 ndk 到 26.2.11394342 后问题解决。
用户 chenyan-master 说, 编译 V8 时遇到类似问题 (ndk 22.0.7026061), 升级 ndk 版本解决了。
2.2 分析
ncnn 版本没有被提及, 大概率是没有变化。 OpenCV 从 4.8.0 到 4.9.0 引发了链接报错, 猜测是因为 OpenCV 官方编译 android sdk 时更换了 ndk 版本, 而 ndk 版本和 clang 版本有一定的对应关系。
https://stackoverflow.com/questions/53385892/find-the-ndk-version-used-for-building-opencv-android-native-libraries (参考链接[3]) 给出了从 OpenCV 静态库反推编译他它的 ndk 版本、 ndk 里的 clang 版本的方法:
strings libopencv_core.a | ag "Android NDK"
strings libopencv_core.a | ag "C++ Compiler"
opencv | ndk | clang |
---|---|---|
4.9.0 | 25.2.9519653 | 14.0.7 |
4.8.0 | 18.1.5063045 | 7.0.2 |
ndk 和 clang 的版本对应关系, 则通过 clang++ --version
确定, e.g.
D:/soft/android-ndk/r21e/toolchains/llvm/prebuilt/windows-x86_64/bin/clang++ --version
ndk 的数字形式的 x.y.z
版本, 和字母形式的版本如 r21e
, 则通过 <ndk-目录>/source.properties
确定, 例如 ndk-r21e:
Pkg.Desc = Android NDK
Pkg.Revision = 21.4.7075529
整理后的 ndk 和 clang 版本对应关系如下:
ndk | ndk | clang |
---|---|---|
r28b | 28.1.13356709 | 19.0.0 |
r27c | 27.2.12479018 | 18.0.3 |
r26d | 26.3.11579264 | 17.0.2 |
r25c | 25.2.9519653 | 14.0.7 |
r25b | 25.1.8937393 | 14.0.6 |
r24 | 24.0.8215888 | 14.0.1 |
r23c | 23.2.8568313 | 12.0.9 |
r22b | 22.1.7171670 | 11.0.5 |
r21e | 21.4.7075529 | 9.0.9 |
r21b | 21.1.6352462 | 9.0.8 |
r20b | 20.1.5948944 | 8.0.7 |
r19c | 19.2.5345600 | 8.0.2 |
r18b | 18.1.5063045 | 7.0.2 |
2.3 结论
根据前一节的两个表格知道:
opencv 4.8.0 是用 ndk-r18b 编译, 对应的编译器是 clang 7.0.2
opencv 4.9.0 是基于 ndk-r25c 编译, 对应的编译器是 clang 14.0.7
ndk 没有使用过 clang 13.0.0 版本, 是从 clang 12.0.9 (ndk-r23c) 直接升级到 clang 14.0.1 (ndk-r24)
编译选项 -moutline-atomics
和 -mno-outline-atomics
是在 clang 13.0.0 引入的, ndk-r21e 使用的是 clang 9.0.9, 因此会提示“不支持 -mno-outline-atomics 选项”.
3. libgcc.a 的类似报错: __aarch64_swp4_acq_rel
3.1 问答描述
https://stackoverflow.com/questions/75045297/libgcc-linker-error-hidden-symbol-aarch64-swp1-acq-rel-in-libgcc-a-is-referen (参考链接[4]) 给出了 gcc aarch64 下的链接报错, __aarch64_swp4_acq_rel
符号找不到, 这和 opencv issue 24856 报错很像, 符号名字结尾略有差别。
用户 Bill Cong 的回答给出了很好的最小复现: 定义和使用 std::atomic<int>
变量, 使用 -O1
优化等级, 在不同编译器下查看对应的反汇编,
#include <atomic>std::atomic<int> ai(3);int main() {return ai.exchange(5);
}
-
ARM64 gcc 9.3, 不会生成
__aarch64_swp4_acq_rel
汇编指令 -
ARM64 gcc 10.2, 会生成
__aarch64_swp4_acq_rel
汇编指令 -
ARM64 gcc 10.2, 传入
-mno-outline-atomics
选项, 不会生成__aarch64_swp4_acq_rel
汇编指令
https://godbolt.org/z/ssK3GGaoE (参考链接[5])
3.2 分析
-m-outline-atomics
编译选项是哪个版本引入 GCC 的? 含义是什么?
https://stackoverflow.com/questions/65239845/how-to-enable-mno-outline-atomics-aarch64-flag (参考链接[6]) 提到, gcc 9.4 开始提供 -m-outline-atomics
编译选项。
https://gcc.gnu.org/gcc-9/changes.html (参考链接[7]) 则证实了这一点
The option -moutline-atomics has been added to aid deployment of the Large System Extensions (LSE) on GNU/Linux systems built with a baseline architecture targeting Armv8-A. When the option is specified code is emitted to detect the presence of LSE instructions at run time and use them for standard atomic operations. For more information please refer to the documentation.
有人在编译 Android FFmpeg 5.0 后的运行阶段遇到报错 (参考链接 [8])
dlopen failed: cannot locate symbol “__aarch64_ldadd8_acq_rel”
参考链接[9] 则给出了关于 LSE 的进一步解释:
Out-of-line Atomics for LSE deploymentAArch64 Large System Extensions (LSE) were introduced in Armv8.1-A. These provide more efficient atomic instructions for large multi-core systems.LLVM 12 adds support for a new flag ‘-moutline-atomics', which detects at runtime whether the processor supports LSE. It then uses these new atomic instructions if possible, falling back to Armv8.0-A LL/SC loops on processors without LSE support. This option behaviour mirrors similar support available within GNU family of projects. We are working towards making this option enabled by default in the upcoming LLVM13 release.
即:
Armv8.1-A 引入了 LSE(大系统扩展), 用于在多核系统上提供更高效的原子指令。 LLVM12 添加了 -moutline-atomics
编译选项, 在运行时检查处理器是否支持 LSE, 如果存在则使用, 不存在则回退到 Arm8.0-A 的 LL/SC。 这个选项在 GNU 家族的工程中也提供了(就是 GCC)。 在 LLVM13 中 -moutline-atomics
选项则被默认开启。
clang 12.0.1 开始,添加了 -moutline-atomics
和 -mno-outline-atomics
选项(参考链接 [10]):
而根据参考链接 [11], LLVM 的开发者们讨论提到, gcc 9.3.1 开始提供了 LSE 的支持, 并在 gcc 10.1 默认开启:
Outline atomics were added with gcc 9.3.1 and turned on by default in gcc 10.1
3.3 结论
-moutline-atomics
编译选项表示开启 LSE (Large System Extension), 意思是在运行时提供更高效率的原子操作, 在 Arm8.1-a 上起作用, 在 Arm8.0 上回退到原本的原子操作处理上。 -mno-outline-atomics
则关闭这一编译选项。
-moutline-atomics
是在 gcc 9.3.1 版本开始提供, 在 clang 12.0.1 版本开始提供, 但都是默认不开启状态。 在 gcc 10.1 版本和 clang 13.0.0-rc1 版本中默认开启了 -moutline-atomics
编译选项。
4. __aarch64_ldadd4_acq_rel
和 __aarch64_swp4_acq_rel
指令, 对应的 C/C++ 代码是什么?
4.1 C++11
基于参考链接[5], 很容易构造如下代码, 并在 armv8-a clang 13.0.0 生成 __aarch64_ldadd4_acq_rel
指令 (仍然使用 -O1
):
https://godbolt.org/z/T7vzesfxd (参考链接[12])
#include <atomic>
std::atomic<int> ai(3);int main() {ai.fetch_add(1, std::memory_order_acquire);return ai.exchange(5);
}
汇编如下, 生成了 __aarch64_ldadd4_acq
和 __aarch64_swp4_acq_rel
指令.
main:stp x29, x30, [sp, #-32]!str x19, [sp, #16]mov x29, spadrp x19, aiadd x19, x19, :lo12:aimov w0, #1mov x1, x19bl __aarch64_ldadd4_acqmov w0, #5mov x1, x19bl __aarch64_swp4_acq_relldr x19, [sp, #16]ldp x29, x30, [sp], #32retai:.word 3
4.2 C++03: ncnn XADD 宏的实现
ncnn 库使用 C++03 编译, 在大部分平台使用到了 __atomic_fetch_add
, __sync_fetch_add_add
等类似的 builtin 函数:
https://github.com/Tencent/ncnn/blob/20250503/src/allocator.h#L105-L151 (参考链接[13])
#if NCNN_THREADS
// exchange-add operation for atomic operations on reference counters
#if defined __riscv && !defined __riscv_atomic
// riscv target without A extension
static NCNN_FORCEINLINE int NCNN_XADD(int* addr, int delta)
{int tmp = *addr;*addr += delta;return tmp;
}
#elif defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
// atomic increment on the linux version of the Intel(tm) compiler
#define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd(const_cast<void*>(reinterpret_cast<volatile void*>(addr)), delta)
#elif defined __GNUC__
#if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
#ifdef __ATOMIC_ACQ_REL
#define NCNN_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL)
#else
#define NCNN_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4)
#endif
#else
#if defined __ATOMIC_ACQ_REL && !defined __clang__
// version for gcc >= 4.7
#define NCNN_XADD(addr, delta) (int)__atomic_fetch_add((unsigned*)(addr), (unsigned)(delta), __ATOMIC_ACQ_REL)
#else
#define NCNN_XADD(addr, delta) (int)__sync_fetch_and_add((unsigned*)(addr), (unsigned)(delta))
#endif
#endif
#elif defined _MSC_VER && !defined RC_INVOKED
#define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta)
#else
但查看 ncnn 库文件的反汇编, 例如 ncnn-20250503-android-shared.zip, 并没有找到 __atomic_fetch_add
指令:
aarch64-linux-android-objdump -d ncnn-20250503-android-shared/arm64-v8a/lib/libncnn.so | ag '__aarch64_ldadd4_acq'
原因是 ncnn 的 CMakeLists.txt 里主动开启了 -mno-outline-atomics
:
https://github.com/Tencent/ncnn/blob/master/src/CMakeLists.txt#L648-L652
if(ANDROID_NDK_MAJOR AND (ANDROID_NDK_MAJOR GREATER_EQUAL 23))# llvm 12 in ndk-23 enables out-of-line atomics by default# disable this feature for fixing linking atomic builtins issue with old ndktarget_compile_options(ncnn PRIVATE -mno-outline-atomics)endif()
(此处存疑, 可能是 ncnn 注释 typo, 个人理解是 llvm 13 和 ndk-r25 默认开启 out-of-line atomics; nihui: 使用 __aarch64_ldadd4_acq_rel后,树莓派上会 crash,链接器会有undefined行为, 因此 ncnn 未开启 )
4.3 自行构造
构造了简单直白的一份 MY_XADD 宏的实现: https://godbolt.org/z/x567r5Gfr (参考链接[14])
#if _MSC_VER
# include <windows.h>
# define MY_XADD(addr, delta) ::InterlockedExchangeAdd((volatile long*)(addr), delta)
#elif __linux__
# define MY_XADD __sync_fetch_and_add
#endifint main() {int refcount = 1;return MY_XADD(&refcount, -1);
}
使用 -O1 优化等级, 在各个编译器下结果如下:
- armv8-a clang 12.0.0: 生成 “平凡的” ldaxr, stlxr 指令
- armv8-a clang 13.0.0: 生成
__aarch64_ldadd4_acq_rel
指令 - armv8-a clang 13.0.0, 生成
-mno-outline-atomics
编译选项: 生成 “平凡的” ldaxr, stlxr 指令 - arm64 msvc v19.43 VS17.13: 生成 “平凡的” ldaxr, stlxr 指令
- x86-64 gcc 15.1: 生成
lock xadd
指令
ldaxr
指令的解释:
Load-Acquire Exclusive Register derives an address from a base register value, loads a 32-bit word or 64-bit doubleword from memory, and writes it to a register. The memory access is atomic. The PE marks the physical address being accessed as an exclusive access. This exclusive access mark is checked by Store Exclusive instructions. See Synchronization and semaphores. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release. For information about memory accesses, see Load/Store addressing modes.
Load-Acquire Exclusive Register 指令根据基址寄存器的值计算地址,从内存中读取一个 32 位字(word)或 64 位双字(doubleword),并写入目标寄存器。此内存访问是原子的。处理单元(PE)会将正在访问的物理地址标记为“独占访问”,该标记稍后由 Store Exclusive 指令检查。详见“同步与信号量”一节。
此外,该指令具有 Load-Acquire/Store-Release 描述的内存排序语义。有关内存访问的更多信息,请参阅“装载/存储寻址模式”。
stlxr
指令的解释:
Store-Release Exclusive Register stores a 32-bit word or a 64-bit doubleword to memory if the PE has exclusive access to the memory address, from two registers, and returns a status value of 0 if the store was successful, or of 1 if no store was performed. See Synchronization and semaphores. The memory access is atomic. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release. For information about memory accesses, see Load/Store addressing modes.
Store-Release Exclusive Register(存储-释放独占寄存器)指令在处理元(PE)对某内存地址拥有独占访问权限时,可将两个寄存器中的数据写入内存:写入 32 位字或 64 位双字。如果写入成功,指令返回状态值 0;若未执行写入,则返回状态值 1。参见“同步与信号量”。
该内存访问是原子的。此指令还具备与“Load-Acquire / Store-Release”描述一致的内存排序语义。关于内存访问的详细说明,请参阅“加载/存储寻址模式”。
4.4 分析 libbase.a 库
前一节构造的最小复现代码,MY_XADD
宏的定义和使用, 对应到文章开头 libbase.a
基础库中的 BASE_XADD
宏实现:
base/atomic.hpp
#if _MSC_VER
# include <windows.h>
# define BASE_XADD(addr, delta) ::InterlockedExchangeAdd((volatile long*)(addr), delta)
#elif __linux__
# define BASE_XADD __sync_fetch_and_add
#endif
base/atomic.hpp
被不同的编译器处理:
-
ndk-r18: clang 7.0.2, 编译出 libbase.a
-
ndk-r25c 或更高版本: clang >= 14.0.7, 编译出 libfoo.so 和 libbar.a
猜测 libapp1.so
和 libapp2.so
不会接触到 base/atomic.hpp
, 并且这两个 app so 是用 ndk-r24 或更低版本编译。 这样一来, libfoo.so 和 libbar.a 的编译过程产生了非预期的 __aarch64_ldadd4_acq_rel
汇编指令, 下游的集成人员遇到链接报错, 集成人员换到 clang >= 13.0.0 的 ndk 版本, 也就是 ndk >= r25, 就避免了报错。
另一种改法: 是 libfoo.so
和 libbar.a
的构建过程, 做类似于 ncnn 的配置, 判断 ndk >= r24 并添加 -mno-outline-atomics
编译选项。
5. 总结
gcc 9.3.1 和 clang 12.0.1 添加了 -moutline-atomics
编译选项, 用来开启 LSE (Large System Extension), 用于在 Armv8.1-a 上改善多核情况下的原子操作的性能。
这个选项在 gcc 9 和 clang 12 是默认不开启的, 相当于是默认开启了 -mno-outline-atomics
。
从 gcc 10 和 clang 13 开始默认开启 -moutline-atomics
编译选项。
ndk 版本和 clang 版本有对应的关系, clang >= 13 对应到 ndk >= r24。
当使用 clang >= 13 (ndk >= r24) 编译了带有 __sync_fetch_and_add
(C/C++ Builtin) 或 C++11 的 std::atomic<T>
的代码, 例如 opencv/ncnn 中的 XADD
的实现, 会生成 __aarch64_ldadd4_acq_rel
等 LSE 相关的汇编指令, 这样的二进制被 clang < 13 (ndk < r24) 的编译器做链接, 会遇到 __aarch64_ldadd4_acq_rel
符号找不到的问题。
当遇到上述报错, 可以对齐编译器版本到 clang >= 13 (ndk >= r24), 或手动指定 -mno-outline-atomics
选项。
如果是 clang 12 或 gcc 9 编译器, 但传入了 -moutline-atomics
选项, 也会发生类似的链接报错, 处理方式同前。
当然, 考虑到 ndk-r24 没有 ndk-24b, ndk-r24c 等版本, 建议用 ndk >= r25c 的版本。
References
- [1] https://github.com/opencv/opencv/issues/24856
- [2] https://github.com/llvm/llvm-project/commit/c5e7e649d537067dec7111f3de1430d0fc8a4d11
- [3] https://stackoverflow.com/questions/53385892/find-the-ndk-version-used-for-building-opencv-android-native-libraries
- [4] https://stackoverflow.com/questions/75045297/libgcc-linker-error-hidden-symbol-aarch64-swp1-acq-rel-in-libgcc-a-is-referen
- [5] https://godbolt.org/z/ssK3GGaoE
- [6] https://stackoverflow.com/questions/65239845/how-to-enable-mno-outline-atomics-aarch64-flag
- [7] https://gcc.gnu.org/gcc-9/changes.html
- [8] https://juejin.cn/post/7149468268674154510
- [9] https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/llvm12-for-arm
- [10] https://releases.llvm.org/12.0.1/tools/clang/docs/ReleaseNotes.html
- [11] https://reviews.llvm.org/D93585
- [12] https://godbolt.org/z/T7vzesfxd
- [13] https://github.com/Tencent/ncnn/blob/20250503/src/allocator.h#L105-L151
- [14] https://godbolt.org/z/x567r5Gfr
相关文章:
android-ndk开发(9): undefined reference to `__aarch64_ldadd4_acq_rel` 报错分析
1. 概要 基础库 libbase.a 基于 android ndk r18b 编译, 被算法库 libfoo.so 和算法库 libbar.a 依赖, 算法库则分别被 libapp1.so 和 libapp2.so 依赖。 libapp1.so 的开发者向 libfoo.so 的开发者反馈了链接报错: error: undefined symb…...
Java 对象克隆(Object Cloning)详解
Java 对象克隆(Object Cloning)详解 对象克隆是指创建一个对象的精确副本,Java 提供了两种克隆方式:浅克隆(Shallow Clone)和深克隆(Deep Clone)。下面从实现原理、使用场景到注意事项全面解析。 一、克隆的基本概念 1. 为什么要克隆? 需要对象副本时避免修改原始对…...
Asp.Net Core IIS发布后PUT、DELETE请求错误405
一、方案1 1、IIS管理器,处理程序映射。 2、找到aspNetCore,双击。点击请求限制...按钮,并在谓词选项卡上,添加两者DELETE和PUT. 二、方案2 打开web.config文件,添加<remove name"WebDAVModule" />&…...
AI搜索的未来:技术纵深发展与关键突破路径
一、模型架构的颠覆性重构 1、混合专家系统(MoE)的工程化突破 动态路径选择:Google Gemini 1.5 Pro采用MoE架构,其门控网络(Gating Network)通过实时计算输入token与128个专家模型的余弦相似度,动态分配计算资…...
从艾米・阿尔文看 CTO 的多面特质与成长路径
在《对话 CTO,驾驭高科技浪潮》的开篇,艾米・阿尔文的经历如同一扇窗,为我们展现出首席技术官丰富而立体的世界。通过深入探究这一章节,我们能洞察 CTO 在技术领域前行所需的特质、面临的挑战,以及成长发展的脉络。 一…...
记录阿里云服务器搭建FTP服务器的注意事项
在阿里云服务器上(centos)系统,使用vsftpd搭建了一台FTP服务器。 搭建过程中,也留意到了操作防火墙放行端口。但搭建成功后,仍无法访问。 问题是:还需要在阿里云控制台设置一下。 在此记录。 1、登陆账…...
第二章 Logback的架构(三)
Logger, Appenders 和 Layouts 工作原理概述 在介绍了基本的Logback组件之后,我们现在可以描述当用户调用Logger的打印方法时,Logback框架日志请求的执行步骤。 现在让我们分析一下当用户调用名为com.wombat的Logger的info()方法时,Logback…...
第十六届蓝桥杯大赛软件赛C/C++大学B组部分题解
第十六届蓝桥杯大赛软件赛C/C大学B组题解 试题A: 移动距离 问题描述 小明初始在二维平面的原点,他想前往坐标(233,666)。在移动过程中,他只能采用以下两种移动方式,并且这两种移动方式可以交替、不限次数地使用: 水平向右移动…...
服务器数据恢复—Linux操作系统服务器意外断电导致部分文件丢失的数据恢复
服务器数据恢复环境&故障: 一台安装linux系统的服务器意外断电。管理员重启服务器后进行检测,发现服务器上部分文件丢失。管理员没有进行任何操作,直接将服务器正常关机并切断电源。 服务器数据恢复过程: 1、北亚企安数据恢复…...
技术视界 | 青龙机器人训练地形详解(三):复杂地形精讲之台阶
在前两篇中,我们依次讲解了“如何创建一个地形”以及“如何将地形添加到训练环境中”。从基础出发,逐步构建机器人可交互的三维仿真环境。在机器人强化学习训练中,地形的复杂度决定了策略的泛化能力,仅靠 jump_plat 和 jump_pit 等…...
Android 位掩码操作(和~和|的二进制运算)
在 Android 开发中,位掩码操作通过二进制位的逻辑运算实现高效的状态管理。以下以 &(与)、|(或)和 ~(非)运算符为例,详细说明其二进制计算过程: 一、按位与 & 运…...
【JS逆向基础】前端基础-HTML与CSS
1,flask框架 以下是一个使用flask框架写成的serve程序 # noinspection PyUnresolvedReferences #Flash框架的基本内容from flask import Flask app Flask(__name__)app.route(/index) def index():return "hello index"app.route(/login) def login():re…...
高速供电,一步到位——以太联-Intellinet 9口2.5G PoE++非管理型交换机_562140:网络升级的理想之选
在数字化浪潮席卷全球的当下,高速稳定的网络连接已成为企业运营、家庭娱乐以及各类智能场景正常运转的基石。从企业办公场景中员工对高效协同办公的追求,到家庭环境里用户对流畅高清视频、在线游戏的渴望,再到智慧城市建设中大量监控设备、无…...
rom定制系列------红米note12 5G版miui14修改型号root版 原生安卓14批量线刷固件 原生安卓15等
红米Note 12 5G机型也称为 Note 12R Pro,机型代码:sunstone 高通骁龙4 Gen1八核处理器适用于以下型号的小米机型:22111317G, 22111317I, 22101317C miui14稳定版 14.0.10安卓13固件 根据客户需求,采用miui最后一个版本。修改以…...
机器学习 数据集
数据集 1. scikit-learn工具介绍1.1 scikit-learn安装1.2 Scikit-learn包含的内容 2 数据集2.1 sklearn玩具数据集介绍2.2 sklearn现实世界数据集介绍2.3 sklearn加载玩具数据集示例1:鸢尾花数据示例2:分析糖尿病数据集 2.4 sklearn获取现实世界数据集示…...
JVM运行时数据区域(Run-Time Data Areas)的解析
# JVM运行时数据区域(Run-Time Data Areas)的解析 欢迎来到我的博客:TWind的博客 我的CSDN::Thanwind-CSDN博客 我的掘金:Thanwinde 的个人主页 本文参考于:深入理解Java虚拟机:JVM高级特性与最佳实践 本文的JVM均…...
python基础:序列和索引-->Python的特殊属性
一.序列和索引 1.1 用索引检索字符串中的元素 # 正向递增 shelloworld for i in range (0,len(s)):# i是索引print(i,s[i],end\t\t) print(\n--------------------------) # 反向递减 for i in range (-10,0):print(i,s[i],end\t\t)print(\n--------------------------) print(…...
在k8s中,如何实现服务的访问,k8s的ip是变化的,怎么保证能访问到我的服务
在K8S中,Pod的IP动态变化确实无法直接通过固定IP限制访问,但可以通过标签(Label)、服务(Service)和网络策略(NetworkPolicy)的组合,实现动态身份识别的访问控制ÿ…...
用NVivo革新企业创新:洞悉市场情绪,引领金融未来
在当今快速变化的商业环境中,理解市场和客户的情感脉动是企业成功的关键。尤其在金融行业,无论是评估经济走势、股票市场波动,还是洞察消费者信心,精准把握隐藏在新闻报道、社交媒体和消费者反馈中的情感倾向至关重要。而NVivo这款…...
如何使用极狐GitLab 软件包仓库功能托管 helm chart?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 软件包库中的 Helm charts (BASIC ALL) WARNING:Helm chart 库正在开发中,由于功能有限,尚未准备好用…...
Qt 通过控件按钮实现hello world + 命名规范(7)
文章目录 使用编辑框来完成 hello world通过编辑图形化界面方式通过纯代码方式 通过按钮的方式来创建 hello world通过编辑图形化界面方式通过纯代码方式 总结Qt Creator中的快捷键如何使用文档命名规范 简介:这篇文章着重点并不在于创建hello world程序,…...
uniapp index.html怎么改都不生效
打开 manifest.json index.html 模板路径默认为空,所以你改的 index.html 是没用的,uni-app 根本没用这个模板 设置模板后就会生效了...
ABP vNext + gRPC 实现服务间高速通信
ABP vNext gRPC 实现服务间高速通信 💨 在现代微服务架构中,服务之间频繁的调用往往对性能构成挑战。尤其在电商秒杀、金融风控、实时监控等对响应延迟敏感的场景中,传统 REST API 面临序列化负担重、数据体积大、通信延迟高等瓶颈。 本文…...
【JAVA】十三、基础知识“接口”精细讲解!(三)(新手友好版~)
目录 1. Object类 1.1 Object的概念 1.2 Object例子 2. toString 2.1 toString的概念 2.2 为什么要重写toString 2.3 如何重写toString 3. 对象比较equals方法 3.1 equals( ) 方法的概念 3.2 Object类中的默认equals实现 3.3 如何正确重写equals方法 4. hashCode方…...
每周靶点分享:Angptl3、IgE、ADAM9及文献分享:抗体的多样性和特异性以及结构的新见解
本期精选了《脂质代谢的关键调控者Angptl3》《T细胞活化抑制因子VISTA靶点》《文献分享:双特异性抗体重轻链配对设计》三篇文章。以下为各研究内容的概述: 1. 脂质代谢的关键调控者Angptl3 血管生成素相关蛋白3(Angptl3)是血管生…...
网络协议之DHCP和PXE分析
写在前面 本文看下DHCP和PXE相关内容。 1:正文 不知道你自己手动配置过IP地址没有,在Linux的环境中可以通过如下的命令们来进行配置: $ sudo ifconfig eth1 10.0.0.1/24 $ sudo ifconfig eth1 up以及:$ sudo ip addr add 10.0…...
SSH 服务部署指南
本指南涵盖 OpenSSH 服务端的安装、配置密码/公钥/多因素认证,以及连接测试方法。 适用系统:Ubuntu/Debian、CentOS/RHEL 等主流 Linux 发行版。 1. 安装 SSH 服务端 Ubuntu/Debian # 更新软件包索引 sudo apt update# 安装 OpenSSH 服务端 sudo apt i…...
表达式求值(算法题)
#include <bits/stdc.h> // 引入常用头文件 using namespace std;stack<int> num; // 存储操作数的栈 stack<char> op; // 存储运算符的栈/* 执行一次运算操作:1. 从num栈弹出两个操作数(n2先弹出,作为右操作数)2. 从op栈弹出运算符…...
IO流--13--MultipartFile
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 MultipartFile1. 概述2. 常用方法解析2.1 getName方法2.2 getOriginalFileName方法2.3 getContentType方法2.4 isEmpty方法2.5 getSize方法2.6 getBytes方法2.7 get…...
leetcode 242. Valid Anagram
题目描述 因为s和t仅仅包含小写字母,所以可以开一个26个元素的数组用来做哈希表。不过如果是unicode字符,那就用编程语言自带的哈希表。 class Solution { public:bool isAnagram(string s, string t) {int n s.size();if(s.size() ! t.size())return …...
内核态函数strlcpy及strscpy以及用户态函数strncpy
一、背景 编写C程序时有一类看似简单实则经常暗藏漏洞的问题就是字符串的处理。对于字符串的处理,常用的函数如strcpy,sprintf,strcat等,这些函数的区别无外乎就是处理\0结尾相关的逻辑。字符串的长度有时候并不能很好确定&#…...
Matlab 车辆四自由度垂向模型平稳性
1、内容简介 Matlab221-车辆四自由度垂向模型平稳性 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略基于Simulink的汽车平顺性仿真_1_杜充 基于Simulink的汽车平顺性仿真分析_谢俊淋...
【hadoop】Sqoop数据迁移工具的安装部署
一、Sqoop安装与配置 步骤: 1、使用XFTP将Sqoop安装包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz发送到master机器的主目录。 2、解压安装包: tar -zxvf ~/sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz 3、修改文件夹的名字,将其改为s…...
只出现一次的数字(暴力、哈希查重、异或运算)
目录 一.题目 题目解析 题目链接 二.解题过程 俗手(暴力:数组模拟哈希表) 思路 代码示例 提交情况 本手:哈希查重 思路 代码示例 提交情况 妙手:异或运算 思路 代码示例 提交情况 作者的个人gitee 作者…...
Spark缓存
生活中缓存容量受成本和体积限制(比如 CPU 缓存只有几 MB 到几十 MB),但会通过算法(如 “最近最少使用” 原则)智能决定存什么,确保存的是 “最可能被用到的数据”。 1. 为什么需要缓存? 惰性执…...
linux中的常用命令(一)
目录 常用的快捷键 1- tab键:命令或者路径提示及补全; 2-ctrlc:放弃当前输入,终止当前任务或程序 3-ctrll;清屏 4-ctrlinsert:复制 5-鼠标右键:粘贴; 6-altc:断开连接/ctrlshift r 重新连接 7-alt1/2/3/等:切换回话窗口 8-上下键…...
Lua学习笔记
文章目录 前言1. Lua的数据类型2. Lua的控制结构2.1 循环2.1.1 for2.1.1.1 数值循环2.1.1.2 迭代循环2.1.2 while2.1.3 repeat-until 2.2 条件语句2.3 函数 3. Lua中的变量作用域 前言 Lua是一种轻量级的、高效的、可扩展的脚本语言,由巴西里约热内卢天主教大学&am…...
5月8日星期四今日早报简报微语报早读
5月8日星期四,农历四月十一,早报#微语早读。 1、外交部回应中美经贸高层会谈:这次会谈是应美方请求举行的; 2、河南许昌官方:胖东来联合京东物流打造的供应链产业基地将于今年投入运营; 3、我国外汇储备…...
P2415 集合求和 详解
此题我认为主要考数学逻辑,这个题目考的是你面对代码时,是否会从中去找规律推导一个数学公式。 先看题目: 此题目与集合有关,所以对于数学基础不好的同学,我会先给你讲一下这个集合的相关知识。 一,首先,…...
#define ccw (0)和#define ccw 0什么区别
目录 区别 一般建议 简单总结 #define ccw (0) 和 #define ccw 0 这两者在大多数情况下的功能非常相似,但在细节上有一些区别,主要涉及宏展开时的行为。 区别 #define ccw (0):宏定义的内容是(0),带括…...
跨平台移动开发框架React Native和Flutter性能对比
背景与架构 React Native 和 Flutter 都是跨平台移动开发框架,但它们的性能表现因架构差异而异。React Native 在 2025 年采用了 Bridgeless New Architecture(版本 0.74),使用 JavaScript Interface (JSI) 替代传统的 JavaScrip…...
【PhysUnits】2 SI 量纲 实现解析(prefix.rs)
源码 这是一个编译时量纲检查的物理单位库。 //! Physical Units Library with Type-Level Dimension Checking //! 带类型级量纲检查的物理单位库 //! //! This module provides type-safe physical unit representations using Rusts type system //! to enforce dimension…...
新能源汽车赛道变局:传统车企子品牌私有化背后的战略逻辑
2025年5月,一则资本市场动态引发行业震动:某国内头部传统车企宣布拟以每股2.57美元的价格私有化旗下高端新能源品牌,若交易完成,该新能源品牌将正式从纽交所退市。这一决策发生在全球新能源汽车行业经历剧烈洗牌、资本市场估值逻辑…...
[matlab]private和+等特殊目录在新版本matlab中不允许添加搜索路径解决方法
当我们目录包含有private,或者时候matlab搜索目录不让添加,比如截图: 在matlab2018以前这些都可以加进去后面版本都不行了。但是有时候我们必须要加进去才能兼容旧版本matlab库,比如mexopencv库就是这种情况。因此我们必须找到一个办法加进去…...
ImportError: cannot import name ‘Optional‘ from ‘pydantic‘
概览 再使用Optional定义fastapi可选参数时,出现了错误: ImportError: cannot import name Optional from pydantic python version: 3.8 pydantic version: 2.9.2 快速解决方案 Optional导入修改为typing包,如下 from typing import List…...
“水木精灵” 王泫梓妍时尚造型引关注
“水木精灵” 王泫梓妍一组时尚照片曝光,再次展现其独特时尚品味与青春活力。 照片中,王泫梓妍身着白色针织开衫搭配深蓝色牛仔短裙,开衫上精致的水钻装饰与深蓝色海军领增添了细节亮点,牛仔短裙的金色纽扣设计别致,整…...
数据结构-堆排序
1.定义 -堆中每个节点的值都必须大于等于(或小于等于)其左右子节点的值。如果每个节点的值都大于等于其子节点的值,这样的堆称为大根堆(大顶堆);如果每个节点的值都小于等于其子节点的值,称为…...
影响服务器性能的主要因素是什么
在这个数字化高速发展的时代,服务器就像是幕后的超级英雄,默默支撑着我们丰富多彩的网络世界。首先,硬件配置堪称服务器性能的基石。就好比一辆跑车,强大的引擎(CPU)、宽敞的跑道(内存ÿ…...
为什么 MySQL 用 B+ 树作为数据的索引,以及在 InnoDB 中数据库如何通过 B+ 树索引来存储数据以及查找数据
http://www.liuzk.com/410.html 索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据。 索引最形象的比喻就是图书的目录了。注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 这个数据&am…...
若依框架Ruoyi-vue整合图表Echarts中国地图标注动态数据
若依框架Ruoyi-vue整合图表Echarts中国地图 概述创作灵感预期效果整合教程前期准备整合若依框架1、引入china.json2、方法3、data演示数据4、核心代码 完整代码[毫无保留]组件调用 总结 概述 首先,我需要回忆之前给出的回答,确保这次的内容不重复&#…...