【Linux学习】基础IO——系统调用 | 文件描述符fd | 重定向
🐱作者:一只大喵咪1201
🐱专栏:《Linux学习》
🔥格言:你只管努力,剩下的交给时间!
基础IO
- 🍎文件操作
- 🍉使用C接口进行文件操作
- 🍉文件操作的系统调用
- 🍎文件描述符fd
- 🍉文件描述符fd=0/1/2
- 🍉文件描述符fd的分配规则
- 🍎重定向
- 🍉重定向系统调用
- 🍉进程独立性
- 🍎Linux下一切皆文件
- 🍎总结
在正式开始介绍之前,本喵先重新谈论一下文件:
- 空文件也是要在内存中占据空间的,因为它还有属性数据。
- 文件 = 属性 + 内容
- 文件操作 = 对内容 + 对属性 或者对内容和属性的操作。
- 标定一个文件的时候,必须使用:路径 + 文件名,因为文件具有唯一性。
- 如果没有指名文件路径,默认是对当前路径的文件进行访问。
- 一个文件,在没有被打开的时候,是不能进行访问的。
- 二进制可执行文件,在没有运行的时候,所谓的文件操作都是没有执行的。
- 磁盘上的文件分为被打开的文件和没有被打开的文件。
结论:文件操作的本质,是进程和被打开文件之间的关系。
上面对文件的认识,是我们所有使用Linux用户的共识。
🍎文件操作
🍉使用C接口进行文件操作
在将我们的程序编译完成以后,再运行,发现生成了一个新的文件,并且文件中的内容和我们代码中写的一样。
- 这个过程中,使用的是C语言的接口进行文件操作。
- 以写的方式打开文件名问log.txt的文件,没有的这个文件的话就会创建。
- 使用C接口向该文件中写入内容。
本喵曾在文章C语言文件操作一文中详细介绍过C语言的文件操作接口,有兴趣的小伙伴可以去看看。
不同的编程语言都有文件操作的接口,包括C++,Java,Python,php等等语言,并且它们的操作接口函数都不一样,但是它们所在的系统都是Linux系统。
无论上层语言如何变化,但是进行文件操作的时候,各种语言最终都会调用Linux的文件操作的系统调用接口。
🍉文件操作的系统调用
open函数:
可以看到,函数声明有两个,一个是两个参数的,一个是三个参数的,它们必然不是函数重载,因为Linux是用纯C实现的。
参数解释:
- const char* pathname:这是文件路径,也就是我们要打开的文件所在的路径,其中包括文件名,如果没有路径只有文件名的话,默认在当前路径打开。
- int flags:打开方式选项标志位。在使用C语言进行文件操作的时候,打开方式有“w”,“r”,“a”等方式,系统调用open也有,只是将这些标志放在了一个32位的变量中。
不同打开方式,其对应的比特位就会被置1。然后将这个设置好的flags变量传给open系统调用,就会按照相应的方式打开文件。- mode_t mode:它是权限值,如果这个文件不存在,那么以写的方式打开的时候就会创建这个文件,在创建文件的时候需要给这个文件设定权限(使用八进制数)。如果这个文件存在的话,那么就不用传第三个参数了,因为文件的权限已经确定了。
- 返回值:是一个int类型的参数,具体的在后面本喵会介绍,但是如果打开失败就会返回-1。
如果有多个选项需要按位或在一起,共同组成int flags变量传给open系统调用。
常用选项 | 功能 |
---|---|
O_RDONLY | 只读 |
O_WRONLY | 只写 |
O_RDWR | 读写 |
O_CREAT | 以写方式打开时,如果文件不存在则创建文件 |
O_TRUNC | 以写方式打开时,清空文件中原内容再写 |
O_APPEND | 追加方式打开文件 |
此时我们没有给open传第三个参数。
执行我们写的代码后,log.txt文件是创建了,但是它是红色的,说明它有错误。可以看到它前面的权限是乱的,因为我们没有指定创建文件时的权限。
将第三个参数加上,因为创建的是普通文件,所以就给它的默认权限是0666。
可以看到,此时创建的文件就正常了,但是权限并不是我们设定的0666,而是0664,这是因为有默认权限掩码(umask)的影响。
我们也可以使用系统调用在程序中改变umask的值。
将默认权限掩码改成0以后,再创建的文件的权限就是我们设置的0666了。本喵曾在文章【Linux学习】权限详细讲解过权限相关的内容,有兴趣的小伙伴可以去看看。
close函数:
将打开文件时返回的int类型的fd值传给close系统调用后,这个被打开的文件就被关闭了。关闭成功返回0,如果关闭失败就返回-1。
write函数:
参数解释:
- int fd:打开文件时返回的int类型整数(文件描述符)。
- const void* buf:要写入的数组地址。对于系统调用来说,它并不在意写入的数据是什么类型的,它接收到的数据都是二进制的数字,然后按照字节为单位写入。
- size_t count:要写入的字节个数。
- 返回类型size_t:写入多个自己就返回多少。
清空方式写入:
可以看到,成功将字符串写入到了log.txt文件中。
追加方式写入:
使用追加方式打开文件,再多次使用系统调用write写入。
可以看到在原有的基础上,多了5行。
read函数:
参数解释:
- int fd:打开文件时返回的文件描述符。
- void* buf:从文件中读取的数据放在这个数组中,同样系统不管文件中的数据类型是什么,都是按字节放入这个数组中。
- size_t count:要读取的字节个数。
- ssize_t:读取了多少个返回多少。
此时log.txt中有五行内容,如上图绿色框中所示。
使用只读方式打开,并且将读取的内容放在ch数组中。
编译执行之后,成功打印出了log.txt中的内容。
- 接收文件中数据的数组我们设定的大小是1024个字节,显然文件中的数据时没有这么大的。
- read系统调用的第三个参数传的也是1024,但是肯定没有读取到1024个字节。
- 每一个文件中都有一个文件结束符标志,在C语言中我们见过,也就是EOF,read函数会自动判断文件是否结束,所以即使设置读取的字节是1024个,但是能够符合我们对读取要求,将文件中的内容都读取出来。
以上便是我们常用的文件操作的系统调用。可以看到,对文件进行什么样的操作,取决于以什么样的方式打开文件,再用相应的操作函数去操作文件。
继续和C语言对应:
C语言的文件操作函数,封装了对应的系统调用接口函数。所以说,无论什么语言,文件操作相关的函数都是对系统调用的封装。
🍎文件描述符fd
在使用系统调用open时,返回的那个整数就是文件描述符。
将文件名使用宏的方式打开多个文件。
现在我们见到了文件描述符,发现它就是几个数字。
- 前面本喵已经讲过,文件操作的本质就是进程和被打开文件的关系。
- 系统中会存在大量被打开的文件,而操作系统同样会管理这些被打开的文件。
- 管理的方式和管理进程类似,也是采用先描述,再组织的方式。
当一个文件被打开后,操作系统会创建一个对应的结构体对象,类型是struct file。
struct file
{//文件大小//文件类型......//文件的各种属性
}
- 每打开一个文件,操作系统就会创建这样的一个结构体对象将被打开的文件描述出来。
- 将多个这样的结构体对象采用一定的方式组织起来,比如链表的方式,以方便操作系统管理这些被打开的文件。
在描述进程的结构体task_struct中,有一个指针,struct files_struct* files,这个指针指向一个结构体对象,该对象类型如下:
struct files_struct
{//......struct file* array[];
}
- struct files_struct结构体中存在一个指针数组array,该数组中的指针指向的是一个个struct file类型的结构体对象。
- 换言之,该数组中放的是被打开文件结构体对象的地址。
- 每一个被指向的struct file结构体对象都描述着一个被打开的文件。
在前面我们看到,打印出来的fd值是连续的小整数,这些小整数就是struct files_struct 结构体中指针数组struct file* array[]的下标。
文件描述符的本质,就是数组的下标。
下面本喵通过一张示意图来展示一下:
- 当一个程序被加载到内存中,操作系统会创建一个结构体struct task_struct对象,在该结构体中有一个指针struct files_struct* files,指向一个struct files_struct结构体对象。
- 这个结构体也被叫做进程描述符表,该结构体中有一个数组struct file* array[],数组中存放的是被打开文件的结构体对象的地址。如上图中,下标为3,也就是fd的是3的时候,访问到的是struct file* array[3]。
- 通过数组中访问到的地址,可以找到对应打开文件的结构体对象,如上图中的struct file log.txt。
只有被打开的文件才会在内存中创建struct file结构体对象,没有被打开的文件就静静的躺在磁盘上。
不是该进程打开的文件,该进程执行的文件描述符表中也没有这个文件的地址。
🍉文件描述符fd=0/1/2
在上面打开多个文件的时候,我们将打开文件的fd值打印出来,发现它是从3开始的。
那么fd = 0/1/2是什么呢?
C默认会打开三个输入输出流,分别是stdin,stdout,stderr。
可以看到,这三个流是FILE*类型的指针,暂时不用管FILE是什么,只需要知道它是一个结构体。
使用C语言的文件操作结构打开一个文件,再使用系统调用去向文件中写内容。
成功的写入了。
- 系统调用write第一个参数需要传文件描述符fd。
- 上面代码中,传入的是FILE->_fileno,并且成功运行。
- 说明FILE中的_fileno就是文件描述符fd。
我们此时已经确定的知道了,FILE结构体中是有文件描述符的。
在之前的代码中,加上打印三个流的文件描述符的语句,如上图中红色框所示。
文件描述符0 1 2出现了。
- fd = 0:标准输入流(stdin)
- fd = 1:标准输出流(stdout)
- fd = 2:标准错误(stderr)
此时我们便清楚了为什么我们打开的文件,文件描述符是从3开始的,因为012被默认打开的三个流占据了。
每个进程的文件描述符表如上图所示。
🍉文件描述符fd的分配规则
为什么我们打开的文件,fd是从3开始的?不是从5或者6开始的呢?
我们将fd=0的标准输入流关闭掉,再打开文件,并且打印fd值。
我们发现此时的fd成了0,而不是3了。
同样的,将fd=2的流关闭,在打开文件。
此时fd的值又成了2了。
根据这个现象,可以得出结论:文件描述符fd的分别规则是:从小到大,按顺序查找,将没有被占用的数组下标作为被打开文件的文件描述符fd值。
🍎重定向
前面我们只关闭过0和2,没有关闭过1,现在我们关闭一下1来看看。
将标准输出关闭,然后打开文件,并且打印出打开文件的文件描述符fd。
此时运行该程序后,什么都没有显示。
- 因为将标准输出关闭了,所以无法显示。
根据前面分析的文件描述符分配规则,可以推断出,将标准输出关闭以后,再打开一个文件,此时这个文件的文件描述符fd等于1。
- 在将fd=1关闭后,再打开一个文件,从小到大按顺序查找,发现数组下标为1的位置没有被占用,所以新打开文件的fd就等于1。
- printf函数原本是要输出到标准输出的,也就是fd为1的数组中指向的struct file对象的地址。
- 此时下标为1的数组中不再是标准输出了,而变成了我们新打开文件的地址。
- 但是printf已经写死了,它仍然会写入到fd为1的文件中,所以原本打印在显示器上的内容此时会写入到新打开的文件中。
查看新打开的文件内容,发现是原本应该打印在屏幕上的内容。
同样的,将1关闭以后,以追加的方式打开一个文件,并且写入多行内容。
同样没有打印到屏幕上,而是打印到了新打开的文件中。
这种将本应该输出到标准输出改为输出到其他文件中的行为称为重定向。
重定向的本质上:上层语言使用的fd不变,在内核中改变fd对应的struct file*地址。
🍉重定向系统调用
上面重定向的实现总感觉怪怪的,还需要关闭,然后再打开新文件,而且也不是很方便,所以操作系统提供了一个系统调用,可以直接实现重定向。
我们常用的函数是dup2。
参数解释:
- 第一个参数是我们新打开文件的fd。
- 第二个参数是标准输出到fd,也就是1。
原本应该输出到显示器上的内容输出到了文件log.txt中。
我们上面一直演示的都是本应该输出到显示器重定向输出到了文件中,这种从显示器到文件的重定向叫做输出重定向。
在shell中有命令可以直接实现输出重定向:
ll命令原本是将文件包括属性显示到屏幕上的,使用大于号>输出重定向到了log.txt文件中,如上图绿色框中所示。
- 使用只读方式打开文件log.txt该文件原本就存在。
文件中内容是如上图中红色框。- 将原本struct file* array[]数组中下标0的内容改成下标为fd的内容,也就是dup2(fd,0)的作用。
- 使用标准输入函数fgets,从标准输入流也就是键盘中读取字符串。
- 屏幕上打印读取到的内容。
运行时直接输出log.txt中的内容,没有从键盘获取数据。也就是说,fgets函数是从文件中获取到内容,而不是标准输入。
这种从标准输入到文件的重定向叫做输入重定向。
shell中同样有输入重定向的命令:是小于号<,具体本喵就不显示了。
使用追加方式打开文件,并且采用输出重定向方式输出内容。
在原本文件内容都基础上追加内容。
这种以追加方式打开文件,并且采用输出重定向的方式称为追加重定向。
shell中同样有追加重定向:
使用双大于号>>,实现了追加重定向,在原本log.txt内容都基础上追加内容。
🍉进程独立性
子进程重定向了以后,会影响父进程吗?根据进程独立性我们可以知道,肯定是不会影响到。
在子进程中进行输出重定向,父进程同样在标准输出打印。
子进程中的重定向,并没有影响父进程标准输出的打印。
- 有两个进程,一个父进程,一个子进程,操作系统维护着两个task_struct结构体,如上图红色框所示。
- 每个进程的PCB中都有一个struct files_struct*的指针files。它们各自指向的struct files_struct结构体中都有一个文件描述符表。
- 两个文件描述符表中的内容在子进程刚创建时是一样的,所以它们都指向相同的被打开的文件。
- 当子进程将自己文件描述符表中下标为1的文件关闭以后,并不影响父进程文件描述符表中下标为1的数组中的内容。
每个进程都会维护自己的文件描述符表,所以多个进程就会存在多个文件描述符表,但是这些表中的指针指向的被打开文件只有一套。
某个进程进行文件的打开与关闭操作时,只需要修改自己的文件描述符表就可以,不会对其他进程造成任何影响。
🍎Linux下一切皆文件
Linux下一切皆文件,这句话相信每一个学习Linux的人都听过,那么如何理解呢?
同样以文件操作的角度来看待硬件,如下图所示:
- 每一个硬件,操作系统都会维护一个struct file类型的结构体,硬件的各种信息都在这个结构体中,并且还有对应读写函数指针(对硬件的操作主要就是读写)。
- 每个硬件的具体读写函数的实现方式都在驱动层中,使用到相应的硬件时,操作系统会通过维护的结构体中的函数指针调用相应的读写函数。
- 站在操作系统的角度来看下层,无论驱动层和硬件层中有什么,在它看来都是struct file结构体,都是通过维护这个结构体来控制各种硬件。
- 站在操作系统的角度来看上层,无论用户层以及系统调用有什么,在它看来都是一个个进程,都是一个个的task_struct结构体,都是通过维护这个结构体来调度各个进程的。
真正的文件在操作系统中的体现也是结构体,操作系统维护的同样是被打开文件的结构体而不是文件本身。
一切皆文件是指:在操作系统中一切都是结构体。
🍎总结
这篇文章主要讲解的是基础IO的应用,包括文件操作的系统调用,文件描述符fd的本质,重定向,以及如何理解Linux下一切皆文件。
相关文章:
【Linux学习】基础IO——系统调用 | 文件描述符fd | 重定向
🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言:你只管努力,剩下的交给时间! 基础IO🍎文件操作🍉使用C接口进行文件操作🍉文件操作的系统调…...
PLC实验—西门子S7 1200读取超声波传感器数据
PLC实验—西门子S7 1200读取超声波传感器数据 US-016超声波测距模块 实验箱上是US-016超声波测距模块,其有关信息可以看实验室的博客 US-016超声波测距模块 1号Pin:接VCC电源(直流5V) 2号Pin:量程设置引脚ÿ…...
一次Linux系统密码修改失败事件
一、事件描述 某业务系统采用移动云主机,某次因误操作导致移动云内嵌密码管理相关Pga进程导致页面无法修改密码,东移动云主机web终端登录也无法修改,密码错误次数最大已无法登录,无奈只能重启主机,修改密码;…...
C语言循环控制语句Break,goto,continue语句讲解
循环控制语句改变你代码的执行顺序。通过它你可以实现代码的跳转。 C 语言中 break 语句有以下两种用法: 当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。 它可用于终止 switch 语句中的一个 …...
Zabbix“专家坐诊”第183期问答汇总
问题一 Q:老师,请问一下zabbix采集的数据怎么过滤,获取数据是nottime20:30 notafter3,怎么过滤出netafter3 ?谢谢。 A:过滤器设置如下图。 问题二 Q:大佬,请问一下被管节点部署了…...
以太网协议和DNS
目录 🐕今日良言:跨过困难,去迎接更好的自己. 🐳一、以太网桢格式 🐳二、DNS 🐕今日良言:跨过困难,去迎接更好的自己. 🐳一、以太网桢格式 数据链路层考虑的是相邻两个节点(通过网线/光纤/无线直接相连的两个设备…...
【设计模式】原型模式与建造者模式
原型模式 原型模式是指通过原型实例指定创建对象的种类,然后通过拷贝的方式创建新的对象。属于创建型模式 原型模式的核心在于拷贝原型对象,主要用于对对象的复制。当你需要通过一大段get/set方法去构建对象的时候,就可以考虑使用原型模式了…...
QT之Http请求
今天我们介绍一下QT的http请求,这里有post和get两种方式 一、post请求方式:参数分为网址和具体请求值两个部分,有时候还需要设置头信息,看具体情况定 1 void MainWindow::sendPostRequest()2 {3 QNetworkAccessManager *m_pH…...
何谓dB , dB怎么理解?
dB 是什么单位 ?愈低愈好吗?对于声频 ( 声学及电子声学 ) 方面的单位,它是以分贝(decibel ,dB ) 来做结果的。斯多里一生专注于科学,1876 发明电话,我们都知道贝尔发明了电话,然而重要的是,他发现我们人类耳朵对声音…...
【数据聚类|深度聚类】Unsupervised Deep Embedding for Clustering Analysis(DEC)论文研读
DEC算法由两部分组成 第一部分会预训练一个SDAE模型;第二部分选取SDAE模型中的Encoder部分,加入聚类层,然后最小化KL散度进行训练聚类Absratct 提出了一种利用深度神经网络同时进行表征学习和聚类分配的方法,称之为深度嵌入聚类。该方法学习从数据空间到低纬空间的映射,并…...
Nuxt.js项目开发过程遇到的问题以及对Nuxt.js的学习与总结
文章目录📋前言💻Nuxtjs3快速了解🎯nuxtjs是什么?官网是这样介绍它的。🎯关于nuxtjs的SSR开发🧩SSR应用场景🧩nuxtjs的特性💻nuxtjs的初始目录结构🎯关于各个目录的解释&…...
JavaSE:异常机制
异常概念异常发生的原因用户输入非法数据要打开的文件不存在网络中断/JVM内存溢出(JVM是JRE的一部分。它是一个虚构出来的计算机)除0、非法参数等三种类型的异常,用以理解异常检查性异常【otherException】:程序员无法预见的&…...
Go mockito 使用说明 (github/mockey)
GitHub - bytedance/mockey: a simple and easy-to-use golang mock library Go mockito 是什么? mockey是一个简单易用的golang mock库,可以快速方便的mock函数和变量。目前广泛应用于字节跳动服务的单元测试编写。底层是monkey patch,通过在运行时重…...
Spring Boot+Vue前后端分离项目练习01之网盘项目的搭建
1.前期设计 一般看来,网盘系统主要实体包括:用户、存储信息、用户文件、文件、回收文件等基本功能点。 各实体对应的表结构如下所示: 表名:user(用户表) 字段名属性说明userIdbigint主键usernamevarcha…...
超详细MySQL(免安装版)安装与配置
一、MySQL下载 首先打开MySQL官网,官网首页地址为 MySQL官网首页地址 进入官网后如下图所示,点击DOWNLOADS进入下载页面 下滑页面找到MySQL Community(GPL)Downloads>>并点击 接下来点击MySQL Community Server 若想要安…...
STM32F1,F4,L1系列禁止JTAG和SW引脚方法
STM32F1系列 程序中在使用到JTAG、SWD的某个IO 时,需要禁用掉相关调试方法后,再配置相应的IO方式。在需要相应的接口配置前使用这些代码。 对于F1系列,调用函数进行专门的禁止。 标准库配置方式: RCC_APB2PeriphClockCmd(RCC_A…...
NVIDIA CUDA初级教程视频学习笔记1
周斌老师 课程链接: 目录第一课内容生态环境第一课 CPU体系架构的概述什么是CPU指令存储器架构CPU内部的并行性第一课 预修课程: Cuda c programming guide 参考内容 1,2,3查找一下。 内容 CPU体系架构概述 并行程序设计概述 CUDA开发环境…...
CEC2005:星雀优化算法(Nutcracker optimizer algorithm,NOA)求解CEC2005(提供MATLAB代码)
一、星雀优化算法NOA 星雀优化算法(Nutcracker optimizer algorithm,NOA)由Mohamed Abdel-Basset等人于2023年提出,该算法模拟星雀的两种行为,即:在夏秋季节收集并储存食物,在春冬季节搜索食物的存储位置。 星鸦单独或成对活动&…...
工作实战之密码防重放攻击
目录 前言 一、登录认证密码加密 二、bcrypt加密密码不一样,匹配原理 1.程序运行现象 2.原理解释 三、密码防重放 总结 前言 密码重放攻击:请求被攻击者获取,并重新发送给认证服务器,从而达到认证通过的目的 一、登录认证密…...
如何编写测试用例?
编写测试用例流程 1、确定测试目标:首先,需要明确测试目标,即测试人员需要测试什么,这有助于测试人员了解需要测试哪些方面,以及如何测试。 2、识别测试场景:在确定测试目标后,测试人员需要识…...
5.排序算法之二:选择排序
选择排序(select sort)在无序列表中,把无序列表分成有序区(刚开始有序区元素个数为0)和无序区(刚开始无序区元素个数为n),循环n-1趟,每一趟找到最小或最大的那个元素&…...
Ubuntu18系统安装:node及node版本管理工具nvm部署前端项目
注意在安装之前先安装好Git 如何在Ubuntu 上安装Git与入门教程_ubuntu安装git_飞鹰雪菲的博客-CSDN博客 1、把nvm远程镜像克隆到指定目录 git clone https://gitee.com/mirrors/nvm 1.1在终端指定的文件夹下 drciZwz91oq31508figapkas0Z:~/qiang/tools$ git clone https://…...
统计学 假设检验
文章目录假设检验假设检验的基本原理提出假设作出决策表述决策结果一个总体参数的检验总体均值的检验总体比例的检验总体方差的检验两个总体参数的检验两个总体均值之差的检验两个总体比例之差的检验两个总体方差比的检验总体分布的检验正态性检验的图示法Shapiro-Wilk 和 K-S …...
【C++】哈希
哈希一、unordered系列关联式容器二、哈希原理2.1 哈希映射2.2 哈希冲突2.2.1 闭散列—开放地址法2.2.2 代码实现2.2.3 开散列—拉链法2.2.4 代码实现三、哈希封装unordered_map/unordered_set3.1 基本框架3.2 迭代器实现3.2.3 operator*和operator->和operator!3.2.4 opera…...
「TCG 规范解读」PC 平台相关规范(3)
可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alli…...
这篇教你搞定Android内存优化分析总结
一、内存优化概念1.1 为什么要做内存优化?内存优化一直是一个很重要但却缺乏关注的点,内存作为程序运行最重要的资源之一,需要运行过程中做到合理的资源分配与回收,不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&…...
概率论与数理统计期末小题狂练 11-12两套,12-13-1
11-12第一学期A1 略。2 X服从正态分布N(0,1),X^2服从卡方分布。又考查了卡方分布均值和方差公式。一开始如果对本题无从下手,大概是没看出来是什么分布。3 第二小空本身也可以作为一个结论。4 考查切比雪夫不等式&…...
golang对字符串的处理操作 如何正确理解 rune byte和string
fmt.Printf相关参数介绍 先来看代码的演示 package mainimport ("fmt""unicode/utf8" )func main() {s:"我爱中国人haha!"fmt.Println(len(s))//20个字节 一个中文三个字节 1541fmt.Print("\n echo byte \n")for k,v: range []byte(…...
软件项目管理简答题复习(1)
1.项目:创造唯一的产品,唯一的服务临时性的努力 2.项目特征:不可见性,复杂性,一致性,变更性,特殊性 3.项目和日常活动的区别? 项目具有特殊性,负责人是项目经理&#…...
云Windows Server 2022 Datacenter 安装MySQL8解压缩版 mysql-8.0.32-winx64 230301记录
MySQL Community Downloads MySQL社区版压缩包下载地址 https://dev.mysql.com/downloads/mysql/ 解压到了C盘 没打算设置环境变量 右键点击开始 或 winx 以管理员身份打开 PowerShell 进入到安装目录下的 bin 目录 可以输入cd 后, 拖动 bin 文件夹到控制台&…...
自己建网站做推广/seo百度排名优化
原文自工程师Enmanuel Durn博客,传送门 最近(或者不是最近,这完全取决于您什么时候阅读这边文章),我正在跟我的团队伙伴讨论如何去处理这种需要根据不同的值去处理不同的情况的方法,通常对于这种情况下&…...
邯郸市做网站建设/提交网站收录入口
对于少量元素,它是一个有效的算法 我们将一个数组一切两半,分为有序组和待插入组,从待插入组逐次拿出元素,与放入有序组的合适位置,就这样,每插入一个元素,有序组元素增加,待插入组元素减少&am…...
有哪些做司考真题的网站/今日国内新闻10则
基本介绍 开发者可以使用云开发快速开发小程序、小游戏、公众号网页等,并且原生打通微信开放能力。 发布小程序需要使用云开发。 开发者无需搭建服务器,可免鉴权直接使用平台提供的 API 进行业务开发。 配有云端数据库,与传统数据库相比操…...
什么网站做国外批发/360站长平台
转载自 IntegerCache的妙用和陷阱 考虑下面的小程序,你认为会输出为什么结果? public class Test {public static void main(String[] args) {Integer n1 123;Integer n2 123;Integer n3 128;Integer n4 128;System.out.println(n1 n2);System.out.…...
怎么做跟P站一样的网站/seo刷词
定时框架中最重要的就是时间,我们也可以直接使用Cron这种事件格式。 使用其他的时间格式,就可以用DateBuilder快速的创建出需要的时间。 因为quartz是一个定时框架,所以对于操控时间 需要更加准确的掌握。当时我们也可以直接通过BCL直接定义…...
文章时间分类wordpress/如何做品牌宣传与推广
下载DevExpress v19.2完整版 通过DevExpress WPF Controls,您能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 又到了每年发布DevExpress WPF产品线2020年非正式计划的时候了&#x…...