名言警句



Windows API:《Windows程序设计》+《Windows核心编程》;

/

C++Primer
The Design and Evolution of C++
Inside C++ Object Model
C++ Template (Meta Programming)?

然后再学Haskell(这是非常重要的一环,不可或缺),之后就会充分理解STL和Template这么设计的深刻含义了,从此成为C++大牛



作者:vczh
链接:https://www.zhihu.com/question/20297036/answer/18380715
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

认真学完 C++ Primer 后,C++ 语言到了什么水平?

达到不会在论坛上问弱智问题的水平。——不是针对你,是真心话。网上很多C++小白问题都可以用一句话回答:C++ Primer第n版第x.y节。
够不够?不够,你至少还要学 Effective C++ 才能开始用 C++ 干活。

C++Primer 5th + Visual Studio 2013 Community

///

http://bbs.csdn.net/topics/391851971

理解讨论之前请先学会如何观察

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

 

///

C++学习建议

C++缺点之一,是相对许多语言复杂,而且难学难精。许多人说学习C语言只需一本K&R《C程序设计语言》即可,但C++书籍却是多不胜数。我是从C进入C++,皆是靠阅读自学。在此分享一点学习心得。个人认为,学习C++可分为4个层次:
第一层次,C++基础:挑选一本入门书籍,如《C++ Primer》、《C++大学教程》、或Stroustrup撰写的经典《C++程序设计语言》或他一年半前的新作《C++程序设计原理与实践》,而一般C++课程也止于此,另外《C++ 标准程序库》及《The C++ Standard Library Extensions》可供参考;
第二层次,正确高效地使用C++:此层次开始必须自修,阅读过《(More)Effective C++》、《(More)Exceptional C++》、《Effective STL》及《C++编程规范》等,才适宜踏入专业C++开发之路;
第三层次,深入了解C++:关于全局问题可读《深入探索C++对象模型》、《Imperfect C++》、《C++沉思录》、《STL源码剖析》,要挑战智商,可看关于模版及模版元编程的书籍如《C++ Templates》、《C++设计新思维》、《C++模版元编程》;
第四层次,研究C++:阅读《C++语言的设计和演化》、《编程的本质》(含STL设计背后的数学根基)、C++标准文件《ISO/IEC 14882:2003》、C++标准委员会的提案书和报告书、关于C++的学术文献。


由于我主要是应用C++,大约只停留于第二、三个层次。然而,C++只是软件开发的一环而已,单凭语言并不能应付业务和工程上的问题。建议读者不要强求几年内“彻底学会C++的知识”,到达第二层左右便从工作实战中汲取经验,有兴趣才慢慢继续学习更高层次的知识。虽然学习C++有难度,但也是相当有趣且有满足感的

/
至于快速入门,强烈推荐 Essential C++,其为C++业界入门必读《C++ Primer》的作者剥去繁杂,只讲C++核心的一本书。
//

我觉得熟悉C++,至少要能够做到这些:

1、你完整阅读过C++ Primer 第五版之后的书,这本书可谓是C++程序员入门必读的书。(为什么我推荐第五版之后,因为第五版之后包涵的内容是C++11标准的内容,你现在重拾编程语言,那么推荐你看新的书)

2、你能够对面向对象编程有明确的概念。因为现在许多程序员用着面向对象语言,却做着面向过程的事情。

3、能够利用C++配合DirectX或者OpenGL来制作Windows小游戏。

4、对数据结构有一定的认识,能够准确针对问题选择你的数据结构。

5、其他内容一下子没想到这么多,等以后更新。
///
整明白《C++ Primer》,对C++有一个感性的认识之后,你可以去看侯捷翻译/写的几本书比如Effective系列、《STL源码剖析》,甚至对于没什么人用的MFC,你也可以看下《MFC九(shen)浅(ru)一(qian)深(chu)》,看下上个世纪的业界的C++程序员都是怎么样来用C++这门语言的。然后,可以看看《Inside C++ Object Model》,深入理解下C++。然后,对C++已经有了一个理性的认识之后,就可以再拿回来《C++ Primer》,顺便再翻翻《Thinking In C++》,查查C++标准什么的,仔细琢磨琢磨自己究竟能用C++干什么。至于模板元、FP什么的,题主看完这些书自然会知道自己有没有兴趣接触的。

最好用的工具:profiler
我身边的这位大牛写程序的方式是:花很多时间设计好架构,然后以最快最易读的方式写出实现,然后profiling,深挖瓶颈再做改进。一开始就考虑细节设计是学生常犯的错误。

最大的鸿沟:多线程
世界上只有两种程序员,一种能左右互搏,另一种不能叫自己程序员。如果不能玩转多线程设计,还是转行做其他有前途的职业好些,比如很多人就回学校当了老师教编程。


最大的挑战:大型多模系统的架构设计
出色的架构师好似乐队的指挥,他们懂得一个很现实的问题:不同的模块是不同的人写出来的,他们能力参差,相互可能不熟,甚至没有见过,更有甚者相互敌视。架构师必须有威望,不然各个组都会找架构师抱怨自己的模块活儿太多可以让别的模块分摊点儿。架构师必须有领导才能,不然上线后出了问题各个组会相互推脱踢皮球。

所以架构并不只是程序和程序怎样沟通,还有不同组的人沟通。好的架构可以让不同模块指责分明,不同组的人分工明确,这不仅有利于初期功能的实现,对之后的系统健康的维护和成长也是至关重要。这一点在学校是学不到的
/
“以前觉得,反正要写程序,只要往死里写,总是可以写出来的。”

Synchronization (Windows)

Processes and Threads (Windows)

 

把这两个都看完(特别是文字部分),然后补补操作系统,你就学会了任意语言的多线程编程了,再也不局限于C++

 

知乎用户

看这个之前需要先看windows程序设计吗

0 赞vczh(作者) 回复 知乎用户

当然是要会一点的

先看操作系统里面的多线程和多进程,个人推荐《现代操作系统》,里面会简单的使用pthread。如果基本理论都懂,你可以直接看《c++标准库》,这个里面有一章讲c++的并发编程,讲了标准库怎么用,有哪些注意的。最全的估计还是c++ concurrency in action了,这本是标准库那本书推荐了的。这几本书都是和操作系统无关的,Linux和Windows下用法一样。我当初是先会了Windows下的并发编程,刚看C++的还有些不习惯。

//

The C++ Standard Library 2nd介绍了C++11中添加的并发特性
《Windows核心编程》更是介绍多线程编程的好书,Jeffery Richter专注多线程一万年,CLR via C#也介绍了多线程编程

 

计算机本科应届毕业生要有怎样的能力才算比较好的?

 

对本科生的要求其实很简单,认真学过专业课就行。

所谓认真学过专业课的程度是:

  • 熟练掌握数门语言
  • 熟练掌握一个平台
  • 熟练掌握、理解算法和数据结构
  • 掌握编译原理、操作系统、网络、图形、数据库等专业课程知识
  • 认可《软件工程》

 

能达到这个程度的本科生,可以随便秒大部分水硕


以我为例,我大二开始学编程,到找工作时只学了两年,达到的水平很低微:

  • 不够熟练地掌握了c和python,完全不会c++
  • 熟练掌握unix平台
  • 熟练掌握、理解算法和数据结构
  • 写过编译器、半成品操作系统、图形网络和数据库流于理论
  • 认可《软件工程》



作者:萧井陌
链接:https://www.zhihu.com/question/25753307/answer/31518801
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

 

 



接着说回开了天眼后的故事,接下来几年,我抱着到处走走看看的想法,游荡了几个不同行业的大公司,接触了形形色色的程序员,总结出规律如下:

  • 大部分程序员都是技术非常单一,视野狭窄的
  • 很多人是拿程序当跳板,最终都要转行
  • 号称喜欢程序又不努力的,其实只是说说而已,做这行八成是没别的会的家里又没背景的



那么回到正题,我觉得本科生具体应该学好的知识如下 :

  • 语言:C和scheme,两个极端范式足够了
  • 数据结构和算法,《算法导论》
  • 计算机系统,《csapp》
  • 软件工程,《sicp》

完,这太简单了。。


以下任意内容可加分,具体加多少分看别人喜欢哪点:

  • 并行算法和数据结构
  • 编程语言理论
  • 数据库、网络、编译器、图形、操作系统
  • 测试

完。



作者:萧井陌
链接:https://www.zhihu.com/question/25753307/answer/31518801
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如何去学习程序员的三大浪漫,编译原理,图形学,操作系统?

 

书给多了你也就迷惑了.
我给一个基本建议, 不要用c/cpp/java这些语言来写. 用python/ruby/racket随你愿

个人觉得那几本书特别是编译器的书很有可能严重打击你的士气, 因为它们都有严重的毛病
就像这样

(汉化了一下...)


所以可以走easy mode, 比如
编译器你可以...

  1. 先实现lisp语法的解释器(以后你可以拿这个金手指找别人约架...)
  2. 把它编译成一个栈式虚拟机代码
  3. 转换到汇编或者直接用虚拟机跑就随意了

 

图形学你可以...
放弃, 最后再弄

操作系统你可以...

  1. 先<操作系统概念/现代操作系统/FreeBSD操作系统设计与实现>随便看一本, 理解概念就行
  2. 再去github上抓一个小操作系统来玩, 也就1万行代码不到, 就ok了

 

然后你别忘了...
计 算 机 网 络, 一个完整的tcp/ip协议栈不过3-5万行代码, 如果你做完了上面的事情, 写个协议栈也就是3-5个月的光景
如果你们学校用锐捷/3com认证网络
如果你们学校限制客户端数量
如果你们学校限制客户端操作系统
如果你们学校限制上网时长
如果....

那你就有救了, 一网在手, 天下你有. (但是的但是千万别专门当写网络程序的程序员, 非 常 无 聊(当然说不定你也许会喜欢什么的...))

 

(在你觉得空虚无聊寂寞冷的时候, 可以看看SICP, 我认为它是软件工程的精华所在
(moreover, 在Lambda the Ultimate上可以学到很多PL知识

 

最后, 要当一个好程序员, 一定要好好看看<代码大全>和这个网站The Pragmatic Bookshelf

上的书

作者:萧井陌
链接:https://www.zhihu.com/question/22482295/answer/23508622
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

//

 

7天看CLRS足够了,不过除了吃饭睡觉之外不能停。我第一次读的时候花了五天半,真的,当小说看,实在太好看了。Introduction to Algorithm本来就是突出一个Intro,在易读性上做了极大的优化,正确性的证明也改成了循环不变式。

/

先学SQL,把子查询,group by, order by, having, union, exists, in, join, left join, inner join 搞得明明白白 
装个SQL 2005,装两个实例。装service pack。装了卸,卸了装,直到呕吐(嘿嘿) 
把login, user, schema, linked server这些基本概念搞清 
把不同的系统权限,用户权限学习一遍 
建数据库,备份数据库,全备份,增量备份,日志备份 
建表,写SQL建表,把常用数据类型搞懂,边建表,学习update/delete边插入/删除记录,边做备份 
然后恢复数据库,恢复全备份,恢复到某个标记,恢复到某个时间点 
用SQL命令把上面的这些操作做一遍(都有SQL的,不要只会用鼠标点来点去) 
DBCC的一些常用命令 
好好学习一下索引,用SQL建索引,各种各样的索引 
建几个表,分别有1千条记录,1万条记录,10万条记录,100万条记录,500万条记录
每建一个表,就看看数据库如何变大,日志如何变大,如果没看懂,恢复数据库到前一个状态再做.... 
把数据库缩小,放大,增加数据文件,把数据文件放在不同硬盘上,把日志截断(虽然小了,但看看还能不能恢复) 
把主键,外键,约束,默认值,数据类型等基本概念搞清楚 
然后开始在上面玩索引和各种查询,玩玩备份和恢复,删除50万条记录,插入10万条记录,等等 
看你的硬盘小灯乱闪,CPU冒烟,你就对性能和速度开始关注了(嘿嘿) 
就会想着怎么优化一下你的SQL,怎么优化索引等这些问题了。 
学习T-SQL的一些基本东西,学习一下存储过程,触发器 
到这里多回答别人的问题,帮别人写点存储过程,触发器的代码,多看别人怎么写的,怎么解决问题的。 
到这里,你应该有不错的基本功了。 
如果对数据库开发有兴趣呢,T-SQL要熟悉,会分析execution plan,对索引比较精通,然后就是要使用的程序语言
如果要做DBA,我觉得一个好的DBA应该有很好的开发方面的经验, 
主动争取维护一下开发环境下的数据库,首先是每天都备份,然后看看有没有可以优化的地方。 
多关注性能,安全,备份/恢复,高可用性方面的东西。试试数据库复制,日志转移,数据镜像,如果有机会再试试集群
//
我觉得软件开发这个行当是工程性很强的一个行当,这类行当的学习路径和学术研究性的几乎相反:不是先学了一堆“基础知识” “背景知识” 之类的东西再深入研究,而是先从最高级最方便的quick&dirty way开始,向底层细化。


按我说就先挑一门语言,然后选这门语言的前三流行的框架或开源应用中任意一款,先撸个hello world,再撸个博客出来,博客做完发布做评论,做完评论做用户,做完用户再看看你以前写的代码删光从头写起。当然把博客换成其他需求也行,只要自己需要用的都行

 

至于需要的知识,压力大了自然要缓存,模块复杂了自然要解耦,上线次数多了自然要部署要自动化,一切知识都是以解决问题为导向的。没遇到问题就空学所谓基础知识,在我看来事倍功半。就好比题主提的“服务端开发”,其中也有很多细分,做业务逻辑的,高并发的,事务的,更别说做数挖的dba的devop的等等,又或是小业务的一条龙包干,都是相当不同的技能要求。

看到此问题心里一惊。。。。一直觉得计算机网络是专业课里面最简单的。谁问我最喜欢哪门课我都说是它。
难,那是因为你没用这本教材。
&amp;amp;lt;img src=&quot;https://i-blog.csdnimg.cn/blog_migrate/98b30e7460ccddfae25127a22b4b2cd7.jpeg&quot; data-rawwidth=&quot;303&quot; data-rawheight=&quot;438&quot; class=&quot;content_image&quot; width=&quot;303&quot;&amp;amp;gt;本人大学所有专业课均为考前看课本自学,唯有这本让我觉得可以完全胜任“自学”的功能。深入浅出,幽默生动。没有数学书上那种一句一句的定义和公式,更多的时候是大段大段的讲解,各种形象,看小说似的,很快就看完了一本,看完后内牛满面,从没想到自己也能读完一本。

本人大学所有专业课均为考前看课本自学,唯有这本让我觉得可以完全胜任“自学”的功能。深入浅出,幽默生动。没有数学书上那种一句一句的定义和公式,更多的时候是大段大段的讲解,各种形象,看小说似的,很快就看完了一本,看完后内牛满面,从没想到自己也能读完一本。

考前5天,每天一到两章通读(中文版就可以了),再把章节后的习题一做,看懂百分之多少就能得多少分。

 

链接:https://www.zhihu.com/question/19718686/answer/17884293

验证码识别竞赛——代码与思路分享 

http://bbs.pkbigdata.com//static/413_detail.html

https://github.com/lllcho/CAPTCHA-breaking

在安卓上部署服务器

http://zkeeer.space/?p=89

https://ngrok.cc/

vultr

/

1417 TCP/IP0341 6008 2589 0001 0020 2861 1819 ,2053 0961 0659 1120 0001 4638 2429 4545 6849 1400 0055 1771 1122 ,1432 0008 6850 1788 0055 ,0110 0007 2508 6969 2234 :


4170 2579 2508 1771 2661 3604 4104 ,1172 2654 3093 2589 3810 6043 ,4170 1346 0048 1432 1808 1346 0055 ,3810 6043 0001 0020 0588 6231 2584 1170 4104 2455 3127 ,0341 4170 2673 0020 0588 6231 1172 ARP,4170 1346 0001 6664 ,2092 7030 2119 0545 6516 0115 wireshark ,3938 6665 3459 0892 0662 2116 ARP filter in,6638 2876 1432 0662 2589 ARP0055 ,4170 6386 0171 3237 2530 1771 1122 ,0132 1432 0668 0110 1976 1976 0433 2649 1338 0226 2508 1172 0149 request ,reply0055 ,0059 1461 0087 8010 0966 0968 ,ARP2589 0763 0067 1316 3008 ,ARP6043 0414 0087 8010 0795 7344 ,0031 2623 1827 8010 4883 1317 1338 ,3938 ARP6638 2742 0730 0109 0668 0110 4170 .


TCP/IP1629 0008 2508 IP ,TCP ,UDP,1338 2508 1771 1122 0588 6231 4104 0678 7162 ,0545 2161 ARP,ICMP,IGMP,DHCP,DNS4583 4583 ,6638 0067 0588 6231 0132 6757 0668 0110 2119 0545 0171 0433 2649 ,6703 6008 1601 4192 0795 7344 0171 4170 2579 0735 0254 1395 7526 :3634 0087 8010 2589 6638 0020 0588 6231 ?6638 0020 0588 6231 2251 0180 0087 8010 2591 0523 ?


2053 1730 3525 1696 6231 4882 0001 0067 UDP-based , TCP-based1420 4453 1645 ,1771 4675 0830 4104 ,1432 2508 6148 3938 socket2234 0656 0428 2422 ,0433 3634 2591 0523 0892 4551 ,1356 2073 4551 ,3544 0683 1432 0668 0110 2119 0545 6665 3459 0433 2649 0055 ,4170 4170 TCP0005 2945 2259 2087 ,0005 2945 2259 2087 6757 2508 socket 0171 1346 2052 4104 ,2477 7194 0132 0171 1400 code,0132 0662 6008 6148 3938 send () receive() 1432 0668 0110 1346 2052 2422 2207 1779 4099 6623 5280 2234 2392 .


3544 0683 0132 6703 0668 0110 capture HTTP 0545 0171 0433 2649 ,4170 4170  data link layer , IP layer , TCP layer , HTTP layer 2508 1172 0149 1409 5944 4104 ,TCP sequence number , 0087 8010 2876 flag4104 TCP segment 2585 0169 sequence number 1073 0502 .


4920 0037 ,0055 6043 3020 0020 0588 6231 6043 0414 0087 8010 0795 7344 ,1601 4192 6638 0020 0795 7344 4170 2579 ,0254 1395 7526 ,4882 1420 4453 1645 ,2119 0545 0433 2649 0588 6231 0074 0062 ,0588 6231 1316 3008 ,6638 2876 0668 0110 0356 2455 0143 0966 4249 6670 2577 1122 4798 4634 ,3810 6043 0055 1432 6068 0145 0055 

这篇不好转载,留着自己看。

///

可以看《TCP/IP详解卷一:协议》,但只看这本书会有点枯燥。

可以边看书边抓包分析,推荐使用Wireshark和另外一款商用抓包软件(为避嫌不说名字了,个人学习版免费)。

链路层,网络层,传输层,应用层各种细节一目了然。

这酸爽让人无法相信。

科来

//

第一阶段:
先了解七层模型,然后看一下CCNA/NP的教学视频和书籍,对网络模型有初步了解。
第二阶段:
可以去看看《TCP/IP详解卷一》,讲基础。
第三阶段:
学习一些理论知识,最好的还是机械工业出版社出版的《计算机网络,自顶向下网络设计》和《计算机网络,系统方法》。
第四阶段:
看《TCP/IP详解卷二》,讲Unix TCP/IP协议栈设计。
第五阶段:
看Linux 内核源码network部分。
以上都是关于TCP/IP的知识点,不包括广域网技术和其他的接入网技术等,

作者:张博

链接:https://www.zhihu.com/question/28943943/answer/47032873

//

达特茅斯的 lab DartNet
传送门: assignments
However, this lab is focused on the whole network protocol stack.
这个实验大概的升级路线是这样的:

  1. 了解 socket 编程,会抓包
  2. 写个 IM
  3. 自己实现 tcp 窗口,重传机制
  4. 然后。。。假装 TCP 不存在,重新实现 传输层,网络层,链路层
  5. 在你自己实现的网络栈上,支持之前的 IM

后面的几个实验相互衔接,并且实验也有框架代码。省去很多琐碎的工作。
而且给的参考文档也不错。比如 socket 编程入门啦,多进程/线程 编程入门啦 之类的。

作者:RunshenZ

链接:https://www.zhihu.com/question/28943943/answer/45613963

/

打开Visual Studio .NET 2003 命令提示键入ILDASM,这个程序可以查看编译后的元数据。

网上查一下Reflector这个软件。干什么用的。反编译呀。。。。寒。

/

关键他基础差啊,就只会界面,还不精通,逻辑底子差,就必须从js练起啊,angular、react,有js基础跟没js基础学能是一个道理吗?(换句话说,他现在vue也才API刚上手,学其他不是一样困难吗)
框架都是相通的,只要你的js基础够扎实,啃会了第一个难度angular框架,之后就发现每拿到一个新框架,上手熟练程度很快,因为很多自主逻辑设计的时候就考验的是你的这个底子,就像造房子,js就是地基,现有的web前端热门框架都是在这个基础上发展来的,他现在缺的就是这方面的练习。会了js,懂了最重要的地基,这些框架的理解就能变得很简单。
至于nodejs,对面他这种刚入行没多少经验的新人,根本用不到,学node是要有雄厚的前端基础才能学好的,一口吃不成胖子,他得从最重要的基础打起,我认为最重要的逻辑基础就是js,没毛病。
至于你的第一句这么多句号,可能是我表达的不够清晰吧。
JS的这个学会,可能我表达的不是很准确,我想说的是js学会,就是至少到熟练的程度,这个是日积月累的一个过程,学会了不是说我看一遍书,看着书敲一下就是学会,学会就是能够自己看到一个js逻辑设计,就能立马用自己的编程还原或者设计出一个类似的逻辑(比如说从小的数组奇偶分组排序,到之后的逻辑配合界面实现动态效果,再比如说做个小游戏demo,像2048、贪吃蛇这种js逻辑程序,就是相当熟练的地步了),犀牛书1000多页,啃的时候难,啃会了还能当指导手册,学会了再看框架真的会舒服很多。
毕竟,框架是会不断的变化的,今年是vue火,未来可能出个新的框架,又得自己看api自学,但是底层的js逻辑设计是一直在的,js对于一个web前端新人来说,是必需也是必须学会的,慢慢熟练至精通的一门技巧。

 

计算机专业课程之间完全可以用抽象来联系:每一门课想做的事就是利用下层提供的接口,实现功能,然后再给上层提供接口。这样一层一层的抽象就构成了几乎所有的专业课。

先来看最高层,问题。刚学编程的时候,会先学一门课导论课或者编程入门课,我当时的入门课叫做“程序设计”,课程内容是介绍一些问题,然后介绍一点编程语言的知识,作业是一些编程问题,比如八皇后、素性测试之类的比较常规的编程题。这门课的目的一般都是介绍“问题”的,介绍计算机科学有哪些有挑战的问题,让学生对计算机专业有一个感性的认识,而不是对特定编程语言或者算法的学习,所以这类课程一般用python来编程。

再往下一层,算法和数据结构。这一层的目的是学习/实现各种算法/数据结构,提供给上层功能。比如排序,问题解决者只要知道这里应该用快速排序,而不是选择排序,而把快速排序的实现留给这一层的开发者,从而使各种优化都可以对上层透明,比如小数组变插入排序、中位数取pivot、三向快速排序等,这些优化调用者完全不必要知道,他只需要知道:哇,这个库提供的快速排序还真快。

再往下一层,语言层,毕竟所有算法都要由某一门语言来实现。这一层的存在使得算法的设计可以脱离具体的语言。不同语言又提供了不同的抽象,像函数式语言就比命令式语言的抽象级高,更高的抽象级意味着更加专注问题本身(不需要考虑内存布局、CPU使用等)以及更少的代码量。

再往下一层,编译器/解释器。我们编写代码是用高级语言,而cpu上执行的是机器码,所以这个抽象层帮我们做了这个转化。这个抽象层的好处是,高级代码的编写者完全不需要知道这个程序所运行的操作系统和硬件平台,任何有该语言编译器/解释器的机器,程序都可以跑(从而实现了跨平台)。应用层开发者可以不用知道这个由高级语言到机器码的转化具体是怎么实现的,毕竟编译器优化的编写和优化完全是一个团队的工作量,开发者关注问题的解决,编译器负责转化出高效的机器码,各干各的,这正是抽象的重点。

再往下一层,操作系统。OS向开发者抽象了硬件(CPU、内存、Disk、NIC等),并且以syscall的形式向用户提供服务。OS的设计是最能体现抽象的,虚拟内存和进程让程序以为自己独占着内存和CPU,同时隔离了不同进程以防恶意进程;文件系统让用户可以方便地读取存储数据,而不需要直接操作底层的硬盘;文件描述符抽象了底层的设备(pipe/file/device/socket/…)。

再往下一层,ISA(Instruction set architecture),俗称软件与硬件的接口。这个俗称是非常形象的。指令集架构,说得简单点就是机器码,也可以理解为一个协议。ISA标准制定者指定一套指令集(比如x86、PowerPC、SPARC),然后编译器开发者需要根据这个标准/协议来编写对应的编译器;CPU制造商需要根据这个标准/协议来制造出支持这套ISA的CPU(比如intel的CPU支持x86/x86_64)。也就是说,软件/硬件都依照这个ISA来设计,那么就可以对接了。

再往下一层,组成原理和体系结构。这一层要做的事情是借助数字电路给它提供的功能(组合电路和锁存器),来设计一个能实现某种ISA的CPU,让编译器生成的指令可以在此CPU上运行。大学里一般会开一门叫“计算机组成原理”的课,一开始学单周期CPU的实现(取指、译码、执行……),为了提高效率又提出了流水线的实现。为了发掘更高的效率,之后又会学一门叫“计算机体系结构”的课,这门课的目的是为了发掘更高的并行,从而制造出更快的CPU。那这一层是如何用数字电路提供的功能?举两个典型例子:一、CPU为了做计算会有ALU模块,而ALU模块正是一个组合电路(输入确定那么输出确定);二、在流水线寄存器中每一个时钟上升沿都会保存输入的值,在这个时钟周期内组合电路会根据这个新值计算出结果传输到下一级流水线寄存器的输入,等待下一个时钟上升沿的到来,这里的流水线寄存器正是某种锁存器的实现,而CPU开发者并不需要这个数字电路模块是怎么实现。

再往下一层,数字电路。这门课的目的是教学生如何利用基本的门电路(与非或门)来实现一些高级的功能(译码器、多路复用器、锁存器、时序电路……),然后给上层提供功能。上数字电路课是一个用砖搭房子的过程,由基本的门电路开始,慢慢构造出复杂的电路。数字电路不需要关心基本的门电路是如何实现的,因为这正是模拟电路向上层提供的功能。

再往下一层,模拟电路。这一层实现了与或非等基本门电路。比如非门、与非门、或非门都可以通过若干个p/n型MOS晶体管构成,而与门可以通过连接一个与非门和非门构成,或门可以通过连接一个或非门和非门构成。很多同学都觉得模电对于计算机的同学不必要学,而我认为相反,它是你构建整个计算机抽象层级的基石。

再往下一层,就不是计算机领域研究的事了。

当然,还有很多专业课我并没有提及,比如网络,它是OS提供的抽象之一,以文件的形式提供给用户使用;在网络协议栈实现的细节里,又分了好几层抽象,这就是我们熟知的OSI七层网络模型(有时候被抽象为五层:Application、Transport、Network、DataLink、Physical)。各位可以自己回忆一下大学里上过哪些专业课,以及它应该放在抽象的哪一层上。

脱离计算机领域,再往高一点看,会发现整个计算机领域好像就是在为别的领域提供功能、并隐藏了细节,如医疗、交通、餐饮、娱乐、安防等等领域都可以看到技术应用的例子。

作者:朱佳顺
链接:https://www.zhihu.com/question/19628851/answer/305960909

嘿嘿,所见即所得

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值