我是一个自学成才的程序员,以防万一CS 101中回答了这个问题。
似乎在遇到麻烦编程时,我总是碰壁。例如,我只是在另一个论坛上问了一个问题,该问题是如何处理函数返回的数组指针。最初,我以为我只是不了解C ++的设计人员为应对这种情况而设置的适当技术。但是,从随后的回答和讨论中,我发现当事情“归还”时,我并没有真正明白会发生什么。
一个好的程序员必须对编程过程有多深的理解?
我是一个自学成才的程序员,以防万一CS 101中回答了这个问题。
似乎在遇到麻烦编程时,我总是碰壁。例如,我只是在另一个论坛上问了一个问题,该问题是如何处理函数返回的数组指针。最初,我以为我只是不了解C ++的设计人员为应对这种情况而设置的适当技术。但是,从随后的回答和讨论中,我发现当事情“归还”时,我并没有真正明白会发生什么。
一个好的程序员必须对编程过程有多深的理解?
Answers:
否。没有人了解硬件方面的情况。
计算机系统就像洋葱一样-有很多层,每一层都取决于它下面的层作为支撑。如果您是在外层之一上工作的人,则不要太在意洋葱中间发生的事情。那是一件好事,因为洋葱的中间总是在变化。只要支持您的特定图层的一个或多个图层继续看起来相同并支持您的图层,就可以了。
但话又说回来...
是。我的意思是,您不需要了解洋葱内部的实际情况,但是对于典型洋葱内部的心理模型很有帮助。也许不是最深的部分,即由晶体管等构成的门,或者下一两层,即具有微码,时钟,指令解码单元等的下一层。不过,下一层是有寄存器,堆栈和堆。这些是最深的层,您会对发生的事情有很大的影响-编译器将您的代码转换为在此级别上运行的指令,如果您愿意,通常可以单步执行这些指令并找出“真正的”情况。
大多数经验丰富的程序员在脑海中都会略有童话般的层次。它们可以帮助您理解编译器在告诉您“无效的地址异常”或“堆栈溢出错误”之类的内容时在谈论什么。
如果您有兴趣,请阅读有关计算机体系结构的书。它甚至不必是一本特别的新书-长期以来,数字计算机一直以几乎相同的方式工作。您对洋葱的内部了解得越多,您就会惊讶于所有这些东西都起作用!学习(大约)底层的操作将使编程既不那么神秘,也更神奇。真的,更有趣。
您可能要注意的另一件事是嵌入洋葱。嗯,我的意思是嵌入式系统。有许多易于使用的嵌入式平台:Arduino和BASIC Stamp是两个示例。这些基本上是具有许多内置功能的小型微处理器。您可以将它们视为洋葱,其层数比典型的台式PC少,因此可以从硬件到软件,对整个系统中发生的事情有一个透彻的了解。
您不是在谈论硬件级别,而是在谈论编译器实际执行的功能以及您要执行的操作。
您最肯定需要具备一定的了解水平,以便找出在不明显的地方出了什么问题,尤其是在处理内存阻塞情况时。
如果您确实决定学习一些汇编程序,则可能应该在Commodore 64(当然是模拟的)上学习诸如6502汇编程序,或者在Amiga上学习诸如68000。
您可以在此处对Commodore 64有所了解...
这里描述的经典的一切您需要知道的书...
http://reprog.wordpress.com/2010/03/12/programming-books-part-3-programming-the-commodore-64/
如果环顾四周,您可能会找到PDF扫描。
IMO,6502比Z80更容易,而68000比8086更容易-更常规的指令集等。
但是CPU只是硬件的一个方面。而且,现代CPU是完全不同的野兽,即使从编译器的角度来看,它所做的事情也是透明的-例如提供虚拟地址空间。
C64上的6502的一个特殊优势是,不仅CPU简单,而且使用硬件也很容易破解。我以前在玩SID音乐芯片时玩得很开心。
所以-如果您不花太多时间在它上面,那可能是一个值得的练习。在Commodore Basic之后的14岁左右,我学习了6502汇编程序作为第二语言。但是大多数情况下,它都具有非常简单的工作模型,因此您可以在不引起任何误解的情况下向其添加更复杂的想法。
您可以在汇编程序中学习一些有用的东西...
我建议这样做的一个特殊原因是,可以更好地了解简单步骤完全确定性地,机械地,完全地在没有智能或常识的情况下进行操作的方式。基本上以最纯粹和最顽固的无知形式习惯了命令式执行模型。
但是,现在准确地了解大多数这些事情到底有多有用,这是一个难题。
您不会学到的一件事是如何在记忆层次结构中表现良好。那些旧机器大多具有简单的内存模型,没有缓存层,也没有虚拟内存。您也不会对并发学到很多东西-它们当然是处理并发的方法,但这主要意味着中断。您无需担心互斥锁等。
有时,关于这些东西曾经如何工作或汇编程序如何工作的思维模型甚至可能会产生误导。例如,将C指针视为地址可能导致未定义的行为问题。AC指针通常以包含地址的整数的形式实现,但不能保证绝对是正确的。例如,在某些奇怪的平台上,不同的指针可能指向不同的地址空间。当您想使用两个指针进行算术或按位逻辑时,这变得很重要。
除非您拥有这些离奇的平台之一,否则您可能不会认为自己在乎这一点-但如今的编译器越来越有可能利用未定义标准的行为来进行优化。
因此,系统体系结构的思维模型可能会有用,但是对语言规范进行编码仍然很重要,而不是对您的语言和平台可能不尊重的假设模型进行编码。
最后,从了解编译器如何生成代码的思想中获得了许多有用的思维模型知识-现代语言的代码生成与当时可用的相当琐碎的编译器有很大不同。
这是我最喜欢的一本书...
http://dickgrune.com/Books/MCD_1st_Edition/
除了有关解析和AST等内容外,它还涵盖了用于多种语言范例(命令式,OOP,功能,逻辑,并行和分布式)以及内存管理的代码生成。如果您想了解多态方法调用的工作原理而又不陷入CPU指令集的详细信息,那么像这样的书就是您的朋友-而且即将发布新版本。
二十年前,它很重要,但现在不那么重要-软件和现代硬件之间有更多的抽象层。
知道需要多个线程以利用多个内核或使用比系统上现有内存更多的内存是一件坏事,这很有用,但除此之外,除非编写这些抽象是您的工作,否则您实际上并不需要它。层。
您剩下的问题表明,您可能更关心编译器,而不是硬件,这有所不同。您可能会遇到很重要的情况,但是这些情况要么是琐碎的事情(无限递归不能很好地工作),要么是您可能会感觉很好解决但可能永远不会遇到相同问题的边缘情况再次。
它对了解和理解硬件提供的抽象有很多帮助,而对于如何创建这种幻觉也有一些一般性的想法-但要真正了解现代硬件的真正工作原理,您需要做大量的工作。很可能只会看到最小的回报。
如果您可以原谅小小的转移:这让我想起了几年前我注意到的事情。几十年前(直到1970年代末),大多数人认为计算机离魔术只有一步之遥-几乎不受物理定律的影响,能够处理几乎没有任何实际意义的各种事物,等等。当时,我花了很多时间(几乎没有成功)试图说服人们,他们不是魔术。它们确实是相当普通的机器,可以非常快速,可靠地完成有限的工作,但在其他方面却非常平凡。
如今,大多数人对计算机的看法已经改变。现在他们已经很普通了,以至于很多非常普通的人对它们有了实际的了解。举例来说,前几天我吃晚饭时,我看到/听到一个侍应生在休息时讨论她应该在新计算机上得到什么。他给出的建议是完全合理和现实的。
我对计算机的看法也发生了变化。我去过热门芯片,在那之前的微处理器论坛可以追溯到1990年代中期。我大概知道更多关于微处理器硬件比程序员的至少99% -而且知道我做什么,我会说:他们是不平凡了。他们也险些破门物理定律。我已经做了很多低级测试,我可以肯定地说一遍:超越CPU产生的幻觉,进入展示硬件真正工作方式的层次通常非常困难。我希望我可以用不低于4个逻辑分析仪将计算机埋在电缆下面的方式发布其中一种设置的图片,以正确地测量一个 高速缓存在现代CPU上如何工作的一个方面(更不用说一些真正的精挑细选的程序设计,以确保我们测量的内容恰好是CPU在做什么,而没有其他内容)。
不同的语言在不同的硬件抽象层次上工作。C和C ++是非常底层的。另一方面,脚本语言要求您对底层细节了解较少。
但是,我仍然要说,在所有情况下,您了解的越多,您将成为一名更好的程序员。编程的一部分是能够同时兼顾多个抽象级别。
如果您使用C ++进行编程,则至少在编译器的工作抽象水平上,您需要对现代CPU的工作方式有很好的了解。(CPU内部也发生了一些对编译器透明的事情)。
我想谈一谈有关C之类的高级语言的总体设计。
总的来说,我认为可以肯定地说这样的语言可以看作是实现一种抽象机器,确实,这就是Dennis Ritchie自己描述C的方式以及C的抽象机的特殊设计如何使其成为更具移植性的语言。这样,对计算机体系结构和机器级别的功能有所了解,对于理解语言的抽象机器也将非常有帮助。
我记得DMR的论文《 C程序和UNIX系统的可移植性》是讨论C语言(抽象)机器模型的第一篇。
我认为DMR关于C的历史和发展的论文在显示真实硬件如何影响语言设计方面也非常有用,并且也许也是早期编程语言设计的典范: C语言的发展