文章目录
- 入门篇
-
- 操作系统入门 Linux
- 编程技能
- 专业基础篇
-
- 编程语言
-
- Java 语言
- 学习 Go 语言
- 理论学科
-
- 数据结构和算法
- 其它理论基础知识
- 系统知识
-
- C10K 问题
- 实践项目
- 软件设计篇
-
- 编程范式
- 一些软件设计的相关原则
- 一些软件设计的读物
- 高手成长篇
-
- Linux 系统、内存和 络(系统底层知识)
-
- Linux 系统相关
- 内存相关
- 计算机 络
-
- 络学习
- 络调优
- 络协议
- 异步 I/O 模型和 Lock-Free 编程(系统底层知识)
-
- 异步 I/O 模型
- Lock-Free 编程相关
- 其它
- 相关论文
- 小结
- Java 底层知识
-
- Java 字节码相关
- JVM 相关
- 小结
- 数据库
-
- 关系型数据库
- NoSQL 数据库
- 各种 NoSQL 数据库
- 小结
- 分布式架构入门(分布式架构)
-
- 分布式架构入门
- 分布式理论
- 小结
- 分布式架构经典图书和论文(分布式架构)
-
- 经典图书
- 经典论文
-
- 分布式事务
- Paxos 一致性算法
- Raft 一致性算法
- Gossip 一致性算法
- 分布式存储和数据库
- 分布式消息系统
- 日志和数据
- 分布式监控和跟踪
- 数据分析
- 与编程相关的论文
- 其它的分布式论文阅读列表
- 小结
- 分布式架构工程设计 (分布式架构)
-
- 设计模式
- 设计与工程实践
-
- 分布式系统的故障测试
- 弹性伸缩
- 一致性哈希
- 数据库分布式
- 缓存
- 消息队列
- 关于日志方面
- 关于性能方面
- 关于搜索方面
- 各公司的架构实践
- 小结
- 微服务
-
- 微服务架构
- 微服务和 SOA
- 设计模式和最佳实践
- 相关资源
- 小结
- 容器化和自动化运维
-
- Docker
- Kubernetes
- 小结
- 机器学习和人工智能
-
- 基本原理简介
- 相关课程
- 相关图书
- 相关文章
- 相关算法
- 相关资源
- 小结
- 前端基础和底层原理(前端方向)
-
- HTML 5
- CSS
- JavaScript
- 浏览器原理
- 络协议
- 小结
- 前端性能优化和框架(前端方向)
-
- 前端框架
-
- React.js 框架
- Vue.js 框架
- 小结
- UI/UX 设计(前端方向)
-
- 图书和文章推荐
- 原子设计(Atomic Design)
- 设计语言和设计系统
-
- Fluent Design System
- Material Design
- 其它公司
- 动画效果设计
- 相关资源
-
- 文章资源
- 设计收集
- 小结
- 技术资源集散地
-
- YouTube 技术频道
入门篇
通过这一系列文章,我主要想回答以下几个问题。
-
理论和现实的差距。你是否觉得自己从学校毕业的时候只做过小玩具一样的程序入职场后哪怕没有什么经验也可以把文中提到的这些课外练习走一遍。学校课程总是从理论出发,作业项目都看不出有什么实际作用,到了工作上发现自己什么也不会干。
-
技术能力的瓶颈。你又是否觉得,在工作当中需要的技术只不过是不断地堆业务功能,完全没有什么技术含量。而你工作一段时间后,自己都感觉得非常地迷茫和彷徨,感觉到达了提高的瓶颈,完全不知道怎么提升了。
-
技术太多学不过来。你是否又觉得,要学的技术多得都不行了,完全不知道怎么学觉完全跟不上。有没有什么速成的方法/p>
对此,我有如下的一些解释,以端正一下你的态度。
- 并不是理论和现实的差距大,而是你还没有找到相关的场景,来感受到那些学院派知识的强大威力。算法与数据结构、操作系统原理、编译原理、数据库原理、计算机原理……这些原理上的东西,是你想要成为一个专家必须要学的东西。这就是“工人”和“工程师”的差别,是“建筑工人”和“建筑架构师”的差别。如果你觉得这些理论上的东西无用,那么只能说明,你只不过在从事工人的工作,而不是工程师的工作。
- 技术能力的瓶颈,以及技术太多学不过来,只不过是你为自己的能力不足或是懒惰找的借口罢了。技术的东西都是死的,这些死的知识只要努力就是可以学会的。只不过聪明的人花得时间少,笨点的人花得时间多点罢了。这其中的时间差距主要是由学习方法的不同,基础知识储备的不同决定的。只要你方法得当,多花点时间在基础知识上,会让你未来学习应用知识的时间大大缩短。以绝大多数人努力的程度,和为自己不努力找借口的程度为参考,只要你坚持正常的学习就可以超过大多数人了。
- 这里没有学习技术的速成的方法,真正的牛人不是能够培训出来的,一切都是要靠你自己去努力和持续地付出。如果你觉得自己不是一个能坚持的人,也不是一个想努力的人,而是一个想找捷径的人,那么,这篇文章并不适合你。这篇文章中的成长路径是需要思考、精力和相关的经验的,这都需要时间,而且是不短的时间。你先问问自己有没有花十年磨一剑的决心,如果没有,那这篇文章对你没有任何作用。
学习建议。
- 一定要坚持,要保持长时间学习,甚至终生学习的态度。
- 一定要动手,不管例子多么简单,建议至少自己动手敲一遍看看是否理解了里头的细枝末节。
- 一定要学会思考,思考为什么要这样,而不是那样。还要举一反三地思考。
- 不要乱买书,不要乱追新技术新名词,基础的东西经过很长时间积累,会在未来至少 10 年通用。
- 回顾一下历史,看看历史时间线上技术的发展,你才能明白明天会是什么样的。
操作系统入门 Linux
学习编程你还需要会玩 Linux,虽然 Windows 占据着更多的桌面市场,但是你还是要了解 Linux。这里,你可以看一下,W3CSchool 上的在线教程 Linux 教程。
记得要看官方文档!!!!!
编程技能
在系统地学习编程技能之前,我希望你能先看一下 ” The Key To Accelerating Your Coding Skills”, 这篇文章会告诉你如何有效地快速提高自己的编程能力。
然后接下来是下面几大块内容,但还只是入门级的。
- 编程技巧方面 – 你可以开始看怎么把程序写好的书了,这里推荐的是**《代码大全》**。这本书好多年没有更新了,其中有一些内容可能有点过时,但还是一本非常好的书,有点厚,你不需要马上就看完。在你的编程路上,这本书可以陪你走很久,因为当你有更多的编程经验时,踩过更多的坑后,再把这本书拿出来看看,你会有更多的体会。好的书和不好的书最大的区别就是,好的书在你不同的阶段来读,你会有不同的收获,而且还会产生更多的深层次的思考! 《代码大全》就是这样的一本书。
- 编程语言方面 – 这个阶段,你可以开始了解一下 Java 语言了,我个人觉得 Java 是世界上目前为止综合排名最好的语言。你一定要学好这门语言。推荐《Java 核心技术(卷 1)》,除了让你了解 Java 的语法,它还会让你了解面向对象编程是个什么概念(如果你觉得这本书有点深,那么,你可以降低难度看更为基础的《Head First Java》)。然后,既然开始学习 Java 了,那就一定要学 Spring,推荐看看《Spring in Action》或是直接从最新的 Spring Boot 开始,推荐看看《Spring Boot 实战》。关于 Spring 的这两本书,里面可能会有很多你从来没有听说过的东西,比如,IoC 和 AOP 之类的东西,能看懂多少就看懂多少,没事儿。——Spring实战
- 操作系统 – 这里你可以看看《鸟哥的 Linux 私房菜》,这本书会让你对计算机和操作系统,以及 Linux 有一个非常全面的了解,并能够管理或是操作好一个 Linux 系统。当然,这本书有很多比较专业的知识,你可能会看不懂,没关系,就暂时略过就好了。这本书的确并不适合初学者,你能看多少就看多少吧。
- 络协议 – 你需要系统地了解一下 HTTP 协议,请到 MDN 阅读一下其官方的 HTTP 的文档。你需要知道 HTTP 协议的几个关键点:1)HTTP 头,2)HTTP 的请求方法,3)HTTP 的返回码。还有,HTTP 的 Cookie、缓存、会话,以及链接管理,等等,在 MDN 的这个文档中都有了。对于 HTTP 协议,你不需要知道所有的东西,你只需要了解这个协议的最关键的那些东西就好了。
- 数据库设计 – 你需要系统地了解一下数据库设计中的那些东西,这里推荐慕课 的一个在线课程:数据库设计的那些事。每个小课程不过 5-6 分钟,全部不到 2 个小时,我相信你一定能跟下来。你需要搞清楚数据的那几个范式,还有 SQL 语句的一些用法。当然,你还要学习和使用一下数据库,这里推荐学习开源的 MySQL。你可以看官方文档,也可以看一下这本书《MySQL 必知必会》。
- 前端方面 – 前端的东西不算复杂,你需要学习几个东西。一个是和 JavaScript 相关的 jQuery,另一个是和 CSS 相关的 Bootstrap,学习这两个东西都不复杂,直接上其官 看文档就好了。最重要的是,你要学习一下如何使用 JavaScript Ajax 请求后端的 API 接口,而不是再像前面那样用后端来向前端返回 HTML 页面的形式了。这里,你需要学习一下,JavaScript 的 Promise 模式。阮一峰翻译的 ES6 的教程中有相关的内容。当然,你 Google 一下,也可以找到一堆学习资料。
- 字符编码方面 – 在你处理中文时有时会发现有乱码出现,此时需要了解 ASCII 和 Unicode 这样的字符编码。这里推荐一篇文章 – “关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)” 或是英文文章 “The history of Character Encoding” 以及 Wikipedia – Character encoding。还有 GitHub 上的这两个 Awesome 仓库:Awesome Unicode 和 Awesome Code Points。
专业基础篇
编程语言
Java 语言
学习 Java 语言有以下入门级的书(注意:下面一些书在入门篇中有所提及,但为了完整性,还是要在这里提一下,因为可能有朋友是跳着看的)。
- 《Java 核心技术:卷 1 基础知识》,这本书本来是 Sun 公司的官方用书,是一本 Java 的入门参考书。对于 Java 初学者来说,是一本非常不错的值得时常翻阅的技术手册。书中有较多地方进行 Java 与 C++ 的比较,因为当时 Java 面世的时候,又被叫作 “C++ Killer”。而我在看这本书的时候,发现书中有很多 C++ 的东西,于是又去学习了 C++。学习 C++ 的时候,发现有很多 C 的东西不懂,又顺着去学习了 C。然后,C -> C++ -> Java 整条线融汇贯通,这对我未来的技术成长有非常大的帮助。
- 有了上述的入门后,Java 的 Spring 框架是你玩 Java 所无法回避的东西,所以接下来是两本 Spring 相关的书,《Spring 实战》和《Spring Boot 实战》。前者是传统的 Spring,后者是新式的微服务的 Spring。如果你只想看一本的话,那么就看后者吧。
前面推荐的几本书可以帮你成功入门 Java,但想要进一步成长,就要看下面我推荐的几本进阶级别的书了。
-
接下来,你需要了解了一下如何编写高效的代码,于是必需看一下《Effective Java》(注意,这里我给的引用是第三版的,也是 2017 年末出版的书),这本书是模仿 Scott Meyers 的经典图书《Effective C++》的。Effective 这种书基本上都是各种经验之谈,所以,这是一本非常不错的书,你一定要读。这里需要推荐一下 Google Guava 库 ,这个库不但是 JDK 的升级库,其中有如:集合(collections)、缓存(caching)、原生类型支持(primitives support)、并发库(concurrency libraries)、通用注解(common annotations)、字符串处理(string processing)、I/O 等库,其还是 Effective Java 这本书中的那些经验的实践代表。
-
了解如何编写出并发的程序,你还需要了解一下如何优化 Java 的性能。我推荐《Java 性能权威指南》。通过学习这本书,你可以比较大程度地提升性能测试的效果。其中包括:使用 JDK 中自带的工具收集 Java 应用的性能数据,理解 JIT 编译器的优缺点,调优 JVM 垃圾收集器以减少对程序的影响,学习管理堆内存和 JVM 原生内存的方法,了解如何最大程度地优化 Java 线程及同步的性能,等等。看完这本书后,如果你还有余力,想了解更多的底层细节,那么,你有必要去读一下《深入理解 Java 虚拟机》。
-
《Java 编程思想》,真是一本透着编程思想的书。上面的书让你从微观角度了解 Java,而这本书则可以让你从一个宏观角度了解 Java。这本书和 Java 核心技术的厚度差不多,但这本书的信息密度比较大。所以,读起来是非常耗大脑的,因为它会让你不断地思考。对于想学好 Java 的程序员来说,这是一本必读的书。
-
《精通 Spring 4.x》,也是一本很不错的书,就是有点厚,一共有 800 多页,都是干货。我认为其中最不错的是在分析原理,尤其是针对前面提到的 Spring 技术,应用与原理都讲得很透彻,IOC 和 AOP 也分析得很棒,娓娓道来。其对任何一个技术都分析得很细致和全面,不足之处就是内容太多了,所以导致很厚,但这并不影响它是一本不错的工具书。
当然,学 Java 你一定要学面向对象的设计模式,这里就只有一本经典的书《设计模式》。如果你觉得有点儿难度了,那么可以看一下《Head First 设计模式》。学习面向对象的设计模式时,你不要迷失在那 23 个设计模式中,你一定要明白这两个原则:
-
Program to an ‘interface’, not an ‘implementation’
- 使用者不需要知道数据类型、结构、算法的细节。
- 使用者不需要知道实现细节,只需要知道提供的接口。
- 利于抽象、封装,动态绑定,多态。符合面向对象的特质和理念。
-
Favor ‘object composition’ over ‘class inheritance’
- 继承需要给子类暴露一些父类的设计和实现细节。
- 父类实现的改变会造成子类也需要改变。
- 我们以为继承主要是为了代码重用,但实际上在子类中需要重新实现很多父类的方法。
- 继承更多的应该是为了多态。
至此,如果你把上面的这些知识都融汇贯通的话,那么,你已是一个高级的 Java 程序员了,我保证你已经超过了绝大多数程序员了。基本上来说,你在技术方面是可以进入到一线公司的,而且还不是一般的岗位,至少是高级程序员或是初级架构师的级别了。
学习 Go 语言
C 语言太原始了,C++ 太复杂了,Go 语言是不二之选。有了 C/C++ 的功底,学习 Go 语言非常简单。
首推 Go by Example 作为你的入门教程。然后,Go 101 也是一个很不错的在线电子书。如果你想看纸书的话,The Go Programming Language 一书在豆瓣上有 9.2 分,但是国内没有卖的。(当然,我以前也写过两篇入门的供你参考 “GO 语言简介(上)- 语法” 和 “GO 语言简介(下)- 特性”)。
另外,Go 语言官方的 Effective Go 是必读的,这篇文章告诉你如何更好地使用 Go 语言,以及 Go 语言中的一些原理。
Go 语言最突出之处是并发编程,Unix 老牌黑客罗勃·派克(Rob Pike)在 Google I/O 上的两个分享,可以让你学习到一些并发编程的模式。
- Go Concurrency Patterns( 幻灯片和演讲视频)。
- Advanced Go Concurrency Patterns(幻灯片、演讲视频)。
然后,Go 在 GitHub 的 wiki 上有好多不错的学习资源,你可以从中学习到多。比如:
- Go 精华文章列表。
- Go 相关博客列表。
- Go Talks。
此外,还有个内容丰富的 Go 资源列表 Awesome Go,推荐看看。
理论学科
数据结构和算法
算法是比较难学习的,而且学习“算法”是需要智商的。数组、链表、哈希表、二叉树、排序算法等一些基础知识,对大多数人来说是没什么问题的。但是一旦进入到路径规划、背包问题、字符串匹配、动态规划、递归遍历等一些比较复杂的问题上,就会让很多人跟不上了,不但跟不上,而且还会非常痛苦。是的,解决算法问题的确是可以区分人类智商的一个比较好的方式,这也是为什么好些公司用算法题当面试题来找到智商比较高的程序员。
然而,在很多时候,我们在工作中却发现根本用不到算法,或是一些基本的算法也没有必要实现,只需要使用一下第三方的库就好了。于是,导致 会上出现很多“算法无用论”的声音。
对此,我想说,算法真的很重要。我这 20 年的经历告诉我,无论是做业务还是做底层系统,经常需要使用算法处理各种各样的问题。比如,业务上我需要用算法比较两个数组中差异的布隆过滤器,或是在做监控系统时实时计算过去一分钟的 P99 统计时的蓄水池算法,或是数据库的 B+ 树索引,还有 Linux 内核中的 epoll 的红黑树,还有在做服务调度里的“背包问题”等都会用算法,真的是会本质上帮助到你,也是会让你瞬间会产生成就感的事情。
虽然算法很难,需要智商,但我还是想鼓励你,这其中是有很多的套路是可以学习的,一旦学会这些套路,你会受益无穷的。
这里有几本书着重推荐一下。
- 基础知识。《算法》,是算法领域经典的参考书,不但全面介绍了关于算法和数据结构的必备知识,还给出了每位程序员应知应会的 50 个算法,并提供了实际代码。最不错的是,其深入浅出的算法介绍,让一些比较难的算法也变得容易理解,尤其是书中对红黑树的讲解非常精彩。其中,还有大量的图解,详尽的代码和讲解,也许是最好的数据结构入门图书。不好的是不深,缺乏进一步的算法设计内容,甚至连动态规划都未提及。另外,如果你觉得算法书比较枯燥的话,你可以看看这本有趣的《算法图解》。
- 理论加持。如果说上面这本书偏于实践和工程,而你看完后,对算法和数据结构的兴趣更浓了,那么你可以再看看另一本也是很经典的偏于理论方面的书——《算法导论》。虽然其中的一些理论知识在《算法》那本书中也有提过,但《算法导论》这本书更为专业一些,是美国计算机科学本科生的教科书。
然后,你需要去做一些题来训练一下自己的算法能力,这里就要推荐 LeetCode 这个 站了。它是一个很不错的做算法训练的地方。现在也越做越好了。基本上来说,这里会有两类题。
- 基础算法题。其中有大量的算法题,解这些题都是有套路的,不是用递归(深度优先 DFS、广度优先 BFS),就是要用动态规划(Dynamic Programming),或是折半查找(Binary Search),或是回溯(Back tracing),或是分治法(Divide and Conquer),还有大量的对树、数组、链表、字符串和 hash 表的操作。通过做这些题能让你对这些最基础的算法的思路有非常扎实的了解和训练。对我而言,Dynamic Programming 是我的短板,尤其是一些比较复杂的问题,在推导递推公式上总是有思维的缺陷(数学是我的硬伤)。做了这些题后,我能感到我在动态编程的思路上受到了很大的启发。
- 编程题。比如:atoi、strstr、add two nums、括 匹配、字符串乘法、通配符匹配、文件路径简化、Text Justification、反转单词等,这些题的 Edge Case 和 Corner Case 有很多。这些题需要你想清楚了再干,只要你稍有疏忽,就会有几个 case 让你痛不欲生,而且一不小心就会让你的代码写得又臭又长,无法阅读。通过做这些题,可以非常好地训练你对各种情况的考虑,以及你对程序代码组织的掌控(其实就是其中的状态变量)。
我觉得每个程序员都应该花时间和精力做这些题,因为你会从这些题中得到很大的收益。我在 Leetcode 上做的一些题的代码在这——我的 GitHub 上,可以给你一些参考。
如果能够把这些算法能力都掌握了,那么你就有很大的概率可以很容易地通过这世界上最优的公司的面试,比如:Google、Amazon、Facebook 之类的公司。对你来说,如果能够进入到这些公司里工作,那么你未来的想像空间也会大很多。
最后,我们要知道这个世界上的数据结构和算法有很多,下面给出了两个 站。
- List of Algorithms ,这个 站罗列了非常多的算法,完全可以当成一个算法字典,或是用来开阔眼界。
- 还有一个数据结构动画图的 站 Data Structure Visualizations。
其它理论基础知识
下面这些书,基本上是计算机科学系的大学教材。如果你想有科班出身的理论基础,那么这些书是必读的。当然,这些理论基础知识比较枯燥,但我觉得如果你想成为专业的程序员,那么应该要找时间读一下。
- 《数据库系统概念》,它是数据库系统方面的经典教材之一。国际上许多著名大学包括斯坦福大学、耶鲁大学、德克萨斯大学、康奈尔大学、伊利诺伊大学、印度理工学院等都采用本书作为教科书。这本书全面介绍了数据库系统的各种知识,透彻阐释数据库管理的基本概念。不仅讨论了数据库查询语言、模式设计、数据仓库、数据库应用开发、基于对象的数据库和 XML、数据存储和查询、事务管理、数据挖掘与信息检索以及数据库系统体系结构等方面的内容,而且对性能评测标准、性能调整、标准化以及空间与地理数据、事务处理监控等高级应用主题进行了广泛讨论。
- 《现代操作系统》,这本书是操作系统领域的经典之作,书中集中讨论了操作系统的基本原理,包括进程、线程、存储管理、文件系统、输入 / 输出、死锁等,同时还包含了有关计算机安全、多媒体操作系统、掌上计算机操作系统、微内核、多核处理机上的虚拟机以及操作系统设计等方面的内容。
- 《计算机 络》,这本书采用了独创的自顶向下方法,即从应用层开始沿协议栈向下讲解计算机 络的基本原理,强调应用层范例和应用编程接口,内容深入浅出,注重教学方法,理论与实践相结合。新版中还增加了无线和移动 络一章,并扩充了对等 络、BGP、MPLS、 络安全、广播选路和因特 编址及转发方面的材料。是一本不可多得的教科书。
- 《计算机程序的构造和解释》,这本书也很经典,是 MIT 的计算机科学系的教材。这本书中主要证实了很多程序是怎么构造出来的,以及程序的本质是什么。整本书主要是使用 Scheme/Lisp 语言,从数据抽象、过程抽象、迭代、高阶函数等编程和控制系统复杂性的思想,到数据结构和算法,到编译器 / 解释器、编程语言设计。
- 《编译原理》,这本书又叫 ” 龙书 “,其全面、深入地探讨了编译器设计方面的重要主题,包括词法分析、语法分析、语法制导定义和语法制导翻译、运行时刻环境、目标代码生成、代码优化技术、并行性检测以及过程间分析技术,并在相关章节中给出大量的实例。与上一版相比,本书进行了全面的修订,涵盖了编译器开发方面的最新进展。每章中都提供了大量的系统及参考文献。
系统知识
进入专业的编程领域,学习系统知识是非常关键的一部分。
首先推荐的是翻译版图书《深入理解计算机系统》,原书名为《Computer Systems A Programmer’s Perspective》。不过,这本书叫做《程序员所需要了解的计算机知识》更为合适。
本书的最大优点是为程序员描述计算机系统的实现细节,帮助其在大脑中构造一个层次型的计算机系统。从最底层的数据在内存中的表示到流水线指令的构成,到虚拟存储器,到编译系统,到动态加载库,到最后的用户态应用。通过掌握程序是如何映射到系统上,以及程序是如何执行的,你能够更好地理解程序的行为为什么是这样的,以及效率低下是如何造成的。
再强调一下,这本书是程序员必读的一本书!
然后就是美国计算机科学家 理查德·史蒂文斯(Richard Stevens) 的三套巨经典无比的书。(理查德·史蒂文斯于 1999 年 9 月 1 日离世,终年 48 岁。死因不详,有人说是滑雪意外,有人说是攀岩意外,有人说是滑翔机意外。总之,家人没有透露。大师的 个人主页 今天还可以访问。)
- 《Unix 高级环境编程》。
- 《Unix 络编程》 第 1 卷 套接口 API 、第 2 卷 进程间通信 。
- 《TCP/IP 详解 卷 I 协议》。
这几本书的地位我就不多说了,你可以自己看相关的书评。但是,这三本书可能都不容易读,一方面是比较厚,另一方面是知识的密度太大了,所以,读起来有点枯燥和乏味。但是,这没办法,你得忍住。
这里要重点说一下《TCP/IP 详解》这本书,是一本很奇怪的书。这本书迄今至少被 近五百篇学术论文引用过 。这本写给工程师看的书居然被各种学院派的论文来引用,也是很神奇的一件事了。而且,虽然理查德·史蒂文斯不是 TCP 的发明人,但是这本书中把这个协议深入浅出地讲出来,还画了几百张时序图,也是令人叹为观止了。
如果你觉得上面这几本经典书比较难啃,你可以试试下面这些通俗易懂的(当然,如果读得懂上面那三本的,下面的这些也就不需要读了)。
- 《Linux C 编程一站式学习》。
- 《TCP/IP 络编程》。
- 《图解 TCP/IP》,这本书其实并不是只讲了 TCP/IP,应该是叫《计算机 络》才对,主要是给想快速入门的人看的。
- 《The TCP/IP Guide》,这本书在豆瓣上的评分 9.2,这里给的链接是这本书的 HTML 英文免费版的,里面的图画得很精彩。
看完《Unix 高级环境编程》后,你可以趁热打铁看看《Linux/Unix 系统编程手册》或是罗伯特·拉姆(Robert Love)的 Linux System Programming 英文电子版 。其中文翻译版Linux 系统编程 也值得一读,虽然和《Unix 高级环境编程》很像,不过其主要突出的是 Linux 的一些关键技术和相关的系统调用。
关于 TCP 的东西,你还可以看看下面这一系列的文章。
- Let’s code a TCP/IP stack, 1: Ethernet & ARP
- Let’s code a TCP/IP stack, 2: IPv4 & ICMPv4
- Let’s code a TCP/IP stack, 3: TCP Basics & Handshake
- Let’s code a TCP/IP stack, 4: TCP Data Flow & Socket API
- Let’s code a TCP/IP stack, 5: TCP Retransmission
对于系统知识,我认为主要有以下一些学习要点。
- 用这些系统知识操作一下文件系统,实现一个可以拷贝目录树的小程序。
- 用 fork / wait / waitpid 写一个多进程的程序,用 pthread 写一个多线程带同步或互斥的程序。比如,多进程购票的程序。
- 用 signal / kill / raise / alarm / pause / sigprocmask 实现一个多进程间的信 量通信的程序。
- 学会使用 gcc 和 gdb 来编程和调试程序(参看我的《用 gdb 调试程序》一、二、三、四、五、六、七)。
- 学会使用 makefile 来编译程序(参看我的《跟我一起写 makefile》一、二、三、四、五、六、七、八、九、十、十一、十二、十三、十四)。
- Socket 的进程间通信。用 C 语言写一个 1 对 1 的聊天小程序,或是一个简单的 HTTP 服务器。
C10K 问题
然后,当你读完《Unix 络编程》后,千万要去读一下 “C10K Problem (中文翻译版)”。提出这个问题的人叫丹·凯格尔(Dan Kegel),目前在 Google 任职。
C10K 问题本质上是操作系统处理大并发请求的问题。对于 Web 时代的操作系统而言,对于客户端过来的大量的并发请求,需要创建相应的服务进程或线程。这些进程或线程多了,导致数据拷贝频繁(缓存 I/O、内核将数据拷贝到用户进程空间、阻塞), 进程 / 线程上下文切换消耗大,从而导致资源被耗尽而崩溃。这就是 C10K 问题的本质。
了解这个问题,并了解操作系统是如何通过多路复用的技术来解决这个问题的,有助于你了解各种 I/O 和异步模型,这对于你未来的编程和架构能力是相当重要的。
另外,现在,整个世界都在解决 C10M 问题,推荐看看 The Secret To 10 Million Concurrent Connections -The Kernel Is The Problem, Not The Solution 一文。
实践项目
我们已经学习完了编程语言、理论学科和系统知识三部分内容,下面就来做几个实践项目,小试牛刀一下。实现语言可以用 C、C++ 或 Java。
实现一个 telnet 版本的聊天服务器,主要有以下需求。
- 每个客户端可以用使用的方式连接到服务器上。
- 新连接需要用用户名和密码登录,如果没有,则需要注册一个。
- 然后可以选择一个聊天室加入聊天。
- 管理员有权创建或删除聊天室,普通人员只有加入、退出、查询聊天室的权力。
- 聊天室需要有人数限制,每个人发出来的话,其它所有的人都要能看得到。
实现一个简单的 HTTP 服务器,主要有以下需求。
- 解释浏览器传来的 HTTP 协议,只需要处理 URL path。
- 然后把所代理的目录列出来。
- 在浏览器上可以浏览目录里的文件和下级目录。
- 如果点击子目录,则进入到子目录中,并把子目录中的文件列出来。
实现一个生产者 / 消费者消息队列服务,主要有以下需求。
- 消息队列采用一个 Ring-buffer 的数据结构。
- 可以有多个 topic 供生产者写入消息及消费者取出消息。
- 需要支持多个生产者并发写。
- 需要支持多个消费者消费消息(只要有一个消费者成功处理消息就可以删除消息)。
- 消息队列要做到不丢数据(要把消息持久化下来)。
- 能做到性能很高。
到今天,我们已经学习完了专业编程方面最为重要的三部分内容:编程语言、理论学科和系统知识,我们针对这些内容做个小结。如果想看完我推荐的那些书和知识,并能理解和掌握,我估计怎么也得需要 4-5 年的时间。嗯,是的,就是一个计算机科学系科班出身的程序员需要学习的一些东西。这其中,最重要的是下面这几点。
编程语言。以工业级的 C、C++、Java 这三门语言为主,这三门语言才是真正算得上工业级的编程语言,因为有工业级的标准化组织在控制着这几门语言,而且也有工业级的企业应用。尤其是 Java,还衍生出了大量的企业级架构上的开源生态。你至少需要掌握 C 语言和 Java 语言,这对你以后面对各式各样的编程语言是非常重要的。
此外,还推荐学习 Go 语言,它已成为云计算领域事实上的标准语言,尤其是在 Docker、Kubernetes 等项目中。而且,Go 语言在国内外一些知名公司中有了一定的应用和实践,并且其生态圈也越来越好。
算法和数据结构。这个太重要了,尤其是最基础的算法和数据结构,这是任何一个称职的程序员都需要学习和掌握的。你必需要掌握。
计算机的相关系统。你至少要掌握三个系统的基础知识,一个是操作系统,一个是 络系统,还有一个是数据库系统。它们分别代表着计算机基础构架的三大件——计算、存储、 络。
如果你能够走到这里,把前面的那些知识都了解了(不用精通,因为精通是需要时间和实践来慢慢锤炼出来的,所以,你也不用着急),那么你已经是一个合格的程序员了,而且你的潜力和可能性是非常非常高的。
如果经历过这些比较枯燥的理论知识,而且你还能有热情和成就感,那么我要恭喜你了。因为你已经超过了绝大多数人,而且还是排在上游的比较抢手的程序员了。我相信你至少可以找到年薪 50 万以上的工作了。
但是,你还需要很多的经验或是一些实践,以及一些大系统大项目的实际动手的经验。没关系,我们后面会有教你怎么实操的方法和攻略。
但是,往后面走,你需要开始需要术业有专攻了。下面给一些建议的方向。
- 底层方向:操作系统、文件系统、数据库、 络……
- 架构方向:分布式系统架构、微服务、DevOps、Cloud Native……
- 数据方向:大数据、机器学习、人工智能……
- 前端方向:你对用户体验或是交互更感兴趣,那么你走前端的路吧。
- 其它方向:比如,安全开发、运维开发、嵌入式开发……
这些方向你要仔细选择,因为一旦选好,就要勇往直前地走下去,当然,你要回头转别的方向也没什么问题,因为你有前面的这些基础知识在身,所以,不用害怕。只是不同的方向上会有不同的经验积累,经验积累是看书看不来的,这个是转方向的成本。
下篇文章,我们将进入《软件设计篇》。敬请期待。
软件设计篇
编程范式
编程范式
学习编程范式可以让你明白编程的本质和各种语言的编程方式。因此,我推荐以下一些资料,以帮助你系统化地学习和理解。
-
一个是我在极客时间写的《编程范式游记》系列文章,目录如下。
- 编程范式游记(1)- 起源
- 编程范式游记(2)- 泛型编程
- 编程范式游记(3)- 类型系统和泛型的本质
- 编程范式游记(4)- 函数式编程
- 编程范式游记(5)- 修饰器模式
- 编程范式游记(6)- 面向对象编程
- 编程范式游记(7)- 基于原型的编程范式
- 编程范式游记(8)- Go 语言的委托模式
- 编程范式游记(9)- 编程的本质
- 编程范式游记(10)- 逻辑编程范式
- 编程范式游记(11)- 程序世界里的编程范式
-
Wikipedia: Programming paradigm ,维基百科上有一个编程范式的页面,顺着这个页面看下去,你可以看到很多很多有用的和编程相关的知识。这些东西对你的编程技能的提高会非常非常有帮助。
-
Six programming paradigms that will change how you think about coding,中文翻译版为 六个编程范型将改变你对编
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!