当前位置: 首页 > news >正文

Linux系统编程-文件系统

目录

什么是Linux文件系统

文件系统的职责

存储介质抽象

inode:文件系统的核心

文件分配策略

目录结构

文件系统布局

日志和恢复机制

目录权限

粘滞位(t位):

硬链接和符号链接

硬链接的特点:

创建硬链接:

符号链接的特点:

创建符号链接:

文件属性

1.stat

2.fstat

3.lstat

4.chmod&fchmod

目录操作

目录的创建和销毁

更改当前工作路径

目录流操作

日期和时间

1.time

2.gmtime

3.localtime

4.strftime

 /etc目录下的文件

/etc/passwd

etc/group

/etc/shadow

GLOB函数

利用glob实现du功能

利用glob实现shell的ls功能


什么是Linux文件系统

        在操作系统的世界中,文件系统扮演着至关重要的角色,它负责管理磁盘上的数据,提供数据持久化和访问的机制。Linux文件系统,以其强大的灵活性和高性能,成为了许多系统管理员和开发者的首选。本文将从底层角度,深入探讨Linux文件系统的内部工作原理。

文件系统的职责

        首先,让我们明确文件系统的基本职责:

        1. 数据持久化:将数据从易失性的内存转移到非易失性的存储介质上。
        2. 数据访问:提供一种机制,允许用户和应用程序读取和写入数据。
        3. 数据组织:以一种逻辑和层次化的方式组织数据,通常以目录和文件的形式呈现。

存储介质抽象

        Linux文件系统将物理存储介质抽象为逻辑存储单元,这个过程涉及到几个关键概念:

        块设备:文件系统通过块设备接口与磁盘交互,块设备提供了一个统一的接口来处理不同类型存储设备的I/O操作。
        缓冲区:为了提高I/O效率,文件系统使用缓冲区暂存即将写入磁盘或从磁盘读取的数据。

inode:文件系统的核心

        每个文件或目录在Linux文件系统中都有一个对应的inode(索引节点)。inode包含了文件的元数据,而不是文件的数据本身。这包括:

        文件大小
        权限(所有者、组、其他)
        时间戳(创建、访问、修改时间)
        数据块索引

文件分配策略

        文件系统需要决定如何将文件数据分配到磁盘上的数据块。这涉及到多种文件分配策略:

        连续分配:在早期的文件系统中使用,将文件数据存储在连续的磁盘块中。
        链式分配:每个数据块包含指向下一个数据块的指针。
        索引分配:使用一个索引块来记录数据块的位置。

        现代文件系统,如Ext4和XFS,采用更为复杂的分配策略,以提高性能和灵活性。

目录结构

        Linux文件系统的目录结构由目录项(Dentry)实现,每个目录项包含:

        文件或目录的名称
        指向对应inode的指针
        这种结构使得文件和目录的查找变得非常高效。

文件系统布局

        在磁盘上,文件系统的布局通常包括:

        超级块:包含文件系统的全局信息,如块大小、inode数量等。
        inode表:存储所有inode的区域。
        数据块区:存储文件数据的区域。

日志和恢复机制

        现代文件系统使用日志来记录文件系统的操作,这有助于在系统崩溃后恢复文件系统的状态。例如,Ext4文件系统使用journaling来保证数据的一致性。


目录权限

        在Linux中,目录权限通常以10个字符的字符串表示,例如-drwxrwxrwt。这个字符串从左到右的含义如下:

第一个字符:
    d:目录(directory)。
    -:普通文件(regular file)。
    l:符号链接(symbolic link)。
    b:块设备文件(block device)。
    c:字符设备文件(character device)。
    p:管道文件(named pipe,FIFO)。
    s:套接字文件(socket)
接下来的三组字符(每组三个字符)
    第一组表示所有者的权限(owner)。
    第二组表示与所有者同一组的用户的权限(group)。
    第三组表示其他所有用户的权限(others)。
    其中r(4)表示可读,w(2)可写,x(1)可执,s表示权限切换user
特殊权限位:
    如果在第三组权限的末尾有一个 t,则表示设置了粘滞位


粘滞位(t位):

        在Linux系统中通常被称为 "t" 位,是一种特殊的文件系统权限位,它对目录的行为有特定的影响。当对目录设置了粘滞位后,只有该目录的拥有者和文件的所有者才能删除或者重命名目录中的文件。


粘滞位的主要作用:
    1.防止删除和重命名:如果一个目录设置了粘滞位,那么只有文件的所有者和目录的所有者可以删除或者重命名该目录下的文件。这可以防止普通用户删除或重命名其他用户在该目录下的文件。
    2.保护公共目录:粘滞位通常用于公共目录,如 /tmp,以确保用户可以创建临时文件,但不能删除或重命名其他用户的临时文件。


如何设置粘滞位:
        在Linux系统中,可以通过 chmod 命令来设置粘滞位。设置粘滞位的命令格式如下:

chmod +t <directory>

硬链接和符号链接

        硬链接(Hard Link)是一种文件链接方式,它直接指向文件的数据所在的位置,即文件系统中的inode(索引节点)。硬链接不是文件的副本,它与原始文件共享相同的inode和数据块。这意味着硬链接和原始文件是完全相同的,对硬链接的修改实际上是对原始文件的修改,反之亦然。硬链接在文件系统管理、备份和数据恢复等场景中非常有用,因为它们提供了对原始数据的直接访问,而不需要复制数据。然而,由于硬链接的特性,使用时也需要谨慎,以避免意外覆盖或删除重要文件。可以使用stat查询Links数,即inode硬链接数量。

硬链接的特点:

        1.共享inode:硬链接共享相同的inode和数据块,因此它们具有相同的inode号。
        2.文件名无关:硬链接可以位于不同的目录中,与文件名无关。硬链接的创建不会影响文件的目录结构。
        3.不可跨文件系统:硬链接不能跨越不同的文件系统创建。硬链接必须位于与原始文件相同的文件系统中。
         4.删除行为:只有当指向同一个inode的所有硬链接都被删除后,文件的数据才会被系统释放。删除硬链接不会删除原始文件或其它硬链接。
         5.不适用于目录和分区:硬链接通常不用于目录,因为目录的硬链接可能导致文件系统中的循环,从而引发问题。

创建硬链接:

        在Linux中,可以使用 ln 命令创建硬链接,命令格式如下:

ln existing_file new_link

        这里的 existing_file 是已存在的文件,new_link 是要创建的硬链接的名称。


        符号链接(Symbolic Link,也称为Symlink)是一种特殊的文件类型,它包含了指向另一个文件或目录的路径。符号链接可以视为一个快捷方式,它允许用户通过链接访问目标文件或目录,就像直接访问原始文件或目录一样。
Blocks为0不占内存空间

符号链接的特点:

    1.包含路径:符号链接是一个单独的文件,包含了指向另一个文件或目录的路径。
    2.跨文件系统:符号链接可以跨越不同的文件系统,这与硬链接不同。
    3.目录和文件:符号链接可以指向文件或目录。
    4.删除独立性:删除符号链接不会影响它所指向的原始文件或目录。
    5.更新和移动:如果原始文件或目录被移动或重命名,符号链接将变为死链接(dangling symlink),即它指向的路径不再有效。
    6.权限继承:符号链接的权限与原始文件或目录的权限无关,但访问符号链接时的权限检查会应用到目标文件或目录。

创建符号链接:

        在Linux中,可以使用 ln 命令的 -s 选项创建符号链接,命令格式如下:

 ln -s target_path link_name

        这里的 target_path 是要链接的目标文件或目录的路径,link_name 是符号链接的名称。


文件属性

1.stat

int stat(const char *pathname, struct stat *statbuf);

        通过文件路径获取属性信息填入 struct stat中,成功返回0,失败返回-1

2.fstat

int fstat(int fd, struct stat *statbuf);

        通过文件描述符获取属性信息填入 struct stat中,成功返回0,失败返回-1

3.lstat

int lstat(const char *pathname, struct stat *statbuf);struct stat {dev_t st_dev;         /* 包含文件的设备的ID */ino_t st_ino;         /* inode(索引节点)编号 */mode_t st_mode;       /* 16位的位图,表示文件类型,文件访问权限,特殊权限位 */nlink_t st_nlink;     /* 硬链接的数量 */uid_t st_uid;         /* 所有者的用户名ID */gid_t st_gid;         /* 所有者的组ID */dev_t st_rdev;        /* 特殊文件的设备ID */off_t st_size;        /* 总大小,单位为字节 */blksize_t st_blksize; /* 文件系统I/O的块大小 */blkcnt_t st_blocks;  /* 分配的512B块的数量 *//* 自 Linux 2.6 起,内核支持以下时间戳字段的纳秒级精度。有关 Linux 2.6 之前的详细信息,请参阅注释。 */struct timespec st_atim;  /* 最后访问时间 */struct timespec st_mtim;  /* 最后修改时间 */struct timespec st_ctim;  /* 最后状态改变时间 */#define st_atime st_atim.tv_sec      /* 向后兼容 */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec
};

        面对符号链接文件时获取的是符号链接文件的属性。

4.chmod&fchmod

int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);

        改变权限,成功返回0,失败-1
S_ISUID  (04000)  设置用户ID(在调用 execve(2) 时设置进程有效用户ID)
S_ISGID  (02000)  设置组ID(在调用 execve(2) 时设置进程有效组ID;强制性锁定,如 fcntl(2) 中所述;从父目录获取新文件的组,如 chown(2) 和 mkdir(2) 中所述)
S_ISVTX  (01000)  粘滞位(限制删除标志,如 unlink(2) 中所述)
S_IRUSR  (00400)  所有者读取
S_IWUSR  (00200)  所有者写入
S_IXUSR  (00100)  所有者执行/搜索("搜索"适用于目录,意味着可以访问目录内的条目)
S_IRGRP  (00040)  组内成员读取
S_IWGRP  (00020)  组内成员写入
S_IXGRP  (00010)  组内成员执行/搜索
S_IROTH  (00004)  其他用户读取
S_IWOTH  (00002)  其他用户写入
S_IXOTH  (00001)  其他用户执行/搜索


目录操作

目录的创建和销毁

int mkdir(const char *pathname, mode_t mode);

        创建一个新目录。如果目录的父目录不存在,或者没有足够的权限,函数将失败。

int rmdir(const char *pathname);

        删除一个空目录。如果目录非空,或者指定路径不存在,或者没有足够的权限,函数将失败。

更改当前工作路径

int chdir(const char *path);

        改变(切换)当前工作目录到指定的路径。如果路径不存在或没有足够的权限访问该路径,函数将失败。

int fchdir(int fd);

          改变当前工作目录到由文件描述符 fd 指向的目录。

char *getcwd(char *buf, size_t size);

         获取当前工作目录的绝对路径,并将其复制到由 buf 指向的缓冲区中。如果缓冲区大小不足以存储路径,函数将失败。

目录流操作

DIR *opendir(const char *name);
DIR *fdopendir(int fd);

        打开文件夹获取DIR流指针,失败返回NULL

struct dirent *readdir(DIR *dirp);struct dirent {ino_t d_ino;       /* inode编号 */off_t d_off;       /* 并非偏移量;详见下文 */unsigned short d_reclen; /* 此记录的长度 */unsigned char d_type; /* 文件类型;并非所有文件系统类型都支持 */char d_name[256]; /* 以空字符结尾的文件名 */};

        返回指向struct dirent指针,dirent里存储了目录的信息,失败返回空指针


日期和时间

1.time

time_t time(time_t *tloc);

        时间戳是从 1970 年 1 月 1 日(UTC 时间)开始计算的Unix 时间戳,tloc如果提供了这个参数,函数会将当前时间的时间戳存储在这个指针指向的位置。如果这个参数是 NULL 或者没有提供,函数不会写入任何值。

2.gmtime

struct tm *gmtime(const time_t *timep);struct tm {int tm_sec;    /* Seconds (0-60) */int tm_min;    /* Minutes (0-59) */int tm_hour;   /* Hours (0-23) */int tm_mday;   /* Day of the month (1-31) */int tm_mon;    /* Month (0-11) */int tm_year;   /* Year - 1900 */int tm_wday;   /* Day of the week (0-6, Sunday = 0) */int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */int tm_isdst;  /* Daylight saving time */
};

        Unix时间转为tm结构体,该结构体表示的是协调世界时UTC

3.localtime

struct tm *localtime(const time_t *timep);

        Unix时间转为tm结构体,会根据本地时区和夏令时调整来转换时间

4.strftime

size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

        根据给定的格式字符串,将 tm 结构体中的时间信息格式化为可读的字符串,并将其存储在提供的字符数组 s 中


参数
    s:指向字符数组的指针,用于存储格式化后的字符串。
    max:s 数组的最大长度,即可以存储的最大字符数,包括空字符('\0')。
    format:一个格式字符串,指定了时间的格式化方式。格式字符串中可以包含特殊的格式说明符,如 %Y 表示四位数的年份等。
    tm:指向 tm 结构体的指针,包含了要格式化的时间信息。

返回值
    函数返回实际写入到 s 数组中的字符数(不包括结尾的空字符)。如果由于缓冲区大小不足而无法写入整个字符串,返回值会小于 max。如果 s 是 NULL 或 max 是 0,则函数不执行格式化操作,但仍然会返回需要的缓冲区大小(不包括结尾的空字符)。

格式化说明符
    %a:缩写的星期名称。
    %A:完整的星期名称。
    %b:缩写的月份名称。
    %B:完整的月份名称。
    %c:适合人类可读的日期和时间。
    %d:月份中的第几天(01-31)。
    %H:小时(24小时制,00-23)。
    %I:小时(12小时制,01-12)。
    %m:月份(01-12)。
    %M:分钟(00-59)。
    %S:秒(00-59)。
    %Y:四位数的年份。


 /etc目录下的文件

/etc/passwd

        文件中的每行都包含一个用户账户的信息,字段之间用冒号(:)分隔。标准的字段包括:

        -用户名:用户的登录名。
        -密码:通常是一个“x”字符,表示密码存储在 /etc/shadow 文件中,或者是加密后的密码散列值。
        -用户ID(UID):用户的唯一标识符,通常是数字。
        -组ID(GID):用户所属主组的唯一标识符。
        -主目录:用户的主目录路径。
        -登录shell:用户登录时使用的 shell。

格式示例如下:
    username:x:UID:GID:User Name:/home/username:/bin/bash

具体解释如下:
    username:用户的登录名。
    x:表示密码存储在 /etc/shadow 文件中。
    UID:用户的唯一标识符。
    GID:用户所属主组的唯一标识符。
    User Name:用户的全名或描述。
    /home/username:用户的主目录路径。
    /bin/bash:用户的默认登录 shell。

struct passwd *getpwnam(const char *name);struct passwd {char   *pw_name;       /* username */char   *pw_passwd;     /* user password */uid_t   pw_uid;        /* user ID */gid_t   pw_gid;        /* group ID */char   *pw_gecos;      /* user information */char   *pw_dir;        /* home directory */char   *pw_shell;      /* shell program */
};

        通过用户名获取用户信息

struct passwd *getpwuid(uid_t uid);

        通过用户uid获取用户信息

etc/group

        是 Linux 和类 Unix 系统中的另一个重要文件,它用于存储用户组的信息。每个条目代表一个用户组,并且每行的字段通常由冒号(:)分隔。标准的字段包括:

        -组名:用户组的名称,通常不包含空格。
        -密码:用户组的加密密码,或者是一个“x”字符,表示密码存储在 /etc/gshadow 文件中。
        -组ID(GID):用户组的唯一标识符,是一个数字。
        -用户列表:属于该组的用户列表,可以是用户名或用户名的逗号分隔列表。

格式示例如下
         groupname:password:GID:user1,user2,user3

具体解释如下
    groupname:用户组的名称。
    password:用户组的加密密码,或者是一个“x”字符表示密码存储在 /etc/gshadow 文件中。
    GID:用户组的唯一标识符。
    user1,user2,user3:属于该组的用户列表,用户之间用逗号分隔。

struct group *getgrnam(const char *name);struct group {char   *gr_name;        /* group name */char   *gr_passwd;      /* group password */gid_t   gr_gid;         /* group ID */char  **gr_mem;         /* NULL-terminated array of pointersto names of group members */
};

        通过组名获取组信息

struct group *getgrgid(gid_t gid);

        通过组gid获取组信息

/etc/shadow

        文件在类 Unix 系统中用于存储用户账户的密码信息,以增强安全性。该文件通常只能由 root 用户访问,并且包含加密后的密码数据。每行对应一个用户,字段之间用冒号(:)分隔。标准的字段包括:

        -用户名:与 /etc/passwd 文件中的用户名相同。
        -加密密码:用户的加密密码或一个特定的值,如 * 或 !,表示账户被锁定或密码无效。
        -最后一次更改密码的日期:以从1970年1月1日(epoch)开始的天数计算。
        -密码最小更改间隔:用户必须等待的最小天数,才能再次更改密码。
        -密码最大有效期限:密码的最大有效天数。
        -密码警告期:在密码过期前,系统会警告用户的天数。
        密码到期后账户被禁用的天数:密码过期后,用户账户被禁用的天数。
        -预留字段:通常为空。

格式示例如下:
        username:$6$somehash$somehash:17000:0:99999:7:7:::

具体解释如下:
    username:用户的登录名。
    $6$somehash$somehash:加密的密码,其中 $6$ 表示使用的是 SHA-512 加密算法。
    17000:最后一次更改密码的日期(天数)。
    0:密码最小更改间隔。
    99999:密码最大有效期限。
    7:密码警告期。
    7:密码到期后账户被禁用的天数。
    :::预留字段,通常为空。


GLOB函数

int glob(const char *pattern, int flags,int (*errfunc) (const char *epath, int eerrno),glob_t *pglob);typedef struct {size_t gl_pathc;    /* 到目前为止匹配的路径数量 */char **gl_pathv;    /* 匹配的路径名列表 */size_t gl_offs;     /* 在 gl_pathv 中预留的槽位数 */
} glob_t;

参数说明:
--pattern:一个指向以null结尾的字符串的指针,指定了要匹配的文件名模式(文件路径)。模式可以包含如下特殊字符:
    *:匹配任意数量的字符。
    ?:匹配任意单个字符。
    [...]:匹配括号内的任意一个字符。

--flags:用于控制glob函数行为的标志位,可以是以下值的组合:
    GLOB_APPEND:如果pglob已经包含一些路径,新的路径将被追加到现有列表中,没有APPEND则是覆盖。
    GLOB_DOOFFS:减少分配给pglob->gl_pathv数组的内存量,数组大小为pglob->gl_pathc + 1。
    GLOB_ERR:如果发生错误并且提供了错误函数,函数将立即调用错误处理函数。
    GLOB_MARK:在每个匹配的路径名末尾添加一个斜杠(/)。
    GLOB_NOCHECK:如果模式没有匹配任何文件,返回空列表而不是GLOB_NOMATCH错误。
    GLOB_NOSORT:不按字母顺序对匹配的路径进行排序。

--errfunc:当出现错误并且GLOB_ERR标志被设置时,将调用此错误处理函数。该函数接受两个参数:错误路径和错误号。不需要错误检查时可以设置NULL。

--pglob:指向glob_t结构的指针,该结构用于存储匹配的路径列表和相关信息。


返回值
    成功时,返回 0。
    当没有找到匹配的文件名时,如果设置了GLOB_NOCHECK标志,返回 0,否则返回 GLOB_NOMATCH。
    发生错误时,返回非零错误代码。

void globfree(glob_t *pglob);

        销毁pglob申请空间,主要是char **gl_pathv;字符数组申请的空间 


利用glob实现du功能

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glob.h>
#include <string.h>#define PATHSIZE 128static path_noloop(const char *path) {char *pos;pos = strrchr(path, '/')'if(pos == NULL)exit(1);if(strcmp(pos+1, ".") == 0 || strcmp(pos+1, "..") == 0)return 0;return 1;
}static int64_t K_du(const char* path){struct stat statres;//非目录if(lstat(path, &statres) < 0 ){perror("lstat()");exit(1);}if(!S_ISDIR(statres.st_mode))return statres.st_blocks/2;//目录char *nextpath[PATHSIZE];glob_t globres;int sum = statres.st_blocks;strncpy(nextpath, path, PATHSIZE);strncat(nextpath, "/*", PATHSIZE);glob(nextpath, 0, NULL, &globres);strncpy(nextpath, path, PATHSIZE);strncat(nextpath, "/.*", PATHSIZE);glob(nextpath, GLOB_APPEND, NULL, &globres);for(int i = 0; i < globres.gl_pathc; i++){if(path_noloop(globres.gl_pathv[i]))sum += mydu(globres.gl_pathv[i]);}return sum;
}

利用glob实现shell的ls功能

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <glob.h>
#include <sys/wait.h>// 定义命令分隔符
#define DELIMS " \t\n"// 定义一个结构体,用于存储 glob 函数的返回结果
struct cmd_st {glob_t globres;
};// promopt 函数用于显示提示符
static void promopt(void) {printf("[myshell-knoci-1.2] $ ");
}// parse 函数用于解析用户输入的命令行
static void parse(char *line, struct cmd_st *cmd) {char *token;  // 用于存储分割出的每个单词int i = 0;    // 用于控制是否追加到 glob 结构// 使用 strsep 函数分割字符串,直到没有更多单词while(1) {token = strsep(&line, DELIMS);if (token == NULL)break;if(token[0] == '\0')  // 跳过空字符串continue;// 对每个分割出的单词进行 glob 匹配,第一个单词不追加,后续追加glob(token, GLOB_NOCHECK | (i ? GLOB_APPEND : 0), NULL, &cmd->globres);i = 1;}
}// 主函数
int main(int argc, char *argv[]) {char *linebuf = NULL;  // 用于存储 getline 读取的整行命令size_t linebuf_size = 0; // linebuf 的当前分配大小struct cmd_st cmd;      // 定义 cmd 结构用于存储 glob 结果// 初始化 glob 结构的指针和计数器cmd.globres.gl_pathv = NULL;cmd.globres.gl_pathc = 0;pid_t pid;  // 存储 fork 函数返回的子进程 ID// 无限循环,持续读取和执行用户命令while(1) {promopt();  // 显示提示符// 使用 getline 函数从标准输入读取一行if(getline(&linebuf, &linebuf_size, stdin) < 0)break;// 解析命令行parse(linebuf, &cmd);// 假设没有内部命令,所有命令都是外部命令pid = fork();  // 创建子进程if(pid < 0) {perror("fork");  // 显示 fork 出错信息exit(1);}// 在子进程中执行命令if(pid == 0) {// 子进程中调用 execvp 执行命令if(cmd.globres.gl_pathc > 0) {execvp(cmd.globres.gl_pathv[0], cmd.globres.gl_pathv);}perror("execvp");  // 如果 execvp 失败,显示错误信息exit(1);  // 退出子进程} else {// 父进程等待子进程结束int status;waitpid(pid, &status, 0);}}// 清理资源globfree(&cmd.globres);  // 释放 glob 分配的内存free(linebuf);  // 释放 getline 分配的内存exit(0);  // 正常退出程序
}

相关文章:

Linux系统编程-文件系统

目录 什么是Linux文件系统 文件系统的职责 存储介质抽象 inode&#xff1a;文件系统的核心 文件分配策略 目录结构 文件系统布局 日志和恢复机制 目录权限 粘滞位(t位)&#xff1a; 硬链接和符号链接 硬链接的特点&#xff1a; 创建硬链接&#xff1a; 符号链接的…...

【解决】ubuntu20.04 root用户无法SSH登陆问题

Ubuntu root用户无法登录的问题通常可以通过修改‌SSH配置文件和系统登录配置来解决。 修改SSH配置文件 sudo vim /etc/ssh/sshd_config 找到 PermitRootLogin 设置&#xff0c;并将其值更改为 yes 以允许root用户通过SSH登录 保存并关闭文件之后&#xff0c;需要重启SSH服务…...

(前缀和) LeetCode 238. 除自身以外数组的乘积

一. 题目描述 原题链接 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&…...

【JVM基础05】——组成-能不能解释一下方法区?

目录 1- 引言&#xff1a;方法区概述1-1 方法区是什么&#xff1f;(What)1-2 为什么用方法区&#xff1f;方法区的作用 (Why) 2- ⭐核心&#xff1a;详解方法区(How)2-1 能不能解释一下方法区&#xff1f;2-2 元空间内存溢出问题2-3 什么是常量池&#xff1f;2-4 运行时常量池 …...

前端:Vue学习-3

前端&#xff1a;Vue学习-3 1. 自定义指令2. 插槽2.1 插槽 - 后备内容&#xff08;默认值&#xff09;2.2 插槽 - 具名插槽2.3 插槽 - 作用域插槽 3. Vue - 路由3.1 路由模块封装3.2 声明式导航 router-link 高亮3.3 自定义匹配的类名3.4 声明式导肮 - 跳转传参3.5 Vue路由 - 重…...

npm 安装报错(已解决)+ 运行 “wue-cli-service”不是内部或外部命令,也不是可运行的程序(已解决)

首先先说一下我这个项目是3年前的一个项目了&#xff0c;中间也是经过了多个人的修改惨咋了布置多少个人的思想&#xff0c;这这道我手里直接npm都安装不上&#xff0c;在网上也查询了多种方法&#xff0c;终于是找到问题所在了 问题1&#xff1a; 先是npm i 报错在下面图片&…...

江苏科技大学24计算机考研数据速览,有专硕复试线大幅下降67分!

江苏科技大学&#xff08;Jiangsu University of Science and Technology&#xff09;&#xff0c;坐落在江苏省镇江市&#xff0c;是江苏省重点建设高校&#xff0c;江苏省人民政府与中国船舶集团有限公司共建高校&#xff0c;国家国防科技工业局与江苏省人民政府共建高校 &am…...

20分钟上手新版Skywalking 9.x APM监控系统

Skywalking https://skywalking.apache.org/ Skywalking是专为微服务、云原生和基于容器的&#xff08;Kubernetes&#xff09;架构设计的分布式系统性能监控工具。 Skywalking关键特性 ● 分布式跟踪 ○ 端到端分布式跟踪。服务拓扑分析、以服务为中心的可观察性和API仪表板。…...

【07】LLaMA-Factory微调大模型——微调模型导出与微调参数分析

上文介绍了如何对微调后的模型进行使用与简单评估。本文将介绍对微调后的模型进行导出的过程。 一、llama-3微调后的模型导出 首先进入虚拟环境&#xff0c;打开LLaMA-Factory的webui页面 conda activate GLM cd LLaMA-Factory llamafactory-cli webui 之后&#xff0c;选择…...

动态路由协议 —— EIGRP 与 OSPF 的区别

EIGRP&#xff08;增强内部网关路由协议&#xff09;和 OSPF&#xff08;开放式最短路径优先&#xff09;是两种最常见的动态路由协议&#xff0c;主要是用来指定路由器或交换机之间如何通信。将其应用于不同的情况下&#xff0c;可提高速率、延迟等方面的性能。那么它们之间到…...

【中项】系统集成项目管理工程师-第5章 软件工程-5.1软件工程定义与5.2软件需求

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…...

HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 多选题序号1

基础认证题库请移步&#xff1a;HarmonyOS应用开发者基础认证题库 注&#xff1a;有读者反馈&#xff0c;题库的代码块比较多&#xff0c;打开文章时会卡死。所以笔者将题库拆分&#xff0c;单选题20个为一组&#xff0c;多选题10个为一组&#xff0c;题库目录如下&#xff0c;…...

Windows11(24H2)LTSC长期版下载!提前曝光Build26100?

系统&#xff1b;windows11 文章目录 前言一、LTSC是什么&#xff1f;二、 Windows 11 Vision 24H2 LTSC 的版本号为 Build 26100&#xff0c;镜像中提供以下三个 SKU&#xff1a;总结 前言 好的系统也能给你带来不一样的效果。 一、LTSC是什么&#xff1f; & & L…...

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十三章 驱动模块传参

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...

uniapp 小程序 支付逻辑处理

uniapp 小程序 支付逻辑处理 上代码如果你不需要支付宝适配&#xff0c;可以删除掉支付宝的条件判断代码 <button class"subBtn" :disabled"submiting" click"goPay">去支付</button>// 以下代码你需要改的地方// 1. order/app/v1…...

scikit-learn库学习之make_regression函数

scikit-learn库学习之make_regression函数 一、简介 make_regression是scikit-learn库中用于生成回归问题数据集的函数。它主要用于创建合成的回归数据集&#xff0c;以便在算法的开发和测试中使用。 二、语法和参数 sklearn.datasets.make_regression(n_samples100, n_feat…...

经典文献阅读之--World Models for Autonomous Driving(自动驾驶的世界模型:综述)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…...

孙健提到的实验室的研究方向之一是什么?()

孙健提到的实验室的研究方向之一是什么?&#xff08;&#xff09; 点击查看答案 A.虚拟现实B.环境感知和理解 C.智能体博弈D.所有选项都正确 图灵奖是在哪一年设立的?&#xff08;&#xff09; A.1962B.1966 C.1976D.1986 孙健代表的实验室的前身主要研究什么?&…...

初级java每日一道面试题-2024年7月23日-Iterator和ListIterator有什么区别?

面试官: Iterator和ListIterator有什么区别? 我回答: Iterator和ListIterator都是Java集合框架中用于遍历集合元素的接口&#xff0c;但它们之间存在一些关键的区别&#xff0c;主要体现在功能和使用场景上。下面我将详细解释这两种迭代器的不同之处&#xff1a; 1. Iterat…...

2024-07-23 Unity AI行为树2 —— 项目介绍

文章目录 1 项目介绍2 AI 代码介绍2.1 BTBaseNode / BTControlNode2.2 动作/条件节点2.3 选择 / 顺序节点 3 怪物实现4 其他功能5 UML 类图 项目借鉴 B 站唐老狮 2023年直播内容。 点击前往唐老狮 B 站主页。 1 项目介绍 ​ 本项目使用 Unity 2022.3.32f1c1&#xff0c;实现基…...

Unity-URP-SSAO记录

勾选After Opacity Unity-URP管线&#xff0c;本来又一个“bug”, 网上查不到很多关于ssao的资料 以为会不会又是一个极度少人用的东西 而且几乎都是要第三方替代 也完全没有SSAO大概的消耗是多少&#xff0c;完全是黑盒(因为用的人少&#xff0c;研究的人少&#xff0c;优…...

无人机上磁航技术详解

磁航技术&#xff0c;也被称为地磁导航&#xff0c;是一种利用地球磁场信息来实现导航的技术。在无人机领域&#xff0c;磁航技术主要用于辅助惯性导航系统&#xff08;INS&#xff09;进行航向角的测量与校正&#xff0c;提高无人机的飞行稳定性和准确性。其技术原理是&#x…...

使用 cURL 命令测试网站响应时间

文章目录 使用 cURL 命令测试网站响应时间工具介绍cURL 命令详解命令参数说明输出格式说明示例运行结果总结使用 cURL 命令测试网站响应时间 本文将介绍如何使用 cURL 命令行工具来测试一个网站的响应时间。具体来说,我们将使用 cURL 命令来测量并显示各种网络性能指标,包括 …...

「网络通信」HTTP 协议

HTTP &#x1f349;简介&#x1f349;抓包工具&#x1f349;报文结构&#x1f34c;请求&#x1f34c;响应&#x1f34c;URL&#x1f95d;URL encode &#x1f34c;方法&#x1f34c;报文字段&#x1f95d;Host&#x1f95d;Content-Length & Content-Type&#x1f95d;User…...

科普文:后端性能优化的实战小结

一、背景与效果 ICBU的核心沟通场景有了10年的“积累”&#xff0c;核心场景的界面响应耗时被拉的越来越长&#xff0c;也让性能优化工作提上了日程&#xff0c;先说结论&#xff0c;经过这一波前后端齐心协力的优化努力&#xff0c;两个核心界面90分位的数据&#xff0c;FCP平…...

LeetCode-day23-3098. 求出所有子序列的能量和

LeetCode-day23-3098. 求出所有子序列的能量和 题目描述示例示例1&#xff1a;示例2&#xff1a;示例3&#xff1a; 思路代码 题目描述 给你一个长度为 n 的整数数组 nums 和一个 正 整数 k 。 一个 子序列的 能量 定义为子序列中 任意 两个元素的差值绝对值的 最小值 。 请…...

CSS3雷达扫描效果

CSS3雷达扫描效果https://www.bootstrapmb.com/item/14840 要创建一个CSS3的雷达扫描效果&#xff0c;我们可以使用CSS的动画&#xff08;keyframes&#xff09;和transform属性。以下是一个简单的示例&#xff0c;展示了如何创建一个类似雷达扫描的动画效果&#xff1a; HTM…...

单例模式懒汉模式和饿汉模式

线程安全 单例模式在单线程中&#xff0c;当然是安全的。但是如果在多线程中&#xff0c;由于并行判断&#xff0c;可能会导致创建多个实例。那么如何保证在多线程中单例还是只有一个实例呢? 常见的三种方式: 局部静态变量 原理和饿汉模式相似&#xff0c;利用static只会初始…...

python __repr__和__str__区别

1. __repr__ __repr__ 方法由 repr() 内置函数调用&#xff0c;用于计算对象的“正式”字符串表示形式。理想情况下&#xff0c;这个字符串应该看起来像一个有效的 Python 表达式&#xff0c;可以在适当的环境下用来重新创建具有相同值的对象。如果这不可能实现&#xff0c;那…...

huawei USG6001v1学习----NAT和智能选路

目录 1.NAT的分类 2.智能选路 1.就近选路 2.策略路由 3.智能选路 NAT:&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09; 指网络地址转换&#xff0c;1994年提出的。NAT是用于在本地网络中使用私有地址&#xff0c;在连接互联网时转而使用全局…...

FPGA JTAG最小系统 EP2C5T144C8N

FPGA的文档没有相应的基础还真不容易看懂&#xff0c;下面是B站上对FPGA文档的解读(本文非对文档解读&#xff0c;只是为个人记录第三期&#xff1a;CycloneIV E最小系统板设计&#xff08;一&#xff09;从Datasheet上获取FPGA的基本参数_哔哩哔哩_bilibili 电源部份 核心电…...

Android 15 之如何快速适配 16K Page Size

在此之前&#xff0c;我们通过 《Android 15 上 16K Page Size 为什么是最坑》 介绍了&#xff1a; 什么是16K Page Size为什么它对于 Android 很坑如何测试 如果你还没了解&#xff0c;建议先去了解下前文&#xff0c;然后本篇主要是提供适配的思路&#xff0c;因为这类适配…...

学习unity官方的网络插件Netcode【一】

对bool值的个人理解&#xff1a; using Unity.Netcode; using UnityEngine; //个人理解&#xff1a;通过Rpc完成了一次客户端给服务端发消息&#xff0c;服务端再向所有客户端广播消息 public class RpcTest : NetworkBehaviour {public override void OnNetworkSpawn(){if (!…...

QT写一个mainWindow

切换风格的写法&#xff1a; 先看看样式效果&#xff1a; mian_window.h文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();void Ini…...

Java查找算法练习(2024.7.23)

顺序查找 package SearchExercise20240723; import java.util.Scanner; public class SearchExercise {public static void main(String[] args) {Scanner sc new Scanner(System.in);System.out.println("需要多大的数组?");int size sc.nextInt();int[] array …...

洗地机哪个牌子好?四款口碑最好的洗地机排名推荐

随着“懒人经济”的出现&#xff0c;越来越多的人开始使用洗地机。洗地机哪个牌子好&#xff1f;为了帮助大家在这个琳琅满目的市场中做出明智决策&#xff0c;本文特别整理了四款口碑最好的洗地机排名推荐&#xff0c;它们凭借出色的清洁效果、智能化的操作体验以及用户的高度…...

如何提升短视频的曝光量和获客效能?云微客来解决

在流量至上的当下&#xff0c;短视频凭借其优势&#xff0c;迅速成为了众多企业获客引流的核心营销手段。进入短视频赛道后&#xff0c;如何提升短视频的曝光量和获客效能&#xff0c;就成为了众多企业亟待解决的焦点。 如果你不想投入大量的广告预算&#xff0c;还想在短视频平…...

SpringBoot开发中如何缓存数据, 减少数据库的访问频率?

一&#xff1a;自定义是否开启缓存 方法一&#xff1a; 在不同环境的配置文件中如application-dev.yml、application-test.yml、application-prod.yml&#xff0c;修改 spring.cache.type none; spring:cache:type: none 方法二&#xff1a; 自定义配置 application.yml&…...

PostgreSQL如何在windows/linux开启归档

linux开启归档&#xff1a; archive_mode onarchive_command test ! -f /mnt/pg12/archivedir/%f && cp %p /mnt/pg12/archivedir/%fwindows开启归档&#xff1a; archive_mode onarchive_command copy "%p" "C:\\server\\pg12\\archivedir\\%f&q…...

【启明智显分享】基于国产Model3芯片的7寸触摸屏助力智慧医疗,电子床头屏提升护理交互

未来医院必然是以信息化为基础&#xff0c;以物联网为特征&#xff0c;以医疗为核心的服务型医院。病房作为医院的重要服务场所&#xff0c;成为智慧医院建设的重要一环。 为提高医护人员与患者的互动交流&#xff0c;给医疗注入智慧元素&#xff0c;让患者享受智能服务&#…...

从理论到实践:如何用 TDengine 打造完美数据模型​

在用 TDengine 进行数据建模之前&#xff0c;我们需要回答两个关键问题&#xff1a;建模的目标用户是谁&#xff1f;他们的具体需求是什么&#xff1f;在一个典型的时序数据管理方案中&#xff0c;数据采集和数据应用是两个主要环节。如下图所示&#xff1a; 对于数据采集工程师…...

可以免费合并pdf的软件 合并pdf文件的软件免费 合并pdf的软件免费

在数字化办公的今天&#xff0c;pdf格式因其稳定性和跨平台兼容性被广泛使用。然而&#xff0c;当我们需要将多个 pdf 文件合并为一个时&#xff0c;却往往感到力不从心。本文将为你介绍几款强大的pdf文件合并软件&#xff0c;让你轻松管理文档。 方法一、使用pdf转换器 步骤1…...

【排序 滑动窗口 】1498. 满足条件的子序列数目

本文涉及至知识点 排序 C算法&#xff1a;滑动窗口总结 LeetCode1498. 满足条件的子序列数目 给你一个整数数组 nums 和一个整数 target 。 请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。 由于答案可能很大&#xff0c;…...

RabbitMQ普通集群搭建指南

RabbitMQ普通集群搭建指南 本文已经完全迁移至&#xff0c;www.geekery.cn 后续不在此更新 目标架构 本次搭建的目标是构建一个由三个节点组成的RabbitMQ集群&#xff0c;节点信息如下&#xff1a; rabbit02: IP地址 192.168.10.132rabbit03: IP地址 192.168.10.133rabbit04:…...

AGV平面坐标系变换公式及实例

1、AGV坐标系简介 如上图&#xff0c;小车前后对角是有激光雷达的&#xff0c;其坐标系称为激光坐标系&#xff0c;采用极坐标系体现。中间为车体坐标系&#xff0c;激光坐标系相对于车体坐标系关系不变&#xff1b;左下角是地图坐标系&#xff0c;小车扫图后&#xff0c;建立的…...

es切片和集群

解决单点故障 支持高并发 解决海量数据 1.cluster 集群&#xff1a;包含多个节点&#xff0c;每个节点属于哪个集群是通过一个集群名称&#xff08;集群名称&#xff0c;默认是elasticsearch&#xff09;来决定的&#xff0c;对于中小型应用来说&#xff0c;刚开始一个集群就…...

IEEE官方列表会议 | 第三届能源与环境工程国际会议(CFEEE 2024)

会议简介 Brief Introduction 2024年第三届能源与环境工程国际会议(CFEEE 2024) 会议时间&#xff1a;2024年12月2日-4日 召开地点&#xff1a;澳大利亚凯恩斯 大会官网&#xff1a;CFEEE 2024-2024 International Conference on Frontiers of Energy and Environment Engineer…...

深度学习中的正则化技术 - Dropout篇

序言 在深度学习的浩瀚领域中&#xff0c;模型过拟合一直是研究者们面临的挑战之一。当模型在训练集上表现得近乎完美&#xff0c;却难以在未见过的数据&#xff08;测试集&#xff09;上保持同样优异的性能时&#xff0c;过拟合现象便悄然发生。为了有效缓解这一问题&#xf…...

《昇思 25 天学习打卡营第 18 天 | 扩散模型(Diffusion Models) 》

《昇思 25 天学习打卡营第 18 天 | 扩散模型&#xff08;Diffusion Models&#xff09; 》 活动地址&#xff1a;https://xihe.mindspore.cn/events/mindspore-training-camp 签名&#xff1a;Sam9029 扩散模型&#xff08;Diffusion Models&#xff09; 扩散模型概述 扩散模…...

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口

文章目录 前言一、Elasticsearch倒排索引 二、Docker 搭建 ESDocker 安装Docker 搭建 ES 三、ES基础语法创建索引查看索引删除索引添加数据查询数据修改数据删除数据条件查询分页查询排序 多条件查询andor 范围查询 四、ES在项目中的应用示例 前言 在数据驱动的时代&#xff0c…...