顶置菜单

2009/11/11

通常,OS X 应用程序的主菜单位置是让刚刚接触 Mac 的 Windows 用户感到新奇的一个地方。主菜单不从属于任何一个窗口。所有应用程序的主菜单都在整个屏幕的最上方显示,同一时刻不可能有多于一个应用程序的菜单显示。所以 active 程序切换的时候会产生 Windows 上没有的菜单切换现象。

对于顶置主菜单与窗口主菜单的优劣,Apple 的 Bruce Tognazzini 从用户交互的效率和速度为 Mac 的风格做出了辩护。当然也有人进行了针锋相对的驳斥。在我看来,在这场围绕 Fitt’s Law(或者说指向设备 —— 即鼠标的操作速度和效率)的争论中,双方至多算打了一个平手。我自己将近三年的 Mac 开发和使用得到的感觉是:主菜单和窗口的逻辑关系要比鼠标的指向速度重要的多得多。

至少有三个原因让我认为主菜单应该和窗口分离。第一,主菜单重在一个『主』字。基本上应用程序能完成的所有功能都应该在主菜单中能够找到对应项。所以,主菜单中必然包含非针对某个窗口(窗口无关的)或者针对多个窗口的操作。最为典型的是『 Windows 』菜单 —— 列出所有打开的窗口,控制窗口的排列。让主菜单这样的 UI 元素从属于某个窗口 —— 一个后果就是每个窗口都有一个 『 Windows 』菜单 —— 从逻辑上说是十分怪异的。第二,在 93 年左右或者更早接触过电脑的人一定知道当年著名的 MDI 模式。也就是 Word 5.0 那种模式 —— 一个大的窗口包含所有的文档窗口。这似乎是 Microsoft 在不违反 Windows 本身的主菜单必须依附于窗口的前提下,尝试让主菜单脱离文档窗口的一种尝试(当然这不是 MDI 的唯一目的,但是我认为从逻辑上看这种考虑是有的)。遗憾的是,MDI 的大窗口带来的用户体验似乎是很糟糕的,让 Microsoft 不得不放弃尝试让 MDI 作为主流。随之而来的是几种不成功的尝试:Visual Basic 6.0 把主菜单做成单独的窗口(也为 Delphi 和某些版本的 Photoshop 采用);Visual Studio 把所有窗口用 dock tab 来实现(UltraEdit 类似)。前者类似 Mac 的风格,但是在处理主菜单的显示上明显没有 Mac 的置顶方式简洁,基本可以认为是 Mac 风格的胜利。而后者并非完美的方案,因为在有了 tab 的情况下用户往往仍然需要窗口级别的组织才能更好的同时处理更多文档。

第三,今天的程序往往很多功能并不体现在窗口上,所以很多程序有了一个特殊的状态 —— 没有任何窗口打开,但是程序仍然保持后台功能的运行。这个状态可以叫做 stealth 模式。MSN、Adobe Bridge、很多浏览器、播放器都有这种状态。但是如何从 stealth 模式恢复成普通模式?当主菜单依附于窗口的时候,进入了没有窗口的 stealth 模式时主菜单对于返回普通模式就无能为力了。在 Windows 下,开发者必须编写支持托盘图标(Tray Icon)的代码来支持 stealth mode。而在 Mac 上,几乎任何程序都天然的拥有 stealth 模式,无需一行特别代码来实现 —— 没有编写的代码就是 bug 最少的代码,也是最快的代码。Mac 程序在 stealth 模式下仍然可以拥有一个全功能的菜单(当然不合理的菜单项会 disable),而不是托盘图标提供的一个粗陋的菜单。Mac 的菜单切换也变成了在 stealth 模式下更好的隐藏程序从而不影响用户使用其它应用的一个优势,这是前面说的那种 Visual Basic 风格的独立窗口主菜单不具备的。

而且,今天的应用程序更多的把主菜单作为一种完备性的体现而不是用户体验的主要组成部分。快捷键,工具条,拖放,图标,右键菜单(context menu),乃至于 multi-touch pad 的 gesture;这些才是用户体验的集中体现。所以,主菜单的设置合理更多的在于逻辑关系的正确和清晰,主菜单是用户发现功能的场所,而不是使用功能的主要场所。不是 Fitt’s Law 体现的速度和效率的主要舞台。所以,即使在 Fitt’s Law 方面各执一词,在菜单切换现象上略有劣势,我仍然有理由认为 Mac 的菜单风格胜出。

Universal Binary

2009/11/09

最近 Ryan Gordon 终止了在 Linux 上实现 Fat Binary 技术的努力。这让我和甫鸼展开了一场对 Universal Binary 技术的讨论。

Universal Binary 的鼓吹者一般认为在连接器和操作系统底层直接加入对多 CPU 架构的支持( multi-arch support )可以大大简化开发者的负担和提高最终用户感受到的易用性。反对者则可以反驳说把能放在 build 脚本和 installer 中的 policy 不必要地塞到底层违反了 Unix 的原则。

抵触最大的恐怕是 Open Source 社区。毕竟这次 Ryan Gordon 放弃的直接原因就是 Linux 社区对其努力的冷落。Open Source 的发布方式可以戏称为 Universal Source —— 程序的大部分由 CPU 架构无关的源代码构成,少部分 CPU 构架相关的代码由条件编译构成或者由 build 脚本根据执行 build 的平台条件来引用不同的源文件。经由 Open Source 的安装三部曲(configure-make-make install),就能安装好一个适合目标硬件的精炼的无冗余的程序。这样的发布是完美的 —— 除了不能兼容非 Open Source 的商业模式。

要应对多 CPU 架构,就必需在程序的发布或者运行中实现应对这种架构的智能。Open Source 模式的优势在于它的发布形式能够完整的体现开发者在编写代码时就考虑到的一切应对 multi-arch 的智能,然后在安装过程中(也就是 build 过程中)由编译器、连接器和 build 脚本的强大智能来完成部署。非 Open Source 的发布模式则必须另辟蹊径。在所有面对 multi-arch 这个难题的企业中,Apple 当年的问题最为紧迫。由于要完成从 Power PC 到 Intel x86 的迁移,Apple 必须在一个时期之内能给开发者和用户一个足够简单(甚至傻瓜化)的解决方案。尽管如 Linux 社区大力主张把 multi-arch 的智能放到 build 脚本和 installer(Linux 的 package manager)为正途,而 Mac OS X 在很多方面也确实遵循 Unix 的文化,最终 Apple 还是选择了 Universal Binary 。因为我每日都在 OS X 上开发,已经习惯 Universal Binary,到了有所偏爱的程度。

为了比较各种方案的差异,设定一个例子。有一个工程,在单一 CPU 架构的时候生成四个可执行文件,六个数据文件,一共十个文件,为其增加 multi-arch 支持。假设我们拥有一个不支持 Universal Binary 的操作系统。当然相应的编译器和连接器也就不会支持 Universal Binary。但是我们仍然假设编译器和连接器的交叉编译功能很方便,只要一个 Option 就能切换目标文件的 CPU 种类。也就是说支持不同 arch 的基础能力具备,只是没有对 Universal Binary 的支持。那么,为了服务使用不同 CPU 架构的用户,我们就必须面临几种选择。第一是我们使用一套标准的工程文件,针对需要支持的每种 CPU 架构,用相应的编译器 Option 编译一次。假设有三个 CPU 构架。因为是采用完全相同的工程文件,仅仅是一个编译目标的 Option 不同,所以我们会生成 30 个文件(三个版本,每个版本十个文件)。使用不同 CPU 的用户可以选择不同的版本安装。这样的方案,build 过程中对六个数据文件(假设是平台无关的格式)的生成就是冗余的。对于拥有多于一种 CPU 架构的机器的用户来说,需要下载相应的多个版本,所以重复下载了六个数据文件(重复的次数由用户拥有的 CPU 种类决定)。

另一种选择是我们写一套特殊的工程文件。一次生成支持三个 CPU 的 12 个可执行文件(每个架构四个),而对于平台无关的六个数据文件只生成一套。所有的结果都打入一个 package。相应的,installer(或者说 unpackager)必须针对用户安装时的平台提取正确的可执行文件版本和数据文件。这种方案的缺点是必须自己在 build 脚本和 installer 里编写处理 multi-arch 的智能。Universal Binary 的反对者会说这些智能并不复杂,Build 脚本和 installer 正是实现它们的好地方。但是,实际上每个工程实现这些智能的方式都会有些微的区别。这就意味着,用户从一个产品得到的知识并不能用到另一个产品里 —— 比如检查该产品支持的所有架构,如果是 Universal Binary 的话可以用统一的命令查询。开发者从一个工程转向另一个工程也必须通过文档或者别人的描述才能熟悉这个工程特有的 multi-arch 处理。

对于上述的工程例子,支持 Universal Binary 的系统则是一次生成十个文件,只在四个可执行文件中同时包含三种 CPU 架构的代码(用 ELF 的术语来说是三个 section )。这种方式为反对者诟病之处在于,安装好的系统存在冗余 —— 磁盘上会有用不到的机器码,提高了连接器和操作系统的复杂度,违反了 Unix 的 Mechanism, not policy 的原则。不过,任何稍稍违背这一原则的做法都会带来一个好处 —— 标准化带来的统一性。在《C++与垃圾回收》一文中我曾经说过,正是因为 C++ 把各种高级内存管理策略放到了库而不是语言级别,才让这些高级策略不能得到强制统一而形同虚设。所以,mechanism-not-policy 需要灵活的「道」来处理而不能一味的极端化。

Universal Binary 其实可以看作一种次优的方案。它的冗余度没有达到最优(与定制编写 build 脚本和 instaler 相比),但是大大低于第一种方案。即使存在冗余度,冗余的粒度也很小,属于次文件级别(ELF 格式为例,即 section 级别)。而且这个冗余度也带来了一些智能 installer 方案不具备的好处,就是安装之后的程序可以在不同架构的 CPU 的机器之间自由拷贝(前提是程序具备这种在任意位置运行的能力,而 Mac OS X 的 Single-File Application 恰恰是这种风格)。Universal Binary 还是一个非强制性使用的功能。连接器和操作系统只是提供支持 multi-arch 的能力,选择打入哪些 CPU 架构的执行码完全由开发者自己决定。从这个角度来说,Universal Binary 并不是真的违背 mechanism-not-policy 的原则。Universal Binary 产生于 Mac 的特殊历史,也与其文化相辅相成 —— Single-File Application,也就是 installer 完全零智能;无中央化的包管理(通过 Guide 来保证用户体验的一致);相当数量的用户(由于 transition 阶段的存在)拥有或者在一段时间拥有基于不同 CPU 架构的多台机器,需要程序能够在机器之间自由拷贝并保持工作(由于 Single-File Application 的文化)。

Universal Binary 是一个能提供有别其它方案的独特优势的方案,当然也引入了自身的代价。综合考虑,这些代价在 Mac 特有的文化中是完全可以接受的,也就是说 Universal Binary 在 Mac 的发展中是最好的选择。至于这种收益代价的比例在其它操作系统上如何还有待考验。不过我认为其它系统应该保持一种开放的态度。

MacBook Pro 图标

2009/10/10

这几天实在是太忙了,这种状态还要持续一段时间,不过也不会很长。没时间写长的东西。

今天无意发现 OS X 里面 MacBook Pro 的图标很精细(也就是在我的 MacBook Pro 上表示本机的图标)。似乎是严格按照 15 寸的 MacBook Pro 外观设计的。不知道在 17 寸的机器上表示本机(或者在网络上表示 17 寸 MacBook Pro)的图标是否会体现出机型之间的细微差异(还有在网络上能否识别对方是 17 寸的机器)。

睡不得

2009/09/26

睡眠这个功能在计算机上出现很久了。我第一次和『睡眠』打交道是 96 年 —— 那年高考结束买了第一台能运行 Windows 95 的机器。遗憾的是,这台机器睡眠再被唤醒之后所有窗口的滚动条(scrollbar)都行为怪异 —— 只能支持拖动,不能支持在空白处点击来翻页。

这以后我发现『睡眠』实在是一个名存实亡的功能。总是有那么一些必用的软件在睡眠唤醒之后行为怪异。用了 Linux,睡眠更是不用想了 —— 平平常常的对硬件的支持还磕磕绊绊的呢。再说我用 Linux 是为了 hack kernel,自己编译的 kernel 这方面的问题更多。所以每次装完系统,不论是 Windows 还是 Linux,第一件事情就是把硬盘休眠和计算机休眠关掉(屏幕休眠还勉强可以保留)。

用 MacBook (Pro) 有一年多的时间了,最近开始不时尝试把屏幕合上享受一下为地球减少二氧化碳排放的感觉。因为硬件和操作系统都是 Apple 一家控制,还真没发现什么功能上的问题。不过今天在咖啡厅着实又麻烦了一把。每次休眠唤醒之后,都要重新输入一遍咖啡厅网络的密码(那个密码是用 Web 页面输入的,不是 Wifi 的密码,所以还没法保存)。然后就是 Tor 也要重新连接一遍(这几天 60 大庆,Tor 的连接也是磕磕绊绊,本来就心惊胆战。我本来就对 Tor 的重联功能不放心,先在又和咖啡厅的网络密码验证有竞争,结果是 Tor 的出错信息一团糟)。

看来工作的时候打盹确实不是什么提高效率的好办法。

对 Basic 的误解

2009/09/20

事情的开始是上周无意中找到了原本以为丢了的《Go To》。这本书读起来很有意思,比如我从中找到了 C++ 和 COBOL 的相似之处。所以,当初以为弄丢了的时候很失望,这次『失而复得』也很惊喜。接着上次停下的地方开始读下去,很快的结束 UNIX 的章节,进入关于 Basic 语言的历史。

我一直以来认为 Basic 不是一个成功的尝试。对于软件开发人员来说,Basic 很像小孩子用的简易学行车,没有必不可少的需要,用的不好还有让孩子骨骼变形的危险。Visual Basic 也是整个业界一次尝试简化开发的歧路(Delphi 部分的修正了这个错误,不过根本的问题是快速应用开发(Rapid App Development)本身就是一个急功近利的产物。今天,GUI 开发中传统的 RAD 已经接近消亡,取而代之的是 Cocoa、GTK、QT、Flash 等等根基更为稳固的技术)。

这次读《Go To》,发现这完全是对 Basic 语言的发明者 Thomas Kurtz 本意的误解。Kurtz 丝毫没有希望 Basic 成为计算机技术人员的入门语言,他的愿望是希望给文科学生提供一个接触计算机技术的机会。这些文科学生将来并不会从事计算机技术和科学的研究,但是他们更可能在社会生活中作出高层决定。如果他们完全不了解计算机技术,那么他们在一个计算机技术主导的社会中作出的决定是否明智就很成问题。也就是说,发明 Basic 语言的本意是社会层面的,是一次对大众和潜在的高层管理人员的公关行为。(相对来说,在中国推广 Basic 语言的行为有一种误导的倾向。Visual Basic 这种尝试也是对其本意的一种偏离。)从这个意义上说,不但 Basic 语言的结果是成功的,能够提出这个设想本身就说明美国的知识阶层是有远见的。

胡扯!

2009/09/19

这篇文章让我不得不摘录下来:

Steve Jobs 第一次见到 Don Knuth,热情洋溢的说『您的大作我都拜读过。』Knuth 当头一棒『胡扯!(full of shit)』

MacBook Pro 两周

2009/09/15

入手 MacBook Pro 整两周了。这段时间,尤其是这周,几乎所有的时间都花在技术以外的事务上。当然每天读的新闻里还是 IT 新闻占绝大多数,不过除此之外新机器几乎没有用来研究技术。这也不算背离我买机器的初衷 —— 购买之初就已经知道近期花在技术上的时间不会太多。当初买第一台 MacBook 的时候,也是因为非技术的原因 —— 读二战史的时候查阅 Wikipedia 发现 OS X 显示的 Wiki 页面比 Windows 好看好多。

使用 15 寸的高配 MacBook Pro 来做非技术的事务是很舒适的。第一点就是『快』。机器的速度由硬件和软件共同决定。MacBook Pro 15 寸高配的硬件规格是不错的。这倒也不值得特别夸耀,毕竟是将近一万八的机器。市面上相同规格的 PC 笔记本要便宜不少。不过要注意的是,规格相同的 PC 比 Mac 价格便宜的例子不少,而相对的例子——价格相同的 PC 规格更高——是很少的。个人认为原因是按照 PC 的硬件规格/价格比线性发展的话,一万八的机器肯定过于变态,普通用户根本用不上,作为移动设备就更离谱,只会出现如联想双屏笔记本这样的鸡肋怪物 —— 用户对电脑的要求不是简单的硬件功率的堆砌。从这方面说,PC 笔记本只能突出自己价格便宜,但是没办法超越这个硬件档次了。虽然高配的硬件不值得过分夸耀,不过 Mac 的价格也毕竟不是全算在硬件上,而且全铝机身这类噱头也还令人满意,所以硬件方面还是物有所值。

软件方面,Snow Leopard 号称很多操作都比 Leopard 性能提高20% – 50%。最近在新 MacBook Pro 的 Safari 上使用 Net App 比较多(主要是 JavaScript 实现),感觉比在 Dell 390 上的 FireFox 流畅不少(主观感觉似乎比办公室里跑 Leopard 的四核 Mac Pro 还好,这个只能等抽空把 Mac Pro 也 upgrade to Snow Leopard 之后再客观评判了)。加上独立显卡,Expose 和其它窗口管理效果都流畅不少,多个程序之间切换的感觉也很舒服。

第二点是易用性。值得一提的是新的 Expose。作为为数不多的 UI 改进里最明显的一个,Expose 是彻底阻止我返回 Leopard 的决定性因素。新的 Grid 排列在美感上不如原来的按比例随意排列,不过确实让查找程序窗口更容易了。真正使用 Snow Leopard 之前我认为自己肯定会怀念按比例随意排列,用了 Grid 排列之后也只能说舍弃按比例排列的美学享受也算是必要的代价,算是在不能兼得的二者里选了稍强的一个。另外把最小化的窗口和普通窗口同时排列在一起,让用户终于在一个地方就能浏览所有打开的窗口了。其实 Expose 和 Dock 的集成,配合上原来的窗口 hide 功能,可以比较方便的找到各个窗口,也不会让桌面过于凌乱,让窗口最小化这个功能都几乎可以不用了。

Stack 的改进也正在点子上。首先是不论 stack 里有多少 item,stack 展开的时候都不会变成 Leopard 里那种普通 menu 的形式,而是保持一个比较大的图标。这样对 Application 这样的 folder 来说,查找图标更容易了。而且,进入 stack 里的下一级 folder 也不会离开 stack 状态,对于拥有一到两级 sub-folder 的 stack 来说,再也不会打开一堆 Finder 窗口的。原来在 Leopard 里,对于 Application/Utilities 下的应用我一般都借助系统菜单里的『Recent Items』打开 —— 副作用就是必须把 maximum recent item number 从缺省的 10 调大。在 Snow Leopard 下我很少用『Recent Items』了。新的 Expose 和 Stack 让 Dock 的使用频率更高,一个副作用让 Dock 的放大效果的实用价值显得低了一些。打开放大效果之后, Dock 总是晃来晃去,在 Leopard 下不觉得,在 Snow Leopard 里 Dock 的使用更频繁,加上展开后的 stack 和 menu 也跟着晃,弄的我第三天就把放大效果关掉了。

OS X 上的 PC Server

2009/09/12

昨天注意了一下 OS X 上的 PC Server 图标,是一个 blue-screen-death。很有趣。

Mac OS X 的 64 位历程与 UNIX 文化

2009/09/04

64 位支持是 Mac OS X Snow Leopard 操作系统最重要的新特性之一。这往往让人以为 Apple 是初次提供 64 位支持。其实 OS X 的 64 位支持从 Tiger 开始就默默存在了。Apple 一贯的风格是做得多说的少 —— 能把 x86 架构的 OS X 研发保密达 5 年之久,它最喜欢在发布会上宣布的消息是『available now』。

64 位支持并非从 Tiger 开始就一步到位。否则的话,Leopard 和 Snow Leopard 有固步不前之嫌,Apple 对 64 位支持保持 4 年的市场宣传沉默也显得毫无必要。下面这幅图说明了 OS X 系统 64 位支持的发展路径。Tiger 仅仅支持没有 GUI 的 64 位应用,Leopard 仅仅在 user space 提供 Cocoa 的 64 位支持,没有 64 位 kernel。而且这两者都仅仅提供系统级的支持,附带的应用仍然都是 32 位。Snow Leopard 的 64 位达到成熟,附带的应用几乎全部为 64 位,并且提供 64 位 kernel(尽管不是缺省设置)。

有意思的是,OS X 系统在 64 位上循序渐进的发展策略,正好有意无意的遵循了 UNIX 的设计文化关于 GUI 的设计的原则。《The Art of UNIX Programming》在第 11.6 章讨论 UI 设计之前就开宗明义地宣布『UNIX 没有发展出本土的 GUI 设计模式』。确实,UNIX 在这点上保持谦逊,向 MacOS(这里指classic)、NeXTStep和其它 GUI 的先行者借鉴了许多经验(以及后来的 OS X 与 UNIX 的相互借鉴)。不过随后在第 11.6.8 节指出了 UNIX 在 GUI 方面还是发展出了一个最基本的准则 —— 『界面和引擎的分离』。UNIX 提倡把尽可能多的代码放到没有可见 GUI 的进程中(即引擎进程),提供 GUI 的进程和引擎进程通过 Application Protocol 通信。引擎进程一般不与用户直接交互,但是很多引擎程序也提供让高级用户直接调用的接口(比如 CLI 命令)。这样做既符合 UNIX 通过协作的多个进程来降低整体复杂度的原则,还让程序能够同时满足初级用户和高级用户的不同使用习惯。甚至程序本身的自动化测试也更为方便。现实中很多程序都在实践这一原则,比如我们每天都用的 P4V,它本身的 GUI 并不实现和 Perforce server 的通信,而是调用 Perforce 的命令行客户端程序。这样即满足了初级用户,也让高级用户了解 GUI 操作对应的都是哪些命令,方便了 trouble shooting 和重复操作的自动化。设计良好的引擎进程还允许第三方开发更好的或者满足特殊用户需求的 GUI。

如果一个系统无法在一个 release 中实现完全的 64 位支持,那么应该如何决定模块 64 位化的先后顺序呢?以上面的 UNIX 原则为依据来决定的话,就正好是 OS X 系统对 64 位支持的实现顺序(尽管也许是无意的,但是我相信 Apple 内部的 UNIX 大牛们有此特意的考虑)。首先提供对 GUI-less 进程的 64 位支持。这样在界面引擎分离的系统中,引擎部分可以首先 64 位化。其实 64 位化带来的性能和可扩展性(scalability)的改进对于界面进程并没有太大影响,而急需此类提升的引擎进程正好可以先一步利用系统的优势。

到了今天的全 64 位 Snow Leopard 系统,除了安全和整体复杂度的考虑,界面引擎分离的原则是否在 32/64 位架构方面还有作用?仍然有。比如,Dropbox 是一个保证文件在多台机器上同步的程序。它由一个提供同步功能的进程和一个 Finder plug-in 构成。Finder 由 Cocoa 重写并且升级为 64 位之后,plug-in 停止工作,所以无法使用 Finder 右键菜单中的 Dropbox 功能,但是提供同步功能的进程仍然可以工作。Dropbox 的引擎界面分离让失败降低到最小的程度。Safari 升级到 64 位之后,很多第三方的 plug-in 仍然没有来得及跟进。但是这些 plug-in 的重要性让 Apple 没有办法说服用户以抛弃它们为代价享用 64 位。所以 Safari 采取了一种特殊的界面引擎分离。把 32 位的 plug-in 放置在单独的、32 位的虚拟 Safari hosting 环境的进程中运行。这些 32 位虚拟 Safari hosting 进程和 64 位的 Safari 通过 application protocol 通信 —— 称之为 out-of-process plug-in。即便如 Flash 视频这样的应用,以今天的硬件性能来通过 IPC 在两个进程间传输数据也无损用户体验。这样做在满足了 32/64 位架构兼容的同时也提供了进程协作的一贯好处 —— 安全、稳定(单个 plug-in 崩溃不会影响整个浏览器)和易于维护(容易定位 bug)。即便今后有 64 位 plug-in 出现,这些好处仍然会促使 Safari 和其它应用采用 out-of-process plug-in 技术。

Snow Leopard 引入 64 位 kernel 也让另一个利用普通进程技术的优势体现出来。TOR(洋葱路由)基于 SOCKS Proxy 技术,所以它的 client 端实现是一个监听特定端口(一般是 9050)并提供 SOCKS 服务的普通进程。Cisco VPN 基于虚拟以太网技术,所以它的 client 端实现是一个虚拟的网卡驱动,运行在 kernel space。当 kernel 升级为 64 位而 Cisco VPN client 无法跟进的时候,用户只好放弃使用其一 —— 退回 32 位 kernel 或者不使用 VPN。而基于普通进程的 TOR 则不受影响。同样,基于普通进程的 SSH tunnel 技术也不受 kernel 64 位升级的影响。同样是提供加密的传输功能,基于普通进程的技术显示了灵活性。

计算机系统各个部分的发展永远呈现不同步的状态。OS X 的 64 位化过程清晰而富有趣味性的重申了这一点。软件应对这一永恒趋势的唯一手段就是把自己分割成一个个功能简单,可以独立替换,甚至在某些其它模块缺失的时候仍然可以正常工作的模块。这是 UNIX 的基本设计原则之一,利用 application protocol 进行协作的进程就是 UNIX 实践这个原则的工程传统。那些在 Tiger 上就利用了 GUI-less 64 位支持的程序、那些在 Leopard 上来不及把 GUI 升级为 Cocoa 的程序、还有 Snow Leopard 上的各种成功和失败的例子都在重申这一原则的重要性。UNIX 诞生于资源奇缺的计算环境。因此演化出『沉默是金』这样的传统(尽管今日沉默是金是因为有了其它的优势而被遵守)。但是同时也顽强的保留了多进程协作这样看似『奢侈』的传统。不能不惊叹于 UNIX 文化的预见性和适应性。

64位的光驱

2009/09/04

今天在 MacBook Pro 上检查以前备份在光盘上的数据,发现有些明明有数据的盘放进光驱之后 OS X 就报告『插入新盘,刻录、弹出、还是忽略』。大惊失色!但是同时期刻录的盘里大多数还是能读的。而且被错认成空白盘的光盘无论放进去多少次都是一样失败。想想不可能人品这么差,新买的硬件就出问题。而且就那么几张稳定的被错认,更像是光盘格式的问题。

仔细想想到底自己做过什么离经叛道的事情。于是把 Boot.plist 里的『arch=x86_64』删掉(见《终于 Pro 了》)。重启之后,被认错的盘又被正确读出了。看来问题在于 DVD 光驱的 64-bit driver。检查了 DVD 光盘,发现在 64-bit kernel 状态下错认的盘和能读出的盘都有 DVD+R 格式的。本来怀疑是 DVD+R 和 DVD-R 的差异,现在被排除了。可能是 64-bit DVD driver 不支持一些更细微的格式差异,比如一次写入和多次写入,不过已经没有时间细察了。

Apple 的 64-bit kernel 支持确实还没有成熟。所以 Apple 把 Snow Leopard 的缺省启动设置成 32-bit kernel。希望 Apple 能在以后的 update 中赶紧完善。不过总的说来我大概两三天才用一次光驱,所以把还是可以把缺省 arch 定为 x86_64 —— 除非又发现了别的 break。