【linux】:老师问什么是爱情,我说了句:软硬链接和动静态库

news2024/10/7 14:28:23

 

 

文章目录

  • 前言
  • 一、软硬链接
  • 二、动态库和静态库
  • 总结

 


前言

上一篇文章的最后我们讲解了文件的inode,那么文件名和inode有什么区别呢?区别就在于linux系统只认inode号,文件的inode属性中,并不存在文件名,而文件名其实是给用户用的。我们以前讲过linux文件目录,那么目录是文件吗?答案是是的,目录也是文件,并且目录也有inode,任何一个文件一定在目录里面,所以目录的内容是什么呢?首先目录的内部需要数据块,目录的数据块里面保存的是文件名和inode编号对应的映射关系,而且在目录内,文件名和inode互为key值,当我们访问一个文件的时候,我们是在特定目录下进行访问的,要找到inode需要先在当前目录下,找到文件对应的inode编号,一个目录也是一个文件,也一定属于一个分区,结合inode,在该分区中找到分组,在该分组的inode table中,找到文件的inode,通过inode和对应的datablock的映射关系,找到改文件的数据块,并加载到操作系统,并完成显示到显示器,下面我们进入本篇文章的主体


 

一、软硬链接

理解文件的增删查改

根据文件名找到inode -》number,从inode number到inode属性中的映射关系,设置block bitmap对应的比特位,然后将这个比特位置0即可。所以删除文件,只需要修改位图即可。

下面我们看一下inode和datablock的映射关系:

0ebefb9c1db14a1a8807de0dc5452ae1.png

上图中我们只画出了直接索引,但其实并不仅仅是这样,因为直接索引能存放的数据太少了,而二级索引能存储的数据更多,二级索引所指向的数据块里面的内容,不是直接的数据,而是其他数据块的编号,二级索引上面还有三级索引,这些我们就不再介绍了 我们直接进入软硬链接的讲解:

我们先演示如何做一个软连接或硬链接:

7b3b5df20f474803adf0508a98b05c41.png

 建立软连接的命令是ln -s 文件名 软连接文件名

文件属性前面的l代表link,表示链接,下面我们看一下这个链接有什么:

49e28f6179f441f18f32a00f97b52e60.png

 我们发现这个链接指向刚刚那个原始文件,下面我们看看这个文件的inode:

65680a1e22aa497fadae2a500ec590c1.png

 软连接是一个独立的链接文件,有自己的inode number,必有自己的inode属性和内容。下面我们再演示一下硬链接:

e98b0cae80d5427eab7be4e7c7507dd9.png

 硬链接就是刚刚的命令少掉-s选项即可,ln 文件名 硬链接文件名。

下面我们看看硬链接的文件和原始文件有什么关系:

ab975b3cce2d47979cec9fba49af760f.png

 我们发现硬链接和原始文件的inode一模一样,硬链接和目标文件共用一个inode number,意味着硬链接一定是和目标文件使用同一个inode的。

并且文件属性后面的数字都变成2了,这是什么意思呢?我们先讲原始文件删除看看有什么不一样的地方:

336933e139b5436ea2e9d51b417cf1cf.png

 我们发现原来的2又变成1了但是inode依旧存在,我们看看可以读取吗

971bd9a9141f41f19999f8450434fe87.png

 我们发现将原始文件删除后硬链接照样可以打印出原始文件的数据,而软连接则不可以并且显示文件不存在。那么硬链接是什么呢?硬链接其实就是一种引用计数,有相同的文件计数++,当我们删除文件的时候先--计数,只有当计数为0才会真正的将文件删除,如下图所示:

ceeebf7efc14448d832afe0f2d82a383.png

c916361289834ba0aaed792c75f8afbd.png

所以我们之前看到的文件属性后面的数字其实就是硬链接数,我们创建几个硬链接这个数字就会加几, 而软连接内部放的是自己所指向的文件的路径,而硬链接就是原始文件的引用。大家看到这里能联想到软连接是windows里面的什么吗?其实就是程序的快捷方式,我们将快捷方式删除是不影响真正的文件本身的,找到其文件路径照样可以打开软件,所以这就是软连接。上面的测试都是以普通文件做测试的,下面我们看看目录是什么样的:

78c96ba8acbb42ba899e10794fcfd5dc.png为什么一个目录的硬链接数是2呢?通过我们刚刚的描述不难理解,是2的原因一定是因为有一个文件名和映射关系所指向了这个目录,首先目录名和自己的inode就是一个硬链接了,接下来我们进入目录里看看有什么文件指向这个目录:

fe8c20a2c93845c0a9447512d0fe76b0.png

 我们发现这个空目录有隐藏文件,一个.和一个..,我们之前讲过.代表当前目录,..代表上级目录,并且最重要的是.这个文件的inode和目录的inode一模一样如下图所示:

48e17a39f0544ff9a3fb48e0668194f5.png

 那么..是否和.一个道理呢?答案是是的,..是上级目录的inode,如下图:

78fdbb7c47044ed1a8b27b58eeec6624.png

既然我们刚刚可以给文件加一个硬链接,那么目录是否也能呢,我们试试:

3f059bdc3f7a4b6b814433bd3e9b10aa.png 结果大家已经看到了,我们不能给目录加一个硬链接,这是为什么呢?为什么刚刚的. 和 .. 都能给目录建立硬链接,而我们却不行呢?因为操作系统不允许用户对目录建立硬链接,因为如果给目录建立硬链接容易造成环路的路径问题,如下图:

da7a56997aef40f2a7f3232455175341.png

 比如我们给上图中这个路径的107目录建立了硬链接,那么当我们用find进行查找路径的时候,找到了107中的硬链接,然后硬链接又将路径送回到107这样就永远找不到路径了,那么. 和 ..为什么可以避免这个问题呢?因为操作系统对这里做了特殊处理可以判断,而用户如果搞出这样的问题操作系统很难去判断是否造成环路如何解决。

文件的三个时间:

首先查看文件的时间的命令stat + 文件名:

bd2c02a0678446c4b5fb7be2386c5671.png

change是对一个文件的属性做修改的时间如下图所示:

9ccbc281bdf14e26b54207af65aa757e.png 而modify是更改内容的时间,下面我们改一下看看:

35ddb041e6c54dae808740331eb30e71.png

 不知道大家有没有发现,我们改内容后属性的时间也跟着变化了,这是因为更改文件内容会改变文件属性中的大小,所以属性也会变。Access是文件的访问时间,下面我们访问试试:

545f5527125244f3b30c4f171b2c182f.png

 为什么我们访问了也没改呢?这是因为查看文件内容的比重很高,如果我们高频次的修改文件访问时间,就会高频次的访问磁盘将文件属性写入磁盘,这样会大大的消耗IO交互的成本,所以一般是访问多次修改一次时间。

二、动态库和静态库

静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

库我们应该很熟悉了,因为我们写c/c++代码一直用着他们的标准库,下面我们看看linux下的库:

fc1980baa1a74403b3ac4ba85b07fefa.png

 我们的系统已经预装了C/C++的头文件和库文件,头文件提供方法说明,库提供方法的实现,库和头是有对应的关系的,是要组合在一起使用的。头文件是在预处理阶段就引入的,链接本质其实就是链接库,所以我们在vs2019下安装开发环境实际上在安装编译器软件以及我们要开发的语言的库和头文件,如果我们在写代码的时候不包含头文件是没有语法的自动提醒功能的。

库的命名后面必须有.so(动态库)或者.a(静态库),比如我们现在有一个库的名字叫libstdc++.so.6,而一个库的真实名字必须去掉前缀lib和后缀.so,所以刚刚我们的那个库的真实名称应该是stdc++才对。在这里我们要说明一下,一般的云服务器,默认只会存在动态库,不存在静态库,静态库需要单独安装。

下面我们封装一个简单的库让大家了解如何使用库:

1c02f4259c694632bf1be102dc28adb5.png

 我们先创建加法减法的头文件和.c文件,接下来写一段简单的代码:

先完成add的头文件以及.c文件:

#ifndef __ADD_H__
 #define __ADD_H__ 
 int add(int a, int b); 
 #endif // __ADD_H__

 

#include "myadd.h"
 int add(int a, int b)
 {
     return a + b;
 }

 头文件中用条件编译的方式防止头文件被包含,在.c文件中包含.h文件。

接着是sub的头文件以及.c文件:

#ifndef __SUB_H__
 #define __SUB_H__ 
 int sub(int a, int b); 
 #endif // __SUB_H__
#include "mysub.h"
 int sub(int a, int b)
 {
    return a - b;
 }

下面我们实现一下main函数:

#include <stdio.h>
#include "myadd.h"
#include "mysub.h"
 
 int main( void )
 {
    int a = 10;
    int b = 20;
    printf("add(%d,%d)=%d\n", a, b, add(a, b));
    a = 100;
    b = 20;
    printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
 }

下面我们用这三个.c文件生成一个可执行程序:

406915f55757449f9aa2a1809f28093d.png

c64fb9e88d554ca5b769e64f0a3db48e.png

 当然我们运行起来肯定也是没问题的,下一步是如何形成自己的库呢?进行这一步之前我们先用另一种方法给对方使用我们的库:创建两个文件夹,我们做的以下步骤都是不给对方源代码的情况下让对方使用我们的库:

06c8a42bf26f4c9e990b9740fee1e1a2.png

 接下来我们将main.c文件放入给他人使用的文件夹中:

2e5dc79471834803acab9c1f98a6fc6e.png

 下一步我们将.c文件和.h文件都放到mylib当中去:

18bd0f4eaeb8493cbc15c49e84015ed4.png

 下一步就是我们进入mylib路径下将这些文件打包:首先将.c文件经过预处理编译汇编形成.o文件,.o文件被叫做可重定位二进制目标文件,这个文件当前是无法运行的,但是已经是二进制了。

1cd5d082351944458b633eb4ff8dadb6.png

 下一步以相同的步骤将mysub.c文件形成.o文件,如下图:

c0a59ed640094de08364ec38566bd19f.png

 接下来将所有的.h文件拷贝到其他人那里去:

1969208e36e94fabb9054cb27b590af9.png

 然后我们进入其他人的那个文件夹中:

f1ecba517dbd4f35947914c9ed53b08e.png

 到了这里其实想使用我们库的那个人已经可以使用了,他只需要在我们给他的文件夹中编译即可如下图:

0ab86d530efe4429a8c4ce8cce79dad3.png

 我们先让main.c文件也形成一个.o文件,然后将这些.o文件链接到一起:

dba6322084294aee97ef0f5e6ba04127.png

 然后我们运行这个可执行程序发现正常使用我们的库。

下面我们正式的打包库,我们先打包一个静态库:

前面我们说过,库的前缀是lib,后缀是.a:

ccda8108cd4b47a08efaa750592d8632.png

 我们将所有的.o文件放进我们的math静态库中,可以看到静态库占用的空间非常大。下面我们将要给其他人的文件中除了main.c的文件其他的都删除:

2442018d9e734d11968522cb686a468d.png

删除后我们将.h和.a静态库拷贝到给其他人的文件中: 

1c08787a47734d3ca4f50e7da682b9e1.png 有了头文件和静态库那么其他人该怎么使用呢?我们直接gcc main.c就可以使用了。

0a3b020c7ce1409d8d54107aa25e481c.png

 这里报错是因为我们的编译器不认识这个库,所以我们需要用-l命令:

89804c23fbf44e6f805a97baeeba6bf2.png

 我们在形成可执行程序的时候,-L表示链接的意思L后面的.表示在当前路径查找我们的库,-l是在对应的路径下我要连哪个库,如上图所示成功运行。为什么不加前缀和后缀.a呢,因为我们前面说过了库的真正的名字是不包含前缀和后缀的。

经过我们前面所讲的,我们要想将我们的库分享给别人只需要把.a库文件放在一个文件夹里,把.h头文件放在一个头文件里,然后把这两个文件都发给对方即可。或者打包上传,对方想用解压即可。

第三方库的使用总结:

1.需要知道的库文件和头文件

2.如果没有默认安装到系统gcc g++默认的搜索路径下,用户必须指明对应的选项,告知编译器,1.头文件在哪里 2.库文件在哪里 3.库文件具体是谁

3.将我们下载下来的头文件和库文件,拷贝到系统默认路径下,在linux下安装库。而安装和卸载的本质就是拷贝到系统特定的路径下。

4.如果我们安装的库是第三方的(语言,操作系统,系统接口)库,我们要正常使用,即便已经全部安装到了系统中,gcc/g++必须用-l指明具体库的名称。

下面我们进行动态库的演示操作:

我们先将刚刚的.o和.a文件删掉

638698b97d3a4b7ca0db20dbbaa4efc4.png

 动态库直接使用gcc就可以了如下图所示:

68a79037794245b780cebd857303d845.png

 -fPIC选项的意思是形成.o文件,接下来我们将.o文件打包:

动态库打包直接用gcc就可以了

9c18f1f2bb3d4d9ca1c27c473807d37a.png

 我们要形成的库为mymath,记得加前缀和后缀,shared表示我们打的包是一个共享包

eaa25ebadd954ef99517fc0fa1f51203.png

 接下来创建两个给别人的文件夹,将.h都放入一个文件,将.so文件放到另一个文件

e2c1c8f3e8e2443c8d72eb671044eb02.png

接下来我们用tar命令进行打包:

151b1ec331204210bf93816ee0924faf.png打包完成后将文件直接发给其他人:

7ade3b20e6844615a559b2649ce24077.png

这个时候其他人就可以直接解包用我们的库了:

26e8f651993b4ddaa1d45ac641ed50fd.png 在我们加载共享库的时候发现报错了,这是为什么呢?

adf6dc45af724329b9042292332650b3.png

 这就说明在连接的时候动态库没有链接到我们的可执行程序里。其实这里报错的最主要的原因是我们在gcc命令中只是告诉了编译器我们的库在哪里,而操作系统并不知道库在哪里,运行的时候,因为我们的.so并没有在系统的默认路径下,所以操作系统依旧找不到库。那么为什么静态库可以找到呢?因为静态库的链接原则是将用户使用的二进制代码直接拷贝到目标可执行程序中,但是动态库却不会。

那么运行时操作系统如何查找动态库呢?我们有3种方法:

1.环境变量:LD_LIBRARY_PATH

cb793afd296344d38637f0bb9cf3dcec.png

 下面我们演示如何将动态库添加到环境变量中:

b84b1ad5362549da88b27bbd8c7c52d2.png

3b3df4be5a92476db225b92f9cc9aee8.png 这个时候我们再去查环境变量发现已经有了路径:

10a22d6693034a928f8804d520f71db5.png

接下来我们将动态库链接到可执行程序中:

c464a2c195774095ba9280f35292ef1a.png2af31c5580034392b2dc185bf3cedf9e.png

 这次我们发现我们的可执行程序可以成功运行了。

 当然这是一种临时方案,因为环境变量只在本次登录内有效当我们退出去重新登录后又不可以运行了。

2.软连接方案:

首先我们退出重新登录一下让刚刚的环境变量失效,然后在系统库中添加我们的库:

21f8182291aa42d7944800c14aa11025.png

b6fb197ba0864082a3d826ea10d693fb.png

 ln -s后面的是找到我们自己库的路径,后面的lib64是将我们的库的软连接添加到系统库中,

然后我们用ls -l命令查看该路径发现对应的软连接就是我们的库。接下来我们看看可以运行吗:

6383fd46f8cd4fc89aada8bd2d50cd5a.png

 从上图中可以看到能成功运行并且不会像刚刚环境变量那样退出xshell后再登录不可以使用的问题了。

3.配置文件方案

我们先将刚刚的软连接方案解除

b2b196098ef543ed96a9a108631920d3.png

 我们先看看linux下的配置文件是什么样的,然后我们也创建一个配置文件:

041771a7777446c39f1a80d419b47b63.png

 创建好我们自己的配置文件后我们直接把我们的库的路径放进去就可以了:

c2b095ab835d437baa66b4dea9bd87f6.png

4e876575ee034fb999c07ad7db217125.png

59c707e0e1904f2e9744917839a1fc02.png

 在配置文件中我们加上我们库的路径后,下一步就是加载对应的配置文件,加载对应的配置的文件的命令是ldconfig  :注意我所使用的root本身就是超级用户,如果你们是普通用户必须前面加sudo提权。

986a46e28d584de7ad214b1671ffb786.png

 并且此方法和第二个方案一样,即使退出xshell重新登录也可以继续使用库。

以上三种方法任意一种都可以查找到动态库,下面讲讲动静态库的加载问题。

静态链接形成的可执行程序本身就有静态库中对方方法的实现,但是静态库非常占用资源(磁盘,可执行程序体积变大加载占用内存,下载周期变长,占用网络资源)

c24a6b00b40247d89bf94cba02e47b59.png

 上图中右边的大方块为磁盘,磁盘中有一个小方块就是我们刚刚写的静态库,而这个静态库会被多个人使用,并且这些人都会将静态库拷贝一份到自己的文件下面,而大家在使用运行的时候这些代码都会被拷贝到内存中,就如上图中的细长小方块就是内存,里面有4份代码并且都是重复的,如果这样的库在多份程序当中都被使用,并且每一个体积都很大,加载到内存当中就势必非常的占用资源,而占用的资源就是磁盘资源,内存资源,网络资源等。

 下面我们看看动态库的加载问题:

ee2b6aca3504421181af733cd3422e4f.png

 最右边的大圆桶是磁盘,磁盘中用绿色方框圈出来的就是我们的动态库,而磁盘左边的是物理内存。当形成一个可执行程序时需要动态库里面的方法时,并不想静态库那样将代码直接拷贝到可执行程序里,而是将动态库中的方法的地址比如1234链接到可执行程序中。也就是说将可执行程序中的外部符号替换成为库中的具体地址。在运行可执行程序的时候会将可执行程序加载到内存,当程序变成进程不仅仅只是加载到内存,还要创建相应的PCB,所以就有了task_struct和进程地址空间和页表,在代码区有printf方法的虚拟地址,当执行这个方法的时候发现经过页表映射没有这个方法,这个时候操作系统就会检索动态库找到后将动态库通过页表映射到进程的共享区当中(共享区在堆区和栈区的中间)。通过我们的描述大家可以发现,动态库必定面临的一个问题就是:不同的进程,运行程度不同,需要使用的第三方库是不同的,注定了每一个进程的共享空间中的空闲位置是不确定的。而动态库中的所有地址,都是偏移量,默认从0地址开始。只有当动态库真正的被映射进地址空间的时候,它的起始地址才能真正确定。


总结

本篇文章相对较难,因为大部分概念都需要我们配合之前的知识去理解,并且这些问题都很抽象,需要大家自己动手画一遍逻辑图才能明白,对于我们给出的3种让操作系统去查找动态库的方法大家一定要动手尝试,因为这些方法在以后做项目的过程中一定会遇到!下一篇linux文章是进程间通信,到时候会详细的给大家介绍linux下的管道。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425568.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高级篇二、MySQL的数据目录

笔记连接 1、MySQL8的主要目录结构 find / -name mysql1.1 数据库文件的存放路径 MySQL数据库文件的存放路径&#xff1a;/var/lib/mysql/ 1.2 相关命令目录 相关命令目录&#xff1a;/usr/bin&#xff08;mysqladmin、mysqlbinlog、mysqldump等命令&#xff09;和/usr/s…

给我拿三桶水来,实在太干了!!!!!来自腾讯学长爆肝总结的纯干货Java面试手册!!!

前言 23年java的行情懂得都懂&#xff0c;有份对口的工作已经很不错了。但经统计在java行业今年只有百分之30的大学生找到了java工作&#xff0c;剩余的还有百分之70不是在面试的路上就是已经只能被迫转行了&#xff01; 而我们去面试的时候也会被一些面试问题给问到&#xff…

DStream是什么?怎样对DStream进行操作?

DStream的本质 DStream(Discretized Stream)是Spark Streaming提供的基本数据抽象。它表示一个连续的数据流&#xff0c;可以是从源接收到的输入数据流&#xff0c;也可以是通过转换输入流生成的已处理数据流。 DStream由一系列连续的RDD表示&#xff0c;每个RDD都包含来自特…

学习黑客十余年,如何成为一名高级的安全工程师?

1. 前言 说实话&#xff0c;一直到现在&#xff0c;我都认为绝大多数看我这篇文章的读者最后终究会放弃&#xff0c;原因很简单&#xff0c;自学终究是一种适合于极少数人的学习方法&#xff0c;而且非常非常慢&#xff0c;在这个过程中的变数过大&#xff0c;稍有不慎&#…

LONG LIVE KEJU! THE PERSISTENT EFFECTS OF CHINA’S CIVIL EXAMINATION SYSTEM

LONG LIVE KEJU! The persistent effects of China’s civil examination system(Ting Chen et al) – 论文精读 总览方法论 本文研究了古代科举制度对当代人力资本的持续性影响。 本文最值得关注的是工具变量的选取&#xff0c;选取了各县到最近的竹子和松柏产地的最短河流…

归并排序(递归+非递归)

目录一、什么是归并排序&#xff1f;二、归并排序&#xff08;递归&#xff09;三、归并排序&#xff08;非递归&#xff09;一、什么是归并排序&#xff1f; 归并排序&#xff0c;是创建在归并操作上的一种有效的排序算法。算法是采用分治法&#xff08;Divide and Conquer&a…

企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

【redis】缓存双写一致性之更新策略探讨(上)

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

移动通信技术的毫米波波束成形系统构成

随着通信产业尤其是移动通信的高速发展&#xff0c;无线电频谱的低端频率已趋饱和。采用各种调制方法或多址技术扩大通信系统的容量&#xff0c;提高频谱的利用率&#xff0c;也无法满足未来通信发展的需求&#xff0c;因而实现高速、宽带的无线通信势必向微波高频段开发新的频…

No.035<软考>《(高项)备考大全》【第19章】流程管理

【第19章】流程管理1 章节相关2流程管理基础3 流程分析、设计、实施与评估4 流程重构与改进5 项目管理流程的管理和优化6 练习题参考答案1 章节相关 本章节看一遍即可。 2流程管理基础 ★1、BPM是一种以规范化的构造端到端的卓越业务流程为中心&#xff0c;以持续的提高组织…

Springboot基础学习之(十九):通过Mybatis和shiro框架实现授权功能

在shiro整合mybatis实现认证功能 在此篇文章的基础上实现授权的功能&#xff1a;对网页的访问设置权限&#xff0c;只有登录的用户具有该网页的访问权限才能够访问此网页&#xff0c;那篇文章已经将系统的环境全都配好了&#xff0c;只需要在完善功能即可&#xff0c;所以关于项…

怎么入驻Tik Tok的跨境MCN机构呢?

TIKTOK强势崛起&#xff0c;跨境MCN成黄金赛道 社交媒体格局的改变&#xff0c;往往体现在青少年身上。面对TIKTOK的强势崛起&#xff0c;全球社媒霸主Facebook已经出现衰落的趋势。 据相关数据显示&#xff0c;TIKTOK目前有四分之一的用户都是二十岁一下的青少年&#xff0c;拥…

大公司的okr管理- 氛围 + 月历

OKR之剑实战篇06&#xff1a;OKR致胜法宝-氛围&业绩双轮驱动&#xff08;下&#xff09;_vivo互联网技术的博客-CSDN博客 先说说氛围。组织氛围的提出者库尔特勒温被尊为“社会心理学之父”&#xff0c;他的核心理论非常通俗易懂&#xff0c;决定人类行为的&#xff0c;不是…

TK4860E交流充电桩检定装置

TK4860系列是专门针对现有交流充电桩现场检测过程中接线复杂、搬运困难、检测效率低、成本投入高等问题而研制的一系列高效检测仪器&#xff0c;旨在更好的开展充电桩的强制检定工作。 TK4860E交流充电桩检定装置是其中一款专用于现场检定电动汽车单相充电桩的一体式便携式仪器…

236页10万字精选数据中台建设方案2022版(word)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 1. 数据中台建设方案 1.1. 总体建设方案通过对客户大数据应用平台服务需求的理解&#xff0c;根据建设目标、设计原则的多方面考虑&#xff0c;建议采用星环科技Transwarp Data…

JAVA局域网飞鸽传书软件设计与实现

本文的目标是设计一个类似飞鸽传输的局域网通信软件&#xff0c;并分析它在其领域的优势。本设计以C编 写&#xff0c;能在windows 2000/net/xp等环境下运行。设计共分为五大模块&#xff0c;分别是&#xff1a;首先&#xff0c;介绍选题背景及意义和国内外研究现状&#xff1b…

【id:31】【20分】A. Point(类与构造)

题目描述 下面是一个平面上的点的类定义&#xff0c;请在类外实现它的所有方法&#xff0c;并生成点测试它。 输入 测试数据的组数 t 第一组测试数据点p1的x坐标 第一组测试数据点p1的y坐标 第一组测试数据点p2的x坐标 第一组测试数据点p2的y坐标 .......... 输出 输出…

阿里都在用的线上问题定位工具【收藏备用】

简介 Arthas 是Alibaba开源的Java诊断工具&#xff0c;动态跟踪Java代码&#xff1b;实时监控JVM状态&#xff0c;可以在不中断程序执行的情况下轻松完成JVM相关问题排查工作 。支持JDK 6&#xff0c;支持Linux/Mac/Windows。这个工具真的很好用&#xff0c;而且入门超简单&…

【故障诊断】用于轴承故障诊断的性能增强时变形态滤波方法及用于轴承断层特征提取的增强数学形态算子研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。⛳座右铭&#…

动态网站开发讲课笔记06:JSP技术

文章目录零、本节学习目标一、JSP概述&#xff08;一&#xff09;什么是JSP1、JSP的概念2、JSP的特征&#xff08;1&#xff09;跨平台&#xff08;2&#xff09;业务代码相分离&#xff08;3&#xff09;组件重用&#xff08;4&#xff09;预编译&#xff08;二&#xff09;编…