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

块设备的两种访问方法的区别

概述

1.当我们运行类似于“dd if=/dev/sdb1of=sdb1.img”的命令把整个/dev/sdb1裸分区复制到sdb1.img的时候,内核走的是def_blk_fops这个file_operations

2.另外一种方法是通过文件系统来访问块设备,file_operations的实现则位于文件系统内,文件系统会把针对文件的读写转换为针对块设备原始扇区的读写。ext2、fat、Btrfs等文件系统中会实现针对VFS的file_operations成员函数,设备驱动层将看不到file_operations的存在

块设备节点文件

如 /dev/sdb1,直接对应于磁盘分区或整个磁盘。这些设备文件由内核的块设备层直接管理,使用 def_blk_fops 文件操作集;在open前因为mknod调用的init_special_inode初始化节点的时候指定了inode->i_fop = &def_blk_fops;

mknoddo_mknodatvfs_mknodshmem_mknodshmem_get_inodeinit_special_inode
void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{inode->i_mode = mode;if (S_ISCHR(mode)) {inode->i_fop = &def_chr_fops;inode->i_rdev = rdev;} else if (S_ISBLK(mode)) {if (IS_ENABLED(CONFIG_BLOCK))inode->i_fop = &def_blk_fops;inode->i_rdev = rdev;} else if (S_ISFIFO(mode))inode->i_fop = &pipefifo_fops;else if (S_ISSOCK(mode));	/* leave it no_open_fops */elseprintk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"" inode %s:%lu\n", mode, inode->i_sb->s_id,inode->i_ino);
}

文件系统文件

/path/to/file,位于文件系统中,由文件系统驱动程序(如 ubifs)管理,inode创建的时候赋予特定的文件操作集(如 ubifs_file_operations);如下述会通过”inode->i_fop = &ubifs_file_operations;“给inode赋予特定的文件操作函数

ubifs_new_inode

struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,umode_t mode)
{int err;struct inode *inode;struct ubifs_inode *ui;bool encrypted = false;if (ubifs_crypt_is_encrypted(dir)) {err = fscrypt_get_encryption_info(dir);if (err) {ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err);return ERR_PTR(err);}if (!fscrypt_has_encryption_key(dir))return ERR_PTR(-EPERM);encrypted = true;}inode = new_inode(c->vfs_sb);ui = ubifs_inode(inode);if (!inode)return ERR_PTR(-ENOMEM);/** Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and* marking them dirty in file write path (see 'file_update_time()').* UBIFS has to fully control "clean <-> dirty" transitions of inodes* to make budgeting work.*/inode->i_flags |= S_NOCMTIME;inode_init_owner(inode, dir, mode);inode->i_mtime = inode->i_atime = inode->i_ctime =current_time(inode);inode->i_mapping->nrpages = 0;switch (mode & S_IFMT) {case S_IFREG:inode->i_mapping->a_ops = &ubifs_file_address_operations;inode->i_op = &ubifs_file_inode_operations;inode->i_fop = &ubifs_file_operations;break;case S_IFDIR:inode->i_op  = &ubifs_dir_inode_operations;inode->i_fop = &ubifs_dir_operations;inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ;break;case S_IFLNK:inode->i_op = &ubifs_symlink_inode_operations;break;case S_IFSOCK:case S_IFIFO:case S_IFBLK:case S_IFCHR:inode->i_op  = &ubifs_file_inode_operations;encrypted = false;break;default:BUG();}ui->flags = inherit_flags(dir, mode);ubifs_set_inode_flags(inode);if (S_ISREG(mode))ui->compr_type = c->default_compr;elseui->compr_type = UBIFS_COMPR_NONE;ui->synced_i_size = 0;spin_lock(&c->cnt_lock);/* Inode number overflow is currently not supported */if (c->highest_inum >= INUM_WARN_WATERMARK) {if (c->highest_inum >= INUM_WATERMARK) {spin_unlock(&c->cnt_lock);ubifs_err(c, "out of inode numbers");make_bad_inode(inode);iput(inode);return ERR_PTR(-EINVAL);}ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",(unsigned long)c->highest_inum, INUM_WATERMARK);}inode->i_ino = ++c->highest_inum;/** The creation sequence number remains with this inode for its* lifetime. All nodes for this inode have a greater sequence number,* and so it is possible to distinguish obsolete nodes belonging to a* previous incarnation of the same inode number - for example, for the* purpose of rebuilding the index.*/ui->creat_sqnum = ++c->max_sqnum;spin_unlock(&c->cnt_lock);if (encrypted) {err = fscrypt_inherit_context(dir, inode, &encrypted, true);if (err) {ubifs_err(c, "fscrypt_inherit_context failed: %i", err);make_bad_inode(inode);iput(inode);return ERR_PTR(err);}}return inode;
}

MTD

嵌入式系统最常用的qspi-flash,一般作为MTD设备,在其上又使用UBIFS来减少闪存的磨损

mount

比如mount文件系统的时候,会挂载文件系统到一个根目录,这个目录也会通过ubifs_new_inode来创建一个inode,mount流程如下

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 38fe20f6e..1239fad37 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -90,7 +90,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,{struct inode *inode;struct ubifs_inode *ui;
-
+       static bool once = true;
+       if(once){
+               dump_stack();
+               once = false;
+       }inode = new_inode(c->vfs_sb);ui = ubifs_inode(inode);if (!inode)[    4.181047] [<c00198e9>] (unwind_backtrace+0x1/0x88) from [<c0017e5f>] (show_stack+0xb/0xc)
[    4.205935] [<c0017e5f>] (show_stack+0xb/0xc) from [<c00b289f>] (ubifs_new_inode+0x17/0x218)
[    4.242626] [<c00b289f>] (ubifs_new_inode+0x17/0x218) from [<c00b2c69>] (ubifs_mkdir+0x41/0x138)
[    4.251746] [<c00b2c69>] (ubifs_mkdir+0x41/0x138) from [<c00776f7>] (vfs_mkdir+0x47/0x74)
[    4.276054] [<c00776f7>] (vfs_mkdir+0x47/0x74) from [<c00d6c1d>] (ovl_create_real+0x5d/0x94)
[    4.284503] [<c00d6c1d>] (ovl_create_real+0x5d/0x94) from [<c00d5dc3>] (ovl_workdir_create+0x83/0x100)
[    4.310915] [<c00d5dc3>] (ovl_workdir_create+0x83/0x100) from [<c00d60b7>] (ovl_fill_super+0x1a3/0x34c)
[    4.320431] [<c00d60b7>] (ovl_fill_super+0x1a3/0x34c) from [<c00732d5>] (mount_nodev+0x25/0x60)
[    4.335254] [<c00732d5>] (mount_nodev+0x25/0x60) from [<c00738a1>] (mount_fs+0x9/0x7c)
[    4.343245] [<c00738a1>] (mount_fs+0x9/0x7c) from [<c0081ea3>] (vfs_kern_mount+0x53/0xb0)
[    4.352334] [<c0081ea3>] (vfs_kern_mount+0x53/0xb0) from [<c00832cd>] (do_mount+0x509/0x5a4)
[    4.362857] [<c00832cd>] (do_mount+0x509/0x5a4) from [<c00833b9>] (SyS_mount+0x51/0x72)
[    4.372007] [<c00833b9>] (SyS_mount+0x51/0x72) from [<c0009081>] (ret_fast_syscall+0x1/0x46)

创建文件

应用层通过touch命令,或者create或者open函数调用创建文件时,本质open系统调用带O_CREAT的flag来执行创建的操作

SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
{return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
}
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{if (force_o_largefile())flags |= O_LARGEFILE;return do_sys_open(AT_FDCWD, filename, flags, mode);
}

open具体获取inode的具体流程如下

do_sys_opendo_filp_openpath_openat
static struct file *path_openat(struct nameidata *nd,const struct open_flags *op, unsigned flags)
{const char *s;struct file *file;int opened = 0;int error;file = get_empty_filp();if (IS_ERR(file))return file;file->f_flags = op->open_flag;if (unlikely(file->f_flags & __O_TMPFILE)) { /*处理临时文件*/error = do_tmpfile(nd, flags, op, file, &opened);goto out2;}if (unlikely(file->f_flags & O_PATH)) { /*打开一个文件或目录的路径,但不进行实际的读写操作*/error = do_o_path(nd, flags, file);if (!error)opened |= FILE_OPENED;goto out2;}s = path_init(nd, flags); /*初始化路径*/if (IS_ERR(s)) {put_filp(file);return ERR_CAST(s);}while (!(error = link_path_walk(s, nd)) && /* 获取不同文件系统的inode的具体实现*/(error = do_last(nd, file, op, &opened)) > 0) { /*创建或打开文件*/nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);s = trailing_symlink(nd);if (IS_ERR(s)) {error = PTR_ERR(s);break;}}terminate_walk(nd);
out2:if (!(opened & FILE_OPENED)) {BUG_ON(!error);put_filp(file);}if (unlikely(error)) {if (error == -EOPENSTALE) {if (flags & LOOKUP_RCU)error = -ECHILD;elseerror = -ESTALE;}file = ERR_PTR(error);}return file;
}

获取inode

 link_path_walk最终调用到ubiffs_iget来获取inode ;通过fast和slow两种方式来查找或者创建inode;并初始化inodef的i_fops:inode->i_fop = &ubifs_file_operations; 对不同文件属性赋值不同操作函数

link_path_walkwalk_componentlookup_fast //用缓存中的 dentry 来避免不必要的磁盘访问,从而提高路径解析的效率lookup_slow //它在缓存中找不到匹配的 dentry 时被调用,需要通过文件系统的特定方法来查找或创建 dentry 和 inodeinode->i_op->lookup(inode, dentry, flags); ubifs_lookupubifs_igetstruct inode *ubifs_iget(struct super_block *sb, unsigned long inum)
{int err;union ubifs_key key;struct ubifs_ino_node *ino;struct ubifs_info *c = sb->s_fs_info;struct inode *inode;struct ubifs_inode *ui;dbg_gen("inode %lu", inum);inode = iget_locked(sb, inum);if (!inode)return ERR_PTR(-ENOMEM);if (!(inode->i_state & I_NEW))return inode;ui = ubifs_inode(inode);ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS);if (!ino) {err = -ENOMEM;goto out;}ino_key_init(c, &key, inode->i_ino);err = ubifs_tnc_lookup(c, &key, ino);if (err)goto out_ino;inode->i_flags |= S_NOCMTIME;
#ifndef CONFIG_UBIFS_ATIME_SUPPORTinode->i_flags |= S_NOATIME;
#endifset_nlink(inode, le32_to_cpu(ino->nlink));i_uid_write(inode, le32_to_cpu(ino->uid));i_gid_write(inode, le32_to_cpu(ino->gid));inode->i_atime.tv_sec  = (int64_t)le64_to_cpu(ino->atime_sec);inode->i_atime.tv_nsec = le32_to_cpu(ino->atime_nsec);inode->i_mtime.tv_sec  = (int64_t)le64_to_cpu(ino->mtime_sec);inode->i_mtime.tv_nsec = le32_to_cpu(ino->mtime_nsec);inode->i_ctime.tv_sec  = (int64_t)le64_to_cpu(ino->ctime_sec);inode->i_ctime.tv_nsec = le32_to_cpu(ino->ctime_nsec);inode->i_mode = le32_to_cpu(ino->mode);inode->i_size = le64_to_cpu(ino->size);ui->data_len    = le32_to_cpu(ino->data_len);ui->flags       = le32_to_cpu(ino->flags);ui->compr_type  = le16_to_cpu(ino->compr_type);ui->creat_sqnum = le64_to_cpu(ino->creat_sqnum);ui->xattr_cnt   = le32_to_cpu(ino->xattr_cnt);ui->xattr_size  = le32_to_cpu(ino->xattr_size);ui->xattr_names = le32_to_cpu(ino->xattr_names);ui->synced_i_size = ui->ui_size = inode->i_size;ui->xattr = (ui->flags & UBIFS_XATTR_FL) ? 1 : 0;err = validate_inode(c, inode);if (err)goto out_invalid;switch (inode->i_mode & S_IFMT) {case S_IFREG:inode->i_mapping->a_ops = &ubifs_file_address_operations;inode->i_op = &ubifs_file_inode_operations;inode->i_fop = &ubifs_file_operations;if (ui->xattr) {ui->data = kmalloc(ui->data_len + 1, GFP_NOFS);if (!ui->data) {err = -ENOMEM;goto out_ino;}memcpy(ui->data, ino->data, ui->data_len);((char *)ui->data)[ui->data_len] = '\0';} else if (ui->data_len != 0) {err = 10;goto out_invalid;}break;case S_IFDIR:inode->i_op  = &ubifs_dir_inode_operations;inode->i_fop = &ubifs_dir_operations;if (ui->data_len != 0) {err = 11;goto out_invalid;}break;case S_IFLNK:inode->i_op = &ubifs_symlink_inode_operations;if (ui->data_len <= 0 || ui->data_len > UBIFS_MAX_INO_DATA) {err = 12;goto out_invalid;}ui->data = kmalloc(ui->data_len + 1, GFP_NOFS);if (!ui->data) {err = -ENOMEM;goto out_ino;}memcpy(ui->data, ino->data, ui->data_len);((char *)ui->data)[ui->data_len] = '\0';break;case S_IFBLK:case S_IFCHR:{dev_t rdev;union ubifs_dev_desc *dev;ui->data = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);if (!ui->data) {err = -ENOMEM;goto out_ino;}dev = (union ubifs_dev_desc *)ino->data;if (ui->data_len == sizeof(dev->new))rdev = new_decode_dev(le32_to_cpu(dev->new));else if (ui->data_len == sizeof(dev->huge))rdev = huge_decode_dev(le64_to_cpu(dev->huge));else {err = 13;goto out_invalid;}memcpy(ui->data, ino->data, ui->data_len);inode->i_op = &ubifs_file_inode_operations;init_special_inode(inode, inode->i_mode, rdev);break;}case S_IFSOCK:case S_IFIFO:inode->i_op = &ubifs_file_inode_operations;init_special_inode(inode, inode->i_mode, 0);if (ui->data_len != 0) {err = 14;goto out_invalid;}break;default:err = 15;goto out_invalid;}kfree(ino);ubifs_set_inode_flags(inode);unlock_new_inode(inode);return inode;out_invalid:ubifs_err(c, "inode %lu validation failed, error %d", inode->i_ino, err);ubifs_dump_node(c, ino);ubifs_dump_inode(c, inode);err = -EINVAL;
out_ino:kfree(ino);
out:ubifs_err(c, "failed to read inode %lu, error %d", inode->i_ino, err);iget_failed(inode);return ERR_PTR(err);
}

将file的fop赋值为inode的fop

里面的f->f_op = fops_get(inode->i_fop);对于/dev下的设备文件就是把上面init_special_inode里的inode->i_fop = &def_blk_fops;def_blk_fops的open为blkdev_open,它又会调用块设备驱动实现的的open;对于在文件系统中touch或者creat的文件,就是文件系统实现的fops

do_sys_opendo_filp_openpath_openatvfs_open do_dentry_openstatic int do_dentry_open(struct file *f,struct inode *inode,int (*open)(struct inode *, struct file *))
{static const struct file_operations empty_fops = {};int error;path_get(&f->f_path);f->f_inode = inode;f->f_mapping = inode->i_mapping;/* Ensure that we skip any errors that predate opening of the file */f->f_wb_err = filemap_sample_wb_err(f->f_mapping);if (unlikely(f->f_flags & O_PATH)) {f->f_mode = FMODE_PATH | FMODE_OPENED;f->f_op = &empty_fops;return 0;}/* Any file opened for execve()/uselib() has to be a regular file. */if (unlikely(f->f_flags & FMODE_EXEC && !S_ISREG(inode->i_mode))) {error = -EACCES;goto cleanup_file;}if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {error = get_write_access(inode);if (unlikely(error))goto cleanup_file;error = __mnt_want_write(f->f_path.mnt);if (unlikely(error)) {put_write_access(inode);goto cleanup_file;}f->f_mode |= FMODE_WRITER;}/* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))f->f_mode |= FMODE_ATOMIC_POS;f->f_op = fops_get(inode->i_fop);if (WARN_ON(!f->f_op)) {error = -ENODEV;goto cleanup_all;}error = security_file_open(f);if (error)goto cleanup_all;error = break_lease(locks_inode(f), f->f_flags);if (error)goto cleanup_all;/* normally all 3 are set; ->open() can clear them if needed */f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;if (!open)open = f->f_op->open;if (open) {error = open(inode, f);if (error)goto cleanup_all;}f->f_mode |= FMODE_OPENED;if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)i_readcount_inc(inode);if ((f->f_mode & FMODE_READ) &&likely(f->f_op->read || f->f_op->read_iter))f->f_mode |= FMODE_CAN_READ;if ((f->f_mode & FMODE_WRITE) &&likely(f->f_op->write || f->f_op->write_iter))f->f_mode |= FMODE_CAN_WRITE;f->f_write_hint = WRITE_LIFE_NOT_SET;f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);/* NB: we're sure to have correct a_ops only after f_op->open */if (f->f_flags & O_DIRECT) {if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)return -EINVAL;}/** XXX: Huge page cache doesn't support writing yet. Drop all page* cache for this file before processing writes.*/if ((f->f_mode & FMODE_WRITE) && filemap_nr_thps(inode->i_mapping))truncate_pagecache(inode, 0);return 0;cleanup_all:if (WARN_ON_ONCE(error > 0))error = -EINVAL;fops_put(f->f_op);if (f->f_mode & FMODE_WRITER) {put_write_access(inode);__mnt_drop_write(f->f_path.mnt);}
cleanup_file:path_put(&f->f_path);f->f_path.mnt = NULL;f->f_path.dentry = NULL;f->f_inode = NULL;return error;
}

文件相关结构体

dentry

表示目录条目,用于路径解析(将路径名转换为文件系统中的实际位置)和缓存(缓存最近访问的目录项),维护文件和目录之间的链接关系

d_name:文件名或目录名。
d_inode:指向该 dentry 对应的 inode。
d_parent:指向父目录的 dentry。
d_subdirs:指向子目录的链表头。
d_u:用于缓存或其他用途的联合体。
d_sb:指向文件系统的超级块(super_block)。
d_flags:标志位,用于控制 dentry 的行为。
d_count:引用计数。
d_lockref:锁和引用计数。
d_vfs_flags:VFS 标志。
d_alias:用于哈希表的链表头

inode

表示文件或目录的元数据,如文件类型、权限、时间戳;用于存储文件属性和操作函数。

i_ino:inode 编号,唯一标识一个 inode。
i_mode:文件类型和权限。
i_uid:文件所有者的用户 ID。
i_gid:文件所有者的组 ID。
i_size:文件大小。
i_atime:上次访问时间。
i_mtime:上次修改时间。
i_ctime:上次状态改变时间。
i_links_count:硬链接数。
i_blocks:文件占用的块数。
i_blkbits:块大小的对数值。
i_op:inode 操作指针。
i_fop:文件操作指针。
i_mapping:地址空间映射。
i_private:私有数据。
i_sb:指向文件系统的超级块(super_block)。

file

表示打开文件,用于文件操作和状态管理。

f_path:指向文件的路径(path),包含 mnt 和 dentry。
f_inode:指向文件的 inode。
f_mapping:文件的地址空间映射。
f_mode:文件的打开模式(读、写、执行)。
f_flags:文件标志(如 O_RDONLY、O_WRONLY、O_RDWR 等)。
f_pos:文件的当前读写位置。
f_op:文件操作指针。
f_owner:文件的所有者。
f_cred:文件的凭证(用户和组信息)。
f_count:引用计数。
f_version:版本号,用于检测文件状态变化。
f_wb_err:写入错误。
f_sb_err:超级块错误。

关系

一个 dentry 可以对应一个 inode,多个 dentry 也可以对应同一个 inode(硬链接)
多个 file 结构体可以对应同一个 inode,表示同一个文件被多次打开
file 结构体中的 f_op 指针指向 inode 中的 i_fop,用于执行文件操作
file 结构体通过 f_path 引用 dentry,确保文件路径的正确性
每个打开的文件描述符对应一个 file 结构体,通过 file 结构体可以访问文件的 dentry 和 inode

相关文章:

块设备的两种访问方法的区别

概述 1.当我们运行类似于“dd if/dev/sdb1ofsdb1.img”的命令把整个/dev/sdb1裸分区复制到sdb1.img的时候&#xff0c;内核走的是def_blk_fops这个file_operations 2.另外一种方法是通过文件系统来访问块设备&#xff0c;file_operations的实现则位于文件系统内&#xff0c;文…...

java 泛型中的 ?

在 Java 泛型中&#xff0c;? 被称为通配符&#xff08;wildcard&#xff09;&#xff0c;它代表了未知的类型。使用通配符可以增加代码的灵活性&#xff0c;允许在不知道具体类型的情况下操作泛型类或接口。通配符主要有以下几种形式&#xff1a; 无界通配符&#xff08;Unbo…...

如何在jupyter notebook切换python环境

目录 参考链接 首先确保conda已经正常安装 conda --version 或者conda -V 以下请将“myenv”替换成自己的命名&#xff01;&#xff01;&#xff01; 1-查看虚拟环境目录 conda env list 2-创建虚拟环境命令 conda create -n myenv 或者 conda create --name myenv 3-激活虚拟环…...

用Python将Word文档转换为Markdown格式

Markdown作为一种轻量级标记语言&#xff0c;以其简洁的语法和广泛的兼容性&#xff0c;特别适合用于博客、技术文档和版本控制系统中的内容管理。而Word文档则因其强大的排版功能&#xff0c;常常成为文档制作的首选。然而&#xff0c;直接使用Word格式在某些平台上可能显得过…...

CSV 文件

CSV&#xff0c;全称为 Comma-Separated Values&#xff09;&#xff08;逗号分隔值&#xff09;&#xff0c;是一种常用的文本文件格式&#xff0c;用于存储表格数据&#xff0c;如电子表格或数据库。它采用纯文本形式&#xff0c;以逗号作为字段之间的分隔符&#xff0c;每行…...

SpringCloud核心组件(五)

文章目录 Gateway一. 概述简介1. Gateway 是什么2. 什么是网关?3.Gateway 和 Nginx 两个网关的区别什么是流量入口&#xff1f; 4.Gateway 能干嘛5.gateway 三大核心概念6.运行方式 二. 入门案例a.创建gateway模块&#xff0c;在pom.xml中引入依赖b.创建启动类GatewayApplicat…...

TCP为什么需要三次握手和四次挥手,有哪些需要注意的地方?

TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。为了确保数据能够准确无误地从一端发送到另一端&#xff0c;TCP设计了一系列机制来保证通信的可靠性&#xff0c;其中包括连接建立和断开的过程。 三次握手&#xff08;Three-…...

机器学习(基础2)

特征工程 特征工程:就是对特征进行相关的处理 一般使用pandas来进行数据清洗和数据处理、使用sklearn来进行特征工程 特征工程是将任意数据(如文本或图像)转换为可用于机器学习的数字特征,比如:字典特征提取(特征离散化)、文本特征提取、图像特征提取。 特征工程API 实例化…...

Cpolar 内网穿透使用

Cpolar登录地址&#xff1a;cpolar - secure introspectable tunnels to localhost 使用固定公网TCP连接ssh ssh -p端口号 用户名公网地址...

ThreadLocal 提供线程局部变量

ThreadLocal作用 相当于建立一个独立的空间&#xff0c;可以把使用频率高的任何类型的数据放到里面&#xff0c;方便调用用来存取数据&#xff1a;set()/get()使用ThreadLocal存储的数据&#xff0c;线程安全 ThreadLocal工具类 /*** ThreadLocal 工具类*/ SuppressWarnings(…...

MongoDB聚合管道数组操作

数组表达式运算符判断数组中是否包含元素( i n ) 并获取元素索引 ( in)并获取元素索引( in)并获取元素索引(indexOfArray) 一、初始化成员数据 db.persons.insertMany([{ "_id" : "1001", "name" : "张三", "fruits" : [ …...

大数据如何助力干部选拔的公正性

随着社会的发展和进步&#xff0c;干部选拔成为组织管理中至关重要的一环。传统的选拔方式可能存在主观性、不公平性以及效率低下等问题。大数据技术的应用&#xff0c;为干部选拔提供了更加全面、精准、客观的信息支持&#xff0c;显著提升选拔工作的科学性和公正性。以下是大…...

Python_爬虫2_爬虫引发的问题

目录 爬虫引发的问题 网络爬虫的尺寸 网络爬虫引发的问题 网络爬虫的限制 Robots协议 Robots协议的遵守方式 Robots的使用 对Robots协议的理解 爬虫引发的问题 网络爬虫的尺寸 爬取网页&#xff0c;玩转网页&#xff1a; 小规模&#xff0c;数据量小&#xff0c;爬取…...

shell编程之编程基础

目录 为什么学习和使用Shell编程Shell是什么shell起源查看当前系统支持的shell查看当前系统默认shellShell 概念 Shell 程序设计语言Shell 也是一种脚本语言用途 如何学好shell熟练掌握shell编程基础知识建议 Shell脚本的基本元素基本元素构成&#xff1a;Shell脚本中的注释和风…...

24.11.15 Vue3

let newJson new Proxy(myJson,{get(target,prop){console.log(在读取${prop}属性);return target[prop];},set(target,prop,val){console.log(在设置${prop}属性值为${val});if(prop"name"){document.getElementById("myTitle").innerHTML val;}if(prop…...

图形几何之美系列:法向量计算之轮廓有向面积辅助法

“ 垂直于平面的直线所表示的向量为该平面的法向量&#xff0c;可以通过法向量识别平面正反面。法向量是轮廓或面的重要特征&#xff0c;求轮廓法向是一种基础的几何工具算法&#xff0c;在图形几何、图像处理等领域具有广泛的应用。” 图形几何之美系列&#xff1a;三维实体结…...

CPU的性能指标总结(学习笔记)

CPU 性能指标 我们先来回顾下&#xff0c;描述 CPU 的性能指标都有哪些。 首先&#xff0c;最容易想到的应该是 CPU 使用率&#xff0c;这也是实际环境中最常见的一个性能指标。 用户 CPU 使用率&#xff0c;包括用户态 CPU 使用率&#xff08;user&#xff09;和低优先级用…...

Cadence安装

记录一下安装过程&#xff0c;方便以后安装使用Cadence。 去吴川斌的博客下载安装包&#xff0c;吴川斌博客&#xff1a; https://www.mr-wu.cn/cadence-orcad-allegro-resource-downloads/ 下载阿狸狗破戒大师 我这边下载的是版本V3.2.6&#xff0c;同样在吴川斌的博客下载安装…...

【网络】子网掩码

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是子网掩码&#xff0c;并且能熟练掌握子网掩码的相关计算。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会…...

Android Osmdroid + 天地图 (二)

Osmdroid 天地图 &#xff08;二&#xff09; 前言正文一、定位监听二、改变地图中心三、添加Marker四、地图点击五、其他配置① 缩放控件② Marker更换图标③ 添加比例尺④ 添加指南针⑤ 添加经纬度网格线⑥ 启用旋转手势⑦ 添加小地图 六、源码 前言 上一篇中我们显示了地图…...

使用大语言模型创建 Graph 数据

Neo4j 是开源的 Graph 数据库&#xff0c;Graph 数据通过三元组进行表示&#xff0c;两个顶点一条边&#xff0c;从语意上可以理解为&#xff1a;主语、谓语和宾语。GraphDB 能够通过图来表达复杂的结构&#xff0c;非常适合存储知识型数据&#xff0c;本文将通过大语言实现图数…...

Java poi 模板导出Word 带图片

Java poi 模板导出Word 带图片 重点&#xff01;&#xff01;&#xff01; 官方文档&#xff1a;https://deepoove.com/poi-tl/#_maven 最终效果 模板 其实内容都在官方文档里写的非常明白了 我这里只是抛砖引玉。 Maven依赖 <poi.version>4.1.2</poi.version>…...

SpringCloud-使用FFmpeg对视频压缩处理

在现代的视频处理系统中&#xff0c;压缩视频以减小存储空间、加快传输速度是一项非常重要的任务。FFmpeg作为一个强大的开源工具&#xff0c;广泛应用于音视频的处理&#xff0c;包括视频的压缩和格式转换等。本文将通过Java代码示例&#xff0c;向您展示如何使用FFmpeg进行视…...

shell bash---类似数组类型

0 Preface/Foreword C/C,Python&#xff0c;Java等编程语言&#xff0c;都含有数组类型&#xff0c;那么shell脚本是不是也有类似的语法呢&#xff1f; 1 类似数组类型 1.1 &#xff08;&#xff09;类似数组类型 #! /bin/bashecho "Welcome to bash world!" anim…...

IIoT(Industrial Internet of Things,工业物联网)

IIoT&#xff08;Industrial Internet of Things&#xff0c;工业物联网&#xff09; 是指物联网技术在工业领域的应用。它将工业设备、传感器、控制系统、数据采集设备等通过互联网或局域网连接起来&#xff0c;实现设备的互联互通和智能化管理。IIoT的目标是提高工业生产效率…...

【C++】引用(reference)

引用是对一个变量或者对象取的别名 定义&#xff1a;真名的数据类型& 别名 真名; 既然是对一个变量或者对象取别名&#xff0c;那就得先有变量或对象&#xff0c;不能凭空取一个别名。也就是定义引用必须初始化。 对引用的操作和对引用对应的变量的操作是完全等价的引用…...

学习日记_20241115_聚类方法(层次聚类)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…...

安卓开发怎么获取返回上一级activity事件

在Android开发中&#xff0c;要获取返回上一级Activity的事件&#xff0c;通常是通过点击设备上的返回按钮或者在代码中调用finish()方法时触发的。为了处理这个事件&#xff0c;你可以在当前Activity中重写onBackPressed()方法。 以下是一个简单的例子&#xff1a; Override…...

神经网络与Transformer详解

一、模型就是一个数学公式 模型可以描述为:给定一组输入数据,经过一系列数学公式计算后,输出n个概率,分别代表该用户对话属于某分类的概率。 图中 a, b 就是模型的参数,a决定斜率,b决定截距。 二、神经网络的公式结构 举例:MNIST包含了70,000张手写数字的图像,其中…...

C语言之MakeFile

Makefile 的引入是为解决多文件项目中手动编译繁琐易错、缺乏自动化构建、项目管理维护困难以及跨平台构建不便等问题&#xff0c;实现自动化、规范化的项目构建与管理 MakeFile 简单的来说,MakeFile就是编写编译命令的文件 文件编写格式 目标:依赖文件列表 <Tab>命令列表…...