2008年12月29日星期一

SVN常用分支模式

发布分支

这是版本控制可以做的帮助,典型的过程如下:

开发者提交所有的新特性到主干。 每日的修改提交到/trunk:新特性,bug修正和其他。

这个主干被拷贝到“发布”分支。 当小组认为软件已经做好发布的准备(如,版本1.0)然后/trunk会被拷贝到/branches/1.0。

项目组继续并行工作,一个小组开始对分支进行严酷的测试,同时另一个小组在/trunk继续新的工作(如,准备2.0),如果一个bug在任何一个位置被发现,错误修正需要来回运送。然而这个过程有时候也会结束,例如分支已经为发布前的最终测试“停滞”了。

分支已经作了标签并且发布,当测试结束,/branches/1.0作为引用快照已经拷贝到/tags/1.0.0,这个标签被打包发布给客户。

分支多次维护。当继续在/trunk上为版本2.0工作,bug修正继续从/trunk运送到/branches/1.0,如果积累了足够的bug修正,管理部门决定发布1.0.1版本:拷贝/branches/1.0到/tags/1.0.1,标签被打包发布。

整个过程随着软件的成熟不断重复:当2.0完成,一个新的2.0分支被创建,测试、打标签和最终发布,经过许多年,版本库结束了许多版本发布,进入了“维护”模式,许多标签代表了最终的发布版本。

特性分支

最终,有一个问题就是怎样保持一个特性分支“同步”于工作中的主干,在前面提到过,在一个分支上工作数周或几个月是很有风险的,主干的修改也许会持续涌入,因为这一点,两条线的开发会区别巨大,合并分支回到主干会成为一个噩梦。

可以用另一种考虑这种模式,每周按时同步分支到主干,类似于在工作拷贝执行svn update的命令,最终的合并操作类似于在工作拷贝运行svn commit,毕竟,工作拷贝不就是一个非常浅的分支吗?只是它一次只可以保存一个修改。

2008年12月23日星期二

#Pragma

在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
其格式一般为: #pragma para
其中para为参数,下面来看一些常用的参数。

(1)message 参数
message参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,
这对于源代码信息的控制是非常重要的。其使用方法为:
#pragma message("消息文本")
当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。
当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏,可以用下面的方法:
#ifdef _X86
#pragma message("_X86 macro activated!")
#endif
我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示"_X86 macro activated!"。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。

(2)另一个使用得比较多的pragma参数是code_seg
格式如:
#pragma code_seg( ["section-name" [, "section-class"] ] )
它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。

(3)#pragma once (比较常用)
只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,
但是考虑到兼容性并没有太多的使用它。

(4)#pragma hdrstop
表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,
但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级,如果使用了#pragma package(smart_init),BCB就会根据优先级的大小先后编译。

(5)#pragma resource "*.dfm"
表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。

(6)#pragma warning( disable: 4507 34; once: 4385; error: 164 )
等价于:
#pragma warning( disable: 4507 34 ) // 不显示4507和34号警告信息
#pragma warning( once: 4385 ) // 4385号警告信息仅报告一次
#pragma warning( error: 164 ) // 把164号警告信息作为一个错误。
同时这个pragma warning 也支持如下格式:
#pragma warning( push [, n ] )
#pragma warning( pop )
这里n代表一个警告等级(1---4)。
#pragma warning( push )保存所有警告信息的现有的警告状态。
#pragma warning( push, n )保存所有警告信息的现有的警告状态,并且把全局警告等级设定为n。
#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消。例如:
#pragma warning( push )
#pragma warning( disable: 4705 )
#pragma warning( disable: 4706 )
#pragma warning( disable: 4707 )
//.......
#pragma warning( pop )
在这段代码的最后,重新保存所有的警告信息(包括4705,4706和4707)。

(7)#pragma comment(...)
该指令将一个注释记录放入一个对象文件或可执行文件中。
常用的lib关键字,可以帮我们连入一个库文件。如:
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "wsock32.lib")

每个编译程序可以用#pragma指令激活或终止该编译程序支持的一些编译功能。
例如,对循环优化功能:
#pragma loop_opt(on) // 激活
#pragma loop_opt(off) // 终止

有时,程序中会有些函数会使编译器发出你熟知而想忽略的警告,
如“Parameter xxx is never used in function xxx”,可以这样:
#pragma warn —100 // Turn off the warning message for warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message for warning #100 back on
函数会产生一条有唯一特征码100的警告信息,如此可暂时终止该警告。

每个编译器对#pragma的实现不同,在一个编译器中有效在别的编译器中几乎无效。可从编译器的文档中查看。

补充 —— #pragma pack 与 内存对齐问题

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。
Win32平台下的微软C编译器(cl.exe for 80x86)在默认情况下采用如下的对齐规则:
任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。

Linux下的GCC奉行的是另外一套规则(在资料中查得,并未验证,如错误请指正):
任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。

ANSI C规定一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。
填充区就是为了使结构体字段满足内存对齐要求而额外分配给结构体的空间。那么结构体本身有什么对齐要求吗?有的,ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松,可以更严格。

如何使用c/c++中的对齐选项
vc6中的编译选项有 /Zp[1|2|4|8|16] ,/Zp1表示以1字节边界对齐,相应的,/Zpn表示以n字节边界对齐。n字节边界对齐的意思是说,一个成员的地址必须安排在成员的尺寸的整数倍地址上或者是n的整数倍地址上,取它们中的最小值。也就是:
min ( sizeof ( member ), n)

实际上,1字节边界对齐也就表示了结构成员之间没有空洞。
/Zpn选项是应用于整个工程的,影响所有的参与编译的结构。
要使用这个选项,可以在vc6中打开工程属性页,c/c++页,选择Code Generation分类,在Struct member alignment可以选择。

要专门针对某些结构定义使用对齐选项,可以使用#pragma pack编译指令:
(1) #pragma pack( [ n ] )
该指令指定结构和联合成员的紧凑对齐。而一个完整的转换单元的结构和联合的紧凑对齐由/Zp 选项设置。紧凑对齐用pack编译指示在数据说明层设置。该编译指示在其出现后的第一个结构或联合说明处生效。
该编译指示对定义无效。
当你使用#pragma pack ( n ) 时, 这里n 为1、2、4、8 或16。
第一个结构成员之后的每个结构成员都被存储在更小的成员类型或n 字节界限内。
如果你使用无参量的#pragma pack, 结构成员被紧凑为以/Zp 指定的值。该缺省/Zp 紧凑值为/Zp8 。

(2) 编译器也支持以下增强型语法:
#pragma pack( [ [ { push | pop } , ] [ identifier, ] ] [ n] )

若不同的组件使用pack编译指示指定不同的紧凑对齐, 这个语法允许你把程序组件组合为一个单独的转换单元。带push参量的pack编译指示的每次出现将当前的紧凑对齐存储到一个内部编译器堆栈中。
编译指示的参量表从左到右读取。如果你使用push, 则当前紧凑值被存储起来;
如果你给出一个n 的值, 该值将成为新的紧凑值。若你指定一个标识符, 即你选定一个名称, 则该标识符将和这个新的的紧凑值联系起来。

带一个pop参量的pack编译指示的每次出现都会检索内部编译器堆栈顶的值,并且使该值为新的紧凑对齐值。如果你使用pop参量且内部编译器堆栈是空的,则紧凑值为命令行给定的值, 并且将产生一个警告信息。
若你使用pop且指定一个n的值, 该值将成为新的紧凑值。若你使用p o p 且指定一个标识符, 所有存储在堆栈中的值将从栈中删除, 直到找到一个匹配的标识符, 这个与标识符相关的紧凑值也从栈中移出, 并且这个仅在标识符入栈之前存在的紧凑值成为新的紧凑值。如果未找到匹配的标识符,
将使用命令行设置的紧凑值, 并且将产生一个一级警告。缺省紧凑对齐为8 。

pack编译指示的新的增强功能让你编写头文件, 确保在遇到该头文件的前后的紧凑值是一样的。

(3) 栈内存对齐

在vc6中栈的对齐方式不受结构成员对齐选项的影响。它总是保持对齐,而且对齐在4字节边界上。

2008年12月18日星期四

在VC2003中编译x264

1、到 http://www.videolan.org/developers/x264.html
下载 x264 源代码,可以从代码库中取:
# git clone git://git.videolan.org/x264.git
或者下载一个 daily snaptshot,这是每天凌晨生成的一个tar.gz文件,例如:
ftp://ftp.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20081217-2245.tar.bz2

2、用VC2003打开 x264\build\win32\x264.sln 文件,会显示有2个工程:
libx264
x264

3、编译会显示找不到 yasm,显然 x264工程用了一个开源的汇编编译器 yasm,其网址是:
http://www.tortall.net/projects/yasm/下载win32版本:
http://www.tortall.net/projects/yasm/releases/yasm-0.7.2-win32.exe将其改名为 yasm.exe 并放到 PATH 路径中,例如 C:\tools

4、再次编译,会报2个错,一个出在 #define ERROR(...),这是因为 VC2003 不支持可变参数的宏函数,得 VC2005 以上才支持,所以这里需要修改为:
#if defined(_MSC_VER) && _MSC_VER < 1400 // Support for variadic macros was introduced in Visual C++ 2005.
#define ERROR { ret = 1; }
#else
#define ERROR(...)\
{\
if( verbose )\
x264_log( h, X264_LOG_WARNING, __VA_ARGS__ );\
ret = 1;\
}
#endif

另一个错在编译不会有问题,但是link的时候可能会报错,说 _fseeki64 和 _ftelli64 找不到,这两个函数支持 64bit 文件访问,但是在 VC2005 以后才支持,所以需要在 osdep.h 中进行修改为:
#if _MSC_VER >= 1400 // _fseeki64 and _ftelli64 introduced in VC2005 and above
#define fseek _fseeki64
#define ftell _ftelli64
#endif

然后再进行编译就可以了,编译完成之后,在 x264\bin\ 下面生成2个文件:
libx264.lib
x264.exe

2008年12月16日星期二

项目管理专家(PMP)认证的条件与方法

  项目管理是指把各种系统、资源和人员有效地结合在一起,采用规范化的管理流程,在规定的时间、预算和质量目标范围内完成项目。项目管理广泛应用于建筑、工程、电子、通讯、计算机、金融、制造、咨询、国防以及政府机关等行业。

1. 认证程序
  PMI认证程序提供国际一流水平的项目管理产品和服务,以保证项目管理专家证书在全球范围内(包括公共和私有部门)的可靠信誉。

2.项目管理协会认证概述
  项目管理认证程序是由项目管理协会PMI发起的,其目的是使严格的、基于考试基础上的最高品质的专业认证程序得到开发、保持、评价、提高和管理。 项目管理专家(PMP)认证程序支持项目管理专家国际团体,客观评估和测试专业知识水平。PMP程序的要求和合格的标准是公平的、公正的,并与适用法律是一致的。无论考生是否属于任何组织、协会或团体,PMP程序遵守美国各州和联邦政府的反歧视法并独立授予证书。 申请者必须达到PMI规定的所有教育和经历要求,并对项目管理专家认证考试测试的关于对项目管理的理解和知识达到认可及合格程度才能获得PMP证书。另外,为满足行业发展计划的需要,PMP证书获得者必须继续致力于项目管理领域。

3.申请资格
  PMP认证申请者必须满足以下类别之一规定的教育背景和专业经历:
  第一类: 申请者需具有学士学位或同等的大学学历,并且须至少具有4500小时的项目管理经历。PMI要求申请者需 至少3年以上,具有4500小时的项目管理经历。仅在申请日之前6年之内的经历有效。需要提交的文件一份详细描述工作经历和教育背景的最新简历(请提供所有雇主和学校的名称及详细地址);一份学士学位或同等大学学历证书或副本的拷贝件;能说明至少3年以上,4500小时的经历审查表。
  第二类: 申请者虽不具备学士学位或同等大学学历,但持有中学文凭或同等中学学历证书,并且至少具有7500小时的项目管理经历。PMI要求申请者需至少5年以上,具有7500小时的项目管理经历。仅在申请日之前8年之内的经历有效。
  所需支持文件:一份详细描述工作经历和教育背景的最新简历(请提供所有雇主和学校的名称及详细地址);能说明至少5年以上,7500小时的经历审查表。

4.申请程序
  PMP认证考试申请资料包括四项内容。申请者需将经历审查表、一份最新的个人简历(应详细说明工作经历和教育背景)、一份毕业证书或副本(如需要的话)拷贝和考试申请表随相应的费用提交PMI认证部。所有申请资料和文件应用英文书写并且属实。

5.经历审查内容
  项目管理经历审查表是PMP认证考试资料的一部分,供申请者以书面资料全面报告其项目管理经历。申请者必须完成并签名一份合格的项目管理经历审查表,随PMP认证考试申请表一起提交。经历审查表不全的申请将被退回。 在有效时间范围内,每个项目都要提交一份经历审查表。
  每份中以下内容必须填写:
  申请者全名
  列出项目管理经历的雇主名称和详细地址
  雇主的电话和传真号码
  项目开始和完成日期(在申请时若项目未完成,用申请日期代替完成日期)
  在项目管理五个过程中的大约工时数(对任何五个过程无最低要求)
  申请者签名和日期
  
6.项目管理五个过程
  立项:确立一个项目或一个项目阶段。
  计划:为完成项目,制定和维护一个可操作的计划。
  执行:协调人力和其他资源以执行计划 。
  控制:通过监控和进度测量及必要时采取纠正措施以确保项目目标的实现。
  收尾:正式验收项目或项目阶段并使其有条不紊地圆满结束。
  *源于项目管理知识体系(The PMBOK Guide)

7.个人简历
  申请者必须提交一份最新的个人简历,须详细说明经历审查表中的工作经历。在个人简历中要 简要陈述所有项目管理工作经历。应试者须提供所有就学学校(包括中学)的名称及详细地址。

8.PMP认证考试申请表内容说明 应试者必须完成本手册中的PMP证书考试申请表,用印刷体清楚地填写以下内容(须大写的部分请大写):
  申请表第I页:
  社会保险号码和母亲的婚前姓(仅用于身份鉴别)
  PMI身份或会员号(无此号码者将被分配一个号码)
  全名,雇主信息,包括公司名称、工作职位、详细地址及电话号码 详细家庭邮寄地址和电话号码 第一电子邮件地址和传真号,注明希望的邮寄地址和电话号码 阅知了PMP认证与应试者的协议 所有会员资格和证书资料将被寄往注明的希望邮寄地址。
  申请表第II页:
  信息来源 会员状况 课程培训情况和PMI分会代码 职业代码和行业代码 最高学历,授予年月和学习领域 经历审查表中的项目管理经历合计(小时) 付款金额和付款方式(一旦支付,非会员费用不再变更,不管以后是否加入PMI) 阅知考试取消和退款条例 完成的申请资料连同认证申请费须一起递交. 传真复印件无效。请勿将您的PMI 会员申请资料和会员费同PMP认证考试申请资料放入同一信封。
  
9.申请资料审查
  PMP认证部按一定比例抽查审核申请资料。提交给PMI证书部的任何虚假和错误信息将受到惩罚,包括中止或撤消考试资格或(和)证书。
  
10.申请合格通知
  在收到PMP认证考试申请资料10到14个工作日之内,将寄给合格的申请者一封PMP认证考试资格信。此信确认申请者考试资格,3个月内有效。

11.延期
  在3个月资格有效期内不能参加PMP认证考试的应试者可申请一次性延期。应试者须提前一个月提交一份书面延期申请报告,包括延期理由。

2008年12月10日星期三

用jni实现java使用dll

使用jni调C++功能,也要之前用java声明出预调用的函数,然后用javah和生成的class文件生成一个.h文件,做的是针对这个.h文件,实现.cpp。

1:写一个Java类,在这个类中包含了需要调用的本地方法的描述。
public class Main {
static{
System.loadLibrary("TestDLL");
}

public native int get();

public static void main(String[] args) {
Main m = new Main();
System.out.println(m.get);
}
}

2:编译,然后命令行下使用命令javah -jni (-classpath . )Main,此时会在当前目录下产生一个Main.h文件
3:使用VC来编写本地方法的实现函数,最后编译成.dll文件。过程如下:
1) 选择new->projects(选择Win32 Dynamic-Link Library)->OK->An ampty DLL project->Finish。
2) 选择Tools->Options->Directories(添加目录..\J2SDK\INCLUDE和..\J2SDK\INCLUDE\WIN32)。
3) 将Main.h添加到工程。
4) 添加源文件Main.cpp,内容如下:
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_get(JNIEnv *, jobject)
{
return 1;
}

5) 编译生成TestDLL.dll文件。并将这个.dll文件拷贝到java工程的目录中。
4:运行java工程就可以了。

问题:dll中如果使用了dynamic_cast,就必须把工程的rtti打开,而且dll编译为debug版本,因为rtti要记录每个类的一些信息。否则不能使用这个dll。

注意: 整个过程要保证jdk的版本统一,如vc环境下和javah部分。

Tomcat 6.0快速配置

第一步:下载j2sdk和tomcat:到sun官方站点
最新的jdk为1.6.04,tomcat为6.0,建议jdk1.4以上,tomcat4.0以上

第二步:安装和配置你的j2sdk和tomcat:执行j2sdk和tomcat的安装程序,然后设置按照路径进行安装即可。
1.安装j2sdk以后,需要配置一下环境变量,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的j2sdk安装在c:\j2sdk1.4.2):
JAVA_HOME=c:\j2sdk1.4.2
classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;(.;一定不能少,因为它代表当前路径)
path=%JAVA_HOME%\bin

接着可以写一个简单的java程序来测试J2SDK是否已安装成功:
public class Test{
public static void main(String args[]){
System.out.println("This is a test program.");
}
}

将上面的这段程序保存为文件名为Test.java的文件。
然后打开命令提示符窗口,cd到你的Test.java所在目录,然后键入下面的命令
javac Test.java
java Test
此时如果看到打印出来This is a test program.的话说明安装成功了,如果没有打印出这句话,你需要仔细检查一下你的配置情况。

2.安装Tomcat后,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的tomcat安装在c:\tomcat):
CATALINA_HOME:c:\tomcat
CATALINA_BASE:c:\tomcat
TOMCAT_HOME: C:\Tomcat
然后修改环境变量中的classpath,把tomat安装目录下的common\lib下的servlet.jar追加到classpath中去,修改后的classpath如下:
classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\common\lib\servlet-api.jar;
接着可以启动tomcat,在IE中访问http://localhost:8080,如果看到tomcat的欢迎页面的话说明安装成功了。

第三步:建立自己的jsp app目录
1.到Tomcat的安装目录的webapps目录,可以看到ROOT,examples, tomcat-docs之类Tomcat自带的的目录;
2.在webapps目录下新建一个目录,起名叫myapp;
3.myapp下新建一个目录WEB-INF,注意,目录名称是区分大小写的;
4.WEB-INF下新建一个文件web.xml,内容如下:
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<display-name>My Web Application</display-name>
<description>
A application for test.
</description>
</web-app>

5.在myapp下新建一个测试的jsp页面,文件名为index.jsp,文件内容如下:
<html>
<body>
<center>
Now time is: <%=new java.util.Date()%>
</center>
</body>
</html>

6.重启Tomcat
7.打开浏览器,输入http://localhost:8080/myapp/index.jsp 看到当前时间的话说明就成功了。

第四步:建立自己的Servlet:
写入你的第一个Servlet:
在你新建的Application myapp/WEB-INF/classes/test目录下新建HelloWorld.java
package test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet
{
public void doGet(HttpServletRequest request,HttpServletResponse response)th
rows ServletException,IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head><title>");
out.println("This is my first Servlet");
out.println("</title></head><body>");
out.println("<h1>Hello,World!</h1>");
out.println("</body></html>");

}
}

然后照样用javac HelloWorld.java来编译这个文件,如果出现无法import javax.servl
et.*
那么就是应该把C:\Tomcat\common\lib里面的servlet-api.jar文件拷贝到C:\JDK\jre\lib\ext中,再次编译,就没有问题了!
然后在Tomcat目录里面的C:\Tomcat\webapps\myapp里面按如下的文件结构:
myapp\index.jsp
myapp\WEB-INF\classes\test\HelloWorld.class(把上面生成的HelloWorld.class文件放在这个
里面)
然后在浏览器中输入http://localhost:8080/myapp/HelloWorld,于是Server众望所归的报错了:Error 404--Not Found
怎么回事呢?
Servlet必须使用C:\Tomcat\webapps\myapp\WEB-INF这个目录下面的web.xml文件进行注册,
用EditPlus打开这个web.xml文件,
在<web-app></web-app>添加下面这段程序:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>test.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>

为什么呢?
因为 这样的结构
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>test.HelloWorld</servlet-class>//类的路径
</servlet>
表示指定包含的servlet类.
而以下的结构
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
表示指定HelloServlet应当映射到哪一种URL模式。

在修改web.xml完毕过后,重新启动Server,然后再输入http://localhost:8080/myapp/HelloWorld,,那么偌大一个Hello,World!等
着你呢,恭喜你!

第五步:建立自己java Bean

1. 在你新建的Application myapp/WEB-INF/classes/test目录下新建TestBean.java
package test;
public class TestBean
{
private String name =null;
public TestBean(String nameInit){
this.name = nameInit;
}
public void setName(String newName){
this.name=newName;
}
public String getName(){
return this.name;
}
}

然后照样用javac TestBean.java来编译这个文件。

2.然后在你新建的应用程序目录myapp下新建一个新的jsp文件:testBean.jsp
<%@ page import="test.TestBean" %>
<html>
<head>
<title>Test Bean</title>
</head>
<body>
<center>
<%
TestBean testBean = new TestBean("Http://yexin218.cublog.cn");
%>
Java Bean Test:
The author's blog address is<%=testBean.getName()%>
</center>
</body>
</html>

好了,确定各个文件的位置:
myapp\index.jsp
myapp\testBean.jsp
myapp\WEB-INF\web.xml
myapp\WEB-INF\classes\test\HelloWorld.class
myapp\WEB-INF\classes\test\TestBean.class

3.重启Tomcat如果需要的话,在浏览器输入:http://localhost:8080/myapp/testBean.jsp 幸运的话就会看到:

Java Bean Test: The author's blog address isHttp://yexin218.cublog.cn

这样就完成了整个Tomcat下的jsp、servlet和javabean的配置。

第六步:配置虚拟目录

打开 Tomcat6.0\conf\server.xml 文件,在 <Host> 和 </Host> 之间加入
<Context path="/myapp" docBase="D:\myapp" debug="0" reloadable="true" crossContext="true" />

2008年11月26日星期三

在JSP中访问数据库示例

将jdbc的驱动程序放到服务器的类路径里,然后要在数据库里建一个表test,有两个字段比如为test1,test2,可以用下面SQL建 create table test(test1 varchar(20),test2 varchar(20),然后向这个表写入一条测试纪录,那么现在开始我们的jsp和数据库之旅吧。

  一、jsp连接Oracle8/8i/9i数据库(用thin模式)

testoracle.jsp如下:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.sql.*"%>
<html>
<body>
<%Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:orcl";
//orcl为你的数据库的SID
String user="scott";
String password="tiger";
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from test";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()) {%>
您的第一个字段内容为:<%=rs.getString(1)%>
您的第二个字段内容为:<%=rs.getString(2)%>
<%}%>
<%out.print("数据库操作成功,恭喜你");%>
<%rs.close();
stmt.close();
conn.close();
%>
</body>
</html>

  二、jsp连接Sql Server7.0/2000数据库


testsqlserver.jsp如下:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.sql.*"%>
<html>
<body>
<%Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs";
//pubs为你的数据库的
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from test";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()) {%>
您的第一个字段内容为:<%=rs.getString(1)%>
您的第二个字段内容为:<%=rs.getString(2)%>
<%}%>
<%out.print("数据库操作成功,恭喜你");%>
<%rs.close();
stmt.close();
conn.close();
%>
</body>
</html>

  三、jsp连接DB2数据库


testdb2.jsp如下:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.sql.*"%>
<html>
<body>
<%Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
String url="jdbc:db2://localhost:5000/sample";
//sample为你的数据库名
String user="admin";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String sql="select * from test";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()) {%>
您的第一个字段内容为:<%=rs.getString(1)%>
您的第二个字段内容为:<%=rs.getString(2)%>
<%}%>
<%out.print("数据库操作成功,恭喜你");%>
<%rs.close();
stmt.close();
conn.close();
%>
</body>
</html>

  四、jsp连接Informix数据库


testinformix.jsp如下:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.sql.*"%>
<html>
<body>
<%Class.forName("com.informix.jdbc.IfxDriver").newInstance();
String url =
"jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver;
user=testuser;password=testpassword";
//testDB为你的数据库名
Connection conn= DriverManager.getConnection(url);
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from test";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()) {%>
您的第一个字段内容为:<%=rs.getString(1)%>
您的第二个字段内容为:<%=rs.getString(2)%>
<%}%>
<%out.print("数据库操作成功,恭喜你");%>
<%rs.close();
stmt.close();
conn.close();
%>
</body>
</html>

  五、jsp连接Access数据库


<%@page import="java.sql.*"
import ="java.util.*"
import ="java.io.*"
import="java.text.*"
contentType="text/html; charset=gb2312"
buffer="20kb"
%><%! int all,i,m_count;
String odbcQuery;
Connection odbcconn;
Statement odbcstmt;
ResultSet odbcrs;
String username,title,content,work,email,url,time,date;
String datetime;
%>
<%
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}catch (ClassNotFoundException e)
{ out.print ("驱动程序不存在");
}
try{
odbcconn = DriverManager.getConnection("jdbc:odbc:db1");
odbcstmt = odbcconn.createStatement();
odbcQuery="Select * From book where datetime>2001-4-26 Order By datetime DESC";
odbcrs=odbcstmt.executeQuery(odbcQuery);
int i=0;
while (i<130) odbcrs.next();
while (odbcrs.next())
{
//*/////////////////////////显示数据库的内容用于调试程序是用//
int ii;
try{
try{
for (ii=1;;ii++)
out.print ("<br>Cloumn "+ii+" is: "+odbcrs.getString(ii));
}catch (NullPointerException e) {
out.print ("有空的指针");
}
}catch (SQLException e){
}
}
odbcrs.close();
odbcstmt.close();
odbcconn.close();
}catch (SQLException e)
{ out.print (e);
}
%>

2008年11月18日星期二

Senior technical lead

Job ID: SWG-0186873
Job type: Full-time Regular
Work country: China
Posted: 10-Sep-2008
Work city: Shanghai
Job area: Software Development
Travel: up to 10%; travelling 1 day a week
Job category: Software Development & Support
Business unit: WPLC
Job role: Technical Support Professional
Job role skillset: General
Job description BU Description:IBM Workplace Portal and Collaboration (WPLC - Lotus)

BU is responsible for developing IBM's collaborative technology and solutions which integrate people, data and business processes to create the "human side" of IBM's On Demand and SOA strategies. We are inviting talents to share our enjoyment of developing Lotus Mashups, one of components of IBM Mashup Center. IBM Mashup Center, as the first integrated enterprise Web 2.0 mashup software platform in the industry, is a complete end-to-end mashup platform, supporting line-of-business assembly of simple, flexible, and dynamic Web applications, with the management, security, and governance capabilities that IT requires. Within this project, developers/testers will have opportunity to develop deep skills and knowledge in J2EE, Web2.0, and will work closely with worldwide senior technical people.

Developer lead:
• Lead the communication and collaboration with worldwide labs, and facilitate conference call with US teams.
• Analyze requirements, design and implementation of new features.
• Develop full owned code for product new release
• Work across organization boundaries to achieve objectives.
• Work as a technical leader to either lead a team to complete the software development project tasks..
• Passionate to software development. An independent, assertive, self-motivated, creative, dynamic, and flexible approach is required, whilst offering and open to new ideas.

Tech Skills:
• Rich programming skills in Java, J2EE, and AJAX
http://en.wikipedia.org/wiki/Ajax_(programming)
http://en.wikipedia.org/wiki/J2ee
• Familiar with software development and software development process
• Solid Knowledge or rich experiences in following fields is a strong plus:
• Web Application Development -- HTML/CSS/JavaScript/JSP
• Hands-on experience on AJAX framework/toolkits such as Dojo, jQuery, YUI, prototype, etc.
http://en.wikipedia.org/wiki/List_of_Ajax_frameworks
• OGSI, eclipse equinox

• WebSphere Application Server public Java API and programming extensions
• iBatis/Hibernate. IBM DB2, Oracle, Microsoft SQL Server
http://ibatis.apache.org/
http://en.wikipedia.org/wiki/Hibernate_(Java)

Soft Skills
• Strong English communication in writing, listening and speaking
• Strong technique leadership and assertive thinking
• Strong communication and team work skills
• Self-motivated
• Strong analytical and troubleshooting skills
• Quick learner and good flexibility
• Having strong sense of ownership and high accountabilityMaster degree or above in Computer Science & Technology or equivalent,

Required
Master's Degree
English: Fluent
Chinese simplified: Fluent

IBM is committed to creating a diverse environment and is proud to be an equal opportunity employer. All qualified applicants will receive consideration for employment without regard to race, color, religion, gender, gender identity or expression, sexual orientation, national origin, genetics, disability, age, or veteran status.

2008年11月14日星期五

视频终端的参数设置

1、基本参数
视频设备,尺寸,帧率,画质
麦克风设备,音量
扬声器设备,音量
带宽

2、H.323
GK地址,用户名,密码,E164

3、SIP
sip server,sip名

4、VMEET
server,ID,password

2008年11月11日星期二

使用OpenSSL制作PKI数字证书

十年前就使用过OpenSSL了,这个加密工具和算法包非常强大和丰富。不过至今仍不能清楚记得命令行的具体参数,需要用的时候总免不了要翻翻手册,这里做一个简单的笔记。

1.首先要生成服务器端的私钥(key文件):
openssl genrsa -des3 -out server.key 1024
运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密算法,当然也可以选用其他你认为安全的算法.),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令.如果觉得不方便,也可以去除这个口令,但一定要采取其他的保护措施!
去除key文件口令的命令:
openssl rsa -in server.key -out server.key

2.openssl req -new -key server.key -out server.csr -config openssl.cnf
生成Certificate Signing Request(CSR),生成的csr文件交给CA签名后形成服务端自己的证书.屏幕上将有提示,依照其指示一步一步输入要求的个人信息即可.

3.对客户端也作同样的命令生成key及csr文件:
openssl genrsa -des3 -out client.key 1024
openssl req -new -key client.key -out client.csr -config openssl.cnf

4.CSR文件必须有CA的签名才可形成证书.可将此文件发送到verisign等地方由它验证,要交一大笔钱,何不自己做CA呢.
openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf

5.用生成的CA的证书为刚才生成的server.csr,client.csr文件签名:
Openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -config openssl.cnf
Openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key -config openssl.cnf

现在我们所需的全部文件便生成了.

另:
client使用的文件有:ca.crt,client.crt,client.key
server使用的文件有:ca.crt,server.crt,server.key

.crt文件和.key可以合到一个文件里面,把2个文件合成了一个.pem文件,直接拷贝过去即可。

IBM技术以及职位相关信息

软件下载资源中心
http://www.ibm.com/developerworks/cn/downloads/index.html

Eclipse开发环境开源项目
http://www.eclipse.org/

IBM职位招聘信息
https://jobs3.netmedia1.com/cp/search.jsp?tc=1199340560188

IBM IT架构师职位要求 链接

2008年10月20日星期一

如何在Vista上安装.NET 1.1

Windows Vista comes packaged with Microsoft .NET Framework 2.0 and 3.0, but not version .NET 1.1, which may still required by some applications such as QuickBooks 7, GFI Report Packs, VS.NET 2003, InstallShield 11.5, and many other developed software.

However, when trying to install Microsoft .NET Framework 1.1 (dotnetfx.exe) on Windows Vista, one or more error messages similar to one of the following text will appear, and stop or prevent setup installation of .NET Framework 1.1 from continuing successfully.

  • RegSvcs.exe - Common Language Runtime Debugging Services
    Application has generated an exception that could not be handled.Process id=0xe50 (3664), Thread id=0xd44 (3396).
    Click OK to terminate the application.Click CANCEL to debug the application.
    If user click “OK’, the installation of .NET 1.1 will be cancelled, while clicking “CANCEL” produces another error message similar to below:
  • RegSvcs.exe - No debugger found
    Registered JIT debugger is not available. An attempt to launch a JIT debugger with the following command resulted in an error code of 0×2 (s). Please check computer settings.
    cardbg.exe !a 9×8e

In Even Viewer of Vista, the following log or similar can be seen:

  • Source: MsiInstallerEvent ID: 1030Description:Product: Microsoft .NET Framework 1.1. The application tried to install a more recent version of the protected Windows file C:\Windows\Microsoft.NET\Framework\sbs_wminet_utils.dll. You may need to update your operating system for this application to work correctly. (Package Version: 1.0.0.0, Operating System Protected Version: 1.0.0.0).
  • Source: MsiInstallerEvent ID: 1030Description:Product: Microsoft .NET Framework 1.1. The application tried to install a more recent version of the protected Windows file C:\Windows\Microsoft.NET\Framework\sbs_system.enterpriseservices.dll. You may need to update your operating system for this application to work correctly. (Package Version: 1.0.0.0, Operating System Protected Version: 1.0.0.0).
The error pops up in the end of .NET Framework 1.1 setup when it’s almost finished, and is registering “System.EnterpriseServices.dll” when the error occurs, time remaining for the installatin process shows 0 seconds.


Why exactly the error occurs when installing Microsoft .NET Framework 1.1 in Windows Vista is not known, as the issue happens randomly. It may affect both 32-bit and 64-bit Vista system, but not all system will have the issue. But one thing is for sure. Microsoft .NET Framework 1.1 SP1 (Service Pack 1) has resolved the issue. However, Microsoft does not provide download to standalone .NET Framework 1.1 installer that integrated with SP1.

Thus, the workaround to fix the Microsoft.NET Framework 1.1. installation error on Vista is to slipstream .NET Framework 1.1 SP1 into .NET Framework 1.1 installer, so that both the .NET Framework and the Service Pack can be installed at the same time.

To slipstream .NET 1.1 SP1 into .NET Framework setup package to have a integrated .NET Framework 1.1 SP1 installer, follow steps in this trick:

1. Create a new folder named DotNet in C:\ drive (C:\DotNet is used in this guide, you can change to any folder you prefer, but ensure that you use correct path in the following steps).
2. Download Microsoft .NET Framework 1.1 Redistributable Package (dotnetfx.exe). Make sure the setup file is saved as dotnetfx.exe.
3. Download Microsoft .NET Framework 1.1 Service Pack 1 (NDP1.1sp1-KB867460-X86.exe). Make sure that the file is renamed and saved as dotnetfxsp1.exe, so that the rest of the steps can be followed easily.
4. Move both installation files into the same directory (i.e. C:\DotNet), if you’re not saving them together.
5. Open command prompt as Administrator.
6. Change to the directory where the two installation setup files for .NET 1.1 are saved (i.e. C:\DotNet).

7. Run the following commands one by one, press Enter after each one.

dotnetfx.exe /c:"msiexec.exe /a netfx.msi TARGETDIR=C:\DotNet"
If you’re not using C:\DotNet directory, change the target to your path accordingly.
Then click on “Yes” when prompted to answer “would you like to install Microsoft .NET Framework 1.1. Package?”
Wait for the uncompression, extraction and setup to complete with the display of the following dialog which says installation complete.

dotnetfxsp1.exe /Xp:C:\DotNet\netfxsp.msp
No status message for this step.

msiexec.exe /a c:\DotNet\netfx.msi /p c:\DotNet\netfxsp.msp
Wait for Windows Installer for Microsoft .NET Framework 1.1 to finish and disappear automatically.

Install Microsoft .Net Framework 1.1 with slipstreamed/integrated Service Pack 1 by running netfx.msi created in the working folder.
netfix.msi

现在用Vista安装了VS2003后出现了一个严重的问题,使用Find In Files功能时, VS2003会停止响应。上网找相关信息,有人已经报告这个问题了。不过MS说不管VS2003了。

后来发现了另外一台VISTA的电脑不存在这个问题,一对比原来是Windows Themes的问题。只要把Windows外观,改成比较难看的标准模式(就像WIN2000那样...)就能把问题解决掉了。

用Microsoft Cluster实现服务器群集

  大网站每天承受上千万的访问量,而服务器却依然能够应付自如;网络空间服务商所提供的大量空间,而却收费低廉,的确这些情况有点让人难以理解,难道天下真的有性能如此之高的服务器单机?其实则不然,支持这些大量访问和无数数据请求的是服务器群集。
  服务器群集是由一组各自独立的服务器连接而成,利用硬件和软件合理分配网络负荷,达到提高整体服务性能的服务器的集合。
  那么如何架设服务器群集呢?其过程并不复杂,利用Windows2000高级服务器版所提供的实用功能,可以轻松地完成群集服务器的架设。

  预备知识
  Windows Cluster
  Windows高级服务器版中提供的负载平衡工具,可以为服务器群集中的服务器合理分配任务,并避免因某一台服务器出现问题而导致的服务失败。
  心跳网线
  用于连接服务器群集中两大服务器间的网线,一般在服务器群集中的服务器都配有两块网卡,其中一块专门用于两台服务器(节点)间的通讯,来检测各自的运行状态,一旦某一节点没有了响应则证明该服务器出现了故障,这种侦测的过程被称作“心跳”。
  磁盘阵列
  由一组硬盘组成的磁盘集合,支持热插拔,一般使用SCSI的连接模式,磁盘阵列大多安装在专用的磁盘阵列柜中。
  PERC 2/DC CARD是用于连接存储外围设备的硬件,它内置了可读写的ROM存储器,可以根据用户的需要进行出厂后的二次设置,PERC 2/DC CARD多使用在服务器群集中,用于连接磁盘阵列。

  方案实施1:服务器基本配置
  接下来开始配置服务器:
  1. 给服务器1和服务器2连接网线,其中在两块Realtek Pci Ethernet 10M网卡间连接心跳网线,将Intel Pro 100+ Network Card连接到集线器或交换机上。
  2. 为服务器1安装Windows2000高级服务器版。
  3. 启动服务器1,分别配置服务器上的两块网卡,其中连接心跳网线的使用内部网内的保留IP地址(如:192.168.0.1),另一块网卡使用服务器对外的IP地址。同时把服务器1设置为域控制器。
  4. 为服务器2安装Windows2000高级服务器版,并将服务器2加入到先前服务器1所设置的域中,同样将服务器2的两块网卡分别设置不同的IP地址,注意两台服务器均需要使用同类型的网卡,并且网卡要配置同类的IP地址(例如均为C类地址)。
  在完成以上步骤后,服务器的软硬件设置就基本上完毕了。但是接下来才是群集服务配置中最关键的步骤——配置Windows Cluster!

  方案实施2:配置Windows Cluster
  配置两台服务器的SCSI磁盘
  启动服务器1,但不启动服务器2。如果在服务器群集中使用了外置磁盘阵列,则需要在Windows2000中根据型号的不同升级PERC 2/DC的驱动程序。在使用了RAID磁盘阵列的情况下,用户还必须根据所使用的PERC 2/DC CARD的情况配置它,其配置过程与BIOS的配置有些类似,主要涉及到系统跳线方式、中断模式等参数,它能够与Windows2000高级服务器版的均衡负载服务协同工作。
  进入管理工具中的计算机管理,选择其中的磁盘管理,在这里会显示当前所有使用的磁盘。一般情况下,在首次使用磁盘管理时会显示签名和升级磁盘向导,该向导主要用于提高访问磁盘的安全性。
  服务器群集中的磁盘在进行读写时磁盘必须处于基本状态,用户可以用右键快捷菜单来更改磁盘的状态。
  接下来配置服务器内置的SCSI磁盘,右键单击第一个磁盘,选择创建磁盘。
  确认主分区被选择,并且已启动使用最大磁盘空间选项,为第一个磁盘分配盘符,一般是倒序排列,即第一个磁盘使用盘符Z。
  确认当前磁盘使用NTFS格式,完成配置向导,第一块磁盘开始格式化,重复以上步骤即可完成对多个SCSI磁盘的配置。按照以上步骤也配置服务器2的全部SCSI磁盘,注意服务器2的SCSI磁盘所使用的盘符应与服务器1的不同。
  关闭服务器2,重新启动服务器1,进入计算机管理中的磁盘管理,可以看到除了刚才配置的磁盘,又多出了一些磁盘,根据它们的顺序,分别使用服务器2的盘符更改它们的驱动器名称和路径。关闭服务器1,启动服务器2,并重复上面的步骤,就可以完成两台服务器的SCSI磁盘共享了。在大多数小型机或服务器中,对于SCSI磁盘都提供了主机断电后的多路电源支持,所以在个别服务器断电后,其所使用的SCSI磁盘仍可以被服务器群集中的其他服务器访问到。

  方案实施3:配置服务器的群集服务
  需要注意,两台服务器都必须配置群集服务,才能保证系统的均衡负载,群集服务可以通过安装完成Windows2000高级服务器版后,第一次启动系统REBOOT时弹出的窗口完成的,在配置服务器群集服务时需要保持两台服务器同时启动。
  1.配置服务器1的群集服务
  在启动服务器时,会弹出安装完成的对话框,用户也可以通过管理工具中的配置服务器的安装来完成打开这个窗口。
  在弹出的窗口中,单击“配置”,窗口中会出现一些有关配置服务器的说明,单击“下一步”即可。
  在选择安装节点名称时,为服务器1选择第一个节点。
  输入本服务器群集的名称,在这里一般使用同域相同的名称,例如输入“POPUNET”。
  为域账户设置用户名和密码,这个域与先前设置的域相类似,但添加了管理服务器群集的功能,为了方便起见,一般使用与域控制器相同的用户名和密码。
  点击“下一步”可以进入共享磁盘窗口,可以看到先前设置过的共享磁盘。
  单击“下一步”,选择群集文件存储的目录,注意这些文件要存储在共享磁盘中,一般选择首磁盘Z。
  单击“下一步”,将INTEL PRO 100+ NETWORK CARD网卡配置为连接外部网络,将Realtek PCI Ethernet 10M网卡配置为连接内部网群集。
  在这一步中要为服务器群集配置一个IP地址,注意这个IP地址就是该群集在互联网上的地址,同时将服务器群集的子网掩码设置为255.255.255.0,单击完成,至此即完成了对服务器1的群集配置。
  2.配置服务器2的群集服务。
  服务器2的群集服务配置与服务器1的配置大体相同,这里主要指出它们的不同之处。
  在选择安装节点名称时,使用第二个或者下一个节点。
  服务器2的群集名称应与服务器一所设置的群集名称相同,否则会出现共享磁盘不能互相访问的情况。
  设置域账户时也要使用与服务器1相同的设置。
  到这里,服务器群集的安装就已经基本完成了,接下来就可以根据服务器在网络中发挥的具体功能,分别配置服务器的其他服务了。注意在服务器群集中的服务器在配置其他诸如:WEB、SMTP、NNTP等服务时必须使用相同的设置,不然的话服务器的工作是非常不稳定的。
  方案校验:服务器群集的测试
  如果要检验该方案实施的可行性,可以用非域控制器的服务器中的“群集管理”功能。
  进入“群集管理”界面可以看到当前群集服务器中的全部服务器,其中处于被访问状态的服务器会显示为一个绿色的“UP”字样,分别点击各个服务器,可以对它们的群集服务属性进行设置。同时用户使用群集内的任意一台服务器都可以浏览所有共享磁盘(如图5),关闭任意一台服务器或多台服务器后,再使用其他计算机访问该服务器群集,仍然可以正常访问。证明方案实施成功!

  注意事项
  1.实现服务器群集至少需要两台计算机,分别作为主、从服务器。
  2. 从服务器的硬盘大小必须能够镜像主服务器上所有必要的分区。Windows2000不支持跨越不同硬盘的分区并镜像,所以不能将一个硬盘上的分区镜像到两个较小容量的硬盘上。
  3.至少需要两块用作专用数据链路的Intel PRO/100B网卡。
  4. 专用数据连线(心跳线)可以用五类或超五类双绞线制作。
  5. 专用数据连线的制作方法是将1和2、3和6反接(网卡之间互联时,连接线均为此接法)。
  6. 最好定期备份数据,以防万一。

  服务器群集工作原理
  实施负载平衡的服务器群集中,处理请求被分布于各服务器。负载平衡群集中的各个不同的服务器分担处理负载,但不共享磁盘阵列或内存等资源。如果其中一个服务器发生故障,处理负载可以被简单地重新分布于群集中幸存的各个节点。

2008年10月13日星期一

经济实用型 HTPC 配置

随着IT技术的进步,人们对娱乐要求已经越来越高,追求的是便捷,追求的是在家里就能享受到高品质的娱乐生活。随着数字家庭理念的逐步深入,高清、无线、多媒体功能等元素都被放入高品质娱乐生活当中。HTPC作为电脑与现代家电结合的典型代表,已经逐渐成为人们实现数字家庭理念的一个重要途径。

今年7月份,自己DIY了一台性价比相当高的HTPC。DIY的目标非常明确,这台HTPC就是放在客厅里连接46吋的三星液晶平板电视,主要用于从网上下载电影和电视剧,以及播放照片等。

主要在主板、机箱、无线键盘的选择上费了点心思。选用了具备H.264高清硬解码能力的AMD主板以及板载ATI显卡,这是AMD收购ATI之后推出的一款相当不错的整合主板。该主板提供了全面丰富的接口,包括VGA,DVI和HDMI,SPDIF光纤接口,USB2.0,IEEE1394和E-SATA等。考虑到大量下载和存储的需要,配置了600GB的大硬盘。只配置了2GB的内存,因为对于普通的多媒体应用来说,这也基本够用了。

外设稍微奢侈了一点,用了罗技的掌上型蓝牙小键盘diNovo Mini,外观非常的小巧漂亮,价格却不菲。

以下是具体的配置,以及当时的淘宝网订购价格。

主机:
CPU:AMD5000+ ¥480
主板:技嘉/GA-MA78GPM-DS2H/板载128M显存 ¥700
硬盘:西部数据/640G/3.5寸/7200转/16M/SATA ¥680
内存:金士顿DDR2 800 2G ¥280
光驱:三星DVD刻录机 ¥230
HTPC电脑机箱(美国NMEDIA原版HTPC100)+读卡器+足瓦300W电源 ¥333
= ¥2703

外设:
罗技diNovo Mini充电式蓝牙键盘 ¥1100
全新微软原装 MCE夜光版遥控器 ¥88

最新报价(徐家汇):
CPU:AMD5000+ 370
主板:技嘉/GA-MA78GPM-DS2H/板载128M显存 635
硬盘:320G/3.5寸/7200转/16M/SATA 375
内存:金士顿DDR2 800 2G 190
光驱:三星DVD刻录机 195
键盘:罗技光电套装 150
 

2008年10月6日星期一

Subversion快速指南

备忘参考。

本文是使用Subversion最快速的说明,在最短的时间里帮助您建立起一套可用的服务器环境,只需略加调整就可以应用到实际项目当中。

本说明分为以下几个部分。为了说明简单,教程是在windows下使用的方式,以方便资源有限的项目使用,对于UNIX环境下,区别并不大。

  • 软件下载
  • 服务器和客户端安装
  • 建立版本库(Repository)
  • 配置用户和权限
  • 运行服务器
  • 初始化导入
  • 基本客户端操作
1,软件下载
下载Subversion服务器程序。
最新Windows版本 : http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91

下载Subversion的Windows客户端TortoiseSVN。
Windows常用客户端TortoiseSVN:http://tortoisesvn.net/downloads

TortoiseSVN是扩展Windows Shell的一套工具,可以看作Windows资源管理器的插件,安装之后Windows就可以识别Subversion的工作目录。

2,服务器和客户端安装

服务器安装,直接运行安装程序 ,根据提示安装即可,这样我们就有了一套服务器可以运行的环境。

安装TortoiseSVN,同样直接运行安装程序,按照提示安装即可,不过最后完成后会提示是否重启,其实重启只是使svn工作拷贝在windows中的特殊样式生效,与所有的实际功能无关,这里为了立刻看到好的效果,还是重新启动机器。

3,建立版本库(Repository)

运行Subversion服务器需要首先要建立一个版本库(Repository),可以看作服务器上存放数据的数据库,在安装了Subversion服务器之后,可以直接运行,如:
svnadmin create E:\svndemo\repository

就会在目录E:\svndemo\repository下创建一个版本库。

我们也可以使用TortoiseSVN图形化的完成这一步:
在目录E:\svndemo\repository下"右键->TortoiseSVN->Create Repository here...“, 然后可以选择版本库模式, 这里使用默认即可, 然后就创建了一系列目录和文件。

4,配置用户和权限

来到E:\svndemo\repository\conf目录,修改svnserve.conf:
# [general]
# password-db = passwd
改为:
[general]
password-db = passwd 然后修改同目录的passwd文件,去掉下面三行的注释:
# [users]
# harry = harryssecret
# sally = sallyssecret
最后变成:
[users]
harry = harryssecret
sally = sallyssecret
前面是用户名,后面是口令。这样在通过svn://或者http://访问时,会要求输入正确的用户名和口令才能允许访问。

5,运行服务器

svn独立服务器:

在任意目录下运行:
svnserve -d -r E:\svndemo\repository 我们的服务器程序就已经启动了。注意不要关闭命令行窗口,关闭窗口也会把svnserve停止。

把windows的console程序变成service并不是很难的事情。有个叫做svnservice.exe的程序,将其放到svnserve.exe的同一目录下,运行 svnservice -install -d -r path/to/repo,即可在windows的service管理器中注册服务。

svnserve运行之后,即可从网络上通过 svn://host/*** 对该服务进行访问。

1.4以上的svn也可以通过sc.exe来创建windows服务记录:

安装服务
sc create subversion_service binpath= "c:\subversion\bin\svnserve.exe --service -r c:\svn_test\repos" displayname= "Subversion Repository" depend= Tcpip

删除服务
sc delete subversion_service

apache svn服务器:

在svn的安装目录下有 mod_*_svn.so 和 README.txt,这是Apache modules以及相关说明,将其复制到apache的modules目录下,并修改 httpd.conf,如下。

3a. Uncomment the following two lines:
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_module modules/mod_dav.so

3b. Add the following two lines to the end of the LoadModule section:
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

3c. Add the following to end of the file.
<Location>
DAV svn
SVNPath your/repository/path
</Location>

重新启动Apache服务进程,即可通过 http://host/svn/*** 对 SVN 进行访问。这对于通过互联网进行远程访问无疑是极其方便的。

注:可能需要重新启动机器,以便 svn 安装程序加入到 system path 中的路径生效,使得 svn 的 dll 对 apache service 进程可见,否则 apache httpd 启动时,可能会报告找不到某些 dll 的错误信息。

另外,在我安装该服务时,用的是 appserv,这是个包含 apache, php, mysql, perl 的快速安装包,其中的 apache 版本是 2.2.8,而 svn 1.5.2 中的 mod_*_svn.so 是在 apache 2.2.9 中编译的。因此存在版本兼容的问题。我从 http://httpd.apache.org/下载了 apache_2.2.9-win32-x86-openssl-0.9.8h-r2.msi,将其中的 bin 和 modules 直接覆盖到 appserv 下的 Apache 目录中,可以直接使用。

6,初始化导入

来到我们想要导入的项目根目录,在这个例子里是E:\svndemo\initproject,目录下有一个readme.txt文件:

右键->TortoiseSVN->Import...
URL of repository输入“svn://localhost/”
ok
完成之后目录没有任何变化,如果没有报错,数据就已经全部导入到了我们刚才定义的版本库中。

需要注意的是,这一步操作可以完全在另一台安装了TortoiseSVN的主机上进行。例如运行svnserve的主机的IP是133.96.121.22,则URL部分输入的内容就是“svn://133.96.121.22/”。

7,基本客户端操作

取出版本库到一个工作拷贝:
来到任意空目录下,在本例中是E:\svndemo\wc1,运行右键->Checkout,在URL of repository中输入svn://localhost/,这样我们就得到了一份工作拷贝。
在工作拷贝中作出修改并提交:
打开readme.txt,作出修改,然后右键->Commit...,这样我们就把修改提交到了版本库,我们可以运行。

察看所作的修改:
readme.txt上右键->TortoiseSVN->Show Log,这样我们就可以看到我们对这个文件所有的提交。在版本1上右键->Compare with working copy,我们可以比较工作拷贝的文件和版本1的区别。

更多的内容可以参考 Subversion 中文站
http://www.subversion.org.cn/?action-viewnews-itemid-1

2008年9月24日星期三

视频YUV格式详解

概述
  YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式采用的颜色空间。其中的Y,U,V几个字母不是英文单词的组合词,Y代表亮度,uv代表色差,u和v是构成彩色的两个分量。在现代彩色电视系统中,通常采用三管彩色摄影机或彩色CCD摄影机进行取像,然后把取得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的YUV色彩空间表示。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有 Y信号分量而没有U、V信号分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的相容问题,使黑白电视机也能接收彩色电视信号。
优点作用
  YUV主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了GB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。
  采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。
  YUV与RGB相互转换的公式如下(RGB取值范围均为0-255):
  Y = 0.299R + 0.587G + 0.114B
  U = -0.147R - 0.289G + 0.436B
  V = 0.615R - 0.515G - 0.100B
  R = Y + 1.14V
  G = Y - 0.39U - 0.58V
  B = Y + 2.03U
  在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。
YUV主要的采样格式
  主要的采样格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。其中YCbCr 4:1:1 比较常用,其含义为:每个点保存一个 8bit 的亮度值(也就是Y值),每 2x2 个点保存一个 Cr 和Cb 值, 图像在肉眼中的感觉不会起太大的变化。所以, 原来用 RGB(R,G,B 都是 8bit unsigned) 模型, 1个点需要 8x3=24 bites(如下图第一个图),(全采样后,YUV仍各占8bit)。按4:1:1采样后,而现在平均仅需要 8+(8/4)+(8/4)=12bites(4个点,8*4(Y)+8(U)+8(V)=48bit), 平均每个点占12bites(如下图第二个图)。这样就把图像的数据压缩了一半。
  上边仅给出了理论上的示例,在实际数据存储中是有可能是不同的,下面给出几种具体的存储形式:
  (1) YUV 4:4:4
  YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。
  下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
  存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3
  (2) YUV 4:2:2
  每个色差信道的抽样率是亮度信道的一半,所以水平方向的色度抽样率只是4:4:4的一半。对非压缩的8比特量化的图像来说,每个由两个水平方向相邻的像素组成的宏像素需要占用4字节内存。
  下面的四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
  存放的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3
  映射出像素点为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]
  (3) YUV 4:1:1
  4:1:1的色度抽样,是在水平方向上对色度进行4:1抽样。对于低端用户和消费类产品这仍然是可以接受的。对非压缩的8比特量化的视频来说,每个由4个水平方向相邻的像素组成的宏像素需要占用6字节内存。
  下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
  存放的码流为: Y0 U0 Y1 Y2 V2 Y3
  映射出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2]
  (4)YUV4:2:0
  4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0...以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是2:1,所以可以说色度的抽样率是4:1。对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存。
  下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3]
  [Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8]
  存放的码流为:Y0 U0 Y1 Y2 U2 Y3
  Y5 V5 Y6 Y7 V7 Y8
  映射出的像素点为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7]
  [Y5 U0 V5] [Y6 U0 V5] [Y7U2 V7] [Y8 U2 V7]
各种YUV格式(图)
  YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。表2.3中的YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。(注意:在介绍各种具体格式时,YUV各分量都会带有下标,如Y0、U0、V0表示第一个像素的YUV分量,Y1、U1、V1表示第二个像素的YUV分量,以此类推。)
  ¨ YUY2(和YUYV)格式为每个像素保留Y分量,而UV分量在水平方向上每两个像素采样一次。一个宏像素为4个字节,实际表示2个像素。(4:2:2的意思为一个宏像素中有4个Y分量、2个U分量和2个V分量。)图像数据中YUV分量排列顺序如下:
  Y0 U0 Y1 V0 Y2 U2 Y3 V2 …
  ¨ YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
  Y0 V0 Y1 U0 Y2 V2 Y3 U2 …
  ¨ UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
  U0 Y0 V0 Y1 U2 Y2 V2 Y3 …
  ¨ AYUV格式带有一个Alpha通道,并且为每个像素都提取YUV分量,图像数据格式如下:
  A0 Y0 U0 V0 A1 Y1 U1 V1 …
  ¨ Y41P(和Y411)格式为每个像素保留Y分量,而UV分量在水平方向上每4个像素采样一次。一个宏像素为12个字节,实际表示8个像素。图像数据中YUV分量排列顺序如下:
  U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y8 …
  ¨ Y211格式在水平方向上Y分量每2个像素采样一次,而UV分量每4个像素采样一次。一个宏像素为4个字节,实际表示4个像素。图像数据中YUV分量排列顺序如下:
  Y0 U0 Y2 V0 Y4 U4 Y6 V4 …
  ¨ YVU9格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个4 x 4的宏块,然后每个宏块提取一个U分量和一个V分量。图像数据存储时,首先是整幅图像的Y分量数组,然后就跟着U分量数组,以及V分量数组。IF09格式与YVU9类似。
  ¨ IYUV格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个2 x 2的宏块,然后每个宏块提取一个U分量和一个V分量。YV12格式与IYUV类似。
  ¨ YUV411、YUV420格式多见于DV数据中,前者用于NTSC制,后者用于PAL制。YUV411为每个像素都提取Y分量,而UV分量在水平方向上每4个像素采样一次。YUV420并非V分量采样为0,而是跟YUV411相比,在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样,如下图所示。


本文转载自
http://baike.baidu.com/view/189685.htm

2008年9月23日星期二

hello, world!

在这个网站上开始贴文章,是想把平时所看、所想、所得,做书面的整理和记录,供自己日后翻阅。

习惯性的采用以上的标题,作为我在这个网站上张贴的第一篇网志。如果你有着十多年软件开发的经历,如果你知道Turbo C、Borland C++,你一定会明白为什么采用这个标题。

"hello, world!",这是个测试程序在屏幕上输出的内容。Hello, World! 程序是一个在计算器屏幕上,只印出 "Hello, World!"(意为「世界,你好!」)这一行字符串的程序。像这样简单的程序,通常是计算器程序语言的初学者,在学习编写时的第一个程序。它还可以用来确定该语言的编译器、程序开发环境,以及执行环境是否已经安装妥当。

把打印出 "Hello World" 作为第一个测试程序,现在已经成为程序语言学习的传统。该程序由 Brian Kernighan 和丹尼斯•里奇写的计算器程序设计教程《C语言程序设计》(The C Programming Language)而广泛流传;但这本书并不是 "hello, world" 的发源处,虽然这是一个普遍存在的错误认知。

这范例程序最早出现于 1972 年,由贝尔实验室成员 Brian Kernighan 撰写的内部技术文件《Introduction to the Language B》之中。不久同作者于 1974 年所撰写的《Programming in C: A Tutorial》,也延用这个范例;而以本文件扩编改写的《C语言程序设计》也保留了这个范例程序。

Turbo C 是美国Borland 公司的产品,Borland公司是一家专门从事软件开发、 研制的大公司。该公司相继推出了一套 Turbo系列软件,如Turbo BASIC, Turbo Pascal, Turbo Prolog, 这些软件很受用户欢迎。

该公司在1987年首次推出Turbo C 1.0 产品,其中使用了全然一新的集成开发环境,即使用了一系列下拉式菜单,将文本编辑、程序编译、连接以及程序运行一体化,大大方便了程序的开发。

1988 年, Borland 公司又推出Turbo C1.5版本, 增加了图形库和文本窗口函数库等, 而Turbo C 2.0 则是该公司1989年出版的。Turbo C2.0在原来集成开发环境的基础上增加了查错功能, 并可以在Tiny模式下直接生成.COM (数据、代码、堆栈处在同一64K 内存中) 文件。还可对数学协处理器 (支持8087/80287/80387等)进行仿真。Borland 公司后来又推出了面向对象的程序软件包Turbo C++,它继承发展Turbo C 2.0 的集成开发环境, 并包含了面向对象的基本思想和设计方法。1991年为了适用Microsoft 公司的Windows 3.0 版本, Borland 公司又将Turbo C++ 作了更新, 即Turbo C 的新一代产品Borlandc C++也已经问世了。

Turbo C 2.0是我当年学习编程的第一个开发环境。这所谓的当年,应该是十五六年前的事情了,那一年大概是1993年。从学习Turbo C, Fortran,Borland C/C++, Delphi, 一直到后来Visual Basic, Visual C++, Perl, Java, ASP, PHP。其实学习不同的编程语言是大同小异的事情,无非不过熟练掌握这种语言的数据类型、关键字、条件分支、循环、程序体,以及开发调试的环境。每次写第一个测试程序,都习惯性的写到 "hello, world!"

在GNU上有一个关于"hello, world!"的笑话,非常有趣。不过看懂这个笑话,需要一点编程方面的知识。如果你看不懂这个笑话,哦,对不起,你一定不是做这行的。

http://www.gnu.org/fun/jokes/helloworld.html