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

十二、C++速通秘籍—静态库,动态库

上一章节:

十一、C++速通秘籍—多线程-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/147055932?spm=1001.2014.3001.5502

本章节代码:

cpp2/library · CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/master/cpp2/library

目录

上一章节:

本章节代码:

一、编程后为什么会引入“库”,什么是库?

二、库分为哪几类? - 静态库,动态库

1、静态库(.a 或.lib)

2、动态库(.so 或.dll)

三、Linux/windows系统下的库

1、Linux 下表现形式

2、Windows 下表现形式

四、Linux/Windows下使用静态库,什么场景下使用静态库?

1、适用场景

2、Linux 下创建和使用静态库

2.1、创建静态库

2.2、使用静态库

3、Windows 下创建和使用静态库

3.1、创建静态库

3.2、使用静态库

五、Linux/Windows下使用动态库,什么场景下使用动态库?

1、适用场景

2、Linux 下创建和使用动态库

2.1、创建动态库

2.1、使用动态库

3、Windows 下创建和使用动态库

3.1、创建动态库

六、静态库,与动态库二者的区别

内存占用

部署难度

运行效率

可维护性

七、总结


一、编程后为什么会引入“库”,什么是库?

        想象一下你是一位超级大厨,每次做饭都要从头开始种粮食、养牲畜、采摘蔬菜,那得花费多少时间和精力呀!在编程的世界里也是如此,如果每次编写程序都要从头开始实现一些常用的功能,比如文件读写、数学计算等,那程序员可就太累啦。于是,“库”就应运而生了。

        库就像是一个装满各种工具的百宝箱,里面存放着已经编写好的代码,这些代码实现了各种各样的功能。当程序员需要使用某个功能时,不需要自己重新编写代码,只需要从这个百宝箱里拿出对应的工具(也就是调用库中的代码)就可以了。比如说,在 C++ 中,我们之前已经接触过std标准库,就提供了很多常用的功能,像字符串处理、容器管理等。你只需要包含相应的头文件,就可以使用这些功能,就像大厨从厨房里拿出现成的调料一样方便。

二、库分为哪几类? - 静态库,动态库

库主要分为两类:静态库和动态库,它们就像是两种不同类型的百宝箱。

1、静态库(.a 或.lib)

        静态库就像是一个可以被复制的百宝箱。当你使用静态库时,编译器会把静态库中的代码完整地复制到你的可执行文件中。这就好比你把百宝箱里的工具都拿出来,放进自己的口袋里,以后无论走到哪里,都可以随时使用这些工具,不需要再依赖原来的百宝箱。

2、动态库(.so 或.dll)

        动态库则像是一个共享的百宝箱,存放在一个公共的地方。当你的程序需要使用动态库中的代码时,程序会在运行时去这个公共的地方查找并加载所需的代码。这就好比你需要某个工具时,不需要把整个百宝箱都拿走,只需要去公共的地方借用一下工具,用完后再还回去。

三、Linux/windows系统下的库

1、Linux 下表现形式

在 Linux 系统中,静态库的文件扩展名通常是 `.a`,例如 `libexample.a`;动态库的文件扩展名通常是 `.so`,例如 `libexample.so`。这些库文件一般存放在 `/usr/lib` 或 `/usr/local/lib` 等目录下。

2、Windows 下表现形式

在 Windows 系统中,静态库的文件扩展名是 `.lib`,例如 `example.lib`;动态库的文件扩展名是 `.dll`,例如 `example.dll`。这些库文件通常存放在系统目录(如 `C:\Windows\System32`)或程序的安装目录下

下面是一个简单的对比图:

系统

静态库扩展名

动态库扩展名

Linux

.a

.so

Windows

.lib

.dll

四、Linux/Windows下使用静态库,什么场景下使用静态库?

1、适用场景

当你需要将程序打包成一个独立的可执行文件,并且不希望依赖外部的库文件时,就可以使用静态库。比如你开发了一个小型的游戏,希望用户下载后可以直接运行,不需要额外安装其他库,这时就可以使用静态库。

2、Linux 下创建和使用静态库

2.1、创建静态库

假设我们有一个简单的 C++ 函数 `add`,用于计算两个整数的和,代码如下:

add.cpp

int add(int a, int b)
{return a + b; 
}

首先,将 `add.cpp` 编译成目标文件:(add.o)

g++ -c add.cpp -o add.o

然后,使用 `ar` 工具将目标文件打包成静态库:

ar rcs libadd.a add.o

这样,我们就创建了一个名为 `libadd.a` 的静态库。

2.2、使用静态库

现在,我们来编写一个主程序 `main.cpp` 来使用这个静态库:

main.cpp

#include <iostream>// 声明 add 函数
extern int add(int a, int b);int main() {int result = add(3, 5);std::cout << "3 + 5 = " << result << std::endl;return 0;
}

编译并链接静态库:

g++ main.cpp -L. -ladd -o main

其中,`-L.` 表示在当前目录下查找库文件,`-ladd` 表示链接名为 `libadd.a` 的静态库。最后,运行可执行文件:

./main

3、Windows 下创建和使用静态库

3.1、创建静态库

同样使用上面的 `add.cpp` 代码,打开 VisualCode,创建一个 `add.cpp`文件。

代码:

int addWin(int a, int b)
{return a + b;
}

这里编译生成.lib,这里需要修改VsCode,中的tasks.json;

通过这个文件创建了两个编译任务:create_targe_file/create_static_lib

{"tasks": [{ // 生成目标文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成静态库"label": "create_static_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\ar.exe","args": ["rcs","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.lib","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

(1)、打开命令面板(Ctrl+Shift+P)

(2)、输入 Tasks: Run Task 并选择 create_target_file

(3)、创建静态库,跟步骤2相同选择create_static_lib

3.2、使用静态库

创建一个staticEx.cpp

// 链接静态库
#include <iostream>// 声明 addWin 函数
extern "C" int addWin(int a, int b);int main() {int result = addWin(5, 5);std::cout << "5 + 5 = " << result << std::endl;return 0;
}

配置tasks.json:

{"tasks": [{ // 生成目标文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成静态库"label": "create_static_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\ar.exe","args": ["rcs","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.lib","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"},{ // 生成可执行文件"label": "create_exe_file","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c",   // 编译参数"${file}","-L${fileDirname}\\..\\..\\build","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.exe","-static"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

五、Linux/Windows下使用动态库,什么场景下使用动态库?

1、适用场景

当多个程序需要共享相同的代码,或者库文件需要经常更新时,使用动态库就非常合适。比如操作系统中的一些公共库,多个程序都可以使用这些库中的功能,这样可以节省系统资源。

2、Linux 下创建和使用动态库

2.1、创建动态库

还是使用上面的 `add.cpp` 代码,将其编译成动态库:

g++ -fPIC -c add.cpp -o add.o
g++ -shared -o libadd.so add.o

其中,`-fPIC` 选项用于生成位置无关代码,`-shared` 选项用于创建动态库。

2.1、使用动态库

编写主程序 `main.cpp`:

// main.cpp
#include <iostream>// 声明 add 函数
extern int add(int a, int b);int main() {int result = add(9, 8);std::cout << "9 + 8 = " << result << std::endl;return 0;
}

编译并链接动态库:


g++ main.cpp -L. -ladd -o mainso

运行程序前,需要设置动态库的搜索路径:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
./main

3、Windows 下创建和使用动态库

3.1、创建动态库

在 VsCode 中创建两个文件`dyAdd.h/dyAdd.cpp`, 在dyAdd.h中添加一个导出函数的声明,dyAdd.cpp中实现函数功能:

dyAdd.h

// 动态库
#ifndef _DYADD_H_
#define _DYADD_H_#ifdef DYADD_DLL_EXPORTS
#define DYADD_API __declspec(dllimport)
#else
#define DYADD_API __declspec(dllexport) // 导出
#endifextern "C" DYADD_API int add(int a, int b);#endif

dyAdd.cpp

#include "dyAdd.h"extern "C" DYADD_API int add(int a, int b)
{return a + b;
}

tasks.json

{"tasks": [{ // 生成目标文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o","-DDYADD_EXPORTS" // 添加此行以定义 DYADD_EXPORTS 宏],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成动态库"label": "create_dynamic_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","-shared","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.dll"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"},{ // 通过动态库生成可执行文件"label": "create_exe_dyfile","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","${file}","-I${fileDirname}","-L${fileDirname}\\..\\..\\build","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.exe","-ladd"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

这里第一步,第二步,执行后生成了dyAdd.dll,以及编译的中间文件dyAll.o,编译方法都是通过控制面板按步骤生成:

使用动态库

dynamicEx.cpp

#include <iostream>
#include <windows.h>// 动态加载
typedef int (*AddFunction)(int, int);int main() {HINSTANCE hDLL = LoadLibrary("dyAdd.dll");if (hDLL != NULL) {AddFunction add = (AddFunction)GetProcAddress(hDLL, "add");if (add != NULL) {int result = add(3, 5);std::cout << "3 + 5 = " << result << std::endl;}else {std::cout << "Failed to get add function address." << std::endl;}FreeLibrary(hDLL);}return 0;
}

编译并运行程序

六、静态库,与动态库二者的区别

内存占用

静态库会将代码复制到可执行文件中,导致可执行文件体积较大,占用更多的磁盘空间;而动态库在多个程序间共享,只需要在内存中加载一份,节省了磁盘空间和内存资源。

部署难度

静态库部署简单,可执行文件不依赖外部库文件,用户只需要运行可执行文件即可;动态库部署时需要确保库文件存在于系统的指定路径中,否则程序可能无法正常运行。

运行效率

静态库的代码在编译时就已经链接到可执行文件中,运行时无需额外加载,效率相对较高;动态库在运行时需要加载,会有一定的性能开销。

可维护性

如果库文件需要更新,使用静态库的程序需要重新编译;而使用动态库的程序只需要替换库文件即可,不需要重新编译。

下面是一个对比表格:

比较项

静态库

动态库

内存占用

部署难度

简单

复杂

运行效率

可维护性

七、总结

        掌握静态库和动态库的使用,能让你的 C++ 编程之路更加顺畅,就像大厨拥有了得心应手的工具,做出更加美味的菜肴一样!希望通过这篇博客,你能对静态库和动态库有更深入的理解。

相关文章:

十二、C++速通秘籍—静态库,动态库

上一章节&#xff1a; 十一、C速通秘籍—多线程-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/147055932?spm1001.2014.3001.5502 本章节代码&#xff1a; cpp2/library CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppst…...

我爱学算法之——滑动窗口攻克子数组和子串难题(下)

这几道题可以说是有一点难度的&#xff0c;但是掌握方法以后可以说非常简单了&#xff1b; 一、找到字符串中所有字母异位词 题目解析 题目给定了两个字符串s和p&#xff0c;让我们在s中找到p的异位词的字串&#xff0c;并且返回这些字串的索引 **异位词&#xff1a;**简单来说…...

leaflet 之 获取中国某个行政区的经纬度边界(latLngBounds)

思路 在json文件中获取下面的四个点 组成东北,西南两组 { “southwest”: { “lat”: 35.950, “lng”: 120.000 },//西南方 “northeast”: { “lat”: 36.200, “lng”: 120.300 }//东北方 } 最西点经度&#xff08;minLng&#xff09; 最东点经度&#xff08;maxLng&#x…...

鸢尾花分类的6种机器学习方法综合分析与实现

鸢尾花分类的6种机器学习方法综合分析与实现 首先我们来看一下对应的实验结果。 数据准备与环境配置 在开始机器学习项目前&#xff0c;首先需要准备编程环境和加载数据。以下代码导入必要的库并加载鸢尾花数据集&#xff1a; import numpy as np import pandas as pd impo…...

基于李永乐线性代数基础的行列式的起源于理解

起源于解方程组的过程 对于解一个二元方程组&#xff0c;很自然的会通过加减消元&#xff0c;变成下面这样 对于三元方程组&#xff0c;也是一样&#xff1a; 这一大长串&#xff0c;是A*x1b1这个形式时&#xff0c;A的值 人们为了方便记忆x未知数前这一大坨相乘后相加减的数…...

MacOs java环境配置+maven环境配置踩坑实录

oracl官网下载jdk 1.8的安装包 注意可能需要注册&#xff01;&#xff01;&#xff01; 下载链接&#xff1a;下载地址点击 注意晚上就不要下载了 报错400 &#xff01;&#xff01;&#xff01; 1.点击安装嘛 2.配置环境变量 export JAVA_HOME/Library/Java/Java…...

LeetCode 3272.统计好整数的数目:枚举+排列组合+哈希表

【LetMeFly】3272.统计好整数的数目&#xff1a;枚举排列组合哈希表 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-the-count-of-good-integers/ 给你两个 正 整数 n 和 k 。 如果一个整数 x 满足以下条件&#xff0c;那么它被称为 k 回文 整数 。 x 是一个…...

蓝桥杯嵌入式历年省赛客观题

一.第十五届客观题 第十四届省赛 十三届 十二届...

RFID 在制造业的深度应用与未来趋势

一、引言 制造业作为国民经济的核心支柱&#xff0c;正面临着全球供应链重构、个性化需求激增、成本压力加剧等多重挑战。RFID&#xff08;射频识别&#xff09;技术以其非接触式自动识别、数据实时传输、环境适应性强等特性&#xff0c;成为推动制造业数字化转型的关键引擎。…...

spring--声明式事务

声明式事务 1、回顾事务 要么都成功&#xff0c;要么都失败&#xff01; 事务在项目开发中&#xff0c;十分重要&#xff0c;涉及数据的一致性问题 确保完整性和一致性 事务ACID&#xff1a; 原子性&#xff1a;事务是原子性操作&#xff0c;由一系列动作组成&#xff0c;…...

java爬虫案例

以下是一个简单的Java爬虫案例&#xff0c;使用了 Jsoup 和 Apache HttpClient 两个常用的库来实现网页内容的爬取和解析。这个案例会演示如何获取网页的HTML内容、解析HTML并提取所需数据。 示例&#xff1a;使用Jsoup爬取网页内容 1. 添加依赖 在项目中添加以下依赖&#xff…...

博途 TIA Portal之1200做主站与有意思的板子做MODBUS_RTU通讯

做为博途的硬件,1200和1500本体都不具有串口通讯功能,只能使用扩展板或是通讯模块完成。 其中1200使用CB1241或CM1241进行串口通讯,本文将使用CM1241进行演示。 1、硬件介绍 1200的PLC一台,有意思的板子(以下简单4D板)一台。 其中1200带扩展模块CM1241 RS232;4D板使…...

01_核心系统下的技术原理解析

15年前&#xff0c;基本上国内的核心系统被C垄断&#xff0c;基本上是IBM的那套东西&#xff0c;场景也是比价复杂&#xff0c;这里不再赘述&#xff0c;TPS太过于庞大&#xff0c;技术上确实比较复杂。为此我这里抛砖引玉&#xff0c;说下对应的支付系统&#xff1a; &#x…...

【力扣hot100题】(092)最长回文串

有点难度&#xff0c;一开始想到的两种方法都不对&#xff0c;花了不少时间。 先说之前的方法&#xff1a; ① 遍历每个点&#xff0c;每个点向外扩张&#xff0c;如果左等于右就一直扩展直到不等。 这个方法可是可以&#xff0c;但我没有考虑到两个相同字母也是回文串的情况…...

第一期:[特殊字符] 深入理解MyBatis[特殊字符]从JDBC到MyBatis——持久层开发的转折点[特殊字符]

前言 &#x1f31f; 在软件开发的过程中&#xff0c;持久层&#xff08;或数据访问层&#xff09;是与数据库进行交互的关键部分。早期&#xff0c;开发者通常使用 JDBC&#xff08;Java Database Connectivity&#xff09;来实现与数据库的连接与操作。虽然 JDBC 在一定程度上…...

指针的进阶2

六、函数指针数组 字符指针数组 - 存放字符指针的数组 char* arr[10] 整型指针数组 - 存放整型指针的数组 int* arr[10] 函数指针数组 - 存放函数指针的数组 void my_strlen() {} int main() {//指针数组char* ch[5];int arr[10] {0};//pa是是数组指针int (*pa)[10] &…...

Java学习——day28(Java并发工具类与线程池)

文章目录 1. 并发工具类简介1.1 ExecutorService1.2 Callable 和 Future1.3 Executors 工具类1.4 线程池优势 2. 实践&#xff1a;线程池执行任务并收集结果示例2.1 示例代码 3. 代码详解3.1 线程池的创建3.2 定义任务列表3.3 提交任务并收集 Future3.4 获取任务执行结果3.5 关…...

2021第十二届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

记录刷题的过程、感悟、题解。 希望能帮到&#xff0c;那些与我一同前行的&#xff0c;来自远方的朋友&#x1f609; 大纲&#xff1a; 1、空间-&#xff08;题解&#xff09;-字节单位转换 2、卡片-&#xff08;题解&#xff09;-可以不用当组合来写&#xff0c;思维题 3、直…...

【数据结构】之二叉树

二叉树是我们在数据结构中学到的第一个非线性结构&#xff0c;是后续学习更为复杂的树、图结构的基础。本文整理了二叉树的概念定义、基本操作、遍历算法、伪代码与代码实现以及实例说明&#xff0c;方便大家随时查找对应。 一、定义与基本术语 二叉树是一种树形结构&#xf…...

电感、互感器、变压器和磁珠综合对比——《器件手册--电感/线圈/变压器/磁珠篇》

三、电感/线圈/变压器/磁珠 名称 定义 特点...

CLIP中的Zero-Shot Learning原理

CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09;是一种由OpenAI提出的多模态模型&#xff0c;它通过对比学习的方式同时学习图像和文本的表示&#xff0c;并且能在多种任务中进行零样本学习&#xff08;Zero-Shot Learning&#xff09;。CLIP模型的核心创…...

基于 Redis 实现一套动态配置中心 DCC 服务与反射基础知识讲解

目录 动态配置中心核心价值 轻量级 Redis 方案与 ZooKeeper 的对比分析 为什么选择自定义 Redis 方案&#xff1f; 1. 技术决策背景 一、活动降级拦截 1. 定义与作用 2. 实现原理 二、活动切量拦截 1. 定义与作用 2. 实现原理 三、两者的核心区别 四、实际应用案例 1. 电商大促…...

vue 前端遇到问题 样式不展示

vue 前端遇到问题 样式不展示 先看接口返回有数据没 如果有数据看下 是不是 输入赋值给其他 字段 没有赋值上导致报错 所以页面没展示数据...

基于 Spring Boot + Vue 的 [业务场景] 管理系统设计与实现

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

2025蓝桥杯JavaB组

说明 博主自己水平有限&#xff0c;而且答案也不一定对&#xff0c;下面代码和思路仅作分享。我只把我考场上做了的写出来了&#xff0c;有什么问题欢迎评论区交流。 A&#xff1a;逃离高塔 思路&#xff1a; 由于有了去年的经验&#xff0c;所以一上来我就是找规律&#xf…...

HDF5文件格式:数据类型与读写功能详解

HDF5文件格式&#xff1a;数据类型与读写功能详解 HDF5简介 HDF5&#xff08;Hierarchical Data Format version 5&#xff09;是一种用于存储和管理大量科学数据的文件格式和库。它由美国国家高级计算应用中心&#xff08;NCSA&#xff09;开发&#xff0c;具有以下特点&…...

探索 Python 的 functools 模块:缓存、属性缓存与 LRU 缓存

李升伟 编译 Python 的 functools 模块是函数式编程爱好者的宝库&#xff0c;提供了许多工具来提升代码的效率和优雅性。本文将深入探讨三个强大的函数——cache、cached_property 和 lru_cache&#xff0c;它们通过存储昂贵计算的结果来优化性能。无论是加速递归算法还是简化…...

缓存与数据库一致性:从问题到解决方案全解析

一、⼀致性问题的由来&#xff1a;为什么会不一致&#xff1f; 我们先从现实例子出发&#xff0c;来看为什么会出现一致性问题&#xff1a; &#x1f4e6; 场景举例&#xff1a;电商下单业务 用户提交订单 → 服务写入数据库订单表&#xff1b;同时更新缓存&#xff08;比如用…...

【android bluetooth 框架分析 02】【Module详解 2】【gd_shim_module 模块介绍】

1. 背景 上一章节 我们介绍了 module_t 的 大体框架 &#xff0c;本节内容我们就选择 我们的 gd_shim_module 模块为例子&#xff0c;具体剖析一下&#xff0c;它里面的逻辑。 static const char GD_SHIM_MODULE[] "gd_shim_module";// system/main/shim/shim.cc …...

dbt:新一代数据转换工具

dbt&#xff08;Data Build Tool&#xff09;一款专为数据分析和工程师设计的开源工具&#xff0c;专注于 ETL/ELT 流程的数据转换&#xff08;Transform&#xff09;环节&#xff0c;帮助用户以高效、可维护的方式将原始数据转换为适合分析的数据模型。 用户只需要编写查询&am…...

Linux-内核驱动-makemenu,make modules,make uImage,杂项

动态生成设备节点设备号...

linux 内存踩踏导致的空指针问题分析纪要

1&#xff0c;查看日志信息打印 我们看到日志发现发包的skb模块有NULL pointer情况&#xff0c;我们看代码分析skb指针不可能出现是空指针&#xff0c;这个时候我们怀疑可能是出现了踩内存导致的空指针情况&#xff0c;所以我们首先需要找到系统PANIC的条件&#xff0c;也就是…...

【C++】 —— 笔试刷题day_14

一、乒乓球筐 题目解析 题目输入两个字符串A和B&#xff0c;分别代表A和B中的乒乓球&#xff0c;不同的大写字母就表示不同的乒乓球&#xff1b; 如果判断B中的所有乒乓球在A中都有&#xff0c;且A中每种乒乓球的数量大于等于B中的。&#xff08;简单来说就是B是A的子集&#…...

在WPS中通过JavaScript宏(JSA)调用DeepSeek官方API自动识别标题级别和目录

我们希望通过AI&#xff0c;能够自动识别像“一”、“&#xff08;一&#xff09;”、“1”、“&#xff08;1&#xff09;” 这类常见标题序号。做一个规则&#xff0c;如果存在“一”时&#xff0c;则“一”、“&#xff08;一&#xff09;”、“1”分别识别为H1、H2、H3&…...

修复 WPS 编译错误:缺少:Sub或Function 且出现两个MathType加载项

问题首次出现于2025.4.12。 同时使用了Word和WPS&#xff0c;在里面都使用了MathType&#xff0c;在Microsoft的Word中&#xff0c;加载项能正常加载且显示&#xff0c;这也是我们要的效果。 而在WPS中&#xff0c;却出现了两个MathType&#xff0c;且在启动时会弹窗报错&…...

HTTP协议

目录 1 Fiddler工具 2 HTTP协议 2.1 HTTP请求和响应格式 2.2 URL 2.3 方法method 2.3.1 GET 2.3.2 POST 2.4 请求报头Header 2.5 请求正文body 2.6 http响应状态码 2.7 响应报头header HTTP协议是应用层的协议&#xff0c;基于传输层的TCP协议来传输&#xff0c;数据…...

拓扑排序 —— 2. 力扣刷题207. 课程表

题目链接&#xff1a;https://leetcode.cn/problems/course-schedule/description/ 题目难度&#xff1a;中等 相关标签&#xff1a;拓扑排序 / 广度优先搜搜 BFS / 深度优先搜索 DFS 2.1 问题与分析 2.1.1 原题截图 2.1.2 题目分析 首先&#xff0c;理解题目后必须马上意识到…...

寻找峰值 --- 二分查找

目录 一&#xff1a;题目 二&#xff1a;算法原理 三&#xff1a;代码实现 一&#xff1a;题目 题目链接&#xff1a;162. 寻找峰值 - 力扣&#xff08;LeetCode&#xff09; 二&#xff1a;算法原理 三&#xff1a;代码实现 class Solution { public:int findPeakElemen…...

SAP系统客户可回收包材库存管理

问题&#xff1a;客户可回收包材库存管理 现象&#xff1a;回收瓶无库存管理&#xff0c;在库数量以及在客户的库存数量没有统计&#xff0c;管理混乱。 解决方法&#xff1a; 客户可回收包装材料在SAP有标准的解决方案&#xff0c;在集团尚未启用该业务&#xff0c;首先…...

C++标识符:检查是否和保留字冲突

1. 基础知识 最基本的要求&#xff1a; 字母、数字、下划线组成&#xff0c; 并且不能是数字开头。 禁忌1&#xff1a; C 关键字不能用做标识符。 它们是&#xff1a; alignas alignof asm auto bool break case catch char char16_t char32_t class const constexpr const_…...

【Java多线程】告别线程混乱!深度解析Java多线程4大实现方式(附实战案例)

一、继承Thread类 实现步骤&#xff1a; 1.继承Thread类 2.重写run()方法 3.创建线程对象并调用start()方法 示例&#xff1a; class MyThread extends Thread {Overridepublic void run() {for (int i 0; i < 5; i) {System.out.println(Thread.currentThread().getNam…...

Linux安装yum和python

一、安装yum(CentOS) 查看yum版本 yum --version 如果未安装&#xff0c;执行以下部分&#xff1a; 1. 确保你的系统中已经安装了epel仓库&#xff0c;如果没有安装可以通过以下命令安装&#xff1a; sudo yum install epel-release 2.yum安装 – CentOS/RHEL系统&#…...

【数据结构】HashMap源码 —— 简单介绍

HashMap源码介绍 下面并非完整的源码&#xff0c;主要简单了解其流程。 1. 基本成员变量 哈希桶/开散列&#xff0c;链地址法/开链法是由&#xff1a;数组 链表(单链表) 红黑树&#xff08;当数组长度>64 && 链表长度>8以后&#xff0c;链表变成红黑树&#xf…...

149页研读——华为基于IPD全过程研发质量管理【附全文阅读】

本文介绍了IPD(集成产品开发)的全过程研发质量管理,强调了以客户需求为导向,通过跨部门协同、资源整合、快速响应等方式提高研发效率和成功率。文章详细阐述了IPD研发管理体系的精要,包括其核心思想、优势、框架以及核心理念。 其中,跨领域平台与技术研发、端到端流程与项…...

深入理解 v-for 指令及其使用方法

在 Vue.js 中&#xff0c;v-for 是用于渲染列表的核心指令&#xff0c;它允许你通过循环渲染数据源中的每一项。通过 v-for&#xff0c;你可以轻松地将数组、对象或其他可迭代的数据渲染成 HTML 元素。本文将详细介绍 v-for 的基本用法、常见的应用场景、最佳实践及性能优化&am…...

swift菜鸟教程24-25(可选链,自动引用计数)

一个朴实无华的目录 今日学习内容&#xff1a;1.Swift 可选链1.1定义1.2通过可选链调用方法1.3使用可选链调用下标脚本1.4通过可选链接调用来访问下标1.4访问可选类型的下标 2.Swift 自动引用计数&#xff08;ARC&#xff09;2.1实例之间的循环强引用会造成内存泄露2.2弱引用&a…...

使用 Visual Studio 2022 (VS2022) 编译 FreeCAD 1.0.0 的详细教程

一、环境准备 官方教程&#xff1a;在 Windows 上编译 - FreeCAD Documentation Windows 10/11&#xff08;推荐&#xff09; git vs2022 cmake 3.26.4 Doxygen1.12 二、获取源码与依赖 版本关系 打开Git Bash或CMD&#xff0c;执行以下命令 git clone --recurse-sub…...

机械臂只有位置信息是否可以进行手眼标定?

平常我在做手眼标定时&#xff0c;一般都是通过OpenCV的cv::calibrateHandEye函数进行求解&#xff0c;需要输入多组不同的机械臂位姿。今天遇到了一款舵机机器人&#xff0c;只能获取位置&#xff0c;得不到姿态信息&#xff0c;想着那就把姿态都设为0&#xff0c;结果求不出来…...

Unity入门

文章目录 Unity脚本基础大基础生命周期函数Inspector窗口显示常用特性辅助特性 MnonBehaviour基类成员变量成员方法 组件GameObject成员变量gameObject静态方法成员方法 组件Time静态成员变量 组件TransformVector3结构体基础基本概念常用向量表示常用方法 位置与位移位置posit…...

《汽车制造技术基础》第一次作业

作业内容 查阅相关资料&#xff0c;谈谈对汽车制造技术的发展的理解。 可以是关于汽车的先进制造技术 或 汽车先进制造技术 与 制造理念的发展趋势 或 汽车先进制造技术对环境与可持续发展的影响等。 以下从技术突破、制造理念转型及环境影响三个维度展开对汽车制造技…...