This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
<audio id="audio" title="69 | 程序员练级攻略:开篇词" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/7c/93/7c6db284645b825fb6accaaa20175593.mp3"></audio>
2011年我在 [CoolShell](https://coolshell.cn/) 上发表了 《[程序员技术练级攻略](https://coolshell.cn/articles/4990.html)》一文,收到了很多读读者的追捧,同时,这几年时间里,我还陆续收到了一些人的反馈,说跟着这篇文章找到了不错的工作,他们希望我把这篇文章更新一下,因为毕竟行业的变化很快。
是的,**老实说,抛开这几年技术的更新迭代不说,那篇文章写得也不算特别系统,同时标准也有点低,当时是给一个想要入门的朋友写的。所以,非常有必要从头更新一下《程序员练级攻略》这一主题**。
# 前言导读
升级版的《程序员练级攻略》会比Coolshell上的内容更多也更专业。这篇文章有【入门篇】、【修养篇】、【专业基础篇】、【软件设计篇】、【高手成长篇】五大篇章。它们会帮助你从零开始一步步地系统地完成从陌生到熟悉到理解掌握从编码到设计再到架构从码农到程序员再到工程师再到架构师的进阶实现从普通到精通到卓越的完美转身……
在**入门篇**中我先推荐的是把Python和JavaScript作为入门语言并给出了相应的学习资源和方法。Python语法比较简单有大量的库和语法糖是零基础的人学习编程的不二之选。而JavaScript是前端语言更容易让你获得编程的成就感。
随后我们需要学习使用操作系统Linux、编程工具Visual Studio Code等入门必学内容。Web互联网作为第三次工业革命信息化浪潮中最大的发明也是每个程序员都不能错过的。而学习编程还是要多多动手因此我给出了Web编程入门的学习要点并给出了一个实践项目帮助你理解和巩固所学的内容。
如果你跟着我的这个教程走过来,并能自己去解决遇到的问题,那么,我相信你能够做一点东西了,而且你还可能会对编程非常感兴趣了。但是你千万不要以为自己已经入门了。我只是用这些内容给你一些成就感,并激发你持续学习的兴趣。
正式入门我推荐的语言是Java因为我认为它是所有语言里综合实力最强的。随后推荐了更为专业实用的编程工具如编程的IDE、版本管理工具Git、调试前端程序和数据库设计工具等并且给出了一个实践项目。我同时设置了业务和技术两方面的需求跟着做一遍相信你对学习编程会有更多的理解和感悟。
接下来,我要带你进入更为专业更为复杂的编程世界中。进入之前,我们需要树立正确的三观和心态,这对于程序员来说至关重要。这就好像民工建筑队和专业的工程队的区别,就好像小作坊和工厂的差别,他们并不仅仅是差别在技能和技术上,更是差别在做事的心态和三观上。
因此,在学习专业的软件开发知识之前,我们来谈谈**程序员修养**。它看似与程序员练级关系不大,实际上却能反映出程序员的工程师特质和价值观,决定了这条路你到底能走多远,是精髓所在。**有修养的程序员才可能成长为真正的工程师和架构师,而没有修养的程序员只能沦为码农,这是码农和工程师的关键区分点。**
在“修养篇”,我给出了一些相关的学习资料,并指出了我认为比较重要的几个方面:英文能力、提问的能力、写代码的修养、安全防范意识、软件工程和上线规范、编程规范等。这些能力的训练和培养将为后续的学习和发展夯实基础。
此时,相信你已经迫不及待地想进入**专业基础篇**了。这部分内容主要涵盖编程语言、理论学科和系统知识三方面知识。在编程语言方面推荐学习C、C++和Java这三个工业级的编程语言。理论学科方面需要学习算法、数据结构、网络模型、计算机原理等内容。系统知识方面会讲述Unix/Linux、TCP/IP、C10K挑战等专业的系统知识。最后给出了你可以选择的几大从业方向。
- 如果你对操作系统、文件系统、数据库、网络等比较感兴趣,那么可以考虑从事底层方面的工作。
- 如果对分布式系统架构、微服务、DevOps、Cloud Native等有热情那么可以从事架构方面的工作。
- 如果是对大数据、机器学习、人工智能等比较关注,那么数据领域可以成为你一展身手的地方。
- 如果你对用户体验或者交互等更感兴趣,那么前端工程师也是个不错的选择。
- 此外,安全开发、运维开发、嵌入式开发等几大方向中,也为你提供了丰富多彩的发展空间。
以我之见,该如何选择应该完全遵从于你的本心,你更愿意在哪个领域里持续奋斗和学习。这个答案,在你的手中,在你的心中。**这里我只想和你说两个观点:各种技术方向不是鱼和熊掌,是可以兼得的;很多技术是相通的,关键是你是学在表面还是深入本质。**
**软件设计**能力是每个程序员都需要具备的基本素质。我结合各主流语言讲述了泛型编程、函数式编程、面向对象编程等多种编程范式分享了DRY-避免重复原则、KISS-简单原则、迪米特法则(又称“最少知识原则”)、 面向对象的S.O.L.I.D原则等等多个经典的软件设计原则。
同时,给出了软件设计领域的一些重要的学习资料。**软件设计是工程师非常重要的能力,这里描述了软件工程自发展以来的各种设计方法,这是从工程师通往架构师的必备技能。**
登峰造极是每个武林高手都渴望达到的境界对于每个有理想有追求的程序员也是如此。因此我特意在《程序员练级攻略2018》这一系列内容的最后设置了**高手成长篇**。
相较前面的内容,这部分内容相当全面和丰富,涵盖系统、数据库、分布式架构、微服务、容器化和自动化运维、机器学习、前端方向和技术论文等几方面内容,而且深度一下子拔高了好几个数量级。
同时,这也是我留给你的再一次做选择的机会,平凡还是卓越?自在悠闲,还是猛啃书本,不破楼兰终不还?还是遵循你内心的选择吧。偷偷地告诉你,我选择的是后者。
你应该不难看出这一系列文章比我在CoolShell上的那一篇更为专业标准也会更高当然难度也会更大。但是也会让你有更坚固的技术基础并能有更高更广泛的提高。
通过这一系列文章,我主要想回答以下几个问题。
- **理论和现实的差距**。你是否觉得自己从学校毕业的时候只做过小玩具一样的程序?走入职场后哪怕没有什么经验也可以把文中提到的这些课外练习走一遍。学校课程总是从理论出发,作业项目都看不出有什么实际作用,到了工作上发现自己什么也不会干。
<li>
**技术能力的瓶颈**。你又是否觉得,在工作当中需要的技术只不过是不断地堆业务功能,完全没有什么技术含量。而你工作一段时间后,自己都感觉得非常地迷茫和彷徨,感觉到达了提高的瓶颈,完全不知道怎么提升了。
</li>
<li>
**技术太多学不过来**。你是否又觉得,要学的技术多得都不行了,完全不知道怎么学?感觉完全跟不上。有没有什么速成的方法?
</li>
对此,我有如下的一些解释,以端正一下你的态度。
<li>
并不是理论和现实的差距大,而是你还没有找到相关的场景,来感受到那些学院派知识的强大威力。算法与数据结构、操作系统原理、编译原理、数据库原理、计算机原理……这些原理上的东西,是你想要成为一个专家必须要学的东西。**这就是“工人”和“工程师”的差别,是“建筑工人”和“建筑架构师”的差别**。如果你觉得这些理论上的东西无用,那么只能说明,你只不过在从事工人的工作,而不是工程师的工作。
</li>
<li>
**技术能力的瓶颈,以及技术太多学不过来,只不过是你为自己的能力不足或是懒惰找的借口罢了**。技术的东西都是死的,这些死的知识只要努力就是可以学会的。只不过聪明的人花得时间少,笨点的人花得时间多点罢了。这其中的时间差距主要是由学习方法的不同,基础知识储备的不同决定的。只要你方法得当,多花点时间在基础知识上,会让你未来学习应用知识的时间大大缩短。**以绝大多数人努力的程度,和为自己不努力找借口的程度为参考,只要你坚持正常的学习就可以超过大多数人了**。
</li>
<li>
**这里没有学习技术的速成的方法,真正的牛人不是能够培训出来的,一切都是要靠你自己去努力和持续地付出**。如果你觉得自己不是一个能坚持的人,也不是一个想努力的人,而是一个想找捷径的人,那么,这篇文章并不适合你。**这篇文章中的成长路径是需要思考、精力和相关的经验的,这都需要时间,而且是不短的时间。你先问问自己有没有花十年磨一剑的决心,如果没有,那这篇文章对你没有任何作用。**
</li>
这里有一篇传世之文《[Teach Yourself Programming in Ten Years](http://norvig.com/21-days.html)》([中英对照版](http://daiyuwen.freeshell.org/gb/misc/21-days-cn.html)。还有在我Cooslhell上的这篇《[程序员的荒谬之言还是至理名言?](https://coolshell.cn/articles/4235.html)》。
我希望你在学习编程之前先读一读这两篇文章。如果你觉得可以坚持的话,那么,我这一系列文章会对你很有帮助。否则,我相信你只要大致浏览一下目录及其中的某些章节,就会选择放弃走这条路的。是的,这个系列的文内容也会让一些想入行但又不愿意付出努力的同学早点放弃。
最后,给出我的几点**学习建议**。
- 一定要坚持,要保持长时间学习,甚至终生学习的态度。
- 一定要动手,不管例子多么简单,建议至少自己动手敲一遍看看是否理解了里头的细枝末节。
- 一定要学会思考,思考为什么要这样,而不是那样。还要举一反三地思考。
- 不要乱买书不要乱追新技术新名词基础的东西经过很长时间积累会在未来至少10年通用。
- 回顾一下历史,看看历史时间线上技术的发展,你才能明白明天会是什么样的。
另外,这篇文章的标准会非常高。希望不会把你吓坏了。《易经》有云:“**取法其上,得乎其中,取法其中,得乎其下,取法其下,法不得也**”。所以,我这里会给你立个比较高标准,你要努力达到。相信我,就算是达不到,也会比你一开始期望的要高很多……
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,145 @@
<audio id="audio" title="70 | 程序员练级攻略:零基础启蒙" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/2d/8f/2d8817d9ebe4736e6200f26710fad08f.mp3"></audio>
如果你从来没有接触过程序语言,这里给你两个方面的教程,一个偏后端,一个偏前端。对从零基础开始的人来说,最重要的是能够对编程有兴趣,而要对编程有兴趣,就要有成就感。而成就感又来自于用程序打造东西,所以,我推荐下面这份不错的入门教程。
第一份入门教程,主要是让你体会到编程是什么。
- [《与孩子一起学编程》](https://book.douban.com/subject/5338024/) 这本书以Python语言教你如何写程序是一本老少咸宜的编程书。其中会教你编一些小游戏还会和你讲基本的编程知识相当不错。
- 两个在线编程入门的网站:[Codecademy: Learn Python](https://www.codecademy.com/learn) 和 [People Can Program](https://www.peoplecanprogram.com/) 你也可以在这两个网站上学习Python只不过是英文的。
然后,你可以到 [CodeAbbey](http://www.codeabbey.com/index/task_list) 上去做一些在线编程的小练习。
第二份入门教程,主要是让你做点实际有用的东西。嗯,做个网页吧。
- [MDN的 Web开发入门](https://developer.mozilla.org/zh-CN/docs/Learn/Getting_started_with_the_web) MDN全称是Mozilla Developer Network你可以认为是Web方面的官方技术网站。这个教程会带着你建立一个网站。然后你可以把你的网页发布在GitHub上。
这两份教程都很不错,都是从零开始,带着你从环境准备开始,一点一点地从一些简单又有意思的东西入手,让你感觉一下编程世界是什么样的,相信这两个教程可以让零基础的你喜欢上编程。
# 编程入门
在这时我们使用Python和JavaScript作为入门语言。Python就不用多说了语法比较简单有大量的库和语法糖是零基础的人学习编程的不二之选。而JavaScript则是前端的语言为了让你更有编程的成就感所以这也成了一门要学习的语言。注意对于计算机专业的学生来说一般会使用Pascal做为入门的编程语言但我觉得编程入门还是要以培养兴趣为主所以还是选一些能让人有成就感的语言会更好
## 入门语言Python
如果你想更为系统地学习一下Python编程我强烈推荐你阅读下面这两本书。它们是零基础入门非常不错的图书里面有大量的更为实用的示例和项目可以快速给你正反馈。
- [Python编程快速上手](https://book.douban.com/subject/26836700/)
- [Python编程从入门到实践](https://book.douban.com/subject/26829016/)
这两本书除了编程语法方面的讲述有所不同之外其他都差不多主要是通过书中的示例来强化你对编程的学习。第一本偏文本处理包括处理Word、Excel和PDF第二本中有一些Web项目和代码部署方面的内容。如果可能的话你可以把两本书中的示例都跑一遍。如果你时间有限的话我推荐你看第二本。
[编辑植入极客时间上也有Python入门的视频课程。]
## 入门语言JavaScript
如果想入门学习JavaScript我主要推荐以下在线教程。
- [MDN JavaScript教程](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)你可以认为这是最权威的JavaScript官方教程了从初级到中级再到高级。
- [W3School JavaScript教程](http://www.w3school.com.cn/js/)这个教程比较偏Web方面的编程。
- [JavaScript全栈教程廖雪峰](https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000)这是廖雪峰的一个比较偏应用的教程也是偏Web方面的编程同时包括涉及后端的Node.js方面的教程。
## 操作系统入门Linux
学习编程你还需要会玩Linux虽然Windows占据着更多的桌面市场但是你还是要了解Linux。这里你可以看一下W3CSchool上的在线教程 [Linux教程](https://www.w3cschool.cn/linux/)。
## 编程工具Visual Studio Code
这里主要推荐时下最流行也是最好用的Visual Studio Code这个工具潜力十足用它开发Python、JavaScript、Java、Go、C/C++都能得心应手([教程](https://jeasonstudio.gitbooks.io/vscode-cn-doc/content/)
## Web编程入门
如果玩到这里你觉得有趣的话可以学习一下Web方面的入门知识。**为什么是Web而不是别的其他技术呢因为你正身处于第三次工业革命的信息化浪潮中在这个浪潮中Web互联网是其中最大的发明所以这是任何一个程序员都不能错过的**。
关于Web编程有下面几个方向你要学习一下。
<li>
**前端基础**。要系统地学习一下前端的知识也就是CSS、HTML和JavaScript这三个东西。这里还是给出MDN的相关的技术文档页面 [CSS文档](https://developer.mozilla.org/zh-CN/docs/Web/CSS) 和 [HTML文档](https://developer.mozilla.org/zh-CN/docs/Web/HTML) 。**文档很大你要学习的并不是所有的东西而是了解CSS和HTML是怎么相互作用来展示数据的然后不用记忆文档中的内容这两个文档是用来查找知识的。** 另外你可以简单地学习使用JavaScript操纵HTML。理解DOM和动态网页可以参看 [W3Schools的JavaScript HTML DOM的教程](https://www.w3schools.com/js/js_htmldom.asp))。
</li>
<li>
**后端基础**。如果你想省点事不想再学一门新的语言了那么你可以直接用Python或者Node.js这两个技术在前面提到的廖雪峰的那个教程里提到过。当然如果你想试试另外一种脚本型的也是比较主流的编程语言那么可以搞搞PHP它也是很快就可以上手的语言。学习PHP语言你可以先跟着 [W3School的PHP教程](http://www.w3school.com.cn/php/index.asp) 玩玩其中有连接数据库的MySQL的教程。然后以 [PHP的官网文档](https://php.net/manual/zh/) 作为更全的文档来学习或查找相关的技术细节。
</li>
下面是一些学习要点:
- 学习HTML基本语法。
- 学习CSS如何选中HTML元素并应用一些基本样式。
- 学会用 Firefox + Firebug 或 Chrome 查看你觉得很炫的网页结构,并动态修改。
- 在一台Linux机器上配置LEMP - Ubuntu/Nginx/PHP/MySQL这个环境。
- 学习PHP让后台PHP和前台HTML进行数据交互对服务器响应浏览器请求形成初步认识并实现一个表单提交和反显的功能。
- 把PHP连接本地或者远程数据库 MySQLMySQL 和 SQL现学现用够了
这里你可能会问我入门时有三个后端语言一个是Python一个是Node.js一个是PHP你对这三门语言怎么看老实说Python我还看好一些PHP次之Node.js最后。原因是
<li>
Python语言的应用面还是很广的。当然性能可能会有一些问题但是用于一些性能不敏感的和运维或是一些小工具相关的还是非常好用的。另外Python的应用场景其实还是很多的包括机器学习和AI也有Python的身影。用Python来做一些爬虫、简单的中间件、应用或是业务服务也是很不错的。
</li>
<li>
PHP也是一个比较主流的简单的语言PHP在目前来说还是一个比较主流的语言但其发展潜力有限虽然可以让你找得到工作但是一般玩玩就行了
</li>
<li>
Node.js 号称 JavaScript 的后端版,但从目前发展来说,在后端的世界里,并不能承担大任,而且问题很多。一些前端程序员用它来做后端的粘合层,我个人觉得这样做法只是掩盖前后端配合有问题,或是接口设计思维上的懒惰,我还是希望前端程序员应该认真学习一门真正的后端语言。
</li>
当然,这里只是让你感觉一下,**Web前端编程的感觉只是为了入门而已。所以对于这些语言你也不用学得特别精通感觉一下这几个不同的语言就可以了然后知道相关的文档和知识在哪里这样有助于你查阅相应的知识点**。
# 实践项目
无论你用Python还是Node.js还是PHP我希望你能做一个非常简单的Blog系统或是BBS系统需要支持如下功能
- 用户登录和注册(不需密码找回)。
- 用户发贴(不需要支持富文本,只需要支持纯文本)。
- 用户评论(不需要支持富文本,只需要支持纯文本)。
你需要从前端一直做到后端也就是说从HTML/CSS/JavaScript到后面的PHPPython/Node.js再到数据库。这其中需要你查阅很多的知识。
这里有几个技术点你需要关注一下。
1. 用户登录时的密码不应该保存为明文应该用MD5+Salt来保存关于这个是什么希望你能自行Google
1. 用户登录后,对于用户自己的贴子可以有“重新编辑”或 “删除”的功能,但是无权编辑或删除其它用户的贴子。
1. 数据库的设计你需要三张表用户表、文章表和评论表它们之间是怎么关联的你需要学习一下。这里有个PHP的blog教你怎么建表你可以 [前往一读](https://code.tutsplus.com/tutorials/how-to-create-a-phpmysql-powered-forum-from-scratch--net-10188)。
如果你有兴趣,你可以顺着这个小项目,研究一下下面这几个事。
- 图片验证码。
- 上传图片。
- 阻止用户在发文章或评论时输入带HTML或JavaScript的内容。
- 防范SQL注入。参看[PHP官方文档](http://php.net/manual/zh/security.database.sql-injection.php) 或 [微软官方文档](https://technet.microsoft.com/zh-cn/library/ms161953%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396)或者你自己Google一下。
上面这些东西不是什么高深的东西但是可以让你从中学到很多。相信你只需要自己Google一下就能搞定。
## 小结
接下来我总结下今天的内容。首先我推荐了Python和JavaScript作为入门语言以让你尽快上手获得成就感从而激发你想持续学习的热情。随后介绍了Linux操作系统、Visual Studio Code编程工具、Web编程入门等方面的学习资料并给出了学习要点。最后我给出了一个实践项目帮助你理解和巩固今天所学的内容。
消化好了今天的内容,就准备好精力迎接后面的挑战吧。下篇文章中,我们将正式入门学习该如何编程。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,146 @@
<audio id="audio" title="71 | 程序员练级攻略:正式入门" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/f9/a5/f97a813671302d323569f3dd83caf3a5.mp3"></audio>
学习了前面文章中的入门级经验和知识后,你可能会有两种反应。
<li>
一种反应可能是,你对编程有一点的兴趣了,甚至有一点点小骄傲,可能还会四处炫耀。我想说,请保持这种感觉,但是你也要清醒一下,上面的那些东西,还不算真正的入门,你只是入门了一条腿。
</li>
<li>
另一种反应也可能是,你被吓着了,觉得太难了。感觉不是一般人能玩的,如果是这样的话,我想鼓励你一下–“**无论你做什么事,你都会面对各式各样的困难,这对每个人来说都是一样的,而只有兴趣、热情和成就感才能让你不畏惧这些困难**”。所以,你问问你自己,是否从中收获了成就感,如果没有的话,可能这条路并不适合你。如果有的话,哪怕一丁点儿,你也应该继续坚持下来。
</li>
这篇文章,我主要是让你成为更为专业的入门程序员。请注意,此时,你可能需要读一些比较枯燥的书,但我想说,这些是非常非常重要的。你一定要坚持住。
# 编程技能
在系统地学习编程技能之前,我希望你能先看一下&quot; [The Key To Accelerating Your Coding Skills](http://blog.thefirehoseproject.com/posts/learn-to-code-and-be-self-reliant/)&quot; 这篇文章会告诉你如何有效地快速提高自己的编程能力。
然后接下来是下面几大块内容,但还只是入门级的。
<li>
**编程技巧方面** - 你可以开始看怎么把程序写好的书了,这里推荐的是《[代码大全](https://book.douban.com/subject/1477390/)》。这本书好多年没有更新了,其中有一些内容可能有点过时,但还是一本非常好的书,有点厚,你不需要马上就看完。在你的编程路上,这本书可以陪你走很久,因为当你有更多的编程经验时,踩过更多的坑后,再把这本书拿出来看看,你会有更多的体会。**好的书和不好的书最大的区别就是,好的书在你不同的阶段来读,你会有不同的收获,而且还会产生更多的深层次的思考!** 《代码大全》就是这样的一本书。
</li>
<li>
**编程语言方面** - 这个阶段你可以开始了解一下Java语言了我个人觉得Java是世界上目前为止综合排名最好的语言。你一定要学好这门语言。推荐《[Java核心技术卷1](https://book.douban.com/subject/26880667/)》除了让你了解Java的语法它还会让你了解面向对象编程是个什么概念如果你觉得这本书有点深那么你可以降低难度看更为基础的《[Head First Java](https://book.douban.com/subject/2000732/)》。然后既然开始学习Java了那就一定要学Spring推荐看看《[Spring in Action](https://book.douban.com/subject/26767354/)》或是直接从最新的Spring Boot开始推荐看看《[Spring Boot 实战](https://book.douban.com/subject/26857423/)》。关于Spring的这两本书里面可能会有很多你从来没有听说过的东西比如IoC和AOP之类的东西能看懂多少就看懂多少没事儿。
</li>
<li>
**操作系统** - 这里你可以看看《[鸟哥的Linux私房菜](https://book.douban.com/subject/4889838/)》这本书会让你对计算机和操作系统以及Linux有一个非常全面的了解并能够管理或是操作好一个Linux系统。当然这本书有很多比较专业的知识你可能会看不懂没关系就暂时略过就好了。这本书的确并不适合初学者你能看多少就看多少吧。
</li>
<li>
**网络协议** - 你需要系统地了解一下HTTP协议请到 MDN 阅读一下其官方的 [HTTP的文档](https://developer.mozilla.org/zh-CN/docs/Web/HTTP)。你需要知道HTTP协议的几个关键点1HTTP头2HTTP的请求方法3HTTP的返回码。还有HTTP的Cookie、缓存、会话以及链接管理等等在MDN的这个文档中都有了。对于HTTP协议你不需要知道所有的东西你只需要了解这个协议的最关键的那些东西就好了。
</li>
<li>
**数据库设计** - 你需要系统地了解一下数据库设计中的那些东西这里推荐慕课网的一个在线课程数据库设计的那些事。每个小课程不过5-6分钟全部不到2个小时我相信你一定能跟下来。你需要搞清楚数据的那几个范式还有SQL语句的一些用法。当然你还要学习和使用一下数据库这里推荐学习开源的MySQL。你可以看官方文档也可以看一下这本书《[MySQL必知必会](https://book.douban.com/subject/3354490/)》。
</li>
<li>
**前端方面** - 前端的东西不算复杂你需要学习几个东西。一个是和JavaScript相关的 [jQuery](https://jquery.com/)另一个是和CSS相关的 [Bootstrap](https://getbootstrap.com/)学习这两个东西都不复杂直接上其官网看文档就好了。最重要的是你要学习一下如何使用JavaScript Ajax请求后端的API接口而不是再像前面那样用后端来向前端返回HTML页面的形式了。这里你需要学习一下JavaScript的Promise模式。[阮一峰翻译的ES6的教程中有相关的内容](http://es6.ruanyifeng.com/#docs/promise)。当然你Google一下也可以找到一堆学习资料。
</li>
<li>
**字符编码方面** - 在你处理中文时有时会发现有乱码出现此时需要了解ASCII和Unicode这样的字符编码。这里推荐一篇文章 - “[关于字符编码你所需要知道的ASCII,Unicode,Utf-8,GB2312…](http://www.imkevinyang.com/2010/06/%E5%85%B3%E4%BA%8E%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%EF%BC%8C%E4%BD%A0%E6%89%80%E9%9C%80%E8%A6%81%E7%9F%A5%E9%81%93%E7%9A%84.html)” 或是英文文章 “[The history of Character Encoding](http://www.developerknowhow.com/1091/the-history-of-character-encoding)” 以及 [Wikipedia - Character encoding](https://en.wikipedia.org/wiki/Character_encoding)。还有GitHub上的这两个Awesome仓库[Awesome Unicode](https://github.com/jagracey/Awesome-Unicode) 和 [Awesome Code Points](https://github.com/Codepoints/awesome-codepoints)。
</li>
# 为什么转成Java语言
相信你可能会问为什么之前学习的Python和JavaScript不接着学而是直接切到Java语言上来这样会不会切得太快了。这是一个好问题这里需要说明一下为什么我会切到Java这个语言上来主要是有以下几方面考虑。
<li>
Java是所有语言里面综合实力最强的这也是为什么几乎所有大型的互联网或是分布式架构基本上都是Java技术栈。所以这是一个工业级的编程语言Python和JavaScript还达不到这样的水准
</li>
<li>
之所以没有用Java来做入门语言而是用了Python这是因为编程是一件比较费脑子的事一开始学习时兴趣的培养很重要。Python比较简单容易上手能够比较容易地提起兴趣而用Java则可能比较难。
</li>
<li>
在你有了一些编程语言的基础后有了一些代码的逻辑后切到工业级的编程语言上来更为专业地学习编程是非常有帮助的。像Python和JavaScript这样的动态语言用着是很爽但是只有像C、C++和Java这样的静态语言才可以让你真正地进阶。
</li>
<li>
对于一个合格的程序员,掌握几门语言是非常正常的事情。一方面,这会让你对不同的语言进行比较,让你有更多的思考。另一方面,这也是一种学习能力的培养。很多时候,一些程序员只在自己熟悉的技术而不是合适的技术上工作,这其实并不好,这会让你的视野受限,而视野会决定你的高度。综上所述,这就是在入门的时候我故意让你多学几门语言的原因。
</li>
# 编程工具
编程工具方面,你需要开始学习使用下面这些工具了。
<li>
**编程的IDE**。传统一点的你可以使用Eclipse[教程](http://www.runoob.com/eclipse/eclipse-tutorial.html)。当然我推荐你使用Intellij IDEA[教程](https://www.gitbook.com/book/dancon/intellij-idea/details)。这两个工具都可以开发各种语言但是主要用在Java。**如果你想玩得更时髦一些的话使用Visual Studio Code也不错这个工具潜力十足**用其开发Python、JavaScript、Java、Go、C和C++都能得心应手([教程](https://www.gitbook.com/book/jeasonstudio/vscode-cn-doc/details))。
</li>
<li>
**版本管理工具**。版本管理工具是非常重要的编程工具。传统的有P4、 SVN、CVS等但都会被Git取代所以你就只用学习Git就好了。学习Git的教程网上有很多这里我推荐非常系统的 [Pro Git 第二版](https://git-scm.com/book/zh/v2/) 如果你觉得Pro Git比较枯燥的话备选[猴子都能懂的Git入门](https://backlog.com/git-tutorial/cn/)然后你要学会使用GitHub。关于一些Git环境安装和准备以及GitHub使用你可以自行Google比如这篇[GitHub and Git 图文教程 ](https://github.com/JiapengLi/GitTutorial) 或是这篇[Git图文教程及详解](https://www.jianshu.com/p/1b65ed31da97))。
</li>
<li>
**调试前端程序**。你需要学会使用Chrome调试前端程序Google一下会有很多文章你可以看看 [超完整的Chrome浏览器客户端调试大全](http://www.igeekbar.com/igeekbar/post/156.htm)。
</li>
<li>
**数据库设计工具**。你需要学会使用MySQL WorkBench这个工具很容易使用。相关的手册你可以看一下[官方文档](https://dev.mysql.com/doc/refman/5.7/en/)。
</li>
# 实践项目
这回我们需要设计一个投票系统的项目。
业务上的需求如下:
- 用户只有在登录后,才可以生成投票表单。
- 投票项可以单选,可以多选。
- 其它用户投票后显示当前投票结果(但是不能刷票)。
- 投票有相应的时间,页面上需要出现倒计时。
- 投票结果需要用不同颜色不同长度的横条,并显示百分比和人数。
技术上的需求如下:
- 这回要用Java Spring Boot来实现了然后后端不返回任何的HTML只返回JSON数据给前端。
- 由前端的JQuery来处理并操作相关的HTML动态生成在前端展示的页面。
- 前端的页面还要是响应式的,也就是可以在手机端和电脑端有不同的呈现。 这个可以用Bootstrap来完成。
如果你有兴趣,还可以挑战以下这些功能。
- 在微信中,通过微信授权后记录用户信息,以防止刷票。
- 可以不用刷页面,就可以动态地看到投票结果的变化。
- Google一些画图表的JavaScript库然后把图表画得漂亮一些。
# 小结
上面那些书和知识你要看完还要能理解并掌握我估计你最少也要花1-2年左右的时间。如果你能够走到这里把前面的那些知识都了解了不用精通能独立地做出上面的那些实践项目那么你就算是真正的入门了。
而且,你已经是一个“全栈工程师”的样子了,在这里我要给你一个大大的赞。如果这个时候,你对编程还有很大的热情,那么我要恭喜你了,你可能会是一个非常不错的程序员。加油啊!
上面的那些技术已经算是比较专业的了。如果你已经大致掌握了我相信你可以找到至少年薪20万以上的工作了而且你的知识面算是有不错的广度了。但是深度还不够这个时候是一个比较关键点了。
你可能已经沉醉在沾沾自喜的骄傲的情绪中,那么你也可以就此止步,加入一些公司,在那里按部就班地完成一些功能性的开发,成为一个搬砖的码农。你也可以开始选择一个方向开始深入。
我给你的建议是选择一个方向开始深入。**因为你并不知道你未来会有多大的可能性,也不知道你会成为什么样的人,所以为什么不再更努力一把呢?**
后面,我们就开始非常专业的程序员之路了。这也是一般程序员和高级程序员的分水岭了,能不能过去就看你的了。
下面是《程序员练级攻略2018》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,360 @@
<audio id="audio" title="72 | 程序员练级攻略:程序员修养" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/be/38/beba47d04794c5a862cbf294871d3138.mp3"></audio>
在完成上述的入门知识学习之后,我们要向专业的计算机软件开发进军了。但是在学习那些专业的知识前,我们先要抽一部分的篇幅来说一下程序员的修养。这是程序员的工程师文化,也就是程序员的价值观,因为我觉得如果你的技术修养不够的话,你学再多的知识也是没有用的。
要了解程序员的修养你可以先从Quora上的这个贴子开始 “[What are some of the most basic things every programmer should know?](https://www.quora.com/What-are-some-of-the-most-basic-things-every-programmer-should-know)”,我摘录一些在这里供你参考。
- Bad architecture causes more problems than bad code.
- You will spend more time thinking than coding.
- The best programmers are always building things.
- Theres always a better way.
- Code reviews by your peers will make all of you better.
- Fewer features for better code is always the right answer in the end.
- If its not tested, it doesnt work.
- Dont reinvent the wheel, library code is there to help.
- Code thats hard to understand is hard to maintain.
- Code thats hard to maintain is next to useless.
- Always know how your business makes money, that determines who gets paid what.
- If you want to feel important as a software developer, work at a tech company.
然后是 《[97 Things Every Programmer Should Know](https://97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/index.html)》其中有97个非常不错的编程方面的建议。这篇文章是比较经典的别被“97”这个数字吓住你可以快速浏览一下会让你有不同的感觉的。另外在工作一段时间后再来读你会更有感觉。
# 英文能力
必须指出再往下走有一个技能非常重要那就是英文。如果对这个技能发怵的话那么你可能无缘成为一个程序员高手了。因为我们所有的计算机技术全部来自于西方国家所以如果你要想成为一个高手的话那么必须到信息的源头去。英文的世界真是有价值的信息的集散地。你可以在那里到官网上直接阅读手册到StackOverflow上问问题到YouTube上看很多演讲和教学到GitHub上参与社区用Google查询相关的知识到国际名校上参加公开课……
如果你的英文能力有问题的话,那么基本上来说,你无法成为一个高手。因此,学好英文是非常有必要的,我说的不只是读写,还有听和说。相信你在学校里学过英文,有一定的基础。所以,我给你下面的这些建议。
<li>
坚持Google英文关键词而不是在Google里搜中文。
</li>
<li>
在GitHub上只用英文。用英文写代码注释写Code Commit信息用英文写Issue和Pull Request以及用英文写Wiki。
</li>
<li>
坚持到YouTube上每天看5分钟的视频。YouTube上有相关的机器字幕实在不行就打开字幕。
</li>
<li>
坚持用英文词典而不是中文的。比如:[剑桥英语词典](https://dictionary.cambridge.org/) 或是 [Dictionary.com](http://www.dictionary.com/) 。你可以安装一个Chrome插件 [Google Dictionary](https://chrome.google.com/webstore/detail/google-dictionary-by-goog/mgijmajocgfcbeboacabfgobmjgjcoja)。
</li>
<li>
坚持用英文的教材而不是中文的。比如:[BBC 的 Learning English](http://www.bbc.co.uk/learningenglish/) 或是到一些ESL网站上看看如 [ESL: English as a Second Language](https://www.rong-chang.com/) 上有一些课程。
</li>
<li>
花钱参加一些线上的英文课程,用视频和老外练习。
</li>
# 问问题的能力
提问的智慧([How To Ask Questions The Smart Way](http://www.catb.org/~esr/faqs/smart-questions.html)一文最早是由Eric Steven Raymond所撰写的详细描述了发问者事前应该做好什么而什么又是不该做的。作者认为这样能让问题容易令人理解而且发问者自己也能学到较多东西。
此文一经发出,就广受好评,被广泛转载并奉为经典。该文也有 [简体中文翻译版](http://doc.zengrong.net/smart-questions/cn.html) 被流传着所以在华人界也是篇很有名的文章。有两个著名的缩写STFWSearch the fxxking web以及RTFMRead the fxxking manual就是出自本文。
另外,还有一个经典的问题叫 [X-Y Problem](http://xyproblem.info/)。对我来说这是一个很容易犯的错误所以你也要小心避免我曾经在我的Coolshell上写过这个事《[X-Y问题](https://coolshell.cn/articles/10804.html)》)。
然后你可以到StackOverflow上看看如何问问题的一些提示-- “[FAQ for StackExchange Site](https://meta.stackexchange.com/questions/7931/faq-for-stack-exchange-sites)”。
作为一个程序员,不做伸手党,你必须要读一读这几篇文章,并努力践行。
# 写代码的修养
除了《代码大全》外,你还需要补充一些如何写好代码的知识,有以下几本书推荐。
<li>
《[重构:改善既有代码的设计](https://book.douban.com/subject/4262627/)》这本书是Martin Fowler的经典之作。这本书的意义不仅仅在于&quot;改善既有代码的设计&quot;,也指导了我们如何从零开始构建代码的时候避免不良的代码风格。这是一本程序员必读的书。
</li>
<li>
《[修改代码的艺术](https://book.douban.com/subject/2248759/)》,这本书是继《重构》之后探讨修改代码技术的又一里程碑式的著作,而且从涵盖面和深度上都超过了前两部经典(《代码大全》和《重构》)。作者将理解、测试和修改代码的原理、技术和最新工具(自动化重构工具、单元测试框架、仿对象、集成测试框架等),与解依赖技术和大量开发和设计优秀代码的原则、最佳实践相结合,许多内容非常深入。这本书不仅可以帮你掌握最顶尖的修改代码技术,还可以大大提高你对代码和软件开发的领悟力。
</li>
<li>
《[代码整洁之道](https://book.douban.com/subject/4199741/)》,这本书提出一种观念:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护和升级奠定了良好基础。本书作者给出了一系列行之有效的整洁代码操作实践。这些实践在本书中体现为一条条规则,并辅以来自现实项目正反两面的范例。
</li>
<li>
《[程序员的职业素养](https://book.douban.com/subject/11614538/)》这本书是编程大师Bob大叔40余年编程生涯的心得体会讲解成为真正专业的程序员需要什么样的态度、原则需要采取什么样的行动。作者以自己以及身边的同事走过的弯路、犯过的错误为例意在为后来人引路助其职业生涯迈上更高台阶。
</li>
另外作为一个程序员Code Review是非常重要的程序员修养。 Code Review对我的成长非常有帮助我认为没有Code Review的公司都没有必要呆因为不做Code Review的公司一定是不尊重技术的。下面有几篇我觉得还不错的Code Review的文章供你参考。
- [Code Review Best Practices](https://medium.com/@palantir/code-review-best-practices-19e02780015f)
- [How Google Does Code Review](https://dzone.com/articles/how-google-does-code-review)
- [LinkedIns Tips for Highly Effective Code Review](https://thenewstack.io/linkedin-code-review/)
除了Code Review之外Unit Test也是程序员的一个很重要的修养。写Unit Test的框架一般来说都是从JUnit衍生出来的比如CppUnit之类的。学习JUnit使用的最好方式就是到其官网上看 [JUnit User Guide](https://junit.org/junit5/docs/current/user-guide/)[中文版](http://sjyuan.cc/junit5/user-guide-cn/)。然后有几篇文章你可以看看也可以自行Google
- [You Still Dont Know How to Do Unit Testing](https://stackify.com/unit-testing-basics-best-practices/)
- [Unit Testing Best Practices: JUnit Reference Guide](https://dzone.com/articles/unit-testing-best-practices)
- [JUnit Best Practices](http://www.kyleblaney.com/junit-best-practices/)
# 安全防范
在代码中没有最基本的安全漏洞问题也是我们程序员必须要保证的重要大事尤其是对外暴露Web服务的软件其安全性就更为重要了。对于在Web上经常出现的安全问题有必要介绍一下 [OWASP - Open Web Application Security Project](https://www.owasp.org/index.php/Main_Page)。
OWASP是一个开源的、非盈利的全球性安全组织致力于应用软件的安全研究。其被视为Web应用安全领域的权威参考。2009年国际信用卡数据安全技术PCI标准将其列为必要组件美国国防信息系统局、欧洲网络与信息安全局、美国国家安全局等政府机构所发布的美国国家和国际立法、标准、准则和行业实务守则参考引用了OWASP。
美国联邦贸易委员会FTC强烈建议所有企业需遵循OWASP十大Web弱点防护守则。所以对于[OWASP Top 10项目]([https://www.owasp.org/index.php/Category:OWASP_T](https://www.owasp.org/index.php/Category:OWASP_T) op_Ten_Project) 是程序员非常需要关注的最基本的也是最严重的安全问题,现在其已经成了一种标准,这里是其中文版《[OWASP Top 10 2017 PDF 中文版](https://www.owasp.org/images/d/dc/OWASP_Top_10_2017_%E4%B8%AD%E6%96%87%E7%89%88v1.3.pdf)》。
下面是安全编程方面的一些Guideline。
- [伯克立大学的Secure Coding Practice Guidelines](https://security.berkeley.edu/secure-coding-practice-guidelines)。
- [卡内基梅隆大学的 SEI CERT Coding Standards](https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards)。
此外有一篇和HTTP相关的安全文章也是每个程序员必须要读的——《[Hardening Your HTTP Security Headers](https://www.keycdn.com/blog/http-security-headers/)》。
最后想说的是&quot;防御性编程&quot;,英文叫[Defensive Programming](https://en.wikipedia.org/wiki/Defensive_programming),它是为了保证对程序的不可预见的使用,不会造成程序功能上的损坏。它可以被看作是为了减少或消除墨菲定律效力的想法。防御式编程主要用于可能被滥用,恶作剧或无意地造成灾难性影响的程序上。下面是一些文章。
- [The Art of Defensive Programming](https://medium.com/web-engineering-vox/the-art-of-defensive-programming-6789a9743ed4)。
- 当然,也别太过渡了,这篇文章可以看看,[Overly defensive programming](https://medium.com/@cvitullo/overly-defensive-programming-e7a1b3d234c2)。
# 软件工程和上线
系统上线是一件比较严肃的事,这表明你写的软件不是跑在自己的机器上的玩具,或是实验室里的实验品,而是交付给用户使用的,甚至是用户付费的软件。对于这样的软件或系统,我们需要遵守一些上线规范,比如,需要认真测试,并做上线前检查,以及上线后监控。下面是几个简单的规范,供你参考。
<li>
关于测试,推荐两本书。
<ul>
<li>
《[完美软件:对软件测试的各种幻想](https://book.douban.com/subject/4187479/)》,这本书重点讨论了与软件测试有关的各种心理问题及其表现与应对方法。作者首先阐述软件测试之所以如此困难的原因–人的思维不是完美的,而软件测试的最终目的就是发现对改善软件产品和软件开发过程有益的信息,故软件测试是一个信息获取的过程。
</li>
<li>
《[Google软件测试之道](https://book.douban.com/subject/25742200/)》描述了测试解决方案揭示了测试架构是如何设计、实现和运行的介绍了软件测试工程师的角色讲解了技术测试人员应该具有的技术技能阐述了测试工程师在产品生命周期中的职责讲述了测试管理并对在Google的测试历史上或者主要产品上发挥了重要作用的工程师的访谈这令那些试图建立类似Google的测试流程或团队的人受益很大。
</li>
当你的系统要上线时你是不是已经做好上线的准备了这里有两个Checklist供你做上线前的一些检查。
- [Server Side checklist](https://github.com/mtdvio/going-to-production/blob/master/serverside-checklist.md)
- [Single Page App Checklist](https://github.com/mtdvio/going-to-production/blob/master/spa-checklist.md)
《[Monitoring 101](https://www.datadoghq.com/blog/monitoring-101-collecting-data/)》这是一篇运维方面的入门文章,告诉你最基本的监控线上运行软件的方法和实践。
# 小结
好了,总结一下今天分享的主要内容。程序员修养看似与程序员练级关系不大,实际上却能反映出程序员的工程师特质和价值观,决定了这条路你到底能走多远。**有修养的程序员才可能成长为真正的工程师和架构师,而没有修养的程序员只能沦为码农**。
因此,在这篇文章中,我指出了我认为比较重要的几个方面:英文能力、问问题的能力、写代码的修养、安全防范意识、软件工程和上线规范等。这些能力的训练和培养将为后续的学习和发展夯实基础。
# 附录:编程规范
我们在写代码时,最好参考一些已有的最佳实践。为什么要有编程规范和最佳实践,要让所有人按一定的规范来编程呢?有下面几个主要原因。
- 可以让你的代码很规整,这有利于代码易读性,从而可以更容易地维护。
- 提升开发效率,我们知道,效率来自于结构化,而不是杂乱。
- 可以让你的软件避免一些容易掉坑的陷阱也让Bug更少质量更高。
- 可以让团队成员更高效率地协作。
如果一个程序员没有这类规范和最佳实践的沉淀,那么是很难成为真正的程序员,只能沦为码农。
当然对于一些代码风格方面的东西比如左大括号是否要换行缩进是用tab还是空格等等我觉得没有对错只要团队统一就好了。
下面,我罗列了一堆各种语言的编程规范,供你参考。
## 编程语言相关
**C语言**
- [NASA C Style](http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf)。
- [C Coding Standard](https://users.ece.cmu.edu/~eno/coding/CCodingStandard.html)。
- [C Programming/Structure and style](https://en.wikibooks.org/wiki/C_Programming/Structure_and_style)。
- [Linux kernel coding style](https://www.kernel.org/doc/html/latest/process/coding-style.html)。
- [GNU Coding Standard](https://www.gnu.org/prep/standards/html_node/Writing-C.html)GNU的编码规范。
**C++语言**
- [C++ Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)这个文档是各种C++的大拿包括原作者在内在持续讨论更新的和C++语言相关的各种最佳实践。
- [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)。
**Go语言**
- [Effective Go](https://golang.org/doc/effective_go.html) Go的语法不复杂所以Go语言的最佳实践只需要看这篇官方文档就够了。
**Java语言**
- [Code Conventions for the Java™ Programming Language](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html) Java官方的编程规范。
- [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)Google的Java编码规范。
**JavaScript语言**
- [JavaScript The Right Way](http://jstherightway.org) 一个相对比较容读的JavaScript编程规范其中不但有代码规范还有设计模式测试工具编程框架游戏引擎……
- [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)Google公司的JavaScript的编码规范一个非常大而全的编程规范。
- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)Airbnb的JavaScript编程规范。没Google的这么大而全但是也很丰富了。
- [jQuery Core Style Guide](http://contribute.jquery.org/style-guide/js/)jQuery的代码规范。
- [JavaScript Clean Code](https://github.com/ryanmcdermott/clean-code-javascript)前面推荐过的《代码整洁之道》一书中的JavaScript的实践 。
还有一些其它相对比较简单的JavaScript编程规范。
- [JavaScript Style Guides And Beautifiers](https://addyosmani.com/blog/javascript-style-guides-and-beautifiers/) 这是一篇推荐JavaScript编程规范的文章你可以看看。
- [JavaScript Style Guide and Coding Conventions](https://www.w3schools.com/js/js_conventions.asp)这是W3Schools的JavaScript。
- [Code Conventions for the JavaScript](http://crockford.com/javascript/code.html)。
**PHP语言**
- [PHP FIG](http://www.php-fig.org/psr/)PHP编码规范及标准推荐。
- [PHP The Right Way](http://www.phptherightway.com)除了编码规范之外的各种PHP的最佳实践还包括一些设计模式安全问题以及服务部署Docker虚拟化以及各种资源。
- [Clean Code PHP](https://github.com/jupeter/clean-code-php)《代码整洁之道》的PHP实践。
**Python语言**
- [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/)Python官方的编程码规范。
- [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)Google公司的Python编码规范。
- [The Hitchhikers Guide to Python](http://docs.python-guide.org/en/latest/)这不只是Python的编程规范还是Python资源的集散地强烈推荐。
**Ruby语言**
- [Ruby Style Guide](https://github.com/airbnb/ruby)Airbnb公司的Ruby编程规范。
- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) 。
**Rust语言**
- [Rust Style Guide](https://github.com/rust-lang-nursery/fmt-rfcs/blob/master/guide/guide.md)。
- [Rust Guidelines](http://aturon.github.io) 开源社区里最好的Rust编程规范。
**Scala语言**
- [Scala Style Guide](http://docs.scala-lang.org/style/)Scala官方的编程规范。
- [Databricks Scala Guide](https://github.com/databricks/scala-style-guide) - Databricks的Scala编程规范。
- [Scala Best Practices](https://github.com/alexandru/scala-best-practices)。
**Shell语言**
- [Google Shell Style Guide](https://google.github.io/styleguide/shell.xml)Google的Shell脚本编程规范。
**Node.js相关**
- [npm-coding-style](https://docs.npmjs.com/misc/coding-style)。
- [Microsoft + Node.js Guidelines](https://github.com/Microsoft/nodejs-guidelines)。
- [Node.js Style Guide](https://github.com/felixge/node-style-guide)。
**Mozilla的编程规范**
- [Mozilla Coding Style Guide](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style)其中包括C、C++、Java、Python、JavaScript、Makefile和SVG等编程规范。
## 前端开发相关
<li>
[CSS Guidelines](https://cssguidelin.es)CSS容易学但是不好写这篇规范会教你如何写出一个健全的、可管理的并可以扩展的CSS。
</li>
<li>
[Scalable and Modular Architecture for CSS](https://smacss.com/)这是一本教你如何写出可扩展和模块化的CSS的电子书非常不错。
</li>
<li>
[Frontend Guidelines](https://github.com/bendc/frontend-guidelines)一些和HTML、CSS、JavaScript相关的最佳实践。
</li>
<li>
[Sass Guidelines](https://sass-guidelin.es)Sass作为CSS的补充其要让CSS变得更容易扩展。然而也变得更灵活这意味着可以被更容易滥用。这里这篇&quot;富有主见&quot;的规范值得你一读。
</li>
<li>
[Airbnb CSS / Sass Styleguide](https://github.com/airbnb/css) Airbnb的CSS/Sass规范。
</li>
<li>
说了Sass就不得不说LESS这里有几篇和LESS相关的[LESS Coding Guidelines](https://gist.github.com/radermacher/f84b24af816111faf0ef)、[LESS Coding Guidelines](https://github.com/odoo/odoo/wiki/LESS-coding-guidelines)、[LESS coding standard](http://devdocs.magento.com/guides/v2.0/coding-standards/code-standard-less.html)。
</li>
<li>
[HTML Style Guide](https://github.com/marcobiedermann/html-style-guide)一个教你如何写出性能更高结构更好容易编程和扩展的HTML的规范。
</li>
<li>
[HTML + CSS Code Guide](http://codeguide.co)如何写出比较灵活、耐用、可持续改进的HTML和CSS的规范。
</li>
<li>
[CoffeeScript Style Guide](https://github.com/polarmobile/coffeescript-style-guide)CoffeeScript的最佳实践和编程规范。
</li>
<li>
[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html)Google的HTML/CSS的编程规范。
</li>
<li>
[Guidelines for Responsive Web Design](https://www.smashingmagazine.com/2011/01/guidelines-for-responsive-web-design/) 响应式Web设计的规范和最佳实践。
</li>
<li>
[U.S. Web Design Standards](https://standards.usa.gov)这是美国政府网端要求的一些UI交互可视化的一些规范。
</li>
最后是一个前端开发的各种注意事项列表,非常有用。
- [Front-End Checklist](https://github.com/thedaviddias/Front-End-Checklist) 一个前端开发的Checklist其中包括HTML、CSS和JavaScript还和图片、字体、SEO、性能相关还包括关一些和安全相关的事项这个列表真的是太好了。
## 移动端相关
**Kotlin**
- [Coding Conventions](https://kotlinlang.org/docs/reference/coding-conventions.html)。
**Objective-C语言**
<li>
[Objective-C Style guide](https://github.com/github/objective-c-style-guide)Style guide &amp; coding conventions for Objective-C projects。
</li>
<li>
[Google Objective-C Style Guide](https://google.github.io/styleguide/objcguide.xml)。
</li>
<li>
[NYTimes Objective-C Style Guide](https://github.com/NYTimes/objective-c-style-guide) The Objective-C Style Guide used by The New York Times。
</li>
**Swift语言**
- [API Design Guidelines](https://swift.org/documentation/api-design-guidelines/)。
- [Swift](https://github.com/github/swift-style-guide) - 一个Swift的相关编程规范的教程。
- [Swift style guide](https://github.com/raywenderlich/swift-style-guide)。
- [Swift Style Guide](https://github.com/linkedin/swift-style-guide) - LinkedIn的官方 Swift编程规范。
- [Metovas Swift style guide](https://github.com/metova/swift-style-guide)。
- [Xmartlabs Swift Style Guide](https://github.com/xmartlabs/Swift-Style-Guide)Xmartlabs的 Swift编程规范。
## API相关
- [HAL](http://stateless.co/hal_specification.html)一个简单的API规范教程。
- [Microsoft REST API Guidelines](https://github.com/Microsoft/api-guidelines)微软的Rest API规范。
- [API Design Guide](http://apiguide.readthedocs.io/en/latest/)。
- [RESTful API Designing guidelines-The best practices](https://hackernoon.com/restful-api-designing-guidelines-the-best-practices-60e1d954e7c9)。
- [JSON API - Recommendations](http://jsonapi.org/recommendations)JSON相关的API的一些推荐实践。
- [API Security Checklist](https://github.com/shieldfy/API-Security-Checklist) API的安全问题的检查列表。
## 开发工具相关
**Markdown相关**
- [Google Markdown Style Guide](https://github.com/google/styleguide/blob/gh-pages/docguide/style.md)。
- [Markdown Style Guide](http://www.cirosantilli.com/markdown-style-guide/)。
**JSON**
- [Google JSON Style Guide](https://google.github.io/styleguide/jsoncstyleguide.xml)。
- [JSON Style Guide](http://www.w3resource.com/slides/json-style-guide.php)。
**Git相关**
- [Git Style Guide](https://github.com/agis/git-style-guide)。
- [Few Rules from Git Documentation](https://github.com/git/git/blob/master/Documentation/CodingGuidelines)。
**正则表达式相关**
- [RegexHQ](https://github.com/regexhq)。
- [Learn regex the easy way](https://github.com/zeeshanu/learn-regex)。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,196 @@
<audio id="audio" title="73 | 程序员练级攻略:编程语言" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/88/74/884383b3b59c2e74e2a9dd46c5d59374.mp3"></audio>
为了进入专业的编程领域,我们需要认真学习以下三方面的知识。
**编程语言**。你需要学习C、C++和Java这三个工业级的编程语言。为什么说它们是工业级的呢主要是C和C++语言规范都由ISO标准化过而且都有工业界厂商组成的标准化委员会来制定工业标准。次要原因是它们已经在业界应用于许多重要的生产环境中。
<li>
C语言不用多说现今这个世界上几乎所有重要的软件都跟C有直接和间接的关系操作系统、网络、硬件驱动等等。说得霸气一点儿这个世界就是在C语言之上运行的。
</li>
<li>
而对于C++来说现在主流的浏览器、数据库、Microsoft Office、主流的图形界面、著名的游戏引擎等都是用C++编写的。而且很多公司都用C++开发核心架构如Google、腾讯、百度、阿里云等。
</li>
<li>
而金融电商公司则广泛地使用Java语言因为Java的好处太多了代码稳定性超过C和C++生产力远超C和C++。有JVM在可以轻松地跨平台做代码优化做AOP和IoC这样的高级技术。以Spring为首的由庞大的社区开发的高质量的各种轮子让你只需关注业务是能够快速搭建企业级应用的不二之选。
</li>
此外我推荐学习Go语言。一方面Go语言现在很受关注它是取代C和C++的另一门有潜力的语言。C语言太原始了C++太复杂了Java太高级了所以Go语言就在这个夹缝中出现了。这门语言已经10多年了其已成为云计算领域事实上的标准语言尤其是在Docker/Kubernetes等项目中。Go语言社区正在不断地从Java社区移植各种Java的轮子过来Go社区现在也很不错。
如果你要写一些PaaS层的应用Go语言会比C和C++更好目前和Java有一拼。而且Go语言在国内外一些知名公司中有了一定的应用和实践所以是可以学习的参看《[Go语言、Docker 和新技术](https://coolshell.cn/articles/18190.html)》一文。此外Go语言语法特别简单你有了C和C++的基础学习Go的学习成本基本为零。
**理论学科**。你需要学习像算法、数据结构、网络模型、计算机原理等计算机科学专业需要学习的知识。为什么要学好这些理论上的知识呢?
<li>
其一,这些理论知识可以说是计算机科学这门学科最精华的知识了。说得大一点,这些是人类智慧的精华。你只要想成为高手,这些东西是你必需要掌握和学习的。
</li>
<li>
其二当你在解决一些很复杂或是很难的问题时这些基础理论知识可以帮到你很多。我过去这20年从这些基础理论知识中受益匪浅。
</li>
<li>
其三,这些理论知识的思维方式可以让你有触类旁通,一通百通的感觉。虽然知识比较难啃,但啃过以后,你将获益终生。
</li>
另外,你千万不要觉得在你的日常工作或是生活当中根本用不上,学了也白学,这样的思维方式千万不要有,因为这是平庸的思维方式。如果你想等我用到了再学也不晚,那么你有必要看一下这篇文章《[程序员的荒谬之言还是至理名言?](https://coolshell.cn/articles/4235.html)》。
**系统知识**。系统知识是理论知识的工程实践这里面有很多很多的细节。比如像Unix/Linux、TCP/IP、C10K挑战等这样专业的系统知识。这些知识是你能不能把理论应用到实际项目当中能不能搞定实际问题的重要知识。
当你在编程的时候,如何和系统进行交互或是获取操作系统的资源,如何进行通讯,当系统出了性能问题,当系统出了故障等,你有大量需要落地的事需要处理和解决。这个时候,这些系统知识就会变得尤为关键和重要了。
这些东西你可以认为是计算机世界的物理世界上层无论怎么玩无论是Java NIO还是Nginx还是Node.js它们都逃脱不掉最下层的限制。所以你要好好学习这方面的知识。
# 编程语言
## Java语言
学习Java语言有以下**入门级的书**(注意:下面一些书在入门篇中有所提及,但为了完整性,还是要在这里提一下,因为可能有朋友是跳着看的)。
<li>
《[Java核心技术卷1基础知识](https://book.douban.com/subject/26880667/)》这本书本来是Sun公司的官方用书是一本Java的入门参考书。对于Java初学者来说是一本非常不错的值得时常翻阅的技术手册。书中有较多地方进行Java与C++的比较因为当时Java面世的时候又被叫作&quot;C++ Killer&quot;。而我在看这本书的时候发现书中有很多C++的东西于是又去学习了C++。学习C++的时候发现有很多C的东西不懂又顺着去学习了C。然后C -&gt; C++ -&gt; Java整条线融汇贯通这对我未来的技术成长有非常大的帮助。
</li>
<li>
有了上述的入门后Java的Spring框架是你玩Java所无法回避的东西所以接下来是两本Spring相关的书《[Spring实战](https://book.douban.com/subject/26767354/)》和《[Spring Boot实战](https://book.douban.com/subject/26857423/)》。前者是传统的Spring后者是新式的微服务的Spring。如果你只想看一本的话那么就看后者吧。
</li>
前面推荐的几本书可以帮你成功入门Java但想要进一步成长就要看下面我推荐的几本进阶级别的书了。
<li>
接下来,你需要了解了一下如何编写高效的代码,于是必需看一下《[Effective Java](https://book.douban.com/subject/27047716/)》注意这里我给的引用是第三版的也是2017年末出版的书这本书是模仿Scott Meyers的经典图书《Effective C++》的。Effective这种书基本上都是各种经验之谈所以这是一本非常不错的书你一定要读。这里需要推荐一下 [Google Guava 库](https://github.com/google/guava) 这个库不但是JDK的升级库其中有如集合collections、缓存caching、原生类型支持primitives support、并发库concurrency libraries、通用注解common annotations、字符串处理string processing、I/O 等库其还是Effective Java这本书中的那些经验的实践代表。
</li>
<li>
《[Java并发编程实战](https://book.douban.com/subject/10484692/)》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发介绍了如何使用类库提供的基本并发构建块用于避免并发危险、构造线程安全的类及验证线程安全的规则如何将小的线程安全类组合成更大的线程安全类如何利用线程来提高并发应用程序的吞吐量如何识别可并行执行的任务如何提高单线程子系统的响应性如何确保并发程序执行预期任务如何提高并发代码的性能和可伸缩性等内容。最后介绍了一些高级主题如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。
</li>
<li>
了解如何编写出并发的程序你还需要了解一下如何优化Java的性能。我推荐《[Java性能权威指南](https://book.douban.com/subject/26740520/)》。通过学习这本书你可以比较大程度地提升性能测试的效果。其中包括使用JDK中自带的工具收集Java应用的性能数据理解JIT编译器的优缺点调优JVM垃圾收集器以减少对程序的影响学习管理堆内存和JVM原生内存的方法了解如何最大程度地优化Java线程及同步的性能等等。看完这本书后如果你还有余力想了解更多的底层细节那么你有必要去读一下《[深入理解Java虚拟机](https://book.douban.com/subject/24722612/)》。
</li>
<li>
《[Java编程思想](https://book.douban.com/subject/2130190/)》真是一本透着编程思想的书。上面的书让你从微观角度了解Java而这本书则可以让你从一个宏观角度了解Java。这本书和Java核心技术的厚度差不多但这本书的信息密度比较大。所以读起来是非常耗大脑的因为它会让你不断地思考。对于想学好Java的程序员来说这是一本必读的书。
</li>
<li>
《[精通Spring 4.x](https://book.douban.com/subject/26952826/)》也是一本很不错的书就是有点厚一共有800多页都是干货。我认为其中最不错的是在分析原理尤其是针对前面提到的Spring技术应用与原理都讲得很透彻IOC和AOP也分析得很棒娓娓道来。其对任何一个技术都分析得很细致和全面不足之处就是内容太多了所以导致很厚但这并不影响它是一本不错的工具书。
</li>
当然学Java你一定要学面向对象的设计模式这里就只有一本经典的书《[设计模式](https://book.douban.com/subject/1052241/)》。如果你觉得有点儿难度了,那么可以看一下《[Head First设计模式](https://book.douban.com/subject/2243615/)》。学习面向对象的设计模式时你不要迷失在那23个设计模式中你一定要明白这两个原则
<li>
**Program to an interface, not an 'implementation**
<ul>
- 使用者不需要知道数据类型、结构、算法的细节。
- 使用者不需要知道实现细节,只需要知道提供的接口。
- 利于抽象、封装,动态绑定,多态。符合面向对象的特质和理念。
**Favor object composition over 'class inheritance**
- 继承需要给子类暴露一些父类的设计和实现细节。
- 父类实现的改变会造成子类也需要改变。
- 我们以为继承主要是为了代码重用,但实际上在子类中需要重新实现很多父类的方法。
- 继承更多的应该是为了多态。
至此如果你把上面的这些知识都融汇贯通的话那么你已是一个高级的Java程序员了我保证你已经超过了绝大多数程序员了。基本上来说你在技术方面是可以进入到一线公司的而且还不是一般的岗位至少是高级程序员或是初级架构师的级别了。
## C/C++语言
不像我出道那个时候几乎所有的软件都要用C语言来写。现在可能不会有多少人学习C语言了因为一方面有Java、Python这样的高级语言为你屏蔽了很多的底层细节另一方面也有像Go语言这样的新兴语言可以让你更容易地写出来也是高性能的软件。但是我还是想说C语言是你必须学习的语言因为这个世界上绝大多数编程语言都是C-like的语言也是在不同的方面来解决C语言的各种问题。**这里我想放个比较武断话——如果你不学C语言你根本没有资格说你是一个合格的程序员**
<li>
这里尤其推荐已故的C语言之父Dennis M. Ritchie和著名科学家Brian W. Kernighan合作的圣经级的教科书《[C程序设计语言](https://book.douban.com/subject/1139336/)》。注意这本书是C语言原作者写的其C语言的标准不是我们平时常说的ANSI标准而是原作者的标准又被叫作K&amp;R C。但是这本书很轻薄也简洁不枯燥是一本你可以拿着躺在床上看还不会看着看着睡着的书。
</li>
<li>
然后还有一本非常经典的C语言的书《[C语言程序设计现代方法](https://book.douban.com/subject/2280547/)》。有人说,这本书配合之前的 [The C Programming Language](https://en.wikipedia.org/wiki/The_C_Programming_Language) 那本书简真是无敌。我想说这本书更实用也够厚完整覆盖了C99标准习题的质量和水准也比较高。更好的是探讨了现代编译器的实现以及和C++的兼容还揭穿了各种古老的C语言的神话和信条……是相当相当干的一本学习C语言的书。
</li>
**对了千万不要看谭浩强的C语言的书。各种误导我大学时就是用这本书学的C后来工作时被坑得不行**
在学习C语言的过程中你一定会感到C语言这么底层而且代码经常性地崩溃经过一段时间的挣扎你才开始觉得你从这个烂泥坑里快要爬出来了。但你还需要看看《[C陷阱与缺陷](https://book.douban.com/subject/2778632/)》这本书,你会发现,这里面的坑不是一般大。
此时如果你看过我的《编程范式游记》那个系列文章你可能会发现C语言在泛型编程上的各种问题这个时候我推荐你学习一下C++语言。可能会有很多人觉得我说的C++是个大坑。是的,这是世界目前来说最复杂也是最难的编程语言了。但是,**C++是目前世界上范式最多的语言了,其做得最好的范式就是&quot;泛型编程&quot;,这在静态语言中,是绝对地划时代的一个事**。
所以你有必要学习一下C++看看C++是如何解决C语言中的各种问题的。你可以先看看我的这篇文章 “[C++的坑真的多吗?](https://coolshell.cn/articles/7992.html)” 有个基本认识。下面推荐几本C++的书。
<li>
《[C++ Primer中文版](https://book.douban.com/subject/25708312/)》这本书是久负盛名的C++经典教程。书是有点厚前面1/3讲C语言后面讲C++。C++的知识点实在是太多了而且又有点晦涩。但是你主要就看几个点一个是面向对象的多态一个是模板和重载操作符以及一些STL的东西。看看C++是怎么玩泛型和函数式编程的。
</li>
<li>
如果你想继续研究,你需要看另外两本更为经典的书《[Effective C++](https://book.douban.com/subject/5387403/)》和《[More Effective C++](https://book.douban.com/subject/5908727/)》。 这两本书不厚但是我读了10多年每过一段时间再读一下就会发现有更多的收获。这两本书的内容会随着你经历的丰富而变得丰富这也是对我影响最大的两本书其中影响最大的不是书中的那些C++的东西,而是作者的思维方式和不断求真的精神,这真是太赞了。
</li>
<li>
<p>学习C/C++都是需要好好了解一下编译器到底干了什么事的。就像Java需要了解JVM一样所以这里还有一本非常非常难啃的书你可以挑战一下《<a href="https://book.douban.com/subject/10427315/">深度探索C++对象模型<br />
</a>》。这本书是非常之经典的看完后C++对你来说就再也没有什么秘密可言。我以前写过的《[C++虚函数表解析](https://coolshell.cn/articles/12165.html)》,还有《[C++对象内存布局](https://coolshell.cn/articles/12176.html)》属于这个范畴。</p>
</li>
<li>
还有C++的作者 Bjarne Stroustrup 写的 [C++ FAQ](http://www.stroustrup.com/bs_faq.html) [中文版](http://www.stroustrup.com/bsfaqcn.html)),也是非常值得一读的。
</li>
## 学习Go语言
C语言太原始了C++太复杂了Go语言是不二之选。有了C/C++的功底学习Go语言非常简单。
首推 [Go by Example](https://gobyexample.com/) 作为你的入门教程。然后,[Go 101](https://go101.org/article/101.html) 也是一个很不错的在线电子书。如果你想看纸书的话,[The Go Programming Language](https://book.douban.com/subject/26337545/) 一书在豆瓣上有9.2分,但是国内没有卖的。(当然,我以前也写过两篇入门的供你参考 “[GO 语言简介(上)- 语法](https://coolshell.cn/articles/8460.html)” 和 “[GO 语言简介(下)- 特性](https://coolshell.cn/articles/8489.html)”)。
另外Go语言官方的 [Effective Go](https://golang.org/doc/effective_go.html) 是必读的这篇文章告诉你如何更好地使用Go语言以及Go语言中的一些原理。
Go 语言最突出之处是并发编程Unix老牌黑客罗勃·派克Rob Pike在 Google I/O上的两个分享可以让你学习到一些并发编程的模式。
- Go Concurrency Patterns [幻灯片](https://talks.golang.org/2012/concurrency.slide)和[演讲视频](https://www.youtube.com/watch?v=f6kdp27TYZs))。
- Advanced Go Concurrency Patterns[幻灯片](https://talks.golang.org/2013/advconc.slide)、[演讲视频](https://youtu.be/QDDwwePbDtw))。
然后Go在 GitHub的wiki上有好多不错的学习资源你可以从中学习到多。比如
- [Go精华文章列表](https://github.com/golang/go/wiki/Articles)。
- [Go相关博客列表](https://github.com/golang/go/wiki/Blogs)。
- [Go Talks](https://github.com/golang/go/wiki/GoTalks)。
此外还有个内容丰富的Go资源列表 [Awesome Go](https://github.com/avelino/awesome-go),推荐看看。
# 小结
好了最后我们来总结一些今天分享的内容。在编程语言方面我推荐学习C、C++、Java和Go四门语言并分别阐释了推荐的原因。
<li>
我认为C语言是必须学习的语言因为这个世界上绝大多数编程语言都是C-like的语言也是在不同的方面来解决C语言的各种问题。
</li>
<li>
而C++虽然复杂难学,但它几乎是目前世界上范式最多的语言了,其做得最好的范式就是&quot;泛型编程&quot;这在静态语言中是绝对地划时代的一个事。尤其要看看C++是如何解决C语言中的各种问题的。
</li>
<li>
Java是我认为综合能力最强的语言。其实我是先学了Java然后又去学了C++之后去学了C语言的。C -&gt; C++ -&gt; Java整条线融汇贯通这对我未来的技术成长有非常大的帮助。
</li>
<li>
在文章最末我推荐了Go语言并给出了相关的学习资料。
</li>
我认为,一个合格的程序员应该掌握几门语言。一方面,这会让你对不同的语言进行比较,让你有更多的思考。另一方面,这也是一种学习能力的培养,会让你对于未来的新技术学习得更快。
下篇文章中,我们将分享每个程序员都需要掌握的理论知识。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,107 @@
<audio id="audio" title="74 | 程序员练级攻略:理论学科" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ce/8e/ce478a62a9c0ea27e629c615a444068e.mp3"></audio>
进入专业的编程领域,算法、数据结构、网络模型、计算机原理等这样的计算机科学专业需要学习的理论知识是必须要学习的。下面我们先来看看数据结构和算法。
# 数据结构和算法
算法是比较难学习的,而且学习“算法”是需要智商的。数组、链表、哈希表、二叉树、排序算法等一些基础知识,对大多数人来说是没什么问题的。但是一旦进入到路径规划、背包问题、字符串匹配、动态规划、递归遍历等一些比较复杂的问题上,就会让很多人跟不上了,不但跟不上,而且还会非常痛苦。是的,解决算法问题的确是可以区分人类智商的一个比较好的方式,这也是为什么好些公司用算法题当面试题来找到智商比较高的程序员。
然而,在很多时候,我们在工作中却发现根本用不到算法,或是一些基本的算法也没有必要实现,只需要使用一下第三方的库就好了。于是,导致社会上出现很多“算法无用论”的声音。
对此我想说算法真的很重要。我这20年的经历告诉我无论是做业务还是做底层系统经常需要使用算法处理各种各样的问题。比如业务上我需要用算法比较两个数组中差异的布隆过滤器或是在做监控系统时实时计算过去一分钟的P99统计时的蓄水池算法或是数据库的B+树索引还有Linux内核中的epoll的红黑树还有在做服务调度里的“背包问题”等都会用算法真的是会本质上帮助到你也是会让你瞬间会产生成就感的事情。
虽然算法很难,需要智商,但我还是想鼓励你,这其中是有很多的套路是可以学习的,一旦学会这些套路,你会受益无穷的。
这里有几本书着重推荐一下。
<li>
**基础知识**。《[算法](https://book.douban.com/subject/10432347/)》是算法领域经典的参考书不但全面介绍了关于算法和数据结构的必备知识还给出了每位程序员应知应会的50个算法并提供了实际代码。最不错的是其深入浅出的算法介绍让一些比较难的算法也变得容易理解尤其是书中对红黑树的讲解非常精彩。其中还有大量的图解详尽的代码和讲解也许是最好的数据结构入门图书。不好的是不深缺乏进一步的算法设计内容甚至连动态规划都未提及。另外如果你觉得算法书比较枯燥的话你可以看看这本有趣的《[算法图解](https://book.douban.com/subject/26979890/)》。
</li>
<li>
**理论加持**。如果说上面这本书偏于实践和工程,而你看完后,对算法和数据结构的兴趣更浓了,那么你可以再看看另一本也是很经典的偏于理论方面的书——《[算法导论](https://book.douban.com/subject/20432061/)》。虽然其中的一些理论知识在《算法》那本书中也有提过,但《算法导论》这本书更为专业一些,是美国计算机科学本科生的教科书。
</li>
<li>
**思维改善**。还有一本叫《[编程珠玑](https://book.douban.com/subject/3227098/)》的书写这本书的人是世界著名计算机科学家乔恩·本特利Jon Bentley被誉为影响算法发展的十位大师之一。你可能不认识这个人但是你知道他的学生有多厉害吗我例举几个一个是Tcl语言设计者约翰·奥斯德奥特John Ousterhout另一个是Java语言设计者詹姆斯·高斯林James Gosling还有一个是《算法导论》作者之一查尔斯·雷斯尔森Charles Leiserson还有好多好多。这本书也是很经典的算法书其中都是一些非常实际的问题并以其独有的洞察力和创造力来引导读者理解并学会解决这些问题的方法也是一本可以改善你思维方式的书。
</li>
然后,你需要去做一些题来训练一下自己的算法能力,这里就要推荐 [LeetCode](https://leetcode.com/) 这个网站了。它是一个很不错的做算法训练的地方。现在也越做越好了。基本上来说,这里会有两类题。
<li>
**基础算法题**。其中有大量的算法题解这些题都是有套路的不是用递归深度优先DFS、广度优先BFS就是要用动态规划Dynamic Programming或是折半查找Binary Search或是回溯Back tracing或是分治法Divide and Conquer还有大量的对树、数组、链表、字符串和hash表的操作。通过做这些题能让你对这些最基础的算法的思路有非常扎实的了解和训练。对我而言Dynamic Programming是我的短板尤其是一些比较复杂的问题在推导递推公式上总是有思维的缺陷数学是我的硬伤。做了这些题后我能感到我在动态编程的思路上受到了很大的启发。
</li>
<li>
**编程题**。比如atoi、strstr、add two nums、括号匹配、字符串乘法、通配符匹配、文件路径简化、Text Justification、反转单词等这些题的Edge Case和Corner Case有很多。这些题需要你想清楚了再干只要你稍有疏忽就会有几个case让你痛不欲生而且一不小心就会让你的代码写得又臭又长无法阅读。通过做这些题可以非常好地训练你对各种情况的考虑以及你对程序代码组织的掌控其实就是其中的状态变量
</li>
我觉得每个程序员都应该花时间和精力做这些题因为你会从这些题中得到很大的收益。我在Leetcode上做的一些题的代码在这——我的 [GitHub](https://github.com/haoel/leetcode) 上,可以给你一些参考。
如果能够把这些算法能力都掌握了那么你就有很大的概率可以很容易地通过这世界上最优的公司的面试比如Google、Amazon、Facebook之类的公司。对你来说如果能够进入到这些公司里工作那么你未来的想像空间也会大很多。
最后,我们要知道这个世界上的数据结构和算法有很多,下面给出了两个网站。
- **[List of Algorithms](https://www.wikiwand.com/en/List_of_algorithms)** ,这个网站罗列了非常多的算法,完全可以当成一个算法字典,或是用来开阔眼界。
- 还有一个数据结构动画图的网站 [Data Structure Visualizations](https://www.cs.usfca.edu/~galles/visualization/Algorithms.html)。
# 其它理论基础知识
下面这些书,基本上是计算机科学系的大学教材。如果你想有科班出身的理论基础,那么这些书是必读的。当然,这些理论基础知识比较枯燥,但我觉得如果你想成为专业的程序员,那么应该要找时间读一下。
<li>
《[数据结构与算法分析](https://book.douban.com/subject/1139426/)》这本书曾被评为20世纪顶尖的30部计算机著作之一作者Mark Allen Weiss在数据结构和算法分析方面卓有建树他在数据结构和算法分析等方面的著作尤其畅销并广受好评已被世界500余所大学用作教材。
</li>
<li>
《[数据库系统概念](https://book.douban.com/subject/1929984/)》它是数据库系统方面的经典教材之一。国际上许多著名大学包括斯坦福大学、耶鲁大学、德克萨斯大学、康奈尔大学、伊利诺伊大学、印度理工学院等都采用本书作为教科书。这本书全面介绍了数据库系统的各种知识透彻阐释数据库管理的基本概念。不仅讨论了数据库查询语言、模式设计、数据仓库、数据库应用开发、基于对象的数据库和XML、数据存储和查询、事务管理、数据挖掘与信息检索以及数据库系统体系结构等方面的内容而且对性能评测标准、性能调整、标准化以及空间与地理数据、事务处理监控等高级应用主题进行了广泛讨论。
</li>
<li>
《[现代操作系统](https://book.douban.com/subject/3852290/)》,这本书是操作系统领域的经典之作,书中集中讨论了操作系统的基本原理,包括进程、线程、存储管理、文件系统、输入/输出、死锁等,同时还包含了有关计算机安全、多媒体操作系统、掌上计算机操作系统、微内核、多核处理机上的虚拟机以及操作系统设计等方面的内容。
</li>
<li>
《[计算机网络](https://book.douban.com/subject/1391207/)》这本书采用了独创的自顶向下方法即从应用层开始沿协议栈向下讲解计算机网络的基本原理强调应用层范例和应用编程接口内容深入浅出注重教学方法理论与实践相结合。新版中还增加了无线和移动网络一章并扩充了对等网络、BGP、MPLS、网络安全、广播选路和因特网编址及转发方面的材料。是一本不可多得的教科书。
</li>
<li>
《[计算机程序的构造和解释](https://book.douban.com/subject/1148282/)》这本书也很经典是MIT的计算机科学系的教材。这本书中主要证实了很多程序是怎么构造出来的以及程序的本质是什么。整本书主要是使用Scheme/Lisp语言从数据抽象、过程抽象、迭代、高阶函数等编程和控制系统复杂性的思想到数据结构和算法到编译器/解释器、编程语言设计。
</li>
<li>
《[编译原理](https://book.douban.com/subject/3296317/)》,这本书又叫&quot;龙书&quot;,其全面、深入地探讨了编译器设计方面的重要主题,包括词法分析、语法分析、语法制导定义和语法制导翻译、运行时刻环境、目标代码生成、代码优化技术、并行性检测以及过程间分析技术,并在相关章节中给出大量的实例。与上一版相比,本书进行了全面的修订,涵盖了编译器开发方面的最新进展。每章中都提供了大量的系统及参考文献。
</li>
# 小结
好了,最后我们来总结一些今天分享的内容。在这篇文章中,我建议想进入专业编程领域的人,一定要学习算法、数据结构、网络模型、计算机原理等理论知识,并推荐了相应的学习素材,给出了我的思考和建议。
我认为,虽然这些理论知识枯燥难学,而且通常学完了在工作中也并不是马上就能用上,但这些知识是必须要学好的。**这些理论知识可以说是计算机科学这门学科最精华的知识了,认真学习,理解其背后的逻辑和思维方式,会让你受益匪浅**。不管是未来你是要学习新技能,还是解决什么疑难问题,都能在这些知识中获得灵感或者启发。
下篇文章中,我们将分享每个程序员都需要掌握的系统知识。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,151 @@
<audio id="audio" title="75 | 程序员练级攻略:系统知识" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/35/95/35c7452d37fd0cdaf99098879ecb5095.mp3"></audio>
进入专业的编程领域,学习系统知识是非常关键的一部分。
首先推荐的是翻译版图书《[深入理解计算机系统](https://book.douban.com/subject/5333562/)》原书名为《Computer Systems A Programmers Perspective》。不过这本书叫做《程序员所需要了解的计算机知识》更为合适。
本书的最大优点是为程序员描述计算机系统的实现细节,帮助其在大脑中构造一个层次型的计算机系统。从最底层的数据在内存中的表示到流水线指令的构成,到虚拟存储器,到编译系统,到动态加载库,到最后的用户态应用。通过掌握程序是如何映射到系统上,以及程序是如何执行的,你能够更好地理解程序的行为为什么是这样的,以及效率低下是如何造成的。
**再强调一下,这本书是程序员必读的一本书!**
然后就是美国计算机科学家 [理查德·史蒂文斯Richard Stevens](https://zh.wikipedia.org/wiki/%E7%90%86%E6%9F%A5%E5%BE%B7%C2%B7%E5%8F%B2%E8%92%82%E6%96%87%E6%96%AF) 的三套巨经典无比的书。理查德·史蒂文斯于1999年9月1日离世终年48岁。死因不详有人说是滑雪意外有人说是攀岩意外有人说是滑翔机意外。总之家人没有透露。大师的 [个人主页](http://www.kohala.com/start/) 今天还可以访问。)
- 《[Unix高级环境编程](https://book.douban.com/subject/1788421/)》。
- 《Unix网络编程》 [第1卷 套接口API](https://book.douban.com/subject/1500149/) 、[第2卷 进程间通信](https://book.douban.com/subject/4118577/) 。
- 《[TCP/IP详解 卷I 协议](https://book.douban.com/subject/1088054/)》。
这几本书的地位我就不多说了,你可以自己看相关的书评。但是,这三本书可能都不容易读,一方面是比较厚,另一方面是知识的密度太大了,所以,读起来有点枯燥和乏味。但是,这没办法,你得忍住。
这里要重点说一下《TCP/IP详解》这本书是一本很奇怪的书。这本书迄今至少被 [近五百篇学术论文引用过](http://portal.acm.org/citation.cfm?id=161724) 。这本写给工程师看的书居然被各种学院派的论文来引用也是很神奇的一件事了。而且虽然理查德·史蒂文斯不是TCP的发明人但是这本书中把这个协议深入浅出地讲出来还画了几百张时序图也是令人叹为观止了。
如果你觉得上面这几本经典书比较难啃,你可以试试下面这些通俗易懂的(当然,如果读得懂上面那三本的,下面的这些也就不需要读了)。
- 《[Linux C编程一站式学习](https://book.douban.com/subject/4141733/)》。
- 《[TCP/IP网络编程](https://book.douban.com/subject/25911735/)》。
- 《[图解TCP/IP](https://book.douban.com/subject/24737674/)》这本书其实并不是只讲了TCP/IP应该是叫《计算机网络》才对主要是给想快速入门的人看的。
- 《[The TCP/IP Guide](http://www.tcpipguide.com/free/index.htm)》这本书在豆瓣上的评分9.2这里给的链接是这本书的HTML英文免费版的里面的图画得很精彩。
另外,学习网络协议不单只是看书,你最好用个抓包工具看看这些网络包是什么样的。所以,这里推荐一本书《[Wireshark数据包分析实战](https://book.douban.com/subject/21691692/)》。在这本书中作者结合一些简单易懂的实际网络案例图文并茂地演示使用Wireshark进行数据包分析的技术方法可以让我们更好地了解和学习网络协议。当然也拥有了一定的黑客的技能。
看完《Unix高级环境编程》后你可以趁热打铁看看《[Linux/Unix系统编程手册](https://book.douban.com/subject/25809330/)》或是罗伯特·拉姆Robert Love的 [Linux System Programming 英文电子版](http://igm.univ-mlv.fr/~yahya/progsys/linux.pdf) 。其中文翻译版[Linux系统编程](https://book.douban.com/subject/25828773/) 也值得一读虽然和《Unix高级环境编程》很像不过其主要突出的是Linux的一些关键技术和相关的系统调用。
关于TCP的东西你还可以看看下面这一系列的文章。
- [Lets code a TCP/IP stack, 1: Ethernet &amp; ARP](http://www.saminiir.com/lets-code-tcp-ip-stack-1-ethernet-arp/)
- [Lets code a TCP/IP stack, 2: IPv4 &amp; ICMPv4](http://www.saminiir.com/lets-code-tcp-ip-stack-2-ipv4-icmpv4/)
- [Lets code a TCP/IP stack, 3: TCP Basics &amp; Handshake](http://www.saminiir.com/lets-code-tcp-ip-stack-3-tcp-handshake/)
- [Lets code a TCP/IP stack, 4: TCP Data Flow &amp; Socket API](http://www.saminiir.com/lets-code-tcp-ip-stack-4-tcp-data-flow-socket-api/)
- [Lets code a TCP/IP stack, 5: TCP Retransmission](http://www.saminiir.com/lets-code-tcp-ip-stack-5-tcp-retransmission/)
**对于系统知识,我认为主要有以下一些学习要点。**
- 用这些系统知识操作一下文件系统,实现一个可以拷贝目录树的小程序。
- 用fork / wait / waitpid写一个多进程的程序用pthread写一个多线程带同步或互斥的程序。比如多进程购票的程序。
- 用signal / kill / raise / alarm / pause / sigprocmask实现一个多进程间的信号量通信的程序。
- 学会使用gcc和gdb来编程和调试程序参看我的《**用gdb调试程序**》[](https://blog.csdn.net/haoel/article/details/2879)、[](https://blog.csdn.net/haoel/article/details/2880)、[](https://blog.csdn.net/haoel/article/details/2881)、[](https://blog.csdn.net/haoel/article/details/2882)、[](https://blog.csdn.net/haoel/article/details/2883)、[](https://blog.csdn.net/haoel/article/details/2884)、[](https://blog.csdn.net/haoel/article/details/2885))。
- 学会使用makefile来编译程序参看我的《**跟我一起写makefile**》[](https://blog.csdn.net/haoel/article/details/2886)、[](https://blog.csdn.net/haoel/article/details/2887)、[](https://blog.csdn.net/haoel/article/details/2888)、[](https://blog.csdn.net/haoel/article/details/2889)、[](https://blog.csdn.net/haoel/article/details/2890)、[](https://blog.csdn.net/haoel/article/details/2891)、[](https://blog.csdn.net/haoel/article/details/2892)、[](https://blog.csdn.net/haoel/article/details/2893)、[](https://blog.csdn.net/haoel/article/details/2894)、[](https://blog.csdn.net/haoel/article/details/2895)、[十一](https://blog.csdn.net/haoel/article/details/2896)、[十二](https://blog.csdn.net/haoel/article/details/2897)、[十三](https://blog.csdn.net/haoel/article/details/2898)、[十四](https://blog.csdn.net/haoel/article/details/2899))。
- Socket的进程间通信。用C语言写一个1对1的聊天小程序或是一个简单的HTTP服务器。
# C10K 问题
然后当你读完《Unix网络编程》后千万要去读一下 “[C10K Problem](http://www.kegel.com/c10k.html) [中文翻译版](https://www.oschina.net/translate/c10k)”。提出这个问题的人叫丹·凯格尔Dan Kegel目前在Google任职。
他从1978年起开始接触计算机编程是Winetricks的作者也是Wine 1.0的管理员同时也是Crosstool 一个让 gcc/glibc 编译器更易用的工具套件的作者。还是Java JSR 51规范的提交者并参与编写了Java平台的NIO和文件锁同时参与了RFC 5128标准中有关NAT穿越P2P打洞技术的描述和定义。
C10K问题本质上是**操作系统处理大并发请求的问题**。对于Web时代的操作系统而言对于客户端过来的大量的并发请求需要创建相应的服务进程或线程。这些进程或线程多了导致数据拷贝频繁缓存I/O、内核将数据拷贝到用户进程空间、阻塞 进程/线程上下文切换消耗大从而导致资源被耗尽而崩溃。这就是C10K问题的本质。
了解这个问题并了解操作系统是如何通过多路复用的技术来解决这个问题的有助于你了解各种I/O和异步模型这对于你未来的编程和架构能力是相当重要的。
另外现在整个世界都在解决C10M问题推荐看看 [The Secret To 10 Million Concurrent Connections -The Kernel Is The Problem, Not The Solution](http://highscalability.com/blog/2013/5/13/the-secret-to-10-million-concurrent-connections-the-kernel-i.html) 一文。
# 实践项目
我们已经学习完了编程语言、理论学科和系统知识三部分内容下面就来做几个实践项目小试牛刀一下。实现语言可以用C、C++或Java。
实现一个telnet版本的聊天服务器主要有以下需求。
- 每个客户端可以用使用`telnet ip:port`的方式连接到服务器上。
- 新连接需要用用户名和密码登录,如果没有,则需要注册一个。
- 然后可以选择一个聊天室加入聊天。
- 管理员有权创建或删除聊天室,普通人员只有加入、退出、查询聊天室的权力。
- 聊天室需要有人数限制,每个人发出来的话,其它所有的人都要能看得到。
实现一个简单的HTTP服务器主要有以下需求。
- 解释浏览器传来的HTTP协议只需要处理URL path。
- 然后把所代理的目录列出来。
- 在浏览器上可以浏览目录里的文件和下级目录。
- 如果点击文件则把文件打开传给浏览器浏览器能够自动显示图片、PDF或HTML、CSS、JavaScript以及文本文件
- 如果点击子目录,则进入到子目录中,并把子目录中的文件列出来。
实现一个生产者/消费者消息队列服务,主要有以下需求。
- 消息队列采用一个Ring-buffer的数据结构。
- 可以有多个topic供生产者写入消息及消费者取出消息。
- 需要支持多个生产者并发写。
- 需要支持多个消费者消费消息(只要有一个消费者成功处理消息就可以删除消息)。
- 消息队列要做到不丢数据(要把消息持久化下来)。
- 能做到性能很高。
# 小结
到今天我们已经学习完了专业编程方面最为重要的三部分内容编程语言、理论学科和系统知识我们针对这些内容做个小结。如果想看完我推荐的那些书和知识并能理解和掌握我估计怎么也得需要4-5年的时间。嗯是的就是一个计算机科学系科班出身的程序员需要学习的一些东西。这其中最重要的是下面这几点。
**编程语言**。以工业级的C、C++、Java这三门语言为主这三门语言才是真正算得上工业级的编程语言因为有工业级的标准化组织在控制着这几门语言而且也有工业级的企业应用。尤其是Java还衍生出了大量的企业级架构上的开源生态。你至少需要掌握C语言和Java语言这对你以后面对各式各样的编程语言是非常重要的。
此外还推荐学习Go语言它已成为云计算领域事实上的标准语言尤其是在Docker、Kubernetes等项目中。而且Go语言在国内外一些知名公司中有了一定的应用和实践并且其生态圈也越来越好。
**算法和数据结构**。这个太重要了,尤其是最基础的算法和数据结构,这是任何一个称职的程序员都需要学习和掌握的。你必需要掌握。
**计算机的相关系统**。你至少要掌握三个系统的基础知识,一个是操作系统,一个是网络系统,还有一个是数据库系统。它们分别代表着计算机基础构架的三大件——计算、存储、网络。
如果你能够走到这里,把前面的那些知识都了解了(不用精通,因为精通是需要时间和实践来慢慢锤炼出来的,所以,你也不用着急),那么你已经是一个合格的程序员了,而且你的潜力和可能性是非常非常高的。
如果经历过这些比较枯燥的理论知识而且你还能有热情和成就感那么我要恭喜你了。因为你已经超过了绝大多数人而且还是排在上游的比较抢手的程序员了。我相信你至少可以找到年薪50万以上的工作了。
但是,你还需要很多的经验或是一些实践,以及一些大系统大项目的实际动手的经验。没关系,我们后面会有教你怎么实操的方法和攻略。
但是,往后面走,你需要开始需要术业有专攻了。下面给一些建议的方向。
- **底层方向**:操作系统、文件系统、数据库、网络……
- **架构方向**分布式系统架构、微服务、DevOps、Cloud Native……
- **数据方向**:大数据、机器学习、人工智能……
- **前端方向**:你对用户体验或是交互更感兴趣,那么你走前端的路吧。
- **其它方向**:比如,安全开发、运维开发、嵌入式开发……
这些方向你要仔细选择,因为一旦选好,就要勇往直前地走下去,当然,你要回头转别的方向也没什么问题,因为你有前面的这些基础知识在身,所以,不用害怕。只是不同的方向上会有不同的经验积累,经验积累是看书看不来的,这个是转方向的成本。
下篇文章,我们将进入《软件设计篇》。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,206 @@
<audio id="audio" title="76 | 程序员练级攻略:软件设计" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/34/55/34c9b25b3ca11eeb5f1f74fbfbeecc55.mp3"></audio>
学习软件设计的方法、理念、范式和模式,是让你从一个程序员通向工程师的必备技能。如果你不懂这些设计方法,那么你将无法做出优质的软件。这就好像写作文一样,文章人人都能写,但是能写得有条理,有章法,有血有肉,就不简单了。软件开发也一样,实现功能,做出来并不难,但是要做漂亮,做优雅,就非常不容易了。
Linus说过这世界程序员之所有高下之分最大的区别就是程序员的“品味”不一样。有品位的程序员和没有品位的程序员写出来的代码做出来的软件差距非常大。**所以,如果你想成为一名优秀的程序员,软件设计定是你的必修课**。
然而,软件设计这个事,并不是一朝一夕就能学会的,也不是别人能把你教会的,很多东西需要你自己用实践、用时间、用错误、用教训、用痛苦才能真正体会其中的精髓。所以,除了学习理论知识外,你还需要大量的工程实践,然后每过一段时间就把这些设计的东西重新回炉一下。你会发现这些软件设计的东西,就像饮茶一样,一开始是苦的,然后慢慢回甘,最终你会喝出真正的滋味。
**要学好这些软件开发和设计的方法,你真的需要磨练和苦行,反复咀嚼,反复推敲,在实践和理论中螺旋式地学习,才能真正掌握。** 所以,你需要有足够的耐心和恒心。
# 编程范式
学习编程范式可以让你明白编程的本质和各种语言的编程方式。因此,我推荐以下一些资料,以帮助你系统化地学习和理解。
<li>
一个是我在极客时间写的《编程范式游记》系列文章,目录如下。
<ul>
- [编程范式游记1- 起源](https://time.geekbang.org/column/article/301)
- [编程范式游记2- 泛型编程](https://time.geekbang.org/column/article/303)
- [编程范式游记3- 类型系统和泛型的本质](https://time.geekbang.org/column/article/2017)
- [编程范式游记4- 函数式编程](https://time.geekbang.org/column/article/2711)
- [编程范式游记5- 修饰器模式](https://time.geekbang.org/column/article/2723)
- [编程范式游记6- 面向对象编程](https://time.geekbang.org/column/article/2729)
- [编程范式游记7- 基于原型的编程范式](https://time.geekbang.org/column/article/2741)
- [编程范式游记8- Go 语言的委托模式](https://time.geekbang.org/column/article/2748)
- [编程范式游记9- 编程的本质](https://time.geekbang.org/column/article/2751)
- [编程范式游记10- 逻辑编程范式](https://time.geekbang.org/column/article/2752)
- [编程范式游记11- 程序世界里的编程范式](https://time.geekbang.org/column/article/2754)
[Wikipedia: Programming paradigm](https://en.wikipedia.org/wiki/Programming_paradigm) ,维基百科上有一个编程范式的页面,顺着这个页面看下去,你可以看到很多很多有用的和编程相关的知识。这些东西对你的编程技能的提高会非常非常有帮助。
[Six programming paradigms that will change how you think about coding](https://www.ybrikman.com/writing/2014/04/09/six-programming-paradigms-that-will/),中文翻译版为 [六个编程范型将改变你对编程的看法](https://my.oschina.net/editorial-story/blog/890965)。这篇文章讲了默认支持并发Concurrent by default、依赖类型Dependent types、连接性语言Concatenative languages、声明式编程Declarative programming、符号式编程Symbolic programming、基于知识的编程Knowledge-based programming等六种不太常见的编程范式并结合了一些你没怎么听说过的语言来分别进行讲述。
比如在讲Concatenative languages时以Forth、cat和joy三种语言为例讲述这一编程范式背后的思想——语言中的所有内容都是一个函数用于将数据推送到堆栈或从堆栈弹出数据程序几乎完全通过功能组合来构建concatenation is composition。作者认为这些编程范式背后的思想十分有魅力能够改变对编程的思考。我看完此文对此也深信不疑。虽然这些语言和编程范式不常用到但确实能在思想层面给予人很大的启发。这也是我推荐此文的目的。
[Programming Paradigms for Dummies: What Every Programmer Should Know](https://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf) 这篇文章的作者彼得·范·罗伊Peter Van Roy是比利时鲁汶大学的计算机科学教师。他在这篇文章里分析了编程语言在历史上的演进有哪些典型的、值得研究的案例里面体现了哪些值得学习的范式。
比如在分布式编程领域他提到了Erlang、E、Distributed Oz和Didactic Oz这四种编程语言。虽然它们都是分布式编程语言但各有特色各自解决了不同的问题。通过这篇文章能学到不少在设计编程语言时要考虑的问题让你重新审视自己所使用的编程语言应该怎样用才能用好有什么局限性这些局限性能否被克服等。
[斯坦福大学公开课:编程范式](http://open.163.com/special/opencourse/paradigms.html)这是一门比较基础且很详细的课程适合学习编程语言的初学者。它通过讲述C、C++、并发编程、Scheme、Python这5门语言介绍了它们各自不同的编程范式。以C语言为例它解释了C语言的基本要素如指针、内存分配、堆、C风格的字符串等并解释了为什么C语言会在泛型编程、多态等方面有局限性。通过学习这门课程你会对一些常用的编程范式有所了解。
# 一些软件设计的相关原则
<li>
**[Dont Repeat Yourself (DRY) ](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)** DRY是一个最简单的法则也是最容易被理解的。但它也可能是最难被应用的因为要做到这样我们需要在泛型设计上做相当的努力这并不是一件容易的事。它意味着当在两个或多个地方发现一些相似代码的时候我们需要把它们的共性抽象出来形成一个唯一的新方法并且改变现有地方的代码让它们以一些合适的参数调用这个新的方法。
</li>
<li>
**[Keep It Simple, Stupid(KISS)](http://en.wikipedia.org/wiki/KISS_principle)** KISS原则在设计上可能最被推崇在家装设计、界面设计和操作设计上复杂的东西越来越被众人所鄙视了而简单的东西越来越被人所认可。宜家IKEA简约、高效的家居设计和生产思路微软Microsoft“所见即所得”的理念谷歌Google简约、直接的商业风格无一例外地遵循了“KISS”原则。也正是“KISS”原则成就了这些看似神奇的商业经典。而苹果公司的iPhone和iPad将这个原则实践到了极至。
</li>
<li>
**Program to an interface, not an implementation**这是设计模式中最根本的哲学注重接口而不是实现依赖接口而不是实现。接口是抽象是稳定的实现则是多种多样的。在面向对象的S.O.L.I.D原则中会提到我们的依赖倒置原则就是这个原则的另一种样子。还有一条原则叫 Composition over inheritance喜欢组合而不是继承这两条是那23个经典设计模式中的设计原则。
</li>
<li>
**[You Aint Gonna Need It (YAGNI)](http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It)** 这个原则简而言之为——只考虑和设计必须的功能避免过度设计。只实现目前需要的功能在以后你需要更多功能时可以再进行添加。如无必要勿增复杂性。软件开发是一场trade-off的博弈。
</li>
<li>
**[Law of Demeter](http://en.wikipedia.org/wiki/Principle_of_Least_Knowledge)**,迪米特法则(Law of Demeter)又称“最少知识原则”Principle of Least Knowledge其来源于1987年荷兰大学的一个叫做Demeter的项目。克雷格·拉尔曼Craig Larman把Law of Demeter又称作“不要和陌生人说话”。在《程序员修炼之道》中讲LoD的那一章将其叫作“解耦合与迪米特法则”。
关于迪米特法则有一些很形象的比喻1) 如果你想让你的狗跑的话你会对狗狗说还是对四条狗腿说2) 如果你去店里买东西你会把钱交给店员还是会把钱包交给店员让他自己拿和狗的四肢说话让店员自己从钱包里拿钱这听起来有点儿荒唐不过在我们的代码里这几乎是见怪不怪的事情了。对于LoD正式的表述如下
对于对象 O 中一个方法MM应该只能够访问以下对象中的方法
<ol>
- 对象O
- 与O直接相关的Component Object
- 由方法M创建或者实例化的对象
- 作为方法M的参数的对象。
</ol>
</li>
<li>
**[面向对象的S.O.L.I.D 原则](&lt;a href=)"&gt;http://en.wikipedia.org/wiki/Solid_(object-oriented_design)**
<ul>
- **SRPSingle Responsibility Principle- 职责单一原则**。关于单一职责原则,其核心的思想是:一个类,只做一件事,并把这件事做好,其只有一个引起它变化的原因。单一职责原则可以看作是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。
职责过多,可能引起它变化的原因就越多,这将导致职责依赖,相互之间就产生影响,从而极大地损伤其内聚性和耦合度。单一职责,通常意味着单一的功能,因此不要为一个模块实现过多的功能点,以保证实体只有一个引起它变化的原因。
<li>
** OCPOpen/Closed Principle- 开闭原则**。关于开发封闭原则,其核心的思想是:模块是可扩展的,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。
</li>
<li>
**LSPLiskov substitution principle- 里氏代换原则**。软件工程大师罗伯特·马丁Robert C. Martin把里氏代换原则最终简化为一句话“Subtypes must be substitutable for their base types”。也就是子类必须能够替换成它们的基类。即子类应该可以替换任何基类能够出现的地方并且经过替换以后代码还能正常工作。另外不应该在代码中出现if/else之类对子类类型进行判断的条件。里氏替换原则LSP是使代码符合开闭原则的一个重要保证。正是由于子类型的可替换性才使得父类型的模块在无需修改的情况下就可以扩展。
</li>
<li>
**ISPInterface Segregation Principle - 接口隔离原则**。接口隔离原则的意思是把功能实现在接口中,而不是类中,使用多个专门的接口比使用单一的总接口要好。举个例子,我们对电脑有不同的使用方式,比如:写作、通讯、看电影、打游戏、上网、编程、计算和数据存储等。
</li>
如果我们把这些功能都声明在电脑的抽象类里面那么我们的上网本、PC机、服务器和笔记本的实现类都要实现所有的这些接口这就显得太复杂了。所以我们可以把这些功能接口隔离开来如工作学习接口、编程开发接口、上网娱乐接口、计算和数据服务接口这样我们的不同功能的电脑就可以有所选择地继承这些接口。
- **DIPDependency Inversion Principle- 依赖倒置原则**。高层模块不应该依赖于低层模块的实现,而是依赖于高层抽象。举个例子,墙面的开关不应该依赖于电灯的开关实现,而是应该依赖于一个抽象的开关的标准接口。这样,当我们扩展程序的时候,开关同样可以控制其它不同的灯,甚至不同的电器。也就是说,电灯和其它电器继承并实现我们的标准开关接口,而开关厂商就可以不需要关于其要控制什么样的设备,只需要关心那个标准的开关标准。这就是依赖倒置原则。
[CCPCommon Closure Principle - 共同封闭原则](http://c2.com/cgi/wiki?CommonClosurePrinciple),一个包中所有的类应该对同一种类型的变化关闭。一个变化影响一个包,便影响了包中所有的类。一个更简短的说法是:一起修改的类,应该组合在一起(同一个包里)。如果必须修改应用程序里的代码,那么我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。
CCP原则就是把因为某个同样的原因而需要修改的所有类组合进一个包里。如果两个类从物理上或者从概念上联系得非常紧密它们通常一起发生改变那么它们应该属于同一个包。CCP延伸了开闭原则OCP的“关闭”概念当因为某个原因需要修改时把需要修改的范围限制在一个最小范围内的包里。
[CRPCommon Reuse Principle- 共同重用原则](http://c2.com/cgi/wiki?CommonReusePrinciple) 包的所有类被一起重用。如果你重用了其中的一个类就重用全部。换个说法是没有被一起重用的类不应该组合在一起。CRP原则帮助我们决定哪些类应该被放到同一个包里。依赖一个包就是依赖这个包所包含的一切。
当一个包发生了改变并发布新的版本使用这个包的所有用户都必须在新的包环境下验证他们的工作即使被他们使用的部分没有发生任何改变。因为如果包中包含未被使用的类即使用户不关心该类是否改变但用户还是不得不升级该包并对原来的功能加以重新测试。CCP则让系统的维护者受益。CCP让包尽可能大CCP原则加入功能相关的类CRP则让包尽可能小CRP原则剔除不使用的类。它们的出发点不一样但不相互冲突。
[好莱坞原则 - Hollywood Principle](http://en.wikipedia.org/wiki/Hollywood_Principle) 好莱坞原则就是一句话——“dont call us, well call you.”。意思是,好莱坞的经纪人不希望你去联系他们,而是他们会在需要的时候来联系你。也就是说,所有的组件都是被动的,所有的组件初始化和调用都由容器负责。
简单来讲就是由容器控制程序之间的关系而非传统实现中由程序代码直接操控。这也就是所谓“控制反转”的概念所在1) 不创建对象而是描述创建对象的方式。2在代码中对象与服务没有直接联系而是容器负责将这些联系在一起。控制权由应用代码中转到了外部容器控制权的转移是所谓反转。好莱坞原则就是[IoCInversion of Control](http://en.wikipedia.org/wiki/Inversion_of_Control) 或[DIDependency Injection](https://martinfowler.com/articles/injection.html)的基础原则。
[高内聚, 低耦合&amp; - High Cohesion &amp; Low/Loose coupling](http://en.wikipedia.org/wiki/Coupling_(computer_science))这个原则是UNIX操作系统设计的经典原则把模块间的耦合降到最低而努力让一个模块做到精益求精。内聚指一个模块内各个元素彼此结合的紧密程度耦合指一个软件结构内不同模块之间互连程度的度量。内聚意味着重用和独立耦合意味着多米诺效应牵一发动全身。对于面向对象来说你也可以看看马萨诸塞州戈登学院的面向对象课中的这一节讲义[High Cohesion and Low Coupling](http://www.math-cs.gordon.edu/courses/cs211/lectures-2009/Cohesion,Coupling,MVC.pdf)。
[CoCConvention over Configuration- 惯例优于配置原则](http://en.wikipedia.org/wiki/Convention_over_Configuration) 简单点说就是将一些公认的配置方式和信息作为内部缺省的规则来使用。例如Hibernate的映射文件如果约定字段名和类属性一致的话基本上就可以不要这个配置文件了。你的应用只需要指定不convention的信息即可从而减少了大量convention而又不得不花时间和精力啰里啰嗦的东东。
配置文件在很多时候相当影响开发效率。Rails 中很少有配置文件但不是没有数据库连接就是一个配置文件。Rails 的fans号称其开发效率是 Java 开发的 10 倍估计就是这个原因。Maven也使用了CoC原则当你执行 `mvn -compile` 命令的时候不需要指定源文件放在什么地方而编译以后的class文件放置在什么地方也没有指定这就是CoC原则。
[SoC (Separation of Concerns) - 关注点分离](http://sulong.me/archives/99) SoC 是计算机科学中最重要的努力目标之一。这个原则,就是在软件开发中,通过各种手段,将问题的各个关注点分开。如果一个问题能分解为独立且较小的问题,就是相对较易解决的。问题太过于复杂,要解决问题需要关注的点太多,而程序员的能力是有限的,不能同时关注于问题的各个方面。
正如程序员的记忆力相对于计算机知识来说那么有限一样,程序员解决问题的能力相对于要解决的问题的复杂性也是一样的非常有限。在我们分析问题的时候,如果我们把所有的东西混在一起讨论,那么就只会有一个结果——乱。实现关注点分离的方法主要有两种,一种是标准化,另一种是抽象与包装。标准化就是制定一套标准,让使用者都遵守它,将人们的行为统一起来,这样使用标准的人就不用担心别人会有很多种不同的实现,使自己的程序不能和别人的配合。
就像是开发镙丝钉的人只专注于开发镙丝钉就行了,而不用关注镙帽是怎么生产的,反正镙帽和镙丝钉按照标准来就一定能合得上。不断地把程序的某些部分抽象并包装起来,也是实现关注点分离的好方法。一旦一个函数被抽象出来并实现了,那么使用函数的人就不用关心这个函数是如何实现的。同样的,一旦一个类被抽象并实现了,类的使用者也不用再关注于这个类的内部是如何实现的。诸如组件、分层、面向服务等这些概念都是在不同的层次上做抽象和包装,以使得使用者不用关心它的内部实现细节。
[DbCDesign by Contract- 契约式设计](http://en.wikipedia.org/wiki/Design_by_contract) DbC的核心思想是对软件系统中的元素之间相互合作以及“责任”与“义务”的比喻。这种比喻从商业活动中“客户”与“供应商”达成“契约”而得来。如果在程序设计中一个模块提供了某种功能那么它要
<li>
期望所有调用它的客户模块都保证一定的进入条件:这就是模块的先验条件(客户的义务和供应商的权利,这样它就不用去处理不满足先验条件的情况)。
</li>
<li>
保证退出时给出特定的属性:这就是模块的后验条件(供应商的义务,显然也是客户的权利)。
</li>
<li>
在进入时假定,并在退出时保持一些特定的属性:不变式。
</li>
[ADPAcyclic Dependencies Principle- 无环依赖原则](http://c2.com/cgi/wiki?AcyclicDependenciesPrinciple) ,包(或服务)之间的依赖结构必须是一个直接的无环图形,也就是说,在依赖结构中不允许出现环(循环依赖)。如果包的依赖形成了环状结构,怎么样打破这种循环依赖呢?
有两种方法可以打破这种循环依赖关系第一种方法是创建新的包如果A、B、C形成环路依赖那么把这些共同类抽出来放在一个新的包D里。这样就把C依赖A变成了C依赖D以及A依赖D从而打破了循环依赖关系。第二种方法是使用DIP依赖倒置原则和ISP接口分隔原则设计原则。无环依赖原则ADP为我们解决包之间的关系耦合问题。在设计模块时不能有循环依赖。
# 一些软件设计的读物
<li>
《[领域驱动设计](https://book.douban.com/subject/26819666/)》 ,本书是领域驱动设计方面的经典之作。全书围绕着设计和开发实践,结合若干真实的项目案例,向读者阐述如何在真实的软件开发中应用领域驱动设计。书中给出了领域驱动设计的系统化方法,并将人们普遍接受的一些实践综合到一起,融入了作者的见解和经验,展现了一些可扩展的设计新实践、已验证过的技术以及便于应对复杂领域的软件项目开发的基本原则。
</li>
<li>
《[UNIX编程艺术](https://book.douban.com/subject/1467587/)》 这本书主要介绍了Unix系统领域中的设计和开发哲学、思想文化体系、原则与经验由公认的Unix编程大师、开源运动领袖人物之一埃里克·雷蒙德Eric S. Raymond倾力多年写作而成。包括Unix设计者在内的多位领域专家也为本书贡献了宝贵的内容。本书内容涉及社群文化、软件开发设计与实现覆盖面广、内容深邃完全展现了作者极其深厚的经验积累和领域智慧。
</li>
<li>
《[Clean Architecture](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)》,如果你读过 《[Clean Code](https://book.douban.com/subject/5442024/)》 和 《[The Clean Coder](https://book.douban.com/subject/11614538/)》这两本书。你就能猜得到这种 Clean 系列一定也是出自“Bob大叔”之手。没错就是Bob大叔的心血之作。除了这个网站《[Clean Architecture](https://book.douban.com/subject/26915970/)》也是一本书,这是一本很不错的架构类图书。对软件架构的元素、方法等讲得很清楚。示例都比较简单,并带一些软件变化历史的讲述,很开阔视野。
</li>
<li>
[The Twelve-Factor App](https://12factor.net/) 如今软件通常会作为一种服务来交付它们被称为网络应用程序或软件即服务SaaS。12-Factor 为构建SaaS 应用提供了方法论,这也是架构师必读的文章。([中译版](https://12factor.net/zh_cn/) 这篇文章在业内的影响力很大,必读!
</li>
<li>
[Avoid Over Engineering](https://medium.com/@rdsubhas/10-modern-software-engineering-mistakes-bc67fbef4fc8) ,有时候,我们会过渡设计我们的系统,过度设计会把我们带到另外一个复杂度上,所以,我们需要一些工程上的平衡。这篇文章是一篇非常不错地告诉你什么是过度设计的文章。
</li>
<li>
[Instagram Engineerings 3 rules to a scalable cloud application architecture](https://medium.com/@DataStax/instagram-engineerings-3-rules-to-a-scalable-cloud-application-architecture-c44afed31406) Instagram 工程的三个黄金法则1使用稳定可靠的技术迎接新的技术2不要重新发明轮子3Keep it very simple。我觉得这三条很不错。其实Amazon也有两条工程法则一个是自动化一个是简化。
</li>
<li>
[How To Design A Good API and Why it Matters - Joshua Bloch](https://www.infoq.com/presentations/effective-api-design) Google的一个分享关于如何设计好一个API。
</li>
<li>
关于Restful API的设计你可以学习并借鉴一下下面这些文章。
<ul>
- [Best Practices for Designing a Pragmatic RESTful API](https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
- [Ideal REST API design](https://betimdrenica.wordpress.com/2015/03/09/ideal-rest-api-design/)
- [HTTP API Design Guide](https://github.com/interagent/http-api-design)
- [Microsoft REST API Guidelines](https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md)
- [IBM Watson REST API Guidelines](https://github.com/watson-developer-cloud/api-guidelines)
- [Zalando RESTful API and Event Scheme Guidelines](https://opensource.zalando.com/restful-api-guidelines/)
[The Problem With Logging](https://blog.codinghorror.com/the-problem-with-logging/) ,一篇关于程序打日志的短文,可以让你知道一些可能以往不知道的打日志需要注意的问题。
[Concurrent Programming for Scalable Web Architectures](http://berb.github.io/diploma-thesis/community/index.html) ,这是一本在线的免费书,教你如何架构一个可扩展的高性能的网站。其中谈到了一些不错的设计方法和知识。
# 小结
好了,总结一下今天分享的内容。我认为,“品位”不同,是各层次程序员之间最大的区别,这也决定了他们所做出来的软件的质量和价值。因此,我特意撰写了软件设计这一篇章,帮助那些想成长为软件工程师、设计师或架构师的程序员,提高软件设计的品位,进而实现自己的目标。
虽然很多程序员都忽略了对编程范式的学习但我觉得学习编程范式其实是非常非常重要的事能够明白编程的本质和各种语言的编程方式。为此我推荐了好几份学习资料帮助你系统化地学习和理解。随后我介绍了DRY-避免重复原则、KISS-简单原则、迪米特法则(又称“最少知识原则”)、 面向对象的S.O.L.I.D原则等多个经典的软件设计原则。
最后我精选并推荐了软件设计方面的学习资料如《领域驱动设计》、《UNIX编程艺术》和《Clean Architecture》等必读好书以及如何构建SaaS如何避免过度设计如何设计API如何用程序打日志等方面的资料。
希望这些内容对你有帮助。从下一篇文章开始,我们将进入《程序员练级攻略》的第五个篇章——高手成长篇。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,304 @@
<audio id="audio" title="77 | 程序员练级攻略Linux系统、内存和网络" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/e3/e4/e338311b8cffea0c66dd71ce657456e4.mp3"></audio>
这一篇章,是本系列中最长的一篇,其中包括了如下的内容。
<li>
**系统底层相关**。 主要是以Linux系统为主其中有大量的文章可以让你学习到Linux内核以及内存、网络、异步I/O模型、Lock-free的无锁编程还有其它和系统底层相关的东西。注意系统底层要是深下去是可以完全不见底的。而且内存方面的知识也是比较多的所以这里还是主要给出一些非常有价值的基础性的知识和技术。学好这些东西你会对系统有很深的理解而且可以把这些知识反哺到架构设计上来。
</li>
<li>
**数据库相关**。数据库方面主要是MySQL和各种开源NoSQL的一些相关的有价值的文章和导读主要是让你对这些数据库的内在有一定的了解但又不会太深。真正的深入是需要扎入到源代码中的。需要说明的是这块技术不是我的长项但又是每个架构师需要知道的所以我在这里给的学习资源可能会比较浅这点还希望你来补充和指正。
</li>
<li>
**分布式架构**。这一部分是最长最多的。其中有架构入门、分布式理论中各种非常有价值的经典论文,然后是一些分布式工程设计方面的文章,其中包括设计模式和工程应用,最后还有各大公司的架构供参考。
</li>
<li>
**微服务**。有了分布式架构理论和工程的基础接下来是对微服务的学习。在这部分内容中我会罗列几个介绍微服务架构非常系统的文章然后比较一下微服务和SOA的差别最后则是一些工程实践和最佳实践。
</li>
<li>
**容器化和自动化运维**。在容器化和自动化运维中主要是学习Docker和Kubernetes这两个自动化运维的杀手型技术。而不是Salt、Puppet、Chef和Ansible这样比较传统的工具。原因很简单因为自动化部署根本不够还需要对环境和运行时的管理和运维才够而只有Docker和Kubernetes才是未来。所以这里重点让你学习这两个技术其中有很多文章需要一些系统底层的知识。
</li>
<li>
**机器学习和人工智能**。机器学习和人工智能,也不是我的长项,我也只是一个入门者。这里,我主要给了一些基础性的知识,其中包括基本原理、图书、课程、文章和相关的算法。你顺着我画的这路走,不能说能成为一个人工智能专家,但成为一个机器学习的高级工程师甚至准专家还是可能的。
</li>
<li>
**前端开发**。这里的前端主要是HTML 5的前端了这一节会带你学习一下前端开发所需要知道的基础知识尤其是对前端开发语言JavaScript的学习我花费了相当的篇幅列出了很多很经典的学习资料必定会让你成为一个JavaScript高手。然后你还需要了解浏览器是怎样工作的还有相关的网络协议和一些性能优化的技巧。最后则是JavaScript框架的学习这里我只给了React.js和Vue.js并通过React.js带出来函数式编程的学习。我虽然不是一个前端程序员但是我相信我这个后端程序员给出来的这组前端开发的学习资料和路径会比前端程序员更靠谱一些。
</li>
<li>
**信息源**。最后则是一些信息源其中包括各大公司的技术Blog还有相关的论文集散地。
</li>
另外,这里需要说明几点。
<li>
我假设你在前面已经打下了非常扎实的基础,但是要成为一个高手,基础知识只是一个地基,你还需要很多更为具体的技术。对我来说,就是看各种各样的文章、手册、论文、分享…… 其实,学习到一定程度,就是要从书本中走出去,到社区里和大家一起学习,而且还需要自己找食吃了。所以,对于这里面的文章,有很多都是在罗列各种文章和资源,只是为你梳理信息源,而不是喂你吃饭。
</li>
<li>
**老实说我已经为你梳理并过滤掉了很多的信息这里只留下了30%我觉得最经济也最有价值的信息**。虽然对于不同定位和不同需求的人还可以再对这些信息进行删减,但是觉得我这么一做就会对其它人不公平了。所以,这也是我觉得最小数量集的信息和资源吧。**你也可以把我这里的东西当成一个索引来对待**。
</li>
<li>
这些内容,不能说是隔离开来的,应该说是相辅相成的。也没什么顺序,可以各取所需。虽然看上去内容很多,但你也别害怕,真的不用害怕,你会越学越快,越实践越有感觉,也越有效率。在一开始可能会很慢,但是坚持住,积累一段时间后就会越来越快的。 而且,我要告诉你,绝大多数人是坚持不下来的。只要你能坚持下来,我保证,你一定会成为各个大公司的抢手货,这点你一定要相信我。**你不需要特别努力只需要日进一步3-5年后你就会发现绝大多数人都在你身后很远的地方了。**
</li>
今天分享的内容为系统底层知识中的Linux系统、内存和网络等方面的相关知识及推荐的学习资料。
# Linux系统相关
学习Linux操作系统的原理是通向系统工程师的必经之路。我觉得Unix/Linux操作系统里的东西并不难学。你千万不要一下子扎到源代码里去那样没用——你还是要在上层先通过读一些不错的文档来学习。下面我罗列了一些很不错的站点其中有很多内容供你去钻研和探索。
我在这里默认你前面已经读过并读懂了我推荐的那些和Unix/Linux相关的图书了。所以我相信你对Unix/Linux下的编程已经是有一些基础了因此你继续深挖Linux下的这些知识应该也不是很难的事了。
<li>
[Red Hat Enterprise Linux文档](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/?version=7) 。Red Hat Enterprise LinuxRHEL是老牌Linux厂商Red Hat出品的面向商业的Linux发行版。Red Hat网站上的这个文档中有很多很有价值的内容值得一看。
</li>
<li>
[Linux Insides](https://github.com/0xAX/linux-insides) GitHub上的一个开源电子书其中讲述了Linux内核是怎样启动、初始化以及进行管理的。
</li>
<li>
[LWNs kernel page](http://lwn.net/Kernel/Index/) 上面有很多非常不错的文章来解释Linux内核的一些东西。
</li>
<li>
[Learn Linux Kernel from Android Perspective](http://learnlinuxconcepts.blogspot.com/2014/10/this-blog-is-to-help-those-students-and.html) 从Android的角度来学习Linux内核这个站点上的Blog相对于前面的比较简单易读一些。
</li>
<li>
[Linux Kernel Doc](https://www.kernel.org/doc/) Linux的内核文档也可以浏览一下。
</li>
<li>
[Kernel Planet](http://planet.kernel.org/) Linux内核开发者的Blog有很多很不错的文章和想法。
</li>
<li>
[Linux Performance and Tuning Guidelines](https://lenovopress.com/redp4285.pdf) 这是IBM出的红皮书虽然有点老了但还是非常值得一读的。
</li>
<li>
[TLK: The Linux Kernel](http://tldp.org/LDP/tlk/tlk.html) 这是一本相对比较老的书了Linux内核版本为2.0.33,但了解一下前人的思路,也是很有帮助的。
</li>
<li>
[Linux Performance](http://www.brendangregg.com/linuxperf.html) 这个网站上提供了和Linux系统性能相关的各种工具和文章收集非常不错。
</li>
<li>
[Optimizing web servers for high throughput and low latency](https://blogs.dropbox.com/tech/2017/09/optimizing-web-servers-for-high-throughput-and-low-latency/) 这是一篇非常底层的系统调优的文章来自DropBox从中你可以学到很多底层的性能调优的经验和知识。
</li>
# 内存相关
计算机内存管理是每一个底层程序员需要了解的非常重要的事儿。当然这里我们重点还是Linux操作系统相关的内存管理上的知识。
首先LWN.net上有一系列的 “**What every programmer should know about memory**” 文章你需要读一下。当然,你可以直接访问一个完整的 [PDF文档](http://futuretech.blinkenlights.nl/misc/cpumemory.pdf)。下面是这个系列文章的网页版列表。读完这个列表的内容,你基本上就对内存有了一个比较好的知识体系了。
- [Part 1: Introduction](https://lwn.net/Articles/250967/) ,中译版为 “[每个程序员都应该了解的内存知识【第一部分】](https://www.oschina.net/translate/what-every-programmer-should-know-about-memory-part1)”
- [Part 2: CPU caches](https://lwn.net/Articles/252125/)
- [Part 3 (Virtual memory)](http://lwn.net/Articles/253361/)
- [Part 4 (NUMA systems)](http://lwn.net/Articles/254445/)
- [Part 5 (What programmers can do - cache optimization)](http://lwn.net/Articles/255364/)
- [Part 6 (What programmers can do - multi-threaded optimizations)](http://lwn.net/Articles/256433/)
- [Part 7 (Memory performance tools)](http://lwn.net/Articles/257209/)
- [Part 8 (Future technologies)](https://lwn.net/Articles/258154/)
- [Part 9 (Appendices and bibliography)](https://lwn.net/Articles/258188/)
然后是几篇和内存相关的论文。下面这三篇论文是我个人觉得能对你非常有帮助的文章,尤其是你要做一些程序的性能优化方面。
<li>
[Memory Barriers: a Hardware View for Software Hackers](http://irl.cs.ucla.edu/~yingdi/web/paperreading/whymb.2010.06.07c.pdf)。内存的读写屏障是线程并发访问共享的内存数据时从程序本身、编译器到CPU都必须遵循的一个规范。有了这个规范才能保证访问共享的内存数据时一个线程对该数据的更新能被另一个线程以正确的顺序感知到。在SMP对称多处理这种类型的多处理器系统包括多核系统这种读写屏障还包含了复杂的缓存一致性策略。这篇文章做了详细解释。
</li>
<li>
[A Tutorial Introduction to the ARM and POWER Relaxed Memory Models](http://www.cl.cam.ac.uk/~pes20/ppc-supplemental/test7.pdf)对ARM和POWER的宽松内存模型的一个教程式的简介。本篇文章的焦点是ARM和POWER体系结构下多处理器系统内存并发访问一致性的设计思路和使用方法。与支持较强的TSO模型的x86体系结构不同ARM和POWER这两种体系结构出于对功耗和性能的考虑使用了一种更为宽松的内存模型。本文详细讨论了ARM和POWER的模型。
</li>
<li>
[x86-TSO: A Rigorous and Usable Programmers Model for x86 Multiprocessors](http://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf)介绍x86的多处理器内存并发访问的一致性模型TSO。
</li>
接下来是开发者最关心的内存管理方面的lib库。通常来说我们有三种内存分配管理模块。就目前而言BSD的jemalloc有很大的影响力。后面我们可以看到不同公司的实践性文章。
<li>
[ptmalloc](http://www.malloc.de/en/) 是glibc的内存分配管理。
</li>
<li>
[tcmalloc](https://github.com/gperftools/gperftools) 是Google的内存分配管理模块全称是Thread-Caching malloc基本上来说比glibc的ptmalloc快两倍以上。
</li>
<li>
[jemalloc](http://jemalloc.net/) 是BSD提供的内存分配管理。其论文为 [A Scalable Concurrent malloc(3) Implementation for FreeBSD](https://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf),这是一个可以并行处理的内存分配管理器。
</li>
关于 C 的这些内存分配器你可以参看Wikipedia的 “[C Dynamic Memory Allocation](https://en.wikipedia.org/wiki/C_dynamic_memory_allocation#Thread-caching_malloc_(tcmalloc))”这个词条。
下面是几篇不错的文章,让你感觉一下上面那三种内存分配器的一些比较和工程实践。
- [ptmalloctcmalloc和jemalloc内存分配策略研究](https://owent.net/2013/867.html)
- [内存优化总结ptmalloc、tcmalloc和jemalloc](http://www.cnhalo.net/2016/06/13/memory-optimize/)
- [Scalable memory allocation using jemalloc](https://www.facebook.com/notes/facebook-engineering/scalable-memory-allocation-using-jemalloc/480222803919)
- [Decreasing RAM Usage by 40% Using jemalloc with Python &amp; Celery](https://zapier.com/engineering/celery-python-jemalloc/)
# 计算机网络
## 网络学习
首先,推荐一本书——《[计算机网络(第五版)](https://book.douban.com/subject/10510747/)》这本“计算机网络”和前面推荐的那本计算机网络不一样前面那本偏扫盲这本中有很多细节。这本书是国内外使用最广泛、最权威的计算机网络经典教材。全书按照网络协议模型自下而上物理层、数据链路层、介质访问控制层、网络层、传输层和应用层有系统地介绍了计算机网络的基本原理并结合Internet给出了大量的协议实例。
这本书还与时俱进地引入了最新的网络技术包括无线网络、3G蜂窝网络、RFID与传感器网络、内容分发与P2P网络、流媒体传输与IP语音以及延迟容忍网络等。另外本书针对当前网络应用中日益突出的安全问题用了一整章的篇幅对计算机网络的安全性进行了深入讨论而且把相关内容与最新网络技术结合起来阐述。这本书读起来并不枯燥因为其中有很多小故事和小段子。
然后,有两个网上的教程和讲义也可以让人入门。
- 渥汰华大学的一个课程讲义你也可以一看 [Computer Network Design](http://www.site.uottawa.ca/~shervin/courses/ceg4185/lectures/) 。
- GeeksforGeeks 上也有一个简单的 [Computer Network Tutorials](https://www.geeksforgeeks.org/computer-network-tutorials/) 。
## 网络调优
接下来,你可能需要一些非常实用的可以操作的技术,下面的几篇文章相信可以帮助到你。
<li>
《Linux的高级路由和流量控制 HowTo》[Linux Advanced Routing &amp; Traffic Control HOWTO](http://lartc.org/) ),这是一个非常容易上手的关于 iproute2、流量整形和一点 netfilter 的指南。
</li>
<li>
关于网络调优,你可以看一下这个文档 [Red Hat Enterprise Linux Network Performance Tuning Guide](https://access.redhat.com/sites/default/files/attachments/20150325_network_performance_tuning.pdf)。
</li>
<li>
还有一些网络工具能够帮上你的大忙这里有一个网络工具的Awesome列表 [Awesome Pcap Tools](https://github.com/caesar0301/awesome-pcaptools) ,其中罗列了各种网络工具,能够让你更从容地调试网络相关的程序。
</li>
<li>
[Making Linux TCP Fast](https://netdevconf.org/1.2/papers/bbr-netdev-1.2.new.new.pdf) 一篇非常不错的TCP调优的论文。
</li>
<li>
下面是在PackageCloud上的两篇关于Linux网络栈相关的底层文章非常值得一读。
<ul>
<li>
[Monitoring and Tuning the Linux Networking Stack: Receiving Data](https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/)
</li>
<li>
[Monitoring and Tuning the Linux Networking Stack: Sending Data](https://blog.packagecloud.io/eng/2017/02/06/monitoring-tuning-linux-networking-stack-sending-data/)
</li>
## 网络协议
接下来想要学习网络协议最好的方式就是学习通讯相关的RFC。所以在这里我会推荐一系列值得读的RFC给你。读RFC有几个好处一方面可以学习技术另一方面你可以通过RFC学习到一个好的技术文档是怎么写的还能看到各种解决问题的方案和思路。
对于第2层链路层你可能需要了解一下ARP
- [RFC 826 - An Ethernet Address Resolution Protocol](https://tools.ietf.org/html/rfc826)
以及Tunnel相关的协议
- [RFC 1853 - IP in IP Tunneling](https://tools.ietf.org/html/rfc1853)
- [RFC 2784 - Generic Routing Encapsulation (GRE)](https://tools.ietf.org/html/rfc2784)
- [RFC 2661 - Layer Two Tunneling Protocol “L2TP”](https://tools.ietf.org/html/rfc2661)
- [RFC 2637 - Point-to-Point Tunneling Protocol (PPTP)](https://tools.ietf.org/html/rfc2637)
对于第4层你最需要了解的是TCP/IP了。和TCP相关的RFC相当多这里给一系列经典的RFC。这些RFC我都引用在了我在CoolShell上的《[TCP的那些事儿](https://coolshell.cn/articles/11564.html)》和《[TCP的那些事儿](https://coolshell.cn/articles/11609.html)》两篇文章中。如果你看不懂RFC你也可以去看我上述的文章。
<li>
[RFC 793 - Transmission Control Protocol](https://tools.ietf.org/html/rfc793) - 最初的TCP标准定义但不包括TCP相关细节。
</li>
<li>
[RFC 813 - Window and Acknowledgement Strategy in TCP](https://tools.ietf.org/html/rfc813) - TCP窗口与确认策略并讨论了在使用该机制时可能遇到的问题及解决方法。
</li>
<li>
[RFC 879 - The TCP Maximum Segment Size and Related Topics](https://tools.ietf.org/html/rfc879) - 讨论MSS参数对控制TCP分组大小的重要性以及该参数与IP分段大小的关系等。
</li>
<li>
[RFC 896 - Congestion Control in IP/TCP Internetworks](https://tools.ietf.org/html/rfc896) - 讨论拥塞问题和TCP如何控制拥塞。
</li>
<li>
[RFC 2581 - TCP Congestion Control](https://tools.ietf.org/html/rfc2581) - 描述用于拥塞控制的四种机制慢启动、拥塞防御、快重传和快恢复。后面这个RFC被 [RFC 5681](https://tools.ietf.org/html/rfc5681) 所更新。还有 [RFC 6582 - The NewReno Modification to TCPs Fast Recovery Algorithm](https://tools.ietf.org/html/rfc6582) 中一个改进的快速恢复算法。
</li>
<li>
[RFC 2018 - TCP Selective Acknowledgment Options](https://tools.ietf.org/html/rfc2018) - TCP的选择确认。
</li>
<li>
[RFC 2883 - An Extension to the Selective Acknowledgement (SACK) Option for TCP](https://tools.ietf.org/html/rfc2883) - 对于RFC 2018的改进。
</li>
<li>
[RFC 2988 - Computing TCPs Retransmission Timer](https://tools.ietf.org/html/rfc2988) - 讨论与TCP重传计时器设置相关的话题重传计时器控制报文在重传前应等待多长时间。也就是经典的TCP Karn/Partridge重传算法。
</li>
<li>
[RFC 6298 - Computing TCPs Retransmission Timer](https://tools.ietf.org/html/rfc6298) - TCP Jacobson/Karels Algorithm重传算法。
</li>
我个人觉得TCP最牛的不是不丢包而是拥塞控制。对此如果你感兴趣可以读一下经典论文《[Congestion Avoidance and Control](http://ee.lbl.gov/papers/congavoid.pdf)》。
关于Linux下的TCP参数你需要仔仔细细地读一下[TCP的man page](http://man7.org/linux/man-pages/man7/tcp.7.html) 。
对于第7层协议HTTP协议是重点要学习的。
首先推荐的是《[HTTP权威指南](https://book.douban.com/subject/10746113/) 》这本书有点厚可以当参考书来看。这本书中没有提到HTTP/2的事但是可以让你了解到HTTP协议的绝大多数特性。
HTTP 1.1的原始RFC是1999年6月的 [RFC 2616](https://tools.ietf.org/html/rfc2616)但其在2014后很快被下面这些RFC给取代了。
<li>
[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing](https://tools.ietf.org/html/rfc7230)
</li>
<li>
[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content](https://tools.ietf.org/html/rfc7231)
</li>
<li>
[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests](https://tools.ietf.org/html/rfc7232)
</li>
<li>
[RFC 7233 - Hypertext Transfer Protocol (HTTP/1.1): Range Requests](https://tools.ietf.org/html/rfc7233)
</li>
<li>
[RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching](https://tools.ietf.org/html/rfc7234)
</li>
<li>
[RFC 7235 - Hypertext Transfer Protocol (HTTP/1.1): Authentication](https://tools.ietf.org/html/rfc7235)
</li>
关于[HTTP/2](https://en.wikipedia.org/wiki/HTTP/2)这是HTTP的一个比较新的协议它于2015年被批准通过现在基本上所有的主流浏览器都默认启用这个协议。所以你有必要学习一下这个协议。下面是相关的学习资源。
<li>
[Gitbook - HTTP/2详解](https://legacy.gitbook.com/book/ye11ow/http2-explained/details)
</li>
<li>
[http2 explained](http://daniel.haxx.se/http2/)[中译版](https://www.gitbook.com/book/ye11ow/http2-explained/details)
</li>
<li>
[HTTP/2 for a Faster Web](https://cascadingmedia.com/insites/2015/03/http-2.html)
</li>
<li>
[Nginx HTTP/2 白皮书](https://www.nginx.com/wp-content/uploads/2015/09/NGINX_HTTP2_White_Paper_v4.pdf)
</li>
<li>
HTTP/2 的两个RFC
<ul>
- [RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)](https://httpwg.org/specs/rfc7540.html) HTTP/2的协议本身
- [RFC 7541 - HPACK: Header Compression for HTTP/2](https://httpwg.org/specs/rfc7541.html) HTTP/2的压缩算法
最后你可以上Wikipedia的 [Internet Protocol Suite](https://en.wikipedia.org/wiki/Internet_protocol_suite) 上看看,这是一个很不错的网络协议的词条汇集地。顺着这些协议,你可以找到很多有用的东西。
# 小结
好了总结一下今天的内容。这是程序员练级攻略2018版第五篇章——高手成长篇的第一篇文章。前面的内容先介绍了一些这一系列内容的总体构成及每一部分的学习重点。后面是这一篇章第一个主题系统底层知识中的部分内容即Linux系统、内存和计算机网络并给出了相应的学习资料。
我认为,学习到一定程度,就是要从书本中走出去,到社区里和大家一起学习,而且还需要自己找食吃了。所以,这篇文章中,我罗列了各种文章和资源,并给出了简短的推荐语言,就是在为你梳理信息源,而不是喂你吃饭。我更希望看到你自趋势地成长。
下篇文章中我们分享的内容为系统底层知识中的异步I/O模型、Lock-Free编程以及其他一些相关的知识点和学习资源。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,211 @@
<audio id="audio" title="78 | 程序员练级攻略异步I/O模型和Lock-Free编程" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/5d/ba/5dd9303e5524df362ad4e4072b7dacba.mp3"></audio>
# 异步I/O模型
异步I/O模型是我个人觉得所有程序员都必需要学习的一门技术或是编程方法这其中的设计模式或是解决方法可以借鉴到分布式架构上来。再说一遍学习这些模型是非常非常重要的你千万要认真学习。
史蒂文斯Stevens在《[UNIX网络编程](https://book.douban.com/subject/4859464/)》一书6.2 I/O Models中介绍了五种I/O模型。
- 阻塞I/O
- 非阻塞I/O
- I/O的多路复用select和poll
- 信号驱动的I/OSIGIO
- 异步I/OPOSIX的aio_functions
然后,在前面我们也阅读过了 - [C10K Problem](https://en.wikipedia.org/wiki/C10k_problem) 。相信你对I/O模型也有了一定的了解。 这里我们需要更为深入地学习I/O模型尤其是其中的异步I/O模型。
首先我们看一篇和Java相关的I/O模型的文章来复习一下之前的内容。[Thousands of Threads and Blocking I/O: The Old Way to Write Java Servers Is New Again (and Way Better)](https://www.slideshare.net/e456/tyma-paulmultithreaded1) 这个PPT中不仅回顾和比较了各种I/O模型而且还有各种比较细节的方案和说明是一篇非常不错的文章。
然后你可以看一篇Java相关的PPT - 道格·莱亚Doug Lea的 [Scalable IO in Java](http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf),这样你会对一些概念有个了解。
接下来我们需要了解一下各种异步I/O的实现和设计方式。
<li>
[IBM - Boost application performance using asynchronous I/O](https://developer.ibm.com/technologies/linux/articles/l-async/) 这是一篇关于AIO的文章。
</li>
<li>
[Lazy Asynchronous I/O For Event-Driven Servers](https://www.usenix.org/legacy/event/usenix04/tech/general/full_papers/elmeleegy/elmeleegy_html/html.html) ,这篇文章也很不错。
</li>
<li>
另外异步I/O模型中的 [Windows I/O Completion Ports](https://docs.microsoft.com/en-us/windows/desktop/FileIO/i-o-completion-ports) ,你也需要了解一下。如果MSDN上的这个手册不容易读你可以看看这篇文章 [Inside I/O Completion Ports](http://sysinternals.d4rk4.ru/Information/IoCompletionPorts.html)。另外关于Windows[Windows Internals](https://book.douban.com/subject/6935552/) 这本书你可以仔细读一下非常不错的。其中有一节I/O Processing也是很不错的这里我给一个网上免费的链接[I/O Processing](https://flylib.com/books/en/4.491.1.85/1/) 你可以看看Windows是怎么玩的。
</li>
<li>
接下来是Libevent。你可以看一下其主要维护人员尼克·马修森Nick Mathewson写的 [Libevent 2.0 book](http://www.wangafu.net/~nickm/libevent-book/)。还有一本国人写的电子书 《[Libevent深入浅出](https://aceld.gitbooks.io/libevent/content/)》。
</li>
<li>
再接下来是 Libuv。你可以看一下其官网的 [Libuv Design Overview](http://docs.libuv.org/en/v1.x/design.html) 了解一下。
</li>
我简单总结一下基本上来说异步I/O模型的发展技术是 select -&gt; poll -&gt; epoll -&gt; aio -&gt; libevent -&gt; libuv。Unix/Linux用了好几十年走过这些技术的变迁然而都不如Windows I/O Completion Port 设计得好免责声明这个观点纯属个人观点。相信你仔细研究这些I/O模型后你会有自己的判断
看过这些各种异步I/O模式的实现以后相信你会看到一个编程模式——Reactor模式。下面是这个模式的相关文章读这三篇就够了
- [Understanding Reactor Pattern: Thread-Based and Event-Driven](https://dzone.com/articles/understanding-reactor-pattern-thread-based-and-eve)
- [Reactor Pattern](https://www.dre.vanderbilt.edu/~schmidt/PDF/Reactor2-93.pdf)
- [The reactor pattern and non-blocking IO](https://www.celum.com/en/blog/technology/the-reactor-pattern-and-non-blocking-io)
然后是几篇有意思的延伸阅读文章。
<li>
[The Secret To 10 Million Concurrent Connections -The Kernel Is The Problem, Not The Solution](http://highscalability.com/blog/2013/5/13/the-secret-to-10-million-concurrent-connections-the-kernel-i.html) - C10M问题来了……
</li>
<li>
还有几篇可能有争议的文章,让你从不同的角度思考。
<ul>
- [Select is fundamentally broken](https://idea.popcount.org/2017-01-06-select-is-fundamentally-broken/)
- [Epoll is fundamentally broken 1/2](https://idea.popcount.org/2017-02-20-epoll-is-fundamentally-broken-12/)
- [Epoll is fundamentally broken 2/2](https://idea.popcount.org/2017-03-20-epoll-is-fundamentally-broken-22/)
# Lock-Free编程相关
Lock-Free - 无锁技术越来越被开发人员重视,因为锁对于性能的影响实在是太大了,所以如果想开发出一个高性能的程序,你就非常有必要学习 Lock-Free的编程方式。
关于无锁的数据结构,有几篇教程你可以看一下。
<li>
[Dr.Dobbs: Lock-Free Data Structures](http://www.drdobbs.com/lock-free-data-structures/184401865)
</li>
<li>
[Andrei Alexandrescu: Lock-Free Data Structures](https://erdani.com/publications/cuj-2004-10.pdf)
</li>
然后强烈推荐一本免费的电子书:[Is Parallel Programming Hard, And, If So, What Can You Do About It?](https://www.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html) ,这是大牛 [保罗·麦肯尼Paul E. McKenney](https://www.linkedin.com/in/paulmckenney/) 写的书。这本书堪称并行编程的经典书,必看。
此时Wikipedia上有三个词条你要看一下以此了解并发编程中的一些概念[Non-blocking algorithm](https://en.wikipedia.org/wiki/Non-blocking_algorithm) 、[Read-copy-update](https://en.wikipedia.org/wiki/Read-copy-update) 和 [Seqlock](https://en.wikipedia.org/wiki/Seqlock)。
接下来,读一下以下两篇论文 。
<li>
[Implementing Lock-Free Queues](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.53.8674&rep=rep1&type=pdf) 这也是一篇很不错的论文,我把它介绍在了我的网站上 ,文章为“[无锁队列的实现](https://coolshell.cn/articles/8239.html)”。
</li>
<li>
[Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms](http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf) ,这篇论文给出了一个无阻塞和阻塞的并发队列算法。
</li>
最后,有几个博客你要订阅一下。
<li>
[1024cores](http://www.1024cores.net/) - 德米特里·伐由科夫Dmitry Vyukov的和 lock-free 编程相关的网站。
</li>
<li>
[Paul E. McKenney](http://paulmck.livejournal.com/) - 保罗Paul的个人网站。
</li>
<li>
[Concurrency Freaks](http://concurrencyfreaks.blogspot.com/) - 关于并发算法和相关模式的网站。
</li>
<li>
[Preshing on Programming](http://preshing.com/) - 加拿大程序员杰夫·普莱辛Jeff Preshing的技术博客主要关注C++和Python两门编程语言。他用C++11实现了类的反射机制用C++编写了3D小游戏Hop Out还为该游戏编写了一个游戏引擎。他还讨论了很多C++的用法比如C++14推荐的代码写法、新增的某些语言构造等和Python很相似。阅读这个技术博客上的内容能够深深感受到博主对编程世界的崇敬和痴迷。
</li>
<li>
[Sutters Mill](http://herbsutter.com/) - 赫布·萨特Herb Sutter是一位杰出的C++专家曾担任ISO C++标准委员会秘书和召集人超过10年。他的博客有关于C++语言标准最新进展的信息其中也有他的演讲视频。博客中还讨论了其他技术和C++的差异如C#和JavaScript,它们的性能特点、怎样避免引入性能方面的缺陷等。
</li>
<li>
[Mechanical Sympathy](http://mechanical-sympathy.blogspot.com/) - 博主是马丁·汤普森Martin Thompson他是一名英国的技术极客探索现代硬件的功能并提供开发、培训、性能调优和咨询服务。他的博客主题是Hardware and software working together in harmony里面探讨了如何设计和编写软件使得它在硬件上能高性能地运行。非常值得一看。
</li>
接下来是一些编程相关的一些C/C++的类库这样你就不用从头再造轮子了对于Java的请参看JDK里的Concurrent开头的一系列的类
<li>
[Boost.Lockfree](http://www.boost.org/doc/libs/1_60_0/doc/html/lockfree.html) - Boost库中的无锁数据结构。
</li>
<li>
[ConcurrencyKit](https://github.com/concurrencykit/ck) - 并发性编程的原语。
</li>
<li>
[Folly](https://github.com/facebook/folly) - Facebook的开源库它对MPMC队列做了一个很好的实现
</li>
<li>
[Junction](https://github.com/preshing/junction) - C++中的并发数据结构。
</li>
<li>
[MPMCQueue](https://github.com/rigtorp/MPMCQueue) - 一个用C++11编写的有边界的“多生产者-多消费者”无锁队列。
</li>
<li>
[SPSCQueue](https://github.com/rigtorp/SPSCQueue) - 一个有边界的“单生产者-单消费者”的无等待、无锁的队列。
</li>
<li>
[Seqlock](https://github.com/rigtorp/Seqlock) - 用C++实现的Seqlock。
</li>
<li>
[Userspace RCU](http://liburcu.org/) - liburcu是一个用户空间的RCURead-copy-update读-拷贝-更新)库。
</li>
<li>
[libcds](https://github.com/khizmax/libcds) - 一个并发数据结构的C++库。
</li>
<li>
[liblfds](https://liblfds.org/) - 一个用C语言编写的可移植、无许可证、无锁的数据结构库。
</li>
# 其它
<li>
关于64位系统编程只要去一个地方就行了 [All about 64-bit programming in one place](https://software.intel.com/en-us/blogs/2011/07/07/all-about-64-bit-programming-in-one-place/)这是一个关于64位编程相关的收集页面其中包括相关的文章、28节课程还有知识库和相关的blog。
</li>
<li>
[What Scalable Programs Need from Transactional Memory](https://dl.acm.org/citation.cfm?id=3037750) 事务性内存TM一直是许多研究的重点它在诸如IBM Blue Gene/Q和Intel Haswell等处理器中得到了支持。许多研究都使用STAMP基准测试套件来评估其设计。然而我们所知的所有TM系统上的STAMP基准测试所获得的加速比较有限。
例如在IBM Blue Gene/Q上有64个线程我们观察到使用Blue Gene/Q硬件事务内存HTM的中值加速比为1.4倍使用软件事务内存STM的中值加速比为4.1倍。什么限制了这些TM基准的性能在本论文中作者认为问题在于用于编写它们的编程模型和数据结构上只要使用合适的模型和数据结构程序的性能可以有10多倍的提升。
</li>
<li>
[Improving OpenSSL Performance](https://software.intel.com/en-us/articles/improving-openssl-performance) 这篇文章除了教你如何提高OpenSSL的执行性能还讲了一些底层的性能调优知识。
</li>
<li>
关于压缩的内容。为了避免枯燥,主要推荐下面这两篇实践性很强的文章。
<ul>
<li>
[How eBays Shopping Cart used compression techniques to solve network I/O bottlenecks](https://www.ebayinc.com/stories/blogs/tech/how-ebays-shopping-cart-used-compression-techniques-to-solve-network-io-bottlenecks/) 这是一篇很好的文章讲述了eBay是如何通过压缩数据来提高整体服务性能的其中有几个比较好的压缩算法。除了可以让你学到相关的技术知识还可以让你看到一种比较严谨的工程师文化。
</li>
<li>
[Linkedin: Boosting Site Speed Using Brotli Compression](https://engineering.linkedin.com/blog/2017/05/boosting-site-speed-using-brotli-compression) LinkedIn在2017年早些时候开始使用 [Brotli](https://en.wikipedia.org/wiki/Brotli) 来替换 gzip以此带来更快的访问这篇文章讲述了什么是Brotli以及与其它压缩程序的比较和所带来的性能提升。
</li>
这里有两篇关于SSD硬盘性能测试的文章。[Performance Testing with SSDs, Part 1](https://devs.mailchimp.com/blog/performance-testing-with-ssds-part-1/) 和 [Performance Testing with SSDs Part 2](https://devs.mailchimp.com/blog/performance-testing-with-ssds-pt-2/) 这两篇文章介绍了测试SSD硬盘性能以及相关的操作系统调优方法。
[Secure Programming HOWTO - Creating Secure Software](https://www.dwheeler.com/secure-programs/) 这是一本电子书其中有繁体中文的翻译这本电子书讲了Linux/Unix下的一些安全编程方面的知识。
# 相关论文
<li>
[Hints for Computer System Design](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/acrobat-17.pdf) 计算机设计的忠告这是ACM图灵奖得主 [Butler Lampson](https://en.wikipedia.org/wiki/Butler_Lampson) 在Xerox PARC工作时的一篇论文。这篇论文简明扼要地总结了他在做系统设计时的一些想法非常值得一读。用他的话来说“Studying the design and implementation of a number of computer has led to some general hints for system design. They are described here and illustrated by many examples, ranging from hardware such as the Alto and the Dorado to application programs such as Bravo and Star“。
</li>
<li>
[The 5 minute rule for trading memory for disc accesses and the 5 byte rule for trading memory for CPU time](http://www.hpl.hp.com/techreports/tandem/TR-86.1.pdf) 根据文章名称也可以看出5分钟法则是用来衡量内存与磁盘的而5字节法则则是在内存和CPU之间的权衡。这两个法则是Jim Gray和Franco Putzolu在1986年的文章。
在该论文发表10年后的1997年Jim Gray和Goetz Graefe 又在 [The Five-Minute Rule Ten Years Later and Other Computer Storage Rules of Thumb](http://research.microsoft.com/en-us/um/people/gray/5_min_rule_SIGMOD.pdf) 中对该法则进行了重新审视。2007年也就是该论文发表20年后这年的1月28日Jim Gray驾驶一艘40英尺长的船从旧金山港出海目的是航行到附近的费拉隆岛在那里撒下母亲的骨灰。出海之后他就同朋友和亲属失去了联系。为了纪念和向大师致敬时隔10多年后的2009年Goetz Graefe又发表了 [The Five-Minute Rule 20 Years Later (and How Falsh Memory Changes the Rules)](http://cacm.acm.org/magazines/2009/7/32091-the-five-minute-rule-20-years-later/fulltext)。
注明一下Jim Gray是关系型数据库领域的大师。因在数据库和事务处理研究和实现方面的开创性贡献而获得1998年图灵奖。美国科学院、工程院两院院士ACM和IEEE两会会士。他25岁成为加州大学伯克利分校计算机科学学院第一位博士。在IBM工作期间参与和主持了IMS、System R、SQLDS、DB2等项目的开发。后任职于微软研究院主要关注应用数据库技术来处理各学科的海量信息。
</li>
# 小结
好了总结一下今天的内容。异步I/O模型是我个人觉得所有程序员都必需要学习的一门技术或是编程方法这其中的设计模式或是解决方法可以借鉴到分布式架构上来。而且我认为学习这些模型非常重要你千万要认真学习。
接下来是Lock-Free方面的内容由于锁对于性能的影响实在是太大了所以它越来越被开发人员所重视。如果想开发出一个高性能的程序你非常有必要学习 Lock-Free的编程方式。随后我给出系统底层方面的其它一些重要知识如64位编程、提高OpenSSL的执行性能、压缩、SSD硬盘性能测试等。最后介绍了几篇我认为对学习和巩固这些知识非常有帮助的论文都很经典推荐你务必看看。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,101 @@
<audio id="audio" title="79 | 程序员练级攻略Java底层知识" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/91/3d/9193b0624ad6d1b5761f0b37f5b0813d.mp3"></audio>
前两篇文章分享的是系统底层方面的内容今天我们进入高手成长篇的第二部分——Java底层知识。
# Java 字节码相关
首先Java最黑科技的玩法就是字节码编程也就是动态修改或是动态生成Java字节码。Java的字节码相当于汇编其中的一些细节你可以从下面的这几个教程中学习。
<li>
[Java Zone: Introduction to Java Bytecode](https://dzone.com/articles/introduction-to-java-bytecode) 这篇文章图文并茂地向你讲述了Java字节码的一些细节是一篇很不错的入门文章。
</li>
<li>
[IBM DeveloperWorks: Java bytecode](https://www.ibm.com/developerworks/library/it-haggar_bytecode/index.html) 虽然这篇文章很老了但是这篇文章是一篇非常好的讲Java 字节码的文章。
</li>
<li>
[Java Bytecode and JVMTI Examples](https://github.com/jon-bell/bytecode-examples),这是一些使用 [JVM Tool Interface](http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html) 操作字节码的比较实用的例子。包括方法调用统计、静态字节码修改、Heap Taggin和Heap Walking。
</li>
当然一般来说我们不使用JVMTI操作字节码而是用一些更好用的库。这里有三个库可以帮你比较容易地做这个事。
- [asmtools](https://wiki.openjdk.java.net/display/CodeTools/asmtools) - 用于生产环境的Java .class文件开发工具。
- [Byte Buddy](http://bytebuddy.net/) - 代码生成库运行时创建Class文件而不需要编译器帮助。
- [Jitescript](https://github.com/qmx/jitescript) - 和 [BiteScript](https://github.com/headius/bitescript) 类似的字节码生成库。
就我而言我更喜欢Byte Buddy它在2015年还获了Oracle的 “[Dukes Choice](https://www.oracle.com/corporate/pressrelease/dukes-award-102815.html)”大奖其中说Byte Buddy极大地发展了Java的技术。
使用字节码编程可以玩出很多高级玩法最高级的还是在Java程序运行时进行字节码修改和代码注入。听起来是不是一些很黑客也很黑科技的事是的这个方式使用Java这门静态语言在运行时可以进行各种动态的代码修改而且可以进行无侵入的编程。
比如, 我们不需要在代码中埋点做统计或监控,可以使用这种技术把我们的监控代码直接以字节码的方式注入到别人的代码中,从而实现对实际程序运行情况进行统计和监控。如果你看过我的《编程范式游记》,你就知道这种技术的威力了,其可以很魔法地把业务逻辑和代码控制分离开来。
要做到这个事你还需要学习一个叫Java Agent的技术。Java Agent使用的是 “[Java Instrumentation API](https://stackoverflow.com/questions/11898566/tutorials-about-javaagents)”,其主要方法是实现一个叫 `premain()` 的方法(嗯,一个比 `main()` 函数还要超前执行的 main 函数然后把你的代码编译成一个jar文件。
在JVM启动时使用这样的命令行来引入你的jar文件`java -javaagent:yourAwesomeAgent.jar -jar App.jar`。更为详细的文章你可以参看:“[Java Code Geeks: Java Agents](https://www.javacodegeeks.com/2015/09/java-agents.html)”,你还可以看一下这个示例项目:[jvm-monitoring-agent](https://github.com/toptal/jvm-monitoring-agent) 或是 [EntryPointKR/Agent.java](https://gist.github.com/EntryPointKR/152f089f6f3884047abcd19d39297c9e)。如果想用ByteBuddy来玩你可以看看这篇文章 “[通过使用Byte Buddy便捷地创建Java Agent](http://www.infoq.com/cn/articles/Easily-Create-Java-Agents-with-ByteBuddy)”。如果你想学习如何用Java Agent做监控你可以看一下这个项目 [Stage Monitor](http://www.stagemonitor.org/)。
# JVM 相关
接下来讲讲Java底层知识中另一个非常重要的内容——JVM。
说起JVM你有必要读一下JVM的规格说明书我在这里放一个Java 8的 [The Java Virtual Machine Specification Java SE 8 Edition](https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf) 。对于规格说明书的阅读我认为是系统了解JVM规范的最佳文档这个文档可以让你对于搞不清楚或是诡异的问题恍然大悟。关于中文翻译有人在GitHub上开了个Repo - “[java-virtual-machine-specification](https://github.com/waylau/java-virtual-machine-specification)”。
另外,也推荐一下 [JVM Anatomy Park](https://shipilev.net/jvm-anatomy-park/) JVM解剖公园这是一个系列的文章每篇文章都不长但是都很精彩带你一点一点地把JVM中的一些技术解开。
学习Java底层原理还有Java的内存模型官方文章是 [JSR 133](http://www.jcp.org/en/jsr/detail?id=133)。还有马里兰大学的威廉·皮尤William Pugh教授收集的和Java内存模型相关的文献 - [The Java Memory Model](http://www.cs.umd.edu/~pugh/java/memoryModel/) ,你可以前往浏览。
对于内存方面道格·利Doug Lea有两篇文章也是很有价值的。
<li>
[The JSR-133 Cookbook for Compiler Writers](http://gee.cs.oswego.edu/dl/jmm/cookbook.html)解释了怎样实现Java内存模型特别是在考虑到多处理器或多核系统的情况下多线程和读写屏障的实现。
</li>
<li>
[Using JDK 9 Memory Order Modes](http://gee.cs.oswego.edu/dl/html/j9mm.html)讲了怎样通过VarHandle来使用plain、opaque、release/acquire和volatile四种共享内存的访问模式并剖析了底层的原理。
</li>
垃圾回收机制也是需要好好学习的,在这里推荐一本书 《[The Garbage Collection Handbook](https://book.douban.com/subject/6809987/)》在豆瓣上的得分居然是9.9(当然,评价人数不多)。这本书非常全面地介绍了垃圾收集的原理、设计和算法。但是这本书也是相当难啃的。中文翻译《[垃圾回收算法手册](https://book.douban.com/subject/26740958/)》翻译得很一般,有人说翻译得很烂。所以,如果可能,还是读英文版的。如果你对从事垃圾回收相关的工作有兴趣,那么你需要好好看一下这本书。
当然,更多的人可能只需要知道怎么调优垃圾回收, 那么推荐读读 [Garbage Collection Tuning Guide](http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/) 它是Hotspot Java虚拟机的垃圾回收调优指南对你很有帮助。
[Quick Tips for Fast Code on the JVM](https://gist.github.com/djspiewak/464c11307cabc80171c90397d4ec34ef) 也是一篇很不错的文章里面有写出更快的Java代码的几个小提示值得一读。
# 小结
好了总结一下今天学到的内容。Java最黑科技的玩法就是字节码编程也就是动态修改或是动态生成Java字节码。Java的字节码相当于汇编学习其中的细节很有意思为此我精心挑选了3篇文章供你学习。我们一般不使用JVMTI操作字节码而是用一些更好用的库如asmtools、Byte Buddy和BiteScript等。使用字节码编程可以玩出很多高级玩法其中最高级的玩法是在Java程序运行时进行字节码修改和代码注入。同时我介绍了Java Agent技术帮助你更好地实现这种高级玩法。
JVM也是学习Java过程中非常重要的一部分内容。我推荐阅读一下JVM的规格说明书我认为它是系统了解JVM规范的最佳文档可以让你对于搞不清楚或是诡异的问题恍然大悟。同时推荐了 [JVM Anatomy Park](https://shipilev.net/jvm-anatomy-park/) 系列文章,也非常值得一读。
随后介绍的是Java的内存模型和垃圾回收机制尤其给出了如何调优垃圾回收方面的资料。这些内容都很底层但也都很重要。对于想成为高手的你来说还是有必要花时间来啃一啃的。
下篇文章是数据库方面的内容,我们将探讨各种类型的数据库,非常有意思。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,428 @@
<audio id="audio" title="80 | 程序员练级攻略:数据库" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/b4/bc/b481f2396ab646fb2d4786ab3d3019bc.mp3"></audio>
对于数据库方向重点就是两种数据库一种是以SQL为代表的关系型数据库另一种是以非SQL为代表的NoSQL数据库。关系型数据库主要有三个Oracle、MySQL 和 Postgres。
在这里我们只讨论越来越主流的MySQL数据库。首先我们要了解数据库的一些实现原理和内存的一些细节然后我们要知道数据的高可用和数据复制这些比较重要的话题了解一下关系型数据库的一些实践和难点。然后我们会进入到NoSQL数据库的学习。
NoSQL数据库千奇百怪其主要是解决了关系型数据库中的各种问题。第一个大问题就是数据的Schema非常多用关系型数据库来表示不同的Data Schema是非常笨拙的所以要有不同的数据库如时序型、键值对型、搜索型、文档型、图结构型等。另一个大问题是关系型数据库的ACID是一件很讨厌的事这极大地影响了数据库的性能和扩展性所以NoSQL在这上面做了相应的妥协以解决大规模伸缩的问题。
对于一个程序员你可能觉得数据库的事都是DBA的事然而我想告诉你你错了这些事才真正是程序员的事。因为程序是需要和数据打交道的所以程序员或架构师不仅需要设计数据模型还要保证整体系统的稳定性和可用性数据是整个系统中关键中的关键。所以作为一个架构师或程序员你必须了解最重要的数据存储——数据库。
# 关系型数据库
今天关系型数据库最主要的两个代表是闭源的Oracle和开源的MySQL。当然还有很多了比如微软的SQL ServerIBM的DB2等还有开源的PostgreSQL。关系型数据库的世界中有好多好多产品。当然还是Oracle和MySQL是比较主流的。所以这里主要介绍更为开放和主流的MySQL。
如果你要玩Oracle我这里只推荐一本书《[Oracle Database 9i/10g/11g编程艺术](https://book.douban.com/subject/5402711/)》无论是开发人员还是DBA它都是必读的书。这本书的作者是Oracle公司的技术副总裁托马斯·凯特Thomas Kyte他也是世界顶级的Oracle专家。
这本书中深入分析了Oracle数据库体系结构包括文件、内存结构以及构成Oracle数据库和实例的底层进程利用具体示例讨论了一些重要的数据库主题如锁定、并发控制、事务等。同时分析了数据库中的物理结构如表、索引和数据类型并介绍采用哪些技术能最优地使用这些物理结构。
<li>
学习MySQL首先一定是要看[MySQL 官方手册](https://dev.mysql.com/doc/)。
</li>
<li>
然后官方还有几个PPT也要学习一下。
<ul>
<li>
[How to Analyze and Tune MySQL Queries for Better Performance](https://www.mysql.com/cn/why-mysql/presentations/tune-mysql-queries-performance/)
</li>
<li>
[MySQL Performance Tuning 101](https://www.mysql.com/cn/why-mysql/presentations/mysql-performance-tuning101/)
</li>
<li>
[MySQL Performance Schema &amp; Sys Schema](https://www.mysql.com/cn/why-mysql/presentations/mysql-performance-sys-schema/)
</li>
<li>
[MySQL Performance: Demystified Tuning &amp; Best Practices](https://www.mysql.com/cn/why-mysql/presentations/mysql-performance-tuning-best-practices/)
</li>
<li>
[MySQL Security Best Practices](https://www.mysql.com/cn/why-mysql/presentations/mysql-security-best-practices/)
</li>
<li>
[MySQL Cluster Deployment Best Practices](https://www.mysql.com/cn/why-mysql/presentations/mysql-cluster-deployment-best-practices/)
</li>
<li>
[MySQL High Availability with InnoDB Cluster](https://www.mysql.com/cn/why-mysql/presentations/mysql-high-availability-innodb-cluster/)
</li>
然后推荐《[高性能MySQL](https://book.douban.com/subject/23008813/)》这本书是MySQL领域的经典之作拥有广泛的影响力。不但适合数据库管理员DBA阅读也适合开发人员参考学习。不管是数据库新手还是专家都能从本书中有所收获。
如果你对MySQL的内部原理有兴趣的话可以看一下这本书《[MySQL技术内幕InnoDB存储引擎](https://book.douban.com/subject/24708143/)》。当然,还有官网的[MySQL Internals Manual](https://dev.mysql.com/doc/internals/en/) 。
数据库的索引设计和优化也是非常关键的,这里还有一本书《[数据库的索引设计与优化](https://book.douban.com/subject/26419771/)》也是很不错的。虽然不是讲MySQL的但是原理都是相通的。这也是上面推荐过的《高性能MySQL》在其索引部分推荐的一本好书。
你千万不要觉得只有做数据库你才需要学习这种索引技术。不是的!在系统架构上,在分布式架构中,索引技术也是非常重要的。这本书对于索引性能进行了非常清楚的估算,不像其它书中只是模糊的描述,你一定会收获很多。
下面还有一些不错的和MySQL相关的文章。
<li>
[MySQL索引背后的数据结构及算法原理](http://blog.codinglabs.org/articles/theory-of-mysql-index.html)
</li>
<li>
[Some study on database storage internals](https://medium.com/@kousiknath/data-structures-database-storage-internals-1f5ed3619d43)
</li>
<li>
[Sharding Pinterest: How we scaled our MySQL fleet](https://medium.com/@Pinterest_Engineering/sharding-pinterest-how-we-scaled-our-mysql-fleet-3f341e96ca6f)
</li>
<li>
[Guide to MySQL High Availability](https://www.mysql.com/cn/why-mysql/white-papers/mysql-guide-to-high-availability-solutions/)
</li>
<li>
[Choosing MySQL High Availability Solutions](https://dzone.com/articles/choosing-mysql-high-availability-solutions)
</li>
<li>
[High availability with MariaDB TX: The definitive guide](https://mariadb.com/sites/default/files/content/Whitepaper_High_availability_with_MariaDB-TX.pdf)
</li>
最后还有一个MySQL的资源列表 [Awesome MySQL](https://shlomi-noach.github.io/awesome-mysql/),这个列表中有很多的工具和开发资源,可以帮助你做很多事。
MySQL有两个比较有名的分支一个是Percona另一个是MariaDB其官网上的Resources页面中有很多不错的资源和文档可以经常看看。 [Percona Resources](https://www.percona.com/resources)、[MariaDB Resources](https://mariadb.com/resources) ,以及它们的开发博客中也有很多不错的文章,分别为 [Percona Blog](https://www.percona.com/blog/) 和 [MariaDB Blog](https://mariadb.com/resources/blog)。
然后是关于MySQL的一些相关经验型的文章。
<li>
[Booking.com: Evolution of MySQL System Design](https://www.percona.com/live/mysql-conference-2015/sessions/bookingcom-evolution-mysql-system-design) Booking.com的MySQL数据库使用的演化其中有很多不错的经验分享我相信也是很多公司会遇到的的问题。
</li>
<li>
[Tracking the Money-Scaling Financial Reporting at Airbnb](https://medium.com/airbnb-engineering/tracking-the-money-scaling-financial-reporting-at-airbnb-6d742b80f040) Airbnb的数据库扩展的经验分享。
</li>
<li>
[Why Uber Engineering Switched from Postgres to MySQL](https://eng.uber.com/mysql-migration/) 无意比较两个数据库谁好谁不好推荐这篇Uber的长文主要是想让你从中学习到一些经验和技术细节这是一篇很不错的文章。
</li>
关于MySQL的集群复制下面有这些文章供你学习一下都是很不错的实践性比较强的文章。
<li>
[Monitoring Delayed Replication, With A Focus On MySQL](https://engineering.imvu.com/2013/01/09/monitoring-delayed-replication-with-a-focus-on-mysql/)
</li>
<li>
[Mitigating replication lag and reducing read load with freno](https://githubengineering.com/mitigating-replication-lag-and-reducing-read-load-with-freno/)
</li>
<li>
另外Booking.com给了一系列的文章你可以看看
<ul>
<li>
[Better Parallel Replication for MySQL](https://medium.com/booking-com-infrastructure/better-parallel-replication-for-mysql-14e2d7857813)
</li>
<li>
[Evaluating MySQL Parallel Replication Part 2: Slave Group Commit](https://medium.com/booking-com-infrastructure/evaluating-mysql-parallel-replication-part-2-slave-group-commit-459026a141d2)
</li>
<li>
[Evaluating MySQL Parallel Replication Part 3: Benchmarks in Production](https://medium.com/booking-com-infrastructure/evaluating-mysql-parallel-replication-part-3-benchmarks-in-production-db5811058d74)
</li>
<li>
<p><a href="https://medium.com/booking-com-infrastructure/evaluating-mysql-parallel-replication-part-4-more-benchmarks-in-production-49ee255043ab">Evaluating MySQL Parallel Replication Part 4: More Benchmarks in Production<br>
</a></p>
</li>
<li>
[Evaluating MySQL Parallel Replication Part 4, Annex: Under the Hood](https://medium.com/booking-com-infrastructure/evaluating-mysql-parallel-replication-part-4-annex-under-the-hood-eb456cf8b2fb)
</li>
对于MySQL的数据分区来说还有下面几篇文章你可以看看。
<li>
[StackOverflow: MySQL sharding approaches?](https://stackoverflow.com/questions/5541421/mysql-sharding-approaches)
</li>
<li>
[Why you dont want to shard](https://www.percona.com/blog/2009/08/06/why-you-dont-want-to-shard/)
</li>
<li>
[How to Scale Big Data Applications](https://www.percona.com/sites/default/files/presentations/How%20to%20Scale%20Big%20Data%20Applications.pdf)
</li>
<li>
[MySQL Sharding with ProxySQL](https://www.percona.com/blog/2016/08/30/mysql-sharding-with-proxysql/)
</li>
然后再看看各个公司做MySQL Sharding的一些经验分享。
<li>
<p><a href="https://devs.mailchimp.com/blog/using-shards-to-accommodate-millions-of-users/">MailChimp: Using Shards to Accommodate Millions of Users<br>
</a></p>
</li>
<li>
[Uber: Code Migration in Production: Rewriting the Sharding Layer of Ubers Schemaless Datastore](https://eng.uber.com/schemaless-rewrite/)
</li>
<li>
[Sharding &amp; IDs at Instagram](https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c)
</li>
<li>
[Airbnb: How We Partitioned Airbnbs Main Database in Two Weeks](https://medium.com/airbnb-engineering/how-we-partitioned-airbnb-s-main-database-in-two-weeks-55f7e006ff21)
</li>
# NoSQL数据库
关于NoSQL数据库其最初目的就是解决大数据的问题。然而也有人把其直接用来替换掉关系型数据库。所以在学习这个技术之前我们需要对这个技术的一些概念和初衷有一定的了解。下面是一些推荐资料。
<li>
Martin Fowler在YouTube上分享的NoSQL介绍 [Introduction To NoSQL](https://youtu.be/qI_g07C_Q5I) 以及他参与编写的 [NoSQL Distilled - NoSQL 精粹](https://book.douban.com/subject/25662138/)这本书才100多页是本难得的关于NoSQL的书很不错非常易读。
</li>
<li>
[NoSQL Databases: a Survey and Decision Guidance](https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#.nhzop4d23)这篇文章可以带你自上而下地从CAP原理到开始了解NoSQL的种种技术是一篇非常不错的文章。
</li>
<li>
[Distribution, Data, Deployment: Software Architecture Convergence in Big Data Systems](https://resources.sei.cmu.edu/asset_files/WhitePaper/2014_019_001_90915.pdf)这是卡内基·梅隆大学的一篇讲分布式大数据系统的论文。其中主要讨论了在大数据时代下的软件工程中的一些关键点也说到了NoSQL数据库。
</li>
<li>
[No Relation: The Mixed Blessings of Non-Relational Databases](http://ianvarley.com/UT/MR/Varley_MastersReport_Full_2009-08-07.pdf)这篇论文虽然有点年代久远。但这篇论文是HBase的基础你花上一点时间来读读就可以了解到对各种非关系型数据存储优缺点的一个很好的比较。
</li>
<li>
[NoSQL Data Modeling Techniques](https://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/) NoSQL建模技术。这篇文章我曾经翻译在了 CoolShell 上,标题为 [NoSQL 数据建模技术](https://coolshell.cn/articles/7270.htm),供你参考。
<ul>
<li>
[MongoDB - Data Modeling Introduction](https://docs.mongodb.com/manual/core/data-modeling-introduction/) 虽然这是MongoDB的数据建模介绍但是其很多观点可以用于其它的NoSQL数据库。
</li>
<li>
[Firebase - Structure Your Database](https://firebase.google.com/docs/database/android/structure-data) Google的Firebase数据库使用JSON建模的一些最佳实践。
</li>
因为CAP原理所以当你需要选择一个NoSQL数据库的时候你应该看看这篇文档 [Visual Guide to NoSQL Systems](http://blog.nahurst.com/visual-guide-to-nosql-systems)。
选SQL还是NoSQL这里有两篇文章值得你看看。
<li>
[SQL vs. NoSQL Databases: Whats the Difference?](https://www.upwork.com/hiring/data/sql-vs-nosql-databases-whats-the-difference/)
</li>
<li>
[Salesforce: SQL or NoSQL ](https://engineering.salesforce.com/sql-or-nosql-9eaf1d92545b)
</li>
# 各种NoSQL数据库
学习使用NoSQL数据库其实并不是一件很难的事只要你把官方的文档仔细地读一下是很容易上手的而且大多数NoSQL数据库都是开源的所以也可以通过代码自己解决问题。下面我主要给出一些典型的NoSQL数据库的一些经验型的文章供你参考。
**列数据库Column Database**
<li>
Cassandra相关
<ul>
<li>
沃尔玛实验室有两篇文章值得一读。
<ul>
- [Avoid Pitfalls in Scaling Cassandra Cluster at Walmart](https://medium.com/walmartlabs/avoid-pitfalls-in-scaling-your-cassandra-cluster-lessons-and-remedies-a71ca01f8c04)
- [Storing Images in Cassandra at Walmart](https://medium.com/walmartlabs/building-object-store-storing-images-in-cassandra-walmart-scale-a6b9c02af593)
[Yelp: How We Scaled Our Ad Analytics with Apache Cassandra](https://engineeringblog.yelp.com/2016/08/how-we-scaled-our-ad-analytics-with-cassandra.html) Yelp的这篇博客也有一些相关的经验和教训。
[Discord: How Discord Stores Billions of Messages](https://blog.discordapp.com/how-discord-stores-billions-of-messages-7fa6ec7ee4c7) Discord公司分享的一个如何存储十亿级消息的技术文章。
[Cassandra at Instagram](https://www.slideshare.net/DataStax/cassandra-at-instagram-2016) Instagram的一个PPT其中介绍了Instagram中是怎么使用Cassandra的。
[Netflix: Benchmarking Cassandra Scalability on AWS-Over a million writes per second](https://medium.com/netflix-techblog/benchmarking-cassandra-scalability-on-aws-over-a-million-writes-per-second-39f45f066c9e) Netflix公司在AWS上给Cassandra做的一个Benchmark。
HBase相关
<li>
[Imgur Notification: From MySQL to HBASE](https://medium.com/imgur-engineering/imgur-notifications-from-mysql-to-hbase-9dba6fc44183)
</li>
<li>
[Pinterest: Improving HBase Backup Efficiency](https://medium.com/@Pinterest_Engineering/improving-hbase-backup-efficiency-at-pinterest-86159da4b954)
</li>
<li>
[IBM : Tuning HBase performance](https://www.ibm.com/support/knowledgecenter/en/SSPT3X_2.1.2/com.ibm.swg.im.infosphere.biginsights.analyze.doc/doc/bigsql_TuneHbase.html)
</li>
<li>
[HBase File Locality in HDFS](http://www.larsgeorge.com/2010/05/hbase-file-locality-in-hdfs.html)
</li>
<li>
[Apache Hadoop Goes Realtime at Facebook](http://borthakur.com/ftp/RealtimeHadoopSigmod2011.pdf)
</li>
<li>
[Storage Infrastructure Behind Facebook Messages: Using HBase at Scale](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.294.8459&amp;rep=rep1&amp;type=pdf)
</li>
<li>
[GitHub: Awesome HBase](https://github.com/rayokota/awesome-hbase)
</li>
针对于HBase有两本书你可以考虑一下。
<li>
首先,先推荐两本书,一本是偏实践的《[HBase实战](https://book.douban.com/subject/25706541/)》,另一本是偏大而全的手册型的《[HBase权威指南](https://book.douban.com/subject/10748460/)》。
</li>
<li>
当然,你也可以看看官方的 [The Apache HBase™ Reference Guide](http://hbase.apache.org/0.94/book/book.html)
</li>
<li>
另外两个列数据库:
<ul>
<li>
[ClickHouse - Open Source Distributed Column Database at Yandex](https://clickhouse.yandex/)
</li>
<li>
[Scaling Redshift without Scaling Costs at GIPHY](https://engineering.giphy.com/scaling-redshift-without-scaling-costs/)
</li>
**文档数据库 Document Database - MongoDB, SimpleDB, CouchDB**
<li>
[Data Points - What the Heck Are Document Databases?](https://msdn.microsoft.com/en-us/magazine/hh547103.aspx)
</li>
<li>
[eBay: Building Mission-Critical Multi-Data Center Applications with MongoDB](https://www.mongodb.com/blog/post/ebay-building-mission-critical-multi-data-center-applications-with-mongodb)
</li>
<li>
[The AWS and MongoDB Infrastructure of Parse: Lessons Learned](https://medium.baqend.com/parse-is-gone-a-few-secrets-about-their-infrastructure-91b3ab2fcf71)
</li>
<li>
[Migrating Mountains of Mongo Data](https://medium.com/build-addepar/migrating-mountains-of-mongo-data-63e530539952)
</li>
<li>
[Couchbase Ecosystem at LinkedIn](https://engineering.linkedin.com/blog/2017/12/couchbase-ecosystem-at-linkedin)
</li>
<li>
[SimpleDB at Zendesk](https://medium.com/zendesk-engineering/resurrecting-amazon-simpledb-9404034ec506)
</li>
<li>
[Github: Awesome MongoDB](https://github.com/ramnes/awesome-mongodb)
</li>
**数据结构数据库 Data structure Database - Redis**
<li>
[Learn Redis the hard way (in production) at Trivago](http://tech.trivago.com/2017/01/25/learn-redis-the-hard-way-in-production/)
</li>
<li>
[Twitter: How Twitter Uses Redis To Scale - 105TB RAM, 39MM QPS, 10,000+ Instances ](http://highscalability.com/blog/2014/9/8/how-twitter-uses-redis-to-scale-105tb-ram-39mm-qps-10000-ins.html)
</li>
<li>
[Slack: Scaling Slacks Job Queue - Robustly Handling Billions of Tasks in Milliseconds Using Kafka and Redis](https://slack.engineering/scaling-slacks-job-queue-687222e9d100)
</li>
<li>
[GitHub: Moving persistent data out of Redis at GitHub](https://githubengineering.com/moving-persistent-data-out-of-redis/)
</li>
<li>
[Instagram: Storing Hundreds of Millions of Simple Key-Value Pairs in Redis](https://engineering.instagram.com/storing-hundreds-of-millions-of-simple-key-value-pairs-in-redis-1091ae80f74c)
</li>
<li>
[Redis in Chat Architecture of Twitch (from 27:22)](https://www.infoq.com/presentations/twitch-pokemon)
</li>
<li>
[Deliveroo: Optimizing Session Key Storage in Redis](https://deliveroo.engineering/2016/10/07/optimising-session-key-storage.html)
</li>
<li>
[Deliveroo: Optimizing Redis Storage](https://deliveroo.engineering/2017/01/19/optimising-membership-queries.html)
</li>
<li>
[GitHub: Awesome Redis](https://github.com/JamzyWang/awesome-redis)
</li>
**时序数据库 Time-Series Database**
<li>
[What is Time-Series Data &amp; Why We Need a Time-Series Database](https://blog.timescale.com/what-the-heck-is-time-series-data-and-why-do-i-need-a-time-series-database-dcf3b1b18563)
</li>
<li>
[Time Series Data: Why and How to Use a Relational Database instead of NoSQL](https://blog.timescale.com/time-series-data-why-and-how-to-use-a-relational-database-instead-of-nosql-d0cd6975e87c)
</li>
<li>
[Beringei: High-performance Time Series Storage Engine @Facebook](https://code.facebook.com/posts/952820474848503/beringei-a-high-performance-time-series-storage-engine/)
</li>
<li>
[Introducing Atlas: Netflixs Primary Telemetry Platform @Netflix](https://medium.com/netflix-techblog/introducing-atlas-netflixs-primary-telemetry-platform-bd31f4d8ed9a)
</li>
<li>
[Building a Scalable Time Series Database on PostgreSQL](https://blog.timescale.com/when-boring-is-awesome-building-a-scalable-time-series-database-on-postgresql-2900ea453ee2)
</li>
<li>
[Scaling Time Series Data Storage - Part I @Netflix](https://medium.com/netflix-techblog/scaling-time-series-data-storage-part-i-ec2b6d44ba39)
</li>
<li>
[Design of a Cost Efficient Time Series Store for Big Data](https://medium.com/@leventov/design-of-a-cost-efficient-time-series-store-for-big-data-88c5dc41af8e)
</li>
<li>
[GitHub: Awesome Time-Series Database](https://github.com/xephonhq/awesome-time-series-database)
</li>
**图数据库 - Graph Platform**
<li>
首先是IBM Devloperworks 上的两个简介性的PPT。
<ul>
<li>
[Intro to graph databases, Part 1, Graph databases and the CRUD operations](https://www.ibm.com/developerworks/library/cl-graph-database-1/cl-graph-database-1-pdf.pdf)
</li>
<li>
[Intro to graph databases, Part 2, Building a recommendation engine with a graph database](https://www.ibm.com/developerworks/library/cl-graph-database-2/cl-graph-database-2-pdf.pdf)
</li>
然后是一本免费的电子书《[Graph Database](http://graphdatabases.com)》。
接下来是一些图数据库的介绍文章。
<li>
[Handling Billions of Edges in a Graph Database](https://www.infoq.com/presentations/graph-database-scalability)
</li>
<li>
[Neo4j case studies with Walmart, eBay, AirBnB, NASA, etc](https://neo4j.com/customers/)
</li>
<li>
[FlockDB: Distributed Graph Database for Storing Adjacency Lists at Twitter](https://blog.twitter.com/engineering/en_us/a/2010/introducing-flockdb.html)
</li>
<li>
[JanusGraph: Scalable Graph Database backed by Google, IBM and Hortonworks](https://architecht.io/google-ibm-back-new-open-source-graph-database-project-janusgraph-1d74fb78db6b)
</li>
<li>
[Amazon Neptune](https://aws.amazon.com/neptune/)
</li>
**搜索数据库 - ElasticSearch**
<li>
[Elasticsearch: The Definitive Guide](https://www.elastic.co/guide/en/elasticsearch/guide/master/index.html) 这是官网方的ElasticSearch的学习资料基本上来说看这个就够了。
</li>
<li>
接下来是4篇和性能调优相关的工程实践。
<ul>
<li>
[Elasticsearch Performance Tuning Practice at eBay](https://www.ebayinc.com/stories/blogs/tech/elasticsearch-performance-tuning-practice-at-ebay/)
</li>
<li>
[Elasticsearch at Kickstarter](https://kickstarter.engineering/elasticsearch-at-kickstarter-db3c487887fc)
</li>
<li>
[9 tips on ElasticSearch configuration for high performance](https://www.loggly.com/blog/nine-tips-configuring-elasticsearch-for-high-performance/)
</li>
<li>
[Elasticsearch In Production-Deployment Best Practices](https://medium.com/@abhidrona/elasticsearch-deployment-best-practices-d6c1323b25d7)
</li>
最后是GitHub上的资源列表 [GitHub: Awesome ElasticSearch](https://github.com/dzharii/awesome-elasticsearch) 。
# 小结
好了总结一下今天分享的内容。虽然有人会认为数据库与程序员无关是DBA的事儿。但我坚信数据库才真正是程序员的事儿。因为程序是需要和数据打交道的所以程序员或架构师不仅需要设计数据模型还要保证整体系统的稳定性和可用性数据是整个系统中关键中的关键。
对于数据库方向重点就是两种数据库一种是以SQL为代表的关系型数据库另一种是以非SQL为代表的NoSQL数据库。因而在这篇文章中我给出了MySQL和各种开源NoSQL的一些相关的有价值的文章和导读主要是让你对这些数据库的内在有一定的了解但又不会太深。同时给出了一些知名企业使用数据库的工程实践这对于了解各种数据库的优劣非常有帮助值得认真读读。
从下篇文章开始,我们将进入分布式系统架构方面的内容,里面不仅涵盖了大量的理论知识,更有丰富的入门指导和大量的工程实践。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,183 @@
<audio id="audio" title="81 | 程序员练级攻略:分布式架构入门" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/37/eb/37043620aea394d126cb1bc07d9117eb.mp3"></audio>
学习分布式系统跟学习其它技术非常不一样,分布式系统涵盖的面非常广,具体来说涵盖如下几方面:
<li>
**服务调度**,涉及服务发现、配置管理、弹性伸缩、故障恢复等。
</li>
<li>
**资源调度**,涉及对底层资源的调度使用,如计算资源、网络资源和存储资源等。
</li>
<li>
**流量调度**,涉及路由、负载均衡、流控、熔断等。
</li>
<li>
**数据调度**,涉及数据复本、数据一致性、分布式事务、分库、分表等。
</li>
<li>
**容错处理**,涉及隔离、幂等、重试、业务补偿、异步、降级等。
</li>
<li>
**自动化运维**,涉及持续集成、持续部署、全栈监控、调用链跟踪等。
</li>
所有这些形成了分布式架构的整体复杂度,也造就了分布式系统中的很多很多论文、图书以及很多很多的项目。要学好分布式系统及其架构,我们需要大量的时间和实践才能真正掌握这些技术。
这里有几点需要你注意一下。
<li>
**分布式系统之所以复杂,就是因为它太容易出错了**。这意味着,**你要把处理错误的代码当成正常功能的代码来处理**。
</li>
<li>
**开发一个健壮的分布式系统的成本是单体系统的几百倍甚至几万倍**。这意味着,**我们要自己开发一个,需要能力很强的开发人员**。
</li>
<li>
**非常健壮的开源的分布式系统并不多,或者说基本没有**。这意味着,**如果你要用开源的那么你需要hold得住其源码**。
</li>
<li>
**管理或是协调多个服务或机器是非常难的**。这意味着,**我们要去读很多很多的分布式系统的论文**。
</li>
<li>
**在分布式环境下出了问题是很难debug的**。这意味着,**我们需要非常好的监控和跟踪系统,还需要经常做演练和测试**。
</li>
<li>
**在分布式环境下,你需要更科学地分析和统计**。这意味着,**我们要用P90这样的统计指标而不是平均值我们还需要做容量计划和评估**。
</li>
<li>
**在分布式环境下,需要应用服务化**。这意味着,**我们需要一个服务开发框架比如SOA或微服务**。
</li>
<li>
**在分布式环境下,故障不可怕,可怕的是影响面过大,时间过长**。这意味着,**我们需要花时间来开发我们的自动化运维平台**。
</li>
总之,在分布式环境下,一切都变得非常复杂。要进入这个领域,你需要有足够多的耐性和足够强的心态来接受各式各样的失败。当拥有丰富的实践和经验后,你才会有所建树。这并不是一日之功,你可能要在这个领域花费数年甚至数十年的时间。
# 分布式架构入门
学习如何设计可扩展的架构将会有助于你成为一个更好的工程师。系统设计是一个很宽泛的话题。在互联网上,关于架构设计原则的资源也是多如牛毛。所以,你需要知道一些基本概念,对此,这里你先阅读下面两篇文章。
<li>
[Scalable Web Architecture and Distributed Systems](http://www.aosabook.org/en/distsys.html) ,这篇文章会给你一个大概的分布式架构是怎么来解决系统扩展性问题的粗略方法。
</li>
<li>
[Scalability, Availability &amp; Stability Patterns](http://www.slideshare.net/jboner/scalability-availability-stability-patterns) 这个PPT能在扩展性、可用性、稳定性等方面给你一个非常大的架构设计视野和思想可以让你感受一下大概的全景图。
</li>
然后我更强烈推荐GitHub上的一篇文档 - [System Design Primer](https://github.com/donnemartin/system-design-primer) ,这个仓库主要组织收集分布式系统的一些与扩展性相关的资源,它可以帮助你学习如何构建可扩展的架构。
目前这个仓库收集到了好些系统架构和设计的基本方法。其中包括CAP理论、一致性模型、可用性模式、DNS、CDN、负载均衡、反向代理、应用层的微服务和服务发现、关系型数据库和NoSQL、缓存、异步通讯、安全等。
我认为上面这几篇文章基本足够可以让你入门了因为其中基本涵盖了所有与系统架构相关的技术。这些技术足够这世上90%以上的公司用了,只有超级巨型的公司才有可能使用更高层次的技术。
# 分布式理论
下面,我们来学习一下分布式方面的理论知识。
首先,你需要看一下 [An introduction to distributed systems](https://github.com/aphyr/distsys-class)。 这只是某个教学课程的提纲我觉得还是很不错的几乎涵盖了分布式系统方面的所有知识点而且辅以简洁并切中要害的说明文字非常适合初学者提纲挈领地了解知识全貌快速与现有知识结合形成知识体系。这也是一个分布式系统的知识图谱可以让你看到分布式系统的整体全貌。你可以根据这个知识图Google下去然后你会学会所有的东西。
然后,你需要了解一下拜占庭将军问题([Byzantine Generals Problem](https://en.wikipedia.org/wiki/Byzantine_fault_tolerance)。这个问题是莱斯利·兰波特Leslie Lamport于1982年提出用来解释一致性问题的一个虚构模型[论文地址](https://www.microsoft.com/en-us/research/uploads/prod/2016/12/The-Byzantine-Generals-Problem.pdf))。拜占庭是古代东罗马帝国的首都,由于地域宽广,守卫边境的多个将军(系统中的多个节点)需要通过信使来传递消息,达成某些一致的决定。但由于将军中可能存在叛徒(系统中节点出错),这些叛徒将努力向不同的将军发送不同的消息,试图会干扰一致性的达成。拜占庭问题即为在此情况下,如何让忠诚的将军们能达成行动的一致。
对于拜占庭问题来说,假如节点总数为 `N`,叛变将军数为 `F`,则当 `N &gt;= 3F + 1`问题才有解即拜占庭容错Byzantine Fault TolerantBFT算法。拜占庭容错算法解决的是网络通信可靠但节点可能故障情况下一致性该如何达成的问题。
最早由卡斯特罗Castro和利斯科夫Liskov在1999年提出的实用拜占庭容错Practical Byzantine Fault TolerantPBFT算法是第一个得到广泛应用的BFT算法。只要系统中有2/3的节点是正常工作的则可以保证一致性。PBFT算法包括三个阶段来达成共识预准备Pre-Prepare、准备Prepare和提交Commit
这里有几篇和这个问题相关的文章,推荐阅读。
<li>
[Dr.Dobbs - The Byzantine Generals Problem](http://www.drdobbs.com/cpp/the-byzantine-generals-problem/206904396)
</li>
<li>
[The Byzantine Generals Problem](http://blog.jameslarisch.com/the-byzantine-generals-problem)
</li>
<li>
[Practicle Byzantine Fault Tolerance](http://pmg.csail.mit.edu/papers/osdi99.pdf)
</li>
拜占庭容错系统研究中有三个重要理论CAP、FLP和DLS。
<li>
[CAP定理](https://en.wikipedia.org/wiki/CAP_theorem)CAP理论相信你应该听说过不下N次了。CAP定理是分布式系统设计中最基础也是最为关键的理论。CAP定理指出分布式数据存储不可能同时满足以下三个条件一致性Consistency、可用性Availability和 分区容忍Partition tolerance。 “在网络发生阻断partition你只能选择数据的一致性consistency或可用性availability无法两者兼得”。
论点比较直观如果网络因阻断而分隔为二在其中一边我送出一笔交易“将我的十元给A”在另一半我送出另一笔交易“将我的十元给B”。此时系统要不是a无可用性即这两笔交易至少会有一笔交易不会被接受要不就是b无一致性一半看到的是A多了十元而另一半则看到B多了十元。要注意的是CAP理论和扩展性scalability是无关的在分片sharded或非分片的系统皆适用。
</li>
<li>
[FLP impossibility](http://the-paper-trail.org/blog/a-brief-tour-of-flp-impossibility/),在异步环境中,如果节点间的网络延迟没有上限,只要有一个恶意的节点存在,就没有算法能在有限的时间内达成共识。但值得注意的是, [“Las Vegas” algorithms](https://en.wikipedia.org/wiki/Las_Vegas_algorithm)这个算法又叫撞大运算法其保证结果正确只是在运算时所用资源上进行赌博一个简单的例子是随机快速排序它的pivot是随机选的但排序结果永远一致在每一轮皆有一定机率达成共识随着时间增加机率会越趋近于1。而这也是许多成功的共识算法会采用的解决问题的办法。
</li>
<li>
容错的上限,从[DLS论文](http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf) 中我们可以得到以下结论:
<ul>
<li>
在部分同步partially synchronous的网络环境中即网络延迟有一定的上限但我们无法事先知道上限是多少协议可以容忍最多1/3的拜占庭故障Byzantine fault
</li>
<li>
在异步asynchronous的网络环境中具有确定性质的协议无法容忍任何错误但这篇论文并没有提及 [randomized algorithms](http://link.springer.com/chapter/10.1007%2F978-3-540-77444-0_7)在这种情况下可以容忍最多1/3的拜占庭故障。
</li>
<li>
在同步synchronous网络环境中即网络延迟有上限且上限是已知的协议可以容忍100%的拜占庭故障但当超过1/2的节点为恶意节点时会有一些限制条件。要注意的是我们考虑的是"具有认证特性的拜占庭模型authenticated Byzantine",而不是"一般的拜占庭模型";具有认证特性指的是将如今已经过大量研究且成本低廉的公私钥加密机制应用在我们的算法中。
</li>
当然还有一个著名的“8条荒谬的分布式假设[Fallacies of Distributed Computing](http://en.wikipedia.org/wiki/Fallacies_of_distributed_computing))”。
1. 网络是稳定的。
1. 网络传输的延迟是零。
1. 网络的带宽是无穷大。
1. 网络是安全的。
1. 网络的拓扑不会改变。
1. 只有一个系统管理员。
1. 传输数据的成本为零。
1. 整个网络是同构的。
阿尔农·罗特姆-盖尔-奥兹Arnon Rotem-Gal-Oz写了一篇长文 [Fallacies of Distributed Computing Explained](http://www.rgoarchitects.com/Files/fallacies.pdf) 来解释为什么这些观点是错误的。另外,[加勒思·威尔逊Gareth Wilson的文章](https://shimo.im/docs/gYpKDyQv6CXGgHTr) 则用日常生活中的例子对这些点做了通俗的解释。为什么我们深刻地认识到这8个错误是因为这要我们清楚地认识到——在分布式系统中错误是不可能避免的我们在分布式系统中能做的不是避免错误而是要把错误的处理当成功能写在代码中。
下面分享几篇一致性方面的论文。
<li>
当然关于经典的CAP理论也存在一些误导的地方这个问题在2012年有一篇论文 [CAP Twelve Years Later: How the Rules Have Changed](https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed) [中译版](http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed)中做了一些讨论主要是说在CAP中最大的问题就是分区也就是P在P发生的情况下非常难以保证C和A。然而这是强一致性的情况。
其实在很多时候我们并不需要强一致性的系统所以后来人们争论关于数据一致性和可用性时主要是集中在强一致性的ACID或最终一致性的BASE。当时BASE还不怎么为世人所接受主要是大家都觉得ACID是最完美的模型大家很难接受不完美的BASE。在CAP理论中大家总是觉得需要“三选二”也就是说P是必选项那“三选二”的选择题不就变成数据一致性(consistency)、服务可用性(availability) 间的“二选一”?
然而现实却是P很少遇到而C和A这两个事工程实践中一致性有不同程度可用性也有不同等级在保证分区容错性的前提下放宽约束后可以兼顾一致性和可用性两者不是非此即彼。其实在一个时间可能允许的范围内是可以取舍并交替选择的。
</li>
<li>
[Harvest, Yield, and Scalable Tolerant Systems](https://pdfs.semanticscholar.org/5015/8bc1a8a67295ab7bce0550886a9859000dc2.pdf) 这篇论文是基于上面那篇“CAP 12年后”的论文写的它主要提出了Harvest和Yield概念并把上面那篇论文中所讨论的东西讲得更为仔细了一些。
</li>
<li>
[Base: An Acid Alternative](https://queue.acm.org/detail.cfm?id=1394128) [中译版](http://www.cnblogs.com/savorboard/p/base-an-acid-alternative.html)本文是eBay的架构师在2008年发表给ACM的文章是一篇解释BASE原则或者说最终一致性的经典文章。文中讨论了BASE与ACID原则的基本差异, 以及如何设计大型网站以满足不断增长的可伸缩性需求,其中有如何对业务做调整和折中,以及一些具体的折中技术的介绍。一个比较经典的话是——“在对数据库进行分区后,为了可用性Availability牺牲部分一致性Consistency可以显著地提升系统的可伸缩性(Scalability)”。
</li>
<li>
[Eventually Consistent](https://www.allthingsdistributed.com/2008/12/eventually_consistent.html) 这篇文章是AWS的CTO维尔纳·沃格尔Werner Vogels在2008年发布在ACM Queue上的一篇数据库方面的重要文章阐述了NoSQL数据库的理论基石——最终一致性对传统的关系型数据库ACIDTransaction做了较好的补充。
</li>
# 小结
好了总结一下今天分享的内容。文章的开头我给出了学习分布式架构需要注意的几个关键点然后列出了入门学习的资源基本涵盖了所有与系统架构相关的技术。随后讲述了拜占庭容错系统研究中有三个重要理论CAP、FLP和DLS以及8条荒谬的分布式假设从理论和认知等角度让你更为清楚地理解分布式系统。最后分享了几篇一致性相关的论文很实用很经典推荐阅读。
下篇文章中,我将推荐一些分布式架构的经典图书和论文,并给出了导读文字,几乎涵盖了分布式系统架构方面的所有关键的理论知识。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,207 @@
<audio id="audio" title="82 | 程序员练级攻略:分布式架构经典图书和论文" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a4/ab/a4a195dd97600b5b33b77bac7b59a0ab.mp3"></audio>
# 经典图书
首先,我推荐几本分布式架构方面的经典图书。
<li>
**[Distributed Systems for fun and profit](http://book.mixu.net/distsys/single-page.html)**这是一本免费的电子书。作者撰写此书的目的是希望以一种更易于理解的方式讲述以亚马逊的Dynamo、谷歌的Bigtable和MapReduce等为代表的分布式系统背后的核心思想。
</li>
<li>
**[Designing Data Intensive Applications](https://book.douban.com/subject/27154352/)**这本书是一本非常好的书我们知道在分布式的世界里数据结点的扩展是一件非常麻烦的事。这本书深入浅出地用很多的工程案例讲解了如何让数据结点做扩展。作者马丁·科勒普曼Martin Kleppmann在分布式数据系统领域有着很深的功底并在这本书中完整地梳理各类纷繁复杂设计背后的技术逻辑不同架构之间的妥协与超越很值得开发人员与架构设计者阅读。
这本书深入到B-Tree、SSTables、LSM这类数据存储结构中并且从外部的视角来审视这些数据结构对NoSQL和关系型数据库的影响。这本书可以让你很清楚地了解到真正世界的大数据架构中的数据分区、数据复制的一些坑并提供了很好的解决方案。最赞的是作者将各种各样技术的本质非常好地关联在一起令你触类旁通。
而且这本书完全就是抽丝剥茧循循善诱从“提出问题”到“解决问题”、“解决方案”、“优化方案”和“对比不同的方案”一点一点地把非常晦涩的技术和知识展开。本书的引用相当多每章后面都有几百个Reference通过这些Reference你可以看到更为广阔、更为精彩的世界。
</li>
<li>
[Distributed Systems: Principles and Paradigms](http://barbie.uta.edu/~jli/Resources/MapReduce&amp;Hadoop/Distributed%20Systems%20Principles%20and%20Paradigms.pdf) 本书是由计算机科学家安德鲁·斯图尔特·塔能鲍姆Andrew S. Tanenbaum和其同事马丁·范·斯蒂恩Martin van Steen合力撰写的是分布式系统方面的经典教材。
语言简洁,内容通俗易懂,介绍了分布式系统的七大核心原理,并给出了大量的例子;系统讲述了分布式系统的概念和技术,包括通信、进程、命名、同步化、一致性和复制、容错以及安全等;讨论了分布式应用的开发方法(即范型)。但本书不是一本指导“如何做”的手册,仅适合系统性地学习基础知识,了解编写分布式系统的基本原则和逻辑。中文翻译版为[《分布式系统原理与范型》(第二版)](https://item.jd.com/10079452.html)。
</li>
<li>
<p>[Scalable Web Architecture and Distributed Systems](http://www.aosabook.org/en/distsys.html)<br>
这是一本免费的在线小册子,其中文翻译版 [可扩展的Web架构和分布式系统](http://nettee.github.io/posts/2016/Scalable-Web-Architecture-and-Distributed-Systems/)。本书主要针对面向互联网公网的分布式系统但其中的原理或许也可以应用于其他分布式系统的设计中。作者的观点是通过了解大型网站的分布式架构原理小型网站的构建也能从中受益。本书从大型互联网系统的常见特性如高可用、高性能、高可靠、易管理等出发引出了一个类似于Flickr的典型的大型图片网站的例子。</p>
</li>
<li>
[Principles of Distributed Systems](http://dcg.ethz.ch/lectures/podc_allstars/lecture/podc.pdf) ,本书是苏黎世联邦理工学院的教材。它讲述了多种分布式系统中会用到的算法。虽然分布式系统的不同场景会用到不同算法,但并不表示这些算法都会被用到。不过,作为学生来说,掌握了算法设计的精髓也就能举一反三地设计出解决其他问题的算法,从而得到分布式系统架构设计中所需的算法。
</li>
# 经典论文
## 分布式事务
想了解分布式模型中最难的“分布式事务”你需要看看Google App Engine联合创始人瑞恩·巴雷特Ryan Barrett在2009年的Google I/O大会上的演讲《[Transaction Across DataCenter](http://snarfed.org/transactions_across_datacenters_io.html)》([YouTube视频](http://www.youtube.com/watch?v=srOgpXECblk))。
在这个演讲中巴雷特讲述了各种经典的解决方案如何在一致性、事务、性能和错误上做平衡。而最后得到为什么分布式系统的事务只有Paxos算法是最好的。
下面这个图是这个算法中的结论。
<img src="https://coolshell.cn/wp-content/uploads/2014/01/Transaction-Across-DataCenter.jpg" alt="">
你也可以移步看一下我在Coolshell上写的这篇文章《[分布式系统的事务处理](https://coolshell.cn/articles/10910.html)》。
## Paxos一致性算法
Paxos算法是莱斯利·兰伯特Lesile Lamport于1990年提出来的一种基于消息传递且具有高度容错特性的一致性算法。但是这个算法太过于晦涩所以一直以来都属于理论上的论文性质的东西。其真正进入工程圈主要是来源于Google的Chubby lock——一个分布式的锁服务用在了Bigtable中。直到Google发布了下面这两篇论文Paxos才进入到工程界的视野中来。
- [Bigtable: A Distributed Storage System for Structured Data](https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf)
- [The Chubby lock service for loosely-coupled distributed systems](https://static.googleusercontent.com/media/research.google.com/en//archive/chubby-osdi06.pdf)
Google与Bigtable相齐名的还有另外两篇论文。
- [The Google File System](https://static.googleusercontent.com/media/research.google.com/en//archive/gfs-sosp2003.pdf)
- [MapReduce: Simplified Data Processing on Large Clusters](https://static.googleusercontent.com/media/research.google.com/en//archive/mapreduce-osdi04.pdf)
不过这几篇文章中并没有讲太多的Paxos算法上的细节反而是在[Paxos Made Live - An Engineering Perspective](https://static.googleusercontent.com/media/research.google.com/en//archive/paxos_made_live.pdf) 这篇论文中提到了很多工程实现的细节。这篇论文详细解释了Google实现Paxos时遇到的各种问题和解决方案讲述了从理论到实际应用二者之间巨大的鸿沟。
Paxos算法的原版论文比较晦涩也不易懂。这里推荐一篇比较容易读的—— [Neat Algorithms - Paxos](http://harry.me/blog/2014/12/27/neat-algorithms-paxos/) 。这篇文章中还有一些小动画帮助你读懂。还有一篇可以帮你理解的文章是 [Paxos by Examples](https://angus.nyc/2012/paxos-by-example/)。
## Raft一致性算法
因为Paxos算法太过于晦涩而且在实际的实现上有太多的坑并不太容易写对。所以有人搞出了另外一个一致性的算法叫Raft。其原始论文是 [In search of an Understandable Consensus Algorithm (Extended Version) ](https://raft.github.io/raft.pdf) 寻找一种易于理解的Raft算法。这篇论文的译文在InfoQ上题为《[Raft一致性算法论文译文](https://infoq.cn/article/raft-paper)》,推荐你读一读。
这里推荐几个不错的Raft算法的动画演示。
- [Raft - The Secret Lives of Data](http://thesecretlivesofdata.com/raft/)
- [Raft Consensus Algorithm](https://raft.github.io/)
- [Raft Distributed Consensus Algorithm Visualization](http://kanaka.github.io/raft.js/)
## Gossip一致性算法
后面业内又搞出来一些工程上的东西比如Amazon的DynamoDB其论文[Dynamo: Amazons Highly Available Key Value Store](http://bnrg.eecs.berkeley.edu/~randy/Courses/CS294.F07/Dynamo.pdf) 的影响力非常大。这篇论文中讲述了Amazon的DynamoDB是如何满足系统的高可用、高扩展和高可靠的。其中展示了系统架构是如何做到数据分布以及数据一致性的。GFS采用的是查表式的数据分布而DynamoDB采用的是计算式的也是一个改进版的通过虚拟结点减少增加结点带来数据迁移的一致性哈希。
这篇文章中有几个关键的概念一个是Vector Clock另一个是Gossip协议。
<li>
[Time, Clocks and the Ordering of Events in a Distributed System](https://www.microsoft.com/en-us/research/publication/time-clocks-ordering-events-distributed-system/) 这篇文章是莱斯利·兰伯特Leslie Lamport于1978年发表的并在2007年被选入SOSP的名人堂被誉为第一篇真正的“分布式系统”论文该论文曾一度成为计算机科学史上被引用最多的文章。分布式系统中的时钟同步是一个非常难的问题因为分布式系统中是使用消息进行通信的若使用物理时钟来进行同步一方面是不同的process的时钟有差异另一方面是时间的计算也有一定的误差这样若有两个时间相同的事件则无法区分它们谁前谁后了。这篇文章主要解决分布式系统中的时钟同步问题。
</li>
<li>
[马萨诸塞大学课程Distributed Operating System](http://lass.cs.umass.edu/~shenoy/courses/spring05/lectures.html) 中第10节 [Clock Synchronization](http://lass.cs.umass.edu/~shenoy/courses/spring05/lectures/Lec10.pdf),这篇讲义讲述了时钟同步的问题。
</li>
<li>
关于Vector Clock你可以看一下[ Why Vector Clocks are Easy](http://basho.com/posts/technical/why-vector-clocks-are-easy/) 和 [Why Vector Clocks are Hard](http://basho.com/posts/technical/why-vector-clocks-are-hard/) 这两篇文章。
</li>
用来做数据同步的Gossip协议的原始论文是 [Efficient Reconciliation and Flow Control for Anti-Entropy Protocols](https://www.cs.cornell.edu/home/rvr/papers/flowgossip.pdf)。Gossip算法也是Cassandra使用的数据复制协议。这个协议就像八卦和谣言传播一样可以“一传十、十传百”传播开来。但是这个协议看似简单细节上却非常麻烦。
Gossip协议也是NoSQL数据库Cassandra中使用到的数据协议你可以上YouTube上看一下这个视频介绍 [Understanding Gossip (Cassandra Internals)](https://www.youtube.com/watch?v=FuP1Fvrv6ZQ)。
关于Gossip的一些图示化的东西你可以看一下动画 [Gossip Visualization](https://rrmoelker.github.io/gossip-visualization/)。
## 分布式存储和数据库
除了前面的Google的BigTable和Google File System那两篇论文还有Amazon的DynamoDB的论文下面也有几篇也是要读一下的。
<li>
一篇是AWS Aurora的论文 [Amazon Aurora: Design Considerations for High Throughput Cloud -Native Relation Databases](http://www.allthingsdistributed.com/files/p1041-verbitski.pdf)。
</li>
<li>
另一篇是比较有代表的论文是Google的 [Spanner: Googles Globally-Distributed Database](http://static.googleusercontent.com/media/research.google.com/zh-CN//archive/spanner-osdi2012.pdf)。 其2017年的新版论文[Spanner, TrueTime &amp; The CAP Theorem](https://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/45855.pdf)。
</li>
<li>
[F1 - The Fault-Tolerant Distributed RDBMS Supporting Googles Ad Business](http://research.google.com/pubs/archive/38125.pdf) 。
</li>
<li>
[Cassandra: A Decentralized Structured Storage System](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.161.6751&amp;rep=rep1&amp;type=pdf) 。
</li>
<li>
<p>[CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data](http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf), 这里提到的算法被应用在了Ceph分布式文件系统中其架构可以读一下 <a href="https://ceph.com/wp-content/uploads/2016/08/weil-rados-pdsw07.pdf">RADOS - A Scalable, Reliable Storage Service for Petabyte-scale<br>
Storage Clusters</a> 以及 [Ceph的架构文档](http://docs.ceph.com/docs/jewel/architecture/)。</p>
</li>
## 分布式消息系统
<li>
分布式消息系统你一定要读一下Kafka的这篇论文 [Kafka: a Distributed Messaging System for Log Processing](http://notes.stephenholiday.com/Kafka.pdf)。
</li>
<li>
[Wormhole: Reliable Pub-Sub to Support Geo-replicated Internet Services](https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-sharma.pdf) Wormhole是Facebook内部使用的一个Pub-Sub系统目前还没有开源。它和Kafka之类的消息中间件很类似。但是它又不像其它的Pub-Sub系统Wormhole没有自己的存储来保存消息它也不需要数据源在原有的更新路径上去插入一个操作来发送消息是非侵入式的。其直接部署在数据源的机器上并直接扫描数据源的transaction logs这样还带来一个好处Wormhole本身不需要做任何地域复制geo-replication策略只需要依赖于数据源的geo-replication策略即可。
</li>
<li>
[All Aboard the Databus! LinkedIns Scalable Consistent Change Data Capture Platform](https://engineering.linkedin.com/research/2012/all-aboard-the-databus-linkedlns-scalable-consistent-change-data-capture-platform) 在LinkedIn投稿SOCC 2012的这篇论文中指出支持对不同数据源的抽取允许不同数据源抽取器的开发和接入只需该抽取器遵循设计规范即可。该规范的一个重要方面就是每个数据变化都必须被一个单调递增的数字标注SCN用于同步。这其中的一些方法完全可以用做异地双活的系统架构中。和这篇论文相关的几个链接如下[PDF论文](https://915bbc94-a-62cb3a1a-s-sites.googlegroups.com/site/acm2012socc/s18-das.pdf?attachauth=ANoY7cpF7igQlU-DGe3gMeW4PZr0cnRDm6cFsuJnv8n5LtJqYrEE9TMMzctK8P9OUTzPD-M2efmpes3zsc10VXN0g6RmdqTpSv3YwgUIW08RBmUvv3XMpUhEAiHkLdrzqC5thiAu5kyskHhkflK3wPYPvA6PeH4uM_XD3u4Quo0MR87BXnE_TcmnRnPzUzNAAYLng2K5t5elUuTj9NaU4o8QSfFX8edgwA%3D%3D&amp;attredirects=0) 、 [PPT分享](https://www.slideshare.net/amywtang/databus-socc-v3)。)
</li>
## 日志和数据
<li>
[The Log: What every software engineer should know about real-time datas unifying abstraction](https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying) ,这篇文章好长,不过这是一篇非常好非常好的文章,这是每个工程师都应用知道的事,必看啊。你可以看中译版《[日志:每个软件工程师都应该知道的有关实时数据的统一概念](https://github.com/oldratlee/translations/blob/master/log-what-every-software-engineer-should-know-about-real-time-datas-unifying/README.md)》。
</li>
<li>
[The Log-Structured Merge-Tree (LSM-Tree)](https://www.cs.umb.edu/~poneil/lsmtree.pdf) N多年前谷歌发表了 Bigtable的论文论文中很多很酷的方面其一就是它所使用的文件组织方式这个方法更一般的名字叫Log Structured-Merge Tree。LSM是当前被用在许多产品的文件结构策略HBase、Cassandra、LevelDB、SQLite甚至在MongoDB 3.0中也带了一个可选的LSM引擎Wired Tiger实现的。LSM有趣的地方是它抛弃了大多数数据库所使用的传统文件组织方法。实际上当你第一次看它时是违反直觉的。这篇论文可以让你明白这个技术。如果读起来有些费解的话你可以看看中文社区里的这几篇文章[文章一](http://www.cnblogs.com/siegfang/archive/2013/01/12/lsm-tree.html)、[文章二](https://kernelmaker.github.io/lsm-tree)。)
</li>
<li>
[Immutability Changes Everything](http://cidrdb.org/cidr2015/Papers/CIDR15_Paper16.pdf) 这篇论文是现任Salesforce软件架构师帕特·赫兰德Pat Helland在CIDR 2015大会上发表的[相关视频演讲](https://vimeo.com/52831373))。
</li>
<li>
[Tango: Distributed Data Structures over a Shared Log](https://www.microsoft.com/en-us/research/wp-content/uploads/2013/11/Tango.pdf)。这个论文非常经典其中说明了不可变性immutability架构设计的优点。随着为海量数据集存储和计算而设计的以数据为中心的新型抽象技术的出现分布式系统比以往任何时候都更容易构建。但是对于元数据的存储和访问不存在类似的抽象。
为了填补这一空白Tango为开发人员提供了一个由共享日志支持的内存复制数据结构例如地图或树的抽象。Tango对象易于构建和使用通过共享日志上简单的追加和读取操作来复制状态而不是复杂的分布式协议。在这个过程中它们从共享日志中获得诸如线性化、持久性和高可用性等属性。Tango还利用共享日志支持跨不同对象的快速事务处理允许应用程序跨机器进行状态划分并在不牺牲一致性的情况下扩展到底层日志的上限。
</li>
## 分布式监控和跟踪
- Google的分布式跟踪监控论文 - [Dapper, a Large-Scale Distributed Systems Tracing Infrastructure](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf) 其开源实现有三个 [Zipkin](http://zipkin.io/)、[Pinpoint](https://github.com/naver/pinpoint) 和 [HTrace](http://htrace.incubator.apache.org/)。我个人更喜欢Zipkin。
## 数据分析
<li>
[The Unified Logging Infrastructure for Data Analytics at Twitter](http://vldb.org/pvldb/vol5/p1771_georgelee_vldb2012.pdf) Twitter公司的一篇关于日志架构和数据分析的论文。
</li>
<li>
[Scaling Big Data Mining Infrastructure: The Twitter Experience](http://www.datascienceassn.org/sites/default/files/Scaling%20Big%20Data%20Mining%20Infrastructure%20-%20The%20Twitter%20Experience.pdf) 讲Twitter公司的数据分析平台在数据量越来越大架构越来越复杂业务需求越来越多的情况下数据分析从头到底是怎么做的。
</li>
<li>
[Dremel: Interactive Analysis of Web-Scale Datasets](http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/36632.pdf)Google公司的Dremel是一个针对临时查询提供服务的系统它处理的是只读的多层数据。本篇文章介绍了它的架构与实现以及它与MapReduce是如何互补的。
</li>
<li>
[Resident Distributed Datasets: a Fault-Tolerant Abstraction for In-Memory Cluster Computing](https://www.usenix.org/system/files/conference/nsdi12/nsdi12-final138.pdf)这篇论文提出了弹性分布式数据集Resilient Distributed DatasetRDD的概念它是一个分布式存储抽象使得程序员可以在大型集群上以容错的方式执行内存计算解释了其出现原因解决之前计算框架在迭代算法和交互式数据挖掘工具两种应用场景下处理效率低下的问题并指出将数据保存在内存中可以将性能提高一个数量级同时阐述了其实现原理及应用场景等多方面内容。很有趣儿推荐阅读。
</li>
## 与编程相关的论文
- [Distributed Programming Model](http://web.cs.ucdavis.edu/~pandey/Research/Papers/icdcs01.pdf)
- [PSync: a partially synchronous language for fault-tolerant distributed algorithms](http://www.di.ens.fr/~cezarad/popl16.pdf)
- [Programming Models for Distributed Computing](http://heather.miller.am/teaching/cs7680/)
- [Logic and Lattices for Distributed Programming](http://db.cs.berkeley.edu/papers/UCB-lattice-tr.pdf)
## 其它的分布式论文阅读列表
除了上面上的那些我觉得不错的论文,下面还有三个我觉得不错的分布式系统论文的阅读列表,你可以浏览一下。
- [Services Engineering Reading List](https://github.com/mmcgrana/services-engineering)
- [Readings in Distributed Systems](http://christophermeiklejohn.com/distributed/systems/2013/07/12/readings-in-distributed-systems.html)
- [Google Research - Distributed Systems and Parallel Computing](https://ai.google/research/pubs/?area=DistributedSystemsandParallelComputing)
# 小结
今天分享的内容是分布式架构方面的经典图书和论文,并给出了导读文字,几乎涵盖了分布式系统架构方面的所有关键的理论知识。这些内容非常重要,是学好分布式架构的基石,请一定要认真学习。
下篇文章中,我们将讲述分布式架构工程设计方面的内容,包括设计原则、设计模式以及工程实践等方面的内容。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,334 @@
<audio id="audio" title="83 | 程序员练级攻略:分布式架构工程设计" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/c8/f6/c83bb40f93c1e2a1b3bae5d2771778f6.mp3"></audio>
要学好分布式架构,你首先需要学习一些架构指导性的文章和方法论,即分布式架构设计原则。下面是几篇很不错的文章,值得一读。
<li>
[Designs, Lessons and Advice from Building Large Distributed Systems](https://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf)Google 杰夫·迪恩Jeff Dean2009年一次演讲的PPT。2010年斯坦福大学请杰夫·迪恩到大学里给他们讲了一节课你可以在YouTube上看一下[Building Software Systems At Google and Lessons Learned](https://www.youtube.com/watch?v=modXC5IWTJI) 其回顾了Google发展的历史。
</li>
<li>
[The Twelve-Factor App](https://12factor.net/) 如今软件通常会作为一种服务来交付它们被称为网络应用程序或软件即服务SaaS。12-Factor 为构建SaaS应用提供了方法论是架构师必读的文章。[中译版](https://12factor.net/zh_cn/))这篇文章在业内的影响力很大,必读!
</li>
<li>
[Notes on Distributed Systems for Young Bloods](http://www.somethingsimilar.com/2013/01/14/notes-on-distributed-systems-for-young-bloods/) ,给准备进入分布式系统领域的人的一些忠告。
</li>
<li>
[On Designing and Deploying Internet-Scale Services](https://www.usenix.org/legacy/event/lisa07/tech/full_papers/hamilton/hamilton_html/index.html)[中译版](http://darktea.github.io/notes/2014/07/23/On-Designing-and-Deploying-Internet-Scale-Services.html)微软Windows Live服务平台的一些经验性的总结文章很值得一读。
</li>
<li>
[4 Things to Keep in Mind When Building a Platform for the Enterprise](https://blog.box.com/blog/4-things-to-keep-in-mind-when-building-a-platform-for-the-enterprise/) Box平台VP海蒂·威廉姆斯Heidi Williams撰写的一篇文章阐述了为企业构建平台时需要牢记的四件关于软件设计方面的事1. Design Broadly, Build Narrowly 2. Platforms Are Powerful and Flexible. Choose wisely what to expose when!3. Build Incrementally, Get Feedback, and Iterate4. Create a Platform-first Mentality。文章中有详细的解读推荐看看。
</li>
<li>
[Principles of Chaos Engineering](https://www.usenix.org/conference/srecon17americas/program/presentation/rosenthal) 我们知道Netflix公司有一个叫Chaos Monkey的东西这个东西会到分布式系统里“瞎搞”以此来测试系统的健壮和稳定性。这个视频中Netflix分享了一些软件架构的经验和原则值得一看。
</li>
<li>
[Building Fast &amp; Resilient Web Applications](https://www.igvita.com/2016/05/20/building-fast-and-resilient-web-applications/) 伊利亚·格里高利克Ilya Grigorik在Google I/O 2016上的一次关于如何通过弹力设计来实现快速和可容错的网站架构的演讲其中有好些经验分享。
</li>
<li>
[Design for Resiliency](http://highscalability.com/blog/2012/12/31/designing-for-resiliency-will-be-so-2013.html) 这篇文章带我们全面认识“弹力Resiliency以及弹力对于系统的重要性并详细阐述了如何设计和实现系统的弹力。
</li>
<li>
微软的Azure网站上有一系列的 [Design Principle](https://docs.microsoft.com/en-us/azure/architecture/guide/design-principles/) 的文章,你可以看看这几篇: [Design for Self-healing](https://docs.microsoft.com/en-us/azure/architecture/guide/design-principles/self-healing) 、[Design for Scaling Out](https://docs.microsoft.com/en-us/azure/architecture/guide/design-principles/scale-out) 和 [Design for Evolution](https://docs.microsoft.com/en-us/azure/architecture/guide/design-principles/design-for-evolution) 。
</li>
<li>
[Eventually Consistent](https://www.allthingsdistributed.com/2008/12/eventually_consistent.html) AWS CTO维尔纳·沃格尔斯Werner Vogels发布在自己Blog上的一篇关于最终一致性的好文。
</li>
<li>
[Writing Code that Scales](https://www.codeproject.com/Articles/151520/Write-Scalable-Code) Rackspace的一篇很不错的博文告诉我们一些很不错的写出高扩展和高性能代码的工程原则。
</li>
<li>
[Automate and Abstract: Lessons from Facebook on Engineering for Scale](https://architecht.io/lessons-from-facebook-on-engineering-for-scale-f5716f0afc7a) 软件自动化和软件抽象这是软件工程中最重要的两件事了。通过这篇文章我们可以看到Facebook的关于这方面的一些经验教训。
</li>
# 设计模式
有了方法论后,你还需要学习一些比较细节的落地的技术。最好的方式就是学习被前人总结出来的设计模式,虽然设计模式也要分场景,但是设计模式可以让你知道一些套路,这些套路对于我们设计的分布式系统有非常大的帮助,不但可以让我们少走一些弯路,而且还能让我们更为系统和健壮地设计我们的架构。
下面是一些分布式架构设计模式的网站。
首先,需要重点推荐的是微软云平台 Azure 上的设计模式。 [Cloud Design Patterns](https://docs.microsoft.com/en-us/azure/architecture/patterns/) ,这个网站上罗列了分布式设计的各种设计模式,可以说是非常全面和完整。对于每一个模式都有详细的说明,并有对其优缺点的讨论,以及适用场景和不适用场景的说明,实在是一个非常不错的学习分布式设计模式的地方。其中有如下分类。
- [设计模式:可用性](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/availability)
- [设计模式:数据管理](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/data-management)
- [设计模式:设计和实现](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/design-implementation)
- [设计模式:消息](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/messaging)
- [设计模式:管理和监控](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/management-monitoring)
- [设计模式:性能和扩展](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/performance-scalability)
- [设计模式:系统弹力](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/resiliency)
- [设计模式:安全](https://docs.microsoft.com/en-us/azure/architecture/patterns/category/security)。
除此之外,还有其它的一些关于分布式系统设计模式的网站和相关资料。
<li>
[AWS Cloud Pattern](http://en.clouddesignpattern.org/index.php/Main_Page) 这里收集了AWS云平台的一些设计模式。
</li>
<li>
[Design patterns for container-based distributed systems](https://research.google.com/pubs/archive/45406.pdf) 这是Google给的一篇论文其中描述了容器化下的分布式架构的设计模式。
</li>
<li>
[Patterns for distributed systems](https://www.slideshare.net/pagsousa/patterns-fro-distributed-systems) 这是一个PPT其中讲了一些分布式系统的架构模式你可以顺着到Google里去搜索。
</li>
我个人觉得微服务也好SOA也好都是分布式系统的一部分这里有两个网站罗列了各种各样的服务架构模式。
<li>
[A Pattern Language for Micro-Services](http://microservices.io/patterns/index.html)
</li>
<li>
[SOA Patterns](http://soapatterns.org/)。
</li>
当然,还有我在极客时间上写的那些分布式的设计模式的总结。
<li>
**弹力设计篇**,内容包括:认识故障和弹力设计、隔离设计、异步通讯设计、幂等性设计、服务的状态、补偿事务、重试设计、熔断设计、限流设计、降级设计、弹力设计总结。
</li>
<li>
**管理设计篇**,内容包括:分布式锁、配置中心、边车模式、服务网格、网关模式、部署升级策略等。
</li>
<li>
**性能设计篇**,内容包括:缓存、异步处理、数据库扩展、秒杀、边缘计算等。
</li>
# 设计与工程实践
## 分布式系统的故障测试
<li>
[FIT: Failure Injection Testing](https://medium.com/netflix-techblog/fit-failure-injection-testing-35d8e2a9bb2) Netflix公司的一篇关于做故障注入测试的文章。
</li>
<li>
[Automated Failure Testing](https://medium.com/netflix-techblog/automated-failure-testing-86c1b8bc841f) 同样来自Netflix公司的自动化故障测试的一篇博文。
</li>
<li>
[Automating Failure Testing Research at Internet Scale](https://people.ucsc.edu/~palvaro/socc16.pdf) Netflix公司伙同圣克鲁斯加利福尼亚大学和Gremlin游戏公司一同撰写的一篇论文。
</li>
## 弹性伸缩
<li>
[4 Architecture Issues When Scaling Web Applications: Bottlenecks, Database, CPU, IO](http://highscalability.com/blog/2014/5/12/4-architecture-issues-when-scaling-web-applications-bottlene.html) 本文讲解了后端程序的主要性能指标即响应时间和可伸缩性这两者如何能提高的解决方案讨论了包括纵向和横向扩展可伸缩架构、负载均衡、数据库的伸缩、CPU密集型和I/O密集型程序的考量等。
</li>
<li>
[Scaling Stateful Objects](http://ithare.com/scaling-stateful-objects/) 这是一本叫《Development&amp;Deployment of Multiplayer Online Games》书中一章内容的节选讨论了有状态和无状态的节点如何伸缩的问题。虽然还没有写完但是可以给你一些很不错的基本概念和想法。
</li>
<li>
[Scale Up vs Scale Out: Hidden Costs](https://blog.codinghorror.com/scaling-up-vs-scaling-out-hidden-costs/) Coding Horror上的一篇有趣的文章详细分析了可伸缩性架构的不同扩展方案横向扩展或纵向扩展所带来的成本差异帮助你更好地选择合理的扩展方案可以看看。
</li>
<li>
[Best Practices for Scaling Out](https://www.infoq.cn/article/hiXg6WRDjvNE0VNuwzPg) OpenShift的一篇讨论Scale out最佳实践的文章。
</li>
<li>
[Scalability Worst Practices](https://www.infoq.com/articles/scalability-worst-practices) ,这篇文章讨论了一些最差实践,你需要小心避免。
</li>
<li>
[Reddit: Lessons Learned From Mistakes Made Scaling To 1 Billion Pageviews A Month](http://highscalability.com/blog/2013/8/26/reddit-lessons-learned-from-mistakes-made-scaling-to-1-billi.html) Reddit分享的一些关于系统扩展的经验教训。
</li>
<li>
下面是几篇关于自动化弹性伸缩的文章。
<ul>
- [Autoscaling Pinterest](https://medium.com/@Pinterest_Engineering/auto-scaling-pinterest-df1d2beb4d64)
- [Square: Autoscaling Based on Request Queuing](https://medium.com/square-corner-blog/autoscaling-based-on-request-queuing-c4c0f57f860f)
- [PayPal: Autoscaling Applications](https://medium.com/paypal-engineering/autoscaling-applications-paypal-fb5bb9fdb821)
- [Trivago: Your Definite Guide For Autoscaling Jenkins](http://tech.trivago.com/2017/02/17/your-definite-guide-for-autoscaling-jenkins/)
- [Scryer: Netflixs Predictive Auto Scaling Engine](https://medium.com/netflix-techblog/scryer-netflixs-predictive-auto-scaling-engine-a3f8fc922270)。
## 一致性哈希
<li>
[Consistent Hashing](http://www.tom-e-white.com/2007/11/consistent-hashing.html) ,这是一个一致性哈希的简单教程,其中还有代码示例。
</li>
<li>
[Consistent Hashing: Algorithmic Tradeoffs](https://medium.com/@dgryski/consistent-hashing-algorithmic-tradeoffs-ef6b8e2fcae8) ,这篇文章讲述了一致性哈希的一些缺陷和坑,以及各种哈希算法的性能比较,最后还给了一组代码仓库,其中有各种哈希算法的实现。
</li>
<li>
[Distributing Content to Open Connect](https://medium.com/netflix-techblog/distributing-content-to-open-connect-3e3e391d4dc9) Netflix的一个对一致性哈希的实践提出了Uniform Consistent Hashing是挺有意思的一篇文章。
</li>
<li>
[Consistent Hashing in Cassandra](https://blog.imaginea.com/consistent-hashing-in-cassandra/) 这是Cassandra中使用到的一致性哈希的相关设计。
</li>
## 数据库分布式
<li>
[Life Beyond Distributed Transactions](https://queue.acm.org/detail.cfm?id=3025012) 该文是Salesforce的软件架构师帕特·赫兰德Pat Helland于2016年12月发表的针对其在2007年CIDR创新数据库研究会议上首次发表的同名文章的更新和缩写版本。业界谈到分布式事务通常指两段提交2PC事务Spring/JEE中JTA等)或者Paxos与Raft这些事务都有明显缺点和局限性。
而赫兰德在本文讨论的是另外一种基于本地事务情况下的事务机制它是基于实体和活动Activity的概念其实类似DDD聚合根和领域事件的概念这种工作流类型事务虽然需要程序员介入依靠消息系统实现但可以实现接近无限扩展的大型系统。赫兰德文中提出了重要的观点“如果你不能使用分布式事务那么你就只能使用工作流。”
</li>
<li>
[How Sharding Works](https://medium.com/@jeeyoungk/how-sharding-works-b4dec46b3f6) 这是一篇很不错的探讨数据Sharding的文章。基本上来说数据Sharding可能的问题都在这篇文章里谈到了。
</li>
<li>
[Why you dont want to shard](https://www.percona.com/blog/2009/08/06/why-you-dont-want-to-shard/) 这是Percona的一篇文章其中表达了不到万不得已不要做数据库分片。是的最好还是先按业务来拆分先把做成微服务的架构然后把数据集变简单然后再做Sharding会更好。
</li>
<li>
[How to Scale Big Data Applications](https://www.percona.com/sites/default/files/presentations/How%20to%20Scale%20Big%20Data%20Applications.pdf) 这也是Percona给出的一篇关于怎样给大数据应用做架构扩展的文章。值得一读。
</li>
<li>
[MySQL Sharding with ProxySQL](https://www.percona.com/blog/2016/08/30/mysql-sharding-with-proxysql/) 用ProxySQL来支撑MySQL数据分片的一篇实践文章。
</li>
## 缓存
<li>
[缓存更新的套路](https://coolshell.cn/articles/17416.html)这是我在CoolShell上写的缓存更新的几个设计模式包括Cache Aside、Read/Write Through、Write Behind Caching。
</li>
<li>
[Design Of A Modern Cache](http://highscalability.com/blog/2016/1/25/design-of-a-modern-cache.html) ,设计一个现代化的缓存系统需要注意到的东西。
</li>
<li>
[Netflix: Caching for a Global Netflix](https://medium.com/netflix-techblog/caching-for-a-global-netflix-7bcc457012f1) Netflix公司的全局缓存架构实践。
</li>
<li>
[Facebook: An analysis of Facebook photo caching](https://code.facebook.com/posts/220956754772273/an-analysis-of-facebook-photo-caching/) Facebook公司的图片缓存使用分析这篇文章挺有意思的用数据来调优不同的缓存大小和算法。
</li>
<li>
[How trivago Reduced Memcached Memory Usage by 50%](https://tech.trivago.com/2017/12/19/how-trivago-reduced-memcached-memory-usage-by-50/) Trivago公司一篇分享自己是如何把Memcached的内存使用率降了一半的实践性文章。很有意思可以让你学到很多东西。
</li>
<li>
[Caching Internal Service Calls at Yelp](https://engineeringblog.yelp.com/2018/03/caching-internal-service-calls-at-yelp.html) Yelp公司的缓存系统架构。
</li>
## 消息队列
<li>
[Understanding When to use RabbitMQ or Apache Kafka](https://content.pivotal.io/blog/understanding-when-to-use-rabbitmq-or-apache-kafka) 什么时候使用RabbitMQ什么时候使用Kafka通过这篇文章可以让你明白如何做技术决策。
</li>
<li>
[Trello: Why We Chose Kafka For The Trello Socket Architecture](https://tech.trello.com/why-we-chose-kafka/) Trello的Kafka架构分享。
</li>
<li>
[LinkedIn: Running Kafka At Scale](https://engineering.linkedin.com/kafka/running-kafka-scale) LinkedIn公司的Kafka架构扩展实践。
</li>
<li>
[Should You Put Several Event Types in the Same Kafka Topic?](https://www.confluent.io/blog/put-several-event-types-kafka-topic/) ,这个问题可能经常困扰你,这篇文章可以为你找到答案。
</li>
<li>
[Billions of Messages a Day - Yelps Real-time Data Pipeline](https://engineeringblog.yelp.com/2016/07/billions-of-messages-a-day-yelps-real-time-data-pipeline.html) Yelp公司每天十亿级实时消息的架构。
</li>
<li>
[Uber: Building Reliable Reprocessing and Dead Letter Queues with Kafka](https://eng.uber.com/reliable-reprocessing/) Uber公司的Kafka应用。
</li>
<li>
[Uber: Introducing Chaperone: How Uber Engineering Audits Kafka End-to-End](https://eng.uber.com/chaperone/) Uber公司对Kafka消息的端到端审计。
</li>
<li>
[Publishing with Apache Kafka at The New York Times](https://open.nytimes.com/publishing-with-apache-kafka-at-the-new-york-times-7f0e3b7d2077) 纽约时报的Kafka工程实践。
</li>
<li>
[Kafka Streams on Heroku](https://blog.heroku.com/kafka-streams-on-heroku) Heroku公司的Kafka Streams实践。
</li>
<li>
[Salesforce: How Apache Kafka Inspired Our Platform Events Architecture](https://engineering.salesforce.com/how-apache-kafka-inspired-our-platform-events-architecture-2f351fe4cf63) Salesforce的Kafka工程实践。
</li>
<li>
[Exactly-once Semantics are Possible: Heres How Kafka Does it](https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how-apache-kafka-does-it/) 怎样用Kafka让只发送一次的语义变为可能。这是业界中一个很难的工程问题。
</li>
<li>
[Delivering billions of messages exactly once](https://segment.com/blog/exactly-once-delivery/) 同上,这也是一篇挑战消息只发送一次这个技术难题的文章。
</li>
<li>
[Benchmarking Streaming Computation Engines at Yahoo!](https://yahooeng.tumblr.com/post/135321837876/benchmarking-streaming-computation-engines-at)。Yahoo!的Storm团队在为他们的流式计算做技术选型时发现市面上缺乏针对不同计算平台的性能基准测试。于是他们研究并设计了一种方案来做基准测试测试了Apache Flink、Apache Storm和Apache Spark这三种平台。文中给出了结论和具体的测试方案。如果原文链接不可用请尝试搜索引擎对该网页的快照。
</li>
## 关于日志方面
<li>
[Using Logs to Build a Solid Data Infrastructure - Martin Kleppmann](https://www.confluent.io/blog/using-logs-to-build-a-solid-data-infrastructure-or-why-dual-writes-are-a-bad-idea/) 设计基于log结构应用架构的一篇不错的文章。
</li>
<li>
[Building DistributedLog: High-performance replicated log service](https://blog.twitter.com/engineering/en_us/topics/infrastructure/2015/building-distributedlog-twitter-s-high-performance-replicated-log-servic.html) Distributed是Twitter 2016年5月份开源的一个分布式日志系统。在Twitter内部已经使用2年多。其主页在 [distributedlog.io](http://distributedlog.io/)。这篇文章讲述了这个高性能日志系统的一些技术细节。另外,其技术负责人是个中国人,其在微信公众号中也分享过这个系统 [Twitter高性能分布式日志系统架构解析](https://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=403051208&idx=1&sn=1694ac05acbcb5ca53c88bfac8a68856&scene=2&srcid=1224xZuQ9QQ4sRmiPVdHTppL)。
</li>
<li>
[LogDevice: a distributed data store for logs](https://code.facebook.com/posts/357056558062811/logdevice-a-distributed-data-store-for-logs/) Facebook分布式日志系统方面的一些工程分享。
</li>
## 关于性能方面
<li>
[Understand Latency](http://highscalability.com/latency-everywhere-and-it-costs-you-sales-how-crush-it) 这篇文章收集并整理了一些和系统响应时间相关的文章可以让你全面了解和Latency有关的系统架构和设计经验方面的知识。
</li>
<li>
[Common Bottlenecks](http://highscalability.com/blog/2012/5/16/big-list-of-20-common-bottlenecks.html) 文中讲述了20个常见的系统瓶颈。
</li>
<li>
[Performance is a Feature](https://blog.codinghorror.com/performance-is-a-feature/) Coding Horror上的一篇让你关注性能的文章。
</li>
<li>
[Make Performance Part of Your Workflow](https://codeascraft.com/2014/12/11/make-performance-part-of-your-workflow/) ,这篇文章是图书《[Designing for Performance](http://shop.oreilly.com/product/0636920033578.do)》中的节选(国内没有卖的),其中给出来了一些和性能有关的设计上的平衡和美学。
</li>
<li>
[CloudFlare: How we built rate limiting capable of scaling to millions of domains](https://blog.cloudflare.com/counting-things-a-lot-of-different-things/)讲述了CloudFlare公司是怎样实现他们的限流功能的。从最简单的每客户IP限流开始分析进一步讲到anycast在这种情况下PoP的分布式限流是怎样实现的并详细解释了具体的算法。
</li>
## 关于搜索方面
- [Instagram: Search Architecture](https://instagram-engineering.com/search-architecture-eeb34a936d3a)
- [eBay: The Architecture of eBay Search](http://www.cs.otago.ac.nz/homepages/andrew/papers/2017-8.pdf)
- [eBay: Improving Search Engine Efficiency by over 25%](https://www.ebayinc.com/stories/blogs/tech/making-e-commerce-search-faster/)
- [LinkedIn: Introducing LinkedIns new search architecture](https://engineering.linkedin.com/search/did-you-mean-galene)
- [LinkedIn: Search Federation Architecture at LinkedIn](https://engineering.linkedin.com/blog/2018/03/search-federation-architecture-at-linkedin)
- [Slack: Search at Slack](https://slack.engineering/search-at-slack-431f8c80619e)
- [DoorDash: Search and Recommendations at DoorDash](https://blog.doordash.com/powering-search-recommendations-at-doordash-8310c5cfd88c)
- [Twitter: Search Service at Twitter (2014)](https://blog.twitter.com/engineering/en_us/a/2014/building-a-complete-tweet-index.html)
- [Pinterest: Manas: High Performing Customized Search System](https://medium.com/@Pinterest_Engineering/manas-a-high-performing-customized-search-system-cf189f6ca40f)
- [Sherlock: Near Real Time Search Indexing at Flipkart](https://tech.flipkart.com/sherlock-near-real-time-search-indexing-95519783859d)
- [Airbnb: Nebula: Storage Platform to Build Search Backends](https://medium.com/airbnb-engineering/nebula-as-a-storage-platform-to-build-airbnbs-search-backends-ecc577b05f06)
## 各公司的架构实践
[High Scalability](http://highscalability.com/) ,这个网站会定期分享一些大规模系统架构是怎样构建的,下面是迄今为止各个公司的架构说明。
- [YouTube Architecture](http://highscalability.com/youtube-architecture)
- [Scaling Pinterest](http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html)
- [Google Architecture](http://highscalability.com/google-architecture)
- [Scaling Twitter](http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster)
- [The WhatsApp Architecture](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html)
- [Flickr Architecture](http://highscalability.com/flickr-architecture)
- [Amazon Architecture](http://highscalability.com/amazon-architecture)
- [Stack Overflow Architecture](http://highscalability.com/blog/2009/8/5/stack-overflow-architecture.html)
- [Pinterest Architecture](http://highscalability.com/blog/2012/5/21/pinterest-architecture-update-18-million-visitors-10x-growth.html)
- [Tumblr Architecture](http://highscalability.com/blog/2012/2/13/tumblr-architecture-15-billion-page-views-a-month-and-harder.html)
- [Instagram Architecture](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html)
- [TripAdvisor Architecture](http://highscalability.com/blog/2011/6/27/tripadvisor-architecture-40m-visitors-200m-dynamic-page-view.html)
- [Scaling Mailbox](http://highscalability.com/blog/2013/6/18/scaling-mailbox-from-0-to-one-million-users-in-6-weeks-and-1.html)
- [Salesforce Architecture ](http://highscalability.com/blog/2013/9/23/salesforce-architecture-how-they-handle-13-billion-transacti.html)
- [ESPN Architecture](http://highscalability.com/blog/2013/11/4/espns-architecture-at-scale-operating-at-100000-duh-nuh-nuhs.html)
- [Uber Architecture](http://highscalability.com/blog/2015/9/14/how-uber-scales-their-real-time-market-platform.html)
- [Dropbox Design](https://www.youtube.com/watch?v=PE4gwstWhmc)
- [Splunk Architecture](http://www.splunk.com/view/SP-CAAABF9)
# 小结
今天我们分享的内容是高手成长篇分布式架构部分的最后一篇——分布式架构工程设计,讲述了设计原则、设计模式等方面的内容,尤其整理和推荐了国内外知名企业的设计思路和工程实践,十分具有借鉴意义。
下篇文章中,我们将分享微服务架构方面的内容。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,160 @@
<audio id="audio" title="84 | 程序员练级攻略:微服务" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/0e/c3/0ee1d747f31fe4e39745b520d3a66ec3.mp3"></audio>
微服务是分布式系统中最近比较流行的架构模型也是SOA架构的一个进化。微服务架构并不是银弹所以也不要寄希望于微服务架构能够解决所有的问题。微服务架构主要解决的是如何快速地开发和部署我们的服务这对于一个能够适应快速开发和成长的公司是非常必要的。同时我也觉得微服务中有很多很不错的想法和理念所以学习微服务是每一个技术人员迈向卓越的架构师的必经之路。
首先你需要看一下Martin Fowler的这篇关于微服务架构的文档 - [Microservice Architecture](http://martinfowler.com/articles/microservices.html) [中译版](https://blog.csdn.net/wurenhai/article/details/37659335)这篇文章说明了微服务的架构与传统架构的不同之处在于微服务的每个服务与其数据库都是独立的可以无依赖地进行部署。你也可以看看Martin Fowler老人家现身说法的[视频](https://www.youtube.com/watch?v=wgdBVIX9ifA)。
另外,你还可以简单地浏览一下,各家对微服务的理解。
- [AWS的理解 - What are Microservices?](https://aws.amazon.com/microservices/)。
- [Microsoft的理解 - Microservices architecture style](https://docs.microsoft.com/en-us/azure/architecture/guide/architecture-styles/microservices)。
- [Pivotal的理解 - Microservices](https://pivotal.io/microservices)。
# 微服务架构
接下来,你可以看一下 [IBM红皮书Microservices Best Practices for Java](https://www.redbooks.ibm.com/redbooks/pdfs/sg248357.pdf) 这本书非常好不但有通过把Spring Boot和 Dropwizard来架建Java的微服务而且还谈到了一些标准的架构模型如服务注册、服务发现、API网关、服务通讯、数据处理、应用安全、测试、部署、运维等是相当不错的一本书。
当然,有一本书你也可以读一下—— [微服务设计](https://book.douban.com/subject/26772677/)。这本书全面介绍了微服务的建模、集成、测试、部署和监控,通过一个虚构的公司讲解了如何建立微服务架构。主要内容包括认识微服务在保证系统设计与组织目标统一上的重要性,学会把服务集成到已有系统中,采用递增手段拆分单块大型应用,通过持续集成部署微服务,等等。
与此相似的,也有其它的一系列文章,值得一读。
下面是Nginx上的一组微服务架构的系列文章。
- [Introduction to Microservices](https://www.nginx.com/blog/introduction-to-microservices/)
- [Building Microservices: Using an API Gateway](https://www.nginx.com/blog/building-microservices-using-an-api-gateway/)
- [Building Microservices: Inter-Process Communication in a Microservices Architecture](https://www.nginx.com/blog/building-microservices-inter-process-communication/)
- [Service Discovery in a Microservices Architecture](https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/)
- [Event-Driven Data Management for Microservices](https://www.nginx.com/blog/event-driven-data-management-microservices/)
- [Choosing a Microservices Deployment Strategy](https://www.nginx.com/blog/deploying-microservices/)
- [Refactoring a Monolith into Microservices](https://www.nginx.com/blog/refactoring-a-monolith-into-microservices/)
下面这是 [Auto0 Blog](https://auth0.com/blog/) 上一系列的微服务的介绍,有代码演示。
- [An Introduction to Microservices, Part 1](https://auth0.com/blog/an-introduction-to-microservices-part-1/)
- [API Gateway. An Introduction to Microservices, Part 2](https://auth0.com/blog/an-introduction-to-microservices-part-2-API-gateway/)
- [An Introduction to Microservices, Part 3: The Service Registry](https://auth0.com/blog/an-introduction-to-microservices-part-3-the-service-registry/)
- [Intro to Microservices, Part 4: Dependencies and Data Sharing](https://auth0.com/blog/introduction-to-microservices-part-4-dependencies/)
- [API Gateway: the Microservices Superglue](https://auth0.com/blog/apigateway-microservices-superglue/)
还有Dzone的这个Spring Boot的教程。
- [Microservices With Spring Boot - Part 1 - Getting Started](https://dzone.com/articles/microservices-with-spring-boot-part-1-getting-star)
- [Microservices With Spring Boot - Part 2 - Creating a Forex Microservice](https://dzone.com/articles/microservices-with-spring-boot-part-2-creating-a-f)
- [Microservices With Spring Boot - Part 3 - Creating Currency Conversion Microservice](https://dzone.com/articles/microservices-with-spring-boot-part-3-creating-cur)
- [Microservices With Spring Boot - Part 4 - Using Ribbon for Load Balancing](https://dzone.com/articles/microservices-with-spring-boot-part-4-using-ribbon)
- [Microservices With Spring Boot - Part 5 - Using Eureka Naming Server](https://dzone.com/articles/microservices-with-spring-boot-part-5-using-eureka)
当然,如果你要玩得时髦一些的话,我推荐你使用下面的这套架构。
<li>
**前端**[React.js](https://reactjs.org/) 或 [Vue.js](https://vuejs.org/)。
</li>
<li>
**后端**[Go语言](https://golang.org/) + 微服务工具集 [Go kit](https://gokit.io/) 因为是微服务了所以每个服务的代码就简单了。既然简单了也就可以用任何语言了所以我推荐Go语言。
</li>
<li>
**通讯**[gRPC](https://grpc.io/)这是Google远程调用的一个框架它比Restful的调用要快20倍到50倍的样子。
</li>
<li>
**API**[Swagger](https://swagger.io/) Swagger是一种Restful API的简单但强大的表示方式标准的语言无关这种表示方式不但人可读而且机器可读。可以作为Restful API的交互式文档也可以作为Restful API形式化的接口描述生成客户端和服务端的代码。今天所有的API应该都通过Swagger来完成。
</li>
<li>
**网关**[Envoy](https://envoyproxy.github.io/) 其包含了服务发现、负载均衡和熔断等这些特性也是一个很有潜力的网关。当然Kubernetes也是很好的而且它也是高扩展的所以完全可以把Envoy通过Ingress集成进Kubernetes。这里有一个开源项目就是干这个事的 - [contour](https://github.com/heptio/contour)。
</li>
<li>
**日志监控**[fluentd](https://www.fluentd.org/) + [ELK](https://www.elastic.co/webinars/introduction-elk-stack) 。
</li>
<li>
**指标监控**[Prometheus](https://prometheus.io/) 。
</li>
<li>
**调用跟踪**[Jaeger](http://jaeger.readthedocs.io/en/latest/) 或是 [Zipkin](http://zipkin.io/)当然后者比较传统一些前者比较时髦最重要的是其可以和Prometheus和Envory集成。
</li>
<li>
**自动化运维**[Docker](https://docker.io/) + [Kubernetes](https://kubernetes.io/) 。
</li>
# 微服务和SOA
在对微服务有了一定的认识以后一定有很多同学分不清楚微服务和SOA架构对此你可以看一下这本电子书 - 《[Microservices vs. Service-Oriented Architecture](https://www.nginx.com/resources/library/microservices-vs-soa/)》。通过这本书你可以学到服务化架构的一些事实还有基础的SOA和微服务的架构知识以及两种架构的不同。这本书的作者马克·理查兹Mark Richards同学拥有十年以上的SOA和微服务架构的设计和实现的经验。
另外还有几篇其它对比SOA和微服务的文章你也可以看看。
- [DZone: Microservices vs. SOA](https://dzone.com/articles/microservices-vs-soa-2)
- [DZone: Microservices vs. SOA - Is There Any Difference at All?](https://dzone.com/articles/microservices-vs-soa-is-there-any-difference-at-al)
- [Microservices, SOA, and APIs: Friends or enemies?](https://www.ibm.com/developerworks/websphere/library/techarticles/1601_clark-trs/1601_clark.html)
除此之外,我们还需要知道微服务和其它架构的一些不同和比较,这样我们就可以了解微服务架构的优缺点。下面几篇文章将帮助获得这些知识。
- [PaaS vs. IaaS for Microservices Architectures: Top 6 Differences](http://blog.altoros.com/microservices-architectures-paas-vs-iaas-top-6-differences.html)
- [Microservices vs. Monolithic Architectures: Pros, Cons, and How Cloud Foundry (PaaS) Can Help](https://www.slideshare.net/altoros/microservices-vs-monolithic-architectures-pros-and-cons)
- [Microservices - Not A Free Lunch!](http://highscalability.com/blog/2014/4/8/microservices-not-a-free-lunch.html)
- [The Hidden Costs Of Microservices](https://www.stackbuilders.com/news/the-hidden-costs-of-microservices)
# 设计模式和最佳实践
然后,你可以看一下微服务的一些设计模式。
<li>
[Microservice Patterns](http://microservices.io/),微服务架构的设计模式和最佳实践。
</li>
<li>
[Microservice Antipatterns and Pitfalls](https://www.oreilly.com/ideas/microservices-antipatterns-and-pitfalls),微服务架构的一些已知的反模式和陷阱。
</li>
<li>
[Microservice Architecture: All The Best Practices You Need To Know](https://codingsans.com/blog/microservice-architecture-best-practices),这是一篇长文,里面讲述了什么是微服务、微服务架构的优缺点、微服务最大的挑战和解决方案是什么、如何避免出错,以及构建微服务架构的最佳实践等多方面的内容。推荐阅读。
</li>
<li>
[Best Practices for Building a Microservice Architecture](https://www.vinaysahni.com/best-practices-for-building-a-microservice-architecture) ,这篇文章分享了构建微服务架构的最佳实践。
</li>
<li>
[Simplicity by Distributing Complexity](https://jobs.zalando.com/tech/blog/simplicity-by-distributing-complexity/),这是一篇讲如何使用事件驱动构建微服务架构的文章,其中有很多不错的设计上的基本原则。
</li>
# 相关资源
<li>
[Microservices Resource Guide](http://martinfowler.com/microservices/) 这个网页上是Martin Fowler为我们挑选的和微服务相关的文章、视频、书或是podcast。
</li>
<li>
[Awesome Microservices](https://github.com/mfornos/awesome-microservices/) ,一个各种微服务资源和相关项目的集中地。
</li>
# 小结
好了总结一下今天的内容。我认为微服务中有很多很不错的想法和理念所以学习微服务是每一个技术人员迈向卓越的架构师的必经之路。在这篇文章中我先给出了AWS、Microsoft和Pivotal对微服务的理解然后给出了好几个系列的教程帮你全面学习和理解微服务架构然后通过一系列文章帮你来区分何为微服务何为SOA最后给出了微服务架构的设计模式和最佳实践以及相关资源。相信通过这一系列内容的学习你一定会对微服务有全面、透彻的理解。
下篇文章,我们将讲述的容器化和自动化运维方面的内容。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,230 @@
<audio id="audio" title="85 | 程序员练级攻略:容器化和自动化运维" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a9/f2/a915e847909a38033be1a3251713cef2.mp3"></audio>
这篇文章我们来重点学习 Docker 和 Kubernetes它们已经是分布式架构和自动化运维的必备工具了。对于这两个东西你千万不要害怕因为技术方面都不算复杂只是它们的玩法和传统运维不一样所以你不用担心只要你花上一点时间一定可以学好的。
# Docker
<li>
你可以先看一下Docker的官方介绍 [Docker Overview](https://docs.docker.com/engine/docker-overview/) 。
</li>
<li>
然后再去一个Web在线的Playground上体验一下 [Katacoda Docker Playground](https://www.katacoda.com/courses/docker/playground) 或者是 [Play With Docker](https://training.play-with-docker.com/) 。
</li>
<li>
接下来,跟着 [Learn Docker](https://github.com/dwyl/learn-docker) 这个文档中的教程自己安装一个Docker的环境实操一把。
</li>
<li>
然后跟着 [Docker Curriculum](https://docker-curriculum.com/) 这个超详细的教程玩一下Docker。
</li>
有了上述的一些感性体会之后你就可以阅读Docker官方文档 [Docker Documentation](https://docs.docker.com/) 了这是学习Docker最好的方式。
如果你想了解一下Docker的底层技术细节你可以参看我的文章。
- [Docker 基础技术Linux Namespace](https://coolshell.cn/articles/17010.html)
- [Docker 基础技术Linux Namespace](https://coolshell.cn/articles/17029.html)
- [Docker 基础技术Cgroup](https://coolshell.cn/articles/17049.html)
- [Docker 基础技术AUFS](https://coolshell.cn/articles/17061.html)
- [Docker 基础技术DeviceMapper](https://coolshell.cn/articles/17200.html)
还有一些不错的与Docker网络有关的文章你需要阅读及实践一下。
- [A container networking overview](https://jvns.ca/blog/2016/12/22/container-networking/)
- [Docker networking 101 - User defined networks](http://www.dasblinkenlichten.com/docker-networking-101-user-defined-networks/)
- [Understanding CNI (Container Networking Interface)](http://www.dasblinkenlichten.com/understanding-cni-container-networking-interface/)
- [Using CNI with Docker](http://www.dasblinkenlichten.com/using-cni-docker/)
Docker有下面几种网络解决方案[Calico](https://www.projectcalico.org/getting-started/docker/) 、[Flannel](https://github.com/coreos/flannel/) 和 [Weave](https://github.com/weaveworks/weave) ,你需要学习一下。另外,还需要学习一下 [netshoot](https://github.com/nicolaka/netshoot) 这是一个很不错的用来诊断Docker网络问题的工具集。
关于这几个容器网络解决方案的性能对比,你可以看一下下面这几篇文章或报告。
<li>
[Battlefield: Calico, Flannel, Weave and Docker Overlay Network](http://chunqi.li/2015/11/15/Battlefield-Calico-Flannel-Weave-and-Docker-Overlay-Network/)
</li>
<li>
[Comparison of Networking Solutions for Kubernetes](http://machinezone.github.io/research/networking-solutions-for-kubernetes/)
</li>
<li>
[Docker Overlay Networks: Performance analysis in high-latency enviroments](http://www.delaat.net/rp/2015-2016/p50/report.pdf)
</li>
如果你对Docker的性能有什么问题的话你可以看一下下面这些文章。
<li>
[IBM Research Report: An Updated Performance Comparison of Virtual Machines and Linux Containers](https://domino.research.ibm.com/library/cyberdig.nsf/papers/0929052195DD819C85257D2300681E7B/$File/rc25482.pdf)
</li>
<li>
[An Introduction to Docker and Analysis of its Performance](http://paper.ijcsns.org/07_book/201703/20170327.pdf)
</li>
下面是一些和存储相关的文章。
<li>
[Storage Concepts in Docker: Network and Cloud Storage](http://cloud-mechanic.blogspot.de/2014/10/storage-concepts-in-docker-network-and.html)
</li>
<li>
[Storage Concepts in Docker: Persistent Storage](http://cloud-mechanic.blogspot.de/2014/10/storage-concepts-in-docker-persistent.html)
</li>
<li>
[Storage Concepts in Docker: Shared Storage and the VOLUME directive](http://cloud-mechanic.blogspot.de/2014/10/storage-concepts-in-docker.html)
</li>
然后是跟运维相关的文章。
- [Docker Monitoring with the ELK Stack: A Step-by-Step Guide](https://logz.io/learn/docker-monitoring-elk-stack/)
最后,推荐看看 [Valuable Docker Links](http://www.nkode.io/2014/08/24/valuable-docker-links.html) ,其中收集并罗列了一系列非常不错的 Docker 文章。
**最佳实践**
下面分享一些与Docker相关的最佳实践。
<li>
[Best Practices for Dockerfile](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) Docker官方文档里的Dockerfile的最佳实践。
</li>
<li>
[Docker Best Practices](https://github.com/FuriKuri/docker-best-practices) 这里收集汇总了存在于各个地方的使用Docker的建议和实践。
</li>
<li>
[Container Best Practices](http://docs.projectatomic.io/container-best-practices/) 来自Atomic项目是一个介绍容器化应用程序的架构、创建和管理的协作型文档项目。
</li>
<li>
[Eight Docker Development Patterns](http://hokstad.com/docker/patterns) 八个Docker的开发模式共享基础容器、共享同一个卷的多个开发容器、开发工具专用容器、测试环境容器、编译构建容器、防手误的安装容器、默认服务容器、胶黏容器如英文链接不能访问可阅读[中文版本](https://www.infoq.cn/article/2014/10/seven-docker-develop-pattern))。
</li>
# Kubernetes
Kubernetes 是Google开源的容器集群管理系统是Google多年大规模容器管理技术Borg的开源版本也是CNCF最重要的项目之一主要功能包括
- 基于容器的应用部署、维护和滚动升级;
- 负载均衡和服务发现;
- 跨机器和跨地区的集群调度;
- 自动伸缩;
- 无状态服务和有状态服务;
- 广泛的Volume支持
- 插件机制保证扩展性。
Kubernetes发展非常迅速已经成为容器编排领域的领导者。
首先我推荐你阅读Kubernetes前世今生的一篇论文。
- [Borg, Omega, and Kubernetes](https://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/44843.pdf) 看看Google这十几年来从这三个容器管理系统中得到的经验教训。
学习Kubernetes有两个免费的开源电子书。
<li>
《[Kubernetes Handbook](https://jimmysong.io/kubernetes-handbook/)》这本书记录了作者从零开始学习和使用Kubernetes的心路历程着重于经验分享和总结同时也会有相关的概念解析。希望能够帮助你少踩坑少走弯路还会指引你关注kubernetes生态周边如微服务构建、DevOps、大数据应用、Service Mesh、Cloud Native等领域。
</li>
<li>
《[Kubernetes指南](https://kubernetes.feisky.xyz/zh/)》这本书旨在整理平时在开发和使用Kubernetes时的参考指南和实践总结形成一个系统化的参考指南以方便查阅。
</li>
这两本电子书都不错前者更像是一本学习教程而且面明显广一些还包括Cloud Natvie、Service Mesh以及微服务相关的东西。而后者聚焦于Kubernetes本身更像一本参考书。
**另外我这两天也读完了《Kubernetes in Action》一书感觉写的非常好一本很完美的教科书抽丝剥茧图文并茂。如果你只想读一本有关Kubernetes的书来学习Kubernetes那么我推荐你就选这本。**
但是也别忘了Kubernetes的官方网站[Kubernetes.io](https://kubernetes.io/),上面不但有[全面的文档](https://kubernetes.io/docs/home/) ,也包括一个很不错的 [官方教程](https://kubernetes.io/docs/tutorials/kubernetes-basics/) 。
此外,还有一些交互式教程,帮助你理解掌握,以及一些很不错的文章推荐你阅读。
**一些交互式教程**
- [Katacoda](https://www.katacoda.com/courses/kubernetes)
- [Kubernetes Bootcamp](https://kubernetesbootcamp.github.io/kubernetes-bootcamp/)
**一些文章**
这里还有一些不错的文档,你应该去读一下。
- [Kubernetes tips &amp; tricks](https://opsnotice.xyz/kubernetes-tips-tricks/)
- [Achieving CI/CD with Kubernetes](http://theremotelab.com/blog/achieving-ci-cd-with-k8s/)
- [How to Set Up Scalable Jenkins on Top of a Kubernetes Cluster](https://dzone.com/articles/how-to-setup-scalable-jenkins-on-top-of-a-kubernet)
- 10 Most Common Reasons Kubernetes Deployments Fail [Part I](https://kukulinski.com/10-most-common-reasons-kubernetes-deployments-fail-part-1/) 和 [Part II](https://kukulinski.com/10-most-common-reasons-kubernetes-deployments-fail-part-2/)
- [How to Monitor Kubernetes](http://sysdig.com/blog/monitoring-kubernetes-with-sysdig-cloud/) 一共有4个篇章
- [Logging in Kubernetes with Fluentd and Elasticsearch](http://www.dasblinkenlichten.com/logging-in-kubernetes-with-fluentd-and-elasticsearch/)
- [Kubernetes Monitoring: Best Practices, Methods, and Existing Solutions](https://dzone.com/articles/kubernetes-monitoring-best-practices-methods-and-e)
**网络相关的文章**
要学习Kubernetes你只需要读一下下面这个Kubernetes 101系列的文章。
- [Kubernetes 101 - Networking](http://www.dasblinkenlichten.com/kubernetes-101-networking/)
- [Kubernetes networking 101 - Pods](http://www.dasblinkenlichten.com/kubernetes-networking-101-pods/)
- [Kubernetes networking 101 - Services](http://www.dasblinkenlichten.com/kubernetes-networking-101-services/)
- [Kubernetes networking 101 - (Basic) External access into the cluster](http://www.dasblinkenlichten.com/kubernetes-networking-101-basic-external-access-into-the-cluster/)
- [Kubernetes Networking 101 - Ingress resources](http://www.dasblinkenlichten.com/kubernetes-networking-101-ingress-resources/)
- [Getting started with Calico on Kubernetes](http://www.dasblinkenlichten.com/getting-started-with-calico-on-kubernetes/)
**CI/CD相关的文章**
- [Automated Image Builds with Jenkins, Packer, and Kubernetes](https://cloud.google.com/solutions/automated-build-images-with-jenkins-kubernetes#kubernetes_architecture)
- [Jenkins setups for Kubernetes and Docker Workflow](http://iocanel.blogspot.in/2015/09/jenkins-setups-for-kubernetes-and.html)
- [Lab: Build a Continuous Deployment Pipeline with Jenkins and Kubernetes](https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes)
**最佳实践**
- [Kubernetes Best Practices](https://medium.com/@sachin.arote1/kubernetes-best-practices-9b1435a4cb53) by [Sachin Arote](https://medium.com/@sachin.arote1?source=post_header_lockup) AWS工程师总结的最佳实践。
- [Kubernetes Best Practices](https://speakerdeck.com/thesandlord/kubernetes-best-practices) by [Sandeep Dinesh](https://github.com/thesandlord) Google云平台工程师总结的最佳实践。
**Docker和Kubernetes资源汇总**
下面是 GitHub 上和 Docker &amp; Kubernetes相关的Awesome系列。
- [Awesome Docker](https://github.com/veggiemonk/awesome-docker)。
- [Awesome Kubernetes](https://github.com/ramitsurana/awesome-kubernetes)。
虽然上面的这些系列非常全的罗列了很多资源但是我觉得很不系统。对于系统的说明Docker和Kubernetes生态圈我非常推荐大家看一下 The New Stack 为Kubernetes出的一系列的电子书或报告。
<li>
[The New Stack eBook Series](http://thenewstack.io/ebookseries/) ,非常完整和详实的 Docker 和 Kubernetes 生态圈的所有东西。
<ul>
- Book 01: [The Docker Container Ecosystem](https://thenewstack.io/ebooks/docker-and-containers/the-docker-container-ecosystem/)
- Book 02: [Applications &amp; Microservices with Docker &amp; Containers](https://thenewstack.io/ebooks/docker-and-containers/applications-microservices-docker-containers/)
- Book 03: [Automation &amp; Orchestration with Docker &amp; Containers](https://thenewstack.io/ebooks/docker-and-containers/automation-orchestration-docker-containers/)
- Book 04: [Network, Security &amp; Storage with Docker &amp; Containers](https://thenewstack.io/ebooks/docker-and-containers/networking-security-storage-docker-containers/)
- Book 05: [Monitoring &amp; Management with Docker &amp; Containers](https://thenewstack.io/ebooks/docker-and-containers/monitoring-management-docker-containers/)
- Book 06: [Use Cases for Kubernetes](https://thenewstack.io/ebooks/use-cases/use-cases-for-kubernetes/)
- Book 07: [State of the Kubernetes Ecosystem](https://thenewstack.io/ebooks/kubernetes/state-of-kubernetes-ecosystem/)
- Book 08: [Kubernetes Deployment &amp; Security Patterns](https://thenewstack.io/ebooks/kubernetes/kubernetes-deployment-and-security-patterns/)
- Book 09: [CI/CD with Kubernetes](https://thenewstack.io/ebooks/kubernetes/ci-cd-with-kubernetes/)
- Book 10: [Kubernetes solutions Directory](https://thenewstack.io/ebooks/kubernetes/kubernetes-solutions-directory/)
- Book 11: [Guid to Cloud-Native Microservices](https://thenewstack.io/ebooks/microservices/cloud-native-microservices-2018/)
# 小结
总结一下今天的内容。Docker 和 Kubernetes已经成为分布式架构和自动化运维方面的不可或缺的两大基本构成是你必需要学习的。虽然它们的玩法跟传统运维不一样但技术方面并不算复杂只要你花上一点时间一定会学好的。
在这篇文章中我推荐了Docker和Kubernetes基础技术方面的学习资料并给出了存储、运维、网络、CI/CD等多方面的资料同时列出了与之相关的最佳实践。相信认真学习和消化这些知识你一定可以掌握Docker和Kubernetes两大利器。
下篇文章,我们将学习机器学习和人工智能方面的内容。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,271 @@
<audio id="audio" title="86 | 程序员练级攻略:机器学习和人工智能" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/04/0c/04005da32b01b21fc34fa6053664be0c.mp3"></audio>
我之前写过一篇机器学习的入门文章,因为我也是在入门和在学习的人,所以,那篇文章和这篇机器学习和人工智能方向的文章可能都会有点太肤浅。如果你有更好的学习方式或资料,欢迎补充。
# 基本原理简介
我们先来介绍一下机器学习的基本原理。
机器学习主要有两种方式一种是监督式学习Supervised Learning另一种是非监督式学习Unsupervised Learning。下面简单地说一下这两者的不同。
<li>
**监督式学习Supervised Learning**。所谓监督式学习,也就是说,我们需要提供一组学习样本,包括相关的特征数据和相应的标签。我们的程序可以通过这组样本来学习相关的规律或是模式,然后通过得到的规律或模式来判断没有被打过标签的数据是什么样的数据。
举个例子假设需要识别一些手写的数字我们要找到尽可能多的手写体数字的图像样本然后人工或是通过某种算法来明确地标注上什么是这些手写体的图片谁是1谁是2谁是3…… 这组数据叫样本数据又叫训练数据training data。然后通过机器学习的算法找到每个数字在不同手写体下的特征找到规律和模式。通过得到的规律或模式来识别那些没有被打过标签的手写数据以此完成识别手写体数字的目的。
</li>
<li>
**非监督式学习Unsupervised Learning**。对于非监督式学习,也就是说,数据是没有被标注过的,所以相关的机器学习算法需要找到这些数据中的共性。因为大量的数据是没被被标识过的,所以这种学习方式可以让大量的未标识的数据能够更有价值。而且,非监督式学习,可以为我们找到人类很难发现的数据里的规律或模型,所以也有人称这种学习为“特征点学习”,其可以让我们自动地为数据进行分类,并找到分类的模型。
一般来说,非监督式学习会应用在一些交易型的数据中。比如,你有一堆堆的用户购买数据,但是对于人类来说,我们很难找到用户属性和购买商品类型之间的关系。所以,非监督式学习算法可以帮助我们找到它们之间的关系。比如,一个在某年龄段的女性购买了某种肥皂,有可能说明这个女性在怀孕期,或是某人购买儿童用品,有可能说明这个人的关系链中有孩子,等等。于是,这些信息会被用作一些所谓的精准市场营销活动,从而可以增加商品销量。
</li>
我们这么来说吧,监督式学习是在被告诉过了正确的答案后的学习,而非监督式学习是在没有被告诉正确答案时的学习。所以,非监督式学习是在大量的非常乱的数据中找寻一些潜在的关系,这个成本也比较高。非监督式学习经常被用来检测一些不正常的事情发生,比如信用卡的诈骗或是盗刷。也被用在推荐系统,比如买了这个商品的人又买了别的什么商品,或是如果某个人喜欢某篇文章、某个音乐、某个餐馆,那么他可能会喜欢某个车、某个明星或某个地方。
在监督式学习算法下,我们可以用一组“狗”的照片来确定某个照片中的物体是不是狗。而在非监督式学习算法下,我们可以通过一个照片来找到其中有与其相似的事物的照片。这两种学习方式都有些有用的场景。
关于机器学习,你可以读一读 [Machine Learning is Fun!](https://medium.com/@ageitgey/machine-learning-is-fun-80ea3ec3c471) ,这篇文章([中文翻译版](https://zhuanlan.zhihu.com/p/24339995))恐怕是全世界最简单的入门资料了。
- [Data Science Simplified Part 1: Principles and Process](https://becominghuman.ai/data-science-simplified-principles-and-process-b06304d63308)
- [Data Science Simplified Part 2: Key Concepts of Statistical Learning](https://towardsdatascience.com/data-science-simplified-key-concepts-of-statistical-learning-45648049709e)
- [Data Science Simplified Part 3: Hypothesis Testing](https://towardsdatascience.com/data-science-simplified-hypothesis-testing-56e180ef2f71)
- [Data Science Simplified Part 4: Simple Linear Regression Models](https://towardsdatascience.com/data-science-simplified-simple-linear-regression-models-3a97811a6a3d)
- [Data Science Simplified Part 5: Multivariate Regression Models](https://towardsdatascience.com/data-science-simplified-part-5-multivariate-regression-models-7684b0489015)
- [Data Science Simplified Part 6: Model Selection Methods](https://towardsdatascience.com/data-science-simplified-part-6-model-selection-methods-2511cbdf7cb0)
- [Data Science Simplified Part 7: Log-Log Regression Models](https://towardsdatascience.com/data-science-simplified-part-7-log-log-regression-models-499ecd1495f0)
- [Data Science Simplified Part 8: Qualitative Variables in Regression Models](https://towardsdatascience.com/data-science-simplified-part-8-qualitative-variables-in-regression-models-d1817d56245c)
- [Data Science Simplified Part 9: Interactions and Limitations of Regression Models](https://towardsdatascience.com/data-science-simplified-part-9-interactions-and-limitations-of-regression-models-4702dff03820)
- [Data Science Simplified Part 10: An Introduction to Classification Models](https://towardsdatascience.com/data-science-simplified-part-10-an-introduction-to-classification-models-82490f6c171f)
- [Data Science Simplified Part 11: Logistic Regression](https://towardsdatascience.com/data-science-simplified-part-11-logistic-regression-5ae8d994bf0e)
# 相关课程
接下来,我们需要比较专业地学习一下机器学习了。
在学习机器学习之前我们需要学习数据分析所以我们得先学一些大数据相关的东西也就是Data Science相关的内容。下面是两个不错的和数据科学相关的教程以及一个资源列表。
<li>
[UC Berkeleys Data 8: The Foundations of Data Science](http://data8.org/) 和电子书 [Computational and Inferential Thinking](https://www.inferentialthinking.com/) 会讲述数据科学方面非常关键的概念,会教你在数据中找到数据的关联、预测和相关的推断。
</li>
<li>
[Learn Data Science](https://github.com/nborwankar/LearnDataScience) 这是GitHub上的一本电子书主要是一些数据挖掘的算法比如线性回归、逻辑回归、随机森林、K-Means聚类的数据分析。然后[donnemartin/data-science-ipython-notebooks](https://github.com/donnemartin/data-science-ipython-notebooks#scikit-learn) 这个代码仓库中用TensorFlow、scikit-learn、Pandas、NumPy、Spark等把这些经典的例子实现了个遍。
</li>
<li>
[Data Science Resources List](https://www.datascienceweekly.org/data-science-resources/the-big-list-of-data-science-resources) ,这个网站上有一个非常长的和数据科学相关的资源列表,你可以从中得到很多你想要的东西。
</li>
之后,有下面几门不错的在线机器学习的课程供你入门,也是非常不错。
<li>
吴恩达教授Andrew Ng在 [Coursera 上的免费机器学习课程](https://www.coursera.org/learn/machine-learning) 非常棒。我强烈建议从此入手。对于任何拥有计算机或科学学位的人,或是还能记住一点点数学知识的人来说,都应该非常容易入门。这个斯坦福大学的课程请尽量拿满分。可以在 [网易公开课](http://open.163.com/special/opencourse/machinelearning.html) 中找到这一课程。除此之外,吴恩达教授还有一组新的和深度学习相关的课程,现在可以在网易公开课上免费学习——[Deep Learning Specialization](https://mooc.study.163.com/smartSpec/detail/1001319001.htm)。
</li>
<li>
[Deep Learning by Google](https://www.udacity.com/course/deep-learning--ud730) Google的一个关于深度学习的在线免费课程其支持中英文。这门课会教授你如何训练和优化基本神经网络、卷积神经网络和长短期记忆网络。你将通过项目和任务接触完整的机器学习系统TensorFlow。
</li>
<li>
卡内基梅隆大学汤姆·米切尔Tom Mitchell的机器学习 [英文原版视频与课件PDF](http://www.cs.cmu.edu/%7Etom/10701_sp11/lectures.shtml) 。
</li>
<li>
2013年加利福尼亚理工学院亚瑟·阿布-穆斯塔法Yaser Abu-Mostafa的Learning from Data [课程视频及课件PDF](http://work.caltech.edu/lectures.html),内容更适合进阶。
</li>
<li>
关于神经网络方面YouTube上有一个非常火的课程视频由宾夕法尼亚大学的雨果·拉罗歇尔Hugo Larochelle出品的教学课程 - [Neural networks class - Université de Sherbrooke ](https://www.youtube.com/playlist?list=PL6Xpj9I5qXYEcOhn7TqghAJ6NAPrNmUBH)。
</li>
除此之外,还有很多的在线大学课程可以供你学习。比如:
<li>
斯坦福大学的《[统计学学习](https://lagunita.stanford.edu/courses/HumanitiesandScience/StatLearning/Winter2015/about)》、《[机器学习](http://cs229.stanford.edu/)》、《[卷积神经网络](http://cs231n.stanford.edu/)》、《[深度学习之自然语言处理](http://cs224d.stanford.edu/)》等。
</li>
<li>
麻省理工大学的《[神经网络介绍](http://ocw.mit.edu/courses/brain-and-cognitive-sciences/9-641j-introduction-to-neural-networks-spring-2005/index.htm) 》、《[机器学习](http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-867-machine-learning-fall-2006/)》、《[预测](http://ocw.mit.edu/courses/sloan-school-of-management/15-097-prediction-machine-learning-and-statistics-spring-2012/index.htm)》等。
</li>
更多的列表,请参看——[Awesome Machine Learning Courses](https://github.com/RatulGhosh/awesome-machine-learning)。
# 相关图书
<li>
《[Pattern Recognition and Machine Learning](https://book.douban.com/subject/2061116/)》这本书是机器学习领域的圣经之作。该书也是众多高校机器学习研究生课程的教科书Google上有[PDF版的下载](http://users.isr.ist.utl.pt/~wurmd/Livros/school/Bishop%20-%20Pattern%20Recognition%20And%20Machine%20Learning%20-%20Springer%20%202006.pdf)。这本书很经典但并不适合入门来看。GitHub上有这本中的 [Matlab 实现](https://github.com/PRML/PRMLT)。
</li>
<li>
下面这两本电子书也是比较经典的,其中讲了很多机器学习的知识,可以当做手册或字典。
<ul>
- 《[Understanding Machine Learning: From Theory to Algorithms](https://www.cs.huji.ac.il/~shais/UnderstandingMachineLearning/understanding-machine-learning-theory-algorithms.pdf)》。
- 《[The Elements of Statistical Learning - Second Edition](https://web.stanford.edu/~hastie/Papers/ESLII.pdf)》。
《[Deep Learning: Adaptive Computation and Machine Learning series](https://book.douban.com/subject/27087503/)》 中文翻译为《深度学习》。这本书由全球知名的三位专家伊恩·古德费洛Ian Goodfellow、友华·本吉奥Yoshua Bengio和亚伦·考维尔Aaron Courville撰写是深度学习领域奠基性的经典教材。
全书内容包括3部分第1部分介绍基本的数学工具和机器学习的概念它们是深度学习的预备知识第2部分系统深入地讲解现今已成熟的深度学习方法和技术第3部分讨论某些具有前瞻性的方向和想法它们被公认为是深度学习未来的研究重点。这本书的官网为 “[deeplearningbook.org](http://www.deeplearningbook.org/)”在GitHub上也有中文翻译 - 《[Deep Learning 中文翻译](https://github.com/exacity/deeplearningbook-chinese)》。
《[Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/)》([中文翻译版](https://tigerneil.gitbooks.io/neural-networks-and-deep-learning-zh/content/)),这是一本非常不错的神经网络的入门书,在[豆瓣上评分9.5分](https://book.douban.com/subject/26727997/),从理论讲到了代码。虽然有很多数学公式,但是有代码相助,就不难理解了。其中讲了很多如激活函数、代价函数、随机梯度下降、反向传播、过度拟合和规范化、权重初始化、超参数优化、卷积网络的局部感受野、混合层、特征映射的东西。
《[Introduction to Machine Learning with Python](https://book.douban.com/subject/26279609/)》算是本不错的入门书也是本比较易读的英文书。其是以Scikit-Learn框架来讲述的。如果你用过Scikit这个框架那么你学这本书还是很不错的。
《[Hands-On Machine Learning with Scikit-Learn and TensorFlow](https://book.douban.com/subject/26840215/) 》这是一门以TensorFlow为工具的入门书其用丰富的例子从实站的角度来让你学习。这本书对于无基础的人也是适合的对于小白来说虽然略难但是受益匪浅。
# 相关文章
除了上述的那些课程和图书外,下面这些文章也很不错。
<li>
YouTube 上的 Google Developers 的 [Machine Learning Recipes with Josh Gordon](https://www.youtube.com/playlist?list=PLOU2XLYxmsIIuiBfYad6rFYQU_jL2ryal) 这9集视频每集不到10分钟从Hello World讲到如何使用TensorFlow非常值得一看。
</li>
<li>
还有 [Practical Machine Learning Tutorial with Python Introduction](https://pythonprogramming.net/machine-learning-tutorial-python-introduction/) 上面一系列的用Python带着你玩Machine Learning的教程。
</li>
<li>
Medium上的 [Machine Learning - 101](https://medium.com/machine-learning-101) ,讲述了好些我们上面提到过的经典算法。
</li>
<li>
Medium上的 [Marchine Learning for Humans](https://medium.com/machine-learning-for-humans)。
</li>
<li>
[Dr. Jason Brownlee 的博客](https://machinelearningmastery.com/blog/) ,也非常值得一读,其中好多的 “How-To”会让你有很多的收获。
</li>
<li>
[Rules of Machine Learning: Best Practices for ML Engineering](http://martin.zinkevich.org/rules_of_ml/rules_of_ml.pdf) ,一些机器学习相关的最佳实践。
</li>
<li>
[i am trask](http://iamtrask.github.io) ,也是一个很不错的博客。
</li>
<li>
关于Deep Learning中的神经网络YouTube上有介绍视频 [Neural Networks](https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi)。
</li>
<li>
麻省理工学院的电子书 [Deep Learning](http://www.deeplearningbook.org)。
</li>
<li>
用Python做自然语言处理[Natural Language Processing with Python](http://www.nltk.org/book/)。
</li>
<li>
最后一个是Machine Learning和Deep Learning的相关教程列表[Machine Learning &amp; Deep Learning Tutorials](https://github.com/ujjwalkarn/Machine-Learning-Tutorials)。
</li>
下面是一些和神经网络相关的不错的文章。
<li>
[The Unreasonable Effectiveness of Recurrent Neural Networks](http://karpathy.github.io/2015/05/21/rnn-effectiveness/) ,这是一篇必读的文章 告诉你为什么要学RNN以及展示了最简单的NLP形式。
</li>
<li>
[Neural Networks, Manifolds, and Topology](http://colah.github.io/posts/2014-03-NN-Manifolds-Topology/) ,这篇文章可以帮助你理解神经网络的一些概念。
</li>
<li>
[Understanding LSTM Networks](http://colah.github.io/posts/2015-08-Understanding-LSTMs/) 解释了什么是LSTM的内在工作原理。
</li>
<li>
[Attention and Augmented Recurrent Neural Networks](http://distill.pub/2016/augmented-rnns/) 用了好多图来说明了RNN的attention机制。
</li>
<li>
[Recommending music on Spotify with deep learning](http://benanne.github.io/2014/08/05/spotify-cnns.html) 一个在Spotify的实习生分享的音乐聚类的文章。
</li>
# 相关算法
下面是10个非常经典的机器学习的算法。
<li>
对于监督式学习,有如下经典算法。
<ol>
<li>
[决策树Decision Tree](https://en.wikipedia.org/wiki/Decision_tree),比如自动化放贷、风控。
</li>
<li>
[朴素贝叶斯分类器Naive Bayesian classifier)](https://en.wikipedia.org/wiki/Naive_Bayes_classifier),可以用于判断垃圾邮件、对新闻的类别进行分类,比如科技、政治、运动、判断文本表达的感情是积极的还是消极的、人脸识别等。
</li>
<li>
[最小二乘法Ordinary Least Squares Regression](https://en.wikipedia.org/wiki/Ordinary_least_squares),是一种线性回归。
</li>
<li>
[逻辑回归Logisitic Regression](https://en.wikipedia.org/wiki/Logistic_regression),一种强大的统计学方法,可以用一个或多个变量来表示一个二项式结果。可以用于信用评分,计算营销活动的成功率,预测某个产品的收入。
</li>
<li>
[支持向量机Support Vector MachineSVM](https://en.wikipedia.org/wiki/Support_vector_machine),可以用于基于图像的性别检测、图像分类等。
</li>
<li>
[集成方法Ensemble methods](https://en.wikipedia.org/wiki/Ensemble_learning)通过构建一组分类器然后通过它们的预测结果进行加权投票来对新的数据点进行分类。原始的集成方法是贝叶斯平均但最近的算法包括纠错输出编码、Bagging和Boosting。
</li>
</ol>
</li>
<li>
对于无监督式的学习,有如下经典算法。
<ol>
<li>
[聚类算法Clustering Algorithms](https://en.wikipedia.org/wiki/Cluster_analysis)。聚类算法有很多目标是给数据分类。有5个比较著名的聚类算法你必需要知道[K-Means](https://en.wikipedia.org/wiki/K-means_clustering)、[Mean-Shift](https://en.wikipedia.org/wiki/Mean_shift)、[DBSCAN](https://en.wikipedia.org/wiki/DBSCAN)、[EM/GMM](https://en.wikipedia.org/wiki/Expectation%E2%80%93maximization_algorithm)、和 [Agglomerative Hierarchical](https://en.wikipedia.org/wiki/Hierarchical_clustering)。
</li>
<li>
[主成分分析Principal Component AnalysisPCA](https://en.wikipedia.org/wiki/Principal_component_analysis)。PCA的一些应用包括压缩、简化数据便于学习、可视化等。
</li>
<li>
[奇异值分解Singular Value DecompositionSVD](https://en.wikipedia.org/wiki/Singular-value_decomposition)。实际上PCA是SVD的一个简单应用。在计算机视觉中第一个人脸识别算法使用PCA和SVD来将面部表示为"特征面"的线性组合,进行降维,然后通过简单的方法将面部匹配到身份。虽然现代方法更复杂,但很多方面仍然依赖于类似的技术。
</li>
<li>
[独立成分分析Independent Component AnalysisICA](https://en.wikipedia.org/wiki/Independent_component_analysis)。ICA是一种统计技术主要用于揭示随机变量、测量值或信号集中的隐藏因素。
</li>
</ol>
</li>
如果你想了解更全的机器学习的算法列表你可以看一下Wikipedia上的 [List of Machine Learning Algorithms](https://en.wikipedia.org/wiki/Outline_of_machine_learning#Machine_learning_algorithms)。
在 [A Tour of Machine Learning Algorithms](https://machinelearningmastery.com/a-tour-of-machine-learning-algorithms/) ,这篇文章带你概览了一些机器学习算法,其中还有一个"脑图"可以下载并还有一些How-To的文章供你参考。
对于这些算法,[SciKit-Learn](http://scikit-learn.org/stable/)有一些文档供你学习。
- [1. Supervised learning](http://scikit-learn.org/stable/supervised_learning.html#supervised-learning)
- [2.3 Clustering](http://scikit-learn.org/stable/modules/clustering.html#clustering)
- [2.5. Decomposing signals in components (matrix factorization problems)](http://scikit-learn.org/stable/modules/decomposition.html#decompositions)
- [3. Model selection and evaluation](http://scikit-learn.org/stable/model_selection.html#model-selection)
- [4.3. Preprocessing data](http://scikit-learn.org/stable/modules/preprocessing.html#preprocessing)
# 相关资源
<li>
对于初学者来说,动手是非常非常重要的,不然,你会在理论的知识里迷失掉自己,这里有篇文章"[8 Fun Machine Learning Projects for Beginners](https://elitedatascience.com/machine-learning-projects-for-beginners)"其中为初学者准备了8个很有趣的项目你可以跟着练练。
</li>
<li>
学习机器学习或是人工智能你需要数据,这里有一个非常足的列表给你足够多的公共数据 《[Awesome Public Datasets](https://github.com/awesomedata/awesome-public-datasets)》,其中包括农业、生物、天气、计算机网络、地球科学、经济、教育、金融、能源、政府、健康、自然语言、体育等。
</li>
<li>
GitHub上的一些Awesome资源列表。
<ul>
- [Awesome Deep Learning](https://github.com/ChristosChristofidis/awesome-deep-learning)
- [Awesome - Most Cited Deep Learning Papers](https://github.com/terryum/awesome-deep-learning-papers)
- [Awesome Deep learning papers and other resources](https://github.com/endymecy/awesome-deeplearning-resources)
# 小结
总结一下今天的内容。我首先介绍了机器学习的基本原理:监督式学习和非监督式学习,然后给出了全世界最简单的入门资料 [Machine Learning is Fun!](https://medium.com/@ageitgey/machine-learning-is-fun-80ea3ec3c471)。随后给出了与机器学习密切相关的数据分析方面的内容和资料,然后推荐了深入学习机器学习知识的在线课程、图书和文章等,尤其列举了神经网络方面的学习资料。最后描述了机器学习的十大经典算法及相关的学习资料。
在机器学习和人工智能领域,我也在学习,也处于入门阶段,所以本文中推荐的内容,可能在你看来会有些浅。如果你有更好的信息和资料,欢迎补充。目前文章中给出来的是,我在学习过程中认为很不错的内容,我从中受益良多,所以希望它们也能为你的学习提供帮助。
从下篇文章开始我们将进入前端知识的学习包括基础和底层原理、性能优化、前端框架、UI/UX设计等内容。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,297 @@
<audio id="audio" title="87 | 程序员练级攻略:前端基础和底层原理" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/59/d3/5983e8e8f6f1ee8b536ec56b31d442d3.mp3"></audio>
对于前端的学习和提高我的基本思路是这样的。首先前端的三个最基本的东西HTML 5、CSS 3和JavaScriptES6是必须要学好的。这其中有很多很多的技术比如CSS 3引申出来的Canvas位图、SVG矢量图 和 WebGL3D图以及CSS的各种图形变换可以让你做出非常丰富的渲染效果和动画效果。
ES6简直就是把JavaScript带到了一个新的台阶JavaScript语言的强大大大释放了前端开发人员的生产力让前端得以开发更为复杂的代码和程序于是像React和Vue这样的框架开始成为前端编程的不二之选。
我一直认为学习任何知识都要从基础出发,所以这篇文章我会着重介绍基础知识和基本原理,尤其是如下的这些知识,都是前端程序员需要花力气啃下来的硬骨头。
<li>
**JavaScript的核心原理**。这里我会给出好些网上很不错的讲JavaScript的原理的文章或图书你一定要学好语言的特性并且详细了解其中的各种坑。
</li>
<li>
**浏览器的工作原理**。这也是一块硬骨头,我觉得这是前端程序员需要了解和明白的关键知识点,不然,你将无法深入下去。
</li>
<li>
**网络协议HTTP**。也是要着重了解的尤其是HTTP/2还有HTTP的几种请求方式短连接、长连接、Stream连接、WebSocket连接。
</li>
<li>
**前端性能调优**。有了以上的这些基础后,你就可以进入前端性能调优的主题了,我相信你可以很容易上手各种性能调优技术的。
</li>
<li>
**框架学习**。我只给了React和Vue两个框架。就这两个框架来说Virtual DOM技术是其底层技术组件化是其思想管理组件的状态是其重点。而对于React来说函数式编程又是其编程思想所以这些基础技术都是你需要好好研究和学习的。
</li>
<li>
**UI设计**。设计也是前端需要做的一个事比如像Google的Material UI或是比较流行的Atomic Design等应该是前端工程师需要学习的。
</li>
而对于工具类的东西这里我基本没怎么涉及因为本文主要还是从原理和基础入手。那些工具我觉得都很简单就像学习Java我没有让你去学习Maven一样因为只要你去动手了这种知识你自然就会获得我们还是把精力重点放在更重要的地方。
下面我们从前端基础和底层原理开始讲起。先来讲讲HTML5相关的内容。
# HTML 5
HTML 5主要有以下几本书推荐。
<li>
[HTML 5权威指南](https://book.douban.com/subject/25786074/) 本书面向初学者和中等水平Web开发人员是牢固掌握HTML 5、CSS 3和JavaScript的必读之作。书看起来比较厚是因为里面的代码很多。
</li>
<li>
[HTML 5 Canvas核心技术](https://book.douban.com/subject/24533314/) 如果你要做HTML 5游戏的话这本书必读。
</li>
对于SVG、Canvas和WebGL这三个对应于矢量图、位图和3D图的渲染来说给前端开发带来了重武器很多HTML5小游戏也因此蓬勃发展。所以你可以学习一下。
学习这三个技术我个人觉得最好的地方是MDN。
- [SVG: Scalable Vector Graphics](https://developer.mozilla.org/en-US/docs/Web/SVG)
- [Canvas API](https://developer.mozilla.org/kab/docs/Web/API/Canvas_API)
- [The WebGL API: 2D and 3D graphics for the web](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API)
最后是几个资源列表。
- [Awesome HTML5](https://github.com/diegocard/awesome-html5) 。GitHub上的Awesome HTML5其中有大量的资源和技术文章。
- [Awesome SVG](https://github.com/willianjusten/awesome-svg)
- [Awesome Canvas](https://github.com/raphamorim/awesome-canvas)
- [Awesome WebGL](https://github.com/sjfricke/awesome-webgl)
# CSS
在《程序员练级攻略》系列文章最开始我们就推荐过CSS的在线学习文档这里再推荐一下 [MDN Web Doc - CSS](https://developer.mozilla.org/zh-CN/docs/Web/CSS) 。我个人觉得只要你仔细读一下文档CSS并不难学。绝大多数觉得难的一方面是文档没读透另一方面是浏览器支持的标准不一致。所以学好CSS最关键的还是要仔细地读文档。
之后在写CSS的时候你会发现你的CSS中有很多看起来相似的东西。你的DRY - Dont Repeat Yourself洁癖告诉你这是不对的。所以你需要学会使用 [LESS](http://lesscss.org/) 和 [SaSS](http://sass-lang.com) 这两个CSS预处理工具其可以帮你提高很多效率。
然后你需要学习一下CSS的书写规范前面的《程序员修养》一文中提到过一些这里再补充几个。
- [Principles of writing consistent, idiomatic CSS](https://github.com/necolas/idiomatic-css)
- [Opinionated CSS styleguide for scalable applications](https://github.com/grvcoelho/css-styleguide)
- [Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html)
如果你需要更有效率那么你还需要使用一些CSS Framework其中最著名的就是Twitter公司的 [Bootstrap](http://getbootstrap.com/),其有很多不错的 UI 组件页面布局方案可以让你非常方便也非常快速地开发页面。除此之外还有主打清新UI的 [Semantic UI](https://semantic-ui.com/) 、主打响应式界面的 [Foundation](http://foundation.zurb.com/) 和基于Flexbox的 [Bulma](http://bulma.io/)。
当然在使用CSS之前你需要把你浏览器中的一些HTML标签给标准化掉。所以推荐几个Reset或标准化的CSS库[Normalize](https://github.com/necolas/normalize.css)、[MiniRest.css](https://github.com/jgthms/minireset.css)、[sanitize.css](https://github.com/jonathantneal/sanitize.css/) 和 [unstyle.css](https://github.com/Martin-Pitt/css-unstyle)。
关于更多的CSS框架你可以参看[Awesome CSS Frameworks](https://github.com/troxler/awesome-css-frameworks) 上的列表。
接下来是几个公司的CSS相关实践供你参考。
- [CodePens CSS](https://codepen.io/chriscoyier/post/codepens-css)
- [Github 的 CSS](http://markdotto.com/2014/07/23/githubs-css/)
- [Mediums CSS is actually pretty f***ing good](https://medium.com/@fat/mediums-css-is-actually-pretty-fucking-good-b8e2a6c78b06)
- [CSS at BBC Sport](https://medium.com/bbc-design-engineering/css-at-bbc-sport-part-1-bab546184e66)
- [Refining The Way We Structure Our CSS At Trello](https://blog.trello.com/refining-the-way-we-structure-our-css-at-trello)
最后是一个可以写出可扩展的CSS的阅读列表 [A Scalable CSS Reading List](https://github.com/davidtheclark/scalable-css-reading-list) 。
# JavaScript
下面是学习JavaScript的一些图书和文章。
<li>
[JavaScript: The Good Parts](https://book.douban.com/subject/11874748/) 中文翻译版为《JavaScript语言精粹》。这是一本介绍JavaScript语言本质的权威图书值得任何正在或准备从事JavaScript开发的人阅读并且需要反复阅读。学习、理解、实践大师的思想我们才可能站在巨人的肩上才有机会超越大师这本书就是开始。
</li>
<li>
[Secrets of the JavaScript Ninja](https://book.douban.com/subject/26638316/) 中文翻译版为《JavaScript忍者秘籍》本书是jQuery库创始人编写的一本深入剖析JavaScript语言的书。适合具备一定JavaScript基础知识的读者阅读也适合从事程序设计工作并想要深入探索JavaScript语言的读者阅读。这本书有很多晦涩难懂的地方需要仔细阅读反复琢磨。
</li>
<li>
[Effective JavaScript](https://book.douban.com/subject/25786138/) Ecma的JavaScript标准化委员会著名专家撰写作者凭借多年标准化委员会工作和实践经验深刻辨析JavaScript的内部运作机制、特性、陷阱和编程最佳实践将它们高度浓缩为极具实践指导意义的68条精华建议。
</li>
<li>
接下来是ES6的学习这里给三个学习手册源。
<ul>
<li>
[ES6 in Depth](https://hacks.mozilla.org/category/es6-in-depth/)InfoQ上有相关的中文版 - [ES6 深入浅出](http://www.infoq.com/cn/es6-in-depth/)。还可以看看 [A simple interactive ES6 Feature list](https://codetower.github.io/es6-features?utm_source=mybridge&amp;utm_medium=email&amp;utm_campaign=read_more) ,或是看一下 [阮一峰翻译的ES6的教程](http://es6.ruanyifeng.com) 。
</li>
<li>
[ECMAScript 6 Tools](https://github.com/addyosmani/es6-tools) 这是一堆ES6工具的列表可以帮助你提高开发效率。
</li>
<li>
[Modern JS Cheatsheet](https://mbeaudru.github.io/modern-js-cheatsheet/) 这个Cheatsheet在GitHub上有1万6千颗星你就可见其影响力了。
</li>
然后,还有一组很不错的《[You Dont Know JS 系列](https://github.com/getify/You-Dont-Know-JS)》 的书。
- [You Dont Know JS: “Up &amp; Going”](https://github.com/getify/You-Dont-Know-JS/blob/master/up%20&amp;%20going/README.md#you-dont-know-js-up--going)
- [You Dont Know JS: “Scope &amp; Closures”](https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&amp;%20closures/README.md#you-dont-know-js-scope--closures)
- [You Dont Know JS: “this &amp; Object Prototypes”](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&amp;%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes)
- [You Dont Know JS: “Types &amp; Grammar”](https://github.com/getify/You-Dont-Know-JS/blob/master/types%20&amp;%20grammar/README.md#you-dont-know-js-types--grammar)
- [You Dont Know JS: “Async &amp; Performance”](https://github.com/getify/You-Dont-Know-JS/blob/master/async%20&amp;%20performance/README.md#you-dont-know-js-async--performance)
- [You Dont Know JS: “ES6 &amp; Beyond”](https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20&amp;%20beyond/README.md#you-dont-know-js-es6--beyond)
接下来是一些和编程范式相关的文章。
<li>
[Glossary of Modern JavaScript Concepts: Part 1](https://auth0.com/blog/glossary-of-modern-javascript-concepts/) ,首先推荐这篇文章,其中收集了一些编程范式方面的内容,比如纯函数、状态、可变性和不可变性、指令型语言和声明式语言、函数式编程、响应式编程、函数式响应编程。
</li>
<li>
[Glossary of Modern JavaScript Concepts: Part 2](https://auth0.com/blog/glossary-of-modern-javascript-concepts-part-2/) ,在第二部分中主要讨论了作用域和闭包,数据流,变更检测,组件化……
</li>
下面三篇文章是德米特里·索什尼科夫Dmitry Soshnikov个人网站上三篇讲JavaScript内在的文章。
- [JavaScript. The Core: 2nd Edition](http://dmitrysoshnikov.com/ecmascript/javascript-the-core-2nd-edition/)
- [JavaScript. The Core (older ES3 version)](http://dmitrysoshnikov.com/ecmascript/javascript-the-core/)
- [JS scope: static, dynamic, and runtime-augmented](https://medium.com/@DmitrySoshnikov/js-scope-static-dynamic-and-runtime-augmented-5abfee6223fe)
“**How JavaScript Works**” 是一组非常不错的文章可能还没有写完强烈推荐。这一系列的文章是SessionStake的CEO写的现在有13篇我感觉可能还没有写完。这个叫 [亚历山大·兹拉特科夫Alexander Zlatkov](https://blog.sessionstack.com/@zlatkov) 的CEO太猛了。
<li>
[An overview of the engine, the runtime, and the call stack](https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf)
</li>
<li>
[Inside the V8 engine + 5 tips on how to write optimized code](https://blog.sessionstack.com/how-javascript-works-inside-the-v8-engine-5-tips-on-how-to-write-optimized-code-ac089e62b12e) 了解V8引擎。这里也推荐 [Understanding V8s Bytecode](https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775) 这篇文章可以让你了解V8引擎的底层字节码。
</li>
<li>
[Memory management + how to handle 4 common memory leaks](https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec) 内存管理和4种常见的内存泄露问题。
</li>
<li>
[Event loop and the rise of Async programming + 5 ways to better coding with async/await](https://blog.sessionstack.com/how-javascript-works-event-loop-and-the-rise-of-async-programming-5-ways-to-better-coding-with-2f077c4438b5) Event Loop和异步编程。
</li>
<li>
[Deep dive into WebSockets and HTTP/2 with SSE + how to pick the right path](https://blog.sessionstack.com/how-javascript-works-deep-dive-into-websockets-and-http-2-with-sse-how-to-pick-the-right-path-584e6b8e3bf7) WebSocket和HTTP/2。
</li>
<li>
[A comparison with WebAssembly + why in certain cases its better to use it over JavaScript](https://blog.sessionstack.com/how-javascript-works-a-comparison-with-webassembly-why-in-certain-cases-its-better-to-use-it-d80945172d79) JavaScript内在原理。
</li>
<li>
[The building blocks of Web Workers + 5 cases when you should use them](https://blog.sessionstack.com/how-javascript-works-the-building-blocks-of-web-workers-5-cases-when-you-should-use-them-a547c0757f6a) Web Workers技术。
</li>
<li>
[Service Workers, their lifecycle and use cases](https://blog.sessionstack.com/how-javascript-works-service-workers-their-life-cycle-and-use-cases-52b19ad98b58) Service Worker技术。
</li>
<li>
[The mechanics of Web Push Notifications](https://blog.sessionstack.com/how-javascript-works-the-mechanics-of-web-push-notifications-290176c5c55d) Web端Push通知技术。
</li>
<li>
[Tracking changes in the DOM using MutationObserver](https://blog.sessionstack.com/how-javascript-works-tracking-changes-in-the-dom-using-mutationobserver-86adc7446401) Mutation Observer技术。
</li>
<li>
[The rendering engine and tips to optimize its performance](https://blog.sessionstack.com/how-javascript-works-the-rendering-engine-and-tips-to-optimize-its-performance-7b95553baeda) ,渲染引擎和性能优化。
</li>
<li>
[Inside the Networking Layer + How to Optimize Its Performance and Security](https://blog.sessionstack.com/how-javascript-works-inside-the-networking-layer-how-to-optimize-its-performance-and-security-f71b7414d34c) ,网络性能和安全相关。
</li>
<li>
[Under the hood of CSS and JS animations + how to optimize their performance](https://blog.sessionstack.com/how-javascript-works-under-the-hood-of-css-and-js-animations-how-to-optimize-their-performance-db0e79586216) CSS和JavaScript动画性能优化。
</li>
接下来是Google Chrome工程经理 [阿迪·奥斯马尼Addy Osmani](https://medium.com/@addyosmani) 的几篇JavaScript性能相关的文章也是非常好的。
- [The Cost Of JavaScript](https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e)
- [JavaScript Start-up Performance](https://medium.com/reloading/javascript-start-up-performance-69200f43b201)
其它与JavaScript相关的资源。
<li>
[JavScript has Unicode Problem](https://mathiasbynens.be/notes/javascript-unicode) 这是一篇很有价值的JavaScript处理Unicode的文章。
</li>
<li>
[JavaScript Algorithms](https://mgechev.github.io/javascript-algorithms/index.html) 用JavaScript实现的各种基础算法库。
</li>
<li>
[JavaScript 30 秒代码](https://github.com/Chalarangelo/30-seconds-of-code) 一堆你可以在30秒内看懂各种有用的JavaScript的代码在GitHub上有2万颗星了。
</li>
<li>
[What the f*ck JavaScript](https://github.com/denysdovhan/wtfjs) 一堆JavaScript搞笑和比较tricky的样例。
</li>
<li>
[Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript) Airbnb的JavaScript的代码规范GitHub上有7万多颗星。
</li>
<li>
[JavaScript Patterns for 2017](https://www.youtube.com/watch?v=hO7mzO83N1Q) YouTube上的一个JavaScript模式分享值得一看。
</li>
# 浏览器原理
你需要了解一下浏览器是怎么工作的,所以,你必需要看《[How browsers work](http://taligarsiel.com/Projects/howbrowserswork1.htm)》。这篇文章受众之大,后来被人重新整理并发布为《[How Browsers Work: Behind the scenes of modern web browsers](https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/)》其中还包括中文版。这篇文章非常非常长所以你要有耐心看完。如果你想看个精简版的可以看我在Coolshell上发的《[浏览器的渲染原理简介](https://coolshell.cn/articles/9666.html)》或是看一下[这个幻灯片](http://arvindr21.github.io/howBrowserWorks)。
然后是对Virtual DOM的学习。Virtual DOM是React的一个非常核心的技术细节它也是前端渲染和性能的关键技术。所以你有必要要好好学习一下这个技术的实现原理和算法。当然前提条件是你需要学习过前面我所推荐过的浏览器的工作原理。下面是一些不错的文章可以帮你学习这一技术。
- [How to write your own Virtual DOM](https://medium.com/@deathmood/how-to-write-your-own-virtual-dom-ee74acc13060)
- [Write your Virtual DOM 2: Props &amp; Events](https://medium.com/@deathmood/write-your-virtual-dom-2-props-events-a957608f5c76)
- [How Virtual-DOM and diffing works in React](https://medium.com/@gethylgeorge/how-virtual-dom-and-diffing-works-in-react-6fc805f9f84e)
- [The Inner Workings Of Virtual DOM](https://medium.com/@rajaraodv/the-inner-workings-of-virtual-dom-666ee7ad47cf)
- [深度剖析:如何实现一个 Virtual DOM 算法](https://github.com/livoras/blog/issues/13)
<li>以及两个Vitual-DOM实现供你参考
<ul>
- [Matt-Esch/Virtual-DOM](https://github.com/Matt-Esch/virtual-dom)
- [Maquette](https://maquettejs.org/)
# 网络协议
<li>
[High Performance Browser Networking](https://book.douban.com/subject/25856314/) 本书是谷歌公司高性能团队核心成员的权威之作堪称实战经验与规范解读完美结合的产物。本书目标是涵盖Web开发者技术体系中应该掌握的所有网络及性能优化知识。
全书以性能优化为主线从TCP、UDP 和TLS协议讲起解释了如何针对这几种协议和基础设施来优化应用。然后深入探讨了无线和移动网络的工作机制。最后揭示了HTTP协议的底层细节同时详细介绍了HTTP 2.0、 XHR、SSE、WebSocket、WebRTC和DataChannel等现代浏览器新增的能力。
</li>
<li>
另外,[HTTP/2](https://en.wikipedia.org/wiki/HTTP/2)也是HTTP的一个新的协议于2015年被批准通过现在基本上所有的主流浏览器都默认启用这个协议。所以你有必要学习一下这个协议。下面相关的学习资源。
<ul>
- [Gitbook - HTTP/2详解](https://legacy.gitbook.com/book/ye11ow/http2-explained/details)
- [http2 explained](http://daniel.haxx.se/http2/)[中译版](https://www.gitbook.com/book/ye11ow/http2-explained/details)
- [HTTP/2 for a Faster Web](https://cascadingmedia.com/insites/2015/03/http-2.html)
- [Nginx HTTP/2 白皮书](https://www.nginx.com/wp-content/uploads/2015/09/NGINX_HTTP2_White_Paper_v4.pdf)
<li>HTTP/2的两个RFC
<ul>
- [RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)](https://httpwg.org/specs/rfc7540.html) HTTP/2的协议本身。
- [RFC 7541 - HPACK: Header Compression for HTTP/2](https://httpwg.org/specs/rfc7541.html) HTTP/2的压缩算法。
新的HTML5支持 [WebSocket](https://en.wikipedia.org/wiki/WebSocket),所以,这也是你要学的一个重要协议。
<li>
[HTML5 WebSocket: A Quantum Leap in Scalability for the Web](http://www.websocket.org/quantum.html) 这篇文章比较了HTTP的几种链接方式Polling、Long Polling和Streaming并引入了终级解决方案WebSocket。你知道的了解一个技术的缘由是非常重要的。
</li>
<li>
[StackOverflow: My Understanding of HTTP Polling, Long Polling, HTTP Streaming and WebSockets](https://stackoverflow.com/questions/12555043/my-understanding-of-http-polling-long-polling-http-streaming-and-websockets) 这是StackOverflow上的一个HTTP各种链接方式的比较也可以让你有所认识。
</li>
<li>
[An introduction to Websockets](http://blog.teamtreehouse.com/an-introduction-to-websockets) 一个WebSocket的简单教程。
</li>
<li>
[Awesome Websockets](https://github.com/facundofarias/awesome-websockets) GitHub的Awesome资源列表。
</li>
<li>
一些和WebSocket相关的想法可以开阔你的思路
<ul>
- [Introducing WebSockets: Bringing Sockets to the Web](https://www.html5rocks.com/en/tutorials/websockets/basics/)
- [Websockets 101](http://lucumr.pocoo.org/2012/9/24/websockets-101/)
- [Real-Time Web by Paul Banks](https://banksco.de/p/state-of-realtime-web-2016.html)
- [Are WebSockets the future?](https://samsaffron.com/archive/2015/12/29/websockets-caution-required)
# 小结
总结一下今天的内容。我一直认为学习任何知识都要从基础出发所以今天我主要讲述了HTML 5、CSS 3和JavaScriptES6这三大基础核心给出了大量的图书、文章以及其他一些相关的学习资源。之后我建议你学习浏览器的工作原理和网络协议相关的内容。我认为掌握这些原理也是学好前端知识的前提和基础。值得花时间好好学习消化。
下篇文章中,我们将讲讲如何做前端性能优化,并推荐一些好用的前端框架。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,279 @@
<audio id="audio" title="88 | 程序员练级攻略:前端性能优化和框架" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/c0/f9/c0b0b028f2dee2cb86601fc8a0f097f9.mp3"></audio>
# 前端性能优化
首先是推荐几本前端性能优化方面的图书。
<li>
[Web Performance in Action](http://www.allitebooks.in/web-performance-action/) 这本书目前国内没有卖的。你可以看电子版本我觉得是一本很不错的书其中有CSS、图片、字体、JavaScript性能调优等。
</li>
<li>
[Designing for Performance](http://designingforperformance.com/) ,这本在线的电子书很不错,其中讲了很多网页优化的技术和相关的工具,可以让你对整体网页性能优化有所了解。
</li>
<li>
[High Performance JavaScript](https://book.douban.com/subject/5362856/) 这本书在国内可以买到能让你了解如何提升各方面的性能包括代码的加载、运行、DOM交互、页面生存周期等。雅虎的前端工程师尼古拉斯·扎卡斯Nicholas C. Zakas和其他五位JavaScript专家介绍了页面代码加载的最佳方法和编程技巧来帮助你编写更为高效和快速的代码。你还会了解到构建和部署文件到生产环境的最佳实践以及有助于定位线上问题的工具。
</li>
<li>
[High Performance Web Sites: Essential Knowledge for Front-End Engineers](https://book.douban.com/subject/26411563/) 这本书国内也有卖翻译版为《高性能网站建设指南前端工程师技能精髓》。作者给出了14条具体的优化原则每一条原则都配以范例佐证并提供了在线支持。
全书内容丰富主要包括减少HTTP请求、Edge Computing技术、Expires Header技术、gzip组件、CSS和JavaScript最佳实践、主页内联、Domain最小化、JavaScript优化、避免重定向的技巧、删除重复JavaScript的技巧、关闭ETags的技巧、Ajax缓存技术和最小化技术等。
</li>
<li>
除了上面这几本书之外Google的 [Web Fundamentals](https://developers.google.com/web/fundamentals/) 里的 [Performance](https://developers.google.com/web/fundamentals/performance/why-performance-matters/) 这一章节也有很多非常不错的知识和经验。
</li>
接下来是一些最佳实践性的文档。
<li>
[Browser Diet](http://browserdiet.com/zh/) ,前端权威性能指南(中文版)。这是一群为大型站点工作的专家们建立的一份前端性能的工作指南。
</li>
<li>
[PageSpeed Insights Rules](https://developers.google.com/speed/docs/insights/rules) ,谷歌给的一份性能指南和最佳实践。
</li>
<li>
[Best Practices for Speeding Up Your Web Site](https://developer.yahoo.com/performance/rules.html) 雅虎公司给的一份7个分类共35个最佳实践的文档。
</li>
接下来,重点推荐一个性能优化的案例学习网站 [WPO Stats](https://wpostats.com/) 。WPO是Web Performance Optimization的缩写这个网站上有很多很不错的性能优化的案例分享一定可以帮助你很多。
然后是一些文章和案例。
<li>
[A Simple Performance Comparison of HTTPS, SPDY and HTTP/2](http://blog.httpwatch.com/2015/01/16/a-simple-performance-comparison-of-https-spdy-and-http2/) 这是一篇比较浏览器的HTTPS、SPDY和HTTP/2性能的文章除了比较之外还可以让你了解一些技术细节。
</li>
<li>
[7 Tips for Faster HTTP/2 Performance](https://www.nginx.com/blog/7-tips-for-faster-http2-performance/) 对于HTTP/2来说Nginx公司给出的7个增加其性能的小提示。
</li>
<li>
[Reducing Slacks memory footprint](https://slack.engineering/reducing-slacks-memory-footprint-4480fec7e8eb) Slack团队减少内存使用量的实践。
</li>
<li>
[Pinterest: Driving user growth with performance improvements](https://medium.com/@Pinterest_Engineering/driving-user-growth-with-performance-improvements-cfc50dafadd7) Pinterest关于性能调优的一些分享其中包括了前后端的一些性能调优实践。其实也是一些比较通用的玩法这篇文章主要是想让前端的同学了解一下如何做整体的性能调优。
</li>
<li>
[10 JavaScript Performance Boosting Tips](http://jonraasch.com/blog/10-javascript-performance-boosting-tips-from-nicholas-zakas) 10个提高JavaScript运行效率的小提示挺有用的。
</li>
<li>
[17 Statistics to Sell Web Performance Optimization](http://www.guypo.com/17-statistics-to-sell-web-performance-optimization/) 这个网页上收集了好些公司的Web性能优化的工程分享都是非常有价值的。
</li>
<li>
[Getting started with the Picture Element](http://deanhume.com/Home/BlogPost/getting-started-with-the-picture-element/8109) 这篇文章讲述了Responsive布局所带来的一些负面的问题。主要是图像适配的问题其中引出了一篇文章"[Native Responsive Images](https://dev.opera.com/articles/native-responsive-images/)" ,值得一读。
</li>
<li>
[Improve Page Load Times With DNS Prefetching](http://www.deanhume.com/Home/BlogPost/improve-page-load-times-with-dns-prefetching/80) 这篇文章教了你一个如何降低DNS解析时间的小技术——DNS prefetching。
</li>
<li>
[Jank Busting for Better Rendering Performance](http://www.html5rocks.com/en/tutorials/speed/rendering/) 这是一篇Google I/O上的分享关于前端动画渲染性能提升。
</li>
<li>
[JavaScript Memory Profiling](https://developer.chrome.com/devtools/docs/javascript-memory-profiling) 这是一篇谷歌官方教你如何使用Chrome的开发工具来分析JavaScript内存问题的文章。
</li>
接下来是一些性能工具。在线性能测试分析工具太多,这里只推荐比较权威的。
<li>
[PageSpeed](https://developers.google.com/speed/pagespeed/) 谷歌有一组PageSpeed工具来帮助你分析和优化网站的性能。Google出品的质量相当有保证。
</li>
<li>
[YSlow](https://github.com/marcelduran/yslow) ,雅虎的一个网页分析工具。
</li>
<li>
[GTmetrix](https://gtmetrix.com/) 是一个将PageSpeed和YSlow合并起来的一个网页分析工具并且加上一些Page load或是其它的一些分析。也是一个很不错的分析工具。
</li>
<li>
[Awesome WPO](https://github.com/davidsonfellipe/awesome-wpo) 在GitHub上的这个Awesome中你可以找到更多的性能优化工具和资源。
</li>
另外中国的网络有各种问题你懂的所以你不能使用Google共享的JavaScript链接来提速你得用中国自己的。你可以到这里看看中国的共享库资源[Forget Google and Use These Hosted JavaScript Libraries in China](http://chineseseoshifu.com/blog/china-hosted-javascript-libraries-jquery-dojo-boostrap.html) 。
# 前端框架
接下来要学习的是Web前端的几大框架。目前而言前端社区有三大框架Angular.js、React.js和Vue.js。我认为React和Vue更为强劲一些所以我这里只写和React和Vue相关的攻略。关于两者的比较网上有好多文章。我这里推荐几篇我觉得还不错的供你参考。
- [Angular vs. React vs. Vue: A 2017 comparison](https://medium.com/unicorn-supplies/angular-vs-react-vs-vue-a-2017-comparison-c5c52d620176)
- [React or Vue: Which JavaScript UI Library Should You Be Using?](https://medium.com/js-dojo/react-or-vue-which-javascript-ui-library-should-you-be-using-543a383608d)
- [ReactJS vs Angular5 vs Vue.js-What to choose in 2018?](https://medium.com/@TechMagic/reactjs-vs-angular5-vs-vue-js-what-to-choose-in-2018-b91e028fa91d)
其实,比较这些框架的优缺点还有利弊并不是要比出个输赢,而是让你了解一下不同框架的优缺点。我觉得,这些框架都是可以学习的。而在我们生活工作中具体要用哪个框架,最好还是要有一些出发点,比如,你是为了找份好的工作,为了快速地搭一个网站,为了改造一个大规模的前端系统,还是纯粹地为了学习……
不同的目的会导致不同的决定。我并不希望上述的这些比较会让你进入“二选一”或是“三选一”的境地。我只是想通过这些文章让你知道这些框架的设计思路和实现原理,这些才是让你受益一辈子的事。
## React.js框架
下面先来学习一下React.js框架。
**入门**
React学起来并不复杂就看 [React 官方教程](https://reactjs.org/tutorial/tutorial.html) 和其文档就好了( [React 的中文教程](https://doc.react-china.org/) )。
然后下面的文章会带你了解一下React.js的基本原理。
<li>
[All the fundamental React.js concepts](https://medium.freecodecamp.org/all-the-fundamental-react-js-concepts-jammed-into-this-single-medium-article-c83f9b53eac2) 这篇文章讲了所有的React.js的基本原理。
</li>
<li>
[Learn React Fundamentals and Advanced Patterns](https://blog.kentcdodds.com/learn-react-fundamentals-and-advanced-patterns-eac90341c9db) 这篇文章中有几个短视频每个视频不超过5分钟是学习React的一个很不错的地方。
</li>
<li>
[Thinking in React](https://reactjs.org/docs/thinking-in-react.html)这篇文章将引导你完成使用React构建可搜索产品数据表的思考过程。
</li>
**提高**
学习一个技术最重要的是要学到其中的思想和方法。下面是一些我觉得学习React中最重要的东西。
<li>
**状态**,对于富客户端来说是非常麻烦也是坑最多的地方,这里有几篇文章你可以一读。
<ul>
<li>
[Common React.js mistakes: Unneeded state](http://reactkungfu.com/2015/09/common-react-dot-js-mistakes-unneeded-state/) React.js编程的常见错误——不必要的状态。
</li>
<li>
[State is an Anti-Pattern](https://www.reddit.com/r/reactjs/comments/3bjdoe/state_is_an_antipattern/) ,关于如何做一个不错的组件的思考,很有帮助。
</li>
<li>
[Why Local Component State is a Trap](https://www.safaribooksonline.com/blog/2015/10/29/react-local-component-state/) ,一些关于 “Single state tree” 的想法。
</li>
<li>
[Thinking Statefully](https://daveceddia.com/thinking-statefully/) ,几个很不错的例子让你对声明式有状态的技术有更好的理解。
</li>
<li>
传统上解决React的状态问题一般用Redux。在这里推荐 [Tips to learn React + Redux in 2018](https://www.robinwieruch.de/tips-to-learn-react-redux/) 。Redux是一个状态粘合组件一般来说我们会用Redux来做一些数据状态和其上层Component上的同步。这篇教程很不错。
</li>
<li>
最后是 "State Architecture Patterns in React " 系列文章,非常值得一读。
<ul>
- [Part 1: A Review](https://medium.com/@skylernelson_64801/state-architecture-patterns-in-react-a-review-df02c1e193c6)
- [Part 2: The Top-Heavy Architecture, Flux and Performance](https://medium.com/@skylernelson_64801/state-architecture-patterns-in-react-part-2-the-top-heavy-architecture-flux-and-performance-a388b928ce89)
- [Part 3: Articulation Points, zine and An Overall Strategy](https://medium.com/@skylernelson_64801/state-architecture-patterns-in-react-part-3-articulation-points-zine-and-an-overall-strategy-cf076f906391)
- [Part 4: Purity, Flux-duality and Dataflow](https://medium.com/@skylernelson_64801/state-architecture-patterns-in-react-part-4-purity-flux-duality-and-dataflow-d06016b3379a)
**函数式编程**。从jQuery过来的同学一定非常不习惯React而从Java等后端过来的程序员就会很习惯了。所以我觉得React就是后端人员开发的或者说是做函数式编程的人开发的。对此你需要学习一下JavaScript函数式编程的东西。
这里推荐一本免费的电子书 《[Professor Frisbys Mostly Adequate Guide to Functional Programming](https://github.com/MostlyAdequate/mostly-adequate-guide)》,其中译版为《[JS函数式编程指南中文版](https://jigsawye.gitbooks.io/mostly-adequate-guide/content/)》。
下面有几篇文章非常不错。前两篇和函数式编程有关的文章非常值得一读。后三篇是一些比较实用的函数式编程和React结合的文章。
- [Master the JavaScript Interview: What is Functional Programming?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0?utm_source=mybridge&amp;utm_medium=email&amp;utm_campaign=read_more)
- [The Rise and Fall and Rise of Functional Programming (Composing Software)](https://medium.com/javascript-scene/the-rise-and-fall-and-rise-of-functional-programming-composable-software-c2d91b424c8c)
- [Functional UI and Components as Higher Order Functions](https://blog.risingstack.com/functional-ui-and-components-as-higher-order-functions/)
- [Functional JavaScript: Reverse-Engineering the Hype](http://banderson.github.io/functional-js-reverse-engineering-the-hype/)
- [Some Thoughts on Function Components in React](https://medium.com/javascript-inside/some-thoughts-on-function-components-in-react-cb2938686bc7)
**设计相关**。接下来是学习一些React的设计模式。[React Pattern](https://reactpatterns.com/) 是一个不错的学习React模式的地方。除此之外还有如下的一些不错的文章也会对你很有帮助的。
- [React Higher Order Components in depth](https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e)
- [Presentational and Container Components](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)
- [Controlled and uncontrolled form inputs in React dont have to be complicated](https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/)
- [Function as Child Components](https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9)
- [Writing Scalable React Apps with the Component Folder Pattern](https://medium.com/styled-components/component-folder-pattern-ee42df37ec68)
- [Reusable Web Application Strategies](https://medium.freecodecamp.org/reusable-web-application-strategies-d51517ea68c8)
- [Characteristics of an Ideal React Architecture](https://medium.com/@robftw/characteristics-of-an-ideal-react-architecture-883b9b92be0b)
**实践和经验**
还有一些不错的实践和经验。
- [9 things every React.js beginner should know](https://camjackson.net/post/9-things-every-reactjs-beginner-should-know)
- [Best practices for building large React applications](https://engineering.siftscience.com/best-practices-for-building-large-react-applications/)
- [Clean Code vs. Dirty Code: React Best Practices](https://americanexpress.io/clean-code-dirty-code/)
- [How to become a more productive React Developer](https://dev.to/jakoblind/how-to-become-a-more-productive-react-developer)
- [8 Key React Component Decisions](https://medium.freecodecamp.org/8-key-react-component-decisions-cc965db11594)
**资源列表**
最后就是React的资源列表。
<li>
[Awesome React](https://github.com/enaqx/awesome-react) 这是一些React相关资源的列表很大很全。
</li>
<li>
[React/Redux Links](https://github.com/markerikson/react-redux-links) 这也是React相关的资源列表与上面不一样的是这个列表主要收集了大量的文章其中讲述了很多React知识和技术比上面的列表好很多。
</li>
<li>
[React Rocks](https://react.rocks/) 这个网站主要收集各种React的组件示例可以让你大开眼界。
</li>
## Vue.js框架
Vue可能是一个更符合前端工程师习惯的框架。不像React.js那样使用函数式编程方式是后端程序员的思路。
<li>
通过文章 “[Why 43% of Front-End Developers want to learn Vue.js](https://medium.com/vue-mastery/why-43-of-front-end-developers-want-to-learn-vue-js-7f23348bc5be)” 你可以看出其编程方式和React是大相径庭的符合传统的前端开发的思维方式。
</li>
<li>
通过文章 [Replacing jQuery With Vue.js: No Build Step Necessary](https://www.smashingmagazine.com/2018/02/jquery-vue-javascript/) 我们可以看到从jQuery是可以平滑过渡到Vue的。
</li>
<li>
另外,我们可以通过 “[10 things I love about Vue](https://medium.com/@dalaidunc/10-things-i-love-about-vue-505886ddaff2)” 了解Vue的一些比较优秀的特性。
</li>
最令人高兴的是Vue的作者是我的好朋友尤雨溪Evan You最近一次对他的采访 “[Vue on 2018-Interview with Evan You](https://blog.hackages.io/https-blog-hackages-io-evanyoubhack2017-cc5559806157)” 当中有很多故事以及对Vue的展望。**注意Vue是完全由其支持者和用户资助的这意味着它更接近社区而不受大公司的控制。**
要学习Vue并不难我认为上官网看文档 [Vue 官方文档](http://vuejs.org/guide/)[中文版](https://cn.vuejs.org/v2/guide/))),照着搞一搞就可以很快上手了。[Vue.js screencasts](https://laracasts.com/series/learn-vue-2-step-by-step) 是一个很不错的英文视频教程。
另外,推荐 [新手向Vue 2.0的建议学习顺序](https://zhuanlan.zhihu.com/p/23134551) 这是Vue作者写的所以有特殊意义。
Vue的确比较简单有Web开发经验的人上手也比较快所以这里也不会像React那样给出很多的资料。下面是一些我觉得还不错的内容推荐给你。
<li>
[How not to Vue](https://itnext.io/how-not-to-vue-18f16fe620b5) 任何技术都有坑了解Vue的短板你就能扬长避短就能用得更好。
</li>
<li>
[Vue.js Component Communication Patterns](https://alligator.io/vuejs/component-communication/)
</li>
<li>
[4 AJAX Patterns For Vue.js Apps](https://medium.com/js-dojo/4-ajax-patterns-for-vue-js-apps-add915fc9168)
</li>
<li>
[How To (Safely) Use A jQuery Plugin With Vue.js](https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/)
</li>
<li>
[7 Ways To Define A Component Template in Vue.js](https://vuejsdevelopers.com/2017/03/24/vue-js-component-templates/)
</li>
<li>
[Use Any Javascript Library With Vue.js](https://vuejsdevelopers.com/2017/04/22/vue-js-libraries-plugins/)
</li>
<li>
[Dynamic and async components made easy with Vue.js](https://lobotuerto.com/blog/dynamic-and-async-components-made-easy-with-vuejs/)
</li>
当然,最后一定还有 [Awesome Vue](https://github.com/vuejs/awesome-vue) Vue.js里最为巨大最为优秀的资源列表。
# 小结
总结一下今天的内容。我先介绍的是前端性能优化方面的内容推荐了图书、最佳实践性的文档、案例以及一些在线性能测试分析工具。随后重点讲述了React和Vue两大前端框架给出了大量的文章、教程和相关资源列表。我认为React.js使用函数式编程方式更加符合后端程序员的思路而Vue是更符合前端工程师习惯的框架。因此两者比较起来Vue会更容易上手一些。
下篇文章我们将讲述前端工程师的一个基本功——UI/UX设计。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,246 @@
<audio id="audio" title="89 | 程序员练级攻略UI/UX设计" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/63/75/633949bccd7cc11f181f09a0f3d95975.mp3"></audio>
上面的技术都讲完了,前端还有一个很重要的事就是设计。作为前端人员,我们有必要了解现在的一些知名且流行的设计语言或是一些设计规范或是设计方法,学习它们的设计思想和方法,有助于我们拓宽眼界、与时俱进。我并不觉得这些内容是设计师要学习的,如果你要成为一个前端程序员,那么学习这些设计上的东西可以让你有更好的成长空间。
对于学习设计的新手来说,推荐看看 [7 steps to become a UI/UX designer](https://blog.nicolesaidy.com/7-steps-to-become-a-ui-ux-designer-8beed7639a95) 这是一篇很不错的让新手入门的文章非常具有指导性。首先你得开始学习设计的一些原则和套路如配色、平衡、排版、一致性等。还有用户体验的4D步骤——Discover、Define、Develop 和 Delivery。然后开始到一些网站上找灵感。接下来是到不同的网站上读各种文章和资源开始学习使用设计工具最后是找人拜师。此外其中还链接了其它一些不错的文章、网站、博客和工具。我认为这篇文章是一篇很不错的设计师从入门到精通的练级攻略。
虽然有这么一个速成的教程,但我觉得还是应该系统地学习一下,所以有了下面这些推荐。
# 图书和文章推荐
先推荐几本书。
<li>
[Dont Make Me Think](https://book.douban.com/subject/1827702/) ,这是我看的第一本和设计相关的书。这本书对我的影响也比较深远。这本书践行了自己的理论,整本书短小精悍,语言轻松诙谐,书中穿插大量色彩丰富的屏幕截图、趣味丛生的卡通插图以及包含大量信息的图表,使枯燥的设计原理变得平易近人。
</li>
<li>
[Simple and Usable Web,Mobile,and Interaction Design](https://book.douban.com/subject/5394309/) 中文版译名为《简约至上》。本书作者贾尔斯Giles有20多年交互式设计的探索与实践。提出了合理删除、分层组织、适时隐藏和巧妙转移这四个达成简约至上的终极策略讲述了为什么应该站在主流用户一边以及如何从他们的真实需求和期望出发简化设计提升易用性。
</li>
<li>
[Designing with the Mind in Mind: Simple Guide to Understanding User Interface Design Rules](https://book.douban.com/subject/6792322/) 中文版译名为《认知与设计理解UI设计准则》。这本书语言清晰明了将设计准则与其核心的认知学和感知科学高度统一起来使得设计准则更容易在具体环境中得到应用。涵盖了交互计算机系统设计的方方面面为交互系统设计提供了支持工程方法。不仅如此这也是一本人类行为原理的入门书。
</li>
<li>
[Designing Interfaces: Patterns for Effective Interaction Design](https://book.douban.com/subject/25716088/) ,中文版译名为《界面设计模式》。这本书开篇即总结了“与人有关”的各类问题,为读者提供了界面设计总体思路上的指引,帮助读者举一反三。然后,收集并分析了很多常用的界面设计模式,帮助读者理解在实现级别的各种常用解决方案,将它们灵活地运用到自己的设计中。
</li>
除了上面的这几本书,还有下面的这几篇文章也是很不错的,推荐一读。
<li>
[The Psychology Principles Every UI/UX Designer Needs to Know](https://uxplanet.org/the-psychology-principles-every-ui-ux-designer-needs-to-know-24116fd65778) 这篇文章讲述了6大用户界面用户体验设计的心理学原则。
</li>
<li>
[18 designers predict UI/UX trends for 2018](https://blog.figma.com/18-designers-predict-ui-ux-trends-for-2018-2d04d41361c6) 我倒不觉得这篇文章中所说的UI/UX是在2018年的趋势我反而觉得这18条原则是指导性的思想。
</li>
<li>
[The Evolution of UI/UX Designers Into Product Designers](https://medium.com/thinking-design/the-evolution-of-ui-ux-designers-into-product-designers-623e4e7eaab3) 这篇文章是Adobe公司的一篇博客其在回顾整个产品设计的演化过程中有一些不错的思考和想法并提供了一些方法论。
</li>
# 原子设计Atomic Design
在2013年网页设计师布拉德·弗罗斯特Brad Frost从化学中受到启发原子Atoms结合在一起形成分子Molecules进一步结合形成生物体Organisms。布拉德将这个概念应用在界面设计中我们的界面就是由一些基本的元素组成的。
乔希·杜克Josh Duck的“HTML元素周期表”完美阐述了我们所有的网站、App、企业内部网、hoobadyboops等是如何由相同的HTML元素组成的。通过在大层面和小层面原子同时思考界面布拉德认为可以利用原子设计建立一个适应组件的动态系统。
为什么要玩原子设计我认为这对程序员来说是非常好理解的因为这就是代码模块化重用化的体现。于是你就是要像搭积木一样开发和设计网页当你把其模块化组件化了也更容易规范整体的风格而且容易维护……这些都意味着你可以更容易地维护你的代码。所以这个方法论导致了Web组件化的玩法。这是设计中非常重要的方法论。
关于这个设计方法论,你可以阅读一下下面这几篇文章。
- [Atomic Design原子设计┃构建科学规范的设计系统](https://www.jianshu.com/p/13e87bf4f857)
- [网页设计Atomic Design简介及工作实例](https://medium.com/uxeastmeetswest/%E7%B6%B2%E9%A0%81%E8%A8%AD%E8%A8%88-atomic-design%E7%B0%A1%E4%BB%8B%E5%8F%8A%E5%B7%A5%E4%BD%9C%E5%AF%A6%E4%BE%8B-42e666358d52)
但是,真正权威的地方还是布拉德·弗罗斯特的电子书、博客和实验室,可以从中获取更多的信息。
- [电子书Atomic Design by Brad Frost](http://atomicdesign.bradfrost.com) 是布拉德·弗罗斯特写的一本书。
- [ Atomic Design](http://bradfrost.com/blog/post/atomic-web-design/) 是布拉德·弗罗斯特的博客。
- [实验室Pattern lab](http://patternlab.io) 是布拉德·弗罗斯特依照这个设计系统所建立的一套工具可以前往Pattern Lab的 [GitHub](https://github.com/bradfrost/patternlab) 来试试Atomic design。
接下来是关于这个设计方法和React.js框架的几篇文章。
- [Atomic Design with React](https://codeburst.io/atomic-design-with-react-e7aea8152957)
- [Atomic Components: Managing Dynamic React Components using Atomic Design](https://medium.com/@yejodido/atomic-components-managing-dynamic-react-components-using-atomic-design-part-1-5f07451f261f)
# 设计语言和设计系统
下面来介绍一下设计语言和设计系统。
## Fluent Design System
[**Fluent Design System**](https://fluent.microsoft.com) 中文翻译为流畅设计体系是微软于2017年开发的设计语言。流畅设计是Microsoft Design Language 2的改版其中包含为所有面向Windows 10设备和平台设计的软件中的设计和交互的指导原则。
该体系基于五个关键元素光感、深度、动效、材质和缩放。新的设计语言包括更多对动效、深度及半透明效果的使用。过渡到流畅设计体系是一个长期项目没有具体的完成目标但是从创作者更新以来新设计语言的元素已被融入到个别应用程序中。它将在未来的Windows 10秋季创作者更新中更广泛地使用但微软也表示该设计体系不会在秋季创作者更新内完成。
微软于2017年5月11日的Microsoft Build 2017开发者大会上公开了该设计体系。
<li>
[Whats new and coming for Windows UI: XAML and composition](https://channel9.msdn.com/Events/Build/2017/B8100) 从概念上讲了一下Fluent Design System的各个部分。
</li>
<li>
[Introducing Fluent Design](https://channel9.msdn.com/Events/Build/2017/B8066) 介绍了Fluent Design System的各个部分。
</li>
还有Build 2018上的一些微软的YouTube分享。
- [Fluent Design: Evolving our Design System : Build 2018](https://www.youtube.com/watch?v=AnqwdPgVXAI)
- [Microsoft Build 2018 - Fluent Design System Demo](https://www.youtube.com/watch?v=dMq8CMIE1xU)
- [Microsoft Build 2018 - Fluent Design System Evolution](https://www.youtube.com/watch?v=pUuHSuCnDGE)
- [Fluent Design System inside of Microsoft: Office : Build 2018](https://www.youtube.com/watch?v=DKvkRfQD8Yg)
## Material Design
[**Material Design**](https://material.io) 中文翻译为质感设计或是材质设计、材料设计。这是由Google开发的设计语言。扩展于 [Google Now](https://en.wikipedia.org/wiki/Google_Now) 的“卡片”设计Material Design基于网格的布局、响应动画与过渡、填充、深度效果如光线和阴影。设计师马蒂亚斯·杜阿尔特Matías Duarte解释说“与真正的纸张不同我们的数字材质可以智能地扩大和变形。材质具有实体的表面和边缘。接缝和阴影表明组件的含义。”Google指出他们的新设计语言基于纸张和油墨。
Material Design于2014年的Google I/O大会上发布参看 [Google I/O 2014 - Material witness: How Android material applications work](https://www.youtube.com/watch?v=97SWYiRtF0Y&amp;feature=youtu.be)。其可借助v7 appcompat库用于Android 2.1及以上版本几乎支持所有2009年以后制造的Android设备。随后Material Design扩展到Google的网络和移动产品阵列提供一致的跨平台和应用程序体验。Google还为第三方开发人员发布了API开发人员可将质感设计应用到他们的应用程序中。
除了到 [官网](https://material.io) 学习 Material Design你还可以访问 [Material Design 中文版](http://design.1sters.com/) 来学习。
另外Wikipedia 上有一张 [Material Design 实现的比较表](https://en.wikipedia.org/wiki/Comparison_of_Material_Design_implementations),供你参考。
下面是几个可供你使用的Material UI的工程实现。
<li>
[Material Design Lite](https://www.getmdl.io/) ,这是 Google 官方的框架,简单易用。
</li>
<li>
[Materialize](https://materializecss.com/) 一组类似于Bootstrap的前端UI框架。
</li>
<li>
[Material-UI](https://material-ui.com/) 是基于Google Material Design的React组件实现。
</li>
<li>
[MUI](https://www.muicss.com/) 是一个轻量级的CSS框架遵循Google的Material Design设计方针。
</li>
## 其它公司
接下来再来推荐其它几家公司的设计语言。
<li>
[苹果公司的设计指南](https://developer.apple.com/design/)在这个网站有苹果的各种设备的设计规范和指导一方面可以让你的App能和苹果的UI融合在一起另一方面你也可以从中看到苹果的审美和思维方式。
</li>
<li>
[IBM公司的设计语言](https://www.ibm.com/design/language/) 我们总觉得IBM公司是一家比较传统的没有新意的公司但是并不是这样的。IBM公司的这个设计语言的确比较出众。所以在这里推荐一下。
</li>
<li>
[Salesforce公司的Lightning Design System](https://www.lightningdesignsystem.com/) 是在Salesforce生态系统中用于创建统一UI的设计模式、组件和指南的集合是一个企业级的产品。
</li>
<li>
[Facebook Design - Whats on our mind?](http://facebook.design/) Facebook的设计师们收集的一系列的文章、视频和资源。很不错哦。
</li>
## 动画效果设计
我认为要了解Web动画效果设计的第一步最好的地方是 [CodePen](https://codepen.io/)。这个网站不只是让人分享HTML、CSS和JavaScript代码的网站。其中也有很多分享样例都和动画效果有关。这个网站可以让你对动画效果有一些感性认识当然还有代码供你参考。
接下来,我们要了解动画效果设计的一些方法。基本上来说,动画设计都会受 “[动画的12项基本法则](https://en.wikipedia.org/wiki/12_basic_principles_of_animation) ”的影响这个方法论源自于迪士尼动画师奥利·约翰斯顿Ollie Johnston和弗兰克·托马斯Frank Thomas在1981年所出的《The Illusion of Life: Disney Animation》一书。这些法则已被普遍采用至今仍与制作3D动画法则有关联。这里还有一篇文章 “[Understand the 12 principles of animation](https://www.creativebloq.com/advice/understand-the-12-principles-of-animation)” 是对这个法则的解读和理解。
除此之外,还有几个动画设计指南和相关文章供你参考和学习。
<li>
[6 Animation Guidelines for UX Design](https://blog.prototypr.io/6-animation-guidelines-for-ux-design-74c90eb5e47a)。这是Prototypr公司的一个指南其中主要指出动画效果不是为了炫配而是能让你的UI/UX能活起来自然不消耗时间并且是生动故事型的动画效果。其中还推荐了如下几篇很不错的文章。
<ul>
- [Transitional Interfaces](https://medium.com/@pasql/transitional-interfaces-926eb80d64e3)
- [UI Animation and UX: A Not-So-Secret Friendship](https://alistapart.com/article/ui-animation-and-ux-a-not-so-secret-friendship)
- [Invisible animation](https://medium.com/@stevenfabre/invisible-animation-ffa27d0b77e5)
- [Creating Usability with Motion: The UX in Motion Manifesto](https://medium.com/ux-in-motion/creating-usability-with-motion-the-ux-in-motion-manifesto-a87a4584ddc)
[Designing Interface Animation](http://alistapart.com/article/designing-interface-animation) ,这篇文章同样说明,任何一个小动画都是要讲一个微故事的,而且这些微故事会和你的品牌和产品理念相融合。动画会给人更深的印象,让人们更容易记住你。这篇文章主要是讲品牌动画。
[Animation principles in motion design](https://www.freepik.com/blog/animation-principles-in-motion-design/) ,这篇文章有点像设计模式,给了一些动画效果的套路和演示。
[Creating Usability with Motion: The UX in Motion Manifesto](https://medium.com/ux-in-motion/creating-usability-with-motion-the-ux-in-motion-manifesto-a87a4584ddc)
[Integrating Animation into a Design System](http://alistapart.com/article/integrating-animation-into-a-design-system)
Great UI/UX Animations是设计师丹尼尔Daniel收集的一些很不错的动画可以给你一些灵感。
- [Great UI/UX Animations 第一组](https://fromupnorth.com/mixed-ui-ux-animations-4d7a22f9ab7)
- [Great UI/UX Animations 第二组](https://fromupnorth.com/great-ui-ux-animations-3e9a0baa336f)
# 相关资源
下面分享一下UI/UX设计的相关资源。文章资源主要有以下这些。
## 文章资源
<li>
[Web Designer News](http://webdesignernews.com) ,一个文章聚合的网站。除此之外,还有两个文章聚合网站,你也可以订阅。一个是[Designer News](https://www.designernews.co/) ,另一个是 [Reddit Web Design](https://www.reddit.com/r/web_design/)。
</li>
<li>
[Marvel Blog](http://blog.marvelapp.com) Marvel团队的博客。
</li>
<li>
[The Next Web](http://thenextweb.com/section/creative/) ,内容主要涵盖国际技术新闻、商业和文化等多个方面。
</li>
<li>
[Medium - Design](https://medium.com/design) Medium现在已经成为一个好文章的集散地了这个地方必去。
</li>
<li>
[Smashing Magazine](http://smashingmagazine.com) 这个地方是给专业的Web设计师和程序员的。不但有设计还有HTML、CSS和JavaScript等各种资源。
</li>
<li>
[Sitepoint](https://www.sitepoint.com/design-ux/) 这个网站上也有很多不错的给Web前端程序员和设计师看的文章当然给程序员看的有点简单了我觉得更像是让设计师来学写程序的网站
</li>
## 设计收集
接下来推荐一些优秀设计的聚集地。
<li>
[Awwwards](http://awwwards.com) ,这个网站给一些设计得不错网站的评分,在这里你可以看到很多设计不错的网站。
</li>
<li>
[One Page Love](http://onepagelove.com) ,就是一个单页的网页设计的收集。
</li>
<li>
[Inspired UI](http://inspired-ui.com/) 移动App的设计模式。
</li>
<li>
[Behance](http://behance.net),这个地言有很不错的很有创意的作品。
</li>
<li>
[Dribbble](http://dribbble.com) ,这应该是设计师都知道也都爱去的网站。除了你可以看到一些很不错的作品外,你还可以在这里看到很多不错的设计师。
</li>
<li>
[UI Movement](https://uimovement.com) 也是个设计的收集网站上面有很多很不错的UI设计大量的动画。虽说会像抖音一样让你不知不觉就看了好几小时但是它比抖音让你的收获大多了。
</li>
# 小结
总结一下今天的内容。我并不认为UI/UX设计这些内容只是设计师要学习的如果你要成为一个前端程序员那么学习这些设计上的东西可以让你有更好的成长空间。首先我推荐了一些图书和文章让你更好地了解经典的设计原则和指导思想。
然后介绍了原子设计以及深入学习和理解这一设计方法论的图书、文章和其他相关资源。最后分享了当下主流和知名公司中在用的设计语言和设计系统并给出了大量的学习资源推荐了一些优秀设计的聚集地。相信通过学习这些内容你在UI/UX设计方面不仅能收获方法还能获得非常多的灵感。
下篇文章是程序员练级攻略高手成长篇的最后一篇,我将推荐大量有价值的技术资源,这些内容将会为你后续的学习和成长提供很大的助力。敬请期待。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,254 @@
<audio id="audio" title="90 | 程序员练级攻略:技术资源集散地" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/29/bc/295243ae242a1388e9d4b48da2dfeabc.mp3"></audio>
# 个人技术博客
首先,我先推荐一些不错的个人技术博客。
<li>
[Coding Horror](https://blog.codinghorror.com/) 这是杰夫·阿特伍德Jeff Atwood于2004年创办的博客记录其在软件开发经历中的所思所想、点点滴滴。时至今日该博客每天都有近10万人次的访问量读者纷纷参与评论各种观点与智慧在这里不断地激情碰撞。其博文选集在中国被翻译成《[高效能程序员的修练](https://book.douban.com/subject/24868904/)》在豆瓣上有8.3的高分。2008年他和Joel Spolsky联合创办了 [StackOverflow](https://stackoverflow.com) 问答网站为程序员在开发软件时节省了非常多的时间并开启了“StackOverflow Copy + Paste 式编程”。
</li>
<li>
[Joel on Software](https://joelonsoftware.com/) Joel Spolsky的这个博客在全世界都有很多的读者和粉丝其博文选集在中国被翻译成《[软件随想录](https://book.douban.com/subject/4163938/)》在豆瓣上有8.7的高分。这是一本关于软件技术、人才、创业和企业管理的随想文集,作者以诙谐幽默的笔触将自己在软件行业的亲身感悟娓娓道来,观点新颖独特,简洁实用。
</li>
<li>
[Clean Coder Blog](http://blog.cleancoder.com/) 这是编程大师“Bob 大叔”的博客其真名叫Robert C. Martin世界级软件开发大师设计模式和敏捷开发先驱敏捷联盟首任主席C++ Report前主编被后辈程序员尊称为“Bob大叔”。其博文选集在中国被翻译成《[程序员的职业素养](https://book.douban.com/subject/11614538/)》在豆瓣上有8.8的高分。
</li>
<li>
[Martin Fowler](https://martinfowler.com/) 这是另外一个程序员大师Martin主要专注于面向对象分析与设计、统一建模语言、领域建模以及敏捷软件开发方法包括极限编程。他的《[重构](https://book.douban.com/subject/1229923/)》、《[分析模式](https://book.douban.com/subject/4832380/)》、《[企业应用架构模式](https://book.douban.com/subject/1230559/)》、《[领域特定语言](https://book.douban.com/subject/21964984/)》和《[NoSQL精粹](https://book.douban.com/subject/25662138/)》都是非常不错的书。在他的博客上有很多很多的编程和架构模式方法可以学习。
</li>
<li>
[Paul Graham Essays](http://www.paulgraham.com/articles.html) ,美国著名程序员、风险投资家、博客和技术作家。《[黑客与画家](https://book.douban.com/subject/6021440/)》是他的著作之一。2005年他与人共同创建了科技创业孵化器Y Combinator孵化了Airbnb、Dropbox、Stripe等知名互联网公司。他有几篇创业方面的文章都很经典如果你想创业可以读一读这几篇《[How to Get Startup Ideas](http://paulgraham.com/startupideas.html)》、《[Do Things that Dont Scale](http://paulgraham.com/ds.html)》、《[Startup = Growth](http://www.paulgraham.com/growth.html)》。Paul Graham的文章以清新自然思想深刻见长。不仅可以跟Paul Graham学创业学思考学技术更可以学习写作。
</li>
<li>
[Steve Yegge](https://medium.com/@steve.yegge) Steve Yegge这个人算是一个知名的程序员了在Amazon呆过现在在Google他的文章都是长篇大论最知名的文章就是[对Amazon和Google平台的吐槽](https://coolshell.cn/articles/5701.html),这篇文章引发了大家的讨论和议论。
</li>
<li>
[Bruce Eckels Programming Blog](http://bruceeckel.github.io/) 《Thinking in Java》作者的博客他之前的博客在artima - [Computing Thoughts](https://www.artima.com/weblogs/index.jsp?blogger=beckel) 。
</li>
<li>
[Herb Sutter](https://herbsutter.com/) C++大拿C++标准委员会专家微软软件架构师。《Exceptional C++ 》、《More Exceptional C++》、《Exceptional C++ Style》作者。
</li>
<li>
[Eli Benderskys website](https://eli.thegreenplace.net/) 这位老哥从2003年就一直写博客到今天其中的文章都非常不错原理型的主要是C、C++和Python相关的。里面有很多干货。
</li>
<li>
[Peter Krumins blog ](http://www.catonmat.net/) 这位老哥从2007年开始写博客他博客里好玩的东西太多了。
</li>
<li>
[Brendan D. Gregg](http://www.brendangregg.com/index.html) Brendan是Netflix的工程师他的博客里有大量的非常不错的文章基本上都是和Linux性能分析相关的这是一个如果你要玩底层性能分析一定不能错过的博客。
</li>
<li>
[Evan Klitzke](https://eklitzke.org/) 主要讨论Linux和C++相关的内容。
</li>
<li>
[Julia Evans](https://jvns.ca/) 主要讨论Linux debug工具和网络相关的内容。
</li>
<li>
[null program](http://nullprogram.com/) 和C/C++相关的一个博客。其中关于Linux系统调用、GPU、无锁编程、JIT编译的一些文章非常不错。
</li>
<li>
[Fluent {C++}](http://www.fluentcpp.com/) 博主是Murex的首席工程师主要玩C++在这个博客里有很多很不错的C++相关的文章。
</li>
<li>
[Preshing on Programming](http://preshing.com/) 这也是一个和C/C++相关的博客,其中有很多的干货。
</li>
<li>
[Programming is Terrible](https://programmingisterrible.com/) ,这个博客有很多强观点的文章,主要是软件开发中的一些教训。
</li>
<li>
[Accidentally Quadratic](https://accidentallyquadratic.tumblr.com/) ,姑且翻译成事故二次方,这里有好些非常有趣的文章。
</li>
<li>
[Hacker Noon](https://hackernoon.com/) ,这是一个一堆人在写的博客,里面有很多质量很高的文章。
</li>
其实还有很多不错的博客,不过,现在国外不错的博客都在一个叫 [Medium](https://medium.com/) 的网站我也发现我Google很多东西时都会到这个网站上。这个网站上的内容不只有技术的还有很多很多其他方面的内容比如文化、艺术、科学等等。这个网站就是一个博客发布系统其是由Twitter联合创始人埃文·克拉克·威廉姆斯Evan Clark Williams和克里斯多福·艾萨克·比兹·斯通Christopher Isaac Biz Stone创办的这两个人觉得Twitter上全是垃圾没有营养的信息。所以创办了Medium这个平台上有专业和非专业的贡献者亦有受雇的编者。
我已经感觉到未来高质量的文章都会在Medium这个平台上出现因为有一些公司的技术博客也在这个平台上发布了比如Netflix的。所以你有必要上到这个平台上 follow 一些作者、专栏和主题。
# YouTube 技术频道
下面是我订阅的一些我认为还不错的和编程相关的频道,推荐给你。
<li>
[Devoxx](https://www.youtube.com/channel/UCCBVCTuk6uJrN3iFV_3vurg) Devoxx的频道其中有各种很不错的技术分享。
</li>
<li>
[Coding Tech](https://www.youtube.com/channel/UCtxCXg-UvSnTKPOzLH4wJaQ) ,也是个非常不错的编程频道,涵盖各种技术。
</li>
<li>
[Amazon Web Services](https://www.youtube.com/channel/UCd6MoB9NC6uYN2grvUNT-Zg)
</li>
<li>
[Facebook Developers](https://www.youtube.com/user/FacebookDevelopers/)
</li>
<li>
[Google Developer](https://www.youtube.com/user/GoogleDevelopers) Google公司的官方频道其中包括Google I/O 大会、教程、新闻、最佳实践、技巧分享……
</li>
<li>
[Spring Developer](https://www.youtube.com/user/SpringSourceDev) Spring的官方频道。
</li>
<li>
[Microsoft Research](https://www.youtube.com/user/MicrosoftResearch)
</li>
<li>
[MIT 公开课](https://www.youtube.com/user/MIT)
</li>
<li>
[Stanford Online](https://www.youtube.com/user/stanfordonline)
</li>
<li>
[Prof. Dr. Jens Dittrich](https://www.youtube.com/user/jensdit) ,一个德国教授开的一个关于数据库相关的频道,里面有很不错的数据库内在原理的内容。
</li>
<li>
[Red Hat Summit](https://www.youtube.com/user/redhatsummit) RedHat峰会频道其中有很多和Linux相关的技术新闻和分享。
</li>
<li>
[Open Networking Summit](https://www.youtube.com/user/OpenNetSummit) ,这是一个网络相关的频道。
</li>
<li>
[Dan Van Boxel](https://www.youtube.com/user/dvbuntu/) ,这是一个机器学习工程师折腾各种事的视频,挺有意思的。
</li>
<li>
[The New Boston](https://www.youtube.com/user/thenewboston/) 这个频道应该是前端开发工程师必去的地方可能也是我所知道的最好的关于前端技术的YouTube频道。
</li>
<li>
[Derek Banas](https://www.youtube.com/user/derekbanas) 是一个教程型的频道其中包括编程语言、游戏开发、Web开发……我个人觉得是一个可以用来练英文听力的频道。
</li>
<li>
[Java](https://www.youtube.com/user/java/) Java相关的各种分享。
</li>
<li>
[CppCon](https://www.youtube.com/user/CppCon) C++大会的一些视频可以让你了解很多C++最新功能和相关的动态。
</li>
<li>
[Computerphile](https://www.youtube.com/user/Computerphile) 这个频道是布雷迪·哈伦Brady Haran运作的几个频道中的一个在这个频道里你可以看到很多很有趣的技术方面的科普教程、资讯、见闻等说得都非常地简单易懂所以有大量的订阅用户。布雷迪是个对任何技术都很有热情的人这个频道是关于计算机技术的。除此之外他还运作 [Numberphile](https://www.youtube.com/user/Numberphile)(数学)、[Periodic Videos](https://www.youtube.com/user/periodicvideos)(化学)、[Sixty Symbols](https://www.youtube.com/user/sixtysymbols)(物理)、[Deep Sky Videos](https://www.youtube.com/user/DeepSkyVideos)天文等有众多阅人数的频道。如果你喜欢你都可以一一订阅感觉就是一个个人版的Discovery。
</li>
<li>
关于安全,有如下四个频道你可以订阅一下:
<ul>
- [DEFCONConference](https://www.youtube.com/user/DEFCONConference) defcon.org的官方频道。
- [CCCen](https://www.youtube.com/user/mediacccde/) Chaos Computer Club。
- [RSA Conference](https://www.youtube.com/user/RSAConference) RSA Conference。
- [Black Hat](https://www.youtube.com/user/BlackHatOfficialYT) - Black Hat Conference。
# 各大公司技术博客
细心的你一定会发现这份攻略中的很多推荐文章都来自于各个公司的技术团队的博客。是的,跟随这些公司的博客,你不但可以看到这些公司的工程技术,还能掌握到一些技术方向和趋势。
下面是Airbnb、AWS、Cloudera、Dropbox、Facebook、Google等各个公司的技术博客列表。
- [Airbnb Engineering](http://nerds.airbnb.com/)
<li>AWS 相关
<ul>
- [All Things Distributed](https://www.allthingsdistributed.com/)
- [AWS Architecture Blog](https://aws.amazon.com/cn/blogs/architecture/)
- [On Efficiency, Reliability, Scaling - James Hamilton, VP at AWS](http://mvdirona.com/jrh/work/)
# 论文
要想将技术研究得精深,论文是必不可少的。那要如何读论文呢?
## 如何读论文
下面有几篇文章,教你一些读论文的方法,非常不错。
- [How to read an academic article](http://organizationsandmarkets.com/2010/08/31/how-to-read-an-academic-article/)
- [Advice on reading academic papers](https://www.cc.gatech.edu/~akmassey/posts/2012-02-15-advice-on-reading-academic-papers.html)
- [How to read and understand a scientific paper](http://violentmetaphors.com/2013/08/25/how-to-read-and-understand-a-scientific-paper-2/)
- [Should I Read Papers?](http://michaelrbernste.in/2014/10/21/should-i-read-papers.html)
- [The Refreshingly Rewarding Realm of Research Papers](https://www.youtube.com/watch?v=8eRx5Wo3xYA)
## 论文集散地
要成长为一个高手,论文是你一定要读的。下面是一些非常不错的计算机方面的论文集散地。
<li>
[2 Minute Papers](https://www.youtube.com/user/keeroyz) 这是一个YouTube的频道其会给出一些非常不错的和计算机相关的论文介绍让你了解目前最有意思的一些科学突破每次两分钟左右。
</li>
<li>
[Best Paper Awards in Computer Science](http://jeffhuang.com/best_paper_awards.html) 从1996年以来获奖的计算机科学方面的论文收集。
</li>
<li>
[Google Scholar](http://scholar.google.com/citations?view_op=top_venues&amp;hl=en&amp;vq=eng) Google学术搜索英语Google Scholar是一个可以免费搜索学术文章的网络搜索引擎由计算机专家阿努拉格·阿查里雅Anurag Acharya开发。2004年11月Google第一次发布了Google学术搜索的试用版。该项索引包括了世界上绝大部分出版的学术期刊。
</li>
<li>
[Facebook](https://research.fb.com/publications/) Facebook公司的论文。
</li>
<li>
[Research at Google](https://research.google.com/pubs/papers.html) Google发布一些论文。
</li>
<li>
[Microsoft Research](http://research.microsoft.com/apps/catalog/default.aspx?t=publications) ,微软发布的论文。
</li>
<li>
[MITs Artificial Intelligence Lab Publications](http://dspace.mit.edu/handle/1721.1/39813) MIT和人工智能相关的论文。
</li>
<li>
[MITs Distributed Systems Reading Group](http://dsrg.pdos.csail.mit.edu/) MIT和分布式系统相关的论文。
</li>
<li>
[arXiv Paper Repository](http://arxiv.org/) arXiv是一个收集物理学、数学、计算机科学与生物学的论文预印本的网站始于1991年8月14日。截至2008年10月arXiv.org已收集超过50万篇预印本。至2014年底藏量达到1百万篇。
在2014年时约以每月8000篇的速度增加。arXiv的存在是造就科学出版业中所谓开放获取运动的因素之一。现今的一些数学家及科学家习惯先将其论文上传至arXiv.org再提交予专业的学术期刊。这个趋势对传统学术期刊的经营模式造成了可观的冲击。
</li>
<li>
[SciRate](https://scirate.com/) arXiv上的论文太多所以SciRate索引了arXiv上的一些好评的论文并供大家评论和打分。[开源代码](https://github.com/scirate/scirate)。)
</li>
<li>
[cat-v.org](http://doc.cat-v.org/) ,这个网站,不只有论文,还有技术手册或是一些有意思的文章,包括一些历史资料什么的。
</li>
<li>
[Usenix: Best Papers](https://www.usenix.org/conferences/best-papers) Usenix上推荐的最佳论文。
</li>
<li>
[The Morning Paper](https://blog.acolyer.org/) ,该博客会每天推送一篇论文,特别棒。
</li>
<li>
[Lobste.rs tagged as PDF](https://lobste.rs/t/pdf) Lobsters是一个聚焦于技术的社区主要是链接聚合和对话题进行讨论。其中的PDF分类可以认为也是一个论文的集散地。
</li>
<li>
[Papers We Love](https://github.com/papers-we-love/papers-we-love) GitHub上的一个近3万颗星的计算机科学方面的论文社区。
</li>
# 小结
总结一下今天的内容。这篇文章我主要跟你分享了一些好的学习资源,帮你开拓眼界,为后续学习夯实基础。
首先我推荐了Coding Horror、Joel on Software、Clean Coder Blog、Martin Fowler、Paul Graham Essays等多个知名的个人技术博客。然后分享了一些我认为还不错的和编程相关的YouTube频道比如Coding Tech、Amazon Web Services、Facebook Developers、Google Developer等。
随后是Airbnb、AWS、Cloudera、Dropbox、Facebook、Google等各个公司的技术博客跟随这些公司的博客你不但可以看到这些公司的工程技术还能掌握到一些技术方向和趋势。最后想成长为一个高手论文是一定要读的。所以我给出了一个非常不错的计算机方面的论文集散地并推荐了一些学习资源来教你如何读这些论文。
我一直认为学习需要自我驱动要学会自己“找食物”而不是“等着喂”。程序员练级攻略2018版到今天就全部更新完成了但我认为这其实只是技术练级的起点还有很多知识和技术需要我们不断地去探索和发现。加油我能做到的你一定也可以做到。
下面是《程序员练级攻略》系列文章的目录。
- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)
- [程序员修养](https://time.geekbang.org/column/article/8700)
- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)
- [软件设计](https://time.geekbang.org/column/article/9369)
- [Linux系统、内存和网络系统底层知识](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程系统底层知识](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门(分布式架构)](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文(分布式架构)](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理(前端方向)](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架(前端方向)](https://time.geekbang.org/column/article/12389)
- [UI/UX设计前端方向](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)

View File

@@ -0,0 +1,49 @@
到这里,我估计《程序员练级攻略》系列文章你都已经了解个大概了,不知道此时此刻你有什么样的感受?这份攻略其实是给了一个进阶的地图,也罗列了很多书籍和文档。但我可以确定地说,只是看这些列表,你肯定会抱怨说头都要大了,而且,你可能还会觉得纸上谈兵,不知道怎么把这些知识转变成自己的能力,尤其是你的工作中没有这些场景,你都可能不知道怎么实操。
所以,在这里,我把我个人相关的实践都写一下,这样会让你更好地掌握这份攻略。如果大家有更好的方法,也欢迎留言。
对于本攻略来说,你并不需要按顺序学习,你可以从自己喜欢的切入点,按自己喜欢的路线学习,通常来说,有如下的一些注意事项。
- 《入门篇》和《专业基础篇》中的那些书和文章,你肯定是得认真精读的,这是基础。但是也没有必要揪住细节不放,重要的是知道这个技术的“解题思路”,抓住其中的重点,一个技术的关键点就那么几个。
- 《高手成长篇》的相关书籍、文章和论文,你不一定全读,可以挑感兴趣的内容研究。
- 《修养篇》和《设计篇》里的内容,你可能要经常拿出来读,因为这些都是经验,随着你的成长,以及阅历的增加,你每次读都会收获更多新东西,正所谓常看常新。另外,你还可以顺着这些东西找到更多的“修养”和“设计”。
但是读这些资料,很多人都是记忆式的学习方式。但,你也知道,记忆学习是简单粗暴的,所以也很容易忘,如果你不实操一下,就不会有具体、真实的感觉。所以,一定要动手实践。
下面是一些配合程序员练级攻略中技术成长的相关的建议。
**首先,你需要建一个自己的实验室**。咱们讲了很多内容,看完之后,你要动起来,徒手把环境搭出来,写一些实验性的程序验证或感受一下相关的技术点,出了问题也要自己进行调试和修复。因为只有这样,你才可以获得一些感性认识。
- 《入门篇》和《专业基础篇》都有很多的编程语言要学你并不需要一下全部都学但是为了你可以一个人solo你需要至少学一个后端和一个前端语言我给你的建议是 Java 和 JavaScript。
- 在《入门篇》和《专业基础篇》我都给了一些实践项目如果你没有太多的工作经验这些实践项目会对你的学习非常有帮助。因为在实现代码的时候你会遇到很多细节问题这些细节问题会倒逼你去看文档去Google去提问这相当于是把你扔到具体的问题场景里锻炼你、打磨你。
- 对于《数据结构》,其实都是在围绕增删改查的相关性能,在平衡时间和空间。对于《算法》则要么这些数据结构的操作,要么就是数学逻辑的推导,比如动态规划。这些东西可能在你的生活当中用不到,但是你可以把它作为一个脑筋体操来不断训练自己的数学思维。
- 对于《高手成长篇》中的很多东西也是需要你自己先搭个环境自己写一些Hello World式的程序先体会一下那些知识。比如内存分配、异步I/O模型、locker-free、JVM和字节码操作还有浏览器原理等等这些东西写几个小程序就可以体会到了。而还有一些中间件的知识你也是可以搭个环境自己玩玩并且最好能够搭出一些比较高级的用法。
**其次,把你的实验室升级成一个工作室**。工作室和实验室不一样的地方是,实验室只是在做一些验证型的实验,以跑通一个小技术功能为主。而工作室则是要以完成一个比较完整的软件功能为主,也就是说,可以让别人/用户来用的东西(哪怕很丑很难用,但是可以让别人来用)。这个阶段,我给你如下的几个建议。
- 你得选用一个主流的开发框架,并且在写这个软件的时候,你需要有一定的修养,比如有不错的编程风格,追求代码的可读性,有一定的测试案例,等等这些我们在《修养篇》和《软件设计篇》里提到的东西。这个时候,你需要大量学习一些优秀项目的代码,因为你可以在开源软件中找到一些不错的代码实现(你可以做一些源码分析的事,但不是去整理其中的编程逻辑,而是要去学习代码组织的方法)。然后你需要照葫芦画瓢似的练习,无论你完成得好不好其实都没有关系,这就像画画一样,一开始总是画的很不好的,但是只要你坚持,并且多思考别人为什么要写成那样,那么,我相信你提高得也会很快。
- 你需要完成一个能用的项目,对于选择什么样的项目,这里,我也有几个建议。第一,从自己的痛点出发,写一个能解决自己问题的东西。第二,临摹别人的作品,复刻一个其它的成功产品。有人说,学好一门语言或是一个开源软件最好的方式,就是用想学/喜欢的编程语言翻译下这个开源软件比如你用Go语言翻译一下某个Java的组件。第三深度参与一些你喜欢的开源项目。第四在工作中找到风险可控的项目和需求。
- 你最好跟别人一起组队升级打怪。这里需要注意的是,一定要找好队友,要那种有热情,爱专研,能相互打气的队友,千万别找那些为自己的不努力找各种各样借口的人。
- 在这个工作室中,你还可以尝试使用各种前沿的或是你没有玩过的技术和中间件。这里,你需要注意的是你一定要使用一些高级技术,比如一些高级算法,或是分布式技术等。
- 当你的东西做好后一定要做压力测试或Benchmark这样你才知道自己产品与其他软件的差距然后还会逼着你对自己的系统或软件进行调优。
**最后,把你的工作室升级成工厂**。工作室与工厂最大的差别就是,工作室是比较自我比较随意的,而工厂是有相关的工业标准的,是有一整套的规范和标准的。对此,有如下的一些建议:
- 当有了“工作室”的能力后,一般来说,你就可以去头部的互联网公司或是一些技术公司了。但是你一定要在一些核心的项目或产品工作,也就是说,你要在那些有技术挑战的地方工作,并在那里收割更多的经验和技能。
- 你需要读各种各样的RFC、论文、Specificaiton、标准化文档还要使用工业级的工程能力要求自己比如CI/CD这样的软件流程。你得不断告诉自己把代码提高到可维护、可扩展甚至可重用的级别。
- 你必须对技术有更深入的了解对软件开发的套路和各种trade-off还有各种解决方案的优缺点都非常熟悉。这就需要你了解软件内部的设计和原理并知道优缺点和使用场景。
- 你需要开始追求软件运行的SLA也就是能在什么样的性能下做到多少个9。还要关注系统的可运维性也就是你需要为你的软件做很多的配套设施。就像为了汽车建加油站建4S店建公路建交通管理部门……
- 你需要找那些有工业素养的工程师一起讨论或工作。这类的工程师有丰富的工作和项目经验,也见过大世面。他们通常来说会对外有输出(不是那些写微信公众号的人,或是在知乎上输出的人,而是那些在软件开发工作上有丰富工程经验的人)
- 这个时候,对于你要做的软件,你不仅仅只是为了完成,你追求的是一种技术高度,追求那种严谨和科学的态度。你已经把这个软件当成了自己作品,变成了自己的名片,你在等待接受别人的学习和膜拜。
好了,基本就是上面这些,你还要记住我的学习能力一文中的那个学习金字塔,在上面的过程中不断地输出你的认识和体会。
最后,我用下面的几个观点来结束这篇文章,希望对你有所帮助:
- 带着一些具体的问题来学习,能够让你更有感觉,也容易获得正反馈和成就感。
- 开拓视野,尽可能只读英文社区的一手文章,这样你会得到更有营养的知识。
- 多问为什么,为什么要设计成这样,为什么要有这个技术,到底解决了什么样的问题?这会让你对技术有更深的认识。
- 学会归纳总结,在不同的技术中找到相似或是相同的东西,更容易让你触及技术的本质。
- 把自己的理解用自己的语言表达出来,对外输出,这是最好的学习方式。
- “动手”和“坚持”,这是一个动手能力很强的学科,不动手,你什么都不可能学精、学深。这是一个需要你不断坚持的事,在这条路上,你有很多很多的理由可以让你放弃,只有坚持才有可能有突破。