Skip to content

Commit

Permalink
feat: 修改一些文档格式、排版,整理侧边导航栏
Browse files Browse the repository at this point in the history
  • Loading branch information
142vip.cn committed Dec 5, 2023
1 parent 08e73a3 commit 1519251
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 195 deletions.
2 changes: 2 additions & 0 deletions docs/.vuepress/config/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {KoaSidebar} from "../../manuscripts/server-end/framework/koa/koa.sidebar
import {ExpressSidebar} from "../../manuscripts/server-end/framework/express/express.sidebar";
import {DesignPatternsSidebar} from "../../manuscripts/server-end/design-patterns/designPatterns.sidebar";
import {SequelizeOrmSidebar} from "../../manuscripts/server-end/orm/sequelize/sequelizeOrm.sidebar";
import {TypeormSidebar} from "../../manuscripts/server-end/orm/typeorm/typeorm.sidebar";

export default {
"/manuscripts/front-end": FrontEndSidebar,
Expand All @@ -32,6 +33,7 @@ export default {
"/manuscripts/server-end/base": BaseSidebar,
"/manuscripts/server-end/node-learn": NodeLearnSidebar,
"/manuscripts/server-end/orm/sequelize": SequelizeOrmSidebar,
"/manuscripts/server-end/orm/typeorm": TypeormSidebar,
"/manuscripts/develop-skill": DevelopSkillSidebar,
// "/manuscripts/solo-algorithm": soloAlgorithmSidebar,
"/manuscripts/read-books": ReadBooksSidebar,
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
251 changes: 132 additions & 119 deletions docs/manuscripts/battle-interview/problems/Node面试.md

Large diffs are not rendered by default.

55 changes: 29 additions & 26 deletions docs/manuscripts/battle-interview/problems/乐观锁和悲观锁.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,21 @@ permalink: /manuscripts/battle-interview/lock.html

# 乐观锁和悲观锁

```mindmap
root(锁)
(乐观锁)
(悲观锁)
```

## 乐观锁的实现

- 版本号机制
- CAS算法

都是采用预期值和原来的值进行比较,相同则允许操作
都是采用预期值和原来的值进行比较,相同则允许操作

### 什么场景下需要使用锁?

在多节点部署或者多线程执行时,同一个时间可能有多个线程更新相同数据,产生冲突,这就是并发问题。这样的情况下会出现以下问题:

- 更新丢失(分两类):一个事务更新数据后,被另一个更新数据的事务覆盖。
- 脏读:一个事务读取另一个事物未提交的数据,即为脏读。
- 幻读:B事务读取了两次数据,在这两次的读取过程中A事务添加了数据,B事务的这两次读取出来的集合不一样
- 不可重复读(Nonrepeatable Read):B事务读取了两次数据,在这两次的读取过程中A事务修改了数据,B事务的这两次读取出来的数据不一样
- `更新丢失`(分两类):一个事务更新数据后,被另一个更新数据的事务覆盖。
- `脏读`:一个事务读取另一个事物未提交的数据,即为脏读。
- `幻读`:B事务读取了两次数据,在这两次的读取过程中A事务添加了数据,B事务的这两次读取出来的集合不一样
- `不可重复读`:B事务读取了两次数据,在这两次的读取过程中A事务修改了数据,B事务的这两次读取出来的数据不一样

针对并发引入并发控制机制,即加锁。

Expand All @@ -37,46 +31,55 @@ root(锁)

### 版本号控制

使用version版本标识来确定读到的数据与提交时的数据是否一致。提交后修改版本标识,不一致时可以采取**丢弃和再次尝试**的策略。
使用`version`版本标识来确定读到的数据与提交时的数据是否一致。提交后修改版本标识,不一致时可以采取**丢弃和再次尝试**的策略。

### CAS算法

compare and swap (比较进行交换),CAS操作包含三个操作数
`Compare And Swap` : 先比较再进行交换,`CAS`算法包含三个操作数

- 内存位置(V)
- 预期原值(A)
- 新值(B)
- `内存位置(V)`
- `预期原值(A)`
- `新值(B)`

如果`内存位置的值V``预期原值A`相匹配,那么处理器会将该位置值更新为`新值B`。否则,处理器不做任何操作,会循环比较直到相等,整个比较赋值操作是一个`原子操作`
如果`内存位置的值V``预期原值A`相匹配,那么处理器会将该位置值更新为`新值B`
。否则,处理器不做任何操作,会循环比较直到相等,整个比较赋值操作是一个`原子操作`

有一点像在缓存中,添加标记去顶当前数据版本号,与预期原值进行比较
**有一点像在缓存中,添加标记去顶当前数据版本号,与预期原值进行比较**

CAS缺点:

(1)循环时间开销大:当内存地址V与预期值B不相等时会一直循环比较直到相等;
- `循环时间开销大`:当内存地址V与预期值B不相等时会一直循环比较直到相等;

- 只能保证一个共享变量的原子操作

(2)只能保证一个共享变量的原子操作;【jvm知识未理解】
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,就能说明它的值没有被其他线程修改过吗?

(3)如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那么我们就能说明它的值没有被其他线程修改过吗?很明显不是,因为在这段时间内它的值可能被改为其他值,然后又被改回A,那CAS操作就会认为它从来没被改过,这个问题就被称为 CAS 操作的“ABA” 问题;
> 很明显不是,因为在这段时间内它的值可能被改为其他值,
> 然后又被改回A,那CAS操作就会认为它从来没被改过,这个问题就被称为`CAS算法`操作的`ABA`问题;
ABA问题------> 互斥同步比原子类更加高效

### 数据库隔离级别

参考:<https://www.cnblogs.com/yubaolee/p/10398633.html>
> 参考:<https://www.cnblogs.com/yubaolee/p/10398633.html>
**读未提交(Read Uncommitted)**

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别是最低的隔离级别,虽然拥有超高的并发处理能力及很低的系统开销,但很少用于实际应用。因为采用这种隔离级别只能防止第一类更新丢失问题,不能解决脏读,不可重复读及幻读问题。
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别是最低的隔离级别,虽然拥有超高的并发处理能力及很低的系统开销,但很少用于实际应用。
因为采用这种隔离级别只能防止第一类更新丢失问题,不能解决脏读,不可重复读及幻读问题。

**读已提交(Read Committed)**

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别可以防止脏读问题,但会出现不可重复读及幻读问题。
这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。
这种隔离级别可以防止脏读问题,但会出现不可重复读及幻读问题。

**可重复读(Repeatable Read)**

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。这种隔离级别可以防止除幻读外的其他问题。
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。
**这种隔离级别可以防止除幻读外的其他问题。**

**可串行化(Serializable)**

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读、第二类更新丢失问题。在这个级别,可以解决上面提到的所有并发问题,但可能导致大量的超时现象和锁竞争,通常数据库不会用这个隔离级别,我们需要其他的机制来解决这些问题:乐观锁和悲观锁
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读、第二类更新丢失问题。
在这个级别,可以解决上面提到的所有并发问题,但可能导致大量的超时现象和锁竞争。
**通常数据库不会用这个隔离级别,需要其他的机制来解决这些问题:乐观锁和悲观锁**
79 changes: 40 additions & 39 deletions docs/manuscripts/battle-interview/problems/接口幂等.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ permalink: /manuscripts/battle-interview/interface-idempotent.html

# 接口幂等

> 参考:<https://www.cnblogs.com/jajian/p/10926681.html>
为了防止上述情况的发生,我们需要提供一个防护措施,对于同一笔支付信息如果我其中某一次处理成功了,
我虽然又接收到了消息,但是这时我不处理了,即保证接口的**幂等性**

为了防止上述情况的发生,我们需要提供一个防护措施,对于同一笔支付信息如果我其中某一次处理成功了,我虽然又接收到了消息,但是这时我不处理了,即保证接口的 **幂等性**
**幂等**是一个数学与计算机学概念,常见于抽象代数中。在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。

> 幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
>
> 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的,更复杂的操作幂等保证是利用唯一交易号(流水号)实现.
例如,`setTrue()`函数就是一个幂等函数,无论多次执行,其结果都是一样的,更复杂的操作幂等保证是利用唯一交易号(流水号)实现。

幂等性的核心特点:**任意多次执行所产生的影响均与一次执行的影响相同**

Expand All @@ -23,58 +23,59 @@ permalink: /manuscripts/battle-interview/interface-idempotent.html

## 幂等性实现方式

前端处理
前端处理

> 对于和web端交互的接口,我们可以在前端拦截一部分,例如防止表单重复提交,按钮置灰、隐藏、不可点击等方式。
对于和web端交互的接口,我们可以在前端拦截一部分,例如防止表单重复提交,按钮置灰、隐藏、不可点击等方式。

后端处理(重要):

- Token机制:前端重复连续多次点击的情况,请求前先获取token
- 数据库去重表:利用唯一索引---->系统容错性不高,瘫痪
- Redis实现: 过期唯一key
- **状态机**:假设当前状态是已支付,这时候如果支付接口又接收到了支付请求,则会抛异常或拒绝此次处理。

---

参考:<https://www.cnblogs.com/huaixiaonian/p/9577567.html>
- `Token机制`:前端重复连续多次点击的情况,请求前先获取token
- `数据库去重表`:利用唯一索引---->系统容错性不高,瘫痪
- `Redis实现`: 过期唯一key
- `状态机`:假设当前状态是已支付,如果支付接口又接收到了支付请求,则会抛异常或拒绝此次处理。

## 什么情况下需要保证接口的幂等性

在增删改查4个操作中,尤为注意就是增加或者修改,

- A: 查询操作,查询对于结果是不会有改变的,查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select是天然的幂等操作

- B: 删除操作,删除一次和多次删除都是把数据删除。注意:可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个,在不考虑返回结果的情况下,删除操作也是具有幂等性的
在增删改查4个操作中,特别注意增加操作和修改修改:

- C: 更新操作,修改在大多场景下结果一样,但是如果是增量修改是需要保证幂等性的,如下例子:
- 把表中id为XXX的记录的A字段值设置为1,这种操作不管执行多少次都是幂等的
- 把表中id为XXX的记录的A字段值增加1,这种操作就不是幂等的

- D: 新增操作,增加在重复提交的场景下会出现幂等性问题,如以上的支付问题
- `查询操作`:查询对于结果是不会有改变的,查询一次和查询多次,在数据不变的情况下,查询结果是一样的。`select`操作是天然的幂等操作
- `删除操作`:删除一次和多次删除都是把数据删除。注意:可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条 ,
返回结果多个,在不考虑返回结果的情况下,删除操作也是具有幂等性的
- `更新操作`:修改在大多场景下结果一样,但是如果是增量修改是需要保证幂等性的,例如:
- 把表中`id``XXX`的记录的A字段值设置为1,这种操作不管执行多少次都是幂等的
- 把表中`id``XXX`的记录的A字段值增加1,这种操作就不是幂等的
- `新增操作`:增加在重复提交的场景下会出现幂等性问题,例如:支付时重复请求问题

## 为什么需要幂等

概念:

> 幂等性是系统的接口对外一种承诺(而不是实现),承诺只要调用接口成功, 外部多次调用对系统的影响是一致的。这里的多次调用强调是指接口一致,参数一致的情况。
**幂等性是系统的接口对外一种承诺(而不是实现),承诺只要调用接口成功,外部多次调用(接口一致、参数一致)对系统的影响是一致的。**

幂等是为了保证重试机制不会带来数据重复,数据不一致等异常情况。
不管在单机还是分布式系统中,都存在因为网络抖动无法收到成功应答;重试补偿机制;用户无意识点击发起多次请求(业务意义上其实是同一条数据记录)等情况带来的相同参数多次调用相同接口的情况。
幂等是为了保证重试机制不会带来数据重复,数据不一致等异常情况。不管在单机还是分布式系统中,都存在因为:

## 如何做到幂等
- 网络抖动无法收到成功应答;
- 重试补偿机机
- 用户无意识点击多次发起请求(业务意义上其实是同一条数据记录)

1、有些接口本身就是幂等的,例如查询接口,当然这是在查询数据没有做变更的情况下;删除操作一般会带有待删除数据的唯一标识,最终结果都是删除,也是幂等的
等情况带来的相同参数、多次调用相同接口的情况

2、对于创建新数据的情况,采用唯一业务单号,业务上的唯一条件约束。
## 如何做到幂等

3、在执行更新操作的时候,可以先查再决定是否更新,但这因为是非原子操作,所以在分布式系统中会存在问题。
- 有些接口本身就是幂等的,例如:
- 查询接口,在查询数据没有做变更的情况下,查询操作是幂等的
- 删除操作一般会带有待删除数据的唯一标识,最终结果都是删除,也是幂等的

- 多版本控制,更新时候更新版本小于更新版本的数据 update t_xxx set name=#{newName} where version<#{version}
- 对于创建新数据的情况,采用唯一业务单号,业务上的唯一条件约束。

- 状态机控制,增加状态字段,状态可能是有先后顺序(例如订单状态总是从待付款到已付款),也可能各个状态互相可以转化(例如与第三方同步数据,同步状态可能从更新待同步直接就变成删除待同步了)
- 在执行更新操作的时候,可以先查再决定是否更新,但这因为是非原子操作,所以在分布式系统中会存在问题。
- `多版本控制`,更新操作时增加版本条件进行更新,例如: `update t_xxx set name=? where version< ?`
- `状态机控制`,增加状态字段,状态可能是有先后顺序,例如:订单状态总是从待付款到已付款。
也可能各个状态互相可以转化,例如:与第三方同步数据,同步状态可能从更新待同步直接就变成删除待同步了
- `定义去重表`,先在去重表中插入,成功执行后续操作
- `悲观锁``select for update`

- 定义去重表,先在去重表中插入,成功执行后续操作
对外提供接口为了支持幂等调用,接口有两个字段必须传:

- 悲观锁,select for update
- 来源source字段
- 来源方序列号seq字段

4、对外提供服务的接口如何做到幂等,对外提供接口为了支持幂等调用,接口有两个字段必须传,一个是来源source,一个是来源方序列号seq,这个两个字段在己方系统里面作为唯一标识符,后续在己方系统中使用以上的方法来保证幂等。
这个两个字段在己方系统里面作为`唯一标识符`,后续在己方系统中使用以上的方法来保证幂等。
22 changes: 17 additions & 5 deletions docs/manuscripts/server-end/orm/sequelize/Reame.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,27 @@ permalink: /manuscripts/server-end/orm/sequelize

# SequelizeORM

![](./images/sequelize-logo.png)

`Sequelize` 是适用于 `Oracle``Postgres``MySQL``MariaDB``SQLite``SQL Server`
等的现代数据库,支持 `TypeScript``Node.js``ORM`框架。具有可靠的事务支持、关系、急切和延迟加载、读取复制等功能。

## 基础教程

- 快速入门
- 数据库连接
- 模型
- 表模型
- 模型实例
- 数据类型
- 实例
- 索引
- 事物操作
- 查询操作
- OP运算符
- 钩子函数
- 关联关系
- 索引
- 事物

## 最佳实践

- CURD操作

## 参考

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions docs/manuscripts/server-end/orm/typeorm/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@ permalink: /manuscripts/server-end/typeorm
---

# TypeORM

![](./images/typeorm-logo.png)

`TypeORM` 是一个`ORM`框架,可以运行在 `NodeJS``Browser``Cordova``PhoneGap``Ionic``React Native``Expo``Electron`
平台上,可以与 `TypeScript``JavaScript`一起使用。

`TypeOrm`目标是始终支持最新的 `JavaScript` 特性并提供额外的特性以帮助开发任何使用数据库的应用程序。

不同于现有的所有其他 `JavaScript ORM`框架,`TypeOrm`可以以最高效的方式编写高质量的、松耦合的、可扩展的、可维护的应用程序。

## 基础教程

## 最佳实践

## 参考
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: 快速入门
permalink: /manuscripts/server-end/orm/typeorm/quick-start.html
---

# 快速入门
12 changes: 12 additions & 0 deletions docs/manuscripts/server-end/orm/typeorm/typeorm.sidebar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const TypeormSidebar = [
{
text: '基础教程',
prefix: 'tutorial',
children: [
{
text: '快速入门',
link: '快速入门.md'
}
]
}
]
6 changes: 0 additions & 6 deletions docs/manuscripts/server-end/orm/typeorm/快速入门.md

This file was deleted.

0 comments on commit 1519251

Please sign in to comment.