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

文章目录

  • 用户缓冲区
  • 磁盘
    • 磁盘分区
    • 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命令的作用变为更新文件信息

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux下的调试器 : gdb指令详解

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;青果大战linux 总有光环在陨落&#xff0c;总有新星在闪烁 gdb是什么 gdn是linu…

SQL注入:原理及示例讲解,配置mysql环境变量,pikachu靶场搭建

SQL注入原理 SQL注入&#xff08;SQL Injection&#xff09;是一种代码注入技术&#xff0c;攻击者通过将恶意的SQL代码插入到应用程序的输入字段中&#xff0c;诱使后台数据库执行这些恶意代码&#xff0c;从而对数据库进行未授权的操作。常见的操作包括获取敏感数据、篡改数…

Liunx基本指令以及权限(个人笔记)

Linux指令和权限 1.指令1.1ls指令1.2pwd命令1.3cd指令1.4touch指令1.5mkdir指令1.6rm指令1.7man指令1.8cp指令1.9mv指令1.10cat指令1.11less指令1.12head指令1.13tail指令1.14date显示1.15Cal指令1.16find指令1.17grep指令1.18zip/unzip指令1.19tar指令1.20bc指令1.21uname -r指…

Python数据可视化(五)

实现GUI效果 借助 matplotlib&#xff0c;除可以绘制动画内容外&#xff0c;还可以实现用户图形界面的效果&#xff0c;也就是 GUI 效果。 GUI是用户使用界面的英文单词首字母的缩写。接下来&#xff0c;我们就以模块widgets中的类RadioButtons、 Cursor 和 CheckButtons 的使用…

属于程序员的浪漫,一颗会跳动的心!!!

绘制一颗会跳动的心❤ 嘿嘿 可以说是程序员的专属浪漫了吧&#xff0c;就像点燃一颗LED灯一样&#xff1f;&#xff08;我瞎说的啊&#xff0c;大家别当真&#xff0c;我很菜的&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 程序就在下面啦&#xff0c;然…

​✨聚梦AI绘图插件-for photoshop(基于ComfyUI) 内测版V0.1发布

&#x1f388;背景 photoshop本身是有AI生成能力的&#xff0c;不过限于种种原因&#xff0c;国内使用很不方便。 photoshop也是有AI插件的&#xff0c;不过大多安装起来比较复杂&#xff0c;或者&#xff0c;干脆就会收费。 所以我们做了一个免费的AI插件&#xff0c;期望能…

Vue.js条件渲染与列表渲染指南

title: Vue.js条件渲染与列表渲染指南 date: 2024/5/26 20:11:49 updated: 2024/5/26 20:11:49 categories: 前端开发 tags: VueJS前端开发数据绑定列表渲染状态管理路由配置性能优化 第1章&#xff1a;Vue.js基础与环境设置 1.1 Vue.js简介 Vue.js (读音&#xff1a;/vju…

如同“水生态”的存储引擎|OceanBase数据转储合并技术解读(一)

本系列文章主要围绕 OceanBase数据库存储引擎中的转储合并进行解读&#xff0c;涉及到数据存储、转储合并、数据校验等方面的内容&#xff0c;旨在让读者了解OceanBase数据库的存储引擎中与转储合并有关的各种概念&#xff0c;帮助读者更好地理解OceanBase数据库的存储技术原理…

20240526怎样将windows的屏幕复制到第二屏

百度&#xff1a;WIN10 第二显示器 COPY https://zhidao.baidu.com/question/761454546683111004.html 20240526怎样将windows的屏幕复制到第二屏  我来答 分享 举报 2个回答#热议# 海关有哪些禁运商品&#xff1f;查到后怎么办&#xff1f; 华硕服务 2022-07-05 百度认证:…

C++模板——函数模板和类模板

目录 泛型编程 函数模板 函数模板概念 函数模板的定义和语法 函数模板的工作原理 函数模板的实例化 隐式实例化 显示实例化 函数模板的匹配原则 类模板 类模板的定义格式 类模板的实例化 泛型编程 什么是泛型编程&#xff1f; 泛型编程&#xff08;Generic Pr…

Sam Altman微软Build 2024最新演讲:AI可能是下一个移动互联网

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

gfast:基于全新Go Frame 2.3+Vue3+Element Plus构建的全栈前后端分离管理系统

gfast&#xff1a;基于全新Go Frame 2.3Vue3Element Plus构建的全栈前后端分离管理系统 随着信息技术的飞速发展和数字化转型的深入&#xff0c;后台管理系统在企业信息化建设中扮演着越来越重要的角色。为了满足市场对于高效、灵活、安全后台管理系统的需求&#xff0c;gfast应…

人工智能+量子计算:飞跃现实边界还是科技幻想?

人工智能量子计算&#xff0c;这是一种可能改变世界的伙伴关系。 在科技的前沿&#xff0c;两大革命性技术——人工智能&#xff08;AI&#xff09;和量子计算——正站在合作的十字路口。人工智能&#xff0c;以其强大的数据分析能力和模式识别&#xff0c;正在改变着我们生活…

MOS选型及其参数解析

背景&#xff1a; 整理现有常用元器件选型&#xff0c;日后使用时针对性观看&#xff0c;生成列表链接如下&#xff1a; https://blog.csdn.net/caozhaokun/article/details/126069701 作者&#xff1a;Cayden 时间&#xff1a;2024/05/26 一、MOS选用现状 MOS是电路设计…

【软件设计师】面向对象技术

1.面向对象基础 1.1 基本概念 方法重载是函数名字相同&#xff0c;参数列表不同 组成 即组合&#xff0c;指整体与部分的关系&#xff0c;整体与部分生命周期相同 聚合 关联关系的一个特例&#xff0c;是体现整体与部分&#xff0c;即使has-a的关系&#xff0c;此时整体与部分…

设计模式在芯片验证中的应用——模板方法

一、模板方法 模板方法(Template Method)设计模式是一种行为设计模式&#xff0c; 它在父类中定义了一个功能的框架&#xff0c; 允许子类在不修改结构的情况下重写功能的特定步骤。也就是模板方法定义了一组有序执行的操作&#xff0c;将一些步骤的实现留给子类&#xff0c;同…

6818 android 修改开机 logo, 编译脚本分析

问题&#xff1a; 客户需要去掉 android5.1 的开机logo. 说明&#xff1a; 对于Android5.1 来说&#xff0c;uboot 与kernel 的logo 是一个。 过程&#xff1a; 其实对于开机logo 的修改很简单&#xff0c;直接参考厂家手册就可以了。 这是 android4.4 的开机logo 的修改&…

Ps:消失点滤镜 - 导出 3D 信息

Ps菜单&#xff1a;滤镜/消失点 Filter/Vanishing Point 快捷键&#xff1a;Ctrl Alt V “消失点”滤镜的导出 Export功能允许用户将创建的 3D 信息&#xff08;包括平面、纹理和测量&#xff09;导出为兼容 CAD、建模、动画和特殊效果应用程序的格式。这使得 Photoshop 与其…

上位机图像处理和嵌入式模块部署(f103 mcu和Qt上位机联动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 之前我们写过一篇文章​​​​​​​&#xff0c;上面说的是如何利用串口对mcu进行控制&#xff0c;即如果利用串口实现mcu led灯的点亮和熄灭。输…

【开源】租房管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、系统介绍 租客屋主模块 房源信息模块 租客评价模块 房源订单模块 留言板模块 二、系统截图 三、核心代码 一、系统介绍 基于Vue.js和SpringBoot的租房管理系统&#xff0c;分为管理后台和用户网页端&#xff0c;可以给管理员、租客和屋主角色使用&#xff0c…