TAG
Software_Engineering
55 篇笔记
- 1.1 架构historical
1. 什么是架构 在抽象层次上描述整体与局部以及他们之间的关系 2. 为什么需要架构 为了解决软件系统复杂度带来的问题 3. 架构分类 - 3.1. 基础架构 - 例如云平台、操作系统、网络、存储、数据库和编译器等 3.2. 中间件与大数据平台 - 中间件架构:例如分布式服务中间件、消息中间件、数据
- 1.2 架构模式historical
1. 单体架构 单体架构.md 2. 分层架构 分层架构.md 3. 事件驱动架构 事件驱动架构.md 4. CQRS架构 读写分离架构.md 5. 微服务架构 微服务.md 6. 可插拔架构 可插拔架构.md 7. 参考 - 架构模式 \- 维基百科,自由的百科全书
- 1.3 单体架构historical
1. 什么是单体架构 - 将所有功能打包在一个容器中运行的设计风格,一个实例中集成了一个系统的所有功能。通过负载均衡软件/设备实现多实例调用 - 2. 单体架构的优缺点 - 优点 - 开发简单 - 部署简单 - 测试简单 - 缺点 - 业务耦合度高导致修改复杂 - 扩展性差
- 1.4 分层架构historical
1. 什么是分层架构 根据系统中的角色/职责拆分和组织代码单元的常规实践 上层依赖下层,上层可以感知到下层,下层感知不到上层 2. 分层架构的演进 2.1. 一层 2.2. 两层 也叫单机架构 2.3. 三层 也叫集中式架构,C/S和B/S架构 2.4. DDD四层 2.4.1. 传统四层架构 用户
- 1.5 读写分离架构historical
1. 什么是读写分离 把读操作(R)和写操作(CUD)分开,本质上就是分布式系统复制中的Leader-Follower模式 2. 为什么需要读写分离 提高读吞吐量 3. 读写分离适用场景 读多写少且允许数据不一致 4. 如何设计读写分离 4.1. 服务层读写分离 优点:代码易维护且没有数据一致性问题
- 1.6 事件驱动架构historical
1. 什么是事件驱动架构 基于事件的一种软件架构模式 系统从A状态- B状态发布消息告知系统的其他部分 2. 为什么需要事件驱动架构 解耦:事件发起者并不知道哪个事件使用者在监听事件,而且事件也不知道其所产生的后续结果 异步 3. 事件驱动架构 对比请求驱动模式实时性差 4. 如何设计事件驱动架构
- 1.7 DDDhistorical
1. 什么是DDD 领域驱动设计,是一种架构方法 1.1. 领域 1.1.1. 什么是领域 领域就是业务的范围/边界,大领域可以划分成多个中领域,中领域又可以继续划分成小领域... 本质就和解决问题一样,采用分而治之的思想把复杂问题简单化,从而降低业务理解和系统实现的复杂度 1.1.2. 为什么需要
- 1.8 微服务historical
1. 什么是微服务架构 - 微服务架构是把单体应用 按功能模块拆分成一组服务 的架构 - 模块即服务,服务之间通过API通信 - 每个服务有自己独立的数据库 1.1. 微服务 vs SOA - 微服务架构是目前主流的构造分布式系统一种架构风格。它可以看做是SOA架构的一种变种或者是延伸 - 所谓分布
- 2.1 OpenId Connecthistorical
1. OpenID Connect是什么 - 一种认证协议 - OAuth只是用于授权,没有定义认证的规范 - 基于OAuth2 - 只是多了个标准化的UserInfo Endpoint 2. OpenID Connect流程 - 跟OAuth.md一样。 - 区别在于 - 再在OAuth第一步请求
- 2.2 JWThistorical
1. JWT是什么 - 用户认证成功后,服务器给用户发放的一种token - token是一定时间内有效的令牌,表明用户已经认证 2. 为什么需要JWT - 用于跨域认证 - 所谓跨域认证:指如果一个公司有两个域名A和B,那么用户在A域名认证后,访问B域名不用再次认证了 - 传统的跨域认证是cook
- 2.3 OAuthhistorical
1. OAuth是什么 - 一种授权协议 - 用来授权第三方应用,获取用户数据。 2. 为什么需要OAuth - 以使用微博登录简书,简书需要用到微博的头像昵称 - 传统的作法是输入微博的用户名+密码获取,这种有几个问题 - 微博用户名密码暴露给了简书,可能会泄露 - 只想获取微博头像昵称,但是简书
- 2.4 如何设计配置中心historical
1. 什么是配置中心 用来统一管理项目中所有配置的系统 2. 为什么需要配置中心 传统的配置是放在一个配置文件中,跟代码一起发布,这种每次修改了配置都要重新发布服务 而配置中心则是把配置存储在独立的配置服务器上,用户通过管理界面配置和调整服务配置,具体服务通过定期拉(Scheduled Pull)的
- 2.5 如何设计负载均衡组件historical
1. 什么是负载均衡 - 将请求(工作负载)平均的打到到多个机器上以提高性能和可用性 2. 为什么需要负载均衡 - 通过机器冗余提高可用性 - 便于横向扩展以提高性能和吞吐量 - 垂直扩展指更换性能更强劲的机器,价格自然更高,性价比不咋地 3. 如何实现负载均衡组件 3.1. 负载均衡算法有哪些 负
- 2.6 如何设计注册中心historical
1. 什么是注册中心 - 记录了 服务名<- IP地址+Port 的映射关系,本质上和DNS没区别 - 2. 为什么需要注册中心 没有注册中心那么A调用B只能写死IP地址,不灵活 3. 如何实现注册中心 3.1. 服务端 3.1.1. 服务注册表 2. 中心化、强一致存储中间件。比如Zookeepe
- 2.7 如何设计API网关historical
1. 什么是API网关 - 网关=路由器+过滤器 - 路由器:外部请求的入口(单点入口)。一般微服务都是部署在内网,所有外部请求都先经过网关,由网关转发到后端服务器(服务路由)。 - 过滤器:限流熔断、安全认证、日志监控等 2. 为什么要需要API网关 - 抽取公共逻辑 - 像授权认证的代码在每个服
- 2.8 如何设计监控系统historical
1. 什么是监控 - 日志监控(Log):把代码中的日志收集在一个地方,用来统一查询处理 - 度量监控(Metrics):记录事件发生的时间和数值,用来查看趋势 - 调用链监控(Tracing):记录一个请求的全部流程。用来查看请求经过了哪些节点,每个节点的耗时 2. 为什么需要监控 微服务架构由众
- 2.9 如何设计链路追踪historical
1. 什么是链路追踪 记录一个请求的全部流程。用来查看请求经过了哪些节点,每个节点的耗时 2. 为什么需要链路追踪 能快速定位一个请求在整个链路上哪个节点出了问题 3. 如何实现链路追踪 3.1. 上报什么数据 3.1.1. Span 3.1.1.1. Span是什么 - 每调用一个模块就生成一个S
- 2.10 如何设计容错组件historical
1. 什么是容错 微服务架构下,如果一个服务故障了,那么会影响到整个链路,导致服务整体不可用 2. 为什么需要容错 确保服务的可用性,防止雪崩效应 2.1. 服务雪崩 多个微服务之间调用的时候,假设服务A调用服务B和C,服务B调用服务D和E,服务C调用服务F和服务G...这就叫 扇出 因“服务提供者
- 2.11 如何设计日志监控historical
1. 日志监控是什么 把代码中的日志收集在一个地方,用来统一查询处理 2. 为什么需要日志监控 如果没有日志监控,那么需要登录上每台机器进行查询,效率很低 3. 如何实现日志监控 3.1. 输出日志 - 由应用程序打印日志,输出到本地文件 - 日志打印策略 - 区分日志等级 - 关键路径和异常路径
- 2.12 如何设计metrics监控historical
1. metrics监控是什么 记录事件发生的时间和数值,用来查看趋势 2. 为什么需要metrics监控 可以用来查看趋势,在出问题之前告警 3. 如何实现metrics监控 3.1. 监控什么数据 - 系统层: - 系统层主要是指宿主机和容器的监控, - 指标:CPU、磁盘、内存、网络等 - 中
- 2.13 如何设计认证授权historical
1. 什么是认证授权 - 认证:当前用户的身份,解决我是谁的问题 - 授权:什么样的身份被允许访问某些资源,解决我能做什么的问题 - 凭证:认证和授权的基础,一种标记访问者的身份或权利的媒介 2. 为什么要认证授权 安全 3. 认证授权技术 3.1. 认证技术 3.1.1. HTTP认证 Base6
- 3.1 ER图historical
1. 是什么 - 提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型 2. 例子 3. 参考 - Entity Relationship diagram syntax and features - 抽象思维实践——ddl2plantuml开发记录
- 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. 架
- 3.3 类图historical
1. 是什么 描述系统中的Class的属性和方法,以及Class之间的关系 2. 使用 2.1. 类和接口 + 表示public - 表示private 2.2. 类之间的关系 2.2.1. 泛化、实现 符号:三角形 泛化指extends一个类。 实线 实现指implement一个接口。虚线 2.2
- 3.9 架构图historical
1. 业务架构图 说明业务流程 2. 应用架构图 说明应用有哪些功能模块,用到了哪些技术 2.1. 功能视角 2.2. 技术视角 3. 技术架构图 4. 数据架构图 5. 安全架构图 6. 部署架构图 7. 4+1视图 7.1. Use-Case View - 描述软件系统的用户以及用户能做什么 -
- 4.1 函数式选项模式historical
1. 定义 - 创建由默认值的对象,同时可以灵活地修改属性 - 我们可能需要为Option的字段指定默认值 - Option的字段成员可能会发生变更 2. Golang 2.1. 要创建的对象 2.2. 测试 3. 参考 - Go语言设计模式之函数式选项模式 \ 李文周的博客
- 4.2 接口型函数historical
1. 接口型函数是什么 一个实现了接口的函数类型,简称为接口型函数 2. 为什么需要接口型函数 既能够将普通的函数类型(需类型转换)作为参数,也可以将结构体作为参数,使用更为灵活,可读性也更好,这就是接口型函数的价值。 3. 实现 4. 参考 - Go 接口型函数的使用场景 \ 极客兔兔
- 4.3 事件溯源模式historical
1. 什么是事件溯源 基于事件的一种软件架构模式 系统的CUD事件进行持久化 2. 为什么需要事件溯源 传统的CRUD存在一些问题 1. 直接操作数据库,而数据库性能比较低 2. 为了防止并发问题需要引入锁、事务等,引发性能上的损失 3. 因为数据存储中通常保存的是数据最终的状态,所以为了追踪数据变
- 4.4 发布订阅模式historical
1. 发布订阅模式是什么 - 有三个角色:发布者、事件中心、订阅者 - 订阅者需要向事件中心订阅指定的事件 - 发布者向事件中心发布指定事件内容 - 事件中心通知订阅者 - 订阅者收到消息 2. 为什么需要发布订阅模式 - 解耦 - 发布者只关注生产数据,不关心订阅者怎么消费 - 订阅者只关注消费数
- 4.5 生产者消费者模式historical
1. 生产者/消费者模式是什么 - 有三个角色:生产者、消费者、队列 - 生产者生产完数据丢入队列,消费者从队列取出数据消费 2. 为什么需要生产者/消费者模式 - 解耦 - 生产者只关注生产数据,不关心消费者怎么消费 - 消费者只关注消费数据,不关心生产者怎么生产 - 异步 3. 生产者/消费者模
- 5.1 开闭原则historical
1. 什么是开闭原则 对扩展开放,对修改关闭 2. 为什么需要开闭原则 降低维护带来的新风险 3. 开闭原则实现 新需求修改代码的时候看下会不会修改到原有的代码,有的话需要重构:通过接口或者抽象类定义抽象层,将可变因素封装在具体实现类中 继承:里氏替换原则.md 组合/聚合:合成复用原则.md 4.
- 5.2 里氏替换原则historical
1. 什么是里氏替换原则 不要破坏继承体系,子类重写方法功能发生改变,不应该影响父类方法的含义 开闭原则在继承中的体现 2. 为什么需要里氏替换原则 通过继承提高软件复用能力 3. 里氏替换原则实现 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法 子类中可以增加自己特有的方法 4. 参考 -
- 5.3 依赖倒置原则historical
1. 什么是依赖倒置原则 高层不应该依赖低层 要面向接口编程,不要面向实现编程。 2. 为什么需要依赖倒置原则 提高可扩展性 3. 依赖倒置原则实现 每个类尽量提供接口或抽象类,或者两者都具备。 变量的声明类型尽量是接口或者是抽象类。 任何类都不应该从具体类派生而应该从抽象类派生。 使用继承时尽量遵
- 5.4 单一职责原则historical
1. 什么是单一职责原则 一个类只干一件事,实现类要单一 2. 为什么需要单一职责原则 提高代码的可读性 3. 单一职责原则实现 需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中 4. 参考 - 单一职责原则——面向对象设计原则
- 5.5 接口隔离原则historical
1. 什么是接口隔离原则 一个接口只干一件事,接口要精简单一 2. 为什么需要接口隔离原则 提高代码的可读性 解耦 3. 接口隔离原则实现 接口尽量小,一个接口只服务于一个子模块或业务逻辑。 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。 4. 参考 - 接口隔离原则——面向对象
- 5.6 迪米特法则historical
1. 什么是迪米特法则 不该知道的不要知道,一个类应该保持对其它对象最少的了解 2. 为什么需要迪米特法则 降低耦合度 3. 迪米特法则实现 从依赖者的角度来说,只依赖应该依赖的对象。 从被依赖者的角度说,只暴露应该暴露的方法。 4. 参考 - 迪米特法则——面向对象设计原则
- 5.7 合成复用原则historical
1. 什么是合成复用原则 尽量使用组合或者聚合关系实现代码复用,少使用继承 开闭原则在组合/聚合中的体现 2. 为什么需要合成复用原则 通过组合提高软件复用能力 3. 合成复用原则实现 将新对象作为原有对象的属性注入 4. 参考 - 合成复用原则——面向对象设计原则
- 5.8 OOP设计原则historical
1. 什么是面向对象设计原则 2. 为什么需要面向对象设计原则 提高代码的可维护性、可扩展性、可复用性 3. 面向对象设计原则分类 3.1. 开闭原则 开闭原则.md 3.2. 里氏替换原则 里氏替换原则.md 3.3. 合成复用原则 合成复用原则.md 3.4. 接口隔离原则 接口隔离原则.md
- 6.1 OOP设计模式historical
1. 什么是设计模式 - 针对某类问题,可复用的解决方案 2. 为什么需要设计模式 3. 设计模式分类 主要分成三类,创建型、结构型、行为型 3.1. 创建型 关注对象的创建 3.2. 结构型 关注类与类之间的组织方式 3.3. 行为型 关注对象之间的交互 4. 参考 - 什么是设计模式? \- 知
- 6.2 单例模式historical
一个类有且仅有一个实例对象 1. uml 2. Java 2.1. 饿汉式 - MySingleton - Client - 特点 - 会在加载类后一开始就被初始化,即使这个实例没有被使用到 2.2. 懒汉式:对整个方法加锁 - 特点 - 只有在真正用到的时候才会创建实例 - 每次调用都要加锁,但其
- 6.3 代理模式historical
1. 定义 不改变原有代码的基础上为类或者函数增加新功能。 我不想做跟我业务无关的东西 2. uml 3. Java 3.1. 静态代理 代理类在编译时生成,需要程序员自己手写 3.1.1. client 3.1.2. 代理 3.1.3. 被代理 3.2. 动态代理 代理类在运行时生成, 利用的ja
- 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. 模板方法
- 6.5 工厂方法historical
相对于简单工厂有多个工厂类。我们可以传递具体工厂实例而不是具体的产品到子类中,当需要的时候再调用工厂实例的创建产品方法(等于把创建实例对象的时机延迟到子类中) 1. uml 2. Java 2.1. client 2.2. 工厂 2.3. 产品 3. Golang 3.1. 工厂 3.2. 产品 3
- 6.6 状态模式historical
1. 定义 根据状态的不同选用不同的处理逻辑,用if else太恶心 与策略模式的区别在于策略模式每种策略都是为了完成同一件事,而状态模式则是为了完成不同的事 2. UML 3. Java 3.1. client 3.2. context 3.3. 状态 4. Golang 4.1. 状态 4.2.
- 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.
- 6.8 策略模式historical
1. 定义 完成同一件事有多种不同的方式,根据不同的type选择不同的算法,用if else太恶心 与状态模式的区别在于策略模式每种策略都是为了完成同一件事,而状态模式则是为了完成不同的事 2. uml 3. Java 3.1. client 3.2. context 3.3. 策略 4. Gola
- 6.9 观察者模式historical
1. 定义 - 某个对象状态更新,需要通知给所有对象:广播 - 由两个角色:目标、观察者 - 观察者观察目标(监听目标) - 目标发生变化 - 目标主动通知观察者。 2. UML 3. Java 3.1. client 3.2. 被观察的对象 3.3. 观察者 4. Golang 4.1. 主题 4
- 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中“装饰模式”
- 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
- 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