【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库

目录

  • 引入
  • 内存级文件
    • 重新使用C文件接口 -- 对比重定向
      • 写文件
      • 读文件
      • 文件流
    • 认识文件操作的系统接口
    • open
      • 参数 -- flag
        • flag的内容
        • 宏的传参方式
      • open
      • 关闭文件
      • 写文件
      • 读文件
      • 结论
    • 引入文件描述符fd、对文件的理解
      • 理解一切皆文件
      • 方法集
      • 文件fd的分配规则
  • 重定向
    • 代码的重定向
      • 输入重定向
      • 输出重定向
      • 追加重定向
    • 指令重定向
      • 输入重定向
      • 输出重定向
      • 追加重定向
    • 修改之前的shell,让它支持重定向
  • 缓冲区
    • 概念
    • 在哪里
  • 磁盘级文件(文件系统)
  • 磁盘
      • 磁盘的机械构成
      • 磁盘的物理存储
      • 磁盘的逻辑存储
        • 1、红色部分
        • 2、蓝色部分
        • 文件的增删查改和路径有关
    • 具体的文件系统
  • 软硬链接
    • 原理
    • 应用场景
  • 动静态库
    • 回顾
    • 动态库的制作和使用
    • 理解动态库加载
      • 系统角度理解
      • 编址
      • 理解动态库动态链接和加载问题

引入

a、文件 = 内容 + 属性
b、访问文件之前,都得先打开。修改文件,都是通过执行代码的方式完成修改,文件必须被加载到内存中
c、进程在打开文件
d、一个打开多少个文件?可以打开多个

一定时间段内,系统中有多个进程,那么就有更多同时被进程打开的文件,OS要不要管理多个被进程打开的文件?肯定的,先描述再组织

e、进程和文件的关系,struct task_struct和struct xxxx
f、没有被打开的文件在哪?磁盘

内存级文件

重新使用C文件接口 – 对比重定向

写文件

文件创建的路径和进程有着很大的关系
在这里插入图片描述

tu
像文件里面写入内容:fputs
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>int main()
{FILE* fp = fopen("./log.txt", "w");if(fp == NULL){perror("fopen");return 1;}const char* str = "hello linux\n";fputs(str, fp);fclose(fp);return 0;
}

文件打开再关闭就被清空了?
以w方式打开文件,该文件会被清空在这里插入图片描述
echo “xxxxxx” > log.txt
以a的方式打开,不会清空文件
在这里插入图片描述
echo “xxxxxx” >> log.txt

fwrite写入数据
第一个参数:写入文件的其实内存;第二个参数:写入数据的大小,每个基本单位的大小;第三个参数:写入几个基本单元;
返回值:写入了多少个基本单位

fputs:是写入字符串的形式,它是认识字符串,以\0结尾
fwrite:是以二进制流写入,不认识字符串

在这里插入图片描述
如果没有此文件,当指定绝对路径就会在绝对路径下创建这个文件,否则就在该进程所在目录下创建

int main()
{FILE* fp = fopen("log.txt", "w");if(fp == NULL){perror("fopen");return 1;}char* str = "hello file\n";int cnt = 5;while(cnt){int num = fwrite(str, strlen(str), 1, fp);cnt--;}fclose(fp);return 0;
}

那改变进程的路径,创建的这个文件也会变
在这里插入图片描述

读文件

fgets:一行读出

文件流

程序默认打开的文件流

stdin标准输入键盘设备
stdout标准输出显示器设备
stderro标准错误显示器设备

向显示器继续打印的方法
printf、fprintf、fwrite、fputs

int main()
{FILE* fp = fopen("./log.txt", "w");if(fp == NULL){perror("fopen");return 1;}//标准写入//默认想显示器写入,写入流是stdoutprintf("hello printf\n");//与printf略有不同,写入到哪里不是默认的fprintf(stdout, "hello fprintf\n");fprintf(fp, "hello fprintf\n");//char* str = "hello fputs";fputs(str, fp);fputs(str, stdout);//char* str2 = "hello fwrite";fwrite(str2, strlen(str2), 1, fp);fwrite(str2, strlen(str2), 1, stdout);fclose(fp);

标准输入的方法
scanf 、 fread、fscanf

	FILE* fp2 = fopen("./log.txt", "r");if(fp2 == NULL){perror("fopen");return 1;}char str3[64];scanf("%s", str3);printf("%s\n", str3);fscanf(stdin, "%s", str3);printf("%s\n", str3);fread(str3, strlen(str3), 1, stdin);fclose(fp2);

结论:stdin、stdout、stderro可以直接被使用

认识文件操作的系统接口

访问文件不仅仅有C语言上的文件接口,OS必须提供对应的访问文件的系统调用

w:会清空文件
a:追加文件
r:读取文件

open

在这里插入图片描述

返回值:成功–文件描述符, 失败—1
参数:flags
返回值:int类型的数据

参数 – flag

flag的内容

在这里插入图片描述
在这里插入图片描述

O_RDONY只读打开
O_WRONLY只写打开
O_RDWR读写打开
O_CREAT如果文件没有就创建
O_TRUNC当对已有内容文件做写入时,会对文件内容清空
O_APPEND每次文件打开向文件结尾处写,追加
宏的传参方式

如果传五个参,要设置五个参数比较低级,可以设置标志位
设置一个参数,参数类型是int, 每个bit位代表一个flag

#include<stdio.h>
#include<string.h>
#include<unistd.h>#define ONE 1
#define TWO (1<<1)
#define THREE (1<<2)
#define FOUR (1<<3)
#define FIVE (1<<4)void Print(int flag)
{if(flag & ONE) printf("1\n");if(flag & TWO) printf("2\n");if(flag & THREE) printf("3\n");if(flag & FOUR) printf("4\n");if(flag & FIVE) printf("5\n");return;
}int main()
{Print(ONE);printf("----------------------\n");Print(THREE);printf("----------------------\n");Print(ONE|TWO|THREE);printf("----------------------\n");Print(THREE|FOUR|FIVE);return 0;
}

daim
对于open函数中的flag参数也是如上那么使用

open

先学习三个参数的
mode : 权限设置

普通文件:0666

在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{int fd = open("log.txt", O_WRONLY|O_CREAT);close(fd);return 0;
}

在这里插入图片描述
两个参数的open在没有文件的时候也能创建,但是创建文件的权限是乱的
因此需要三个参数的open的第三个参数mode去设置创建文件的权限

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{int fd = open("log.txt", O_WRONLY|O_CREAT, 0666);close(fd);return 0;
}

在这里插入图片描述
但是上面创建的文件的属性和我们设置的0666还是不一样的,它是0644。那是因为操作系统有自己的掩码umask

不使用系统的umask,想使用自己的可以在代码中使用umask()函数进行设置
在这里插入图片描述

在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{umask(0);int fd = open("log.txt", O_WRONLY|O_CREAT, 0666);close(fd);return 0;
}

在这里插入图片描述

如果文件存在,使用两个参数的open,如果文件不存在,使用三个参数的open

关闭文件

利用返回值关闭文件

用那个整数文件描述符
在这里插入图片描述
在这里插入图片描述

返回值
为何默认从3开始?0、1、2已经被用了,stdin – 0、stdout–1、stderror – 2
数组下标?

写文件

write

strlen(str)不要+1 : \0不是字符串的内容,是C语言规定字符串以、0结尾。写入就是乱码

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>int main()
{//写文件int fd = open("log.txt", O_WRONLY|O_CREAT, 0666);if(fd == -1){perror("open");return 1;}char* str = "hello world";ssize_t i = write(fd, str, strlen(str));if(i < 0){perror("write");return 1;}close(fd);return 0;
}

在这里插入图片描述

系统调用写文件,不会清空文件,直接覆盖式的往里写
在这里插入图片描述
参数flag使用O_TRUNC,即可清空文件里的内容再往里面写
在这里插入图片描述

读文件

在这里插入图片描述
返回值:ssize_t有符号的整数

fd:要读取文件的描述符
buf:读出的内容存放的缓冲区
count:放入内容最大可以存放多少

=0文件结束
<0读取错误
>0读取成功,读到多少个字符
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>int main()
{int fd = open("log.txt", O_RDONLY);char str[1024];ssize_t s = read(fd, str, sizeof(str)-1);str[s] = '\0';printf("%s\n", str);close(fd);

结论

1、C语言的文件接口,本质是封装了系统调用。不仅在接口进行封装,在类型上进行封装
2、FILE是C标准库自己封装的一个结构体,这个结构体里一定包含open返回的那个fd(0.1.2.3…)
3、为何C语言要封装?为了保证自己的跨平台性和可移植性
4、文件描述符的本质:数组下标

引入文件描述符fd、对文件的理解

文件描述符的本质:数组下标

理解一切皆文件

方法集

对于文件的描述struct file 里面有一块是函数指针,函数指针指向具体的硬件的调用方法

文件fd的分配规则

现象1:
关掉0文件,再打开自己文件,看其文件描述符
tu
最小的没有被使用的数组下标,会分配给最新打开的文件
现象2:
关掉1,打印时并没有在屏幕里打印出来,竟然把信息写入到了文件里面
输出重定向:语言层不变,在操作系统层进行更改
在这里插入图片描述

重定向

代码的重定向

输入重定向

输入重定向,从键盘输入的重定向,stdin – 0

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>int main()
{close(0);int fd = open("log.txt", O_RDONLY);char buffer[1024];while(1){char* s =  fgets(buffer, sizeof(buffer), stdin);if(s == NULL) break;printf("file content:%s", buffer);}close(fd);return 0;
}

输出重定向

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>int main()
{char* str = "hello world";int fd = open("log.txt", O_WRONLY|O_CREAT|O_APPEND, 0666);dup2(fd, 1);fprintf(stdout, "file %s\n", str);close(fd);return 0;
}

追加重定向

不想利用文件描述符的分配规则,直接打开,打开之后再拷贝到1的位置,也完成了重定向
在这里插入图片描述
在这里插入图片描述
最终只剩old

dup2(fd, 1);
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>int main()
{char* str = "hello world";int fd = open("log.txt", O_WRONLY|O_CREAT|O_APPEND, 0666);dup2(fd, 1);fprintf(stdout, "file %s\n", str);close(fd);return 0;
}

在这里插入图片描述

指令重定向

输入重定向

没有对应的文件会创建
在这里插入图片描述
什么也不做的时候会被清空
在这里插入图片描述

输出重定向

在这里插入图片描述

追加重定向

在这里插入图片描述

修改之前的shell,让它支持重定向

缓冲区

概念

缓冲区是一块内存空间
提高使用者效率
刷新:聚集数据,一次拷贝,提高整体效率
我们一直在说的缓冲区和内核中的缓冲区没有关系,语言层面的缓冲区,C语言自带缓冲区

调用系统调用是有成本的,时间&&空间
单次调用一次系统调用就可以完成工作是效率比较高的

在这里插入图片描述
语言层缓冲区刷新
(1)无刷新,无缓冲
(2)行刷新 ----- 显示器,XXXX\nYY
(3)全刷新 ----- 普通文件,缓冲区写满才刷新

例外
强制刷新
进程退出,要自动刷新
内核中的缓冲区
OS自主决定

在哪里

缓冲区在大写的FILE*内部,像stdin、stdout、stderror都是一个FILE里面都有一个缓冲区
如何证明这个缓冲区的存在呢?
在这里插入图片描述
在这里插入图片描述
子进程先退出,退出时对于缓冲区需要进行刷新,刷新就是修改,修改就要写时拷贝,因此打了两遍

缓冲区还要支持格式化输入输出的实现
键盘显示器的输入和显示都是字符级的,格式化输入输出,就是把字符转换成int、string...,或者int、string...转换成字符级的

磁盘级文件(文件系统)

如何让系统快速定位一个文件?
文件系统,通过路径快速定位文件

例如:菜鸟驿站取快递

磁盘

磁盘的机械构成

盘片、磁头(一面一个磁头)、马达、伺服系统(识别指令并控制盘片和磁头)

磁盘的物理存储

磁道/柱面:一圈
扇区:磁道中的某一部分成为扇区,磁盘IO的基本单位,不一定是系统的

当你想要修改某一个扇区中的一个bit位,必须把整个扇区加载到内存里,修改要修改的bit位,之后再将整个扇区的信息写入。一般512字节

磁头/盘面:一个磁头一个盘面,一个盘面一个编号

访问某一个扇区:
CHS定位法
1、通过磁头定位在哪个磁道/柱面 cylinder
2、使用哪一个磁头/盘面head
3、使用哪一个扇区sector

磁盘的逻辑存储

逻辑存储方便软件的编写
LBA地址logical block address
虽然把内容进行了抽象,但是一次管理这么多还是不容易,所有分成几块,分区
大的分区再分成很多很多组

一个文件一个inode(大小128字节)

删除文件:不会删除内容,只要把inode bitmap和block bitmap使用的置为0就好了
Linux磁盘文件的特性:内容+属性

内容和属性分开存储
内容大小不确定,可能很大,可能很小
属性固定大小的
文件名不属于文件属性

ll -i //显示inode

在这里插入图片描述
系统中,表示一个文件吧不是用文件名,而是inode
每个inode的大小:128字节

inode Bitmap:知道inode Table的使用情况
Data blocks:数据区
Block Bitmap:块位图
Group Descriptor Table:块组描述符表

系统里面创建一个文件的步骤
在某一个块创建一个文件,首先查Inode Bitmap找一个没有被使用的inode,将该文件的相关属性写到找的那个inode在inode table里面。当对此文件进行写入数据的时候,先查Block Bitmap看看数据区的哪一块可以使用,写入到数据区相应的块。之后在该文件的inode里面的有个int block[15]写到这里面,让文件知道自己用了哪个块

inode在整个分区内唯一
在这里插入图片描述

1、首先确定inode在哪个组里

1、红色部分

对于一个文件,int block只有15块吗,这么小?不是的,有直接索引、间接索引、三级索引
在这里插入图片描述

2、蓝色部分

在这里插入图片描述
GDT,Group Descriptor Table:块组描述符,对分组进行管理,描述块组属性信息
超级块(Super Block)存放整个分区情况,对分区做管理,一个文件系统对应一个super block。一个区里选n个group里面有super block,内容是一致的
在这里插入图片描述
每个分区可以写入相同或不同的文件系统 — super block

目录是不是文件?是。inode(inode编号)+ 目录的内容(文件名和inode的映射)
当目录没有w权限,在该目录里面就没法创建文件,没法删除文件
当目录没有r权限,就读不到文件名和inode的映射信息,也就读不到该目录下的文件信息

创建文件
(1)查询inode bitmap查找哪个inode没有用,在相应位置创建inode
(2)将inode编号和文件名的对应写在相应目录的内容里
删除一个文件
(1)从目录里面找到要删文件名对应的inode
(2)将inode bitmap和block bitmap该文件使用的位置设置为0
(3)删除该文件在相应目录内容里的inode和文件名的对应

那么访问目录的内容也是需要inode的,哪里来的

文件的增删查改和路径有关

根目录的inode,开机OS是知道的
查一个文件:在内核中,都要逆向的递归般得到/,从根目录进行路径解析

struct dentry{ }每打开一个路径都会缓存路径,缓存成一个dentry

一个被写入文件系统的分区,要被linux使用,必须要先把这个具有文件系统的分期进行==“挂载”==

挂起:一个文件系统所对应的分区,挂载在对于目录里面
每一个分区都会挂载在一个目录下在这里插入图片描述
访问一个文件,可以根据路径前缀,优先区分文件在哪一个分区下

具体的文件系统

软硬链接

原理

软连接
在这里插入图片描述

软链接本质:是一个文件,因为它有自己的inode
软件内容放的是目标文件的路径,类似快捷方式

硬链接
在这里插入图片描述

硬链接:本质不是一个独立的文件,因为它的inode编号和目标文件的一样。一定没有新建文件
是新的文件名,和目标文件inode号的映射关系,写入到指定的目录的数据库中

硬链接像重命名,引用计数
在这里插入图片描述
在这里插入图片描述

应用场景

删除一个文件

rm -f 文件名
unlink 文件名

1、软链接
当我们写了一个项目mytest要传给其他人,不想把原始代码传给他,只传bin、conf、log、myexe
在这里插入图片描述
对方要运行myexe就需要./bin/myxe这样很麻烦,因此可以用一个软连接
在这里插入图片描述
2、硬链接
当创建一个空文件的时候,它的硬链接数就是2,为什么?
在这里插入图片描述
因为他有一个.
在这里插入图片描述

OS不允许用户自己给目录简历硬链接,因为会形成环路问题
OS可以自己建立,eg. ..

动静态库

回顾

1、默认安装的是动态库,云服务器,静态库(c标准库)默认没有安装
2、默认编译程序,用的是动态链接的

动态库的制作和使用

为什么要有库?
提高开发效率
隐藏源代码

1、建立静态库

当没有源代码的时候,只有.o .h就可以使用里面的方法
假设我有一些写好的方法,user这个用户想要使用,但我不想给他我的源代码,就可以只给他.o .h文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

但是当.o文件很多的时候很麻烦,而且难免会有遗漏的

ar -rc libmyc.a  打包文件 打包文件

在这里插入图片描述
库名:myc,去掉前缀、去掉后缀
在这里插入图片描述

-l:链接哪个库
-L:连接的库在什么地方,因为系统只默认知道lib64下的,所以这要指明

在这里插入图片描述
2、形成动态库并发布
转换成.o文件
fPIC :产生位置无关码

//形成.o文件
gcc -c -fPIC 文件名

动态库打包
shared:表示生产共享库格式

gcc -shared -o libxxx.so xxxx.o xxxx.o

库的名字以so结尾
在这里插入图片描述
但此时给使用者动态库,还是需要给动态库、.h等文件,我们可以把它们合并成一个

libmyc.so: mymath1.o mymath2.ogcc -shared -o $@ $^%.o:%.cgcc -c -fPIC $<
#mymath1.o:mymath1.c
#	gcc -c -fPIC $<
#mymath2.o:mymath2.c
#	gcc -c -fPIC $<.PHONY:clean
clean:rm -f *.o mylib libmyc.so.PHONY:output
output:mkdir -p mylib/includemkdir -p mylib/libcp -rf *.h mylib/includecp -rf *.so mylib/lib

其中$<代表依赖的对象从左到右一个一个执行

在这里插入图片描述
还可以吧mylib压缩一下
在这里插入图片描述
在这里插入图片描述

不想使用-L:把这个库拷贝到/lib64

//看可执行程序连接了那些库                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
ldd xxx.out

4、用户下载
在这里插入图片描述

下载使用很麻烦,把.h和库拷贝到默认路径下,就可以不用带了
在这里插入图片描述

所谓的把库(其他软件)安装到系统中,本质就是把文件拷贝到指定路径

在这里插入图片描述
在这里插入图片描述

5、卸载
不建议把自己写的不成熟的库写到默认路径里
在这里插入图片描述

注意
静态库只需要编译的时候使用,之后运行什么的就不需要了(只影响编译阶段)
动态库:(1)编译时搜索路径 ---- gcc(2)运行时的搜索路径 — 操作系统
对于动态库在编译的时候可以跑通,运行的时候又找不到库了
在这里插入图片描述

解决方法
1、把自己的库拷贝到默认路径下/lib64,既可以支持编译、又可以支持运行
2、将不在系统默认库搜索路径下的库连接,添加到LD_LIBERERY_PATH
在这里插入图片描述:系统运行程序时,动态库查找时的辅助,:为分隔符
export LD_LIBERERY_PATH=$LD_LIBRARY_PATH:具体路径
问题:重新登陆就没有了,但是在家目录里面的.bashrc里配置
3、对库文件在默认库路径下建立同名软连接
4、配置文件:把路径放到配置文件里就可以
/etc/ld.so.conf.d在该目录下创建配置文件
ldconfig使配置文件生效

理解动态库加载

1、同时形成动静态库,默认动态链接
2、非要静态链接必须使用选项-static
3、如果只提供静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体是静态链接
4、如果只提供动态库,默认只能动态链接,非得静态链接,会发生连接报错

系统角度理解

库函数的调用,依旧在进程的地址空间中进行的
动态库加载之后,会映射到进程的共享区

1、谁来决定,哪些库加载了,那些没加载?OS会自动决定
2、系统中可以同时有多个库吗?可以
3、操作系统对这些库先描述再组织

编址

可执行程序加载之前,就有地址
我们进程地址空间里面很多地址数据,是从可执行程序里面来的(因为不同的可执行程序,他的数据段和代码段是不一样的,进程初始化进程地址空间每块多大的时候就是根据可执行程序)
可执行程序编制方式:
绝对编址方式—平坦模式(从0开始编址)
相对地址—逻辑编制(偏移量)
==虚拟地址空间本身不仅OS要遵守,编译器编译程序的时候,也要遵守

理解动态库动态链接和加载问题

1、进程的地址空间既然是一个数据结构对象,谁来用什么数据初始化呢?
可执行程序本身在加载到内存之前,根据自身表头的数据部分初始化进程地址空间的数据段、代码段等的begin end

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

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

相关文章

手写实现call,apply,和bind方法

手写实现call&#xff0c;apply和bind方法 call&#xff0c;apply和bind方法均是改变this指向的硬绑定方法&#xff0c;要想手写实现此三方法&#xff0c;都要用到一个知识点&#xff0c;即对象调用函数时&#xff0c;this会指向这个对象&#xff08;谁调用this就指向谁&#…

Redis全系列学习基础篇之位图(bitmap)常用命令的解析

文章目录 描述常用命令及解析常用命令解析 应用场景统计不确定时间周期内用户登录情况思路分析实现 统计某一特定时间内活跃用户(登录一次即算活跃)的数量思路分析与实现 描述 bitmap是redis封装的用于针对位(bit)的操作,其特点是计算效率高&#xff0c;占用空间少,常被用来统计…

Java | Leetcode Java题解之第518题零钱兑换II

题目&#xff1a; 题解&#xff1a; class Solution {public int change(int amount, int[] coins) {int[] dp new int[amount 1];boolean[] valid new boolean[amount 1];dp[0] 1;valid[0] true;for (int coin : coins) {for (int i coin; i < amount; i) {valid[i…

Java的包、final关键字以及代码块

Java的包、final关键字以及代码块 一、包 包的作用 &#xff1a; ​ 包就是文件夹&#xff0c;用来管理各种不同功能的Java类 包名的书写规则&#xff1a; ​ 公司域名反写 包的作用&#xff0c;需要全部英文小写&#xff0c;见名知意 什么是全类名&#xff1a; ​ 包名…

【AI视频换脸整合包及教程】AI换脸新星:Rope——让换脸变得如此简单

在数字技术迅猛发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;的应用已经渗透到了我们生活的方方面面&#xff0c;从日常的语音助手到复杂的图像处理&#xff0c;无不体现着AI技术的魅力。特别是在娱乐和创意领域&#xff0c;AI技术更是展现出了惊人的潜力。其中&a…

Ubuntu下安装和配置MySQL5.7教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 在ubuntu下安装MySQL数据库 查看操作系统版本 ​编辑 添加 MySQL APT 源 访问下载页面并下载发布包 安装发布包 安装MySQL 查看MySQL状态 开启自启动 登…

Java中常见的异常类型

1、Exception和Error有什么区别&#xff1f; 首先Exception和Error都是继承于Throwable类&#xff0c;在Java中只有Throwable类型的实例才可以被抛出&#xff08;throw&#xff09;或者捕获&#xff08;catch&#xff09;&#xff0c;它是异常处理机制的基本组成类型。 Except…

Unity的gRPC使用之实现客户端

应用背景&#xff1a;本想Unity调用C的dll库获取一些数据资源&#xff0c;但是由于自己调用的C库模块化处理的不太理想&#xff0c;众多dll之间相互依赖&#xff0c;使得在调用dll的时候&#xff0c;会忽略一些dll的缺失&#xff0c;使Unity项目报错&#xff0c;故想到了使用gR…

GPU-主板-内存-硬盘-CPU-电源分类及区别总结大全

一、背景 用了7年的笔记本&#xff0c;现在感觉它实在是扛不住了&#xff0c;中间自己缝缝补补坚持到现在&#xff0c;把机械硬盘换成了固态&#xff0c;加装了内存条。换过2次还是3次风扇&#xff08;不知道为啥坏的&#xff0c;高转速时哧哧响&#xff09;&#xff0c;换过一…

【JavaSE练习题】数组的创建和使用

数组的创建和使用 奇数位于偶数之前冒泡排序两数之和只出现一次的数字多数元素存在连续三个奇数的数组 奇数位于偶数之前 调整数组顺序使得奇数位于偶数之前。调整之后&#xff0c;不关心大小顺序。 如数组&#xff1a;[1,2,3,4,5,6] 调整后可能是&#xff1a;[1, 5, 3, 4, 2,…

使用Vue.js和Vuex构建可维护的前端应用

使用Vue.js和Vuex构建可维护的前端应用 Vue.js简介 安装Vue.js 使用npm安装 使用CDN引入 创建Vue项目 安装Vuex 初始化Vuex Store 在Vue组件中使用Store Vuex模块化 Vuex命名空间 Vuex插件 Vuex热重载 Vuex持久化状态 Vuex调试工具 Vuex的高级用法 异步Actions 中间件 Vuex的…

小新学习k8s第四天之发布管理

一、金丝雀发布&#xff08;灰度发布&#xff09; Deployment控制器支持自定义控制更新过程中的滚动节奏&#xff0c;如“暂停(pause)”或“继续(resume)”更新操作。 ①比如等待第一批新的Pod资源创建完成后立即暂停更新过程&#xff0c;此时&#xff0c;仅存在一部分新版本的…

机器人领域中的scaling law:通过复现斯坦福机器人UMI——探讨数据规模化定律(含UMI的复现关键)

前言 在24年10.26/10.27两天&#xff0c;我司七月在线举办的七月大模型机器人线下营时&#xff0c;我们带着大家一步步复现UMI「关于什么是UMI&#xff0c;详见此文&#xff1a;UMI——斯坦福刷盘机器人&#xff1a;从手持夹持器到动作预测Diffusion Policy(含代码解读)」&…

项目模块1~12总结:服务器大模块梳理

一、思维导图 二、设计思路 1、各种回调函数梳理 服务器里面包含了监听套接字和监听到的通信套接字&#xff08;新连接&#xff09;&#xff0c;我们要对这两种套接字进行设置回调函数&#xff0c;其中监听套接字里面只要设置读回调&#xff0c;通信套接字要设置5种回调&…

【django】Django REST Framework 序列化与反序列化详解

目录 1、什么是序列化和反序列化&#xff1f; 2、Django REST Framework中的序列化和反序列化 3、安装与配置&#xff08;第10章是从零开始&#xff09; 3.1 安装 3.2 配置 4、基本使用 4.1 创建序列化器 4.2 使用序列化器&#xff08;将数据序列化返回给前端&#xff…

三周精通FastAPI:27 使用使用SQLModel操作SQL (关系型) 数据库

官网文档&#xff1a;https://fastapi.tiangolo.com/zh/tutorial/sql-databases/ SQL (关系型) 数据库 FastAPI不需要你使用SQL(关系型)数据库。 但是您可以使用任何您想要的关系型数据库。 这里我们将看到一个使用SQLModel的示例。 SQLModel是在SQLAlchemy和Pydantic的基础…

C++中使用seekg函数进行随机读写

seekg&#xff08;off type offset, ios::seekdir origin ); //作用:设置输入流的位置 这个函数有俩个参数&#xff0c;第一个是表示偏移量&#xff0c;第二个是表示相对位置 infile.seekg(-50, infile.end);//表示从文件结尾开始&#xff0c;向文件开头方向读50个字节 参数 …

2-137 基于matlab的sigmoid函数的变步长自适应语音信号增强

基于matlab的sigmoid函数的变步长自适应语音信号增强&#xff0c;与传统LMS相对比&#xff0c;比较不同的变步长函数去噪效果&#xff0c;并基于较好的去噪算法分析不同变步长中参数变化对降噪的影响。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-13…

有效利用关键词研究工具提升网站流量的策略

内容概要 在当前信息泛滥的时代&#xff0c;关键词研究工具的重要性愈发突出。它们不仅能帮助我们识别和分析用户搜索行为&#xff0c;还能够精准地为网站内容定位&#xff0c;确保我们能够吸引并留住目标受众。关键词研究工具通过提供大量的数据&#xff0c;帮助站长和营销策…

探索全托的自闭症学校:打造个性化成长场所

文章详情&#xff1a;http://www.zibizhengwang.com/page35.html 在广州这座充满活力的城市里&#xff0c;有一个特别的地方&#xff0c;它以独特的教育理念和深切的关怀之心&#xff0c;为自闭症儿童提供了一个温暖的避风港。这个地方就是星贝育园自闭症儿童寄宿制学校&#…