1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

[feat]🔥 基于 vuepress 重构整个项目,提升阅读体验

This commit is contained in:
guide 2021-11-09 18:47:58 +08:00
parent 23efacc28e
commit dc45389934
308 changed files with 5795 additions and 4229 deletions

4
.gitattributes vendored
View File

@ -1,4 +0,0 @@
* text=auto
*.js linguist-language=java
*.css linguist-language=java
*.html linguist-language=java

38
.gitignore vendored
View File

@ -1,38 +1,2 @@
.gradle
/build/
/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
/out/
/**/out/
.shelf/
.ideaDataSources/
dataSources/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/node_modules/
### OS ###
.DS_Store
.Ds_Store´
/node_modules
/package-lock.json

0
.nojekyll Normal file → Executable file
View File

201
LICENSE
View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

802
README.md Normal file → Executable file
View File

@ -1,432 +1,370 @@
👉 [阿里云双11服务器新人优惠2核2g 一年仅需58元数量有限速抢](https://www.aliyun.com/minisite/goods?taskPkg=1111ydsrwb&pkgSid=1532&recordId=959605&userCode=hf47liqn)
👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://zhuanlan.zhihu.com/p/379041500) (原创不易,欢迎点赞,精简版学习路线正在路上),这是 2021 最新最完善的 Java 学习路线!另外,[我的朋友整理了一份消息队列常见面试题,需要的小伙伴可以点击领取!](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100025985&idx=1&sn=681af486050fabbeea27fa1c3bec5d65&chksm=4ea1e94a79d6605c72f280b5268100c6e96c6ab1dc9a0178b33e25a72ff5f4eac3dcb56fa44f#rd)。
👉 推荐 [在线阅读](https://snailclimb.gitee.io/javaguide) (Github 访问速度比较慢可能会导致部分图片无法刷新出来)
👉 书单已经被移动到 [awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。
👉 [朋友开源的面试八股文系列](https://github.com/csguide-dabai/interview-guide)。
> 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。
> 2. **贡献指南** :欢迎参与 [JavaGuide的维护工作](https://github.com/Snailclimb/JavaGuide/issues/1235),这是一件非常有意义的事情。
> 3. **PDF版本** [《JavaGuide 面试突击版》PDF 版本](#公众号) 。
> 4. **图解计算机基础** [图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。
> 5. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。
> 6. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java面试进阶指北 》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7) (质量很高,专为面试打造,星球用户免费)
> 7. **转载须知** 以下所有文章如非文首说明皆为我Guide哥的原创转载在文首注明出处如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️
<p align="center">
<a href="https://github.com/Snailclimb/JavaGuide" target="_blank">
<img src="https://img-blog.csdnimg.cn/img_convert/1c00413c65d1995993bf2b0daf7b4f03.png#pic_center" width=""/>
</a>
</p>
<p align="center">
<a href="https://snailclimb.gitee.io/javaguide"><img src="https://img.shields.io/badge/阅读-read-brightgreen.svg" alt="阅读"></a>
<a href="#公众号"><img src="https://img.shields.io/badge/%E5%85%AC%E4%BC%97%E5%8F%B7-JavaGuide-lightgrey.svg" alt="公众号"></a>
<a href="#公众号"><img src="https://img.shields.io/badge/PDF-Java面试突击-important.svg" alt="公众号"></a>
<a href="#投稿"><img src="https://img.shields.io/badge/support-投稿-critical.svg" alt="投稿"></a>
<img src="https://img.shields.io/github/stars/Snailclimb/JavaGuide" alt="投稿">
<a href="https://xiaozhuanlan.com/javainterview?rel=javaguide"><img src="https://img.shields.io/badge/Java-面试指南-important" alt="投稿"></a>
</p>
<h3 align="center">Sponsor</h3>
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://t.1yb.co/iskv">
<img src="./media/sponsor/知识星球.png" style="margin: 0 auto;width:850px" /></a>
</td>
</tr>
</tbody>
</table>
## Java
### 基础
**知识点/面试题** : (必看:+1: )[Java 基础知识点/面试题总结](docs/java/basis/Java基础知识.md)
**重要知识点详解:**
3. [什么是反射机制?反射机制的应用场景有哪些?](docs/java/basis/反射机制.md)
4. [代理模式详解:静态代理+JDK/CGLIB 动态代理实战](docs/java/basis/代理模式详解.md)
5. [常见的 IO 模型有哪些Java 中的 BIO、NIO、AIO 有啥区别?](docs/java/basis/IO模型.md)
### 集合
1. **[Java 集合常见问题总结](docs/java/collection/java集合框架基础知识&面试题总结.md)** (必看 :+1:)
2. [Java 容器使用注意事项总结](docs/java/collection/java集合使用注意事项总结.md)
3. **源码分析** [ArrayList 源码+扩容机制分析](docs/java/collection/arraylist-source-code.md) 、[LinkedList 源码](docs/java/collection/linklist-source-code.md) 、[HashMap(JDK1.8)源码+底层数据结构分析](docs/java/collection/hashmap-source-code.md) 、[ConcurrentHashMap 源码+底层数据结构分析](docs/java/collection/concurrent-hash-map-source-code.md)
### 并发
**知识点/面试题:** (必看 :+1:)
1. **[Java 并发基础常见面试题总结](docs/java/multi-thread/java并发基础常见面试题总结.md)**
2. **[Java 并发进阶常见面试题总结](docs/java/multi-thread/java并发进阶常见面试题总结.md)**
**重要知识点详解:**
1. **线程池**[Java 线程池学习总结](./docs/java/multi-thread/java线程池学习总结.md)、[拿来即用的 Java 线程池最佳实践](./docs/java/multi-thread/拿来即用的java线程池最佳实践.md)
2. [ThreadLocal 关键字解析](docs/java/multi-thread/threadlocal.md)
3. [Java 并发容器总结](docs/java/multi-thread/并发容器总结.md)
4. [Atomic 原子类总结](docs/java/multi-thread/atomic原子类总结.md)
5. [AQS 原理以及 AQS 同步组件总结](docs/java/multi-thread/aqs原理以及aqs同步组件总结.md)
6. [CompletableFuture入门](docs/java/multi-thread/completablefuture-intro.md)
### JVM (必看 :+1:)
JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle.com/javase/specs/jvms/se8/html/index.html) 和周志明老师的[《深入理解Java虚拟机第3版](https://book.douban.com/subject/34907497/) (强烈建议阅读多遍!)。
1. **[Java 内存区域](docs/java/jvm/内存区域.md)**
2. **[JVM 垃圾回收](docs/java/jvm/jvm垃圾回收.md)**
3. [JDK 监控和故障处理工具](docs/java/jvm/jdk监控和故障处理工具总结.md)
4. [类文件结构](docs/java/jvm/类文件结构.md)
5. **[类加载过程](docs/java/jvm/类加载过程.md)**
6. [类加载器](docs/java/jvm/类加载器.md)
7. **[【待完成】最重要的 JVM 参数总结(翻译完善了一半)](docs/java/jvm/jvm参数指南.md)**
9. **[【加餐】大白话带你认识 JVM](docs/java/jvm/[加餐]大白话带你认识jvm.md)**
### 新特性
1. **Java 8** [Java 8 新特性总结](docs/java/new-features/Java8新特性总结.md)、[Java8常用新特性总结](docs/java/new-features/java8-common-new-features.md) 、[Java 8 学习资源推荐](docs/java/new-features/Java8教程推荐.md)、[Java8 forEach 指南](docs/java/new-features/Java8foreach指南.md)
2. **Java9~Java15** : [一文带你看遍 JDK9~15 的重要新特性!](./docs/java/new-features/java新特性总结.md)
### 小技巧
1. [JAD 反编译](docs/java/tips/JAD反编译tricks.md)
2. [手把手教你定位常见 Java 性能问题](./docs/java/tips/locate-performance-problems/手把手教你定位常见Java性能问题.md)
## 计算机基础
👉 **[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。
### 操作系统
1. [操作系统常见问题总结!](docs/cs-basics/operating-system/basis.md)
2. [后端程序员必备的 Linux 基础知识总结](docs/cs-basics/operating-system/linux.md)
3. [Shell 编程入门](docs/cs-basics/operating-system/Shell.md)
### 网络
1. [计算机网络常见面试题](docs/cs-basics/network/计算机网络.md)
2. [计算机网络基础知识总结](docs/cs-basics/network/计算机网络知识总结.md)
### 数据结构
**图解数据结构:**
1. [线性数据结构 :数组、链表、栈、队列](docs/cs-basics/data-structure/线性数据结构.md)
2. [](docs/cs-basics/data-structure/图.md)
3. [](docs/cs-basics/data-structure/堆.md)
4. [](docs/cs-basics/data-structure/树.md) :重点关注[红黑树](docs/cs-basics/data-structure/红黑树.md)、B-B+B*树、LSM树
其他常用数据结构
1. [布隆过滤器](docs/cs-basics/data-structure/bloom-filter.md)
### 算法
算法这部分内容非常重要,如果你不知道如何学习算法的话,可以看下我写的:
- [算法学习书籍+资源推荐](https://www.zhihu.com/question/323359308/answer/1545320858) 。
- [如何刷Leetcode?](https://www.zhihu.com/question/31092580/answer/1534887374)
**常见算法问题总结**
- [几道常见的字符串算法题总结 ](docs/cs-basics/algorithms/几道常见的字符串算法题.md)
- [几道常见的链表算法题总结 ](docs/cs-basics/algorithms/几道常见的链表算法题.md)
- [剑指 offer 部分编程题](docs/cs-basics/algorithms/剑指offer部分编程题.md)
另外,[GeeksforGeeks]( https://www.geeksforgeeks.org/fundamentals-of-algorithms/) 这个网站总结了常见的算法 ,比较全面系统。
## 数据库
### MySQL
**总结:**
1. [数据库基础知识总结](docs/database/数据库基础知识.md)
2. **[MySQL知识点总结](docs/database/mysql/mysql知识点&面试题总结.md)** (必看 :+1:)
4. [一千行 MySQL 学习笔记](docs/database/mysql/a-thousand-lines-of-mysql-study-notes.md)
5. [MySQL 高性能优化规范建议](docs/database/mysql/mysql-high-performance-optimization-specification-recommendations.md)
**重要知识点:**
1. [MySQL数据库索引总结](docs/database/mysql/mysql-index.md)
2. [事务隔离级别(图文详解)](docs/database/mysql/transaction-isolation-level.md)
3. [MySQL三大日志(binlog、redo log和undo log)详解](docs/database/mysql/mysql-logs.md)
4. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/innodb-implementation-of-mvcc.md)
5. [一条 SQL 语句在 MySQL 中如何被执行的?](docs/database/mysql/how-sql-executed-in-mysql.md)
6. [字符集详解为什么不建议在MySQL中使用 utf8 ](docs/database/字符集.md)
7. [关于数据库中如何存储时间的一点思考](docs/database/mysql/some-thoughts-on-database-storage-time.md)
### Redis
1. [Redis 常见问题总结](docs/database/redis/redis-all.md)
2. [3种常用的缓存读写策略](docs/database/redis/3-commonly-used-cache-read-and-write-strategies.md)
## 搜索引擎
用于提高搜索效率,功能和浏览器搜索引擎类似。比较常见的搜索引擎是 Elasticsearch推荐 和 Solr。
## 系统设计
### 系统设计必备基础
#### RESTful API
我们在进行后端开发的时候,主要的工作就是为前端或者其他后端服务提供 API 比如查询用户数据的 API 。RESTful API 是一种基于 REST 构建的 API它是一种被设计的更好使用的 API。
相关阅读:[RestFul API 简明教程](docs/system-design/coding-way/RESTfulAPI简明教程.md)
#### 命名
编程过程中,一定要重视命名。因为好的命名即是注释,别人一看到你的命名就知道你的变量、方法或者类是做什么的!
相关阅读: [Java 命名之道](docs/system-design/naming.md) 。
### 常用框架
如果你没有接触过 Java Web 开发的话,可以先看一下我总结的 [《J2EE 基础知识》](docs/java/J2EE基础知识.md) 。虽然,这篇文章中的很多内容已经淘汰,但是可以让你对 Java 后台技术发展有更深的认识。
#### Spring/SpringBoot (必看 :+1:)
**知识点/面试题:**
1. **[Spring 常见问题总结](docs/system-design/framework/spring/Spring常见问题总结.md)**
2. **[SpringBoot 入门指南](https://github.com/Snailclimb/springboot-guide)**
**重要知识点详解:**
1. **[Spring/Spring Boot 常用注解总结!安排!](./docs/system-design/framework/spring/SpringBoot+Spring常用注解总结.md)**
2. **[Spring 事务总结](docs/system-design/framework/spring/Spring事务总结.md)**
3. [Spring 中都用到了那些设计模式?](docs/system-design/framework/spring/Spring-Design-Patterns.md)
4. **[SpringBoot 自动装配原理?”](https://www.cnblogs.com/javaguide/p/springboot-auto-config.html)**
#### MyBatis
- [MyBatis 常见面试题总结](docs/system-design/framework/mybatis/mybatis-interview.md)
#### Netty (必看 :+1:)
1. [剖析面试最常见问题之 Netty](https://xiaozhuanlan.com/topic/4028536971)
2. [剖析面试最常见问题之 Netty](https://xiaozhuanlan.com/topic/3985146207)
#### ZooKeeper
> 前两篇文章可能有内容重合部分,推荐都看一遍。
1. [【入门】ZooKeeper 相关概念总结](docs/system-design/distributed-system/zookeeper/zookeeper-intro.md)
2. [【进阶】ZooKeeper 相关概念总结](docs/system-design/distributed-system/zookeeper/zookeeper-plus.md)
3. [【实战】ZooKeeper 实战](docs/system-design/distributed-system/zookeeper/zookeeper-in-action.md)
### 安全
#### 认证授权
**[《认证授权基础》](docs/system-design/authority-certification/basis-of-authority-certification.md)** 这篇文章中我会介绍认证授权常见概念: **Authentication**,**Authorization** 以及 **Cookie**、**Session**、Token、**OAuth 2**、**SSO** 。如果你不清楚这些概念的话,建议好好阅读一下这篇文章。
- **JWT** JWTJSON Web Token是一种身份认证的方式JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。相关阅读:
- [JWT 优缺点分析以及常见问题解决方案](docs/system-design/authority-certification/JWT优缺点分析以及常见问题解决方案.md)
- [适合初学者入门 Spring Security With JWT 的 Demo](https://github.com/Snailclimb/spring-security-jwt-guide)
- **SSO(单点登录)** **SSO(Single Sign On)** 即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东家电等子系统。相关阅读:[**SSO 单点登录看这篇就够了!**](docs/system-design/authority-certification/SSO单点登录看这一篇就够了.md)
#### 数据脱敏
数据脱敏说的就是我们根据特定的规则对敏感信息数据进行变形,比如我们把手机号、身份证号某些位数使用 * 来代替。
### 定时任务
最近有朋友问到定时任务相关的问题。于是,我简单写了一篇文章总结一下定时任务的一些概念以及一些常见的定时任务技术选型:[《Java定时任务大揭秘》](./docs/system-design/Java定时任务大揭秘.md)
### 分布式
#### CAP 理论和 BASE 理论
CAP 也就是 Consistency一致性、Availability可用性、Partition Tolerance分区容错性 这三个单词首字母组合。关于 CAP 的详细解读请看:[《CAP理论解读》](docs/system-design/distributed-system/CAP理论.md)。
**BASE** 是 **Basically Available基本可用** 、**Soft-state软状态** 和 **Eventually Consistent最终一致性** 三个短语的缩写。BASE 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于 CAP 定理逐步演化而来的,它大大降低了我们对系统的要求。关于 BASE 的详细解读请看:[《BASE理论解读》](docs/system-design/distributed-system/BASE理论.md)。
#### Paxos 算法和 Raft 算法
**Paxos 算法**诞生于 1990 年,这是一种解决分布式系统一致性的经典算法 。但是,由于 Paxos 算法非常难以理解和实现不断有人尝试简化这一算法。到了2013 年才诞生了一个比 Paxos 算法更易理解和实现的分布式一致性算法—**Raft 算法**。
#### RPC
RPC 让调用远程服务调用像调用本地方法那样简单。
Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读:
- [Dubbo 常见问题总结](docs/system-design/distributed-system/rpc/Dubbo.md)
- [服务之间的调用为啥不直接用 HTTP 而用 RPC](docs/system-design/distributed-system/rpc/服务之间的调用为啥不直接用HTTP而用RPC.md)
#### API 网关
网关主要用于请求转发、安全认证、协议转换、容灾。
相关阅读:
- [为什么要网关?你知道有哪些常见的网关系统?](docs/system-design/distributed-system/api-gateway/api网关入门.md)
- [百亿规模API网关服务Shepherd的设计与实现](https://tech.meituan.com/2021/05/20/shepherd-api-gateway.html)
#### 分布式 id
在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。比如数据量太大之后,往往需要对数据进行分库分表,分库分表后需要有一个唯一 ID 来标识一条数据或消息,数据库的自增 ID 显然不能满足需求。相关阅读:[为什么要分布式 id ?分布式 id 生成方案有哪些?](docs/system-design/distributed/分布式ID.md)
#### 分布式事务
**分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。**
简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
### 微服务
1. [ 大白话入门 Spring Cloud](docs/system-design/micro-service/spring-cloud.md)
2. [微服务/分布式大厂真实面试问题解答](https://xiaozhuanlan.com/topic/2895047136)
### 高性能
#### 消息队列
消息队列在分布式系统中主要是为了解耦和削峰。相关阅读: [消息队列常见问题总结](docs/system-design/distributed-system/message-queue/message-queue.md)。
1. **RabbitMQ** : [RabbitMQ 入门](docs/system-design/distributed-system/message-queue/RabbitMQ入门看这一篇就够了.md)
2. **RocketMQ** : [RocketMQ 入门](docs/system-design/distributed-system/message-queue/RocketMQ.md)、[RocketMQ 的几个简单问题与答案](docs/system-design/distributed-system/message-queue/RocketMQ-Questions.md)
3. **Kafka** [Kafka 常见问题总结](docs/system-design/distributed-system/message-queue/Kafka常见面试题总结.md)
#### 读写分离&分库分表
读写分离主要是为了将数据库的读和写操作分不到不同的数据库节点上。主服务器负责写,从服务器负责读。另外,一主一从或者一主多从都可以。
读写分离可以大幅提高读性能,小幅提高写的性能。因此,读写分离更适合单机并发读请求比较多的场景。
分库分表是为了解决由于库、表数据量过大,而导致数据库性能持续下降的问题。
常见的分库分表工具有:`sharding-jdbc`(当当)、`TSharding`(蘑菇街)、`MyCAT`(基于 Cobar`Cobar`(阿里巴巴)...。 推荐使用 `sharding-jdbc`。 因为,`sharding-jdbc` 是一款轻量级 `Java` 框架,以 `jar` 包形式提供服务,不要我们做额外的运维工作,并且兼容性也很好。
相关阅读: [读写分离&分库分表常见问题总结](docs/system-design/读写分离&分库分表.md)
#### 负载均衡
负载均衡系统通常用于将任务比如用户请求处理分配到多个服务器处理以提高网站、应用或者数据库的性能和可靠性。
常见的负载均衡系统包括 3 种:
1. **DNS 负载均衡** :一般用来实现地理级别的均衡。
2. **硬件负载均衡** 通过单独的硬件设备比如 F5 来实现负载均衡功能(硬件的价格一般很贵)。
3. **软件负载均衡** :通过负载均衡软件比如 Nginx 来实现负载均衡功能。
### 高可用
高可用描述的是一个系统在大部分时间都是可用的,可以为我们提供服务的。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的 。
相关阅读: **《[如何设计一个高可用系统?要考虑哪些地方?](docs/system-design/high-availability/如何设计一个高可用系统要考虑哪些地方.md)》** 。
#### 限流
限流是从用户访问压力的角度来考虑如何应对系统故障。
限流为了对服务端的接口接受请求的频率进行限制,防止服务挂掉。比如某一接口的请求限制为 100 个每秒, 对超过限制的请求放弃处理或者放到队列中等待处理。限流可以有效应对突发请求过多。相关阅读:[限流算法有哪些?](docs/system-design/high-availability/limit-request.md)
#### 降级
降级是从系统功能优先级的角度考虑如何应对系统故障。
服务降级指的是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
#### 熔断
熔断和降级是两个比较容易混淆的概念,两者的含义并不相同。
降级的目的在于应对系统自身的故障,而熔断的目的在于应对当前系统依赖的外部系统或者第三方系统的故障。
#### 排队
另类的一种限流,类比于现实世界的排队。玩过英雄联盟的小伙伴应该有体会,每次一有活动,就要经历一波排队才能进入游戏。
#### 集群
相同的服务部署多份,避免单点故障。
#### 超时和重试机制
**一旦用户的请求超过某个时间得不到响应就结束此次请求并抛出异常。** 如果不进行超时设置可能会导致请求响应速度慢,甚至导致请求堆积进而让系统无法在处理请求。
另外,重试的次数一般设为 3 次,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合)。
#### 灾备设计和异地多活
**灾备** = 容灾+备份。
- **备份** 将系统所产生的的所有重要数据多备份几份。
- **容灾** 在异地建立两个完全相同的系统。当某个地方的系统突然挂掉,整个应用系统可以切换到另一个,这样系统就可以正常提供服务了。
**异地多活** 描述的是将服务部署在异地并且服务同时对外提供服务。和传统的灾备设计的最主要区别在于“多活”,即所有站点都是同时在对外提供服务的。异地多活是为了应对突发状况比如火灾、地震等自然或者认为灾害。
相关阅读:
- [搞懂异地多活,看这篇就够了](https://mp.weixin.qq.com/s/T6mMDdtTfBuIiEowCpqu6Q)
- [四步构建异地多活](https://mp.weixin.qq.com/s/hMD-IS__4JE5_nQhYPYSTg)
- [《从零开始学架构》— 28 | 业务高可用的保障:异地多活架构](http://gk.link/a/10pKZ)
### 大型网站架构
- [8 张图读懂大型网站技术架构](docs/system-design/website-architecture/8%20张图读懂大型网站技术架构.md)
- [关于大型网站系统架构你不得不懂的 10 个问题](docs/system-design/website-architecture/关于大型网站系统架构你不得不懂的10个问题.md)
## 工具
2. **Git** [Git 入门](docs/tools/Git.md)
3. **Github** [Github小技巧](docs/tools/Github技巧.md)
4. **Docker** : [Docker 基本概念解读](docs/tools/Docker.md) 、[Docker从入门到上手干事](docs/tools/Docker从入门到实战.md)
5. **IDEA** [IntelliJ IDEA 使用指南 | 必备插件推荐 | 插件开发入门 | 重构小技巧 | 源码阅读技巧](https://github.com/CodingDocs/awesome-idea-tutorial)。
## Java 学习常见问题汇总
1. [2021最新 Java 学习路线!凎!](https://www.zhihu.com/question/56110328/answer/869069586)
2. [Java 培训四个月能学会吗?](docs/questions/java-training-4-month.md)
3. [新手学习 Java有哪些 Java 相关的博客,专栏,和技术学习网站推荐?](docs/questions/java-learning-website-blog.md)
4. [Java 还是大数据,你需要了解这些东西!](docs/questions/java-big-data.md)
---
## 其他
### 贡献者
[你可以点此链接查看JavaGuide的所有贡献者。](https://github.com/Snailclimb/JavaGuide/graphs/contributors) 感谢你们让 JavaGuide 变得更好!如果你们来到武汉一定要找我,我请你们吃饭玩耍。
*悄悄话JavaGuide 会不定时为贡献者们送福利。*
### 待办
- [ ] 计算机网络知识点完善
- [ ] 分布式常见理论和算法总结完善
### 捐赠支持
项目的发展离不开你的支持,如果 JavaGuide 帮助到了你找到自己满意的 offer请作者喝杯咖啡吧 ☕ 后续会继续完善更新!加油!
[点击捐赠支持作者](https://www.yuque.com/snailclimb/dr6cvl/mr44yt#vu3ok)
### 联系我
![各种技术的学习路线](https://img-blog.csdnimg.cn/20210609102613344.png)
整理了一份各个技术的学习路线,需要的小伙伴加我微信:“**JavaGuide1996**”备注“**Github-学习路线**”即可!
![](https://img-blog.csdnimg.cn/20210609084555810.jpg)
### 公众号
如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号“**JavaGuide**”。
**《Java 面试突击》:** 由本文档衍生的专为面试而生的《Java 面试突击》V4.0 PDF 版本[公众号](#公众号)后台回复 **"面试突击"** 即可领取!
![我的公众号](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-08/167598cd2e17b8ec.png)
👉 [阿里云双11服务器新人优惠2核2g 一年仅需58元数量有限速抢](https://www.aliyun.com/minisite/goods?taskPkg=1111ydsrwb&pkgSid=1532&recordId=959605&userCode=hf47liqn)
👉 如果你不知道该学习什么的话,请看 [Java 学习线路图是怎样的?]( https://zhuanlan.zhihu.com/p/379041500) (原创不易,欢迎点赞,精简版学习路线正在路上),这是 2021 最新最完善的 Java 学习路线!另外,[我的朋友整理了一份消息队列常见面试题,需要的小伙伴可以点击领取!](http://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100025985&idx=1&sn=681af486050fabbeea27fa1c3bec5d65&chksm=4ea1e94a79d6605c72f280b5268100c6e96c6ab1dc9a0178b33e25a72ff5f4eac3dcb56fa44f#rd)。
👉 推荐 [在线阅读](https://snailclimb.gitee.io/javaguide) (Github 访问速度比较慢可能会导致部分图片无法刷新出来)
👉 书单已经被移动到 [awesome-cs](https://github.com/CodingDocs/awesome-cs) 这个仓库。
👉 [朋友开源的面试八股文系列](https://github.com/csguide-dabai/interview-guide)。
> 1. **介绍**:关于 JavaGuide 的相关介绍请看:[关于 JavaGuide 的一些说明](https://www.yuque.com/snailclimb/dr6cvl/mr44yt) 。
> 2. **贡献指南** :欢迎参与 [JavaGuide的维护工作](https://github.com/Snailclimb/JavaGuide/issues/1235),这是一件非常有意义的事情。
> 3. **PDF版本** [《JavaGuide 面试突击版》PDF 版本](#公众号) 。
> 4. **图解计算机基础** [图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd) 。
> 5. **知识星球** : 简历指导/Java学习/面试指导/面试小册。欢迎加入[我的知识星球](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) 。
> 6. **面试专版** :准备面试的小伙伴可以考虑面试专版:[《Java面试进阶指北 》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7) (质量很高,专为面试打造,星球用户免费)
> 7. **转载须知** 以下所有文章如非文首说明皆为我Guide哥的原创转载在文首注明出处如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!⛽️
<p align="center">
<a href="https://github.com/Snailclimb/JavaGuide" target="_blank">
<img src="https://img-blog.csdnimg.cn/img_convert/1c00413c65d1995993bf2b0daf7b4f03.png#pic_center" width=""/>
</a>
</p>
<p align="center">
<a href="https://snailclimb.gitee.io/javaguide"><img src="https://img.shields.io/badge/阅读-read-brightgreen.svg" alt="阅读"></a>
<img src="https://img.shields.io/github/stars/Snailclimb/JavaGuide" alt="stars">
</p>
<h3 align="center">Sponsor</h3>
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://t.1yb.co/iskv">
<img src="./media/sponsor/知识星球.png" style="margin: 0 auto;width:850px" /></a>
</td>
</tr>
</tbody>
</table>
## Java
### 基础
**知识点/面试题** : (必看:+1: )[Java 基础知识点/面试题总结](docs/java/basis/java基础知识总结.md)
**重要知识点详解:**
- [什么是反射机制?反射机制的应用场景有哪些?](docs/java/basis/反射机制详解.md)
- [代理模式详解:静态代理+JDK/CGLIB 动态代理实战](docs/java/basis/代理模式详解.md)
- [常见的 IO 模型有哪些Java 中的 BIO、NIO、AIO 有啥区别?](docs/java/basis/java基础知识总结)
### 集合
1. **[Java 集合常见问题总结](docs/java/collection/java集合框架基础知识&面试题总结.md)** (必看 :+1:)
2. [Java 容器使用注意事项总结](docs/java/collection/java集合使用注意事项总结.md)
3. **源码分析** [ArrayList 源码+扩容机制分析](docs/java/collection/arraylist-source-code.md) 、[HashMap(JDK1.8)源码+底层数据结构分析](docs/java/collection/hashmap-source-code.md) 、[ConcurrentHashMap 源码+底层数据结构分析](docs/java/collection/concurrent-hash-map-source-code.md)
### 并发
**知识点/面试题:** (必看 :+1:)
1. **[Java 并发基础常见面试题总结](docs/java/concurrent/java并发基础常见面试题总结.md)**
2. **[Java 并发进阶常见面试题总结](docs/java/concurrent/java并发进阶常见面试题总结.md)**
**重要知识点详解:**
1. **线程池**[Java 线程池学习总结](./docs/java/concurrent/java线程池学习总结.md)、[拿来即用的 Java 线程池最佳实践](./docs/java/concurrent/拿来即用的java线程池最佳实践.md)
2. [ThreadLocal 关键字解析](docs/java/concurrent/threadlocal.md)
3. [Java 并发容器总结](docs/java/concurrent/并发容器总结.md)
4. [Atomic 原子类总结](docs/java/concurrent/atomic原子类总结.md)
5. [AQS 原理以及 AQS 同步组件总结](docs/java/concurrent/aqs原理以及aqs同步组件总结.md)
6. [CompletableFuture入门](docs/java/concurrent/completablefuture-intro.md)
### JVM (必看 :+1:)
JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle.com/javase/specs/jvms/se8/html/index.html) 和周志明老师的[《深入理解Java虚拟机第3版](https://book.douban.com/subject/34907497/) (强烈建议阅读多遍!)。
1. **[Java 内存区域](docs/java/jvm/内存区域.md)**
2. **[JVM 垃圾回收](docs/java/jvm/jvm垃圾回收.md)**
3. [JDK 监控和故障处理工具](docs/java/jvm/jdk监控和故障处理工具总结.md)
4. [类文件结构](docs/java/jvm/类文件结构.md)
5. **[类加载过程](docs/java/jvm/类加载过程.md)**
6. [类加载器](docs/java/jvm/类加载器.md)
7. **[【待完成】最重要的 JVM 参数总结(翻译完善了一半)](docs/java/jvm/jvm参数指南.md)**
9. **[【加餐】大白话带你认识 JVM](docs/java/jvm/[加餐]大白话带你认识jvm.md)**
### 新特性
1. **Java 8** [Java 8 新特性总结](docs/java/new-features/Java8新特性总结.md)、[Java8常用新特性总结](docs/java/new-features/java8-common-new-features.md)
2. **Java9~Java15** : [一文带你看遍 JDK9~15 的重要新特性!](./docs/java/new-features/java新特性总结.md)
### 小技巧
1. [JAD 反编译](docs/java/tips/JAD反编译tricks.md)
2. [手把手教你定位常见 Java 性能问题](./docs/java/tips/locate-performance-problems/手把手教你定位常见Java性能问题.md)
## 计算机基础
👉 **[图解计算机基础 PDF 下载](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd)** 。
### 操作系统
1. [操作系统常见问题总结!](docs/cs-basics/operating-system/basis.md)
2. [后端程序员必备的 Linux 基础知识总结](docs/cs-basics/operating-system/linux.md)
3. [Shell 编程入门](docs/cs-basics/operating-system/Shell.md)
### 网络
1. [计算机网络常见面试题](docs/cs-basics/network/计算机网络.md)
2. [计算机网络基础知识总结](docs/cs-basics/network/计算机网络知识总结.md)
### 数据结构
**图解数据结构:**
1. [线性数据结构 :数组、链表、栈、队列](docs/cs-basics/data-structure/线性数据结构.md)
2. [](docs/cs-basics/data-structure/图.md)
3. [](docs/cs-basics/data-structure/堆.md)
4. [](docs/cs-basics/data-structure/树.md) :重点关注[红黑树](docs/cs-basics/data-structure/红黑树.md)、B-B+B*树、LSM树
其他常用数据结构
1. [布隆过滤器](docs/cs-basics/data-structure/bloom-filter.md)
### 算法
算法这部分内容非常重要,如果你不知道如何学习算法的话,可以看下我写的:
- [算法学习书籍+资源推荐](https://www.zhihu.com/question/323359308/answer/1545320858) 。
- [如何刷Leetcode?](https://www.zhihu.com/question/31092580/answer/1534887374)
**常见算法问题总结**
- [几道常见的字符串算法题总结 ](docs/cs-basics/algorithms/几道常见的字符串算法题.md)
- [几道常见的链表算法题总结 ](docs/cs-basics/algorithms/几道常见的链表算法题.md)
- [剑指 offer 部分编程题](docs/cs-basics/algorithms/剑指offer部分编程题.md)
另外,[GeeksforGeeks]( https://www.geeksforgeeks.org/fundamentals-of-algorithms/) 这个网站总结了常见的算法 ,比较全面系统。
## 数据库
### MySQL
**总结:**
1. [数据库基础知识总结](docs/database/数据库基础知识.md)
2. **[MySQL知识点总结](docs/database/mysql/mysql知识点&面试题总结.md)** (必看 :+1:)
4. [一千行 MySQL 学习笔记](docs/database/mysql/a-thousand-lines-of-mysql-study-notes.md)
5. [MySQL 高性能优化规范建议](docs/database/mysql/mysql-high-performance-optimization-specification-recommendations.md)
**重要知识点:**
1. [MySQL数据库索引总结](docs/database/mysql/mysql-index.md)
2. [事务隔离级别(图文详解)](docs/database/mysql/transaction-isolation-level.md)
3. [MySQL三大日志(binlog、redo log和undo log)详解](docs/database/mysql/mysql-logs.md)
4. [InnoDB存储引擎对MVCC的实现](docs/database/mysql/innodb-implementation-of-mvcc.md)
5. [一条 SQL 语句在 MySQL 中如何被执行的?](docs/database/mysql/how-sql-executed-in-mysql.md)
6. [字符集详解为什么不建议在MySQL中使用 utf8 ](docs/database/字符集.md)
7. [关于数据库中如何存储时间的一点思考](docs/database/mysql/some-thoughts-on-database-storage-time.md)
### Redis
1. [Redis 常见问题总结](docs/database/redis/redis-all.md)
2. [3种常用的缓存读写策略](docs/database/redis/3-commonly-used-cache-read-and-write-strategies.md)
## 搜索引擎
用于提高搜索效率,功能和浏览器搜索引擎类似。比较常见的搜索引擎是 Elasticsearch推荐 和 Solr。
## 系统设计
### 系统设计必备基础
#### RESTful API
我们在进行后端开发的时候,主要的工作就是为前端或者其他后端服务提供 API 比如查询用户数据的 API 。RESTful API 是一种基于 REST 构建的 API它是一种被设计的更好使用的 API。
相关阅读:[RestFul API 简明教程](docs/system-design/basis/RESTfulAPI.md)
#### 命名
编程过程中,一定要重视命名。因为好的命名即是注释,别人一看到你的命名就知道你的变量、方法或者类是做什么的!
相关阅读: [Java 命名之道](docs/system-design/naming.md) 。
### 常用框架
如果你没有接触过 Java Web 开发的话,可以先看一下我总结的 [《J2EE 基础知识》](docs/system-design/J2EE基础知识.md) 。虽然,这篇文章中的很多内容已经淘汰,但是可以让你对 Java 后台技术发展有更深的认识。
#### Spring/SpringBoot (必看 :+1:)
**知识点/面试题:**
1. **[Spring 常见问题总结](docs/system-design/framework/spring/Spring常见问题总结.md)**
2. **[SpringBoot 入门指南](https://github.com/Snailclimb/springboot-guide)**
**重要知识点详解:**
1. **[Spring/Spring Boot 常用注解总结!安排!](./docs/system-design/framework/spring/Spring&SpringBoot常用注解总结.md)**
2. **[Spring 事务总结](docs/system-design/framework/spring/Spring事务总结.md)**
3. [Spring 中都用到了那些设计模式?](docs/system-design/framework/spring/Spring设计模式总结.md)
4. **[SpringBoot 自动装配原理?”](docs/system-design/framework/spring/SpringBoot自动装配原理.md)**
#### MyBatis
[MyBatis 常见面试题总结](docs/system-design/framework/mybatis/mybatis-interview.md)
#### Spring Cloud
[ 大白话入门 Spring Cloud](docs/system-design/framework/springcloud/springcloud-intro.md)
### 安全
#### 认证授权
**[《认证授权基础》](docs/system-design/security/basis-of-authority-certification.md)** 这篇文章中我会介绍认证授权常见概念: **Authentication**,**Authorization** 以及 **Cookie**、**Session**、Token、**OAuth 2**、**SSO** 。如果你不清楚这些概念的话,建议好好阅读一下这篇文章。
- **JWT** JWTJSON Web Token是一种身份认证的方式JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。相关阅读:
- [JWT 优缺点分析以及常见问题解决方案](docs/system-design/security/jwt优缺点分析以及常见问题解决方案.md)
- [适合初学者入门 Spring Security With JWT 的 Demo](https://github.com/Snailclimb/spring-security-jwt-guide)
- **SSO(单点登录)** **SSO(Single Sign On)** 即单点登录说的是用户登陆多个子系统的其中一个就有权访问与其相关的其他系统。举个例子我们在登陆了京东金融之后,我们同时也成功登陆京东的京东超市、京东家电等子系统。相关阅读:[**SSO 单点登录看这篇就够了!**](docs/system-design/security/sso-intro.md)
#### 数据脱敏
数据脱敏说的就是我们根据特定的规则对敏感信息数据进行变形,比如我们把手机号、身份证号某些位数使用 * 来代替。
### 定时任务
最近有朋友问到定时任务相关的问题。于是,我简单写了一篇文章总结一下定时任务的一些概念以及一些常见的定时任务技术选型:[《Java定时任务大揭秘》](./docs/system-design/定时任务.md)
## 分布式
### CAP 理论和 BASE 理论
CAP 也就是 Consistency一致性、Availability可用性、Partition Tolerance分区容错性 这三个单词首字母组合。
**BASE** 是 **Basically Available基本可用** 、**Soft-state软状态** 和 **Eventually Consistent最终一致性** 三个短语的缩写。BASE 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于 CAP 定理逐步演化而来的,它大大降低了我们对系统的要求。
相关阅读:[CAP 理论和 BASE 理论解读](docs/distributed-system/理论&算法/cap&base理论.md)
### Paxos 算法和 Raft 算法
**Paxos 算法**诞生于 1990 年,这是一种解决分布式系统一致性的经典算法 。但是,由于 Paxos 算法非常难以理解和实现不断有人尝试简化这一算法。到了2013 年才诞生了一个比 Paxos 算法更易理解和实现的分布式一致性算法—**Raft 算法**。
### RPC
RPC 让调用远程服务调用像调用本地方法那样简单。
Dubbo 是一款国产的 RPC 框架,由阿里开源。相关阅读:
- [Dubbo 常见问题总结](docs/distributed-system/rpc/dubbo.md)
- [服务之间的调用为啥不直接用 HTTP 而用 RPC](docs/distributed-system/rpc/why-use-rpc.md)
### API 网关
网关主要用于请求转发、安全认证、协议转换、容灾。
相关阅读:
- [为什么要网关?你知道有哪些常见的网关系统?](docs/distributed-system/api-gateway.md)
- [百亿规模API网关服务Shepherd的设计与实现](https://tech.meituan.com/2021/05/20/shepherd-api-gateway.html)
### 分布式 id
在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。比如数据量太大之后,往往需要对数据进行分库分表,分库分表后需要有一个唯一 ID 来标识一条数据或消息,数据库的自增 ID 显然不能满足需求。相关阅读:[为什么要分布式 id ?分布式 id 生成方案有哪些?](docs/distributed-system/distributed-id.md)
### 分布式事务
**分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。**
简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
### 分布式协调
**ZooKeeper**
> 前两篇文章可能有内容重合部分,推荐都看一遍。
1. [【入门】ZooKeeper 相关概念总结](docs/distributed-system/分布式协调/zookeeper/zookeeper-intro.md)
2. [【进阶】ZooKeeper 相关概念总结](docs/distributed-system/分布式协调/zookeeper/zookeeper-plus.md)
3. [【实战】ZooKeeper 实战](docs/distributed-system/分布式协调/zookeeper/zookeeper-in-action.md)
## 高性能
### 消息队列
消息队列在分布式系统中主要是为了解耦和削峰。相关阅读: [消息队列常见问题总结](docs/high-performance/message-queue/message-queue.md)。
1. **RabbitMQ** : [RabbitMQ 入门](docs/high-performance/message-queue/rabbitmq-intro.md)
2. **RocketMQ** : [RocketMQ 入门](docs/high-performance/message-queue/rocketmq-intro)、[RocketMQ 的几个简单问题与答案](docs/high-performance/message-queue/rocketmq-questions.md)
3. **Kafka** [Kafka 常见问题总结](docs/high-performance/message-queue/kafka知识点&面试题总结.md)
### 读写分离&分库分表
读写分离主要是为了将数据库的读和写操作分不到不同的数据库节点上。主服务器负责写,从服务器负责读。另外,一主一从或者一主多从都可以。
读写分离可以大幅提高读性能,小幅提高写的性能。因此,读写分离更适合单机并发读请求比较多的场景。
分库分表是为了解决由于库、表数据量过大,而导致数据库性能持续下降的问题。
常见的分库分表工具有:`sharding-jdbc`(当当)、`TSharding`(蘑菇街)、`MyCAT`(基于 Cobar`Cobar`(阿里巴巴)...。 推荐使用 `sharding-jdbc`。 因为,`sharding-jdbc` 是一款轻量级 `Java` 框架,以 `jar` 包形式提供服务,不要我们做额外的运维工作,并且兼容性也很好。
相关阅读: [读写分离&分库分表常见问题总结](docs/high-performance/读写分离&分库分表.md)
### 负载均衡
负载均衡系统通常用于将任务比如用户请求处理分配到多个服务器处理以提高网站、应用或者数据库的性能和可靠性。
常见的负载均衡系统包括 3 种:
1. **DNS 负载均衡** :一般用来实现地理级别的均衡。
2. **硬件负载均衡** 通过单独的硬件设备比如 F5 来实现负载均衡功能(硬件的价格一般很贵)。
3. **软件负载均衡** :通过负载均衡软件比如 Nginx 来实现负载均衡功能。
## 高可用
高可用描述的是一个系统在大部分时间都是可用的,可以为我们提供服务的。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的 。
相关阅读: **《[如何设计一个高可用系统?要考虑哪些地方?](docs/high-availability/高可用系统设计.md)》** 。
### 限流
限流是从用户访问压力的角度来考虑如何应对系统故障。
限流为了对服务端的接口接受请求的频率进行限制,防止服务挂掉。比如某一接口的请求限制为 100 个每秒, 对超过限制的请求放弃处理或者放到队列中等待处理。限流可以有效应对突发请求过多。相关阅读:[何为限流?限流算法有哪些?](docs/high-availability/limit-request.md)
### 降级
降级是从系统功能优先级的角度考虑如何应对系统故障。
服务降级指的是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
### 熔断
熔断和降级是两个比较容易混淆的概念,两者的含义并不相同。
降级的目的在于应对系统自身的故障,而熔断的目的在于应对当前系统依赖的外部系统或者第三方系统的故障。
### 排队
另类的一种限流,类比于现实世界的排队。玩过英雄联盟的小伙伴应该有体会,每次一有活动,就要经历一波排队才能进入游戏。
### 集群
相同的服务部署多份,避免单点故障。
### 超时和重试机制
**一旦用户的请求超过某个时间得不到响应就结束此次请求并抛出异常。** 如果不进行超时设置可能会导致请求响应速度慢,甚至导致请求堆积进而让系统无法在处理请求。
另外,重试的次数一般设为 3 次,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合)。
### 灾备设计和异地多活
**灾备** = 容灾+备份。
- **备份** 将系统所产生的的所有重要数据多备份几份。
- **容灾** 在异地建立两个完全相同的系统。当某个地方的系统突然挂掉,整个应用系统可以切换到另一个,这样系统就可以正常提供服务了。
**异地多活** 描述的是将服务部署在异地并且服务同时对外提供服务。和传统的灾备设计的最主要区别在于“多活”,即所有站点都是同时在对外提供服务的。异地多活是为了应对突发状况比如火灾、地震等自然或者认为灾害。
相关阅读:
- [搞懂异地多活,看这篇就够了](https://mp.weixin.qq.com/s/T6mMDdtTfBuIiEowCpqu6Q)
- [四步构建异地多活](https://mp.weixin.qq.com/s/hMD-IS__4JE5_nQhYPYSTg)
- [《从零开始学架构》— 28 | 业务高可用的保障:异地多活架构](http://gk.link/a/10pKZ)

View File

@ -1,12 +0,0 @@
<p align="center">
<img src="./media/pictures/logo.png" width="200" height="200"/>
</p>
<h1 align="center">Java 学习/面试指南</h1>
[常用资源](https://shimo.im/docs/MuiACIg1HlYfVxrj/)
[GitHub](<https://github.com/Snailclimb/JavaGuide>)
[开始阅读](#java)

365
docs/.vuepress/config.js Normal file
View File

@ -0,0 +1,365 @@
const { config } = require("vuepress-theme-hope");
module.exports = config({
title: "JavaGuide",
description: "Java学习&&面试指南",
dest: "./dist",
head: [
[
"script",
{ src: "https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js" },
],
[
"script",
{
src: "https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js",
},
],
["script", { src: "https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js" }],
[
"script",
{ src: "https://cdn.jsdelivr.net/npm/@babel/standalone/babel.min.js" },
],
],
themeConfig: {
logo: "/logo.png",
hostname: "https://vuepress-theme-hope-demo.mrhope.site",
author: "Guide哥",
repo: "https://github.com/Snailclimb/JavaGuide",
nav: [
{ text: "Java面试指南", icon: "java", link: "/", },
{ text: "Java书单", icon: "book", link: "https://gitee.com/SnailClimb/awesome-cs", },
{ text: "Java学习路线", icon: "luxianchaxun", link: "https://zhuanlan.zhihu.com/p/379041500", },
{ text: "IDEA指南", icon: "intellijidea", link: "/idea-tutorial/", },
{ text: "开发工具", icon: "Tools", link: "/tools/", },
{
text: "PDF资源", icon: "file",
items: [
{ text: "JavaGuide面试突击版", link: "https://t.1yb.co/Fy1e", },
{ text: "消息队列常见知识点&面试题总结", link: "https://t.1yb.co/Fy0u", },
{ text: "图解计算机基础!", link: "https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100021725&idx=1&sn=2db9664ca25363139a81691043e9fd8f&chksm=4ea19a1679d61300d8990f7e43bfc7f476577a81b712cf0f9c6f6552a8b219bc081efddb5c54#rd" }
],
},
{
text: "关于作者", link: "/about-the-author/"
},
],
sidebar: {
"/about-the-author/": [
"internet-addiction-teenager", "feelings-after-one-month-of-induction-training"
],
// 应该把更精确的路径放置在前边
'/tools/': [
{
title: "数据库",
icon: "database",
prefix: "database/",
collapsable: false,
children: ["CHINER", "DBeaver", "screw"]
},
{
title: "Git",
icon: "git",
prefix: "git/",
collapsable: false,
children: ["git", "github小技巧"]
},
{
title: "Docker",
icon: "git",
prefix: "docker/",
collapsable: false,
children: ["docker", "docker从入门到实战"]
},
],
'/idea-tutorial/':
[
{
title: "IDEA小技巧",
icon: "creative",
prefix: "idea-tips/",
collapsable: false,
children: [
"idea-refractor-intro",
"idea-plug-in-development-intro",
"idea-source-code-reading-skills",
]
},
{
title: "IDEA插件推荐",
icon: "plugin",
collapsable: false,
prefix: "idea-plugins/",
children: [
"shortcut-key", "idea-themes", "improve-code", "interface-beautification",
"camel-case", "code-glance", "code-statistic",
"git-commit-template", "gson-format", "dea-features-trainer", "jclasslib",
"maven-helper", "rest-devlop", "save-actions", "sequence-diagram", "translation",
"others"
]
},
],
// 必须放在最后面
'/': [{
title: "Java", icon: "java", prefix: "java/",
children: [
{
title: "基础", prefix: "basis/",
children: [
"java基础知识总结",
{
title: "重要知识点",
children: ["反射机制详解", "代理模式详解", "io模型详解"],
},],
},
{
title: "容器", prefix: "collection/",
children: [
"java集合框架基础知识&面试题总结", "java集合使用注意事项总结",
{
title: "源码分析",
children: ["arraylist-source-code", "hashmap-source-code", "concurrent-hash-map-source-code"],
},],
},
{
title: "并发编程", prefix: "concurrent/",
children: [
"java并发基础常见面试题总结", "java并发进阶常见面试题总结",
{
title: "重要知识点",
children: ["java线程池学习总结", "并发容器总结", "拿来即用的java线程池最佳实践", "aqs原理以及aqs同步组件总结", "reentrantlock",
"atomic原子类总结", "threadlocal", "completablefuture-intro"],
},
],
},
{
title: "JVM", prefix: "jvm/",
children: ["内存区域", "jvm垃圾回收", "类文件结构", "类加载过程", "类加载器", "jvm参数指南", "[加餐]大白话带你认识jvm"],
},
{
title: "新特性", prefix: "new-features/",
children: ["java8-common-new-features", "java8新特性总结", "java新特性总结"],
},
{
title: "小技巧", prefix: "tips/",
children: ["locate-performance-problems/手把手教你定位常见Java性能问题", "jad反编译tricks"],
},
],
},
{
title: "计算机基础", icon: "computer", prefix: "cs-basics/",
children: [
{
title: "计算机网络", prefix: "network/", icon: "network",
children: [
"计算机网络常见面试题", "谢希仁老师的《计算机网络》内容总结", "HTTPS中的TLS"
],
},
{
title: "操作系统", prefix: "operating-system/", icon: "caozuoxitong",
children: [
"basis", "linux", "shell"
],
},
{
title: "数据结构", prefix: "data-structure/", icon: "people-network-full",
children: [
"线性数据结构", "图", "堆", "树", "红黑树", "bloom-filter"
],
},
{
title: "算法", prefix: "algorithms/", icon: "suanfaku",
children: [
"几道常见的字符串算法题", "几道常见的链表算法题", "剑指offer部分编程题"
],
},
],
},
{
title: "数据库", icon: "database", prefix: "database/",
children: [
"数据库基础知识",
"字符集",
{
title: "MySQL", prefix: "mysql/",
children: [
"mysql知识点&面试题总结",
"a-thousand-lines-of-mysql-study-notes",
"mysql-high-performance-optimization-specification-recommendations",
"mysql-index", "mysql-logs", "transaction-isolation-level",
"innodb-implementation-of-mvcc", "how-sql-executed-in-mysql",
"some-thoughts-on-database-storage-time"
],
},
{
title: "Redis", prefix: "redis/",
children: ["redis-all", "3-commonly-used-cache-read-and-write-strategies"],
},
],
},
{
title: "系统设计", icon: "xitongsheji", prefix: "system-design/",
children: [
{
title: "基础", prefix: "basis/", icon: "jibendebasic",
children: [
"RESTfulAPI",
"naming",
],
},
{
title: "常用框架", prefix: "framework/", icon: "framework",
children: [{
title: "Spring", prefix: "spring/",
children: ["Spring常见问题总结", "Spring&SpringBoot常用注解总结", "Spring事务总结", "Spring设计模式总结", "SpringBoot自动装配原理"]
},
"mybatis/mybatis-interview", "netty",
{
title: "SpringCloud", prefix: "springcloud/",
children: ["springcloud-intro"]
},
],
},
{
title: "安全", prefix: "security/", icon: "security-fill",
children: ["basis-of-authority-certification", "jwt优缺点分析以及常见问题解决方案", "sso-intro", "数据脱敏"]
},
"定时任务"
],
},
{
title: "分布式", icon: "distributed-network", prefix: "distributed-system/",
children: [
{
title: "理论&算法", prefix: "理论&算法/",
children: ["cap&base理论", "paxos&raft算法"],
},
"api-gateway", "distributed-id",
{
title: "rpc", prefix: "rpc/",
children: ["dubbo", "why-use-rpc"]
},
"distributed-transaction",
{
title: "分布式协调", prefix: "分布式协调/",
children: ["zookeeper/zookeeper-intro", "zookeeper/zookeeper-plus", "zookeeper/zookeeper-in-action"]
},
],
}, {
title: "高性能", icon: "gaojixiaozuzhibeifen", prefix: "high-performance/",
children: [
"读写分离&分库分表", "负载均衡",
{
title: "消息队列", prefix: "message-queue/",
children: ["message-queue", "kafka知识点&面试题总结", "rocketmq-intro", "rocketmq-questions", "rabbitmq-intro"],
},
],
}, {
title: "高可用", icon: "CalendarAvailability-1", prefix: "high-availability/",
children: [
"高可用系统设计", "limit-request", "降级&熔断", "超时和重试机制", "集群", "灾备设计和异地多活", "性能测试"
],
}],
},
blog: {
intro: "/intro/",
sidebarDisplay: "mobile",
links: {
Zhihu: "https://www.zhihu.com/people/javaguide",
Github: "https://github.com/Snailclimb",
Gitee: "https://gitee.com/SnailClimb",
},
},
footer: {
display: true,
content: '<a href="https://beian.miit.gov.cn/" target="_blank">鄂ICP备2020015769号-1</a>',
},
copyright: {
status: "global",
},
git: {
timezone: "Asia/Shanghai",
},
mdEnhance: {
enableAll: true,
presentation: {
plugins: [
"highlight",
"math",
"search",
"notes",
"zoom",
"anything",
"audio",
"chalkboard",
],
},
},
pwa: {
favicon: "/favicon.ico",
cachePic: true,
apple: {
icon: "/assets/icon/apple-icon-152.png",
statusBarColor: "black",
},
msTile: {
image: "/assets/icon/ms-icon-144.png",
color: "#ffffff",
},
manifest: {
icons: [
{
src: "/assets/icon/chrome-mask-512.png",
sizes: "512x512",
purpose: "maskable",
type: "image/png",
},
{
src: "/assets/icon/chrome-mask-192.png",
sizes: "192x192",
purpose: "maskable",
type: "image/png",
},
{
src: "/assets/icon/chrome-512.png",
sizes: "512x512",
type: "image/png",
},
{
src: "/assets/icon/chrome-192.png",
sizes: "192x192",
type: "image/png",
},
],
shortcuts: [
{
name: "Guide",
short_name: "Guide",
url: "/guide/",
icons: [
{
src: "/assets/icon/guide-maskable.png",
sizes: "192x192",
purpose: "maskable",
type: "image/png",
},
{
src: "/assets/icon/guide-monochrome.png",
sizes: "192x192",
purpose: "monochrome",
type: "image/png",
},
],
},
],
},
},
},
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,317 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="404px" height="314px" viewBox="0 0 404 314" enable-background="new 0 0 404 314" xml:space="preserve"> <image id="image0" width="404" height="314" x="0" y="0"
href="data:image/png;base64,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
NInAQwAAAABJRU5ErkJggg==" />
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

View File

@ -0,0 +1,2 @@
// import icon
@import '//at.alicdn.com/t/font_2922463_q3a7d03y4sd.css'

View File

@ -0,0 +1,19 @@
# 入职培训一个月后的感受
不知不觉已经入职一个多月了,在入职之前我没有在某个公司实习过或者工作过,所以很多东西刚入职工作的我来说还是比较新颖的。学校到职场的转变,带来了角色的转变,其中的差别因人而异。对我而言,在学校的时候课堂上老师课堂上教的东西,自己会根据自己的兴趣选择性接受,甚至很多课程你不想去上的话,还可以逃掉。到了公司就不一样了,公司要求你会的技能你不得不学,除非你不想干了。在学校的时候大部分人编程的目的都是为了通过考试或者找到一份好工作,真正靠自己兴趣支撑起来的很少,到了工作岗位之后我们编程更多的是因为工作的要求,相比于学校的来说会一般会更有挑战而且压力更大。在学校的时候,我们最重要的就是对自己负责,我们不断学习知识去武装自己,但是到了公司之后我们不光要对自己负责,更要对公司负责,毕竟公司出钱请你过来,不是让你一直 on beach 的。
刚来公司的时候,因为公司要求,我换上了 Mac 电脑。由于之前一直用的是 Windows 系统,所以非常不习惯。刚开始用 Mac 系统的时候笨手笨脚,自己会很明显的感觉自己的编程效率降低了至少 3 成。当时内心还是挺不爽的,心里也总是抱怨为什么不直接用 Windows 系统或者 Linux 系统。不过也挺奇怪,大概一个星期之后,自己就开始慢慢适应使用 Mac 进行编程,甚至非常喜欢。我这里不想对比 Mac 和 Windows 编程体验哪一个更好,我觉得还是因人而异,相同价位的 Mac 的配置相比于 Windows确实要被甩几条街。不过 Mac 的编程和使用体验确实不错,当然你也可以选择使用 Linux 进行日常开发,相信一定很不错。 另外Mac 不能玩一些主流网络游戏,对于一些克制不住自己想玩游戏的朋友是一个不错的选择。
不得不说 ThoughtWorks 的培训机制还是很不错的。应届生入职之后一般都会安排培训与往年不同的是今年的培训多了中国本地班TWU-C。作为本地班的第一期学员说句心里话还是很不错。8周的培训除了工作需要用到的基本技术比如ES6、SpringBoot等等之外还会增加一些新员工基本技能的培训比如如何高效开会、如何给别人正确的提 Feedback、如何对代码进行重构、如何进行 TDD 等等。培训期间不定期的有活动比如Weekend Trip、 City Tour、Cake time等等。最后三周还会有一个实际的模拟项目这个项目基本和我们正式工作的实际项目差不多我个人感觉很不错。目前这个项目已经正式完成了一个迭代我觉得在做项目的过程中收获最大的不是项目中使用的技术而是如何进行团队合作、如何正确使用 Git 团队协同开发、一个完成的迭代是什么样子的、做项目的过程中可能遇到那些问题、一个项目运作的完整流程等等。
ThoughtWorks 非常提倡分享、提倡帮助他人成长,这一点在公司的这段时间深有感触。培训期间,我们每个人会有一个 Trainer 负责Trainer 就是日常带我们上课和做项目的同事,一个 Trainer 大概会负责5-6个人。Trainer不定期都会给我们最近表现的 Feedback( 反馈) 我个人觉得这个并不是这是走走形式Trainer 们都很负责,很多时候都是在下班之后找我们聊天。同事们也都很热心,如果你遇到问题,向别人询问,其他人如果知道的话一般都会毫无保留的告诉你,如果遇到大部分都不懂的问题,甚至会组织一次技术 Session 分享。上周五我在我们小组内进行了一次关于 Feign 远程调用的技术分享,因为 team 里面大家对这部分知识都不太熟悉,但是后面的项目进展大概率会用到这部分知识。我刚好研究了这部分内容,所以就分享给了组内的其他同事,以便于项目更好的进行。
另外ThoughtWorks 也是一家非常提倡 Feedback( 反馈) 文化的公司,反馈是告诉人们我们对他们的表现的看法以及他们应该如何更好地做到这一点。刚开始我并没有太在意,慢慢地自己确实感觉到正确的进行反馈对他人会有很大的帮助。因为人在做很多事情的时候,会很难发现别人很容易看到的一些小问题。就比如一个很有趣的现象一样,假如我们在做项目的时候没有测试这个角色,如果你完成了自己的模块,并且自己对这个模块测试了很多遍,你发现已经没啥问题了。但是,到了实际使用的时候会很大概率出现你之前从来没有注意的问题。解释这个问题的说法是:每个人的视野或多或少都是有盲点的,这与我们的关注点息息相关。对于自己做的东西,很多地方自己测试很多遍都不会发现,但是如果让其他人帮你进行测试的话,就很大可能会发现很多显而易见的问题。
![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/feedback.png)
工作之后,平时更新公众号、专栏还有维护 Github 的时间变少了。实际上,很多时候下班回来后,都有自己的时间来干自己的事情,但是自己也总是找工作太累或者时间比较零散的接口来推掉了。到了今天,翻看 Github 突然发现 14 天前别人在 Github 上给我提的 pr 我还没有处理。这一点确实是自己没有做好的地方,没有合理安排好自己的时间。实际上自己有很多想写的东西,后面会慢慢将他们提上日程。工作之后,更加发现下班后的几个小时如何度过确实很重要 ,如果你觉得自己没有完成好自己白天该做的工作的话,下班后你可以继续忙白天没有忙完的工作,如果白天的工作对于你游刃有余的话,下班回来之后,你大可去干自己感兴趣的事情,学习自己感兴趣的技术。做任何事情都要基于自身的基础,切不可好高骛远。
工作之后身边也会有很多厉害的人,多从他人身上学习我觉得是每个职场人都应该做的。这一届和我们一起培训的同事中,有一些技术很厉害的,也有一些技术虽然不是那么厉害,但是组织能力以及团队协作能力特别厉害的。有一个特别厉害的同事,在我们还在学 SpringBoot 各种语法的时候,他自己利用业余时间写了一个简化版的 SpringBoot ,涵盖了 Spring 的一些常用注解比如 `@RestController``@Autowried``@Pathvairable``@RestquestParam`等等(已经联系这位同事,想让他开源一下,后面会第一时间同步到公众号,期待一下吧!)。我觉得这位同事对于编程是真的有兴趣,他好像从初中就开始接触编程了,对于各种底层知识也非常感兴趣,自己写过实现过很多比较底层的东西。他的梦想是在 Github 上造一个 20k Star 以上的轮子。我相信以这位同事的能力一定会达成目标的,在这里祝福这位同事,希望他可以尽快实现这个目标。
这是我入职一个多月之后的个人感受,很多地方都是一带而过,后面我会抽时间分享自己在公司或者业余学到的比较有用的知识给各位,希望看过的人都能有所收获。

View File

@ -0,0 +1,104 @@
# 我曾经也是网瘾少年
聊到高考,无数人都似乎有很多话说。今天就假借高考的名义,**简单**来聊聊我的求学经历吧!因为我自己的求学经历真的还不算平淡,甚至有点魔幻,所以还是有很多话想要说的。这篇文章大概会从我的初中一直介绍到大学,每一部分我都不会花太多篇幅。实际上,每一段经历我都可以增加很多“有趣”的经历,考虑到篇幅问题,以后有机会再慢慢说吧!
整个初中我都属于有点网瘾少年的状态,不过初三的时候稍微克制一些。到了高二下学期的时候,自己才对游戏没有真的没有那么沉迷了。
另外,关于大学的详细经历我已经在写了。想要知道我是如何从一个普通的不能再普通的少年慢慢成长起来的朋友不要错过~
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-08/0e370ac2-5f96-4e17-9ff4-8cc78ef72f19-20200802173544441.png)
**以下所有内容皆是事实,没有任何夸大的地方,稍微有一点点魔幻。**
## 01 刚开始接触电脑
最开始接触电脑是在我五年级的时候,那时候家里没电脑,都是在黑网吧玩的。我现在已经记不清当时是被哥哥还是姐姐带进网吧的了。
起初的时候,自己就是玩玩流行蝴蝶剑、单机摩托之类的单机游戏。但是,也没有到沉迷的地步,只是觉得这东西确实挺好玩的。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-08/2a6021b9-e7a0-41c4-b69e-a652f7bc3e12-20200802173601289.png)
开始有网瘾是在小学毕业的时候,在我玩了一款叫做 **QQ 飞车**的游戏之后(好像是六年级就开始玩了)。我艹,当时真的被这游戏吸引了。**每天上课都幻想自己坐在车里面飘逸,没错,当时就觉得秋名山车神就是我啦!**
我记得那时候上网还不要身份证10 元办一张网卡就行了,网费也是一元一小时。但凡,我口袋里有余钱,我都会和我的小伙伴奔跑到网吧一起玩 QQ 飞车。Guide 的青回啊!说到这,我情不自禁地打开自己的 Windows 电脑,下载了 Wegame ,然后下载了 QQ 飞车。
到了初二的时候,就没玩 QQ 飞车了。我的等级也永久定格在了 **120** 级,这个等级在当时那个升级难的一匹的年代,算的上非常高的等级了。
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/b488618c-3c25-4bc9-afd4-7324e27553bd-20200802175534614.png)
## 02 初二网瘾爆发
网瘾爆发是在上了初中之后。初二的时候,最为猖狂,自己当时真的是太痴迷 **穿越火线** 了,每天上课都在想像自己拿起枪横扫地方阵营的场景。除了周末在网吧度过之外,我经常每天早上还会起早去玩别人包夜留下的机子,毕竟那时候上学也没什么钱嘛!
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/9e94bb35-650d-4cad-8e69-40043fb4ec3d-20200802173632800.png)
那时候成绩挺差的。这样说吧!我当时在很普通的一个县级市的高中,全年级有 500 来人,我基本都是在 280 名左右。
而且,整个初二我都没有学物理。因为开学不久的一次物理课,物理老师误会我在上课吃东西还狡辩,闪了我一巴掌。从此,我上物理课就睡觉,平常的物理考试就交白卷。那时候心里一直记仇,想着以后自己长大了把这个物理暴打他一顿。
初中时候的觉悟是在初三上学期的时候当时就突然意识到自己马上就要升高中了。为了让自己能在家附近上学因为当时我家就在我们当地的二中附近_附近网吧多是主要原因哈哈_。年级前 80 的话基本才有可能考得上二中。**经过努力,初三上学期的第一次月考我直接从 280 多名进不到了年级 50 多名。当时,还因为进步太大,被当做进步之星在讲台上给整个年级做演讲。**那也是我第一次在这么多人面前讲话,挺紧张的,但是挺爽的。
**其实在初三的时候,我的网瘾还是很大。不过,我去玩游戏的前提都是自己把所有任务做完,并且上课听讲也很认真。** 我参加高中提前考试前的一个晚上我半夜12点乘着妈妈睡着跑去了网吧玩CF到凌晨 3点多回来。那一次我被抓了现行到家之后发现妈妈就坐在客厅等我训斥一顿后我就保证以后不再晚上偷偷跑出去了*其实整个初二我通宵了无数次,每个周五晚上都回去通宵*)。
_这里要说明一点我的智商我自己有自知之明的属于比较普通的水平吧 前进很大的主要原因是自己基础还行,特别是英语和物理。英语是因为自己喜欢,加上小学就学了很多初中的英语课程。 物理的话就很奇怪虽然初二也不怎么听物理课也不会物理但是到了初三之后自己就突然开窍了。真的我现在都感觉很奇怪。然后到了高中之后我的英语和物理依然是我最好的两门课。大学的兼职我出去做家教都是教的高中物理。_
后面,自己阴差阳错参加我们那个县级市的提前招生考试,然后就到了我们当地的二中,也没有参加中考。
## 03 高中生活
上了高中的之后,我上课就偷偷看小说,神印王座、斗罗大陆很多小说都是当时看的。中午和晚上回家之后,就在家里玩几把 DNF当时家里也买了电脑。没记错的话到我卸载 DNF 的时候已经练了 4 个满级的号。大量时间投入在游戏和小说上,我成功把自己从学校最好的小班玩到奥赛班,然后再到平行班。有点魔幻吧!
高中觉悟是在高二下学期的时候,当时是真的觉悟了,就突然觉得游戏不香了,觉得 DNF 也不好玩了。我妈妈当时还很诧异,还奇怪地问我:“怎么不玩游戏了?”(*我妈属于不怎么管我玩游戏的,她觉得这东西还是要靠自觉*)。
*当时自己就感觉这游戏没啥意思了。内心的真实写照是“我练了再多的满级的DNF账号有啥用啊以后有钱了直接氪金不久能很牛逼嘛” 就突然觉悟了!*
然后,我就开始牟足劲学习。当时,理科平行班大概有 7 个,每次考试都是平行班之间会单独拍一个名次。 后面的话,自己基本每次都能在平行班得第一,并且很多时候都是领先第二名个 30 来分。因为成绩还算亮眼,高三上学期快结束的时候,我就向年级主任申请去了奥赛班。
## 04 高考前的失眠
> **失败之后,不要抱怨外界因素,自始至终实际都是自己的问题,自己不够强大!** 然后,高考前的失眠也是我自己问题,要怪只能怪自己,别的没有任何接口。
我的高考经历其实还蛮坎坷的,毫不夸张的说,高考那今天可能是我到现在为止,经历的最难熬的时候,特别是在晚上。
我在高考那几天晚上都经历了失眠,想睡都睡不着那种痛苦想必很多人或许都体验过。
其实我在之前是从来没有过失眠的经历的。高考前夕,因为害怕自己睡不着,所以,我提前让妈妈去买了几瓶老师推荐的安神补脑液。我到现在还记得这个安神补脑液是敖东牌的。
高考那几天的失眠,我觉得可能和我喝了老师推荐的安神补脑液有关系,又或者是我自己太过于紧张了。因为那几天睡觉总会感觉有很多蚂蚁在身上爬一样,然后还起了一些小痘痘。
然后,这里要格外说明一点,避免引起误导: **睡不着本身就是自身的问题,上述言论并没有责怪这个补脑液的意思。** 另外, 这款安神补脑液我去各个平台都查了一下,发现大家对他的评价都挺好,和我们老师当时推荐的理由差不多。如果大家需要改善睡眠的话,可以咨询相关医生之后尝试一下。
## 05 还算充实的大学生活
高考成绩出来之后,比一本线高了 20 多分。自己挺不满意的,因为比平时考差了太多。加上自己泪点很低,就哭了一上午之后。后面,自我安慰说以后到了大学好好努力也是一样的。然后,我的第一志愿学校就报了长江大学,第一志愿专业就报了计算机专业。
后面,就开始了自己还算充实的大学生活。
大一的时候,满腔热血,对于高考结果的不满意,化作了我每天早起的动力。雷打不动,每天早上 6点左右就出去背英语单词。这也奠定了我后面的四六级都是一次过并且六级的成绩还算不错。大一那年的暑假我还去了孝感当了主管几乎从无到有办了 5 个家教点。不过,其中两个家教点的话,是去年都已经办过的,没有其他几个那么费心。
![被我的学生 diss](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/5a47eb4614934a25b8ea1a83cafac43d-20200802173912511.png)
大二的时候加了学校一个偏技术方向的传媒组织做网站、APP 之类的工作),后面成功当了副站长。在大二的时候,我才开始因为组织需要而接触 Java不过当时主要学的是安卓开发。
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/b16201d0-37d4-462a-a5e6-bf95ca503d39-20200802174034108.png)
大三的时候,正式确定自己要用 Java 语言找工作,并且要走 Java 后台(当时感觉安卓后台在求职时长太不吃香了)。我每天都在寝室学习 Java 后台开发,自己看视频,看书,做项目。我的开源项目 JavaGuide 和公众号都是这一年创建的。这一年,我大部分时间都是在寝室学习。带上耳机之后,即使室友在玩游戏或者追剧,都不会对我有什么影响。
我记得当时自己独立做项目的时候,遇到了很多问题。**就很多时候,你看书很容易就明白的东西,等到你实践的时候,总是会遇到一些小问题。我一般都是通过 Google 搜索解决的,用好搜索引擎真的能解决自己 99% 的问题。**
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-08/d30eef29-3a73-483d-9a4a-d63f41271fb4-20200802174048832.png)
大四的时候,开始找工作。我是参加的秋招,开始的较晚,基本很多公司都没有 HC 了。这点需要 diss 一下学校了,你其他地方都很好,但是,大四的时候就不要再上课点名了吧!然后,**希望国内的学校尽量能多给学生点机会吧!很多人连春招和秋招都不清楚,毕业了连实习都没实习过。**
## 06 一些心里话
关于大学要努力学习专业知识、多去读书馆这类的鸡汤Guide 就不多说了。就谈几条自己写这篇文章的时候,想到了一些心理话吧!
1. **不要抱怨学校** :高考之后,不论你是 985、211 还是普通一本,再或者是 二本、三本,都不重要了,好好享受高考之后的生活。如果你觉得自己考的不满意的话,就去复读,没必要天天抱怨,复读的一年在你的人生长河里根本算不了什么的!
2. **克制** :大学的时候,克制住自己,诱惑太多了。你不去上课,在寝室睡到中午,都没人管你。你的努力不要只是感动自己!追求形式的努力不过是你打得幌子而已。到了社会之后,这个说法依然适用! 说一个真实的发生在我身边的事情吧!高中的时候有一个特别特别特别努力的同班同学,家里的条件也很差,大学之前没有接触过手机和游戏。后来到了大学之后,因为接触了手机还有手机游戏,每天沉迷,不去上课。最后,直接就导致大学没读完就离开了。我听完我的好朋友给我说了之后,非常非常非常诧异!真的太可惜了!
3. **不要总抱怨自己迷茫,多和优秀的学长学姐沟通交流。**
4. **不知道做什么的时候,就把手头的事情做好比如你的专业课学习。**
*不论以前的自己是什么样,自己未来变成什么样自己是可以决定的,未来的路也终究还是要自己走。大环境下,大部分人都挺难的,当 996 成为了常态Life Balance 是不可能的了。我们只能试着寻求一种平衡,试着去热爱自己现在所做的事情。*
**往后余生,爱家人,亦爱自己;好好生活,不忧不恼。**

View File

@ -0,0 +1,52 @@
# 个人介绍 Q&A
大家好,我是 Gudie哥这篇文章我会通过 Q&A 的形式简单介绍一下我自己。
## 我是什么时候毕业的?
很多老读者应该比较清楚,我是 19 年本科毕业的,刚毕业就去了某家外企“养老”。
我的学校背景是比较差的,高考失利,勉强过了一本线 20 来分,去了荆州的一所很普通的双非一本。不过,还好我没有因为学校而放弃自己,反倒是比身边的同学都要更努力,整个大学还算过的比较充实。
下面这张是当时拍的毕业照:
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/%E4%B8%AA%E4%BA%BA%E4%BB%8B%E7%BB%8D.png)
## 为什么要做 JavaGuide 这个项目?
我从大二坚持写作,坚持分享让我收获了 30w+ 的读者以及一笔不错的副业收入。
2018 年我还在读大三的时候JavaGuide 开源项目&公众号诞生了。很难想到,日后,他们会陪伴我度过这么长的时间。
开源 JavaGuide 初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 以及面试过程中遇到问题的小伙伴。
- **对于 Java 初学者来说:** 本文档倾向于给你提供一个比较详细的学习路径,让你对于 Java 整体的知识体系有一个初步认识。另外,本文的一些文章也是你学习和复习 Java 知识不错的实践;
- **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。
## 如何看到 JavaGuide 的 star 数量很多?
[JavaGuide](https://github.com/Snailclimb) 目前已经是 Java 领域 star 数量最多的几个项目之一,登顶过很多次 Github Trending。
不过这个真心没啥好嘚瑟的。因为教程类的含金量其实是比较低的Star 数量比较多主要也是因为受众面比较广,大家觉得不错,点个 star 就相当于收藏了。很多特别优秀的框架star 数量可能只有几 K。所以单纯看 star 数量没啥意思,就当看个笑话吧!
维护这个项目的过程中,也被某些人 diss 过“md 项目,没啥含金量,给国人丢脸!”。
对于说这类话的人,我觉得对我没啥影响,就持续完善,把 JavaGuide 做的更好吧!其实,国外的很多项目也是纯 MD 啊!就比如外国的朋友发起的 awesome 系列、求职面试系列。无需多说,行动自证!凎!
开源非常重要的一点就是协作。如果你开源了一个项目之后,就不再维护,别人给你提交 issue/pr你都不处理那开源也没啥意义了
## 我在大学期间赚了多少钱?
在校期间,我还通过接私活、技术培训、编程竞赛等方式变现 20w+,成功实现“经济独立”。我用自己赚的钱去了重庆、三亚、恩施、青岛等地旅游,还给家里补贴了很多,减轻的父母的负担。
如果你也想通过接私活变现的话,可以在我的公众号后台回复“**接私活**”来了解详细情况。
![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2020-8/1d38ea3b-da2a-41df-9ac4-087356e9b5b4-20200802185910087.png)
## 为什么自称 Guide 哥?
可能是因为我的项目名字叫做 JavaGudie ,所以导致有很多人称呼我为 **Gudie哥**
后面,为了读者更方便称呼,我就将自己的笔名改成了 **Gudie哥**
我早期写文章用的笔名是 SnailClimb 。很多人不知道这个名字是啥意思给大家拆解一下就清楚了。SnailClimb=Snail蜗牛+Climb(攀登)。我从小就非常喜欢听周杰伦的歌曲,特别是他的《蜗牛》🐌 这首歌曲,另外,当年我高考发挥的算是比较失常,上了大学之后还算是比较“奋青”,所以,我就给自己起的笔名叫做 SnailClimb ,寓意自己要不断向上攀登,哈哈

View File

@ -1,20 +1,4 @@
<!-- MarkdownTOC -->
- [说明](#说明)
- [1. KMP 算法](#1-kmp-算法)
- [2. 替换空格](#2-替换空格)
- [3. 最长公共前缀](#3-最长公共前缀)
- [4. 回文串](#4-回文串)
- [4.1. 最长回文串](#41-最长回文串)
- [4.2. 验证回文串](#42-验证回文串)
- [4.3. 最长回文子串](#43-最长回文子串)
- [4.4. 最长回文子序列](#44-最长回文子序列)
- [5. 括号匹配深度](#5-括号匹配深度)
- [6. 把字符串转换成整数](#6-把字符串转换成整数)
<!-- /MarkdownTOC -->
# 几道常见的字符串算法题
> 授权转载!
>
@ -22,9 +6,6 @@
> - 原文地址:https://www.weiweiblog.cn/13string/
考虑到篇幅问题,我会分两次更新这个内容。本篇文章只是原文的一部分,我在原文的基础上增加了部分内容以及修改了部分代码和注释。另外,我增加了爱奇艺 2018 秋招 Java`求给定合法括号序列的深度` 这道题。所有代码均编译成功,并带有注释,欢迎各位享用!
## 1. KMP 算法
谈到字符串问题,不得不提的就是 KMP 算法它是用来解决字符串查找的问题可以在一个字符串S中查找一个子串W出现的位置。KMP 算法把字符匹配的时间复杂度缩小到 O(m+n) ,而空间复杂度也只有O(m)。因为“暴力搜索”的方法会反复回溯主串导致效率低下而KMP算法可以利用已经部分匹配这个有效信息保持主串上的指针不回溯通过修改子串的指针让模式串尽量地移动到有效的位置。
@ -284,10 +265,7 @@ class Solution {
输出: "bb"
```
以某个元素为中心,分别计算偶数长度的回文最大长度和奇数长度的回文最大长度。给大家大致花了个草图,不要嫌弃!
![](https://user-gold-cdn.xitu.io/2018/9/9/165bc32f6f1833ff?w=723&h=371&f=png&s=9305)
以某个元素为中心,分别计算偶数长度的回文最大长度和奇数长度的回文最大长度。
```java
//https://leetcode-cn.com/problems/longest-palindromic-substring/description/
@ -401,11 +379,6 @@ class Solution {
2
```
思路草图:
![](https://user-gold-cdn.xitu.io/2018/9/9/165bc6fca94ef278?w=792&h=324&f=png&s=15868)
代码如下:
```java

View File

@ -1,29 +1,6 @@
<!-- MarkdownTOC -->
# 几道常见的链表算法题
- [1. 两数相加](#1-两数相加)
- [题目描述](#题目描述)
- [问题分析](#问题分析)
- [Solution](#solution)
- [2. 翻转链表](#2-翻转链表)
- [题目描述](#题目描述-1)
- [问题分析](#问题分析-1)
- [Solution](#solution-1)
- [3. 链表中倒数第k个节点](#3-链表中倒数第k个节点)
- [题目描述](#题目描述-2)
- [问题分析](#问题分析-2)
- [Solution](#solution-2)
- [4. 删除链表的倒数第N个节点](#4-删除链表的倒数第n个节点)
- [问题分析](#问题分析-3)
- [Solution](#solution-3)
- [5. 合并两个排序的链表](#5-合并两个排序的链表)
- [题目描述](#题目描述-3)
- [问题分析](#问题分析-4)
- [Solution](#solution-4)
<!-- /MarkdownTOC -->
# 1. 两数相加
## 1. 两数相加
### 题目描述
@ -92,7 +69,7 @@ public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
}
```
# 2. 翻转链表
## 2. 翻转链表
### 题目描述
@ -180,7 +157,7 @@ public class Solution {
1
```
# 3. 链表中倒数第k个节点
## 3. 链表中倒数第k个节点
### 题目描述
@ -240,7 +217,7 @@ public class Solution {
```
# 4. 删除链表的倒数第N个节点
## 4. 删除链表的倒数第N个节点
> Leetcode:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
@ -367,7 +344,7 @@ public class Solution {
# 5. 合并两个排序的链表
## 5. 合并两个排序的链表
### 题目描述

View File

@ -1,17 +1,19 @@
### 一 斐波那契数列
# 剑指offer部分编程题
#### **题目描述:**
## 斐波那契数列
**题目描述:**
大家都知道斐波那契数列现在要求输入一个整数n请你输出斐波那契数列的第n项。
n<=39
#### **问题分析:**
**问题分析:**
可以肯定的是这一题通过递归的方式是肯定能做出来但是这样会有一个很大的问题那就是递归大量的重复计算会导致内存溢出。另外可以使用迭代法用fn1和fn2保存计算过程中的结果并复用起来。下面我会把两个方法示例代码都给出来并给出两个方法的运行时间对比。
#### **示例代码:**
**示例代码:**
**采用迭代法:**
采用迭代法:
```java
int Fibonacci(int number) {
@ -31,7 +33,7 @@ int Fibonacci(int number) {
}
```
**采用递归:**
采用递归:
```java
public int Fibonacci(int n) {
@ -46,27 +48,30 @@ public int Fibonacci(int n) {
}
```
### 二 跳台阶问题
## 跳台阶问题
#### **题目描述:**
**题目描述:**
一只青蛙一次可以跳上1级台阶也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
#### **问题分析:**
**问题分析:**
**正常分析法:**
a.如果两种跳法1阶或者2阶那么假定第一次跳的是一阶那么剩下的是n-1个台阶跳法是f(n-1);
b.假定第一次跳的是2阶那么剩下的是n-2个台阶跳法是f(n-2)
c.由ab假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
**找规律分析法:**
f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5 可以总结出f(n) = f(n-1) + f(n-2)的规律。
但是为什么会出现这样的规律呢假设现在6个台阶我们可以从第5跳一步到6这样的话有多少种方案跳到5就有多少种方案跳到6另外我们也可以从4跳两步跳到6跳到4有多少种方案的话就有多少种方案跳到6其他的不能从3跳到6什么的啦所以最后就是f(6) = f(5) + f(4);这样子也很好理解变态跳台阶的问题了。
正常分析法:
> a.如果两种跳法1阶或者2阶那么假定第一次跳的是一阶那么剩下的是n-1个台阶跳法是f(n-1);
> b.假定第一次跳的是2阶那么剩下的是n-2个台阶跳法是f(n-2)
> c.由ab假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
> d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
找规律分析法:
> f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5 可以总结出f(n) = f(n-1) + f(n-2)的规律。但是为什么会出现这样的规律呢假设现在6个台阶我们可以从第5跳一步到6这样的话有多少种方案跳到5就有多少种方案跳到6另外我们也可以从4跳两步跳到6跳到4有多少种方案的话就有多少种方案跳到6其他的不能从3跳到6什么的啦所以最后就是f(6) = f(5) + f(4);这样子也很好理解变态跳台阶的问题了。
**所以这道题其实就是斐波那契数列的问题。**
代码只需要在上一题的代码稍做修改即可。和上一题唯一不同的就是这一题的初始元素变为 1 2 3 5 8.....而上一题为1 1 2 3 5 .......。另外这一题也可以用递归做,但是递归效率太低,所以我这里只给出了迭代方式的代码。
#### **示例代码:**
**示例代码:**
```java
int jumpFloor(int number) {
@ -89,13 +94,13 @@ int jumpFloor(int number) {
}
```
### 三 变态跳台阶问题
## 变态跳台阶问题
#### **题目描述:**
**题目描述:**
一只青蛙一次可以跳上1级台阶也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
#### **问题分析:**
**问题分析:**
假设n>=2第一步有n种跳法跳1级、跳2级、到跳n级
跳1级剩下n-1级则剩下跳法是f(n-1)
@ -108,7 +113,7 @@ f(n)=f(n-1)+f(n-2)+...+f(1)
因为f(n-1)=f(n-2)+f(n-3)+...+f(1)
所以f(n)=2*f(n-1) 又f(1)=1,所以可得**f(n)=2^(number-1)**
#### **示例代码:**
**示例代码:**
```java
int JumpFloorII(int number) {
@ -116,25 +121,28 @@ int JumpFloorII(int number) {
}
```
#### **补充:**
**补充:**
**java中有三种移位运算符**
java中有三种移位运算符
1. “<<” : **左移运算符**等同于乘2的n次方
2. “>>”: **右移运算符**等同于除2的n次方
3. “>>>” : **无符号右移运算符**不管移动前最高位是0还是1右移后左侧产生的空位部分都以0来填充。与>>类似。
例:
int a = 16;
int b = a << 2;//左移2等同于16 * 2的2次方也就是16 * 4
int c = a >> 2;//右移2等同于16 / 2的2次方也就是16 / 4
### 四 二维数组查找
```java
int a = 16;
int b = a << 2;//左移2等同于16 * 2的2次方也就是16 * 4
int c = a >> 2;//右移2等同于16 / 2的2次方也就是16 / 4
```
#### **题目描述:**
## 二维数组查找
**题目描述:**
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
#### **问题解析:**
**问题解析:**
这一道题还是比较简单的,我们需要考虑的是如何做,效率最快。这里有一种很好理解的思路:
@ -142,7 +150,7 @@ int JumpFloorII(int number) {
> 因此从左下角开始查找,当要查找数字比左下角数字大时。右移
> 要查找数字比左下角数字小时,上移。这样找的速度最快。
#### **示例代码:**
**示例代码:**
```java
public boolean Find(int target, int [][] array) {
@ -163,21 +171,21 @@ public boolean Find(int target, int [][] array) {
}
```
### 五 替换空格
## 替换空格
#### **题目描述:**
**题目描述:**
请实现一个函数,将一个字符串中的空格替换成“%20”。例如当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
#### **问题分析:**
**问题分析:**
这道题不难我们可以通过循环判断字符串的字符是否为空格是的话就利用append()方法添加追加“%20”否则还是追加原字符。
或者最简单的方法就是利用replaceAll(String regex,String replacement)方法了,一行代码就可以解决。
#### **示例代码:**
**示例代码:**
**常规做法:**
常规做法:
```java
public String replaceSpace(StringBuffer str) {
@ -194,7 +202,7 @@ public String replaceSpace(StringBuffer str) {
}
```
**一行代码解决:**
一行代码解决:
```java
public String replaceSpace(StringBuffer str) {
@ -206,13 +214,13 @@ public String replaceSpace(StringBuffer str) {
}
```
### 六 数值的整数次方
## 数值的整数次方
#### **题目描述:**
**题目描述:**
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
#### **问题解析:**
**问题解析:**
这道题算是比较麻烦和难一点的一个了。我这里采用的是**二分幂**思想,当然也可以采用**快速幂**。
更具剑指offer书中细节该题的解题思路如下
@ -224,7 +232,7 @@ public String replaceSpace(StringBuffer str) {
**时间复杂度**O(logn)
#### **示例代码:**
**示例代码:**
```java
public class Solution {
@ -289,18 +297,18 @@ public double powerAnother(double base, int exponent) {
}
```
### 七 调整数组顺序使奇数位于偶数前面
## 调整数组顺序使奇数位于偶数前面
#### **题目描述:**
**题目描述:**
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
#### **问题解析:**
**问题解析:**
这道题有挺多种解法的,给大家介绍一种我觉得挺好理解的方法:
我们首先统计奇数的个数假设为n,然后新建一个等长数组然后通过循环判断原数组中的元素为偶数还是奇数。如果是则从数组下标0的元素开始把该奇数添加到新数组如果是偶数则从数组下标为n的元素开始把该偶数添加到新数组中。
#### **示例代码:**
**示例代码:**
时间复杂度为On空间复杂度为On的算法
@ -333,13 +341,13 @@ public class Solution {
}
```
### 八 链表中倒数第k个节点
## 链表中倒数第k个节点
#### **题目描述:**
**题目描述:**
输入一个链表输出该链表中倒数第k个结点
#### **问题分析:**
**问题分析:**
**一句话概括:**
两个指针一个指针p1先开始跑指针p1跑到k-1个节点后另一个节点p2开始跑当p1跑到最后时p2所指的指针就是倒数第k个节点。
@ -347,6 +355,7 @@ public class Solution {
**思想的简单理解:**
前提假设:链表的结点个数(长度)为n。
规律一要找到倒数第k个结点需要向前走多少步呢比如倒数第一个结点需要走n步那倒数第二个结点呢很明显是向前走了n-1步所以可以找到规律是找到倒数第k个结点需要向前走n-k+1步。
**算法开始:**
1. 设两个都指向head的指针p1和p2当p1走了k-1步的时候停下来。p2之前一直不动。
@ -354,11 +363,11 @@ public class Solution {
3. 当p1走到链表的尾部时即p1走了n步。由于我们知道p2是在p1走了k-1步才开始动的也就是说p1和p2永远差k-1步。所以当p1走了n步时p2走的应该是在n-(k-1)步。即p2走了n-k+1步此时巧妙的是p2正好指向的是规律一的倒数第k个结点处。
这样是不是很好理解了呢?
#### **考察内容:**
**考察内容:**
链表+代码的鲁棒性
#### **示例代码:**
**示例代码:**
```java
/*
@ -401,24 +410,25 @@ public class Solution {
}
```
### 九 反转链表
## 反转链表
#### **题目描述:**
**题目描述:**
输入一个链表,反转链表后,输出链表的所有元素。
#### **问题分析:**
**问题分析:**
链表的很常规的一道题,这一道题思路不算难,但自己实现起来真的可能会感觉无从下手,我是参考了别人的代码。
思路就是我们根据链表的特点,前一个节点指向下一个节点的特点,把后面的节点移到前面来。
就比如下图我们把1节点和2节点互换位置然后再将3节点指向2节点4节点指向3节点这样以来下面的链表就被反转了。
![链表](https://img-blog.csdn.net/20160420134000174)
#### **考察内容:**
![链表](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/844773c7300e4373922bb1a6ae2a55a3~tplv-k3u1fbpfcp-zoom-1.image)
**考察内容:**
链表+代码的鲁棒性
#### **示例代码:**
**示例代码:**
```java
/*
@ -449,13 +459,13 @@ public class Solution {
}
```
### 十 合并两个排序的链表
## 合并两个排序的链表
#### **题目描述:**
**题目描述:**
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
#### **问题分析:**
**问题分析:**
我们可以这样分析:
@ -465,13 +475,13 @@ public class Solution {
4. A2再和B2比较。。。。。。。
就这样循环往复就行了,应该还算好理解。
#### **考察内容:**
**考察内容:**
链表+代码的鲁棒性
#### **示例代码:**
**示例代码:**
**非递归版本:**
非递归版本:
```java
/*
@ -530,7 +540,7 @@ public class Solution {
}
```
**递归版本:**
递归版本:
```java
public ListNode Merge(ListNode list1,ListNode list2) {
@ -550,13 +560,13 @@ public ListNode Merge(ListNode list1,ListNode list2) {
}
```
### 十一 用两个栈实现队列
## 用两个栈实现队列
#### **题目描述:**
**题目描述:**
用两个栈来实现一个队列完成队列的Push和Pop操作。 队列中的元素为int类型。
#### 问题分析:
**问题分析:**
先来回顾一下栈和队列的基本特点:
**栈:**后进先出LIFO
@ -566,11 +576,11 @@ public ListNode Merge(ListNode list1,ListNode list2) {
既然题目给了我们两个栈我们可以这样考虑当push的时候将元素push进stack1pop的时候我们先把stack1的元素pop到stack2然后再对stack2执行pop操作这样就可以保证是先进先出的。负[pop]负[pop]得正[先进先出]
#### 考察内容:
**考察内容:**
队列+栈
#### 示例代码:
示例代码:
```java
//左程云的《程序员代码面试指南》的答案
@ -602,13 +612,13 @@ public class Solution {
}
```
### 十二 栈的压入,弹出序列
## 栈的压入,弹出序列
#### **题目描述:**
**题目描述:**
输入两个整数序列第一个序列表示栈的压入顺序请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序序列45,3,2,1是该压栈序列对应的一个弹出序列但4,3,5,1,2就不可能是该压栈序列的弹出序列。注意这两个序列的长度是相等的
#### **题目分析:**
**题目分析:**
这道题想了半天没有思路参考了Alias的答案他的思路写的也很详细应该很容易看懂。
作者Alias
@ -638,11 +648,11 @@ https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106
….
依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。
#### **考察内容:**
**考察内容:**
#### **示例代码:**
**示例代码:**
```java
import java.util.ArrayList;

View File

@ -1,3 +1,11 @@
---
category: 计算机基础
tag:
- 数据结构
---
# 布隆过滤器
海量数据处理以及缓存穿透这两个场景让我认识了 布隆过滤器 ,我查阅了一些资料来了解它,但是很多现成资料并不满足我的需求,所以就决定自己总结一篇关于布隆过滤器的文章。希望通过这篇文章让更多人了解布隆过滤器,并且会实际去使用它!
下面我们将分为几个方面来介绍布隆过滤器:
@ -9,7 +17,7 @@
5. 利用 Google 开源的 Guava 中自带的布隆过滤器。
6. Redis 中的布隆过滤器。
### 1.什么是布隆过滤器?
## 什么是布隆过滤器?
首先,我们需要了解布隆过滤器的概念。
@ -21,7 +29,7 @@
总结:**一个名叫 Bloom 的人提出了一种来检索元素是否在给定大集合中的数据结构,这种数据结构是高效且性能很好的,但缺点是具有一定的错误识别率和删除难度。并且,理论情况下,添加到集合中的元素越多,误报的可能性就越大。**
### 2.布隆过滤器的原理介绍
## 布隆过滤器的原理介绍
**当一个元素加入布隆过滤器中的时候,会进行如下操作:**
@ -45,12 +53,15 @@
综上,我们可以得出:**布隆过滤器说某个元素存在,小概率会误判。布隆过滤器说某个元素不在,那么这个元素一定不在。**
### 3.布隆过滤器使用场景
## 布隆过滤器使用场景
1. 判断给定数据是否存在比如判断一个数字是否存在于包含大量数字的数字集中数字集很大5 亿以上!)、 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、邮箱的垃圾邮件过滤、黑名单功能等等。
2. 去重:比如爬给定网址的时候对已经爬取过的 URL 去重。
### 4.通过 Java 编程手动实现布隆过滤器
## 编码实战
### 通过 Java 编程手动实现布隆过滤器
我们上面已经说了布隆过滤器的原理,知道了布隆过滤器的原理之后就可以自己手动实现一个了。
@ -188,7 +199,7 @@ true
true
```
### 5.利用 Google 开源的 Guava 中自带的布隆过滤器
### 利用 Google 开源的 Guava 中自带的布隆过滤器
自己实现的目的主要是为了让自己搞懂布隆过滤器的原理Guava 中布隆过滤器的实现算是比较权威的,所以实际项目中我们不需要手动实现一个布隆过滤器。
@ -222,26 +233,26 @@ System.out.println(filter.mightContain(1));
System.out.println(filter.mightContain(2));
```
在我们的示例中,当`mightContain()` 方法返回 _true_ 时,我们可以 99确定该元素在过滤器中当过滤器返回 _false_ 时,我们可以 100确定该元素不存在于过滤器中。
在我们的示例中,当 `mightContain()` 方法返回 _true_ 时,我们可以 99确定该元素在过滤器中当过滤器返回 _false_ 时,我们可以 100确定该元素不存在于过滤器中。
**Guava 提供的布隆过滤器的实现还是很不错的(想要详细了解的可以看一下它的源码实现),但是它有一个重大的缺陷就是只能单机使用(另外,容量扩展也不容易),而现在互联网一般都是分布式的场景。为了解决这个问题,我们就需要用到 Redis 中的布隆过滤器了。**
### 6.Redis 中的布隆过滤器
## Redis 中的布隆过滤器
#### 6.1 介绍
### 介绍
Redis v4.0 之后有了 Module模块/插件) 功能Redis Modules 让 Redis 可以使用外部模块扩展其功能 。布隆过滤器就是其中的 Module。详情可以查看 Redis 官方对 Redis Modules 的介绍 https://redis.io/modules
另外,官网推荐了一个 RedisBloom 作为 Redis 布隆过滤器的 Module地址https://github.com/RedisBloom/RedisBloom
其他还有:
- redis-lua-scaling-bloom-filterlua 脚本实现https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter
- pyreBloomPython 中的快速 Redis 布隆过滤器) https://github.com/seomoz/pyreBloom
- ......
* redis-lua-scaling-bloom-filterlua 脚本实现https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter
* pyreBloomPython 中的快速 Redis 布隆过滤器) https://github.com/seomoz/pyreBloom
* ......
RedisBloom 提供了多种语言的客户端支持包括Python、Java、JavaScript 和 PHP。
#### 6.2 使用 Docker 安装
### 使用 Docker 安装
如果我们需要体验 Redis 中的布隆过滤器非常简单,通过 Docker 就可以了!我们直接在 Google 搜索 **docker redis bloomfilter** 然后在排除广告的第一条搜素结果就找到了我们想要的答案这是我平常解决问题的一种方式分享一下具体地址https://hub.docker.com/r/redislabs/rebloom/ (介绍的很详细 )。
@ -254,7 +265,7 @@ root@21396d02c252:/data# redis-cli
127.0.0.1:6379>
```
#### 6.3 常用命令一览
### 常用命令一览
> 注意: key : 布隆过滤器的名称item : 添加的元素。
@ -263,11 +274,11 @@ root@21396d02c252:/data# redis-cli
3. **`BF.EXISTS`** : 确定元素是否在布隆过滤器中存在。格式:`BF.EXISTS {key} {item}`
4. **`BF.MEXISTS`** 确定一个或者多个元素是否在布隆过滤器中存在格式:`BF.MEXISTS {key} {item} [item ...]`
另外,`BF.RESERVE` 命令需要单独介绍一下:
另外, `BF. RESERVE` 命令需要单独介绍一下:
这个命令的格式如下:
`BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion]`。
`BF. RESERVE {key} {error_rate} {capacity} [EXPANSION expansion]`
下面简单介绍一下每个参数的具体含义:
@ -277,9 +288,9 @@ root@21396d02c252:/data# redis-cli
可选参数:
- expansion如果创建了一个新的子过滤器则其大小将是当前过滤器的大小乘以`expansion`。默认扩展值为 2。这意味着每个后续子过滤器将是前一个子过滤器的两倍。
* expansion如果创建了一个新的子过滤器则其大小将是当前过滤器的大小乘以`expansion`。默认扩展值为 2。这意味着每个后续子过滤器将是前一个子过滤器的两倍。
#### 6.4 实际使用
### 实际使用
```shell
127.0.0.1:6379> BF.ADD myFilter java

View File

@ -1,3 +1,9 @@
---
category: 计算机基础
tag:
- 数据结构
---
# 图
> 开头还是求点赞,求转发!原创优质公众号,希望大家能让更多人看到我们的文章。

View File

@ -1,3 +1,9 @@
---
category: 计算机基础
tag:
- 数据结构
---
# 堆
## 什么是堆

View File

@ -1,3 +1,9 @@
---
category: 计算机基础
tag:
- 数据结构
---
# 树
树就是一种类似现实生活中的树的数据结构(倒置的树)。任何一颗非空树只有一个根节点。

View File

@ -1,3 +1,11 @@
---
category: 计算机基础
tag:
- 数据结构
---
# 红黑树
**红黑树特点** :
1. 每个节点非红即黑;

View File

@ -1,4 +1,10 @@
# 线性数据结构
---
category: 计算机基础
tag:
- 数据结构
---
# 线性数据结构 :数组、链表、栈、队列
> 开头还是求点赞,求转发!原创优质公众号,希望大家能让更多人看到我们的文章。
>

View File

@ -1,22 +1,9 @@
<!-- TOC -->
- [1. SSL 与 TLS](#1-ssl-%E4%B8%8E-tls)
- [2. 从网络协议的角度理解 HTTPS](#2-%E4%BB%8E%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE%E7%9A%84%E8%A7%92%E5%BA%A6%E7%90%86%E8%A7%A3-https)
- [3. 从密码学的角度理解 HTTPS](#3-%E4%BB%8E%E5%AF%86%E7%A0%81%E5%AD%A6%E7%9A%84%E8%A7%92%E5%BA%A6%E7%90%86%E8%A7%A3-https)
- [3.1. TLS 工作流程](#31-tls-%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B)
- [3.2. 密码基础](#32-%E5%AF%86%E7%A0%81%E5%9F%BA%E7%A1%80)
- [3.2.1. 伪随机数生成器](#321-%E4%BC%AA%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90%E5%99%A8)
- [3.2.2. 消息认证码](#322-%E6%B6%88%E6%81%AF%E8%AE%A4%E8%AF%81%E7%A0%81)
- [3.2.3. 数字签名](#323-%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D)
- [3.2.4. 公钥密码](#324-%E5%85%AC%E9%92%A5%E5%AF%86%E7%A0%81)
- [3.2.5. 证书](#325-%E8%AF%81%E4%B9%A6)
- [3.2.6. 密码小结](#326-%E5%AF%86%E7%A0%81%E5%B0%8F%E7%BB%93)
- [3.3. TLS 使用的密码技术](#33-tls-%E4%BD%BF%E7%94%A8%E7%9A%84%E5%AF%86%E7%A0%81%E6%8A%80%E6%9C%AF)
- [3.4. TLS 总结](#34-tls-%E6%80%BB%E7%BB%93)
- [4. RSA 简单示例](#4-rsa-%E7%AE%80%E5%8D%95%E7%A4%BA%E4%BE%8B)
- [5. 参考](#5-%E5%8F%82%E8%80%83)
<!-- TOC -->
---
title: HTTPS中的TLS
category: 计算机基础
tag:
- 计算机网络
---
# 1. SSL 与 TLS

View File

@ -1,4 +1,11 @@
## 一 OSI 与 TCP/IP 各层的结构与功能,都有哪些协议?
---
title: 计算机网络常见面试题
category: 计算机基础
tag:
- 计算机网络
---
## 一 OSI 与 TCP/IP 各层的结构与功能, 都有哪些协议?
学习计算机网络时我们一般采用折中的办法,也就是中和 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚。
@ -67,14 +74,16 @@
### 2.1 TCP 三次握手漫画图解
如下图所示,下面的两个机器人通过 3 次握手确定了对方能正确接收和发送消息(图片来源:《图解 HTTP》)。
![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手.png)
**简单示意图:**
![TCP三次握手](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/三次握手2.png)
- 客户端–发送带有 SYN 标志的数据包–一次握手–服务端
- 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端
- 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端
* 客户端–发送带有 SYN 标志的数据包–一次握手–服务端
* 服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端
* 客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端
**详细示意图(图片来源不详)**
@ -104,10 +113,10 @@
断开一个 TCP 连接则需要“四次挥手”:
- 客户端-发送一个 FIN用来关闭客户端到服务器的数据传送
- 服务器-收到这个 FIN它发回一 个 ACK确认序号为收到的序号加 1 。和 SYN 一样,一个 FIN 将占用一个序号
- 服务器-关闭与客户端的连接,发送一个 FIN 给客户端
- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加 1
* 客户端-发送一个 FIN用来关闭客户端到服务器的数据传送
* 服务器-收到这个 FIN它发回一 个 ACK确认序号为收到的序号加 1 。和 SYN 一样,一个 FIN 将占用一个序号
* 服务器-关闭与客户端的连接,发送一个 FIN 给客户端
* 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加 1
任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
@ -115,7 +124,7 @@
上面讲的比较概括,推荐一篇讲的比较细致的文章:[https://blog.csdn.net/qzcsu/article/details/72861891](https://blog.csdn.net/qzcsu/article/details/72861891)
## 三 TCP,UDP 协议的区别
## 三 TCP, UDP 协议的区别
![TCP、UDP协议的区别](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp-vs-udp.jpg)
@ -146,12 +155,12 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接,
**优缺点:**
- **优点:** 简单
- **缺点:** 信道利用率低,等待时间长
* **优点:** 简单
* **缺点:** 信道利用率低,等待时间长
**1) 无差错情况:**
发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送。
发送方发送分组, 接收方在规定时间内收到, 并且回复确认. 发送方再次发送。
**2) 出现差错情况(超时重传):**
@ -159,8 +168,8 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接,
**3) 确认丢失和确认迟到**
- **确认丢失** :确认消息在传输过程丢失。当 A 发送 M1 消息B 收到后B 向 A 发送了一个 M1 确认消息,但却在传输过程中丢失。而 A 并不知道在超时计时过后A 重传 M1 消息B 再次收到该消息后采取以下两点措施1. 丢弃这个重复的 M1 消息,不向上层交付。 2. 向 A 发送确认消息。不会认为已经发送过了就不再发送。A 能重传,就证明 B 的确认消息丢失)。
- **确认迟到** 确认消息在传输过程中迟到。A 发送 M1 消息B 收到并发送确认。在超时时间内没有收到确认消息A 重传 M1 消息B 仍然收到并继续发送确认消息B 收到了 2 份 M1。此时 A 收到了 B 第二次发送的确认消息。接着发送其他数据。过了一会A 收到了 B 第一次发送的对 M1 的确认消息A 也收到了 2 份确认消息。处理如下1. A 收到重复的确认后直接丢弃。2. B 收到重复的 M1 后,也直接丢弃重复的 M1。
* **确认丢失** :确认消息在传输过程丢失。当 A 发送 M1 消息B 收到后B 向 A 发送了一个 M1 确认消息,但却在传输过程中丢失。而 A 并不知道在超时计时过后A 重传 M1 消息B 再次收到该消息后采取以下两点措施1. 丢弃这个重复的 M1 消息,不向上层交付。 2. 向 A 发送确认消息。不会认为已经发送过了就不再发送。A 能重传,就证明 B 的确认消息丢失)。
* **确认迟到** 确认消息在传输过程中迟到。A 发送 M1 消息B 收到并发送确认。在超时时间内没有收到确认消息A 重传 M1 消息B 仍然收到并继续发送确认消息B 收到了 2 份 M1。此时 A 收到了 B 第二次发送的确认消息。接着发送其他数据。过了一会A 收到了 B 第一次发送的对 M1 的确认消息A 也收到了 2 份确认消息。处理如下1. A 收到重复的确认后直接丢弃。2. B 收到重复的 M1 后,也直接丢弃重复的 M1。
#### 连续 ARQ 协议
@ -168,8 +177,8 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接,
**优缺点:**
- **优点:** 信道利用率高,容易实现,即使确认丢失,也不必重传。
- **缺点:** 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5 条 消息中间第三条丢失3 号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N回退 N表示需要退回来重传已经发送过的 N 个消息。
* **优点:** 信道利用率高,容易实现,即使确认丢失,也不必重传。
* **缺点:** 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5 条 消息中间第三条丢失3 号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N回退 N表示需要退回来重传已经发送过的 N 个消息。
### 4.2 滑动窗口和流量控制
@ -183,9 +192,9 @@ TCP 提供面向连接的服务。在传送数据之前必须先建立连接,
TCP 的拥塞控制采用了四种算法,即 **慢开始****拥塞避免** 、**快重传** 和 **快恢复**。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM以减少网络拥塞的发生。
- **慢开始:** 慢开始算法的思路是当主机开始发送数据时如果立即把大量数据字节注入到网络那么可能会引起网络阻塞因为现在还不知道网络的符合情况。经验表明较好的方法是先探测一下即由小到大逐渐增大发送窗口也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1每经过一个传播轮次cwnd 加倍。
- **拥塞避免:** 拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送放的 cwnd 加 1.
- **快重传与快恢复:**
* **慢开始:** 慢开始算法的思路是当主机开始发送数据时如果立即把大量数据字节注入到网络那么可能会引起网络阻塞因为现在还不知道网络的符合情况。经验表明较好的方法是先探测一下即由小到大逐渐增大发送窗口也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1每经过一个传播轮次cwnd 加倍。
* **拥塞避免:** 拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送放的 cwnd 加 1.
* **快重传与快恢复:**
在 TCP/IP 中快速重传和恢复fast retransmit and recoveryFRR是一种拥塞控制算法它能快速恢复丢失的数据包。没有 FRR如果数据包丢失了TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR如果接收机接收到一个不按顺序的数据段它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认它会假定确认件指出的数据段丢失了并立即重传这些丢失的数据段。有了 FRR就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时快速重传和恢复FRR能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时它则不能很有效地工作。
## 五 在浏览器中输入 url 地址 ->> 显示主页的过程(面试常客)
@ -196,9 +205,9 @@ TCP 的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免*
图解(图片来源:《图解 HTTP》
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/url输入到展示出来的过程.jpg" style="zoom:50%;" />
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/url输入到展示出来的过程.jpg" style="zoom:50%; " />
> 上图有一个错误,请注意,是 OSPF 不是 OPSF。 OSPFOpen Shortest Path Firstospf开放最短路径优先协议,是由 Internet 工程任务组开发的路由选择协议
> 上图有一个错误,请注意,是 OSPF 不是 OPSF。 OSPFOpen Shortest Path Firstospf开放最短路径优先协议, 是由 Internet 工程任务组开发的路由选择协议
总体来说分为以下几个过程:
@ -211,7 +220,7 @@ TCP 的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免*
具体可以参考下面这篇文章:
- [https://segmentfault.com/a/1190000006879700](https://segmentfault.com/a/1190000006879700)
* [https://segmentfault.com/a/1190000006879700](https://segmentfault.com/a/1190000006879700)
## 六 状态码
@ -225,7 +234,7 @@ TCP 的拥塞控制采用了四种算法,即 **慢开始** 、 **拥塞避免*
![各种协议与HTTP协议之间的关系](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/各种协议与HTTP协议之间的关系.png)
## 八 HTTP 长连接,短连接
## 八 HTTP 长连接, 短连接
在 HTTP/1.0 中默认使用短连接。也就是说,客户端和服务器每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源(如 JavaScript 文件、图像文件、CSS 文件等),每遇到这样一个 Web 资源,浏览器就会重新建立一个 HTTP 会话。
@ -241,7 +250,7 @@ Connection:keep-alive
—— [《HTTP 长连接、短连接究竟是什么?》](https://www.cnblogs.com/gotodsp/p/6366163.html)
## 九 HTTP 是不保存状态的协议,如何保存用户状态?
## 九 HTTP 是不保存状态的协议, 如何保存用户状态?
HTTP 是一种不保存状态即无状态stateless协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢Session 机制的存在就是为了解决这个问题Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session过了时间限制就会销毁这个 Session
@ -253,7 +262,7 @@ HTTP 是一种不保存状态即无状态stateless协议。也就是说
![HTTP是无状态协议](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HTTP是无状态的.png)
## 十 Cookie 的作用是什么?和 Session 有什么区别?
## 十 Cookie 的作用是什么? 和 Session 有什么区别?
Cookie 和 Session 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。
@ -276,8 +285,8 @@ HTTP1.0 最早在网页中使用是在 1996 年,那个时候只是使用一些
## 十二 URI 和 URL 的区别是什么?
- URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
- URL(Uniform Resource Locator) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
* URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
* URL(Uniform Resource Locator) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
URI 的作用像身份证号一样URL 的作用更像家庭住址一样。URL 是一种具体的 URI它不仅唯一标识资源而且还提供了定位该资源的信息。
@ -294,7 +303,7 @@ URI 的作用像身份证号一样URL 的作用更像家庭住址一样。URL
## 参考
- [https://blog.csdn.net/qq_16209077/article/details/52718250](https://blog.csdn.net/qq_16209077/article/details/52718250)
- [https://blog.csdn.net/zixiaomuwu/article/details/60965466](https://blog.csdn.net/zixiaomuwu/article/details/60965466)
- [https://blog.csdn.net/turn\_\_back/article/details/73743641](https://blog.csdn.net/turn__back/article/details/73743641)
- <https://mp.weixin.qq.com/s/GICbiyJpINrHZ41u_4zT-A?>
* [https://blog.csdn.net/qq_16209077/article/details/52718250](https://blog.csdn.net/qq_16209077/article/details/52718250)
* [https://blog.csdn.net/zixiaomuwu/article/details/60965466](https://blog.csdn.net/zixiaomuwu/article/details/60965466)
* [https://blog.csdn.net/turn\_\_back/article/details/73743641](https://blog.csdn.net/turn__back/article/details/73743641)
* <https://mp.weixin.qq.com/s/GICbiyJpINrHZ41u_4zT-A?>

View File

@ -1,3 +1,11 @@
---
title: 谢希仁老师的《计算机网络》内容总结
category: 计算机基础
tag:
- 计算机网络
---
本文是我在大二学习计算机网络期间整理, 大部分内容都来自于谢希仁老师的《计算机网络》这本书。
为了内容更容易理解,我对之前的整理进行了一波重构,并配上了一些相关的示意图便于理解。

View File

@ -1,33 +1,10 @@
<!-- MarkdownTOC -->
- [Shell 编程入门](#shell-编程入门)
- [走进 Shell 编程的大门](#走进-shell-编程的大门)
- [为什么要学Shell](#为什么要学shell)
- [什么是 Shell](#什么是-shell)
- [Shell 编程的 Hello World](#shell-编程的-hello-world)
- [Shell 变量](#shell-变量)
- [Shell 编程中的变量介绍](#shell-编程中的变量介绍)
- [Shell 字符串入门](#shell-字符串入门)
- [Shell 字符串常见操作](#shell-字符串常见操作)
- [Shell 数组](#shell-数组)
- [Shell 基本运算符](#shell-基本运算符)
- [算数运算符](#算数运算符)
- [关系运算符](#关系运算符)
- [逻辑运算符](#逻辑运算符)
- [布尔运算符](#布尔运算符)
- [字符串运算符](#字符串运算符)
- [文件相关运算符](#文件相关运算符)
- [shell流程控制](#shell流程控制)
- [if 条件语句](#if-条件语句)
- [for 循环语句](#for-循环语句)
- [while 语句](#while-语句)
- [shell 函数](#shell-函数)
- [不带参数没有返回值的函数](#不带参数没有返回值的函数)
- [有返回值的函数](#有返回值的函数)
- [带参数的函数](#带参数的函数)
<!-- /MarkdownTOC -->
---
title: Shell 编程入门
category: 计算机基础
tag:
- 操作系统
- Linux
---
# Shell 编程入门

View File

@ -1,3 +1,10 @@
---
title: 操作系统常见面试题总结
category: 计算机基础
tag:
- 操作系统
---
大家好,我是 Guide 哥!
很多读者抱怨计算操作系统的知识点比较繁杂,自己也没有多少耐心去看,但是面试的时候又经常会遇到。所以,我带着我整理好的操作系统的常见问题来啦!这篇文章总结了一些我觉得比较重要的操作系统相关的问题比如**进程管理**、**内存管理**、**虚拟内存**等等。

View File

@ -1,45 +1,12 @@
点击关注[公众号](#公众号)及时获取笔主最新更新文章并可免费领取本文档配套的《Java 面试突击》以及 Java 工程师必备学习资源。
---
title: 后端程序员必备的 Linux 基础知识总结
category: 计算机基础
tag:
- 操作系统
- Linux
---
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
<!-- code_chunk_output -->
- [1. 从认识操作系统开始](#1-从认识操作系统开始)
- [1.1. 操作系统简介](#11-操作系统简介)
- [1.2. 操作系统简单分类](#12-操作系统简单分类)
- [1.2.1. Windows](#121-windows)
- [1.2.2. Unix](#122-unix)
- [1.2.3. Linux](#123-linux)
- [1.2.4. Mac OS](#124-mac-os)
- [1.3. 操作系统的内核Kernel](#13-操作系统的内核kernel)
- [1.4. 中央处理器CPUCentral Processing Unit](#14-中央处理器cpucentral-processing-unit)
- [1.5. CPU vs Kernel(内核)](#15-cpu-vs-kernel内核)
- [1.6. 系统调用](#16-系统调用)
- [2. 初探 Linux](#2-初探-linux)
- [2.1. Linux 简介](#21-linux-简介)
- [2.2. Linux 诞生](#22-linux-诞生)
- [2.3. 常见 Linux 发行版本有哪些?](#23-常见-linux-发行版本有哪些)
- [3. Linux 文件系统概览](#3-linux-文件系统概览)
- [3.1. Linux 文件系统简介](#31-linux-文件系统简介)
- [3.2. inode 介绍](#32-inode-介绍)
- [3.3. Linux 文件类型](#33-linux-文件类型)
- [3.4. Linux 目录树](#34-linux-目录树)
- [4. Linux 基本命令](#4-linux-基本命令)
- [4.1. 目录切换命令](#41-目录切换命令)
- [4.2. 目录的操作命令(增删改查)](#42-目录的操作命令增删改查)
- [4.3. 文件的操作命令(增删改查)](#43-文件的操作命令增删改查)
- [4.4. 压缩文件的操作命令](#44-压缩文件的操作命令)
- [4.5. Linux 的权限命令](#45-linux-的权限命令)
- [4.6. Linux 用户管理](#46-linux-用户管理)
- [4.7. Linux 系统用户组的管理](#47-linux-系统用户组的管理)
- [4.8. 其他常用命令](#48-其他常用命令)
- [5. 公众号](#5-公众号)
<!-- /code_chunk_output -->
今天这篇文章中简单介绍一下一个 Java 程序员必知的 Linux 的一些概念以及常见命令。
简单介绍一下 Java 程序员必知的 Linux 的一些概念以及常见命令。
_如果文章有任何需要改善和完善的地方欢迎在评论区指出共同进步笔芯_
@ -443,13 +410,3 @@ Linux 系统是一个多用户多任务的分时操作系统,任何一个要
- **`shutdown`** `shutdown -h now` 指定现在立即关机;`shutdown +5 "System will shutdown after 5 minutes"`:指定 5 分钟后关机,同时送出警告信息给登入用户。
- **`reboot`** **`reboot`** 重开机。**`reboot -w`** 做个重开机的模拟(只有纪录并不会真的重开机)。
## 5. 公众号
如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
**《Java 面试突击》:** 由本文档衍生的专为面试而生的《Java 面试突击》V3.0 PDF 版本[公众号](#公众号)后台回复 **"Java 面试突击"** 即可免费领取!
**Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。
![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png)

View File

@ -1,3 +1,10 @@
---
title: Redis知识点&面试题总结
category: 数据库
tag:
- Redis
---
### 简单介绍一下 Redis 呗!

View File

@ -1,35 +1,15 @@
---
title: 一千行 MySQL 学习笔记
category: 数据库
tag:
- MySQL
---
> 原文地址https://shockerli.net/post/1000-line-mysql-note/ JavaGuide 对本文进行了简答排版,新增了目录。
> 作者:格物
非常不错的总结,强烈建议保存下来,需要的时候看一看。
<!-- TOC -->
- [基本操作](#基本操作)
- [数据库操作](#数据库操作)
- [表的操作](#表的操作)
- [数据操作](#数据操作)
- [字符集编码](#字符集编码)
- [数据类型(列类型)](#数据类型列类型)
- [列属性(列约束)](#列属性列约束)
- [建表规范](#建表规范)
- [SELECT](#select)
- [UNION](#union)
- [子查询](#子查询)
- [连接查询(join)](#连接查询join)
- [TRUNCATE](#truncate)
- [备份与还原](#备份与还原)
- [视图](#视图)
- [事务(transaction)](#事务transaction)
- [锁表](#锁表)
- [触发器](#触发器)
- [SQL编程](#sql编程)
- [存储过程](#存储过程)
- [用户和权限管理](#用户和权限管理)
- [表维护](#表维护)
- [杂项](#杂项)
<!-- /TOC -->
### 基本操作
```mysql

View File

@ -1,23 +1,12 @@
---
title: 一条 SQL 语句在 MySQL 中如何被执行的?
category: 数据库
tag:
- MySQL
---
本文来自[木木匠](https://github.com/kinglaw1204)投稿。
<!-- TOC -->
- [一 MySQL 基础架构分析](#一-mysql-基础架构分析)
- [1.1 MySQL 基本架构概览](#11-mysql-基本架构概览)
- [1.2 Server 层基本组件介绍](#12-server-层基本组件介绍)
- [1) 连接器](#1-连接器)
- [2) 查询缓存(MySQL 8.0 版本后移除)](#2-查询缓存mysql-80-版本后移除)
- [3) 分析器](#3-分析器)
- [4) 优化器](#4-优化器)
- [5) 执行器](#5-执行器)
- [二 语句分析](#二-语句分析)
- [2.1 查询语句](#21-查询语句)
- [2.2 更新语句](#22-更新语句)
- [三 总结](#三-总结)
- [四 参考](#四-参考)
<!-- /TOC -->
本篇文章会分析下一个 sql 语句在 MySQL 中的执行流程,包括 sql 的查询在 MySQL 内部会怎么流转sql 语句的更新是怎么完成的。
在分析之前我会先带着你看看 MySQL 的基础架构,知道了 MySQL 由那些组件组成以及这些组件的作用是什么,可以帮助我们理解和解决这些问题。
@ -30,13 +19,13 @@
先简单介绍一下下图涉及的一些组件的基本作用帮助大家理解这幅图,在 1.2 节中会详细介绍到这些组件的作用。
- **连接器:**身份认证和权限相关(登录 MySQL 的时候)。
- **查询缓存:**执行查询语句的时候会先查询缓存MySQL 8.0 版本后移除,因为这个功能不太实用)。
- **连接器:** 身份认证和权限相关(登录 MySQL 的时候)。
- **查询缓存:** 执行查询语句的时候会先查询缓存MySQL 8.0 版本后移除,因为这个功能不太实用)。
- **分析器:** 没有命中缓存的话SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
- **优化器:**按照 MySQL 认为最优的方案去执行。
- **执行器:**执行语句,然后从存储引擎返回数据。
- **优化器:** 按照 MySQL 认为最优的方案去执行。
<!-- - **执行器:** 执行语句,然后从存储引擎返回数据。 -->
![](https://user-gold-cdn.xitu.io/2019/3/23/169a8bc60a083849?w=950&h=1062&f=jpeg&s=38189)
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/13526879-3037b144ed09eb88.png)
简单来说 MySQL 主要分为 Server 层和存储引擎层:

View File

@ -1,20 +1,9 @@
<!-- TOC -->
- [一致性非锁定读和锁定读](#一致性非锁定读和锁定读)
- [一致性非锁定读](#一致性非锁定读)
- [锁定读](#锁定读)
- [InnoDB 对 MVCC 的实现](#InnoDB对MVCC的实现)
- [隐藏字段](#隐藏字段])
- [ReadView](#ReadView)
- [undo-log](#undo-log)
- [数据可见性算法](#数据可见性算法)
- [RC、RR 隔离级别下 MVCC 的差异](#RC、RR隔离级别下MVCC的差异)
- [MVCC 解决不可重复读问题](#MVCC解决不可重复读问题)
- [在 RC 下 ReadView 生成情况](#在RC下ReadView生成情况)
- [在 RR 下 ReadView 生成情况](#在RR下ReadView生成情况)
- [MVCC+Next-key-Lock 防止幻读](#MVCCNext-key-Lock防止幻读)
<!-- /TOC -->
---
title: InnoDB存储引擎对MVCC的实现
category: 数据库
tag:
- MySQL
---
## 一致性非锁定读和锁定读

View File

@ -1,59 +1,12 @@
---
title: MySQL 高性能优化规范建议
category: 数据库
tag:
- MySQL
---
> 作者: 听风,原文地址: <https://www.cnblogs.com/huchong/p/10219318.html>。JavaGuide 已获得作者授权。
<!-- TOC -->
- [数据库命令规范](#数据库命令规范)
- [数据库基本设计规范](#数据库基本设计规范)
- [1. 所有表必须使用 Innodb 存储引擎](#1-所有表必须使用-innodb-存储引擎)
- [2. 数据库和表的字符集统一使用 UTF8](#2-数据库和表的字符集统一使用-utf8)
- [3. 所有表和字段都需要添加注释](#3-所有表和字段都需要添加注释)
- [4. 尽量控制单表数据量的大小,建议控制在 500 万以内。](#4-尽量控制单表数据量的大小建议控制在-500-万以内)
- [5. 谨慎使用 MySQL 分区表](#5-谨慎使用-mysql-分区表)
- [6.尽量做到冷热数据分离,减小表的宽度](#6尽量做到冷热数据分离减小表的宽度)
- [7. 禁止在表中建立预留字段](#7-禁止在表中建立预留字段)
- [8. 禁止在数据库中存储图片,文件等大的二进制数据](#8-禁止在数据库中存储图片文件等大的二进制数据)
- [9. 禁止在线上做数据库压力测试](#9-禁止在线上做数据库压力测试)
- [10. 禁止从开发环境,测试环境直接连接生成环境数据库](#10-禁止从开发环境测试环境直接连接生成环境数据库)
- [数据库字段设计规范](#数据库字段设计规范)
- [1. 优先选择符合存储需要的最小的数据类型](#1-优先选择符合存储需要的最小的数据类型)
- [2. 避免使用 TEXT,BLOB 数据类型,最常见的 TEXT 类型可以存储 64k 的数据](#2-避免使用-textblob-数据类型最常见的-text-类型可以存储-64k-的数据)
- [3. 避免使用 ENUM 类型](#3-避免使用-enum-类型)
- [4. 尽可能把所有列定义为 NOT NULL](#4-尽可能把所有列定义为-not-null)
- [5. 使用 TIMESTAMP(4 个字节) 或 DATETIME 类型 (8 个字节) 存储时间](#5-使用-timestamp4-个字节-或-datetime-类型-8-个字节-存储时间)
- [6. 同财务相关的金额类数据必须使用 decimal 类型](#6-同财务相关的金额类数据必须使用-decimal-类型)
- [索引设计规范](#索引设计规范)
- [1. 限制每张表上的索引数量,建议单张表索引不超过 5 个](#1-限制每张表上的索引数量建议单张表索引不超过-5-个)
- [2. 禁止给表中的每一列都建立单独的索引](#2-禁止给表中的每一列都建立单独的索引)
- [3. 每个 Innodb 表必须有个主键](#3-每个-innodb-表必须有个主键)
- [4. 常见索引列建议](#4-常见索引列建议)
- [5.如何选择索引列的顺序](#5如何选择索引列的顺序)
- [6. 避免建立冗余索引和重复索引(增加了查询优化器生成执行计划的时间)](#6-避免建立冗余索引和重复索引增加了查询优化器生成执行计划的时间)
- [7. 对于频繁的查询优先考虑使用覆盖索引](#7-对于频繁的查询优先考虑使用覆盖索引)
- [8.索引 SET 规范](#8索引-set-规范)
- [数据库 SQL 开发规范](#数据库-sql-开发规范)
- [1. 建议使用预编译语句进行数据库操作](#1-建议使用预编译语句进行数据库操作)
- [2. 避免数据类型的隐式转换](#2-避免数据类型的隐式转换)
- [3. 充分利用表上已经存在的索引](#3-充分利用表上已经存在的索引)
- [4. 数据库设计时,应该要对以后扩展进行考虑](#4-数据库设计时应该要对以后扩展进行考虑)
- [5. 程序连接不同的数据库使用不同的账号,禁止跨库查询](#5-程序连接不同的数据库使用不同的账号禁止跨库查询)
- [6. 禁止使用 SELECT * 必须使用 SELECT <字段列表> 查询](#6-禁止使用-select--必须使用-select-字段列表-查询)
- [7. 禁止使用不含字段列表的 INSERT 语句](#7-禁止使用不含字段列表的-insert-语句)
- [8. 避免使用子查询,可以把子查询优化为 join 操作](#8-避免使用子查询可以把子查询优化为-join-操作)
- [9. 避免使用 JOIN 关联太多的表](#9-避免使用-join-关联太多的表)
- [10. 减少同数据库的交互次数](#10-减少同数据库的交互次数)
- [11. 对应同一列进行 or 判断时,使用 in 代替 or](#11-对应同一列进行-or-判断时使用-in-代替-or)
- [12. 禁止使用 order by rand() 进行随机排序](#12-禁止使用-order-by-rand-进行随机排序)
- [13. WHERE 从句中禁止对列进行函数转换和计算](#13-where-从句中禁止对列进行函数转换和计算)
- [14. 在明显不会有重复值时使用 UNION ALL 而不是 UNION](#14-在明显不会有重复值时使用-union-all-而不是-union)
- [15. 拆分复杂的大 SQL 为多个小 SQL](#15-拆分复杂的大-sql-为多个小-sql)
- [数据库操作行为规范](#数据库操作行为规范)
- [1. 超 100 万行的批量写 (UPDATE,DELETE,INSERT) 操作,要分批多次进行操作](#1-超-100-万行的批量写-updatedeleteinsert-操作要分批多次进行操作)
- [2. 对于大表使用 pt-online-schema-change 修改表结构](#2-对于大表使用-pt-online-schema-change-修改表结构)
- [3. 禁止为程序使用的账号赋予 super 权限](#3-禁止为程序使用的账号赋予-super-权限)
- [4. 对于程序连接数据库账号,遵循权限最小原则](#4-对于程序连接数据库账号遵循权限最小原则)
<!-- /TOC -->
## 数据库命令规范
- 所有数据库对象名称必须使用小写字母并用下划线分割

View File

@ -1,3 +1,12 @@
---
title: MySQL 索引详解
category: 数据库
tag:
- MySQL
---
## 何为索引?有什么作用?
**索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。**

View File

@ -1,3 +1,12 @@
---
title: MySQL三大日志(binlog、redo log和undo log)详解
category: 数据库
tag:
- MySQL
---
> 本文来自公号程序猿阿星投稿JavaGuide 对其做了补充完善。
## 前言

View File

@ -1,3 +1,12 @@
---
title: MySQL知识点&面试题总结
category: 数据库
tag:
- MySQL
- 大厂面试
---
## MySQL 基础
### 关系型数据库介绍

View File

@ -1,3 +1,12 @@
---
title: 关于数据库中如何存储时间的一点思考
category: 数据库
tag:
- MySQL
---
我们平时开发中不可避免的就是要存储时间,比如我们要记录操作表中这条记录的时间、记录转账的交易时间、记录出发时间等等。你会发现时间这个东西与我们开发的联系还是非常紧密的,用的好与不好会给我们的业务甚至功能带来很大的影响。所以,我们有必要重新出发,好好认识一下这个东西。
这是一篇短小精悍的文章,仔细阅读一定能学到不少东西!
@ -150,11 +159,4 @@ MySQL 中时间到底怎么存储才好Datetime?Timestamp? 数值保存的时
每种方式都有各自的优势,根据实际场景才是王道。下面再对这三种方式做一个简单的对比,以供大家实际开发中选择正确的存放时间的数据类型:
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/总结-常用日期存储方式.jpg" style="zoom:50%;" />
如果还有什么问题欢迎给我留言如果文章有什么问题的话也劳烦指出Guide 哥感激不尽!
后面的文章我会介绍:
- [ ] Java8 对日期的支持以及为啥不能用 SimpleDateFormat。
- [ ] SpringBoot 中如何实际使用(JPA 为例)
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/总结-常用日期存储方式.jpg" style="zoom:50%;" />

View File

@ -1,20 +1,12 @@
---
title: 事务隔离级别(图文详解)
category: 数据库
tag:
- MySQL
---
> 本文由 [SnailClimb](https://github.com/Snailclimb) 和 [guang19](https://github.com/guang19) 共同完成。
<!-- TOC -->
- [事务隔离级别(图文详解)](#事务隔离级别图文详解)
- [什么是事务?](#什么是事务)
- [事务的特性(ACID)](#事务的特性acid)
- [并发事务带来的问题](#并发事务带来的问题)
- [事务隔离级别](#事务隔离级别)
- [实际情况演示](#实际情况演示)
- [脏读(读未提交)](#脏读读未提交)
- [避免脏读(读已提交)](#避免脏读读已提交)
- [不可重复读](#不可重复读)
- [可重复读](#可重复读)
- [防止幻读(可重复读)](#防止幻读可重复读)
- [参考](#参考)
<!-- /TOC -->
## 事务隔离级别(图文详解)

View File

@ -1,3 +1,11 @@
---
title: 3种常用的缓存读写策略
category: 数据库
tag:
- Redis
---
看到很多小伙伴简历上写了“**熟练使用缓存**”,但是被我问到“**缓存常用的3种读写策略**”的时候却一脸懵逼。
在我看来,造成这个问题的原因是我们在学习 Redis 的时候,可能只是简单了写一些 Demo并没有去关注缓存的读写策略或者说压根不知道这回事。

View File

@ -1,3 +1,11 @@
---
title: 字符集
category: 数据库
tag:
- 数据库基础
---
MySQL 字符编码集中有两套 UTF-8 编码实现:**`utf8`** 和 **`utf8mb4`**。
如果使用 **`utf8`** 的话存储emoji 符号和一些比较复杂的汉字、繁体字就会出错。

View File

@ -2,7 +2,7 @@
title: 数据库基础知识
category: 数据库
tag:
+ 数据库基础
- 数据库基础
---
数据库知识基础,这部分内容一定要理解记忆。虽然这部分内容只是理论知识,但是非常重要,这是后面学习 MySQL 数据库的基础。PS: 这部分内容由于涉及太多概念性内容,所以参考了维基百科和百度百科相应的介绍。
@ -148,4 +148,3 @@ truncate 和 drop 属于 DDL(数据定义语言)语句,操作立即生效,
* <https://blog.csdn.net/rl529014/article/details/48391465>
* <https://www.zhihu.com/question/24696366/answer/29189700>
* <https://blog.csdn.net/bieleyang/article/details/77149954>

View File

@ -1,3 +1,6 @@
# 网关
## 何为网关?为什么要网关?
![微服务-网关](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/%E5%BE%AE%E6%9C%8D%E5%8A%A1-%E7%BD%91%E5%85%B3.png)
@ -101,3 +104,4 @@ Shenyu 通过插件扩展功能,插件是 ShenYu 的灵魂,并且插件也
- Github 地址: https://github.com/apache/incubator-shenyu
- 官网地址 https://shenyu.apache.org/

View File

@ -1,4 +1,6 @@
## 分布式 ID
# 分布式 ID
## 分布式 ID 介绍
### 何为 ID

View File

@ -0,0 +1,7 @@
# 分布式事务
这部分内容为我的星球专属,已经整理到了[《Java面试进阶指北 打造个人的技术竞争力》](https://www.yuque.com/docs/share/f37fc804-bfe6-4b0d-b373-9c462188fec7?# )中。
欢迎加入我的星球,[一个纯 Java 面试交流圈子 Ready](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=100015911&idx=1&sn=2e8a0f5acb749ecbcbb417aa8a4e18cc&chksm=4ea1b0ec79d639fae37df1b86f196e8ce397accfd1dd2004bcadb66b4df5f582d90ae0d62448#rd) (点击链接了解星球详细信息,还有专属优惠款可以领取)。
![](https://img-blog.csdnimg.cn/57cedfa4d3d1425a8e4c6a6807d8f732.png)

View File

@ -1,3 +1,5 @@
# Dubbo知识点&面试题总结
这篇文章是我根据官方文档以及自己平时的使用情况,对 Dubbo 所做的一个总结。欢迎补充!
## RPC基础

View File

@ -1,3 +1,5 @@
# 服务之间的调用为啥不直接用 HTTP 而用 RPC
## 什么是 RPC?RPC原理是什么?
### **什么是 RPC**

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -1,31 +1,4 @@
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
<!-- code_chunk_output -->
- [1. 前言](#1-前言)
- [2. ZooKeeper 安装和使用](#2-zookeeper-安装和使用)
- [2.1. 使用Docker 安装 zookeeper](#21-使用docker-安装-zookeeper)
- [2.2. 连接 ZooKeeper 服务](#22-连接-zookeeper-服务)
- [2.3. 常用命令演示](#23-常用命令演示)
- [2.3.1. 查看常用命令(help 命令)](#231-查看常用命令help-命令)
- [2.3.2. 创建节点(create 命令)](#232-创建节点create-命令)
- [2.3.3. 更新节点数据内容(set 命令)](#233-更新节点数据内容set-命令)
- [2.3.4. 获取节点的数据(get 命令)](#234-获取节点的数据get-命令)
- [2.3.5. 查看某个目录下的子节点(ls 命令)](#235-查看某个目录下的子节点ls-命令)
- [2.3.6. 查看节点状态(stat 命令)](#236-查看节点状态stat-命令)
- [2.3.7. 查看节点信息和状态(ls2 命令)](#237-查看节点信息和状态ls2-命令)
- [2.3.8. 删除节点(delete 命令)](#238-删除节点delete-命令)
- [3. ZooKeeper Java客户端 Curator简单使用](#3-zookeeper-java客户端-curator简单使用)
- [3.1. 连接 ZooKeeper 客户端](#31-连接-zookeeper-客户端)
- [3.2. 数据节点的增删改查](#32-数据节点的增删改查)
- [3.2.1. 创建节点](#321-创建节点)
- [3.2.2. 删除节点](#322-删除节点)
- [3.2.3. 获取/更新节点数据内容](#323-获取更新节点数据内容)
- [3.2.4. 获取某个节点的所有子节点路径](#324-获取某个节点的所有子节点路径)
<!-- /code_chunk_output -->
# ZooKeeper 实战
## 1. 前言

View File

@ -1,34 +1,4 @@
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
<!-- code_chunk_output -->
- [1. 前言](#1-前言)
- [2. ZooKeeper 介绍](#2-zookeeper-介绍)
- [2.1. ZooKeeper 由来](#21-zookeeper-由来)
- [2.2. ZooKeeper 概览](#22-zookeeper-概览)
- [2.3. ZooKeeper 特点](#23-zookeeper-特点)
- [2.4. ZooKeeper 典型应用场景](#24-zookeeper-典型应用场景)
- [2.5. 有哪些著名的开源项目用到了 ZooKeeper?](#25-有哪些著名的开源项目用到了-zookeeper)
- [3. ZooKeeper 重要概念解读](#3-zookeeper-重要概念解读)
- [3.1. Data model数据模型](#31-data-model数据模型)
- [3.2. znode数据节点](#32-znode数据节点)
- [3.2.1. znode 4 种类型](#321-znode-4种类型)
- [3.2.2. znode 数据结构](#322-znode-数据结构)
- [3.3. 版本version](#33-版本version)
- [3.4. ACL权限控制](#34-acl权限控制)
- [3.5. Watcher事件监听器](#35-watcher事件监听器)
- [3.6. 会话Session](#36-会话session)
- [4. ZooKeeper 集群](#4-zookeeper-集群)
- [4.1. ZooKeeper 集群角色](#41-zookeeper-集群角色)
- [4.2. ZooKeeper 集群中的服务器状态](#42-zookeeper-集群中的服务器状态)
- [4.3. ZooKeeper 集群为啥最好奇数台?](#43-zookeeper-集群为啥最好奇数台)
- [5. ZAB 协议和 Paxos 算法](#5-zab-协议和paxos-算法)
- [5.1. ZAB 协议介绍](#51-zab-协议介绍)
- [5.2. ZAB 协议两种基本的模式:崩溃恢复和消息广播](#52-zab-协议两种基本的模式崩溃恢复和消息广播)
- [6. 总结](#6-总结)
- [7. 参考](#7-参考)
<!-- /code_chunk_output -->
# ZooKeeper 相关概念总结(入门)
## 1. 前言

View File

@ -1,39 +1,6 @@
[FrancisQ](https://juejin.im/user/5c33853851882525ea106810) 投稿。
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
<!-- code_chunk_output -->
- [1. 好久不见](#1-好久不见)
- [2. 什么是ZooKeeper](#2-什么是zookeeper)
- [3. 一致性问题](#3-一致性问题)
- [4. 一致性协议和算法](#4-一致性协议和算法)
- [4.1. 2PC两阶段提交](#41-2pc两阶段提交)
- [4.2. 3PC三阶段提交](#42-3pc三阶段提交)
- [4.3. `Paxos` 算法](#43-paxos-算法)
- [4.3.1. prepare 阶段](#431-prepare-阶段)
- [4.3.2. accept 阶段](#432-accept-阶段)
- [4.3.3. `paxos` 算法的死循环问题](#433-paxos-算法的死循环问题)
- [5. 引出 `ZAB`](#5-引出-zab)
- [5.1. `Zookeeper` 架构](#51-zookeeper-架构)
- [5.2. `ZAB` 中的三个角色](#52-zab-中的三个角色)
- [5.3. 消息广播模式](#53-消息广播模式)
- [5.4. 崩溃恢复模式](#54-崩溃恢复模式)
- [6. Zookeeper的几个理论知识](#6-zookeeper的几个理论知识)
- [6.1. 数据模型](#61-数据模型)
- [6.2. 会话](#62-会话)
- [6.3. ACL](#63-acl)
- [6.4. Watcher机制](#64-watcher机制)
- [7. Zookeeper的几个典型应用场景](#7-zookeeper的几个典型应用场景)
- [7.1. 选主](#71-选主)
- [7.2. 分布式锁](#72-分布式锁)
- [7.3. 命名服务](#73-命名服务)
- [7.4. 集群管理和注册中心](#74-集群管理和注册中心)
- [8. 总结](#8-总结)
<!-- /code_chunk_output -->
# ZooKeeper 相关概念总结(进阶)
> [FrancisQ](https://juejin.im/user/5c33853851882525ea106810) 投稿。
## 1. 好久不见

View File

@ -1,3 +1,6 @@
# CAP & BASE理论
经历过技术面试的小伙伴想必对这个两个概念已经再熟悉不过了!
Guide哥当年参加面试的时候不夸张地说只要问到分布式相关的内容面试官几乎是必定会问这两个分布式相关的理论。
@ -85,3 +88,70 @@ CAP 理论的提出者布鲁尔在提出 CAP 猜想的时候,并没有详细
1. [CAP 定理简化](https://medium.com/@ravindraprasad/cap-theorem-simplified-28499a67eab4) (英文,有趣的案例)
2. [神一样的 CAP 理论被应用在何方](https://juejin.im/post/6844903936718012430) (中文,列举了很多实际的例子)
3. [请停止呼叫数据库 CP 或 AP ](https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html) (英文,带给你不一样的思考)
## BASE 理论
[BASE 理论](https://dl.acm.org/doi/10.1145/1394127.1394128)起源于 2008 年, 由eBay的架构师Dan Pritchett在ACM上发表。
### 简介
**BASE** 是 **Basically Available基本可用** 、**Soft-state软状态** 和 **Eventually Consistent最终一致性** 三个短语的缩写。BASE 理论是对 CAP 中一致性 C 和可用性 A 权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于 CAP 定理逐步演化而来的,它大大降低了我们对系统的要求。
### BASE 理论的核心思想
即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
> 也就是牺牲数据的一致性来满足系统的高可用性,系统中一部分数据不可用或者不一致时,仍需要保持系统整体“主要可用”。
**BASE 理论本质上是对 CAP 的延伸和补充,更具体地说,是对 CAP 中 AP 方案的一个补充。**
**为什么这样说呢?**
CAP 理论这节我们也说过了:
> 如果系统没有发生“分区”的话,节点间的网络连接通信正常的话,也就不存在 P 了。这个时候,我们就可以同时保证 C 和 A 了。因此,**如果系统发生“分区”,我们要考虑选择 CP 还是 AP。如果系统没有发生“分区”的话我们要思考如何保证 CA 。**
因此AP 方案只是在系统发生分区的时候放弃一致性,而不是永远放弃一致性。在分区故障恢复后,系统应该达到最终一致性。这一点其实就是 BASE 理论延伸的地方。
### BASE 理论三要素
![BASE理论三要素](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91c2VyLWdvbGQtY2RuLnhpdHUuaW8vMjAxOC81LzI0LzE2MzkxNDgwNmQ5ZTE1YzY?x-oss-process=image/format,png)
#### 1. 基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。但是,这绝不等价于系统不可用。
**什么叫允许损失部分可用性呢?**
- **响应时间上的损失**: 正常情况下,处理用户请求需要 0.5s 返回结果,但是由于系统出现故障,处理用户请求的时间变为 3 s。
- **系统功能上的损失**:正常情况下,用户可以使用系统的全部功能,但是由于系统访问量突然剧增,系统的部分非核心功能无法使用。
#### 2. 软状态
软状态指允许系统中的数据存在中间状态(**CAP 理论中的数据不一致**),并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
#### 3. 最终一致性
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
> 分布式一致性的 3 种级别:
>
> 1. **强一致性** :系统写入了什么,读出来的就是什么。
>
> 2. **弱一致性** :不一定可以读取到最新写入的值,也不保证多少时间之后读取到的数据是最新的,只是会尽量保证某个时刻达到数据一致的状态。
>
> 3. **最终一致性** :弱一致性的升级版,系统会保证在一定时间内达到数据一致的状态。
>
> **业界比较推崇是最终一致性级别,但是某些对数据一致要求十分严格的场景比如银行转账还是要保证强一致性。**
那实现最终一致性的具体方式是什么呢? [《分布式协议与算法实战》](http://gk.link/a/10rZM) 中是这样介绍:
> - **读时修复** : 在读取数据时,检测数据的不一致,进行修复。比如 Cassandra 的 Read Repair 实现,具体来说,在向 Cassandra 系统查询数据的时候,如果检测到不同节点 的副本数据不一致,系统就自动修复数据。
> - **写时修复** : 在写入数据,检测数据的不一致时,进行修复。比如 Cassandra 的 Hinted Handoff 实现。具体来说Cassandra 集群的节点之间远程写数据的时候,如果写失败 就将数据缓存下来,然后定时重传,修复数据的不一致性。
> - **异步修复** : 这个是最常用的方式,通过定时对账检测副本数据的一致性,并修复。
比较推荐 **写时修复**,这种方式对性能消耗比较低。
### 总结
**ACID 是数据库事务完整性的理论CAP 是分布式系统设计理论BASE 是 CAP 理论中 AP 方案的延伸。**

View File

@ -0,0 +1,4 @@
# Paxos 算法和 Raft 算法
Paxos 算法诞生于 1990 年,这是一种解决分布式系统一致性的经典算法 。但是,由于 Paxos 算法非常难以理解和实现不断有人尝试简化这一算法。到了2013 年才诞生了一个比 Paxos 算法更易理解和实现的分布式一致性算法—Raft 算法。

View File

@ -0,0 +1,203 @@
# 限流
## 何为限流?为什么要限流?
针对软件系统来说,限流就是对请求的速率进行限制,避免瞬时的大量请求击垮软件系统。毕竟,软件系统的处理能力是有限的。如果说超过了其处理能力的范围,软件系统可能直接就挂掉了。
限流可能会导致用户的请求无法被正确处理,不过,这往往也是权衡了软件系统的稳定性之后得到的最优解。
现实生活中,处处都有限流的实际应用,就比如排队买票是为了避免大量用户涌入购票而导致售票员无法处理。
![排队示意图](https://img-blog.csdnimg.cn/f9f17071fc4d489d85d2a234fb298df1.png)
## 常见限流算法
简单介绍 4 种非常好理解并且容易实现的限流算法!
> 图片来源于 InfoQ 的一篇文章[《分布式服务限流实战,已经为你排好坑了》](https://www.infoq.cn/article/Qg2tX8fyw5Vt-f3HH673)。
### 固定窗口计数器算法
固定窗口其实就是时间窗口。**固定窗口计数器算法** 规定了我们单位时间处理的请求数量。
假如我们规定系统中某个接口 1 分钟只能访问 33 次的话,使用固定窗口计数器算法的实现思路如下:
- 给定一个变量 `counter` 来记录当前接口处理的请求数量,初始值为 0代表接口当前 1 分钟内还未处理请求)。
- 1 分钟之内每处理一个请求之后就将 `counter+1` ,当 `counter=33` 之后(也就是说在这 1 分钟内接口已经被访问 33 次的话),后续的请求就会被全部拒绝。
- 等到 1 分钟结束后,将 `counter` 重置 0重新开始计数。
**这种限流算法无法保证限流速率,因而无法保证突然激增的流量。**
就比如说我们限制某个接口 1 分钟只能访问 1000 次,该接口的 QPS 为 500前 55s 这个接口 1 个请求没有接收,后 1s 突然接收了 1000 个请求。然后,在当前场景下,这 1000 个请求在 1s 内是没办法被处理的,系统直接就被瞬时的大量请求给击垮了。
![固定窗口计数器算法](https://static001.infoq.cn/resource/image/8d/15/8ded7a2b90e1482093f92fff555b3615.png)
### 滑动窗口计数器算法
**滑动窗口计数器算法** 算的上是固定窗口计数器算法的升级版。
滑动窗口计数器算法相比于固定窗口计数器算法的优化在于:**它把时间以一定比例分片** 。
例如我们的借口限流每分钟处理 60 个请求,我们可以把 1 分钟分为 60 个窗口。每隔 1 秒移动一次,每个窗口一秒只能处理 不大于 `60(请求数)/60窗口数` 的请求, 如果当前窗口的请求计数总和超过了限制的数量的话就不再处理其他请求。
很显然, **当滑动窗口的格子划分的越多,滑动窗口的滚动就越平滑,限流的统计就会越精确。**
![滑动窗口计数器算法](https://static001.infoq.cn/resource/image/ae/15/ae4d3cd14efb8dc7046d691c90264715.png)
### 漏桶算法
我们可以把发请求的动作比作成注水到桶中,我们处理请求的过程可以比喻为漏桶漏水。我们往桶中以任意速率流入水,以一定速率流出水。当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。
如果想要实现这个算法的话也很简单,准备一个队列用来保存请求,然后我们定期从队列中拿请求来执行就好了(和消息队列削峰/限流的思想是一样的)。
![漏桶算法](https://static001.infoq.cn/resource/image/75/03/75938d1010138ce66e38c6ed0392f103.png)
### 令牌桶算法
令牌桶算法也比较简单。和漏桶算法算法一样,我们的主角还是桶(这限流算法和桶过不去啊)。不过现在桶里装的是令牌了,请求在被处理之前需要拿到一个令牌,请求处理完毕之后将这个令牌丢弃(删除)。我们根据限流大小,按照一定的速率往桶里添加令牌。如果桶装满了,就不能继续往里面继续添加令牌了。
![令牌桶算法](https://static001.infoq.cn/resource/image/ec/93/eca0e5eaa35dac938c673fecf2ec9a93.png)
## 单机限流
单机限流可以直接使用 Google Guava 自带的限流工具类 `RateLimiter``RateLimiter` 基于令牌桶算法,可以应对突发流量。
> Guava 地址https://github.com/google/guava
除了最基本的令牌桶算法(平滑突发限流)实现之外Guava 的`RateLimiter`还提供了 **平滑预热限流** 的算法实现。
平滑突发限流就是按照指定的速率放令牌到桶里,而平滑预热限流会有一段预热时间,预热时间之内,速率会逐渐提升到配置的速率。
我们下面通过两个简单的小例子来详细了解吧!
我们直接在项目中引入 Guava 相关的依赖即可使用。
```xml
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
```
下面是一个简单的 Guava 平滑突发限流的 Demo。
```java
import com.google.common.util.concurrent.RateLimiter;
/**
* 微信搜 JavaGuide 回复"面试突击"即可免费领取个人原创的 Java 面试手册
*
* @author Guide哥
* @date 2021/10/08 19:12
**/
public class RateLimiterDemo {
public static void main(String[] args) {
// 1s 放 5 个令牌到桶里也就是 0.2s 放 1个令牌到桶里
RateLimiter rateLimiter = RateLimiter.create(5);
for (int i = 0; i < 10; i++) {
double sleepingTime = rateLimiter.acquire(1);
System.out.printf("get 1 tokens: %ss%n", sleepingTime);
}
}
}
```
输出:
```bash
get 1 tokens: 0.0s
get 1 tokens: 0.188413s
get 1 tokens: 0.197811s
get 1 tokens: 0.198316s
get 1 tokens: 0.19864s
get 1 tokens: 0.199363s
get 1 tokens: 0.193997s
get 1 tokens: 0.199623s
get 1 tokens: 0.199357s
get 1 tokens: 0.195676s
```
下面是一个简单的 Guava 平滑预热限流的 Demo。
```java
import com.google.common.util.concurrent.RateLimiter;
import java.util.concurrent.TimeUnit;
/**
* 微信搜 JavaGuide 回复"面试突击"即可免费领取个人原创的 Java 面试手册
*
* @author Guide哥
* @date 2021/10/08 19:12
**/
public class RateLimiterDemo {
public static void main(String[] args) {
// 1s 放 5 个令牌到桶里也就是 0.2s 放 1个令牌到桶里
// 预热时间为3s,也就说刚开始的 3s 内发牌速率会逐渐提升到 0.2s 放 1 个令牌到桶里
RateLimiter rateLimiter = RateLimiter.create(5, 3, TimeUnit.SECONDS);
for (int i = 0; i < 20; i++) {
double sleepingTime = rateLimiter.acquire(1);
System.out.printf("get 1 tokens: %sds%n", sleepingTime);
}
}
}
```
输出:
```bash
get 1 tokens: 0.0s
get 1 tokens: 0.561919s
get 1 tokens: 0.516931s
get 1 tokens: 0.463798s
get 1 tokens: 0.41286s
get 1 tokens: 0.356172s
get 1 tokens: 0.300489s
get 1 tokens: 0.252545s
get 1 tokens: 0.203996s
get 1 tokens: 0.198359s
```
另外,**Bucket4j** 是一个非常不错的基于令牌/漏桶算法的限流库。
> Bucket4j 地址https://github.com/vladimir-bukhtoyarov/bucket4j
相对于Guava 的限流工具类来说Bucket4j 提供的限流功能更加全面。不仅支持单机限流和分布式限流,还可以集成监控,搭配 Prometheus 和 Grafana 使用。
不过,毕竟 Guava 也只是一个功能全面的工具类库,其提供的开箱即用的限流功能在很多单机场景下还是比较实用的。
Spring Cloud Gateway 中自带的单机限流的早期版本就是基于 Bucket4j 实现的。后来,替换成了 **Resilience4j**
Resilience4j 是一个轻量级的容错组件,其灵感来自于 Hystrix。自[Netflix 宣布不再积极开发 Hystrix](https://github.com/Netflix/Hystrix/commit/a7df971cbaddd8c5e976b3cc5f14013fe6ad00e6) 之后Spring 官方和 Netflix 都更推荐使用 Resilience4j 来做限流熔断。
> Resilience4j 地址: https://github.com/resilience4j/resilience4j
一般情况下,为了保证系统的高可用,项目的限流和熔断都是要一起做的。
Resilience4j 不仅提供限流还提供了熔断、负载保护、自动重试等保障系统高可用开箱即用的功能。并且Resilience4j 的生态也更好,很多网关都使用 Resilience4j 来做限流熔断的。
因此,在绝大部分场景下 Resilience4j 或许会是更好的选择。如果是一些比较简单的限流场景的话Guava 或者 Bucket4j 也是不错的选择。
## 分布式限流
分布式限流常见的方案:
- **借助中间件架限流** :可以借助 Sentinel 或者使用 Redis 来自己实现对应的限流逻辑。
- **网关层限流** :比较常用的一种方案,直接在网关层把限流给安排上了。不过,通常网关层限流通常也需要借助到中间件/框架。就比如 Spring Cloud Gateway 的分布式限流实现`RedisRateLimiter`就是基于 Redis+Lua 来实现的,再比如 Spring Cloud Gateway 还可以整合 Sentinel 来做限流。
如果你要基于 Redis 来手动实现限流逻辑的话,建议配合 Lua 脚本来做。
网上也有很多现成的脚本供你参考,就比如 Apache 网关项目 ShenYu 的 RateLimiter 限流插件就基于 Redis + Lua 实现了令牌桶算法/并发令牌桶算法、漏桶算法、滑动窗口算法。
> ShenYu 地址: https://github.com/apache/incubator-shenyu
![](https://img-blog.csdnimg.cn/e1e2a75f489e4854990dabe3b6cec522.png)
## 相关阅读
- 服务治理之轻量级熔断框架 Resilience4j https://xie.infoq.cn/article/14786e571c1a4143ad1ef8f19
- 超详细的 Guava RateLimiter 限流原理解析https://cloud.tencent.com/developer/article/1408819
- 实战 Spring Cloud Gateway 之限流篇 👍https://www.aneasystone.com/archives/2020/08/spring-cloud-gateway-current-limiting.html

View File

@ -0,0 +1,150 @@
# 性能测试入门
性能测试一般情况下都是由测试这个职位去做的,那还需要我们开发学这个干嘛呢?了解性能测试的指标、分类以及工具等知识有助于我们更好地去写出性能更好的程序,另外作为开发这个角色,如果你会性能测试的话,相信也会为你的履历加分不少。
这篇文章是我会结合自己的实际经历以及在测试这里取的经所得,除此之外,我还借鉴了一些优秀书籍,希望对你有帮助。
本文思维导图:
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/网站性能测试.png" style="zoom:50%;" />
## 一 不同角色看网站性能
### 1.1 用户
当用户打开一个网站的时候,最关注的是什么?当然是网站响应速度的快慢。比如我们点击了淘宝的主页,淘宝需要多久将首页的内容呈现在我的面前,我点击了提交订单按钮需要多久返回结果等等。
所以,用户在体验我们系统的时候往往根据你的响应速度的快慢来评判你的网站的性能。
### 1.2 开发人员
用户与开发人员都关注速度,这个速度实际上就是我们的系统**处理用户请求的速度**。
开发人员一般情况下很难直观的去评判自己网站的性能,我们往往会根据网站当前的架构以及基础设施情况给一个大概的值,比如:
1. 项目架构是分布式的吗?
2. 用到了缓存和消息队列没有?
3. 高并发的业务有没有特殊处理?
4. 数据库设计是否合理?
5. 系统用到的算法是否还需要优化?
6. 系统是否存在内存泄露的问题?
7. 项目使用的 Redis 缓存多大?服务器性能如何?用的是机械硬盘还是固态硬盘?
8. ......
### 1.3 测试人员
测试人员一般会根据性能测试工具来测试,然后一般会做出一个表格。这个表格可能会涵盖下面这些重要的内容:
1. 相应时间;
2. 请求成功率;
3. 吞吐量;
4. ......
### 1.4 运维人员
运维人员会倾向于根据基础设施和资源的利用率来判断网站的性能,比如我们的服务器资源使用是否合理、数据库资源是否存在滥用的情况、当然,这是传统的运维人员,现在 Devpos 火起来后,单纯干运维的很少了。我们这里暂且还保留有这个角色。
## 二 性能测试需要注意的点
几乎没有文章在讲性能测试的时候提到这个问题,大家都会讲如何去性能测试,有哪些性能测试指标这些东西。
### 2.1 了解系统的业务场景
**性能测试之前更需要你了解当前的系统的业务场景。** 对系统业务了解的不够深刻,我们很容易犯测试方向偏执的错误,从而导致我们忽略了对系统某些更需要性能测试的地方进行测试。比如我们的系统可以为用户提供发送邮件的功能,用户配置成功邮箱后只需输入相应的邮箱之后就能发送,系统每天大概能处理上万次发邮件的请求。很多人看到这个可能就直接开始使用相关工具测试邮箱发送接口,但是,发送邮件这个场景可能不是当前系统的性能瓶颈,这么多人用我们的系统发邮件, 还可能有很多人一起发邮件,单单这个场景就这么人用,那用户管理可能才是性能瓶颈吧!
### 2.2 历史数据非常有用
当前系统所留下的历史数据非常重要,一般情况下,我们可以通过相应的些历史数据初步判定这个系统哪些接口调用的比较多、哪些 service 承受的压力最大,这样的话,我们就可以针对这些地方进行更细致的性能测试与分析。
另外,这些地方也就像这个系统的一个短板一样,优化好了这些地方会为我们的系统带来质的提升。
### 三 性能测试的指标
### 3.1 响应时间
**响应时间就是用户发出请求到用户收到系统处理结果所需要的时间。** 重要吗?实在太重要!
比较出名的 2-5-8 原则是这样描述的通常来说2到5秒页面体验会比较好5到8秒还可以接受8秒以上基本就很难接受了。另外据统计当网站慢一秒就会流失十分之一的客户。
但是,在某些场景下我们也并不需要太看重 2-5-8 原则 ,比如我觉得系统导出导入大数据量这种就不需要,系统生成系统报告这种也不需要。
### 3.2 并发数
**并发数是系统能同时处理请求的数目即同时提交请求的用户数目。**
不得不说高并发是现在后端架构中非常非常火热的一个词了这个与当前的互联网环境以及中国整体的互联网用户量都有很大关系。一般情况下你的系统并发量越大说明你的产品做的就越大。但是并不是每个系统都需要达到像淘宝、12306 这种亿级并发量的。
### 3.3 吞吐量
吞吐量指的是系统单位时间内系统处理的请求数量。衡量吞吐量有几个重要的参数QPSTPS、并发数、响应时间。
1. QPSQuery Per Second服务器每秒可以执行的查询次数
2. TPSTransaction Per Second服务器每秒处理的事务数这里的一个事务可以理解为客户发出请求到收到服务器的过程
3. 并发数;系统能同时处理请求的数目即同时提交请求的用户数目。
4. 响应时间: 一般取多次请求的平均响应时间
理清他们的概念,就很容易搞清楚他们之间的关系了。
- **QPSTPS** = 并发数/平均响应时间
- **并发数** = QPS\平均响应时间
书中是这样描述 QPS 和 TPS 的区别的。
> QPS vs TPSQPS 基本类似于 TPS但是不同的是对于一个页面的一次访问形成一个TPS但一次页面请求可能产生多次对服务器的请求服务器对这些请求就可计入“QPS”之中。如访问一个页面会请求服务器2次一次访问产生一个“T”产生2个“Q”。
### 3.4 性能计数器
**性能计数器是描述服务器或者操作系统的一些数据指标如内存使用、CPU使用、磁盘与网络I/O等情况。**
### 四 几种常见的性能测试
### 性能测试
性能测试方法是通过测试工具模拟用户请求系统,目的主要是为了测试系统的性能是否满足要求。通俗地说,这种方法就是要在特定的运行条件下验证系统的能力状态。
性能测试是你在对系统性能已经有了解的前提之后进行的,并且有明确的性能指标。
### 负载测试
对被测试的系统继续加大请求压力,直到服务器的某个资源已经达到饱和了,比如系统的缓存已经不够用了或者系统的响应时间已经不满足要求了。
负载测试说白点就是测试系统的上线。
### 压力测试
不去管系统资源的使用情况,对系统继续加大请求压力,直到服务器崩溃无法再继续提供服务。
### 稳定性测试
模拟真实场景,给系统一定压力,看看业务是否能稳定运行。
## 五 常用性能测试工具
这里就不多扩展了,有时间的话会单独拎一个熟悉的说一下。
### 5.1 后端常用
没记错的话,除了 LoadRunner 其他几款性能测试工具都是开源免费的。
1. Jmeter Apache JMeter 是 JAVA 开发的性能测试工具。
2. LoadRunner一款商业的性能测试工具。
3. Galtling 一款基于Scala 开发的高性能服务器性能测试工具。
4. ab :全称为 Apache Bench 。Apache 旗下的一款测试工具,非常实用。
### 5.2 前端常用
1. Fiddler抓包工具它可以修改请求的数据甚至可以修改服务器返回的数据功能非常强大是Web 调试的利器。
2. HttpWatch: 可用于录制HTTP请求信息的工具。
## 六 常见的性能优化策略
性能优化之前我们需要对请求经历的各个环节进行分析,排查出可能出现性能瓶颈的地方,定位问题。
下面是一些性能优化时,我经常拿来自问的一些问题:
1. 系统是否需要缓存?
2. 系统架构本身是不是就有问题?
3. 系统是否存在死锁的地方?
4. 系统是否存在内存泄漏Java 的自动回收内存虽然很方便,但是,有时候代码写的不好真的会造成内存泄漏)
5. 数据库索引使用是否合理?
6. ......

View File

@ -0,0 +1,14 @@
# 灾备设计&异地多活
**灾备** = 容灾+备份。
- **备份** 将系统所产生的的所有重要数据多备份几份。
- **容灾** 在异地建立两个完全相同的系统。当某个地方的系统突然挂掉,整个应用系统可以切换到另一个,这样系统就可以正常提供服务了。
**异地多活** 描述的是将服务部署在异地并且服务同时对外提供服务。和传统的灾备设计的最主要区别在于“多活”,即所有站点都是同时在对外提供服务的。异地多活是为了应对突发状况比如火灾、地震等自然或者认为灾害。
相关阅读:
- [搞懂异地多活,看这篇就够了](https://mp.weixin.qq.com/s/T6mMDdtTfBuIiEowCpqu6Q)
- [四步构建异地多活](https://mp.weixin.qq.com/s/hMD-IS__4JE5_nQhYPYSTg)
- [《从零开始学架构》— 28 | 业务高可用的保障:异地多活架构](http://gk.link/a/10pKZ)

View File

@ -0,0 +1,5 @@
# 超时&重试机制
**一旦用户的请求超过某个时间得不到响应就结束此次请求并抛出异常。** 如果不进行超时设置可能会导致请求响应速度慢,甚至导致请求堆积进而让系统无法在处理请求。
另外,重试的次数一般设为 3 次,再多次的重试没有好处,反而会加重服务器压力(部分场景使用失败重试机制会不太适合)。

View File

@ -0,0 +1,9 @@
# 降级&熔断
降级是从系统功能优先级的角度考虑如何应对系统故障。
服务降级指的是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
熔断和降级是两个比较容易混淆的概念,两者的含义并不相同。
降级的目的在于应对系统自身的故障,而熔断的目的在于应对当前系统依赖的外部系统或者第三方系统的故障。

View File

@ -0,0 +1,3 @@
# 集群
相同的服务部署多份,避免单点故障。

View File

@ -1,3 +1,5 @@
# 高可用系统设计
一篇短小的文章,面试经常遇到的这个问题。本文主要包括下面这些内容:
1. 高可用的定义
@ -66,7 +68,3 @@
4. **灰度发布:** 将服务器集群分成若干部分,每天只发布一部分机器,观察运行稳定没有故障,第二天继续发布一部分机器,持续几天才把整个集群全部发布完毕,期间如果发现问题,只需要回滚已发布的一部分服务器即可
5. **定期检查/更换硬件:** 如果不是购买的云服务的话,定期还是需要对硬件进行一波检查的,对于一些需要更换或者升级的硬件,要及时更换或者升级。
6. .....(想起来再补充!也欢迎各位欢迎补充!)
## 总结
![如何设计高可用系统?](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/如何设计高可用的系统?.png)

View File

@ -1,8 +1,5 @@
------
## Kafka面试题总结
# Kafka知识点&面试题总结
### Kafka 是什么?主要应用场景有哪些?

View File

@ -1,4 +1,4 @@
# 消息队列其实很简单
# 消息队列知识点&面试题总结
“RabbitMQ”“Kafka”“RocketMQ”...在日常学习与开发过程中,我们常常听到消息队列这个关键词。我也在我的多篇文章中提到了这个概念。可能你是熟练使用消息队列的老手,又或者你是不懂消息队列的新手,不论你了不了解消息队列,本文都将带你搞懂消息队列的一些基本理论。如果你是老手,你可能从本文学到你之前不曾注意的一些关于消息队列的重要概念,如果你是新手,相信本文将是你打开消息队列大门的一板砖。
@ -76,13 +76,13 @@ JMSJAVA Message Service,java 消息服务)是 java 的消息服务JMS
**① 点到点P2P模型**
![点到点P2P模型](https://user-gold-cdn.xitu.io/2018/4/21/162e7185572ca37d?w=575&h=135&f=gif&s=8530)
![队列模型](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/队列模型23.png)
使用**队列Queue**作为消息通信载体;满足**生产者与消费者模式**,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送 100 条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。)
**② 发布/订阅Pub/Sub模型**
![发布/订阅Pub/Sub模型](https://user-gold-cdn.xitu.io/2018/4/21/162e7187c268eaa5?w=402&h=164&f=gif&s=15492)
![发布订阅模型](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/java-guide-blog/%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E6%A8%A1%E5%9E%8B.png)
发布订阅模型Pub/Sub 使用**主题Topic**作为消息通信载体,类似于**广播模式**;发布者发布一条消息,该消息通过主题传递给所有的订阅者,**在一条消息广播之后才订阅的用户则是收不到该条消息的**。

View File

@ -1,25 +1,5 @@
<!-- TOC -->
- [一文搞懂 RabbitMQ 的重要概念以及安装](#一文搞懂-rabbitmq-的重要概念以及安装)
- [一 RabbitMQ 介绍](#一-rabbitmq-介绍)
- [1.1 RabbitMQ 简介](#11-rabbitmq-简介)
- [1.2 RabbitMQ 核心概念](#12-rabbitmq-核心概念)
- [1.2.1 Producer(生产者) 和 Consumer(消费者)](#121-producer生产者-和-consumer消费者)
- [1.2.2 Exchange(交换器)](#122-exchange交换器)
- [1.2.3 Queue(消息队列)](#123-queue消息队列)
- [1.2.4 Broker消息中间件的服务节点](#124-broker消息中间件的服务节点)
- [1.2.5 Exchange Types(交换器类型)](#125-exchange-types交换器类型)
- [① fanout](#-fanout)
- [② direct](#-direct)
- [③ topic](#-topic)
- [④ headers(不推荐)](#-headers不推荐)
- [二 安装 RabbitMq](#二-安装-rabbitmq)
- [2.1 安装 erlang](#21-安装-erlang)
- [2.2 安装 RabbitMQ](#22-安装-rabbitmq)
<!-- /TOC -->
# 一文搞懂 RabbitMQ 的重要概念以及安装
# RabbitMQ 入门总结
## 一 RabbitMQ 介绍

View File

@ -1,3 +1,5 @@
# RocketMQ入门总结
> 文章很长,点赞再看,养成好习惯😋😋😋
>
> [本文由 FrancisQ 老哥投稿!](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485969&idx=1&sn=6bd53abde30d42a778d5a35ec104428c&chksm=cea245daf9d5cccce631f93115f0c2c4a7634e55f5bef9009fd03f5a0ffa55b745b5ef4f0530&token=294077121&lang=zh_CN#rd)

View File

@ -1,25 +1,8 @@
# RocketMQ常见问题
本文来自读者 [PR](https://github.com/Snailclimb/JavaGuide/pull/291)。
<!-- TOC -->
- [1 单机版消息中心](#1-%E5%8D%95%E6%9C%BA%E7%89%88%E6%B6%88%E6%81%AF%E4%B8%AD%E5%BF%83)
- [2 分布式消息中心](#2-%E5%88%86%E5%B8%83%E5%BC%8F%E6%B6%88%E6%81%AF%E4%B8%AD%E5%BF%83)
- [2.1 问题与解决](#21-%E9%97%AE%E9%A2%98%E4%B8%8E%E8%A7%A3%E5%86%B3)
- [2.1.1 消息丢失的问题](#211-%E6%B6%88%E6%81%AF%E4%B8%A2%E5%A4%B1%E7%9A%84%E9%97%AE%E9%A2%98)
- [2.1.2 同步落盘怎么才能快](#212-%E5%90%8C%E6%AD%A5%E8%90%BD%E7%9B%98%E6%80%8E%E4%B9%88%E6%89%8D%E8%83%BD%E5%BF%AB)
- [2.1.3 消息堆积的问题](#213-%E6%B6%88%E6%81%AF%E5%A0%86%E7%A7%AF%E7%9A%84%E9%97%AE%E9%A2%98)
- [2.1.4 定时消息的实现](#214-%E5%AE%9A%E6%97%B6%E6%B6%88%E6%81%AF%E7%9A%84%E5%AE%9E%E7%8E%B0)
- [2.1.5 顺序消息的实现](#215-%E9%A1%BA%E5%BA%8F%E6%B6%88%E6%81%AF%E7%9A%84%E5%AE%9E%E7%8E%B0)
- [2.1.6 分布式消息的实现](#216-%E5%88%86%E5%B8%83%E5%BC%8F%E6%B6%88%E6%81%AF%E7%9A%84%E5%AE%9E%E7%8E%B0)
- [2.1.7 消息的 push 实现](#217-%E6%B6%88%E6%81%AF%E7%9A%84-push-%E5%AE%9E%E7%8E%B0)
- [2.1.8 消息重复发送的避免](#218-%E6%B6%88%E6%81%AF%E9%87%8D%E5%A4%8D%E5%8F%91%E9%80%81%E7%9A%84%E9%81%BF%E5%85%8D)
- [2.1.9 广播消费与集群消费](#219-%E5%B9%BF%E6%92%AD%E6%B6%88%E8%B4%B9%E4%B8%8E%E9%9B%86%E7%BE%A4%E6%B6%88%E8%B4%B9)
- [2.1.10 RocketMQ 不使用 ZooKeeper 作为注册中心的原因,以及自制的 NameServer 优缺点?](#2110-rocketmq-%E4%B8%8D%E4%BD%BF%E7%94%A8-zookeeper-%E4%BD%9C%E4%B8%BA%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83%E7%9A%84%E5%8E%9F%E5%9B%A0%E4%BB%A5%E5%8F%8A%E8%87%AA%E5%88%B6%E7%9A%84-nameserver-%E4%BC%98%E7%BC%BA%E7%82%B9)
- [2.1.11 其它](#2111-%E5%85%B6%E5%AE%83)
- [3 参考](#3-%E5%8F%82%E8%80%83)
<!-- TOC -->
# 1 单机版消息中心
## 1 单机版消息中心
一个消息中心,最基本的需要支持多生产者、多消费者,例如下:
@ -127,40 +110,40 @@ class Broker {
4. 没有使用多个队列(即多个 LinkedBlockingQueueRocketMQ 的顺序消息是通过生产者和消费者同时使用同一个 MessageQueue 来实现,但是如果我们只有一个 MessageQueue那我们天然就支持顺序消息
5. 没有使用 MappedByteBuffer 来实现文件映射从而使消息数据落盘非常的快(实际 RocketMQ 使用的是 FileChannel+DirectBuffer
# 2 分布式消息中心
## 2 分布式消息中心
## 2.1 问题与解决
### 2.1 问题与解决
### 2.1.1 消息丢失的问题
#### 2.1.1 消息丢失的问题
1. 当你系统需要保证百分百消息不丢失你可以使用生产者每发送一个消息Broker 同步返回一个消息发送成功的反馈消息
2. 即每发送一个消息,同步落盘后才返回生产者消息发送成功,这样只要生产者得到了消息发送生成的返回,事后除了硬盘损坏,都可以保证不会消息丢失
3. 但是这同时引入了一个问题,同步落盘怎么才能快?
### 2.1.2 同步落盘怎么才能快
#### 2.1.2 同步落盘怎么才能快
1. 使用 FileChannel + DirectBuffer 池,使用堆外内存,加快内存拷贝
2. 使用数据和索引分离,当消息需要写入时,使用 commitlog 文件顺序写当需要定位某个消息时查询index 文件来定位从而减少文件IO随机读写的性能损耗
### 2.1.3 消息堆积的问题
#### 2.1.3 消息堆积的问题
1. 后台定时任务每隔72小时删除旧的没有使用过的消息信息
2. 根据不同的业务实现不同的丢弃任务,具体参考线程池的 AbortPolicy例如FIFO/LRU等RocketMQ没有此策略
3. 消息定时转移,或者对某些重要的 TAG 型(支付型)消息真正落库
### 2.1.4 定时消息的实现
#### 2.1.4 定时消息的实现
1. 实际 RocketMQ 没有实现任意精度的定时消息,它只支持某些特定的时间精度的定时消息
2. 实现定时消息的原理是:创建特定时间精度的 MessageQueue例如生产者需要定时1s之后被消费者消费你只需要将此消息发送到特定的 Topic例如MessageQueue-1 表示这个 MessageQueue 里面的消息都会延迟一秒被消费,然后 Broker 会在 1s 后发送到消费者消费此消息,使用 newSingleThreadScheduledExecutor 实现
### 2.1.5 顺序消息的实现
#### 2.1.5 顺序消息的实现
1. 与定时消息同原理,生产者生产消息时指定特定的 MessageQueue ,消费者消费消息时,消费特定的 MessageQueue其实单机版的消息中心在一个 MessageQueue 就天然支持了顺序消息
2. 注意:同一个 MessageQueue 保证里面的消息是顺序消费的前提是:消费者是串行的消费该 MessageQueue因为就算 MessageQueue 是顺序的,但是当并行消费时,还是会有顺序问题,但是串行消费也同时引入了两个问题:
>1. 引入锁来实现串行
>2. 前一个消费阻塞时后面都会被阻塞
### 2.1.6 分布式消息的实现
#### 2.1.6 分布式消息的实现
1. 需要前置知识2PC
2. RocketMQ4.3 起支持原理为2PC即两阶段提交prepared->commit/rollback
@ -168,31 +151,31 @@ class Broker {
>注意,就算是事务消息最后回滚了也不会物理删除,只会逻辑删除该消息
### 2.1.7 消息的 push 实现
#### 2.1.7 消息的 push 实现
1. 注意RocketMQ 已经说了自己会有低延迟问题,其中就包括这个消息的 push 延迟问题
2. 因为这并不是真正的将消息主动的推送到消费者,而是 Broker 定时任务每5s将消息推送到消费者
3. pull模式需要我们手动调用consumer拉消息而push模式则只需要我们提供一个listener即可实现对消息的监听而实际上RocketMQ的push模式是基于pull模式实现的它没有实现真正的push。
4. push方式里consumer把轮询过程封装了并注册MessageListener监听器取到消息后唤醒MessageListener的consumeMessage()来消费,对用户而言,感觉消息是被推送过来的。
### 2.1.8 消息重复发送的避免
#### 2.1.8 消息重复发送的避免
1. RocketMQ 会出现消息重复发送的问题,因为在网络延迟的情况下,这种问题不可避免的发生,如果非要实现消息不可重复发送,那基本太难,因为网络环境无法预知,还会使程序复杂度加大,因此默认允许消息重复发送
2. RocketMQ 让使用者在消费者端去解决该问题,即需要消费者端在消费消息时支持幂等性的去消费消息
3. 最简单的解决方案是每条消费记录有个消费状态字段,根据这个消费状态字段来判断是否消费或者使用一个集中式的表,来存储所有消息的消费状态,从而避免重复消费
4. 具体实现可以查询关于消息幂等消费的解决方案
### 2.1.9 广播消费与集群消费
#### 2.1.9 广播消费与集群消费
1. 消息消费区别:广播消费,订阅该 Topic 的消息者们都会消费**每个**消息。集群消费,订阅该 Topic 的消息者们只会有一个去消费**某个**消息
2. 消息落盘区别:具体表现在消息消费进度的保存上。广播消费,由于每个消费者都独立的去消费每个消息,因此每个消费者各自保存自己的消息消费进度。而集群消费下,订阅了某个 Topic而旗下又有多个 MessageQueue每个消费者都可能会去消费不同的 MessageQueue因此总体的消费进度保存在 Broker 上集中的管理
### 2.1.10 RocketMQ 不使用 ZooKeeper 作为注册中心的原因,以及自制的 NameServer 优缺点?
#### 2.1.10 RocketMQ 不使用 ZooKeeper 作为注册中心的原因,以及自制的 NameServer 优缺点?
1. ZooKeeper 作为支持顺序一致性的中间件在某些情况下它为了满足一致性会丢失一定时间内的可用性RocketMQ 需要注册中心只是为了发现组件地址在某些情况下RocketMQ 的注册中心可以出现数据不一致性,这同时也是 NameServer 的缺点,因为 NameServer 集群间互不通信,它们之间的注册信息可能会不一致
2. 另外当有新的服务器加入时NameServer 并不会立马通知到 Producer而是由 Producer 定时去请求 NameServer 获取最新的 Broker/Consumer 信息(这种情况是通过 Producer 发送消息时,负载均衡解决)
### 2.1.11 其它
#### 2.1.11 其它
![][1]
@ -203,7 +186,7 @@ class Broker {
4. Broker 同步双写和异步双写中 Master 和 Slave 的交互
5. Broker 在 4.5.0 版本更新中引入了基于 Raft 协议的多副本选举,之前这是商业版才有的特性 [ISSUE-1046][2]
# 3 参考
## 3 参考
1. 《RocketMQ技术内幕》https://blog.csdn.net/prestigeding/article/details/85233529
2. 关于 RocketMQ 对 MappedByteBuffer 的一点优化https://lishoubo.github.io/2017/09/27/MappedByteBuffer%E7%9A%84%E4%B8%80%E7%82%B9%E4%BC%98%E5%8C%96/

View File

@ -1,3 +1,5 @@
# 读写分离&分库分表
大家好呀!今天和小伙伴们聊聊读写分离以及分库分表。
相信很多小伙伴们对于这两个概念已经比较熟悉了,这篇文章全程都是大白话的形式,希望能够给你带来不一样的感受。
@ -8,8 +10,6 @@
_个人能力有限。如果文章有任何需要补充/完善/修改的地方欢迎在评论区指出共同进步_
# 读写分离&分库分表
## 读写分离
### 何为读写分离?

View File

@ -0,0 +1,13 @@
# 负载均衡
负载均衡系统通常用于将任务比如用户请求处理分配到多个服务器处理以提高网站、应用或者数据库的性能和可靠性。
常见的负载均衡系统包括 3 种:
1. **DNS 负载均衡** :一般用来实现地理级别的均衡。
2. **硬件负载均衡** 通过单独的硬件设备比如 F5 来实现负载均衡功能(硬件的价格一般很贵)。
3. **软件负载均衡** :通过负载均衡软件比如 Nginx 来实现负载均衡功能。
## 推荐阅读
- [《凤凰架构》-负载均衡](http://icyfenix.cn/architect-perspective/general-architecture/diversion-system/load-balancing.html)

View File

@ -0,0 +1,27 @@
---
title: Camel Case命名之间快速切换
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
非常有用这个插件可以实现包含6种常见命名格式之间的切换。并且你还可以对转换格式进行相关配置转换格式如下图所示
![img](./pictures/camel-case/camel-case1.png)
有了这个插件之后,你只需要使用快捷键 `shift+option+u(mac)` / `shift+alt+u` 对准你要修改的变量或者方法名字,就能实现在多种格式之间切换了,如下图所示:
![](./pictures/camel-case/camel-case2.gif)
如果你突然忘记快捷键的话可以直接在IDEA的菜单栏的 Edit 部分找到。
![](./pictures/camel-case/camel-case3.png)
使用这个插件对开发效率提升高吗?拿我之前项目组的情况举个例子:
我之前有一个项目组的测试名字是驼峰这种形式: `ShouldReturnTicketWhenRobotSaveBagGiven1LockersWith2FreeSpace` 。但是使用驼峰形式命名测试方法的名字不太明显一般建议用下划线_的形式 `should_return_ticket_when_robot_save_bag_given_1_lockers_with_2_free_space`
如果我们不用这个插件,而是手动去一个一个改的话,工作量想必会很大,而且正确率也会因为手工的原因降低。
>

View File

@ -0,0 +1,11 @@
---
title: CodeGlance代码微型地图
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
CodeGlance提供一个代码的微型地图当你的类比较多的时候可以帮忙你快速定位到要去的位置。这个插件在我们日常做普通开发的时候用处不大不过在你阅读源码的时候还是很有用的如下图所示
![](./pictures/code-glance.png)

View File

@ -0,0 +1,39 @@
---
title: Statistic项目代码统计
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
编程是一个很奇妙的事情,大部分的我们把大部分时间实际都花在了复制粘贴,而后修改代码上面。
很多时候,我们并不关注代码质量,只要功能能实现,我才不管一个类的代码有多长、一个方法的代码有多长。
因此,我们经常会碰到让自己想要骂街的项目,不过,说真的,你自己写的代码也有极大可能被后者 DISS。
为了快速分析项目情况,判断这个项目是不是一个“垃圾”项目,有一个方法挺简单的。
那就是**对代码的总行数、单个文件的代码行数、注释行数等信息进行统计。**
**怎么统计呢?**
首先想到的是 Excel 。不过,显然太麻烦了。
**有没有专门用于代码统计的工具呢?**
基于Perl语言开发的cloccount lines of code或许可以满足你的要求。
**有没有什么更简单的办法呢?**
如果你使用的是 IDEA 进行开发的话,推荐你可以使用一下 **Statistic** 这个插件。
有了这个插件之后你可以非常直观地看到你的项目中所有类型的文件的信息比如数量、大小等等,可以帮助你更好地了解你们的项目。
![](./pictures/Statistic1.png)
你还可以使用它看所有类的总行数、有效代码行数、注释行数、以及有效代码比重等等这些东西。
![](./pictures/Statistic2.png)
如果你担心插件过多影响IDEA速度的话可以只在有代码统计需求的时候开启这个插件其他时间禁用它就完事了

View File

@ -0,0 +1,19 @@
---
title: Git Commit Template提交代码格式规范
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
没有安装这个插件之前我们使用IDEA提供的Commit功能提交代码是下面这样的
![](./pictures/git-commit-template/Git-Commit-Template1.png)
使用了这个插件之后是下面这样的提供了一个commit信息模板的输入框
![](./pictures/git-commit-template/Git-Commit-Template2.png)
完成之后的效果是这样的:
![](./pictures/git-commit-template/Git-Commit-Template3.png)

View File

@ -0,0 +1,32 @@
---
title: GsonFormatJSON转对象
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
GsonFormat 这个插件可以根据Gson库使用的要求,将JSONObject格式的String 解析成实体类。
> 说明2021.x 版本以上的 IDEA 可以使用GsonFormatPlus
这个插件使用起来非常简单,我们新建一个类,然后在类中使用快捷键 `option + s`(Mac)或`alt + s` (win)调出操作窗口(**必须在类中使用快捷键才有效**),如下图所示。
![](./pictures/GsonFormat2.gif)
这个插件是一个国人几年前写的不过已经很久没有更新了可能会因为IDEA的版本问题有一些小Bug。而且这个插件无法将JSON转换为Kotlin这个其实无关痛痒IDEA自带的就有Java转Kotlin的功能
![](./pictures/GsonFormat1.png)
另外一个与之相似的插件是 **RoboPOJOGenerator** ,这个插件的更新频率比较快。
`File-> new -> Generate POJO from JSON`
![](./pictures/RoboPOJOGenerator1.png)
然后将JSON格式的数据粘贴进去之后配置相关属性之后选择“*Generate*”
![](./pictures/RoboPOJOGenerator2.png)

View File

@ -0,0 +1,17 @@
---
title: IDE Features TrainerIDEA 交互式教程
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
**有了这个插件之后,你可以在 IDE 中以交互方式学习IDEA最常用的快捷方式和最基本功能。** 非常非常非常方便强烈建议大家安装一个尤其是刚开始使用IDEA的朋友。
当我们安装了这个插件之后你会发现我们的IDEA 编辑器的右边多了一个“**Learn**”的选项,我们点击这个选项就可以看到如下界面。
![](./pictures/IDE-Features-Trainer1.png?lastModify=1633856821)
我们选择“Editor Basics”进行然后就可以看到如下界面这样你就可以按照指示来练习了非常不错
![](./pictures/IDE-Features-Trainer2.png?lastModify=1633856821)

View File

@ -0,0 +1,99 @@
---
title: IDEA主题推荐
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
经常有小伙伴问我“Guide哥你的IDEA 主题怎么这么好看,能推荐一下不?”。就实在有点不耐烦了,才索性写了这篇文章。
在这篇文章中,我精选了几个比较是和 Java 编码的 IDEA 主题供小伙伴们选择。另外,我自己用的是 One Dark theme 这款。
**注意:以下主题按照使用人数降序排序。**
## [Material Theme UI](https://plugins.jetbrains.com/plugin/8006-material-theme-ui)
**推荐指数** :⭐⭐⭐⭐
这是 IDEA 中使用人数最多的一款主题。
当你安装完这个插件之后,你会发现这个主题本身又提供了多种相关的主题供你选择。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20/image-20201119182935201.png)
**Material Deep Ocean** 这款的效果图如下。默认的字体是真的小,小伙伴们需要自行调整一下。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20/image-20201119183044068.png)
## [One Dark theme](https://plugins.jetbrains.com/plugin/11938-one-dark-theme)
**推荐指数** :⭐⭐⭐⭐⭐
我比较喜欢的一款(*黄色比较多?*)。 没有花里花哨,简单大气,看起来比较舒服。颜色搭配也很棒,适合编码!
这款主题的效果图如下。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20-11/image-20201119180300975.png)
## [Gradianto](https://plugins.jetbrains.com/plugin/12334-gradianto)
**推荐指数** :⭐⭐⭐⭐⭐
Gradianto这个主题的目标是在保持页面色彩比较层次分明的情况下让我们因为代码而疲惫的双眼更加轻松。
Gradianto附带了自然界的渐变色看着挺舒服的。另外这个主题本身也提供了多种相关的主题供你选择。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20/image-20201119183825753.png)
**Gradianto Nature Green** 的效果图如下。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20/image-20201119183920889.png)
## [Dark Purple Theme](https://plugins.jetbrains.com/plugin/12100-dark-purple-theme)
**推荐指数** :⭐⭐⭐⭐⭐
这是一款紫色色调的深色主题,喜欢紫色的小伙伴不要错过。
这个主题的效果图如下。个人觉得整体颜色搭配的是比较不错的,适合编码!
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20-11/image-20201119184654132.png)
## [Hiberbee Theme](https://plugins.jetbrains.com/plugin/12118-hiberbee-theme)
**推荐指数** :⭐⭐⭐⭐⭐
一款受到了 Monokai Pro 和 MacOS Mojave启发的主题是一款色彩层次分明的深色主题。
这个主题的效果图如下。看着也是非常赞!适合编码!
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20-11/image-20201119191441248.png)
上面推荐的都是偏暗色系的主题,这里我再推荐两款浅色系的主题。
## [Gray Theme](https://plugins.jetbrains.com/plugin/12103-gray-theme)
**推荐指数** :⭐⭐⭐
这是一款对比度比较低的一款浅色主题不太适合代码阅读毕竟这款主题是专门为在IntelliJ IDE中使用Markdown而设计的。
这个主题的效果图如下。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-3@main/11-20-11/image-20201119194512164.png)
## [Roboticket Light Theme](https://plugins.jetbrains.com/plugin/12191-roboticket-light-theme)
**推荐指数** :⭐⭐⭐
这是一款对比度比较低的浅色主题,不太适合代码阅读。
这个主题的效果图如下。
![](https://img-blog.csdnimg.cn/img_convert/194581c7b72d49b512b12814340f00c8.png)
## 后记
我个人还是比较偏爱深色系的主题。
小伙伴们比较喜欢哪款主题呢?可以在评论区简单聊聊不?如果你还有其他比较喜欢的主题也可以在评论区说出来供大家参考哦!

View File

@ -0,0 +1,153 @@
---
title: IDEA 代码优化插件推荐
category: IDEA指南
tag:
- IDEA
- IDEA插件
- 代码优化
---
## Lombok:帮你简化代码
之前没有推荐这个插件的原因是觉得已经是人手必备的了。如果你要使用 Lombok 的话,不光是要安装这个插件,你的项目也要引入相关的依赖。
```xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
```
使用 Lombok 能够帮助我们少写很多代码比如 Getter/Setter、Constructor等等。
关于Lombok的使用可以查看这篇文章[《十分钟搞懂Java效率工具Lombok使用与原理》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485385&idx=2&sn=a7c3fb4485ffd8c019e5541e9b1580cd&chksm=cea24802f9d5c1144eee0da52cfc0cc5e8ee3590990de3bb642df4d4b2a8cd07f12dd54947b9&token=1667678311&lang=zh_CN#rd)。
## Codota代码智能提示
我一直在用的一个插件,可以说非常好用了(*我身边的很多大佬平时写代码也会用这个插件*)。
Codota 这个插件用于智能代码补全它基于数百万Java程序能够根据程序上下文提示补全代码。相比于IDEA自带的智能提示来说Codota 的提示更加全面一些。
如果你觉得 IDEA 插件安装的太多比较卡顿的话不用担心Codota 插件还有一个对应的在线网站([https://www.codota.com/code](https://www.codota.com/code)),在这个网站上你可以根据代码关键字搜索相关代码示例,非常不错!
我在工作中经常会用到,说实话确实给我带来了很大便利,比如我们搜索 `Files.readAllLines`相关的代码,搜索出来的结果如下图所示:
![](./pictures/Codota3.png)
另外Codota 插件的基础功能都是免费的。你的代码也不会被泄露,这点你不用担心。
简单来看看 Codota 插件的骚操作吧!
### 代码智能补全
我们使用`HttpUrlConnection ` 建立一个网络连接是真的样的:
![](./pictures/Codota1.gif)
我们创建线程池现在变成下面这样:
![](./pictures/Codota4.gif)
上面只是为了演示这个插件的强大,实际上创建线程池不推荐使用这种方式, 推荐使用 `ThreadPoolExecutor` 构造函数创建线程池。我下面要介绍的一个阿里巴巴的插件-**Alibaba Java Code Guidelines** 就检测出来了这个问题,所以,`Executors`下面用波浪线标记了出来。
### 代码智能搜索
除了,在写代码的时候智能提示之外。你还可以直接选中代码然后搜索相关代码示例。
![](./pictures/Codota2.png)
## Alibaba Java Code Guidelines阿里巴巴 Java 代码规范
阿里巴巴 Java 代码规范对应的Github地址为[https://github.com/alibaba/p3c](https://github.com/alibaba/p3c ) 。非常推荐安装!
安装完成之后建议将与语言替换成中文,提示更加友好一点。
![](./pictures/p3c/Alibaba-Java-Code-Guidelines2.png)
根据官方描述:
> 目前这个插件实现了开发手册中的的53条规则大部分基于PMD实现其中有4条规则基于IDEA实现并且基于IDEA [Inspection](https://www.jetbrains.com/help/idea/code-inspection.html)实现了实时检测功能。部分规则实现了Quick Fix功能对于可以提供Quick Fix但没有提供的我们会尽快实现也欢迎有兴趣的同学加入进来一起努力。 目前插件检测有两种模式:实时检测、手动触发。
上述提到的开发手册也就是在Java开发领域赫赫有名的《阿里巴巴Java开发手册》。
### 手动配置检测规则
你还可以手动配置相关 inspection规则
![](./pictures/p3c/Alibaba-Java-Code-Guidelines3.png)
### 使用效果
这个插件会实时检测出我们的代码不匹配它的规则的地方,并且会给出修改建议。比如我们按照下面的方式去创建线程池的话,这个插件就会帮我们检测出来,如下图所示。
![](./pictures/p3c/Alibaba-Java-Code-Guidelines1.png)
这个可以对应上 《阿里巴巴Java开发手册》 这本书关于创建线程池的方式说明。
![](./pictures/p3c/阿里巴巴开发手册-线程池创建.png)
## CheckStyle: Java代码格式规范
### 为何需要CheckStyle插件
**CheckStyle 几乎是 Java 项目开发必备的一个插件了,它会帮助我们检查 Java 代码的格式是否有问题比如变量命名格式是否有问题、某一行代码的长度是否过长等等。**
在项目上,**通过项目开发人员自我约束来规范代码格式必然是不靠谱的!** 因此,我们非常需要这样一款工具来帮助我们规范代码格式。
如果你看过我写的轮子的话,可以发现我为每一个项目都集成了 CheckStyle并且设置了 **Git Commit 钩子**,保证在提交代码之前代码格式没有问题。
> **Guide哥造的轮子***代码简洁,结构清晰,欢迎学习,欢迎一起完善*
>
> 1. [guide-rpc-framework](https://github.com/Snailclimb/guide-rpc-framework) A custom RPC framework implemented by Netty+Kyro+Zookeeper.(一款基于 Netty+Kyro+Zookeeper 实现的自定义 RPC 框架-附详细实现过程和相关教程)
> 2. [jsoncat](https://github.com/Snailclimb/jsoncat) :仿 Spring Boot 但不同于 Spring Boot 的一个轻量级的 HTTP 框架
>
> **Git 钩子** Git 能在特定的重要动作比如commit、push发生时触发自定义脚本。 钩子都被存储在 Git 目录下的 `hooks` 子目录中。 也即绝大部分项目中的 `.git/hooks`
### 如何在Maven/Gradle项目中集成 Checksytle?
一般情况下,我们都是将其集成在项目中,并设置相应的 Git 钩子。网上有相应的介绍文章,这里就不多提了。
如果你觉得网上的文章不直观的话,可以参考我上面提到了两个轮子:
1. [guide-rpc-framework](https://github.com/Snailclimb/guide-rpc-framework) Maven项目集成 Checksytle。
2. [jsoncat](https://github.com/Snailclimb/jsoncat) Gradle项目集成 Checksytle。
如果你在项目中集成了 Checksytle 的话,每次检测会生成一个 HTML格式的文件告诉你哪里的代码格式不对这样看着非常不直观。通过 Checksytle插件的话可以非常直观的将项目中存在格式问题的地方显示出来。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/IDEA%E6%8F%92%E4%BB%B6/image-20201013135044410.png)
如果你只是自己在本地使用,并不想在项目中集成 Checksytle 的话也可以,只需要下载一个 Checksytle插件就足够了。
### 如何安装?
我们直接在 IDEA 的插件市场即可找到这个插件。我这里已经安装好了。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/IDEA%E6%8F%92%E4%BB%B6/image-20201013103610557.png)
安装插件之后重启 IDEA你会发现就可以在底部菜单栏找到 CheckStyle 了。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/IDEA%E6%8F%92%E4%BB%B6/image-20201013134644991.png)
### 如何自定义检测规则?
如果你需要自定义代码格式检测规则的话,可以按照如下方式进行配置(你可以导入用于自定义检测规则的`CheckStyle.xml`文件)。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/IDEA%E6%8F%92%E4%BB%B6/setting-check-style.png)
### 使用效果
配置完成之后,按照如下方式使用这个插件!
![run-check-style](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/IDEA%E6%8F%92%E4%BB%B6/run-check-style.png)
可以非常清晰的看到CheckStyle 插件已经根据我们自定义的规则将项目中的代码存在格式问题的地方都检测了出来。
## SonarLint:帮你优化代码
SonarLint 帮助你发现代码的错误和漏洞就像是代码拼写检查器一样SonarLint 可以实时显示出代码的问题,并提供清晰的修复指导,以便你提交代码之前就可以解决它们。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images-2@main/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/image-20201019222817359.png)
并且,很多项目都集成了 SonarQube,SonarLint 可以很方便地与 SonarQube 集成。

View File

@ -0,0 +1,67 @@
---
title: IDEA 界面美化插件推荐
category: IDEA指南
tag:
- IDEA
- IDEA插件
- 代码优化
---
## Background Image Plus:背景图片
我这里推荐使用国人 Jack Chu 基于 Background Image Plus 开发的最新版本,适用于 2021.x 版本的 IDEA。
前面几个下载量比较高的,目前都还未支持 2021.x 版本的 IDEA。
![Background Image Plus](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/idea/image-20211010174138279.png)
通过这个插件,你可以将 IDEA 背景设置为指定的图片,支持随机背景。
效果图如下:
![Background Image Plus 设置背景效果图](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/idea/image-20211010173730828.png)
如果你想要设置随机背景的话,可以通过 IDEA 设置页 **Settings** -> **Appearance & Behaviour** -> **Background Image Plus** 自定义设置项,随机显示目录下的图片为背景图。
## Power Mode II : 代码特效
使用了这个插件之后,写代码会自带特效,适用于 2021.x 版本的 IDEA。 2021.x 版本之前,可以使用 **activate-power-mode**
![Power Mode II 效果图](./pictures/power-mode/Power-Mode-II.gif)
你可以通过 IDEA 设置页 **Settings** -> **Appearance & Behaviour** -> **Power Mode II** 自定义设置项。
![Power Mode II](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/idea/image-20211010175304108.png)
## Nyan Progress Bar : 进度条美化
可以让你拥有更加漂亮的进度条。
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/idea/image-20211010175434133.png)
## Grep Console:控制台输出处理
可以说是必备的一个 IDEA 插件,非常实用!
这个插件主要的功能有两个:
**1. 自定义设置控制台输出颜色**
我们可以在设置中进行相关的配置:
![](./pictures/grep-console/grep-console2.png)
配置完成之后的 log warn 的效果对比图如下:
![](./pictures/grep-console/grep-console3.png)
**2. 过滤控制台输出**
![](./pictures/grep-console/grep-console.gif)
## Rainbow Brackets : 彩虹括号
使用各种鲜明的颜色来展示你的括号,效果图如下。可以看出代码层级变得更加清晰了,可以说非常实用友好了!
![](./pictures/rainbow-brackets.png)

View File

@ -0,0 +1,93 @@
---
title: jclasslib 一款IDEA字节码查看神器
category: IDEA指南
tag:
- IDEA
- IDEA插件
- 字节码
---
由于后面要分享的一篇文章中用到了这篇文章要推荐的一个插件,所以这里分享一下。非常实用!你会爱上它的!
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B8%93%E4%B8%9A%E5%AD%A6%E4%B9%A0%E6%8C%87%E5%8D%97/image-20201013084919965.png)
**开始推荐 IDEA 字节码查看神器之前,先来回顾一下 Java 字节码是啥。**
## 何为 Java 字节码?
Java 虚拟机JVM是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现WindowsLinuxmacOS目的是使用相同的字节码它们都会给出相同的结果。
**什么是字节码?采用字节码的好处是什么?**
> 在 Java 中JVM 可以理解的代码就叫做`字节码`(即扩展名为 `.class` 的文件它不面向任何特定的处理器只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效而且由于字节码并不针对一种特定的机器因此Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。
**Java 程序从源代码到运行一般有下面 3 步:**
![Java程序运行过程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/Java%20%E7%A8%8B%E5%BA%8F%E8%BF%90%E8%A1%8C%E8%BF%87%E7%A8%8B.png)
## 为什么要查看 Java 字节码?
我们在平时学习的时候,经常需要查看某个 java 类的字节码文件。查看字节码文件更容易让我们搞懂 java 代码背后的原理比如搞懂 java 中的各种语法糖的本质。
## 如何查看 Java 字节码?
如果我们通过命令行来查看某个 class 的字节码文件的话,可以直接通过 `javap` 命令,不过这种方式太原始了,效率十分低,并且看起来不直观。
下面介绍两种使用 IDEA 查看类对应字节码文件的方式_`javap`这种方式就不提了_
我们以这段代码作为案例:
```java
public class Main {
public static void main(String[] args) {
Integer i = null;
Boolean flag = false;
System.out.println(flag ? 0 : i);
}
}
```
上面这段代码由于使用三目运算符不当导致诡异了 NPE 异常。为了搞清楚事情的原因,我们来看其对应的字节码。
### 使用 IDEA 自带功能
我们点击 `View -> Show Bytecode` 即可通过 IDEA 查看某个类对应的字节码文件。
> 需要注意的是:**查看某个类对应的字节码文件之前确保它已经被编译过。**
![使用IDEA自带功能查看Java字节码](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/IDEA%E6%8F%92%E4%BB%B6/image-20201012143530226.png)
稍等几秒钟之后,你就可以直观到看到对应的类的字节码内容了。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-10/image-20201012145127465.png)
从字节码中可以看出,我圈出来的位置发生了 **拆箱操作**
> - **装箱**:将基本类型用它们对应的引用类型包装起来;
> - **拆箱**:将包装类型转换为基本数据类型;
详细解释下就是:`flag ? 0 : i` 这行代码中0 是基本数据类型 int返回数据的时候 i 会被强制拆箱成 int 类型,由于 i 的值是 null因此就抛出了 NPE 异常。
```java
Integer i = null;
Boolean flag = false;
System.out.println(flag ? 0 : i);
```
如果,我们把代码中 `flag` 变量的值修改为 true 的话,就不会存在 NPE 问题了,因为会直接返回 0不会进行拆箱操作。
### 使用 IDEA 插件 jclasslib(推荐)
相比于 IDEA 自带的查看类字节的功能,我更推荐 `jclasslib` 这个插件,非常棒!
**使用 `jclasslib` 不光可以直观地查看某个类对应的字节码文件,还可以查看类的基本信息、常量池、接口、属性、函数等信息。**
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-10/image-20201012145646086.png)
我们直接在 IDEA 的插件市场即可找到这个插件。我这里已经安装好了。
![](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/2020-10-12/image-20201012145900911.png)
安装完成之后,重启 IDEA。点击`View -> Show Bytecode With jclasslib` 即可通过`jclasslib` 查看某个类对应的字节码文件。
![使用IDEA插件jclasslib查看类的字节码](https://cdn.jsdelivr.net/gh/javaguide-tech/blog-images/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B8%93%E4%B8%9A%E5%AD%A6%E4%B9%A0%E6%8C%87%E5%8D%97/image-20201012150252106.png)

View File

@ -0,0 +1,19 @@
---
title: Maven Helper解决 Maven 依赖冲突问题
category: IDEA指南
tag:
- IDEA
- IDEA插件
- Maven
---
**Maven Helper** 主要用来分析 Maven 项目的相关依赖,可以帮助我们解决 Maven 依赖冲突问题。
![](./pictures/maver-helper.png)
**何为依赖冲突?**
说白了就是你的项目使用的 2 个 jar 包引用了同一个依赖 h并且 h 的版本还不一样,这个时候你的项目就存在两个不同版本的 h。这时 Maven 会依据依赖路径最短优先原则,来决定使用哪个版本的 Jar 包,而另一个无用的 Jar 包则未被使用,这就是所谓的依赖冲突。
大部分情况下,依赖冲突可能并不会对系统造成什么异常,因为 Maven 始终选择了一个 Jar 包来使用。但是,不排除在某些特定条件下,会出现类似找不到类的异常,所以,只要存在依赖冲突,在我看来,最好还是解决掉,不要给系统留下隐患。

View File

@ -0,0 +1,21 @@
---
title: 其他
category: IDEA指南
tag:
- IDEA
- IDEA插件
---
1. **leetcode editor** :提供在线 Leetcode 刷题功能,比较方便我们刷题,不过我试用之后发现有一些小 bug个人感觉还是直接在网站找题目刷来的痛快一些。
2. **A Search with Github** :直接通过 Github搜索相关代码。
3. **stackoverflow** : 选中相关内容后单击右键即可快速跳转到 stackoverflow 。
4. **CodeStream** 让code review变得更加容易。
5. **Code screenshots** :代码片段保存为图片。
6. **GitToolBox** :Git工具箱
7. **OK, Gradle!** 搜索Java库用于Gradle项目
8. **Java Stream Debugger** : Java8 Stream调试器
9. **EasyCode** : Easycode 可以直接对数据的表生成entity、controller、service、dao、mapper无需任何编码简单而强大。更多内容可以查看这篇文章[《懒人 IDEA 插件插件:EasyCode 一键帮你生成所需代码~》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486205&idx=1&sn=0ff2f87f0d82a1bd9c0c44328ef69435&chksm=cea24536f9d5cc20c6cc7669f0d4167d747fe8b8c05a64546c0162d694aa96044a2862e24b57&token=1862674725&lang=zh_CN#rd)
10. **JFormDesigner** Swing GUI 在线编辑器。
11. **VisualVM Launcher** Java性能分析神器。
12. ......

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

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