这是个好问题。就是难度有点高。

这可能是我在知乎上回答的、难度最高的问题了。


从题主加的标签看,他似乎想问的是「如何读懂程序代码、并用语言描述其功能」。

嗯……这本身就是个难题。

因为程序代码是「为了解决问题而给CPU安排的一系列动作」;但这些动作本身是琐碎的、而且丢失了大量信息——包括待解决问题、包括解决思路、包括决策点的设计原理/上下文等等,全都丢失了。

当然,如果有注释的话,部分被丢弃的信息还是可以找回来的。注释越详尽,可以找回来的信息就越多。

但是,注释也是有时效性的。一段代码可能经过了很多修改,这些修改会使得一些注释变得无效、甚至指向了反方向。

如果愿意花时间的话,或许跟踪修改记录,查看伴随每次提交的说明信息(comment),也有助于还原真相……

总之,和警察破案差不多,需要大量的经验,也需要灵活的脑子——猜测最初面对的问题,猜测设计者的解决思路;寻觅证据,证明自己的猜测……

没错。读代码是个苦差事。尤其是那些脑洞大开、自解释性差、又没有注释的代码。

当我写这些代码时,只有我和上帝知道它要做什么。现在只有上帝知道了。

——某人给自己的程序写的注释。


既然读代码是只有上帝才敢保证自己能搞定的难题,我当然也只能绕开了。

既然我们不是上帝,那么,作为人,我们是否可以想想办法,把代码写的简明易懂、方便后来者(包括半年后的我们自己)读懂它、维护它呢?

没错。这正是业界一直推崇的做法。


先从细节说起吧。

我提过很多次了:代码难读难懂,根本原因是因为信息的丢失。

要解决什么问题?解决思路是什么?这一段做了什么事?

一旦写成代码……

因此,我们不得不防微杜渐,尽量在代码中多保存信息。

比如说,推崇结构化程序设计、推崇面向对象程序设计,使得代码中的功能分界清晰、每块的总体结构(循环/多重循环/分支/dispatch等等)一目了然。

比如,要求变数命名规范合理,有自解释性:一个变数叫x,你当然摸不著头脑;但如果它被程序员精确的命名为「userInputedNumber」,你就知道它的值从何而来;而如果它能叫「inputForSum」,你马上就知道这个值是用户输入的、用来做汇总(sum)。

类似的,函数名、类名、模块名、命名空间名称等等,都必须如实反映其功能。这就叫「代码有自解释性」。

当然,设计方案到代码,信息散失太过严重。仅靠代码自解释往往是不够用的。此时就必须以注释补充了。

注意,注释的作用是「补充代码无法自解释的信息」。因此,不要写这种注释:

//计算b+c的值,存入a
int a=b+c;

这种注释没有提供任何信息,作用仅仅是浪费了读者和写者的时间。

当然,这种错误的注释更不行:

//计算d+c的值,存入a
int a=b+c;

注释应该说明无法在代码中体现的思路:

//解决XX情况下、无法走通用流程的问题
//解决思路是,生成一个虚拟的XX表,设置其中xx和yy栏位值为a/b
//这样,当遇到XX情况时,这个虚拟的XX表就可以参与运算,求得结果
//处理结束后,因为系统中会多余一个XX表,因此需要设置个标记,在YY流程中删除

如此一来,代码的设计思路、corner case的解决思路、因此造成的后遗症以及workaround,全都清清楚楚摆在读者面前了。


容易想到,想要把注释写清楚,那么写注释的大脑必须是清醒的、有条理的——如果别人问你这是怎么回事,你吭哧半天:「我这样一弄、一弄……再一弄,就成了……」

你觉得这种人能把注释写清楚?

你觉得这种人写的代码,你可以随随便便解释清楚其中的每个细节?他自己都不清楚怎么「弄」出来的。

因此,写文档精确描述需求的能力、提纲契领三言两语说清设计思路的能力、有条不紊分解问题、详略得当的把一个极为复杂的事物分片分块说清楚的能力,归根结底,就是你的写代码能力——也是你的读代码的能力。

换句话说,写代码、读代码、写设计文档、需求文档,这几种能力归根结底是一体的。根本无法拆分:要么全好,要么全坏;不存在说不清思路却写的一手好代码的可能;也不存在文档写的丝丝入扣、每个边角都能照顾到、却怎么都写不好代码的可能

换句话说:有强悍的实施能力,必然有强悍的规划能力;想要有强悍的规划能力,那么实施能力必然登峰造极。

否则,没有强悍的规划能力,大脑稀里糊涂,前因后果都理不明白、注释都写不清楚,能写清楚代码?

没有强悍的实施能力,规划?规划个屁啊。你怎么保证你规划出来的,就一定能实施呢?

规划个「识别用户手机壳颜色切换界面主题」,不是找打么?

因此,我才说题主这个问题问的好,问的难。因为你问的,其实是整个软体工程这个至今未能解决的老大难问题。


当然,虽然没有成法,虽然没有什么「套路」;但一般化的思路还是有的。

第一板斧叫「溯源」。

「溯源」就是彻底搞清楚一件事究竟是什么,弄明白它的本质、它的来龙去脉。

举例来说,有人问「为什么我include个C头文件,程序就能正确运行了」?

这个问题,如果你不挖到根本,那么起码得一本书才说得清;而且你读了之后,多半还是丈二和尚摸不著头脑。必须很长很长时间的消化——还不一定真消化得了。

而我呢,直接挖本质:函数就是内存中的一段二进位数据。

C 语言为什么只需要 include& 就能使用里面声明的函数?

技术问题,想彻底解决必须溯源,从根本上把它看透。

如果不能看透,拦腰来一下,你就得编译器链接器系统调度啥的眉毛胡子一把抓。这样自然越说越复杂,越学越困难。

但一旦看透了,一切就都是那么一句话,自然而然就串起来了。

从要做什么事、为什么要做、为什么这样能行、可以玩出哪些花样,全都给串起来了。

很多人喜欢在我的回答下评论说什么「生命有限」,意思是技术内容浩如烟海,短暂的人生根本学不过来。

还是那句回应:你们学错了。

跟著树叶学,收集一千万片叶子,把自己搞的头昏脑胀,照样不知道树是什么样子;找到主干,学习分岔规律、学习叶子生长绽开规律、学习开花结果的规律、学习能量循环的规律——别说一棵树,一片森林都轻轻松松放脑子里。

学习是这样,解决问题也是这样。你必须极其善于抓主干;一旦抓到主干,一切细节都不过是基于少量基本规律的衍生物罢了。

第二板斧叫「抽象」。

我们知道了「函数就是内存中一段二进位数据」,把整个编译链接过程全都「衍生」出来自然很容易。

但这样很容易造成「复杂度失控」:

哎呀这个是不是函数?

不是,字元串。

那个是不是函数?

不是,它在data段。

哎哎,你刚才不是说它不是函数吗?这里怎么调用它了?

嗯……我看看……他在这里做了手工编译动作,把编译后的指令存到原本字元串占用的空间,因此现在它已经是函数了……

好吧……这个函数为什么执行出错?

调用约定不同,你看调用者没清栈它也没清……

怎么样,晕不晕?

因此,想要简洁,我们还必须有意识的丢弃一些信息,从而完成「抽象」。

通过「抽象」,诸多不同的实体被藏起了个性、只留共性;于是外层使用者就可以拿它当「光滑的抽象物」使用,无需关注细节。

通过抽象,函数就从「一段二进位指令」变成了「可以接受外部参数、做一些处理然后返回处理结果」这样一种功能更明确、限制更多、同时又有了诸多相关约定(比如调用时参数如何压栈、由谁保护执行现场由谁清栈、比如变数的作用域等)的抽象概念。

注意,函数有很多种实现方式;有些语言/专家还会把「执行一些动作、但没有结果返回」的函数(function)另外抽象为「过程(procedure)」;这些概念又被另一些语言混乱的杂糅起来,比如C,一切都是函数,再比如tcl,一切都是过程(它就是用proc声明函数/过程的)……

编程领域,这类混乱是常态。以至于很多人觉得这个领域的各种概念都「没有定义」,是没法讨论的虚拟物。

嗯……编程领域的各种概念,的确是人为了各种目的抽象出来的虚拟物;但它们绝不是什么「没有定义」「没法讨论」的虚拟物。

恰恰相反,这里恰恰需要你那强悍的抽象能力。

比如说,当有人说,过程/函数一团乱,没法讨论时,真正的行内人会告诉你,这类东西有严格定义;只不过太多人做了太多随心所欲的扩展/分类,这才搅乱了讨论基础。

想要讨论,很简单,找一个最简洁最原始的抽象,在它上面讨论就行了。

比如,函数就是一段代码,执行完还会返回到调用点,没了。

在这个基础上,如果我们要考察它是否返回值,就把它分为「函数」和「过程」;要考察它是否存在内部状态,于是把函数区分为「只要输入参数相同、返回总是同一个值」的、「幂等」的函数,和每次调用都因为引用的全局/静态变数影响而得到不同结果的、非幂等的函数,等等。

类似的,Linux说一切皆文件,这个一切皆文件就是它的核心抽象——它管理的一切对象,归根结底就是个读写操作嘛,所以可以全都归结到文件上;然后继续添加细节,分成字元设备(文件)/块设备(文件)之类(根本区别是后者有缓冲区,前者没有)……

无论如何,思路是一样的:我们需要先搞出一个最简的核心抽象,然后再在上面添加细节。

显然,想要找出这个最简的核心抽象,先得完成「溯源」。否则何以做出最简抽象?

这个核心抽象可不是随随便便就能搞出来的。它看起来简单,却是最见功底的一环

举例来说,当年的MFC,把图形界面程序抽象成消息、窗口、消息循环等等,然后又搞DDX/DDV(对话框数据交换/对话框数据验证),复杂难懂难用;之后呢,我们知道,有人把图形界面程序抽象为MVC——数据模型(Model)、查看数据/和用户交互的视口(View)、窗口/数据的控制(Control),一下子就把图形程序设计变成了只需拖拖拉拉、连小学生都会玩堆积木/绘图板。

你看,仅仅是核心抽象思路的不同,一个难学难用、到处都是神秘咒语(各种奇怪的宏),就连验证下输入框中的数据是否全是数字,你都得通过宏动用难懂的DDV机制;另一个呢,你只要拖个控制项上去、然后设置属性!

你觉得,是一个MFC程序容易讲明白呢,还是一个MVC程序容易讲明白?

当然,讲明白的前提是你看得懂。先看懂人家的核心抽象,接下来稍微一提就能说通;否则……你慢慢玩,我研究研究你——研究你还能把自己的脑子搅乱到什么程度。

做好了抽象,想要真正简化我们的描述——也简化我们的代码实现——我们还需要……

第三板斧,封装

前面说过,抽象是为了主动丢弃一些细节;但你丢了,你的用户又给它找回来了;或者,你自己写程序时,不自觉的又去窥探细节了——这个抽象,是不是就白费心机了?

因此,我们需要添加一个界面层。这样将来用户就不再能「直接在数组中存机器码当函数用」,而是必须透过我们的这个界面,按照标准流程声明和使用函数。

这样做的好处是,我们可以把函数产生、调用以及运行维护等等细节全部自动化,藏在界面层之后;于是用户们就可以忘记一切细节,只管声明函数、按函数名/函数指针调用它——我们会自动帮他们检查参数个数、类型是否正确,帮他们维护好栈、保护好执行现场,甚至帮他们优化寄存器的使用、自动清理栈上对象,等等。

这些全都对用户「透明」。

透明的意思是,他们可以真的认为,函数这种东西的的确确是存在的、是严格定义的——并不是用一段二进位数据模拟的。

做到这点,这才是高明的封装——术语叫「依赖倒置」:设计者想好自己打算做出怎样的抽象、然后实实在在把这个抽象提供给用户,使得用户的的确确得到了我们的抽象。

不能是反过来,猜想用户将来会怎么用我们的东西、我们要如何迎合他们、他们将来有什么奇葩需求我们该怎么满足……千万不要这样。这会引来没完没了的工作和无穷无尽的bug。

相反,我们得「依赖倒置」:我们搞了一个抽象,我们要把这个抽象搞的尽善尽美,就好像函数这个事物真的存在一样——绝不能让用户看到隐藏在后面的东西、干扰到我们的实现细节(反过来说也对:绝不能让我们的实现细节干扰到用户)。

用术语说,这就叫「封装要自然,不能有封装泄露」。

当然,这是理想。现实中往往有很多妥协。比如为了性能,常常就不得不选择封装泄露。

举例来说,C++的placement new就是一种封装泄露。它泄露了对象初始化流程,使得用户不得不用怪异的语法更改这个流程。

类似的,现在的很多语言喜欢帮用户管理内存,称其为「托管代码」;但直接使用裸指针的需求无法消除,此时就不得不「封装泄露」,允许用户使用unsafe代码。

最典型就是MFC。嗯,业内现在认为,MFC压根就没封装,人家的一切本就在外面露著……

封装的很好,你就可以直接从抽象讲起——这个系统由数据、视图、控制三大基本元素构成,它们的关系是……

一旦封装泄露,你就得下潜一个层次,从背后原理谈起——这个消息循环啊,它其实是一个dispatch,用来派发OS传来的事件……事件和中断的关系是……

至于压根没封装的……你先看看书。先看完微机原理操作系统原理网路原理编译原理……当然,看他们之前你得先搞懂数据结构与演算法……之前你得先上机,做大量练习……没这十几本书打底,我给你讲再多也白讲。

你看,想要「傻瓜式编程」,封装必不可少。封装的越优秀,你的用户才可以越傻瓜

类似的,写程序时,你也一定要做好抽象,然后在良好抽象的基础上完成封装——然后在抽象的基础上讲,才能轻易说清你的设计思路、说清某段程序的功能与职责。


很明显,封装的好坏取决于抽象水平

人生如戏,全靠演技。抽象就是这个演技,抽象的越好,越合理,封装就越自然,越不容易泄露——最好的封装甚至都不需要付出性能代价(甚至反而能轻易得到最优化性能)。

抽象水平又受制于追根溯源、抓住主干的能力

越是善于抓主干,你「讲故事」时,就越容易讲的逻辑清晰、短小精悍。

换句话说,虽然「外向的程序员盯著自己的脚尖和你说话」,但真正玩透了的程序员一定有强悍的语言表达能力。因为他的工作就是寻找自己面临的、复杂的任务的核心矛盾,然后形象生动的把它讲清楚——清楚到连电脑都能听懂、都能一丝不苟的把事情做完美的程度。

为了讲清楚这些,他的等效能力、抽象能力,必然会向著登峰造极的方向不断发展——与之同时,优秀程序员的理解力必然得到锻练。以至于很多很多东西,只要你提一个关键词,前因后果他就全知道了。

当然,我也遇到过很多很多怎么讲他都不明白的。甚至可以说这些人是大多数。「听不懂一个机制」很可能仅仅是因为这个机制就有那么复杂,实在没法继续简化。

还是那句话,表达能力和理解能力本是一体,你不可能丢掉其中一端。程序员这个职业不存在「茶壶里煮饺子」这一说,毕竟他们的「沟通目标」是机器——人和机器的区别是,机器只要你把事情讲清楚了,不管篇幅多长,它都不会漏看半个字。

而人嘛……因为长了看不懂,所以太长不看。


综上,如何语言描述代码实现的功能?

首先,你得看透这个功能的本质。

然后,你得把这个本质清晰表达出来。

之后,你还得针对这个本质做出一个漂亮的抽象,把核心问题转化到这个抽象上。

有了抽象之后,你再通过抽象「讲故事」,把要做的事说清楚。

最后,把以上种种,全都通过代码表达出来——这一步至关重要。很多对人类来说很简单的事,电脑就完全不能理解。比如「妥善护住颈部、把孩子慢慢抱起来」,这句话就没人能教给电脑。

看个实例。

假设我们需要做一个淘宝,允许成千上百万类商品通过淘宝售卖。那么这里就有一个难题:电话卡的卖法能和网游充值卡一样吗?和卖袜子等实物商品能一样吗?怎么卖3件呢?怎么第二件半价呢?怎么「满三十包邮」呢?

你看,几百万类商品啊,个个要求都不一样……淘宝程序员要累死了吧?

还好。我们可以抽象。

怎么抽象呢?

成千上百万类商品,归根结底都是「商品」。

商品是什么呢?

一种「可以通过交易改变所有权」的、有形或无形的劳动产品。

好了,抽象有了:

1、商品有所有权

2、商品所有权可交换

3、满足这两点的,就是「抽象商品」

有了这么个抽象商品,接下来就简单了:

1、我们需要允许卖家自定义一个页面,用来展示商品

2、我们需要允许卖家给商品定价

3、当买家有意购买时,他要付出相应的金钱

4、现在,我们要标记这件商品,把「它的所有权正在从XX卖家转换到XX买家」更新到其状态上

这是分界线内部做的事;外部使用者呢?

商家:

1、我要自己维护一个页面,把自己的商品描述清楚

2、我要选择一个定价策略,设置好商品价格

3、等待顾客购买

4、发货(提供数字凭据,或者召唤快递公司)

用户:

1、我看到了一些商品,通过商品页面的描述,我知道了它的各项参数

2、我看到了商品价格,也知道如何取得优惠

3、购买

4、商家给我发来了数字凭据,或者通过快递公司送来了商品

你看,有形/无形商品,后台逻辑完全一样嘛。

逻辑简单了,是不是很容易就能说清楚了?

一旦基本逻辑说清楚了,继续:

1、为商品添加更丰富的说明手段(支持更多表现形式)

2、增加更多更灵活的定价策略(包括618以及跨店满减等等)

3、(后台)通过CDN使得用户浏览更顺畅,通过集群、队列等各种技术支持秒杀

4、通过支付宝担保交易

你看,核心抽象之上,可以添加很多很多东西。

你可能已经注意到了,核心抽象越简单、功能越薄弱,系统反而可以写的越灵活、越方便扩展

没错,这就是Linux哲学:做一件事,把一件事做好。

一样样做好抽象,确保这些抽象彼此「正交」,反倒更容易集成出庞大、复杂却又高效的各种功能。

眉毛胡子一把抓,反而什么都做不好、将来也难以维护、难以扩展。

这种强悍的抽象能力,这种把复杂问题做简单的能力,是软体工程师的最重要的核心能力之一。

它的养成不是一蹴而就的,需要你长时间的浸淫其中,在大量的思考和实践中总结、升华。

只有获得这个能力之后,那些经典代码背后藏著的思想才会对你开放——读这些代码时,你才能飞快抓住重点。

换句话说,强悍的读代码能力是靠著强悍的写代码能力支撑的;而强悍的写代码能力又要求你善于总结、善于抽象、善于表达;两者相辅相成,读懂代码、讲懂代码和写出易懂的代码才会齐头并进的发展。

这个能力的核心虽然说起来简单,抽象和封装而已;但这种能力的养成是水磨工夫,需要自己在大量的成功与失败中慢慢体会——不然一句句都是「务虚」,没一句是能马上拿来用的。

——你看,为了把这件事说清楚,为了让表达有说服力,我就不得不写这么长。

——写这么长,就必然会引来「太长不看」党。然后继续重复他们那可笑的错误……

——正是这种无法用条条框框取代亦难以言传的经验,使得软体工程至今不能是个工程;程序设计仍然是个艺术。

【套装4卷】计算机程序设计艺术京东¥ 534.30去购买?

代码大全 第2版 电子工业京东¥ 96.00去购买?


大佬们从理论出发了……

我就说点儿,实际业务的:分层每层只描述自己这一层该知道的概念。每层的每个模块都足够简单了,你就好描述了……

直接细化到 var a = "b"; 你当然不知道 a是干嘛的 b是干嘛的……

每个层级的概念混为一谈,那就肯定会乱。

编程语言本身,就已经是很多层的封装了……

也就提供了很多抽象的概念,执行顺序、函数、运算、类、介面等等、等等我等CURD程序员,要做的是什么呢?是把这些封装,再进行封装,封装成 用户数据结构,用户类实例,用户控制器,用户介面并对外「暴露」这个介面。使得其他程序可以按照某种方式调用这个介面

对调用者来说,我只需要知道 用户这个抽象概念有个创建介面,就足够了。

至于里面你是怎么实现的,到底是操作了一个用户表,还是操作了 几十个表和我没关系。

知乎计算机回答下面的回答,一般来说,很少看到经典的理论讨论, 大多流于类似于B站看谁敲代码快的竞赛,而在知乎就是文章长,长就是对。上次谈资料库,随口讲了个范式,被一堆小鬼轮流百度百科。

语言描述代码这是门科学,属于概念设计底下。用的是伪代码。pesudocode。顺便说一句,这个单词有趣的点在于,p是不发音的,所以你写伪代码写的好,我就按正确的读音读,你伪代码写的不好,我就p发音,表示你写的是个p。

在概要设计里面,详细代码的功能实现,一般采用数学化伪代码方式解决,这既照顾了普通人又照顾了实现者。

比如最常见的例子就是这个FFA,这就是标准的「语言描述代码功能」,或者更准确一点「数学化自然语言描述代码功能」,很多人可能会骂,这个你也算是自然语言?对不起,当谈论编程的时候,你可以没有实际编程时数,但是如果你没有高中左右数学基础,那我们还是去追割割比较好。别浪费时间。

在自然语言当中,有皮钦语,也就是一种语言的分支,比方言更正式化,但是和本源语言又有不同,比如很人多认为日本侵华时候的兵队中国语就是一种日语和中文的皮钦语。皮钦语的存在是为了弥合两个语言族群之间的落差而产生的一种沟通用「语言胶水」

在计算机世界也有皮钦代码,也就是代码和自然语言的混合,或者多种语言之间的混合。一种「洋泾浜代码」,这让自然人和程序员,或者不同语言程序员之间能够就程序上沟通。


其实有些事不要陷进去,而是从整体量上看待,就能得出可靠的结论。

我一般一个工程项目30KB代码,把这些代码头尾相连连续不断地口头读一遍,差不多要多久呢?按照一秒钟一个词,平均三五个字母一个词,我想大致2至5个小时吧。算上重写的部分,差不多10个小时。(完全没有重写的新工程代码,相当于要求人做数学题不用草稿纸,直接写答案。)

注意,是讲10个小时的量的,前后逻辑严谨的话。这样看还能够胜任吗?

类似的例子还有,牛人完全理解一个操作系统,这是可能的。但是Windows系统的源代码体积,查一查,就会发现那是一个人不吃不喝一辈子照著成品敲,也敲不完的量。因此显而易见,一个人不能写出一个完整的操作系统。


用语言去描述有点苍白,一般很少有人直接写文章去描述一个程序的实现细节和功能。

那我来说吧,我在梳理代码的时候会使用流程图来做辅助。

一般功能上的逻辑直接使用脑图按照函数的调用关系进行一层一层梳理。

如果是面向对象的架构,使用viso画出uml图就比较直观。

流程图比语言更直观,程序代码,只要你理解了,梳理通了就可以去得心应手的解bug了。


尽量少写注释,提高自己的不可替代性,防止轻易地被优化掉


这是个什么语病问题?

代码都写出来了,却没有文档描述?不知道怎么用自然语言描述和解释?


确实是个好问题,我来蹭大神写个回答。

读代码是一种能力,和写代码确实不一样。

代码是给计算机读的,所以读代码时你得是一台计算机。

你首先必须熟悉计算机能干什么,最基础的,cpu能干什么?看这个吧

《深入理解计算机系统(原书第3版) 》([美]兰德尔 E.布莱恩特(Randal,E.·Bryant),等)【摘要 书评 试读】- 京东图书?

item.jd.com

CPU基本就是读内存,算,写内存。在代码中,内存大多数时以变数形式存在,那一段代码的基本行为,就是在读变数,写变数。你需要知道一种语言的变数生命周期,来确定哪些改变是临时的,哪些是有意义的,需要你关心的。对于一段代码的封装语法,也是很重要的,现在封装的比较流行的单位是函数,其实还是语言问题。

语言的话,我知道C++不完美,但是作为学习对象是非常不错的。很多工程上的问题,作为学习目标来说,反倒是优点,比如特性多,啥范式都支持等等,有时间读读这个

《C++ Primer(中文版 第5版)》(Stanley B. Lippman,Josée Lajoie,Barbara E. Moo)【摘要 书评 试读】- 京东图书?

item.jd.com

明确了生命周期和函数的作用(输入与输出),就可以开始读了,关注点就是变数,这个时候就是IDE出场的时候了,你需要学会按变数名查询一个项目的所有引用,这样可以针对关键变数在脑中或者纸上构建数据处理流。

除了数据处理之外,函数内部的计算过程其实大多数假设他们写的是对的就行了,如果需要深究,学习一下基础知识比较好,演算法导论这个时候出场

《演算法导论(原书第3版)/计算机科学丛书》([美]Thomas H.Cormen,[美]Charles E.Leiserson,[美]Ronald L.Rivest,[美]Clifford Stein)【摘要 书评 试读】- 京东图书?

item.jd.com

以上都过一遍之后,你可能发现只能看懂计算矩阵对角线数字的值这种代码(话说这个叫啥来著,有个名词来著)。但是CPU真的也就能干这些。更进一步,需要其他硬体的配合了。问题是我是搞软体的,硬体真的不懂,多亏有操作系统封装了硬体相关的操作。其实不需要操作系统这门课,对与读代码帮助太小。我们需要的是操作系统的编程介面介绍,下边两本书值得推荐,当然手机和苹果操作系统也需要,但是我不懂。

《微软技术丛书:Windows核心编程(第5版)》(杰夫瑞(Jeffrey Richter),等)【摘要 书评 试读】- 京东图书?

item.jd.com

《UNIX环境高级编程(第3版)》((美)史蒂文斯(W. Richard Stevens),(美)拉戈(Stephen A. Rago))电子书下载、在线阅读、内容简介、评论?

e.jd.com图标

操作系统编程介面,API,主要就是一些函数,我们知道功能就可以读懂代码了。

更进一步的话,需要看一个存在的框架的介绍了,当前要看的目标代码所依赖的框架,做进一步研究。

以上基本是以C++语言为基础假设做的推荐。对于带虚拟机的语言,操作系统API,语言,框架等等,很多是合一的,可能需要单独讨论。但是,还是那句话,C++这系列虽然工程上有很多问题,但是学习的话,比较清晰明确,而且很多时候造轮子比较多,适合了解原理,对于任何软体方向都是有帮助的。


推荐阅读:
相关文章