DDD架构学习

文章目录

  • 领域建模
    • 事件风暴
    • 四色建模法
  • DDD名称解析
    • 领域
    • 子域
    • 核心域
    • 通用域
    • 支撑域
    • 限界上下文
    • 战术设计
    • 实体
    • 值对象
    • 聚合和聚合根
    • 工厂
    • 资源库
    • 领域服务
    • 领域事件
  • DDD代码的分层
  • 名词解析
    • 实体
    • 值对象
    • 聚合根
    • 领域服务
    • 领域事件
  • VO&DTO&DO&PO
  • 博客


领域建模

领域驱动设计的核心在于领域建模,架构师的水平高低在很大程度上也体现在领域建模水平上。

领域建模的主要目的是捕捉业务知识,形成统一语言,沉淀领域模型。好的领域建模就意味着对业务要有深刻的理解,能够洞察问题本质。

建模就是将一个大的需求或者系统,经过一系列方法拆分细化,变成一些小而专的小需求,小服务。

领域驱动的战略设计应该如何分析呢?我们不需要独自去摸索,总结前辈的一些经验即可:

  • 通用语言:它的作用是定义上下文含义,以便限界上下文定义领域边界

  • 事件风暴:由项目团队、领域专家等多人参与,采用头脑风暴的方式进行用户故事分析,找出并建立领域对象

  • 四色建模:按时间发展先后顺序,识别“追溯单据”作用的“时标”概念,直达业务核心数据;它强调可追溯性与执行效率

  • 限界纸笔建模:回到一百年前,在一个我们没有计算机的年代,我们要做业务设计会用什么方法呢?我们可以用纸和笔画表格并写实例,管理核心领域“恰好够用”的数据,增强数据完整性,避免过度设计

  • DCI建模:可能DCI我们听得比较少,其实DCI架构与MVC架构的提出者是同一个人。DCI建模通过角色扮演模型使得领域模型易于理解,通过小类大对象的手法避免上帝类的问题;同时它也能解决贫血模型和充血模型之争,使模块更加高内聚、低耦合;当然,DCI建模也可以与四色建模融合使用

事件风暴

事件风暴就是一个建模的过程,梳理出系统或需求中有哪些事件。

在事件风暴中,主要关注以下几个方面:

  • 事件:某个动作的结果。

  • 属性:事件的输入和输出。

  • 命令:描述某个动作。

  • 实体:执行命令的触发者。

简单理解,即谁(实体)使用什么(输入)做了什么(命令、动作),产生了什么(输出),并影响了什么(事件)。

首先邀请正确的人来一起参加:有问题的人和有答案的人。

第一步:梳理事件(橙色贴纸)

从一个个事件开始(事件是已发生且重要的事情,事件必须是既成事实,且业务关注的事情。),梳理清楚该事件发生前有哪些事件?事件一定会发生吗?事件发生后下一个事件是什么?

假设第一个事件是:专栏已订阅,那么“专栏已订阅”事件发生前前须有“订单已支付”事件。
订单一定可以创建成功吗?不是,贴上“订单创建失败”事件。

经过一系列讨论,得出“专栏已订阅”事件会发生以下事件:

在这里插入图片描述

当大家发现新事件的速度接近停滞的时候,就应进入梳理业务规则的阶段了。

第二步:业务规则(粉色贴纸)

业务规则或者业务逻辑,是业务中最重要的部分,主持人会提出以下问题:

事件是否一定成功?如果不是,那么成功的前提条件是什么?该事件是否会导致其他事件的发生?

例如“订单已创建”事件的业务逻辑:

  • 订单已创建的前提条件是专栏可订阅,同时用户未订阅过该专栏。
  • 订单创建后,会导致发起支付。

第三步:行动者(浅黄色贴纸),命令(蓝色贴纸)、阅读模型(绿色贴纸)和系统(紫色贴纸)

主持人通过问题引导:

  • 是什么触发了事件,是命令还是规则

  • 是谁执行了动作,是人还是系统

  • 做出动作前,用户需要获取到哪些信息

通过类似上面的问题,逐步引导大家找到Actor, Command, Read Model

第四步:热点问题(红色贴纸

业务痛点、瓶颈、模糊点可以用红色贴纸记录,这些问题需要业务带回去讨论确定清楚,不要在事件风暴中尝试解决所有的hotspot。

第五步:故事串讲

邀请一名现场参与成员,按事件发生的时间顺序串讲业务,过程中,听众注意到不一致的地方,提出问题;大家一起讨论,调整相关的事件、逻辑来达成一致。

在这里插入图片描述
第六步:产出架构
通过事件风暴,业务流程和处理逻辑应该已经很清楚了,接下来就由架构师产出对应的架构。可以依据事件风暴产出领域模型、用例图、状态图、活动图、序列图等关键架构交付物。

四色建模法

待学习。。。

DDD名称解析

在DDD中可以分为战略设计战术设计,各自包含的内容如下图所示:

在这里插入图片描述

战略设计指的是对整个领域进行分析和规划(宏观),确定领域中的概念、业务规则和领域边界等基础性问题。在战略设计中,需要对领域进行全面的了解和分析,探究业务的规则和本质,并且需要考虑到领域的未来发展趋势和可能的变化。领域、子域和限界上下文属于战略设计的范畴。

领域

领域(Domain)其实就是一个组织所要做的整个事情,以及这个事情下所包含的一切内容,指在特定的范围或边界内要解决的业务问题域,它的核心思想是将业务问题域逐级细为子域/核心域/通用域/支撑域,降低业务理解和系统实现的复杂度。

这是一个范围概念,而且是面向业务的(注意这里不是面向技术的,更不是面向数据库的持久化的),每个组织都有自己的人员、规则和流程,当你为该组织开发软件的时候,你面对的就是这个组织的领域。

例如,在“智学公司”的“智慧课堂”中,领域就是知识付费领域。

子域

子域是指在一个大的领域中,可以进一步划分出来的独立的业务子领域,它们有着自己的业务概念、规则和流程等。

为了区分重要性的不同,我们又会将子域划分成核心域、通用域以及支撑域。

例如,在“智慧课堂”中,子域可以有订阅域、金融域、专栏域等。

核心域

决定公司和产品核心竞争力的子域就是核心域,它是业务成功的主要因素。核心域直接对业务产生价值。

例如,在“智慧课堂”中,订阅域就是核心域。

通用域

没有太多个性化的诉求,同时被多个子域使用的、具有通用功能的子域就是通用域。通用域间接对业务产生价值。

例如,在“智慧课堂”中,权限域、登录域就是通用域。

支撑域

支撑其他领域业务,具有企业特性,但不具有通用性。支撑域间接对业务产生价值。

例如,在“智慧课堂”中,专栏域、评论域就是支撑域。

限界上下文

限界上下文就是业务边界的划分,这个边界可以是一个子域或者多个子域的集合。如何进行划分,一个行之有效的方法是一个界限上下文必须支持一个完整的业务流程,保证这个业务流程所涉及的领域都在一个限界上下文中。限界上下文是微服务拆分的依据,即每个限界上下文对应一个微服务。

例如,在“智慧课堂”中,可以有一个限界上下文叫“专栏订阅上下文”,它就包含了订单域和订阅域。

战术设计

战术设计则是在战略设计的基础上,对领域中的具体问题进行具体的解决方案设计。战术设计关注的是领域中的具体情境和场景,需要针对具体的问题进行具体的分析和设计,以满足业务需求。实体、值对象、聚合、工厂、资源库、领域服务和领域事件就属于战术设计的范畴。

实体

实体是拥有唯一标识和状态,且具有生命周期的业务对象。实体通常代表着现实世界中的某个概念,实体与领域模型密切相关,它是领域模型中多个属性、操作或者行为的载体。

例如:在“智慧课堂”中,专栏、课程文章、订阅都是实体。

实体的代码形态一般有四种形态:

  • 失血模型:模型仅仅包含数据的定义和getter/setter方法,业务逻辑和应用逻辑都放到服务层中。这种类在Java中叫POJO。
  • 贫血模型:贫血模型中包含了一些业务逻辑,但不包含依赖持久层的业务逻辑。这部分依赖于持久层的业务逻辑将会放到服务层中。
  • 充血模型:充血模型中包含了所有的业务逻辑,包括依赖于持久层的业务逻辑。
  • 胀血模型:胀血模型就是把和业务逻辑不想关的其他应用逻辑(如授权、事务等)都放到领域模型中。

值对象

通过对象属性值来识别的对象,它将多个相关属性组合为一个概念整体。在 DDD 中用来描述领域的特定方面,并且是一个没有标识符的对象,叫作值对象。值对象没有唯一标识,没有生命周期,不可修改,当值对象发生改变时只能替换。

值对象的业务形态:大多数情况下实体具有很多属性,这些属性一般都是平铺,但有的属性进行归类和聚合后能够表达一个业务含义,就将这些属性封装到一起形成值对象,从而方便沟通而无需关注细节,因此可以说值对象就是用来描述实体的特征。当然实体的单一属性也是值对象。

值对象的代码形态:值对象有两种:单一属性的值对象,例如字符串、整型、枚举等;多个属性的值对象,这时候设计成class,包含多个属性,但是没有ID,值对象中可以嵌套值对象。

一本书对象中,书本的颜色,尺寸等描述就是值对象。

聚合和聚合根

聚合是一种更大范围的封装,把一组有相同生命周期、在业务上不可分隔的实体和值对象放在一起考虑,只有根实体可以对外暴露引用,这个根实体就是聚合根,聚合也是一种内聚性的表现。

领域、子域、限界上下文、聚合都是用来表示一个业务范围,那他们的关系是怎样的呢?
领域、子域、限界上下文属于战略设计,而聚合属于战术设计,聚合的范围是小于前三者的,范围大小图如下:

在这里插入图片描述

值得注意的是,一个微服务最小不要小于一个聚合,避免引入分布式事务的复杂度。

一个用户对象,一个地址对象,用户对象内包含地址对象,那么用户对象就是聚合根,关于用户及地址对象内的描述信息就是值对象。

工厂

工厂是一种重要的设计模式;

在DDD中,工厂负责将创建复杂对象和聚合的职责分配给一个单独的对象,该对象本身并不承担领域模型中的职责,但是依然是领域设计的一部分。工厂应该提供一个创建对象的接口,该接口封装了所有创建对象的复杂操作过程,同时,它并不需要客户去引用那个实际被创建的对象。对于聚合来说,我们应该一次性地创建整个聚合,并且确保它的不变条件得到满足。

资源库

资源库(Repository)是一种模式,用于封装数据访问逻辑,提供对数据的持久化和查询。它旨在将数据访问细节与领域模型分离,使领域模型更加独立和可测试。资源库提供了一种统一的接口,使得领域模型可以与不同的数据存储方式(如关系数据库、文档数据库、内存数据库等)进行交互,同时也提供了一些查询操作,以便在领域层中进行数据查询。如果我们使用MyBatis的话,Mapper就是对资源库的一种实现。

例如持久化到数据库,可以实现一个MyBatis的持久化类,存储到磁盘,就可以实现一个刷盘类等等。

领域服务

有些领域中的动作看上去并不属于任何对象。它们代表了领域中的一个重要的行为,不能忽略它们或者简单地把它们合并到某个实体或者值对象中。当这样的行为从领域中被识别出来时,推荐的实践方式是将它声明成一个服务,这个服务就是领域服务。

例如,在“智慧课堂”中,订阅(Subscribe)行为是一个非常重要的领域概念,它涉及到订单创建、支付、增加订阅记录等和多个实体相关联的操作,将该行为放到任何一个实体中都不合适,在这种情况下,将“订阅”识别为领域服务是比较合适的。

领域事件

领域事件是发生在领域中且值得注意的事件。而领域事件通常意味着领域对象状态的改变。领域事件在系统中起到了传递消息、触发其他动作的作用,是解耦领域模型的重要手段之一。我们往往利用消息队列来传递领域事件。

例如,在“智慧课堂”中,当用户订阅了一个专栏后,会产生一个“专栏订阅成功”的领域事件,用户成长域会根据这个领域事件决定增加用户积分。


在DDD中,领域模型是核心。领域模型是一个抽象的概念,它代表着业务领域中的实体、值对象、聚合根、领域服务等。在建模领域模型时,需要从业务需求出发,将领域模型与业务模型相对应,并将它们映射到代码实现中。

领域驱动设计则是将二者有机地结合起来,以统一的领域通用语言(不一定是UML)进行系统建模,进行系统的分析和设计工作,即该领域专业的业务人员(领域专家) 和 软件开发人员通过领域模型进行需求沟通,彼此共享领域知识,确立符合真实业务需求的领域模型。
其本质上就是对面向对象分析过程的一个扩展和延伸。

建模及名词原文-知乎

DDD代码的分层

在这里插入图片描述

  • Interfaces(用户接口层):它主要存放用户接口层与前端交互、展现数据相关的代码。前端应用通过这一层的接口,向应用服务获取展现所需的数据。这一层主要用来处理用户发送的 Restful 请求,解析用户输入的配置文件,并将数据传递给 Application 层。数据的组装、数据传输格式以及 Facade 接口等代码都会放在这一层目录里。

  • Application(应用层):它主要存放应用层服务组合和编排相关的代码。应用服务向下基于微服务内的领域服务或外部微服务的应用服务完成服务的编排和组合,向上为用户接口层提供各种应用数据展现支持服务。应用服务和事件等代码会放在这一层目录里。

  • Domain(领域层):它主要存放领域层核心业务逻辑相关的代码。领域层可以包含多个聚合代码包,它们共同实现领域模型的核心业务逻辑。聚合以及聚合内的实体、方法、领域服务和事件等代码会放在这一层目录里。

  • Infrastructure(基础层):它主要存放基础资源服务相关的代码,为其它各层提供的通用技术能力、三方软件包、数据库服务、配置和基础资源服务的代码都会放在这一层目录里。

箭头表示该层次可以调用的其他层次,领域层不能调用其他领域层,必须通过应用层来调用。

四层架构的作用

  • 用户交互层:web请求,rpc请求,mq消息等外部输入均被视为外部输入的请求,可能修改到内部的业务数据。
  • 业务应用层:与MVC中的service不同的不是,service中存储着大量业务逻辑。但在应用服务的实现中(以功能点为维度),它负责编排、转发、校验等。(在设计和开发时,不要将本该放在领域层的业务逻辑放到应用层中实现。因为庞大的应用层会使领域模型失焦,时间一长你的服务就会演化为传统的三层架构,业务逻辑会变得混乱。)
  • 领域层:或称为模型层,系统的核心,负责表达业务概念,业务状态信息以及业务规则。即包含了该领域(问题域)所有复杂的业务知识抽象和规则定义。该层主要精力要放在领域对象分析上,可以从实体,值对象,聚合(聚合根),领域服务,领域事件,仓储,工厂等方面入手。
  • 基础设施层:主要有2方面内容,一是为领域模型提供持久化机制,当软件需要持久化能力时候才需要进行规划;一是对其他层提供通用的技术支持能力,如消息通信,通用工具,配置等的实现。
分层英文描述
表现层User Interface用户界面层,或者表现层,负责向用户显示解释用户命令
应用层Application Layer定义软件要完成的任务,并且指挥协调领域对象进行不同的操作。该层不包含业务领域知识。
领域层Domain Layer或称为模型层,系统的核心,负责表达业务概念,业务状态信息以及业务规则。即包含了该领域(问题域)所有复杂的业务知识抽象和规则定义。该层主要精力要放在领域对象分析上,可以从实体,值对象,聚合(聚合根),领域服务,领域事件,仓储,工厂等方面入手
基础设施层Infrastructure Layer主要有2方面内容,一是为领域模型提供持久化机制,当软件需要持久化能力时候才需要进行规划;一是对其他层提供通用的技术支持能力,如消息通信,通用工具,配置等的实现;

战术设计下的分层:

类型英文描述
值对象value object无唯一标识的简单对象
实体entity充血的领域模型, 有唯一标识
聚合(聚合根)aggregate实体的聚合,拥有聚合根,可为某一个实体
领域服务service无法归类到某个具体领域模型的行为
领域事件event不常用
仓储repository持久化相关,与基础设施层关联
工厂factory负责复杂对象创建
模块module子模块引入,可以理解为子域划分

代码结构描述
后端Java代码工程为例:

├─com.company.microservice
├─com.company.microservice
│    │ 
│    ├─apis   API接口层/表现层 
│    │    └─controller       控制器,对外提供(Restful)接口
│    │ 
│    ├─application           应用层
│    │    ├─model            数据传输对象模型及其装配器(含校验)
│    │    │    ├─assembler   装配器,,实现模型转换eg. apiModel<=> domainModel
│    │    │    └─dto         模型定义(含校验规则)      
│    │    ├─service          应用服务,非核心服务,跨领域的协作、复杂分页查询等
│    │    ├─task             任务定义,协调领域模型
│    │    ├─listener         事件监听定义
│    │    └─***              others
│    │ 
│    ├─domain   领域层
│    │    ├─common           模块0-公共代码抽取,限于领域层有效  
│    │    ├─module-xxx       模块1-xxx,领域划分的模块,可理解为子域划分     
│    │    ├─module-user      模块2-用户子域(领域划分的模块,可理解为子域划分)
│    │    │    ├─action      行为定义
│    │    │    │    ├─UserDomainService.java        领域服务,用户领域服务
│    │    │    │    ├─UserPermissionChecker.java    其他行为,用户权限检查器
│    │    │    │    ├─WhenUserCreatedEventPublisher.java     领域事件,当用户创建完成时的事件 
│    │    │    ├─model       领域聚合内模型 
│    │    │    │    ├─UserEntity.java                领域实体,有唯一标识的充血模型,如本身的CRUD操作在此处
│    │    │    │    ├─UserDictVObj.java              领域值对象,用户字典kv定义       
│    │    │    |    ├─UserDPO.java                   领域负载对象    
│    │    │    ├─repostiory  领域仓储接口
│    │    │    │    ├─UserRepository.java
│    │    │    ├─reference   领域适配接口
│    │    │    │    ├─UserEmailSenderFacade.java
│    │    │    └─factory     领域工厂  
│    │ 
│    ├─infrastructure  基础设施层
│    │    ├─persistence      持久化机制
│    │    │    ├─converter   持久化模型转换器
│    │    │    ├─po          持久化对象定义 
│    │    │    └─repository.impl  仓储类,持久化接口&实现,可与ORM映射框架结合
│    │    ├─general          通用技术支持,向其他层输出通用服务
│    │    │    ├─config      配置类
│    │    │    ├─toolkit     工具类  
│    │    │    ├─extension   扩展定义  
│    │    │    └─common      基础公共模块等 
│    │    ├─reference        引用层,包装外部接口用,防止穿插到Domain层腐化领域模型等
│    │    │    ├─dto         传输模型定义
│    │    │    ├─converter   传输模型转换器       
│    │    │    └─facade.impl 适配器具体实现,此处的RPC、Http等调用
│    │ 
│    └─resources  
│        ├─statics  静态资源
│        ├─template 系统页面 
│        └─application.yml   全局配置文件

DDD的核心诉求就是将业务架构映射到系统架构上,在响应业务变化调整业务架构时,也随之变化系统架构。而微服务追求业务层面的复用,设计出来的系统架构和业务一致;在技术架构上则系统模块之间充分解耦,可以自由地选择合适的技术架构,去中心化地治理技术和数据。

名词解析

层次概念

代码层次

实体

当一个对象由其标识(而不是属性)区分时,这种对象称为实体(Entity)。
例:最简单的,公安系统的身份信息录入,对于人的模拟,即认为是实体,因为每个人是独一无二的,且其具有唯一标识(如公安系统分发的身份证号码)。

在实践上建议将属性的验证放到实体中。

值对象

当一个对象用于对事务进行描述而没有唯一标识时,它被称作值对象(Value Object)。

例:比如颜色信息,我们只需要知道 {“name”:“黑色”,”css”:“#000000”} 这样的值信息就能够满足要求了,这避免了我们对标识追踪带来的系统复杂性。它具有不变性、相等性和可替换性。

在实践中,需要保证值对象创建后就不能被修改,即不允许外部再修改其属性。在不同上下文集成时,会出现模型概念的公用,如商品模型会存在于电商的各个上下文中。在订单上下文中如果你只关注下单时商品信息快照,那么将商品对象视为值对象是很好的选择。

值对象很重要,在习惯了使用数据库的数据建模后,很容易将所有对象看作实体。使用值对象,可以更好地做系统优化、精简设计。

聚合根

Aggregate(聚合)是一组相关对象的集合,作为一个整体被外界访问,聚合根(Aggregate Root)是这个聚合的根节点。

聚合由根实体,值对象和实体组成。

领域服务

一些重要的领域行为或操作,可以归类为领域服务。它既不是实体,也不是值对象的范畴。

当我们采用了微服务架构风格,一切领域逻辑的对外暴露均需要通过领域服务来进行。如原本由聚合根暴露的业务逻辑也需要依托于领域服务。

领域事件

领域事件是对领域内发生的活动进行的建模。

VO&DTO&DO&PO

每一层都有自己特定的数据,可以做如下区分:

  • VO(View Object):视图对象,主要对应界面显示的数据对象。对于一个WEB页面,或者SWT、SWING的一个界面,用一个VO对象对应整个界面的值。
  • DTO(Data Transfer Object):数据传输对象,主要用于远程调用等需要大量传输对象的地方。比如我们一张表有100个字段,那么对应的PO就有100个属性。但是我们界面上只要显示10个字段,客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,这时我们就可以用只有这10个属性的DTO来传递结果到客户端,这样也不会暴露服务端表结构.到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO。在这里,我泛指用于展示层与服务层之间的数据传输对象。
  • DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。
  • PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。最形象的理解就是一个PO就是数据库中的一条记录,好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。

PO是数据库表结构的一一映射,DO是数据库结构在领域服务层的处理对象。多个DO可以组成一个PO,一个DO不一定包含PO所有值。

前端发送请求(VO) -> 系统接收请求 (VO->DTO) -> 系统各个模块处理请求(DTO->DO) -> 持久化到库 -> (DO->PO)

博客

微信公众号博客

爪哇缪斯

是下雨天啊

VO、DTO、DO、PO的概念

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/602441.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式】——专栏概述

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

智慧校园与学生成长

当时间追溯到2018年&#xff0c;技术的前进已经逾越了人们的幻想&#xff0c;很多先进的设备也投入到了大众的日子中去&#xff0c;为信息化的推进带来了全新的改动。与此同时&#xff0c;校园也不甘落后&#xff0c;将教育与信息化得到一个完美的融合&#xff0c;为学生的未来…

想要买到心仪的旋转式孔板流量计吗?

选择旋转式孔板流量计可不能云里雾里的乱选择呀&#xff0c;煤矿对产品质量要求很严格的。所以我们要先了解产品的再决定才是对的选择。 旋转式孔板流量计技术参数【1--5--9】 规格&#xff1a;DN15&#xff5e;DN1000 孔径比(βd/D)&#xff1a;β0&#xff0e;2—0&#xff…

Web前端三大主流框架是什么?

Web前端开发领域的三大主流框架分别是Angular、React和Vue.js。它们在Web开发领域中占据着重要的地位&#xff0c;各自拥有独特的特点和优势。 Angular Angular是一个由Google开发的前端框架&#xff0c;最初版本称为AngularJS&#xff0c;后来升级为Angular。它是一个完整的…

MySQL迁移data目录

MYSQL数据库有时候安装好了&#xff0c;想移动一下data目录&#xff0c;但是又不想重新安装一下&#xff0c;就只能想办法把这个目录迁移一下。 先找到my.ini配置文件&#xff0c;可以全局搜索一下&#xff0c; 找到之后&#xff0c;把这个地方修改一下&#xff0c;就把data目…

IP协议全解析:网络层通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在数字化时代的浪潮中&#xff0c;网络通信无处不在&#xff0c;它连接着世界的每一个角落&#xff0c;承载着信息的高…

评估Transitions

Stateflow使用图表中的转换从一种OR状态移动到另一种OR状态。对于图表执行的输入和执行工作流,Stateflow评估转换以确定它们是否有效。有效转换是条件标签为true且路径以状态结束的转换。如果转换有效,则Stateflow将从源状态退出并进入目标状态。 评估Transitions的工作流 T…

Java八股文3

3.垃圾回收 1.对象什么时候可以被垃圾器回收 1.垃圾回收的概念 为了让程序员更专注于代码的实现&#xff0c;而不用过多的考虑内存释放的问题&#xff0c;所以&#xff0c; 在Java语言中&#xff0c;有了自动的垃圾回收机制&#xff0c;也就是我们熟悉的GC(Garbage Collection)…

代码随想录算法训练营第四十二天| 01背包问题理论基础,416. 分割等和子集

理论基础&#xff1a; 带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili很多同学对背包问题的理解程度都处于一种黑盒的状态&#xff0c;及时这道题目在力…

WebDAV之π-Disk派盘 + 溯记

“溯记”是一款提供丰富功能的时间轴日记应用,旨在帮助用户记录生活中的碎片化想法和事件,并提供便捷的回顾和管理功能。根据您提供的描述,这款应用具有丰富的特性,包括时间轴浏览、多媒体支持、实时存储、模糊搜索、日历视图、故事关联和随机回溯。这些功能将帮助用户记录…

C++奇迹之旅:string类对象的容量操作

文章目录 &#x1f4dd; string类的常用接口&#x1f309; string类对象的容量操作&#x1f320;size&#x1f320;length&#x1f320;capacity&#x1f320;clear&#x1f320;empty&#x1f320;reserve&#x1f309;resize &#x1f6a9;总结 &#x1f4dd; string类的常用…

vue导出大量数据的表格方法

我目前的项目导出4万7数据没问题 先安装 npm install -S file-saver npm install xlsx0.16.0 -S npm install -D script-loader 我使用的版本是"file-saver": “^2.0.5”, “xlsx”: “^0.16.0” 新建Export2Excel.js //Export2Excel.js /* eslint-disable */ requ…

直播产品实习生实习报告,笔灵AI生成模版分享

实习体验报告&#xff1a;直播产品实习生 如果有不同的岗位需要写的话可以去笔灵生成一下 网址&#xff1a;https://ibiling.cn/scene/inex?fromcsdnsx 一、实习背景我是XXX&#xff0c;作为一名直播产品实习生&#xff0c;我在XX公司进行了为期X个月的实习。在这段时间里&…

bfs之八数码

文章目录 八数码解题思路图解举例算法思路 代码CPP代码Java代码 八数码 在一个 33的网格中&#xff0c;1∼8这 8个数字和一个 x 恰好不重不漏地分布在这 33 的网格中。 例如&#xff1a; 1 2 3 x 4 6 7 5 8在游戏过程中&#xff0c;可以把 x 与其上、下、左、右四个方向之一…

【微机原理及接口技术】8086/8088系统时序和微机总线

【微机原理及接口技术】8086/8088系统时序和微机总线 文章目录 【微机原理及接口技术】8086/8088系统时序和微机总线前言一、8086/8088引脚信号和工作模式1.8088 的两种组态模式2.最小组态的引脚信号3.最小组态的总线形成4.最大组态的总线形成 二、8086/8088典型时序1.三种周期…

【工具】Office/WPS 插件|AI 赋能自动化生成 PPT 插件测评 —— 必优科技 ChatPPT

本文参加百度的有奖征文活动&#xff0c;更主要的也是借此机会去体验一下 AI 生成 PPT 的产品的现状&#xff0c;因此本文是设身处地从用户的角度去体验、使用这个产品&#xff0c;并反馈最真实的建议和意见&#xff0c;除了明确该产品的优点之外&#xff0c;也发现了不少缺陷和…

vue的css深度选择器 deep /deep/

作用及概念 当 <style> 标签有 scoped 属性时&#xff0c;它的 CSS 只作用于当前组件中的元素&#xff0c;父组件的样式将不会渗透到子组件。在vue中是这样描述的&#xff1a; 处于 scoped 样式中的选择器如果想要做更“深度”的选择&#xff0c;也即&#xff1a;影响到子…

2024年数维杯数学建模ABC题思路分析

文章目录 1 赛题思路2 比赛日期和时间3 竞赛信息4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

[GESP样题 三级] 进制转换、春游、密码合规

B3849 [GESP样题 三级] 进制转换 题目 小美刚刚学习了十六进制&#xff0c;她觉得很有趣&#xff0c;想到是不是还有更大的进制呢&#xff1f;在十六进制中&#xff0c;用 A 表示 10、F 表示 15。如果扩展到用 Z 表示 35&#xff0c;岂不是可以表示 36进制数了嘛&#xff01;…

线程理论篇1

本章问题&#xff1a;什么是线程?线程的使用场景&#xff1f;什么是线程池&#xff1f;线程池是如何工作的&#xff1f;线程池共享了哪些资源?线程安全代码怎么写&#xff1f;什么是线程安全? 什么是线程&#xff1f; 线程是为了提高进程的效率。进程的地址空间中保存了cpu…
最新文章