同一句问候,在不同的屏幕上说不同的方言

1天前

文/一个在四种操作系统之间来回切换的人

我办公桌上常年摆着三台设备——一台Windows台式机、一台MacBook Pro、一台装了Ubuntu的旧笔记本。再加上偶尔掏出来的手机,我每天至少要在四五个屏幕之间来回切换。有时候一个上午,我的手就要在三种不同的键盘布局、四种不同的命令行环境里轮流转。

但我发现一件有意思的事情:同样的一个Hello World程序,在这些设备上跑起来的样子,其实是不一样的。不是输出内容不一样,是”看见它”的过程不一样。

在Windows上:黑窗口里的第一次

Windows用户写Hello World,通常是打开一个叫”命令提示符”的黑底白字窗口,或者打开Visual Studio之类的IDE。那个窗口有一个名字叫”控制台”,它从DOS时代一路延续下来,外观变化不大,跟你爷爷奶奶那辈人看到的差不多。

在Windows上编译运行一个C语言的Hello World,会有一个黑色的窗口突然弹出来,显示那行字,然后可能在你还没来得及看清的时候就消失了,因为程序跑完就退出了。Windows用户的第一课,往往不是”怎么输出”,而是”怎么让那个窗口停下来”——要学会在代码末尾加一个system("pause")或者getchar()

我在Windows上写第一个Hello World的时候,对着那个一闪而过的黑窗口愣了好几秒。我以为程序出错了,重试了好几次,才搞清楚”它其实成功了,只是成功得太快,没来得及让我看到而已”。那个体验其实挺有象征意义的——Windows的Hello World告诉你:你是看不见结果的,除非你特意让它停下。

后来我在Windows上用Python,直接在命令行里输入python进入交互模式,然后打print("Hello, World!"),这次不需要system("pause")了,因为交互模式会一直等着你输入下一条命令。输出就在你输入的命令下面,安安静静地待在那里,等你自己决定什么时候关掉窗口。

Windows的Hello World,像一个急性子的传令兵——把话带到了就跑了,你想确认他来过,得专门叫他站住。

在macOS上:白色终端里的干净输出

我第一次在Mac上写Hello World的时候,打开的是那个叫”终端”的App。它的背景是白色的(早期版本),或者深色(现在可以调),但它跟Windows命令提示符最大的区别是——它不会一闪而过。

在Mac终端里写一个C程序的Hello World,编译成可执行文件,然后在命令行里输入./a.out,输出就直接出现在下一行。窗口不会消失,程序也不会自动退出到你找不到的状态。你看到那行字了,它就在那里,上面是你敲的命令,下面是输出的结果,清清楚楚。

我第一次看到那个界面的时候,心里想的是”这才是正常的样子”。输出就是输出,不应该跑掉。后来我发现,macOS源自Unix系统,Unix传统里程序跑完就退出、把输出留在当前终端,是一件理所当然的事情。Windows那边留下来的”黑窗口一闪而过”的记忆,其实是DOS时代的遗产,跟Unix传统不太一样。

在Mac终端里写Hello World,就像在纸上写字——你写完了,字就在那里,不会消失。你什么时候想看,它都还在。

在Linux上:不说话的规矩

Linux的Hello World跟macOS很像,因为macOS底层也是Unix,终端行为基本一致。但Linux的环境有一个特点——你对它说什么,它就做什么,不多说一句废话。

在Ubuntu的终端里,你敲gcc hello.c -o hello,它什么提示都没有,就直接回到命令行。你敲./hello,它就输出那行字,然后回到命令行。没有”编译成功!”的庆祝,没有”程序已退出”的提示。它默认你是懂行的,不需要多余的装饰。

我第一次用Linux的时候,编译完一个程序发现”什么都没发生”,我还以为编译失败了。后来才知道”什么都没发生”就是成功了——在Linux的世界里,不报错就是最好的消息。

Linux的Hello World,像一位寡言的同事——你交代的事他做了,结果放在你面前,然后安静地回自己座位。不邀功,不解释,不拖泥带水。你习惯了之后会很喜欢这种风格,但第一次接触的时候可能会觉得”它是不是对我不太热情”。

在浏览器里:人人都能看到的那行字

还有一种Hello World跟操作系统无关——你在浏览器里打开开发者工具,在Console面板里敲console.log("Hello, World!"),回车,它就出现了。它不在终端里,不在黑窗口里,不在任何”命令行环境”里。它就是浏览器的一部分,跟网页的HTML、CSS、JavaScript待在一起。

这个Hello World是”网络一代”程序员的起点。它不需要安装编译器,不需要配置环境变量,不需要知道操作系统是什么版本。你只要有一个浏览器,按F12,然后就能看到那行字。

我第一次在浏览器控制台写Hello World的时候,觉得”这也太方便了”。不需要任何设置,不需要任何”配环境”的步骤,打开即用。但后来我也意识到,这种方便是建立在”浏览器已经帮你做好了一切”的基础上的。它帮你隐藏了编译器、解释器、运行时环境的所有细节,让你只需要关心那一行输出本身。

浏览器的Hello World,像一个帮你把所有麻烦都挡在门外的人。你只需说”你好”,其他事情它来办。

那句问候,见证了所有平台的差异与统一

这些年我在四个平台之间来回切换,几乎每天都在跨环境工作。同样的代码、同样的输出内容,但每一次看到那行字的方式都不一样。Windows的窗口会闪,macOS的终端会留,Linux的环境不废话,浏览器的控制台最便捷。

但有趣的是,这四个平台用各自的方式输出同一行字,内容却完全一致。不管是在黑窗口、白终端、Linux命令行还是浏览器控制台,”Hello, World!”这几个字符永远不会变。它可能是你写过的、唯一在所有平台上表现完全一致的代码。

后来我跟一个做跨平台开发的同事聊过这个话题。他说:”Hello World可能是唯一一个’不需要担心跨平台兼容’的程序。几乎所有语言、所有操作系统、所有终端环境,都能用它测试’基础通路’。它不是针对某个平台写的,它是针对’所有平台’写的。”

这句话让我想了好一会儿——我们平时写代码,要考虑Windows和Linux的换行符不一样、要考虑不同终端的字符编码不一样、要考虑不同系统的文件路径写法不一样。但Hello World不需要考虑这些。它在任何环境里都输出同样的东西,没有任何歧义,没有任何”取决于平台”的行为。

这大概就是为什么它适合当”第一个程序”——你不必知道你在哪个操作系统上,不必关心终端的类型,不必考虑环境差异。你只需要写那行字,然后它就会以”那个平台该有的方式”出现在你面前。

那行字,帮你认清了平台的”性格”

我现在用不同设备的时候,还会偶尔写一个Hello World来”打招呼”。不是出于需要,而是出于习惯——每次打开一个新的终端环境,敲下那行字,看到它用那种平台特有的方式输出,我就会觉得”嗯,这个环境我熟悉了”。

Windows的Hello World让你学会”如何让窗口停下来”——这教会你控制程序的执行流程。macOS的Hello World让你学会”如何让程序不自动退出”——这教会你理解Unix的运行模型。Linux的Hello World让你学会”如何解读’什么都没发生'”——这教会你理解”沉默即是成功”的哲学。浏览器的Hello World让你学会”如何利用已有的工具”——这教会你明白”环境帮你做好的事情,也是你需要知道的事情”。

同一行字,在不同平台上教会你不同的东西。但等你把四个平台都用过一遍,你会发现它们教的东西合在一起,刚好拼出了对”编程环境”这件事的完整理解。

我坐在三台设备中间,看着它们各自的屏幕上、各自的终端里,用各自的方式显示着同一行问候。那行字像我站在这三台设备中间说了一句话,然后它们各自用不同的声音、在不同的频率上,重复了一次。

内容完全一样,但各自的方式,透露了各自的”性格”。