随心所欲


随心所欲22 Aug 2007 09:10 am

Mandriva

Mandriva原名Mandrake,最早由Ga&l Duval创建并在1998年7月发布。记得前两年国内刚开始普及Linux时,Mandrake非常流行。说起Mandrake的历史,其实最早 Mandrake的开发者是基于Redhat进行开发的。Redhat默认采用GNOME桌面系统,而Mandrake将之改为KDE。而由于当时的 Linux普遍比较难安装,不适合第一次接触Linux的新手,所以Mandrake还简化了安装系统。我想这也是当时Mandrake在国内如此红火的 原因之一。Mandrake在易用性方面的确是下了不少功夫,包括默认情况下的硬件检测等。

Mandrake的开发完全透明化,包括“cooker”。当系统有了新的测试版本后,便可以在cooker上找到。之前Mandrake的新版本的发布速度很快,但从9.0之后便开始减缓。估计是希望能够延长版本的生命力以确保稳定和安全性。

优点:友好的操作界面,图形配置工具,庞大的社区技术支持,NTFS分区大小变更
缺点:部分版本bug较多,最新版本只先发布给Mandrake俱乐部的成员
软件包管理系统:urpmi (RPM)
免费下载:FTP即时发布下载,ISO在版本发布后数星期内提供
官方主页:[url]http://www.mandrivalinux.com/[/url]

Red Hat

国内,乃至是全世界的Linux用户所最熟悉、最耳闻能详的发行版想必就是Red Hat了。Red Hat最早由Bob Young和Marc Ewing在1995年创建。而公司在最近才开始真正步入盈利时代,归功于收费的Red Hat Enterprise Linux(RHEL,Red Hat的企业版)。而正统的Red Hat版本早已停止技术支持,最后一版是Red Hat 9.0。于是,目前Red Hat分为两个系列:由Red Hat公司提供收费技术支持和更新的Red Hat Enterprise Linux,以及由社区开发的免费的Fedora Core。Fedora Core 1发布于2003年年末,而FC的定位便是桌面用户。FC提供了最新的软件包,同时,它的版本更新周期也非常短,仅六个月。目前最新版本为FC 3,而FC4也预定将于今年6月发布。这也是为什么服务器上一般不推荐采用Fedora Core。

适用于服务器的版本是Red Hat Enterprise Linux,而由于这是个收费的操作系统。于是,国内外许多企业或空间商选择CentOS。CentOS可以算是RHEL的克隆版,但它最大的好处是免费!菜鸟油目前的服务器便采用的CentOS 3.4。

优点:拥有数量庞大的用户,优秀的社区技术支持,许多创新
缺点:免费版(Fedora Core)版本生命周期太短,多媒体支持不佳
软件包管理系统:up2date (RPM), YUM (RPM)
免费下载:是
官方主页:[url]http://www.redhat.com/[/url]

SUSE

SUSE是德国最著名的Linux发行版,在全世界范围中也享有较高的声誉。SUSE自主开发的软件包管理系统YaST也大受好评。SUSE于2003年年末被Novell收购。

SUSE之后的发布显得比较混乱,比如9.0版本是收费的,而10.0版本(也许由于各种压力)又免费发布。这使得一部分用户感到困惑,也转而使用其它发行版本。但是,瑕不掩瑜,SUSE仍然是一个非常专业、优秀的发行版。

优点:专业,易用的YaST软件包管理系统
缺点:FTP发布通常要比零售版晚1~3个月
软件包管理系统:YaST (RPM), 第三方APT (RPM) 软件库(repository)
免费下载:取决于版本
官方主页:[url]http://www.suse.com/[/url]

Debian GNU/Linux

Debian是菜鸟油服务器之前所采用的操作系统。Debian最早由Ian Murdock于1993年创建。可以算是迄今为止,最遵循GNU规范的Linux系统。Debian系统分为三个版本分支(branch): stable, testing 和 unstable。截至2005年5月,这三个版本分支分别对应的具体版本为:Woody, Sarge 和 Sid。其中,unstable为最新的测试版本,其中包括最新的软件包,但是也有相对较多的bug,适合桌面用户。testing的版本都经过 unstable中的测试,相对较为稳定,也支持了不少新技术(比如SMP等)。而Woody一般只用于服务器,上面的软件包大部分都比较过时,但是稳定 和安全性都非常的高。菜鸟油之前所采用的是Debian Sarge。

为何有如此多的用户痴迷于Debian呢(包括笔者在内)?apt-get / dpkg是原因之一。dpkg是Debian系列特有的软件包管理工具,它被誉为所有Linux软件包管理工具(比如RPM)最强大的!配合apt- get,在Debian上安装、升级、删除和管理软件变得异常容易。许多Debian的用户都开玩笑的说,Debian将他们养懒了,因为只要简单得敲一 下”apt-get upgrade && apt-get update”,机器上所有的软件就会自动更新了……

优点:遵循GNU规范,100%免费,优秀的网络和社区资源,强大的apt-get
缺点:安装相对不易,stable分支的软件极度过时
软件包管理系统:APT (DEB)
免费下载:是
官方主页:[url]http://www.debian.org/[/url]

Ubuntu

笔者的桌面电脑便使用的Ubuntu。依照笔者的理解,简单而言,Ubuntu就是一个拥有Debian所有的优点,以及自己所加强的优点的近乎完美的 Linux操作系统。 Ubuntu是一个相对较新的发行版,但是,它的出现可能改变了许多潜在用户对Linux的看法。也许,从前人们会认为Linux难以安装、难以使用,但 是,Ubuntu出现后,这些都成为了历史。Ubuntu基于Debian Sid,所以这也就是笔者所说的,Ubuntu拥有Debian的所有优点,包括apt-get。然而,不仅如此而已,Ubuntu默认采用的GNOME 桌面系统也将Ubuntu的界面装饰的简易而不失华丽。当然,如果你是一个KDE的拥护者的话,Kubuntu同样适合你!

Ubuntu的安装非常的人性化,只要按照提示一步一步进行,安装和Windows同样简便!并且,Ubuntu被誉为对硬件支持最好最全面的Linux 发行版之一,许多在其他发行版上无法使用,或者默认配置时无法使用的硬件,在Ubuntu上轻松搞定。并且,Ubuntu采用自行加强的内核 (kernel),安全性方面更上一层楼。并且,Ubuntu默认不能直接root登陆,必须从第一个创建的用户通过su或sudo来获取root权限 (这也许不太方便,但无疑增加了安全性,避免用户由于粗心而损坏系统)。Ubuntu的版本周期为六个月,弥补了Debian更新缓慢的不足。

优点:人气颇高的论坛提供优秀的资源和技术支持,固定的版本更新周期和技术支持,可从Debian Woody直接升级
缺点:还未建立成熟的商业模式
软件包管理系统:APT (DEB)
免费下载:是
官方主页:[url]http://www.ubuntulinux.org/[/url]

Gentoo

Gentoo最初由Daniel Robbins(前Stampede Linux和FreeBSD的开发者之一)创建。由于开发者对FreeBSD的熟识,所以Gentoo拥有媲美FreeBSD的广受美誉的ports系统 ——portage。(Ports和Portage都是用于在线更新软件的系统,类似apt-get,但还是有很大不同)Gentoo的首个稳定版本发布 于2002年。

Gentoo的出名是因为其高度的自定制性:因为它是一个基于源代码的(source-based)发行版。尽管安装时可以选择预先编译好的软件包,但是 大部分使用Gentoo的用户都选择自己手动编译。这也是为什么Gentoo适合比较有Linux使用经验的老手使用的原因。但是要注意的是,由于编译软 件需要消耗大量的时间,所以如果你所有的软件都自己编译,并安装KDE桌面系统等比较大的软件包,可能需要几天时间才能编译完……

优点:高度的可定制性,完整的使用手册,媲美Ports的Portage系统,适合“臭美”的高手使用^^
缺点:编译耗时多,安装缓慢
软件包管理系统:Portage (SRC)
免费下载:是
官方主页:[url]http://www.gentoo.org/[/url]

Slackware

Slackware由Patrick Volkerding创建于1992年。算起来应当是历史最悠久的Linux发行版。曾经Slackware非常的流行,但是当Linux越来越普及,用 户的技术层面越来越广(更多的新手)后,Slackware渐渐的被新来的人们所遗忘。在其他主流发行版强调易用性的时候,Slackware依然固执的 追求最原始的效率——所有的配置均还是要通过配置文件来进行。

尽管如此,Slackware仍然深入人心(大部分都是比较有经验的Linux老手)。Slackware稳定、安全,所以仍然有大批的忠实用户。由于 Slackware尽量采用原版的软件包而不进行任何修改,所以制造新bug的几率便低了很多。Slackware的版本更新周期较长(大约1年),但是 新版本的软件仍然不间断的提供给用户下载。

优点:非常稳定、安全,高度坚持UNIX的规范
缺点:所有的配置均通过编辑文件来进行,自动硬件检测能力较差
软件包管理系统:Slackware Package Management (TGZ)
免费下载:是
官方主页:[url]http://www.slackware.com/[/url]

Knoppix

由德国的Klaus Knopper开发的Knoppix,是一个基于Debian的发行版。Knoppix严格算起来是一款LiveCD Linux,所谓的LiveCD就是整个操作系统都在一张光盘上,只要开机从光盘启动,就能拥有一个完整的Linux系统!无需安装!当然, Knoppix也能够非常轻松的安装到硬盘上。其强大的硬件检测能力、系统修复能力、即时压缩传输技术,都令人大加称赞。可以说,在LiveCD界, Knoppix是无人能及的!

优点:无需安装可直接运行于CD上,优秀的硬件检测能力,可作为系统急救盘使用
缺点:LiveCD由于光盘的数据读取速度限制导致性能大幅下降
软件包管理系统:APT (DEB)
免费下载:是
官方主页:[url]http://www.knoppix.com/[/url]

MEPIS

MEPIS由Warren Woodford在2003年建立。MEPIS虽然刚建立不久,但是迅速的传播在Linux用户间。简单来说,MEPIS是一个集合了Debian Sid和Knoppix的产物。用户即能将之当作LiveCD使用,也能使用常规的图形界面进行安装。

MEPIS默认集成安装了Java Runtime Environment、Flash插件、nVidia加速驱动等许多常用的程序。用户可以非常轻松的安装完系统后就直接开始使用,而不用到处寻找资料如 何下载、如何安装、如何配置这些软件。这不仅给Linux新手带来了便捷,也给老手们节约了相当多的时间。

优点:LiveCD与常规安装两用,优秀的硬件检测能力,预装了许多实用的软件
缺点:建立时间不长,默认的界面有些寒酸
软件包管理系统:APT (DEB)
免费下载:是
官方主页:[url]http://www.mepis.org/[/url]

Xandros

Xandros建立在已经成为历史的Corel Linux之上。当初Corel Linux的公司由于财政上的困难,被迫终止了Corel Linux的开发,而Xandros适时的将Corel Linux部门买下,于2002年10月推出全新的Xandros Desktop。

Xandros的卖点在于极其简单的安装和使用,所以它的市场定位是那些没有任何Linux使用经验的新手,或是习惯使用Windows的用户。Xandros的标准版和增强版都是商业软件,分别售价$40和$99美元。不过你仍然可以在这里下载到免费的公开发行版。

优点:适合完全没有经验的新手,安装完以后就能立即投入使用,自带非常不错的工具
缺点:商业软件
软件包管理系统:Xandros Networks (DEB) 或 APT (DEB) (可选,但不提供技术支持)
免费下载:公开发行版
官方主页:[url]http://www.xandros.com/[/url]

随心所欲04 Apr 2007 09:46 pm

        冲动了~~一夜没睡~~手写ajax rss2.0 reader
        最近比较容易冲动,这不昨天一冲动,研究了半天,晚上没睡觉,用js写了ajax的rss2的未化妆版的阅读器。本来是因为想找一个合适的yahoo widget用来read rss的,但是在网上找了很久都不如意,nnd,于是算了自己做一个吧。
        关键还是使用ajax的过程吧,后来才发现yahoo widget他有他自己实现fetch的过程,所以最后写出来的代码,还必须好好改造一下才能用在yahoo widget上面。
        正当发愁之际,想看看人家的yahoo widget是怎么写的,然后打开默认的my widget文件夹,找找自己感兴趣的widget研究一下,没想到竟然被我看到了rss reader。我的天啊!我怎么一开始没看到呢。适用了一下虽然只能订阅一个rss,但是还是挺漂亮的。于是放弃了把ajax迁移过来的想法。

       总结一下用ajax写rss reader
       下面就是样图,很朴素吧,呵呵 , 非常之土了,但是功能到了,如果一天以前的就会显示为以前的源,一天之内的会显示多少分钟之前的,自己可以设定多长时间重新获取。下面写的临时更新是我让他更新的时候打印出来给我看的,没有什么实际意义。

先是html页面

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>ajax测试</title>
<link href=”a.css” rel=”stylesheet” type=”text/css”/>
<script type=”text/javascript” src=”js/ajax.js”></script>
<script type=”text/javascript” src=”js/rss2reader.js”></script>
<script type=”text/javascript” src=”js/rssClass.js”></script>
<script type=”text/javascript” src=”js/display.js”></script>
<script type=”text/javascript”>
var requestUrl = “http://dongpingyuwen.blog.sohu.com/rss”
function iniPage(){
display.iniHolder(”holder”);
display.setTime(”time”);
if(initXMLHTTPRequest()!==null){
sendRequest(requestUrl,’1′,’GET’);
}
}
</script>
<meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″>
<meta http-equiv=”description” content=”this is my page”>
<meta http-equiv=”content-type” content=”text/html; charset=UTF-8″>
</head>
<body onload=”iniPage()”>
<div id=”time”></div>
<br/>
<div id=”holder”></div>
<br/>
<input type=”hidden” name=”hd” id=”hd”/>
</body>
</html>

//然后是负责异步的ajax核心代码,一般都是大同小异

var req = null;
var console = null;
var ie = false;
var READY_STATE_UNINITIALIZED = 0;
var READY_STATE_LOADING = 1;
var READY_STATE_LOADED = 2;
var READY_STATE_INTERACTIVE = 3;
var READY_STATE_COMPLETE = 4;

function sendRequest(url,params,HttpMethod){
if(!HttpMethod){
HttpMethod = “GET”
}
req = initXMLHTTPRequest();
if(req){
req.onreadystatechange = onReadyState;
try{
req.open(HttpMethod,url,true);
}catch(error){
alert(error);
}
req.setRequestHeader(”Content-Type”,”application/x-www-form-urlencoded”);
req.send(null);
}
}
function initXMLHTTPRequest(){
var xRequest = null;
try {
ie=true;
xRequest = new ActiveXObject(”Msxml2.XMLHTTP”);
return xRequest;
} catch (othermicrosoft) {
try {
xRequest = new ActiveXObject(”Microsoft.XMLHTTP”);
return xRequest;
} catch (failed) {
ie = false;
try{
xRequest = new XMLHttpRequest();
return xRequest;
}catch(error){
alert(error);
}
}
}
}
function onReadyState(){
var ready = req.readyState;
var xml = null;
if(ready==READY_STATE_COMPLETE){
var result = document.getElementById(’result’);
if(req.status==200){
xml = req.responseXML;
rss2Reader.fetchRss(xml,10000,true);
}
else{
result.value = req.status;
}
}
else{
data = “loading…[”+ready+”]”
}
}

//下面是自定义的保存rss节点信息的一些“类”和处理方法var rssClass = {};
rssClass.getChannelInfoInstance = function(channel){
var info = new Object();
var titleNodes = channel.getElementsByTagName(”title”);
var linkNodes = channel.getElementsByTagName(”link”);
var descriptionNodes = channel.getElementsByTagName(”description”);
var pubDateNodes = channel.getElementsByTagName(”pubDate”);
var generatorNodes = channel.getElementsByTagName(”generator”);
try{
if(titleNodes.length>0){
info.title = channel.getElementsByTagName(”title”)[0].firstChild.nodeValue;
}
if(linkNodes.length>0){
info.link = channel.getElementsByTagName(”link”)[0].firstChild.nodeValue;
}
if(descriptionNodes.length>0){
info.description = channel.getElementsByTagName(”description”)[0].firstChild.nodeValue;
}
if(pubDateNodes.length>0){
info.pubDate = channel.getElementsByTagName(”pubDate”)[0].firstChild.nodeValue;
}
if(generatorNodes.length>0){
info.generator = channel.getElementsByTagName(”generator”)[0].firstChild.nodeValue;
}
return info;
}catch(error){
alert(error);
return null;
}
};
rssClass.getItemInfoInstance=function(item){
var info = new Object();
var titleNodes = item.getElementsByTagName(”title”);
var linkNodes = item.getElementsByTagName(”link”);
var descriptionNodes = item.getElementsByTagName(”description”);
var pubDateNodes = item.getElementsByTagName(”pubDate”);
var commentsNodes = item.getElementsByTagName(”comments”);
var creatorNodes = item.getElementsByTagName(”dc:creator”);
var guidNodes = item.getElementsByTagName(”guid”);
try{
if(titleNodes.length>0){
info.title = item.getElementsByTagName(”title”)[0].firstChild.nodeValue;
}
if(linkNodes.length>0){
info.link = item.getElementsByTagName(”link”)[0].firstChild.nodeValue;
}
if(descriptionNodes.length>0){
info.description = item.getElementsByTagName(”description”)[0].firstChild.nodeValue;
}
if(pubDateNodes.length>0){
info.pubDate = item.getElementsByTagName(”pubDate”)[0].firstChild.nodeValue;
}
if(commentsNodes.length>0){
info.comments = item.getElementsByTagName(”comments”)[0].firstChild.nodeValue;
}
if(pubDateNodes.length>0){
info.creator = item.getElementsByTagName(”dc:creator”)[0].firstChild.nodeValue;
}
if(commentsNodes.length>0){
info.guid = item.getElementsByTagName(”guid”)[0].firstChild.nodeValue;
}
return info;
}catch(error){
alert(error);
return null;
}
};
rssClass.getTimeInstance = function(time){
var date = new Date(time);
var instance = new Object();
if(!ie){
instance.year = date.getYear()+1900;
}
else{
instance.year = date.getYear();
}
instance.month = date.getMonth()+1;
instance.date = date.getDate();
instance.day = date.getDay();
instance.hour = date.getHours();
instance.minute = date.getMinutes();
instance.second = date.getSeconds();
instance.zone = date.getTimezoneOffset();
return instance;
};
rssClass.getOffsetMinuteDescription = function(time){
var offset = rssClass.getMinutesByNow(time);
switch(offset){
case -1:return “无效时间:”break;
case -2:return “以前的:”break;
case 0:return “最新的:”break;
default:return offset+”分钟之前:”break;
}
}
rssClass.getCustomDate = function(time){
var t = rssClass.getTimeInstance(time);
return t.year+”年”+t.month+”月”+t.date+”日”+” “+t.hour+”时”+t.minute+”分”
}
rssClass.getMinutesByNow = function(time){
var date = new Date(time);
var current = new Date();
var result = 0;
var deltaYear = current.getYear() - date.getYear();
var deltaMonth = current.getMonth() - date.getMonth();
var deltaDay = current.getDate() - date.getDate();
var deltaHour = current.getHours() - date.getHours();
var deltaMinute = current.getMinutes() - date.getMinutes();
if(deltaYear < 0){
return -1;
}
else if(deltaYear==0){
if(deltaMonth<0){
return -1
}
else if(deltaMonth==0){
if(deltaDay<0){
return -1
}
else if(deltaDay==0){
if(deltaHour<0){
return -1;
}
else if(deltaHour==0){
if(deltaMinute <0){
return -1;
}
else{
result = deltaMinute + result;
}
}
else{
result = deltaHour*60+result;
}
}
else{
return -2;
}
}
else{
return -2;
}
}
else{
return -2;
}
return result;
}

//下面是负责解析rss的代码

 

var channels;
var first=true;
var rss2Reader={};
rss2Reader.fetchRss = function (xmlDoc,delay,timeEnabled){
if(delay>0){
if(timeEnabled){
display.setTime(”time”,”default”);
}
var root = xmlDoc.getElementsByTagName(”rss”)[0];
channels = root.getElementsByTagName(”channel”);
var oldItemDate = document.getElementById(”hd”).value;
var newItemDate = rss2Reader.getLatestItemDate(channels[0]);
if(oldItemDate!==newItemDate){
display.removeAll();
for(var i=0;i<channels.length;i++){
rss2Reader.decode(channels[i]);
}
}
else{
var div = display.appendDiv(”default”);
display.appendTextNode(div,”没有更新”,”default”);
}
window.setTimeout(”sendRequest(’”+requestUrl+”‘,’1′,’GET’)”,delay);
}
else{
var root = xmlDoc.getElementsByTagName(”rss”)[0];
channels = root.getElementsByTagName(”channel”);
for(var i=0;i<channels.length;i++){
rss2Reader.decode(channels[i]);
}
}
};
rss2Reader.getLatestItemDate = function(channel){
var channelInfo = rssClass.getChannelInfoInstance(channel);
if(channelInfo!==null){
return channelInfo.pubDate;
}
return null;
};
rss2Reader.decode = function(channel){
var channelInfo = rssClass.getChannelInfoInstance(channel);
if(channelInfo!==null){
display.setHiddenValue(channelInfo.pubDate);
var items = channel.getElementsByTagName(”item”);
for(var i = 0 ; i< items.length ; i++){
itemInfo = rssClass.getItemInfoInstance(items[i]);
if(itemInfo!==null){
var div = display.appendDiv(”defaultdiv”);
display.appendTextNode(div,rssClass.getOffsetMinuteDescription(itemInfo.pubDate),”default”);
display.appendLink(div,itemInfo.title,itemInfo.link,”default”);
}
}
}
};

//下面是用来显示在页面上的方法

var holder;
var display={};
display.iniHolder = function (holderid){
holder = document.getElementById(holderid);
if(holder===null){
alert(holderid);
window.alert(”Error while getting the holder!”);
}
};
display.removeAll = function(node,style){
var length = holder.childNodes.length;
for(var i = 0; i<length;i++){
holder.removeChild(holder.firstChild);
}
};
display.appendDiv = function (style){
if(holder===null){
window.alert(”Must you first initialize the holder!”);
}
var newDiv = document.createElement(”div”);
newDiv.className = style;
holder.appendChild(newDiv);
return newDiv;
};
display.appendTextNode = function (parentNode , text , style){
var newTextNode = document.createTextNode(text);
parentNode.appendChild(newTextNode);
return newTextNode;
};
display.appendLink = function (parentNode , text , link , style){
var newlink = document.createElement(”a”);
newlink.setAttribute(”href”,link);
newlink.setAttribute(”class”,style);
var newTextNode = document.createTextNode(text);
newlink.appendChild(newTextNode);
parentNode.appendChild(newlink);
return newlink;
};
display.setTime = function(holderid,style){
var holder = document.getElementById(holderid);
if(holder===null){
window.alert(”Error while getting the holder!”);
}
else{
if(holder.hasChildNodes()){
holder.removeChild(holder.firstChild);
}
var time = document.createTextNode(rssClass.getCustomDate(new Date))
holder.appendChild(time);
holder.setAttribute(”class”,style);
}
};
display.setHiddenValue = function(value){
var hd = document.getElementById(”hd”);
hd.value = value;
};

基本的逻辑是

1 在html里调用ajax的异步获取

2 将异步获取到的xml交给rssreader解析

3 rssreader将具体的每一个item以及channel信息,用具体的“类”rssClass来解析,并保存

4 rssreader将获得的数据调用display中的方法显示到页面上

 

由于是兴起而至,所以没有加注释 呵呵 敬请原谅

 

目前有一点碰到的问题

ajax有着很严格的安全性,是不能跨域的,比如说我在自己本机的tomcat里面架了一个网站,我的html是这个网站的一部分,我用localhost去访问时,如果这个时候xml源也是tomcat里面的另一个网站里的xml,那么没问题一切正常,但是如果我fetch的是internet上的源就不行了,无论是ie还是firefox都没有权限。

 

如果我们只是通过本地访问html文件,而不是通过网站访问,那么ie是可以的,但是firefox不可以。

这是很郁闷的一件事情不是吗?

网上提供了一个解决方法,就是在internet自己的站点上架一个servlet,然后去掉,自己对自己域内的有访问权限,然后由internet上的servlet对信息做中转,访问internet其他的信息源。

这种解决方案实在是哎 ~~ 欺负我们这种穷人啊。

 

自己写着玩的,首先健壮性肯定很弱的,呵呵,欢迎提出一些意见建议

随心所欲03 Apr 2007 07:00 pm

RSS是“Rich Site Summary”或“Really Simple Syndication”的英文首字母缩写,中文称作“简易信息聚合”。RSS是一种基于XML标准,在互联网上被广泛采用的内容包装和投递协议。

RSS技术诞生于1999年的网景公司(Netscape)。当时网景公司定义了一套描述新闻频道的语言,RSS,用于将网站内容投递到Netscape Navigator互联网浏览器中。但由于公司内部商务决策、当时互联网内容匮乏等诸多原因,网景最终只发布了一个0.9版本的规范。微软当时也推出了类 似的数据规格,与RSS非常接近,试图利用新闻频道的架构把“推”(Push)技术变成一个应用主流,捆绑在IE浏览器中与Netscape Navigator抗衡。不过无奈的是,由于当时互联网访问速度慢、内容缺乏、用户不熟悉等原因,这个“推”技术自始至终没有得到市场的广泛支持。

但是随着时间的推移,RSS技术随着XML技术的发展和博客群体的快速增长,逐渐被人们广泛地接受,其应用范围也已经跳出单纯的博客圈,成为新闻传媒、电 子商务、企业知识管理等众多领域的不可缺少的新技术。2001年,RSS技术标准的发展工作被戴夫·温那(Dave Winer)的公司UserLand所接手,继续开发新的版本,以适应新的网络应用需要。通过戴夫·温那的努力,RSS升级到了0.91版,然后达到了 0.92版,并随后被众多的专业新闻站点所接受和支持。在广泛的应用过程中,众多的专业人士认识到需要组织起来,把RSS发展成为一个通用的规范,并进一 步标准化。一个联合小组根据W3C新一代的语义网技术RDF对RSS进行了重新定义,发布了RSS 1.0版,并把RSS定义为“RDF Site Summary”。这项工作并没有与戴夫·温那进行有效的沟通,而戴夫则坚持在自己设想的方向上进一步开发RSS的后续版本2.0,同时也并不承认RSS 1.0的有效性。RSS由此开始分化形成了RSS 0.9x/2.0和RSS 1.0两个阵营。

戴夫·温那在2002年9月独自把RSS升级到了2.0版本,并交由哈佛大学法学院Berkman互联网和社会学中心进行维护。而RSS 1.0版则仍然由W3C联合小组维护。

最近,著名的互联网搜索引擎公司GOOGLE收购了美国大型的博客服务网站www.blogger.com, 使这个网站一直采用的一种近似于RSS的技术衍生版Atom一夜之间成为RSS领域标准之争的新的有力竞争对手。目前,这三个技术标准阵营(RSS 0.9x/2.0,RSS 1.0,Atom 0.3) 正在展开相互兼容的对话,相信在不久的将来会有积极的结果。

RSS 1.0和 2.0 格式所包含的核心信息相同,但其结构不一样。

RSS 1.0 的根元素是 rdf:RDF,而 RSS 2.0 的根元素是 rss。rss 还包含一个强制版本属性用以表示所用的RSS的准确格式(可能的值包括:0.91, 0.94 等)。另一个主要差别是 RSS 1.0 文档有名字空间限定,RSS 2.0 的文档就没有。不管怎样,包含在两个文档中的信息本质上是一样的。

两个版本都包含 channel 元素,而 channel 元素又包含三个必须的元素:title、description 和 link,其代码如下:

<channel>
<title><!– channel 的标题 –></title>
<description><!– 简要描述 –></description>
<link><!– channel 的 URL –></link>
<!– 可选/可扩展元素 –>
</channel>
除了这些必须的元素外,RSS 1.0 还定义了三个附加元素:image、items 和 textinput,其中,image 和 textinput 是可选的。另一方面,RSS 2.0 提供了 16 个附加元素,其中也包括 image、items 和 textinput,此外还有 language、copyright、managingEditor、pubDate 和 category。RSS 1.0 允许通过定义在单独的 XML 名字空间中的可扩展元素来创建这种类型的元数据。
这两种格式在结构上的主要区别必须要看其 item、image 和 textinput 节点的表示形式。RSS 1.0 中,channel 元素包含对 item、image 和 textinput 节点的引用,这些节点存在于 channel 节点本身之外。这样在 channel 和 所引用的节点之间建立了一种 RDF 关联。如 Figure 1 所示,channel 元素与一个 image 元素以及两个 item 元素关联。RSS 2.0 中,item 元素只是在 channel 元素中连续排放(如 Figure 2 所示)。item 元素包含实际的新闻项信息。item 的结构在两个版本中是相同的。item 元素通常包含 title、link 和 description 元素,如下代码所示:
<item>
<title><!– 项标题 –></title>
<link><!– 项 URL –></link>
<description><!– 简要描述 –></description>
<!– 可选的/可扩展的元素 –>
</item>
在 RSS 1.0 中,title 和 link 是必须的,description 是可选的。而在 RSS 2.0 中,title 或 description 必须提供其中的一个;其它均可选。这些只是定义在 RSS 1.0 中的 item 元素。RSS 2.0 提供几个其它可选元素,其中有 author、category、comments、enclosure、guid、pubDate 和 source。RSS 1.0 获取这样的元数据是通过定义在单独的 XML 名字空间中称为 RSS 模块的可扩展元素来实现的。例如,在 Figure 1 中,item 的日期是用 Dublic Core 模块的 <dc:date> 元素表示的。

有关不同格式的完整信息请参考 RSS 1.0 和 2.0 规范。

那么,何为 Atom?
Atom 乃一项目的名字,主要是开发一个新的网志摘要格式以解决目前 RSS 存在的问题(混乱的版本号,不是一个真正的开放标准,表示方法的不一致,定义贫乏等等)。Atom 希望提供一个清晰的版本以解决每个人的需要,其设计完全不依赖于供货商,任何人都可以对之进行自由扩展,完整详细说明。
当今许多 Blog 引擎已经支持当前的摘要格式。Figure 3 是一个Atom 0.3 提要例子,它与前述 Figure 1 及 Figure 2 RSS 提要等同。注意 Atom 提要用名字空间限定的,但它不使用 RDF。这使得 Atom 和 RSS 1.0 及 RSS 2.0 在某些地方有相似之处。Atom 在未来是否能被接受,人们拭目以待。
除了定义新的摘要格式之外,Atom 还希望定义一个标准的档案文件格式和一个标准的网志编辑 API(Atom API)。有关 Atom 详细规范以及其它 Atom 资源请访问 The Atom Project。

随心所欲14 Mar 2007 11:25 am

学生信息管理平台开发心得

 

这个项目的开发对我来说是一个极大的挑战。整个项目的复杂性对我来说还是第一次,而且自己的工作贯穿了整个软件开发的整个流程。在这个漫长的过程中也走了很多弯路,当然最后系统的顺利完成对我来说是个极大的欣慰和鼓舞。在这里我也把我整个项目的心得写下来。

 

开发软件是团队的工作

       企图一个人进行软件开发那绝对是件自虐的事情,除非那是个天才。

       开发工作不仅仅是写代码,还包括需求分析,软件设计,软件测试等,写代码也分为写前端(视图层),后端(业务逻辑层,数据持久层)代码,两者代码是截然不同的,前台使用的语言可能又包括htmljspjavascript等等。如此多的工作由一两个人完成,这的确是件很不容易的事情。

       所以在一个项目还是应该由一个项目组进行开发,在这个团队中每个人都会用所专长,首先必须有人能够有着较强的沟通能力、语言表达能力、耐性与客户进行沟通,并写成需求分析文档,并且需要与向团队中的每一个人介绍整个系统的应该要实现的功能,团队根据需求分析讨论出实现功能的最佳方法,然后必须有人熟悉将要使用在项目中的开发技术以及应用框架,并且有着类似的开发经验,由他对整个系统的开发进行框架构造,分清层次模块,以对团队其它成员进行分工。然后团队中熟悉对应工作的开发者专心从事于自己熟悉的工作。

       比如3个人是一个典型的小团队,那么这三个人之间也应该根据特长进行分工,首先应该定义好一个好的开发框架,定义好层次之间的接口,并由三个人分别予以实现,最后拼装在一起。那么对于软件工程流程中的分工,我认为可以共同进行需求分析,软件测试,软件设计工作。或者在编写代码时,其中一位开发者负责项目进程的控制以及软件测试。

       团队的开发工作是很有必要的,一个优秀的团队才能保证写出有质量的代码,有质量的软件项目。

 

写代码不能光靠脑子

以前写代码总是把思路都记在脑子里面,但是在做这个项目的时候,脑子的容量实在不够了,整个项目分为很多模块,而模块之下也有很多的子模块,模块与模块之间,业务逻辑层,视图层,数据持久层之间都应该存在有很多接口。

在一开始写管理活动模块时,考虑到这个模块接口及方法时就忽略了其他模块的接口方法或者其他功能在这个模块中的应用,导致在写的代码的复用性不强,不易于以后的修改。导致再定义该模块其他功能的时候必须重新写一段代码来实现新的功能。当一个模块中的方法定义很多时,整个模块的结构就会显得很杂乱。

在写管理奖学金管理模块时,虽然整个流程与活动模块的流程相近,但是由于整个模块过于复杂,使得脑子里面对于活动模块的整个结构很是杂乱,已经不能够将整个设计迁移到新的类似模块中。

所以在发现这个问题之后,就决定将整个活动模块重整了一遍,理清结构,接下来按照这个结构类似定义其他的几个模块,很明显开发这几个模块非常的迅速,而且不存在什么逻辑上的问题。

所以不要过分地相信自己的脑子,必须先有设计然后才可以进行编码,虽然之前增加了这么一个步骤,但是,非常有利于有效率的开发,有利于写出有质量的代码。

 

编码规范很重要

写了很多代码之后,出现了很多作用域不同的变量以及方法,再回头查看对变量以及方法的调用时,因为命名并不统一,比如管理活动信息模块以及管理奖学金信息模块中查看自己的列表功能,业务逻辑层所使用的页面文件一个是activity.jsp,另外一个是scholarship_home.jsp,很明显两个页面文件的文件名所表达的意义很难看出是一致的。另外有意个例子活动信息模块中的actapply.jsp,和奖学金模块中的schapply.jsp,从文件名的结构看,两个信息所展现的功能是一致的。如此定义才能方便后续的开发,重构工作,以及项目交付之后的维护升级工作。

特别是一个团队中每一个程序员的编码风格都是不一致的,而团队工作中程序员之间的工作是有交叉的,包括之后可能出现的程序员之间的工作顶替,或者日后的维护升级工作,整个项目所使用的编码会有很多风格,这样会很不利于后续的开发维护工作。

所以在一个团队形成之初,就应当定义一整套的编码规范,哪怕是一个人进行开发,都应该明确自己的编码规范,特别是命名标准。每一个成员都应当按照编码规范进行编码。

 

重构的是很有必要的

一次设计出完美的结构或者写出完美的代码,那是不可能的。在开发过程中,当发现现有的设计已经不满足后续的开发需求,或者设计明显存在不合理之处。在这个时候就必须对代码进行重构。

不要舍不得之前写代码花费的精力,之间的过程只不过是给自己增加一段新的反面经验。对代码进行重构之后,将会很有利于后续的开发。有利于给系统形成一个良好的体系结构,这样也有利于性能的控制。

重构的过程同样也是对代码进行进一步检查的过程,在这个过程中,可以发现一些新的不合理的地方,进一步减少系统发生错误的可能性。

 

项目的开发计划很重要

一个项目不是几天就能开发完毕的,整个开发过程一定要有一个好的计划,第一步做什么,第二步做什么。比如a模块需要定义接口123b模块需要定义接口456,在开发过程中应该要避免按照自己的意愿顺序定义这一批接口,不能想到哪就做到哪,如果是这样进行操作,很有可能遗漏了某个接口的定义。而且如此安排即脑子里面没有好的设计模式,结构杂乱,当然不能写出一个高质量的接口。

所以在项目的开始即应该制定详细的开发计划,在每一个子模块开发之前也应该针对子模块中的逻辑制定详细的开发计划。在开发过程中,严格的按照开发计划进行定义。这样才能够有效率地进行开发。

 

 

写代码之前一定要有一个好的设计框架

       在开发一个项目的过程中,最好的参考资料不是成堆的技术图书,而是一个良好的设计文档。

在一个项目中最重要的应该是这个设计框架,或许一个小规模的项目,不需要重构或者制定详细的开发计划而避免增加开发的成本。但是一定要有一个好的设计框架。

比如整个系统的层次分割,模块的划分,层次之间的接口,模块之间的调用,这些都是应该在设计中体现的。这些也是进行团队分工的基础。根据框架定义好接口之后,就可以将工作分给团队中其他的成员开发。一个好的框架有利于制定项目的开发计划,以及测试计划。这样才能够进行有效率的团队开发。

设计文档也是节省脑力活动的重要工具。

比如上面一例中,相同功能的模块的开发,有了设计文档之后,用户不必在脑子中记住整个模块的结构,而当开发第二个模块的时候只需要查阅设计文档,就能够快速地开发出新的模块,甚至,开发完第一个模块之后,完全能可以交给另外一个成员开发,这个成员只需要查阅设计文档,就可以了解到第一个模块中使用的设计结构,再进行快速的开发。

 

要设计好一个系统必须有足够的经验和知识

自己曾经尝试着使用Google Web TookitGooglejava程序员开发的一套实现ajax的框架)做了一个版本的学生信息管理系统。但是开发完之后,发现这个设计非常得杂乱,自己再需要对某个模块的功能进行修改的时候,显得非常得复杂。性能也不高,页面也不够友好。原因是自己对gwt框架并不是很了解,只是一个新手,而且gwt是新出的开发工具,还没有足够的开发类的文章供参考,更多的需要自己去探索。一个新手拿自己并不熟悉的工具来开发一个具有一定规模的系统很明显是力不从心的。

当时对mvc三层架构的设计模式并不是很了解,对于ajax技术也只是略知皮毛,结果并没有将ajax的长处发挥在异步数据传输上,更多的只是客户端的javascript的应用。所以第一版本整体被自己否决了,浪费了很多宝贵的时间。但是也增加了一个教训。

于是在新版本的系统中,我选用Struts。虽然在开发初期,对于Struts并不是很了解,但是因为Struts已经十一个非常成熟的框架了,有很多的资源可以参考。于是我利用了一段时间迅速入门,并投入开发,开发的过程中,为了增加客户端的体验,我还迅速学习了javascrpit以及css

在对struts以及jscss有一定了解之后,眼前逐渐明朗起来。整个开发的结构也逐渐浮出水面。

所以要设计好一个系统必须要有足够的经验和知识。

 

 

本次srtp经历对我来说的确受益匪浅。所获心得我也必将使用在以后的项目之中。

 

秦岭

2007-3-12

随心所欲14 Mar 2007 11:24 am

    准备了很久的Srtp项目,昨天第一批三个组结题,排在最后一个答辩,不过最后是优秀,还是比较欣慰的。毕竟自己还是付出了很多的。听闻05级的同学正在为此事头疼,所以发此文分享一些经验。
申请的有两个级别,一个是校srtp项目,一个是院级的课外研学项目,二者形式基本一样,也都能拿到学分,不同的是校级的项目学校在最后应该都会有资金 的包销,而 院级项目还要“争取”。申请的时候,填写都是一样的申请,申请提交给院里之后,院里要经过筛选,将一些有价值,有新意的项目报给学校作为校级的SRTP项 目,而所申请的资金不是都能批下来的,一般什么什么系统之类的一个组能批下300-400元,但是这些钱不是一开始就给项目组的,是要在最后项目组凭发票 报销的,所以开发过程中,一定要注意保留原始发票,特别是一些打印的材料,交通费这些。而书籍有一种说法是如  果你要包销,书就要上交,这个说法尚未得到证实。
我以我本人为例,一开始申请的时候,申请了一个什么教室资源管理系统,结果给  了一个院级项目,说实话这个项目的题目实在是不怎么新颖,所以只能留在院里。不过 后来我自己把题目改掉了,改成了自己比较了解的学生工作范畴的“学生信息管理平台”,但是这个时候已经不能再申请了,只能留在院里面作为课外研学项目了, 也就是有可能得不到资金的。
这就涉及到了开题的问题,很多人盲目开题,在自己没有任何开发经验或者技术储备的情况下,不做任何的可行性及复杂度分析盲目开题。从我们这一届的情况 看,申请审批下来的项目,特别是校级项目里面有不少题目感觉很不错,很有难度,但是看看做的人,于是就对这个项目不报什么信心了。
选题非常重要,个人认为要注意几点,各位后来者在确定自己题目的时候一定要问自己以下几个问题
1.我的这个项目有没有实用价值
2.这个项目针对哪些用户群体
3.对于这些用户群体他们目前在用什么样的系统
4.他们目前用的这套系统和我们要开发的系统相比,我们到底胜出多少,或者说我们到底能改善多少使用的便利,或体验
我有一个案例,有个小组开发了一套也是面向辅导员服务的系统,在这套系统中提供了学生成绩管理,课表查询,还有其他的小功能比如计算器,万年历这些。在 老师评审的时候直接指出了目前的教务处的系统已经为辅导员提供了这个服务,而且这个服务已经很成熟了,如果没有很大用户使用,安全性,整体性能上的提高的 话,根本没有必要再做这么一套系统,另外一个系统要做专,你可以只包括一个成绩管理,就叫学生成绩管理系统,那你就必须把这一块做专,不要以为这个很简 单,在做这么一套系统的时候要充分考虑到这套系统对于以有系统的创新点和优势,以及整个系统的特殊要求,比如说安全性。为什么难?主要还是因为目前已经存 在的系统已经很成熟了,想超越他,一个字——难。
另外就是你既然把课题定向为面向辅导员服务,那你得好好想想这些人群到底最需要什么,虽然说做需求分析很麻烦,但是个人觉得还是很有必要的,一个辅导员 目前可能对学生的动态情况想有一个好的把握,比如学生的缺勤情况,参加过活动的情况,是不是应该找个时间跟学生交流交流(日程安排)等等等等,所有这些都 是目前还是空白的地方的。所以要知道那些地方是空白,问问你的系统定向的人群。
关于所使用的技术,我也谈一些
我的项目做了两个版本,之前使用的是Ajax的框架GWT,但是因为GWT是一个新家伙,网上的参考资料,开发的经验都少,所以自己边做边研究,结果做 出来整体的感觉很不好,而且在功能上还有一些定位错误,于是在做好之后忍痛割爱,pass掉了,最后结题的时候用到的技术/知识主要是JSP (JSTL),Struts,Javascript,XML,Dom,CSS。刚才这几项都是目前都很成熟的技术,如果你还不是很了解,我稍微解释一下 jsp不用说了吧,关于JSTL,在写JSP的初期阶段,每个人都在页面里面写过Java代码,但是要知道,这样是很不好的,如果你了解HTML,那你就 应该知道里面其实都是成对的标签比如<html></html>,<td></td>等等,而如果我们 直接写了Java代码,那就破坏了这样的结构,在维护起来就非常不方便,另外很重要的一点,就是如果这么些那么你的层次就非常的不明确,你可能在jsp里 面直接写从request里面获取attribute,然后作判断,再作处理,但是要知道这样该属于业务逻辑,不适合出现在页面里面,而JSTL就可以解 决这些。关于Struts,是目前J2EE的一个轻量级的框架,很成熟,可以用它来负责业务逻辑层,表现层,网上有很多资料,经常用来和这个相配合的是 Spring 和 Hibernate,Spring负责逻辑层,Hibernate负责数据持久层。
JavaScript这个家伙这两年已为Ajax的流行而开始转变名声,之前JavaScript经常用来做一个花俏的菜单,放一个时钟,或者在状态栏 变换文字等等,而现在JavaScript已经成为改善用户客户端体验的重要工具,目前的ajax技术全程就是异步的JavaScript and XML,使用Javascript在客户端页面局部修改,使用XML进行数据异步传输,使得用户就像在使用一个桌面应用程序一样。Dom全称是文档对象模 型,对于一个html来说可以利用DOM来解析他,得到HTML的每一个结构,用Javascript调用dom,就可以动态的修改页面上的东西,比如当 我正在填一个表单,当我填完一项,文本框失去焦点的时候,客户端自动对所填的格式进行验证,这个时候只要在textbox的onblur属性里面调用已经 定义的javascript函数,在函数中使用dom来获取这个文本框的引用然后进行格式验证。所谓CSS就是样式表,我在css里面定义了很多样式,然 后在写jsp的时候就直接使用这些样式,很重要的!
以上就是我自己用到的技术。当然这是J这一头的,相信肯定有人使用.net,我自己也不是很熟悉,就不说什么了。
不管你使用哪种技术,哪怕你现在什么都不会,都来得及。当然不要拖到最后。
如果你的项目是定位于将目前已有的系统使用新的技术进行重新架构。那就应该考虑到使用目前比较流行的框架,或者改善客户端体验(Ajax)。
在这里我说一下Ajax,Ajax这两年因为google而火起来,其实是新瓶装老酒。Ajax也是web2.0中的主要力量。上面提到过使用Ajax 就好像使用本地的桌面应用程序一样。使用过Gmail,163,yahoo等邮箱的同学都能有所体验。就好像在控制自己及其里面的程序一样。要想有更多的 体验,你可以多访问google的一些东西,Google Map(百度也有了),Gmail,还有个性化主页等等,利用Ajax可以轻松的实现拖拽等功能。比如一个注册表单,我们都有这么一个经验,我们申请一个 用户名,还要判断一下有没有已经注册了,那我们得把注册停下来,单击一个检察按钮,然后等他的返回结果,如果我们使用了Ajax,我们不必停下来,只要继 续填写,Ajax会利用异步传输,得到结果返回在页面上。
在以下的几个技术里面从左到右,与常规的桌面应用程序的相似度依次提高            php,asp,jsp->>Struts->>JSF,Shale->>Ajax
而目前还有一个很热门的Ruby,Ruby on Rails对Ajax的支持特别的好(虽然我自己没做过,都这么说),能够很方便的开发出Ajax的系统。如果你不懂JavaScript怎么办,现在有 很多框架,比如我所使用的GWT,是google出的可以在code.google.com下载到。这个框架是给java程序员的。你只要写Java就行 了,框架会自动生成js,还有很流行的一个框架是DWR也是给java程序员的,另外网上还有很多ajax的标签,可以用来改造现有的系统,有兴趣也可以 去看一下。用.net的也不要急,微软毕竟是大牛,他有他自己独特的东西叫ATALAS,微软的人叫它为阿塔拉斯,在微软的网站上可以下到,中文的教程目 前只有一本。

定位到用户的角色
现在说说这点,就是做项目的时候要充分考虑到用户的角色,也就是说你的使用必须方便,必须傻瓜化,任何人都能够使用,而不仅仅是计算机/软件专业的人, 你不可能让用户写一条sql语句添加一条新的纪录。所以整个系统必须考虑完整了。再举上面那个案例,成绩管理,课表查询,难道让辅导员自己往里面输课表 吗,这是明显很不现实的事情。再者如果想优秀的话,你的使用说明书也要写好噢。
关于IDE的使用
j的当然首推Eclipse+Myeclipse了,当然如果你时间足够的话,想多学一点可以直接用Eclipse,然后自己到相应的网站上去下开发包,自己配制。
.net的显然vs2005,其他的就不谈了。

补充一点,就是测试的环境,BS的结构一定要试一下Firefox,IE6,和IE7,这三者对W3C的标准都有不同的支持。所以自己好不容易定义出来的页面极有可能,换一种浏览器就乱七八糟了。

下面给大家推荐J方向的几本书
JSP:Beginning JavaServer Pages (Wrox-人民邮电出版社) 中文(JSP高级程序设计)55rmb   还有一本初级的(jsp程序设计)。
Struts:Struts In Action (Struts实战),Struts基础教程(Apress-人民邮电出版社)45rmb
CSS:CSS Mastery Advanced Web Standards Solutions 精通CSS(Apress-人民邮电出版社) 39rmb
Ajax:Ajax in Action(Ajax 实战) Manning-人民邮电出版社 69rmb, Ajax基础教程 Manning-人民邮电出版社 ,Atalas基础教程 人民邮电出版社
Javascript宝典  太贵了 99好像

随心所欲09 Feb 2007 05:01 pm

/**opacity.css
*Version :20070207.0010
*Author :TopBlack
*Email :qinling@live.cn
*/
.opac0{
opacity:.0;
filter:alpha(opacity = 0);
}
.opac1{
opacity:.2;
filter:alpha(opacity = 20);
}
.opac2{
opacity:.4;
filter:alpha(opacity = 40);
}
.opac3{
opacity:.6;
filter:alpha(opacity = 60);
}
.opac4{
opacity:.8;
filter:alpha(opacity = 80);
}

 

/**opacity.js
*功能:执行渐入渐出
*函数:渐入 opacity([element id])
*版本:20070207.0010
*作者:秦岭
*Email:qinling@live.cn
*/
var time =100;
var acc =10;
var inId = 0;
var outId = 4;
function opacIn(elid){
var opac = inId;
var el = document.getElementById(elid);
var oldStyle = el.className;
el.className = oldStyle +” ” +”opac”+opac;
var args = “(\”"+elid + “\”,\”" +oldStyle + “\”,” +(opac+1)+”,”+(time-acc)+”)”
window.setTimeout(”setOpacIn”+args,time);
}
function setOpacIn(elid,oldStyle,opac,time){
if(opac>outId)
return;
var el = document.getElementById(elid);
el.className = oldStyle +” ” +”opac”+opac;
var args = “(\”"+elid + “\”,\”" +oldStyle + “\”,” +(opac+1)+”,”+(time-acc)+”)”
window.setTimeout(”setOpacIn”+args,time);
}
function opacOut(elid){
var el = document.getElementById(elid);
var oldStyle = el.className;
var opac = outId;
el.className = oldStyle +” ” +”opac”+opac;
var args = “(\”"+elid + “\”,\”" +oldStyle + “\”,” +(opac-1)+”,”+(time-acc)+”)”
window.setTimeout(”setOpacOut”+args,time);
}
function setOpacOut(elid,oldStyle,opac,time){
if(opac<inId)
return;
var el = document.getElementById(elid);
el.className = oldStyle +” ” +”opac”+opac;
var args = “(\”"+elid + “\”,\”" +oldStyle + “\”,” +(opac-1)+”,”+(time-acc)+”)”
window.setTimeout(”setOpacOut”+args,time);
}

随心所欲04 Feb 2007 07:35 pm

1 这个世界不存在“永远“
2 任何事情都能被时间改变
在这个世界上没有绝对,没有什么永远,或许这句话本身就是有问题的,因为我把上面两句作为“绝对“的真理。
不要轻易说永远,如果你是一个负责任的人,一旦说了一个永远,那么会是一个很深的伤害,或是很重的包袱。
不要说永远恨谁,电视上总会有这样的安排,女主人公在一开始会说永远怎样怎样,而最后还是……
不要说永远爱谁,特别是男生,已经广有帖子说男人们从来不守信用……
永远不如一生。
一生一世的爱人,一生一世的亲人,一生一世的朋友。
即便是一生也是很沉重的。
因为我还坚信任何事情都能被时间改变。
海枯石烂,山无棱,天地合,多么得轰轰烈烈,也多么得不可能。
如果这一切都会成真,当然我相信总有一天会这样,因为这是地球所注定的,那只是时间的事情。
我们所认识的世界尚且如此,我们人又能如何,人的感情,人的所有事情又如何。
当我们遇到困难的时候,加油,不要放弃,时间可以改变一切,如果自己努力了,那么等待成功的时间会短一些,如果不努力,那么成功的概率……
也有些东西有时候不得不放弃,总觉得自己会痴痴地继续,但是几年之后再回头看吧。
所以不要陷在脚下的烂泥中,抬起脚来,大胆地放下,往前走。
或许有些东西是需要自己坚持的,个人觉得,走一步是一步吧,对于自己正在努力的而又暂时看不到终点的时候,我不喜欢去幻想终点,不要把自己陷在将来的困境中。好好做好手中的事情。
我想对自己,也对朋友们说,加油吧!为了自己的理想,为了自己的目标,为了自己的动力,加油吧。
对于一个人来说,除非真的到了人生命结束的那一刻,一切皆有可能!

随心所欲01 Feb 2007 08:41 pm

最近的一些事情还有老爸的一些事情让我又了解到了一些世事。

做人难啊。处事难啊。

很多时候真的要靠自己。

记不得什么时候在哪里看到的,人这一辈子成功与否就在于结识几个人,说实在的这句话是挺有道理的,伯乐的重要性也在于此。

加油吧。

随心所欲31 Jan 2007 07:48 pm

1小时候放电视连续剧《神探亨特》和《流氓大亨》,院儿里一个老奶奶说:“今天晚上演《大流氓亨特》。”。。。。。。
2 一不熟的同事和我聊天,聊的内容无聊至极,,净讲他和他女朋友怎么啦,怎么啦
 我无言以对,,,,待他讲了半天之后,看着我,,,,意思可能是,他说这么多,我总该表表态吧,,,,
 一瞬间,,实在不知说什么,,脱口竟然问了一句:你女朋友是女的吧?
 自己暴寒半天!!!!
3 初中时候老师讲古巴比伦文明的时候,讲到苏美尔人,历史老师一激动讲成“还有两河流域的舒而美人”,当场笑晕一大半
4 一起买锅盔吃,某男的上前:老板,来两个钢盔!
  (牙好,胃口就好,吃嘛嘛香。。。)
5 高中时班上有个同学叫黄家健
  某天上课没有到 老班进教室后见他座位空着
  就问了一句:夷,黄家健 人呢?
  全班大笑 以后都叫他黄家贱人。
6 以前考试老师发卷子,后边的女生多拿了一张,高呼“老师,我有了,我有了”结果坐他旁边的男生说道“是我的,是我的”全班爆寒~~~
7 两年前在厂里干,一天我跟我师父(其实就比我大1岁)去分厂办事,材料员是个四十多数的大姐,姓董.办完事,我师父十分有礼貌,想说:董姐,走了啊.结果说出来成了:“懂了啊.“
  8 ~还有一次,我去买早餐,排队时发现平时不苟言笑的老板也在排队,于是非常紧张,打过招呼后,鼓起勇气对厨师说:“师傅麻烦来一杯包子,两个奶〈!–>子!”~
  ~~~~呜~~ 两年来第一次听老板笑那么大声~~~郁闷~~~
  9 朋友小孩半岁了,打电话去关心,寒暄了两句后,来了一句:你的小孩现在是吃人奶还是你的奶
  10 有一天傍晚,碰到个熟人,开口就说:“早啊“…
  11 晚上,一室友进屋大声宣布: “今天我看午夜版的美国凶铃了!“
  12 那天去买西瓜,听见有人在问卖瓜的:你的西瓜有皮吗?
  13 一农民在场院里晒麦子,几只鸡来啄食,农民扫,鸡挠,再扫再挠,忍无可忍,大骂:“你们这些坏东西,我挠挠,你扫扫,我挠挠,你扫扫。”
  14 一天去逛街,尿急,发现前方一网吧,冲进门去对着网管大喊:你们这个茅房的厕所在哪~?
  15 在食堂买饭,看到了心仪以久的豆腐皮,一激动和服务员说,来一份土豆皮,把周围人都惊呆了.
  16 由于一次出差机会,要去某地的中国银行维修设备,从宾馆出来做上出租车后对女司机说:“去中国银行、顺便找一家五金店买把刀”汗!当时我的意思是买把螺丝刀,我没注意到我说错了,这时那个女司机一直看着我非常委屈的说:“大哥我要下班了,你重新打辆车吧”。当时我就非常生气,恶狠狠的说:“你要下班了在宾馆泊什么车呀!?”女司机看了看我快要崩溃的说:“大哥那买完刀我不要车钱了你再找辆吧”晕!!!这才知道我说错了,赶紧解释了半天,现在想一想都感觉对不住人家女司机。
  17 政治老师有一次讲课的时候说:“下面我举个比方”,然后觉得不对,又说:“打个例子”
  18 记得《汉武大帝》里面
  张骞从西域回来,带来的炼铁新材料
  炼出来一柄好剑,刘彻拿来给李广
  李广不停的重复:
  陛下,好剑(贱),陛下,好剑(贱)阿 ……
  无语……
  19 真是好驴当做心肝肺
  20 初中的时候,老师叫翻译Who is this man ?
  一同学翻译:这是谁的男人?全班大笑,老师无语
  21 上次去麦当劳,对营业员说:来一包薯片,人家说没有。我说,什么店啊连薯片都没有,说完转身就走了。。。
  22 期中考试,偶后面的女生桌上有个裤子形状的笔袋,我一回头,笔袋掉了,我说:“MM你裤子掉了”
  23 记得路遇一犬,旁MM惊讶的大叫:呀,那个尾巴没有狗!!
  23 晒阳太屁股
  24 记得小时候去买玩具枪里装的圆形塑料子弹,直接对玩具店里的老爷爷说:买一包原(圆)子弹!
  25 同学向我解释如何拨打某查询电话。
  我想问问那边接电话的是真人还是语音,竟说成了:“接电话的是活人还是死人呀?”
  26 拎着好多东西和gg在火车站找存包的地方。
  迎面来一巡警,gg立刻上前很客气地问:“请问埋包处怎么走?”
  27 政治课时谈到中日政治问题,扯阿扯说到日本武士剖腹自杀。
  老师介绍说:“日本武士死前都剖腹产的~~~”
  28 有一次找一位姓王的客户打电话,总机接电话的是一个声音很甜的MM,她告诉我他的分机号,我不知道我要找的这位姓王的是男是女,我就顺便问了一句“请问他是男先生还是女先生?”
  29 大学时期,我一同学刚买了手机,办了移动卡,打1860人工台询问,一时激动:请问你们的地感动带业务。。。,从免提中我们竟然听到话务员小姐客气的说:我们的地感动带业务。。。全宿舍暴笑
  30 大三那年十一我同学去卖鱼的商场打工。客人拿了挑好的鱼,我同学很温柔地指着杀鱼台对他说:
  “你过去,有人会把你杀掉。。。”
  31 昨天有个人说要给我介绍一个女朋友,我本来想问“漂亮吗”,结果说成“便宜吗”。汗死自己!
  32 老师嘱咐我们:“春游坐车时老实点,别总把头和胳膊扔出去。。。”
  33 我老公特别瘦,有次我急了就说道“老公,看你瘦的象猪似的!”
  34 有一天去天津比较出名的大桥道食品店买吃的。差不多每次都要买老婆饼吃吃!结果那天我看到新出了一种稍微小一号的饼,样子基本一致,可是我不确定,于是向售货员阿姨发问:“这个是小老婆饼吗??”
  结果全场白眼
  35 表姐家开幼儿园,有一次她有急事,要我去帮她照顾那些小孩1小时,做游戏讲故事什么的。头一次面对十多个小孩,太紧张了,舌头打结:“小朋友,今天阿姨给你们讲一个“阿拉灯”的故事(阿拉丁和神灯)………”
  36 凹出来
  凸进去….
  37 播音稿原文:两歹徒打伤我110干警后逃窜
  播音员读成:两歹徒打伤我一百一十名干警后逃窜
  (黄飞鸿转世??!)
  38 我上高中的时候和我弟弟一个班,他就坐在我后面
  一天晚上我们地理老师问我们:
  你们谁是姐姐?谁是弟弟?
  当时我就呆掉了
  39 一次买凉皮回宿舍后,去别的宿舍溜了一圈,回来发现舍友在吃我的凉皮。
  她们见我回来,其中一人对我说:你怎么才回来?凉皮都凉了!
  40 那天想喝汽水,赶几步朝冷饮摊想说来瓶汽水,不料看见跟前放着的啤酒,一急竟说:“老板,来一瓶屁水”,老板………………
  41 刚才一同事看报纸问了句“昨天中国队一比几赢的?”
  中国就一了,新加坡怎么也出不来负数吧
  42 以前红白机上有个游戏叫《荒野大镖客》,欧们一般都叫它《荒野大嫖客》
  43 有个解说员:冲出亚洲、冲出世界!
  44 有一次,我和老公吵架,他骂我:“猪!”我骂他:“你是猪的老公。。。”骂完真觉得自己是猪。
  45 我们一个同事,他去考驾照时,对考官说了一句经典的话:
  报告仪表,,考官正常~~~~~~<
  46 记得有一次,和一姐们儿去KFC,排队的时候我听她口中念念有词,一个鸡腿汉堡,一对鸡翅……,好不容易轮到她了,一开口就笑翻了所有人,她本想说“小姐,来个鸡腿汉堡”,可话到口中竟成了“小腿,来个汉堡”
  47 大学同学在森林公园聚会,时间到了大家准备开饭,俩男生自告奋勇去小卖部买啤酒。班长想提醒他们买啤酒买易拉罐的,可能由于刚才一直在聊国际时事,班长站起来喊:“啤酒要伊拉克的啊~~~”
  我们全倒了,俩男生疯了。。。
  48 MM告诉我肯德基新出的“骨肉相连”(肉串有脆骨),要我带她去吃,那几天北京巨热无比,我昏昏沉沉,到了餐厅,我对微笑的肯德基小姐来了句:请给我两个“血肉模糊”,谢谢!………….
  无地自容-_-!
  49 平时工作一直很忙,情人节,下班比较晚,急匆匆的去买花,老婆在家做饭等我,打来电话,问我什么时候回家,我骗老婆说,还要很久,听到她不是很高兴的挂了电话,我心说,给你个惊喜……,买了花,又匆忙去买巧克力,又匆忙去打车,很久打不到,终于找到车,到家,匆忙上楼,悄悄开门,看到老婆在厨房,心里一阵温暖,一下,蹦过去,举起花,有些颤抖且深情的跟老婆说……
  ……圣诞快乐!!!!!!
  50 唉,又把键盘都喷到水里了。。。
身边的一些事
我一哥们给她客户打电话,那女的姓高,我哥们打完电话问了一句,你是哪个高呀,也不知道那女的当时想啥呢,来了一句:高潮的高嘛!我哥们当时一句也说不出来了,暴寒,最后呆了半天来了一句:我知道了!!(估计那女的也巨不好意思吧)
小学有一女同学姓甄单字爽,其实这也没啥,重要的是她班有一男同学姓朴叫已回,后来同学们就这样叫:嫖一回,真爽。(这些学生从小就是栋梁之材呀)
有一次和我男朋友说话,急了,我骂他一句:你老婆婆的。他回我一句:你老婆婆的。(当时我那个乐呀,一直让他再骂我一句。气死他了,哈哈)

随心所欲31 Jan 2007 02:54 pm

这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:
  问题一:
  使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?
  我很早前就发现Unicode、Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但这些标记是基于什么标准呢?
  问题二:
  最近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。
  查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。
  0、big endian和little endian
  big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian。
  “endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。
  我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
  1、字符编码、内码,顺带介绍汉字编码
  字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。
  GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。
  GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。
  从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。
  有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。
  这里还有一些细节:
  GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0。
  在DBCS中,GB内码的存储格式始终是big endian,即高位在前。
  GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析:在读取DBCS字符流时,只要遇到高位为1的字节,就可以将下两个字节作为一个双字节编码,而不用管低字节的高位是什么。
  2、Unicode、UCS和UTF
  前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。
  Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是”Universal Multiple-Octet Coded Character Set”,简称为UCS。UCS可以看作是”Unicode Character Set”的缩写。
  根据维基百科全书(http://zh.wikipedia.org/wiki/)的记载:历史上存在两个试图独立设计Unicode的组织,即国际标准化组织(ISO)和一个软件制造商的协会(unicode.org)。ISO开发了ISO 10646项目,Unicode协会开发了Unicode项目。
  在1991年前后,双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode2.0开始,Unicode项目采用了与ISO 10646-1相同的字库和字码。
  目前两个项目仍都存在,并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode 4.1.0。ISO的最新标准是10646-3:2003。
  UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-7、UTF-16。
  IETF的RFC2781和RFC3629以RFC的一贯风格,清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet Engineering Task Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。
  3、UCS-2、UCS-4、BMP
  UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节(实际上只用了31位,最高位必须为0)编码。下面让我们做一些简单的数学游戏:
  UCS-2有2^16=65536个码位,UCS-4有2^31=2147483648个码位。
  UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行 (rows),每行包含256个cells。当然同一行的cells只是最后一个字节不同,其余都相同。
  group 0的plane 0被称作Basic Multilingual Plane, 即BMP。或者说UCS-4中,高两个字节为0的码位被称作BMP。
  将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节,就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。
  4、UTF编码
  UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:
  UCS-2编码(16进制) UTF-8 字节流(二进制)
  0000 - 007F 0xxxxxxx
  0080 - 07FF 110xxxxx 10xxxxxx
  0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
  例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。
  读者可以用记事本测试一下我们的编码是否正确。
  UTF-16以16位为单元对UCS进行编码。对于小于0×10000的UCS码,UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0×10000的UCS码,定义了一个算法。不过由于实际使用的UCS2,或者UCS4的BMP必然小于0×10000,所以就目前而言,可以认为UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案,UTF-16却要用于实际的传输,所以就不得不考虑字节序的问题。
  5、UTF的字节序和BOM
  UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?
  Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:
  在UCS编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。
  这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作BOM。
  UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
  Windows就是使用BOM来标记文本文件的编码方式的。
  6、进一步的参考资料
  本文主要参考的资料是 “Short overview of ISO-IEC 10646 and Unicode” (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。
  我还找了两篇看上去不错的资料,不过因为我开始的疑问都找到了答案,所以就没有看:
  ”Understanding Unicode A general introduction to the Unicode Standard” (_id=nrsi&item_id=IWS-Chapter04a”>http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a)
  ”Character set encoding basics Understanding character set encodings and legacy encodings” (_id=nrsi&item_id=IWS-Chapter03″>http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03)
  我写过UTF-8、UCS-2、GBK相互转换的软件包,包括使用Windows API和不使用Windows API的版本。以后有时间的话,我会整理一下放到我的个人主页上(http://fmddlmyy.home4u.china.com)。
  我是想清楚所有问题后才开始写这篇文章的,原以为一会儿就能写好。没想到考虑措辞和查证细节花费了很长时间,竟然从下午1:30写到9:00。希望有读者能从中受益。

Next Page »