Files
CategoryResourceRepost/极客时间专栏/左耳听风/程序员练级攻略/75 | 程序员练级攻略:系统知识.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

152 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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)