堆排序在最坏的情况下,其时间复杂度也能达到O(nlogn)。相对于快速排序来说,
这是它最大的优点,此外,堆排序仅需要一个记录大小供交换用的辅助存储空间。
堆排序的数据结构是二叉堆,二叉堆的特点有两个,一个是它是一棵完全二叉树,
另一个是它的根结点小于孩子结点,所以我们很容易找到它的最小结点----根结点;当然
如果你想找到最大结点的话,那就要扫描所有的叶子结点,这是很费时间的,如果你想找的
是最大结点的话,你最好把它弄成一个大顶堆,即一棵根结点大于孩子结点的完全二叉树。
二叉堆通常用数组来实现,它舍弃下标0,从下标1开始置数,则很容易满足,对于数组
中任意位置i上的元素,其左儿子的位置在2i上,右儿子的位置在2i+1上,双亲的位置则在
i/2上。
堆排序的算法之一是把数组构建成二叉堆----这只要增添一个长度为n+1的辅助空间,
然后把原数组的元素依次插入到二叉堆即可。然后删除二叉堆的根,把它作为排序后的数组
的第一个元素,然后使二叉堆的长度减1,并通过上移使得新得到的序列仍为二叉堆,
再提取新二叉堆的第一个元素到新数组。依此类推,直到提取最后一个元素,
新得到的数组就是排序后的数组。
template
void Insert(T a[], int len, T x)//把x插入到原长度为len的二叉堆,注意保证新二叉堆不越界
{
int i;
for (i=len; i/2>0 && a[i/2]>x; i/=2)
a[i] = a[i/2];
a[i] = x;
}
template
T DeleteMin(T a[], int len)//删除二叉堆的根,并通过上移使得新得到的序列仍为二叉堆
{
if (len == 0)
exit(1);
T min = a[1];//二叉堆的根
T last = a[len--];//二叉堆的最后一个元素
int c;
int i;
for (i=1; i*2<=len; i=c)//把二叉堆的某些元素往前移,使得新得到的序列仍为二叉堆 { c = i * 2;//i的左儿子 if (c != len && a[c+1] <> a[c])//若i的小儿子小于二叉堆的最后一个元素,把其移到i的位置
a[i] = a[c];
else
break;
}
a[i] = last; //把二叉堆的最后一个元素放到适当的空位,此时得到的序列仍为二叉堆
return min;
}
template
void HeapSort(T a[], int len)
{
T *ca = new T[len+1]; //复制原数组到二叉堆
ca[0] = 0;
for (int i=0; i
Insert(ca, i+1, a[i]);
for (int i=0; i
{
a[i] = DeleteMin(ca, len-i);
}
a[len-1] = ca[1]; //注意不能忘了最后一个元素
delete []ca;
}
在《数据结构习题与解析》(李春葆 编著 清华大学出版社)中看到一个类似的算法,
它是把原数组构建成一个大顶堆,然后把大顶堆的第一个元素与最后一个元素交换;
再把前n-1个元素重新构造成一个大顶堆,把新大顶堆的第一个元素与最后一个元素交换;
依此类推,直到新大顶堆只有一个元素,这样就得到了一个有序的二叉堆。
算法如下:
template
void HeapSort(T a[], int len)
{
T *ca = new T[len+1];
ca[0] = 0;
for (int i=0; i
ca[i+1] = a[i];
for (int i=len/2; i>0; i--) //建立初始堆
HeapAdjust(ca, len, i);
for (int i=len; i>1; i--)//进行len-1次循环,完成堆排序
{
Swap(ca[1], ca[i]); //新大顶堆的第一个元素与最后一个元素交换
HeapAdjust(ca, i-1, 1);//筛a[1]元素,得到i-1个元素的堆
}
for (int i=0; i
a[i] = ca[i+1];
delete []ca;
}
template
void HeapAdjust(T a[], int len, int left) //将i与其小儿子交换位置
{
if (len == 0)
exit(1);
T x = a[left];
int i = left;
int c = 2 * i;
while (c <= len) { if (c <> a[c])//若i有右儿子,且右儿子大于左儿子,c指向右儿子
c++;
if (last < i =" c;" c =" 2" t =" a;" a =" b;" b =" t;" ca =" new" i="0;" i="len/2;">0; i--) //把原数组构建成一个大顶堆
HeapAdjust(ca, len, i);
Swap(ca[1], ca[len]); //把大顶堆的第一个元素与最后一个元素交换
for (int i=len-1; i>0; i--)
{
for (int j=i/2; j>0; j--)//遍历长度为i的堆,得到新的大顶堆
HeapAdjust(ca, i, j);
Swap(ca[1], ca[i]);
}
for (int i=0; i
a[i] = ca[i+1];
delete []ca;
}
template
void HeapAdjust(T a[], int len, int i) //将i与其小儿子交换位置
{
int c = 2 * i;
if (c < max =" (a[c]"> a[c+1])? a[c] : a[c+1];
if (a[i] < t =" a;" a =" b;" b =" t;" ca =" new" i="0;" i="len/2;">0; i--) //把原数组构建成一个大顶堆
HeapAdjust(ca, len, i);
a[0] = ca[1];
ca[1] = ca[len]; //把二叉堆的最后一个元素放到根的位置
for (int i=len-1; i>0; i--)
{
for (int j=i/2; j>0; j--)
HeapAdjust(ca, i, j);
a[len-i] = ca[1];
ca[1] = ca[i]; //把二叉堆的最后一个元素放到根的位置
}
delete []ca;
}
template
void HeapAdjust(T a[], int len, int i)
{
int c = 2 * i;
if (c < min =" (a[c]"> min)
Swap(a[i], min);
}
else
{
if (a[i] > a[c])
Swap(a[i], a[c]);
}
}
template
void Swap(T & a, T & b)
{
T t = a;
a = b;
b = t;
}
后面两种方法采用的是递归,容易理解,但时间复杂度较高,因为比前两种要慢上很多,
所以不可能是O(nlogn),估计是O(n^2),但具体我也不会算,请。
星期二, 十二月 04, 2007
[fwd]搜索引擎学习资源收集
搜索引擎学习资源收集
一、搜索引擎技术/动态资源
<一>、综合类
1、卢亮的搜索引擎研究 http://www.wespoke.com/
卢亮属于搜索引擎开发上的专家,以前开发过一个搜索引擎"博索"(http://booso.com/),好像现在已经停止开发了,目前他服务于博客网。在他的这个blog上可以了解许多搜索引擎开发的技术和经验,值得持续关注。
2、laolu'blog
有不少来自国外的关于搜索引擎方面的资料,偏重于资料和数字
3、哈斯日志 http://www.loverty.org/
在这里可以看到国内外几大搜索引擎的最新动态,值得关注搜索发展形势的人多看看
4、北京奕天锐新科技有限公司 http://www.21cnbj.com/
搜索引擎、SEO、SEM等行业新闻动态
5、中文搜索引擎指南网 http://www.sowang.com/
搜索引擎最新动态,各种搜索技巧、方法
6、中文全文检索网 http://www.fullsearcher.com/
FullSearcher.Com是有两个对搜索爱好的年轻人创办,我们的目标是让中文互联网全面进入搜索时代,让搜索无处不在。通过搜索改变人们的生活。FullSearcher提供全文检索的相关知识、垂直搜索引擎知识、搜索的相关新闻等搜索相关内容。
7、周博——每天9点档的搜索引擎动态
8、李彦宏的博客 http://hi.baidu.com/liyanhong
9、中科院软件所- 张俊林博客 http://blog.csdn.net/malefactor/
搜索引擎技术研究
<二>、Google动态
Google官方博客:Google 黑板报 http://googlechinablog.com/
Google 中国的博客网志,走近我们的产品、技术和文化1、Gfans http://gfans.org/
2、G速客 http://www.gseeker.com/
<二>、其他搜索引擎动态
1、雅虎搜索日志 http://ysearchblog.cn/
记录雅虎搜索引擎的动态、产品、技术等
2、搜狗实验室 http://www.sogou.com/labs/
搜狗实验室(Sogou Labs)是搜狗搜索核心研发团队对外交流的窗口,包含创意产品、原型演示、资料下载、学术论文四个栏目。实验室热烈欢迎一直以来关注搜狗、支持搜狗的各位互联网玩家;对于致力于中文互联网研究的学术界同仁们的经常来访,也予以热切的期待。我们期望通过这个平台,展现搜狗研发团队强大的研发、创新能力;推动学术界和产业界的交互;了解用户对新产品的需求。我们的目标:为中文网民的互联网生活提供更加全面、更加优质的服务。
搜狗实验室博客 http://labs.blog.sohu.com/
3、百度的空间 http://hi.baidu.com/baidu
百度的动态
4、有道搜索博客 http://i.yodao.com/
网易新推搜索引擎--有道搜索的近期动态
5、Live Search's WebLog http://blogs.msdn.com/livesearch/
Microsoft Live Search's news http://windowslivebeta.spaces.live.com/
搜索引擎学习资源收集
一、搜索引擎技术/动态资源
<一>、综合类
1、卢亮的搜索引擎研究 http://www.wespoke.com/
卢亮属于搜索引擎开发上的专家,以前开发过一个搜索引擎"博索"(http://booso.com/),好像现在已经停止开发了,目前他服务于博客网。在他的这个blog上可以了解许多搜索引擎开发的技术和经验,值得持续关注。
2、laolu'blog
有不少来自国外的关于搜索引擎方面的资料,偏重于资料和数字
3、哈斯日志 http://www.loverty.org/
在这里可以看到国内外几大搜索引擎的最新动态,值得关注搜索发展形势的人多看看
4、北京奕天锐新科技有限公司 http://www.21cnbj.com/
搜索引擎、SEO、SEM等行业新闻动态
5、中文搜索引擎指南网 http://www.sowang.com/
搜索引擎最新动态,各种搜索技巧、方法
6、中文全文检索网 http://www.fullsearcher.com/
FullSearcher.Com是有两个对搜索爱好的年轻人创办,我们的目标是让中文互联网全面进入搜索时代,让搜索无处不在。通过搜索改变人们的生活。FullSearcher提供全文检索的相关知识、垂直搜索引擎知识、搜索的相关新闻等搜索相关内容。
7、周博——每天9点档的搜索引擎动态
8、李彦宏的博客 http://hi.baidu.com/liyanhong
9、中科院软件所- 张俊林博客 http://blog.csdn.net/malefactor/
搜索引擎技术研究
<二>、Google动态
Google官方博客:Google 黑板报 http://googlechinablog.com/
Google 中国的博客网志,走近我们的产品、技术和文化1、Gfans http://gfans.org/
2、G速客 http://www.gseeker.com/
<二>、其他搜索引擎动态
1、雅虎搜索日志 http://ysearchblog.cn/
记录雅虎搜索引擎的动态、产品、技术等
2、搜狗实验室 http://www.sogou.com/labs/
搜狗实验室(Sogou Labs)是搜狗搜索核心研发团队对外交流的窗口,包含创意产品、原型演示、资料下载、学术论文四个栏目。实验室热烈欢迎一直以来关注搜狗、支持搜狗的各位互联网玩家;对于致力于中文互联网研究的学术界同仁们的经常来访,也予以热切的期待。我们期望通过这个平台,展现搜狗研发团队强大的研发、创新能力;推动学术界和产业界的交互;了解用户对新产品的需求。我们的目标:为中文网民的互联网生活提供更加全面、更加优质的服务。
搜狗实验室博客 http://labs.blog.sohu.com/
3、百度的空间 http://hi.baidu.com/baidu
百度的动态
4、有道搜索博客 http://i.yodao.com/
网易新推搜索引擎--有道搜索的近期动态
5、Live Search's WebLog http://blogs.msdn.com/livesearch/
Microsoft Live Search's news http://windowslivebeta.spaces.live.com/
二、搜索引擎代码资源
一>、搜索引擎/网络蜘蛛程序代码
国外开发的相关程序
1、Nutch
官方网站 http://www.nutch.org/中文站点 http://www.nutchchina.com/最新版本:Nutch 0.7.2 Released
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具,可以建立自己内部网的搜索引擎,也可以针对整个网络建立搜索引擎。自由(Free)而免费(Free)。
2、Lucene
官方网站 http://lucene.apache.org中文站点 http://www.lucene.com.cn/
Lucene 是apache软件基金会 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包[用Java写的],即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
3、Larbin: http://larbin.sourceforge.net/index-eng.html
larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人 Sébastien Ailleret独立开发。larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源。
国内开发的相关程序
1、SQLET - 开放源码的中文搜索引擎
官方网站 http://www.sqlet.com/
SQLET,是Search & Query &Link, 加后缀 let,表示小的,小型的意思.打算建立一个能搜上亿张网页的基于主题功能的中文搜索引擎.支持3种索引方式:MySql_table_Index, Lucene_Index,SQLET_Index.网页抓取可以保存在文件系统及数据库里。自带WebServer.
2、菲度垂直搜索引擎代码
菲度http://www.faydu.net 为一个垂直在线搜索的演示版,主要对国内一些购物站点进行搜索整理,
现在开源测试版本的代码,供大家讨论。下载说明:
1》因为本程序是在服务器上运行,是在多个处理器下运行的,个人电脑上请控制线程数量
2》包含一个data 的数据库 还原到sql server
3》收集完毕默认在bin目录有licene生成的反排的索引文件
4》下载地址:http://www.faydu.net/download/code.rar
开放日期:2006-4-18 来源:http://blog.csdn.net/faydu/archive/2006/04/18/667997.aspx语言:VB.net(c#)
二>、中文分词程序代码
1、计算所汉语词法分析系统 ICTCLAS
中国科学院计算技术研究所在多年研究基础上,耗时一年研制出了基于多层隐马模型的汉语词法分析系统 ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System),该系统的功能有:中文分词;词性标注;未登录词识别。分词正确率高达97.58%(最近的973专家组评测结果),基于角色标注的未登录词识别能取得高于90%召回率,其中中国人名的识别召回率接近98%,分词和词性标注处理速度为31.5KB/s。ICTCLAS 和计算所其他14项免费发布的成果被中外媒体广泛地报道,国内很多免费的中文分词模块都或多或少的参考过ICTCLAS的代码。
下载页面:http://www.nlp.org.cn/project/project.php?proj_id=6
由于 ICTCLAS 是由 C 语言写成的,现在主流的开发工具用起来不太方便,于是有一些热心的程序员把 ICTCLAS 改为 Java 和 C# 等其他语言。
(1)fenci,Java 的 ICTCLAS,下载页面:http://www.xml.org.cn/printpage.asp?BoardID=2&id=11502
(2)AutoSplit,另一个 Java 的 ICTCLAS,已经找不到下载页面,点击本地下载
(3)小叮咚中文分词,曾经有下载页面,现在找不到了。据作者介绍,从 ICTCLAS 中改进,有 Java,C# 和 C++ 三个版本,介绍页面:http://www.donews.net/accesine
2、海量智能分词研究版
海量智能计算技术研究中心为了使中文信息处理领域的研究者们能够共同分享海量智能中心的研究成果,共同提高中文信息处理水平,特此发布《海量智能分词研究版》,供专家、学者和爱好者进行研究。
下载页面:http://www.hylanda.com/cgi-bin/download/download.asp?id=8
3、其他
(1)CSW中文智能分词组件
运行环境:Windows NT、2000、XP 或更高,可以在 ASP,VB 等微软的开发语言中调用。
简介: CSW中文智能分词DLL组件,可将一段文本自动的按常规汉语词组进行拆分,并以指定方式进行分隔,且可对其拆分后的词组进行语义、词频标注。其广范应用于各行各业的信息资料检索、分析。
下载页面:http://www.vgoogle.net/
(2) C# 写的中文分词组件
据作者介绍,一个 DLL 文件,可以做中英文分词组件。完全C#托管代码编写,独立开发。
下载页面:http://www.rainsts.net/article.asp?id=48编辑 引用 报告 评分 回复 顶部查看 IP dongdonglang版主Rank: 7Rank: 7Rank: 7
UID 1000精华 0积分 39帖子 11阅读权限 100注册 2006-11-11状态 在线
#3发表于 2007-1-24 04:41 PM 资料 文集 短消息 三>、开源spider一览
spider是搜索引擎的必须模块.spider数据的结果直接影响到搜索引擎的评价指标.
第一个spider程序由MIT的Matthew K Gray操刀该程序的目的是为了统计互联网中主机的数目
Spier定义(关于Spider的定义,有广义和狭义两种).
* 狭义:利用标准的http协议根据超链和web文档检索的方法遍历万维网信息空间的软件程序.* 广义:所有能利用http协议检索web文档的软件都称之为spider.
其中Protocol Gives Sites Way To Keep Out The 'Bots Jeremy Carl, Web Week, Volume 1, Issue 7, November 1995 是和spider息息相关的协议,大家有兴趣参考robotstxt.org.Heritrix
Heritrix is the Internet Archive's open-source, extensible, web-scale, archival-quality web crawler project.
Heritrix (sometimes spelled heretrix, or misspelled or missaid as heratrix/heritix/ heretix/heratix) is an archaic word for heiress (woman who inherits). Since our crawler seeks to collect and preserve the digital artifacts of our culture for the benefit of future researchers and generations, this name seemed apt.
语言:JAVA, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=73833&package_id=73980WebLech URL Spider
WebLech is a fully featured web site download/mirror tool in Java, which supports many features required to download websites and emulate standard web-browser behaviour as much as possible. WebLech is multithreaded and comes with a GUI console.
语言:JAVA, (下载地址) http://sourceforge.net/project/showfiles.php?group_id=38170
JSpider
A Java implementation of a flexible and extensible web spider engine. Optional modules allow functionality to be added (searching dead links, testing the performance and scalability of a site, creating a sitemap, etc ..
语言:JAVA, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=65617
WebSPHINX
WebSPHINX is a web crawler (robot, spider) Java class library, originally developed by Robert Miller of Carnegie Mellon University. Multithreaded, tollerant HTML parsing, URL filtering and page classification, pattern matching, mirroring, and more.
语言:JAVA, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=48810
PySolitaire
PySolitaire is a fork of PySol Solitaire that runs correctly on Windows and has a nice clean installer. PySolitaire (Python Solitaire) is a collection of more than 300 solitaire and Mahjongg games like Klondike and Spider.
语言ython , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=86107
The Spider Web Network Xoops Mod Team
The Spider Web Network Xoops Module Team provides modules for the Xoops community written in the PHP coding language. We develop mods and or take existing php script and port it into the Xoops format. High quality mods is our goal.
语言hp , (下载地址) http://sourceforge.net/projects/tswnmoddev
Fetchgals
A multi-threaded web spider that finds free porn thumbnail galleries by visiting a list of known TGPs (Thumbnail Gallery Posts). It optionally downloads the located pictures and movies. TGP list is included. Public domain perl script running on Linux.
语言erl , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=110338
Where Spider
The purpose of the Where Spider software is to provide a database system for storing URL addresses. The software is used for both ripping links and browsing them offline. The software uses a pure XML database which is easy to export and import.
语言:XML , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=115931
Sperowider
Sperowider Website Archiving Suite is a set of Java applications, the primary purpose of which is to spider dynamic websites, and to create static distributable archives with a full text search index usable by an associated Java applet.
语言:Java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=90254
SpiderPy
SpiderPy is a web crawling spider program written in Python that allows users to collect files and search web sites through a configurable interface.
语言ython , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=55531
Spidered Data Retrieval
Spider is a complete standalone Java application designed to easily integrate varied datasources. * XML driven framework * Scheduled pulling * Highly extensible * Provides hooks for custom post-processing and configuration
语言:Java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=90769
webloupe
WebLoupe is a java-based tool for analysis, interactive visualization (sitemap), and exploration of the information architecture and specific properties of local or publicly accessible websites. Based on web spider (or web crawler) technology.
语言:java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=121963
ASpider
Robust featureful multi-threaded CLI web spider using apache commons httpclient v3.0 written in java. ASpider downloads any files matching your given mime-types from a website. Tries to reg.exp. match emails by default, logging all results using log4j.
语言:java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=126578
larbin
Larbin is an HTTP Web crawler with an easy interface that runs under Linux. It can fetch more than 5 million pages a day on a standard PC (with a good network).
语言:C++, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=42562
三、SEO相关资源
1、域名信息查询
★ 查询国际顶级域名的信息(.aero, .arpa, .biz, .com, .coop, .edu, .info, .int, .museum, .net, .org),可以通过ICANN授权的域名注册商来查询,也可以直接到INTERNIC网站查询,网址是
http://www.internic.com/whois.html
http://www.iwhois.com/
★ 查询全球各个地理顶级域名是否已经被注册可以到下列网址查询(其中也包括国内域名.cn):
http://www.uwhois.com/cgi/domains.cgi?User=NoAds
★ 查询国内域名的注册情况,
http://ewhois.cnnic.net.cn/index.jsp
★ 万网的域名注册信息查询
http://www.net.cn/
★ IP地址查询、域名注册信息Whois查询
http://ip.zahuopu.com/
2、alexa相关与搜索排行榜
★ 中文排名500强
http://www.alexa.com/site/ds/top ... &lang=zh_gb2312
★ Google Zeitgeist--Google搜索排行榜
http://www.google.com/press/intl-zeitgeist.html#cn
★ 百度中文搜索风云榜
http://top.baidu.com/
★ 雅虎搜索排行榜
http://misc.yahoo.com.cn/top_index.html
★ 搜狗搜索指数
http://www.sogou.com/top/
3、搜索关键词查询
★ google关键字查询 https://adwords.google.com/select/KeywordSandbox★ 百度关键字查询 http://www2.baidu.com/inquire/dsquery.php★ 搜狐关键词 http://db.sohu.com/regurl/pv_price/query_consumer.asp
4、外部链接查询
★ 搜狗Link查询 http://www.sogou.com/features/
5、seo项目/工具
★网页质量 http://category.booso.com/cgi-bin/category/category.cgi★关键词密度 http://www.21ql.com/seo/keyword.asp★搜索引擎蜘蛛模拟器 http://www.webconfs.com/search-engine-spider-simulator.php
★Google Dance查询工具:http://www.google-dance-tool.com/
6、seo网站
英文网站:
搜索观察 http://www.searchenginewatch.com/seochat http://www.seochat.com
中文网站
在这里可以获取最新的SEO行业信息
搜索引擎优化交流中心 http://www.seoonline.cn
四、各大搜索引擎公司相关资料
1、联系方式
Google
http://www.google.com/intl/zh-CN/contact.html公司总部1600 Amphitheatre ParkwayMountain View, CA94043 USAphone: (650) 253-0000fax: (650) 253-0001电子邮件:chinese_s@google.com
百度
http://d.baidu.com/contact/index.html电话 (010)82621188传真 (010)82607007 82607008E-mail webmaster@baidu.com地址 北京市北四环西路58号理想国际大厦12层邮编 100080
雅虎/一搜
http://cn.yahoo.com/docs/sales/040203_contact.htm总机:010-65811221地址:北京市朝阳区光华东路和乔大厦B座5层雅虎中国搜索事业部邮编:100026传真:010-65812440在线问题提交:http://www.yisou.com/search_feedback.html
中国搜索
http://www.zhongsou.com/kefu/kfzs.htm地址:北京市西直门北大街42号华星大厦a座15.16层邮编:100088总机:010-62266296传真: 010-82211302
搜狐搜索
http://www.sohu.com/about/lianxi.htm地址:北京市海淀区中关村东路1号清华科技园9号威新国际大厦10层邮编: 100084电话: 86-10-62726666传真: 86-10-62728300
新浪搜索
http://ads.sina.com.cn/contact.html北京市北四环西路58号理想国际大厦20层邮编:100080Tel:(86-10)82628888Fax:(86-10)82607166搜索引擎咨询电话:010-82628888转6688搜索引擎联系信箱 searchcn@staff.sina.com.cn
网易搜索
http://so.163.com/contactus.shtml北京市东城区东长安街1号东方广场东方经贸城东三办公楼1901室邮编/Zip:100738网易搜索引擎客服热线:电话:010-82110163-8350、8121、8136E-mail:adp_complaint@service.netease.com
一、搜索引擎技术/动态资源
<一>、综合类
1、卢亮的搜索引擎研究 http://www.wespoke.com/
卢亮属于搜索引擎开发上的专家,以前开发过一个搜索引擎"博索"(http://booso.com/),好像现在已经停止开发了,目前他服务于博客网。在他的这个blog上可以了解许多搜索引擎开发的技术和经验,值得持续关注。
2、laolu'blog
有不少来自国外的关于搜索引擎方面的资料,偏重于资料和数字
3、哈斯日志 http://www.loverty.org/
在这里可以看到国内外几大搜索引擎的最新动态,值得关注搜索发展形势的人多看看
4、北京奕天锐新科技有限公司 http://www.21cnbj.com/
搜索引擎、SEO、SEM等行业新闻动态
5、中文搜索引擎指南网 http://www.sowang.com/
搜索引擎最新动态,各种搜索技巧、方法
6、中文全文检索网 http://www.fullsearcher.com/
FullSearcher.Com是有两个对搜索爱好的年轻人创办,我们的目标是让中文互联网全面进入搜索时代,让搜索无处不在。通过搜索改变人们的生活。FullSearcher提供全文检索的相关知识、垂直搜索引擎知识、搜索的相关新闻等搜索相关内容。
7、周博——每天9点档的搜索引擎动态
8、李彦宏的博客 http://hi.baidu.com/liyanhong
9、中科院软件所- 张俊林博客 http://blog.csdn.net/malefactor/
搜索引擎技术研究
<二>、Google动态
Google官方博客:Google 黑板报 http://googlechinablog.com/
Google 中国的博客网志,走近我们的产品、技术和文化1、Gfans http://gfans.org/
2、G速客 http://www.gseeker.com/
<二>、其他搜索引擎动态
1、雅虎搜索日志 http://ysearchblog.cn/
记录雅虎搜索引擎的动态、产品、技术等
2、搜狗实验室 http://www.sogou.com/labs/
搜狗实验室(Sogou Labs)是搜狗搜索核心研发团队对外交流的窗口,包含创意产品、原型演示、资料下载、学术论文四个栏目。实验室热烈欢迎一直以来关注搜狗、支持搜狗的各位互联网玩家;对于致力于中文互联网研究的学术界同仁们的经常来访,也予以热切的期待。我们期望通过这个平台,展现搜狗研发团队强大的研发、创新能力;推动学术界和产业界的交互;了解用户对新产品的需求。我们的目标:为中文网民的互联网生活提供更加全面、更加优质的服务。
搜狗实验室博客 http://labs.blog.sohu.com/
3、百度的空间 http://hi.baidu.com/baidu
百度的动态
4、有道搜索博客 http://i.yodao.com/
网易新推搜索引擎--有道搜索的近期动态
5、Live Search's WebLog http://blogs.msdn.com/livesearch/
Microsoft Live Search's news http://windowslivebeta.spaces.live.com/
搜索引擎学习资源收集
一、搜索引擎技术/动态资源
<一>、综合类
1、卢亮的搜索引擎研究 http://www.wespoke.com/
卢亮属于搜索引擎开发上的专家,以前开发过一个搜索引擎"博索"(http://booso.com/),好像现在已经停止开发了,目前他服务于博客网。在他的这个blog上可以了解许多搜索引擎开发的技术和经验,值得持续关注。
2、laolu'blog
有不少来自国外的关于搜索引擎方面的资料,偏重于资料和数字
3、哈斯日志 http://www.loverty.org/
在这里可以看到国内外几大搜索引擎的最新动态,值得关注搜索发展形势的人多看看
4、北京奕天锐新科技有限公司 http://www.21cnbj.com/
搜索引擎、SEO、SEM等行业新闻动态
5、中文搜索引擎指南网 http://www.sowang.com/
搜索引擎最新动态,各种搜索技巧、方法
6、中文全文检索网 http://www.fullsearcher.com/
FullSearcher.Com是有两个对搜索爱好的年轻人创办,我们的目标是让中文互联网全面进入搜索时代,让搜索无处不在。通过搜索改变人们的生活。FullSearcher提供全文检索的相关知识、垂直搜索引擎知识、搜索的相关新闻等搜索相关内容。
7、周博——每天9点档的搜索引擎动态
8、李彦宏的博客 http://hi.baidu.com/liyanhong
9、中科院软件所- 张俊林博客 http://blog.csdn.net/malefactor/
搜索引擎技术研究
<二>、Google动态
Google官方博客:Google 黑板报 http://googlechinablog.com/
Google 中国的博客网志,走近我们的产品、技术和文化1、Gfans http://gfans.org/
2、G速客 http://www.gseeker.com/
<二>、其他搜索引擎动态
1、雅虎搜索日志 http://ysearchblog.cn/
记录雅虎搜索引擎的动态、产品、技术等
2、搜狗实验室 http://www.sogou.com/labs/
搜狗实验室(Sogou Labs)是搜狗搜索核心研发团队对外交流的窗口,包含创意产品、原型演示、资料下载、学术论文四个栏目。实验室热烈欢迎一直以来关注搜狗、支持搜狗的各位互联网玩家;对于致力于中文互联网研究的学术界同仁们的经常来访,也予以热切的期待。我们期望通过这个平台,展现搜狗研发团队强大的研发、创新能力;推动学术界和产业界的交互;了解用户对新产品的需求。我们的目标:为中文网民的互联网生活提供更加全面、更加优质的服务。
搜狗实验室博客 http://labs.blog.sohu.com/
3、百度的空间 http://hi.baidu.com/baidu
百度的动态
4、有道搜索博客 http://i.yodao.com/
网易新推搜索引擎--有道搜索的近期动态
5、Live Search's WebLog http://blogs.msdn.com/livesearch/
Microsoft Live Search's news http://windowslivebeta.spaces.live.com/
二、搜索引擎代码资源
一>、搜索引擎/网络蜘蛛程序代码
国外开发的相关程序
1、Nutch
官方网站 http://www.nutch.org/中文站点 http://www.nutchchina.com/最新版本:Nutch 0.7.2 Released
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具,可以建立自己内部网的搜索引擎,也可以针对整个网络建立搜索引擎。自由(Free)而免费(Free)。
2、Lucene
官方网站 http://lucene.apache.org中文站点 http://www.lucene.com.cn/
Lucene 是apache软件基金会 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包[用Java写的],即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
3、Larbin: http://larbin.sourceforge.net/index-eng.html
larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人 Sébastien Ailleret独立开发。larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源。
国内开发的相关程序
1、SQLET - 开放源码的中文搜索引擎
官方网站 http://www.sqlet.com/
SQLET,是Search & Query &Link, 加后缀 let,表示小的,小型的意思.打算建立一个能搜上亿张网页的基于主题功能的中文搜索引擎.支持3种索引方式:MySql_table_Index, Lucene_Index,SQLET_Index.网页抓取可以保存在文件系统及数据库里。自带WebServer.
2、菲度垂直搜索引擎代码
菲度http://www.faydu.net 为一个垂直在线搜索的演示版,主要对国内一些购物站点进行搜索整理,
现在开源测试版本的代码,供大家讨论。下载说明:
1》因为本程序是在服务器上运行,是在多个处理器下运行的,个人电脑上请控制线程数量
2》包含一个data 的数据库 还原到sql server
3》收集完毕默认在bin目录有licene生成的反排的索引文件
4》下载地址:http://www.faydu.net/download/code.rar
开放日期:2006-4-18 来源:http://blog.csdn.net/faydu/archive/2006/04/18/667997.aspx语言:VB.net(c#)
二>、中文分词程序代码
1、计算所汉语词法分析系统 ICTCLAS
中国科学院计算技术研究所在多年研究基础上,耗时一年研制出了基于多层隐马模型的汉语词法分析系统 ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System),该系统的功能有:中文分词;词性标注;未登录词识别。分词正确率高达97.58%(最近的973专家组评测结果),基于角色标注的未登录词识别能取得高于90%召回率,其中中国人名的识别召回率接近98%,分词和词性标注处理速度为31.5KB/s。ICTCLAS 和计算所其他14项免费发布的成果被中外媒体广泛地报道,国内很多免费的中文分词模块都或多或少的参考过ICTCLAS的代码。
下载页面:http://www.nlp.org.cn/project/project.php?proj_id=6
由于 ICTCLAS 是由 C 语言写成的,现在主流的开发工具用起来不太方便,于是有一些热心的程序员把 ICTCLAS 改为 Java 和 C# 等其他语言。
(1)fenci,Java 的 ICTCLAS,下载页面:http://www.xml.org.cn/printpage.asp?BoardID=2&id=11502
(2)AutoSplit,另一个 Java 的 ICTCLAS,已经找不到下载页面,点击本地下载
(3)小叮咚中文分词,曾经有下载页面,现在找不到了。据作者介绍,从 ICTCLAS 中改进,有 Java,C# 和 C++ 三个版本,介绍页面:http://www.donews.net/accesine
2、海量智能分词研究版
海量智能计算技术研究中心为了使中文信息处理领域的研究者们能够共同分享海量智能中心的研究成果,共同提高中文信息处理水平,特此发布《海量智能分词研究版》,供专家、学者和爱好者进行研究。
下载页面:http://www.hylanda.com/cgi-bin/download/download.asp?id=8
3、其他
(1)CSW中文智能分词组件
运行环境:Windows NT、2000、XP 或更高,可以在 ASP,VB 等微软的开发语言中调用。
简介: CSW中文智能分词DLL组件,可将一段文本自动的按常规汉语词组进行拆分,并以指定方式进行分隔,且可对其拆分后的词组进行语义、词频标注。其广范应用于各行各业的信息资料检索、分析。
下载页面:http://www.vgoogle.net/
(2) C# 写的中文分词组件
据作者介绍,一个 DLL 文件,可以做中英文分词组件。完全C#托管代码编写,独立开发。
下载页面:http://www.rainsts.net/article.asp?id=48编辑 引用 报告 评分 回复 顶部查看 IP dongdonglang版主Rank: 7Rank: 7Rank: 7
UID 1000精华 0积分 39帖子 11阅读权限 100注册 2006-11-11状态 在线
#3发表于 2007-1-24 04:41 PM 资料 文集 短消息 三>、开源spider一览
spider是搜索引擎的必须模块.spider数据的结果直接影响到搜索引擎的评价指标.
第一个spider程序由MIT的Matthew K Gray操刀该程序的目的是为了统计互联网中主机的数目
Spier定义(关于Spider的定义,有广义和狭义两种).
* 狭义:利用标准的http协议根据超链和web文档检索的方法遍历万维网信息空间的软件程序.* 广义:所有能利用http协议检索web文档的软件都称之为spider.
其中Protocol Gives Sites Way To Keep Out The 'Bots Jeremy Carl, Web Week, Volume 1, Issue 7, November 1995 是和spider息息相关的协议,大家有兴趣参考robotstxt.org.Heritrix
Heritrix is the Internet Archive's open-source, extensible, web-scale, archival-quality web crawler project.
Heritrix (sometimes spelled heretrix, or misspelled or missaid as heratrix/heritix/ heretix/heratix) is an archaic word for heiress (woman who inherits). Since our crawler seeks to collect and preserve the digital artifacts of our culture for the benefit of future researchers and generations, this name seemed apt.
语言:JAVA, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=73833&package_id=73980WebLech URL Spider
WebLech is a fully featured web site download/mirror tool in Java, which supports many features required to download websites and emulate standard web-browser behaviour as much as possible. WebLech is multithreaded and comes with a GUI console.
语言:JAVA, (下载地址) http://sourceforge.net/project/showfiles.php?group_id=38170
JSpider
A Java implementation of a flexible and extensible web spider engine. Optional modules allow functionality to be added (searching dead links, testing the performance and scalability of a site, creating a sitemap, etc ..
语言:JAVA, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=65617
WebSPHINX
WebSPHINX is a web crawler (robot, spider) Java class library, originally developed by Robert Miller of Carnegie Mellon University. Multithreaded, tollerant HTML parsing, URL filtering and page classification, pattern matching, mirroring, and more.
语言:JAVA, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=48810
PySolitaire
PySolitaire is a fork of PySol Solitaire that runs correctly on Windows and has a nice clean installer. PySolitaire (Python Solitaire) is a collection of more than 300 solitaire and Mahjongg games like Klondike and Spider.
语言ython , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=86107
The Spider Web Network Xoops Mod Team
The Spider Web Network Xoops Module Team provides modules for the Xoops community written in the PHP coding language. We develop mods and or take existing php script and port it into the Xoops format. High quality mods is our goal.
语言hp , (下载地址) http://sourceforge.net/projects/tswnmoddev
Fetchgals
A multi-threaded web spider that finds free porn thumbnail galleries by visiting a list of known TGPs (Thumbnail Gallery Posts). It optionally downloads the located pictures and movies. TGP list is included. Public domain perl script running on Linux.
语言erl , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=110338
Where Spider
The purpose of the Where Spider software is to provide a database system for storing URL addresses. The software is used for both ripping links and browsing them offline. The software uses a pure XML database which is easy to export and import.
语言:XML , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=115931
Sperowider
Sperowider Website Archiving Suite is a set of Java applications, the primary purpose of which is to spider dynamic websites, and to create static distributable archives with a full text search index usable by an associated Java applet.
语言:Java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=90254
SpiderPy
SpiderPy is a web crawling spider program written in Python that allows users to collect files and search web sites through a configurable interface.
语言ython , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=55531
Spidered Data Retrieval
Spider is a complete standalone Java application designed to easily integrate varied datasources. * XML driven framework * Scheduled pulling * Highly extensible * Provides hooks for custom post-processing and configuration
语言:Java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=90769
webloupe
WebLoupe is a java-based tool for analysis, interactive visualization (sitemap), and exploration of the information architecture and specific properties of local or publicly accessible websites. Based on web spider (or web crawler) technology.
语言:java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=121963
ASpider
Robust featureful multi-threaded CLI web spider using apache commons httpclient v3.0 written in java. ASpider downloads any files matching your given mime-types from a website. Tries to reg.exp. match emails by default, logging all results using log4j.
语言:java , (下载地址)http://sourceforge.net/project/showfiles.php?group_id=126578
larbin
Larbin is an HTTP Web crawler with an easy interface that runs under Linux. It can fetch more than 5 million pages a day on a standard PC (with a good network).
语言:C++, (下载地址)http://sourceforge.net/project/showfiles.php?group_id=42562
三、SEO相关资源
1、域名信息查询
★ 查询国际顶级域名的信息(.aero, .arpa, .biz, .com, .coop, .edu, .info, .int, .museum, .net, .org),可以通过ICANN授权的域名注册商来查询,也可以直接到INTERNIC网站查询,网址是
http://www.internic.com/whois.html
http://www.iwhois.com/
★ 查询全球各个地理顶级域名是否已经被注册可以到下列网址查询(其中也包括国内域名.cn):
http://www.uwhois.com/cgi/domains.cgi?User=NoAds
★ 查询国内域名的注册情况,
http://ewhois.cnnic.net.cn/index.jsp
★ 万网的域名注册信息查询
http://www.net.cn/
★ IP地址查询、域名注册信息Whois查询
http://ip.zahuopu.com/
2、alexa相关与搜索排行榜
★ 中文排名500强
http://www.alexa.com/site/ds/top ... &lang=zh_gb2312
★ Google Zeitgeist--Google搜索排行榜
http://www.google.com/press/intl-zeitgeist.html#cn
★ 百度中文搜索风云榜
http://top.baidu.com/
★ 雅虎搜索排行榜
http://misc.yahoo.com.cn/top_index.html
★ 搜狗搜索指数
http://www.sogou.com/top/
3、搜索关键词查询
★ google关键字查询 https://adwords.google.com/select/KeywordSandbox★ 百度关键字查询 http://www2.baidu.com/inquire/dsquery.php★ 搜狐关键词 http://db.sohu.com/regurl/pv_price/query_consumer.asp
4、外部链接查询
★ 搜狗Link查询 http://www.sogou.com/features/
5、seo项目/工具
★网页质量 http://category.booso.com/cgi-bin/category/category.cgi★关键词密度 http://www.21ql.com/seo/keyword.asp★搜索引擎蜘蛛模拟器 http://www.webconfs.com/search-engine-spider-simulator.php
★Google Dance查询工具:http://www.google-dance-tool.com/
6、seo网站
英文网站:
搜索观察 http://www.searchenginewatch.com/seochat http://www.seochat.com
中文网站
在这里可以获取最新的SEO行业信息
搜索引擎优化交流中心 http://www.seoonline.cn
四、各大搜索引擎公司相关资料
1、联系方式
http://www.google.com/intl/zh-CN/contact.html公司总部1600 Amphitheatre ParkwayMountain View, CA94043 USAphone: (650) 253-0000fax: (650) 253-0001电子邮件:chinese_s@google.com
百度
http://d.baidu.com/contact/index.html电话 (010)82621188传真 (010)82607007 82607008E-mail webmaster@baidu.com地址 北京市北四环西路58号理想国际大厦12层邮编 100080
雅虎/一搜
http://cn.yahoo.com/docs/sales/040203_contact.htm总机:010-65811221地址:北京市朝阳区光华东路和乔大厦B座5层雅虎中国搜索事业部邮编:100026传真:010-65812440在线问题提交:http://www.yisou.com/search_feedback.html
中国搜索
http://www.zhongsou.com/kefu/kfzs.htm地址:北京市西直门北大街42号华星大厦a座15.16层邮编:100088总机:010-62266296传真: 010-82211302
搜狐搜索
http://www.sohu.com/about/lianxi.htm地址:北京市海淀区中关村东路1号清华科技园9号威新国际大厦10层邮编: 100084电话: 86-10-62726666传真: 86-10-62728300
新浪搜索
http://ads.sina.com.cn/contact.html北京市北四环西路58号理想国际大厦20层邮编:100080Tel:(86-10)82628888Fax:(86-10)82607166搜索引擎咨询电话:010-82628888转6688搜索引擎联系信箱 searchcn@staff.sina.com.cn
网易搜索
http://so.163.com/contactus.shtml北京市东城区东长安街1号东方广场东方经贸城东三办公楼1901室邮编/Zip:100738网易搜索引擎客服热线:电话:010-82110163-8350、8121、8136E-mail:adp_complaint@service.netease.com
星期六, 十二月 01, 2007
[fwd]C2C简介
C2C什么是C2C
很多人不明白什么是c2c?c2c实际上是电子商务一个专业术语,c2c即c to c ,因为在英文中的2的发音同to,所以c to c简写为c2c。c指的是消费者,因为消费者的英文单词是consumer,所以简写为c。现在大家应该知道c2c的意思就是消费者(consumer)与消费者(consumer)之间的电子商务。打个比方,比如一个消费者的有一台旧电脑,通过网上拍卖,把它卖给另外一个消费者,这种交易类型就称为c2c电子商务。
c2c电子商务主要是指网上拍卖。c2c模式的特点就是大众化交易,因为是个人与个人之间的交易!
C2C中国发展现状
在快速变化的互联网行业,一年的时间足以让沧海变成桑田。
一年之前,拍拍网的强势介入让C2C领域形成了三足鼎立之势,淘宝、易趣、拍拍三家各有千秋,而又强弱分明。一年的风雨之后再回头来看,太多的事情让原有的格局已悄然改变,强弱之势的异位让C2C进入了更加扑朔迷离的后三国时代。
淘宝:在领先与压力之间
毋庸置疑,淘宝在C2C领域的领先地位暂时还无人能够撼动。然而,淘宝却也不得不承受这份领先带来的沉甸甸的压力。在领先与压力之间,淘宝在奋力往前走。
在中国C2C市场,淘宝的市场份额超过60%。如果是在传统行业,淘宝完全可以高枕无忧。然而在瞬息万变的互联网领域,这样的优势并不是什么不可逾越的屏障。早在2006年5月推出招财进宝受挫,马云便意识到这样的市场地位并不稳固,竞争对手完全可能爆发出惊人的能量,直接挑战淘宝的权威。
就这样,领先本身就成为了一种压力。后有追兵,前路又是一片茫茫。没有人告诉你前面的路该如何去走,迈出的每一步都成为一次小心翼翼的尝试,可能踏出一片广阔天地,也可能会一无所获。在过去的一年内,淘宝显示了其在创新上的勇气,收购口碑网推出分类信息,大力拓展品牌商城,将团购做成一个频道,将交易的视野扩向全球推出“全球购”频道……很难说这些尝试给淘宝带来的直接收益有多大,但是淘宝却因此明白了什么可以做、什么可以不做。依靠不断的尝试,淘宝在小小翼翼的维护着自己的领先地位。
对于淘宝而言,领先还有一个代价,就是巨大的资金投入。不管马云夸口的20亿资金投入是否属实,一个无可辩驳的事实是淘宝面临的资金压力越来越明显的显示出来。在悄无声息之中,淘宝对于入住品牌/商城的用户开始收取服务费,而在政策和资源上对于该部分商户的倾斜,以及不自觉间对于小商户的忽视,使得免费的淘宝已经名存实亡。很显然,免费的淘宝已经不能承担巨大的资金压力之重。
07年,淘宝还在前行,但是每一步都不会再像以前那样轻松和自如。
拍拍:商品超千万只是另一个起点
近日,拍拍网对外宣布,其在线商品数突破1000万。商品数突破千万量级意味着,只要是正常的购买需求,用户都可以在拍拍网上得到满足。籍此,拍拍网也正式跻身千万商品俱乐部,目前,进入中国千万商品俱乐部的只有淘宝和拍拍两家。
06年3月,拍拍网对外宣布正式运营。一年多的快速成长,让依托于腾讯的拍拍网已经成为中国C2C领域一匹潜力十足的黑马。去年5月,拍拍网发布的“蚂蚁搬家”让马云开始认真打量这个快速崛起的竞争对手。07年3月,拍拍网正式宣布其在线商品数突破千万,并且成为了最短时间内打破这一纪录的行业领先者,而这距其正式运营的时间不过一年,成长速度之快,令人乍舌。
当然,拍拍网的快速发展让中国的C2C市场格局也在悄然发生着变化。在线商品数突破千万,让拍拍在不经意间又逼近了淘宝一步。在Alexa的世界网站排名上,拍拍网跃进国内C2C网站流量排名第二位的位置已经持续了很久。“对于购物网站来说,商品和人流量是两个关键指标。简而言之:当一个商场的商品非常丰富,而来商场的消费者又非常多的时候,商场成交额的提升将是一个必然。而在这两项指标上都跃居第二,这也意味着C2C的产业格局正在悄然改变,三足鼎立的传统格局很有可能会被淘宝、拍拍双峰对峙的局面所替代。”业内专家认为。
尽管背后有着2.3亿庞大的活跃QQ用户群作为基础,然而,能够取得如此的成长速度仍属不易。业内资深人士认为,和腾讯其他业务的密切捆绑,使得拍拍拥有了很多其他购物平台所无法比拟的差异化优势,而这是拍拍网快速发展的另一个关键原因。以交易腾讯增值产品为主的QQ特区在拍拍中占据着重要的位置。在去年10月,拍拍和QQ空间共同推出的QCC商城就取得了很大的成功。据保守估计,QCC商城给拍拍带来的流量和交易量的提升都在20%以上。
尽管有着业界最快的成长速度和强劲的发展势头,但是和淘宝相比,拍拍网在市场份额上的差距也并不是凭一日之功就能解决的。对此,拍拍网负责人湛炜标有着非常清醒的认识:“在线商品数突破千万,对于我们来说只是一个新的起点。接下来,我们会在商品搜索、购物流程、支付、物流等方面做持续改进,不断提升用户体验。比如说在最近推出的QQ新版本中,我们就融入了更多的拍拍元素,在进行对话时,可以清晰的显示卖家和商品信息,这样就有助于在沟通过程中快速达成交易。毕竟,用户的选择才是评判一个购物平台是否具有良好发展前景的最好标准。”
07年,在挑战的道路上,拍拍任重而道远。
易趣:转型的阵痛
从本土企业到跨国企业,再从跨国企业到本土企业,转了一个圈,易趣又回来了。不同的是其名字由易趣改成了TOM易趣,老板也从邵亦波变成了王雷雷。
在去年易趣和TOM合并的时候,王雷雷曾经豪言:“要在半年的时间内找到可行的盈利模式。”半年的时间还没到,豪言能否兑现尚未可知,但是可以看得到的是在TOM易趣身上明显的本土化气息。eBay易趣是不大注重社区的,如今的TOM易趣再次把社区当作重点抓了起来。过完年,易趣忙不迭的推出了年货交易专区,并大做宣传文章,而这在以前的eBay易趣则是不可想象的。
深入了解中国网民的习惯,并做出与之相对应的调整,易趣正在向一个纯粹的本土企业接近,然而,无可回避的事实是,几经周折的易趣已经元气大伤。在王雷雷的手中,易趣究竟能恢复几成的王者之风,还需要我们拭目以待。
C2C和B2C
艾瑞市场咨询即将出版的《2007年中国网络购物报告》数据显示,俗称“网上开店”的C2C网络购物模式发展快于B2C,两者融合的趋势越来越明显,未来将共同形成最有竞争力的互联网商业模式。
C2C交易额超过B2C
网络购物有两种模式:一种是B2C模式,即商品和信息从企业直接到消费者,另一种是C2C,即商品和信息从消费者直接到消费者,俗称“网上开店”。数据显示,截至2006年年底,网络购物总体交易额达到312亿元,B2C和C2C总体交易额分别为82亿元和230亿元,C2C市场规模同比增加85%,增长速度超过网络购物的整体增速。
从购物内容看,B2C类购买商品种类以音像制品为主,其次是软件类商品;C2C购物网站销售的各类商品中,游戏点卡、数码产品和家居百货等产品都是买家在C2C类购物网站购买的重点。此外,随着买家购买经验的累积和商家对商品描述内容愈发详细和贴切,加上退换货制度的建立,服装鞋帽逐渐成为网络销售中的热门商品种类。
艾瑞市场总监侯涛认为,在市场成长阶段初期,由于相对C2C,B2C交易避免了信用和支付安全等问题,更容易被用户接受,因此交易额在2003年和2004年都高于C2C。但随着第三方支付平台的出现和信用评价体系的建立,C2C更灵活和自由的购物模式也得到越来越多用户的认可。从2005年开始,C2C的交易额快速增长。
形成“内外”争霸格局
艾瑞咨询提供的数据预计,2007年我国网络购物的市场规模将突破500亿元,达到510亿元,增长率则从2002年起点时期的196%下降到2006年60%左右,明年将略有提高,为63.5%。
此外,网络购物注册人数在2006年达到4310万人,预计今年会保持25%以上的增长率,达到5500万人。另据中国互联网络信息中心(CNNIC)发布的第十八次“中国互联网络发展状况统计报告”,在12300万网民数十种网上行为中,通过网络进行购物的比例高达26%。按照这个比例计算,网络购物的直接顾客群将达到3200万人。
然而,如此巨大的市场目前只有寥寥数家瓜分。尽管购物网站数目众多,但由于购物网站需要巨额资金投入,目前只有几家在苦苦支撑,形成“内外”相争的局面。外资代表如卓越网和易趣网;卓越网由金山公司和联想投资创建,2004年被美国电子商务网站巨头亚马逊收购,易趣网引入合作伙伴美国电子商务网站eBay,随后被其全面收购。内资代表如淘宝网和拍拍网,电子商务网站阿里巴巴创建淘宝并多次注资,中国市场上最大的互联网即时通信软件开发商腾讯公司也染指购物网站,成立拍拍网,与淘宝叫板。
这4家购物网站占据了网络购物市场的半壁江山,但是网站间同质化竞争严重。侯涛指出,在B2C、C2C融合的背景下,如果购物网站能够结合自身的网站资源优势进行创新,将能够催生网络购物航空母舰型企业的出现。
中国C2C简史:
1999年: 邵亦波创立易趣网,创中国C2C先河。
1999年8月: 易趣网正式上线。
2002年3月: eBay注资易趣网3000万美元。
2003年5月: 阿里巴巴4.5亿成立C2C网站淘宝网。
2003年7月: eBay斥资1.5亿美元全资收购易趣网。
2004年6月: 易趣网进入与美国eBay平台对接整合。
2005年9月: 腾讯推出拍拍网,2006年3月13日运营。
2006年12月: TOM在线与eBay合资,更名为TOM易趣。
2007年10月: 搜索引擎公司百度宣布进军电子商务,筹建C2C平台,预计2008年初推出。
SNA的讨论-关于Rails大容量网站部署性能的讨论
前段时间就rails的部署的负载能力进行了相关的讨论,请看:
http://www.javaeye.com/topic/19534
http://www.javaeye.com/topic/18675
这两天在安装服务器,顺便到处看了一下,搞清楚了一些对rails的误解。因此对服务器部署有了一些新的想法,和大家探讨一下。
以前我以为rails像PHP那样,以apache的server mod方式运行,今天仔细看了一下FastCGI/SCGI/mongrel的安装手册,这才搞明白,我弄错了。
当FastCGI/SCGI/mongrel方式部署的时候,ruby并不是直接运行在apache的进程中的,而是独立的运行在CGI或者 server上面的。在这种情况下lighthttpd/apache仅仅充当了一个前端HTTP请求分发的代理作用(和静态页面的处理),动态内容交给了后台的ruby CGI/Server去处理的。
其实这种部署方式和我们J2EE常用的apache+(mod_jk)+n个tomcat实例的方式本质上是没有什么区别的。更进一步来说,IBM WebSphere的cluster实际上也是这种方式,在前端使用Apache作为请求分发代理,后面若干个WebSphere实例来处理请求。
在J2EE群集部署方案中,虽然目前的企业应用都强调了应用服务器提供的Session复制功能,EJB调用的负载均衡能力,但是考虑到目前 J2EE潮流发展的趋势,已经不再使用EJB的负载均衡,同时Session复制也被证明为影响cluster水平扩展的主要障碍之一。因此对于大容量的 J2EE水平扩展群集而言,保持每个节点的无状态性,不再使用Session来保持全局状态是必经之路。
因为只有每个JVM进程不保持全局状态,才能够保证n个JVM节点的幂等性,那些所有涉及到全局状态的,必须放在JVM进程之外,例如用户ID可以使用cookie,session可以放入数据库,文件可以放在共享存储系统中。
这样的方案做下来,前端的apache也仅仅是一个HTTP请求代理,后面的应用服务器实例几乎是可以无限水平扩展的,瓶颈永远不会出现在应用服务器层,只会出现在apache端,或者数据库端。当然apache不行,还可以用lighthttpd,甚至使用四层交换机硬件进行请求的分发工作,后端的单台数据库不行,还可以使用多个数据库同步复制,甚至使用Oracle Grid。
这个时候我们考察一下J2EE的群集方案,竟然会发现和Rails的群集方案没有多大的差别了。为了讨论的简单,我们拿J2EE的apache2.2 + tomcat5.5和apache2.2 + mongrel来对比一下:
先看J2EE群集方案:
Apache2.2 proxy分发请求给后面n个tomat5.5实例(这里甚至都不需要使用mod_proxy_ajp,apache直接转发请求给tomcat的http端口);
每个tomcat实例没有内部全局状态,完全是无状态的服务,用户标示从cookie取得,session可以放在数据库中,假设不使用分布式Cache。每个tomcat实例收到一个请求以后,自行处理,然后返回给apache。
再看rails群集方案:
Apache2.2 proxy分发请求给后面n个mongrel实例;
每个mongrel实例也是无状态的,用户标示使用cookie,从apache收到一个请求以后,自行处理,然后返回给apache。
从两者的对比来看,J2EE的每个节点是一个JVM进程,里面若干Java线程都是无状态的,而mongrel据说也是多线程的,rails的每个节点是一个Ruby进程,里面若干ruby线程都是无状态。竟然完全一致的模型!
在这种情况下,究竟是进程多一点,线程少一点;还是进程少一点,线程多一点,都不是最重要的讨论话题,焦点是J2EE和Rails的群集方案是一致的,在应用逻辑处理层的群集水平扩展能力都是近乎无限的,因此都不是系统的瓶颈所在。这意味着什么呢?
这意味着,只要硬件管够,J2EE系统和Rails系统的网站负载能力不会有多大的差别。
也许,ruby的解析执行速度比Java慢,由于没有数据库连接池导致每个请求需要多消耗一些建立物理连接的时间。但是这些因素只能导致单个用户请求的响应时间比Java慢,不会导致整个网站的负载能力差。
也就是说,如果Java的系统,用户打开一个页面需要两秒钟,而Rails的系统,用户打开一个页面可能需要四秒钟,但是他们都能够每天负载100 万的PV,这100万个请求,rails大概也同样是四秒钟,这方面没有什么差别(同样的网站负载,mongrel的实例数量也许远多于tomcat实例数量,但是总体处理能力没有区别)。
当然,J2EE群集方案和Rails群集方案还是有两点不同:
1、J2EE有内置分布式Cache,例如JBoss Cache,而rails的方式是独立的Cache进程在运行,这两种方式来说,对于群集水平扩展,甚至rails的Cache方案还要更好。
2、数据库连接池,对于mongrel,我觉得增加数据库连接池是完全做得到的事情。不过即使不增加连接池,这里也不会成为系统瓶颈,最多会导致数据库多花一些时间在处理连接的建立和断开上面。
最后这种群集部署方案下面,web server退化成为一个请求分发代理,找不到任何理由使用apache了,对,是lighthttpd出场kick off apache的时候。如果网站容量大到连lighthttpd都无法及时分发请求的时候,你还可以用四层交换机来分发请求,那lighthttpd也该被 kick off了。
用J2EE看起来确实能够更加节省硬件,但是我们不能再用Rails无法负载大容量网站的理由来攻击rails了,只有硬件管够,不管是J2EE,还是Rails,都有近乎无限的水平扩展能力。
[fwd]SEDA简介
1.Overview
* SEDA
* An Architecture for Highly Concurrent,Well-Conditioned Internet Services
* Adaptive Overload Control for Busy Internet Servers
SEDA是NIO的重要input,但SEDA框架本身已不再发展。
它的核心思想是把一个请求处理过程分成几个阶段,不同资源消耗的阶段使用不同数量的线程来处理,阶段间使用事件驱动的异步通信模式。
SEDA要求每个Stage需要
* 动态配置自己的线程数
* 在超载时降级运行,如输出纯文字页面
* 在超载时拒绝接收服务
因此每个SEDA的Stage的结构通常有如下组件
* Incoming Event Queue ,事件队列。
* Admission Controller 阀门,拒绝服务。
* Dynamically sized Thread Pool 线程池。
* Event Handler 实际处理业务的Compinent。
* Resource Controller 控制Stage的参数。
2.Web2.0+SOA环境下的SEDA应用
Java EE 迎合 Web 2.0(IBM DW) web2.0虽然最重要的还是策划者的点子,但架构师在Web2.0大潮里也不再无所事事了 因为:
2.1 问题
1.在Web2.0+SOA里,系统越来越多的调用外系统,mashup的应用更需要从外系统pull大量data。
外系统的调用直线增加了任务的时长。cache是一个常用方法,但对一些query result或实时信息较为无力。
而且Web Service调用的时间主要时间花在建立连接与传输数据上,对服务处理的CPU时间花费不大,对服务代码的优化成果不大。
长连接是更有效的方法(比如Ajax的Comet),但要求服务端有高效的处理模型。
2. 在Web2.0里,用户获得了更多的交互动作,会比Web1.0发起更多的请求,尤其是Ajax的大量运用,显示一个页面需要更多的连接交互。
3. 页面的长度也在内容丰富中膨胀。而且页面的数量也因为用户的直接参与创建而疯狂增长。
4. 峰值效应。如果你的网站被某知名网媒头条推荐(如一个著名的新闻站,博客站,社区),可能会在短时间内迎来一个完全超出平时设计容量的访问洪峰。网媒的发达使洪峰发生的概率要远高于1.0时代。
JavaEE 的同步调用机制(除JMS),有限的线程池与连接池(超出范围性能会下降),固定的定义在JNDI的资源对Web2.0/SOA的需求并不吻合。对BEEP,SCTP这些协议,必须依靠JCA另行编写模块来实现长连接模型。
2.2 SEDA的解决方案
从统计学上看,在系统总线程数固定的情况下,使用SEDA能获得较高的Throughput,阶段间的资源差异越大就越明显。
比如处理一个Web 2.0常用请求,有如下几步
1. 接收用户请求(1单位时间)
2. 数据库查询(4单位时间)
3. 根据数据库查询结果,准备Web Service调用参数(1单位时间)
4. 发起Web Service调用((16单位时间))
5. 将结果渲染返回给用户(2单位时间)
那么SEDA会使用一条线程处理1.接收用户请求、3.准备WebService、5.返回结果,两条线程处理数据库查询, 而5条线程处理耗时最多的WebService请求。
而且结果表明,当远程调用所花时间不变,而本地操作得到优化时,系统通量也能获得明显提高。
3. SEDA 实例
* Mule
* MINA
阿里巴巴盈利模式分析
阿里巴巴作为中国电子商务界的一个神话,从98年创业之初就开始了它的传奇发展。它在短短几年时间里累积300万的企业会员,并且每天以6000多新用户的速度增加。不仅仅是搭上了其创始人马云的传奇神话,它的成功更是得力于其准确的市场定位,以及前瞻性的远见。阿里巴巴在电子商务萌芽阶段就商业化地切入,并且踏实的做着自己能力能够做到的事情。自己诚实守信并且在实际行动中致力于规范网上电子商务贸易。这一切在中国二十一世纪的前几年,这个中国电子商务迅速发展的阶段,成就了阿里巴巴今天的成绩。一个错误就可以造成一个失败,但一个成功必然是很多个正确的原因带来的,下面我们就来简单分析一下阿里巴巴网站的运营模式、盈利点、成功之处以及目前和以后的发展战略。
阿里巴巴网站的目标是建立全球最大最活跃的网上贸易市场,它不同于早期互联网公司以技术为驱动的网络服务模式,它从一开始就有明确的商业模式。阿里巴巴具有明确的市场定位,在发展初期专做信息流,绕开物流,前瞻性的观望资金流并在恰当的时候介入支付环节。它的的运营模式是遵循循序渐进的过程,依据中国电子商务界的发展状况来准确定位网站。首先抓基础的,然后在事实过程中不断捕捉新的收入机会。从最基础的替企业架设站点,到随之而来的网站推广以及对在线贸易资信的辅助服务,交易本身的订单管理,不断延伸。其出色的赢利模式符合:赢利的强有力,可持续,可拓展的特点。
具体谈阿里巴巴网站的运营模式主要有以下几个特点:
首先,专做信息流,汇聚大量的市场供求信息。马云曾在05年阿里巴巴在广交会期间主办的电子商务研讨会,阐述了以下观点,即中国电子商务将经历三个阶段,信息流、资金流和物流阶段。目前还停留在信息流阶段。交易平台在技术上虽然不难,但没有人使用,企业对在线交易基本上还没有需求,因此做在线交易意义不大。这是阿里巴巴最大的特点,就是做今天能做到的事,循序渐进发展电子商务。
功能上,阿里巴巴在充分调研企业需求的基础上,将企业登录汇聚的信息整合分类,形成网站独具特色的栏目,使企业用户获得有效的信息和服务。阿里巴巴主要信息服务栏目包括:①商业机会,有27个行业700多个产品分类的商业机会供查阅,通常提供大约50万供求信息②产品展示:按产品分类陈列展示阿里巴巴会员的各类图文并茂的产品信息库③公司全库:公司网站大全,目前已经汇聚4万多家公司网页。用户可以通过搜索寻找贸易伙伴,了解公司详细资讯。会员也可以免费申请自己的公司加入到阿里巴巴“公司全库”中,并链接到公司全库的相关类目中方便会员有机会了解公司全貌。④行业资讯:按各类行业分类发布最新动态信息,会员还可以分类订阅最新信息,直接通过电子邮件接受。⑤价格行情:按行业提供企业最新报价和市场价格动态信息⑥以商会友:商人俱乐部。在这里会员交流行业见解,谈天说地。其中咖啡时间为会员每天提供新话题,为会员分析如何做网上营销等话题。⑦商业服务:航运、外币转换、信用调查、保险、税务、贸易代理等咨询和服务。这些栏目为用户提供了充满现代商业气息,丰富实用的信息,构成了网上交易市场的主体。
第二,阿里巴巴采用本土化的网站建设方式,针对不同国家采用当地的语言,简易可读,这种便利性和亲和力将各国市场有机地融为一体。阿里巴巴已经建立运作四个相互关联的网站:英文的国际网站(http://www.alibaba.com)面向全球商人提供专业服务;简体中文的中国网站(http://china.aliaba.com)主要为中国大陆市场服务;全球性的繁体中文网站(http://chinese.alibaba.com)则为台湾、香港、东南亚及遍及全球的华商服务;韩文的韩国网站(http://kr.alibaba.com)针对韩文用户服务(目前不可用),日文的日本网站(http://japan.alibaba.com)。而且即将推出针对当地市场的欧洲语言和南美网站。这些网站相互链接,内容相互交融,为会员提供一个整合一体的国际贸易平台,汇集全球178个国家(地区)的商业信息和个性化的商人社区。
第三,在起步阶段,网站放低会员准入门槛,以免费会员制吸引企业登录平台注册用户,从而汇聚商流,活跃市场,会员在浏览信息的同时也带来了源源不断的信息流和创造无限商机。截至2001年7月,阿里巴巴会员数目已达73万,分别来自202个国家和地区,每天登记成为阿里巴巴的商人会员超过1500名。阿里巴巴会员多数为中小企业,免费会员制是吸引中小企业的最主要因素。在市场竞争将日趋复杂激烈的情况下,中小企业当然不肯错过这个成本低廉的机遇,利用网上市场来抓住企业商机。大大小小的企业活跃于网上市场,反过来为阿里巴巴带来了各类供需,壮大了网上交易平台。阿里巴巴每月页面浏览量超过4500万,信息库存买卖类商业机会信息达50万条,每天新增买卖信息超过3000条,每月有超过30万个询盘,平均每条买卖信息会得到四个反馈。
第四,阿里巴巴通过增值服务为会员提供了优越的市场服务,增值服务一方面加强了这个网上交易市场的服务项目功能,另一方面又使网站能有多种方式实现直接赢利。尽管目前阿里巴巴不向会员收费,但据马云介绍,阿里巴巴网站目前是赢利的。阿里巴巴的赢利栏目主要是:中国供应商、委托设计公司网站、网上推广项目和诚信通。中国供应商是通过ALIBABA的交易信息平台,给中国的商家提供来自各国国际买家的特别询盘。客户可以委托阿里巴巴作一次性的投资建设公司网站,这个项目主要是alibaba帮助企业建立拥有独立域名网站,并且与alibaba链接。网上推广项目,是由邮件广告、旗帜广告、文字链接和模块广告组成。邮件广告由网站每天向商人发送的最新商情特快邮件插播商家的广告;文字链接将广告置于文字链接中。新推出的诚信通项目能帮助用户了解潜在客户的资信状况,找到真正的网上贸易伙伴;进行权威资信机构的认证,确认会员公司的合法性和联络人的业务身份;展现公司的证书和荣誉,用业务伙伴的好评成为公司实力的最好证明。
第五,适度但比较成功的市场运作,比如福布斯评选,提升了阿里巴巴的品牌价值和融资能力。阿里巴巴与日本互联网投资公司软库(Softbank)结盟,请软库公司首席执行官、亚洲首富孙正义担任阿里巴巴的首席顾问,请世界贸易组织前任总干事、现任高盛国际集团主席兼总裁彼得•萨瑟兰担任阿里巴巴的特别顾问。通过各类成功的宣传运作,阿里巴巴多次被选为全球最佳B2B站点之一。2000年10月,阿里巴巴荣获二十一世纪首届中国百佳品牌网站评选"最佳贸易网"。
从业务角度来看,阿里巴巴的赢利点主要在以下四方面:
1设企业站点
2网站推广
3诚信通
4贸易通
从另一个角度,我们还可以将阿里巴巴的利益点做如下归纳:
一、诚信安全
A、几百万的诚信通会员,通过第三方评估认证,定期进行榜单追踪,网上企业诚信指数一目了然。
B、电子支付系统——支付宝,确保买卖双方资金的安全流动。
C、十大网商成功实例、十大浙商成功实例、十大粤商成功实例。
D、几百万诚实守信的网商。
二、品牌资质
福布斯连续5年全球最佳B2B网站。
中国最大B2B网站。
全球电子商务领袖。
三、快捷方便
即使相隔千里,照样实现点对点的沟通和交易。
四、成本低廉
免费注册,普通会员交易不受任何费用。
诚信通会员只须缴纳2300元年费,就可开展国内贸易,无须其他附加费用。
五、渠道广阔
A、阿里巴巴网络覆盖亚、欧、美,真正做到足不出户,照样把产品卖到国外。
B、通过阿里巴巴结识众多志同道合的网商,共同打开财富之门。
六、海量信息
通过传统渠道无法获取的供求信息,在阿里巴巴网站上,都能找到。
综合以上分析阿里巴巴目前能够有这样的成功,可以总结为这样一句话:良好的定位,稳固的结构,优秀的服务。
1、准确的定位于最初做信息交流平台绕开困难,充分发展。然后在资金流相对解决的时候推出相应的接口工具支付宝占领先机并为自己的平台提供强有力的支撑。
2、稳固的结构。WTO首任总干事萨瑟兰出任阿里巴巴顾问,美国商务部、日本经济产业省、欧洲中小企业联合会等政府和民间机构均向本地企业推荐阿里巴巴。传统渠道领域为阿里巴巴提供了强有力支撑。("倾听客户的声音,满足客户的需求"也许是阿里巴巴生存与发展的根基,根据相关的调查显示:阿里巴巴的网上会员近五成是通过口碑相传得知阿里巴巴并使用阿里巴巴;各行业会员通过阿里巴巴商务平台双方达成合作者占总会员比率近五成。)
3、在产品与服务方面,阿里巴巴公司为中国优秀的出口型生产企业提供在全球市场的"中国供应商"专业推广服务。中国供应商是依托世界级的网上贸易社区,顺应国际采购商网上商务运作的趋势,推荐中国优秀的出口商品供应商,获取更多更有价值的国际订单。截至2003年5月底加盟企业达到近3000家。目前已经有70%的被推荐企业已在网上成交,众多类别市场名额已满。2002年3月开始为全球注册会员提供进入诚信商务社区的通行证-"诚信通"服务。阿里巴巴积极倡导诚信电子商务,与邓白氏、ACP、华夏、新华信等国际国内著名的企业资信调查机构合作推出电子商务信用服务,帮助企业建立网上诚信档案,通过认证、评价、记录、检索、反馈等信用体系,提高网上交易的效率和成功的机会。每月赢收以双位数增长。
另外,除了上述谈到的方面阿里巴巴在人力资源管理理念,市场拓展战略方面都有过人的聪明远见之处。阿里巴巴所用人才按照四年的速度在更新,保持其团队的年轻与时代创新性。在市场拓展方面方面,阿里巴巴并购了雅虎中国目的就是在于做搜索引擎,阿里巴巴现在潜心培育淘宝网。商机搜索、高级智能化的商品、商家信息搜索在未来都有可能成为阿里巴巴强大的核心产品。我想,商业化的运作、超前的想象力和坚强的技术后盾加上阿里巴巴已经积累的庞大的客户,真正阿里巴巴模式也许会在2009年真的出现。
总的来说阿里巴巴网站是一个成功的网上交易平台,它提供来自全球商业机会信息以及商人交流社区,其所有的供求信息由买卖双方自动登陆,会员之间以自由开放的形式在这个平台上寻找贸易伙伴,磋谈生意。可以说在互联网上建立了一个无地理和时间障碍的自由贸易市场,用户从中可获得前所未有的商机。
它发展八年来取得了惊人的成功,这与它成功独到的商业模式是分不开的。但是我们在研究它的时候千万也要看到众多模仿该模式的企业的失败。由阿里巴巴网站的商业模式我们可以得出结论,真正开放的、内容具有本土化特色、信息全球性并且协同性强的电子商务是具有强大的生命力的。但是像这种E-market要生存和发展必须本着为企业提供公平竞争空间的原则,融合参与企业信息资源,达到规模经济效果。中国人做电子商务,不能迷信任何国家电子商务模式,必须有所借鉴亦有所自立。从阿里巴巴网站的商业模式的成功经验之中,我们不仅要学习它可以借鉴的东西,更要能为发展自己的电子商务寻找到适合中国不同阶段具体国情的自己的道路。
阿里巴巴的盈利模式:难以模仿
研究网络创收阿里巴巴是绕不过去的。
正如方博士说:“BtoB商业模式是互联网所有商业模式里面最苦最累的一个。”
如果说亚玛逊是全球B2C的典范,阿里巴巴是世界B2B的典范。它是世界规模最大而且多渠道高盈利的唯一的B2B网站。正像马云说:“直到今天为止人家还说美国没有成功的BTOB,没有上市公司做BTOB。”“我们打着望远镜也找不到竞争对手。”
阿里巴巴的盈利模式人们谈论很多,我想可否总结为:它是组合盈利拳,是进化盈利链,是动态发展的盈利模式。将其归结到企业战略和核心竞争力的一个共同点上,就是“难以模仿”。阿里巴巴的盈利模式是难以模仿的一个典型。
它的关键的棋步,如果算上准备出台的,有以下4步:
阿里巴巴成功的第一步是抢先快速圈地。1988年马云以5万元起家时,中国互联网先锋赢海威已经创办了3年。赢海威采用美国AOL的收费入网模式,这对于经济发展水平的高的国家本身经济实力强而且网络信息丰富的AOL是适用的。马运并没有采用赢海威的收入模式,而采用了免费大量争取企业的方式,这对于一个个人出资的公司,是非常有洞见和魄力的。(记得1997年,我曾经向赢海威建议为福建省获评企业赠送免费的电子邮件信箱被婉拒)。坚持这样一种模式是需要坚毅的精神的。在遭遇互联网寒冬的2001年马云给公司定了一个目标,要做最后一个站着的人。他说: “今天是很残酷,明天更残酷,后天很美好,但是很多人都看不到后天,因为他们死在明天的晚上”。 这种抢先圈地的模式坚持下来并贯彻至今,现在阿里巴巴在中国的企业会员是700万家,海外是200多万家。时机本身是最不可模仿的。现在如果谁还重复阿里巴巴的这一战略,还可能占有这么多的企业吗?
如果仅仅逗留在圈地上,可以断定阿里巴巴无法获得4次私募融资了,早就灰飞烟灭了。马云成功的第二步是利用第一步的成功开展企业的信用认证,敲开了创收的大门。信用对于重建市场经济和经济刚起飞的是中国市场交易是拦路虎,电子商务尤为突出。马云抓住了这个关键问题,2002年力排众议创新了中国的互联网上的企业诚信认证方式。如果说,这种方式在普遍讲诚信的发达国家,是多余的,在中国则是恰逢其时了。阿里巴巴既依靠了国内外的信用评价机构的优势,又结合了企业网上行为的评价,恰当配合了国家和社会对于信用的提倡。由于有了创收的渠道,2002年马云给公司提出一个目标,全年赚一块钱。到03年的时候,就达到一天有100万了。现在这个项目,阿里巴巴带来每年几千万元的不断增加的收入。
这里要特别指出,中国信用问题突出,不等于企业就愿意参与你阿里巴巴的诚信通认证。在诱导企业缴费加入“诚信通”方面阿里巴巴巧妙利用了它抢先圈地的成果。几百万的企业为它提供了大量的企业需求信息。这对于60%加工能力过剩的中国企业是非常宝贵的信息。阿里巴巴仅仅对于通过诚信通的企业提供需求信息,还通过电子邮件一年提供3600条。这些需求信息对于众多千方百计寻求订单的企业来说,其价值不言而喻,最起码也有把握现实的市场动态的参考价值。用圈地中换取的关键信息作为企业进入创收项目的“诱饵”,这也是难以模仿的无的招术。
阿里巴巴的第三部就是他掌握5000家的外商采购企业的名单,可以实实在在帮助中国企业出口。对于每家企业收费4-6万元这又为阿里巴巴带来每年大几千万元的收入,并带来国内外的知名度。这一招其他单位也可以学,但阿里巴巴等于外商的采购有最大规模的供给信息和诚信通为基础的优势,其他单位是难以模仿的。
阿里巴巴的第四招,是他今年8月收购雅虎中国后准备推出的电子商务搜索。今年3月阿里巴巴的已经推出自己的关键字竞价搜索。雅虎的搜索在中国仅低于百度3个百分点,超过全球龙头google8个百分点。现在阿里巴巴依靠雅虎每年几十亿美元技术开发投入形成的技术实力必然要有所创新。创建全球首个有影响力和创收力的专业化搜索应当是合理选择。电子商务搜索可以将电子商务的涉及的产品信息、企业信息,还有物流、支付有关信息都串通起来。可以逐步自然形成一种电子商务信息的标准。可以首先推进阿里巴巴的电子商务,并统领全国的电子商务。中国去年的出口额是1万亿美元,通过阿里巴巴做的只有100亿美元是1%,还有99%的企业并没有使用电子商务,这里面的生意潜力可就太大了。这一招将又是以前三招为基础而难以模仿的。
阿里巴巴的关键的招术并不多,但招术的单纯性、连贯性、组合性和有效性非常突出。最典型的例子就是2001年间,马云也险些迷失了方向。获得两轮风险投资后,“想做大”的马云邀请了多名在海外有优秀履历的人才。“在阿里巴巴内部,坚持各种生意模式的人都有。终于,到2002年底,马云将他们一一清退,同时,他把当时占据公司收入60%的系统集成业务一刀砍下,以保证公司继续按自己设定的方向前进。
从里巴巴模式难以模仿的盈利模式背后的思想和理念是可以模仿的,我们可以学习和仿效的阿里巴巴的是对于网络形势的深度洞察,洞察到可以翘动公司发展的杠杆点,以创新作为杠杆,还有就是翘动杠杆的执行力的坚决和坚定。如果再浓缩阿里巴巴的难以模仿的盈利模式的核心就是——难以模仿的创新。创新时就要不仅仅考虑有效性,还要考虑难以模仿性。难以模仿给阿里巴巴带来的是自然的垄断巨大效益。
我们不拒绝模仿,面对模仿的目标是难以模仿时,要以创新超越。创新是无限的,我们不要馁于模仿。
[fwding]
星期五, 十一月 30, 2007
NAS释疑
NAS简介
网络附加存储的概念 NAS是Network Attached Storage的简称,中文称为网络附加存储。在NAS存储结构中,存储系统不再通过I/O总线附属于某个服务器或客户机,而直接通过网络接口与网络直接相连,由用户通过网络访问。 NAS实际上是一个带有瘦服务器的存储设备,其作用类似于一个专用的文件服务器。这种专用存储服务器去掉了通用服务器原有的不适用的大多数计算功能,而仅仅提供文件系统功能。与传统以服务器为中心的存储系统相比,数据不再通过服务器内存转发,直接在客户机和存储设备间传送,服务器仅起控制管理的作用。 NAS的主要特点 NAS使用了传统以太网协议,当进行文件共享时,则利用了NFS和CIFS以沟通NT和Unix系统。由于NFS和CIFS都是基于操作系统的文件共享协议,所以NAS的性能特点是进行小文件级的共享存取。 NAS设备是直接连接到以太网的存储器,并以标准网络文件系统如NFS、SMB/CIFS over TCP/IP接口向客户端提供文件服务。NAS设备向客户端提供文件级的服务。但内部依然是以数据块的层面与它的存储设备通讯。文件系统是在这个NAS 存储器里。 NAS的主要长处 第一,NAS适用于那些需要通过网络将文件数据传送到多台客户机上的用户。NAS设备在数据必须长距离传送的环境中可以很好地发挥作用。 第二,NAS设备非常易于部署。可以使NAS主机、客户机和其他设备广泛分布在整个企业的网络环境中。NAS可以提供可靠的文件级数据整合,因为文件锁定是由设备自身来处理的。 第三,NAS应用于高效的文件共享任务中,例如UNIX中的NFS和Windows NT中的CIFS,其中基于网络的文件级锁定提供了高级并发访问保护的功能。 最后,在某些情况下,企业可以有限地为数据库应用部署NAS解决方案。 NAS分类 1、电器型服务器 电器型服务器是NAS系列设备中最低端的产品。电器型服务器不是专门附加的存储设备。它们为网络提供了一个存储的位置,但是由于没有冗余的以及和高性能的组件,它们相对比较便宜。在工作组环境中,电器型服务器要起很多作用。典型服务包括网络地址翻译(NAT)、代理、DHCP、电子邮件、Web服务器、DNS、防火墙和VPN。 2、工作组NAS 工作组级的NAS特别适合于存储需求相对较低的小型和中型公司,它们的存储需要一般从几百GB到1TB。运行电子商务软件或者大型数据库的公司会需要几TB的存储空间,他们使用的属于中型NAS。 一般来说,当从工作组升级到中型NAS时,你会发现热插拔驱动器和一些可以放置额外的驱动器或更多的故障恢复产品的设备盒、增强的管理功能以及系统复杂性的少许提高。 3、中型NAS 我们所说的中型NAS解决方案提供了更好的扩展性和可靠性,而且有着与低端NAS类似的优点,例如方便、专用的存储空间和简单的安装和管理过程。与电器型服务器和工作组级NAS相比,这些NAS设备的成本明显要高很多。 4、大型NAS 这类存储设备,系统的易扩展性以及高可用性和冗余性都是十分关键的。这些设备还必须提供高端服务器的性能、灵活的管理以及与异类网络平台交互的能力。
NAS是英文“Network Attached Storage”的缩写, 中文意思是“网络附加存储”。按字面简单说就是连接在网络上, 具备资料存储功能的装置,因此也称为“网络存储器”或者“网络磁盘阵列”。
从结构上讲,NAS是功能单一的精简型电脑,因此在架构上不像个人电脑那么复杂,在外观上就像家电产品,只需电源与简单的控制钮,NAS是一种专业的网络文件存储及文件备份设备,它是基于LAN(局域网)的,按照TCP/IP协议进行通信,以文件的I/O(输入/输出)方式进行数据传输。在LAN环境下,NAS已经完全可以实现异构平台之间的数据级共享,比如NT、UNIX等平台的共享。一个NAS系统包括处理器,文件服务管理模块和多个硬盘驱动器(用于数据的存储)。 NAS 可以应用在任何的网络环境当中。主服务器和客户端可以非常方便地在NAS上存取任意格式的文件,包括SMB格式(Windows)NFS格式(Unix, Linux)和CIFS(Common Internet File System)格式等等。典型的NAS的网络结构
1. NAS作为文件服务器为IP网络上的客户机上的重要数据或需共享的数据提供存储空间。利用NAS本身具有的SnapShot(快照)功能,在NAS上可制定自动的快速备份策略,将其上的重要数据进行备份恢复。
具体实现:
1) NAS将其上的某一目录共享给若干主机
2) 这些主机可通过map(映射) NAS的这个目录到其相应的驱动器的方式实现文件共享
3) 对NAS上的重要数据可通过“快照”功能进行快速保存(将数据信息直接保存在NA
NAS(Network Attached Storage,网络附属存储)
是一种将分布、独立的数据整合为大型、集中化管理的数据中心,以便于对不同主机和应用服务器进行访问的技术。
NAS被定义为一种特殊的专用数据存储服务器,包括存储器件(例如磁盘阵列、CD/DVD驱动器、磁带驱动器或可移动的存储介质)和内嵌系统软件,可提供跨平台文件共享功能。NAS通常在一个LAN上占有自己的节点,无需应用服务器的干预,允许用户在网络上存取数据,在这种配置中,NAS集中管理和处理网络上的所有数据,将负载从应用或企业服务器上卸载下来,有效降低总拥有成本,保护用户投资。
NAS本身能够支持多种协议(如NFS、CIFS、FTP、HTTP等),而且能够支持各种操作系统。通过任何一台工作站,采用IE或Netscape浏览器就可以对NAS设备进行直观方便的管理。
NAS和SAN最大的区别就在于NAS有文件操作和管理系统,而SAN却没有这样的系统功能,其功能仅仅停留在文件管理的下一层,即数据管理。SAN和NAS并不是相互冲突的,是可以共存于一个系统网络中的,但NAS通过一个公共的接口实现空间的管理和资源共享,SAN仅仅是为服务器存储数据提供一个专门的快速后方通道。
NAS和简单PC服务器的区别是什么?
从高的层面来说,NAS可以在操作系统中容纳多协议的数据传输。NAS优
于传统的PC服务器的第一个原因是它可以在你的系统中既担当Fibre Channel的存储阵列也可以担当iSCSI的阵列,而且NAS的应用依然可以采用想数据快照和复制这样的数据保护软件。
星期三, 十一月 14, 2007
本体
本体
一、 本体的概念
本体(Ontology )的概念最初起源于哲学领域,可以追溯到公元前古希腊哲学家亚里士多德(384-322 b.c.)。它在哲学中的定义为"对世界上客观存在物的系统地描述,即存在论",是客观存在的一个系统的解释或说明,关心的是客观现实的抽象本质。
在人工智能界,最早给出Ontology定义的是Neches等人,他们将Ontology定义为"给出构成相关领域词汇的基本术语和关系,以及利用这些术语和关系构成的规定这些词汇外延的规则的定义"。Neches认为:"本体定义了组成主题领域的词汇表的基本术语及其关系,以及结合这些术语和关系来定义词汇表外延的规则。"("An ontology defines the basic terms and relations comprising the vocabulary of a topic area, as well as the rules for combining terms and relations to define extensions to the vocabulary.")。后来在信息系统、知识系统等领域,越来越多的人研究Ontology,并给出了许多不同的定义。其中最著名并被引用得最为广泛的定义是由Gruber提出的,"本体是概念化的明确的规范说明",原文参见:
"An ontology is an explicit specification of a conceptualization. The term is borrowed from philosophy, where an Ontology is a systematic account of Existence. For AI systems, what "exists" is that which can be represented. When the knowledge of a domain is represented in a declarative formalism, the set of objects that can be represented is called the universe of discourse. This set of objects, and the describable relationships among them, are reflected in the representational vocabulary with which a knowledge-based program represents knowledge. Thus, in the context of AI, we can describe the ontology of a program by defining a set of representational terms. In such an ontology, definitions associate the names of entities in the universe of discourse ( e.g., classes, relations, functions, or other objects) with human-readable text describing what the names mean, and formal axioms that constrain the interpretation and well-formed use of these terms. Formally, an ontology is the statement of a logical theory."。
和这个定义类似的有N. Guarino and P. Giaretta (1995)"本体是概念化的明确的部分的说明/一种逻辑语言的模型"("an ontology is an explicit, partial account of a conceptualization/ the intended models of a logical language.")。
W. N. Borst对该定义也进行了引申"本体是共享的概念模型的形式化的规范说明"("An ontology is a formal specification of a shared conceptualization")
Fensel对这个定义进行分析后认为Ontology的概念包括四个主要方面:
1. 概念化(conceptualization):客观世界的现象的抽象模型;
2. 明确(explicit):概念及它们之间联系都被精确定义;
3. 形式化(formal):精确的数学描述;
4. 共享(share):本体中反映的知识是其使用者共同认可的。
原文:"an abstract model of a phenomenon termed 'conceptualization',a precise mathematical description hints the word 'formal', the precision of concepts and their relationships clearly defined are expressed by the term 'explicit' and the existence of an agreement between ontology users is hinted by the term 'shared'."
Swartout将本体定义为:"本体是一个为描述某个领域而按继承关系组织起来作为一个知识库的骨架的一系列术语"。("An ontology is a hierarchically structured set of terms for describing a domain that can be used as a skeletal foundation for a knowledge base.")。他的定义强调了本体中术语(terms)的重要性。
Fensel定义"本体是对一个特定领域中重要概念的共享的形式化的描述"。("An ontology is a common, shared and formal description of important concepts in an specific domain.")。
Noy F.N. 认为"本体是对某个领域中的概念的形式化的明确的表示,每个概念的特性描述了概念的各个方面及其约束的特征和属性。"("An ontology is a formal explicit representation of concepts in a domain, properties of each concept describes characteristics and attributes of the concept known as slots and constrains on these slots.")。
Fonseca定义"本体是以某一观点用详细明确的词汇表描述实体、概念、特性和相关功能的理论"。("An ontology is a theory which uses a specific vocabulary to describe entities, classes, properties and related function with certain point of view.")。
Starla认为"本体必需包括所使用术语的规范说明、决定这些术语含义的协议、以及术语之间的联系,来表达概念"。("An ontology necessarily includes a specification of the terms used (terminology) and agreements that allow to determine their meaning, along with the possible inter-relationships between these terms, standing for "concepts".")。
M. Uschold and M. Gruninger认为""("Ontology is an explicit account or representation of (some part of) a conceptualisation.")。他还推荐了一个来自SRKB(Shared Re-usable Knowledge Bases)电子邮件列表的定义"本体是关于共享的概念模型的协议。共享的概念模型包括进行领域知识建模的概念框架、互操作的agent之间进行交流的内容明确协议、以及表达特定领域理论的协定。在知识共享的上下文环境中,本体特指表达性词汇表的定义的形式。一个非常简单的例子就是分类的层次结构,指明了类和它们之间的包含关系。关系数据库模式的作用也和本体一样,它指定了某些共享数据库之间可以存在的关系以及必须保持的完整性约束"("Ontologies are agreements about shared conceptualization. Shared conceptualizations include conceptual frameworks for modeling domain knowledge; content-specific protocols for communication among inter-operating agents; and agreements about the representation of particular domain theories. In the knowledge sharing context, ontologies are specified in the form of definitions of representational vocabulary. A very simple case would be a type hierarchy, specifying classes and their subsumption relationships. Relational database shemata also serve as ontologies by specifying the relations that can exist in some shared database and the integrity constraints that must hold for them.")。
一、 本体的概念
本体(Ontology )的概念最初起源于哲学领域,可以追溯到公元前古希腊哲学家亚里士多德(384-322 b.c.)。它在哲学中的定义为"对世界上客观存在物的系统地描述,即存在论",是客观存在的一个系统的解释或说明,关心的是客观现实的抽象本质。
在人工智能界,最早给出Ontology定义的是Neches等人,他们将Ontology定义为"给出构成相关领域词汇的基本术语和关系,以及利用这些术语和关系构成的规定这些词汇外延的规则的定义"。Neches认为:"本体定义了组成主题领域的词汇表的基本术语及其关系,以及结合这些术语和关系来定义词汇表外延的规则。"("An ontology defines the basic terms and relations comprising the vocabulary of a topic area, as well as the rules for combining terms and relations to define extensions to the vocabulary.")。后来在信息系统、知识系统等领域,越来越多的人研究Ontology,并给出了许多不同的定义。其中最著名并被引用得最为广泛的定义是由Gruber提出的,"本体是概念化的明确的规范说明",原文参见:
"An ontology is an explicit specification of a conceptualization. The term is borrowed from philosophy, where an Ontology is a systematic account of Existence. For AI systems, what "exists" is that which can be represented. When the knowledge of a domain is represented in a declarative formalism, the set of objects that can be represented is called the universe of discourse. This set of objects, and the describable relationships among them, are reflected in the representational vocabulary with which a knowledge-based program represents knowledge. Thus, in the context of AI, we can describe the ontology of a program by defining a set of representational terms. In such an ontology, definitions associate the names of entities in the universe of discourse ( e.g., classes, relations, functions, or other objects) with human-readable text describing what the names mean, and formal axioms that constrain the interpretation and well-formed use of these terms. Formally, an ontology is the statement of a logical theory."。
和这个定义类似的有N. Guarino and P. Giaretta (1995)"本体是概念化的明确的部分的说明/一种逻辑语言的模型"("an ontology is an explicit, partial account of a conceptualization/ the intended models of a logical language.")。
W. N. Borst对该定义也进行了引申"本体是共享的概念模型的形式化的规范说明"("An ontology is a formal specification of a shared conceptualization")
Fensel对这个定义进行分析后认为Ontology的概念包括四个主要方面:
1. 概念化(conceptualization):客观世界的现象的抽象模型;
2. 明确(explicit):概念及它们之间联系都被精确定义;
3. 形式化(formal):精确的数学描述;
4. 共享(share):本体中反映的知识是其使用者共同认可的。
原文:"an abstract model of a phenomenon termed 'conceptualization',a precise mathematical description hints the word 'formal', the precision of concepts and their relationships clearly defined are expressed by the term 'explicit' and the existence of an agreement between ontology users is hinted by the term 'shared'."
Swartout将本体定义为:"本体是一个为描述某个领域而按继承关系组织起来作为一个知识库的骨架的一系列术语"。("An ontology is a hierarchically structured set of terms for describing a domain that can be used as a skeletal foundation for a knowledge base.")。他的定义强调了本体中术语(terms)的重要性。
Fensel定义"本体是对一个特定领域中重要概念的共享的形式化的描述"。("An ontology is a common, shared and formal description of important concepts in an specific domain.")。
Noy F.N. 认为"本体是对某个领域中的概念的形式化的明确的表示,每个概念的特性描述了概念的各个方面及其约束的特征和属性。"("An ontology is a formal explicit representation of concepts in a domain, properties of each concept describes characteristics and attributes of the concept known as slots and constrains on these slots.")。
Fonseca定义"本体是以某一观点用详细明确的词汇表描述实体、概念、特性和相关功能的理论"。("An ontology is a theory which uses a specific vocabulary to describe entities, classes, properties and related function with certain point of view.")。
Starla认为"本体必需包括所使用术语的规范说明、决定这些术语含义的协议、以及术语之间的联系,来表达概念"。("An ontology necessarily includes a specification of the terms used (terminology) and agreements that allow to determine their meaning, along with the possible inter-relationships between these terms, standing for "concepts".")。
M. Uschold and M. Gruninger认为""("Ontology is an explicit account or representation of (some part of) a conceptualisation.")。他还推荐了一个来自SRKB(Shared Re-usable Knowledge Bases)电子邮件列表的定义"本体是关于共享的概念模型的协议。共享的概念模型包括进行领域知识建模的概念框架、互操作的agent之间进行交流的内容明确协议、以及表达特定领域理论的协定。在知识共享的上下文环境中,本体特指表达性词汇表的定义的形式。一个非常简单的例子就是分类的层次结构,指明了类和它们之间的包含关系。关系数据库模式的作用也和本体一样,它指定了某些共享数据库之间可以存在的关系以及必须保持的完整性约束"("Ontologies are agreements about shared conceptualization. Shared conceptualizations include conceptual frameworks for modeling domain knowledge; content-specific protocols for communication among inter-operating agents; and agreements about the representation of particular domain theories. In the knowledge sharing context, ontologies are specified in the form of definitions of representational vocabulary. A very simple case would be a type hierarchy, specifying classes and their subsumption relationships. Relational database shemata also serve as ontologies by specifying the relations that can exist in some shared database and the integrity constraints that must hold for them.")。
星期五, 九月 28, 2007
[fwd]12个J2EE最佳实践
12个最重要的J2EE最佳实践
1. 始终使用 MVC 框架。
MVC 框架可以将业务逻辑(Java beans 和 EJB 组件)、控制器逻辑 (Servlets/Struts 动作)、表示层(JSP、XML/XSLT)清晰地分离开来。良好的分层可以带来许多好处。
MVC 框架对于成功使用 J2EE 是如此重要,以致没有其他最佳实践可以与其相提并论。模型-视图-控制器(MVC)是设计 J2EE 应用程序的基础。MVC 将您的程序代码 简单地划分下面几个部分:
负责业务逻辑的代码(即模型??通常使用 EJB 或者普通的 Java 对象来实现)。
负责用户界面 显示的代码(即视图??通常通过 JSP 及标记库来实现,有时也使用 XML 和 XSLT 来实现)。
负责应用程序流程的代码(即控制器?? 通常使用 Java Servlet 或像 Struts 控制器这样的类来实现)。
如果您不遵循基本的 MVC 框架,在开发过程中就会出现许多的问 题。最常见的问题就是在视图部分添加了太多的成分,例如,可能存在使用 JSP 标记来执行数据库访问,或者在 JSP 中进行应用程序的流程 控制,这在小规模的应用程序中是比较常见的,但是,随着后期的开发,这样做将会带来问题,因为 JSP 逐步变得越来越难以维护和调试。
类似地,我们也经常看到将视图层构建到业务逻辑的情况。例如,一个常见的问题就是将在构建视图时使用的 XML 解析技术直接应用 到业务层。业务层应该对业务对象??而不是绑定到视图的特定数据表示进行操作。
然而,只是具有合适的组件并不一定意味着可以使 您的应用程序得到合适的分层。我们常常见到一些应用程序包含 servlet、JSP 和 EJB 组件所有这三项,然而,其主要的业务逻辑却是在 servlet 层实现的,或者应用程序导航是在 JSP 中处理的。您必须进行严格的代码检查并重构您的代码,以确保应用程序的业务逻辑只在模型 层(Model layer)进行处理,应用程序导航只通过控制器层(Controller layer)进行处理,而您的视图(Views)只是将传递过来的模型对 象以 HTML 及 JavaScript 的形式表示出来。
2. 在应用程序的每一层都使用自动单元测试和测试管理。
不要只是测试您的图形用户界面(GUI)。分层的测试使测试及维护工作变得极其简单。
在过去的几年中,在方法学领域有了 相当大的革新,例如新出现的被称为 Agile(例如 SCRUM [Schwaber] 和极限编程 [Beck1])的轻量级方法现在已经得到了很普遍的应用。几 乎所有的这些方法中的一个共同的特征是它们都提倡使用自动的测试工具,这些工具可以帮助开发人员用更少的时间进行回归测试 (regression testing),并可以帮助他们避免由于不充分的回归测试造成的错误,因此可以用来提高程序员的工作效率。实际上,还有一种被 称为 Test-First Development [Beck2] 的方法,这种方法甚至提倡在开发实际的代码之前就先编写单元测试。然而,在您测试代码之前,您 需要将代码分割成一些可测试的片断。一个"大泥球"是难以测试的,因为它不是只实现一个简单的易于识别的功能。如果您的每个代码片断实 现多个方面的功能,这样的代码将难以保证其完全的正确性。
MVC 框架(以及 J2EE 中的 MVC 实现)的一个优点就是元素的组 件化能够(实际上,相当的简单)对您的应用程序进行单元测试。因此,您可以方便地对实体 bean、会话 bean 以及 JSP 独立编写测试用例 ,而不必考虑其他的代码。现在有许多用于 J2EE 测试的框架和工具,这些框架及工具使得这一过程更加简单。例如,JUnit(是一种由 junit.org 开发的开放源代码工具)和 Cactus(由 Apache 开发的开放源代码工具)对于测试 J2EE 组件都非常有用。[Hightower] 详细探讨 了如何在 J2EE 中使用这些工具。
尽管所有这些详述了怎样彻底地测试您的应用程序,但是我们仍然看到一些人认为只要他们测试了 GUI(可能是基于 Web 的 GUI,或者是独立的 Java 应用程序),则他们就全面地测试了整个应用程序。GUI 测试很难达到全面的测试,有以 下几种原因。首先,使用 GUI 测试很难彻底地测试到系统的每一条路径,GUI 仅仅是影响系统的一种方式,可能存在后台运算、脚本和各种各 样的其他访问点,这也需要进行测试。然而,它们通常并不具有 GUI。第二,GUI 级的测试是一种非常粗粒度的测试。这种测试只是在宏观水 平上测试系统的行为。这意味着一旦发现存在问题,则与此问题相关的整个子系统都要进行检查,这使得找出 bug(缺陷)将是非常困难的事 情。第三,GUI 测试通常只有在整个开发周期的后期才能很好地得到测试,这是因为只有这那个时候 GUI 才得到完整的定义。这意味着只有在 后期才可能发现潜在的 bug。第四,一般的开发人员可能没有自动的 GUI 测试工具。因此,当一个开发人员对代码进行更改时,没有一种简单 的方法来重新测试受到影响的子系统。这实际上不利于进行良好的测试。如果开发人员具有自动的代码级单元测试工具,开发人员就能够很容 易地运行这些工具以确保所做的更改不会破坏已经存在的功能。最后,如果添加了自动构建功能,则在自动构建过程中添加一个自动的单元测 试工具是非常容易的事情。当完成这些设置以后,整个系统就可以有规律地进行重建,并且回归测试几乎不需要人的参与。
另外 ,我们必须强调,使用 EJB 和 Web 服务进行分布式的、基于组件的开发使得测试单个的组件变得非常必要。如果没有"GUI"需要测试,您就必 须进行低级(lower-level)测试。最好以这种方式开始测试,省得当您将分布式的组件或 Web 服务作为您的应用程序的一部分时,您不得不 花费心思重新进行测试。
总之,通过使用自动的单元测试,能够很快地发现系统的缺陷,并且也易于发现这些缺陷,使得测试工作变 得更加系统化,因此整体的质量也得以提高。
3. 按照规范来进行开发,而不是按照应用服务器来进行开发。
要将规范熟记于心,如果要背离规范,要经过慎密的考虑后才可以这样做。这是因为当您背离规则的时候,您所做的事情往往并不是 您应该做的事情。
当您要背离 J2EE 可以允许您做的事情的时候,这很容易让使您遭受不幸。我们发现有一些开发人员钻研一些 J2EE 允许之外的东西,他们认为这样做可以"稍微"改善J2EE的性能,而他们最终只会发现这样做会引起严重的性能问题,或者在以后的移植( 从一个厂商到另一个厂商,或者是更常见的从一个版本到另一个版本)中会出现问题。实际上,这种移植问题是如此严重,以致 [Beaton] 将 此原则称为移植工作的基本最佳实践。
现在有好几个地方如果不直接使用 J2EE 提供的方法肯定会产生问题。一个常见的例子 就是开发人员通过使用 JAAS 模块来替代 J2EE 安全性,而不是使用内置的遵循规范的应用程序服务器机制来进行验证和授权。要注意不要脱 离 J2EE 规范提供的验证机制,如果脱离了此规范,这将是系统存在安全漏洞以及厂商兼容性问题的主要原因。类似地,要使用 servlet 和 EJB 规范提供的授权机制,并且如果您要偏离这些规范的话,要确保使用规范定义的 API(例如 getCallerPrincipal())作为实现的基础。通 过这种方式,您将能够利用厂商提供的强安全性基础设施,其中,业务要求需要支持复杂的授权规则。
其他常见的问题包括使用不遵 循 J2EE 规范的持久性机制(这使得事务管理变得困难)、在J2EE程序中使用不适当的J2SE 方法(例如线程或 singleton),以及使用您自己 的方法解决程序到程序(program-to-program)的通信,而不是使用 J2EE 内在支持的机制(例如 JCA、JMS 或 Web 服务)。当您将一个遵循 J2EE 的服务器移植到其他的服务器上,或者移植到相同服务器的新版本上,上述的设计选择将会造成无数的问题。唯一要背离规范的情况是, 当一个问题在规范的范围内无法解决的时候。例如,安排执行定时的业务逻辑在 EJB2.1 出现之前是一个问题,在类似这样的情况下,我们建 议当有厂商提供的解决方案时就使用厂商提供的解决方案(例如 WebSphere Application Server Enterprise 中的 Scheduler 工具),而在 没有厂商提供的解决方案时就使用第三方提供的工具。如果使用厂商提供的解决方案,应用程序的维护以及将其移植到新的规范版本将是厂商 的问题,而不是您的问题。
最后,要注意不要太早地采用新技术。太过于热衷采用还没有集成到 J2EE 规范的其他部分或者还 没有集成到厂商的产品中的技术常会带来灾难性的后果。支持是关键的??如果您的厂商不直接支持一种特定的在 JSR 中提出的技术,但此技术 还没有被 J2EE 所接受,那么您就不应该采用此技术。毕竟,我们中的大多数人从事解决业务问题,而不是推进技术的发展。
4. 从一开始就计划使用 J2EE 安全性。
启用 WebSphere 安全性。这使您的 EJB 和 URL 至少可以让所 有授权用户访问。不要问为什么??照着做就是了。
在与我们合作的客户中,一开始就打算启用 WebSphere J2EE 安全性的顾客 是非常少的,这一点一直让我们感到吃惊。据我们估计大约只有 50% 的顾客一开始就打算使用此特性。例如,我们曾与一些大型的金融机构( 银行、代理等等)合作过,他们也没有打算启用安全性。幸运的是,这种问题在部署之前的检查时就得以解决.
不使用 J2EE 安全性 是危险的事情。假设您的应用程序需要安全性(几乎所有的应用程序都需要),您敢打赌您的开发人员能够构建出自己的安全性系统,而这个 系统比您从 J2EE 厂商那里买来的更好。这可不是个好的赌注,为分布式的应用程序提供安全性是异常困难的。例如,您需要使用网络安全加 密令牌控制对 EJB 的访问。以我们的经验看来,大多数自己构建的安全性系统是不安全的,并且有重大的缺陷,这使产品系统极其脆弱。
一些不使用 J2EE 安全性的理由包括:担心性能的下降,相信其他的安全性(例如 Netegrity SiteMinder)可以取代 J2EE 安全性, 或者是不知道 WebSphere Application Server 安全特性及功能。不要陷入这些陷阱之中,尤其是,尽管像 Netegrity SiteMinder 这样的产 品能够提供优秀的安全特性,但是仅仅其自身不可能保护整个 J2EE 应用程序。这些产品必须与 J2EE 应用程序服务器联合起来才可能全面地 保护您的系统。
其他的一种常见的不使用 J2EE 安全性的原因是:基于角色的模型没有提供足够的粒度访问控制以满足复杂的业务规 则。尽管事实是这样的,但这也不应该成为不使用 J2EE 安全性的理由。相反地,应该将 J2EE 验证及 J2EE 角色与特定的扩展规则结合起来 。如果复杂的业务规则需要做出安全性决策,那就编写相应的代码,其安全性决策要基于可以直接使用的以及可靠的 J2EE 验证信息(用户 ID 和角色)。
5. 创建您所知道的
反复的开发工作将使您能够逐渐地掌握所有的 J2EE 模块。要从创建小而简单的模块开 始而不是从一开始就马上涉及到所有的模块。
我们必须承认 J2EE 是庞大的体系。如果一个开发小组只是开始使用 J2EE,这将很难 一下子就能掌握它。在 J2EE 中有太多的概念和 API 需要掌握。在这种情况下,成功掌握 J2EE 的关键是从简单的步骤开始做起。
这种方法可以通过在您的应用程序中创建小而简单的模块来得到最好的实现。如果一个开发小组通过创建一个简单的域模型以 及后端的持久性机制(也许使用的是 JDBC),并且对其进行了完整的测试,这会增强他们的自信心,于是他们会使用该域模型去掌握使用 servlet 和 JSP 的前端开发。如果一个开发组发现有必要使用 EJB,他们也会类似地开始在容器管理的持久性 EJB 组件之上使用简单的会话 Facades,或者使用基于 JDBC 的数据访问对象(JDBC-based Data Access Objects,DAO),而不是跳过这些去使用更加复杂的构造(例如消 息驱动bean和JMS)。
这种方法并不是什么新方法,但是很少有开发组以这种方式来培养他们的技能。相反地,多数开发组由于尝试 马上就构建所有的模块,同时涉及 MVC 中的视图层、模型层和控制器层,这样做的结果是他们往往会陷入进度的压力之中。他们应该考虑一些 敏捷(Agile)开发方法,例如极限编程(XP),这种开发方法采用一种增量学习及开发方法。在 XP 中有一种称为 ModelFirst 的过程,这个 过程涉及到首先构建域模型作为一种机制来组织和实现用户场景。基本说来,您要构建域模型作为您要实现的用户场景的首要部分,然后在域 模型之上构建一个用户界面(UI)作为用户场景实现的结果。这种方法非常适合让一个开发组一次只学到一种技术,而不是让他们同时面对很 多种情况(或者让他们读很多书),这会令他们崩溃的。
还有,对每个应用程序层重复的开发可能会包含一些适当的模式及最佳实践 。如果您从应用程序的底层开始应用一些模式如数据访问对象和会话 Facades,您就不应该在您的JSP和其他视图对象中使用域逻辑。
最后,当您开发一些简单的模块时,在开始的初期就可以对您的应用程序进行性能测试。如果直到应用程序开发的后期才进行性能测 试的话,这往往会出现灾难性的后果。
6. 当使用 EJB 组件时,始终使用会话 Facades。
决不 要将实体 bean 直接暴露给任何用户类型。对实体 bean 只可以使用本地 EJB 接口(Local EJB interfaces)。
当使用 EJB 组件时 ,使用一个会话 Facades 是一个确认无疑的最佳实践。实际上,这个通用的实践被广泛地应用到任何分布式的技术中,包括 CORBA、EJB 和 DCOM。从根本上讲,您的应用程序的分布"交叉区域"越是底层化,对小块的数据由于多次重复的网络中继造成的时间消耗就越少。要达到这个 目的的方法就是:创建大粒度的 Facades 对象,这个对象包含逻辑子系统,因而可以通过一个方法调用就可以完成一些有用的业务功能。这种 方法不但能够降低网络开销,而且在 EJB 内部通过为整个业务功能创建一个事务环境也可以大大地减少对数据库的访问次数。
EJB 本地接口(从 EJB 2.0 规范开始使用)为共存的 EJB 提供了性能优化方法。本地接口必须被您的应用程序显式地进行访问,这需要代码的改 变和防止以后配置 EJB 时需要应用程序的改变。由于会话 Facades 和它包含的整个 EJB 对于彼此来说都应该是本地的,我们建议对会话 Facades 后面的实体 bean 使用本地接口。然而,会话 Facades 本身的实现(典型例子如无状态会话 bean)应该设计为远程接口。
为了性能的优化,可以将一个本地接口添加到会话 Facades。这样做利用了这样一个事实:在大多数情况下(至少在 Web 应用程序中),您的 EJB 客户端和 EJB 会共同存在于同一个 Java 虚拟机(JVM)中。另外一种情况,如果会话 Facades 在本地被调用,可以使用 J2EE 应用服务 器配置优化(configuration optimizations),例如 WebSphere 中的"No Local Copies"。然而,您必须注意到这些可供选择的方案会将交互 方法从按值传递(pass-by-value)改变为按引用传递(pass-by-reference)。这可能会在您的代码中产生很微妙的错误。当您要利用这些方 案时,您应该在一开始就考虑其可行性。
如果在您的会话 Facades 中使用远程接口(而不是本地接口),您也可以将同样的会 话 Facades 在 J2EE 1.4 中以兼容的方式作为 Web 服务来配置。这是因为 JSR 109(J2EE 1.4 中的 Web 服务部署部分)要求使用无状态会 话 bean 的远程接口作为 EJB Web 服务和 EJB 实现的接口。这样做是值得的,因为这样做可以为您的业务逻辑增加客户端类型的数量。
7. 使用无状态会话 bean,而不是有状态会话 bean
这样做可以使您的系统经得起错误的终止。使用 HttpSession 存储和用户相关的状态。
以我们的观点看来,有状态会话 bean 的概念已经过时了。如果您仔细对其考虑一下,一个有 状态会话 bean 实际上与一个 CORBA 对象在体系结构上是完全相同的,无非就是一个对象实例,绑定到一个服务器,并且依赖于服务器来管理 其生命周期。如果服务器关闭了,这种对象也就不存在,那么这个 bean 的客户端的信息也就不存在。
J2EE 应用服务器为有状态会 话 bean 提供的故障转移(failover)能够解决一些问题,但是有状态的解决方案没有无状态的解决方案易于扩展。例如,在 WebSphere Application Server 中,对无状态会话 bean 的请求,是通过对部署无状态会话的成员集群进行平衡加载来实现。相反地,J2EE 应用服务器 不能对有状态 bean 的请求进行平衡加载。这意味着您的集群中的服务器的加载过程会是不均衡的。此外,使用有状态会话 bean 将会再添加 一些状态到您的应用服务器上,这也是不好的做法。这样就增加了系统的复杂性,并且在出现故障的情况下使问题变得复杂化。创建健壮的分 布式系统的一个关键原则是尽量使用无状态行为。
因此,我们建议对大多数应用程序使用无状态会话 bean 方法。任何在处理时需要 使用的与用户相关的状态应该以参数的形式传送到 EJB 的方法中(并且通过使用一种机制如 HttpSession 来存储它)或者从持久性的后端存 储(例如通过使用实体 bean)作为 EJB 事务的一部分来进行检索。在合适的情况下,这个信息可以缓存到内存中,但是要注意在分布式的环境 中保存这种缓存所潜在的挑战性。缓存非常适合于只读数据。
总之,您要确保从一开始就要考虑到可伸展性。检查设计中的所有设想 ,并且考虑到当您的应用程序要在多个服务器上运行时,是否也可以正常运行。这个规则不但适合上述情况的应用程序代码,也适用于如 MBean 和其他管理界面的情况下。
避免使用有状态性不只是对 IBM/WebSphere 的建议,这是一个基本的 J2EE 设计原则。
8. 使用容器管理的事务
学习一下 J2EE 中的两阶段提交事务,并且使用这种方式,而不是开放您自己的 事务管理。容器在事务优化方面几乎总是比较好的。
使用容器管理的事务(CMT)提供了两个关键的优势(如果没有容器支持这几乎 是不可能的):可组合的工作单元和健壮的事务行为。
如果您的应用程序代码显式地使用了开始和结束事务(也许使用 javax.jts.UserTransaction 或者甚至是本地资源事务),而将来的要求需要组合模块(也许会是代码重构的一部分),这种情况下往往需要 改变事务代码。例如,如果模块 A 开始了一个数据库事务,更新数据库,随后提交事务,并且有模块 B 做出同样的处理,请考虑一下当您在 模块 C 中尝试使用上述两个模块,会出现什么情况呢?现在,模块 C 正在执行一个逻辑动作,而这个动作实际上将调用两个独立的事务。如 果模块 B 在执行中失败了,而模块 A 的事务仍然能被提交。这是我们所不希望出现的行为。如果,相反地,模块 A 和模块 B 都使用 CMT 的 话,模块 C 也可以开始一个 CMT(通常通过配置描述符),并且在模块 A 和模块 B 中的事务将是同一个事务的隐含部分,这样就不再需要复 杂的重写代码的工作了。
如果您的应用程序在同一个操作中需要访问多种资源,您就要使用两阶段提交事务。例如,如果从 JMS 队 列中删除一个消息,并且随后更新基于这条消息的纪录,这时,要保证这两个操作都会执行或都不会执行就变得尤为重要。如果一条消息已经 从队列中被删除,而系统没有更新与此消息相关的数据库中的纪录,那么这种系统是不稳定的。一些严重的客户及商业纠纷源自不一致的状态 。
我们时常看到一些客户应用程序试图实现他们自己的解决方案。也许会通过应用程序的代码在数据库更新失败的时候 "撤销"对队 列的操作。我们不提倡这样做。这种实现要比您最初的想象要复杂得多,并且还有许多其他的情况(想象一下如果应用程序在执行此操作的过 程中突然崩溃的情况)。作为替代的方式,应该使用两阶段提交事务。如果您使用 CMT,并且在一个单一的 CMT 中访问两阶段提交的资源(例 如 JMS 和大多数数据库),WebSphere 将会处理所有的复杂工作。它将确保整个事务被执行或者都不被执行,包括系统崩溃、数据库崩溃或其 他的情况。其实现在事务日志中保存着事务状态。当应用程序访问多种资源的时候,我们怎么强调使用 CMT 事务的必要性都不为过。
9. 将 JSP 作为表示层的首选
只有在需要多种表示输出类型,并且输出类型被一个单一的控制器及后端支持时才使 用 XML/XSLT。
我们常听到一些争论说,为什么您选择 XML/XSLT 而不是 JSP 作为表示层技术。选择 XML/XSLT 的人的观点是,JSP" 允许您将模型和视图混合在一起",而 XML/XSLT 不会有这种问题。遗憾的是,这种观点并不完全正确,或者至少不像白与黑那样分的清楚。实 际上,XSL 和 XPath 是编程语言。XSL 是图灵完成的(Turing-complete),尽管它不符合大多数人定义的编程语言,因为它是基于规则的, 并且不具备程序员习惯的控制工具。
现在的问题是既然给予了这种灵活性,开发人员就会利用这种灵活性。尽管每个人都认同 JSP 使开发人员容易在视图中加入"类似模型"的行为,而实际上,在 XSL 中也有可能做出一些同样的事情。尽管从 XSL 中进行访问数据库这样的 事情会非常困难,但是我们曾经见到过一些异常复杂的 XSLT 样式表执行复杂的转换,这实际上是模型代码。
然而,应该选择 JSP 作为首选的表示技术的最基本的原因是,JSP 是现在支持最广泛的、也是最被广泛理解的 J2EE 视图技术。而随着自定义标记库、JSTL 和 JSP2.0 的新特性的引入,创建 JSP 变得更加容易,并且不需要任何 Java 代码,以及可以将模型和视图清晰的分离开。在一些开发环境中( 如 WebSphere Studio)加入了对 JSP(包括对调试的支持)的强大支持,并且许多开发人员发现使用 JSP 进行开发要比使用 XLS 简单,一些 支持 JSP 的图形设计工具及其他特征(尤其在 JSF 这样的框架下)使得开发人员可以以所见即所得的方式进行 JSP 的开发,而对于 XSL 有 时不容易做到。
最后一个要谨慎考虑使用 JSP 的原因是速度问题。在 IBM 所作的对比 XSL 和 JSP 相对速度的性能测试显示:在大 多数情况下,JSP 在生成同样的 HTML 的时候,要比 XSL 快好几倍,甚至使用编译过的 XSL 也是如此。尽管多数情况下这不是问题,但在性 能要求很高的情况下,这就会成为问题。
然而,这也不能说,您永远也不要使用 XSL。在一些情况下,XSL 能够表示一组固定的数据 ,并且可以基于不同的样式表来以不同的方式显示这些数据的能力是显示视图的最佳解决方案。然而,这只是一种例外的情况,而不是通用的 规则。如果您只是生成 HTML 来表达每一个页面,那么在大多数情况下,XSL 是一种不必要的技术,并且,它给您的开发人员所带来的问题远 比它所能解决的问题多。
10. 当使用 HttpSession 时,尽量只将当前事务所需要的状态保存其中,其他内容不要保存在 HttpSession 中。
启用会话持久性。
HttpSessions 对于存储应用程序状态信息是非常有用的。其 API 易于使用和理解。遗憾的是,开发人员常常遗忘了 HttpSession 的目的----用来保持暂时的用户状态。它不是任意的数据缓存。我们已经 见到过太多的系统为每个用户的会话放入了大量的数据(达到兆字节)。那好了,如果同时有 1000 个登录系统的用户,每个用户拥有 1MB 的 会话数据,那么就需要 1G 或者更多的内存用于这些会话。要使这些 HTTP 会话数据较小一些,不然的话,您的应用程序的性能将会下降。一 个大约比较合适的数据量应该是每个用户的会话数据在 2K-4K 之间,这不是一个硬性的规则,8K 仍然没有问题,但是显然会比 2K 时的速度 要慢。一定要注意,不要使 HttpSession 变成数据堆积的场所。
一个常见的问题是使用 HttpSession 缓存一些很容易再创建 的信息,如果有必要的话。由于会话是持久性的,进行不必要的序列化以及写入数据是一种很奢侈的决定。相反地,应该使用内存中的哈希表 来缓存数据,并且在会话中保存一个对此数据进行引用的关键字。这样,如果不能成功登录到另外的应用服务器的话,就可以重新创建数据。
当谈及会话持久性时,不要忘记要启用这项功能。如果您没有启用会话持久性,或者服务器因为某种原因停止了(服务器故障或正常 的维护),则所有此应用服务的当前用户的会话将会丢失。这是件令人非常不高兴的事情。用户不得不重新登录,并且重新做一些他们曾经已 经做过的事情。相反地,如果启用了会话持久性,WebSphere 会自动将用户(以及他们的会话)移到另外一个应用服务器上去。用户甚至不知 道会有这种事情的发生。我们曾经见到过一些产品系统因为存在于本地代码中令人难以忍受的 bug(不是 IBM 的代码!)而突然崩溃的情况, 这这种情况下,上述功能仍然可以运行良好。
11. 在 WebSphere 中,使用动态缓存,并使用 WebSphere servlet 缓 存机制。
通过使用这些功能,系统性能可以得到很大的提高,而开销是很小的。并且不影响编程模型。
通 过缓存来提高性能的好处是众所周知的事情。遗憾的是,当前的 J2EE 规范没有包括一种用于 servlet/JSP 缓存的机制。然而,WebSphere 提 供了对页面以及片断缓存的支持,这种支持是通过其动态缓存功能来实现的,并且不需要对应用程序作出任何改变。其缓存的策略是声明性的 ,而且其配置是通过 XML 配置描述符来实现的。因此,您的应用程序不会受到影响,并保持与 J2EE 规范的兼容性和移植性,同时还从 WebSphere 的 servlet 及 JSP 的缓存机制中得到性能的优化。
从 servet 及 JSP 的动态缓存机制得到的性能的提高是显而易见的 ,这取决于应用程序的特性。Cox 和 Martin [Cox] 指出对一个现有的 RDF(资源描述格式)站点摘要 (RSS)servlet,当使用动态缓存时,其 性能可以提高 10%。请注意这个实验只涉及到一个简单的 servlet,这个性能的增长量可能并不能反映一个复杂的应用程序。
为了更 多地提高性能,将 WebSphere servlet/JSP 结果缓存与 WebSphere 插件 ESI Fragment 处理器、IBM HTTP Server Fast Response Cache Accelerator (FRCA) 和 Edge Server 缓存功能集成在一起。对于繁重的基于读取的工作负荷,通过使用这些功能可以得到许多额外的好处。
12. 为了提高程序员的工作效率,将 CMP 实体 bean 作为 O/R 映射的首选解决方案.
通过 WebSphere 框架(readahead、缓存、隔离级别等)优化性能。如果可能,有选择的应用一些模式来达到提高性能的目的,例如 Fast-Lane 阅读器 [Marinescu]。
对象/关系(O/R)映射是使用 Java 创建企业级的应用程序的基础。几乎每个 J2EE 应用程序都需要一些类型的 O/R 映射。J2EE 厂商提供一种 O/R 映射机制,这种机制在不同的厂商间是可移植的,高效的,并且能够被一些标准及工具很好地支持。这就是 EJB 规范中的 CMP(容器管理的持久性)部分。
早期的 CMP 实现以表现不佳及不支持许多 SQL 结构而著称。然而,随着 EJB 2.0 及 2.1 规范的出现,以及被一些厂商所采纳,并且随着像 IBM WebSphere Studio Application Developer 的出现,这些问题已经不再是问题 了。
CMP EJB 组件现在已经被广泛地应用于许多高性能的应用程序中。WebSphere 包括一些优化功能以提高 EJB 组件的性能,优化 功能包括:对生命周期的缓存和 read-ahead 能力。这两者优化功能都是配置时的选项,并且不需要对应用程序进行修改或者影响可移植性。
处于缓存状态的生命周期缓存 CMP 状态数据并提供基于时间的无效性。从处于缓存状态的生命周期得到的性能提高可以达到选项 A 的缓存性能,并且仍然可以为您的应用程序提供可伸展性。Read-ahead 能力和容器管理的关系结合使用。这个特性通过在相同的查询中随意地 检索相关的数据作为父数据而减少与数据库的交互。如果相关的数据要通过使用并发的查询来访问的话,这种方法可以得到性能的改进。 [Gunther]提供了详细的描述以及通过这些特性得到的性能提高的细节。
此外,为了完全优化您的 EJB 组件,当指定隔离级别时要特 别注意。尽可能使用最低的隔离级别,并且仍然保持您的数据的完整性。较低的隔离级别可以提供最佳的性能,并且可以降低出现数据库死锁 的危险。
这是目前最有争议的最佳实践。已经有大量的文章赞扬 CMP EJB,同样的贬斥声也不绝于耳。然而,这里最基本的问题是数 据库开发是困难的。当您开始使用任何持久性解决方案之前,您需要掌握查询以及数据库锁定如何工作这些基础知识。如果您选择使用 CMP EJB,您要确保您已经通过一些书籍(例如 [Brown] 和 [Barcia])知道如何使用它们。在锁定及争用方面有一些微妙的交互难以理解,但是, 在您耗费一定的时间及努力后会将其掌握的。
1. 始终使用 MVC 框架。
MVC 框架可以将业务逻辑(Java beans 和 EJB 组件)、控制器逻辑 (Servlets/Struts 动作)、表示层(JSP、XML/XSLT)清晰地分离开来。良好的分层可以带来许多好处。
MVC 框架对于成功使用 J2EE 是如此重要,以致没有其他最佳实践可以与其相提并论。模型-视图-控制器(MVC)是设计 J2EE 应用程序的基础。MVC 将您的程序代码 简单地划分下面几个部分:
负责业务逻辑的代码(即模型??通常使用 EJB 或者普通的 Java 对象来实现)。
负责用户界面 显示的代码(即视图??通常通过 JSP 及标记库来实现,有时也使用 XML 和 XSLT 来实现)。
负责应用程序流程的代码(即控制器?? 通常使用 Java Servlet 或像 Struts 控制器这样的类来实现)。
如果您不遵循基本的 MVC 框架,在开发过程中就会出现许多的问 题。最常见的问题就是在视图部分添加了太多的成分,例如,可能存在使用 JSP 标记来执行数据库访问,或者在 JSP 中进行应用程序的流程 控制,这在小规模的应用程序中是比较常见的,但是,随着后期的开发,这样做将会带来问题,因为 JSP 逐步变得越来越难以维护和调试。
类似地,我们也经常看到将视图层构建到业务逻辑的情况。例如,一个常见的问题就是将在构建视图时使用的 XML 解析技术直接应用 到业务层。业务层应该对业务对象??而不是绑定到视图的特定数据表示进行操作。
然而,只是具有合适的组件并不一定意味着可以使 您的应用程序得到合适的分层。我们常常见到一些应用程序包含 servlet、JSP 和 EJB 组件所有这三项,然而,其主要的业务逻辑却是在 servlet 层实现的,或者应用程序导航是在 JSP 中处理的。您必须进行严格的代码检查并重构您的代码,以确保应用程序的业务逻辑只在模型 层(Model layer)进行处理,应用程序导航只通过控制器层(Controller layer)进行处理,而您的视图(Views)只是将传递过来的模型对 象以 HTML 及 JavaScript 的形式表示出来。
2. 在应用程序的每一层都使用自动单元测试和测试管理。
不要只是测试您的图形用户界面(GUI)。分层的测试使测试及维护工作变得极其简单。
在过去的几年中,在方法学领域有了 相当大的革新,例如新出现的被称为 Agile(例如 SCRUM [Schwaber] 和极限编程 [Beck1])的轻量级方法现在已经得到了很普遍的应用。几 乎所有的这些方法中的一个共同的特征是它们都提倡使用自动的测试工具,这些工具可以帮助开发人员用更少的时间进行回归测试 (regression testing),并可以帮助他们避免由于不充分的回归测试造成的错误,因此可以用来提高程序员的工作效率。实际上,还有一种被 称为 Test-First Development [Beck2] 的方法,这种方法甚至提倡在开发实际的代码之前就先编写单元测试。然而,在您测试代码之前,您 需要将代码分割成一些可测试的片断。一个"大泥球"是难以测试的,因为它不是只实现一个简单的易于识别的功能。如果您的每个代码片断实 现多个方面的功能,这样的代码将难以保证其完全的正确性。
MVC 框架(以及 J2EE 中的 MVC 实现)的一个优点就是元素的组 件化能够(实际上,相当的简单)对您的应用程序进行单元测试。因此,您可以方便地对实体 bean、会话 bean 以及 JSP 独立编写测试用例 ,而不必考虑其他的代码。现在有许多用于 J2EE 测试的框架和工具,这些框架及工具使得这一过程更加简单。例如,JUnit(是一种由 junit.org 开发的开放源代码工具)和 Cactus(由 Apache 开发的开放源代码工具)对于测试 J2EE 组件都非常有用。[Hightower] 详细探讨 了如何在 J2EE 中使用这些工具。
尽管所有这些详述了怎样彻底地测试您的应用程序,但是我们仍然看到一些人认为只要他们测试了 GUI(可能是基于 Web 的 GUI,或者是独立的 Java 应用程序),则他们就全面地测试了整个应用程序。GUI 测试很难达到全面的测试,有以 下几种原因。首先,使用 GUI 测试很难彻底地测试到系统的每一条路径,GUI 仅仅是影响系统的一种方式,可能存在后台运算、脚本和各种各 样的其他访问点,这也需要进行测试。然而,它们通常并不具有 GUI。第二,GUI 级的测试是一种非常粗粒度的测试。这种测试只是在宏观水 平上测试系统的行为。这意味着一旦发现存在问题,则与此问题相关的整个子系统都要进行检查,这使得找出 bug(缺陷)将是非常困难的事 情。第三,GUI 测试通常只有在整个开发周期的后期才能很好地得到测试,这是因为只有这那个时候 GUI 才得到完整的定义。这意味着只有在 后期才可能发现潜在的 bug。第四,一般的开发人员可能没有自动的 GUI 测试工具。因此,当一个开发人员对代码进行更改时,没有一种简单 的方法来重新测试受到影响的子系统。这实际上不利于进行良好的测试。如果开发人员具有自动的代码级单元测试工具,开发人员就能够很容 易地运行这些工具以确保所做的更改不会破坏已经存在的功能。最后,如果添加了自动构建功能,则在自动构建过程中添加一个自动的单元测 试工具是非常容易的事情。当完成这些设置以后,整个系统就可以有规律地进行重建,并且回归测试几乎不需要人的参与。
另外 ,我们必须强调,使用 EJB 和 Web 服务进行分布式的、基于组件的开发使得测试单个的组件变得非常必要。如果没有"GUI"需要测试,您就必 须进行低级(lower-level)测试。最好以这种方式开始测试,省得当您将分布式的组件或 Web 服务作为您的应用程序的一部分时,您不得不 花费心思重新进行测试。
总之,通过使用自动的单元测试,能够很快地发现系统的缺陷,并且也易于发现这些缺陷,使得测试工作变 得更加系统化,因此整体的质量也得以提高。
3. 按照规范来进行开发,而不是按照应用服务器来进行开发。
要将规范熟记于心,如果要背离规范,要经过慎密的考虑后才可以这样做。这是因为当您背离规则的时候,您所做的事情往往并不是 您应该做的事情。
当您要背离 J2EE 可以允许您做的事情的时候,这很容易让使您遭受不幸。我们发现有一些开发人员钻研一些 J2EE 允许之外的东西,他们认为这样做可以"稍微"改善J2EE的性能,而他们最终只会发现这样做会引起严重的性能问题,或者在以后的移植( 从一个厂商到另一个厂商,或者是更常见的从一个版本到另一个版本)中会出现问题。实际上,这种移植问题是如此严重,以致 [Beaton] 将 此原则称为移植工作的基本最佳实践。
现在有好几个地方如果不直接使用 J2EE 提供的方法肯定会产生问题。一个常见的例子 就是开发人员通过使用 JAAS 模块来替代 J2EE 安全性,而不是使用内置的遵循规范的应用程序服务器机制来进行验证和授权。要注意不要脱 离 J2EE 规范提供的验证机制,如果脱离了此规范,这将是系统存在安全漏洞以及厂商兼容性问题的主要原因。类似地,要使用 servlet 和 EJB 规范提供的授权机制,并且如果您要偏离这些规范的话,要确保使用规范定义的 API(例如 getCallerPrincipal())作为实现的基础。通 过这种方式,您将能够利用厂商提供的强安全性基础设施,其中,业务要求需要支持复杂的授权规则。
其他常见的问题包括使用不遵 循 J2EE 规范的持久性机制(这使得事务管理变得困难)、在J2EE程序中使用不适当的J2SE 方法(例如线程或 singleton),以及使用您自己 的方法解决程序到程序(program-to-program)的通信,而不是使用 J2EE 内在支持的机制(例如 JCA、JMS 或 Web 服务)。当您将一个遵循 J2EE 的服务器移植到其他的服务器上,或者移植到相同服务器的新版本上,上述的设计选择将会造成无数的问题。唯一要背离规范的情况是, 当一个问题在规范的范围内无法解决的时候。例如,安排执行定时的业务逻辑在 EJB2.1 出现之前是一个问题,在类似这样的情况下,我们建 议当有厂商提供的解决方案时就使用厂商提供的解决方案(例如 WebSphere Application Server Enterprise 中的 Scheduler 工具),而在 没有厂商提供的解决方案时就使用第三方提供的工具。如果使用厂商提供的解决方案,应用程序的维护以及将其移植到新的规范版本将是厂商 的问题,而不是您的问题。
最后,要注意不要太早地采用新技术。太过于热衷采用还没有集成到 J2EE 规范的其他部分或者还 没有集成到厂商的产品中的技术常会带来灾难性的后果。支持是关键的??如果您的厂商不直接支持一种特定的在 JSR 中提出的技术,但此技术 还没有被 J2EE 所接受,那么您就不应该采用此技术。毕竟,我们中的大多数人从事解决业务问题,而不是推进技术的发展。
4. 从一开始就计划使用 J2EE 安全性。
启用 WebSphere 安全性。这使您的 EJB 和 URL 至少可以让所 有授权用户访问。不要问为什么??照着做就是了。
在与我们合作的客户中,一开始就打算启用 WebSphere J2EE 安全性的顾客 是非常少的,这一点一直让我们感到吃惊。据我们估计大约只有 50% 的顾客一开始就打算使用此特性。例如,我们曾与一些大型的金融机构( 银行、代理等等)合作过,他们也没有打算启用安全性。幸运的是,这种问题在部署之前的检查时就得以解决.
不使用 J2EE 安全性 是危险的事情。假设您的应用程序需要安全性(几乎所有的应用程序都需要),您敢打赌您的开发人员能够构建出自己的安全性系统,而这个 系统比您从 J2EE 厂商那里买来的更好。这可不是个好的赌注,为分布式的应用程序提供安全性是异常困难的。例如,您需要使用网络安全加 密令牌控制对 EJB 的访问。以我们的经验看来,大多数自己构建的安全性系统是不安全的,并且有重大的缺陷,这使产品系统极其脆弱。
一些不使用 J2EE 安全性的理由包括:担心性能的下降,相信其他的安全性(例如 Netegrity SiteMinder)可以取代 J2EE 安全性, 或者是不知道 WebSphere Application Server 安全特性及功能。不要陷入这些陷阱之中,尤其是,尽管像 Netegrity SiteMinder 这样的产 品能够提供优秀的安全特性,但是仅仅其自身不可能保护整个 J2EE 应用程序。这些产品必须与 J2EE 应用程序服务器联合起来才可能全面地 保护您的系统。
其他的一种常见的不使用 J2EE 安全性的原因是:基于角色的模型没有提供足够的粒度访问控制以满足复杂的业务规 则。尽管事实是这样的,但这也不应该成为不使用 J2EE 安全性的理由。相反地,应该将 J2EE 验证及 J2EE 角色与特定的扩展规则结合起来 。如果复杂的业务规则需要做出安全性决策,那就编写相应的代码,其安全性决策要基于可以直接使用的以及可靠的 J2EE 验证信息(用户 ID 和角色)。
5. 创建您所知道的
反复的开发工作将使您能够逐渐地掌握所有的 J2EE 模块。要从创建小而简单的模块开 始而不是从一开始就马上涉及到所有的模块。
我们必须承认 J2EE 是庞大的体系。如果一个开发小组只是开始使用 J2EE,这将很难 一下子就能掌握它。在 J2EE 中有太多的概念和 API 需要掌握。在这种情况下,成功掌握 J2EE 的关键是从简单的步骤开始做起。
这种方法可以通过在您的应用程序中创建小而简单的模块来得到最好的实现。如果一个开发小组通过创建一个简单的域模型以 及后端的持久性机制(也许使用的是 JDBC),并且对其进行了完整的测试,这会增强他们的自信心,于是他们会使用该域模型去掌握使用 servlet 和 JSP 的前端开发。如果一个开发组发现有必要使用 EJB,他们也会类似地开始在容器管理的持久性 EJB 组件之上使用简单的会话 Facades,或者使用基于 JDBC 的数据访问对象(JDBC-based Data Access Objects,DAO),而不是跳过这些去使用更加复杂的构造(例如消 息驱动bean和JMS)。
这种方法并不是什么新方法,但是很少有开发组以这种方式来培养他们的技能。相反地,多数开发组由于尝试 马上就构建所有的模块,同时涉及 MVC 中的视图层、模型层和控制器层,这样做的结果是他们往往会陷入进度的压力之中。他们应该考虑一些 敏捷(Agile)开发方法,例如极限编程(XP),这种开发方法采用一种增量学习及开发方法。在 XP 中有一种称为 ModelFirst 的过程,这个 过程涉及到首先构建域模型作为一种机制来组织和实现用户场景。基本说来,您要构建域模型作为您要实现的用户场景的首要部分,然后在域 模型之上构建一个用户界面(UI)作为用户场景实现的结果。这种方法非常适合让一个开发组一次只学到一种技术,而不是让他们同时面对很 多种情况(或者让他们读很多书),这会令他们崩溃的。
还有,对每个应用程序层重复的开发可能会包含一些适当的模式及最佳实践 。如果您从应用程序的底层开始应用一些模式如数据访问对象和会话 Facades,您就不应该在您的JSP和其他视图对象中使用域逻辑。
最后,当您开发一些简单的模块时,在开始的初期就可以对您的应用程序进行性能测试。如果直到应用程序开发的后期才进行性能测 试的话,这往往会出现灾难性的后果。
6. 当使用 EJB 组件时,始终使用会话 Facades。
决不 要将实体 bean 直接暴露给任何用户类型。对实体 bean 只可以使用本地 EJB 接口(Local EJB interfaces)。
当使用 EJB 组件时 ,使用一个会话 Facades 是一个确认无疑的最佳实践。实际上,这个通用的实践被广泛地应用到任何分布式的技术中,包括 CORBA、EJB 和 DCOM。从根本上讲,您的应用程序的分布"交叉区域"越是底层化,对小块的数据由于多次重复的网络中继造成的时间消耗就越少。要达到这个 目的的方法就是:创建大粒度的 Facades 对象,这个对象包含逻辑子系统,因而可以通过一个方法调用就可以完成一些有用的业务功能。这种 方法不但能够降低网络开销,而且在 EJB 内部通过为整个业务功能创建一个事务环境也可以大大地减少对数据库的访问次数。
EJB 本地接口(从 EJB 2.0 规范开始使用)为共存的 EJB 提供了性能优化方法。本地接口必须被您的应用程序显式地进行访问,这需要代码的改 变和防止以后配置 EJB 时需要应用程序的改变。由于会话 Facades 和它包含的整个 EJB 对于彼此来说都应该是本地的,我们建议对会话 Facades 后面的实体 bean 使用本地接口。然而,会话 Facades 本身的实现(典型例子如无状态会话 bean)应该设计为远程接口。
为了性能的优化,可以将一个本地接口添加到会话 Facades。这样做利用了这样一个事实:在大多数情况下(至少在 Web 应用程序中),您的 EJB 客户端和 EJB 会共同存在于同一个 Java 虚拟机(JVM)中。另外一种情况,如果会话 Facades 在本地被调用,可以使用 J2EE 应用服务 器配置优化(configuration optimizations),例如 WebSphere 中的"No Local Copies"。然而,您必须注意到这些可供选择的方案会将交互 方法从按值传递(pass-by-value)改变为按引用传递(pass-by-reference)。这可能会在您的代码中产生很微妙的错误。当您要利用这些方 案时,您应该在一开始就考虑其可行性。
如果在您的会话 Facades 中使用远程接口(而不是本地接口),您也可以将同样的会 话 Facades 在 J2EE 1.4 中以兼容的方式作为 Web 服务来配置。这是因为 JSR 109(J2EE 1.4 中的 Web 服务部署部分)要求使用无状态会 话 bean 的远程接口作为 EJB Web 服务和 EJB 实现的接口。这样做是值得的,因为这样做可以为您的业务逻辑增加客户端类型的数量。
7. 使用无状态会话 bean,而不是有状态会话 bean
这样做可以使您的系统经得起错误的终止。使用 HttpSession 存储和用户相关的状态。
以我们的观点看来,有状态会话 bean 的概念已经过时了。如果您仔细对其考虑一下,一个有 状态会话 bean 实际上与一个 CORBA 对象在体系结构上是完全相同的,无非就是一个对象实例,绑定到一个服务器,并且依赖于服务器来管理 其生命周期。如果服务器关闭了,这种对象也就不存在,那么这个 bean 的客户端的信息也就不存在。
J2EE 应用服务器为有状态会 话 bean 提供的故障转移(failover)能够解决一些问题,但是有状态的解决方案没有无状态的解决方案易于扩展。例如,在 WebSphere Application Server 中,对无状态会话 bean 的请求,是通过对部署无状态会话的成员集群进行平衡加载来实现。相反地,J2EE 应用服务器 不能对有状态 bean 的请求进行平衡加载。这意味着您的集群中的服务器的加载过程会是不均衡的。此外,使用有状态会话 bean 将会再添加 一些状态到您的应用服务器上,这也是不好的做法。这样就增加了系统的复杂性,并且在出现故障的情况下使问题变得复杂化。创建健壮的分 布式系统的一个关键原则是尽量使用无状态行为。
因此,我们建议对大多数应用程序使用无状态会话 bean 方法。任何在处理时需要 使用的与用户相关的状态应该以参数的形式传送到 EJB 的方法中(并且通过使用一种机制如 HttpSession 来存储它)或者从持久性的后端存 储(例如通过使用实体 bean)作为 EJB 事务的一部分来进行检索。在合适的情况下,这个信息可以缓存到内存中,但是要注意在分布式的环境 中保存这种缓存所潜在的挑战性。缓存非常适合于只读数据。
总之,您要确保从一开始就要考虑到可伸展性。检查设计中的所有设想 ,并且考虑到当您的应用程序要在多个服务器上运行时,是否也可以正常运行。这个规则不但适合上述情况的应用程序代码,也适用于如 MBean 和其他管理界面的情况下。
避免使用有状态性不只是对 IBM/WebSphere 的建议,这是一个基本的 J2EE 设计原则。
8. 使用容器管理的事务
学习一下 J2EE 中的两阶段提交事务,并且使用这种方式,而不是开放您自己的 事务管理。容器在事务优化方面几乎总是比较好的。
使用容器管理的事务(CMT)提供了两个关键的优势(如果没有容器支持这几乎 是不可能的):可组合的工作单元和健壮的事务行为。
如果您的应用程序代码显式地使用了开始和结束事务(也许使用 javax.jts.UserTransaction 或者甚至是本地资源事务),而将来的要求需要组合模块(也许会是代码重构的一部分),这种情况下往往需要 改变事务代码。例如,如果模块 A 开始了一个数据库事务,更新数据库,随后提交事务,并且有模块 B 做出同样的处理,请考虑一下当您在 模块 C 中尝试使用上述两个模块,会出现什么情况呢?现在,模块 C 正在执行一个逻辑动作,而这个动作实际上将调用两个独立的事务。如 果模块 B 在执行中失败了,而模块 A 的事务仍然能被提交。这是我们所不希望出现的行为。如果,相反地,模块 A 和模块 B 都使用 CMT 的 话,模块 C 也可以开始一个 CMT(通常通过配置描述符),并且在模块 A 和模块 B 中的事务将是同一个事务的隐含部分,这样就不再需要复 杂的重写代码的工作了。
如果您的应用程序在同一个操作中需要访问多种资源,您就要使用两阶段提交事务。例如,如果从 JMS 队 列中删除一个消息,并且随后更新基于这条消息的纪录,这时,要保证这两个操作都会执行或都不会执行就变得尤为重要。如果一条消息已经 从队列中被删除,而系统没有更新与此消息相关的数据库中的纪录,那么这种系统是不稳定的。一些严重的客户及商业纠纷源自不一致的状态 。
我们时常看到一些客户应用程序试图实现他们自己的解决方案。也许会通过应用程序的代码在数据库更新失败的时候 "撤销"对队 列的操作。我们不提倡这样做。这种实现要比您最初的想象要复杂得多,并且还有许多其他的情况(想象一下如果应用程序在执行此操作的过 程中突然崩溃的情况)。作为替代的方式,应该使用两阶段提交事务。如果您使用 CMT,并且在一个单一的 CMT 中访问两阶段提交的资源(例 如 JMS 和大多数数据库),WebSphere 将会处理所有的复杂工作。它将确保整个事务被执行或者都不被执行,包括系统崩溃、数据库崩溃或其 他的情况。其实现在事务日志中保存着事务状态。当应用程序访问多种资源的时候,我们怎么强调使用 CMT 事务的必要性都不为过。
9. 将 JSP 作为表示层的首选
只有在需要多种表示输出类型,并且输出类型被一个单一的控制器及后端支持时才使 用 XML/XSLT。
我们常听到一些争论说,为什么您选择 XML/XSLT 而不是 JSP 作为表示层技术。选择 XML/XSLT 的人的观点是,JSP" 允许您将模型和视图混合在一起",而 XML/XSLT 不会有这种问题。遗憾的是,这种观点并不完全正确,或者至少不像白与黑那样分的清楚。实 际上,XSL 和 XPath 是编程语言。XSL 是图灵完成的(Turing-complete),尽管它不符合大多数人定义的编程语言,因为它是基于规则的, 并且不具备程序员习惯的控制工具。
现在的问题是既然给予了这种灵活性,开发人员就会利用这种灵活性。尽管每个人都认同 JSP 使开发人员容易在视图中加入"类似模型"的行为,而实际上,在 XSL 中也有可能做出一些同样的事情。尽管从 XSL 中进行访问数据库这样的 事情会非常困难,但是我们曾经见到过一些异常复杂的 XSLT 样式表执行复杂的转换,这实际上是模型代码。
然而,应该选择 JSP 作为首选的表示技术的最基本的原因是,JSP 是现在支持最广泛的、也是最被广泛理解的 J2EE 视图技术。而随着自定义标记库、JSTL 和 JSP2.0 的新特性的引入,创建 JSP 变得更加容易,并且不需要任何 Java 代码,以及可以将模型和视图清晰的分离开。在一些开发环境中( 如 WebSphere Studio)加入了对 JSP(包括对调试的支持)的强大支持,并且许多开发人员发现使用 JSP 进行开发要比使用 XLS 简单,一些 支持 JSP 的图形设计工具及其他特征(尤其在 JSF 这样的框架下)使得开发人员可以以所见即所得的方式进行 JSP 的开发,而对于 XSL 有 时不容易做到。
最后一个要谨慎考虑使用 JSP 的原因是速度问题。在 IBM 所作的对比 XSL 和 JSP 相对速度的性能测试显示:在大 多数情况下,JSP 在生成同样的 HTML 的时候,要比 XSL 快好几倍,甚至使用编译过的 XSL 也是如此。尽管多数情况下这不是问题,但在性 能要求很高的情况下,这就会成为问题。
然而,这也不能说,您永远也不要使用 XSL。在一些情况下,XSL 能够表示一组固定的数据 ,并且可以基于不同的样式表来以不同的方式显示这些数据的能力是显示视图的最佳解决方案。然而,这只是一种例外的情况,而不是通用的 规则。如果您只是生成 HTML 来表达每一个页面,那么在大多数情况下,XSL 是一种不必要的技术,并且,它给您的开发人员所带来的问题远 比它所能解决的问题多。
10. 当使用 HttpSession 时,尽量只将当前事务所需要的状态保存其中,其他内容不要保存在 HttpSession 中。
启用会话持久性。
HttpSessions 对于存储应用程序状态信息是非常有用的。其 API 易于使用和理解。遗憾的是,开发人员常常遗忘了 HttpSession 的目的----用来保持暂时的用户状态。它不是任意的数据缓存。我们已经 见到过太多的系统为每个用户的会话放入了大量的数据(达到兆字节)。那好了,如果同时有 1000 个登录系统的用户,每个用户拥有 1MB 的 会话数据,那么就需要 1G 或者更多的内存用于这些会话。要使这些 HTTP 会话数据较小一些,不然的话,您的应用程序的性能将会下降。一 个大约比较合适的数据量应该是每个用户的会话数据在 2K-4K 之间,这不是一个硬性的规则,8K 仍然没有问题,但是显然会比 2K 时的速度 要慢。一定要注意,不要使 HttpSession 变成数据堆积的场所。
一个常见的问题是使用 HttpSession 缓存一些很容易再创建 的信息,如果有必要的话。由于会话是持久性的,进行不必要的序列化以及写入数据是一种很奢侈的决定。相反地,应该使用内存中的哈希表 来缓存数据,并且在会话中保存一个对此数据进行引用的关键字。这样,如果不能成功登录到另外的应用服务器的话,就可以重新创建数据。
当谈及会话持久性时,不要忘记要启用这项功能。如果您没有启用会话持久性,或者服务器因为某种原因停止了(服务器故障或正常 的维护),则所有此应用服务的当前用户的会话将会丢失。这是件令人非常不高兴的事情。用户不得不重新登录,并且重新做一些他们曾经已 经做过的事情。相反地,如果启用了会话持久性,WebSphere 会自动将用户(以及他们的会话)移到另外一个应用服务器上去。用户甚至不知 道会有这种事情的发生。我们曾经见到过一些产品系统因为存在于本地代码中令人难以忍受的 bug(不是 IBM 的代码!)而突然崩溃的情况, 这这种情况下,上述功能仍然可以运行良好。
11. 在 WebSphere 中,使用动态缓存,并使用 WebSphere servlet 缓 存机制。
通过使用这些功能,系统性能可以得到很大的提高,而开销是很小的。并且不影响编程模型。
通 过缓存来提高性能的好处是众所周知的事情。遗憾的是,当前的 J2EE 规范没有包括一种用于 servlet/JSP 缓存的机制。然而,WebSphere 提 供了对页面以及片断缓存的支持,这种支持是通过其动态缓存功能来实现的,并且不需要对应用程序作出任何改变。其缓存的策略是声明性的 ,而且其配置是通过 XML 配置描述符来实现的。因此,您的应用程序不会受到影响,并保持与 J2EE 规范的兼容性和移植性,同时还从 WebSphere 的 servlet 及 JSP 的缓存机制中得到性能的优化。
从 servet 及 JSP 的动态缓存机制得到的性能的提高是显而易见的 ,这取决于应用程序的特性。Cox 和 Martin [Cox] 指出对一个现有的 RDF(资源描述格式)站点摘要 (RSS)servlet,当使用动态缓存时,其 性能可以提高 10%。请注意这个实验只涉及到一个简单的 servlet,这个性能的增长量可能并不能反映一个复杂的应用程序。
为了更 多地提高性能,将 WebSphere servlet/JSP 结果缓存与 WebSphere 插件 ESI Fragment 处理器、IBM HTTP Server Fast Response Cache Accelerator (FRCA) 和 Edge Server 缓存功能集成在一起。对于繁重的基于读取的工作负荷,通过使用这些功能可以得到许多额外的好处。
12. 为了提高程序员的工作效率,将 CMP 实体 bean 作为 O/R 映射的首选解决方案.
通过 WebSphere 框架(readahead、缓存、隔离级别等)优化性能。如果可能,有选择的应用一些模式来达到提高性能的目的,例如 Fast-Lane 阅读器 [Marinescu]。
对象/关系(O/R)映射是使用 Java 创建企业级的应用程序的基础。几乎每个 J2EE 应用程序都需要一些类型的 O/R 映射。J2EE 厂商提供一种 O/R 映射机制,这种机制在不同的厂商间是可移植的,高效的,并且能够被一些标准及工具很好地支持。这就是 EJB 规范中的 CMP(容器管理的持久性)部分。
早期的 CMP 实现以表现不佳及不支持许多 SQL 结构而著称。然而,随着 EJB 2.0 及 2.1 规范的出现,以及被一些厂商所采纳,并且随着像 IBM WebSphere Studio Application Developer 的出现,这些问题已经不再是问题 了。
CMP EJB 组件现在已经被广泛地应用于许多高性能的应用程序中。WebSphere 包括一些优化功能以提高 EJB 组件的性能,优化 功能包括:对生命周期的缓存和 read-ahead 能力。这两者优化功能都是配置时的选项,并且不需要对应用程序进行修改或者影响可移植性。
处于缓存状态的生命周期缓存 CMP 状态数据并提供基于时间的无效性。从处于缓存状态的生命周期得到的性能提高可以达到选项 A 的缓存性能,并且仍然可以为您的应用程序提供可伸展性。Read-ahead 能力和容器管理的关系结合使用。这个特性通过在相同的查询中随意地 检索相关的数据作为父数据而减少与数据库的交互。如果相关的数据要通过使用并发的查询来访问的话,这种方法可以得到性能的改进。 [Gunther]提供了详细的描述以及通过这些特性得到的性能提高的细节。
此外,为了完全优化您的 EJB 组件,当指定隔离级别时要特 别注意。尽可能使用最低的隔离级别,并且仍然保持您的数据的完整性。较低的隔离级别可以提供最佳的性能,并且可以降低出现数据库死锁 的危险。
这是目前最有争议的最佳实践。已经有大量的文章赞扬 CMP EJB,同样的贬斥声也不绝于耳。然而,这里最基本的问题是数 据库开发是困难的。当您开始使用任何持久性解决方案之前,您需要掌握查询以及数据库锁定如何工作这些基础知识。如果您选择使用 CMP EJB,您要确保您已经通过一些书籍(例如 [Brown] 和 [Barcia])知道如何使用它们。在锁定及争用方面有一些微妙的交互难以理解,但是, 在您耗费一定的时间及努力后会将其掌握的。
[fwd]CA SiteMinder Web Access Manager
CA SiteMinder Web Access Manager
CA SiteMinder 提供了一种企业级的安全基础架构,可以安全有效地向员工、顾客和业务合作伙伴提供Web应用和Web站点访问。
概述
CA SiteMinder 是什么?
CA SiteMinder 是一种集中式Web访问管理系统,它支持用户身份验证和单点登录,基于策略的授权、身份联盟以及Web应用和门户访问的审计。
CA SiteMinder 面临的访问管理挑战是什么?
CA SiteMinder 可以弱化 IT 安全相关风险,降低应用的开发成本和运用成本,同时还会增强用户的Web应用体验。
CA SiteMinder 具有哪些特性?
CA SiteMinder 隶属于一种高度可管理的、可靠的、可扩展的著名企业安全系统,它具有集中式Web单点登录、身份验证管理、基于策略的授权、身份联盟和审计服务等特征。
CA SiteMinder 支持哪些平台?
CA SiteMinder 支持 UNIX、Linux 以及 Windows,还支持主机、应用服务器、Web服务器、ERP、CRM、RDBMS、目录服务器和其他系统。
星期三, 九月 26, 2007
常用新闻组列表
新闻组是个人向新闻服务器所张贴邮件的集合。
您几乎可以找到任何主题的新闻组。虽然某些新闻组是受到监控的,但大多数不是。对于受监控的新闻组,其“拥有者”可以检查张贴的邮件、提出问题,或删除不适当的邮件等等。任何人都可以向新闻组张贴邮件。新闻组不需要成员资格或加入费用。
Internet 服务提供商必须为您提供与一个或多个新闻服务器的链接,以便在新闻组阅读器中使用新闻组。在新闻组阅读器中为每台需要的服务器设置完帐户后,您就可以在该新闻服务器上的新闻组中随意阅读和张贴邮件了。
找到喜爱的新闻组时,您可以“预订”它,这样它会显示在新闻组阅读器的文件夹列表中。通过预订您可以方便地访问喜欢的新闻组,而不必在每次要访问一个喜欢的新闻组时去翻阅服务器上冗长的新闻组列表了。
常用新闻组服务器
宁波新闻组 news://news.cnnb.net
微软新闻组 news://msnews.microsoft.com
万千新闻组 news://news.webking.cn
希网新闻组 news://news.cn99.com
雅科新闻组 news://news.yaako.com
香港新闻组 news://news.newsgroup.com.hk
前线新闻组 news://freenews.netfront.net
其他新闻组
b.. news://news.freeforum.org
c.. news://news.netteens.net
d.. news://news.so-net.com.hk
e.. news://freenews.netfront.net
f.. news://news.3home.net
g.. news://news.newsgroup.com.hk
h.. news://news.popart.com.hk
i.. news://news.hkhosting.com
j.. news://wonderspace.net
k.. news://news.hkpeople.net
l.. news://news.netgod.org.hk
m.. news://news.tatgod.com
n.. news://ourrice.com
o.. news://hknews.info
p.. news://inhk.net
q.. news://newsgroup.cc
r.. news://news.dial-up.to
s.. news://news.hkbookmarks.com
t.. news://news.school.net.hk
u.. news://news.wonderfuland.net
v.. news://news.imart.com.hk
w.. news://news.hkux.net
x.. news://news.linux.org.hk
y.. news://news.idclub.net
z.. news://news.debugnet.com
aa.. news://news.hkcampus.net
ab.. news://news.nntp.cn
ac.. news://news.ismart.net
ad.. news://hk-system.com/hk.ive
ae.. news://news.whiz.com.hk
af.. news://news.siukeung.com
ag.. news://news.asdfasdf.org
ah.. news://news.visualmedia.com.hk
ai.. news://news.net4hk.com
aj.. news://news.nowstart.com
ak.. news://news.idotworld.com
al.. news://news.hkhost.net
am.. news://news.hkpcug.org
an.. news://news.easy4web.com
ao.. news://news.adtic.com
ap.. news://news.wyk.edu.hk
aq.. news://news.w3.com.hk
ar.. news://news.e-fever.org
as.. news://news.loveclubhk.com
at.. news://newsgroup.com.hk
au.. news://news.d2g.com
av.. news://news.hkxdd.net
aw.. news://news.grace-ip.net
ax.. news://news.chau.com.hk
java高级时间概念[转贴]
如果你的Java 程序向处在不同时区或者不同国家的用户显示时间和日期,那么你需要了解Java日期类的一些更加高级的方面。在“使用Java Date和Calendar类计算,定制和解析日期”的这篇文章里我们提供了对日期,日期数据的格式化,日期数据的解析和日期计算的一个概览。对于这些概念的深入的理解对于讨论更高级的诸如时区,国际化标准格式和SQL日期数据等这些有关日期的问题是关键的。
我们在本文中讨论的类将包含java.text.DateFormat,以及java.util.TimeZone和java.util.Locate。我们还将讨论如何使用一个java.util.Date的子类java.sql.Date来从Oracle数据库里提取和保存Java日期数据。
地区的问题
在我们国际化我们的日期数据以前,我们需要进一步的学习Locale类,也就是java.util.Locale。Locale类的一个实例通常包含国家和语言信息。其中的每一个部分都是由基于国际标准化组织(ISO)制定的国家代码ISO-3166和语言代码ISO-639的两字符的字符串构成的。
让我们来创建两个Locale实例,其中一个对应的是美国英语而另一个对应的是法国法语。见表A。
表A
import java.util.Locale;
public class DateExample6 {
public static void main(String[] args) {
// Create a locale for the English language in the US.
Locale localeEN = new Locale("en", "US");
System.out.println("Display Name: " +
localeEN.getDisplayName());
System.out.println("Country: " + localeEN.getCountry());
System.out.println("Language: " + localeEN.getLanguage());
// Create a locale for the French language in France.
Locale localeFR = new Locale("fr", "FR");
System.out.println("\nDisplay Name: " +
localeFR.getDisplayName());
System.out.println("Country: " + localeFR.getCountry());
System.out.println("Language: " + localeFR.getLanguage());
// Display the English-US locale in French
System.out.println("\nen Display Name in French: " +
localeEN.getDisplayName(localeFR));
}
}
在这个例子中,我们用getDisplayName方法来显示Locale的一个更易读的文本。你还应该注意到我们在最后一次调用getDisplayName的时候,我们在对English Locale对象调用getDisplayName的时候同时传递了French Locale对象。这允许我们选择显示Locale对象所用的语言,让我们用英语显示法语Locale对象的内容。下面是这个例子的输出:
Display Name: English (United States)
Country: US
Language: en
Display Name: French (France)
Country: FR
Language: fr
en Display Name in French: anglais (états-Unis)
多个地域的日期格式化
使用java.util.Locale和java.text.DateFormat类我们就能够格式化日期数据把它显示给在另一个地域的用户,比方法国。表B中的例子为英语和法语各创建了一个完整的日期格式化器。
表 B
import java.util.Locale;
import java.util.Date;
import java.text.DateFormat;
public class DateExample7 {
public static void main(String[] args) {
// Get the current system date and time.
Date date = new Date();
// Get a France locale using a Locale constant.
Locale localeFR = Locale.FRANCE;
// Create an English/US locale using the constructor.
Locale localeEN = new Locale("en", "US" );
// Get a date time formatter for display in France.
DateFormat fullDateFormatFR =
DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeFR);
// Get a date time formatter for display in the U.S.
DateFormat fullDateFormatEN =
DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeEN);
System.out.println("Locale: " + localeFR.getDisplayName());
System.out.println(fullDateFormatFR.format(date));
System.out.println("Locale: " + localeEN.getDisplayName());
System.out.println(fullDateFormatEN.format(date));
}
}
这个例子的输出是:
Locale: French (France)
vendredi 5 octobre 2001 21 h 05 GMT-04:00
Locale: English (United States)
Friday, October 5, 2001 9:05:54 PM EDT
注意这个输出包括了时区信息:GMT-04:00 和 PM EDT。这个时区是人系统的时区设置里捕获的。你可以看见,日期是以那个地区的用户期望的格式显示的。让我们等一下来看看时区的概念
时区
TimeZone类,即java.util.TimeZone类的实例包含了一个与格林威治标准时间(GMT)相比较得出的以微秒为单位的时区偏移量,而且它还处理夏令时
。要获得一个所有支持的进区的列表,你可以使用方法TimeZone.getAvailableIDs,它将返回一个包含了所有进区ID的字符串数组。要知道关于TimeZone类的更多细节,可以参看Sun公司的Web站点。
为了演示这个概念,我们将创建三个时区对象。第一个对象将使用getDefault从系统时钟返回时区数据;第二个和第三个对象将传入一个时区字符串ID。见表C中的代码。
表 C
import java.util.TimeZone;
import java.util.Date;
import java.text.DateFormat;
import java.util.Locale;
public class DateExample8 {
public static void main(String[] args) {
// Get the system time zone.
TimeZone timeZoneFL = TimeZone.getDefault();
System.out.println("\n" + timeZoneFL.getDisplayName());
System.out.println("RawOffset: " + timeZoneFL.getRawOffset());
System.out.println("Uses daylight saving: " + timeZoneFL.useDaylightTime());
TimeZone timeZoneLondon = TimeZone.getTimeZone("Europe/London");
System.out.println("\n" + timeZoneLondon.getDisplayName());
System.out.println("RawOffset: " + timeZoneLondon.getRawOffset());
System.out.println("Uses daylight saving: " + timeZoneLondon.useDaylightTime());
燭imeZone timeZoneParis = TimeZone.getTimeZone("Europe/Paris");
System.out.println("\n" + timeZoneParis.getDisplayName());
System.out.println("RawOffset: " + timeZoneParis.getRawOffset());
System.out.println("Uses daylight saving: " + timeZoneParis.useDaylightTime());
}
}
其输出如下:
Eastern Standard Time
RawOffset: -18000000
Uses daylight saving: true
GMT+00:00
RawOffset: 0
Uses daylight saving: true
Central European Standard Time
RawOffset: 3600000
Uses daylight saving: true
正如你所看见的,TimeZone对象给我们的是原始的偏移量,也就是与GMT相差的微秒数,而且还会告诉我们这个时区是否使用夏令时。有个这个信息,我们就能够继续将时区对象和日期格式化器结合在一起在其它的时区和其它的语言显示时间了。
国际化的时期显示了时区转换
让我们来看一个结合了国际化显示,时区和日期格式化的例子。表D为一个在迈阿密和巴黎拥有办公室的公司显示了当前的完整日期和时间。对于迈阿密的办公室,我们将在每个办公室里用英语显示完整的日期和时间。对于巴黎的办公室,我们将用法语显示完整的当前日期和时间。
表 D
import java.util.TimeZone;
import java.util.Date;
import java.util.Locale;
import java.text.DateFormat;
public class DateExample9 {
public static void main(String[] args) {
Locale localeEN = Locale.US;
Locale localeFrance = Locale.FRANCE;
TimeZone timeZoneMiami = TimeZone.getDefault();
TimeZone timeZoneParis = TimeZone.getTimeZone("Europe/Paris");
DateFormat dateFormatter = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeEN);
DateFormat dateFormatterParis = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeFrance);
Date curDate = new Date();
System.out.println("Display for Miami office.");
// Print the Miami time zone display name in English
System.out.println(timeZoneMiami.getDisplayName(localeEN));
// Set the time zone of the dateFormatter to Miami time zone.
dateFormatter.setTimeZone(timeZoneMiami);
// Print the formatted date.
System.out.println(dateFormatter.format(curDate));
// Set the time zone of the date formatter to Paris time zone.
dateFormatter.setTimeZone(timeZoneParis);
// Print the Paris time zone display name in English.
System.out.println(timeZoneParis.getDisplayName(localeEN));
// Print the Paris time in english.
System.out.println(dateFormatter.format(curDate));
System.out.println("\nDisplay for Paris office.");
// Print the Miami time zone display name in French
System.out.println(timeZoneMiami.getDisplayName(localeFrance));
// Set the timezone of the
// dateFormatterParis to Miami time zone.
dateFormatterParis.setTimeZone(timeZoneMiami);
// Print the formatted date in French.
燬ystem.out.println(dateFormatterParis.format(curDate));
// Set the timezone of the date formatter to Paris time zone.
dateFormatterParis.setTimeZone(timeZoneParis);
// Print the Paris time zone display name in French.
System.out.println(timeZoneParis.getDisplayName(localeFrance));
// Print the Paris time in French.
System.out.println(dateFormatterParis.format(curDate));
}
}
这个例子的输出是:
Display for Miami office.
Eastern Standard Time
Friday, October 5, 2001 10:28:02 PM EDT
Central European Standard Time
Saturday, October 6, 2001 4:28:02 AM CEST
Display for Paris office.
GMT-05:00
vendredi 5 octobre 2001 22 h 28 GMT-04:00
GMT+01:00
samedi 6 octobre 2001 04 h 28 GMT+02:00
在一个SQL数据库中保存和提取日期数据我们将要使用的下一个类是java.sql.Date,它是java.util.Date的子类但它使用了Java数据库连接(JDBC)方法
。让我们来看一个简单的只有一个表单--LAST_ACCESS的ORACLE数据库,它是用下面的SQL创建的:
create table LAST_ACCESS (
LAST_HIT date
);
这个表单只有一个记录,用下面的插入语句创建:
insert into LAST_ACCESS values (Sysdate);
表E演示了如何修改和提取LAST_HIT数据库域。
表 E
import java.sql.*;
import java.text.DateFormat;
import java.util.Date;
public class DateExample10 {
public static void main(String[] args) {
// Get a full date formatter.
DateFormat dateFormatter = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL);
// Get the system date and time.
java.util.Date utilDate = new Date();
// Convert it to java.sql.Date
java.sql.Date date = new java.sql.Date(utilDate.getTime());
// Display the date before storing.
System.out.println(dateFormatter.format(date));
// Save the date to the database.
setLastHit(date);
// Get the date from the database.
Date dateFromDB = getLastHit();
// Display the date from the database.
System.out.println(dateFormatter.format(dateFromDB));
}
public static void setLastHit(java.sql.Date date) {
try {
// Load the class.
Class.forName("oracle.jdbc.driver.OracleDriver");
// Get a connection.
燙onnection connection = DriverManager.getConnection(
// Database URL
"jdbc:oracle:thin:@localhost:1521:buzz2",
"web_site", // Username
"web_site"); // Password
try {
/ Get a prepared statement fromthe connection
// specifying the update SQL.
PreparedStatement ps = connection.prepareStatement(
"update LAST_ACCESS set LAST_HIT=");
try {
/ set the date letting JDBC to the work of
// formatting the SQL appropriately.
ps.setDate(1, date);
// Execute the update statement.
int iRowsUpdated = ps.executeUpdate();
System.out.println("Rows updated: " + iRowsUpdated);
} finally {
ps.close();
}
} finally {
connection.close();
}
} catch (Exception ex) {
System.out.println("Error: " + ex.getMessage());
}
}
public static java.sql.Date getLastHit() {
java.sql.Date returnDate = null;
try {
// Load the driver class.
Class.forName("oracle.jdbc.driver.OracleDriver");
// Get the connection.
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:buzz2",
"web_site", "web_site");
try {
/ Get the prepared statement specifying the
// select SQL.
PreparedStatement ps = connection.prepareStatement(
"select LAST_HIT from LAST_ACCESS");
try {
// Execute the SQL and get the ResultSet object.
ResultSet rs = ps.executeQuery();
try {
// Retreive the record.
if (rs else {
燬ystem.out.println("Did not get last hit.");
}
}
finally {
rs.close();
}
} finally {
ps.close();
爙
} finally {
connection.close();
}
} catch (Exception ex) {
System.out.println("Error: " + ex.getMessage());
}
return returnDate;
}
}
这个例子的输出如下:
Friday, October 5, 2001 10:42:34 PM EDT
Rows updated: 1
Successfully retrieved last hit.
Friday, October 5, 2001 12:00:00 AM EDT
虽然这个例子没有为保存和提取日期数据提供性能上优良的方法,但它确实示范了如何为一条更新和删除语句将Java日期数据转换成SQL日期数据。从一个java.util.Date对象设置Oracle date数据域的过程是由以下的语句处理的:
ps.setDate(1, date);
它是我们预定义语句接口java.sql.PreparedStatement.setDate 的一个方法。
这行代码出现在我们的setLastHit方法里。它将Java以微秒为单位的长整型日期值转换成ORACLE的SQL日期格式。当我们能够在getLastHit方法里用java.sql.PreparedStatement.getDate从数据库取得日期数据的时候这种转换就能够完成。
你还应该注意到只有日期被设置了。小时,分钟,秒,和微秒都没有包括在从Java日期数据到SQL日期数据的转换过程中。
结论
一旦你掌握了这些概念,你就应该能够基于系统时间或者一个输入的时间创建日期对象了。另外,你还应该能够使用标准和定制的格式化过程格式化日期数据,将文本的日期数据解析成日期对象,并以多种语言和多种时区显示一个日期数据。最后,你将能够在一个SQL数据库里保存和提取日期值
全国省市的数据库脚本(postgres测试通过)
--**************************************************************
CREATE TABLE common_Area
(
Area_Id INT,
AreaName NVARCHAR(5'0'); NOTNULL,
RootID INT,
ChildAmount INT,
Depth INT,
Sort INT,
IsOpen BIT
); ;
--中国(2007年:24个省,5个自治区,4个直辖市,2个特别行政区);
INSERT INTO common_Area VALUES(1,'北京市',0,0,1,1,'1');
INSERT INTO common_Area VALUES(2,'天津市',0,0,1,2,'1');
INSERT INTO common_Area VALUES(3,'上海市',0,0,1,3,'1');
INSERT INTO common_Area VALUES(4,'重庆市',0,0,1,4,'1');
INSERT INTO common_Area VALUES(5,'河北省',0,0,1,5,'1');
INSERT INTO common_Area VALUES(6,'山西省',0,0,1,6,'1');
INSERT INTO common_Area VALUES(7,'台湾省',0,0,1,7,'1');
INSERT INTO common_Area VALUES(8,'辽宁省',0,0,1,8,'1');
INSERT INTO common_Area VALUES(9,'吉林省',0,0,1,9,'1');
INSERT INTO common_Area VALUES(10,'黑龙江省',0,0,1,10,'1');
INSERT INTO common_Area VALUES(11,'江苏省',0,0,1,11,'1');
INSERT INTO common_Area VALUES(12,'浙江省',0,0,1,12,'1');
INSERT INTO common_Area VALUES(13,'安徽省',0,0,1,13,'1');
INSERT INTO common_Area VALUES(14,'福建省',0,0,1,14,'1');
INSERT INTO common_Area VALUES(15,'江西省',0,0,1,15,'1');
INSERT INTO common_Area VALUES(16,'山东省',0,0,1,16,'1');
INSERT INTO common_Area VALUES(17,'河南省',0,0,1,17,'1');
INSERT INTO common_Area VALUES(18,'湖北省',0,0,1,18,'1');
INSERT INTO common_Area VALUES(19,'湖南省',0,0,1,19,'1');
INSERT INTO common_Area VALUES(20,'广东省',0,0,1,20,'1');
INSERT INTO common_Area VALUES(21,'甘肃省',0,0,1,21,'1');
INSERT INTO common_Area VALUES(22,'四川省',0,0,1,22,'1');
INSERT INTO common_Area VALUES(23,'贵州省',0,0,1,23,'1');
INSERT INTO common_Area VALUES(24,'海南省',0,0,1,24,'1');
INSERT INTO common_Area VALUES(25,'云南省',0,0,1,25,'1');
INSERT INTO common_Area VALUES(26,'青海省',0,0,1,26,'1');
INSERT INTO common_Area VALUES(27,'陕西省',0,0,1,27,'1');
INSERT INTO common_Area VALUES(28,'广西壮族自治区',0,0,1,28,'1');
INSERT INTO common_Area VALUES(29,'西藏自治区',0,0,1,29,'1');
INSERT INTO common_Area VALUES(30,'宁夏回族自治区',0,0,1,30,'1');
INSERT INTO common_Area VALUES(31,'新疆维吾尔自治区',0,0,1,31,'1');
INSERT INTO common_Area VALUES(32,'内蒙古自治区',0,0,1,32,'1');
INSERT INTO common_Area VALUES(33,'澳门特别行政区',0,0,1,33,'1');
INSERT INTO common_Area VALUES(34,'香港特别行政区',0,0,1,34,'1');
--1北京市
INSERT INTO common_Area VALUES(61,'东城区',1,0,2,1,'0');
INSERT INTO common_Area VALUES(62,'西城区',1,0,2,2,'0');
INSERT INTO common_Area VALUES(63,'崇文区',1,0,2,3,'0');
INSERT INTO common_Area VALUES(64,'宣武区',1,0,2,4,'0');
INSERT INTO common_Area VALUES(65,'朝阳区',1,0,2,5,'0');
INSERT INTO common_Area VALUES(66,'丰台区',1,0,2,6,'0');
INSERT INTO common_Area VALUES(67,'石景山区',1,0,2,7,'0');
INSERT INTO common_Area VALUES(68,'海淀区',1,0,2,8,'0');
INSERT INTO common_Area VALUES(69,'门头沟区',1,0,2,9,'0');
INSERT INTO common_Area VALUES(70,'房山区',1,0,2,10,'0');
INSERT INTO common_Area VALUES(71,'通州区',1,0,2,11,'0');
INSERT INTO common_Area VALUES(72,'顺义区',1,0,2,12,'0');
INSERT INTO common_Area VALUES(73,'昌平区',1,0,2,13,'0');
INSERT INTO common_Area VALUES(74,'大兴区',1,0,2,14,'0');
INSERT INTO common_Area VALUES(75,'怀柔区',1,0,2,15,'0');
INSERT INTO common_Area VALUES(76,'平谷区',1,0,2,16,'0');
INSERT INTO common_Area VALUES(77,'延庆县',1,0,2,17,'0');
INSERT INTO common_Area VALUES(78,'密云县',1,0,2,18,'0');
UPDATE common_Area SET ChildAmount = 18 WHERE Area_Id = 1 ;
--5河北省(2005年辖:11个地级市,36个市辖区、22个县级市、108个县、6个自治县,'1');
INSERT INTO common_Area VALUES(101,'石家庄市',5,0,2,1,'1');
INSERT INTO common_Area VALUES(102,'唐山市',5,0,2,2,'1');
INSERT INTO common_Area VALUES(103,'秦皇岛市',5,0,2,3,'1');
INSERT INTO common_Area VALUES(104,'邯郸市',5,0,2,4,'1');
INSERT INTO common_Area VALUES(105,'邢台市',5,0,2,5,'1');
INSERT INTO common_Area VALUES(106,'保定市',5,0,2,6,'1');
INSERT INTO common_Area VALUES(107,'张家口市',5,0,2,7,'1');
INSERT INTO common_Area VALUES(108,'承德市',5,0,2,8,'1');
INSERT INTO common_Area VALUES(109,'沧州市',5,0,2,9,'1');
INSERT INTO common_Area VALUES(110,'廊坊市',5,0,2,10,'1');
INSERT INTO common_Area VALUES(111,'衡水市',5,0,2,11,'1');
UPDATE common_Area SET ChildAmount = 11 WHERE Area_Id = 5 ;
--6山西省11个城市
INSERT INTO common_Area VALUES(121,'太原市',6,0,2,1,'1');
INSERT INTO common_Area VALUES(122,'大同市',6,0,2,2,'1');
INSERT INTO common_Area VALUES(123,'阳泉市',6,0,2,3,'1');
INSERT INTO common_Area VALUES(124,'长治市',6,0,2,4,'1');
INSERT INTO common_Area VALUES(125,'晋城市',6,0,2,5,'1');
INSERT INTO common_Area VALUES(126,'朔州市',6,0,2,6,'1');
INSERT INTO common_Area VALUES(127,'晋中市',6,0,2,7,'1');
INSERT INTO common_Area VALUES(128,'运城市',6,0,2,8,'1');
INSERT INTO common_Area VALUES(129,'忻州市',6,0,2,9,'1');
INSERT INTO common_Area VALUES(130,'临汾市',6,0,2,10,'1');
INSERT INTO common_Area VALUES(131,'吕梁市',6,0,2,11,'1');
UPDATE common_Area SET ChildAmount = 11 WHERE Area_Id = 6 ;
---7台湾省(台湾本岛和澎湖共设7市、16县,其中台北市和高雄市为“院辖市”,直属“行政院”,其余属台湾省;市下设区,县下设市(县辖市)、镇、乡,合称区市镇乡。,'1');
INSERT INTO common_Area VALUES(141,'台北市',7,0,2,1,'1');
INSERT INTO common_Area VALUES(142,'高雄市',7,0,2,2,'1');
INSERT INTO common_Area VALUES(143,'基隆市',7,0,2,3,'1');
INSERT INTO common_Area VALUES(144,'台中市',7,0,2,4,'1');
INSERT INTO common_Area VALUES(145,'台南市',7,0,2,5,'1');
INSERT INTO common_Area VALUES(146,'新竹市',7,0,2,6,'1');
INSERT INTO common_Area VALUES(147,'嘉义市',7,0,2,7,'1');
INSERT INTO common_Area VALUES(148,'台北县',7,0,2,8,'1');
INSERT INTO common_Area VALUES(149,'宜兰县',7,0,2,9,'1');
INSERT INTO common_Area VALUES(150,'桃园县',7,0,2,10,'1');
INSERT INTO common_Area VALUES(151,'新竹县',7,0,2,11,'1');
INSERT INTO common_Area VALUES(152,'苗栗县',7,0,2,12,'1');
INSERT INTO common_Area VALUES(153,'台中县',7,0,2,13,'1');
INSERT INTO common_Area VALUES(154,'彰化县',7,0,2,14,'1');
INSERT INTO common_Area VALUES(155,'南投县',7,0,2,15,'1');
INSERT INTO common_Area VALUES(156,'云林县',7,0,2,16,'1');
INSERT INTO common_Area VALUES(157,'嘉义县',7,0,2,17,'1');
INSERT INTO common_Area VALUES(158,'台南县',7,0,2,18,'1');
INSERT INTO common_Area VALUES(159,'高雄县',7,0,2,19,'1');
INSERT INTO common_Area VALUES(160,'屏东县',7,0,2,20,'1');
INSERT INTO common_Area VALUES(161,'澎湖县',7,0,2,21,'1');
INSERT INTO common_Area VALUES(162,'台东县',7,0,2,22,'1');
INSERT INTO common_Area VALUES(163,'花莲县',7,0,2,23,'1');
UPDATE common_Area SET ChildAmount = 23 WHERE Area_Id = 7 ;
--8辽宁省(2006年,辖:14个地级市;56个市辖区、17个县级市、19个县、8个自治县。,'1');
INSERT INTO common_Area VALUES(181,'沈阳市',8,0,2,1,'1');
INSERT INTO common_Area VALUES(182,'大连市',8,0,2,2,'1');
INSERT INTO common_Area VALUES(183,'鞍山市',8,0,2,3,'1');
INSERT INTO common_Area VALUES(184,'抚顺市',8,0,2,4,'1');
INSERT INTO common_Area VALUES(185,'本溪市',8,0,2,5,'1');
INSERT INTO common_Area VALUES(186,'丹东市',8,0,2,6,'1');
INSERT INTO common_Area VALUES(187,'锦州市',8,0,2,7,'1');
INSERT INTO common_Area VALUES(188,'营口市',8,0,2,8,'1');
INSERT INTO common_Area VALUES(189,'阜新市',8,0,2,9,'1');
INSERT INTO common_Area VALUES(190,'辽阳市',8,0,2,10,'1');
INSERT INTO common_Area VALUES(191,'盘锦市',8,0,2,11,'1');
INSERT INTO common_Area VALUES(192,'铁岭市',8,0,2,12,'1');
INSERT INTO common_Area VALUES(193,'朝阳市',8,0,2,13,'1');
INSERT INTO common_Area VALUES(194,'葫芦岛市',8,0,2,14,'1');
UPDATE common_Area SET ChildAmount = 14 WHERE Area_Id = 8 ;
--9吉林省(2006年,辖:8个地级市、1个自治州;20个市辖区、20个县级市、17个县、3个自治县。,'1');
INSERT INTO common_Area VALUES(201,'长春市',9,0,2,1,'1');
INSERT INTO common_Area VALUES(202,'吉林市',9,0,2,2,'1');
INSERT INTO common_Area VALUES(203,'四平市',9,0,2,3,'1');
INSERT INTO common_Area VALUES(204,'辽源市',9,0,2,4,'1');
INSERT INTO common_Area VALUES(205,'通化市',9,0,2,5,'1');
INSERT INTO common_Area VALUES(206,'白山市',9,0,2,6,'1');
INSERT INTO common_Area VALUES(207,'松原市',9,0,2,7,'1');
INSERT INTO common_Area VALUES(208,'白城市',9,0,2,8,'1');
INSERT INTO common_Area VALUES(209,'延边朝鲜族自治州',9,0,2,9,'1');
UPDATE common_Area SET ChildAmount = 9 WHERE Area_Id = 9 ;
--10黑龙江省(2006年,辖:12地级市、1地区;64市辖区、18县级市、45县、1自治县,'1');
INSERT INTO common_Area VALUES(221,'哈尔滨市',10,0,2,1,'1');
INSERT INTO common_Area VALUES(222,'齐齐哈尔市',10,0,2,2,'1');
INSERT INTO common_Area VALUES(223,'鹤 岗 市',10,0,2,3,'1');
INSERT INTO common_Area VALUES(224,'双鸭山市',10,0,2,4,'1');
INSERT INTO common_Area VALUES(225,'鸡 西 市',10,0,2,5,'1');
INSERT INTO common_Area VALUES(226,'大 庆 市',10,0,2,6,'1');
INSERT INTO common_Area VALUES(227,'伊 春 市',10,0,2,7,'1');
INSERT INTO common_Area VALUES(228,'牡丹江市',10,0,2,8,'1');
INSERT INTO common_Area VALUES(229,'佳木斯市',10,0,2,9,'1');
INSERT INTO common_Area VALUES(230,'七台河市',10,0,2,10,'1');
INSERT INTO common_Area VALUES(231,'黑 河 市',10,0,2,11,'1');
INSERT INTO common_Area VALUES(232,'绥 化 市',10,0,2,12,'1');
INSERT INTO common_Area VALUES(233,'大兴安岭地区',10,0,2,13,'1');
UPDATE common_Area SET ChildAmount = 13 WHERE Area_Id = 10 ;
--11江苏省(2005年辖:13个地级市;54个市辖区、27个县级市、25个县,'1');
INSERT INTO common_Area VALUES(241,'南京市',11,0,2,1,'1');
INSERT INTO common_Area VALUES(242,'无锡市',11,0,2,2,'1');
INSERT INTO common_Area VALUES(243,'徐州市',11,0,2,3,'1');
INSERT INTO common_Area VALUES(244,'常州市',11,0,2,4,'1');
INSERT INTO common_Area VALUES(245,'苏州市',11,0,2,5,'1');
INSERT INTO common_Area VALUES(246,'南通市',11,0,2,6,'1');
INSERT INTO common_Area VALUES(247,'连云港市',11,0,2,7,'1');
INSERT INTO common_Area VALUES(248,'淮安市',11,0,2,8,'1');
INSERT INTO common_Area VALUES(249,'盐城市',11,0,2,9,'1');
INSERT INTO common_Area VALUES(250,'扬州市',11,0,2,10,'1');
INSERT INTO common_Area VALUES(251,'镇江市',11,0,2,11,'1');
INSERT INTO common_Area VALUES(252,'泰州市',11,0,2,12,'1');
INSERT INTO common_Area VALUES(253,'宿迁市',11,0,2,13,'1');
UPDATE common_Area SET ChildAmount = 13 WHERE Area_Id = 11 ;
--12浙江省(2006年,辖:11个地级市;32个市辖区、22个县级市、35个县、1个自治县。,'1');
INSERT INTO common_Area VALUES(281,'杭州市',12,0,2,1,'1');
INSERT INTO common_Area VALUES(282,'宁波市',12,0,2,2,'1');
INSERT INTO common_Area VALUES(283,'温州市',12,0,2,3,'1');
INSERT INTO common_Area VALUES(284,'嘉兴市',12,0,2,4,'1');
INSERT INTO common_Area VALUES(285,'湖州市',12,0,2,5,'1');
INSERT INTO common_Area VALUES(286,'绍兴市',12,0,2,6,'1');
INSERT INTO common_Area VALUES(287,'金华市',12,0,2,7,'1');
INSERT INTO common_Area VALUES(288,'衢州市',12,0,2,8,'1');
INSERT INTO common_Area VALUES(289,'舟山市',12,0,2,9,'1');
INSERT INTO common_Area VALUES(290,'台州市',12,0,2,10,'1');
INSERT INTO common_Area VALUES(291,'丽水市',12,0,2,11,'1');
UPDATE common_Area SET ChildAmount = 11 WHERE Area_Id = 12 ;
--13安徽省(2005年辖:17个地级市;44个市辖区、5县个级市、56个县。,'1');
INSERT INTO common_Area VALUES(301,'合肥市',13,0,2,1,'1');
INSERT INTO common_Area VALUES(302,'芜湖市',13,0,2,2,'1');
INSERT INTO common_Area VALUES(303,'蚌埠市',13,0,2,3,'1');
INSERT INTO common_Area VALUES(304,'淮南市',13,0,2,4,'1');
INSERT INTO common_Area VALUES(305,'马鞍山市',13,0,2,5,'1');
INSERT INTO common_Area VALUES(306,'淮北市',13,0,2,6,'1');
INSERT INTO common_Area VALUES(307,'铜陵市',13,0,2,7,'1');
INSERT INTO common_Area VALUES(308,'安庆市',13,0,2,8,'1');
INSERT INTO common_Area VALUES(309,'黄山市',13,0,2,9,'1');
INSERT INTO common_Area VALUES(310,'滁州市',13,0,2,10,'1');
INSERT INTO common_Area VALUES(311,'阜阳市',13,0,2,11,'1');
INSERT INTO common_Area VALUES(312,'宿州市',13,0,2,12,'1');
INSERT INTO common_Area VALUES(313,'巢湖市',13,0,2,13,'1');
INSERT INTO common_Area VALUES(314,'六安市',13,0,2,14,'1');
INSERT INTO common_Area VALUES(315,'亳州市',13,0,2,15,'1');
INSERT INTO common_Area VALUES(316,'池州市',13,0,2,16,'1');
INSERT INTO common_Area VALUES(317,'宣城市',13,0,2,17,'1');
UPDATE common_Area SET ChildAmount = 17 WHERE Area_Id = 13 ;
--14福建省(2006年辖:9个地级市;26个市辖区、14个县级市、45个县。,'1');
INSERT INTO common_Area VALUES(321,'福州市',14,0,2,1,'1');
INSERT INTO common_Area VALUES(322,'厦门市',14,0,2,2,'1');
INSERT INTO common_Area VALUES(323,'莆田市',14,0,2,3,'1');
INSERT INTO common_Area VALUES(324,'三明市',14,0,2,4,'1');
INSERT INTO common_Area VALUES(325,'泉州市',14,0,2,5,'1');
INSERT INTO common_Area VALUES(326,'漳州市',14,0,2,6,'1');
INSERT INTO common_Area VALUES(327,'南平市',14,0,2,7,'1');
INSERT INTO common_Area VALUES(328,'龙岩市',14,0,2,8,'1');
INSERT INTO common_Area VALUES(329,'宁德市',14,0,2,9,'1');
UPDATE common_Area SET ChildAmount = 9 WHERE Area_Id = 14 ;
--15江西省(2006年全省辖:11个地级市;19个市辖区、10个县级市、70个县。,'1');
INSERT INTO common_Area VALUES(341,'南昌市',15,0,2,1,'1');
INSERT INTO common_Area VALUES(342,'景德镇市',15,0,2,2,'1');
INSERT INTO common_Area VALUES(343,'萍乡市',15,0,2,3,'1');
INSERT INTO common_Area VALUES(344,'九江市',15,0,2,4,'1');
INSERT INTO common_Area VALUES(345,'新余市',15,0,2,5,'1');
INSERT INTO common_Area VALUES(346,'鹰潭市',15,0,2,6,'1');
INSERT INTO common_Area VALUES(347,'赣州市',15,0,2,7,'1');
INSERT INTO common_Area VALUES(348,'吉安市',15,0,2,8,'1');
INSERT INTO common_Area VALUES(349,'宜春市',15,0,2,9,'1');
INSERT INTO common_Area VALUES(350,'抚州市',15,0,2,10,'1');
INSERT INTO common_Area VALUES(351,'上饶市',15,0,2,11,'1');
UPDATE common_Area SET ChildAmount = 11 WHERE Area_Id = 15 ;
--16山东省(2005年,辖:17个地级市;49个市辖区、31个县级市、60个县。,'1');
INSERT INTO common_Area VALUES(361,'济南市',16,0,2,1,'1');
INSERT INTO common_Area VALUES(362,'青岛市',16,0,2,2,'1');
INSERT INTO common_Area VALUES(363,'淄博市',16,0,2,3,'1');
INSERT INTO common_Area VALUES(364,'枣庄市',16,0,2,4,'1');
INSERT INTO common_Area VALUES(365,'东营市',16,0,2,5,'1');
INSERT INTO common_Area VALUES(366,'烟台市',16,0,2,6,'1');
INSERT INTO common_Area VALUES(367,'潍坊市',16,0,2,7,'1');
INSERT INTO common_Area VALUES(368,'济宁市',16,0,2,8,'1');
INSERT INTO common_Area VALUES(369,'泰安市',16,0,2,9,'1');
INSERT INTO common_Area VALUES(370,'威海市',16,0,2,10,'1');
INSERT INTO common_Area VALUES(371,'日照市',16,0,2,11,'1');
INSERT INTO common_Area VALUES(372,'莱芜市',16,0,2,12,'1');
INSERT INTO common_Area VALUES(373,'临沂市',16,0,2,13,'1');
INSERT INTO common_Area VALUES(374,'德州市',16,0,2,14,'1');
INSERT INTO common_Area VALUES(375,'聊城市',16,0,2,15,'1');
INSERT INTO common_Area VALUES(376,'滨州市',16,0,2,16,'1');
INSERT INTO common_Area VALUES(377,'菏泽市',16,0,2,17,'1');
UPDATE common_Area SET ChildAmount = 17 WHERE Area_Id = 16 ;
--17河南省(2005年辖:17个地级市;50个市辖区、21个县级市、88个县。)
INSERT INTO common_Area VALUES(401,'郑州市',17,0,2,1,'1');
INSERT INTO common_Area VALUES(402,'开封市',17,0,2,2,'1');
INSERT INTO common_Area VALUES(403,'洛阳市',17,0,2,3,'1');
INSERT INTO common_Area VALUES(404,'平顶山市',17,0,2,4,'1');
INSERT INTO common_Area VALUES(405,'安阳市',17,0,2,5,'1');
INSERT INTO common_Area VALUES(406,'鹤壁市',17,0,2,6,'1');
INSERT INTO common_Area VALUES(407,'新乡市',17,0,2,7,'1');
INSERT INTO common_Area VALUES(408,'焦作市',17,0,2,8,'1');
INSERT INTO common_Area VALUES(409,'濮阳市',17,0,2,9,'1');
INSERT INTO common_Area VALUES(410,'许昌市',17,0,2,10,'1');
INSERT INTO common_Area VALUES(411,'漯河市',17,0,2,11,'1');
INSERT INTO common_Area VALUES(412,'三门峡市',17,0,2,12,'1');
INSERT INTO common_Area VALUES(413,'南阳市',17,0,2,13,'1');
INSERT INTO common_Area VALUES(414,'商丘市',17,0,2,14,'1');
INSERT INTO common_Area VALUES(415,'信阳市',17,0,2,15,'1');
INSERT INTO common_Area VALUES(416,'周口市',17,0,2,16,'1');
INSERT INTO common_Area VALUES(417,'驻马店市',17,0,2,17,'1');
INSERT INTO common_Area VALUES(418,'济源市',17,0,2,18,'1');
UPDATE common_Area SET ChildAmount = 18 WHERE Area_Id = 17 ;
--18湖北省(截至2005年12月31日,全省辖13个地级单位(12个地级市、1个自治州);102县级单位(38个市辖区、24个县级市、37个县、2个自治县、1个林区),共有1220个乡级单位(277个街道、733个镇、210个乡)。)
INSERT INTO common_Area VALUES(421,'武汉市',18,0,2,1,'1');
INSERT INTO common_Area VALUES(422,'黄石市',18,0,2,2,'1');
INSERT INTO common_Area VALUES(423,'十堰市',18,0,2,3,'1');
INSERT INTO common_Area VALUES(424,'荆州市',18,0,2,4,'1');
INSERT INTO common_Area VALUES(425,'宜昌市',18,0,2,5,'1');
INSERT INTO common_Area VALUES(426,'襄樊市',18,0,2,6,'1');
INSERT INTO common_Area VALUES(427,'鄂州市',18,0,2,7,'1');
INSERT INTO common_Area VALUES(428,'荆门市',18,0,2,8,'1');
INSERT INTO common_Area VALUES(429,'孝感市',18,0,2,9,'1');
INSERT INTO common_Area VALUES(430,'黄冈市',18,0,2,10,'1');
INSERT INTO common_Area VALUES(431,'咸宁市',18,0,2,11,'1');
INSERT INTO common_Area VALUES(432,'随州市',18,0,2,12,'1');
INSERT INTO common_Area VALUES(433,'仙桃市',18,0,2,13,'1');
INSERT INTO common_Area VALUES(434,'天门市',18,0,2,14,'1');
INSERT INTO common_Area VALUES(435,'潜江市',18,0,2,15,'1');
INSERT INTO common_Area VALUES(436,'神农架林区',18,0,2,16,'1');
INSERT INTO common_Area VALUES(437,'恩施土家族苗族自治州',18,0,2,17,'1');
UPDATE common_Area SET ChildAmount = 17 WHERE Area_Id = 18 ;
--19湖南省(2005年辖:13个地级市、1个自治州;34个市辖区、16个县级市、65个县、7个自治县。)
INSERT INTO common_Area VALUES(441,'长沙市',19,0,2,1,'1');
INSERT INTO common_Area VALUES(442,'株洲市',19,0,2,2,'1');
INSERT INTO common_Area VALUES(443,'湘潭市',19,0,2,3,'1');
INSERT INTO common_Area VALUES(444,'衡阳市',19,0,2,4,'1');
INSERT INTO common_Area VALUES(445,'邵阳市',19,0,2,5,'1');
INSERT INTO common_Area VALUES(446,'岳阳市',19,0,2,6,'1');
INSERT INTO common_Area VALUES(447,'常德市',19,0,2,7,'1');
INSERT INTO common_Area VALUES(448,'张家界市',19,0,2,8,'1');
INSERT INTO common_Area VALUES(449,'益阳市',19,0,2,9,'1');
INSERT INTO common_Area VALUES(450,'郴州市',19,0,2,10,'1');
INSERT INTO common_Area VALUES(451,'永州市',19,0,2,11,'1');
INSERT INTO common_Area VALUES(452,'怀化市',19,0,2,12,'1');
INSERT INTO common_Area VALUES(453,'娄底市',19,0,2,13,'1');
INSERT INTO common_Area VALUES(454,'湘西土家族苗族自治州',19,0,2,14,'1');
UPDATE common_Area SET ChildAmount = 14 WHERE Area_Id = 19 ;
--20广东省(截至2005年12月31日,广东省辖:21个地级市,54个市辖区、23个县级市、41个县、3个自治县,429个街道办事处、1145个镇、4个乡、7个民族乡。)
INSERT INTO common_Area VALUES(455,'广州市',20,0,2,1,'1');
INSERT INTO common_Area VALUES(456,'深圳市',20,0,2,2,'1');
INSERT INTO common_Area VALUES(457,'珠海市',20,0,2,3,'1');
INSERT INTO common_Area VALUES(458,'汕头市',20,0,2,4,'1');
INSERT INTO common_Area VALUES(459,'韶关市',20,0,2,5,'1');
INSERT INTO common_Area VALUES(460,'佛山市',20,0,2,6,'1');
INSERT INTO common_Area VALUES(461,'江门市',20,0,2,7,'1');
INSERT INTO common_Area VALUES(462,'湛江市',20,0,2,8,'1');
INSERT INTO common_Area VALUES(463,'茂名市',20,0,2,9,'1');
INSERT INTO common_Area VALUES(464,'肇庆市',20,0,2,10,'1');
INSERT INTO common_Area VALUES(465,'惠州市',20,0,2,11,'1');
INSERT INTO common_Area VALUES(466,'梅州市',20,0,2,12,'1');
INSERT INTO common_Area VALUES(467,'汕尾市',20,0,2,13,'1');
INSERT INTO common_Area VALUES(468,'河源市',20,0,2,14,'1');
INSERT INTO common_Area VALUES(469,'阳江市',20,0,2,15,'1');
INSERT INTO common_Area VALUES(470,'清远市',20,0,2,16,'1');
INSERT INTO common_Area VALUES(485,'东莞市',20,0,2,17,'1');
INSERT INTO common_Area VALUES(486,'中山市',20,0,2,18,'1');
INSERT INTO common_Area VALUES(487,'潮州市',20,0,2,19,'1');
INSERT INTO common_Area VALUES(488,'揭阳市',20,0,2,20,'1');
INSERT INTO common_Area VALUES(489,'云浮市',20,0,2,21,'1');
UPDATE common_Area SET ChildAmount = 21 WHERE Area_Id = 20 ;
--21甘肃省(2006年辖:12个地级市、2个自治州;17个市辖区、4个县级市、58个县、7个自治县。)
INSERT INTO common_Area VALUES(471,'兰州市',21,0,2,1,'1');
INSERT INTO common_Area VALUES(472,'金昌市',21,0,2,2,'1');
INSERT INTO common_Area VALUES(473,'白银市',21,0,2,3,'1');
INSERT INTO common_Area VALUES(474,'天水市',21,0,2,4,'1');
INSERT INTO common_Area VALUES(475,'嘉峪关市',21,0,2,5,'1');
INSERT INTO common_Area VALUES(476,'武威市',21,0,2,6,'1');
INSERT INTO common_Area VALUES(477,'张掖市',21,0,2,7,'1');
INSERT INTO common_Area VALUES(478,'平凉市',21,0,2,8,'1');
INSERT INTO common_Area VALUES(479,'酒泉市',21,0,2,9,'1');
INSERT INTO common_Area VALUES(480,'庆阳市',21,0,2,10,'1');
INSERT INTO common_Area VALUES(481,'定西市',21,0,2,11,'1');
INSERT INTO common_Area VALUES(482,'陇南市',21,0,2,12,'1');
INSERT INTO common_Area VALUES(483,'临夏回族自治州',21,0,2,13,'1');
INSERT INTO common_Area VALUES(484,'甘南藏族自治州',21,0,2,14,'1');
UPDATE common_Area SET ChildAmount = 14 WHERE Area_Id = 21 ;
--22四川省(2006年辖:18个地级市、3个自治州;43个市辖区、14个县级市、120个县、4个自治县。)
INSERT INTO common_Area VALUES(491,'成都市',22,0,2,1,'1');
INSERT INTO common_Area VALUES(492,'自贡市',22,0,2,2,'1');
INSERT INTO common_Area VALUES(493,'攀枝花市',22,0,2,3,'1');
INSERT INTO common_Area VALUES(494,'泸州市',22,0,2,4,'1');
INSERT INTO common_Area VALUES(495,'德阳市',22,0,2,5,'1');
INSERT INTO common_Area VALUES(496,'绵阳市',22,0,2,6,'1');
INSERT INTO common_Area VALUES(497,'广元市',22,0,2,7,'1');
INSERT INTO common_Area VALUES(498,'遂宁市',22,0,2,8,'1');
INSERT INTO common_Area VALUES(499,'内江市',22,0,2,9,'1');
INSERT INTO common_Area VALUES(500,'乐山市',22,0,2,10,'1');
INSERT INTO common_Area VALUES(501,'南充市',22,0,2,11,'1');
INSERT INTO common_Area VALUES(502,'眉山市',22,0,2,12,'1');
INSERT INTO common_Area VALUES(503,'宜宾市',22,0,2,13,'1');
INSERT INTO common_Area VALUES(504,'广安市',22,0,2,14,'1');
INSERT INTO common_Area VALUES(505,'达州市',22,0,2,15,'1');
INSERT INTO common_Area VALUES(506,'雅安市',22,0,2,16,'1');
INSERT INTO common_Area VALUES(507,'巴中市',22,0,2,17,'1');
INSERT INTO common_Area VALUES(508,'资阳市',22,0,2,18,'1');
INSERT INTO common_Area VALUES(509,'阿坝藏族羌族自治州',22,0,2,19,'1');
INSERT INTO common_Area VALUES(510,'甘孜藏族自治州',22,0,2,20,'1');
INSERT INTO common_Area VALUES(511,'凉山彝族自治州',22,0,2,21,'1');
UPDATE common_Area SET ChildAmount = 21 WHERE Area_Id = 22 ;
--23贵州省(2006年辖:4个地级市、2个地区、3个自治州;10个市辖区、9个县级市、56个县、11个自治县、2个特区。,'1');
INSERT INTO common_Area VALUES(521,'贵阳市',23,0,2,1,'1');
INSERT INTO common_Area VALUES(522,'六盘水市',23,0,2,2,'1');
INSERT INTO common_Area VALUES(523,'遵义市',23,0,2,3,'1');
INSERT INTO common_Area VALUES(524,'安顺市',23,0,2,4,'1');
INSERT INTO common_Area VALUES(525,'铜仁地区',23,0,2,5,'1');
INSERT INTO common_Area VALUES(526,'毕节地区',23,0,2,6,'1');
INSERT INTO common_Area VALUES(527,'黔西南布依族苗族自治州',23,0,2,7,'1');
INSERT INTO common_Area VALUES(528,'黔东南苗族侗族自治州',23,0,2,8,'1');
INSERT INTO common_Area VALUES(529,'黔南布依族苗族自治州',23,0,2,9,'1');
UPDATE common_Area SET ChildAmount = 9 WHERE Area_Id = 23 ;
--24海南省(2003-2005年 全省有2个地级市,6个县级市,4个县,6个民族自治县,4个市辖区,1个办事处(西南中沙群岛办事处,县级)。,'1');
INSERT INTO common_Area VALUES(541,'海口市',24,0,2,1,'1');
INSERT INTO common_Area VALUES(542,'三亚市',24,0,2,2,'1');
INSERT INTO common_Area VALUES(543,'五指山市',24,0,2,3,'1');
INSERT INTO common_Area VALUES(544,'琼海市',24,0,2,4,'1');
INSERT INTO common_Area VALUES(545,'儋州市',24,0,2,5,'1');
INSERT INTO common_Area VALUES(546,'文昌市',24,0,2,6,'1');
INSERT INTO common_Area VALUES(547,'万宁市',24,0,2,7,'1');
INSERT INTO common_Area VALUES(548,'东方市',24,0,2,8,'1');
INSERT INTO common_Area VALUES(549,'澄迈县',24,0,2,9,'1');
INSERT INTO common_Area VALUES(550,'定安县',24,0,2,10,'1');
INSERT INTO common_Area VALUES(551,'屯昌县',24,0,2,11,'1');
INSERT INTO common_Area VALUES(552,'临高县',24,0,2,12,'1');
INSERT INTO common_Area VALUES(553,'白沙黎族自治县',24,0,2,13,'1');
INSERT INTO common_Area VALUES(554,'昌江黎族自治县',24,0,2,14,'1');
INSERT INTO common_Area VALUES(555,'乐东黎族自治县',24,0,2,15,'1');
INSERT INTO common_Area VALUES(556,'陵水黎族自治县',24,0,2,16,'1');
INSERT INTO common_Area VALUES(557,'保亭黎族苗族自治县',24,0,2,17,'1');
INSERT INTO common_Area VALUES(558,'琼中黎族苗族自治县',24,0,2,18,'1');
UPDATE common_Area SET ChildAmount = 18 WHERE Area_Id = 24 ;
--25云南省(2006年辖:8个地级市、8个自治州;12个市辖区、9个县级市、79个县、29个自治县。,'1');
INSERT INTO common_Area VALUES(571,'昆明市',25,0,2,1,'1');
INSERT INTO common_Area VALUES(572,'曲靖市',25,0,2,2,'1');
INSERT INTO common_Area VALUES(573,'玉溪市',25,0,2,3,'1');
INSERT INTO common_Area VALUES(574,'保山市',25,0,2,4,'1');
INSERT INTO common_Area VALUES(575,'昭通市',25,0,2,5,'1');
INSERT INTO common_Area VALUES(576,'丽江市',25,0,2,6,'1');
INSERT INTO common_Area VALUES(577,'思茅市',25,0,2,7,'1');
INSERT INTO common_Area VALUES(578,'临沧市',25,0,2,8,'1');
INSERT INTO common_Area VALUES(579,'文山壮族苗族自治州',25,0,2,9,'1');
INSERT INTO common_Area VALUES(580,'红河哈尼族彝族自治州',25,0,2,10,'1');
INSERT INTO common_Area VALUES(581,'西双版纳傣族自治州',25,0,2,11,'1');
INSERT INTO common_Area VALUES(582,'楚雄彝族自治州',25,0,2,12,'1');
INSERT INTO common_Area VALUES(583,'大理白族自治州',25,0,2,13,'1');
INSERT INTO common_Area VALUES(584,'德宏傣族景颇族自治州',25,0,2,14,'1');
INSERT INTO common_Area VALUES(585,'怒江傈傈族自治州',25,0,2,15,'1');
INSERT INTO common_Area VALUES(586,'迪庆藏族自治州',25,0,2,16,'1');
UPDATE common_Area SET ChildAmount = 16 WHERE Area_Id = 25 ;
--26青海省(2006年辖:1个地级市、1个地区、6个自治州;4个市辖区、2个县级市、30个县、7个自治县。,'1');
INSERT INTO common_Area VALUES(601,'西宁市',26,0,2,1,'1');
INSERT INTO common_Area VALUES(602,'海东地区',26,0,2,2,'1');
INSERT INTO common_Area VALUES(603,'海北藏族自治州',26,0,2,3,'1');
INSERT INTO common_Area VALUES(604,'黄南藏族自治州',26,0,2,4,'1');
INSERT INTO common_Area VALUES(605,'海南藏族自治州',26,0,2,5,'1');
INSERT INTO common_Area VALUES(606,'果洛藏族自治州',26,0,2,6,'1');
INSERT INTO common_Area VALUES(607,'玉树藏族自治州',26,0,2,7,'1');
INSERT INTO common_Area VALUES(608,'海西蒙古族藏族自治州',26,0,2,8,'1');
UPDATE common_Area SET ChildAmount = 8 WHERE Area_Id = 26 ;
--27陕西省(2006年辖:10个地级市;24个市辖区、3个县级市、80个县。,'1');
INSERT INTO common_Area VALUES(621,'西安市',27,0,2,1,'1');
INSERT INTO common_Area VALUES(622,'铜川市',27,0,2,2,'1');
INSERT INTO common_Area VALUES(623,'宝鸡市',27,0,2,3,'1');
INSERT INTO common_Area VALUES(624,'咸阳市',27,0,2,4,'1');
INSERT INTO common_Area VALUES(625,'渭南市',27,0,2,5,'1');
INSERT INTO common_Area VALUES(626,'延安市',27,0,2,6,'1');
INSERT INTO common_Area VALUES(627,'汉中市',27,0,2,7,'1');
INSERT INTO common_Area VALUES(628,'榆林市',27,0,2,8,'1');
INSERT INTO common_Area VALUES(629,'安康市',27,0,2,9,'1');
INSERT INTO common_Area VALUES(630,'商洛市',27,0,2,10,'1');
UPDATE common_Area SET ChildAmount = 10 WHERE Area_Id = 27 ;
--28广西壮族自治区(2005年辖:14个地级市;34个市辖区、7个县级市、56个县、12个自治县。,'1');
INSERT INTO common_Area VALUES(641,'南宁市',28,0,2,1,'1');
INSERT INTO common_Area VALUES(642,'柳州市',28,0,2,2,'1');
INSERT INTO common_Area VALUES(643,'桂林市',28,0,2,3,'1');
INSERT INTO common_Area VALUES(644,'梧州市',28,0,2,4,'1');
INSERT INTO common_Area VALUES(645,'北海市',28,0,2,5,'1');
INSERT INTO common_Area VALUES(646,'防城港市',28,0,2,6,'1');
INSERT INTO common_Area VALUES(647,'钦州市',28,0,2,7,'1');
INSERT INTO common_Area VALUES(648,'贵港市',28,0,2,8,'1');
INSERT INTO common_Area VALUES(649,'玉林市',28,0,2,9,'1');
INSERT INTO common_Area VALUES(650,'百色市',28,0,2,10,'1');
INSERT INTO common_Area VALUES(651,'贺州市',28,0,2,11,'1');
INSERT INTO common_Area VALUES(652,'河池市',28,0,2,12,'1');
INSERT INTO common_Area VALUES(653,'来宾市',28,0,2,13,'1');
INSERT INTO common_Area VALUES(654,'崇左市',28,0,2,14,'1');
UPDATE common_Area SET ChildAmount = 14 WHERE Area_Id = 28 ;
--29西藏自治区(2005年辖:1个地级市、6个地区;1个市辖区、1个县级市、71个县。,'1');
INSERT INTO common_Area VALUES(671,'拉萨市',29,0,2,1,'1');
INSERT INTO common_Area VALUES(672,'那曲地区',29,0,2,2,'1');
INSERT INTO common_Area VALUES(673,'昌都地区',29,0,2,3,'1');
INSERT INTO common_Area VALUES(674,'山南地区',29,0,2,4,'1');
INSERT INTO common_Area VALUES(675,'日喀则地区',29,0,2,5,'1');
INSERT INTO common_Area VALUES(676,'阿里地区',29,0,2,6,'1');
INSERT INTO common_Area VALUES(677,'林芝地区',29,0,2,7,'1');
UPDATE common_Area SET ChildAmount = 7 WHERE Area_Id = 29 ;
--30宁夏回族自治区
INSERT INTO common_Area VALUES(681,'银川市',30,0,2,1,'1');
INSERT INTO common_Area VALUES(682,'石嘴山市',30,0,2,2,'1');
INSERT INTO common_Area VALUES(683,'吴忠市',30,0,2,3,'1');
INSERT INTO common_Area VALUES(684,'固原市',30,0,2,4,'1');
INSERT INTO common_Area VALUES(685,'中卫市',30,0,2,5,'1');
UPDATE common_Area SET ChildAmount = 5 WHERE Area_Id = 30 ;
--31新疆维吾尔自治区(2005年辖:2个地级市、7个地区、5个自治州;11个市辖区、20个县级市、62个县、6个自治县,'1');
INSERT INTO common_Area VALUES(691,'乌鲁木齐市',31,0,2,1,'1');
INSERT INTO common_Area VALUES(692,'克拉玛依市',31,0,2,2,'1');
INSERT INTO common_Area VALUES(693,'石河子市 ',31,0,2,3,'1');
INSERT INTO common_Area VALUES(694,'阿拉尔市',31,0,2,4,'1');
INSERT INTO common_Area VALUES(695,'图木舒克市',31,0,2,5,'1');
INSERT INTO common_Area VALUES(696,'五家渠市',31,0,2,6,'1');
INSERT INTO common_Area VALUES(697,'吐鲁番市',31,0,2,7,'1');
INSERT INTO common_Area VALUES(698,'阿克苏市',31,0,2,8,'1');
INSERT INTO common_Area VALUES(699,'喀什市',31,0,2,9,'1');
INSERT INTO common_Area VALUES(700,'哈密市',31,0,2,10,'1');
INSERT INTO common_Area VALUES(701,'和田市',31,0,2,11,'1');
INSERT INTO common_Area VALUES(702,'阿图什市',31,0,2,12,'1');
INSERT INTO common_Area VALUES(703,'库尔勒市',31,0,2,13,'1');
INSERT INTO common_Area VALUES(704,'昌吉市 ',31,0,2,14,'1');
INSERT INTO common_Area VALUES(705,'阜康市',31,0,2,15,'1');
INSERT INTO common_Area VALUES(706,'米泉市',31,0,2,16,'1');
INSERT INTO common_Area VALUES(707,'博乐市',31,0,2,17,'1');
INSERT INTO common_Area VALUES(708,'伊宁市',31,0,2,18,'1');
INSERT INTO common_Area VALUES(709,'奎屯市',31,0,2,19,'1');
INSERT INTO common_Area VALUES(710,'塔城市',31,0,2,20,'1');
INSERT INTO common_Area VALUES(711,'乌苏市',31,0,2,21,'1');
INSERT INTO common_Area VALUES(712,'阿勒泰市',31,0,2,22,'1');
UPDATE common_Area SET ChildAmount = 22 WHERE Area_Id = 31 ;
--33内蒙古自治区(2006年,辖:9个地级市、3个盟;21个市辖区、11个县级市、17个县、49个旗、3个自治旗。,'1');
INSERT INTO common_Area VALUES(721,'呼和浩特市',32,0,2,1,'1');
INSERT INTO common_Area VALUES(722,'包头市',32,0,2,2,'1');
INSERT INTO common_Area VALUES(723,'乌海市',32,0,2,3,'1');
INSERT INTO common_Area VALUES(724,'赤峰市',32,0,2,4,'1');
INSERT INTO common_Area VALUES(725,'通辽市',32,0,2,5,'1');
INSERT INTO common_Area VALUES(726,'鄂尔多斯市',32,0,2,6,'1');
INSERT INTO common_Area VALUES(727,'呼伦贝尔市',32,0,2,7,'1');
INSERT INTO common_Area VALUES(728,'巴彦淖尔市',32,0,2,8,'1');
INSERT INTO common_Area VALUES(729,'乌兰察布市',32,0,2,9,'1');
INSERT INTO common_Area VALUES(730,'锡林郭勒盟',32,0,2,10,'1');
INSERT INTO common_Area VALUES(731,'兴安盟',32,0,2,11,'1');
INSERT INTO common_Area VALUES(732,'阿拉善盟',32,0,2,12,'1');
UPDATE common_Area SET ChildAmount = 12 WHERE Area_Id = 32 ;
订阅:
博文 (Atom)