Hadoop-Yarn-NodeManager如何计算Linux系统上的资源信息

一、上下文

<Hadoop-Yarn-NodeManager都做了什么>中讲节点资源监控服务(NodeResourceMonitorImpl)时只是提了下SysInfoLinux,下面我们展开讲下

SysInfoLinux是用于计算Linux系统上的资源信息的插件

二、SysInfoLinux源码

package org.apache.hadoop.util;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.util.Shell.ShellCommandExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 用于计算Linux系统上的资源信息的插件*/
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class SysInfoLinux extends SysInfo {private static final Logger LOG =LoggerFactory.getLogger(SysInfoLinux.class);/*** proc的meminfo虚拟文件具有以下格式的键值* "key:[ \t]*value[ \t]kB".*/private static final String PROCFS_MEMFILE = "/proc/meminfo";private static final Pattern PROCFS_MEMFILE_FORMAT =Pattern.compile("^([a-zA-Z_()]*):[ \t]*([0-9]*)[ \t]*(kB)?");//我们需要meminfo中以下键的值private static final String MEMTOTAL_STRING = "MemTotal";private static final String SWAPTOTAL_STRING = "SwapTotal";private static final String MEMFREE_STRING = "MemFree";private static final String SWAPFREE_STRING = "SwapFree";private static final String INACTIVE_STRING = "Inactive";private static final String INACTIVEFILE_STRING = "Inactive(file)";private static final String HARDWARECORRUPTED_STRING = "HardwareCorrupted";private static final String HUGEPAGESTOTAL_STRING = "HugePages_Total";private static final String HUGEPAGESIZE_STRING = "Hugepagesize";/*** 解析/proc/cpuinfo的样板*/private static final String PROCFS_CPUINFO = "/proc/cpuinfo";private static final Pattern PROCESSOR_FORMAT =Pattern.compile("^processor[ \t]:[ \t]*([0-9]*)");private static final Pattern FREQUENCY_FORMAT =Pattern.compile("^cpu MHz[ \t]*:[ \t]*([0-9.]*)");private static final Pattern PHYSICAL_ID_FORMAT =Pattern.compile("^physical id[ \t]*:[ \t]*([0-9]*)");private static final Pattern CORE_ID_FORMAT =Pattern.compile("^core id[ \t]*:[ \t]*([0-9]*)");/*** 解析/proc/stat的样板*/private static final String PROCFS_STAT = "/proc/stat";private static final Pattern CPU_TIME_FORMAT =Pattern.compile("^cpu[ \t]*([0-9]*)" +"[ \t]*([0-9]*)[ \t]*([0-9]*)[ \t].*");private CpuTimeTracker cpuTimeTracker;/*** 解析/proc/net/dev的样板*/private static final String PROCFS_NETFILE = "/proc/net/dev";private static final Pattern PROCFS_NETFILE_FORMAT =Pattern .compile("^[ \t]*([a-zA-Z]+[0-9]*):" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+).*");/*** 解析/proc/diskstats的样板*/private static final String PROCFS_DISKSFILE = "/proc/diskstats";private static final Pattern PROCFS_DISKSFILE_FORMAT =Pattern.compile("^[ \t]*([0-9]+)[ \t]*([0-9 ]+)" +"(?!([a-zA-Z]+[0-9]+))([a-zA-Z]+)" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)" +"[ \t]*([0-9]+)[ \t]*([0-9]+)[ \t]*([0-9]+)");/*** 解析/sys/block/partition_name/queue/hw_sector_size的样板*/private static final Pattern PROCFS_DISKSECTORFILE_FORMAT =Pattern.compile("^([0-9]+)");private String procfsMemFile;private String procfsCpuFile;private String procfsStatFile;private String procfsNetFile;private String procfsDisksFile;private long jiffyLengthInMillis;private long ramSize = 0;private long swapSize = 0;private long ramSizeFree = 0;  // 机器上的可用 ram 磁盘空间 (kB)private long swapSizeFree = 0; // 机器上的可用 swap 空间 (kB)private long inactiveSize = 0; // 不活跃内存 (kB)private long inactiveFileSize = -1; // 非活动缓存,-1(如果不存在)private long hardwareCorruptSize = 0; // RAM已损坏且不可用大小private long hugePagesTotal = 0; // # 保留的标准大页private long hugePageSize = 0; // # 每个标准大页的大小/* 系统上的逻辑处理器数量. */private int numProcessors = 0;/* 系统上的物理核心数. */private int numCores = 0;private long cpuFrequency = 0L; // 系统上的CPU频率 (kHz)private long numNetBytesRead = 0L; // 从网络读取的聚合字节private long numNetBytesWritten = 0L; // 写入网络的聚合字节数private long numDisksBytesRead = 0L; // 从磁盘读取的聚合字节数private long numDisksBytesWritten = 0L; // 写入磁盘的聚合字节数private boolean readMemInfoFile = false;private boolean readCpuInfoFile = false;/* 为每个磁盘映射其扇区大小 */private HashMap<String, Integer> perDiskSectorSize = null;public static final long PAGE_SIZE = getConf("PAGESIZE");public static final long JIFFY_LENGTH_IN_MILLIS =Math.max(Math.round(1000D / getConf("CLK_TCK")), -1);private static long getConf(String attr) {if(Shell.LINUX) {try {ShellCommandExecutor shellExecutorClk = new ShellCommandExecutor(new String[] {"getconf", attr });shellExecutorClk.execute();return Long.parseLong(shellExecutorClk.getOutput().replace("\n", ""));} catch (IOException|NumberFormatException e) {return -1;}}return -1;}/*** 获取当前时间* @return Unix时间戳(毫秒)*/long getCurrentTime() {return System.currentTimeMillis();}public SysInfoLinux() {this(PROCFS_MEMFILE, PROCFS_CPUINFO, PROCFS_STAT,PROCFS_NETFILE, PROCFS_DISKSFILE, JIFFY_LENGTH_IN_MILLIS);}/*** 构造函数,它允许分配/proc/目录。这将仅用于单元测试* @param procfsMemFile fake file for /proc/meminfo* @param procfsCpuFile fake file for /proc/cpuinfo* @param procfsStatFile fake file for /proc/stat* @param procfsNetFile fake file for /proc/net/dev* @param procfsDisksFile fake file for /proc/diskstats* @param jiffyLengthInMillis fake jiffy length value*/@VisibleForTestingpublic SysInfoLinux(String procfsMemFile,String procfsCpuFile,String procfsStatFile,String procfsNetFile,String procfsDisksFile,long jiffyLengthInMillis) {this.procfsMemFile = procfsMemFile;this.procfsCpuFile = procfsCpuFile;this.procfsStatFile = procfsStatFile;this.procfsNetFile = procfsNetFile;this.procfsDisksFile = procfsDisksFile;this.jiffyLengthInMillis = jiffyLengthInMillis;this.cpuTimeTracker = new CpuTimeTracker(jiffyLengthInMillis);this.perDiskSectorSize = new HashMap<String, Integer>();}/*** 读 /proc/meminfo, 只解析和计算一次内存信息.*/private void readProcMemInfoFile() {readProcMemInfoFile(false);}/**** Long.parseLong()的包装器,如果值无效则返回零。在某些情况下,* /proc/meminfo中的swapFree可能为负数,报告为非常大的十进制值。*/private long safeParseLong(String strVal) {long parsedVal;try {parsedVal = Long.parseLong(strVal);} catch (NumberFormatException nfe) {parsedVal = 0;}return parsedVal;}/*** 读 /proc/meminfo, 解析和计算内存信息.* @param readAgain if false, read only on the first time*/private void readProcMemInfoFile(boolean readAgain) {if (readMemInfoFile && !readAgain) {return;}// Read "/proc/memInfo" fileBufferedReader in;InputStreamReader fReader;try {fReader = new InputStreamReader(new FileInputStream(procfsMemFile), Charset.forName("UTF-8"));in = new BufferedReader(fReader);} catch (FileNotFoundException f) {// shouldn't happen....LOG.warn("Couldn't read " + procfsMemFile+ "; can't determine memory settings");return;}Matcher mat;try {String str = in.readLine();while (str != null) {mat = PROCFS_MEMFILE_FORMAT.matcher(str);if (mat.find()) {if (mat.group(1).equals(MEMTOTAL_STRING)) {ramSize = Long.parseLong(mat.group(2));} else if (mat.group(1).equals(SWAPTOTAL_STRING)) {swapSize = Long.parseLong(mat.group(2));} else if (mat.group(1).equals(MEMFREE_STRING)) {ramSizeFree = safeParseLong(mat.group(2));} else if (mat.group(1).equals(SWAPFREE_STRING)) {swapSizeFree = safeParseLong(mat.group(2));} else if (mat.group(1).equals(INACTIVE_STRING)) {inactiveSize = Long.parseLong(mat.group(2));} else if (mat.group(1).equals(INACTIVEFILE_STRING)) {inactiveFileSize = Long.parseLong(mat.group(2));} else if (mat.group(1).equals(HARDWARECORRUPTED_STRING)) {hardwareCorruptSize = Long.parseLong(mat.group(2));} else if (mat.group(1).equals(HUGEPAGESTOTAL_STRING)) {hugePagesTotal = Long.parseLong(mat.group(2));} else if (mat.group(1).equals(HUGEPAGESIZE_STRING)) {hugePageSize = Long.parseLong(mat.group(2));}}str = in.readLine();}} catch (IOException io) {LOG.warn("Error reading the stream " + io);} finally {//关闭流try {fReader.close();try {in.close();} catch (IOException i) {LOG.warn("Error closing the stream " + in);}} catch (IOException i) {LOG.warn("Error closing the stream " + fReader);}}readMemInfoFile = true;}/*** 读 /proc/cpuinfo, 解析和计算CPU信息.*/private void readProcCpuInfoFile() {// 此目录只需读取一次if (readCpuInfoFile) {return;}HashSet<String> coreIdSet = new HashSet<>();// Read "/proc/cpuinfo" fileBufferedReader in;InputStreamReader fReader;try {fReader = new InputStreamReader(new FileInputStream(procfsCpuFile), Charset.forName("UTF-8"));in = new BufferedReader(fReader);} catch (FileNotFoundException f) {// shouldn't happen....LOG.warn("Couldn't read " + procfsCpuFile + "; can't determine cpu info");return;}Matcher mat;try {numProcessors = 0;numCores = 1;String currentPhysicalId = "";String str = in.readLine();while (str != null) {mat = PROCESSOR_FORMAT.matcher(str);if (mat.find()) {numProcessors++;}mat = FREQUENCY_FORMAT.matcher(str);if (mat.find()) {cpuFrequency = (long)(Double.parseDouble(mat.group(1)) * 1000); // kHz}mat = PHYSICAL_ID_FORMAT.matcher(str);if (mat.find()) {currentPhysicalId = str;}mat = CORE_ID_FORMAT.matcher(str);if (mat.find()) {coreIdSet.add(currentPhysicalId + " " + str);numCores = coreIdSet.size();}str = in.readLine();}} catch (IOException io) {LOG.warn("Error reading the stream " + io);} finally {// Close the streamstry {fReader.close();try {in.close();} catch (IOException i) {LOG.warn("Error closing the stream " + in);}} catch (IOException i) {LOG.warn("Error closing the stream " + fReader);}}readCpuInfoFile = true;}/*** 读/proc/stat file, parse and calculate cumulative CPU.*/private void readProcStatFile() {// Read "/proc/stat" fileBufferedReader in;InputStreamReader fReader;try {fReader = new InputStreamReader(new FileInputStream(procfsStatFile), Charset.forName("UTF-8"));in = new BufferedReader(fReader);} catch (FileNotFoundException f) {// shouldn't happen....return;}Matcher mat;try {String str = in.readLine();while (str != null) {mat = CPU_TIME_FORMAT.matcher(str);if (mat.find()) {long uTime = Long.parseLong(mat.group(1));long nTime = Long.parseLong(mat.group(2));long sTime = Long.parseLong(mat.group(3));cpuTimeTracker.updateElapsedJiffies(BigInteger.valueOf(uTime + nTime + sTime),getCurrentTime());break;}str = in.readLine();}} catch (IOException io) {LOG.warn("Error reading the stream " + io);} finally {// Close the streamstry {fReader.close();try {in.close();} catch (IOException i) {LOG.warn("Error closing the stream " + in);}} catch (IOException i) {LOG.warn("Error closing the stream " + fReader);}}}/*** Read /proc/net/dev file, 解析并计算通过网络读取和写入的字节数。*/private void readProcNetInfoFile() {numNetBytesRead = 0L;numNetBytesWritten = 0L;// Read "/proc/net/dev" fileBufferedReader in;InputStreamReader fReader;try {fReader = new InputStreamReader(new FileInputStream(procfsNetFile), Charset.forName("UTF-8"));in = new BufferedReader(fReader);} catch (FileNotFoundException f) {return;}Matcher mat;try {String str = in.readLine();while (str != null) {mat = PROCFS_NETFILE_FORMAT.matcher(str);if (mat.find()) {assert mat.groupCount() >= 16;// 忽略环回接口if (mat.group(1).equals("lo")) {str = in.readLine();continue;}numNetBytesRead += Long.parseLong(mat.group(2));numNetBytesWritten += Long.parseLong(mat.group(10));}str = in.readLine();}} catch (IOException io) {LOG.warn("Error reading the stream " + io);} finally {// Close the streamstry {fReader.close();try {in.close();} catch (IOException i) {LOG.warn("Error closing the stream " + in);}} catch (IOException i) {LOG.warn("Error closing the stream " + fReader);}}}/*** Read /proc/diskstats file, 解析和计算从磁盘读取和写入磁盘的字节数。*/private void readProcDisksInfoFile() {numDisksBytesRead = 0L;numDisksBytesWritten = 0L;// Read "/proc/diskstats" fileBufferedReader in;try {in = new BufferedReader(new InputStreamReader(new FileInputStream(procfsDisksFile), Charset.forName("UTF-8")));} catch (FileNotFoundException f) {return;}Matcher mat;try {String str = in.readLine();while (str != null) {mat = PROCFS_DISKSFILE_FORMAT.matcher(str);if (mat.find()) {String diskName = mat.group(4);assert diskName != null;// 忽略循环或ram分区if (diskName.contains("loop") || diskName.contains("ram")) {str = in.readLine();continue;}Integer sectorSize;synchronized (perDiskSectorSize) {sectorSize = perDiskSectorSize.get(diskName);if (null == sectorSize) {// 检索扇区大小// 如果不可用或错误,假设512sectorSize = readDiskBlockInformation(diskName, 512);perDiskSectorSize.put(diskName, sectorSize);}}String sectorsRead = mat.group(7);String sectorsWritten = mat.group(11);if (null == sectorsRead || null == sectorsWritten) {return;}numDisksBytesRead += Long.parseLong(sectorsRead) * sectorSize;numDisksBytesWritten += Long.parseLong(sectorsWritten) * sectorSize;}str = in.readLine();}} catch (IOException e) {LOG.warn("Error reading the stream " + procfsDisksFile, e);} finally {// Close the streamstry {in.close();} catch (IOException e) {LOG.warn("Error closing the stream " + procfsDisksFile, e);}}}/*** Read /sys/block/diskName/queue/hw_sector_size file, 解析并计算特定磁盘的扇区大小* @return sector size of specified disk, or defSector*/int readDiskBlockInformation(String diskName, int defSector) {assert perDiskSectorSize != null && diskName != null;String procfsDiskSectorFile ="/sys/block/" + diskName + "/queue/hw_sector_size";BufferedReader in;try {in = new BufferedReader(new InputStreamReader(new FileInputStream(procfsDiskSectorFile),Charset.forName("UTF-8")));} catch (FileNotFoundException f) {return defSector;}Matcher mat;try {String str = in.readLine();while (str != null) {mat = PROCFS_DISKSECTORFILE_FORMAT.matcher(str);if (mat.find()) {String secSize = mat.group(1);if (secSize != null) {return Integer.parseInt(secSize);}}str = in.readLine();}return defSector;} catch (IOException|NumberFormatException e) {LOG.warn("Error reading the stream " + procfsDiskSectorFile, e);return defSector;} finally {// Close the streamstry {in.close();} catch (IOException e) {LOG.warn("Error closing the stream " + procfsDiskSectorFile, e);}}}/** {@inheritDoc} */@Overridepublic long getPhysicalMemorySize() {readProcMemInfoFile();return (ramSize- hardwareCorruptSize- (hugePagesTotal * hugePageSize)) * 1024;}/** {@inheritDoc} */@Overridepublic long getVirtualMemorySize() {return getPhysicalMemorySize() + (swapSize * 1024);}/** {@inheritDoc} */@Overridepublic long getAvailablePhysicalMemorySize() {readProcMemInfoFile(true);long inactive = inactiveFileSize != -1? inactiveFileSize: inactiveSize;return (ramSizeFree + inactive) * 1024;}/** {@inheritDoc} */@Overridepublic long getAvailableVirtualMemorySize() {return getAvailablePhysicalMemorySize() + (swapSizeFree * 1024);}/** {@inheritDoc} */@Overridepublic int getNumProcessors() {readProcCpuInfoFile();return numProcessors;}/** {@inheritDoc} */@Overridepublic int getNumCores() {readProcCpuInfoFile();return numCores;}/** {@inheritDoc} */@Overridepublic long getCpuFrequency() {readProcCpuInfoFile();return cpuFrequency;}/** {@inheritDoc} */@Overridepublic long getCumulativeCpuTime() {readProcStatFile();return cpuTimeTracker.getCumulativeCpuTime();}/** {@inheritDoc} */@Overridepublic float getCpuUsagePercentage() {readProcStatFile();float overallCpuUsage = cpuTimeTracker.getCpuTrackerUsagePercent();if (overallCpuUsage != CpuTimeTracker.UNAVAILABLE) {overallCpuUsage = overallCpuUsage / getNumProcessors();}return overallCpuUsage;}/** {@inheritDoc} */@Overridepublic float getNumVCoresUsed() {readProcStatFile();float overallVCoresUsage = cpuTimeTracker.getCpuTrackerUsagePercent();if (overallVCoresUsage != CpuTimeTracker.UNAVAILABLE) {overallVCoresUsage = overallVCoresUsage / 100F;}return overallVCoresUsage;}/** {@inheritDoc} */@Overridepublic long getNetworkBytesRead() {readProcNetInfoFile();return numNetBytesRead;}/** {@inheritDoc} */@Overridepublic long getNetworkBytesWritten() {readProcNetInfoFile();return numNetBytesWritten;}@Overridepublic long getStorageBytesRead() {readProcDisksInfoFile();return numDisksBytesRead;}@Overridepublic long getStorageBytesWritten() {readProcDisksInfoFile();return numDisksBytesWritten;}/*** 测试 {@link SysInfoLinux}.** @param args - arguments to this calculator test*/public static void main(String[] args) {SysInfoLinux plugin = new SysInfoLinux();System.out.println("Physical memory Size (bytes) : "+ plugin.getPhysicalMemorySize());System.out.println("Total Virtual memory Size (bytes) : "+ plugin.getVirtualMemorySize());System.out.println("Available Physical memory Size (bytes) : "+ plugin.getAvailablePhysicalMemorySize());System.out.println("Total Available Virtual memory Size (bytes) : "+ plugin.getAvailableVirtualMemorySize());System.out.println("Number of Processors : " + plugin.getNumProcessors());System.out.println("CPU frequency (kHz) : " + plugin.getCpuFrequency());System.out.println("Cumulative CPU time (ms) : " +plugin.getCumulativeCpuTime());System.out.println("Total network read (bytes) : "+ plugin.getNetworkBytesRead());System.out.println("Total network written (bytes) : "+ plugin.getNetworkBytesWritten());System.out.println("Total storage read (bytes) : "+ plugin.getStorageBytesRead());System.out.println("Total storage written (bytes) : "+ plugin.getStorageBytesWritten());try {// 睡眠,以便计算CPU使用量Thread.sleep(500L);} catch (InterruptedException e) {// do nothing}System.out.println("CPU usage % : " + plugin.getCpuUsagePercentage());}@VisibleForTestingvoid setReadCpuInfoFile(boolean readCpuInfoFileValue) {this.readCpuInfoFile = readCpuInfoFileValue;}public long getJiffyLengthInMillis() {return this.jiffyLengthInMillis;}
}

从源码中可以看到,linux上的资源信息是从各个文件中获取的:

/proc/meminfo    解析和计算内存信息
/proc/cpuinfo    解析和计算CPU信息
/proc/stat        获取CPU的运行数据
/proc/net/dev    解析并计算通过网络读取和写入的字节数。
/proc/diskstats    解析和计算从磁盘读取和写入磁盘的字节数
/sys/block/partition_name/queue/hw_sector_size 解析并计算特定磁盘的扇区大小

下面我们看下linux操作系统中的这些文件中都是什么内容

三、proc下各示例文件

1、/proc/meminfo

MemTotal:       131479404 kB 
MemFree:        29109144 kB
MemAvailable:   109564132 kB
Buffers:         3922940 kB
Cached:         65545372 kB
SwapCached:            0 kB
Active:          9252304 kB
Inactive:       79107168 kB
Active(anon):     120256 kB
Inactive(anon): 18893260 kB
Active(file):    9132048 kB
Inactive(file): 60213908 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:            123956 kB
Writeback:             0 kB
AnonPages:      18856940 kB
Mapped:           151268 kB
Shmem:            122260 kB
KReclaimable:   12166144 kB
Slab:           13454424 kB
SReclaimable:   12166144 kB
SUnreclaim:      1288280 kB
KernelStack:       29584 kB
PageTables:        88028 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    65739700 kB
Committed_AS:   34508552 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      168540 kB
VmallocChunk:          0 kB
Percpu:           210432 kB
HardwareCorrupted:     0 kB
AnonHugePages:  12728320 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
DupText:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:     2277228 kB
DirectMap2M:    119357440 kB
DirectMap1G:    14680064 kB

/proc/meminfo是了解Linux系统内存使用状况的主要接口,我们最常用的”free”、”vmstat”等命令就是通过它获取数据的

MemTotal:系统从加电开始到引导完成,firmware/BIOS要保留一些内存,kernel本身要占用一些内存,最后剩下可供kernel支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的

MemFree:表示系统尚未使用的内存。[MemTotal-MemFree]就是已被用掉的内存

MemAvailable:有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,要注意这是一个估计值,并不精确

Buffers:用于缓存数据的内存量

Cached:用于缓存文件系统数据的内存量

SwapCached:用于缓存交换分区数据的内存量

Active:活跃内存量,活跃指最近被访问过或正在使用中的内存

Inactive:非活跃内存量,非活跃指长时间没有被访问或已经释放但仍在缓冲区中的内存

Active(anon):活跃的匿名内存

Inactive(anon):不活跃的匿名内存

Active(file):活跃的文件使用内存

Inactive(file):不活跃的文件使用内存

Unevictable:不能被释放的内存页

Mlocked:系统调用 mlock 家族允许程序在物理内存上锁住它的部分或全部地址空间。这将阻止Linux 将这个内存页调度到交换空间(swap space),即使该程序已有一段时间没有访问这段空间

SwapTotal:交换分区总容量

SwapFree:交换分区剩余容量

Dirty:脏页面数量,脏页面是指已经被修改但还没有被写回磁盘的页面

Writeback:等待写回磁盘的页面数量

AnonPages:未映射页的内存大小

Mapped:设备和文件等映射的大小

Shmem:包含共享内存以及tmpfs文件系统占用的内存

KReclaimable:SReclaimable的基础上加上MISC_RECLAIMABLE

Slab:Slab是Linux中用来管理小块内核对象分配和释放的一种内存管理机制,Slab = SReclaimable + SUnreclaim

SReclaimable:slab中可回收的部分

SUnreclaim:slab中不可回收的部分

KernelStack:内核消耗的内存

PageTables:管理内存分页的索引表的大小

NFS_Unstable:不稳定页表的大小

Bounce:在低端内存中分配一个临时buffer作为跳转,把位于高端内存的缓存数据复制到此处消耗的内存

WritebackTmp:FUSE用于临时写回缓冲区的内存

CommitLimit:系统实际可分配内存

Committed_AS:系统当前已分配的内存

VmallocTotal:预留的虚拟内存总量

VmallocUsed:已经被使用的虚拟内存

VmallocChunk:可分配的最大的逻辑连续的虚拟内存

Percpu:表示用于percpu分配的的内存大小,不包括metadata

HardwareCorrupted:当系统检测到内存的硬件故障时删除掉的内存页的总量

AnonHugePages:匿名大页缓存

ShmemHugePages:表示用于shared memory或tmpfs的透明大页

ShmemPmdMapped:表示用于用户态shared memory映射的透明大页

FileHugePages:

FilePmdMapped:

DupText:

HugePages_Total:预留的大页内存总量

HugePages_Free:空闲的大页内存

HugePages_Rsvd:已经被应用程序分配但尚未使用的大页内存

HugePages_Surp:初始大页数与修改配置后大页数的差值

Hugepagesize:单个大页内存的大小

Hugetlb:

DirectMap4k:映射TLB为4kB的内存数量

DirectMap2M:映射TLB为2M的内存数量

DirectMap1G:映射TLB为1G的内存数量

2、/proc/cpuinfo

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel Xeon Processor (Skylake, IBRS)
stepping        : 4
microcode       : 0x1
cpu MHz         : 2299.992
cache size      : 16384 KB
physical id     : 0
siblings        : 12
core id         : 0
cpu cores       : 12
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology c
puid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid
_single ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xge
tbv1 xsaves arat umip pku ospke md_clear
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit mmio_stale_data retbleed
bogomips        : 4599.98
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

.................................省略...............................

processor       : 23
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel Xeon Processor (Skylake, IBRS)
stepping        : 4
microcode       : 0x1
cpu MHz         : 2299.992
cache size      : 16384 KB
physical id     : 1
siblings        : 12
core id         : 11
cpu cores       : 12
apicid          : 27
initial apicid  : 27
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat umip pku ospke md_clear
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit mmio_stale_data retbleed
bogomips        : 4599.98
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

通过/proc/cpuinfo,可以查看系统中CPU的提供商和相关配置信息,例如我们想获取,有多少颗物理CPU,每个物理cpu核心数,以及超线程是否开启等信息,下面是每项参数的解释:

processor :系统中逻辑处理核心数的编号,从0开始排序

vendor_id :CPU制造商

cpu family :CPU产品系列代号

model :CPU属于其系列中的哪一代的代号

model name:CPU属于的名字及其编号、标称主频

stepping  :CPU属于制作更新版本

cpu MHz  :CPU的实际使用主频

cache size :CPU二级缓存大小

physical id :单个物理CPU的标号

siblings :单个物理CPU的逻辑CPU数。siblings=cpu cores [*2]

core id :当前物理核在其所处CPU中的编号,这个编号不一定连续

cpu cores :该逻辑核所处CPU的物理核数。比如此处cpu cores 是4个,那么对应core id 可能是 1、3、4、5。

apicid :用来区分不同逻辑核的编号,系统中每个逻辑核的此编号必然不同,此编号不一定连续

fpu :是否具有浮点运算单元(Floating Point Unit)

fpu_exception :是否支持浮点计算异常

cpuid level :执行cpuid指令前,eax寄存器中的值,根据不同的值cpuid指令会返回不同的内容

wp :表明当前CPU是否在内核态支持对用户空间的写保护(Write Protection)

flags :当前CPU支持的功能

bugs :保存内核检测到的硬件错误

bogomips:在系统内核启动时粗略测算的CPU速度(Million Instructions Per Second

clflush size :每次刷新缓存的大小单位

cache_alignment :缓存地址对齐单位

address sizes :可访问地址空间位数

power management :对能源管理的支持

3、/proc/stat

cpu  8736131408 5678 193273561 20516569092 64420147 202089758 24839900 736849109 0 0
cpu0 248135539 221 7727953 977102347 3547852 7843342 1836321 26959080 0 0
cpu1 288960610 208 7253118 939752913 3465875 6253758 983012 22610655 0 0
cpu2 331782665 173 6580943 898614791 3179773 5927649 705463 20377701 0 0
cpu3 357312958 119 6079401 873515056 3082820 5636253 675032 19192651 0 0
cpu4 416415379 134 4970987 817517624 2702326 5029001 461878 15707695 0 0
cpu5 431656991 49 4560783 803250964 2571613 4865074 410522 14757252 0 0
cpu6 435254195 169 4473639 799793313 2533305 4816086 391800 14568012 0 0
cpu7 430149966 193 5306474 799970897 2274711 5119291 4203530 15644401 0 0
cpu8 442943177 38 4245770 792483084 2429873 4720225 472371 14247201 0 0
cpu9 450045462 66 4306296 784947171 2410185 4660788 1014418 13736325 0 0
cpu10 451355787 39 4064980 784676208 2261500 4619102 396365 13709422 0 0
cpu11 457452811 64 3901559 778822656 2231050 4565301 393815 13362096 0 0
cpu12 308242715 360 10256742 887773491 2996516 16295533 1139546 52646450 0 0
cpu13 291977604 326 12356349 906520116 2948164 14127718 995623 49241553 0 0
cpu14 314799511 763 11789179 887439430 2724265 12548004 926359 45887607 0 0
cpu15 343893959 589 10565703 861975365 2476760 11234089 879714 42636791 0 0
cpu16 357686825 202 9889055 850148237 2299417 10596337 839523 40920853 0 0
cpu17 371250803 336 9230196 838222800 2170862 10053101 814107 39442271 0 0
cpu18 381559924 227 8684083 829076848 2133621 9640147 793837 38300080 0 0
cpu19 391204359 360 8217143 820527206 2044874 9294489 780223 37347635 0 0
cpu20 395787749 376 7934865 816504952 2030798 9101060 793620 36768582 0 0
cpu21 382765684 287 8586382 826536768 2751789 9517617 1313220 39011440 0 0
cpu22 403637541 284 7699240 808560612 3025058 8623423 868515 35789081 0 0
cpu23 51859181 83 24592711 1132836231 4127127 17002359 2751076 73984264 0 0
intr 41293626138 0 9 0 0 250 0 0 0 0 0 1257757 0 15 0 12281947 0 0 0 0 0 0 0 0 0 0 74418226 0 9915152 0 62205235 0 16892400 0 170973248 4915 0 3076909346 41960 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 66125412027
btime 1695643289
processes 68123558
procs_running 20
procs_blocked 0
softirq 26896249797 0 1534546890 2296517 681491783 147607814 0 4570937 2751393260 9053148 290452968

/proc/stat记录的是系统进程整体的统计信息

cpu ~ cpu23 描述的指标如下:(单位都是jiffies,1jiffies=0.01秒)

nameusernicesystemidleiowaitirrqsoftirqstealguestguest_nice
cpu8736131408567819327356120516569092644201472020897582483990073684910900
…………………………………………………………
cpu23518591818324592711113283623141271271700235927510767398426400

这部分统计了CPU时间消耗分布在哪些地方,是用户态任务,还是内核或者是中断、idle等等;第一行的第一个字段为"cpu",没有指定CPU号,表示是其他各个CPU时间分布的汇总;而其他行有cpu编号表示特定编号的cpu时间消耗分布情况。

name:cpu汇总/cpu编号

user:到目前为止,CPU上nice值不大于0的用户态任务的运行时间

nice:到目前为止,CPU上nice值大于0的用户态任务的运行时间

system:到目前为止,CPU上内核态的运行时间。包括用户态任务系统调用、异常等陷入内核消耗时间,也包括内核线程消耗的时间; 但是不包括中断和软中断的执行时间

idle:到目前为止,处于idle任务的时间。不包括CPU上因为任务IO阻塞导致CPU上没有任务可运行、处于idle状态的时间。

iowait:到目前为止,由于CPU上任务IO阻塞导致CPU无可运行任务、处于idle的时间。需要强调的是,iowait是在CPU处于idle状态下的一种特殊情况的时间,与上面的“idle”列互补构成CPU上真正处于idle的时间。

irrq:到目前为止,CPU进入到中断处理的时间(在没有使能CONFIG_IRQ_TIME_ACCOUNTING的情况下,大部分架构实际上无法记录到该项,见下面的分析)。

softirq:到目前为止,CPU处理软中断的时间,包括softirqd中处理软中断的时间。

steal:与虚拟化有关

guest:与虚拟化有关

guest_nice:与虚拟化有关

其他指标如下:

intr:系统启动以来的所有interrupts的次数情况

ctxt: 系统上下文切换次数

btime:启动时长(单位:秒),从Epoch(即1970零时)开始到系统启动所经过的时长,每次启动会改变。此处指为1695643289,转换北京时间为2023-09-25 20:01:29

processes:系统启动后所创建过的进程数量。当短时间该值特别大,系统可能出现异常

procs_running:处于Runnable状态的进程个数

procs_blocked:处于被阻塞的进程个数

softirq:此行显示所有CPU的softirq总数,第一列是所有软件和每个软件的总数,后面的列是特定softirq的总数

4、/proc/net/dev

Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo: 8262570189990 1009625458    0 1217    0     0          0         0 8262570189990 1009625458    0    0    0     0       0          0
  eth0: 4725352845467 3727035213    0    0    0     0          0         0 12125473603784 322028286    0    0    0     0       0          0
  eth1: 12250497813726 9789277543    0 1066    0     0          0         0 12066904463831 2712923220    0    0    0     0       0          0

/proc/net/dev提供了网络设备接口的统计信息,lo、eth0、eth1为网络社保接口的名称。下面是具体指标解释

bytes:接收或发送的总字节数。

packets:接收或发送的总数据包数量。

errs:在接收或发送过程中发生的错误数量。

drop:由于缓冲区溢出或其他原因而丢弃的数据包数量。

fifo:由于队列拥塞而丢弃的数据包数量。

frame:由于帧错误而丢弃的数据包数量。

compressed:压缩传输所节省的字节数量。

multicast:接收到多播数据包的数量。

5、/proc/diskstats

 253       0 vda 978184 4128 81150594 20755299 73453182 4078455 1309816689 398292145 0 113223744 426791458 0 0 0 0 15585634 7744013 20200452 365556940 0
 253       1 vda1 977999 4128 81131978 20753990 72102739 4078455 1309816681 396863176 0 112567056 417617166 0 0 0 0 0 0 20199145 365556938 0
 253      16 vdb 10371383 566918 5197295816 186317736 4253043 5537854 2637106896 128050659 0 68754698 314653319 0 0 0 0 411815 284922 185895864 126318932 0
 253      17 vdb1 10371274 566918 5197280288 186316863 4253012 5537854 2637106896 128050617 0 68754916 314367481 0 0 0 0 0 0 185894994 126318932 0
 253      32 vdc 62355261 2902021 51036086962 4222776827 51209471 48829571 38641223240 1144000034 1 453445155 1073094954 0 0 0 0 1186448 1285388 4096018303 1082051035 0
  11       0 sr0 352 0 3115 420 0 0 0 0 0 456 420 0 0 0 0 0 0 419 0 0

/proc/diskstatsv提供了磁盘信息的统计信息,含义从左到右依次如下

设备号 编号 设备  读完成次数  合并完成次数   读扇区次数   读操作花费毫秒数   写完成次数   合并写完成次数   写扇区次数   写操作花费的毫秒数   正在处理的输入/输出请求数   输入/输出操作花费的毫秒数   输入/输出操作花费的加权毫秒数

6、/sys/block/partition_name/queue/hw_sector_size

通过hw_sector_size可以获取磁盘块大小相关的信息。我们把partition_name换成vda、vdb、vdc或者sr0即可,注意:下面的512就是文件的内容

vda、vdb、vdc的磁盘块大小为

512

sr0的磁盘块大小为

2048

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

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

相关文章

前后图片对比控件使用

在build.gradle中添加依赖&#xff1a; implementation com.github.pavel163:BifacialView:1.4.1 在布局文件中&#xff1a; <com.ebr163.bifacialview.view.BifacialViewandroid:id"id/bv_before_after"android:layout_width"match_parent"android:la…

设计模式学习笔记 - 学前简述

1.为什么学习设计模式&#xff1f; 学习设计模式的原因&#xff1a; 应对面试中的设计模式相关问题&#xff1b;写出高质量代码&#xff0c;告别让人吐槽的烂代码&#xff1b;提高复杂代码的设计和开发能力让读源码、学习框架爱事半功倍&#xff1b;为职场发展铺垫。 设计模…

LNMP搭建discuz论坛

discuz论坛是一种网络论坛软件&#xff0c;也称bbs&#xff0c;它是一种用于在互联网上建立论坛社区的程序系统。只哟中功能强大的论坛软件&#xff0c;可以帮助用户建立一个专业、完善的论坛社区&#xff0c;并且可以实现多种功能&#xff0c;如搭建用户注册、登录、查看主题、…

vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据

文章目录 一、按需引入自定义组件&#xff1a;unplugin-vue-components1. 安装[unplugin-vue-components]2. 在vite中使用 二、自动导入依赖包&#xff1a;unplugin-auto-import1.安装2.vite.config.js配置3.使用效果 三、自动生成路由&#xff1a;vite-plugin-pages1、安装2、…

任务处理 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 在某个项目中有多个任务(用tasks数组表示)需要您进行处理&#xff0c;其中tasks[i][si,ei], 你可以在si < day < ei 中的任意一天处理该任务&#xff0c;请…

代码随想录day25--回溯的应用4

LeetCode491.非递减子序列 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;…

【目标跟踪】提供一种简单跟踪测距方法(c++)

文章目录 一、前言二、c代码2.1、Tracking2.2、KalmanTracking2.3、Hungarian2.4、TrackingInfo 三、调用示例四、结果 一、前言 在许多目标检测应用场景中&#xff0c;完完全全依赖目标检测对下游是很难做出有效判断&#xff0c;如漏检。检测后都会加入跟踪进行一些判断或者说…

中科星图——Landsat8_C2_ST数据集是经大气校正的地表温度数据

数据名称&#xff1a; Landsat8_C2_ST 数据来源&#xff1a; USGS 时空范围&#xff1a; 2020年1月-2023年3月 空间范围&#xff1a; 全国 数据简介&#xff1a; Landsat8_C2_ST数据集是经大气校正的地表温度数据&#xff0c;属于Collection2的二级数据产品&#xff0…

nginx 日志改为json格式

nginx 日志改为json格式 场景描述 正常使用nginx时&#xff0c;使用默认的日志输出格式&#xff0c;对于后续日志接入其他第三方日志收集、清洗环节&#xff0c;因分隔符问题可能不是很友好。 xxxx - - [19/Feb/2024:11:16:48 0800] "GET /time_feed HTTP/1.1" 20…

虚拟和现实的界限不存在了吗

Sora是美国人工智能公司OpenAI最新发布的“文生视频”大模型。与之前的模型相比&#xff0c;Sora能够一次性生成长达一分钟的高清视频&#xff0c;这是目前业内主流的数秒钟版本所无法比拟的。Sora的发布在市场上引起了极大的关注&#xff0c;并被认为是人工智能领域的一次重大…

Spring boot 实现监听 Redis key 失效事件

一. 开启Redis key过期提醒 方式一&#xff1a;修改配置文件 redis.conf # 默认 notify-keyspace-events "" notify-keyspace-events Ex方式二&#xff1a;命令行开启 CONFIG SET notify-keyspace-events Ex CONFIG GET notify-keyspace-events二. notify-keyspace-e…

【Java EE初阶十三】网络初识

1. 网络发展史 网络发展的几个主要时期&#xff1a; 单机时代->局域网时代->广域网时代->移动互联网时代 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同工作来完成 业务&#xff0c;就有了网络互…

行人重识别

&#xfeff;在人的感知系统所获得的信息中&#xff0c;视觉信息大约占到80%&#xff5e;85%。行人重识别&#xff08;person re-identification&#xff09;是近几年智能视频分析领域兴起的一项新技术&#xff0c;属于在复杂视频环境下的图像处理和分析范畴&#xff0c;是许多…

300分钟吃透分布式缓存-02讲:如何根据业务来选择缓存模式和组件?

缓存读写模式 如下图&#xff0c;业务系统读写缓存有 3 种模式&#xff1a; & Cache Aside&#xff08;旁路缓存&#xff09; & Read/Write Through&#xff08;读写穿透&#xff09; & Write Behind Caching&#xff08;异步缓存写入&#xff09; Cache Asid…

redis 值中文显示乱码

问题&#xff1a; 解决办法&#xff1a; exit退出 进入时添加 --raw参数

【软件设计师】程序猿需掌握的技能——数据流图

作为一个程序员&#xff0c;不仅要具备高水平的程序编码能力&#xff0c;还要是熟练掌握软件设计的方法和技术&#xff0c;具有一定的软件设计能力&#xff0c;一般包括软件分析设计图&#xff08;常见的有数据流图&#xff0c;程序流程图&#xff0c;系统流程图&#xff0c;E-…

面试官:能不能给 Promise 增加取消功能和进度通知功能... 我:???

扯皮 这段时间闲着没事就去翻翻红宝书&#xff0c;已经看到 Promise 篇了&#xff0c;今天又让我翻到两个陌生的知识点。 因为 Promise 业务场景太多了自我感觉掌握的也比较透彻&#xff0c;之前也跟着 Promise A 的规范手写过完整的 Promise&#xff0c;所以这部分内容基本上…

常用的图像大小进行操作

一&#xff1a;在图像读取时&#xff0c;常用的读取方式包括PIL和CV2。 1&#xff1a;用PIL读取 首先载入PIL&#xff0c;接着用Image打开图片。 from PIL import Image image Image.open("D:/PycharmProjects/python function/0005.png") print(type(image)) imag…

每日一练:LeeCode-501、二叉搜索树中的众数【二叉搜索树+pre辅助节点+DFS】

本文是力扣LeeCode-LeeCode-501、二叉搜索树中的众数【二叉搜索树pre辅助节点DFS】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;…

个性签名大全

只许一生浮世清欢愿我以孤独作为铠甲&#xff0c;自此不再受伤愿我是阳光&#xff0c;明媚而不忧伤我不敢太勇敢太执着太骄傲&#xff0c;我怕失去开始你是我的天使&#xff0c;最后你是我的唯一姐的霸气&#xff0c;无人能比&#xff0c;哥的傲气&#xff0c;无人能朋唯有万事…