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

日志系统项目(2)项目实现(实用工具类、日志等级类、日志消息类、日志格式化输出类)

前面的文章中我们讲述了日志系统项目的前置知识点,再本文中我们将开始日志项目的细节实现。

日志系统框架设计

本项目实现的是一个多日志器日志系统,主要实现的功能是让程序员能够轻松的将程序运行日志信息落地到指定的位置,且支持同步与异步两种方式的日志落地方式。
项目的框架设计将项目分为以下几个模块来实现。

模块划分

  • 日志等级模块:对输出日志的等级进行划分,以便于控制日志的输出,并提供等级枚举转字符串功能。

    • OFF:关闭
    • DEBUG:调试,调试时的关键信息输出。
    • INFO:提示,普通的提示型日志信息。
    • WARN:警告,不影响运行,但是需要注意一下的日志。
    • ERROR:错误,程序运行出现错误的日志。
    • FATAL:致命,一般是代码异常导致程序无法继续推进运行的日志。
  • 日志消息模块:中间存储日志输出所需的各项要素信息

    • 时间:描述本条日志的输出时间。
    • 线程ID:描述本条日志是哪个线程输出的。
    • 日志等级:描述本条日志的等级。
    • 日志数据:本条日志的有效载荷数据。
    • 日志文件名:描述本条日志在哪个源码文件中输出的。
    • 日志行号:描述本条日志在源码文件的哪一行输出的。
  • 日志消息格式化模块:设置日志输出格式,并提供对日志消息进行格式化功能。

    • 系统的默认日志输出格式:%d{%H:%M:%S}%T[9%t]%T[%p]%T[%c]%T%f:%1%T%m%no
      ->13:26:32 [2343223321] [FATAL] [root] main.c:76 套接字创建失败\n
    • %d{%H:%M:%S}:表示日期时间,花括号中的内容表示日期时间的格式。
    • %T:表示制表符缩进。
    • %t:表示线程ID。
    • %p:表示日志级别。
    • %c:表示日志器名称,不同的开发组可以创建自己的日志器进行日志输出,小组之间互不影响。
    • %f:表示日志输出时的源代码文件名。
    • %l:表示日志输出时的源代码行号。
    • %m:表示给与的日志有效载荷数据。
    • %n:表示换行。
    • 设计思想:设计不同的子类,不同的子类从日志消息中取出不同的数据进行处理。
  • 日志消息落地模块∶决定了日志的落地方向,可以是标准输出,也可以是日志文件,也可以滚动文件输出…

    • 标准输出:表示将日志进行标准输出的打印。
    • 日志文件输出:表示将日志写入指定的文件末尾。
    • 滚动文件输出:当前以文件大小进行控制,当一个日志文件大小达到指定大小,则切换下一个文件进行输出
    • 后期,也可以扩展远程日志输出,创建客户端,将日志消息发送给远程的日志分析服务器。
    • 设计思想:设计不同的子类,不同的子类控制不同的日志落地方向。
  • 日志器模块:

    • 此模块是对以上几个模块的整合模块,用户通过日志器进行日志的输出,有效降低用户的使用难度。
    • 包含有:日志消息落地模块对象,日志消息格式化模块对象,日志输出等级
  • 日志器管理模块:

    • 为了降低项目开发的日志耦合,不同的项目组可以有自己的日志器来控制输出格式以及落地方向,因此本项目是一个多日志器的日志系统。
    • 管理模块就是对创建的所有日志器进行统一管理。并提供一个默认日志器提供标准输出的日志输出。
  • 异步线程模块:

    • 实现对日志的异步输出功能,用户只需要将输出日志任务放入任务池,异步线程负责日志的落地输出功能,以此提供更加高效的非阻塞日志输出。

模块关系图

在这里插入图片描述

代码设计

实用类设计

完成一些零碎的功能接口,以便于后面会用到。

  • 获取系统时间信息
  • 判断文件是否存在
  • 获取文件所在路径
  • 创建目录
/*实用工具类的实现:1. 获取系统时间2. 判断文件是否存在3. 获取文件所在目录4. 创建目录
*/
namespace zyqlog
{namespace util{class Date {public:static size_t now() // 获取当前的系统时间{return (size_t)time(nullptr);}};class File{public:static bool exists(const std::string &pathname) // 判断当前的文件是否存在{// return (access(pathname.c_str(), F_OK) == 0); // Linux下的接口struct stat st;if (stat(pathname.c_str(), &st) < 0){return false;}return true;}static std::string path(const std::string &pathname) // 获取当前的文件路径{// ./abc/a.txtsize_t pos = pathname.find_last_of("/\\"); // 从文件路径最后的一个/或者\\开始获取文件路径if (pos == std::string::npos) return ".";return pathname.substr(0, pos + 1);}static void createDirectory(const std::string &pathname){// ./abc/bcd/a.txtsize_t pos = 0, idx = 0;while (idx < pathname.size()){pos = pathname.find_first_of("/\\", idx); // 从文件路径开始处的/或者\\开始获取文件路径if (pos == std::string::npos) // 获取到的结果如果已到文件末尾则说明传入的整个路径名都是需要创建的目录,直接进行创建{mkdir(pathname.c_str(), 0777);}std::string parent_dir = pathname.substr(0, pos + 1); // 将获取到的每级目录进行截取if (parent_dir == "." || parent_dir == "..") // 如果截取的目录是当前目录或者是上一级目录则继续进行截取。{idx = pos + 1;continue;}if (exists(parent_dir) == true) // 如果目录已经存在则继续进行截取{idx = pos + 1;continue;}mkdir(parent_dir.c_str(), 0777); // 创建截取得到的未创建目录idx = pos + 1;}}};}
}
/*test*/
std::cout << zyqlog::util::Date().now() << std::endl;
std::string pathname = "./abc/bcd/a.txt";
zyqlog::util::File().createDirectory(zyqlog::util::File::path(pathname));

日志等级类设计

日志等级共分为7个等级,分别为:

  • OFF 关闭所有日志输出
  • DRBUG 进行debug时候打印日志的等级
  • INFO 打印一些用户提示信息
  • WARN 打印警告信息
  • ERROR 打印错误信息
  • FATAL 打印致命信息-导致程序崩溃的信息
/*1. 定义枚举类,枚举出日志等级2. 提供转换接口,将枚举转换为对应的字符串
*/
namespace zyqlog
{class LogLevel{private:public:enum class value // 枚举类实现不同的日志等级{UNKNOW = 0,DEBUG,INFO,WARNING,ERROR,FATAL,OFF};static const char *toString(LogLevel::value level) // 将获取到的日志等级转换为字符串{switch (level){case LogLevel::value::DEBUG:return "DEBUG";case LogLevel::value::INFO:return "INFO";case LogLevel::value::WARNING:return "WARNING";case LogLevel::value::ERROR:return "ERROR";case LogLevel::value::FATAL:return "FATAL";case LogLevel::value::OFF:return "OFF";}return "UNKNOW";}};
}

日志消息类设计

/*定义日志消息类,进行日志中间信息的存储:1. 日志的输出时间--用于过滤日志输出时间2. 日志等级--用于进行日志过滤分析3. 源文件名称4. 源代码行号--用于定位出现错误的代码的位置5. 线程ID--用于过滤出错的线程6. 日志主体消息7. 日志器名称--支持多日志器同时使用
*/
namespace zyqlog
{struct LogMsg{time_t _ctime; // 日志产生的时间戳LogLevel::value _level; // 日志等级std::thread::id _tid; // 线程IDsize_t _line; // 行号std::string _file; // 源码文件名std::string _logger; // 日志器名称std::string _payload; // 有效消息数据LogMsg() {}LogMsg(LogLevel::value level, size_t line, const std::string file, const std::string logger, const std::string msg) : _ctime(util::Date::now()), _level(level), _line(line), _tid(std::this_thread::get_id()), _file(file), _logger(logger), _payload(msg){}};
}

日志格式化输出类

日志格式化(Formatter)类主要负责格式化日志消息。其主要包含以下内容

  • pattern成员:保存日志输出的格式字符串
    • %d 日期
    • %T 缩进
    • %t 线程id
    • %p 日志级别
    • %c 日志器名称
    • %f 文件名
    • %l 行号
    • %m 日志消息
    • %n 换行
  • std::vector< FormatItem::ptr > items成员:用于按序保存格式化字符串对应的子格式化对象
    FormatItem类主要负责日志消息子项的获取及格式化。其包含以下子类
  • MsgFormatItem:表示要从LogMsg中取出有效日志数据
  • LevelFormatItem:表示要从LogMsg中取出日志等级
  • ThreadFormatItem:表示要从LogMsg中取出线程ID
  • TimeFormatItem:表示要从LogMsg中取出时间戳并按照指定格式进行格式化
  • LineFormatItem:表示要从LogMsg中取出源码所在行号
  • TabFormatItem:表示⼀个制表符缩进
  • NLineFormatItem:表示⼀个换行
  • OtherFormatItem:表示非格式化的原始字符串

格式化的过程其实就是按次序从Msg中取出需要的数据进行字符串的连接的过程。

// 设计思想:
// 1. 抽象一个格式化子项基类
// 2. 基于基类, 派生出格式化子项子类// 在父类中定义父类指针数组,指向不同格式化子类对象
namespace zyqlog
{// 抽象格式化子项基类class FormatItem{public:using ptr = std::shared_ptr<FormatItem>;virtual void format(std::ostream &out, const LogMsg &msg) = 0;};// 派生类格式化子项子类--消息,等级,时间,文件名,行号,线程ID,日志器名,制表符,换行吗,其他class MsgFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << msg._payload;}};class LevelFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << LogLevel::toString(msg._level);}};class TimeFormatItem : public FormatItem{public:TimeFormatItem(const std::string &fmt = "%H:%M:%S") :_time_fmt(fmt) {}void format(std::ostream &out, const LogMsg &msg) override{struct tm t;localtime_r(&msg._ctime, &t);char tmp[32] = {0};strftime(tmp, 31, _time_fmt.c_str(), &t); // strftime()函数根据格式字符串将给定的日期和时间从给定的日历时间转换为以空结尾的多字节字符串。out << tmp;}private:std::string _time_fmt; // %H:%M:%S};class FileFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << msg._file;}};class LineFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << msg._line;}};class ThreadFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << msg._tid;}};class LoggerFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << msg._logger;}};class TabFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << "\t";}};class NLineFormatItem : public FormatItem{public:void format(std::ostream &out, const LogMsg &msg) override{out << "\n";}};class OtherFormatItem : public FormatItem{public:OtherFormatItem(const std::string &str) :_str(str) {}void format(std::ostream &out, const LogMsg &msg) override{out << _str;}private:std::string _str;};/*%d 表示日期 包含子格式{%H:%M:%S}%t 表示线程ID %c 表示日志器名称%f 表示源码文件名%l 表示源码行号%p 表示日志级别%T 表示制表符缩进%m 日志消息%n 表示换行*/class ForMatter{public:using ptr = std::shared_ptr<ForMatter>;ForMatter(const std::string &pattern = "[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n") : _pattern(pattern) {assert(parsePattern()); // 对格式化规则字符串进行解析}// 对msg进行格式化void format(std::ostream &out, LogMsg &msg){for(auto &item : _items){item->format(out, msg);}}std::string format(LogMsg &msg){std::stringstream ss;format(ss, msg);return ss.str();}private:// 对格式化规则字符串进行解析bool parsePattern(){// 1. 对格式化规则字符串进行解析// abcd[ % d {%H:%M:%S} ][ %t][%c][%f:%l][%p]%T%m%nstd::vector<std::pair<std::string, std::string>> fmt_order;size_t pos = 0;std::string key, val;while (pos < _pattern.size()){// 1. 处理原始字符串--判断是否是%,不是就是原始字符if (_pattern[pos] != '%'){val.push_back(_pattern[pos++]);continue;}// 能进行到此说明pos位置是%字符,%%处理称为一个%字符if (pos + 1 < _pattern.size() && _pattern[pos + 1] == '%'){val.push_back('%');pos += 2;continue;}// 这时候原始字符串处理完毕if (!val.empty()){fmt_order.push_back(std::make_pair("", val));val.clear();}//代表%后面是一个格式化字符,格式化字符的处理pos += 1; // pos指向格式化字符的位置if (pos == _pattern.size()) {std::cerr << "%之后没有对应的字符!\n";return false;}key = _pattern[pos]; // 确定key格式化字符的位置// 此时pos指向格式化字符后的位置pos += 1;if (pos < _pattern.size() && _pattern[pos] == '{') {pos += 1; // pos指向子规则的起始位置while (pos < _pattern.size() && _pattern[pos] != '}'){val.push_back(_pattern[pos++]);}// 走到末尾跳出循环,则代表没有遇到},代表格式是错误的if (pos == _pattern.size()) {std::cerr << "子规则{}匹配出错!\n";return false;}pos += 1; // pos指向}位置,向后走一步,到了下一步的位置}fmt_order.push_back(std::make_pair(key, val));key.clear();val.clear();}/*这个处理的过程以 abcd[%d{%H:%M:%S}][ %t][%c][%f:%l][%p]%T%m%n 为例子进行解析key = nullptr,val = abcd[key = d,val = %H:%M:%Skey = nullptr,val = ][...得到数组内容之后,根据数组内容,创建格式化子项对象,添加到items成员数组中。*/// 2. 根据解析得到的数据初始化格式化子项数组成员for (auto &it : fmt_order){_items.push_back(createItem(it.first, it.second));}return true;}// 根据不同格式化字符创建不同的格式化子项对象FormatItem::ptr createItem(const std::string &key, const std::string &val){if (key == "d") return std::make_shared<TimeFormatItem>(val);if (key == "t") return std::make_shared<ThreadFormatItem>();if (key == "c") return std::make_shared<LoggerFormatItem>();if (key == "f") return std::make_shared<FileFormatItem>();if (key == "l") return std::make_shared<LineFormatItem>();if (key == "p") return std::make_shared<LevelFormatItem>();if (key == "T") return std::make_shared<TabFormatItem>();if (key == "m") return std::make_shared<MsgFormatItem>();if (key == "n") return std::make_shared<NLineFormatItem>();if (key.empty()) return std::make_shared<OtherFormatItem>(val);std::cerr << "没有对应的格式化字符: %" << key << std::endl;abort();return FormatItem::ptr();}private:std::string _pattern; // 格式化规则字符串std::vector<FormatItem::ptr> _items;};
}

相关文章:

日志系统项目(2)项目实现(实用工具类、日志等级类、日志消息类、日志格式化输出类)

前面的文章中我们讲述了日志系统项目的前置知识点&#xff0c;再本文中我们将开始日志项目的细节实现。 日志系统框架设计 本项目实现的是一个多日志器日志系统&#xff0c;主要实现的功能是让程序员能够轻松的将程序运行日志信息落地到指定的位置&#xff0c;且支持同步与异…...

剑指offer面试题19 二叉树的镜像

考察点 树的遍历知识点 题目 分析 我们分析算法题目的思路基本上都是归纳法&#xff0c;即通过举一些普通的例子来推理出算法流程&#xff0c;而画图又是举例子的常用手段&#xff0c;比如针对树或者链表画画图&#xff0c;针对数字类的举一些数字的例子寻找规律&#xff0c…...

SpringCloud Alibaba 2022之Nacos学习

SpringCloud Alibaba 2022使用 SpringCloud Alibaba 2022需要Spring Boot 3.0以上的版本&#xff0c;同时JDK需要是17及以上的版本。具体的可以看官网的说明。 Spring Cloud Alibaba版本说明 环境搭建 这里搭建的是一个聚合项目。项目结构如下&#xff1a; 父项目的pom.xm…...

js之数组遍历

for 可以用来遍历数组、字符串、类数组、DOM节点&#xff0c;可以更改原数组&#xff0c;可以使用break、continue 跳出循环 return 只能在函数内部使用 for(声明循环变量&#xff1b;判断循环条件&#xff1b;更新循环变量){循环体 }forEach 参数&#xff08;当前元素&#x…...

极狐GitLab 16.9 重磅发布,快来 pick 你心仪的功能吧~【五】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 沿袭我们的月度发版机制&#xff0c;今天我们正式发布极狐GitL…...

如何在本地部署密码管理软件bitwarden并结合cpolar实现远程同步

文章目录 1. 拉取Bitwarden镜像2. 运行Bitwarden镜像3. 本地访问4. 群晖安装Cpolar5. 配置公网地址6. 公网访问Bitwarden7. 固定公网地址8. 浏览器密码托管设置 Bitwarden是一个密码管理器应用程序&#xff0c;适用于在多个设备和浏览器之间同步密码。自建密码管理软件bitwarde…...

DT DAY3 信号和槽

作业&#xff1a; 1> 思维导图 2> 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 btn3 new QPushButton("按钮3",this);btn3->resize(ui->btn2->width(),ui->b…...

Spring、SpringBoot、SpringCloud三者的区别

Spring、Spring Boot 和 Spring Cloud 是构建企业级 Java 应用程序的不同层次的框架和工具。下面详细介绍它们之间的区别&#xff1a; 1. Spring框架&#xff1a; 概述&#xff1a; Spring 是一个全功能的企业级 Java 框架&#xff0c;提供了依赖注入、面向切面编程、事务管理…...

leetcode:46.全排列

1.什么是排列&#xff1f; 有顺序&#xff01;&#xff01; 2.树形结构&#xff1a; 使用used数组进行标记取过的元素&#xff0c;一个元素一个元素地进行取值&#xff0c;取完之后将used数组进行标记。 3.代码实现&#xff1a;&#xff08;循环从i0开始&#xff0c;而不是…...

基于STM32的宠物箱温度湿度监控系统

基于STM32的宠物箱温度湿度监控系统 一、引言 随着人们生活水平的提高,养宠物已经成为越来越多人的选择。宠物作为家庭的一员,其生活环境和健康状况受到了广泛关注。温度和湿度是影响宠物舒适度和健康的重要因素之一。因此,开发一款能够实时监控宠物箱温度和湿度的系统具有…...

《高质量的C/C++编程规范》学习

目录 一、编程规范基础知识 1、头文件 2、程序的板式风格 3、命名规则 二、表达式和基本语句 1、运算符的优先级 2、复合表达式 3、if语句 4、循环语句的效率 5、for循环语句 6、switch语句 三、常量 1、#define和const比较 2、常量定义规则 四、函数设计 1、参…...

客户端订阅服务端事件的机制

一、场景描述 产业大脑平台是一个典型的审核系统&#xff0c;用户发布到平台的信息需要经过审核员审核后生效。 用户发布信息->审核员审核信息->用户信息生效&#xff0c;这一流程可能发生在用户的同一次登录周期内。为了使客户端能实时响应信息的状态变化&#xff0c;…...

pulsar入门介绍

概述 Pulsar 是一个多租户、高性能的服务器到服务器消息传递解决方案。Pulsar 最初由 Yahoo 开发&#xff0c;由 Apache 软件基金会管理。 特点 Pulsar 的主要功能如下&#xff1a; 原生支持 Pulsar 实例中的多个集群&#xff0c;可跨集群无缝地复制消息。非常低的发布和端…...

Leetcode 3047. Find the Largest Area of Square Inside Two Rectangles

Leetcode 3047. Find the Largest Area of Square Inside Two Rectangles 1. 解题思路2. 代码实现 题目链接&#xff1a;3047. Find the Largest Area of Square Inside Two Rectangles 1. 解题思路 这道题倒是没啥特别的思路&#xff0c;直接暴力求解就是了&#xff0c;因此…...

ELK 简介安装

1、概念介绍 日志介绍 日志就是程序产生的&#xff0c;遵循一定格式&#xff08;通常包含时间戳&#xff09;的文本数据。 通常日志由服务器生成&#xff0c;输出到不同的文件中&#xff0c;一般会有系统日志、 应用日志、安全日志。这些日志分散地存储在不同的机器上。 日志…...

Linux 的交换空间(swap)是什么?有什么用?

目录 swap是什么&#xff1f;swap有什么用&#xff1f;swap使用典型场景如何查看你的系统是否用到交换空间呢&#xff1f;查看系统中swap in/out的情况 swap是什么&#xff1f; swap就是磁盘上的一块区域。它和Windows系统中的交换文件作用类似&#xff0c;但是它是一段连续的…...

消息中间件篇之RabbitMQ-消息不丢失

一、生产者确认机制 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后&#xff0c;会返回一个结果给发送者&#xff0c;表示消息是否处理成功。 当消息没有到交换机就失败了&#xff0c;就会返回publish-confirm。当消息没有到达MQ时&…...

MongoDB中的TTL索引:自动过期数据的深入解析与使用方式

目录 一、TTL索引的深入原理二、TTL索引的使用方式三、TTL索引的限制与考虑因素四、优化TTL索引的策略五、总结 一、TTL索引的深入原理 TTL&#xff08;Time-To-Live&#xff09;索引在MongoDB中是一种特殊的索引&#xff0c;用于自动删除过期的文档。其核心原理在于MongoDB会…...

IPV6地址

技术背景&#xff1a;对IPV4做优化&#xff0c;比如地址长度128&#xff0c;简化了报文头部---快 ipv6地址 十六进制&#xff0c;简写前导0忽略&#xff0c;连续的0写成:: IPv6地址类型 1.单播 2.组播---接口有地址后&#xff0c;自动加入到一个组播里 3.任播---允许地址…...

解密API关键词搜索(淘宝京东1688)商品列表数据

API关键词搜索商品列表数据&#xff1a;赋能电商行业的新动力 随着电子商务的蓬勃发展&#xff0c;API&#xff08;应用程序接口&#xff09;关键词搜索商品列表数据在电商行业中的重要性日益凸显。这一数据资源不仅为消费者提供了便捷的购物体验&#xff0c;还为电商企业带来…...

wpf 简单实验 数据更新 列表更新

1.概要 1.1 需求 一个列表提供添加修改删除的功能&#xff0c;添加和修改的内容都来自一个输入框 1.2 要点 DisplayMemberPath"Zhi"列表.ItemsSource datalist;(列表.SelectedItem ! null)(列表.SelectedItem as A).Zhi 内容.Text;datalist.Remove((列表.Selec…...

【Flink精讲】Flink性能调优:内存调优

内存调优 内存模型 JVM 特定内存 JVM 本身使用的内存&#xff0c;包含 JVM 的 metaspace 和 over-head 1&#xff09; JVM metaspace&#xff1a; JVM 元空间 taskmanager.memory.jvm-metaspace.size&#xff0c;默认 256mb 2&#xff09; JVM over-head 执行开销&#xff1…...

Java 中常用的数据结构类 API

目录 常用数据结构API 对应的线程安全的api 高可用衡量标准 常用数据结构API ArrayList: 实现了动态数组&#xff0c;允许快速随机访问元素。 import java.util.ArrayList; LinkedList: 实现了双向链表&#xff0c;适用于频繁插入和删除操作。 import java.util.LinkedLis…...

JavaScript学习小记(1)基本数据结构(数组,字符串)

一个寒假确实过的很快&#xff0c;这个寒假除了调包调参突然心血来潮想学一下前端&#xff0c;学习过程比较平滑&#xff0c;我是自己找的技术文档&#xff0b;写代码实践来学习的&#xff0c;教程视频虽然详细&#xff0c;但是真的一点都看不动。 目录 JS如何定义变量的老旧的…...

python opencv实现车牌识别

目录 一:实现步骤: 二:实现车牌检测 一:实现步骤: 使用Python和OpenCV实现车牌识别的步骤大致可以分为以下两部分: 车牌检测: 读取需要进行车牌识别的图片。 对图像进行灰度化处理,可能还包括高斯模糊和灰度拉伸。 进行开运算,消除图像中的噪声。 将灰度拉伸后的图…...

K8S节点GPU虚拟化(vGPU)

vGPU实现方案 4paradigm提供了k8s-device-plugin,该插件基于NVIDIA官方插件(NVIDIA/k8s-device-plugin),在保留官方功能的基础上,实现了对物理GPU进行切分,并对显存和计算单元进行限制,从而模拟出多张小的vGPU卡。在k8s集群中,基于这些切分后的vGPU进行调度,使不同的容器…...

NLP 使用Word2vec实现文本分类

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客 &#x1f366; 参考文章&#xff1a;365天深度学习训练营 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制]\n&#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.com/…...

【Redis学习笔记03】Java客户端

1. 初识Jedis Jedis的官网地址&#xff1a;https://github.com/redis/jedis 1.1 快速入门 使用步骤&#xff1a; 注意&#xff1a;如果是云服务器用户使用redis需要先配置防火墙&#xff01; 引入maven依赖 <dependencies><!-- 引入Jedis依赖 --><dependency&g…...

神经网络系列---激活函数

文章目录 激活函数Sigmoid 激活函数Tanh激活函数ReLU激活函数Leaky ReLU激活函数Parametric ReLU激活函数 &#xff08;自适应Leaky ReLU激活函数&#xff09;ELU激活函数SeLU激活函数Softmax 激活函数Swish 激活函数Maxout激活函数Softplus激活函数 激活函数 一般来说&#xf…...

python中continue的对比理解

# 使用while循环&#xff0c;输入1-10之间的数字&#xff0c;除7之外。 以下为代码对比&#xff1a; # 使用while循环&#xff0c;输入1-10之间的数字&#xff0c;除7之外。 # 第一种方式 num 0 while num < 10:num num 1if num 7:print("")else:print(num)…...

Amazon Generative AI | 基于 Amazon 扩散模型原理的代码实践之采样篇

以前通过论文介绍 Amazon 生成式 AI 和大语言模型&#xff08;LLMs&#xff09;的主要原理之外&#xff0c;在代码实践环节主要还是局限于是引入预训练模型、在预训练模型基础上做微调、使用 API 等等。很多开发人员觉得还不过瘾&#xff0c;希望内容可以更加深入。因此&#x…...

[服务器-数据库]MongoDBv7.0.4不支持ipv6访问

文章目录 MongoDBv7.0.4不支持ipv6访问错误描述问题分析错误原因解决方式 MongoDBv7.0.4不支持ipv6访问 错误描述 报错如下描述 Cannot connect to MongoDB.No suitable servers found: serverSelectionTimeoutMS expired: [failed to resolve 2408]问题分析 首先确定其是…...

【b站咸虾米】chapter5_uniapp-API_新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握

课程地址&#xff1a;【新课uniapp零基础入门到项目打包&#xff08;微信小程序/H5/vue/安卓apk&#xff09;全掌握】 https://www.bilibili.com/video/BV1mT411K7nW/?p12&share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 5 API 5.1 页面和路…...

自学Python第十八天-自动化测试框架(二):DrissionPage、appium

自学Python第十八天-自动化测试框架&#xff08;二&#xff09;&#xff1a;DrissionPage、appium DrissionPage环境和安装配置准备工作简单的使用示例控制浏览器收发数据包模式切换 浏览器模式创建浏览器对象访问页面加载模式none 模式技巧 获取页面信息页面交互查找元素ele()…...

云尚办公-0.3.0

5. controller层 import pers.beiluo.yunshangoffice.model.system.SysRole; import pers.beiluo.yunshangoffice.service.SysRoleService;import java.util.List;//RestController&#xff1a;1.该类是控制器&#xff1b;2.方法返回值会被写进响应报文的报文体&#xff0c;而…...

汇编英文全称

mov move mvn Mov Negative ldr LoaD Register str Store Register lsl Logic Shift Left lsr Logic Shift Right asr Arithmetic Shift Right 算数右移 ror Rotate right 循环右移…...

基于虚拟力优化的无线传感器网络覆盖率matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 虚拟力优化算法 4.2 覆盖覆盖率计算 5.完整程序 1.程序功能描述 基于虚拟力优化的无线传感器网络覆盖率&#xff0c;仿真输出优化前后的网络覆盖率&#xff0c;覆盖率优化收敛迭代曲线…...

阿里云-系统盘-磁盘扩容

阿里云系统磁盘扩容 之前是测试环境磁盘用的默认的有 40G&#xff0c;后面升级到正式的 磁盘怕不够用打算升级到 100G&#xff0c; 系统镜像&#xff1a; Alibaba Cloud Linux 3.2104 LTS 64 位 磁盘 ESSD 40G 升级步骤&#xff1a; 扩容与创建快照 在阿里云后台首先去扩容…...

libmmd.dll修复

libmmd.dll 是与Intel Math Kernel Library (MKL) 相关的动态链接库文件&#xff0c;通常用于数学和科学计算。 最常出现的错误信息是&#xff1a; 程序无法启动&#xff0c;因为您的计算机缺少 libmmd.dll 。尝试重新安装程序来解决这个问题。 启动 libmmd.dll 发生错误。无法…...

大数据时代的明星助手:数据可视化引领新风潮

在大数据时代的浪潮中&#xff0c;数据可视化如一位巧夺天工的画师&#xff0c;为我们描绘出庞大而丰富的信息画卷&#xff0c;为我们提供了直观、清晰、高效的数据呈现方式。下面我就以可视化从业者的角度&#xff0c;来简单聊聊这个话题。 数据可视化首先在信息管理和理解方面…...

设计模式--享元模式和组合模式

享元模式 享元模式&#xff08;Flyweight Pattern&#xff09;又称为轻量模式&#xff0c;是对象池的一种实现。类似于线程池&#xff0c;线程池可以避免不停的创建和销毁多个对象&#xff0c;销毁性能。提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒…...

基于Java springmvc+mybatis酒店信息管理系统设计和实现

基于Java springmvcmybatis酒店信息管理系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获…...

leetcode-找不同

389. 找不同 题解&#xff1a; 从题意我们可以知道&#xff0c;虽然 t 是由 s组成&#xff0c;但是 t中又随机添加了一个字符&#xff0c;也就是相当于 t 包含 s,我们使用字典&#xff0c;将 t 转换成字典对应关系t_map&#xff0c;然后遍历 s 中的字符&#xff0c;若存在&am…...

笔记本hp6930p安装Android-x86避坑日记

一、序言 农历癸卯年前大扫除&#xff0c;翻出老机hp6930p&#xff0c;闲来无事&#xff0c;便安装Android-x86玩玩&#xff0c;期间多次入坑&#xff0c;随手记之以避坑。 笔记本配置&#xff1a;T9600,4G内存&#xff0c;120G固态160G机械硬盘 二、Android-x86系统简介 官…...

zabbix监控业务数据

前言 监控系统除了监控os和数据库性能相关的指标外&#xff0c;业务数据也是重点监控的对象。 一线驻场的运维同学应该深有体会&#xff0c;每天需要向甲方或者公司反馈现场的数据情况&#xff0c;正常情况下一天巡检两次&#xff0c;早上上班后和下午下班前各一次。监控项目…...

access数据库泄露与IIS短文件名利用

access数据库 Microsoft Office Access是微软把 数据库引擎 的图形用户界面和 软件开发工具 结合在一起的一个 数据库管理系统 它的数据库是没有库名的&#xff0c;都是表名。 (借用别的up的图)是不是感觉有点像excel access数据库的后缀是.mdb access数据库泄露漏洞 如果…...

MySQL 篇-深入了解 DDL 语言(一)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 MySQL 说明 2.0 DDL 语言 2.1 DDL 语言 - 定义数据库 2.1.1 创建数据库操作 2.1.2 查看数据库操作 2.1.3 使用数据库操作 2.1.4 删除数据库操作 2.2 DDL 语言 …...

MT8788|MTK8788安卓核心板参数_4G联发科MTK模块

MT8788核心板是一款功能强大的4G全网通安卓智能模块。该模块采用了联发科AIOT芯片平台&#xff0c;具有长达8年的生命周期。MT8788模块内置了12nm制程的八核处理器&#xff0c;包括4个Cortex A73和4个Coretex A53&#xff0c;主频最高可达2.0GHZ。标配内存为4GB64GB&#xff0c…...

EXCEL 在列不同单元格之间插入N个空行

1、第一步数据&#xff0c;要求在每个数字之间之间插入3个空格 2、拿数据个数*&#xff08;要插入空格数1&#xff09; 19*4 3、填充 4、复制数据到D列 5、下拉数据&#xff0c;选择复制填充这样1-19就会重复4次 6、全选数据D列排序&#xff0c;这样即完成了插入空格 以…...

Linux快速修改ip地址

Linux修改IP配置 一 、查找ip配置文件 ifcfg-ens33二、编辑 vi ifcfg-ens33文件三、重启网络或者重启系统 一 、查找ip配置文件 ifcfg-ens33 cd /etc/sysconfig/network-scripts/ls //查看network-scripts文件夹下面的文件二、编辑 vi ifcfg-ens33文件 vi ifcfg-ens33注意&…...