Browse Source

第一次提交,初始化

Sun1040084806 4 years ago
commit
8e1736a7da
100 changed files with 5733 additions and 0 deletions
  1. 1349 0
      Git学习笔记/A_Git详细学习笔记.md
  2. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210508171916951.png
  3. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210508182039450.png
  4. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510171915185.png
  5. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510172159472.png
  6. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180415796.png
  7. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180539437.png
  8. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180756184.png
  9. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180757993.png
  10. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510181329197.png
  11. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510181407805.png
  12. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210510183253770.png
  13. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210621171934972.png
  14. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210621172453710.png
  15. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210701180547401.png
  16. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/image-20210705115521085.png
  17. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/列出仓库中最大的几个对象及其文件名.png
  18. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/删除大文件前大小.png
  19. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/删除大文件后大小.png
  20. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/删除引用.png
  21. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/删除截图.png
  22. BIN
      Git学习笔记/A_Git详细学习笔记中的图片/强制提交.jpg
  23. 9 0
      Git学习笔记/README.md
  24. 393 0
      Git学习笔记/git与vim常见指令集.md
  25. 289 0
      Git学习笔记/你可能会忽略的 Git 提交规范摘录.md
  26. 367 0
      Git学习笔记/分支管理策略[Git工作流]学习笔记.md
  27. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702142024042.png
  28. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702144120442.png
  29. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702152422183.png
  30. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702152726339.png
  31. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702152841056.png
  32. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702153021942.png
  33. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702153327715.png
  34. BIN
      Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702154430932.png
  35. 342 0
      Git学习笔记/开发中必须要掌握的 Git 技巧摘录.md
  36. 84 0
      linux/centos网络配置.md
  37. 56 0
      linux/学习正则表达式.md
  38. 111 0
      前端/mock/Mock的使用.md
  39. 0 0
      前端/react/.md
  40. 60 0
      前端/react/1.react简介.md
  41. 80 0
      前端/react/2.react组件.md
  42. 43 0
      前端/react/3.生命周期.md
  43. 30 0
      前端/react/4.DOM的diffing算法.md
  44. 44 0
      前端/react/5.react脚手架.md
  45. 18 0
      前端/react/6.React ajax.md
  46. 55 0
      前端/react/7.React路由.md
  47. 187 0
      前端/react/8.路由总结.md
  48. 311 0
      后端/Mysql/1.MySQL基础课堂笔记.md
  49. 199 0
      后端/Mysql/2.MySQL多表&事务课堂笔记.md
  50. 255 0
      后端/Mysql/3.MySQL约束课堂笔记.md
  51. 11 0
      后端/Mysql/4.mysql启动报错.md
  52. 47 0
      大数据/K8S/1.K8S的基本概念.md
  53. 33 0
      大数据/K8S/10.集群的安全机制.md
  54. 24 0
      大数据/K8S/11.Ingress.md
  55. 136 0
      大数据/K8S/12.Helm.md
  56. 38 0
      大数据/K8S/13.持久化网络存储.md
  57. 58 0
      大数据/K8S/14.K8S集群监控.md
  58. 4 0
      大数据/K8S/15.kubsphere.md
  59. 10 0
      大数据/K8S/16.强制删除ns.md
  60. 275 0
      大数据/K8S/17.velero的使用.md
  61. 22 0
      大数据/K8S/2.构建K8S-kubeadm方式.md
  62. 187 0
      大数据/K8S/3.使用kubeadm快速部署一个K8s集群.md
  63. 22 0
      大数据/K8S/4.命令行工具kubectl.md
  64. 81 0
      大数据/K8S/5.Pod.md
  65. 44 0
      大数据/K8S/6.Controller-无状态.md
  66. 16 0
      大数据/K8S/7.Service.md
  67. 38 0
      大数据/K8S/8.Controller-有状态.md
  68. 19 0
      大数据/K8S/9.Secret.md
  69. 37 0
      大数据/docker/1.什么是docker.md
  70. 27 0
      大数据/docker/2.centos7安装docker.md
  71. 99 0
      大数据/docker/3.docker基本使用.md
  72. 14 0
      大数据/docker/4.docker数据卷.md
  73. 8 0
      大数据/docker/5.docker镜像加载原理.md
  74. 32 0
      大数据/docker/6.dockerfile文件.md
  75. 58 0
      大数据/docker/7.docker compose.md
  76. 13 0
      大数据/docker/8.docker可视化.md
  77. 75 0
      机器学习/谷歌云的使用/使用Google Colab.md
  78. 23 0
      煤矿项目问题汇总/无法启动人人项目.md
  79. BIN
      照片/20190324224152631.png
  80. BIN
      照片/clip_image002.jpg
  81. BIN
      照片/clip_image004.jpg
  82. BIN
      照片/image-20210416184645628.png
  83. BIN
      照片/image-20210628143454069.png
  84. BIN
      照片/image-20210628154743311.png
  85. BIN
      照片/image-20210629161212299.png
  86. BIN
      照片/image-20210629170139908.png
  87. BIN
      照片/image-20210629180552052.png
  88. BIN
      照片/image-20210629180901274.png
  89. BIN
      照片/image-20210629180953925.png
  90. BIN
      照片/image-20210629182003299.png
  91. BIN
      照片/image-20210630093930467.png
  92. BIN
      照片/image-20210630100843770.png
  93. BIN
      照片/image-20210701163336651.png
  94. BIN
      照片/image-20210701170610466.png
  95. BIN
      照片/image-20210701170803400.png
  96. BIN
      照片/image-20210701210351090.png
  97. BIN
      照片/image-20210701210558888.png
  98. BIN
      照片/image-20210702101021414.png
  99. BIN
      照片/image-20210705092042263.png
  100. BIN
      照片/image-20210705092333874.png

+ 1349 - 0
Git学习笔记/A_Git详细学习笔记.md

@@ -0,0 +1,1349 @@
+> 此笔记为 本人洪详细学习Git阶段记录笔记,本笔记将记录 较深入的学习git知识点
+>
+> 如果仅仅简单使用,可先只看(必看)本笔记的:①高层命令 ②分支部分 ③数据恢复 ④远程操作
+>
+> 但是git知识是一个整体,系统的学习下来在之后使用也能更加得心应手
+>
+> 本人笔记地址分享:[`全部笔记`](https://gitee.com/hongjilin/hongs-study-notes)、[`Git笔记`](https://gitee.com/hongjilin/hongs-study-notes/tree/master/%E7%BC%96%E7%A8%8B_%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0)
+>
+> ​															始于:2021-1-27    截至:2021-2-2
+
+# Git详细学习
+
+# #目录
+
+>[TOC]
+
+# Ⅰ-Git操作
+
+## 一、初始化
+
+> 该处是用来提交时当作签名使用的
+
+```shell
+git config --global user.name "我的用户名"
+git config --global user.email "我的邮箱"
+#删除配置信息
+git config --global --unset user.name
+git config --global --unset user.email
+```
+
+## 二、Git工作流程与区域
+
+### 1、区域
+
+1. 工作区
+
+   > 平时写代码的文件目录
+
+2. 暂存区
+
+   > git add 后提交暂存的地方
+
+3. 版本库
+
+   > git commit 后给你生成版本的地方,注意push是提交到远程仓库而不是版本库,请勿混淆
+
+### 2、工作流程
+
+> 每个项目都有一个Git目录(.git)他是Git用来保存元数据和对象数据库的地方.该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里的数据
+
+##### ①、在工作目录中修改某些文件
+
+>从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录,这些文件实际上都是从Git目录中的压缩对象数据库中提取出来的,接下去就可以在工作目录中对这些文件进行编辑
+
+##### ②、保存到暂存区域,对暂存区做快照
+
+> 暂存区域只不过是个简单的文件,一般都放在Git目录中,有时候人们会把这个区域的文件叫做索引文件,不过标准说法还是叫暂存区域
+
+##### ③、提交更新
+
+> 将保存区在暂存区域的文件快照永久转储到本地数据库(Git目录)中
+
+我们可以从文件所处位置来判断状态:如果是Git目录中保存着的特定版本文件,就属于提交版本;如果做了修改并已放入暂存区域,就属于已暂存状态;如果自上次去除后,做了修改但还没有放到暂存区域,就是已修改状态
+
+## 三、对象详解(底层命令)
+
+### 1、git对象
+
+> 1. key:val 组成的键值对(key是val相应的hash)
+>
+> ​		键值对在git内部是blob类型(git特有)
+>
+> 2. 存储数据文件内容,也称为数据对象
+
+##### ① 直接写入git对象方法与读取(存入".git/objects")
+
+```shell
+#将打印内容写入对象(git数据库)并且返回其相应哈希值
+echo "写入的对象内容" | git hash-object -w --stdin 
+#读取内容并不能直接cat读取,因为git存入时已经加密,需要如下代码 -p:内容  -t:类型
+git cat-file -p 存入对象的哈希值(此值可以由上一步得到) 
+#将文件写入git对象,即我们常见的版本控制中出现的
+git hash-object -w ./test.txt
+#查看Git存储的数据  返回其文件夹内的所有哈希文件
+find .git/objects -type f 
+```
+
+### 2、树对象
+
+> 树对象是存储键值 作用为控制版本,如我们的版本前回退 就是在操作这个对象的(指向改变)
+>
+> 作用就是生成快照
+>
+> 这个也是git的必杀特性,因为他的切换分支与版本都很快 只是指针切换
+
+#### 构建树对象
+
+> 我们可以通过 update-index , write-tree , read-tree 等命令来构建树对象并且塞到暂存区
+
+##### ① 利用 `update-index` 命令 创建暂存区
+
+>利用 `update-index` 命令 为test.txt文件的首个版本创建一个暂存区,并通过`write-tree`命令生成树对象
+
+```shell
+#1生成一个树对象
+git update-index --add --cacheinfo 100664(文件状态码:普通文件) 哈希值 对应文件名
+#生成快照(树对象)
+git write-tree
+#2 将第一个树对象加入第二个树对象,使其成为新的树对象
+git read-tree -prefix=bak 哈希值(树对象的)  
+git write-tree
+```
+
+##### ② 查看暂存区当前样子
+
+```shell
+git ls-files -s
+```
+
+### 3、提交对象
+
+> 1. 通过上述两个对象操作后,你会发现你已经生成了不同项目的快照,但是问题是:如果想重用这些快照,你必须记住所有三个 SHA-1(快照)哈希值 .但是,你也完全不知道是谁保存了这些快照,在什么时刻保存的,以及为什么保存这些快照.而以上这些,正是提交对象(commit object)能为你保存的基本信息
+> 2. 我们可以通过调用commit-tree命令创建一个提交对象,为此需要指定一个树对象的SHA-1值,为此需要指定一个树对象的SHA-1值 , 以及该提交的父提交对象(如果有的话,第一次将暂存区做快照就没有父对象)
+> 3. 真正的一个版本其实就是提交对象
+
+##### ① 创建提交对象
+
+```shell
+echo "first commit" |git commit-tree 树对象的哈希值
+```
+
+②指定一个树对象的SHA-1值 , 以及该提交的父提交对象
+
+```shell
+echo "second commit" | git commit-tree 提交的树对象哈希值 -p 父亲树对象哈希值
+```
+
+## 四、高层命令
+
+### 1、git add  .
+
+>1. 会将工作目录的修改,保存成git对象 `先到版本库,再到暂存区`,而不是直接到暂存区
+>
+>2. 在工作目录修改几个文件,就会生成几个git对象(一个文件对应一个git文件)
+>
+>3. 同一个文件,每次修改再add的时候都会生成一个新的git对象,是`增量`而不是覆盖
+>4. 所以说git是绝对安全的,就算我只存到暂存区没有提交 git也会给我保存
+>5. 只有后面提交的时候,才会根据暂存区内容给我生成树对象并存入版本区,然后加上我们的提交信息,才生成提交对象存入版本库
+
+```shell
+#相当于以下两个命令集合
+git hash-object -w 文件名(修改了多少个工作目录中的文件,就要被执行几次)
+git update-index ...
+```
+
+### 2、git  commit -m "注释内容"
+
+> 将暂存区提交到版本库
+
+```shell
+git write-tree
+git commit-tree
+```
+
+> 跳过暂存区存入(之前add过的,直接提交)
+
+```shell
+git commit -a -m ""
+```
+
+### 3、git init 
+
+> 初始化仓库 初始化后,在当前目录下出现一个名为.git的文件夹
+
+### 4、git status
+
+> 查看文件的状态
+
+### 5、git diff
+
+1. 当前做的那些更新没有暂存?
+
+   命令:`git diff`(不加参数直接输入git diff)
+
+2. 有哪些更新已经暂存起来准备好了下次提交
+
+   命令:`git diff --cached`或者`git diff --staged(1.6.1以上版本)`
+
+### 6、git log
+
+> 1. `git log`(不带参数)
+>
+>    `空格键`往下翻页 `b`向上翻页 `q`退出日志查阅
+>
+> 2. git log --oneline 
+>
+>    将日志信息拍成一行显示
+>
+> 3. git reflog
+>
+>    所有的日志信息
+>
+> 4. git log --oneline --decorate --graph --all
+>
+>    查看所有的分支信息命令
+
+### 7、git rm 
+
+> 删除工作目录对应的文件,再将修改添加到暂存区(如同删除后给你用了 `git add 文件名`)
+
+```shell
+#删除命令
+git rm 文件名 
+#直接提交修改,因为rm命令帮你提交到暂存区了
+git commit -m "xxx"
+```
+
+### 8、git mv
+
+>将工作目录中的文件进行重命名,再将修改添加到暂存区
+
+```shell
+git mv 原文件名  新文件名
+```
+
+## 五、配别名
+
+> Git并不会在你输入部分命令时自动推断出你想要的命令,如果不想每次都输入完整的Git命令,可以通过git config 文件来轻松为每一个命令设置一个别名
+>
+> 此处运行后将会写入你的配置文件,可以进入配置文件直接删除
+
+```shell
+git config --global alias.自定义命令 " `git` 命令后面的指令 "
+#如配置查看分支信息 "git log --oneline --decorate --graph --all"
+git config --global alias.logbranch "log --oneline --decorate --graph --all"
+#配置切换分支
+git config --global alias.co checkout
+#使用方式
+git logbranch
+```
+
+## 六、分支
+
+> 1. 前言:
+>
+>    几乎所有的版本控制系统都以某种形式支持分支.使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线.在很多版本控制系统中,这是略微低效的过程--常常需要完全创建一个源代码目录的副本,对于大项目来说,这会耗费很多时间,而Git的分支模型极其的高校轻量,是Git的必杀特性,也正因为这一特性,是的Git从众多版本控制系统中脱颖而出
+>
+> 2. 分支的本质:
+>
+>    `Git的分支,其实本质上是提交对象`,,所有的分支都有机会被HEAD引用(`HEAD一个时刻只会指向一个分支`),当我们有新的提交的时候 HEAD会携带当前持有的分支向前移动
+>
+>    Git的默认分支名字是master,在多次提交后,你其实已经有一个指向最后那个提交对象的master分支.他会在每次的提交操作中自动向前
+>
+>    注意:Git的"master"分支并不是一个特殊分支.她就跟其他分支完全没有区别.之所以几乎每个仓库都有master分支,是因为`git init`命令默认创建它,并且大多数人懒得区改动它
+>
+> 3. 分支的原理:
+>
+>    1. `.git/refs`目录中保存了分支及其对应的提交对象
+>
+>    2. 当运行类似于`git branch (branchname)`这样的命令时,Git会取得当前所在分支最新提交对应的SHA-1值,并将其加入你想要创建的任何新分支中
+>
+>    3. 当你执行`git branch (branchname)`时,Git如何知道最新提交的SHA-1值呢?答案是HEAD文件
+>
+>       `HEAD文件`是一个符号引用(stmbolic reference),指向目前所在的分支.所谓符号医用,意味着它并不像普通引用那样包含一个SHA-1值.它时一个指向其他引用的指针
+
+### 1、git branch 
+
+> 1. git branch(不加参数)
+>
+>    作用:`显示所有分支`信息
+>
+> 2. git branch 分支名
+>
+>    作用:`创建分支`
+>
+> 3. git branch -v
+>
+>    作用:查看每一个分支最后一次提交
+>
+> 4. git branch -d(-D强制删除) 分支名
+>
+>    作用:`删除分支`,小d需要你这个分支是干净的才能删除(如已合并)
+>
+> 5. git branch --merged 
+>
+>    作用:查看那些分支已经合并到当前分支
+>
+>    在这个列表中的分支名字前没有*号的分支通常可以使用`git branch -d` 删除掉
+>
+> 6. git branch --no-merged
+>
+>    作用:查看所有包含未合并工作的分支
+>
+>    尝试使用`git branch -d`命令删除在这个列表中的分支时会失败,如果真的想要删除分支并丢掉哪些工作,可以使用`-D` 选项爱强制删除它
+>
+> 7. git log --oneline --decorate --graph --all
+>
+>    作用:查看所有的分支信息命令
+>
+> 8. git branch 分支名 commitHash
+>
+>    作用:新建一个分支,并且使分支指向对应的提交对象(版本穿梭`可以替代撤销与重置`)
+
+### 2、git checkout 分支名
+
+> 作用:`切换分支`  checkout还有其他作用,后面会提到
+>
+> 它会动三个地方:HEAD(指针) 暂存区 工作目录
+
+> 1. `注意`:分支切换会改变你工作目录中的文件,所以在切换分支时,一定要注意你的工作目录里的文件会被改变,如果时切换到一个比较旧的分支,你的工作目录会回复到该分支最后一次提交的样子,如果Git不能干净利落的完成这个任务,它将禁止切换分支
+>
+> 2. `坑`:在切换分支时, 如果当前分支上由未暂存的修改(`第一次`) 或者 有未提交的暂存`(第一次`) 分支可以切换成功,但是这种操作可能会污染其他分支
+>
+>    ps:`第一次`--当前分支如果已经提交过一次,将不让你切换,但是第一次没有提交过,git会帮你保存文件 但是它并不知道新增修改是属于哪个分支,所以会带回当前分支
+>
+> 3. 最佳操作方式:`每次在切换分支前,需要提交一下当前分支(先使用status查看状态)`
+
+### 3、git checkout -b "新的分支名"
+
+> 创建并进入该分支,类似于上面两个命令集合
+
+### 4、模拟实战流程
+
+>1. 需要解决主程序的的一个小BUG,所以使用`git  checkout -b "iss_bug"`新建分支并在这个分支进行bug调修
+>
+>2. 当你再`iss_bug`分支上开发到一半,这时,在主程序发现了一个紧急BUG需要你放下这个重要性为次要的bug进行修改.你老板都给你打了紧急电话,所以你需要先将写到一半的bug进行保存提交(`commit`提交或者储存  到暂存区,并不是提交合并到主分支,也不是push提交),确定status是干净的时候,切换回主分支,再用第一步的方法创建`hot_bug`分支(这时候`hit_bug`的版本是master没有进行`iss_bug`调修的版本),进行修复
+>
+>3. 当你将紧急bug修复后,进行提交,确定status干净后切换回master分支,进行合并:代码如下
+>
+> ```shell
+> git checkout master
+> git merge hit_bug
+> ```
+>
+>4. 修改完后再查看status(这是个好习惯,防止偶尔记忆混淆造成不必要的麻烦),再切换至普通bug分支`iss_bug`进行修改,成功后切换回去合并
+>5. 如果出现冲突,去出现冲突的文件手动修改(决定保留那部分代码),再进行`git add`表示冲突解决,在进行提交 
+
+### 5、合并分支
+
+> 命令: `git merge branchname`(分支名)
+>
+> 注意:合并分支时要先切换到`主要分支`(即下面的被合并分支),在这个分支上进行合并新分支,使得这个分支进行版本更新
+>
+> 1. 快进合并-->不会产生冲突
+>
+>    ​		指被合并分支并没有进行修改,停留在原地,只有新分支进行修改更新,更		新完成后进行合并,原版本相当于直接前进版本,称为快进合并
+>
+> 2. 典型合并-->有可能产生冲突
+>
+>    ​		指被合并分支在新分支进行开发时,本身也进行修改开发,可能会改动到同		一代码或者文件而产生重复修改
+>
+> 3. 解决冲突:`打开冲突的文件`  进行修改 ,修改完成后进行:`add标记修改完成`,然后commit进行提交
+
+>`git 在pull或者合并分支`的时候有时会遇到一个第一段是黄色,下面文字是青色(偏蓝色)。可以不管(直接下面3,4步),如果要输入解释的话就需要:
+>
+>1.按键盘字母 i 进入insert模式
+>
+>2.修改最上面那行黄色合并信息,可以不修改
+>
+>3.按键盘左上角"Esc"
+>
+>4.输入":wq",注意是冒号+wq,按回车键即可
+
+## 七、存储
+
+> 1. 需求背景:
+>
+>    有时,当你在项目的一部分上已经工作了一段时间后,所有东西都进入了混乱的状态,而这时你想要切换到另一个分支做一点别的事情.问题是,你不想仅仅因为过会儿回到这一点而做了一半的工作创建一次提交
+>
+> 2. 解决:
+>
+>    针对这个问题的答案是 `git stash` 命令(当然,直接提交`commit`也可以,这个是用来不想生成提交对象而用)
+>
+> 3. 原理:
+>
+>    git切换分支之所以保留你的未提交的修改文件,是因为它不想你因为误操作使得之前代码报废所以会当你status不干净时组织你切换分支(`ps`:如果是第一次创建的文件没有追踪过,它不认识是属于那份分支将会带到你切换后的分支造成污染),
+>
+>    而你将其保存到栈上(`ps`:换句话说将这部分内容抽取到一个类似共有的栈上,你在哪个分支都能够通过命令取到),git就知道你这个内容已经储存并不会造成切换分支使得你写的代码丢失,便不会阻止你切换分支或者切换带文件污染分支
+
+### 1、git stash
+
+> `git stash`命令会将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动(`git stash apply`),
+>
+> `注意!!!!!`:使用前你要先`git add .`,否则你会发现,你执行此命令后,没有追踪的部分全部消失了
+
+### 2、git stash list 
+
+> 查看存储
+
+### 3、git stash pop
+
+> 来应用储藏然后立即从栈上扔掉它 `这是最推荐的使用`
+
+#### 4、git stash apply stash@{2}
+
+> 如果不指定一个储藏,git认为指定栈顶`不常用`
+
+### 5、git stash drop "储藏的名字"
+
+>加上要储藏的名字移除他 `不常用`
+
+## 八、撤销与重置
+
+> 特别是重置部分理解即可(用到了再去查),撤销尽量可以掌握
+
+### 撤销
+
+#### 1、git commit --amend
+
+> 1. 这个命令会将暂存区中的文件提交,修订提交(`不是撤销而是重新提交`)
+>
+> 2. 如果自上次提交以来你还未做任何修改(如:在上次提交后马上执行此命令),那么快照会保持不变,而你修改的只是提交信息
+>
+> 3. 如果你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作
+>
+>    ```shell
+>    git commit -m "错误的注释" #或者commit了错误的修改
+>    git add "文件名或者."  #重新add正确的文件
+>    git commit --amend		#进行重新提交
+>    ```
+>
+>    最终你只会有一个提交 (第二次提交将会替代第一次提交)
+>
+> 4. 可以修改上次提交的文件与注释
+
+#### 2、git reset 
+
+>命令:`git reset HEAD 文件名`
+>
+>作用:将文件从`暂存区中撤回`到工作目录中
+
+#### 3、git checkout
+
+>是的,你没看错,这个是切换分支的命令,但是他也能用来`撤销文件修改`
+>
+>命令:`git checkout --文件名`
+>
+>将在工作目录中对文件的修改撤销
+>
+>`注意`:这是一个危险的命令,这很重要.你对那个文件做的任何修改都会消失--你只是拷贝了另一个文件(原来版本的文件)来覆盖它.除非你确实秦楚不想要那个文件了,否则不要使用这个命令
+
+### 重置reset
+
+> 注意:`--hard`标记是`reset`命令唯一的`危险用法`,也是Git真正的销毁数据的几个仅有操作之一.其他任何形式的`reset`调用都可以轻松撤销,但是`--hard`选项不能,因为它强制覆盖了工作目录中的文件.
+>
+> 如在这种特殊情况:我们的Git数据库中的一个提交内还留有该文件的几个版本,我们可以通过`reflog`来找回它,但若是该文件还未提交,Git仍会覆盖他导致它无法恢复
+
+#### reset三部曲
+
+>第一部:git reset --soft HEAD~(等于之前的--amend)
+>
+>​	移动HEAD (但带着分支一起移动,与checkout不同(它只动HEAD))
+>
+>第二部:git reset --mixed HEAD~
+>
+>​	移动HEAD 并且动了了暂存区
+>
+>第三部:git reset --hard HEAD~
+>
+>​	移动HEAD 并且动了了暂存区 动了工作目录
+
+## 九、数据恢复
+
+> 在你使用Git的时候,你可能会意外丢失一次提交:
+>
+> ①通常这是因为你强制删除了正在工作的分支,但是最后你却需要这个分支;②抑或是你硬重置了一个分支,放弃了你想要的提交.
+>
+> 如果这些事情已经发生,该如何找回你的提交呢?
+
+### 实例
+
+> 推荐方法最好是`直接看恢复`,上面实例时当你使用硬重置回当初未删除版本进行恢复,出现的一系列问题解决
+
+>1. 假设你已经提交了五次,而现在,我们将master分支硬重置到了第三次提交来找回当时删除的分支.但是这时候你会发现一个事情:
+>
+> 现在顶部的两个提交已经丢失了-没有分支指向这些提交(因为你将指针移到了第三个,那么前面两个就找不到了)
+>
+>2. 你现在已经得到并且恢复当时第三次还存在的的提交了(`恢复方法在下面,恢复文件到这步,下面3、4是回到最新版本`)
+>
+> 现在准备回到当初最新的版本时,你发现你进行打印竟然没有前面两次提交信息(你需要他的哈希值进行版本穿梭或者重置),你需要最新一次提交的哈希值,但是你估计想不起来了,对吗?
+>
+>3. 最方便,也是最常用的方法,是使用一个名叫`log reflog`的工具(前面高层命令提过),当你在工作时,Git会默默记录每一次你改变的HEAD时它的值,每一次你提交或者改变分支,引用日志都会被刷新
+>
+>4. 如果`git reflog`显示的内容你觉得不足够多,可以执行`git log -g`,这个命令会以标准日志的格式输出引用日志
+
+### 恢复 `推荐的`
+
+> 1. 通过`git reflog`找到你需要的文件还未删除的版本哈希值,那个就是你丢失的提交,你可以通过创建一个新的分支指向这个提交来恢复它.
+>
+>    例如:你可以创建一个名为`recover-branch`的分支执行这个提交
+>
+>    ```shell
+>    git branch recover-branch 当前需要恢复(之前丢失的)的提交哈希值
+>    ```
+>
+> 2. 现在有一个名为`recover-branch`的分支是你的`master`分支曾经指向的地方(即当时你删除该需要的文件的前的那个版本),这样你在这次提交的版本后,也能通过切换这个分支得到曾丢失的文件
+>
+> 3. 这个分支功能能帮你做很多东西,善用分支,Git最强功能
+
+## 十、打tag
+
+> Git可以给历史中的某一次提交打上标签,表示重要.比较有代表性的是人们会用这个功能来`标记发布节点`(v1.0等等)
+
+### 1、列出标签
+
+>命令:`git tag` 或者 `git tag -l 'v1.*'`
+>
+>​	前者列出所有,后者列出以`v1.`开头的所有
+
+### 2、创建标签
+
+> git使用两种主要类型的标签:轻量标签 与 附注标签
+
+##### ①轻量标签
+
+> 轻量标签很像一个不会改变的的分支(他只是一个特定提交的引用),直接在提交前使用命令即可给当前分支打上标签
+
+```shell
+git tag v1.0
+#或者下面的
+git tag v1.0 提交对象哈希
+```
+
+##### ②附注标签
+
+> 附注标签是存储在Git数据库中的一个完整对象.他们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间;通常`建议创建复制标签`,这样你可以拥有以上所有信息,但如果只是想用一个临时标签,或者由于某些原因不想表村那些信息,轻量标签也是可用的
+
+```shell
+git tag -a v1.0
+git tag -a v1.0 提交对象哈希
+git tag -a v1.0 提交对象哈希 -m "我的注释信息"
+```
+
+### 3、查看特定标签
+
+> `git show` 可以显示任意类型的对象(git对象 树对象 提交对象 tag对象)
+>
+> 命令: `git show tagname`
+
+### 4、删除标签
+
+> 1. 删除标签 要删除你在本地仓库上的标签,可以使用命令 `git tag -d <tagname>`如下:
+>
+>    ```shell
+>    git tag -d v1.0
+>    ```
+>
+> 2. 应该注意上述命令并不会从任何远程仓库中移出这个标签,你必须使用`git push <tamote>:refs/tags/<tagname>`来更新你的远程仓库,如下
+>
+>    ```shell
+>    git push origin :refs/tags/v1.0
+>    # origin是你配置的远程仓库地址别名,你可以直接用远程仓库地址
+>    ```
+
+### 5、捡出标签
+
+> 1. 如果说你想查看某个标签所指向的文件版本,可以使用`git checkout`命令
+>
+>    ```shell
+>    git checkout tagname
+>    ```
+>
+> 2. 虽然说这会使得你的仓库处于"分离 头指针(deacthed HEAD)"状态.在"分离头指针"状态下,如果你做了某些更改然后提交它们,标签不会发生变化,但你的新提交将不属于任何分支,并且将无法访问,除非访问确切的提交哈希,因此你如果需要进行更改--比如说你需要`修复旧版本`的错误--这通常需要创建一个新的分支(捡出后创建,就会默认将当前捡出的版本作为新分支的第一版本-前面分支提到过)
+>
+>    这样就可以修改到旧版本的代码(如同vue的尤雨溪在vue3.x会更新vue1.0版本生态)
+>
+>    ```shell
+>    git checkout -b version(新的分支)
+>    ```
+
+# Ⅱ-代码风格
+
+## 1、Eslint
+
+> ESlint是一个开源的JavaScript代码检查工具,由红宝书作者创建
+>
+> 初衷是为了让程序员可以创建自己的检测规则.ESLint的所有规则都被设计成可插入的
+>
+> ESLint使用Node.js编写,这样既可以有一个快速的运行环境同时也便于安装
+>
+> 此处引入概念,具体学习之后将开新的笔记
+
+## 2、commit提交规范
+
+>1. [参考自阮一峰老师的文章](http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html)
+>
+>2. Header
+>
+> Header部分只有一行,包括三个字段:`type`(必需)、`scope`(可选)和`subject`(必需)。
+>
+> **(1)type**
+>
+> `type`用于说明 commit 的类别,只允许使用下面几个标识。
+>
+> > ```js
+> > feat:新功能(feature)。
+> > fix/to:修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。
+> > fix:产生diff并自动修复此问题。适合于一次提交直接修复问题
+> > to:只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fix
+> > docs:文档(documentation)。
+> > style:格式(不影响代码运行的变动)。
+> > refactor:重构(即不是新增功能,也不是修改bug的代码变动)。
+> > perf:优化相关,比如提升性能、体验。
+> > test:增加测试。
+> > chore:构建过程或辅助工具的变动。
+> > revert:回滚到上一个版本。
+> > merge:代码合并。
+> > sync:同步主线或分支的Bug。
+> > ```
+>
+> 如果`type`为`feat`和`fix`,则该 commit 将肯定出现在 Change log 之中。其他情况(`docs`、`chore`、`style`、`refactor`、`test`)由你决定,要不要放入 Change log,建议是不要。
+>
+> **(2)scope**
+>
+> `scope`用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
+>
+> **(3)subject**
+>
+> `subject`是 commit 目的的简短描述,不超过50个字符。
+>
+> > - 以动词开头,使用第一人称现在时,比如`change`,而不是`changed`或`changes`
+> > - 第一个字母小写
+> > - 结尾不加句号(`.`)
+
+# Ⅲ-远程操作
+
+>三个必须懂的概念
+>
+>1. 本地分支
+>
+>   工作目录中的分支
+>
+>2. 远程跟踪分支
+>
+>   当你往远程分支`push`(还有克隆)的时候会创建远程跟踪分支
+>
+>3. 远程分支
+>
+>   指保存在git网站上的那个远程仓库中的分支
+
+### 1、团队协作流程
+
+>1. 项目经理初始化远程仓库
+>
+>     一定要初始化一个空的仓库:再github上操作
+>
+>2. 项目经理创建本地仓库
+>
+>     1. `git remote 别名 仓库地址`
+>     2. `git --init`,然后将源码复制进来
+>     3. 修改用户名 修改邮箱(双账号的才需要这步)
+>     4. `git  add` 和 `git commit`
+>
+>3. 项目经理推送到本地仓库到远程仓库
+>
+>     1. 清理window凭据
+>     2. `git push 别名 分支`(输入账号密码;推完之后会附带生成远程跟踪分支) 
+>
+>4. 项目邀请成员&&成员接受邀请
+>
+>     在git网站上操作
+>
+>5. 成员克隆远程仓库
+>
+>     `git clone 仓库地址`
+>
+>     只有在克隆的时候 本地分支master 和 远程跟踪分支别名/master 是有同步关系的(可以直接pull或者push后面不用加origin)
+>
+>     原因是,每次你push的时候是你远程跟踪分支替换掉(同步)你的远程分支,如果你想要新分支能直接push,需要本地分支去追踪远程追踪分支
+>
+>6. 成员做出贡献
+>
+>     1. 修改源代码文件
+>     2. `git add -> commit -> push`
+>
+>7. 项目经理更新修改
+>
+>     1. `git fetch 别名`(将修改同步到远程跟踪分支上)
+>     2. git merge 远程跟踪分支
+
+### 2、远程库
+
+> 正常的数据推送 和 拉取步骤
+>
+> 1. 确保本地分支已经跟踪了远程跟踪分支
+> 2. 拉取上传数据: git `pull` or `push`
+
+####  Ⅰ-远程跟踪分支
+
+> 流程与释义:
+>
+> 1. `远程跟踪分支`是远程分支状态的引用。它们是你不能移动的本地分支。当你做任何网络通信操作时,它们会自动移动
+>
+> 2. 它们以(remote)/(branch)形式命名,如果你想要看你最后一次与远程仓库origin时master分支的状态,可以查看origin/master分支
+>
+> 3. 当`克隆`一个仓库时,它通常会自动的创建一个跟踪`origin/master`的master分支(所以你可以不跟踪直接pull与push后面不跟origin)
+> 4. 当我克隆之后,别人新建了一个分支push上去,我这时候想要或者并且跟踪这个新分支,我需要先`git fetch origin`获取下来,获取下来后想要切换并且跟踪这个分支时使用命令`git checkout --track 远程跟踪分支名(origin/分支名)`
+
+##### 做跟踪:
+
+>1. 克隆仓库时,会自动为master做跟踪
+>
+>2. 本地没有分支,要新建分支且追踪
+>
+>   ```shell
+>   git checkout --track 远程跟踪分支(remote/分支名)
+>   ```
+>
+>3. 本地已经创建了分支,
+>
+>   ```shell
+>   git branch -u 远程跟踪分支(remote/分支名)
+>   ```
+
+#### Ⅱ-本地分支怎么跟踪远程跟踪分支
+
+> 1. 当克隆的时候 会自动生成一个master本地分支(已经跟踪了对应的远程跟踪分支)
+>
+> 2. 在新建其他分支时,可以指定想要跟踪的远程跟踪分支
+>
+>    ```shell
+>    git checkout -b 本地分支名 远程跟踪分支名
+>    #简写形式
+>    git checkout --track 远程跟踪分支名(origin/分支名)
+>    ```
+>
+> 3. 将一个已经存在的本地分支 改成 一个跟踪分支
+>
+>    ```shell
+>    git branch -u 远程跟踪分支名
+>    ```
+
+#### Ⅲ-冲突
+
+>1. git本地操作会不会有冲突?
+>
+>   典型合并的时候(如新建分支合并时)
+>
+>2. git远程协作的时候会不会有冲突
+>
+>   `push`与`pull`
+
+>解决流程:
+>
+>1. 假设你修改了a.js的代码,已经`add &&commit`(必须先这样才能提交,才能触发冲突)
+>
+>2. 但是这时别人也改了a.js同一行代码并且已经push上去了,你这时候进行push将会报错
+>
+>3. 这时候你需要先将其pull下来,这时候你会发现你的git将会给你提示,并且在本地的a.js中文件代码中,保留了你们两个的代码(并且会给你标注出来)
+>
+>4. 这时候一定要去与`与你冲突的开发人员交流`,讨论保留哪一个人的代码,或者进行修改(直接在你pull后的本地目录中修改),修改完成后使用`git add .`标记解决冲突然后`push`提交,这样别人pull的时候git就知道这部分时保留哪部分代码,直接覆盖(即在一个地方更改然后标记提交即可)
+>
+>5. 如果你发生冲突`不进行沟通`,将别人代码`直接注释掉`,让自己代码能跑,那么--真的很爽
+>
+>   但是别人功能可能就炸了,这时候你会被暴打:smirk:
+>
+>   因为你解决冲突后(git add .)别人pull的时候并不会提示冲突,因为你用`add`标记解决了冲突,git认出来后会直接默认`覆盖`他的代码,不知不觉,你可能就毁了另外一个程序员美好的一天(莫名其妙的BUG导致加班),如果他没反应过来,可能就是两天甚至...,你到时候住院的时间也与这个成正比:smirk:
+
+#### Ⅳ- pull request 流程
+
+> ​	`如果你想要参加某个项目,但是并没有推送权限`,这时候可以对这个项目进行”派生“(`Fork`),派生是指GitHub将在你的空间创建一个完全属于你的项目副本,且你对其有推送权限.通过这种方式,项目的管理者不再需要忙着把用户添加到贡献者列表并给予它们推送权限.人们可以派生这个项目,将修改推送到派生出的项目副本中,并通过创建合并请求(pull request)让它们改动进入原版本库
+>
+> 基本流程:
+>
+> 1. 自己在git网站上fork的项目到自己空间中,下面的操作都是基于这个fork的项目
+> 2. 从master分支中创建一个新的分支
+> 3. 提交一些修改来改进项目
+> 4. 将这个分支推送到git上
+> 5. 创建一个`合并`请求(在网站上点击发送信息)
+> 6. 在网站上进行讨论,并且根据实际情况继续修改
+> 7. 项目的拥有者合并或者关闭你的合并请求
+>
+> 注意:
+>
+>  每次在发起新的`Pull Request`时 要去拉去最新的原仓库的代码 而不是自己fork的那个仓库
+>
+> ```sh
+> git remote add <源仓库名字(自己定义)> <仓库地址链接>
+> git fetch 远程仓库名字
+> git merge 对应的远程跟踪分支
+> ```
+
+------
+
+
+
+# Ⅳ-版本控制工具的使用基本原则
+
+## 1、精准的提交
+
+每次提交都是一个小儿完整的功能或者一个BUG的修复。不应该出现多个功能点一块提交或者多个BUG一起修复的情况。如果一旦发现提交的代码有问题,可以方便的会滚到改动之前的正确状态,不会影响到其他协作者开发进程。
+
+## 2、频繁的提交
+
+尽可能频繁的提交你的改动到远程仓库,这样,可以避免将来合并代码的时候产生大量的冲突以至于难以解决。同时,也可以让其他同事比较快的共享你的改动。
+
+## 3、不要提交不完整的功能
+
+如果你正在开发的新功能比较庞大,那么可以讲这个功能尽可能拆分为几个逻辑模块,并且要保证分次提交的逻辑模块不会影响到整个系统的正确性。如果你只是因为临时的一些事情需要切到别的分支或者是临时需要中断开发(比如说下班),那么应该使用`Stash`储藏功能来保存你的更改。   -->[相关知识点部分我跳转](#七、存储)
+
+## 4、提交前进行测试
+
+不要想当然的认为自己的代码是正确的,提交之前应该经过充分的测试才能提交,即使是提交到本地仓库,也应该进行测试,因为这些代码在未来会被推送到远程共享给你的同事。
+
+## 5、高质量的提交注释
+
+每次提交都应该包含完整的注释。团队成员应当遵循统一的提交规则,一般应当明确的体现出提交的类型以及具体的事情,例如 feat: add message list;
+
+## 6、遵循统一的流程规范
+
+Git 可以支持很多不同的工作流程:长期分支、功能分支、合并以及 rebase、git-flow 等等。选择什么样的开发流程要取决如下一些因素:项目开发的类型,部署模式和(可能是最重要的)开发团队成员的个人习惯。不管怎样,选择什么样的流程都需要得到所有开发成员的一致认可,并且一直遵循它。
+
+
+
+
+
+# Ⅴ- 实际遇到的问题与解决Mark
+
+## 1、将本地已有的一个项目上传到新建的git仓库的方法
+
+将本地已有的一个非git项目上传到新建的git仓库的方法一共有两种。
+
+### Ⅰ-  克隆+拷贝
+
+>第一种方法比较简单,直接用把远程仓库拉到本地,然后再把自己本地的项目拷贝到仓库中去。然后push到远程仓库上去即可。**此方法适用于本地项目不是一个git仓库的情况。**
+>
+>具体步骤如下:
+>
+>#### 1、首先克隆
+>
+>```bash
+>git clone git@github.com:yuanmingchen/tensorflow_study.git
+>```
+>
+>#### 2、然后复制自己项目的所有文件到刚刚克隆下来的仓库中
+>
+>#### 3、最后push到远程仓库上面去:
+>
+>```bash
+>git push -u origin master
+>```
+
+### Ⅱ-  强行合并两个仓库
+
+>第二种方法就是先将本地的项目初始化为一个git仓库,然后再强行合并本地仓库和远程仓库,由于这两个仓库是完全不同的两个仓库,所以直接pull都会报错,需要在pull的时候假加上–allow-unrelated-histories才可以pull成功。**此方法适用于本地项目已经是一个git仓库的情况。**
+>
+>具体步骤如下:
+>
+>#### 1、新建git仓库,将本地项目设置为一个git仓库。如果本地项目已经是一个git仓库了,请跳过这一步。在项目根目录下:
+>
+>```bash
+>git init
+>```
+>
+>#### 2、把当前目录下的已有文件全部加到刚刚新建的git仓库中:
+>
+>```bash
+>git add .
+>```
+>
+>#### 3、保存刚刚加入的文件,并书写保存信息:
+>
+>```bash
+>git commit -m "push current files"
+>```
+>
+>#### 4、将本地仓库与远程仓库关联起来:
+>
+>```bash
+>git remote add origin git@github.com:yuanmingchen/tensorflow_study.git
+>```
+>
+>#### 5、pull远程仓库的内容,更新本地仓库,使用–allow-unrelated-histories忽略本地仓库和远程仓库的无关性,强行合并(关键):
+>
+>```bash
+>git pull origin master --allow-unrelated-histories
+>```
+>如果不采用上述代码可以使用git rebase命令合并
+>```bash
+>git pull origin master 
+>git rebase FETCH_HEAD
+>```
+>或者直接在pull命令指定参数,pull默认为fetch+merge
+>指定参数为fetch+rebase
+>```bash
+>git pull origin master --rebase 
+>```
+>#### 6、把本地仓库的内容push到远程仓库:
+>
+>```bash
+>git push -u origin master
+>```
+>
+>然后就ok了。
+
+### Ⅲ- 强制合并仓库不保留原仓库文件
+>第三种方法不会保留原有仓库的东西
+>
+>#### 1、新建git仓库,将本地项目设置为一个git仓库。如果本地项目已经是一个git仓库了,请跳过这一步。在项目根目录下:
+>
+>```bash
+>git init
+>git add .
+>git commit -m "add some files"
+>```
+>#### 2、强制push
+>```bash
+>git remote add origin git@github.com:yuanmingchen/tensorflow_study.git
+>git push origin master --force
+>```
+
+
+### Ⅳ- 其他git命令
+
+>最后附上git的一些其他命令:
+>1、删除已将关联的远程主机
+>
+>```bash
+>git remote rm origin
+>```
+>
+>2、查看所有本地分支
+>
+>```bash
+>git branch -a
+>```
+>
+>3、新建一个分支,名字叫xf
+>
+>```bash
+>git branch xf
+>```
+>
+>4、切换分支到xf分支
+>
+>```bash
+>git checkout xf
+>```
+>
+>5、把远程分支的代码pull到本地分支:git pull <远程主机名> <远程分支名>:<本地分支名>
+>如:取回origin主机的master分支,与本地的xf分支合并,输入命令:
+>
+>```bash
+>git pull origin master:xf
+>```
+>
+>6、推送当前的分支,git push <远程主机名> <本地分支名>:<远程分支名>
+>PS:注意,分支推送顺序的写法是<来源地>:<目的地>,所以git pull是<远程分支>:<本地分支>,而git push是<本地分支>:<远程分支>。
+>如:把本地的xf分支推送到origin主机的master分支,输入命令:
+>
+>```bash
+>git push origin xf:master
+>```
+
+
+
+## 2、解决同一台电脑生成两份或多份ssh密钥、公钥映射两个或多个GitHub账号
+
+> 此解决方案由百度多个方案结合而来,截取对我有用部分
+
+### Ⅰ- 需求分析
+
+> 本人注册一个GitHub账户,用来分享本人自己的开源项目或者代码,同时,公司注册了一个GitHub账户,用来分享公司的开源项目。如果按照单个ssh公钥生成的方法则会把之前的公钥覆盖掉,这样将导致其中一方在下一次上传代码,本机和GitHub无法映射成功。
+>
+> 解决这个问题首先要明确如何生成单个ssh公钥。
+> ssh生成单个公钥命令:`ssh-keygen -t rsa -b 4096 -C "your_email@example.com"`。[如何生成ssh公钥](https://blog.csdn.net/mynameissls/article/details/50528048)
+> 上述命令会在当前`~/.ssh`目录下生成`id_rsa`和`id_rsa.pub`两个文件。其中`id_rsa`是私钥文件,`id_rsa_.pub`是公钥文件。
+> `id_rsa`和`id_rsa_.pub`文件都是通过一个邮箱号生成的,同一个公钥文件不可以配置两个不同GitHub账户(已测试)。
+> 那么两个GitHub账户就需要两个不同的邮箱号,来生成两组不同的公钥文件。
+
+### Ⅱ- 解决方案思路
+
+>命令:`ssh-keygen -t rsa -C "your_email@example.com" -f ~/.ssh/id_rsa_example`
+>示例:分别以791815567@qq.com和galaxysoft@sina.cn两个邮箱在`~/.ssh`目录下生成两级不同的公钥文件。
+>791815567@qq.com邮箱:`ssh-keygen -t rsa -C "791815567@qq.com" -f ~/.ssh/id_rsa_me`
+>galaxysoft@sina.cn邮箱:`ssh-keygen -t rsa -C "galaxysoft@sina.cn" -f ~/.ssh/id_rsa_galaxysoft`
+>生成过程可参考[如何生成单个ssh公钥](https://blog.csdn.net/mynameissls/article/details/50528048) 这篇文章。
+>执行完成后,会以`~/.ssh`目录下看791815567@qq.com邮箱对应的私钥文件`id_rsa_me`、公钥文件`id_rsa_me.pub`和galaxysoft@sina.cn邮箱对应的私钥文件`id_rsa_galaxysoft`、公钥文件`id_rsa_galaxysoft.pub`
+>分别在两个GitHub账户中添加对应的公钥信息即可,可参考[如何生成单个ssh公钥](https://blog.csdn.net/mynameissls/article/details/50528048) 这篇文章
+
+### Ⅲ- 生成新ssh key
+
+> 如果我们电脑上已经存在了一个ssh key,那么我们需要在我们电脑上生成第二个你想在本电脑上使用的id_rsa,使用命令:`ssh-keygen -t rsa -C "你的github注册邮箱"`。
+>
+> 下图红色标注部分会提示你把新生成的id_rsa存放到哪里,此处默认会存放在c盘的用户名下的.ssh文件夹下(即你第一个github用户ssh key存放的目录),因此我们需要输入路径/c/Users/DodoMonster/.ssh(注意此路径是你的系统盘下用户目录安放ssh密钥的目录,请使用自己电脑上相对应的目录),最后我以“id_rsa_me”重新命名了ssh key防止默认与已有的ssh key重复。
+>
+> > 在输入了路径后,会提示你输入提交项目时输入的验证密码,不输则表示不用密码,这是为了防止别人随便在你的项目上push东西,所以最好还是输入以下你的密码。回车,再重复输入确认回车即可。
+
+### Ⅳ- 添加新ssh key
+
+>默认SSH只会读取id_rsa,所以为了让SSH识别新的私钥,需要将其添加到SSH agent
+>使用命令:`ssh-add ~/.ssh/id_rsa_me`(后面的是自己取的名字)
+>
+>如果报错:Could not open a connection to your authentication agent.无法连接到ssh agent
+>可执行`ssh-agent bash`命令后再执行`ssh-add`命
+>
+>然后将公钥添加到git账号中 https://github.com/settings/keys
+
+### Ⅴ- 配置config文件
+
+> 查看.ssh文件中是否存在config文件
+>
+> 如果已存在则直接编辑config文件,命令:`vim config` #这是linux的命令,进入了vim界面后按`a或i或A或I`进入编辑模式,编辑完成后按esc键输入`:wq` 保存文件退出
+>
+> 如果不存在则需要创建config文件,命令:`touch config`,再对config文件进行编辑
+>
+> 对config文件进行配置填写:
+>
+> ```bash
+> #Default 第一个账号(123456@xxxx.com)
+> 
+> Host gsgit
+>     HostName gitee.com
+>     PreferredAuthentications publickey
+>     IdentityFile ~/.ssh/id_rsa_me
+>     
+>    
+> #second 第二个账号(38894403@xxxx.com)
+>     
+> Host mygit
+>      HostName gitee.com
+>     PreferredAuthentications publickey
+>     IdentityFile ~/.ssh/id_rsa
+> ```
+>
+> > 其中Host 后的名字可以随意方便自己记忆,但HostName必须为`github.com(或者其它git地址)。`
+
+### Ⅵ- 测试是否配置成功
+
+>使用命令:
+>
+>```bash
+>ssh -T git@zc
+>```
+>
+>出现欢迎语则为配置成功。
+>
+>注意:配置完成后,在连接Host不是github.com的github仓库时,远程库的地址要对应地做一些修改:
+>
+>而并非原来的git@github.com
+>
+>```shell
+>git clone git@gitee.com:hongjilin/cx.git
+>//改为
+>git clone git@mygit:hongjilin/cx.git
+>```
+>
+>这样每次连接都会使用id_rsa_me与服务器进行连接。
+>
+>配置至此,大功告成!
+
+###  Ⅶ- 问题Mark
+
+> 当我切换到另外一个账号提交时 commit的提交者仍寻找全局配置中的username作为签名 而不是当前本地库绑定提交账号的用户名(所以我用公司账号的`.ssh`配置绕过了组织检测,但是署名却用的是个人账户)
+>
+> 别小看这个BUG,挺恐怖的,下面举个我的栗子:
+>
+> ![image-20210621172453710](A_Git详细学习笔记中的图片/image-20210621172453710.png)
+>
+> 到这时候你可能觉得好像也没啥吧?但是我个人账号不是公司组织里面的(也不好解释)、计算公司个人绩效时也无法统计、之前版本还无法用搜索条件查找我个人账号(因为本身个人账号就不是组织里面的)的提交.....问题可大可小
+>
+> 所以此处`Mark`,留待后续学习生活解决
+
+#### 此问题解决
+
+> 之前只是将此问题Mark,但是未将解决方式具体写下,现将其更新
+>
+> ![image-20210621171934972](A_Git详细学习笔记中的图片/image-20210621171934972.png)
+>
+> 或者可以直接写个python小脚本来修改:如果根据该仓库clone时的账号来进行切换是否更合理,这是个好办法... 
+
+## 3、commit报错无法提交
+
+>```shell
+>> running pre-commit hook: lint-staged
+>[STARTED] Preparing...
+>[FAILED] warning: LF will be replaced by CRLF in sh.exe.stackdump.
+>[FAILED] The file will have its original line endings in your working directory.
+>[STARTED] Running tasks...
+>[SKIPPED] Skipped because of previous git error.
+>[STARTED] Applying modifications...
+>[SKIPPED]
+>[SKIPPED]   × lint-staged failed due to a git error.
+>
+>  × lint-staged failed due to a git error.
+>[STARTED] Cleaning up...
+>[SKIPPED]   × lint-staged failed due to a git error.
+>  Any lost modifications can be restored from a git stash:
+>
+>
+>pre-commit hook failed (add --no-verify to bypass)
+>```
+>
+>解决方式
+>
+>```shell
+>执行npm run lint, 根据提示修改错误(推荐)
+>git commit -m "" --no-verify 绕过了lint的检查
+>```
+
+
+
+## 4、Git提交时出现(`合并提示`)`Merge branch 'master' of ...`之解决方法
+
+>多人协作开发项目,在上传代码时通常会先pull一下远程代码,使本地与远程同步更新,但是如果远程此时与自己代码存在冲突,在解决冲突后提交有时会出现“Merge branch ‘master’ of …”这条信息。这是因为pull其本质是fetch+Merge的结合。通常会分为以下两种情况:
+>
+>1.如果远程分支超前于本地分支,并且本地也没有commit操作,此时pull会采用’fast-forward’模式,该模式不会产生合并节点,也即不产生"Merge branch ‘master’ of …"信息。
+>
+>2.如果本地有commit提交,此时若存在冲突,pull拉取代码时远程和本地会出现分叉,会进行分支合并,就会产生"Merge branch ‘master’ of …"信息。
+>
+>**解决方法**
+>
+>>使用`git pull --rebase`命令,如果没有冲突,则会直接合并,如果存在冲突,手动解决冲突即可,不会再产生那条多余的信息。如果你不想每次都rebase,可以在git bash里执行
+>>
+>>```shell
+>>git config --global pull.rebase true
+>>```
+>>
+>>这个配置就是告诉git在每次pull前先进行rebase操作。
+
+### ① 可能出现的相关报错`error:Cannot pull with rebase`
+
+>1. git 执行`git pull –rebase`后报错误如下:
+>
+>   ```sh
+>   error: cannot pull with rebase: Your index contains uncommitted changes.
+>   error: please commit or stash them.
+>   ```
+>
+>2. 原因:如果有未提交的更改,是不能git pull的
+>
+>3. 解决:
+>
+>   - 先执行`git stash`    -->#可用来暂存当前正在进行的工作
+>   - 再执行`git pull –-rebase`
+>   - 最后再执行`git stash pop`  -->#从Git栈中读取最近一次保存的内容
+>
+>4. 截图示例
+>
+>   ![image-20210705115521085](A_Git详细学习笔记中的图片/image-20210705115521085.png)
+
+### ② *防止冲突的有效操作*
+
+>不要直接用`git pull`拉取,而是分开操作,先拉取代码(拉取后可以先查看冲突部分取解决).随后再去合并
+>
+>1. `git fetch 别名`(将修改同步到远程跟踪分支上)
+>2. git merge 远程跟踪分支
+
+## 5、Git删除误提交的大文件历史记录
+
+>1. 应用场景:在我们日常使用Git的时候,一般比较小的项目,我们可能不会注意到.git 这个文件。其实.git文件主要用来记录每次提交的变动,当我们的项目越来越大的时候,我们发现.git文件越来越大。很大的可能是因为提交了大文件,如果你提交了大文件,那么即使你在之后的版本中将其删除,但是`实际上记录中的大文件仍然存在`。
+>2. 原因分析:为什么呢?仔细想一想,虽然你在后面的版本中删除了大文件,但是Git是有版本倒退功能的吧,那么如果大文件不记录下来,git拿什么来给你回退呢?
+>3. 导致的问题:.git文件越来越大导致的问题是--每次拉项目都要耗费大量的时间,并且每个人都要花费那么多的时间。
+>4. git给出了解决方案,使用git branch-filter来遍历git history tree, 可以永久删除history中的大文件,达到让.git文件瘦身的目的。
+>
+>下面给出步骤(以下步骤非常危险,`操作需谨慎!`,最好最好不要在公司项目中使用)
+
+### Ⅰ-列出仓库中最大的几个对象及其文件名
+
+>列出所有仓库中的对象(包括SHA值、大小、路径等),并按照大小降序排列,列出TOP 5(本人示例,你也可多展示)
+>
+>1. 命令示例
+>
+>   ```bash
+>   git rev-list --all --objects | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -n 5 | awk -F ' '  '{print $1}')"
+>   ```
+>
+>2. 图示
+>
+>   ![image-20210508171542001](A_Git详细学习笔记中的图片/列出仓库中最大的几个对象及其文件名.png)
+
+### Ⅱ-将某文件从历史记录中删除
+
+>既然文件找到了(此处删除`杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg`),那么得将该文件从历史记录中删除,执行以下命令:
+>
+>1. 命令示例:
+>
+>   ```bash
+>   git log --pretty=oneline --branches -- "杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg"
+>   ```
+>
+>2. 图示
+>
+>   ![image-20210508171916951](A_Git详细学习笔记中的图片/image-20210508171916951.png)
+
+### Ⅲ-重写所有 commit,将该文件从 Git 历史中完全删除
+
+>上面的命令执行后只是从历史记录中移除,还没有完全删除它,我们需要重写所有 commit,将该文件从 Git 历史中完全删除:
+>
+>1. 代码示例:
+>
+>   ```bash
+>   git filter-branch --index-filter 'git rm --cached --ignore-unmatch  "杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg"' -- --all
+>   ```
+>
+>2. 图示
+>
+>   ![](A_Git详细学习笔记中的图片/删除截图.png)
+>
+>3. 补充注意点:
+>
+>   如果你像我一样,工作区有新写的内容没有追踪与提交导致无法进行删除操作时,千万不要直接暂存`stash`,否则这些没有暂存的内容就没了,要记得先`git add .`
+
+### Ⅳ-把该文件的引用完全删除
+
+>上面的命令执行后,此时历史记录中已经没有该文件了,此时是真正删除了它。 不过我们运行 filter-branch 产生的日志还是会对该文件有引用,所以我们还需要运行以下几条命令,把该文件的引用完全删除:
+>
+>1. 命令示例:
+>
+>  ```bash
+>  rm -rf .git/refs/original/
+>  git reflog expire --expire=now --all
+>  git gc --prune=now
+>  git gc --aggressive --prune=now
+>  ```
+>
+>2. 图示
+>
+>  ![image-20210510183253770](A_Git详细学习笔记中的图片/image-20210510183253770.png)
+>
+>3. 果真编程其实殊途同归,该学的都得学,这里就暴露的Linux没学好的弊端,所以暗下决心,争取今年内将linux系统学习一遍
+
+### Ⅴ-强制提交
+
+>现在我们再看 .git 文件的大小明显变小了,少了那个大文件,说明我们之前误提交的大文件已经删除了。 最后一步就是 push 代码了,不过就是需要强制 push
+>
+>1. 命令示例
+>
+>   ```bash
+>   git push --force
+>   ```
+>
+>2. 图示
+>
+>   ![](A_Git详细学习笔记中的图片/强制提交.jpg)
+
+### Ⅵ-远程仓库GC
+
+>网上所能百度的方法中都没有说到要进行远程存储库GC,但是本人操作后发现,明明命令行中运行了`git gc`,但你的远程仓库仍然会非常庞大甚至更加庞大,也许你本地已经删减至几十兆,但是远程仓库已经"爆仓"达到`1300+兆`,详见`问题7`
+>
+>
+>
+>![image-20210510180757993](A_Git详细学习笔记中的图片/image-20210510180757993.png)
+
+### Ⅶ-删除前后`.git`大小对比
+
+>本人此时测试删除的文件正好为10M,成功删除
+>
+>1. 删除前截图
+>
+>  <img src="A_Git详细学习笔记中的图片/删除大文件前大小.png" style="zoom:67%;" />
+>
+>2. 删除后截图
+>
+>  <img src="A_Git详细学习笔记中的图片/删除大文件后大小.png" style="zoom:67%;" />
+>
+>3. 删除多个文件后
+>
+>   <img src="A_Git详细学习笔记中的图片/image-20210508182039450.png" alt="image-20210508182039450" style="zoom:67%;" />
+
+## 6、git出现文件夹后面跟`@+数字`问题
+
+>1. 问题出现场景:本人欲将两个仓库代码合到一个仓库中,但是原本文件夹内还有.git,导致这些文件夹push后变成了子模块
+>
+>2. 问题场景图例-->具体出问题时并没有截图,此处截图提交时差别(原本应该是一大堆V1.0的文件,结果只有一个文件夹,后面跟着哈希值)
+>
+>   ![image-20210510171915185](A_Git详细学习笔记中的图片/image-20210510171915185.png)
+>
+>3. 解决思路
+>
+>   >删除原来的子文件夹的.git  -->`rm -r .git`,当然也可以手动删除
+>   >
+>   >删除本地git缓存  -->`git rm -r --cached fileName`
+>   >
+>   >重新add,push 
+>
+>4. 解决结果截图
+>
+>   <img src="A_Git详细学习笔记中的图片/image-20210510172159472.png" alt="image-20210510172159472" style="zoom:67%;" />
+
+## 7、远程仓库过大导致无法push
+
+>问题出现场景:在前两天本人发现笔记仓库过大 已经达到600M的时候,本人花了一些时间将无用的大文件删除(详见`问题5`),并且减小到了100M+,然后推送上了gitee上,但是今天push的时候突然报错仓库过大无法推送
+>
+>1. 问题报错截图![image-20210510180415796](A_Git详细学习笔记中的图片/image-20210510180415796.png)
+>
+>2. 本人就产生很大的疑惑,明明我本地仓库才100+M,`.git`文件也才86M,但是远程仓库竟然达到了恐怖的1300M+(当时急于寻找解决方案,没有截图)
+>
+>   本人推测(不确定,也找不到人问,朋友都没经历过这个情况,所以引出记录待定,如果有小伙伴知道了希望可以发在评论区或者私信我)
+>
+>   1. 当时我是将多条命令一起复制进去运行,可能导致`git gc`命令没有运行到(可能性极小,但还是留下悔恨的泪水)
+>
+>   2. 也许本地的gc命令只是清理了本地仓库的,远程也要清理,但这个并不重要,知道了这个点后我们能进行解决了
+>
+>       <img src="A_Git详细学习笔记中的图片/image-20210510180539437.png" alt="image-20210510180539437" style="zoom:50%;" /><img src="A_Git详细学习笔记中的图片/image-20210510181407805.png" alt="image-20210510181407805" style="zoom:67%;" />
+>
+>3. 问题解决:
+>
+>    ![image-20210510180757993](A_Git详细学习笔记中的图片/image-20210510180757993.png)
+>
+>    GC后内存![image-20210510181329197](A_Git详细学习笔记中的图片/image-20210510181329197.png)
+>
+>   4. GC详解
+>
+>   >Git的底层并没有采用 CVS、SVN 底层所采用的那套增量式文件系统,而是采用一套自行维护的存储文件系统。当文件变动发生提交时,该文件系统存储的不是文件的差异信息,而是文件快照,即整个文件内容,并保存指向快照的索引。这种做法,提高 Git 分支的使用效率;但也容易导致代码仓库中内容重复程度过高,从而仓库体积过大。当遇到这种情况时,或者需要将仓库推送到远程主机时,就需要Git中的gc(garbage collect)功能,也就是`垃圾回收功能`。
+>   >
+>   >大体来说,当运行 "git gc" 命令时,Git会收集所有松散对象并将它们存入 packfile,合并这些 packfile 进一个大的 packfile,然后将不被任何 commit 引用并且已存在一段时间 (数月) 的对象删除。 此外,Git还会将所有引用 (references) 并入一个单独文件。
+>   >
+>   >就细节而言,Git做了这几件事:
+>   >
+>   >pack_refs 过程
+>   >reflog expire 过程
+>   >repack 过程
+>   >prune 过程
+>   >rerere 过程
+>   >
+>   >pack_refs 过程相当于执行"git pack-refs --all --prune",它会将$GIT_DIR/refs目录下的所有heads和tags打包成一个文件并保存为$GIT_DIR/packed-refs下。
+>   >
+>   >reflog expire 过程相当于执行"git reflog expire --all",它会将删除所有超过期限而且没有被refs涉及的reflog条目。
+>   >
+>   >repack 过程相当于执行"git repack -d -l",一般情况下还会包括"-A"选项,它会将所有未被包含在一个pack的松散对象连结成一个pack,也会将现有的pack重新组织为一个新的更有效率的pack,并删除冗余的pack(如果她们中存在不可达的松散对象,会先把这些对象释放出来)。
+>   >
+>   >prune 过程相当于执行"git prune --expire",他会删除所有过期的、不可达的且未被打包的松散对象。
+>   >
+>   >rerere 过程相当于执行"git rerere gc",这种情形下似乎没什么用。
+>   >
+>   >所以本人推测应该是进行了`问题5`操作后还需要`进行一次GC操作`
+
+## 8、Git GUI中文乱码问题解决方法
+
+>当我们使用Git GUI的查看代码的时候,有时候会出现中文乱码:
+>
+>1. 解决方案1:直接在`GIT GUI`中操作
+>
+>   **![image-20210701180547401](A_Git详细学习笔记中的图片/image-20210701180547401.png) 
+>
+>2. 解决方案2:命令行
+>
+>   ```sh
+>   git config --global gui.encoding utf-8
+>   ```
+>
+>3. 解决方案3:直接修改配置文件
+>
+>   >在软件的安装目录下,在`Git\mingw32\etc\gitconfig`文件末尾添加:
+>   >
+>   >```sh
+>   >[gui]encoding=utf-8
+>   >```

BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210508171916951.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210508182039450.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510171915185.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510172159472.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180415796.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180539437.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180756184.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510180757993.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510181329197.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510181407805.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210510183253770.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210621171934972.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210621172453710.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210701180547401.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/image-20210705115521085.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/列出仓库中最大的几个对象及其文件名.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/删除大文件前大小.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/删除大文件后大小.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/删除引用.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/删除截图.png


BIN
Git学习笔记/A_Git详细学习笔记中的图片/强制提交.jpg


+ 9 - 0
Git学习笔记/README.md

@@ -0,0 +1,9 @@
+>123
+>1231
+>>>12313123
+>>>123213
+adas 
+ada s
+
+
+as d

+ 393 - 0
Git学习笔记/git与vim常见指令集.md

@@ -0,0 +1,393 @@
+> [十分详细的git指令](https://juejin.im/post/5deb81b0e51d4557fd76f5f3)
+
+# 常用Git命令总结
+
+- git config --global user.name "你的名字" 让你全部的Git仓库绑定你的名字
+- git config --global user.email "你的邮箱" 让你全部的Git仓库绑定你的邮箱
+- git init 初始化你的仓库
+- git add . 把工作区的文件全部提交到暂存区
+- git add ./<file>/ 把工作区的<file>文件提交到暂存区
+- git commit -m "xxx" 把暂存区的所有文件提交到仓库区,暂存区空空荡荡
+- git remote add origin https://github.com/name/name_cangku.git 把本地仓库与远程仓库连接起来
+- git push -u origin master 把仓库区的主分支master提交到远程仓库里
+- git push -u origin <其他分支> 把其他分支提交到远程仓库
+- git status查看当前仓库的状态
+- git diff 查看文件修改的具体内容
+- git log 显示从最近到最远的提交历史  git log --pretty=oneline(更简洁的方式显示)
+- git clone + 仓库地址下载克隆文件
+- git reset --hard + 版本号 回溯版本,版本号在commit的时候与master跟随在一起
+- git reflog 显示命令历史
+- git checkout -- <file> 撤销命令,用版本库里的文件替换掉工作区的文件。我觉得就像是Git世界的ctrl + z
+- git rm 删除版本库的文件
+- git branch 查看当前所有分支
+- git branch <分支名字> 创建分支
+- git checkout <分支名字> 切换到分支
+- git merge <分支名字> 合并分支
+- git branch -d <分支名字> 删除分支,有可能会删除失败,因为Git会保护没有被合并的分支
+- git branch -D + <分支名字> 强行删除,丢弃没被合并的分支
+- git log --graph 查看分支合并图
+- git merge --no-ff <分支名字> 合并分支的时候禁用Fast forward模式,因为这个模式会丢失分支历史信息
+- git stash 当有其他任务插进来时,把当前工作现场“存储”起来,以后恢复后继续工作
+- git stash list 查看你刚刚“存放”起来的工作去哪里了
+- git stash apply 恢复却不删除stash内容
+- git stash drop 删除stash内容
+- git stash pop 恢复的同时把stash内容也删了
+- git remote 查看远程库的信息,会显示origin,远程仓库默认名称为origin
+- git remote -v 显示更详细的信息
+- git pull 把最新的提交从远程仓库中抓取下来,在本地合并,和git push相反
+- git rebase 把分叉的提交历史“整理”成一条直线,看上去更直观
+- git tag 查看所有标签,可以知道历史版本的tag
+- git tag <name> 打标签,默认为HEAD。比如git tag v1.0
+- git tag <tagName> <版本号> 把版本号打上标签,版本号就是commit时,跟在旁边的一串字母数字
+- git show <tagName> 查看标签信息
+- git tag -a <tagName> -m "<说明>" 创建带说明的标签。-a指定标签名,-m指定说明文字
+- git tag -d <tagName> 删除标签
+- git push origin <tagname> 推送某个标签到远程
+- git push origin --tags 一次性推送全部尚未推送到远程的本地标签
+- git push origin :refs/tags/<tagname> 删除远程标签<tagname>
+- git config --global color.ui true 让Git显示颜色,会让命令输出看起来更醒目
+- git add -f <file> 强制提交已忽略的的文件
+- git check-ignore -v <file> 检查为什么Git会忽略该文件
+
+
+
+# vim常用指令
+
+## VIM 进入和退出命令
+
+> 常用命令是ESC,然后:wq(保存并退出),:q!(不保存并强制退出),i进入vim模式。另外还有其它的,我可能都不会用到。。。
+> 按ESC键 跳到命令模式,然后:
+
+1. **:w 保存文件但不退出vi**
+2. **:w file 将修改另外保存到file中,不退出vi**
+3. **:w! 强制保存,不推出vi**
+4. **:wq 保存文件并退出vi**
+5. **:wq! 强制保存文件,并退出vi**
+6. **q: 不保存文件,退出vi**
+7. **:q! 不保存文件,强制退出vi**
+8. **:e! 放弃所有修改,从上次保存文件开始再编辑**
+
+## 命令历史
+
+以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令。
+
+## 启动vim
+
+在命令行窗口中输入以下命令即可
+
+vim 直接启动vim
+
+vim filename 打开vim并创建名为filename的文件
+
+## 文件命令
+
+打开单个文件
+
+vim file
+
+同时打开多个文件
+
+vim file1 file2 file3 ...
+
+在vim窗口中打开一个新文件
+
+:open file
+
+在新窗口中打开文件
+
+:split file
+
+切换到下一个文件
+
+:bn
+
+切换到上一个文件
+
+:bp
+
+查看当前打开的文件列表,当前正在编辑的文件会用[]括起来。
+
+:args
+
+打开远程文件,比如ftp或者share folder
+
+:e ftp://192.168.10.76/abc.txt
+
+:e \\qadrive\test\1.txt
+
+## vim的模式
+
+正常模式(按Esc或Ctrl+[进入) 左下角显示文件名或为空
+插入模式(按i键进入) 左下角显示--INSERT--
+可视模式(不知道如何进入) 左下角显示--VISUAL--
+
+## 导航命令
+
+% 括号匹配
+
+## 插入命令
+
+i 在当前位置生前插入
+
+I 在当前行首插入
+
+a 在当前位置后插入
+
+A 在当前行尾插入
+
+o 在当前行之后插入一行
+
+O 在当前行之前插入一行
+
+## 查找命令
+
+/text  查找text,按n健查找下一个,按N健查找前一个。
+
+?text  查找text,反向查找,按n健查找下一个,按N健查找前一个。
+
+vim中有一些特殊字符在查找时需要转义  .*[]^%/?~$
+
+:set ignorecase  忽略大小写的查找
+
+:set noignorecase  不忽略大小写的查找
+
+查找很长的词,如果一个词很长,键入麻烦,可以将光标移动到该词上,按*或#键即可以该单词进行搜索,相当于/搜索。而#命令相当于?搜索。
+
+:set hlsearch  高亮搜索结果,所有结果都高亮显示,而不是只显示一个匹配。
+
+:set nohlsearch  关闭高亮搜索显示
+
+:nohlsearch  关闭当前的高亮显示,如果再次搜索或者按下n或N键,则会再次高亮。
+
+:set incsearch  逐步搜索模式,对当前键入的字符进行搜索而不必等待键入完成。
+
+:set wrapscan  重新搜索,在搜索到文件头或尾时,返回继续搜索,默认开启。
+
+## 替换命令
+
+ra 将当前字符替换为a,当期字符即光标所在字符。
+
+s/old/new/ 用old替换new,替换当前行的第一个匹配
+
+s/old/new/g 用old替换new,替换当前行的所有匹配
+
+%s/old/new/ 用old替换new,替换所有行的第一个匹配
+
+%s/old/new/g 用old替换new,替换整个文件的所有匹配
+
+:10,20 s/^/  /g 在第10行知第20行每行前面加四个空格,用于缩进。
+
+ddp 交换光标所在行和其下紧邻的一行。
+
+## 移动命令
+
+h 左移一个字符
+l 右移一个字符,这个命令很少用,一般用w代替。
+k 上移一个字符
+j 下移一个字符
+以上四个命令可以配合数字使用,比如20j就是向下移动20行,5h就是向左移动5个字符,在Vim中,很多命令都可以配合数字使用,比如删除10个字符10x,在当前位置后插入3个!,3a!<Esc>,这里的Esc是必须的,否则命令不生效。
+
+w 向前移动一个单词(光标停在单词首部),如果已到行尾,则转至下一行行首。此命令快,可以代替l命令。
+
+b 向后移动一个单词 2b 向后移动2个单词
+
+e,同w,只不过是光标停在单词尾部
+
+ge,同b,光标停在单词尾部。
+
+^ 移动到本行第一个非空白字符上。
+
+0(数字0)移动到本行第一个字符上,
+
+<HOME> 移动到本行第一个字符。同0健。
+
+$ 移动到行尾 3$ 移动到下面3行的行尾
+
+gg 移动到文件头。 = [[
+
+G(shift + g) 移动到文件尾。 = ]]
+
+f(find)命令也可以用于移动,fx将找到光标后第一个为x的字符,3fd将找到第三个为d的字符。
+
+F 同f,反向查找。
+
+跳到指定行,冒号+行号,回车,比如跳到240行就是 :240回车。另一个方法是行号+G,比如230G跳到230行。
+
+Ctrl + e 向下滚动一行
+
+Ctrl + y 向上滚动一行
+
+Ctrl + d 向下滚动半屏
+
+Ctrl + u 向上滚动半屏
+
+Ctrl + f 向下滚动一屏
+
+Ctrl + b 向上滚动一屏
+
+## 撤销和重做
+
+u 撤销(Undo)
+U 撤销对整行的操作
+Ctrl + r 重做(Redo),即撤销的撤销。
+
+## 删除命令
+
+x 删除当前字符
+
+3x 删除当前光标开始向后三个字符
+
+X 删除当前字符的前一个字符。X=dh
+
+dl 删除当前字符, dl=x
+
+dh 删除前一个字符
+
+dd 删除当前行
+
+dj 删除上一行
+
+dk 删除下一行
+
+10d 删除当前行开始的10行。
+
+D 删除当前字符至行尾。D=d$
+
+d$ 删除当前字符之后的所有字符(本行)
+
+kdgg 删除当前行之前所有行(不包括当前行)
+
+jdG(jd shift + g)  删除当前行之后所有行(不包括当前行)
+
+:1,10d 删除1-10行
+
+:11,$d 删除11行及以后所有的行
+
+:1,$d 删除所有行
+
+J(shift + j)  删除两行之间的空行,实际上是合并两行。
+
+## 拷贝和粘贴
+
+yy 拷贝当前行
+
+nyy 拷贝当前后开始的n行,比如2yy拷贝当前行及其下一行。
+
+p 在当前光标后粘贴,如果之前使用了yy命令来复制一行,那么就在当前行的下一行粘贴。
+
+shift+p 在当前行前粘贴
+
+:1,10 co 20 将1-10行插入到第20行之后。
+
+:1,$ co $ 将整个文件复制一份并添加到文件尾部。
+
+正常模式下按v(逐字)或V(逐行)进入可视模式,然后用jklh命令移动即可选择某些行或字符,再按y即可复制
+
+ddp交换当前行和其下一行
+
+xp交换当前字符和其后一个字符
+
+## 剪切命令
+
+正常模式下按v(逐字)或V(逐行)进入可视模式,然后用jklh命令移动即可选择某些行或字符,再按d即可剪切
+
+ndd 剪切当前行之后的n行。利用p命令可以对剪切的内容进行粘贴
+
+:1,10d 将1-10行剪切。利用p命令可将剪切后的内容进行粘贴。
+
+:1, 10 m 20 将第1-10行移动到第20行之后。
+
+## 退出命令
+
+:wq 保存并退出
+
+ZZ 保存并退出
+
+:q! 强制退出并忽略所有更改
+
+:e! 放弃所有修改,并打开原来文件。
+
+## 窗口命令
+
+:split或new 打开一个新窗口,光标停在顶层的窗口上
+
+:split file或:new file 用新窗口打开文件
+
+split打开的窗口都是横向的,使用vsplit可以纵向打开窗口。
+
+Ctrl+ww 移动到下一个窗口
+
+Ctrl+wj 移动到下方的窗口
+
+Ctrl+wk 移动到上方的窗口
+
+关闭窗口
+
+:close 最后一个窗口不能使用此命令,可以防止意外退出vim。
+
+:q 如果是最后一个被关闭的窗口,那么将退出vim。
+
+ZZ 保存并退出。
+
+关闭所有窗口,只保留当前窗口
+
+:only
+
+录制宏
+
+按q键加任意字母开始录制,再按q键结束录制(这意味着vim中的宏不可嵌套),使用的时候@加宏名,比如qa。。。q录制名为a的宏,@a使用这个宏。
+
+## 执行shell命令
+
+:!command
+
+:!ls 列出当前目录下文件
+
+:!perl -c script.pl 检查perl脚本语法,可以不用退出vim,非常方便。
+
+:!perl script.pl 执行perl脚本,可以不用退出vim,非常方便。
+
+:suspend或Ctrl - Z 挂起vim,回到shell,按fg可以返回vim。
+
+## 注释命令
+
+perl程序中#开始的行为注释,所以要注释某些行,只需在行首加入#
+
+3,5 s/^/#/g 注释第3-5行
+
+3,5 s/^#//g 解除3-5行的注释
+
+1,$ s/^/#/g 注释整个文档。
+
+:%s/^/#/g 注释整个文档,此法更快。
+
+## 帮助命令
+
+:help or F1 显示整个帮助
+:help xxx 显示xxx的帮助,比如 :help i, :help CTRL-[(即Ctrl+[的帮助)。
+:help 'number' Vim选项的帮助用单引号括起
+:help <Esc> 特殊键的帮助用<>扩起
+:help -t Vim启动参数的帮助用-
+:help i_<Esc> 插入模式下Esc的帮助,某个模式下的帮助用模式_主题的模式
+帮助文件中位于||之间的内容是超链接,可以用Ctrl+]进入链接,Ctrl+o(Ctrl + t)返回
+
+## 其他非编辑命令
+
+. 重复前一次命令
+
+:set ruler?  查看是否设置了ruler,在.vimrc中,使用set命令设制的选项都可以通过这个命令查看
+
+:scriptnames  查看vim脚本文件的位置,比如.vimrc文件,语法文件及plugin等。
+
+:set list 显示非打印字符,如tab,空格,行尾等。如果tab无法显示,请确定用set lcs=tab:>-命令设置了.vimrc文件,并确保你的文件中的确有tab,如果开启了expendtab,那么tab将被扩展为空格。
+
+Vim教程
+在Unix系统上
+$ vimtutor
+在Windows系统上
+:help tutor
+
+:syntax 列出已经定义的语法项
+:syntax clear 清除已定义的语法规则
+:syntax case match 大小写敏感,int和Int将视为不同的语法元素
+:syntax case ignore 大小写无关,int和Int将视为相同的语法元素,并使用同样的配色方案

+ 289 - 0
Git学习笔记/你可能会忽略的 Git 提交规范摘录.md

@@ -0,0 +1,289 @@
+# #目录
+
+>[TOC]
+
+# 本人笔记提交标准
+
+```jsx
+docs: 新建知识点笔记
+feat:新增知识点(feature)。
+update:对于某部分知识点的更新修改(不是勘误,如更新目录索引、某正确知识点补全等操作)
+fix:勘误,修正知识点错误等操作
+style:如文档内样式调整,格式调整等不影响笔记内容的操作 (如删除多余资源,如无用的图片,无用语句删除等)
+refactor:笔记重构与优化(主要就是目录变动、笔记文件结构调整、文件名更改等操作)
+//举例
+docs(算法):新建数据结构与算法知识点笔记
+feat(前端-promise): 新增笔记中async+await+promise知识点笔记
+fix(前端-微信小程序):更正笔记中对于自定义组件描述的不恰当处
+refactor(前端):对于前端笔记部分文件目录进行重构调整
+style(后台-java):进行对该笔记中笔记格式与样式调整 或 进行对该笔记中多余图片展示资源的删除
+update:(README):笔记目录索引更新-新增小程序自封装组件笔记索引
+```
+
+
+
+# 你可能会忽略的 Git 提交规范
+
+一直是 ESLint 的忠实用户,深知规范的重要性。然而,在新项目交接中,我被 Git Commit 规范逼疯了。才意识到自己的疏忽,于是便有了一探究竟的想法。
+
+#### 一、为什么需要规范?
+
+无规矩不成方圆,编程也一样。
+
+如果你有一个项目,从始至终都是自己写,那么你想怎么写都可以,没有人可以干预你。可是如果在团队协作中,大家都张扬个性,那么代码将会是一团糟,好好的项目就被糟践了。不管是开发还是日后维护,都将是灾难。
+
+这时候,有人提出了何不统一标准,大家都按照这个标准来。于是 `ESLint`,`JSHint` 等代码工具如雨后春笋般涌现,成为了项目构建的必备良品。
+
+`Git Commit` 规范可能并没有那么夸张,但如果你在版本回退的时候看到一大段糟心的 `Commit`,恐怕会懊恼不已吧。所以,严格遵守规范,利人利己。
+
+#### 二、具体规则
+
+先来看看公式:
+
+```
+<type>(<scope>): <subject>
+```
+
+
+
+- type
+
+  - 用于说明
+
+     
+
+    ```
+    commit
+    ```
+
+     
+
+    的类别,只允许使用下面7个标识。
+
+    ```jsx
+    feat:新功能(feature)。
+    fix/to:修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。
+    fix:产生diff并自动修复此问题。适合于一次提交直接修复问题
+    to:只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fix
+    docs:文档(documentation)。
+    style:格式(不影响代码运行的变动)。
+    refactor:重构(即不是新增功能,也不是修改bug的代码变动)。
+    perf:优化相关,比如提升性能、体验。
+    test:增加测试。
+    chore:构建过程或辅助工具的变动。
+    revert:回滚到上一个版本。
+    merge:代码合并。
+    sync:同步主线或分支的Bug。
+    ```
+
+- scope
+
+  - 用于说明 `commit` 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
+
+- subject
+
+  - 是
+
+     
+
+    ```
+    commit
+    ```
+
+     
+
+    目的的简短描述,不超过50个字符。
+
+    ```
+    1.以动词开头,使用第一人称现在时,比如change,而不是changed或changes
+    2.第一个字母小写
+    3.结尾不加句号(.)
+    ```
+
+规范参考自阮一峰老师的文章:[Commit message 和 Change log 编写指南](http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html)。
+
+#### 三、异常处理
+
+我们先来看看这个异常提醒:
+
+```
+INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" !
+jartto:fix bug
+```
+
+
+
+这里之所以报出这个警告,是因为我的提交出现了两个问题:
+其一,使用了规范外的关键字;
+其二,很细节的问题,jartto:后少了空格;
+
+这时候我才回忆起来,当时提交一直失败,情急之下直接强制提交,所以以后的提交都会抱出这个异常。大致意思就是:
+
+你的之前的 Commit 不合格~你的之前的 Commit 不合格~你的之前的 Commit 不合格
+
+这时候就很烦了,我们只能去将之前的错误修正,那么如何操作呢?
+
+#### 四、如何修改之前的 commit 信息?
+
+其实并不复杂,我们只需要这样做:
+1、将当前分支无关的工作状态进行暂存
+
+```
+git stash
+```
+
+
+
+2、将 `HEAD` 移动到需要修改的 `commit` 上
+
+```
+git rebase 9633cf0919^ --interactive
+```
+
+
+
+3、找到需要修改的 `commit` ,将首行的 `pick` 改成 `edit`
+4、开始着手解决你的 `bug`
+5、 `git add` 将改动文件添加到暂存
+6、 `git commit –amend` 追加改动到提交
+7、`git rebase –continue` 移动 `HEAD` 回最新的 `commit`
+8、恢复之前的工作状态
+
+```
+git stash pop
+```
+
+
+
+大功告成,是不是想把整个 Commit 都修改一遍,逃~
+
+此处参考自:[修改 Commit 日志和内容](https://www.aliyun.com/jiaocheng/125261.html)
+
+#### 五、项目中使用
+
+这时候问题又来了,为什么我提交的时候会有警告,这个又是如何做到的呢?
+
+这时候,我们需要一款 `Node` 插件 `validate-commit-msg` 来检查项目中 `Commit message` 是否规范。
+
+1.首先,安装插件:
+
+```
+npm install --save-dev validate-commit-msg
+```
+
+
+
+2.使用方式一,建立 `.vcmrc` 文件:
+
+```
+{
+  "types": ["feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert"],
+  "scope": {
+    "required": false,
+    "allowed": ["*"],
+    "validate": false,
+    "multiple": false
+  },
+  "warnOnFail": false,
+  "maxSubjectLength": 100,
+  "subjectPattern": ".+",
+  "subjectPatternErrorMsg": "subject does not match subject pattern!",
+  "helpMessage": "",
+  "autoFix": false
+}
+```
+
+
+
+3.使用方式二:写入 `package.json`
+
+```
+{
+  "config": {
+    "validate-commit-msg": {
+      /* your config here */
+    }
+  }
+}
+```
+
+
+
+4.可是我们如果想自动使用 [`ghooks`](https://www.npmjs.com/package/ghooks) 钩子函数呢?
+
+```
+{
+  …
+  "config": {
+    "ghooks": {
+      "pre-commit": "gulp lint",
+      "commit-msg": "validate-commit-msg",
+      "pre-push": "make test",
+      "post-merge": "npm install",
+      "post-rewrite": "npm install",
+      …
+    }
+  }
+  …
+}
+```
+
+
+
+在 `ghooks` 中我们可以做很多事情,当然不只是 `validate-commit-msg` 哦。
+
+更多细节请参考:[validate-commit-msg](https://github.com/conventional-changelog-archived-repos/validate-commit-msg)
+
+#### 六、Commit 规范的作用
+
+1.提供更多的信息,方便排查与回退;
+2.过滤关键字,迅速定位;
+3.方便生成文档;
+
+#### 七、生成 Change log
+
+正如[上文](http://jartto.wang/2018/07/08/git-commit/)提到的生成文档,如果我们的提交都按照规范的话,那就很简单了。生成的文档包括以下三个部分:
+
+- New features
+- Bug fixes
+- Breaking changes.
+
+每个部分都会罗列相关的 `commit` ,并且有指向这些 `commit` 的链接。当然,生成的文档允许手动修改,所以发布前,你还可以添加其他内容。
+
+这里需要使用工具 [Conventional Changelog](https://github.com/conventional-changelog/conventional-changelog) 生成 `Change log` :
+
+```
+npm install -g conventional-changelog
+cd jartto-domo
+conventional-changelog -p angular -i CHANGELOG.md -w
+```
+
+
+
+为了方便使用,可以将其写入 `package.json` 的 `scripts` 字段。
+
+```
+{
+  "scripts": {
+    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0"
+  }
+}
+```
+
+
+
+这样,使用起来就很简单了:
+
+```
+npm run changelog
+```
+
+
+
+到这里,我们所有的问题都搞明白了,🍻Cheers~
+
+#### 八、总结
+
+看完文章,你还会如此放荡不羁吗?你还会随心所欲的编写 `Commit` 吗?你还会如此 `git commit -m "hello jartto"`提交吗?
+
+答案是否定的,因为使用了钩子函数,你没有机会了,否则将是无穷无尽的恢复 `Commit`。这倒可以养成良好的提交习惯,🙈~

+ 367 - 0
Git学习笔记/分支管理策略[Git工作流]学习笔记.md

@@ -0,0 +1,367 @@
+# #说明
+
+> 本笔记是本人对于Git工作流的学习感悟与记录(部分是摘录)
+>
+> 借阅参考的资料:阮一峰的[Git工作流程](http://www.ruanyifeng.com/blog/2015/12/git-workflow.html)、[《Git 分支管理策略》](https://www.ruanyifeng.com/blog/2012/07/git.html);掘金上zifeiyu的[GIT工作流指南系列--gitFlow工作流](https://juejin.cn/post/6844903997589946382#heading-4)、红尘炼心的[『前端进阶』—— 代码管理方案之Aone Flow](https://juejin.cn/post/6979605217184579591);[钱五哥の自由空间](http://www.brofive.org/)的[Git 代码分支模型GitFlow、GitHub Flow、Trunk Based Development](http://www.brofive.org/?p=2165);[替代分支模型](https://trunkbaseddevelopment.com/alternative-branching-models/);*[刘尚奇](https://insights.thoughtworks.cn/author/liushangqi/)*的[Gitflow有害论](http://insights.thoughtworks.cn/gitflow-consider-harmful/);Paul Hammant的[What is Trunk-Based Development?](https://paulhammant.com/2013/04/05/what-is-trunk-based-development/);以及公司前辈在技术分享会上的讲述
+>
+> 本人笔记地址分享:[`全部笔记`](https://gitee.com/hongjilin/hongs-study-notes)、[`Git笔记`](https://gitee.com/hongjilin/hongs-study-notes/tree/master/%E7%BC%96%E7%A8%8B_%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0)
+
+# #目录
+
+>[TOC]
+
+# 一、Git 工作流程概念
+
+>Git 作为一个源码管理系统,不可避免涉及到多人协作。
+>
+>协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去。"工作流程"在英语里,叫做"workflow"或者"flow",原意是水流,比喻项目像水流那样,顺畅、自然地向前流动,不会发生冲击、对撞、甚至漩涡。
+>
+>如果你对于Git还不是很熟练,可以看本人关于Git的详细学习笔记,内给出了对应的学习教程来源    -->**[点我跳转](https://gitee.com/hongjilin/hongs-study-notes/tree/master/编程_前端开发学习笔记/Git学习笔记)** 
+
+## 1、定义
+
+>- 基于Git的强大分支能力所构建的一套软件开发工作流
+>- 根据项目具体需求定制的一套工作规范
+
+## 2、存在意义
+
+>1. 整个研发流程(软件工程)管理中的重要环节
+>    - 上游:项目管理/缺陷管理  
+>    - 下游:运维部署(CD)
+>
+>2. 所有类型的提出基本能解决:
+>   - 特性独立开发互不影响,记录发布历史
+>    - 多版本并行,多环境多渠道部署的不同需求
+
+## 3、功能驱动
+
+>- 常见的几种工作流程,有一个共同点:都采用["功能驱动式开发"](https://en.wikipedia.org/wiki/Feature-driven_development)(Feature-driven development,简称FDD)。
+>- 它指的是,需求是开发的起点,先有需求再有功能分支(feature branch)或者补丁分支(hotfix branch)。完成开发后,该分支就合并到主分支,然后被删除。
+>
+>例如:Git flow、Github flow、Gitlab flow等
+
+## 4、省流总结
+
+>- `没有银弹!!`-->没有非黑即白的工作流,只有不同应用场景的选择
+>- `branch的本质是一种轻量级的代码隔离技术,生命周期应该尽可能地短`
+>- 本身工作流也是一种人为规定的规范,可以结合常见的几种工作流然后取其精华去其糟粕规定出自己所需的工作流
+>- 工作中最好细致拆解任务,这样可以防止feature开发周期过长导致合并时带上`痛苦面具`
+>- 养成习惯:频繁进行pull与rebase操作,冲突还真是麻烦的
+
+# 二、Git Flow
+
+> 更详细的关于Git flow相关知识可以查阅阮一峰的[《Git 分支管理策略》](https://www.ruanyifeng.com/blog/2012/07/git.html)。
+>
+> 此工作流也是最具有争议的
+
+## 1、工作流程图
+
+>![image-20210702142024042](分支管理策略[Git工作流]学习笔记中的图片/image-20210702142024042.png)
+
+## 2、特点
+
+>它主要有两个特点
+>
+>1. 首先项目存在两个长期分支:
+>   - 主分支`master`
+>   - 开发分支`develop`
+>   - `ps`:前者用于存放对外发布的版本,任何时候在这个分支拿到的,都是稳定的分布版;后者用于日常开发,存放最新的开发版。
+>2. 其次,项目存在三种短期分支
+>   - 功能分支(feature branch)
+>   - 补丁分支(hotfix branch)
+>   - 预发分支(release branch)
+>   - ps`:一旦完成开发,它们就会被合并进`develop`或`master`,然后被删除。
+
+## 3、分支删除管理
+
+>- 特性分支合并到dev后,删除feature
+>- 发布分支合并到master和dev后,删除release
+>- 修复分支合并到master和dev后,删除hotfix
+
+## 4、GitFlow分支说明
+
+>根据主流的Git工作流,一般分为:master(`必须`)、release(`通常必须`)、develop(`必须`)、hoxfix/xxx、bug/xxx、feature/xxx,分支贯穿了整个**开发、测试、部署**流程
+>
+>各分支的定位以及权限描述:
+>
+>![image-20210702154430932](分支管理策略[Git工作流]学习笔记中的图片/image-20210702154430932.png) 
+
+## 5、缺点与其有害论
+
+>缺点
+>
+>- 特性分支基于dev,代码不够稳定
+>- 发布分支基于dev,可能含有不打算发布的特性
+>- 非官方推荐,类似于民间约定俗成的工作流
+>
+>有害论
+>
+>- 流程相对复杂,需要要求成员深刻理解流程并且严格执行
+>- merge总是痛苦和易错的,成本异常高,特别是feature的周期很长的时候.合并的时候总会带上`痛苦面具`
+>- 持续集成引起的不适
+>- 借阅的资料:[Gitflow有害论](http://insights.thoughtworks.cn/gitflow-consider-harmful/)
+
+## 6、工作流实践
+
+> 此实践参考资料来自于掘金的[zifeiyu的GIT工作流指南系列](https://juejin.cn/post/6844903997589946382)
+
+### Ⅰ-初始化
+
+>你可以从远程仓库clone项目或者本地新建项目
+>
+>1. 初始化命令
+>
+>```sh
+>git flow init
+>```
+>
+>2. 该命令会指引你去修改不同分支的前缀,建议没有特别的需求使用默认前缀即可
+>
+>   ```sh
+>   $ git flow init
+>   Initialized empty Git repository in /Users/tobi/acme-website/.git/
+>   Branch name for production releases: [master] 
+>   Branch name for "next release" development: [develop] 
+>   
+>   How to name your supporting branch prefixes?
+>   Feature branches? [feature/] 
+>   Release branches? [release/] 
+>   Hotfix branches? [hotfix/] 
+>   ```
+>
+>3. 如果你不需要修改默认的分支前缀(大多数情况)那么也可以使用如下命令进行初始化来跳过询问过程
+>
+>```sh
+>git flow init -d
+>```
+
+### Ⅱ-feature分支
+
+#### ① *本地操作流程*
+
+>- 当我们初始化完成之后,就可以开始一个新功能的开发,开发新功能需要在feature分支上进行,下面就让我们创建一个新的叫做rss-feed的feature分支
+>
+>```sh
+>git flow feature start rss-feed
+>```
+>
+>- 这个功能可能需要多人协作才能完成,所以我们需要把它发布到远端(如果是本地创建的项目,请先与远端仓库建立联系)
+>
+>```sh
+>git flow feature public rss-feed
+>```
+>
+>这条指令在远程仓库新建了一个feature/rss-feed的分支,并将本地ree-feed分支track上述分支,push本地分支代码。
+>
+>ps:该命令只能执行一次,当远程仓库已经有了相应分支,在执行该命令将会报错,这个时候只要执行push命令就可以了。
+>
+>- 经过一段时间的努力,我们跟同事一起协作开发完成了rss-feed分支上的功能,我们需要把这个feature分支合并到develop分支(可能还有别的feature分支,一起合并到develop)。
+>
+>```sh
+>git flow feature finish rss-feed
+>```
+>
+>*该命令做了以下几件事*
+>
+>- 切换到develop分支
+>- 将feature/rss-feed分支merge到develop分支
+>- 删除本地feature/rss-feed分支
+>
+>  `注意`:
+> - git flow进行merge操作或者tag操作的时候,会让打开vim编辑器让你填写merge信息或者tag信息(tag信息必须填写,否则无法打tag)
+> - 如果merge过程发生了冲突,则在第二步merge时终止流程,即不会再删除本地分支。但当前已处于develop分支,待本地冲突解决并commit后,重新执行git flow feature finish <feature_name>即可完成finish流程。
+
+#### ② *同步远程仓库*
+
+>- push本地develop分支
+>
+>- 删除远端仓库feature/rss-feed分支
+>
+>- ```sh
+>  git push origin develop
+>   git push origin :feature/rss-feed
+
+#### ③ ***finish指令的附加参数***
+
+>- -r mege前先进行rebase操作
+>- -F merge操作完成后删除远程和本地feature分支
+>- -k 保留feature分支
+
+### Ⅲ-release分支
+
+>当项目组的各个成员都完成了自己在本次版本中feature分支的功能开发并合并到develop分支,项目的管理员应当开始`release`操作。
+>
+>基于develop分支拉出release分支进行测试,发现bug项目组成员拉取release分支后直接在release分支上进行修改,并提交到远程仓库。
+
+#### **操作具体流程**
+
+>1. 切换到master分支
+>2. 执行git fetch检查更新: 如果远程仓库有更新,会停下来并让你先执行git pull命令(如果有冲突解决冲突并提交,这可能是唯一一种直接操作master分支的情形了), 确保本地master是最新的。
+>3. 如果没有更新,将release/v2.0分支合并到本地master: 会让你填写merge信息,vim的形式(如何操作vim)
+>4. 将release/v2.0分支合并到本地develop
+>5. 删除本地release/v2.0分支
+>6. 注意:
+>   - 建议在使用`release finish`命令之前使用git pull更新develop和master代码,特别是master
+>   - 如果本地还有未finish的release分支,将不允许使用start指令开启新的release分支,这一点是对并行发布的一个限制。
+>7. 然后同步到远程
+
+### Ⅳ-hotfix分支
+
+>当我们的线上版本出现BUG需要紧急修复的时候,流程如下:
+>
+>1. 假设修复bug的版本号为v2.0-patch
+>
+>   ```sh
+>   git flow hotfix start v2.0-patch
+>   ```
+>
+>   hotfix并没有public命令,因为BUG一般是比较小且不可分割的逻辑单元,通常是单人在单个工作周期内完成,也不需要跟其他人协作。
+>
+>2. 本地完成修复,并测试通过commit之后就可以执行finish命令
+>
+>   ```sh
+>   git flow hotfix finish v2.0-patch
+>   ```
+>
+>3. 运行结果
+>
+>   ```sh
+>   Summary of actions:
+>   - Latest objects have been fetched from 'origin'
+>   - Hotfix branch has been merged into 'master'
+>   - The hotfix was tagged 'v2.0-patch'
+>   - Hotfix branch has been back-merged into 'develop'
+>   - Hotfix branch 'hotfix/v2.0-patch' has been deleted
+>   ```
+>
+>   对应的意思
+>
+>   - git fetch 检查本地与远端是否up-to-date
+>   - 将v2.0-patch分支合并到master分支
+>   - 生成「v2.0-pathc」标签
+>   - 将v2.0-patch分支合并到develop分支
+>   - 删除本地v2.0-patch分支
+
+### Ⅴ-关于feature分支的讨论
+
+>不知道大家有没有这个疑问?feature分支的逻辑功能颗粒度应当是怎样的?是一个可拆分的大任务?需要多人协作?还是一个不可拆分的逻辑单元,只能由一个人独立完成?
+>
+>我的看法是,每个人都应该有自己的feature分支,feature分支应当是不可拆分的完整逻辑功能,不应当多人协作;如果能够拆分那就拆成两个不同的feature分支。
+
+**这么做的理由是:**
+
+- 如果多人使用同一个feature,势必会导致publish的冲突,因为只能publish一次。
+- finish操作也只能有一个人完成
+- feature分支需要时不时的进行pull/push操作
+- 每个分支还必须有一个管理者,整个项目还需要一个最终管理者进行release操作,导致组织结构复杂,而软件工程开发本身是一个扁平化的结构,扁平化代表了高效率。
+
+**由此引发的讨论:**
+
+- 既然feature分支只是自己在用,是否有必要将feature分支publish到远程仓库呢?
+- 前端如何进行任务分配?模块化,微服务等概念如何在前端落地?一个项目如何能够拆分成互不干涉,完全解耦的几个部分?如果不能,那么多人协作的过程中势必会产生冲突和功能重复,代码冗余,如何避免呢?
+
+
+
+
+## 7、结论
+
+>Git flow的优点是清晰可控,缺点是相对复杂,需要同时维护两个长期分支。大多数工具都将`master`当作默认分支,可是开发是在`develop`分支进行的,这导致经常要切换分支,非常烦人。
+>
+>更大问题在于,这个模式是基于"版本发布"的,目标是一段时间以后产出一个新版本。但是,很多网站项目是"持续发布",代码一有变动,就部署一次。这时,`master`分支和`develop`分支的差别不大,没必要维护两个长期分支。
+
+
+
+
+# 三、Trunk-based Flow
+
+>也许你会突然有疑惑,不应该先说 Github flow与Gitlab flow吗?
+>
+>其实这个工作流是本人学习`Git flow`过程中根据其缺点有人提出的新的工作流程,此处就将其排于`Git flow`之后
+>
+>更详细请看相关资料:[What is Trunk-Based Development?](https://paulhammant.com/2013/04/05/what-is-trunk-based-development/)
+
+## 1、工作流程图
+
+>![image-20210702144120442](分支管理策略[Git工作流]学习笔记中的图片/image-20210702144120442.png)
+>
+>适用场景:`适合于单一稳定产品线,迭代排期稳定,需求边界完全可控的团队`
+
+## 2、提出的原因
+
+>- 使用`Git flow`:
+>
+>  你会发现,在坚持持续集成实践的情况下,feature branch是一件非常矛盾的事情。持续集成在鼓励更加频繁的代码集成和交互,让冲突越早解决越好。feature branch的代码隔离策略却在尽可能推迟代码的集成。延迟集成所带来的恶果在软件开发的历史上已经出现过很多次了,每个团队自己写自己的代码是挺high,到最后不同团队进行联调集成的时候就傻眼了,经常出现写两个月代码,花一个月时间集成的情况,质量还无法保证。
+>
+>- 而此工作流所有的开发工作都在同一个master分支上进行,同时利用[Continuous Integration](http://www.martinfowler.com/articles/continuousIntegration.html)确保master上的代码随时都是production ready的。从master上拉出release分支进行release的追踪。
+
+## 3、缺点
+
+>没有Feature分支:feature branch可以确保没完成的feature不会进入到production呀。没关系,[Feature Toggle](http://martinfowler.com/bliki/FeatureToggle.html)技术也可以帮你做到这一点
+
+## 4、优点
+
+>对于持续集成,每日构建,每日冒烟十分友好
+
+# 四、GitHub Flow
+
+## 1、工作流程图
+
+>![image-20210702152422183](分支管理策略[Git工作流]学习笔记中的图片/image-20210702152422183.png) 
+>
+>详细了解看:https://guides.github.com/introduction/flow/
+
+## 2、特点
+
+>分支结构简单,`非常强调CR`,通过CR保证理论上主干代码质量有保障
+
+## 3、缺点
+
+>没有解答部署、环境、发布、集成等问题
+
+# 五、GitLab Flow
+
+>在`GitHub Flow`的基础上考虑了一些环境部署、项目管理等问题
+>
+>![image-20210702152726339](分支管理策略[Git工作流]学习笔记中的图片/image-20210702152726339.png) 
+
+# 六、Aone Flow
+
+>参考资料:掘金的红尘炼心的[『前端进阶』—— 代码管理方案之Aone Flow](https://juejin.cn/post/6979605217184579591)
+>
+>其关于此知识点博客写的已经很好了,摘录下来并加上自己少许理解
+
+## 1、开发流程
+
+>
+>
+>![image-20210702152841056](分支管理策略[Git工作流]学习笔记中的图片/image-20210702152841056.png) 
+>
+>在Aone Flow中只有三种分支,正式分支master,预发布分支release,功能分支(特性分支)feature。
+>
+>当开发新功能时,从master分支创建feature分支,分支的命名通常以“feature/功能名称”来命名,每个feature分支可以是一个人完成,或是多个人协作完成。
+>
+>切记不能用master分支去合并feature分支,也不能在master分支上直接修改代码然后提交,master分支只能用来合并release分支
+
+## 2、预发布流程
+
+>![image-20210702153327715](分支管理策略[Git工作流]学习笔记中的图片/image-20210702153327715.png) 
+>
+>在Aone Flow中使用release分支作为预发布分支,先用master分支创建一个release分支,分支的名称通常以release/环境名称,然后将要预发布的功能对应的feature分支合并到release分支。最后将release分支的代码部署到对应的预发布环境进行测试,若出现BUG,直接在release分支上修复,修复完成后再部署到对应的预发布环境测试。
+
+## 3、正式发布流程
+
+>![image-20210702153021942](分支管理策略[Git工作流]学习笔记中的图片/image-20210702153021942.png) 
+>
+>当release分支的代码在对应的预发布环境测试通过后,用master分支合并release分支,合并完成后打出一个tag,其tag的名称可以用版本号来命名,然后将tag上的代码部署到正式环境,正式发布流程完成,同时删除release分支和相关联的feature分支。
+
+## 4、修复正式环境的BUG流程
+
+>- 若正式环境出现BUG,那么要找到对应版本的tag,用tag创建出一个release分支,此时的release分支相当fixbug分支,在release分支上修复BUG后,将代码部署到对应的预发布环境进行测试。
+>- 若测试通过后,在release分支打一个tag,其tag的名字用该版本号后面加个小版本号来命名,如修复v1.1版本的BUG,则tag的名称为v1.1.1,然后将该tag的代码部署在正式环境,最后再用master分支合并release分支,合并完成后将release分支删除。
+>- 若测试未通过,继续在release分支修复BUG,再将代码部署到对应的预发布环境进行测试。
+
+## 5、可能的玩法
+
+>- 发布分支对应具体的环境
+>- 一个发布分支对应多个环境,比如把`灰度发布`和正式发布串在一起,中间加上人工验收的步骤  -->[什么是灰度发布?](http://www.appadhoc.com/blog/what-is-gray-release/)
+>- 分布分支对应办呢吧,再将一系列环境串联起来

BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702142024042.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702144120442.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702152422183.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702152726339.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702152841056.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702153021942.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702153327715.png


BIN
Git学习笔记/分支管理策略[Git工作流]学习笔记中的图片/image-20210702154430932.png


+ 342 - 0
Git学习笔记/开发中必须要掌握的 Git 技巧摘录.md

@@ -0,0 +1,342 @@
+# #目录
+
+>[TOC]
+
+## 开发中必须要掌握的 Git 技巧
+
+本文是参考廖雪峰老师的Git资料再加上我自己对Git的理解,记录我的Git学习历程,作下此文是为以后学习,工作,开发中如果遇到问题可以回过头来参考参考。因为水平有限,难免会有出错的地方,欢迎指正。
+
+廖雪峰老师讲Git讲的通俗易懂,对小白很友好。认认真真花上两天时间去整理,会有所收获的。
+
+廖老师的个人网站传送门:
+
+> https://www.liaoxuefeng.com/
+
+## Git是什么
+
+官方话:Git是一个免费的开源分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有事务。
+
+它能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以。
+
+## 为什么要学习Git
+
+- 面试要被问。可以应付面试。
+- 很多公司开发都用Git来处理项目。现在不学,以后肯定还要学。
+- 在我看来Git是现如今所有程序员都要掌握的,以后与同事共同开发项目必定要用到的,熟练掌握Git命令,可以提高开发的效率。
+
+## 安装Git
+
+### Windows
+
+直接在官网上去下载。下载完成后,随便在某个文件下右键如果有Git Bash Here就安装成功。安装后,还要在命令行输入
+
+```
+$git config --global user.name "你的名字"
+$git config --global user.email "你的邮箱"
+```
+
+global表示全局,这台机器所有的Git仓库都会使用这个配置。允许单个仓库使用其他的名字和邮箱。
+
+### Mac
+
+> Mac也可以像Windows一样,按上面的步骤安装。
+
+也可以直接从AppStore安装Xcode,Xcode集成了Git,不过默认没有安装,你需要运行Xcode,选择菜单“Xcode”->“Preferences”,在弹出窗口中找到“Downloads”,选择“Command Line Tools”,点“Install”就可以完成安装了。
+
+## 仓库
+
+![图片](https://mmbiz.qpic.cn/mmbiz/eQPyBffYbufTCibib86U9CCeu7ibdH4FyIsH10EpW9P88HfHYRVab9HxJjpmXpS2RqI0wNIiaibCOsZUWPrc3bfHs5w/640?wx_fmt=other&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)
+
+本地仓库是对于远程仓库而言的。本地仓库 = 工作区 + 版本区。
+
+- 工作区即磁盘上的文件集合。
+- 版本区(版本库)即.git文件。
+- 版本库 = 暂存区(stage) + 分支(master) + 指针Head。
+
+以我使用最频繁的git命令为例,即提交到github为例。
+
+- git init 原本本地仓库只包含着工作区,这是最常见的工作状态。此时,git init一下,表示在本地区域创建了一个.git文件,版本区建立。
+- git add . 表示把工作区的所有文件全部提交到版本区里面的暂存区
+- 当然你也可以通过 git add ./xxx/ 一条一条分批添加到暂存区。
+- git commit -m "xxx" 把暂存区的所有文件提交到仓库区,暂存区空空荡荡。
+- git remote add origin https://github.com/name/name_cangku.git 把本地仓库与远程仓库连接起来。
+- git push -u origin master 把仓库区的文件提交到远程仓库里。
+- 一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的。会有这样的信息nothing to commit, working tree clean
+
+## 提交到GitHub
+
+以前不熟悉git命令的时候,我提交项目到github上都是直接在网页上直接拉取文件提交上去的。有点羞耻。
+
+![图片](https://mmbiz.qpic.cn/mmbiz/eQPyBffYbufTCibib86U9CCeu7ibdH4FyIs0icjYJkBm5FgUxI39IuibpzHx7zGpcb9EE0sPp19dqluib7icLHAGFnhOQ/640?wx_fmt=other&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)
+
+
+
+- git init .初始化,表示把这个文件变成Git可以管理的仓库。初始化后打开隐藏的文件可以看到有一个.git文件。
+- git add . 后面的一个点表示把这个文件全部提交到暂存区。
+- git add ./readme.md/ 表示把这个文件下面的readme.md文件提交到暂存区。
+- git commit -m "你要评论一点什么东西" git commit的意思是把暂存区的全部文件提交到本地仓库。-m后接评论。
+- git remote add origin https://github.com/name/name_cangku.git表示把你本地的仓库与GitHub上的远程仓库连接起来。只需要连接一次,以后提交的时候就可以不用谢这条命令了。name是你的github名字,name_cangku是你的仓库名。注意不要把后面的.git给漏掉了。因为我前面就是这么走过来的,绕了很多弯路。至于如何在GitHub上新建仓库,网上有很多教程,这里不再赘述了。
+- git push -u origin master 把本地仓库提交到远程仓库。(最后一步)在你的远程仓库上刷新一下就可以看到你提交的文件了。
+- 最后提到的是,在git commit -m ""之前,可以重复git add到暂存区。但是git commit会把你之前存放在暂存区的全部文件一次性全部提交到本地仓库。
+
+## 版本的回溯与前进
+
+提交一个文件,有时候我们会提交很多次,在提交历史中,这样就产生了不同的版本。每次提交,Git会把他们串成一条时间线。如何回溯到我们提交的上一个版本,用git reset --hard + 版本号即可。版本号可以用git log来查看,每一次的版本都会产生不一样的版本号。
+
+回溯之后,git log查看一下发现离我们最近的那个版本已经不见了。但是我还想要前进到最近的版本应该如何?只要git reset --hard + 版本号就行。退一步来讲,虽然我们可以通过git reset --hard + 版本号,靠记住版本号来可以在不同的版本之间来回穿梭。
+
+但是,有时候把版本号弄丢了怎么办?git reflog帮你记录了每一次的命令,这样就可以找到版本号了,这样你又可以通过git reset来版本穿梭了。
+
+## 撤销
+
+**场景1:**在工作区时,你修改了一个东西,你想撤销修改,git checkout -- file。廖雪峰老师指出撤销修改就回到和版本库一模一样的状态,即用版本库里的版本替换工作区的版本。
+
+**场景2:**你修改了一个内容,并且已经git add到暂存区了。想撤销怎么办?回溯版本,git reset --hard + 版本号,再git checkout -- file,替换工作区的版本。
+
+**场景3:**你修改了一个内容,并且已经git commit到了master。跟场景2一样,版本回溯,再进行撤销。
+
+## 删除
+
+如果你git add一个文件到暂存区,然后在工作区又把文件删除了,Git会知道你删除了文件。如果你要把版本库里的文件删除,git rm 并且git commit -m "xxx".
+
+如果你误删了工作区的文件,怎么办?使用撤销命令,git checkout --就可以。这再次证明了撤销命令其实就是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
+
+## 分支
+
+分支,就像平行宇宙,廖雪峰老师如是说。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
+
+### 创建与合并分支
+
+![img](data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==)
+
+在没有其他分支插进来时,只有一个master主分支。每次你git push -u origin master 提交就是增加一条时间轴,master也会跟着移动。
+
+创建一个other的分支,通过other提交,虽然时间轴向前走了,但是主分支master还在原来的位置。
+
+理论分析完,看一下命令怎么写。
+
+**创建分支other,切换到other分支。**
+
+```
+git branch other
+git checkout other
+```
+
+**查看当前所有分支**
+
+```
+git branch
+```
+
+
+
+```
+* other
+  master
+```
+
+当前的分支会有一个*
+
+**用other提交**
+
+```
+git add ./xxx/
+git commit -m "xxx"
+```
+
+**other分支完成,切换回master**
+
+```
+git checkout master
+```
+
+此时,master分支上并没有other的文件,因为分支还没有合并。
+
+**合并分支**
+
+```
+git merge other
+```
+
+合并完成之后,就可以在master分支上查看到文件了。
+
+**删除other分支**
+
+```
+git branch -d other
+```
+
+我由此想到,在以后工作中,应该是一个开放小组共同开发一个项目,组长会创建很多分支,每一个分支可以交给一个人去开发某一个功能,一个小组共同开发而且不会相互干扰。谁的功能完成了,可以由组长合并一下完成了的分支。哦,完美!
+
+## 解决合并分支问题
+
+
+
+![图片](https://mmbiz.qpic.cn/mmbiz/eQPyBffYbufFIDkCuX4BXqUgSibdycoPPEfd4SmMEBDPQzEjXN5rSCuxY0X4b1wmPCckSmnlSfAYOKFA9kWleWQ/640?wx_fmt=other&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)
+
+假如有这样一种情况,分支other已经commit了,但是此时指针指回master时,并且master没有合并,而是git add / commit 提交了。这样,就产生了冲突,主分支master文件内容与other分支的内容不一样。合并不起来!所以,
+
+ 
+
+- 修改文件的内容,让其保持一致。
+
+- git add git commit 提交。
+
+- 分支合并了。
+
+  ![img](data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==)
+
+- git log --graph 查看分支合并图
+
+- git branch -d other 删除分支,任务结束。
+
+## 分支管理策略
+
+git merge --no-ff other 禁用Fast forward模式,因为使用Fast forward模式,删除分支后,分支历史信息会丢失。Git的实现原理,点这里:[深入理解Git的实现原理](http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247486905&idx=2&sn=50d4e5789262d7440c49684e1a652c7d&chksm=ebd63295dca1bb83f50f1b5fe2947fbcf1564decb95f4d3e4a04104f2c406f3f6fb23947be56&scene=21#wechat_redirect)
+
+### BUG分支
+
+> 廖雪峰老师提到,工作中每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。但如果你手上有分支在工作中,你的上级要你改另外的分支的BUG。
+>
+> 
+>
+> 你要把现在正在工作的分支保存下来,git stash,把当前工作现场“存储”起来,等以后恢复后继续工作。当你解决BUG后,git checkout other回到自己的分支。用git stash list查看你刚刚“存放”起来的工作去哪里了。
+
+此时你要恢复工作:
+
+- git stash apply恢复却不删除stash内容,git stash drop删除stash内容。
+- git stash pop恢复的同时把stash内容也删了.
+- 此时,用git stash list查看,看不到任何stash 内容。
+
+**总结:修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场**
+
+### 删除分支
+
+- git branch -d + 分支有可能会删除失败,因为Git会保护没有被合并的分支。
+- git branch -D + 分支 强行删除,丢弃没被合并的分支。
+
+### 多人协作
+
+- git remote 查看远程库的信息,会显示origin,远程仓库默认名称为origin
+- git remote -v显示更详细的信息
+- git push -u origin master推送master分支到origin远程仓库。
+- git push -u origin other 推送other到origin远程仓库。
+
+### 抓取分支
+
+产生上图的冲突时,
+
+- git pull 把最新的提交从远程仓库中抓取下来,在本地合并,解决冲突。在进行git pull
+- 如果git pull 也失败了,还要指定分支之间的链接,这一步Git会提醒你怎么做。然后再git pull。
+
+廖雪峰老师的总结:多人协作的工作模式通常是这样:
+
+- 首先,可以试图用git push origin 
+
+  推送自己的修改;
+
+- 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
+
+- 如果合并有冲突,则解决冲突,并在本地提交;
+
+- 没有冲突或者解决掉冲突后,再用git push origin 
+
+  推送就能成功!
+
+- 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/。
+
+### Rebase
+
+git rebase 把分叉的提交历史“整理”成一条直线,看上去更直观.缺点是本地的分叉提交已经被修改过了。
+
+最后在进行git push -u origin master
+
+rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
+
+## 标签管理
+
+比如一个APP要上线,通常在版本库中打一个标签(tag),这样,就确定了打标签的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
+
+Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针。
+
+tag其实就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。比如tag v2.1就是把历史上的一个版本的东西叫做v2.1
+
+### 创建标签
+
+步骤:
+
+- git branch查看当前分支,git checkout master切换到master分支。
+- git tag <name> 打标签,默认为HEAD。比如git tag v1.0
+- 默认标签是打在最新提交的commit上的。如果想要打标签在以前的commit上,要git log找到历史提交的commit id.
+- 如果一个commt id是du2n2d9,执行git tag v1.0 du2n2d9就把这个版本打上了v1.0的标签了。
+- git tag 查看所有标签,可以知道历史版本的tag
+- 标签不是按时间顺序列出,而是按字母排序的。
+- git show <tagname> 查看标签信息。
+- git tag -a <标签名> -m "<说明>",创建带说明的标签。-a指定标签名,-m指定说明文字。用show可以查看说明。
+
+### 操作标签
+
+- git tag -d v1.0 删除标签。因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
+- git push origin <tagname> 推送某个标签到远程
+- git push origin --tags 一次性推送全部尚未推送到远程的本地标签
+- 如果标签推送到远程。git tag -d v1.0 先删除本地标签v1.0。git push origin :refs/tags/v1.0删除远程标签v1.0
+
+### 自定义Git
+
+- git config --global color.ui true让Git显示颜色,会让命令输出看起来更醒目
+- 忽略特殊文件 创建一个.gitignore文件,把需要忽略的文件名填进去。Git就会自动忽略这些文件。我也在学习中遇到过这样的问题,比如node_modules文件就可以忽略。
+
+> 忽略文件原则:忽略操作系统自动生成的文件,比如缩略图等;忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
+
+- 强制提交已忽略的的文件。git add -f <file>
+- git check-ignore -v <file>检查为什么Git会忽略该文件。
+- 给Git命令配别名,这个有点骚,就是你以后想输入git rebase时,你给它一个“外号”,就叫它git nb。以后你可以通过git nb来代替git rebase。
+
+## 常用Git命令总结
+
+- git config --global user.name "你的名字" 让你全部的Git仓库绑定你的名字
+- git config --global user.email "你的邮箱" 让你全部的Git仓库绑定你的邮箱
+- git init 初始化你的仓库
+- git add . 把工作区的文件全部提交到暂存区
+- git add ./<file>/ 把工作区的<file>文件提交到暂存区
+- git commit -m "xxx" 把暂存区的所有文件提交到仓库区,暂存区空空荡荡
+- git remote add origin https://github.com/name/name_cangku.git 把本地仓库与远程仓库连接起来
+- git push -u origin master 把仓库区的主分支master提交到远程仓库里
+- git push -u origin <其他分支> 把其他分支提交到远程仓库
+- git status查看当前仓库的状态
+- git diff 查看文件修改的具体内容
+- git log 显示从最近到最远的提交历史  git log --pretty=oneline(更简洁的方式显示)
+- git clone + 仓库地址下载克隆文件
+- git reset --hard + 版本号 回溯版本,版本号在commit的时候与master跟随在一起
+- git reflog 显示命令历史
+- git checkout -- <file> 撤销命令,用版本库里的文件替换掉工作区的文件。我觉得就像是Git世界的ctrl + z
+- git rm 删除版本库的文件
+- git branch 查看当前所有分支
+- git branch <分支名字> 创建分支
+- git checkout <分支名字> 切换到分支
+- git merge <分支名字> 合并分支
+- git branch -d <分支名字> 删除分支,有可能会删除失败,因为Git会保护没有被合并的分支
+- git branch -D + <分支名字> 强行删除,丢弃没被合并的分支
+- git log --graph 查看分支合并图
+- git merge --no-ff <分支名字> 合并分支的时候禁用Fast forward模式,因为这个模式会丢失分支历史信息
+- git stash 当有其他任务插进来时,把当前工作现场“存储”起来,以后恢复后继续工作
+- git stash list 查看你刚刚“存放”起来的工作去哪里了
+- git stash apply 恢复却不删除stash内容
+- git stash drop 删除stash内容
+- git stash pop 恢复的同时把stash内容也删了
+- git remote 查看远程库的信息,会显示origin,远程仓库默认名称为origin
+- git remote -v 显示更详细的信息
+- git pull 把最新的提交从远程仓库中抓取下来,在本地合并,和git push相反
+- git rebase 把分叉的提交历史“整理”成一条直线,看上去更直观
+- git tag 查看所有标签,可以知道历史版本的tag
+- git tag <name> 打标签,默认为HEAD。比如git tag v1.0
+- git tag <tagName> <版本号> 把版本号打上标签,版本号就是commit时,跟在旁边的一串字母数字
+- git show <tagName> 查看标签信息
+- git tag -a <tagName> -m "<说明>" 创建带说明的标签。-a指定标签名,-m指定说明文字
+- git tag -d <tagName> 删除标签
+- git push origin <tagname> 推送某个标签到远程
+- git push origin --tags 一次性推送全部尚未推送到远程的本地标签
+- git push origin :refs/tags/<tagname> 删除远程标签<tagname>
+- git config --global color.ui true 让Git显示颜色,会让命令输出看起来更醒目
+- git add -f <file> 强制提交已忽略的的文件
+- git check-ignore -v <file> 检查为什么Git会忽略该文件

+ 84 - 0
linux/centos网络配置.md

@@ -0,0 +1,84 @@
+# 1.配置网络
+1. 首先进入root模式
+2. 打开
+
+```shell
+cd /etc/sysconfig/network-scripts/
+vim ifcfg-ens33
+```
+```shell
+TYPE=Ethernet
+BOOTPROTO=static //这里改一下,默认的是dhcp,改成static表示静态的意思
+DEFROUTE=yes
+PEERDNS=yes
+PEERROUTES=yes
+IPV4_FAILURE_FATAL=no
+IPV6INIT=yes
+IPV6_AUTOCONF=yes
+IPV6_DEFROUTE=yes
+IPV6_PEERDNS=yes
+IPV6_PEERROUTES=yes
+IPV6_FAILURE_FATAL=no
+IPV6_ADDR_GEN_MODE=stable-privacy
+NAME=ens33
+UUID=fa3a4df3-e833-410a-9c95-94e3ee645d12
+DEVICE=ens33
+ONBOOT=yes //这里改成yes,表示网卡设备开机启动
+//下边的都是加上的
+IPADDR=192.168.133.20 //IP地址自己写,只要和网关处于同一网段就行,如192.168.133.xxx
+PREFIXO=24
+NTSMASK=255.255.0.0 //这里是子网掩码
+GATEWAY=192.168.133.2 //这里是网关
+DNS1=114.114.114.114
+DNS2=8.8.8.8
+```
+3. 配置如下
+
+![image-20210705094943628](../照片/image-20210705094943628.png)
+
+4. ![image-20210628154743311](D:\笔记\照片\image-20210628154743311.png)
+
+5. 重启即可
+```shell
+systemctl restart network
+```
+
+# 2.关闭防火墙
+
+```
+systemctl stop firewalld && systemctl disable firewalld
+```
+
+# 3.开启时间同步
+
+首先要更新yum源
+
+```
+1.先备份
+mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
+2.下载
+wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
+或者
+curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
+3.清理缓存
+yum clean all     # 清除系统所有的yum缓存
+yum makecache     # 生成yum缓存
+
+
+```
+
+
+
+
+```
+yum install ntp -y
+systemctl enable ntpd && systemctl start ntpd
+```
+
+# 4.主机名称
+
+```
+hostnamectl set-hostname  
+```
+
+

+ 56 - 0
linux/学习正则表达式.md

@@ -0,0 +1,56 @@
+# 基本使用
+
+## grep  "搜索的字符"  文件名
+
+	grep "good"  test
+
+* -c	统计出现次数
+* -i	 不区分大小写
+* -n	删除行号
+* -v	反向匹配
+>这些参数也可以一起使用
+
+
+## 正则表达式与grep
+
+### 基础的正则表达式
+
+* \*符号	 匹配0次或者多次
+* .符号	匹配除了换行符之外的所有符号
+* \{n,m\}    指定匹配次数
+* ^表示以……开头
+* $		结尾
+* ^$	空行
+
+### 正则表达式的范围匹配
+
+* []	  匹配范围
+* \b	 匹配边界---表示只匹配\b里面的字符
+* \B	 非单词边界匹配
+* \w	 字母数字和下划线
+* \W	非字母非数字非下划线
+
+### 通配符的使用
+
+>注意该字符都要加上转义字符\
+
+
+* ?	      匹配前一个字符0次或者1次
+* \+	       匹配前一个字符1次以上
+* () 	  	一般与 | 一起使用表示枚举
+
+
+
+# 高级使用
+
+## 可以使用$()或者``结合运行复杂命令
+
+```
+docker rmi --force `docker images | grep doss-api | awk '{print $3}'`    
+或者
+docker rmi --force $(docker images | grep doss-api | awk '{print $3}')
+表示先执行docker images | grep doss-api | awk '{print $3}'
+将它执行后的结果,执行docker  rmi   
+
+```
+

+ 111 - 0
前端/mock/Mock的使用.md

@@ -0,0 +1,111 @@
+# 1.什么是Mock
+
+Mock: 一种模拟后端接口的解决方案,能让我们提前调用模拟接口,完成前端开发
+
+[官网地址](http://mockjs.com/)
+
+# 2.Mock优点
+
+![image-20210819095725847](../../照片/image-20210819095725847.png)
+
+# 3.Mock的使用
+
+```
+npm install mockjs
+var Mock = require('mockjs')
+var data = Mock.mock({....})
+```
+
+# 4.Mock语法规范
+
+## 4.1Mock.js 的语法规范包括两部分:
+
+1. 数据模板定义规范(Data Template Definition,DTD)
+	数据模板中的每个属性由 3 部分构成:属性名(name)、生成规则(rule)、属性值(value):
+```
+'name|rule': valu
+```
+
+2. 数据占位符定义规范(Data Placeholder Definition,DPD)
+	占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中
+```
+@占位符
+@占位符(参数 [, 参数])
+```
+
+## 4.2数据模板定义规范
+
+### 4.2.1属性值是字符串 String
+```
+1. 'name|min-max': string
+通过重复 string 生成一个字符串,重复次数大于等于 min,小于等于 max。
+2. 'name|count': string
+通过重复 string 生成一个字符串,重复次数等于 count
+```
+
+### 4.2.2属性值是数字 Numbe
+```
+1. 'name|min-max': number
+生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定类型
+```
+
+### 4.2.3其他类型
+```
+@id() : 得到随机的id
+@cname(): 随机生成中文名字
+@date('yyyy-MM-dd'): 随机生成日期
+@paragraph(): 描述
+@email(): 邮箱地址
+```
+
+## 4.3Mock.js基本代码格式
+
+```
+Mock.mock({
+id: "@id()",//得到随机的id,对象
+username: "@cname()",//随机生成中文名字
+date: "@date()",//随机生成日期
+description: "@paragraph()",//描述
+email: "@email()", //email
+'age|18-38': 0
+})
+```
+
+# 5.Mock在Vue中使用
+
+步骤:
+1. 定义接口路由,在接口中并返回mock模拟的数据
+
+```
+module.exports = function (app) { app.use('/api/userinfo', (req, res) => { res.json(obj) })
+```
+
+2. 在vue.config.js中配置devServer,在before属性中引入接口路由函数
+
+```
+module.exports = {
+	devServer: {
+		before: require('./mock/index.js')//引入mock/index.js
+	}
+}
+```
+
+3. 使用axios调用该接口,获取数据
+
+
+
+# 6.如何控制Mock接口的开关?
+
+1. 新建.env.development,定义环境变量
+```
+MOCK=true
+```
+2. 定义接口路由前,判断当前MOCK环境变量是否为true
+```
+module.exports = function (app) {
+	if (process.env.MOCK == 'true') {
+		app.use('/api/userinfo', (req, res) => {
+		res.json(obj)
+	})
+}
+```

+ 0 - 0
前端/react/.md


+ 60 - 0
前端/react/1.react简介.md

@@ -0,0 +1,60 @@
+# 1.是什么
+
+用于构建用户界面的jsp库
+
+# 2.为什么学习
+
+1. 原生jsp操作DOM繁琐,效率低
+2. jsp直接操作DOM,浏览器会进行大量重绘重排
+3. jsp没有组件化方案
+
+# 3.react的特点
+
+1. 组件化模式
+2. 移动端开发
+3. 虚拟DOM+优秀Diffing算法
+
+# 4.虚拟DOM与真实DOM
+
+1. React提供了一些API来创建一种 “特别” 的一般js对象
+2.	虚拟DOM对象最终都会被React转换为真实的DOM
+3.	我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界。
+
+# 5.JSX
+
+1.	全称:  JavaScript XML
+2.	react定义的一种类似于XML的JS扩展语法: JS + XML本质是React.createElement(component, props, ...children)方法的语法糖
+3.	作用: 用来简化创建虚拟DOM 
+1)	写法:var ele = <h1>Hello JSX!</h1>
+2)	注意1:它不是字符串, 也不是HTML/XML标签
+3)	注意2:它最终产生的就是一个JS对象
+4.	标签名任意: HTML标签或其它标签
+5.	标签属性任意: HTML标签属性或其它
+6.	基本语法规则
+1)	遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析
+2)	遇到以 { 开头的代码,以JS语法解析: 标签中的js表达式必须用{ }包含
+7.	babel.js的作用
+1)	浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行
+2)	只要用了JSX,都要加上type="text/babel", 声明需要babel来处理
+
+# 6. 渲染虚拟DOM(元素)
+
+1.	语法:  ReactDOM.render(virtualDOM, containerDOM)
+2.	作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示
+3.	参数说明
+1)	参数一: 纯js或jsx创建的虚拟dom对象
+2)	参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)
+
+# 7.模块与组件
+
+## 1.模块
+
+1.	理解:向外提供特定功能的js程序, 一般就是一个js文件
+2.	为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂。
+3.	作用:复用js, 简化js的编写, 提高js运行效率
+
+## 2.组件
+
+1.	理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)
+2.	为什么要用组件: 一个界面的功能更复杂
+3.	作用:复用编码, 简化项目编码, 提高运行效率

+ 80 - 0
前端/react/2.react组件.md

@@ -0,0 +1,80 @@
+# 核心概念
+
+## 1.state
+
+### 1.定义
+
+1.	state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
+2.	组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
+3.	与用户交互的桥梁
+
+### 2.注意事项
+
+1.	组件中render方法中的this为组件实例对象
+2.	组件自定义的方法中this为undefined,如何解决?
+a)	强制绑定this: 通过函数对象的bind()
+b)	箭头函数
+3.	状态数据,不能直接修改或更新
+
+### 3.关于__proto__
+
+1. 类中的this定义会挂载到类中
+
+![image-20210711160930064](../../照片/image-20210711160930064.png)
+
+2. 类中定于的函数会挂载到__protot__中
+
+![image-20210711161011771](../../照片/image-20210711161011771.png)
+
+3. 如果直接访问类中的函数,this会指向undefined
+
+## 2.props
+
+### 1.定义
+
+1. 组件之间进行传值。
+2. state 和 props 主要的区别在于 props 是只读的,而 state 可以根据与用户交互来改变。
+3. 子组件只能通过 props 来传递数据。
+
+### 2.理解
+
+1.	每个组件对象都会有props(properties的简写)属性
+2.	组件标签的所有属性都保存在props中
+
+### 3.作用
+
+1.	通过标签属性从组件外向组件内传递变化的数据
+2.	注意: 组件内部不要修改props数据
+
+## 3.refs
+
+### 1.定义
+
+组件内的标签可以定义ref属性来标识自己,代替ID的存在
+收集到的是真实DOM
+
+### 2.种类
+
+1. 字符串形式的ref
+
+   ![image-20210711210508635](../../照片/image-20210711210508635.png)
+
+2. 回调形式的ref
+
+![image-20210711210528433](../../照片/image-20210711210528433.png)
+
+3. createRef创建ref容器·
+
+![image-20210711210543482](../../照片/image-20210711210543482.png)
+
+## 4.事件处理
+
+1.	通过onXxx属性指定事件处理函数(注意大小写)
+1)	React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 --- 兼容性
+2)	React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) --- 高效
+2.	通过event.target得到发生事件的DOM元素对象 --- 不要过度使用ref
+
+## 5.受控组件和非受控组件
+
+受控组件:输入类的DOM维护到state里面 --- 尽量采取这种形式,不要过度使用ref 
+非受控组件:输入类的DOM采取现用现取形式

+ 43 - 0
前端/react/3.生命周期.md

@@ -0,0 +1,43 @@
+# 1.定义
+
+1.	组件从创建到死亡它会经历一些特定的阶段。
+2.	React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
+3.	我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。
+
+# 2.生命周期(旧)
+
+![image-20210711233704769](../../照片/image-20210711233704769.png)
+注意父组件调用render,初始化不走流程,第二次才走!!
+
+1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
+
+	1)	constructor()
+	2)	componentWillMount()
+	3)	render()
+	4)	componentDidMount() --- 初始化
+2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
+
+	1)	shouldComponentUpdate()
+	2)	componentWillUpdate()
+	3)	render()
+	4)	componentDidUpdate()
+3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
+
+	1)	componentWillUnmount() --- 收尾
+
+# 3.生命周期(新)
+
+![image-20210712085719929](../../照片/image-20210712085719929.png)
+
+## 1.即将弃用
+
+1.	componentWillMount
+2.	componentWillReceiveProps
+3.	componentWillUpdate
+现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
+
+## 2.重要的勾子
+
+1.	render:初始化渲染或更新渲染调用
+2.	componentDidMount:开启监听, 发送ajax请求
+3.	componentWillUnmount:做一些收尾工作, 如: 清理定时器

+ 30 - 0
前端/react/4.DOM的diffing算法.md

@@ -0,0 +1,30 @@
+1). react/vue中的key有什么作用?(key的内部原理是什么?)
+2). 为什么遍历列表时,key最好不要用index?
+
+# 1. 虚拟DOM中key的作用:
+1)  简单的说: key是虚拟DOM对象的标识, 在更新显示时key起着极其重要的作用。
+
+2)  详细的说: 当状态中的数据发生变化时,react会根据【新数据】生成【新的虚拟DOM】, 
+随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:
+
+a. 旧虚拟DOM中找到了与新虚拟DOM相同的key:
+	(1).若虚拟DOM中内容没变, 直接使用之前的真实DOM
+	(2).若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
+
+b. 旧虚拟DOM中未找到与新虚拟DOM相同的key
+根据数据创建新的真实DOM,随后渲染到到页面
+
+# 2.用index作为key可能会引发的问题:
+
+1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
+会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
+
+2. 如果结构中还包含输入类的DOM:
+会产生错误DOM更新 ==> 界面有问题。
+
+3. 注意!如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
+
+# 3.开发中如何选择key?:
+
+1. 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
+2. 如果确定只是简单的展示数据,用index也是可以的。

+ 44 - 0
前端/react/5.react脚手架.md

@@ -0,0 +1,44 @@
+# 1.定义
+
+1.	xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
+	1.	包含了所有需要的配置(语法检查、jsx编译、devServer…)
+	2.	下载好了所有相关的依赖
+	3.	可以直接运行一个简单效果
+2.	react提供了一个用于创建react项目的脚手架库: create-react-app
+3.	项目的整体技术架构为:  react + webpack + es6 + eslint
+4.	使用脚手架开发的项目的特点: 模块化, 组件化, 工程化
+
+# 2.react脚手架项目结构
+
+public ---- 静态资源文件夹
+		favicon.icon ------ 网站页签图标
+		index.html -------- 主页面
+		logo192.png ------- logo图
+		logo512.png ------- logo图
+		manifest.json ----- 应用加壳的配置文件
+		robots.txt -------- 爬虫协议文件
+src ---- 源码文件夹
+		App.css -------- App组件的样式
+		App.js --------- App组件
+		App.test.js ---- 用于给App做测试
+		index.css ------ 通用样式
+		index.js ------- 入口文件
+		logo.svg ------- logo图
+		reportWebVitals.js
+			--- 页面性能分析文件(需要web-vitals库的支持)
+		setupTests.js
+			---- 组件单元测试的文件(需要jest-dom库的支持)
+
+# 3.功能界面的组件化编码流程(通用)
+
+1. 拆分组件: 拆分界面,抽取组件
+
+2. 实现静态组件: 使用组件实现静态页面效果
+
+3. 实现动态组件
+
+   3.1 动态显示初始化数据
+   	3.1.1 数据类型
+   	3.1.2 数据名称
+   	3.1.2 保存在哪个组件?
+   3.2 交互(从绑定事件监听开始)

+ 18 - 0
前端/react/6.React ajax.md

@@ -0,0 +1,18 @@
+# 1.定义
+
+1.	React本身只关注于界面, 并不包含发送ajax请求的代码
+2.	前端应用需要通过ajax请求与后台进行交互(json数据)
+3.	react应用中需要集成第三方ajax库(或自己封装)
+
+# 2.常见库
+
+1.	jQuery: 比较重, 如果需要另外引入不建议使用
+2.	axios: 轻量级, 建议使用
+1)	封装XmlHttpRequest对象的ajax
+2)	 promise风格
+3)	可以用在浏览器端和node服务器端
+
+# 3.axios
+
+https://github.com/axios/axios
+

+ 55 - 0
前端/react/7.React路由.md

@@ -0,0 +1,55 @@
+# 1.定义
+
+## 1.SPA的理解
+
+1.	单页Web应用(single page web application,SPA)。
+2.	整个应用只有一个完整的页面。
+3.	点击页面中的链接不会刷新页面,只会做页面的局部更新。
+4.	数据都需要通过ajax请求获取, 并在前端异步展现。
+
+## 2.路由的理解
+
+### 1.什么是路由?
+
+1. 一个路由就是一个映射关系(key:value)
+2.	key为路径, value可能是function或component
+
+### 2.路由分类
+
+1.	后端路由:
+1)	理解: value是function, 用来处理客户端提交的请求。
+2)	注册路由: router.get(path, function(req, res))
+3)	工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
+2.	前端路由:
+1)	浏览器端路由,value是component,用于展示页面内容。
+2)	注册路由: <Route path="/test" component={Test}>
+3)	工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件
+
+### 3. react-router-dom的理解
+
+1.	react的一个插件库。
+2.	专门用来实现一个SPA应用。
+3.	基于react的项目基本都会用到此库。
+
+# 2.react-router-dom相关API
+
+## 1.内置组件
+
+1.	<BrowserRouter>
+2.	<HashRouter>
+3.	<Route>
+4.	<Redirect>
+5.	<Link>
+6.	<NavLink>
+7.	<Switch>
+
+## 2.其它
+
+1.	history对象
+2.	match对象
+3.	withRouter函数
+
+
+
+
+

+ 187 - 0
前端/react/8.路由总结.md

@@ -0,0 +1,187 @@
+## 一、todoList案例相关知识点
+
+1. 拆分组件、实现静态组件,注意:className、style的写法
+2. 动态初始化列表,如何确定将数据放在哪个组件的state中?
+
+	——某个组件使用:放在其自身的state中
+	——某些组件使用:放在他们共同的父组件state中(官方称此操作为:状态提升)
+3.	关于父子之间通信:
+	1. 【父组件】给【子组件】传递数据:通过props传递
+	2. 【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递一个函数
+4. 注意defaultChecked 和 checked的区别,类似的还有:defaultValue 和 value
+5. 状态在哪里,操作状态的方法就在哪里
+
+## 二、github搜索案例相关知识点
+
+1. 设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办。
+2. ES6小知识点:解构赋值+重命名
+    let obj = {a:{b:1}}
+    const {a} = obj; //传统解构赋值
+    const {a:{b}} = obj; //连续解构赋值
+    const {a:{b:value}} = obj; //连续解构赋值+重命名
+3. 消息订阅与发布机制
+    1. 先订阅,再发布(理解:有一种隔空对话的感觉)
+    2. 适用于任意组件间通信
+    3. 要在组件的componentWillUnmount中取消订阅
+    4. fetch发送请求(关注分离的设计思想)
+    
+    		try {
+    		const response= await fetch(`/api1/search/users2?q=${keyWord}`)
+    		const data = await response.json()
+   		console.log(data);
+    				} catch (error) {
+    				console.log('请求出错',error);
+    				}
+
+
+## 三、路由的基本使用
+
+1. 明确好界面中的导航区、展示区
+2. 导航区的a标签改为Link标签
+<Link to="/xxxxx">Demo</Link>
+3. 展示区写Route标签进行路径的匹配
+<Route path='/xxxx' component={Demo}/>
+4. <App>的最外侧包裹了一个<BrowserRouter>或<HashRouter>
+
+## 四、路由组件与一般组件
+
+1. 写法不同:
+一般组件:<Demo/>
+路由组件:<Route path="/demo" component={Demo}/>
+2. 存放位置不同:
+一般组件:components
+路由组件:pages
+3. 接收到的props不同:
+   一般组件:写组件标签时传递了什么,就能收到什么
+   路由组件:接收到三个固定的属性
+        history:
+            go: ƒ go(n)
+            goBack: ƒ goBack()
+            goForward: ƒ goForward()
+            push: ƒ push(path, state)
+            replace: ƒ replace(path, state)
+        location:
+            pathname: "/about"
+            search: ""
+            state: undefined
+        match:
+            params: {}
+            path: "/about"
+            url: "/about"
+
+## 五、NavLink与封装NavLink
+
+1. NavLink可以实现路由链接的高亮,通过activeClassName指定样式名
+
+## 六、Switch的使用
+
+1. 通常情况下,path和component是一一对应的关系。
+2. Switch可以提高路由匹配效率(单一匹配)。
+
+## 七、解决多级路径刷新页面样式丢失的问题
+
+1. public/index.html 中 引入样式时不写 ./ 写 / (常用)
+2. public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
+3. 使用HashRouter
+
+## 八、路由的严格匹配与模糊匹配
+
+1. 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
+2. 开启严格匹配:<Route exact={true} path="/about" component={About}/>
+3. 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
+
+## 九、Redirect的使用	
+
+1. 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
+2. 具体编码:
+        <Switch>
+        <Route path="/about" component={About}/>
+        <Route path="/home" component={Home}/>
+        <Redirect to="/about"/>
+        </Switch>
+
+## 十、嵌套路由
+
+1.注册子路由时要写上父路由的path值
+2.路由的匹配是按照注册路由的顺序进行的
+
+## 十一、向路由组件传递参数
+1. params参数
+
+	路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
+	注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
+	接收参数:this.props.match.params
+2. search参数
+
+	路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
+	注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
+	接收参数:this.props.location.search
+	备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
+3. state参数
+
+	路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
+	注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
+	接收参数:this.props.location.state
+	备注:刷新也可以保留住参数
+
+
+
+## 十二、编程式路由导航
+
+借助this.prosp.history对象上的API对操作路由跳转、前进、后退
+	-this.prosp.history.push()
+	-this.prosp.history.replace()
+	-this.prosp.history.goBack()
+	-this.prosp.history.goForward()
+	-this.prosp.history.go()
+
+## 十三、BrowserRouter与HashRouter的区别
+
+1. 底层原理不一样:
+
+	BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
+	HashRouter使用的是URL的哈希值。
+2. path表现形式不一样
+
+	BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
+	HashRouter的路径包含#,例如:localhost:3000/#/demo/test
+3. 刷新后对路由state参数的影响
+
+	(1).BrowserRouter没有任何影响,因为state保存在history对象中。
+	(2).HashRouter刷新后会导致路由state参数的丢失!!!
+4. 备注:HashRouter可以用于解决一些路径错误相关的问题。
+
+## 十四、antd的按需引入+自定主题
+1. 安装依赖:yarn add react-app-rewired customize-cra babel-plugin-import less less-loader
+2. 修改package.json
+
+```
+        "scripts": {
+        "start": "react-app-rewired start",
+        "build": "react-app-rewired build",
+        "test": "react-app-rewired test",
+        "eject": "react-scripts eject"
+        },
+```
+
+3. 根目录下创建config-overrides.js
+
+//配置具体的修改规则
+```
+const { override, fixBabelImports,addLessLoader} = require('customize-cra');
+module.exports = override(
+fixBabelImports('import', {
+libraryName: 'antd',
+libraryDirectory: 'es',
+style: true,
+}),
+addLessLoader({
+lessOptions:{
+javascriptEnabled: true,
+modifyVars: { '@primary-color': 'green' },
+}
+}),
+);
+```
+
+4. 备注:不用在组件里亲自引入样式了,即:import 'antd/dist/antd.css'应该删掉

+ 311 - 0
后端/Mysql/1.MySQL基础课堂笔记.md

@@ -0,0 +1,311 @@
+
+
+## 数据库的基本概念
+
+    1. 数据库的英文单词: DataBase 简称 : DB
+    2. 什么数据库?
+    * 用于存储和管理数据的仓库。
+    
+    3. 数据库的特点:
+    1. 持久化存储数据的。其实数据库就是一个文件系统
+    2. 方便存储和管理数据
+    3. 使用了统一的方式操作数据库 -- SQL
+
+# SQL
+
+	1.什么是SQL?
+		Structured Query Language:结构化查询语言
+		其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
+		
+	2.SQL通用语法
+		1. SQL 语句可以单行或多行书写,以分号结尾。
+		2. 可使用空格和缩进来增强语句的可读性。
+		3. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
+		4. 3 种注释
+			* 单行注释: -- 注释内容 或 # 注释内容(mysql 特有) 
+			* 多行注释: /* 注释 */
+		
+	3. SQL分类
+		1) DDL(Data Definition Language)数据定义语言
+			用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
+		2) DML(Data Manipulation Language)数据操作语言
+			用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
+		3) DQL(Data Query Language)数据查询语言
+			用来查询数据库中表的记录(数据)。关键字:select, where 等
+		4) DCL(Data Control Language)数据控制语言(了解)
+			用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
+
+## DDL:操作数据库、表
+
+	1. 操作数据库:CRUD
+		1. C(Create):创建
+			* 创建数据库:
+				* create database 数据库名称;
+			* 创建数据库,判断不存在,再创建:
+				* create database if not exists 数据库名称;
+			* 创建数据库,并指定字符集
+				* create database 数据库名称 character set 字符集名;
+	
+			* 练习: 创建db4数据库,判断是否存在,并制定字符集为gbk
+				* create database if not exists db4 character set gbk;
+		2. R(Retrieve):查询
+			* 查询所有数据库的名称:
+				* show databases;
+			* 查询某个数据库的字符集:查询某个数据库的创建语句
+				* show create database 数据库名称;
+		3. U(Update):修改
+			* 修改数据库的字符集
+				* alter database 数据库名称 character set 字符集名称;
+		4. D(Delete):删除
+			* 删除数据库
+				* drop database 数据库名称;
+			* 判断数据库存在,存在再删除
+				* drop database if exists 数据库名称;
+		5. 使用数据库
+			* 查询当前正在使用的数据库名称
+				* select database();
+			* 使用数据库
+				* use 数据库名称;
+
+
+	2. 操作表
+		1. C(Create):创建
+			1. 语法:
+				create table 表名(
+					列名1 数据类型1,
+					列名2 数据类型2,
+					....
+					列名n 数据类型n
+				);
+				* 注意:最后一列,不需要加逗号(,)
+				* 数据库类型:
+					1. int:整数类型
+						* age int,
+					2. double:小数类型
+						* score double(5,2)
+					3. date:日期,只包含年月日,yyyy-MM-dd
+					4. datetime:日期,包含年月日时分秒	 yyyy-MM-dd HH:mm:ss
+					5. timestamp:时间错类型	包含年月日时分秒	 yyyy-MM-dd HH:mm:ss	
+						* 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
+	
+					6. varchar:字符串
+						* name varchar(20):姓名最大20个字符
+						* zhangsan 8个字符  张三 2个字符
+
+
+			* 创建表
+				create table student(
+					id int,
+					name varchar(32),
+					age int ,
+					score double(4,1),
+					birthday date,
+					insert_time timestamp
+				);
+			* 复制表:
+				* create table 表名 like 被复制的表名;	  	
+		2. R(Retrieve):查询
+			* 查询某个数据库中所有的表名称
+				* show tables;
+			* 查询表结构
+				* desc 表名;
+		3. U(Update):修改
+			1. 修改表名
+				alter table 表名 rename to 新的表名;
+			2. 修改表的字符集
+				alter table 表名 character set 字符集名称;
+			3. 添加一列
+				alter table 表名 add 列名 数据类型;
+			4. 修改列名称 类型
+				alter table 表名 change 列名 新列别 新数据类型;
+				alter table 表名 modify 列名 新数据类型;
+			5. 删除列
+				alter table 表名 drop 列名;
+		4. D(Delete):删除
+			* drop table 表名;
+			* drop table  if exists 表名 ;
+
+## DML:增删改表中数据
+
+	1. 添加数据:
+		* 语法:
+			* insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
+		* 注意:
+			1. 列名和值要一一对应。
+			2. 如果表名后,不定义列名,则默认给所有列添加值
+				insert into 表名 values(值1,值2,...值n);
+			3. 除了数字类型,其他类型需要使用引号(单双都可以)引起来
+	2. 删除数据:
+		* 语法:
+			* delete from 表名 [where 条件]
+		* 注意:
+			1. 如果不加条件,则删除表中所有记录。
+			2. 如果要删除所有记录
+				1. delete from 表名; -- 不推荐使用。有多少条记录就会执行多少次删除操作
+				2. TRUNCATE TABLE 表名; -- 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
+	3. 修改数据:
+		* 语法:
+			* update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];
+	
+		* 注意:
+			1. 如果不加任何条件,则会将表中所有记录全部修改。
+
+
+
+## DQL:查询表中的记录
+	* select * from 表名;
+	
+	1. 语法:
+		select
+			字段列表
+		from
+			表名列表
+		where
+			条件列表
+		group by
+			分组字段
+		having
+			分组之后的条件
+		order by
+			排序
+		limit
+			分页限定
+
+
+	2. 基础查询
+		1. 多个字段的查询
+			select 字段名1,字段名2... from 表名;
+			* 注意:
+				* 如果查询所有字段,则可以使用*来替代字段列表。
+		2. 去除重复:
+			* distinct
+		3. 计算列
+			* 一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
+			* ifnull(表达式1,表达式2):null参与的运算,计算结果都为null
+				* 表达式1:哪个字段需要判断是否为null
+				* 如果该字段为null后的替换值。
+		4. 起别名:
+			* as:as也可以省略
+
+
+	3. 条件查询
+		1. where子句后跟条件
+		2. 运算符
+			* > 、< 、<= 、>= 、= 、<>
+			* BETWEEN...AND  
+			* IN( 集合) 
+			* LIKE:模糊查询
+				* 占位符:
+					* _:单个任意字符
+					* %:多个任意字符
+			* IS NULL  
+			* and  或 &&
+			* or  或 || 
+			* not  或 !
+			
+				-- 查询年龄大于20岁
+	
+				SELECT * FROM student WHERE age > 20;
+				
+				SELECT * FROM student WHERE age >= 20;
+				
+				-- 查询年龄等于20岁
+				SELECT * FROM student WHERE age = 20;
+				
+				-- 查询年龄不等于20岁
+				SELECT * FROM student WHERE age != 20;
+				SELECT * FROM student WHERE age <> 20;
+				
+				-- 查询年龄大于等于20 小于等于30
+				
+				SELECT * FROM student WHERE age >= 20 &&  age <=30;
+				SELECT * FROM student WHERE age >= 20 AND  age <=30;
+				SELECT * FROM student WHERE age BETWEEN 20 AND 30;
+				
+				-- 查询年龄22岁,18岁,25岁的信息
+				SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
+				SELECT * FROM student WHERE age IN (22,18,25);
+				
+				-- 查询英语成绩为null
+				SELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 = (!=) 判断
+				
+				SELECT * FROM student WHERE english IS NULL;
+				
+				-- 查询英语成绩不为null
+				SELECT * FROM student WHERE english  IS NOT NULL;
+
+
+
+				-- 查询姓马的有哪些? like
+				SELECT * FROM student WHERE NAME LIKE '马%';
+				-- 查询姓名第二个字是化的人
+				
+				SELECT * FROM student WHERE NAME LIKE "_化%";
+				
+				-- 查询姓名是3个字的人
+				SELECT * FROM student WHERE NAME LIKE '___';
+
+
+​				
+​				-- 查询姓名中包含德的人
+​				SELECT * FROM student WHERE NAME LIKE '%德%';
+
+## DCL:
+	* SQL分类:
+		1. DDL:操作数据库和表
+		2. DML:增删改表中数据
+		3. DQL:查询表中数据
+		4. DCL:管理用户,授权
+	
+	* DBA:数据库管理员
+	
+	* DCL:管理用户,授权
+		1. 管理用户
+			1. 添加用户:
+				* 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
+			2. 删除用户:
+				* 语法:DROP USER '用户名'@'主机名';
+			3. 修改用户密码:
+				
+				UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
+				UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';
+				
+				SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
+				SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');
+	
+				* mysql中忘记了root用户的密码?
+					1. cmd -- > net stop mysql 停止mysql服务
+						* 需要管理员运行该cmd
+	
+					2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables
+					3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功
+					4. use mysql;
+					5. update user set password = password('你的新密码') where user = 'root';
+					6. 关闭两个窗口
+					7. 打开任务管理器,手动结束mysqld.exe 的进程
+					8. 启动mysql服务
+					9. 使用新密码登录。
+			4. 查询用户:
+				-- 1. 切换到mysql数据库
+				USE myql;
+				-- 2. 查询user表
+				SELECT * FROM USER;
+				
+				* 通配符: % 表示可以在任意主机使用用户登录数据库
+	
+		2. 权限管理:
+			1. 查询权限:
+				-- 查询权限
+				SHOW GRANTS FOR '用户名'@'主机名';
+				SHOW GRANTS FOR 'lisi'@'%';
+	
+			2. 授予权限:
+				-- 授予权限
+				grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
+				-- 给张三用户授予所有权限,在任意数据库任意表上
+				
+				GRANT ALL ON *.* TO 'zhangsan'@'localhost';
+			3. 撤销权限:
+				-- 撤销权限:
+				revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
+				REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';

+ 199 - 0
后端/Mysql/2.MySQL多表&事务课堂笔记.md

@@ -0,0 +1,199 @@
+# 今日内容
+
+	1. 多表查询
+
+	2. 事务
+
+
+## 多表查询:
+	* 查询语法:
+		select
+			列名列表
+		from
+			表名列表
+		where....
+	* 准备sql
+		# 创建部门表
+		CREATE TABLE dept(
+			id INT PRIMARY KEY AUTO_INCREMENT,
+			NAME VARCHAR(20)
+		);
+		INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
+		# 创建员工表
+		CREATE TABLE emp (
+			id INT PRIMARY KEY AUTO_INCREMENT,
+			NAME VARCHAR(10),
+			gender CHAR(1), -- 性别
+			salary DOUBLE, -- 工资
+			join_date DATE, -- 入职日期
+			dept_id INT,
+			FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
+		);
+	* 笛卡尔积:
+		* 有两个集合A,B .取这两个集合的所有组成情况。
+		* 要完成多表查询,需要消除无用的数据
+	* 多表查询的分类:
+		1. 内连接查询:
+			1. 隐式内连接:使用where条件消除无用数据
+				* 例子:
+				-- 查询所有员工信息和对应的部门信息
+
+				SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
+				
+				-- 查询员工表的名称,性别。部门表的名称
+				SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
+				
+				SELECT 
+					t1.name, -- 员工表的姓名
+					t1.gender,-- 员工表的性别
+					t2.name -- 部门表的名称
+				FROM
+					emp t1,
+					dept t2
+				WHERE 
+					t1.`dept_id` = t2.`id`;
+
+	
+			2. 显式内连接:
+				* 语法: select 字段列表 from 表名1 [inner] join 表名2 on 条件
+				* 例如:
+					* SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;	
+					* SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;	
+
+			3. 内连接查询:
+				1. 从哪些表中查询数据
+				2. 条件是什么
+				3. 查询哪些字段
+		2. 外链接查询:
+			1. 左外连接:
+				* 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
+				* 查询的是左表所有数据以及其交集部分。
+				* 例子:
+					-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
+					SELECT 	t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;
+			2. 右外连接:
+				* 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
+				* 查询的是右表所有数据以及其交集部分。
+				* 例子:
+					SELECT 	* FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;
+		3. 子查询:
+			* 概念:查询中嵌套查询,称嵌套查询为子查询。
+				-- 查询工资最高的员工信息
+				-- 1 查询最高的工资是多少 9000
+				SELECT MAX(salary) FROM emp;
+				
+				-- 2 查询员工信息,并且工资等于9000的
+				SELECT * FROM emp WHERE emp.`salary` = 9000;
+				
+				-- 一条sql就完成这个操作。子查询
+				SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);
+
+			* 子查询不同情况
+				1. 子查询的结果是单行单列的:
+					* 子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =
+					* 
+					-- 查询员工工资小于平均工资的人
+					SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
+				2. 子查询的结果是多行单列的:
+					* 子查询可以作为条件,使用运算符in来判断
+					-- 查询'财务部'和'市场部'所有的员工信息
+					SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
+					SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;
+					-- 子查询
+					SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');
+
+				3. 子查询的结果是多行多列的:
+					* 子查询可以作为一张虚拟表参与查询
+					-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
+					-- 子查询
+					SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
+					WHERE t1.id = t2.dept_id;
+					
+					-- 普通内连接
+					SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` >  '2011-11-11'
+
+## 事务
+
+	1. 事务的基本介绍
+		1. 概念:
+			*  如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
+			
+		2. 操作:
+			1. 开启事务: start transaction;
+			2. 回滚:rollback;
+			3. 提交:commit;
+		3. 例子:
+			CREATE TABLE account (
+				id INT PRIMARY KEY AUTO_INCREMENT,
+				NAME VARCHAR(10),
+				balance DOUBLE
+			);
+			-- 添加数据
+			INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
+			
+			
+			SELECT * FROM account;
+			UPDATE account SET balance = 1000;
+			-- 张三给李四转账 500 元
+			
+			-- 0. 开启事务
+			START TRANSACTION;
+			-- 1. 张三账户 -500
+			
+			UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
+			-- 2. 李四账户 +500
+			-- 出错了...
+			UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
+			
+			-- 发现执行没有问题,提交事务
+			COMMIT;
+			
+			-- 发现出问题了,回滚事务
+			ROLLBACK;
+		4. MySQL数据库中事务默认自动提交
+			
+			* 事务提交的两种方式:
+				* 自动提交:
+					* mysql就是自动提交的
+					* 一条DML(增删改)语句会自动提交一次事务。
+				* 手动提交:
+					* Oracle 数据库默认是手动提交事务
+					* 需要先开启事务,再提交
+			* 修改事务的默认提交方式:
+				* 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交  0 代表手动提交
+				* 修改默认提交方式: set @@autocommit = 0;
+
+
+	2. 事务的四大特征:
+		1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
+		2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
+		3. 隔离性:多个事务之间。相互独立。
+		4. 一致性:事务操作前后,数据总量不变
+	3. 事务的隔离级别(了解)
+		* 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
+		* 存在问题:
+			1. 脏读:一个事务,读取到另一个事务中没有提交的数据
+			2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
+			3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
+		* 隔离级别:
+			1. read uncommitted:读未提交
+				* 产生的问题:脏读、不可重复读、幻读
+			2. read committed:读已提交 (Oracle)
+				* 产生的问题:不可重复读、幻读
+			3. repeatable read:可重复读 (MySQL默认)
+				* 产生的问题:幻读
+			4. serializable:串行化
+				* 可以解决所有的问题
+
+			* 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
+			* 数据库查询隔离级别:
+				* select @@tx_isolation;
+			* 数据库设置隔离级别:
+				* set global transaction isolation level  级别字符串;
+
+		* 演示:
+			set global transaction isolation level read uncommitted;
+			start transaction;
+			-- 转账操作
+			update account set balance = balance - 500 where id = 1;
+			update account set balance = balance + 500 where id = 2;

+ 255 - 0
后端/Mysql/3.MySQL约束课堂笔记.md

@@ -0,0 +1,255 @@
+
+
+## 数据库的基本概念
+	1. 数据库的英文单词: DataBase 简称 : DB
+	2. 什么数据库?
+		* 用于存储和管理数据的仓库。
+
+	3. 数据库的特点:
+		1. 持久化存储数据的。其实数据库就是一个文件系统
+		2. 方便存储和管理数据
+		3. 使用了统一的方式操作数据库 -- SQL
+
+# SQL
+
+	1.什么是SQL?
+		Structured Query Language:结构化查询语言
+		其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
+		
+	2.SQL通用语法
+		1. SQL 语句可以单行或多行书写,以分号结尾。
+		2. 可使用空格和缩进来增强语句的可读性。
+		3. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
+		4. 3 种注释
+			* 单行注释: -- 注释内容 或 # 注释内容(mysql 特有) 
+			* 多行注释: /* 注释 */
+		
+	3. SQL分类
+		1) DDL(Data Definition Language)数据定义语言
+			用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
+		2) DML(Data Manipulation Language)数据操作语言
+			用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
+		3) DQL(Data Query Language)数据查询语言
+			用来查询数据库中表的记录(数据)。关键字:select, where 等
+		4) DCL(Data Control Language)数据控制语言(了解)
+			用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
+
+## DDL:操作数据库、表
+
+	1. 操作数据库:CRUD
+		1. C(Create):创建
+			* 创建数据库:
+				* create database 数据库名称;
+			* 创建数据库,判断不存在,再创建:
+				* create database if not exists 数据库名称;
+			* 创建数据库,并指定字符集
+				* create database 数据库名称 character set 字符集名;
+
+			* 练习: 创建db4数据库,判断是否存在,并制定字符集为gbk
+				* create database if not exists db4 character set gbk;
+		2. R(Retrieve):查询
+			* 查询所有数据库的名称:
+				* show databases;
+			* 查询某个数据库的字符集:查询某个数据库的创建语句
+				* show create database 数据库名称;
+		3. U(Update):修改
+			* 修改数据库的字符集
+				* alter database 数据库名称 character set 字符集名称;
+		4. D(Delete):删除
+			* 删除数据库
+				* drop database 数据库名称;
+			* 判断数据库存在,存在再删除
+				* drop database if exists 数据库名称;
+		5. 使用数据库
+			* 查询当前正在使用的数据库名称
+				* select database();
+			* 使用数据库
+				* use 数据库名称;
+
+
+	2. 操作表
+		1. C(Create):创建
+			1. 语法:
+				create table 表名(
+					列名1 数据类型1,
+					列名2 数据类型2,
+					....
+					列名n 数据类型n
+				);
+				* 注意:最后一列,不需要加逗号(,)
+				* 数据库类型:
+					1. int:整数类型
+						* age int,
+					2. double:小数类型
+						* score double(5,2)
+					3. date:日期,只包含年月日,yyyy-MM-dd
+					4. datetime:日期,包含年月日时分秒	 yyyy-MM-dd HH:mm:ss
+					5. timestamp:时间错类型	包含年月日时分秒	 yyyy-MM-dd HH:mm:ss	
+						* 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
+
+					6. varchar:字符串
+						* name varchar(20):姓名最大20个字符
+						* zhangsan 8个字符  张三 2个字符
+				
+
+			* 创建表
+				create table student(
+					id int,
+					name varchar(32),
+					age int ,
+					score double(4,1),
+					birthday date,
+					insert_time timestamp
+				);
+			* 复制表:
+				* create table 表名 like 被复制的表名;	  	
+		2. R(Retrieve):查询
+			* 查询某个数据库中所有的表名称
+				* show tables;
+			* 查询表结构
+				* desc 表名;
+		3. U(Update):修改
+			1. 修改表名
+				alter table 表名 rename to 新的表名;
+			2. 修改表的字符集
+				alter table 表名 character set 字符集名称;
+			3. 添加一列
+				alter table 表名 add 列名 数据类型;
+			4. 修改列名称 类型
+				alter table 表名 change 列名 新列别 新数据类型;
+				alter table 表名 modify 列名 新数据类型;
+			5. 删除列
+				alter table 表名 drop 列名;
+		4. D(Delete):删除
+			* drop table 表名;
+			* drop table  if exists 表名 ;
+
+* 客户端图形化工具:SQLYog
+
+## DML:增删改表中数据
+
+	1. 添加数据:
+		* 语法:
+			* insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
+		* 注意:
+			1. 列名和值要一一对应。
+			2. 如果表名后,不定义列名,则默认给所有列添加值
+				insert into 表名 values(值1,值2,...值n);
+			3. 除了数字类型,其他类型需要使用引号(单双都可以)引起来
+	2. 删除数据:
+		* 语法:
+			* delete from 表名 [where 条件]
+		* 注意:
+			1. 如果不加条件,则删除表中所有记录。
+			2. 如果要删除所有记录
+				1. delete from 表名; -- 不推荐使用。有多少条记录就会执行多少次删除操作
+				2. TRUNCATE TABLE 表名; -- 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
+	3. 修改数据:
+		* 语法:
+			* update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];
+
+		* 注意:
+			1. 如果不加任何条件,则会将表中所有记录全部修改。
+
+
+
+## DQL:查询表中的记录
+	* select * from 表名;
+	
+	1. 语法:
+		select
+			字段列表
+		from
+			表名列表
+		where
+			条件列表
+		group by
+			分组字段
+		having
+			分组之后的条件
+		order by
+			排序
+		limit
+			分页限定
+
+
+	2. 基础查询
+		1. 多个字段的查询
+			select 字段名1,字段名2... from 表名;
+			* 注意:
+				* 如果查询所有字段,则可以使用*来替代字段列表。
+		2. 去除重复:
+			* distinct
+		3. 计算列
+			* 一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
+			* ifnull(表达式1,表达式2):null参与的运算,计算结果都为null
+				* 表达式1:哪个字段需要判断是否为null
+				* 如果该字段为null后的替换值。
+		4. 起别名:
+			* as:as也可以省略
+			
+
+	3. 条件查询
+		1. where子句后跟条件
+		2. 运算符
+			* > 、< 、<= 、>= 、= 、<>
+			* BETWEEN...AND  
+			* IN( 集合) 
+			* LIKE:模糊查询
+				* 占位符:
+					* _:单个任意字符
+					* %:多个任意字符
+			* IS NULL  
+			* and  或 &&
+			* or  或 || 
+			* not  或 !
+			
+				-- 查询年龄大于20岁
+
+				SELECT * FROM student WHERE age > 20;
+				
+				SELECT * FROM student WHERE age >= 20;
+				
+				-- 查询年龄等于20岁
+				SELECT * FROM student WHERE age = 20;
+				
+				-- 查询年龄不等于20岁
+				SELECT * FROM student WHERE age != 20;
+				SELECT * FROM student WHERE age <> 20;
+				
+				-- 查询年龄大于等于20 小于等于30
+				
+				SELECT * FROM student WHERE age >= 20 &&  age <=30;
+				SELECT * FROM student WHERE age >= 20 AND  age <=30;
+				SELECT * FROM student WHERE age BETWEEN 20 AND 30;
+				
+				-- 查询年龄22岁,18岁,25岁的信息
+				SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
+				SELECT * FROM student WHERE age IN (22,18,25);
+				
+				-- 查询英语成绩为null
+				SELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 = (!=) 判断
+				
+				SELECT * FROM student WHERE english IS NULL;
+				
+				-- 查询英语成绩不为null
+				SELECT * FROM student WHERE english  IS NOT NULL;
+	
+
+
+				-- 查询姓马的有哪些? like
+				SELECT * FROM student WHERE NAME LIKE '马%';
+				-- 查询姓名第二个字是化的人
+				
+				SELECT * FROM student WHERE NAME LIKE "_化%";
+				
+				-- 查询姓名是3个字的人
+				SELECT * FROM student WHERE NAME LIKE '___';
+				
+				
+				-- 查询姓名中包含德的人
+				SELECT * FROM student WHERE NAME LIKE '%德%';
+
+
+
+	

+ 11 - 0
后端/Mysql/4.mysql启动报错.md

@@ -0,0 +1,11 @@
+[MySQL 服务正在启动 . MySQL 服务无法启动 服务没有报告任何错误 解决方案](https://www.pianshen.com/article/7952979816/)
+
+[本地Mysql忘记密码的修改方法(windows)](https://blog.csdn.net/qq382495414/article/details/107253577/)
+
+
+sqlyog报错2058
+
+[SQLyog报错2058](https://blog.csdn.net/weixin_42759709/article/details/82895649)
+
+[ERROR 1396 (HY000): Operation ALTER USER failed for ‘root‘@‘localhost‘](https://blog.csdn.net/q258523454/article/details/84555847)
+

+ 47 - 0
大数据/K8S/1.K8S的基本概念.md

@@ -0,0 +1,47 @@
+# 1.什么是K8S
+
+Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。
+# 2.K8S的优势
+
+1. 自动装箱
+2. 自动修复
+3. 水平扩展
+4. 服务发现
+统一入口service
+5. 滚动更新
+6. 版本回退
+7. 密码配置管理
+类似热部署
+8. 存储编排
+9. 批处理
+
+# 3.K8S的基本概念
+![K8S结构](../../照片/20190324224152631.png)
+## 1.master组件
+apiserver
+集群统一入口,以restful方式,交给eted存储
+sheduler
+节点的调度,选择node节点应用部署
+controller-manager
+处理集群中常规后台任务,一个资源对应一个控制器
+etcd
+存储系统,保存集群相关的数据
+## 2.node组件
+kubelet
+master派到node节点代表,管理本机容器
+kube-proxy
+提供网络代理,负载均衡等操作  
+# 4.K8S的核心概念
+## 1.Pod
+K8S中最小的部署单元
+一组容器的集合
+共享网络
+生命周期是短暂的
+## 2.controller
+确保预期的pod副本数量
+无状态应用部署
+有状态应用部署(特定条件才可以使用,例如:特定的端口)
+确保所有的node运行用一个pod
+一次性任务和定时任务
+## 3.service
+定义一组pod的访问规则

+ 33 - 0
大数据/K8S/10.集群的安全机制.md

@@ -0,0 +1,33 @@
+# 1.概述
+## 1.访问K8S集群时候,需要经过三个步骤完成具体操作
+第一步 认证        ---门卫
+传输安全:对外不暴露8080端口,只能内部访问,对外使用端口6443
+客户端身份认证常用方式:
+* https证书认证,基于ca证书
+* http token认证,通过token(令牌)识别用户
+* http基本认证,用户名+密码
+第二步 鉴权(授权)   ---权限
+* 基于RBAC进行鉴权操作
+* 基于角色访问控制
+第三步 准入控制    ---是否存在相关资源
+* 准入控制器列表,如果列表有请求内容,通过,没有则拒绝
+
+
+## 2.进行访问时候,过程中都需要经过api.service
+api.service统一协调,
+访问过程中需要授权,证书,或者用户名密码
+如果访问pod需要ServiceAccount(服务账号)
+* Service Account为Pod中的进程和外部用户提供身份信息
+
+# 2.RBAC
+## 1.RBAC是什么?
+RBAC  是基于角色的访问控制(Role-Based Access Control )在 RBAC  中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
+
+## 2.RBAC名词
+* User(用户):每个用户都有唯一的UID识别,并被授予不同的角色
+* Role(角色):不同角色具有不同的权限
+* Permission(权限):访问权限
+* 用户-角色映射:用户和角色之间的映射关系
+* 角色-权限映射:角色和权限之间的映射
+  ![image-20210701163336651](../../照片/image-20210701163336651.png)
+

+ 24 - 0
大数据/K8S/11.Ingress.md

@@ -0,0 +1,24 @@
+# Ingress
+## 1.把端口号对外暴露,通过IP+端口号进行访问
+
+使用service里面的nodeport实现
+
+## 2.Nodeport去缺陷
+
+在每个节点都会启动端口,在访问时候通过任何节点,通过节点IP+端口号进行访问
+
+意味着每个端口只能使用一次,一个端口对应一个应用
+
+实际访问都是用域名,根据不同域名跳转到不同端口服务器中
+
+## 3.Ingress和Pod关系
+
+Pod和ingress通过service关联的
+
+ingress作为统一入口,由service关联一组pod
+![image-20210701170610466](../../照片/image-20210701170610466.png)
+
+## 4.ingress工作流程
+
+![image-20210701170803400](../../照片/image-20210701170803400.png)
+

+ 136 - 0
大数据/K8S/12.Helm.md

@@ -0,0 +1,136 @@
+# 1.什么是Helm
+
+## 1.之前部署应用的基本过程
+
+1. 编写yaml文件
+2. deployment
+3. 创建service
+4. ingress域名管理
+
+缺陷
+如果部署单一应用,少数应用,比较合适
+比如部署微服务项目,可以由几十个服务,每个服务都有一套yaml文件,需要维护大量yaml文件,版本管理特别不方便
+
+## 2.使用helm可以解决什么问题
+
+1. 使用helm可以把这些yaml作为一个整体管理
+2. 实现yaml文件高效复用
+3. 使用helm应用级别的版本管理
+
+## 3.Helm是什么
+
+Helm 是 Kubernetes 的包管理器。包管理器类似于我们在 Ubuntu 中使用的apt、Centos中使用的 yum 或者Python中的 pip 一样,能快速查找、下载和安装软件包。Helm 由客户端组件 helm 和服务端组件 Tiller 组成,能够将一组K8S资源打包统一管理,是查找、共享和使用为Kubernetes构建的软件的最佳方式。
+
+Helm类似于yum安装指令,统一对安装服务进行管理,使得用户不需要关系服务之间的依赖关系。
+
+## 4.Helm 相关组件及概念
+
+* helm 是一个命令行工具,用于本地开发及管理chart,chart仓库管理等
+* chart Helm的打包格式叫做chart,所谓chart就是一系列文件, 它描述了一组相关的 k8s 集群资源
+* release 使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release  本质是部署实体
+
+## 5.helm的V3版本新变化
+
+1. v3版本删除Tiller
+2. release可以在不同命名空间重用
+3. 将chart推送到docker仓库中
+
+v3之前版本架构图
+![image-20210701210351090](../照片/image-20210701210351090.png)
+
+v3版本
+![image-20210701210558888](../照片/image-20210701210558888.png)
+
+# 2.helm安装与使用
+
+第一步 下载helm安装文件,上传系统
+第二步 解压文件复制到/usr/bin 目录下
+
+| 命令       | 描述                                                         |
+| ---------- | ------------------------------------------------------------ |
+| create     | 创建一个chart并指定名字                                      |
+| dependency | 管理chart依赖                                                |
+| get        | 下载一个release。可用子命令:all、hooks、manifest、notes、values |
+| history    | 获取release历史                                              |
+| install    | 安装一个chart                                                |
+| list       | 列出release                                                  |
+| package    | 将chart目录打包到chart存档文件中                             |
+| pull       | 从远程仓库中下载chart并解压到本地#helmpullstable/mysql–untar |
+| repo       | 添加,列出,移除,更新和索引chart仓库。可用子命令:add、index、list、remove、update |
+| rollback   | 从之前版本回滚                                               |
+| search     | 根据关键字搜索chart。可用子命令:hub、repo                   |
+| show       | 查看chart详细信息。可用子命令:all、chart、readme、values    |
+| status     | 显示已命名版本的状态                                         |
+| template   | 本地呈现模板                                                 |
+| uninstal   | 卸载一个release                                              |
+| upgrade    | 更新一个release                                              |
+| version    | 查看helm客户端版本                                           |
+
+
+
+添加仓库  helm repo add  仓库名称  仓库地址
+helm repo add stable http://mirror.azure.cn/kubernetes/charts
+helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
+helm repo update
+
+查看配置的存储库
+helm repo list
+helm search repo stable
+
+删除存储库
+helm repo remove aliyun
+
+# 3.使用helm快速部署应用
+
+```
+helm search repo weave
+helm show chart stable/mysql
+helm install ui stable/weave-scope
+helm list
+helm status ui 
+```
+
+# 4.自己搭建chart
+
+## 1.使用命令搭建chart
+helm create chart 名称
+目录解释:
+charts:空目录,一般不会写什么
+Chart.yaml:chart的基本信息,包括版本名字之类
+templates:存放yaml文件
+values.yaml:存放全局变量,templates下的文件可以调用
+
+## 2.在templates文件创建两个yaml文件
+
+deployment.yaml  service.yaml
+
+## 3.安装
+
+helm install web1 mychart/
+
+## 5.升级
+
+helm upgrade chart 名称 目录
+
+# 5.helm实现yaml文件高效复用
+
+yaml文件有几个地方不同
+* image
+* tag
+* label
+* port
+* replicas
+
+## 1.在values.yaml定义变量和值
+
+replicas: 1
+image: nginx
+tag: 1.19
+label: nginx
+port: 80
+
+## 2.在具体yaml文件定义变量值
+
+在templates的yaml文件使用values.yaml定义变量
+通过表达式形式使用全局变量:{{ .Values.变量 }}
+{{ .Release.Name }}取到当前版本的名称

+ 38 - 0
大数据/K8S/13.持久化网络存储.md

@@ -0,0 +1,38 @@
+# 1.数据卷
+
+优点:简单易用,无需额外支持
+缺点:依赖宿主机磁盘容量,pod与宿主机存在强耦合,不利于管理。当pod部署多个副本并分配到不同host时,数据不共享;当pod漂移时,数据不同步;当node故障时,数据易丢失;
+
+# 2.nfs网络存储
+
+## 1.找一台服务器作为nfs服务端
+
+1. 安装nfs
+yum install -y nfs-utils
+2. 设置挂载路径
+/data/nfs * (rw, no_root_squsah)
+3. 创建挂载路径
+
+## 2.在node节点上安装nfs
+
+yum install -y nfs-utils
+
+## 3.启动nfs服务
+
+systemctl start nfs
+
+# 3.PV和PVC
+
+## 1.PV
+
+生产者
+持久化存储,对存储资源进行抽象,对外提供可以调用的地方
+
+## 2.PVC
+
+消费者
+用于调用,不需要关心内部实现细节
+
+## 3.实现流程
+
+应用部署->定义PVC(绑定PV,匹配容量和模式)->定义PV(数据存储服务器IP,路径)

+ 58 - 0
大数据/K8S/14.K8S集群监控.md

@@ -0,0 +1,58 @@
+# 1.监控指标
+
+集群监控
+* 节点资源利用率
+* 节点数
+* 运行pods
+
+pod监控
+* 容器指标
+* 应用程序
+
+# 2.监控平台搭建
+
+prometheus+Grafana
+
+## 1.prometheus
+
+* 开源的,通过https进行监控
+* 监控,报警,数据库
+* http协议周期性抓取被监控组件状态
+* 不需要复杂的集成环境,使用http接口接入
+
+## 2.Grafana
+
+* 开源的数据分析和可视化工具
+* 支持多种数据源
+
+## 3.基本流程
+
+![image-20210702101021414](../../照片/image-20210702101021414.png)
+
+# 3.搭建过程
+
+## 1.部署prometheus
+
+通过yaml文件直接部署
+
+首先部署守护进程
+
+然后部署其他yaml文件
+* RBAC
+* configmap
+* deployment
+* svc
+
+## 2.部署Grafana
+
+通过yaml文件直接部署
+
+* deployment
+* ingress
+* svc
+
+## 3.配置Grafana,配置数据源,导入显示模板
+
+1.配置数据源,设置为prometheus -- IP要设置为内部IP
+2.设立模板,显示内容
+

+ 4 - 0
大数据/K8S/15.kubsphere.md

@@ -0,0 +1,4 @@
+https://www.yuque.com/leifengyang/kubesphere/hxzk3t
+
+链接:https://pan.baidu.com/s/1_icCXoaYlNroCXdrJ3sgnQ
+提取码:0bjt ;

+ 10 - 0
大数据/K8S/16.强制删除ns.md

@@ -0,0 +1,10 @@
+```
+kubectl delete ns --grace-period=0 –force 
+
+kubectl get namespace <terminating-namespace> -o json >tmp.json
+
+kubectl proxy
+
+curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/istio-system/finalize
+
+```

+ 275 - 0
大数据/K8S/17.velero的使用.md

@@ -0,0 +1,275 @@
+# 1.安装minio
+
+## 1.使用外部安装
+首先拉取镜像
+```
+docker pull minio
+```
+使用命令安装minio,指定端口号
+
+```
+docker run -p 30900:9000 --name minio \
+-d --restart=always \
+-e "MINIO_ACCESS_KEY=admin" \
+-e "MINIO_SECRET_KEY=admin123456" \
+-v /home/data:/data \
+-v /home/config:/root/.minio \
+minio/minio server --console-address :30900 /data
+```
+
+## 2.使用内部安装
+
+minio 官方推荐安装在k8s集群中,在上步解压的压缩包中里的examples/minio/00-minio-deployment.yaml包含了在k8s中安装minio的yaml文件,内容如下,可按照如下步骤修改minio的service类型为NodePort,进行安装:
+```
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: velero
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  namespace: velero
+  name: minio
+  labels:
+    component: minio
+spec:
+  strategy:
+    type: Recreate
+  selector:
+    matchLabels:
+      component: minio
+  template:
+    metadata:
+      labels:
+        component: minio
+    spec:
+      volumes:
+      - name: storage
+        emptyDir: {}
+      - name: config
+        emptyDir: {}
+      containers:
+      - name: minio
+        image: minio/minio:latest
+        imagePullPolicy: IfNotPresent
+        args:
+        - server
+        - /storage
+        - --config-dir=/config
+        env:
+        - name: MINIO_ACCESS_KEY
+          value: "minio"
+        - name: MINIO_SECRET_KEY
+          value: "minio123"
+        ports:
+        - containerPort: 9000
+        volumeMounts:
+        - name: storage
+          mountPath: "/storage"
+        - name: config
+          mountPath: "/config"
+      volumes:
+      - name: config
+        hostPath:
+         path: /minio/config
+      - name: storage
+        hostPath:
+         path: /minio/storage
+         
+---
+apiVersion: v1
+kind: Service
+metadata:
+  namespace: velero
+  name: minio
+  labels:
+    component: minio
+spec:
+  # ClusterIP is recommended for production environments.
+  # Change to NodePort if needed per documentation,
+  # but only if you run Minio in a test/trial environment, for example with Minikube.
+  type: NodePort
+  ports:
+    - port: 9000
+      targetPort: 9000
+      protocol: TCP
+      nodePort: 30900
+  selector:
+    component: minio
+
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  namespace: velero
+  name: minio-setup
+  labels:
+    component: minio
+spec:
+  template:
+    metadata:
+      name: minio-setup
+    spec:
+      restartPolicy: OnFailure
+      volumes:
+      - name: config
+        emptyDir: {}
+      containers:
+      - name: mc
+        image: minio/mc:latest
+        imagePullPolicy: IfNotPresent
+        command:
+        - /bin/sh
+        - -c
+        - "mc --config-dir=/config config host add velero http://minio:9000 minio minio123 && mc --config-dir=/config mb -p velero/velero"
+        volumeMounts:
+        - name: config
+          mountPath: "/config"
+
+```
+
+将config和stroge文件挂载到/minio/stroge和/minio/config
+
+
+
+# 2.安装velero
+
+
+## 1.安装在集群外部需要额外创建服务
+由于minio安装在集群外,pod无法访问外部服务,需要创建一个external类型的服务,用来访问外部minio,yaml内容如下:(注意端口号对应)
+
+    ---
+    apiVersion: v1
+    kind: Namespace
+    metadata:
+      name: velero
+    ---
+    apiVersion: v1
+    kind: Service
+    metadata:
+      name: minio
+      namespace: velero
+    spec:
+      ports:
+        - port: 9000
+    ---
+    kind: Endpoints
+    apiVersion: v1
+    metadata:
+      name: minio
+      namespace: velero
+    subsets:
+      - addresses:
+          - ip: (这个端口号为内部端口)通过kubectl get svc 查看
+        ports:
+          - port: 9000
+执行命令
+	kubectl apply -f minio-service.yaml
+
+## 2.安装集群内部直接运行
+
+将velero放入  /usr/local/bin/目录下,创建 minio 的访问密钥文件 credentials-velero
+
+    cat <<'EOF' > credentials-velero
+    [default]
+    aws_access_key_id = minio
+    aws_secret_access_key = minio123
+    EOF
+
+
+
+安装velero
+
+	velero install    \
+	--image velero/velero:v1.6.1  \
+	--plugins velero/velero-plugin-for-aws:v1.0.0  \
+	--provider aws   \
+	--bucket velero   \
+	--namespace velero  \
+	--secret-file ./credentials-velero  \
+	--velero-pod-cpu-request 200m   \
+	--velero-pod-mem-request 200Mi   \
+	--velero-pod-cpu-limit 1000m  \
+	--velero-pod-mem-limit 1000Mi   \
+	--use-volume-snapshots=false   \
+	--use-restic   \
+	--restic-pod-cpu-request 200m   \
+	--restic-pod-mem-request 200Mi   \
+	--restic-pod-cpu-limit 1000m  \
+	--restic-pod-mem-limit 1000Mi  \
+	--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://内部端口:9000
+
+如果您想从集群中完全卸载Velero,则以下命令将删除由velero install创建的所有资源:
+
+    kubectl delete namespace/velero clusterrolebinding/velero
+    kubectl delete crds -l component=velero
+
+
+# 3.创建备份
+
+## 1.备份指定 namespaces
+
+	velero backup create 备份名字 --include-namespaces 命名空间名字
+
+## 2.备份全部 namespaces
+
+	velero backup create all
+
+# 4.恢复备份
+
+* 恢复备份
+
+```
+velero restore create --from-backup test-1
+```
+
+* 查看恢复
+
+```
+velero restore get
+```
+
+* 查看恢复日志、描述
+
+```
+velero restore logs name
+velero restore describe name
+```
+
+* 查看恢复的 Pod
+
+```
+kubectl get pod -n velero-test
+```
+
+# 5.定时备份
+
+
+	velero schedule create velero-test-daily --schedule="0 7 * * *" --include-namespaces 名字
+
+schedule任务  注意:由于"月份中的日期"和"星期中的日期"这两个元素互斥的,如果设置其中一个,就必须要对另外的一个设置?
+```
+*  *  *  *  *  *
+┬  ┬  ┬  ┬  ┬  ┬
+│  │  │  │  │  |
+│  │  │  │  │  └ day of week (0 - 7) (0 or 7 is Sun)
+│  │  │  │  └───── month (1 - 12)
+│  │  │  └────────── day of month (1 - 31)
+│  │  └─────────────── hour (0 - 23)
+│  └──────────────────── minute (0 - 59)
+└───────────────────────── second (0 - 59, OPTIONAL)
+
+```
+
+# 6.参考文档
+
+[使用 Velero 备份 Kubernetes 集群](https://www.chenshaowen.com/blog/backup-kubernetes-cluster-using-velero.html)
+
+[Velero安装与使用手册](https://blog.csdn.net/weixin_42143049/article/details/115757747)
+
+[Kubernetes数据卷介绍及yaml示例](https://www.codercto.com/a/75268.html)
+
+[velero文档](https://velero.io/docs/v1.6/)

+ 22 - 0
大数据/K8S/2.构建K8S-kubeadm方式.md

@@ -0,0 +1,22 @@
+# 1.搭建K8S环境平台规划
+## 1.单master集群
+单个节点容易损坏
+## 2.多master集群
+master与node之间多一个负载均衡
+# 2.服务器硬件要求
+## 1.测试环境
+master
+至少2核心
+内存至少4G
+内存20G以上
+node
+4核心
+8G
+40G
+## 2.生产环境
+更高要求
+# 3.搭建方式
+1. kubeadm部署
+2. 二进制包部署
+
+# 4.搭建集群

+ 187 - 0
大数据/K8S/3.使用kubeadm快速部署一个K8s集群.md

@@ -0,0 +1,187 @@
+
+kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。
+
+这个工具能通过两条指令完成一个kubernetes集群的部署:
+
+```
+# 创建一个 Master 节点
+$ kubeadm init
+
+# 将一个 Node 节点加入到当前集群中
+$ kubeadm join <Master节点的IP和端口 >
+```
+
+## 1. 安装要求
+
+在开始之前,部署Kubernetes集群机器需要满足以下几个条件:
+
+- 一台或多台机器,操作系统 CentOS7.x-86_x64
+- 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
+- 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
+- 禁止swap分区
+
+## 2. 准备环境
+
+| 角色   | IP           |
+| ------ | ------------ |
+| master | 192.168.1.11 |
+| node1  | 192.168.1.12 |
+| node2  | 192.168.1.13 |
+
+```
+# 关闭防火墙
+systemctl stop firewalld
+systemctl disable firewalld
+
+# 关闭selinux
+sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
+setenforce 0  # 临时
+cat /etc/selinux/config
+
+# 关闭swap
+swapoff -a  # 临时
+sed -ri 's/.*swap.*/#&/' /etc/fstab    # 永久
+free -m
+
+# 根据规划设置主机名
+hostnamectl set-hostname <hostname>
+
+# 在master添加hosts
+cat >> /etc/hosts << EOF
+192.168.44.146 k8smaster
+192.168.44.145 k8snode1
+192.168.44.144 k8snode2
+EOF
+
+# 将桥接的IPv4流量传递到iptables的链
+cat > /etc/sysctl.d/k8s.conf << EOF
+net.bridge.bridge-nf-call-ip6tables = 1
+net.bridge.bridge-nf-call-iptables = 1
+EOF
+sysctl --system  # 生效
+
+# 时间同步
+yum install ntpdate -y
+ntpdate time.windows.com
+```
+
+## 3. 所有节点安装Docker/kubeadm/kubelet
+
+Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。
+
+### 3.1 安装Docker
+
+```
+$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
+$ yum -y install docker-ce-18.06.1.ce-3.el7
+$ systemctl enable docker && systemctl start docker
+$ docker --version
+Docker version 18.06.1-ce, build e68fc7a
+```
+
+```
+$ cat > /etc/docker/daemon.json << EOF
+{
+  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
+}
+EOF
+```
+
+### 3.2 添加阿里云YUM软件源
+
+```
+$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
+[kubernetes]
+name=Kubernetes
+baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
+enabled=1
+gpgcheck=0
+repo_gpgcheck=0
+gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
+EOF
+```
+
+### 3.3 安装kubeadm,kubelet和kubectl
+
+由于版本更新频繁,这里指定版本号部署:
+
+```
+$ yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
+$ systemctl enable kubelet
+```
+
+## 4. 部署Kubernetes Master
+
+在192.168.31.61(Master)执行。
+
+```
+$ kubeadm init \
+  --apiserver-advertise-address=192.168.44.146 \
+  --image-repository registry.aliyuncs.com/google_containers \
+  --kubernetes-version v1.18.0 \
+  --service-cidr=10.96.0.0/12 \
+  --pod-network-cidr=10.244.0.0/16
+```
+
+由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。
+
+使用kubectl工具:
+
+```bash
+mkdir -p $HOME/.kube
+sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
+sudo chown $(id -u):$(id -g) $HOME/.kube/config
+$ kubectl get nodes
+```
+
+## 5. 加入Kubernetes Node
+
+在192.168.1.12/13(Node)执行。
+
+向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:
+
+```
+$ kubeadm join 192.168.1.11:6443 --token esce21.q6hetwm8si29qxwn \
+    --discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5
+```
+
+默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,操作如下:
+
+```
+kubeadm token create --print-join-command
+```
+
+## 6. 部署CNI网络插件
+访问其他容器
+
+```
+wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
+```
+
+默认镜像地址无法访问,sed命令修改为docker hub镜像仓库。
+
+```
+kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
+
+kubectl get pods -n kube-system
+NAME                          READY   STATUS    RESTARTS   AGE
+kube-flannel-ds-amd64-2pc95   1/1     Running   0          72s
+```
+
+## 7. 测试kubernetes集群
+
+在Kubernetes集群中创建一个pod,验证是否正常运行:
+
+```
+$ kubectl create deployment nginx --image=nginx
+$ kubectl expose deployment nginx --port=80 --type=NodePort
+$ kubectl get pod,svc
+```
+
+访问地址:http://NodeIP:Port  
+
+curl -k -H "Content-Type: application/json" -X PUT --data-binary @monitoring.json http://127.0.0.1:8081/api/v1/namespaces/monitoring/finalize
+————————————————
+版权声明:本文为CSDN博主「Jerry_Pan1990」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
+原文链接:https://blog.csdn.net/Jerry_Pan1990/article/details/103633627
+

+ 22 - 0
大数据/K8S/4.命令行工具kubectl.md

@@ -0,0 +1,22 @@
+# 1.基本格式
+```shell
+kubectl [command] [type] [name] [flags]
+
+
+kubectl --help
+```
+# 2.YAML文件
+YAML资源清单文件
+语法格式:一种标记语言
+* 通过缩进表示层级关系
+* 只能使用空格缩进
+* 使用---表示新的yaml文件开始
+* 使用#号表示注释
+# 3.YAML文件组成部分
+控制器定义 
+被控制对象
+![image-20210629161212299](../../照片/image-20210629161212299.png)
+# 4.常用字段含义
+如何快速编写yaml文件
+第一种 使用kubectl create命令生成yaml文件
+第二种 使用kubectl get命令导出yaml文件

+ 81 - 0
大数据/K8S/5.Pod.md

@@ -0,0 +1,81 @@
+# 1.Pod的基本概念
+1. 在Kubernetes中,最小的管理元素不是一个个独立的容器,而是Pod,Pod是最小的,管理,创建,计划的最小单元。
+2. Pod是一组容器的集合
+3. 一个Pod中的容器共享网络空间
+4. Pod是短暂存在的
+# 2.Pod存在的意义
+1. 创建容器使用docker,一个docker对应一个容器,一个容器有进程,一个容器运行一个应用程序
+2. Pod是多进程设计,运行多个应用程序。
+* 一个Pod有多个容器,一个容器里面运行一个应用程序
+3. Pod存在为了亲密性应用
+* 两个应用进行交互
+* 网络之间的调用
+* 两个应用需要频繁调用
+# 3.Pod的实现机制
+## 1.共享网络
+容器之间相互隔离,namespace,group
+多个容器在同一个namespace里面
+![image-20210629170139908](../../照片/image-20210629170139908.png)
+pause(info)是根容器
+新容器(业务容器)会加入info容器之中
+info容器会独立出IP地址,MAC地址
+在同一个namespace里面
+
+## 2.共享存储
+pod持久化数据-日志数据,业务数据
+持久化存储--数据卷(volumn)
+# 4.镜像拉取策略
+* ifnotpresent:默认值,镜像在宿主机不存在才拉取
+* always:每次创建Pod都会重新拉取一次镜像
+* never:Pod永远不会主动拉取这镜像
+# 5.Pod资源的限制
+限制由docker实现
+
+# 6.Pod的重启的机制
+![image-20210629180552052](../../照片/image-20210629180552052.png)
+# 7.Pod的健康检查
+容器检查-无法检查潜在危险,例如不能提供服务
+应用层面健康检查
+
+K8S的检查机制
+![image-20210629180901274](../../照片/image-20210629180901274.png)
+![image-20210629180953925](../../照片/image-20210629180953925.png)
+
+# 8.Pod的调度策略
+
+![image-20210629182003299](../../照片/image-20210629182003299.png)
+master节点
+create --- apiserver -- etcd
+scheduler -- apiserver -- etcd --调度算法,把Pod调度某个node系欸但上
+
+node节点
+kublet -- apiserver -- 读取etcd拿到分配给当前节点的pod -- docker创建容器
+
+## 1.影响调度的属性
+### 1.Pod资源的限制
+### 2.节点选择器标签
+首先对节点创建标签
+### 3.节点亲和性(nodeaffinity)
+和nodeselector基本一样,根据节点上标签约束来决定Pod调度到那些节点上
+(1)硬亲和性-required
+约束条件必须满足
+(2)软亲和性-preferred
+尝试满足,不保证
+
+支持的操作符
+In NotIn Exists Gt Li DoesNotExists
+### 4.污点和污点容忍
+Taint污点:节点不做普通分配调度,是节点属性
+(上面三个都是对Pod做的限制,污点是对节点表示限制)
+* 专用节点
+* 配置特定硬件节点
+* 基于Taint驱逐
+
+污点值有三个
+NoSchedule:一定不被调度
+PreferNoSchdule:尽量不被调度
+NoExecute:不会调度,并且还会驱逐Node已有Pod
+
+污点容忍
+![image-20210630093930467](../../照片/image-20210630093930467.png)
+加入污点也可能被调度到

+ 44 - 0
大数据/K8S/6.Controller-无状态.md

@@ -0,0 +1,44 @@
+# 1.什么是controller
+在集群上管理和运行容器的对象
+
+# 2.Pod和controller的关系
+Pod是通过controller实现应用的运维
+比如伸缩,滚动升级等等
+
+Pod和controller通过label标签建立关系
+
+# 3.Deployment控制器应用场景
+部署一个无状态应用
+管理Pod和replicaSet
+
+replicaSet保证在同一时间能够运行指定数量的Pod副本,保证Pod总是可用。如果实际Pod数量比指定的多就结束掉多余的,如果实际数量比指定的少就启动缺少的。
+
+当Pod失败、被删除或被终结时,replicaSet会自动创建新的Pod来保证副本数量,所以即使只有一个Pod,也应该使用replicaSet来进行管理。
+
+部署,滚动升级等功能
+
+应用场景:web服务,微服务
+
+# 4.yaml文件字段说明
+
+![image-20210630100843770](../../照片/image-20210630100843770.png)
+
+matchlabel和label匹配
+
+# 5.Deployment控制器部署应用
+
+1.调出yaml文件
+2.使用yaml部署应用
+3.对外发布
+
+# 6.升级回滚
+
+升级采用覆盖模式,下载完成才会覆盖
+
+回滚使用history命令查看回滚
+回滚到上一个版本
+回滚到指定的版本
+
+# 7.弹性伸缩
+
+增加多个副本

+ 16 - 0
大数据/K8S/7.Service.md

@@ -0,0 +1,16 @@
+# 1.service的存在意义
+1. 防止Pod失联(服务发现)--更新Pod的IP
+2. 定义一组pod的访问规则(负载均衡)
+# 2.Pod和Service关系
+selector
+  app:nginx
+
+lable:
+  app:nginx
+
+service有一个对外暴露的虚拟IP,由endpoint管理
+endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。service配置selector,endpoint controller才会自动创建对应的endpoint对象;否则,不会生成endpoint对象.
+# 3.service类型
+1. clusterIP:集群内部使用
+2. NodePort:对外暴露使用
+3. LoadBalancer:对外访问使用,公有云

+ 38 - 0
大数据/K8S/8.Controller-有状态.md

@@ -0,0 +1,38 @@
+# 1.无状态与有状态
+
+无状态的特点
+* Pod都是一样的
+* 没有顺序的要求
+* 不用考虑哪个node运行
+* 随意进行伸缩和扩展
+
+有状态的特点
+* 上面要素都要考虑
+* 然后每个Pod都是独立的
+* 保持Pod启动顺序唯一性
+* 通过唯一的网络标识符,持久存储
+* 有序的,主从关系
+
+# 2.部署有状态应用
+
+* 无头service -- ClusterIP:none
+StatefulSet部署有状态应用
+
+statefulset:唯一标识
+根据主机名+一定规则生成域名
+唯一的域名
+
+# 3.部署守护进程DaemonSet
+作用
+* 保证集群内每一个(或者一些)节点都运行一组相同的Pod
+* 跟踪集群节点状态,保证新加入的节点自动创建对应的Pod
+* 跟踪集群节点状态,保证移除的节点删除对应的Pod
+* 跟踪Pod状态,保证每个节点Pod处于运行状态
+
+适用场景:日志采集
+
+# 4.job(一次性任务)
+
+
+
+# 5.cronjib(定时任务)

+ 19 - 0
大数据/K8S/9.Secret.md

@@ -0,0 +1,19 @@
+secret
+作用:加密数据存在etcd里面,让Pod容器以挂在Volume方式进行访问
+
+1. 创建secret加密数据
+2. 以变量形式挂载到pod容器中
+3. 以volume形式挂载到容器中
+
+
+configmap
+存储不加密数据
+
+ex:项目中的配置文件
+
+1. 创建配置文件
+2. 创建configmap
+3. 以volume形式挂载到容器中
+
+4. 以变量形式挂载到Pod容器中
+先创建变量,然后挂在数据

+ 37 - 0
大数据/docker/1.什么是docker.md

@@ -0,0 +1,37 @@
+# 1.docker解决的问题
+
+* 解决虚拟化问题。 
+* 解决运行环境配置问题
+* 弹性扩容
+* 代码流水线管理
+
+# 2.应用场景
+
+1. Web 应用的自动化打包和发布。
+2. 自动化测试和持续集成、发布。
+3. 在服务型环境中部署和调整数据库或其他的后台应用。
+4. 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
+
+# 3.docker的架构设计原理
+
+## 1.docker三大核心要素
+
+1. 仓库 --- 存放镜像文件 
+2. 镜像 --- 类似于安装包,描述运行所需要的环境配置和依赖
+来源
+* 自建创建的dockerfile
+* docker hub仓库下载
+3. 容器 --- 运行镜像文件,独立的IP和网络信息,虚拟化一个linux系统
+
+## 2.docker架构图
+
+![image-20210705092042263](../../照片/image-20210705092042263.png)
+
+# 4.容器与虚拟机的区别
+
+![image-20210705092333874](../../照片/image-20210705092333874.png)
+
+![image-20210705092429027](../../照片/image-20210705092429027.png)
+
+虚拟机在硬件级别虚拟化
+docker在Linux系统级别虚拟化

+ 27 - 0
大数据/docker/2.centos7安装docker.md

@@ -0,0 +1,27 @@
+# 1.下载docker镜像
+
+```
+$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
+官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,你可以通过以下方式开启。同理可以开启各种测试版本等。
+$ yum -y install docker-ce-18.06.1.ce-3.el7
+$ systemctl enable docker && systemctl start docker
+$ docker --version
+Docker version 18.06.1-ce, build e68fc7a
+```
+
+# 2.docker配置镜像加速
+
+
+阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
+
+```
+sudo mkdir -p /etc/docker
+sudo tee /etc/docker/daemon.json <<-'EOF'
+{
+  "registry-mirrors": ["https://an54fymq.mirror.aliyuncs.com"]
+}
+EOF
+sudo systemctl daemon-reload
+sudo systemctl restart docker
+```
+

+ 99 - 0
大数据/docker/3.docker基本使用.md

@@ -0,0 +1,99 @@
+# 1.docker基本命令
+
+## 1.docker images
+
+查看本地images 镜像缓存
+
+docker images 查看本地镜像文件
+* REPOSITORY 存储库名称
+* Tag  镜像的标签  不写版本号码 默认下载最新latest镜像
+* IMAGE ID  镜像id
+* CREATED 创建时间
+* SIZE 大小
+
+docker images -a
+docker images -q ---只显示镜像的id
+docker images --digests ---显示镜像的摘要信息
+docker images --no-trunc ---显示完整镜像信息
+
+## 2.docker search 
+```
+docker search mysql 
+docker search -s 30 mysql  列出点赞数超过30以上。
+```
+## 3.docker pull
+```
+docker pull nginx:latest --默认的情况下,下载最新版本的镜像  
+```
+## 4.docker ps
+```
+docker ps 查看正在运行的容器
+docker ps -a 查看运行和已经运行关闭大的容器
+```
+## 5.docker run
+
+docker run -i(保持容器一直运行)-t(给容器一个伪终端)-d(后台运行,不直接进入容器) --name=tomcat9.2(给启动容器起名字)-p 8080:8080(宿主:docker容器)tomcat:9.2(启动的容器)  【参数】(加入容器初始化命令)
+#通过 -it 启动的容器有两个特点 一创建就进入容器 exit退出容器 容器就会停止运行  ---交互式容器
+#通过 -id 创建的容器 docker exec -it tomcat9.2(--name起的名称)进入容器 exit退出容器 容器不会停止运行   ---守护式容器
+```
+docker stop tomcat8  关闭容器
+docker start tomcat8 启动容器
+docker rm tomcat8 删除容器
+docker inspect tomcat8 查看容器信息
+docker exec 参数  进入容器
+```
+## 6.docker rmi
+
+删除镜像:docker rmi tomcat(镜像文件名称) 
+
+1. 删除所有容器
+```
+docker rm `docker ps -a -q`
+```
+2. 删除所有镜像
+```
+docker rmi `docker images -q`
+```
+3. 按条件删除镜像
+```
+docker rmi --force `docker images | grep doss-api | awk '{print $3}'`    
+//其中doss-api为关键字
+```
+
+
+# 2.docker运行原理
+
+docker run mayikt 
+每个容器都有自己独立的网络ip信息 ,运行成功就是一个轻量级linux操作系统
+
+![img](../../照片/clip_image002.jpg)
+
+简单描述:首先会先从本地获取获取mayikt镜像文件,如果本地没有该镜像文件则会去阿里云仓库查找该镜像文件,如果阿里云仓库也没有该镜像文件,则会报错找不到镜像文件。获取到镜像文件之后直接运行。
+
+详细描述: 
+1. docker在本机缓存中 mayikt镜像文件,如果本地存在该镜像文件,则以该镜像文件作为模板在容器中运行。
+2. 如果本地缓存中,没有mayikt镜像文件 则会从dockerhub 或者加速镜像中查找,如果查找不到的话,则返回错误找不到该镜像。如果能够查找到该镜像,则以该镜像作为模板运行。
+![img](../../照片/clip_image004.jpg)
+
+docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start即可。docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。而dockerstart的作用是,重新启动已存在的镜像。也就是说,如果使用这个命令,我们必须事先知道这个容器的ID,或者这个容器的名字,我们可以使用docker ps找到这个容器的信息。
+
+# 3.docker commit
+
+主要作用:根据当前容器制作为镜像文件
+
+流程:
+1. 从docker hub中下载一个tomcat8镜像文件;
+2. 运行tomcat8镜像文件 在tomcatwebapps 目录中新增 mayikt文件夹 index.html
+3. 将当前容器内容根据模板制作为镜像文件
+
+docker commit提交容器副本使之成为一个新的镜像
+命令:
+
+```
+docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:标签名
+1.根据当前容器作为模板制作为镜像文件
+docker commit -m="mayikt tomcat" -a="mayikt"  3a06b4c779a8 mayikt-tomcat:1.0
+2.在以当前自己制作的镜像文件运行
+docker run -p 8088:8080   mayikt-tomcat:1.0
+```
+

+ 14 - 0
大数据/docker/4.docker数据卷.md

@@ -0,0 +1,14 @@
+# 1.基本概念
+
+数据卷就是宿主机上的一个文件或目录
+当容器目录和数据卷(宿主机)目录绑定,双方修改会立即同步操作
+一个数据卷可以被多个容器同时挂载
+数据卷作用:容器数据的持久化 外部机器和容器间接通信 容器之间数据交换
+使用 -v命令。
+
+# 2.数据卷添加的方式
+
+容器内与宿主机实现数据的共享
+数据卷--添加两种方式
+1. 直接命令形式添加   docker run -it -v 宿主机绝对路径目录:容器内目录 镜像文件名称
+2. Dockerfile方式添加

+ 8 - 0
大数据/docker/5.docker镜像加载原理.md

@@ -0,0 +1,8 @@
+
+
+dockerfile --- 文件
+![image-20210705111816103](../../照片/image-20210705111816103.png)
+
+docker镜像底层实际上是由不同的联合文件系统组成的,可以做文件的复用
+![image-20210705112334544](../../照片/image-20210705112334544.png)
+

+ 32 - 0
大数据/docker/6.dockerfile文件.md

@@ -0,0 +1,32 @@
+# 1.dockerfile的作用
+
+docker镜像文件如何组成?
+
+1. dockerfile --- 依赖下载镜像,环境配置封装
+2. dockerfile --- 文件打包成一个镜像文件
+3. 使用容器运行镜像文件
+
+# 2.dockerfile指令
+
+1.	FROM 指定父镜像:  基于哪个镜像image构建  指定基础镜像,必须为第一个命令
+2.	MAINTAINER :维护者
+3.	RUN: 容器创建的时候执行一段命令   构建镜像时执行的命令,例如创建一些目录
+4.	ADD: 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
+5.	COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
+6.	CMD:构建容器后调用,也就是在容器启动时才进行调用。 .sh执行文件
+7.	ENV: 设置环境变量
+8.	EXPOSE: 指定于外界交互的端口
+9.	VOLUME  用于指定持久化目录
+10.	WORKDIR 设置进入容器时的路径 默认访问的目录 
+
+# 3.dockerfile编码规范
+
+A.#描述注释
+B.指令必须要大写,后面至少需要带至少一个参数;
+C.指令是按照从上到下,顺序执行;
+
+# 4.docker build
+
+docker build -f (指定要使用的Dockerfile路径) dockerfile -t 镜像名称:标签
+
+然后启动 docker start

+ 58 - 0
大数据/docker/7.docker compose.md

@@ -0,0 +1,58 @@
+# 1.什么是docker compose
+
+Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。
+
+
+Docker-Compose运行目录下的所有文件(docker-compose.yml(由该文件配置环境依赖),extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。
+
+Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。
+
+Compose 中有两个重要的概念:
+服务 (service) :一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
+项目 (project) :由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
+
+# 2.docker compose基本命令
+
+1. docker-compose -h                           # 查看帮助
+2. docker-compose up                           # 创建并运行所有容器
+3. docker-compose up -d                        # 创建并后台运行所有容器
+4. docker-compose -f docker-compose.yml up -d  # 指定模板
+5. docker-compose down                         # 停止并删除容器、网络、卷、镜像。
+6. docker-compose logs       # 查看容器输出日志
+7. docker-compose pull       # 拉取依赖镜像
+8. dokcer-compose config     # 检查配置
+9. dokcer-compose config -q  # 检查配置,有问题才有输出
+10. docker-compose restart   # 重启服务
+11. docker-compose start     # 启动服务
+12. docker-compose stop      # 停止服务
+13. docker-compose ps  列出项目中所有的容器
+14. docker-compose stop 停止docker-compose
+15. docker-compose logs  查看容器中日志信息
+16. docker-compose pull  拉取服务依赖的镜像
+
+# 3.基本语法
+
+* Image 镜像名称;
+* Build 根据docker file 打包 成镜像;
+* Context  指定docker file文件位置;
+* Commond 使用command可以覆盖容器启动后默认执行的命令;
+* Container_name 容器名称;
+* depends_on 指定依赖那个服务;
+* Ports 映射的端口号;
+* extra_hosts 会在/etc/hosts文件中添加一些记录;
+* Volumes 持久化目录;
+* volumes_from 从另外一个容器挂在数据卷;
+* Dns 设置dns
+* networks 加入同一个局域网
+* environment 定义的环境变量传给container
+* hostname 宿主机名字
+
+
+# 4.基本使用
+
+流程:
+1.  需要定义一个docker-compose.yml文件----工程
+2.	需要在docker-compose文件配置依赖服务
+3.	docker-compose up 执行该文件
+
+

+ 13 - 0
大数据/docker/8.docker可视化.md

@@ -0,0 +1,13 @@
+# 可视化工具Porainer
+
+Portainer是一款Docker可视化管理工具,允许我们在网页中方便的查看和管理Docker容器。
+要使用Portainer很简单,运行下面两条命令即可。这些命令会创建一个Portainer专用的卷,然后在8000和9000端口创建容器并运行。
+
+```
+docker run -d -p 9000:9000 
+--name=portainer 
+--restart=always 
+-v /var/run/docker.sock:/var/run/docker.sock 
+-v portainer_data:/data portainer/portainer
+```
+![image-20210705161656141](../../照片/image-20210705161656141.png)

+ 75 - 0
机器学习/谷歌云的使用/使用Google Colab.md

@@ -0,0 +1,75 @@
+# 1.基础篇
+
+[Google Colab的基础使用](https://zhuanlan.zhihu.com/p/54389036)
+
+***
+# 2.Google Colab初始化
+
+## 2.1安装必要的库
+
+```python
+!apt-get install -y -qq software-properties-common python-software-properties module-init-tools
+!add-apt-repository -y ppa:alessandro-strada/ppa 2>&1 > /dev/null
+!apt-get update -qq 2>&1 > /dev/null
+!apt-get -y install -qq google-drive-ocamlfuse fuse
+from google.colab import auth
+auth.authenticate_user()
+from oauth2client.client import GoogleCredentials
+creds = GoogleCredentials.get_application_default()
+import getpass
+!google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret} < /dev/null 2>&1 | grep URL
+vcode = getpass.getpass()
+!echo {vcode} | google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret}
+```
+
+
+
+## 2.2挂在目录
+
+google colab要挂载在当前目录
+
+```python
+!ls
+```
+
+得到当前的目录![image-20210416184645628](D:\笔记\照片\image-20210416184645628.png)
+
+
+
+进入当前文件夹,更换目录
+
+```python
+import sys
+from google.colab import drive
+# 这个命令是将Drive挂载到‘/content/drive’下,查看此时的目录就知道了
+drive.mount('/content/drive')
+# 加入系统路径
+sys.path.append('/content/drive/MyDrive/Palmprint')
+# 进入当前路径
+%cd /content/drive/MyDrive/Palmprint
+
+```
+
+
+
+---
+
+# 3.查看gup使用情况
+
+```python
+torch.cuda.is_available()
+cuda是否可用;
+
+torch.cuda.device_count()
+返回gpu数量;
+
+torch.cuda.get_device_name(0)
+返回gpu名字,设备索引默认从0开始;
+
+torch.cuda.current_device()
+返回当前设备索引;
+
+!/opt/bin/nvidia-smi
+查看GPU情况
+```
+

+ 23 - 0
煤矿项目问题汇总/无法启动人人项目.md

@@ -0,0 +1,23 @@
+# 导致无法启动人人项目原因
+
+1. 没有安装visual stdio c++环境
+
+安装2017 2019任意一种环境配置
+![image-20210721205050551](../照片/image-20210721205050551.png)
+包含c++包
+![image-20210721205117880](../照片/image-20210721205117880.png)
+
+2. 版本没有对应上
+
+renren-fast使用node版本较老,版本对应不上不能启动
+
+可以降低node版本使它与视频对应
+
+或者修改package.json文件
+![image-20210721205239388](../照片/image-20210721205239388.png)
+
+版本对应关系可以新建一个npm仓库使用npm命令下载可以看出版本的对应关系!!!
+
+![image-20210721205335111](../照片/image-20210721205335111.png)
+![image-20210721205344214](../照片/image-20210721205344214.png)
+

BIN
照片/20190324224152631.png


BIN
照片/clip_image002.jpg


BIN
照片/clip_image004.jpg


BIN
照片/image-20210416184645628.png


BIN
照片/image-20210628143454069.png


BIN
照片/image-20210628154743311.png


BIN
照片/image-20210629161212299.png


BIN
照片/image-20210629170139908.png


BIN
照片/image-20210629180552052.png


BIN
照片/image-20210629180901274.png


BIN
照片/image-20210629180953925.png


BIN
照片/image-20210629182003299.png


BIN
照片/image-20210630093930467.png


BIN
照片/image-20210630100843770.png


BIN
照片/image-20210701163336651.png


BIN
照片/image-20210701170610466.png


BIN
照片/image-20210701170803400.png


BIN
照片/image-20210701210351090.png


BIN
照片/image-20210701210558888.png


BIN
照片/image-20210702101021414.png


BIN
照片/image-20210705092042263.png


BIN
照片/image-20210705092333874.png


Some files were not shown because too many files changed in this diff