八、2023.10.2.Linux(二).8

news2024/11/26 2:44:22

文章目录

  • 17、简述一下虚拟内存和物理内存,为什么要用虚拟内存,好处是什么?
  • 18、虚拟地址到物理地址怎么映射的?
  • 19、说说堆栈溢出是什么,会怎么样?
  • 20、简述操作系统中malloc的实现原理?
  • 21、说说进程空间从高位到低位都有些什么?
  • 22、32位系统能访问4GB以上的内存吗?
  • 23、请你说说并发和并行?
  • 24、说说进程、线程、协程是什么,区别是什么?
  • 25、请你说说Linux的fork的作用?
  • 26、请你说说什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程?
  • 27、请你说说什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程?
  • 28、说说进程通信的方式有哪些?
  • 29、说说进程同步的方式?
  • 30 、说说Linux进程调度算法及策略有哪些?
  • 31 、说说Linux进程调度算法及策略有哪些?
  • 32 、进程通信中的管道实现原理是什么?

17、简述一下虚拟内存和物理内存,为什么要用虚拟内存,好处是什么?

  1. 物理内存:物理内存有四个层次,分别是寄存器、高速缓存、主存、磁盘。
    寄存器:速度最快、量少、价格贵。
    高速缓存:次之。
    主存:再次之。
    磁盘:速度最慢、量多、价格便宜。
    在这里插入图片描述
    操作系统会对物理内存进行管理,有一个部分称为内存管理器(memory manager),它的主要工作是有效的管理内存,记录哪些内存是正在使用的,在进程需要时分配内存以及在进程完成时回收内存。
  2. 虚拟内存:操作系统为每一个进程分配一个独立的地址空间,但是虚拟内存。虚拟内存与物理内存存在映射关系,通过页表寻址完成虚拟地址和物理地址的转换。
  3. 为什么要用虚拟内存:因为早期的内存分配方法存在以下问题:
    (1)进程地址空间不隔离。会导致数据被随意修改。
    (2)内存使用效率低。
    (3)程序运行的地址不确定。操作系统随机为进程分配内存空间,所以程序运行的地址是不确定的。
  4. 使用虚拟内存的好处:
    (1)扩大地址空间。每个进程独占一个4G空间,虽然真实物理内存没那么多。
    (2)内存保护:防止不同进程对物理内存的争夺和践踏,可以对特定内存地址提供写保护,防止
    恶意篡改。
    (3)可以实现内存共享,方便进程通信。
    (4)可以避免内存碎片,虽然物理内存可能不连续,但映射到虚拟内存上可以连续。
  5. 使用虚拟内存的缺点:
    (1)虚拟内存需要额外构建数据结构,占用空间。
    (2)虚拟地址到物理地址的转换,增加了执行时间。
    (3)页面换入换出耗时。
    (4)一页如果只有一部分数据,浪费内存。

18、虚拟地址到物理地址怎么映射的?

操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表。页表中的每一项都记录了这个页的基地址。
三级页表转换方法:(两步)

  1. 逻辑地址转线性地址:段起始地址+段内偏移地址=线性地址
  2. 线性地址转物理地址:
    (1)每一个32位的线性地址被划分为三部分:页目录索引(DIRECTORY,10位)、页表索引 (TABLE,10位)、页内偏移(OFFSET,12位)
    (2)从cr3中取出进程的页目录地址(操作系统调用进程时,这个地址被装入寄存器中)
    页目录地址 + 页目录索引 = 页表地址
    页表地址 + 页表索引 = 页地址
    页地址 + 页内偏移 = 物理地址
    在这里插入图片描述

19、说说堆栈溢出是什么,会怎么样?

堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界。常指调用堆栈溢出,本质上一种数据结构的满溢情况。堆栈溢出可以理解为两个方面:堆溢出和栈溢出。

  1. 堆溢出:比如不断的new 一个对象,一直创建新的对象,而不进行释放,最终导致内存不足。将会报错:OutOfMemory Error。
  2. 栈溢出:一次函数调用中,栈中将被依次压入:参数,返回地址等,而方法如果递归比较深或进去死循环,就会导致栈溢出。将会报错:StackOverflow Error

20、简述操作系统中malloc的实现原理?

malloc底层实现:当开辟的空间小于 128K 时,调用 brk()函数;当开辟的空间大于 128K 时,调用mmap()。malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲快。采用隐式链表将所有空闲块,每一个空闲块记录了一个未分配的、连续的内存地址。

21、说说进程空间从高位到低位都有些什么?

在这里插入图片描述
如上图,从高地址到低地址,一个程序由命令行参数和环境变量、栈、文件映射区、堆、BSS段、数据段、代码段组成。

  1. 命令行参数和环境变量
  2. 栈区:存储局部变量、函数参数值。栈从高地址向低地址增长。是一块连续的空间。
  3. 文件映射区,位于堆和栈之间。
  4. 堆区:动态申请内存用。堆从低地址向高地址增长。
  5. BSS 段:存放程序中未初始化的全局变量和静态变量的一块内存区域。
  6. 数据段:存放程序中已初始化的全局变量和静态变量的一块内存区域。
  7. 代码段:存放程序执行代码的一块内存区域。只读,代码段的头部还会包含一些只读的常数变量。

22、32位系统能访问4GB以上的内存吗?

正常情况下是不可以的。原因是计算机使用二进制,每位数只有0或1两个状态,32位正好是2的32次方,正好是4G,所以大于4G就没办法表示了,而在32位的系统中,因其它原因还需要占用一部分空
间,所以内存只能识别3G多。要使用4G以上就只能换64位的操作系统了。但是使用PAE技术就可以实现 32位系统能访问4GB以上的内存。
Physical Address Extension(PAE)技术最初是为了弥补32位地址在PC服务器应用上的不足而推出的。我们知道,传统的IA32架构只有32位地址总线,只能让系统容纳不超过4GB的内存,这么大的内存,对于普通的桌面应用应该说是足够用了。可是,对于服务器应用来说,还是显得不足,因为服务器上可能承载了很多同时运行的应用。PAE技术将地址扩展到了36位,这样,系统就能够容纳2^36=64GB的内存。

23、请你说说并发和并行?

  1. 并发:对于单个CPU,在一个时刻只有一个进程在运行,但是线程的切换时间则减少到纳秒数量
    级,多个任务不停来回快速切换。
  2. 并行:对于多个CPU,多个进程同时运行。
  3. 区别。通俗来讲,它们虽然都说是"多个进程同时运行",但是它们的"同时"不是一个概念。并行的"同时"是同一时刻可以多个任务在运行(处于running),并发的"同时"是经过不同线程快速切换,使得看上去多个任务同时都在运行的现象。

24、说说进程、线程、协程是什么,区别是什么?

  1. 进程:程序是指令、数据及其组织形式的描述,而进程则是程序的运行实例,包括程序计数器、寄
    存器和变量的当前值。
  2. 线程:微进程,一个进程里更小粒度的执行单元。一个进程里包含多个线程并发执行任务。
  3. 协程:协程是微线程,在子程序内部执行,可在子程序内部中断,转而执行别的子程序,在适当的时候再返回来接着执行。

线程与进程的区别:
(1)一个线程从属于一个进程;一个进程可以包含多个线程。
(2)一个线程挂掉,对应的进程挂掉;一个进程挂掉,不会影响其他进程。
(3)进程是系统资源分配、管理、调度的最小单位;线程CPU调度的最小单位。
(4)进程系统开销显著大于线程开销;线程需要的系统资源更少。
(5)进程在执行时拥有独立的内存单元,多个线程共享进程的内存,如代码段、数据段、扩展
段;但每个线程拥有自己的栈段和寄存器组。
(6)进程切换时需要刷新TLB并获取新的地址空间,然后切换硬件上下文和内核栈,线程切换时只
需要切换硬件上下文和内核栈。
(7)通信方式不一样。
(8)进程适应于多核、多机分布;线程适用于多核
线程与协程的区别:
(1)协程执行效率极高。协程直接操作栈基本没有内核切换的开销,所以上下文的切换非常快,
切换开销比线程更小。
(2)协程不需要多线程的锁机制,因为多个协程从属于一个线程,不存在同时写变量冲突,效率
比线程高。
(3)一个线程可以有多个协程

25、请你说说Linux的fork的作用?

fork函数用来创建一个子进程。对于父进程,fork()函数返回新创建的子进程的PID。对于子进程,fork()函数调用成功会返回0。如果创建出错,fork()函数返回-1。

#include <unistd.h>
pid_t fork(void);

fork()函数不需要参数,返回值是一个进程标识符PID。返回值有以下三种情况:
(1) 对于父进程,fork()函数返回新创建的子进程的PID。
(2) 对于子进程,fork()函数调用成功会返回0。
(3) 如果创建出错,fork()函数返回-1。
fork()函数创建一个新进程后,会为这个新进程分配进程空间,将父进程的进程空间中的内容复制到子进程的进程空间中,包括父进程的数据段和堆栈段,并且和父进程共享代码段。这时候,子进程和父进程一模一样,都接受系统的调度。因为两个进程都停留在fork()函数中,最后fork()函数会返回两次,一次在父进程中返回,一次在子进程中返回,两次返回的值不一样,如上面的三种情况。

26、请你说说什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程?

  1. 孤儿进程:是指一个父进程退出后,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并且由init进程对它们完整状态收集工作。
  2. 僵尸进程:是指一个进程使用fork函数创建子进程,如果子进程退出,而父进程并没有调用wait()或者waitpid()系统调用取得子进程的终止状态,那么子进程的进程描述符仍然保存在系统中,占用系统资源,这种进程称为僵尸进程。
  3. 如何解决僵尸进程:
    (1)一般,为了防止产生僵尸进程,在fork子进程之后我们都要及时使用wait系统调用;同时,当子进程退出的时候,内核都会给父进程一个SIGCHLD信号,所以我们可以建立一个捕获SIGCHLD信号的信号处理函数,在函数体中调用wait(或waitpid),就可以清理退出的子进程以达到防止僵尸进程的目的
    (2)使用kill命令。

打开终端并输入下面命令:

ps aux | grep Z

会列出进程表中所有僵尸进程的详细内容。
然后输入命令

kill -s SIGCHLD pid(父进程pid)

27、请你说说什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程?

  1. 守护进程:守护进程是运行在后台的一种生存期长的特殊进程。它独立于控制终端,处理一些系统
    级别任务。
  2. 如何实现:
    (1)创建子进程,终止父进程。方法是调用fork() 产生一个子进程,然后使父进程退出。
    (2)调用setsid() 创建一个新会话。
    (3)将当前目录更改为根目录。使用fork() 创建的子进程也继承了父进程的当前工作目录。
    (4)重设文件权限掩码。文件权限掩码是指屏蔽掉文件权限中的对应位。
    (5)关闭不再需要的文件描述符。子进程从父进程继承打开的文件描述符。

28、说说进程通信的方式有哪些?

进程间通信主要包括管道、系统IPC(包括消息队列、信号量、信号、共享内存)、套接字socket。

  1. 管道:包括无名管道和命名管道,无名管道半双工,只能用于具有亲缘关系的进程直接的通信(父
    子进程或者兄弟进程),可以看作一种特殊的文件;命名管道可以允许无亲缘关系进程间的通信。
  2. 系统IPC
  • 消息队列:消息的链接表,放在内核中。消息队列独立于发送与接收进程,进程终止时,消息队列及其内容并不会被删除;消息队列可以实现消息的随机查询,可以按照消息的类型读取。
  • 信号量semaphore:是一个计数器,可以用来控制多个进程对共享-资源的访问。信号量用于实现进程间的互斥与同步。
  • 信号:用于通知接收进程某个事件的发生。
  • 内存共享:使多个进程访问同一块内存空间。
  1. 套接字socket:用于不同主机直接的通信。

29、说说进程同步的方式?

  1. 信号量semaphore:是一个计数器,可以用来控制多个进程对共享资源的访问。信号量用于实现进程间的互斥与同步。P操作(递减操作)可以用于阻塞一个进程,V操作(增加操作)可以用于解除阻塞一个进程。
  2. 管道:一个进程通过调用管程的一个过程进入管程。在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用
  3. 消息队列:消息的链接表,放在内核中。消息队列独立于发送与接收进程,进程终止时,消息队列及其内容并不会被删除;消息队列可以实现消息的随机查询,可以按照消息的类型读取。

30 、说说Linux进程调度算法及策略有哪些?

  1. 先来先服务调度算法
  2. 短作业(进程)优先调度算法
  3. 高优先级优先调度算法
  4. 时间片轮转法
  5. 多级反馈队列调度算法

31 、说说Linux进程调度算法及策略有哪些?

进程有五种状态:创建、就绪、执行、阻塞、终止。一个进程创建后,被放入队列处于就绪状态,等待操作系统调度执行,执行过程中可能切换到阻塞状态(并发),任务完成后,进程销毁终止。

  1. 创建状态
    一个应用程序从系统上启动,首先就是进入创建状态,需要获取系统资源创建进程管理块(PCB:Process Control Block)完成资源分配。
  2. 就绪状态
    在创建状态完成之后,进程已经准备好,处于就绪状态,但是还未获得处理器资源,无法运行。
  3. 运行状态
    获取处理器资源,被系统调度,当具有时间片开始进入运行状态。如果进程的时间片用完了就进入就绪状态。
  4. 阻塞状态
    在运行状态期间,如果进行了阻塞的操作,如耗时的I/O操作,此时进程暂时无法操作就进入到了阻塞状态,在这些操作完成后就进入就绪状态。等待再次获取处理器资源,被系统调度,当具有时间片就进入运行状态。
  5. 终止状态
    进程结束或者被系统终止,进入终止状态

在这里插入图片描述

32 、进程通信中的管道实现原理是什么?

操作系统在内核中开辟一块缓冲区(称为管道)用于通信。管道是一种两个进程间进行单向通信的机制。因为这种单向性,管道又称为半双工管道,所以其使用是有一定的局限性的。半双工是指数据只能
由一个进程流向另一个进程(一个管道负责读,一个管道负责写);如果是全双工通信,需要建立两个管道。管道分为无名管道和命名管道,无名管道只能用于具有亲缘关系的进程直接的通信(父子进程或者兄弟进程),可以看作一种特殊的文件,管道本质是一种文件;命名管道可以允许无亲缘关系进程间的通信。

#include <unistd.h>
int pipe(int fd[2]);

pipe()函数创建的管道处于一个进程中间,因此一个进程在由 pipe()创建管道后,一般再使用fork() 建立一个子进程,然后通过管道实现父子进程间的通信。管道两端可分别用描述字fd[0]以及fd[1]来描述。注意管道的两端的任务是固定的,即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。如果试图从管道写端读取数据,或者向管道读端写入数据都将发生错误。一般文件的 I/O 函数都可以用于管道,如close()、read()、write()等。

具体步骤如下:

  1. 父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。
  2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里写,子进程可以从管道里读,管道是
    用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INPUT 0
#define OUTPUT 1
int main(){
//创建管道
int fd[2];
pipe(fd);
//创建子进程
pid_t pid = fork();
if (pid < 0){
printf("fork error!\n");
exit(-1);
}
else if (pid == 0){//执行子进程
printf("Child process is starting...\n");
//子进程向父进程写数据,关闭管道的读端
close(fd[INPUT]);
write(fd[OUTPUT], "hello douya!", strlen("hello douya!"));
exit(0);
}
else{//执行父进程
printf ("Parent process is starting......\n");
//父进程从管道读取子进程写的数据 ,关闭管道的写端
close(fd[OUTPUT]);
char buf[255];
int output = read(fd[INPUT], buf, sizeof(buf));
printf("%d bytes of data from child process: %s\n", output, buf);
}
return 0;
}

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

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

相关文章

uboot启动流程-涉及board_init_f 函数

一. uboot启动流程 _main 函数中会调用 board_init_f 函数&#xff0c;本文简单分析一下 board_init_f 函数。 二. board_init_f 函数 board_init_f 函数主要有两个工作&#xff1a; (1) 初始化一系列外设&#xff0c;比如串口、定时器&#xff0c;或者打印一些消息等。…

Docker Tutorial

什么是Docker 为每个应用提供完全隔离的运行环境 Dockerfile&#xff0c; Image&#xff0c;Container Image&#xff1a; 相当于虚拟机的快照&#xff08;snapshot&#xff09;里面包含了我们需要部署的应用程序以及替它所关联的所有库。通过image&#xff0c;我们可以创建很…

音乐创作软件:ToneLIB Jam v4.7.8 Crack

从强大的选项卡编辑器到 3D 模式 Tonelib Jam 是一款用于播放和创作音乐的综合软件应用程序。TL Jam专为初学者和经验丰富的吉他手而设计&#xff0c;可以提供一个完美的平台来掌握乐器&#xff0c;让您轻松学习自己喜欢的歌曲或设置高效的日常吉他练习程序。TL Jam 具有功能强…

目标检测|边框检测框转换,交并比计算 代码实现

文章目录 1. 相互转换的函数2.交并比实现 在目标检测任务中&#xff0c;非常重要的一部分就是框出检测框 这就需要检测框的位置大小等一些信息 一般我们有如下两种方式标记一个检测的位置和大小 1 两点法 检测框左上角坐标(x1,y1)&#xff0c;检测框右下角坐标&#xff08;x2…

2023年最新云存储工具排行榜:找到适合你的云存储服务

随着数据规模的不断增长&#xff0c;传统的本地存储已经无法满足用户的需求。云存储工具通过提供灵活、安全和高效的数据存储服务&#xff0c;成为了现代化的数据管理方式。在众多云存储工具中&#xff0c;有一些在功能和性能方面表现出色&#xff0c;成为用户首选。下面是2023…

时间序列-AR模型与MA模型的原理与实现

文章目录 1 自回归模型AR Model1.1 自回归模型 vs 多元线性回归模型1.1.1 线性回归1.1.2 AR(1)模型1.1.3 AR(p)模型 1.2 AR建模问题 2 移动平均模型 MA Model2.1 MA模型的数学表示2.1.1 MA(1)模型2.2.2 MA(q)模型 2.2 MA建模问题 ARIMA模型是AR模型&#xff08;自回归模型&…

计算机网络(二):物理层

参考引用 计算机网络微课堂-湖科大教书匠计算机网络&#xff08;第7版&#xff09;-谢希仁 1. 物理层的基本概念 物理层考虑的是怎样才能在连接各种计算机的传输媒体上传输数据比特流物理层为数据链路层屏蔽了各种传输媒体的差异&#xff0c;使数据链路层只需要考虑如何完成本…

levelDB引擎

一、背景 1.1、影响磁盘性能的因素&#xff1a; 主要受限于磁盘的寻道时间&#xff0c;优化磁盘数据访问的方法是尽量减少磁盘的IO次数。磁盘数据访问效率取决于磁盘IO次数&#xff0c;而磁盘IO次数又取决于数据在磁盘上的组织方式。磁盘数据存储大多采用B树类型数据结构&…

排序篇(三)----交换排序

排序篇(三)----交换排序 1.冒泡排序 基本思想: ​ 通过不断地比较相邻的元素&#xff0c;将较大的元素往后移动&#xff0c;从而实现排序的目的。 具体的步骤如下&#xff1a; 从待排序的数组中选择相邻的两个元素进行比较&#xff0c;如果前一个元素大于后一个元素&#…

Java编程技巧:swagger2、knif4j集成SpringBoot或者SpringCloud项目

目录 1、springbootswagger2knif4j2、springbootswagger3knif4j3、springcloudswagger2knif4j 1、springbootswagger2knif4j 2、springbootswagger3knif4j 3、springcloudswagger2knif4j 注意点&#xff1a; Api注解&#xff1a;Controller类上的Api注解需要添加tags属性&a…

在云服务器上打开ftp服务-踩坑及心得

我们产生这个需求的原因是因为打算搭建一个博客&#xff0c;选择了使用wordpress框架。然后&#xff0c;在安装插件的过程中&#xff0c;需要使用FTP服务进行操作。于是&#xff0c;我们决定搞清楚这个过程&#xff0c;并在其中遇到的困难进行记录。 一、安装vsftpd # 安装 s…

python生成中金所期权行权价

参考沪深300股指期权的合约表&#xff0c;写一个工具函数&#xff1a; 使用方法 def get_format_option_gap(value: float, deviation: int 0): # 根据中证1000指数获取点位"""根据标准的行权价&#xff0c;生成不同档位的期权列表&#xff0c;适合中金所:…

铁道货车通用技术条件

声明 本文是学习GB-T 5600-2018 铁道货车通用技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 90 mm90 mm。 B.2 制造要求 B.2.1 车体钢结构组成后&#xff1a; a) 敞车钢质侧、端板的平面度公差应小于或等于15 mm/m; 压型侧、端板的平面度…

S0003-Mac下iTerm2+zsh+ohmyzsh打造优雅美观终端

背景 优雅耐看的终端工具&#xff0c;必是每个程序员的追求。 本人也不例外&#xff0c;从业几年先后使用过&#xff1a; windows电脑&#xff1a;cmd、git bash、wsl zsh、terminal zshMac电脑: 自带terminal、iTerm2、terminal zsh 其中windows terminal zsh、mac ter…

数据结构——二叉树的基本概念及顺序存储(堆)

目录 一.前言 二.树概念及结构 2.1 树的概念 2.2 树的相关概念 2.3 树的表现 2.4 树在实际中的应用&#xff08;表示文件系统的目录树结构&#xff09; 三.二叉树的概念及结构 3.1 概念 3.2 特殊的二叉树 3.3 二叉树的性质 3.4 二叉树的存储结构 3.4.1 顺序存储 3…

Vitamin K

各位 比对 机制 --Mechanism of Action of Vitamin K Carboxylase (VKC).IV. Intermediates and Transition State-davis2007.pdf --Mechanism of Action of Vitamin K Carboxylase (VKC).IV. Intermediates and Transition State-davis2007.pdf -- 维生素K的作用机制-dow…

房子再小,也要有自己的装修设计!福州中宅装饰,福州装修

小空间 也要有好设计 小户型的房子现在越来越受欢迎了 但是面积不大的小户型 怎么装修才能更适合居住呢&#xff1f; 那么多的东西又应该如何收纳呢&#xff1f; 白色系装修 采用白色系为装修的主色调 白色在装修上能让视觉上显得更宽敞 让小面积的房子 变得更多简洁大…

91、Redis - 事务 与 订阅-发布 相关的命令 及 演示

★ 事务相关的命令 Redis事务保证事务内的多条命令会按顺序作为整体执行&#xff0c;其他客户端发出的请求绝不可能被插入到事务处理的中间&#xff0c; 这样可以保证事务内所有命令作为一个隔离操作被执行。 Redis事务同样具有原子性&#xff0c;事务内所有命令要么全部被执…

最新AI智能创作系统源码V2.6.2/AI绘画系统/支持GPT联网提问/支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…

【C语言】IO流(文件操作)- scanf / printf没那么简单!

本篇文章目录 1. 为什么使用文件&#xff1f;2. 什么是文件&#xff1f;3. IO流的概念4. 操作文件的步骤文件指针4.1 打开文件和关闭文件4.2 读写文件&#xff08;顺序读取&#xff09;4.2.1 字符输入输出4.2.2 字符串&#xff08;文本行&#xff09;输入输出4.2.3 格式化输入输…