有哪些具体例子可以说明了解 C 语言可以让您成为更好的高级程序员?

StackOverflow https://stackoverflow.com/questions/2077913

  •  21-09-2019
  •  | 
  •  

我知道诸如此类的问题的存在 这个这个. 。让我解释。

Afet 阅读 Joel 的文章 回归本源 看到很多类似的问题,我开始想知道了解 C 之类的东西可以让你成为一个更好的高级程序员,有哪些具体的例子。

我想知道是否有很多这样的例子。很多时候,这个问题的答案是这样的:“了解 C 可以让您更好地了解幕后发生的事情“ 或者 ”您的计划需要坚实的基础”,而这些答案并没有多大意义。我想了解您将从了解低级概念中受益的不同具体方式,

乔尔举了几个例子:二进制数据库与 XML 和字符串。但两个例子并不能真正证明学习 C 和/或汇编的合理性。所以我的问题是这样的: 有哪些具体例子可以说明了解 C 语言可以让您成为更好的高级程序员?

有帮助吗?

解决方案

我的带教的学生和与人谁只研究高级语言的工作是,他们往往认为在一定的高度抽象的,他们认为“一切都免费”体验。他们可能会变得非常称职的程序员,但他们最终不得不面对有性能问题的一些代码,然后说到咬他们。

当你工作了很多与C,你想想内存分配。你经常想想内存布局(与高速缓存位置,如果这是一个问题)。你了解如何以及为什么某些图形操作只花费了很多。效率如何某些插座行为是。缓冲区是如何工作的,等等。我觉得思考的性能时使用高级语言的抽象,当你知道它是怎么盖下面实施有时为您提供“额外的秘密武器”。

例如,Java有一个垃圾收集器和你不能直接直接分配的东西到存储器。然而,你可以使某些设计选择(例如,使用自定义的数据结构)影响的,因为同样的原因,表现,这将是C的一个问题。

此外,更一般地,我觉得这是一个权力程序员不仅知道大O记法(其中大部分学校教)很重要,但是,在现实生活中的应用不断的也很重要(这所学校尝试忽视)。我的经验看人们在这两种语言水平的技能往往有更好的理解不变的,什么上述我,也许是因为。

此外,我所看到的界面与较低级别的库和基础设施许多较高级别的系统。例如,一些通信,数据库或图形库。有些驾驶员为了某些设备等。如果你是一个程序员的功率,则可能eventially不得不冒险在那里,它有助于至少有发生了什么事的想法。

其他提示

知道低层次的东西可以有很大的帮助。

要成为一名赛车手,你必须学习和了解的基本物理如何轮胎抓地力的道路。任何人都可以学开车相当快,但你需要的“低水平”的东西(力和摩擦,赛车线,细油门和刹车控制等)有很好的理解,以获得性能的最后几个百分点,这将让你赢得比赛。

例如,如果你理解了CPU架构在你的电脑是如何工作的,你可以写的作品与它(更好的代码,例如,如果你知道你有一定的CPU缓存的大小或每CPU缓存行一定数量的字节,你可以安排你的数据结构和访问他们做出缓存的最佳使用方式 - 例如,为了处理一个数组的许多元素往往比处理随机元素更快,由于CPU高速缓存)。如果你有一个多核心计算机,然后了解如何低水平的技术,如线程的工作可以得到巨大的好处(就像不理解水平低会导致灾难的线程)。

如果您了解磁盘I / O和缓存的作品,你可以修改文件操作,如果你从一个文件中读取和写入到另一个,在RAM中的数据的大批量工作可以帮助减少我与它(例如很好地工作/ O代码的读取和写入阶段之间的争用,和大大提高吞吐量)

如果您了解虚函数是如何工作的,你可以设计一个使用虚拟功能的高级代码以及的。如果使用不当,它们可严重妨碍的性能。

如果您了解绘图是如何处理的,你可以用聪明的技巧,以提高绘图速度。例如您可以通过交替绘制64个白色和黑色方块画一个棋盘。但它往往是更快地得出32个白色sqares然后32黑色的(因为你只需要改变绘图颜色而不是两次64倍)。但实际上你可以画出整板黑色,然后全线XOR 4条和第4条在案板上的白色,这样就可以更快还是(2度色的变化,只有9矩形画,而不是64)。这棋盘招教你一个很重要的编程技巧:横向思维。通过设计算法好,你经常可以有很大的不同有多好你的程序操作。

了解C,或者就此而言,任何低级语言,给你一个机会去了解的东西,如内存使用率(即为什么是一件坏事创造数百万重物),指针/对象引用是如何工作的,等

的问题是,因为我们已经创建了不断增加的抽象层次,我们发现我们做了很多的“乐高块”的节目,而无需了解积木如何实际运作。并且通过具有几乎是无限的资源,我们开始治疗记忆和资源如水,并且倾向于通过在情况投掷更多的铁来解决问题。

尽管不限于C,有在低级别与像Arduino的或老学校的8位处理器小得多,存储器受限系统工作一个巨大的利益。它可以让你体验到接近金属编码以更加平易近人的包,花时间挤应用到512K之后,你会发现自己在您的日常节目中的较大级别应用这些技能。

所以语言本身并不重要,但有如何的所有位的走到一起,如何在一定的水平更接近硬件的有效工作更深层次的欣赏是一组技能,任何软件开发者有益。

有关,能知道C有助于你理解记忆在OS和其他高级语言是如何工作的。当你的C#或内存使用Java程序的气球,理解是引用(这基本上只是指针)取内存过,并了解有多少数据结构的实现(你从制作自己用C获得),帮助您了解你的字典保留大量内存未实际使用。

有关其他,知道C能帮助您了解如何利用较低级别的操作系统功能。你不需要经常这样,但有时你可能需要内存映射文件,或在C#中使用编组,和C将大大有助于理解这种情况发生时,你在做什么。

我认为C也有助于我的网络协议的理解,但我不能把我的手指上的具体例子。我读另一SO质疑一天如果有人抱怨关于C的位字段如何“基本没用”,我想C位字段如何优雅地代表低级网络协议。高水平的处理比特最终总是乱七八糟的结构语言!

在一般情况下,你知道的越多,更好的程序员,你会。

不过,有时明知另一种语言,如C,可以让你做错误的事情,因为有可能是一个假设,是不是在一个更高层次的语言(如Python或PHP)真。例如,人们可能会认为找到一个列表的长度可能是O(N),其中N是该列表的长度。然而,这可能不是在许多高级语言实例的情况。在Python,对于大多数列表类似的东西的成本是O(1)。

了解更多关于语言会帮助的细节,但我们知道更一般可能导致一个做出不正确的假设。

只是 “知道” C不会让你更好的。

但是,如果你了解整个事情,双星如何本地工作,如何做它CPU的工作,什么是架构的限制,你可能会写代码,这对于CPU更容易。

例如,L1 / L2缓存是如何影响你的工作,你应该如何编写代码来在L1 / L2缓存更多的点击。当使用C / C ++的工作和做重的优化,你将不得不下降到那种东西。

据与其说知道C作为它是,C是比许多其他语言更靠近裸露的金属。您需要更多地了解如何,因为你必须做你自己分配/释放内存。自己做它可以帮助你了解你做许多决策的影响。

要我的任何语言,只要你知道如何编译器/解释器(基本)代码映射到机器上是可以接受的。这是一个有点更容易直接公开这个语言的事,但你应该能够,有一点阅读,找出内存是如何分配的,有组织,有什么样的索引模式比其他人更优化,结构是什么用于特定应用的更有效的,等等。

更重要的是,我认为,是操作系统,存储器架构和算法的一个很好的理解。如果你了解你的算法是如何工作的,为什么它会是更好的选择一个算法或数据结构对另一个(例如,HashSet的对比列表),以及如何你的代码映射到机器上,它不应该不管你使用的是什么语言

这是我学习和自学编程的经验,特别是理解 C,这可以追溯到 1990 年代初,所以可能有点过时,但热情和动力很重要:

  • 学习了解计算机的底层原理,比如EGA/VGA编程,这里有一个 关联 到 PC 上的 C 程序员指南上的 Simtel 存档。
  • 了解 TSR 的工作原理
  • 下载整个档案 鲍勃·斯托特的片段 这是一个 C 代码的大集合,只做一件事 - 研究它们并理解它,不仅如此,代码片段的集合力求可移植。
  • 浏览国际混淆 C 代码竞赛 (国际奥委会)在线,了解 C 代码如何被滥用并了解该语言的内在本质。最严重的代码滥用就是胜利者!下载档案并研究它们。
  • 像我自己一样,我喜欢臭名昭著的 Ponzo's C 教程,它对我帮助很大,不幸的是,档案很难找到。如果有人知道在哪里可以获得它们,请发表评论,我将修改此答案以包含链接。我还记得另一本 - Coronado 的 [通用?] C 教程,同样,我对此的记忆很模糊......
  • 看看博士。Dobb 的日志和 C 用户日志 这里 - 我不知道你是否还能得到它们的印刷版,但它们是经典,记得手里拿着印刷版并撕下回家输入代码看看会发生什么的感觉!
  • 获取一份古老的副本 涡轮C v2 我相信你可以从 borland.com 获得它,然后玩一下 16 位 C 编程来感受一下并弄乱指针……当然它很古老,但玩指针是没问题的。
  • 理解和学习指针、链接 这里 到遗产 Simtel.net - 获得 C Guru 地位的关键链接,因为需要一个更好的词,您还会发现大量与 C 编程语言相关的下载 - 我记得实际上订购了 Simtel CD Archive 并寻找 C 的东西......

一对夫妇的,你必须直接在C处理的事情,其他语言的抽象离你有明确的内存管理(malloc),并直接与指针处理。

我的女友是从麻省理工学院毕业与计算机科学学位(其中他们主要使用Java,计划和Python)一个学期,她目前在其代码库是C ++的公司工作。对于前几天她有困难的时候认识所有的指针/引用的/ etc。

在另一方面,我发现由C ++移动到Java很容易,因为我是从来没有感到困惑通引用按值VS通按引用。

类似地,在C / C ++它是更显而易见的是,原语只是编译器处理所述同一组以不同的方式位的,而不是像Python或Ruby语言的一切是与它自己的独特的属性的对象。

一个简单的(不完全现实的)的例子来说明上面的一些建议。考虑看似无害

while(true)
   for(Iterator iter = foo.iterator(); iter.hasNext();)
       bar.doSomething( iter.next() )

或甚至更高水平

while(true)
    for(Baz b: foo)
        bar.doSomething(b)

这里的一个可能的问题是,每一次轮的循环的新对象(迭代)被创建。如果所有你关心的是程序员的方便,那么后者肯定是更好了。但是,如果循环必须是高效或设备处于资源受限,那么你在你的高级语言的设计师摆布漂亮多了。

例如,这样做高性能的Java由具有执行停止,同时垃圾(如所有那些分配迭代的对象)的典型投诉被回收。不太好,如果你的软件被指控跟踪来袭导弹,自动驾驶喷气式客机,或者只是没有留给用户想知道为什么GUI已停止响应。

一种可能的溶液(在更高级别的语言静止)。将削弱迭代器的东西的便利性等

Iterator iter = new Iterator();
while(true)
    for(foo.initAlreadyAllocatedIterator(iter); iter.hasNext();)
       bar.doSomething(iter.next())

但这样做才有意义,如果你有关于内存分配的一些想法......否则它只是看起来像一个讨厌的API。便利始终成本的地方,知道低层次的东西可以帮助你发现和减少这些成本。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top