现在学习 CSAPP 对我的工作有帮助吗?

在学习之前,我其实也有同样的疑问。大致看了一遍书,还做了一份笔记之后,对这个问题也有了一些自己的感受。

思考这个问题的过程,让我想起了刘润老师的一本书《底层逻辑》。是的,这个问题最好的回答就是“从底层逻辑开始”。接下来我就从 Why / What / How 三个角度来聊聊我的理解和学习收获。

1. Why

拿书本的第三章为例,这个章节的英文叫做 Machine-Level Representation of Programs,翻译过来就是“程序的机器级别表示”。

大家平时工作中使用的都是 Java,C#,JavaScript 等这类高级编程语言。而且我们在工作中也不需要使用汇编这类的低级语言。

那么我们现在为什么要去学习“程序的机器级别表示”呢?

我在看到码农翻身的一篇文章后对这个问题恍然大悟。文章中提到 Stack Overflow 的创始人 Joel Spolsky 一个理论:抽象泄漏法则

1.1 抽象泄漏法则

以编程语言为例,这就是一个不断向上抽象的产物。

从机器语言开始到汇编语言,然后到 c/c++ 高级语言,再到 Java,C#,JavaScript 等高级编程语言,总是在不断地抽象。

Joel Spolsky 说:

All non-trivial abstractions, to some degree, are leaky.(所有非琐碎的抽象,在某种程度上,都是泄露的。)

比如在高级语言中,会将 string 抽象成像 int 一样来使用。我们可以使用加号将两个字符串串联,就像这样: "foo" + "bar"。

当我们这么使用的时候,可能会有资深的程序员告诉大家,串联字符串时最好使用 StringBuilder 类。我们会记住这个用法,但是不一定能理解为什么。

这其实就是抽象的泄露。

在低级别语言中其实并没有字符串这个类型,只有char *,字符串就是一个 char 的数组。

理解到这一层,再回头看看 StringBuilder 类,就会知道底层的原理,就是一个数组。

所以 Joel Spolsky 说:

the abstractions save us time working, but they don’t save us time learning. (抽象可以节省我们的工作时间,但不能节省我们的学习时间。)

*Joel Spolsky 原文:[The Law of Leaky Abstractions]

https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/

1.2 理解基础知识

从底层开始学习,还能够更好地理解编程的基础知识,这是我在学习过程中感触最深的地方。举两个例子:闭包和递归

a. 闭包

前端开发的朋友第一次遇到闭包问题,可能都是从一段 for 循环不能正常执行开始。

for (var i = 0; i < greetings.length; i++) {...
}

我们会发现将 var 写成 let 就可以正常工作了。

闭包到底是什么原因导致的?

当我们知道了函数栈帧和堆的概念之后,再去找找相应的专业文章,就能够从原理上理解闭包这个概念。

*这里推荐一下我翻译的一篇文章:[JavaScript 闭包在 Heap 中的表示]

https://zhuanlan.zhihu.com/p/468527405

b. 递归

记得我第一次跟踪递归实现汉诺塔的算法时,完全是一团浆糊。这个问题同样也可以从底层逻辑来搞明白。

当我们清楚了函数栈帧的概念,知道了每次函数调用都有自己的栈帧,知道了栈帧里面保存了局部变量。

这时候再回过头来理解递归,其实就是基于栈帧这个概念,生成一条栈帧链,实现的从大到小,从整体到局部一个推导过程。

递归是计算机基于自己的运算特性(栈帧),形成了自己独特地处理问题的方式,这种方式有别于人类的正常思维。作为程序员,我们需要理解并按照这种方式编写自己的代码。

*阶乘递归实现的状态机

2. What

什么是 “程序的机器级别表示” ?我们可以理解为汇编语言。

在了解汇编语言之前,我们还需要从程序的视角对一些硬件有大致的认识。什么是内存?什么是寄存器?什么是程序计数器?……

产生这些疑问,其实也是因为汇编也是一种抽象,是机器语言的抽象。

我们当然可以跳过这部分知识。但是如果能了解这些知识,的确可以帮助我们学习。

从书中的内容,我整理出下面这几部分内容,可以帮助大家快速理解这些概念。

  从程序的角度看,内存是什么?

  内存的布局

  寄存器

*内存的布局

理解了这些知识点后,如何理解什么是汇编语言呢?

这里我还想推荐一本书——《编码》,顺便也介绍一种选择书籍的好办法,概括起来就三个字:白,浅,透。

对新手来说,一听就明白。对专业人士来说,讲解的方式浅显易懂。对高手来说,道理讲得很透彻。

3. How

如何学习汇编语言呢?

要知道我们学习的目的不是为了能够编写汇编代码,而是能够看懂。所以学习起来相对简单。

我将第三章的内容分成了三部分。

首先,第一部分我们需要学习基本的指令形式,就像学习编程语言时我们需要先学基本语法一样。

指令1 - MOV

  指令2 - LEA

指令3 - 算术和逻辑 

指令4 - PUSH 和 POP

指令5 - CALL 和 RET

*POP 指令的执行

然后,第二部分在学习函数相关的知识,这一部分我们可以学到栈和栈帧的概念。

  程序运行时的栈

栈帧的布局

*栈帧的布局

最后,掌握一下条件分支的知识,看看条件分支是如何实现编程语言中 `if` 和 循环语句的,也能够明白递归到底是怎么回事。

  条件码寄存器

 条件分支

  循环

  递归

*递归运行时栈的情况

汇编语言作为一门低级语言,相比其他高级语言来说语法非常简洁,如果只要做到能够看懂,并不用花费太长时间。

4. One More Thing

学习“程序的机器级别表示”,看上去我们一直在研究汇编语言。然而这仅仅是个开始,从这里起步,在接下来的章节中我们可以看到操作系统的其他特性,比如虚拟、并发、持久化等等知识。

最后说一件最近工作中遇到的问题。我在前端使用 ajax 请求数据,接下去的事情需要等待这些数据到达后才能继续。

当时心中出现了好多问题:JavaScript 作为一个单线程语言,是如何实现 ajax 的异步调用的?这些跟线程有关系吗?有没有方法保证异步调用的顺序执行?

回过头来细想,能提出这些问题,都是因为我当时看过了操作系统是如何处理并发的,如何处理线程的。这些问题自然地出现在我的思考过程中。

顺着这个思路,很顺利地找到了 JavaScript 中异步编程的方法 promise,async、await。

*这里推荐一下我翻译的一篇文章:可视化的 JavaScript Promises & Async/Await (https://zhuanlan.zhihu.com/p/467601693)

其实,在很多高级的编程语言中都有异步编程。比如 JavaScript 中的 promise,async、await;C# 中的 async、await、Task 等等。

我个人的体验是这样的,如果只是为了掌握语言的特性,学习异步编程很有可能会学得雨里雾里。但是,当我们知道了操作系统是如何处理并发的,如何处理线程的,这些知识都将会帮助我们更加深刻地理解编程语言中的异步问题。

最后,还是回到文章开头那句话 —— 一切都从底层逻辑开始


关于作者:丁亭立,微信公众号“dingtingli-pub”作者。如果你对这份笔记感兴趣,可以关注公众号“dingtingli-pub”,我会每周更新。所有笔记的初稿也已经发布在 github 上,大家可以直接访问:https://github.com/dingtingli/csapp-learning

RECOMMEND

推荐阅读

01

《深入理解计算机系统(原书第3版)》  

作者:[美] 兰德尔 E.布莱恩特(Randal E. Bryant)

大卫 R. 奥哈拉伦(David R. O'Hallaron)

译者:龚奕利、贺莲

推荐理由

本书是一本将计算机软件和硬件理论结合讲述的经典教程,内容覆盖计算机导论、体系结构和处理器设计等多门课程。卡内基-梅隆大学、北京大学、上海交大等国内外众多知名高校选用指定教材。本书的最大优点是为程序员描述计算机系统的实现细节,通过描述程序是如何映射到系统上,以及程序是如何执行的,使读者更好地理解程序的行为,以及造成效率低下的原因

02

《计算机系统解密:从理解计算机到编写高效代码》

作者:[美]乔纳森·E.斯坦哈特(Jonathan E. Steinhart )

译者:张开元、张淼

推荐阅读

计算机程序硬件软件从底层实现到高层展现原理讲解,对底层知识的多个主题进行了公平的覆盖。

计算机编程不是抽象的,程序是在机器上运行的。了解计算机如何工作以及程序如何在计算机上运行是成为一名更好的程序员的必要条件。在本书中,资深工程师Jonathan E. Steinhart深入探讨了计算机背后的基础概念,比如计算机硬件,软件在硬件上的行为,如何编写高效的程序,计算机安全基础知识,以及在编写代码时需要考虑的现实问题。本书对底层知识的多个主题进行了公平的覆盖——介绍有助于提高整个系统质量的许多领域的知识(包括计算机硬件、组合逻辑、时序逻辑、计算机体系结构、计算机组成原理、操作系统、系统程序设计等)。

直播回看

Java核心技术大会2022|李三红老师的专场分享回放现已上传至B站【Java核心技术站】。

https://www.bilibili.com/video/BV1Xr4y1M7nk

(长按复制至浏览器打开)

嘉宾分享PPT请点击下方链接获取

更多精彩回顾

资讯 |《Java核心技术》基于Java 17全面升级!

干货 |再见了Java8,Java17:我要取代你

资讯 | Java核心技术大会2022 · 重磅发布

书单 |今天,Java27岁了!

新书 | 红蓝攻防:构建实战化网络安全防御体系

书讯 |7月书讯 | 12本新书如期而至!

每周赠书 | 【第109期】4种 Redis 集群方案介绍+优缺点对比

新书 | 分布式算法精髓

干货 |详解大数据、数据存储和边缘计算技术在元宇宙中的应用

资讯 |Marcus再战三巨头,一场关于深度学习前景的辩论

点击阅读全文看大会回放

学习 CSAPP 对工作有帮助吗?一切从底层逻辑开始!相关推荐

  1. 学习Java好找工作吗?Java学完后薪资怎么样?

    作为编程届的头牌语言,Java历经数十年仍然占据语言排行榜前三.正是因为如此,很多人在转行的时候首先考虑的就是学习Java.那么,学习Java好找工作吗?Java学完后薪资怎么样?自然是很多人学习后最 ...

  2. 深度学习数据集制作工作_创建我的第一个深度学习+数据科学工作站

    深度学习数据集制作工作 My Home Setup 我的家庭设置 Creating my workstation has been a dream for me, if nothing else. 创 ...

  3. 【Vue2.0学习】—Vuex工作原理图(二十五)

    [Vue2.0学习]-Vuex工作原理图(二十五) 一. Vuex 是什么? 概念: 专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写 ...

  4. 7-154 置点不动产——认真学习,努力工作买买房子吧

    7-154 置点不动产--认真学习,努力工作买买房子吧 某程序员开始工作,年薪N万,他希望在ZG村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每年百分之K增长,并且该程序员未来年薪不变 ...

  5. PTA 7-154 置点不动产——认真学习,努力工作买买房子吧

    PTA 7-154 置点不动产--认真学习,努力工作买买房子吧 分数 10 作者 焦晓军 单位 重庆科技学院 某程序员开始工作,年薪N万,他希望在ZG村公馆买一套60平米的房子,现在价格是200万,假 ...

  6. 女生学习软件测试好找工作吗?

    女生在学习软件测试方面有很大的优势,因为软件测试的主要工作是发现错误.女孩子自然更专心.细心.耐心.这些优势满足了企业的需求,我从事软件测试已经超过10年了.现在,从IT职位的分析来看,大多数公司做测 ...

  7. 推荐算法工程师学习路线及工作指南

    干货!推荐算法工程师学习路线及工作指南 以下文章来源于大数据与人工智能 ,作者gongyouliu 本文从我自己的学习成长经历.如何判断自己是否适合从事推荐算法.推荐算法工程师需要的知识储备.怎么找一 ...

  8. 计算机系班级未来展望,关于班级学习委员的工作总结5篇

    作为学习委员,首先我应该清楚自己的职责.因此,关于工作总结,我想从学习委员的职责方面,总结近期的工作情况,工作内容,在下学期能够更好的完成工作目标.下面是小编收集整理的关于班级学习委员的工作总结5篇范 ...

  9. 陈表达VBA学习笔记-新建工作表鼠标右键菜单按钮

    陈表达VBA学习笔记-新建工作表鼠标右键菜单按钮:新建一个我的菜单按钮 设置对应的宏过程名称为 [我的菜单宏] 点击按钮弹窗信息,信息可自定义设置 详细代码如下: Sub 新建右键菜单()Dim 菜单 ...

  10. TI CC1101学习笔记:工作原理简单入门

    众所周知,在IOT的市场应用中,从通信协议细分的话,有SUB-1G,2.4G,3G, 4G,以及最新推出的5G,虽然5G通信协议已经在崭露头角,但是不同的通信协议在不同的应用领域之中还是占据着一定的重 ...

最新文章

  1. Toad 修改起始窗口
  2. 用一句sql语句更新两个表并可更新对应的字段的值
  3. 23行代码AC_2017 蓝桥杯A组 正则问题(解题报告)
  4. Numpy Data type
  5. 验证Vsphere 5 支持大于2TB磁盘
  6. VS2019C++代码出现cout不明确
  7. php服务器错误日志在哪里看,PHP取服务器错误日志
  8. vue 转换信息为二进制 并实现下载
  9. 当音乐博士开始写代码...
  10. 苹果 macOS 再曝漏洞,输任意密码可进入 App Store 首选项
  11. 【Gbase】建表时候hash分布列的制定方式(DISTRIBUTED BY column_name)
  12. Dynamic CRM 2013学习笔记(二十八)用JS动态设置字段的change事件、必填、禁用以及可见...
  13. java gbk转机内码_GBK/GB2312编码问题分析以及java获取汉字国标码
  14. 三菱f800变频器 频率设定_三菱F800变频器调试参数总结
  15. 深度学习笔试、面试题 二
  16. Excel图表坐标轴出现系列1、系列2的解决方案
  17. itunes未能连接到iphone软件更新服务器,无法联系iphone软件更新服务器,itunes无法联系iphone软件更新服务器解决方法...
  18. 远古守卫/cocos2d-x 源码/塔防游戏/高仿王国保卫战
  19. MYSQL选修课的心得体会_选修课学习心得体会范文7篇_大学选修课心得体会
  20. Inventor API 年度需求调查

热门文章

  1. linux屏幕触碰事件,触摸屏中鼠标事件的捕获和传递及触摸屏的移植
  2. js保留2位小数(且四舍五入)
  3. [附源码]Java计算机毕业设计SSM常见病辅助食疗系统
  4. DOCTYPE声明——标准模式与怪异模式的区别
  5. 清明五一假期催热周边自驾游 迪庆州应势推出“杜鹃花之旅”
  6. html学习 - 检测浏览器是否支持Canvas
  7. python汇率兑换_汇率兑换—python第一课
  8. 云杰恒指:7.19恒指期货早盘资讯
  9. 简单做(ZTD)的十个好习惯总结
  10. PHP GD竖排文字写法