android-ndk开发(6): 查看反汇编
android-ndk开发(6): 查看反汇编
2025/05/05
1. 概要
android-ndk 是基于 clang 的工具链, clang 则保持了和 gcc 的高度兼容。 在 Linux 开发机上, GCC 套件里的 objdump 提供了反汇编的功能。 实际上 android-ndk 也提供了一份 objdump, 用它可以反汇编 android 平台的二进制文件。
使用调试器带来的交互式体验, 在 android-ndk 这一交叉编译 - 连接到设备上运行和调试的场景下, 卡顿感比较明显; 相比之下, 查看反汇编代码来辅助 crash 分析, 是 android-ndk 开发过程中会使用到的一个技能。 不求精通汇编, 反正可以问 AI; 而具备查看反汇编的思维则显得更加重要。
2. 查看反汇编
2.1 查看可执行文件的反汇编
还记得上一篇我们搭建的 hello-world 工程吗?
#include <stdio.h>
int main() {printf("hello, world!\n");
}
#!/bin/bash
NDK=~/soft/android-ndk/r21e
HOST_TAG=darwin-x86_64
$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/clang \-target aarch64-linux-android21 hello.c \-o helloadb push hello /data/local/tmp/hello
adb shell "cd /data/local/tmp; chmod +x ./hello; ./hello"
编译后会在当前目录得到 hello
可执行文件。 查看它的反汇编:
/<path/to>/aarch64-linux-android-objdump -d hello
例如我的路径是:
/Users/zz/soft/android-ndk/r21e/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-objdump -d hello
反汇编结果如下:
hello: file format elf64-littleaarch64Disassembly of section .plt:0000000000000560 <printf@plt-0x20>:560: a9bf7bf0 stp x16, x30, [sp,#-16]!564: b0000010 adrp x16, 1000 <main+0x9d8>568: f947de11 ldr x17, [x16,#4024]56c: 913ee210 add x16, x16, #0xfb8570: d61f0220 br x17574: d503201f nop578: d503201f nop57c: d503201f nop0000000000000580 <printf@plt>:580: b0000010 adrp x16, 1000 <main+0x9d8>584: f947e211 ldr x17, [x16,#4032]588: 913f0210 add x16, x16, #0xfc058c: d61f0220 br x170000000000000590 <__libc_init@plt>:590: b0000010 adrp x16, 1000 <main+0x9d8>594: f947e611 ldr x17, [x16,#4040]598: 913f2210 add x16, x16, #0xfc859c: d61f0220 br x1700000000000005a0 <__cxa_atexit@plt>:5a0: b0000010 adrp x16, 1000 <main+0x9d8>5a4: f947ea11 ldr x17, [x16,#4048]5a8: 913f4210 add x16, x16, #0xfd05ac: d61f0220 br x17Disassembly of section .text:00000000000005b0 <_start>:5b0: 910003e0 mov x0, sp5b4: 14000001 b 5b8 <_start_main>00000000000005b8 <_start_main>:5b8: d100c3ff sub sp, sp, #0x305bc: a9027bfd stp x29, x30, [sp,#32]5c0: b0000008 adrp x8, 1000 <main+0x9d8>5c4: f947f508 ldr x8, [x8,#4072]5c8: b0000009 adrp x9, 1000 <main+0x9d8>5cc: f947fd29 ldr x9, [x9,#4088]5d0: b000000a adrp x10, 1000 <main+0x9d8>5d4: f947f94a ldr x10, [x10,#4080]5d8: 9e670100 fmov d0, x85dc: 4e181d20 mov v0.d[1], x95e0: 3d8003e0 str q0, [sp]5e4: f9000bea str x10, [sp,#16]5e8: b0000002 adrp x2, 1000 <main+0x9d8>5ec: f947f042 ldr x2, [x2,#4064]5f0: 910003e3 mov x3, sp5f4: aa1f03e1 mov x1, xzr5f8: 910083fd add x29, sp, #0x205fc: 97ffffe5 bl 590 <__libc_init@plt>0000000000000600 <__atexit_handler_wrapper>:600: b4000040 cbz x0, 608 <__atexit_handler_wrapper+0x8>604: d61f0000 br x0608: d65f03c0 ret000000000000060c <atexit>:60c: 90000008 adrp x8, 0 <note_android_ident-0x218>610: 91180108 add x8, x8, #0x600614: d0000002 adrp x2, 2000 <__bss_start>618: 91000042 add x2, x2, #0x061c: aa0003e1 mov x1, x0620: aa0803e0 mov x0, x8624: 17ffffdf b 5a0 <__cxa_atexit@plt>0000000000000628 <main>:628: d10083ff sub sp, sp, #0x2062c: a9017bfd stp x29, x30, [sp,#16]630: 910043fd add x29, sp, #0x10634: 90000000 adrp x0, 0 <note_android_ident-0x218>638: 91197000 add x0, x0, #0x65c63c: 52800008 mov w8, #0x0 // #0640: b81fc3a8 stur w8, [x29,#-4]644: 97ffffcf bl 580 <printf@plt>648: b85fc3a8 ldur w8, [x29,#-4]64c: 2a0803e0 mov w0, w8650: a9417bfd ldp x29, x30, [sp,#16]654: 910083ff add sp, sp, #0x20658: d65f03c0 ret
也可以封装为脚本: disassemble.sh
:
#!/bin/bash
NDK=~/soft/android-ndk/r21e
HOST_TAG=darwin-x86_64
$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/aarch64-linux-android-objdump -d hello
3.2 查看单个 .c/.cpp 文件的反汇编
对于 hello-world 工程, 可执行文件对应到唯一的源代码文件 hello.c。
对于稍微有点内容的工程, 不止一个源代码文件。 拿我本地的 ncv 工程来说, 有5个源文件:
- color.c
- io.c
- main.c
- thread.c
- timer.c
这对应两个事情:
- 使用 cmake 构建比较方便, 使用纯粹的命令行也行, 但是有点麻烦
- 查看反汇编时, 分别对每个 .c 对应的 .o 反汇编, 内容比较清晰; 所有文件编译出的可执行文件 test_ncv 的反汇编, 内容太多, 看不过来
我的 CMakeLists.txt 为:
cmake_minimum_required(VERSION 3.10)
project(ncv C)
add_library(ncv STATIC color.c io.c)
add_executable(test_ncv main.c)
target_link_libraries(test_ncv PUBLIC ncv)
对应的 cmake 构建输出, build/CMakeFiles 目录下的文件:
➜ ncv git:(main) ✗ tree build/CMakeFiles
build/CMakeFiles
├── 3.31.6
│ ├── CMakeCCompiler.cmake
│ ├── CMakeDetermineCompilerABI_C.bin
│ └── CMakeSystem.cmake
├── CMakeConfigureLog.yaml
├── TargetDirectories.txt
├── cmake.check_cache
├── ncv.dir
│ ├── color.c.o
│ └── io.c.o
├── pkgRedirects
├── rules.ninja
└── test_ncv.dir└── main.c.o5 directories, 10 files
我们感兴趣的 ncv.dir/color.c.o
和 ncv.dir/io.c.o
. 他们是库目标 ncv
对应的源代码们, 对应的 .o 文件。
执行反汇编:
/Users/zz/soft/android-ndk/r21e/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-objdump -d build/CMakeFiles/ncv.dir/color.c.o
一些反汇编结果:
Disassembly of section .text.nv21_to_rgb_worker:0000000000000000 <nv21_to_rgb_worker>:0: a9bf4ff4 stp x20, x19, [sp,#-16]!4: 69402408 ldpsw x8, x9, [x0]8: 6b09011f cmp w8, w9c: 540014aa b.ge 2a0 <nv21_to_rgb_worker+0x2a0>10: f940040a ldr x10, [x0,#8]14: 9000000b adrp x11, 0 <nv21_to_rgb_worker>18: 9000000c adrp x12, 0 <nv21_to_rgb_worker>1c: fd400160 ldr d0, [x11]20: fd400181 ldr d1, [x12]24: a940314b ldp x11, x12, [x10]28: 9000000d adrp x13, 0 <nv21_to_rgb_worker>2c: 9000000e adrp x14, 0 <nv21_to_rgb_worker>30: fd4001a2 ldr d2, [x13]34: fd4001c3 ldr d3, [x14]38: a941396d ldp x13, x14, [x11,#16]3c: f9400990 ldr x16, [x12,#16]40: 69462971 ldpsw x17, x10, [x11,#48]44: b9803180 ldrsw x0, [x12,#48]48: b940056b ldr w11, [x11,#4]4c: 9100050f add x15, x8, #0x150: 9b113501 madd x1, x8, x17, x1354: d37ffa2c lsl x12, x17, #158: 9b1135f1 madd x17, x15, x17, x135c: 910005cd add x13, x14, #0x160: 9b004102 madd x2, x8, x0, x1664: d37ff80e lsl x14, x0, #168: 9b0041e0 madd x0, x15, x0, x166c: 9100042f add x15, x1, #0x170: 91000630 add x16, x17, #0x174: 91000851 add x17, x2, #0x278: 91000800 add x0, x0, #0x27c: 52801fe1 mov w1, #0xff // #25580: 7100057f cmp w11, #0x184: 5400014a b.ge ac <nv21_to_rgb_worker+0xac>88: 91000908 add x8, x8, #0x28c: 8b0c01ef add x15, x15, x1290: 8b0c0210 add x16, x16, x1294: 8b0e0231 add x17, x17, x1498: eb09011f cmp x8, x99c: 8b0e0000 add x0, x0, x14a0: 5400100a b.ge 2a0 <nv21_to_rgb_worker+0x2a0>a4: 7100057f cmp w11, #0x1a8: 54ffff0b b.lt 88 <nv21_to_rgb_worker+0x88>ac: 93417d02 sbfx x2, x8, #1, #31b0: 9b0a3442 madd x2, x2, x10, x13b4: aa0003e3 mov x3, x0b8: aa1103e4 mov x4, x17bc: aa1003e5 mov x5, x16c0: aa0f03e6 mov x6, x15c4: 2a0b03e7 mov w7, w11c8: 385ff053 ldurb w19, [x2,#-1]cc: 3c5ff0c4 ldur b4, [x6,#-1]d0: 38402454 ldrb w20, [x2],#2d4: 510008e7 sub w7, w7, #0x2d8: 51020273 sub w19, w19, #0x80dc: 1e620265 scvtf d5, w19e0: 7e61d884 ucvtf d4, d4e4: 1e6008a7 fmul d7, d5, d0e8: 1e6428e4 fadd d4, d7, d4ec: 1e780093 fcvtzs w19, d4f0: 7103fe7f cmp w19, #0xfff4: 1a81b273 csel w19, w19, w1, ltf8: 0ab37e73 bic w19, w19, w19, asr #31fc: 381fe093 sturb w19, [x4,#-2]100: 3c5ff0c6 ldur b6, [x6,#-1]104: 51020294 sub w20, w20, #0x80108: 1e620290 scvtf d16, w2010c: 1e610a04 fmul d4, d16, d1110: 7e61d8c6 ucvtf d6, d6114: 1e6208a5 fmul d5, d5, d2118: 1e6438c6 fsub d6, d6, d411c: 1e6538c6 fsub d6, d6, d5120: 1e7800d3 fcvtzs w19, d6124: 7103fe7f cmp w19, #0xff128: 1a81b273 csel w19, w19, w1, lt12c: 0ab37e73 bic w19, w19, w19, asr #31130: 381ff093 sturb w19, [x4,#-1]134: 3c5ff0d1 ldur b17, [x6,#-1]138: 1e630a06 fmul d6, d16, d313c: 7e61da30 ucvtf d16, d17140: 1e7028d0 fadd d16, d6, d16144: 1e780213 fcvtzs w19, d16148: 7103fe7f cmp w19, #0xff14c: 1a81b273 csel w19, w19, w1, lt150: 0ab37e73 bic w19, w19, w19, asr #31154: 39000093 strb w19, [x4]158: 3d4000d0 ldr b16, [x6]15c: 7e61da10 ucvtf d16, d16160: 1e7028f0 fadd d16, d7, d16164: 1e780213 fcvtzs w19, d16168: 7103fe7f cmp w19, #0xff16c: 1a81b273 csel w19, w19, w1, lt170: 0ab37e73 bic w19, w19, w19, asr #31174: 39000493 strb w19, [x4,#1]178: 3d4000d0 ldr b16, [x6]17c: 7e61da10 ucvtf d16, d16180: 1e643a10 fsub d16, d16, d4184: 1e653a10 fsub d16, d16, d5188: 1e780213 fcvtzs w19, d1618c: 7103fe7f cmp w19, #0xff190: 1a81b273 csel w19, w19, w1, lt194: 0ab37e73 bic w19, w19, w19, asr #31198: 39000893 strb w19, [x4,#2]19c: 3d4000d0 ldr b16, [x6]1a0: 910008c6 add x6, x6, #0x21a4: 7e61da10 ucvtf d16, d161a8: 1e7028d0 fadd d16, d6, d161ac: 1e780213 fcvtzs w19, d161b0: 7103fe7f cmp w19, #0xff1b4: 1a81b273 csel w19, w19, w1, lt1b8: 0ab37e73 bic w19, w19, w19, asr #311bc: 39000c93 strb w19, [x4,#3]1c0: 3c5ff0b0 ldur b16, [x5,#-1]1c4: 91001884 add x4, x4, #0x61c8: 7e61da10 ucvtf d16, d161cc: 1e7028f0 fadd d16, d7, d161d0: 1e780213 fcvtzs w19, d161d4: 7103fe7f cmp w19, #0xff1d8: 1a81b273 csel w19, w19, w1, lt1dc: 0ab37e73 bic w19, w19, w19, asr #311e0: 381fe073 sturb w19, [x3,#-2]1e4: 3c5ff0b0 ldur b16, [x5,#-1]1e8: 7e61da10 ucvtf d16, d161ec: 1e643a10 fsub d16, d16, d41f0: 1e653a10 fsub d16, d16, d51f4: 1e780213 fcvtzs w19, d161f8: 7103fe7f cmp w19, #0xff1fc: 1a81b273 csel w19, w19, w1, lt200: 0ab37e73 bic w19, w19, w19, asr #31204: 381ff073 sturb w19, [x3,#-1]208: 3c5ff0b0 ldur b16, [x5,#-1]20c: 7e61da10 ucvtf d16, d16210: 1e7028d0 fadd d16, d6, d16214: 1e780213 fcvtzs w19, d16218: 7103fe7f cmp w19, #0xff21c: 1a81b273 csel w19, w19, w1, lt220: 0ab37e73 bic w19, w19, w19, asr #31224: 39000073 strb w19, [x3]228: 3d4000b0 ldr b16, [x5]22c: 7e61da10 ucvtf d16, d16230: 1e7028e7 fadd d7, d7, d16234: 1e7800f3 fcvtzs w19, d7238: 7103fe7f cmp w19, #0xff23c: 1a81b273 csel w19, w19, w1, lt240: 0ab37e73 bic w19, w19, w19, asr #31244: 39000473 strb w19, [x3,#1]248: 3d4000a7 ldr b7, [x5]24c: 7e61d8e7 ucvtf d7, d7250: 1e6438e4 fsub d4, d7, d4254: 1e653884 fsub d4, d4, d5258: 1e780093 fcvtzs w19, d425c: 7103fe7f cmp w19, #0xff260: 1a81b273 csel w19, w19, w1, lt264: 0ab37e73 bic w19, w19, w19, asr #31268: 39000873 strb w19, [x3,#2]26c: 3d4000a4 ldr b4, [x5]270: 910008a5 add x5, x5, #0x2274: 7e61d884 ucvtf d4, d4278: 1e6428c4 fadd d4, d6, d427c: 1e780093 fcvtzs w19, d4280: 7103fe7f cmp w19, #0xff284: 1a81b273 csel w19, w19, w1, lt288: 0ab37e73 bic w19, w19, w19, asr #3128c: 710000ff cmp w7, #0x0290: 39000c73 strb w19, [x3,#3]294: 91001863 add x3, x3, #0x6298: 54fff18c b.gt c8 <nv21_to_rgb_worker+0xc8>29c: 17ffff7b b 88 <nv21_to_rgb_worker+0x88>2a0: aa1f03e0 mov x0, xzr2a4: a8c14ff4 ldp x20, x19, [sp],#162a8: d65f03c0 retDisassembly of section .text.ncv_color_cvt:0000000000000000 <ncv_color_cvt>:0: d10143ff sub sp, sp, #0x504: f9001bf3 str x19, [sp,#48]8: a9047bfd stp x29, x30, [sp,#64]c: 910103fd add x29, sp, #0x4010: d53bd053 mrs x19, tpidr_el014: f9401669 ldr x9, [x19,#40]18: aa0003e8 mov x8, x01c: 52800020 mov w0, #0x1 // #120: f81e83a9 stur x9, [x29,#-24]24: b4000668 cbz x8, f0 <ncv_color_cvt+0xf0>28: b4000641 cbz x1, f0 <ncv_color_cvt+0xf0>2c: b940010a ldr w10, [x8]30: b9400029 ldr w9, [x1]34: 7108055f cmp w10, #0x20138: 54000321 b.ne 9c <ncv_color_cvt+0x9c>3c: 711c053f cmp w9, #0x70140: 540002e1 b.ne 9c <ncv_color_cvt+0x9c>44: b9400509 ldr w9, [x8,#4]48: b940042a ldr w10, [x1,#4]4c: 6b0a013f cmp w9, w1050: 540004e1 b.ne ec <ncv_color_cvt+0xec>54: b9400909 ldr w9, [x8,#8]58: b940082a ldr w10, [x1,#8]5c: 6b0a013f cmp w9, w1060: 54000461 b.ne ec <ncv_color_cvt+0xec>64: f940090a ldr x10, [x8,#16]68: b400054a cbz x10, 110 <ncv_color_cvt+0x110>6c: f940082a ldr x10, [x1,#16]70: b400050a cbz x10, 110 <ncv_color_cvt+0x110>74: 90000000 adrp x0, 0 <ncv_color_cvt>78: a90187e8 stp x8, x1, [sp,#24]7c: 910063e8 add x8, sp, #0x1880: 91000000 add x0, x0, #0x084: 910023e1 add x1, sp, #0x888: 290127ff stp wzr, w9, [sp,#8]8c: f9000be8 str x8, [sp,#16]90: 94000000 bl 0 <ncv_parallel_for>94: 2a1f03e0 mov w0, wzr98: 14000016 b f0 <ncv_color_cvt+0xf0>9c: 7108055f cmp w10, #0x201a0: 2a1f03e0 mov w0, wzra4: 54000261 b.ne f0 <ncv_color_cvt+0xf0>a8: 7108053f cmp w9, #0x201ac: 54000221 b.ne f0 <ncv_color_cvt+0xf0>b0: b9400509 ldr w9, [x8,#4]b4: b940042a ldr w10, [x1,#4]b8: 6b0a013f cmp w9, w10bc: 54000181 b.ne ec <ncv_color_cvt+0xec>c0: b9400909 ldr w9, [x8,#8]c4: b940082a ldr w10, [x1,#8]c8: 6b0a013f cmp w9, w10cc: 54000101 b.ne ec <ncv_color_cvt+0xec>d0: f9400908 ldr x8, [x8,#16]d4: 528000a0 mov w0, #0x5 // #5d8: b40000c8 cbz x8, f0 <ncv_color_cvt+0xf0>dc: f9400828 ldr x8, [x1,#16]e0: f100011f cmp x8, #0x0e4: 1a9f0000 csel w0, w0, wzr, eqe8: 14000002 b f0 <ncv_color_cvt+0xf0>ec: 52800080 mov w0, #0x4 // #4f0: f9401668 ldr x8, [x19,#40]f4: f85e83a9 ldur x9, [x29,#-24]f8: eb09011f cmp x8, x9fc: 540000e1 b.ne 118 <ncv_color_cvt+0x118>100: a9447bfd ldp x29, x30, [sp,#64]104: f9401bf3 ldr x19, [sp,#48]108: 910143ff add sp, sp, #0x5010c: d65f03c0 ret110: 528000a0 mov w0, #0x5 // #5114: 17fffff7 b f0 <ncv_color_cvt+0xf0>118: 94000000 bl 0 <__stack_chk_fail>
4. 反汇编有什么用处?
当发生 crash 时, 当程序耗时超出预期时, 都可以从汇编代码进一步分析。
举例: 对于一个C/C++函数,返回值类型不是 void; 如果缺失返回值,可能会在 Debug 模式发生 TRAP(crash,信号为TRAP), 在 Release 模式能运行而不会 Trap。 这时候可以从反汇编分析。
再举例: 对于 rgb 到 gray 的颜色空间转换, 在 Release 模式下的程序运行的很快, 在 Debug 模式下运行的稍慢, 并且如果手写了 arm neon (intrinsics)优化, 仍然和 Release 模式差不多快。 那么检查 Release 下的反汇编代码, 大概率是生成了 neon intrinsics 指令, 并且可能还把流水排布做了优化。
5. 搞一个网站查看反汇编呗!
很可惜, godbolt.org 目前还不支持 android-ndk 作为编译器。
对于 infra 比较到位的公司, 应该可以自行搭建一个在线网站来查看反汇编, 以及根据 crash 堆栈自动做分析等 (比如腾讯)。
6. 总结
给出了 android-ndk 程序查看反汇编代码的方法, 包括单个可执行文件、 基于 cmake 构建时的每个源代码文件。 简要提及了反汇编典型使用场景: crash 分析、 性能分析.
相关文章:
android-ndk开发(6): 查看反汇编
android-ndk开发(6): 查看反汇编 2025/05/05 1. 概要 android-ndk 是基于 clang 的工具链, clang 则保持了和 gcc 的高度兼容。 在 Linux 开发机上, GCC 套件里的 objdump 提供了反汇编的功能。 实际上 android-ndk 也提供了一份 objdump,…...
浅析AI大模型为何需要向量数据库?【入门基础】
文章目录 引言:大模型时代的存储挑战一、向量数据库:大模型的"海马体"1.1 什么是向量数据库?1.2 为什么大模型离不开向量数据库?(1) 嵌入(Embedding)的本质(2) 突破上下文窗口限制 二、相似性度量:欧氏距离与…...
Java面试:微服务与大数据场景下的技术挑战
面试对话场景 第一轮:基础知识考察 面试官:谢先生,您能简单介绍一下Java SE 8的新特性吗? 谢飞机:当然,Java SE 8引入了Lambda表达式、Stream API和新的日期时间API,大大简化了代码编写。 面…...
[前端]异步请求的竞态问题
竞态条件简介 遇到的问题 切换标签请求数据,但又快速切换标签请求数据,展示的是前一个标签的数据, 需要在切换标签时添加取消请求的机制,使用AbortController来取消正在进行的请求。当用户快速切换标签时,取消之前的请…...
【PDF拆分+提取内容改名】批量拆分PDF提取拆分后的每个PDF物流面单数据改名或导出表格,基于WPF的PDF物流面单批量处理方案
应用场景 物流行业每天需要处理大量包含物流面单的PDF文件,这些文件通常包含运单号、收发货人信息、货物详情等重要数据。传统手动处理方式效率低下且容易出错。本方案通过WPF实现一个自动化工具,能够: 批量拆分多页PDF为单页文件提取每页面单中的关键信息(如运单号、收件人…...
adb无线调试步骤
环境: macOS; 换成 linux 或 windows 也支持的小米15 Pro; 换成其他 android 手机也支持的 电脑和手机接入相同Wifi在电脑上,确保安装了 adb 对于 Android 开发者, 一般是是通过 Android Studio 安装对于 ndk 开发者…...
RocketMQ与Kafka的区别
文章目录 相同之处不同之处存储形式性能对比传输系统调用存储可靠性单机支持的队列数延时消息消息重复消息过滤消息失败重试死信队列 DLQ回溯消息分布式事务服务发现开发语言友好性开源社区活跃度商业支持成熟度 总结Kafka 和 RocketMQ 怎么选? 本文参考:…...
剥开 MP4 的 千层 “数字洋葱”:从外到内拆解通用媒体容器的核心
在当今数字化时代,MP4 格式随处可见,无论是在线视频、手机拍摄的短片,还是从各种渠道获取的音频视频文件,MP4 都占据着主流地位。它就像一个万能的 “数字媒体集装箱”,高效地整合和传输着各种视听内容。接下来&#x…...
设计模式(结构型)-组合模式
定义 组合模式的定义为:将对象组合成树形结构以表示 “部分 - 整体” 的层次结构,并且使得用户对单个对象和组合对象的使用具有一致性。其最关键的实现要点在于,简单对象和复合对象必须实现相同的接口,这一特性正是组合模式能够对…...
使用 IDEA + Maven 搭建传统 Spring MVC + Thymeleaf 项目的详细步骤
使用 IDEA Maven 搭建传统 Spring MVC Thymeleaf 项目 环境准备步骤 1:创建 Maven 项目步骤 2:添加依赖(pom.xml)步骤 3:配置 web.xml步骤 4:Spring 配置类(Java Config)步骤 5&am…...
「Mac畅玩AIGC与多模态19」开发篇15 - 判断节点与工具节点联动示例
一、概述 本篇在引入工具节点的基础上,进一步结合判断节点(条件分支),实现根据用户输入内容动态控制是否调用外部接口。通过构建“用户是否需要天气信息”的条件逻辑,开发人员将掌握如何在 Dify 工作流中通过条件判断…...
docker 外部能访问外网,内部不行(代理问题)
如果宿主机访问外网依赖代理(比如 http_proxy 环境变量),容器默认不会继承。需要显式传入代理: docker run -e http_proxy... -e https_proxy... ...在 docker-compose 中配置 HTTP/HTTPS 代理 version: 3 services:app:image: …...
模糊控制理论(含仿真)
本文讲解模糊控制理论、设计步骤以及案例。 1. 模糊控制原理: 模糊控制(Fuzzy Control)是一种基于模糊逻辑推理的人类经验规则实现的控制方法,适用于对系统模型不精确或难以建立精确数学模型的复杂系统。它利用“如果…那么…”&…...
《 C++ 点滴漫谈: 三十六 》lambda表达式
一、引言 在 C98 和 C03 时代,尽管 C 拥有强大的泛型编程能力和丰富的面向对象特性,但在表达局部逻辑、回调行为或一次性函数处理时,程序员却常常需要冗长的代码来定义函数对象(functor),或者使用函数指针…...
【C/C++】函数模板
🎯 C 学习笔记:函数模板(Function Template) 本文是面向 C 初学者的函数模板学习笔记,内容包括基本概念、定义与使用、实例化过程、注意事项等,附带示例代码,便于理解与复现。 📌 一…...
电赛经验分享——模块篇
1、前言 打算在这一个专栏中,分享一些本科控制题电赛期间的经验,和大家共同探讨,也希望能帮助刚刚参加电赛的同学,了解一些基本的知识。一些见解和看法可能不同或有错误,欢迎批评指正。 在本文中,主要介绍笔…...
LeetCode 热题 100 70. 爬楼梯
LeetCode 热题 100 | 70. 爬楼梯 大家好,今天我们来解决一道经典的动态规划入门题——爬楼梯。这道题在LeetCode上被标记为简单难度,要求我们计算爬到第n阶楼梯的不同方法数,每次可以爬1或2个台阶。下面我将详细讲解解题思路,并附…...
浔川AI测试版内测报告
浔川AI测试版内测报告 一、引言 本次对浔川AI测试版进行内测,旨在全面评估其功能表现与性能状况,为后续的优化升级及正式上线提供有力依据。 二、测试环境 1. 硬件环境:[Windows 10】 2. 软件环境:操作系统为【核桃编程]ÿ…...
Leetcode刷题记录31——旋转图像
题源:https://leetcode.cn/problems/rotate-image/description/?envTypestudy-plan-v2&envIdtop-100-liked 题目描述: 思路一: 💡 解题思路:分两步完成旋转 虽然“直接旋转”看起来有点抽象,但我们…...
攻防世界-php伪协议和文件包含
fileinclude 可以看到正常回显里面显示lan参数有cookie值表示为language 然后进行一个判断,如果参数不是等于英语,就加上.php,那我们就可以在前面进行注入一个参数,即flag, payload:COOKIE:languageflag …...
[C++] 小游戏 决战苍穹
大家好,各位看到这个标题,斗破苍穹什么时候改叫决战苍穹了?其实,因为版权等一系列问题,斗破苍穹正式改名为决战苍穹,这个版本主要更新内容为解决了皇冠竞技场太过影响游戏平衡,并且提高了一些装…...
项目成本管理_挣得进度ES
在项目成本管理的新实践中, 通过挣值管理(EVM) 的扩展,引入 挣得进度ES 这一概念, ES是EVM理论和实践的延伸,挣得进度理论用ES和实际时间(AT) 替代了传统EVM所使用的进度偏差测量指标SV(挣值—计划价值)。 使用这种替代方法计算…...
矩阵快速幂 快速求解递推公式
文章目录 习题790.多米诺和托米诺平铺 对于一个给定的递推公式,例如dp[i] dp[i-1] * a dp[i-2] * b,那么常用的做法,肯定是使用o(n)的时间复杂度进行线性求解,但是如果 n 10 18 n{10}^{18} n1018,那么肯定超时的,这…...
驱动开发硬核特训 · Day 28(上篇):pinctrl 子系统详解与实战分析
📅 日期:2025-05-05 📚 技术平台:嵌入式Jerry(B站) 一、引言 在嵌入式系统中,SoC 芯片的引脚通常具有多种功能,如 GPIO、UART、I2C、SPI 等。为了在不同的应用场景中灵活配置引脚功…...
20250505下载VLC for Android
20250505下载VLC for Android 2025/5/5 14:35 缘起:做Rockchip的RK3566的Android13下的跨网段PING。 酷芯的图传网段 和 softAP/以太网RJ45共享网段之间互相PING通。 图传的原厂/供应商说可以使用ffmpeg进行rtsp流的转发。 后来确认VLC for Android版本只有接受流&a…...
Jetpack Compose 响应式布局实战:BoxWithConstraints 完全指南
深入理解 Jetpack Compose 中的 BoxWithConstraints 前言 在构建现代 Android 应用时,响应式设计已成为必不可少的要求。Jetpack Compose 作为 Android 的现代 UI 工具包,提供了 BoxWithConstraints 这一强大组件,帮助我们轻松创建能够适应…...
ZYNQ笔记(十七):IP核封装与接口定义
版本:Vivado2020.2(Vitis) 任务:将“HDMI彩条显示实验”(正点原子 ZYNQ FPGA 开发视频)中所实现的 RGB2DVI 模块封装成一个 IP 核。 目录 一、介绍 (1)IP核 (2&#x…...
学习笔记msp430f5529lp
注:本文仅用于个人学习使用,记录笔记。 学习视频msp430f5529库函数入门教程 00.序言_哔哩哔哩_bilibili 向大佬致敬理工男小帅-CSDN博客 CCS环境快捷键使用 代码注释:Ctrl/ 提示/补全: CtrlShiftC 放大:Ctrl 缩小:Ctrl- 切换选择模式&…...
人工智能应用:从技术突破到生态重构的演进之路
一、人工智能的发展历程:从符号主义到通用智能探索 人工智能(AI)的发展始于20世纪中叶,其历程可划分为四个关键阶段: 符号主义与早期探索(1950s-1970s) 以逻辑推理和专家系统为核心&…...
【ZYNQ Linux移植】4-内核移植
文章目录 0 写在前面1 内核源码的文件结构2 Linux内核移植2.1 移植配置文件2.2 移植设备树2.3 创建脚本进行编译2.4 备份相关文件 3 测试4 总结5 参考资料 0 写在前面 这是一个系列博客,详细介绍如何在 ZYNQ 与 ZYNQ MP 平台上如何移植 Linux 系统。目前网络上的大部…...
代码随想录算法训练营第三十二天
LeetCode/卡码网题目: 518. 零钱兑换 II377. 组合总和 Ⅳ790. 多米诺和托米诺平铺(每日一题)57. 爬楼梯(第八期模拟笔试) 其他: 今日总结 往期打卡 背包问题特点: 滚动数组背包遍历顺序 完全背包从小到大,即基于当前物品更新过的继续更新01背包从大到…...
java CompletableFuture 异步编程工具用法1
1、测试异步调用: static void testCompletableFuture1() throws ExecutionException, InterruptedException {// 1、无返回值的异步任务。异步线程执行RunnableCompletableFuture.runAsync(() -> System.out.println("only you"));// 2、有返回值的异…...
Spring Boot 集成 Solr 的详细步骤及示例
环境准备 安装 Solr :从 Solr 官网(Welcome to Apache Solr - Apache Solr)下载并安装最新版本,然后通过命令 bin/solr start 启动 Solr 服务,使用 bin/solr create -c mycore 创建一个新的 Solr 核心。 安装 JDK &am…...
Nemotron-Research-Tool-N1 如何提升大语言模型工具使用能力?
Nemotron-Research-Tool-N1如何提升大语言模型工具使用能力? 如今,大语言模型(LLMs)发展迅猛,给它配备外部工具成为研究热点。但传统方法存在不少问题。这篇论文提出的Nemotron-Research-Tool-N1系列模型带来新突破&a…...
OpenCV进阶操作:图像直方图、直方图均衡化
文章目录 一、图像直方图二、图像直方图的作用三、使用matplotlib方法绘制直方图2.使用opencv的方法绘制直方图(划分16个小的子亮度区间)3、绘制彩色图像的直方图 四、直方图均衡化1、绘制原图的直方图2、绘制经过直方图均衡化后的图片的直方图3、自适应…...
Android控件VideoView用法
一 控件UI <VideoViewandroid:id="@+id/videoView"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitCenter" /> 二 配置 <?xml version="1.0" encoding="u…...
人工智能数学基础(十)—— 图论
图论作为数学的重要分支,为人工智能提供了强大的建模和分析工具。无论是社交网络分析、路径规划还是数据结构设计,图论都发挥着不可替代的作用。今天,我将带领大家深入浅出地探索图论的核心概念,并结合 Python 实例,让…...
深入探索Anthropic Claude与Spring AI的融合应用
深入探索Anthropic Claude与Spring AI的融合应用 前言 在人工智能的蓬勃发展进程中,自然语言处理领域不断涌现出强大的模型和工具。Anthropic Claude系列基础AI模型凭借其出色的性能,在各种应用场景中展现出巨大潜力,为开发者和企业提供了丰…...
Python爬虫实战:获取优美图库各类高清图片,为用户提供设计素材
一、引言 在互联网时代,高清壁纸资源丰富多样,而优美图库作为一个提供大量精美壁纸的网站,吸引了众多用户。通过 Python 爬虫技术,可以自动化地从该网站获取所需的壁纸资源,为用户节省时间和精力。然而,网站通常会采取反爬措施来防止数据被恶意抓取,因此需要在爬虫程序…...
Java常用注解大全(基于JDK17+SpringBoot3)
一、基础注解(Java原生) 编译相关 @Override:方法重写校验 java 复制 下载 @Override public String toString() { return "CustomObj"; } @Deprecated:标记过时元素 java 复制 下载 @Deprecated(since="1.8", forRemoval=true) public void oldMethod…...
【NLP】30. 深入理解 In-Context Learning 的核心机制与策略
In-Context Learning(ICL)详解:提示学习时代的语言理解 一、什么是 In-Context Learning(ICL)? In-Context Learning 是指: 不改变模型参数,通过在输入中加入示例(demon…...
数字化工厂中央控制室驾驶舱系统 - Windows 部署笔记
数字化工厂中央控制室驾驶舱系统 - Windows 部署笔记 环境准备 这篇笔记记录了我在 Windows 10/11 上部署数字化工厂中央控制室驾驶舱系统的全过程,包括各种常见问题的解决方法。部署过程中使用了国内镜像源来加快下载速度。 前置需求 Python:3.8 到…...
数据库的原子事务
原子事务 11.1 全有或全无效应 二级索引需要原子性的多键更新,这不仅对数据库内部一致性至关重要,也对应用数据的一致性非常有用(例如考虑账户余额和账户交易)。 我们将放弃get-set-del接口,并添加一个新的接口来允…...
基于51单片机的红外人体感应报警器
基于51单片机的人体监测报警 (仿真+程序+原理图+PCB) 功能介绍 具体功能: 1.按下报警按钮会发生红LED蜂鸣器声光报警; 2.若检测到人,黄LED打开; 3.按下布防按键&…...
从Excel到高级工具:数据分析进阶指南
从Excel到高级工具:数据分析进阶指南 在数据分析的世界里,Excel曾经是众多人的第一站。它简单、直观、功能强大,从普通用户到专业人士,无不对其依赖。然而,随着数据规模增长、分析需求升级,Excel渐渐显得力…...
Excel VBA 自定义函数
一、VBA 函数基础概念 在 Excel VBA 中,函数主要分为两种类型: Sub 过程:执行操作但不返回值Function 函数:执行操作并返回结果 基本语法示例 1. Function 函数示例 定义一个返回字符串的公共函数 Public Function GetGreetin…...
004-nlohmann/json 快速认识-C++开源库108杰
了解 nlohmann/json 的特点;理解编程中 “数据战场”划分的概念;迅速上手多种方式构建一个JSON对象; 1 特点与安装 nlohmann/json 是一个在 github 长期霸占 “JSON” 热搜版第1的CJSON处理库。它的最大优点是与 C 标准库的容器数据…...
【Quest开发】接入语音转文字
参考官方文档:https://developers.meta.com/horizon/documentation/unity/voice-sdk-tutorials-overview 软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72 硬件:Meta Quest3 注意:需全程科学上网 Meta提供了一…...
Vim 命令从头学习记录
学习链接:eleon-vim基础教程 Vim - 基础翻屏操作 光标移动:hjkl 20j 向下移动20行,w 向后移动一个字符,b 向前移动一个字符。 Ctrl u 向上翻半页 UP Ctrl d 向下翻半页 Down Ctrl f 向下翻整页 Forward Ctrl b 向上翻整页 …...
[Linux]物理地址到虚拟地址的转化
[Linux]物理地址到虚拟地址的转化 水墨不写bug 文章目录 一、再次认识地址空间二、页表1、页表的结构设计2、页表节省了空间,省在哪里?3、页表的物理实现 一、再次认识地址空间 OS和磁盘交互的内存基本单位是4KB,这4KB通常被称为内存块。OS对…...