https://juejin.cn/post/6844904003998842887

分布式锁的实现

https://juejin.cn/post/7041375517580689439
etcd实现分布式锁

CICD的区别

https://zhuanlan.zhihu.com/p/103554905

  • 持续集成是对仓库每次更新完就跟进测试,每次提交远程仓库时,CI工具都会重建分支,并运行所有相关的测试用例,以验证新更改不会破坏现有应用程序的运行。然而要实施持续集成,必须满足一些先决条件。

    1
    2
    3
    4
    条件如下
    为了使应用程序做好持续集成的准备,需要事先采取一些措施。最显而易见的是如果没有构建系统或测试要运行,则无法构建和测试应用程序。尽管看起来可能要花费额外的精力(特别是在代码没有进行过任何测试的情况下),持续集成可以带来很多好处。例如,自动化单元和集成测试能够在 bug 进入生产环境之前就捕获它们,这样一来更少的 bug 会被交付到生产中。事实上,防止一个潜在 bug 进入生产阶段的有效措施就是用一个测试用例覆盖它们,以确保它们不会导致产品回滚。除此之外,由于持续集成可以在短短几分钟内运行数百个测试用例,花费在手动测试上的时间也将大大减少,这意味着测试人员可以专注于更重要的改进而不是耗费大量精力在反复测试现有功能上。

    为了进一步开发和拓展持续集成机制以实现更高的自动化程度,我们引进了持续交付这一理念。
  • 持续交付
    每次代码更改通过测试时都要对其进行重新部署。把构建和测试,发布三阶段自动化了,运维人员只要点一下按钮就可以部署应用程序。

  • 持续部署
    部署则建立在交付之上。与持续交付相比,持续部署自动将代码更改部署到生产中而无需人工干预。这也意味着为了避免出现回滚和其他问题,您的测试包必须是一流的,因为它决定了您的发布过程。

项目团队将获取更快的部署速度,因为每项更改都可以进行自动处理,代码合并后几分钟就能够在生产环境中看到本地开发的功能;另一方面,代码发布的风险也能够进一步降低,因为您应该尽可能进行小批量部署,所以比较合适的场景是微服务和serverless场景。

serverless 和微服务的区别

  • 视频处理的后端系统,常见功能需求如下:视频转码、抽取数据、人脸识别等,这些均为通用计算任务,可由函数计算执行。
    aliyun serverless的场景

merge 和 rebase 的区别【合并方式和历史记录,冲突解决方式】

git merge:

  • 将目标分支的最新提交合并到当前分支,创建一个新的合并提交,保留了分支的历史记录。
  • 合并后会产生一个新的合并提交,记录了分支的合并操作。
  • 适合公共分支的合并

git rebase:

  • 将当前分支的提交“移动”到目标分支的最新提交之后,使得分支历史看起来更线性。
  • 实际上是将当前分支的提交重新应用在目标分支的最新提交之后,形成一系列新的提交。
  • 适合本地工作分支的合并
  • 然后rebase 合并一些提交记录
    git merge:
    保留了分支的整个历史记录,可以清晰地看到分支的合并过程。
    git rebase:
    使得分支历史看起来更加线性,但也会丢失了分支的原始历史记录。

    pull 和fetch的区别

  • fetch拉取最新代码,本身不会产生冲突,origin/branch1 会覆盖掉本底的暂存branch1
  • pull = fetch + merge,会产生冲突

stash的使用【在merge之前,把本地stash起来,或者当前版本需要临时存到一个分支里】

git rm的使用

  1. git rm file 删除暂存区和源文件
  2. git rm –cached file 删除暂存区文件
  3. git reset file 删除暂存区文件
  4. git restore –staged file 删除暂存区文件

强制切换分支,并丢弃当前内容

checkout -f branchname

切换到 某个提交 log查看提交hash,checkout过来

撤销一个commit

  1. 保留历史,丢弃提交
    git reset HEAD^
  2. 完全丢弃
    git reset –hard HEAD^
    git revert ,这会创建一个新的提交来撤销特定的提交,保留了提交历史。

如果你已经push,不推荐使用 git reset,因为它会改变历史记录,可能会影响其他开发者。
git revert 会创建一个新的提交,用于撤销指定的提交,这样可以保持提交历史的完整性。

git checkout 和reset 到指定版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1. checkout作用:
主要用于切换分支、切换到某个特定的提交、或者查看历史版本的内容。
影响:
切换分支或切换到特定提交时,会将工作目录和暂存区的状态更新为目标分支或提交的状态。如果是切换到特定提交,会处于“分离头指针”状态。
回滚版本:
不能用 git checkout 直接回滚到以前的版本。如果你只是想查看以前的版本,可以使用 git checkout <commit_sha> 来切换到特定提交。
1. reset作用:
用于重置当前分支的 HEAD 指针,可以将分支回退到以前的提交。
影响:
可以影响工作目录、暂存区和分支的状态,具体取决于使用的选项:
--soft:保留工作目录和暂存区,只重置 HEAD 指针。
--mixed(默认选项):重置 HEAD 指针和暂存区,但保留工作目录。
--hard:重置 HEAD 指针、暂存区和工作目录,丢弃所有本地的更改。
回滚版本:
可以用 git reset 回滚到以前的版本。例如,可以使用 git reset HEAD^ 将分支回滚到前一个提交。
总结:
如果你只是想查看以前的版本,可以使用 git checkout。
如果你想回滚到以前的版本,可以使用 git reset,但要注意谨慎使用,因为它会影响工作目录、暂存区和分支的状态,并且在共享分支上可能会影响其他开发者。

github和gitlab的区别

持续集成和持续部署的区别是什么,

持续集成(CI)注重的是团队成员之间的协作与代码的频繁集成。通过自动化的构建和测试流程,保证了每次提交的代码都能够顺利地融入共享代码库,从而快速发现并解决潜在的集成问题,使团队能够保持稳步前进。

而持续部署(CD)则是在持续集成的基础上,将通过CI验证的代码自动地部署到目标环境,实现了软件交付的高效、可靠,甚至是自动化。这使得开发团队能够以更迅速的速度向生产环境中推送稳定可靠的软件,为项目的成功交付提供了坚实保障。

慢SQL问题如何排查

如果你的数据库查询变慢了,可以采取以下步骤来找出问题并解决它:

  1. 找出慢查询:首先,找出哪些数据库查询很慢。通常,这些查询会花费很长时间才能返回结果。
  2. 检查查询计划:查看慢查询的执行计划,看看数据库是如何执行这些查询的。这可以帮助你找到性能瓶颈。
  3. 考虑索引:确保查询使用了适当的索引。有时候,缺少或错误使用索引会导致查询变慢。
  4. 优化SQL:审查慢查询的SQL语句,看看是否可以通过改写查询或者使用更有效的SQL来提高性能。
  5. 检查数据库服务器:确保数据库服务器有足够的资源来处理查询。不足的CPU、内存或磁盘IO可能会导致性能问题。
  6. 连接池:如果你在应用程序中使用了数据库连接池,确保连接池的配置正确。连接池的设置也可能影响性能。
  7. 数据库统计信息:查看数据库的统计信息,了解表的大小、索引情况和数据分布。这些信息可以指导你哪些地方需要优化。
  8. 查询缓存:考虑使用查询缓存,将经常执行的查询结果缓存起来,以减轻数据库负担。
  9. 分页查询优化:如果涉及到分页查询,确保使用了有效的分页查询方式,避免一次性获取大量数据。
  10. 监控和性能测试:建立监控系统,随时监测数据库性能。进行性能测试,模拟高负载情况,确保数据库在压力下能够正常工作。

explain的字段有哪些【主要看 type key rows extra】底层是查询优化器实现的,

  • id 查询序号

  • select_type 查询类型

  • table 表名

  • partitions 匹配的分区

  • type(主要) 查询使用了什么类型,是index还是全表扫描,同时用了index还会在extra里显示using index

    1
    system --> const --> eq_ref --> ref --> fulltext --> ref_or_null --> index_merge --> unique_subquery --> index_subquery --> range --> index --> ALL
  • prossible_keys 可能会选择的索引

  • key(主要) 实际选择的索引

  • key_len 索引的长度

  • ref 与索引作比较的列

  • rows(主要) 要检索的行数(估算值)

  • filtered 查询条件过滤的行数的百分比

  • Extra(主要) 额外信息,dictinct,using index,using filesort,using temporary,最好是using index,filesort和tmp都可能导致性能下降

select type有哪些

1
2
3
4
5
6
7
8
9
10
11
SIMPLE	简单SELECT(不使用UNION或子查询)
PRIMARY 最外层的SELECT
UNION UNION中第二个或之后的SELECT语句
DEPENDENT UNION UNION中第二个或之后的SELECT语句取决于外面的查询
UNION RESULT UNION的结果
SUBQUERY 子查询中的第一个SELECT
DEPENDENT SUBQUERY 子查询中的第一个SELECT, 取决于外面的查询
DERIVED 衍生表(FROM子句中的子查询)
MATERIALIZED 物化子查询
UNCACHEABLE SUBQUERY 结果集无法缓存的子查询,必须重新评估外部查询的每一行
UNCACHEABLE UNION UNION中第二个或之后的SELECT,属于无法缓存的子查询

type的详细内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。

1、system

表中只有一行数据或者是空表,这是const类型的一个特例。且只能用于myisam和memory表。如果是Innodb引擎表,type列在这个情况通常都是all或者index

2、const

最多只有一行记录匹配。当联合主键或唯一索引的所有字段跟常量值比较时,join类型为const。其他数据库也叫做唯一索引扫描

3、eq_ref

多表join时,对于来自前面表的每一行,在当前表中只能找到一行。这可能是除了system和const之外最好的类型。当主键或唯一非NULL索引的所有字段都被用作join联接时会使用此类型。

eq_ref可用于使用'='操作符作比较的索引列。比较的值可以是常量,也可以是使用在此表之前读取的表的列的表达式。

相对于下面的ref区别就是它使用的唯一索引,即主键或唯一索引,而ref使用的是非唯一索引或者普通索引。
eq_ref只能找到一行,而ref能找到多行。
4、ref

对于来自前面表的每一行,在此表的索引中可以匹配到多行。若联接只用到索引的最左前缀或索引不是主键或唯一索引时,使用ref类型(也就是说,此联接能够匹配多行记录)。

ref可用于使用'='或'<=>'操作符作比较的索引列。

5、 fulltext

使用全文索引的时候是这个类型。要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引

6、ref_or_null

跟ref类型类似,只是增加了null值的比较。实际用的不多。

eg.
SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;
7、index_merge

表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取多个索引,性能可能大部分时间都不如range

8、unique_subquery

用于where中的in形式子查询,子查询返回不重复值唯一值,可以完全替换子查询,效率更高。
该类型替换了下面形式的IN子查询的ref:
value IN (SELECT primary_key FROM single_table WHERE some_expr)

9、index_subquery

该联接类型类似于unique_subquery。适用于非唯一索引,可以返回重复值。

10、range

索引范围查询,常见于使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等运算符的查询中。

SELECT * FROM tbl_name
WHERE key_column BETWEEN 10 and 20;

SELECT * FROM tbl_name
WHERE key_column IN (10,20,30);
11、index

索引全表扫描,把索引从头到尾扫一遍。这里包含两种情况:
一种是查询使用了覆盖索引,那么它只需要扫描索引就可以获得数据,这个效率要比全表扫描要快,因为索引通常比数据表小,而且还能避免二次查询。在extra中显示Using index,反之,如果在索引上进行全表扫描,没有Using index的提示。

SQL的优化方式有哪些,优化方式可能根据业务

  1. 索引,在where或者需要orderby的字段使用索引,来避免扫全表
  2. Union创建临时表,或者创建view在业务中临时使用
  3. 创建联合索引
  4. 还有网上说的是join代替嵌套子查询,但是分布式,微服务场景下查的时候,可能就有些分库分表场景下的优化方式就不好说了
  5. 常用的方法是用索引单表查完之后在业务里做filter,merge之类的操作
  6. 如果仅用join,有俩原则,一个是小表驱动大表去连接,另外是on的字段要建上个索引;如果还是出现瓶颈的话,就调大join的buffersize

join buffer的底层

join buffer将参与join操作中的两个或者多个表数据缓存在内存中,以便在下一次进行相同的查询时可以直接从缓存中获取数据,而不必访问磁盘或索引。这样可以大大提高查询速度。

索引的优化方式有哪些?

  1. 在合适的列上建立索引,1.唯一性2经常用于where或者orderby的 3.可比较的

为什么有时候使用索引反而会降低性能

  1. 联合索引不满足最左覆盖的时候,索引失效,退化成全表扫描
  2. 索引碎片的东西,比如说如果建在经常修改删除的字段,可能产生不连续的区域,增加IO的压力
  3. 索引就失效了⁴。这时候MySQL就会退化为全表扫描,而不是利用索引进行快速定位

MYSQL 如果发现CPU,或者IO压力很大,怎么定位问题

1、首先用htop命令和iostat命令,定位是什么进程在占用cpu和磁盘io
2、sql执行show full processlist命令,看现在数据库在执行什么sql语句,是否有语句长时间执行使数据库卡住
3、执行show innodb engine status命令,查看数据库是否有锁资源争用
4、查看mysql慢查询日志/slow_query.log文件,看是否有慢sql
5、找到引起数据库占用资源高的语句,进行优化,该建索引的建索引,索引不合适的删索引,或者根据情况kill掉耗费资源的sql语句等

大表要如何优化

  1. 分区表:
    使用分区表将大表拆分为更小的、易管理的分区。根据数据的时间范围、地理位置等因素进行分区,可以提高查询性能和维护效率。
  2. 垂直切分:
    将大表按列进行垂直切分,将一部分列存储在一个表中,将其他列存储在另一个表中。这可以提高热数据的读取效率。
  3. 水平切分(分库分表),mysql分布式存到不同节点上。
    将大表数据水平切分成多个小表,每个小表存储部分数据。这样可以提高并发性能,使查询分散在不同的数据节点上。

    Redis Lua常用的命令

  • EVAL:EVAL script numkeys key [key …] arg [arg …]
  • EVALSHA:EVALSHA sha1 numkeys key [key …] arg [arg …]
    SCRIPT LOAD命令格式:SCRIPT LOAD script
    EVALSHA命令格式:

这两个命令放在一起讲的原因是:EVALSHA 命令中的sha1参数,就是SCRIPT LOAD 命令执行的结果。

  • SCRIPT LOAD
  • SCRIPT EXISTS
  • SCRIPT FLUSH
  • SCRIPT KILL

本地缓存如何选型

  1. ConcurrentHashMap
  2. golang的话,本地一级缓存和一用