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

理解PLT表和GOT表

1 简介

  现代操作系统都是通过库来进行代码复用,降低开发成本提升系统整体效率。而库主要分为两种,一种是静态库,比如windows的.lib文件,macos的.a,linux的.a,另一种是动态库,比如windows的dll文件,macos的.dylib,linux的so。静态库本身就是中间产物的ar打包link阶段会参与直接的产物生成,而动态库本身已经是完整的二进制文件,link阶段只会进行符号定位。
  传统意义上认为静态链接的函数加载和执行效率要高于动态链接,这是由于静态链接在编译-链接阶段就能够确定函数的库入口地址。而动态链接并不是所有场景下都能够提前知道入口地址,可能只有需要加载的时候才需要确定。为了实现这一点,和提升加载效率,便诞生了PLT和GOT表。

2 PLT表和GOT表

2.1 GOT表

  GOT(Global Offset Table,全局偏移表)是为了实现地址无关代码而引入的一个偏移表格。函数调用或者数据访问时先访问GOT表,再通过该表中对应表项的偏移在动态库映射内存中找到具体的函数地址和数据地址。

  为什么需要使用GOT表进行重定位?

  1. 动态库需要生成地址无关代码方便动态库加载时定位函数地址或者数据地址,否则动态库的动态共享的优势不再存在,因此需要生成地址无关代码;
  2. GOT表格存储在数据区而不属于代码段,这样可以保证各个进程各自持有一份各自的GOT表根据自己的内存映射地址进行调整。

  GOT表需要考虑哪些内容?

  1. 模块间数据和函数地址访问。模块内不需要考虑,模块内使用模块内相对偏移即可。
  2. 全局数据,比如extern表示的数据。

2.2 PLT表

  PLT(Procedure Link Table,过程绑定表)是为了实现延迟绑定的地址表格。由于动态链接是在运行期链接并且进行重定位,本来直接访问的内存可能变成间接访问,会导致性能降低。ELF采用延迟绑定来缓解性能问题,其假设就是动态库中并不是所有的函数与数据都会用到,类似copy-on-write,仅仅在第一次符号被使用时才进行相关的重定位工作,避免对一些不必要的符号的重定位。
  ELF使用PLT(Procedure Linkage Table)实现延迟绑定。在进行重定位时每个符号需要了解符号在那个模块(模块ID)以及符号。当调用外部模块中的函数时,PLT为每个外部函数符号添加了PLT项,然后通过PLT项跳转到GOT表再到最终的函数地址。也就是说第一次调用会间接调用,之后可以直接通过PLT确认调用地址调用。

  PLT解决了哪些性能问题?

  1. 符号解析。动态库加载时不需要加载所有符号,只需要加载部分能够大幅度降低加载耗时;
  2. 避免重复解析。当外部调用动态库内函数或者访问数据地址时需要搜索符号表访问找到对应的项,对于比较大的动态库这个过程比较耗时。通过延迟加载只会在第一次比较耗时,之后不会重复解析;

3 深入理解GOT和PLT

  我们简单做个试验研究下PLT和GOT。下面是一段简单的代码,我们将其编译成动态库libadd.so

#include <cstdio>
#include <cmath>static int myadd(const int a, const int b){return a + b;
}int myabs(const int a){return std::abs(a);
}void test(const int a, const int b){printf("%d %d", myadd(a, b), myabs(a));
}

  下面是生成的动态库的反汇编:

0000000000000630 <_Z5myabsi>:630:	55                   	push   %rbp631:	48 89 e5             	mov    %rsp,%rbp634:	89 7d fc             	mov    %edi,-0x4(%rbp)637:	8b 45 fc             	mov    -0x4(%rbp),%eax63a:	89 c1                	mov    %eax,%ecx63c:	f7 d9                	neg    %ecx63e:	0f 49 c1             	cmovns %ecx,%eax641:	5d                   	pop    %rbp642:	c3                   	retq   643:	66 66 66 66 2e 0f 1f 	data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)64a:	84 00 00 00 00 00 0000000000000650 <_Z4testii>:650:	55                   	push   %rbp651:	48 89 e5             	mov    %rsp,%rbp654:	48 83 ec 10          	sub    $0x10,%rsp658:	89 7d fc             	mov    %edi,-0x4(%rbp)65b:	89 75 f8             	mov    %esi,-0x8(%rbp)65e:	8b 7d fc             	mov    -0x4(%rbp),%edi661:	8b 75 f8             	mov    -0x8(%rbp),%esi664:	e8 27 00 00 00       	callq  690 <_ZL5myaddii>669:	89 45 f4             	mov    %eax,-0xc(%rbp)66c:	8b 7d fc             	mov    -0x4(%rbp),%edi66f:	e8 bc fe ff ff       	callq  530 <_Z5myabsi@plt>674:	8b 75 f4             	mov    -0xc(%rbp),%esi677:	89 c2                	mov    %eax,%edx679:	48 8d 3d 2d 00 00 00 	lea    0x2d(%rip),%rdi        # 6ad <_fini+0x9>680:	b0 00                	mov    $0x0,%al682:	e8 99 fe ff ff       	callq  520 <printf@plt>687:	48 83 c4 10          	add    $0x10,%rsp68b:	5d                   	pop    %rbp68c:	c3                   	retq   68d:	0f 1f 00             	nopl   (%rax)0000000000000690 <_ZL5myaddii>:690:	55                   	push   %rbp691:	48 89 e5             	mov    %rsp,%rbp694:	89 7d fc             	mov    %edi,-0x4(%rbp)697:	89 75 f8             	mov    %esi,-0x8(%rbp)69a:	8b 45 fc             	mov    -0x4(%rbp),%eax69d:	03 45 f8             	add    -0x8(%rbp),%eax6a0:	5d                   	pop    %rbp6a1:	c3                   	retq   

  从上面能够看到对于内部函数的调用直接使用的内部偏移,比如myadd2中调用myadd就是callq 690 <_ZL5myaddii>。而调用printfmyabs就是callq 520 <printf@plt>callq 530 <_Z5myabsi@plt>
  下来我们分析下这个跳转指令。e8表示偏移跳转,后面跟的就是跳转地址偏移,即0xfffffebc,实际跳转地址便是off + rip=0xfffffebc + 674=0x530。(需要注意的是执行 callq 指令之前,RIP 指向 callq 指令的下一条指令,因此RIP是674)。

66f:	e8 bc fe ff ff       	callq  530 <_Z5myabsi@plt>

  接下来我们找到0x530的地址能够看到该地址又跳转到了510即plt表项,最终跳转到0x200af2(%rip)从注释中能够看到是GOT的表项。

0000000000000510 <.plt>:510:	ff 35 f2 0a 20 00    	pushq  0x200af2(%rip)        # 201008 <_GLOBAL_OFFSET_TABLE_+0x8>516:	ff 25 f4 0a 20 00    	jmpq   *0x200af4(%rip)        # 201010 <_GLOBAL_OFFSET_TABLE_+0x10>51c:	0f 1f 40 00          	nopl   0x0(%rax)0000000000000520 <printf@plt>:520:	ff 25 f2 0a 20 00    	jmpq   *0x200af2(%rip)        # 201018 <printf@GLIBC_2.2.5>526:	68 00 00 00 00       	pushq  $0x052b:	e9 e0 ff ff ff       	jmpq   510 <.plt>0000000000000530 <_Z5myabsi@plt>:530:	ff 25 ea 0a 20 00    	jmpq   *0x200aea(%rip)        # 201020 <_Z5myabsi@@Base+0x2009f0>536:	68 01 00 00 00       	pushq  $0x153b:	e9 d0 ff ff ff       	jmpq   510 <.plt>

  接下来要查看GOT需要运行时查看,我们用GDB调试即可。首先在调用myabs的地方断点,单步进入,可以看到当前的代码:

(gdb) x /10i $pc
=> 0x7fffff1f0530 <_Z5myabsi@plt>:      jmpq   *0x200aea(%rip)        # 0x7fffff3f10200x7fffff1f0536 <_Z5myabsi@plt+6>:    pushq  $0x10x7fffff1f053b <_Z5myabsi@plt+11>:   jmpq   0x7fffff1f05100x7fffff1f0540 <__cxa_finalize@plt>: jmpq   *0x200a9a(%rip)        # 0x7fffff3f0fe00x7fffff1f0546 <__cxa_finalize@plt+6>:       xchg   %ax,%ax

  从上面的代码中能够看到需要跳转的地址是RIP+off=0x7fffff1f0536+0x200aea=0x7fffff3f1020。从下面的内容可以看到这个地址存储的是当前指令下一条执行的地址,即0x7fffff1f0536,也就是说这不是真正的函数地址还没有重定位。而上面的push $0x1就是预期这个符号在plt中的槽位编号。

(gdb) x /gx 0x7fffff3f1020
0x7fffff3f1020: 0x00007fffff1f0536
(gdb) x /gx 0x00007fffff1f0536
0x7fffff1f0536 <_Z5myabsi@plt+6>:       0xffd0e90000000168

  我们再单步几次就能看到基本能够确认这个过程是在进行符号解析:

(gdb) si
_dl_runtime_resolve_xsavec () at ../sysdeps/x86_64/dl-trampoline.h:71
71      ../sysdeps/x86_64/dl-trampoline.h: No such file or directory.
(gdb) x /3i $pc
=> 0x7fffff4178f0 <_dl_runtime_resolve_xsavec>: push   %rbx0x7fffff4178f1 <_dl_runtime_resolve_xsavec+1>:       mov    %rsp,%rbx0x7fffff4178f4 <_dl_runtime_resolve_xsavec+4>:       and    $0xffffffffffffffc0,%rsp

  退出当前函数,我们再看PLT表中的表项,可以看到已经被修改为_Z5myabsi的函数地址了。

(gdb) disass '_Z5myabsi@plt'
Dump of assembler code for function _Z5myabsi@plt:0x00007fffff1f0530 <+0>:     jmpq   *0x200aea(%rip)        # 0x7fffff3f10200x00007fffff1f0536 <+6>:     pushq  $0x10x00007fffff1f053b <+11>:    jmpq   0x7fffff1f0510
End of assembler dump.
(gdb) x /gx 0x7fffff3f1020
0x7fffff3f1020: 0x00007fffff1f0630
(gdb) x /gx 0x00007fffff1f0630
0x7fffff1f0630 <_Z5myabsi>:     0x8bfc7d89e5894855

4 总结

  PLT 和 GOT 是现代动态链接的核心机制,通过延迟绑定和地址无关性,提升了动态库的加载效率和灵活性。这些机制确保了代码复用及共享的优势,同时优化了性能。

相关文章:

理解PLT表和GOT表

1 简介 现代操作系统都是通过库来进行代码复用&#xff0c;降低开发成本提升系统整体效率。而库主要分为两种&#xff0c;一种是静态库&#xff0c;比如windows的.lib文件&#xff0c;macos的.a&#xff0c;linux的.a&#xff0c;另一种是动态库&#xff0c;比如windows的dll文…...

InfluxDB 2.0 到 3.0 技术架构演进与性能分析

架构演进 关键技术变化&#xff1a;InfluxDB 3.0 相比 2.0 在架构上进行了重大的技术升级。首先&#xff0c;核心代码由 Go 语言重写为 Rust&#xff0c;以利用 Rust 更高的性能和内存安全特性&#xff0c;从而显著提升数据库的性能、可靠性和安全性。其次&#xff0c;引入列式…...

介绍一下Mybatis的底层原理(包括一二级缓存)

表面上我们的就是Sql语句和我们的java对象进行映射&#xff0c;然后Mapper代理然后调用方法来操作数据库 底层的话我们就涉及到Sqlsession和Configuration 首先说一下SqlSession&#xff0c; 它可以被视为与数据库交互的一个会话&#xff0c;用于执行 SQL 语句&#xff08;Ex…...

docker gitlab arm64 版本安装部署

前言&#xff1a; 使用RK3588 部署gitlab 平台作为个人或小型团队办公代码版本使用 1. docker 安装 sudo apt install docker* 2. 获取arm版本的gitlab GitHub - zengxs/gitlab-arm64: GitLab docker image (CE & EE) for arm64 git clone https://github.com/zengxs…...

7、怎么定义一个简单的自动化测试框架?

定义一个简单的自动化测试框架可以从需求理解、框架设计、核心模块实现、测试用例编写和集成执行等方面入手&#xff0c;以下为你详细介绍&#xff1a; 1. 明确框架需求和范围 确定测试类型&#xff1a;明确框架要支持的测试类型&#xff0c;如单元测试、接口测试、UI 测试等…...

linux组管理

创建组&#xff1a;groupadd &#xff08;创建组命令的详细使用&#xff1a;如何创建组-CSDN博客&#xff09; 修改组&#xff1a;groupmod &#xff08;修改组命令的详细使用&#xff1a;如何修改组-CSDN博客&#xff09; 组配置文件: /etc/group...

【MySQL】常用语句

目录 1. 数据库操作2. 表操作3. 数据操作&#xff08;CRUD&#xff09;4. 高级查询5. 索引管理6. 用户与权限7. 数据导入导出8. 事务控制9. 其他实用语句注意事项 如果这篇文章对你有所帮助&#xff0c;渴望获得你的一个点赞&#xff01; 1. 数据库操作 创建数据库 CREATE DATA…...

二维数组 C++ 蓝桥杯

1.稀疏矩阵 #include<iostream> using namespace std;const int N 1e4 10; int a[N][N];int main() {int n, m; cin >> n >> m;for (int i 1; i < n; i) {for (int j 1; j < m; j) {cin >> a[i][j];}}for (int j m; j > 1; j--) {for (i…...

SAP HCM 回溯分析

最近总有人问回溯问题&#xff0c;今天把12年总结的笔记在这共享下&#xff1a; 12年开这个图的时候总是不明白是什么原理&#xff0c;教程看N次&#xff0c;网上资料找一大堆&#xff0c;就是不明白原理&#xff0c;后来为搞明白逻辑&#xff0c;按照教材的数据一样做&#xf…...

MySQl的日期时间加

MySQL日期相关_mysql 日期加减-CSDN博客MySQL日期相关_mysql 日期加减-CSDN博客 raise notice 查询目标 site:% model:% date:% target:%,t_shipment_date.site,t_shipment_date.model,t_shipment_date.plant_date,v_date_shipment_qty_target;...

前部分知识复习03

一、光照模型 经验型&#xff1a; 1.Lambert光照模型 2.Phong光照模型 3.Blinn-Phong光照模型 物理型&#xff1a; 4.PBR光照模型 二、渲染路径 渲染路径&#xff1a;是为进行光照计算而设置的渲染方式 前向渲染路径顶点照明渲染路径延迟渲染路径 顶点照明渲染路径中的灯光…...

Windows图形界面(GUI)-QT-C/C++ - QT MDI Area

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 一、概述 二、使用场景 1. 多文档编辑器 2. 多窗口应用程序 3. 多视图应用程序 三、常见样式 1. 子窗口管理 2. 布局管理 四、属性设置 1. 添加子窗口 2. 移除子窗口 3. 设置…...

基于微信小程序的私家车位共享系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

用deepseek制作我的第一个长视频---使用AI解决尝试新领域没有经验拖延的问题!

&#xff08;由于技术原因&#xff0c;联网搜索暂不可用&#xff09; 制作一个高质量的Vlog或生活记录长视频&#xff0c;即使零基础也能通过系统规划实现&#xff01;以下是为你定制的「从零到成品」全流程指南&#xff0c;结合叙事逻辑、剪辑技巧和效率工具&#xff0c;帮你…...

零基础学习电磁兼容(EMC)06--时域和频域

大部分工程师很熟悉示波器,并使用它读取信号的频率和电压值,然而,在EMC领域,绝大多数的数据都是从频谱分析仪、测量接收机等基于频率测量的设备中读取的,因此,了解这些频率参数的含义以及与时域信号的关系,是非常重要的。 时域和频域的本质:傅里叶变换及其逆过程 如下…...

解决在使用自己的数据集在 Ultralytics 上运行 RT - DETR 模型时显存爆满的问题

在使用自己的数据集在 Ultralytics 上运行 RT - DETR 模型时&#xff0c;显存爆满是一个常见问题。以下是一系列可以采取的步骤和方法&#xff0c;帮助你解决这个问题&#xff0c;同时使用 Ultralytics 的官方源码。 1. 环境准备 确保你已经安装了 Ultralytics 库&#xff0c…...

Android学习19 -- 手搓App

1 前言 之前工作中&#xff0c;很多时候要搞一个简单的app去验证底层功能&#xff0c;Android studio又过于重型&#xff0c;之前用gradle&#xff0c;被版本匹配和下载外网包折腾的堪称噩梦。所以搞app都只有找应用的同事帮忙。一直想知道一些简单的app怎么能手搓一下&#x…...

鼠标拖尾特效

文章目录 鼠标拖尾特效一、引言二、实现原理1、监听鼠标移动事件2、生成拖尾元素3、控制元素生命周期 三、代码实现四、使用示例五、总结 鼠标拖尾特效 一、引言 鼠标拖尾特效是一种非常酷炫的前端交互效果&#xff0c;能够为网页增添独特的视觉体验。它通常通过JavaScript和C…...

【CSS】什么是响应式设计?响应式设计的基本原理,怎么做

在当今多设备、多屏幕尺寸的时代&#xff0c;网页设计面临着前所未有的挑战。传统的固定布局已无法满足用户在不同设备上浏览网页的需求&#xff0c;响应式设计&#xff08;Responsive Web Design&#xff09;应运而生&#xff0c;成为网页设计的趋势和标准。本文将深入探讨响应…...

单机性能调优中的程序优化

目录 一、系统框架的选择 二、程序优化 表单压缩 局部刷新 仅取所需 逻辑清晰 谨慎继承 程序算法优化 批处理 延迟加载 防止内存泄漏 减少大对象引用 防止争用死锁 存储过程 内存分配 并行 异步 缓存 单机优化顾名思义就是我们要在单机上对系统的性能进行调优…...

2.4学习总结

洛谷1305代码 #include<stdio.h> #include<stdlib.h> struct treenode {char val;struct treenode* left;struct treenode* right; }; struct treenode* createnode(char val) {struct treenode* node (struct treenode*)malloc(sizeof(struct treenode));node-&…...

小程序-视图与逻辑

前言 1. 声明式导航 open-type"switchTab"如果没有写这个&#xff0c;因为是tabBar所以写这个&#xff0c;就无法跳转。路径开始也必须为斜线 open-type"navigate"这个可以不写 现在开始实现后退的效果 现在我们就在list页面里面实现后退 2.编程式导航…...

突破封闭集限制:OvSGTR引领开放词汇场景图生成新纪元

场景图生成&#xff08;Scene Graph Generation, SGG&#xff09;&#xff0c;这个领域&#xff0c;旨在通过解析图像来构建描述性的结构化图表&#xff0c;不仅能够识别图片中的物体&#xff0c;还能捕捉它们之间的相互关系。 这种能力对于诸如图像字幕、视觉问答以及图像生成…...

C语言基础之【程序流程结构】

C语言基础之【程序流程结构】 概述选择结构if语句if…else语句小练习&#xff1a;“三只小猪体重比较” if…else if…else语句小练习&#xff1a;“三只小猪体重比较” 三目运算符小练习&#xff1a;“三只小猪体重比较” switch语句小练习&#xff1a;**“成绩等级判断器”**…...

代码随想录35 动态规划

目录 leetcode 746.使用最小花费爬楼梯 leetcode 62.不同路径 思路&#xff1a; leetcode 63.不同路径|| leetcode 746.使用最小花费爬楼梯 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选…...

【游戏设计原理】98 - 时间膨胀

从上文中&#xff0c;我们可以得到以下几个启示&#xff1a; 游戏设计的核心目标是让玩家感到“时间飞逝” 游戏的成功与否&#xff0c;往往取决于玩家的沉浸感。如果玩家能够完全投入游戏并感受到时间飞逝&#xff0c;说明游戏设计在玩法、挑战、叙事等方面达到了吸引人的平衡…...

51单片机 06 定时器

51 单片机的定时器属于单片机的内部资源&#xff0c;其电路的连接和运转均在单片机内部完成。 作用&#xff1a;1、用于计时&#xff1b;2、替代长时间的Delay&#xff0c;提高CPU 运行效率和处理速度。 定时器个数&#xff1a;3个&#xff08;T0、T1、T2&#xff09;&#xf…...

4 前端前置技术(中):node.js环境

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 前言...

【Leetcode刷题记录】1456. 定长子串中元音的最大数目---定长滑动窗口即解题思路总结

1456. 定长子串中元音的最大数目 给你字符串 s 和整数 k 。请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。 英文中的 元音字母 为&#xff08;a, e, i, o, u&#xff09;。 这道题的暴力求解的思路是通过遍历字符串 s 的每一个长度为 k 的子串&#xf…...

C++效率掌握之STL库:string函数全解

文章目录 1.为什么要学习string&#xff1f;什么是string&#xff1f;2.string类对象的常见构造3.string类对象的容量操作4.string类对象的迭代器5.string类对象的元素访问6.string类对象的元素修改7.string类对象的查找、提取、对比8.string类的非成员函数及npos希望读者们多多…...

Linux命令运行原理及权限管理

目录 1.引言 2.shell命令以及运行原理 3.Linux权限 3.1Linux下的用户类型 3.2Linux权限管理 3.2.1文件访问者的分类&#xff08;人&#xff09; 3.2.2文件类型和访问权限&#xff08;事物属性&#xff09; 3.2.3文件权限值的表示方法 3.2.4文件访问权限的相关设置方法…...

linux内核源代码中__init的作用?

在 Linux 内核源代码中&#xff0c;__init是一个特殊的宏&#xff0c;用于标记在内核初始化阶段使用的变量或函数。这个宏的作用是告诉内核编译器和链接器&#xff0c;被标记的变量或函数只在内核的初始化阶段使用&#xff0c;在系统启动完成后就不再需要了。因此&#xff0c;这…...

系统学习算法:专题九 穷举vs暴搜vs深搜vs回溯vs剪枝

其中标题的深搜&#xff0c;回溯&#xff0c;剪枝我们之前专题都已经有过学习和了解&#xff0c;这里多了两个穷举和暴搜&#xff0c;其实意思都差不多&#xff0c;穷举就是穷尽力气将所有情况都列举出来&#xff0c;暴搜就是暴力地去一个一个情况搜索&#xff0c;所以就是全部…...

《深度洞察ICA:人工智能信号处理降维的独特利器》

在人工智能技术飞速发展的今天&#xff0c;信号处理作为关键环节&#xff0c;面临着数据维度不断攀升的挑战。高维信号数据虽蕴含丰富信息&#xff0c;但也给处理和分析带来诸多难题&#xff0c;如计算资源消耗大、分析复杂度高、模型易过拟合等。独立成分分析&#xff08;ICA&…...

FASTA 和 FASTQ 格式详解|SRA转fastq

FASTA 格式 FASTA 格式是一种用于存储序列信息的简单格式&#xff0c;广泛应用于核酸&#xff08;DNA/RNA&#xff09;和蛋白质序列的存储。它主要由两个部分组成&#xff1a; 描述行&#xff1a;以“>”符号开头&#xff0c;包含序列的描述信息&#xff0c;如名称、来源等…...

Docker使用指南(一)——镜像相关操作详解(实战案例教学,适合小白跟学)

目录 1.镜像名的组成 2.镜像操作相关命令 镜像常用命令总结&#xff1a; 1. docker images 2. docker rmi 3. docker pull 4. docker push 5. docker save 6. docker load 7. docker tag 8. docker build 9. docker history 10. docker inspect 11. docker prune…...

为何在Kubernetes容器中以root身份运行存在风险?

作者&#xff1a;马辛瓦西奥内克&#xff08;Marcin Wasiucionek&#xff09; 引言 在Kubernetes安全领域&#xff0c;一个常见的建议是让容器以非root用户身份运行。但是&#xff0c;在容器中以root身份运行&#xff0c;实际会带来哪些安全隐患呢&#xff1f;在Docker镜像和…...

【人工智能】多模态学习在Python中的应用:结合图像与文本数据的深度探索

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 多模态学习是人工智能领域的一个重要研究方向,旨在通过结合多种类型的数据(如图像、文本、音频等)来提高模型的性能。本文将深入探讨多模…...

以AI为翼:技术能力进阶的新路径

一、引言 1.1 研究背景与意义 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动各领域发展的核心驱动力。从最初简单的算法模型到如今复杂的深度学习架构&#xff0c;AI 技术取得了令人瞩目的进步。自 20 世纪 50 年代人工智能概念提出以来&#x…...

使用 HTTP::Server::Simple 实现轻量级 HTTP 服务器

在Perl中&#xff0c;HTTP::Server::Simple 模块提供了一种轻量级的方式来实现HTTP服务器。该模块简单易用&#xff0c;适合快速开发和测试HTTP服务。本文将详细介绍如何使用 HTTP::Server::Simple 模块创建和配置一个轻量级HTTP服务器。 安装 HTTP::Server::Simple 首先&…...

Jenkins 触发构建的几种常见方式

为了实现自动化构建,Jenkins 提供了多种触发构建的方式。这些触发方式可以根据开发团队的需求来选择,使得构建过程更加灵活和高效。 1. 手动触发构建 手动触发构建是最简单的一种方式,通常用于开发人员或管理员手动启动构建任务。 步骤: 登录 Jenkins 后,进入某个项目(…...

算法基础--二分查找

模板 #include <iostream> #include <cstring> #include <algorithm> #include <unordered_map> /** 二分查找&#xff08;Binary Search&#xff09;是一种高效的查找算法&#xff0c;其时间复杂度为 o(logn) */ using namespace std;const int N …...

Vue 3 30天精进之旅:Day 14 - 项目实践

在前面的学习中&#xff0c;我们已经掌握了Vue 3的基础知识&#xff0c;包括其核心概念、Vue Router、Vuex&#xff0c;以及异步操作等。今天是一个重要的里程碑&#xff1a;我们将把这些知识整合到一个实际的项目中。通过项目实践&#xff0c;你将能够深入理解所学知识&#x…...

【Java基础-42.4】Java中的包装类对象默认值:深入解析与注意事项

在Java编程中&#xff0c;包装类&#xff08;Wrapper Classes&#xff09;是将基本数据类型&#xff08;如int、char等&#xff09;封装为对象的类。它们提供了更多的功能和灵活性&#xff0c;例如允许基本数据类型参与面向对象的操作&#xff08;如存储在集合中&#xff09;。…...

Linux进程概念

目录 一.进程 二.进程状态 三.环境变量 四.程序地址空间 五.Linux2.6内核进程调度队列 一.进程 基本概念 课本概念&#xff1a;程序的一个执行实例&#xff0c;正在执行的程序等内核观点&#xff1a;担当分配系统资源&#xff08;CPU时间&#xff0c;内存&#xff09;的…...

Linux的简单使用和部署4asszaaa0

一.部署 1 环境搭建方式主要有四种: 1. 直接安装在物理机上.但是Linux桌面使用起来非常不友好.所以不建议.[不推荐]. 2. 使用虚拟机软件,将Linux搭建在虚拟机上.但是由于当前的虚拟机软件(如VMWare之类的)存在⼀些bug,会导致环境上出现各种莫名其妙的问题比较折腾.[非常不推荐…...

人工智能专业术语详解(A)

人工智能不仅是指寻求如何替代人类的机器人或人类寻求自我挑战的游戏&#xff0c;更是指运用复杂的程序化数学&#xff0c;其结果与高质量的训练数据相结合&#xff0c;推动了我们在日常生活中所看到的技术进步。从无人驾驶汽车到寻找癌症的治疗方法&#xff0c;人工智能正在逐…...

深度学习 Pytorch 基础网络手动搭建与快速实现

为了方便后续练习的展开&#xff0c;我们尝试自己创建一个数据生成器&#xff0c;用于自主生成一些符合某些条件、具备某些特性的数据集。 导入相关的包 # 随机模块 import random# 绘图模块 import matplotlib as mpl import matplotlib.pyplot as plt# 导入numpy import nu…...

deepseek的对话风格

概述 deepseek的对话风格&#xff0c;比一般的模型的回答多了思考过程&#xff0c;这是它比较可爱的地方&#xff0c;模型的回答有了思考过程&#xff0c;对用户而言大模型的回答不完全是一个黑盒。 deepseek的对话风格 train_prompt_style """Below is an…...

Spring Security(maven项目) 3.0.2.9版本 --- 改

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…...