关于作者

用户名:nearxlz
笔名:nearxlz
地区: 中国-北京
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



我的好友

访问统计:
文章个数:32
评论个数:12
留言条数:9




Powered by BlogDriver 2.1

海中一浪

 

我是清华大学计算机系的一名即将毕业的学生。 喜好网络,投资和追求高品质的生活。 希望大家和我成为朋友。

文章

lint使用简介
LINT工具是一种软件质量保证工具许多国外的大型专业软件公司,如微软公司,都把它作为程序检查工具,在程序合入正试版本或交付测试之前一定要保证通过了LINT检查,他们要求软件工程师在使用LINT时要打开所有的编译开关,如果一定要关闭某些开关,那么要给出关闭这些开关的正当理由。

   可想而知,如果从我们编码后第一次编译程序时就使用LINT来检查程序,并且保证消除所有的LINT告警,我们就不会遇到象今天这么多的告警信息。即使 在今天,我们如果能抽出一定的精力来消除程序中的LINT告警,以后再维持这种无告警状态就是很容易的了。我们程序质量的提高也是不言而喻的。

   PC-LINT是GIMPEL SOFTWARE公司的产品,其中的内容是非常广泛的,光是选项就有300多个,涉及到程序编译及语法使用中的方方面 面。本篇培训材料旨在引导读者入门,学会PC-LINT的基本使用方法,起抛砖引玉的作用,能让读者从这里起步继续去研究如何娴熟地使用PC-LINT的 各种选项,能让它充分为我们的开发工作服务。

1.概述
  如果要给LINT工具下一个形象点的定义,那就是:一种更加严格的编译器。它不仅可以象普通编译器那样检查出一般的语法错误,还可以检查出那些虽然完全合乎语法要求,但很可能是潜在的、不易发现的错误。请看下面的例子:
1:
2:char *report( int m, int n, char *p )
3:{
4: int result;
5: char *temp;
6: long nm;
7: int i, k, kk;
8: char name[11] = "Joe Jakeson";
9:
10: nm = n * m;
11: temp = p == "" ? "null" : p;
12: for( i = 0; i 13: {
14: k++;
15: kk = i;
16: }
17:
18: if( k== 1 ) result = nm;
19: else if( kk > 0 ) result = 1;
20: else if( kk < 0 ) result = -1;
21:
22: if( m == result ) return( temp );
23: else return( name );
24:}
   上面的代码用一般的编译器编译是一段有效的代码,但是用PC-LINT编译就会有几个告警。首先第8行向name数组赋值时丢掉了nul字符,第10行 的乘法精度会失准,第11行的比较有问题,第14行的变量k没有初始化,第15行的kk可能没有被初始化,第22行的result也有可能没有被初始化, 第23行返回的是一个局部对象的地址。这段代码在大部分编译器下是可以顺利编译通过的,继续查找其中的错误就要靠人工调试程序,如果程序很大,这将是一项 烦琐的工作,没有人可以保证能找出所有的这类问题,但PC-LINT只通过一次简单的编译就可做到,显然为我们节省了大量的开发时间。

  下面就让我们看看如何安装使用PC-LINT。
2.如何安装PC-LINT
  PC-LINT的软件的安装过程比较复杂,选项较多,下面根据安装过程,逐条说明每一步的含义。
0)如果是zip文件,将ZIP安装文件展开到目录C:\lint.ins下,进入COMMAND PROMPT,先进行目录映射 subst g: c:\lint.ins,然后转到G: , 执行install。其他步骤和下面的从软盘安装是一样的。

1)在A:驱插入PC-LINT安装盘,输入A:\>install命令,进入开始安装栏,按任意键继续,进入PC-LINT介绍栏,再按任意键继续。
2)进入环境选择栏,这一栏中有三个选项:
Windows NT/Windows 95
MS-DOS(DOS extended)
OS/2(32bit)
如果计算机安装了WIN95、WIN97、WIN98或WINNT要选择Windows NT/Windows 95,如果
只有DOS则选择DOS。
3)进入安装目录选择栏,它推荐的是C:\>LINT,如不想安装在这个目录下,可输入自己想要安装的目录,然后按回车确认,如果要安装的目录不存在,它会提示为你建立这个目录。我们这里选C:\>LINT
4)选择安装盘所在的磁盘驱动器,我们这里选A:
5)判断是否要选择多种编译器或编译库的配置,如果要对不同编译环境下的程序进行L
INT,则选YES,否则选NO。然后回车确认。
6)这时看到一个编译器列表,在这个表中选择自己使用的编译器,如果表中没有自己使用的编译器,可选择通用编译器:Generic Compilers。按回车确认。这个选项会体现在co-xxx.lnt文件中。
7)接着安装程序会让你选择一个的内存模型,可以根据自己程序区和数据区的实际大小选择一个恰当的内存模型。如果CPU为32位68K系列,则要选择:32-bit Flat Module。
内存模型的选项会体现在STD.LNT文件中。
8)选完内存模型后,会看到一个库类型的列表,在这里选择一个或多个编译时使用的库。这个选项会体现在LIB-xxx.LNT文件中。
9)接着是让你选择为使用C++编程提出过重要建议的作者,选择的某作者后,他提出的编程建议方面的选项将被打开。与作者选择有关的选项会体现在AU-xxx.LNT文件中。
10) 下一步是设置包含文件目录。有两种选项,第一种是使用环境变量INCLUDE,环境变量在批处理文件中设置,环境变量后每个目录用分号隔开,例如可设成 “INCLUDE=C:\MRI\MCC68K;D:\LAP\SRC\INC”。第二种选项是使用-i选项,-i选项体现在STD.LNT文件中,每个 目录前以-I引导,目录间以空格分隔,例如可设成“-IC:\MRI\MCC68K -ID:\LAP\SRC\INC”。如果选择使用-I选项,安装程 序会接着让你输入包含文件所在的目录。
11) 如果前面选择了使用多个编译环境,这里将会问你是否选择更多的编译环境,如果选YES,将会从第6步开使重复。如果选NO则会结束编译器选择。
12) 接下来将会准备产生一个 反映全局编译信息显示情况的选项文件OPTIONS.LNT,该文件的产生方式有两种,一种是安装程序对几个核心选项逐一解释并 提问你是否取消该选项,如果你选择取消,则会体现在OPTIONS.LNT文件中,具体体现方式是在该类信息编码前加-e,后面第13~18步是逐一选择 核心选项的过程。如果选择第二种选择方式,安装文件会先生成一个空的OPTIONS.LNT文件,等你以后在实际应用时加入必要的选项。
13)是否关闭赋值时的布尔测试告警,如:if(a=f()){...
14)是否关闭赋值时的有符号量和无符号量间的不匹配告警,通常情况下,这种赋值不会带来问题,选择关闭该告警信息的同时,其他类型的有符号量和无符号量间混合操作的告警仍然是打开的。
15)当把一个整形量赋值给一个比它短的量时,后者会丢失精度,例如把一个INT量赋值给给一个CHAR量。本步是让你选择是否关闭该类告警。
16)是否关闭左移带符号量的告警。通常PC-LINT会对所有带符号量的移动产生告警,但右移一般是由不同的CPU来确定是否将符号位移入,左移一般是不会产生什么问题的,所以可以选择关闭该告警。
17)在一个C函数被定义或声明前调用它,并不总是会产生错误,在这里可以选择是否关闭该告警选项。该选项对C++程序不起作用。
18)是否关闭“调用不存在的函数原型”告警。有些程序员不愿遵守严格的函数原形定义约定,但PC-LINT会在调用一个没有定义的函数原型时产生一个告警,在这里可以选择关闭该告警。
19) 通过上面的步骤确定OPTIONS.LNT文件的形式后,接着是选择编译环境。PC-LINT提供了集成在多种开发环境中工作的功能,例如可集成在VC、 BC、Source Insight中。假如我们在这里选择Source Insight。选择后安装程序会继续问你是否还选择其它的环境,可根据自己应 用的实际情况选择一种或多种开发环境。开发环境的选择情况记录在env-xxx.lnt文件中。
20)安装程序会生成一个LIN.BAT文件,该 文件是运行PC-LINT的批处理文件,为了使该文件能在任何路径下运行,安装程序提供了两种方法供你选择。第一种方法是让你选择把LIN.BAT拷贝到 任何一个PATH目录下,在安装结束运行LCOPY.BAT文件时,会把LIN.BAT拷贝到你指定的目录。第二种方法是生成一个LSET.BAT文件, 在每次使用PC-LINT前先运行它来设置路径,或者把LSET.BAT文件的内容拷贝到AUTOEXEC.BAT文件中。
21)在安装程序执行完后第一件事是在你安装的目录下执行LCOPY.BAT文件。它会从安装盘拷贝将一些文件拷贝到安装目录下,并根据你在安装过程中的选择来设置文件中的参数。
3.LINT 一个C文件
3.1用命令行方式进行LINT
如 果使用LIN.BAT批处理文件进行LINT,在LINT前要先看一下该批处理文件中的内容,里面包含了LINT-NT命令和命令选项,可以根据自己的要 求来修改、增减选项。我们看到,在这个批命令中嵌套了一个std.lnt文件,在std.lnt文件中还嵌套了co.lnt、options.lnt和 lib-stl.lnt文件,原则上*.lnt文件是可以无限制嵌套,该类文件中一般都是了LINT的选项,可通过修改这些文件来修改LINT选项,选项 是按照从左到右的顺序执行的。可执行下面命令行:
C:\abc\src>lin alpha.c beta.c gamma.c
通常对于由多个C模块组成的程序,最好先分别对每个C模块单元进行LINT检查,做单元LINT时可如下运行:
C:\abs\src>lin -u alpha.c
其中-u是单元选项,使用-u后可以关闭一些检查多模块时会产生的告警,例如“函数未被使用”或“函数没有定义”等。
也 可以不使用LIN.BAT批处理文件,而直接使用LINT命令。在DOS环境下LINT命令为LINT.EXE,在Windows95/NT环境下为 LINT-NT.EXE,在OS2环境下为LINT-OS2.EXE。直接使用LINT命令要注意的一点是要在使用前预先设置LINT目录所在路径,最好 的方法是把该路径加在AUTOEXEC.BAT文件中。其它的使用方法与使用批处理文件相同。例如:
C:\abs\src>lint-nt -ic:\lint\ std.lnt -os(_lint.tmp) *.c
3.2用开发环境进行LINT
也可以使用开发环境来执行LINT操作,一般开发环境都支持运行可执行文件,但不一定支持运行批处理文件,下面用Source Insight , Ultra Edit, MSVC 6.0 来举例说明如何在开发环境下进行LINT。
3.2.1 在Source Insight中集成
如 果你在安装过程中选定了使用某个开发环境,安装程序会在你安装的目录下生成一个env-xxx.lnt的文件,例如选择了Source Insight就 会有一个env-si.lnt文件。用编辑器打开该文件,在该文件开始的注释中说明了如何将PC-LINT功能集成在开发环境中,集成在 Source Insight中的过程如下:
1)从Options菜单中选择“Custom Commands”命令项。
2)在Name栏中输入“PC-lint ”,原则上这个名称可以随便起,只要你能搞清楚它的含义就可以了。
3)在Run栏中输入“c:\lint\lint-nt -u -ic:\lint std env-si %f”其中c:\lint是你PC-LINT的安装目录。
4)在Output栏中选择“Iconic Window”、“Capture Output”。
5)在Control栏中选择“Save Files First”。
6)在Source Links in Output栏中选择“Parse Links in Output”、“File,then Line”。
7)在Pattern栏中输入“^\([^ ]*\) \([0-9]+\)”。
8)点Add键加入该命令。如下图:
9)使用时,在Source Insight下打开要LINT的文件,打开Options菜单中的“Custom Commands”命令项,在“Command”栏中选择“PC-lint unit check”命令运行即可。
注意到我的Run一栏的参数和上面的提示不一样,其实我的其他古怪参数都放到c:\lint\std.lnt中了。请注意,不论你怎样配置参数一定不要忘记了将si-env.lnt包含在你的配置文件里,否则就无法进行错误信息和程序的自动对应了。
为了使用方便,你还可以配置一下Menu按钮,将它加到系统菜0单里,这属于一般性的
Source Insight应用,笔者就不在此赘述了。
第二笔者在NT中使用Source Insight时,好象集成不了,原因暂时不明了。上面的例子在WIN 95下测试成功。
如果要修改LINT选项,可直接在Run栏中修改,也可专门编辑一个*.lnt文件放在c:\lint目录下,并将该文件名加入Run栏中,和命令行方式是一样的。
3.2.2在Ultra Editor中集成
选取 Menu | Advanced | Tool Configuration ... , 显示如下图:
1)点按“Insert",
2)在command line:中填写:c:\lint\lint-nt c:\lint\std.lnt %f
3)在Menu Item中填写:PC-LINT
4)在Command Output中选择: (x) Output to List Box 和 (x) Capture Output
5)点按"OK"
如图所示的配置笔者在UE6.0 / NT 4.0 下测试成功。
3.2.3 在MSVC 6.0中集成
基本原理是一样的:
1)选取 menu | tools | customize.....
2)选取 Tools Tab:
3)点按主对话框上方的虚线小方框 New a tool item
4)输入 name: PC-LINT
5)输入 Command: c:\lint\lint-nt.exe
6)输入 Arguments: c:\lint\std.lnt $(FilePath)
7) 选择 (x) Use Output Window
8)Close
完成后,在tools菜单下就会有一项PC-LINT选项。
下面是笔者在VC6 / Win NT 4.0 的情况下的TOOL配置图:
3.3LINT选项
LINT选项可以放在注释中,例如:
/*lint option1 option2 ... optional commentary */
//lint option1 option2 ... optional commentary
选 项间要以空格分开,lint命令一定要小写,并且紧跟在/*或//后面,不能有空格。如果选项由类似于操作符和操作数的部分组成,例如-esym (534, printf, scanf, operat or new),其中最后一个选项是operator new,那么在operator和 new中间只能有一个空
格。
选项还可以放在宏定义中,例如:
#define DIVZERO(x) /*lint -save -e54 */ ((x) /o) /*lint -restore */
LINT的选项很多共有300多种,大体可分为以下几类:
1)错误信息禁止选项
该类选项是用于禁止生成某类错误信息的选项,最常用的是-e和+e,-e是禁止生成某类错误信息,+e是恢复生成某类错误信息。运行lint目录下的msg.exe可以得到msg.txt文件,这个长达5000行的文件包含了所有的错误信息号和解释。
-w 对于所有大于级别的告警信息都不显示。
-wlib()对于所有大于级别的关于库函数数的告警信息都不显示。我们可以用-wlib(0)来屏蔽所有的库函数的告警信息,-wlib(1)只显示库函数中的句法错误。
-esym(#,) 可以屏蔽对于特定符号的某告警信息。
2)变量类型大小选项
不 同的目标机、编译系统变量类型的的大小(如短整形变量、整形变量等)会有所不同,该类选项用于为目标机设置变量类型的大小。由于默认的设置与大部分的编译 器是匹配的,这些专门的设置通常情况下是不需要的,只在特别的目标机结构中才用。例如一个M68000目标机,它的int类型和指针类型通常是32bit 的,这时你应该使用选项:-si4
-sp4。这些尺寸参数的当前值可以通过help屏来获得,例如可以输入以下命令行:
lin -si4 -sp4 ?
3)冗长信息选项
冗长信息指的是LINT过程中产生的一些与编译过程有关的信息,而不是真正的告警信息、错误信息等。是否生成这些信息可以通过-v和+v选项来决定。+v是生成这些信息,-v是关闭这些信息,这组选项中除+v外,其它所有选项都可以关闭+v选项。
4)标记选项
以+f、++f、-f和--f开头的选项是标记选项。他们的逻辑含义分别如下:
+f...:通过把标志置为1而把它置为ON
-f...:通过把标志置为0而把它置为OFF
++f...:标志增1
--f...:标志减1
后面两个用于你想在局部把一个标志置为ON的情况,而不影响全局设置。例如你可以这样使用:
/*lint ++flb */
int printf( );
/*lint --flb */
标记选项的种类很多,基本含义是用于打开或关闭某类语法情况使用,例如允许使用缩写结构体名称,允许使用无名联合体,把所有模块当作C++编译等。
5)消息显示选项
消息显示选项用于定义消息输出格式。主要有消息高度选项、消息宽度选项、消息格式选项等。
6)其它选项
其 它选项中的种类很多,各种类间差异很大,在这里就不一一介绍了,建议大家看一看《PC-LINT》一书,第五章有对每种选项的详细说明。lint本身也有 一些说明信息, lint-nt 2> lint.txt 然后狂按几个回车就可以生成一个lint选项的说明文件。
4.LINT一个工程下的多个C文件
4.1为何要LINT多个C文件
在 程序编码初期,我们关心的可能只是单个C模块种中的语法问题,等到编程后期,对于由多个C模块组成的程序,我们希望了解当把多个模块连接在一起后是否还有 存在于模块间的语法问题。这时编译器虽然能给出一些告警,但PC-LINT的连接能给出更多的告警。还有当我们能保证其中的几个模块相对稳定,而另外几个 模块仍有问题时可以先将几个稳定的模块编译连接成一个目标文件,文件每次修改完成后先单独编译,然后连接入总的目标文件。
4.2如何LINT一个工程下的多个C文件
象 我们平时使用的编译工具一样,PC-LINT在编译连接多个C文件时也会先把每个C文件编译生成中间的目标文件*.lob,然后再将所有的LOB文件连接 在一起。LOB是Lint Object Module的缩写。这个文件中包含了一个C或C++模块的所有外部信息。生成LOB文件时有三种选项要注意: 第一种是-u,如果要LINT生成LOB文件,就一定要加-u选项;第二种是-zero或-zero(500)选项,为了保证LOB文件在模块存在错误的 情况下也能生成,就一定要加这个选项;第三种是-oo[(filename)],filename是生成的LOB文件的名称,在-oo后面,可加,也可不 加,如不加,则LOB文件名与原C模块的名称相同,例如:
lint -u alpha.c -oo(a1)
生成的LOB文件名为:a1.lob
lint -u alpha.c -oo
生成的LOB文件名为:alpha.lob
LINT一个工程下的多个C模块,在用户的源程序目录下一般需要三个文件: 一个选项文件(*.lnt)、一个批处理文件(*.bat)和一个MAKEFILE文件(*.mak)。下面一一讲述如何制作这些文件。
1)选项文件(*.lnt)
选项文件在前面也提到过,你可以把你LINT每个C文件时时用到的所有公共选项罗列在该文件中,选项生效的顺序按照从左到右,从上到下的原则。该类文件可以层层嵌套,嵌套的层数没有限制。例如make.lnt文件:
-iC:\lint
std.lnt
+os(temp)
-e46
+vm
-zero
2)批处理文件(*.bat)
制作批处理文件时要注意要在该文件中调用TCMAKE.EXE文件和MAKEFILE文件,例如lintmake.mak文件:
@echo Lint Making 'makelap':
tcmake -flintmake.mak
@echo End of making
3)MAKEFILE文件(*.mak)
MAKEFILE使用的TCMAKE的语法,和我们平时开发编译时使用的MAKEFILE文件语法格式一样,例如下面的lintmake.mak文件:
MCCPATH = c:\mcc68k
OPTION = -u make.lnt -oo
GLOBLE = os.h l2lap.h
mail_depend = $(GLOBLE) q931.h mail.h
lapmain_depend = $(GLOBLE) l1pubdef.h q931.h mail.h
lapos_depend = $(GLOBLE)
fhdlc1_depend = $(GLOBLE) cpuhdlc.h bd_prar.h q931.h
OBJ = mail.lob lapmain.lob lapos.lob fhdlc1.lob
project.lob : $(OBJ)
lint-nt make.lnt -e768 -e769 *.lob
mail.lob: mail.c $(mail_depend)
lint-nt $(OPTION) mail.c
lapmain.lob: lapmain.c $(lapmain_depend)
lint-nt $(OPTION) lapmain.c
lapos.lob: lapos.c $(lapos_depend)
lint-nt $(OPTION) lapos.c
fhdlc1.lob: fhdlc1.c $(fhdlc1_depend)
lint-nt $(OPTION) fhdlc1.c
4.3简单的LINT多个文件
假设我们的工程不复杂,我们可以负担起每次都将所有的文件都lint一遍的开销,也可以不使用上面的正规用法。笔者在实践中发现,将所有的*.c文件放在一个lint命令中,同样能完成lint整个工程的目的。
如:
lint-nt c:\lint\std.lnt AllMySource.lnt
在AllMySource.lnt中包括你的工程中的所有源文件:
a1.c
a2.c
a3.c
需要注意的是,在std.lnt文件中就不需要-u选项了。因为我们已经提供了所有的信息

- 作者: nearxlz 2006年04月29日, 星期六 11:05  回复(2) |  引用(0) 加入博采

asmlinkage的作用
相信大家在看linux的source code的时候,都会注意到asmlinkage这个宏,它是用来做什么的呢?

The asmlinkage tag is one other thing that we should observe about this simple function. This is a #define for some gcc magic that tells the compiler that the function should not expect to find any of its arguments in registers (a common optimization), but only on the CPU's stack. Recall our earlier assertion that system_call consumes its first argument, the system call number, and allows up to four more arguments that are passed along to the real system call. system_call achieves this feat simply by leaving its other arguments (which were passed to it in registers) on the stack. All system calls are marked with the asmlinkage tag, so they all look to the stack for arguments. Of course, in sys_ni_syscall's case, this doesn't make any difference, because sys_ni_syscall doesn't take any arguments, but it's an issue for most other system calls.

看一下/usr/include/asm/linkage.h里面的定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是关键字,是gcc的C语言扩展,regparm(0)表示不从寄存器传递参数

如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数。

- 作者: nearxlz 2006年04月28日, 星期五 10:38  回复(0) |  引用(0) 加入博采

Software Architecture
  软件架构software architecture)是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。 软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个或者对象。在面向对象领域中,组件之间的连接通常用接口_(计算机科学)来实现。

    软件体系结构是构建计算机软件实践的基础。与建筑师设定建筑项目的设计原则和目标,作为绘图员画图的基础一样,一个软件架构师或者系统架构师陈述软件构架以作为满足不同客户需求的实际系统设计方案的基础。

      软件构架是一个容易理解的概念,多数工程师(尤其是经验不多的工程师)会从直觉上来认识它,但要给出精确的定义很困难。特别是,很难明确地区分设计和构架:构架属于设计的一方面,它集中于某些具体的特征。

      在“软件构架简介”中,David GArlan 和 Mary Shaw 认为软件构架是有关如下问题的设计层次:“在计算的算法和数据结构之外,设计并确定系统整体结构成为了新的问题。结构问题包括总体组织结构和全局控制结 构;通信、同步和数据访问的协议;设计元素的功能分配;物理分布;设计元素的组成;定标与性能;备选设计的选择。”[GS93]

      但构架不仅是结构;IEEE Working Group on Architecture 把其定义为“系统在其环境中的最高层概念”[IEEE98]。构架还包括“符合”系统完整性、经济约束条件、审美需求和样式。它并不仅注重对内部的考虑,而且还在系统的用户环境和开发环境中对系统进行整体考虑,即同时注重对外部的考虑。

      在 Rational Unified ProcESs 中,软件系统的构架(在某一给定点)是指系统重要构件的组织或结构,这些重要构件通过接口与不断减小的构件与接口所组成的构件进行交互。

    从和目的、主题、材料和结构的联系上来说,软件架构可以和建筑物的架构相比拟。一个软件架构师需要有广泛 的软件理论知识和相应的经验来事实和管理软件产品的高级设计。软件架构师定义和设计软件的模块化,模块之间的交互,用户界面风格,对外接口方法,创新的设 计特性,以及高层事物的对象操作、逻辑和流程。

  是一般而言,软件系统的架构(ArchitECture)有两个要素:

  ·它是一个软件系统从整体到部分的最高层次的划分。

  一个系统通常是由元件组成的,而这些元件如何形成、相互之间如何发生作用,则是关于这个系统本身结构的重要信息。

  详细地说,就是要包括架构元件(Architecture Component)、联结器(Connector)、任务流(TASk-flow)。所谓架构元素,也就是组成系统的核心"砖瓦",而联结器则描述这些元件之间通讯的路径、通讯的机制、通讯的预期结果,任务流则描述系统如何使用这些元件和联结器完成某一项需求。

  ·建造一个系统所作出的最高层次的、以后难以更改的,商业的和技术的决定。

  在建造一个系统之前会有很多的重要决定需要事先作出,而一旦系统开始进行详细设计甚至建造,这些决定就很难更改甚至无法更改。显然,这样的决定必定是有关系统设计成败的最重要决定,必须经过非常慎重的研究和考察。

      历史
      早在1960年代,诸如E·W·戴克斯特拉就已经涉及软件架构这个概念了。自1990年代以来,部分由于在 Rational Software Corporation 和MiCROSoft内部的相关活动,软件架构这个概念开始越来越流行起来。

      卡内基梅隆大学和加州大学埃尔文分校在这个领域作了很多研究。卡内基·梅隆大学的Mary Shaw和David Garlan于1996年写了一本叫做 Software Architecture perspective on an emerging DIscipline的书,提出了软件架构中的很多概念,例如软件组件、连接器、风格等等。 加州大学埃尔文分校的软件研究院所做的工作则主要集中于架构风格、架构描述语言以及动态架构。

  计算机软件的历史开始于五十年代,历史非常短暂,而相比之下建筑工程则从石器时代就开始了,人类在几千年的建筑设计实践中积累了大量的经验和教训。建筑设计基本上包含两点,一是建筑风格,二是建筑模式。独特的建筑风格和恰当选择的建筑模式,可以使一个独一无二。

  下面的照片显示了中美洲古代玛雅建筑,Chichen-Itza大金字塔,九个巨大的石级堆垒而上,九十一级台阶(象征着四季的天数)夺路而出,塔顶的神殿耸入云天。所有的数字都如日历般严谨,风格雄浑。难以想象这是石器时代的建筑物。


图1、位于墨西哥Chichen-Itza(在玛雅语中chi意为嘴chen意为井)的古玛雅建筑。(摄影:作者)

  软件与人类的关系是架构师必须面对的核心问题,也是自从软件进入历史舞台之后就出 现的问题。与此类似地,自从有了建筑以来,建筑与人类的关系就一直是建筑设计师必须面对的核心问题。英国首相丘吉尔说,我们构造建筑物,然后建筑物构造我 们(We shape our buildings, and afterwaRDS our buildings shape us)。英国下议院的会议厅较狭窄,无法使所有的下议院议员面向同一个方向入座,而必须分成两侧入座。丘吉尔认为,议员们入座的时候自然会选择与自己政见 相同的人同时入座,而这就是英国政党制的起源。Party这个词的原意就是"方"、"面"。政党起源的关键就是建筑物对人的影响。

  在软件设计界曾经有很多人认为功能是最为重要的,形式必须服从功能。与此类似地,在建筑学界,现代主义建筑流派的开创人之一Louis Sullivan也认为形式应当服从于功能(FORMs follows function)。

  几乎所有的软件设计理念都可以在浩如烟海的建筑学历史中找到更为遥远的历史回响。最为著名的,当然就是模式理论和XP理论。

  架构的目标是什么

  正如同软件本身有其要达到的目标一样,架构设计要达到的目标是什么呢?一般而言,软件架构设计要达到如下的目标:

  ·可靠性(Reliable)。软件系统对于用户的商业经营和管理来说极为重要,因此软件系统必须非常可靠。

  ·安全行(Secure)。软件系统所承担的交易的商业价值极高,系统的安全性非常重要。

  ·可扩展性(Scalable)。软件必须能够在用户的使用率、用户的数目增加很快的情况下,保持合理的性能。只有这样,才能适应用户的市场扩展得可能性。

  ·可定制化(CuSTomizable)。同样的一套软件,可以根据客户群的不同和市场需求的变化进行调整。

  ·可扩展性(Extensible)。在新技术出现的时候,一个软件系统应当允许导入新技术,从而对现有系统进行功能和性能的扩展

  ·可维护性(MAIntainable)。软件系统的维护包括两方面,一是排除现有的错误,二是将新的软件需求反映到现有系统中去。一个易于维护的系统可以有效地降低技术支持的花费

  ·客户体验(Customer Experience)。软件系统必须易于使用。

  ·市场时机(Time to Market)。软件用户要面临同业竞争,软件提供商也要面临同业竞争。以最快的速度争夺市场先机非常重要。

  架构的种类

  根据我们关注的角度不同,可以将架构分成三种:

  ·逻辑架构、软件系统中元件之间的关系,比如用户界面,数据库,外部系统接口,商业逻辑元件,等等。

  比如下面就是笔者亲身经历过的一个软件系统的逻辑架构图

 


图2、一个逻辑架构的例子

  从上面这张图中可以看出,此系统被划分成三个逻辑层次,即表象层次,商业层次和数据持久层次。每一个层次都含有多个逻辑元件。比如WEB服务器层次中有HTML服务元件、Session服务元件、安全服务元件、系统管理元件等。

  ·物理架构、软件元件是怎样放到硬件上的。

  比如下面这张物理架构图描述了一个分布于北京和上海的分布式系统的物理架构,图中所有的元件都是物理设备,包括网络分流器、代理服务器、WEB服务器、应用服务器、报表服务器、整合服务器、存储服务器、主机等等。


图3、一个物理架构的例子

  ·系统架构、系统的非功能性特征,如可扩展性、可靠性、强壮性、灵活性、性能等。

  系统架构的设计要求架构师具备软件和硬件的功能和性能的过硬知识,这一工作无疑是架构设计工作中最为困难的工作。

  此外,从每一个角度上看,都可以看到架构的两要素:元件划分和设计决定。

  首先,一个软件系统中的元件首先是逻辑元件。这些逻辑元件如何放到硬件上,以及这些元件如何为整个系统的可扩展性、可靠性、强壮性、灵活性、性能等做出贡献,是非常重要的信息。

  其次,进行软件设计需要做出的决定中,必然会包括逻辑结构、物理结构,以及它们如何影响到系统的所有非功能性特征。这些决定中会有很多是一旦作出,就很难更改的。

  根据作者的经验,一个基于数据库的系统架构,有多少个数据表,就会有多少页的架构设计文档。比如一个中等的数据库应用系统通常含有一百个左右的数据表,这样的一个系统设计通常需要有一百页左右的架构设计文档。

      构架描述

      为了讨论和分析软件构架,必须首先定义构架表示方式,即描述构架重要方面的方式。在 Rational Unified Process 中,软件构架文档记录有这种描述。

构架视图

      我们决定以多种构架视图来表示软件构架。每种构架视图针对于开发流程中的涉众(例如最终用户、设计人员、管理人员、系统工程师、维护人员等)所关注的特定方面。

      构架视图显示了软件构架如何分解为构件,以及构件如何由连接器连接来产生有用的形式 [PW92],由此记录主要的结构设计决策。这些设计决策必须基于需求以及功能、补充和其他方面的约束。而这些决策又会在较低层次上为需求和将来的设计决策施加进一步的约束。

典型的构架视图集

      构架由许多不同的构架视图来表示,这些视图本质上是以图形方式来摘要说明“在构架方面具有重要意义”的模型元素。在 Rational Unified Process 中,您将从一个典型的视图集开始,该视图集称为“4+1 视图模型”[KRU95]。它包括:

用例视图:包括用例和场景,这些用例和场景包括在构架方面具有重要意义的行为、类或技术风险。它是用例模型的子集。
逻辑视图:包括最重要的设计类、从这些设计类到包和子系统的组织形式,以及从这些包和子系统到层的组织形式。它还包括一些用例实现。它是设计模型的子集。
实施视图:包括实施模型及其从模块到包和层的组织形式的概览。 同时还描述了将逻辑视图中的包和类向实施视图中的包和模块分配的情况。它是实施模型的子集。
进程视图:包括所涉及任务(进程和线程)的描述,它们的交互和配置,以及将设计对象和类向任务的分配情况。只有在系统具有很高程度的并行时,才需要该视图。在 Rational Unified Process 中,它是设计模型的子集。
配置视图:包括对最典型的平台配置的各种物理节点的描述以及将任务(来自进程视图)向物理节点分配的情况。只有在分布式系统中才需要该视图。它是部署模型的一个子集。
构架视图记录在软件构架文档中。您可以构建其他视图来表达需要特别关注的不同方面:用户界面视图、安全视图、数据视图等等。对于简单系统,可以省略 4+1 视图模型中的一些视图。

      构架重点

      虽然以上视图可以表示系统的整体设计,但构架只同以下几个具体方面相关:

模型的结构,即组织模式,例如分层
基本元素,即关键用例、主类、常用机制等,它们与模型中的各元素相对。
几个关键场景,它们表示了整个系统的主要控制流程。
记录模块度、可选特征、产品线状况的服务。

      构架视图在本质上是整体设计的抽象或简化,它们通过舍弃具体细节来突出重要的特征。在考虑以下方面时,这些特征非常重要:

系统演进,即进入下一个开发周期。
在产品线环境下复用构架或构架的一部分。
评估补充质量,例如性能、可用性、可移植性和安全性。
团队或分包商分配开发工作。
决定是否包括市售构件。
插入范围更广的系统。

构架模式

      构架模式是解决复发构架问题的现成形式。构架框架或构架基础设施(中间件)是可以在其上构建某种构架的构件集。许多主要的构架困难应在框架或基础设施中进行解决,而且通常针对于特定的领域:命令和控制、MIS、控制系统等等。

构架模式示例

      [BUS96] 根据构架模式最适用的系统的特征将其分类,其中一个类别处理更普遍的结构问题。下表显示了 [BUS96] 中所提供的类别和这些类别所包含的模式。

类别 模式
结构
管道和过滤器
黑板
分布式系统 代理
交互系统 模型-视图-控制器
表示-抽象-控制
自适应系统 反射
微核

      软件构架是一个容易理解的概念,多数工程师(尤其是经验不多的工程师)会从直觉上来认识它,但要给出精确的定义很困难。特别是,很难明确地区分设计和构架:构架属于设计的一方面,它集中于某些具体的特征。

      在“软件构架简介”中,David Garlan 和 Mary Shaw 认为软件构架是有关如下问题的设计层次:“在计算的算法和数据结构之外,设计并确定系统整体结构成为了新的问题。结构问题包括总体组织结构和全局控制结 构;通信、同步和数据访问的协议;设计元素的功能分配;物理分布;设计元素的组成;定标与性能;备选设计的选择。”[GS93]

       但构架不仅是结构;IEEE Working Group on Architecture 把其定义为“系统在其环境中的最高层概念”[IEEE98]。构架还包括“符合”系统完整性、经济约束条件、审美需求和样式。它并不仅注重对内部的考虑, 而且还在系统的用户环境和开发环境中对系统进行整体考虑,即同时注重对外部的考虑。

      在 Rational Unified Process 中,软件系统的构架(在某一给定点)是指系统重要构件的组织或结构,这些重要构件通过接口与不断减小的构件与接口所组成的构件进行交互。

为阐明其含义,下面将详述其中的两个;完整说明请参见 [BUS96]。模式以下列广泛使用的形式来表示:

模式名
环境
问题
影响,描述应考虑的不同问题方面
解决方案
基本原理
结果环境
示例
模式名

环境
需要进行结构分解的大系统。

问题
必须处理不同抽象层次的问题的系统。例如:硬件控制问题、常见服务问题和针对于不同领域的问题。最好不要编写垂直构件来处理所有抽象层次的问题。否则要在不同的构件中多次处理相同的问题(可能会不一致)。

影响

系统的某些部分应当是可替换的
构件中的变化不应波动
相似的责任应归为一组
构件大小 -- 复杂构件可能要进行分解
解决办法
将系统分成构件组,并使构件组形成层叠结构。使上层只使用下层(决不使用上层)提供的服务。尽量不使用非紧邻下层提供的服务(不跳层使用服务,除非中间层只添加通过构件)。

示例:

1. 通用层


 

严格的分层构架规定设计元素(类、构件、包、子系统)只能使用下层提供的服务, 服务可以包括事件处理、错误处理、数据库访问等等。  相对于记录在底层的原始操作系统级调用,它包括更明显的机制。

2. 业务系统层

上图显示了另一个分层示例,其中有垂直特定应用层、水平层和基础设施层。注意:此处的目标是采用非常短的业务“烟囱”并实现各种应用程序间的通用性。  否则,就可能有多个人解决同一问题,从而导致潜在的分歧。

有关该模式的深入讨论,请参见指南:分层。

模式名
黑板

环境
没有解决问题的确定方法(算法)或方法不可行的领域。例如 AI 系统、语音识别和监视系统。

问题
多个问题解决顾问(知识顾问)必须通过协作来解决他们无法单独解决的问题。各顾问的工作结果必须可以供所有其他顾问访问,使他们可以评估自己是否可以参与解决方案的查找并发布其工作结果。

影响

知识顾问参与解决问题的顺序不是确定的,这可能取决于问题解决策略

不同顾问的输入(结果或部分解决方案)可能有不同的表示方式

各顾问并不直接知道对方的存在,但可以评估对方发布的工作

解决办法
多名知识顾问都可访问一个称为“黑板”的共享数据库。黑板提供监测和更新其内容的接口。控制模块/对象激活遵循某种策略的顾问。激活后,顾问查看黑板,以确定它是否能参与解决问题。如果顾问决定它可以参与,控制对象就可以允许顾问将其部分(或最终)解决方案放置于黑板上。

示例:

以上显示了使用 UML 建模的结构或静态视图。 它将成为参数化协作的一部分,然后会绑定到实参上对模式进行实例化。

构架风格
软件构架(或仅是构架视图)可以具有名为构架风格 的属性,该属性减少了可选的形式,并使构架具有一定程度的一致性。样式可以通过一组模式或通过选择特定构件或连接器作为基本构件来定义。对给定系统,某些 样式可作为构架描述的一部分记录在构架风格指南(Rational Unified Process 中设计指南文档的一部分)中。样式在构架的可理解性与完整性方面起着主要的作用。

构架设计图
构架视图的图形描述称为构架设计图。对于以上描述的各种视图,设计图由以下统一建模语言图组成 [UML99]:

逻辑视图:类图、状态机和对象图
进程视图:类图与对象图(包括任务 - 进程与线程)。
实施视图:构件图。
部署视图配置图
用例视图:用例图描述用例、主角和普通设计类;顺序图描述设计对象及其协作关系。
构架设计流程
在 Rational Unified Process 中,构架主要是分析设计工作流程的结果。当项目再次进行此工作流程时,构架将在一次又一次迭代中不断演化、改进、精炼。由于每次迭代都包括集成和测试,所以在交付产品时,构架就相当强壮了。构架是精化阶段各次迭代的重点,构架的基线通常会在此阶段结束时确定。

  架构师

  软体设计师中有一些技术水平较高、经验较为丰富的人,他们需要承担软件系统的架构设计,也就是需要设计系统的元件如何划分、元件之间如何发生相互作用,以及系统中逻辑的、物理的、系统的重要决定的作出。

  这样的人就是所谓的架构师(Architect)。在很多公司中,架构师不是一个专门的和正式的职务。通常在一个开发小组中,最有经验的程序员会负责一些架构方面的工作。在一个部门中,最有经验的项目经理会负责一些架构方面的工作。

  但是,越来越多的公司体认到架构工作的重要性,并且在不同的组织层次上设置专门的架构师位置,由他们负责不同层次上的逻辑架构、物理架构、系统架构的设计、配置、维护等工作。

卡内基梅隆大学软件研究所关于软件架构的定义

- 作者: nearxlz 2006年04月28日, 星期五 10:23  回复(0) |  引用(0) 加入博采

C++中extern “C”含义深层探索
 

1.引言

C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言,C++保留了一部分过程 式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支 持函数的重载,C++对全局函数的处理方式与C有明显的不同。

2.从标准头文件说起



某企业曾经给出如下的一道面试题:

面试题:为什么标准头文件都有类似以下的结构?

#ifndef __INCvxWorksh

#define __INCvxWorksh

#ifdef __cplusplus

extern "C" {

#endif

/*...*/

#ifdef __cplusplus

}

#endif

#endif /* __INCvxWorksh */

分析

显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用是防止该头文件被重复引用。

那么

#ifdef __cplusplus

extern "C" {

#endif

#ifdef __cplusplus

}

#endif

的作用又是什么呢?我们将在下文一一道来。

3.深层揭密extern "C"



extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。让我们来详细解读这两重含义。

被extern "C"限定的函数或变量是extern类型的;

extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。记住,下列语句:

extern int a;

仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。

通 常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只 需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生 成的目标代码中找到此函数。

与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。

被extern "C"修饰的变量和函数是按照C语言方式编译和连接的;

未加extern “C”声明时的编译方式

首先看看C++中对类似C的函数是怎样编译的。

作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:

void foo( int x, int y );

该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。

foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。

同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本 质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

未加extern "C"声明时的连接方式

假设在C++中,模块A的头文件如下:

// 模块A头文件 moduleA.h

#ifndef MODULE_A_H

#define MODULE_A_H

int foo( int x, int y );

#endif

在模块B中引用该函数:

// 模块B实现文件 moduleB.cpp

#include "moduleA.h"

foo(2,3);

实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号!

加extern "C"声明后的编译和连接方式

加extern "C"声明后,模块A的头文件变为:

// 模块A头文件 moduleA.h

#ifndef MODULE_A_H

#define MODULE_A_H

extern "C" int foo( int x, int y );

#endif

在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:

(1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;

(2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。

如果在模块A中函数声明了foo为extern "C"类型,而模块B中包含的是extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。

所 以,可以用一句话概括extern “C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么 做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):

实现C++与C及其它语言的混合编程。

明白了C++中extern "C"的设立动机,我们下面来具体分析extern "C"通常的使用技巧。

4.extern "C"的惯用法

(1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:

extern "C"

{

#include "cExample.h"

}

而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。

笔者编写的C++引用C函数例子工程中包含的三个文件的源代码如下:

/* c语言头文件:cExample.h */

#ifndef C_EXAMPLE_H

#define C_EXAMPLE_H

extern int add(int x,int y);

#endif

/* c语言实现文件:cExample.c */

#include "cExample.h"

int add( int x, int y )

{

return x + y;

}

// c++实现文件,调用add:cppFile.cpp

extern "C"

{

#include "cExample.h"

}

int main(int argc, char* argv[])

{

add(2,3);

return 0;

}

如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }。

(2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。

笔者编写的C引用C++函数例子工程中包含的三个文件的源代码如下:

//C++头文件 cppExample.h

#ifndef CPP_EXAMPLE_H

#define CPP_EXAMPLE_H

extern "C" int add( int x, int y );

#endif

//C++实现文件 cppExample.cpp

#include "cppExample.h"

int add( int x, int y )

{

return x + y;

}

/* C实现文件 cFile.c

/* 这样会编译出错:#include "cExample.h" */

extern int add( int x, int y );

int main( int argc, char* argv[] )

{

add( 2, 3 );

return 0;

}


- 作者: nearxlz 2006年04月27日, 星期四 17:52  回复(1) |  引用(0) 加入博采

extern作用总结

extern int i;
指明这里的i只是声明,否则i为全局变量的话会看作定义,有可能违反一次定义法则(ODR)
   
extern foo();
将函数"在其他地方定义"变为显式的
   
 extern的作用是不包.h文件也能用,如果你函数在.h里面声明过,而且在其它.c文件里面你包括进来,可以不用extern

- 作者: nearxlz 2006年04月27日, 星期四 17:50  回复(0) |  引用(0) 加入博采

浅谈static
主要内容:

一. 面向过程程序设计中的static
   1. 全局静态变量
   2. 局部静态变量
   3. 静态函数(可不是静态成员函数哦)

二. 面向对象程序设计中的static
   1. 静态数据成员
   2. 静态成员函数
 
一. 面向过程程序设计中的static

1. 全局静态变量

   在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。

   1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)

   2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非
他被显示初始化)

   3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结
尾。
  
   看下面关于作用域的程序:
//testStatic1.cpp
#i nclude <iostream>
using namespace std;
 
void display();
extern int n;
 
int main()
{
  n = 20;
  cout << n << endl;
  display();
  return 0;
}
 
//testStatic2.cpp
#i nclude <iostream>
using namespace std;
 
static int n;   //定义全局静态变量,自动初始化为0,仅在本文件中可见

void display()
{
  n++;
  cout << n << endl;
}
 

文件分别编译通过,但link的时候testStatic1.cpp中的变量n找不到定义,产生错误。
 
定义全局静态变量的好处:

<1>不会被其他文件所访问,修改

<2>其他文件中可以使用相同名字的变量,不会发生冲突。
 

2 局部静态变量

  在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。

  1)内存中的位置:静态存储区

  2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非
他被显示初始化)

  3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。

  注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改
为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。

      当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是
不可见的),但是没有改变它的存放位置,还是在静态存储区中。
 
3 静态函数

  在函数的返回类型前加上关键字static,函数就被定义成为静态函数。

  函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其
他文件所用。

  例如:
//testStatic1.cpp
#i nclude <iostream>
using namespace std;
 
void display();
void staticDis();
 
int main()
{
  display();
  staticDis();
  renturn 0;
}
 
//testStatic2.cpp
#i nclude <iostream>
using namespace std;
 
void display()
{
  staticDis();
  cout << "display() has been called " << endl;
}
 
void staticDis()
{
  cout << "staticDis() has been called" << endl;
}
 
文件分别编译通过,但是连接的时候找不到函数staticDis()的定义,产生错误。
 
定义静态函数的好处:

<1> 其他文件中可以定义相同名字的函数,不会发生冲突

<2> 静态函数不能被其他文件所用。
 
存储说明符auto,register,extern,static,对应两种存储期:自动存储期和静态存储期。
 
auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。

关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态
存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。(摘自《C++ Primer》 P337)

由于static变量的以上特性,可实现一些特定功能。

1. 统计次数功能

声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可
以进行计数。这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调用者的角度来统计比较困难。代码如下:
 
#i nclude <stdio>
#i nclude <iostream>
using namespace std;
 
void count();

int main()
{
 int i;
 for (i = 1; i <= 3; i++)
  count();
  return 0;
}
 
void count()
{
 static num = 0;
 num++;
 cout << " I have been called" << num << "times" << endl;
}

输出结果为:
I have been called 1 times.
I have been called 2 times.
I have been called 3 times.
 
二 面向对象程序设计中的static

1. 静态数据成员

   1) 内存中的位置:静态存储区

   2) 初始化和定义:

       <1> 静态数据成员定义时要分配空间,所以不能在类声明中定义。

       <2> 静态数据成员在程序中只能提供一个定义,所以静态数据成员的初始化不能在类的头文
件中。

   3)  访问:

       <1> 类对象名.静态数据成员

       <2> 类类型名::静态数据成员
 
   4) 说明:

       a.static数据成员和普通数据成员一样遵public, protected, private 访问规则。

       b.对于非静态数据成员,每个类对象都有自己的拷贝。静态数据成员被当作类的全局对象,
无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类类型的所有对象共享访问。 

   5) 同全局对象相比,使用静态数据成员有两个优势:

       <1> 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的
可能性。

       <2> 可以实现信息隐藏。静态成员可以是private成员,而全局对象不能。

   6) 应用:

class Account {
    Account( double amount, const string &owner );
    String owner() { return _owner ;}
  private:
    static double _interestRate;
    double _amount;
    string _owner;
};
 
为什把_interestRate声明为static,而_amount和_owner不呢?
这是因为每个Account对应不同的主人,有不同数目的钱,而所有Account的利率却是相同的。

因为在整个程序中只有一个_interestRate数据成员,他被所有Account对象共享,所以把
_interestRate声明为静态数据成员减少了每个Account所需的存储空间。

_interestRate值可能变化,所以不能声明为const。因为_interestRate是静态的,所以它只需要
更新一次我们就可以保证每个Account对象都能访问到更新后的值。要是每个类对象都维持自己的一个拷贝,那么每个拷贝都必须更新,这将导致效率低下和更大的错误可能。

  
  7)静态数据成员的“唯一性”本质(独立于类的任何对象而存在的唯一实例),使他能够以独特
的方式被使用,这些方式对于非static数据成员来说是非法的。

     <1> 静态数据成员的类型可以是其所属类,而非static数据成员只能被声明为该类对象的指针
或引用,例如:
 
class Bar{
  public:
    //...
  private:
    static Bar mem1; //OK
    Bar *mem2;  //OK
    Bar mem3;  //错误
};
 
     <2> 静态数据成员可以被作为类成员函数的缺省实参,而非static数据成员不可以。例如:
 
extern int var;
class Foo {
  private:
    int var;
    static int stcvar;
  public:
    //错误:被解析为非static的Foo:var
    //没有相关的类对象
    int mem1( int = var );
    //OK:解析为static的Foo:stcvar
    //无需相关的类对象
    int mem2( int = stcvar );
    //OK:int var 的全局实例
    int mem3( int = ::var );
};
 
  8) 类模板的静态数据成员以后讨论^-^
 
2. 静态成员函数

  1) 声明:在类的成员函数返回值之前加上关键字static,他就被声明为一个静态成员函数。静
态成员函数不能声明为const或volatile,这与非静态成员函数不同。

  2) 定义:出现在类体外的函数定义不能指定关键字static。

  3) 作用:主要用于对静态数据成员的操作

  4) 静态成员函数与类相联系,不与类的对象相联系。

  5) 静态成员函数不能访问斐静态数据成员。因为非静态数据成员属于特定的类实例。

  6) 静态成员函数没有this指针,因此在静态成员函数中隐式或显示的引用这个指针都将导致编
译时刻错误。试图访问隐式引用this指针的非静态数据成员也会导致编译时刻错误。

  7) 访问:可以用成员访问操作符(.)和箭头(->)为一个类对象或指向类对象的指针调用静态成员
函数,也可以用限定修饰符名直接访问或调用静态成员函数,而无需声明类对象。
(http://www.shineblog.com/user3/qghcim/archives/2006/348398.shtml)

- 作者: nearxlz 2006年04月27日, 星期四 17:28  回复(0) |  引用(0) 加入博采

境界
编程之道,呵呵

Price Wang's programmer was coding software. His fingers danced upon the
keyboard. The program compiled without an error message, and the program ran
like a gentle wind.

###编程大师编写软件时,手指在键盘上快速飞舞。程序编译时没有一条错误信息,程
序运行起来就象一阵微风吹过。

Excellent!" the Price exclaimed, "Your technique is faultless!"

太精彩了!你的技巧已经无可挑剔了。

"Technique?" said the programmer, turning from his terminal, "What I follow
is the Tao -- beyond all technique. When I first began to program I would
see before me the whole program in one mass. After three years I no longer
saw this mass. Instead, I used subroutines. But now I see nothing. My whole
being exists in a formless void. My senses are idle. My spirit, free to work
without a plan, follows its own instinct. In short, my program writes
itself. True, sometimes there are difficult problems. I see them coming, I
slow down, I watch silently. Then I change a single line of code and the
difficulties vanish like puffs of idle smoke. I then compile the program. I
sit still and let the joy of the work fill my being. I close my eyes for a
moment and then log off."

“技巧?”,大师转过身说,“我所遵循的是道--它超乎所有的技巧。当我开始编程时
我看到的是整个一大块的程序,三年后我看到的是子过程。现在我什么也看不到了。我
的整个存在是没有任何形式的虚无。我感觉很悠闲,总之,事实上是我的程序自己在
写,有时我看到一些问题,我看到它们,就停下来静静地观察它们,然后我改变了一行
代码,难题就象一阵轻烟一样化为乌有。然后我编译程序。坐在那里享受工作的喜悦。
闭了一会眼睛然后退出系统。

Price Wang said, "Would that all of my programmers were as wise!"

“什么时候我的程序员才能都达到这样的境界!”
   

- 作者: nearxlz 2006年04月21日, 星期五 10:58  回复(0) |  引用(0) 加入博采

印度人的代码
以前在论坛上听说印度人的代码拖塌冗长,这两天在看
美国印度人的代码,发现果真不错,看得我都快找不到北了 : )
这是一段处理文本的Java代码,先请看美国印度人的代码:
if(osname.startsWith("Windows"))
{
    if(runcmd.stdout == null)
        return null;
    StringTokenizer stringtokenizer = new StringTokenizer(runcmd.stdout.toSt
ring());
    Hashtable hashtable = null;
    Object obj = null;
    String s2 = null;
    String s5 = null;
    while(stringtokenizer.hasMoreTokens())
    {
        String s6 = stringtokenizer.nextToken();
        if(s6.equals("Type"))
            break;
    }
    while(stringtokenizer.hasMoreTokens())
    {
        String s1 = stringtokenizer.nextToken();
        if(stringtokenizer.hasMoreTokens())
        {
            s2 = stringtokenizer.nextToken();
            if(stringtokenizer.hasMoreTokens())
                s5 = stringtokenizer.nextToken();
        }
        if(s5 == null || !s5.equals("invalid"))
        {
            if(hashtable == null)
                hashtable = new Hashtable();
            if(s1 != null && s2 != null && !s2.equals("00:00:00:00:00:00"))
                hashtable.put(s1, s2);
        }
    }
    return hashtable;
}
这是我对整个程序结构调整后的部分代码:
if(strOSName.startsWith("Windows"))
{
    StringTokenizer stringtokenizer = new StringTokenizer(strCommandResult);

    String[] strValue = new String[3];
    while(stringtokenizer.hasMoreTokens() && (! stringtokenizer.nextToken().
equals("Type")))
    {//发现"Type"关键字后退出}
    while(stringtokenizer.hasMoreTokens())
    {
        for(int i = 0; i < 3; i++)
            if(stringtokenizer.hasMoreTokens())
              strValue[i] = stringtokenizer.nextToken();
        if(strValue[2] == null || !strValue[2].equals("invalid"))
            if(strValue[0] != null && strValue[1] != null && !strValue[1].eq
uals("00:00:00:00:00:00"))
                hashtable.put(strValue[0], strValue[1]);
    }
}
大家看了之后感觉如何?

- 作者: nearxlz 2006年04月21日, 星期五 10:55  回复(1) |  引用(0) 加入博采

印度程序员vs中国程序员
【 原文由 自由编码员 所发表 】
 印度软件开发

 我在工作中,接触到印度软件公司开发出来的软件:
 整个体系架构非常清晰,按照我们的要求实现了全部功能,而且相当稳定。但
是打开具体的代码一看,拖沓冗长,水平不咋样。我们自己的一些程序员就有怪
话了,说他们水平真低。但是! 印度人能够把软件整体把握得很好,能够完成软
件,并得到相当好的设计文档。 而中国人在那里琢磨数据结构、算法,界面人员
就还没编码就想着是Outlook式的还是Visual Studio式的界面。到最后就成为Co
de高手,对某些特定的开发工具精通,但是就是不能保证能够把一个软件稳当、
完整的开发出来。
 举个简单的例子:
 软件中需要一个列表,用来表示我们处理的事务。该类表在业务繁忙的时候将
变得很大。中国人就用双向链表,抱着《数据结构》书在那里写链表的类。印度
人开了一个大数组,然后就开始干。为什么印度人不用链表,他们说:
 1、你们给出的设备(小型机),最少具备512M内存,浪费一些没有什么。
 2、数组方式访问方便、效率高。
 看出了一拿到东西就吭哧吭哧作Code,和好好进行软件分析的不同了吗?
 正好前几天我有几个同事从印度回来和我们交流,那家公司是CMM4级公司. 我感
受的几点:
 1,流程重于项目
 2,QC(就是QA)独立于研发部门,专门检查研发部门的开发流程是不是按照既定流
程走.如果QC觉得流程不对,他会直接上报高层,项目肯定就此停止.
 3,所谓的项目经理(PC)一般也是从编码人员升上来的,并不是所谓的不懂技术,
一般都至少有四年以上的经验
 4,PC主要就是制定开发计划,负责协调,填写各种表格.
 5,所有的东西(包括草稿)都有文档.
 6,详细文档要求达到只有这个文档就可以编码的程度,一般写文档时间占60%,编
码时间极少 7,有各种详细的review(同行评审),项目组内的,项目组之间的,客户
的...
 8,计划很详细,的确能达到小时级,但是实际情况还是误差比较大,所以他们也有
加 班.
 先学习UML和Rose以及RUP,不要总是要找着证据。 在中国的软件开发水平下,
很难给你一个好的例子,OK? 中国人总是要看到一个东西有了试验田,而且稻子
长得好,才换稻种。要知道在国外上述的软件开发模式的应用,大可以看看Rati
onal网页上的story。Just do it! 一句话,中国的软件开发水平低得很。赶不上
印度人,印度的软件公司可以让高中生编代码,它的软件工程水平可想而知。 当
然,你如果是个很牛的程序员。估计够呛,因为中国的气氛中,很牛的程序员都
很难接受软件工程的。你可以测试一下自己,看看自己适不适合现在学习软件工
程:
 1、你是不是不能忍受一个编程序不如你的人做你的项目经理?
 2、你是不是觉得你的老板对客户吹牛皮、夸大自己而感到不舒服?
 3、你是不是一个拿到一个需求脑袋里第一念头就是如何实现的人?
 4、你是不是很崇拜Stallman,Linus,很讨厌Microsoft?
 5、你是不是曾经在深夜编码的时候,突然感觉到一种乏味,对Code的生涯感到
一种无趣? 以管窥豹──印度神话 作者:"Kino" 我们现在处于深深的自卑当中
,感到中国的软件工程水平的低下已经是牵涉到民族劣根性的问题了。
 1、他们的软件教育水平: 我们招聘印度人,给应聘者出了一份与国内差不多
的试卷,有基础概念和编程题目。 等到他们完成后,我们这些中国的自认高手惊
呆了!他们的编程题目简直象是抄袭的。 程序结构,注释,变量命名就不说了吧
,全部都是极其类似! 反观中国的牛人、高手,每个人有自己的一套。到了新的
岗位,先把前任的程序贬损一通,然后自己再开发更多的问题的代码来代替。我
的公司统计,一个软件中有4个以上 CSocket版本,每个人都觉得别人做得差,自
己再搞一套。中国人,就是这个样子,还会辩解说“我们这样有创造性”。 其实
软件发展,早就走过了求伯君那个编码英雄的年代,程序员已经是个坐办公室的
蓝领了。你具备拧好一个螺丝钉的能力就可以了。Code是最低级的事情了。
 2、他们许多公司的项目经理根本就不懂技术。 中国的项目经理如果不能在技
术上压服下属,那么下属将与他搞鬼,越是高手越喜欢搞鬼,根本不知道作软件
的终极目的是从别人兜里掏钱,而在内部搞不团结。技术高手都会纠集一些对他
技术上崇拜的菜鸟,与管理层作对。而印度的软件经理根本就不懂正在做的东西
,许多甚至直接就是MBA,或者是领域专家 (工业设计、地理专家等),而不是
编码的专家。但是却能够领导大群素质良好的程序 员把工作做好,没有内部不团
结的情况。许多印度的程序员加入一个公司很长时间,都不知道自己整天编的代
码是干什么用的。给他们的任务可能就是一个函数的声明以及该函数要实现的功
能。我们呢?
 3、他们的编程人员的流动率达到30%! 他们的编程人员流动率(包括内部项目
之间的流动)高达30%,可以想见他们的文档水 平如何。他们的产品不依赖任何
一个人,谁都可以立即辞职,产品的开发还是会正常进行。 而中国,是老板怕总
工。技术骨干拥兵自重,抗拒管理。任何制定好的计划,都有可能被技术人员推
翻或者跟你消极怠工。
 4、他们的开发计划能够做到小时级别。 如果一个印度公司的项目经理没有上
班,那么他的下属将可能不知道作什么。他们的计 划一般都定到天,每个基层开
发人员每天的工作量就是8小时。 而我们能够给出月度计划的公司就很少,而给
出的月度计划要么不可能实现,要么就可 能被取消。开发人员被初略的给个任务
,他在月初,可以慢慢琢磨是做成什么样子,然 后上上网,聊聊天。到了月中和
月末,就开始熬夜编码。
 看到每年,从各大高校不尽牛人滚滚来,我们是不得不要召人,同时又是不抱
希望。我 公司现在有意以后将核心软件开发外包给印度公司,中国人?做做界面
吧,中国人做界 面会极尽奇技淫巧,搞得花里胡哨的。 BTW,我公司非外企,大
家不要误会我们有什么种族歧视。但是我们现在就是对自己歧 视,自卑得很。中
科院那么多研究院,连个能用的操作系统都搞不定。北大开发一些东 西,比如什
么青鸟CASE,就是给一帮人评职称的。杨芙清院士整天搞来搞去,搞出了什 么东
西?B大,T大的人最难管理,牛得看不见人。 中国的程序员骂微软,追Linux是
全世界最狠的,可是我们除了汉化Linux,做了什么东 西出来。CDE是瑞典人写的
,Linus是芬兰的,GNome是墨西哥人写的。哎,我们曾经是多么的瞧不起印度人

- 作者: nearxlz 2006年04月21日, 星期五 10:52  回复(5) |  引用(0) 加入博采

编程是一种艺术,也是一种美
 编程是一种艺术,也是一种美:
       对OS的研究如同探索一个未知的山洞,是一种幽深的美;
       研究或设计一个结构良好的软件系统,是一种结构清晰的建筑物式的美;
       对好的编程语言、编程思想、编程模型的研究,就象是欣赏或设计一种
    艺术品内在的美;
       而编写或设计用户界面〔包括可视化〕,是构造一种外在的美,看的见的
    赏心悦目的美;
       编写或设计优良的程序,是一种逻辑的美。
       .....

        可惜的是,画家,就算是称的上艺术家的,也不只是为了艺术而绘画,
    他们也会为了挣到钱而把一个他们自己都不满意的画拿去卖。
    因此,并非所有的画都能成为艺术品,更不提下三流的画家画出的下三流的画了。
    但这些不能说明绘画不是艺术.

        程序员也一样。在多数情况下,程序员,即使是特别苛求完美的程序员,
    也不总是为了"艺术"而编程,可能只把它当成赚money的工具,或偶尔不得不
    仓促为之。这样就可能会有一些编写不良或设计混乱的情况,
    因此并非所有的程序都是艺术品。这也同样不足以证明编程不是艺术。

        与其他艺术一样,编程的美往往有一定的欣赏人群和级别. 风景画每个人
    都能欣赏,而抽象画只有一些人能欣赏。一些人认为美的,另一些人并不认为美。

- 作者: nearxlz 2006年04月21日, 星期五 10:46  回复(0) |  引用(0) 加入博采

程序员的成长历程
一般来说, 一个软件工程师将按如下几个阶段成长下去:

*****高中时代*****
10 PRINT "HELLO WORLD"
20 END

*****大学新生*****
program Hello(input, output)
begin
writeln('Hello World')
end.

*****高年级学生*****
(defun hello
(print
(cons 'Hello (list 'World))))

*****新来的程序员*****
#include <stdio.h>
void main(void)
{
char *message[] = {"Hello ", "World"};
int i;
for(i = 0; i < 2; ++i)
printf("%s", message[i]);
printf("\n");
}

*****经验丰富的程序员*****
#include <iostream.h>
#include <string.h>

class string {
private:
int size;
char *ptr;
public:
string() : size(0),
ptr(new char('\0')) {}
string(const string &s) : size(s.size)
{
ptr = new char[size + 1];
strcpy(ptr, s.ptr);
}
~string()
{
delete [] ptr;
}

friend ostream &operator <<(ostream &, const string &);
string &operator=(const char *);
};

ostream &operator<<(ostream &stream, const string &s)
{
return(stream << s.ptr);
}

string &string::operator=(const char *chrs)
{
if (this != &chrs)
{
delete [] ptr;
size = strlen(chrs);
ptr = new char[size + 1];
strcpy(ptr, chrs);
}
return(*this);
}

int main()
{
string str;
str = "Hello World";
cout << str << endl;
return(0);
}

*****学徒级别的HACKER*****
#!/usr/local/bin/perl
$msg="Hello, world.\n";
if ($#ARGV >= 0) {
while(defined($arg=shift(@ARGV))) {
$outfilename = $arg;
open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n";
print (FILE $msg);
close(FILE) || die "Can't close $arg: $!\n";
}
}
else
{
print ($msg);
}
1;

*****中级HACKER*****
#include <stdio.h>
#define S "Hello, World\n"

main()
{exit(printf(S) == strlen(S) ? 0 : 1);}

*****老练的HACKER*****

% cc -o a.out ~/src/misc/hw/hw.c
% a.out

*****魔法HACKER*****
% cat
Hello, world.
^D

*****项目组长*****
10 PRINT "HELLO WORLD"
20 END

*****部门经理*****
mail -s "Hello, world." bob@b12
Bob, could you please write me a program that prints "Hello, world."?
I need it by tomorrow.
^D

*****总经理*****
% zmail jim
I need a "Hello, world." program by this afternoon.

*****(跨国企业)首席行政长官*****
% letter
letter: Command not found.
% mail
To: ^X ^F ^C
% help mail
help: Command not found.
% 他妈的!
!: Event unrecognized
% logout

- 作者: nearxlz 2006年04月21日, 星期五 10:43  回复(0) |  引用(0) 加入博采

处理日常事务的 Linux 程序和它们的配置

Linux 是非常好的***作系统。他让我们可以自由自在的研究和创造我们喜欢的东西。

下面列出我常用的一些 Linux 程序供大家参考。

  • Shell: bash。它结合了 csh 和 ksh 的优点,并且有 readline 功能,你可以随意绑定自己的键盘,使用 emacs 或者 vi 的方式都可以帮助你高效的输入命令行。info bash 可以得到非常详细的 bash 说明书。你可以按照这个说明自己写一个 .bashrc,你还可以写一个 .inputrc 来配置 readline 库,这样其它使用 readline 的程序也可以使用同样的方法输入,这样可以达到命令行输入方式的统一。
  • 编辑器: Emacs, VIM。

    Emacs 是非常强大的编辑器,它似乎有永远挖掘不完的能力。Emacs 有很多种变体,你可以根据需要选择。一般用户使用的是 GNU Emacs 或者 XEmacs.

    VIM 是 vi 的改进,具有方便简短的键绑定和强大的编辑功能。Emacs 和 VIM 通常是程序员首选的两个编辑器。

  • 程序开发: gcc(g++), make, automake, autoconf, autoheader, ... Linux 下有各种各样方便的开发环境,几乎所有程序语言的编译器,而且大多数都是自由软件。
  • 内存调试: valgrind。它是一种虚拟机器设计,能够滴水不漏的检查内存分配时可能出现的错误。只需要在命令行前面加上 valgrind 就行,不用在自己的程序中编译进奇怪的函数库,这样的设计非常友好。
  • 文档工具:TeX/LaTeX, TeXmacs。 TeX/LaTeX 可以用来撰写非常漂亮而专业化的论文和书籍,是数学排版的首选工具。

    TeXmacs 可以看作是一个“所见即所得”的 TeX,它具有 TeX 的输出效果,而且是即时能看见效果的。TeXmacs 底层支持 Scheme 语言扩展,发展潜力非常大。

  • 绘图工具:MetaPost。它是一种精确的描述性的绘图语言。你也可以用 xfig, dia 来画一些流程图之类的图片。xgraph 可以绘制简单的数据图。Grace, 和gnuplot, 可以绘制复杂多样的数据图形,拟合曲线,柱状图,饼状图等东西。这里有一个 Grace 的抓图
  • 图 像处理:ImageMagick 中的 import 程序可以屏幕抓图, convert 程序可以转换图像格式,display 可以显示图片和简单编辑 (缩放,换质量,转格式,简单绘图,简单虑镜)。通常我就这么点需要。如果你要更强大的图像工具可以用 Gimp, 它几乎和 Photoshop 差不多。自己 man 一下 import, convert 就知道怎么用了, display 显示图片后在图片上点击鼠标会有菜单,很简单的,不多说了。
  • 图片显示浏览:gThumb,CompuPic。其中 gThumb 是完全的自由软件,浏览图片非常稳定方便。CompuPic 性能非常好,据说速度比 ACDSee 还要快三倍。
  • 数值计算程序:Octave。这个程序基本上可以实现 Matlab 的数值计算功能,而且语法跟 Matlab 一样。当然你也可以用 Linux 版的 Matlab.
  • 代数计算程序:MAXIMA。这个程序基于世界上最老的计算机代数系统之一: MACSYMA 系统。它是用 Common Lisp 实现的。很多现在的符号计算程序比如 Maple 都从 MAXIMA 身上学到很多东西。

    我为 MAXIMA 写了一个简单的介绍,通过这个介绍你会知道 MAXIMA 的历史,体会到自由软件的重要优势。 MAXIMA现在以GPL发行,永远是一个自由软件。

    Linux 版本的 Mathematica 或者 Maple 也挺好用的。

  • 加密程序:GnuPG。不过说实话,我从来没有用的着它的地方。
  • 打包,压缩程序。tar, gzip, bzip2, zip, rar, ... 对于 tar 通常你只需要知道3种参数: zxf(解包),zcf(打包), ztf(看包里有什么文件)。bzip2 的压缩比非常高。
  • 虚 拟光驱程序。Linux 不需要虚拟光驱程序,要看一个iso文件的内容,直接 mount 就行了。比如 mount -o loop mycd.iso /mnt/cdrom。要把光盘做成一个iso文件,用dd就行了,比如如果你的光驱是 /dev/hdb,那么: dd if=/dev/hdb of=mycd.iso 就可以做一个光盘镜像文件叫做 mycd.iso.

    用 mkisofs 可以制造 iso 虚拟光盘。

  • ftp 服务器:proftpd, vsftpd。
  • WWW 服务器:apache。
  • ftp 客户程序:lftp,ncftp。它们都是文本方式***作的,但是比起图形界面的方便的多。比如 lftp 几乎具有 bash 的所有方便功能,Tab 补全,bookmark, queue, 后台下载,镜像……

    lftp 缺省不会显示 ftp 服务器的欢迎信息和错误信息,这在很多时候不方便,因为你有可能想知道这个服务器到底是因为没开机连不上,还是连接数已满。如果是这样,你可以在 ~/.lftprc 里写入一行

     debug 3 
    就可以看到出错信息了。
  • 自动下载工具:wget。它非常稳定,有一次我下载一个程序,用 IE 和 Mozilla 下载回来的文件都是坏的,最后还是 wget 可靠的传输了数据。用它甚至可以镜像整个网站,info wget 可以得到完整的使用说明。

    这里给出一个用 wget 下载我的整个网页的命令:

    wget -r -p -np -k http://learn.tsinghua.edu.cn/homepage/015450/index.html
  • 虚拟终端:rxvt+screen。我在 rxvt 里启动一个 screen, 它可以把一个终端当成好几个来用,功能非常强大。C-a ? 可以得到帮助。注意它的 detach 功能非常有用。
  • X server: XFree86。如果你不了解 Xwindow,可以看看这个 理解Xwindow
  • 窗口管理器:Sawfish, FVWM。FVWM 可以加入 libstroke,从而实现鼠标动作。详细使用方法见我的FVWM网页

    Sawfish 可以用 LISP 设置,有关 Sawfish,请看这里

  • 中文输入:fcitx。它支持拼音,双拼,五笔和二笔输入。安装极其方便,不依赖任何特殊的库。另外推荐你还可以用 SCIM 等。
  • email 处理:Mutt + sendmail(Postfix) + fetchmail。配置方法见我的 Mutt 网页。如果你觉得配置很麻烦,而你的 email 通信量很少,其实可以用 web 登录你的信箱。如果你 email 订阅很多邮件列表,建议使用 gnus.
  • 看 PDF, PS, DJVU 文件:Acrobat Reader, xpdf, GhostScript, gv, djvu工具包和 netscape 插件。它们都是可以免费得到的。
  • 看网页:Firefox, Konqueror, Galeon, lynx, w3m, links, ...
  • 英汉字典:dictd, WordNet,IBM 智能词典,星际译王。dictd 是字典服务器,你可以到 dict.org去下载一个服务器和很多词库。包括 Webster 1913,WordNet, CIDE, FOLDOC, ... 我还安装了英法,法英词典,甚至魔鬼词典 :)

    我的 Emacs 可以使用一个叫做 dictionary 的扩展连接字典服务器,我可以随时用鼠标右键查询词意,看这个抓图。我也可以使用屏幕取词功能,看看这个抓图

    WordNet 是一个奇特的字典。你可以看看这个介绍

  • 编辑网页:我用 Emacs 或者 VIM 直接写 HTML。这可以满足一般的需要。WebSphere,screem, BlueFish 可以构造更复杂美观的网页。
  • 登录其它 UNIX, Linux 机器:openSSH, telnet。我可以用 openSSH 把其它机器的 X 程序通过 ssh 加密的隧道传到我机器上显示。
  • 登录 Windows2000 server 的 display service: rdesktop,...
  • 同步程序:rsync。我用 rsync 通过 ssh 来跟某些机器同步数据,或者做自己机器上不同目录间的同步。
  • 上BBS:QTerm 或者 rxvt(或任何一种终端) + telnet + chatbot(helloooo 机器人的程序)
  • QQ, ICQ, MSN messenger: QQ 用户可以用 LumaQQ。也可以用 Gaim,它同时支持 QQ, ICQ, MSN, AIM 和很多其它的即时通信方式。 ICQ 用户也可以用 Licq。Emacs 也有 ICQ, MSN 和 AIM 的插件,不知道现在有没有 QQ 的。
  • 放录像:MPlayer, RealPlayer。MPlayer 太好了,直接就可以放 VCD, DVD, divx, wma, wmv ... rm 最好还是用 realplayer 放,它是免费的。
  • 放音乐: xmms(mp3,ogg都可以), mpg321(放mp3), ogg123(放 ogg)。mpg321 不如 xmms 管理音乐文件那么方便,但是有时我还是用 mpg321 放 mp3 作为背景音乐,因为懒得开一个xmms窗口。
  • 游戏:我已经很久没有玩电子游戏了。不过我觉得 KDE 的那个 ksokoban(推箱子),很好玩。大型游戏比如 Quake 也有 Linux 版本。
  • 看 Word 文档或PPT。简单的就用 wvware 把它转成 HTML 看。

    wvware 可以在 http://www.wvware.com免费得到。

    wvHtml --charset=gb2312 your.doc your.html
    就可以把doc转成 HTML。经测试,能够正确处理汉字和图片。

    你可以让mutt调用 wvHtml 在自己的窗口里直接显示转换的 doc 文档。只需要在 ~/.mailcap 文件加入:

    application/msword; wvHtml --charset=gb2312 %s - | lynx --dump -stdin;
    nametemplate=%s.html; copiousoutput
    在 ~/.muttrc 加入:
    auto_view text/html application/msword
  • 字处理。如果你真的要用字处理程序,那么就用 OpenOffice 里的 oowriter。
  • 使用 spreadsheet。我很少使用 spreadsheet,不过 OpenOffice 的 oocalc 应该能满足你的要求。看看 oocalc 打开一个 excel 文档的抓图
  • 编辑复杂的幻灯片。可以用 OpenOffice 的 impress, 它可以正确编辑和显示 PPT 很很多其它幻灯格式。可以做出很多复杂的动画效果,投影显示效果也挺好。看看这个 抓图 就是 OpenOffice 打开一个别人的 ppt 文档的样子。
  • 兼容 Windows 程序。crossoffice 可以模拟运行包括 IE, MS Office, Quicktime, Acrobat 完全版在内的 Windows 程序。偶尔遇到专门为 IE 定制的网页就用 IE 打开它。

- 作者: nearxlz 2006年04月3日, 星期一 21:55  回复(0) |  引用(0) 加入博采

python无所不能
面对珍珠(Perl)夺目之光、灵蛇(Python)更具有上天入地之能。它可以在 MS-DOS,Amiga,BeOS, OS/2,VMS,QNX等多种OS上运行;比 Perl 和 VB更快更好,比 C 和 C++ 语言更具扩充性;不仅在“星球大战”、 “星球之旅(Star Trek)”等超级大片中当纲特技和动画制作,还闯入了美国航天航空局控制室。真相如何,请看报道。

对 Perl (珍珠) 语言,互联网开发人员可以说是无人不知、无人不晓;它运行迅捷、操作简单,而且可以让用户在使用时感到其乐无穷。但它也有不竟如人意的时候:它的开放性同时带来了它的复杂性,用它处理大项目时尤其会使人无从下手。

尽管如此,大部分互联网项目仍得靠着 Perl 这员“功臣”来搭建。

但也并非别无选择。最新推荐的软件叫 Python (灵蛇),它的历史仅有 Perl 的1/4,有着许多相似的特征。

Python 的名字源于著名的滑稽团 Monty Python,它拥有许多广为人知的演员,并塑造了许多妇孺皆知的银屏形象。

那么,互联网世界中的 Python 又是怎样的一个形象呢?

更快更好的 Python

与 Perl 一样, Python 也是一种解释语言,它完全采用面向对象的方式,语言结构介于 C 语言和 Perl 语言之间。虽然它被视作一种高极语言,但它的内置解释器的功能却非常基本,仅有几种功能、操作符和关键词便构成了整个程序语言。它的优势可不仅如此,它还 能通过一系列的模块进行扩充。它既比 Perl 和 VB 语句更快更好,又比 C 和 C++ 语言更有扩充性。

同样,Python 对程序语句的处理首先通过一个解释和编译系统转换成为一系列的字节代码,然后再由 Python 的虚拟机进行处理。Python 设计得非常有效,主要归功于它庞大的功能库,因此用户不用进入系统环境或是操作系统,也不用引用模块。用 Python 编程,小程序还是小程序,不必劳费太多的成本和时间。

除了它的 Core 平台外, Python 还能在 MS-DOS,Amiga,BeOS, OS/2,VMS,QNX 以及其它许多操作系统上运行。甚至还可以在掌上电脑上运行 Python 程序。
面对珍珠(Perl)夺目之光、灵蛇(Python)更具有上天入地之能。


除了它的 Core 平台外, Python 还能在 MS-DOS,Amiga,BeOS, OS/2,VMS,QNX 以及其它许多操作系统上运行。甚至还可以在掌上电脑上运行 Python 程序。

Python 还有以下显著的特征:

超强的适应性

Python 可以由一系列的平台支持。它编译完备的格式可以在 Windows 和 MacOS 及其自身 Tk 扩充平台上运行,并可用于开发对用户友好的界面。在 UNIX 和其它平台上, Python 可以作为源代码由程序员自行编译,或者与其它预编的二进制编码共同使用。它超强的适应性更能让它有跨平台适用的能力:用它在 UNIX 平台上书写的程序段95%的情况下无须作任何修改就可用于 Mac 和 PC 机。扩充 Tk 平台对它的支持,甚至可以让基于GUI 格式的应用程序不用大动筋骨就可在上述三种平台上做自由切换,还保持着统一的界面。

正因为这种天然生就的跨平台运行能力,Python 还能支持一些平台的扩充平台,从而简化和免除了对其它语言和环境的适应过程。与 SunOS / Solaris 工具带有 Sun 音频设备及 SGI版本带有视音频接口(包括 OpenGL)一样,Windows Pytyon 解释器也同样带有 Visual C++ 类库和 Windows 音频驱动接口。此外还有与 COM 对象进行通讯的功能。

超大的功能性

Python 几乎无所不能。它的内核很小,但却拥有足够的基本程序块用于设计大部分应用软件。而且在某些情况下该程序语言还可以扩充与 C,C++ 和 Java 语言并用,因此没有它编不了的程序。 Python 解释器还带有极为强大的补充模块库,用于扩充语言能力,进行网络通讯、文本处理和规则表达式匹配。

虽然 Python 的主要特点是隐去程序员的许多低级复杂工作,它还能支持钩、扩充程序以及其它功能对某些操作系统进行低级接入。正因为这种高低兼行的特点,Python 可以视作和 C,Visual Basic 同等级别的语言,或是介于二者间的其它级别的语言。

超凡的扩容性

因 为 Python 本身用 C 语言写成(某些扩充平台采用C++语言编写),而且它采用开放式的源代码,这样可以对程序本身进行主动扩充。另外该程序语言的许多模块由 C 和 C++ 界面支持,包括一些诸如网络和DBM数据库接入等基本构件,以及其它如 Tk 等许多先进工具。

此外,Python 还能融入 C 或 C++ 语言,从而可以使用 Python 语言为应用程序提供编程界面。也正基于它的跨语言开发的支持能力,还可以使用 Python 设计应用程序后再输送到为 C 语言环境而无须将程序用 C 语言重写,因为两种语言均可同时使用。

JPython 是一个完全采用 Java 语言编写的 Python 解释器,这就意味着任何 Python 程序都可与一个 Java 对象或是使用 Python 对象的应用程序相联结。

超常的简易性

了解了 Python 以上几个基本特点后,再对程序语言它内容进行了解就相对容易了。该语言内核很小,而且格式和文体简明。由于所有其它的组件和扩充部分都使用完全一样的句法结构,利用 Python 编程会很快让人速成。

但这并不意味着 Python 语言就没有复杂的地方。对其许多扩充部分和内库都必需经过深思熟虑后方可进行有效的利用。

超强的功能性

拥有如此广泛的支持和博采众长的特征,Python 在处理一系列问题上都显得特别有效。以下为它的功能简介:

计算器:

由 Python 支持的一个扩充程序叫 NumPy,它可以提供与许多标准数学库相连的接口。Python 语言还拥有无限精确的特性,可以单独处理100位数字的算术。

文字处理器:

Python 能够对任何数据进行分割、累加和总结。它的模块可以对日志文件行中的元素进行分割,并根据内置的数据种类对其信息进行记录和总结,最后才进行输出。它的规 则表达式库使程序员可以使用 emacs,Perl 等等。 这再次证明 Python 的无所不能,曾经有程序员还利用 Python 编制成非常复杂的 SGML 处理工具。

便捷的应用开发:

Python对程序员而言一目了然,用它编程迅速有效。它博大的模块库可以提供针对不同协议、工具和库的接口。免除重新开发之苦。

由于Python 还支持 Tk 工具,所以可以在几个小时内完成一个应用软件,而用 Perl 语言可能会需要2到3天,用 C 语言甚至要几个星期。

跨平台开发:

Python 以中立方式支持不同的一系列平台,如果用户使用的系统包含不同的平台,使用 Python 开发应用程序则再好不过;它这种适应性也可以为系统预留使用其它工具的可能。对于频繁更换平台用户,Python 是个理想的选择。

为最终用户提供软件服务时,Python 也是个备选方案,可以避免同时用不同应用软件编程的时间和费用。

系统设备

Python 旨在避免操作系统中低级部分的滋扰,但如若需要主动进入这些低级部分时也完全可以通过相应的工具和扩充件来实现。与操作系统一样, Python 可以进入相同的的功能,并予以备份和扩充,而且备份和扩充后的功能会增加 Python 的所有的适应性和接口能力。

互联网程序设计

Python 带有的标准模块可以对网络插槽进行初级和协议级别的通讯,比如,如果要从 POP 服务器上读取电子邮件,Python 随带的库模块可以做到。另外, Python 还支持 XML、HTML和 CGI 库文件,所以利用它可以解析用户输入的需求,并通过网络服务器产生最佳质量的成果。

程序员还可为拥有 Python 内置解释器的 Apache、Unix 和 Windows 网络服务器编译模块。基于 CGI 程序的功效,可以很方便地执行 Python 语句而不用单独装载。

数据库编程

Python 中有无数的扩充模块可以连接如 Orcle、Informix 、mySOL和PostgreSql等通用的数据库系统;还有称作 Gadfly 的工具可以独立Python 提供完全的SQL环境。Python 有强大的文本和数据处理能力,可以用它作为不同数据库间的连接,比起那些数据库附带的总结和汇报工具显得更有优势。同时,由于它支持不同系统,用同样的接 口也可以连接任何数据库。可以用 Tk 在支持平台上建立前端,马上就可获得高速跨平台、独立数据库的查询工具。

其它

Python 应用范围广泛,几乎没有它不适配的语言;凭籍它的微小内核、丰富功能、多样数据,Python 提供了一个良好的程序构建基础。综合了C 和 C++二者的优点,只要采用合适的结构和方式,便可对 Python 程序进行无限的扩充。除了一大堆显著的优点,Python 也有缺点。

要列出 Python 的缺点确实不太容易。Python 在其扩充模块中提供了大部分的功能,并充分显示了对其增加功能有多容易,一旦用它还不能解决问题,那么也仅需要利用 C 或 C++ 语言重新编写一个扩充程序便可。

批 评 Python 的人往往不是说Python 缺乏某种功能,而是对这种功能并不了解。通常还有一种抱怨说 Python 缺少规则表达式的支持-但实际上有两个模块可以用来处理规则表达式,其中之一还可以完全用来支持 Perl 语言的句式句法。对规则表达式的处理并没有编进该语言中,但并不等于它作不到。

针对 Perl、Rebol 和 Java 语句而言, Python 的优势在于它的内核很小。这减少了执行的时间,因为在运行时需要装载的代码较少,而且这个特点也使它有着更广的适应性。

一旦熟悉了 Python 语句的简明风格,它的强大优势顿时便会凸现出来。用它编就的程序历久不衰。

Python 的理想用户群

它适合不同类型的用户以解决不同类型的问题。大部分时候这些问题一般不为人所知,因为它们有着较高的保密性。也有大型公司用它进行商用开发,并展示开发所获的成果。

红帽 (Red Hat )曾用 Python 和 Tk 一起成功开发配置和管理操作系统的可视界面。整个系统可以全面控制 Linux 操作系统,并根据用户选择对配置文件作自动更新。

Infoseek 在其公用搜索引擎使用了Python。该公司还用 Python 对其软件进行定制,使最终用户能对该网站内容进行方便下栽。

美国航空航天局也在不少领域中用到 Python 程序语言,最出名的莫过于在任务控制中心将 Python 用于任务计划;对 Python 在其它方面的使用例如用其计算天体方位和设计卫星的路径等等都充分体现了 Python 的超强计算能力。

以在“星球大站”、“阿贝斯 (Abyss)”、 “星球之旅 (Star Trek)”、 “印地安那琼斯 (Indiana Jones)”超级大片中当纲特技和动画制作的工业光魔公司 (Industrial Light)也采用 Python 制作商业动画。

- 作者: nearxlz 2006年04月3日, 星期一 21:54  回复(0) |  引用(0) 加入博采

完全用Linux工作,抛弃windows --王垠

我已经半年没有使用 Windows 的方式工作了。Linux 高效的完成了我所有的工作。

       NU/Linux 不是每个人都想用的。如果你只需要处理一般的事务,打游戏,那么你不需要了解下面这些了。

我不是一个狂热的自由软件份子,虽然我很喜欢自由软件。这篇文章也不是用来推行自由软件运动的,虽然我觉得自由软件运动是非常好的。

这篇文章也不是用来比较 Linux 和 Windows 内核效率,文件系统,网络服务的。我现在是作为一个用户而不是一个开发者来说话的,我们的讨论是基于操作,应用层面的。是为了告诉大学里还不了解,或者不 理解 UNIX 的科学工作者和大学生,UNIX 比 Windows 更适合用于科学研究工作,请大家理解 UNIX 的工作方式,不要用 Windows 的标准来要求 Linux,而要用一个科学工作者的标准来要求自己,用UNIX 的思想来武装自己。

我显然是反对在大学,特别是理工科专业推广 Windows 的。我也反对在对"娃娃"们的计算机启蒙教育中使用 Windows。因为 Windows 不论从技术上,经济上,思想风格上都是与我们培养高科技人才的目标格格不入的。Windows 的流行属于历史遗留问题,爷爷一级的人当然已经不可救药,但是我们不应该让下一代继续走上歧途。

UNIX 不是计算机专家的专利

当我建议一些非计算机专业的人用 Linux 的时候,很多人说:"UNIX 是计算机系的人用的,我们不能理解。" "UNIX 是男孩用的,我们女孩不用。"

但是其实世界上的大多数科学家和工程师几乎用的都是 UNIX 作为他们的电脑工具。就因为它简单,可靠,稳定,强大,有趣。甚至很多时候 UNIX 就是唯一的选择。

你说:"我们都会用 UNIX 的话,你们计算机专业的人还用来干什么?" 很容幸的告诉你,计算机专业的有一部分人就是专门为你们提供这样强大而方便的计算机工具的。如果他们制造的工具只有自己会用的话,那这个工具还有什么用?

理解 GNU/Linux 不要用 Windows 的标准来要求 Linux。

由于GNU/Linux这个词太长,下面如果没有特别指明,"Linux"就是指GNU/Linux"。

在这个年代,恐怕没有人需要我来介绍 Linux 是什么了吧?如果你觉得"Linux 只不过是跟 DOS 差不多的东西",那请问问你旁边的 Linux 用户,Linux 到底是什么?

那为什么我还要写一篇这样的文章?因为,我发现还有很多人不不理解 Linux 和 UNIX,虽然他们也在用它,但是他们有时会问:"为什么 Linux 不能像 Windows 那样 ……?","怎么Redhat Linux不能 mount NTFS 分区!","Linux 下用什么整理硬盘?","什么时候OpenOffice才能完全兼容Word文件啊?","现在还有什么Windows能干的事情Linux干不了的? "……

他们有40G的硬盘,却只为 Linux 分配了2G空间,有时还抱怨"这个东西怎么占这么多硬盘!" 似乎 Windows 该占用大部分硬盘。他们把重要的数据装在Windows的分区,似乎信不过Linux。他们总是到处寻找新奇的,好看的GUI程序,对命令行的东西一概不 屑一顾。他们对Drag&Drop,菜单配置,自动升级非常感兴趣。他们如果找到一个很像 Windows 程序的 Linux 程序,一定会很高兴的说:"哈哈!Linux 也能……了!"如果Linux在某种测试中胜过Windows,他们会高兴得跳起来。他们没有办法用Linux 解决问题的时候,甚至用Wine来运行Windows程序。有时实在没办法,只好重起到Windows,或者干脆省得麻烦,在 Windows 下装一个 VMWare 虚拟一个 Linux 玩。

你如果出现了上面的情况,说明你的思想受到了 Windows 的某种潜移默化的影响和误导。你没有能够从本质上理解存在于 Linux 身上的 UNIX 思想。你支持 Linux,你喜欢 Linux,你能从中感觉到快乐,这非常好。你现在只需要明白的是:Linux 从来就不是一个玩具,它是天才UNIX的后代。UNIX 是自晶体管发明以来最伟大的发明,它从诞生那一天开始就比 Windows 的设计出色。

你要体会什么叫做"设计",一个糟糕的设计并不是到后来缝缝补补就可以变好的,而一个出色的 设计,不但可以以不变应万变,而且可以影响到后来者。一个出色的设计配上一个出色的实现,那就是非常出色的发明。Linux 就是这样的一个出色的发明。Linux 并不需要追赶 Windows,也不需要打垮微软。它的最终目标是改变整个计算机世界,还人们自由,给人们乐趣和方便。

Unix 是简单的,你不需要成为一个天才也能理解这种简单。

UNIX的设计者 Dennis Ritchie 说:"Unix is simple. It just takes a genius to understand its simplicity." 但是我不这么认为,因为我不是一个天才,但是我却勇敢的把 Windows 完全删除掉,遇到不明白的事情的时候努力用 UNIX 的方式去解决,而不是寻求 Windows 的帮助。现在我体会到了 UNIX 的思想和好处,我可以用比 Windows 高效几倍的效率工作。因为我相信这样的信念:"Windows 能办到的事 Linux 一定能办到,而且办的更好。"

这小节开头的话应该改成:"Unix 是简单的,你不需要成为一个天才或是计算机专家。但是在这个冲斥着 Windows 错误观念的世界,你需要信念和勇气才能理解它的简单。" 我下面就告诉你一些我理解到的东西。首先,你要知道的是微软在国际科学领域是根本没有地位的。

微软的地位

微软的名声在欧洲和美国的大学里,特别是在计算机系里之坏,大家可能有所耳闻。我认识的 MIT,Stanford 的教授,贝尔实验室的专家,甚至一个欧洲小国的高中计算机老师都绝口不提微软的名字。在他们眼里,微软只是一个没有真技术,专靠在落后国家商业宣传和垄断 经营的小公司。这个"小"并不是说它人少,钱少,而是说它先进技术少。

我上次和王益合作写了一个算法演示程序,那个算法是贝尔实验室一位科学家Steven Fortune很天才的发明,为了程序能够被身边大多数人使用,我们选择了 VC+MFC 作为平台。我在分析算法时还得到 Fortune 很热情的鼓励,寄给我一份资料,还多次回信耐心的给我讲解了很多细节。但是程序完成之后,我把样品发给 Fortune,他回信说:"对不起。我机器上没有 MFC。" 话说的很客气,但是我已经感觉到了他对 Windows的不屑。然后我把 MFC 静态编译进程序再发给他,他就没有再回信了。他显然不是瞧不起我,而是确实有难处。

你能感觉到这位科学家对微软和 Windows 是什么态度了吧?不是反感,而是他心里根本没有 Windows 这个东西!微软在高科技领域没有发展,那么它怎么生存呢?到发展中国家去发展一下,他们的人民还对电脑一无所知,我说不定甚至可以打入大学的计算机系呢。 我送他们软件,我捐钱盖大楼,我出钱找图灵奖获得者来演讲,让他们觉得我们都是科学家!

好了,现在全国的大学包括清华,几乎所有人机器必装盗版 Win2000,Office XP,学校的选课系统是非IE不能正确浏览,论文用 Word 编辑,演示用ppt做,email 的通知附件是 doc 文件,你不用 Word 打不开,连 863 项目都用 VC 写程序了。我很久以前就看到一份报纸说,"微软为什么不严厉打击盗版?" 这篇文章说,微软非但不打击中国的盗版行为,而且有放任之趋势。放长线吊大鱼,"以后我要你们加倍的来还我!" 确实如此,它的目的快实现了。

Windows 笼罩下的中国计算机教育

说句丢脸的话,比尔盖茨很久以前是我的偶像…… //blush

在中国,比尔盖茨被很多人奉为神圣,"少年电脑天才",甚至有的人提到他的名字就做出"抱拳 对天"的姿势。很多人谈到微软的"新技术","高科技" 都是眉飞色舞。各种"VC编程圣经","深入了解 Visual C++"之类的书,在开头几页都会出现非常肉麻的字眼,"在那团团的混沌中,一个开天辟地的精灵,Windows 1.0,诞生了……"

微软的软件被这么多人盗用,那么人们是怎样使用这些盗版程序的呢?先看看电脑培训班,教的都 是一些 DOS 命令,打字,Windows 基本操作,Word 文档处理,PowerPoint,高级班可能有 Excel,Access…… 参加各种微软认证考试,MCSE,MSDE 的人络绎不绝。考试辅导班都贴出了"280元,考过为止"之类的字样。考试参考资料更是昂贵,有些电脑书店整整两书架都是"Microsoft Press"的东西。我有个同学参加认证考试,每门考试都要200多元。而且你一次考不过可以再考,又要交钱。他后来还津津乐道跟我说,看我,花了 XXXX(一个四位数)元考过了微软认证,得到一张比尔盖茨亲笔签名的证书和价值6000元的 Windows XP 内部发行版。

"电脑要从娃娃抓起",我们再来看看娃娃们学的是什么。大部分家长给孩子买了电脑之后,他们 首先就会装一个盗版的 Windows,然后买来盗版的游戏开始玩。如果哪个孩子会用 Delphi 编程序,那可不得了。报社记者,电视台争相报导,说,某某学校的初中生某某,在别人都还在玩电脑游戏这种"初级阶段"的时候就已经用 Delphi 写程序了。镜头还瞄准了他显示器上面的像框中的比尔盖茨头像!

我刚进入大学计算机系时还不懂得什么是操作系统,因为我以前只用过"中华学习机"。看到新入 学的同学们各个谈论的都是 "Windows 95","VC"…… 我简直觉得我落后了好几十年一样,整个一土人,根本跟他们答不上话。好不容易找到一个比较熟的同学问了一下:"你们天天谈论的瘟95是什么啊?"答: "win95就是一个操作系统,跟DOS是一类。""朵死是什么?" "你连DOS都不知道是什么?别在计算机系混了。" 学校上课当然不讲VC编程之类的东西,但是上 Pascal 的老师有一次就说:"嗨,我们学校真是落后。现在别人都用 C, C++,甚至 VC 了,我们还在讲 Pascal。不知道什么时候才能有VC课啊。你们出去也是要用VC的,只好自学了。" 于是,有些同学很多时候上课都捧着一本很重的"Windows 编程大全"之类的书,根本没有听课。吃饭时就念念有词的跟我说,"代码的优化是无止境的","匈牙利命名法真是伟大的发明" …… 这就是中国很多大学计算机系的情况。

感觉到无知了?这不是偶然的,而是微软长久以来埋下的伏笔。它要让无知的大家都把它奉为神 圣,它要让支持UNIX,Xwindow的人一旦说 UNIX 好,Xwindow 好的时候,都被一群人围着说教:"这个 Windows 也能做到","你对 Windows 有偏见","微软才是主流啊","你敢瞧不起 win2k?",".NET 就是世界潮流","微软的毕竟是新技术","有钱就是有技术"…… 甚至在一番论战比较后败下来还是要说:"Windows 性能差点,但是易用性强","Windows 是老百姓用的,要求别那么?quot;,"微软那么有钱,以后想超过 UNIX 还不容易吗?"……

发达国家的计算机教育

我前段时间在 USENET 发文问有关 Scheme 语言的问题时,认识了一位丹麦人。他解决了我所有的问题,并且建议我阅读一些很"深奥"的有关程序语言语法,文法的书,他告诉我很多网站可以学习 LISP,Scheme,人工智能,算法。他叫我看 Jonathan Rees 的论文 "Syntactic Closures"。他还打包给我寄过来一份 MIT 的 "How to Design Programs"。他说他在自己的 PC 机上装的是 Linux,他用 Emacs 编辑,运行Scheme 程序。他对 Emacs 的了解和爱好真是使人惊讶。他大学本科毕业时做的毕业设计是一个 Scheme 解释器。这对于我来说是望尘末及了。

他是那么的不厌其烦,我的每一个问题他都详细的回答。我有时都觉得过于详细了,怎么这么耐心啊?我觉得他似乎是我的高中老师。他是什么样的人呢?我好奇的打听了他的情况。原来,他是丹麦一所普通高中的计算机老师。

他说他在高中里讲授程序设计和算法,计算机语言文法。他说用 Scheme,他的学生不用再为内存泄漏等程序语言本身的问题而烦恼,而专注于问题和算法本身。有利于培养学生解决问题的能力,特别是用计算机解决数学问题的能力。

天哪!为什么欧洲出现那么多数学家,几何学家?你看看别人重视的是什么!我们的计算机教育如果继续这样下去,只会沿着弯路越走越远!

微软和它的朋友们的如意算盘

下面来看看微软的收入是怎么来的。首先,Windows 98系列操作系统,一个就是 100多美元,每次升级又是几乎同样的价钱。Windows NT 还要贵几倍,而且有用户数目限制,5个用户的,10个用户的…… 以后如果要增加用户数目还要按比例付钱。

花了如此多钱买来的操作系统就能用了吗?它竟然连压缩程序都没有提供!你装上Windows 之后一般第一件事就是去下载一个 WinZip 吧,"只要 29 美元"。Windows会中病毒啊,马上花 70 美元买一个 Norton AntiVirus 吧。还有黑客呢?再买一个Norton Internet Security 好了,100 美元。系统需要优化,磁盘需要整理,买一个Norton System Works 是你最佳的解决方案,100美元。

可是你现在还是不能干正事啊!你想要一个 Word, PowerPoint?那就买一套 Office XP 吧,一起买便宜些,$459.90。

那些程序不会用啊!那些菜单怎么设置,到底有什么功能啊?看"帮助"也学不会。买本书看看 吧,我推荐"Special Edition Using Microsoft Office XP",不贵,$27.99。这本书里面大部分是屏幕抓图,还是买一本旧的比较划算,$17.85。

你如果只是当个秘书,上面的差不多还凑合了。可是你有更高的追求,你想成为 Windows程序员。首先买一个 Visual Studio.NET 吧,要不然怎么编译程序。$494.95。

为了紧跟微软动向,世界潮流,不能不注册个 MSDN 什么的吧?这个贵一点,不过物有所值啊,$2,799。

嗯,你现在已经是上层阶级,白领人士了。你现在可以像这样"自由"的,"安全"的生活了。

为什么要反对使用 Windows

很多人都说不应该完全否定 Window,Windows 也有它的长处。不应该骂微软。

对。Windows 容易操作,适合普通用户。如果微软把它自己定位在 P&G,Philips 那样的地位,能够给我们的百姓提供周到的,完善的,价廉物美的服务。那我肯定是很喜欢它的。但是从上面的种种情况说明,微软是一个野心极大的国际垄断组 织!它的产品没有一个是不出问题的:Windows 不稳定,容易中病毒,而微软不为大家免费提供杀毒软件。我就是要让你们花钱买我的朋友 Symantec 的杀毒软件,谁叫你们已经上了我的贼船?这叫什么售后服务啊!

你买来微软的程序,安装的时候一般都有一个协议,说:"由于微软的程序造成你的数据损坏或丢 失,微软概不负责。" 我想很多人肯定觉得这个不合理,不想按那个 "I accept"。但是你的软件买都买来了,钱都花了,现在一按 "I decline",安装程序马上就会退出。你只好被迫点击了 "I accept"!这不是不平等条约吗?

我已经目睹了好几个朋友的文档被 Microsoft Word 损坏,有的是编辑了十多天的30多页的论文,有的是费了很大工夫做出来的个人简历,那个朋友为此失去了到自己向往的P&G 工作的机会。就在他要投简历的前一个晚上,就在那一瞬间…… 不知道他痛哭的时候有没有想起要投诉微软,可是谁叫我们用的都是盗版呢,况且你还点击了 "I accept"。

微软仗势已经占有大部分PC市场,制定不符合国际标准的"微软的标准",以不合理的方式压制 其它公司的软件,这个问题已经在美国司法部闹了很久了。他甚至在 Windows系列操作系统中放置能够通过网络泄漏用户信息的代码,以至于 Windows 刚进入澳大利亚时被澳大利亚政府禁止使用。

有些人说:"微软毕竟开创了一个历史,造就了今天的 IT 行业。" 但是,如果没有微软,我们今天早就用上非常稳定,非常可靠,非常方便,非常"傻瓜"的软件了!微软是阻挡信息技术发展的罪魁祸首。

微软的程序的工作方式(注意,我只是说操作方式,病毒的事情另外算)确实适合于一般家庭,上 上网,发发邮件,打打游戏都不错。可是微软却要把自己包装成什么"高科技"企业,要在世界各地设置"研究院",在大学计算机系赠送不适合用于科研的 Windows产品,甚至出钱请图灵奖得主来中国畅谈"二十一世纪的计算",还在大会上宣传自己的 .NET 技术。非要把别人认为自己是科学的,自己是领导世界高科技的。但是呢?它什么高科技也没有。欧洲,美国,哪一个关键部门在用微软的东西?NASA? DOE? CERN?你仔细想一想,微软的程序对人类到底有什么重大作用?

什么是 Windows 能干而 Linux 干不了的事情?---

"Windows 能干而 Linux 干不了的事情,那就是不需要干的事情。"

有个朋友看我半年没有用 Windows,有时就会问我:"你只用 Linux,有没有发现有些Windows 能处理的事情 Linux 干不了?"---

我回答说:"Windows 能干而 Linux 干不了的事情,那就是不需要干的事情。"

Windows 能做的有益的事情 Linux 都能做---

Windows 下的某些功能确实是我们需要的,那么 Linux 的开发者们和用户也需要这种功能,他们就会去实现这种功能,而且比 Windows 的方式好得多。由于大多数科学家,工程师用的都是 Linux 或者某种商业 UNIX, 所以几乎所有商业的科学工程程序,比如Matlab, Mathematica, AutoCAD, Candence的,Synopsys的,Avant! 的……全都是先有UNIX 的版本(包括Linux),然后再考虑移植给 Windows,甚至根本不移植给Windows,因为 Windows 的机器一般没有足够的能力运行这样的程序。你不要以为只有 Windows 才有 PSpice, UNIX 的 HSpice 要好得多,而且可以运行在大型主机上。当然它们不是免费的,但是它们值那个价钱。

但是 Windows 下有些东西在 Linux 下没有很相似的,或者你找到很多类似的,但是它们每一个比起 Windows 的那个程序都要差很多,那么原因有两种可能性:

有一个完全类似的程序,但是由于它乍一看不漂亮,被你忽略了。而其它程序虽然看起来很漂亮, 但是它们是一些初学编程的人写的。现在由于 Gtk, Qt 的诞生,Linux 下开发图形界面程序极其简单,很多初中生甚至小学生都可以随手编出一些漂亮不中用的程序。如果你整天寻找这样的程序挑来挑去,永远也找不到你满意的。当然 也有一流的程序用 Gtk 和 Qt,比如 GVIM 就可以用 Gtk 作为图形界面,我还知道 Synopsys 一些程序用了 Qt。

我曾经也犯过这样的错误,从外表区分一切。结果优秀的 FVWM, lftp, Mutt, wget 都被我忽略过。当我找回它们的时候,我是那么的羞愧不已,它们现在都是我的朋友 我第一次看到 FVWM 觉得它只不过是一个有很厚很难看边框的东西。可是现在,我的同学看到 FVWM 都说:"哇!真漂亮。"

有另一种完全不同的方式可以达到相同的目的,甚至更好。

很多人很关心 Open Office, Star Office, AbiWord, ... 他们多么盼望有一天某一个Linux 程序能够完全兼容的打开一个复杂的 doc 文档。但是你永远也不可能有那一天。为什么呢?因为微软为了占有市场,必定不会让其它系统的程序能够完全兼容它的文档格式。它一定会不断变化 doc 文档的内部结构,隐藏一些秘密,让其它公司的程序打开 doc 文档时总是有某种问题,从而你必需购买 Microsoft Office 和 Windows。

你应该想一下,那么多的高智商的大学教授,科学家,学生,他们用的都是 Linux 或者其它类型的 UNIX,他们没有 Word 可用,怎么处理文档呢?这么多年没有一个像Open Office 的程序出现,难道大家没有办法写文档吗?

显然不是这样。你看看那些高水平的学术杂志,论文,那些大学教授的网页,那些漂亮的幻灯片, 它们是什么做的?原来 UNIX 用户早就有非常方便的 troff, LaTeX, SGML等东西可以处理文档,而且它们比起 Word 都要高明的多。Word 显然被这些大拿忽略了,以至于很久以来没有人想在 Linux 下开发一个类似 Word 的程序,除非某些公司想抢微软的饭碗。

很多人留着 Windows 在硬盘上的原因无非是为了用 Word 和 PowerPoint。我见过一个教授,他的 Windows 笔记本电脑上除了 PowerPoint 什么都没有。有一天演示的时候,他指着堆乱字符说:"对不起,这是一个公式……怎么每次都是这样……" 其实有比PowerPoint 好几百倍的东西可以制造幻灯片,你可以用最简单的方法制造世界一流效果的论文和幻灯片。你待会儿可以看看我的TeX网页,你就会知道为什么我可以完全离开 Windows。

Windows 能做的那些没用的事情 Linux 永远做不好

电脑游戏

有些人说 Linux 下不能玩 Windows 下所能得到的所有游戏。的确,Linux 下虽然也有少量的游戏,比如 Quake。但是它没有 Counter Strike, 没有 Star Craft, ……

并不是说电脑游戏不该玩,但是应该适可而止。电脑是用来处理事务,帮助你学习,解决问题的工具,而不是一个玩具!整天沉迷于电脑游戏中,而不出去感觉外面的世界,你会变得越来越冷酷,越来越缺乏人情味。你与真实的世界越来越远。

你可以在 CS 里杀人,你可以在 Tomb Raider 里探险,你甚至可以在 Tony Hawk's Pro Skaters 里滑板…… 但是 It's not real!你虽然有很高的"反恐技巧",但是遇到歹徒的时候,你是那么的怯懦;你虽然控制 Laura 伸手敏捷,但是你打篮球的时候怎么总是被人断球?你虽然可以轻易的在 THPS 里作出一个 "360 kickflip to hangten grind to fakie",但是你踩在自己的滑板上的时候还不会 ollie!

说回来,如果你偶尔玩一下电脑游戏未尝不可。但是世界上有远比 Windows + PC 更好的游戏方式。Sony 的 PlayStation2, SEGA 的 DreamCast, Nintendo 的 N64,Namco的街机……每一个都比 Windows 游戏精彩,每一个都有如此高的3D性能,以至于Pentium4, Itanium + GForce4 都无法与它们比美!

Linux 的用户们都是关心解决世界的关键问题的份子,他们哪里有时间用自己的机器来玩游戏啊?他们每天用Linux高效的做完自己的工作就到阳光下享受自然去了。 要玩游戏也是玩一些类似推箱子,贪吃蛇之类的智力小游戏。所以,你知道为什么 Linux 几乎没有游戏了吧?

"整理硬盘,优化系统"

这是一个非常有意思的话题,仅次于有关"病毒"的话题。相信很多 Windows 用户都有整理硬盘的经历。在很多 Windows 用户眼里,"硬盘用久了,会出现碎片,速度会减慢,需要一个程序来整理,整理硬盘的时候不要做其它工作",这好像是天经地义的事情。

我也曾经津津有味的看着 Norton Defrag 一点一点的把我的硬盘排序,调整,用图形的方式显示出来,然后报告?quot;100% 没有碎片。你的硬盘现在已经达到最佳状态。" 我现在才发觉我那时是多么的幼稚。

Linux 和 UNIX 用户似乎从来没有"整理硬盘"这种说法呢?你觉得很奇怪吗?如果你觉得很奇怪,那说明你的思想在某种程度上被微软的垃圾程序禁锢了。你需要明白,UNIX 的大型主机很多必须是一天24小时,一年365又1/4天不停运转的,要是每个星期都要整理一次硬盘,在整理的时候几乎不能干任何事情,那是绝对行不通 的!

Linux 机器根本不用整理硬盘,这就是为什么没有看到过 Linux 用户整理硬盘。Linux 的文件系统是比 Windows 的 FAT, FAT32, NTFS 高明得多的文件系统,它们不但可以对文件设置权限,实施完全的保护,而且可以"越用越整齐","越用碎片越少"!你应该把文件大部分放在 Linux 的分区,而不是 Windows 分区,因为它比 Windows分区可靠得多。

还有更滑稽的事情就是有很多"Norton System Doctor","Windows 优化大师","超级兔仔注册表魔法" 之类的程序存在,而且价格昂贵。似乎一个操作系统本来应该有很多问题,需要别的厂商做程序来"优化"它,而且为了得到优化,你需要付钱!这些问题 Linux 根本就没有,所以不需要什么优化。Linux 内核本身就是高度优化的。

IDE

有些人在抱怨为什么 Linux 没有一个良好的 IDE 开发环境。Linux 现在已经有一些IDE 了,但是总是有很多问题。你是不是正在寻找,正在期望 Linux 某一天可以有一个VC那样的开发环境?你有没有发现你正在进入微软给你设下的怪圈?你为什么一定要用 IDE?你说:"IDE 开发迅速,调试方便,适合大型程序……" 那说明微软的程序在你脑子里已经比较根深蒂固,你需要好好清醒一下了,看看我来告诉你。

高明的 UNIX 程序员不用 IDE,IDE 从来就是给初级 Windows 程序员用的。

你看看大型的 UNIX 程序,包括 Linux 内核,各种网络服务程序,Xwindow 程序在内,哪一个是 IDE 搞出来的?我们实验室的 EDA 程序也没有一个是 IDE 弄的,我还知道Candence, Synopsys,Mentor 的高性能的图形界面 EDA 程序也都不是 IDE 写的。你信不信,微软的人在写 Windows 本身的时候也根本不用 IDE。微软内部程序员最喜欢的编辑器其实是 VIM,用 VIM 的微软程序员上次向乌干达的可怜儿童捐助了1000多美元,这是值得称赞的。

有一次某杂志采访一些出名的 Linux 内核程序员,包括 Linus 在内,没有一个人用IDE,有的人用 VIM,有的用 Emacs,只有 Linus 说"GNU Emacs is evil",但是其实他用的是一种跟 Emacs 有同样键绑定功能的 MicroEmacs。大家都是用编辑器编辑了程序文件,然后用 make 这样的自动工具调用 gcc 编译器完成编译工作的。甚至高级的 Windows 程序员也不用 IDE,他们可以从命令行调用 cl,nmake 来编译自己的程序。虽然这样的 Windows 程序员很少,但是他们却是最了解 Windows,最高明的Windows 程序员。

为什么 UNIX 程序员不用 IDE?明白了这个道理你就能体会到 UNIX 的设计思想了。首先,一个 IDE 集成了编辑器,编译器,汇编器,调试器,跟踪器…… 这个编辑器功能肯定比不上 VIM 或 Emacs,编译器比不上 GCC,汇编器比不上 as,调试器比不上 gdb,ddd, 跟踪器比不上 strace, ltrace, truss。你得到的是一套整合的低能的程序。如果你对调试器的功能不满意,你只好换用另外一套 IDE,但是这套 IDE 的热键,菜单,编辑器功能,按钮…… 跟原来那个有很大不同。你不得不花很多时间来熟悉新的环境,而不能保持原来的某些东西。

而在 UNIX 下就不一样了。你可以用你最喜欢的 VIM 编辑程序,你在 VIM 里可以调用GNU make,make 可以调用 gcc, ld, ... make 的出错信息可以被 VIM 捕获,VIM 能帮你在源程序里定位。你如果喜欢 icc, 你可以让 make 用 icc 而不是 gcc。你如果觉得 gdb 跟踪变量时比较麻烦,你可以用 ddd 来显示各种数据结构之间的关系。你还可以在 Emacs 里调用 gdb,那样就可以同步显示源代码了。而且 VIM 和 Emacs 还可以编辑很多其它东西,比如信件,LaTeX 文档,HTML,配置文件…… 你不用另外找一个什么编辑器来干这些杂活了。很多程序比如 Mutt, tin 都可以在内部使用 VIM,这样就更方便了。实际上 make 在其它方面还能帮你很多忙,我的每一个比较大型的 LaTeX文档都是用 make 维护的。

Linux 能干的高精尖的事情 Windows 都干不了

当然有很多事情是Linux/UNIX的专利了。因为 Windows 只能装在 PC 机上,好像以前也有 Alpha 可以使用 Windows NT,但是就是没见到有人用。PC 机的能力是很低的,像我们编程序处理 NP-Hard 问题的人,用 Windows 的机器显然速度不够,而且有时一个问题算上几天甚至几个星期,Windows 机器是以"死机"著称的,我们怎么能放心?所以几乎所有科学计算程序,EDA 程序,高性能图像处理程序都不是 Windows 的。他们有时也会移植一些给 Windows,但是常常降低那些程序的能力。你比较过 Windows 版本的 Mathematica 和 Linux 的有什么区别吗?

IBM 制造的最大的并行计算机有 8000 多个处理器,Windows 不可能有能力管理这么多处理器,它用的是什么操作系统?答案是 Linux。

《泰坦尼克号》电影里的三维动画,那么细腻逼真,Windows机器能做出来吗?不行。那也是 Linux 机器做的。

民航总局用来训练地情人员的虚拟现实训练设备,Windows 当然无能为力。那都是商业的 IRIX 机器。

UNIX 是最早支持 TCP/IP 网络协议的系统。它上面有很多可以互相协作的网络服务程序,它们经过多年的使用和修订,已经达到比较完善的程度。而就在1997年,微软的比尔盖茨还在扬 言:"Internet 是没有前途的。" 微软的这个"远见卓识"大家应该都已见识,它后来加上的网络服务程序IIS漏洞之多,让公安部都频频发出警报,大家也是见识了的。

其实你知道了,Windows 没有一样有用的事情能比 UNIX 干的更好。

Linux 干不了的有用的事情 Windows 照样干不了

当然 Linux 不是万能的。它也有不能干的事情,电脑也有干不了的事情。但是 Linux干不了的事情,Windows 肯定也干不了。这些事情就是我们需要探索,需要努力的事情了。在你探索的过程中,Linux 必定是你的好伙伴。

不要把Linux和Xwindow掩盖起来!不要把我们的用户当成傻瓜。

什么?你早就知道 Windows 是垃圾?噢!你怎么不早说呢!害我废话这么多。嘿嘿。

"好了。你知道 Windows 是垃圾,你现在用什么?quot;

"Linux + Xwindow"

"那我问你,Xwindow 是什么样的?"

"不就是跟 Windows 差不多吗?只不过 'Start' 按钮比较方,而且上面不是一个Windows 标志,而是一个脚丫子。点击一下居然还有很漂亮的中文菜单。我喜欢!"

"你知道什么是'根窗口'吗?"

"不知道。从来没听说过呢?"

"根窗口就是遮盖整个屏幕的那个最大的窗口。"

"哪儿有什么窗口啊!我没有看到呢?"

你发现了问题吗?这些 Linux 用户说是在用 Linux 和 Xwindow,但是他们对 Linux和 Xwindow 几乎完全不了解。很多人用了那么久 Xwindow 都不知道根窗口是什么东西,不知道其实按钮也是窗口,不知道窗口管理器和其它程序有什么关系,大家都以为窗口上面的按钮是程序自己放上去的,不知道窗口? quot;class name","resource name"是什么东西。他们也不知道 .Xdefaults 是用来干什么的。特别是他们很多人都不知道 Xwindow 的字体是如何命名的,什么是 fontset,有了一个新的字体也不知道怎么安装。

他们被遮在 Linux 之上的一层一层的包装迷惑了,他们等待有图形界面的工具来帮助完成一切事情,他们认为 Linux 跟 Windows 一样,只是麻烦一点。他们知道 Linux内核很好,但是他们感觉不到 Linux 和 Xwindow 在操作层面的天生的先进性,随后不久就把 Linux 完全删除掉了。你发现没有,要用户理解 UNIX 和 Xwindow 的操作层面的先进性,才是留住用户的最好办法。如果用户体会不到操作时的方便和高效,内核再好他们也不会理会。

但是用摹仿 Windows 的作法来吸引用户,永远会失败的。因为 Linux 如果摹仿Windows那一套低效率的方式,那么 Linux 的这套"低效率方式"永远比不上Windows 的那一套"低效率方式"。那么用户就会说:"这个 Linux,没有一样比的上 Windows。"

Linux 天生就是继承了 UNIX 的高效的工作方式,为什么我们要把它掩盖起来?我们为什么只告诉用户 KDE 的菜单怎么用?我们为什么不能像早期的 Xwindow 书籍那样第一节就告诉用户什么是 X server, 什么是 X client,什么是 Window Manager, 什么是根窗口。第二章就告诉用户窗口有哪些属性,什么是 classname, resource name, hint,怎样使用 .Xdefaults, xrdb ……

在这里我又不得不说一下那些 Linux 的发行公司和写书的人,他们把 Linux 和Xwindow 包装起来,却没有从基本上告诉用户 Xwindow 的工作原理。很多书籍讲授的层次就是在Gnome, KDE 的菜单操作的层次,靠大量抓图来占篇幅,"繁荣"Linux 书籍市场。

现在很多人已经把能够利用别人的库写出一个好看的程序作为自己编程水平的象征。在这? quot;图形化","可视化" 的年代,你如果还在用 troff, LaTeX 写文档,你还在用VIM 自己编辑 HTML,用 Mutt 处理邮件,你还在用文本模式的 gdb 调试程序,你还在用Xlib 写程序, 你还在用 tin 上 USENET,你还在自己写 Makefile,写机器代码,你还在玩 Clossal Cave 这样的字符模式冒险游戏,那你就是老古董。

其实这种思想是错误的。虽然你是一个坚决的 Linux 支持者,但是你的思想是 Windows的思想。你认为图形界面,菜单,按钮就可以解决一切问题,就可以给你高效方便。你还是没能摆脱微软给你的潜移默化的东西。你其实离不开 Windows 那样的环境,你迟早会删掉自己的 Linux。

GUI vs. CLI

做一个坚定不移的"两面派"

大家看到这个标题是不是热血沸腾?两派大虾都可以围攻我了:

GUI派用户:"哇!我一看你这小子就是 CLI 的。要不然自己写什么 Makefile?用什么Mutt?"

CLI派用户:"切~ 你还用 X!高手都不用 X。你是 GUI 那边的。"

可怜的我:"555~~ 你们都不要我~~ GUI 和 CLI 就那么水火不容吗?"

计算机界这样的门派之分还很多。很有特点的就是 CLI 和 GUI 了。CLI (Command LIne)的狂热份子声称永远不用 X。我上次在实验室看到一个同学用一个 SecureCRT 登录到Sun 机器,然后用一个 vanilla vi 编辑程序,我建议他启动一个 GVIM 过来显示在Exceed 上可以有语法加亮。但是他坚决反对,说:"高手不用X。你想想,要是我在一个很慢的网络连接怎么用 X?而且好多服务器没有装 X 程序。"

但是我们实验室的网速可够快,Windows 机器都有 Exceed 啊,而且 Sun 机器有全套X 客户程序包括 GVIM。他说他是 CLI 的坚决拥护者,但是他却在用 Windows,他后来打开了好几个 SecureCRT,每次从文本框输入地址,用户名和密码,从下拉菜单选择"SSH2",然后点击"Connnect"。他还不断的夸SecureCRT 是"网络管理员投票选出的最受欢迎的登录方式"。老天,SecureCRT 本身就是个 GUI 啊,他其实没有明白Xwindow 的好处。

你说我是 GUI 的?我虽然很少在 console 下工作。但是我对 bash, VIM 很熟悉,我可以让 bash 按照我的键绑定方式来工作。我可以在 rxvt 里使用 Mutt 来收发 email。我的每个桌面上都常常堆放着一打不同大小的 rxvt。我用 VIM 编辑 LaTeX。我自己写Makefile 来维护 LaTeX 文档。我有时用 mpg321 来放 mp3。我上BBS用的我自己写的expect 脚本。 好了,CLI 派的朋友可以收我做盟友了

你说我是 CLI 的老古董?我的 FVWM 被我配置为可以"手写操作",我只要画一个"r"就可以启动 rxvt,我只要画一个 "U" 就可以启动 GVIM,…… 我用 GVIM 语法加亮模式编辑程序,我用 Mozilla 浏览网页,…… GUI 派的现在好像认我做朋友了

好了。CLI 派的朋友,虽然我很喜欢命令行,但是我有时在屏幕上左右画一下就可以执行:

Module FvwmConsole -terminal rxvt -geometry 45x5-0+0 -bg gold -fg midnightblue -fn "-adobe-courier-medium-r-*-*-14-*-*-*-*-*-*-*"

你是不是现在又想把我逐出师门?

GUI 派的朋友,虽然我很喜欢窗口。但是我可以在 FvwmConsole 里输入:

All (rxvt) MoveToDesk

把我所有的 rxvt 移动到我现在工作的桌面。"这家伙,怎么这么快就叛变了!"

其实何必分什么 GUI 和 CLI,UNIX 和 Xwindow 都是工业标准,它们从设计那天开始就有非常灵活的用法,各个程序,不管是 GUI 还是命令行的都可以互相协作。UNIX 和X 是一家,何必搞的那么偏激,非此即彼?你从我上面的行为可以看出 GUI 和 CLI的模糊界线吗?我就是坚定不移的"两面派"。

UNIX 是简单的--

"我相信简单就是最好,如果太复杂,我是不能理解的。" -Seymour Cray

很多第一次用 Linux 的人会惊奇的发现,Linux 的程序居然不?quot;安装"就可以运行,程序拷贝到随便那个目录都可以用,而不是一定要占用你第一个分区的空间。程序的设置只是一些简简单单的文本文 件。你根本不需要什么"注册表修改器" 就可以改变系统的设置。这就叫做简单,但是简单就是美。虽然这只是 UNIX 简单性的一个肤浅的认识,你已经体会到了某些东西。

但是简单并不意味着功能弱,并不意味着落后。相反,简单意味着强大,意味着生命力。

我不会再继续阐述我理解到的"UNIX 的简单",因为这个需要自己去体会。

UNIX 是永恒的

有人说:"Plan9 会取代 UNIX,Mach 会取代 Linux 内核。"

但是你如果是一个深入体会了 UNIX 的人,你就会知道:UNIX 的思想是永恒的,不管时过境迁,Plan9 是否代替 UNIX,UNIX 的灵魂都会在 Plan9 身上现形!

我为同一个设备写过 Linux 内核和 Windows VxD 驱动程序。写 Linux 驱动程序时,我对 UNIX 设计的完美的一致性,远见性所折服。UNIX 用同样界面的 read(), write()系统调用就可以对不同的对象:普通文件,设备文件,管道,管道文件,socket,……进行统一的读写操作。我跟本不需要写一个测试用的应 用程序就可以对我的设备驱动进行测试,因为 cat, cp, dd, 它们也使用了同样的 read(), write(),设备和普通文件在应用程序眼里没有区别。在那个还没有 Smalltalk, 没有 C++ 的年代,UNIX 的设计者已经使用了所谓的 "面向对象方法"。对,C 语言也可以实现面向对象。

UNIX 的系统调用几十年都没有很大变化,这非但不是顽固,不进步的象征,反而是UNIX 的远见卓识的体现!这就跟 TeX 程序几十年都不变的情况差不多。这些才是真正的永恒的 master piece! 你应该改变所有软件都必需从 0.1, 1.0, 1.1, 1.2, 2.0,..., 3.0, 3.1, 95, 98, 2000, XP, ... 不断升级的想法。

Windows 就不同了,它在最开头只是一个 DOS 之上的图形包装而已。后来为了兼容以前的糟糕设计,不得不加上很多累赘。我写 VxD 驱动程序的时候就深有体会,Windows 95 程序对设备的操作只有用 DeviceIoControl,我不得不写了两个应用程序来对设备驱动进行测试。Windows 内核的不一致性和隐密性使我非常恼火。不过 Windows WDM驱动程序现在也有了 ReadFile, WriteFile,…… 那说明什么?那说明 Windows 在向UNIX 学习,或者有可能是某个 UNIX 设计人员在微软打了几天临工,顺手加了几个UNIX 的东西进去。这样做是没有用的,Windows 从一开始就是非常糟糕的设计,它的历史的包袱太沉重了,缝缝补补有什么用?它只能永远的被 UNIX 甩在身后!

UNIX 是强大的

让聪明人干任何他们想干的事情。

UNIX 的一个特点就是非常高的灵活性,Xwindow 也具有这种灵活性。这种灵活性体现在哪里呢?

UNIX 的程序一般都有很多参数,不管你现在用的着用不着,总有人需要某些参数。它们的行为很多都可以用配置文件来改变。比如 GNU bash, 通常缺省的命令行输入方式是 Emacs 方式,但是只要我编辑一个 .inputrc 文件,就可以把它变成 vi 的输入方式,而且我还可以自己绑定键序列到某些操作。我可以用 shopt 来设置它的很多特点,比如是否进行通配符扩展,是否可以把一个变量当作一个目录来cd,是否可以自动纠正某些明显的目录名打字错误 ……

UNIX 程序设计的思想是提供给用户"机制",而不限制用户制定"政策"。这是一个重要的尊重用户的作法。

我们再来看看 Xwindow。Xwindow 是一个出色的设计,它把显示服务器和客户程序分开。一个显示上既可以显示本机上的程序,也可以显示别的机器上的 X 程序,而它们都遵守你的窗口管理器的统一指挥,它们之间可以方便的传送剪贴版数据,各种事件 …… 比如有时我的 XFree86 上会出现四个不同机器上的 XTerm,两个不同机器上的 GVIM,…… 它们统一受本机上的 FVWM 指挥。

Xwindow 程序都具有很多很多命令行参数和 resource 参数。你可以随意的在命令行或者 .Xdefaults 文件设置所有的颜色,字体,尺寸…… 而且如果你用 xrdb 把 .Xdefaults 导入到根窗口,那么其它机器上没有经过配置的同样的程序,显示到你的机器上的时候也会遵守同样的外观规定。

Xwindow 的窗口具有 Property, 也就是一些可以自己定义的共享数据(原子)。正是因为这些 Property 的存在,使得 Xwindow 具有无比强大的生命力。X 的窗口管理器和其它客户程序之间并没有统一的协议,但是后来出现了 ICCCM(客户程序间通信规范),这个规范就是通过 property 定义的。现在又有人定义了一套"扩展的窗口协议(EWM Hints)",使得Xwindow 可以具有某些 Windows 的特征,比如一个工具条程序可以告诉窗口管理器:"这个屏幕下面被我占据了24个像素的空间,你最大化程序的时候不要越过这个界线。"

一个强大的窗口管理程序比如 FVWM,它收到这样的提示时,可以答应工具条程序的这个要求,也可以不答应。一切选择的权力在于谁?当然是用户了!

你想想,是不是有些 Windows 程序常常弹出一个窗口要你选择 "Yes or No"?你不点击它它就不下去。你觉不觉得你的程序在侵犯你的尊严?你是一个人,一个智慧的生物,怎能受到一个程序如此的待遇?

还有就是很多 Windows 程序把人当成傻瓜,而它是"智能程序"。比如,有一个程序就是喜欢把你的每句话第一个字母都变成大写,我不说它是谁了,你遇到的时候就知道了。

如果连"一句话开头一个字母要大写"这么明显的问题都需要程序帮你纠正的话,人脑还用来干什么?况且如果你故意想要不大写的话,那就更麻烦了,我楞是没有从它那一大堆菜单里找到怎么关闭这个愚蠢的选项。

只有符号才能完全操纵计算机。

我们来说说很多初学 Linux 的用户。虽然他们在用 Linux,但是他们打心眼儿里是觉得Windows 的工作方式好,他们希望 Linux 有一天能"像Windows那样"。你说:"我的鼠标一点,我菜单一拉,…… 就可以完成我的操作。" 但是我要告诉你:"Linux 从来没有摹仿 Windows,将来也不会。Linux 从诞生之日起,它的工作方式就比 Windows 的先进。

Linux 属于能勇敢面对符号的人。只有符号才能完全操纵计算机。"

看看优秀的 UNIX 程序,XFree86, FVWM, VIM, Emacs, proftpd, Mutt, wget, tin, ... 没有一个不是用配置文件来设置选项的。为什么这些程序没有方便的菜单可以用来配置?难道它们的设计者就那么低能,连个图形配置界面也写不出来?

当然不是。因为图形界面配置方式的能力是极其有限的,而配置文件和程序语言的表达能力却是无 限的。用图形界面配置这些程序的话,如果你想达到配置文件的效果,你需要成百上千的菜单,checkbox, radio button, ... 到时候你根本没办法找到你需要修改的地方了!而各个程序的配置文件的语法都有很多相似之处,一般就是一些命令,设置一些变量,参数,…… 一旦用会了一个,其它的也就容易理解了。如果你用惯了 awk, sed, Perl,你会觉得那才是真正的自动化啊。

鼠标虽然是很好的工具,但是它的表达能力是有限的。你不可能光用鼠标就让电脑完全明白你的意思,它毕竟只有3个按钮。看看我的MetaPost页你就能体会到鼠标的这一弱点。所以我们虽然很喜欢鼠标,但是却不能完全依赖它。

各个小程序的完美配合

这就是UNIX最重要的特点了,它就是UNIX设计的思想。让每个程序只具有一项专门的能 力,然后让它们合作。Xwindow也继承了这种好传统。这恐怕就是Windows和其它操作系统望尘末及的地方了。UNIX 程序设计之统一,配合之完美,真使我难以置信!shell, grep, find, awk, sed, make, Perl, Emacs, vi, tin, Mutt, ... 它们是那么的具有一致性!你一旦学会了 sed 的正则表达式,其它程序基本上都能用了。你一旦学会了vi 和 VIM, 你会发现它的操作是那么的有规律性,似乎vi的设计者在几十年前就已经设计好了 VIM 在今天的完美而统一的操作方式!而且vi的操作还体现在 Mutt, tin 等很多程序中。你甚至可以把 bash 设置为 vi 的输入方式来输入命令行,我就是这么做的。一个程序可以调用另外一个程序来得到数据,可以把数据交给它处理后返回来,可以在自己的窗口里"嵌入"另外一个 程序。

在 Windows 和其它非 UNIX 操作系统中,这种合作是非常困难的。我曾经在Windows下使用 Perl来进行一些自动工作。但是 Windows 的文件操作,管道是如此的不稳定,程序之间基本不能合作。你别想在 Visual Studio 窗口里面嵌入 UltraEdit 编辑器,你别想用一个 expect 脚本来控制 telnet 到水木清华BBS。

Windows 的程序都是大而全,大而杂,所有的电子邮件程序都需要自己提供编辑器,自己发送和收取邮件,自己显示邮件的附件。每一个BBS程序都提供自己的 Virtual Terminal, 自己的通讯代码。每一个 IDE 都自己提供编辑器,编译器,汇编器,调试器。人们为了使用一种新的程序,需要适应所有这些它提供的界面,而不能使用自己喜欢的编辑器的键绑定,菜单组 织…… 不能 DIY!

你要知道,最高级的电脑是定做的,自己想要什么什么CPU,什么主板,多少内存,什么硬盘, 键盘,鼠标,显示器都是自己选择的。最高级的滑板,自己想要什么牌子的版面,什么牌子的沙,什么桥,什么轮子,什么轴承,也都是自己选的。最高级的古球 拍,木板,胶皮,海绵,胶水都是可以自己选择…… 而用 Windows 程序,你得到的是大杂烩,就像你去买"品牌机",只有那么几种配置,而且附带很多你不需要的软件和服务;就像你去买组装好的滑板,你想要大一点的轮子和窄 一点的板子,但是你没有这种选择余地!Windows 程序就相当于最廉价,最次的滑板。但是它却会花你更多的钱,因为一旦一个部件坏了,或者你不喜欢了,你不能另外找一个好的换掉它,你必需重新买全套配件!

而 UNIX 和 Xwindow 就是高档的"组装货"。比如我用 Mutt 的时候,我可以用 VIM也可以用 pico 来编辑邮件,我可以用 ImageMagick 也可以用 xv 来显示附件里的图片,我可以用 lynx 把 HTML 附件转成文本嵌入窗口中,我也可以把 HTML 附件交给Mozilla 图形显示。我可以让 GnuPG 帮我把邮件进行数字签名和加密,我也可以用其它 PGP 程序。

我想让 Postfix 而不是 sendmail 帮我发出邮件,我想让 fetchmail 帮我收邮件,转发给 postfix,然后被我自己写的Perl过滤器处理…… 这一切我都可以办到!我可以选择我最喜欢的专门的程序来完成专门的工作,然后把它们结合在一起,我也可以分别得到它们的好处。

学 UNIX 绝对不是浪费时间

有人告诉我:"你看我用 Windows 什么都不用学。而用 Linux,光是安装就花了我一个星期!"

首先,我要告诉你的是,你装 Linux 花了一个星期,不是因为 Linux 不好装,而是因为你已经习惯了 Windows,对 Linux 最初难以理解而已。你想一想你最初安装Windows的时候呢?你花了多少时间搞明白什么是硬盘分区?什么是盘符?什么是目录?你认为Windows 就是那么容易可以学会的吗?虽然你觉得没花时间学,但是你以前在用别人的机器的时候已经耳濡目染,自然就了解了。而且由于你想要 Linux 和 Windows 并存于硬盘上,又增加了安装难度。而且你肯定没有得到有经验的 Linux 用户的帮助,否则他们会在20分种之内帮你搞定。一个星期也太夸张了.

如果一开始用的就是Linux就没有这个问题。你想想如果你没有用过 windows,你肯定会很习惯 /etc, /usr, /usr/local ,... 而不是 C:, D:, E:, ... 是不是?如果你只用过Linux,你第一次用 windows 时恐怕也会问:"/bin 目录哪里去了啊?"

最重要的是,你用惯了的UNIX工具,它们可以伴随你一生,而不会那么容易变化或消失。你可以永远不用再换另外的工具了。除非那个工具比你这个好的太多,而且可以完全模拟你现在的工具。

我们实验室一个60多岁的老师,用vi, cc, make, ...都几十年了,他以前的经验绝对没有白费,而且教会了我们一批又一批的学生。vi 伴随着 UNIX 的最初发行而诞生,直到今天还是世界上头两号编辑器之一!有些人的 FVWM 配置文件已经用了 10 多年,现在完全不经修改还可以用。

看看 Windows 的工具,你从 Borland C++ 换到 VC, 就必需适应新的环境:菜单不同了,颜色不同了,按钮不同了,帮助信息不同了,热键不同了,编译器参数,调试器功能也不同了,…… 那个时候恐怕花要花你很多时间去适应。当你刚刚适应了 VC, 你又要换成VJ, PowerBuilder, C++Builder, ...

很多windows程序员都是这样,开头在dos下用Turbo C, 然后是 Borland C, VC, C++ Builder, ......不断追赶微软的潮流。而且微软的SDK, MFC, .NET …… 什么都在不断变化,不断出问题,又不断的在修改…… Windows 程序员不得不买又厚又重的 Microsoft Press 的书籍,看了才一个月,又过时了。今天你才学会了写 VxD,明天你就必须用WDM 了。你不得不注册 MSDN 才能赶上 Microsoft 的步伐。很多人说:"计算机是贵族的专业。" 这就是微软一手造成的。

这些东西才是没完没了的浪费大家的时间和金钱的。这是是浪费生命!我们为什么不使用从诞生就 那么一致和完美的 UNIX?你需要理解先进工具的设计理念。UNIX 的工具就像我们用的汽车,它的离合器,油门,刹车,方向盘,后视镜,永远都在同样的位置。用惯了的话,你对你的汽车的每一个部件都会了如指掌,甚至你自己 都可以修车了。这难道不好吗?

有人说:"你说我们需要了解 UNIX,难道你要开车还必须了解汽车的结构吗?" 你去问问开车的司机,哪一个不了解汽车的结构的,那他的驾照就是混来的。你难道想要傻瓜型的"微软牌汽车"吗?我们来看看:

你买的微软牌汽车最开头只有一个座位,每加一个座位你得向汽车公司付钱。车上的防撞气囊不时 会冒出来,说是为了你的安全。每开100英里要大修一次,每过一年要换一次引擎8酱模慊贡匦牖挥糜晌⑷砥倒局付ǖ氖凸咎峁┑男滦秃诺幕汀D 愕某党隽宋侍猓欠晒娑ǎ悴蛔妓阶圆鹂愕钠道葱蘩恚惚匦璧轿⑷砥倒局付ǖ奈薜闳ィ枰断嗟倍嗟那拍苄藓靡桓鲂∶ ?

最可气的是,你每换一个型号的微软牌汽车,它的刹车和离合器都在不同的位置,你需要重新去考 驾驶执照。如果这辆汽车在途中刹车失灵,你受了重伤,你也不能状告微软汽车公司,因为你买来汽车之后必须签一个合同,说"由于微软牌汽车对你和家人造成的 一切死伤,微软概不负责。"

怎样完全用 GNU/Linux 工作

说了这么多 Windows 的不好。我还没有告诉你我怎么用 Linux 处理有些必要的事情。半年以前我由于中文老是配置不好,一直是双系统,不时需要重起到 Win2k 来处理汉字。后来我找到了 miniChinput, XSIM 和 SCIM 输入法。这下可以处理汉字了。而且 VIM 和Emacs 对汉字支持越来越好。我的大部分文本是用 VIM 编辑的,包括程序,信件,网页,LaTeX 论文,MetaPost 绘图语言。

我不用 Word 这样的程序写论文,而是用 LaTeX,因为这是世界上效果最好,最方便的论文工具,是大多数学术杂志要求的格式。幻灯都是用 ConTeXt 做的,用起来很简单,而且效果非常漂亮。你可以看看我的TeX介绍。

至于绘图,你可以用很多可视化的工具,比如 xfig,dia。但是对于我来说,任何可视化的工具都不能完成某些任务,我需要一种可以精确描述图形的语言。我找到了MetaPost。它简单又好用, 而且效果是世界一流的。我的插图,如果不是图像,都是MetaPost 画出来的。

我曾经抱怨 mozilla-mail 经常突然消失,损坏我好几封快要完成的信件。后来我发现mozilla 的邮件处理程序确实是不稳定的,功能又弱,有经验的 UNIX 用户都不用这样的程序。Mutt 是一个非常稳定可靠的 UNIX 邮件处理程序,而且功能非常强大。我曾经为 Gnome 和 KDE 的不稳定而烦恼。现在我找到了非常强大的 FVWM。KDE,Gnome也能和 FVWM 一起工作。虽然 Gnome 和 KDE 总体不稳定,但是某些部件程序还不错,很多 gtk, Qt 的程序也很不错,它们很多都是可以独立于这些桌面环境运行的。

Linux 有很多强大方便的工作方式是 Windows 没有的,或者有类似的东西,但是很差劲或者用起来不方便。比如 ssh 服务,rsync,cvs,expect ……

结论

我写这么多的目的是什么?我希望喜欢 Linux 的朋友,完全清除微软和 Windows 灌输在你脑子里的谬论,别再相信它们所谓的"新技术",别再追赶 Windows,因为追赶Windows = 倒退。马克思有一个思想很重要,"新生事物并不一定是在最近出现的。"

UNIX,Xwindow, TeX 虽然都比 Windows 先出现,但是它们才是先进生产力的代表。我们要清楚的认识到什么才是真正的现代化,什么才是真正的自动化。

消除学计算机很难的幻觉,勇敢的拿起像 bash, FVWM, TeX, VIM, Emacs, Mutt ……这样强大的程序,勇敢的面对符号。不要再埋怨"Linux 为什么不能像 Windows 那样",不要再浪费时间试用这样那样的程序,不要再忙着升级。你需要理解 UNIX 的工作方式,因为那是大多数科学家的工作方式。Linux 可以成为你的好朋友,你需要认识它,了解它,信任它,才能完全的靠它来高效的工作。当然,在游戏机,手机,掌上电脑里,或者在用电脑来娱乐的时候,用一些 "傻瓜软件"还是不错的.

我希望小学,中学的计算机老师能够提高自己的素质,在孩子们的启蒙教育中充分利用Linux 神秘的特点,引起孩子们对数学,对符号的好奇心。诱导他们用计算机来解决世界上的有趣问题,而不要把教学的范围局限于计算机的操作和它自身的问题。

附录: 我用来处理日常事务的 Linux 程序

好了好了。我知道你发现自己应该转向 Linux,你很后悔当初为什么中了微软的邪。但是不要着急。因为这些东西本来只是工具,它们是用来完成你的主要任务的辅助而已。你以前选错了工具,这不 要紧。你还是拥有你自己原来的专业技能,那才是最重要的。工具的东西只有慢慢适应转换,不能一蹴而就,否则你会感到非常没意思,甚至放弃。

如果你只想做一个像我这样的普通用户,主要目的是用 Linux 来完成自己的任务,那就可以不用系统管理员或者网络管理员的标准来要求自己,因为当一个系统和网络管理员确实很辛苦。这里我对实验室的网管同学鞠一躬,谢 谢你的指点和帮助. 不用把你的机器当成网络服务器,不用开放没有必要的服务,设置好 ssh, ftp 已经足够了。这样会省去了解很多没必要了解的东西的时间。不用过度考虑"安全",因为 Linux 缺省已经很安全了。不过你有兴趣了解更多那也无妨。

下面给出一些推荐使用的可以处理一般事情的程序。至于你的专业上要用到的科学和工程软件比如 Matlab, Mathematica, Maple, HSpice, Design Compiler, …… 还有其它物理上的,化学上的,生物上的 …… 都必然有 Linux 和 UNIX 的版本。当然他们很多不是免费的,不要总是觉得什么都应该免费,自由不等于免费。它们是经过很多人辛勤劳动的产物,是可靠的程序,它们物有所值。

下面列出我常用的一些 Linux 程序。一个列表里可能有很多,那是为了方便你来选择,我列出了比较信得过的。但其实很多只有第一个是我真正在用的,我不喜欢试用程序。我不是一个合格的网络管理员,我的服务器都只设置了我自己需要的功能,那样可以省去我很多麻烦。

Shell: bash。它结合了 csh 和 ksh 的优点,并且有 readline 功能,你可以随意绑定自己的键盘。

编辑器: VIM, Emacs。

程序开发: GCC, make, ld, Scheme48, j2sdk, Perl, Python, Tcl/Tk ...

论文,幻灯工具:LaTeX, ConTeXt

绘图工具:MetaPost。这个语言太强了,以至于我只用它了。你不熟悉的话可以用xfig, dia 来画一些流程图之类的图片。

图像处理:ImageMagick。其中的 import 程序可以屏幕抓图,convert 程序可以转换图像格式,display 可以显示图片和简单编辑(缩放,换质量,转格式,简单绘图,简单虑镜)。通常我就这么点需要。如果你要更强大的图像工具可以用 Gimp, 它几乎和Photoshop差不多。

自动管理工具:make。我可以用make来自动编译程序,自动编译文档,自动更新插图…… 全自动,而且不会重复劳动。

数值计算程序:SciLab。这个程序基本上可以代替 Matlab。

代数计算程序:MAXIMA。这个程序基于世界上最老的计算机代数系统之一: 由美国能源部(DOE)发行的 MIT Macsyma 系统。它是用 Common Lisp 实现的。很多现在的符号计算程序比如 Maple 都从 MAXIMA 身上学到很多东西。它现在经过 DOE 批准以GPL发行,永远是一个自由软件。

加密程序:GnuPG。我的 PGP 密钥就是它搞出来的。

打包,压缩程序。什么都有: tar, gzip, bzip2, zip, rar, ...

虚拟光驱程序。Linux 不需要虚拟光驱程序,直接 mount 就行了。

ftp 服务器:proftpd, vsftpd。proftpd 功能很强,但是我只用了最简单的一种设置。

WWW 服务器:apache。(我一般没有开)

ftp 客户程序:lftp,ncftp。它们都是文本方式操作的,但是比起图形界面的方便的多。比如 lftp 几乎具有 bash 的所有方便功能,Tab 补全,bookmark, queue, 后台下载,镜像…… Linux 也有图形界面的 ftp 客户程序,但是大多不稳定,有很多问题。这就是很多人抱怨 Linux 不如 Windows 的一个小原因。还有很多人用 Wine 模拟 Windows 的leapftp,其实 lftp 比 leapftp 好很多,你需要的只是适应一下。

自动下载工具:wget。它非常稳定,有一次我下载一个程序,用 IE 和 Mozilla 下载回来的文件都是坏的,最后还是 wget 可靠的传输了数据。用它甚至可以镜像整个网站,比起WebZip 这样的 Windows 程序强多了,而且不会因为你不付钱就在下载回来的网页里强制插入广告。

虚拟终端:rxvt, xterm, gnome-terminal, mlterm, ...

X server: XFree86

窗口管理器:FVWM。编译加入了 libstroke。

中文输入:XSIM。被我修改过以适应 FVWM 的需要。另外推荐你还可以用 SCIM。

email 处理:Mutt + Postfix + fetchmail

看 PDF, PS, DJVU 文件:Acrobat Reader, xpdf, GhostScript, gv, djvu工具包和netscape 插件。

看CAJ文档。我从来不看CAJ之类的文档,如果找不到PDF或PS,直接去图书馆借最好。

看网页:Mozilla, Phoenix, lynx。Mozilla-Xft 的显示效果比IE 好很多。

英汉字典:IBM智能词典,星际译王。

编辑网页:我用VIM 直接写 HTML。你如果想要图形方式的可以用其它的比如screem, BlueFish。

登录其它 UNIX, Linux 机器:openSSH, telnet。 我喜欢用 openSSH 把其它机器的X 程序通过 ssh 加密的隧道传到我机器上显示。

登录 Windows2000 server 的 display service: rdesktop,...我有一天试了一下,不错。后来就没有用过了。

同步程序:rsync。我用 rsync 通过 ssh 来跟某些机器同步数据,或者做自己机器上不同目录间的同步。

上BBS:rxvt(或任何一种终端) + telnet + chatbot(helloooo 机器人的程序)

QQ, ICQ: 我没有 QQ 或 ICQ。不过你可以用 Gaim, 它同时支持 QQ, ICQ 和很多其它的即时通信方式。ICQ 用户也可以用 Licq。

放录像:MPlayer, RealPlayer。MPlayer 太好了,直接就可以放 VCD, DVD, divx, wma, wmv ... 用 Windows 的同学都很羡慕我,说 Windows 要放这个需要大堆插件。rm 最好还是用 realplayer 放,它也是免费的。

放音乐: xmms(mp3,ogg都可以), mpg321(放mp3), ogg123(放ogg)。mpg321 不如xmms管理音乐文件那么方便,但是有时我还是用 mpg321 放 mp3 作为背景音乐,因为懒得开一个xmms窗口:-)

游戏:我觉得 KDE 的那个 ksokoban(推箱子),很好玩 :-)

看 Word 文档。请 Word 用户把文档全部转为 PDF 或 PS 再给我,文档里没有特殊的格式干脆就用文本吧,何必那么麻烦。以前很奇怪的是,通知里本来没有什么特殊的格式居然还要发doc附件的email。现在好 了,我们系发通知都用文本,PDF,甚至图片了。

其它程序:还有很多我需要用而你不一定用得着的。比如,Doctor Scheme,

Scheme48, Scsh, kawa...这些程序只有 Doctor Scheme 有Windows版本。还有很多幕后工作但是你一般不察觉的:xinetd, telnetd, sshd, crond, atd, lpd, ... 他们都比 Windows 的对应者强的多,或者根本没有对应者。

附:

写给支持和反对《完全用Linux工作》的人们

作者:王垠

在一阵阵唾骂和欢呼声中,《完全用linux工作》被转载到了天涯海角。很多人支持我,也有 很多人唾骂我。我不知道它是怎样流传到那么多地方,其实我不知道它都被转到哪里去了…… 我知道现在这篇文章又会罗里罗索写很长(因为我计划写这样一个东西已经很久了,坐在Emacs前面总是有一种巫师在炼丹的感觉……),所以先提出中心思想 吧。中心思想就是:

我只是一个傻瓜。看《完全用Linux 工作》的时候请用你们自己的判断力。

几乎所有人都承认,那篇文章很偏激。当时的情况是这样,我用 Linux 的时候被一个同学鄙视了,说:"你怎么用像 DOS 一样落后的东西,真土!看我漂亮的 Win2000..." 这跟当面嘲笑别人老婆或者妈妈有什么区别?我义愤填膺啊,就几乎跟他吵起来。然后就写出了这篇文章放在主页上,叫了几个人来看。接着我珍爱的 TeX 又受到众人鄙视,于是我又写了一篇文章打击 Word,然后把 TeX 捧上了天。道理很简单,鄙视我喜欢的东西的人就是敌人 --邪教徒或者恐怖分子--他支持的我就反对,他反对的我就支持。为了使人信服,举例必用大科学家,世界一流大学,一流实验室的名号,虽然我不跟其中任何 一种沾边。还好那时候我还不认识上帝,要不就打他的名字了。论据不管是实际经历还是自己推测的,先写上去再说。扬眉吐气啊!隔壁微软研究院的哥们居然都被 我打动了,开始写 Linux 程序,学用 LaTeX 和 Emacs。不过几天之后我就把它删掉了,因为我自己都感觉到偏激。

于是就没管那篇文章了。可是没想到它竟然已经被转载到那么多地方,似乎引起不小的波澜。有段 时间每天都收到十几封email,国内的,国外的,问技术问题的,夸我的,骂我的,讲道理的,鄙视我的,想交朋友的,语重心长的,号称要删掉机器上的 Windows 的…… 我的主页居然也占据了"王垠"在 Google 上的首选位置,把那个日本的什么王公贵族"李王垠殿下"都挤下去了。大家似乎都知道我天花乱坠的本事了,有人就想找我写文章向别人推荐商业软件,我很后悔 没有趁机狠狠赚一笔。走到图书馆,亮出借书证,管理员张大了嘴说:"哇!你就是那个 Linux 牛人啊!",也不知道他是褒是贬。甚至有人把他的 BBS 昵称都改成了"坚决拥护精神领袖花生" (花生是我的外号)。为此还骗到了好几顿报告?quot;报告"是清华专用动词,意思是请客吃饭)。虽然我觉得自己身上没有什么值得自豪的东西,但是又有 点为自己兴风作浪的本事感到惊讶。虽然我一再告诫自己要谦虚,但是不由的有一种毛泽东,甘地,甚至摩西的感觉。我更加体会到"网络上没有人知道你是一头猪 "的真理性。其实,不但网络上没有人知道我是一头猪,实际生活中也没有人知道,其实我是一头笨猪。

这么长的时间之后,还有人写信给我说"深受鼓舞","提壶灌顶","对不起我还在用 Windows 给你写信","真想删掉Windows 啊" …… 我很好奇,我的文章真的有那么大的威力?我再看这篇文章,觉得有点惨不忍睹,看了开头就不忍心再看下去。我告诉同学我很后悔写了一篇这么偏激的文章,可是 他?quot;徼枉必须过正,你没有错",所以我也搞不清楚自己这样写对不对,这样自责对不对。就像我从来不敢看自己照片,却有时被人称为帅哥,就让我无 法判断自己是否帅一样。所以现在我就开始怀疑我自己是否真是一头笨猪。也许多年以后,我会正确的评价我的想法。就像我现在觉得我15岁的照片挺养眼一样, 也许我会发现自己其实是一头聪明猪?

写这篇文章不是为了让自己免得被骂,也不是为了显示高深的猪的哲理。只是因为我深深的感到人应该有自己的判断力,不要简单的接受别人说的 DO's 和 DONT's。怀疑一切,同时又敞开心扉去了解一切。

看过《完全用Linux工作》的朋友,请仔细检查里面的 DO's 和 DONT's。

2004.8.26

- 作者: nearxlz 2006年04月1日, 星期六 12:25  回复(2) |  引用(0) 加入博采

Web 2.0 网站成功的关键

内因类

一、网站是否能满足较多用户的需求。

这 里的较多不是一个绝对的量,要依情况而定。如Flickr满足人们分享、存储图像的需求,这个人群是非常大的。而Linkist满足人们建立人脉的需求, 有这个需要的人群也很大。但你要说一个绝对的量,就不好估计了。总之,网站要能满足较多用户的某种(或几种)需要。而那种只针对小圈子的服务,和Web 2.0的根本要求就有些差距了,这里不涉及。

二、网站的易用性、用户体验是否够好。

一 个针对广大群众的网站,其对易用性的考虑是必要的。如果你的操作流程,功能实现等设计得太过于复杂,那么,是会吓跑用户的。而好的用户体验,才是用户持续 使用你的服务,并愿意为你贡献信息和资源的重要前提。所以,对于网站经营者、建设者来说,这是一个需要充分考虑的问题。而且,这也会催生UI设计师这一个 新个职业的出现。

用户体验主要涉及这几个方面:

  • 品牌内涵形象。(如google)
  • 操作是否简便。(如del.icio.us)
  • 功能是否够用。(如flickr)
  • 界面是否美观。(如digg、last.fm)
  • 速度和稳定性。(如豆瓣)

三、已有资源的质量和数量。

只有当已有资源够多够好时,才会有更多的用户愿意加入进来,因此,Web 2.0网站最初的内容建设是非常关键的,而且也是战胜对手、摆脱追兵和模仿者的重要基础。

四、网站本身是否有足够的、持续的吸引力。

只有当网站有足够的、持续的吸引力时,它的经营、发展才是稳定的、增长的。事实上,满足上面三大要素,问题就不大了。

外因类

一、用户的数量是否够多。

更多的用户数量,说明有更多有人在关注网站,说明网站有更大的潜力,说明影响力的多少,这些注册用户是网站最重要的有生资源。但我们也要注意的是,注册用 户的量对Web 2.0网站的建设和发展来说,并不是最关键的外因。活跃的、能够不断贡献资源和信息的注册用户才是。至于怎么让这一部分人不遗余力地去做贡献,则是网站经 营者需要去深入考虑的问题之一了。

二、用户是否愿意为网站贡献资源。

用户创 造资源,是Web2.0的关键特性。这些资源是网站最重要东西。它们可有多种形式: 图片、音频、视频、文章,甚至是关系。任何一个好的Web 2.0都是能够充分地调动用户的积极,不断地为其贡献信息和资源的,这是一个Web 2.0网站成功的关键因素,甚至可以说是重中之重。

要让用户免费为网站贡献资源和信息,有三点是很重要的:

  • 对用户自身有什么意义、好处。
  • 用户体验是否够好。(如操作方便)
  • 网站是否会诱导。

如果Web 2.0网站不能很好的利用用户创造信息和资源,那么,它就只有等死了。不要怪现实残酷,事实就是这样。

附加信息: 用户为什么自愿免费贡献内容给一个网站?

  • 期望被周围亲近的朋友们关注
  • 期望被更有 power 的人关注
  • 把自己的秘密在网上挖个洞埋进去,心情会变好(有多少人觉得这样的方式有效?)
  • 炫耀自己拥有的或者自己知道的,或者说共享(大部分人这样做)
  • 学术性的交流(很少人这样做)
  • 通过 Google AdSense 挣钱(极少人这样做)
  • SEO(确实有效,但是只有极少极少的人这样做)
(via livid.cn)

三、网站的知名度是否够高

有更多的人知道你的网站及其提供的服务,那么,那目标用户需要由你的网站提供的那种服务的时候,他们选择你的网站的机率就大大的提高了。从而,使网站的规模、实力、潜力,都一点点地得到增强。

要让更多人知道你的网站,就主要靠广告宣传和口碑宣传了:

  • 广告宣传:比如淘宝和eBay易趣,双方都猛打广告,其目的就是要让更多的人知道它们。而当这些人有买卖商品的需要时,自然就是奔向它们了。
  • 口碑宣传:
    • 媒体吹捧(在线媒体、门户的宣传,传统电视台、电台、纸媒的宣传等)。
    • 用户推广(如有名的病毒式营销、Blogger们的介绍、用户介绍朋友等)。


- 作者: nearxlz 2006年03月9日, 星期四 23:14  回复(0) |  引用(0) 加入博采