先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
正文
1、硬链接的文件属性和原文件相同,inode、权限、日期、文件内容大小等等相同。
2、硬链接没有创建新的文件—>没有给硬链接分配独立的inode,既然没有创建新文件,就没有自己的属性集合和内容集合。用的内容是别人的inode和内容。
3、硬链接的本质就是在指定的路径下,新增文件名和inode映射关系
4、向硬链接写入数据,原文件
删除原文件后,引用计数减减,所以引用计数又称硬链接数。当一个文件的硬链接数为0时,文件才算真正被删除。
软链接
指令:ln -s 文件名 软链接名
Linux的软链接等同于windows下的快捷方式!
1、软链接是独立的文件,有独立的文件属性和文件内容。 和硬链接的区别就是软链接有独立的inode
2、软链接的文件属性开头是’l’,代表链接文件
2、向软链接写入数据,原文件会因此改变,软链接文件本身不会改变
3、软链接的本质是在把原文件的文件路径存入软链接的data block中,软链接 链接的是文件名,而不是文件的inode(类似windows下的快捷方式)
4、指向的文件如果被删除,那么软链接报错:可以看到原文件inode 926589还存在一个指向,但原文件myfile.txt已经被删除,软链接也会报错(印证了第3点)
取消链接: unlink 链接名
取消链接可以用unlink也可以用rm删掉链接(文件),且删除链接对原文件没有影响
链接的应用
比如软链接,如果要运行某个目录下的程序,就需要输入程序的路径,这样比较麻烦
那么链接一下,输入链接名即可运行程序
理解.和…
理解.
我在当前目录创建一个新目录mydir,查看到inode是921783,硬链接数是2;进入到mydir目录,查看到.的inode也是921783,可以知道,.是硬链接,意思是当前目录,相当于运行程序时会用./程序名即运行当前目录的程序;即这个inode和mydir目录及这个inode和.分别有映射关系即一共两组映射关系
理解…
在目录mydir里再创建一个一个目录dir,可以看到mydir的inode是921783,硬链接数是3;进到mydir目录可以看到当前目录.的inode也是921783;再进到dir目录可以看到…的inode也是921783
…是硬链接,表示上级目录;即和上级目录的inode同样有映射关系
动态库和静态库
在linux系统下,编译c语言通过【gcc -o 可执行文件 编译的文件】可形成可执行文件。形成可执行文件依次通过预处理、编译、汇编、链接。而给编译器传递-c则可形成编译文件对应的.o 文件—可重定向二进制文件,.o文件已经完成了预处理、编译、汇编,最后把全部的.o文件加上库链接起来就可以形成可执行文件了。
恰恰是最后一步,可重定向二进制文件和库是怎么链接起来的呢?
通过库的使用者看待库
现在我写了一个main.c,并且也写了一个两个.h文件和两个.c文件,.h文件有函数实现的方法,.c文件有函数的实现;当函数的拥有者不想给使用者源代码(.c文件)时,就把.c形成的.o(可重定位二进制文件),和.h(函数的方法)给使用者,使用者照样可以链接形成可执行文件
把.o文件(方法的实现),.h文件(有什么方法)给使用者,使用者可以利用这些文件形成可执行文件,这就是库的最初思想
当要使用的.o文件越来越多,就有了一个思想:把多个.o文件打一个包,即库文件,然后把库文件和对应的.h文件给对方即可! 库是.o文件的集合
静态库
静态库特征:程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
ar打包文件
指令【ar -rc 要形成的包文件的名称 要打包的文件】rc(replace and create:打包形成的文件原来存在则替换,不存在则形成)
打包后通过file查看到该文件是当前的归档文件(档案文件)
把.o文件打包了还有.h文件也要打包
output 发布
output 发布文件,创建一个mylib路径,把.a文件放到路径底下的lib路径,把.h文件放到路径底下的include路径。
然后就能看到一个路径底下有我们发布的文件
单单是发布了还不行,还得打包起来好发送给别人,tar 压缩打包
这个压缩包就可以放到yum原上给别人下载使用
现在路径底下只有main.c和压缩包,等于这个压缩包就yum上的库,我刚下载下来,
编译代码时,展开头文件只会在两个地方搜索头文件,一是当前路径(源文件路径)下搜索,二是在系统指定的路径下搜索;
生成静态库
链接静态库有两种方法,一是指定库和头文件,二是把库和头文件放在系统指定的路径
指定库和头文件生成静态库
把压缩包解压后,需要的头文件和库文件在mylib路径底下,所以头文件并不是在源文件路径底下
编译时使用第三方库,需要指明第三方库的头文件路径(-I【大写i】),需要指明第三方库文件路径(-L),需要指明库文件名称(-l【小写L】)
然后就能成功编译
然而查看该文件时,可以看到这个库显示的是动态链接。事实上,对于单个库而言,gcc编译默认是动态链接(建议性),如果是静态库,就选择以静态库的内容拷贝到源文件里的形式实现。而一次编译链接形成可执行程序,链接的不仅仅一个库,则对于多个库时,对于只有静态库则拷贝静态库对应内容到源文件,而对于动态库则动态链接,只要有一个动态库就都是动态链接的形式!
拷贝到系统指定的目录底下生成静态库
把第三方库的头文件拷贝到/usr/include/目录底下,把库文件拷贝到/lib64/目录底下;这就是在yum源下下载资源的过程:把压缩包下载下来,系统自动解压,然后安装即把对应的文件拷贝到对应的地方去;所谓的安装的本质就是拷贝
然而直接编译也会报错,刚刚咱们写的是第三方库,就算拷贝到了系统指定的目录底下,还是得说明库文件是哪个
然而最好还是不要把自己写的文件拷贝到系统底下,这样会污染系统指令池
动态库
- 程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
- 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
- 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
- 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
生成动态库
fPIC:产生位置无关码(position independent code)
要生成动态库时,.c文件编译出来的.o 文件要携带fPIC(形成.o文件在动态库中的偏移量【相对地址】)
shared: 表示生成共享库格式
要生成动态库时,打包.o 文件的库文件不需要ar打包,直接用gcc就可以行,但是要携带shared
然后按照之前对待第三方静态库的方法对待第三方动态库,然而报错,且说明.so文件找不到
在编译的时候告诉了gcc头文件路径、库文件路径和库名称,但是当把程序编译完,程序运行起来的时候,OS和xshell也需要知道这些信息,然而我们写的第三方库不再系统路径底下,OS和xshell无法找到!
那这么让操作系统找到第三方库呢?这里有四种方法:一是在可执行文件的路径底下或者系统默认路径下给库文件建立软链接;二是配置环境变量 LD_LIBRARY_PATH;三把库文件和.h文件拷贝到系统指定的目录底下生成动态库,方法和生成静态库的第二种方法一样后面就不讲了,四是配置文件
在可执行文件的路径底下或者系统默认路径下给库文件建立软链接
在可执行文件的路径底下给库文件建立软链接
在系统默认路径下给库文件建立软链接
image-20230204223251200
配置环境变量 LD_LIBRARY_PATH
这里的配置环境变量只对本次登录有效,下次登录就会失效
操作系统除了在系统默认路径下搜索,也会在LD_LIBRARY_PATH这个环境变量下搜索
把库文件的路径配置到该环境变量里
然后查看该可执行文件时系统就能找到库文件了,而且运行也不会报错
配置文件
在/etc/ld.so.conf.d/路径下有很多配置文件(.conf结尾的),通过
把库文件的路径写道到/etc/ld.so.conf.d/路径的任意一个文件即可
这里我创建一个.conf文件,把库函数路径写进去,注意这里要sudo提权
ldconfig:更新文件配置
配置完文件后,要通过ldconfig更新文件配置
后面可执行文件就可以运行了
动静态库的加载
静态库不需要加载:在编译可执行程序时,就把静态库里的代码拷贝到程序的代码区,需要一份就拷贝一份,要是有多份需要就拷贝多份;可执行程序文件本身也有逻辑地址,静态库在该文件的代码区从0x00000000 到0xffffffff编址,当可执行程序加载到内存中时,这重复的代码就会造成空间浪费
理解动态库的加载
在编译动态库中某对应的.o文件地址时:由于组成动态库的可重定向二进制文件是通过位置无关码fPIC生成的,所以这个地址不是.o的地址,而是**.o文件在动态库中的偏移量**;
然后可执行程序运行时:操作系统会把磁盘中的可执行程序加载到内存,再通过页表映射到进程地址空间的代码段,然后开始执行代码,当执行到动态库时,操作系统发现这个函数链接的地址是一个动态库的地址,且该地址是一个外部地址,操作系统会暂停程序运行,开始把动态库加载到内存中;
加载动态库:把磁盘上的动态库加载到内存中,然后通过页表映射到进程地址空间的共享区,立即就在共享区确认了动态库在进程地址空间的起始地址,然后操作系统跳回到代码段继续执行代码
执行代码:操作系统拿着.o文件在动态库的偏移量去到共享区从起始地址开始找到.o文件然后执行动态库的代码,继续执行后面的代码。这就是完整的动态库的加载过程。
因此程序中多个函数需要链接相同动态库中的相同代码时,就只需要把一份对应代码加载到内存中,不会出现重复代码。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
。
因此程序中多个函数需要链接相同动态库中的相同代码时,就只需要把一份对应代码加载到内存中,不会出现重复代码。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-6qBBpX0q-1713410151428)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!