低级很容易(2008)

2021-07-29 22:04:26

我以前的条目有一个非常有趣的标题“写博客很难”。哎呀,真是个笨蛋,偶尔路过的人说。必须修复我的形象,快。想,想,想!好的,这就是我要告诉你的:低级编程很容易。与高级编程相比,就是这样。我是认真的。首先,这里有一个关于一位了不起的开发人员的故事,他暂时将重命名为无名。看,我认识这个了不起的开发人员。现在适用于谷歌。他拥有大约 5 年的客户端 Web 编程经验。并且“永远不再”这个词纹在他的全身(在比喻意义上;我想;我还没有真正检查过)。有一次,我决定我必须了解这项永不复存在的业务。 “了不起的开发人员”,我说,“你为什么要退出令人兴奋的 Web 前端世界?” “我不喜欢它”,神奇的开发者说。 “但是,但是!The Second Dot Com Bubble 怎么样?风投基金会恳求你拿出 100 万美元来开发下一个 Arsebook 或者其他什么。你不想变得富有吗?” “我真的不太喜欢网络前端”,他一直坚持。这不奇怪吗?你怎么解释?我只是一直问。现在想起来,他大概是有些恼火了。 “听着,伙计”,他说(在比喻意义上;他实际上并没有那样说;他很有礼貌)。 “我有驾驶 5 吨卡车的执照。但我不想从事卡车驾驶的职业。希望这能澄清事情”。他还说了一些关于普通卡车司机比典型的 Web 开发人员更重要的事情,但我不记得确切的侮辱。现在,过去 4 年我一直在使用裸机硬件。没有操作系统,没有驱动程序,什么都没有。相比之下,在恶劣的硬件环境中。例如,在多核台式机中,当您修改缓存变量时,其他处理器的缓存会看到更新。在我们的芯片中?忘了它。在这些市场中,内存一致性的自动硬件级维护是非常新鲜的消息。当你改变一个变量然后另一个处理器决定写回它过时的缓存行时,它会很糟糕,覆盖你的更新。它完全糟透了。一个相关的数据点:我天生爱抱怨。呜呜呜呜呜。您可能是通过 C++ FQA 找到此博客的,因此您已经了解我的所有抱怨。而且我也不是没有被低级错误烧死。哦,我有那个。就在截止日期之前。周末的乐趣。那么我怎么不尖叫着大喊大叫地逃离这些东西呢?哎呀,我不介意在我剩余的职业生涯中处理裸机。好吧,尝试其他东西可能会更有趣一些,但裸机胜过卡车驾驶,我可以告诉你。公平地说,我不能确定最后一点——我不会开车。在所有。也许这可以解释一切?我会告诉你我是如何真正解释这一切的。不,下一句不对;有一卡车的原因(大约 5 吨),所以可能需要一些段落。系好安全带。 “高水平”基本上是什么意思?你的级别越高,你下面的级别就越多。这一点都不重要:在你的级别,你有一套方法来操纵现有的低级别环境,你可以在此基础上构建你的东西​​。谁在乎下面的级别数?重要的是,我如何轻松地构建我的新东西?如果我弄乱了易失性指针和硬件寄存器,并在最轻微的错误时覆盖了整个宇宙的一半,那就太糟糕了。如果我可以使用单个函数弹出一个窗口,那就是我喜欢的方式。对?嗯,大致是这样,但是有问题。

问题1:你下面的东西在更高的层次上是巨大的。在我看来,HTML、CSS、JavaScript、XML 和 DOM 是很多东西。很多规格页面。 CPU 稍微小一些。您拥有运行 C 所需的汇编命令(加/乘、加载/存储、分支)。您拥有运行某种操作系统所需的汇编命令(移入/移出系统协处理器寄存器;我不知道,如今每个中端 RISC 内核有数十种口味?)。并且你有中断处理规则(把reset handler放在这里,把data abort handler放在这里,这样就可以得到导致异常的地址)。就这样。我将大部分 ARM946E-S 的感觉保留在我的脑海中;仍然在我大脑之外的东西可能永远不会妨碍我。这并不是一个特别令人印象深刻的结果。例如,坐在我旁边的那个人可以打败我(“身体和智力”,正如穆罕默德·阿里所说的那样;在他的例子中,后者是一个严重的夸张——他被发现对美国军队来说太愚蠢了,但我离题)。无论如何,我旁边的这个人的头骨下有一个 MIPS 34Kf,他看起来很开心。这比ARM9要复杂一些。早在富客户端时代,我就开发了相当多的基于 MFC 的 GUI(ewww);在任何时候我都不想将大部分 MFC 或 COM 或 Win32 留在我的脑海中。我怀疑它是否适合。问题2:你下面的东西坏了。我见过硬件错误;每 100 个低级软件错误和每 10000 个高级软件错误 1 ​​个。我认为。我觉得。我没算。但无论如何,你可能相信我。与最终用户应用程序相比,与操作系统相比,您在硬件方面遇到了多少问题?根据我得到的大多数证据,JavaScript 在每个浏览器上都可以随心所欲。硬件不是这样的。同一品种的 CPU 将运行相同的用户级指令或退出市场。遵循与总线通信的硬件协议的内存映射设备实际上会遵循它,该死的,或者退出市场。低级别的事情可能会正常工作,因为他们这样做有巨大的压力。因为不然的话,所有更高层次的东西都会崩溃,所有人都会“啊啊啊啊啊啊!!”更高层次的东西承载的重量更小。好的,因此这次浏览器更新(或对浏览器或金字塔的任何其他部分使用的系统库的更新)破坏了五个 Web 应用程序。如果您的 Web 应用程序损坏,最好的办法是修复它,而不是等到问题在以下级别得到解决。你的等级越高,你就越孤独。您不仅依赖于更多可以破坏的东西,而且在每个特定情况下关心的人也更少。问题 3:您很少可以修复低于您级别的损坏的东西。通常你没有来源。哦,浏览器是开源的?快乐,快乐,快乐,快乐!您实际上可以深入研究庞大的代码库(在您至少知道词汇表的正常抽象级别下工作),修复错误并......希望每个人都能尽快升级。这总是一个明智的选择吗?你可以拥有开源硬件,你知道的。硬件是用符号语言编写的,具有结构化的流程和一切。唯一的问题是,家里的人无法重新编译他们的 CPU。生命周期。这都是关于生命周期的。你的更高级别的东西现在想要在野外生活,而所有其他的点点滴滴都按照自己的时间表生活。您最终会解决该错误。有时会阻止较低级别的组件作者修复错误,因为这会破坏您和其他人的解决方法。哎呀。您的解决方法有多复杂?复杂性也随着您的抽象级别而增加。那是因为更高级别的组件处理更复杂的输入。好的解决方法本质上是避免输入破坏错误实现的方法。糟糕的解决方法是提供输入的方法,这些输入不应导致正确的行为,但会导致错误的实现。好的变通方法比坏的变通方法要好,因为当修复实施时,坏的变通方法会中断。但无论哪种方式,您都必须限制或转换输入。原始输入集比复杂的输入集更容易约束或转换。因此,低级错误更容易解决。 QED。低级:“不要连续写入该寄存器两次;在写入之间发出读取”。 * Grump* 愚蠢的硬件。 OK完成。下一个。

高级:“不要做某事,嗯,该死,我不知道到底是什么,嗯,交互式 OLE 矩形跟踪器的东西;他们会重新绘制有趣的东西”。我曾经开发过一个用于编辑表单的应用程序,很像 Visual Studio 6 资源编辑器。在我的最终版本中,RectTracker 会重新绘制有趣的东西,就像它在 Visual Studio 6 中的类似情况一样。我想我了解当时的确切情况,但还没有想出合理的方法来避免它们。显然,在 Microsoft 的那个抽象层工作的人也无法弄清楚。那是什么?微软的软件总是垃圾?你是个白痴,认为一切都是微不足道的,因为你一生都没有做过任何有价值的事情。下一个。问题4:在更高的层次上,你甚至无法理解发生了什么。使用裸机机器,您只需在物理上停止处理器(不运行),然后读取您想要的每一位内存。所有数据都由一个程序管理,因此您可以显示每个变量并查看每个函数的源代码。高级调试乐趣的终极例子是一个大的、缓慢的、毛茸茸的 shell 脚本。 “rm:不匹配。”这到底是谁说的,我该怎么知道?下面可能是十个子壳。它甚至重要吗?那么如果我无法删除某些文件怎么办?等等,但为什么他们失踪了——有人认为他们应该在那里?可能基于这样的假设,即程序应该先前已生成它们,因此该程序已损坏。哪个程序?啊啊啊!!好的,所以 shell 脚本并不是高级语言的最佳示例。或者你认为他们是;玩得开心。我不在乎。我也有过语言战争。这与语言无关。我想继续下一个例子。没有 shell 脚本。您在 Windows(无源代码)下的 Firefox(用语言 4 编写)下的 HTML/CSS(语言 2 和 3)中运行 JavaScript(语言 1),与用 PHP(语言 5,一个很好的)编写的服务器交谈Linux(是的源代码,但无法对内核进行符号调试)。我认为它使调试过程有些复杂;肯定没有一个调试器能够理解这一点。问题 5:随着你爬得更高,选择的数量呈指数增长。一棵树只有一个根,上面有几根粗枝,顶部有数千片叶子。弯曲根,树倒下。但是叶子,它们可以朝任何他们喜欢的方向生长。链接器是如此的低级以至于它们实际上是可移植的,而且它们都是相似的。当你游那么低时,你能想出什么?你的输出是一个内存映射。一堆片段。基数,大小,位,基数,大小,位。有点限制了你的创造力。图形用户界面工具包?下一个当然比第一个更容易掌握,但它们确实不同。你用什么格式来指定布局,哪一部分是数据驱动的,哪一部分拼写为代码?您如何处理 GUI 在远程机器上运行的情况?哪些 UI 组件是内置的?你有一个带有单元格连接和东西的表格控件还是一个列表控件?您的编辑框是否检查拼写?如何?我想用我自己的字典!可以覆盖现有控件行为的哪些部分以及如何覆盖?你是在每个主机上使用原生小部件,让切换平台的用户感到惊讶,还是推出自己的小部件,让不使用的用户感到惊讶? HTML 和 Qt 本质上都是 UI 平台。对我来说算作“足够不同”。不可避免地,在选择错误的方法后,您会发现两者都有不同的糟糕方式(好吧,从一开始就很明显这两个方法很明显;Qt 和 gtk 可能是一个更好的例子)。跨他们移植?哈。根本问题是,对于许多较低级别的问题,都有正确的答案(IEEE 浮点数)。有时,错误答案会获得一些市场份额,而您必须忍受它(大端;最近失去了一些市场份额)。对于更高层次的事物,几乎不可能定义哪个答案是正确的。这与破解您自己的不兼容的更高级别的噩梦的容易程度严重相互作用。这让我们……

问题6:大家都认为high-level很容易,理由是它明显更快。与较低级别的功能相比,您肯定可以在给定的时间段内开发更多的高级功能。所以呢?你可以开车比走路快。但开车并不容易;每个人都可以走路,但要开车,你需要有执照。也许这就是 Awesome (Ex-Web) Developer 提到的事情:至少卡车司机有执照。但我不确定这是他说的。我会告诉你我所知道的:我尝试的每一秒 WordPress 主题都被打破了,以三种方式之一:(1) PHP 错误,(2) SQL 错误和 (3) 指向的链接缺页。 WordPress 主题是用 CSS 和 PHP 编写的。每个白痴都能学会 CSS 和 PHP;显然,每个白痴都捡到了它们。难道他们不能至少对他们中的一些人保密吗?哇哦!快速的 5 吨卡车直接驶入树中。漂亮的高级树叶纷纷落下,在夕阳的柔光下覆盖着司机流血的尸体。不要让我开始了解 WordPress 条目编辑窗口。现在,虽然每个白痴都在尝试使用高级编码来碰运气,但并不是每个人都在进行高级编码……您明白了。另一种说法是不正确的。事实上,这个条目是关于另一个声明是如何不正确的。有很多才华横溢的人在研究高级别的东西。问题是,他们并不孤单。您的抽象级别越高,您遇到的平均代码片段的质量就越低。因为通过复制和粘贴方法很容易破解,所以它有点工作,如果没有,它似乎可以,平均而言,如果它破坏了你的东西,很可能是你的问题,记得吗?问题 7:不仅仅是开发人员认为它非常简单。每个最终用户都认为他确切地知道您需要哪些功能。每个经理也这么认为。有时他们不同意,不,经理并不总是认为“客户永远是对的”。但那是另一回事。这里的重点是,当你做一些“简单”的事情时,太多人会告诉你它有多糟糕,你只能忍受它(当然有 1 亿用户可以安慰你,但这又是另一回事,而且有时您不能指望这一点)。我维护低级代码,人们对它很满意。有时我认为它有一些糟糕的地方,这会妨碍你。在这些情况下,我实际上必须说服人们应该改变这些东西,因为每个人都害怕在那个级别破坏某些东西。该死,即使是错误修复也被视为您所做的好事,就好像您不应该修复该死的错误一样。低级令人生畏。位!注册!十六进制!帮助!!有些人滥用他们的手艺并积极恐吓他人。我不是说你应该这样做;事实上,这个条目是关于你不应该这样做的。这样做的人都是混蛋。我认识这样一个开发者;我称他为混蛋。有一天我可能会发布 The Bastard 的冒险经历,但我需要仔细考虑这一点。我很确定如果有人在公开可用的页面上认出他,Awesome Developer 不会介意,但由于某种原因,我不太确定 The Bastard。我要说的是,维护高级代码极其困难。做出改变很容易;在不破坏任何东西的情况下做对不是。您可以立即驶入一棵树。高级代码有无数的需求,随着时间的推移,其中许多是隐含的和未记录的,甚至没有人记得它们的可能性越来越大。人们不明白。这是一个很大的社会问题。作为一名低级程序员,你必须说服人们在给他们一些东西时不要害怕。作为一名高级程序员,你必须说服他们,你不能只是给他们越来越多、越来越多。猜猜哪个更容易。这就像付款,这总是比获得付款更麻烦。即使您与一个大型的、相互尊重的组织打交道。吞咽比随地吐痰容易,即使对于有礼貌的组织也是如此。哎呀,里面有一个意想不到的含义。他妈的。我不是在编辑这个。我想解决这个问题。让我们向前推进。最搞笑的神话是“软件很容易修复”;当然它指的是应用软件,而不是“系统”软件。曾经收到过在一行开头带有“> From”的电子邮件吗?我偶尔会得到那些。最初,该行表示“发件人”,然后被 sendmail 或后代引用。这个错误已经存在了几十年。原来运行 sendmail 的硬件已经死了。而且那个硬件没有错误。当前运行 sendmail 的硬件也没有错误。这些错误在测试阶段的某个地方得到了修复。应用软件永远不会像硬件一样被测试。我知道,因为我花了大约 9 个月,也就是 2007 年的大部分时间,编写硬件测试。几乎没有特征;测试,专门。而我只是少数进行测试的人之一。你看,你无法修复硬件错误;它至少会花费你 100 万美元。结果是您在制造之前测试了硬件模型,并且您确实修复了错误。但是对于软件,您以后可以随时更改它,因此您无需进行测试。在硬件方面,最优秀的软件所经历的测试将被称为“无测试”。然后已经有一个庞大的安装基础,加上人们编写的快速而肮脏的邮箱解析脚本,所有这些邮箱都散落一地,如果不保持错误兼容性,就无法理解它们(该术语属于我的,谁 - 猜猜看 - 维护高级代码库)。所以你永远不会修复错误。并且大多数更高级别的代码是可移植的;它的错误可以永远存在。

还有最后期限。您可以发布的软件版本数量。 1.0、1.1、1.1.7、1.1.7.3……你的抽象级别越高,他们想要的改变就越多,你最终会得到的中间版本和分支也就越多。然后你必须支持他们所有人。也许他们必须能够读取彼此的数据文件。也许他们需要加载彼此的模块。而且他们是高级别的。每个下面都有很多东西,其中有很多功能。大量的模块和数据文件。许多开发人员,其中一些人不经意地添加了变得重要且必须支持的功能。该死的......我敢打赌,你现在确信“低级”与“更容易”相关。除非你累了搬到别处,在这种情况下,我什至不和你说话。 QED。我同意你在这里所说的大部分内容,但我不明白你(我指的是低级别开发人员)如何不受高级别 - 低级别责任链的影响。例如,如果您是 GPU 的设备驱动程序编写者,并且您仍然可以弄乱一些管道代码并让其他人依赖您的错误代码,您必须永远维护这些代码,因为下一个大型游戏会拉皮条你的 GPU 而大老板不能不在乎。诚然,这个级别仍然高于机器级别,但我假设低级别>机器级别。 – Re: C++ FQA – 我同意 99.9% 我......