Skip to content

Commit f004527

Browse files
2 parents 21658e3 + 6a9eb01 commit f004527

5 files changed

Lines changed: 294 additions & 5 deletions

File tree

AlgorithmAndDataStructure/12-LinkedHashMap.md

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
如果我们想要按照添加元素的顺序遍历,显然HashMap是达不到我们的要求的,`TreeMap`可以满足我们的要求,但是效率没有HashMap高
99

10-
接下来介绍一种新的数据结构——LinkedHashMap
10+
接下来介绍一种新的数据结构——`LinkedHashMap`
1111

1212
LinkedHashMap就是在HashMap的基础上维护元素的添加顺序,使得遍历的结果是遵从添加顺序的
1313

@@ -156,15 +156,100 @@ protected void afterRemove(Node<K, V> removedNode) {
156156

157157
我们会发现,站在红黑树的角度上来看,删除`83`结点其实是删除它的前驱或者后继结点,也就是删除结点`95`,但是站在链表的角度来看,删除结点`83`就是删除结点`83`
158158

159-
**这里就产生了冲突,所以我们上面的链表结点删除代码中逻辑其实是有问题的**
159+
**在我们删除度为2的结点的时候就会产生冲突,所以我们上面的链表结点删除代码中逻辑其实是有问题的**
160160

161+
>那么我们如果解决`红黑树``链表`之间的冲突的呢?
162+
>
163+
>其实做法也很简单,我们只需要将红黑树的后继结点与要删除的结点在`链表中的顺序交换`即可(改变的是指针的指向)
161164
165+
我们来简单演示 一下这个过程,假设我现在要删除结点`31`
162166

167+
![image-20220918194009929](https://cdn.fengxianhub.top/resources-master/202209181940217.png)
163168

169+
- 从红黑树的角度,其实需要交换结点`31`和结点`37`的值,然后将结点`37`从内存中抹去
170+
- 在链表的角度,之前链表结构为:`52 -> 37 -> 21 -> 31 -> 41`,当我们交换两个结点在链表中的顺序后为:`52 -> 31 -> 21 -> 37 -> 41`,注意这里并没有交换结点的位置,只是交换了结点在链表中的指向,可以看到当我们的红黑树删除结点`31`的时候,链表的顺序并没有收到影响
164171

172+
那么到底如何实现呢?我们可以改造一下之前在HashMap的`afterRemove`函数,处理一下度为2的结点在红黑树中删除的逻辑
165173

174+
```java
175+
/**
176+
* 删除结点后的操作,注意这里不是修复红黑树的性质
177+
*
178+
* @param willNode 红黑树中想要删除的结点
179+
* @param removedNode 红黑树中实际要删除的结点
180+
*/
181+
protected void afterRemove(Node<K, V> willNode, Node<K, V> removedNode) {
182+
}
183+
```
184+
185+
在红黑树删除结点的时候,将刚刚传进来的结点当做`willNode`
186+
187+
```java
188+
/**
189+
* 根据结点删除该结点
190+
*/
191+
protected V remove(Node<K, V> node) {
192+
if (node == null) return null;
193+
// 开始想要删除的结点,此处是为了处理linkedHashMap的删除逻辑
194+
Node<K, V> willNode = node;
195+
....其他代码
196+
}
197+
```
198+
199+
接着我们只需要在子类中去处理交换链表中结点的逻辑,交换链表中的两个结点的位置,这个应该是比较容易的
200+
201+
![image-20220918203517622](https://cdn.fengxianhub.top/resources-master/202209182035877.png)
202+
203+
先处理所有指向要交换结点的指针
204+
205+
```java
206+
/**
207+
* 这里并不是删除结点后修复红黑树性质的代码,而是修复链表和红黑树结点指向关系的代码
208+
*/
209+
@Override
210+
protected void afterRemove(Node<K, V> willNode, Node<K, V> removedN
211+
LinkedNode<K, V> linkedWillNode = (LinkedNode<K, V>) willNode;
212+
LinkedNode<K, V> linkedRemoveNode = (LinkedNode<K, V>) removedN
213+
// 如果想要删除的实际要删除的结点不一样,表示该结点为红黑树中度为2的结点,需要交换链表的指向
214+
if (linkedRemoveNode != linkedWillNode) {
215+
// 设置中间结点,处理prev
216+
LinkedNode<K, V> temp = linkedWillNode.prev;
217+
linkedWillNode.prev = linkedRemoveNode.prev;
218+
linkedRemoveNode.prev = temp;
219+
if (linkedWillNode.prev == null) {
220+
first = linkedWillNode;
221+
} else {
222+
linkedWillNode.prev.next = linkedWillNode;
223+
}
224+
if (linkedRemoveNode.prev == null) {
225+
first = linkedRemoveNode;
226+
} else {
227+
linkedRemoveNode.prev.next = linkedRemoveNode;
228+
}
229+
// 处理next
230+
temp = linkedWillNode.next;
231+
linkedWillNode.next = linkedRemoveNode.next;
232+
linkedRemoveNode.next = temp;
233+
if (linkedWillNode.prev == null) {
234+
last = linkedWillNode;
235+
} else {
236+
linkedWillNode.next.prev = linkedWillNode;
237+
}
238+
if (linkedRemoveNode.next == null) {
239+
last = linkedRemoveNode;
240+
} else {
241+
linkedRemoveNode.next.prev = linkedRemoveNode;
242+
}
243+
}
244+
// 后面的逻辑省略,和上面的是一样的
245+
}
246+
```
247+
248+
## 3. LinkedHashMap源码分析
166249

250+
我们通过`LinkedHashMap`的源码可以看到,基本上逻辑和我们的差不多,主要思路也就是用双向链表将添加的结点串起来
167251

252+
![image-20220918230956767](https://cdn.fengxianhub.top/resources-master/202209182309014.png)
168253

169254

170255

Linux/Linux常用命令.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,12 @@ docker run -p 6500:6379 \
790790
命令:
791791

792792
```sh
793-
docker run -d -p 9528:9528 --name nginx_volunteer -v /root/volunteer/nginx/conf.d:/etc/nginx/conf.d -v /root/volunteer/nginx/html:/usr/share/nginx/html nginx
793+
docker run -d \
794+
-p 9528:9528 \
795+
--name nginx_volunteer \
796+
-v /root/volunteer/nginx/conf.d:/etc/nginx/conf.d \
797+
-v /root/volunteer/nginx/html:/usr/share/nginx/html \
798+
nginx
794799
```
795800

796801
-d后台运行 -p映射端口 -v映射目录

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
**SSM**
5656

57-
- [Spring&SpringMVC](/Spring_Framework/Spring&SpringMVC.md) | [SpringBoot](/Spring_Framework/SpringBoot学习.md) | [MyBatis](/Spring_Framework/MyBatis学习.md) | [Spring Transaction](/Spring_Framework/Spring Transaction(事物)学习一、数据库事物、隔离级别.md)
57+
- [Spring&SpringMVC](/Spring_Framework/Spring&SpringMVC.md) | [SpringBoot](/Spring_Framework/SpringBoot学习.md) | [MyBatis](/Spring_Framework/MyBatis学习.md) | [Spring Transaction](/Spring_Framework/Spring Transaction.md)
5858

5959
**SpringCloud Alibaba**
6060

@@ -79,7 +79,7 @@
7979

8080
**容器技术**
8181

82-
[Docker基本使用](/SpringCloud/黑马SpringCloud-阿里巴巴/2-Docker实用篇.md)
82+
[Docker基本使用](/SpringCloud/黑马SpringCloud-阿里巴巴/2-Docker实用篇.md) | [Docker常用镜像构建命令](/运维/常用docker部署容器命令.md)
8383

8484
**缓存相关**
8585

File renamed without changes.
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# docker安装集合
2+
3+
🌻 如果已经过运行的项目
4+
🌟如果已经启动的项目.则使用update更新:
5+
6+
```jva
7+
docker update --restart = always 容器id
8+
```
9+
10+
## 1. 项目管理工具
11+
12+
### 1.1 docker安装禅道
13+
14+
```java
15+
docker run -d \
16+
-p 9053:80 \
17+
--restart always \
18+
--name zandao \
19+
--privileged \
20+
idoop/zentao:latest \
21+
&& docker ps
22+
```
23+
24+
### 1.2 安装堡垒机jumpserver
25+
26+
数据库由 DBA 在 MySQL 中创建:
27+
28+
```java
29+
create database jumpserver default charset 'utf8' collate 'utf8_bin';
30+
grant all on jumpserver.* to 'jumpserver'@'%' identified by 'l5UxsdvsdpYKdX';
31+
```
32+
33+
```java
34+
$ docker run --name jumperserver -d \
35+
-v /home/data/www/jms.wzlinux.com:/opt/jumpserver/data/media \
36+
-p 80:80 \
37+
-p 2222:2222 \
38+
-e SECRET_KEY=ytdh2lXAId8KjUdfyrVREVucBDCcnJzYehuHf6WRgLEXneUAsP \
39+
-e BOOTSTRAP_TOKEN=WhcyK8QTa0vckMmC \
40+
-e DB_HOST=172.17.0.5 \
41+
-e DB_PORT=3306 \
42+
-e DB_USER=jumpserver \
43+
-e DB_PASSWORD=l5UxsdvsdpYKdX \
44+
-e DB_NAME=jumpserver \
45+
-e REDIS_HOST=127.0.0.1 \
46+
-e REDIS_PORT=6379 \
47+
-e REDIS_PASSWORD= \
48+
--restart=on-failure:10 \
49+
jumpserver/jms_all:latest
50+
```
51+
52+
53+
54+
55+
56+
## 2. 数据库
57+
58+
### 2.1 安装mysql
59+
60+
```java
61+
docker run -d \
62+
-p 3308:3306 \
63+
--name mysql57 \
64+
--restart always \
65+
-e MYSQL_ROOT_PASSWORD=k4uc93i9y7v9r3ernbhijd848dawp6alb8ko8 \
66+
--character-set-server=utf8mb4 \
67+
--collation-server=utf8mb4_unicode_ci \
68+
mysql:5.7
69+
```
70+
71+
### 2.2 安装redis
72+
73+
74+
75+
76+
77+
78+
79+
80+
81+
## 3. 容器编排工具
82+
83+
### 3.1 K8s集群(手动安装)
84+
85+
#### 3.1.1 docker搭建centos容器
86+
87+
K8s集群需要centos版本高于7.8
88+
89+
首先我们创建一个网桥
90+
91+
```java
92+
docker network create --subnet=172.30.0.0/16 k8s_net && docker network ls
93+
```
94+
95+
拉取centos7.9的镜像(已经包含ssh、已更新yum源、安装python3.7)
96+
97+
```java
98+
docker pull azheng0506/centos7.9_python3.7:v1.0
99+
```
100+
101+
制作镜像,创建Dockerfile文件
102+
103+
```java
104+
FROM azheng0506/centos7.9_python3.7:1.0
105+
RUN yum -y install openssh-server
106+
RUN yum -y install bind-utils
107+
RUN yum -y install which
108+
RUN yum -y install sudo
109+
RUN yum install -y wget
110+
```
111+
112+
构建自己的镜像
113+
114+
```java
115+
docker build -t centos7.9-k8s .
116+
```
117+
118+
创建容器并分配好ip地址
119+
120+
```java
121+
docker run -d \
122+
--add-host k8s-master:172.30.0.2 \
123+
--net k8s_net \
124+
--ip 172.30.0.2 \
125+
-h k8s-master \
126+
-p 10122:22 \
127+
-p 17180:7180 \
128+
--restart always \
129+
--name k8s-master \
130+
--privileged \
131+
fengxiandada/centos7.9-k8s:v1.0.0 \
132+
/usr/sbin/init \
133+
&& docker ps
134+
```
135+
136+
进入容器修改root密码
137+
138+
```java
139+
$ docker exec -it k8s-master bash
140+
$ su root
141+
$ passwd
142+
$ root
143+
$ root
144+
```
145+
146+
创建slave
147+
148+
```java
149+
docker run -d \
150+
--add-host k8s-master:172.30.0.2 \
151+
--add-host k8s-slave01:172.30.0.3 \
152+
--net k8s_net \
153+
--ip 172.30.0.3 \
154+
-h k8s-slave01 \
155+
-p 10222:22 \
156+
--restart always \
157+
--name k8s-slave01 \
158+
--privileged \
159+
fengxiandada/centos7.9-k8s:v1.0.0 \
160+
/usr/sbin/init \
161+
&& docker ps
162+
```
163+
164+
#### 3.1.2 集群搭建
165+
166+
初始化master结点
167+
168+
```java
169+
# 只在 master 节点执行
170+
# 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP
171+
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
172+
export MASTER_IP=172.30.0.2
173+
# 替换 apiserver.demo 为 您想要的 dnsName
174+
export APISERVER_NAME=apiserver.demo
175+
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
176+
export POD_SUBNET=10.100.0.1/16
177+
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
178+
curl -sSL https://kuboard.cn/install-script/v1.19.x/init_master.sh | sh -s 1.19.5
179+
```
180+
181+
### 3.2 K8s集群(Kuboard-Spray方式)
182+
183+
```java
184+
docker run -d \
185+
--privileged \
186+
--restart=unless-stopped \
187+
--name=kuboard-spray \
188+
-p 80:80/tcp \
189+
-v /var/run/docker.sock:/var/run/docker.sock \
190+
-v /home/data/kuboard-spray-data:/data \
191+
eipwork/kuboard-spray:latest-amd64
192+
# 如果抓不到这个镜像,可以尝试一下这个备用地址:
193+
# swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard-spray:latest-amd64
194+
```
195+
196+
197+
198+
199+

0 commit comments

Comments
 (0)