├── src
├── offical-delivery
│ └── README.md
├── recommendation-delivery
│ └── README.md
├── start-learning
│ ├── resume.md
│ ├── README.md
│ ├── routine.md
│ └── interview.md
├── .vuepress
│ ├── styles
│ │ ├── index.scss
│ │ ├── config.scss
│ │ └── palette.scss
│ ├── public
│ │ ├── logo.jpg
│ │ ├── logo.png
│ │ ├── favicon.ico
│ │ ├── logodark.png
│ │ ├── assets
│ │ │ └── icon
│ │ │ │ ├── chrome-192.png
│ │ │ │ ├── chrome-512.png
│ │ │ │ ├── ms-icon-144.png
│ │ │ │ ├── apple-icon-152.png
│ │ │ │ ├── chrome-mask-192.png
│ │ │ │ ├── chrome-mask-512.png
│ │ │ │ └── guide-maskable.png
│ │ └── logo.svg
│ ├── config.ts
│ ├── navbar
│ │ └── navbar.ts
│ ├── theme.ts
│ └── sidebar
│ │ └── sidebar.ts
├── nginx
│ ├── README.md
│ └── rank.md
├── deliver
│ └── README.md
├── hr
│ ├── rank.md
│ └── README.md
├── k8s
│ └── rank.md
├── resume
│ └── README.md
├── docker
│ └── rank.md
├── rabbitmq
│ ├── README.md
│ ├── rank.md
│ ├── summary.md
│ └── apply.md
├── design
│ ├── README.md
│ ├── rank.md
│ └── bigdata.md
├── intelligence
│ ├── rank.md
│ └── README.md
├── golang
│ ├── README.md
│ ├── rank.md
│ ├── gc.md
│ ├── summary.md
│ └── gmp.md
├── network
│ ├── README.md
│ ├── summary.md
│ ├── rank.md
│ └── ip.md
├── article
│ ├── README.md
│ └── 02.md
├── java
│ ├── README.md
│ ├── rank.md
│ ├── summary.md
│ ├── jvm.md
│ ├── collection.md
│ └── spring.md
├── data-structure
│ └── rank.md
├── redis
│ ├── README.md
│ ├── rank.md
│ ├── summary.md
│ ├── colony.md
│ ├── persistence.md
│ ├── data-structure.md
│ └── application.md
├── mysql
│ ├── README.md
│ ├── optimize.md
│ ├── engine.md
│ ├── rank.md
│ ├── lock.md
│ ├── transaction.md
│ ├── summary.md
│ └── indexing.md
├── os
│ ├── README.md
│ ├── rank.md
│ ├── filesystem.md
│ └── concurrency.md
├── cpp
│ ├── rank.md
│ ├── README.md
│ ├── memoryManagement.md
│ ├── dataTypesAndTypeConversions.md
│ └── functionAndOperationOverloaders.md
├── reward
│ └── README.md
├── interview
│ └── README.md
├── group
│ └── README.md
├── project
│ └── rank.md
├── website-contribution
│ └── README.md
├── rank
│ └── README.md
├── algorithm-mandatory
│ ├── rank.md
│ └── README.md
├── README.md
├── guide
│ └── README.md
├── development-log
│ └── README.md
└── introduction
│ └── README.md
├── .gitignore
├── package.json
└── README.md
/src/offical-delivery/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/recommendation-delivery/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/start-learning/resume.md:
--------------------------------------------------------------------------------
1 | 努力赶稿中……
--------------------------------------------------------------------------------
/src/.vuepress/styles/index.scss:
--------------------------------------------------------------------------------
1 | // place your custom styles here
2 |
--------------------------------------------------------------------------------
/src/nginx/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Nginx
3 | pageInfo: false
4 | editLink: false
5 | ---
--------------------------------------------------------------------------------
/src/deliver/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | ---
--------------------------------------------------------------------------------
/src/hr/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
--------------------------------------------------------------------------------
/src/k8s/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
--------------------------------------------------------------------------------
/src/.vuepress/public/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/logo.jpg
--------------------------------------------------------------------------------
/src/.vuepress/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/logo.png
--------------------------------------------------------------------------------
/src/resume/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: heading
6 | ---
--------------------------------------------------------------------------------
/src/.vuepress/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/favicon.ico
--------------------------------------------------------------------------------
/src/.vuepress/public/logodark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/logodark.png
--------------------------------------------------------------------------------
/src/docker/rank.md:
--------------------------------------------------------------------------------
1 | ### 容器相比于虚拟机有什么优势?(1次)
2 |
3 | ### docker-compose的编排结构?(1次)
4 |
5 | ### 有写过dockerfile吗?RUN和CMD命令有什么区别?(1次)
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/chrome-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/chrome-192.png
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/chrome-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/chrome-512.png
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/ms-icon-144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/ms-icon-144.png
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/apple-icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/apple-icon-152.png
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/chrome-mask-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/chrome-mask-192.png
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/chrome-mask-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/chrome-mask-512.png
--------------------------------------------------------------------------------
/src/.vuepress/public/assets/icon/guide-maskable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zijing2333/CSView/HEAD/src/.vuepress/public/assets/icon/guide-maskable.png
--------------------------------------------------------------------------------
/src/nginx/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
7 |
8 |
9 |
10 | ### 令牌桶的原理?(1次)
11 |
12 | ### 令牌桶与漏桶相比有什么优势?(1次)
--------------------------------------------------------------------------------
/src/.vuepress/styles/config.scss:
--------------------------------------------------------------------------------
1 | // you can change config here
2 | $colors: #c0392b, #d35400, #f39c12, #27ae60, #16a085, #2980b9, #8e44ad, #2c3e50;
3 | // #7f8c8d !default;
4 | $code-light-theme: coy;
--------------------------------------------------------------------------------
/src/rabbitmq/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: RabbitMQ
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | ------
9 |
10 |
11 |
12 | # [概念](./summary.md)
13 |
14 | # [应用](./apply.md)
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | node_modules/
3 | src/.vuepress/.cache/
4 | src/.vuepress/.temp/
5 | src/.vuepress/dist/
6 |
7 | .idea/
8 |
9 | package-lock.json
10 | pnpm-lock.yaml
11 | yarn.lock
12 | deploy.sh
13 | .github
14 | src/.env
15 | src/config.json
16 |
--------------------------------------------------------------------------------
/src/design/README.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | pageInfo: false
4 | title: 设计题
5 | editLink: false
6 | comment: false
7 |
8 | ---
9 |
10 | # [常见设计题](./design.md)
11 |
12 | # [常见设计题](./design.md)
13 |
14 | # [海量数据处理题](./bigdata..mds)
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/intelligence/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
7 |
8 | ### 如何用[0,4]的随机数生成[0,6]的随机数?(1次)
9 |
10 | ### 判断一个数的二进制里面有多少个1? (1次)
11 |
12 | ### 怎么判断一个数是不是2的幂? (1次)
13 |
14 | ### 1000个银币中有一个假币,用天平找找几次? (1次)
15 |
--------------------------------------------------------------------------------
/src/golang/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | title: golang
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | # [概述](./summary.md)
9 |
10 | # [概述](./summary.md)
11 |
12 | # [关键字](./keyword.md)
13 |
14 | # [GMP](./gmp.md)
15 |
16 | # [垃圾回收](./gc.md)
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/network/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 计算机网络
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | # [HTTP(7题)](./http.md)
9 |
10 | # [概述](./summary.md)
11 |
12 | # [TCP和UDP](./tcp.md)
13 |
14 | # [HTTP](./http.md)
15 |
16 | # [IP](./ip.md)
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/article/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | ---
6 |
7 |
8 |
9 | ⭐️ 精品文章
10 |
11 |
12 |
13 | 🧭 学习路线
14 |
15 |
16 | ::: center
17 | ### [校招和实习,编程语言该怎么选?](./02.md)
18 |
19 | :::
20 |
21 |
--------------------------------------------------------------------------------
/src/java/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Java
3 | pageInfo: false
4 | editLink: false
5 | author: xmy
6 | comment: false
7 | ---
8 |
9 | ------
10 |
11 |
12 |
13 | # [基础](./summary.md)
14 |
15 | # [集合](./collection.md)
16 |
17 | # [并发](./concurrent.md)
18 |
19 | # [JVM](./jvm.md)
20 |
21 | # [Spring](./spring.md)
22 |
--------------------------------------------------------------------------------
/src/data-structure/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 数据结构面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | sidebar: false
6 | ---
7 |
8 | ------
9 |
10 | ------
11 |
12 | ### BFS和DFS的区别?(1次)
13 |
14 | ### Hash的实现方式?(1次)
15 |
16 | ### 介绍一下红黑树?(1次)
17 |
18 | ### 1w个数取前10大的数,用什么排序算法?(1次)
19 |
20 | ### 堆排序用的是小顶堆和大顶堆?(1次)
21 |
22 |
--------------------------------------------------------------------------------
/src/redis/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Redis
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | # [概述(6题)](./summary.md)
9 |
10 | # [概述](./summary.md)
11 |
12 | # [数据结构](./data-structure.md)
13 |
14 | # [持久化](./persistence.md)
15 |
16 | # [应用](./application.md)
17 |
18 | # [集群](./colony.md)
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/hr/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: HR面常见面试题
3 | sidebar: heading
4 | ---
5 |
6 | ### 你的优势和劣势是什么?
7 | ### 能接受多大强度的加班?
8 | ### 简单描述一下自己是怎么样的人?
9 | ### 最近阅读哪些技术书籍,遇到技术问题是怎么去解决?
10 | ### 项目中最难的地方是哪里?你学习到了什么?
11 | ### 与同事沟通的时候,如果遇到冲突了如何解决?
12 | ### 项目中有哪些可改进的点以及很优秀的点?
13 | ### 如何评价自己学习新知识的能力?
14 | ### 目前为止,坚持得最久一件事情是什么?
15 | ### 未来的职业规划是什么?
16 | ### 最近学习了哪些新技术?
17 | ### 你的老师和同学是如何评价你的?
--------------------------------------------------------------------------------
/src/mysql/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: MySQL
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | ------
9 |
10 | ------
11 |
12 |
13 |
14 |
15 | # [概述](./summary.md)
16 |
17 | # [事务](./transaction.md)
18 |
19 | # [索引](./indexing.md)
20 |
21 | # [锁](./lock.md)
22 |
23 | # [存储引擎](./engine.md)
24 |
25 | # [日志](./log.md)
26 |
27 | # [优化](./optimize.md)
28 |
29 |
--------------------------------------------------------------------------------
/src/os/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 操作系统
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | ------
9 |
10 |
11 |
12 | ### [计算机系统基础](./summary.md)
13 |
14 | ### [并发](./concurrency.md)
15 |
16 | ### [内存管理](./memory-management.md)
17 |
18 | ### [进程与线程管理](./process.md)
19 |
20 | ### [文件系统](./filesystem.md)
21 |
22 | ### [服务器编程](./serverprogramming.md)
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/cpp/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: C++面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | -------
10 | -------
11 |
12 |
13 |
14 | ### 手写智能指针类?(1次)
15 |
16 | ### 说一下C++多态有几种方式,分别怎么实现?(1次)
17 |
18 | ### 重定义和重载的区别是什么?(1次)
19 |
20 | ### 说一下虚函数?(1次)
21 |
22 | ### C++的内存分为哪几个区,分别是做什么的?(1次)
23 |
24 | ### 堆和栈的区别说一下?(1次)
25 |
26 | ### malloc分配在哪,alloc呢?(1次)
--------------------------------------------------------------------------------
/src/design/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 设计题和智力题题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 |
14 |
15 | ### 设计一个秒杀系统?(1次)
16 |
17 | ### 如果给你一个分布式系统,要求你限流,你怎么做,如何优化?(1次)
18 |
19 | ### 实际开发如何避免死锁?(1次)
20 |
21 | ### 后端解决同一个订单重复提交?(1次)
22 |
23 | ### 10亿个整数找出不同的整数,限制1G内存?(1次)
24 |
25 | ### 300个数据初始化后如何判重、如果是三千万个整型数据呢?(1次)
26 |
27 |
--------------------------------------------------------------------------------
/src/reward/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
7 | 
8 | ::: center
9 | ### 🧋打赏6元,作者可以喝一杯蜜雪冰城
10 |
11 | ### ☕️打赏18.88元,作者可以喝一杯瑞幸咖啡
12 |
13 | ### 🍔打赏50元,作者可以吃一顿疯狂星期四
14 |
15 | ### 🧸打赏188.88元,作者可以买一个仙子伊布玩偶
16 |
17 | ### ⭐或者帮作者去[GitHub](https://github.com/zijing2333/CSView)给项目点一个免费的star
18 |
19 | :::
20 |
21 |
--------------------------------------------------------------------------------
/src/rabbitmq/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
7 |
8 | ### RabbitMQ的作用? (1次)
9 |
10 | ### RabbitMQ怎么解决重复消费问题?(1次)
11 |
12 | ### MQ是否是消息安全的? (1次)
13 |
14 | ### RabbitMQ如何持久化? (1次)
15 |
16 | ### 为什么选择RocketMQ,和其他MQ的区别?(1次)
17 |
18 | ### RocketMQ如何保证消息的有序性? (1次)
19 |
20 | ### RocketMQ如何保证消息的可靠性? (1次)
21 |
22 | ### Kafka如何保障高性能的?(1次)
23 |
24 | ### Kafka能解决什么问题?(1次)
25 |
--------------------------------------------------------------------------------
/src/interview/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: heading
6 | ---
7 |
8 | ## 🔆面经提交的意义
9 |
10 | 为了更方便广大求职者寻找工作机会,同时也有利于本站的持续发展,希望您在每次面试之后,将面试过程中的内容记录下来并提交到的网站。
11 |
12 | 我们会将您提交的内容汇总展示为 [**面试分类**] 和 [**题目频次**] 等各个模块,同时针对面试经验中出现的题目,我们会不断更新我们网站上的内容。
13 |
14 | 这样可以帮助更多的学习者了解真实的面试过程,并更好地应对面试中出现的问题。
15 |
16 |
17 | ## 📬提交方式
18 |
19 | 可以添加我的个人微信或者发送到邮箱:
20 |
21 | - 微信账号:zijing5277
22 |
23 |
24 | - 邮箱:944741457@qq.com
--------------------------------------------------------------------------------
/src/group/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | ---
6 |
7 | 📣扫描下方二维码,即可关注微信公众号CSView:
8 |
9 | 
10 |
11 | 📥点击加入群聊,获取CSView学习交流群二维码,群内不仅有备战招聘面试的朋友,也有已经上岸的同学:
12 |
13 | 
14 |
15 | 📲回复[**面试学习资料**],即可获得本站所有推荐学习资料PDF版本:
16 |
17 |
18 | 
19 |
20 | 📂更多面经解析和面试知识将在公众号更新。
--------------------------------------------------------------------------------
/src/project/rank.md:
--------------------------------------------------------------------------------
1 | ### 项目里怎么用的Redis?为什么要用Redis?(2次)
2 |
3 | ### 项目哪里用到了多线程?(2次)
4 |
5 | ### 项目用过哪些设计模式?(1次)
6 |
7 | ### 项目中用到了Redis哪些数据结构?(1次)
8 |
9 | ### 项目中用过什么索引?(1次)
10 |
11 | ### 介绍一下工厂方法,有哪些应用场景?(1次)
12 |
13 | ### 项目里为什么要用Elasticsearch来做查询,为什么不直接用数据库查询?(1次)
14 |
15 | ### 针对项目里的保证登录用户唯一性,这个唯一性指的什么?(1次)
16 |
17 | ### 如果在不同的机器上登录,只要有账户密码就能登录吗?(1次)
18 |
19 | ### 单例模式里面的懒汉式线程安全吗?(1次)
20 |
21 | ### 怎么让懒汉式实现线程安全?(1次)
22 |
23 | ### 懒汉式加锁具体是加在哪里的?(1次)
24 |
25 | ### 项目中MQ用在哪些场景?(1次)
--------------------------------------------------------------------------------
/src/cpp/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: C++
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | ------
9 |
10 |
11 |
12 | ### [C++基础概念和语法](./summary.md)
13 |
14 | ### [数据类型和类型转换](./dataTypesAndTypeConversions.md)
15 |
16 | ### [指针和引用](./pointersAndReferences.md)
17 |
18 |
19 | ### [函数和运算重载符](./functionAndOperationOverloaders.md)
20 |
21 | ### [继承和多态](./inheritanceAndPolymorphism.md)
22 |
23 | ### [内存管理](./memoryManagement.md)
24 |
25 | ### [编译和链接](./compileAndLink.md)
26 |
27 | ### [C++11/14/17/20新特性](./newFeatures.md)
28 |
29 | ### [STL](./stl.md)
30 |
--------------------------------------------------------------------------------
/src/website-contribution/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 网站贡献
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | ------
9 |
10 |
11 |
12 | | 日期 | 贡献者 | 金额 | 备注 |
13 | | :-----------: | :-----: | :---: | :--: |
14 | | 2023年2月27日 | 云隙光| 18.88 | 无 |
15 | | 2023年2月27日 | Zacking | 6 | 无 |
16 | | 2023年2月28日 | 元 | 66.66 | 打call! |
17 | | 2023年3月9日 | 生 | 50 | 感谢良心整理! |
18 | | 2023年3月20日 | 振 | 50 | 无 |
19 | | 2023年4月10日 | 辰砂 | 50 | 加油! |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vuepress-theme-hope-template",
3 | "version": "2.0.0",
4 | "description": "A project of vuepress-theme-hope",
5 | "license": "MIT",
6 | "type": "module",
7 | "scripts": {
8 | "docs:build": "vuepress build src",
9 | "docs:clean-dev": "vuepress dev src --clean-cache",
10 | "docs:dev": "vuepress dev src",
11 | "docs:deploy": "sh deploy.sh",
12 | "docs:update-package": "pnpm dlx vp-update"
13 | },
14 | "devDependencies": {
15 | "@vuepress/client": "2.0.0-beta.61",
16 | "vue": "^3.2.47",
17 | "vuepress": "2.0.0-beta.61",
18 | "vuepress-plugin-search-pro": "2.0.0-beta.193",
19 | "vuepress-theme-hope": "2.0.0-beta.193"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/rank/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | comment: false
5 | sidebar: false
6 | ---
7 |
8 | ::: tip 页面内容
9 | **提交面经到本站,我会将面经内容整理到以下各个模块,帮助大家更好复习。**
10 | :::
11 |
12 | ### [算法刷题题频排序](../algorithm-mandatory/rank.md)
13 |
14 | ### [计算机网络题频排序](../network/rank.md)
15 |
16 | ### [操作系统题频排序](../os/rank.md)
17 |
18 | ### [mysql题频排序](../mysql/rank.md)
19 |
20 | ### [redis题频排序](../redis/rank.md)
21 |
22 | ### [golang题频排序](../golang/rank.md)
23 |
24 | ### [Java题频排序](../java/rank.md)
25 |
26 | ### [C++题频排序](../cpp/rank.md)
27 |
28 | ### [设计模式题频排序](../cpp/rank.md)
29 |
30 | ### [RabbitMQ题频排序](../rabbitmq/rank.md)
31 |
32 | ### [系统设计题题频排序](../design/rank.md)
33 |
34 | ### [智力题题频排序](../intelligence/rank.md)
35 |
36 | ### [HR面题频排序](../hr/rank.md)
--------------------------------------------------------------------------------
/src/algorithm-mandatory/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 面试算法题频排序
3 | pageInfo: false
4 | editLink: false
5 | sidebar: false
6 | ---
7 |
8 | ------
9 |
10 | ------
11 |
12 |
13 |
14 | ### 常见的排序算法 (3次)
15 |
16 | ### 3.无重复字符的最长子串(2次)
17 |
18 | ### 手撕单例模式(2次)
19 |
20 | ### 124.二叉树中的最大路径和(2次)
21 |
22 | ### 3.无重复字符的最长子串(2次)
23 |
24 | ### 多线程交替打印数字(2次)
25 |
26 | ### 1143.最长公共子序列(2次)
27 |
28 | ### 739.每日温度(1次)
29 |
30 | ### 手撕约瑟夫环(1次)
31 |
32 | ### 143. 重排链表(1次)
33 |
34 | ### 518.零钱兑换 II (1次)
35 |
36 | ### 43.字符串相乘 (1次)
37 |
38 | ### 59.螺旋矩阵 II (1次)
39 |
40 | ### 328.奇偶链表 (1次)
41 |
42 | ### 206.反转链表 (1次)
43 |
44 | ### 146.LRU 缓存(1次)
45 |
46 | ### 24.两两交换链表中的节点(1次)
47 |
48 | ### 25.K个一组翻转链表(1次)
49 |
50 | ### 209.长度最小的子数组(1次)
51 |
52 | ### 572.另一棵树的子树(1次)
53 |
54 | ### 141.环形链表(1次)
55 |
56 | ### 142.环形链表 II(1次)
57 |
58 | ### 二叉树BFS(1次)
59 |
60 | ### 常见排序算法时间复杂度(1次)
61 |
62 | ### 92.反转链表(1次)
63 |
--------------------------------------------------------------------------------
/src/golang/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: golang面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 |
14 | ### 介绍一下goroutine调度机制? (2次)
15 |
16 | ### 介绍一下golang的垃圾回收? (2次)
17 |
18 | ### Slice的底层实现? (2次)
19 |
20 | ### 黑色对象新产生的对象怎么回收? (1次)
21 |
22 | ### GMP中M的时是操作系统内核吗? (1次)
23 |
24 | ### GMP中M的数量是多少? (1次)
25 |
26 | ### 并发编程的channel和sync有什么区别? (1次)
27 |
28 | ### sync底层实现原理? (1次)
29 |
30 | ### String的底层实现?(1次)
31 |
32 | ### String或者切片作为函数参数形参会不会影响实参?(1次)
33 |
34 | ### Slice和数组的区别? (1次)
35 |
36 | ### Slice的扩容机制? (1次)
37 |
38 | ### defer的概述? (1次)
39 |
40 | ### defer的底层原理? (1次)
41 |
42 | ### defer函数和return的执行顺序? (1次)
43 |
44 | ### 有缓冲channel和无缓冲channel有什么区别? (1次)
45 |
46 | ### 读写已关闭的channel会发生什么? (1次)
47 |
48 | ### goroutine与进程、线程的区别?(1次)
49 |
50 | ### make和new的区别?(1次)
51 |
52 | ### map并发安全的吗?如何实现并发安全的map?(1次)
53 |
--------------------------------------------------------------------------------
/src/os/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 操作系统面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 |
14 |
15 | ### 进程间的通信方式有哪些? (5次)
16 |
17 | ### 介绍一下I/O多路复用,select、poll、epoll有什么区别? (4次)
18 |
19 | ### 进程、线程、协程的区别?(3次)
20 |
21 | ### 介绍一下一致性哈希算法?(2次)
22 |
23 | ### Linux常用命令有哪些?(2次)
24 |
25 | ### 什么是死锁? (2次)
26 |
27 | ### 介绍一下零拷贝?(2次)
28 |
29 | ### 操作系统中什么是缺页中断?(1次)
30 |
31 | ### 详细介绍一下管道?(1次)
32 |
33 | ### 如何避免死锁?(1次)
34 |
35 | ### 一致性哈希算法如何防止数据倾斜?(1次)
36 |
37 | ### epoll的效率会随着文件描述符增多而下降吗?(1次)
38 |
39 | ### IO/NIO的区别?(1次)
40 |
41 | ### 多线程、多进程、I/O多路复用对比?(1次)
42 |
43 | ### 协程相比于线程有哪些优势? (1次)
44 |
45 |
46 | ### 中断的类型有哪些?(1次)
47 |
48 | ### 中断处理程序是怎么实现的?(1次)
49 |
50 | ### 乐观锁和悲观锁? (1次)
51 |
52 | ### CAS算法? (1次)
53 |
54 | ### 什么是CPU运行的基本单位?(1次)
55 |
56 | ### 什么是操作系统执行的基本单位?(1次)
57 |
58 | ### 进程调度算法? (1次)
59 |
60 | ### 介绍一下内存 分页置换算法? (1次)
61 |
62 | ### 进程之间如何进行同步?(1次)
63 |
64 | ### 介绍一下虚拟内存?(1次)
--------------------------------------------------------------------------------
/src/start-learning/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 学习指南
3 | index: false
4 | pageInfo: false
5 | editLink: false
6 | ---
7 |
8 |
9 |
10 |
11 | ## 面试
12 |
13 |
14 | - [面试学习路线](../start-learning/routine.md)
15 |
16 | - [面试内容(附带面试建议:heavy_exclamation_mark:)](../start-learning/interview.md)
17 |
18 |
19 |
20 | ## 刷题
21 |
22 | - [面试必刷算法题](../algorithm-mandatory/README.md)
23 |
24 | - [智力题](../intelligence/README.md)
25 |
26 | - [设计题](../design/README.md)
27 |
28 | - [HR面常见题](../hr/README.md)
29 |
30 |
31 | ## 计算机基础
32 |
33 | - [计算机网络](../network/README.md)
34 |
35 | - [操作系统](../os/README.md)
36 |
37 |
38 | ## 数据库
39 |
40 | - [MySQL](../mysql/README.md)
41 |
42 | - [Redis](../redis/README.md)
43 |
44 |
45 | ## 语言基础
46 |
47 | - [golang](../golang/README.md)
48 |
49 | - [Java](../java/README.md)
50 |
51 | - [C++](../cpp/README.md)
52 |
53 |
54 | ## 中间件
55 |
56 | - [RabbitMQ](../rabbitmq/README.md)
57 |
58 | - [Nginx](../nginx/README.md)
59 |
60 | - [K8s](../k8s/README.md)
61 |
62 |
--------------------------------------------------------------------------------
/src/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | icon: home
4 | title: 首页
5 | heroImage: /logo.png
6 | heroImageDark: /logodark.png
7 | heroText: CSView
8 | tagline: 一个互联网面试内容汇总和八股文学习的网站,让互联网面试不再成为困难~
9 |
10 | actions:
11 | - text: 开始学习 🧭
12 | link: /start-learning
13 | type: primary
14 |
15 | - text: 题频排序 💡
16 | link: /rank
17 |
18 | - text: 精品文章 📄
19 | link: /article
20 |
21 | features:
22 | - title: 使用指南
23 | icon: zhinanzhidao-xianxing
24 | details: 介绍网站的一些基本功能,阅读指南有助于提高学习效率
25 | link: /guide
26 |
27 | - title: 公众号&学习群
28 | icon: shuyi_qunliao
29 | details: 加入微信交流群跟各位互联网上岸同学交流,互相学习,一起进步。公众号会定期分享高质量面经解析
30 | link: /group
31 |
32 |
33 | - title: 支持网站
34 | icon: hongbao1
35 | details: 可以请作者喝一杯奶茶,或者去Github点一个免费的star
36 | link: /reward
37 |
38 |
39 |
40 |
41 | footer: 备案号:吉ICP备2023000735号-2
42 |
43 | ---
44 |
45 |
46 |
47 | 
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/golang/gc.md:
--------------------------------------------------------------------------------
1 | ### golang的垃圾回收?
2 |
3 | golang GC 算法使用的是无分代(对象没有代际之分)、不整理(回收过程中不对对象进行移动与整理)、并发(与用户代码并发执行)的三色标记清扫算法。
4 |
5 |
6 |
7 | 三色标记法将对象分为三类,并用不同的颜色相称:
8 |
9 | - **白色对象(可能死亡)**:未被回收器访问到的对象。在回收开始阶段,所有对象均为白色,当回收结束后,白色对象均不可达
10 | - **灰色对象(波面)**:已被回收器访问到的对象,但回收器需要对其中的一个或多个指针进行扫描,因为他们可能还指向白色对象
11 | - **黑色对象(确定存活)**:已被回收器访问到的对象,其中所有字段都已被扫描,黑色对象中任何一个指针都不可能直接指向白色对象
12 |
13 | 标记过程如下:
14 |
15 | - 第一步:起初所有的对象都是白色的
16 | - 第二步:从根对象出发扫描所有可达对象,标记为灰色,放入待处理队列
17 | - 第三步:从待处理队列中取出灰色对象,将其引用的对象标记为灰色并放入待处理队列中,自身标记为黑色
18 | - 重复第三步,直到待处理队列为空,此时白色对象即为不可达的“垃圾”,回收白色对象
19 |
20 |
21 |
22 | ### 写屏障?
23 |
24 | 当标记和程序是并发执行的,这就会造成一个问题。在标记过程中,有新的引用产生,可能会导致误清扫。清扫开始前,标记为黑色的对象引用了一个新申请的对象,它肯定是白色的,而黑色对象不会被再次扫描,那么这个白色对象无法被扫描变成灰色、黑色,它就会最终被清扫。golang 采用了写屏障,作用就是为了避免这类误清扫问题,写屏障即在内存写操作前,维护一个约束,从而确保清扫开始前,黑色的对象不能引用白色对象。gc一旦开始,无论是创建对象还是对象的引用改变,都会先变为灰色。
25 |
26 |
27 |
28 | ### 垃圾回收的触发条件?
29 |
30 | - 系统触发:运行时自行根据内置的条件,检查、发现到则进行 GC 处理,维护整个应用程序的可用性
31 | - 系统监控:当超过两分钟没有产生任何GC时,强制触发 GC
32 | - 步调(Pacing)算法,其核心思想是控制内存增长的比例,当前内存分配达到一定比例则触发
33 | - 触发:开发者在业务代码中自行调用 runtime.GC 方法来触发 GC
--------------------------------------------------------------------------------
/src/network/summary.md:
--------------------------------------------------------------------------------
1 | ### OSI的7层网络模型?
2 |
3 | 分为应用层、表示层、会话层、运输层、网络层、链路层、物理层。
4 |
5 | - 应用层(数据):确定进程之间**通信的性质**以及满足用户需要以及提供网络和用户应用,为应用程序提供服务,DNS,HTTP,HTTPS,DHCP,FTP,POP3(Post Office Protocol)、SMTP(Simple Mail Transfer Protocol)都是这层的协议。
6 | - 表示层(数据):主要解决用户信息的**语法表示**问题,表示层提供各种**用于应用层数据的编码和转换功能**,确保一个系统的应用层发送的数据能被另一个系统的应用层识别,**如数据转换,压缩和加密,解密**。
7 | - 会话层(数据):会话层就是负责**建立、管理和终止表示层实体之间的通信会话**。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。 比如服务器验证用户登录就是在会话层。
8 | - 传输层(段):实现网络不同主机上的用户进程之间的数据通信,可靠与不可靠的传输,传输层的错误检测,流量控制,拥塞控制。TCP UDP就这层。
9 | - 网络层(包):本层通过**IP寻址**来建立两个节点之间的连接,为源端的运输层送来的分组,**选择合适的路由和交换节点**,正确无误地按照地址传送给目的端的运输层。IP就是这层。
10 | - 数据链路层(帧):将上层数据封装成帧,用**MAC**地址访问媒介,并由错误检测和修正
11 | - 物理层(比特流):设备之间比特流的传输,物理接口,电气特性(常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。)
12 |
13 |
14 |
15 | ### TCP/IP的四层网络模型?
16 |
17 | TCP四层模型是我们实践过程中发现比较合理的分层,虽然我们实际过程中都没有按OSI分为七层,但是OSI对我们实践过程分层有着指导性的意义。
18 |
19 | 
20 |
21 |
22 |
23 | ### 五层因特网协议栈?
24 |
25 | 应用层、运输层、网络层、链路层、物理层。
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/algorithm-mandatory/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | title: 面试必刷算法题
4 | editLink: false
5 | comment: false
6 | ---
7 | ------
8 |
9 | ------
10 |
11 | ## :closed_book: 手撕
12 |
13 | #### [常见面试手撕题目总结](./handtearing.md)
14 |
15 |
16 |
17 | ## :green_book:链表
18 |
19 | #### 1️⃣[链表第一部分 1~7 题](./linklist/01.md)
20 |
21 | #### 2️⃣[链表第二部分 8~14 题](./linklist/02.md)
22 |
23 | #### 3️⃣[链表第三部分 15~20 题](./linklist/03.md)
24 |
25 |
26 |
27 |
28 |
29 | ## :blue_book:树
30 |
31 | #### 1️⃣[树第一部分 1~10 题](./tree/01.md)
32 |
33 | #### 2️⃣[树第二部分 11~20 题](./tree/02.md)
34 |
35 | #### 3️⃣[树第三部分 21~28 题](./tree/03.md)
36 |
37 |
38 |
39 | ## :orange_book:栈和队列
40 |
41 | #### 1️⃣[栈和队列第一部分 1~4 题](./stark-queue/01.md)
42 |
43 | #### 2️⃣[栈和队列第二部分 5~8 题](./stark-queue/02.md)
44 |
45 |
46 |
47 | ## :notebook:字符串
48 |
49 | #### 1️⃣[第一部分 1~6 题](./string/01.md)
50 |
51 | #### 2️⃣[第二部分 7~11 题](./string/02.md)
52 |
53 |
54 |
55 | ## :notebook_with_decorative_cover:[数组](./array.md)
56 |
57 | ## :ledger:[动态规划](./dp.md)
58 |
59 | ## :page_facing_up:[DFS](./dfs.md)
60 |
61 | ## :page_with_curl:[回溯](./backtrack.md)
62 |
63 | ## :bookmark_tabs:[其他](./other.md)
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/src/.vuepress/public/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/guide/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar: heading
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 | ### 📱题频标注
9 |
10 | 本站多数题目用已用标注出现频率:
11 |
12 | - 对于题目,面试必问,如果简历上写了相关内容一定要会
13 |
14 | - 对于题目,面试中出现几率较高,应当作为掌握内容
15 |
16 | - 对于题目,面试偶尔会出现,可作为补充学习或深入探究掌握
17 |
18 |
19 |
20 | ### ➡️算法页面跳转
21 |
22 | 刷题页面点击题目名称:
23 |
24 | 
25 |
26 | 即可跳转道对应题目力扣做题界面:
27 |
28 | 
29 |
30 | ### 🔍全站搜索
31 |
32 | 网站已经配置了全站搜索功能,您可以在网页右上角使用它帮助你找到需要的内容。
33 |
34 | 
35 |
36 | ### 🌙夜间模式
37 |
38 | 可以在页面右上角选择切换夜间模式,帮助你获得不同的阅读体验。
39 |
40 | 
41 |
42 | 
43 |
44 |
45 |
46 | ### ❤🩹编辑修改
47 |
48 | 在每个页面文末都有**编辑此页**功能,对于错误内容可以直接提交到GitHub,我将每天审核并进行修复。
49 |
50 |
51 |

52 |
--------------------------------------------------------------------------------
/src/network/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 计算机网络面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 |
14 |
15 | ### 介绍一下TCP的拥塞控制?(5次)
16 |
17 | ### 介绍一下TCP的三次握手?(4次)
18 |
19 | ### 介绍一下TCP的四次挥手?(4次)
20 |
21 | ### TCP和UDP的区别?(4次)
22 |
23 | ### 浏览器输入URL到显示的过程发生了什么?(3次)
24 |
25 | ### HTTPS加密通信过程?(3次)
26 |
27 | ### TCP是如何保证可靠传输的?(3次)
28 |
29 | ### 中间人攻击?(2次)
30 |
31 | ### 介绍一下HTTPS协议?(2次)
32 |
33 | ### SYN攻击的概念?怎么解决SYN攻击?(2次)
34 |
35 | ### TCP的为什么要四次挥手?(2次)
36 |
37 | ### 介绍一下HTTP的状态码?(2次)
38 |
39 | ### HTTP和HTTPS有什么区别?(2次)
40 |
41 | ### HTTP1.0、2.0、3.0之间的区别?(2次)
42 |
43 | ### TIME_WAIT作用是什么,过多如何解决?(2次)
44 |
45 | ### TCP的为什么要三次握手?(2次)
46 |
47 | ### TCP的为什么不是两次握手?(2次)
48 |
49 | ### 介绍一下cookie和session的区别和联系?(1次)
50 |
51 | ### 有哪些网络攻击方式?(1次)
52 |
53 | ### 介绍一下五层网络模型?(1次)
54 |
55 | ### TCP和UDP在哪一层?(1次)
56 |
57 | ### 介绍一下跨域?如何解决跨域问题?(1次)
58 |
59 | ### 介绍一下TCP的滑动窗口作用和原理?(1次)
60 |
61 | ### TCP有哪些优点?(1次)
62 |
63 | ### 计算机网络的分层?每层的作用是什么?(1次)
64 |
65 | ### TCP的MSL时间是多长?(1次)
66 |
67 | ### 为什么TIME_WAIT状态需要经过2MSL?(1次)
68 |
69 | ### 如果已经建立了连接,但是客户端突然出现故障了怎么办?(1次)
70 |
71 | ### 介绍一下HTTP常见状态码? (1次)
72 |
73 | ### 介绍一下XSS攻击?(1次)
74 |
75 | ### 介绍一下粘包和拆包?怎么解决?(1次)
76 |
77 | ### CA证书可以防止中间人吗? (1次)
78 |
79 | ### 滑动窗口和拥塞窗口的作用? (1次)
80 |
81 | ### ping命令的工作原理是什么? (1次)
82 |
83 | ### JWT Token怎么签发? (1次)
84 |
--------------------------------------------------------------------------------
/src/mysql/optimize.md:
--------------------------------------------------------------------------------
1 | ### 慢查询的原因?
2 |
3 | - **索引不足**:如果查询的表没有合适的索引,MySQL需要遍历整个表才能找到匹配的记录,这会导致查询变慢。可以通过添加索引来优化查询性能。
4 |
5 | - **数据库设计问题**:如果数据库设计不合理,例如表过于庞大、列过多等,查询时可能需要耗费大量时间。这时可以通过优化数据库设计来解决问题。
6 |
7 | - **数据库服务器负载过高**:如果MySQL服务器上同时运行了太多的查询,会导致服务器负载过高,从而导致查询变慢。可以通过增加服务器硬件配置或分散查询负载来解决问题。
8 |
9 | - **查询语句复杂**:复杂的查询语句可能需要耗费更多的时间才能完成。可以尝试简化查询语句或将查询分解成多个较简单的查询语句来提高性能。
10 |
11 | - **数据库统计信息不准确**:如果数据库统计信息不准确,MySQL可能会选择不合适的查询计划,从而导致查询变慢。可以通过更新数据库统计信息来解决问题。
12 |
13 | - **MySQL版本过低**:较老版本的MySQL可能性能较差,升级到较新版本的MySQL可能会提高查询性能。
14 |
15 | 
16 |
17 | ### MySQL磁盘I/O很高有什么优化的方法?
18 |
19 | **设置组提交的两个参数**: binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 参数,延迟 binlog 刷盘的时机,从而减少 binlog 的刷盘次数。
20 |
21 | ::: tip 提示
22 |
23 | 这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但即使 MySQL 进程中途挂了,也没有丢失数据的风险,因为 binlog 早被写入到 page cache 了,只要系统没有宕机,缓存在 page cache 里的 binlog 就会被持久化到磁盘。
24 |
25 | :::
26 |
27 | **将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000)**:表示每次提交事务都 write,但累积 N 个事务后才 fsync,相当于延迟了 binlog 刷盘的时机。但是这样做的风险是,主机掉电时会丢 N 个事务的 binlog 日志。
28 |
29 | **将 innodb_flush_log_at_trx_commit 设置为 2**:表示每次事务提交时,都只是缓存在 redo log buffer 里的 redo log 写到 redo log 文件,注意写入到redo log 文件并不意味着写入到了磁盘,因为操作系统的文件系统中有个 Page Cache,专门用来缓存文件数据的,所以写入 redo log文件意味着写入到了操作系统的文件缓存,然后交由操作系统控制持久化到磁盘的时机。但是这样做的风险是,主机掉电的时候会丢数据。
--------------------------------------------------------------------------------
/src/redis/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Redis面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 | ### 介绍一下Redis的缓存击穿、穿透和雪崩?以及对应怎么解决?(6次)
14 |
15 | ### 如何用Redis实现分布式锁? (6次)
16 |
17 | ### 如何保证数据库和缓存的一致性?(4次)
18 |
19 | ### Redis有哪些数据结构?(4次)
20 |
21 | ### 介绍一下Redis的持久化方式?(4次)
22 |
23 | ### 介绍一下布隆过滤器?(4次)
24 |
25 | ### 介绍一下Redis的Zset的底层数据结构? (3次)
26 |
27 | ### Redis为什么采用跳表作为Zset底层数据结构?(2次)
28 |
29 | ### 介绍一下Redis数据结构的应用场景?(2次)
30 |
31 |
32 | ### 使用旁路缓存(Cathe Aside)策略会有什么问题?(2次)
33 |
34 | ### Zset怎么实现插入和删除?如何确定Zset新节点的层数?(2次)
35 |
36 | ### Redis哈希扩容的过程?(2次)
37 |
38 | ### 介绍一下AOF和RDB的优点和缺点?(1次)
39 |
40 | ### **Redis支持回滚吗?**(1次)
41 |
42 | ### 介绍一下Redis的底层数据结构?(1次)
43 |
44 | ### 如何提高Redis的性能?(1次)
45 |
46 | ### 怎么解决缓存脏数据? (1次)
47 |
48 | ### Redis实现分布式锁节点上锁之后解锁之前挂掉了怎么办? (1次)
49 |
50 | ### Redis哪里用到了单线程,哪里用到了多线程? (1次)
51 |
52 | ### 使用Redis的优点有哪些? (1次)
53 |
54 | ### 为什么选择Redis作为MySQL的缓存? (1次)
55 |
56 | ### Redis宕机要怎么进行数据恢复? (1次)
57 |
58 |
59 | ### 哨兵集群有什么缺点? (1次)
60 |
61 | ### 热key失效怎么解决?(1次)
62 |
63 |
64 | ### AOF文件过大会怎么样?(1次)
65 |
66 | ### Redis持久化时可以进行写操作吗?(1次)
67 |
68 | ### 删除缓存失败怎么办?(1次)
69 |
70 | ### 介绍一下Redis的集群模式?(1次)
71 |
72 | ### 集群的脑裂是什么?如何解决脑裂?(1次)
73 |
74 | ### Redis是如何实现I/O多路复用的?(1次)
75 |
76 | ### select、poll、epoll在Redis中如何应用的?使用时会不会陷入内核态?(1次)
77 |
78 | ### Redis原子性操作的原理?(1次)
79 |
80 | ### 介绍一下Redis的主从集群?(1次)
81 |
82 | ###
83 |
84 |
--------------------------------------------------------------------------------
/src/intelligence/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar: heading
3 | ---
4 |
5 |
6 |
7 | ### 利用不均匀硬币产生等概率?
8 |
9 | 连续抛两次硬币,正反面的出现有四种情况,概率依次为:
10 |
11 | 1. 两次均为正面:p * p
12 | 2. 第一次正面,第二次反面:p * (1 - p)
13 | 3. 第一次反面,第二次正面:(1 - p) * p
14 | 4. 两次均为反面:(1 - p) * (1 - p)
15 |
16 | 问题的解法就是连续抛两次硬币,如果两次得到的相同则重新抛两次;否则根据第一次(或第二次)的正面反面情况,就可以得到两个概率相等的事件。
17 |
18 |
19 |
20 | ### 5只猫5分钟捉5只老鼠,请问100分钟捉100只老鼠需要多少只猫?
21 |
22 | 5只,分析:1只猫5分钟捉1只老鼠,1只猫100分钟捉20只老鼠,5只猫100分钟捉100只老鼠。
23 |
24 |
25 |
26 | ### 3升的杯子一个,5升的杯子一个,杯子不规则形状,问怎么得到4升的水?
27 |
28 | - 5升杯子装满,全部倒给空的3升杯子,此时5升杯子有2升,3升杯子要3升
29 | - 倒掉3升杯子的全部水,再把5升杯子的2升水倒给3升杯子,此时5升杯子有0升,3升杯子有2升
30 | - 5升杯子装满水,向3升辈子倒水,倒满,此时此时5升杯子有4升,3升杯子有3升
31 |
32 |
33 |
34 | ### 用5L和6L的桶,没有刻度,怎么量出3L的水?
35 |
36 | - 6L桶装满水,向空的5升桶倒水至水满为止,此时6L桶有1升水,5L桶有5升水
37 | - 倒掉5L桶的全部水,再把6L桶的1升水倒给5L桶,此时6L桶有0升水,5L桶有1升水
38 | - 6L桶装满水,向5升桶倒水至水满为止,此时6L桶有2升水,5L桶有5升水
39 | - 倒掉5L桶的全部水,再把6L桶的2升水倒给5L桶,此时6L桶有0升水,5L桶有2升水
40 | - 6L桶装满水,向5升桶倒水至水满为止,此时6L桶有3升水,5L桶有5升水
41 |
42 |
43 |
44 | ### 晚上有四个人过桥,一次只能过两个人,但是只有一只手电筒,四个人过桥时间分别是1,2,5,8,求最短过桥时间?
45 |
46 | 假设这四人依次是甲乙丙丁:首先甲和乙过桥,甲带手电筒回来;然后丙和丁过桥,由乙带手电筒回来;最后甲再和乙一起过桥,所以最少用时间是2+1+8+2+2=15(分钟)
47 |
48 |
49 |
50 | ### 有十张扑克牌,每次可以只出一张,也可以只出两张,要出完有多少种出法?
51 |
52 | - 还有一张牌就出完10张,可能的情况有两种,从9到10和从8到10,已知了从0到9的出法有N种,如果再知道从0到8的出法有P种,那么从0到10级的出法就是N+P,那么可得出:
53 | - F(9)=N;F(8)=P;F(10)=N+P;F(10)=F(9)+F(8);
54 | - 又有:F(1)=1;F(2)=2最后推出:F(10)=89
55 |
56 |
57 |
58 | ### 两根香,一根烧完1小时,如何测量15分钟?
59 |
60 | 开始时一根香两头点着,一根香只点一头,两头点着的香烧完说明过去了半小时,这时将只点了一头的香另一头也点着,从这时开始到烧完就是15分钟。
61 |
62 |
--------------------------------------------------------------------------------
/src/mysql/engine.md:
--------------------------------------------------------------------------------
1 | ### MySQL的执行引擎有哪些?
2 |
3 | 主要有MyISAM、InnoDB、Memery等引擎:
4 |
5 | - InnoDB引擎提供了对事务ACID的支持,还提供了行级锁和外键的约束。
6 | - MyISAM引擎不支持事务,也不支持行级锁和外键约束。
7 | - Memery就是将数据放在内存中,数据处理速度很快,但是安全性不高。
8 |
9 |
10 |
11 | ### MyISAM和InnoDB存储引擎的区别?
12 |
13 | - **锁的细粒度不同**:InnoDB比MyISAM更好的支持并发,因为InnoDB的支持行锁,而MyISAM支持表锁,行锁对每一条记录上锁,所以开销更大,但是可以解决脏读和不可重复读的问题,相对来说也更容易发生死锁。
14 | - **可恢复性**:InnoDB有事务日志,数据库崩溃后可以通过日志进行恢复,MyISAM没有日志支持。
15 | - **查询性能**:MyISAM要好于InnoDB,因为InnoDB在查询过程中是在维护数据缓存。并且先要定位到所在数据块,然后从数据块定位到数据内存地址来查找数据。
16 | - **表结构文件**:MyISAM 的表结构文件包括 .frm(表结构定义),.MYI(索引)、.MYD(数据);而InnDB的表数据文件为 .ibd(数据和索引集中存储)和.frm(表结构定义)。
17 | - **记录存储顺序**:MyISAM按照记录插入顺序,InnoDB按照主键大小顺序有序插入。
18 | - **外键和事务**:MyISAM均不支持,InnoDB支持。对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务。对一个包含外键的InnoDB表转为MYISAM会失败。
19 | - **操作速度**:对于SELECT前者更优,INSERT、UPDATE、DELETE后者更优。select count(*)使用MyISAM更块,因为内部维护了一个计数器,可以直接调度。
20 | - **存储空间**:MyISAM可被压缩,存储空间较小,InnoDB的表需要更多的内存和存储,会在主内存中建立专用的缓冲池用于高速缓存数据和索引。
21 | - **索引方式**:二者都是B+树索引,前者是堆表,后者是索引组织表。
22 |
23 | ::: tip 为什么InnoDB没有计数器变量?
24 |
25 | 因为InnoDB的事务特性,同一时刻表中的行数对于不同事务而言是不同的,因此计数器统计的是当前事务对应的行数,而不是总行数。
26 |
27 | :::
28 |
29 |
30 |
31 | ### 存储引擎如何选择?
32 |
33 | 如果没有特别的需求,使用默认的InnoDB即可。
34 |
35 | 要支持事务选择InnoDB,如果不需要可以考虑MyISAM;如果表中绝大多数都只是读查询考虑MyISAM,如果既有读也有写使用InnoDB存储引擎。
36 |
37 | 系统奔溃后,MyISAM恢复起来更困难,能否接受系统崩溃的程度;MySQL5.5版本开始Innodb已经成为MySQL的默认引擎(之前是MyISAM),说明其优势是有目共睹的。
38 |
39 |
40 |
41 | ### MyISAM索引与InnoDB索引的区别?
42 |
43 | - InnDB是聚簇索引,MyISAM是非聚簇索引。
44 | - InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
45 | - InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。
46 |
47 |
--------------------------------------------------------------------------------
/src/java/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Java面试高频题
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 |
14 |
15 | ### 介绍一下Java的垃圾回收算法?(4次)
16 |
17 | ### 介绍一下Java的线程池?(4次)
18 |
19 | ### 介绍一下SpringAOP和IOC?(3次)
20 |
21 | ### 介绍一下ConcurrentHashMap的实现原理?(3次)
22 |
23 | ### JVM的内存模型?(3次)
24 |
25 | ### 类加载机制是什么?(3次)
26 |
27 | ### 介绍一下Java的多线程?(2次)
28 |
29 | ### 面向对象的原则?(2次)
30 |
31 | ### Java线程池有哪些参数?(2次)
32 |
33 | ### 介绍一下HashMap?(2次)
34 |
35 | ### 介绍一下JVM?(2次)
36 |
37 | ### 创建线程的方法?(1次)
38 |
39 | ### 介绍一下AQS?(1次)
40 |
41 | ### 介绍一下Spring事务的原理?(1次)
42 |
43 | ### **SpringEvent和RocketMQ有什么区别?(1次)**
44 |
45 | ### **Spring事务失效有哪些场景**?(1次)
46 |
47 | ### ReentrantLock和syncronized差别?(1次)
48 |
49 | ### 内存区域哪些地方会OOM?(1次)
50 |
51 | ### Java8有什么新特性?(1次)
52 |
53 | ### Spring Boot的优势?(1次)
54 |
55 | ### Spring支持哪些作用域?(1次)
56 |
57 | ### 介绍一下Java的异常处理?(1次)
58 |
59 | ### 异常和错误有什么区别?(1次)
60 |
61 | ### 介绍一下volatile关键字?(1次)
62 |
63 | ### 什么是多线程?如何保证多线程的执行顺序?(1次)
64 |
65 | ### 创建对象的过程?(1次)
66 |
67 | ### Object类有哪些方法?(1次)
68 |
69 | ### Thread类中三个方法的区别?(1次)
70 |
71 | ### 介绍一下双亲委派机制?(1次)
72 |
73 | ### Java线程的资源都有哪些,线程栈的大小大致在多少?(1次)
74 |
75 | ### SpringBoot和Spring有哪些区别?(1次)
76 |
77 | ### mybatis的映射是怎么实现的?(1次)
78 |
79 | ### Java的可重入锁是怎么实现的?(1次)
80 |
81 | ### Synchronized和Reentrantlock的区别和场景?(1次)
82 |
83 | ### Synchronized锁升级?(1次)
84 |
85 | ### Sleep和Wait的区别?(1次)
86 |
87 | ### Bean的生命周期?(1次)
88 |
89 | ### Bean的作用域?(1次)
90 |
91 | ### Java中的多态是怎么实现的?(1次)
92 |
93 | ### 多个线程都处于running状态,实际是在同时运行吗?(1次)
94 |
95 | ### 如何控制切面执行顺序?(1次)
96 |
97 | ### MVC使用HTTP的常用注解?(1次)
98 |
99 | ### 链表底层原理?(1次)
100 |
101 | ### 哪些对象可以作为GCRoot?(1次)
102 |
103 | ### Java的引用类型和应用?(1次)
104 |
105 |
--------------------------------------------------------------------------------
/src/start-learning/routine.md:
--------------------------------------------------------------------------------
1 | ::: tip 提示
2 |
3 | 只推荐一些自己学习时候看过的书和内容,此内容不存在任何广告,请放心实用。点击名称即可跳转到对应购买链接。
4 |
5 | 关注微信公众号[CSView],即可获得所有资料供学习和交流使用。
6 |
7 | :::
8 |
9 |
10 |
11 | ## MySQL
12 |
13 | ### [《MySQL必知必会》](http://product.dangdang.com/28522531.html)
14 |
15 | 这本书适合SQL都不会写的初学者入门,教你最基础的SQL语法,书不厚,几个小时能看完,用作入门性价比非常高。
16 |
17 | 我见过数据库八股文背的贼6,最后面试官考了一条简单的SQL查询都不会写的人,蛮有意思:smile:。
18 |
19 | ### [《MySQL技术内幕:InnoDB存储引擎》](http://product.dangdang.com/29412434.html)
20 |
21 | 数据库的经典之作,也算热门神书之一,深入浅出,非常适合用来进阶。通过这本书可以对存储引擎、索引、锁、事务等有所掌握。无论面试还是用来学习都非常合适,如果这本书读完了去面试,至少面试官对你的评价应该是“你对数据库非常了解”了。
22 |
23 | ### [《MySQL实战45讲》](https://time.geekbang.org/column/intro/139)
24 |
25 | 前腾讯云数据库负责人丁奇在极客时间上推出的专栏,常年位于学习榜TOP1位置,知名度是有目共睹的。作者给了很多生动的例子,让你对MySQL的实践运用有更深一层的了解。
26 |
27 | ### [《图解MySQL》](https://xiaolincoding.com/mysql/)
28 |
29 | 小林哥创作的图解系列一直有口皆碑,里面有很多面试题的详细解析,配合丰富的图解,很值得一读。
30 |
31 |
32 |
33 | ## Redis
34 |
35 | ### [《Redis设计与实现》](http://product.dangdang.com/23501734.html)
36 |
37 | 讲的比较细,对新手很友好的一本书。想啃Redis源码又啃不进去的,从这本书入门吧,面试很有用:muscle:!
38 |
39 | ### [《Redis开发与运维》](http://product.dangdang.com/24194121.html)
40 |
41 | 兼顾了原理和实践、开发与运维。看看下面的豆瓣评论,不多介绍了。
42 |
43 | 
44 |
45 | ### [《图解Redis》](https://xiaolincoding.com/redis/)
46 |
47 | 推荐理由同MySQL,很适合面试学习,里面同样讲解了很多面试题。
48 |
49 |
50 |
51 | ## 计算机网络
52 |
53 | ### [《图解HTTP》](http://product.dangdang.com/29236370.html)、[《图解TCP/IP》](http://product.dangdang.com/23265967.html)
54 |
55 | 这两本书同属一个系列所以放一起说了:计算机网络最佳入门书籍,没有之一。日本人写的很多介绍类书籍都值得一看,非常通俗易懂,讲的也比较好(想深入学习去啃自顶向下)。
56 |
57 | ### [《图解网络》](https://xiaolincoding.com/network/)
58 |
59 | 最早开始因为啃不动自顶向下大黑书进而读的小林哥的图解网络系列。写的很好,再次推荐。
60 |
61 |
62 |
63 | ## Golang
64 |
65 |
66 |
67 | ### [《Go语言精进之路套装 从新手到高手的编程思想 方法和技巧》](http://product.dangdang.com/29386170.html)
68 |
69 | 适合熟悉golang语法之后看一看,配有github开源的代码,在学习的时候可以跟着敲一敲。这本书讲了很多golang的设计哲学和编程语言的惯用方法,作为通用了解也是干货比较多的书籍之一。
70 |
71 |
72 |
73 | ## K8s
74 |
75 | ### [《深入剖析Kubernetes》](http://product.dangdang.com/11150718490.html)
76 |
77 | 从行业视角解读了容器化技术的发展过程,这个部分我觉得是作为一般的技术书籍很少涉及到的,让读者可以理解为什么容器技术会有今天的局面。技术部分讲了很多可以实操的东西,至少我认为书中的内容面试是可以用上的。
78 |
79 |
--------------------------------------------------------------------------------
/src/mysql/rank.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 数据库面试题频排序
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | sidebar: false
7 | ---
8 |
9 | ------
10 |
11 | ------
12 |
13 | ### 介绍一下事务隔离级别?使用场景和原理是什么?(7次)
14 |
15 | ### MySQL里面有哪些索引?(5次)
16 |
17 | ### MySQL为什么选择B+树作为索引?对比二叉树有哪些优势?(4次)
18 |
19 | ### 什么是幻读?怎么解决幻读?(3次)
20 |
21 | ### B和B+树有什么区别?(3次)
22 |
23 | ### undolog、redolog、binlog对于一个写操作的执行顺序?(2次)
24 |
25 | ### MySQL的执行引擎有哪些?(2次)
26 |
27 | ### MyISAM和InnoDB的区别? (2次)
28 |
29 | ### 介绍一下MVCC?(2次)
30 |
31 | ### 事务有哪些特性?(2次)
32 |
33 | ### 介绍一下聚簇索引和非聚簇索引的区别?(2次)
34 |
35 | ### 介绍一下什么是数据库的事务?(1次)
36 |
37 | ### redis和MySQL有什么区别?(1次)
38 |
39 | ### 讲一讲联表查询?(1次)
40 |
41 | ### B+树的查询只访问一次磁盘吗?(1次)
42 |
43 | ### 分布式事务实现方式?(1次)
44 |
45 | ### MySql数据库都是支持事务的吗?(1次)
46 |
47 | ### 介绍一下replace into?(1次)
48 |
49 | ### 索引的优化?(1次)
50 |
51 | ### 可重复读是怎么实现的?(1次)
52 |
53 | ### MySQL的默认隔离级别是什么?(1次)
54 |
55 | ### 重复读和幻读的区别是什么?(1次)
56 |
57 | ### 什么是前缀索引?(1次)
58 |
59 | ### 什么是最左匹配原则?(1次)
60 |
61 | ### 事务的持久性是怎么实现的?(1次)
62 |
63 | ### 事务的隔离性是怎么实现的?(1次)
64 |
65 |
66 | ### MySQL的三大日志?(1次)
67 |
68 | ### MySQL in和or的区别?(1次)
69 |
70 | ### redo log的作用?(1次)
71 |
72 | ### 索引有哪些数据结构?(1次)
73 |
74 | ### Where和Having有什么区别?(1次)
75 |
76 | ### join和union有什么区别?(1次)
77 |
78 | ### 为什么不用bin log来实现崩溃恢复?(1次)
79 |
80 |
81 | ### 如何开启、提交、回滚一个事务?(1次)
82 |
83 | ### 聚簇索引和非聚簇索引的区别?(1次)
84 |
85 | ### InnoDB如何存储数据?(1次)
86 |
87 | ### InnoDB和MyISAM的区别?(1次)
88 |
89 | ### InnoDB的四大特性?(1次)
90 |
91 | ### 存储引擎的选择?(1次)
92 |
93 | ### B树和B+树对比有什么区别?(1次)
94 |
95 | ### MySQL都有什么类型的锁? (1次)
96 |
97 | ### 介绍一下乐观锁和悲观锁? (1次)
98 |
99 | ### 行锁和表锁? (1次)
100 |
101 | ### MySQL会出现死锁吗,怎么检测死锁? (1次)
102 |
103 | ### MySQL怎么避免死锁?(1次)
104 |
105 | ### SQL注入攻击?(1次)
106 |
107 |
108 | ### ACID是什么?怎么实现的?(1次)
109 |
110 | ### B+树、红黑树和跳表的区别?(1次)
111 |
112 | ### B+树的阶是不是越大越好?(1次)
113 |
114 | ### Insert一条数据的过程?(1次)
115 |
116 | ### MySQL的两阶段提交?(1次)
117 |
118 | ### MySQL性能调优?(1次)
119 |
120 | ### 如何合理使用索引?(1次)
121 |
122 | ### 慢查询的原因?怎么解决?(1次)
123 |
124 | ### 读未提交是怎么实现的?(1次)
125 |
126 | ### 读提交是怎么实现的?(1次)
127 |
128 | ### 使用SQL统计一个班级同名的学生姓名(名字相同大于1人的学生)(1次)
--------------------------------------------------------------------------------
/src/.vuepress/styles/palette.scss:
--------------------------------------------------------------------------------
1 | // you can change colors here
2 | // $theme-color: #096dd9;
3 | // $text-color:(
4 | // light:#212c37,
5 | // dark:#c9cad8,
6 | // );
7 |
8 | // $home-page-width: 70em;
9 | $theme-color: #2980b9;
10 | // $sidebar-width: 17rem;
11 | // $sidebar-mobile-width: 16rem;
12 | // $bg-color: (
13 | // light: #fdfafa,
14 | // dark: #1b1a1a,
15 | // );
16 | // $content-width: 50em;
17 | $border-color: (
18 | light: #ddd,
19 | dark: #444,
20 | );
21 |
22 | // .hero-info-wrapper .action-button {
23 | // // display: inline-block;
24 | // // overflow: hidden;
25 | // margin: 0.6rem;
26 | // padding: 0.5em 1.7rem;
27 | // border-radius: 3rem;
28 | // background: #67a52e;
29 | // color: #fffdfd;
30 | // font-size: 1.3rem;
31 | // transition: color var(--color-transition), color var(--color-transition), transform var(--transform-transition);
32 | // }
33 |
34 | // .hero-info-wrapper img {
35 | // display: block;
36 | // max-width: 100%;
37 | // max-height: 23rem;
38 | // margin: 0;
39 | // }
40 |
41 | .hero-info-wrapper .description {
42 | max-width: 35rem;
43 | color: #396794;
44 | font-weight: 500;
45 | font-size: 1.6rem;
46 | line-height: 1.3;
47 | }
48 |
49 | h1,
50 | h2,
51 | h3,
52 | h4,
53 | h5,
54 | h6 {
55 | font-weight: 600;
56 | line-height: 1.25;
57 | overflow-wrap: break-word;
58 | }
59 |
60 | .sidebar > .sidebar-links > li > .sidebar-link {
61 | font-size: 1em;
62 | }
63 |
64 | .hero-info-wrapper {
65 | .hero-info {
66 | .actions {
67 | .action-button {
68 | color: #2c3e50;
69 | transition-property: background-color;
70 | // transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
71 | // transition-duration: 150ms;
72 | }
73 | .action-button:nth-child(1) {
74 | background: #f9a8d4;
75 | }
76 | .action-button:nth-child(1):hover {
77 | background: #fbcfe8;
78 | }
79 | .action-button:nth-child(2) {
80 | background: #93c5fd;
81 | }
82 | .action-button:nth-child(2):hover {
83 | background: #bfdbfe;
84 | }
85 | .action-button:nth-child(3) {
86 | background: #7dd3fc;
87 | }
88 | .action-button:nth-child(3):hover {
89 | background: #bae6fd;
90 | }
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/src/.vuepress/config.ts:
--------------------------------------------------------------------------------
1 | import { defineUserConfig } from "vuepress";
2 | import theme from "./theme.js";
3 | import { searchProPlugin } from "vuepress-plugin-search-pro";
4 |
5 |
6 | export default defineUserConfig({
7 |
8 |
9 | // 部署站点基础路径
10 | base: "/",
11 |
12 | // 站点的语言
13 | lang: "zh-CN",
14 |
15 | // 站点的标题
16 | title: 'CSView计算机招聘知识分享',
17 |
18 | // 站点的描述
19 | description : 'CSView是一个互联网面试知识学习和汇总的八股文网站,包括面试高频算法、系统设计、计算机网络、操作系统、C++、Java、golang、MySQL、Redis、K8s、消息队列等常见面试题。',
20 |
21 |
22 | head: [
23 | // 自定义favicon
24 | ['link', { rel: 'icon', href: '/logo.png' }],
25 | // 流量统计脚本
26 | [
27 | "script",
28 | {},
29 | `var _hmt = _hmt || [];
30 | (function() {
31 | var hm = document.createElement("script");
32 | hm.src = "https://hm.baidu.com/hm.js?c902278b2f3d0bef22a61dce631ddecb";
33 | var s = document.getElementsByTagName("script")[0];
34 | s.parentNode.insertBefore(hm, s);
35 | })();`,
36 | ],
37 | [
38 | "script",
39 | {},
40 | `var _paq = window._paq = window._paq || [];
41 | /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
42 | _paq.push(['trackPageView']);
43 | _paq.push(['enableLinkTracking']);
44 | (function() {
45 | var u="//www.csguide.xyz/";
46 | _paq.push(['setTrackerUrl', u+'matomo.php']);
47 | _paq.push(['setSiteId', '1']);
48 | var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
49 | g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
50 | })();`,
51 | ],
52 | ],
53 |
54 | // 主题
55 | theme,
56 |
57 | // 插件
58 | plugins: [
59 |
60 | // 搜索插件
61 | searchProPlugin({
62 | // 索引全部内容
63 | indexContent: true,
64 | locales:{
65 | "/zh/": {
66 | cancel: "取消",
67 | placeholder: "搜索",
68 | search: "搜索",
69 | searching: "搜索中",
70 | select: "选择",
71 | navigate: "切换",
72 | exit: "关闭",
73 | history: "搜索历史",
74 | emptyHistory: "无搜索历史",
75 | emptyResult: "没有找到结果",
76 | loading: "正在加载搜索索引...",
77 | },
78 | },
79 |
80 | }),
81 | ],
82 | shouldPrefetch: true,
83 | });
84 |
--------------------------------------------------------------------------------
/src/java/summary.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 基础
3 | author: xmy
4 | ---
5 |
6 | ### Object类
7 | Object类是Java所有类的父类,包含了所有对象最通用的方法,主要有:
8 | - **equals**:用于判断两个对象内容是否等同,没有重写的情况下与`==`相同,都是比较地址是否相同,而它设计出来的目的就是为了使程序员通过重写equals自定义比较对象的哪些内容,比如String的equals是比较字符串内容
9 | - **getClass**:用于获取对象(堆)运行时的类对象(方法区)
10 | - **hashCode**:用于获取对象的hashCode,主要应用于哈希桶相关容器的定位计算。
11 | - **toString**:用于获取对象的字符串表示
12 | - **notify/notifyAll/wait**:用于将线程唤醒/阻塞
13 | - **clone**:用于拷贝对象
14 | ### 深浅拷贝
15 | 浅拷贝只拷贝对象本身,不对其属性中的引用类型创建新的对象,即拷贝前后的两个对象中的引用指向同一个对象。深拷贝则会为引用类型递归地创建新的对象。对于基本数据类型的属性则都会复制一份。Java中对象的clone方法默认是浅拷贝,如果想深拷贝可以重写clone来实现
16 |
17 | 
18 | ### 拆装箱原理
19 | 以Integer为例
20 |
21 | `Integer i = 10`
22 |
23 | 装箱时自动调用Integer的valueOf(int)方法
24 |
25 | `int n = i`
26 |
27 | 拆箱时自动调用Integer的intValue方法
28 | 
29 | Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的,它们的参数如果在一定范围内,则会返回cache中已经存在的对象,否则new一个新对象返回
30 |
31 | Double、Float的valueOf方法的实现是类似的,这两个没有范围,都返回新对象
32 |
33 | ```java
34 | public static Integer valueOf(int i) {
35 | if (i >= IntegerCache.low && i <= IntegerCache.high)
36 | return IntegerCache.cache[i + (-IntegerCache.low)];
37 | return new Integer(i);
38 | }
39 | ```
40 |
41 | ```java
42 | public static Double valueOf(double d) {
43 | return new Double(d);
44 | }
45 | ```
46 |
47 | Boolean的valueOf都返回两个单例的变量之一
48 |
49 | ```java
50 | public static final Boolean TRUE = new Boolean(true);
51 |
52 | public static final Boolean FALSE = new Boolean(false);
53 |
54 | public static Boolean valueOf(boolean b) {
55 | return (b ? TRUE : FALSE);
56 | }
57 | ```
58 |
59 | 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
60 | ### String相关
61 | **String、StringBuilder和StringBuffer的主要区别**
62 |
63 | - String中的字符数组有final修饰,因此不可变,每次给String类型的引用赋值都是新生成个对象再把该引用指过去,或者是指向字符串常量池中的对象
64 |
65 | - StringBuilder和StringBuffer都继承AbstractStringBuilder,其中的字符数组没有final修饰,可通过令其指向新的字符数组实现各种增删改查操作,二者都有功能相同的各种对其中字符串增删改查的方法,区别是后者的这些方法都加了synchronized修饰,是线程安全的
66 |
67 | **各自使用场景**
68 |
69 | - String:操作少量数据
70 |
71 | - StringBuilder:操作大量数据,单线程
72 |
73 | - StringBuffer:操作大量数据,多线程
74 |
75 | ### 接口和抽象类的区别
76 | - 接口方法默认public,抽象类还有protected和default,它们都不能有private,因为生来只为被重写
77 | - 接口只能有static、final变量,抽象类不一定
78 | - 一个类只能继承一个类/抽象类,但可以实现多个接口。一个接口也可以继承多个接口
79 | - 设计上讲,抽象类抽象一类事物,接口抽象一组行为
80 | - 在 jdk 7 或更早版本中,接口里面只能有常量变量和抽象方法。这些接口方法必须由选择实现接口的类实现。jdk 8 的时候接口可以有默认方法和静态方法功能。Jdk 9 在接口中引入了私有方法和私有静态方法。
--------------------------------------------------------------------------------
/src/.vuepress/navbar/navbar.ts:
--------------------------------------------------------------------------------
1 | import { navbar } from "vuepress-theme-hope";
2 |
3 | export const navBar = navbar([
4 |
5 | {
6 | text: "面试题",
7 | icon: "suanfaku",
8 | children: [
9 | {
10 | text: "力扣高频必刷题",
11 | icon: "zhongdianbiaozhu",
12 | link: "/algorithm-mandatory/",
13 |
14 | },
15 | {
16 | text: "智力题",
17 | icon: "dengpao",
18 | link: "/intelligence/",
19 |
20 | },
21 | {
22 | text: "设计题",
23 | icon: "sheji-xianxing",
24 | link: "/design/",
25 | },
26 | {
27 | text: "HR面常见题",
28 | icon: "mianshianpai",
29 | link: "/hr/",
30 | },
31 | ],
32 | },
33 |
34 | { text: "计算机网络", icon: "wangluo1", link: "/network/" },
35 |
36 | { text: "操作系统", icon: "caozuoxitong", link: "/os/" },
37 |
38 | {
39 | text: "数据库",
40 | icon: "data-Inquire-full",
41 | children: [
42 | {
43 | text: "MySQL",
44 | icon: "odbc-full",
45 | link: "/mysql/",
46 | },
47 | {
48 | text: "Redis",
49 | icon: "redis",
50 | link: "/redis/",
51 | },
52 | ],
53 | },
54 |
55 | {
56 | text: "编程语言基础",
57 | icon: "biancheng-01",
58 | children: [
59 | {
60 | text: "golang",
61 | icon: "Goyuyan",
62 | link: "/golang/",
63 | },
64 | {
65 | text: "c++",
66 | icon: "cyuyan",
67 | link: "/cpp/",
68 | },
69 | {
70 | text: "java",
71 | icon: "java",
72 | link: "/java/",
73 | },
74 | ],
75 | },
76 |
77 | {
78 | text: "中间件",
79 | icon: "gongju",
80 | children: [
81 | {
82 | text: "RabbitMQ",
83 | icon: "RabbitMQ",
84 | link: "/rabbitmq/",
85 | },
86 | {
87 | text: "Nginx",
88 | icon: "nginx",
89 | link: "/nginx/",
90 | },
91 | {
92 | text: "Kubernetes",
93 | icon: "kubernetes",
94 | link: "/k8s/",
95 | },
96 | ],
97 | },
98 |
99 | {
100 | text: "关于本站",
101 | icon: "guanyu",
102 | children: [
103 | {
104 | text: "项目介绍",
105 | icon: "jieshaoxinxi",
106 | link: "/introduction",
107 | },
108 | {
109 | text: "开发日志",
110 | icon: "rizhi",
111 | link: "/development-log",
112 | },
113 | {
114 | text: "网站贡献",
115 | icon: "gongxian",
116 | link: "/website-contribution",
117 | },
118 | ],
119 | },
120 | ]);
121 |
--------------------------------------------------------------------------------
/src/redis/summary.md:
--------------------------------------------------------------------------------
1 | ### Redis为什么快?
2 |
3 | **基于内存操作**:Redis的绝大部分操作在内存里就可以实现,数据也存在内存中,与传统的磁盘文件操作相比减少了IO,提高了操作的速度。
4 |
5 | **高效的数据结构**:Redis有专门设计了STRING、LIST、HASH等高效的数据结构,依赖各种数据结构提升了读写的效率。
6 |
7 | **采用单线程**:单线程操作省去了上下文切换带来的开销和CPU的消耗,同时不存在资源竞争,避免了死锁现象的发生。
8 |
9 | **I/O多路复用**:采用I/O多路复用机制同时监听多个Socket,根据Socket上的事件来选择对应的事件处理器进行处理。
10 |
11 |
12 |
13 | ### 为什么Redis是单线程?
14 |
15 | 单线程指的是:网络请求模块使用单线程进行处理,其他模块仍用多个线程。
16 |
17 | 官方答案是:因为CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。
18 |
19 | ::: tip redis采用多线程的模块和原因
20 |
21 | Redis 在启动的时候,会启动后台线程(BIO):
22 |
23 | - Redis的早期版本会启动2个后台线程,来处理关闭文件、AOF 刷盘这两个任务;
24 | - Redis的后续版本,新增了一个新的后台线程,用来异步释放 Redis 内存。执行 unlink key / flushdb async / flushall async 等命令,会把这些删除操作交给后台线程来执行。
25 |
26 | 之所以 Redis 为关闭文件、AOF 刷盘、释放内存这些任务创建单独的线程来处理,是因为这些任务的操作都很耗时,把这些任务都放在主线程来处理会导致主线程阻塞,导致无法处理后续的请求。后台线程相当于一个消费者,生产者把耗时任务丢到任务队列中,消费者不停轮询这个队列,拿出任务去执行对应的方法即可。
27 |
28 | :::
29 |
30 |
31 |
32 | ### Redis为什么要引入多线程?
33 |
34 | 因为Redis的瓶颈不在内存,而是在网络I/O模块带来CPU的耗时,所以Redis6.0的多线程是用来处理网络I/O这部分,充分利用CPU资源,减少网络I/O阻塞带来的性能损耗。Redis引入的多线程 I/O 特性对性能提升至少是一倍以上。
35 |
36 |
37 |
38 | ### 为什么用Redis作为MySQL的缓存?
39 |
40 | MySQL是数据库系统,对于数据的操作需要访问磁盘,而将数据放在Redis中,需要访问就可以直接从内存获取,避免磁盘I/O,提高操作的速度。
41 |
42 | 使用Redis+MySQL结合的方式可以有效提高系统QPS。
43 |
44 |
45 |
46 | ### Redis和Memcached的联系和区别?
47 |
48 | **共同点**:
49 |
50 | - 都是内存数据库
51 | - 性能都非常高
52 | - 都有过期策略
53 |
54 | **区别**:
55 |
56 | - **线程模型**:Memcached采用多线程模型,并且基于I/O多路复用技术,主线程接收到请求后分发给子线程处理,这样做好的好处是:当某个请求处理比较耗时,不会影响到其他请求的处理。缺点是CPU的多线程切换存在性能损耗,同时,多线程在访问共享资源时要加锁,也会在一定程度上降低性能;Redis也采用I/O多路复用技术,但它处理请求采用是单线程模型,从接收请求到处理数据都在一个线程中完成。这意味着使用Redis一旦某个请求处理耗时比较长,那么整个Redis就会阻塞住,直到这个请求处理完成后返回,才能处理下一个请求,使用Redis时一定要避免复杂的耗时操作,单线程的好处是,少了CPU的上下文切换损耗,没有了多线程访问资源的锁竞争,但缺点是无法利用CPU多核的性能。
57 |
58 | - **数据结构**:Memcached支持的数据结构很单一,仅支持string类型的操作。并且对于value的大小限制必须在1MB以下,过期时间不能超过30天;而Redis支持的数据结构非常丰富,除了常用的数据类型string、list、hash、set、zset之外,还可以使用geo、hyperLogLog数据类型;使用Memcached时,我们只能把数据序列化后写入到Memcached中。然后再从Memcached中读取数据,再反序列化为我们需要的格式,只能“整存整取”;Redis提供的数据结构提升了操作的便利性。
59 |
60 | - **淘汰策略**:Memcached必须设置整个实例的内存上限,数据达到上限后触发LRU淘汰机制,优先淘汰不常用使用的数据。它的数据淘汰机制存在一些问题:刚写入的数据可能会被优先淘汰掉,这个问题主要是它本身内存管理设计机制导致的;Redis没有限制必须设置内存上限,如果内存足够使用,Redis可以使用足够大的内存,同时Redis提供了多种内存淘汰策略。
61 |
62 | - **持久化**:Memcached不支持数据的持久化,如果Memcached服务宕机,那么这个节点的数据将全部丢失。Redis支持AOF和RDB两种持久化方式。
63 |
64 | - **集群**:Memcached没有主从复制架构,只能单节点部署,如果节点宕机,那么该节点数据全部丢失,业务需要对这种情况做兼容处理,当某个节点不可用时,把数据写入到其他节点以降低对业务的影响;Redis拥有主从复制架构,主节点从可以实时同步主的数据,提高整个Redis服务的可用性。
65 |
66 |
67 |
68 |
69 |
70 | ### 如何理解Redis原子性操作原理?
71 |
72 | **API**:Redis提供的API都是单线程串行处理的。
73 |
74 | **网络模型**:采用单线程的epoll的网络模型,用来处理多个Socket请求。
75 |
76 | **请求处理**:Redis会fork子进程来出来类似于RDB和AOF的操作,不影响主进程工作。
77 |
--------------------------------------------------------------------------------
/src/.vuepress/theme.ts:
--------------------------------------------------------------------------------
1 | import { hopeTheme } from "vuepress-theme-hope";
2 | import { navBar } from "./navbar/navbar";
3 | import { sideBar } from "./sidebar/sidebar";
4 |
5 |
6 |
7 | export default hopeTheme({
8 |
9 | // 导航栏中Logo的链接,404页面的返回首页链接
10 | home: '/',
11 |
12 | // logo
13 | logo: "/logo.png",
14 |
15 | // 夜间模式logo
16 | logoDark:"/logodark.png",
17 |
18 | // 项目仓库
19 | repo: "https://github.com/zijing2333/CSView",
20 |
21 | // 项目仓库标签
22 | repoLabel: "GitHub仓库",
23 |
24 | // 编辑此页
25 | editLink: true,
26 |
27 | // 文档源文件的仓库 URL
28 | docsRepo:"https://github.com/zijing2333/CSView",
29 |
30 | // 文档源文件的仓库分支
31 | docsBranch: "main",
32 |
33 | // 文档源文件存放在仓库中的目录名
34 | docsDir: 'src',
35 |
36 | // lastUpdated
37 | lastUpdated: true,
38 |
39 | // 域名
40 | hostname: "https://www.csview.cn",
41 |
42 | // 作者信息
43 | author: {
44 | name: "zijing2333",
45 | email: "944741457@qq.com",
46 | },
47 |
48 | favicon: '/logo.png',
49 |
50 | // 图标
51 | iconAssets: "//at.alicdn.com/t/c/font_3888455_yh47d67uz7k.css",
52 |
53 | // 面包屑导航
54 | breadcrumb:false,
55 |
56 | // 侧边栏
57 | sidebar:sideBar,
58 |
59 | // 导航栏
60 | navbar:navBar,
61 |
62 | // 隐藏打印按钮
63 | print: false,
64 |
65 | // 插件
66 | plugins: {
67 |
68 | // 评论插件
69 | comment: {
70 | /**
71 | * Using Waline
72 | */
73 | provider: "Waline",
74 | serverURL: "https://comment-3nup9yoof-zijing2333.vercel.app",
75 | requiredMeta: ['nick', 'mail'],
76 | meta: ['nick', 'mail'],
77 | comment: true,
78 | },
79 |
80 | mdEnhance: {
81 | align: true,
82 | attrs: true,
83 | chart: true,
84 | codetabs: true,
85 | container: true,
86 | tasklist: true,
87 | demo: true,
88 | echarts: true,
89 | figure: true,
90 | flowchart: true,
91 | gfm: true,
92 | imgLazyload: true,
93 | imgSize: true,
94 | include: true,
95 | katex: true,
96 | mark: true,
97 | mermaid: true,
98 | playground: {
99 | presets: ["ts", "vue"],
100 | },
101 | presentation: {
102 | plugins: ["highlight", "math", "search", "notes", "zoom"],
103 | },
104 | stylize: [
105 | {
106 | matcher: "Recommended",
107 | replacer: ({ tag }) => {
108 | if (tag === "em")
109 | return {
110 | tag: "Badge",
111 | attrs: { type: "tip" },
112 | content: "Recommended",
113 | };
114 | },
115 | },
116 | ],
117 | sub: true,
118 | sup: true,
119 | tabs: true,
120 | vPre: true,
121 | vuePlayground: true,
122 | },
123 | }
124 | });
125 |
--------------------------------------------------------------------------------
/src/mysql/lock.md:
--------------------------------------------------------------------------------
1 | ### MySQL的全局锁有什么作用?
2 |
3 | **作用**:让整个数据库就处于只读状态了,增删改会被阻塞。
4 |
5 | **使用场景**:全局锁主要应用于做**全库逻辑备份**,不会因为数据或表结构的更新而出现备份文件的数据与预期的不一样。
6 |
7 | **缺陷**:数据库里有很多数据,备份会花费很多的时间。备份期间,业务只能读数据,而不能更新数据,这样会造成业务停滞。
8 |
9 | **改进**:可重复读的隔离级别,在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。即使其他事务更新了表的数据,也不会影响备份数据库时的 Read View,这样备份期间备份的数据一直是在开启事务时的数据。
10 |
11 |
12 |
13 | ### MySQL的表级锁有哪些?作用是什么?
14 |
15 | #### 元数据锁
16 |
17 | **作用**:对数据库表进行操作时,会自动给这个表加上元数据锁,为了保证当用户对表执行 CRUD 操作时,其他线程对这个表结构做了变更。元数据锁在事务提交后才会释放。
18 |
19 | #### 意向锁
20 |
21 | **作用**:对某些记录加上「共享锁」之前,需要先在表级别加上一个「意向共享锁」,对某些纪录加上「独占锁」之前,需要先在表级别加上一个「意向独占锁」。普通的 select 是不会加行级锁的,普通的 select 语句是利用 MVCC 实现一致性读,是无锁的。
22 |
23 | 意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发生冲突,意向锁之间也不会发生冲突,只会和共享表锁和独占表锁发生冲突。意向锁的目的是为了快速判断表里是否有记录被加锁。
24 |
25 | ::: tip 提示
26 |
27 | select也是可以对记录加共享锁和独占锁的。
28 |
29 | :::
30 |
31 | #### AUTO-INC锁
32 |
33 | **作用**:表里的主键通常都会设置成自增的,之后可以在插入数据时,可以不指定主键的值,数据库会自动给主键赋值递增的值通过 **AUTO-INC 锁**实现的。**在插入数据时,会加一个表级别的 AUTO-INC 锁**,然后为被 AUTO_INCREMENT 修饰的字段赋值递增的值,等插入语句执行完成后,才会把 AUTO-INC 锁释放掉。其他事务的如果要向该表插入语句都会被阻塞,从而保证插入数据时字段的值是连续递增的。
34 |
35 | **缺陷**:对大量数据进行插入的时候,会影响插入性能,因为其他事务中的插入会被阻塞。
36 |
37 | **改进**:InnoDB 存储引擎提供了一种**轻量级的锁**来实现自增。在插入数据的时候,会为被 AUTO_INCREMENT 修饰的字段加上轻量级锁,**然后给该字段赋值一个自增的值,就把这个轻量级锁释放了,而不需要等待整个插入语句执行完后才释放锁**。
38 |
39 | ::: tip AUTO-INC锁控制
40 |
41 | 设置innodb_autoinc_lock_mode的系统变量,是用来控制选择用 AUTO-INC 锁。:
42 |
43 | - 当 innodb_autoinc_lock_mode = 0,采用 AUTO-INC 锁,语句执行结束后才释放锁;
44 | - 当 innodb_autoinc_lock_mode = 2,采用轻量级锁,申请自增主键后就释放锁,并不需要等语句执行后才释放。
45 | - 当 innodb_autoinc_lock_mode = 1:
46 | - 普通 insert 语句,自增锁在申请之后就马上释放;
47 | - 类似 insert … select 这样的批量插入数据的语句,自增锁要等语句结束后才被释放;
48 |
49 | 当 innodb_autoinc_lock_mode = 2 是性能最高的方式,但是当搭配 binlog 的日志格式是 statement 一起使用的时候,在主从复制的场景中会发生**数据不一致的问题**。
50 |
51 | binlog 日志格式要设置为 row,这样在 binlog 里面记录的是主库分配的自增值,到备库执行的时候,主库的自增值是什么,从库的自增值就是什么。
52 |
53 | 所以,**当 innodb_autoinc_lock_mode = 2 时,并且 binlog_format = row,既能提升并发性,又不会出现数据一致性问题**。
54 |
55 | :::
56 |
57 | ### MySQL的行级锁有哪些?作用是什么?
58 |
59 | #### 记录锁
60 |
61 | **作用**:锁住的是一条记录,记录锁分为排他锁和共享锁。
62 |
63 | #### 间隙锁
64 |
65 | **作用**:只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。**间隙锁之间是兼容的,两个事务可以同时持有包含共同间隙范围的间隙锁,并不存在互斥关系**。
66 |
67 | **Next-Key Lock**:Next-Key Lock临键锁,是 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。next-key lock 即能保护该记录,又能阻止其他事务将新纪录插入到被保护记录前面的间隙中。
68 |
69 | **插入意向锁**:一个事务在插入一条记录的时候,需要判断插入位置是否已被其他事务加了间隙锁(next-key lock 也包含间隙锁)。如果有的话,插入操作就会发生**阻塞**,直到拥有间隙锁的那个事务提交为止,在此期间会生成一个**插入意向锁**,表明有事务想在某个区间插入新记录,但是现在处于等待状态。
70 |
71 |
72 |
73 | ### MySQL怎么加锁的?
74 |
75 | 当查询的记录是存在的,在用「唯一索引进行等值查询」时,next-key lock 会退化成「记录锁」。
76 |
77 | 当查询的记录是不存在的,在用「唯一索引进行等值查询」时,next-key lock 会退化成「间隙锁」。
78 |
79 | 当查询的记录存在时,用非唯一索引进行等值查询除了会加 next-key lock 外,还额外加间隙锁。
80 |
81 | 当查询的记录不存在时,用非唯一索引进行等值查询只会加 next-key lock,然后会退化为间隙锁。
82 |
83 | 非唯一索引范围查,next-key lock 不会退化为间隙锁和记录锁。
--------------------------------------------------------------------------------
/src/start-learning/interview.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar: heading
3 | ---
4 |
5 | (**注意:本站一切分享类文章都是作者观点,难免偏颇失误,请谅解。**)
6 |
7 | ## :one:重新看待面试
8 |
9 | **面试的本质是帮助企业筛选出他们想要的人**。企业招进来一个人的成本不低,包括:
10 |
11 | - 面试时间成本:员工要花工作时间[^1]给你面试
12 | - 培训资源成本:入职之后要对你培训,越好的企业培训机制越完善
13 |
14 | 企业只能通过面试的两到三个小时、最多不超过五个小时[^2]的时间来了解你,想了解你的内容包括但不限于:
15 |
16 | - **学历**:对于校园招聘,学历是第一硬性指标。互联网面试学历不是唯一指标,有些学历平平但是技术良好的同学也可以拿到很多offer。高学历的学生简历通过率更高,公司会给更多的面试机会,**但无论如何是否获得offer仍取决于面试表现**。参加过去年招聘的都知道:22年整体就业形势不好,**互联网公司也越来越看重校招生的学历了**。注意:如果你想去的企业[^3]对学历有要求,请去深造,因为这不能靠技术弥补。
17 | - **实习经历/项目经历**:有项目经历或者实习经历证明你更适应工作要求,且实践能力更强。一般价值是[**好的项目经历≈互联网公司实习经历>你给实验室打工的实习经历>水的项目经历**]。
18 | - **奖项/论文**:硬实力的象征,强求不来。
19 | - **技术**:会的越多、会的越贴近公司技术的要求,通过面试的概率越高,技术栈符合招聘要求真的有加成。
20 | - **沟通能力**:有的人平时表现很好,但是面试时候紧张,会的东西发挥不出来,就很影响面试。我认识一个同学(还是专业前几名的巨佬)在面字节的时候紧张的一句话都说不出,导致没能通过面试。
21 | - **英语水平**:最好通过四级,个别企业要求六级[^4]。
22 | - ……
23 |
24 | ::: tip 为什么基础很重要
25 |
26 | 面试官不可能问你他自己也不会的知识,因为不了解的他就算问你,你答的再多也没用[^5],他不知对错没法对你评价,而他也很有可能是从前八股文时代过来的。在未来可预见的很长一段时间,校招面试围绕八股文展开依旧是主流形式,所以请好好准备。
27 |
28 | :::
29 |
30 | ## :two:面试流程
31 |
32 | ### 自我介绍
33 |
34 | 这个环节除了告知你的基本个人信息,还要**尽可能展示你的亮点**:学校好的说学校、技术好的说技术、有实习的说实习、做过项目就说项目……自己准备的时候可以写一份个人介绍,背下来面试时候用,不容易紧张。
35 |
36 | ### 实习经历/项目经历
37 |
38 | 这部分很重要,侧面了解你的动手实践能力和技术运用能力。通常会问你:做过什么内容?细节是怎么实现的?做的东西技术上优缺点?怎么改进?还会根据你的项目延伸问一些八股文[^6]。这部分你准备的越好、和面试官之间探讨越多,八股文问的就越少。
39 |
40 | ### 八股文
41 |
42 | 多看多背多了解,基础八股文**多次**答不上来是很致命的。
43 |
44 | ### 算法
45 |
46 | 算法或许可以称为整个面试过程最重要的内容,如果你没做出来并且连思路都没有,**基本宣告着面试的失败**。
47 |
48 | 算法准备策略是按照**题频次高低刷**,这是性价比最高且最稳的一种做法,**为了通过面试优先刷本站总结的100多题**,再补充其他算法。
49 |
50 | 此外,就我和同学遇到的面试题,90%都是高频常规题型。万一某次遇到一个非常规中等题或者简单题,你有几百道题的积累做不出来也能说个思路,如果遇到非常规的困难题,那就自认倒霉吧,**因为面试也需要运气**,只能说你与这家企业无缘。
51 |
52 | ::: warning 小贴士
53 |
54 | **如果高频100多道题你都不会做就去面试,挂多少次都属于自己活该**:expressionless:。
55 |
56 | :::
57 |
58 | ### 一些情景设计题或者智力题
59 |
60 | 这个主管面会问的多一些。考察你的综合能力和思维发散力,通常比较难,能引申的东西很多,没有定数,比如他可能随时就想到一个题来问你。不过也有一些常常出现的题目,可以适当总结准备一下,拓展一下这方面问题的回答模板,网站也放了一些案例给大家学习。
61 |
62 | ## :three:面试准备
63 |
64 | ::: danger 提示
65 |
66 | 实习/提前批的面试表现和正式批是有关系的,想去的公司实习时候不准备好别乱投!!!
67 |
68 | 实习/提前批的面试表现和正式批是有关系的,想去的公司实习时候不准备好别乱投!!!
69 |
70 | 实习/提前批的面试表现和正式批是有关系的,想去的公司实习时候不准备好别乱投!!!
71 |
72 | :::
73 |
74 | ### 充分准备,再投递
75 |
76 | 你是否听过面试要海投只管投就完事了?根据22年的经验来说,我劝你不要这么做。因为**面试评价**都是有长期记录的,如果你准备的一般就去面试,表现特别不好,那么后续就算捞你了你过得概率也不大,而且这个还会影响正式批的定薪。我朋友就是,他提前批投了抖音表现很差,正式秋招连简历筛选都过不了。
77 |
78 | 那么应该怎么做呢?
79 |
80 | 游戏里有个概念叫做垫刀,我想你也大概知道是什么意思。有两种方法:你可以先拿自己不想去的公司面试;或者是找一篇网上的面经让好朋友给你模拟面试。
81 |
82 | ### 每天清晨自查
83 |
84 | 不妨对着镜子,说一说面试的内容,心理学表明人在照镜子的时候会增加自己的自信度;不想背的话,就对着八股文一遍一遍的读,遛一遛嘴熟,面试才不生。选择清晨是因为你在这个时候思路最清晰。以上是锻炼表达能力和克服紧张情绪非常有效的方法。
85 |
86 | ### 容许失败,及时复盘
87 |
88 | 刚开始投失败几次都很正常,然后详实记录面试的内容,进行复盘,复盘包括:你投递的岗位和你的知识储备符合吗?你的简历写的有没有问题?你自己的知识储备足够吗?以及其他内容。
89 |
90 | 以上就是我自己的一些看法,欢迎在评论区里面讨论。
91 |
92 |
93 |
94 | [^1]: 通常可能占用一线研发人员写代码的时间或者主管更重要的项目整合时间。
95 | [^2]: 见过一个岗位五场校招面试的,我把这种称为地狱模式。
96 | [^3]: 通常国企、银行和研究所,还比如华为,对学历都有要求。
97 | [^4]: 如一汽大众研发岗有六级要求。
98 | [^5]: 我遇到一个Java的面试官问我go的东西,我给他讲了很多但是他都听不懂,所以意义不大。
99 | [^6]: 例如,你项目用了数据库,他就会问你数据库索引怎么使用之类的,所以问索引的概率真的很高。
--------------------------------------------------------------------------------
/src/golang/summary.md:
--------------------------------------------------------------------------------
1 | ### 进程、线程、协程的区别?
2 |
3 | **进程**:进程是每一次程序动态执行的过程,是程序运行的基本单位。进程占据独立的内存,有内存地址,有自己的堆,上级挂靠操作系统,操作系统以进程为单位分配资源(如CPU时间片、内存等),进程是资源分配的最小单位。
4 |
5 | **线程**:线程又叫做轻量级进程,是CPU调度的最小单元。线程从属于进程,是程序的实际执行者,一个进程至少包含一个主线程,也可以有多个子线程。线程会共享所属进程的资源,同时线程也有自己的独占资源。线程切换和线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
6 |
7 | **协程**:协程是一种用户态的轻量级线程,协程的调度完全由用户控制。一个线程可以有多个协程,协程不是被操作系统内核所管理,而是由程序所控制。
8 |
9 | **区别**
10 |
11 | - **拥有资源**:进程是拥有资源的最小单位,线程不拥有资源,但是可以访问隶属进程的资源。进程所维护的是程序所包含的资源静态资源), 如:**地址空间,打开的文件句柄集,文件系统状态,信号处理handler等**;线程所维护的运行相关的资源(动态资源),如:**运行栈,调度相关的控制信息,待处理的信号集等**。
12 | - **并发性**:不仅进程可以并发执行,同一进程的多个线程也可以并发执行。
13 |
14 | - **系统开销**:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以**多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些**。
15 | - **协程和线程**:协程避免了无意义的调度,由此可以提高性能,但是用户调度过程中可能存在风险。
16 |
17 |
18 |
19 | ### goroutine相比线程的优势?
20 |
21 | 协程拥有极高的执行效率,子程序切换不是线程切换而是由程序自身控制,所以没有线程切换的开销。和多线程比,线程的数量越多,协程的性能优势就越明显。
22 |
23 | 协程不需要多线程的锁机制,因为只有一个线程,所以不存在同时写变量的冲突。在协程中控制共享资源不加锁,只需要判断状态就可以,执行效率比多线程要高。
24 |
25 |
26 |
27 | ### go与Java的区别?
28 |
29 | **运行**:go是静态编译语言;Java基于类的面向对象语言,Java应用程序在JVM上运行。
30 |
31 | **函数重载**:go上不允许函数重载,必须具有方法和函数的唯一名称;java允许函数重载。
32 |
33 | **多态**:Java默认允许多态,而go没有。
34 |
35 | **路由配置**:go语言使用HTTP协议进行路由配置;java使用Akka.routing进行路由配置。
36 |
37 | **继承**:go的继承通过匿名组合完成,基类以Struct的方式定义,子类只需要把基类作为成员放在子类的定义中,支持多继承;Java的继承通过extends关键字完成,不支持多继承。
38 |
39 |
40 |
41 | ### go语言中是如何实现继承的?
42 |
43 | 在go中没有extends关键字,所以go并没有原生级别的继承支持。本质上,Go使用组合来代替继承:
44 |
45 | ```go
46 | type Person struct {
47 | Name string
48 | Age int
49 | }
50 |
51 | type Student struct {
52 | Person
53 | School string
54 | }
55 | ```
56 |
57 |
58 |
59 | ### for遍历多次执行goroutine会存在什么问题?
60 |
61 | **在协程中打印for的下标i或当前下标的元素**
62 |
63 | 会随机打印载体中的元素。
64 |
65 | golang值拷贝传递,for循环很快就执行完了,但是创建的10个协程需要做初始化:上下文准备,堆栈,和内核态的线程映射关系的工作,是需要时间的,比for慢,等都准备好了的时候,会同时访问i。这个时候的i肯定是for执行完成后的下标(也可能有个别的协程已经准备好了,取i的时候,正好是5,或者7,就输出了这些数字)。
66 |
67 | 解决的方法就是闭包,给匿名函数增加入参,因为是值传递,所以每次for创建一个协程的时候,会拷贝一份i传到这个协程里面去,或者在开启协程之前声明一个新的变量 = i。
68 |
69 | **for并发读取文件**
70 |
71 | 程序会panic:too many open files
72 |
73 | 解决的方法:通过带缓冲的channel和sync.waitgroup控制协程并发量。
74 |
75 |
76 |
77 | ### init函数是什么时候执行的?
78 |
79 | **特点**:
80 |
81 | - init函数先于main函数自动执行,不能被其他函数调用。
82 | - init函数没有输入参数、返回值。
83 | - 每个包可以有多个init函数,包的每个源文件也可以有多个init函数。
84 | - go没有明确定义同一个包的init执行顺序,编程时程序不能依赖这个执行顺序。
85 | - 不同包的init函数按照包导入的依赖关系决定执行顺序。
86 |
87 | **作用**:
88 |
89 | - 初始化不能采用初始化表达式初始化的变量。
90 | - 程序运行前的注册。
91 | - 实现sync.Once功能。
92 |
93 | **执行顺序**:
94 |
95 | go程序初始化先于main函数执行,由runtime进行初始化,初始化顺序如下:
96 |
97 | - 初始化导入的包,包的初始化顺序并不是按导入顺序执行的,runtime需要解析包依赖关系,没有依赖的包最先初始化
98 | - 初始化包作用域的变量,runtime解析变量依赖关系,没有依赖的变量最先初始化
99 | - 执行包的init函数
100 |
101 | **最终初始化顺序:变量初始化 -> init() -> main()**
102 |
103 |
--------------------------------------------------------------------------------
/src/design/bigdata.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ### 海量日志数据,提取出某日访问百度次数最多的那个IP?
4 |
5 | 首先是找到这一天的日志,并且是访问百度的IP从日志中提取出来逐个写入大文件中,如果IP是32位的,最多可能有2^32次方种结果。
6 |
7 | 采用映射的方法,比如%1000,把大文件依次映射成1000个小文件,找出每个小文件中出现频率最多的IP,可以使用hashMap统计频率,依次找出每个文件中出现频率最大IP,一共1000个。然后在1000个IP中找出频率最大即为所求,可以使用归并或者小顶堆。
8 |
9 |
10 |
11 | ### 寻找热门查询中,1000万个查询字符串中最热门的10个查询?要求内存使用不超过1G,每个查询串长度都是1~255字节?
12 |
13 | 1000万个字符串肯定会有重复,假设不重复字段大约300万,3M * 1K/4 = 0.75G,可以在内存中全部装下,因此采用hashTable,key位字符串,value位为出现的次数,每次读取一个串,如果串在hashTable中就将统计频率加1,否则将value置为1。然后维护一个堆,保存10个元素,找出TopK,遍历300个串的value分别与根元素进行比较,最终时间复杂度为O(N)+M*O(logK),N为1000万,M为300万,K为堆大小10。
14 |
15 |
16 |
17 | ### 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词?
18 |
19 | 顺序读取文件,对于每个词采用hash%5000,映射到(x0,x1,……,x4999),每个文件大约200KB,如果有文件大小超过1K就继续分治,直到所有文件大小都小于1M。对于每个小文件采用hashMap或者前缀树统计相应的词和频率。取出现频率最大的100个词,存入文件可以得到5000个文件,最后把5000个文件进行归并排序。
20 |
21 |
22 |
23 | ### 海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10?
24 |
25 | 如果每个元素只出现一次并且出现在某一台机器上,可以在每台电脑上求TOP10,采用最大堆,然后求出每个电脑的TOP10之后将100个电脑的TOP组合起来得到1000条数据,再用大顶堆划分出TOP10。
26 |
27 | 如果同一元素重复出现在不同电脑中,可以遍历一遍所数据后hash取模,使同一元素只出现在一台电脑上。统计每个元素的TOP10,找出最后的TOP10。
28 |
29 | 或者直接暴力统计每个电脑各个元素出现的次数,把同一元素在不同电脑上次数相加,找出最终数据的TOP10。
30 |
31 |
32 |
33 | ### 有10个文件,每个文件1G,每个文件的每一行存放的都是用户的查询,每个文件的查询都可能重复。要求你按照查询的频度排序?
34 |
35 | 顺序读取10个文件,按照hash(query)%10的结果写入10个文件中,生成的新文件大小也是1G。找一个内存是2G的机器,依次对用hashMap(query, query_count)来统计每个query出现的次数。然后将排序好的query和count存储到文件中,得到10个已经排序的文件,最后对10个文件进行归并排序。
36 |
37 |
38 |
39 | ### 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
40 |
41 | 50亿个URL每个URL是64字节,一共占用320亿字节,内存4G装不下,所以采用分治的思想。先遍历a文件,对于每个hash(URL)%1000,分别将1000个URL存储到1000个小文件里面,记为a1、a2、……、a1000,每个文件大约就是300M,遍历文件b采取同样的方法。因为使用的是相同的哈希算法,所以相同的URL在对应文件对里面,这样就会有1000对小文件。不对应的小文件不可能有相同的URL。
42 |
43 | 然后对每对URL,先把一个文件的URL存储到hashSet中,遍历另一个小文件的每个URL,看是否在hashSet,如果有相同的URL存储到文件就行。
44 |
45 | 如果允许一定错误率,可以使用布隆过滤器,4亿内存可以保存340亿bit。用一个布隆过滤器映射340亿bit,然后读取另一个文件的URL,检查是否在布隆过滤器里面,快速判断URL是否存在。
46 |
47 |
48 |
49 | ### 在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数?
50 |
51 | **方案1**:采用2比特位的位图,每个数分配2位,00表示这个数不存在,01表示出现一次,10表示出现多次,11无意义,共需要内存2^32*2 = 1G内存,扫描2.5亿个整数判断位图中是否存在,并调换对应的位,查看所有的01位并进行输出即可。
52 |
53 | **方案2**:先把2.5亿个小文件进行划分,在小文件中找到不重复整数,并且排序,然后再归并。
54 |
55 |
56 |
57 | ### 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
58 |
59 | 采用位图,申请512M内存,一位代表一个unsigned int,然后读入40亿数字,设置相应的bit位。读出要查询的数并且判段bit是否为1。
60 |
61 |
62 |
63 | ### 100w个数中找出最大的100个数?
64 |
65 | **局部淘汰法**:选取前100个元素,并排。依次扫描剩余元素,与排好序的最小的元素比,如果比这个最小的大,那么把这个最小的元素删除,并利用插入排序的思想,把新元素插入到序列中。依次循环,直到扫描了所有的元素。复杂度为O(100w\*100)。
66 | **快排**:采用快速排序的思想,每次分割之后只考虑比轴大的一部分,知道比轴大的一部分在比100多的时候,采用传统排序算法排序,取前100个。复杂度为O(100w\*100)。
67 | **最小堆**:用一个含100个元素的最小堆完成。复杂度为O(100w*lg100)。
68 |
69 | **双层桶划分**:整数个数一共2\^32个,划分为2\^8个区域,一个单一的文件可以代表一个区域。将数据离散到不同区域,在不同的区域利用bitmap进行统计,只要磁盘空间足够即可。
70 |
71 |
72 |
73 | ### 5亿个int找到它的中位数?
74 |
75 | **bitmap**:可以把int划分为2\^16个区域,然后读取数据落在各个区域的个数,在统计结构中判断中位数落在哪个位置,同时对这个区域操作,知道第几大的是中位数。数据量过大可以进行两次划分,先将int64放入2\^24个区域内,确定是第几区域大的数,将该区域划分为2^20个子区域,确定是子区域第几大的数字,直接进行统计。
76 |
77 | **快排**:内存足够的情况可以使⽤用类似quick sort的思想进行,均摊复杂度为O(n):随机选取一个元素,将比它小的元素放在它左边,比它大的元素放在右边;如果它恰好在中位数的位置,那么它就是中位数,可以直接返回;如果小于它的数超过一半,那么中位数一定在左半边,递归到左边处理;否则中位数一定在右半边,根据左半边的元素个数计算出中位数是右半边的第几大,然后递归到右半边处理。
78 |
79 |
--------------------------------------------------------------------------------
/src/development-log/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageInfo: false
3 | editLink: false
4 | title: 开发日志
5 | comment: false
6 | sidebar: heading
7 | ---
8 |
9 |
10 |
11 | ## 2023年4月11日
12 |
13 | - 题频界面更新两篇面经
14 | - 重写3道设计题(未推送)
15 | - 新增3道智力题(未推送)
16 |
17 | ## 2023年4月10日
18 |
19 | - 操作系统界面重构完成
20 |
21 | ## 2023年4月8日
22 |
23 | - 题频界面更新两篇面经
24 | - 算法界面更新6道题(未推送)
25 | - 操作系统更新7道题(未推送)
26 |
27 | ## 2023年4月7日
28 |
29 | - 题频界面更新两篇面经
30 | - 算法界面更新8道字符串的题(未推送)
31 | - 操作系统更新10道题(未推送)
32 |
33 | ## 2023年4月5日
34 |
35 | - 题频界面更新两篇面经
36 | - 算法界面更新10道树的题(未推送)
37 | - 操作系统更新10道题(未推送)
38 |
39 | ## 2023年4月3日
40 |
41 | - 更新归并排序、桶排序、快速排序思路和示例代码
42 |
43 | ## 2023年4月2日
44 |
45 | - C++更新150余道题目
46 | - 链表更新20余道题目,树更新10道题目
47 |
48 | ## 2023年3月16日
49 |
50 | - 题频界面更新四篇面经
51 | - 引入Spring界面
52 | - 算法界面加入SEO优化
53 |
54 | ## 2023年2月26日
55 |
56 | - 算法界面修改3处错误
57 | - 引入C++界面
58 | - 操作系统界面更新10道题目
59 | - 设计题界面修复若干错误
60 |
61 | ## 2023年2月25日
62 |
63 | - 题频界面引入三篇面经内容
64 | - 算法更新20道Java题解
65 |
66 | ## 2023年2月24日
67 |
68 | - 完成公众号介绍文章和打赏界面文章
69 | - 题频界面引入四篇面经内容
70 | - Java界面图片导入
71 |
72 | ## 2023年2月23日
73 |
74 | - 定义[首页]六大模块
75 | - 主页引入公众号图片
76 | - 打赏页引入图片
77 | - 重新构建指南页面
78 | - 定义题频页面
79 |
80 | ## 2023年2月22日
81 |
82 | - github上传源代码,开源项目
83 | - golang更新面试题
84 | - 主页布局重新更新,导航栏和侧边栏重新定义
85 | - 域名审核通过,使用新域名 csview.cn
86 | - 解决vue编译过程中内存溢出问题
87 | - 算法更新Java题解35道
88 |
89 | ## 2023年2月21日
90 |
91 | - 算法更新33道Java题解
92 | - golang更新部分习题
93 | - 主题组件升级,配置search插件
94 |
95 |
96 |
97 | ## 2023年2月20日
98 |
99 | - Java界面基础知识分享
100 | - 算法更新20道Java题解
101 | - [学习路线]文章完成50%
102 |
103 |
104 |
105 | ## 2023年2月19日
106 |
107 | - Java语言知识重新分类
108 | - [学习路线]文章完成30%
109 | - 修复设计题部分错误
110 |
111 |
112 |
113 | ## 2023年2月18日
114 |
115 | - 修复页面跳转索引无效bug
116 | - golang页面新增8题
117 | - 操作系统页面整理重新分类
118 | - 算法题重新筛选
119 | - MySQL更新1题
120 | - 设计题重新分类
121 | - 尝试引入侧边栏图片
122 |
123 |
124 |
125 | ## 2023年2月17日
126 |
127 | - 为页面分别配置评论和文章信息内容
128 | - 计算机网络、数据库、操作系统、golang修改更新30余道题目
129 | - RabbitMQ页面更新和配置
130 | - HR常见面试题页面引入
131 | - K8s页面修改
132 | - 智力题、设计题审核更新
133 | - 逐步为内容增加参考来源
134 |
135 |
136 |
137 | ## 2023年2月16日
138 |
139 | - 配置Waline并开启评论功能
140 | - [面试内容]文章更新
141 | - 清除所有无效页面链接
142 | - 算法题目整理
143 | - 智力题、设计题、RabbitMQ页面引入内容
144 |
145 |
146 |
147 | ## 2023年2月15日
148 |
149 | - 完成Redis内容页面更新
150 | - 所有页面信息和标注优化:非内容页面去除编辑和作者信息按钮
151 | - 每个模块题目数据统计
152 | - 计算机网络、golang、MySQL增加问题重要程度标注
153 | - csview域名提交腾讯云审核
154 |
155 |
156 |
157 | ## 2023年2月14日
158 |
159 | - 完成**项目介绍**页面
160 | - 所有页面内容按照章节分割
161 | - 重现构建导航栏和索引
162 |
163 |
164 |
165 | ## 2023年2月13日
166 |
167 | - 再次尝试docSearch插件配置(**失败**)
168 | - 页面引入badge,标识问题重要程度
169 | - Redis页面内容更新,进度完成50%
170 | - **项目介绍**更新,进度完成30%
171 | - 算法题目更新
172 |
173 |
174 |
175 | ## 2023年2月12日
176 |
177 | - 重新命名网站为CSView
178 | - 申请域名csview.cn(等待审核更新)
179 | - 页面重新定义布局规则:分类设为二级标题,问题设为三级标题,尽量减少四级小标题使用
180 | - 计算机网络、数据库、golang问题回答优化
181 |
182 |
183 |
184 | ## 2023年2月11日
185 |
186 | - 算法页面引入代码切换容器
187 | - 计算机网络、数据库、golang页面优化:增加问题和优化回答
188 | - 算法页面修改样式
189 | - 导航栏引入全局搜索插件,使用search-Pro
190 | - 使用algolia网站配置docSearch爬虫,构建全文搜索功能(**失败**)
191 | - [开始学习]侧边栏引入
192 | - 更新白天和夜间的代码块样式
193 |
194 | ## 2023年2月10日
195 |
196 | - 项目提交github并部署托管到vercel
197 | - 使用vercel解析关联域名csguide.xyz
198 | - 网站页面取消面包屑导航
199 | - 算法页面样式重新设计布局
200 | - 修复c++代码块不显示样式问题
201 | - 白天夜间网站采用不同logo
202 | - 计算机网络界面内容修改完善
203 | - 网站全文搜索docSearch申请
204 |
205 | ## 2023年2月9日
206 |
207 | - csguide.xyz域名审核通过
208 | - SSL证书申请
209 | - 使用vuepress-theme-hope重新初始化网站
210 | - 网站基本结构设计
211 | - 完成顶部导航栏和侧边栏配置
212 | - 导航栏引入图标
213 | - golang、数据库、计算机网络页面内容更新
214 | - 夜间模式网页首页logo适配
215 | - 搜索插件和网页浏览次数插件引入
216 | - 首页[开始学习]按钮配置
217 | - 容器使用引入
--------------------------------------------------------------------------------
/src/mysql/transaction.md:
--------------------------------------------------------------------------------
1 | ### MySQL之事务的四大特性(ACID)?
2 |
3 | **原子性(atomicity)**:一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。
4 |
5 | **一致性(consistency)**:数据库总是从一个一致性的状态转换到另一个一致性的状态。
6 |
7 | **隔离性(isolation)**:一个事务所做的修改在最终提交以前,对其他事务是不可见的。
8 |
9 | **持久性(durability)**:一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。
10 |
11 | ::: tip 实现
12 |
13 | - 持久性:通过 redo log来保证的
14 | - 原子性:通过 undo log来保证的
15 | - 隔离性:通过 MVCC 或锁机制来保证的
16 | - 一致性:通过持久性+原子性+隔离性来保证
17 |
18 | :::
19 |
20 |
21 |
22 | ### 并发事务会出现什么问题?
23 |
24 | **脏读**:脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。
25 |
26 | **不可重复读**:对比可重复读,不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新操作。
27 |
28 | **幻读**:幻读是针对数据插入操作来说的。假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,让用户感觉感觉出现了幻觉,这就叫幻读。
29 |
30 | **可重复读**:可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。
31 |
32 |
33 |
34 | ### MySQL的事务隔离级别?
35 |
36 | **读未提交(read uncommitted)**:指一个事务还没提交时,它做的变更就能被其他事务看到。
37 |
38 | **读提交(read committed)**:指一个事务提交之后,它做的变更才能被其他事务看到。
39 |
40 | **可重复读(repeatable read)**:指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,**MySQL InnoDB 引擎的默认隔离级别**。
41 |
42 | **串行化(serializable )**:会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
43 |
44 |
45 |
46 | ### 在不同事务隔离级别下会发生什么现象?
47 |
48 | **读未提交**:可能发生脏读、不可重复读和幻读现象;
49 |
50 | **读提交**:可能发生不可重复读和幻读现象,但是不可能发生脏读现象;
51 |
52 | **可重复读**:可能发生幻读现象,但是不可能脏读和不可重复读现象;
53 |
54 | **串行化**:隔离级别下,脏读、不可重复读和幻读现象都不可能会发生。
55 |
56 | ::: tip 提示
57 |
58 | **解决脏读现象**:升级到读提交以上的隔离级别
59 |
60 | **解决不可重复读**:升级到可重复读的隔离级别
61 |
62 | **解决幻读**:不建议将隔离级别升级到串行化,因为这样会导致数据库在并发事务时性能很差。
63 |
64 | :::
65 |
66 |
67 |
68 | ### MVVC实现原理?
69 |
70 | 
71 |
72 | Read View 有四个重要的字段:
73 |
74 | - m_ids :指的是在创建 Read View 时,当前数据库中活跃事务的事务 id 列表,活跃事务指的就是,启动了但还没提交的事务。
75 | - min_trx_id :指的是在创建 Read View 时,当前数据库中活跃事务中事务 id 最小的事务,也就是 m_ids 的最小值。
76 | - max_trx_id :创建 Read View 时当前数据库中应该给下一个事务的 id 值,也就是全局事务中最大的事务 id 值 + 1。
77 | - creator_trx_id :指的是创建该 Read View 的事务的事务 id。
78 |
79 | 对于使用 InnoDB 存储引擎的数据库表,它的聚簇索引记录中都包含下面两个隐藏列:
80 |
81 | - trx_id,当一个事务对某条聚簇索引记录进行改动时,就会**把该事务的事务 id 记录在 trx_id 隐藏列里**。
82 | - roll_pointer,每次对某条聚簇索引记录进行改动时,都会把旧版本的记录写入到 undo 日志中,然后**这个隐藏列是个指针,指向每一个旧版本记录**,于是就可以通过它找到修改前的记录。
83 |
84 | 一个事务去访问记录的时候,除了自己的更新记录总是可见之外,还有这几种情况:
85 |
86 | - 如果记录的 trx_id 值小于 Read View 中的 min_trx_id 值,表示这个版本的记录是在创建 Read View **前**已经提交的事务生成的,所以该版本的记录对当前事务**可见**。
87 | - 如果记录的 trx_id 值大于等于 Read View 中的 max_trx_id 值,表示这个版本的记录是在创建 Read View **后**才启动的事务生成的,所以该版本的记录对当前事务**不可见**。
88 | - 如果记录的 trx_id 值在 Read View 的min_trx_id和max_trx_id之间,需要判断 trx_id 是否在 m_ids 列表中:
89 | - 如果记录的 trx_id **在** m_ids 列表中,表示生成该版本记录的活跃事务依然活跃着(还没提交事务),所以该版本的记录对当前事务**不可见**。
90 | - 如果记录的 trx_id **不在** m_ids 列表中,表示生成该版本记录的活跃事务已经被提交,所以该版本的记录对当前事务**可见**。
91 |
92 |
93 |
94 | ### 幻读是如何解决的?
95 |
96 | **快照读**(普通 select 语句):是**通过 MVCC 方式解决了幻读**,可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,查询不出来这条数据的。
97 |
98 | **当前读**(select ... for update 等语句):是**通过 next-key lock(记录锁+间隙锁)方式解决了幻读**,因为当执行 select ... for update 语句的时候会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入。
99 |
100 | ::: tip 失效
101 |
102 | - 对于快照读, MVCC 并不能完全避免幻读现象。当事务 A 更新了一条事务 B 插入的记录,那么事务 A 前后两次查询的记录条目就不一样了,所以就发生幻读。
103 | - 对于当前读,如果事务开启后,并没有执行当前读,而是先快照读,然后这期间如果其他事务插入了一条记录,那么事务后续使用当前读进行查询的时候,就会发现两次查询的记录条目就不一样了,所以就发生幻读。
104 |
105 | 即**MySQL 可重复读隔离级别并没有彻底解决幻读,只是很大程度上避免了幻读现象的发生。**
106 |
107 | **尽量在开启事务之后,马上执行 select ... for update 这类当前读的语句**,因为它会对记录加 next-key lock,从而避免其他事务插入一条新记录。
108 |
109 | :::
110 |
111 |
112 |
113 |
114 | ### 读提交怎么实现的?
115 |
116 | 读提交隔离级别是在每次读取数据时,都会生成一个新的 Read View。事务期间的多次读取同一条数据,前后两次读的数据可能会出现不一致,因为可能这期间另外一个事务修改了该记录,并提交了事务。
--------------------------------------------------------------------------------
/src/article/02.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | pageInfo: false
4 | editLink: false
5 |
6 | ---
7 |
8 |
9 |
10 | 校招和实习,编程语言该怎么选择?
11 |
12 |
13 |
14 | 0️⃣ 前言
15 |
16 | 最近很多同学在准备面试,问的比较多的一个问题:
17 |
18 | | “自己一直跟着学校课程按部就班地学习,各类编程语言都学的半斤八两,找工作或者准备实习的时候,选什么作为主语言好一点?”
19 | |
20 |
21 |
22 | 针对这个问题我谈一下看法。
23 |
24 |
25 |
26 | 1️⃣ 编程语言是不重要的
27 |
28 |
29 | 先说结论:校招的时候,选择哪门语言反而是不重要的。
30 |
31 | 招聘分为两个阶段:第一个阶段是你一点经验没有,正在找第一份实习;第二个阶段是你已经实习几个月,有了一定地经验,正式找工作。
32 |
33 | 针对第一阶段找实习:无论做的什么WebServer、秒杀系统、在线OJ平台、课设大作业,还是实验室做的种种水项目,绝大部分人的简历上东西在稍微有点经验的面试官眼里就是玩具。这里我说的是绝大部分人。
34 |
35 | 针对第二阶段正式找工作:我问了不少朋友,他们给我的反馈都是面试主要根据你的项目经验问,编程语言相关的八股问的蛮少的,这和我实际面试体验也是比较吻合的。可以理解为:项目有得聊,他问纯八股也挺没意思。
36 |
37 | 我有一个朋友他主要学的是go,面的也是go,拼多多、阿里云、抖音、快手各个厂顶配offer都有,工资非常可人。他在22年招聘环境如此恶劣的情况下拿到这么多好的工作,跟学了哪门编程语言关系其实不大,因为有不少公司要求进去转。根本原因是他有一段腾讯核心部门一年的高质量实习+个人解决问题能力非常强。
38 |
39 | 又比如我,在找实习和工作的时候一直都是用go来面试,面试中主要都是对着我的简历项目深挖,语言相关的问的很少。我在字节实习的时候,项目需求有什么就写什么,js、python、go都写;我的正式工作,进去之后也要更换技术栈,做的是底层,需要转C或者C++;未来要做什么,我自己也不确定。
40 |
41 | 所以我的建议是:花更多时间准备算法刷题、计算机网络、操作系统、数据结构、计算机组成原理、设计模式这些通用的东西,当你了解这些通用的东西之后,以后不同语言之间的技术迁移也会容易很多。
42 |
43 | **注意:这里说的不重要指的是面试内容占比不大,但是常见语言八股文该背还是要背:比如Java的HashMap底层原理、C++的虚函数、go的三色标记法和混合写屏障......**
44 |
45 |
46 |
47 | 2️⃣ 各类编程语言的对比
48 |
49 |
50 |
51 |
52 | Java
53 |
54 | 
55 |
56 |
57 | Java是目前国内第一编程语言,主要用于企业级应用开发、网站平台开发、移动领域的手机游戏和移动android开发,大数据生态也是Java的天下。几乎所有的交易网站(淘宝,天猫,京东等)和金融网站都是用Java开发的。
58 |
59 | **优点**:稳,Java虽然被喷卷上天,但是岗位却仍然是最多的,生态十分完善。太多国内公司为其背书了。
60 |
61 | **缺点**:要学的真的很多,不仅仅有Java基本的语言基础,还有衍生出的各种生态: Java基础、Java并发、JVM、MySQL、Redis、Spring、MyBatis、Kafka、Dubbo啥的,面试基本都会问一问。
62 |
63 |
64 | C++
65 |
66 | 
67 |
68 | C++主要用于游戏领域、办公软件、图形处理、网站、搜索引擎、图形界面层、关系型数据库、浏览器、软件开发、集成环境IDE等等。想学好不容易,市面上的岗位招聘数量仅次于Java,一般搞游戏开发的都要学,现在游戏公司的薪资不低所以这一块的收入也不差。嵌入式、底层这边用的C或者C++也很多。
69 |
70 | **优点**:没Java卷,但是难学。虽然难学但是一通百会。
71 |
72 | **缺点**:学习门槛高,上手慢。因为比较难,不同程序员写的C++程序层次不齐,质量难以保证。
73 |
74 |
75 | Python
76 |
77 | 
78 |
79 | 主要应用领域是爬虫、数据分析、自动化测试和机器学习,但也有一些中小企业在做自研的网站和app应用的时候用Python做后端开发。
80 |
81 | Python大多数是数据分析和测试岗位,这个语言学习难度本身是低的,但是如果你要搞人工智能那么机器学习领域的专业知识才是难啃的硬骨头,这一行对与学历的要求也会很高。
82 |
83 | **注意:没有经验背书不建议把python作为自己后端的主语言,要求最低的其实是要求最高的**
84 |
85 |
86 |
87 | Golang
88 |
89 | 
90 |
91 | go主要应用于区块链技术和后端服务器应用,云原生、微服务、Web表现也很好,现在很多厂后端服务开始用go重构了。go好上手,学习起来比Java和C++简单,能写出什么样的代码还是取决于刚才提到的编程内功。招聘需求数量比不上Java和C++。
92 |
93 | **优点**:简单易懂,面试要背的八股文比Java或者C++少;面向未来的语言,需求会越来越大。
94 |
95 | **缺点**:岗位少比Java或者C++少很多很多;按照专业对口的角度,去不上中大厂基本宣告着失业;短期内生态不是很完善。
96 |
97 |
98 |
99 | 3️⃣ 校招生该如何选择
100 |
101 | 该怎么选择编程语言来面试呢?我的想法是:多多益善,技术永无止境。很多人精力有限,学好一门都可能身心交瘁,还要打磨这门语言对应的生态和应用场景。学好指的是:对这门语言的底层有了解,会使用它解决实际问题。而不是停留于知道语法、输出个"Hello World"、写个IF-ELSE语句。精通一门比会用三门更有竞争力,校招少选择几门,把该语言相关的技术往深度和广度学。
102 |
103 | 做后端开发方向,Java、C++、golang选一门作为自己的主修语言即可,或者类似于Rust、C#等语言也可以,都有市场和岗位。选择哪个编程语言,找工作的简历要有对应技术栈的项目作为支持。
104 |
105 | 如果求稳,选C++或者Java,基本没有公司不要Java和C++的。想去传统国企或者是银行之类就选Java,因为这些企业的上层应用基本都是Java开发。
106 |
107 | 如果确定自己想进大厂并且不想学的很多,go是不错的选择。腾讯、阿里、京东、百度、华为各个大厂都要go,还有深信服、快手、虾皮这些厂也要go,小型企业和各类国企基本对go没需要,虾皮22年秋招也没招人。
108 |
109 | 
110 |
--------------------------------------------------------------------------------
/src/introduction/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar: heading
3 | pageInfo: false
4 | editLink: false
5 | comment: false
6 | ---
7 |
8 |
9 |
10 | CSView | 计算机面试知识汇总
11 |
12 |
13 |
14 |
15 |
16 |
17 | 👁🗨CSView介绍
18 |
19 | CSView是一个互联网面试知识学习和汇总项目,包括**面试高频算法、系统设计、计算机网络、操作系统、cpp语言基础、Java语言基础、golang语言基础、MySQL、Redis、K8s、消息队列**等常见面试题。
20 |
21 | 与传统的学习网站不同的是,**CSView的内容来源于面经,并且网站和公众号会不断汇总面经内容来进行迭代**。真实的面试问什么,网站就写什么,这样更有助面试者了解面试情形。同时项目还会定期分享面试经验和互联网实用知识,帮助大家更好准备面试。
22 |
23 | 
24 |
25 |
26 |
27 | 🧑💻适用者
28 |
29 |
30 | **该项目适用于**:
31 |
32 | - 准备实习/校招面试的人
33 | - 面试前自查基础知识掌握程度的人
34 | - 社招补充基础的人
35 | - 喜欢抽象事物的人
36 | - 爱好仙子伊布的人
37 |
38 |
39 |
40 |
41 |
42 | 💻项目来源
43 |
44 |
45 | 我叫zijing,是**CSView**的发起人。作为一个参加过22届秋招的人,我投递参加过**数十场校招面试,看过上百篇面经**,最后成功拿下了**字节、百度**等互联网公司的offer。我发现大多数互联网校招的准备方法仍有迹可循,围绕着**项目经历、语言基础、计算机网络,数据库、操作系统**等询问的基础知识(一般被称为八股文),在更为充分的准备下,明显会有更高面试通过率。
46 |
47 | 然而,现在互联网上存在大量低质量、错误频出、无用内容占多数的校招和八股文网站和文档分享,这会浪费面试准备者大量时间。为了避免时间浪费,让同学们把握面试中的要点内容,我找了几个朋友一起整理分享,于是CSView这个项目应运而生。
48 |
49 | 虽然现在有很多不足之处,但是好在开发迭代的速度很快,我们每天都在完善网站的内容,与面试准备者进行交流,帮助大家能找到更满意的工作。
50 |
51 | 当然,如果本站内容对你准备学习知识有帮助,您可以给一个**打赏(您的打赏将被放在网站的[贡献页面](https://www.csview.cn/website-contribution))**或者是**简单地去[GitHub](https://github.com/zijing2333/CSView)给项目点一个star**,作为对我们工作内容的认可。
52 |
53 | ::: tip CSView的来源
54 |
55 | 为什么网站和项目的名称叫CSView呢?CS是计算机科学Computer Science的缩写,而View在汉语里有**视野、个人意见、见解、(理解或思维的)方法和风景**的意思,在使用本站的过程中,我们希望:
56 |
57 | - 网站可以带给你不一样的理解和思维
58 |
59 | :::
60 |
61 |
62 |
63 | ✨项目特点
64 |
65 |
66 | **贴合面试**:网站的题目都是从数百篇面经中提取出来的**最常考**的题目,准备这些题目通常是性价比最高。我们并不会把诸如“**什么是数据库**”这类的问题放在网站上,一是没必要,二是浪费面试者的宝贵时间。
67 |
68 | **高质量回答**:针对高频次的题目网站都会给出一定的回答,回答介于书面语和口头语之间,既不失阅读时的严谨性,也不失理解上的简易性。
69 |
70 | **体验良好**:我们曾尝试过WordPress、MkDocs、Hexo等多种框架搭建网站,最后选择了功能完善且阅读体验更好的vuepress架构,并采用了vuepress-theme-hope主题。网站的**页面布局、内容分类、字体颜色、功能选配、代码块主题和图片配色**等都是精心调试过的,旨在带来更好的使用体验。
71 |
72 | **开源免费**:项目承诺所有内容完全免费,并且在[GitHub](https://github.com/zijing2333/CSView)可以获取一切关于本站的内容。
73 |
74 | **共商共建**:可以在[开发日志](https://www.csview.cn/development-log/)看到网站更新工作和进展,我们会不断优化网站的每一处内容,网站内容也会根据面经和实际需求**每天更新**,及时修复存在的错误。任何人都可以参与到项目的建设中来,任何人都可以贡献内容到网站,贡献内容的人将会出现在网站的作者栏。
75 |
76 |
77 |
78 |
79 |
80 |
81 | ✍作者
82 |
83 | **枫长**:算法页面作者,某C9高校硕士,**曾在字节跳动和阿里云各实习两个月,力扣刷题800多道**,经常参加算法周赛,算法解题经验丰富。主要技术栈是C++。
84 |
85 |
86 |
87 | **LH**:985硕士,**22年秋招上岸字节核心部门**,是一个唱歌很好听的小哥哥。主要技术栈是C++。
88 |
89 |
90 |
91 | **jjd**:操作系统和C++页面作者,**国内top3计算机专业硕士在读**,本科专业top5%,曾获数学建模国奖一等奖。
92 |
93 |
94 |
95 | **xmy**:Java页面作者,985计算机硕士,曾在网易实习三个月,爱好打星际。主要技术栈是Java。
96 |
97 |
98 |
99 | **fawn**:CSView的图片绘制人,华五计算机专业,**高考680分+**,爱好睡觉。
100 |
101 |
102 |
103 | **小羊**:专业的图案创意设计者,爱好不加班。
104 |
105 |
106 |
107 | **子敬**:某985大学软件工程专业读研二,**仙子伊布爱好者**,喜欢读哲学、历史和养生学。主要技术栈是Golang。
108 |
109 |
110 |
111 |
112 | 🛠技术支持
113 |
114 | **开发测试**:[腾讯云服务器](https://github.com/zijing2333/CSView)
115 |
116 | **项目框架**:[vuepress2.0](https://v2.vuepress.vuejs.org/)
117 |
118 | **主题**:[vuepress-theme-hope](https://theme-hope.vuejs.press/)
119 |
120 | **代码托管和CDN加速**:[Vercel](https://vercel.com/)
121 |
122 | **图床**:[聚和图床](https://www.superbed.cn/)
123 |
124 | **图标**:[iconfont](https://www.iconfont.cn/)
125 |
126 | **页面语法**:MarkDown-Enhance
127 |
128 |
129 |
130 |
131 | ⚠️声明
132 |
133 | 网站为本人整合创作,禁止整合恶意搬运、分享,且严禁将网站内容整合搬运到任何公众号。未按要求注明来源的内容请联系我整改或者删除。
134 |
135 |
136 |
137 |
138 | 🦀特别鸣谢
139 |
140 | **特别感谢**[xiaolingcoding](https://xiaolincoding.com/)对本站创作和内容的支持,本站复用xiaolingcoding内容是为了带来更高质量的内容,同时也推荐大家去[xiaolingcoding](https://xiaolincoding.com/)系统学习计算机基础知识,这是一个质量极高的学习网站。
141 |
142 | **特别感谢**[Mr.Hope](https://mrhope.site/)(vue-theme-hope主题开发者)项目开发中提供的技术支持及问题解决方案。
143 |
144 |
145 |
146 |
147 | 📅未来计划
148 |
149 | - [ ] 面试题频次排序功能实现
150 | - [ ] 面经提交功能实现
151 | - [ ] 招聘汇总信息上线
152 | - [ ] 面经总结页面上线
153 | - [ ] 使用algolia重新构建网站索引
154 |
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/src/redis/colony.md:
--------------------------------------------------------------------------------
1 | ### Redis集群模式有哪些?
2 |
3 | **主从**:选择一台作为主服务器,将数据到多台从服务器上,构建一主多从的模式,主从之间读写分离。主服务器可读可写,发生写操作会同步给从服务器,而从服务器一般是只读,并接受主服务器同步过来写操作命令。主从服务器之间的命令复制是**异步**进行的,所以无法实现强一致性保证(主从数据时时刻刻保持一致)。
4 |
5 | **哨兵**:当 Redis 的主从服务器出现故障宕机时,需要手动进行恢复,为了解决这个问题,Redis 增加了哨兵模式,哨兵监控主从服务器,并且提供**主从节点故障转移的功能。**
6 |
7 | **切片集群**:当数据量大到一台服务器无法承载,需要使用Redis切片集群(Redis Cluster)方案,它将数据分布在不同的服务器上,以此来降低系统对单主节点的依赖,提高 Redis 服务的读写性能。
8 |
9 |
10 |
11 | ### Redis切片集群的工作原理?
12 |
13 | 切片集群会采用哈希槽来进行数据和节点的映射,一个切片集群一共有16384个槽位,每个存储数据的key会经过运算映射到16384个槽位中,映射关系如下:
14 |
15 | - 由key通过CRC16算法计算出一个16bit的数字
16 | - 根据上面计算得到的数字对16384取模来确定对应的哈希槽
17 |
18 |
19 |
20 | ### 哈希槽和Redis节点是如何对应的?
21 |
22 | 主要有平均分配和手动分配两种方式。平均分配是集群创建时,Redis自动将哈希槽平均分配到集群节点上;手动分配是使用命令指定每个节点上面的哈希槽数目,使用手动分配时要把16384个槽位给分完,否则集群不会正常工作。
23 |
24 |
25 |
26 | ### 主从模式的同步过程?
27 |
28 | **第一次同步**
29 |
30 | 主要分为建立**连接协商、主从数据同步、发送新操作**三个步骤:
31 |
32 | - **连接协商**:从服务器先发送命令给主服务器表示要进行数据同步,命令内容包括**主服务器的runID**和**复制进度**两个参数,主服务器收到命令之后会给从服务响应命令,响应包括**主服务器的runID**和**复制进度**。从服务器收到响应之后会记录这两个值。
33 | - **主从数据同步**:主服务器生成RDB文件并发送给从服务器,从服务器收到RDB之后先清空自己的数据,再载入RDB文件。为了主从数据的一致性,这个期间主服务器后续的写操作会记录到replication buffer缓冲区里
34 | - **发送新操作**:主服务器发送replication buffer里面的写操作给从服务器,从服务器执行这些操作。第一次同步完成。
35 |
36 | **命令传播**
37 |
38 | 第一次同步完成之后双方会维护一个TCP连接,后续主服务器的写命令通过TCP连接发送给从服务器,保证主从一致。
39 |
40 | **压力分摊**
41 |
42 | 为了分摊服务器的压力,生成和传输RDB的工作可以分摊到经理从服务器上。
43 |
44 | **增量复制**
45 |
46 | 如果服务器网路断开,在恢复之后,会把网络断开期间主服务器接收到的写操作命令同步给从服务器。
47 |
48 |
49 |
50 | ### 主服务器如何知道要将哪些增量数据发送给从服务器?
51 |
52 | 网络断开从服务器重新上线之后,会发送自己的复制偏移量到主服务器,主服务器根据偏移量之间的差距判断要执行的操作:如果从服务器要读的数据在repl_backlog_buffe中,则采用增量复制;如果不在,采用全量复制。
53 |
54 | ::: tip repl_backlog_buffer
55 |
56 | **repl_backlog_buffer**是一个**环形**缓冲区,用于主从服务器断连后,从中找到差异的数据;**replication offset**标记缓冲区的同步进度。
57 |
58 | :::
59 |
60 |
61 |
62 | ### 如何避免主从数据的不一致?
63 |
64 | 让主从节点处于同一机房,降低网络延迟;或者由外部程序监控主从复制进度:先计算得出主从服务之间的复制进度差,如果复制进度差大于程序设定的阈值,让客户端不再在此节点读取数据,减小数据不一致的情况对业务的影响。
65 |
66 | ::: tip 提示
67 |
68 | 为了避免出现客户端和所有从节点都不能连接的情况,需要把复制进度差值的阈值设置得大一些。
69 |
70 | :::
71 |
72 |
73 |
74 | ### 主从架构中过期key如何处理?
75 |
76 | 主节点处理一个过期的key之后就会发送一条删除命令给从服务器,从节点收到命令后进行删除。
77 |
78 |
79 |
80 | ### 主从模式是同步复制还是异步复制?
81 |
82 | 异步。因为主节点收到写命令之后,先写到内部的缓冲区,然后再异步发送给从节点。
83 |
84 |
85 |
86 | ### 哨兵机制是什么?
87 |
88 | 因为在主从架构中读写是分离的,如果主节点挂了,将没有主节点来响应客户端的写操作请求,也无法进行数据同步。哨兵作用是实现主从节点故障转移。哨兵会监测主节点是否存活,如果发现主节点挂了,会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。
89 |
90 |
91 |
92 | ### 哨兵机制的工作原理?
93 |
94 | **判断节点是否存活**
95 |
96 | 哨兵会周期性给所有主节点发送PING命令来判断其他节点是否正常运行。如果PING命令响应失败哨兵会将节点标记为**主观下线**,然后该哨兵会向其他节点发出投票命令,当票数达到设定的阈值之后这个主节点就被标记为**客观下线**。然后哨兵会从从节点中选择一个作为主节点。
97 |
98 | **投票**
99 |
100 | 哨兵集群中会选择一个leader来负责主从切换,选举是一个投票过程:判断主节点为**客观下线**的是候选者,候选者向其他哨兵发送命令表示要成为leader,其他哨兵会进行投票,每个哨兵只有一票,可以投给自己或投给别人,但是只有候选者才能把票投给自己。候选者之后拿到半数以上的赞成票并且票数大于设置的阈值,就会成为候选者。
101 |
102 | **选出新主节点**
103 |
104 | 把网络状态不好的从节点给排除:先把已经下线的从节点过滤掉,然后把以往网络连接状态不好的从节点排除掉。接下来要对所有从节点进行三轮考察:**优先级、复制进度、ID号**。在进行每一轮考察的时候,哪个从节点优先胜出,就选择其作为新主节点:
105 |
106 | - 第一轮考察:哨兵首先会根据从节点的优先级来进行排序,优先级越小排名越靠前。
107 | - 第二轮考察:如果优先级相同,则查看复制的下标,哪个接收的复制数据多哪个就靠前。
108 | - 第三轮考察:如果优先级和下标都相同,选择ID较小的那个。
109 |
110 | **更换主节点**
111 |
112 | 选出新主节点之后,哨兵leader让已下线主节点属下的所有从节点指向新主节点。
113 |
114 | **通知客户的主节点已更换**
115 |
116 | 客户端和哨兵建立连接后,客户端会订阅哨兵提供的频道。主从切换完成后,哨兵就会向 `+switch-master` 频道发布新主节点的 IP 地址和端口的消息,这个时候客户端就可以收到这条信息,然后用这里面的新主节点的 IP 地址和端口进行通信了。
117 |
118 | **将旧主节点变为从节点**
119 |
120 | 继续监视旧主节点,当旧主节点重新上线时,哨兵集群就会向它发送SLAVEOF命令,让它成为新主节点的从节点。
121 |
122 |
123 |
124 | ### 什么是集群的脑裂?
125 |
126 | 如果主节点的网络突然发生了问题与所有的从节点都失联了,但此时的主节点和客户端的网络是正常的,客户端不知道集群内部已经出现了问题,还在向这个失联的主节点写数据,此时这些数据被主节点缓存到了缓冲区里。哨兵也发现主节点失联了,就会在从节点中选举出一个leader作为主节点,会导致集群有两个主节点。
127 |
128 | 网络恢复后哨兵因为之前已经选举出一个新主节点了,它就会把旧主节点降级,然后从旧主节点会向新主节点请求数据同步,**因为第一次同步是全量同步的方式,旧主节点会清空掉自己本地的数据。客户端在过程之前写入的数据就会丢失了**。所以脑裂会导致集群数据的丢失。
129 |
130 |
131 |
132 | ### 如何减少主从切换带来的数据丢失?
133 |
134 | **异步复制同步丢失**
135 |
136 | 配置一个阈值,一旦所有的从节点数据复制和同步的延迟都超过了阈值,主节点就会拒绝接收任何请求。对于客户端发现主节点不可写后,可以采取降级措施。将数据暂时写入本地缓存和磁盘中,在一段时间后重新写入主节点来保证数据不丢失,也可以将数据写入消息队列,等主节点恢复正常,再隔一段时间去消费消息队列中的数据,让将数据重新写入主节点。
137 |
138 | **集群产生脑裂数据丢失**
139 |
140 | 当主节点发现从节点下线或者通信超时的总数量小于阈值时,那么禁止主节点进行写数据,直接把错误返回给客户端。**设置主节点连接的从节点中至少有 N 个从节点,并且主节点进行数据复制时的 ACK 消息延迟不能超过 T 秒**,否则,主节点就不会再接收客户端的写请求了。等到新主节点上线时,就只有新主节点能接收和处理客户端请求,此时,新写的数据会被直接写到新主节点中。而原主节点会被哨兵降为从节点,即使它的数据被清空了,也不会有新数据丢失。
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/src/os/filesystem.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 文件系统
3 | author: ["jjd","枫长"]
4 | ---
5 |
6 |
7 |
8 | ### 文件系统虚拟化?
9 |
10 | - 文件是操作系统进行存储时使用最多的抽象之一,每个文件实际上是一个**有名字的字符序列**,也可以把文件叫做虚拟磁盘,我们实际操作时都是在操作文件而非直接操作硬盘中的数据。序列内容为**文件数据**,而序列长度,修改时间等描述文件数据的属性特征的其他信息被称为**文件元数据**。
11 | - 文件系统就是管理文件数据与文件元数据的系统,即文件系统。文件系统提供文件抽象并实现文件访问所需要的接口。考虑到存储空间太大,文件以数据块为单位进行访问,一个块一般4KB。
12 | - 当应用程序想访问或写入一些数据到存储设备上时,它会采用Linux系统提供的open,write,read等系统调用;在处理系统调用时,内核会调用**虚拟文件系统**(VFS)来处理文件请求,虚拟文件系统负责管理具体的文件系统如inode文件系统,FAT32文件系统等。
13 |
14 | ### 什么是硬链接与符号连接?
15 |
16 | 硬链接(hard link)和符号链接(symbolic link,也称为软链接)是Unix和类Unix文件系统中两种不同的文件链接类型。它们用于创建文件或目录的引用。
17 |
18 | **硬链接**
19 |
20 | 硬链接是文件系统中一个文件的额外引用。在Unix和类Unix文件系统中,每个文件都有一个称为inode的数据结构来存储文件的元数据,例如文件权限、所有者、大小等。每个文件都有一个或多个文件名(硬链接),它们指向相应的inode。换句话说,硬链接是文件名和inode之间的关联。
21 |
22 | 硬链接的特点如下:
23 |
24 | - 硬链接不能跨文件系统。由于硬链接直接关联到inode,它只能在同一个文件系统中创建。
25 | - 硬链接不能引用目录。这是为了防止文件系统中出现循环引用和其他不一致性问题。
26 | - 删除一个文件的所有硬链接会导致文件被删除。当一个文件的最后一个硬链接被删除时,文件系统将释放该文件的inode以及占用的存储空间。
27 | - 硬链接不影响原始文件的访问。所有硬链接都指向相同的inode,因此访问任何一个硬链接实际上是访问原始文件。
28 |
29 | **符号链接**
30 |
31 | 符号链接是一种特殊的文件,它包含指向另一个文件或目录的路径。与硬链接直接关联到inode不同,符号链接通过路径名来引用目标文件。当用户或应用程序访问符号链接时,文件系统会自动将其重定向到目标路径。
32 |
33 | 符号链接的特点如下:
34 |
35 | - 符号链接可以跨文件系统。由于符号链接通过路径名引用目标文件,它可以链接到其他文件系统中的文件或目录。
36 | - 符号链接可以引用目录。这使得符号链接在文件系统组织和目录结构管理中非常有用。
37 | - 删除符号链接不会影响目标文件。当删除一个符号链接时,只有链接本身被删除,而目标文件保持不变。
38 | - 符号链接可能引起死链接(dangling link)。如果目标文件被删除或移动,符号链接将指向一个不存在的路径,导致死链接。
39 |
40 | ### 讲一讲Inode文件系统结构?
41 |
42 | Inode(索引节点)是UNIX和类UNIX文件系统中的一个重要概念。Inode是文件系统中的一个数据结构,用于存储文件或目录的元数据(metadata),例如文件大小、时间戳、权限、所有者等。Inode还包含了指向实际文件数据块(data block)的指针,这些数据块存储了文件的内容。
43 |
44 | 在UNIX和类UNIX文件系统中,每个文件或目录都有一个唯一的Inode号(Inode number),用于唯一标识文件系统中的对象。文件名只是一个用户友好的引用,实际上是指向Inode号的指针。这种设计允许文件系统以更高效的方式管理和访问文件,同时提供了硬链接等高级功能。以下是Inode文件系统结构的几个关键组成部分:
45 |
46 | - **Inode表**:Inode表是文件系统中一个预先分配的区域,用于存储Inode数据结构。每个Inode在Inode表中占用固定大小的空间,通常为128字节或256字节。文件系统在格式化时会预先分配一定数量的Inode,这些Inode数量决定了文件系统能够容纳的最大文件和目录数量。
47 | - **数据块**:数据块(data block)是文件系统中用于存储文件内容的基本单位。数据块的大小通常为4KB、8KB或更大。每个Inode包含了指向文件数据块的指针,这些指针可以直接指向数据块(直接块指针),也可以指向间接块(间接块指针)、二次间接块(双间接块指针)或三次间接块(三间接块指针)。
48 | - **目录项**:目录项(directory entry)是文件系统中表示目录结构的数据结构。每个目录项包含一个文件名和一个对应的Inode号。目录项存储在目录文件的数据块中,通过Inode号可以找到目录项所指向的文件或子目录的Inode和数据块。
49 | - **超级块**:超级块(superblock)是文件系统中存储文件系统元数据的区域。超级块包含了文件系统的基本信息,如文件系统类型、大小、块大小、Inode数量等。操作系统在挂载文件系统时会读取超级块,以确定文件系统的参数和状态。
50 |
51 | 
52 |
53 |
54 |
55 | ### 讲一讲FAT文件系统与UNIX文件系统?
56 |
57 | FAT(File Allocation Table)文件系统和UNIX文件系统是两种不同的文件系统结构。
58 |
59 | **FAT文件系统**
60 |
61 | FAT文件系统最初是为MS-DOS操作系统设计的,后来成为了Windows操作系统中的一个主要文件系统。FAT文件系统有多个版本,包括FAT12、FAT16和FAT32。FAT文件系统的核心组件是文件分配表(File Allocation Table),它是一个记录文件数据块使用情况的表格
62 |
63 | FAT文件系统的特点如下:
64 |
65 | - 结构简单:FAT文件系统的结构相对简单,易于实现和维护。它是通过链表的形式管理数据块,**随机访问能力较差**。
66 | - 跨平台兼容性:由于FAT文件系统的普及程度很高,大多数操作系统都支持FAT文件系统。这使得FAT文件系统成为了很多可移动存储设备(如U盘、SD卡等)的首选文件系统。
67 | - 局限性:FAT文件系统在文件权限管理、文件大小限制和磁盘空间利用率等方面存在一定的局限性。例如,FAT32文件系统不支持超过4GB的单个文件(因为链表管理的原因,访问最后一个数据块要遍历完所有数据块的指针,所以大文件性能很差),而且没有类似UNIX文件系统中的文件权限和所有权管理功能。
68 |
69 | **UNIX文件系统**
70 |
71 | UNIX文件系统通常指代在UNIX和类UNIX操作系统中使用的一系列文件系统,这类系统相比于FAT**主要提升了随机访问的能力**,并且支持链接。
72 |
73 | UNIX文件系统的特点如下:
74 |
75 | - Inode结构:UNIX文件系统使用Inode(索引节点)来存储文件元数据,这种设计使得文件系统可以更高效地管理和访问文件。
76 | - 权限管理:UNIX文件系统支持详细的文件权限和所有权管理,允许对文件和目录进行读、写和执行权限的控制。
77 | - 硬链接和符号链接:UNIX文件系统支持硬链接和符号链接,这些链接类型可以用于创建文件和目录的引用,实现更灵活的文件系统组织和管理。
78 | - 日志功能:许多UNIX文件系统(如EXT4、XFS等)具有日志功能,这有助于提高文件系统的数据一致性和恢复能力。
79 |
80 | 在实际应用中,这两种文件系统有各自的优势和适用场景。
81 |
82 | FAT文件系统通常适用于以下场景:
83 |
84 | - 可移动存储设备:由于FAT文件系统在各种操作系统中都有很好的支持,它成为了许多可移动存储设备(如U盘、SD卡等)的默认文件系统。
85 | - 嵌入式系统:FAT文件系统简单的结构和较低的系统资源需求使其在嵌入式系统和低端设备中非常受欢迎。
86 |
87 | UNIX文件系统通常适用于以下场景:
88 |
89 | - UNIX和类UNIX操作系统:在这些操作系统中,UNIX文件系统(如EXT4、XFS等)是默认或推荐的文件系统。
90 | - 服务器和高性能计算:由于UNIX文件系统在性能、可靠性和扩展性方面的优势,它们通常被用于服务器和高性能计算系统。
91 |
92 | 除了FAT和UNIX文件系统外,还有其他类型的文件系统,如Windows中的NTFS和macOS中的APFS等。
93 |
94 | ### 文件传输中断后如何续传,讲一讲Rsync算法?
95 |
96 | 当文件传输过程中遇到中断,如网络故障或其他原因,需要一种方法来继续传输,而不是从头开始。续传功能可以有效地减少重复传输的数据量,从而提高传输效率。Rsync算法是一种用于文件同步和增量备份的高效算法,可以实现文件传输的续传功能。
97 |
98 | Rsync算法基于滚动哈希(rolling hash)和数据块签名的方法来实现文件同步。以下是Rsync算法的基本步骤:
99 |
100 | 1. 将目标文件分割成固定大小或可变大小的数据块。对于每个数据块,计算两个哈希值:一个弱哈希值(如Adler-32校验和)和一个强哈希值(如MD5或SHA-1散列)。
101 | 2. 将这些哈希值(也称为数据块签名)发送到接收方。接收方在本地查找与目标文件相同的文件,通常是一个旧版本或部分传输的文件。
102 | 3. 接收方将本地文件划分为与发送方相同大小的数据块,并计算每个数据块的弱哈希值。
103 | 4. 接收方使用滚动哈希方法,在本地文件中寻找与发送方数据块相匹配的哈希值。通过比较弱哈希值,接收方可以快速找到潜在的匹配数据块。为了避免误报,接收方还会比较强哈希值来确认数据块是否真正匹配。
104 | 5. 接收方将匹配的数据块信息(如数据块索引和偏移量)发送回发送方。
105 | 6. 发送方根据接收方返回的匹配信息,仅发送目标文件中未匹配的数据块,从而实现增量更新和续传功能。
106 |
107 | Rsync算法的主要优势是它可以在不传输整个文件的情况下检测和同步文件的差异。这种方法在大文件、低带宽和不稳定网络连接的场景中非常高效。不过Rsync算法本身并不负责文件传输,而是需要与其他文件传输协议(如SSH、FTP等)结合使用。
108 |
109 | Rsync算法已经被广泛应用于各种文件同步和备份工具中,如Linux中的`rsync`命令。这些工具提供了丰富的选项和功能,可以实现文件传输的续传、增量备份、压缩传输等高级功能。
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | CSView | 计算机面试知识汇总
4 |
5 |
6 |
7 | 📖在线阅读网址👉:www.csview.cn
8 |
9 |
10 |
11 |
12 | 👁🗨CSView介绍
13 |
14 | CSView是一个互联网面试知识学习和汇总项目,包括**面试高频算法、系统设计、计算机网络、操作系统、cpp语言基础、Java语言基础、golang语言基础、MySQL、Redis、K8s、消息队列**等常见面试题。
15 |
16 | 与传统的学习网站不同的是,**CSView的内容来源于面经,并且网站和公众号会不断汇总面经内容来进行迭代**。真实的面试问什么,网站就写什么,这样更有助面试者了解面试情形。同时项目还会定期分享面试经验和互联网实用知识,帮助大家更好准备面试。
17 |
18 | 
19 |
20 |
21 |
22 | 🧑💻适用者
23 |
24 |
25 | **该项目适用于**:
26 |
27 | - 准备实习/校招面试的人
28 | - 面试前自查基础知识掌握程度的人
29 | - 社招补充基础的人
30 | - 喜欢抽象事物的人
31 | - 爱好仙子伊布的人
32 |
33 |
34 |
35 | 📚️学习
36 |
37 |
38 | 🟠刷题
39 |
40 | ### [👉面试必刷算法题](./src/algorithm-mandatory)
41 | ### [👉系统设计题](./src/design)
42 | ### [👉智力题](./src/intelligence)
43 | ### [👉HR面常见题](./src/hr)
44 |
45 |
46 |
47 |
48 | 🟢编程语言基础
49 |
50 | ### [👉cpp](./src/cpp/)
51 | ### [👉golang](./src/golang/)
52 | ### [👉java](./src/java/)
53 |
54 |
55 |
56 |
57 | 🔵计算机基础
58 |
59 | ### [👉计算机网络](./src/network/)
60 | ### [👉操作系统](./src/os/)
61 |
62 |
63 |
64 | 🔴数据库
65 |
66 | ### [👉MySQL](./src/mysql/)
67 | ### [👉Redis](./src/redis/)
68 |
69 |
70 | ⚫中间件
71 |
72 |
73 | ### [👉RabbitMQ](./src/rabbitmq/)
74 | ### [👉K8s](./src/k8s/)
75 | ### [👉Nginx](./src/nginx/)
76 |
77 |
78 |
79 |
80 |
81 | 💻项目来源
82 |
83 |
84 | 我叫zijing,是**CSView**的发起人。作为一个参加过22届秋招的人,我投递参加过**数十场校招面试,看过上百篇面经**,最后成功拿下了**字节、百度**等互联网公司的offer。我发现大多数互联网校招的准备方法仍有迹可循,围绕着**项目经历、语言基础、计算机网络,数据库、操作系统**等询问的基础知识(一般被称为八股文),在更为充分的准备下,明显会有更高面试通过率。
85 |
86 | 然而,现在互联网上存在大量低质量、错误频出、无用内容占多数的校招和八股文网站和文档分享,这会浪费面试准备者大量时间。为了避免时间浪费,让同学们把握面试中的要点内容,我找了几个朋友一起整理分享,于是CSView这个项目应运而生。
87 |
88 | 虽然现在有很多不足之处,但是好在开发迭代的速度很快,我们每天都在完善网站的内容,与面试准备者进行交流,帮助大家能找到更满意的工作。
89 |
90 | 当然,如果本站内容对你准备学习知识有帮助,您可以给一个**打赏(您的打赏将被放在网站的[贡献页面](https://www.csview.cn/website-contribution))**或者是**简单地去[GitHub](https://github.com/zijing2333/CSView)给项目点一个star**,作为对我们工作内容的认可。
91 |
92 |
93 |
94 |
95 |
96 | ✨项目特点
97 |
98 |
99 | **贴合面试**:网站的题目都是从数百篇面经中提取出来的**最常考**的题目,准备这些题目通常是性价比最高。我们并不会把诸如“**什么是数据库**”这类的问题放在网站上,一是没必要,二是浪费面试者的宝贵时间。
100 |
101 | **高质量回答**:针对高频次的题目网站都会给出一定的回答,回答介于书面语和口头语之间,既不失阅读时的严谨性,也不失理解上的简易性。
102 |
103 | **体验良好**:我们曾尝试过WordPress、MkDocs、Hexo等多种框架搭建网站,最后选择了功能完善且阅读体验更好的vuepress架构,并采用了vuepress-theme-hope主题。网站的**页面布局、内容分类、字体颜色、功能选配、代码块主题和图片配色**等都是精心调试过的,旨在带来更好的使用体验。
104 |
105 | **开源免费**:项目承诺所有内容完全免费,并且在[GitHub](https://github.com/zijing2333/CSView)您可以获取一切关于本站的内容。
106 |
107 | **共商共建**:您可以[开发日志](https://www.csview.cn/development-log/)看到网站更新工作和进展,我们会不断优化网站的每一处内容,网站内容也会根据面经和实际需求**每天更新**,及时修复存在的错误。任何人都可以参与到项目的建设中来,任何人都可以贡献内容到网站,贡献内容的人将会出现在网站的作者栏。
108 |
109 |
110 |
111 |
112 |
113 |
114 | ✍作者
115 |
116 | **枫长**:算法页面作者,某C9高校硕士,**曾在字节跳动和阿里云各实习两个月,力扣刷题800多道**,经常参加算法周赛,算法解题经验丰富。主要技术栈是C++。
117 |
118 |
119 |
120 | **LH**:985硕士,**22年秋招上岸字节核心部门**,是一个唱歌很好听的小哥哥。主要技术栈是C++。
121 |
122 |
123 |
124 | **jjd**:操作系统和C++页面作者,**国内top3计算机专业硕士在读**,本科专业top5%,曾获数学建模国奖一等奖。
125 |
126 |
127 |
128 | **xmy**:Java页面作者,985计算机硕士,曾在网易实习三个月,爱好打星际。主要技术栈是Java。
129 |
130 |
131 |
132 | **fawn**:CSView的图片绘制人,华五计算机专业,**高考680分+**,爱好睡觉。
133 |
134 |
135 |
136 | **小羊**:专业的图案创意设计者,爱好不加班。
137 |
138 |
139 |
140 | **子敬**:某985大学软件工程专业读研二,**仙子伊布爱好者**,喜欢读哲学、历史和养生学。主要技术栈是Golang。
141 |
142 |
143 |
144 |
145 | 🛠技术支持
146 |
147 | **开发测试**:[腾讯云服务器](https://github.com/zijing2333/CSView)
148 |
149 | **项目框架**:[vuepress2.0](https://v2.vuepress.vuejs.org/)
150 |
151 | **主题**:[vuepress-theme-hope](https://theme-hope.vuejs.press/)
152 |
153 | **代码托管和CDN加速**:[Vercel](https://vercel.com/)
154 |
155 | **图床**:[聚和图床](https://www.superbed.cn/)
156 |
157 | **图标**:[iconfont](https://www.iconfont.cn/)
158 |
159 | **页面语法**:MarkDown-Enhance
160 |
161 |
162 |
163 |
164 | ⚠️声明
165 |
166 | 网站为本人整合创作,禁止整合恶意搬运、分享,且严禁将网站内容整合搬运到任何公众号。未按要求注明来源的内容请联系我整改或者删除。
167 |
168 |
169 |
170 |
171 | 🦀特别鸣谢
172 |
173 | **特别感谢**[xiaolingcoding](https://xiaolincoding.com/)对本站创作和内容的支持,本站复用xiaolingcoding内容是为了带来更高质量的内容,同时也推荐大家去[xiaolingcoding](https://xiaolincoding.com/)系统学习计算机基础知识,这是一个质量极高的学习网站。
174 |
175 | **特别感谢**[Mr.Hope](https://mrhope.site/)(vue-theme-hope主题开发者)项目开发中提供的技术支持及问题解决方案。
176 |
177 |
178 |
179 |
180 | 📅未来计划
181 |
182 | - [ ] 面试题频次排序功能实现
183 | - [ ] 面经提交功能实现
184 | - [ ] 招聘汇总信息上线
185 | - [ ] 面经总结页面上线
186 | - [ ] 使用algolia重新构建网站索引
187 |
--------------------------------------------------------------------------------
/src/rabbitmq/summary.md:
--------------------------------------------------------------------------------
1 | ### AMQP协议?
2 |
3 | AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
4 |
5 | AMQP三层协议:
6 |
7 | - Module Layer:协议最高层,主要定义了一些客户端调用的命令,客户端可以用这些命令实现自己的业务逻辑。
8 |
9 | - Session Layer:中间层,主要负责客户端命会发送给服务器,再将服务端应答返回客户端,提供可靠性同步机制和错误处理。
10 |
11 | - TransportLayer:最底层,主要传输二进制数据流,提供帧的处理、信道服用、错误检测和数据表示等。
12 |
13 |
14 | AMQP组件:
15 |
16 | - 交换器(Exchange):消息代理服务器中用于把消息路由到队列的组件。
17 |
18 | - 队列(queue):用来存储消息的数据结构,位于硬盘或内存中。
19 |
20 | - 绑定(Binding):一套规则,告知交换器消息应该将消息投递给哪个队列。
21 |
22 |
23 | ### RabbitMQ包含哪些要素?
24 |
25 | - 生产者:消息队列创建者,发送消息到MQ
26 | - 消费者:连接到RabbitMQ,订阅到队列上,消费消息,持续订阅和单条订阅
27 | - 消息:包含有效载荷和标签,有效载荷指要传输的数据,标签描述了有效载荷,并且RabbitMQ用它来决定谁获得消息,消费者只能拿到有效载荷,并不知道生产者是谁
28 |
29 | ### RabbitMQ各个部分的概念?
30 |
31 | **信道**
32 |
33 | 是生产者、消费者与RabbitMQ通信的渠道,生产者publish或是消费者subscribe 一个队列都是通过信道来通信的。
34 |
35 | 信道是建立在TCP连接上的虚拟连接,就是说RabbitMQ在一条TCP上建立成百上千个信道来达到多个线程处理,这个TCP被多个线程共享,每个线程对应一个信道,信道在RabbitMQ都有一个唯一的ID,保证了信道私有性,对应上唯一的线程使用。
36 |
37 | **Broker**
38 |
39 | broker是指一个或多个erlang node的逻辑分组,且node上运行着RabbitMQ应用程序。
40 |
41 | **Cluster**
42 |
43 | cluster是在broker的基础之上,増加了node之间共享元数据的约束。
44 |
45 | **Exchange**
46 |
47 | 生产者将消息发送到交换器,有交换器将消息路由到一个或者多个队中。当路由不到时,或返回给生产者或直接丟弃。
48 |
49 | **RoutingKey**
50 |
51 | 生产者将消息发送给交换器的时候,会指定一个RoutingKey,用来指定这个消息的路由规则,这个RoutingKey需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。
52 |
53 | **Binding**
54 |
55 | 通过绑定将交换器和队列关联起来,一般会指定一个BindingKey,这样RabbitMq就知道如何正确路由消息到队列了。
56 |
57 | **死信队列**
58 |
59 | 当消息被RabbitMQ server投递到consumer后,但consumer却通过 Basic.Reject进行了拒绝时(同时设置requeue=false),那么该消息会被放入死信队列中。该 queue 可用于排查 message 被 reject 或 undeliver 的原因。
60 |
61 | **vhost**
62 |
63 | vhost可以理解为虚拟broker,即mini-RabbitMQ server。其内部均含有独立的queue、exchange和binding等,但最最、重要的是,其拥有独立的权限系统,可以做到vhost范围的用户控制。当然,从RabbitMQ的全局角度,vhost可以作为不同权限隔离的手段(一个典型的例子就是不同的应用可以跑在不同的vhost中)。
64 |
65 |
66 |
67 | ### RabbitMQ的routing key和binding key的最大长度是多少?
68 |
69 | 255字节。
70 |
71 |
72 |
73 | ### RabbitMQ中消息可能有的几种状态?
74 |
75 | - alpha:消息内容(包括消息体、属性和headers)和消息索引都存储在内存
76 | - beta:消息内容保存在磁盘中,消息索引保存在内存中
77 | - gamma:消息内容保存在磁盘中,消息索引在磁盘和内存中都有
78 | - delta:消息内容和索引都在磁盘中
79 |
80 |
81 |
82 | ### RabbitMQ的消息传输保证层级?
83 |
84 | - At most once:最多一次。消息可能会丢失,但不会重复传递
85 |
86 | - At least once:最少一次。消息绝不会丟失,但可能会重夏传输
87 |
88 | - Exactly once:恰好一次。每条消息肯定仅传输一次
89 |
90 |
91 |
92 | ### RabbitMQ的工作模式?
93 |
94 | **simple模式(即最简单的收发模式)**
95 |
96 | 消息产生消息,将消息放入队列
97 |
98 | 消息的消费者监听消息队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列中删除(隐患消息可能没有被消费者正确处理,已经从队列中消失了,造成消息的丢失,这里可以设置成手动的ack,但如果设置成手动ack,处理完后要及时发送ack消息给队列,否则会造成内存溢出)。
99 |
100 | **work工作模式(资源的竞争)**
101 |
102 | 消息产生者将消息放入队列消费者可以有多个,消费者1,消费者2同时监听同一个队列,消息被消费。C1 C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息(隐患:高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关[syncronize]保证一条消息只能被一个消费者使用)。
103 |
104 | **publish/subscribe发布订阅(共享资源)**
105 |
106 | 每个消费者监听自己的队列。
107 |
108 | 生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息。
109 |
110 | **routing路由模式**
111 |
112 | 消息生产者将消息发送给交换机按照路由判断,路由是字符串(info)当前产生的消息携带路由字符(对象的方法),交换机根据路由的key,只能匹配上路由key对应的消息队列,对应的消费者才能消费消息。
113 |
114 | **topic主题模式(路由模式的一种)**
115 |
116 | 为路由功能添加模糊匹配,消息产生者产生消息,把消息交给交换机,交换机根据key的规则模糊匹配到对应的队列,由队列的监听消费者接收消息消费。
117 |
118 |
119 |
120 | ### 发送消息的过程?
121 |
122 | - 生产者将消息发布到一个或多个交换器(Exchange)中。交换器的作用是根据路由键(Routing Key)将消息分配给特定的队列(Queue)。
123 |
124 | - 交换器通过路由键将消息路由到一个或多个队列。如果路由键为空,消息会被分配给所有绑定到该交换器的队列。
125 |
126 | - 消息进入队列,等待被消费者接收。在队列中,消息会被存储在持久化存储中,以防服务器崩溃或重启时数据丢失。
127 |
128 | - 消费者从队列中获取消息并进行处理。消费者可以通过订阅一个或多个队列来接收消息。一旦消息被消费者接收,它将从队列中移除。
129 |
130 |
131 |
132 |
133 |
134 | ### 为什么要使用RabbitMQ?
135 |
136 | - 在分布式系统下具备异步,削峰,负载均衡等一系列高级功能
137 |
138 | - 拥有持久化的机制,进程消息,队列中的信息也可以保存下来
139 |
140 | - 实现消费者和生产者之间的解耦
141 |
142 | - 对于高并发场景下,利用消息队列可以使得同步访问变为串行访问达到一定量的限流,利于数据库的操作
143 |
144 | - 可以使用消息队列达到异步下单的效果,排队中,后台进行逻辑下单
145 |
146 |
147 |
148 |
149 | ### RabbitMQ缺点?
150 |
151 | - 复杂性:RabbitMQ 需要一定的学习和理解成本,特别是在配置、管理和监控方面。
152 |
153 | - 可靠性:RabbitMQ 的可靠性依赖于其配置和管理,需要进行合理的配置和监控,否则可能会出现消息丢失或重复传递等问题。
154 |
155 | - 性能:RabbitMQ 的性能与其配置和使用方式密切相关,如果配置不当或使用不当,可能会导致性能问题。
156 |
157 | - 成本:RabbitMQ 需要一定的硬件和软件资源支持,特别是在高并发和大规模应用场景下,需要投入更多的资源。
158 |
159 | - 可扩展性:RabbitMQ 的可扩展性有一定限制,如果需要支持更高的并发和吞吐量,需要进行集群部署和负载均衡等操作。
160 |
161 | - 存储要求:RabbitMQ 依赖于磁盘进行消息存储,因此需要一定的存储空间,并需要定期清理过期消息。
162 |
163 |
164 | ### Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么优缺点?
165 |
166 | 一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;
167 |
168 | 后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;
169 |
170 | 不过现在确实越来越多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄;
171 |
172 | 所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择;
173 |
174 | 大数据领域的实时计算、日志采集等场景,使用Kafka。
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
--------------------------------------------------------------------------------
/src/mysql/summary.md:
--------------------------------------------------------------------------------
1 | ### 关系的三个范式是什么?
2 |
3 | **第一范式(1NF)**:用来确保每列的原子性,要求每列(或者每个属性值)都是不可再分的最小数据单元(也称为最小的原子单元)。
4 |
5 | **第二范式(2NF)**:在第一范式的基础上更进一层,要求表中的每列都和主键相关,即要求实体的唯一性。如果一个表满足第一范式,并且除了主键以外的其他列全部都依赖于该主键,那么该表满足第二范式。
6 |
7 | **第三范式(3NF)**:在第二范式的基础上更进一层,第三范式是确保每列都和主键列直接相关,而不是间接相关,即限制列的冗余性。如果一个关系满足第二范式,并且除了主键以外的其他列都依赖于主键列,列和列之间不存在相互依赖关系,则满足第三范式。
8 |
9 |
10 |
11 |
12 |
13 | ### MySQL中varchar和char的区别是什么?
14 |
15 | - char字段的最大长度为255字符,varchar字段的最大长度为65535个字符。
16 | - char类型如果存的数据量小于最大长度,剩余的空间会使用空格填充,因此可能会浪费空间,所以char类型适合存储长度固定的数据,这样不会浪费空间,效率还比varchar略高;varchar类型如果存到数据量小于最大长度,剩余的空间会留给别的数据使用,所以varchar类型适合存储长度不固定的数据,这样虽然没有char存储效率高,但至少不会浪费空间。
17 | - char类型的查找效率高,varchar类型的查找效率较低。
18 |
19 |
20 |
21 | ### join和left join的区别?
22 |
23 | - join等价于inner join内连接,是返回两个表中都有的符合条件的行。
24 |
25 | - left join左连接,是返回左表中所有的行及右表中符合条件的行。
26 |
27 | - right join右连接,是返回右表中所有的行及左表中符合条件的行。
28 |
29 |
30 |
31 | ### SQL怎么实现模糊查询?
32 |
33 | 索引 B+ 树是按照索引值有序排列存储的,只能根据前缀进行比较。每一次按照模糊匹配的前缀字典序来进行比较。
34 |
35 |
36 |
37 | ### select的执行过程?
38 |
39 | **连接**:首先客户端和MySQL通过三次握手建立连接,MySQL是基于TCP进行传输的。MySQL服务如果没有启动就会报错。MySQL正常运行的话就去校验用户名和密码,如果认证信息错误也会报错。检验通过之后连接器会获取用户权限并且保存起来,后续的任何操作都会基于开始的读到权限进行判断,即便创建连接之后更改了权限也不会影响已连接的权限。
40 |
41 | ::: tip 长连接解决
42 |
43 | 第一种,**定期断开长连接**。
44 |
45 | 第二种,**客户端主动重置连接**。当客户端执行了一个很大的操作后,在代码里调用 mysql_reset_connection 函数来重置连接,达到释放内存的效果。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
46 |
47 | :::
48 |
49 | **查询缓存**:连接成功后会像MySQL服务中发送SQL语句,MySQL服务收到语句之后会进行解析判断SQL语句的类型。如果是select语句的话就去缓存中查询,看看之前有没有执行过这条select语句。缓存是以k-v形式保存在内存中的,key是SQL语句,value是SQL查询结果。如果缓存中有结果就直接返回给客户端,如果没有命中就继续向下执行。执行完成后的结果会被放入缓存中。
50 |
51 | ::: tip 缓存缺点
52 |
53 | 对于更新比较频繁的表,查询缓存的命中率很低的,只要一个表有更新操作,那么这个表的查询缓存就会被清空。如果刚缓存了一个查询结果很大的数据,还没被使用的时候,刚好这个表有更新操作,查询缓冲就被清空了寞。
54 |
55 | MySQL 8.0 版本直接将查询缓存删掉了,执行一条 SQL 查询语句,不会有查询缓存这个阶段了。
56 |
57 | :::
58 |
59 | **SQL解析**:词法分析和语法分析,词法分析是把SQL语句的字符串识别出关键字,方便后续优化,语法分析根据语法规则判断SQL语句是否满足要求。如果SQL语句不对就会报错,
60 |
61 | **执行SQL**:主要是prepare预处理、optimize优化和execute执行阶段。预处理器检查SQL查询的表或者字段是否存在,如果有*就将它扩展为SQL的所有的列。优化器是确定SQL语句的执行方案,比方说有索引会选择走了哪个索引。执行器会与存储引擎交互,如果走索引了就将相应索引条件交给存储引擎,存储引擎通过B+树定位数据,如果数据不存在就像执行器返回错误,然后查询结束,找到了就将记录返回给执行数,执行器读到数据之后判断记录是否满足要求,如果满足要求就将数据返回给客户端,否则跳过该数据。如果是全表扫描优化器和存储引擎交互之后存储引擎会访问第一条表中数据,执行器会判断这条数据是否满足条件,满足就发给客户端,然后执行器查询是一个while循环,继续取下一条记录重复判断,直到读完表中所有记录退出循环。如果使用联合索引的话,会在存储引擎层分别判断每个索引是否满足条件,而不先执行回表,所有索引有一个不成立就跳过,否则就返回给Server层回表,这是一个索引下推的过程。
62 |
63 |
64 |
65 | ### update的执行过程?
66 |
67 | 执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取一行记录:
68 |
69 | - 如果记录所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新;
70 | - 如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器。
71 |
72 | 执行器得到聚簇索引记录后,会看一下更新前的记录和更新后的记录是否一样:
73 |
74 | - 如果一样的话就不进行后续更新流程;
75 | - 如果不一样的话就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 真正的执行更新记录的操作;
76 |
77 | 开启事务,首先要记录相应的 undo log,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面,不过在内存修改该 Undo 页面后,需要记录对应的 redo log。
78 |
79 | InnoDB 层开始更新记录,会先更新内存(同时标记为脏页),然后将记录写到 redo log 里面,这个时候更新就算完成了。为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。
80 |
81 | 在一条更新语句执行完成后,然后开始记录该语句对应的 binlog,此时记录的 binlog 会被保存到 binlog cache,在事务提交时才会统一将该事务运行过程中的所有 binlog 刷新到硬盘。
82 |
83 | 两阶段提交:
84 |
85 | - **prepare 阶段**:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘;
86 | - **commit 阶段**:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit 状态后,刷入到磁盘 redo log 文件);
87 |
88 |
89 |
90 | ### count性能比较?
91 |
92 | count(*)=count(1)>count(主键)>count(字段)
93 |
94 | MySQL 会将星号参数转化为参数 0 来处理,所以count(*) 和count(1)相等。count(主键)需要判断主键是否为空值;count(字段)会进行全表扫描,效率最差。
95 |
96 |
97 |
98 | ### drop、truncate和delete的区别?
99 |
100 | drop删除整张表和表结构,以及表的索引、约束和触发器;truncate只删除表数据,表的结构、索引、约束等会被保留; delete只删除表的全部或部分数据,表结构、索引、约束等会被保留。
101 |
102 | delete语句为DML(data maintain Language),执行删除操作的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作;truncate、drop是DLL(data define language),删除行是不能恢复的,并且在删除的过程中不会激活与表有关的删除触发器,执行速度快,原数据不放到rollback segment中,不能回滚。
103 |
104 | truncate 和 drop 不支持添加 where 条件,而 delete 支持 where 条件。
105 |
106 | 执行速度drop>truncate>delete,delete 是逐行执行的,并且在执行时会把操作日志记录下来,以备日后回滚使用,所以 delete 的执行速度是比较慢的;而 truncate 的操作是先复制一个新的表结构,再把原先的表整体删除,所以它的执行速度居中,而 drop 的执行速度最快。
107 |
108 | truncate 只能对TABLE;delete可以是TABLE和VIEW。
109 |
110 | ::: tip 使用场景
111 |
112 | 如果想删除表,用**drop**;
113 |
114 | 如果想保留表而将所有数据删除,和事务无关,用**truncate**即可;
115 |
116 | 如果和事务有关,或者想触发**trigger**,用**delete**;
117 |
118 | 如果是整理表内部的碎片,可以用**truncate**跟上reuse stroage,再重新导入/插入数据。
119 |
120 | :::
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | ### MySQL会出现死锁吗,怎么检测死锁?
129 |
130 | 如果 update 语句的 where 条件没有用到索引列,那么就会全表扫描,在一行行扫描的过程中,不仅给行记录加上了行锁,还给行记录两边的空隙也加上了间隙锁,相当于锁住整个表,然后直到事务结束才会释放锁。
131 |
132 | 行锁会发生死锁,表锁不会。死锁的四个必要条件:**互斥、占有且等待、不可强占用、循环等待**。只要系统发生死锁,这些条件必然成立,但是只要破坏任意一个条件就死锁就不会成立。
133 |
134 | 解决办法:
135 |
136 | - **设置事务等待锁的超时时间**。当一个事务的等待时间超过该值后,就对这个事务进行回滚,于是锁就释放了,另一个事务就可以继续执行了。在 InnoDB 中,参数 innodb_lock_wait_timeout 是用来设置超时时间的,默认值时 50 秒。
137 |
138 | 当发生超时后,就出现下面这个提示:
139 |
140 | - **开启主动死锁检测**。主动死锁检测在发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑,默认就开启。当检测到死锁后,就会出现提示。
141 |
142 |
143 |
144 |
145 |
146 | #
--------------------------------------------------------------------------------
/src/network/ip.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: IP面试常见题
3 | ---
4 |
5 |
6 |
7 | ### DNS查询服务器的基本流程?
8 |
9 | - 客户机向其本地域名服务器发出DNS请求报文
10 | - 本地域名服务器收到请求后,**查询本地缓存**,假设没有该记录,则以DNS客户的身份向**根域名**服务器发出解析请求
11 | - **根域名**服务器收到请求后,判断该域名所属域,将对应的**顶级域名服务器**的IP地址返回给本地域名服务器
12 | - 本地域名服务器向**顶级域名服务器**发出解析请求报文
13 | - 顶级域名服务器收到请求后,将所对应的**授权域名服务器**的IP地址返回给本地域名服务器
14 | - 本地域名服务器向授权域名服务器发起解析请求报文
15 | - 授权域名服务器收到请求后,将**查询结果返回给本地域名服务器**
16 | - 本地域名服务器将查询结果保存到**本地缓存**,**同时**返回给客户机
17 |
18 | . —- .com —– qq.com —– [www.qq.com](http://www.qq.com/) –ip给客户机。
19 |
20 | 如果是转发模式,则与上一步骤相反,从下往上找。[www.qq.com](http://www.qq.com/) => qq.com => .com => .
21 |
22 |
23 |
24 | ### DNS采用TCP还是UDP,为什么?
25 |
26 | DNS在进行区域传输的时候使用TCP协议,**其它时候则使用UDP协议**。TCP与UDP传送字节的长度限制不同,一般情况下一个DNS的UDP包的最大长度是**512**字节。
27 |
28 | 区域传输使用TCP协议的原因大概是:
29 |
30 | - 区域传输的数据量相比单次DNS查询的数据量要大得多
31 | - 区域传输对数据的可靠性和准确性相比普通的DNS查询要要高得多,因此使用TCP协议
32 |
33 | 域名解析时一般返回的内容都不超过512字节,首选的通讯协议是UDP。使用UDP传输,不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。
34 |
35 |
36 |
37 | ### DNS劫持是什么?解决办法?
38 |
39 | #### 概念
40 |
41 | DNS重定向,通过覆盖计算机的TCP/IP设置,将个人查询重定向到域名服务器DNS。这可以通过使用恶意软件或修改服务器的设置来实现,一旦执行DNS劫持的个人控制了DNS,他们就可以使用它来将流量引导到不同的网站。
42 |
43 | **本地DNS劫持**
44 |
45 | 攻击者在用户的计算机上安装木马恶意软件,并更改本地DNS设置以将用户重定向到恶意站点。
46 |
47 | **路由器DNS劫持**
48 |
49 | 攻击者接管路由器并覆盖DNS设置,从而影响连接到该路由器的所有用户。
50 |
51 | **中间DNS攻击的人**
52 |
53 | 攻击者拦截用户和DNS服务器之间的通信,并提供指向恶意站点的不同目标IP地址。
54 |
55 | #### 解决方法
56 |
57 | - 加强域名账户的安全防护能力,使用有别于其他平台的用户名和强密码,定期对密码进行更换。
58 |
59 | - 定期查看域名账户信息、域名whois信息、域名解析状态,每天site网站检查是否存在非个人设定网页,发现异常及时联系域名服务商。
60 |
61 | - 锁定域名解析状态,不允许通过DNS服务商网站修改记录,使用此方法后,需要做域名解析都要通过服务商来完成,这样可以从根本上杜绝通过攻击服务商修改解析记录的方法。
62 |
63 |
64 |
65 |
66 | ### 浏览器输入一个URL到显示器显示的过程?
67 |
68 | **键盘输入**
69 |
70 | 输入键盘字符后键盘就会产生扫描数据,并将其缓冲存在寄存器中,然后键盘通过总线给 CPU 发送中断请求。CPU 收到中断请求后,操作系统会保存被中断进程的 CPU 上下文,然后调用键盘的中断处理程序。键盘中断处理函数从键盘的寄存器的缓冲区读取扫描码,再根据扫描码找到用户在键盘输入的字符的ASCII 码。然后把 ASCII 码放到读缓冲区队列,显示器会定时从读缓冲区队列读取数据放到写缓冲区队列,最后把写缓冲区队列的数据一个一个写入到显示器的寄存器中的数据缓冲区,最后将这些数据显示在屏幕里。
71 |
72 | **URL解析**
73 |
74 | 浏览器会首先从缓存中找是否存在域名,如果存在就直接取出对应的ip地址,如果没有就开启一个DNS域名解析器。DNS域名解析器会首先访问顶级域名服务器,将对应的IP发给客户端;然后访问根域名解析器,将对应的IP发给客户端;最后访问本地域名服务器,得到最终的ip地址。
75 |
76 | **TCP连接**
77 |
78 | 在URL解析过程中得到真实的IP地址之后,会调用Socket函数建立TCP连接。
79 |
80 | **HTTP请求**
81 |
82 | 浏览器向服务器发起一个 HTTP请求,HTTP协议是建立在TCP协议之上的应用层协议,其本质是建立起的 TCP连接中,按照 HTTP协议标准发送一个索要网页的请求。请求包含请求行、请求头、请求体三个部分组成,有GET、POST等主要方法。
83 |
84 | **浏览器接收响应**
85 |
86 | 服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码,响应头,响应报文三个部分。
87 |
88 | **页面渲染**
89 |
90 | 浏览器根据响应开始显示页面,首先解析 HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。
91 |
92 | **断开连接**
93 |
94 | 客户端和服务器通过四次挥手终止TCP连接。
95 |
96 |
97 |
98 | ### PING是怎么工作的?
99 |
100 | ::: tip
101 |
102 | ICMP主要的功能包括:确认IP包是否成功送达目标地址、报告发送过程中IP包被废弃的原因、改善网络设置等。在IP通信中如果某个IP包因为某种原因未能达到目标地址,具体的原因将由ICMP通知。
103 |
104 | :::
105 |
106 | ping命令执行的时候,源主机首先会构建一个ICMP回送请求消息数据包,由ICMP协议将这个数据包连同服务端IP一起交给IP层,IP层将以服务端IP作为目的地址,本机IP地址作为源地址,协议字段设置为1,再加上一些其他控制信息,构建一个IP数据包;然后加入MAC头;如果在本地ARP映射表中查找出服务端IP所对应的MAC地址,则可以直接使用,如果没有,则需要发送ARP协议查询MAC地址。获得MAC地址后,由数据链路层构建一个数据帧,目的地址是IP层传过来的MAC地址,源地址则是本机的MAC地址;还要附加上一些控制信息,依据以太网的介质访问规则将它们传送出去。
107 |
108 | 目的收到这个数据帧后,先检查它的目的MAC地址,并和本机的MAC地址对比,如符合,则接收,否则就丢弃。接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层。IP层检查后,将有用的信息提取后交给ICMP协议。主机B会构建一个ICMP回送响应消息数据包,回送响应数据包的类型字段为0,序号为接收到的请求数据包中的序号,然后再发送出去给主机A。
109 |
110 | 在规定的时候间内,源主机如果没有接到ICMP的应答包,则说明目标主机不可达;如果接收到了ICMP回送响应消息,则说明目标主机可达。
111 |
112 |
113 |
114 | ### Cookie和Session的关系和区别是什么?
115 |
116 | #### Cookie
117 |
118 | **概念**
119 |
120 | Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务器两个请求是否来自同一浏览器。
121 |
122 | 如保持用户的登录状态,**Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能**。
123 |
124 | **作用**
125 |
126 | - 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
127 | - 个性化设置(如用户自定义设置、主题等)
128 | - 浏览器行为跟踪(如跟踪分析用户行为等)
129 |
130 | #### Session
131 |
132 | Session代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。
133 |
134 | #### 差别
135 |
136 | - **作用范围不同**:Cookie 保存在客户端(浏览器),Session 保存在服务端
137 | - **存取方式的不同**:Cookie 只能保存 ASCII,Session 可以存任意数据类型
138 | - **有效期不同**:Cookie 可设置为长时间保持,比如经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效
139 | - **隐私策略不同**:Cookie 存储在客户端,比较容易遭到不法获取;Session 存储在服务端,安全性相对 Cookie 要好一些
140 | - **存储大小不同**:单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie
141 |
142 |
143 |
144 | ### iPv4和iPv6的区别?
145 |
146 | - IPv6的首部长度是40个字节,相对IPv4的首部长度24字节要长,但IPv6首部结构比IPv4简单。
147 |
148 | - IPv6 把 IP 地址由 32 位增加到 128 位,从而能够支持更大的地址空间。IPv6 简化了路由, 加快了路由速度。
149 |
150 | - IPv6 的可选项不放入报头,而是放在一个个独立的扩展头部。如果不指定路由器不会打开处理扩展头部, IPv6 放宽了对可选项长度的严格要求 (IPv4 的可选项总长最多为 40 字节) ,并可根据需要随时引入新选项。
151 |
152 | - IPv6协议支持地址自动配置,这是一种即插即用的机制。IPv6节点通过地址自动配置得到IPv6地址和网关地址。IPv6支持无状态地址自动配置和状态地址自动配置两种地址自动配置方式。它会给配置128位的地址带来很大的方便,特别是无状态地址自动配置。
153 |
154 | - 在IPv6 中加入了关于身份验证、数据一致性和保密性的内容。
155 |
156 |
157 |
158 | ### 什么是跨域,什么情况下会发生跨域请求?
159 |
160 | #### 概念
161 |
162 | 指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的。a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
163 |
164 | #### 解决方法
165 |
166 | - **Nginx**:使用Nginx作为代理服务器和用户交互,用户就只需要在80端口上进行交互就可以了,这样就避免了跨域问题。
167 | - **JSONP**:网页通过添加一个script元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。缺点是只支持get请求,不支持post请求。
168 | - **CORS**:跨域资源分享。
169 |
170 |
171 |
172 |
173 |
174 | [^1]: http://www.zhanghuihui.cloud/2022/10/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E9%9D%A2%E7%BB%8F/
175 |
176 |
--------------------------------------------------------------------------------
/src/redis/persistence.md:
--------------------------------------------------------------------------------
1 | ### AOF和RDB?
2 |
3 | **AOF**
4 |
5 | 每执行一条**写操作**命令,就将该命令以追加的方式写入到 AOF 文件,然后在恢复时,以逐一执行命令的方式来进行数据恢复。用 AOF 日志的方式来恢复数据很慢,因为 Redis 执行命令由单线程负责的,AOF 日志恢复数据的方式是顺序执行日志里的每一条命令,如果 AOF 日志很大,这个过程就会很慢了。
6 |
7 | **RDB**
8 |
9 | RDB 快照是记录某一个瞬间的内存数据,记录的是实际数据,而 AOF 文件记录的是命令操作的日志,而不是实际的数据。因此在 Redis 恢复数据时, RDB 恢复数据的效率会比 AOF 高些,因为直接将 RDB 文件读入内存就可以,不需要像 AOF 那样还需要额外执行操作命令的步骤才能恢复数据。
10 |
11 | RDB快照是全量快照,也就是说每次执行快照,都是把内存中的所有数据都记录到磁盘中。如果频率太频繁,可能会对 Redis 性能产生影响。如果频率太低,服务器故障时,丢失的数据会更多。通常可能设置至少 5 分钟才保存一次快照,这时如果 Redis 出现宕机等情况,意味着最多可能丢失 5 分钟数据。
12 |
13 | **AOF-RDB混用**
14 |
15 | 在 AOF 重写日志时,fork出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。
16 |
17 | 这样的好处在于,重启 Redis 加载数据的时候,由于前半部分是 RDB 内容,这样**加载的时候速度会很快**。加载完 RDB 的内容后,才会加载后半部分的 AOF 内容,这里的内容是 Redis 后台子进程重写 AOF 期间,主线程处理的操作命令,可以使得**数据更少的丢失**。缺点是AOF文件的可读性变差了。
18 |
19 |
20 |
21 | ### AOF的三种写回策略?
22 |
23 | Always、Everysec 和 No,这三种策略在可靠性上是从高到低,而在性能上从低到高。
24 |
25 | **Always**是每次写操作命令执行完后,同步将 AOF 日志数据写回硬盘;**Everysec**每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘;**No**就是不控制写回硬盘的时机。每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。
26 |
27 |
28 |
29 | ### AOF的磁盘重写机制?
30 |
31 | 随着执行的命令越多,AOF 文件的体积自然也会越来越大,为了避免日志文件过大, Redis 提供了 AOF 重写机制,它会直接扫描数据中所有的键值对数据,然后为每一个键值对生成一条写操作命令,接着将该命令写入到新的 AOF 文件,重写完成后,就替换掉现有的 AOF 日志。重写的过程是由后台子进程完成的,这样可以使得主进程可以继续正常处理命令。
32 |
33 |
34 |
35 |
36 |
37 | ### 为什么先执行Redis命令,再把数据写入AOF日志呢?
38 |
39 | **好处**:
40 |
41 | - **保证正确写入**:如果当前的命令语法有问题,错误的命令记录到 AOF 日志里后可能还会进行语法检查。先执行Redis命令,再把数据写入AOF日志可以保证写入的都是正确可执行的命令。
42 | - **不阻塞当前写操作**:因为当写操作命令执行成功后才会将命令记录到AOF日志,避免写入阻塞。
43 |
44 | **缺陷**:
45 |
46 | - **数据可能会丢失:** 执行写操作命令和记录日志是两个过程,Redis还没来得及将命令写入到硬盘时发生宕机,数据会有丢失的风险。
47 | - **阻塞其他操作:** 不会阻塞当前命令的执行,但因为 AOF 日志也是在主线程中执行,所以当 Redis 把日志文件写入磁盘的时候,还是会阻塞后续的操作无法执行。
48 |
49 |
50 |
51 | ### AOF的重写的具体过程?
52 |
53 | 触发重写机制后,主进程会创建重写 AOF 的子进程,此时父子进程共享物理内存,重写子进程只会对这个内存进行只读。重写 AOF 子进程读取数据库里的所有数据,并逐一把内存数据的键值对转换成一条命令,再将命令记录到重写日志。
54 |
55 | 在发生写操作的时候,操作系统才会去复制物理内存,这样是为了防止 fork 创建子进程时,由于物理内存数据的复制时间过长而导致父进程长时间阻塞的问题。
56 |
57 |
58 |
59 | ### AOF子进程的内存数据跟主进程的内存数据不一致怎么办?
60 |
61 | Redis设置了一个 **AOF 重写缓冲区**,这个缓冲区在创建 bgrewriteaof 子进程之后开始使用。在重写 AOF 期间,当 Redis 执行完一个写命令之后,它会**同时将这个写命令写入到AOF 缓冲区和AOF 重写缓冲区**。当子进程完成 AOF 重写工作后,会向主进程发送一条信号。主进程收到该信号后,会调用一个信号处理函数,将 AOF 重写缓冲区中的所有内容追加到新的 AOF 的文件中,使得新旧两个 AOF 文件所保存的数据库状态一致;新的 AOF 的文件进行改名,覆盖现有的 AOF 文件。
62 |
63 | ::: tip 提示
64 |
65 | Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的,这有两个好处:
66 |
67 | - 子进程进行 AOF 重写期间,主进程可以继续处理命令请求,从而避免阻塞主进程;
68 | - 子进程带有主进程的数据副本,使用子进程而不是线程,因为如果是使用线程,多线程之间会共享内存,那么在修改共享内存数据的时候,需要通过加锁来保证数据的安全,而这样就会降低性能。创建子进程时,父子进程是共享内存数据的,不过这个共享的内存只能以只读的方式,而当父子进程任意一方修改了该共享内存,会发生写时复制,于是父子进程就有了独立的数据副本,不用加锁来保证数据安全。
69 |
70 | :::
71 |
72 | ### RDB 在执行快照的时候,数据能修改吗?
73 |
74 | 可以。执行 bgsave 过程中,Redis 依然**可以继续处理操作命令**的,数据是能被修改的,采用的是写时复制技术(Copy-On-Write, COW)。执行 bgsave 命令的时候,会通过 fork()创建子进程,此时子进程和父进程是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是一个,由于共享父进程的所有数据,可以直接读取主线程里的内存数据,并将数据写入到 RDB 文件。此时如果主线程执行读操作,则主线程和 bgsave 子进程互相不影响。如果主线程要修改共享数据里的某一块数据,就会发生写时复制,数据的物理内存就会被复制一份,主线程在这个数据副本进行修改操作。与此同时,子进程可以继续把原来的数据写入到 RDB 文件。
75 |
76 |
77 |
78 | ### Redis过期机制?
79 |
80 | 三种过期删除策略:
81 |
82 | - 定时删除:**在设置 key 的过期时间时,同时创建一个定时事件,当时间到达时,由事件处理器执行 key 的删除操作。**
83 |
84 | - **优点**:内存可以被尽快地释放。定时删除对内存是最友好的。
85 |
86 | - **缺点**:定时删除策略对 CPU 不友好,删除过期 key 可能会占用相当一部分 CPU 时间,CPU 紧张的情况下将 CPU 用于删除和当前任务无关的过期键上,会对服务器的响应时间和吞吐量造成影响。
87 |
88 | - 惰性删除:**不主动删除过期键,每次从数据库访问 key 时检测 key 是否过期,如果过期则删除该key。**
89 |
90 | - **优点**:只会使用很少的系统资源,对 CPU 最友好。
91 |
92 | - **缺点**:如果一个 key 已经过期,而这个 key 又仍然保留在数据库中,那么只要这个过期 key 一直没有被访问,它所占用的内存就不会释放。惰性删除策略对内存不友好。
93 |
94 | - 定期删除:**每隔一段时间随机从数据库中取出一定数量的 key 进行检查,并删除其中的过期key。**
95 | - **优点**:限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响,同时也能删除一部分过期的数据减少了过期键对空间的无效占用。
96 | - **缺点**:内存清理方面没有定时删除效果好,同时没有惰性删除使用的系统资源少。难以确定删除操作执行的时长和频率。
97 |
98 | **Redis 选择惰性删除+定期删除这两种策略配和使用**,以求在合理使用 CPU 时间和避免内存浪费之间取得平衡。Redis 在访问或者修改 key 之前,都会调用 expireIfNeeded 函数对其进行检查,检查 key 是否过期:
99 |
100 | - 如果过期,则删除该 key,然后返回 null 客户端;
101 | - 如果没有过期,不做任何处理,然后返回正常的键值对给客户端;
102 |
103 | 从过期字典中随机抽取 20 个 key;检查这 20 个 key 是否过期,并删除已过期的 key;已过期 key 的数量占比随机抽取 key 的数量大于 25%,则继续重复步骤直到比重小于25%。
104 |
105 |
106 |
107 |
108 |
109 | ### Redis的内存淘汰策略?
110 |
111 | **不进行数据淘汰的策略**
112 |
113 | 它表示当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,则会触发 OOM,只是单纯的查询或者删除操作的话还是可以正常工作。
114 |
115 | **进行数据淘汰的策略**
116 |
117 | 在设置了过期时间的数据中进行淘汰:
118 |
119 | - **volatile-random**:随机淘汰设置了过期时间的任意键值
120 | - **volatile-ttl**:优先淘汰更早过期的键值
121 | - **volatile-lru**:淘汰所有设置了过期时间的键值中,最久未使用的键值
122 | - **volatile-lfu**:淘汰所有设置了过期时间的键值中,最少使用的键值
123 |
124 | 在所有数据范围内进行淘汰:
125 |
126 | - **allkeys-random**:随机淘汰任意键值
127 | - **allkeys-lru**:淘汰整个键值中最久未使用的键值
128 | - **allkeys-lfu**:淘汰整个键值中最少使用的键值
129 |
130 |
131 |
132 | ### Redis持久化时对过期键会如何处理的?
133 |
134 | **RDB**
135 |
136 | RDB分文生成阶段和加载阶段,生成阶段会对key进行过期检查,过期的key不会保存到RDB文件中;加载阶段看服务器是主服务器还是从服务器,如果是主服务器,在载入 RDB 文件时,程序会对文件中保存的键进行检查,过期键不会被载入到数据库中;如果从服务器,在载入 RDB 文件时,不论键是否过期都会被载入到数据库中。但由于主从服务器在进行数据同步时,从服务器的数据会被清空。过期键对载入 RDB 文件的从服务器也不会造成影响。
137 |
138 | **AOF**
139 |
140 | AOF文件写入阶段和AOF重写阶段。写入阶段如果数据库某个过期键还没被删除,AOF 文件会保留此过期键,当此过期键被删除后,Redis 会向 AOF 文件追加一条 DEL 命令来显式地删除该键值。重写阶段会对 Redis 中的键值对进行检查,已过期的键不会被保存到重写后的 AOF 文件中。
141 |
142 |
143 |
144 | ### Redis主从模式中,对过期键会如何处理?
145 |
146 | 从库不会进行过期扫描,即使从库中的 key 过期了,如果有客户端访问从库时,依然可以得到 key 对应的值。从库的过期键处理依靠主服务器控制,**主库在 key 到期时,会在 AOF 文件里增加一条 del 指令,同步到所有的从库**,从库通过执行这条 del 指令来删除过期的 key。
147 |
--------------------------------------------------------------------------------
/src/.vuepress/sidebar/sidebar.ts:
--------------------------------------------------------------------------------
1 | import { sidebar } from "vuepress-theme-hope";
2 |
3 | export const sideBar = sidebar({
4 |
5 | "/network/":[
6 |
7 | { text: "🟠 概述", link: "summary"},
8 | { text: "🔴 TCP和UDP", link: "tcp"},
9 | { text: "🔵 IP", link: "ip"},
10 | { text: "🟢 HTTP", link: "http"},
11 | ],
12 |
13 |
14 | "/mysql/":[
15 | { text: "🔴 概述", link: "summary"},
16 | { text: "🟤 事务", link: "transaction"},
17 | { text: "🔵 索引", link: "indexing"},
18 | { text: "🟢 锁", link: "lock"},
19 | { text: "🟣 存储引擎", link: "engine"},
20 | { text: "🟠 日志", link: "log"},
21 | { text: "🟡 优化", link: "optimize"},
22 | ],
23 |
24 | "/golang/":[
25 | { text: "🔴 概述", link: "summary"},
26 | { text: "🔵 关键字", link: "keyword"},
27 | { text: "🟢 GMP", link: "gmp"},
28 | { text: "🟡 垃圾回收", link: "gc"},
29 | ],
30 |
31 | "/redis/":[
32 | { text: "🔴 概述", link: "summary"},
33 | { text: "🔵 数据结构", link: "data-structure"},
34 | { text: "🟢 持久化", link: "persistence"},
35 | { text: "🟡 应用", link: "application"},
36 | { text: "🟣 集群", link: "colony"},
37 | ],
38 |
39 | "/cpp/":[
40 | { text: "🔴 C++基础概念和语法", link: "summary"},
41 | { text: "🟤 数据类型和类型转换", link: "dataTypesAndTypeConversions"},
42 | { text: "🔵 指针和引用", link: "pointersAndReferences"},
43 | { text: "🟢 函数和运算重载符", link: "functionAndOperationOverloaders"},
44 | { text: "🟣 继承和多态", link: "inheritanceAndPolymorphism"},
45 | { text: "🟠 内存管理", link: "memoryManagement"},
46 | { text: "🟡 编译和链接", link: "compileAndLink"},
47 | { text: "⚫ C++11/14/17/20新特性", link: "newFeatures"},
48 | { text: "⚪ STL", link: "stl"},
49 | ],
50 |
51 | "/java/":[
52 | { text: "🔴 基础", link: "summary"},
53 | { text: "🔵 集合", link: "collection"},
54 | { text: "🟢 并发", link: "concurrent"},
55 | { text: "🟡 JVM", link: "jvm"},
56 | { text: "🟣 Spring", link: "spring"},
57 | ],
58 |
59 | "/design/":[
60 | { text: "🔴 常见设计题", link: "design"},
61 | { text: "🔵 海量数据处理题", link: "bigdata"},
62 | ],
63 |
64 | "/rabbitmq/":[
65 | { text: "🔴 概述", link: "summary"},
66 | { text: "🔵 应用", link: "apply"},
67 | ],
68 |
69 | "/os/":[
70 | { text: "🔴 计算机系统基础", link: "summary"},
71 | { text: "🔵 并发", link: "concurrency"},
72 | { text: "🟢 内存管理", link: "memory-management"},
73 | { text: "🟡 进程与线程管理", link: "process"},
74 | { text: "🟣 文件系统", link: "filesystem"},
75 | { text: "🟠 服务器编程", link: "serverprogramming"},
76 | ],
77 |
78 |
79 |
80 | "/algorithm-mandatory/":[
81 | { text: "🔴 链表", link: "linklist"},
82 | { text: "🟤 树", link: "tree"},
83 | { text: "🔵 栈和队列", link: "stark-queue"},
84 | { text: "🟢 字符串", link: "string"},
85 | { text: "🟣 数组", link: "array"},
86 | { text: "🟠 动态规划", link: "dp"},
87 | { text: "🟡 DFS", link: "dfs"},
88 | { text: "⚫ 回溯", link: "backtrack"},
89 | { text: "⚪ 手撕", link: "handtearing"},
90 | { text: "🔶 其他", link: "other"},
91 | ],
92 |
93 |
94 |
95 | "/": [
96 | {
97 | text: "刷题",
98 | icon: "suanfaku",
99 | collapsible: true,
100 | children: [
101 | {
102 | text: "面试必刷算法题",
103 | icon: "zhongdianbiaozhu",
104 | link: "algorithm-mandatory",
105 |
106 | },
107 | {
108 | text: "智力题",
109 | icon: "dengpao",
110 | link: "intelligence",
111 |
112 | },
113 | {
114 | text: "设计题",
115 | icon: "sheji-xianxing",
116 | link: "design",
117 | },
118 | {
119 | text: "HR面常见题",
120 | icon: "mianshianpai",
121 | link: "hr",
122 | },
123 | ],
124 | },
125 |
126 |
127 | { text: "操作系统", icon: "caozuoxitong", link: "/os" },
128 | {
129 | text: "数据库",
130 | icon: "data-Inquire-full",
131 | collapsible: true,
132 |
133 | children: [
134 | {
135 | text: "MySQL",
136 | icon: "odbc-full",
137 | link: "/mysql",
138 | },
139 | {
140 | text: "Redis",
141 | icon: "redis",
142 | link: "/redis",
143 | },
144 | ],
145 | },
146 |
147 | {
148 | text: "编程语言基础",
149 | icon: "biancheng-01",
150 | collapsible: true,
151 |
152 | children: [
153 | {
154 | text: "golang",
155 | icon: "Goyuyan",
156 | link: "/golang",
157 | },
158 | {
159 | text: "c++",
160 | icon: "cyuyan",
161 | link: "/cpp",
162 | },
163 | {
164 | text: "java",
165 | icon: "java",
166 | link: "/java",
167 | },
168 | ],
169 | },
170 |
171 | {
172 | text: "中间件",
173 | icon: "gongju",
174 | collapsible: true,
175 | children: [
176 | {
177 | text: "RabbitMQ",
178 | icon: "RabbitMQ",
179 | link: "/rabbitmq",
180 | },
181 | {
182 | text: "Nginx",
183 | icon: "nginx",
184 | link: "/nginx",
185 | },
186 |
187 | {
188 | text: "Kubernetes",
189 | icon: "kubernetes",
190 | link: "/k8s",
191 | },
192 | ],
193 | },
194 |
195 | ],
196 | });
197 |
--------------------------------------------------------------------------------
/src/redis/data-structure.md:
--------------------------------------------------------------------------------
1 |
2 | ### Redis数据类型?
3 |
4 | 主要有STRING,LIST,ZSET,SET,HASH。
5 |
6 | **STRING**
7 |
8 | String类型的底层的数据结构实现主要是SDS(简单动态字符串)。应用场景主要有:
9 |
10 | - 缓存对象:例如可以用STRING缓存整个对象的JSON。
11 | - 计数:Redis处理命令是单线程,所以执行命令的过程是原子的,因此String数据类型适合计数场景,比如计算访问次数、点赞、转发、库存数量等等。
12 | - 分布式锁:可以利用SETNX命令。
13 | - 共享Session信息:服务器都会去同一个Redis获取相关的Session信息,解决了分布式系统下Session存储的问题。
14 |
15 | **LIST**
16 |
17 | List 类型的底层数据结构是由**双向链表或压缩列表**实现的:
18 |
19 | - 如果列表的元素个数小于 512 个,列表每个元素的值都小于 64 字节,Redis 会使用**压缩列表**作为 List 类型的底层数据结构;
20 | - 如果列表的元素不满足上面的条件,Redis 会使用**双向链表**作为 List 类型的底层数据结构;
21 |
22 | 在 Redis 3.2 版本之后,List 数据类型底层数据结构只由 quicklist 实现,替代了双向链表和压缩列表。在 Redis 7.0 中,压缩列表数据结构被废弃,由 listpack 来实现。应用场景主要有:
23 |
24 | - **微信朋友圈点赞**:要求按照点赞顺序显示点赞好友信息,如果取消点赞,移除对应好友信息。
25 | - **消息队列**:可以使用左进右出的命令组成来完成队列的设计。比如:数据的生产者可以通过Lpush命令从左边插入数据,多个数据消费者,可以使用BRpop命令阻塞的”抢”列表尾部的数据。
26 |
27 | **HASH**
28 |
29 | Hash 类型的底层数据结构是由压缩列表或哈希表实现的:
30 |
31 | - 如果哈希类型元素个数小于 512 个,所有值小于 64 字节的话,Redis 会使用压缩列表作为 Hash 类型的底层数据结构;
32 | - 如果哈希类型元素不满足上面条件,Redis 会使用哈希表作为 Hash 类型的底层数据结构。
33 |
34 | 在Redis 7.0 中,压缩列表数据结构被废弃,交由 listpack 来实现。应用场景主要有:
35 |
36 | - **缓存对象**:一般对象用 String + Json 存储,对象中某些频繁变化的属性可以考虑抽出来用 Hash 类型存储。
37 | - **购物车**:以用户 id 为 key,商品 id 为 field,商品数量为 value,恰好构成了购物车的3个要素。
38 |
39 | **SET**
40 |
41 | Set 类型的底层数据结构是由**哈希表或整数集合**实现的:
42 |
43 | - 如果集合中的元素都是整数且元素个数小于 512个,Redis 会使用**整数集合**作为 Set 类型的底层数据结构;
44 | - 如果集合中的元素不满足上面条件,则 Redis 使用**哈希表**作为 Set 类型的底层数据结构。
45 |
46 | 应用场景主要有:
47 |
48 | - **点赞**:key 是文章id,value 是用户id。
49 | - **共同关注**:Set 类型支持交集运算,所以可以用来计算共同关注的好友、公众号等。key 可以是用户id,value 则是已关注的公众号的id。
50 | - **抽奖活动**:存储某活动中中奖的用户名 ,Set 类型因为有去重功能,可以保证同一个用户不会中奖两次。
51 |
52 | ::: warning 提示
53 |
54 | Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞。在主从集群中,为了避免主库因为 Set 做聚合计算(交集、差集、并集)时导致主库被阻塞,可以选择一个从库完成聚合统计,或者把数据返回给客户端,由客户端来完成聚合统计。
55 |
56 | :::
57 |
58 | **Zset**
59 |
60 | Zset类型(Sorted Set,有序集合)可以根据元素的权重来排序,可以自己来决定每个元素的权重值。比如说,可以根据元素插入Sorted Set 的时间确定权重值,先插入的元素权重小,后插入的元素权重大。应用场景主要有:
61 |
62 | - 在面对需要展示最新列表、排行榜等场景时,如果数据更新频繁或者需要分页显示,可以优先考虑使用 Zset。
63 |
64 | - **排行榜**:有序集合比较典型的使用场景就是排行榜。例如学生成绩的排名榜、游戏积分排行榜、视频播放排名、电商系统中商品的销量排名等。
65 |
66 | **BitMap**
67 |
68 | bit 是计算机中最小的单位,使用它进行储存将非常节省空间,特别适合一些数据量大且使用二值统计的场景。可以用于签到统计、判断用户登陆态等操作。
69 |
70 | **HyperLogLog**
71 |
72 | HyperLogLog用于基数统计,统计规则是基于概率完成的,不准确,标准误算率是 0.81%。优点是,在输入元素的数量或者体积非常非常大时,所需的内存空间总是固定的、并且很小。比如百万级网页 UV 计数等;
73 |
74 | **GEO**
75 |
76 | 主要用于存储地理位置信息,并对存储的信息进行操作。底层是由Zset实现的,使用GeoHash编码方法实现了经纬度到Zset中元素权重分数的转换,这其中的两个关键机制就是「对二维地图做区间划分」和「对区间进行编码」。一组经纬度落在某个区间后,就用区间的编码值来表示,并把编码值作为Zset元素的权重分数。
77 |
78 | **Stream**
79 |
80 | Redis专门为消息队列设计的数据类型。相比于基于 List 类型实现的消息队列,有这两个特有的特性:自动生成全局唯一消息ID,支持以消费组形式消费数据。
81 |
82 | 之前方法缺陷:不能持久化,无法可靠的保存消息,并且对于离线重连的客户端不能读取历史消息。
83 |
84 |
85 |
86 | ### Redis底层数据结构?
87 |
88 | **SDS**
89 |
90 | SDS 不仅可以保存文本数据,还可以保存二进制数据。
91 |
92 | O(1)复杂度获取字符串长度,因为有Len属性。
93 |
94 | 不会发生缓冲区溢出,因为 SDS 在拼接字符串之前会检查空间是否满足要求,如果空间不够会自动扩容,所以不会导致缓冲区溢出的问题。
95 |
96 | **链表**
97 |
98 | 节点是一个双向链表,在双向链表基础上封装了listNode这个数据结构。包括链表节点数量 len、以及可以自定义实现的 dup、free、match 函数。
99 |
100 | - listNode 链表节点的结构里带有 prev 和 next 指针,获取某个节点的前置节点或后置节点的时间复杂度只需O(1),而且这两个指针都可以指向 NULL,所以链表是无环链表;
101 | - list 结构因为提供了表头指针 head 和表尾节点 tail,所以获取链表的表头节点和表尾节点的时间复杂度只需O(1);
102 |
103 | 缺陷:
104 |
105 | - 链表每个节点之间的内存都是不连续的,无法很好利用 CPU 缓存。能很好利用CPU缓存的数据结构是数组,因为数组的内存是连续的。
106 | - 保存一个链表节点的值都需要一个链表节点结构头的分配,内存开销较大。
107 |
108 | **压缩列表**
109 |
110 | 压缩列表是由连续内存块组成的顺序型数据结构,类似于数组。不仅可以利用 CPU 缓存,而且会针对不同长度的数据,进行相应编码,这种方法可以有效地节省内存开销。不能保存过多的元素,否则查询效率就会降低;新增或修改某个元素时,压缩列表占用的内存空间需要重新分配,甚至可能引发连锁更新的问题。
111 |
112 | **缺陷:**
113 |
114 | - 空间扩展操作也就是重新分配内存,因此连锁更新一旦发生,就会导致压缩列表占用的内存空间要多次重新分配,直接影响到压缩列表的访问性能。
115 |
116 | - 如果保存的元素数量增加了,或是元素变大了,会导致内存重新分配,会有连锁更新的问题。
117 |
118 | - 压缩列表只会用于保存的节点数量不多的场景,只要节点数量足够小,即使发生连锁更新也能接受。
119 |
120 | **哈希**
121 |
122 | 哈希表是一种保存键值对(key-value)的数据结构。优点在于能以O(1)的复杂度快速查询数据。Redis 采用了拉链法来解决哈希冲突,在不扩容哈希表的前提下,将具有相同哈希值的数据串起来,形成链接。渐进式哈希的过程如下:
123 |
124 | Redis定义一个dict结构体,这个结构体里定义了**两个哈希表(ht[2])**。
125 |
126 | - 给ht2分配空间;
127 | - 在 rehash 进行期间,每次哈希表元素进行新增、删除、查找或者更新操作时,Redis 除了会执行对应的操作之外,还会顺序将ht1中索引位置上的所有数据迁移到ht2上;
128 | - 随着处理客户端发起的哈希表操作请求数量越多,最终在某个时间点会把「哈希表 1 」的所有 key-value 迁移到「哈希表 2」,从而完成 rehash 操作。
129 |
130 | ::: tip 渐进式哈希的触发条件?
131 |
132 | **触发条件**:
133 |
134 | 负载因子 = 哈希表已保存节点数/哈希表大小
135 |
136 | 当负载因子大于等于 1 ,没有执行 RDB 快照或没有进行 AOF 重写的时候,就会进行 rehash 操作。
137 |
138 | 当负载因子大于等于 5 时,此时说明哈希冲突非常严重了,不管有没有有在执行 RDB 快照或 AOF 重写,都会强制进行 rehash 操作。
139 |
140 | :::
141 |
142 | **跳表**
143 |
144 | 一种多层的有序链表,能快读定位数据。当数据量很大时,跳表的查找复杂度就是O(logN)。
145 |
146 | 节点同时保存元素和元素的权重,每个跳表节点都有一个后向指针,指向前一个节点,目的是为了方便从跳表的尾节点开始访问节点,为了倒序查找时方便。跳表是一个带有层级关系的链表,而且每一层级可以包含多个节点,每一个节点通过指针连接起来。Zset数组中一个属性是level数组,一个level数组就代表跳表的一层,定义了指向下一个节点的指针和跨度。
147 |
148 | ::: tip 跳表的查找过程?
149 |
150 | 查找一个跳表节点的过程时,跳表会从头节点的最高层开始,逐一遍历每一层。在遍历某一层的跳表节点时,会用跳表节点中的 SDS 类型的元素和元素的权重来进行判断:
151 |
152 | - 如果当前节点的权重小于要查找的权重时,跳表就会访问该层上的下一个节点。
153 | - 如果当前节点的权重等于要查找的权重时,并且当前节点的 SDS 类型数据小于要查找的数据时,跳表就会访问该层上的下一个节点。
154 |
155 | 如果上面两个条件都不满足,或者下一个节点为空时,跳表就会使用目前遍历到的节点的 level 数组里的下一层指针,然后沿着下一层指针继续查找。
156 |
157 | :::
158 |
159 | 跳表的相邻两层的节点数量的比例会影响跳表的查询性能。相邻两层的节点数量最理想的比例是 2:1,查找复杂度可以降低到 O(logN)。为了防止插入删除时间消耗,跳表在创建节点的时候,随机生成每个节点的层数。具体的做法是,跳表在创建节点时候,会生成范围为[0-1]的一个随机数,如果这个随机数小于 0.25(相当于概率 25%),那么层数就增加 1 层,然后继续生成下一个随机数,直到随机数的结果大于 0.25 结束,最终确定该节点的层数。
160 |
161 | **整数集合**
162 |
163 | 整数集合本质上是一块连续内存空间。
164 |
165 | 整数集合有一个升级规则,就是当将一个新元素加入到整数集合里面,如果新元素的类型(int32_t)比整数集合现有所有元素的类型(int16_t)都要长时,整数集合需要先进行升级,也就是按新元素的类型(int32_t)扩展 contents 数组的空间大小,然后才能将新元素加入到整数集合里,升级的过程中也要维持整数集合的有序性。
166 |
167 | **quicklist**
168 |
169 | 其实 quicklist 就是双向链表 + 压缩列表组合,quicklist 就是一个链表,而链表中的每个元素又是一个压缩列表。quicklist 解决办法,通过控制每个链表节点中的压缩列表的大小或者元素个数,来规避连锁更新的问题。因为压缩列表元素越少或越小,连锁更新带来的影响就越小,从而提供了更好的访问性能。
170 |
171 | **listpack**
172 |
173 | listpack 没有压缩列表中记录前一个节点长度的字段了,listpack 只记录当前节点的长度,当向 listpack 加入一个新元素的时候,不会影响其他节点的长度字段的变化,从而避免了压缩列表的连锁更新问题。
174 |
175 |
176 |
177 | ### 为什么用跳表而不用平衡树?
178 |
179 | **从内存占用上来比较,跳表比平衡树更灵活一些**:平衡树每个节点包含 2 个指针(分别指向左右子树),而跳表每个节点包含的指针数目平均为 1/(1-p),如果像 Redis里的实现一样,取 p=1/4,那么平均每个节点包含 1.33 个指针,比平衡树更有优势。
180 |
181 | **在做范围查找的时候,跳表比平衡树操作要简单**:在平衡树上,找到指定范围的小值之后,还需要以中序遍历的顺序继续寻找其它不超过大值的节点。如果不对平衡树进行一定的改造,这里的中序遍历并不容易实现。而在跳表上进行范围查找就非常简单,只需要在找到小值之后,对第 1 层链表进行若干步的遍历就可以实现。
182 |
183 | **从算法实现难度上来比较,跳表比平衡树要简单得多**。平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而跳表的插入和删除只需要修改相邻节点的指针,操作简单又快速。
184 |
--------------------------------------------------------------------------------
/src/java/jvm.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Java
3 | author: xmy
4 | ---
5 |
6 | ### 内存区域
7 | 
8 |
9 | HotSpot在JDK1.8之前方法区就是永久代,永久代就是方法区。
10 |
11 | JDK1.8后删除了永久代,改为元空间,元空间在直接内存中。方法区就是元空间,元空间就是方法区。
12 |
13 | 创建一个线程,JVM就会为其分配一个私有内存空间,其中包括PC、虚拟机栈和本地方法栈
14 |
15 | **PC**
16 |
17 | 用来指示下一个执行的字节码指令,基于这一点就能实现代码的控制流程
18 |
19 | 为了确保每个线程切换回来都能从上次的位置继续运行,PC必须是线程私有的,切换出去时需保存各自的PC
20 |
21 | **虚拟机栈**
22 |
23 | 虚拟机栈中一个栈帧压入就对应一个方法的调用,栈帧弹出就对应方法返回。栈帧中包含:局部变量表、操作数栈、动态链接、方法出口信息。
24 |
25 | 局部变量表也就是常说的栈内存,用来存储基本类型和引用
26 |
27 | HotSpot不支持动态扩展虚拟机栈,在创建线程时就确定了虚拟机栈的最大深度,如果申请不了这么多内存,就会抛出OOM错误,如果线程在运行时调用了很多方法,到达了栈的最大深度,就会抛出SOF错误
28 |
29 | **本地方法栈**
30 |
31 | 和虚拟机栈相同,区别仅在于虚拟机栈中是java方法,本地方法栈中是native方法,但HotSpot中已经将二者合而为一了。
32 |
33 | **堆**
34 |
35 | JVM中最大的一块内存空间,所有对象实例和数组都在这里分配内存,所有线程共享堆内存。
36 |
37 | JDK1.7开始默认开启了逃逸分析,如果一个对象只在一个线程中被引用了,则该对象可以直接在栈上分配内存空间。
38 |
39 | 堆也叫GC堆,是垃圾回收的主要区域。为了便于垃圾回收,JDK1.8之前将堆分为三个部分:
40 |
41 | 1. 新生代
42 | 2. 老年代
43 | 3. 永久代
44 |
45 | 而1.8之后将永久代删除了,取而代之的是元空间,元空间则在直接内存中。
46 |
47 | 此外,新生代还细分为eden、from survivor(s0)和to survivor(s1)
48 |
49 | 当新对象实例产生时,年龄为0,首先被分配在eden里,在一次gc后,如果还存活,就被扔到survivor里,并且年龄+1,当年龄增加到一定程度后就被扔到老年代里。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。
50 |
51 | **方法区**
52 |
53 | 存放被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
54 |
55 | 1.8之前是永久代,属于堆内存。1.8之后是元空间,属于直接内存。
56 |
57 | 永久代受JVM创建时分配的最大堆内存限制,而元空间则受系统内存限制,可以存储更多。
58 |
59 | **常量池**
60 |
61 | 分为字符串常量池和运行时常量池
62 |
63 | 1.8之后字符串常量池在堆中,而运行时常量池在元空间
64 |
65 | **直接内存**
66 |
67 | 在JVM进程的内存空间之外,属于系统内存。
68 |
69 | JVM可通过native方法对其进行直接操作,而无需在使用时将其拷贝到JVM内存区。
70 |
71 | ### 对象创建过程
72 | 
73 |
74 | 1. **类加载检查:**
75 |
76 | JVM遇到一条new指令时,先检查能不能在常量池中定位到该类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化。如果没有就要先进行类加载。类已被加载就通过检查。
77 |
78 | 2. **分配内存:**
79 |
80 | 类加载检查通过后JVM为新对象分配内存,对象所需的内存大小在类加载完成后就确定了,JVM会在堆中按照**指针碰撞**或**空闲列表**的方式为对象划分出一块空间,选择哪种方式会根据垃圾收集器的算法而定。此外,内存分配还要保证线程安全,JVM采用**CAS+失败重试**或**TLAB**的方式保证线程安全。
81 |
82 | CAS+失败重试:乐观锁的一种实现,每次占用资源不加锁,而是不断尝试占用。
83 |
84 | TLAB:线程创建时预先在堆中给线程分配一块内存,称为TLAB,专门用来存放该线程运行过程中创建的对象,而TLAB满了时,采用上述CAS在堆的其它内存中分配
85 |
86 | 3. **初始化零值:**
87 |
88 | 将对象的字段设为默认零值,不包括对象头
89 |
90 | 4. **设置对象头:**
91 |
92 | 在对象头中设置这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄、是否启用偏向锁等信息
93 |
94 | 5. **执行init方法:**
95 |
96 | 初始化对象,即按照程序员写的构造方法给对象进行初始化。
97 | ### GC
98 |
99 | **内存分配与回收**
100 |
101 | 新对象优先被分配在eden里,年龄设置为0,经历第一次gc后如果还存活,就被扔到survivor中,并且年龄+1,随后每经历一次gc如果还存活就年龄+1,如果年龄超过了上限(默认15),就被扔到老年代中。通过-XX:MaxTenuringThreshold设置上限。
102 |
103 | 此外,JVM还有动态年龄判定机制:如果在survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无需等到年龄超过上线。
104 |
105 | 如果是过大的对象,为了避免其来回复制,可以在创建时直接扔到老年代里。通过-XX:PretenureSizeThreshold设置,只支持Serial和ParNew。
106 |
107 | 
108 |
109 | hotspot中gc分为两类:部分收集partial gc和全收集full gc。
110 |
111 | 部分收集又分minor gc、major gc和mixed gc
112 |
113 | minor gc:只对新生代进行回收
114 |
115 | major gc:只对老年代进行回收(有时也指代full gc)
116 |
117 | mixed gc:对整个新生代和部分老年代进行回收
118 |
119 | 全收集full gc:对整个堆和方法区(hotspot中的元空间)进行回收
120 |
121 | **判别对象、常量、类死亡的方法**
122 |
123 | - **对象**
124 |
125 | 1. **引用计数法:**
126 |
127 | 对象中设置一个引用计数器,每当该对象被引用时,引用计数器就会+1,失去一个引用时就会-1。引用计数器为0时就代表已经死亡,不会再被引用了。这种判别方式有个缺点,如果两个对象互相引用,但又没有外界对它们的引用,则它们引用计数都为1,会一直存在,但没有意义。
128 |
129 | 2. **可达性分析法:**
130 |
131 | 设置一组对象为**gc roots**,如果一个对象没有能到达任何一个gc root的引用链,则判别这个对象死亡。一般一个线程启动后并列创建的一组对象会构成gc roots,gc roots内部引用的对象就是非gc root。
132 |
133 | - **常量**
134 |
135 | 没有被任何对象引用时就是废弃的
136 |
137 | - **类**
138 |
139 | 同时满足如下三点就是无用的类
140 |
141 | 1. 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
142 | 2. 加载该类的 ClassLoader 已经被回收。
143 | 3. 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类
144 | 的方法。
145 |
146 | **引用类型都有哪些?**
147 | 1. **强引用**
148 |
149 | ```java
150 | Object strong = new Object();
151 | ```
152 |
153 | 一个对象如果被引用,且最高级别是强引用,就不会被回收。
154 |
155 | 2. **软引用**
156 |
157 | ```java
158 | SoftReference