既然你是在校学生,而且编程语言和数据结构的基础还不错,我认为应该在操作系统和计算机体系结构这两门课上下功夫,然后才去读编程方面的 APUE、UNP 等书。
下面简单谈谈我对学习这两门课的看法和建议,都是站在服务端程序员的角度,从实用主义(pragmatic)的立场出发而言的。
学习操作系统的目的,不是让你去发明自己操作系统内核,打败 Linux;也不是成为内核开发人员;而是理解操作系统为用户态进程提供了怎样的运行环境,作为程序员应该如何才能充分利用好这个环境,哪些做法是有益的,哪些是做无用功,哪些则是帮倒忙。
学习计算机体系结构的目的,不是让你去设计自己的 CPU(新的 ISA 或微架构),打败 Intel 和 ARM;也不是参与到 CPU 设计团队,改进现有的微架构;而是明白现代的处理器的能力与特性(例如流水线、多发射、分支预测、乱序执行等等指令级并行手段,内存局部性与 cache,多处理器的内存模型、能见度、重排序等等),在编程的时候通过适当组织代码和数据来发挥 CPU 的效能,避免 pitfalls。Modern Microprocessors
这两门课程该如何学?看哪些书?这里我告诉你一个通用的办法,去美国计算机系排名靠前的大学的课程主页,找到这两门课最近几年的课程大纲、讲义、参考书目、阅读材料、随堂练习、课后作业、编程实验、期末项目等,然后你就心里有数了。
学习任何一门课程都要善于抓住主要矛盾、分清主次、突出重点,关键是掌握知识框架,学会以后真正有用的知识和技能,而不要把精力平均分配在一些琐事上。
请允许我再次引用孟岩的观点:
我主张,在具备基础之后,学习任何新东西,都要抓住主线,突出重点。对于关键理论的学习,要集中精力,速战速决。而旁枝末节和非本质性的知识内容,完全可以留给实践去零敲碎打。
原因是这样的,任何一个高级的知识内容,其中都只有一小部分是有思想创新、有重大影响的,而其它很多东西都是琐碎的、非本质的。因此,集中学习时必须把握住真正重要那部分,把其它东西留给实践。对于重点知识,只有集中学习其理论,才能确保体系性、连贯性、正确性,而对于那些旁枝末节,只有边干边学能够让你了解它们的真实价值是大是小,才能让你留下更生动的印象。如果你把精力用错了地方,比如用集中大块的时间来学习那些本来只需要查查手册就可以明白的小技巧,而对于真正重要的、思想性东西放在平时零敲碎打,那么肯定是事倍功半,甚至适得其反。
因此我对于市面上绝大部分开发类图书都不满——它们基本上都是面向知识体系本身的,而不是面向读者的。总是把相关的所有知识细节都放在一堆,然后一堆一堆攒起来变成一本书。反映在内容上,就是毫无重点地平铺直叙,不分轻重地陈述细节,往往在第三章以前就用无聊的细节谋杀了读者的热情。
比如说操作系统,应该把精力主要放在进程管理与调度、内存管理、并发编程与同步、高效的IO等等,而不要过于投入到初始化(从 BIOS 加载引导扇区、设置 GDT、进入保护模式)这种一次性任务上。我发现国内讲 Linux 内核的书往往把初始化的细节放在前几章,而国外的书通常放附录,你可以体会一下。初始化对操作系统本身而言当然是重要的,但是对于在用户态写服务程序的人来说,弄清楚为什么要打开 PC 上的 A20 地址线真的有用处吗?(这不过是个历史包袱罢了。)
再比方说计算机网络,关键之一是理解如何在底层有丢包、重包、乱序的条件下设计出可靠的网络协议,这不算难。难一点的是这个可靠协议能达到“既能充分利用带宽,又能做到足够公平(并发连接大致平均分享带宽)”。而不是学会手算 CRC32,这更适合放到信息论或别的课程里去讲。
|