1. 1.1 架构historical

    1. 什么是架构 在抽象层次上描述整体与局部以及他们之间的关系 2. 为什么需要架构 为了解决软件系统复杂度带来的问题 3. 架构分类 - 3.1. 基础架构 - 例如云平台、操作系统、网络、存储、数据库和编译器等 3.2. 中间件与大数据平台 - 中间件架构:例如分布式服务中间件、消息中间件、数据

  2. 1.2 架构模式historical

    1. 单体架构 单体架构.md 2. 分层架构 分层架构.md 3. 事件驱动架构 事件驱动架构.md 4. CQRS架构 读写分离架构.md 5. 微服务架构 微服务.md 6. 可插拔架构 可插拔架构.md 7. 参考 - 架构模式 \- 维基百科,自由的百科全书

  3. 1.3 单体架构historical

    1. 什么是单体架构 - 将所有功能打包在一个容器中运行的设计风格,一个实例中集成了一个系统的所有功能。通过负载均衡软件/设备实现多实例调用 - 2. 单体架构的优缺点 - 优点 - 开发简单 - 部署简单 - 测试简单 - 缺点 - 业务耦合度高导致修改复杂 - 扩展性差

  4. 1.4 分层架构historical

    1. 什么是分层架构 根据系统中的角色/职责拆分和组织代码单元的常规实践 上层依赖下层,上层可以感知到下层,下层感知不到上层 2. 分层架构的演进 2.1. 一层 2.2. 两层 也叫单机架构 2.3. 三层 也叫集中式架构,C/S和B/S架构 2.4. DDD四层 2.4.1. 传统四层架构 用户

  5. 1.5 读写分离架构historical

    1. 什么是读写分离 把读操作(R)和写操作(CUD)分开,本质上就是分布式系统复制中的Leader-Follower模式 2. 为什么需要读写分离 提高读吞吐量 3. 读写分离适用场景 读多写少且允许数据不一致 4. 如何设计读写分离 4.1. 服务层读写分离 优点:代码易维护且没有数据一致性问题

  6. 1.6 事件驱动架构historical

    1. 什么是事件驱动架构 基于事件的一种软件架构模式 系统从A状态- B状态发布消息告知系统的其他部分 2. 为什么需要事件驱动架构 解耦:事件发起者并不知道哪个事件使用者在监听事件,而且事件也不知道其所产生的后续结果 异步 3. 事件驱动架构 对比请求驱动模式实时性差 4. 如何设计事件驱动架构

  7. 1.7 DDDhistorical

    1. 什么是DDD 领域驱动设计,是一种架构方法 1.1. 领域 1.1.1. 什么是领域 领域就是业务的范围/边界,大领域可以划分成多个中领域,中领域又可以继续划分成小领域... 本质就和解决问题一样,采用分而治之的思想把复杂问题简单化,从而降低业务理解和系统实现的复杂度 1.1.2. 为什么需要

  8. 1.8 微服务historical

    1. 什么是微服务架构 - 微服务架构是把单体应用 按功能模块拆分成一组服务 的架构 - 模块即服务,服务之间通过API通信 - 每个服务有自己独立的数据库 1.1. 微服务 vs SOA - 微服务架构是目前主流的构造分布式系统一种架构风格。它可以看做是SOA架构的一种变种或者是延伸 - 所谓分布

  9. 2.1 OpenId Connecthistorical

    1. OpenID Connect是什么 - 一种认证协议 - OAuth只是用于授权,没有定义认证的规范 - 基于OAuth2 - 只是多了个标准化的UserInfo Endpoint 2. OpenID Connect流程 - 跟OAuth.md一样。 - 区别在于 - 再在OAuth第一步请求

  10. 2.2 JWThistorical

    1. JWT是什么 - 用户认证成功后,服务器给用户发放的一种token - token是一定时间内有效的令牌,表明用户已经认证 2. 为什么需要JWT - 用于跨域认证 - 所谓跨域认证:指如果一个公司有两个域名A和B,那么用户在A域名认证后,访问B域名不用再次认证了 - 传统的跨域认证是cook

  11. 2.3 OAuthhistorical

    1. OAuth是什么 - 一种授权协议 - 用来授权第三方应用,获取用户数据。 2. 为什么需要OAuth - 以使用微博登录简书,简书需要用到微博的头像昵称 - 传统的作法是输入微博的用户名+密码获取,这种有几个问题 - 微博用户名密码暴露给了简书,可能会泄露 - 只想获取微博头像昵称,但是简书

  12. 2.4 如何设计配置中心historical

    1. 什么是配置中心 用来统一管理项目中所有配置的系统 2. 为什么需要配置中心 传统的配置是放在一个配置文件中,跟代码一起发布,这种每次修改了配置都要重新发布服务 而配置中心则是把配置存储在独立的配置服务器上,用户通过管理界面配置和调整服务配置,具体服务通过定期拉(Scheduled Pull)的

  13. 2.5 如何设计负载均衡组件historical

    1. 什么是负载均衡 - 将请求(工作负载)平均的打到到多个机器上以提高性能和可用性 2. 为什么需要负载均衡 - 通过机器冗余提高可用性 - 便于横向扩展以提高性能和吞吐量 - 垂直扩展指更换性能更强劲的机器,价格自然更高,性价比不咋地 3. 如何实现负载均衡组件 3.1. 负载均衡算法有哪些 负

  14. 2.6 如何设计注册中心historical

    1. 什么是注册中心 - 记录了 服务名<- IP地址+Port 的映射关系,本质上和DNS没区别 - 2. 为什么需要注册中心 没有注册中心那么A调用B只能写死IP地址,不灵活 3. 如何实现注册中心 3.1. 服务端 3.1.1. 服务注册表 2. 中心化、强一致存储中间件。比如Zookeepe

  15. 2.7 如何设计API网关historical

    1. 什么是API网关 - 网关=路由器+过滤器 - 路由器:外部请求的入口(单点入口)。一般微服务都是部署在内网,所有外部请求都先经过网关,由网关转发到后端服务器(服务路由)。 - 过滤器:限流熔断、安全认证、日志监控等 2. 为什么要需要API网关 - 抽取公共逻辑 - 像授权认证的代码在每个服

  16. 2.8 如何设计监控系统historical

    1. 什么是监控 - 日志监控(Log):把代码中的日志收集在一个地方,用来统一查询处理 - 度量监控(Metrics):记录事件发生的时间和数值,用来查看趋势 - 调用链监控(Tracing):记录一个请求的全部流程。用来查看请求经过了哪些节点,每个节点的耗时 2. 为什么需要监控 微服务架构由众

  17. 2.9 如何设计链路追踪historical

    1. 什么是链路追踪 记录一个请求的全部流程。用来查看请求经过了哪些节点,每个节点的耗时 2. 为什么需要链路追踪 能快速定位一个请求在整个链路上哪个节点出了问题 3. 如何实现链路追踪 3.1. 上报什么数据 3.1.1. Span 3.1.1.1. Span是什么 - 每调用一个模块就生成一个S

  18. 2.10 如何设计容错组件historical

    1. 什么是容错 微服务架构下,如果一个服务故障了,那么会影响到整个链路,导致服务整体不可用 2. 为什么需要容错 确保服务的可用性,防止雪崩效应 2.1. 服务雪崩 多个微服务之间调用的时候,假设服务A调用服务B和C,服务B调用服务D和E,服务C调用服务F和服务G...这就叫 扇出 因“服务提供者

  19. 2.11 如何设计日志监控historical

    1. 日志监控是什么 把代码中的日志收集在一个地方,用来统一查询处理 2. 为什么需要日志监控 如果没有日志监控,那么需要登录上每台机器进行查询,效率很低 3. 如何实现日志监控 3.1. 输出日志 - 由应用程序打印日志,输出到本地文件 - 日志打印策略 - 区分日志等级 - 关键路径和异常路径

  20. 2.12 如何设计metrics监控historical

    1. metrics监控是什么 记录事件发生的时间和数值,用来查看趋势 2. 为什么需要metrics监控 可以用来查看趋势,在出问题之前告警 3. 如何实现metrics监控 3.1. 监控什么数据 - 系统层: - 系统层主要是指宿主机和容器的监控, - 指标:CPU、磁盘、内存、网络等 - 中

  21. 2.13 如何设计认证授权historical

    1. 什么是认证授权 - 认证:当前用户的身份,解决我是谁的问题 - 授权:什么样的身份被允许访问某些资源,解决我能做什么的问题 - 凭证:认证和授权的基础,一种标记访问者的身份或权利的媒介 2. 为什么要认证授权 安全 3. 认证授权技术 3.1. 认证技术 3.1.1. HTTP认证 Base6

  22. 3.1 ER图historical

    1. 是什么 - 提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型 2. 例子 3. 参考 - Entity Relationship diagram syntax and features - 抽象思维实践——ddl2plantuml开发记录

  23. 3.2 UMLhistorical

    1. 结构建模 1.1. 类图 - 类图.md 1.2. 部署图 - 部署图.md 1.3. 组件图 - 组件图.md 2. 行为建模 2.1. 用例图 - 用例图.md 2.2. 流程图/活动图 - 流程图.md 2.3. 状态转换图 - 状态图.md 2.4. 时序图 - 时序图.md 3. 架

  24. 3.3 类图historical

    1. 是什么 描述系统中的Class的属性和方法,以及Class之间的关系 2. 使用 2.1. 类和接口 + 表示public - 表示private 2.2. 类之间的关系 2.2.1. 泛化、实现 符号:三角形 泛化指extends一个类。 实线 实现指implement一个接口。虚线 2.2

  25. 3.4 时序图historical

    1. 是什么 用户和系统的各个组件之间的交互流程,主要描述消息如何传递的 电商详情页的设计.md 2. 例子

  26. 3.5 流程图historical

    1. 是什么 某个流程的详细步骤,比如用于描述某个复杂函数的流程 Hystrix.md 2. 例子

  27. 3.6 状态图historical

    1. 是什么 - 描述某个对象的状态转换 2. 例子

  28. 3.7 组件图historical

    1. 是什么 描述每一层的组件,比如用于描述开源软件分层架构,展示了软件与 软件组件(比如库函数)的依赖 关系 2. 例子

  29. 3.8 部署图historical

    1. 是什么 - 部署图描述的是系统运行时的结构,展示了 硬件的配置 以及 软件如何部署到网络结构 中。 2. 例子

  30. 3.9 架构图historical

    1. 业务架构图 说明业务流程 2. 应用架构图 说明应用有哪些功能模块,用到了哪些技术 2.1. 功能视角 2.2. 技术视角 3. 技术架构图 4. 数据架构图 5. 安全架构图 6. 部署架构图 7. 4+1视图 7.1. Use-Case View - 描述软件系统的用户以及用户能做什么 -

  31. 4.1 函数式选项模式historical

    1. 定义 - 创建由默认值的对象,同时可以灵活地修改属性 - 我们可能需要为Option的字段指定默认值 - Option的字段成员可能会发生变更 2. Golang 2.1. 要创建的对象 2.2. 测试 3. 参考 - Go语言设计模式之函数式选项模式 \ 李文周的博客

  32. 4.2 接口型函数historical

    1. 接口型函数是什么 一个实现了接口的函数类型,简称为接口型函数 2. 为什么需要接口型函数 既能够将普通的函数类型(需类型转换)作为参数,也可以将结构体作为参数,使用更为灵活,可读性也更好,这就是接口型函数的价值。 3. 实现 4. 参考 - Go 接口型函数的使用场景 \ 极客兔兔

  33. 4.3 事件溯源模式historical

    1. 什么是事件溯源 基于事件的一种软件架构模式 系统的CUD事件进行持久化 2. 为什么需要事件溯源 传统的CRUD存在一些问题 1. 直接操作数据库,而数据库性能比较低 2. 为了防止并发问题需要引入锁、事务等,引发性能上的损失 3. 因为数据存储中通常保存的是数据最终的状态,所以为了追踪数据变

  34. 4.4 发布订阅模式historical

    1. 发布订阅模式是什么 - 有三个角色:发布者、事件中心、订阅者 - 订阅者需要向事件中心订阅指定的事件 - 发布者向事件中心发布指定事件内容 - 事件中心通知订阅者 - 订阅者收到消息 2. 为什么需要发布订阅模式 - 解耦 - 发布者只关注生产数据,不关心订阅者怎么消费 - 订阅者只关注消费数

  35. 4.5 生产者消费者模式historical

    1. 生产者/消费者模式是什么 - 有三个角色:生产者、消费者、队列 - 生产者生产完数据丢入队列,消费者从队列取出数据消费 2. 为什么需要生产者/消费者模式 - 解耦 - 生产者只关注生产数据,不关心消费者怎么消费 - 消费者只关注消费数据,不关心生产者怎么生产 - 异步 3. 生产者/消费者模

  36. 5.1 开闭原则historical

    1. 什么是开闭原则 对扩展开放,对修改关闭 2. 为什么需要开闭原则 降低维护带来的新风险 3. 开闭原则实现 新需求修改代码的时候看下会不会修改到原有的代码,有的话需要重构:通过接口或者抽象类定义抽象层,将可变因素封装在具体实现类中 继承:里氏替换原则.md 组合/聚合:合成复用原则.md 4.

  37. 5.2 里氏替换原则historical

    1. 什么是里氏替换原则 不要破坏继承体系,子类重写方法功能发生改变,不应该影响父类方法的含义 开闭原则在继承中的体现 2. 为什么需要里氏替换原则 通过继承提高软件复用能力 3. 里氏替换原则实现 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法 子类中可以增加自己特有的方法 4. 参考 -

  38. 5.3 依赖倒置原则historical

    1. 什么是依赖倒置原则 高层不应该依赖低层 要面向接口编程,不要面向实现编程。 2. 为什么需要依赖倒置原则 提高可扩展性 3. 依赖倒置原则实现 每个类尽量提供接口或抽象类,或者两者都具备。 变量的声明类型尽量是接口或者是抽象类。 任何类都不应该从具体类派生而应该从抽象类派生。 使用继承时尽量遵

  39. 5.4 单一职责原则historical

    1. 什么是单一职责原则 一个类只干一件事,实现类要单一 2. 为什么需要单一职责原则 提高代码的可读性 3. 单一职责原则实现 需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中 4. 参考 - 单一职责原则——面向对象设计原则

  40. 5.5 接口隔离原则historical

    1. 什么是接口隔离原则 一个接口只干一件事,接口要精简单一 2. 为什么需要接口隔离原则 提高代码的可读性 解耦 3. 接口隔离原则实现 接口尽量小,一个接口只服务于一个子模块或业务逻辑。 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。 4. 参考 - 接口隔离原则——面向对象

  41. 5.6 迪米特法则historical

    1. 什么是迪米特法则 不该知道的不要知道,一个类应该保持对其它对象最少的了解 2. 为什么需要迪米特法则 降低耦合度 3. 迪米特法则实现 从依赖者的角度来说,只依赖应该依赖的对象。 从被依赖者的角度说,只暴露应该暴露的方法。 4. 参考 - 迪米特法则——面向对象设计原则

  42. 5.7 合成复用原则historical

    1. 什么是合成复用原则 尽量使用组合或者聚合关系实现代码复用,少使用继承 开闭原则在组合/聚合中的体现 2. 为什么需要合成复用原则 通过组合提高软件复用能力 3. 合成复用原则实现 将新对象作为原有对象的属性注入 4. 参考 - 合成复用原则——面向对象设计原则

  43. 5.8 OOP设计原则historical

    1. 什么是面向对象设计原则 2. 为什么需要面向对象设计原则 提高代码的可维护性、可扩展性、可复用性 3. 面向对象设计原则分类 3.1. 开闭原则 开闭原则.md 3.2. 里氏替换原则 里氏替换原则.md 3.3. 合成复用原则 合成复用原则.md 3.4. 接口隔离原则 接口隔离原则.md

  44. 6.1 OOP设计模式historical

    1. 什么是设计模式 - 针对某类问题,可复用的解决方案 2. 为什么需要设计模式 3. 设计模式分类 主要分成三类,创建型、结构型、行为型 3.1. 创建型 关注对象的创建 3.2. 结构型 关注类与类之间的组织方式 3.3. 行为型 关注对象之间的交互 4. 参考 - 什么是设计模式? \- 知

  45. 6.2 单例模式historical

    一个类有且仅有一个实例对象 1. uml 2. Java 2.1. 饿汉式 - MySingleton - Client - 特点 - 会在加载类后一开始就被初始化,即使这个实例没有被使用到 2.2. 懒汉式:对整个方法加锁 - 特点 - 只有在真正用到的时候才会创建实例 - 每次调用都要加锁,但其

  46. 6.3 代理模式historical

    1. 定义 不改变原有代码的基础上为类或者函数增加新功能。 我不想做跟我业务无关的东西 2. uml 3. Java 3.1. 静态代理 代理类在编译时生成,需要程序员自己手写 3.1.1. client 3.1.2. 代理 3.1.3. 被代理 3.2. 动态代理 代理类在运行时生成, 利用的ja

  47. 6.4 模板方法historical

    1. 定义 适用于某个算法整体步骤固定,某些部分易变化.可以把变化的部分抽象出来.如servlet的doGet()和doPost()方法 2. uml 3. Java 3.1. client 3.2. 固定步骤 4. Golang 4.1. 第一种 4.1.1. client 4.1.2. 模板方法

  48. 6.5 工厂方法historical

    相对于简单工厂有多个工厂类。我们可以传递具体工厂实例而不是具体的产品到子类中,当需要的时候再调用工厂实例的创建产品方法(等于把创建实例对象的时机延迟到子类中) 1. uml 2. Java 2.1. client 2.2. 工厂 2.3. 产品 3. Golang 3.1. 工厂 3.2. 产品 3

  49. 6.6 状态模式historical

    1. 定义 根据状态的不同选用不同的处理逻辑,用if else太恶心 与策略模式的区别在于策略模式每种策略都是为了完成同一件事,而状态模式则是为了完成不同的事 2. UML 3. Java 3.1. client 3.2. context 3.3. 状态 4. Golang 4.1. 状态 4.2.

  50. 6.7 构建者模式historical

    用于构建一个对象,这个对象由许多小对象组成,且流程复杂.如各种Builder. builder负责构建,director负责组装 1. uml 2. Java 2.1. client 2.2. 产品 2.3. 构造者 2.4. 装配者 3. Golang 3.1. client 3.2. 产品 3.

  51. 6.8 策略模式historical

    1. 定义 完成同一件事有多种不同的方式,根据不同的type选择不同的算法,用if else太恶心 与状态模式的区别在于策略模式每种策略都是为了完成同一件事,而状态模式则是为了完成不同的事 2. uml 3. Java 3.1. client 3.2. context 3.3. 策略 4. Gola

  52. 6.9 观察者模式historical

    1. 定义 - 某个对象状态更新,需要通知给所有对象:广播 - 由两个角色:目标、观察者 - 观察者观察目标(监听目标) - 目标发生变化 - 目标主动通知观察者。 2. UML 3. Java 3.1. client 3.2. 被观察的对象 3.3. 观察者 4. Golang 4.1. 主题 4

  53. 6.10 装饰器模式historical

    1. 定义 不改变原有代码的基础上为类或者函数增加新功能。 我增强我自己的业务功能 2. uml 3. Java 3.1. client 3.2. 原有对象 3.3. 新增功能 4. Golang 4.1. 原有对象 4.2. 新增功能 4.3. client 5. 参考 - Java中“装饰模式”

  54. 6.11 责任链historical

    1. 定义 能处理同一类请求的对象连成一条链,servlet filter 2. uml 3. Java 3.1. client 3.2. 处理链 3.3. 请求 4. Golang 4.1. client 4.2. 处理链 4.3. 请求 5. 实例 5.1. 过滤器链 6. 参考 - niedb

  55. 6.12 适配器模式historical

    1. 定义 兼容旧系统的接口 2. uml 3. Java 3.1. client 3.2. 被适配 3.3. 转换器 4. Golang 4.1. 旧接口 4.2. 新接口 4.3. 转换器 4.4. client