大家好,我是乔戈里。
之前在知乎上回答了这个问题,获得了近千点赞,还有读者说一看就是有生活的人:
噗,的确,我自己以前看书的时候也有这些困惑。
再到后来有自己的看书方法和节奏,我觉得适合自己的方法就是最好的。
再说回这个问题本身,
其实不用看就知道,这种问题下的观点一般都是两类:
没必要!直接做项目
有必要,经典的书必须啃
甚至还有这种反智言论:
只想说就算 Linus 这种级别的巨佬, 自学操作系统的时候,也是从一本很好的教材 《操作系统:设计与实现》 开始的 ,然后花了一个暑假看完,才自己写操作系统。
对于该不该看不看这个问题,我的核心观点就是:
初学者别看那种大黑书,先看视频入门
该看的书别省,学到了一定程度你应该自己知道该看什么书一、怎么看大黑书?
今天来聊聊如何啃这些动辄上千页的大黑书。
说实话,类似 CSAPP、SICP(计算机程序的构造和解释) 这些书都被各路大神反反复复推荐过了,确实经典。
但是大神们却很少告诉你他们是如何去看的,该怎么去看这些书。
难道一本本一页页的挨着啃吗?
这部分才是我今天最想说的部分,「该如何去看大厚书」。
之前在一些文章末尾有聊过一些,但是我觉得这个话题值得单独发一篇文章。
比如我后台就经常有同学问:
有些书看的找不到重点,看不下去了,怎么办,比如深入理解计算机系统,UNIX 网络编程,APUE,求指教
我不是科班 CSAPP 可能不是全部看得懂,该怎么办?
大佬,这么多书看得完吗?
刚开始看这些书很痛苦怎么办?
这些书该怎么看,可能过来人,准备过秋招的都比较清楚,但是作为还在大二、大三的会比较懵逼。
就拿我当时亲身经历来说,在网上搜网络编程如何学习。
很多人都会推荐 UNP(Unix网络编程)、APUE(Unix高级环境编程),这两本也确实是网络编程和 Linux 系统编程领域的圣经。
好嘛,买来看,从第一页挨着挨着看,而且书中的示例代码我大部分也照着敲了。
最后看了七八章,发现始终是在学一些 socket api 和 系统 api 的用法,没摸到网络编程的框架思维。
这就是只见树木不见森林。
后面我又去搜,看到有人推荐《Linux高性能服务器编程》,去豆瓣看了下了目录,似乎正是我想要的东西。
直接找来 PDF 开始看,果然这本书才真正让我理解了网络编程的整个套路和框架。
学到了各种事件处理模型,什么 Reactor, Proactor、计时器、信号处理、线程池这些网络编程中很重要的东西。
我才领悟到网络编程中最重要的不是 epoll 也不是 socket api,而是线程模型。
当然 UNP 和 APUE 也是不能丢的,这两本书我当做了字典查询,比如学到了 IO 部分,回去看 UNP 中关于五种 IO 模型的介绍:
用到 connect、listen、bind 这些函数,再回去看 UNP 第四章,不得不说,UNP 关于这些 Socket API 的使用和各种异常情况的处理方式都介绍得非常详细和深入,不愧是网络编程领域的圣经。
但是初学者看却容易在细节中迷失,抓不到纲领,这也是这类书的缺点。
类似 UNP、APUE 这种书本身是面向知识体系的,而不是面向读者。
它们其实更像字典,把这个领域内的所有知识,非常细致的堆叠在一起,看上去就是平铺直叙,充斥着细节,对读者极其不友好。并且书里内容实在大而全,很多根本不用学。
比如 UNP 讲了 sctp 这种协议用法、多播、unix 域协议这些实际用得很少的东西,挨着看不仅会看不下去,而且比较浪费时间。
但是它们又是经典的,确实是这些领域内在体系性和深入性上都做得非常好的书。
二、什么书才是面向读者的呢?
那就是抓住该领域的核心主干,提纲挈领,带领读者由浅入深,同时又有一定的细节,看完让人茅塞顿开。
比如《自顶向下》、《Linux高性能服务器编程》、《Linux多线程服务端编程》、《STL源码剖析》、《Effective C++》、《CSAPP》、《程序员自我修养》等都有各自想要论述的主线在里面,看起来也是一环扣一环,非常循序渐进。
我的看书方法就是对于面向知识体系那种堆砌细节的书,我们先浏览目录,做到对整本书有映像,再大致看一些我们关心的部分,比如 UNP 和 APUE 中 IO、文件、进程控制、信号、线程、线程控制、基本套接字编程 这些是比较重要的模块,其它边角知识,可以用到再去查。
还有一点,很多同学反映看不懂类似 CSAPP 这样的书,那我们都知道,任何一本书基本上都是有前置依赖的。
没有掌握要求的背景知识去看肯定很吃力的。
就比如我大一下只有基础的 C 知识和一丁点计算机导论知识,然后屁颠屁颠的跑去看 CSAPP(学长毕业摆地摊卖书我瞎买的),那时候只知道这本书被誉为神书。
但是看到前两三章就蒙了,真的有点难,对于当时的我来说太底层了,根本不知道在说啥,看过也只是看过,就像天空飞过鸟儿,但没有痕迹。
直到后来大三再次拿起,我才意识到这本书的伟大之处就在于将计算机不同学科知识有机的串在了一起。
那时候看,更多是一种补充、深入学习以及完善了,因为很多知识分别在数字逻辑、汇编语言、操作系统这些课程中学过了。
所以要明白,你看不懂不是因为你笨没天赋,而是你有前置依赖的知识没有完成,还没学会走,就想跑了。
一般来说,每本书的首页会介绍看这本书需要哪些前置知识,可以关注一下。
比如 CSAPP 的序言部分就写了这本书读者所应该具备的背景知识:
三、以主题聚合各种书
还有一种看书的方法,我在复习的时候采用过,那就是横向学习。
比如我复习操作系统,在《操作系统:精髓和设计原理》中看到了关于内存、虚拟内存的各种介绍。
看完理论再去看《Linux内核设计与实现》12 章「虚拟内存」、15 章『进程地址空间』。
最后再去看《CSAPP》第 9 章『虚拟内存』,这样看下来,基本上内存这块理解得比较透了,这些书关于这块的介绍是各有优缺点的,正好互补。
又比如在《精髓与设计原理》中介绍了进程加载和链接,其实讲得比较偏理论,看完还是觉得似懂非懂。
那我又会去《CSAPP》看第 7 章「链接」,这一章基本讲清了静态链接、目标文件、可重定位目标文件、引用解析、加载这些关于链接的核心概念,但是一个章节讲这么多,难免不够深入。
我又会去看《程序员自我修养》这本书第 4 章「静态链接」、第 6 章 「可执行文件的装载与进程」、第 7 章 「动态链接」,这本书核心主题就是链接、加载,所以这一路看下来,对于链接、加载这块基本上搞得比较透彻了,也许没几个面试官有你清楚。
同样索引你也能从《数据库系统概念》、《高性能MySQL》、《MySQL技术内幕》中挑选对应的章节,串起来看,取每本书优点,这样学习真的很高效也很深入。
这就是我在复习的时候采用的用知识点串联,跨多本书高效精准的复习方式,效果也很不错,春招十几次面试没有一次因为这些基础知识挂过。
四、浅谈学习方法
学习一定要有打法,学会抓主线,先把主线任务完成,再去看支线。
学习新东西的时候,重点是先对整体脉络、知识结构有一个大概的映像和了解,然后抓住这个领域的主线,顺着主干,突出重点去学习。
集中时间,速战速决,不要将时间线拉得太长,越长可能越坚持不下去,效果越差。
对于细枝末节的内容,可以留到实践的时候,用到了再去查!
如果一头扎进零碎的知识,去看手册、字典型的书,那必然是事倍功半的。
细节留给实践去补充,我们的时间要花在刀刃上,注重知识的体系性和框架的建立。
五、该不该记笔记?
因人而异,我个人看书,尤其是技术类,觉得是没有必要再去把书中的原话誊抄一遍。
我更爱按章节,做个思维导图,做一些提纲挈领的总结,而非单纯的技术 「What」
导图中可以加一些注解,把你当时脑袋里闪过的想法记下来。
彩蛋:
最近我就会在知识星球组织球友们一起啃「CSAPP」,但是我觉得用啃不太合适,这本书其实就是一本导论书,没有那么神,大多数人觉得看不懂的原因也是因为缺少一些背景知识。
那么我建议先去简单补齐背景知识再来看书。
如果你后面也想和一群爱学习的小伙伴们打卡学习,那么欢迎加入:
爱学习的小伙伴