冰河

有些论文的Full text只提供给subscribers,普通用户不能下载。这个时候如果在本校或者其他开放的libraries也下不到的话,只能发邮件索取了。据我 的感受,老外一般都很热情,也很愿意与你沟通交流(国人的话就看RP了)。如果不涉及到商业机密和版权问题,一般都会成功。下面有2篇信件原文,是我从互 联网上找的,大家参考。

第一篇是索要论文

Dear Prof. Carlos Antonio
I am writing to request your assistance. I am a doctor student and study at Northwestern Science and Technology University of Agriculture and Forestry, my research focus on hypoxia stress. I searched one of your papers: “The metabolic response of plants to oxygen deficiency” is published at Brazilian Journal of Plant Physiology. I am very interested in you paper, but I can not read full-text content, would you mind sending your full-text content by E-mail
I am looking forward for your kind reply early. Thank you for your assistance.
With kind regards

Sincerely yours

College of Horticulture, Northwest A & F University
Yangling, shaanxi712100, China

2009-3-26

第二篇是索取某一解答的详细推导和作者最近的其他论文

我的邮件:
Dear Dr. Sagaseta,
I am a Ph.D student of Zhejiang University at China. Recently, I have read one of your articles, titled “Consolidation around stone columns. Influence of column deformation” in “Internation Journal for Numerical and Analytical Methods in Geomechanics”.I got many new ideas from your article. For me, your work is quite innovative. However, there are some jumps in the derivations of the solutions presented in Table 1 of your paper(i.e.,General elastic solution. Stresses and Strains for any load pa and excess pore pressure u) and it is difficult for me to understand these results. I wonder if you would consider sending me the detailed derivation of the solutions presented in Table 1 in a seperate Word file. In addtion, I would be grateful if you can sent me some papers regarding your recently research about the subject of your present paper by Email.

Respectfully yours,
Meng-Meng LU
Institute of Geotechnical Engineering, Zhejiang University, Hangzhou 310058, China

老外的回复:

Dear Mr. Lu,
Thank you very much for your interest in our recent publication. I’m the other author of the paper, which was basically the core of my PhD thesis. In my thesis, the solution is derived in detail, unfortunately, it’s written in Spanish, so please, give me a couple of weeks to translate this part of the thesis and I will gratefully send it to you.

I’ve read also part of your work with Prof. Xie, e.g. a paper in Computer and Geotechnics, in the field of consolidation of composite materials. I’ve got also some ideas, because you apply your consolidation derivation to the Han and Ye’s solution, and I think it could be also applied to the solution that we’ve published in the Int. J. Num. and Analyt. Met. in Geom. So, please, feel free to ask further questions and I am open to any kind of collaboration.

Regarding to other papers, I don’t know now of any other that could be of interest for you. We’ve got another paper in the 2nd IWGSS (www.iwgss.org), but it’s basically a summary ot the journal paper.
We keep in touch.
If I happen not to send you the derivation in a couple of weeks, please remind me it.
With kind regards,

Jorge

Jorge Castro
Group of Geotechnical Engineering
Universidad de Cantabria
ETS. Ing. Caminos, Canales y P.
39005 Santander (Spain)

MySQL命令集锦

Posted by 冰河 at 21:00 No Responses » 20,077 Views
十二 182009

测试环境:mysql 5.0.45
【注:可以在mysql中通过mysql> SELECT VERSION();来查看数据库版本】

一、连接MYSQL

格式: mysql -h主机地址 -u用户名 -p用户密码

1、连接到本机上的MYSQL

键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密码前必须没有空格,否则让你重新输入密码.

如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL的提示符是: mysql>

2、连接到远程主机上的MYSQL。假设远程主机的IP为:110.110.110.110,用户名为root,密码为abcd123。则键入以下命令:

mysql -h110.110.110.110 -u root -p 123;(注:u与root之间可以不用加空格,其它也一样)

3、退出MYSQL命令: exit (回车)

二、修改密码。

格式:mysqladmin -u用户名 -p旧密码 password 新密码

1、给root加个密码ab12。键入以下命令

mysqladmin -u root -password ab12

注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。

2、再将root的密码改为djg345。

mysqladmin -u root -p ab12 password djg345

三、增加新用户。
(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)

格式:grant select on 数据库.* to 用户名@登录主机 identified by “密码”

1、增加一个用户test1密码为abc,让他可以在任何主机上登录,并对所有数据库有查询、插入、修改、删除的权限。首先用root用户连入MYSQL,然后键入以下命令:

grant select,insert,update,delete on *.* to test1@”%” Identified by “abc”;

但增加的用户是十分危险的,你想如某个人知道test1的密码,那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了,解决办法见2。

2、增加一个用户test2密码为abc,让他只可以在localhost上登录,并可以对数据库mydb进行查询、插入、修改、删除的操作(localhost指本地主机,即MYSQL数据库所在的那台主机),

这样用户即使用知道test2的密码,他也无法从internet上直接访问数据库,只能通过MYSQL主机上的web页来访问了。

grant select,insert,update,delete on mydb.* to test2@localhost identified by “abc”;

如果你不想test2有密码,可以再打一个命令将密码消掉。

grant select,insert,update,delete on mydb.* to test2@localhost identified by “”;

下篇我是MYSQL中有关数据库方面的操作。注意:你必须首先登录到MYSQL中,以下操作都是在MYSQL的提示符下进行的,而且每个命令以分号结束。

一、操作技巧

1、如果你打命令时,回车后发现忘记加分号,你无须重打一遍命令,只要打个分号回车就可以了。

也就是说你可以把一个完整的命令分成几行来打,完后用分号作结束标志就OK。

2、你可以使用光标上下键调出以前的命令。

二、显示命令

1、显示当前数据库服务器中的数据库列表:

mysql> SHOW DATABASES;

注意:mysql库里面有MYSQL的系统信息,我们改密码和新增用户,实际上就是用这个库进行操作。

2、显示数据库中的数据表:

mysql> USE 库名;
mysql> SHOW TABLES;

3、显示数据表的结构:

mysql> DESCRIBE 表名;

4、建立数据库:

mysql> CREATE DATABASE 库名;

5、建立数据表:

mysql> USE 库名;
mysql> CREATE TABLE 表名 (字段名 VARCHAR(20), 字段名 CHAR(1));

6、删除数据库:

mysql> DROP DATABASE 库名;

7、删除数据表:

mysql> DROP TABLE 表名;

8、将表中记录清空:

mysql> DELETE FROM 表名;

9、显示表中的记录:

mysql> SELECT * FROM 表名;

10、往表中插入记录:

mysql> INSERT INTO 表名 VALUES (”hyq”,”M”);

11、更新表中数据:

mysql-> UPDATE 表名 SET 字段名1=’a’,字段名2=’b’ WHERE 字段名3=’c’;

12、用文本方式将数据装入数据表中:

mysql> LOAD DATA LOCAL INFILE “D:/mysql.txt” INTO TABLE 表名;

13、导入.sql文件命令:

mysql> USE 数据库名;
mysql> SOURCE d:/mysql.sql;

14、命令行修改root密码:

(1)已知当前密码

mysql> UPDATE mysql.user SET password=PASSWORD(’新密码’) WHERE User=’root’;
mysql> FLUSH PRIVILEGES;

(2)忘记密码

1、首先停止正在运行的MySQL进程

Linux下,运行 killall -TERM mysqld
Windows下,如果写成服务的 可以运行:net stop mysql,如未加载为服务,可直接在进程管理器中进行关闭。

2、以安全模式启动MySQL

Linux下,运行 /usr/local/mysql/bin/mysqld_safe –skip-grant-tables >/dev/null 2>&1 &
Windows下,在命令行下运行 X:/MySQL/bin/mysqld-nt.exe –skip-grant-tables

3、完成以后就可以不用密码进入MySQL了

Linux下,运行 /usr/local/mysql/bin/mysql -u root -p 进入
Windows下,运行 X:/MySQL/bin/mysql -u root -p 进入

4、更改密码

>use mysql
>update user set password=password(“新密码”) where user=”root”;
>flush privileges;

15、显示use的数据库名:

mysql> SELECT DATABASE();

16、显示当前的user:

mysql> SELECT USER();

三、一个建库和建表以及插入数据的实例

drop database if exists school; //如果存在SCHOOL则删除

create database school; //建立库SCHOOL

use school; //打开库SCHOOL

create table teacher //建立表TEACHER
(
id int(3) auto_increment not null primary key,
name char(10) not null,
address varchar(50) default ‘深圳’,
year date
); //建表结束

//以下为插入字段
insert into teacher values(”,’allen’,’大连一中’,’1976-10-10′);
insert into teacher values(”,’jack’,’大连二中’,’1975-12-23′);

如果你在mysql提示符键入上面的命令也可以,但不方便调试。

(1)你可以将以上命令原样写入一个文本文件中,假设为school.sql,然后复制到c:\下,并在DOS状态进入目录\mysql\bin,然后键入以下命令:

mysql -uroot -p密码 < c:\school.sql

如果成功,空出一行无任何显示;如有错误,会有提示。(以上命令已经调试,你只要将//的注释去掉即可使用)。

(2)或者进入命令行后使用 mysql> source c:\school.sql; 也可以将school.sql文件导入数据库中。

四、将文本数据转到数据库中

1、文本数据应符合的格式:字段数据之间用tab键隔开,null值用\n来代替.例:

3 rose 大连二中 1976-10-10

4 mike 大连一中 1975-12-23

假设你把这两组数据存为school.txt文件,放在c盘根目录下。

2、数据传入命令 load data local infile “c:\school.txt” into table 表名;

注意:你最好将文件复制到\mysql\bin目录下,并且要先用use命令打表所在的库。

五、备份数据库:(命令在DOS的\mysql\bin目录下执行)

1.导出整个数据库

导出文件默认是存在mysqlin目录下

mysqldump -u 用户名 -p 数据库名 > 导出的文件名

mysqldump -u user_name -p123456 database_name > outfile_name.sql

2.导出一个表

mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名

mysqldump -u user_name -p database_name table_name > outfile_name.sql

3.导出一个数据库结构

mysqldump -u user_name -p -d –add-drop-table database_name > outfile_name.sql

-d 没有数据 –add-drop-table 在每个create语句之前增加一个drop table

4.带语言参数导出

mysqldump -uroot -p –default-character-set=latin1 –set-charset=gbk –skip-opt database_name > outfile_name.sql

十二 182009

这2天接触了一下Amazon Web Services(AWS)中的Amazon Simple Storage Service,简称Amazon S3(下称S3)。S3站点上用下面的语句描述了自己的作用:

Amazon S3 is storage for the Internet. It is designed to make web-scale computing easier for developers.

Amazon S3 provides a simple web services interface that can be used to store and retrieve any amount of data, at any time, from anywhere on the web. It gives any developer access to the same highly scalable, reliable, fast, inexpensive data storage infrastructure that Amazon uses to run its own global network of web sites. The service aims to maximize benefits of scale and to pass those benefits on to developers.
通过S3这个接口,您可以把Amazon的存储服务当作一个硬盘,可以随时随地上传,下载数据,不过您得付钱才可以使用,即使您只是准备测试一 下。S3首页上有价格表。在S3注册并付费获取2个数:Access Key ID和Secret Access Key,才可以使用S3的服务,因为所有的操作都需要这2个数进行身份验证。

一、基本概念:Buckets,Objects,Keys,Operations

注册后,用户通过名为bucket的容器来管理所有数据,这些数据称之为对象(Object)。比如,一个名为20071211/logo- 320×240.gif的对象存放在livebaby这个bucket里,则可以通过URL:http: //s3.amazonaws.com/livebaby/20071211/logo-320×240.gif来访问这个对象。bucket有3个基本 概念:1、不能删除非空的bucket;2、bucket不能转让给其他用户;3、每个用户最多只能有100个buckets。简单的说,bucket类 似硬盘分区中的第一层目录。

这里还有一个key的概念,key是bucket中对象的唯一标识符,每个对象对应一个key。上例中,20071211/logo-320×240.gif称为key。

每个对象都有一组键值对,称为MetaData,分2种,系统metadata和 用户metadata。S3不处理用户metadata,只接收、存储、返回给用户,由用户自己处理。REST下,系统metadata以x-amz-开 头,用户metadata以x-amz-meta-开头。

Amazon提供2种API:Simple Object Access Protocol(SOAP)和Representational State Transfer(REST)来访问AWS。这里一篇文章,其中简单对比了一下2者的区别,区别后总结说:“ In fact, you can think of REST as a kind of data-access methodology whereas SOAP is a process-control methodology.”

通过SOAP和REST,最常用的操作(Operation)有这么几个:

* 创建bucket;
* 上传对象,上传时必须指定一个key,同时还可以设置这个对象的访问控制权限,默认是私有的;
* 下载对象,有HTTP 和 BitTorrent2种方式;
* 删除对象;
* 列表对象;列表时,可以通过一个前缀(prefix)来过滤显示不同的对象。

通过向AWS的服务端点(endpoint,http://s3.amazonaws.com/)发出PUT、GET、DELETE、HEAD等HTTP Requests,便可以操作S3上的数据。

如果通过web访问S3服务来获取数据(Object),则分页、搜索等功能是比不可少的。而S3提供的4个参数,可以让我们方便快捷的将数据取出来,这4个参数是基于key操作的。key的概念参见文章一。

1、prefix。比如http://bucket.s3.amazonaws.com/?prefix=123,则将key中以123开头的列出来。

2、delimiter。比如http://bucket.s3.amazonaws.com/?delimiter=/,此时,S3可能会返回CommonPrefixes,将key中采用“/”分隔的列出来。

<Contents>
<Key>123/zzz.txt</Key>
<LastModified>2007-12-11T07:41:51.000Z</LastModified>
<ETag>”d725dfc2167445d1db23067de33ebd28″</ETag>
<Size>203</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>abc/ooo/yxx.txt</Key>
<LastModified>2007-12-12T05:34:35.000Z</LastModified>
<ETag>”4fdf8a4dd42bd4d24855eebd5c9b9434″</ETag>
<Size>41</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>

用了“delimiter=/”返回,告诉你 有prefix为123/和abc/可用。

<CommonPrefixes>
<Prefix>123/</Prefix>
</CommonPrefixes>
<CommonPrefixes>
<Prefix>abc/</Prefix>
</CommonPrefixes>

这时输入http://bucket.s3.amazonaws.com/?delimiter=/&prefix=123/则将prefix中有123/的全部列出来。

如果key有这样的形式:ms_vb_5_src/sss.frm,ms_vb_6_src/ddd.frm,你可以把delimiter设为“_”来取数据。通过不同的delimiter和prefix可以非常灵活的获取数据。

如果数据量很大,则可以用第三个和第四个参数

3、MaxKeys。这个告诉S3一次性返回多少数据,默认返回1000个。URL输入http://bucket.s3.amazonaws.com/?delimiter=/&prefix=123/&max-keys=10,则返回:

<Name>bucket</Name>
<Prefix>123/</Prefix>
<Marker />
<NextMarker>123/10.txt</NextMarker>
<MaxKeys>10</MaxKeys>
<Delimiter>/</Delimiter>
<IsTruncated>true</IsTruncated>
<Contents>
<Key>123/1.txt</Key>
<LastModified>2007-12-12T06:02:33.000Z</LastModified>
<ETag>”9dd4e461268c8034f5c8564e155c67a6″</ETag>
<Size>1</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>

里面IsTruncated为true,表示按照delimiter和prefix和max-keys取出的数据不止10个;余下的数据怎么取?就用到了NextMarker元素中数据。

4、Marker。 URL输入http://bucket.s3.amazonaws.com/?delimiter=/&prefix=123/&max -keys=10&marker=123/10.txt,marker的值就是NextMarker元素中数据。这样S3就返回了下10条数据。

<Name>bucket</Name>
<Prefix>123/</Prefix>
<Marker>123/10.txt</Marker>
<NextMarker>123/19.txt</NextMarker>
<MaxKeys>10</MaxKeys>
<Delimiter>/</Delimiter>
<IsTruncated>true</IsTruncated>
<Contents>
<Key>123/1.txt</Key>
<LastModified>2007-12-12T06:02:33.000Z</LastModified>
<ETag>”9dd4e461268c8034f5c8564e155c67a6″</ETag>
<Size>1</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>

如果IsTruncated仍为true,则表示还有数据,我们把marker改为marker=123/19.txt便可以继续取下10条数据;如果IsTruncated为false,则表示按照条件已经将数据全部取出来了。

S3文档中,提供更为详细的解释。点击查看:http://docs.amazonwebservices.com/AmazonS3/2006-03-01/

云计算

Posted by 冰河 at 20:58 No Responses » 11,993 Views
十二 182009

在这场围绕云计算的竞赛中,究竟谁能捷足先登?

你的企业的计算机速度够快么?这是一个很难回答的问题。对众多企业来说,自身计算机设备的性能也许永远无法满足需求,因为企业内部信息爆炸的 速度远远比摩尔定律要快得多。一个简单的办法是采购更多、更先进的设备,这可正中设备公司的下怀。英特尔(www.intel.cn)、AMD (www.amd.com.cn)马不停蹄地推出一系列多核处理器,戴尔(www.dell.com.cn)、惠普(www.hp.com.cn)、 IBM(www.ibm.com.cn)等公司的服务器销售人员也从未放松对客户的关照。

但问题也随之而来。尤其是对于众多在资金预算上捉襟见肘的企业来说,不断更新计算设备并非万全之策。还有一点,企业必须租用更多的地方来存放 这些发热量惊人的大铁箱子—由此带来的耗电量本身也是一个令人挠头的问题。有没有更加经济有效的解决途径呢?“云计算”的出现也许为这个问题的解决推开了 大门的一个缝隙。

云计算兴起

云计算是一种全新的商业模式,其核心部分依然是数据中心,它使用的硬件设备主要是成千上万的工业标准服务器,它们由英特尔或AMD生产的处理器以及其他硬件厂商的产品组成。企业和个人用户通过高速互联网得到计算能力,从而避免了大量的硬件投资。

简而言之,云计算将使未来的互联网变成超级计算的乐土。“云计算的基本原理是,通过使计算分布在大量的分布式计算机上,而非本地计算机或远程 服务器中,企业数据中心的运行将更与互联网相似。这使得企业能够将资源切换到需要的应用上,根据需求访问计算机和存储系统。”在11月中旬的上海IBM创 新论坛上,IBM高性能随需解决方案团队副总裁Willy Chiu对记者解释说。

这可是一种革命性的举措,打个比方,这就好比是从古老的单台发电机模式转向了电厂集中供电的模式。它意味着计算能力也可以作为一种商品进行流通,就像煤气、水电一样,取用方便,费用低廉。最大的不同在于,它是通过互联网进行传输的。

这场技术竞赛吸引了众多参赛者。包括Sun、IBM、微软、Google(www.g.cn)、亚马逊(www.amazon.cn)等信息 业巨头都已经循迹而来。“云计算正在兴起。”微软超级计算机研究员Dan Reed也说,“推动云计算兴起的动力是高速互联网连接的发展、更加廉价且功能强劲的芯片以及硬盘、数据中心的发展。”

互联网企业是这方面的先行者,Google的搜索引擎可以视为云计算的早期产品。用户的搜索请求经过互联网发送到Google的大型服务器集 群上,完成之后再返回用户桌面。Amazon.com最近向开发者开放了名为“弹性计算机云”的服务,它可以让小软件公司按照自己的需要购买Amazon 数据中心的处理能力。

IT巨头从中窥到了更大的商机。去年,Sun公司推出了基于云计算理论的“黑盒子”计划。按照它的规划,将来的数据中心将不会局限于拥挤、闷 热的机房中,而是一个个可移动的集装箱—它装载的是10吨经过合理安置的服务器,作为一个可移动的数据中心。它既可以为拥有上万名雇员的大型公司服务,也 能为中小企业提供支持。至于这种数据中心的最佳安放位置,有人推荐是郊外的田野上,最好是发电站附近,这样可以实现成本最低化。

蓝色巨人IBM对此也投下了重注,并为此命名为“蓝云”计划。不久前,IBM和Google达成了一项合作,两家公司将各自出资2000 万~2500万美元,为从事计算机科学研究的教授和学生提供所需的电脑软硬件和相关服务。IBM负责系统和技术团队的高级副总裁Willian M.Zeilter表示:“对我来说,这种感觉就像2000年面对Linux。”目前,该公司已经部署了200多名研发人员在这项业务的研究上。

“从某种意义上说,云计算是网格计算模型自然而然的进一步发展。”IDC分析师Frank Gens认为。那么,究竟谁能够在这场围绕云计算的竞赛中获胜呢?

谁是主宰者?

截至目前,Sun公司已经雄赳赳地冲在了前面。这家计算机巨头的“黑盒子”计划已经进入了发售阶段,而大部分竞争对手的相关服务则依然在酝酿 当中。“我们进展顺利,再加上与客户进行的充分沟通,我们知道我们有望成功。”Sun公司CEO舒瓦茨·乔纳森在个人博客中写道。

微软的优势也显而易见,全世界有数以亿计的Windows用户,微软所要做的就是将这些用户通过互联网更紧密地连接起来,并向他们提供云计算 服务—通过Windwos Live。“当你想到存储,就会想到Windows Live。”这是比尔·盖茨在今年夏天说的话,微软正在创造这样一种用户体验,即从一般的设备存储转移到任何时间都可以存储的模式,其目的很明显,就是在 互联网战略上同Google平起平坐。

不过,短时间内Google的地位依然不可撼动,其开放式的平台体现了云计算模式的精髓。Google的云计算服务所需要的绝大部分基础软件 都是开源的,这意味着用户可以自由的得到那些代码并修改。“Google的编程模式以及它真正的开放性很关键,普通人也可以编写应用程序,而不必非得是斯 坦福或者卡耐基梅隆大学的博士。”IDC(www.idc.com.cn)分析师Frank Gens说。

对IBM来说,这也是扩张自身领地的绝佳机会。IBM具有发展云计算业务的一切有利因素:应用服务器、存储、管理软件、中间件等等,因此IBM自然不会放过这样一个成名机会。Willy Chiu透露,“云计算将是IBM接下来的一个重点业务。”

Google(www.g.cn)和IBM的合作则颇具互补效应。两家公司正试图将各自的技术进行融合,IBM熟谙企业级计算机的运行之道, 而Google悉知大流量数据传输和高速网路链接的不二法门—两家公司的联手有望创造出重大成就。IBM公司CEO塞缪尔·帕米萨诺开玩笑地把这个项目形 容为Google年轻工程师与IBM“胖老头儿”的绝妙拍档。Forrester Research分析师阿德利安称,云计算编程技术将成为基准的下一代计算机编程结构,IBM想捷足先登以抢占制高点,这正好可以利用Google的网络 优势。

谁能真正成为云计算的代言人其实并不重要,重要的是,有了这一系列IT巨头作为后盾,毫无疑问,云计算已经拥有了一个光明的前景。云计算的蓝 图已经呼之欲出:在未来,只需要一台笔记本或者一个iPhone,就可以通过网络服务来实现我们需要的一切,甚至包括超级计算这样的任务。从这个角度而 言,最终用户才是云计算的真正拥有者。

十二 182009

第一篇

MapReduce: Simplified Data Processing on Large Clusters
Jeffrey Dean and Sanjay Ghemawat

Abstract

MapReduce is a programming model and an associated implementation for processing and generating large data sets. Users specify a map function that processes a key/value pair to generate a set of intermediate key/value pairs, and a reduce function that merges all intermediate values associated with the same intermediate key. Many real world tasks are expressible in this model, as shown in the paper.

Programs written in this functional style are automatically parallelized and executed on a large cluster of commodity machines. The run-time system takes care of the details of partitioning the input data, scheduling the program's execution across a set of machines, handling machine failures, and managing the required inter-machine communication. This allows programmers without any experience with parallel and distributed systems to easily utilize the resources of a large distributed system.

Our implementation of MapReduce runs on a large cluster of commodity machines and is highly scalable: a typical MapReduce computation processes many terabytes of data on thousands of machines. Programmers find the system easy to use: hundreds of MapReduce programs have been implemented and upwards of one thousand MapReduce jobs are executed on Google's clusters every day.

Appeared in:
OSDI'04: Sixth Symposium on Operating System Design and Implementation,
San Francisco, CA, December, 2004.

Download: PDF Version

Slides: HTML Slides


第二篇

Bigtable: A Distributed Storage System for Structured Data
Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C. Hsieh, Deborah A. Wallach, Mike Burrows, Tushar Chandra, Andrew Fikes, and Robert E. Gruber

Abstract

Bigtable is a distributed storage system for managing structured data that is designed to scale to a very large size: petabytes of data across thousands of commodity servers. Many projects at Google store data in Bigtable, including web indexing, Google Earth, and Google Finance. These applications place very different demands on Bigtable, both in terms of data size (from URLs to web pages to satellite imagery) and latency requirements (from backend bulk processing to real-time data serving). Despite these varied demands, Bigtable has successfully provided a flexible, high-performance solution for all of these Google products. In this paper we describe the simple data model provided by Bigtable, which gives clients dynamic control over data layout and format, and we describe the design and implementation of Bigtable.

Appeared in:
OSDI'06: Seventh Symposium on Operating System Design and Implementation,
Seattle, WA, November, 2006.

Download: PDF Version

第三篇:

The Google File System
Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung

Abstract

We have designed and implemented the Google File System, a scalable distributed file system for large distributed data-intensive applications. It provides fault tolerance while running on inexpensive commodity hardware, and it delivers high aggregate performance to a large number of clients.

While sharing many of the same goals as previous distributed file systems, our design has been driven by observations of our application workloads and technological environment, both current and anticipated, that reflect a marked departure from some earlier file system assumptions. This has led us to reexamine traditional choices and explore radically different design points.

The file system has successfully met our storage needs. It is widely deployed within Google as the storage platform for the generation and processing of data used by our service as well as research and development efforts that require large data sets. The largest cluster to date provides hundreds of terabytes of storage across thousands of disks on over a thousand machines, and it is concurrently accessed by hundreds of clients.

In this paper, we present file system interface extensions designed to support distributed applications, discuss many aspects of our design, and report measurements from both micro-benchmarks and real world use.

Appeared in:
19th ACM Symposium on Operating Systems Principles,
Lake George, NY, October, 2003.

Download: PDF Version

十二 182009

微软著名的C++大师Herb Sutter在2005年初的时候曾经写过一篇重量级的文章:”The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software“,预言OO之后软件开发将要面临的又一次重大变革-并行计算。

摩尔定律统制下的软件开发时代有一个非常有意思的现象:”Andy giveth, and Bill taketh away.”。不管CPU的主频有多快,我们始终有办法来利用它,而我们也陶醉在机器升级带来的程序性能提高中。

我记着我大二的时候曾经做过一个五子棋的程序,当时的算法就是预先设计一些棋型(有优先级),然后扫描棋盘,对形势进行分析,看看当前走哪部对自己 最重要。当然下棋还要堵别人,这就需要互换双方的棋型再计算。如果只算一步,很可能被狡猾的对手欺骗,所以为了多想几步,还需要递归和回朔。在当时的机器 上,算3步就基本上需要3秒左右的时间了。后来大学毕业收拾东西的时候找到这个程序,试了一下,发现算10步需要的时间也基本上感觉不出来了。

不知道你是否有同样的经历,我们不知不觉的一直在享受着这样的免费午餐。可是,随着摩尔定律的提前终结,免费的午餐终究要还回去。虽然硬件设计师还 在努力:Hyper Threading CPU(多出一套寄存器,相当于一个逻辑CPU)使得Pipeline尽可能满负荷,使多个Thread的操作有可能并行,使得多线程程序的性能有 5%-15%的提升;增加Cache容量也使得包括Single-Thread和Multi-Thread程序都能受益。也许这些还能帮助你一段时间,但 问题是,我们必须做出改变,面对这个即将到来的变革,你准备好了么?

Concurrency Programming != Multi-Thread Programming。很多人都会说MultiThreading谁不会,问题是,你是为什么使用/如何使用多线程的?我从前做过一个类似AcdSee 一样的图像查看/处理程序,我通常用它来处理我的数码照片。我在里面用了大量的多线程,不过主要目的是在图像处理的时候不要Block住UI,所以将 CPU Intensive的计算部分用后台线程进行处理。而并没有把对图像矩阵的运算并行分开。

我觉得Concurrency Programming真正的挑战在于Programming Model的改变,在程序员的脑子里面要对自己的程序怎样并行化有很清楚的认识,更重要的是,如何去实现(包括架构、容错、实时监控等等)这种并行化,如何去调试,如何去测试。

在Google,每天有海量的数据需要在有限的时间内进行处理(其实每个互联网公司都会碰到这样的问题),每个程序员都需要进行分布式的程序开发, 这其中包括如何分布、调度、监控以及容错等等。Google的MapReduce正是把分布式的业务逻辑从这些复杂的细节中抽象出来,使得没有或者很少并 行开发经验的程序员也能进行并行应用程序的开发。

MapReduce中最重要的两个词就是Map(映射)和Reduce(规约)。初看Map/Reduce这两个词,熟悉Function Language的人一定感觉很熟悉。FP把这样的函数称为”higher order function”(”High order function”被成为Function Programming的利器之一哦),也就是说,这些函数是编写来被与其它函数相结合(或者说被其它函数调用的)。如果说硬要比的化,可以把它想象成C 里面的CallBack函数,或者STL里面的Functor。比如你要对一个STL的容器进行查找,需要制定每两个元素相比较的 Functor(Comparator),这个Comparator在遍历容器的时候就会被调用。

拿前面说过图像处理程序来举例,其实大多数的图像处理操作都是对图像矩阵进行某种运算。这里的运算通常有两种,一种是映射,一种是规约。拿两种效果 来说,”老照片”效果通常是强化照片的G/B值,然后对每个象素加一些随机的偏移,这些操作在二维矩阵上的每一个元素都是独立的,是Map操作。而”雕 刻”效果需要提取图像边缘,就需要元素之间的运算了,是一种Reduce操作。再举个简单的例子,一个一维矩阵(数组)[0,1,2,3,4]可以映射为 [0,2,3,6,8](乘2),也可以映射为[1,2,3,4,5](加1)。它可以规约为0(元素求积)也可以规约为10(元素求和)。

面对复杂问题,古人教导我们要“分而治之”,英文中对应的词是”Divide and Conquer“。Map/Reduce其实就是Divide/Conquer的过程,通过把问题Divide,使这些Divide后的Map运算高度并 行,再将Map后的结果Reduce(根据某一个Key),得到最终的结果。

Googler发现这是问题的核心,其它都是共性问题。因此,他们把MapReduce抽象分离出来。这样,Google的程序员可以只关心应用逻 辑,关心根据哪些Key把问题进行分解,哪些操作是Map操作,哪些操作是Reduce操作。其它并行计算中的复杂问题诸如分布、工作调度、容错、机器间 通信都交给Map/Reduce Framework去做,很大程度上简化了整个编程模型。

MapReduce的另一个特点是,Map和Reduce的输入和输出都是中间临时文件(MapReduce利用Google文件系统来管理和访问这些文件),而不是不同进程间或者不同机器间的其它通信方式。我觉得,这是Google一贯的风格,化繁为简,返璞归真。

接下来就放下其它,研究一下Map/Reduce操作。(其它比如容错、备份任务也有很经典的经验和实现,论文里面都有详述)

Map的定义:

Map, written by the user, takes an input pair and produces a set of intermediate key/value pairs. The MapReduce library groups together all intermediate values associated with the same intermediate key I and passes them to the Reduce function.

Reduce的定义:

The Reduce function, also written by the user, accepts an intermediate key I and a set of values for that key. It merges together these values to form a possibly smaller set of values. Typically just zero or one output value is produced per Reduce invocation. The intermediate values are supplied to the user’s reduce function via an iterator. This allows us to handle lists of values that are too large to fit in memory.

MapReduce论文中给出了这样一个例子:在一个文档集合中统计每个单词出现的次数。

Map操作的输入是每一篇文档,将输入文档中每一个单词的出现输出到中间文件中去。

map(String key, String value):
    // key: document name
    // value: document contents
    for each word w in value:
        EmitIntermediate(w, “1″);

比如我们有两篇文档,内容分别是

A - “I love programming”

B - “I am a blogger, you are also a blogger”。

B文档经过Map运算后输出的中间文件将会是:

	I,1
	am,1
	a,1
	blogger,1
	you,1
	are,1
	a,1
	blogger,1

Reduce操作的输入是单词和出现次数的序列。用上面的例子来说,就是 (”I”, [1, 1]), (”love”, [1]), (”programming”, [1]), (”am”, [1]), (”a”, [1,1]) 等。然后根据每个单词,算出总的出现次数。

reduce(String key, Iterator values):
    // key: a word
    // values: a list of counts
    int result = 0;
    for each v in values:
        result += ParseInt(v);
    Emit(AsString(result));

最后输出的最终结果就会是:(”I”, 2″), (”a”, 2″)……

实际的执行顺序是:

  1. MapReduce Library将Input分成M份。这里的Input Splitter也可以是多台机器并行Split。
  2. Master将M份Job分给Idle状态的M个worker来处理;
  3. 对于输入中的每一个<key, value> pair 进行Map操作,将中间结果Buffer在Memory里;
  4. 定期的(或者根据内存状态),将Buffer中的中间信息Dump到本地磁盘上,并且把文件信息传回给Master(Master需要 把这些信息发送给Reduce worker)。这里最重要的一点是,在写磁盘的时候,需要将中间文件做Partition(比如R个)。拿上面的例子来举例,如果把所有的信息存到一个 文件,Reduce worker又会变成瓶颈。我们只需要保证相同Key能出现在同一个Partition里面就可以把这个问题分解。
  5. R个Reduce worker开始工作,从不同的Map worker的Partition那里拿到数据(read the buffered data from the local disks of the map workers), 用key进行排序(如果内存中放不下需要用到外部排序 – external sort)。很显然,排序(或者说Group)是Reduce函数之前必须做的一步。 这里面很关键的是,每个Reduce worker会去从很多Map worker那里拿到X(0<X<R) Partition的中间结果,这样,所有属于这个Key的信息已经都在这个worker上了。
  6. Reduce worker遍历中间数据,对每一个唯一Key,执行Reduce函数(参数是这个key以及相对应的一系列Value)。
  7. 执行完毕后,唤醒用户程序,返回结果(最后应该有R份Output,每个Reduce Worker一个)。

可见,这里的分(Divide)体现在两步,分别是将输入分成M份,以及将Map的中间结果分成R份。将输入分开通常很简单,Map的中间结果通常 用”hash(key) mod R”这个结果作为标准,保证相同的Key出现在同一个Partition里面。当然,使用者也可以指定自己的Partition Function,比如,对于Url Key,如果希望同一个Host的URL出现在同一个Partition,可以用”hash(Hostname(urlkey)) mod R”作为Partition Function。

对于上面的例子来说,每个文档中都可能会出现成千上万的 (”the”, 1)这样的中间结果,琐碎的中间文件必然导致传输上的损失。因此,MapReduce还支持用户提供Combiner Function。这个函数通常与Reduce Function有相同的实现,不同点在于Reduce函数的输出是最终结果,而Combiner函数的输出是Reduce函数的某一个输入的中间文件。

Tom White给出了Nutch[2]中另一个很直观的例子,分布式Grep。我一直觉得,Pipe中的很多操作,比如More、Grep、Cat都类似于一种Map操作,而Sort、Uniq、wc等都相当于某种Reduce操作。

加上前两天Google刚刚发布的BigTable论文,现在Google有了自己的集群 – Googel Cluster,分布式文件系统 – GFS,分布式计算环境 – MapReduce,分布式结构化存储 – BigTable,再加上Lock Service。我真的能感觉的到Google著名的免费晚餐之外的对于程序员的另一种免费的晚餐,那个由大量的commodity PC组成的large clusters。我觉得这些才真正是Google的核心价值所在。

呵呵,就像微软老兵Joel Spolsky(你应该看过他的”Joel on Software”吧?)曾经说过,对于微软来说最可怕的是[1],微软还在苦苦追赶Google来完善Search功能的时候,Google已经在部署下一代的超级计算机了。

The very fact that Google invented MapReduce, and Microsoft didn’t, says something about why Microsoft is still playing catch up trying to get basic search features to work, while Google has moved on to the next problem: building Skynet^H^H^H^H^H^H the world’s largest massively parallel supercomputer. I don’t think Microsoft completely understands just how far behind they are on that wave.

注1:其实,微软也有自己的方案 – DryAd。问题是,大公司里,要想重新部署这样一个底层的InfraStructure,无论是技术的原因,还是政治的原因,将是如何的难。

注2:Lucene之父Doug Cutting的又一力作,Project Hadoop - 由Hadoop分布式文件系统和一个Map/Reduce的实现组成,Lucene/Nutch的成产线也够齐全的了。

Nginx负载均衡

Posted by 冰河 at 20:33 No Responses » 6,259 Views
十二 182009

nginx是什么?

Nginx (“engine x”) 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor将源代码以类BSD许可证的形式发布。尽管还是测试版,但是,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。

首先是配置十分的简单,而且功能非常强大。真是相见恨晚。
先来看看配置文件怎么写吧

worker_processes 1;
events {
worker_connections 1024;
}
http{
upstream myproject {
#这里指定多个源服务器,ip:端口,80端口的话可写可不写
server 192.168.43.158:80;
server 192.168.41.167;
}

server {
listen 8080;
location / {
proxy_pass http://myproject;
}
}
}

nginx的负载均衡有哪些功能呢?
[list]
[*]如果后面的服务器其中一台坏了,它能自动识别,更牛的是它好了之后nginx可以马上识别
[*]服务器A和B,如果A的响应时间为3,B的响应时间为1,那么nginx会自动调整访问B的概率是A的3倍,真正做到负载均衡
[/list]

在这里还是想说说nginx的安装及运行
先到http://www.nginx.net/下载最新的源码包。
我下载到的是nginx-0.5.33.tar.gz
解压:tar zxvf nginx-0.5.33.tar.gz
接着:./configure
再接着:make
最后:make install
好的,安装完成了。我在make的时候报了个错,说HTTP Rewrite 模块 有问题,我就./configure –without-http_rewrite_module
然后再make,make install就可以了。
安装好了之后新建一个配置文件,把上面的配置文件内容拷进去,当然要修改你的IP,保存为比如 load_balance.conf

然后启动:
/usr/local/nginx/sbin/nginx -c load_balence.conf

如果上面的步骤走下来有问题的话,可以参考:
nginx的中文维基

http://wiki.codemongers.com/NginxChs

当然也可以到官方网站
www.nginx.net
www.nginx.com

由于nginx的作者是俄国人,所以英文的文档也不是那么完善,对于我来说nginx的最大优点还是配置简单,功能强大
apache-jk配起来太复杂了,而且只能用来做tomcat的负载均衡。
nginx就没有这个限制,对它来说后面是什么服务器是完全透名的。

十二 182009

Log4jApache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

commons-logging组件与log4j组件的使用,已成为当今非常流行的日志记录方法,在许多开源软件设计中,都会看到它们的身影;它们的组合使用,不仅简化了的log4j使用,而且还实现了日志工具的灵活配置,以下介绍其使用方法:

一.commons-logging.properties的配置
#LogFactory implement
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
# SimpleLog
#org.apache.commons.logging.Log = org.apache.commons.logging.impl.SimpleLog
# JDK 1.4 logger
#org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
# Avalon Toolkit
#org.apache.commons.logging.Log=org.apache.commons.logging.impl.LogKitLogger
#Log4j
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

二.log4j.properties的配置
#rootLogger
log4j.rootLogger = DEBUG,stdout, R
#自定义输出目的地stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#定义输出目的格式
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#定义具体的输出样式
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}-[TEST] %p [%t] %C.%M(%L)-%m%n
#自定义输出目的地R
log4j.appender.R=org.apache.log4j.FileAppender
log4j.appender.R.file=D:\app\personalProject\classes\hailin.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}-[TEST] %p [%t] %C.%M(%L)-%m%n
#定义具体的类日志属性
log4j.logger.com.tongda.whl.log=INFO

配置说明:(转自他处,与上面的log4j.properties不一致

1 log4j.rootCategory=INFO, stdout , R

此句为将等级为INFO的日志信息输出到stdoutR这两个目的地,stdoutR的定义在下面的代码,可以任意起名。等级可分为OFF FATALERRORWARNINFODEBUGALL,如果配置OFF则不打出任何信息,如果配置为INFO这样只显示INFO, WARN, ERRORlog信息,而DEBUG信息不会被显示,具体讲解可参照第三部分定义配置文件中的logger

3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender

此句为定义名为stdout的输出端是哪种类型,可以是

org.apache.log4j.ConsoleAppender(控制台),

org.apache.log4j.FileAppender(文件),

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

具体讲解可参照第三部分定义配置文件中的Appender

4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

此句为定义名为stdout的输出端的layout是哪种类型,可以是

org.apache.log4j.HTMLLayout(以HTML表格形式布局),

org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

具体讲解可参照第三部分定义配置文件中的Layout

5 log4j.appender.stdout.layout.ConversionPattern= [QC] %p [%t] %C.%M(%L) | %m%n

如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:

%m 输出代码中指定的消息

%p 输出优先级,即DEBUGINFOWARNERRORFATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目,通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n

%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:20021018 221028921

%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

[QC]log信息的开头,可以为任意字符,一般为项目简称。

输出的信息

[TS] DEBUG [main] AbstractBeanFactory.getBean(189) | Returning cached instance of singleton bean ‘MyAutoProxy’

具体讲解可参照第三部分定义配置文件中的格式化日志信息。

7 log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

此句与第3行一样。定义名为R的输出端的类型为每天产生一个日志文件。

8 log4j.appender.R.File=D:Tomcat 5.5logsqc.log

此句为定义名为R的输出端的文件名为D:Tomcat 5.5logsqc.log

可以自行修改。

9 log4j.appender.R.layout=org.apache.log4j.PatternLayout

与第4行相同。

10 log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c – %m%n

与第5行相同。文章整理:学网 http://www.xue5.com (本站) [1] [2] [3] [4]

12 log4j.logger.com. neusoft =DEBUG

指定com.neusoft包下的所有类的等级为DEBUG

可以把com.neusoft改为自己项目所用的包名。

13 log4j.logger.com.opensymphony.oscache=ERROR

14 log4j.logger.net.sf.navigator=ERROR

这两句是把这两个包下出现的错误的等级设为ERROR,如果项目中没有配置EHCache,则不需要这两句。

15 log4j.logger.org.apache.commons=ERROR

16 log4j.logger.org.apache.struts=WARN

这两句是struts的包。

17 log4j.logger.org.displaytag=ERROR

这句是displaytag的包。(QC问题列表页面所用)

18 log4j.logger.org.springframework=DEBUG

此句为Spring的包。

24 log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN

25 log4j.logger.org.hibernate=DEBUG

此两句是hibernate的包。

以上这些包的设置可根据项目的实际情况而自行定制。

三.把commons-logging.properties,log4j.properties放在classpath下
commons-logging.properties可以不需要(参照commons-logging组件的使用说明),系统会有一个自动的寻找过 程,log4j.properties必须作配置(参照log4j组件的使用说明),至少配置一个根日志(rootLogger)的级别及其输出地,如果 不做配置会报错。如果具体的类不作配置日志属性,会默认继承根日志的
属性;如果需具体配置,则如下所示:
log4j.logger.com.IR=INFO,定义了IR包的日志属性

四.程序使用
package IR;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LogTest {
private static Log log=LogFactory.getLog(LogTest.class);
public static void main(String [] args){
// System.out.println(log.getClass());//测试调用的是哪个日志工具
// System.out.println(LogTest.class);//测试类的路径
log.info(“This is info!”);
log.debug(“This is debug !”);
}
}

十二 182009

这或许是众多OIer最大的误区之一。

你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题并不是那种“只有搜才行”的问题,NPC问题才是。好,行了,基本上这个误解已经被澄清了。下面的内容都是在讲什么是P问题,什么是NP问题,什么是NPC问题,你如果不是很感兴趣就可以不看了。接下来你可以看到,把NP问题当成是 NPC问题是一个多大的错误。

还是先用几句话简单说明一下时间复杂度。时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快。也 就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而应该看当这个数据的规模变大到数百倍后,程序运行时间是否还 是一样,或者也跟着慢了数百倍,或者变慢了数万倍。不管数据有多大,程序处理花的时间始终是那么多的,我们就说这个程序很好,具有O(1)的时间复杂度,也称常数级复杂度;数据规模变得有多大,花的时间也跟着变得有多长,这个程序的时间复杂度就是O(n),比如找n个数中的最大值;而像冒泡排序、插入排序等,数据扩大2倍,时间变慢4倍的,属于O(n^2)的复杂度。还有一些穷举类的算法,所需时间长度成几何阶数上涨,这就是O(a^n)的指数级复杂度,甚至O(n!)的阶乘级复杂度。不会存在O(2*n^2)的复杂度,因为前面的那个“2”是系数,根本不会影响到整个程序的时间增长。同样地,O (n^3+n^2)的复杂度也就是O(n^3)的复杂度。因此,我们会说,一个O(0.01*n^3)的程序的效率比O(100*n^2)的效率低,尽管在n很小的时候,前者优于后者,但后者时间随数据规模增长得慢,最终O(n^3)的复杂度将远远超过O(n^2)。我们也说,O(n^100)的复杂度小于O(1.01^n)的复杂度。

容易看出,前面的几类复杂度被分为两种级别,其中后者的复杂度无论如何都远远大于前者:一种是O(1),O(log(n)),O(n^a)等,我们把它叫做多项式级的复杂度,因为它的规模n出现在底数的位置;另一种是O(a^n)O(n!)型复杂度,它是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。

自然地,人们会想到一个问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?很遗憾,答案是否定的。有些问题甚至根本不可能找到一个正确的算法来,这称之为“不可解问题”(Undecidable Decision Problem)。比如,输出从1nn个数的全排列。不管你用什么方法,你的复杂度都是阶乘级,因为你总得用阶乘级的时间打印出结果来。有人说,这样的“问题”不是一个“正规”的问题,正规的问题是让程序解决一个问题,输出一个“YES”或“NO”(这被称为判定性问题),或者一个什么什么的最优值(这被称为最优化问题)。那么,根据这个定义,我也能举出一个不大可能会有多项式级算法的问题来:Hamilton回路。问题是这样的:给你一个图,问你能否找到一条经过每个顶点一次且恰好一次(不遗漏也不重复)最后又走回来的路(满足这个条件的路径叫做Hamilton回路)。这个问题现在还没有找到多项式级的算法。事实上,这个问题就是我们后面要说的NPC问题。

下面引入P类问题的概念:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。P是英文单词多项式的第一个字母。哪些问题是P类问题呢?通常NOINOIP不会出不属于P类问题的题目。我们常见到的一些信息奥赛的题目都是P问题。道理很简单,一个用穷举换来的非多项式级时间的超时程序不会涵盖任何有价值的算法。

接下来引入NP问题的概念。这个就有点难理解了,或者说容易理解错误。在这里强调(回到我竭力想澄清的误区上),NP问题不是非P类问题。NP问题是指可以在多项式的时间里验证一个解的问题。NP问题的另一个定义是,可以在多项式的时间里猜出一个解的问题。比方说,我RP很好,在程序中需要枚举时,我可以一猜一个准。现在某人拿到了一个求最短路径的问题,问从起点到终点是否有一条小于100个单位长度的路线。它根据数据画好了图,但怎么也算不出来,于是来问我:你看怎么选条路走得最少?我说,我RP很好,肯定能随便给你指条很短的路出来。然后我就胡乱画了几条线,说就这条吧。那人按我指的这条把权值加起来一看,嘿,神了,路径长度98,比100小。于是答案出来了,存在比100小的路径。别人会问他这题怎么做出来的,他就可以说,因为我找到了一个比100 小的解。在这个题中,找一个解很困难,但验证一个解很容易。验证一个解只需要O(n)的时间复杂度,也就是说我可以花O(n)的时间把我猜的路径的长度加出来。那么,只要我RP好,猜得准,我一定能在多项式的时间里解决这个问题。我猜到的方案总是最优的,不满足题意的方案也不会来骗我去选它。这就是NP问题。当然有不是NP问题的问题,即你猜到了解但是没用,因为你不能在多项式的时间里去验证它。下面我要举的例子是一个经典的例子,它指出了一个目前还没有办法在多项式的时间里验证一个解的问题。很显然,前面所说的Hamilton回路是NP问题,因为验证一条路是否恰好经过了每一个顶点非常容易。但我要把问题换成这样:试问一个图中是否不存在Hamilton回路。这样问题就没法在多项式的时间里进行验证了,因为除非你试过所有的路,否则你不敢断定它“没有Hamilton回路”。

之所以要定义NP问题,是因为通常只有NP问题才可能找到多项式的算法。我们不会指望一个连多项式地验证一个解都不行的问题存在一个解决它的多项式级的算法。相信读者很快明白,信息学中的号称最困难的问题——“NP问题”,实际上是在探讨NP问题与P类问题的关系。

很显然,所有的P类问题都是NP问题。也就是说,能多项式地解决一个问题,必然能多项式地验证一个问题的解——既然正解都出来了,验证任意给定的解也只需要比较一下就可以了。关键是,人们想知道,是否所有的NP问题都是P类问题。我们可以再用集合的观点来说明。如果把所有P类问题归为一个集合P中,把所有 NP问题划进另一个集合NP中,那么,显然有P属于NP。现在,所有对NP问题的研究都集中在一个问题上,即究竟是否有P=NP?通常所谓的“NP问题”,其实就一句话:证明或推翻P=NP

NP问题一直都是信息学的巅峰。巅峰,意即很引人注目但难以解决。在信息学研究中,这是一个耗费了很多时间和精力也没有解决的终极问题,好比物理学中的大统一和数学中的歌德巴赫猜想等。

目前为止这个问题还“啃不动”。但是,一个总的趋势、一个大方向是有的。人们普遍认为,P=NP不成立,也就是说,多数人相信,存在至少一个不可能有多项式级复杂度的算法的NP问题。人们如此坚信PNP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-完全问题,也即所谓的 NPC问题。C是英文单词“完全”的第一个字母。正是NPC问题的存在,使人们相信PNP。下文将花大量篇幅介绍NPC问题,你从中可以体会到NPC问题使P=NP变得多么不可思议。

为了说明NPC问题,我们先引入一个概念——约化(Reducibility,有的资料上叫“归约”)

简单地说,一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A,或者说,问题A可以“变成”问题B。 《算法导论》上举了这么一个例子。比如说,现在有两个问题:求解一个一元一次方程和求解一个一元二次方程。那么我们说,前者可以约化为后者,意即知道如何 解一个一元二次方程那么一定能解出一元一次方程。我们可以写出两个程序分别对应两个问题,那么我们能找到一个“规则”,按照这个规则把解一元一次方程程序 的输入数据变一下,用在解一元二次方程的程序上,两个程序总能得到一样的结果。这个规则即是:两个方程的对应项系数不变,一元二次方程的二次项系数为0。按照这个规则把前一个问题转换成后一个问题,两个问题就等价了。同样地,我们可以说,Hamilton回路可以约化为TSP问题(Travelling Salesman Problem,旅行商问题):在Hamilton回路问题中,两点相连即这两点距离为0,两点不直接相连则令其距离为1,于是问题转化为在TSP问题中,是否存在一条长为0的路径。Hamilton回路存在当且仅当TSP问题中存在长为0的回路。

“问题A可约化为问题B”有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说,问题A不比问题B难。这很容易理解。既然问题A能用问题B来解决,倘若B的时间复杂度比A的时间复杂度还低了,那A的算法就可以改进为B的算法,两者的时间复杂度还是相同。正如解一元二次方程比解一元一次方程难,因为解决前者的方法可以用来解决后者。

很显然,约化具有一项重要的性质:约化具有传递性。如果问题A可约化为问题B,问题B可约化为问题C,则问题A一定可约化为问题C。这个道理非常简单,就不必阐述了。

现在再来说一下约化的标准概念就不难理解了:如果能找到这样一个变化法则,对任意一个程序A的输入,都能按这个法则变换成程序B的输入,使两程序的输出相同,那么我们说,问题A可约化为问题B

当然,我们所说的“可约化”是指的可“多项式地”约化(Polynomial-time Reducible),即变换输入的方法是能在多项式的时间里完成的。约化的过程只有用多项式的时间完成才有意义。

好了,从约化的定义中我们看到,一个问题约化为另一个问题,时间复杂度增加了,问题的应用范围也增大了。通过对某些问题的不断约化,我们能够不断寻找复杂度更高,但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法。再回想前面讲的PNP问题,联想起约化的传递性,自然地,我们会想问,如果不断地约化上去,不断找到能“通吃”若干小NP问题的一个稍复杂的大NP问题,那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的 NP问题的这样一个超级NP问题?答案居然是肯定的。也就是说,存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。这种问题的存在难以置信,并且更加不可思议的是,这种问题不只一个,它有很多个,它是一类问题。这一类问题就是传说中的NPC 问题,也就是NP-完全问题。NPC问题的出现使整个NP问题的研究得到了飞跃式的发展。我们有理由相信,NPC问题是最复杂的问题。再次回到全文开头,我们可以看到,人们想表达一个问题不存在多项式的高效算法时应该说它“属于NPC问题”。此时,我的目的终于达到了,我已经把NP问题和NPC问题区别开了。到此为止,本文已经写了近5000字了,我佩服你还能看到这里来,同时也佩服一下自己能写到这里来。

NPC问题的定义非常简单。同时满足下面两个条件的问题就是NPC问题。首先,它得是一个NP问题;然后,所有的NP问题都可以约化到它。证明一个问题是 NPC问题也很简单。先证明它至少是一个NP问题,再证明其中一个已知的NPC问题能约化到它(由约化的传递性,则NPC问题定义的第二条也得以满足;至于第一个NPC问题是怎么来的,下文将介绍),这样就可以说它是NPC问题了。

既然所有的NP问题都能约化成NPC问题,那么只要任意一个NPC问题找到了一个多项式的算法,那么所有的NP问题都能用这个算法解决了,NP也就等于P 了。因此,给NPC找一个多项式算法太不可思议了。因此,前文才说,“正是NPC问题的存在,使人们相信PNP”。我们可以就此直观地理解,NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。

顺便讲一下NP-Hard问题。NP-Hard问题是这样一种问题,它满足NPC问题定义的第二条但不一定要满足第一条(就是说,NP-Hard问题要比 NPC问题的范围广)。NP-Hard问题同样难以找到多项式的算法,但它不列入我们的研究范围,因为它不一定是NP问题。即使NPC问题发现了多项式级的算法,NP-Hard问题有可能仍然无法得到多项式级的算法。事实上,由于NP-Hard放宽了限定条件,它将有可能比所有的NPC问题的时间复杂度更高从而更难以解决。

不要以为NPC问题是一纸空谈。NPC问题是存在的。确实有这么一个非常具体的问题属于NPC问题。下文即将介绍它。

下文即将介绍逻辑电路问题。这是第一个NPC问题。其它的NPC问题都是由这个问题约化而来的。因此,逻辑电路问题是NPC类问题的“鼻祖”。

逻辑电路问题是指的这样一个问题:给定一个逻辑电路,问是否存在一种输入使输出为True

什么叫做逻辑电路呢?一个逻辑电路由若干个输入,一个输出,若干“逻辑门”和密密麻麻的线组成。看下面一例,不需要解释你马上就明白了。

┌───┐

输入1├─→┐ ┌──┐

└───┘ └─→┤

or ├→─┐

┌───┐ ┌─→┤ ┌──┐

输入2├─→┤ └──┘ └─→┤

└───┘ ┌─→┤AND ├──→输出

└────────┘┌→┤

┌───┐ ┌──┐ └──┘

输入3├─→┤ NOT├─→────┘

└───┘ └──┘

这是个较简单的逻辑电路,当输入1、输入2、输入3分别为TrueTrueFalseFalseTrueFalse时,输出为True

有输出无论如何都不可能为True的逻辑电路吗?有。下面就是一个简单的例子。

┌───┐

│输入1 ├→─┐ ┌──┐

└───┘ └─→┤

AND ├─→┐

┌─→┤

└──┘ ┌──┐

└→┤

┌───┐ AND ├─→输出

│输入2 ├→─┤ ┌──┐ ┌→┤

└───┘ └→┤NOT ├→──┘ └──┘

└──┘

上面这个逻辑电路中,无论输入是什么,输出都是False。我们就说,这个逻辑电路不存在使输出为True的一组输入。

回到上文,给定一个逻辑电路,问是否存在一种输入使输出为True,这即逻辑电路问题。

逻辑电路问题属于NPC问题。这是有严格证明的。它显然属于NP问题,并且可以直接证明所有的NP问题都可以约化到它(不要以为NP问题有无穷多个将给证明造成不可逾越的困难)。证明过程相当复杂,其大概意思是说任意一个NP问题的输入和输出都可以转换成逻辑电路的输入和输出(想想计算机内部也不过是一些 01的运算),因此对于一个NP问题来说,问题转化为了求出满足结果为True的一个输入(即一个可行解)。

有了第一个NPC问题后,一大堆NPC问题就出现了,因为再证明一个新的NPC问题只需要将一个已知的NPC问题约化到它就行了。后来,Hamilton 回路成了NPC问题,TSP问题也成了NPC问题。现在被证明是NPC问题的有很多,任何一个找到了多项式算法的话所有的NP问题都可以完美解决了。因此说,正是因为NPC问题的存在,P=NP变得难以置信。P=NP问题还有许多有趣的东西,有待大家自己进一步的挖掘。攀登这个信息学的巅峰是我们这一代的终极目标。现在我们需要做的,至少是不要把概念弄混淆了。

怎样写好论文

Posted by 冰河 at 20:22 No Responses » 5,501 Views
十二 182009

一、科技论文的内容

中学时就学过,文章的体裁最主要的有记叙文和议论文两种。记叙文说的是某一事件发生的背景、过程及影响,也可以加点作者的感想。议论文要说的是对某些问题的 论点和为证明论点的正确性而做的求证工作,即提供论据,进行推理,最后得出结论。因此,这两种体裁是很不相同的。还有一种接近议论文但严格说来不算议论文 的体裁是只对某些问题或现象发表自己的看法或观感,虽有观点但并不刻意去证明观点的正确性,这种文章属于散文中的随笔,本文即属于这种文章。

科技论文应该是议论文,至少应该有观点。通俗地说,科技论文要解决的主要问题不是“是什么”,而是“怎样做” 和“为什么”,对于“怎样做”的文章,最好要有“为什么要这样做”的内容。

有的作者很容易把议论文写成记叙文,特别是在做了某个项目的研究后的总结性文章,只说自己是怎样做的,很少去说为什么要这样做。原因可能是这样写很顺,因为 工作是他(们)做的,过程很清楚,用不着费劲就可以说明白。这样的文章深度不够。近年来软件受到大家重视,但软件类的文章大多属于这种情况。加之软件的头 绪一般很多,要说明白了,不分粗细,面面俱到,篇幅不短,很有点雾里看花的味道。

科技论文不是工作总结,也不是说明书。

论文内容的正确性当然是非常重要的。不过,不同领域的出错情况很不相同,很难概括。然而,有五点是应该注意的:

⑴ 要有创新,至少要有新意。是否有创新,是很多刊物考虑录用的最主要出发点,特别像《中国科学》这样的权威性刊物,没有创新就不可能录用。可以说,创新有原 始创新和集成创新两种。工学类论文中,原始创新比较少,大多是提出一些新方法、新算法,或是以别人没有用过的方法对一个问题进行分析,属于集成创新。虽然 这也是可取的,但论文必须雄辩地说明采用采用新方法所取得的结果。有一篇论文写基于Hermit样条的彩色图象道路提取方法,方法本身并没有错,但有两个结论有问题。一是说用Hermit样条对提取的间断的道路标志线拟合后可以得到连续的标志线,实际上,一般的三次样条或多项式拟合也能解决这个问题;二是说Hermit样条更适于表达图象上的弯曲的道路标志线,但是没有数据表明为什么其它的拟合曲线就不适合。这样一来,虽然别人在道路提取中没有用过Hermit样条,这篇论文的新意也就荡然无存了。

⑵ 论文的写法一定要突出重点。有篇文章谈及机器人的灵巧手,这个项目本身做得不错,但这篇文章把灵巧手的结构、手指驱动、抓握控制面面俱到地说了一遍,每一 部分都说得不透彻,没有深度。如果这篇文章能集中论述尺寸受限制的灵巧手的驱动,就要好得多。还有一篇谈遥在技术的文章,先泛泛地讲了微型摄像头的结构, 再从一些书上摘录了人所共知的模糊控制的基本概念,二者之间又没有有机联系,这样的文章根本没有内容。如果集中论述在视觉系统微小型化中所解决的问题,恐 怕还能写出点东西。

⑶ 论文的内容要真实、正确。这一点是很重要的,不弄虚作假是良好的科学道德。如果让人看出虚假的东西,这篇文章就肯定不能用。有一篇写控制算法的文章,对算法做了仿真。仿真时用的关节角函数是q=0.1sin(3πt),周期显然是(2/3)s,而做出的仿真曲线的周期却是2.8s,角速度的最大值也小得多,这样的结果至少使人怀疑作者并没有真正做了仿真。

⑷ 关于综述性文章。综述性文章的内容主要是前人对某一专题做过哪些研究、哪些问题已经解决、哪些问题还需要继续研究,最重要的是要指出对这一专题继续研究的 方向。从这个意义上来说,写综述性文章实际上是比较难的,需要占有大量资料,而且,对资料要分析,去粗存精,去伪存真,高屋建瓴。千万不要看了几篇发表过 的论文 就写综述。

⑸ 关于论文中的公式。科技论文一般少不了公式。公式推导的正确固然很重要,但也并非一定要把一步一步的推导过程写清楚。有的文章虽然写出了公式,但是,不注 意对公式中所用符号的说明,不注意说明公式的适用条件,这样的公式是没什么用的。有一篇文章论述以三条人工肌肉作为作动器的并联机构,作者试图建立它的数 学模型,前面写出了人工肌肉输入气压与肌肉长度的关系式,又列出力平衡方程,然后就说把前一式与后一式相结合,得到一个非线性的状态方程,把它作为数学模 型。方程中有很多系数,显然是与机构及肌肉参数有关的,作者恰恰没有写出系数与参数的关系,这就使人怀疑这个模型是不是推导出来的。即使是,这样的模型只 是通式,没有用处。

二、论文的标题

论文的标题有画龙点睛的作用。标题应该与文章的内容非常贴切。这一点往往不被注意。有的标题过大;有的又过于局限。有一篇文章的标题是“服务机器人仿人手臂 运动学研究”,内容是作者在研制一种服务机器人时对一种七自由度手臂运动学所做的分析。“仿人”并不重要,重要的是作者提出了这种冗余自由度手臂逆运动学 的一种解法,这样的解法并不只能用于服务机器人。如果把标题改为“七自由度仿人手臂逆运动学的一种解法”,则既有学术意义,又兼顾了作者的研究项目。还有 一篇论文的题目是“登月机器人关节润滑技术的研究”,内容是一种固体润滑膜的制备和特性。论文的题目太大,而且,如果题目中就明确提出登月机器人,就需要 有在模拟月球超低真空、超低温、强粉尘环境中的实验,目前尚无条件。如果将题目改为“MoS2基固体润滑膜制备方法及特性的研究”,既缩小了范围,又避开了尚不能进行的实验。还有些论文题目本身就有问题,例如,有一篇博士学位论文题目是“仿人机器人的动态行走控制”,行走有静态的吗?肯定没有,连原地踏步都是动态的。这样的标题岂不让人笑话?

三、摘要

摘要是对文章内容的概括。摘要应写得简练,只需说明写论文的目的、所用的方法及取得的结果即可。写得不好的摘要中常常有一些没用的话。例如,“随着机器人技术的发展,应用领域更加广阔,某问题成为研究的热点”,之类的话就没有用。

四、引言

论文引言的作用是开宗明义提出本文要解决的问题。引言应开门见山、简明扼要。有的写机器人的文章,一开始写捷克一作家写的戏剧中一个机器奴隶叫Robota,美国1950年制造了第一台工业机器人,这就绕了太大的圈子,有点“言必称希腊”。

很多论文在引言中简要叙述前人在这方面所做过的工作,这是必要的。特别是那些对前人的方法提出改进的文章更有必要。应该注意的是,对前人工作的概括不要断章 取义,如果有意歪曲别人的意思而突出自己方法的优点就更不可取了。在一篇论文中,对前人工作的概括应尽可能放在引言中。在正文中,如非很必要,就不要再有 这类段落了。

文献的引述要正确。你的文章里引用了某些文献,别人的文章也可能引用你的文章。如果引用时不注意正确性,就可能以讹传讹。有一篇谈遥操作的文章引用了美国《自然》杂志的文章,提到在相距7000km的两地进行遥操作,从操作端发出操作命令到执行端反馈回信息只用了150μs。这是完全不可能的。即使电波直线传播,至少也需要46.67ms。后来查明是作者引用时单位写错了。如果文章发表了,以《自然》杂志的权威性及这篇文章作者的影响力,这个错误的数据肯定还会接着被引用。

一些论文也开始引用互联网上的文献和消息。网上文献的可信度要好一些;由于各种各样的原因,消息的可靠性不高。我们曾用装甲车为某试验基地研制了一台遥控靶 车,在《兵器知识》上曾有过报道。由于某些内容不便公开,对文章做了一些技术处理。这个消息到了网上却变成了“我国研制成功遥控装甲车”,“蚂蚁”成了“ 大象”。所以,如果要引用网上的消息,一定要通过其它渠道对消息进行核实。

不少论文在引言中还说明了文章的结构,虽然话不多,但并非很必要。对于学位论文,因篇幅大,在绪论中交代一下整个论文的结构是应该的。在刊物上发表的文章就没有这个必要。

五、实验验证

论文中的实验的目的是验证论文提出的理论或方法的正确性、可行性和有效性。有一个阶段我不太同意把仿真叫做实验,但随着仿真技术的进步,至少它可以成为一种验证的手段。

理论的正确性并非总是要用实验来验证的。那些用公认的定理证明的新定理就不需要验证。

方法可行性的验证相对简单一些,实验只要说明所用的方法解决了问题即可。

方法(特别是算法)有效性的验证在很多论文里做得不好。所谓有效性,应该是比别的方法更快或更简单地解决了问题,或是计算复杂性低,或是计算速度更高,或是占用的内存小。要说明有效性,一是要有比较,不能“老王卖瓜”;二是要有相应的数据。

从这个意义上来说,论文中的实验往往是一种为说明问题而专门设计的实验。实验的设计是非常重要的。要说明某一因素的作用,就要设法将它孤立起来。

我 曾连续审了四篇关于构建机器人仿真球队的论文。这四篇论文除了叙述性的内容偏多以外,写得还是不错的。文章的内容涉及个人技巧、决策机制及整体协调,并不 重复。而且,球队两次参加了机器人足球世界杯仿真组的比赛,都取得亚军的好成绩。这就是说,在构建球队时代所采取的技术措施还是有成效的。但是,这四篇文 章都用参赛对阵的得分来说明技术措施的有效性,这是不合适的。因为,足球赛的成绩只是一种排名,只说明参赛队实力的相对强弱。如果对手的实力太低,即使己 方取得冠军,也不能有效地说明自己所采取的措施是正确的。而且,如前所 述,一个队能否取得胜利与个人技巧、决策能力、整体协调等多种因素有关,取得较好成绩倒底是哪个因素起了作用往往是说不清楚的。作者在最近的两篇文章中用 了相同的比赛结果来说明不相同的技术措施的作用,显然也是没有说服力的。如果对同一对手以采取论文中的措施和不采用这种措施进行两次比赛,则比赛的结果就 能较好地说明这种措施的作用。

有不少论文由于各种原因不能用严格的理论证明方法的正确性和有效性,也暂时做不了实验,于是就用仿真的方法来说明。这时应注意的是,尽管文章中只能给出个别 的仿真实例,但做仿真时应该尽可能对各种可能发生的情况多做一些实例,因为,用一、两个实例的仿真结果说明的结论很可能被另一个实例推翻。有一篇论文要在 相互距离已知的几个点中寻找一条最短的遍历路径,论文的篇幅很长,所用的方法兜了不少圈子,方法倒也对,但没有证明。最后用了一个实例做仿真。我在审稿时 写了一个更简单的方法,与论文方法所得的结果一致。这样一来,这篇文章所提出的方法虽然不错,但一点意义也没有了。

六、结论

结论中出现的问题不太多,不过精彩的结论也不多。由于Word等 文字处理软件提供的“复制”、“粘贴”的方便,论文正文、引言、摘要中的一些话也就被拷贝到结论中,还没看到结论就知道结论说什么,这样的结论已经没味 了。不过偶尔也碰到“过火”的,正文中根本未涉及的问题在结论中突然冒了出来。比较罕见的情况是,有的论文的结论把文章中的论述部分或全部推翻了。

七、文字

以前用笔写字的时候,常听人说“字是人的脸面”,意思是说,一手好字会为你增添光彩,看着也舒服。现在,论文上的字都是打印机打出的印刷体,文章是不是通顺 就很突出了,也就成为“人的脸面”了。俗话说“文如其人”,如果一篇文章的文字方面的问题太多,?不顺口,作者给人的印象也不会好。

送审稿中,比较突出的文字、标点方面的问题有;

⑴ 天一句,地一句,想到哪里,说到哪里,语气、语意不连贯。

⑵ 语意重复,用词罗嗦,不善运用代词。

⑶ “而”、“故”、“然”、“其”之类的虚构词用得别扭。

⑷ 技术术语使用不当或生造术语,这是在论文中最不应出现的文字问题。如果某一领域的名词术语已经有了国家标准,虽然这类标准一般是推荐性标准,但也应首先使 用标准核定的术语,为的是与别人有“共同语言”。在论文中不应使用俗名,即使这样的名词已被较多的人使用。术语是有内涵的,在制定术语标准时,对收纳的每 条术语都有严格的定义。如果在论文中不得不创造一条新的术语,对它的内涵一定要说清楚,要有严格的定义。我对一篇论文中的“轨迹跟踪控制”提出过质疑。表 面看来“跟踪控制”还说得过去,细想想,能与“控制” 相连的无非是两类词,一是对象,如“温度控制”、“压力控制、“位置控制”、“力控制”等等;另一是方法,如“PID控 制”、“自适应控制”、“模糊控制”等等。“轨迹跟踪控制”是什么?“轨迹跟踪”既不是控制对象,也不是控制方法。实际轨迹对期望轨迹的跟踪正是对运动轨 迹进行控制的效果。所以,“轨迹跟踪”和“轨迹控制”都是可用的术语,而“轨迹跟踪控制”则站不住脚。还有,在学术性文章中不应使用“电脑”、“光碟”这 类商业化和港台化的名词。

⑸ 乱用标点符号。错得最多的是句号,或是长句不断,或是断句不当。最不容易用错的只有问号和感叹号。

⑹ 近年来有个很时髦也用得很滥的词“基于”。有时侯翻开一本杂志十有二、三的文章标题有“基于”二字。“基于X”的英文是“X-based”或“based on X”。应该说“基于”一词翻译得还是不错的。“基于规则的系统”比早年译的“规则基系统”、“以规则为基础的系统” 听起来要顺耳一些。问题是要把“基于”用得必要、得当。不是非用不可的地方,大可不必用它来追求文皱皱的味道。而且,既然是“在X的基础上”,X就应该是个可以被当做基础的实实在在的东西。一篇文章用了“基于任务级……”,这个“任务级”就不是实在的东西。还有一个用得不当的词就是“智能”,有些根本没有智能的东西也被带上了这个帽子。

其实,解决文字方面的问题并不难。作者在写完文章后只要?一、两遍,大部分文字问题都可以发现。不过,如果作者在口语表达上就有不规范的地方和固癖,这样做的收效不大。

八、英文稿的特殊问题

英语不是我们的母语,用英语写作论文当然就会出现一些问题。大多数人还不具有用英语思考的能力。在这种情况下,比较好的做法是先写中文稿再译成英语,这样至少能避免直接写英文稿时容易出现的语意不连贯的问题。

英文稿中最容易出现的用词问题是:

⑴ 按汉语硬译,形成所谓的“中式英语”。虽然不大会看到“good good study, day day up”这类“洋泾浜”,硬译的情况还是常见的。有一篇论文把“车载的”译为“tank-load,其实,单词“vehicular”的意思就是车载。

⑵ 介词的使用不当,用“of”、“to”较多,其它介词用得少。

⑶ 代词“this”、“that”用得多,“it”用得少,而后者恰恰在科技文章中用得多。

⑷ 句型单调,喜欢(或不得不)用“to be”构成句子。

⑸ 不注意动词的词性。有些动词既可是及物动词也可是不及物动词,应该优先用不及物动词成句,而不要用及物动词的被动语态成句。

⑹ 冠词“a”、“the”的使用不当,尤其容易忘记使用定冠词“the”。

⑺ 不注意名词的单、复数,不注意主、谓语的人称配合。

⑻ 论文中的用词应该比较正式,尽量少用一词多意的词,例如,口语中“get”有“获得”的意思,但论文中最好用“obtain”。

⑼ 中西文化的差异常常使英文稿带有“中国特色”。有一篇稿件的作者很谦虚,在文章的结尾分析了所提出的方法的缺点,说在今后的研究中会逐步克服这些缺点。外 国人就不会这么说,他们总是向前看,即使看到了缺点,也会说随着研究的深入,这种方法将会有更广阔的应用前景。有些文章的作者介绍中非要在“教授”后面加 个“博士导师”,外国人就相象不出不是博士导师的教授是什么样子。

九、论文的署名

毫无疑问,论文的第一作者应该是执笔者。这不仅体现了对他劳动的尊重,而且有对文章的责任。

不少文章是在读的研究生写的,导师的名字署在后面,这无可非议。但是,从有些文章可以明显看出,在投稿前导师并没有看过。甚至有的文章已经发表,导师还不知道。这种情况不好。导师即使在成文前参加过意见但成文后不看,这是导师没有负起责任;如果学生在导师不知情的情况下就署上导师的名字投稿,从好的方面理解 是对导师的尊重,从不好的方面理解则有“拉大旗作虎皮”之嫌。

近来论文署名还有人数增多的趋势,甚至一篇不长的文章署了五、六个人的名字。这种情况在某个项目的总结性文章中比较多见。诚然,项目参与者在研究过程中的主意是很难分清楚的,但是,论文不是工作总结,在写论文时不太可能集中很多人的想法。至于在署名时多写几个人送人情或者写上根本没有参加工作的领导的名字的 做法,更是不应提倡的风气。

十、如何面对审稿意见

一般来说,投送的稿件至少要经过一次技术性审查,英文稿还有一次文字性审查。这种审查通常是学报或杂志的编辑部聘请同领域的专家进行的。编辑部的责任是统一 论文的格式、审查文字、处理审稿意见。审稿人的责任是对论文的创新性和正确性进行审查,审稿意见一般应包括为提高稿件质量而应做的修改的建议。

作者对审稿人提出的审查意见首先应很重视,考虑他为什么要提出这些建议。审稿人的意见毕竟是来自一个旁观者的意见,俗话说“旁观者清”,他的意见总有一定道 理。有的作者觉得审稿人没有读懂自己的文章(我并不排除有这种可能性),对他的意见也就不认真考虑,这是不对的。审稿人是论文的第一读者,如果他都没有读 懂,作者也得考虑自己的文章有什么问题让人家不懂,否则发表后如何面对更多的读者?

当然,对审稿意见也要分析。虽然编辑部聘请的审稿人是同领域的专家,但是,隔行如隔山,领域很宽,审稿人可能并不熟悉文章作者所研究的某个具体专题,提出一些并不十分中肯的意见也不奇怪。所以,不一定要完全按照审稿人的意见去做。

审稿后,如果要对稿件做修改,一定要实事求是,不能应付审稿人。我给某学报审过一篇关于类刚毛表面减阻效应的论文,一审时我提出了一些问题要求改后再审,作 者的态度倒也是谦虚的,承认所提出的问题都有道理,作了一些修改。但是我提出的最关键的问题是对实验的疑问,作者就有点敷衍,将实验结果用与第一稿不同的 另一种曲线形式表现出来,而这种曲线明显地是不能由以前的实验结果得出的。我就有了更大的疑问,提出修改后再审。第三稿中,作者又换了一种方式,有了更多 的漏洞,后来,这篇稿件再也没有出现过。

不少编辑部对审稿采取了双盲制,即审稿人不知道论文的作者是谁;作者也不知道审稿人是谁。不管这种制度的出发点是什么,我认为它把作者和审稿人的交流限制在文字上,有的编辑部甚至只将审稿人的部分意见转述给作者,这样的交流往往是不充分的,很可能成为提高稿件质量的障碍。既然是做学问,就不应该有所顾忌。

有的杂志的编辑部似乎不审稿。你刚把稿件发过去,它就来函说拟在某期发表,要寄版面费。这是不负责任的编辑部,应该离远点。

说到标题,本文的标题也太大了,不过,本文只是随笔,用这样题目是追求一种引人注意的效果,并不是说,注意了本文所提到的这些事就能写出好论文。打个不十分 准确的比方,论文好比一棵树,内容是它的主杆和分支,本文所述的标题、引言、实验、文字等等,或许可以算是一部分叶片,这棵树植根于真才实学的沃土上。要想写好论文,刻苦钻研,增长学识才是关键,论文是用心血浇灌出来的。

© 2009 - 2024 冰河的博客