Android学习总结之APK打包流程
一、预处理阶段(编译前准备)
1. AIDL 文件处理(进程间通信基础)
- 流程:
- 用于实现 Android 系统中不同进程间的通信(IPC)。
- 在项目构建时,AIDL 编译器会将
.aidl
文件编译为 Java 接口文件。
- 面试考点:
- AIDL 如何生成 Binder 通信代码?(自动生成
Stub
类,实现 Binder 接口) - 为什么 AIDL 文件需要先编译?(其生成的 Java 文件是后续代码编译的依赖)
- AIDL 如何生成 Binder 通信代码?(自动生成
扩展:
- 问题:AIDL 中使用自定义对象时,为什么要实现
Parcelable
接口?- 解答:由于不同进程间的内存空间是独立的,对象不能直接在进程间传递。
Parcelable
接口提供了一种高效的序列化和反序列化机制,通过将对象转换为字节流,使得对象可以在不同进程间传输。例如,一个自定义的User
对象,实现Parcelable
接口后,可以在 AIDL 接口中作为参数或返回值使用。
- 解答:由于不同进程间的内存空间是独立的,对象不能直接在进程间传递。
- 问题:AIDL 接口方法的调用是同步还是异步的?
- 解答:AIDL 接口方法的调用默认是同步的。如果在客户端调用 AIDL 服务端的方法,客户端线程会被阻塞,直到服务端方法执行完成并返回结果。如果需要异步调用,可以使用 Messenger 或 Handler 来实现。例如,在客户端可以创建一个新的线程来调用 AIDL 方法,避免阻塞主线程。
2. 生成 BuildConfig 类(动态配置注入)
- 流程:
- Android 构建系统自动生成的,用于存储项目的构建配置信息。
- 通过在
build.gradle
文件中使用buildConfigField
可以向BuildConfig
类中添加自定义的静态常量。
- 面试考点:
BuildConfig
和Manifest
中meta-data
的区别?(前者是编译时常量,后者是运行时读取的资源)- 如何在不同 Build Variant(如 Debug/Release)中差异化配置?(通过
buildTypes
分别定义)
扩展
- 问题:
BuildConfig
类有什么作用?- 解答:
BuildConfig
类主要用于在代码中区分不同的构建环境(如 Debug 和 Release),以及存储一些配置信息。例如,可以在BuildConfig
中定义一个布尔类型的常量DEBUG_MODE
,在 Debug 环境下设置为true
,在 Release 环境下设置为false
,这样在代码中就可以根据这个常量来控制一些调试相关的代码是否执行。还可以存储 API 密钥、服务器地址等配置信息,避免在代码中硬编码这些信息。
- 解答:
- 问题:如何在
BuildConfig
中添加自定义的常量?- 解答:在
build.gradle
文件的defaultConfig
或不同的buildTypes
中使用buildConfigField
来添加自定义常量。例如:
- 解答:在
android {defaultConfig {buildConfigField "String", "API_KEY", "\"your_api_key\""buildConfigField "boolean", "DEBUG_MODE", "true"}
}
这样就可以在代码中通过 BuildConfig.API_KEY
和 BuildConfig.DEBUG_MODE
来访问这些常量。
- 问题:
BuildConfig
类的常量在不同构建类型下可以有不同的值吗?- 解答:可以。可以在不同的
buildTypes
中为BuildConfig
类的常量设置不同的值。例如:
- 解答:可以。可以在不同的
android {buildTypes {debug {buildConfigField "String", "SERVER_URL", "\"http://debug-server.com\""}release {buildConfigField "String", "SERVER_URL", "\"http://release-server.com\""}}
}
这样在 Debug 构建类型下,BuildConfig.SERVER_URL
的值为 "http://debug-server.com"
,在 Release 构建类型下,其值为 "http://release-server.com"
。
二、资源处理阶段(核心依赖生成)
3. 合并资源文件(Manifest/Res/Assets)
- 流程:
- 使用 AAPT2.0 工具合并项目中的
Resources
、assets
、manifest
、so
等资源文件。 - AAPT2.0 会将 XML 文件(除 drawable 图片外)编译成二进制文件,生成资源索引表
resources.arsc
和资源 ID 常量类R.java
。 assets
和raw
目录下的资源不会被编译,会原封不动地打包到 APK 压缩包中。
- 使用 AAPT2.0 工具合并项目中的
- 关联:
- 代码中引用资源(如
findViewById(R.id.button)
)依赖R.java
,而R.java
的生成依赖aapt2
对资源的处理。
- 代码中引用资源(如
- 面试考点:
- 为什么 APK 解压后 XML 文件无法直接阅读?(被 aapt2 编译为二进制格式)
assets
和res
的区别?(前者不生成资源 ID,需通过AssetManager
读取;后者生成 ID,通过R.xxx
引用)
扩展
- 问题:为什么要将 XML 文件编译成二进制文件?
- 解答:将 XML 文件编译成二进制文件有以下好处:一是可以减少资源文件的体积,因为二进制文件的存储效率更高;二是提高解析速度,二进制文件的解析比 XML 文件更快,能够提升应用的性能。例如,布局文件编译成二进制文件后,在应用启动时可以更快地加载和显示界面。
- 问题:
assets
和raw
目录有什么区别?- 解答:
assets
目录可以有子目录结构,适合存放需要动态加载的资源,如 HTML 文件、字体文件等,并且可以通过AssetManager
来访问其中的资源。raw
目录只能存放文件,不能有子目录,通常用于存放原始的二进制文件,如音频文件、视频文件等,可以通过R.raw
来访问其中的资源。
- 解答:
- 问题:
resources.arsc
文件和R.java
文件的作用分别是什么?- 解答:
resources.arsc
文件是一个资源索引表,它保存了所有资源的元数据和索引信息,系统可以通过这个文件快速定位和查找资源。R.java
文件定义了各个资源的 ID 常量,在代码中可以通过这些常量来引用资源。例如,R.layout.activity_main
表示activity_main.xml
布局文件的资源 ID。
- 解答:
4. 处理 AAR/JAR 依赖(库文件整合)
- 流程:
- 解析
build.gradle
中的依赖(如implementation 'com.example:lib:1.0'
),将 AAR 中的资源、类文件与主项目合并(AAR 包含编译后的.class
和资源,JAR 仅含.class
)。 - 冲突处理:若资源 ID 冲突(如两个库都有
R.id.button
),Gradle 通过resourcePrefix
或手动调整解决。
- 解析
- 关联:
- 库的资源和代码需在后续编译阶段与主项目一起处理,是代码编译和资源合并的输入。
- 面试考点:
- AAR 和 JAR 的区别?(AAR 包含资源和清单文件,JAR 仅含类文件)
- 如何解决依赖冲突?(排除冲突模块、调整版本、使用
android:allowBackup
等属性优先级)
三、代码编译阶段(从源码到可执行文件)
5. 编译 Java/Kotlin 代码(生成.class 文件)
- 流程:
- Java 代码:通过
javac
编译所有 Java 源码(包括 AIDL 生成的 Java 文件、R.java
、用户代码),生成.class
文件(对应 JVM 字节码)。 - Kotlin 代码:通过
Kotlin Compiler
编译为.class
文件(与 Java 字节码兼容),可与 Java 代码混合运行。
- Java 代码:通过
- 关联:
- 编译依赖前序生成的
R.java
和BuildConfig
(代码中需引用资源 ID 和常量),若资源处理失败,编译会报错(如 “找不到 R.id.xxx”)。
- 编译依赖前序生成的
- 面试考点:
- Kotlin 编译如何与 Java 兼容?(生成 JVM 字节码,遵循 Java 命名规范)
- 编译时如何处理注解?(通过
Annotation Processor
,如 ButterKnife 在编译期生成绑定代码)
扩展
- 问题:Kotlin 代码和 Java 代码在编译过程中有什么不同?
- 解答:Kotlin 代码使用 Kotlin 编译器进行编译,而 Java 代码使用
javac
编译器。Kotlin 编译器会将 Kotlin 代码转换为与 Java 兼容的字节码,并且在编译时会进行一些额外的处理,如 null 安全检查、协程支持等。另外,Kotlin 代码可以使用更简洁的语法,在编译时会被转换为对应的 Java 字节码。
- 解答:Kotlin 代码使用 Kotlin 编译器进行编译,而 Java 代码使用
- 问题:如果项目中同时存在 Java 和 Kotlin 代码,编译过程是怎样的?
- 解答:Gradle 会先使用 Kotlin 编译器编译 Kotlin 代码,生成
.class
文件。然后再使用javac
编译器编译 Java 代码,包括 AIDL 生成的 Java 文件和R.java
文件。最后将所有的.class
文件进行合并处理。在这个过程中,Kotlin 代码和 Java 代码可以相互调用,因为它们最终都被编译成了.class
文件。
- 解答:Gradle 会先使用 Kotlin 编译器编译 Kotlin 代码,生成
- 问题:如何解决 Java 和 Kotlin 代码混合编译时可能出现的问题?
- 解答:首先要确保 Kotlin 和 Java 的版本兼容。在项目中可以使用
kotlin-android
插件来支持 Kotlin 代码的编译。如果出现类型不匹配等问题,需要检查代码中对 Java 和 Kotlin 类型的使用是否正确。另外,在使用 Java 库时,要注意一些 Java 库可能不支持 Kotlin 的某些特性,需要进行相应的处理。
- 解答:首先要确保 Kotlin 和 Java 的版本兼容。在项目中可以使用
6. 转换为 Dex 文件(Android 虚拟机适配)
- 流程:
- 早期使用
dx
工具将.class
文件转换为 Dalvik 字节码(.dex
格式), - Android 8.0 + 引入
D8
(优化版 dx),Android 9.0 + 默认使用R8
(集成代码混淆和优化)。 - 优化步骤:
- 代码混淆(ProGuard/R8):通过
minifyEnabled true
开启,重命名类 / 方法(如a.class
),删除未使用代码(如-keep
规则保留反射使用的类)。 - dex 合并 :若多个
.class
文件(如主项目 + 库),合并为单个或多个.dex
(Android 5.0 + 支持多 dex,通过MultiDex
处理)。
- 代码混淆(ProGuard/R8):通过
- 早期使用
- 关联:
.dex
是 Dalvik/ART 虚拟机的执行格式,必须在.class
编译后进行转换,且混淆优化可减小 APK 体积。
- 面试考点:
- 为什么需要将.class 转为.dex?(Dalvik 虚拟机不直接支持 JVM 字节码,.dex 是压缩后的格式,减少内存占用)
- R8 相比 ProGuard 的优势?(更快的编译速度,深度优化与混淆结合,支持 Lambda 表达式)
扩展
- 问题:为什么要将
.class
文件打包成 DEX 文件?- 解答:Android 系统中的 Dalvik/ART 虚拟机只能执行 DEX 格式的文件,因此需要将 Java 或 Kotlin 编译后的
.class
文件打包成 DEX 文件,以便在 Android 设备上运行。另外,DEX 文件对多个.class
文件进行了优化合并,减少了文件体积和 I/O 开销。
- 解答:Android 系统中的 Dalvik/ART 虚拟机只能执行 DEX 格式的文件,因此需要将 Java 或 Kotlin 编译后的
- 问题:R8 相比 D8 有什么优势?
- 解答:R8 不仅可以将
.class
文件转换为 DEX 文件,还集成了代码压缩和混淆功能。它可以删除无用的代码,重命名类和方法,从而减少 APK 的体积,提高代码的安全性。而 D8 主要负责将.class
文件转换为 DEX 文件,没有代码压缩和混淆功能。
- 解答:R8 不仅可以将
- 问题:在什么情况下会出现方法数超限(65536 限制)问题,如何解决?
- 解答:当项目中的方法数超过 65536 个时,会出现方法数超限问题。这通常发生在项目规模较大、引入了大量依赖库的情况下。解决方法是启用 MultiDex。在
build.gradle
文件中添加multiDexEnabled true
,并确保minSdkVersion
不低于 21(ART 支持自动加载多个 dex,低于 21 需手动初始化MultiDex.install(this)
)
- 解答:当项目中的方法数超过 65536 个时,会出现方法数超限问题。这通常发生在项目规模较大、引入了大量依赖库的情况下。解决方法是启用 MultiDex。在
四、打包生成 APK(整合所有产物)
7. 构建 APK 二进制包
- 流程:
- 工具演进:
- AGP 3.6.0 前使用
apkbuilder
,之后默认使用zipflinger
(基于 ZIP 流操作,避免内存峰值,提升构建速度)。
- AGP 3.6.0 前使用
- 打包内容:
- 合并所有编译后的产物:
.dex
文件、资源文件(res/
编译结果 +assets/
)、AndroidManifest.xml
、so
库(jniLibs/
目录,按 CPU 架构分目录)、META-INF/
(签名相关)等。
- 合并所有编译后的产物:
- 工具演进:
- 关联:
- 打包依赖前序生成的
.dex
、resources.arsc
、AndroidManifest.xml
等文件,是各阶段产物的最终整合。
- 打包依赖前序生成的
- 面试考点:
- 为什么 zipflinger 比 apkbuilder 快?(流式处理,无需一次性加载所有文件到内存)
- 如何处理多 ABI 架构的 so 库?(Gradle 根据
ndk.abiFilters
过滤,仅保留指定架构,如armeabi-v7a
)
扩展
- 问题:
zipflinger
相比apkbuilder
有什么优势?- 解答:
zipflinger
是一个高性能的 ZIP 打包工具,它采用了更高效的算法和数据结构,减少了打包过程中的 I/O 操作,能够显著提高 APK 的构建速度,尤其是在处理大型项目时。而apkbuilder
的性能相对较低。
- 解答:
- 问题:如何优化 APK 的构建速度?
- 解答:可以采取以下措施来优化 APK 的构建速度:使用 Gradle 缓存(
android.enableBuildCache=true
)、启用增量编译、减少不必要的依赖、分模块构建、禁用调试信息(debuggable false
)等。另外,使用zipflinger
等高性能的打包工具也可以提高构建速度。
- 解答:可以采取以下措施来优化 APK 的构建速度:使用 Gradle 缓存(
8. zipalign 对齐(提升 IO 效率)
- 流程:
- 使用
zipalign
工具对 APK 进行对齐处理,确保未压缩的资源(如图像、视频)在 APK 中的偏移量为 4 字节的整数倍(Android 要求)。
- 使用
- 关联:
- 对齐是签名前的步骤(签名后再对齐会破坏签名),目的是让系统更高效地读取 APK 内的资源,减少内存消耗。
- 面试考点:
- 为什么需要 4 字节对齐?(Android 内存页大小为 4KB,对齐后可直接通过内存映射读取资源,避免额外复制)
- 不对齐会有什么问题?(可能导致资源读取缓慢,甚至安装失败)
扩展
- 问题:
zipalign
对齐操作对 APK 有什么影响?- 解答:对齐操作可以提高 APK 中资源的访问速度,减少内存访问的开销。当资源按照 4 字节的边界对齐时,系统可以更高效地读取资源,尤其是在处理大量资源的情况下。同时,对齐后的 APK 在安装和运行时也会更加高效。
- 问题:如何判断一个 APK 是否已经经过
zipalign
处理?- 解答:可以使用
zipalign -c -v 4 your_app.apk
命令来检查 APK 是否已经对齐。如果输出结果显示Verification successful
,则表示 APK 已经对齐。
- 解答:可以使用
五、签名阶段(安全性核心)
9. APK 签名(验证完整性和来源)
- 流程:
- 签名方式:
- v1 签名(JAR 签名):通过
apksigner
使用私钥对 APK 内容签名,生成META-INF/CERT.SF
等文件,验证 APK 是否被篡改。 - v2 签名(全文件签名):Android 7.0 + 引入,对 APK 整包进行加密签名(非 ZIP 条目级签名),提升安全性和验证速度。
- v3 签名(增量更新):Android 9.0 + 支持,允许 APK 部分更新(如修复补丁),减少下载体积。
- v1 签名(JAR 签名):通过
- 关联:
- 签名是打包的最后一步(对齐后),未签名的 APK 无法在设备上安装。不同签名版本可同时启用(如 v1+v2),兼容旧设备。
- 签名方式:
- 面试考点:
- v1 和 v2 签名的区别?(v1 基于 ZIP 条目,可修改 APK 内容后重新签名;v2 对整包签名,修改任何字节都会导致签名失效)
- 为什么发布版本必须签名?(系统通过签名验证开发者身份,防止恶意篡改)
六、全流程关联总结
- 依赖链:
源码(AIDL/.java/.kt) → 资源处理(生成R.java/resources.arsc) → 代码编译(.class) → Dex转换(优化/混淆) → 打包(整合资源+Dex) → 对齐 → 签名
- 核心工具链:
- 资源处理:
aapt2
→ 代码编译:javac
/Kotlin Compiler
→ Dex 转换:R8
→ 打包:zipflinger
→ 对齐:zipalign
→ 签名:apksigner
。
- 资源处理:
- 面试高频问题串联:
- Q:APK 体积过大如何优化?
A:资源处理阶段压缩图片(WebP 格式)、删除未使用资源(shrinkResources true
);Dex 阶段开启混淆(R8 删除无效代码);签名阶段按需保留 ABI 架构(abiFilters
)。 - Q:编译时如何处理多模块资源冲突?
A:通过resourcePrefix
为模块指定唯一前缀(如"module1_"
),或在build.gradle
中排除冲突资源(android { packagingOptions { exclude 'res/drawable/conflict.png' } }
)。
- Q:APK 体积过大如何优化?
相关文章:
Android学习总结之APK打包流程
一、预处理阶段(编译前准备) 1. AIDL 文件处理(进程间通信基础) 流程: 用于实现 Android 系统中不同进程间的通信(IPC)。在项目构建时,AIDL 编译器会将 .aidl 文件编译为 Java 接口…...
java面试篇(常见的集合底层原理)
集合 1、arraylist源码分析 三种构造方法: 扩容的逻辑: 2、ArrayList的底层实现原理是什么? ArrayList listnew ArrayList(10)中的list扩容几次 3、如何实现数组和List之间的转换 4、LinkedList和arraylist的区别 5、hashmap的实现原理 二叉…...
RAG框架精选2
原文链接:https://i68.ltd/notes/posts/20250406-llm-rag2/ 清华Hyper-RAG 使用超图驱动的RAG对抗LLM幻觉论文链接:https://arxiv.org/pdf/2504.08758项目仓库:https://github.com/iMoonLab/Hyper-RAG清华Hyper-RAG:利用超图建模高阶关系,让DeepSeek/Q…...
Redis进阶学习
什么是Redis? Redis是一个key-value结构的非关系型数据库,将数据存储在内存中,结构简单(五种数据结构:string、list、set、zset、hash),数据读写速度快,还可以将数据持久化到硬盘上。…...
【读书笔记·VLSI电路设计方法解密】问题63:为什么可测试性设计对产品的财务成功至关重要
可测试性设计至关重要,因为我们不希望将劣质或故障部件交付给客户。向客户交付过多不良部件意味着财务灾难,更会损害企业声誉并导致商业机会流失。 若设计中未嵌入可测试性设计(DFT),区分良品与不良品的唯一方法就是由应用工程师或客户在实际应用环境中测试芯片。此时芯片…...
Federated Weakly Supervised Video Anomaly Detection with Multimodal Prompt
标题:联邦弱监督视频异常检测的多模态提示方法 原文链接:https://ojs.aaai.org/index.php/AAAI/article/view/35398 源码链接:https://github.com/wbfwonderful/Fed-WSVAD 发表:AAAI-2025 摘要(Abstract) …...
计算机视觉与深度学习 | LSTM原理,公式,代码,应用
LSTM(长短期记忆网络)详解 一、原理 LSTM(Long Short-Term Memory)是RNN的改进版本,通过引入门控机制(输入门、遗忘门、输出门)和细胞状态(Cell State),有效解决传统RNN的梯度消失/爆炸问题,擅长捕捉长距离依赖关系。 核心思想: 细胞状态(C_t):贯穿整个时间步…...
UI界面工程,如何使用控制台
我们通常会使用print函数向控制台输出调试信息。但创建UI界面工程时,默认不会显示控制台。 通过如下方法切换到控制台 项目属性—链接器—系统—子系统—窗口改为控制台...
mysql——基础知识
关键字大小写不敏感 查看表结构中的 desc describe 描述 降序中的 desc descend 1. 数据库的操作 1. 创建数据库 create database 数据库名;为防止创建的数据库重复 CREATE DATABASE IF NOT EXISTS 数据库名;手动设置数据库采用的字符集 character set 字符集名;chars…...
UE虚幻4虚幻5动画蓝图调试,触发FellOutOfWorld事件和打印输出,继续DeepSeek输出
找到了一个pdf,本来想写个翻译的,但还是算了,大概看了下,这类文档很全面,内容很多,但都不是我要的,我想要一个动画蓝图,搜索Montage,或者Anim 只占了一行(几百…...
52单片机LED实验
文章目录 前言点亮一个LEDLED闪烁 LED灯亮灭交替LED流水灯 前言 我所用的板子是普中的STC89C52RC,创建文件的过程中如果你发现keil文件找不到单片机依赖,那怎么办呢 下面从创建新项目讲起 首先打开keil软件,点击project new一个新的projec…...
【C++详解】C++入门(一)命名空间、缺省参数、函数重载
文章目录 一、命名空间命名空间的基本特性命名空间的使用 二、C输入输出用法三、缺省参数(默认参数)定义用法 四、函数重载 一、命名空间 命名空间的基本特性 #include <stdio.h> #include <stdlib.h>int rand 10;int main() {// 编译报错:error C23…...
AWS Linux快速指南:5分钟搭建多用户图形界面
一、概述 本指南将帮助您在AWS上快速部署一个支持多用户、带图形界面和浏览器的Linux环境。我们将使用Ubuntu Server作为基础,配合轻量级的Xfce桌面环境和VNC服务。同时,我们还将提供不同用户规模下的实例规格推荐。 二、实例规格推荐 根据您的用户规模,我们推荐以下EC2实例…...
kotlin,编码、解码
kotlin写程序确实简洁,就是函数式编程对我这种用惯了过程的,换思想有难度。package org.exampleimport java.io.File import java.io.FileNotFoundExceptionval byteToHanzi mapOf(0x00 to "凡", 0x01 to "周", 0x02 to "张&q…...
从零创建 Docker 镜像(基于 OCI 格式)
更现代的 OCI 镜像格式,采用了 OCI Image Format Specification,其中文件引用使用 blobs/sha256/<hash> 的形式,层和配置存储在 blobs/sha256/ 目录下,并且包含 LayerSources 字段。这种格式在较新的 Docker 版本和 OCI 兼容…...
JavaScript 版本号比较
问题描述: 实现 : <script>const compare function(v1,v2){const arr1 v1.split(.)const arr2 v2.split(.)for(let i 0;i<arr1.length||i<arr2.length;i){const a arr1[i]||0const b arr2[i]||0if(a>b){return 1}else if(a<b){…...
MySQL为什么默认使用RR隔离级别?
大家好,我是锋哥。今天分享关于【MySQL为什么默认使用RR隔离级别?】面试题。希望对大家有帮助; MySQL为什么默认使用RR隔离级别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL 默认使用 RR(Repeatable Read)…...
第37讲|AI+农业气象建模:预测极端天气对农业的影响
目录 ✨ 导语:天气不可控,但影响可以预测 📦 一、数据准备:融合农业与气象 ⚡ 二、极端天气如何“定义”? 🔧 三、模型选择与结构设计 🔁 时间序列模型:LSTM 🎯 非时序模型:XGBoost / LightGBM 🧪 四、案例实战:用LSTM预测小麦产量下降风险(受极端天气…...
(done) 吴恩达版提示词工程 1. 引言 (Base LLM 和 Instruction Tuned LLM)
url: https://www.bilibili.com/video/BV1Z14y1Z7LJ/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 LLM 有两种: 1.基础 LLM,通过文本训练数据预测后面的内容。 这种 LLM 当你给它提问:What is…...
Vue如何实现样式隔离
1. 使用 CSS Modules CSS Modules 允许你在 Vue 组件中定义局部作用域的 CSS,这样可以避免全局样式的冲突 步骤如下: 在你的 Vue 组件中,创建一个 <style> 标签并添加 module 属性。 <template><div :class"$style.c…...
Sentinel源码—6.熔断降级和数据统计的实现二
大纲 1.DegradeSlot实现熔断降级的原理与源码 2.Sentinel数据指标统计的滑动窗口算法 2.Sentinel数据指标统计的滑动窗口算法 (1)滑动窗口介绍 (2)StatisticSlot使用滑动窗口算法进行数据统计 (1)滑动窗口介绍 一.滑动窗口原理 滑动窗口不会指定固定的时间窗口起点与终点…...
B+树删除和测试
B树删除和测试 5.1 高级接口:B 树作为键值存储 在本章中,我们将实现 B 树的高级接口,使其能够作为键值存储(Key-Value Store)使用。这些接口包括插入和删除操作,并处理根节点的维护。 1. 插入接口 1.1 I…...
常用算法解析:从基础排序到图论应用
一、算法基础与设计原则 算法是计算机解决问题的核心工具,其五大基本特性决定了程序的可靠性: 有穷性:算法必须能在有限步骤内终止确定性:每步操作无歧义可行性:可被计算机执行输入输出:具备数据交互能力…...
Java Web项目(一)
框架 java web项目总工分为两部分:客户端(前端)和服务端(后端) 客户端发起请求,服务端接受请求并进行处理 发起请求的方式:from表单、jQuery ajax from表单 造成全局的变化,在发…...
兴达易控DP主站网关数据映射快速配置案例
兴达易控DP主站网关数据映射快速配置案例 在工业自动化的领域,不同通讯协议之间的转换是常见的需求。特别是Profibus DP与Modbus-RTU这两种广泛应用于不同系统和设备的通讯协议,它们之间的数据转换显得尤为重要。本文将详细探讨兴达易控Profibus DP主站…...
Tailwindcss 入门 v4.1
以 react 为例,步骤如下: npm create vitelatest my-app -- --template react 选择 React 和 JavaScript 根据上述命令的输出提示,运行以下命令 cd my-app npm install npm run dev 一个 React App 初始化完成。 安装 Tailwindcss theme …...
通过 WebSocket 接收和播放 WSS 协议视频流
1.创建wss协议视频 1.1必备包 npm install ws ffmpeg-installer/ffmpeg fluent-ffmpeg 说明:安装以下三个包。 1.2代码实现 说明:创建WebSocket服务器,端口为8080 import { WebSocket, WebSocketServer } from ws; // 导入 WebSocket 和 W…...
HTML 如何改变字体颜色?深入解析与实践指南
网页上的字体颜色是网页设计中至关重要的元素之一,它像字体大小一样,对于提升用户体验起着举足轻重的作用。精心选择和运用字体颜色,能够增强页面的可读性、突出重点信息、营造特定的情感氛围,甚至直接影响用户的视觉感受和品牌认…...
tigase源码学习杂记-组件化设计
前言 tigase官方号称高度抽象和组件化。这篇文章就记录一下我研究组件化的相关设计 概述 我的理解tigase高度组件化是所有的关键的功能的类,它都称之为组件,即只要继承于BasicComponent,它都可以成为组件,BasicComponent类实现…...
十二、人工神经网络及其应用
写在前面 这部分内容老师说很重要,不管是实验还是考试占比都非常大 AIGC的全称是“Artificial Intelligence Generated Content”,即人工智能生成内容。这一术语通常用于指代通过人工智能技术自动生成的各种类型的内容,如文本、图像、音频和视频等。随着AI技术的发展,AIG…...
vscode使用技巧
一、符号定位技巧 跳转到定义 F12 或右键「Go to Definition」跳转到符号定义位置CtrlClick 直接点击符号跳转(支持变量/函数/类) 符号大纲视图 CtrlShiftO 打开文件符号大纲,支持模糊搜索符号名输入: 分类显示符号(…...
测试基础笔记第七天
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、cat命令二、ls -al命令三、>重定向符号四、>>追加重定向符号五、less/more命令六、grep命令七、|管道符八、clear命令九、head命令十、tail命令十一、…...
FOC控制中的正弦PWM和空间矢量PWM对比与理解
参考: simple foc:https://docs.simplefoc.com/docs_chinese/foc_theory博客:https://blog.csdn.net/qq_43332314/article/details/126449398 一、无刷电机基础原理 1., 原理图:至少三个绕组线圈(定子&…...
【Oracle专栏】函数中SQL拼接参数 报错处理
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 最近同事反馈了一个很奇怪的问题,即有一个函数,入参是当前年月,主要作用是通过SQL语句将不合规的数据插入到指定表中,插入数据时带上入参的年月参数。当前问题:单独测试SQL没有问题可以执行成功,…...
无意间发现的宝藏项目:开源世界中的演示项目精选合集
🌟无意间发现的宝藏项目:开源世界中的演示项目精选合集 最近在 GitHub 上随手翻了翻 Spring 官方代码仓库,意外发现一个超有趣的演示项目 —— spring-petclinic。一个轻量但结构完整的 Spring 全家桶演示,让人忍不住一探究竟。 这…...
OpenCSG AutoHub v0.5.0 版本发布
OpenCSG AutoHub v0.5.0 版本发布 作为一款智能化自动化操作的浏览器插件,AutoHub不断致力于为用户提供更加高效、便捷的网页浏览体验。本次 v0.5.0版本 的发布,不仅进一步强化了核心功能,还引入了一些创新特性,旨在帮助用户更智…...
基于Python智能体API的Word自动化排版系统:从零构建全流程模块化工作流与版本控制研究
基于Python智能体API的Word自动化排版系统:从零构建全流程模块化工作流与版本控制实践研究 1. 引言2. 研究背景与意义3. 自动排版工作流的设计原理3.1 文档内容提取与解析3.2 样式参数与格式化规则3.3 智能体API接口调用3.4 自动生成与批量处理3.5 与生成式AI的协同4. 系统架构…...
在 Node.js 中设置响应的 MIME 类型
在 Node.js 中设置响应的 MIME 类型是为了让浏览器正确解析服务器返回的内容,比如 HTML、CSS、图片、JSON 等。我们通常通过设置响应头中的 Content-Type 字段来完成。 ✅ 一、什么是 MIME 类型(Content-Type)? MIME(…...
jsch(shell终端Java版)
学习笔记 Java SSH库使用简介:Apache sshd和JSch(Java Secure Channel) github - fork of the popular jsch library JSch学习笔记 web-shell - gitee代码 - 纯Java实现一个web shell登录Linux远程主机,技术选型 SpringBoot …...
Redis分布式锁RedLock机制详解
一、RedLock机制解决的问题 核心场景:解决传统Redis单节点/主从架构下分布式锁的不可靠问题。当主节点故障时,若从节点未同步锁信息,可能导致多个客户端同时持有锁,破坏互斥性。 典型问题案例: 主从切换锁丢失&…...
Vivado中Tri_mode_ethernet_mac的时序约束、分析、调整——(五)调试注意的问题
一、几个注意点 1、每个bank中IO的组织形式 1Bank的52Pins分4 Byte Group,每Byte Group 13PinsNibble_up 7Pins Nibble_low 6Pins。 每个nibble一个bitslice_control管理自己的6~7个pins 。 每个pin对应一个bitslice,它内部又包含多个component&#…...
MFC文件-写MP4
下载本文件 本文件将创作MP4视频文件代码整合到两个文件中(Mp4Writer.h和Mp4Writer.cpp),将IYUV视频流,PCM音频流写入MP4文件。本文件仅适用于MFC程序。 使用方法 1.创建MFC项目。 2.将Mp4Writer.h和Mp4Writer.cpp文件复制到项目目录下。 3…...
PyTorch 深度学习实战(39):归一化技术对比(BN/LN/IN/GN)
在上一篇文章中,我们全面解析了注意力机制的发展历程。本文将深入探讨深度学习中的归一化技术,对比分析BatchNorm、LayerNorm、InstanceNorm和GroupNorm四种主流方法,并通过PyTorch实现它们在图像分类和生成任务中的应用效果。 一、归一化技术…...
C#/.NET/.NET Core技术前沿周刊 | 第 35 期(2025年4.14-4.20)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。 欢迎投稿、推荐…...
柱状图QCPBars
一、QCPBars 概述 QCPBars 是 QCustomPlot 中用于绘制柱状图/条形图的类,支持单组或多组柱状图显示,可自定义宽度、颜色和间距等属性。 二、主要属性 属性类型描述widthdouble柱子的宽度(坐标轴单位)widthTypeWidthType宽度计算…...
2025-04-20 李沐深度学习4 —— 自动求导
文章目录 1 导数拓展1.1 标量导数1.2 梯度:向量的导数1.3 扩展到矩阵1.4 链式法则 2 自动求导2.1 计算图2.2 正向模式2.3 反向模式 3 实战:自动求导3.1 简单示例3.2 非标量的反向传播3.3 分离计算3.4 Python 控制流 硬件配置: Windows 11Inte…...
Nginx在微服务架构项目(Spring Cloud)中的强大作用
文章目录 一、Nginx是什么?二、Nginx在微服务架构(Spring Cloud)项目中的作用1.前端静态资源托管2.反向代理后端 API3.负载均衡4.SSL 证书与 HTTPS 支持5.缓存与压缩优化6.安全防护7.灰度发布与流量控制8.跨域处理(CORS࿰…...
Mysql相关知识2:Mysql隔离级别、MVCC、锁
文章目录 MySQL的隔离级别可重复读的实现原理Mysql锁按锁的粒度分类按锁的使用方式分类按锁的状态分类 MySQL的隔离级别 在 MySQL 中,隔离级别定义了事务之间相互隔离的程度,用于控制一个事务对数据的修改在何时以及如何被其他事务可见。MySQL 支持四种…...
解决IDEA创建SpringBoot项目没有Java版本8
问题:idea2023版本创建springboot的过程中,选择java版本时发现没有java8版本,只有java17和java20 原因:spring2.X版本在2023年11月24日停止维护了,因此创建spring项目时不再有2.X版本的选项,只能从3.1.X版本…...
第十章:Agent 的评估、调试与可观测性:确保可靠与高效
引言 随着我们一步步构建出越来越复杂的 AI Agent,赋予它们高级工具和更智能的策略,一个至关重要的问题浮出水面:我们如何知道这些 Agent 是否真的有效、可靠?当它们行为不符合预期时,我们又该如何诊断和修复问题&…...