【Linux我做主】探秘gcc/g++和动静态库
@TOC
Linux编译器gcc/g++的使用
github地址
有梦想的电信狗
前言
在软件开发的世界中,编译器如同匠人的工具,将人类可读的代码转化为机器执行的指令。
对于Linux
开发者而言,gcc
和g++
是构建C/C++
程序的核心工具链,掌握它们的原理和使用技巧是每一位开发者成长的必经之路。
本文将深入剖析从源代码到可执行程序的完整生命周期,揭示预处理、编译、汇编、链接四大阶段的神秘面纱,探讨动静态库的本质差异,解密Debug
与Release
版本背后的工程权衡。
无论您是初探Linux开发的爱好者,还是希望夯实编译原理的进阶者,本文都将为您呈现一场理论与实践并重的技术之旅。
C/C++可执行程序的形成过程
从C/C++
源文件.c或.cpp源文件形成可执行程序需要经历预处理、编译、汇编、链接四个过程,接下来依次介绍各个时期的特点以及Linux
下的编译器gcc/g++
是如何实现这些过程的。
预处理 (Preprocessing)
输入文件: .c
/.cpp
源文件
输出文件: .i
文件(预处理后的文本文件,预处理后依然是.c
/.cpp
文件)
工具: 预处理器
核心过程:
- 展开所有
#include
指令,递归插入头文件内容 - 处理
#define
宏定义,执行文本替换。 - 条件编译处理(
#ifdef
,#ifndef
,#endif
等) - 删除所有注释(
//
和/* */
),删除所有空行和空白。 - 添加行标记(
#line
指令)供调试使用 - 处理
#pragma
编译器指令
- 使用gcc编译器仅完成预处理步骤
示例:gcc -E main.c -o main.i
编译 (Compilation)
输入文件: .i
文件
输出文件: .s
文件(汇编代码文件)
工具: 编译器(如 gcc
, clang
)
- 编译是消耗时间和资源最多的步骤。
核心过程:
- 词法分析:将源代码分解为
Token
流,检查语法 - 语法分析:构建抽象语法树
(AST)
- 语义分析:类型检查、作用域验证等
- 中间代码生成:生成平台无关的中间表示(如 LLVM IR)
- 代码优化:进行死代码消除、循环优化等
- 目标代码生成:生成特定 CPU 架构的汇编代码
了解了以上过程,我们认识到,**宏不会进行类型检查和语法分析
**的原因是:
-
宏进行的是文本替换,在预处理阶段进行。
-
语法检查是在编译阶段进行的。
因此常说宏是类型不安全的
将预处理后的文件翻译成汇编语言指令:
示例:
gcc -S main.i -o main.s
汇编 (Assembly)
- 将汇编指令翻译成机器指令的过程。
输入文件:.s
文件
输出文件:.o
/.obj
文件(二进制目标文件)
工具: 汇编器
核心过程:
- 将助记符形式的汇编代码转换为机器指令(二进制操作码)
- 生成符号表(记录函数/变量地址信息)
- 生成重定位表(标记需要链接时修正的地址)
- 生成节区信息(
text/data/bss
等段)
可执行文件的格式:
- Linux:
ELF
格式(Executable and Linkable Format) - Windows:
COFF
格式(Common Object File Format)
示例:gcc -c main.s -o main.o
链接 (Linking)
输入文件: .o
文件 + 静态库或动态库(.a
/.lib
)
输出文件: 可执行文件(.exe
(windows下) 或有执行权限的文件
(Linux下
))
工具: 链接器
核心过程:
- 符号解析:匹配所有未定义符号与其定义
- 地址分配:
- 地址回填:给每个目标文件分配运行时内存地址
- 数据段合并:合并相同类型的节区(如多个.text段合并)
- 重定位修正:根据实际地址修改代码中的引用
- 解析库依赖:
- 静态链接:直接将库代码复制到可执行文件中
- 动态链接:生成导入表记录共享库信息
链接类型:
类型 | 特点 | 文件扩展名 |
---|---|---|
静态链接 | 代码体积大,无运行时依赖 | .a (Linux) .lib (Windows) |
动态链接 | 代码体积小,需要运行时环境支持 | .so (Linux) .dll (Windows) |
示例:gcc main.o -o main
在进行多文件编译时,对每个文件进行单独编译,最终一起链接。
完整流程示例
# 完整编译流程(隐含执行所有阶段)
gcc main.c -o main# 分步执行(显式控制每个阶段)
gcc -E main.c -o main.i # 预处理
gcc -S main.i -o main.s # 编译
gcc -c main.s -o main.o # 汇编
gcc main.o -o main # 链接
gcc/g++如何完成可执行程序的形成过程
形成过程
例如有源文件main.c
,现要分步骤对其进行编译形成可执行文件。
-
预处理
gcc -E main.c -o main.i
该指令告诉gcc
,现在开始进行程序的翻译,预处理结束后停止。
-
编译
gcc -S main.i -o main.s
该指令告诉gcc
,对预处理过后的.i
文件进行处理,编译结束后停止。
-
汇编
gcc -c main.s -o main.o
该指令告诉gcc
,汇编结束后停止。- 形成的
.o
文件是可重定位目标二进制文件,简称目标文件。windows
下是.obj
文件,不可以独立执行,虽然已经是二进制格式了,但需要链接后才可以执行。
-
链接
gcc main.o -o main
将可重定位目标二进制文件,和库链接形成可执行程序。
最常用的命令行编译指令
我们在进行单个源文件的编译时,如果没有查看中间文件的需求,则直接使用gcc
一步完成编译
gcc test.c #默认生成的程序名为a.out
gcc test.c -o test # 指定可执行程序的名字为 test
选项记忆小妙招
预处理、编译、汇编三个过程的选项分别是-E -S -c
- 刚好组成
ESc
键
预处理、编译、汇编三个过程形成的文件的后缀依次是.i .s .o
- 三个字母组成
iso
,恰好是操作系统的镜像文件的后缀名。
gcc编译的其他常用选项
-E
: 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面。-S
: 编译到汇编语言,不进行汇编和链接-c
编译到目标代码-o
文件输出到文件-static
此选项对生成的文件采用静态链接。gcc
编译在链接库时默认采用动态链接。-g
生成调试信息。GNU
调试器可利用该信息。-shared
此选项将尽量使用动态库,所以生成文件比较小,但是需要系统有动态库.-O0
、-O1
、-O2
、-O3
编译器的优化选项的4个级别,-O0
表示没有优化,-O1
为缺省值,-O3
优化级别最高-w
不生成任何警告信息。-Wall
生成所有警告信息。
g++相关
对于以上操作和选项,gcc
所有的编译操作和命令选项同样适用于g++
,只不过编译的源程序变成了.cpp
文件。
g++和gcc的区别
编译器 | 主要语言支持 | 次要语言支持 |
---|---|---|
gcc | C语言 | C++(需显式指定) |
g++ | C++(ISO标准) | C(不推荐) |
关键区别:
gcc
默认作为C语言编译器g++
默认作为C++
编译器,g++
既可编译C语言,也可以编译C++
预定义宏差异
编译器 | 默认宏 |
---|---|
gcc | __STDC__ |
g++ | __cplusplus |
示例检测:
#ifdef __cpluspluscout << "C++环境"; // g++会执行
#elseprintf("C环境"); // gcc可能执行
#endif
使用场景指南
✅ 推荐使用g++的情况:
- 纯C++项目开发
- 使用STL/模板等C++特性
- 需要异常处理/RTTI特性
- 混合C/C++代码(作为主要编译器)
✅ 推荐使用gcc的情况:
- 纯C语言项目开发
- 需要严格C标准兼容
- 嵌入式开发(配合
-ffreestanding
) - 内核开发等底层编程
对比总结表
特性 | gcc | g++ |
---|---|---|
默认标准 | C17 | C++17 |
标准库链接 | 需手动-lstdc++ | 自动链接 |
文件后缀处理 | 根据后缀判断 | 强制C++模式 |
函数重载 | 不支持 | 支持 |
异常处理 | 默认禁用 | 默认启用 |
RTTI | 需手动开启 | 默认启用 |
启动代码 | C启动程序 | C++启动程序 |
预定义宏 | STDC | __cplusplus |
链接与库:初始动静态库
上文在介绍链接过程时,提到了输入文件.o
与静态库或动态库(.a
/.lib
)的链接共同形成可执行文件,那么什么是库呢?
- 同时思考
我们的C程序中,并没有定义printf
的函数实现,且在预编译中包含的头文件<stdio.h>
中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现printf
函数的呢?
最后的答案是:系统把这些函数实现都被做到名为 libc.so.6
的库文件中去了,在没有特别指定时,gcc
会到系统默认的搜索路径/usr/include
下进行查找,也就是链接到 libc.so.6
库函数中去,这样就能实现函数printf
了,而这也就是链接的作用
什么是库?
库(Library)是预编译的二进制代码集合,包含可重用的函数/类/资源。在链接过程中,编译器会将.o
目标文件与静态库(.a
/.lib
)或动态库(.so
/.dll
)链接,最终生成可执行文件。
库分为动态库和静态库。
Linux
下的头文件和库默认搜索路径在/usr/include
目录下
动态库
- 概念
动态库(Dynamic Library
)是一种在程序运行时被动态加载到内存
的二进制代码库,其核心设计目标是实现代码的共享复用和资源优化。
动态库的代码不会在编译时直接嵌入可执行文件,而是由操作系统的动态链接器(如ld-linux.so)在程序启动时或运行期间(通过dlopen())按需加载到内存。
- 特点
- 文件扩展名:Linux下为
.so
(Shared Object),Windows为.dll
- 运行时加载:程序运行时由动态链接器加载到内存
- 共享性:多个程序可共享同一份动态库实例
- 版本控制:通过符号版本机制支持ABI兼容更新
- 文件扩展名:Linux下为
静态库
- 概念
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中
,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为.a
- 特点
- 文件扩展名:Linux下为
.a
(Archive),Windows为.lib
- 编译时链接:库代码直接嵌入到最终可执行文件中
- 独立性:不依赖外部库文件即可运行
- 体积代价:导致可执行文件体积显著增大
- 文件扩展名:Linux下为
- 库存在的意义
- 代码复用:避免重复造轮子
- 模块化开发:解耦复杂系统
- 知识产权保护:分发二进制而非源码
- 降低维护成本:更新库文件无需重新编译主程序
- 节省存储空间:动态库可被多个进程共享
- **关于学习和工作:**在学习阶段,我们是适度的造轮子;而在工作阶段,我们最好找已有的解决方案。
gcc的默认链接方式及file和ldd命令
- 在
Linux
中,gcc
编译形成可执行程序,默认采用的是动态链接,需要系统提供动态库。 - 在
Linux
中,如果想以静态链接的方式形成可执行程序,需要在编译时添加-static
选项,并且系统需要提供静态库。
-
test_dy
是gcc
默认的编译程序,默认采用动态链接。 -
test_static
是gcc
指定静态链接时的编译程序,可以明显的看到程序的体积大了很多。 -
我们可以通过
file
命令来查看可执行程序的链接方式。
-
可以使用
ldd
命令查看可执行程序已链接的动态库
可以看到: -
动态链接形成的
test_dy
链接了一些动态库 -
静态链接形成的
test_static
没有已链接的动态库
动静态库优缺点对比
特性 | 静态库 | 动态库 |
---|---|---|
文件体积 | 显著增大 | 较小 |
内存占用 | 独立占用 | 共享内存 |
部署复杂度 | 简单(单文件) | 需确保库文件存在 |
更新维护 | 需重新编译 | 替换库文件即可 |
启动速度 | 较快(无加载开销) | 略慢(需要加载) |
适用场景 | 嵌入式、独立工具 | 大型应用、系统级服务 |
- 动态库因为是共享库,可以有效的节省资源,包括(磁盘空间、内存空间、网络空间等)。动态库一旦缺失,会导致各个程序都无法运行。
- 静态库,不依赖库,程序可以独立运行。但体积大,消耗资源。
总结
- 动态链接的库,就叫动态库,静态链接的库,就叫静态库。
- 如果我们没有静态库,但要在编译时使用
-static
选项,这是不可行的。 - 如果我们没有动态库,只有静态库,且能静态库被编译器找到,则可以正常链接。
-static
选项的本质是改变编译器链接模式的优先级。-static
只适配一次,会将所有的链接要求全部变成静态链接。- 在一个程序中,既会有动态库,也会有静态库,一般都是动静态库混合使用的。
CentOS下安装静态库
一般的Linux
系统,默认只提供了动态库,静态库库需要我们自行进行安装。
C语言静态库
sudo yum install glibc-static
C++静态库
sudo yum install libstdc++-static
验证安装
# 查找静态库路径
sudo find /usr/ -name "libc.a"
sudo find /usr/ -name "libstdc++.a"
- 查找结果如下
开发建议
- 优先使用动态库:适用于大多数桌面/服务器应用
- 谨慎选择静态库:考虑磁盘空间和内存限制
- 混合使用策略:关键模块静态链接,通用功能动态链接
- ABI兼容性:动态库更新时保持向后兼容
Debug与Release软件简介
gcc
编译器在不增加特殊选项时,默认采用release
版本编译形成可执行程序
核心概念
Debug版本
- 编译特性:包含调试符号(-g)可以被追踪调试、禁用优化(-O0)
- 文件体积:可执行文件略大(形成可执行文件时,添加了调试信息)
- 典型用途:
- 开发阶段调试
- 崩溃问题分析
- 性能问题定位
Release版本
- 编译特性:启用优化(-O2/-O3)、去除调试符号
- 文件体积:可执行文件较小
- 典型用途:
- 生产环境部署
- 性能敏感场景
- 正式版本发布
- debug版本软件包含了调试信息,因此软件的体积更大一些
gcc
编译器在不增加特殊选项时,默认采用release
版本编译形成可执行程序- 我们在编译时添加
-g
选项,可形成包含调试信息
的可执行程序 - 那么选项
-DDEBUG
又有什么含义呢?
场景引入:
两个命令-g
和-DDEBUG
两个选项生成的程序虽然都用于调试,但包含的信息不同,具体区别如下:
gcc test.c -o test_Debug -DDEBUG
:
•-DDEBUG
:定义预处理宏DEBUG
,用于在编译时启用代码中#ifdef DEBUG
控制的调试逻辑(如打印日志、额外检查等)。
• 不包含调试符号:生成的程序没有嵌入调试信息(如变量名、行号),无法直接通过调试器(如GDB
)进行源码级调试。
• 程序行为可能不同:如果代码依赖DEBUG
宏控制逻辑,test_DEBUG
会执行这些调试相关的代码。-DDEBUG
选项的本质是在源程序文件中添加了DEBUG宏
,用于在编译时启用代码中#ifdef DEBUG
控制的调试逻辑。
gcc test.c -o test_debug -g
:
•-g
:嵌入调试符号,允许使用调试器跟踪变量、设置断点等。
• 不启用DEBUG
宏:除非代码中已定义或通过其他方式启用,否则#ifdef DEBUG
的代码不会编译到程序中。
• 程序行为与未启用DEBUG
宏的版本一致(假设代码逻辑依赖该宏)。
关键区别:
选项 | 调试符号(-g ) | 启用DEBUG 宏(-DDEBUG ) |
---|---|---|
test_Debug | ❌ 无 | ✔️ 启用 |
test_debug | ✔️ 有 | ❌ 未启用(除非代码已定义) |
结论:
• 是否属于“Debug模式”:取决于定义。若认为需同时包含调试符号和调试代码,则两者均不完全;若接受部分特性,则分别属于不同维度的调试版本。
• 信息差异:两者包含的信息不同。test_Debug
可能包含更多调试输出但难以用调试器分析;test_debug
便于调试但可能缺少DEBUG
宏控制的代码。
Debug和Release核心差异对比
特性 | Debug版本 | Release版本 |
---|---|---|
编译选项 | -g -O0 | -O2/-O3 |
符号表 | 包含完整调试信息 | 通常去除 |
代码优化 | 无优化(保留原始逻辑) | 高度优化(可能改变执行流) |
执行速度 | 较慢 | 快(提升20%-300%) |
内存占用 | 较高 | 较低 |
逆向难度 | 容易(保留符号) | 困难 |
readelf命令查看调试信息
高级控制技巧
条件编译宏:
#ifdef NDEBUG
// Release模式专用代码
#else
// Debug模式专用代码
#endif
总结
通过本文的探索,我们揭开了gcc/g++
编译器从源代码到二进制程序的全流程面纱。从预处理阶段的宏展开到编译阶段的语法树构建,从汇编指令的生成到链接时的符号解析,每一个环节都彰显着计算机科学的精妙设计。
理解动静态库的取舍之道,掌握Debug
版本的调试信息嵌入,这些知识不仅让我们在日常开发中游刃有余,更赋予了我们优化程序性能、诊断疑难问题的关键能力。
以上就是本文的所有内容了,如果觉得文章写的不错,还请留下免费的赞和收藏,也欢迎各位大佬在评论区交流
分享到此结束啦
一键三连,好运连连!
相关文章:
【Linux我做主】探秘gcc/g++和动静态库
TOC Linux编译器gcc/g的使用 github地址 有梦想的电信狗 前言 在软件开发的世界中,编译器如同匠人的工具,将人类可读的代码转化为机器执行的指令。 对于Linux开发者而言,gcc和g是构建C/C程序的核心工具链,掌握它们的原理和使…...
工控系统前端设计(pyqt)
题目源自:白月黑羽的项目实战四-[工控系统前端] 代码已上传至gitcode https://gitcode.com/m0_37662818/Industrial_Control_System_Front_End 心得体会:直接用组态软件或者js吧 项目亮点 tablemodel的使用,绑定了表格和数据风机自定义ite…...
一台 Master 多节点玩转 Kubernetes:sealos 一键部署实践
文章目录 一台 Master 多节点玩转 Kubernetes:sealos 一键部署实践🔗 参考链接🌐 部署环境📦 安装包说明🔧 前期准备🚀 使用 sealos 安装 Kubernetes✅ 验证集群状态📌 后续可做的优化和拓展&am…...
写书的三驾马车
2019年8月19日23:52:28 先亮出我们的兵器组合: GitBook Git Markdown,享受行云流水一般的写作 个人秀 GitBook : 一个基于 Node.js 的文档格式转换工具,支持 Markdown 和 AsciiDoc 两种语法格式,可以输出 HTML、PDF等格式的…...
科学护理进行性核上性麻痹,缓解病痛提升生活质量
进行性核上性麻痹是一种罕见的神经系统变性疾病,患者常出现姿势平衡障碍、吞咽困难、眼球运动异常等症状。通过科学的健康护理,能在一定程度上减轻患者痛苦,提升生活质量。 日常护理,保障安全舒适 患者日常活动时,需确…...
第七章:7.2求方程a*x*x+b*x+c=0的根,用3个函数,分别求当:b*b-4*a*c大于0、等于0和小于0时的根并输出结果。从主函数输入a、b、c的值
//求方程a*x*xb*xc0的根,用3个函数,分别求当:b*b-4*a*c大于0、等于0和小于0时的根并输出结果。 //从主函数输入a、b、c的值 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<math.h> void s1(float a, float b, fl…...
优选算法系列(7.BFS 解决最短路问题)
简介: 先走到A,之后弹出A再把A能走到的地方加进去向外扩展把队列里面的元素(B,C)弹出来,再把B,C能到的地方入队列 一直这样那么最短路程就是扩展的层数。 迷宫中离入口最近的出口(me…...
实现定时发送邮件,以及时间同步
定时发送邮件 部署邮件服务 查看有没有安装mailx,安装了 [root192 ~]# rpm -q mailx mailx-12.5-43.fc38.x86_64去网易拿一下授权码,写到配置文件里 vim /etc/mail.rcset fromxxxxxxx163.com set smtpsmtp.163.com set smtp-auth-userxxxxxxx163.com set smtp-auth-passwor…...
Java反射知识点学习笔记
目录 一、定义 二、获取class对象的三种方式 1、Class.forName("全类名") 2、类名.class 3、对象.getClass() 三、案例 1、获取 class 反射对象三种方式 2、利用反射获取构造方法 3、利用反射获取成员变量 4、利用反射获取成员方法 Java反射是一种强大的编…...
Unity ShaderLab引用HLSL文件找不到其中函数
在写Unity Shader的过程中,常常需要将方法封装到HLSL文件中,今天遇到一个这样的报错, 明明hlsl文件路径引用没问题,却引用不到方法 并且将分散文件中的函数复制过来一切正常,最终定位到HLSL的预编译指令中 这指令的…...
【文献笔记】LLM-based control code generation using image recognition
LLM-based control code generation using image recognition 原文代码 标题翻译:基于图像识别的LLM控制代码生成 1. 内容介绍 1.1. 简介 论文提出了一种基于LLM的新方法,通过图像识别从管道仪表图(Piping and Instrumentation Diagrams,…...
算法之贪心算法
贪心算法 贪心算法核心思想常见应用场景典型案例案例一:找零问题案例二:活动选择问题案例三:货仓选址问题 贪心算法的应用详解霍夫曼编码最小生成树Dijkstra最短路径算法 总结 贪心算法 核心思想 贪心算法(Greedy Algorithm&…...
从“链主”到“全链”:供应链数字化转型的底层逻辑
1. 制造业与供应链数字化转型的必然性 1.1. 核心概念与战略重要性 制造业的数字化转型,是利用新一代数字技术(如工业互联网、人工智能、大数据、云计算、边缘计算等)对制造业的整体价值链进行根本性重塑的过程。这不仅涉及技术的应用&#…...
【Windows本地部署n8n工作流自动平台结合内网穿透远程在线访问】
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
Python中如何加密/解密敏感信息(如用户密码、token)
敏感信息,如用户密码、API密钥、访问令牌(token)、信用卡号以及其他个人身份信息(PII),构成了现代应用程序和系统中最为关键的部分。这些信息一旦被未经授权的第三方获取,可能引发灾难性的后果,从个人隐私泄露到企业经济损失,甚至是大规模的社会安全问题。保护这些敏感…...
Win10如何一键切换IP地址教程
切换IP地址可能对于许多用户来说是一个相对陌生但又可能经常需要进行的操作。无论是出于网络安全、突破网络限制还是仅仅为了测试目的,一键切换IP地址都能带来极大的便利。以下是在 Windows 10 中通过批处理脚本实现一键切换 IP 地址的详细教程: 方法一&…...
2021-11-09 C++三位数平方含有该数
缘由求解,运算函数,哪位大神教一下-编程语言-CSDN问答 void 三位数平方含有该数() {//缘由https://ask.csdn.net/questions/7560152?spm1005.2025.3001.5141int a 100, aa 1000, f 0;while (a < aa){f a*a;while (f > a)if ((f - a) % aa)f …...
高效检测书签网址,告别无效链接烦恼
软件介绍 你是否有过面对浏览器中满满的书签,却不知道哪些网址还“健在”,哪些已经“跑路”的烦恼?别担心,今天就给大家介绍一款神奇的小工具——“网址小卫士”。 检测轻松搞定 还在一个个手动检查书签网址的有效性吗…...
SpringBoot高校学生评教系统设计实现
概述 基于SpringBoot的高校学生评教系统项目,该系统包含了学生评教、教师管理等功能,适合作为JavaWeb学习项目。 主要内容 1. 学生功能模块 查看评教信息:可以查看学期、院系、任课教师、课程名称等信息评价打分功能:可以对课…...
代码随想录算法训练营第二十天
LeetCode题目: 39. 组合总和40. 组合总和 II131. 分割回文串2176. 统计数组中相等且可以被整除的数对(每日一题) 其他: 今日总结 往期打卡 39. 组合总和 跳转: 39. 组合总和 学习: 代码随想录公开讲解 问题: 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 targ…...
C++入门基础:命名空间,缺省参数,函数重载,输入输出
命名空间: C语言是基于C语言的,融入了面向对象编程思想,有了很多有用的库,所以接下来我们将学习C如何优化C语言的不足的。 在C/C语言实践中,在全局作用域中变量,函数,类会有很多,这…...
GPU怎么绑定到服务器上
确认服务器与 GPU 兼容性1:不同的服务器和 GPU 型号连接方式有所不同,要确保所选的 GPU 卡与服务器兼容。可通过服务器和 GPU 的产品文档,或使用服务器厂商提供的兼容性查询工具进行确认。安装前准备:关闭服务器电源,并…...
opencv函数展示2
一、像素操作与算术运算 1.cv2.split() 2. cv2.merge() 3.cv2.add() 4.cv2.bitwise_and() 5.cv2.bitwise_or() 6.cv2.inRange() 二、仿射变换 1.cv2.getRotationMatrix2D() 2.cv2.warpAffine() 3.cv2.flip() 4.cv2.resize() 三、透视变换 1.cv2.getPerspectiveTransform() 2…...
零基础上手Python数据分析 (16):DataFrame 常用统计分析方法
写在前面 —— 超越简单排序,探索数据内在规律,掌握Pandas统计分析基础 上一篇博客,我们学习了如何使用 Pandas 对 DataFrame 进行排序和排名,这使得我们能够更好地组织数据并快速定位关键信息。 然而,仅仅对数据进行排序和排名,还不足以完全理解数据。 要想更深入地解…...
文件系统 软硬连接
🌻个人主页:路飞雪吖~ 🌠专栏:Linux 目录 一、理解文件系统 🌠磁盘结构 二、软硬连接 🌟软硬链接 🌠软链接: 🌠硬链接: 🌟理解软硬链接的应…...
Linux环境基础开发工具使用
本节目标: 1. 学习yum工具,进行软件安装 2. 掌握vim编辑器使用,学会vim的简单配置 3. 掌握gcc/g编译器的使用,并了解其过程,原理 4. 掌握简单gdb使用于调试 5. 掌握简单的Makefile编写,了解其运行思想…...
秘密任务 2.0:如何利用 WebSockets + DTOs 设计实时操作
在之前的文章中,我们探讨了为什么 DTO 是提升 API 效率和安全性的秘密武器。现在,我们进入了一个全新的场景——我们将深入探讨如何通过 WebSockets DTOs 实现实时操作! Agent X 正在进行一项高风险的卧底任务。突然,总部更新了…...
LeetCode hot 100—括号生成
题目 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例 示例 1: 输入:n 3 输出:["((()))","(()())","(())()","()(())",&…...
2025.04.17【Dendrogram】生信数据可视化:Dendrogram图表详解
Dendrogram customization Go further with ggraph: edge style, general layout, node features, adding labels, and more. Customized circular dendrogram Learn how to build a circular dendrogram with proper labels. 文章目录 Dendrogram customizationCustomized c…...
SDL基础
SDL SDL(Simple DirectMedia Layer)是一个开源的跨平台多媒体开发库,主要用于开发需要图形、音频和输入设备支持的应用程序。它使用C语言编写,提供了简单易用的API,**能够帮助开发者快速实现跨平台的多媒体功能。**SD…...
硬件工程师面试常见问题(2)
第六问:你知道那些常用逻辑电平?TTL与COMS电平可以直接互连吗? 逻辑电平:是数字电路中用于表示二进制逻辑状态(0 和 1)的电压或电流信号范围,是数字系统中器件间信号传输的统一标准。 注:逻辑电…...
Python自学第2天:条件语句,循环语句
条件语句 1.条件判断 score 60 if score > 90:print("优秀") elif score > 60:print("及格") else:print("不及格") 注意: 1、每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语句块。2、使用缩进来划…...
2025年4月16日华为笔试第一题100分
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 01. 博物馆展览规划 问题描述 卢小姐是一家著名博物馆的策展人,她需要从众多展品中选择一些组成新的展览。每件展品可以展示不同的历史文化主题,而博物馆希望通过最少的展品数量覆…...
智能体开发的范式革命:Cangjie Magic全景解读与实践思考
引言:当智能体开发遇见仓颉魔法 在人工智能技术日新月异的今天,智能体(Agent)开发正从实验室走向产业应用的核心舞台。2025年3月,仓颉社区推出的Cangjie Magic开源平台,以其创新的设计理念和技术架构,为这一领域带来了…...
LeetCode hot 100—单词搜索
题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或…...
基于flask+vue框架的灯饰安装维修系统u49cf(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
系统程序文件列表 项目功能:用户,工单人员,服务项目,订单记录,服务记录,评价记录 开题报告内容 基于 FlaskVue 框架的灯饰安装维修系统开题报告 一、选题背景与意义 (一)选题背景 随着城市化进程的加速与居民生活品质的显著提升…...
C/C++指针
为什么要使用指针 函数的值传递,无法通过调用函数,来修改函数的实参;被调用函数需要提供更多的“返回值”给调用函数;减少值传递时带来的额外开销,提高代码执行效率 指针定义:指针是什么 int age18; /* …...
Unity编辑器扩展之项目资源查找工具
一、需要实现的效果如下: 二、在项目的Asset目录下新增Editor目录,新增AssetSearchWindow和EditorDefine和EditorTools这三个C#脚本,并复制以下的代码保存好之后,就可以实现上述功能啦。 -------------------------------------------EditorTools脚本Begin----------------…...
什么是分布式锁?
分布式锁是一种在分布式系统中控制资源共享的机制。 一、背景和作用 在单机环境下,当多个线程同时访问共享资源时,可以通过线程锁(如 Java 中的 synchronized 关键字、ReentrantLock 等)来保证操作的原子性、可见性和有序性&#…...
ESP32- 开发笔记- 硬件设计-ESP32-C3 天线设计-利用嘉立创EDA来设计
这个硬件设计,只是一个随手记录文档。如果中间有什么问题,欢迎大家提出来。 1 板载天线 1.1 背景介绍 PCB(Printed Circuit Board)板载天线是现代电子设备中用于无线通信的一种关键组件,它直接集成在电路板上&#…...
setTimeoutsetIntervalrequestAnimationFrame
requestAnimationFrame 详解及与 setTimeout/setInterval 的比较 requestAnimationFrame(简称 rAF)是浏览器提供的专门用于 动画渲染 的 API,相比 setTimeout 和 setInterval,它在性能和流畅度上有显著优势。以下是详细解析和对比…...
Python内置函数---anext()
用于异步迭代器的核心工具,专为处理异步数据流设计。 1. 基本语法 await anext(async_iterator, default) 参数: async_iterator :实现了异步迭代协议的对象(如异步生成器、异步迭代器类)。 default (可选…...
JavaEE——线程安全
目录 前言1.线程安全的定义2.线程安全问题产生的原因2.1 多个线程修改一个变量2.2 修改操作不是原子的2.3 内存可见性引起的线程安全问题 3.解决线程安全问题的方法3.1 通过synchronized关键字加锁3.2 使用volatile关键字 总结 前言 在使用多线程的时候,难免会出现…...
MongoServerError: Authentication failed.处理办法
1停止MongoDB服务: systemctl stop mongod2临时修改MongoDB配置,禁用认证: vim /etc/mongdb.config 在配置文件中找到 security:authorization: disabled # 临时关闭认证3.重启MongoDB服务 # 重启MongoDB服务 sudo systemctl restart mon…...
IOS微信小程序无法显示背景图片
最近线上突然出现了一个问题,就是原来的在线上的小程序无法显示背景图片。而且这个问题只有在IOS上才有。在安卓上是正常的。 然后这里和前端沟通说是,看能不能用苹果手机真机调试。果然也成功复现出来了,部分图片无法显示。 然后在网上找了…...
实验五 8255和LED数码管显示实验
一、实验目的 1.掌握并行接口8255A的工作原理及使用方法。 2.了解七段数码管显示数字的原理。 3.掌握多位数码显示的接口技术。 二、实验电路 三、实验内容 1.静态显示:按图3连接好电路࿰…...
秒杀系统解决两个核心问题的思路方法总结:1.库存超卖问题;2.用户重复抢购问题。
秒杀系统解决两个核心问题 秒杀系统解决两个核心问题:一、解决库存超卖的核心逻辑:解释:原子性保证: 二、如何避免重复抢购:使用 Redis 做唯一标识判断优点: 三、流程完整梳理:四、通过数据库建…...
大数吞小数
A-春_牛客练习赛134 double 的有效数字约 15-17 位十进制,因此: 如果两个数的数量级相差超过 15-16 个数量级,较小的数会被吞掉。...
1-9 堆宝塔
堆宝塔游戏是让小朋友根据抓到的彩虹圈的直径大小,按照从大到小的顺序堆起宝塔。但彩虹圈不一定是按照直径的大小顺序抓到的。聪明宝宝采取的策略如下: 首先准备两根柱子,一根 A 柱串宝塔,一根 B 柱用于临时叠放。把第 1 块彩虹圈…...
Java虚拟机(JVM)平台无关?相关?
计算机的概念模型 计算机实际上就是实现了一个图灵机模型。即,输入参数,根据程序计算,输出结果。图灵机模型如图。 Tape是输入数据,Program是针对这些数据进行计算的程序,中间横着的方块表示的是机器的状态。 目前使…...