文 章 目 录

  • 一、文 件
    • 1、基 础 知 识
    • 2、C 文 件 接 口
      • (1)代 码 示 例
      • (2)当 前 路 径
      • (3)文 件 权 限
      • (4)w
      • (5)a
      • (6)三 个 输 入 输 出 流
    • 3、分 开 显 示 stdout 和 stderr
    • 4、基 础 知 识
      • (1)open
      • (2)close
      • (3)write
      • (4)标 志 位 传 递 方 式
  • 二、访 问 文 件 的 本 质
    • 1、struct file
    • 2、FILE
    • 3、close(1)
    • 4、fd
    • 5、read
    • 6、引 用 计 数 与 关 闭 文 件
  • 三、重 定 向
    • 1、文 件 描 述 符 的 分 配 规 则
      • (1)原 版 代 码
      • (2)close(0)
      • (3)close(1)
      • (4)close(2)
      • (5)总 结
    • 2、重 定 向 的 原 理
    • 3、dup2
    • 4、输 入 重 定 向
    • 5、追 加 重 定 向
    • 6、输 入 重 定 向
    • 7、printf 与 fprintf
  • 四、总 结

💻作 者 简 介:曾 与 你 一 样 迷 茫,现 以 经 验 助 你 入 门 Linux。
💡个 人 主 页:@笑口常开xpr 的 个 人 主 页
📚系 列 专 栏:Linux 探 索 之 旅:从 命 令 行 到 系 统 内 核
✨代 码 趣 语:当 0、1、2 先 占 满 文 件 描 述 符 的 “插 槽”,open 总 会 寻 着 最 小 的 空 缺 安 家 - - - 每 个 fd 的 数 字,都 是 进 程 与 文 件 牵 手 的 “门 牌 号 码”,藏 着 读 写 消 息 的 去 向。
💪代 码 千 行,始 于 坚 持,每 日 敲 码,进 阶 编 程 之 路。
📦gitee 链 接:gitee

在这里插入图片描述

         Linux 初 学 者 常 困 惑:会 用 > 重 定 向 却 不 懂 原 理,知 道 printf 输 出 却 不 明 其 与 “文 件” 的 关 联,对 0、1、2 文 件 描 述 符 更 是 茫 然。这 些 疑 问 的 核 心,正 是 “进 程 与 文 件 的 交 互 逻 辑” - - - 本 文 以 实 操 + 原 理 为 核 心,从 “文 件 = 内 容 + 属 性” 切 入,讲 清 C 库 / 系 统 调 用 用 法,拆 解 文 件 描 述 符 规 则 与 重 定 向 本 质,搭 配 代 码 截 图 帮 你 打 通 “命 令 - 代 码 - 内 核” 链 路。


一、文 件

1、基 础 知 识

  1. 文 件 = 内 容 + 属 性
  2. 文 件 分 为 打 开 的 文 件 和 没 有 打 开 的 文 件。进 程 打 开 的 文 件,没 打 开 的 文 件 存 储 在 磁 盘 上,没 有 打 开 的 文 件 非 常 多。本 质 上 是 研 究 进 程 和 文 件 的 关 系,要 快 速 的 对 文 件 进 行 增 删 查 改。
  3. 文 件 想 要 被 打 开 首 先 应 该 被 加 载 到 内 存。
  4. 进 程 :打 开 文 件 = 1:n,一 个 进 程 可 以 打 开 多 个 文 件。操 作 系 统 内 部 一 定 存 在 大 量 的 被 打 开 的 文 件。操 作 系 统 要 管 理 被 打 开 的 文 件,先 描 述,再 组 织。
  5. 在 Linux 内 核 中,一 个 被 打 开 的 文 件 都 必 须 有 自 己 的 文 件 打 开 对 象,包 含 文 件 的 很 多 属 性。

2、C 文 件 接 口

C 语 言 文 件 操 作

(1)代 码 示 例

#include<stdio.h>
#include<unistd.h>
int main()
{printf("pid:%d\n",getpid());//打开文件的路径和文件名,默认在当前路径下创建一个文件FILE* pf = fopen("test.txt","w");if(pf == NULL){perror("fopen fail");return 1;}fclose(pf);sleep(100);return 0;
}

在这里插入图片描述


(2)当 前 路 径

         当 前 路 径 指 的 是 进 程 的 当 前 路 径 cwd,如 果 更 改 了 当 前 进 程 的 cwd,就 可 以 把 文 件 新 建 到 其 他 目 录。

         可 以 使 用 ll /proc/进 程 的 PID 来 查 看 进 程 的 当 前 路 径。
在这里插入图片描述


chdir
更 改 进 程 的 工 作 目 录。
在这里插入图片描述
         在 上 面 的 代 码 中 添 加 chdir("/home/xpr/linux"); 可 以 更 改 进 程 的 路 径。
在这里插入图片描述


(3)文 件 权 限

在这里插入图片描述


(4)w

         将 字 符 写 入 文 件。如 果 没 有 文 件 则 会 创 建 文 件,如 果 文 件 有 内 容 则 会 清 空。


fwrite
将 字 符 写 入 到 文 件 中。
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{printf("pid:%d\n",getpid());//打开文件的路径和文件名,默认在当前路径下创建一个文件FILE* pf = fopen("test.txt","w");if(pf == NULL){perror("fopen fail");return 1;}const char* str = "hello linux";fwrite(str,strlen(str),1,pf);fclose(pf);return 0;
}

在这里插入图片描述


         这 里 strlen 不 需 要 加 1 原 因 是 因 为 如 果 加 1 会 出 现 乱 码,如 下 图 所 示。字 符 串 以 \0 结 尾 是 C 语 言 的 规 定,和 文 件 没 有 关 系。

strlen + 1
strlen + 1 会 在 文 件 中 出 现 ^@,这 个 字 符 就 是 \0
在这里插入图片描述


echo 及 输 入 重 定 向
         类 似 的,echo 的 输 入 重 定 向 和 w 类 似,如 果 没 有 文 件 则 会 创 建,文 件 有 内 容 则 会 清 空。
在这里插入图片描述


(5)a

         在 文 件 结 尾 追 加 字 符 串,如 果 没 有 文 件 则 会 创 建 文 件。
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{printf("pid:%d\n",getpid());//打开文件的路径和文件名,默认在当前路径下创建一个文件FILE* pf = fopen("test.txt","a");if(pf == NULL){perror("fopen fail");return 1;}const char* str = "hello linux";fwrite(str,strlen(str)+1,1,pf);fclose(pf);return 0;
}

在这里插入图片描述


echo 及 输 出 重 定 向
在这里插入图片描述


(6)三 个 输 入 输 出 流

         所 有 的 语 言 在 启 动 时 默 认 都 会 打 开 对 应 的 设 备 文 件,原 因 是 因 为 电 脑 开 机 时 就 会 打 开 显 示 器 和 键 盘,编 写 代 码 时 使 用 键 盘 输 入,用 显 示 器 显 示。C 语 言 的 3 个 输 入 输 出 流。C 程 序 默 认 在 启 动 时 会 打 开 三 个 标 准 输 入 输 出 流(文 件)。
所 有 的 语 言 对 于 文 件 的 操 作 都 包 括 文 件 描 述 符 fd

stdin:键 盘
stdout:显 示 器 文 件
stderr:显 示 器 文 件
在这里插入图片描述


3、分 开 显 示 stdout 和 stderr

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{fprintf(stdout,"hello normal message\n");fprintf(stdout,"hello normal message\n");fprintf(stdout,"hello normal message\n");fprintf(stdout,"hello normal message\n");fprintf(stderr,"hello error message\n");fprintf(stderr,"hello error message\n");fprintf(stderr,"hello error message\n");fprintf(stderr,"hello error message\n");return 0;
}

在这里插入图片描述
         重 定 向 以 后,向 1 里 面 写 入 的 内 容 都 会 写 入 normal.txt 文 件 中。只 对 1 重 定 向,没 有 对 2 重 定 向。
在这里插入图片描述
         1 可 以 省 略 不 写。stdout 和 stderr 可 以 重 定 向 到 1 个 文 件 中。
         ./mytest >err.txt 2>&1 先 表 示 把 1 号 文 件 描 述 符 的 内 容 写 入 err.txt 中,然 后 2>&1 表 示 把 2 号 文 件 描 述 符 中 的 内 容 写 入 1 号 文 件 描 述 符 中。


fprintf
         将 字 符 写 入 文 件 或 使 用 流。
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{printf("pid:%d\n",getpid());//打开文件的路径和文件名,默认在当前路径下创建一个文件FILE* pf = fopen("test.txt","a");if(pf == NULL){perror("fopen fail");return 1;}const char* str = "hello linux";fprintf(stdout,"%s,%d\n",str,1234);fclose(pf);return 0;
}

在这里插入图片描述


4、基 础 知 识

         文 件 其 实 是 在 磁 盘 上 的,磁 盘 是 外 部 设 备,访 问 文 件 其 实 是 访 问 硬 件。操 作 系 统 是 硬 件 的 管 理 者。几 乎 所 有 的 库 只 要 是 访 问 硬 件 设 备,必 定 要 封 装 系 统 调 用。


(1)open

         打 开 或 者 创 建 文 件 或 者 设 备,可 以 指 定 文 件 的 权 限,即 文 件 是 否 存 在。
在这里插入图片描述
flags
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.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);if(fd<0){printf("open fail\n");return 1;}return 0;
}

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


(2)close

关 闭 文 件

文 件 描 述 符
file descriptor:文 件 描 述 符,是 int 类 型。
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.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);if(fd<0){printf("open fail\n");return 1;}close(fd);return 0;
}

(3)write

         向 文 件 中 写 入 文 件 描 述 符,返 回 值 是 实 际 写 入 的 字 节 数。默 认 从 文 件 的 开 始 处 写,不 会 对 文 件 清 空,让 新 增 加 的 字 符 替 换 掉 旧 的 字 符。
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.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);if(fd<0){printf("open fail\n");return 1;}const char* str = "hello world";write(fd,str,strlen(str));close(fd);return 0;
}

在这里插入图片描述


(4)标 志 位 传 递 方 式

1 个 整 数 可 以 传 递 1 个 标 志 位。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define ONE (1 << 0)  //1
#define TWO (1 << 1)  //2
#define THREE (1 << 2)//4
#define FOUR (1 << 3) //8
void show(int flags)
{if(flags&ONE){printf("hello function1\n");}if(flags&TWO){printf("hello function2\n");}if(flags&THREE){printf("hello function3\n");}if(flags&FOUR){printf("hello function4\n");}
}
int main()
{    show(ONE);printf("-----------\n");show(ONE|TWO);printf("-----------\n");show(ONE|TWO|THREE);printf("-----------\n");return 0;
}

在这里插入图片描述


二、访 问 文 件 的 本 质

1、struct file

         操 作 系 统 内 描 述 一 个 被 打 开 文 件 的 信 息。

直 接 或 者 间 接 包 含 以 下 属 性:

  1. 被 打 开 的 文 件 在 哪 个 位 置
  2. 基 本 属 性、权 限、大 小、读 写 位 置、谁 打 开 的。
  3. 文 件 的 内 核 缓 冲 区 信 息
  4. struct file *next 指 针。

         对 文 件 的 操 作 改 为 对 双 向 链 表 的 增 删 查 改。

         一 个 进 程 可 以 打 开 多 个 文 件,要 建 立 进 程 PCB 和 打 开 文 件 的 关 系。
在这里插入图片描述

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


2、FILE

         C 语 言 中 的 FILE 是 C 库 中 自 己 封 装 的 结 构 体,里 面 包 含 文 件 描 述 符。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{   printf("stdin->fd:%d\n",stdin->_fileno);printf("stdout->fd:%d\n",stdout->_fileno);printf("stderr->fd:%d\n",stderr->_fileno);return 0;
}

在这里插入图片描述


3、close(1)

printf
         可 以 使 用 close(1); 关 闭 显 示 器 使 printf 无 法 显 示 在 显 示 屏 上。说 明 printf 的 底 层 使 用 了 1 号 文 件 描 述 符。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{  close(1);printf("stdin->fd:%d\n",stdin->_fileno);printf("stdout->fd:%d\n",stdout->_fileno);printf("stderr->fd:%d\n",stderr->_fileno);return 0;
}

在这里插入图片描述
fprintf

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{  close(1);int ret = printf("stdin->fd:%d\n",stdin->_fileno);printf("stdout->fd:%d\n",stdout->_fileno);printf("stderr->fd:%d\n",stderr->_fileno);fprintf(stderr,"printf ret:%d\n",ret);return 0;
}

在这里插入图片描述
         如 果 关 闭 了 1 号 文 件 描 述 符,使 用 2 号 文 件 描 述 符 也 可 以 在 显 示 器 上 输 出。


4、fd

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{    umask(0); // 文件掩码int fd1 = open("log.txt",O_WRONLY|O_CREAT,0666);int fd2 = open("log.txt",O_WRONLY|O_CREAT,0666);int fd3 = open("log.txt",O_WRONLY|O_CREAT,0666);int fd4 = open("log.txt",O_WRONLY|O_CREAT,0666);printf("fd1:%d\n",fd1);printf("fd2:%d\n",fd2);printf("fd3:%d\n",fd3);printf("fd4:%d\n",fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

在这里插入图片描述
         返 回 的 整 数 值 都 是 数 组 的 下 标 且 都 是 整 数,返 回 的 整 数 值 都 是 从 3 开 始 的。0 是 stdin(键 盘 文 件),1 是 stdout(显 示 器 文 件),2 是 stderr(显 示 器 文 件)。


验 证

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{   const char* str = "hello linux";write(1,str,strlen(str));write(2,str,strlen(str));return 0;
}

在这里插入图片描述


5、read

         从 文 件 描 述 符 中 读 取。
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{   char buf[100];ssize_t count = read(0,buf,sizeof(buf));if(count < 0){return 1;}buf[count] = '\0';printf("%s\n",buf);return 0;
}

在这里插入图片描述


6、引 用 计 数 与 关 闭 文 件

引 用 计 数
         关 闭 文 件 时,使 用 close 时,对 1 号 描 述 符 的 引 用 计 数 减 1,然 后 将 1 号 指 针 位 置 置 空 即 可,然 后 判 断 引 用 计 数 是 否 为 0,如 果 为 0,则 说 明 没 有 文 件 被 使 用,系 统 会 回 收 struct 对 象。如 果 不 为 0,则 说 明 还 有 文 件 被 使 用。


三、重 定 向

1、文 件 描 述 符 的 分 配 规 则

(1)原 版 代 码

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open fail");return 1;}printf("fd:%d\n",fd);const char* str = "hello world\n";int cnt = 5;while(cnt){write(fd,str,strlen(str));cnt--;}close(fd);return 0;
}

在这里插入图片描述
         此 时 文 件 描 述 符 为 3,log.txt 所 对 应 的 文 件 权 限 为 664。


(2)close(0)

在 代 码 最 前 面 添 加 close(0),输 出 的 文 件 描 述 符 为 0。
在这里插入图片描述


(3)close(1)

在 代 码 最 前 面 添 加 close(1)
在这里插入图片描述
         因 为 printf 的 底 层 使 用 了 stdout,stdout 的 文 件 描 述 符 为 1,这 里 将 1 关 闭,无 法 在 显 示 器 上 输 出。


(4)close(2)

在 代 码 最 前 面 添 加 close(2)
在这里插入图片描述
关 闭 2 号 文 件 描 述 符 后,输 出 的 文 件 描 述 符 为 2。

(5)总 结

         关 闭 几 号 文 件 描 述 符,文 件 描 述 符 就 输 出 几 号,说 明 文 件 描 述 符 对 应 的 分 配 规 则 是 从 0 下 标 开 始,寻 找 最 小 的 没 有 使 用 的 数 组 位 置,它 的 下 标 就 是 新 文 件 的 文 件 描 述 符。

2、重 定 向 的 原 理

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  close(1);int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open fail");return 1;}const char* str = "hello world\n";int cnt = 5;while(cnt){write(1,str,strlen(str));cnt--;}close(fd);return 0;
}

在这里插入图片描述
         关 闭 1 号 文 件 描 述 符 后,结 果 没 有 在 显 示 器 中 显 示,却 写 入 了 文 件 中。
在这里插入图片描述
         关 闭 1 号 文 件 描 述 符 后,此 时 打 开 文 件,文 件 原 来 应 该 指 向 3 号 文 件 描 述 符,现 在 被 改 成 了 1 号 文 件 描 述 符,此 时 发 生 了 输 入 重 定 向。
         重 定 向 的 本 质 是 对 数 组 下 标 的 内 容 进 行 了 修 改。如 果 想 要 发 生 重 定 向 需 要 将 原 来 文 件 描 述 符 中 的 内 容 关 闭 或 者 覆 盖 掉 即可。


3、dup2

         拷 贝 文 件 描 述 符 的 指 针 内 容,将 新 的 文 件 描 述 符 的 内 容 拷 贝 给 旧 的 文 件 描 述 符,然 后 关 闭 新 的 文 件 描 述 符。
在这里插入图片描述

4、输 入 重 定 向

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open fail");return 1;}//重定向dup2(fd,1);close(fd);const char* str = "hello world\n";int cnt = 5;while(cnt){write(1,str,strlen(str));cnt--;}close(fd);return 0;
}

在这里插入图片描述
         原 来 1 号 文 件 描 述 符 可 以 将 内 容 输 出 到 显 示 器 中,重 定 向 以 后 显 示 器 无 法 输 出 内 容,输 出 的 是 文 件 的 内 容。


5、追 加 重 定 向

将 write 中 的 O_TRUNC 改 成 O_APPEND 即 可 实 现 追 加 重 定 向。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_APPEND,0666);if(fd < 0){perror("open fail");return 1;}//重定向dup2(fd,1);close(fd);const char* str = "hello world\n";int cnt = 5;while(cnt){write(1,str,strlen(str));cnt--;}close(fd);return 0;
}

在这里插入图片描述


6、输 入 重 定 向

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{int fd = open(filename,O_RDONLY);if(fd < 0){perror("open");return 1;}dup2(fd,0);//从标准输入读取改为从文件中读取char buf[1024];ssize_t s = read(0,buf,sizeof(buf)-1);if(s>0){buf[s]='\0';printf("echo:%s\n",buf);}return 0;
}

在这里插入图片描述


cat 的 输 入 重 定 向
从 文 件 中 读 取 改 为 从 键 盘 中 读 取。
在这里插入图片描述


7、printf 与 fprintf

         printf 和 fprintf 用 的 都 是 stdin,可 以 修 改 文 件 描 述 符,改 变 输 出 的 位 置。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_APPEND,0666);if(fd < 0){perror("open fail");return 1;}//重定向dup2(fd,1);printf("fd:%d\n",fd);printf("hello printf\n");fprintf(stdout,"hello fprintf\n");close(fd);return 0;
}

在这里插入图片描述


如 何 理 解 “linux 中 一 切 皆 文 件”
         所 有 操 作 计 算 机 的 动 作 都 是 以 进 程 的 形 式 操 作 的,所 有 访 问 文 件 的 操 作 都 是 用 进 程 的 方 式 访 问 文 件 的。


在这里插入图片描述


四、总 结

         本 文 已 帮 你 掌 握 Linux 文 件 操 作 核 心:文 件 定 义、文 件 描 述 符、重 定 向 本 质,及 C 库 与 系 统 调 用 的 关 系,也 理 解 了 “一 切 皆 文 件” 的 设 计。这 些 知 识 是 后 续 进 程 通 信、网 络 编 程 的 基 础。建 议 动 手 修 改 代 码 加 深 理 解,关 注 专 栏 Linux 探 索 之 旅:从 命 令 行 到 系 统 内 核,后 续 将 解 锁 更 多 进 阶 内 容,帮 你 搭 建 系 统 编 程 知 识 体 系。

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

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

相关文章

【高分论文密码】大尺度空间模拟与不确定性分析及数字制图技术应用

大尺度模拟技术能够从不同的时空尺度揭示农业生态环境领域的内在机理和时空变化规律&#xff0c;为复杂过程模型的模拟提供技术基础。一&#xff1a;R语言空间数据及数据挖掘关键技术1、R语言空间数据讲解及应用特点 1)R语言基础与数据科学 2)R空间矢量数据 3)R栅格数据2、R语言…

Git 工作流与分支管理实战:rebase vs merge 对比、冲突解决、规范 Commit Message 与主干稳定性最佳实践

1. 版本控制与协作流程&#xff08;Git 工作流、分支管理、合并冲突&#xff09; 虽然 Git 用得多&#xff0c;但“rebase vs. merge”、如何解决冲突、如何编写规范的 commit message、如何维护主干的稳定性&#xff0c;都需要一段时间才能形成体系化的理解。 摘要 在日常团队…

调试 cuda kernel

调试 CUDA Kernel 并进入 __device__ 函数是 CUDA 开发中一项非常重要的技能。这主要依赖于 NVIDIA 的官方调试器 NVIDIA Nsight Systems (用于系统级分析) 和 NVIDIA Nsight Compute (用于内核级分析) 以及经典的 cuda-gdb (命令行调试器)。 这里将重点介绍两种最常用和强大的…

GD32自学笔记:4.ADC

while(1)里测试ADC是否正常首先&#xff0c;ADC引脚说明如下&#xff1a;ADC 通道引脚描述ADC_CHANNEL_0PA0端口 A 的引脚 0&#xff0c;可用于模拟信号输入&#xff0c;如传感器或外部电压。ADC_CHANNEL_1PA1端口 A 的引脚 1&#xff0c;常用于模拟输入&#xff0c;适用于一般…

渐变背景色和渐变字体颜色的实现方法

一、渐变背景色&#xff08;Gradient Background&#xff09;1. 线性渐变&#xff08;Linear Gradient&#xff09;通过 linear-gradient 创建从一种颜色到另一种颜色的线性渐变。代码示例<div class"linear-gradient"></div><style> .linear-grad…

Wi-Fi技术——传播与损耗

一、频段和信道 Wi-Fi通过发射无线电进行传输&#xff0c;而无线电的一个重要特性是频率。 频段&#xff1a;一个大的频率范围&#xff0c;如Wi-Fi工作在2.4GHz、5GHz、6GHz&#xff0c;其并不是一个值&#xff0c;而是一个范围信道&#xff1a;在每个频段中划分小的频率范围…

【Mysql-installer-community-8.0.26.0】Mysql 社区版(8.0.26.0) 在Window 系统的默认安装配置

ℹ️大家好&#xff0c;我是练小杰&#xff0c;好久不见了&#xff0c;周末愉快&#xff0c;今天周六了&#xff01;&#xff01;做了CSDN博客才发现&#xff0c;坚持不断发文是那么的困难&#xff0c;大家都是好样的&#xff01;&#xff01;&#x1f606; 本文是针对 Mysql 的…

【RabbitMQ】----初识 RabbitMQ

1. MQ 是什么&#xff1f; 在互联网中&#xff0c;会经常使用 MQ 来作为消息通信服务&#xff0c;我们一起来看一下什么是 MQ 吧&#xff01; 1.1 MQ 本质 【MQ】&#xff08;Message queue&#xff09;&#xff0c;消息队列&#xff0c;字面意思来看&#xff0c;本质是一个…

深度学习:归一化技术

在深度学习中&#xff0c;归一化技术是提高模型训练效率和性能的重要手段。归一化通过调整输入数据的分布&#xff0c;使得模型在训练过程中更易于收敛&#xff0c;减少过拟合的风险。本文将介绍几种常见的归一化技术&#xff0c;包括特征归一化、批归一化、层归一化和实例归一…

【Javaweb学习|实训总结|Week1】html基础,CSS(选择器、常用样式、盒子模型、弹性盒布局、CSS定位、动画),js(基本类型、运算符典例)

开学前三周先进行企业实训&#xff0c;主要学习Javaweb并实现一些小的项目&#xff0c;本篇笔记主要记录第一周实训的知识总结以及个人遇到的问题及解答&#xff0c;用于日后复习回顾和知识巩固&#xff0c;希望可以帮到同样在学Javaweb的大家 文章目录D1html基础D2块元素与行…

SQL 拓展指南:不同数据库差异对比(MySQL/Oracle/SQL Server 基础区别)

在学习 SQL 的过程中&#xff0c;你可能会发现&#xff1a;同样的 “建表语句” 在 MySQL 能运行&#xff0c;在 Oracle 却报错&#xff1b;“分页查询” 的写法在 SQL Server 和 MySQL 完全不同。这是因为 MySQL、Oracle、SQL Server 是三大主流关系型数据库&#xff0c;虽都支…

论文阅读:DMD | Improved Distribution Matching Distillation for Fast Image Synthesis

论文地址&#xff1a;https://arxiv.org/abs/2405.14867 项目官网&#xff1a;https://tianweiy.github.io/dmd2/ 代码地址&#xff1a;https://github.com/tianweiy/DMD2 发表时间&#xff1a;2024年5月24日 分布匹配蒸馏&#xff08;DMD&#xff09;生成的一步生成器能够与教…

嵌入式 Linux 启动流程详解 (以 ARM + U-Boot 为例)

嵌入式 Linux 启动流程详解 (以 ARM U-Boot 为例) 对于嵌入式开发者而言&#xff0c;深入理解系统的启动流程至关重要。这不仅有助于进行底层驱动开发和系统移植&#xff0c;还能在遇到启动失败等问题时&#xff0c;快速定位和解决。本文将详细分解基于 ARM 架构的嵌入式 Linu…

在前端开发中,html中script 的type分别有哪几种?分别什么情况用到?

以下是 HTML 中<script>标签type属性的常见取值、说明及使用场景&#xff1a;type 值说明使用场景不写&#xff08;空值&#xff09;HTML5 中默认等同于text/javascript&#xff0c;表示普通 JavaScript 脚本绝大多数传统 JavaScript 代码&#xff0c;包括内联脚本和外部…

2025职教技能大赛汽车制造与维修赛道速递-产教融合实战亮剑​

各位职教同仁&#xff0c;2025年世界职业院校技能大赛总决赛争夺赛&#xff08;汽车制造与维修赛道&#xff09;国内赛区的战报新鲜出炉&#xff01;本次大赛以“技炫青春 能创未来”为主题&#xff0c;聚焦汽车产业链高质量发展需求&#xff0c;在真实场景中比拼技能&#xff…

日志 | Spring Boot 日志配置通用规律(AI问答)

Spring Boot 日志配置通用规律。想看特定日志&#xff0c;怎么打开日志开关 文章目录一、一句话总结二、AI问答版提问词AI的响应&#x1f4ca; Spring Boot 日志配置通用规律1. 基本语法结构2. 日志级别&#xff08;从详细到简洁&#xff09;&#x1f3af; 常用日志配置分类1. …

DJANGO后端服务启动报错及解决

1.报错信息[2025-09-05 17:08:54 0800] [23438] [INFO] Worker exiting (pid: 23438) [2025-09-05 17:08:54 0800] [23440] [ERROR] Exception in worker process Traceback (most recent call last):File "/www/SOP/lib64/python3.11/site-packages/gunicorn/arbiter.py&…

Qt 中的 Q_OBJECT 宏详解 —— 从源码到底层机制的全面剖析

Qt 中的 Q_OBJECT 宏详解 —— 从源码到底层机制的全面剖析 文章目录Qt 中的 Q_OBJECT 宏详解 —— 从源码到底层机制的全面剖析摘要一、Q_OBJECT 宏是什么&#xff1f;二、Q_OBJECT 宏背后的源码三、moc 工具的作用四、信号与槽调用流程五、没有 Q_OBJECT 会怎样&#xff1f;六…

GD32自学笔记:5.定时器中断

定时器中断功能主要是两点&#xff1a;1.怎么配置的定时器中断时间间隔&#xff1b;2.中断里长什么样一、定时器中断配置函数直接在bsp_basic_timer.c里找到下面函数&#xff1a;void basic_timer_config(uint16_t pre,uint16_t per) {/* T 1/f, time T * pre,pertime (pre …

[Godot入门大全]目录

1 免责声明 资源分享免责声明&#xff1a; 本平台/本人所分享的各类资源&#xff08;包括但不限于文字、图片、音频、视频、文档等&#xff09;&#xff0c;均来源于公开网络环境中的可分享内容或已获授权的传播素材。 本平台/本人仅出于信息交流、资源共享之目的进行传播&…