TONT 33083 当标记的含义中途发生变化的时候

原文链接:https://devblogs.microsoft.com/oldnewthing/20051206-10/?p=33083

The project leader for the initial version of Internet Explorer was well-known for wearing Hawaiian shirts. I’m told that the team managers decided to take one of those shirts and use it as an award to the team member who fixed the most bugs or some similar thing. What the team managers failed to take into account that nobody actually liked having a Hawaiian shirt hanging in their office, especially not one that was worn by somebody else. If you happened to be the person who fixed the most bugs, you sort of reluctantly accepted the shirt even though you really didn’t want it.

Internet Explorer 早期版本的项目领导人的夏威夷衫装束在公司内人尽皆知。团队管理者告诉我,他们决定拿其中一件衬衫当奖励,奖给修复了最多bug或者做了类似贡献的团队成员。但是团队管理者没有考虑到的是,并没有人喜欢在办公室里挂一件夏威夷衬衫,尤其是被别人穿过的那种。如果你碰巧修复了最多的bug,就得不怎么情愿地接受一件衬衫,即便是你并不怎么想要它。

And then a wonderful thing happened: The meaning of the shirt flipped.

然后就发生了一件奇妙的事情:衬衫的含义来了个180度的转变。

I don’t know the details. I suspect at one point, somebody who “won” the shirt just left it in somebody else’s office as a way of getting rid of it. This simple gesture was the turning point. The shirt became a symbol of disapproval. I believe the unofficial rule was that in order to get rid of the shirt, you had to find somebody who messed up at least as bad as whatever you did to earn the shirt in the first place.

我不知道事情的详细经过,估计是在某个时候,某个『赢得』了这件衬衫的人干脆把它留在了别人的办公室里,权当一种丢弃的方式。如此简单的一道行为成为了转折点,衬衫变成了不赞成的标志。我觉得这条不成文的规定是,要想把衬衫推给别人,你得找一个像自己一样因为把事情搞糟(至少跟自己的程度差不多)、因而被塞给了这件衬衫的人。

It took a while before the team managers even realized what happened to their “award”.

团队管理者过了好一阵子才发现自己的『奖励』变成了什么样子。

TONT 33103 将软盘用作信号量标记

原文链接:https://devblogs.microsoft.com/oldnewthing/20051205-09/?p=33103

In the very early days of Windows 95, the distribution servers were not particularly powerful. The load of having the entire team installing the most recent build when it came out put undue strain on the server. The solution (until better hardware could be obtained) was to have a stack of floppy disks in the office of the “build shepherd”. (The job of “Build Shepherd” was to perform the initial diagnosis of problems with the build itself or with verification testing and make sure the right developer is called in to address the problem.)

在 Windows 95 研发的初期,用来发版的服务器性能并不算强大。当新版本发布后,整个团队都去上拉取最新构建版本进行安装这件事对服务器造成了可观的压力。解决方法(在换用更强力的硬件之前)是在『构建牧羊人』的办公室里放置一摞软盘。(『构建牧羊人』的工作是对构建版本、或者验证测试进行初步的问题筛查,并确保对应的开发者能被及时叫来处理问题。)

If you wanted to install the latest build, you had to go to the Build Shepherd’s office and take one of the specially-marked floppy disks. When you finished installing, you returned the disk.

假如你想安装最新的构建版,你就需要去构建牧羊人的办公室里去取一张做了特殊标记的软盘,等安装完之后,再把软盘送回去。

In other words, the floppy disk acted as a real-world semaphore token.

换句话说,这些软盘变成了现实世界中的信号量标记。

TONT 33243 为什么(有时)UNC路径的开头允许有盘符?

原文链接:https://devblogs.microsoft.com/oldnewthing/20051122-15/?p=33243

A little-known quirk is that the file system accepts and ignores a drive letter in front of a UNC path. For example, if you have a directory called \\server\share\directory, you can say

有个鲜为人知的奇怪设计是,文件系统接受(并会忽略)UNC 路径的开头包含盘符。例如,如果你有个目录(的共享路径)是\\server\share\directory,你可以输入

dir P:\\server\share\directory

and the directory will be listed to the screen. The leading P: is ignored.

目录内容会成功列出,开头的 P: 被忽略了。

Why is that?

这是为什么呢?

Rewind to 1984 and the upcoming release of MS-DOS 3.1, which added networking support. Up to this point, all fully-qualified file specifications consisted of three components: A drive letter, a path, and a file name. Many programs relied on this breakdown and did things like “helpfully” prepend a drive letter if it looks like you “forgot” one. For example, if you told it to save the results to \\server\share\file.txt it would say, “Oh dear, that’s not good, the user forgot the drive letter! I’ll put the current drive in front to make things better,” resulting in C:\\server\share\file.txt. Other programs would prompt you with “Please enter a drive letter”, and you couldn’t say “No, there’s no drive letter, just take the path and use it.” They insisted on a drive letter, and you darn sure better give them one.

回到 1984 年,MS-DOS 3.1 即将发布,该版本新增了网络支持。到这时为止,所有完全限定的文件规范包含三个组成部分:盘符、路径和文件名。很多应用程序都依赖这种组合方式,并且如果路径看上去是用户『忘了』录入盘符的话,还会在最前面『帮忙』加上一个。例如,如果用户指定将数据保存到 \\server\share\file.txt,程序就会认为:『哎呀,这怎么行,用户忘了写盘符了!让我在最前面加上当前驱动器的盘符,这样就好了』,路径就变成了 C:\\server\share\file.txt。另外也有程序会提示用户『请输入盘符』,而用户无法告诉程序『不不,这个路径里没有盘符,直接用这个路径就行了』。程序是一定要一个盘符的,而用户不给是不行的。

(Compare the Unix programs that “helpfully” rewrite //server/volume/file as /server/volume/file because they “know” that consecutive slashes collapse, unaware of the special exception for two leading slashes.)

(相较之下,UNIX 程序则会『帮忙』将 //server/volume/file 重写为 /server/volume/file,因为他们『知道』连续斜线应当进行合并,但却不知道两道斜线开头是个例外。)

In order to retain compatibility with programs that provided this sort of “unwanted help”, the designers of the networking support in MS-DOS decided to allow the strange syntax C:\\server\share\directory and treat it as if the drive letter simply weren’t there. Some (but not all) of this quirk of path parsing persists today.

为了保持与提供这种『毫无必要的帮助』的程序的兼容性,MS-DOS 网路支持功能的设计者们决定允许 C:\\server\share\directory 这种奇怪语法的存在,并将其视为开头的盘符

TONT 33303 硬塞狗粮

原文标题:Force-feeding the dogfood

原文链接:https://devblogs.microsoft.com/oldnewthing/20051117-11/?p=33303

Windows 95 contained some new networking features, and since I was one of those crazy people who sampled every flavor of dogfood in the store, I actually tried out all of them. One of the features, a network protocol, I thought was interesting enough that I decided to help them out by forcing everybody else on the team to dogfood it.

Windows 95 包含了一些新的网络功能。鉴于我是会遍尝店里每种口味狗粮的那种人(译注:见上一篇),我是真的都试了一个遍。对于其中一个功能(某个网络协议),我觉得它很有趣,最终使我决定通过让团队里的每个人都尝一尝这份狗粮的味道的方式,来帮助对应团队的人将它做好。

Here’s how I did it.

以下是我的做法。

I had a bunch of debugging documents and other materials that people generally found useful. I put them on my machine, which acted as a file server. Anybody who wanted these files had to install the network protocol in order to get them. And the files were valuable enough that people were willing to take a chance on a new network driver just to get them. Not only did the client side of the driver get a lot of dogfood test coverage, so too did the server side, since my computer would be servicing a lot of simultaneous connections from people reading my documents. I remember finding a variety of interesting bugs this way. (And of course I ran stress over this protocol.)

我手里有一套调试用的文档、以及其它一些资料,对开发人员来说都很有用。我将这些资料放在我的机器上,并让我的机器作为一台文件服务器。任何想要获取这些资料的人,都得安装这个网络协议才能访问它。这些资料的价值,已经高到人们宁可安装一套新的网络驱动也要拿到它的程度了。如此,这个驱动不光在客户端一侧被尝了个遍,在服务端一侧也一样,因为我的机器对前来阅读这些资料的人们同时建立了大量的连接。我记得通过这种方式,得以发现了几个有趣的bug。(当然了,我也有对这个协议进行压力测试。)

I later became friends with the lead tester for the protocol, and he told me that my simple act of force-feeding the dogfood to every other member of the Windows 95 team was a key element of making their feature a success.

后来我跟这个协议的领头开发者成了朋友,他告诉我,我这种让 Windows 95 开发团队的每个人都被强塞一遍狗粮(译注:咳咳)的做法是令他们研发的功能成功的关键元素之一。

TONT 33323 遍尝商店里每种口味的狗粮

原文标题:Sampling every flavor of dogfood in the store

原文链接:https://devblogs.microsoft.com/oldnewthing/20051116-12/?p=33323

During the development of Windows 95, everybody was, of course, self-hosted and upgraded the operating system on a regular basis as new builds came out. I took it upon myself never to install the operating system twice the same way. Each time I ran setup, I would give different answers to the questions. Maybe this time, I’ll leave out Wordpad and bind NetBIOS over TCP/IP to my Xircom parallel-port network adapter. Or maybe I wouldn’t choose any networking drivers at all during setup and try to add them later. Towards the beginning of the project, nearly every run of setup would run into some strange problem, and some developer from whatever component I decided to configure randomly would be in my office at the debugger trying to figure out what happened. (Fortunately, as the project matured, the problems were rarer and rarer.)

在 Windows 95 的研发过程中,伴随着新编译版本的发布,每个人都时常对手里的版本自行托管、自行升级。我的做法则是从来不用同一种方法运行安装程序两次。每次我运行安装程序的时候,我都会对安装程序给出的提问做出不同的回答。可能这次,我会选择不安装写字板,然后把 NetBIOS over TCP/IP 协议配置在 Xircom 并口网卡上,下次则可能在安装时什么网络驱动程序也不装,等装完系统后再进行配置。在整个开发流程最开始的时候,几乎每次运行安装程序都会遇到一些奇怪的问题,然后负责我随机挑选进行配置的某个组件对应的开发者就会来到我的办公室,打开调试器,试着搞清楚到底发生了什么事。(幸而随着整个工程逐渐成熟之后,类似的问题也变得越来越罕见了。)

I was, you might say, sampling every flavor of dogfood in the store.

也可以说,我这是在遍尝商店里每种口味的狗粮。(译注:Eat your own dogfood 字面意思是『吃自家的狗粮』,在软件开发中,则指『自己开发的产品,自己得先用』,即进行内部测试。)

I would also do crazy things for nightly stress runs. My favorite was to run stress over a parallel port direct cable connection. I don’t think it ever occurred to anyone to test DCC quite this way.

有时在进行连夜的压力测试时,我也会搞一些疯狂的事情。我最喜欢的一个案例是在并口的直接电缆连接上运行压力测试,我个人认为不会有人把测试直接电缆连接功能这件事搞得那么绝。

TONT 33353 Dr. Watson 原来叫什么名字?

原文链接:https://devblogs.microsoft.com/oldnewthing/20051114-00/?p=33353

What most people probably don’t know is that Dr. Watson’s name wasn’t originally “Dr. Watson”.

大多数人可能不知道的是,Dr. Watson 的名字原本并不是 Dr. Watson。

The original name of the diagnostic tool was “Sherlock”, whose icon was a lit drop-stem pipe. I remember chatting about the Doctor with its author, the late Don Corbitt, whose office was just a few doors down from mine. In 1991, he had to change the name from “Sherlock” to “Dr. Watson”; I had forgotten why, but Danny Glasser came to my rescue and reminded me that there was already a debugging tool called “Sherlock” that had come out a few years previously. The name had to change, and the Doctor stepped in to fill Sherlock’s shoes. The icon was originally a doctor’s bag, but it changed to the stethoscope-wielding general practitioner a few months later.

这个诊断工具原来的名字是『夏洛克』(Sherlock),图标则是一只点燃了的烟斗。我还记得跟小 Don Corbitt、也就是这个软件的作者聊起过这件事,他的办公室跟我就隔着几道门。1991 年的时候,他不得不把他的工具从 Sherlock 改名为 Dr. Watson。我已经忘记为什么了,不过 Danny Glasser 帮了我一把,让我想起是因为几年前已经有一个调试工具用过 Sherlock 这个名字了。名字非换不可,于是华生博士(Dr. Watson)就顶替了夏洛克(Sherlock)的位置。新工具原本的图标是一个医师手提包,不过过了几个月就换成戴着听诊器的医生的形象了。

You should also check out Matt Pietrek’s reminiscences about Dr. Watson.

我在这里也推荐 Matt Pietrek 对于 Dr. Watson 的回忆文章。

A note about Don Corbitt. He was a tall fellow with a deep booming voice, but he never used it. Instead, he spoke in a gentle, reassuring tone, backing it up with code that was always solid. I consider it an honor to have worked with him. Taking up the mantle of keeping the Doctor up to date with the latest forensic techniques, I updated it (i.e., rewrote it from scratch) for Windows 98. I was not a member of the Windows 98 team but wrote the program as a favor to them at great personal cost. (My then-boss didn’t approve of my little side project and made his displeasure known at my next performance review.)

这里还要提一下 Don Corbitt,他是个声音低沉的高个子,不过他不怎么用这种音调说话,而是用一种礼貌而令人安心的语调与人交谈,在协助我编写代码方面非常靠得住,我认为跟他共事是一种荣誉。为了肩负起让 Dr. Watson 保持更新的责任,我面向 Windows 98 对其作了更新(也就是从头重写一遍)。我并不是 Windows 98 开发团队的一员,不过还是花费了自己很大的功夫做好了这件事来向 Windows 98 团队表示支持。(我那时候的上司对我这么做并不感冒,并且在之后的一次效率评审会上表达了这种不满。)

 

TONT 33423 GlobalWire 的名字是怎么来的?

原文链接:https://devblogs.microsoft.com/oldnewthing/20051108-05/?p=33423

John Elliott wondered why the GlobalWire function was called GlobalWire.

John Elliott 想知道为什么 GlobalWire 函数起了这么个名字。

First, some background for those who never had to write 16-bit Windows programs. The GlobalWire function was similar to the 16-bit GlobalLock function, except that it had the bonus feature of relocating the memory to the lowest available linear address. You used this function as a courtesy if you intended to leave the memory locked for a long time. Moving it to the edge of the address space means that it is unlikely to become an obstacle in the middle of the address space which would otherwise prevent future large memory allocations from succeeding.

首先,给从来都不需要撰写 16 位 Windows 应用程序的人一点背景资料。GlobalWire 函数与 16 位函数 GlobalLock 类似,不过还有将内存块移动到可用的最低线性地址的附加作用。调用这个函数意味着你想让某部分内存锁定较长的一段时间。将内存块移动到地址空间的边缘,使得这块内存不会成为不上不下地横亘在地址空间的一部分,以期未来的大块内存分配不会失败。

But why “wire”?

不过『wire』这个写法又是怎么回事呢?

This employs a colloquial sense of the word “wire” as a verb which has lost its currency in the intervening years. To wire means to fasten securely in a very strong sense. It probably derives from the phrase “hard-wired”, which means “permanently attached in circuitry”. Therefore, “wiring” memory into place ensures that it doesn’t move around.

这里是借用了 wire 这个词作为动词的口语说法,而这种用法这些年大概逐渐式微了。『To wire』意味着将某物『紧紧绑住』的一种强烈语气,可能是来自短语『hard-wired』,含义是『在电路中永久固定』。由此,将内存『捆绑』在某处就是期望其不会到处乱跑。

TONT 33473 要做领导者,必须知道何时应当跟从

原文链接:https://devblogs.microsoft.com/oldnewthing/20051103-43/?p=33473

Many people misinterpreted my use of the term “reluctant” to describe the attitude of the designers in changing the way the Date/Time control panel functions. It was a reluctance of shame, not a reluctance of defiance.

很多人错误地理解了我对修改日期/时间控制面板功能中设计人员的『不情愿』的含义。这里的『不情愿』指的是羞愧心,而不是抗拒心。

Your software is there for the users, not vice versa. If you find that your users are using the software in a manner contrary to its intended purpose, your first reaction may be to try to educate users not to do whatever it is they’re doing. But eventually you reach a point where the efforts in convincing people not to do something dangerous outweighs the cost of just making it less dangerous. (Even though this may annoy those who genuinely want to perform that dangerous activity.)

你的软件是为了用户而生的,但并不是说反之亦然。如果你发现用户在使用你的软件时,总是与你的设计初衷相悖,你的第一反应可能是去指导用户不要这么做。但是,迟早你会发现教给用户不要做什么的成本大大高于让你的设计更加合理。(虽然这会让刻意做这些操作的人感到恼火就是。)

You may not do it with a smile on your face (hence the reluctance), but you know deep in your heart that it’s the right thing to do.

可能做出这些修改的时候,你的脸上不会带着笑容(也就是所谓的『不情愿』),但在内心深处你也明白这才是正道。

Side note: Why did the Date/Time control panel apply changes immediately anyway? Historical artifact. That’s the way the Date/Time control panel has worked since Windows 1.0. In fact, originally, the Date/Time control panel didn’t even have a Cancel button. Any changes you made to the time took effect immediately and irrevocably. (Mind you, MS-DOS and the original Macintosh did the same thing.) It wasn’t until after Windows 95 shipped that this behavior started being a problem.

再说个小故事:为什么日期/时间控制面板会立刻应用修改呢?这是历史上一以贯之的设计,也是日期/时间控制面板从 Windows 1.0 起的设计。实际上,原本日期/时间控制面板连『取消』按钮都没有,任何对时间的修改都立刻生效、无法撤销。(小提示:MS-DOS 和原始的 Macintosh 都是这么设计的。)但是直到 Windows 95 发布后,这样的设计才成为了一个问题。

TONT 33503 为什么行内自动完成功能默认是关闭的?

原文链接:https://devblogs.microsoft.com/oldnewthing/20051102-48/?p=33503

Earlier versions of Internet Explorer used inline autocomplete, but newer versions use drop-down autocomplete that requires you to press the down-arrow key to select an item from the drop-down. Why the change?

早期版本的 Internet Explorer 启用了行内自动完成,但新版本改成了下拉列表式的自动完成,需要用户按下箭头键来在列表中选择一项。为什么会有这种变动呢?

Because it interferes with normal keyboard operation.

因为先前的设计影响了正常的键盘操作。

Suppose http://www.microsoft.com/windows/ is in your history, but you want to go to http://www.microsoft.com/. As you type the desired destination, inline autocomplete kicks in and fills in the remainder of the URL for you, http://www.microsoft.com/windows/. If you aren’t watching the screen and just hit Enter, you end up going to the autocompleted URL instead of the URL you typed. Oops.

假设 http://www.microsoft.com/windows/ 在你的浏览记录中,但你想浏览的是 http://www.microsoft.com/。当你在地址栏中输入要访问的网址时,行内自动完成发挥了作用,帮你补全了余下的部分,(使网址变成了)http://www.microsoft.com/windows/。如果你(低头敲键盘)没看屏幕就直接按下了回车键,结果就是访问了自动完成给出的 URL 而不是你录入的网址。哎呀。

To me, this is a fatal flaw, namely that one has to be watching the screen to perform an operation that one would think consisted purely of typing. In particular, this creates problems for people with limited visual capability who necessarily “type blind” most of the time.

对我来说,这是个难以接受的缺陷,使得一项让只管录入就能完成的工作,变成了需要盯着屏幕才能完成的情况。尤其是针对事实上总是在『盲打』的视弱用户而言,便是一个大问题。

Even using Tab as the autocomplete character suffers from the same flaw. Consider the Run dialog or IE’s address bar. In those places, the Tab key moves you around the window. (To the OK, Cancel, and Browse buttons on the Run dialog, or into the web page itself for IE.) If the Tab key were the autocomplete completion key, it wouldn’t be possible to Tab around the dialog/window any more. For example, suppose you want to browse around your C drive, so you type C:\ into the Run dialog and hit Tab three times to get to the Browse button. But, oops, the Tab key autocompletes, so instead of browsing C:\, you’re browsing whatever directory in your C: drive the autocomplete engine decided to show you.

就算将自动完成功能改成用 Tab 键,也会产生同样的问题。考虑在『运行』对话框或 IE 的地址栏里,在这些地方,Tab 键会将你的焦点移动到其它控件上。(例如在『运行』对话框中移动到『确定』、『取消』或『浏览』按钮上,或者在 IE 中移动到网页上去。)如果让 Tab 键作为自动完成的案件,那么就无法再用其在对话框或窗口中的控件之间进行切换了。举个例子,假设你想浏览C盘的内容,于是你就在『运行』对话框中输入了 C:\,然后按了 3 下 Tab 键想移动到『浏览』按钮上,然而这时 Tab 键是自动完成键了,于是你输入的路径就变成了自动完成引擎帮你决定的、你的 C 盘中随便哪个目录的内容,而不是浏览 C:\ 的内容了。

TONT 33593 为什么 OEM 代码页经常被称作 ANSI?

原文链接:https://devblogs.microsoft.com/oldnewthing/20051027-37/?p=33593

It has been pointed out that the documentation for the cmd.exe program says

Cmd.exe 的文档中曾指出,

/A Causes the output of internal commands to a pipe or file to be ANSI

/A 选项使内部命令输出至管道或文件时使用 ANSI

even though the output is actually in the OEM code page. Why do errors such as this persist?

——不过实际上是用 OEM 代码页输出的,为什么这种错误会不断出现呢?

Because ANSI sometimes means OEM.

因为 ANSI 有时候指的就是 OEM。

The “A” versions of the console functions accept characters in the OEM code page despite the “A” suffix that would suggest ANSI. What’s more, if you call the SetFileAPIsToOEM function, then “A” functions that accept file names will also interpret the filenames in the OEM code page rather than the ANSI code page.

『A』版本的控制台函数接受在 OEM 代码页中的字符,即便『A』这个前缀指的是 ANSI 也一样。此外,如果你调用 SetFileAPIsToOEM 这个函数,那么接受传入文件名的『A』系的函数同样会使用 OEM 代码页、而不是 ANSI 代码页来解析文件名。

“There are two types of people in the world: Those who believe that the world can be divided into two types of people, and those who do not.”

『这世上有两种人:相信人们可以被分成两种人的,和不相信的。』

There are those who mentally divide the world of characters into two groups: Unicode and 8-bit. And as you can see, many of them were involved in the original design of Win32. There are “W” functions (Unicode) and “A” functions (ANSI). There are no “O” functions (OEM). Instead, the OEM folks got lumped in with the ANSI folks.

这世上也有在精神上将字符世界一分为二的人:不是 Unicode 就是 8 位字符集。并且与此同时,这类人中的许多也与 Win32 的原始设计相关联。有『W』系函数(Unicode)(译注:W 指 Wide),也有『A』系函数(ANSI),就是没有『O』系函数(OEM),OEM 字符集的认同者们被与 ANSI 字符集的拥趸们撮成了一堆。

There are also those who realize the distinction, but out of laziness or convenience often use “ANSI” as an abbreviation for “an appropriate 8-bit character set, determined from context”. In the context of console programming, the appropriate 8-bit character set is the OEM character set.

这世上也有人能分清(这三种字符集)的区别,但出于懒惰或便利,经常使用『ANSI』来指代『某种8位字符集(依据上下文来确定)』。在控制台应用程序的上下文中,对应的8位字符集指的就是 OEM 字符集。

The person who wrote the online help for cmd.exe clearly meant ANSI to mean “That thing that isn’t Unicode.”

给 cmd.exe 撰写线上帮助信息的人,实际上想让 ANSI 指代的是『不是 Unicode 的那种字符集』。

/A Causes the output of internal commands to a pipe or file to be ANSI

/A 选项使内部命令输出至管道或文件时使用 ANSI

/U Causes the output of internal commands to a pipe or file to be Unicode

/U 选项使内部命令输出至管道或文件时使用 Unicode

I’ll leave you to decide whether this author belongs to the “Everything is either Unicode or ANSI” camp or the “just being casual” camp.

至于写这个帮助信息的人是属于『这世上的字符不是 Unicode 就是 ANSI』还是『俺就素懒』阵营的,就留待您自行评说了。