Tuesday, April 29, 2008

总结一些我不会打的粤语字的拼音打法……

其实以前都不是很在意,觉得看得懂就行;不过为了能更好地融入"生活",还是总结一下...

吖 : a 或者 ya
嗌 : ai 嗌救命
拗 : ao 拗口
嘈 : cao 不是"吵"
� : che 不是"扯"
� : dang ��转菊花圆
� : di 不是"你地"
� : di 不是"d"
� : chi 不是"痴线"
呃 : e 呃人
戆 : gang 戆居 而不是 憨(han)
� : gua 不是"唔��"
嗟 : jie 不是"姐"
� : kai 不是"既"
� : hou 不是"旧" (打不出来....)
叻 : le 叻仔
� : luo 不是"罗"...
乜 : mie 乜都�
嬲 : nao 好 嬲你
� : sai �饭倒晒!(表示全部)
� : sai �左 (表示浪费)
谂 : shen 谂野 而不是 "林�" 或 "念�"
� : song 饭�
� : wen 不是 "稳人"
� : qian ��
� : yu �手 �脚 而不是 "郁" (搜狗打不出这个字)
� : wo 不是"沃"
� : kan �家富贵

补充:
寻日 而不是 "层日" "琴日"(虽然好似我两个都讲……)
千祈 而不是 "千其"
�贵! -- 表示 这么
�都得? -- 表示 这样


Thursday, April 24, 2008

Web Service,XMP-RPC,SOAP,WSDL,UDDI,SOA

Web Service
根据W3C的定义,Web Service就是一个被设计来用于支持网络上机器到机器之间交互的软件系统。
简单来说,Web Service可以被看作一系列的Web API,它们可通过网络被远程调用。
比如说有一个歌词服务器提供一个API为getLyric,则我们只需要发送请求getLyric("someSongName"),则可以期待从服务器返回歌词。

摘抄网络上得到的另一个例子:

<quote>

从表面上看,Web service 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。
这就是说,你能够用编程的方法通过Web来调用这个应用程序。
我们把调用这个 Web service 的应用程序叫做客户。

例如,你想创建一个Web service ,它的作用是返回当前的天气情况。
那么你可已建立一个ASP页面,它接受邮政编码作为查询字符串,然后返回一个由逗号隔开的字符串,包含了当前的气温和天气。
要调用这个ASP页面,客户端需要发送下面的这个HTTP GET请求:

http://host.company.com/weather.asp?zipcode=20171

返回的数据就应该是这样:

21,晴

这个ASP页面就应该可以算作是Web service 了。
因为它基于HTTP GET请求,暴露出了一个可以通过Web调用的API。
当然,Web service 还有更多的东西。

</quote>

最常见的三种Web Service风格分别是RPC,SOA和REST。

1.RPC(Remote Procedure Call)
这是最基本最原始的方法,但是往往由于其调用方法与具体语言绑定,因此被建议废弃。

2.SOA(Service-oriented architecture)

3.REST(Representational state transfer)

-------------------------------------------------------------------------------

XML-RPC
XML-RPC是一个使用XML编码其调用,并使用HTTP协议进行传输的RPC协议。
由于其非常简单易用,因此得到大量广泛的应用。
随着新功能的引入,这个标准发展成了SOAP。
然而由于其易用性,许多人仍然喜欢使用改协议

一个典型的XML-RPC调用的例子如下:

<?xml version="1.0"?>
<methodCall>
  <methodName>examples.getEmployeeName</methodName>
  <params>
    <param>
        <value><i4>40</i4></value>
    </param>
  </params>
</methodCall>

一个对应的XML-RPC相应如下:
<?xml version="1.0"?>
<methodResponse>
  <params>
    <param>
        <value><string>John</string></value>
    </param>
  </params>
</methodResponse>

另外还有XML-RPC错误应答,此处略。

-------------------------------------------------------------------------------

SOAP(Simple Object Access Protocol)
简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议。
它被设计成在 WEB 上交换结构化的和固化的信息,以在应用程序间发送消息。
由于使用了标准的消息描述,它能做到平台独立和语言独立。
SOAP 可以和现存的许多因特网协议和格式结合使用,包括HTTP,SMTP,MIME等,一般使用HTTP/HTTPS。
因此人们一般认为"HTTP + XML = SOAP",与HTTP绑定时,可以使用HTTP POST或HTTP GET方法发送请求。
SOAP可以使用许多不同的消息传递风格,但最常用的是RPC。
SOAP可以看作是TCP/IP体系结构中的应用层协议。事实上它使用了现存的应用层协议作为传输消息的方法。

类似地,DCOM等也可被用于分布式对象访问,但是DCOM往往会被防火墙所过滤。
而SOAP是建立在HTTP等应用层协议上的,一般不会被过滤。

一个典型的SOAP请求如下(获得apple的price,包括HTTP头部):
POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Body>
   <m:GetPrice xmlns:m="http://www.w3schools.com/prices">
      <m:Item>Apples</m:Item>
   </m:GetPrice>
</soap:Body>

</soap:Envelope>

对应的应答如下(包括HTTP头部):
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Body>
   <m:GetPriceResponse xmlns:m="http://www.w3schools.com/prices">
      <m:Price>1.90</m:Price>
   </m:GetPriceResponse>
</soap:Body>

</soap:Envelope>

-------------------------------------------------------------------------------

WSDL(Web Services Description Language)
Web Services Description Language的缩写,是一个用来描述Web Service和说明如何与Web Service通信的XML语言。
注意它本身使用XML语言编写,是一个XML文档,使用了XML Schema来描述网络服务。



有了SOAP后,Web Service提供商还必须向别人提供一套描述自己所提供的SOAP的规范,类似用户手册(manual)
可以把WSDL看作是Web Service的使用说明书。包括接口名称、参数类型等。
然而对于开发人员,无法方便地得到以上信息,因此有必要提供一套解决方案,
以一种统一的、机器能阅读的、人能阅读的描述文档来描述。使用相应的工具可以导入WSDL文档生成调用相应
Web Service的代码,也能根据自己提供的Web Service生成WSDL文档,以供它人使用。


它往往被用于与SOAP,XML Schema结合以在Internet上提供Web Service。

客户端可以通过读取WSDL来得到它能进行什么函数调用,以及可以使用的数据类型。
然后可以使用SOAP来调用WSDL中定义的函数。

WSDL 文档仅仅是一个简单的 XML 文档。
它包含一系列描述某个 web service 的定义。

一个简化的例子,描述了两个消息:

<message name="getTermRequest">
   <part name="term" type="xs:string"/>
</message>

<message name="getTermResponse">
   <part name="value" type="xs:string"/>
</message>

<portType name="glossaryTerms">
  <operation name="getTerm">
      <input message="getTermRequest"/>
      <output message="getTermResponse"/>
  </operation>
</portType>

-------------------------------------------------------------------------------

UDDI(Universal Description, Discovery and Integration)
UDDI 是一种目录服务,企业可以使用它对 Web services 进行注册和搜索。

在 UDDI 之前,还不存在一种 Internet 标准,可以供企业为它们的企业和伙伴提供有关其产品和服务的信息。
也不存在一种方法,来集成到彼此的系统和进程中。

假如行业发布了一个用于航班比率检测和预订的 UDDI 标准,航空公司就可以把它们的服务注册到一个 UDDI 目录中。
然后旅行社就能够搜索这个 UDDI 目录以找到航空公司预订界面。
当此界面被找到后,旅行社就能够立即与此服务进行通信,这样由于它使用了一套定义良好的预订界面。
这一注册中心与一个电话号码簿非常类似,因为顾客可以通过注册中心查询已经注册Seb services的公司列表。

UDDI用来发布我们提供的web services,当我们写好了一个web services,并且为他建立了WSDL文件,
剩下的事情就是宣传自己,让用户能够找到我们的web services。这个过程有点像电信的"黄页服务(Yellow Paqge)",
企业为了扩展自己的业务,将电话号码登记在黄页上,电信局免费将黄页送给用户,
用户就可以在上面找到自己感兴趣企业的电话。
UDDI就像黄页,如果web services分布在不同的主机上
(比如做为客户端,我们想要的分别访问sohu提供的天气预报服务和sina提供的股票查询服务,
我们没有必要直接去 sohu或者sina的主机上去寻找服务,而是在提供UDDI服务的主机上寻找,
这样,我们的程序就不用直接关联到sohu或者sina,提高了灵活性),那么一个集中管理信息的UDDI则十分重要。

这里有一篇很详细描述UDDI的文章:
http://www.ibm.com/developerworks/cn/webservices/ws-featuddi/index.html


-------------------------------------------------------------------------------

SOA(Service-Oriented Architecture)
看了很多文章,看不懂。
唯一有点感觉的是这篇:
http://se.csai.cn/Monograph/200611141640091038.htm

这里还有很多相关文章:
http://se.csai.cn/zt/SOA/index.asp

Tuesday, April 22, 2008

Cloud Computing,Grid Computing,Utility Computing

Cloud Computing: 云计算
google与ibm提出的概念。把计算的概念伸展。
形象来理解就是,把计算能力也作为一种商品出售。
传统的工作模式是,每个用户使用一台PC进行计算
而云计算模型则通过使计算分布在大量的计算机上,而非本地机器,这使得企业能够根据整体情况实现负载均衡。
看起来,用户只需携带一个终端并且连接到internet上,就能获得非凡的计算能力。
google某工程师给的一个很好的比方就是,在旧时代,每个人都要用电,则必须自己携带发电机(PC),
而在云计算时代,每个人不必拥有发电机,而是直接从服务提供商获得电力(计算能力)。

Grid Computing : 网格计算/晶格计算
从电网中延伸过来的概念。因为电网是通过发电厂以及输电线路之间建立起来的一个动态供电系统,其部署类似一个个的网格。
而网格计算中的网格则是计算机组成。在整个大的网格中,一部计算机加入就可以很方便地成为计算节点,也可以很方便地退出网格。
一个很好的例子就是BOINC。使用中心服务器分发任务+分布在全球的计算机系统组成了计算网格,其计算能力已经达到了某个天文数字。
而用户可以自由地决定是否提供自己的计算资源(因此也被叫做志愿计算,volunteer computing)

云计算与网格计算: 云计算总是使用网格计算的管理资源方法来管理节点,而网格计算的技术并不局限于云计算技术之中。

Utility Computing : 实用计算
一种提供服务的模型。IT企业通过创建一个虚拟的计算中心,把内存、I/O设备等利用起来成为一个虚拟的服务池来提供服务,是云计算的一种应用。

Saturday, April 19, 2008

使用C++编写Hadoop Map Reduce程序

今天在实验室的机器上配置好了Hadoop,因为今后预计会使用C++进行一些开发,
因此模仿word count的example写了个C++测试程序(好简陋 - -!!)。

贴个代码:
Mapper:
// c++ map reduce Mapper
// word count example
// 2008.4.18
// by iveney
#include <string>
#include <iostream>
using namespace std;

int main()
{
        string buf;
        while( cin>>buf )
                cout<<buf<<"\t"<<"1"<<endl;
        return 0;
}

Reducer:
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
        map<string,int> dict;
        map<string,int>::iterator iter;
        string word;
        int count;
        while( cin>>word>>count )
                dict[word]+=count;
        iter = dict.begin();
        while( iter != dict.end() )
        {
                cout<<iter->first<<"\t"<<iter->second<<endl;
                iter++;
        }
        return 0;
}

编译:
[hadoop@master ~]$ g++ mapper.cpp -o mapper
[hadoop@master ~]$ g++ reducer.cpp -o reducer

简单测试:
[hadoop@master ~]$ echo "ge abc ab  df ge" | ./mapper | ./reducer
ab      1
abc     1
df      1
ge      2

使用Hadoop计算:
(数据使用了Project Gutenberg的几本电子书,不过貌似国内被屏蔽了?www.gutenberg.org
好在在UPenn的图书馆里有资源 ^^V http://digital.library.upenn.edu/webbin/gutbook

[hadoop@master ~]$ ll -h gutenberg
total 5.3M
-rw-r--r-- 1 hadoop hadoop 336K 2008-04-18 07:45 132.txt
-rw-r--r-- 1 hadoop hadoop 154K 2008-04-18 07:45 1ws1510.txt
-rw-r--r-- 1 hadoop hadoop 659K 2008-04-18 07:45 20417-8.txt
-rw-r--r-- 1 hadoop hadoop 1.4M 2008-04-18 07:45 7ldvc09.txt
-rw-r--r-- 1 hadoop hadoop 577K 2008-04-18 07:45 advsh12.txt
-rw-r--r-- 1 hadoop hadoop 377K 2008-04-18 07:45 dvldc10.txt
-rw-r--r-- 1 hadoop hadoop 185K 2008-04-18 07:45 frhnt10.txt
-rw-r--r-- 1 hadoop hadoop 152K 2008-04-18 07:45 rgsyn10.txt
-rw-r--r-- 1 hadoop hadoop 1.5M 2008-04-18 07:45 ulyss12.txt


运行结果:
[hadoop@master hadoop]$ bin/hadoop jar contrib/streaming/hadoop-0.16.3-streaming.jar -mapper /home/hadoop/mapper -reducer /home/hadoop/reducer -input gutenberg/* -output gutenberg-c++-output
additionalConfSpec_:null
null=@@@userJobConfProps_.get(stream.shipped.hadoopstreaming
packageJobJar: [/usr/share/hadoop-datastore/hadoop-hadoop/hadoop-unjar41914/] [] /tmp/streamjob41915.jar tmpDir=null
08/04/18 01:16:13 INFO mapred.FileInputFormat: Total input paths to process : 9
08/04/18 01:16:13 INFO streaming.StreamJob: getLocalDirs(): [/usr/share/hadoop-datastore/hadoop-hadoop/mapred/local]
08/04/18 01:16:13 INFO streaming.StreamJob: Running job: job_200804171952_0005
08/04/18 01:16:13 INFO streaming.StreamJob: To kill this job, run:
08/04/18 01:16:13 INFO streaming.StreamJob: /usr/share/hadoop/bin/../bin/hadoop job  -Dmapred.job.tracker=master:54311 -kill job_200804171952_0005
08/04/18 01:16:13 INFO streaming.StreamJob: Tracking URL: http://master.cluster:50030/jobdetails.jsp?jobid=job_200804171952_0005
08/04/18 01:16:14 INFO streaming.StreamJob:  map 0%  reduce 0%
08/04/18 01:16:17 INFO streaming.StreamJob:  map 11%  reduce 0%
08/04/18 01:16:18 INFO streaming.StreamJob:  map 22%  reduce 0%
08/04/18 01:16:19 INFO streaming.StreamJob:  map 67%  reduce 0%
08/04/18 01:16:20 INFO streaming.StreamJob:  map 78%  reduce 0%
08/04/18 01:16:22 INFO streaming.StreamJob:  map 100%  reduce 0%
08/04/18 01:16:23 INFO streaming.StreamJob:  map 100%  reduce 4%
08/04/18 01:16:26 INFO streaming.StreamJob:  map 100%  reduce 26%
08/04/18 01:16:33 INFO streaming.StreamJob:  map 100%  reduce 30%
08/04/18 01:16:36 INFO streaming.StreamJob:  map 100%  reduce 33%
08/04/18 01:16:38 INFO streaming.StreamJob:  map 100%  reduce 71%
08/04/18 01:16:41 INFO streaming.StreamJob:  map 100%  reduce 80%
08/04/18 01:16:43 INFO streaming.StreamJob:  map 100%  reduce 100%
08/04/18 01:16:43 INFO streaming.StreamJob: Job complete: job_200804171952_0005
08/04/18 01:16:43 INFO streaming.StreamJob: Output: gutenberg-c++-output

跟使用例程测试得到的结果相同~成功~

用了29secs,竟然比Python写的例程还慢5secs。
很可能是数据量大小java虚拟机的启动显得没那么trivial了 -_-|||

另外直接运行其实更快……咔咔......数据量
[hadoop@master ~]$ cat test.sh
#!/bin/bash

cd /home/hadoop/gutenberg
for i in `ls`
do
        cat $i | /home/hadoop/mapper | /home/hadoop/reducer \
             >> /home/hadoop/output
done
[hadoop@master ~]$ time ./test.sh

real    0m4.176s
user    0m5.454s
sys     0m1.611s

Monday, April 14, 2008

CAcert小试

CAcert是一个免费的CA系统,试图建议所谓的可信网络(Web of trust),这是它对自己object的介绍:

CAcert.org was designed to be by the community for the community, and instead of placing all the labour on a central authority and in turn increasing the cost of certificates, the idea was to get community in conjunction with this website to have trust maintained in a dispersed and automated manner!

上去试了一下,发觉它提供的证书包括个人证书、domain证书、SSL证书等,都是免费的。
可以用于电子邮件签名、加密、SSL服务器、客户端等。
当然,认证的过程是严格的。要成为一个assurer,首先必须获得100点的assurer points。
另外还要通过所谓的Certificate Test. (我裸考过一次,60分,要80分才合格,100分才能获得资格)

-------------------------------------------
下面介绍一下如何申请与注册。

首先登陆www.cacert.org
按照页面连接进入Root certificate页面,倒入它的class 1和class 3的根证书,然后还要倒入crl(证书撤销列表)
firefox浏览器操作很方便,直接点击就可以自动下载与导入了。导入根证书时会要求用户确认,因为它是自签发的。

接下来选择join us。
然后会让你填一堆东西,其中密码有个评分制度,必须达到6分才能通过它的认证。
根据提示,必须要有足够长度、英文大小写、标点符号才能达到……我随便写了一个面目全非的,也不知有没可能记住。

点击下一步后,(我用的是firefox),firefox要求你输入一个密码用以保护证书(我不知有没理解错,后面好像都没用到),然后firefox生成一个私钥与公钥对。
cacert随之根据签发的信息生成你的帐号。必须登陆邮箱激活帐号。

最后可以去申请数字证书,登陆后发觉有3种证书,分别是个人证书、domain证书、服务器证书。
后面两种没有测试,我申请了个人证书。

申请的过程比较简单,按部就班就完成了。最后会给邮箱发一封确认邮件,点击连接自动添加证书到浏览器里
同时又需要一个密码来保护该证书……(好多密码啊……)
然后浏览器还提示要注意备份,于是我选择导出备份,然则此时又需要一个密码以保护该证书……

更新:关于导出文件.P12
In cryptography, PKCS#12 is one of the family of standards called Public-Key Cryptography Standards (PKCS), published by RSA Laboratories. It defines a file format commonly used to store private keys with accompanying public key certificates, protected with a password-based symmetric key, and is the successor to PFX.
File extension: .p12

 原来这个导出文件包括私钥和包含公钥的数字证书。同时可以输入一个密码(对称的)以保护它。



最后,当证书成功保存在你的浏览器里时,就可以使用了!
进入这个网站时再也不用输入密码了 ~.~
直接点击证书登陆即可。

另外,这个证书好像只有半年有效期,到时要主动来更新。
并且在更新的页面上也有revoke的选项。(我申请了3次,前两次都不小心revoke了……)

-------------------------------------------

看了一下关于assure,发觉真的好麻烦。
Find an assurer: 离广州方圆1000里只能搜索到4个assurer,而且貌似都是HK的。

Michael B 120km 10 contact by email only Email Me
Yat Hei C 130km 35 Please contact me at xxxx Email Me
David W 130km 35
Email Me
Kin Fung Y 240km 35 I live in Hong Kong. Email me for assurance only. Email Me

如果要成为assurer,还必须通过律师等把资料寄到相关的委员会。

-------------------------------------------

总的来说,申请个人数字证书如果普及起来,达到可信网络的状态的话,应该相当不错吧。
可惜学习梯度似乎有点大,连自认为理解能力比较好的我也看得晕晕乎乎的(之前还花了整个星期看PKI的原理、概念)
感觉PKI要做起来也不容易,虽然从各方面来分析都相当合理。

然而我认为它的最大缺陷还是:最多仅能保证到网络传输安全,端点安全也尤为重要啊。
如果别人直接用你的浏览器,它在网上的身份就成为你了……
所以说自己的电脑要保护好才行。个人电脑一定要设密码。

Wednesday, April 9, 2008

关于redhat系列与debian系列的网络基本配置

以前弱,只知道用system-config-network这个GUI来设置网络,又烂又慢.
最近因为要远程配置cluster,因此研究了一下静态配置的方法,其实也很简单.
但是由于cluster用的系统是fedora,但自己机器上是ubuntu,发觉有些不一样,做个笔记对比下.
PS.由于ubuntu是debian系列的,我猜想debian也是差不多的
而网上查到redhat与fedora的配置文件的确是一样的.

以下仅涉及以太网的IP,netmask,gateway,broadcast设置.
以及dns,resolve配置.

共同的设置:
1. DNS服务器 resolv.conf
均使用/etc/resolv.conf ( 注意是resolv不是resolve )来配置DNS服务器
它的格式如下:
nameserver IP
nameserver IP
...

很简单
另外还有不少的option,不过发觉似乎没什么会用到的,就没有细看了.

2.静态主机名查询表 hosts
均使用/etc/hosts来记录静态的主机名,别名以及IP. 在windows下则是 %windows%\system32\hosts( 如果没记错 )
格式如下:
IP    hostname alias[,alias...]
其中这行必须存在,用于定义换回接口的地址以及域名
127.0.0.1       localhost.localdomain   localhost       localhost

一个IP对应一个主机名以及多个别名.使用hostname可以设置以及修改域名

不同的设置

1.
ubuntu中,/etc/hostname 用来定义本机主机名,用于启动时供启动脚本读取设定.
而redhat系列貌似没有这个文件,在hostname的手册页中介绍到
       The host name is usually set once at system startup in /etc/rc.d/rc.inet1 or /etc/init.d/boot (normally by reading the contents  of  a
       file which contains the host name, e.g.  /etc/hostname).
另外在网上看到的介绍是:
在/etc/sysconfig/network中进行设定.然而我在ubuntu中貌似找不到类似的文件.

我在启动脚本看到,/etc/rc.d/rc.sysvinit里含有设定的语句.
而在/etc/rc.d/rc.local中看到用nisdomainname来设定nis的domainname.

2.
ubuntu中/etc/network/interfaces用来定义各个interface的IP等设定
----------------------
我的机器该文件如下:
auto lo
iface lo inet loopback
address 127.0.0.1
netmask 255.0.0.0


iface eth0 inet static
address 172.18.34.177
netmask 255.255.252.0
gateway 172.18.35.254

auto eth0

iface eth1 inet dhcp

----------------------
其中auto表示机器启动时自动up.
iface一项定义该界面的具体参数,
static表示静态地址而dhcp表示...就是dhcp拉 -.-
其中static又应包括address,netmask,gateway.

而在redhat中,使用/etc/sysconfig/network-scripts/ifcfg-ethn来设定
其中ethn可替换为网卡名.在某台机器上看到内容ifcfg-eth0如下:
# Intel Corporation 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
DEVICE=eth0
BOOTPROTO=none
BROADCAST=202.116.76.255
IPADDR=202.116.76.163
NETMASK=255.255.255.0
NETWORK=202.116.76.0
ONBOOT=yes
GATEWAY=202.116.76.1
TYPE=Ethernet
USERCTL=no
IPV6INIT=no
PEERDNS=yes

需要填写的field其实跟ubuntu大同小异.
同时注意到,ifup和ifdown script都在这里.它们就是通过读取这里的设定来完成interface的up & down的.
但是

另外我还注意到,在/etc/sysconfig/networking中:
devices文件夹包含ifcfg-eth{0,1},其中eth0和eth1是已有的网络设备.
这两个文件与/etc/sysconfig/network-scripts的两个文件inode相同,说明是硬链接.

而在profiles/default中包含有:
hosts  ifcfg-eth0  ifcfg-eth1  network  resolv.conf
几个文件,其中hosts,network,resolv.conf分别为/etc/hosts,/etc/sysconfig/network,/etc/resolv.conf的硬链接.
而ifcfg-eth{0,1}与上面提到的是硬链接.




Monday, April 7, 2008

我的汉编作品

/*
 * 拷贝右 (西) 二零零八 逸仙之狼工作室
 * 所有权限被保留
 * 文件名 : 汉语编程演示程序示例.源文件
 * 编写日期:二零零八年三月二十八日
 * 修订版本:一点五
 * 作者:艾文尼 在 逸仙时空
 * 版权所有,翻版必究
 */

# 包含 "人.头文件"
# 包含 "男人.头文件"

/**
 * 类 : 女人
 * 描述 : 继承父类人,实现女人某些基本功能
 */
公共 类 女人:公共 人
{

    公共:
      女人(字符串 姓名,整数 年龄,三元组 她的三围,布尔 她的发长):
      人(姓名,年龄),三围(她的三围),发长(她的发长){}

      ~女人(){}

     /**
      * 方法 : 亲吻
      * 效果 : 亲吻一个人
      * 参数 : 指向一个人对象的指针
      * 返回 : 真 如果 成功 假 如果 失败
      */
      布尔 亲吻(对象 指针 某人):抛出 反抗异常
     {
           尝试
           {
               这个.拥抱(某人);
               这个.咬嘴唇(某人;
               这个.舔舌头(某人);
           }
           抓住(反抗异常 异常)
           {
                返回 假;
            }
           返回 真;
     }
     私有:
          三元组 三围;
          布尔  发长;
}

字符串 姓名数组 [][]={"萝莉","御姐"};

整数  主要()
{
        // 创建一个女人对象
        女人 指针 美女;
        // 创建男人,我
        男人  我;

        整数 索引;
        整数  年龄;
        布尔  长发 赋值 真;
        三元组  三围;
        当(真)
       {// 在死循环内歪歪
              索引 赋值 随机() 取模 二;
              如果 (  索引 等于 零 )
             {
                     年龄 赋值 十五;
                     三围.设置(三十,十八,二十);
             }
              否则
             {
                     年龄 赋值  二十五;
                     三围.设置(三十五,二十,二十五);
              }
              美女 = 新 女人(姓名数组[索引],年龄,三围,长发 取反);
              美女->亲吻(我);
              删除 美女;
        }
       返回 零;
}

Tuesday, April 1, 2008

序列化serialization,元编程metaprogramming,反射reflexivity,quine,语法糖衣syntactic sugar

很好很强大,一上来就遇到这么一长串题目.
今晚偶尔无聊看了一下这几个概念,其实每个概念都可以引申出一长串东西了...
不过为了做个备忘,还是稍微写写吧.不保证我理解和语言表达的正确性.最终解释均以wikipedia为准.

1.序列化,serialization
序列化可以保持对象的持久性(简单来说就是把你程序运行时对象在内存的映像保存起来,写到非易失性存储介质上).
对于普通的一个数据结构,比如
class A
{
    int a;
    char b;
}
这样的东东显然很容易做到,比如我只要简单地把一个4B的int和1B的char保存下来就好.
如果有一堆这样的对象,比如十个A对象,也许我可以定义我保存下来这个文件,前4个字节保存的是后面含有的A对象数,
然后就可以遍历读出来了.

但是,如果对于一个链表呢?
class Node
{
    int value;
    Node * next;
}
我们在创建此类对象时一般是使用动态内存分配的.那么就要考虑到:对于每个run time,显然分配到的内存地址是不大可能一样的.
因为这涉及到了内存的relocate.
那么我们应该怎麽保存这种对象数据呢?这就涉及到了序列化与逆序列化(serialization,deserialization)

More specifically,
从一个对象/指针/地址的引用转换到在存储器上的表示,可以称为"pointer unswizzling"(我也不知中文怎麽喊),也即是serialization的过程.
而反过来,从一个序列化的文件转换为一个对象可以称为"pointer swizzling",也即是deserialization的过程.

完成序列化的方法是多种多样的,还是以链表为例子.
我们可以遍历一个链表,然后给每个节点一个内部标号,最后存储时描述的数据结构就可以如下:
class _Node
{
    int value;
    int _id;
    int _next_id;
}
因此每个对象之间的相对关系可以用偏移量计算出来,因此deserialization也是一样的原理了.当然这里还有很多情况没有分析到.
不过大概的一种实现方法就就是如此.

不同语言有不同的序列化方法.我所接触过的,有
1)Java的serialization mechanism,通过声明某对象为serializable
2)MFC的serialization
3)C++的boost库的serialization实现
其余语言略.

2.元编程(meta programming)
元编程简单来说就是可编程的编程...或者理解成自动生成代码,动态改变指令也行.
因此引申出两个概念,一个是符合这种定义/有这种功能的语言--元语言,一个是该语言能生成的语言--目标语言.如果这种语言的目标语言就是它本身,那么我们称它是自反的(反射的,reflective).

比如yacc,lex等,就是一种生成语言的语言...只不过是在源代码级的.
而我们常见的"宏",通过在编译前的预处理帮助我们生成代码,这种是宏拓展,也是在源码级的.
最强大的莫过于运行时动态修改了.现代程序设计的模型(图灵机)是把指令与数据同等对待的,
那么既然我们能动态修改数据,为什么不能修改指令呢?当然要实施相应的安全机制拉.....

比如说最近我想写这么一个脚本,不过我是脚本菜鸟 -v-
我想定义一系列的shell的环境变量,分别是for i in seq `1 8`;ip$i=192.168.1.$i;
问题是,ip[1-8]这些变量现在还没定义阿...因此后面也不能进行export.于是我只好折中地先写一个脚本生成要执行的语句,
然后再执行生成的脚本,分两步执行.殊不知这也算是一种元编程(在wikipedia上是这么说的...)
我想,如果能动态生成变量就好了.其实也许是可以的,只不过我不会而已.....

另一个典型的例子是java的反射机制,这又要涉及到了所谓的first-class datatype.关于这个就先不说了.
在经典的C/C++等语言中,基本的数据类型/对象有int,char等这些,但是在java中,连类,方法本身也是一种对象!
因此对于类,方法,我们可以保存一些元信息,来做到一些强悍的事情.

比如我们可以动态地执行一个方法,通过接收用户的输入,然后在类里面查找相应的方法,创建一个这个方法的引用,
然后调用之.这在以往的C/C++中根本不可想象.

C++貌似也想加入一点这个特性,比如RTTI也算是一个半成品.另外template也多少有点这么个意思.
只不过template现在引出的是generic programming,范型编程,此处不表...

关于元编程,我理解的就这么多,还要更都的可以去学习一下lisp等...可以参见这位大牛...
http://pluskid.lifegoo.com/?p=46#more-46

最后要小小地说一下"quine",在programming领域中,它指的是"能够打印自己源代码的程序".
往往被hacker们用来show自己对某种语言的熟练与掌握程度.
Quine 以哲学家 Willard van Orman Quine (1908-2000) 而命名.因为他提出了" indirect self-reference"这个概念.
与它相关的有这么一个悖论:"This sentence is false."
那么,究竟那句sentence是对还是错呢 ^_^ 说它对时,也就承认了它是错的;说它错时,也就承认了它是对的......
一个最简单的C-quine如下,很强大:
main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}

更多的请继续参看这位童鞋的wiki:
http://pluskid.lifegoo.com/wiki/Quine.html

3.语法糖衣syntactic sugar
这个比较好理解.我们知道一种语言有固定的语法结构与关键字.
程序设计的三种基本结构为顺序,选择,循环.
因此完成了这些基本功能的语言的语法与关键字我们可以看作一个集合,在这个集合里面我们可以干出程序允许的任何事.
但是如果我们添加一些关键字后,也许可以增强程序的可读性,或者降低编程的复杂度,然而我们不能做出比原来更多的事!

举一个例子,比如在C++中,我们完全可以使用for来完成所有的循环,而while可以改写成for.
另外由if-else结构也能完成所有的条件语句,switch, :? 这些都可以转化成if-else的表示.
因此很直观地,我们可以定义这种语言的语法的"核心"(core syntax).
语法糖衣是好的还是不好的?也许对于我们这些普通人他们是好的,习惯了写for loop的我在写shell程序时觉得写一个for i in ...
觉得很脑残,幸而有for((;;)) 这个糖衣帮我解决了问题.
然而大牛们一致认为这是没有必要的,因为单靠最基本的语法就能解决问题.
这又牵涉到了数学问题,学过scheme等函数式语言的都知道,所有语句其实都是由表达式递归定义而成,包括循环,选择.
因此大牛们写程序往往可以用几个括号,四则运算,数字就搞定了....
Linux内核维护者也坚持只需要用C来完成OO以及所有功能,而不需要C++等.
更直观地说,比如我们可以这种定义正整数:
1)最小的数是1
2)第i大的数是比它前一位的数加1
(可能写得有点不准确,不过递归定义的思想基本就如此)

然后还有两个不那么流行的术语:
语法盐 syntactic salt
被用于增强程序健壮性或代码编写规范的语法,它们本身并不能简化程序的写法或增强语言的功能.
比如一些程序语言中提倡if与endif要配对,而不是简单地用{}括起来.

语法糖精 Syntactic saccharin
这个比较无聊,指那些并不能使程序编写简单的无用的特性.

---分割线来了---

恩,好了,大概就联想这么多...
愚人节就让我geek一回...