Merge pull request #2 from CyC2018/master

update
This commit is contained in:
Peter Ma 2019-02-05 01:51:40 -08:00 committed by GitHub
commit fc3c2e2ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 180 additions and 363 deletions

114
README.md
View File

@ -1,52 +1,46 @@
<!-- | | Ⅱ | Ⅲ | Ⅳ | | Ⅵ | Ⅶ | Ⅷ | Ⅸ | |
<!--| | Ⅱ | Ⅲ | Ⅳ | | Ⅵ | Ⅶ | Ⅷ | Ⅸ | |
| :--------: | :---------: | :---------: | :---------: | :---------: | :---------:| :---------: | :-------: | :-------:| :------:|
| 算法[:pencil2:](#pencil2-算法) | 操作系统[:computer:](#computer-操作系统)|网络[:cloud:](#cloud-网络) | 面向对象[:couple:](#couple-面向对象) |数据库[:floppy_disk:](#floppy_disk-数据库)| Java [:coffee:](#coffee-java)| 系统设计[:bulb:](#bulb-系统设计)| 工具[:hammer:](#hammer-工具)| 编码实践[:speak_no_evil:](#speak_no_evil-编码实践)| 后记[:memo:](#memo-后记) | -->
| 算法[:pencil2:](#pencil2-算法) | 操作系统[:computer:](#computer-操作系统)|网络[:cloud:](#cloud-网络) | 面向对象[:art:](#art-面向对象) |数据库[:floppy_disk:](#floppy_disk-数据库)| Java [:coffee:](#coffee-java)| 系统设计[:bulb:](#bulb-系统设计)| 工具[:wrench:](#wrench-工具)| 编码实践[:watermelon:](#watermelon-编码实践)| 后记[:memo:](#memo-后记) | -->
<!-- | | Ⅱ | Ⅲ | Ⅳ | |
| :--------: | :---------: | :---------: | :---------: | :---------: |
| &emsp;&emsp;&emsp;算法&emsp;&emsp;&emsp;<br>[:pencil2:](#pencil2-算法) | &emsp;&emsp;&emsp;操作系统&emsp;&emsp;&emsp;<br>[:computer:](#computer-操作系统) | &emsp;&emsp;&emsp;&emsp;网络&emsp;&emsp;&emsp;&emsp;<br>[:cloud:](#cloud-网络) | &emsp;&emsp;&emsp;面向对象&emsp;&emsp;&emsp;<br>[:couple:](#couple-面向对象) | &emsp;&emsp;&emsp;数据库&emsp;&emsp;<br>[:floppy_disk:](#floppy_disk-数据库)|
| Ⅵ | Ⅶ | Ⅷ | Ⅸ | |
|:---------:| :---------: | :-------: | :-------:| :------:|
| &emsp;&emsp;&emsp;Java&emsp;&emsp;&emsp;<br>[:coffee:](#coffee-java) | &emsp;&emsp;&emsp;系统设计&emsp;&emsp;&emsp;<br>[:bulb:](#bulb-系统设计) | &emsp;&emsp;&emsp;&emsp;工具&emsp;&emsp;&emsp;&emsp;<br>[:hammer:](#hammer-工具) | &emsp;&emsp;&emsp;编码实践&emsp;&emsp;&emsp;<br>[:speak_no_evil:](#speak_no_evil-编码实践) | &emsp;&emsp;&emsp;后记 &emsp;&emsp;&emsp;<br>[:memo:](#memo-后记) |
-->
| &nbsp;&nbsp;&nbsp;算法&nbsp;&nbsp;&nbsp; | 操作系统 | &nbsp;&nbsp;&nbsp;网络&nbsp;&nbsp;&nbsp; | 面向对象 | &nbsp;&nbsp;数据库&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;Java&nbsp;&nbsp;&nbsp; | 系统设计 | &nbsp;&nbsp;&nbsp;工具&nbsp;&nbsp;&nbsp; | 编码实践 | &nbsp;&nbsp;&nbsp;后记&nbsp;&nbsp;&nbsp; |
| :--------: | :---------: | :---------: | :---------: | :---------: | :---------:| :---------: | :-------: | :-------:| :------:|
| [:pencil2:](#pencil2-算法) | [:computer:](#computer-操作系统)|[:cloud:](#cloud-网络) | [:art:](#art-面向对象) |[:floppy_disk:](#floppy_disk-数据库)| [:coffee:](#coffee-java)| [:bulb:](#bulb-系统设计)| [:wrench:](#wrench-工具)| [:watermelon:](#watermelon-编码实践)| [:memo:](#memo-后记) |
<br>
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
<div align="center">
<img src="other/LogoMakr_0zpEzN.png" width="190px">
<img src="other/LogoMakr_0zpEzN.png" width="200px">
<br>
<a href="https://cyc2018.github.io/CS-Notes"> <img src="https://img.shields.io/badge/>-read-4ab8a1.svg"></a> <a href="https://xiaozhuanlan.com/CyC2018"> <img src="https://img.shields.io/badge/_-more-4ab8a1.svg"></a>
<br> <br>
本项目包含了技术面试必备的基础知识,浅显易懂,你不需要花很长的时间去阅读和理解成堆的技术书籍就可以快速掌握这些知识,从而节省宝贵的面试复习时间。你也可以订阅 <a href="https://xiaozhuanlan.com/CyC2018">面试进阶专栏</a>,包含了学习指导和面试技巧,让你更轻松拿到满意的 Offer。
</div>
<br/>
<br>
### :pencil2: 算法
## :pencil2: 算法
- [剑指 Offer 题解](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/剑指%20offer%20题解.md)
- [Leetcode 题解](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Leetcode%20题解.md)
- [算法](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/算法.md)
### :computer: 操作系统
## :computer: 操作系统
- [计算机操作系统](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/计算机操作系统.md)
- [Linux](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Linux.md)
### :cloud: 网络
## :cloud: 网络
- [计算机网络](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/计算机网络.md)
- [HTTP](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/HTTP.md)
- [Socket](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Socket.md)
### :couple: 面向对象
## :art: 面向对象
- [设计模式](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/设计模式.md)
- [面向对象思想](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/面向对象思想.md)
### :floppy_disk: 数据库
## :floppy_disk: 数据库
- [数据库系统原理](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/数据库系统原理.md)
- [SQL](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/SQL.md)
@ -54,7 +48,7 @@
- [MySQL](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/MySQL.md)
- [Redis](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Redis.md)
### :coffee: Java
## :coffee: Java
- [Java 基础](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Java%20基础.md)
- [Java 容器](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Java%20容器.md)
@ -62,7 +56,7 @@
- [Java 虚拟机](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Java%20虚拟机.md)
- [Java I/O](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Java%20IO.md)
### :bulb: 系统设计
## :bulb: 系统设计
- [系统设计基础](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/系统设计基础.md)
- [分布式](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/分布式.md)
@ -71,69 +65,64 @@
- [缓存](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/缓存.md)
- [消息队列](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/消息队列.md)
### :hammer: 工具
## :wrench: 工具
- [Git](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Git.md)
- [Docker](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Docker.md)
- [构建工具](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/构建工具.md)
- [正则表达式](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/正则表达式.md)
### :speak_no_evil: 编码实践
## :watermelon: 编码实践
- [代码可读性](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/代码可读性.md)
- [代码风格规范](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/代码风格规范.md)
### :memo: 后记
## :memo: 后记
#### 关于
### 内推信息
本仓库主要是根据计算机经典书籍以及官方技术文档进行总结的学习笔记,希望对大家有所帮助。
[Job-Recommend](https://github.com/CyC2018/Job-Recommend)
学习笔记不是从网上到处拼凑而来,除了少部分引用书上和技术文档的原文,其余都是笔者的原创。在您引用本仓库内容或者对内容进行修改演绎时,请遵循文末的开源协议,谢谢。
### 专栏
#### 如何贡献
[面试进阶指南](https://xiaozhuanlan.com/CyC2018)
笔记内容是笔者一个字一个字打上去的,难免会有一些笔误,如果发现笔误可直接对相应文档进行编辑修改。
### 知识星球
如果想要提交一个仓库现在还没有的全新内容,可以先将相应的文档放到 other 目录下
想要向我提问关于学习和求职方面的建议?来知识星球,你的每个提问我都会认真回答
#### 交流群
[知识星球](other/Planet.md)
为大家提供一个学习交流平台,在这里你可以自由地和笔者以及其他人进行技术上的交流。
### QQ 群
[💬](other/Group.md)
为大家提供一个学习交流平台,在这里你可以自由地讨论技术问题。
#### 知识星球
<img src="https://github.com/CyC2018/CS-Notes/raw/master/other/group1.png" width="200px"></br>
想要向笔者提问关于学习和求职方面的建议?来知识星球,你的每个提问我都会认真回答。
### 排版
[🎓](other/Planet.md)
笔记内容按照 [文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines) 进行排版,以保证内容的可读性。笔记不使用 `![]()` 这种方式来引用图片,而是用 `<img>` 标签。一方面是为了能够控制图片以合适的大小显示,另一方面是因为 GFM 不支持 `<center> ![]() </center>` 让图片居中显示,只能使用 `<div align="center"> <img src=""/> </div>` 达到居中的效果。
#### 内推信息
我将自己实现的文档排版功能提取出来,放在 Github Page 中,无需下载安装即可免费使用:[Text-Typesetting](https://github.com/CyC2018/Text-Typesetting)。
[🔎](https://github.com/CyC2018/Job-Recommend)
### 上传方案
#### 排版
我在本地使用为知笔记软件进行书写,为了方便将本地笔记内容上传到 Github 上实现了一整套自动化上传方案包括文本文件的导出、提取图片、Markdown 文档转换、Git 同步。进行 Markdown 文档转换是因为 Github 使用的 GFM 不支持 MathJax 公式和 TOC 标记,所以需要替换 MathJax 公式为 CodeCogs 的云服务和重新生成 TOC 目录。
笔记内容按照 [中文文案排版指北](https://mazhuang.org/wiki/chinese-copywriting-guidelines/) 进行排版,以保证内容的可读性。笔记不使用 `![]()` 这种方式来引用图片,而是用 `<img>` 标签。一方面是为了能够控制图片以合适的大小显示,另一方面是因为 GFM 不支持 `<center> ![]() </center>` 让图片居中显示,只能使用 `<div align="center"> <img src=""/> </div>` 达到居中的效果。笔者将自己实现的文档排版功能提取出来,放在 Github Page 中,无需下载安装即可免费使用:[Text-Typesetting](https://github.com/CyC2018/Markdown-Typesetting)。
我将自己实现文档转换功能提取出来,方便大家在需要将本地 Markdown 上传到 Github或者制作项目 README 文档时生成目录时使用:[GFM-Converter](https://github.com/CyC2018/GFM-Converter)。
#### 上传方案
### License
笔者在本地使用为知笔记软件进行书写,为了方便将本地笔记内容上传到 Github 上实现了一整套自动化上传方案包括文本文件的导出、提取图片、Markdown 文档转换、Git 同步。进行 Markdown 文档转换是因为 Github 使用的 GFM 不支持 MathJax 公式和 TOC 标记,所以需要替换 MathJax 公式为 CodeCogs 的云服务和重新生成 TOC 目录。
笔者将自己实现文档转换功能提取出来,方便大家在需要将本地 Markdown 上传到 Github或者制作项目 README 文档时生成目录时使用:[GFM-Converter](https://github.com/CyC2018/GFM-Converter)。
#### Logo
Power by [logomakr](https://logomakr.com/).
#### License
在对本作品进行演绎时,请署名并以相同方式共享。
学习笔记不是从网上到处拼凑而来,除了少部分引用书上和技术文档的原文,其余都是笔者的原创。在您引用本仓库内容或者对内容进行修改演绎时,请署名并以相同方式共享,谢谢。
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="知识共享许可协议" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
#### 致谢
### Logo
Power by [logomakr](https://logomakr.com/).
### 致谢
感谢以下人员对本仓库做出的贡献,当然不仅仅只有这些贡献者,这里就不一一列举了。如果你希望被添加到这个名单中,并且提交过 Issue 或者 PR请与笔者联系。
@ -164,3 +153,20 @@ Power by [logomakr](https://logomakr.com/).
<a href="https://github.com/yanglbme">
<img src="https://avatars1.githubusercontent.com/u/21008209?s=400&v=4" width="50px">
</a>
<!-- | | Ⅱ | Ⅲ | Ⅳ | | Ⅵ | Ⅶ | Ⅷ | Ⅸ | |
| :--------: | :---------: | :---------: | :---------: | :---------: | :---------:| :---------: | :-------: | :-------:| :------:|
| 算法[:pencil2:](#pencil2-算法) | 操作系统[:computer:](#computer-操作系统)|网络[:cloud:](#cloud-网络) | 面向对象[:couple:](#couple-面向对象) |数据库[:floppy_disk:](#floppy_disk-数据库)| Java [:coffee:](#coffee-java)| 系统设计[:bulb:](#bulb-系统设计)| 工具[:hammer:](#hammer-工具)| 编码实践[:speak_no_evil:](#speak_no_evil-编码实践)| 后记[:memo:](#memo-后记) | -->
<!-- | | Ⅱ | Ⅲ | Ⅳ | |
| :--------: | :---------: | :---------: | :---------: | :---------: |
| &emsp;&emsp;&emsp;算法&emsp;&emsp;&emsp;<br>[:pencil2:](#pencil2-算法) | &emsp;&emsp;&emsp;操作系统&emsp;&emsp;&emsp;<br>[:computer:](#computer-操作系统) | &emsp;&emsp;&emsp;&emsp;网络&emsp;&emsp;&emsp;&emsp;<br>[:cloud:](#cloud-网络) | &emsp;&emsp;&emsp;面向对象&emsp;&emsp;&emsp;<br>[:couple:](#couple-面向对象) | &emsp;&emsp;&emsp;数据库&emsp;&emsp;<br>[:floppy_disk:](#floppy_disk-数据库)|
| Ⅵ | Ⅶ | Ⅷ | Ⅸ | |
|:---------:| :---------: | :-------: | :-------:| :------:|
| &emsp;&emsp;&emsp;Java&emsp;&emsp;&emsp;<br>[:coffee:](#coffee-java) | &emsp;&emsp;&emsp;系统设计&emsp;&emsp;&emsp;<br>[:bulb:](#bulb-系统设计) | &emsp;&emsp;&emsp;&emsp;工具&emsp;&emsp;&emsp;&emsp;<br>[:hammer:](#hammer-工具) | &emsp;&emsp;&emsp;编码实践&emsp;&emsp;&emsp;<br>[:speak_no_evil:](#speak_no_evil-编码实践) | &emsp;&emsp;&emsp;后记 &emsp;&emsp;&emsp;<br>[:memo:](#memo-后记) |
-->
<br>

View File

@ -1,5 +1,5 @@
[🎉 面试进阶专栏已上线](https://xiaozhuanlan.com/CyC2018)
> [🍉 点击订阅面试进阶专栏](https://xiaozhuanlan.com/CyC2018)
## ✏️ 算法
@ -18,7 +18,7 @@
> [HTTP](notes/HTTP.md) </br>
> [Socket](notes/Socket.md)
## 👫 面向对象
## 🔓 面向对象
> [设计模式](notes/设计模式.md) </br>
> [面向对象思想](notes/面向对象思想.md)
@ -48,7 +48,7 @@
> [缓存](notes/缓存.md) </br>
> [消息队列](notes/消息队列.md)
## 🔨 工具
## 🔧 工具
> [Git](notes/Git.md) </br>
> [Docker](notes/Docker.md) </br>

View File

@ -2,11 +2,7 @@
# CS-Notes
> Computer Sicence Learning Notes.
- Algorithm
- Computer Networks
- ...
- 本项目包含了技术面试必备的基础知识,浅显易懂,你不需要花很长的时间去阅读和理解成堆的技术书籍就可以快速掌握这些知识,从而节省宝贵的面试复习时间。你也可以订阅 <a href="https://xiaozhuanlan.com/CyC2018">面试进阶专栏</a>,包含了学习指导和面试技巧,让你更轻松拿到满意的 Offer。
<span id="busuanzi_container_site_pv">Site View : <span id="busuanzi_value_site_pv">

View File

@ -3,6 +3,10 @@
display: none;
}
#main>ul:nth-child(2) {
display: none;
}
.markdown-section h1 {
margin: 3rem 0 2rem 0;
}
@ -36,4 +40,12 @@ body {
/*.anchor span {
color: rgb(66, 185, 131);
}*/
}*/
section.cover h1 {
margin: 0;
}
body>section>div.cover-main>ul>li>a {
color: #42b983;
}

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、解决的问题](#一解决的问题)
* [二、与虚拟机的比较](#二与虚拟机的比较)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [集中式与分布式](#集中式与分布式)
* [中心服务器](#中心服务器)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一 、基础概念](#一-基础概念)
* [URI](#uri)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概览](#一概览)
* [二、磁盘操作](#二磁盘操作)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、数据类型](#一数据类型)
* [包装类型](#包装类型)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概览](#一概览)
* [Collection](#collection)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、线程状态转换](#一线程状态转换)
* [新建New](#新建new)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、运行时数据区域](#一运行时数据区域)
* [程序计数器](#程序计数器)
@ -31,7 +31,7 @@
# 一、运行时数据区域
<div align="center"> <img src="pics/ab701824-e308-4284-88b6-596cc606fadb.png" width="450"/> </div><br>
<div align="center"> <img src="pics/11548742157520.gif" width="450"/> </div><br>
## 程序计数器
@ -41,7 +41,7 @@
每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
<div align="center"> <img src="pics/28ab96b4-82ea-4d99-99fb-b320f60d0a58.png" width="500"/> </div><br>
<div align="center"> <img src="pics/11548741556940.gif" width="500"/> </div><br>
可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小:
@ -60,7 +60,8 @@ java -Xss512M HackTheJava
本地方法一般是用其它语言C、C++ 或汇编语言等)编写的,并且被编译为基于本机硬件和操作系统的程序,对待这些方法需要特别处理。
<div align="center"> <img src="pics/JNI-Java-Native-Interface.jpg" width="350"/> </div><br>
<div align="center"> <img src="pics/11548742010310.gif"/> </div><br>
## 堆
@ -73,7 +74,7 @@ java -Xss512M HackTheJava
堆不需要连续内存,并且可以动态增加其内存,增加失败会抛出 OutOfMemoryError 异常。
可以通过 -Xms 和 -Xmx 两个虚拟机参数来指定一个程序的堆内存大小,第一个参数设置初始值,第二个参数设置最大值。
可以通过 -Xms 和 -Xmx 两个虚拟机参数来指定一个程序的堆内存大小,第一个参数设置初始值,第二个参数设置最大值。
```java
java -Xms1M -Xmx2M HackTheJava
@ -99,7 +100,7 @@ Class 文件中的常量池(编译器生成的字面量和符号引用)会
## 直接内存
在 JDK 1.4 中新入了 NIO 类,它可以使用 Native 函数库直接分配堆外内存,然后通过 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在堆内存和堆外内存来回拷贝数据。
在 JDK 1.4 中新入了 NIO 类,它可以使用 Native 函数库直接分配堆外内存,然后通过 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在堆内存和堆外内存来回拷贝数据。
# 二、垃圾收集
@ -113,25 +114,25 @@ Class 文件中的常量池(编译器生成的字面量和符号引用)会
为对象添加一个引用计数器,当对象增加一个引用时计数器加 1引用失效时计数器减 1。引用计数为 0 的对象可被回收。
两个对象出现循环引用的情况下,此时引用计数器永远不为 0导致无法对它们进行回收。正因为循环引用的存在因此 Java 虚拟机不使用引用计数算法。
两个对象出现循环引用的情况下,此时引用计数器永远不为 0导致无法对它们进行回收。正因为循环引用的存在因此 Java 虚拟机不使用引用计数算法。
```java
public class ReferenceCountingGC {
public class Test {
public Object instance = null;
public static void main(String[] args) {
ReferenceCountingGC objectA = new ReferenceCountingGC();
ReferenceCountingGC objectB = new ReferenceCountingGC();
objectA.instance = objectB;
objectB.instance = objectA;
Test a = new Test();
Test b = new Test();
a.instance = b;
b.instance = a;
}
}
```
### 2. 可达性分析算法
通过 GC Roots 作为起始点进行搜索,能够到达到的对象都是存活的,不可达的对象可被回收。
将 GC Roots 作为起始点进行搜索,可达的对象都是存活的,不可达的对象可被回收。
Java 虚拟机使用该算法来判断对象是否可被回收,在 Java 中 GC Roots 一般包含以下内容:
@ -140,11 +141,11 @@ Java 虚拟机使用该算法来判断对象是否可被回收,在 Java 中 GC
- 方法区中类静态属性引用的对象
- 方法区中的常量引用的对象
<div align="center"> <img src="pics/0635cbe8.png" width=""/> </div><br>
<div align="center"> <img src="pics/11548742505541.gif"/> </div><br>
### 3. 方法区的回收
因为方法区主要存放永久代对象,而永久代对象的回收率比新生代低很多,因此在方法区上进行回收性价比不高。
因为方法区主要存放永久代对象,而永久代对象的回收率比新生代低很多,所以在方法区上进行回收性价比不高。
主要是对常量池的回收和对类的卸载。
@ -158,9 +159,9 @@ Java 虚拟机使用该算法来判断对象是否可被回收,在 Java 中 GC
### 4. finalize()
finalize() 类似 C++ 的析构函数,用于关闭外部资源。但是 try-finally 等方式可以做的更好,并且该方法运行代价很高,不确定性大,无法保证各个对象的调用顺序,因此最好不要使用。
类似 C++ 的析构函数用于关闭外部资源。try-finally 等方式可以做的更好,并且该方法运行代价很高,不确定性大,无法保证各个对象的调用顺序,因此最好不要使用。
当一个对象可被回收时,如果需要执行该对象的 finalize() 方法,那么就有可能在该方法中让对象重新被引用,从而实现自救。自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会调用 finalize() 方法。
当一个对象可被回收时,如果需要执行该对象的 finalize() 方法,那么就有可能在该方法中让对象重新被引用,从而实现自救。自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会再调用该方法。
## 引用类型
@ -194,7 +195,7 @@ obj = null; // 使对象只被软引用关联
被弱引用关联的对象一定会被回收,也就是说它只能存活到下一次垃圾回收发生之前。
使用 WeakReference 类来实现弱引用。
使用 WeakReference 类来创建弱引用。
```java
Object obj = new Object();
@ -208,7 +209,7 @@ obj = null;
为一个对象设置虚引用的唯一目的是能在这个对象被回收时收到一个系统通知。
使用 PhantomReference 来实现虚引用。
使用 PhantomReference 来创建虚引用。
```java
Object obj = new Object();
@ -220,7 +221,7 @@ obj = null;
### 1. 标记 - 清除
<div align="center"> <img src="pics/a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg" width=""/> </div><br>
<div align="center"> <img src="pics/11548743021625.gif"/> </div><br>
标记要回收的对象,然后清除。
@ -231,21 +232,21 @@ obj = null;
### 2. 标记 - 整理
<div align="center"> <img src="pics/902b83ab-8054-4bd2-898f-9a4a0fe52830.jpg" width=""/> </div><br>
<div align="center"> <img src="pics/11548743193273.gif"/> </div><br>
让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
### 3. 复制
<div align="center"> <img src="pics/e6b733ad-606d-4028-b3e8-83c3a73a3797.jpg" width=""/> </div><br>
<div align="center"> <img src="pics/11548743457272.gif"/> </div><br>
将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了就将还存活的对象复制到另一块上面,然后再把使用过的内存空间进行一次清理。
主要不足是只使用了内存的一半。
现在的商业虚拟机都采用这种收集算法回收新生代,但是并不是划分为大小相等的两块,而是一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 空间和其中一块 Survivor。在回收时将 Eden 和 Survivor 中还存活着的对象全部复制到另一块 Survivor 空间上,最后清理 Eden 和使用过的那一块 Survivor。
现在的商业虚拟机都采用这种收集算法回收新生代,但是并不是划分为大小相等的两块,而是一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 和其中一块 Survivor。在回收时将 Eden 和 Survivor 中还存活着的对象全部复制到另一块 Survivor 上,最后清理 Eden 和使用过的那一块 Survivor。
HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1保证了内存的利用率达到 90%。如果每次回收有多于 10% 的对象存活,那么一块 Survivor 空间就不够用了,此时需要依赖于老年代进行空间分配担保,也就是借用老年代的空间存储放不下的对象。
HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1保证了内存的利用率达到 90%。如果每次回收有多于 10% 的对象存活,那么一块 Survivor 就不够用了,此时需要依赖于老年代进行空间分配担保,也就是借用老年代的空间存储放不下的对象。
### 4. 分代收集
@ -262,7 +263,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 的大小比例默认为 8:1保证了
以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。
- 单线程与多线程:单线程指的是垃圾收集器只使用一个线程进行收集,而多线程使用多个线程;
- 单线程与多线程:单线程指的是垃圾收集器只使用一个线程,而多线程使用多个线程;
- 串行与并行:串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并行指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。
### 1. Serial 收集器
@ -275,7 +276,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。
它的优点是简单高效,对于单个 CPU 环境来说,由于没有线程交互的开销,因此拥有最高的单线程收集效率。
它是 Client 模式下的默认新生代收集器,因为在该应用场景下内存一般来说不会很大。Serial 收集器收集几十兆甚至一两百兆的新生代停顿时间可以控制在一百多毫秒以内,只要不是太频繁,这点停顿是可以接受的。
它是 Client 模式下的默认新生代收集器,因为在该应用场景下内存一般来说不会很大。收集几十兆甚至一两百兆的新生代停顿时间可以控制在一百多毫秒以内,只要不是太频繁,这点停顿时间是可以接受的。
### 2. ParNew 收集器
@ -285,8 +286,6 @@ Serial 翻译为串行,也就是说它以串行的方式执行。
是 Server 模式下首选的新生代收集器,除了性能原因外,主要是因为除了 Serial 收集器,只有它能与 CMS 收集器配合工作。
默认开启的线程数量与 CPU 数量相同,可以使用 -XX:ParallelGCThreads 参数来设置线程数。
### 3. Parallel Scavenge 收集器
与 ParNew 一样是多线程收集器。
@ -441,7 +440,7 @@ G1 把堆划分成多个大小相等的独立区域Region新生代和
## 类的生命周期
<div align="center"> <img src="pics/32b8374a-e822-4720-af0b-c0f485095ea2.jpg" width=""/> </div><br>
<div align="center"> <img src="pics/11548744140733.gif"/> </div><br>
包括以下 7 个阶段:
@ -583,7 +582,7 @@ System.out.println(ConstClass.HELLOWORLD);
## 类与类加载器
两个类相等需要类本身相等,并且使用同一个类加载器进行加载。这是因为每一个类加载器都拥有一个独立的类名称空间。
两个类相等需要类本身相等,并且使用同一个类加载器进行加载。这是因为每一个类加载器都拥有一个独立的类名称空间。
这里的相等,包括类的 Class 对象的 equals() 方法、isAssignableFrom() 方法、isInstance() 方法的返回结果为 true也包括使用 instanceof 关键字做对象所属关系判定结果为 true。
@ -591,9 +590,9 @@ System.out.println(ConstClass.HELLOWORLD);
从 Java 虚拟机的角度来讲,只存在以下两种不同的类加载器:
- 启动类加载器Bootstrap ClassLoader这个类加载器用 C++ 实现,是虚拟机自身的一部分;
- 启动类加载器Bootstrap ClassLoader使用 C++ 实现,是虚拟机自身的一部分;
- 所有其他类的加载器,这些类由 Java 实现,独立于虚拟机外部,并且全都继承自抽象类 java.lang.ClassLoader。
- 所有其它类的加载器,使用 Java 实现,独立于虚拟机,继承自抽象类 java.lang.ClassLoader。
从 Java 开发人员的角度看,类加载器可以划分得更细致一些:
@ -607,13 +606,13 @@ System.out.println(ConstClass.HELLOWORLD);
应用程序都是由三种类加载器相互配合进行加载的,如果有必要,还可以加入自己定义的类加载器。
下图展示的类加载器之间的层次关系称为类加载器的双亲委派模型Parents Delegation Model。该模型要求除了顶层的启动类加载器外其余的类加载器都有自己的父类加载器。这里类加载器之间的父子关系一般通过组合Composition关系来实现而不是通过继承Inheritance的关系实现。
下图展示的类加载器之间的层次关系称为类加载器的双亲委派模型Parents Delegation Model。该模型要求除了顶层的启动类加载器外其余的类加载器都有自己的父类加载器。这里类加载器之间的父子关系一般通过组合Composition关系来实现而不是通过继承Inheritance的关系实现。
<div align="center"> <img src="pics/class_loader_hierarchy.png" width="600"/> </div><br>
### 1. 工作过程
一个类加载器首先将类加载请求传送到父类加载器,只有当父类加载器无法完成类加载请求时才尝试加载。
一个类加载器首先将类加载请求传送到父类加载器,只有当父类加载器无法完成类加载请求时才尝试自己加载。
### 2. 好处

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [算法思想](#算法思想)
* [双指针](#双指针)
@ -3050,7 +3050,6 @@ public boolean canPartition(int[] nums) {
int W = sum / 2;
boolean[] dp = new boolean[W + 1];
dp[0] = true;
Arrays.sort(nums);
for (int num : nums) { // 0-1 背包一个物品只能用一次
for (int i = W; i >= num; i--) { // 从后往前,先计算 dp[i] 再计算 dp[i-num]
dp[i] = dp[i] || dp[i - num];
@ -5695,7 +5694,7 @@ Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].
```
和谐序列中最大数和最小数差正好为 1应该注意的是序列的元素不一定是数组的连续元素。
和谐序列中最大数和最小数差正好为 1应该注意的是序列的元素不一定是数组的连续元素。
```java
public int findLHS(int[] nums) {

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [595. Big Countries](#595-big-countries)
* [627. Swap Salary](#627-swap-salary)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、常用操作以及概念](#一常用操作以及概念)
* [快捷键](#快捷键)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、索引](#一索引)
* [B+ Tree 原理](#b-tree-原理)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概述](#一概述)
* [二、数据类型](#二数据类型)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、基础](#一基础)
* [二、创建表](#二创建表)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、I/O 模型](#一io-模型)
* [阻塞式 I/O](#阻塞式-io)

BIN
docs/notes/pics/1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

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: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、可读性的重要性](#一可读性的重要性)
* [二、用名字表达代码含义](#二用名字表达代码含义)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
<!-- GFM-TOC -->

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、分布式锁](#一分布式锁)
* [数据库的唯一索引](#数据库的唯一索引)

View File

@ -1,7 +1,5 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [1. 前言](#1-前言)
* [2. 实现 Singleton](#2-实现-singleton)
* [3. 数组中重复的数字](#3-数组中重复的数字)
* [4. 二维数组中的查找](#4-二维数组中的查找)
* [5. 替换空格](#5-替换空格)
@ -82,21 +80,6 @@
<!-- GFM-TOC -->
# 1. 前言
本文的绘图可通过以下途径免费获得并使用:
- [ProcessOn](https://www.processon.com/view/5a3e4c7be4b0909c1aa18b49)
- [DrawIO](https://drive.google.com/file/d/1nSSCpPUC05MFoeFuf_aeTtkm7dG5-bJ1/view?usp=sharing)
本文内容可在微信小程序中阅读:
<div align="center"> <img src="pics/gh_a68199af85d6_258_20_282_29.jpg"/> </div><br>
# 2. 实现 Singleton
[单例模式](设计模式.md)
# 3. 数组中重复的数字
[NowCoder](https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
@ -115,24 +98,13 @@ Output:
## 解题思路
要求复杂度为 O(N) + O(1),也就是时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。牛客网讨论区这一题的首票答案使用 nums[i] + length 来将元素标记,这么做会有加法溢出问题。
要求是时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。
这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上。
对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解
以 (2, 3, 1, 0, 2, 5) 为例:
以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复
```text
position-0 : (2,3,1,0,2,5) // 2 <-> 1
(1,3,2,0,2,5) // 1 <-> 3
(3,1,2,0,2,5) // 3 <-> 0
(0,1,2,3,2,5) // already in position
position-1 : (0,1,2,3,2,5) // already in position
position-2 : (0,1,2,3,2,5) // already in position
position-3 : (0,1,2,3,2,5) // already in position
position-4 : (0,1,2,3,2,5) // nums[i] == nums[nums[i]], exit
```
遍历到位置 4 时,该位置上的数为 2但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复。
<div align="center"> <img src="pics/_u6570_u7EC4_u4E2D_u91CD_u590D_1548260392361.gif" width="250px"> </div><br>
```java
public boolean duplicate(int[] nums, int length, int[] duplication) {
@ -163,7 +135,7 @@ private void swap(int[] nums, int i, int j) {
## 题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数
给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中
```html
Consider the following matrix:
@ -181,13 +153,11 @@ Given target = 20, return false.
## 解题思路
从右上角开始查找。矩阵中的一个数,它左边的数都比它小,下边的数都比它大。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间
要求时间复杂度 O(M + N),空间复杂度 O(1)
复杂度O(M + N) + O(1)
该二维数组中的一个数,它左边的数都比它小,下边的数都比它大。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间,当前元素的查找区间为左下角的所有元素。
当前元素的查找区间为左下角的所有元素,例如元素 12 的查找区间如下:
<div align="center"> <img src="pics/f94389e9-55b1-4f49-9d37-00ed05900ae0.png" width="250"/> </div><br>
<div align="center"> <img src="pics/_u4E8C_u7EF4_u6570_u7EC4_u4E2D_.gif"/> </div><br>
```java
public boolean Find(int target, int[][] matrix) {
@ -218,10 +188,10 @@ public boolean Find(int target, int[][] matrix) {
```text
Input:
"We Are Happy"
"A B"
Output:
"We%20Are%20Happy"
"A%20B"
```
## 解题思路
@ -232,6 +202,8 @@ Output:
从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。
<div align="center"> <img src="pics/_u66FF_u6362_u7A7A_u683C.gif"/> </div><br>
```java
public String replaceSpace(StringBuffer str) {
int P1 = str.length() - 1;
@ -260,30 +232,16 @@ public String replaceSpace(StringBuffer str) {
## 题目描述
输入链表的第一个节点,从尾到头反过来打印出每个结点的值。
从尾到头反过来打印出每个结点的值。
<div align="center"> <img src="pics/d99dc9e2-197c-4085-813d-7195da1c6762.png" width="300"/> </div><br>
<div align="center"> <img src="pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548293972480.gif" width="250px"> </div><br>
## 解题思路
### 使用栈
```java
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.add(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> ret = new ArrayList<>();
while (!stack.isEmpty())
ret.add(stack.pop());
return ret;
}
```
### 使用递归
<div align="center"> <img src="pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548296249372.gif" width="200px"> </div><br>
```java
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> ret = new ArrayList<>();
@ -304,6 +262,8 @@ public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
- 头结点是在头插法中使用的一个额外节点,这个节点不存储值;
- 第一个节点就是链表的第一个真正存储值的节点。
<div align="center"> <img src="pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548295232667.gif" width="300px"> </div><br>
```java
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
// 头插法构建逆序链表
@ -325,16 +285,20 @@ public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
}
```
### 使用 Collections.reverse()
### 使用栈
<div align="center"> <img src="pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548503461113.gif" width="500px"> </div><br>
```java
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> ret = new ArrayList<>();
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
ret.add(listNode.val);
stack.add(listNode.val);
listNode = listNode.next;
}
Collections.reverse(ret);
ArrayList<Integer> ret = new ArrayList<>();
while (!stack.isEmpty())
ret.add(stack.pop());
return ret;
}
```
@ -352,12 +316,14 @@ preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
```
<div align="center"> <img src="pics/8a4c6ad4-a816-47d1-b93f-7ca4f78ab67a.png" width="250"/> </div><br>
<div align="center"> <img src="pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-1.gif" width="200"/> </div><br>
## 解题思路
前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。
<div align="center"> <img src="pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-21548502782193.gif"/> </div><br>
```java
// 缓存中序遍历数组每个值对应的索引
private Map<Integer, Integer> indexForInOrders = new HashMap<>();
@ -406,11 +372,11 @@ public class TreeLinkNode {
① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点;
<div align="center"> <img src="pics/cb0ed469-27ab-471b-a830-648b279103c8.png" width="250"/> </div><br>
<div align="center"> <img src="pics/_u4E8C_u53C9_u6811_u7684_u4E0B_.gif" width="250"/> </div><br>
② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。
<div align="center"> <img src="pics/e143f6da-d114-4ba4-8712-f65299047fa2.png" width="250"/> </div><br>
<div align="center"> <img src="pics/_u4E8C_u53C9_u6811_u7684_u4E0B_1548504426508.gif" width="250"/> </div><br>
```java
public TreeLinkNode GetNext(TreeLinkNode pNode) {
@ -443,7 +409,8 @@ public TreeLinkNode GetNext(TreeLinkNode pNode) {
in 栈用来处理入栈push操作out 栈用来处理出栈pop操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。
<div align="center"> <img src="pics/5acf7550-86c5-4c5b-b912-8ce70ef9c34e.png" width="400"/> </div><br>
<div align="center"> <img src="pics/_u7528_u4E24_u4E2A_u6808_u5B9E_.gif" width="500"/> </div><br>
```java
Stack<Integer> in = new Stack<Integer>();
@ -479,7 +446,8 @@ public int pop() throws Exception {
如果使用递归求解,会重复计算一些子问题。例如,计算 f(10) 需要计算 f(9) 和 f(8),计算 f(9) 需要计算 f(8) 和 f(7),可以看到 f(8) 被重复计算了。
<div align="center"> <img src="pics/faecea49-9974-40db-9821-c8636137df61.jpg" width="300"/> </div><br>
<div align="center"> <img src="pics/_u6590_u6CE2_u90A3_u5951_u6570_u5217.gif" width="400"/> </div><br>
递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、跨站脚本攻击](#一跨站脚本攻击)
* [二、跨站请求伪造](#二跨站请求伪造)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、事务](#一事务)
* [概念](#概念)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、构建工具的作用](#一构建工具的作用)
* [二、Java 主流构建工具](#二java-主流构建工具)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概述](#一概述)
* [二、匹配单个字符](#二匹配单个字符)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、消息模型](#一消息模型)
* [点对点](#点对点)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、前言](#一前言)
* [二、算法分析](#二算法分析)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、性能](#一性能)
* [二、伸缩性](#二伸缩性)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、缓存特征](#一缓存特征)
* [二、LRU](#二lru)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概述](#一概述)
* [基本特征](#基本特征)
@ -47,7 +47,7 @@
并发是指宏观上在一段时间内能同时运行多个程序,而并行则指同一时刻能运行多个指令。
并行需要硬件支持,如多流水线、多核处理器或分布式计算系统。
并行需要硬件支持,如多流水线、多核处理器或分布式计算系统。
操作系统通过引入进程和线程,使得程序能够并发运行。
@ -67,7 +67,7 @@
多个进程能在同一个处理器上并发执行使用了时分复用技术,让每个进程轮流占有处理器,每次只执行一小个时间片并快速切换。
虚拟内存使用了空分复用技术,它将物理内存抽象为地址空间,每个进程都有各自的地址空间。地址空间和物理内存使用页进行交换,地址空间的页并不需要全部在物理内存中,当使用到一个没有在物理内存的页时,执行页面置换算法,将该页置换到内存中。
虚拟内存使用了空分复用技术,它将物理内存抽象为地址空间,每个进程都有各自的地址空间。地址空间的页被映射到物理内存,地址空间的页并不需要全部在物理内存中,当使用到一个没有在物理内存的页时,执行页面置换算法,将该页置换到内存中。
### 4. 异步

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概述](#一概述)
* [网络的网络](#网络的网络)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、概述](#一概述)
* [二、创建型](#二创建型)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、负载均衡](#一负载均衡)
* [负载均衡算法](#负载均衡算法)

View File

@ -1,4 +1,4 @@
[🎉 面试进阶专栏限时优惠](https://xiaozhuanlan.com/CyC2018)
[🍉 点击订阅面试进阶专栏 ](https://xiaozhuanlan.com/CyC2018)
<!-- GFM-TOC -->
* [一、三大特性](#一三大特性)
* [封装](#封装)

BIN
docs/pics/1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

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: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,139 +0,0 @@
作者CyC2018
链接https://www.nowcoder.com/discuss/137593
来源:牛客网
## 前言
2018有过迷茫有过努力也有很多收获。为了记录这一年以来的感受于是有了这篇文章。
## Offer 情况
经过了长达一年左右的复习,秋招也收到了几个比较满意的 Offer参加面试的都通过了。
- 百度,企业智能平台;
- 阿里,高德地图,部门已联系,目前还在申报 Offer 中;
- 腾讯IEG 游戏平台后台研发SP
- 字节跳动头条后台研发SSP
- 华为Cloud Bu
- 网易游戏,梦幻事业部;
- 顺丰科技。
## 前期准备
也是在去年十一月份左右,看着身边两年制的同学经历了长时间而又艰难的秋招,我开始意识到自己应该提前准备了,否则自己的秋招会很惨。
本科的时候,虽然学过计算机网络、操作系统和数据结构等课程,而且 Leetcode 也刷了一两百题,但是离招聘要求还差的很远,学的都很浅只够应付考试,也没有实际的项目经验。
我的研究生方向是计算机图形学,研究生期间主要做一些科研项目。在选择招聘方向的时候,我也纠结了是不是找图形学相关方向的,但是考虑到图形学的选择不是很多,所以还是决定投后台研发相关的岗位。
于是开始收集各种学习资料,也买了很多纸质书。最开始的学习效率并不是很高,很迷茫,觉得要学的内容很多无从下手。那时候看别人的面经,感觉自己太弱了,很多内容都没接触过,于是更加迷茫。迷茫的时候总想着逃避,要是不复习多好,玩玩游戏每天多简单。但是游戏玩的越多,那种焦虑感越是强烈。解决焦虑的唯一办法就是想办法解决当前问题。当慢慢地从消极的学习态度中调整过来,掌握的知识越多,那种焦虑感也随之消失。当然这个过程并不容易,不仅需要很好的毅力,也要根据自身情况找到问题的有效解决方法。
## 春招开始
三月份各个公司就开始春招了那时候刚把一些基础知识简单地复习了一下Leetcode 刷到了三四百题。但是没有后台研发相关的项目,于是花了一个星期左右用 PHP 做了一个微博系统。当时做简历特别痛苦,没内容可以写,看着其他人简历各种新技术,自己都没掌握,所以很虚。
## 阿里一轮游
最开始投的阿里实验室大几届有个师兄在天猫精灵团队所以给我内推了。于是我人生中第一场面试就是阿里很自然地被虐了一遍。记得当时约好下午两点电话面试午饭都没吃怕吃完之后犯困影响状态然后找了一个很安静又没人的地方呆到了两点调整自己的状态。可是面试官突然打电话来说有个会议要开所以推迟了大概一个小时。苦苦等到三点左右面试正式开始不出所料面得非常糟糕。首先自己表述的很有问题很多内容没回答到关键点上自己会的内容也不怎么继续扩展回答。其次知识掌握得确实不够连线程安全、ThreadLocal、函数式编程都不会。虽然被虐的很惨但是也有好处知道了面试到底是怎样的自己还有哪方面的不足该怎么准备。
## 腾讯被鞭尸
第二场面试是腾讯,在经历了阿里的面试之后,并且又继续复习了一段时间,我对面试就比较有信心了。一面其实回答的挺理想的,虽然很多问题没有立马回答出来,但是经过面试官的耐心提示之后都能回答一些内容。当时面了一个半小时,面试体验特别好。印象比较深刻的题目有,阅读一个 Redis 源码,分析存在哪些问题。其实就是一个计数器实现的限流算法,会有临界值的问题,但是当时没回答出来,只能听面试官给我解释。还有一个微信扫二维码,这个过程发生了什么,也没回答得很好,不过面试官也很耐心地纠正我回答上的错误。一面顺利通过了,但是总监面挂了。总监面没有问什么技术问题,就是问了问项目和职业规划。自己的项目确实比较 Low我自己在介绍的时候也说得很不堪。职业规划我说自己希望在一些方面深入学习因为自己现在在这些方面还很薄弱... 面完之后我就知道挂了,因为整个面试过程我都特别虚,还主动说自己技术能力不行。不出所料,面完的当天晚上,状态变成了不合适。
但是过了几天,突然收到腾讯的电话,问我是否愿意去深圳参加面试(笔者学校在广州)。当然我毫不犹豫地答应了,很开心腾讯还能给我机会。经过了上一场面试的启示,这次面试我表现地非常自信,自己知道的知识都很有信心地表达出来,被问到不会的内容也不会那么慌张,和面试官探讨一些细节,然后说说自己的想法,还有自己看过相关的内容。由于这是腾讯云部门,对 Linux 内核和 C++ 有很高的要求问了几个相关的问题我都没回答出来比如如何实现守护进程Linux 信号机制Linux 线程的不可中断阻塞状态如何进入等等。除了这些问题,其它地回答的都还行。遗憾的是,当天晚上面试官打电话告知我面试没通过。但是他说我其它方面都很不错,所以问我愿不愿意参加腾讯云 Java 部门的招聘,于是第二天我又去了一个新的部门面试。
这次面试是在部门的会议室进行的,进到公司之后说实话没有自己想象中那么好,工位很挤环境一般。一开始就先随便聊聊,学校的研究工作,学习之类的。然后看了看项目,看完之后我就知道凉了一半,这个项目确实太水了,面试官看了之后没有接着问,也能感受到面试官有点嫌弃。然后他就问了一些基础知识,问到进程调度算法,面试官让我实现一个任务调度系统。因为是第一次手写代码,而且之前确实没考虑过这个问题,然后就胡乱写了一堆代码,特别乱,而且到处涂改。显然面试官是不满意的,写了也有十几分钟之后,我自己都知道已经凉了,然后面试官没让我接着写,也没给我任何提示,说就到这里,面试结束了,还有没有什么问题想问的。当然看过任务调度系统相关的文章会觉得挺容易的,比如使用时间轮实现等等。我依然记得面试官送我出门时候的热情,送我坐电梯的时候还很热情地和我说,非常感谢参加本次面试,辛苦了。
## 虎牙过于自信
经过了阿里和腾讯的面试之后,我觉得自己大概已经知道该怎么面试了,面试时候该注意什么,该怎么表达等等。而且腾讯面试表现也不差,虽然最后没通过。所以在虎牙面试的时候特别放松,觉得应该能通过。前面面的也都还行,虽然有几个问题没回答好,比如分析一下微博的时间线。通过了第一轮面试直接等第二轮,等到了晚上七点多才等到我。虎牙面试还是很注重技术的,虽然问的都不是很深入,只要简单回答到点上就不会接着问下去。二面也有一些问题没回答好,比如 ConcurrentHashMap 的并发机制,问 Spring 直接说不会。也有一些问题回答得比较乱,没有条理。但是我觉得大部分问题都回答的不错,应该能通过。可是面试完之后,面试官问有没有什么问题要问他,由于太过放松,我就问你们都加班到这么晚不吃饭吗,好饿啊,周六周日还加班吗... 问完之后面试官就很严肃了,说平常不加班的,我突然意识到了问题的严重性... 最后还是凉了。
## 百度第一个 Offer
被三家连续拒了之后,都开始怀疑自己了,不过还是提醒自己要保持信心。
幸运的是,百度的面试非常适合我,三轮都是技术面,而且手写算法题目居多,而我准备最多的是算法,所以很顺利通过了面试。但是面试表现并没有特别好,过了比较长的时间才被捞,而且是工程效率部门,做内部工具的,对个人成长并不好,所以不是特别满意。
## 网易游戏最好的面试体验
其实最开始没有打算投网易游戏的,因为被脉脉洗脑,已经放弃了做游戏。但是因为前面面试基本被拒了,担心没有实习 Offer因此就试试看。
因为没有特别想去网易游戏,所以面试过程也比较放松,就当去聊聊天。面试官非常 nice那天下午挤了很久地铁比较口渴然后面试官看我说得沙哑了到门口帮我买了一瓶可乐非常感激。面试之前我就提出我对 C++ 不熟悉,最近主要看 Java 的内容。面试官还是说没关系,尽量回答就好。当然最后我都把问题往 Java 那里回答了,比如 Map 的实现,内存管理等等。最后聊了一些玩过的游戏,就让我回去等消息。网易游戏就一轮面试,确实就一轮。周五参加的面试,下周一就给 Offer 了,效率特别高。
## 微众玄学面试
通过微众面试我自己都非常吃惊,一面的时候就简单自我介绍了一下,然后面试官开始介绍他自己的工作经历,以及现在部门在做的内容。之后问了我一个场景分析问题,我想了一会儿没想出来,于是面试官拿起草稿纸把各种需求详细说了一遍,然后把系统架构图也画了出来... 最后他问还有什么我优势的地方他没问到的我问他怎么不问问算法题他说笔试都通过了没必要再问。面完之后我觉得聊得很开心但是技术问题没回答好出乎意料收到了二面通知。二面没问技术就让介绍了项目再问问家住哪之类的问题也顺利通过了。HR 面就不用介绍。收到了微众的 Offer得知了部门是贷款科技部非常核心很吃香近几年也在扩展一些业务还是有点小心动的。虽然最后没选择去微众实习但是一面面试官加了我微信我很感谢他一面非常耐心给我讲解并让我通过。他说我是他面试的第一顺位也就是第一个面试者所以会放宽很多也希望我秋招能加入他们。
## 实习选择
其实最理想的是去百度实习,秋招也会容易很多。但是考虑到百度是在北京,部门很边缘,而且需要实习很长时间也不一定能转正,所以还是放弃了。最后只能在网易游戏和微众选,虽然自己不想做游戏,但是考虑到网易游戏的平台认可程度比微众好,秋招肯定会更容易一些。而且秋招如果还想进微众的话也会比较容易,因为面试官和 HR 都说秋招的时候会优先考虑我,所以最后还是去了网易游戏实习。
## 实习之前的快速学习期
经历了春招之后,认识到了自己身上的不足,比如交流表达能力的欠缺,知识积累得不够,项目深度不够。因此在实习之前的两三个月,开始针对这些问题逐个解决。
- 交流表达能力欠缺,就提前准备好各种非技术问题,然后对着镜子回答,把自己当成听众,并且也用录音机录下来。
- 知识积累不够,采取的策略是保证广度优先,并且在重要的内容上保证深度。其实之前基础知识已经掌握的比较好了,再学其它技术的时候都有很多相同的地方,所以学起来很快。
- 项目深度不够,就把那个微博系统做了一点改进,学了 Spring 之后改用 Java 实现。
## 不那么安心的实习
去实习的时候还是挺惊喜的,因为我被安排的工作是游戏引擎相关的,和自己的研究生方向紧密相关,我觉得做完实习项目之后自己的毕业论文也会比较有灵感。
但不幸的是,在去的第一天部门接待聚餐上,服务端主程就说,我们部门工作制是九九六,现在互联网都是九九六。在实习之前我了解的是实习生六点就可以走,而且只用上五天班,听到他这么一说心都凉透了,因为已经想好了晚上和周末时间用来复习。如果知道是九九六,我会选择去百度。
其实网易游戏部门氛围还是不错的,对员工很好,而且我的实习导师人也很好,在我生病的那几天很关心我。但是九九六的工作制对秋招复习还是有很大影响的,而且每天上下班花在路上的时间超过了两个小时,下班回寝室之后总想着看会儿视频休息一下,然后又要早早睡觉赶着第二天上班。没办法只能在上下班地铁上复习,还有就是午休时间接着复习。
## 秋招开始
实习之后已经是九月份了,那时候已经错过了所有提前批。而且实习的时候没怎么复习,九月初还是感觉没怎么准备充分,所以就又等了半个月才开始投简历。
但是这个时候和春招相比,已经把大部分后台研发相关的知识点过了一遍,很多重要的内容前前后后也看了十几遍,没有春招时候那么迷茫和焦虑。即使被问到没有掌握的知识,我也有把握通过讨论的方式,给出大概的思路,因为很多技术确实是相通的。
## 阿里看不懂的内部流程
秋招第一个投递的依然是阿里,最开始系统自动发起了一个新的流程,然后过了几天自动回绝了... 八月末的时候也找人内推了,但是又被阿里直接回绝了... 那时候已经觉得可能是春招面试表现太差,此生无缘阿里了。可是过了一段时间,正式校招的时候,阿里又发起了一个新的流程戏弄我,收到笔试通知的时候,我还犹豫了到底参不参加,因为那时候已经九月中旬,听说阿里已经没有 HC 了。而且按前面回绝我的态度,感觉即使笔试通过面试也通过不了。笔试那天晚上,本来准备看个电影放松一下,后来想了想还是参加了笔试,笔试各种机器学习和数学题,感觉拿错了试卷,笔试完我已经把阿里从我的公司进度列表中删除了,不再纠结阿里。可是过了一段时间收到阿里的面试通知,我以为是走走形式,可能参加笔试的人很少了,所以才选中我参加面试。那时候阿里招聘官网状态一排的已回绝,让我对阿里有一种恐惧感,觉得面试肯定挂。但是真正面试的时候却意外的顺利,收到二面通知的时候特别激动,然后面完二面又让直接等 HR 面HR 面虽然不是很理想,但是没有很大的问题。又过了很长一段时间,在我去深圳参加腾讯招聘的高铁上,收到了高德地图 HR 的电话,问是否愿意去。虽然得知部门在北京有点小失落,但是还是很开心终于被阿里认可了,摆脱了对阿里的恐惧。
实验室上届毕业在阿里云的大佬某天突然和我说,他们部门有新的 HC让我把简历发给他他要帮我内推会帮我安排一场线下面试如果通过的话到时候和高德的 HR 沟通一下,直接把我从高德捞过来。很感谢大佬向他老大极力推荐我,给我了这次面试机会。线下面试也很顺利,聊聊实习项目,问问我的开源博客,然后问些 Paxos 等分布式的问题,还有就是手写代码,信号量实现生产者消费者,以及一个位运算的问题。其实位运算的问题面试的时候写的不完善,面试官让我之后完善了再发给他,因为面试一个多小时有点长了。过后我写了详细文档讲解了思路,以及使用 JUnit 进行了详细的单元测试,把文档和代码都发给了他。现在面试已经通过了,但是最近阿里集团 HC 比较紧张,也不知道能不能批到 HC。
## 百度又是不那么满意的部门
虽然阿里是最先开始流程,但是第一个参加面试的是百度。因为实习的时候通过了百度的面试,所以这次面试还是比较有信心的。百度面试连续三天,都在同一个地方,最后签约也在同一个地方。还记得每次都坐一个小时左右的地铁去那里,路线已经非常熟悉了,和每天去实习的感觉类似。百度面试比较注重技术,三轮面试基本都是问技术问题,而且问的也比较深入,内容也非常广。但是面的不是那么理想,有两点原因,首先是因为确实有些知识点还没掌握好,比如 AC 自动机,系统故障分析等等;其次是对实习项目的描述上还不够好,没有把实习内容的闪光点描述出来,也没有讲清楚为什么做这个项目,自己通过什么方法去做,以及最后的结果。
最后百度给了白菜价,部门是企业智能平台,主要是内部系统,虽然会接触到机器学习和大数据。
## 腾讯虐我千百遍
秋招腾讯第一场面试和实习参加腾讯面试的感觉非常像,第一轮技术面感觉很好,手写堆排序算法,二部图分析等等。面完之后通知待会儿二面,听到之后还是很激动的,觉得这次应该没问题了。我在等二面的时候,碰到了室友(他经常不住宿舍,所以不清楚他也去面试),聊着聊着居然发现我两是同一个面试官,而且他是来二面的,也就是等一下我两就要一前一后进去面试。二面的感觉和实习二面非常像,非技术问题回答的支支吾吾,然后面试官开始质疑我说的内容,给我压力,我没有当场反驳,就说了哦,好像是这样的。因为面试官全程都绷着脸,所以我也比较紧张,很多问题没回答好。过了几天,室友和我说收到 HR 面试通知了,我去官网看了一下状态,已经变成了熟悉的不合适。这次面试失败的主要原因是自己在应对这种压力时处理地不是很好,主要体现在失去信心以及紧张。解决方法也简单,做好充分准备来保持信心,受到质疑的时候积极反驳,紧张的时候及时调整心态,可以试试深呼吸或者喝水。
因为实习有被捞起来的经历,所以被拒之后我特别希望能继续被捞起来,然后把简历上的面试城市改成了深圳。苦苦等到深圳场面试的前几天,在不经意的一个下午手机突然响了,我记得是短信邮件同时收到面试通知。于是又开始了新一轮被腾讯虐的面试之旅。
一面和之前一样也是意外地顺利,虽然问了一些 C++ 的问题,但是我都说到 Java 相关的实现上。在一些问题上确实回答的深度不够比如网络编程里面的水平触发和边缘触发等问题。然后问了几个算法本来要求手写我说我实现过所以就讲了讲思路。面试和腾讯第一场面试一样持续了一个半小时面试官也很好很多问题都会给提示即使最开始回答的有问题。二面面试官也很好问了问实习项目然后再聊一聊一些技术经过了之前的面试到这次面试真的就像在聊天一样而不是面试我们都会说一些对技术上的理解。HR 面其实面得很差,对于非技术问题的吹水能力我还是不太行。最终和我预期的一样,给了我 SP 的 Offer因为觉得自己面得还可以但是也不够好到给 SSP有些 C++ 问题还是没回答的特别好。
## 头条意外的惊喜
之前看到学弟收到头条的 Offer薪资非常诱人所以也想去试试。也听说头条面试难度非常大主要考察手写算法因为自己算法方面准备得比较充分所以觉得会比较顺利但是也没有特别高的预期。前两面中规中矩算法题和其它问题我都回答的比较好到三面的时候问了一个错排问题其实最开始我给了正确的递推公式但不是面试官想要的答案所以让我再想想。我想了十几分钟还是觉得没问题那时候觉得自己已经凉了因为面试官一直不满意。后面的几个问题也没回答的很好分析一个 SQL 语句的具体执行过程,比如会怎么利用索引,怎么优化之类的,虽然在他的提示下还是回答了,但是感觉并不好。面完之后我立马查了一下那个错排问题,证实了我的答案是正确的,于是写了一个详细的文档,联系 HR 让她发给面试官。出乎意料的是HR 让我不用担心,他说面试官对我的评价很好... 不过最后还是让她把文档发给了面试官。之后收到了加面通知,头条加面有两种情况,一是三轮评级都是 4 可以评 SSP二是面试官评价差别很大再面一轮决定是否录用。收到加面的时候完全不知道自己属于哪一种感觉两种情况都有可能。加面回答的也不好主要是问项目面了 25 分钟就草草结束,最后面试官说有些内容需要找一些文献参考参考。面完之后我觉得,即使我属于第一种要评 SSP 的情况,加面面的那么差应该也没希望了。苦苦等了好多天之后,最后确定是 SSP 之后,还是很惊喜的,感觉是对自己这么长时间复习的一个认可。
## 顺丰最后的保底
投顺丰是因为九月中旬很多公司都结束了招聘,所以那时候比较慌,就投了顺丰当做保底,顺便也练练手。最开始还担心顺丰笔试没通过,因为编程题最后一题没做出来,那题的题目都出错了,而且题目是网上直接 copy 过来的,网上的源码都不能通过,更别说我自己的实现了。顺丰面试主要问了数据库的内容,而且问的特别深,几乎把每种日志的实现和作用都问了一遍。面顺丰的时候也比较早,那时候有些问题的回答上没有组织好,回答得比较凌乱,虽然最后也算给了一个小 SP。
## 华为特别纠结的部门
去华为面试确实是没有压力的,因为都知道华为面试不怎么问技术,虽然还是问了我一些技术问题,不过不是问的很深。面试主要介绍项目,我对自己的实习项目还是比较有信心的,因为觉得做的确实不错,而且面了很多场了,知道该怎么介绍项目。面试官问我个人意愿,我说自己对分布式中间件等比较感兴趣,于是面试官把我推荐到了 Cloud Bu。本来没打算签华为的现场签约也就去看看到底给我开多少。最开始其实给我开了十四级最高的薪资我本来不是很想去虽然对这个部门感兴趣但是薪资确实比不上头条。然后随口问了一句可不可以给十五级本来 HR 说是可以试着申请一下,不过最后没申请成功。
## 技术博客
最后安利一下自己的技术博客:[CS-Notes](https://github.com/CyC2018/CS-Notes),虽然现在还有很多不完善的地方,但以后会不断改进。
## 小结
很多人都说,面试和考试一样,要背很多没用的东西。最开始我也认同这种看法,可是参加了几场面试之后,我就不这么认为了。因为面试出的问题,有很多是实际开发中碰到的,所以准备面试相当于提前做入职准备。而且面试中考察的思维能力、交流表达能力、应对压力能力,都是真正工作中所需要的。
我觉得自己比别人做的好的地方是,有很强烈的想找到好工作的意愿,才驱使我不断学习,所以态度很重要。
信心源自于充分准备,有了信心,面试的时候才能游刃有余。而毫无依据的自我感觉良好,在每次失败之后都看不到自身的不足,而是怪罪于外界因素。
做好自己的简历,我在简历上花了很长时间,只要允许,我都会用这个简历给面试官演示:[个人简历](https://cyc2018.github.io)。

View File

@ -1,7 +0,0 @@
</br>
<div align="center">
<img src="https://github.com/CyC2018/CS-Notes/raw/master/other/group1.png" width="300px"></br>
<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=93df4b54d965e6c649fe49fe109b2d656609aacc5ec49b4ef4071ae6db1d43c0">QQ 群</a>
</div>

View File

@ -8,7 +8,7 @@
# ⭐️ 加入方式
可以用微信直接扫下面的二维码直接加入,或者订阅专栏 https://xiaozhuanlan.com/CyC2018 ,加星主微信 zhengyochuan备注 “你的姓名 + 订阅专栏加星球”。
可以用微信直接扫下面的二维码直接加入,或者订阅专栏 https://xiaozhuanlan.com/CyC2018 ,加微信 zhengyochuan备注 “已订阅专栏加星球”。
<img src="https://github.com/CyC2018/CS-Notes/raw/master/other/planet1.png" width="200px">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -1,17 +0,0 @@
# 交流群
为大家提供一个学习交流平台,在这里你可以自由地和笔者以及其他人进行技术上的交流。
[💬](other/Group.md)
# 知识星球
想要向笔者提问关于学习和求职方面的建议?来知识星球,你的每个提问我都会认真回答。
[🎓](other/Planet.md)
# 内推信息
[🔎](https://github.com/CyC2018/Job-Recommend)