Android HWASAN使用与实现原理

一、背景

为了提前检测出Android User Sapce的app或native进程的内存错误问题,帮助研发定位与分析这些问题,基于Android 14版本上对HWASAN做了调研分析。

二、ASAN介绍

HWASAN是在ASAN的基础上做了拓展,因此在介绍HWASAN之前先了解下ASAN.

ASAN(AddressSanitizer)和HWASAN(Hardware-assisted AddressSanitizer)都是内存错误检测工具,用于帮助开发者发现和修复内存相关的bug,如heap-buffer-overflow、Heap-use-after-free、stack-buffer-overflow、global-buffer-overflow、double-free、Use-after-return、Alloc-dealloc-mismatch、use-after-poision等内存错误问题。它们的主要区别在于实现方式和性能开销。

2.1 shadow memory

shadow memory区域来记录实际内存的状态信息,malloc申请的内存或其它方式申请的内存一般8字节对齐,8字节的正常内存对应1个字节的shadow memory,8个字节中可划分为可寻址(访问)与不可寻址区域。如,前4个字节可寻址,后4个字节不可寻址,shadow memory记录的数据为5,即0000 0100.

normal mem与shadow mem对应关系:

shadow memory address = (normal memory address >> 3) + 0x1000000000

8字节组成的normal memory region共有3种状态:

1)1~7个字节可寻址,即shadow memory的值为1~7。

2)8个字节都可寻址,即shadow memory的值为0。

3)0个字节可寻址,shadow memory的值为负数。

0个字节可寻址其实可以分为多种情况,如:

这块区域是heap redzones、stack redzones、global redzones、freed memory,不同错误类型对应的shadow memory值也不一样。

 Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa (实际上Heap right redzone也是fa)
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  Container overflow:    fc
  Array cookie:          ac
  Intra object redzone:  bb
  ASan internal:         fe
  Left alloca redzone:   ca
  Right alloca redzone:  cb
  Shadow gap:            cc

每次访问normal memory地址时,都会去结合对应的shadow mem的值检测是否合法。

2.2 ASAN实现原理

ASAN实现原理:通过在内存分配时插入额外的代码来检查内存访问是否合法。使用一个影子内存(shadow memory)区域来记录实际内存的使用情况,当检测到非法内存访问时,ASAN会报告错误。

检测算法:

ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k))
        ReportAndCrash(Addr);

k!=0,说明Normal memory region中的8个字节并不是都可以被寻址的。

Addr & 7,将得知此次内存访问是从memory region的第几个byte开始的。

AccessSize是此次内存访问需要访问的字节长度。

(Addr&7)+AccessSize > k,则说明此次内存访问将会访问到不可寻址的字节。

当此次内存访问可能会访问到不可寻址的字节时,ASAN会报错并结合shadow memory中具体的值明确错误类型。

下面以use-after-free、heap-buffer-overflow来分析具体的检测原理。

2.2.1 use-after-free检测

检测原理:

1)已经free的normal memory对应的shadow memory值为0xfd.

2)已经free的normal memory区域需要放入隔离区一段时间(过段时间才允许被重新分配),防止发生错误时该区域已经通过malloc重新分配给其他人使用。一旦分配给其他人使用,则可能漏掉UseAfterFree的错误。

3)如果再次访问该normal memory区域时,发现对应的shadow memory值为0xfd,则触发ASAN异常报错。

2.2.2 heap-buffer-overflow检测

检测原理:

1)分配内存时normal memory的前后需要插入一定长度的安全区(大小不定),且此安全区对应的shadow memory被标记为0xfa.

2)当访问越界时,刚好访问了normal memory的前后安全区,此安全区对应的shadow memory值为0xfa,则触发ASAN异常报错。

2.3 ASAN缺陷

2.3.1 存在漏检的风险

1)use-after-free检测依赖隔离区,一段时间后这块内存被其他模块重新分配后,该模块再去访问,则无法检测出use-after-ree的错误。


2)heap-buffer-overflow检测依赖安全区,安全区有大小限制。可能是8bytes,64bytes或者其他什么值,但不管怎么样终归是有限的。如果某次踩踏跨过了安全区,踩踏到另一片可寻址的内存区域,则无法检测出heap-buffer-overflow的错误。

2.3.2 性能开销大

有两个原因导致ASAN性能开销:

1)增加额外的内存消耗:8字节的normal memory对应1个字节的shadow memory,相当于额外多出1/8的内存用于记录正常内存的状态信息;内存分配时需要在前后插入安全区,用于检测越界访问。这两种情况都会导致内存增加。

2)效率降低:需要在每次内存访问时进行检查,降低了效率;被释放的内存,需被隔离一段时间,无法立即被重新分配,系统内存紧张时,可能存在较大的性能影响

因此,针对ASAN的存在漏检的风险和性能开销大的缺陷,google提出了HWASAN来改善这两大缺陷。HWASAN解决措施:

1)措施1:64位的机器,实际上ARMv8寻址只用到了低48位,因此malloc时,HWASAN利用高8位标记tag,对应的shadow memory的值也记做tag

由于HWASAN 16字节的normal memory对应1个字节的shadow memory(ASAN为8:1),降低额外内存的消耗;由于HWASAN use-after-free检测不依赖隔离区,解决use-after-free漏检的风险(详细参考3.1.1)。

2)措施2:去除ASAN安全区的内存机制

由于去除ASAN安全区的内存机制,被释放的内存可以被其他模块立即分配,从而提高了内存的利用效率;

同时可以解决heap-buffer-overflow漏检的风险(详细参考3.1.2)。

三、HWASAN介绍

HWASAN是ASAN的升级版,优化了ASAN性能开销和漏检风险的缺陷。

3.1 实现原理

实现原理:64位的机器,实际上ARMv8寻址只用到了低48位。HWASAN用这8bit来存储一块内存区域的标签(tag)。

堆内存通过malloc分配出来,HWASAN在它返回地址时会更改该有效地址的高8位,随机生成一个tag数值,并将该tag同步到内存对应的shadow memory,当内存释放时,更新shadow memory的tag,HWASAN中normal memory和shadow memory的映射关系是16:1,而ASAN中二者的映射关系是8:1。通过对比内存高8位的tag与shadow memory的tag是否一致,如果不一致,会触发HWASAN相关的内存错误。

下面以use-after-free、heap-buffer-overflow来分析具体的检测原理。

3.1.1 use-after-free检测

检测原理:

1)分配一块内存时,内存的高8位打上tag,对应的shadow memory的值也为该tag

2)内存释放时,更新对应的shadow memory的tag,使这块内存的高8位的tag与shadow memory的tag不一致

3)当再次访问这块内存时,发现内存的高8位的tag与shadow memory的tag不一致,触发HWASAN内存错误

如,char* p =new char[10],分配10个字节的内存,由于8个字节对齐,共占用16个字节,高8位随机生成tag1。

当内存释放时,对应的shadow memory的值由原来的tag1更新位tag2.再次访问p[0]时,检查高8位tag1与shadow memory中的值tag2不一致,触发HWASAN use-after-free.

char* p =new char[10];
delete [] p;
p[0] = "abc";

3.1.2 heap-buffer-overflow检测

检测原理:

1)相邻内存的shadow memory的tag不一致

2)当访问这块内存地址时,会去检测该地址高8位的tag与对应shadow memory的tag是否一直不一致。如果不一致,说明越界访问

如,char* p =new char[10],分配10个字节的内存,由于8个字节对齐,共占用16个字节,高8位随机生成tag2。当访问p[16]时,由于p+16所处地址对应的shadow memory的值为tag3与p地址对应的高8位tag2不一致,会触发HWASAN heap-buffer-overflow.

char* p =new char[10];
p[16] = "abc";

由于每次malloc,高8位的tag随机生成,因此存在相邻内存高8位的tag一致的概率(如tag2等于tag3),概率为1/256,在这种情况下即使越界访问,也无法检测出heap-buffer-overflow的问题。

3.2 HWASAN优缺点

优点:

解决了ASAN的缺陷

缺点:

1)由于采用了高8位的tag检测机制,因此只能适用于64位的机器

2)HWASAN中normal memory和shadow memory的映射关系是16:1,即会多消耗1/16的额外内存用于记录normal memory的状态(tag)信息

3)每次内存分配、释放、访问,都需要额外的检测工作,降低性能

4.1 系统全功能打开

1)编译带HWASAN的镜像和带hwasan的libc.so & libclang_rt.hwasan-aarch64-android.so

source build/envsetup.sh
lunch missi_auto_native_only64-userdebug
export SANITIZE_TARGET=hwaddress
make -j8 或make systemimage

libc.so路径:

out/target/product/missi/system/lib64/bootstrap/hwasan/libc.so

libclang_rt.hwasan-aarch64-android.so路径:out/target/product/missi/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so

2)刷机或push libc.so和libclang_rt.hwasan-aarch64-android.so到/system/lib64目录后重启设备

4.2 单个应用或进程打开

AndroidManifest.xml中 <application> 元素中配置了 android:debuggable="true"

<application android:debuggable="true">

</application>

native进程开启HWASAN,需要在Android.bp中做配置:

sanitize: {
    hwaddress: true,
},

五、Debug案例

在设备验证HWASAN功能:

1)设置HWASAN环境变量,编译出带HWASAN的镜像或libc.so + libclang_rt.hwasan-aarch64-android.so

source build/envsetup.sh
lunch missi_auto_native_only64-userdebug
export SANITIZE_TARGET=hwaddress
make -j8 或make systemimage

带hwasan的libc.so路径:

out/target/product/missi/system/lib64/bootstrap/hwasan/libc.so

libclang_rt.hwasan-aarch64-android.so路径:out/target/product/missi/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so

(刷机方式效率较低,可以直接push so库到设备)

2)push libc.so和libclang_rt.hwasan-aarch64-android.so到/system/lib64目录后重启设备

3)自己编写一个Demo,push hw-asan-test-bin Demo到/system/bin目录并执行

检测double-free、use-after-free、invalid-free、heap-over-flow等场景,

分别执行./system/bin/hw-asan-test-bin double-free、./system/bin/hw-asan-test-bin use-after-free、./system/bin/hw-asan-test-bin heap-over-flow命令。

Demo的部分代码:

void doubleFree() {
    // 分配4个字节
    int *ptr = (int*)malloc(4);
    std::cout << "ptr = " << ptr << std::endl;
    free(ptr);
    free(ptr);
}

void invalidFree() {
    int *ptr = (int*)malloc(4);
    std::cout << "ptr = " << ptr << std::endl;
    free(ptr+1);
    std::cout << "invalid-free ~" << std::endl;
}

void useAfterFree() {
    char* ptr = new char[20];
    std::cout << "ptr = " << ptr << std::endl;
    delete[] ptr;
    ptr[0] = 'A';
    std::cout << "useAfterFree ~" << std::endl;
}

void heapOverFlow() {
    char* ptr = new char[20];
    std::cout << "ptr = " << ptr << std::endl;
    ptr[32] = 'A';
    std::cout << "heapOverFlow ~" << std::endl;
}

void memLeak() {
    for (int i = 0; i < 1000; i++) {
        char *buffer = (char *)malloc(100);
    }
    std::cout << "memLeak ~" << std::endl;
}

4)查询生成的tombstone文件

以下是hw-asan-test-bin Demo crash生成的HWASAN tombstone文件,如下:

Cmdline: ./system/bin/hw-asan-test-bin double-free
pid: 12968, tid: 12968, name: hw-asan-test-bi  >>> ./system/bin/hw-asan-test-bin <<<
uid: 0
tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
// 内存被释放后,0x003c95840020地址对应的内存被标记为6c
Abort message: '==12968==ERROR: HWAddressSanitizer: invalid-free on address 0x003c95840020 at pc 0x007d0dd81ba4 on thread T0
tags: 77/6c (ptr/mem)
    #0 0x7d0dd81ba4  (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x23ba4) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
    #1 0x5b9584c230  (/system/bin/hw-asan-test-bin+0x1230) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
    #2 0x5b9584c6a4  (/system/bin/hw-asan-test-bin+0x16a4) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
    #3 0x7d0aab6b60  (/apex/com.android.runtime/lib64/bionic/hwasan/libc.so+0xb0b60) (BuildId: 86a860a589207e712675d7d611b13147)
    #4 0x5b9584c054  (/system/bin/hw-asan-test-bin+0x1054) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)

[0x003c95840020,0x003c95840040) is a small unallocated heap chunk; size: 32 offset: 0

Cause: use-after-free
// 分配的内存地址0x003c95840020至0x003c95840024,刚好是4个字节与Demo代码一致
0x003c95840020 is located 0 bytes inside a 4-byte region [0x003c95840020,0x003c95840024)
// HWASAN内存释放的堆栈信息
freed by thread T0 here:
    #0 0x7d0dd81ba4  (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x23ba4) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
    #1 0x5b9584c188  (/system/bin/hw-asan-test-bin+0x1188) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
    #2 0x5b9584c6a4  (/system/bin/hw-asan-test-bin+0x16a4) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
    #3 0x7d0aab6b60  (/apex/com.android.runtime/lib64/bionic/hwasan/libc.so+0xb0b60) (BuildId: 86a860a589207e712675d7d611b13147)
    #4 0x5b9584c054  (/system/bin/hw-asan-test-bin+0x1054) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
// HWASAN内存分配的堆栈信息
previously allocated here:
    #0 0x7d0dd82244  (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x24244) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
    #1 0x7d0aa671dc  (/apex/com.android.runtime/lib64/bionic/hwasan/libc.so+0x611dc) (BuildId: 86a860a589207e712675d7d611b13147)
    #2 0x5b9584c0d4  (/system/bin/hw-asan-test-bin+0x10d4) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
    #3 0x5b9584c6a4  (/system/bin/hw-asan-test-bin+0x16a4) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
    #4 0x7d0aab6b60  (/apex/com.android.runtime/lib64/bionic/hwasan/libc.so+0xb0b60) (BuildId: 86a860a589207e712675d7d611b13147)
    #5 0x5b9584c054  (/system/bin/hw-asan-test-bin+0x1054) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)

hwasan_dev_note_heap_rb_distance: 1 1023
hwasan_dev_note_num_matching_addrs: 0
hwasan_dev_note_num_matching_addrs_4b: 0
Thread: T0 0x007400002000 stack: [0x007fc95fb000,0x007fc9dfb000) sz: 8388608 tls: [0x007d0ea6efc0,0x007d0ea72000)
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0x003c9583f800: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583f900: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583fa00: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583fb00: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583fc00: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583fd00: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583fe00: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c9583ff00: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
=>0x003c95840000: 08  00 [6c] 00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840100: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840200: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840300: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840400: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840500: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840600: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840700: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
  0x003c95840800: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0x003c9583ff00: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. 
=>0x003c95840000: 6e  .. [..] ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. 
  0x003c95840100: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. 
  
  ......
  backtrace:
      #00 pc 00000000000bab8c  /apex/com.android.runtime/lib64/bionic/hwasan/libc.so (abort+308) (BuildId: 86a860a589207e712675d7d611b13147)
      #01 pc 00000000000354b4  /system/lib64/libclang_rt.hwasan-aarch64-android.so (__sanitizer::Abort()+60) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
      #02 pc 0000000000033d3c  /system/lib64/libclang_rt.hwasan-aarch64-android.so (__sanitizer::Die()+204) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
      #03 pc 00000000000286c4  /system/lib64/libclang_rt.hwasan-aarch64-android.so (__hwasan::ScopedReport::~ScopedReport()+544) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
      #04 pc 0000000000027458  /system/lib64/libclang_rt.hwasan-aarch64-android.so (__hwasan::ReportInvalidFree(__sanitizer::StackTrace*, unsigned long)+560) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
      #05 pc 0000000000023c00  /system/lib64/libclang_rt.hwasan-aarch64-android.so (__sanitizer_free+264) (BuildId: 558b5c131872716737ddc0a62f3382dd3df70b9a)
      #06 pc 0000000000001230  /system/bin/hw-asan-test-bin (doubleFree()+472) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
      #07 pc 00000000000016a4  /system/bin/hw-asan-test-bin (main+648) (BuildId: b3d99e0748a4c4a2607c8c2b9b91815e)
      #08 pc 00000000000b0b60  /apex/com.android.runtime/lib64/bionic/hwasan/libc.so (__libc_init+148) (BuildId: 86a860a589207e712675d7d611b13147)
      ......

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电源设计改进稳定度和误差放大器的解决方案

电池&#xff0c;变压器&#xff0c;电源和转换器会不断受到能量损失的影响。结果&#xff0c;负载上的输出电压会降低。温度是性能的另一个关键特征。通过创建误差放大系统&#xff0c;可以在任何类型的负载下稳定输出电压。 稳压二极管稳定器 使用功率晶体管以及电流放大器…

自己动手实现语音识别

声音的本质是震动,震动的本质是位移关于时间的函数,波形文件(.wav)中记录了不同采样时刻的位移。 通过傅里叶变换,可以将时间域的声音函数分解为一系列不同频率的正弦函数的叠加,通过频率谱线的特殊分布,建立音频内容和文本的对应关系,以此作为模型训练的基础。 语音mfc…

比赛获奖的武林秘籍:02 国奖秘籍-大学生电子计算机类竞赛快速上手的流程,小白必看

比赛获奖的武林秘籍&#xff1a;02 国奖秘籍-大学生电子计算机类竞赛快速上手的流程&#xff0c;小白必看 摘要 本文主要介绍了大学生参加电子计算机类比赛&#xff08;电赛、光电设计大赛、计算机设计大赛、嵌入式芯片与系统设计大赛等比赛&#xff09;的流程和涉及到的知识…

【Portswigger 学院】文件上传

教程和靶场来源于 Burpsuite 的官网 Portswigger&#xff1a;File upload vulnerabilities - PortSwigger 原理与危害 很多网站都有文件上传的功能&#xff0c;比如在个人信息页面允许用户上传图片作为头像。如果网站应用程序对用户上传的文件没有针对文件名、文件类型、文件内…

解决中型组织三个人力资源基础问题的方法

中型企业 (通常在700 - 5000名员工之间)是从中小企业发展起来的&#xff0c;但不称为大型企业。虽然个别市场取得了成功&#xff0c;但到2023年&#xff0c;中端市场经历了一个艰难的结局&#xff0c;受到了更广泛的经济挑战的影响。然而&#xff0c;它仍然具有灵活性和乐观性&…

24_嵌入式系统输入输出设备

目录 GPIO原理与结构 A/D接口基本原理 A/D接口原理 A/D转换的重要指标 D/A接口基本原理 D/A接口原理 DAC的分类 D/A转换器的主要指标 键盘接口基本原理 键盘接口原理 用I/O口实现键盘接口 显示接口基本原理 基本结构和特点 基本原理 LCD种类 市面上出售的LCD的类…

dtpay聚合支付系统在跨境支付场景中技术及业务方案

1 什么是跨境支付 我们从两个维度来分析什么是跨境支付&#xff0c;第一个维度我们从资金流向分析&#xff0c;国内的消费者在境外进行消费对于国内资金流来说这属于资金流出&#xff0c;这是跨境支付的第一种应用场景。第二个场景国外游客在国内进行消费&#xff0c;这属于资…

【ECCV 2024】首个跨模态步态识别框架:Camera-LiDAR Cross-modality Gait Recognition

【ECCV 2024】首个跨模态步态识别框架&#xff1a;Camera-LiDAR Cross-modality Gait Recognition 简介&#xff1a;主要方法&#xff1a;实验结果&#xff1a; 论文&#xff1a;https://arxiv.org/abs/2407.02038 简介&#xff1a; 步态识别是一种重要的生物特征识别技术。基…

【论文阅读】-- Strscope:不规则测量的时间序列数据的多尺度可视化

Stroscope: Multi-Scale Visualization of Irregularly Measured Time-Series Data 摘要1 引言2相关工作2.1&#xff08;大型&#xff09;时间序列数据可视化2.2 事件序列数据可视化2.3 评价 3问题分析3.1 数据集3.2 场景——现状3.3 设计流程3.4 设计原理 4 涟漪图&#xff1a…

十大排序:插入/希尔/选择/堆/冒泡/快速/归并/计数/基数/桶排序 汇总(C语言)

目录 前言非线性时间比较类插入排序(1) 直接插入排序(2) 希尔排序 选择排序(3) 选择排序优化版(4) 堆排序 交换排序(5) 冒泡排序(6) 快速排序hoare版本挖坑版前后指针版非递归版 归并排序(7) 归并排序递归版非递归版 线性时间比较类(8) 计数排序基数排序与桶排序 总结 前言 在计…

昇思25天学习打卡营第16天|文本解码原理——以MindNLP为例

在大模型中&#xff0c;文本解码通常是指在自然语言处理&#xff08;NLP&#xff09;任务中使用的大型神经网络模型&#xff08;如Transformer架构的模型&#xff09;将编码后的文本数据转换回可读的原始文本的过程。这些模型在处理自然语言时&#xff0c;首先将输入文本&#…

自闭症儿童的治疗方法有哪些?

身为星贝育园自闭症儿童康复学校的资深教育者&#xff0c;我深知自闭症谱系障碍&#xff08;ASD&#xff09;儿童的教育与治疗需要一个全面、个性化的方案。在星贝育园&#xff0c;我们致力于为孩子们提供一个充满爱与理解的环境&#xff0c;采用多种科学验证的教育方法&#x…

【Java11】变量的初始化和内存中的运行机制

成员变量的初始化和内存中的运行机制 系统加载类或创建类的实例时&#xff0c;系统自动为成员变量分配内存空间&#xff0c;然后自动为成员变量指定初始值。 class Person {public String name; // 实例变量public static int eyeNum; // 类变量 }var p1 Person(); var p2 …

动态线程池思想学习及实践

引言 在后台项目开发过程中&#xff0c;我们常常借助线程池来实现多线程任务&#xff0c;以此提升系统的吞吐率和响应性&#xff1b;而线程池的参数配置却是一个难以合理评估的值&#xff0c;虽然业界也针对CPU密集型&#xff0c;IO密集型等场景给出了一些参数配置的经验与方案…

MQ:RabbitMQ

同步和异步通讯 同步通讯: 需要实时响应,时效性强 耦合度高 每次增加功能都要修改两边的代码 性能下降 需要等待服务提供者的响应,如果调用链过长则每次响应时间需要等待所有调用完成 资源浪费 调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下…

【后端面试题】【中间件】【NoSQL】MongoDB查询优化2(优化排序、mongos优化)

优化排序 在MongoDB里面&#xff0c;如果能够利用索引来排序的话&#xff0c;直接按照索引顺序加载数据就可以了。如果不能利用索引来排序的话&#xff0c;就必须在加载了数据之后&#xff0c;再次进行排序&#xff0c;也就是进行内存排序。 可想而知&#xff0c;如果内存排序…

【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】

【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】 1、前言2、环境3、事项了解&#xff08;1&#xff09;了解sem概念-了解官网消息&#xff08;2&#xff09;根据自己理解&#xff0c;设计几个使用方式&#xff08;3&#xff09;不建议运行…

DataWhale-吃瓜教程学习笔记 (七)

学习视频**&#xff1a;第6章-支持向量机_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 第六章 支持向量机 - 算法原理 几何角度 对于线性可分数据集&#xff0c;找距离正负样本距离都最远的超平面&#xff0c;解是唯一的&#xff0c;泛化性能较好 - 超平面 - 几何间隔 例…

堆叠的作用

一、为什么要堆叠 传统的园区网络采用设备和链路冗余来保证高可靠性&#xff0c;但其链路利用率低、网络维护成本高&#xff0c;堆叠技术将多台交换机虚拟成一台交换机&#xff0c;达到简化网络部署和降低网络维护工作量的目的。 二、堆叠优势 1、提高可靠性 堆叠系统多台成…

ServiceImpl中的参数封装为Map到Mapper.java中查询

ServiceImpl中的参数封装为Map到Mapper.java中查询&#xff0c;可以直接从map中获取到key对应的value
最新文章