领域驱动设计(DDD)【23】之泛化:从概念到实践
文章目录
- 一 泛化基础:理解DDD中的核心抽象机制
- 1.1 什么是泛化?
- 1.2 为什么泛化在DDD中重要?
- 1.3 泛化与特化的双向关系
- 二 DDD中泛化的实现形式
- 2.0 实现形式概览
- 2.1 类继承:最直接的泛化实现
- 2.2 接口实现:更灵活的泛化方式
- 2.3 组合优于继承:现代DDD的实践
- 2.4 特征值实现:马匹管理
- 三 DDD中泛化的高级应用
- 3.1 限界上下文中的泛化
- 3.2 泛化的层次设计
- 3.3 泛化与持久化的权衡
- 四 避免泛化的常见陷阱
- 4.1 过度泛化:当抽象变成负担
- 4.2 错误泛化:混淆本质差异
- 4.3 泛化导致的数据污染
- 五、实战案例:电商系统中的泛化设计
- 5.1 商品类别的泛化设计
- 5.2 订单处理的状态模式实现
- 六 总结与最佳实践
- 6.1 何时使用泛化?
- 6.3 泛化的替代方案
- 6.4 持续重构的视角
一 泛化基础:理解DDD中的核心抽象机制
- 在领域驱动设计(Domain-Driven Design, DDD)中,泛化(Generalization)是一种强大的抽象工具,它允许我们识别和表达领域概念之间的"是一种"(is-a)关系。
1.1 什么是泛化?
- 泛化是指从多个特定概念中提取其共性,形成更一般化的概念的过程。在面向对象编程中,这通常通过继承来实现,但在DDD中,泛化的含义更为广泛。现实世界类比:想象你在设计一个动物园管理系统,特定概念:狮子、老虎、长颈鹿->泛化概念:动物。这里,"狮子是一种动物"就体现了泛化关系。
1.2 为什么泛化在DDD中重要?
- 减少重复:共性行为可以放在父类中
- 提高可维护性:修改一处即可影响所有子类
- 增强表达力:更准确地反映业务领域的关系
- 支持多态:允许以统一方式处理不同子类
1.3 泛化与特化的双向关系
- 在这个类图中,Animal是泛化类,Lion和Tiger是特化类。所有动物都有name和birthDate属性,都能eat()和sleep(),但只有狮子能roar(),只有老虎能growl()。
二 DDD中泛化的实现形式
2.0 实现形式概览
第一种是使用类的继承。领域模型中的父类、子类,和实现中的父类、子类直接对应。它的特点在于必须有不同种类的特性或者不同的操作。如果仅仅是某个属性值不同造成的泛化,那么用继承就不合适了。
第二种是接口的实现。如果各个子类在属性和操作实现方面没有共性,但有相同的操作接口,就使用这种方式。
第三种是用特性的值来区分,这时候在实现层面,没有父类和子类之分。特别适用于那些行为完全相同,仅在某些属性值上存在差异的领域概念。
2.1 类继承:最直接的泛化实现
- 电商系统示例:
public abstract class Payment {private BigDecimal amount;private Currency currency;private LocalDateTime paymentDate;public abstract void process();
}public class CreditCardPayment extends Payment {private String cardNumber;private String cardHolder;private LocalDate expiryDate;@Overridepublic void process() {// 信用卡支付处理逻辑}
}public class PayPalPayment extends Payment {private String email;private String transactionId;@Overridepublic void process() {// PayPal支付处理逻辑}
}
优劣分析:
- 优点:直接、明确、编译器支持
- 缺点:Java等语言单继承限制、父类修改影响大
2.2 接口实现:更灵活的泛化方式
public interface Shipment {void schedule();void cancel();TrackingInfo track();
}public class StandardShipment implements Shipment {// 实现标准物流
}public class ExpressShipment implements Shipment {// 实现快递物流
}public class InternationalShipment implements Shipment {// 实现国际物流
}
适用场景:
- 当不同实现有完全不同的行为时
- 需要多重"泛化"时
- 强调能力而非共同结构时
2.3 组合优于继承:现代DDD的实践
public class Product {private String id;private String name;private PricingStrategy pricingStrategy;public BigDecimal calculatePrice(OrderContext context) {return pricingStrategy.calculate(this, context);}
}public interface PricingStrategy {BigDecimal calculate(Product product, OrderContext context);
}public class StandardPricing implements PricingStrategy {// 标准定价策略
}public class DiscountPricing implements PricingStrategy {// 折扣定价策略
}public class BundlePricing implements PricingStrategy {// 捆绑定价策略
}
优势:
- 运行时可替换策略
- 避免类爆炸
- 更符合"组合优于继承"原则
2.4 特征值实现:马匹管理
- 其中:所有马都有相同的属性和行为、唯一区别是颜色不同(枣红马、白马、黑马等)。
public class Horse {private String name;private int age;private HorseColor color; // 类型区分字段public Horse(String name, int age, HorseColor color) {this.name = name;this.age = age;this.color = color;}public void run() { /* 奔跑实现 */ }public void eat() { /* 进食实现 */ }// 特定于颜色的行为(如果需要)public String getDescription() {return color.getDescription() + "马";}
}public enum HorseColor {RED("枣红"),WHITE("白"),BLACK("黑"),PALOMINO("金鬃"),DAPPLE("花斑");private final String description;HorseColor(String description) {this.description = description;}public String getDescription() {return description;}
}
public class HorseService {public void demo() {Horse redHorse = new Horse("赤兔", 5, HorseColor.RED);Horse whiteHorse = new Horse("的卢", 4, HorseColor.WHITE);System.out.println(redHorse.getDescription()); // 输出: 枣红马System.out.println(whiteHorse.getDescription()); // 输出: 白马// 所有马统一处理List<Horse> horses = List.of(redHorse, whiteHorse);horses.forEach(Horse::run);}
}
三 DDD中泛化的高级应用
3.1 限界上下文中的泛化
- 在不同限界上下文中,同一概念的泛化可能不同。医院系统示例:
患者管理上下文:
预约系统上下文:
- 注意在不同上下文中,泛化层次和标准完全不同。
3.2 泛化的层次设计
银行账户系统示例:
设计考量:
- 抽象层次不宜过深(通常不超过3层)
- 每个层次都应增加明确的业务价值
- 避免过度设计,只为真正的业务差异创建子类
3.3 泛化与持久化的权衡
- JPA继承策略示例:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "account_type")
public abstract class BankAccount {@Idprivate String accountNumber;private BigDecimal balance;// 公共字段
}@Entity
@DiscriminatorValue("SAVINGS")
public class SavingsAccount extends BankAccount {private BigDecimal interestRate;// 特有字段
}@Entity
@DiscriminatorValue("CHECKING")
public class CheckingAccount extends BankAccount {private BigDecimal overdraftLimit;// 特有字段
}
三种继承映射策略对比:
策略类型 | 数据库结构 | 优点 | 缺点 |
---|---|---|---|
SINGLE_TABLE | 单表,用区分字段标识子类 | 查询高效,无需连接 | 字段稀疏,可能有NULL |
JOINED | 父类子类分开表,主键关联 | 结构规范,无冗余 | 查询需连接,性能较差 |
TABLE_PER_CLASS | 每个具体类对应完整表 | 查询具体类高效 | 多态查询需UNION,设计复杂 |
四 避免泛化的常见陷阱
4.1 过度泛化:当抽象变成负担
反例:
public abstract class Entity {private Long id;// 所有实体都需要的字段
}public abstract class Person extends Entity {private String name;private String email;// 所有人共有的字段
}public abstract class User extends Person {private String username;private String password;// 所有用户共有的字段
}public class Customer extends User {// 客户特有字段
}public class Employee extends User {// 员工特有字段
}public class SystemAdmin extends Employee {// 系统管理员特有字段
}
问题分析:
- 层次过深,修改基类影响范围大
- 中间抽象类可能包含不相关功能
- 实际业务需求可能不需要如此复杂的层次
4.2 错误泛化:混淆本质差异
错误案例:
public abstract class PaymentMethod {private BigDecimal amount;public abstract void process();
}public class CreditCard extends PaymentMethod {// 信用卡支付
}public class Invoice extends PaymentMethod {// 发票支付
}public class BankTransfer extends PaymentMethod {// 银行转账
}public class Coupon extends PaymentMethod {// 优惠券
}
问题:
- 优惠券本质上不是支付方式,而是折扣机制
- 强行泛化导致业务逻辑混乱
- 更好的设计是将Coupon作为独立的折扣概念
4.3 泛化导致的数据污染
- 问题示例:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Notification {@Idprivate Long id;private String recipient;private String content;private LocalDateTime sentTime;// 其他公共字段
}@Entity
public class EmailNotification extends Notification {private String emailSubject;private String ccList;
}@Entity
public class SMSNotification extends Notification {private String phoneNumber;
}@Entity
public class PushNotification extends Notification {private String deviceToken;private String appId;
}
问题:
- 单表策略下,表会包含所有子类的字段
- 大多数记录会有大量NULL字段
- 随着子类增加,表会变得臃肿
解决方案:
- 考虑使用JOINED策略
- 或将完全不相关的通知类型拆分到不同限界上下文
五、实战案例:电商系统中的泛化设计
5.1 商品类别的泛化设计
- 初始设计:
演进设计(考虑更多业务需求后):
设计演进说明:
- 从简单的继承层次转变为更灵活的混合模式
- 使用接口(或mixin)表示横切关注点
- 将定价策略分离出来,符合单一职责原则
- 每个产品可以组合不同的特性
5.2 订单处理的状态模式实现
public class Order {private String orderId;private OrderState state;public void cancel() {state.cancel(this);}public void approve() {state.approve(this);}public void ship() {state.ship(this);}public void deliver() {state.deliver(this);}// 状态转移方法void changeState(OrderState newState) {this.state = newState;}
}public interface OrderState {void cancel(Order order);void approve(Order order);void ship(Order order);void deliver(Order order);
}public class DraftState implements OrderState {// 实现草案状态的行为
}public class ApprovedState implements OrderState {// 实现已批准状态的行为
}public class ShippedState implements OrderState {// 实现已发货状态的行为
}public class DeliveredState implements OrderState {// 实现已交付状态的行为
}public class CancelledState implements OrderState {// 实现已取消状态的行为
}
优势:
- 每个状态的行为集中在一处
- 避免大量的if-else条件判断
- 新状态易于添加
- 状态转换逻辑明确
六 总结与最佳实践
6.1 何时使用泛化?
适合使用泛化的情况:
- 存在明确的"是一种"业务关系
- 多个概念有显著共享的行为和属性
- 需要以统一接口处理不同概念时
- 业务领域本身有明显的分类体系
应避免泛化的情况:
- 仅为了代码复用而强行抽象
- 差异大于共性的情况
- 未来可能有根本性差异的概念
- 技术驱动而非业务驱动的分类
6.3 泛化的替代方案
当泛化不合适时,考虑:
- 组合:将共性部分提取为独立组件
- 策略模式:将变化的行为抽象为策略
- 装饰器模式:动态添加功能
- 角色模式:允许对象动态获得能力
6.4 持续重构的视角
泛化设计应是演进式的:
- 开始时可以扁平化设计
- 随着重复代码的出现识别共性
- 当业务规则差异明确时引入抽象
- 定期审视泛化层次是否仍然合理
- 记住Eric Evans的话:“深层次模型是逐步演进而非一次性设计出来的,它需要开发人员和领域专家持续协作,通过多次迭代精炼而成。”
相关文章:
领域驱动设计(DDD)【23】之泛化:从概念到实践
文章目录 一 泛化基础:理解DDD中的核心抽象机制1.1 什么是泛化?1.2 为什么泛化在DDD中重要?1.3 泛化与特化的双向关系 二 DDD中泛化的实现形式2.0 实现形式概览2.1 类继承:最直接的泛化实现2.2 接口实现:更灵活的泛化方…...
零基础langchain实战二:大模型输出格式化成json
零基础langchain实战一:模型、提示词和解析器-CSDN博客 书接上文 大模型输出格式化 在下面例子中:我们需要将大模型的输出格式化成json。 import os from dotenv import load_dotenvload_dotenv() # 加载 .env 文件 api_key os.getenv("DEEPS…...
Python 数据分析:numpy,抽提,整数数组索引
目录 1 代码示例2 欢迎纠错3 免费爬虫------以下关于 Markdown 编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个…...
在项目中如何巧妙使用缓存
缓存 对于经常访问的数据,每次都从数据库(硬盘)中获取是比较慢,可以利用性能更高的存储来提高系统响应速度,俗称缓存 。合理使用缓存可以显著降低数据库的压力、提高系统性能。 那么,什么样的数据适合缓存…...
C语言字符串
字符串是C语言最核心的概念之一,却也是引发最多Bug的领域。掌握它,你将解锁高效处理文本的能力;忽视细节,则可能陷入内存陷阱。 一、字符串的本质:字符数组 核心规则:C语言用\0(ASCII值0&#…...
HarmonyOS NEXT仓颉开发语言实战案例:图片预览器
上文分享了如何使用仓颉语言实现动态广场,动态广场中有很多图片,本文一下如何使用仓颉语言实现一个图片放大预览器: 看到这个效果,我首先想到的实现方案是弹窗,弹窗的弹出和消失效果为我们节省了很多工作,这…...
Rust代码规范之蛇形命名法和驼峰命名法
Rust 使用两种主要的命名风格:驼峰命名法(UpperCamelCase)和蛇形命名法(snake_case)。通常,类型(如结构体、枚举、特征)使用驼峰命名法,而变量、函数、方法等使用蛇形命名…...
cocos creator 3.8 - 精品源码 - 六边形消消乐(六边形叠叠乐、六边形堆叠战士)
cocos creator 3.8 - 精品源码 - 六边形消消乐 游戏介绍功能介绍免费体验下载开发环境游戏截图免费体验 游戏介绍 六边形堆叠战士(六边形消消消)是一款脱胎于2048、1010,基于俄罗斯方块的魔性方块达人小游戏,可以多方向多造型消除哦! 功能介…...
(七)Spring Web
Spring Web 是 Spring Framework 的一部分,专门用于构建 Web 应用程序。Spring Web 提供了一个强大的基础设施,用于开发 Web 服务、Web 应用程序和 RESTful API。它包括许多模块和组件,帮助开发人员轻松地构建、配置和管理 Web 应用程序。 以…...
计算机操作系统(十七)内存管理
计算机操作系统(十七)内存管理 前言一、内存的使用与程序重定位(一)内存是什么?(二)程序的重定位过程(三)总结:内存使用的核心问题 二、连续分区管理…...
Java 大视界 -- Java 大数据机器学习模型在金融市场高频交易策略优化与风险控制中的应用(327)
Java 大视界 -- Java 大数据机器学习模型在金融市场高频交易策略优化与风险控制中的应用(327) 引言:正文:一、Java 驱动的高频交易数据处理架构1.1 边缘 - 中心协同数据接入系统(SEC 17a-4 合规)1.2 多市场…...
Idea 项目远程开发 Remote Development
个人建议:Remote Development 使用体验不佳,不推荐。实际远程开发受限于网络通信速度,在开发时,基本无法SSH更新项目内容。 1. File -> Remote Development 2. New Connection Connect to SSH Connection 3. Project director…...
【驱动设计的硬件基础】CPLD和FPGA
在数字电路设计领域,CPLD(复杂可编程逻辑器件)和 FPGA(现场可编程门阵列)堪称 “变形金刚” 般的存在。它们既能像 ASIC(专用集成电路)一样实现硬件加速,又能通过软件编程快速迭代功…...
JavaScript中Object()的解析与应用
在JavaScript中,Object() 是一个基础构造函数,用于创建对象或转换值为对象类型。它既是语言的核心组成部分,也提供了一系列静态方法用于对象操作。以下是详细解析和应用示例: 一、Object() 的基本行为 作为构造函数(…...
Spring Cloud 微服务(负载均衡策略深度解析)
📌 摘要 在微服务架构中,负载均衡是实现高可用、高性能服务调用的关键机制之一。Spring Cloud 提供了基于客户端的负载均衡组件 Ribbon,结合 Feign 和 OpenFeign,实现了服务间的智能路由与流量分配。 本文将深入讲解 Spring Clo…...
从单体架构到微服务:微服务架构演进与实践
一、单体架构的困境与演进 (一)单体应用的初始优势与演进路径 在系统发展的初期,单体架构凭借其简单性和开发效率成为首选。单体应用将整个系统的所有功能模块整合在一个项目中,以单一进程的方式运行,特别适合小型系…...
Infineon AURIX TriCore TC3xx芯片内存专题报告
作者: DBGAUTOMAN 日期: 2025-06-28 摘要 本报告旨在深入分析Infineon AURIX TriCore TC3xx系列微控制器的内存架构。通过对官方技术文档的系统性研究,报告详细阐述了TC3xx的内存配置、架构设计、存储器技术特性、系统级内存管理以及性能优化策略,为相关技术开发和系统设计…...
WPF中获取主窗体
在WPF的MVVM模式中,通常不直接引用主窗体(MainWindow),而是通过依赖注入、事件聚合器或命令参数传递等方式实现逻辑解耦。以下是几种推荐方法: 方法1:依赖注入(推荐) 在ViewModel中…...
【龙泽科技】新能源汽车故障诊断仿真教学软件【吉利几何G6】
产品简介 新能源汽车故障诊断仿真教学软件是依托《全国职业院校技能大赛》“新能源汽车维修”赛项中“新能源汽车简单故障诊断与排除” 竞赛模块,自主开发的一款仿真教学软件。软件采用仿真技术模拟实际的新能源汽车故障诊断过程,主要通过对新能源汽车常…...
SpringBoot -- 以 jar 包运行(以及常见错误分析)
7.SpringBoot 以 jar 包运行 打包 在打包之前先要导入一个maven项目的打包插件,使用 springInitializr 创建的 maven 项目,已经自动导入了。如果没有需要手动导入。将下面代码,放进 Pom.xml 里面即可。 <build><plugins><p…...
求职招聘小程序源码招聘小程序搭建招聘小程序定制开发
身份:求职者、企业 求职者:完善简历,简历投递 企业:企业入驻,查看简历 企业会员:半年 、年度 权益:每日发布条数、刷新条数,简历下载数量 聊天:求职者可以和企业聊…...
Day44 预训练模型
目录 一、预训练的概念 二、常见的分类预训练模型 2.1 CNN架构预训练模型 2.2 Transformer类预训练模型 2.3 自监督预训练模型 三、图像预训练模型的发展史 四、预训练的策略 五、预训练代码实战:resnet18 六、尝试在cifar10对比alexnet 七、尝试通过ctrl进…...
【菜狗的记录】模糊聚类最大树、图神经网络、大模型量化——20250627
每日学习过程中记录的笔记,从各个网站整理下来,用于当日复盘。 如果其中的知识点能帮到你,也很荣幸呀。 -------------------------------------------------------20250622------------------------------------------------------------- …...
【Linux 设备模型框架 kobject 和 kset】
Linux 设备模型框架 kobject 和 kset 一、Linux 设备模型概述二、kobject 与 kset 的核心概念1. kobject2. kset3. 关键数据结构 三、kobject 与 kset 的实现源码四、源码解析与使用说明1. kset 的创建与初始化2. kobject 的创建与属性3. sysfs 属性操作4. 用户空间访问示例 五…...
leetcode.2014 重复k次的最长子序列
题目描述 解题思路 这一题本来在想怎么样做才能获得通用解,因为乍一看总感觉遍历的时间代价会非常高。直到后面看到提示: 提示里面专门包含了一个n < k * 8,这太反常了。后面仔细一想,有道理,最后答案的字符个数一定…...
机器学习3——参数估计之极大似然估计
参数估计 问题背景: P ( ω i ∣ x ) p ( x ∣ ω i ) P ( ω i ) p ( x ) p ( x ) ∑ j 1 c p ( x ∣ ω j ) P ( ω j ) \begin{aligned} & P\left(\omega_i \mid \mathbf{x}\right)\frac{p\left(\mathbf{x} \mid \omega_i\right) P\left(\omega_i\right)…...
利用python实现NBA数据可视化
大家好,今天我们利用python爬取NBA球星每年的比赛数据并进行可视化展示。主要用到三个模块:xpath、matplotlib。其中xpth负责爬取网站上的信息。Matplotlib是Python开发人员常用的Python绘图库,可以用来绘制各种2D图形,具有绘图质…...
杭州西湖断桥不断:3D扫描还原‘残雪‘视觉骗局
“断桥残雪”是西湖十景之一,所谓“视觉骗局”指的是在特定条件下,从远处看断桥仿佛断开的奇妙视觉效果。利用3D扫描技术还原这一效果可按以下步骤进行: 数据采集 3D扫描断桥:使用高精度的3D激光扫描仪对断桥及其周边环境进行全面…...
Dubbo服务调用超时问题解决方案
Dubbo服务调用超时问题解决方案 Dubbo服务调用超时通常由网络延迟、服务端性能瓶颈、配置不当或资源竞争引发。以下解决方案基于根本原因分类,优先采用高可信度实践: 🔍 一、排查问题根源 网络诊断 使用 ping、telnet 检查服务提供者网络连…...
视觉疲劳检测如何优化智能驾驶的险情管理
视觉分析疲劳检测在智能驾驶中的应用研究 一、背景与需求 近年来,智能驾驶领域因疲劳驾驶引发的交通事故频发,如2025年某品牌智能汽车因驾驶员疲劳导致高速追尾事件,暴露了现有技术对复杂场景的适应不足。传统疲劳检测依赖单一生理信号或车…...
C++ 第三阶段 并发与异步 - 第二节:异步任务(std::async)
目录 一、std::async 概述 1. std::async 的定义 二、std::async 的基本用法 1. 基本语法 (1) 函数调用 (2) Lambda 表达式 三、执行策略详解 1. std::launch::async 2. std::launch::deferred 3. 默认策略(std::launch::any) 四、std::futur…...
OpenCV图像添加水印
一、前言 在数字图像处理中,为图片添加水印是一项常见且重要的技术。无论是版权保护、品牌宣传还是防止未经授权的使用,水印都能发挥重要作用。OpenCV作为一款强大的计算机视觉库,提供了丰富的功能来实现各种水印效果。本教程将详细介绍如何…...
Linux信号机制:从入门到精通
嘿,小伙伴们!今天我要和大家聊一个Linux系统中非常有趣又重要的话题——信号机制。别担心,虽然信号听起来有点高深,但我会用最通俗易懂的语言,配合清晰的图表,带你彻底搞懂这个概念! 什么是信号…...
EXCEL数据报表
客单价成交金额*成交客户数 —— 提取年份 YEAR() 视图-窗口-新建窗口,就能将excel的一个子表格单拎出来成为独立窗口,方便对比查看 数据报表的单元格尽量都用公式来填补,链接到源表上去。这样当源表有新数据更新进来后,报表也…...
openGL学习(VAO和VBO)
理论 VBO void prepare() {//创建一个VBO,但是还没有分配显存GLuint vbo 0;GL_CALL( glGenBuffers(1, &vbo));cout << "vbo " << vbo << endl;//销毁一个VBOGL_CALL(glDeleteBuffers(1, &vbo));cout << "delete vbo "…...
【请关注】制造企业机械加工数据脱敏解决方案
制造企业机械加工数据脱敏解决方案 一、方案概述 在制造企业尤其是机械加工领域,数字化转型带来了生产效率的大幅提升,大量生产数据、设备运行数据、供应链数据以及客户订单数据等成为企业发展的关键驱动力。然而,这些数据中包含众多敏感信息,如客户定制产品的设计图纸(…...
2025.6.27总结
最近工作又开始内耗了,一位同事的转岗直接让我破防了,明明他工作干得很不错,会得又多,性格又好,我还经常请教他业务上的问题。我和他的关系并不算太好,但他加入其他部门,竟然让我有些不舍&#…...
Python打卡:Day38
知识点回顾: Dataset类的__getitem__和__len__方法(本质是python的特殊方法)Dataloader类minist手写数据集的了解 浙大疏锦行...
Ubuntu18.04/Mysql 5.7 建立主备模式Mysql集群
一、数据库的安装 详见https://www.jianshu.com/p/5073177eedf2 本文实验环境为阿里云的两台ubuntu18.04服务器: master ip: 172.26.138.7 slave ip: 172.26.0.209 二、修改Master的配置(# 的行是我后增加的部分): 编辑 /etc/mysql/mysql.conf.d/mysqld.…...
Linux journal 日志大小限制与管理详解
文章目录 Linux journal 日志大小限制与管理详解journal 日志的默认存储位置journal 日志大小限制配置查看当前日志占用情况手动清理日志文件按大小清理日志按时间清理日志按文件数清理日志 journald 日志机制原理简析(适当加点原理)日志筛选与导出技巧&…...
Linux基本指令篇 —— tac指令
tac 是 Linux 系统中一个非常实用的文本处理命令,它是 cat 命令的反向操作(名称也是 "cat" 的反写)。tac 是一个简单但功能强大的工具,特别适合需要反向处理文本数据的场景: 目录 一、基本功能 二、基本语法…...
【Yonghong 企业日常问题08 】永洪BI的Apache Tomcat版本升级指南
文章目录 前言操作步骤登录验证 前言 某公司业务永洪BI系统使用tomcat 9.0.97版本,接到总公司漏洞扫描整改要求需要将tomcat版本升级到9.0.97以上。 目标:tomcat 9.0.97》 9.0.98 1、下载tomcat所需要的版本 地址:https://tomcat.apache.org/download-…...
动手学Python:从零开始构建一个“文字冒险游戏”
动手学Python:从零开始构建一个“文字冒险游戏” 大家好,我是你的技术向导。今天,我们不聊高深的框架,也不谈复杂的算法,我们来做一点“复古”又极具趣味性的事情——用Python亲手打造一个属于自己的文字冒险游戏&…...
【C/C++】C++26新特性前瞻:全面解析未来编程
展望未来:C26 新特性全面解析 随着 C 标准每三年一次的迭代节奏,C26(预计于 2026 年底正式发布)正在逐步成型。相比 C20 的革命性更新和 C23 的“修补增强”,C26 继续推进现代 C 的理念——更安全、更高效、更模块化&…...
Linux系统日志与守护进程开发实战指南
Linux系统日志与守护进程开发实战指南 系统日志与守护进程 ├── 系统日志syslog │ ├── 日志路径: /var/log/syslog │ └── 核心API │ ├── openlog │ ├── syslog │ └── closelog └── 守护进程daemon└── 创建步骤├── um…...
兰洋科技上合组织论坛发表专题分享,全球液冷布局引领绿色算力未来
2025年6月17-19日,中国—上海合作组织数字技术合作发展论坛在新疆克拉玛依市举办。作为第四次上海合作组织成员国信息通信技术发展部门负责人会议的配套会议,论坛以“数字化转型助力可持续发展,数字包容促进上合共同繁荣”为主题,…...
桌面小屏幕实战课程:DesktopScreen 11 SPI 水墨屏
飞书文档https://x509p6c8to.feishu.cn/docx/doxcnlzpIgj3gosCZufBTCZxlMb SPI说明 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上占用…...
小知识点五、无刷电机闭环控制(电流)
0 前言 该部分只用于自学使用,作为笔记方便后续自查。 资料参考:http://dengfoc.com 硬件:2208云台电机MT6701磁编码器 1 电流控制理论 1.1 待解决的问题 简单回顾一下在之前的学习中,我们通过 U q U_q Uq和电角度 θ \the…...
Java 编程之备忘录模式
前言 有时候,我们真希望人生能有“CtrlZ”。在日常生活中,我们经常使用“撤销”功能,例如在写 Word、画图、写代码时一不小心操作失误,就希望能回到之前的状态。这种**“状态快照 恢复”**机制,在设计模式中就叫做&a…...
SQL SERVER存储过程
什么是存储过程 SQL 存储过程(Stored Procedure)是一个在数据库中预编译并存储的一组 SQL 语句。它们可以包含查询、插入、更新、删除等数据库操作,甚至包括控制流语句(如条件判断、循环等)。存储过程可以通过调用来执…...