《系统架构设计》-07-面向领域的技术设计

news2024/11/15 1:43:21

文章目录

  • 1 实体与值对象
    • 1.1 实体对象
      • 1.1.1 唯一标识(Identity)
      • 1.1.2 可变性
        • 贫血模型
        • 充血模型
    • 1.2 值对象
    • 1.3 示例(识别实体和值对象)
      • 1)识别实体对象
      • 2)提取值对象
      • 3)挖掘实体的关键行为
      • 4)识别其他值对象
      • 5)识别结果
    • 1.4 总结实体和值对象的区别
  • 2. 领域服务
    • 2.1 概念
    • 2.2 示例(提取领域服务)
  • 3. 领域事件
    • 3.1 概述
    • 3.2 领域事件生命周期
      • 3.2.1 简单订阅者
      • 3.2.2 即时转发订阅者
      • 3.2.3 事件存储订阅者
    • 3.3 领域事件建模
      • 3.3.1 概述
      • 3.3.2 示例
        • 1) 事件的发布与订阅
        • 2) 时序图
        • 3)时序图(包含存储)
  • 4 聚合(Aggregate)
    • 4.1 聚合
      • 4.1.1 概述
      • 4.1.2 示例
      • 4.1.3 聚合和领域服务
    • 4.2 聚合建模
      • 4.2.1 有缺陷的思路
      • 4.2.2 聚合建模的原则
        • 1)聚合内部真正的不变条件
        • 2)设计小聚合
        • 3)通过唯一标识引用其他聚合
      • 4.2.3 正确的建模思路
  • 5. 资源库(Repository)
  • 6 集成界限上下文
    • 6.1 4种主流的集成模式
    • 6.2 上下文集成实现
      • 6.2.1 概述
      • 6.2.2 防腐层示例
      • 6.2.3 消息传递模式
      • 6.2.4 Core+Discussion上下文集成时序图
  • 7. 应用程序
    • 7.1 用户界面
    • 7.2 应用服务
      • 7.2.1 应用服务的定位
      • 7.2.2 应用服务和领域服务的区别
    • 7.3 3.基础设施
  • 8 案例技术设计
    • 8.1 上下文领域模型
      • 8.1.1 Core核心域
      • 8.1.2 Discussion支撑域
      • 8.1.3 UserCenter通用域
    • 8.2 上下文集成

1 实体与值对象

1.1 实体对象

在面向对象开发过程中,任何事物都是对象。在领域驱动设计中,我们关注的是实体(Entity)对象而非数据本身。

实体应该具有两个基本特征:唯一标识和可变性。

1.1.1 唯一标识(Identity)

通用的策略:

  • 用户提供初始唯一值

处理方式依赖于用户通过界面输入,系统根据用户输入判断是否重复,如果重复则不允许创建实体。

  • 系统内部自动生成唯一标识

该方法被广泛应用于各种需要生成唯一标识的场景。常见的是根据时间、IP、对象标识、随机数、加密等多种手段混合生成。

  • 系统依赖持久化存储生成唯一标识
    • 延时标识
    • 尽早标识

延时标识示例:

延迟标识可以使用数据库中类似自增主键的功能

在这里插入图片描述

当我们构建Project实体对象时,该对象并不具备唯一性标识,该唯一性标识需要进行持久化之后才能获取。

尽早标识示例:

当实体对象生成的同时,该对象就已具备唯一性标识

在这里插入图片描述

  • 来自另一个上下文。

该种方式尽管可行,但从实现复杂度上讲我们也不推荐。

1.1.2 可变性

贫血模型

在这里插入图片描述

  • 优点
    层次结构清楚,各层之间单向依赖,领域对象几乎只作传输介质之用,不会影响到层次的划分。
  • 缺点
    领域对象只是作为保存状态或者传递状态使用并不包含任何业务逻辑,只有数据没有行为的对象不是真正的领域对象,在应用层里面处理所有的业务逻辑,对于细粒度的逻辑处理,通过增加一层Facade达到门面包装的效果,应用层比较庞大,边界不易控制,内部的各个模块之间的依赖关系不易管理。这些都与面向领域驱动设计中子域和界限上下文的划分及集成思想相违背,所以我们推荐的是充血模型。

充血模型

充血模型更加适合较复杂业务逻辑的设计开发

在这里插入图片描述

  • 优点
    • 面向对象,应用层符合单一职责。(不像在贫血模型里面那样包含所有的业务逻辑而显得太过沉重。)
    • 每一个领域模型对象一般都会具备自己的基础业务方法,满足充血模型的特征。
  • 难点
    如何划分业务逻辑。即如何把业务逻辑正确放在领域层和应用层中比较困难。

1.2 值对象

  • 值对象特征:具备根据明确的约束条件,包括值对象是不变对象、值对象没有唯一标识、值对象具有较低的复杂性。

当我们把实体对象提取完毕,就需要进一步梳理实体中是否包含了潜在的值对象。

  • 值对象提取:如下,我么可以认为是一个值对象:

    • 一个对象满足自身是度量或描述领域中的一个部分
    • 可以作为不变量
    • 将不同的相关属性组合成一个概念整体
    • 当度量或描述改变时可以用另一个值对象予以替换
    • 可以和其他值对象进行相等性比较
    • 不会对协作对象造成副作用等条件时
  • 提取示例
    在这里插入图片描述

我们发现:Customer对象中包含了客户的Address信息,而Address就是一个值对象,因为Address将Street、City、State等相关属性组合成一个概念整体;Address也可以作为不变量,当该Address改变时,可以用另一个Address值对象予以替换。

1.3 示例(识别实体和值对象)

说明:以UserCenter为例

1)识别实体对象

UserCenter上下文对User的通用语言包括:

  • 必须对系统中的User进行认证
  • User可以处理自己的个人信息,包含姓名、联系方式等
  • User的安全密码等个人信息能被本人修改

如上可判断:User是一个实体对象而不是值对象

2)提取值对象

  • User应该包含一个唯一标识 ===>
  • User实体的唯一标识UserId可能只是一个数据库主键值或一个复杂的数据结构 ===>
  • 我们将UserId提取成一个值对象。

在这里插入图片描述

3)挖掘实体的关键行为

考虑到用户可能离职等原因,User可以处于激活或锁定状态,对应的User实体应用具备激活(active)或锁定(deactive)相关的行为。
在这里插入图片描述

4)识别其他值对象

  • User可以修改密码、姓名、联系方式等个人信息 ===》
  • 我们可以从User中提取出Person的概念

User实体中提取姓名、联系方式等信息,实际上构成了一个 Person 的概念,它是User的一部分。

  • 虽然Person是一个实体,但联系方式(Contact Info)等信息倾向于分离成值对象

在这里插入图片描述

5)识别结果

通过以上分析我们得出:

  • User和Person代表两个实体
  • User中包含Person实现和UserId值对象
  • Person中包含PersonId、Name和ContactInfo值对象

1.4 总结实体和值对象的区别

  • 从标识的角度
    • 实体有唯一标识
    • 值对象没有唯一标识(不存在这个值对象或那个值对象的说法)
  • 是否只读的角度
    • 实体是可变的
    • 值对象是只读的
  • 从生命周期的角度
    • 实体具有生命周期
    • 值对象无生命周期可言(需要依附于某个具体实体)

2. 领域服务

2.1 概念

  • 领域服务
    当领域中某个重要的过程或转换操作不属于实体或值对象的职责时,应该在模型中添加一个作为独立接口的操作,即领域服务。

  • 与实体和值对象的区别
    其执行的是一个显著的业务操作过程,并以多个领域对象作为输入进行计算,其结果往往产生一个值对象供应用层使用

示例:银行资金转账场景
考虑现实中银行资金转账场景,用户通过ATM(Automatic Teller Machine,自动取款机)输入银行账户和转账金额等转账相关基本信息,银行执行转账操作并发送手机短信。从架构分层上,应用层获取来自用户接口层的输入,发送消息给领域层并监听确认消息,根据操作结果决定是否使用基础设施层服务发送通知。如果需要发送通知,则基础设施层按照应用程序的指示发送手机短信。关键在于领域层需要执行资金转账操作。该服务需要与Account和Money等对象进行交互,执行相应地借入和贷出操作,并提供结果的确认。领域层中涉及多个领域对象协作的资金转账领域服务即是典型的领域服务。

2.2 示例(提取领域服务)

需求:UserCenter上下文中的User实体的一个需求是必须对用户密码进行加密,并且不能使用明文密码。

  • 方案一(客户端加密)【不推荐】
    • 操作:客户端处理密码的加密,然后将加密后的密码传给User
    • 弊端:
      • 客户端承载太多细节
      • 不符合基本的安全设计原则
  • 方案二(User内部加密)【不推荐】
    • 操作:User内部使用加密算法进行加密
    • 弊端:不符合单一原则(User对象只是代表一个用户信息,并不需要也不应该知道太多加密信息)
  • 方案三 (提取领域服务)【推荐】
    • 操作:将加密操作提取成领域服务,通过独立接口的方式暴露给领域对象使用

例如,我们可以抽象一个EncrytionService,然后采用MD5或其他加密算法实现该接口即可。

3. 领域事件

3.1 概述

  • 领域事件:把领域中所发生的活动建模成一系列离散事件。

领域事件也是一种领域对象,是领域模型的组成部分。

  • 领域事件生命周期
    • 产生
    • 存储
    • 分发
    • 使用

3.2 领域事件生命周期

在这里插入图片描述

领域事件框架围绕领域事件生命周期给出了3种不同的处理方式,
3种事件订阅者可以进行组合形成对事件存储、分发和使用的完整处理过程。

3.2.1 简单订阅者

简单订阅者直接处理事件,表现为一个独立的事件处理程序,对应于事件的使用阶段。

3.2.2 即时转发订阅者

  • 对应于事件的分发和使用阶段
  • 作用:
    • 具备简单订阅者的功能
    • 可以把事件转为给其他订阅者
      把事件转发到消息队列,以满足远程订阅者的需求

3.2.3 事件存储订阅者

  • 对应于事件的存储和使用阶段
  • 作用:
    • 在处理事件的同时对事件进行持久化(如历史记录)
    • 通过专门的事件转发器转发到消息队列

3.3 领域事件建模

3.3.1 概述

  • 作用:
    事件的识别有时候具有一定的隐秘性,当一个实体依赖于另外一个实体,但两者之间并不希望产生强耦合而又需要保证两者之间的一致性时,我们通常就可以提取事件。

示例:我们可以根据通用语言识别Discussion实体。而为了避免Disscussin上下文和Core上下文之间产生强耦合,当一个Discussion结束时,该上下文需更新项目的评估,并通知相关兴趣方。这个过程中我们就可以提取DiscussionClosed事件。

  • 领域事件命名:一般使用过去时对事件进行命名(如上述的DiscussionClosed事件)
  • 领域事件内容
    • 唯一标识
    • 产生时间
    • 事件来源
    • 其他元数据、业务数据
  • 领域事件特性
    • 严格意义上的不变性(因为事件代表的是一种瞬时状态。)
  • 对领域事件的处理:发布-订阅风格。

3.3.2 示例

1) 事件的发布与订阅

DomainEventPublisher和DomainEventSubscriber分别代表发布者和订阅者,DomainEvent本身具备一定的类型,DomainEventSubscriber根据类型订阅某种特定的DomainEvent

在这里插入图片描述

2) 时序图

发布订阅风格中涉及的领域对象及交互时序图

在这里插入图片描述

  • 应用层Application Service对某个实体对象进行操作会触发领域事件的生成
  • 领域事件通过Domain Event Publisher进行发布
  • DomainEventSubscriber则根据需要由Application Service创建并根据事件类型进行订阅和处理。

3)时序图(包含存储)

包含事件存储的发布订阅时序图

在这里插入图片描述

领域事件既可以由本地界限上下文消费,也可以由远程的界限上下文消费。远程界限上下文发布领域事件需要考虑消息的最终一致性、同步和异步及领域事件存储等问题。尤其针对远程交互本身存在的网络稳定性等各种不可控原因,一般都会对事件进行存储以便发生问题时进行跟踪和重试。支持不同事件类型、支持领域事件和存储事件之间的转换、检索由领域模型所产生的所有结果的历史记录、使用事件存储中的数据进行业务预测和分析是常见的事件存储需求。事件可以通过Domain Event Publisher进行集中式的存储,也可以分别保存在各个Domain Event Subscriber中。通过Domain Event Subscriber构建Event Store进行事件存储。

4 聚合(Aggregate)

4.1 聚合

4.1.1 概述

  • 聚合:一组相关对象的组合,是数据修改的最小单元。

    也就是意味着对对象组合的修改只能通过聚合中的根实体进行,而不是对于组合中的所有实体都能进行直接修改。

  • 聚合的核心思想:将关联减至最少,有助于简化对象之间的遍历,使用一个抽象来封装模型中的引用。

  • 聚合的组成

    • 根(Root)实体,是聚合中的某一个特定实体
    • 描述一个边界,定义聚合内部都有什么
  • 聚合固定规则

    • 根实体具有全局标识
    • 外部系统只能看到根实体
    • 只有根实体才能直接通过数据进行查询获取,其他对象必须通过聚合内部关联的遍历才能找到
    • 删除操作必须一次删除聚合之内的所有对象

4.1.2 示例

  • 没有采用聚合概念的对象遍历图(图左半部分)
    • 任何对象都能两两进行交互,所以对象都处于同一个边界中
  • 采用聚合概念的对象遍历图(图右半部分)
    • 通过聚合思想把系统划分成3个边界
    • 每个边界里面包含一个聚合
    • 与外部边界直接关联的就是聚合中的根对象
    • 只有根对象之间才能进行直接交互,其他对象只能与该聚合中的根对象进行直接交互
    • 通过聚合可以把最多28-1次对象直接交互减少的23-1次

在这里插入图片描述

4.1.3 聚合和领域服务

回顾领域服务,使用领域服务实际上就是执行跨聚合的操作,领域服务的输入对象即是各个聚合的根实体对象。

4.2 聚合建模

4.2.1 有缺陷的思路

  • 思路一(基于聚合的建模)
    • 把Project、Task、Plan归为实体对象
    • 把Project上升到聚合的根对象

即:外部系统只能通过Project对象访问Plan和Task对象,而Project中包含着对Plan和Task的直接引用。

在这里插入图片描述

  • 思路二(划分为三个聚合)
    • Project、Plan、Task划分为3个不同的聚合。
    • 把Project的唯一标识提取成一个值对象Project Id
    • Project通过Project Id与Plan和Task对象进行关联

在这里插入图片描述

4.2.2 聚合建模的原则

1)聚合内部真正的不变条件

  • 原则
    业务规则应该总是保持一致,即在一个事务中只修改一个聚合实例

    如果一个事务内需要修改的所有内容处于不同聚合中,我们就要重新考虑聚合划分的有效性。聚合内部保持强一致性的同时,聚合之间需要保持最终一致性。

  • 示例
    思路二中,Project和Plan的更新处于同一个事务中(即,更新Project的同时也应该同时更新Plan),所以把Plan放到以Project为根实体的聚合中更加符合聚合建模的这一条原则。

2)设计小聚合

  • 原则
    倾向于使用小聚合

  • 原因诠释

    • 从性能角度讲
      聚合内部复杂的对象管理和深层次的对象遍历会降低系统的性能
    • 扩展性
      • 系统的变化对于大粒度聚合的影响显然大于小聚合
      • 考虑到实体具备生命周期和状态变化,聚合建模也推荐优先使用值对象以降低聚合内部复杂性。

3)通过唯一标识引用其他聚合

  • 原则:
    • 通过标识而非对象引用使多个聚合协同工作
    • 聚合中的根实体应该具备唯一标识
  • 示例
    思路二中引入值对象Project Id作为Project的唯一标识,并通过该值对象与其他聚合中的根实体进行交互就是这条原则的具体体现。如果Task业务作为一个根实体的话,一般也会提取一个值对象Task Id作为其唯一标识。

4.2.3 正确的建模思路

综合运用3条聚合建模的原则之后,我们可以得到聚合建模思路三,这是我们对上述场景进行聚合建模的最终结果。

在这里插入图片描述

5. 资源库(Repository)

  • 资源库
    在领域驱动设计中,资源库实际上就是对象的提供方,能够实现对象的持久化

  • 资源库的实现过程中有几个注意点:

    • 每一个聚合类型对应一个资源库(因为对聚合的操作需要维持在一个事务中)。
    • 获取聚合时,我们从聚合根实体开始导航对象以控制聚合界限。
    • 充血模型对数据对象的要求:防止数据驱动、避免实体和值对象成为单纯的数据容器是。
    • 通过资源库屏蔽数据访问的技术复杂性
  • 领域驱动设计中引入资源库模式的目的:

    • 为客户提供一个简单模型,可以获取持久化对象
    • 使应用程序和领域设计与持久化技术解耦,体现有关对象访问的设计决策

在这里插入图片描述

  • 资源库可以分成两个部分:
    • 资源库的定义
      • 表现为一个抽象接口
      • 位于领域层
    • 资源库的实现
      • 依赖于具体的持久化媒介
      • 位于基础设施层

6 集成界限上下文

6.1 4种主流的集成模式

在这里插入图片描述

  • 包括文件传输(File Transfer)
    • 缺点:在于如何进行文件的更新和同步
  • 共享数据库(Shared Database)
    • 缺点:在于如何确保数据库模式统一
  • 远程过程调用(RPC):
    • 缺点:容易产生瓶颈节点
  • 而消息传递
    • 缺点:提供松耦合的同时也加大了系统的复杂性

6.2 上下文集成实现

6.2.1 概述

  • 在面向领域的策略设计中,我们提到上下文集成的基本模式有两种:
    • 防腐层
    • 统一协议
      • 统一协议模式(为系统所提供的服务)定义一套(包含标准化数据结构在内的)协议
      • 开发该协议以使其他需要集成的系统能够使用,同时在有新的集成需求时对协议进行改进和扩展
  • HTTP方法及所代表的资源就是一种统一协议
    • RESTful风格的集成实现机制如下表:
URLHTTP方法描述
http://www.liubei.com/usersGET获取User对象列表
http://www.liubei.com/usersPUT更新一组User对象
http://www.liubei.com/usersPOST新增一组User对象
http://www.liubei.com/usersDELETE删除所有User对象
http://www.liubei.com/users/guanyuGET根据用户名guanyu获取User对象列表
http://www.liubei.com/users/guanyuPUT根据用户名guanyu更新User对象
http://www.liubei.com/users/guanyuPOST添加用户名为guanyu的User对象
http://www.liubei.com/users/guanyuDELETE根据用户名guanyu删除User对象

6.2.2 防腐层示例

  • 前提条件:
    在案例的UserCenter上下文中,参加Discussion的用户需要通过UserCenter进行用户身份验证。这个过程就涉及二者的上下文之间的集成
  • 集成方案
    • 在UserCenter上下文中提供基于RESTful风格的UserResource
    • Discussion上下文通过基本的HTTP请求就可以访问该UserResource以实现用户身份认证
    • 两个上下文之间添加了一层包含UserAdapter和UserTranslator组件的防腐层(降低系统耦合)

案例防腐层示例

6.2.3 消息传递模式

  • 发布/订阅模式
  • 点对点模式
    在这里插入图片描述

6.2.4 Core+Discussion上下文集成时序图

  • 需求:

Core上下文创建Project,而项目的时间计划由Discussion上下文计算得出

  • 时序图
    在这里插入图片描述
  • 时序图说明:
    • Core上下文可以通过创建ProjectCreated领域事件并通过消息传递系统进行发布。
    • Discussion上下文订阅并处理该事件
    • Discussion将项目的时间计划通过DiscussionFinished事件反向发送给Core上下文处理

7. 应用程序

7.1 用户界面

  • 用户界面并不是领域驱动设计的重点

  • 需要明确的问题

    • 如何将领域对象渲染到用户界面中
    • 如何将用户操作反映到领域模型上
  • 用户界面与领域模型解耦模式

    1. 数据传输对象(DTO)模式
      • 业务对象(Business Object)为传输对象填充数据的业务服务,相当于领域对象
      • 传输对象(Transfer Object)也被称为数值对象,只有设置和获取属性的方法
      • 客户端(Client)则可以发送请求或者发送传输对象到业务对象
    2. 门面(Façade)模式
      • 为子系统中的一组接口提供一个一致的界面,使得子系统更加易用
      • 实现上用户界面不与系统耦合,而外观类与系统耦合
      • 在层次化结构中,可以使用Façade模式定义系统中每一层的入口

在这里插入图片描述
在领域驱动设计中,我们使用应用服务实现类似DTO和Façade的功能。

7.2 应用服务

7.2.1 应用服务的定位

  • 是领域模型的直接客户
  • 负责业务流程的协调
  • 控制事务使用资源库并解耦服务输出

在这里插入图片描述

7.2.2 应用服务和领域服务的区别

应用服务通常不包含业务,表现为类似Façade的很薄的一个层次。

7.3 3.基础设施

  • 资源库的定义属于领域模型的一部分
  • 基础设施的一大功能就是提供各种资源库的实现
  • 应用服务依赖于领域模型中的资源库定义,并使用基础设施中提供的资源库实现。
  • 使用依赖注入完成资源库实现在应用服务中的动态注入
    在这里插入图片描述

8 案例技术设计

8.1 上下文领域模型

8.1.1 Core核心域

  • 其通用语言:

    • 一个项目具有优先级
    • 一个项目具有很多Task
    • 项目的任务就是完成任务的分解及项目的计划
  • 其上下文对应的领域模型如图
    在这里插入图片描述

Project和Task两个聚合根实体是Core核心域中的主要领域模型,围绕着项目的创建、任务的分解和状态更新以及最终计划的制定系统生成相应的领域事件,而应用服务和资源库都与两个聚合采用通用的命名结构

8.1.2 Discussion支撑域

  • 其通用语言包括

    • 通过Discussion中的会议得出Plan
    • 参加Discussion的成员必须是系统的合法成员
  • 该上下文对应的领域模型如图
    在这里插入图片描述

该支撑域中的主要实体就是Discussion,同时作为集成上下文中UserCenter的上游,Discussion支撑域采用防腐层策略进行集成解耦。

8.1.3 UserCenter通用域

  • 其通用语言

    • 提供服务供外部系统进行用户注册和认证
    • 支持修改用户的联系方式、密码等基本信息
  • 该上下文对应的领域模型如图
    在这里插入图片描述

UserCenter通用域涉及User聚合根、Person实体及一系列表述实体属性的值对象。User的注册、修改密码和联系方式等操作都被抽象成领域事件,而User的验证、密码的修改因为涉及多个对象的交互被单独提取成领域服务。作为Discussion支撑域的下游,UserCenter通用域采用统一协议策略暴露User验证的入口

8.2 上下文集成

  • 使用统一协议和防腐层集成模式实现3个上下文之间的集成
    • 左半部分代表集成模式
    • 右半部分是集成模式所对应的实现方案
      在这里插入图片描述

采用上述集成模式和实现手段之后,3个上下文之间交互的时序图:
在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

solidworks2022 - feature works 变灰的解决方法

文章目录 solidworks2022 - feature works 变灰的解决方法概述实验feature works 变灰问题的重现备注END solidworks2022 - feature works 变灰的解决方法 概述 feature works 用于step文件转零件. 一般是不同版本的solidworks交换文件的方法. 今天突然发现, 我自己转出的ste…

Spring框架使用总结

Spring框架使用 前言处理事务管理声明式事务:编程式事务: 框架核心常见注解 AOP( 面向切面编程)切面和通知有哪些类型?切面的类型通知类型AOP实现使用场景 IOC(管理所有的JavaBean)依赖注入(DI)…

像素比特行列置乱加密算法安全性分析

比特行列置乱加密 将MN大小的灰度图像每个像素值转换为8bit二进制,得到M8N大小的二值图像。 基于加密秘钥,生成随机序列TM和TN分别对二进制图像的行列进行置乱,生成置乱加密后的图像。 Logistic混沌序列加密: 选择明文攻击过程 …

Node内置模块 【path模块】

文章目录 🌟前言🌟path模块🌟引用模块🌟常用属性🌟path.sep🌟在MacOSX、 Unix、Linux操作系统上:🌟在 Windows 上: 🌟常用方法🌟将路径转换为对象…

【python视图1】networkx操作Graph图

一、说明 数据可视化需要显示种种数据,matplotlib负责曲线类画图,然而类似于图论的操作用什么方法。这里用networkx程序包完成。本文专门介绍这种程序包的用法。 二、生成图(Creating a graph) 2.1 创建一个没有节点和边的空图。…

Linux:centos 7:查看运行级别 控制init运行级别 已安装图形化以后设置开机进入图形化或命令行

0 target 关机状态,使用该级别时将关闭主机 1 rescue.target 单用户模式,不需要密码验证即可登录系统,多用于系统维护 …

HTTP 的工作原理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、简单 HTTP二、HTTP 连接请求 I请求Ⅱ 持久 HTTP并执行 HTTP默认浏览器连接设置总结 前言 在处理 Web 性能监控或优化时,了解 HTTP 协议的基础知…

leetcode每日一题——美团笔试题【3】

第一题: 股票的最大利润 假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?示例 1:输入: [7,1,5,3,6,4] 输出: 5 解释: 在第 2 天(股票价格 1)的时候买入,在…

UWB隧道人员定位技术应用,施工作业安全精准保障

隧道施工的安全不仅关系到工程项目的质量和施工效率,也关系到我国的资金安全、施工人员和人民的生命财产安全。如何有效加强隧道施工的安全管理能力,成为隧道施工企业管理者最关心的问题。国家铁道局在《关于加强铁路隧道工程安全工作的若干意见》中指出…

人力资源软件的六个功能,你知道吗?

企业组织越来越多地转向通过人力资源软件来简化他们的人力资源运作。在疫情开始后,人力资源软件的采用尤其迅猛,因为组织希望无缝地管理他们的远程和混合员工。根据SkyQuest的调查人力资源技术市场预计到2028年将达到356.8亿美元。 如果您正在考虑采用人…

面试题思路分享以及延伸问题探讨三

面试题思路分享以及延伸问题探讨 1.前言2. 环形链表初阶2.1 审题2.2 代码实现以及紧急情况的处理方法2.3 延伸问题2.3.1 为什么slow和fast一定会遇上?2.3.2 走n步会是什么样的情况? 3. 环形链表进阶3.1 审题3.2 代码实现3.3 方法二:相交链表法 4. 复制带随机指针的链表4.1审题…

vue3组件二次封装Ui处理

vue 组件二次封装Ui处理 vue 组件二次封装Ui处理 在Vue开发中,我们常常需要使用UI框架提供的组件。但是UI框架的组件可能并不符合我们的需求,这时候就需要进行二次封装。下面是一些关于Vue组件二次封装Ui处理的技巧: 常规时候咱们使用组件…

深元AI盒子在矿山安全生产中实现皮带跑偏、异物、煤流量、大块煤等识别

摘要:随着技术的发展,矿山安全生产已经从传统的人工监测逐步转向现代化智能化。本文旨在探讨矿山安全生产AI盒子在皮带跑偏、异物、煤流量和大块煤之外的功能,以期进一步提高矿山生产的安全性和效率。 正文: 一、引言 矿山安全生…

【获奖案例巡展】信创先锋之星——中信证券基于国产图数据库构建企业图谱的应用实践

为表彰使用大数据、人工智能等基础软件为企业、行业或世界做出杰出贡献和巨大创新的标杆项目,星环科技自2021年推出了“新科技 星力量” 星环科技科技实践案例评选活动,旨在为各行业提供更多的优秀产品案例,彰显技术改变世界的力量&#xff0…

vue2、vue3实现暗黑模式

1、序言 elementPlus、naive UI这些UI组件里面封装好了暗黑模式,直接使用相关api即可实现暗黑模式切换功能,而elementUI没有封装好,我们可以看看elementPlus、naive UI如何实现暗黑模式,然后在elementUI中模仿,从而实现…

【C++】模板初识

C模板初识 1.泛型编程2.函数模板2.1.函数模板概念2.2.函数模板格式2.3.函数模板使用的原理2.4.函数模板的实例化2.5.模板参数的匹配原则 3.类模板3.1.类模板格式3.2.类模板的实例化 1.泛型编程 在实际编程中,经常会用到交换函数。比如有整型值的交换,浮…

Nacos 鉴权系统源码讲解

目录 1. 介绍 2. Nacos SPI 鉴权机制 3. 后台管理 / HTTP 接口鉴权 4. 客户端 / GRPC 接口鉴权 1. 介绍 鉴权功能默认没有开启,开启后的效果就是 Nacos 的接口需要用户登录并且具有权限才能调用该接口。例如注册实例、发布配置等。 鉴权也就是 我是谁、我能干…

探讨接口测试颗粒度

偶然间在论坛上看到一个帖子,帖子内容如下: 假设现在有一个新增商品的接口,返回的参数中有新增商品的 id(每次返回的 id 都不一样)、success(判断是否成功,0 失败 1 成功) 1. 接口…

代码随想录之对称二叉树

本内容来自代码随想录 使用后序遍历。 class Solution { public:bool traversal(TreeNode* left,TreeNode* right){//处理空节点情况if (left nullptr && right ! nullptr) return false;else if (left ! nullptr && right nullptr) return false;else if …

Python人工智能之混合高斯模型运动目标检测详解分析

搬运工项目,换个平台纪录,之前的广告太多 运动目标检测是计算机视觉领域中的一个重要内容,其检测效果将会对目标跟踪与识别造成一定的影响,本文将介绍用Python来进行混合高斯模型运动目标检测,感兴趣的朋友快来看看吧 …