Linux 第二十四章

news2024/11/18 13:40:06

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

fd的分配规则

重定向

dup2

命令行中的重定向

isspace

重定向的使用:就是<, >, >>等

那为什么要有2:标准错误

缓冲区

样例

理解样例(2中的样例)

什么叫作刷新

用户缓冲区和内核缓冲区


fd的分配规则

进程默认已经打开了0,1,2,我们可以直接使用0,1,2进行数据访问

[BCH@hcss-ecs-6176 11_28]$ cat myfile.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>


#define FILE_NAME "log.txt"
int main()
{
        char buf[1024];
        ssize_t s=read(0,buf,1024);
        //ssize_t有符号整型
        //read的返回值是实际读取的字节数,1024是我们设置最大读取的字节数,buf接收数据的缓冲区
        //从fd所指向的文件中读取数据放到buf中
        if(s>0)
        {
                buf[s]=0;//将中实际读取的最后一个字符尾加上0
                //printf("%s\n",buf);
                write(1,buf,strlen(buf));//将读取的buf的数据,输出到fd(1)指向的文件,1指向的就是标准输出流,屏幕
        }
        return 0;
}

文件描述符的分配规则:寻找最小的,没有被使用的数据位置,分配给指定的打开文件

[BCH@hcss-ecs-6176 11_28]$ cat myfile.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

#define FILE_NAME "log.txt"
int main()
{
        close(0);//关闭fd==0的文件,标准输入流被关闭(键盘)

        int fd=open(FILE_NAME,O_CREAT | O_WRONLY | O_TRUNC,0666);
        if(fd<0)
        {
                perror("open");
                return 1;
        }

        printf("%s :fd:%d\n",FILE_NAME,fd);//输出被创建的FILE_NAME “log.txt"的文件描述符

        close(fd);
        return 0;
}

[BCH@hcss-ecs-6176 11_28]$ ./myfile
log.txt :fd:0//此时创建的文件的文件描述符为0

[BCH@hcss-ecs-6176 11_28]$ cat myfile.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>

#define FILE_NAME "log.txt"
int main()
{
        close(2);//关闭fd==2的文件,标准错误流流被关闭(屏幕)

        int fd=open(FILE_NAME,O_CREAT | O_WRONLY | O_TRUNC,0666);
        if(fd<0)
        {
                perror("open");
                return 1;
        }

        printf("%s :fd:%d\n",FILE_NAME,fd);//输出被创建的FILE_NAME “log.txt"的文件描述符

        close(fd);
        return 0;
}

[BCH@hcss-ecs-6176 11_28]$ ./myfile
log.txt :fd:2//此时创建的文件的文件描述符为2



[BCH@hcss-ecs-6176 11_28]$ cat myfile.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>


#define FILE_NAME "log.txt"
int main()
{
        close(1);//关闭fd==1的文件,标准输出流被关闭(屏幕)


        int fd=open(FILE_NAME,O_CREAT | O_WRONLY | O_TRUNC,0666);
        if(fd<0)
        {
                perror("open");
                return 1;
        }


        printf("%s :fd:%d\n",FILE_NAME,fd);//输出被创建的FILE_NAME “log.txt"的文件描述符


        close(fd);
        return 0;
}

//什么也没有输出:因为把fd==1的文件关闭了,把标准输出流(屏幕关闭了),所以不输出到屏幕上
[BCH@hcss-ecs-6176 11_28]$ ./myfile
[BCH@hcss-ecs-6176 11_28]$

重定向

重定向的本质,就是修改fd指向的文件

dup2

在Linux中,dup2是一个系统调用函数,用于复制文件描述符。它的原型定义在头文件<unistd.h>中。dup2函数的作用是将一个文件描述符复制到另一个文件描述符上,如果另一个文件描述符已经被使用,那么先关闭它。

函数原型如下:

int dup2(int oldfd, int newfd);
参数说明:
oldfd:要复制的文件描述符。
newfd:要复制到的目标文件描述符。

返回值:
如果成功,返回新的文件描述符(即newfd);如果失败,返回-1,并设置errno。
这个函数通常用于重新定向标准输入、标准输出和标准错误流,以及实现管道和重定向等功能。

例如,下面的代码将标准输出重定向到文件output.txt中:

#include <unistd.h>
#include <fcntl.h>
int main() {
    int fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open");
        return 1;
    }
    // 将标准输出重定向到文件描述符fd所指向的文件
    if (dup2(fd, STDOUT_FILENO) == -1) {
        perror("dup2");
        return 1;
    }
    // 关闭不再需要的文件描述符
    close(fd);
    // 此时标准输出已经重定向到output.txt文件
    printf("This will be written to output.txt\n");
    return 0;
}

在这个示例中,dup2函数将文件描述符fd复制到标准输出的文件描述符上,从而将标准输出重定向到了output.txt文件中

命令行中的重定向

[BCH@hcss-ecs-6176 11_28]$ echo "hello">log.txt
[BCH@hcss-ecs-6176 11_28]$ cat log.txt
hello
[BCH@hcss-ecs-6176 11_28]$ echo "hello">>log.txt
[BCH@hcss-ecs-6176 11_28]$ cat log.txt
hello
hello
[BCH@hcss-ecs-6176 11_28]$ cat <log.txt
hello
hello

isspace

在Linux中,isspace()是一个用于判断字符是否为空白字符的C标准库函数。它位于<ctype.h>头文件中。isspace()函数接受一个整型参数,该参数可被解释为unsigned char或EOF的值。它检查这个字符是否为空格、水平制表符、换行符、回车符、换页符或垂直制表符。如果是空白字符,isspace()函数返回一个非零值(true),否则返回0(false)。

以下是一个示例程序,演示了isspace()函数的使用:

#include <stdio.h>
#include <ctype.h>

int main() {
    int ch;

    printf("请输入一个字符:");
    ch = getchar();

    if (isspace(ch)) {
        printf("输入的字符是空白字符。\n");
    } else {
        printf("输入的字符不是空白字符。\n");
    }

    return 0;
}


该程序首先提示用户输入一个字符,然后使用getchar()函数获取用户输入的字符。接下来,使用isspace()函数判断该字符是否为空白字符,并打印相应的提示信息。

注意,isspace()函数只能判断单个字符是否为空白字符,而不能判断字符串中的空白字符。如果需要判断整个字符串是否只包含空白字符,可以自行编写相应的逻辑。

重定向的使用:就是<, >, >>等

那为什么要有2:标准错误

[BCH@hcss-ecs-6176 testfile]$ cat myfile.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
int main()
{
        fprintf(stdout,"hello stdout\n");
        fprintf(stderr,"hello stderr\n");
        return 0;
}

[BCH@hcss-ecs-6176 testfile]$ ./myfile
hello stdout
hello stderr
都是打在屏幕上

但是为什么重定向的时候,会出现如下结果呢
[BCH@hcss-ecs-6176 testfile]$ ./myfile > log.txt
hello stderr
[BCH@hcss-ecs-6176 testfile]$ cat log.txt
hello stdout

原因:因为重定向的时候,只是重定向了fd==1,而fd==2并没有,所以屏幕上还是会显示hello stderr,log.txt里含有hello stdout

那为什么要有2呢?

[BCH@hcss-ecs-6176 testfile]$ ./myfile >log.txt
hello stderr
[BCH@hcss-ecs-6176 testfile]$ ./myfile 1>log.txt
hello stderr
这两种写法是一样的,只是一个是省略的写法
[BCH@hcss-ecs-6176 testfile]$ ./myfile 1>log.txt 2>log.txt.error
[BCH@hcss-ecs-6176 testfile]$ ls
log.txt  log.txt.error  Makefile  myfile  myfile.c

就是我们在写程序的时候,有时需要显示常规信息,例如printf输出的,有时需要显示错误信息
所以我们可以通过重定向把常规信息输出到一个文件,错误信息输出到另一个文件(方便我们统一排查,例如,日志)

linux实现自己的bash

缓冲区

预备知识
我们理解缓冲区:就是一部分内存(由提供的??)

为什么要缓冲区?
缓冲区的主要作用是提高效率——提高使用者的效率

缓冲区因为能够暂存数据,必定要有一定的刷新方式:
1.无缓冲(立即刷新)
2.行缓冲(行刷新)
3.全缓冲(缓冲区满了,再刷新)

特殊情况:
1.强制刷新
2.进程退出的时候,一般要进行刷新缓冲区

一般对于显示器文件,行刷新(行缓冲)
对于磁盘上的文件,全缓冲(缓冲写满,再刷新)

样例

[BCH@hcss-ecs-6176 12_5]$ cat myfile.c
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
{
        fprintf(stdout,"C:hello fprintf\n");
        printf("C:hello printf\n");
        fputs("C:hello fputs\n",stdout);
        
        char * str="system call: hello write\n";
        write(1,str,strlen(str));

        fork();//注意fork的位置
        //如果fork在最前面,我们都能理解,因为子进程和父进程会同时执行
        //但是,fork在最后面,父进程已经运行完了,怎还能将代码打印两次呢?

        return 0;
}

[BCH@hcss-ecs-6176 12_5]$ ./myfile
C:hello fprintf
C:hello printf
C:hello fputs
system call: hello write
[BCH@hcss-ecs-6176 12_5]$ ./myfile > log.txt
[BCH@hcss-ecs-6176 12_5]$ cat log.txt
system call: hello write
C:hello fprintf
C:hello printf
C:hello fputs
C:hello fprintf
C:hello printf
C:hello fputs
//c语言的接口的打印了两次,系统调用接口的打印了一次

理解样例(2中的样例)

1.当我们直接向显示器打印的时候,显示器文件的刷新方式是行刷新!而且你的代码输出的所有字符串,都有\n,fork之前,数据全部已经被刷新,包括sysstemcall

2.重定向到log.txt,本质是向磁盘文件中写入,我们系统对于数据的刷新方式已经由行刷新,变成了全缓冲!

3.全缓冲意味着缓冲区变大,实际写入的简单数据,不足以把缓冲区写满,fork执行的时候,数据区依就在就缓冲区中!

4.我们所谈的“缓冲区”和操作系统是没有关系的(printf/fprintf/fputs——底层都是封装的write),只能和C语言本身有关

5.C/C++提供的缓冲区,里面一定保存的是用户的数据,属不属于当前进程在运行时自己数据呢?属于
如果我们(进程)把数据交给了OS,这个数据就属于OS,不属于OS,不属于我自己的

6.当进程退出的时候,一般要进行刷新缓冲区,即便你的数据没有满足刷新条件!
这个过程,属于清空或写入操作

fork立马退出,任意一个进程退出的时候,刷新缓冲区,就要发生写时拷贝
write系统调用,没有使用C的缓冲区!!!
write直接写入到操作系统!不属于进程了!不发生写时拷贝了

什么叫作刷新

这个缓冲区在哪里
任何情况下,我们输入输出的时候,都要有一个FILE
FILE是一个结构体,FILE里面包含了fd,FILE提供一段缓冲区

例如输入缓冲区
例如输出缓冲区
每一个文件(linux所说的文件)都有一个缓冲区

用户缓冲区和内核缓冲区


我们日常使用的最的是C/C++提供的语言级别的缓冲区

我们模拟实现一下C标准库的函数——只做代码说明

注意:

在c语言头文件中,函数声明不用加extern,后面加分号结尾就行

但是变量一定要加extern,因为无法分清这个变量是声明还是定义

mystdio.h
[BCH@hcss-ecs-6176 c_lib]$ cat mystdio.h
#pragma once//防止头文件重复包含


#define SIZE 4096
#define FLUSH_NONE 1
#define FLUSH_LINE (1<<1)
#define FLUSH_ALL (1<<2)


typedef struct myFILE
{
        int fileno;
        int flag;
        char buffer[SIZE];
        int end;
}myFILE;


extern  myFILE* my_fopen(const char* path,const char* mode);
extern  int my_fputs(const char* s,myFILE* stream);
extern  int my_fwrite(const char* s,int num,myFILE* stream);
extern  int my_fflush(myFILE* stream);
extern  int my_fclose(myFILE* stream);

mystdio.c
[BCH@hcss-ecs-6176 c_lib]$ cat mystdio.c
#include"mystdio.h"
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>


#define DFL_MODE 0666


myFILE* my_fopen(const char* path,const char* mode)
{
        int fd=0;
        int flag=0;
        if(strcmp(mode,"r")==0)
        {
                flag |= O_RDONLY;
        }
        else if(strcmp(mode,"w")==0)
        {
                flag |=(O_CREAT | O_TRUNC | O_WRONLY);
        }
        else if(strcmp(mode,"a"))
        {
                flag |=(O_CREAT|O_WRONLY|O_APPEND);
        }
        else
        {


        }


        if(flag & O_CREAT)
        {
                fd=open(path,flag,DFL_MODE);
        }
        else
        {
                fd=open(path,flag);
        }
        if(fd<0)
        {
                errno=2;
                return NULL;
        }
        myFILE* fp=(myFILE*)malloc(sizeof(myFILE));
        if(fp==NULL)
        {
                errno=3;
                return NULL;
        }
        fp->fileno=fd;
        fp->end=0;
        fp->flag=FLUSH_LINE;
        return fp;
}
int my_fwrite(const char* s,int num,myFILE* stream)
{
        //写入过程
        memcpy(stream->buffer+stream->end,s,num);
        stream->end+=num;
        //判断是否需要刷新
        if((stream->flag& FLUSH_LINE)&&stream->end>0&&stream->buffer[stream->end-1]=='\n')
        {
                //"abc\ndt";这种情况处理
                
                my_fflush(stream);
        }
        return num;
}
int my_fflush(myFILE* stream)
{


        if(stream->end>0)
        {
                write(stream->fileno,stream->buffer,stream->end);
                stream->end=0;
        }
        return 0;
}
int my_fclose(myFILE* stream)
{
        my_fflush(stream);
        return close(stream->fileno);
}

main.c
[BCH@hcss-ecs-6176 c_lib]$ cat main.c
#include"mystdio.h"
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
{
        myFILE* fp=my_fopen("./log.txt","w");
        if(fp==NULL)
        {
                perror("my_fopen");
                return 1;
        }
        int cnt=20;
        const char* msg="haha,this is my stdio lib\n";
        while(cnt--)
        {
                my_fwrite(msg,strlen(msg),fp);
                sleep(1);
        }




        my_fclose(fp);
        return 0;
}

Makefile
[BCH@hcss-ecs-6176 c_lib]$ cat Makefile
mytest:mystdio.c main.c
        gcc -o $@ $^
.PHONY:clean
clean:
        rm -f mytest

make
[BCH@hcss-ecs-6176 c_lib]$ make
gcc -o mytest mystdio.c main.c
[BCH@hcss-ecs-6176 c_lib]$ ./mytest
[BCH@hcss-ecs-6176 c_lib]$ ls
log.txt  main.c  Makefile  mystdio.c  mystdio.h  mytest
[BCH@hcss-ecs-6176 c_lib]$ cat log.txt
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib
haha,this is my stdio lib






























  🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 

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

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

相关文章

python面向函数

组织好的&#xff0c;可重复利用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段&#xff0c;避免重复造轮子&#xff0c;增加程序复用性。 定义方法为def 函数名 (参数) 参数可动态传参&#xff0c;即使用*args代表元组形式**kwargs代表字典形式&#xff0c;代替…

探索智能编程新境界:我与Baidu Comate的独特体验之旅

文章目录 一、认识Baidu Comate二、VS Code安装Baidu Comate教程三、Baidu Comate功能体验功能概览具体功能1.根据注释自动生成代码2.函数注释3.行间注释4.代码解释5.生成单元测试6.代码优化7.答疑解惑 四、交互体验五、总结 一、认识Baidu Comate ✨Baidu Comate插件是一款基…

如何在PPT中插入网页?这样操作,免费还高效!

融合课、跨学科课&#xff0c;已经是近两年来教育界的热门词。 在公开课、微课比赛中&#xff0c;不添融合一些较为先进的信息技术&#xff0c;都不好意思拿出手了。 最近&#xff0c;由不坑老师开发制作的Office插件——不坑盒子&#xff0c;实现了在PPT中插入网页&#xff…

鸿蒙开发接口Ability框架:【(StaticSubscriberExtensionAbility)】

StaticSubscriberExtensionAbility StaticSubscriberExtensionAbility模块提供静态订阅者扩展能力的类别的能力。 说明&#xff1a; 本模块首批接口从API version 9 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下…

987: 输出用先序遍历创建的二叉树是否为完全二叉树的判定结果

解法&#xff1a; 一棵二叉树是完全二叉树的条件是&#xff1a; 对于任意一个结点&#xff0c;如果它有右子树而没有左子树&#xff0c;则这棵树不是完全二叉树。 如果一个结点有左子树但是没有右子树&#xff0c;则这个结点之后的所有结点都必须是叶子结点。 如果满足以上条…

ADOP带你了解:温度如何影响您的室外以太网电缆?

温度&#xff1a;室外以太网电缆的隐形敌人 在构建和维护室外以太网网络时&#xff0c;我们通常会考虑到许多物理因素&#xff0c;如电缆的长度、宽带容量和连接质量。然而&#xff0c;有一个不那么显眼但同样重要的因素常常被忽视&#xff0c;那就是温度。温度的波动不仅影响…

物联网实战--平台篇之(四)账户后台交互

目录 一、交互逻辑 二、请求验证码 三、帐号注册 四、帐号/验证码登录 五、重置密码 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631…

《21天学通C++》(第二十章)STL映射类(map和multimap)

为什么需要map和multimap&#xff1a; 1.查找高效&#xff1a; 映射类允许通过键快速查找对应的值&#xff0c;这对于需要频繁查找特定元素的场景非常适合。 2.自动排序&#xff1a; 会自动根据键的顺序对元素进行排序 3.多级映射&#xff1a; 映射类可以嵌套使用&#xff0c;创…

java.net.SocketInputStream.socketRead0 卡死导致 tomcat 线程池打满的问题

0 TL;DR; 问题与原因&#xff1a;某些特定条件下 java.net.SocketInputStream.socketRead0 方法会卡死&#xff0c;导致运行线程一直被占用导致泄露采用的方案&#xff1a;使用监控线程异步监控卡死事件&#xff0c;如果发生直接关闭网络连接释放链接以及对应的线程 1. 问题 …

贪心算法--将数组和减半的最小操作数

本题是力扣2208---点击跳转题目 思路&#xff1a; 要尽快的把数组和减小&#xff0c;那么每次挑出数组中最大的元素减半即可&#xff0c;由于每次都是找出最值元素&#xff0c;可以用优先队列来存储这些数组元素 每次取出最值&#xff0c;减半后再放入优先队列中&#xff0c;操…

最新:Lodash 严重安全漏洞背后你不得不知道的 JavaScript 知识

可能有信息敏感的同学已经了解到&#xff1a;Lodash 库爆出严重安全漏洞&#xff0c;波及 400万 项目。这个漏洞使得 lodash “连夜”发版以解决潜在问题&#xff0c;并强烈建议开发者升级版本。 我们在忙着“看热闹”或者“”升级版本”的同时&#xff0c;静下心来想&#xf…

如何通过代理IP实现搜索引擎优化

目录 前言 一、代理IP的基本概念 二、通过代理IP访问其他地区的搜索引擎 三、对比不同地区搜索结果 结论 前言 搜索引擎优化&#xff08;Search Engine Optimization&#xff0c;SEO&#xff09;是指通过优化网站的结构、内容和关键词等因素&#xff0c;提高网站在搜索引…

ubuntu挂载固态硬盘

ubuntu挂载固态硬盘 两种情况 包装盒拆出来的新硬盘用过的需要后处理的硬盘 新硬盘 一、确认硬盘设备 插上主机后输入 lsblk检查是否识别到你插入的硬盘 可以看到上图的nvme0n1是我挂载的硬盘&#xff08;目前已经挂载完成并映射到 ~/ssd目录&#xff09;&#xff0c;nvm…

如果你这样使用电路仿真软件,你就无敌了!

在电子设计领域&#xff0c;电路仿真软件如同一把锋利的宝剑&#xff0c;掌握它&#xff0c;你就能在复杂的电子世界中游刃有余。今天&#xff0c;就让我们一起探讨如何高效利用电路仿真软件&#xff0c;让你在电子设计领域所向披靡&#xff01; 一、熟悉软件界面与基础操作 …

点击短信链接唤起Android App实战

一.概述 在很多业务场景中,需要点击短信链接跳转到App的指定页面。在Android系统中,想要实现这个功能,可以通过DeepLink或AppLink实现。二.方案 2.1 DeepLink 2.1.1 方案效果 DeepLink是Android系统最基础、最普遍、最广泛的外部唤起App的方式,不受系统版本限制。当用户…

基于Vue3与ElementUI Plus的酷企秀场景可视化DIY设计器:前端技术引领下的数字化展示新篇章

一、引言 在当今信息化高速发展的时代&#xff0c;企业对于展示自身形象、提升用户体验以及增强品牌知名度的需求日益迫切。针对这一市场需求&#xff0c;我们推出了基于Vue3与ElementUI Plus的酷企秀场景可视化DIY设计器。该产品不仅具备电子画册、VR全景、地图秀三大核心功能…

2024年自动驾驶、车辆工程与智能交通国际会议(ICADVEIT2024)

2024年自动驾驶、车辆工程与智能交通国际会议&#xff08;ICADVEIT2024&#xff09; 会议简介 2024年自动驾驶、车辆工程和智能交通国际会议&#xff08;ICADVEIT 2024&#xff09;将在中国深圳举行。会议主要聚焦自动驾驶、车辆工程和智能交通等研究领域&#xff0c;旨在为从…

pytest教程-42-钩子函数-pytest_runtest_makereport

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_runtest_teardown钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_runtest_makereport钩子函数的使用方法。 pytest_runtest_makereport 钩子函数在 pytest 为每个测试生成报…

使用HashMap实现,对一个字符集进行哈夫曼编码

最终达到的效果: 调用一个类 class HuffmanCodin{.....} 使用类中的静态方法&#xff0c;获取哈夫曼编码&#xff1a; 事前准备——哈夫曼树的节点定义 class Node implements Comparable<Node> {int weight;//权重Node left;Node right;char ch;//关键字&#xff0c…

Zabbix5.0——安装与部署

目录 一、zabbix-server(192.168.206.134) 监控方 1. 环境准备 2.安装zabbix 2.1 准备zabbix-repo 2.2清理缓存 2.3安装zabbix主包&#xff08;服务器和代理&#xff09; 2.4安装zabbix前端包 3. 数据库安装 3.1 授权zabbix账号 3.2导入数据库&#xff08;初始化zabbix&#x…