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

news2024/11/18 6:03:57

说在前面

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

谈谈你的DDD落地经验?

谈谈你对DDD的理解?

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

用电商系统为例介绍一下领域驱动设计DDD?

最近有小伙伴在字节,又遇到了相关的面试题。小伙伴懵了, 当然,面试也就挂了

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

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

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

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

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

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

《阿里面试:让代码不腐烂,DDD是怎么做的?》

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

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

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

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

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

文章目录

    • 说在前面
    • 领域驱动设计介绍
      • 第1步:战略设计
        • 1、业务分析
          • 事件风暴业务分析的核心环节
        • 2、领域建模
        • 3、划分边界上下文
      • 第2步:战术设计
        • 1、领域服务设计
        • 2、领域分层
        • 3、代码结构
    • 电商的领域驱动设计
      • 第1步:战略设计
        • 1、事件风暴:参与者、动作以及事件 整个协作流程梳理
        • 2、领域建模与边界上下文划分
      • 第2步:战术阶段
    • 领域驱动设计与微服务的关系
    • 领域驱动设计与敏捷开发相结合
    • 未完待续,尼恩说在最后
    • 尼恩技术圣经系列PDF

领域驱动设计介绍

领域驱动设计(Domain-driven Design,DDD)是一种软件设计方法,该方法的核心思想是将业务领域作为设计和开发的中心,强调对业务领域的深入理解、业务语言的建模以及领域对象的设计和实现。

这样可以更好地将软件设计和业务需求紧密结合起来,从而提高软件的可维护性、可扩展性和可重用性,使得软件更加贴近业务需求。

DDD设计的两个阶段包括两部分,战略设计部分和战术设计部分:

第1步: 战略设计

战略设计主要从业务视角出发,包括了业务场景分析、领域建模、划分边界上下文三个阶段。限界上下文可以作为微服务设计的参考边界。

第2步:战术设计

战术设计则从技术视角出发,侧重于领域模型的技术实现,完成软件开发和落地,

战术设计包括:聚合根、实体、值对象、领域服务、应用服务和资源库等代码逻辑的技术设计和技术设计。

第1步:战略设计

在战略设计阶段,我们最主要的过程大致包括了业务场景分析、领域建模、划分边界上下文三个阶段。

实际上战略设计是 DDD 过程中的核心步骤。

1、业务分析

在这个阶段我们所有做的就是进行全面的业务梳理,把业务中涉及到的所有细节都梳理出来,为后续进行领域建模分析提供足够的、全面的业务输入。

战略设计 经常使用到的业务场景分析方法主要包括

  • 用例分析法
  • 事件风暴法
  • 四色建模法。

一般使用事件风暴法。

事件风暴是一种快速,轻量级且未得到充分认可的群体建模技术,它对于加速开发团队而言非常强大,有趣且有用。

事件风暴业务分析的核心环节

这里我们使用事件风暴进行业务场景的分析以及梳理。

(1)事前准备

在进行事件风暴之前我们需要进行一些准备,主要包括贴纸、笔以及讨论的会议室,

会议室中最好不要有椅子,目的是想让大家都能够站立在一起、全神贯注的去进行业务讨论。

(2)邀请参会的人

会议的参与方主要包括用户、产品经理、PD、研发、测试、架构师等。

其中,PD为产品设计师,也可能叫产品规划师、需求分析师、小产品经理。

PD侧重于将对应用做功能级的设计,在这个模块上,PD类似是一个小产品经理、模块级别的产品经理。

架构师(系统分析师)会与PD紧密合作,架构师 这时候开始考虑技术可行性,性价比。

PD的职位描述:

(1)调查市场并研究需求,形成市场需求文档。

(2)负责新产品设计,拟定设计规划和方案。

(3)负责新产品的原型设计。

(4)组织产品开发团队,协调资源,跟进产品的开发,保证日程进度。

(5)分析产品运营数据,收集运营意见,及时调整产品形态,优化产品,并提出合理的运营建议。

(6) 以用户体验为中心,改进现有产品,或设计新产品。

(3)业务讨论

首先确定我们今天需要讨论的业务是什么,目标是什么。

咱们业务场景中,如果讨论的业务就是电商,那么,目标就是完成业务梳理,确保没有业务方面的理解 gap,在团队中达成业务理解的的一致性。

事件风暴过程需要问题驱动,一般通过提问的方式来驱动交流。

a、分析业务中的事件,搞清楚事件发生的前因后果

  • 什么动作会导致当前事件的发生,
  • 当前这个事件发生后又会导致怎样的后果。

这些我们都需要梳理清楚。

还有一点需要注意, 需要全面梳理

  • 不但要关注正常的业务流程,
  • 还要关注异常的业务流程。

b、寻找业务逻辑和业务规则

:在进行事件风暴过程中,所有的参与人都要全身投入整个过程,

大家都是站立形式,聚焦全部注意力,

大家都放下手机以及电脑,一起参与整个业务梳理过程,只有这样,事件风暴才可能有比较好的效果。

在前面的事件风暴业务梳理中,我们已经把电商业务涉及到的参与者、动作以及事件等都进行了全面的梳理。

参与者、动作以及事件 整个协作流程,是一个粗粒度的 业务流程, 非常粗。

2、领域建模

那么接下来我们就要在此基础之上,进行细粒度的 领域建模,这是整个 DDD 的核心。

DDD领域模型 细分为两步骤,第一步是发散,产生很多实体、命令、事件等领域对象,

DDD领域模型 细分为两步骤,第二步是收敛,我们从不同的维度对进行聚类形成聚合,建立最终领域模型, 这是一个收敛的过程。

(1)发散阶段:领域对象分析

领域对象分析,也就 实体、值对象、领域事件、领域命令的分析。

(2)收敛阶段:构建业务聚合

完成领域对象分析之后,我们需要构建业务聚合。

想要构建聚合,那么首先就要在实体中找到聚合根。

来看看,一个 聚合根的特点:

  • 聚合根一定是实体,那么它具有全局唯一的标识,
  • 聚合根是具备生命周期的
  • 聚合根需要专门的模块来进行管理。
3、划分边界上下文

获得了整个业务流程中的所有聚合后,我们需要更具业务语义上下文将具体的聚合划分到对应的上下文中,

  • 域的拆分
    • 按业务抽象进行划分
    • 一个业务拆分成几个独立的域,每个域又可细拆成不同子域
  • 防腐
    • 一个域在访问其他域的模型时,把获取到的模型做层转换映射到自己域的模型中(不直接使用别的域模型作为自己域模型中的一部分)
    • 防止源域模型发生变更,依赖源域模型的调用方,在需要源域模型新功能时,必须要全局依赖修改,才在能兼容
    • 防止域上下文不一致产生的冲突
  • 限界上下文之间的映射关系
    • 合作关系(Partnership):两个上下文紧密合作的关系,一荣俱荣,一损俱损。
    • 共享内核(Shared Kernel):两个上下文依赖部分共享的模型。
    • 客户方-供应方开发(Customer-Supplier Development):上下文之间有组织的上下游依赖。
    • 遵奉者(Conformist):下游上下文只能盲目依赖上游上下文。
    • 防腐层(Anticorruption Layer):一个上下文通过一些适配和转换与另一个上下文交互。
    • 开放主机服务(Open Host Service):定义一种协议来让其他上下文来对本上下文进行访问。
    • 发布语言(Published Language):通常与OHS一起使用,用于定义开放主机的协议。
    • 大泥球(Big Ball of Mud):混杂在一起的上下文关系,边界不清晰。
    • 另谋他路(SeparateWay):两个完全没有任何联系的上下文。

第2步:战术设计

在战略设计阶段,我们通过事件风暴法对整体的业务进行了全部的梳理,同时构建了领域模型,以及划分了边界下文。

那么接下来我们就要将领域模型映射到工程结构,以及代码中实现最终的实现落地。

另外在这个阶段实际还有很多细节需要明确的。

1、领域服务设计

需要哪些领域服务,领域服务依赖哪些属性,依赖哪些实体,依赖哪些值对象,这些都是需要在战术设计阶段明确下来。

2、领域分层

在领域分层方面,可以按照cola分层结构来进行,这个后面结合cola框架进行说明。

3、代码结构

当我们把领域对象进行进一步的细化之后,同时把对应的领域服务敲定之后,我们可以把这些分析后的内容映射成工程分层后的代码了。

所以,后续就进入到阶段了,还有很多工作要做,比如详细设计、编写代码以及功能测试,

特别实在详细设计阶段,我们还要涉及很多的细节问题的敲定,比如数据库表的设计、比如使用什么 MQ,用不用缓存,怎么保证缓存和数据库的数据一致性问题,分布式服务有没有分布式事务的问题,应该怎么解决?

有没有服务幂等问题,应该怎么解决?

这些都是需要在详细设计阶段进行确定的。

因此 DDD 就像是框架,通过它把业务映射成为领域对象以及领域服务和领域事件,再把这些领域相关内容再读映射为实际的代码。

使得我们的服务更加的逻辑清晰以及扩展性更强,但是分布式的技术实现细节,我们还是需要有对应的解决方案来进行解决。

电商的领域驱动设计

第1步:战略设计

1、事件风暴:参与者、动作以及事件 整个协作流程梳理

大致可以梳理出下面的参与者、动作以及事件

  1. 订单创建事件:当用户下单后,系统需要创建一个新的订单,并触发订单创建事件。
  2. 订单支付事件:当用户完成订单支付后,系统需要将订单状态设置为已支付,并触发订单支付事件。
  3. 订单发货事件:当商家完成订单发货后,系统需要将订单状态设置为已发货,并触发订单发货事件。
  4. 订单退款事件:当用户申请退款并经过审核后,系统需要将订单状态设置为已退款,并触发订单退款事件。
  5. 商品上架事件:当商家将商品上架时,系统需要将商品状态设置为上架,并触发商品上架事件。
  6. 商品下架事件:当商家将商品下架时,系统需要将商品状态设置为下架,并触发商品下架事件。
  7. 库存变更事件:当用户下单后,系统需要检查商品库存是否充足,并对库存进行相应的变更,并触发库存变更事件。
  8. 物流状态变更事件:当订单状态变更为已发货时,系统需要记录物流信息,并触发物流状态变更事件。

通过对领域事件的记录和处理,可以在电商系统中实现更加复杂的业务逻辑,提高系统的灵活性和可维护性。

2、领域建模与边界上下文划分

电商系统中的聚合和聚合根是什么?

在电商系统中,可以将订单作为一个聚合,其中包括多个领域对象,例如订单项、收货地址、发票信息等。

订单作为一个聚合,它的内部领域对象之间有明确的关联关系,并且需要满足一些业务规则,例如订单项的数量不能为负数,订单状态必须是待付款、待发货、待收货、已完成等状态之一。

在订单聚合中,可以将订单对象作为聚合根,用于保证订单聚合的完整性和一致性。订单对象具有唯一标识和全局访问权限,它可以被其他领域对象引用,例如订单项和收货地址等。

使用聚合和聚合根可以将复杂的业务逻辑封装在一个边界内,提高系统的可维护性和可扩展性。

电商系统是一个涉及到多个业务领域的复杂应用系统,经过上下文建模和边界上下文划分,最后确定电商系统所包含了众多的子域。

以下是电商系统中常见的一些子域:

  1. 商品子域:包括商品分类、商品管理、商品展示等功能。
  2. 订单子域:包括下单、订单管理、订单配送、订单支付等功能。
  3. 营销子域:包括促销活动、优惠券、积分、礼品卡等功能。
  4. 用户子域:包括用户注册、用户登录、用户个人信息管理等功能。
  5. 支付子域:包括支付方式、支付渠道、支付接口等功能。
  6. 物流子域:包括订单配送、物流跟踪、运费计算等功能。
  7. 客服子域:包括售后服务、用户反馈、在线客服等功能。
  8. 数据统计子域:包括用户行为分析、交易数据统计、业务数据报表等功能。

在实际的电商应用系统中,可能会根据业务需求进一步细分和扩展各个子域。每个子域都可以作为一个独立的微服务进行设计和开发,从而实现更好的业务解耦和系统扩展性。

第2步:战术阶段

核心是领域服务设计

电商系统中包括的领域服务,主要如下:

  1. 商品服务:负责管理商品的上架、下架、库存等信息,并提供商品的查询、搜索、推荐等功能。
  2. 订单服务:负责管理订单的创建、支付、发货、退款等流程,并提供订单的查询、取消、评价等功能。
  3. 用户服务:负责管理用户的注册、登录、个人信息管理等功能,并提供用户评价、收藏、关注等功能。
  4. 支付服务:负责管理系统的支付方式、支付账户等信息,并提供支付的流程和接口。
  5. 物流服务:负责管理物流的配送、快递信息等,并提供物流的查询、跟踪等功能。
  6. 营销服务:负责管理系统的促销活动、优惠券等信息,并提供优惠券领取、使用等功能。
  7. 数据统计服务:负责收集、分析、展示系统的数据统计信息,例如订单量、销售额、用户活跃度等。
  8. 客服服务:负责管理系统的客户服务、投诉处理等工作,并提供在线客服、电话客服等渠道。

这些领域服务之间相互协作,共同实现电商系统的核心功能和业务流程。

通过领域服务的划分和封装,可以提高系统的可扩展性和可维护性,降低系统的耦合度和复杂度。

领域驱动设计与微服务的关系

领域驱动设计(DDD)和微服务是两种不同的概念,但它们可以结合在一起来提高软件的质量和可维护性。

微服务架构是一种将应用程序拆分成多个小型、自治的服务的架构模式,每个服务专注于某个特定的业务功能,通过轻量级通信机制进行协作。

微服务架构通常需要处理大量的业务逻辑,因此需要一个清晰的领域模型来管理这些业务逻辑,这时领域驱动设计就能够发挥作用了。

通过领域驱动设计,开发人员可以更好地理解业务需求,更好地建模业务领域,将领域模型作为微服务架构的核心,从而更好地支持微服务架构。

具体来说,领域驱动设计可以帮助实现以下方面:

  1. 微服务的拆分和划分:通过领域驱动设计,可以将业务领域划分为不同的子域,并将每个子域划分为一个或多个微服务,从而实现微服务的拆分和划分。

  2. 服务间的通信:微服务架构中的服务需要通过通信机制进行协作。

    通过领域驱动设计,可以在微服务之间定义明确的接口和协议,使得服务之间的通信更加清晰和稳定。

  3. 微服务的扩展和维护:通过领域驱动设计,可以将业务逻辑清晰地划分为不同的领域模型,从而使得微服务的扩展和维护更加容易。例如,在需要修改业务逻辑时,只需要修改对应的领域模型和微服务,而不需要修改整个应用程序。

因此,领域驱动设计可以帮助开发人员更好地支持微服务架构,并实现更好的软件设计和开发。

领域驱动设计与敏捷开发相结合

领域驱动设计和敏捷开发是两种不同的方法论,但可以相互结合,提高开发效率和软件质量。

在敏捷开发过程中,团队通常采用迭代式的开发模式,不断地根据用户反馈和需求变化进行调整和优化。

这种敏捷开发模式与领域驱动设计的思想相契合,因为领域驱动设计强调将业务领域建模为一个相对独立的系统,同时也强调不断优化和迭代。

以下是一些结合领域驱动设计和敏捷开发的方法:

  1. 划分迭代周期:在敏捷开发中,团队通常会划分出多个迭代周期来实现软件的开发和交付。在每个迭代周期中,可以采用领域驱动设计方法进行领域建模和设计,以确保软件系统的质量和可维护性。
  2. 与领域专家和用户紧密合作:在敏捷开发中,团队需要与领域专家和用户紧密合作,及时获取用户反馈和需求变化。在领域驱动设计中,也需要与领域专家和用户紧密合作,以确保领域建模的准确性和实用性。
  3. 重构和优化:敏捷开发中,团队需要不断地重构和优化代码,以提高软件系统的质量和可维护性。在领域驱动设计中,也需要不断地优化领域建模和设计,以提高系统的可扩展性和可维护性。
  4. 测试和验收:在敏捷开发中,团队需要进行测试和验收,以确保软件系统的质量和稳定性。在领域驱动设计中,也需要进行测试和验收,以确保领域建模和设计的准确性和实用性。

未完待续,尼恩说在最后

DDD 面试题,是非常常见的面试题。 DDD的学习材料, 汗牛塞屋,又缺乏经典。

大家面试的时候, 可以参考以上的内容去组织答案,如果大家能做到对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

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

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

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

尼恩技术圣经系列PDF

  • 《NIO圣经:一次穿透NIO、Selector、Epoll底层原理》
  • 《Docker圣经:大白话说Docker底层原理,6W字实现Docker自由》
  • 《K8S学习圣经:大白话说K8S底层原理,14W字实现K8S自由》
  • 《SpringCloud Alibaba 学习圣经,10万字实现SpringCloud 自由》
  • 《大数据HBase学习圣经:一本书实现HBase学习自由》
  • 《大数据Flink学习圣经:一本书实现大数据Flink自由》
  • 《响应式圣经:10W字,实现Spring响应式编程自由》
  • 《Go学习圣经:Go语言实现高并发CRUD业务开发》

……完整版尼恩技术圣经PDF集群,请找尼恩领取

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

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

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

相关文章

matlab GUI界面实现ZieglerNicholas调节PID参数

1、内容简介 略 11-可以交流、咨询、答疑 ZieglerNicholas、PID、GUI 2、内容说明 GUI界面实现ZieglerNicholas调节PID参数 通过ZieglerNicholas调节PID参数,设计了GUI 3、仿真分析 略 4、参考论文 略 链接:https://pan.baidu.com/s/1yQ1yDfk-_…

vue+mongodb+nodejs实现表单增删改查

ExpressMongodbVue实现增删改查 效果图 前言 最近一直想学下node,毕竟会node的前端更有市场。但是光看不练,感觉还是少了点什么,就去github上看别人写的项目,收获颇丰,于是准备自己照葫芦画瓢写一个。 作为程序员,一…

电容的作用

文章目录 总结1.降压2.滤波3.延时4.耦合5.旁路电容 总结 1.降压 问题: 直接连接灯泡会烧掉 解决方案 进一步为了防止电容放电,伤人,加入一个大电阻 2.滤波 直流的情况 交流的情况 频率与容抗的关系 3.延时 4.耦合 滤除直流成分&#xf…

学习c#的第七天

目录 C# 封装 概念 Public 访问修饰符 Private 访问修饰符 Protected 访问修饰符 Internal 访问修饰符 Protected Internal 访问修饰符 总结 C# 封装 概念 在面向对象程序设计中,封装是一种将数据和方法包含在一个单元中,并控制对这些数据和方…

LeetCode算法心得——高级访客(模拟枚举+小窗口)

大家好,我是晴天学长,今天的周赛第二题,需要的小伙伴可以关注支持一下哦!后续会继续更新的。💪💪💪 1) .高级访客 给你一个长度为 n 、下标从 0 开始的二维字符串数组 access_times 。对于每个 …

Redis五种数据类型及命令操作(二)

🎈个人公众号:🎈 :✨✨✨ 可为编程✨ 🍟🍟 🔑个人信条:🔑 知足知不足 有为有不为 为与不为皆为可为🌵 🍉本篇简介:🍉 本篇记录Redis五种数据类型及命令操作,如…

Oracle(2-1) Networking Overview

文章目录 一、基础知识1、Network Environ Challenges 网络环境挑战2、Simple Network :2-Tier 简单的两层网络3、Simple to Complex : N-Tier 简单到复杂:N层网络4、Oracle Network Solutions Oracle网络解决方案5、Key Features of Oracle Net Oracle Net的主要功…

[MySQL] MySQL表的基础操作

文章目录 一、创建表 1、1 SQL语法 1、2 实例演示 二、查询表 三、修改表 3、1 修改表名字 3、2 新增列(字段) 3、3 修改列类型 3、4 修改列名 3、5 删除表 四、总结 🙋‍♂️ 作者:Ggggggtm 🙋‍♂️ 👀 专…

详解Redis持久化(上篇——RDB持久化)

Redis持久化的作用和意义 Redis 持久化是一种机制,用于将内存中的数据写入磁盘,以保证数据在服务器重启时不会丢失。持久化是为了解决内存数据库(如 Redis)在服务器关闭后,数据丢失的问题。 Redis 持久化的主要作用和…

如何判断一个角是否大于180度(2)

理论计算见上一篇: 如何判断一个角是否大于180度?_kv1830的博客-CSDN博客 此篇为代码实现 一。直接上代码: import cv2 as cv import numpy as np import mathdef get_vector(p_from, p_to):return p_to[0] - p_from[0], p_to[1] - p_from…

【第六章】软件设计师 之 数据结构与算法基础

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 1、数据结构与算法基础 2、数据 3、稀疏矩阵…

【第三章】软件设计师 之 数据库系统

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 1、数据库系统前言 2、三级模式 - 两级映射…

爬虫项目(12):正则、多线程抓取腾讯动漫,Flask展示数据

文章目录 书籍推荐正则抓取腾讯动漫数据Flask展示数据 书籍推荐 如果你对Python网络爬虫感兴趣,强烈推荐你阅读《Python网络爬虫入门到实战》。这本书详细介绍了Python网络爬虫的基础知识和高级技巧,是每位爬虫开发者的必读之作。详细介绍见&#x1f44…

Netty入门指南之NIO Selector写操作

作者简介:☕️大家好,我是Aomsir,一个爱折腾的开发者! 个人主页:Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏:Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言操作演…

transfomer模型——简介,代码实现,重要模块解读,源码,官方

一、什么是transfomer Transformer是一种基于注意力机制(attention mechanism)的神经网络架构,最初由Vaswani等人在论文《Attention Is All You Need》中提出。它在自然语言处理(NLP)领域取得了巨大成功,特…

自定义Graph Component:1.1-JiebaTokenizer具体实现

JiebaTokenizer类继承自Tokenizer类,而Tokenizer类又继承自GraphComponent类,GraphComponent类继承自ABC类(抽象基类)。本文使用《使用ResponseSelector实现校园招聘FAQ机器人》中的例子,主要详解介绍JiebaTokenizer类…

JavaScript_动态表格_添加功能

1、动态表格_添加功能.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>动态表格_添加功能</title><style>table{border: 1px solid;margin: auto;width: 100%;}td,th{text-align: ce…

Python:Unittest框架快速入门:用例、断言、夹具、套件、HTML报告、ddt数据驱动

快速看了套Unittest的入门教程 软件测试全套资料赠送_哔哩哔哩_bilibili软件测试全套资料赠送是快速入门unittest测试框架&#xff01;全实战详细教学&#xff0c;仅此一套&#xff01;的第1集视频&#xff0c;该合集共计11集&#xff0c;视频收藏或关注UP主&#xff0c;及时了…

ElasticSearch学习和使用 (使用head软件可视化es数据)

使用步骤 直接使用 Elasticsearch的安装和使用 下载Elasticsearch6.2.2的zip包&#xff0c;并解压到指定目录&#xff0c;下载地址&#xff1a;https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2运行bin目录下的elasticsearch.bat启动Elasticsearch安…

【Python】python读取,显示,保存图像的几种方法

一、PIL&#xff1a;Python Imaging Library&#xff08;pillow&#xff09; PIL读取图片不直接返回numpy对象&#xff0c;可以用numpy提供的函数np.array()进行转换&#xff0c;亦可用Image.fromarray()再从numpy对象转换为原来的Image对象&#xff0c;读取&#xff0c;显示&…