提交 80da36f2 编写于 作者: 沉默王二's avatar 沉默王二 💬

学习路线

上级 b36bc7fe
* [计算机经典书籍下载](https://mp.weixin.qq.com/s/bUTOG2jOw1gWw-YpZaxqww)
* 学习路线
* [Java并发学习路线](docs/xuexiluxian/java-thread.md)
* [C语言学习路线](docs/xuexiluxian/c.md)
* [C++学习路线](docs/xuexiluxian/ccc.md)
* [Python学习路线](docs/xuexiluxian/python.md)
* [Go语言学习路线](docs/xuexiluxian/go.md)
* [操作系统学习路线](docs/xuexiluxian/os.md)
我花时间写这篇文章来给大家讲C语言的学习,当然是希望大家真正的学会、学懂C语言,并能够真正感觉到它的用处。
我们先从 C 语言的入门开始,总共**一本书,两门视频课**
### 01)阮一峰老师的 C语言入门教程
阮一峰老师的 C语言入门课,我第一时间就拜读了一遍,受益匪浅!可以说目前我见到的最好的 C语言入门教程了,没有之一!国内的绝大多数高校,大一都会安排 C 语言这门课,阮一峰了老师的这份《C语言入门教程》,绝对是福音。
我第一时间就整理了一份 PDF 版,截个图大家可以感受下。我对这份教程非常满意,该讲的地方都讲到了,示例也给了很多,对初学者来说,入门必备。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-1.png)
直接长按扫描下方二维码,关注后回复 「**C语言**」 下载这份 PDF 吧:
![(长按扫码识别)](https://files.mdnice.com/user/3903/24b2eb71-bca8-4915-b68b-f9214db6c316.png)
### 02)翁恺教授的C语言视频课
可以先看阮一峰老师的《C语言入门教程》,也可以先花一个月的时间,去 mooc 把《程序设计入门 C语言》这门视频课过一遍。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-2.png)
>视频地址:https://www.icourse163.org/course/ZJU-199001
看完这套视频,大家至少能学到:
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-3.jpg)
学完这门入门课后,可以再看一下进阶版的。课程以一个 Windows 下的图形游戏程序入手,借助一个 C 语言图形库,展开全部的教学内容,非常有趣。
>视频地址:https://www.icourse163.org/course/ZJU-200001
这里给大家一点看视频的小建议哈。
老老实实听课,做笔记,严格按照翁恺老师的要求完成作业。如果还有余力,那么考虑一下课后的思考题。如果没有思路,先看一下别人的讨论,然后渐渐学会自己总结。
**没有学不会的 C 语言,只有不对的学习姿势**
### 03)为什么要学习 C语言?
很多初学者会感到困惑,C 语言既然工作岗位不多,为什么还要学习呢?学习 C语言能做什么?如果这两个问题搞不清楚的话,学习的过程中就容易脱靶。
C语言是由贝尔实验室的 Dennis Ritchie 在 1969 年~ 1973 年间发明创造的。
![C语言之父](https://files.mdnice.com/user/3903/02e8ad2c-f442-41a5-b8cd-e8e602098689.jpg)
Dennis Ritchie是这样评价自己的亲儿子的:“**古怪的、有缺陷的,但同时也是一个巨大的成功**。”这句评语还是非常中肯的。
**第一,C语言在计算机领域起到了承上启下的作用**
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-4.jpg)
C语言非常的简洁,几乎没有任何冗余。上手难度几乎为 0,除了指针难以被新手掌握以外,其他的基础语法都很容易上手。很多编程语言都受到了C语言的影响,比如说 Java、C++、C#、Python、Go 等等,那学会了 C语言,再学习其他的编程语言就会丝滑得多。
另外,大部分 Unix 内核,以及所有支撑工具和函数库都是用 C语言来编写的。以至于后来几乎所有的操作系统内核都用到了C语言,比如说 Windows、Linux、macOS 等等。那学会了 C语言,就可以学习计算机组成原理、操作系统等等偏基础的计算机基础知识。
《指环王》里有这样一句话:“one ring to them all”,可以把 ring 换成 language,这个 language 就是C语言。
**第二,C语言可以用于嵌入式系统的开发**
除了用于计算机操作系统的编写,C语言现在主要用于嵌入式系统的开发,汽车、照相机、家用电器等设备的底层系统都是用 C 语言编写的。
C语言能够直接操作硬件、管理内存、跟操作系统交互,这使得它成为了一种非常接近底层的编程语言,非常适合有极高性能要求的程序。
![MATLAB+C语言来控制机械臂](https://files.mdnice.com/user/3903/2cc58dea-4890-41a2-bb84-fcd9d99e3679.jpg)
**04)C语言核心知识点汇总**
为了方便大家的学习,我这里汇总一下 C语言的核心知识点。先来看文字版的:
- 数据类型
- 运算符和表达式
- 输入和输出
- 流程控制
- 函数
- 数组
- 指针
- 结构体
- 文件操作
- 内存管理
再来看详细版的思维导图:
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-5.png)
C语言有两个关键部分:
第一是语法:也是入门教材里最看重的内容,也就是那些变量、数据类型、分支判断、循环、函数、指针等等。
第二是函数库:简单来说,函数库就是别人编写好的 C 函数,你可以直接拿来调用,比如说调用 `printf()` 函数就可以在屏幕上打印。很多人可能觉得库函数不重要,都是别人封装好的,只要记住函数名就可以了,但其实我想表达的是,库函数才是你学习 C语言并将其应用于实践的关键。
因为学会调用别人的库函数(例如malloc函数、calloc函数、realloc函数、free函数),才有机会写出自己的库函数,否则从零开始撸实在是太不现实了。
**05)学习 C语言的一些建议**
一般来说,学习 C语言可以分为以下 5 个阶段:
- 1)学习基础语法
- 2)学会使用 C语言自带的库函数,比如说 printf 级别的
- 3)学会使用一些基本的数据结构与算法
- 4)有了一定的 C语言基础,开始学习一些计算机专业的核心知识,比如说操作系统、计算机组成原理等
- 5)动手做出一些 lab,造一些简单的轮子,实现一些简单的小应用
这里推荐 2 个蓝桥云课上的免费小 lab,大家可以动手练起来。
**1)可以进行加减乘除的计算器**
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-6.jpg)
>课程地址:https://www.lanqiao.cn/courses/75
通过这个 lab,大家可以学到:
* 计算器设计思路
* C 语言的格式检查
* C 语言输入与输出
**2)实现一个属于自己的编程语言**
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-7.png)
>课程地址:https://www.shiyanlou.com/courses/670
通过这个 lab,大家可以学到:
* 解析器
* 波兰表达式
* 解析树的计算
* S-Expression
* 变量定义和使用
* 条件判断
* 正则表达式
* 递归分析长字符串
* 出错处理
* Q-Expression
* 函数
* 字符串
这个 lab 翻译自国外的 build your own lisp:
>https://buildyourownlisp.com/
如果英语功底比较扎实的话,可以直接看原版。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-8.png)
认真跟着做这些 lab,真本领就学到手了。
**06)学习 C语言的其他资源**
给初中生看的《啊哈 C语言》,简单易懂,生动有趣,虽然只能学到 C语言的冰山一角,但也值了。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-9.png)
给高中生、大一新生看的入门书《c primer plus》,语法全覆盖,细节多,知识点讲的清楚,缺点是琐碎,细节弯弯绕。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-10.png)
还有一本《C 程序设计语言》,这本书的作者是 C语言之父,所以全书讲的都是 C语言的核心。代码示例大多都是库函数的实现方法,内容简洁明了,干净利落,没有废话。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-11.png)
- 想成为大佬的人
- 想进阶 C语言
- 想理解指针和内存
- 想搞懂 Linux 内核
- 想搞基础设备的
- 想搞单片机的
- 想进微软改进 Windows 的
- 想搞贴近生活硬件的,比如说闹钟、计时器、简单的机器人
看的进阶书《C 陷阱与缺陷》、《C 专家编程》、《C 和指针》
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-12.png)
尽管我不推荐大家看书入门,但我知道很多读者还是喜欢通过看书的方式学习。直接长按扫描下方二维码,关注后回复 「**C语言**」 下载这 PDF 版吧:
![(长按扫码识别)](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongzhonghao.png)
-------
到此为止,C语言的重点就全部划出来了,剩下的学习就交给大家了。最后,二哥再唠叨几句:
1、自学才是硬道理。强大的自学能力是独自解决问题的根本,程序员需要拥有强大的自学能力。
2、一个人可以走得很快,但一群人才能走的更远。最好加入一些有氛围的技术交流群,结交一两个有能力的同阶段的人,切磋精进一下。
3、入门阶段,coding 为主,视频为辅,不要搞反了。记住这个公式:只看+不练=假把戏。
4、如果以后不想当一个优秀的工程师,不想在计算机这条道路上走得更远,只想躺平当个平平淡淡的码农,那么我推荐一条路:跟着老师一步步走,跟着大学的教学方案,一步步走就行了。
上面这4条建议其实不仅适用于C语言的学习,还适用于其他任何一门编程语言的学习。如果能够这样坚持下去,几年后,你将是一名善于解决实际问题的工程师,而不是一名普普通通的码农。
以上,希望能帮助到大家!
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/c-13.png)
*没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟*
学习 C++ 语法,首推《C++ Primer 第五版》。我在参加第一份工作的时候,就买过一本《C++ Primer 第四版》,这本书一直不舍得扔,尽管它已经非常破了,但我们之间的感情是深厚的,毕竟跟随我辗转了好几个城市了。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/ccc-1.png)
*是不是一下子就暴露自己工作年限了*
这本书非常全面地讲解了 C++ 的语法以及 C++ 的各种特性,如果能坚持看完的话,帮助会很大。如果时间比较充分的话,建议至少看两遍。如果时间比较紧张的话,至少通读一遍吧,要能把握住这本书的大体框架,然后结合个人的实际情况选择性地看一些重点章节。
然后是《Effective C++》,侯捷老师译的,这本书主要讲解了编写 C++ 代码需要注意的一些条款,和《Effective Java》 属于同一个系列。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/ccc-2.jpg)
第三本是《STL源码剖析》这本书,侯捷老师写的,这本书讲了C++的底层实现,包括各种容器(vector、list、heap、deque、Red Black tree、hash table、set/map)的实现、各种常见算法(排序、查找、排列组合、数据移动与复制技术)的实现等。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/ccc-3.png)
第四本《深度探索C++对象模型》,侯捷老师译的,这本书讲解了 C++ 面向对象特性的底层实现机制,读起来虽然有点晦涩,但读完后就会搞明白“代码跑起来的时候实际发生了什么”。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/ccc-4.jpg)
既然有三本书都是侯捷老师的,那再刷一刷侯捷老师的视频,岂不是效果更佳?不过,由于涉及到版权,国内的 B 站、A 站都下架了相关的视频资源,包括:
- 《C++面向对象高级编程》
- 《STL》
- 《C++ 内存管理》
- 《C++ 11 新特性》
- 《C++ 程序的生前死后》
我从网上 down 了一份,保存到了本地。大家需要的话,可以在后台回复「**侯捷**」关键字拉取下载链接。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongzhonghao.png)
大家好,我是二哥呀!最近又有一个读者来咨询我的建议:**应届生,要求 Java 进去后转 Go,问我咋样?**
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-1.png)
据我自己的印象,前前后后有十个读者来问过我这个问题了。一方面 Java 就业岗位确实多,薪资也给力;另外一方面,Go 确实很有潜力。
尤其是国内的字节跳动,Go 在常用的编程语言中占比是最高的,大部分产品的后端都在使用 Go。
那作为贴心的二哥,必须得给大家梳理一波思路了,希望能给需要的读者一点点帮助和启发~
### 一、Go 的优势和劣势
Go 语言诞生于 2009 年,发展到现在,已经 12 岁了(应该没算错吧😭)。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-2.png)
很多明星级的开源产品,比如说 Kubernetes、Docker等,都是基于 Go 语言编写的。再加上近些年来微服务架构和云原生技术的普及,也大大的带火了 Go 这门编程语言,使其在 C/C++ 和 Java 中杀出了一条血路。
再加上从 2010 年 5 月起,Google 开始将 Go 语言投入到后端基础设施的实际开发中,很多我们能耳熟能详的应用都有使用 Go 语言,比如说谷歌地图、Google Cloud 等。
国内的字节跳动,就别提了。
Google 和字节两家大厂对 Go 的大力投入,在一定程度上又加速了 Go 这门编程语言的发展。
目前,使用 Go 语言的公司越来越多了,阿里、百度、腾讯、小米这些互联网大厂也在积极拥抱。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-3.png)
这使得 Go 工程师的薪资待遇也得到了很大程度上提高。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-4.png)
当然了,目前基本上除了大厂,很少有其他中小型公司用 Go,因为 Go 的生态还比不上 Java,没有 Java 那么丰富健全,中小公司的投入产出比比较低。大厂有人有钱,愿意在 Go 上投入成本。
另外,Go 也没有像外界吹捧的那么牛叉,就编程语言的排行榜上来看,Go 还是个滴滴(Python、C/C++、Java、C# 这些仍然是前排),有待发展。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-5.jpg)
### 二、为什么会要求 Java 转 Go 呢?
最直接的原因就是 Go 这边比较缺人,而 Java 这边基本上是招聘的多,竞聘的更多。
熟练掌握 Java 的一般都比较能打,转 Go 后作战能力肯定也是不容小觑。
对于我们国内的开发环境来说,Java 的确是顶流,我个人也是 Java 的重度使用者,但**我私底下也在学习其他的编程语言,因为只有这样,才能最大程度上保持自己的竞争力**
每种编程语言只要能发挥出它最大的优势,就是值得我们去学习和使用的。
再者,编程语言这东西,你掌握了一个,再学另外一个也会很快的。
截止到目前,我学过 Python、C/C++、Go、JavaScript 等等,因为有 Java 语言的底子在,学这些编程语言的时候,阻力基本上就像在泳池里游泳一样,一开始会感觉有点困难,等熟练了之后,会感觉很舒服。
### 三、Go 语言该怎么学习呢?
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-6.png)
不管怎么说,Go 语言的确是值得去学习的。如果公司确实需要转 Go 岗,也完全没有必要抗拒。
这里给大家推荐一个 Go 语言的学习路线图,如果你想要成为一名Go语言的开发者的话,可以沿着这张图里面的路径去学习。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-7.jpg)
接下来给大家推荐一些 Go 语言的学习资料,全部免费开源,是我肝了两个大夜精挑细选出来的。
记住一点:**不管是学习哪一门编程语言,顺序基本上就是视频入门+教程/书籍巩固+项目练习**
**1)视频课**
**第一套视频:《Go 编程基础》**,主要面向 Go 语言新手级别的学习者。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-8.jpg)
>课程地址:https://github.com/unknwon/go-fundamental-programming
**第二套视频:尚硅谷 Go 入门到实战教程**,采用真实案例,从理论到实践,一步一步将 Go 的核心编程技术、编程思想、底层实现融会贯通。
虽然尚硅谷是一家培训机构,但在 B 站上公开的一些课程还真的是挺香的,学 Java 的同学可能很大一部分都看过宋红康老师的课,YYDS!
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-9.jpg)
>视频地址:https://www.bilibili.com/video/BV1ME411Y71o
**2)教程/书籍**
**第一套教程:Go 语言之旅**,这是一个对初学者极其友好的在线网站,并且每一步都可以直接运行代码并看到效果。初学阶段,最重要的就是能通过手敲代码感受到学习的成果。
点击右侧的菜单可以快速浏览教程的所有内容,非常方便。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-10.jpg)
>教程地址:http://tour.studygolang.com/welcome/1
**第二套教程:LeetCode-Go**,一本 LeetCode 的刷题笔记,代码是用 Go 语言实现的,收录了超过 500 道题的题解思路和代码,代码方案都是效率超高的“标准答案”:
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-11.jpg)
>教程地址:https://books.halfrost.com/leetcode/
**第三套教程:《Go 语言设计与实现》**,这份教程的内容可以分成四个部分:
- 编译原理
- 运行时
- 基础知识
- 进阶知识
几乎覆盖了 Go 语言从编译到运行的方方面面,读完后能对 Go 语言有更加整体和深刻的认识。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-12.jpg)
>在线地址:https://draveness.me/golang/
是开发者内功修炼号主飞哥给我推荐的,当时看完后就大为震撼。目前我看作者已经出版了纸质书。
**第四套教程:《玩转 GO》**,内容包括但不限于并发、网络编程、垃圾回收、组合、Go UNIX系统编程、基本数据类型(Array,Slice,Map)、Go源码、反射,接口,类型方法等高级概念。
不过遗憾的是,在线阅读地址挂了,我还提交了一个 issue:
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-13.jpg)
不过幸好我备份了一份离线版 PDF,里面的内容还是非常完整的:
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-14.jpg)
**第五套教程:Go标准库文档**,可以查询每个API的具体使用方式,这也是 Go 开发者的必备手册。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-15.jpg)
>在线地址:https://studygolang.com/static/pkgdoc/main.html
再推荐一些比较优质的纸质书籍吧。
**第一本:Go语言实战**,这本书关注于 Go 语言的规范和实现,涉及的内容包括语法、Go 的类型系统、并发、通道和测试等主题。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-16.jpg)
**第二本:《Go 语言学习笔记》**,上卷专注于语言规范相关细节,下卷专注于对运行时源码做出深度剖析,诸如内存分配、垃圾回收和并发调度等。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-17.jpg)
**第三本:《Go Web 编程》**,这本书以一个网络论坛作为例子,讲解了如何使用请求处理器、多路复用器、模板引擎、存储系统等核心组件去构建一个 Go 的 Web 应用。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-18.jpg)
**3)实战项目**
**第一个项目:seaweedfs**,GitHub 上星标 13k+,这是一个分布式文件系统,基于 Go 开发,部署方便,使用简单,功能强大。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-19.jpg)
>地址:https://github.com/chrislusf/seaweedfs
**第二个项目:seaweedfs**,GitHub 上星标 13k+,这是一个自带文件浏览器的网盘服务,支持文件浏览、生成分享链接、批量上传、创建文件夹等功能、用户系统。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-20.jpg)
>地址:https://github.com/filebrowser/filebrowser
**第三个项目:go-admin**,GitHub 上星标 5k+,基于 Go 语言的一个数据可视化与管理平台,使开发者能在极简短的时间里,用极简短的代码量搭建起一个后台管理。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-21.jpg)
>地址:https://github.com/GoAdminGroup/go-admin
**第四个项目:7天用Go从零实现分布式缓存GeeCache**,每天完成的部分都是可以独立运行和测试的,就像搭积木一样,最终组合在一起就是一个完整的分布式缓存系统。每天的代码在 100 行左右。。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/go-22.jpg)
>地址:https://geektutu.com/post/geecache.html
### 四、Java 和 Go 如何做取舍?
Go 语言设计的晚一点,所以可以站在巨人的肩膀上,不像 Java,历史包袱很沉重。比如 Go 在并发编程方面,就比 Java 更轻量级,性能也更强劲,因为 Java 诞生的时候还没有为高并发这样的场景做好准备。
Go 的使用简单,如果有其他编程语言的基础,也容易切换,阻力小。国内的大厂,比如说字节、腾讯这些都是要经常对抗高并发的场景,所以对 Go 的人才需求量比较大。
Go 这边没有 Java 那么卷,岗位的薪资却也比较客观。如果能趁早建立优势的话,以后发展的路子也就更宽广了一些。
但与此同时,由于 Go 的整个生态还没有 Java 那么完善,所以中小厂直接上 Go 的寥寥无几。**稳妥起见,Java 为主,Go 为辅是比较合理的选择**
但一定要记住,无论什么时候,编程语言都不是最重要的,反而计算机基础是最重要的,尤其是操作系统、计网、计组、数据结构与算法这一块。
万丈高楼平地起,勿在浮沙筑高台。
基础扎实了,切换编程语言的时候只需要熟悉一下语法和库就 OK 了。
一名优秀的程序员,只会一种编程语言肯定是不够的,应该深入掌握一门,然后再涉足 1-2 门,这样的话,你能横向对比出来哪一种编程语言在哪一些领域有着比较大的优势,体会不同编程语言之间的差异性也会让你变得更加的优秀。
从个人职场发展来看,多一条腿走路,也更稳。。
大家好,我是二哥呀!今天新来个实习生小二,信誓旦旦说他精通 Java 并发,我气不过直接一道 **CyclicBarrier和CountDownLatch有什么区别**就把他问懵😳了。
众所周知,Java 并发是 Java 程序员必须懂但又很难懂的一块知识点。一般来说,很少有人敢说自己精通 Java 并发的,一是容易被面试官吊打,二是并发编程涉及到操作系统、内存、CPU 等计算机专业比较核心的内容,比较考验一个程序员的内功。
今天这篇文章就来给大家盘点一下 Java 并发到底该如何从入门到精通,请及时用鸡毛掸子把收藏夹里的灰清理一下。在阅读过程中,如果有所帮助,麻烦点赞和在看,算是对我码字的这份坚持的亿点点鼓励。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-1.gif)
### 一、为什么要学 Java 并发?
有句话不知道当讲不当讲,先讲了再说,就是“如果你只想 CURD,那么 Java 并发不学也罢!”但其实呢,大家都已经被教育的很有涵养了,工作中拧不拧螺丝不重要,重要的是面试一定要会造火箭,不然面试的机会都很难捞得到。
那作为 Java 体系中非常重要的一环,Java 并发自然是必须要掌握的,最起码也得会起个多线程吧?哈哈哈。高级点的,像平常开发中用到的 Tomcat 服务器、消息中间件、RPC 框架等等,它们的底层都涉及到了并发编程。
当然了,Java 并发涉及到东西实在是不少,包括操作系统的知识,Java 虚拟机的一些知识,Java 线程模型的知识,多线程相关的关键字,比如说 synchronized、volatile 等,还有锁的知识、JDK 提供的工具类等等,学起来还是非常容易令人头大的。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-2.png)
因此,我们需要一些高效的学习路线图,以及一些优质的学习资源,从而减少我们学习Java 并发编程所投入的时间和精力。
### 二、Java 并发学习路线图
给大家看一张 pdai.tech 学习网站上总结的一张关于 Java 并发编程的思维导图,非常清晰,一目了然,包含了理论基础、线程基础、synchronized、volatile、final关键字,以及JUC框架等核心内容。
>网站地址:https://pdai.tech/
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-concurrent-overview-1.png)
如果想总览 Java 并发编程的关键知识点的话,这张思维导图还是非常值得参考的。
### 三、硬核 Java 并发学习资料
**1)视频**
懂的都懂,看视频到 B 站。黑马的《Java并发编程》评价还不错,300 多个小节,我觉得讲的比较好的有三部分:synchronized优化原理、AQS和线程池。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-4.png)
>视频地址:https://www.bilibili.com/video/BV16J411h7Rd
**2)书籍**
纸质书只推荐一本《[Java 并发编程实战](https://book.douban.com/subject/10484692/)》,豆瓣评分 9.0。不过这本书确实有点老了,基本上是按照 Java 6 来讲解的,希望出版社能早点出 2.0 版。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-5.png)
《Java 并发编程实战》这本书从总体上来看,分两条主线:
- 介绍 Java 并发包的重要组件和原理
- 如何利用这些组件来保证线程安全
到底该如何获得线程安全呢?背会并理解下面这段话:
>Writing thread-safe code is, at its core, about managing access to state, and in particular to shared, mutable state.
如果发现不是很好懂,想从国内作者下手的话,可以尝试一下《[Java并发编程的艺术](https://book.douban.com/subject/26591326/)》和《[图解Java并发编程](https://book.douban.com/subject/35634953/)》这两本书,虽然豆瓣上评分一般,但对于构建 Java 并发的知识体系还是有很大帮助的。
之后,再去啃《Java 并发编程实战》就会发现没有以前那么费劲了,这本书之所以被誉为 Java 并发编程的圣经,确实可以看得出作者在并发编程方面有着丰富的经验。
**3)开源电子书**
推荐 RedSpider社区的[深入浅出 Java 多线程](http://concurrent.redspider.group/RedSpider.html),比Java 并发编程实战更通俗易懂一些,因为里面穿插了很多精美的手绘图。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-6.png)
>GitHub地址:https://github.com/RedSpider1/concurrent
考虑到有些小伙伴可能需要 [PDF 版本](https://mp.weixin.qq.com/s/pxKrjw_5NTdZfHOKCkwn8w),我花了一周的时间整理了一份,需要的戳前面的链接就好了。
再推荐一份 GitHub 上星标 3.6k+ 的 Java 并发知识点总结:
>https://github.com/CL0610/Java-concurrency
仓库里有一句话我非常喜欢,也分享给各位小伙伴:
>努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事!
顺带再推荐一份完整的Java 并发学习笔记:
>http://www.blogjava.net/xylz/archive/2010/07/08/325587.html
**4)付费专栏**
王宝令老师在极客时间上开了一门《Java 并发编程实战》的付费专栏,质量还是挺高的,喜欢的小伙伴可以戳[链接](http://gk.link/a/11cBH)去购买。
### 四、优质八股文
这里给大家推荐两份 Java 并发编程方面的八股文,一份来自[三分恶](https://mp.weixin.qq.com/s/1jhBZrAb7bnvkgN1TgAUpw),一份来自小牛,先截图给大家看一下 Java 并发方面都有哪些高频的面试题。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-7.png)
为了方便大家的阅读和背诵,我已经将其整理到了二哥的小破站《Java 程序员进阶之路》上。路径一:Java 基础→进阶篇→Java 并发编程→面渣逆袭
>https://tobebetterjavaer.com/#/README?id=面渣逆袭
路径二:求职面试→八股文→Java 并发编程八股文(背诵版)
>https://tobebetterjavaer.com/#/docs/baguwen/java-thread
这两份八股文的质量都非常高,来看一下「[AQS了解多少](https://tobebetterjavaer.com/#/docs/thread/sanfene/aqs)」小节下的内容,图文并茂,非常容易消化和吸收。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-8.png)
诚实点说,如果能把这两份八股文背会的话,简历上就真的敢写“精通”Java 并发了。
### 五、Java 并发学习心得
Java 提供的并发组件,大致可以分为两类:
- 从预防阶段下手,防止错误发生,比如说 synchronized 关键字
- 一旦发生错误能及时重试,比如说 CAS
对于线程数量比较多的并发场景,采用预防的措施会比较合理,这样大部分线程就不会因为小概率时间的 CAS 重试浪费掉大量的 CPU 周期;在线程数量小的时候,CAS 的意义就比较大,因为预防措施带来的线程切换要比 CAS 等待的开销更大。
想要学好 Java 并发编程,就必须得对下图中提到的基础概念进行充分的理解。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/java-thread-9.jpg)
在我看来,并发编程主要是用来解决这两个痛点的:
- 多个线程对同一变量造成的不一致问题;
- 为提高性能,计算机的很多执行单元都配备了缓存,那势必会影响并发编程的数据一致性。
需要提醒一点的是,多线程并发虽然是用来解决性能问题的,但并不意味着所有情况下都需要开启多线程,有时候反而会适得其反,那如果不是特别要求,尽量不要过早开启多线程。
并发编程是 Java 体系当中相对难掌握的一块知识点,比较考验一名程序员的内功,其实并发编程最早的应用领域就是操作系统的实现。
如果你已经有一定的编程经验,建议先学一下《计算机组成原理》,对操作系统、内存、CPU 先进行一些大致的了解,然后再来学习 Java 并发编程,可能就会感觉舒服多了!
结合我多年的工作经验来看,并发编程可以抽象成**三个核心问题:分工、同步和互斥**
1)分工
分工指的是如何高效地拆解任务并分配给线程,像并发编程领域的一些设计模式,比如说生产者与消费者就是用来进行分工的。
2)同步
同步指的是线程之间如何协作,一个线程执行完了一个任务,要通知另外一个线程开工。还拿生产者-消费者模型来说吧,当队列满的时候,生产者线程等待,当队列不满的时候,生产者线程需要被唤醒重新执行;当队列空的时候,消费者线程开始等待,不空的时候,消费者线程被重新唤醒。
3)互斥
互斥指的是保证同一时刻只有一个线程访问共享资源,是解决线程安全问题的杀手锏。
当多个线程同时访问一个共享变量的时候,很容易出现“线程安全”问题,因为结果可能是不确定的——导致出现这个问题的根源就是可见性、有序性和原子性——为了解决它们,Java 引入了内存模型的概念,可以在一定程度上缓解“线程安全”的问题,但要想完全解决“线程安全”问题,还得靠互斥。
互斥的核心技术就是锁,比如说 synchronized,还有各种 Lock。
锁可以解决线程安全的问题,但同时也就意味着程序的性能要受到影响。
因此,Java 提供了针对不同场景下的锁,比如说读写锁 ReadWriteLock,可以解决多线程同时读,但只有一个线程能写的问题;但 ReadWriteLock 也有自己的问题,就是如果有线程正在读,写线程需要等待度线程释放锁后才能获得写锁,也就是读的过程中不允许写,属于一种悲观的读锁。
为了进一步提升并发执行的效率,Java 8 引入了一个新的读写锁 StampedLock,与ReadWriteLock 相比,StampedLock的优势在于读的过程中也允许获取写锁后写入,但带来的问题就是可能读的数据不一致,需要一点额外的代码来判断读的过程中是否有写入,本质上是一种乐观的锁。
乐观锁的意思就是估计读的过程中大概率不会有写入,而悲观锁则是读的过程中拒绝有写入,两者的区别就在于性能上会有差异,乐观锁需要针对小概率事件进行多一步的检测,但性能也会有所提升;悲观锁更能保证“线程安全性”。
听我这么一说,是不是一下子就清晰多了!
**Java 并发编程虽然难学,会涉及到操作系统、CPU、内存等偏基础方面的内容,但如果你能坚持学下去,内功自然而然就提升了一大截**
参考资料:
>小熊的技术之路:https://zhuanlan.zhihu.com/p/25577863
操作系统是管理计算机硬件和软件资源的程序,是计算机的基石。
举个例子来讲,像 Java 中的并发编程这块,如果连进程调度的相关原理、同步和互斥都搞不懂,那多半会有两种结果:
- 写出来的多线程程序出现了各种奇奇怪怪的问题;
- 不知道为什么出现这些问题。
**操作系统该怎么学呢?入门推荐两门视频课程**
先看一门国内的,再看一门国外的,中西合璧,药效持久。
### 一、哈工大的《操作系统》实验课
国内的推荐哈工大的《操作系统》实验课,以下四部分最为重要。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-1.png)
1)操作系统基础篇
>https://mooc.study.163.com/course/1000002004
2)操作系统之进程与线程
>https://mooc.study.163.com/course/1000002008
3)操作系统之内存管理
>https://mooc.study.163.com/course/1000003007
4)操作系统之外设与文件系统
>https://mooc.study.163.com/course/1000002009
哈工大的操作系统课是该校 CS 课程中含金量最高的,尤其是实验课。八个实验涉及到了操作系统的核心部分,虽然 lab 不是在哈工大自创的 HITOS 上,但 linux-0.11 确实是一个非常好的选择。
Linux-0.11 这个版本能让学生更加专注于实验,而不是纠结于各种奇奇怪怪的问题,作为 OS 入门算是足够了。
Linux 发展到现在,内核源码与 0.11 相比,几乎是翻天覆地的变化,但这不代表研究 linux-0.11 就没有意义,毕竟内核这东西,你懂的。。。
多的不说,学完 linux-0.11 后,你至少能明白,原来一个最简单的完整的操作系统,是这个样子的:它是这样一步步从 BIOS 开始加载程序加载数据的,它是这样实现单 CPU 多任务多进程调度和切换的。
Linux 内核主要由 5 个模块构成,分别是:
- 进程调度模块,负责控制进程对 CPU 资源的使用。
- 内存管理模块,用于确保所有进程能够安全地共享主机内存,同时,内存管理模块还支持虚拟内存管理方式,使得进程所使用的内存比实际的内存更多。
- 文件系统模块,用于支持对外部设备的驱动和存储。linux-0.95 版本又逐步实现了虚拟文件系统,该模块通过向所有的外部存储设备提供一个通用的文件接口,隐藏了各种硬件设备的不同细节,从而兼容其他操作系统。
- 进程间通信模块,用于支持多种进程间的信息交换方式。
- 网络接口模块(linux-0.96 版本才有),提供对多种网络通信标准的访问并支持网络硬件。
它们之间的依赖关系见下图所示。其实连线代表它们之间的依赖关系,虚线代表 linux-0.11 中还未实现的部分。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-2.png)
由上图可以看得出,所有模块都与进程调度模块存在依赖关系,因为它们都需要进程调度程序来挂起或重新运行它们的进程。
linux-0.11 的学习推荐《Linux 内核完全注释》,该书对 linux-0.11 的全部代码文件进行了详细全面的注释和说明,能够让大家在尽量短的时间内对 Linux 的工作机制有一个全面而深刻的理解,为进一步学习 Linux 系统打下坚实的基础。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-3.jpg)
高清 PDF 版在 GitHub 上的一个开源仓库(JavaBooks)里可以找得到(附 linux-0.11 内核的源码):
>https://github.com/itwanger/JavaBooks#Linux%E5%86%85%E6%A0%B8
我在逛 GitHub 的时候发现了这样一个仓库:
>https://github.com/hoverwinter/HIT-OSLab
作者大四,他的这门操作系统实验课满分,打算自己写一个 OS,就顺带把之前的代码给开源了出来,希望对学习操作系统,以及对哈工大这门实验课感兴趣的同学一些参考。
其中 lab1-lab7 给出了修改的部分,lab 8 给出了完整的修改后的 linux-0.11 的代码。虽然这个仓库已经有好多年没有更新了,但仍然有参考的价值。
作者的那句:“Just coding system,it’s fantastic!”我觉得也蛮给力的。
### 二、MIT 6.268 和 6.S081
国外的强烈推荐 MIT 6.268 这门课(主要研究生级别),是一门公认的硬核课程,一直以来都有很高的知名度,广受好评,是理论与实践相结合的经典。
>https://pdos.csail.mit.edu/6.828/2018/schedule.html
不过,在学习这门课之前,最好之前有过一些操作系统的基础,比如说上过本校的 OS 课,比如说阅读过《操作系统导论》这本书,比如说熟悉 C语言和汇编,对计算机组成原理也有一定的了解。
这门课有多牛逼呢?
>举个例子,以陈波老师为首的上海交通大学的 IPADS 实验室可以说是国内最强的操作系统相关实验室之一了,而陈波老师等人在读博阶段就完成了 6.828 课程的学习,并且在此基础上开发了 corey 操作系统,并发表了一篇被广泛引用的论文:Corey——An operating system for many cores。
如果觉得这门课的难度有点大,可以选择 MIT 的 6.S081(Introduction to Operating System,操作系统导论)这门课,主要针对本科生级别。
>https://pdos.csail.mit.edu/6.S081/2020/schedule.html
6.S081 这门课是基于一个类似于 Unix,但比 Unix 简单得多的一个教学操作系统 XV6 来讲解的,虽然不是原汁原味的 Linux,但对于理解 Linux 的工作方式和结构是足够了。
这门课是全英文的形式,video 链接里甚至没有英文字幕,对于国内的同学来说,如果英文功底一般的话,很难较好的理解这门课程。
下图是课程表,里面有 PDF 和 video 链接🔗。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-4.png)
为了减轻大家的学习压力,我在哔哩哔哩上找到了这门课的克隆版,但中英文字幕的那种。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-5.png)
哇,有了中英文字幕,学起来就舒服多了。课程地址我贴一下:
>https://www.bilibili.com/video/BV19k4y1C7kA
除了这个,我还找到了一份中文版的在线阅读文档,总共有 35 万字左右,据作者说,他大概花费了 200 个小时,辛苦劳作的结果是不仅作者自己的知识盲区补全了,也为后来者留下了一笔不可多得的学习资料。害,除了能蹦出“牛逼”两个字外,我想不到更惊艳的词汇了!
>https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-6.png)
这门课的一部分会讲操作系统的基本概念,一部分是 lab,几乎每周都会有一些编程实验。
我们都知道,操作系统很重要,那操作系统的学习单靠看和听肯定是不行的,必须配合实战来。做实验的意义就在于能帮我们获得一些使用和实现操作系统的实际动手经验。
还有xiaofan 的学习笔记也是非常值得参考的:
>https://fanxiao.tech/posts/MIT-6S081-notes/#11-processes-and-memory
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-7.png)
学习 6.S081 这门课的目的有三个:
- 理解操作系统的设计和实现
- 能动手扩展一个小型 OS
- 能动手实现系统应用
### 三、硬核 OS PDF
这里给大家推荐两门超级硬核的操作系统学习资料,我都已经整理成 PDF 了。
第一份,给操作系统捋条线
看图感受一下吧,想要下载的话,戳这个[链接🔗](https://mp.weixin.qq.com/s/puTGbgU7xQnRcvz5hxGBHA)
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-8.png)
第二份,操作系统核心知识点
同样看图感受一下吧,想要下载的话,戳这个[链接🔗](https://mp.weixin.qq.com/s/_lOvToFwDki2nDFvwDV5gg)
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/os-9.png)
有一说一,操作系统确实难刷,大家在刷的过程中一定要记得多喝水,因为这门课实在是太干了。说实话,光是整理这两门课的过程,我就又 get 到了不少新鲜的知识点。希望我推荐的这两门课算是抛砖引玉吧,大家一起冲!
记住一点,**动手很重要,动手做 lab 很重要**
先上一张 Python 知识图谱,直观的了解一下 Python 的基本构成与实际应用。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-1.png)
**1)视频篇**
B 站也就是哔哩哔哩,是国内最大的二次元视频网站之一。作为一个半吊子 up 主,我虽然看视频不多,但现在基本想看视频就直接去 B 站了。
上面也有非常多的 Python 视频可供学习。
01、小甲鱼零基础入门学习Python,1669.8万播放。画面虽然有点儿童风,但配合 up 幽默的教学风格到也显得非常有意思。
>https://www.bilibili.com/video/av4050443
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-2.png)
02、Python从入门到精通教程,1165.8万播放。虽然是培训机构出品的,但视频质量还过得去,也比较像大学老师的授课风格,况且还可以白票。前 100 集在讲 Linux 基础,没兴趣的可以直接跳过。
>https://www.bilibili.com/video/av14184325
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-3.png)
03、Python编程从入门到实践,84.4万播放。虽然播放量一般,内容也一般,但如果想听萝莉小姐姐的声音的话,可以尝试下,听完整个人都治愈了。
>https://www.bilibili.com/video/av35698354
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-4.png)
**2)教程篇**
01、Python 3.10.0 文档,官方文档,毫无疑问是需要学习的。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-5.png)
>https://docs.python.org/zh-cn/3/
02、Python - 100天从新手到大师,112k star,足见受到的关注程度。
>https://github.com/jackfrued/Python-100-Days
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-6.png)
03、Python Cookbook,比较适合那些想深入理解 Python 语言机制和现代编程风格的有经验的 Python 程序员。
![](https://cdn.jsdelivr.net/gh/itwanger/toBeBetterJavaer/images/xuexiluxian/python-7.png)
>https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
......@@ -18,6 +18,7 @@
<body>
<nav>
<a href="https://mp.weixin.qq.com/s/bUTOG2jOw1gWw-YpZaxqww">计算机经典书单下载</a>
<a href="https://mp.weixin.qq.com/s/bUTOG2jOw1gWw-YpZaxqww">计算机经典书单下载</a>
</nav>
<div id="app">加载中。。。</div>
......@@ -26,6 +27,7 @@
name: '<span>🌈Java程序员进阶之路</span>',
repo: 'https://github.com/itwanger/toBeBetterJavaer',
loadSidebar: true,
loadNavbar: true,
autoHeader: false,
coverpage: true,
onlyCover: false,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册