第31篇:块设备与字符设备管理深度解析(基于OpenEuler 24.03)

块设备与字符设备管理深度解析(基于OpenEuler 24.03)

文章目录

  • 块设备与字符设备管理深度解析(基于OpenEuler 24.03)
    • 一、设备基础概念体系
      • 1.1 块设备的核心特性与分类
      • 1.2 字符设备的流式数据模型
      • 1.3 设备标识系统:主设备号与次设备号
    • 二、设备信息查询与管理工具
      • 2.1 系统设备注册表:/proc/devices
      • 2.2 块设备可视化工具:lsblk
        • 2.2.1 基本用法与输出解析
        • 2.2.2 高级查询功能
      • 2.3 设备号查询工具:ls -l
    • 三、设备文件操作与管理
      • 3.1 手动创建设备文件:mknod
      • 3.2 自动创建设备文件:MAKEDEV
    • 四、udev设备管理系统
      • 4.1 udev概述与发展历程
      • 4.2 udev核心配置文件
        • 4.2.1 udev.conf配置文件
        • 4.2.2 规则文件目录:/etc/udev/rules.d
      • 4.3 udev规则语法详解
        • 4.3.1 操作符类型
        • 4.3.2 常用匹配键
        • 4.3.3 常用赋值键
      • 4.4 udev规则实例解析
      • 4.5 udev设备信息查询工具:udevadm
        • 4.5.1 查询设备路径信息
        • 4.5.2 全面设备信息查询
      • 4.6 udev服务控制
    • 五、实战案例:自定义udev规则
      • 5.1 案例:为USB打印机分配固定名称
      • 5.2 案例:设置串口设备权限
  • 移除并重新插入打印机
  • 应看到指向实际设备文件的符号链接

一、设备基础概念体系

1.1 块设备的核心特性与分类

块设备是Linux系统中以"数据块"为基本单位进行数据传输的设备类型,其核心特征是支持随机访问。在OpenEuler 24.03中,块设备的典型代表包括:

  • 存储介质类:硬盘(HDD/SSD)、U盘、SD卡等,这类设备以512字节或其整数倍的块为单位读写数据
  • 光学存储类:CD-ROM、DVD驱动器,数据组织为固定大小的逻辑块
  • 虚拟存储类:Loop设备(用于挂载镜像文件)、RAM磁盘(基于内存的块设备)

块设备在文件系统中的标识遵循特定规范:

  • SCSI/SATA设备:/dev/sd[a-z],如/dev/sda表示第一块SCSI磁盘
  • 光驱设备:/dev/sr[0-9],如/dev/sr0对应系统识别的第一个光驱
  • 软RAID设备:/dev/md[0-9],用于软件磁盘阵列
  • 内存磁盘:/dev/ram[0-0]/dev/ram19,基于物理内存创建的块设备

1.2 字符设备的流式数据模型

字符设备以字节为单位顺序处理数据,不支持随机寻址,适用于数据流式传输场景。OpenEuler 24.03中的典型字符设备包括:

  • 输入输出设备:键盘(/dev/input/event*)、串口(/dev/ttyS[0-9]
  • 虚拟设备:空设备(/dev/null)、零设备(/dev/zero
  • 控制台设备/dev/console(系统控制台)、/dev/tty[0-31](虚拟终端)
  • 多媒体设备:帧缓冲设备(/dev/fb[0-31])、声卡设备(/dev/snd/*

字符设备的访问特性决定了其应用场景:

  • /dev/null:数据写入后会被丢弃,常用于屏蔽命令输出
  • /dev/zero:读取时返回无限零数据流,可用于文件填充
  • /dev/tty:指向当前终端,实现终端无关的输入输出

1.3 设备标识系统:主设备号与次设备号

Linux系统通过设备号对设备进行唯一标识,设备号由两部分组成:

  • 主设备号(Major Number):标识设备驱动程序,范围0-255
  • 次设备号(Minor Number):标识具体的设备实例,范围0-65535

在OpenEuler中查看设备号的典型方法:

# 查看光驱设备号
ls -l /dev/cdrom
# 输出示例:lrwxrwxrwx. 1 root root 3 7月 1 2016 /dev/cdrom -> sr0
ls -l /dev/sr0
# 输出示例:brw-rw----+ 1 root cdrom 11, 0 7月 1 2016 /dev/sr0
# 解析:主设备号11,次设备号0# 查看帧缓冲设备号
ls -l /dev/fb
# 输出示例:lrwxrwxrwx. 1 root root 3 7月 1 2016 /dev/fb -> fb0
ls -l /dev/fb0
# 输出示例:crw-rw----. 1 root root 29, 0 7月 1 2016 /dev/fb0
# 解析:主设备号29,次设备号0

二、设备信息查询与管理工具

2.1 系统设备注册表:/proc/devices

/proc/devices文件记录了系统中所有已注册的设备类型及其主设备号,在OpenEuler中分为字符设备和块设备两部分:

cat /proc/devices
# 输出片段:
Character devices:1 mem4 /dev/vc/04 tty4 ttyS5 /dev/tty5 /dev/console5 /dev/ptmx7 vcs10 misc13 input14 sound21 sg29 fb
116 alsa
128 ptm
136 pts
162 raw
180 usb
189 usb_device
202 cpu/msr
203 cpu/cpuid
249 hidraw
250 usbmon
251 bsg
252 pcmcia
253 watchdog
254 rtcBlock devices:1 ramdisk
259 blkext7 loop8 sd9 md11 sr65 sd66 sd67 sd68 sd69 sd70 sd71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
253 device-mapper
254 mdp

2.2 块设备可视化工具:lsblk

lsblk是OpenEuler中用于查看块设备层次结构的强大工具,包含在util-linux包中(已默认安装)。其核心功能包括:

2.2.1 基本用法与输出解析
# 列出所有块设备及其挂载关系
lsblk
# 输出示例:
NAME                        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0                          11:0    1  4.2G  0 rom  /media/cdrom
sda                           8:0    0   50G  0 disk 
├─sda1                        8:1    0  500M  0 part /boot
└─sda2                        8:2    0 49.5G  0 part ├─VolGroup-lv_root (dm-0) 253:0    0 47.6G  0 lvm  /└─VolGroup-lv_swap (dm-1) 253:1    0    2G  0 lvm  [SWAP]# 字段解析:
# NAME:设备名称
# MAJ:MIN:主设备号:次设备号
# RM:是否可移动设备(1为可移动)
# SIZE:设备容量
# RO:是否只读(0为可写)
# TYPE:设备类型(disk=磁盘,part=分区,rom=光驱等)
# MOUNTPOINT:挂载点
2.2.2 高级查询功能
# 显示文件系统信息
lsblk -f
# 输出示例:
NAME   FSTYPE   LABEL          UUID                                   MOUNTPOINT
sr0    iso9660  CentOS_6.5_Final                                       /media/cdr
sda                                                                   
├─sda1 ext4                    294ad562-2483-41ce-b5c8-22feb620a766   /boot
└─sda2 LVM2_mem                sPD7DF-cTL5-R8XK-fl0y-9Hlr-8uic-LDgOpH ├─VolGroup-lv_root (dm-0)ext4                    95161875-59c2-4777-a7ba-599f1cc1fffc   /└─VolGroup-lv_swap (dm-1)swap                    17981850-c0ec-4b36-8f93-5c4e36165af5   [SWAP]# 显示权限信息
lsblk -m
# 输出示例:
NAME                         SIZE OWNER GROUP MODE
sr0                          4.2G root  cdrom brw-rw----
sda                           50G root  disk  brw-rw----
├─sda1                       500M root  disk  brw-rw----
└─sda2                      49.5G root  disk  brw-rw----├─VolGroup-lv_root (dm-0) 47.6G root  disk  brw-rw----└─VolGroup-lv_swap (dm-1)    2G root  disk  brw-rw----# 显示拓扑结构
lsblk -t
# 输出示例:
NAME   ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED RQ-SIZE   RA
sr0            0   2048      0    2048    2048    1 cfq       128  128
sda            0    512      0     512     512    1 cfq       128  128
├─sda1         0    512      0     512     512    1 cfq       128  128
└─sda2         0    512      0     512     512    1 cfq       128  128├─VolGroup-lv_root (dm-0)0    512      0     512     512    1           128  128└─VolGroup-lv_swap (dm-1)0    512      0     512     512    1           128  128

2.3 设备号查询工具:ls -l

通过ls -l命令可以直接查看设备文件的主设备号和次设备号,这是最基础的设备信息查询方式:

# 查看硬盘设备号
ls -l /dev/sda
# 输出示例:brw-rw----. 1 root disk 8, 0 7月 1 2016 /dev/sda
# 解析:主设备号8,次设备号0# 查看串口设备号
ls -l /dev/ttyS0
# 输出示例:crw-rw----. 1 root dialout 4, 64 7月 1 2016 /dev/ttyS0
# 解析:主设备号4,次设备号64

三、设备文件操作与管理

3.1 手动创建设备文件:mknod

mknod命令用于在OpenEuler中手动创建设备文件,支持块设备、字符设备和FIFO文件:

# 命令语法
mknod [选项] 设备文件 类型 主设备号 次设备号# 选项说明:
# -Z:设置安全上下文
# -m:设置权限模式(如0666)
# --help:显示帮助信息
# --version:显示版本信息# 示例1:创建/dev/sda设备文件
ls -l /dev/sda  # 确认设备文件存在
# 输出示例:brw-rw----. 1 root disk 8, 0 7月 1 2016 /dev/sda
rm -rf /dev/sda  # 删除原有设备文件
mknod /dev/sda b 8 0  # 创建块设备文件
ls -l /dev/sda  # 验证创建结果
# 输出示例:brw-r--r--. 1 root root 8, 0 3月 24 21:24 /dev/sda# 示例2:创建字符设备文件
mknod /dev/test_char c 249 0  # 创建hidraw字符设备
ls -l /dev/test_char 
# 输出示例:crw-r--r--. 1 root root 249, 0 3月 24 21:30 /dev/test_char# 示例3:创建FIFO文件
mknod /tmp/myfifo p  # 创建命名管道
ls -l /tmp/myfifo 
# 输出示例:prw-r--r--. 1 root root 0 3月 24 21:35 /tmp/myfifo

3.2 自动创建设备文件:MAKEDEV

MAKEDEV是OpenEuler中的设备文件自动创建脚本,基于预设规则生成标准设备文件:

# 命令语法
MAKEDEV [选项] [设备类型]# 选项说明:
# -a:强制创建设备文件,覆盖已存在的文件
# -d <目录>:指定设备文件创建目录
# -m <最大设备数>:限制创建的设备数量
# -n:仅显示操作,不实际执行
# -v:显示详细执行过程# 示例1:自动创建/dev/sda设备文件
ls -l /dev/sda  # 确认设备文件存在
# 输出示例:brw-rw----. 1 root disk 8, 0 7月 1 2016 /dev/sda
rm -rf /dev/sda  # 删除原有设备文件
MAKEDEV sda  # 自动创建sda设备文件
ls -l /dev/sda  # 验证结果
# 输出示例:brw-r-----. 1 root disk 8, 0 3月 25 08:30 /dev/sda# 示例2:创建所有磁盘设备文件
MAKEDEV -a disk  # 强制创建所有磁盘相关设备文件

四、udev设备管理系统

4.1 udev概述与发展历程

udev是OpenEuler中负责动态管理/dev目录设备文件的用户空间工具,其发展背景如下:

  • 早期阶段:静态设备文件(通过mknod手动创建)
  • devfs阶段:内核动态设备文件系统(2.3内核引入,2.6.13后移除)
  • udev阶段:用户空间设备管理(当前主流方案,解决了devfs的诸多问题)

udev的核心优势:

  • 动态管理:自动识别热插拔设备,实时更新/dev目录
  • 稳定命名:基于设备硬件特征(如序列号)分配固定名称
  • 灵活配置:可自定义设备权限、属主、符号链接等属性
  • 资源优化:仅创建系统实际存在的设备文件,减少资源消耗

4.2 udev核心配置文件

4.2.1 udev.conf配置文件

/etc/udev/udev.conf是udev的主配置文件,控制udev的基本行为:

# 查看udev.conf内容
cat /etc/udev/udev.conf 
# 输出示例:
# The initial syslog(3) priority: "err", "info", "debug" or its
# numerical equivalent. For runtime debugging, the daemons internal
# state can be changed with: "udevadm control --log-priority=<value>".
udev_log="err"# 主要配置参数:
udev_log="err"  # 日志级别(err/info/debug)
udev_root="/dev"  # 设备文件根目录
udev_db="/dev/.udevdb"  # udev数据库路径
udev_rules="/dev/udev/rules.d"  # 规则文件目录
4.2.2 规则文件目录:/etc/udev/rules.d

udev规则文件存储在/etc/udev/rules.d目录中,文件名通常以两位数字开头表示执行顺序:

# 查看规则文件列表
ls -l /etc/udev/rules.d/
# 输出示例:
总用量 44
-rw-r--r--. 1 root root 1652 1112 2010 60-fprint-autosuspend.rules
-rw-r--r--. 1 root root 1060 1112 2010 60-pcmcia.rules
-rw-r--r--. 1 root root  316 1122 2013 60-raw.rules
-rw-r--r--. 1 root root  789 71 2016 70-persistent-cd.rules
-rw-r--r--. 1 root root  420 71 2016 70-persistent-net.rules
-rw-r--r--. 1 root root  320 912 2012 90-alsa.rules
-rw-r--r--. 1 root root   83 720 2011 90-hal.rules
-rw-r--r--. 1 root root 2486 1111 2010 97-bluetooth-serial.rules
-rw-r--r--. 1 root root  308 1123 2013 98-kexec.rules
-rw-r--r--. 1 root root   54 128 2011 99-fuse.rules
-rw-r--r--. 1 root root  341 71 2016 99-vmware-scsi-udev.rules

4.3 udev规则语法详解

4.3.1 操作符类型

udev规则由键值对组成,通过操作符连接,主要操作符包括:

  • 匹配操作符
    • ==:等于
    • !=:不等于
  • 赋值操作符
    • =:赋值(可覆盖)
    • +=:追加值
    • :=:赋值(不可覆盖)
4.3.2 常用匹配键
键名说明示例
ACTION设备事件(add/remove等)ACTION==“add”
KERNEL内核设备名KERNEL==“sd*”
DEVPATH设备在sysfs中的路径DEVPATH==“/devices/*”
SUBSYSTEM设备子系统SUBSYSTEM==“block”
BUS总线类型BUS==“usb”
DRIVER驱动程序名DRIVER==“ide-cdrom”
ATTRS{key}sysfs属性值ATTRS{removable}==“1”
ENV{key}环境变量ENV{ID_FS_TYPE}==“ext4”
4.3.3 常用赋值键
键名说明示例
NAME设备文件名NAME=“mydevice”
SYMLINK符号链接名SYMLINK+=“link1 link2”
OWNER设备属主OWNER=“root”
GROUP设备属组GROUP=“disk”
MODE设备权限MODE=“0666”
ATTR{key}设置sysfs属性ATTR{power/state}==“on”
RUN执行外部程序RUN+=“/sbin/modprobe sg”
OPTIONS特殊选项OPTIONS=“last_rule”

4.4 udev规则实例解析

以下是OpenEuler中典型的udev规则示例及其解析:

# 规则1:默认设备权限设置
KERNEL=="*", OWNER="root", GROUP="root", MODE="0600"
# 解析:匹配所有设备,设置属主为root,属组为root,权限0600(仅root可读写)# 规则2:终端设备配置
KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666", OPTIONS="last_rule"
# 解析:
# - 匹配所有tty设备
# - 设备名为内核名称(%k)
# - 属组为tty
# - 权限0666(所有用户可读写)
# - OPTIONS="last_rule"表示这是终端规则# 规则3:光驱符号链接
KERNEL=="scd[0-9]*", SYMLINK+="cdrom cdrom-%k"
# 解析:匹配SCSI光驱设备,创建符号链接cdrom和cdrom-内核名# 规则4:ATA光驱识别
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"
# 解析:
# - 匹配ATA设备(hd[a-z])
# - 总线类型为IDE
# - 可移动设备(removable=1)
# - 媒体类型为cdrom
# - 创建光驱符号链接# 规则5:SCSI设备驱动加载
ACTION=="add", SUBSYSTEM=="scsi_device", RUN+="/sbin/modprobe sg"
# 解析:当SCSI设备添加时,加载sg驱动模块

4.5 udev设备信息查询工具:udevadm

udevadm是OpenEuler中用于查询和管理udev数据库的命令行工具:

4.5.1 查询设备路径信息
# 查询/dev/sda的系统设备路径
udevadm info -q path -n /dev/sda
# 输出示例:/devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda# 查询符号链接信息
udevadm info -q symlink -n /dev/sda
# 输出示例:block/8:0 disk/by-path/pci-0000:00:10.0-scsi-0:0:0:0
4.5.2 全面设备信息查询
# 查询所有设备信息
udevadm info -q all -n /dev/sda
# 输出片段:
P: /devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda
N: sda
W: 27
S: block/8:0
S: disk/by-path/pci-0000:00:10.0-scsi-0:0:0:0
E: UDEV_LOG=3
E: DEVPATH=/devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda
E: MAJOR=8
E: MINOR=0
E: DEVNAME=/dev/sda
E: DEVTYPE=disk
E: SUBSYSTEM=block
# (省略更多输出)# 基于sysfs路径查询
udevadm info -a -p /sys/block/sda
# 输出包含从设备到总线的完整层次结构信息

4.6 udev服务控制

在OpenEuler中控制udev服务的常用命令:

# 重启udev服务使规则生效
systemctl restart udev# 查看udev进程状态
ps -ef | grep udev
# 输出示例:
root      42737      1  1 12:20 ?        00:00:00 /sbin/udevd -d
root      43263  12851  0 12:20 pts/0    00:00:00 grep udev# 重新加载udev规则
udevadm control --reload-rules

五、实战案例:自定义udev规则

5.1 案例:为USB打印机分配固定名称

需求:为特定USB打印机分配固定设备名/dev/usb_printer,避免因插拔顺序导致设备名变化。

实现步骤:

  1. 查询打印机硬件信息
# 插入打印机后执行
udevadm info -a -n /dev/usb/lp0
# 记录关键信息:
# - 厂商ID(ATTRS{idVendor})
# - 产品ID(ATTRS{idProduct})
# - 序列号(ATTRS{serial})
  1. 创建自定义规则
# 在rules.d目录创建新规则文件
vi /etc/udev/rules.d/99-usb-printer.rules
# 添加以下内容:
SUBSYSTEM=="usb", ATTRS{idVendor}=="0419", ATTRS{idProduct}=="0050", ATTRS{serial}=="PRN001", SYMLINK+="usb_printer"
# 解析:
# - 匹配USB子系统
# - 厂商ID 0419,产品ID 0050
# - 序列号PRN001
# - 创建符号链接usb_printer
  1. 应用规则并验证
# 重新加载规则
udevadm control --reload-rules
# 移除并重新插入打印机
ls -l /dev/usb_printer
# 应看到指向实际设备文件的符号链接

5.2 案例:设置串口设备权限

需求:将串口设备/dev/ttyS0的权限设置为允许dialout组用户访问。

实现步骤:

  1. 创建规则文件
vi /etc/udev/rules.d/60-serial-port.rules
# 添加内容:
KERNEL=="ttyS0", GROUP="dialout", MODE="0660"
# 解析:
# - 匹配ttyS0设备
# - 属组设为dialout
# - 权限设为0660(dialout组可读写)
  1. 应用规则
systemctl restart udev
# 或
udevadm control --reload-rules
  1. 验证权限
ls -l /dev/ttyS0
# 应显示权限为crw-rw----,属组为dialout

ol --reload-rules

移除并重新插入打印机

ls -l /dev/usb_printer

应看到指向实际设备文件的符号链接


### 5.2 案例:设置串口设备权限需求:将串口设备`/dev/ttyS0`的权限设置为允许dialout组用户访问。实现步骤:1. **创建规则文件**:
```bash
vi /etc/udev/rules.d/60-serial-port.rules
# 添加内容:
KERNEL=="ttyS0", GROUP="dialout", MODE="0660"
# 解析:
# - 匹配ttyS0设备
# - 属组设为dialout
# - 权限设为0660(dialout组可读写)
  1. 应用规则
systemctl restart udev
# 或
udevadm control --reload-rules
  1. 验证权限
ls -l /dev/ttyS0
# 应显示权限为crw-rw----,属组为dialout

通过上述内容,我们全面解析了OpenEuler 24.03中块设备与字符设备的管理体系,从基础概念到高级配置,结合具体命令和案例,帮助读者深入理解Linux设备管理的核心机制。无论是设备信息查询、手动/自动创建设备文件,还是通过udev实现动态设备管理,都提供了完整的操作指南和实践案例,适用于系统管理员和开发人员掌握设备管理的关键技术。

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

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

相关文章

Django Channels WebSocket实时通信实战:从聊天功能到消息推送

引言 在Web开发中&#xff0c;实时通信功能&#xff08;如在线聊天、实时通知、数据推送&#xff09;已成为许多应用的核心需求。传统的HTTP协议由于其请求-响应模式的限制&#xff0c;无法高效实现实时通信。WebSocket作为一种全双工通信协议&#xff0c;为实时Web应用提供了…

day52 神经网络调参指南

目录 随机种子 内参的初始化 神经网络调参指南 参数的分类 调参顺序 初始化参数 batchsize的选择 学习率调整 激活函数的选择 损失函数的选择 模型架构中的参数 正则化系数 其他补充 随机种子 import torch import torch.nn as nn# 定义简单的线性模型&#xf…

.NET9 实现斐波那契数列(FibonacciSequence)性能测试

在 .NET 平台上实现 斐波那契数列 并使用 BenchmarkDotNet 进行性能测试&#xff0c;是评估不同算法实现方式性能表现的一种高效且标准化的方法。通过该方式&#xff0c;可以对比递归、迭代、记忆化递归以及结合高性能优化技术&#xff08;如 Span<T>、Memory<T> 和…

三、docker软件安装:gitlab,nexus,mysql8,redis,nacos,nginx

目录 1.gitlab安装 2.nexus安装 (1)下载启动 (2)设置中央仓库远程地址 (3)配置maven的settings.xml 3.mysql8安装 4.redis安装 5.nacos安装 6.nginx安装 1.gitlab安装 #创建目录 cd /usr/local/ mkdir docker cd docker/ mkdir gitlab_docker cd gitlab_docker…

【与AI+】SAP WEBGUI集成开发与SAP INTERNET服务的关系

前言&#xff1a;这是我的水水专栏第五篇文章&#xff0c;这个专栏呢&#xff0c;是放一些我向AI提问的问题&#xff0c;以及AI的回答。因为感觉真的好方便哈哈哈~ 我不是很确定我的专栏文章内容是否涉及版权&#xff0c;以及也不确定这些整合过的文字是否涉嫌抄袭&#xff0c…

浅谈几种js设计模式

JavaScript设计模式是开发中常用的一种解决方案&#xff0c;它们帮助开发者以一种更结构化、更易维护的方式编写代码。本文将深入介绍几种常见的JavaScript设计模式&#xff0c;包括单例模式、工厂模式、观察者模式和策略模式。 一、单例模式&#xff08;Singleton Pattern&am…

手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程

目录 一、虚拟 DOM 的核心概念 二、虚拟 DOM 到真实 DOM 的流程 三、手写虚拟 DOM 到真实 DOM 的实现 1. 定义虚拟 DOM 的结构&#xff08;VNode&#xff09; 2. 创建虚拟 DOM 转真实 DOM 的函数 3. 挂载虚拟 DOM 到页面 4. 更新虚拟 DOM 的过程&#xff08;Diff 算法简化…

jmm--volatile

指令重排基础概念 在现代处理器和编译器为了提高程序执行效率&#xff0c;会对指令进行优化&#xff0c;其中一种优化方式就是指令重排序。在单线程环境下&#xff0c;指令重排序不会影响最终执行结果&#xff0c;因为处理器和编译器会保证重排序后的执行结果与按照代码顺序执行…

【硬件开发】滤波电容的选择:原理、计算与多电压值应用实践

滤波电容的选择&#xff1a;原理、计算与多电压值应用实践 1. 引言 在现代电子系统中&#xff0c;稳定的电源供应是保证电路可靠运行的基础。然而&#xff0c;电源线上往往不可避免地存在各种噪声和纹波&#xff0c;这些干扰可能源自电源本身&#xff08;如整流后的脉动直流&…

【seismic unix数据生成-unif2】

Seismic Unix简介 Seismic Unix&#xff08;SU&#xff09;是由科罗拉多矿业学院&#xff08;Colorado School of Mines&#xff09;开发的开源地震数据处理软件包&#xff0c;专为地震勘探数据分析和研究设计。它提供了一系列命令行工具&#xff0c;支持从数据加载、处理到可…

【逆向思考 并集查找】P2391 白雪皑皑|省选-

本文涉及知识点 C并集查找 P2391 白雪皑皑 题目背景 “柴门闻犬吠&#xff0c;风雪夜归人”&#xff0c;冬天&#xff0c;不期而至。千里冰封&#xff0c;万里雪飘。空中刮起了鸭毛大雪。雪花纷纷&#xff0c;降落人间。 美能量星球&#xff08;pty 在 spore 上的一个殖民地…

一文讲清楚React中setState的使用方法和机制

文章目录 一文讲清楚React中setState的使用方法和机制1. setState是什么2. setState方法详解2.1 setState参数详解2.2 setState同步异步问题2.2.1 setState异步更新2.2.2 setState同步更新 一文讲清楚React中setState的使用方法和机制 1. setState是什么 React中&#xff0c;…

01_软件卓越之道:功能性与需求满足

引言 在软件的世界里&#xff0c;功能性是产品与用户之间的第一桥梁。一个软件即使拥有华丽的界面和极致的性能&#xff0c;如果不能解决用户的核心需求&#xff0c;也终将被市场淘汰。本文将深入探讨如何确保软件的功能性与用户需求完美契合。 1. 需求理解&#xff1a;从模糊…

StarRocks × Tableau 连接器完整使用指南 | 高效数据分析从连接开始

一、导语&#xff1a;为什么选择 StarRocks Tableau 连接器&#xff1f; 在当今数据驱动的商业环境中&#xff0c;企业不仅需要一个能够处理海量数据的高性能分析数据库&#xff0c;还需要一个直观、强大的可视化工具来解读数据背后的故事。StarRocks 作为新一代极速全场景 MP…

基于 SpringBoot+VueJS 助农生鲜销售系统设计与实现7000字论文实现

摘要本论文设计并实现了一个基于 SpringBoot 和 VueJS 的助农生鲜销售系统。系统采用前后端分离架构&#xff0c;前端使用 VueJS 框架实现用户界面&#xff0c;后端使用 SpringBoot 框架构建服务&#xff0c;通过 MyBatis 实现数据持久化。系统实现了农产品展示、在线购物、订单…

Pytest 测试发现机制详解:自动识别测试函数与模块

概述 在编写自动化测试时,如何让 Pytest 自动找到你的测试代码 是一个非常基础但重要的问题。Pytest 通过其强大的 测试发现(Test Discovery)机制,能够自动扫描项目目录、识别测试模块和测试函数,从而大大简化了测试流程。 本文将为你详细讲解 Pytest 的测试发现机制,包…

MySQL 时间日期函数

时间日期类型 MySQL中主要支持以下几种时间日期类型&#xff1a; DATE - 日期类型 格式&#xff1a;YYYY-MM-DD范围&#xff1a;1000-01-01 到 9999-12-31示例&#xff1a;2023-05-20 TIME - 时间类型 格式&#xff1a;HH:MM:SS范围&#xff1a;-838:59:59 到 838:59:59示例&…

408第三季part2 - 计算机网络 - 物理层

理解 这里有8个波形&#xff0c;每个波形代表一个马原&#xff0c;一个马原代表多个比特&#xff0c;这里3个比特 求波特率就直接2W 求比特率就要乘log2V 这块记两公式就行&#xff0c;一个下面一个上面 题目 4个相位加4种幅度就是有16种波形 这里无噪声就是奈奎斯特定理 这…

iOS 集成RN Installing glog (0.3.5)报错的解决方案

在集成执行RN bundle exec pod install 命令到Installing glog (0.3.5)时报错,报错信息如下: Installing glog (0.3.5) [!] /bin/bash -c set -e #!/bin/bash # Copyright (c) Facebook, Inc. and its affiliates. # # This source code is licensed under the MIT license …

【进阶篇-消息队列】——MQTT协议如何支持海量的在线IoT设备

目录 一、什么是IoT二、MQTT 和其他消息队列的传输协议有什么不同三、如何选择 MQTT 产品四、MQTT 集群如何支持海量在线的 IoT 设备五、总结本文来源:极客时间vip课程笔记 一、什么是IoT IoT,也就是物联网,物联网这个词儿,它的含义还不那么直观,但你看它的英文:IoT,也就…