【Linux篇】基础IO - 文件描述符的引入
📌 个人主页: 孙同学_
🔧 文章专栏:Liunx
💡 关注我,分享经验,助你少走弯路!
文章目录
- 一. 理解文件
- 1.1 侠义理解
- 1.2 广义理解
- 1.3 文件操作的归类认知
- 1.4 系统角度
- 二. 回顾C语言文件接口
- 2.1 打开文件
- 2.2 对文件进行写入
- 2.3 输出信息到显示器,有哪些方法
- 2.4 stdin & stdout & stderr
- 2.5 打开文件的方式
- 三. 系统文件I/O
- 3.1 位图传递标志位
- 3.2 open
- 3.3 write
- 3.4 read
- 四. 访问文件的本质
- 4.1 文件描述符
一. 理解文件
我们以前就说过 文件 = 文件内容 + 文件属性
1.1 侠义理解
- 文件是在磁盘上的,磁盘本质上是个外设,我们访问文件其实就是在系统和磁盘上进行IO
- 磁盘是永久性的存储介质,文件在磁盘上的存储是永久性的
- 对文件的所有操作,本质上是对外设的输入输出 简称 IO
1.2 广义理解
Linux
下一切皆文件(键盘,显示器,网卡,磁盘… )
1.3 文件操作的归类认知
- 对于0KB的空文件,是占据磁盘的空间的
- 文件 = 文件内容 + 文件属性
- 所有对文件的操作本质上是对文件内容和文件属性的操作
1.4 系统角度
- 对文件的操作本质上是进程对文件的操作
- 磁盘的管理者是操作系统
- 文件的读或写本质上不是通过
C语言/C++
的库函数来操作的(这些库函数只是为用户提供方便),而是通过文件相关的系统调用接口实现的
文件
- “内存级(被打开)”文件
- 磁盘级文件
二. 回顾C语言文件接口
2.1 打开文件
// 文件打开接口
FILE *fopen(const char *path, const char *mode);
path
:表示要打开文件的路径,或者文件名,只有文件名而没有路径表示打开当前路径下的文件。mode
:表示打开的方式,比如只读r
,只写w
,追加a
等。
📌 Tips: 我们之前介绍的重定向,>
本质上就对应使用的是w
选项,>>
本质上就对应使用的是a
选项。
2.2 对文件进行写入
#include<stdio.h>int main()
{FILE* fp = fopen("myfile.txt","w");if (fp == NULL){perror("fopen");return 1;}while (1);fclose(fp);return 0;
}
打开的myfile
文件在哪个路径下呢?
- 在程序的当前路径下
- 那系统怎么知道程序的当前路径在哪里呢?
可以使用ls /proc/[进程id] -l
命令查看当前正在运行进程的信息:
cwd
:进程当前的工作路径exe
:指向启动当前进程的可执行文件(完整路径)的符号链接。
2.3 输出信息到显示器,有哪些方法
printf()
fprintf()
fwrite()
当我们向显示器打印本质上就是向显示器文件写入,Linux
下一切皆文件
2.4 stdin & stdout & stderr
- c语言会默认打开三个输入输出流,分别是
stdin
,stdout
,stderr
- 这三个流的类型都是
FILE*
为什么要帮我们把这几个流自动打开呢?
我们传统上写的程序是做数据处理的
2.5 打开文件的方式
- 以
w
的方式打开文件时,文件首先会被清空,然后从0开始写
- 我们以前说过的重定向,比如
echo aaaaa > log.txt
,把打印到显示器上的内容写入文件里,前提是我们先得把文件打开。我们的输出重定向>log.txt
为什么会把文件内容清空呢?因为我们输出重定向第一步要打开文件,而打开文件,而打开文件第一步先要把文件清空
- 以
a
的方式打开文件,这种方式叫做追加,它一般写的时候会向文件结尾进行写入,不存在的话就创建它。>>
叫做追加重定向,以a
的方式进行写入本质上也是先要把文件打开,然后再进行写入。
- 当我们向文件里写入一段字符串时,我们需不需要在字符串后面加
\0
呢?答案是不需要,因为\0
是c语言的规定,与我文件又有什么关系呢。
三. 系统文件I/O
我们对文件操作的是时候,文件是在磁盘上面的,而真正对文件进行操作的其实是操作系统,操作系统对磁盘文件进行读写访问,我们以前使用c语言对文件的访问其实是c语言封装了系统调用。比如说访问文件得先打开,那么就得先有open
flags
有众多选项O_RDONLY
表示只读, O_WRONLY
表示只写, O_RDWR
表示读写,O_TRUNC
表示
int open(const char *pathname,int flags,mode_t mode);
如果我们今天要打开一个文件,并且这个文件不存在要新建的话,就用上面的这个open
,必须指定权限,如果不指定的话这个权限就是乱码。如果打开一个已经存在的文件,就用两个参数的。
open
的返回值:如果打开成功的话返回一个新的文件描述符,如果失败的话-1
被返回,并且错误码就被设置了。
flags
是一种整形标志位,一共有32个bit
位,,如果用O_RDONLY
这种选项直接传参的话会很麻烦,所以选用位图的方式来传递。
3.1 位图传递标志位
#include<stdio.h>#define ONE_FLAG (1<<0)// 000000....00000001
#define TWO_FLAG (1<<1)// 000000....00000010
#define THREE_FLAG (1<<2)// 000000....00000100
#define FOUR_FLAG (1<<3)// 000000....00001000void Print(int flags)
{if(flags & ONE_FLAG){printf("One!\n");}if(flags & TWO_FLAG){printf("Two!\n");}if(flags & THREE_FLAG){printf("Three!\n");}if(flags & FOUR_FLAG){printf("Four!\n");}}int main()
{Print(ONE_FLAG); //打印oneprintf("\n");Print(ONE_FLAG | TWO_FLAG); //打印one twoprintf("\n");Print(ONE_FLAG | TWO_FLAG | THREE_FLAG);//打印one two threeprintf("\n");Print(ONE_FLAG | TWO_FLAG | THREE_FLAG | FOUR_FLAG);//打印one two three fourprintf("\n");return 0;
}
3.2 open
我们open
打开文件的时候绝对相对路径都可以,因为在哪个路径下创建文件是由进程决定的,进程记录了自己的cwd
,说明我们新建文件是在指定路径下建还是在其他路径下建和cd
,fopen
都没有关系,它是系统的行为。
我们接下来验证一下log.txt
它默认会在当前路径下去创建,因为它进程的路径就在当前路径下。
我们对文件进行写入write
接口
#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);
- 第一个参数: 是
open
的返回值,这个返回值叫文件描述符 - 第二个参数: 是我们要写入的
buffer
- 第三个参数: 是我们要写的数据的长度,返回值是实际写入的长度。写入失败返回
-1
。
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{umask(0);//在新建文件之前将umask权限眼掩码设置为0int fd = open("log.txt",O_CREAT | O_WRONLY,0666);//不存在就创建,而且以写入的方式打开if(fd < 0){perror("open");return 1;//进程的退出码设为1}printf("fd = %d/n",fd);const char *msg = "hello world\n";//定义一个字符串int cnt = 5;while(cnt){write(fd,msg,strlen(msg));//向指定文件描述符里写,写的内容是msg,写的长度//我们在写入时是当做字符来写,所以这里不需要strlen(msg)+1,因为\0是c语言规定的,如果写\0的话在我们的文件中就会出现@^乱码现象cnt--;}close(fd);//关闭文件return 0;
}
当我们把要写的内容该为abcd
并且只让它写一行。
现象是在我们往文件里写的时候应当是先清空再进行写入,而现在是覆盖写,文件内原来的内容并没有清空,为什么没有清空呢?答案是我们再创建文件的时候,只填了创建和写入,而并没有要清空。
所以我们加上O_TRUNC
💦结论:如果我们要打开文件,并且将它清空,若要用系统级的函数,我们就需要传递这几个标志位。
清空并写入:
int fd = open("log.txt",O_CREAT | O_WRONLY | O_TRUNC,0666);
如果O_CREAT
(不存在就新建),O_WRONLY
(以只写入的方式),O_TRUNC
(清空)
追加并写入:
int fd = open("log.txt",O_CREAT | O_WRONLY | O_APPEND,0666);
所以C语言中的fopen
中的w
选项和a
选项就会被分别转化为上面的那样。
3.3 write
write
这个接口在写的时候参数不是char*
,而是void*
ssize_t write(int fd, const void *buf, size_t count);
说明write
在进行写入的时候,进行二进制写入也可以,做字符串写入也可以。
文本写入 vs 二进制写入
我们在往显示器上打印12345
的时候是往显示器打印的是1
字符2
字符3
字符4
字符和5
字符。而不是一万两千三百四十五。
📌小tips: 我们往显示器上打印和我们往文件里写入其实是一摸一样的,因为Linux
下一切皆文件。
我们往文件里以清空写的方式写入1234567
查看log.txt
我们会发现log.txt
是4
个字节里面的内容是乱码,这是为什么呢?因为这种写入叫做二进制写入,在实际写的时候把a
这个整形变量写到了文件里面,所以文件的大小是4
字节,因为整数的大小是4
字节,而我们写入的1234567
不可显,它是把1234567
这个二进制数字写在了磁盘上。而我们想看到的是1234567
,那可怎么办呢?
将a
这个整形格式化处理成字符串,然后将字符串写入到要写的文件中。
此时的log.txt
中就是1234567
了。
💦结论: 在系统层面上并不存在所谓的文本写入和二进制写入,系统并不关心你写入的类型,文本写入还是二进制写入其实是语言层 提供的概念。所以我们在c语言中有fpus
文本写入fwrie
二进制写入,这两个底层最终调用的都是这个接口。
ssize_t write(int fd, const void *buf, size_t count);
格式化输入输出其实就是将内存里的二进制数据转成字符串,在使用write
接口将数据写进去。所以格式化输入输出,文本式的写入全都是语言层的概念。这个格式化工作要么是语言来做,要么是我们自己来做。
3.4 read
#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);
- 返回值:如果成功,则返回读的字节数(0表示文件结束),如果错误返回
-1
- 第一个参数:是
open
的返回值,这个返回值叫文件描述符 - 第二个参数: 指向一段空间,该空间用来存储读取到的内容。
我们读取log.txt
中的内容
四. 访问文件的本质
我们一次性打开四个文件,并观察它的fd
打出来的文件描述符是3
,4
,5
,6
问题是0
,1
,2
去哪里了呢?
0
:标准输入1
:标准输出2
:标准错误
这三个叫做默认的文件流,因为它默认的把三个文件打开了,012
已经被占了。
C语言
中有三个标准输入,标准输出,标准错误的文件流
C++
中也有标准输入(cin)
,标准输出cout
,标准错误cerr
的文件流
C语言
中我们打开文件叫做FILE*
,*
是指针,可是FILE
是什么呢?FILE
是C语言
提供的一个结构体,它是被typedef
出来的,结构体里包含了文件的属性。
在OS
接口层面上只认fd
文件描述符,所以这个结构体里一定封装了文件描述符。
所以我们以前学到的文件操作,在类型层面的文件对象FILE
封装了文件描述符,在接口层面打开文件是封装了对应的选项。
所以任何语言,底层只认文件描述符,C语言
/C++
会把市面上的各种平台的代码各自实现一份,然后采用条件编译,代码裁剪的方式,把不同的系统需要的库编到不同的系统里,给用户提供的是同一个语言型接口,这样写出来的代码具有可移植性。
要了解可移植性就需要知道不可移植性,不可移植性是由于平台不一样,平台不一样系统调用的接口不一样。
4.1 文件描述符
操作系统要把被打开的文件管理起来,怎么管理呢?先描述,再组织
创建一个进程的时候,首先在内核当中创建的了一个task_struct
,我们称之为进程控制块。操作系统在打开文件时需要在内核当中创建一个数据结构struct file
,打开很多文件就会创建很多的struct file
,然后用指针连接起来。那么找一个文件的所有内容或者任何一个属性就都能通过struct file
找到。也就是说未来想访问文件就只需要找到对应的struct file
结构体队对象就可以了。
在文件中,每一个文件的struct file
都会提供一个文件级缓冲区,将来文件的内容就会加载到文件缓冲区当中,文件的属性会用来初始化我们的struct file
以及将来的inode
结构体。今天我们如果是想读取文件里面的内容,一定先是我们把文件打开,创建struct file
结构体,通过file
内部的指针操作找到文件缓冲区,然后操作系统把文件的内容给我们加载或者预加载到缓冲区里面,加载之后我们读写文件的本质就是从缓冲区里面把内容拷贝出去。
可是在进程中怎么快速找到我们自己打开的文件呢?被连起来的文件有可能属于进程a
,也有可能属于进程b
,哪个文件是和你的进程相关的呢?在我们的进程的PCB
当中,当一个进程被创建,除了地址空间页表,它还要创建一个struct files_struct
文件描述符表,文件描述符表中包含一个数组,这个数组是可大可小的,一般的Linux
系统是32
或者64
,在云服务器上它可以支持内核扩展,这个struct files_struct
中还包含了其他属性,包括打开文件的个数,其他的一些属性信息。这个数组叫做struct file *fd array[]
,这是一个指针数组,在PCB
中会存在一个struct files_struct *files
指向文件描述符表。这个数组中放的就是这个进程打开的文件,把操作系统打开的struct file
对象填充到我们数组对应的指定下标当中。此时那些进程有哪些文件就被关联起来了,建立被打开的文件和进程之间的映射关系。所以进程要访问任意一个被打开的文件就可以通过下标来访问了。
所以文件描述符的本质就是数组下标
当我们的用户层在进行open
调用的时候,就会在操作系统里创建一个新的struct file
,然后在当前进程的文件描述符表里面找到一个没有被使用的下标,然后把struct file
的地址填进去,此时进程和文件就关联了。下来读取数据(read)时要传fd
,当前进程调用read
,进程拿着fd
去文件描述符中的数组中找,就能找到对应的文件,每一个文件都有对应的文件缓冲区,操作系统把磁盘中的内容预加载到缓冲区当中,然后把文件缓冲区当中的数据拷贝到用户层的buffer
中。
文件描述符的分配原则:最小的没有被使用的作为新的fd
分配给用户。
👍 如果对你有帮助,欢迎:
- 点赞 ⭐️
- 收藏 📌
- 关注 🔔
相关文章:
【Linux篇】基础IO - 文件描述符的引入
📌 个人主页: 孙同学_ 🔧 文章专栏:Liunx 💡 关注我,分享经验,助你少走弯路! 文章目录 一. 理解文件1.1 侠义理解1.2 广义理解1.3 文件操作的归类认知1.4 系统角度 二. 回顾C语言文件…...
13.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Refit
在微服务架构中,不同服务之间经常需要相互调用以完成复杂业务流程,而 Refit 能让这种“跨服务调用”变得简洁又可靠。开发者只需将对外暴露的 REST 接口抽象成 C# 接口,并通过共享库或内部 NuGet 包在各服务中引用,这种契约优先的…...
C++ 并发性能优化实战:提升多线程应用的效率与稳定性
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,获得2024年博客之星荣誉证书,高级开发工程师,数学专业,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开发技术,…...
前端性能优化的全方位方案【待进一步结合项目】
以下是前端性能优化的全方位方案,结合代码配置和最佳实践,涵盖从代码编写到部署的全流程优化: 一、代码层面优化 1. HTML结构优化 <!-- 语义化标签减少嵌套 --> <header><nav>...</nav> </header> <main&…...
(undone) 并行计算 CS149 Lecture3 (现代多核处理器2 + ISPC编程抽象)
url: https://www.bilibili.com/video/BV1du17YfE5G?spm_id_from333.788.videopod.sections&vd_source7a1a0bc74158c6993c7355c5490fc600&p3 如上堂课,超线程技术通过储存不同线程的 execution context,能够在一个线程等待 IO 的时候低成本切换…...
DiffAD:自动驾驶的统一扩散建模方法
25年3月来自新加坡公司 Carion 和北航的论文“DiffAD: A Unified Diffusion Modeling Approach for Autonomous Driving”。 端到端自动驾驶 (E2E-AD) 已迅速成为实现完全自动驾驶的一种有前途的方法。然而,现有的 E2E-AD 系统通常采用传统的多任务框架,…...
QScrollArea 内部滚动条 QSS 样式失效问题及解决方案
在使用 Qt 进行 UI 开发时,我们经常希望通过 QSS(Qt Style Sheets)自定义控件的外观,比如为 QScrollArea 的内部滚动条设置特定的样式。然而,有开发者遇到了这样的问题:在 UI 设计器中预览 QSS 显示效果正常,但程序运行时却显示为系统默认样式。经过反复测试和调试,最终…...
换脸视频FaceFusion3.1.0-附整合包
2025版最强换脸软件FaceFusion来了(附整合包)超变态的AI换脸教程 2025版最强换脸软件FaceFusion来了(附整合包)超变态的AI换脸教程 整合包地址: 「Facefusion_V3.1.0」 链接:https://pan.quark.cn/s/f71601…...
Qt 入门 1 之第一个程序 Hello World
Qt 入门1之第一个程序 Hello World 直接上操作步骤从头开始认识,打开Qt Creator,创建一个新项目,并依次执行以下操作 在Qt Creator中,一个Kits 表示一个完整的构建环境,包括编译器、Qt版本、调试器等。在上图中可以直…...
无锁队列简介与实现示例
1. 简介 无锁队列是一种数据结构,旨在在多线程环境中实现高效的并发访问,而无需使用传统的锁机制(如互斥锁)。无锁队列通过使用原子操作(如CAS,Compare-And-Swap)来确保线程安全,从…...
SpringMVC与SpringCloud的区别
SpringMVC与SpringCloud的核心区别 功能定位 • SpringMVC: 基于Spring框架的Web层开发模块,采用MVC(Model-View-Controller)模式,专注于处理HTTP请求、路由分发(如DispatcherServlet)和视图…...
STM32F103C8T6单片机开发:简单说说单片机的外部GPIO中断(标准库)
目录 前言 如何使用STM32F1系列的标准库完成外部中断的抽象 初始化我们的GPIO为输入的一个模式 初识GPIO复用,开启GPIO的复用功能时钟 GPIO_EXTILineConfig和EXTI_Init配置外部中断参数 插入一个小知识——如何正确的配置结构体? 初始化中断&#…...
Python urllib3 全面指南:从基础到实战应用
欢迎来到涛涛的频道,今天用到了urllib3,和大家分享下。 1、介绍 urllib3 urllib3 是 Python 中一个功能强大且用户友好的 HTTP 客户端库,它提供了许多标准库 urllib 所不具备的高级特性。作为 Python 生态中最受欢迎的 HTTP 库之一…...
25.5 GLM-4优化RAG实战:0.1%参数实现准确率飙升30%,成本直降90%!
使用 GLM-4 优化 RAG 程序:基于标注数据的 Adapter 训练实战 关键词:GLM-4 优化, RAG 增强, 数据标注, Adapter 训练, 检索增强生成 1. RAG 系统的核心挑战与优化方向 传统 RAG(Retrieval-Augmented Generation)系统常面临以下瓶颈: graph LR A[用户提问] --> B[检…...
OrangePi入门教程(待更新)
快速上手指南 https://www.hiascend.com/developer/techArticles/20240301-1?envFlag1 教学课程(含开发板配置和推理应用开发) https://www.hiascend.com/developer/devboard 开发推理应用 https://www.hiascend.com/developer/techArticles/20240326-1?envFlag1...
基于SpringBoot+Vue实现的二手交易市场平台功能一
一、前言介绍: 1.1 项目摘要 随着社会的发展和人们生活水平的提高,消费者购买能力的提升导致产生了大量的闲置物品,这些闲置物品具有一定的经济价值。特别是在高校环境中,学生群体作为一个具有一定消费水平的群体,每…...
TC3xx芯片的UCB介绍
文章目录 前言一、UCB的定义及其功能简介二、UCB_BMHDx_ORIG and UCB_BMHDx_COPY (x 0 - 3)2.1 BMHD(Boot Mode Head) 三、UCB_SSW四、UCB_PFLASH_ORIG and UCB_PFLASH_COPY4.1 Password4.2 UCB Confirmation 前言 缩写全称UCBUser Configuration BlockBMHDBoot Mode Headers…...
Airflow量化入门系列:第四章 A股数据处理与存储优化
Airflow量化入门系列:第四章 A股数据处理与存储优化 本教程系统性地讲解了 Apache Airflow 在 A 股量化交易中的应用,覆盖从基础安装到高级功能的完整知识体系。通过八章内容,读者将掌握 Airflow 的核心概念、任务调度、数据处理、技术指标计…...
《海空重力测量理论方法及应用》之一重力仪系统组成及工作原理(下)
2、三轴稳定平台型 稳定平台的作用是隔离测量载体角运动对重力观测量的影响,确保重力传感器的敏感轴方向始终与重向保持一致。 当前主流的海空重力仪使用的稳定平台方案主要有4种: ①双轴阻尼陀螺平台: ②)双轴惯导加捷联方位平台: ③三轴惯导平台; ④捷联惯导…...
C++模板递归结构详解和使用
示例代码 template<typename _SourceIterator, typename _DestT> struct convert_pointer {typedef typename convert_pointer<typename _SourceIterator::pointer, _DestT>::type type; };1. 模板参数 _SourceIterator 是输入的类型,通常表示迭代器类…...
(八)PMSM驱动控制学习---无感控制之滑膜观测器
在FOC矢量控制中,我们需要实时得到转子的转速和位置 ,但在考虑到成本和使用场合的情况下,往往使用无感控制,因为无位置传感器克服了传统机械式传感器的很多缺点和不足。比如,机械式传感器对环境要求比较严格࿰…...
蓝桥杯真题-分糖果-题解
链接:https://www.lanqiao.cn/problems/4124/learning/ 题目 复述:两种糖果,分别有9和16,分给7人,每个人得到的最少2,最多5,必需全部分完,几种分法? 复习-深度优先搜索 …...
推荐系统(二十二):基于MaskNet和WideDeep的商品推荐CTR模型实现
在上一篇文章《推荐系统(二十一):基于MaskNet的商品推荐CTR模型实现》中,笔者基于 MaskNet 构建了一个简单的模型。笔者所经历的工业级实践证明,将 MaskNet 和 Wide&Deep 结合应用,可以取得不错的效果&…...
辅助查询是根据查询到的文档片段再去生成新的查询问题
💡 辅助查询是怎么来的? 它是基于你当前查询(query)检索到的某个文档片段(chunk_result),再去“反推”出新的相关问题(utility queries),这些问题的作用是&a…...
Spring Cloud 框架为什么能处理高并发
Spring Cloud框架能够有效处理高并发场景,核心在于其微服务架构设计及多组件的协同作用,具体机制如下: 一、分布式架构设计支撑高扩展性 服务拆分与集群部署 Spring Cloud通过微服务拆分将单体系统解耦为独立子服务,每个服务可独…...
Pseduo LiDAR(CVPR2019)
文章目录 AbstractIntroductionRelated WorkLiDAR-based 3D object detectionStereo- and monocular-based depth estimationImage-based 3D object detection MethodDepth estimationPseudo-LiDAR generationLiDAR vs. pseudo-LiDAR3D object detectionData representation ma…...
强化学习课程:stanford_cs234 学习笔记(3)introduction to RL
文章目录 前言7 markov 实践7.1 markov 过程再叙7.2 markov 奖励过程 MRP(markov reward process)7.3 markov 价值函数与贝尔曼方程7.4 markov 决策过程MDP(markov decision process)的 状态价值函数7.4.1 状态价值函数7.4.2 状态…...
前端精度计算:Decimal.js 基本用法与详解
一、Decimal.js 简介 decimal.js 是一个用于任意精度算术运算的 JavaScript 库,它可以完美解决浮点数计算中的精度丢失问题。 官方API文档:Decimal.js 特性: 任意精度计算:支持大数、小数的高精度运算。 链式调用:…...
来聊聊C++中的vector
一.vector简介 vector是什么 C 中的 vector 是一种序列容器,它允许你在运行时动态地插入和删除元素。 vector 是基于数组的数据结构,但它可以自动管理内存,这意味着你不需要手动分配和释放内存。 与 C 数组相比,vector 具有更多的…...
对比学习中的NCE(Noise-Contrastive Estimation)和InfoNCE(SimCLR)损失函数+案例(附SimSiam分析)
在对比学习(Contrastive Learning)中,NCE(Noise-Contrastive Estimation)和InfoNCE是两种常见的目标函数,它们都用于通过区分正样本和负样本来学习高质量的表示。 1. NCE(Noise-Contrastive Est…...
基于FAN网络的图像识别系统设计与实现
基于FAN网络的图像识别系统设计与实现 一、系统概述 本系统旨在利用FAN(Fourier Analysis Networks)网络架构实现高效的图像识别功能,并通过Python语言设计一个直观的用户界面,方便用户操作与使用。FAN网络在处理周期性特征方面具有独特优势,有望提升图像识别在复杂场景…...
【瑞萨 RA-Eco-RA2E1-48PIN-V1.0 开发板测评】PWM
【瑞萨 RA-Eco-RA2E1-48PIN-V1.0 开发板测评】PWM 本文介绍了瑞萨 RA2E1 开发板使用内置时钟和定时器实现 PWM 输出以及呼吸灯的项目设计。 项目介绍 介绍了 PWM 和 RA2E1 的 PWM 资源。 PWM 脉冲宽度调制(Pulse Width Modulation, PWM)是一种对模拟…...
NDK开发:开发环境
NDK开发环境 一、NDK简介 1.1 什么是NDK NDK(Native Development Kit)是Android提供的一套工具集,允许开发者在Android应用中使用C/C++代码。它包含了: 交叉编译器构建工具调试器系统头文件和库示例代码和文档1.2 NDK的优势 性能优化:直接使用底层代码,提高性能代码保…...
设计模式简述(三)工厂模式
工厂模式 描述简单工厂(静态工厂)工厂方法模式 抽象工厂增加工厂管理类使用 描述 工厂模式用以封装复杂的实例初始化过程,供外部统一调用 简单工厂(静态工厂) 如果对象创建逻辑简单且一致,可以使用简单工…...
通过Postman和OAuth 2.0连接Dynamics 365 Online的详细步骤
🌟 引言 在企业应用开发中,Dynamics 365 Online作为微软的核心CRM平台,提供了强大的Web API接口。本文将教你如何通过Postman和OAuth 2.0认证实现与Dynamics 365的安全连接,轻松调用数据接口。 📝 准备工作 工具安装…...
LlamaIndex实现RAG增强:上下文增强检索/重排序
面向文档检索的上下文增强技术 文章目录 面向文档检索的上下文增强技术概述技术背景核心组件方法详解文档预处理向量存储创建上下文增强检索检索对比技术优势结论导入库和环境变量读取文档创建向量存储和检索器数据摄取管道使用句子分割器的摄取管道使用句子窗口的摄取管道查询…...
AI比人脑更强,因为被植入思维模型【43】蝴蝶效应思维模型
giszz的理解:蝴蝶效应我们都熟知,就是说一个微小的变化,能带动整个系统甚至系统的空间和时间的远端,产生巨大的链式反应。我学习后的启迪,简单的说,就是不要忽视任何微小的问题,更多时候&#x…...
程序化广告行业(62/89):DSP系统的媒体与PDB投放设置探秘
程序化广告行业(62/89):DSP系统的媒体与PDB投放设置探秘 大家好!在之前的学习中,我们对程序化广告的DSP系统有了一定了解。今天还是带着和大家共同进步的想法,深入探索DSP系统中媒体设置以及PDB投放设置的…...
Java项目之基于ssm的怀旧唱片售卖系统(源码+文档)
项目简介 怀旧唱片售卖系统实现了以下功能: 用户信息管理: 用户信息新增:添加新用户的信息。 用户信息修改:对现有用户信息进行修改。 商品信息管理: 商品信息添加:增加新的商品(唱片&#x…...
程序化广告行业(61/89):DSP系统活动设置深度剖析
程序化广告行业(61/89):DSP系统活动设置深度剖析 大家好!在程序化广告的学习道路上,我们已经探索了不少重要内容。今天依旧本着和大家一起学习进步的想法,深入解析DSP系统中活动设置的相关知识。这部分内容…...
Altshuller矛盾矩阵查询:基于python和streamlit
基于python和streamlit实现的Altshuller矛盾矩阵查询 import streamlit as st import json# 加载数据 st.cache_resource def load_data():with open(parameter.json, encodingutf-8) as f:parameters json.load(f)with open(way.json, encodingutf-8) as f:contradictions …...
FreeRTOS的空闲任务
在 FreeRTOS 中,空闲任务(Idle Task) 是操作系统自动创建的一个特殊任务,其作用和管理方式如下: 1. 空闲任务创建 FreeRTOS 内核自动创建:当调用 vTaskStartScheduler() 启动调度器时,内核会自…...
【代码模板】如何用FILE操作符打开文件?fopen、fclose
#include "stdio.h" #include "unistd.h"int main(int argc, char *argv[]) {FILE *fp fopen("1.log", "wb");if (!fp) {perror("Failed open 1.log");return -1;}fclose(fp); }关于权限部分参考兄弟篇【代码模板】C语言中…...
[特殊字符] Pandas 常用操作对比:Python 运算符 vs Pandas 函数
在 Pandas 中,许多操作可以直接使用 Python 的比较运算符(如 、!、>、< 等),而不需要调用 Pandas 的专门函数(如 eq()、ne()、gt() 等)。这些运算符在 Pandas 中已经被重载,代码更简洁。以…...
I.MX6ULL开发板与linux互传文件的方法--NFS,SCP,mount
1、内存卡或者U盘 方法比较简单,首先在linux系统中找到u盘对应的文件夹,随后使用cp指令将文件拷贝进u盘。 随后将u盘插入开发板中,找到u盘对应的设备文件。一般u盘对应的设备文件在/dev下,以sda开头,可以使用命令列出所…...
图解AUTOSAR_SWS_FlashEEPROMEmulation
AUTOSAR Flash EEPROM Emulation (FEE) 详解 基于AUTOSAR规范的Flash EEPROM Emulation模块分析 目录 1. 概述2. 架构设计 2.1 模块位置与接口2.2 内部状态管理2.3 配置结构3. API接口 3.1 接口功能分类3.2 错误管理4. 操作流程 4.1 写入操作序列5. 总结1. 概述 Flash EEPROM …...
Unity:Simple Follow Camera(简单相机跟随)
为什么需要Simple Follow Camera? 在游戏开发中,相机(Camera)是玩家的“眼睛”。它的作用是决定玩家看到游戏世界的哪一部分。很多游戏需要相机自动跟随玩家角色,让玩家始终可以看到角色及其周围的环境,而…...
[项目总结] 在线OJ刷题系统项目总结与分析(二): 技术应用(上)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
针对Ansible执行脚本时报错“可执行文件格式错误”,以下是详细的解决步骤和示例
针对Ansible执行脚本时报错“可执行文件格式错误”,以下是详细的解决步骤和示例: 目录 一、错误原因分析二、解决方案1. 检查并添加可执行权限2. 修复Shebang行3. 转换文件格式(Windows → Unix)4. 检查脚本内容兼容性5. 显式指定…...
从 Dense LLM 到 MoE LLM:以 DeepSeek MoE 为例讲解 MoE 的基本原理
写在前面 大多数 LLM 均采用 Dense(密集) 架构。这意味着,在处理每一个输入 Token 时,模型所有的参数都会被激活和计算。想象一下,为了回答一个简单的问题,你需要阅读整部大英百科全书的每一个字——这显然效率低下。 为了突破 Dense 模型的瓶颈,一种名为 Mixture of …...