领域驱动设计(DDD)模式深度剖析与 C# 实践
一、DDD 模式概述
领域驱动设计(Domain-Driven Design,简称 DDD)是一种软件开发方法论,旨在应对复杂业务领域的软件系统构建挑战。它强调以领域模型为核心,围绕业务领域中的关键概念、规则以及它们之间的关系来组织软件架构与设计,使软件系统能够更紧密地贴合业务需求,提高可维护性、可扩展性与可理解性。
在传统软件开发过程中,常出现业务逻辑分散于不同技术层面(如数据库操作层、用户界面层)的问题,导致系统牵一发而动全身,代码变更困难。DDD 则通过划分清晰的分层架构与明确界定领域对象职责,将复杂业务领域分解为多个界限明确的子领域,各子领域聚焦自身业务逻辑,协同工作以支撑整体业务运转。
二、DDD 核心概念
(一)领域与子领域
领域是指业务所涉及的整个范围,涵盖业务操作、规则、流程等方方面面。例如,电商领域包含商品管理(上架、下架、库存盘点等)、订单处理(下单、支付、发货、退款)、客户服务(用户注册、信息修改、咨询处理)等复杂业务活动。为便于管理与设计,会依据业务关联性与功能独立性,将大领域切分为多个子领域,像电商领域可细分为商品子领域、交易子领域、客户子领域等,各子领域相对自治又协同配合。
(二)限界上下文
限界上下文(Bounded Context)是 DDD 中至关重要的概念,它界定每个子领域的边界,明确其中通用语言(Ubiquitous Language)适用范围与领域对象含义。在不同限界上下文里,相同术语可能有不同语义,例如电商 “商品”,在商品管理上下文中侧重于属性编辑、分类设定;在订单处理上下文中则侧重商品规格、价格用于订单金额计算,借助限界上下文避免语义混淆,确保领域模型准确性。
(三)实体
实体(Entity)是具有唯一标识的领域对象,其标识在生命周期内保持不变,即便对象属性值变更。以电商订单为例,订单号作为唯一标识,无论订单状态(待支付、已发货、完成等)、商品详情、收货地址如何改变,订单实体凭借订单号可被精准追踪与操作,实体承载业务规则与行为,像订单可执行取消操作(需校验支付状态、库存回滚等规则)。
(四)值对象
值对象(Value Object)无自身唯一标识,通过属性值组合确定自身特征,多个属性共同描述一个完整概念且不可变(若需变更则创建新值对象)。如电商收货地址是值对象,包含省、市、区、街道、邮编等属性,当地址信息修改,等同替换整个地址值对象,它用于传递数据、参与运算且简化实体间关联,增强领域模型内聚性。
(五)聚合与聚合根
聚合(Aggregate)是一组紧密关联的领域对象集合,遵循一致性边界规则,确保数据完整性与业务规则一致性。聚合根(Aggregate Root)是聚合的入口点,外部对象只能通过聚合根访问聚合内其他对象,维护聚合内对象间层级与协作关系。例如电商订单聚合,订单实体作为聚合根,关联订单项(包含商品、数量、单价等)、收货地址等值对象,订单取消时,聚合根协调各对象按规则执行库存回补、状态更新等系列操作。
(六)领域事件
领域事件(Domain Event)是领域内发生的有意义事情的记录与通知机制,反映业务流程关键节点变化,如 “订单已支付”“商品库存不足” 事件。它解耦不同限界上下文或业务模块,发布订阅模式下,相关方监听感兴趣事件触发后续业务逻辑,像支付成功事件触发物流系统启动发货准备、积分系统给予用户积分奖励。
(七)通用语言
通用语言是团队(包含业务人员、开发人员、测试人员等)在 DDD 项目沟通中统一使用的业务术语集合,确保各方对领域概念、规则理解一致,融入代码实现(类名、方法名、注释等),使代码 “可读”“可沟通”,如 “确认收货” 在业务流程与代码方法命名保持一致,减少歧义、提升协作效率。
三、DDD 分层架构
(一)用户界面层(User Interface Layer)
负责与用户交互,接收输入、展示输出,涵盖 Web 页面、桌面客户端、移动端界面等形式,是系统对外 “窗口”。在 C# Web 应用中,ASP.NET Core MVC 或 Blazor 框架负责渲染视图、处理用户请求(如用户在电商页面点击下单,接收表单数据传递给下一层),应保持简洁,避免业务逻辑嵌入,仅做数据展示与请求转发。
(二)应用层(Application Layer)
编排领域对象协作完成业务用例,类似 “指挥官” 角色,不包含核心业务规则。它接收界面层请求,调用领域层方法、协调多个聚合操作、处理事务、发布领域事件等。以电商下单流程为例,应用层方法PlaceOrder
接收订单数据,验证参数合法性后,通过仓储接口获取商品库存、客户信息,指挥订单聚合根创建订单、扣减库存、关联支付信息等系列操作,确保业务流程连贯、原子性。
public class OrderApplicationService
{private readonly IOrderRepository _orderRepository;private readonly IProductRepository _productRepository;private readonly IUnitOfWork _unitOfWork;public OrderApplicationService(IOrderRepository orderRepository, IProductRepository productRepository, IUnitOfWork unitOfWork){_orderRepository = orderRepository;_productRepository = productRepository;_unitOfWork = unitOfWork;}public async Task<OrderDto> PlaceOrder(OrderCreateDto orderCreateDto){// 验证订单数据合法性if (!ValidateOrderData(orderCreateDto)){throw new ApplicationException("订单数据无效");}// 获取商品信息var productList = await _productRepository.GetProductsByIds(orderCreateDto.ProductIds);// 创建订单聚合根var order = new Order(orderCreateDto.CustomerId);foreach (var item in orderCreateDto.OrderItems){var product = productList.FirstOrDefault(p => p.Id == item.ProductId);if (product == null){throw new ApplicationException($"商品{item.ProductId}不存在");}order.AddOrderItem(product, item.Quantity);}// 保存订单_orderRepository.Add(order);await _unitOfWork.CommitAsync();return MapToDto(order);}
}
(三)领域层(Domain Layer)
是 DDD “心脏”,包含实体、值对象、聚合、领域服务、领域事件等核心元素,封装复杂业务逻辑与规则。如订单实体类中Cancel
方法实现取消订单逻辑,检查支付状态、解锁库存、记录取消日志等操作都依循严谨业务规则,领域层独立于技术框架,专注业务本质表达,保证高内聚、低耦合,提升复用性与可维护性。
public class Order : AggregateRoot
{public Guid Id { get; private set; }public Guid CustomerId { get; private set; }public OrderStatus Status { get; private set; }private readonly List<OrderItem> _orderItems = new List<OrderItem>();public Order(Guid customerId){Id = Guid.NewGuid();CustomerId = customerId;Status = OrderStatus.Created;}public void AddOrderItem(Product product, int quantity){var orderItem = new OrderItem(product, quantity);_orderItems.Add(orderItem);}public void Cancel(){if (Status == OrderStatus.Paid){// 执行库存回滚等复杂逻辑foreach (var item in _orderItems){item.Product.ReleaseStock(item.Quantity);}}Status = OrderStatus.Cancelled;// 记录取消日志等业务逻辑}
}
(四)基础层(Infrastructure Layer)
提供通用技术能力支撑,涵盖数据库持久化(EF Core 实现仓储接口与数据库交互)、消息队列集成(发送接收领域事件)、缓存机制等,实现领域层抽象接口,为上层屏蔽技术细节,保障领域层纯净业务性,像仓储接口IOrderRepository
在基础层用 SQL Server 数据库操作实现增删改查订单实体功能。
public class OrderRepository : IOrderRepository
{private readonly MyDbContext _dbContext;public OrderRepository(MyDbContext dbContext){_dbContext = dbContext;}public async Task Add(Order order){await _dbContext.Orders.AddAsync(order);}public async Task<Order> GetById(Guid id){return await _dbContext.Orders.FindAsync(id);}// 其他查询、更新、删除方法实现
}
四、DDD 实践步骤
(一)领域建模启动
项目伊始,业务专家与技术团队紧密合作,梳理业务流程、挖掘领域概念,绘制业务流程图、用例图勾勒业务场景与操作,提炼实体、值对象、聚合关系形成初步领域模型草图,例如电商项目初期确定商品、订单、客户为核心实体及关联关系,勾勒出商品聚合(含分类、属性等值对象)、订单聚合框架。
(二)限界上下文划分
依据业务功能模块独立性、语义一致性细分领域为限界上下文,绘制上下文映射图展示交互关系(合作、共享、防腐层隔离等),像电商分商品管理、订单交易、物流配送限界上下文,商品管理上下文为订单交易提供商品详情,借助防腐层转换适配避免直接依赖、保证各自演进。
(三)领域对象精化与代码实现
在各限界上下文内,详细设计实体属性、行为,值对象结构,聚合层次,用 C# 类、接口精准编码实现,遵循领域层业务聚焦、应用层编排协调、基础层技术支撑分层原则,持续迭代优化领域模型,应对业务变化,如订单实体随支付规则调整完善支付相关方法逻辑、仓储接口适配新数据库架构优化查询性能。
(四)集成与演进
完成各模块开发后,通过依赖注入、接口适配集成各层组件,搭建完整系统,上线运行后依据业务反馈、性能瓶颈监测,持续回溯优化领域模型、调整分层架构、升级技术选型,如电商流量增长时优化数据库索引、引入分布式缓存提升订单查询效率、拓展领域事件应用于大数据分析场景。
五、DDD 优势与挑战
(一)优势
- 紧密贴合业务:通用语言与领域建模保障软件与业务同频,业务变更能高效映射到代码,降低需求理解偏差。
- 架构清晰可维护:分层架构、限界上下文隔离,职责明确,修改局部代码不牵全局,长期维护成本低。
- 复用与扩展:领域对象高内聚、通用业务逻辑复用,新业务拓展可在既有模型、架构添模块,如电商拓展跨境业务复用基础商品、订单模型修改适配海关规则。
(二)挑战
- 学习成本高:复杂概念多,团队需深入理解掌握 DDD 理念、实践,前期投入大。
- 初期建模难度大:精准勾勒领域模型、划分限界上下文依赖深厚业务洞察、经验,易返工调整。
- 团队协作要求高:业务、开发、测试围绕通用语言协同,跨职能沟通不畅会致模型 “走样”、功能偏离。
六 、DDD开源项目
1. Axon Framework(Java)
- 项目概述
- Axon Framework 是一个用于构建基于事件驱动的微服务和应用程序的框架,它紧密遵循领域驱动设计(DDD)原则。这个框架提供了一系列工具和库,帮助开发者轻松地实现事件溯源、命令查询职责分离(CQRS)以及领域模型的构建。
- 功能特点
- 事件溯源:Axon 支持事件溯源,这意味着它可以记录领域对象的所有状态变化历史。例如,在一个财务系统中,每一笔账目交易都可以被看作是一个事件,通过事件溯源,系统能够重现账户在任何时间点的状态。它通过存储事件流,并根据这些事件重新构建对象状态。
- CQRS 架构实现:Axon 能够很好地实现 CQRS 模式。在这种模式下,命令(用于修改状态)和查询(用于获取数据)被分离到不同的模型和处理路径中。这样可以优化系统的性能,提高可扩展性,并且使得系统更容易维护。例如,在一个电商系统中,下单操作(命令)和查询订单详情(查询)可以通过不同的方式处理,互不干扰。
- 聚合管理:Axon 提供了强大的聚合管理功能。聚合是 DDD 中的核心概念之一,它代表了一组相关的领域对象,这些对象应该作为一个整体来处理。Axon 通过提供注解和接口,方便开发者定义和管理聚合,确保聚合的一致性和完整性。例如,在一个物流系统中,一个 “运输任务” 聚合可能包含货物信息、运输车辆信息、司机信息等,Axon 帮助管理这些对象之间的关系和操作。
- 应用场景示例
- 金融交易系统:可以利用 Axon 的事件溯源功能记录每一笔交易,如股票交易、转账等操作。通过存储这些事件,系统可以方便地进行审计、风险评估和历史数据查询。例如,当需要查询某个账户在过去一个月内的所有交易记录时,Axon 可以快速地根据事件流重建账户状态并提供准确的信息。
- 供应链管理系统:在供应链中,从订单处理、库存管理到物流配送都涉及大量的事件和复杂的业务逻辑。Axon 可以帮助构建一个基于事件驱动的系统,使得各个环节之间能够通过事件进行通信和协调。例如,当库存水平低于某个阈值时,库存管理模块可以发布一个 “库存不足” 的事件,触发采购模块进行补货操作。
2. Eventuate Tram(Java)
- 项目概述
- Eventuate Tram 是一个用于构建微服务架构的开源框架,它强调事件驱动和 DDD 理念。这个框架提供了一套简单而强大的工具,用于在微服务之间进行异步通信、数据一致性维护以及领域事件的处理。
- 功能特点
- 事件驱动通信:Eventuate Tram 支持微服务之间通过事件进行通信。这使得各个微服务可以解耦,它们只需要关注自己感兴趣的事件,而不需要直接依赖其他微服务的接口。例如,在一个电商系统中,用户服务可以发布 “用户注册成功” 的事件,而营销服务可以订阅这个事件,以便向新用户发送欢迎邮件或优惠券。
- 数据一致性保障:在分布式系统中,数据一致性是一个关键问题。Eventuate Tram 提供了机制来确保跨多个微服务的数据一致性。它通过使用事件溯源和分布式事务处理技术,保证在复杂的业务操作中,各个微服务的数据状态能够保持一致。例如,在一个在线预订系统中,当用户预订一个酒店房间时,预订服务、支付服务和酒店库存服务之间需要保持数据一致,Eventuate Tram 可以帮助协调这些服务之间的操作。
- 领域事件处理:框架提供了方便的方式来处理领域事件。开发者可以轻松地定义事件处理器,对不同类型的事件进行相应的业务逻辑处理。例如,在一个物流系统中,当收到 “货物已发货” 的事件时,可以触发通知用户的操作,同时更新运输状态的记录。
- 应用场景示例
- 微服务架构的电商平台:包括用户服务、商品服务、订单服务、支付服务等多个微服务。Eventuate Tram 可以用于在这些微服务之间传递事件,如订单创建事件、支付完成事件等。当订单服务创建一个新订单时,它可以发布一个订单事件,商品服务和支付服务可以订阅这个事件并进行相应的处理,如扣除库存和处理支付。
- 物联网应用场景:在物联网环境中,有大量的设备产生数据并需要进行处理。Eventuate Tram 可以用于在不同的物联网服务之间传递设备事件,例如传感器数据更新事件、设备状态变化事件等。这些事件可以被不同的服务用于监控、分析和决策,如能源管理系统根据设备能耗数据进行节能策略调整。
3. NestJS(TypeScript/JavaScript)
- 项目概述
- NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。它借鉴了许多其他流行框架的优秀设计理念,包括 Angular,并很好地支持 DDD 原则,使得开发者能够以模块化、层次化的方式构建应用。
- 功能特点
- 模块化架构:NestJS 采用模块化的设计,这与 DDD 中的模块划分理念相契合。每个模块可以看作是一个独立的领域单元,它包含了自己的控制器(用于处理 HTTP 请求)、服务(包含业务逻辑)、存储库(用于数据访问)等组件。例如,在一个博客系统中,可以有用户模块、文章模块和评论模块,每个模块都有自己的功能和职责范围。
- 依赖注入系统:NestJS 拥有强大的依赖注入系统,这有助于实现组件之间的解耦和可测试性。通过依赖注入,对象之间的依赖关系可以在外部进行配置,而不是在对象内部硬编码。在 DDD 中,这对于管理领域对象之间的关系非常有用。例如,在一个电商应用中,订单服务可能依赖于商品服务和用户服务,通过依赖注入可以方便地替换这些服务的实现,用于测试或者适应不同的业务场景。
- 中间件支持:框架提供了中间件机制,用于在请求处理管道中添加各种预处理和后处理逻辑。这在 DDD 中可以用于处理跨领域的横切关注点,如日志记录、权限验证等。例如,在一个企业资源规划(ERP)系统中,可以通过中间件对所有的业务请求进行权限验证,确保只有授权用户能够访问相应的领域功能。
- 应用场景示例
- 企业级后台管理系统:构建一个用于企业内部资源管理的系统,包括员工管理、项目管理、财务管理等模块。NestJS 的模块化架构可以很好地组织这些领域模块,每个模块可以独立开发、测试和维护。例如,员工管理模块可以处理员工信息的增删改查、工资计算等业务逻辑,项目管理模块可以负责项目的创建、进度跟踪等功能。
- 实时应用程序:如在线聊天应用或者实时数据监控系统。NestJS 结合 WebSockets 等技术可以实现实时通信功能,同时利用其 DDD 友好的架构来处理聊天消息的领域逻辑、用户状态管理以及数据持久化等任务。例如,在聊天应用中,消息模块可以处理消息的发送、接收和存储,用户模块可以管理用户的在线状态和聊天权限。
4. SimpleCQRS(C#)
- 项目概述
- SimpleCQRS 是一个用 C# 编写的简单的命令查询职责分离(CQRS)和事件溯源示例项目。它通过一个小型但完整的应用场景展示了如何在.NET 环境中应用 DDD 的一些关键原则,特别是 CQRS 和事件溯源的实现方式。
- 功能特点
- CQRS 实现示例:SimpleCQRS 清晰地展示了命令和查询的分离。它定义了不同的命令对象用于修改领域状态,以及查询对象用于获取数据。例如,在一个库存管理系统的示例中,有 “调整库存数量” 的命令对象,它包含了要调整的产品 ID 和调整的数量等信息,用于修改库存数据;同时有 “查询库存水平” 的查询对象,用于获取指定产品的当前库存数量。
- 事件溯源基础展示:项目展示了事件溯源的基本原理。所有对领域状态的修改都会产生相应的事件,这些事件被存储起来。系统可以通过重新播放这些事件来重建领域对象的状态。以库存管理为例,每次库存的增加或减少都会产生一个库存变更事件,通过这些事件的历史记录,可以追溯库存的变化情况。
- 简单易懂的架构:SimpleCQRS 的代码结构简单,易于理解。它没有过多复杂的框架依赖,对于初学者来说是一个很好的学习 DDD 相关概念的示例。它展示了如何在一个相对简单的 C# 应用程序中构建领域模型、处理命令和查询,以及如何利用事件来维护领域状态。
- 应用场景示例
- 小型业务系统学习案例:作为一个学习工具,SimpleCQRS 可以用于教学或者个人学习 DDD 和 CQRS 概念。例如,在一个小型的学生成绩管理系统中,可以应用其理念。“更新成绩” 命令用于修改学生的成绩信息,产生相应的成绩变更事件,“查询成绩” 查询对象用于获取学生的成绩列表。通过这种方式,学生可以直观地理解 DDD 相关概念在实际系统中的应用。
- 快速原型开发:在开发一些小型的、对架构灵活性有一定要求的项目原型时,SimpleCQRS 可以作为一个基础框架。例如,在一个活动报名系统的早期原型阶段,利用其命令和查询分离的思想,快速实现活动报名(命令)和活动参与人数查询(查询)等功能,并且通过事件溯源来记录报名信息的变化历史,为后续系统的完善提供基础。
七、总结
DDD 模式为复杂业务软件系统构建提供有力范式,以领域模型锚定业务核心,借分层架构、限界上下文等机制解耦复杂性、保障系统演进。虽面临学习、建模、协作挑战,但长期收益可观,C# 生态凭借丰富框架(ASP.NET、EF Core 等)适配 DDD 实践各环节,助力开发者打造高质量、可扩展、贴合业务 “灵动” 软件系统,持续赋能业务创新与数字化转型。随着业务场景愈发复杂、技术迭代加速,DDD 将在软件开发领域持续深耕拓展,融入微服务、云原生架构,绽放更大价值。
相关文章:
领域驱动设计(DDD)模式深度剖析与 C# 实践
一、DDD 模式概述 领域驱动设计(Domain-Driven Design,简称 DDD)是一种软件开发方法论,旨在应对复杂业务领域的软件系统构建挑战。它强调以领域模型为核心,围绕业务领域中的关键概念、规则以及它们之间的关系来组织软…...
2024“蜀道山” RE 部分题解
Map_maze 题目描述 真真假假真真,你能够寻找到最后的终点吗? 附件下载 迷宫生成 v5 是一个长度为 105 的数组,被用作 15x15 的二维网格 int __cdecl sub_4010D0(_DWORD *a1, _DWORD *a2) {_DWORD *v2; // eax_DWORD *v3; // eaxint result; // eax_DWORD v5[1…...
composition
议论文 三个段落 第一段:2-3句话((1)引出背景(2)提出问题(3)过渡句) 第一段 (1)引出背景 As the giant leap of __(society,technology,education,culture,medical se…...
前端开发:构建高质量用户体验的全方位指南(含实际案例与示例)
前端开发:构建高质量用户体验的全方位指南(含实际案例与示例) 在当今数字化时代,前端技术不仅是网页和应用的门面,更是连接用户与数字世界的桥梁。一个高质量的前端开发项目不仅能够提升用户体验(UX&#…...
从Facebook的技术演进看社交媒体的未来趋势
在过去的二十年里,Facebook(现为Meta)从一个大学校园中的社交平台发展成了全球最大的社交媒体网络之一,成功塑造了人们交流、分享和消费信息的方式。作为社交媒体的巨头,Facebook的技术演进不仅推动了平台自身的发展&a…...
Linux下的wlan0控制
WIFI常用的两种模式:STA / AP 1. STA模式:客户端 嵌入式的系统下常常要手动配置wifi,和IP地址才能开始上网,关于STA模式下,常用的wifi配置工具有wpa_supplicant和轻量级的udhcpc客户端。 1.1wpa_supplicant 最小配置…...
常用循环依赖解决方案
常用循环依赖解决方案 Spring框架在4.3版本开始引入了对循环依赖的更好支持,但在此之前,Spring已经提供了一些机制来处理循环依赖。 实际上,Spring从一开始就提供了几种解决循环依赖的方法,只是在后续版本中对这些机制进行了优化…...
HTTPTomcatServlet
今日目标: 了解JavaWeb开发的技术栈理解HTTP协议和HTTP请求与响应数据的格式掌握Tomcat的使用掌握在IDEA中使用Tomcat插件理解Servlet的执行流程和生命周期掌握Servlet的使用和相关配置1,Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网,也称为万维网(www),能够通过浏览…...
instanceof运算符
而instanceof可以精准判断数据类型...
Conda 管理python开发环境
同步发布于我的网站 🚀 故事起因: 在公司使用Requests多任务并行开发时遇到了问题,使用 ProcessPoolExecutor 时不能正常发出网络请求,会卡在网络请求发不出去,但是善于用 ThreadPoolExecutor 时是可以的,纠结了很久,一…...
uniapp关闭sourceMap的生成,提高编译、生产打包速度
警告信息:[警告⚠] packageF\components\mpvue-echarts\echarts.min.js 文件体积超过 500KB,已跳过压缩以及 ES6 转 ES5 的处理,手机端使用过大的js库影响性能。 遇到问题:由于微信小程序引入了mpvue-echarts\echarts.min.js&…...
服务器挖矿
文章目录 一、确定挖矿进程并停止二、查找并清除挖矿相关文件三、检查并修复系统漏洞四、加强安全防护 一、确定挖矿进程并停止 查找挖矿进程 在Linux系统中,可以使用命令如top或htop来查看系统资源占用情况。挖矿程序通常会占用大量的CPU或GPU资源。例如ÿ…...
Flink双流Join
在离线 Hive 中,我们经常会使用 Join 进行多表关联。那么在实时中我们应该如何实现两条流的 Join 呢?Flink DataStream API 为我们提供了3个算子来实现双流 join,分别是: join coGroup intervalJoin 下面我们分别详细看一下这…...
.net XSSFWorkbook 读取/写入 指定单元格的内容
方法如下: using NPOI.SS.Formula.Functions;using NPOI.SS.UserModel;using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;using OfficeOpenXml.FormulaParsing.Excel.Functions.Numeric;/// <summary>/// 读取Excel指定单元格内容/// </summa…...
【VUE3】【Naive UI】<NCard> 标签
【Vue3】【Naive UI】 标签 title 属性bordered 属性header-style 和 body-style 属性footer 属性actions 属性hoverable 属性loading 属性size 属性type 属性cover 和 avatar 属性description 属性style 属性 【VUE3】【Naive UI】<NCard> 标签 【VUE3】…...
喜欢发光的自己
Music: 听见下雨的声音 想着写点什么吧...从哪开头好呢?... 好像有很多话想记录下来,但又不知道从哪开头 自上次写博客至现在已经有段时间了。 最近还发生了挺多事,自己的身体又将面临一次考验... 有颗蛀牙,但莫名奇妙的是里…...
mfc110u.dll是什么意思,mfc110u.dll丢失解决方法大全详解
mfc110u.dll是Microsoft Foundation Classes (MFC)库的一个特定版本(版本11.0)的Unicode动态链接库文件。MFC是Microsoft为C开发者设计的一个应用程序框架,主要用于简化Windows应用程序的开发工作。这个框架封装了很多Windows API函数&#x…...
制片人欧阳行远:引领独立电影斩获国际殊荣
随着全球电影市场对独特叙事和多元化题材的需求持续高涨,独立电影再次成为业内外讨论的焦点,尤其是聚焦亲情、成长经历和女性视角的影片,在国际影坛掀起了一股热潮。这一趋势的形成,离不开一些杰出短片的奠基作用,而欧阳行远作为执行制片人,凭借敏锐的行业嗅觉和出色的制作能力…...
《C++ Primer Plus》学习笔记|第7章-函数——C++编程模块 (未完结)
文章目录 7.1 函数的基本知识7.1.1 定义函数7.1.2 函数原型和函数调用 7.2 函数参数和按值传递7.3 函数与数组7.3.5 指针与const7.4 函数和二维数组 7.10 函数指针1. 函数的地址2. 声明函数指针3.使用指针来调用函数 7.12 复习题1. 使用函数的3个步骤是什…...
C/C++ 数据结构与算法【线性表】 顺序表+链表详细解析【日常学习,考研必备】带图+详细代码
1)线性表的定义 线性表(List):零个或多个数据元素的有限序列。 线性表的数据集合为{a1,a2,…,an},假设每个元素的类型均为DataType。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素…...
详细说说 JDK 的线程池的创建参数
文章目录 1. 概要2. 线程的核心参数2.1.核心线程和最大线程2.2.任务队列2.2.1.ArrayBlockingQueue2.2.2.LinkedBlockingQueue2.2.3.SynchronousQueue2.2.4.PriorityBlockingQueue2.2.5.DelayQueue2.2.7.LinkedBlockingDeque 2.3 keepAliveTime2.4 ThreadFactory2.5 拒绝策略 3.…...
惠普电脑切换默认F1至F12快捷键,FN切换
发现新买的惠普电脑,按F1至F12发现是快捷功能键,而按fnF1至F12才是windows的功能键和正常我自己使用的电脑刚好相反,实在太不方便了。 解决办法需要进入biso里面去把功能键模式选中给关掉,才能恢复回来...
RabbitMQ在手动消费的模式下设置失败重新投递策略
最近在写RabbitMQ的消费者,因为业务需求,希望失败后重试一定次数,超过之后就不处理了,或者放入死信队列。我这里就达到重试次数后就不处理了。本来以为很简单的,问了kimi,按它的方法配置之后,发…...
[巅峰极客 2021]签到
[巅峰极客 2021]签到 给了我们好多表情,真的是一脸懵逼 注意给我们的关键词 GAME 现在还不知道是什么意思我们去试着解开一下 用这个emoji表情解密器,这里我找了好久才找到一个 emoji-aes 这里的Key值就是GAME 运行后出现flag NSSCTF{10ve_4nd_Peace…...
CrystalDiskInfo:硬盘健康监测工具简介和下载
原论坛给你更好的阅读体验:CrystalDiskInfo:硬盘健康监测工具简介和下载 | 波波论坛 引言 在日常使用电脑时,硬盘的健康状态对于系统的稳定性和数据的安全性至关重要。硬盘出现故障可能会导致数据丢失,严重时甚至会使整个系统无…...
循环神经网络(RNN)详解
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
vue基础之3:模板语法、数据绑定
欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…...
Ubuntu通过脚本启动多个可执行文件
Ubuntu通过脚本启动多个可执行文件 在 Ubuntu 中,可以通过一个脚本启动多个可执行文件,同时支持顺序执行、并行执行或特定条件下的执行。以下是实现的详细方法: 1. 创建脚本文件 首先,创建一个脚本文件,例如 start_p…...
【C++】LeetCode:LCR 026. 重排链表
题干 LCR 026. 重排链表 给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 → L1 → … → Ln-1 → Ln 请将其重新排列后变为: L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → … 不能只是单纯的改变节点内部的值,而是需要实…...
文档加密怎么做才安全?
公司的文档包含很多机密文件,这些文件不仅关乎公司的核心竞争力,还涉及到客户隐私、商业策略等敏感信息。因此,文档的保管和传递一直是我们工作的重中之重。 为了确保机密文件的安全,公司需要制定了一系列严格的保密措施。从文件的…...
CTF之WEB(php弱类型绕过)
PHP 的弱类型特性有时会导致意外的行为,特别是在类型比较时。这些特性可以被利用来绕过一些预期的安全检查。以下是一些常见的 PHP 弱类型绕过技巧及其解释: 类型介绍 1. 类型比较 ( vs ) 在 PHP 中, 是松散比较,而 是严格比较…...
Java ConcurrentHashMap
Java Map本质不是线程安全的,HashTable和Collections同步包装器(Synchronized Wrapper)在并发场景下性能低。Java还为实现 Map 的线程安全提供了并发包,保证线程安全的方式从synchronize简单方式到精细化,比如Concurre…...
力扣162:寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时间复杂度为 O(…...
网络设备配置指南:交换机、路由器与防火墙的基础配置与管理
在现代网络管理中,交换机、路由器和防火墙是不可或缺的关键设备。掌握这些设备的基本配置与管理,对于确保网络的稳定性、安全性和高效性至关重要。本文将详细介绍交换机、路由器和防火墙的基础配置与管理,并通过代码示例和图示来帮助读者更好地理解和应用。 一、交换机的基…...
parallelStream并行流使用踩坑,集合安全
parallelStream并行流使用踩坑 parallelStream介绍 parallelStream实现的是多线程处理从而实现并行流,相较于stream的单行流处理数据的速度更快,看一下其源码会发现parallelStream是使用线程池ForkJoin来调度的。 而ForkJoinPool的默认线程数是CPU核数 …...
清远榉之乡托养机构探讨:自闭症的本质辨析
当人们谈及自闭症时,常常会产生一个疑问:自闭症是精神类疾病吗?今天,清远榉之乡托养机构就来为大家解开这个疑惑。 榉之乡大龄自闭症托养机构在江苏、广东、江西等地都有分校,一直致力于为大龄自闭症患者提供专业的支持…...
音视频入门基础:MPEG2-TS专题(10)——PAT简介
一、引言 当某个transport packet的TS Header中的PID属性的值为0x0000时,该transport packet的payload为Program association table ,即 PAT表。PAT表包含所有PMT表的目录列表,将program_number和PMT表的PID相关联,获取数据的起始…...
wordpress网站首页底部栏显示网站备案信息
一、页脚文件footer.php 例如,wordpress主题使用的是simple-life主题,服务器IP为192.168.68.89,在wordpress主题文件中有个页脚文件footer.php,这是一个包含网站页脚代码的文件。 footer.php 路径如下: /www/wwwroot/192.168.68…...
SOLIDWORKS英文,怎么修改成中文
SOLIDWORKS英文,怎么修改成中文 打开控制面板里的程序 选择程序与功能 找到SOLIDWORKS,选择并点击上方 “更改” 在跳出来的更改页面,选择“简体中文” 点击SOLIDWORKS界面上小齿轮,进入设置 取消勾选English两个相关设置 重启SO…...
简单搭建qiankun的主应用和子应用并且用Docker进行服务器部署
在node18环境下,用react18创建qiankun主应用和两个子应用,react路由用V6版本,都在/main路由下访问子应用,用Dockerfile部署到腾讯云CentOS7.6服务器的8000端口进行访问,且在部署过程中进行nginx配置以进行合理的路由访…...
等保三级安全架构设计方案
一、概述 等保三级,全称为“信息系统安全等级保护三级”,是根据信息安全保护的需求,将系统的安全保护划分为五个等级中的第三级,主要针对相对重要的信息系统进行保护。根据《信息系统安全等级保护基本要求》(GB/T 222…...
【Stable Diffusion】安装教程
目录 一、python 安装教程 二、windows cuda安装教程 三、Stable Diffusion下载 四、Stable Diffusion部署(重点) 一、python 安装教程 (1)第一步下载 打开python下载页面,找到python3.10.9,点击右边…...
05—如何设计和仿真阻抗匹配网络
如何设计和仿真阻抗匹配网络 1. 介绍 在设计电路时,大部分同学只是想把布局布置的更专业,可能没有考虑串扰、电源完整性或阻抗匹配等问题。当了解天线和其他射频设备的匹配网络后,才会意识到阻抗匹配在高速和高频电路中的重要性。 但是,什么时候应该使用阻抗匹配网络?哪…...
Trimble X12助力电力管廊数据采集,为机器人巡视系统提供精准导航支持
地下电缆是一个城市重要的基础设施,它不仅具有规模大、范围广、空间分布复杂等特点,更重要的是它还承担着信息传输、能源输送等与人们生活息息相关的重要功能,也是一个城市赖以生存和发展的物质基础。 01、项目概述 本次项目是对某区域2公里左…...
新质驱动·科东软件受邀出席2024智能网联+低空经济暨第二届湾区汽车T9+N闭门会议
为推进广东省加快发展新质生产力,贯彻落实“百县千镇万村高质量发展工程”,推动韶关市新丰县智能网联新能源汽车、低空经济与数字技术的创新与发展,充分发挥湾区汽车产业链头部企业的带动作用。韶关市指导、珠三角湾区智能网联新能源汽车产业…...
UE5_建立自己的资产库
资产库需要用到一个插件: UAsset Browser - 直接在当前项目预览其他UE项目资产(.uasset 文件) - 直接迁移其他UE项目资产到当前项目 - 不用另外打开资产项目查看资产,迁移资产(麻烦) 插件官网插件文档插…...
Matlab搜索路径添加不上
发现无论是右键文件夹添加到路径,还是在“设置路径”中专门添加,我的路径始终添加不上,导致代码运行始终报错,后来将路径中的“”加号去掉后,就添加成功了,经过测试,路径中含有中文也可以添加成…...
跨UI发送信号
如何自定义信号 1.使用signals声明 2.返回值是void 3.在需要发送的地方使用 emit 信号名字(参数); 进行发送 4.在需要链接的地方使用connect进行链4 接 signals:void sig_addOne(int value); connect(&dlg,&SetDialog::sig_addOne,[](int value){ui->lineEdit…...
宠物领养平台构建:SpringBoot技术路线图
摘 要 如今社会上各行各业,都在用属于自己专用的软件来进行工作,互联网发展到这个时候,人们已经发现离不开了互联网。互联网的发展,离不开一些新的技术,而新技术的产生往往是为了解决现有问题而产生的。针对于宠物领养…...
uniapp App端在renderjs层渲染echarts获取不到service层id的问题
报错信息:Cannot read properties of undefined (reading id) at app-view.js 这样的写法App端有时在renderjs视图层获取不到server逻辑层的数据 server层 renderjs层 解决方法:需要把数据(id)通过server层向renderjs层传值 server层 renderjs层...