java思维

正在学习中:(

2007年11月22日 #

bcb6 中安装 boost

正则表达式是一种模式匹配形式,它通常用在处理的文本程序中。比如我们经常使用的grep工具,还是perl语言都使用了正则表达式。传统的C++处理正则表达式是非常麻烦的,这也成为很多其他语言爱好者的笑柄,现在情况不一样了,因为有了boost。
Boost是一个基于Template的开发源代码库,在这个库中有很多子库用来高效处理各方面的问题,比如字符串拆分,格式化,线程等等,Boost对于每一个C++爱好者都是应该了解的,对于C++ Builder用户如果能在熟练使用VCL的情况下再熟练使用Boost,我想一定如虎添翼。
一般来说,使用Boost是非常简单,和使用其他STL库没有太大区别,但使用Boost的正则表达式库则不那么容易,因为这个库还需要我们单独编译,下面我将详细介绍如何使用。
如果你还不知道或者还没有Boost的话,你可以去www.boost.org下载最新版本,作者使用的是1.30版本。将下载下来的zip包[1]解压到任何你喜欢的目录,比如D:\boost。
编译正则表达式库
前面已经提到,这个库需要我们单独编译才能使用,为什么不编译好一起发布呢?主要是考虑到不同的编译器需要不同的链接库文件和链接库太大了。在命令行下,进入[%Boost]\Libs\RegEx\Build目录,直接敲入make –fbcb6.mak命令开始编译,这里请大家注意了,如果你的计算机上同时安装了BCB5,请一定要把path设置成为BCB6的bcc32.exe程序所在的目录,否则可能使用BCB5的make程序,这样虽然能编译但最后不能使用。
编译过程相当耗时,你需要耐心等待,最终编译完成,会在[%Boost]\Libs\RegEx\Build目录生成一个BCB6目录,在这个目录生成了很多lib文件和dll文件,把所有dll文件复制到windows系统目录,所以lib文件复制到bcb6\lib目录。如果你不想这么麻烦的复制文件,可以在编译时加入install参数,就像这样make –fBcb6.mak install,不过作者还是比较喜欢前一种方式,这样我可以知道到底生成了什么文件。现在编译已经完成了,你可以体现boost的神奇魅力了。
#include<deque>
#include<iostream>
#include<algorithm>
#include<boost/regex.hpp>
int main()
{
using namespace boost;
using namespace std;
regex expression("\\s+href\\s*=\\s*\"([^\"]*)\"",regbase::normal|regbase::icase);
string s="<a href=\"index.html\"><img src=\"logo.gif\"></a>";
deque<string> result;
regex_split(std::back_inserter(result),s,expression);
copy(result.begin(),result.end(),ostream_iterator<string>(cout,"\n"));
int c;
cin>>c;
return 0;
}
设置BCB6 Project属性的Lib Path和Include Path为你安装boost的目录,运行你会看到结果:
index.html
可以看到index.html已经从字符串中提出出来了,那么为什么会是这样呢?
代码的核心部分是:
regex expression("\\s+href\\s*=\\s*\"([^\"]*)\"",regbase::normal|regbase::icase);
它用来设置如何匹配字符串,上面乱七八糟的字符串很难看懂,如果不了解正则表达式的书写规则,上
面代码可以和天书媲美。
regbase::normal|regbase::icase 是解析参数设置,具体可以参考boost帮助文档。
正则表达式的书写规则
具体的书写规则,大家可以参看boost的文档,我这里做一下简要说明:
. (dot)
用来匹配任何一个字符,但不包括新行上的字符
*
闭包,任意有限次的自重复连接
+
有限次自重复连接,但至少出现一次
{}
指定可能的重复次数
例如:
ba* 匹配 b ba baa baaa等
ba+ 匹配 ba baa baaaaaaaaa等
ba{1,5} 匹配 ba baa baaa baaaa baaaaa
\
转义字符,有很多用途,根据参数设置而变化,最常见的就是类似于c语言\的用法
\s
匹配空格
\w
匹配一个单词
\d
匹配数字
()
有两种用法:
1是合并的作用,例如(ab)*匹配ab abab ababab等
2是确定匹配,也就是说在()中的字符将被最终拆解出来
根据上面这张表,我们可以很容易知道前面的那段天书如何解释。
一个实际的例子
前一段时间在CSDN上有一篇帖子,问题是有一种文件结构如(类似):
@People{
Age=19
Speek=”Hay,{name},how are you”
}
问如何拆分字符串得到@后面的名字,=两边的属性名和属性值,引号里{}种的名字。
解决这个问题用正则表达式再合适不过了。
根据分析,我们可以这样构造匹配规则:
"@(.*?)\s*\\{" 匹配@开始的字符创,后面两种类型如何构造匹配规则留给大家思考吧。
这样我们可以轻易拆解这个例子。

性能分析
通过上面的讨论,大家已经了解到boost的强大威力,那个性能又如何呢?为此我们再实际来拆分一个
复杂的html代码,看看到底需要花费多少时间。
为了节省篇幅,这里就不列出html代码了,不过可以告诉大家,这是一个又Word生成的大小为186K
的html文件,这个文件中用到了很多<table>标签,所以我这里测试就来拆分所有<table>标签的
width属性。测试代码如下:
#include<deque>
#include<iostream>
#include<algorithm>
#include<boost/regex.hpp>
#include<vcl.h>
int main()
{
 using namespace boost;
 using namespace std;
 TStringList* html=new TStringList();
 html->LoadFromFile("D:\\1.htm");
 regex expression("\\s+width=([^\"]*)\s+",regbase::normal|regbase::icase);
DWORD start=GetTickCount();
 for(int n=0;n<html->Count;n++)
 {
    string s=html->Strings[n].c_str(); 
    deque<string> result;
    regex_split(std::back_inserter(result),s,expression);
copy(result.begin(),result.end(),ostream_iterator<string>(cout,"\n"));
result.clear();
}
 start=GetTickCount()-start;
 delete html;
 cout<<start;
int c;
 cin>>c;
 return 0;
}
输出结果为671毫秒,拆分得到1072个width属性值,我们可以看到boost的效率是非常高的,虽然与一些角本语言比起来解析速度还是慢,但已经可以满足大多数编程要求了。另外作者的计算机配置并不是非常高,相信拿到现在任何一台主流配置的计算机上都会优于作者的结果。
结束语

其实上面的强大威力只是boost的冰山一角,如果你不自己去体会,你很难想象到boost的强大威力。在boost里还有很多使用的库,比如格式化输出,字符串拆解,类型转换等,这些库使用起来也比较方便,大家可以自行参考boost文档。在这些库中还有两个库需要自行编译,他们是Python和thread库,而且这些库的编译需要专门的工具Jam,所以我们在编译这些库的时候还要编译jam工具,而编译jam工具也不是一件快乐的事情,麻烦同样出现在如果你安装了多个编译器,如果读者有兴趣可以自己试一下。
不过BCB6并不支持全部boost库,从boost提供的编译器支持表可以看到[2],BCB6还是有相当多的库不支持的,支持最好的是gcc/g++的编译器,但也不是全部支持。希望borland下一个将要发布的C++编译器可以支持更多C++标准。
[1] 其实还有其他类型的包,但在windows系统下,你最好下载zip包
[2] Boost提供的编译器支持表是针对BCB5的,对于BCB6的支持作者并没有详细测试,如果读者有兴趣可以自己测试boost附带的测试代码。

posted @ 2008-12-07 21:22 john 阅读(869) | 评论 (0)编辑 收藏

RedHat LinuxAS4 cvs 服务器搭建步骤

根据网上各种文档整理而成.=号两边要空格的问题折磨了我好久.

 

1:安装

先检查是否安装CVS包

#>rpm -qa|grep cvs

没有安装的话,用下面2种方法安装

(1):在安装linux的时候可以选择安装CVS包
(2):另外下载CVS RPM包 自行安装

2:建立cvs用户和组

#> groupadd cvs
#> useradd -g cvs -G cvs –d /cvsroot cvsroot
#> passwd cvsroot

更改目录属性
chmod –R 770 /cvsroot

3:建立CVS服务

#more /etc/services | grep cvspserver

看看是否有
cvspserver 2401/tcp #CVS client/server operations
cvspserver 2401/udp #CVS client/server operations

如果没有需要到/etc/service文件中增加

建立#vi /etc/xinet.d/cvspserver 文件内容如下

service cvspserver
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/bin/cvs
server_args = -f --allow-root=/cvsroot pserver
}

该文件有特别要注意的地方,所有=号两边都需要空一个空格,除了"root=/cvsroot" 所有要空格的地方,不要多加空格.否则会有CVS服务不能启动的问题

切换到cvsroot用户

#cvs -d /cvsroot init

然后重新启动xinetd服务或者重启动机器

#service xinetd restart

然后用

#netstat -l | grep cvspserver
or
#netstat -l | grep 2401

看是否有下面tcp 0 0 *:cvspserver *:* LISTEN

说明已经正常启动,没有的话请重新检查配置过程是否有错误或者遗漏。最后还必须检查防火墙的设置,把2401端口打开。

4:用户管理

CVS默认使用系统用户登录,所有系统用户都可以登陆,但是这样对系统不安全,我们需要独立的用户管理.CVS用户名和密码保存在CVSROOT目录下的passwd文件中.格式

用户名:密码:系统用户

#htpasswd passwd username

用来设置用户密码并保存到passwd文件中.

然后需要关闭系统用户登陆使用cvs的权限,CVSROOT目录下的config文件,把#SystemAuth=no的#去掉就可以了.

测试登陆

#cvs -d “:pserver:username@127.0.0.1:/cvsroot” login

ok

 

5 :源代码仓库的备份和移动
基本上,CVS的源代码仓库没有什么特别之处,完全可以用文件备份的方式进行备份。需要注意的只是,应该确认备份的过程中没有用户提交修改,具体的做法可以是停止CVS服务器或者使用锁等等。恢复时只需要把这些文件按原来的目录结构存放好,因为CVS的每一个模块都是单独的一个目录,与其他模块和目录没有任何瓜葛,相当方便。甚至只需要在仓库中删除一个目录或者文件,便可以删除该模块的一些内容,不过并不建议这么做,使用CVS的删除功能将会有一个历史记录,而对仓库的直接删除不留任何痕迹,这对项目管理是不利的。移动仓库与备份相似,只需要把该模块的目录移动到新的路径,便可以使用了。
如果不幸在备份之后有过一些修改并且执行了提交,当服务器出现问题需要恢复源代码仓库时,开发者提交新的修改就会出现版本不一致的错误。此时只需要把CVS相关的目录和文件删除,即可把新的修改提交。

6.更进一步的管理
CVSROOT目录下还有很多其他功能,其中最重要的就是modules文件。这个文件定义了源代码库的模块,下面是一个例子:

代码:
Linux    Linux
Kernel   Linux/kernel


这个文件的内容按行排列,每一行定义一个模块,首先是模块名,然后是模块路径,这是相对于CVS根目录的路径。它定义了两个模块,第一个是Linux模块,它位于Linux目录中,第二个是Kernel模块,这是Linux模块的子模块。
modules文件并非必须的,它的作用相当于一个索引,部分CVS客户端软件通过它可以快速找到相应的模块,比如WinCVS。

7.协同开发的问题
默认方式下,CVS允许多个用户编辑同一个文件,这对一个协作良好的团队来说不会有什么问题,因为多个开发者同时修改同一个文件的同一部分是不正常的,这在项目管理中就应该避免,出现这种情况说明项目组内部没有统一意见。而多个开发者修改文件的不同部分,CVS可以很好的管理。
如果觉得这种方式难以控制,CVS也提供了解决办法,可以使用cvs admin -l进行锁定,这样一个开发者正在做修改时CVS就不会允许其他用户checkout。这里顺便说明一下文件格式的问题,对于文本格式,CVS可以进行历史记录比较、版本合并等工作,而二进制文件不支持这个操作,比如word文档、图片等就应该以二进制方式提交。对于二进制方式,由于无法进行合并,在无法保证只有一个用户修改文件的情况下,建议使用加锁方式进行修改。必须注意的是,修改完毕记得解锁。
从1.6版本开始,CVS引入了监视的概念,这个功能可以让用户随时了解当前谁在修改文件,并且CVS可以自动发送邮件给每一个监视的用户告知最新的更新。

8.建立多个源代码仓库
如果需要管理多个开发组,而这些开发组之间不能互相访问,可以有2个办法:
a.共用一个端口,需要修改cvspserver文件,给server_args指定多个源代码路径,即多个—allow-root参数。由于xinetd的server_args长度有限制,可以在cvspserver文件中把服务器的设置重定向到另外一个文件,如:

代码:
server = /home/cvsroot/cvs.run


然后创建/home/cvsroot/cvs.run文件,该文件必须可执行,内容格式为:

代码:
#!/bin/bash
/usr/bin/cvs -f \
--allow-root=/home/cvsroot/src1 \
--allow-root=/home/cvsroot/src2 \
pserver


注意此时源代码仓库不再是/home/cvsroot,进行初始化的时候要分别对这两个仓库路径进行初始化,而不再对/home/cvsroot路径进行初始化。
b.采用不同的端口提供服务
重复第2步和第3步,为不同的源代码仓库创建不同服务名的启动脚本,并为这些服务名指定不同的端口,初始化时也必须分别进行初始化。
 
 

 

 

posted @ 2008-05-25 02:04 john 阅读(421) | 评论 (0)编辑 收藏

Oracle 内存分配建议


 Oracle 内存分配建议
关于SGA设置的一点总结
本总结不针对特例,仅对服务器只存在OS + ORACLE 为例,如果存在其他应用请酌情考虑
写这个也是因为近来这种重复性的问题发生的太多所导致的

首先不要迷信STS,SG,OCP,EXPERT 等给出的任何建议、内存百分比的说法
基本掌握的原则是, data buffer 通常可以尽可能的大,shared_pool_size 要适度,log_buffer 通常大到几百K到1M就差不多了

设置之前,首先要明确2个问题
1: 除去OS和一些其他开销,能给ORACLE使用的内存有多大
2:oracle是64bit or 32 bit,32bit 通常 SGA有 1.7G 的限制(某些OS的处理或者WINDOWS上有特定设定可以支持到2G以上甚至达到3.7G,本人无这方面经验)

下面是我的windows2000下的oracle :

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
PL/SQL Release 8.1.7.0.0 - Production
CORE 8.1.7.0.0 Production
TNS for 32-bit Windows: Version 8.1.7.0.0 - Production
NLSRTL Version 3.4.1.0.0 - Production

SQL>

windows上存在32bit的限制,如AIX、HP UNIX 等有明确的64BIT OS and ORACLE的版本,32bit oracle可以装在64bit os 上,64 bit oracle不能装在32 bit OS上

不管oracle是32 bit ORACLE还是 64 bit 的,假定应用存在没有很好的使用bind var 的情况,也不能设置 shared_pool_size 过大,通常应该控制在200M--300M,如果是 ORACLE ERP 一类的使用了很多存储过程函数、包 ,或者很大的系统,可以考虑增大shared_pool_size ,但是如果超过500M可能是危险的,达到1G可能会造成CPU的严重负担,系统甚至瘫痪。所以shared_pool_size 如果超过300M还命中率不高,那么应该从应用上找原因而不是一味的增加内存,shared_pool_size 过大主要增加了管理负担和latch 的开销。

log_buffer : 128K ---- 1M 之间通常问题不大,不应该太大

large_pool_size :如果不设置MTS,通常在 RMAN 、OPQ 会使用到,但是在10M --- 50M 应该差不多了。假如设置 MTS,则由于 UGA 放到large_pool_size 的缘故,这个时候依据 session最大数量和 sort_ares_size 等参数设置,必须增大large_pool_size 的设置,可以考虑为 session * (sort_area_size + 2M)。这里要提醒一点,不是必须使用MTS,我们都不主张使用MTS,尤其同时在线用户数小于500的情况下。

java_pool_size : 若不使用java,给30M通常就够了

data buffer ,在做了前面的设置后,凡可以提供给oracle的内存,都应该给data buffer = (db_block_size * db_block_buffers)
在9i 中可以是 db_cache_size

还有2个重要参数我们需要注意

sort_area_size and hash_area_size
这两个参数在非MTS下都是属于PGA ,不属于SGA,是为每个session单独分配的,在我们的服务器上除了OS + SGA,一定要考虑这两部分

(****) : OS 使用内存+ SGA + session*(sort_area_size + hash_area_size + 2M) < 总物理RAM 为好


这样归结过来,假定oracle是 32 bit ,服务器RAM大于2G ,注意你的PGA的情况,,则建议

shared_pool_size + data buffer +large_pool_size + java_pool_size < 1.6G


再具体化,注意满足上面(****) 的原则的基础上可以参考如下设置
如果512M RAM
建议 shared_pool_size = 50M, data buffer = 200M

如果1G RAM
shared_pool_size = 100M , data buffer = 500M

如果2G
shared_pool_size = 150M ,data buffer = 1.2G

物理内存再大已经跟参数没有关系了


假定64 bit ORACLE

内存4G
shared_pool_size = 200M , data buffer = 2.5G

内存8G
shared_pool_size = 300M , data buffer = 5G

内存 12G
shared_pool_size = 300M-----800M , data buffer = 8G



以上仅为参考值,不同系统可能差异比较大,需要根据具体情况调整。建议在设置参数的同时,init中使用 lock_sga ,在不同的平台上可能有不同的方式,使得SGA锁定在物理内存中而不被放入 SWAP 中,这样对效率有好处


关于内存的设置,要再进行细致的调整,起的作用不大,但可根据statspack信息和v$system_event,v$sysstat,v$sesstat,v$latch 等view信息来考虑微调

posted @ 2008-01-28 23:58 john 阅读(783) | 评论 (0)编辑 收藏

Oracle 回滚段空间回收步骤

     摘要:   是谁"偷偷的"用了那么多空间呢(本来有几十个G的Free磁盘空间的)? 检查数据库表空间占用空间情况: SQL> select tablespace_name,sum(bytes)/1024/1024/1024 GB  2 from dba...  阅读全文

posted @ 2007-12-27 00:50 john 阅读(2242) | 评论 (1)编辑 收藏

常用的MQ命令

最近在配置MQ,记下了一些常用的MQ命令,如下:

创建队列管理器
crtmqm –q QMgrName
-q是指创建缺省的队列管理器

删除队列管理器
dltmqm QmgrName

启动队列管理器
strmqm QmgrName
如果是启动默认的队列管理器,可以不带其名字

停止队列管理器
endmqm QmgrName 受控停止

endmqm –i QmgrName 立即停止

endmqm –p QmgrName 强制停止

显示队列管理器
dspmq –m QmgrName

运行MQ命令
runmqsc QmgrName
如果是默认队列管理器,可以不带其名字

往队列中放消息
amqsput QName QmgrName
如果队列是默认队列管理器中的队列,可以不带其队列管理器的名字

从队列中取出消息
amqsget QName QmgrName
如果队列是默认队列管理器中的队列,可以不带其队列管理器的名字

启动通道
runmqchl –c ChlName –m QmgrName

启动侦听
runmqlsr –t TYPE –p PORT –m QMgrName

停止侦听
endmqlsr -m QmgrName

下面是在MQ环境中可以执行的MQ命令(即在runmqsc环境下可以敲的命令)

定义持久信队列
DEFINE QLOCAL(QNAME) DEFPSIST(YES) REPLACE

设定队列管理器的持久信队列
ALTER QMGR DEADQ(QNAME)

定义本地队列
DEFINE QL(QNAME) REPLACE

定义别名队列
DEFINE QALIAS(QALIASNAME) TARGQ(QNAME)

远程队列定义
DEFINE QREMOTE(QRNAME) +
RNAME(AAA) RQMNAME(QMGRNAME) +
XMITQ(QTNAME)

定义模型队列
DEFINE QMODEL(QNAME) DEFTYPE(TEMPDYN)

定义本地传输队列
DEFINE QLOCAL(QTNAME) USAGE(XMITQ) DEFPSIST(YES) +
INITQ(SYSTEM.CHANNEL.INITQ)+
PROCESS(PROCESSNAME) REPLACE

创建进程定义
DEFINE PROCESS(PRONAME) +
DESCR(‘STRING’)+
APPLTYPE(WINDOWSNT)+
APPLICID(’ runmqchl -c SDR_TEST -m QM_ TEST’)
其中APPLTYPE的值可以是:CICS、UNIX、WINDOWS、WINDOWSNT等

创建发送方通道
DEFINE CHANNEL(SDRNAME) CHLTYPE(SDR)+
CONNAME(‘100.100.100.215(1418)’) XMITQ(QTNAME) REPLACE
其中CHLTYPE可以是:SDR、SVR、RCVR、RQSTR、CLNTCONN、SVRCONN、CLUSSDR和CLUSRCVR。

创建接收方通道
DEFINE CHANNEL(SDR_ TEST) CHLTYPE(RCVR) REPLACE

创建服务器连接通道
DEFINE CHANNEL(SVRCONNNAME) CHLTYPE(SVRCONN) REPLACE

显示队列的所有属性
DISPLAY QUEUE(QNAME) [ALL]

显示队列的所选属性
DISPLAY QUEUE(QNAME) DESCR GET PUT
DISPLAY QUEUE(QNAME)MAXDEPTH CURDEPTH

显示队列管理器的所有属性
DISPLAY QMGR [ALL]

显示进程定义
DISPLAY PROCESS(PRONAME)

更改属性
ALTER QMGR DESCR(‘NEW DESCRIPTION’)
ALTER QLOCAL(QNAME) PUT(DISABLED)
ALTER QALIAS(QNAME) TARGQ(TARGQNAME)

删除队列
DELETE QLOCAL(QNAME)
DELETE QREMOTE(QRNAME)

清除队列中的所有消息
CLEAR QLOCAL(QNAME)

以下是一些高级配置的命令:

amqmcert                  配置SSL证书

amqmdain                配置windows上的MQ服务

crtmqcvx                    转换数据

dmpmqaut                转储对象权限管理

dmpmqlog                转储日志管理

dspmq                         显示队列管理器

dspmqaut                  显示打开对象的权限

dmpmqcap               显示处理程序容量和处理程序数

dspmqcsv                 显示命令服务器状态

dspmqfls                   显示文件名

dspmqtrc                   跟踪MQ输出(HP-UNIX LINUX Solaris)

dspmqrtn                   显示事务的详细信息

endmqcsv                 停止队列管理器上的命令服务器

strmqcsv                    启动队列管理器上的命令服务器

endmqtrc                   停止跟踪

rcdmqimg                  向日志写对象的映像

rcmqobj                      根据日志中的映像重新创建一个对象

rsvmqtrn                     提交或逆序恢复事务

 


posted @ 2007-12-26 17:26 john 阅读(2580) | 评论 (0)编辑 收藏

BCB UTF-8 格式转换

如果是字串转换.BCB有多个方法(如TStringConverter,或API的 WideCharToMultiByte/MultiByteToWideChar,VCL的WideCharToString/StringToWideChar等)
当然,BCB本身就支持三种字串,前两种可自动转,后一种有函数:
String x; //GBK
WideString y; //unicode
UTF8String z; //utf8

x=y; //自动
y=x; //自动
z=AnsiToUtf8(x);
x=Utf8ToAnsi(z);

posted @ 2007-11-22 18:11 john 阅读(2667) | 评论 (1)编辑 收藏