2006-01-12 10:28:10  |
| 软件核心竞争力 |
搞软件开发这些年来,无论开发思想还是开发技术总是在跟着国外的潮流跑。struts热时研究struts,hibernate热时研究hibernate,设计模式热时研究设计模式,spring热时研究spring,ejb热时研究ejb,soa现在热了又开始研究soa...唉,反反复复,无穷尽也。我们总是在研究研究,学习学习。国外西北风,国内也马上西北风,国外东南风,国内也马上跟着转。 什么时候我们也有自己的核心技术,让国外的开发人员跟着我们的技术方向跑?国内不少开发人员做起了国外先进技术的播种者,但却很少人实实在在的作一些核心技术产品的开发。而更多的象我之类的人,为了生存,每天忙忙碌碌的随波逐流。 没有核心技术,就没有竞争力。期待软件行业更多的弄潮儿! |
| 标签:软件核心竞争力 |
作者 zhaoshouzhong 阅读全文 |
评论()
| 人气() |
引用()
| 推荐 | 保存日志
|
2006-01-12 10:08:55  |
2005-11-22 11:32:29  |
| XPDL2.0正式版发布 |
WFMC于2005.10.3发布了xpdl2.0 Release版本。xpdl2.0比1.0语法增强了很多,兼容了BPMN(Business Process Modeling Notation)。并且对于应用部分,扩充增加了对EJB,POJO,WebService,xlst的支持,增加了事件的语法。有了这些支持,对实现分布式工作流开发就相对比较容易了。 JAWE目前仅实现了xpdl1.0版本,shark也仅能解析xpdl1.0版本。要他们完全支持xpdl2.0,还需要等待他们最新的版本发布。 |
| 标签:XPDL2.0正式版发布 |
作者 zhaoshouzhong 阅读全文 |
评论()
| 人气() |
引用()
| 推荐 | 保存日志
|
2005-11-13 12:58:03  |
| 基于基线的版本管理和质量控制 |
基线概念: 基线是项目储存库中每个工件版本在特定时期的一个“快照”。它提供一个正式标准,随后的工作基于此标准,并且只有经过授权后才能变更这个标准。建立一个初始基线后,以后每次对其进行的变更都将记录为一个差值,直到建成下一个基线。 参与项目的开发人员将基线所代表的各版本的目录和文件填入他们的工作区。随着工作的进展,基线将合并自从上次建立基线以来开发人员已经交付的工作。变更一旦并入基线,开发人员就采用新的基线,以与项目中的变更保持同步。调整基线将把集成工作区中的文件并入开发工作区。 建立基线的三大原因是:重现性、可追踪性和报告。 重现性是指及时返回并重新生成软件系统给定发布版的能力,或者是在项目中的早些时候重新生成开发环境的能力。可追踪性建立项目工件之间的前后继承关系。其目的在于确保设计满足要求、代码实施设计以及用正确代码编译可执行文件。报告来源于一个基线内容同另一个基线内容的比较。基线比较有助于调试并生成发布说明。 建立基线后,需要标注所有组成构件和基线,以便能够对其进行识别和重新建立。 建立基线有以下几个优点: •基线为开发工件提供了一个定点和快照。 •新项目可以从基线提供的定点之中建立。作为一个单独分支,新项目将与随后对原始项目(在主要分支上)所进行的变更进行隔离。 •各开发人员可以将建有基线的构件作为他在隔离的私有工作区中进行更新的基础。 •当认为更新不稳定或不可信时,基线为团队提供一种取消变更的方法。 您可以利用基线重新建立基于某个特定发布版本的配置,这样也可以重现已报告的错误。 备注:以上的信息摘至 RUP(Rational Unified Process,统一过程管理)
基于基线的版本管理和质量控制: 版本管理通常采用如下的方式:(1)每天用最新的程序作为进行测试和bug修正。如果开发新的功能,也是copy最新的版本作为基准版本开发、测试。(2)指定某一天的版本作为一个发布版本,然后把这个版本的文档在vss中单独建档,那么这个版本的程序就和其它版本隔离开了。 以上方法存在如下问题: (1)采用每天的版本作为基准版本开发、测试,那么谁也无法保证这个版本是否是稳定的,哪么每天的版本都处于一种不稳定状态。如果始终在一种不稳定的版本上测试、开发,那么测试效果、开发效果可想而知。 (2)第二种方法也存在不足,即无法实现版本的可跟踪性,并且这种版本的指定,缺乏一定的质量标准(即达到某种质量标准后才可以升级版本),版本的稳定系数无法确知。如果版本多了,那么开发员要同时维护多个版本的程序,既增加了开发成本,又增加了测试人员的测试成本。 (3)无法确切知道开发程序的质量水准,目前仅仅通过bug数量来衡量。这个标准比较粗,并且只是对程序开发测试结果的衡量,无法衡量开发过程、测试过程对软件质量的影响。 解决以上问题,可以以基线作为版本管理的手段,通过基线的提升进行软件质量水平的提升,每次基线的提升就是一个版本的发布。图形如下所示:
 基线初始化: 把某个版本的某个日期的程序(经过充分测试,证明相对稳定的),加入版本控制,放到vss中,作为初始版本。 制订基线晋升标准: 我们可以制订几个基线,如单元测试级别、集成测试级别、系统测试级别、初步稳定级别、较为稳定级别、稳定级别等基线,以用来标示版本的稳定程度。 每个级别都要制定一定的标准,如单元测试级别,需要覆盖80%以上的单元测试,并且bug数量累计小于50个,日平均小于3个,如果达到这个标准,就可以认为需要提出基线晋升申请了。 制订基线晋升策略: 晋升时间:如开始可以每三个月晋升一次,以后每半年晋升一次,可以作为具体任务下达给各项目经理,正如同目前的版本稳定计划一样。 晋升评审:基线晋升需要提出申请,并需要准备相关资料和数据,由配置变更委员会评审。首先要由各项目经理提出负责系统的基线晋升申请,然后由研发主管提出整个系统的基线晋升申请。 不达线处理:对于按期达不到标准的,需要制订相关修正策略。 基线测试:基线评审通过后,要进行测试,证明该基线是否稳定,稳定后,正式提升基线。 程序员: 程序员,每天作的就是在原基线程序的基础上修改程序、测试、提交。为了能够通过基线晋升、他必须提高开发质量、提高bug修改成功、发掘更多的bug(在制订基线标准时,需要把程序员影响的因素考虑在内) 程序经理: 程序经理,每天都要把精力放到软件的质量监控上,指导程序修改bug,安排开发人员、测试人员测试,以及代码抽查、代码检查。如果不这样,到时候他无法完成基线晋升的任务。 测试员: 测试员必须根据基线晋升的标准全面、系统的进行测试,如果他完不成测试要求,也会影响基线的晋升。 测试经理: 根据基线晋升的任务,合理安排、组织对某个系统、模块的测试。 总之,通过基线的管理,把方方面面的人调动起来,把他们的精力由被动的作,到主动的承担起软件质量改进的责任。并且,这种质量的改进是个渐进的过程。 基线管理涉及的东西还是很多的,限于篇幅限制,无法一一列举了。基线管理是配置管理的一个很重要的内容,关于它的意义和作用,网上有好多资料介绍,因此采用基线进行版本管理是项目管理的重要组成部分。
|
| 标签:基于基线的版本管理和质量控制 |
作者 zhaoshouzhong 阅读全文 |
评论()
| 人气() |
引用()
| 推荐 | 保存日志
|
2005-11-13 12:37:37  |
| 计划管理 |
ISO的核心理念是PDCA(Plan,Do,Check,Again)。其中首要的要素是计划。一些小的公司,计划管理是很混乱甚至没有什么计划的。其管理是触发式管理,客户有什么需求、发现什么bug了,就组织人员开发和解决。这些公司缺少一个长期、中期、短期的项目和产品计划。 计划得重要性是不言而喻的,万事“预则立,不预则废”。具体的重要性,相关的企业管理理论中讲的很多,我就不再重复,我的重点是如何制定计划,监控计划。 工具的选择:目前有比较好的项目管理工具,如project,visio(可以作干特图,不是专门的项目管理工具)。利用这些工具,可以提高项目管理水平。当然还有其他的项目管理工具,不过本人认为利用project就足够了。关于如何使用project,读者可以参阅相关资料,如何基于project,开发网络版项目管理工具,可以查找本人以前的有关文档。 计划的制定:计划有长期、中期、短期计划。长期计划是由公司的上层和高级管理层制定的,一般为一年以上的计划。长期计划一般是产品的版本发布计划,新版本计划,市场计划等。中期和短期计划,一般由项目经理制定,中期计划主要侧重于版本的开发计划,短期计划主要侧重于本月、本周的开发计划。而一些软件开发的实际情况是长期计划几乎没有,中期计划很少,短期计划任务不够明确。制定计划是很繁琐的,也很难制定准确,有时候需要经常调整计划。但是无论多麻烦,都必须有清晰的计划。制定计划,要注意检查资源是否超负荷或者负荷不够。当计划计划涉及多个部门时,要充分协调后在制定,以防止制定的计划不可行。 目标:有了计划,还不够,还要给计划制定具体的目标。长期、中期、短期计划都要有目标,有了目标,才能使开发不偏离方向。这往往是计划制定者最容易忽略的地方。比如说开发一个新产品,新产品的目标是什么要制定,如:功能强大(如何强大,要列出包含的具体功能),操作简单(要制定相关标准),架构可以扩充,兼容等等。而短期开发计划中,也要制定明确的目标。如开发新任务时,要告诉程序员,目标是:质量第一,宁可慢些也要保证开发质量;开发完必须通过单元测试等。其实我们制定计划时,都有一个默认的目标,这个目标存在自己的大脑中,必须把它表达出来,清楚地传递给开发人员。不要以为自己明白了,其他人就明白了。 计划的调整:计划制定后,不会一成不变的。而往往需要经常调整。如果计划涉及到多个部门,调整就比较复杂了。要和各部门协调好后,才能调整。计划是有优先级的,要根据实际情况,调整任务的优先级。优先级高的先开发,低的延后开发。但是如果计划调整的太频繁,就需要检查制定的计划是否合理,或者反思公司的管理是否有问题。开发中经常会出现这样的现象:一个任务A正在开发,突然接到一个命令,要先做任务B;任务B还没有作多久,领导又要让作任务C…..如此的安排,将会搞得开发混乱和开发人员的无所适从。出现这种情况,项目经理必须要把关,必要时“抗令”。我和一个香港朋友闲谈时,他说老板的头脑很活跃,经常是一转身就是一个想法,常常令他不知下一步要干什么。 计划的监控:计划制定后,必须检查计划的执行情况,否则计划就会白制定。这也是计划制定者最容易忽略的。计划制订好后就束之高阁,不管不问了。至少每周要检查一次项目的进展,如果比较重要的计划,最好每天都检查。否则时间长了再检查,往往发现开发员实际作的和计划的差别很大,从而造成任务的延期。任务检查时,发现的问题要立即解决,如果和其他部门有关,要要其他部门协调后共同解决。如果发现程序员工作方法有问题,也要立即指正。发现问题后,不要等到工作总结时才提,这样就达不到实际的效果了。 总结:计划管理涉及的东西很多,很难用一点文字描述清楚。要了解计划管理的精髓,还需要阅读有关管理方面的书籍。
|
| 标签:计划管理 |
作者 zhaoshouzhong 阅读全文 |
评论()
| 人气() |
引用()
| 推荐 | 保存日志
|
2005-11-06 19:33:20  |
| winrunner经验总结 |
1.1脚本录制规范: 基本原则是录制脚本要分开、gui文件要合并、批调用回放验证、可移植回放验证。 1.1.1录制脚本要分开: 脚本太大,不仅不利于以后的维护,并且会导致WinRunner的不可预测的错误产生(具体可以参考WinRunner 的Readme文档)。录制时,可以根据测试用例的流程,拆分为几个小流程,对每个小流程分别录制成不同的脚本。 1.1.2gui文件要合并: 首先,要在系统参数中,设置gui的录制模式为“Global GUI Map File”,如下: 
录制过程中,WinRunner会自动产生gui文件,一个测试用例要确保生成一个公用gui文件。用一个gui文件主要是为了以后gui对象的维护,脚本回放时gui对象的查找。但是由于我们的测试用例是分开录制的,每个小流程录制时都会产生一个gui临时文件,因此录制完脚本后要把临时gui文件合并到该测试用例的公用gui文件中。但是也要注意,开始新的录制前,一定要先手工加载测试用例的公用gui文件。 如果划分的子流程超过20个,则按每20个子流程录制一个gui文件的方式。Gui文件太大,会影响WinRunner的回放效率。 1.1.3批调用回放验证: 为了提高脚本的正确性,每录制完成一个子流程后,都要恢复数据库,其他初始环境进行回放,以近早发现脚本错误。 单个测试用例脚本录制完成后,要专门写一个主脚本,进行各子脚本的主次调用处理,然后恢复数据库和其他初始环境进行回放,以验证整个脚本是否可以正确回放。 1.1.4可移植回放验证: 由于WinRunner 工具的限制,在本机回放成功后,如果把脚本移植到其他机器上,往往无法成功。这其中既有自己编写的脚本问题,又有WinRunner录制自动生成的脚本问题。 自己编写脚本问题:往往是编写的可移植性较差,如加载gui文件时用的是绝对地址,如gui_load(“c:\\aa\\aa.gui”),这样的脚本换到其他机器必然出错。 WinRunner录制自动生成的脚本问题: WinRunner的录制脚本往往和机器的环境有关,如果换了其他机器环境,往往回放不成功,这就需要手工修改脚本。 因此,可移植性回放是非常必要的。 1.1.5脚本中使用的ODBC数据源名称统一命名为WR。 1.1.6录入中文数据时统一使用简体。 1.1.7数据表列名称规定 录入数据驱动的脚本时,数据表列名称统一采用英文,使用PB数据窗口中列对象的名称。数据表列名称下的第一行用中文对英文列名称做注释,使用PB数据窗口中列对象的中文标签,这一行不作为有效的录入数据。与数据表相关的循环语句请修改脚本从数据表的第二行开始读取数据。典型的例子是将数据驱动脚本中For循环的第一个表达式改为table_Row = 2。 1.1.8脚本成功回放判定规定 一个子测试录制完成后,一定要及时回放测试,直到测试报告显示测试结果为OK,且子测试明细报告中没有红色的出错提示。如果是回放主测试,回放成功的标准是:主测试的结果报告显示为OK,同时所有子测试的结果报告也为OK,且子测试明细报告中没有红色的出错提示。 1.1.9WinRuner主脚本中关于设置系统日期时间设置的规定,以保证脚本所描述的业务过程按业务逻辑在时间上有序。 因为脚本回放与脚本录制时的系统日期时间不一致,会导致与系统时间关系密切的测试脚本回放时失败。 为了消除时间差导致的回放错误,要求每一个测试用例的主测试在第一个子测试前加上date_set_system_date(年,月,日,时,分,秒)函数,以修改本地机器的日期时间等于这个主测试在接力式验收回放成功执行后的日期时间.这样再次回放时系统的日期时间就和上一次成功回放时的日期时间一致。
1.2测试脚本存放规范: 各子测试脚本必须放到同一目录下,即环境目录下的Script目录下。这样便于批调用时引用。 1.3Gui文件的存放: Gui 文件,必须和测试脚本放到同一目录下,即环境目录下的Script目录下。 1.4WinRunner使用规范: (1)必须写上清楚的注释:编写测试脚本,要进行详细的标注,每测试一小段,就要写一段备注,以便于将来修改,格式可以参考如下: 功能描述:描述脚本的功能 前置条件:该脚本在满足什么条件下才可以被执行 步骤描述:描述脚本录制的动作 检查点描述:描述作了对什么的检查,检查条件。 录入人:录制人 录入时间: 备注: (2)gui文件的加载保存: 每次开始测试用例的录制脚本前,如果该测试用例已经存在gui文件,一定要手工打开gui文件,再开始录制。如果不想手工打开,可以写段自动加载gui的脚本,每次录制前运行一下该脚本。录入脚本后,要注意保存GUI文件,如果测试用例已经存在gui文件,一定要把临时的gui文件合并到该用例的公用gui文件中,然后保存。 (3)如果机器数据较慢,或者网络较慢、或者数据库运行较慢,需要把等待打开窗口的时间设长。或者在脚本中插入同步点来处理。 
(4)WinRunner不支持Fomular One,目前不可以用wr测试Fomular One 使用WinRunner录制时不可以切换不同输入法录制,仅可以用一种输入法。 (5)WinRunner 对shift 键无法纪录,需要特殊处理 ,可以加入如下处理 obj_type "dw_1.fslipbugno","<kShift_L>-");(告诉WinRunner按下Shift键) 中间是选择行的脚本 obj_type ("dw_1.FBugNo","<kShift_L>+");(告诉WinRunner释放Shift键) (6)保证录制的脚本干净性: 在录制过程中,不可避免的要进行其他动作,如打开邮件、打开非录制程序等,这些动作也会被WinRunner录制下来,这些动作会严重影响测试脚本的回放(除非作这些动作前停止录制)。 因此,为了保证脚本的干净,在WinRunner的参数中进行如下设置:设置Recode 的“Selected Applications” 为要录制的程序。

(7)录制脚本时,不允许同时打开两个运行程序(指进行wr测试的程序) (8)变量的声明:WinRunner有auto \public \static \extern 四个类型的变量作用域声明,其中public为默认的类型。由于public 是全局的,只要在一个脚本中声明了,在任何其他脚本都可以引用,这就带来一个问题,如果其他的脚本修改了这个public 变量的值,将会引发问题。因此变量声明时必须明确的加上类型(auto \public \static \extern),public 的一般不要使用,推荐使用static \auto 。 2.异常处理规范: 在录制或者编写测试脚本时,必须进行异常的错误处理。以提高程序的错误检查能力。 2.1函数异常检测: 对于一些常用函数,必须进行函数执行异常的处理。至少进行如下函数的异常检测:et_window、win_activate、menu_select_item、ddt_open。 发现异常后,要终止程序的执行,并发邮件通知相关人员。 2.2返回值规范: 模块、函数的返回值约定如下,0 表示成功 ,其他失败。 对于一些函数的返回值,需要进行判断处理: (1)每一个call语句都应该检查它的返回值是否为0, 如果不为0则报错退出。 所有GUI检查点、数据库检查点都应做返回值检查。如果不为0则报错退出。
|
| 标签:winrunner经验总结 |
作者 zhaoshouzhong 阅读全文 |
评论()
| 人气() |
引用()
| 推荐 | 保存日志
|
2005-11-06 18:52:05  |
| Workflow模式 |
Workflow模式是开发工作流必须了解的知识。 本文档是根据如下资料简单翻译的:
http://is.tm.tue.nl/research/patterns/patterns.htm
Basic Control Flow Patterns(基本模式) 1.Sequence 模式 定义:串行模式:在一个工作流中,一个动作在另外一个动作完成后使能。  举例:单据录入的动作完成后,审核的动作被执行。
2.Parallel Split模式: 定义:并行分支模式(与分支、AND-Split):工作流中的一个节点,在该节点,一个单一的线程被分成多个线程,这些线程可以被并行执行,因此,分支的动作可以被同时执行或者以某种顺序执行。

举例:客户付款后,送货和通知客户的动作可以并行执行 3.Synchronization模式: 定义:同步模式,(与汇合、AND-Join):在工作流中的一个点,在该点处,所有并行的子流程或者活动,汇合成一个单一的线程。因此必须所有子流程(活动)执行完成后,才可以执行下一个活动。 前提条件:所有的子流程(活动)仅能被执行一次,不可以重复执行

举例: 4.Exclusive Choice 模式: 定义:唯一选择模式(XOR-split):在工作流的一个点,根据选择条件或者工作流控制数据,在多个分支中选择一个分支执行。

5.Simple Merge 模式 定义:简单合并模式(XOR-join):在工作流的一个节点,一个或者多个可选分支非同步到达。只要一个动作完成,就会触发后续动作。 前提条件:这些分支中不存在并行执行的情况。

Advanced Branching and Synchronization Patterns (高级分支、同步模式) 6.Muti-Choice模式: 定义:多选择模式(或分支 OR-split):在工作流中的一个节点,根据条件或者相关控制数据,多个分支被选择。Exclusive Choice 模式仅能选择一个分支 备注:由于某些工作流不支持该模式,因此,可以通过AND-split 模式,XOR-split模式组合来表达。
 举例:A活动执行完后,根据条件,B活动,C活动被选择执行。
7.Synchronizing Merge模式: 定义:同步合并模式:在工作流中的一个节点,多个被选的分支汇合成一个单一的线程。如果有多于一个的分支被执行,工作流会等待所有的分支执行完成后,才开始下一个动作的执行。
前提条件:在该节点的下一个动作执行前,被选的分支动作仅能被执行一次。

举例:加入A、 B 被选择执行,只有当A 、B都执行完毕后,动作D才可以被执行。
8.Multi Merge 模式: 定义:重复组合模式:在工作流的一个节点,多个被选分支非同步的聚合。每一个分支完成后,后续的动作都会被执行一次。

举例:如果A、B被 选择执行,A执行完毕后,D会被跟着执行;B执行完毕后,D也会再执行一次。
9.Discriminator 模式: 鉴别器模式(M-OUT-of-N模式 ):在工作流中的一个节点,在等待N个分支的执行的过程中,只要其中的M个分支完成,它就会触发随后的动作,并忽略其他的分支。

举例:只要B\C\D 三个活动中,有两个活动完成,就会触发E动作。另外一个动作将会被忽略。
Structural Patterns(结构化模式) 10.Arbitrary Cycles模式: 定义:任意循环模式:在工作流的一个节点,一个或者多个活动可以被重复执行。

11.Implicit Termination 模式: 定义:隐式终止模式:在没有其他活动可以执行时,一个子流程应该被终止。当然,前提是不存在死锁的情况。
Patterns involving Multiple Instances (多实例模式) 12.Multiple Instances Without Synchronization 模式: 定义:非同步多实例模式:在一个工作流实例的环境中,一个动作的多个实例可以被创建。也就是说在控制线程外,产生新的线程。这些线程相互独立,不需要同步。
举例:在客户订书的流程中,客户可以对不同的书下单,因此订书的动作存在多个实例,订A书的实例,订B书的实例等等。
13.Multiple Instances With a Priori Design Time Knowledge 定义:拥有优先设计知识的多实例模式:在一个流程实例中,一个活动被实例化的次数在设计时是可知的。一旦所有已知的实例完成,其他的活动需要被执行。
举例:某个订单,需要三次不同的审核。
14.Multiple Instances With a Priori Runtime Knowledge模式: 定义:拥有优先运行知识的多实例模式:在一个流程实例中,一个活动被实例的话次数在设计时是不可知的,它依赖于流程特性或者资源可用性,仅在流程实例运行时的某个阶段可知。
举例:在一个评审团对科学论文的评审流程中,评审的动作依赖于论文的内容,评审团人员的数量,评审团的信誉。
15.Multiple Instances Without a Priori Runtime Knowledge模式: 定义:无运行知识的多实例模式:在一个流程实例中,一个活动被实例的话次数在设计时是不可知的,在流程运行的过程中也是不可知的。
举例:在100台计算机的运输流程中,每次运输的计算机的个数是不可知的,因此整个的运输次数也是不可知的。
State-based Patterns (基于状态的模式) 16.Deferred Choise 模式: 定义:延期选择模式:在工作流的一个节点,在多个可选分支中,只有一个分支选中。不同于XOR-split模式(选择是显式的,根据条件判断,立即决定分支的选择),可选分支是由环境决定的。不同于AND-split模式,只有一个分支被选择。也就是说一旦环境激活其中的一个分支,其他的分支讲被丢掉。很重要的一点是:直到可选分支中的一条被激活,“选择”才进行,因此选择的时刻被尽可能的延期。
17.Interleaved Parallel Pattern模式: 定义:交叉并行模式:一组动作以任意的顺序执行。动作执行的顺序,在工作流实例运行时刻决定,不存在两个动作同时运行的情况。
举例:在体检的中,血液检查、视力检查是两个不同的动作,这两个动作的先后顺序可以是随机的,但是一个时刻只可以执行一个动作,不会同时进行。
18.Milestone模式: 定义:里程碑模式:工作流实例的一个动作依赖于某个特定状态,也就是说当某个里程碑到达后,该动作才可以被执行。
举例:在工厂发货前的头两天,客户可以取消订单。
19.Cancel Activity 模式: 定义:活动取消模式:一个使能的活动被设为不可用,即等待一个活动执行的线程被移除。
举例:一个设计通常由两组工程师检查,为了赶进度,其中一组的检查可能被取消
20.Cancel Case模式: 定义:取消案例模式:一个工作流的实例被彻底的移除,也就是说无论是否该实例有动作已经实例化。
举例:在最终法院判决前,起诉人可以撤销上诉。
|
| 标签:Workflow模式 |
作者 zhaoshouzhong 阅读全文 |
评论()
| 人气() |
引用()
| 推荐 | 保存日志
|
2005-11-04 20:23:40  |
|