基础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 ->19   fprintf ( stdout ,"hello fprintf\n" );//stdout ->110   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   //C9   printf("hello printf "); //stdout ->110   fprintf ( stdout ,"hello fprintf " );//stdout ->111   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 ->110 //  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   //C9   printf("hello printf\n"); //stdout ->110   fprintf ( stdout ,"hello fprintf\n" );//stdout ->111   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 06669  _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 10245 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_FILE13 {14   int fileno ;// 文件描述符fd15   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 MakefileFile: ‘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 +0800Birth: -

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

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

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

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

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

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

相关文章

基于FIDO2和USBKEY硬件的SSH认证

在 8.2&#xff08;最新为 8.3&#xff09;版本中&#xff0c;OpenSSH 提供了对 FIDO 和 UAF 的支持。从此用户就可以用硬件 USBKEY 证书进行 SSH 原生认证。这样可以实现简捷、有效和安全的 SSH 认证。本文我们就就少一下 FIDO2 以及 OpenSSH 对其的支持&#xff0c;并尝试一下…

【调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件】

调试笔记-系列文章目录 调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件 文章目录 调试笔记-系列文章目录调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件 前言一、调试环境操作系统&#xff1a;Ubuntu 22.04.4 LTS编译环境调试目标 二、调…

日志的介绍及简单实现

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 日志是什么&#xff1f; 为什么需要日志&#xff1f; 实现一个简单日志 时间戳 clock_gettime time & localtime 可变模板参数(使用C语言)&#xff0c;va_start & va_end & vsprintf 宏 __LINE__…

Digital Image Processing System(DIPS)

数字图像处理系统 Digital Image Processing System&#xff08;DIPS&#xff09; 早前版本&#xff1a; ​​​​​​​DIPS_YTPC OCR-CSDN博客

数据结构和算法|排序算法系列(二)|冒泡排序

首先需要你对排序算法的评价维度和一个理想排序算法应该是什么样的有一个基本的认知&#xff1a; 《Hello算法之排序算法》 主要内容来自&#xff1a;Hello算法11.3 冒泡排序 我觉得冒泡排序非常有意思&#xff0c;也非常简单&#xff0c;就是不停地交换相邻的元素即可&#…

ElasticSearch插件版本与ES版本不对应的解决方案

一、背景 最近需要给es安装ik、hanlp分词器和ingest-attachment管道&#xff0c;服务器已有的es版本为8.5.3&#xff08;似乎太新了&#xff09;&#xff0c;hanlp和ingest-attachment都没有这么高的版本&#xff0c;因此只能下载相对老的版本&#xff0c;然后自己修改配置文件…

安全设计 | 安全设计不得马虎!微软STRIDE威胁建模方法让你事半功倍,快速发现应用安全隐患!

STRIDE威胁建模方法最早发表于2006年11月的《MSDN杂志》&#xff0c;作者是微软的工程师Shawn Hernan、Scott Lambert 、Tomasz Ostwald 和 Adam Shostack。那我们为什么要进行威胁建模&#xff1f; 如何使用数据流图对系统进行威胁建模&#xff1f;如何减轻威胁&#xff1f;接…

java项目之桂林旅游景点导游平台源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的桂林旅游景点导游平台。 项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 桂林旅游景点导游…

mysql5.5版本安装过程

mysql是关系型数据库的管理系统 将安装包放在 c盘根目录 名称为mysql 在该路径下cmd进入命令执行窗口 出现此页面说明安装成功 需要修改配置文件内容 将my-medium.ini 复制粘贴并改名为 my.ini 并添加如下内容 改好之后在mysql目录下cmd进入命令执行窗口 切换到cd bin …

Java实现图书系统

首先实现一个图书管理系统,我们要知道有哪些元素? 1.用户分成为管理员和普通用户 2.书:书架 书 3.操作的是: 书架 目录 第一步:建包 第二步:搭建框架 首先:完成book中的方法 其次:完成BookList 然后:完成管理员界面和普通用户界面 最后:Main 第三步:细分方法 1.退…

Spring—Spring配置文件概念及应用(实现一个图形验证码)

文章目录 配置文件配置文件作用配置文件的格式配置文件优先级说明配置文件书写代码的格式yml文件代码的格式 Value注解 properties 缺点分析properties VS yml实现一个验证码程序 配置文件 配置文件作用 整个项目的重要信息我们都会配置在配置文件中&#xff0c;比如说我们数…

视频拼接融合产品的产品与架构设计(四)分布式GPU运算合并单元

上一篇如下 视频拼接融合产品的产品与架构设计(三&#xff09;内存和显存单元数据迁移 视频合并单元说明 对下面这张图做些说明&#xff0c;视频接入是比较常见&#xff0c;可以说是普通&#xff0c;但是做到接入后随即进行比较重的算法运算&#xff0c;这个在视频领域并不多…

软件项目详细设计说明书实际项目参考(word原件下载及全套软件资料包)

系统详细设计说明书案例&#xff08;直接套用&#xff09; 1.系统总体设计 2.性能设计 3.系统功能模块详细设计 4.数据库设计 5.接口设计 6.系统出错处理设计 7.系统处理规定 软件开发全文档下载&#xff08;下面链接或者本文末个人名片直接获取)&#xff1a;软件开发全套资料-…

C++ 常用UI库

AWTK github gitee doc scons 类似RT-Thread element github C Cross platfrom C GUI libraries&#xff0c;QT可替代方案。调试包 SDL GUI cegui 创作不易&#xff0c; 小小的支持一下吧&#xff01;

泛型...

定义&#xff1a;在编译过程中约束操作的数据类型。&#xff08;统一数据类型&#xff09; 格式&#xff1a;<数据类型> 泛型中不能写基本数据类型。 泛型类 在一个类中&#xff0c;某个变量的数据类型不确定时&#xff0c;可以定义带有泛型的类。 泛型的底层是Obje…

电量计量芯片HLW8110的前端电路设计与误差分析校正.pdf 下载

电量计量芯片HLW8110的前端电路设计与误差分析校正.pdf 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1vlCtC3LGFMzYpSUUDY-tEg 提取码&#xff1a;8110

十四天学会Vue——Vue核心(理论+实战)(第一天)上篇

&#xff01;&#xff01;&#xff01;声明必看&#xff1a;由于本篇开始就写了Vue&#xff0c;内容过多&#xff0c;本篇部分内容还有待完善&#xff0c;小编先去将连续更新的js高阶第四天完成~本篇部分待完善内容明日更新 一、Vue核心&#xff08;上篇&#xff09; 热身top…

vue3+electron+typescript 项目安装、打包、多平台踩坑记录

环境说明 这里的测试如果没有其他特别说明的&#xff0c;就是在win10/i7环境&#xff0c;64位 创建项目 vite官方是直接支持创建electron项目的&#xff0c;所以&#xff0c;这里就简单很多了。我们已经不需要向开始那样自己去慢慢搭建 yarn create vite这里使用yarn创建&a…

外企也半夜发布上线吗?

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

golang创建式设计模式---工厂模式

创建式设计模式—工厂模式 目录导航 创建式设计模式---工厂模式1)什么是工厂模式2)使用场景3)实现方式4)实践案例5)优缺点分析 1)什么是工厂模式 工厂模式(Factory Method Pattern)是一种设计模式&#xff0c;旨在创建对象时&#xff0c;将对象的创建与使用进行分离。通过定义…