IDE 的诅咒 警告 强力工具的黑暗面 程序员的强力工具 文本编辑器 编码 老式调试 命令行 编译 重新引入 IDE

2025-06-04

IDE 的诅咒

警告

电动工具的阴暗面

程序员的强大工具

文本编辑器编码

老式调试

命令行编译

重新引入 IDE

每当有人以“这是一个新时代……”开头,你就应该提高警惕。现代社会带来了一系列令人难以置信的科技进步,但坦白地说,这句谚语仍然适用:事物变化越大,保持不变的就越多。

很少有哪个领域像编程领域一样,如此受时代思潮的左右。我们往往只看流行度来选择技术,并盲目追随设计模式,最终损害了自身利益。我们会进行一些荒谬的讨论,比如“X 语言是否正在消亡”,并不断争论任何我们认为“过时”的东西是否仍然适用

因此,流行的编程趋势要求我们放弃一半的历史工具箱,这应该不足为奇,我认为这对我们的伤害比我们所知道的要大。

警告

现在,在我们进一步讨论之前,我要求您不要将此作为真正的程序员使用 Emacs、Vim、Nano 或 Butterfly 的证据……

XKCD:真正的程序员

集成开发环境(IDE)——对于我们这些痴迷于缩写的人来说——绝对是不可思议的工具。我甚至可以说,它们几乎是所有现代程序员工具箱里必不可少的工具。如果你还没有找到一个,那你真的需要找一个了,尤其是现在市面上有数百个IDE可供选择:Visual Studio Code、Atom、Brackets、Eclipse、Emacs,以及Jetbrains的任何IDE……

更进一步说,我实际上想说,绝对没有理由不定期学习和使用至少一个 IDE,尤其是在编写生产代码时。即使是最笨重的、只支持终端的“恐龙”也能运行 Emacs。如果我听说有人发布新的生产代码,而没有可用的 IDE,只用记事本编写,我一定会亲自用他们的源代码狠狠地打他们一顿。

现在,这个问题已经解决了……

电动工具的阴暗面

如果你做过木工活,你就知道电钻和电锯能省下多少时间。如果专业的承包商团队有这些工具却不用,那真是太荒唐了。

然而,同样的承包商团队几乎肯定能够在没有电动工具的情况下完成同样的工作。事实上,我敢保证他们的工具箱里一定有手锯、夹具、螺丝刀、锤子、砂纸、卷尺和水平仪。有人可能会想,这有什么意义呢?如果用自动工具能更快地完成,为什么还要携带这些手动工具呢?

据我所知有两个非常好的理由:

  1. 电动工具失灵了!您可能无法获得所需的电源,或者处于不安全使用工具的环境中(例如在雨中)。在少数情况下,需要手动工具,但这种情况非常常见。

  2. 在某些情况下,手动工具实际上更容易操作!某些电动工具很难完成精密工作。电动工具的实用性——动力——有时反而会让工作变得更加困难。手动工具的控制更精细。

然而,除了这些问题之外,还有一个更深层次的问题:有效使用手动和自动工具需要相同的技能。当然,一个完全不懂如何使用螺丝刀的人可能看起来精通钻头,但他们的技术最终很可能会导致更多的螺丝滑丝。不会使用手锯的人可能会轻松使用电锯台,但他们缺乏精准切割的经验,会犯更多的错误。电动工具会让你更快地犯下更大的错误。

每个木匠都必须能够以同样的方式测量、观察、选择工具并控制这些工具。使用手动工具的过程速度较慢,更注重手工操作,这可以培养这些本能。一旦熟练掌握,就能充分利用电动工具,将工具的便利性与工人的本能相结合,从而快速、高效、准确地完成工作。电动工具可以提高速度和准确性,但无法弥补工人能力的不足。

程序员的强大工具

很多人惊讶地发现,我竟然在近十年的时间里完全忽略了智能感知和自动完成功能。我学会了用一些恰当的打印语句就能像使用调试器一样快速有效地进行调试。事实上,我甚至在命令行中编写并编译了练习代码!

这一切听起来可能像是我的努力白费了。毕竟,智能感知、调试器和功能齐全的编辑器都是必不可少的工具!我为什么不好好利用它们呢?

事实上,我知道我只需几分钟就能学会使用这些工具。它们唾手可得,总有一天我会选择经常使用它们。这些都是我们工具包里的强大工具,它们都完美地集成在 IDE 中,并附带了数十种其他实用功能。事实上,这一天已经到来:我几乎从不离开自己选择的 IDE 来编写 C++、Python、HTML 或 CSS。

然而,我早年决定放弃那些强大的工具,却收获了难得的成果。我可以用文本编辑器编写一段相当复杂的代码,而且一次或第二次就能运行,几乎没有逻辑错误(如果有的话)。加上 IDE 的便利,我经常可以编写出一整个类,而且第一次就能运行。

在培训年轻程序员的过程中,我发现他们早期对IDE的依赖剥夺了他们很多这样的技能,导致他们编写的代码在最初的六次尝试中很少稳定、简洁或高效。如果他们继续这样下去,他们的成长就会受到阻碍。

有些基本技能只有在不使用 IDE 的情况下编写代码才能获得和完善!这并不意味着我们每天都不使用 IDE,而是意味着刻意磨练这项技能可以让我们最大限度地高效地使用 IDE。

文本编辑器编码

我希望每个程序员在职业生涯的某个阶段,都能用记事本编写一整套编程挑战解决方案,并且还要确保它一次就能编译通过。没有语法高亮,没有智能感知,只有编辑器和语言文档。

这项训练包含以下几种技能:

理解语法

你必须记住你所用语言的主要语法规则;这反过来又要求你理解这些规则的“为什么”。无论使用哪种语言,了解“为什么”总能写出更好的代码。

你当然可以每次都去查阅样板代码和语法,但迟早,这种纯粹的不便会让你明白“嘿”int main(int argc, char* argv) { //... }到底是什么意思!一旦你明白了,你就可以真正地利用它。模式和解决方案会自然而然地呈现在你面前。语言行为会成为你本能的一部分。

发现错误

你训练自己的眼睛识别拼写错误,包括那些语法高亮和 linter 通常能帮你指出的错误。之后,这些工具会减轻你编辑工作的大部分负担,让你有更多时间去发现那些 IDE 漏掉的棘手错误!

几年前,我使用 ActionScript 3.0 时——我从未学过如何在没有 IDE 的情况下编写这种语言——我忘了​​一个循环中的分号,结果在代码库中一个特别棘手的地方创建了一个无限循环。我花了两个星期才找到它!相比之下,经过多年不使用 Intellisense 和 linters 编写 C++ 的经验,我只需几分钟就能找到相同类型的循环错误。

键入样式

杂乱的代码是无法维护的,但 IDE 的代码格式化程序常常让我们对空格和括号感到沾沾自喜。懒惰的危害非常大,习惯性地不正确地缩进很快就会导致函数名拼写错误。(这远非理论上的——在近十年的程序员指导经验中,我观察到这两种懒惰习惯的结合。)

剥离代码格式化程序后,我们被迫承担自身草率的直接后果。我们不得不忍受一遍遍令人眼花缭乱地重读代码,直到被迫重构代码风格才能使其更易于阅读。我们学会了以干净、风格良好的源代码为荣。

当 IDE 重新引入时,它只是帮我们省去了额外的按键操作,比如正确的缩进和括号。代码格式化程序变成了一个纯粹的清洁工,负责清理偶尔出现的拼写错误。与此同时,我们的代码风格习惯已经蔓延到了 IDE 无法帮到我们的领域:命名约定和标准遵从。我们养成了做正确事情的习惯!

老式调试

调试器简直就是我的救星,我每天都为此心怀感激!不过,你永远不会听到我说“如果没有 gdb 和 valgrind,我真不知道该怎么办”。我知道自己该怎么办,因为我已经练就了一门被遗忘的调试技巧

现在,我绝对建议用这些习惯来代替你编程语言的调试工具。坦白说,那样做太愚蠢了。调试器的存在是有原因的,你没有理由不知道如何使用你的调试器!同时,调试器仍然是一种强大的工具。能够不用调试器进行调试意味着我们可以调试器更快、更高效地进行调试

您愿意做什么:花一个小时用调试器逐步检查源代码,还是花十分钟用调试器逐步检查源代码?

办公桌检查

我的好友兼程序员同事 Chris “Fox” Frasier 年轻时大部分时间都在研究 FORTRAN、COBOL、汇编和穿孔卡。在他那个年代,调试器几乎还是个梦想。如果你想调试代码,只有一种方法:桌面检查

桌面检查指的是审阅打印好的源代码副本,并真正扮演计算机的角色。你以与机器相同的方式单步执行,记录所有寄存器和变量的值变化。持续的桌面检查练习会让我们放弃自己的思维捷径,转而关注计算机的纯粹逻辑。

这确实是一门失传的艺术,但我们需要重新引入!我做桌面检查的时间几乎和写代码的时间一样长。因此,我能够在 C 和 C++ 中手动分配、管理和释放原始内存,错误很少,而且几乎所有遇到的错误都能在几分钟内调试出来已经学会了像计算机一样思考。内存管理、缓存、条件分支、操作顺序、数据转换……所有这些对我来说都只是本能!

当然,我经常使用调试器,但我的桌面检查能力已经与它无缝衔接了!当我单步执行代码时,我会在脑海中运行逻辑,通常几分钟就能找到问题所在。有时我甚至根本不需要运行调试器——只要仔细阅读一下函数就能发现问题。

流程图

很遗憾,流程图已经不再受到很多程序员的青睐。或许是因为它们被当成了最终目标,而不是手段,但我希望更多程序员能够学会如何利用流程图。

一个好的流程图有助于预防调试错误。它将非线性的计算机逻辑从源代码有限的线性结构中分离出来,并将其转化为我们更容易处理的形式。即使不遵循“官方”的符号体系,在白板或笔记本上快速绘制流程图也能解决一些最棘手的逻辑错误。

打印语句调试

说实话,我觉得这项技术并没有得到足够的重视。虽然很多年轻的程序员(不明智地)用打印语句调试来代替正规的调试器,但这并不能抵消这项技术的潜在价值。

本质上,打印语句调试其实只是I/O 调试(最早的测试形式)的一种。在调试器出现之前的时代,这是程序员除了桌面检查之外的另一个工具。Fox 描述过,他们只需要观察指示灯的闪烁,就能仅凭这些数据推断出逻辑错误!

有些 bug 我选择用一些恰当的 print 语句来追踪,而不是直接触发gdb。这并不是因为懒惰或无知,而是我刻意想要用一种不同于以往的方式来处理这种情况。

请注意,我并不是简单地把所有可用的数据都转储到命令行上。我会快速地在脑海里检查一下,找出逻辑可能崩溃的地方,然后编写一个打印语句来显示相关的变量值和函数调用顺序。我强迫自己选择一个信息子集来解决问题。这与调试器不同,调试器会把所有信息都直接交给你。然后,根据输出,我必须在脑海中运行逻辑并推断出问题所在。

难吗?当然难!但努力终有回报。现在,当我使用调试器时,我就能精准地找到我需要的信息,并在更短的时间内找出问题所在。

这也培养了我的测试编写习惯。在进行了大量这样的调试之后,我更加清楚哪些测试是重要的,哪些最好放在后台进行。毕竟,测试所有东西会浪费大量的时间和精力。

命令行编译

我使用 IDE 获得的最后一项技能是自己编译或运行代码的必要性。这适用于任何语言,无论是构建 C++ 二进制文件,还是执行 Python 模块。通过在命令行中手动运行代码,您可以了解构建/运行过程的内在工作原理。

了解相关步骤让我在编写可移植的构建系统以及选择语言、库、工具和构建选项方面节省了大量时间。根据我的经验,没有什么比完成一个项目后却发现由于某个依赖项而无法在目标平台上打包二进制文件更糟糕的了!

其实,我希望自己早点学会这一点。我以前经常在命令行中编译或运行单文件程序,但直到最近我才真正尝试用这种方法构建更大的程序。告诉你,这完全是另一个过程!

即使你最终使用 IDE 和自动构建系统进行生产构建,你也应该挑战自己至少在命令行上编译一次整个大型项目。现在我有了这样的经验,几乎可以在短短几分钟内诊断出任何构建问题。

重新引入 IDE

我希望你现在相信,不使用 IDE 编写代码可以培养许多宝贵的技能和习惯。然而,我必须再次强调,我绝不提倡摒弃 IDE!这些强大的工具非常有用,尤其是当我们在不使用 IDE 的情况下,还能获得一些实用技能时!

在某些情况下,我们不依赖 IDE 会很方便:

  1. 当您需要修复紧急问题时,IDE 可能并不总是触手可及。想象一下,您的构建从根本上崩溃了,责任链意味着您需要立即采取措施。您没有在史蒂夫叔叔的桌面上安装 IntelliJ IDEA 的奢侈;您需要打开一个隐私浏览选项卡(这样您的凭据就不会被存储),登录 GitHub,然后修复以某种方式推送到实时生产环境中的根本性错误功能。(是的,这种情况很少见,但在我的职业生涯中遇到过两三次)。如果您依赖 IDE,那么在这种情况下您完全没用。但如果您知道如何在没有 IDE 的情况下编写代码,您就可以直接在 GitHub 中编辑,一次性在不到十分钟的时间内解决问题,并减轻重大灾难或不便。

  2. 有时候,IDE 会碍事。有时候,我其实更喜欢打印出源代码,坐在扶手椅上,端着一杯热茶,用一支红笔,在办公桌上检查一下。这不仅能让我的眼睛从屏幕上休息一下,而且环境和工具的改变还能让我从不同的角度看待问题。我甚至可能比使用调试器更快地解决问题!

大多数时候,你仍然会使用 IDE,但我保证这些额外的技能能让你在更短的时间内写出更简洁的代码。有了新增的功能和安全保障——语法高亮、linters、智能感知、自动完成、调试器等等——你原本就不错的代码有潜力成为真正优秀的代码。

文章来源:https://dev.to/codemouse92/the-curse-of-the-ide-3j7n
PREV
前端调试第一部分:不仅仅是控制台日志
NEXT
如何成为一名开发人员 - 第 4 部分:推荐阅读编程文化常识 Python C++ 和 C Linux