[操作系统] 策略模式进行日志模块设计
文章目录
- @[toc]
- 一、什么是设计模式?
- 二、日志系统的基本构成
- 三、策略模式在日志系统中的落地实现
- ✦ 1. 策略基类 LogStrategy
- ✦ 2. 具体策略类
- ▸ 控制台输出:ConsoleLogStrategy
- ▸ 文件输出:FileLogStrategy
- 四、日志等级枚举与转换函数
- 五、日志时间戳格式化
- 六、日志核心类 Logger 与内部类 LogMessage
- ✦ 1. Logger 类
- ✦ 2. LogMessage 类(Logger 内部类)
- 七、使用宏简化调用
- 八、完整使用示例
- 九、总结
文章目录
- @[toc]
- 一、什么是设计模式?
- 二、日志系统的基本构成
- 三、策略模式在日志系统中的落地实现
- ✦ 1. 策略基类 LogStrategy
- ✦ 2. 具体策略类
- ▸ 控制台输出:ConsoleLogStrategy
- ▸ 文件输出:FileLogStrategy
- 四、日志等级枚举与转换函数
- 五、日志时间戳格式化
- 六、日志核心类 Logger 与内部类 LogMessage
- ✦ 1. Logger 类
- ✦ 2. LogMessage 类(Logger 内部类)
- 七、使用宏简化调用
- 八、完整使用示例
- 九、总结
在当今IT行业中,程序开发已不仅仅是写代码,更重要的是“写好代码”。在系统开发中,日志系统是一个不可或缺的模块,承担着问题定位、性能分析、安全审计等重要职责。而借助于设计模式,我们可以构建一个更灵活、可拓展、维护性更强的日志系统。本篇博客将结合C++代码示例,深入讲解策略模式在日志系统中的应用。
一、什么是设计模式?
在软件开发中,为了解决一些通用、重复出现的问题,业界总结出一套“最佳实践”方案,这就是设计模式。设计模式并非代码模板,而是对问题的抽象解决思路。
在本项目中,我们采用了策略模式(Strategy Pattern),它的核心思想是:定义一组算法,将每一个算法封装起来,并且使它们可以互换使用。也就是说,行为的变化不影响使用它的对象本身。
二、日志系统的基本构成
一个合格的日志系统通常需要具备以下信息:
- 时间戳:记录事件发生的准确时间;
- 日志等级:例如 DEBUG、INFO、WARNING、ERROR、FATAL;
- 日志内容:需要打印的事件信息;
- 元数据(可选):如源文件名、行号、线程ID、进程ID等,辅助定位问题。
我们希望实现的日志输出格式如下:
[2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [16] - hello world
三、策略模式在日志系统中的落地实现
策略模式的精髓是将不同的行为封装为不同的策略类,而日志模块的“行为”就是日志的输出方式(比如输出到终端或写入文件)。
✦ 1. 策略基类 LogStrategy
这是所有具体策略类的基类,定义了统一接口:
class LogStrategy {
public:virtual void SyncLog(const std::string &message) = 0; // 刷新日志 ,写成纯虚函数,派生类必须强制实现该函数virtual ~LogStrategy() = default; // 析构函数:写成使用默认的析构函数
};
这是一个纯虚函数接口,用于实现不同的日志写入方式。
✦ 2. 具体策略类
▸ 控制台输出:ConsoleLogStrategy
// 显示器打印日志的策略 : 子类
class ConsoleLogStrategy : public LogStrategy
{
public:
ConsoleLogStrategy()
{
}
void SyncLog(const std::string &message) override
{LockGuard lockguard(_mutex);std::cout << message << gsep;
}
~ConsoleLogStrategy()
{
}private:
Mutex _mutex;
};
使用互斥锁保证线程安全,并将日志写入 std::cout
。
▸ 文件输出:FileLogStrategy
// 文件打印日志的策略 : 子类
const std::string defaultpath = "./log";
const std::string defaultfile = "my.log";
class FileLogStrategy : public LogStrategy
{
public:
FileLogStrategy(const std::string &path = defaultpath, const std::string &file = defaultfile)
: _path(path),
_file(file)
{LockGuard lockguard(_mutex);if (std::filesystem::exists(_path)){return;}try{std::filesystem::create_directories(_path);}catch (const std::filesystem::filesystem_error &e){std::cerr << e.what() << '\n';}
}
void SyncLog(const std::string &message) override
{LockGuard lockguard(_mutex);std::string filename = _path + (_path.back() == '/' ? "" : "/") + _file; // "./log/" + "my.log"std::ofstream out(filename, std::ios::app); // app : 'append' 追加写入的 方式打开if (!out.is_open()){return;}out << message << gsep;out.close();
}
~FileLogStrategy()
{
}private:
std::string _path; // 日志文件所在路径
std::string _file; // 日志文件本身
Mutex _mutex;
};
- 构造函数会检查目录是否存在;
- 使用
std::ofstream
追加写入日志; - 同样使用互斥锁保护写入过程。
四、日志等级枚举与转换函数
日志等级被定义为强类型枚举:
enum class LogLevel { DEBUG, INFO, WARNING, ERROR, FATAL };
转换函数 Level2Str(LogLevel)
用于将枚举转为字符串,便于日志输出格式化。
enum class
的枚举值是限定在其枚举类型本身的作用域内的。必须使用枚举类型名和 ::
操作符来访问枚举值,这避免了命名冲突。
五、日志时间戳格式化
时间的格式由 GetTimeStamp()
函数生成:
std::string GetTimeStamp() // 获取当前时间
{time_t curr = time(nullptr);struct tm curr_tm;localtime_r(&curr, &curr_tm);char timebuffer[128];snprintf(timebuffer, sizeof(timebuffer),"%4d-%02d-%02d %02d:%02d:%02d",curr_tm.tm_year+1900, // 操作系统默认的时间戳是 year - 1900,所以要+1900curr_tm.tm_mon+1, // 操作系统获取的月份是从0开始的0 ~ 11,所以要+1curr_tm.tm_mday,curr_tm.tm_hour,curr_tm.tm_min,curr_tm.tm_sec);return timebuffer;
}
使用 snprintf
以字符串形式格式化时间,保证可读性。
六、日志核心类 Logger 与内部类 LogMessage
Logger类是日志模块的核心:
✦ 1. Logger 类
- 持有一个策略指针
_fflush_strategy
,作为内部类·; - 提供
EnableConsoleLogStrategy()
和EnableFileLogStrategy()
来切换策略; - 使用重载函数
operator()
生成一个LogMessage
临时对象:
LogMessage operator()(LogLevel level, std::string name, int line)
该对象负责构建一条完整的日志记录,构造完直接销毁。
✦ 2. LogMessage 类(Logger 内部类)
// 表示的是未来的一条日志
class LogMessage
{
public:
LogMessage(LogLevel &level, std::string &src_name, int line_number, Logger &logger): _curr_time(GetTimeStamp()), // 获取当前时间_level(level), // 日志等级_pid(getpid()), // 进程号_src_name(src_name), // 源文件名_line_number(line_number), // 源文件行号_logger(logger) // 当前日志对象所属的logger
{/*std::stringstream如何使用:C++17 将格式转换成string,保存到创建的ss对象,写入stringstream流里面,将所有写入的自动转为string类型后面可以通过 .str()接口 存入普通的string对象中但是enum class不能直接转换成string 所以需要自定义转换函数 Level2Str(_level)*/// 日志的左边部分,合并起来std::stringstream ss;ss << "[" << _curr_time << "] "<< "[" << Level2Str(_level) << "] "<< "[" << _pid << "] "<< "[" << _src_name << "] "<< "[" << _line_number << "] "<< "- ";_loginfo = ss.str();
}
// LogMessage() << "hell world" << "XXXX" << 3.14 << 1234// 构造函数用来打印日志头信息(结构化元数据),<< 重载函数用来构建日志具体内容
template <typename T>
LogMessage &operator<<(const T &info)
{// a = b = c =d;// 日志的右半部分,可变的 使用LogMessage & 自身的引用返回std::stringstream ss;ss << info;_loginfo += ss.str();return *this; // 返回当前对象,因为是引用,所以可以继续链式调用
}~LogMessage()
{if (_logger._fflush_strategy){/*内部类的作用:*/// 这就是为什么要写成内部类,因为内部类可以访问外部类的私有成员// 这样就可以使用logger对象中的fflush_strategy策略类,然后使用成员函数进行刷新在指定位置_logger._fflush_strategy->SyncLog(_loginfo);}
}private:
std::string _curr_time; // 当前时间
LogLevel _level; // 日志等级
pid_t _pid; // 进程号
std::string _src_name; // 源文件名
int _line_number; // 源文件行号
std::string _loginfo; //将以上内容合并之后,一条完整的信息Logger &_logger; // 一个Logger对象,表示的是一个日志对象
};
这个内部类的职责是:
- 构造函数收集日志元数据(时间、等级、文件名、行号、pid等);
- 重载
operator<<
来拼接日志主体内容; - 析构函数中自动调用
SyncLog()
完成日志刷新:
~LogMessage()
{if (_logger._fflush_strategy){/*内部类的作用:*/// 这就是为什么要写成内部类,因为内部类可以访问外部类的私有成员// 这样就可以使用logger对象中的fflush_strategy策略类,然后使用成员函数进行刷新在指定位置_logger._fflush_strategy->SyncLog(_loginfo);}
}
这是一种 RAII(资源获取即初始化)思想的应用,确保日志一定在对象生命周期结束时输出。
七、使用宏简化调用
定义了以下宏方便用户调用:
// 使用宏,简化用户操作,获取文件名和行号
#define LOG(level) logger(level, __FILE__, __LINE__) // __FILE__ __LINE__ 为预定义宏 在主函数文件中使用时会替换为主函文件的文件名和行号
#define Enable_Console_Log_Strategy() logger.EnableConsoleLogStrategy()
#define Enable_File_Log_Strategy() logger.EnableFileLogStrategy()
其中 __FILE__
和 __LINE__
是C++预定义宏,会在宏展开时替换为当前源文件和行号。
八、完整使用示例
using namespace LogModule;int main() {Enable_Console_Log_Strategy(); // 选择输出到控制台LOG(LogLevel::DEBUG) << "hello world";Enable_File_Log_Strategy(); // 切换输出到文件LOG(LogLevel::WARNING) << "log file output test";return 0;
}
输出示例:
[2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [16] - hello world
[2024-08-04 12:27:03] [WARNING] [202938] [main.cc] [18] - log file output test
九、总结
通过这套自定义日志模块的实现,我们学习并实践了策略模式的核心思想:行为的封装与可替换性。这种设计不仅使日志系统具有更高的可拓展性(比如将来可以添加数据库日志策略、远程日志策略等),还体现了低耦合、高内聚的设计理念。
日志系统本身也利用了C++的许多优秀特性:
- 内部类实现闭包式封装;
std::stringstream
实现类型安全拼接;- RAII 保证资源自动释放和操作完成;
- 线程安全的日志输出策略。
这是一个非常经典且实用的C++日志系统练习案例,建议读者在理解基础上动手编码,实现自己的日志模块,加深对设计模式的掌握。
相关文章:
[操作系统] 策略模式进行日志模块设计
文章目录 [toc]一、什么是设计模式?二、日志系统的基本构成三、策略模式在日志系统中的落地实现✦ 1. 策略基类 LogStrategy✦ 2. 具体策略类▸ 控制台输出:ConsoleLogStrategy▸ 文件输出:FileLogStrategy 四、日志等级枚举与转换函数五、日…...
LeetCode 每日一题 3341. 到达最后一个房间的最少时间 I + II
3341. 到达最后一个房间的最少时间 I II 有一个地窖,地窖中有 n x m 个房间,它们呈网格状排布。 给你一个大小为 n x m 的二维数组 moveTime ,其中 moveTime[i][j] 表示在这个时刻 以后 你才可以 开始 往这个房间 移动 。你在时刻 t 0 时从…...
《Python星球日记》 第68天:BERT 与预训练模型
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、BERT模型基础1. 什么是BERT?2. BERT 的结构3.预训练和微调对比二、BERT 的预训练任务1. 掩码语言模型 (MLM)2. 下一句预测 (NSP)三、微调 …...
Angular 知识框架
一、Angular 基础 1. Angular 简介 Angular 是什么? 基于 TypeScript 的前端框架(Google 维护)。 适用于构建单页应用(SPA)。 核心特性 组件化架构 双向数据绑定 依赖注入(DI) 模块化设计…...
python三方库sqlalchemy
SQLAlchemy 是 Python 中最强大、最受欢迎的 ORM(对象关系映射)库,它允许你使用 Python 对象来操作数据库,而不需要直接编写 SQL 语句。同时,它也提供了对底层 SQL 的完全控制能力,适用于从简单脚本到大型企…...
【SSL部署与优化】如何为网站启用HTTPS:从Let‘s Encrypt免费证书到Nginx配置
网站启用HTTPS 的完整实战指南,涵盖从 Let’s Encrypt 免费证书申请到 Nginx 配置的详细步骤,包括重定向、HSTS 设置及常见问题排查: 一、准备工作 1. 确保域名解析正确 • 在 DNS 管理后台,将域名(如 example.com&…...
Kubernetes控制平面组件:Kubelet详解(四):gRPC 与 CRI gRPC实现
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
电商平台自动化
为什么要进行独立站自动化 纯人工测试人力成本高,相对效率低 回归测试在通用模块重复进行人工测试,测试效率低 前期调研备选自动化框架(工具): Katalon Applitools Testim 阿里云EMAS Playwright Appium Cypress 相关…...
【kafka】kafka概念,使用技巧go示例
1. Kafka基础概念 1.1 什么是Kafka? Kafka是一个分布式流处理平台,用于构建实时数据管道和流式应用。核心特点: 高吞吐量:每秒可处理百万级消息持久化存储:消息按Topic分区存储在磁盘分布式架构:支持水平…...
计算机系统结构——Cache性能分析
一、实验目的 加深对Cache的基本概念、基本组织结构以及基本工作原理的理解。掌握Cache容量、相联度、块大小对Cache性能的影响。掌握降低Cache不命中率的各种方法以及这些方法对提高Cache性能的好处。理解LRU与随机法的基本思想以及它们对Cache性能的影响。 二、实验平台 实…...
Spring Web MVC————入门(2)
1,请求 我们接下来继续讲请求的部分,上期将过很多了,我们来给请求收个尾。 还记得Cookie和Seesion吗,我们在HTTP讲请求和响应报文的时候讲过,现在再给大家讲一遍,我们HTTP是无状态的协议,这次的…...
Adobe DC 2025安装教程
一.软件下载 点此下载 二.软件安装...
W1电力线载波通信技术
CK_Label_W1 产品型号:CK_Label_W1 尺寸:37*65*33.7mm 按键:1 指示灯:1 RGB灯(红/绿/蓝/黄/紫/白/青) 外观颜色:白色 合规认证:CE, RoHS 工作温度:0-50℃ 提示功能:蜂鸣器声音…...
现代 Web 自动化测试框架对比:Playwright 与 Selenium 的深度剖析
现代 Web 自动化测试框架对比:Playwright 与 Selenium 的深度剖析 摘要:本文对 Playwright 与 Selenium 在开发适配性、使用难度、场景适用性及性能表现等方面进行了全面深入的对比分析。通过详细的技术实现细节阐述与实测数据支撑,为开发者…...
第二章:CSS秘典 · 色彩与布局的力量
剧情承接:色彩失衡的荒原 林昊穿过 HTML 大门,眼前却是一片 灰白扭曲的荒原。所有页面元素如同幽灵般漂浮,没有色彩、没有结构,错乱无章。 “这是失控的样式荒原。” 零号导师的声音再次响起, “HTML 给了你骨架&…...
ubuntu studio 系统详解
Ubuntu Studio 系统详解:面向多媒体创作的专业 Linux 发行版 一、定位与目标用户 Ubuntu Studio 是 Ubuntu 的官方衍生版本(Flavor),专为 音频、视频、图形设计、音乐制作、影视后期 等多媒体创作场景设计。目标用户包括&#x…...
在 Ubuntu 20.04.6 LTS 中将 SCons 从 3.1.2 升级到 4.9.1
在 Ubuntu 20.04.6 LTS 中将 SCons 从 3.1.2 升级到 4.9.1,可以通过以下步骤完成: 方法 1:使用 pip 安装(推荐) 步骤 1:卸载旧版本 SCons # 如果通过 apt 安装的旧版本,先卸载 sudo apt remov…...
边缘计算网关工业物联网应用:空压机远程运维监控管理
边缘计算网关在空压机远程运维监控管理中的工业物联网应用,主要体现在数据采集与处理、设备监控、故障诊断与预警、远程控制等方面,以下是具体介绍: 数据采集与处理 多源数据采集:边缘计算网关能连接空压机的各类传感器…...
【大模型面试每日一题】Day 18:大模型中KV Cache的作用是什么?如何通过Window Attention优化其内存占用?
【大模型面试每日一题】Day 18:大模型中KV Cache的作用是什么?如何通过Window Attention优化其内存占用? 📌 题目重现 🌟🌟 面试官:大模型中KV Cache的作用是什么?如何通过Window Attention优…...
Spring的 @Validate注解详细分析
在 Spring Boot 中,参数校验是保证数据合法性的重要手段。除了前面提到的NotNull、Size等基础注解外,JSR-303(Bean Validation 1.0)、JSR-349(Bean Validation 1.1)和 JSR-380(Bean Validation …...
现代计算机图形学Games101入门笔记(三)
三维变换 具体形式缩放,平移 特殊点旋转。这里涉及到坐标系,先统一定义右手坐标系,根据叉乘和右手螺旋判定方向。这里还能法线Ry Sina 正负与其他两个旋转不一样。这里可以用右手螺旋,x叉乘z,发现大拇指朝下࿰…...
AI时代的弯道超车之第八章:具体分享几个AI实际操作方法和案例
在这个AI重塑世界的时代,你还在原地观望吗?是时候弯道超车,抢占先机了! 李尚龙倾力打造——《AI时代的弯道超车:用人工智能逆袭人生》专栏,带你系统掌握AI知识,从入门到实战,全方位提升认知与竞争力! 内容亮点: AI基础 + 核心技术讲解 职场赋能 + 创业路径揭秘 打破…...
企业网络新选择:软件定义架构下的MPLS
随着现代企业园区网络和运营商级基础设施的不断发展,多协议标签交换 (MPLS) 已成为一项基础技术,这要归功于其高效的数据包转发、高级流量工程功能以及对多租户环境的强大支持。 什么是MPLS? MPLS(多协议…...
SparkSQL操作Mysql
(一)准备mysql环境 我们计划在hadoop001这台设备上安装mysql服务器,(当然也可以重新使用一台全新的虚拟机)。 以下是具体步骤: 使用finalshell连接hadoop001.查看是否已安装MySQL。命令是: rpm -qa|grep…...
【论文阅读】UNIT: Backdoor Mitigation via Automated Neural Distribution Tightening
ECCV2024 https://github.com/Megum1/UNIT 我们的主要贡献总结如下: 我们引入了UNIT(“AUtomated Neural DIstribution Tightening”),这是一种创新的后门缓解方法,它为每个神经元近似独特的分布边界,用于…...
Android逆向学习(十) IDA逆向编辑Android so文件
Android逆向学习(十) IDA逆向编辑Android so文件 一、 写在前面 这是吾爱破解论坛正己大大的第10个教程 native code在我之前的博客中讲到过,所以这里就不讲了 简单来说,native code就是在android中使用c或c语言进行开发 这样…...
OpenCV + PyAutoGUI + Tkinter + FastAPI + Requests 实现的远程控制软件设计方案
以下是基于 OpenCV PyAutoGUI Tkinter FastAPI Requests 实现的远程控制软件设计方案。该方案分为 被控端(服务端) 和 控制端(客户端),支持屏幕实时查看、键盘映射和鼠标操作。 1. 系统架构 ------------------- …...
C++.神经网络与深度学习(赶工版)(会二次修改)
神经网络与深度学习 1. 神经网络基础1.1 神经元模型与激活函数1.2 神经网络结构与前向传播2.1 损失函数与优化算法均方误差损失函数交叉熵损失函数梯度下降优化算法 2.2 反向传播与梯度计算神经元的反向传播 3.1 神经元类设计与实现神经元类代码实现代码思路 3.2 神经网络类构建…...
砷化镓太阳能电池:开启多元领域能源新篇
砷化镓太阳能电池作为一种高性能的光伏产品,具有诸多独特优势。其中,锗衬底砷化镓太阳能电池表现尤为突出,它具备高转化效率、耐辐照和高电压等特性。在空间供电电源领域,这些优势使其成为人造卫星、太空站、太空探测器和登陆探测…...
[Linux] vim及gcc工具
目录 一、vim 1.vim的模式 2.vim的命令集 (1):命令模式 (2):底行模式 3.vim配置 二、gcc 1.gcc格式及选项 2.工作布置 三、自动化构建工具makefile 1.基本使用方法 2.配置文件解析 3.拓展 在linux操作系统的常用工具中,常用vim来进行程序的编写;…...
java加强 -stream流
Stream流是jdk8开始新增的一套api,可以用于操作集合或数组的内容。 Stream流大量的结合了Lambda的语法风格来编程,功能强大,性能高效,代码简洁,可读性好。 体验Stream流 把集合中所有以三开头并且三个字的元素存储到…...
RHCE认证通过率
红帽RHCE考试总体通过率38%(2023年数据),细分数据显示自学者通过率18%,参加官方培训者47%,企业团体考生53%。通过率差异由备考资源和考试策略决定。 RHCE考试重点考Ansible自动化运维,需在3.5小时内完成12…...
OpenEvidence AI临床决策支持工具平台研究报告
平台概述 OpenEvidence是一个专为医疗专业人士设计的临床决策支持工具,旨在通过整合各类临床计算器和先进的人工智能技术,提高医生的诊疗决策效率和准确性。作为一款综合性医疗平台,OpenEvidence将复杂的医学计算流程简化,同时提供个性化的临床建议,使医生能够更快、更准…...
gd32e230c8t6 keil6工程模板
下载固件gd32e230c8t6固件官方下载(需登录) 或 蓝奏云 新建一个文件夹,把固件压缩包里的里的Firmware和Template拖进去 keil新建gd32e230c8工程 必须勾选CMSIS-CORE 新建一个文件夹,双击任意改名 点击manage project it…...
正向代理与反向代理区别及应用
正向代理和反向代理是两种常见的代理服务器类型,它们在网络架构中扮演不同角色,核心区别在于代理对象和使用场景。 1. 正向代理(Forward Proxy) 定义:正向代理是客户端(如浏览器)主动配置的代理…...
自然语言处理入门级项目——文本分类
文章目录 前言1.数据预处理1.1数据集介绍1.2数据集抽取1.3划分数据集1.4数据清洗1.5数据保存 2.样本的向量化表征2.1词汇表2.2向量化2.3自定义数据集2.4备注 结语 前言 本篇博客主要介绍自然语言处理领域中一个项目案例——文本分类,具体而言就是判断评价属于积极还…...
UOS专业版上通过源码安装 Python 3.13 并保留系统默认版本
在 UOS 专业版上通过源码安装 Python 3.13 并保留系统默认版本,可按照以下步骤操作: 1. 安装依赖 首先安装编译 Python 所需的依赖库: sudo apt update sudo apt install -y build-essential zlib1g-dev libncurses5-dev \ libgdbm-dev li…...
【论文笔记】ViT-CoMer
【题目】:ViT-CoMer: Vision Transformer with Convolutional Multi-scale Feature Interaction for Dense Predictions 【引用格式】:Xia C, Wang X, Lv F, et al. Vit-comer: Vision transformer with convolutional multi-scale feature interaction…...
kaggle薅羊毛
参考:https://pytorch-tutorial.readthedocs.io/en/latest/tutorial/chapter05_application/5_1_kaggle/#512-kaggle https://github.com/girls-in-ai/Girls-In-AI/blob/master/machine_learning_diary/data_analysis/kaggle_intro.md 1,code training…...
Python 之 Flask 入门学习
安装 Flask 在开始使用 Flask 之前,需要先安装它。可以通过 pip 命令来安装 Flask: pip install Flask创建第一个 Flask 应用 创建一个简单的 Flask 应用,只需要几行代码。以下是一个最基本的 Flask 应用示例: from flask imp…...
SpringBoot Vue MySQL酒店民宿预订系统源码(支付宝沙箱支付)+代码讲解视频
💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...
Oracle日期计算跟Mysql计算日期差距问题-导致两边计算不一致
Oracle数据库对日期做加法时,得到的时间是某天的12:00:00 例: Oracle计算 select (TO_DATE(2025-04-14, YYYY-MM-DD)1.5*365) from dual; 结果:2026/10/13 12:00:00Mysql计算 select DATE_ADD( str_to_date( 2025-04-14, %Y-%m-%d ), INTER…...
多线程(三)
上一期关于线程的执行,咱们说到线程是 “ 随机调度,抢占式执行 ”。所以我们对于线程之间执行的先后顺序是难以预知的。 例如咱们打篮球的时候,球场上的每一位运动员都是一个独立的 “ 执行流 ”,也可以认为是一个线程࿰…...
微服务商城(1)开篇、服务划分
参考:https://mp.weixin.qq.com/s?__bizMzg2ODU1MTI0OA&mid2247485597&idx1&sn7e85894b7847cc50df51d66092792453&scene21#wechat_redirect 为什么选择go-zero go-zero 为我们提供了许多高并发场景下的实用工具,比如为了降低接口耗时…...
刘强东 “猪猪侠” 营销:重构创始人IP的符号革命|创客匠人热点评述
当刘强东身着印有外卖箱猪猪侠的 T 恤漫步东京涩谷街头时,这场看似荒诞的行为艺术实则揭开了互联网商业竞争的新篇章。这位曾经以严肃企业家形象示人的京东创始人,正通过二次元 IP 的深度绑定,完成从商业领袖到文化符号的华丽转身。 一、IP …...
MQ消息队列的深入研究
目录 1、Apache Kafka 1.1、 kafka架构设 1.2、最大特点 1.3、功能介绍 1.4、Broker数据共享 1.5、数据一致性 2、RabbitMQ 2.1、架构图 2.2、最大特点 2.3、工作原理 2.4、功能介绍 3、RocketMQ 3.1、 架构设计 3.2、工作原理 3.3、最大特点 3.4、功能介绍 3…...
填涂颜色(bfs)
归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言📝 含泪播种的人一定能含笑收获! 题目描述 由数字 0 0 0 组成的方阵中,有一任意形状的由数字 1 1 1 构成的闭合圈。现…...
FFplay 音视频同步机制解析:以音频为基准的时间校准与动态帧调整策略
1.⾳视频同步基础 1.2 简介 看视频时,要是声音和画面不同步,体验会大打折扣。之所以会出现这种情况,和音视频数据的处理过程密切相关。音频和视频的输出不在同一个线程,就像两个工人在不同车间工作,而且不一定会同时…...
【Linux笔记】——进程信号的捕捉——从中断聊聊OS是怎么“活起来”的
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux笔记】——进程信号的保存 🔖流水不争,争的是滔滔不息 一、信号捕捉的流程二、…...
VCS X-PROP建模以及在方针中的应用
VCS X-PROP建模以及在方针中的应用 摘要:VCS X-Prop(X-Propagation)是 Synopsys VCS 仿真工具中的一种高级功能,用于增强 X 态(未知态)和 Z 态(高阻态)在 RTL 仿真中的建模和传播能力…...