CS巴别塔(1)

说说用户界面那些事——鸣雷篇

Posted in Uncategorized by Kenny Yuan on 2012/01/10

聪明的一休哥片段

一休哥提问:这些界面设计有什么共同之处?

图像

小叶子回答:So called “Hermann Grid Illusion”

参考:

Tagged with: , ,

我们正处在一场革命中——Mobile Market观察笔记(序)

Posted in Uncategorized by Kenny Yuan on 2011/05/09

——那是在2010年的春季,因为全球变暖,所以那是一个寒冷的春季。有一家叫摩根士丹利的投行,公布了他们对移动市场的预测:移动互联网市场大有可为,设备数量将十倍于桌面互联网时代。

——那是在2011年的春季,因为全球变暖,所以那也是一个寒冷的春季。有一家叫凯鹏华盈的投行,公布了他们对移动市场的趋势分析:从1960年代到现在,每隔十年,业界就要重新洗牌。而每次洗牌,必将会成就一批人(公司),也会倒下一批人(公司)——那么:谁将是下一批的成就者

本系列文章打算引用市场上公开的数据,对Mobile Market进行一次定量的介绍与分析,并对未来进行一些预测。

在正式开始之前,请让我首先说出我的感受——我们正处在一场革命中!

Tagged with: ,

Windows你在哪里?在哪里呀在哪里?

Posted in Uncategorized by Kenny Yuan on 2011/05/08

这是一篇吐槽的BLOG。

总有很多搞IT的人(特别是程序员)恨不得微软立刻死(一般是Linux和Mac的粉丝),他们有各种各样的理由,许多都很宏大、很冠冕堂皇。但是我一般不会买帐,因为我相信diversity之美,并且我比那些偏激的程序员们略微多了一点点常识,知道我们现在的这个世界,是由Windows来支撑着的

以下全是一些常识的列举:

采矿冶金,离不开Windows(包括生产管理如作业面规划分析、钻机控制、熔炉管理,和信息系统)
电力生产,离不开Windows(包括生产管理,信息系统等)
石油开采,离不开Windows(包括油井生产管理,石油勘探,wellbore规划和分析等)
物流运输,离不开Windows(包括管理终端,集装箱装载规划,通讯调度等)
银行金融,离不开Windows(包括ATM机,柜台终端,交易终端等)
零售餐饮,离不开Windows(包括计费系统,仓库/座位管理等)
仪器仪表,离不开Windows(包括高端仪器本身,仪器的设计制造过程等)
生产管理,离不开Windows(包括各种ERP系统,财会系统,车间管理终端等)
卫生医疗,离不开Windows(包括各种仪器本身,仪器设计制造过程,HIS系统等)
教育教学,离不开Windows(这个还用举例么?)
交通管理,离不开Windows(交通监控,机场/铁路流量规划控制,救援系统等)
娱乐传媒,离不开Windows(电视电影节目采编,后期制作,广告设计制作展示等)
垃圾处理,离不开Windows(嗯,其实在中国是离得开的)
2012年6月14日更新——美军的无人机,离不开Windows(嗯,现在正在开始转向Linux了)Source
2012年7月30日更新——西门子出品的核设施,离不开Windows Source

……这个单子还可以列得很长。试想,如果没有了Windows,这些行业要如何才能运转?

(我知道有些人会不服气,他们会认为,这样“高端”的应用,肯定不会用的是Windows……其实现在网终上的各种行业信息已经有很多了,每个人都完全可以去搜索一下,看看在我上面列举的这些行业,什么操作系统才是主流的。当然,我也可以给出部分软件的列表和截图等等,但是目前我不打算这样做)

嗯,再加一条:中国军方的高科技系统,离不开Windows……

在这些领域,Linux也许可以代替Windows,但这么多年,Linux也只在服务端发展得不错,因为运维人员可以玩得转Linux,而普通用户却不行(在这里我不打算论述,只说些例子:某些机构为了省钱,全面采用Linux,但最终发现总体费用太高,还不如买Windows划算,于是又换回了Windows)。

Mac OS是无法替代Windows的。之所以我敢这样说,还是因为它是不开放的。可能有些人又要对此说法嗤之以鼻,但开放这个词的意义,远比一些爱走极端的人所能理解的要有意义。还是举几个例子吧,比如你无法制造一个示波器,然后把Mac OS装到其中(装一台完整的Mac机器进去是行不通的);你无法制造一台ATM机,里面安装Mac OS(同样,一台完整的Mac机器也是不可取的方案);你无法制造一个大广告牌,然后安装Mac OS(这种方案里,理论上可以嵌一台完整的Mac机器到里面,但是成本会增加很多,机械设计和散热方案还需要额外更改——所以苹果商店橱窗里用的展示系统一般也是基于Windows的)……

这么多的现有系统,在Windows上的投入,应该是一个天文数字。所以目前最合理的选择还是让它继续下去,支撑着我们的世界继续运转。

那么未来呢?近期的未来似乎是比较确定的,长远的未来,又有谁能说得清呢——想想30年前的电脑是什么样子的……

补充:有人提到Mac在增长,Win在失势。其实全球的统计数据是这样的,2010年全球个人电脑出货量是368MM,其中Mac占4MM14MM,也就是1.08%3.8%,所以Mac还是有点任重道远的。

再补充:中国人似乎一般都喜欢看作者也表个态,以便划分一下立场?其实我也很烦现在的Windows(很多方面,不一一列举了),只不过我觉得个人喜好不应该影响对事物的认知——不能因为我不喜欢它,就说它快要完蛋了(甚至像有些人那样说它已经完蛋了)。

面试宝典3:计算机体系结构

Posted in Uncategorized by Kenny Yuan on 2010/10/31

(这段声明还是加上比较好:此《宝典》系列虽然名为“宝典”,但写的都是一些“不知道就别出来混”的基础知识。这一篇也仍然还是基础中的基础,而并非是什么高级货色——任何一个合格的在校本科生,学过计算机体系结构这门课的,都要懂得多得多——在我看来唯一可被理解的例外是那些在当年上学时,被劣质教材和老师害了的人。本文末尾有一本推荐的书籍,建议此类人士进补)

Human-Architecture

Human-Architecture

让我们来假设,有那么一天,作为软件工程师的你,面对这样一道Computer Architecture面试题:

程序在运行时,计算机内部到底会发生什么样的事情?

在继续阅读之前,请你先回想一下相关知识,并估算一下所涉及知识点的数量:

A. <10个;

B. 10-50个;

C. 50-100个;

D. >100个

请选择: ______。

……

以下,是我的回答(非标准答案,供参考):

首先是要搞清楚这台机器具有什么类型的ISA。ISA有四种:Stack,Accumulator,Register-Memory,Load-Store。现代的处理器都是Reg-Mem或者Load-Store的,或者说:有一些ISA,表面上是Reg-Mem这样的一只被汇编程序员所喜爱的喜羊羊,实际上它也是一头Load-Store的灰太狼(例如x86就是在CPU内部进行翻译的)。Stack类型的ISA似乎已经没有流行的硬件了,但是在许多Virtual ISA——也就是在各种高级语言虚拟机(HLL VM)中,却非常地流行。究其根本原因,应该是为了在各种不同的机器上移植的方便(因为这种结构对寄存器没有特别的要求)。

如果是Load-Store的ISA,那么可以肯定它是一个RISC处理器,那么它必有pipeline。例如经典的MIPS的5段流水线(ARM是3)。前面刚刚说过,不仅仅是RISC处理器,连x86也是把翻译出来的RISC操作码发射到超标量流水线中。这些辛辛苦苦翻译出来的操作码会用一个cache来缓存,名为trace cache。如果是RISC指令,因为其格式固定,还可以对其进行固定位置解码(fixed-field decoding)。在pipeline中,也有一些对软件透明,所以不太出名的部件,比如pipeline register,用来在各个stage之间传递数据。

pipeline不是随时都在满负荷工作的,时不时地会有一些停顿(stall),比如:因为结构冒险(structural hazard)引起的停顿。结构冒险是流水线冒险的一种,举例说明:如果register file的并行读写操作太多,port已经用光了,那么就会有一个停顿插入流水线;如果指令和数据都是存在同一个存储器中(冯·诺依曼结构),在同一时刻内又有WB(写回数据)和IF(取指令)的冲突,那么就需要插入一个停顿(也叫pipeline bubble)。哈佛结构不存在这种限制,而现代的冯·诺依曼处理器将Data Cache和Instruction Cache分开,也没有这种限制了(是的,不光是CISC和RISC,哈佛和诺依曼的界限也不是那么清晰了)。

(上面说到了存储器,我们先记下,一会接着再说它,否则就失去连续性了)

引起pipeline stall的原因,除了structural hazard,还有可能是control hazard控制冒险,比如各种转移(branch)。有了转移,就需要对转移进行预测,以便提高效率,否则流水线的损失太大太大。一般常用的转移预测(branch prediction)有这样几种:2-bit历史预测,多级相关预测(比如2级2bit 4KiB)。要进行这些预测,就需要额外的存储,一般CPU内建有BTB也就是branch target buffer。有些CPU中有多个这样的BTB,用于不同的预测,比如有的专门用来预测局部的转移(local branch prediction)。

有些转移是无条件的,比如call和jmp(goto),在现代处理器中对这种无条件的转移基本可做到不需耗费额外时钟周期。还有一种特殊类型的转移预测:return address prediction。我记得有个数据在C++或者JAVA这种高级语言中RET会占15%左右的转移总量,有了这个数据,这种类型的预测立即就有了意义:) 同理,对loop进行专门的loop prediction也是很有意义的。

除了前面说的两种,还有一种流水线冒险:数据冒险(data hazard)。数据冒险有三种,RAW(Read After Write),WAW(Write After Write)和WAR(Write After Read)。如果对R和W进行排列组合的话,其实还有RAR。但是我喜欢7z,不喜欢RAR,所以我说RAR不存在数据冒险(于是它就没有数据冒险)。

对于WAW和WAR,可以通过寄存器重命名(register renaming)来解决,也就是说,汇编大佬们注意了:CPU并不诚实,它欺骗了你,还一笑而过……嘿嘿……另一个可能会让汇编大佬伤心的事实是:处理器会乱序执行(out of order execution)多数指令(需要ROB — Re-Order Buffer的帮助),而且指令还是多发射(issue)的,这时候都没有先后关系了……前面讲的这些工作和一位几十年前在IBM工作,名叫Tomasulo的老爷爷有关(都已经过世两年了)。他用自己的姓来命名算法,所以大家虽然记不住他叫Robert,但还能知道他姓Tomasulo。

关于数据冒险,还有一种类型是RAW(Read After Write)。简单的解决方法是插入pipeline stall,等着数据写完再读,同时引来了pipeline的低效。更快的方法是在流水线内部的pipeline register直接传递数据,叫作直通或者短路。但即使加上了这种技术,有时候还是需要停顿,因为有时候从逻辑上来说,是必须要等的。

上面说的都是在ILP(Instruction Level Parallelism)级别的东西,其中也提到了内存,所以下面开始说一说内存相关的。

说到内存,就离不开Cache。Cache是一个伟大的发明,但一开始它却是为TLB(Translation Look-aside Buffer)服务的,因为“内存分页”的概念虽然好,但是多次间接地访问内存,搞得效率实再是太低下,于是有CPU设计者,在忍了再忍、忍无可忍的情况下,揭竿而起,给页表加上了cache——性能问题立即就得到了解决。

TLB和普通的cache一样,也会有hit和miss,现代CPU中的TLB在locality原则的保证下,甚至能够达到99%以上的TLB hit,但是那1%的TLB miss的penalty却非常地expensive(两个数量级以上),以至于无法忽略。据说TLB可以放在所有cache之前,或者在多级cache之间,或者在所有cache之后,分别对应:所有cache物理编址,L1 Cache虚拟编址+L2 Cache物理编址,以及所有Cache均为虚拟编码的三种情况,但实际上cache似乎都是物理编址的。理论上来讲,越大的Cache越需要用物理编址,否则一旦碰上进程切换……哼哼……

说到TLB就不得不说页表(本来它就是页表的cache)。页表有两种方式:多级页表和反向页表。32位地址模式下x86是三级每页4KiB,如果启用了PAE则是2MiB(这里多说一句,PAE不是Bank Switching,因为PAE扩展的那几位是参与VA->PA计算的)。AMD64位模式下为4级页表结构48Bit地址线。页表中对每个项(PTE)都至少有Present和Modified两个标志。P标志指示此页是否真在物理内存中,M标志指示此页是否在上次载入后被更改过。这两个标志是用来做虚拟内存的磁盘交换的,如果一个页被交换到磁盘上,它的P位就是False,访问它就会引发page fault中断,于是OS中断服务程序开始介入,假如不是非法访问的话,就要去从磁盘装载页面数据到物理内存,一般这时会硬盘狂响,界面冻结,用户开始捶打键盘……如果一个页由磁盘装入了内存,但一直还没有被更改过,那么M位就是False,也就是说如果在将来这个页要被换出的话,可以不必将它的内容写到磁盘。Linux内核中的pte_present()和pte_dirty()就是用来查询这两个标志的。除了这两个标志,还会有一些其它的,比如是否可更改等,用来做内存保护。

另外,Linux的程序装载,也是依靠page fault的,所谓的装载器其实并没有将程序内容从磁盘向内存复制(名不符实的东西遍地都有,是吧?),而是靠mmap机制映射之,随后在用到时,自然会有page fault出现,于是程序自然就被一点一点装载好了(这种感觉有点像刚刚写好了一个原语操作,然后就立即用它去发威了)。

TLB和Cache是紧密结合工作的,一个VA的VPO(Virtual Page Offset)会直接送到Cache中做匹配,VPN(Virtual Page Number)则送到TLB作查找,二者并行进行,如果都是hit,PN又对得上,那么这就是我们最想要的情形了。反之就要准备好至少两个数量级以上的penalty。在有些CPU中,TLB也有data TLB/instruction TLB,以及L1 TLB/L2 TLB之分。更多类型和更大的TLB cache力求减少miss,用以保证更好的VA->PA性能。

说完了TLB回过头来再说Cache。一般的Cache都是Set Associative的,因为Full Associative会慢,而且代价高,Direct Map又太不灵活(有一个经验定律是:2-way Set Associative,与双倍size的direct map cache相比,其cache miss rate持平)。因为Set Associativity的特性决定了有时候cache line必须被换出(此时称为victim,可以用LRU或FIFO来决定谁是victim),所以这里面就有一个优化:放置一个victim cache,专门用来保存上次被换出,但是马上又要被换入的那个line(我还看过有paper说用空闲的cache来做virtual victim cache)。OS中也有许多利用Cache的Set Associativity的特性,比如Page Coloring, Slab Coloring, Hot-n-Cold Allocator(另:设想Buddy System和非Full Associative的Cache一起使用,会有什么问题?)

从类型上来说,Cache分instruction cache和data cache两种,分别用来cache指令和数据。前面在说pipeline的时候曾经说过,如果在流水线中同时有“将运算结果写回”和“取指令”两个操作,存储器是无法接受这样的任务的。但区分了Instruction和Data两种类型后,就不存在此问题了,因为两个cache当然可以同时读+写。这种划分的另一个好处是,指令和数据的各自有自己的locality(包括时间和空间局部性),而且很少有交集(那个会写LISP的不要笑!严肃点!我们这儿侃大山呢!),所以区别对待它们,能带来性能上的提升。

一般CPU中cache至少有两级:L1和L2,现在开始流行三级cache了。越小的cache越快(基本和寄存器相当),越大的cache越慢,但无论如何也比内存快(最慢的也比内存快一个数量级左右)。分级的cache就带来一个问题:L2缓存中是不是有全部的L1缓存的内容?L3缓存中是不是有全部的L1&L2缓存的内容?这个决策不是一成不变的,有三种情况:如果大的cache一定含有小cache的内容,那么就算是strictly inclusive的;如果一定没有,就是exclusive的;如果基本上有(但有时候可能没有),就是inclusive的(注意和strictly inclusive的区别)。如果是inclusive cache,那么显而易见这里面就有一个更新的问题:更新L1 cache的时候,什么时候再去更新L2 cache中的对应内容?

层次当然是越多越好

层次当然是越多越好

另一个cache问题是在多核心/多CPU系统中出现的(SMP和NUMA均有),一般称为cache coherence问题。每个核心/CPU的L1 Cache一定是独享的,那么,如果相同Physical Address的内容被装到了不同的Core/CPU的L1 Data Cache中,然后这些Core/CPU又要去更新它们,就会出现问题。为了解决这个问题,在硬件中提供 了directory方式或者监听的方式,其中监听方式很简单:监听别的cache中的写入,如果是相同的PA,那么可以将其标为invalidated状态然后重装入,或者将监听到的写入动作同样执行一遍。

关于Cache,还有一个初看无关,但是细细考虑后,发现很相关的问题:DMA。经典的DMA讲解中,把“数据装入了内存、从而能够被直接使用”当成一个很终极的目标,但是现在我们还有更快的Cache,倘若每次用到DMA数据就需要从主存中取——这倒是没什么别的问题,就是太慢了——用惯了这么快的cache,早就把我们都惯坏了。所以又有一种办法被提了出来:对DMA的数据进行cache pre-fetching。当然这种pre-fetching不能太过份,否则cache会被这些东西给灌满,而真正需要用的热数据都被换出了——这就是所谓的cache polluting。cache polluting其实就是过量的cache warming-up以至于伤害了性能。

(曾经在某讨论组见过一个狂人,说整个组的人都不懂什么叫set associative cache,只有他自己一个人懂得……会不会我这篇blog侵犯到这位狂人独有的知识产权了呢?嘻嘻……)

说完了Cache这回终于能够说到内存了。内存的访问速度很慢,比CPU要慢两个数量级以上——这也正是Cache的意义所在。Cache也是内存,只不过是SRAM,特点是速度快;而内存是DRAM,特点是集成度高(其实计算机体系结构的许多问题都是由速度和容量的tradeoff产生的)。和双稳态的SRAM不同,DRAM每隔一段时间(典型数据:几十毫秒)就需要刷新数据以保证不丢失。过去的DRAM都是异步时钟的,直到SDRAM的时候才变成同步的(S就是synchronous)。DRAM颗粒是通过RAS和CAS信号来选取地址的(先用RAS锁出一行到行缓冲,然后靠CAS挑出需要的),每个内存颗粒可以一次选出8bit,然后这样8个8bit,并列起来构成了64位宽的数据(话说SDRAM和DDR都是64位宽的,更老的EDO和FPRAM什么的就让它们往事随风都随风吧——还不如关注一下双通道和三通道呢!)。有些内存模组上面有9片内存颗粒,这就是ECC内存了,一般是给服务器用的(Google的人曾发paper说,统计一下他们用ECC发现的内存错误,发现比想像中的可要频繁多了——对几万台服务器进行了长达两年半的跟踪记录,发现每年会发生22,696个可纠正的错误)。这里我不打算详细讲解校验原理,只做一个这样的计算:不带额外的颗粒时是8×8=64位,用它编码可以表达2^64种状态。现在是8×9=72位,也就是说可以用2^72种状态来表达2^64种编码,也就是说每256种编码中,就只有1种是对的,其它的255种排列方式都是错的……(嗯,Richard Hamming老先生要是看了我这样来解说,不知道会不会气得跳出来,然后再演讲一个Me and My Regret)

内存的访问有alignment一说,也就是说取32位数的时候,最好低5位地址为0,64位的则要求低6位地址为0。如果不是对齐的话,就需要两次存储器访问才能把完整的数给拼出来(注意这时候不考虑Cache的问题,完全是在说内存本身)。

在内存和Cache之间,同样有数据同步的问题, 为解决此问题,在Cache中也设计有dirty标志位:如果Cache要被淘汰掉了,并且dirty位为True,那么就需要把cache中的数据写回到memory中。当然,也有可能是用Write Through方式更新memory(不过,即使是Write Through,也是可以利用buffer来后台批量更新memory的,而不像传统教科书上讲的那样地naive)

关于内存访问,我想说的最后一件事是:程序中的内存访问操作,其顺序并不是按照程序规定的那样,而是经过了Memory Re-Ordering的。这种机制是乱序执行的一种,CPU中的MOB(Memory Ordering Buffer)就是来做这件事情的。

说完内存,就可以开始说外存了。如果不把穿孔纸带/卡算在内的话,外存是从磁芯磁鼓磁带一类的东西开始的,中间还有过8英寸、5英寸和3英寸软盘(后来又出现过LS-120/Zip/MO等软盘替代品,但它们都被U盘给干掉了)。现在的主流外存是硬盘,不久的未来可能会是SSD的天下。倒是磁带这东西还没有全死,因为容量实再是巨大(最新的大约是一卷500TiB);或者严格说来,软盘也没有全死:那些闻名世界的中国制造小工厂,常常使用老旧设备,那些设备上的计算机只能吃软盘:) 硬盘是从PIO方式发展过来的,后来才出现了DMA方式,后来又制定了DMA66/DMA100/DMA133等标准。有个经验规律是说,带宽的增长是延时的增长的两倍速度,但对于硬盘来说,这增长的带宽只是通讯线上的理论速度,硬盘本身的连续传输速率还是受机械机构的限制,不可能太快;延时方面则是基本没变。最新的硬盘外圈的连续速率可以有100+MB/Sec,但内圈速度至少减半。之所以有这样的速率差别,是因为硬盘是恒角速度旋转的(光盘倒是可以恒线速度),在相同时间内,外圈转过的距离当然比内圈要长,于是就可以多安排扇区。传统教科书上认为每个磁道上的扇区数都是固定的,但硬盘厂商早就打破了这一限制:他们在硬盘内部的固件里把逻辑扇区映射到物理扇区。这样的映射还带来另一个好处——试想,现在的硬盘是10年前的1000倍容量,如果工艺的改变没有1000倍(这种好事不用去想的!),那么坏扇区出现的故障率就大大增高了(比如100倍以上)。所以每个硬盘在正常的存储区之外,还有一些额外的保留区域备用,一旦出现了坏扇区,硬盘会把出错的逻辑扇区映射到保留区域内,这样就可以保证硬盘继续正常使用,只不过受到一点性能的损失(原来还有可能是连续的,现在是一定不连续了)。希捷硬盘的三黄问题,其中有一黄就是这个“重映射扇区”的计数。

1GB Hard Disk vs. 1GB Flash Card

1GB Hard Disk vs. 1GB Flash Card

如果硬盘中的碎片不特别严重,那么空间局部性原理也是起作用的(时间局部性原理多数会起作用,但考虑到OS有disk cache,可以稍微放松一下要求)。所以硬盘也安装有Cache,用来缓存读和写,在测试硬盘时候出现的最高的峰值速率都是Cache的功劳(硬盘用的Cache就是普通的DRAM颗粒)。

最早的硬盘是并行通讯。很多年前,并行通讯是比串行通讯快的,因为线多,可以同时传送一个字节或者更多。但后来发现,如果提高时钟频率,线多了会导致串扰变大(比如DMA33只要求40根的排线,而DMA66的线需要80根,其中就是添加了40根地线,每根地线和信号线并排),这就限制了时钟频率的提升,最终影响到通讯速率(还限制了通讯线的长度)。设想一下:如果串行通讯的时钟速率能有并行通讯的8倍以上(大约吧,因为还有其它开销),那么8位并行口就可以被打败了。实际上,用了低电压差分信号的串行线可以相当地快:比如PCI Express(过去叫3GIO),其时钟速率是2.5GHz,而PCI总线是33MHz或者66MHz(服务器上用的PCI-X最高有133MHz的)。当然,多组LVDS信号也是可以并列的(注意这仍不是并行通讯),这样就有了另一个优势:可以根据带宽需要来灵活安排。硬盘也在这几年完成了从并行到串行的进化,SATA中的S就是Serial的缩写。串行的最后一个优势是成本,如果提升速率带来的结果是价格翻倍,制造商们就不可能答应,因为一般来说消费者不会为这个买单。

Parallel->Serial->PS2->USB, And It Works

Parallel->Serial->PS2->USB, And It Works

硬盘的另一个进化,或者说革命,是SSD。SSD有两个巨大优势:一是访问延时(或相应的IOPS)。硬盘的典型寻道是10ms左右(硬盘直径小一些,就可以转得再快一些,寻道时间就可以再小一些,但至少也有几个ms;NCQ也可以优化寻道时间,原理是减少多余的空转),在这期间CPU能完成大约三千万条指令的运算。而优质的SSD(非中国山寨品)可以在1微秒内完成“寻道”(这是软件测试数据,实际有可能更小,因为本来SSD就没有“道”,就是做地址转换而已),至少提高了4个数量级。反过来用它折算IOPS,如果均为随机访问,大小为1Byte,那么这样的SSD至少应该有10k的IOPS;而10ms寻道的硬盘,一秒内至多能够有100个IO。SSD不仅仅是极限值估算中占优,在测试软件的IOPS实测中,也是以数量级领先于硬盘。SSD的第二个优势是速度,读取速率领先硬盘2-6倍。SSD的写入速率比SSD的读要慢百分之十几(SLC),但仍然大幅领先硬盘,而且SSD的速率在未来可能还会大幅提高,反过来看硬盘,在这10年间,盘片介质的传输速率也就是提高了两到三倍。

(往上翻了翻,发现打了一大堆字了,幸亏我有Cherry的机械键盘,打起字来一点也不累,嘿嘿……另外,如果是用嘴说的话,估计嗓子早就冒烟了……嗯,顺便在此BS一下弃blog而去录音频的tinyfool,然后咱们继续……)

说了这么半天,还有一件重要的东西一直还没提到:中断。同步/异步中断,可屏蔽/不可屏蔽中断,硬件/软件中断(软件中断由指令引发,常被用来实现系统调用),这里允许我虎头蛇尾一下吧,此处就先不展开了。

嗯,另外还有一个有趣的技术,SMT。这个技术的思路是,反正现代的CPU都是superscalar的了,程序经常无法用上这么多的运算部件,但如果把它们拆成两个传统的处理器核心的话,在可以充分ILP的时候却又吃亏了,而且需要的部件也变多了,再考虑到某些情况下流水线的长长等待停顿,设计者就盯上了近些年来开始流行的多线程技术,在CPU内实现了多线程并行——这也是SMT名字的由来:Simultaneous Multi-Threading。SMT属于线程级别的并行(TLP),它和ILP不同,它同时解决流水线垂直和水平浪费的问题,从充分利用运算部件的角度来说,SMT肯定是赚到了,但是从Cache和TLB等的角度来说,多个线程有可能互相warm up也有可能互相pollute,胜负难料。另外,从CPU设计的角度来说,支持SMT肯定会更复杂(register file需要再大一些,program counter需要两份等),坊间有传闻说Intel的Core2系列CPU就是因为没时间去做而放弃了SMT……嗯,传说而已,作为不明真相的雪亮群众,我们一定要保持情绪蛋定。

最后写点和知识无关的话:我上面写的这些体系结构方面的东西,全部都是因为组装电脑才学到的。有一本名叫CSAPP的教材(国内翻译版名为《深入理解计算机系统》),被某些人奉为神器,但在我这个装机十几年的人眼里,其中没有任何新鲜的知识,都是炒冷饭。

然后,请允许我吐一个槽:有些写程序的人,格外瞧不起会装电脑的,声称那些装机高手都是XXXX……在我看来,这有可能是他们自身知识层次的限制,外加一些很常见的biases(具体的我就不列举了,有兴趣的同学可以回家翻心理学教材),才导致他们会说出这样的话来(而且还有个逻辑错误)。

P.S. 说起基础的教材来,倒是《Computer Architecture – A Quantitative Approach》这一本,相当地不错。本着国内技术圈儿喜欢8褂教材的习惯,我在这里多介绍一些背景:作者共有两人,其中John Hennessy是RISC的大牛,斯坦福大学的校长,MIPS的发明人和公司创立者;另一位David Patterson是伯克利的教授,RISC的大牛,SPARC处理器原型的发明人……(嗯,看来我的8褂工夫不到家,说完这几句就没词儿了——这俩人获得冯诺依曼奖什么的不知道是不是应该8一下)……我个人建议:每个有志把程序写得更好的人,至少要把此书精读一遍(在上学时没有学到好教材的,该进补一下了)。其中的理由,我就不论证了——应该会有一小撮儿的software die-hard同意我的观点吧?最后,套用一句公司老大的话:

Software + Hardware = Complete!

An Architect

An Architect

感谢 @welfear 指出几处问题。

然后,自己留言给自己“辩解”一下:这个文章是在某一个周六的下午闲得无聊憋得难受就打一口气打出来的(前一个月左右曾复习了一下体系结构方面的东西,外加某些情况,不写写文章就有点憋得难受了:),最近我还没有仔细review,如果有错误肯定是在所难免,等回头对这些文字开始生疏的时候,我会再来修改订正。所以,大家千万看的时候要注意挑错,别轻信我说的,呵呵……

Tagged with:

资深架构设计师的30条忠告

Posted in Uncategorized by Kenny Yuan on 2010/10/18

UI really matters!
界面真TMD不能忽视!

The design should base on the problem domain, not on what you have done before.
设计是应该按照问题域来进行的,而不该根据你过去做的事情为蓝本。

It’s hard to say “I was wrong”, but if you don’t say it, you’ll have to pay for it.
说出“我是错的”是很困难的,但是如果你(在该说的时候却)不说,你会为此付出代价。

It’s not your full time job demonstrating how to write code. You can do it, but not all the time.
你的工作不是做编程示范。你可以做,但是不要全身心投入进去。

Bug fixing is also your responsibility, don’t leave it to the maintenance team.
处理BUG也是你的责任,别把它扔给维护团队就不管了,要不然你的设计会被维护团队搞得面目全非的。如果写烂代码更方便的话,维护团队一定会写出大堆的烂代码的。作为架构师,你要去控制修改代码的成本,让成本最低的那一个成为你所期望的那一个(借鉴一下经济学)。

You are not Winston Wolf. Try to eliminate problems before they surface. (good design has less problems; you’re not a firefighter)
你不是一个专门来解决麻烦的(见《低俗小说》)。试着在麻烦出现前将它们干掉。(好的设计能消除问题和麻烦;你不是消防队员)

Design is technical, try to avoid politics. Or negotiate with politics to make things still work.
设计是技术问题。不要让政治参与其中。或者适当妥协以便让事情还能运转。

If your decision is based on some limitations, always remember those limitations along with your decision.
如果你的决策是基于某些限制的,那么在记住你的决策的同时,要记住这些限制(不要直接记住结论)

If you can summarize principles from your work, write it down. Then sometimes you’re able to know you were wrong.
如果你能在工作中总结出原则,就写下来。这样以后你就能知道你曾经如此这般地犯过错(我打赌你写过的多数都是错的,除了OCP,但那不是你发明的,嘿嘿)

If there are many programmers awaiting for your design, you’re definitely dead meat. (Human Resource driven is the sin)
如果有太多的程序员在等你的设计(来开工),你就死定了。(人力资源驱动是一种原罪)

Prevent lame metaphors; software is neither art nor brick building.
别用蹩脚的比喻;软件不是艺术,也不是砖墙。

Tell the user what you can provide; don’t ask them what they REALLY WANT.
告诉用户你能提供什么;别问他们“你到底要什么”。

Quality is your responsibility too, don’t hand it over to QA. (Design in the robust way)
质量也是你的责任;别把它们交给QA。

Don’t get smart. Write it down when you feel like a genius, and attack your idea as the most dangerous enemy.
别耍小聪明。当你感觉自己像天才似地做出一个设计的时候,要把它当成最危险的敌人来对待。

Reuse is not your purpose, it’s neither necessary nor sufficient to success.
“重用”不是你的目的。它不是“成功”的充分条件,也不是必要条件。别单纯为了重用去设计,别忘了重用是为了达到什么样的目的。

A language addict will always be a slave. Try to become a sensai.
语言上瘾者永远是一个奴隶;尝试变成斯普林特老师吧!

Solutions/Tools with high price guarantee nothing on productivity.
售价很高的解决方案/工具从不保证任何生产力。

Don’t say “Microsoft did the same thing”. It proves nothing. (Google/Facebook/Twitter/etc.)
别用“微软也这么干过”来支持你自己。它什么也证明不了(google/facebook/twitter同理)

Don’t try to collect information/requirements first and decide later; welcome to the moving planet.
别尝试先收集所有的信息和需求,然后再决定;欢迎来到地球——这颗移动的行星!

There’s no universal solution; The programming language sometimes can be the one, unfortunately we have lots of languages.
没有万能的解决方案;有时候编程语言可以是一个(万能解决方案),不幸的是我们有很多种语言

Age and experience are not the right way to defend yourself in an argument.
在争论中,年龄和经历不是你证明自己的正确方式(以德服人,以理服人)

Yesterday’s workaround is tomorrow’s limitation.
昨天的Workaround就是明天的限制

Good design evolves; bad design patches.
好的设计在进化,坏的设计不停地打补丁

Design what you’re able to write code for it. If it’s too hard to you, don’t count on the others.
用你能实现的方式来设计;如果困难到你也写不出来了,那么就别指望其它人

Don’t be the captain in the engine room.
不要成为引擎室里的船长(把船开好是你的职责,而添煤则不是)。

Inspect your design in each level.
在不同的级别下仔细检视你的设计。

Understand the hardware; your system doesn’t run in air. (Hardware goes wrong too)
要懂得硬件。你的系统不是在空气中运行的(但是可以Adobe Air)(硬件不是完美的,可能会出各种错误;)

Make your design natural and comfortable. Don’t fight against programmers, and don’t let them fight against your design.
让你的设计是自然而舒服的;别跟程序员斗争,也别让他们和你的设计斗争。(参考QT的舒适与灵活,外加良好的命名和强大的功能;另参见最小惊奇原则)

It’s too late when you realize it’s slow; design for performance;
当你意识到速率太慢的时候,已经太晚了。为性能而设计。

……嗯……如果你仔细数过了这些原则的数目,会发现其实只有29条。第30条我没有写,其实原打算是这样的:

(30)这篇文章是由Kenny Yuan在1.5小时内直接敲出来的,其中英文敲了一小时左右,中文翻译了半小时左右;他写这篇文章是为了说明:滔滔不绝地谈论具有迷惑性的原则是多么的容易!而且居然还能骗到一部分人哩……

(P.S. 之所以选择从“架构”这个角度来忽悠,是受到以下这个的启发:http://97-things.near-time.net/wiki/97-things-every-software-architect-should-know-the-book)

最后祝大家动脑快乐!

(P.P.S. 此为旧文,一直在草稿里忘了发。现在编辑一下发出来,其目的,当然是想要给大家的Google Reader再添一个未读数,嘻嘻——嗯,要keep it on the down low…)

渔讯——这拨儿都是咸带鱼

Posted in Uncategorized by Kenny Yuan on 2010/10/13
Big Fish

Big Fish

一段时间以来,我在慢慢总结自己的知识结构。原来是用DOT来做图(优势是可以画graph而不是仅仅限定于tree,而且还能上版本管理),但后来因为种种原因,转到了xmind的Mind Map方式——既然用了xmind,那就可以开始分享了。虽然我估计当前的完成度只有两、三成左右(很多地方没有深入展开,有些类别也还没有添加),但本着“Getting Real”的思想,还是尽早拿出来分享吧!题目仍然是标题党的形式:Interview Bible (面试圣经),嘿嘿

地址如下(可下载):

http://www.xmind.net/share/kenny_yuan/interview-bible/

Interview Bible (collapsed)

Interview Bible (collapsed)

Tagged with:

A Complete Program Inside a Tweet?

Posted in Uncategorized by Kenny Yuan on 2010/09/21

这是一篇无聊的文章,对此不感兴趣的读者可自行选择:关Tab、关窗口、退订、拔网线、砸电脑、自残、自焚、人体炸弹、当黑暗大BOSS毁灭人类、入党……





Boss

Boss





OK,你还在,我也还在,那么我来继续记流水帐:《能否在一条tweet中写一个求值程序?》

看到有人讨论面试问题,其中有人提到用“现场写一个计算器”来作为考题。在瞎掰了很久之后,我决定自己实际试试,因为“光说不练是假把式”么……当然,既然是自我挑战,那目标就设高一点:试着在一条推中写完表达式求值程序……

……嗯……显而易见地,我失败了!不过我在一条推的长度内写完了一个后辍(RPN)表达式的求值程序,共113字符:

(defun r(e)(let((s()))(dolist(x e)(if(numberp x)(push x s)(push(eval(reverse(list(pop s)(pop s)x)))s)))(car s)))

用的是标准的stack解法。

至于将中辍转后辍的程序,我只写出来这个:

(defun v(e)(let((s())(o())(m'((+ 1)(* 2)(- 1)(/ 2))))(dolist(x e)(if(listp x)(setf x(v x)))(if(numberp x)(push x o)(progn(do()((or(null s)(<(cadr(assoc(car s)m))(cadr(assoc x m)))))(push(pop s)o))(push x s))))(r(append(reverse o)s))))

足足有235字符!看来目标是达不到了……(@googollee老大也失败鸟——嗯,我很happy)

不知道有没有哪位读者是语言达人,可以完成这个伟大的目标呢?

最后声明一下:直接eval,或者调用bc这些玩赖的方式肯定能行,但太没技术含量……

——路人甲:还有比这篇日志更没有技术含量的?

——路人乙:大家洗洗睡了吧!

于是,我去准备洗洗睡了……

(如果哪位有好点子,请一定别忘了留言)








Tagged with: ,

说说用户界面那些事儿-银杏篇

Posted in Uncategorized by Kenny Yuan on 2010/09/19

汽车驾驶员需要专注,肯定不能边开车边看电影——就连打电话、发短信造成的事故都挺高发的,更别提电影了,这是在NHTSA有数据可查的。所以车载系统的屏幕,为了安全,最好也只显示枯燥的导航地图。但是乘客们不这样想,乘客们会想要利用车载系统来娱乐,比如看看电视、放放电影什么的。无奈安全第一,于是在常见的设计方案中,车载系统会“贴心地”在行驶中关闭娱乐功能,只允许使用地图功能。

但这个方案并不怎么高明:除了专业司机,很少有人会坐在停驶的车上看几小时的电影,而行驶途中的乘客则是最无聊的——跑长途时,行车几个小时太平常不过了,连续几天每天跑十个钟头的也很常见,就说在北京城内,堵俩钟头也算稀松平常的——这就让用户花高价买来的车载娱乐系统成了摆设(什么QNX什么WINCE的高科技RTOS,都是骗银滴)。这时候,可能有些负责任的厂商就会开始教育用户了:“just don’t sit in that spot——我们不是提供了后座上的车载娱乐系统了么?您倒是坐后座上去啊?”于是,当两人旅行的时候,如果乘客们不想在车上无聊,就会发生“妻离子散、劳燕分飞、两地分居、君在奔驰头我坐奥迪尾”的问题。而且因为无人陪同,驾驶员更容易疲倦,也就有可能造成更高的事故率——那可真是“撒手人寰、驾鹤西游、尘归尘土归土、生死相隔解愁肠”了。

在我往下接着侃之前,请读者您花10分钟细细考虑一下这些场景,并试着找一找技术上的解决方案……

梅赛德斯在08年发布了一项名为SplitView的技术(官方中文名称为“分屏视图”,是联合BOSCH做出来的),请看视频:http://www.5min.com/Video/Mercedes-Benz-SplitView-Tech-Review-259734353

大概地解释一下:司机在左边,看到的画面是导航地图;乘客在右边,看到的画面是电影。电影的声音可以外放(比如演唱会之类的还是可以让驾驶员听听的),或者也可以将声音全部输送到乘客的无线耳机上。所有的中控台按纽都是给驾驶员用的,控制的是导航画面等功能。乘客使用一个独立的无线遥控器来控制娱乐功能。嗯……遥控器?

Remote Click

Remote Click

我想,看过了视频之后,关于这个系统的优劣,聪明的读者你一定已经有所体会,我就不多评价了。这个系统的原理也很简单:从像素上来讲,那个显示屏是“双份”的,所以画面都是同时显示的(并非分时)。只不过两份画面被分别限制了可视角度,估计是利用了裸眼3D之类的技术,但是设定了不同的研发目标而已。

本文没有末尾的总结,因为读者们总是最聪明的 🙂

Mercedes Benz Splitview官方图

Mercedes Benz Splitview官方图

Ctrl + X, Ctrl +S; Ctrl +X, Ctrl + C …

Tagged with: , ,

说说用户界面那些事儿(第三部分)

Posted in Uncategorized by Kenny Yuan on 2010/09/12

这真是一个最好的时代,也是一个最坏的时代:优秀的用户界面全都相似,差劲的用户界面却各有千秋——但无论如何,一个优秀的计算设备必须要有一个优秀的用户界面,这是放之四海皆准的事实。好的用户界面是设备的生命之光、欲望之火种源,同时也是设备的罪恶……

——哦,对不起,我不是文学青年,不能引用太多的“名著”开头,这部分文章里,我得继续讲科学定律……截止到目前为止,本系列文章仍然在介绍小学文化程度的基础知识,没有侃大山,也就没有切题(因为题目叫《说说用户界面那些事儿》,典型的侃-able title)。所以我尽量压缩内容,尝试在本篇内结束这些没人爱看的基础知识介绍,从下篇开侃。

嗯,虽然我很想压缩内容,但是有一个新的变化:我终于又回归到了机械键盘一族(Cherry的青轴)。虽然在twitter上我不是像某些同学那样不管什么样的鸡毛蒜皮的小事都要不停地推啊推啊的那种话痨但是有了这块超级好用的每按一次键就发出清脆的响声让人感觉打起字来就像弹钢琴时用上了节拍器一样合谐的Cherry机械键盘之后我发现我打字的欲望开始变得异常地强烈了起来甚至达到了一句话竟然可以写出上百个字都没有标点符号的程度而且整个句子都只是没多少意义的文字而已似乎只是为了打字而打字这一个单纯的目的而已了——嗯,话说小时候写作文的时候也是这样凑字数的。

——常看网络小说的你一定知道的:以上段落作废……(并非只有起点的大大们才能享有这种权利)

Cherry青轴机械键盘

Cherry青轴机械键盘


(2.3) Hick-Hyman Law (希克海曼定律)

常有脑残批评我的思想太阴暗,为什么不忽略那些负面的东西,只看那些伟光正的。从这个角度来说的话,此系列的前两篇文章恐怕也太“负面”了。所以我来写点光明的、令人振奋的东西,同样的,它还是科学定律:

——嗯,以上段落仍旧作废。下面我来介绍一个科学定律:Hick-Hyman Law (希克海曼定律)。

T = b * log2 (N + 1)

其中,N是选项个数,b是可以用经验法测量的常量,T是做出选择所需要的时间。

这个定律说明,当选项的个数以线性增长时,在若干个选项中作出选择所需要的时间是以对数曲线增长的。换句话说,选项的数目在快速增长的时候,做出选择所需要的时间只是在慢慢地增长。假如选项的数目增长了250倍,所需的时间也仅仅是增长了8倍左右。在前面一句多余的解释之外,还有一个多余的图表用来解释:

从图中我们可以看出,如果你弄了许多的菜单项出来,用户肯定会受到困扰,操作时间会变长。但是操作时间的增长数量,和菜单项数目的增长数量相比,基本上可以无视了。

Maya的PieMenu里有很多选项


关于这个定律,其实还有一些可以深入的话题,还可以扯到认知科学和神经网络。但我一来懂得不多,二来不想浪费太多篇幅,所以就到此打住——嗯,有话痨趋势的我在此不得不多说一句,研究HCI一定要懂一些Cognitive Sciences(认知科学),不用精通但是怎么也得懂一些基础。比如:Change Blindness, Inattention Blindness和IOR之类的……


(2.4) Power Law of Practice (实践的幂定律)

古人云,常言道,俗话说,曾子曰,Confucius he say:“包子有肉不在摺儿上”……哦,错了,应该是“一回生、二回熟”(所以,摺上有肉的包子不能只蒸一回,嘻嘻)

——以上段落作废。

我们都有过这样的体会,在最开始做一件事情的时候,往往需要集中全部精力,但往往还做得不够好,比如骑自行车/学开车,或者解数独,或者打地鼠,或者玩Super Mario Bro——还记得你第一次上手红白机的时候么?在控制Mario向前跳跃的时候,你有没有把手柄当成了WII手柄来用?后来当你可以不用Konami Code也能全八面迅速通关的时候,你肯定不会再把游戏机从桌子上扯下来了吧?

Super Mario Bro


上上下下左右左右前前后后


Power Law of Practice (实践的幂定律)

T = a * N ^ (-b)

其中,N是练习的次数,T是第N次的完成时间,a和b是常数。

这个定律的意思是:随着练习次数的增加,完成相同任务所需要的时间是指数下降的,参见下图:


有了这样的一条定律,对我们来说无疑又是一大利好消息——哪怕一个任务设计得很糟糕、很耗时也不用太担心,只要用户多加练习,那么用户完成任务的时间就会大幅下降,而且是迅速地大幅度下降。

如果你想验一下Power Law of Practice,可以先找一个秒表(或用手机功能/手机App),开始计时,然后清空你的浏览器的内容缓存、所有保存的表单内容、所有保存的密码、所有的URL历史、所有的Cookie,然后记录下所用的时间。然后再重新开始并计算时间,如此重复若干次,然后画图。

如果你多注意观察,在以下这些电脑用户的身上也能观察到Power Law of Practice的效果:超市收银员、银行柜员、照相馆里PS一寸免冠照片的操作员、电脑城装机器的技术员……

虽然有Power Law of Practice的保驾护航,但是,我要说“但是”:一般在设计一个普通操作的时候,最好也不要超过3次鼠标点击。这并不是一个科学定律,只是一个经验公式;而且它也不是普适的,只是针对一般性的普通操作。举个例子来说:一个频繁更新的软件,如果在下载完更新包后,一定需要用户的操作才可以实施更新,那么,最好能让用户在三次鼠标点击之内完成这一次更新。(联想一下JRE Update/Adobe Update/iTunes Update/Windows Update,再对比一下Google Chrome这种不需要任何鼠标点击的)

嗯,接下来我的恭喜作为读者的你,看了我这么多枯燥的说教竟然还没有被吓跑,其实我还有心介绍一些更多的理论上的东西,比如GOMS/MTM之类的,但一来那只是一种测量方法,二来做科普时基本上无法夹带我的私货(嗯,开篇说过了,我自己在做的一个基于手势的HCI,暂定名为WheelUI),三来有许多有意思的东西如果不“先下手为强”,估计别人慢慢地就都知道了(那样子就无法完成ZB伟业了)……呵呵,你看我写了这么多理由,就是为了能够到此为止,点到为止,从些不再写知识点,继而进入侃大山的历史新篇章…… History became legend; legend became lenovo… until, when chance came, a new era had begun… And a brand new saga is being written…

谢谢观赏,下次再见!



00:00:25,469 --》 02:45:35,634
<font color="#ffff00"
反义:Sharon桶 盆泥
脚对:大妈 杀啦
世间粥:歪脖子的小马,不拉屎皮特



(以上是字幕组加上的一大堆乱七八糟的文字,我从来没有看懂它们的意义,请不要跨服务器追捕)






Tagged with: ,

[书摘]群体思维:群体会阻碍还是促进好的决策

Posted in Uncategorized by Kenny Yuan on 2010/07/03

(Kenny注:这回是名符其实的抄书了!为了写群体思维,翻了翻书,然后发现还是抄书更省力气,要我写的话,一小时内可写不出这样水平的……)

什么情况下群体影响会阻碍好的决策?什么情况下群体会促进好的决策?以 我们应该怎样引导群体做出最好的决策?

研究背后的故事:贾尼斯对群体思维的研究

当我阅读施莱辛格(Arthur Schlesinger)描述关于肯尼迪政府如何决定袭击猪湾的内容时,我萌发了群体思维的念头。一开始,我很困惑:像肯尼迪及其顾问那样聪明雄辩的人怎么会卷入由CIA愚蠢拼凑起来的计划中呢?我开始关注其间是否涉及一些心理学因素,例如社会从众或是我在团结的小型群体中所观察到的寻求一致。进一步的研究(开始是我受女儿夏洛特高中论文的启发)使我相信一些微妙的群体过程阻碍了他们仔细地评估风险和讨论问题。接着当我分析了其他的美国外交失误以及水门事件后,我发现了这样不利的群体过程。
——欧文•贾尼斯(Irving Janis, 1918-1990)

我们在前8章所讨论的社会心理学现象是否同样会发生在公司董事会或者总统内阁这样复杂的群体中呢?他们是否会出现自我合理化行为?或者自我服务偏见?那种有凝聚力的“我们的感受”是否会唤起从众或是拒绝异议的行为?社会心理学家贾尼斯(Irving Janis)想知道这些是否能够帮助解释20世纪的美国总统及其顾问怎样做出好的或坏的群体决策。为此,他分析了几次大的失败决策的过程:


  • 珍珠港。1941年12月的珍珠港被龙事件使美国也加入到了第二次世界大战中,事件发生之前的几个星期,夏威夷的军事指挥收到了一条可靠的消息:日本计划袭击美国在太平洋上的某个地方。之后军事情报失去了与日本航空母舰的无线电联系,那时航空母舰正径直朝夏威夷前进。空中侦察队本来应该能侦察出航空母舰的位置或者至少发出几分钟的警报。但是自以为是的司令们完全无动于衷。结果是:直到日军开始对这个毫无防备的基地发动袭击,警报才被拉响。袭击后美军损失了:18艘舰艇、170架飞机,以及2400条生命。
  • 入侵猪湾。1961年,总统肯尼迪及其顾问们试图用1400名由CIA训练过的古巴流放者来袭击古巴,以此推翻卡斯特罗政权。几乎所有的袭击者都被杀或抓获,美国颜面尽失,而且古巴与前苏联更为团结了。在得知后果以后,肯尼迪大呼:我们怎么做出了如此愚蠢的事呢?
  • 越南战争。在1964到1967年之间,由总统约翰逊及其政治顾问组成的“周二午餐团”决定扩大对越南的战争,因为他们预测美国的空中轰炸、空降以及搜索捣毁任务会迫使北越南接受和谈,而南越南人民出于感激也会支持和谈。尽管政府的情报专家以及所有美国的盟国都对他们提出警告,但他们还是继续将战争扩大化。这场空难使58000多美国人和100万越南人丧生,开卷有益国人变得极端化,总统被迫下台,庞大的财政赤字加速了20世纪70年代的通货膨胀。
贾尼斯认为酿成这些大错的原因是由于在群体决策中人们为了维护群体和颜面而压制异议,他把这种现象称为群体思维(groupthink)。在群体工作中,同志式的友情可以提高生产力(Mullen & Copper, 1994)。而且,团队精神有助于鼓舞士气。但是在决策时,紧密团结的群体可能反而不利。贾尼斯认为友善的、凝聚力强的群体,对异议的相对排斥,以及从自己的喜好出发做决策的支配型领导都恰是培养群体思维的温床。
在计划那次不幸的猪湾袭击时,刚刚当选的骨尼迪总统和他的顾问们高兴地组成了一个极有团队精神的队伍。而对这次计划十分关键的观点都被压制或是排除了,总结本人很快就对这次袭击表示了认同。


群体思维的症状表现


从历史记录以及参与者和观察者的回忆来看,贾尼斯列出了八条群体思维的症状表现。这些症状集中反映了对异议的排除,表面上看来就是群体成员在遇到威胁时,会努力保持他们的积级群体感(Turner & others, 1992, 1994)。

前两条群体思维症状表现往往导致群体成员高估群体的力量和权利

无懈可击的错觉。贾尼斯所研究的群体都表现得过分自信,以至蒙蔽了眼睛,看不到危险警报。当珍珠港的海军总指挥基梅尔(Admiral Kimmel)得知他们已经与日本航空母舰的无线电失去联系后,还开玩笑说或许日本人打算绕檀香山转一圈。事实上日本人确实这样做了,但基梅尔对这种想法的嘲讽使人们认为这不可能是事实。
对群体道义无可质疑。群体成员接受了其所在群体内在的道义,却忽略了伦理和道义上的其它问题。肯尼迪等人知道基辛格顾问和富布赖特(J. William Fulbright)议员对于袭击一个小小的邻国在道义上持保留态度,但整个群体从没有接纳或讨论过这些道义上的疑虑。


群体成员还会在想法上越来越接近


合理化。群体以集体将决策合理化的方式来减少挑战。比起自省和重新考虑以前的决定,约翰逊总统的周五午餐团花了更多的时间来使扩大战争的决策合理化(对其进行解释和找出合理的理由)。每个行为都 变成了掩饰和合理化。
对对手的刻板印象。陷于群体思维的人们往往会认为自己的对手不是太难于协商就是太弱小愚蠢以于难以抵制他们的计划。肯尼迪等人自认为卡斯特罗的军事力量很薄弱,其支持势力也很弱,因此仅仅一个旅就能推翻他的政权。


最后,群体会受制于追求一致性的压力


从众压力。群体成员会抵制那些对群体的设想和计划提出疑问的人,而且有时候这种抵制并不是通过讨论而是针对个人的嘲讽。有一次,当约翰逊总统的助理莫伊斯抵达会场时,总统嘲笑他说:“噢,‘阻止爆炸的先生’来了呀!”面对这样的讥讽,很多人都选择了从众。
自我审查压力。由于异议往往会令人不舒服,而且整个群体似乎表现出一致性,所以人们往往会将自己的疑虑压制下来。在猪湾袭击之后的几个月,施莱辛格自我谴责说,他在“内阁进行的那些重要会义中保持了沉默。即使提出反对意见也无济于事,我仍将被人们厌恶,这样的念头压倒了我的愧疚感”。


人们自由地进行讨论时,并不一定能正确地解决问题——John Stuart Mill, On Liberty,
1859


一致同意错觉。不要去破坏一致性的这种自我潜力会导致一致同意错觉。而且,这种表面上的一致性更坚定了群体的决策。这种表面上的一致性在上述的三次大失误中十分明显,在其前后的其它失误也是如此。斯皮尔(Speer, 1971),希特勒的顾问之一,把希特勒周围的氛围描述为,从众的压力压制了一切异议。异议的缺乏造成了一致同意错觉:
在正常的氛围中,背离事实的人们会很快被拉回正轨,因为他们会受到周围人的嘲弄或批评,这样他们就会意识到自己已经失去了可信度。而在第三德意志帝国,没有这样的矫正措施,尤其是对那些身处社会最高层的人们而言。相反,每个人的自我欺骗都被放大了,就好像是身处一个摆满哈哈镜的大厅里,人们脱离了残酷和外罪,梦幻世界般的图景被反复强化。在那些镜子中,除了被不断复制的自己的脸以外,就什么也没有了。外界没有什么因素能干扰这许多不变的脸的一致性,因为那全都是我自己的脸。(P. 379)

心理防御。有些成员会保护群体,使那些质疑群体决策效率和道义的信息不会对群体构成干扰。在猪湾袭击之前,肯尼迪把施莱辛格叫到一旁,告诉他说:不要把话题扯远了。国务卿腊斯克(Dean Rusk)作为外交和情报专家所应提出的反对袭击的警告也就此打住。就这样他们完全服从于总统的“心理防御”作用,使他没受到不同意见的干扰,但却无法保护其身体不受到危害。


群体思维的各种症状表现会阻止群体成员对相反信息以及问题的各种可能性的探寻以及讨论(见团8-11)。当领导主张某种观点而整体群体又排斥异议时,群体思维可能就会产生错误的决策(McCauley, 1989)。
英国心理学家纽厄尔和拉格纳多(Newell & Lagnado, 2003)认为群体思维还可能解释伊拉克战争。他们指出,无论是萨达姆还是布什,身边都有一大群和他们具有同样目的的进言者,这就迫使反对者闭嘴,而令其只过滤支持自己假定的信息——伊拉克的假定是对入侵者进行反抗,而美国的假定则是成功地入侵伊拉克会带来短暂而和平的领土占领和今后长期的民主统治。


对群体思维的批评


虽然贾尼斯的想法和观察结果引起了广泛关注,但一些研究者对此持怀疑态度(Fuller & Aldag, 1998; t’Hart, 1998)。贾尼斯的证据都是回溯性的,因此他可以挑出支持自己观点的例证。后来的研究也表明:


  • 支配型的领导方式确实和糟糕的决策相关,有时下属会认为自己太弱小或缺乏自信,因此不敢站出来表达自己的意见(Granstrom & Stiwne, 1998; McCauley, 1998)
  • 群体确实倾向于支持极富挑战性的信息(SchulzHardt & others, 2000)
  • 当成员们希望从群体中获得接纳、赞许和社会认同时,他们会压抑自己与他人不同的想法(Hogg & Hains, 1998; Turner & Pratkanis, 1997)
  • 但是友情并不会滋生群体思维(Esser, 1998; Mullen & others, 1994)。安全而高度团结的群体(例如,一对夫妻)会为成员提供自由的氛围来提出异议。凝聚力比较高的群体规范既能够导致意见的统一(从而造成群体思维),也可以进行批判性地分析,以避免出现群体思维(Postmes & others, 2001)。而一个组织严密的部门学术伙伴彼此分享手稿时,他们想要的就是批评:“尽你所能地来给我挑毛病吧。”在自由的氛围中,团结会提高团队工作的效率。


真理产生于朋友间的讨论——休谟,1711-1776


而且,当泰特落克及其同事(Tetlock & others, 1992)在各个历史时期大范围地搜集样本时,清楚地发现即使是好的群体交流过程有时也会做出错误的决策。1980年,当卡特总统及其顾问们密谋营救在伊朗的美国人质时,他们一度欢迎大家提出各种观点,而且很现实地考虑到了行动的危险性。要不是一架直升飞机出了问题,营救行动可能已经成功了。卡特事后回忆说,如果他当时能多派一架直升机,自己可能就已经连任总统了。在此又得提起罗杰斯先生,有时候好的群体也会做出错误的事情。


纵览对群体思维的各种批评,保卢斯(Paulus, 1998)用费斯汀格(Festinger, 1987)的话来提醒我们,只有那些无法用实验证实的理论才是不会改变的。如果一个理论完全可以用实验来验证,它就不可能永远保持不变。它必须做出改变。所有的理论都是不完美的。费斯汀格说,因此我们不应该问一个理论是对还是错,而应该问它能对我们的经验领域做出多少解释以及它在多大程度上必须被修改。贾尼斯直到1990年去世之前,都在对自己的理论进行测试和修改,他也一定非常欢迎其他人继续对它进行修正。在科学领域,这就是我们探索真理的方法:根据事实来设计实验,修改它们,然后再进行更多的实验。


聚焦:群体思维与挑战者号的灾难


1986年1月,当美国宇航局(NASA)决定发射挑战者号航天飞机时,群体思维很显然导致了悲剧的发生(Esser & Lindoerfer, 1989)。考虑到零下温度会对设备造成损害,以及在Rockwell International制造绕行太空船的工程师们都反对这次发射。Thiokol的工程师们担心低温会使火箭的四个部分之间的橡胶封口变脆,以至于不能封住过热的气体。公司的高层专家在回忆录中都提到,在这次注定失败的发射任务之前的几个月,他们已经警告说无论封口能否封住,飞船就像一个“跳球”,如果飞行失败了,“结果将是最高阶层带来的灾难”(Magnuson, 1986)。
在发射前一天晚上的电话讨论中,工程师们向拿不定主意的主管们以及宇航局的官员们提出了他们的看法。宇航局的官员们原本就很希望将这次已经被耽搁的发射继续进行下去。一个Thiokol的官员后来证实说:“我们都陷入思考的过程,试图找出一些迹象来证明它们(加速器)确实不能工作。但我们并不能完全证明它们不能工作。”结果就形成了无懈可击的错觉。
从众压力也在其间起了作用。宇航局的一个官员解释说:“我的天,Thiokol,你希望我什么时候发射。明年4月?”Thiokol的首席执行官宣布说:“我们需要做出一个管理决策,”然后他要求自己的工程师兼副总经理“摘下工程师帽子,换上管理者帽子”。
为营造一致同意错觉,这位执行官只让管理官员投票,而把工程师排除在外。做出继续执行任务的决策后,一名工程师曾提出让一位宇航局的官员再考虑一下不:“如果这次发射出了任何意外,”他预言到,“我肯定不愿意做那个不得不当众解释为什么要进行这次发射的人。”
最后,出于心理防御,做出最后决定的宇航局的首席执行官根本不在乎工程师们的观点,也不理会Rockwell官员们所持的保留意见。他在排除了异议的情况下,自信地将挑战者号送上了它的悲剧之旅。
在2003年,宇航局由于专家顾问小组警告其航天飞船因老化存在安全隐患而撤销了五个顾问成员资格之后,灾难再次降临(Broad & Hulse, 2002)。宇航局说这只是为了吸收新鲜血液,但是几名顾问成员认为是当局企图压制他们提出的批评,而且宇航局对他们的担忧漠然置之,当2月1日哥伦比亚号在返回地球途中发生断裂事故,这一切显得更为可信了。哥伦比亚号事故调查小组(2003)总结道:“技术的原因与组织的原因在哥伦比亚号事故中不分伯促,泡沫材料撞击上升中的航天飞机与事故关系密切,而宇航局的组织文化也是一样难逃罪责,”另一个同样重要的原因是组织内的阻碍者“屏蔽了关键安全信息的有效沟通,抵制了专家意见中的不同声音。”
图:行动中的群体思维:挑战者号航天飞机爆炸,1986年1月28日


“在决策过程中存在严重失误”——摘自总统委员会关于挑战者号飞船事件的报告,1986年



关于泰坦尼克号的群体思维


尽管有四条信息显示前方可能有冰山,而且一名守望人员提出需要借助于望远镜,但爱德华•史密斯船长——一位受人尊敬的支配型领导——还是坚持让船在夜晚全速前进。这其中有无懈可击的错觉感(“上帝自己也无法弄沉这艘船,”船长曾经这样说过。),还有从众的压力(其它船员都斥责那名不能用肉眼了望的看守,对他的异议置之不理。),同时工作人员也存在失职行为(一名泰坦尼克的电报员没能把最后也是最完整的冰山警报传递给船长)。


另一个例子


对航空人员的行为表现进行研究的社会心理学家赫尔姆里希(Helmrich, 1997)指出,1982年的一天,当佛罗里达航空公司的一架飞机从华盛顿国际机场起飞时,其不良的群体动力是非常明显的。传感器上的冰块使得速度显示器的读数过高,以致机长在飞机上升时无法提供足够的动力:


副机长:啊,那里有问题。
机长:没有问题,它就是80(指速度)
副机长:我认为是有问题的。呃,不过也许它没问题。
机长:120。
副机长:我也搞不清了。


速度确实有问题,副机长的沉默导致了飞机失速并且撞上了波托马克河上的一座桥,整架飞机除了五个人以外全部遇难。


(Kenny注:打字到这里的时候我不禁想到了那个笑话,paste如下:一架飞机正准备进入跑道时突然又折回停机坪,过了30分钟飞机又退出停机坪并顺利的起飞,当飞机抵达目的地时,一位乘客忍不住好奇的问空服员,为什么飞机第一次起飞前到折回机场,而且也没有人跟乘客报告发生了什么事?空服员就对他说,因为第一次要起飞前机长听到引擎有怪声音,所以他就回去换了一位敢开的机长上来……)


对群体思维的理论分析


(资料来源:Janis & Mann, 1977, P.132)


社会状况


1.高凝聚力
2.群体隔离
3.缺乏对搜索和评估的方法学程序
4.支配型领导方式
5.对于找出一个更好的解决方法感到压力大而希望渺茫,认为还不如服从领导或其它有影响力的人物所赞同的方案


在寻求一致性之后==>


群体思维的症状表现


1.无懈可击的错觉
2.对群体道义无可质疑
3.集体合理化
4.对对手的刻板印象
5.对异议者的支配性压力
6.自我潜意识压力
7.一致同意错觉
8.自我指向的心理防御


错误决策的特征


1.对可能性选择方案的不完全调查
2.对目标的不完全调查
3.对所认同的选择方案的冒险估测有误
4.信息搜索不到位
5.对手头信息的加工存在选择性偏见
6.未能对各种选择方案进行重新评估
7.未能执行备用方案




(典型的群体思维的例子还有水门事件和切尔诺贝利核电站事故——Kenny注)


(P.S. 本文是用五笔在累计两次总共不到50分钟的时间内敲完的,且没有检查错别字,用拼音的不服气的可以来试试,全文共计六千多字,录入速度平均为一分钟130个汉字左右。再P.S. 排版竟然比打字还费时间,换个行还得编辑HTML用CODE和BR……


不得不写的一条说明:虽然Apple的iPhone 4天线门(iPhone4 Antenna Gate)有可能是群体思维(groupthink)的产物,但作为局外人我们无法做出这种判断。虽然这次抄书的确是和天线门有关,但我可从来没有说iPhone 4天线门是群体思维的产物——不管看上去多像,也不能就此判断一定是。


Tagged with: