基础IO用户缓冲区 、inode、硬软链接【Linux】

news2024/12/23 2:03:23

文章目录

  • 用户缓冲区
  • 磁盘
    • 磁盘分区
    • EXT2文件系统的存储方案
  • inode
  • 软链接
  • 硬链接

用户缓冲区

代码一:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<string.h>                                     
  4 int main()
  5 {
  6   const char * fstr = "hello fwrite\n";
  7   const char * str =" hello write\n";
  // C语言接口
  8   printf("hello printf\n"); //stdout ->1
  9   fprintf ( stdout ,"hello fprintf\n" );//stdout ->1
 10   fwrite( fstr , strlen(fstr), 1, stdout);
 //操作系统提供的系统调用接口
 11  write(1, str, strlen(str));
 12 
 13   return 0 ;
 14 }

代码三:
去掉了\n

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<string.h>
  4 int main()
  5 {
  6   const char * fstr = "hello fwrite ";                                                                                              
  7   //const char * str =" hello write\n";
  8   //C
  9   printf("hello printf "); //stdout ->1
 10   fprintf ( stdout ,"hello fprintf " );//stdout ->1
 11   fwrite( fstr , strlen(fstr), 1, stdout);
 12    close(1);
 13   //操作系统提供的系统调用接口
 14  //write(1, str, strlen(str));
 15 //  fork();
 16   return 0 ;
 17 }

代码四:

  1 #include<stdio.h>  
  2 #include<unistd.h>  
  3 #include<string.h>  
  4 int main()  
  5 {  
  6   //const char * fstr = "hello fwrite ";  
  7   const char * str =" hello write";                                                                                                 
  8   //C                                      
  9 //  printf("hello printf "); //stdout ->1
 10 //  fprintf ( stdout ,"hello fprintf " );//stdout ->1  
 11 //  fwrite( fstr , strlen(fstr), 1, stdout);  
 12   //操作系统提供的系统调用接口  
 13  write(1, str, strlen(str));  
 14    close(1);             
 15 //  fork();              
 16   return 0 ;             
 17 } 

在这里插入图片描述

printf/fprintf/fwrite/fputs 等, 这些函数都是C接口,底层一定调用了write(操作系统提供的系统调用接口)

 const char * str =" hello write";    
write(1, str, strlen(str));  

在这里插入图片描述

write能看到打印的结果
原因:
写入的字符串通过write()这样的系统调用接口直接写到了内核的文件缓冲区中 ,close()关闭文件描述符对write不影响

printf/fprintf/fwrite/fputsC接口看不到
原因:调用C接口时,写入的字符串写到了C语言提供的缓冲区,用户缓冲区,如果遇到了\n或者强制刷新,此时C接口才会调用write()接口,把用户缓冲区的数据写入到系统中,

如果此时调用了close(1) ,把1号文件描述符关闭了,就不能刷新数据 ,所以不能显示结果

显示器的文件的刷新方案是行刷新,所以在printf执行完就会立即遇到\n的时候,将数据进行刷新

缓冲区刷新问题
1、无缓冲—直接刷新数据
2、行缓冲—不刷新,直到碰到\n才刷新数据,向显示器文件打印,一般是行
刷新
3、全缓冲—缓冲区满了,才刷新数据 ,向普通文件写入,一般是全缓冲
4、进程退出的时候,也会刷新
例如:这段代码并没有写\n,但是当进程退出的时候,也会刷新

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

在这里插入图片描述

用户刷新的本质,就是将数据通过1 (stdout)+ write写入到内核中
目前我们认为,只要将数据刷新到了内核,数据就到可以硬件了

语言都属于用户层
这个FILE对象属于用户,这个缓冲区是用户级缓冲区

为什么要有这个缓冲区?
1、解决用户的效率问题
2、配合格式化
例如:

int a =123 ;
printf("hello %d\n",a);

printf ,fprintf 这些格式化输出接口 , 如果此时需要在显示器上打印123 ,其实在显示器上打印的是字符1 ,字符2 ,字符3, ,将hello %d ,a 格式化成" hello 123" 写到缓冲区中

缓冲区在什么位置?
FILE里面有对应打开文件的缓冲区字段和维护信息
FILE结构体当中不仅保存了对应文件的文件描述符还保存了用户缓冲区的相关信息

//缓冲区相关
/* The following pointers correspond to the C++ streambuf protocol. */
/* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr;   /* Current read pointer */
char* _IO_read_end;   /* End of get area. */
char* _IO_read_base;  /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr;  /* Current put pointer. */
char* _IO_write_end;  /* End of put area. */
char* _IO_buf_base;   /* Start of reserve area. */
char* _IO_buf_end;    /* End of reserve area. */
/* The following fields are used to support backing up and undo. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base;  /* Pointer to first valid character of backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */

exit :C语言接口,exit可以看到用户缓冲区,exit能将用户缓冲区的数据刷新

_exit: 系统调用接口 ,看不到用户缓冲区 ,_exit把文件描述符关闭,将进程释放,

代码:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<string.h>
  4 int main()
  5 {
  6   const char * fstr = "hello fwrite\n";
  7   const char * str =" hello write\n";
  8   //C
  9   printf("hello printf\n"); //stdout ->1
 10   fprintf ( stdout ,"hello fprintf\n" );//stdout ->1
 11   fwrite( fstr , strlen(fstr), 1, stdout);
 12   // close(1);
 13   //操作系统提供的系统调用接口
 14  write(1, str, strlen(str));
 15   fork();                                              
 16   return 0 ;
 17 }

在这里插入图片描述

./myfile > log.txt , 重定向完成之后, 本来向显示器打印,现在打印到log.txt文件
而且缓冲方案从行缓冲变成了全缓冲 , 也就是遇到\n不在刷新,而是等缓冲区被写满才刷新

C接口的hello printf、 hello fprintf 、hello fwrite 先写入到用户级缓冲区中 ,因为此时是全缓冲,所以数据还未刷出
write是操作系统提供的系统调用接口 ,直接写到了内核的文件缓冲区中,所以hello write数据先刷出来,当进程退出时, 将用户缓冲区的数据全部刷出,即C接口的hello printf、 hello fprintf 、hello fwrite

为什么C接口打印两次?

一旦执行fork ,操作系统就会创建子进程 ,父进程和子进程的代码是共享的,数据会以写时拷贝的方式被父子进程各自私有一份 ,用户缓冲区属于用户,也就是属于进程地址空间的堆空间的一段内存缓冲区。当操作系统对用户缓冲区进行操作时,此时发生写时拷贝,父子进程对这段缓冲区各自私有一份,当进程退出时,双方都需要对数据刷新,父进程先刷新,就刷父进程的,子进程先刷新,就刷子进程的

[cxq@iZ7xviiy0goapxtblgih6oZ lesson20]$ while :; do cat log.txt ;sleep 1  ; echo "-----------"; done

模拟实现一下fopen ,fwrite ,fclose
main.c

   1 #include<stdio.h>
    2 #include"Mystdio.h"
    3 #define  myfile "test.txt"
    4 int main()
    5 {
    6   _FILE * fp = _fopen( myfile , "a" );
    7   if( fp ==NULL )
    8   {
    9     perror("fopen fail\n");
   10   }
   11 
   12  const char *msg = "hello world\n";
   13 
   14  int cnt =5 ;
   15  while(cnt)
   16  {
   17    _fwrite(fp, msg, strlen(msg));
   18                                                                                                                                   
E> 19    sleep(1);
   20 
   21 cnt --;
   22  }
   23 
   24 
   25   _fclose(fp);
   26 
   27   return 0 ;
   28 }

Mystdio.c

  1 #include"Mystdio.h"
  2 #include<assert.h>
  3 #include<unistd.h>
  4  #include <sys/types.h>
  5  #include <sys/stat.h>
  6  #include <fcntl.h>
  7 #include<stdlib.h>
  8 #define FILE_MODE 0666
  9  _FILE*_fopen  ( const char*filename, const char *flag  ) 
 10 {
 11  assert(filename);
 12  assert(flag);
 13  int f =0 ;
 14  int fd = -1 ;
 15  if(strcmp( flag,"w" ) ==0) 
 16  {
 17     f = (O_CREAT | O_WRONLY | O_TRUNC) ;    
 18   fd =  open  (filename , f, FILE_MODE );
 19  }
 20  
 21 else  if(strcmp( flag,"a" ) ==0) 
 22  {
 23     f = (O_CREAT | O_WRONLY | O_APPEND) ;    
 24   fd =  open  (filename , f, FILE_MODE );
 25  }
 26 
 27 else  if(strcmp( flag,"r" ) ==0) 
 28  {
 29     f = O_RDONLY ;    
 30   fd =  open  (filename , f, FILE_MODE );
 31  }                                                                                                                                  
 32 else 
 33 {
 34   return NULL;
 35 }
36 
 37  if( fd ==-1  )
 38 {
 39   return NULL ;                                                                                                                     
 40 }
 41 
 42   _FILE *  fp =  (_FILE *) malloc (sizeof(_FILE));
 43   if(fp ==NULL)
 44   {
 45     return NULL ;
 46   }
 47   fp->fileno = fd ;
 48   //fp->flag =FLUSH_LINE ; 
 49   fp->flag =FLUSH_ALL ; 
 50   fp->out_pos = 0;
 51 return  fp;
 52 
 53 }
 54 
 55 void _fflush  ( _FILE  * fp  )
 56 {
 57  if( fp->out_pos >0 )
 58  {
 59  //刷新 
 60  write ( fp->fileno , fp->outbuffer , fp->out_pos   );
 61   fp->out_pos=0; //缓冲区清零
 62  }
 63 }
64 
 65 
 66 void _fclose ( _FILE *fp )
 67 {
 68 if(fp == NULL) return;
 69 
 70   _fflush(fp);
 71   close ( fp->fileno );
 72  free(fp) ;
 73 }
 74 int _fwrite(_FILE *fp, const char *s, int len)
 75 {
 76  // "abcd\n"
 77  
 78  //拷贝
 79  memcpy( &fp->outbuffer[fp->out_pos] , s,len  );
 80  fp->out_pos +=len;
 81 
 82  //无缓冲
 83 if(fp->flag&FLUSH_NOW) // &  ??
 84 {
 85 write(fp->fileno , fp->outbuffer , fp->out_pos);
 86 fp->out_pos =0 ;
 87 
 88 }
 89 
 90 else if( fp->flag&FLUSH_LINE )
 91 {
 92 //行缓冲
 93   if( fp->outbuffer[fp->out_pos-1] == '\n')
 94   {
 95     write(fp->fileno, fp->outbuffer, fp->out_pos);
 96             fp->out_pos = 0; 
 97   }
 98 
 99 
100 }
101 //全缓冲
102 else if( fp->flag & FLUSH_ALL  )
103 {
104   if(fp->out_pos == SIZE)
105   {
106       write(fp->fileno, fp->outbuffer, fp->out_pos);
107             fp->out_pos = 0;
108   }
109 }
110 return len ;
111 }

Mystdio.h

  1 //防止头文件重复包含
  2 #ifndef __MYSTDIO_H__
  3 #define __MYSTDIO_H__ 
  4 #define SIZE 1024
  5 
  6 
  7 #define FLUSH_NOW 1  // 无缓冲
  8 #define FLUSH_LINE 2 //行缓冲
  9 #define FLUSH_ALL 4//全缓冲
 10 #include<string.h>
 11 
 12 typedef struct IO_FILE
 13 {
 14   int fileno ;// 文件描述符fd
 15   int  flag ; //缓冲方式
 16  //  char inbuffer[SIZE] ;//接收缓冲区 
 17   char outbuffer[SIZE] ; // 
 18   //  int in_pos ; 
 19   int out_pos; //outbuffer这个缓冲区使用了多少,由out_pos决定                                                                       
 20 }_FILE;
 21 
 22  _FILE *  _fopen ( const char * filename, const char * mode ) ;
 23   int  _fwrite (  _FILE * fp , const char  * ptr , int len  ) ;
 24   void  _fclose(_FILE* fp  )  ;
 25 #endif

在这里插入图片描述

磁盘

磁盘是一种永久性存储介质,在计算机中,磁盘几乎是唯一的机械设备。与磁盘相对应的就是内存,内存是掉电易失存储介质,目前所有的普通文件都是在磁盘中存储的
在这里插入图片描述

磁盘被访问的最基本单元是扇区,一个扇区的大小通常为512字节
可以把磁盘看做由无数个扇区构成的永久性存储介质
任意—个扇区都有下标

要把数据存到磁盘,需要三个步骤

1、确定读写信息在磁盘的哪一面(定位用哪个磁头)
2、这一面的哪一个磁道
3、这个磁道的哪一个扇区

Cylinder (磁道或者柱面)Header(磁头) Sector(扇区)

通过磁道、磁头、扇区来定位 ,把这种寻址方式叫CHS寻址方式

磁盘分区

计算机为了更好的管理磁盘,于是对磁盘进行了分区,盘片一旦划分成数个分区,不同的目录与文件就可以存储进不同的分区,分区越多,就可以将文件的性质区分得越细

磁盘通常被称为块设备,一般以扇区为单位,一个扇区的大小通常为512字节。我们若以大小为512G的磁盘为例,该磁盘就可被分为十亿多个扇区

在这里插入图片描述

EXT2文件系统的存储方案

格式化:每一个分区再被使用之前,都必须提前先将部分文件系统的属性信息提前设置进对应的分区中,方便我们后续使用这个分区或者分组

在这里插入图片描述

Super Block:文件系统的基本信息,里面包含的是整个分区的文件系统基本使用情况,Super Block不会在每个组都存在
例如:一共有多少个组,每个组的大小,每个组的inode数量,每个组的block数量,每个组的起始inode ,文件系统的类型与名称等

Group Descriptor Table: 块组描述符表,描述该分区当中块组的属性信息。
整个分组的相关属性和具体使用情况
例如该分组一共有多少个块,一共有多少inode,这些inode中被使用的数量,未被使用的数量,整个数据块中被使用的具体数量,未被使用的具体数量

Block Bitmap:比特位的位置和块号映射起来,比特位的内容,表示该块有没有被使用删一个文件的时候,找到对应文件的inode,把对应的inode编号在位图清空,这个文件就被删除了

inode Bitmap:比特位的位置和inode的编号映射起来,比特位的内容表示inode是否是有效的

inode Table:inode:单个文件的所有的属性,一般是128字节,一个文件,一个inode,每一个inode都有自己的inode编号(inode的设置,是以分区为单位的,不能跨分区),inode表示文件的所有属性,文件名,并不属于inode内的属性

Data Blocks:存文件内容的区域,以块的形式呈现。常见的是4KB大小—文件系统的块大小! 例如:在磁盘中,新建一个文件,就算往文件中写入一个字节的内容,在文件系统中,在某一个分区中,找到某一个块组,在该块组中申请一个块,大小也要为4KB

一个文件使用的数据块和inode结构的对应关系,是通过一个数组进行维护的,该数组一般可以存储15个元素,其中前12个元素分别对应该文件使用的12个数据块,剩余的三个元素分别是一级索引、二级索引和三级索引,当该文件使用数据块的个数超过12个时,可以用这三个索引进行数据块扩充

在这里插入图片描述

inode

磁盘文件由两部分构成,分别是文件内容和文件属性。文件内容就是文件当中存储的数据,文件属性就是文件的一些基本信息,例如文件名、文件大小以及文件创建时间等信息都是文件属性,文件属性又被称为元信息

显示当前目录下各文件的inode编号

ls -i

[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ touch test.c
[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ ls -i
789121 test.c
[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ ls -il
total 0
789121 -rw-rw-r-- 1 cxq cxq 0 May 23 15:46 test.c

查看磁盘的分区信息

[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ ls /dev/vda* -l
brw-rw---- 1 root disk 253, 0 Apr 15 09:28 /dev/vda
brw-rw---- 1 root disk 253, 1 Apr 15 09:28 /dev/vda1

在文件系统中,如何理解创建一个空文件?

查Group Descriptor Table ,如果inode使用率较低,
再查inode Bitmap,扫描位图结构,找到最近未被使用的inode编号,并确认在哪个组中,inode Bitmap里对应的位图将0改为1,通过inode编号在inode Table中找到对应的inode,将写入的文件属性填入Block Bitmap

在文件系统中,如何理解对文件写入信息?

通过文件的inode编号找到对应的inode结构。
通过inode结构找到存储该文件内容的数据块,并将数据写入数据块。
若不存在数据块或申请的数据块已被写满,则通过遍历块位图的方式找到一个空闲的块号,并在数据区当中找到对应的空闲块,再将数据写入数据块,最后还需要建立数据块和inode结构的对应关系

在文件系统中,如何理解目录?

目录也是文件,也有自己的inode。目录也有自己的属性
目录的inode结构当中存储的就是目录的属性信息,比如目录的大小、目录的拥有者等。
目录也有自己的内容,目录的数据块当中存储的是,该目录下,文件的文件名和对应文件的inode的映射关系

在文件系统中,如何理解删除一个文件
找到文件对应的inode编号,根据文件所处在的目录,得知文件处在具体的分区,在根据inode范围,确定具体的分组, 在inode Bitmap中,将对应的比特位由1改为0,根据Block Bitmap,由1该为0

在文件系统中,如何理解查找一个文件?
找到这个文件的inode编号,在inode Bitmap中,确定对应的比特位为1,读取inode Table,将文件属性拿出来,通过inode结构体里面的blocks数组,找到对应的数据块

软链接

任意一个文件,无论是目录,还是普通文件,都有inode每一个inode内部,都有一个叫做引用计数的计数器(有多少个文件名指向我)!

创建一个文件的软连接

[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ ln -s myproc myproc-s
[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ ll
total 20
-rw-rw-r-- 1 cxq cxq   70 May 24 09:19 Makefile
-rwxrwxr-x 1 cxq cxq 8360 May 24 09:21 myproc
-rw-rw-r-- 1 cxq cxq   73 May 24 09:13 myproc.c
lrwxrwxrwx 1 cxq cxq    6 May 24 09:41 myproc-s -> myproc

在这里插入图片描述
软链接文件的inode号与源文件的inode号是不同的,软连接是一个独立的文件,有独立的inode,也有独立的数据块,软连接的数据块里面保存的是指向的目标文件的路径
并且软链接文件的大小比源文件的大小要小得多

软链接又叫做符号链接,软链接文件相对于源文件来说是一个独立的文件,该文件有自己的inode号,但是该文件只包含了源文件的路径名,所以软链接文件的大小要比源文件小得多。软链接就类似于Windows操作系统当中的快捷方式

**加粗样式**4f689b2eb17ae06da43.png)

软链接文件只是其源文件的一个标记,当删除了源文件后,链接文件不能独立存在,虽然仍保留文件名,但却不能执行或是查看软链接的内容

硬链接

建立硬链接,本质其实就是在特定目录的数据块中,新增文件名和指向的文件的inode编号的映射关系

硬链接应用场景:通常用来进行路径定位,采用硬链接,可以进行目录间切换

cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ ln myproc  myproc-h

硬链接文件的inode号与源文件的inode号是相同的,并且硬链接文件的大小与源文件的大小也是相同的,特别注意的是,当创建了一个硬链接文件后,该硬链接文件和源文件的硬链接数都变成了2
在这里插入图片描述
硬链接文件就是源文件的一个别名,一个文件有几个文件名,该文件的硬链接数就是几,这里inode号为789123的文件有myproc和myproc-h两个文件名,因此该文件的硬链接数为2。

与软连接不同的是,当硬链接的源文件被删除后,硬链接文件仍能正常执行,只是文件的链接数减少了一个,因为此时该文件的文件名少了一个
在这里插入图片描述
硬链接就是让多个不在或者同在一个目录下的文件名,同时能够修改同一个文件,其中一个修改后,所有与其有硬链接的文件都一起修改了

[cxq@iZ7xviiy0goapxtblgih6oZ lesson22]$ mkdir dir 
[cxq@iZ7xviiy0goapxtblgih6oZ lesson22]$ ll
total 4
drwxrwxr-x 2 cxq cxq 4096 May 26 19:28 dir
[cxq@iZ7xviiy0goapxtblgih6oZ lesson22]$ ls -li
total 4
789125 drwxrwxr-x 2 cxq cxq 4096 May 26 19:28 dir
[cxq@iZ7xviiy0goapxtblgih6oZ lesson22]$ cd dir 
[cxq@iZ7xviiy0goapxtblgih6oZ dir]$ ls -lia
total 8
789125 drwxrwxr-x 2 cxq cxq 4096 May 26 19:28 .
789124 drwxrwxr-x 3 cxq cxq 4096 May 26 19:28 ..

在这里插入图片描述

dir的硬链接数是2
在这里插入图片描述

linux系统不允许对目录建立硬链接

stat 文件名来查看对应文件的信息

[cxq@iZ7xviiy0goapxtblgih6oZ lesson21]$ stat Makefile
  File: ‘Makefile’
  Size: 70        	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 789122      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     cxq)   Gid: ( 1000/     cxq)
Access: 2024-05-24 09:21:10.264336601 +0800
Modify: 2024-05-24 09:19:44.614656971 +0800
Change: 2024-05-24 09:19:44.614656971 +0800
 Birth: -

这其中包含了文件的三个时间信息:

Access: 文件最后被访问的时间。
Modify: 文件内容最后的修改时间。
Change: 文件属性最后的修改时间。
当我们修改文件内容时,文件的大小一般也会随之改变,所以一般情况下Modify的改变会带动Change一起改变,但修改文件属性一般不会影响到文件内容,所以一般情况下Change的改变不会带动Modify的改变。

可以使用命令touch 文件名,将文件的这三个时间都更新到最新状态

注意: 当某一文件存在时使用touch命令,此时touch命令的作用变为更新文件信息

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

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

相关文章

从XPS迁移到IP Integrator

从XPS迁移到IP Integrator 概述 AMD Vivado™设计套件IP集成器可让您将包含AMD的设计缝合在一起 IP或您的自定义IP在相对较短的时间内&#xff0c;在GUI环境中工作。 就像在Xilinx Platform Studio中一样&#xff0c;您可以快速创建嵌入式处理器设计&#xff08;使用&#xff0…

中兴通讯助力中国移动,推动SPN AI节能技术于23省规模部署

SPN作为中国移动自主创新的新一代综合承载网络&#xff0c;相比PTN设备&#xff0c;SPN的单机容量及性能有大幅提升&#xff0c;整机功耗也相应变大。在当前国家双碳政策的目标下&#xff0c;SPN设备的节能降耗也日益成为中国移动关注的焦点。因此&#xff0c;中国移动选择与中…

Crafty - hackthebox

简介 靶场&#xff1a;hackmyvm 靶机&#xff1a;Crafty(10.10.11.254) 难度&#xff1a;Easy 靶机链接:https://app.hackthebox.com/machines/Crafty 攻击机1&#xff1a;ubuntu22.04 (10.10.16.16) 攻击机2&#xff1a;windows11(10.10.14.33) 扫描 fscan扫描http服务…

graspnet+Astra2相机实现部署

graspnetAstra2相机实现部署 &#x1f680; 环境配置 &#x1f680; ubuntu 20.04Astra2相机cuda 11.0.1cudnn v8.9.7python 3.8.19pytorch 1.7.0numpy 1.23.5 1. graspnet的复现 具体的复现流程可以参考这篇文章&#xff1a;Ubuntu20.04下GraspNet复现流程 这里就不再详细…

贪心-leetcode402.移掉 K 位数字-XMUOJ符文序列

题目 思路 话不多说&#xff0c;直接上代码 代码 /*leetcode402.移掉 K 位数字-XMUOJ符文序列--JinlongW-2024/05/26单调栈贪心*/ #include<bits/stdc.h> const int N1010; char num[N],result[N],numStack[N]; int k; using namespace std;void removeKdigits( int k…

Excel 多行表头的列转行

Excel中A3:F6是带表头的典型表格&#xff0c;但上面多了额外的两行表头&#xff1a; ABCDEF1ActualsActualsPlanPlan2FY20FY21FY20FY213CountryOwner1/1/20201/1/20201/1/20201/1/20204FranceRichard100150801605FranceMartin1201401301406FrancePierre501005080 现在要将典型…

美业美容院会员服务预约店铺管理小程序的效果是什么

美容业各个服务都有不少人需要&#xff0c;美容项目通常价格高&#xff0c;本地客户触达的同时&#xff0c;品牌形象触达外地客户也可获取&#xff0c;女性消费群体在“美”的各方面多数情况下是不惜资金投入。 客户需要找到靠谱商家&#xff0c;而项目消费/同行竞争/升级发展…

matplotlib latex表格

使用python3环境 import matplotlib.gridspec as gridspec import matplotlib.pyplot as pltimport numpy as np import matplotlib as mpl #mpl.use(pgf)def figsize(scale, nplots 1):fig_width_pt 390.0 # Get this from LaTeX using \the\text…

如何解决mfc110udll丢失的问题,7个方法可解决mfc110udll丢失

mfc110u.dll是一个动态链接库文件&#xff0c;属于Microsoft Visual C 2012 Redistributable Package的一部分。它是Microsoft Foundation Classes (MFC) 库的一个版本&#xff0c;专门用于支持基于MFC开发的应用程序运行。MFC是一个用于Windows操作系统上使用C进行本机应用程序…

【启程Golang之旅】深入解析函数的奥秘与技巧

欢迎来到Golang的世界&#xff01;在当今快节奏的软件开发领域&#xff0c;选择一种高效、简洁的编程语言至关重要。而在这方面&#xff0c;Golang&#xff08;又称Go&#xff09;无疑是一个备受瞩目的选择。在本文中&#xff0c;带领您探索Golang的世界&#xff0c;一步步地了…

command not found: wire 解决方案【学习笔记,不作教程】

command not found: wire command not found: wire command not found: wire go get github.com/google/wire/cmd/wirego install github.com/google/wire/cmd/wirelatest再次在 /bubble/cmd/bubble目录下执行wire wire wire: bubble/cmd/bubble: wrote /Users/zhengshijie/go…

JavaEE之线程(7)_单例模式(设计模式概念、单例模式优点、懒汉、饿汉模式)

一、什么是设计模式&#xff1f; 单例模式是设计模式中较为常见的一种。那么&#xff0c;什么是单例模式&#xff1f; 设计模式&#xff08;Design Pattern&#xff09;都是一些相对优秀的解决方案&#xff0c;很多问题都是典型的、有代表性的问题&#xff0c;学习设计模式&am…

外企也半夜发布上线吗?

0 别把问题想得太复杂 如果有灰度发布的能力&#xff0c;最好白天发布&#xff1b;如果没有灰度发布&#xff0c;只能在半夜发布。 即使有灰度发布能力&#xff0c;也不要沾沾自喜&#xff0c;好好反思一下你们的灰度发布是否真的经得起考验&#xff0c;还是仅仅是装装样子。…

Python语言绘制好看的小提琴图、箱形图、散点图、山脊图和柱状图等等

废话不多说&#xff0c;今天给大家分享一个&#xff0c;使用python绘制小提琴图、箱形图、散点图、山脊图和柱状图等等 图中的数据是随机生成的&#xff0c;图例&#xff0c;图注以及坐标题目各种信息&#xff0c;具体内容大家可以自己修改~ 效果图如下所示 &#x1f447;&a…

web如何做接口层面自动化测试?

接口层面约等于集成化测试&#xff0c;且需要启动web容器 一般web项目的&#xff0c;代码都是按照分层开发的&#xff0c;业务主要是集中在service和dao层&#xff0c;而我们如果仅仅是利用之前的单元测试,然后把依赖的代码直接mock掉&#xff0c;仅仅测试controller这一块是没…

数据结构(四)

数据结构&#xff08;四&#xff09; 算法算法的特征算法和程序的区别怎么样评判一个算法的好坏 常见的查找算法线性树状哈希查找构建哈希函数的方法质数求余法解决冲突 算法 一堆指令的有序集合 算法的特征 唯一性&#xff1a;每一句话只有一种解释 有穷性&#xff1a;算法能…

第十课,while循环

一&#xff0c;认识循环是什么 循环普遍存在于日常生活中&#xff0c;同样&#xff0c;在程序中&#xff0c;循环功能也是至关重要的基础功能。 当程序需要重复执行某一段代码&#xff0c;利用循环可以轻松完成工作 例如我要你打印100次上课&#xff0c;直接写100次print&…

SpringBoo+vue3整合讯飞星火3.5通过webscoket实现聊天功能(全网首发)附带展示效果

API版本&#xff1a;Spring Boot 整合讯飞星火3.5通过接口Api接口实现聊天功能&#xff08;首发&#xff09;复制粘贴即可使用&#xff0c;后续更新WebSocket实现聊天功能_讯飞星火web聊天-CSDN博客https://blog.csdn.net/qq_53722480/article/details/138865508?csdn_share_t…

基于xilinx FPGA的 FFT IP使用例程说明文档(可动态配置FFT点数,可计算信号频率与幅度)

目录 1 概述2 IP examples功能3 IP 使用例程3.1 IP设置3.2 fft_demo端口3.3 例程框图3.4 仿真结果3.5 仿真验证得出的结论4 注意事项5例程位置 1 概述 本文用于讲解xilinx IP 的FFT ip examples的功能说明&#xff0c;方便使用者快速上手。 参考文档&#xff1a;《PG109》 2 …

推荐13款常用的Vscode插件,提高前端日常开发效率

1. Live Server Live Server 插件是一个用于前端开发的扩展&#xff0c;它的主要作用是提供一个本地开发服务器&#xff0c;以便实时预览和调试网页应用程序。其最大特点在于热重载&#xff0c;即开发者可实时预览代码效果。 因为Live Server 允许开发者在浏览器中实时预览您正…