DDD落地:爱奇艺打赏服务,如何DDD架构?

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

谈谈你的DDD落地经验?

谈谈你对DDD的理解?

如何保证RPC代码不会腐烂,升级能力强?

微服务如何拆分?

微服务爆炸,如何解决?

你们的项目,DDD是怎么落地实操的?

所以,这里尼恩给大家做一下系统化、体系化的梳理,使得大家可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”

也一并把这个题目以及参考答案,收入咱们的 《尼恩Java面试宝典PDF》V144版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】取

除了本文,尼恩输出了一个 《从0到1,带大家精通DDD》系列,帮助大家彻底掌握DDD,链接地址是:

《阿里DDD大佬:从0到1,带大家精通DDD》

《阿里大佬:DDD 落地两大步骤,以及Repository核心模式》

《阿里大佬:DDD 领域层,该如何设计?》

《极兔面试:微服务爆炸,如何解决?Uber 是怎么解决2200个微服务爆炸的?》

《阿里大佬:DDD中Interface层、Application层的设计规范》

《字节面试:请说一下DDD的流程,用电商系统为场景》

《DDD如何落地:去哪儿的DDD架构实操之路》

《DDD落地:从腾讯视频DDD重构之路,看DDD极大价值》

《DDD落地:从美团抽奖平台,看DDD在大厂如何落地?》

《美团面试:微服务如何拆分?原则是什么?》

《DDD神药:去哪儿结合DDD,实现架构大调优》

《DDD落地:从网易新闻APP重构,看DDD的巨大价值》

《DDD落地:从阿里单据系统,看DDD在大厂如何落地?》

《DDD落地:有赞的生产项目,DDD如何落地?》

《DDD落地:从携程订单系统重构,看DDD的巨大价值》

《DDD落地:京东的微服务生产项目,DDD如何落地?》

《DDD落地:阿里供应链商品域,DDD如何落地?》

《240Wqps,美团用户中台, 如何使用DDD架构?》

大家可以先看前面的文章,再来看本篇,效果更佳。

另外,尼恩会结合一个工业级DDD实操项目,在第34章视频《DDD的学习圣经》中,给大家彻底介绍一下DDD的实操、COLA 框架、DDD的面试题。

DDD现在非常火爆,是有其巨大生产价值,经济价值的, 绝不仅仅是一套概念那么简单。

DDD的绝大价值,具体请参见以下视频:

从腾讯视频DDD重构案例,看看DDD极大价值

文章目录

    • 尼恩说在前面
    • 爱奇艺打赏业务DDD实践
    • 价值
    • 领域驱动设计是什么
    • DDD打赏业务实践
      • 1、打赏业务简介
      • 2、战略设计
        • 六边形架构
      • 3、战术设计
    • DDD的优势
    • 几个关键问题
    • 结束语
    • 说在最后
    • 技术自由的实现路径 PDF:
        • 实现你的 架构自由:
        • 实现你的 响应式 自由:
        • 实现你的 spring cloud 自由:
        • 实现你的 linux 自由:
        • 实现你的 网络 自由:
        • 实现你的 分布式锁 自由:
        • 实现你的 王者组件 自由:
        • 实现你的 面试题 自由:

爱奇艺打赏业务DDD实践

作者:爱奇艺会员技术团队

领域驱动设计(Domain-Driven Design,以下简称DDD)思潮的形成要追述到30几年前,17年前,Eirc Evans定义了领域驱动设计的概念。

DDD为传统行业的软件工程师提供了一种新的设计方法论,但在互联网领域的应用却相对较少。

然而,随着互联网行业对业务复杂性的应对以及对微服务架构的偏好,DDD再次回到了人们的视线之中。本文将主要探讨如何应对软件复杂性问题。

  • 互联网的行业的业务越来越复杂,面临与传统行业软件相同的问题;
  • 微服务的流行带火了DDD,以解决微服务拆分问题。

本文主要对第一点“解决软件复杂性之道”进行讲解。

价值

详细讲解之前,我们先给出DDD为打赏业务带来的价值

会员业务部门在打赏业务中实践 DDD 后,取得了以下显著成果:

  • 新需求接入开发成本节约20%
  • 更换底层中间件开发成本节约20%
  • 项目熟悉成本节约30%(对DDD有基本了解为前提);
  • 单测开发成本指数级降低
  • 上线风险、成本降低

了解了DDD流行的背景及业务价值后,下面我们对DDD是什么、有哪些优势、项目中如何实践,以及几个关键问题进行叙述。

领域驱动设计是什么

讨论领域驱动设计是什么之前,我们先看下面一段代码:

这是一个打赏接口定义,单看这个接口是没有问题的,用户基于活动,选择明星,选择道具进行打赏。

业务逻辑上没问题,但我们会发现一些代码的坏味道。

  • 代码编译后方法的参数名会丢失。

在编码过程中,如果明星和道具的参数顺序传递错误,代码仍可顺利编译,但只有在运行时才会暴露出业务错误。尽管这种问题的发现成本相对较低,但在编译阶段就能发现并避免这类错误,可以降低问题的排查成本。在上述方法中,参数编码可以唯一标识实体,但失去了实体在业务领域的实际意义,例如为特定明星赠送特定道具。

在打赏业务逻辑中,存在大量与核心业务无关的前置校验逻辑,这会影响代码的可读性。所有逻辑都堆叠在一个方法中,增加了编写测试用例的复杂度。

这些问题出现的根本原因在于对业务领域的划分不够明确,仅仅实现了操作流程,缺乏领域抽象。方法参数定义缺少业务领域含义。实际上,活动校验本质上是活动属性判断,活动是否有效取决于活动自身的属性。可以将活动校验抽象为 ActivityValidate 类,或在实体中增加 validate 方法。更进一步,可以将校验逻辑直接放在活动的构造方法中,既能达到校验目的,又避免漏校验。这样,在编写单元测试时,将大逻辑拆分为多个逻辑单元,可以大大减少用例数量。优化后的代码如下:

针对活动校验,我们可以采用构造函数校验,因此在打赏方法中无需再进行校验。将活动校验放在前置构造函数中,有助于降低测试用例数量。

回到最初的问题,什么是领域驱动设计?

1、领域驱动设计基于领域建模而非数据建模

在上面的例子中,重构前 activity 实体仅具有基本属性和 get/set 方法,即“失血模型”。这导致 activity 作为领域对象退化为数据对象,仅用于 ORM 组件的 CRUD 操作。失血模型在项目代码中随处可见。其原因与对象-关系映射(ORM,如 Hibernate)持久化机制的流行直接相关。使用 ORM 将每个类映射到一张数据表,通过实体对象完成 CRUD 操作,久而久之,实体成为 ORM 框架的专用名词,失去了领域能力。在进行项目设计时,应从业务领域角度出发,而非数据库角度。我们将在战略设计部分详细讨论这一问题。

2、满足六边形架构设计

六边形架构将在后续章节中详细介绍,洋葱架构、干净架构与六边形架构相似。

满足以上两点,并对 DDD 的一些概念进行映射实践,那么你的系统已符合 DDD。总结来说,DDD 并非一套全新的特殊架构,而是项目代码经过重构,满足高可维护性、高可扩展性、高可测试性、代码结构清晰之后必然达到的终点。

领域驱动设计(DDD)是一种软件设计方法,它强调基于领域建模而非数据建模,关注六边形架构设计。通过实践 DDD,我们可以更好地应对业务复杂性,实现软件系统的卓越表现。在实际项目中,根据业务需求和场景,灵活运用 DDD 理念和相关架构,构建高质量、高可维护和易于扩展的软件系统。

DDD打赏业务实践

1、打赏业务简介

  • 观看视频时,选择明星、礼物进行打赏;

  • 打赏后屏幕有气泡提示;

  • 打赏数据在排行榜进行显示;

  • 累计一定的打赏获得某种奖励。

2、战略设计

在谈论战略设计时,我们必须了解几个核心概念:领域、子域、限界上下文和架构分层。

领域:广义上讲,领域代表了组织所从事的业务范围及其涉及的所有内容。每个公司或组织都有其独特的业务领域和运营方式,这个领域即为该公司或组织的业务范围及在其中进行的活动。当你为某个企业开发软件时,你所面对的就是这个企业的领域。对于你来说,这个领域应该是清晰明确的,因为你是在这个领域内开展工作。

对于打赏这种业务,打赏本身便是领域,即打赏领域。无论你的打赏对象是一位主播、一部电影或者一篇博文,又无论你的打赏道具是RMB、虚拟币、火箭等等,打赏都是这个领域的核心。

子域:领域模型可能会让我们认为整个业务系统应该构建一个单一、紧凑、功能齐全的模型。然而,这并不是 DDD 的目标。相反,在 DDD 中,一个领域被划分为多个子领域。这些子领域有助于我们更加关注业务系统的某一特定方面,从而实现领域的有效拆分。

限界上下文:限界上下文是一个具有明确边界的特定职责范围。在这个范围内,领域模型中的每个概念(包括属性和操作)都有其特定的含义。

打赏系统搭建之初,需求比较简单,随着业务的发展,需求不断复杂化,领域拆分及迭代如下:

  • 初期,运营和产品需求简单,只需实现免费打赏功能并在界面展示打赏气泡,因此将整个系统划分为一个领域;

  • 经过一段时间的试水,发现活动效果不错,需求方希望增加支持多场打赏活动。为了实现这个目标,我们需要新增活动支撑子领域;

  • 随着需求的进一步升级,用户在达到一定打赏额度后可以获得奖品。为了实现这个功能,我们引入了奖励子领域;

  • 为了提高用户的参与度,我们增设了排行榜功能,从而引入了排行榜子领域。

最终领域划分如下图:

  • 打赏核心子域:完成打赏操作。

  • 通知子域:实现界面气泡通知能力。

  • 奖励子域:奖励策略匹配,奖励发放。

  • 排行子域:完成排行功能。

  • 活动子域:活动、明星、道具管理。

  • 用户子域:完成用户查询、校验等通用能力。

领域的拆分过程并没有上面描述的那么顺利,经历了很多推翻重来的过程,正是经历了这些过程,我们对领域的理解才能更深入,更符合领域建模。

架构分层:分层架构的一个关键原则是,每层只能与下方层发生聚合。

为了解耦接口定义与实现,我们将接口定义在领域层,实现定义在基础设施层。但这样违反了从顶至底的单项依赖原则。

为了解决这个问题,我们采用依赖倒置原则——高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

根据此原则,结构调整如下

我们将基础设施层置于所有层次结构的顶部,使其能够实现其他层次定义的接口。

在分层架构中遵循依赖倒置原则,可能会发现分层概念实际上已不再存在。无论是高层次还是低层次,它们都仅依赖于抽象。

这样一来,整个分层结构仿佛被推平,客户可以以“平等”的方式与系统交互。当加入新的客户时,它们仅作为不同的输入、输出以及展示形式,这就是我们将要了解的另一种架构——六边形架构。

六边形架构

六边形架构

在我们的代码库中,有许多直接的外部依赖和实现细节,例如 MyBatis 的 Mapper 类、HttpClient 注入、RocketMQ 的监听、缓存的直接操作等。

这种实现方式有两个明显的问题:

  • 一是当底层更换基础组件时,会对业务逻辑产生直接影响,导致代码修改量和测试范围大幅增加;

  • 二是缺乏功能复用性,若其他业务有类似逻辑,无法直接移植和复用。

于 2005 年,Alistair Cockburn 提出了六边形架构,亦称为端口和适配器架构。

从上图可以看出,针对核心的应用程序和领域模型,其他底层依赖或实现都可以抽象为输入和输出两类。

组织关系变成了一个二维的内外关系,而非上下结构。每个 I/O 与应用程序之间都有适配器进行隔离,每个最外围的边都代表一个端口。

基于六边形架构设计的系统是领域驱动设计(DDD)所追求的最终形态。六边形架构的实践将在“DDD 优势”部分进行详细阐述。

先给出基于六边形架构实践后,项目模块结构:

模块说明
Admin-api配置后台相关
api对外用户接口
application应用
domain领域
infrastructure基础设施
query查询模块
task与使用的中间件相关,可忽略
worker处理事件消息模块
common基础包

通过六边形架构,我们可以更有效地实现领域模型的内外分离,降低外部依赖,提高代码的可维护性和复用性。在实际项目中,我们可以根据业务需求和场景,灵活运用六边形架构,将底层实现与领域模型分离,使代码更具灵活性和可扩展性。六边形架构有助于我们实现高质量、高可用的软件系统,满足不断变化的业务需求。

3、战术设计

在战略设计的基础上,领域边界已清晰可见。接下来,我们讨论战术设计,首先对领域驱动设计(DDD)的几个基本概念进行业务映射。

实体:由属性和行为组成,具有唯一标识。

在设计系统时,我们往往侧重于数据而非领域。对于 DDD 开发者来说,这种情况同样存在,因为在软件开发中,数据库仍然占据主导地位。首先考虑的是数据的属性和关联关系,而非具有丰富行为的领域概念。

这种做法的结果是将数据模型直接映射到对象模型上,导致实体仅包含 get/set 方法,这并非 DDD 的风格。

只有get/set实体需配合service使用,内聚性、可维护性,以及复用迁移成本均明显高于DDD的做法。

值对象:没有唯一标识,具有可度量或可描述,并满足不变性的对象。

我们应该尽量使用值对象来建模而不是实体对象,因为相比实体,我们可以非常容易地对值对象进行创建、测试、使用、优化和维护。

对于第一种实现,用户必须了解同时使用 amount 和 currency,并清楚如何运用这两个属性。这是因为这两个属性并未构成一个概念整体。对于 PropName 值对象的定义,可以带来一定的扩展性。例如,如果需要对道具名称进行大小写转换,可以在 PropName 内部实现此操作,而无需将相关逻辑泄漏到 Prop 中。

领域服务

领域服务表示一个无状态的操作,用于实现特定于某个领域的任务。

当某个操作不适合放在聚合和值对象上时,最好的方式便是使用领域服务了。

例如“用户认证”,一种方式是我们可以简单地将认证操作放在实体上。

对于这种设计,存在两个问题。

  • 首先,用户类需要知道某些认证细节,

  • 其次,这种方法也不能显示的表达通用语言。

这里我们询问的是一个User“是否被认证了”,而没有表达出“认证”这个过程。

在有可能的情况下,我们应该尽量使用建模术语直接地表达出交流语言。

领域事件:领域专家所关心的发生在领域中的一些事件。我们通常将领域事件用于维护事件的一致性,这样可以消除两阶段提交(全局事务)。

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

聚合是核心领域的重要概念,它可以用来说明领域内的关系。

此外,聚合在技术上也有很高的价值,可以指导详细设计。聚合由根实体、实体、值对象组成。

工厂:工厂提供一个创建对象的接口,封装了所有创建对象的复杂操作过程。

同时,客户无需直接引用实际被创建的对象。

在实际应用中,我们可以根据业务需求和场景,灵活运用工厂模式。工厂模式可以简化对象创建的过程,提高代码的可维护性和可扩展性。通过封装创建对象的复杂操作,工厂模式还可以降低代码之间的耦合度,便于后续的优化和扩展。在项目中,我们可以根据实际需求,定义不同的工厂类来创建相应的对象,从而实现对象的灵活创建和管理。

DDD的优势

应用DDD的系统符合六边形架构,我们实现了以下目标

  • 独立于框架:架构不应该依赖某个外部的库或者框架,不应该被框架的结构所束缚;

  • 独立于UI:前台展示的样式可能会随时发生变化,但是底层架构不应该随之而变化;

  • 独立于底层数据源:软件架构不应该因为不同的底层数据存储而产生巨大改变;

  • 独立于外部依赖:无论外部依赖如何变更、升级,业务的核心逻辑不应随之而大幅变化。

为实现以上目标,六边形架构(如洋葱架构、干净架构等)是个合适的选择。接下来,结合打赏具体业务实现,讲解如何实现这些目标。

先给出项目某个模块的代码包结构:

资源库:将资源库作为业务与数据的隔离层,屏蔽底层数据表细节,同时完成 PO 与 DO 的转化。DO 与 PO 的转化有利于领域层不直接依赖底层实现,便于后续更换底层实现或功能迁移。资源库接口定义在领域层,接口实现在基础设施层。

RPC:RPC 部分的结构拆分与资源库类似,区别在于存在领域服务。接口定义放在领域层,具体实现在基础设施层。

在遵循六边形架构的大原则下,其他边的拆分也变得清晰简单了,此处不再赘述。

通过以上实践,我们可以看到 DDD 在实际应用中的优势:

  • 灵活性:基于领域驱动设计的系统具有较高的灵活性,可以轻松应对业务变化和需求变更。
  • 可维护性:领域驱动设计将业务逻辑与技术实现分离,使得代码更具可读性和可维护性。
  • 复用性:通过领域服务、聚合等概念,实现业务逻辑的复用,降低开发成本。
  • 扩展性:领域驱动设计有助于提高系统的扩展性,方便引入新功能和模块。
  • 降低耦合度:通过六边形架构,将业务层与底层技术层分离,降低系统耦合度,便于后续迭代和升级。

总之,应用 DDD 可以让我们更好地应对复杂多变的业务挑战,实现软件开发的卓越表现。在实际项目中,我们可以根据业务需求和场景,灵活运用 DDD 理念和相关架构,构建高质量、高可维护和易于扩展的软件系统。

几个关键问题

1、事务

在上文中“聚合”章节,我们讨论了事务,即在一次事务中只操作一个聚合实例。如果发现一次事务内的逻辑过多,可以考虑将部分逻辑剥离为独立的聚合,采用最终一致性。基于这个基础,应用层是最适合声明事务的层次。

2、查询

CQRS(命令查询职责分离)在 DDD 中是一种常见的模式。它将领域模型与查询功能分离,让复杂的查询摆脱领域模型的限制,以更简单的 DTO 形式展现查询结果。同时,CQRS 还分离了不同的数据存储结构,让开发者可以根据查询功能和需求更自由地选择数据存储引擎。具体实践可参考相关资料。

3、框架无关

六边形架构设计已实现与底层实现、框架、中间件无关。但还有一个较大的框架依赖,即 Spring。我们的解决方案是,在领域内使用的 Spring Bean 通过传参方式实现领域层与框架的解耦。

4、成本

在实践 DDD 时,成本是一个重要考虑因素,包括学习成本、改造成本、兼容成本等。在实际操作前,建议先评估好成本。

结束语

领域驱动设计(DDD)并非一套全新的特殊架构,而是一种应对软件复杂性的方法论。它基于面向领域建模,六边形架构,以及经过重构的项目代码,旨在实现高可维护性、高可扩展性、高可测试性和代码结构清晰。遵循这一方法,我们将能够更好地应对复杂多变的业务挑战,实现软件开发的卓越表现。

说在最后

DDD架构如何落地,是非常常见的面试题。

以上的内容,如果大家能对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,并且在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

当然,关于DDD,尼恩即将给大家发布一波视频 《第34章:DDD的学习圣经》, 帮助大家彻底穿透DDD。

技术自由的实现路径 PDF:

实现你的 架构自由:

《吃透8图1模板,人人可以做架构》

《10Wqps评论中台,如何架构?B站是这么做的!!!》

《阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了》

《峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?》

《100亿级订单怎么调度,来一个大厂的极品方案》

《2个大厂 100亿级 超大流量 红包 架构方案》

… 更多架构文章,正在添加中

实现你的 响应式 自由:

《响应式圣经:10W字,实现Spring响应式编程自由》

这是老版本 《Flux、Mono、Reactor 实战(史上最全)》

实现你的 spring cloud 自由:

《Spring cloud Alibaba 学习圣经》

《分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)》

《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)》

实现你的 linux 自由:

《Linux命令大全:2W多字,一次实现Linux自由》

实现你的 网络 自由:

《TCP协议详解 (史上最全)》

《网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!》

实现你的 分布式锁 自由:

《Redis分布式锁(图解 - 秒懂 - 史上最全)》

《Zookeeper 分布式锁 - 图解 - 秒懂》

实现你的 王者组件 自由:

《队列之王: Disruptor 原理、架构、源码 一文穿透》

《缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)》

《缓存之王:Caffeine 的使用(史上最全)》

《Java Agent 探针、字节码增强 ByteBuddy(史上最全)》

实现你的 面试题 自由:

4000页《尼恩Java面试宝典 》 40个专题

以上尼恩 架构笔记、面试题 的PDF文件更新,▼请到下面【技术自由圈】公号取 ▼

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Kubernetes】存储类StorageClass

存储类StorageClass 一、StorageClass介绍二、安装nfs provisioner,用于配合存储类动态生成pv2.1、创建运行nfs-provisioner需要的sa账号2.2、对sa授权2.3、安装nfs-provisioner程序 三、创建storageclass,动态供给pv四、创建pvc,通过storage…

二百一十五、Flume——Flume拓扑结构之复制和多路复用的开发案例(亲测,附截图)

一、目的 对于Flume的复制和多路复用拓扑结构,进行一个小的开发测试 二、复制和多路复用拓扑结构 (一)结构含义 Flume 支持将事件流向一个或者多个目的地。 (二)结构特征 这种模式可以将相同数据复制到多个channe…

开辟“护眼绿洲”,荣耀何以为师?

文 | 智能相对论 作者 | 佘凯文 俗话说,眼睛是心灵的窗户,可如今,人们对于这扇“窗户”的保护,似乎越来越不重视。 据人民日报今年发布的调查显示,中国眼病患病人数2.1亿,近视患者人数多达6亿&#xff0…

多功能神器,强劲升级,太极2.x你值得拥有!

嗨,大家好,今天给大家分享一个好用好玩的软件。那就是太极2.x软件,最近在1.0版本上进行了全新升级,升级后的功能更强更稳定,轻度用户使用基本功能就已经足够了,我们一起来看看吧! 首页 首页左…

input、el-input输入框输入规则

一、input 只能输入框只能输入正整数&#xff0c;输入同时禁止了以0开始的数字输入&#xff0c;防止被转化为其他进制的数值。 <!-- 不能输入零时--> <input typetext οninput"valuevalue.replace(/^(0)|[^\d]/g,)"><!-- 能输入零时--> <inp…

【SpringBoot】之Mybatis=Plus集成及使用(入门级)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringBoot开发之Mybatis-Plus系列》。&#x1…

WPF仿网易云搭建笔记(2):组件化开发

文章目录 前言专栏和Gitee仓库依赖属性实战&#xff1a;缩小&#xff0c;全屏&#xff0c;关闭按钮依赖属性操作封装主窗口传递this本身给TitleView标题控件主要代码MainWindow.xmalMainWindow.cs依赖属性方法封装TitleView.csTitleViewModelTitleViewModel实现效果 前言 这次…

有什么好用的资产设备管理系统?工单管理系统在设备管理上有什么作用?

设备管理对于企业而言是非常重要的&#xff0c;像互联网企业、医院、化工企业、制造企业等&#xff0c;都需要用到贵重设备或者仪器。这些设备仪器不仅本身造价成本高&#xff0c;还和生产活动息息相关&#xff0c;所以必须做好日常的维护管理才能确保企业生产活动正常进行。而…

计算机网络:物理层(三种数据交换方式)

今天又学到一个知识&#xff0c;加油&#xff01; 目录 前言 一、电路交换 二、报文交换 三、分组交换 1、数据报方式 2、虚电路方式 3、比较 总结 前言 为什么要进行数据交换&#xff1f; 一、电路交换 电路交换原理&#xff1a;在数据传输期间&#xff0c;源结点与…

新手HTML和CSS的常见知识点

​​​​ 目录 1.HTML标题标签&#xff08;到&#xff09;用于定义网页中的标题&#xff0c;并按照重要性递减排列。例如&#xff1a; 2.HTML段落标签&#xff08;&#xff09;用于定义网页中的段落。例如&#xff1a; 3.HTML链接标签&#xff08;&#xff09;用于创建链接…

【网络编程之初出茅庐】

前言&#xff1a;本章主要先讲解一些基本的网络知识&#xff0c;先把基本的知识用起来&#xff0c;后续会更深入的讲解底层原理。 网络编程的概念 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数…

深度学习 Day16——P5运动鞋识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 文章目录 前言1 我的环境2 代码实现与执行结果2.1 前期准备2.1.1 引入库2.1.2 设置GPU&#xff08;如果设备上支持GPU就使用GPU,否则使用C…

【数据结构第 6 章 ④】- 用 C 语言实现图的深度优先搜索遍历和广度优先搜索遍历

目录 一、深度优先搜索 1.1 - 深度优先搜索遍历的过程 1.2 - 深度优先搜索遍历的算法实现 二、广度优先搜索 2.1 - 广度优先搜索遍历的过程 2.2 - 广度优先搜索遍历的算法实现 和树的遍历类似&#xff0c;图的遍历也是从图中某一顶点出发&#xff0c;按照某种方法对图中所…

VUE-脚手架搭建

文章目录 一、概述二、前提准备1. 安装 node-js2. npm 镜像设置3. 安装 vs-code 三、脚手架搭建1. Vue-2 搭建1. Vue-3 搭建 一、概述 官网&#xff1a;http://cn.vuejs.org/ vue 有两个大版本&#xff0c;分别是 vue-2 和 vue-3&#xff0c;目前新项目的话用 vue-3 的会比较多…

Jmeter,提取响应体中的数据:正则表达式、Json提取器

一、正则表达式 1、线程组--创建线程组&#xff1b; 2、线程组--添加--取样器--HTTP请求&#xff1b; 3、Http请求--添加--后置处理器--正则表达式提取器&#xff1b; 4、线程组--添加--监听器--查看结果树&#xff1b; 5、线程组--添加--取样器--调试取样器。 响应体数据…

正则表达式详解

什么是正则表达式 正则表达式&#xff0c;又称规则表达式&#xff0c;通常被用来检索、替换那些符合某个模式(规则)的文本。 正则表达式是对字符串操作的一种逻辑公式&#xff0c;就是用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个"规则字符串…

Docker-consule 服务发现与注册

consul服务更新和服务发现 什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构&…

Redis新数据类型-Bitmaps

目录 Bitmaps 简介 命令 1. setbit (1) 格式 (2) 实例 2. getbit (1) 格式 (2) 实例 3. bitcount (1) 格式 (2) 实例 4. bitop (1) 格式 (2) 实例 我的其他博客 Bitmaps 简介 Bitmaps 是 Redis 的一种新数据类型&#xff0c;它是一种用于存储位信息的数据结构&…

Dockerfile创建镜像--LNMP+wordpress

实验准备&#xff1a; nginx&#xff1a;172.111.0.10 docker-nginx mysql&#xff1a;172.111.0.20 docker-mysql php&#xff1a;172.111.0.30 docker-php 自定义网段&#xff1a;172.111.0.0/16mkdir nginx mysql php mv nginx-1.22.0.tar.gz wordpress-6.4.2-zh_CN.ta…

用postman进行web端自动化测试

前言 概括说一下&#xff0c;web接口自动化测试就是模拟人的操作来进行功能自动化&#xff0c;主要用来跑通业务流程。 主要有两种请求方式&#xff1a;post和get&#xff0c;get请求一般用来查看网页信息&#xff1b;post请求一般用来更改请求参数&#xff0c;查看结果是否正…