该笔记仅用来记录学习狂神docker进阶视频的过程
Docker Compose是Docker官方的又一个开源项目,而不是Docker里面的内容,所以需要另外安装
# 下载
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 授权
[root@VM-20-17-centos bin]# sudo chmod +x /usr/local/bin/docker-compose
# 查看版本信息
[root@VM-20-17-centos bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
[root@VM-20-17-centos home]# mkdir composetest
[root@VM-20-17-centos home]# cd composetest
[root@VM-20-17-centos composetest]# vim app.py
#以下是app.py的内容
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
[root@VM-20-17-centos composetest]# vim requirements.txt
# Dockerfile 内容
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
[root@VM-20-17-centos composetest]# vim docker-compose.yml
# 以下是 docker-compose.yml内容
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
# 启动
[root@VM-20-17-centos composetest]# docker-compose up
ERROR: Version in "./docker-compose.yml" is unsupported. You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/
版本报错,照他提示修改docker-compose.yml里面的版本,我这里就改为3.3
# 启动成功
[root@VM-20-17-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bdeaaf95a605 redis:alpine "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp composetest_redis_1
3ba57318e521 composetest_web "flask run" About a minute ago Up About a minute 0.0.0.0:8000->5000/tcp, :::8000->5000/tcp composetest_web_1
成功效果图
[root@VM-20-17-centos ~]# curl localhost:8000
Hello World! I have been seen 1 times.
[root@VM-20-17-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest fe3ae489c0b5 6 minutes ago 185MB
redis alpine 3900abf41552 4 months ago 32.4MB
python 3.7-alpine a1034fd13493 4 months ago 41.8MB
# 查看网络,compose自动维护了一个网络,该网络内的容器之间就可以通过服务名互相访问
[root@VM-20-17-centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
34508300f083 bridge bridge local
6d7ed0ee2506 composetest_default bridge local
2242e5304377 host host local
7125179683a5 none null local
[root@VM-20-17-centos ~]# docker network inspect 6d7ed0ee2506
停止 docker-compose down
(需要在composetest目录下)
https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
version: "" # 版本
services: # 服务
(服务1)web:
# 服务配置
images
build: .
ports:
- "8000:5000"
network
.....
(服务2)redis:
....
(服务3)
。。。。
# 其他配置 网络/卷 、全局规则
volumes:
networks:
configs:
启动顺序要注意,如下中的web是依赖redis执行的,通过depends_on配置,保证redis先启动,再启动web
官方文档:https://docs.docker.com/samples/wordpress/
版本我这里依旧改为 3.3,官方给的版本太高
[root@VM-20-17-centos ~]# cd /home
[root@VM-20-17-centos home]# ls
composetest docker-test-volume lighthouse mybuild mysql springbootdocker test
[root@VM-20-17-centos home]# mkdir my_wordpress
[root@VM-20-17-centos home]# ls
composetest docker-test-volume lighthouse mybuild mysql my_wordpress springbootdocker test
[root@VM-20-17-centos home]# cd my_wordpress/
[root@VM-20-17-centos my_wordpress]# vim docker-compose.yml
[root@VM-20-17-centos my_wordpress]# docker-compose up
# docker-compose.yml内容如下
version: "3.3"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
wordpress博客密码: x$^VPwutKX9rfahXQX
管理页面地址 http://119.91.149.217:8000/wp-admin/
前台地址 http://119.91.149.217:8000/
# 后台启动
docker-compose up -d
1、编写微服务项目
2、dockerfile构建镜像
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
3、docker-compose.yaml 编排项目
version: '3.3'
services:
kayapp:
build: .
image: kayapp
depends_on:
- redis
ports:
- "8080:8080"
redis:
image: "library/redis:alpine"
4、丢到服务器 ,执行命令 docker-compose up
[root@iZwz98fvksp4n70u68swzqZ ~]# docker swarm --help
Usage: docker swarm COMMAND
Manage Swarm
Commands:
ca Display and rotate the root CA
init Initialize a swarm
join Join a swarm as a node and/or manager
join-token Manage join tokens
leave Leave the swarm
unlock Unlock swarm
unlock-key Manage the unlock key
update Update the swarm
Run 'docker swarm COMMAND --help' for more information on a command.
[root@iZwz98fvksp4n70u68swzqZ ~]# docker swarm init --help
Usage: docker swarm init [OPTIONS]
Initialize a swarm
Options:
--advertise-addr string Advertised address (format: <ip|interface>[:port])
--autolock Enable manager autolocking (requiring an unlock key to start a stopped manager)
--availability string Availability of the node ("active"|"pause"|"drain") (default "active")
--cert-expiry duration Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
--data-path-addr string Address or interface to use for data path traffic (format: <ip|interface>)
--data-path-port uint32 Port number to use for data path traffic (1024 - 49151). If no value is set or is set to 0, the
default port (4789) is used.
--default-addr-pool ipNetSlice default address pool in CIDR format (default [])
--default-addr-pool-mask-length uint32 default address pool subnet mask length (default 24)
--dispatcher-heartbeat duration Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
--external-ca external-ca Specifications of one or more certificate signing endpoints
--force-new-cluster Force create a new cluster from current state
--listen-addr node-addr Listen address (format: <ip|interface>[:port]) (default 0.0.0.0:2377)
--max-snapshots uint Number of additional Raft snapshots to retain
--snapshot-interval uint Number of log entries between Raft snapshots (default 10000)
--task-history-limit int Task history retention limit (default 5)
# 初始化节点 (这个操作是在docker-1这个服务器上操作的) 172.29.97.81用自己的 eth0网卡的地址
[root@iZwz98fvksp4n70u68swzqZ ~]# docker swarm init --advertise-addr 172.29.97.81
Swarm initialized: current node (qhf6uz80r4po13l3svkj4q69v) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-cbgd7xjwi4nmmugugbmn2bfla 172.29.97.81:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
# 加入工作节点(从)
docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-cbgd7xjwi4nmmugugbmn2bfla 172.29.97.81:2377
# 加入管理(主)
docker swarm join-token manager
# docker-2执行
[root@iZwz98fvksp4n70u68swzrZ ~]# docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-cbgd7xjwi4nmmugugbmn2bfla 172.29.97.81:2377
This node joined a swarm as a worker.
# docker-1执行
[root@iZwz98fvksp4n70u68swzqZ ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
qhf6uz80r4po13l3svkj4q69v * iZwz98fvksp4n70u68swzqZ Ready Active Leader 20.10.14
l5wtyhnza7gveyakkjdnhhp5u iZwz98fvksp4n70u68swzrZ Ready Active 20.10.14
# 获取令牌
docker swarm join-token manager
docker swarm join-token worker
# docker-1执行
[root@iZwz98fvksp4n70u68swzqZ ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-cbgd7xjwi4nmmugugbmn2bfla 172.29.97.81:2377
# docker-3 执行
[root@iZwz98fvksp4n70u68swzpZ ~]# docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-cbgd7xjwi4nmmugugbmn2bfla 172.29.97.81:2377
This node joined a swarm as a worker.
# docker-1
[root@iZwz98fvksp4n70u68swzqZ ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-dltdf7dwha0niw0nu7r2mb8y3 172.29.97.81:2377
#docker-4
[root@iZwz98fvksp4n70u68swzoZ ~]# docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-dltdf7dwha0niw0nu7r2mb8y3 172.29.97.81:2377
This node joined a swarm as a manager.
双主双从的集群 (搭建集群其实本来应该是至少三主 的)
[root@iZwz98fvksp4n70u68swzqZ ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
jr315df2w8mhxkj8mmmvcog43 iZwz98fvksp4n70u68swzoZ Ready Active Reachable 20.10.14
sqwv8fihfs72kj0t1bi495cxn iZwz98fvksp4n70u68swzpZ Ready Active 20.10.14
qhf6uz80r4po13l3svkj4q69v * iZwz98fvksp4n70u68swzqZ Ready Active Leader 20.10.14
l5wtyhnza7gveyakkjdnhhp5u iZwz98fvksp4n70u68swzrZ Ready Active 20.10.14
Raft动画演示 :http://thesecretlivesofdata.com/raft/
双主双从:假设一个节点挂了,其他节点是否可用?
Raft协议:保证大多数节点存活才可以用。 集群至少要大于3台
测试
1、将docker-1这台机器停止systemctl stop docker
。 双主的情况下,另外一个主节点也不能使用了(因为他无法判断是自己离线了还是另一个主节点离线了)
在docker-4执行 docker node ls,报如下错误
2、节点离开集群
# 重启docker-1
[root@iZwz98fvksp4n70u68swzqZ ~]# systemctl start docker
# 发现老大已经变成docker-4
[root@iZwz98fvksp4n70u68swzqZ ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
jr315df2w8mhxkj8mmmvcog43 iZwz98fvksp4n70u68swzoZ Ready Active Leader 20.10.14
sqwv8fihfs72kj0t1bi495cxn iZwz98fvksp4n70u68swzpZ Ready Active 20.10.14
qhf6uz80r4po13l3svkj4q69v * iZwz98fvksp4n70u68swzqZ Ready Active Reachable 20.10.14
l5wtyhnza7gveyakkjdnhhp5u iZwz98fvksp4n70u68swzrZ Ready Active 20.10.14
# docker-3离开集群 (打工人离职)
[root@iZwz98fvksp4n70u68swzpZ ~]# docker swarm leave
Node left the swarm.
# docker-1查看,发现docker-3的STATUS(状态)已经变为down
[root@iZwz98fvksp4n70u68swzqZ ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
jr315df2w8mhxkj8mmmvcog43 iZwz98fvksp4n70u68swzoZ Ready Active Leader 20.10.14
sqwv8fihfs72kj0t1bi495cxn iZwz98fvksp4n70u68swzpZ Down Active 20.10.14
qhf6uz80r4po13l3svkj4q69v * iZwz98fvksp4n70u68swzqZ Ready Active Reachable 20.10.14
l5wtyhnza7gveyakkjdnhhp5u iZwz98fvksp4n70u68swzrZ Ready Active 20.10.14
# docker-1 生成令牌
[root@iZwz98fvksp4n70u68swzqZ ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-dltdf7dwha0niw0nu7r2mb8y3 172.29.97.81:2377
# docker-3 成为主节点,此时就成了三主
[root@iZwz98fvksp4n70u68swzpZ ~]# docker swarm join --token SWMTKN-1-2phlgtraz7k3dfz7ulwyo59puwxwzxii2iiglx4m9gfa4iyasb-dltdf7dwha0niw0nu7r2mb8y3 172.29.97.81:2377
This node joined a swarm as a manager.
3、worker节点就算工作的,所以docker-2没法执行 docker node ls
这样的操作
# 停掉 docker-1
[root@iZwz98fvksp4n70u68swzqZ ~]# systemctl stop docker
# docker-4 查看
[root@iZwz98fvksp4n70u68swzoZ ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
jr315df2w8mhxkj8mmmvcog43 * iZwz98fvksp4n70u68swzoZ Ready Active Leader 20.10.14
dph67shd544rhfmjgt7ay4w9m iZwz98fvksp4n70u68swzpZ Ready Active Reachable 20.10.14
sqwv8fihfs72kj0t1bi495cxn iZwz98fvksp4n70u68swzpZ Down Active 20.10.14
qhf6uz80r4po13l3svkj4q69v iZwz98fvksp4n70u68swzqZ Down Active Unreachable 20.10.14
l5wtyhnza7gveyakkjdnhhp5u iZwz98fvksp4n70u68swzrZ Ready Active 20.10.14
# docker-3 查看
[root@iZwz98fvksp4n70u68swzpZ ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
jr315df2w8mhxkj8mmmvcog43 iZwz98fvksp4n70u68swzoZ Ready Active Leader 20.10.14
dph67shd544rhfmjgt7ay4w9m * iZwz98fvksp4n70u68swzpZ Ready Active Reachable 20.10.14
sqwv8fihfs72kj0t1bi495cxn iZwz98fvksp4n70u68swzpZ Down Active 20.10.14
qhf6uz80r4po13l3svkj4q69v iZwz98fvksp4n70u68swzqZ Down Active Unreachable 20.10.14
l5wtyhnza7gveyakkjdnhhp5u iZwz98fvksp4n70u68swzrZ Ready Active 20.10.14
可以正常使用,即实现了高可用
# 把docker-3也停掉
[root@iZwz98fvksp4n70u68swzpZ ~]# systemctl stop docker
# docker-4 查看
[root@iZwz98fvksp4n70u68swzoZ ~]# docker node ls
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.
docker集群 -> 容器是服务-> 服务可以在容器中启动多个
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service --help
Usage: docker service COMMAND
Manage services
Commands:
create Create a new service
inspect Display detailed information on one or more services
logs Fetch the logs of a service or task
ls List services
ps List the tasks of one or more services
rm Remove one or more services
rollback Revert changes to a service's configuration
scale Scale one or multiple replicated services
update Update a service
Run 'docker service COMMAND --help' for more information on a command.
# docker-1
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service create -p 8888:80 --name my-nginx nginx
docker run 启动容器,不具有扩缩容的功能
docker service 服务 具有扩缩容、滚动更新等功能
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service ps my-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
mpcff3vfx6xt my-nginx.1 nginx:latest iZwz98fvksp4n70u68swzpZ Running Running about a minute ago
# 查看服务
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
khx16af3ydne my-nginx replicated 1/1 nginx:latest *:8888->80/tcp
# docker-1 、docker-2 、docker-3、docker-4一个个尝试,发现服务跑在docker-3这台机器上面
[root@iZwz98fvksp4n70u68swzpZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96c83c3b3f9b nginx:latest "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 80/tcp my-nginx.1.mpcff3vfx6xt49ecsqwpgopvt
# 动态扩缩容
# docker-1上,给my-nginx创建三个副本
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service update --replicas 3 my-nginx
[root@iZwz98fvksp4n70u68swzqZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#docker-2查看
[root@iZwz98fvksp4n70u68swzrZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06883f50c1c5 nginx:latest "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp my-nginx.3.xekwkxqplqhx8d0r95pyzehcl
#docker-3 查看
[root@iZwz98fvksp4n70u68swzpZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96c83c3b3f9b nginx:latest "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 80/tcp my-nginx.1.mpcff3vfx6xt49ecsqwpgopvt
#docker-4 查看
[root@iZwz98fvksp4n70u68swzoZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66b48717cf69 nginx:latest "/docker-entrypoint.…" 54 seconds ago Up 53 seconds 80/tcp my-nginx.2.r56lr76bfa2d8da5rq0f0oiot
[root@iZwz98fvksp4n70u68swzoZ ~]#
# 开十个副本也没问题
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service update --replicas 10 my-nginx
overall progress: 10 out of 10 tasks
1/10: running [==================================================>]
2/10: running [==================================================>]
3/10: running [==================================================>]
4/10: running [==================================================>]
5/10: running [==================================================>]
6/10: running [==================================================>]
7/10: running [==================================================>]
8/10: running [==================================================>]
9/10: running [==================================================>]
10/10: running [==================================================>]
verify: Service converged
集群中任意节点都可以访问服务。服务可以有多个副本动态扩缩容实现高可用
# 嫌副本太多了,动态回滚,让他只剩下一个副本
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service update --replicas 1 my-nginx
my-nginx
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
# scale命令 和上面的update命令是一样的,也是动态扩缩容
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service scale my-nginx=5
my-nginx scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [===============
# 移除服务
[root@iZwz98fvksp4n70u68swzqZ ~]# docker service rm my-nginx
my-nginx
swarm
集群的管理和编排,docker可以初始化一个swarm集群,其他节点可以加入
Node
就是一个docker节点,多个节点就组成了一个网络集群。(节点分为:管理节点、工作节点)
Service
任务,可以在管理节点或者工作节点来运行。用户访问的就是Service
Task
容器内的命令,细节任务。前面说的副本,每个副本其实就是一个Task任务
下图是创建副本的时候的截图,可以看出就是在创建Task
docker-compose 单机部署项目
Docker Stack 集群部署
# 单机
docker-compose up -d wordpress.yml
# 集群
docker stack deploy wordpress.yml
# Docker Stack 案例
# docker-compose.yml内容如下
version: "3.3"
services:
service1:
image: "registry.cn-guangzhou.aliyuncs.com/lengcz_pub/test1:1.0"
deploy:
replicas: 2
ports:
- "8080:8080"
service2:
image: "registry.cn-guangzhou.aliyuncs.com/lengcz_pub/test2:1.0"
deploy:
replicas: 4
ports:
- "8081:8081"
名企笔试真题练习 https://www.nowcoder.com/contestRoom
校招笔试真题汇总 https://www.nowcoder.com/contestRoom?mutiTaglds=1657
校招备战学习计划 https://www.nowcoder.com/studypath/1
在线编程 https://www.nowcoder.com/activity/oj
剑指offer在线编程 https://www.nowcoder.com/ta/coding-interviews
牛客讨论区 https://www.nowcoder.com/discuss
各岗位汇总目录 https://www.nowcoder.com/discuss/167046
各公司面经汇总目录 https://www.nowcoder.com/discuss/161635
deploy:
replicas: 4
ports:
- “8081:8081”
# Docker Secret
[外链图片转存中...(img-bdAkaW2f-1651135164774)]
# Docker Config
[外链图片转存中...(img-Lh7I0ZVW-1651135164775)]
# CI/CD之Jenkins
## 什么是DevOps
[外链图片转存中...(img-5QUTk0zh-1651135164777)]
[外链图片转存中...(img-3zqqRbHo-1651135164778)]
## 如何落地实现DevOps理念
[外链图片转存中...(img-oMVnjFJ7-1651135164780)]
名企笔试真题练习 https://www.nowcoder.com/contestRoom
校招笔试真题汇总 https://www.nowcoder.com/contestRoom?mutiTaglds=1657
校招备战学习计划 https://www.nowcoder.com/studypath/1
在线编程 https://www.nowcoder.com/activity/oj
剑指offer在线编程 https://www.nowcoder.com/ta/coding-interviews
牛客讨论区 https://www.nowcoder.com/discuss
各岗位汇总目录 https://www.nowcoder.com/discuss/167046
各公司面经汇总目录 https://www.nowcoder.com/discuss/161635