日志系统项目(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:表示换行。
- 设计思想:设计不同的子类,不同的子类从日志消息中取出不同的数据进行处理。
- 系统的默认日志输出格式:%d{%H:%M:%S}%T[9%t]%T[%p]%T[%c]%T%f:%1%T%m%no
-
日志消息落地模块∶决定了日志的落地方向,可以是标准输出,也可以是日志文件,也可以滚动文件输出…
- 标准输出:表示将日志进行标准输出的打印。
- 日志文件输出:表示将日志写入指定的文件末尾。
- 滚动文件输出:当前以文件大小进行控制,当一个日志文件大小达到指定大小,则切换下一个文件进行输出
- 后期,也可以扩展远程日志输出,创建客户端,将日志消息发送给远程的日志分析服务器。
- 设计思想:设计不同的子类,不同的子类控制不同的日志落地方向。
-
日志器模块:
- 此模块是对以上几个模块的整合模块,用户通过日志器进行日志的输出,有效降低用户的使用难度。
- 包含有:日志消息落地模块对象,日志消息格式化模块对象,日志输出等级
-
日志器管理模块:
- 为了降低项目开发的日志耦合,不同的项目组可以有自己的日志器来控制输出格式以及落地方向,因此本项目是一个多日志器的日志系统。
- 管理模块就是对创建的所有日志器进行统一管理。并提供一个默认日志器提供标准输出的日志输出。
-
异步线程模块:
- 实现对日志的异步输出功能,用户只需要将输出日志任务放入任务池,异步线程负责日志的落地输出功能,以此提供更加高效的非阻塞日志输出。
模块关系图
代码设计
实用类设计
完成一些零碎的功能接口,以便于后面会用到。
- 获取系统时间信息
- 判断文件是否存在
- 获取文件所在路径
- 创建目录
/*实用工具类的实现: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)项目实现(实用工具类、日志等级类、日志消息类、日志格式化输出类)
前面的文章中我们讲述了日志系统项目的前置知识点,再本文中我们将开始日志项目的细节实现。 日志系统框架设计 本项目实现的是一个多日志器日志系统,主要实现的功能是让程序员能够轻松的将程序运行日志信息落地到指定的位置,且支持同步与异…...
剑指offer面试题19 二叉树的镜像
考察点 树的遍历知识点 题目 分析 我们分析算法题目的思路基本上都是归纳法,即通过举一些普通的例子来推理出算法流程,而画图又是举例子的常用手段,比如针对树或者链表画画图,针对数字类的举一些数字的例子寻找规律,…...
SpringCloud Alibaba 2022之Nacos学习
SpringCloud Alibaba 2022使用 SpringCloud Alibaba 2022需要Spring Boot 3.0以上的版本,同时JDK需要是17及以上的版本。具体的可以看官网的说明。 Spring Cloud Alibaba版本说明 环境搭建 这里搭建的是一个聚合项目。项目结构如下: 父项目的pom.xm…...
js之数组遍历
for 可以用来遍历数组、字符串、类数组、DOM节点,可以更改原数组,可以使用break、continue 跳出循环 return 只能在函数内部使用 for(声明循环变量;判断循环条件;更新循环变量){循环体 }forEach 参数(当前元素&#x…...
极狐GitLab 16.9 重磅发布,快来 pick 你心仪的功能吧~【五】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 沿袭我们的月度发版机制,今天我们正式发布极狐GitL…...
如何在本地部署密码管理软件bitwarden并结合cpolar实现远程同步
文章目录 1. 拉取Bitwarden镜像2. 运行Bitwarden镜像3. 本地访问4. 群晖安装Cpolar5. 配置公网地址6. 公网访问Bitwarden7. 固定公网地址8. 浏览器密码托管设置 Bitwarden是一个密码管理器应用程序,适用于在多个设备和浏览器之间同步密码。自建密码管理软件bitwarde…...
DT DAY3 信号和槽
作业: 1> 思维导图 2> 使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数 btn3 new QPushButton("按钮3",this);btn3->resize(ui->btn2->width(),ui->b…...
Spring、SpringBoot、SpringCloud三者的区别
Spring、Spring Boot 和 Spring Cloud 是构建企业级 Java 应用程序的不同层次的框架和工具。下面详细介绍它们之间的区别: 1. Spring框架: 概述: Spring 是一个全功能的企业级 Java 框架,提供了依赖注入、面向切面编程、事务管理…...
leetcode:46.全排列
1.什么是排列? 有顺序!! 2.树形结构: 使用used数组进行标记取过的元素,一个元素一个元素地进行取值,取完之后将used数组进行标记。 3.代码实现:(循环从i0开始,而不是…...
基于STM32的宠物箱温度湿度监控系统
基于STM32的宠物箱温度湿度监控系统 一、引言 随着人们生活水平的提高,养宠物已经成为越来越多人的选择。宠物作为家庭的一员,其生活环境和健康状况受到了广泛关注。温度和湿度是影响宠物舒适度和健康的重要因素之一。因此,开发一款能够实时监控宠物箱温度和湿度的系统具有…...
《高质量的C/C++编程规范》学习
目录 一、编程规范基础知识 1、头文件 2、程序的板式风格 3、命名规则 二、表达式和基本语句 1、运算符的优先级 2、复合表达式 3、if语句 4、循环语句的效率 5、for循环语句 6、switch语句 三、常量 1、#define和const比较 2、常量定义规则 四、函数设计 1、参…...
客户端订阅服务端事件的机制
一、场景描述 产业大脑平台是一个典型的审核系统,用户发布到平台的信息需要经过审核员审核后生效。 用户发布信息->审核员审核信息->用户信息生效,这一流程可能发生在用户的同一次登录周期内。为了使客户端能实时响应信息的状态变化,…...
pulsar入门介绍
概述 Pulsar 是一个多租户、高性能的服务器到服务器消息传递解决方案。Pulsar 最初由 Yahoo 开发,由 Apache 软件基金会管理。 特点 Pulsar 的主要功能如下: 原生支持 Pulsar 实例中的多个集群,可跨集群无缝地复制消息。非常低的发布和端…...
Leetcode 3047. Find the Largest Area of Square Inside Two Rectangles
Leetcode 3047. Find the Largest Area of Square Inside Two Rectangles 1. 解题思路2. 代码实现 题目链接:3047. Find the Largest Area of Square Inside Two Rectangles 1. 解题思路 这道题倒是没啥特别的思路,直接暴力求解就是了,因此…...
ELK 简介安装
1、概念介绍 日志介绍 日志就是程序产生的,遵循一定格式(通常包含时间戳)的文本数据。 通常日志由服务器生成,输出到不同的文件中,一般会有系统日志、 应用日志、安全日志。这些日志分散地存储在不同的机器上。 日志…...
Linux 的交换空间(swap)是什么?有什么用?
目录 swap是什么?swap有什么用?swap使用典型场景如何查看你的系统是否用到交换空间呢?查看系统中swap in/out的情况 swap是什么? swap就是磁盘上的一块区域。它和Windows系统中的交换文件作用类似,但是它是一段连续的…...
消息中间件篇之RabbitMQ-消息不丢失
一、生产者确认机制 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。 当消息没有到交换机就失败了,就会返回publish-confirm。当消息没有到达MQ时&…...
MongoDB中的TTL索引:自动过期数据的深入解析与使用方式
目录 一、TTL索引的深入原理二、TTL索引的使用方式三、TTL索引的限制与考虑因素四、优化TTL索引的策略五、总结 一、TTL索引的深入原理 TTL(Time-To-Live)索引在MongoDB中是一种特殊的索引,用于自动删除过期的文档。其核心原理在于MongoDB会…...
IPV6地址
技术背景:对IPV4做优化,比如地址长度128,简化了报文头部---快 ipv6地址 十六进制,简写前导0忽略,连续的0写成:: IPv6地址类型 1.单播 2.组播---接口有地址后,自动加入到一个组播里 3.任播---允许地址…...
解密API关键词搜索(淘宝京东1688)商品列表数据
API关键词搜索商品列表数据:赋能电商行业的新动力 随着电子商务的蓬勃发展,API(应用程序接口)关键词搜索商品列表数据在电商行业中的重要性日益凸显。这一数据资源不仅为消费者提供了便捷的购物体验,还为电商企业带来…...
wpf 简单实验 数据更新 列表更新
1.概要 1.1 需求 一个列表提供添加修改删除的功能,添加和修改的内容都来自一个输入框 1.2 要点 DisplayMemberPath"Zhi"列表.ItemsSource datalist;(列表.SelectedItem ! null)(列表.SelectedItem as A).Zhi 内容.Text;datalist.Remove((列表.Selec…...
【Flink精讲】Flink性能调优:内存调优
内存调优 内存模型 JVM 特定内存 JVM 本身使用的内存,包含 JVM 的 metaspace 和 over-head 1) JVM metaspace: JVM 元空间 taskmanager.memory.jvm-metaspace.size,默认 256mb 2) JVM over-head 执行开销࿱…...
Java 中常用的数据结构类 API
目录 常用数据结构API 对应的线程安全的api 高可用衡量标准 常用数据结构API ArrayList: 实现了动态数组,允许快速随机访问元素。 import java.util.ArrayList; LinkedList: 实现了双向链表,适用于频繁插入和删除操作。 import java.util.LinkedLis…...
JavaScript学习小记(1)基本数据结构(数组,字符串)
一个寒假确实过的很快,这个寒假除了调包调参突然心血来潮想学一下前端,学习过程比较平滑,我是自己找的技术文档+写代码实践来学习的,教程视频虽然详细,但是真的一点都看不动。 目录 JS如何定义变量的老旧的…...
python opencv实现车牌识别
目录 一:实现步骤: 二:实现车牌检测 一:实现步骤: 使用Python和OpenCV实现车牌识别的步骤大致可以分为以下两部分: 车牌检测: 读取需要进行车牌识别的图片。 对图像进行灰度化处理,可能还包括高斯模糊和灰度拉伸。 进行开运算,消除图像中的噪声。 将灰度拉伸后的图…...
K8S节点GPU虚拟化(vGPU)
vGPU实现方案 4paradigm提供了k8s-device-plugin,该插件基于NVIDIA官方插件(NVIDIA/k8s-device-plugin),在保留官方功能的基础上,实现了对物理GPU进行切分,并对显存和计算单元进行限制,从而模拟出多张小的vGPU卡。在k8s集群中,基于这些切分后的vGPU进行调度,使不同的容器…...
NLP 使用Word2vec实现文本分类
🍨 本文为[🔗365天深度学习训练营学习记录博客 🍦 参考文章:365天深度学习训练营 🍖 原作者:[K同学啊 | 接辅导、项目定制]\n🚀 文章来源:[K同学的学习圈子](https://www.yuque.com/…...
【Redis学习笔记03】Java客户端
1. 初识Jedis Jedis的官网地址:https://github.com/redis/jedis 1.1 快速入门 使用步骤: 注意:如果是云服务器用户使用redis需要先配置防火墙! 引入maven依赖 <dependencies><!-- 引入Jedis依赖 --><dependency&g…...
神经网络系列---激活函数
文章目录 激活函数Sigmoid 激活函数Tanh激活函数ReLU激活函数Leaky ReLU激活函数Parametric ReLU激活函数 (自适应Leaky ReLU激活函数)ELU激活函数SeLU激活函数Softmax 激活函数Swish 激活函数Maxout激活函数Softplus激活函数 激活函数 一般来说…...
python中continue的对比理解
# 使用while循环,输入1-10之间的数字,除7之外。 以下为代码对比: # 使用while循环,输入1-10之间的数字,除7之外。 # 第一种方式 num 0 while num < 10:num num 1if num 7:print("")else:print(num)…...
阿里云建站公司靠谱吗/中国十大seo公司
基于Django开发的SkyNet博客一——创建模型基于Django开发的SkyNet博客二——base Template基于Django开发的SkyNet博客三——登录注册界面代码传送门 这是我这个项目的github代码库,目前项目正在更新,所以代码不是很全。上一篇博客主要讲了博客的登录注…...
个人网站制作 教程/seo课程培训班费用
转载说明:这篇文章是以前在网上看到的,它以很容易理解的方式解释了什么是运算符的优先级,当时觉得写的不错,因此看完之后保存了下来,今天拿出来与大家分享。由于已不知道它的作者和出处,因此无法标明了&…...
做淘宝网站需要/软文批发网
一直想写一个下拉刷新,一直没有一个好的想法,在git 中浏览了几款下啦刷新Demo,他们实现的方式也不一样,老一点的框架是自定义View 然后监听手势实现效果。新一点的是自定一ViewGroup 组建 然后结合 NestedScrollingParent, Nested…...
wordpress葡萄酒模板/今晚比分足球预测
http://blog.csdn.net/todd911/article/details/8047445 1.在cdrom中放入光盘,或者在虚拟机中连接光盘镜像 (具体的操作就不说了,但是这边有一点要强调,就是镜像一定要是DVD版本,不能使用liveCD版本的,之前…...
网站如何做公安部备案/网络销售推广公司
任务描述: 现欲对该系统中主机进行ARP扫描渗透测试,确认该系统中都有哪些IP主机在线. 1.进入虚拟机操作系统:Ubuntu Linux 32bit中的/root目录,完善该目录下的arp_sweep.py文件,填写该文件当中空缺的Flag1字符串&#…...
汕头网站制作哪家强/网络推广外包联系方式
pwd查看当前目录相对路径 :相对于所在目录的路径[rootlocalhost ~]# pwd/root[rootlocalhost ~]# ls .ssh/authorized_keys .ssh/authorized_keys这种就是相对路径,相对于root下的路径 绝对路径 :从“/”根开始的就是绝对路径[rootlocalhost …...