summaryrefslogtreecommitdiff
path: root/content/article/lost-in-gui.md
blob: 3e73a91220a5e23b8e8b52e720736dd21a334e83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
+++
title = "迷失于图形界面"
subtitle = "Not to be fooled by magic."
slug = "lost-in-gui"
tags = [
    "软件",
]
categories = "软件杂谈"
date = 2026-03-07T19:41:05
draft = false
toc = true
toot = "https://akk.eltr.ac/objects/f188c4b3-6897-4de9-b551-5326927d339e"
url = "/essays/lost-in-gui/"

+++

学校开设了 Python 课程,课程还涉及人工智能相关的内容,但也有相当一部分内容是 Python 程序设计基础。自然地,第一堂课的内容是配置开发环境,*自然地*,配置开发环境的内容就是*安装 PyCharm*,并在 PyCharm 的图形界面里找到对应的面板安装要用的依赖项。

一般来说,只要老师没有妨碍我愉快地用我爱用的编辑器(Neovim)写代码,我是不会说什么的。只不过,这位老师之前也教过我数据库的课程,他对于开发工具的态度在我看来非常典型,所以值得一谈。<!--more-->

## 不解之词

老师在演示如何用 PyCharm 安装依赖时说了这样一句话:

> “我看有的人用写代码的方式就能把依赖安装上了,那样好像是会快很多,有些人就是能找到捷径啊!”

尽管我对 Python 生态不熟悉,但根据他的描述,我大概明白他说的是类似 Node.js 的 `package.json`、Go 语言的 `go.mod` 和 Maven 的 `pom.xml` 之类的东西。在项目根目录的一个文件声明项目所需的依赖之后,执行安装命令,就能在当前项目下安装所需的依赖。这实际上是相当常见的实践,有正经工程应用的编程语言都有类似的东西。

在讲授数据库原理及其应用这门课的时候,他要求我们安装的是 [Navicat](https://www.navicat.com/),一个管理数据库的图形界面工具。我不想用闭源的商业软件(而且我当时的操作系统是 Arch Linux,似乎也没有在 AUR 上找到包),所以选择了 [DBeaver](https://dbeaver.io/)。我记得很清楚,我除了在需要提交作业截图时使用了这个软件,其他时候都是用 [MariaDB](https://mariadb.org/) 自带的命令行工具,手打 `SELECT` 和 `INSERT INTO` 等语句,因为我真的不想在层层叠叠的图形界面里找我想要的功能。

我记得有一次交作业我实在不想打开 DBeaver,于是提交了终端截图,结果下一次上课的时候就听到他这样说:

> “有的同学直接输入 SQL 语句,都不嫌麻烦的吗?临时输入一两句还好,要输的东西多的时候,就直接在软件的表格里编辑数据表就好了啊。”

~~那这和用 Excel 有什么区别!~~

到目前为止,这还只是操作习惯的差异,不足为奇。*所以,老师是一个喜欢操作图形界面的人,这不代表他是个差劲的程序员,程序员的能力不体现在工具的选择上,不熟悉命令行工具又怎么了?用 Neovim 和 Emacs 就比用 VS Code 更高尚?用 Postman 就比用 `curl` 更愚蠢?用集成开发环境也不代表无能啊。*

> “大家用 `pip` 安装依赖的时候注意一下啊。”老师好像是突然想起了以往的经历,在讲课时突然插入了这样一句话,“用 `pip` 安装的第三方库和你的 PyCharm 里的第三方库可能不会互通,就是说你用 `pip` 安装了第三方库之后,在 PyCharm 里可能用不了,要在 PyCharm 的图形界面里安装依赖。”

我没学过 Python,但确实用 Python 写过不少脚本来帮我自动化处理某些操作,比如批量修改博客的 Markdown 文件格式、替换文本之类的,我也的确遇到过没办法正常加载依赖的问题。当时我只能改变实现方式,避免调用第三方库,一直没明白原因。这么说,我的问题就要从老师那里得到解答了?

没有,他直接往后讲了,什么也没说。他自己大概也不明白为什么 `pip` 安装的依赖会没办法在 PyCharm 里使用。

求助*熟练操作蟒蛇*的[狐狸](https://blog.southfox.me/)之后得知,这是 Python 的[虚拟环境](https://docs.python.org/3.14/library/venv.html)导致的,即 `venv`。虚拟环境会将软件包与全局环境的软件包隔离开来,只有在环境内显式声明的软件包才可用。`pip` 默认把软件包安装到全局环境中,而 PyCharm 会帮忙管理虚拟环境,两者不在同一个环境里操作软件包,所以没办法直接互通。

这就解释清楚了,所以我只需要执行 `source` 命令进入虚拟环境,然后在虚拟环境里管理依赖和运行 Python 程序就可以了;如果安装了 uv,使用 `uv run` ,可以直接在项目的环境里执行命令。[^1]

不过,老师看起来教授 Python 也有几年了,为什么会不清楚这个基础概念呢?难道是我误解了老师的……

*好了,是时候放下我对教师的假惺惺的尊敬了。*

## 图形界面的魔法

图形界面的优点在于,它屏蔽了很多细节,避免直接和复杂的配置文件和基础工具打交道。这无可厚非,软件设计的一大原则就是「信息屏蔽」,让用户关注更重要的事情。可是,对于程序员来说,这些细节真的应该被屏蔽吗?一个好的程序员不应该了解自己所使用的开发工具是如何运作的吗?

我在英文博客上写过一篇《[Java Development with True IDEA](/en/posts/java-dev-with-true-idea/)》,强烈抨击了 IntelliJ IDEA 单边主义,[^5]并把软件开发所需要的 IDEA 重新定义为 Instant(快速)、Deliberate(审慎)、Elegant(优雅)和 Attentive(专心)。

我当时连续使用 IDEA 将近一年的时间,原因在于:没了 IDEA 我就不知道怎么开发 Java 项目了。之所以会这样,是因为 IDEA 给我屏蔽的信息太多了。不操心底层真正发生了什么的后果是,我根本不知道底下发生了什么。当我按下 IDEA 的「运行」按钮时,究竟有什么命令被执行了?我不清楚,以前的我也不关心,我只知道「这个按钮能让我的代码跑起来」,就像魔法一样。

可是,要是有一天魔法失效了呢?当我按下「运行」的时候程序没有被执行,当我按下「同步」按钮的时候依赖没有被同步(IDEA 的设计非常奇怪,有时候「同步」按钮根本不会显示,我必须在一个下拉框里找到某个菜单项才能正常同步依赖),当我的程序没有被正常编译,而我在密密麻麻的界面里找不到相关的配置项时,我要怎么办?

要找到图形界面里的某项配置可真不简单。

首先,我很难用语言描述清楚我要找的是什么,如果描述不清楚,又怎么在搜索引擎里搜索教程呢?其次,就算找到了我要的东西,有人告诉我这个东西要在 `Project Strucutre -> Libraries -> More` 里面找到,我也要在硕大的图形界面里搜寻这些文字的位置。再次,就算有截图指引,我也有可能因为版本差异而没有办法在图中所示的地方找到我需要的东西。

有人可能会因为熟悉图形界面迷宫而感到自豪吧。我记得我在各种按钮、菜单、面板和输入框之间穿梭,只为了调整项目的编译方式时,有一个不熟悉计算机的朋友突然凑过来看我在做什么,发出了「好厉害」的感叹。可是,究竟为什么要学习一套可有可无的、建立在基础工具之上的抽象,而不去直接使用基础工具呢?

这就好比用 React 开发一个只有一页的网站,而这一页的内容只是几句话和几个链接——*那你为什么不能直接写 HTML,而要去操作虚拟 DOM 呢?这层多余的抽象究竟给你带来了什么价值?*

我为什么要学习 Postman 的图形界面,等待它花几秒钟的时间启动一个 Chromium 实例渲染一个网页,学习和记忆 URL 输入框 和 HTTP 请求方法的选择框的位置,只为了发一个简单的 HTTP 请求?我为什么不能直接使用 `curl`?如果我只会用 Postman,我就不知道要怎么在其他的地方发送 HTTP 请求了,而 `curl` 却被安装在几乎任何一台计算机上,是很多软件的基础工具,无论是日常测试、运维还是开发工作,都能用到。我调试自己写的 API 会用 `curl`,我测试部署的服务有没有真的跑起来会 `curl localhost:<port>`,像 [Hurl](https://hurl.dev/) 这类与 HTTP 请求相关的软件也是在 `curl` 的基础上开发的。

显然,无论选用抽象层次很高的图形界面软件,还是最基础的命令行工具,都有学习的成本。那为什么要学习一套将你与底层隔离开来的抽象,而不是直接学习更接近底层的工具呢?

我承认抽象有存在的价值,但我反对过度且不必要的抽象。

## 专业与门槛

可能有些幼稚,但我又要举一个大学老师的例子了。不过这个老师本身就很讨人厌,说话爹味很重而且粗俗,还觉得自己和蔼可亲,他项目组里的学生能跑的都跑了。他身上有一个很多爹味浓重的人都有的典型特质:热衷于做「守门人」,强调门槛与专业性,踩在门槛上拉开自己与他人的距离。

他也喜欢使用图形界面,但原因,在我看来,并非是权衡利弊之后的选择,而是对门槛的维护。在我看来,如果你不想接触基础工具,只想要优化开发体验,那么选择简洁直观的图形界面工具也无可厚非,只要这是你自己选的。

设计软件架构常用 UML,即统一建模语言,UML 有各种不同类型的图表,用来表达架构、活动、操作的时间顺序、涉及的模块和对象等等,总之是便于沟通的标准化工具。既然目的是「沟通」,那么只要能准确表达,能让他人理解,就达到了目的。简单来说,只要图画得清晰,没有错误和歧义,能够高效沟通,就是好图。

但是这位老师显然不这么认为。

> “有的同学用 Visio 画图,这样不好,我们作为软件工程的学生,要使用**专业**的 UML 绘图工具。你作为**专业**的软件工程学生,连**专业**的画图工具都不会用,怎么行!?”,老师神情严肃地讲道,“我在群里发了两个软件,第一个软件我们把他叫作 EA[^3],这个软件是商用的,你也可以用第二个开源的 StarUML。[^4]”

Visio(以及开源的 draw.io)不被他视作**专业**的 UML 图绘制工具,并不是说架构师没办法用它们画好图,而是因为它们缺乏与 UML 相关的抽象。这位老师强调,Visio 是矢量图绘制工具,而不是**专业**的 UML 图绘制工具。这两类工具的区别就在于抽象层次的高低。

之所以这么说,是因为,UML 图明显就是图片的一种,一般也是作为矢量图来绘制的。能绘制矢量图的工具当然也能绘制 UML 图,说白了,UML 图里最常见的元素就是方框、圆圈、直线、箭头、小人和文字,连 PowerPoint 都能画这种图。只要使用了正确的建模语言和规范,保证图片清晰易懂,就是好的 UML 图。

前文提及的 EA 和 StarUML 等软件,当然也是能画方框、圆圈和小人的,只不过它们只能用这些元素来画 UML 图。使用这种工具绘制 UML 图是自然的,哪怕对建模语言本身不熟悉的人,也不容易画出错误的图。

通俗地来讲,这两类软件的区别,就是化学原料和包装好的清洁剂的区别。这位老师觉得:使用一水柠檬酸溶液来清除水垢是不专业的,应该使用包装上写明了「水垢清洁剂」的清洁产品,才**显得专业**。

## 破除魔法

让我总结一下目前为止我的观点。

长期依赖于高度抽象的图形界面工具,尤其是在一开始就没有了解过低层次抽象的前提下,会让人忽略最基础的知识。这是个人层面的问题。社会层面上,会创造出本不应该存在的门槛和鄙视链,仿佛使用高度抽象的软件系统就更专业。

这种心态不罕见,我相信:如果让所有的 Java 开发者停止使用 IDEA,有相当一部分人会不知道如何启动 Spring Boot 项目(答案:用 `mvn spring-boot:run`);如果你告诉别人你用 GIMP 编辑图片而不是 PhotoShop,有相当一部分人会认为你不够专业。

这么说来,因为普遍认为前端技术很简单,所以常常被鄙视的前端开发者,实际上大多都脱离了这种窘境,因为前端开发的必要工具之一就是 `npm` 或者其他相关的命令行工具,我很少看到有人用 JetBrains 的 WebStorm,通过操作图形界面管理依赖项。当然,前端开发也有自己的问题。

使用 LLM 开发也是,许多人宁愿用高度抽象的自然语言描述需求,也不愿意手写代码,就算在遇到 Bug 时跟 Agent 发疯也不愿意停下。[^2]如果他们愿意去看看真实的代码,接触被抽象掩盖的东西,他们就不会如此狼狈。我想这背后也是相似的心态在作祟,而且「程序员应该跟上潮流用 LLM 写代码,手写代码是落后的」这种思想,似乎也有愈演愈烈的苗头。这种潮流,何尝不是痴迷于高度抽象的软件,所造就的门槛?

最后,我想说的是,不要怕麻烦,接触低层次的抽象并不可怕,反而能帮助自己建立起对软件的清晰认知,而清晰是非常宝贵的。就像学习 C 语言有助于程序员理解内存、指针和数据结构等基础概念,就算不用 C 做开发,有了这些理解,也更容易写出高性能、速度快的软件。

从长期来看,对软件的清晰认知,要胜过生产力和专业的外表,而扒开抽象的外壳向内看,是培养这种认知的关键步骤。

[^1]: 参见:[Running commands in projects | uv](https://docs.astral.sh/uv/concepts/projects/run/)

[^2]: 顺带一提,我甚至见过有 Java 开发者非常认真地讨论,要不要双开 Cursor 和 IDEA 做开发,因为他们觉得需要用 AI 编程,而离开了 IDEA 做 Java 开发又很麻烦。

[^3]: 全称是 Enterprise Architect,中文意思是「企业架构师」。英文里的 Enterprise 除了指代企业和创业,也和企业家精神和专业性有关联,所以也可以理解为「专业架构师」。

[^4]: 我了解之后发现,StarUML 也是专卖软件(Proprietary software),最初以 GNU GPL 协议发布了开源版本,但开源版本在 2010 年就停止维护了。当然,就算它是自由软件,我也不想用,原因在于它是 GUI 软件,很重,另一个很关键的的原因是,*它是用 Electron 和 Java 写的*。

[^5]: IntelliJ IDEA 是 JetBrains 开发的,专注于 Java 和 Kotlin 开发的集成开发环境。一般来说,学校里教 Java,要么会要求学生安装 Eclipse,要么就是 IDEA。IDEA 是最常见的,人们几乎不会思考开发 Java 软件的其他方式。