随笔-153  评论-235  文章-19  trackbacks-0
  2007年12月30日
如鼠标移到 class 为 box 的 div 标签中背景变色

.vbox div:hover{background: #ddd;}

据说 IE6.0、Firefox2.0、Opera 9.23都不支持

posted @ 2010-02-24 22:10 流浪汗 阅读(1949) | 评论 (0)编辑 收藏
想改 a  的默认方式,比如:链接不要下划线,鼠标移到上面时有划线。

css 如
a:hover {text-decoration: underline;}
a:link 
{text-decoration: none;}
a:visited 
{text-decoration: none;}

是没有达到鼠标称到上面有划线。

必须改为:
a:link {text-decoration: none;}
a:visited 
{text-decoration: none;}
a:hover 
{text-decoration: underline;}

a:hover 放到最后。
posted @ 2010-02-24 22:04 流浪汗 阅读(973) | 评论 (3)编辑 收藏
一、介绍Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.
二、Location语法语法:location [=|~|~*|^~] /uri/ { … }
注:
1、~   为区分大小写匹配
2、~* 为不区分大小写匹配
3、!~和!~*分别为区分大小写不匹配及不区分大小写
不匹配
示例一:
location  / {
}
匹配任何查询,因为所有请求都以 / 开头。但是正则表达式规则将被优先和查询匹配。
示例二:
location =/ {}
仅仅匹配/

示例三:
location ~* \.(gif|jpg|jpeg)$ {
rewrite \.(gif|jpg)$ /logo.png;

注:不区分大小写匹配任何以gif,jpg,jpeg结尾的文件

三、ReWrite语法
last - 基本上都用这个Flag。
break - 中止Rewirte,不在继续匹配
redirect - 返回临时重定向的HTTP状态302
permanent - 返回永久重定向的HTTP状态301

1、下面是可以用来判断的表达式:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
2、下面是可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:
http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php

四、Redirect语法
    server {
    listen 80;
    server_name start.igrow.cn;
    index index.html index.php;
    root html;
    if ($http_host !~ "^star\.igrow\.cn$&quot {
         rewrite ^(.*)
http://star.igrow.cn$1 redirect;
    }
    }

五、防盗链location ~* \.(gif|jpg|swf)$ {
  valid_referers none blocked start.igrow.cn sta.igrow.cn;
  if ($invalid_referer) {
  rewrite ^/
http://$host/logo.png;
  }
}

六、根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
   expires    1h;
   break;
}
}

七、禁止访问某个目录
location ~* \.(txt|doc)${
   
  root /data/www/wwwroot/linuxtone/test;
   
deny all;
}

转:http://www.phpchina.com/html/70/t-162870.html,http://idev.yo2.cn/go/19761.html
posted @ 2010-02-03 10:25 流浪汗 阅读(11996) | 评论 (0)编辑 收藏
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。

   
 top - 01:06:48 up  1:22,  1 user,  load average: 0.06, 0.60, 0.48
Tasks:  29 total,   1 running,  28 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.3% us,  1.0% sy,  0.0% ni, 98.7% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    191272k total,   173656k used,    17616k free,    22052k buffers
Swap:   192772k total,        0k used,   192772k free,   123988k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  1379 root      16   0  7976 2456 1980 S  0.7  1.3   0:11.03 sshd
14704 root      16   0  2128  980  796 R  0.7  0.5   0:02.72 top
     1 root      16   0  1992  632  544 S  0.0  0.3   0:00.90 init
     2 root      34  19     0    0    0 S  0.0  0.0   0:00.00 ksoftirqd/0
     3 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 watchdog/0

    统计信息区
    前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下:

    01:06:48 当前时间
    up 1:22 系统运行时间,格式为时:分
    1 user 当前登录用户数
    load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。
    三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

    第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:

    Tasks: 29 total 进程总数
    1 running 正在运行的进程数
    28 sleeping 睡眠的进程数
    0 stopped 停止的进程数
    0 zombie 僵尸进程数
    Cpu(s): 0.3% us 用户空间占用CPU百分比
    1.0% sy 内核空间占用CPU百分比
    0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
    98.7% id 空闲CPU百分比
    0.0% wa 等待输入输出的CPU时间百分比
    0.0% hi
    0.0% si

    最后两行为内存信息。内容如下:

    Mem: 191272k total 物理内存总量
    173656k used 使用的物理内存总量
    17616k free 空闲内存总量
    22052k buffers 用作内核缓存的内存量
    Swap: 192772k total 交换区总量
    0k used 使用的交换区总量
    192772k free 空闲交换区总量
    123988k cached 缓冲的交换区总量。
    内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,
    该数值即为这些内容已存在于内存中的交换区的大小。
    相应的内存再次被换出时可不必再对交换区写入。

进程信息区
    统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。

    序号 列名 含义
    a PID 进程id
    b PPID 父进程id
    c RUSER Real user name
    d UID 进程所有者的用户id
    e USER 进程所有者的用户名
    f GROUP 进程所有者的组名
    g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
    h PR 优先级
    i NI nice值。负值表示高优先级,正值表示低优先级
    j P 最后使用的CPU,仅在多CPU环境下有意义
    k %CPU 上次更新到现在的CPU时间占用百分比
    l TIME 进程使用的CPU时间总计,单位秒
    m TIME+ 进程使用的CPU时间总计,单位1/100秒
    n %MEM 进程使用的物理内存百分比
    o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
    q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    r CODE 可执行代码占用的物理内存大小,单位kb
    s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
    t SHR 共享内存大小,单位kb
    u nFLT 页面错误次数
    v nDRT 最后一次写入到现在,被修改过的页面数。
    w S 进程状态。
    D=不可中断的睡眠状态
    R=运行
    S=睡眠
    T=跟踪/停止
    Z=僵尸进程
    x COMMAND 命令名/命令行
    y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
    z Flags 任务标志,参考 sched.h

    默认情况下仅显示比较重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通过下面的快捷键来更改显示内容。

    更改显示内容
    通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或隐藏对应的列,最后按回车键确定。

    按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z 可以将相应的列向左移动。最后按回车键确定。

    按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的 R 键可以将当前的排序倒转。

 命令使用

    1. 工具(命令)名称
    top
    2.工具(命令)作用
    显示系统当前的进程和其他状况; top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止. 比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定.
    3.环境设置
    在Linux下使用。
    4.使用方法
    4.1使用格式
    top [-] [d] [p] [q] [c] [C] [S] [s]  [n]
    4.2参数说明
     d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。
     p 通过指定监控进程ID来仅仅监控某个进程的状态。
     q该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。
     S 指定累计模式
     s 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
     i  使top不显示任何闲置或者僵死进程。
     c  显示整个命令行而不只是显示命令名
    4.3其他
       下面介绍在top命令执行过程中可以使用的一些交互命令。从使用角度来看,熟练的掌握这些命令比掌握选项还重要一些。这些命令都是单字母的,如果在命令行选项中使用了s选项,则可能其中一些命令会被屏蔽掉。
      Ctrl+L 擦除并且重写屏幕。
      h或者? 显示帮助画面,给出一些简短的命令总结说明。
      k 终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。一般的终止进程可以使用15信号;如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。
      i 忽略闲置和僵死进程。这是一个开关式命令。
      q 退出程序。
      r 重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低,反之则可以使该进程拥有更高的优先权。默认值是10。
      S 切换到累计模式。
      s 改变两次刷新之间的延迟时间。系统将提示用户输入新的时间,单位为s。如果有小数,就换算成m s。输入0值则系统将不断刷新,默认值是5 s。需要注意的是如果设置太小的时间,很可能会引起不断刷新,从而根本来不及看清显示的情况,而且系统负载也会大大增加。
      f或者F 从当前显示中添加或者删除项目。
      o或者O 改变显示项目的顺序。
      l 切换显示平均负载和启动时间信息。
      m 切换显示内存信息。
      t 切换显示进程和CPU状态信息。
      c 切换显示命令名称和完整命令行。
      M 根据驻留内存大小进行排序。
      P 根据CPU使用百分比大小进行排序。
      T 根据时间/累计时间进行排序。
        W 将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。

posted @ 2010-01-08 11:08 流浪汗 阅读(731) | 评论 (0)编辑 收藏

想发布新版的 mmseg4j 到现在已经有二个多月了。主要是因为这段时间忙其它事情了。现 Lucene 2.9 发布了,solr 1.4 也应该会比较快就要发布了。对 mmseg4j 兼容新版的 lucene/solr 也是个任务。

现 mmseg4j 发布新版 1.8,可以下载:mmseg4j-1.8.zip 包括了源码与词库,还有创建文件。下面说下此版的主要变更:

new:

1、有检测词典变更的接口,外部程序可以使用 wordsFileIsChange() 和 reload() 来完成检测与加载的工作. (内部不实现自动检测与加载,留给外部程序去做。)

2、添加 MMseg4jHandler 类,可以在solr中用url的方式来控制加载检测词库。

3、增加 CutLetterDigitFilter过虑器,切分“字母和数”混在一起的过虑器。比如:mb991ch 切为 "mb 991 ch"。

changes:

1、默认在 classpath 中加载 data 目录(词库目录),找不到再找 user.dir/data 目录。但是优先 mmseg.dic.path 系统属性指定的。

2、新词库,去除 sogou 高频无词性的词,合并 rmmseg 提供的词(是 mmseg4j 1.0 使用的词库),共计(14W 多词)。

3、数字或英文开头的数字或英文不独立分出。如 MB991CH/A 分为 mb991ch a,cq40-519tx 分为 CQ40 519TX

4、内置支持小写,不需要 LowerCaseFilter 了。MMSegAnalyzer 去除了小写过虑。

5、支持 solr 1.3/1.4、lucene 2.3/2.4/2.9

6、尝试加载 jar 里的 words.dic,并构建含有 words.dic 的 jar(mmseg4j-*-with-dic.jar)。

bugs:

1、Dictionary 添加 finalize 方法。修正 tomcat reload 时 OOM 的 bug: http://code.google.com/p/mmseg4j/issues/detail?id=4

2、MMSegTokenizer 在 lucene 2.4 编译的 在 lucene 2.9 中会报 java.lang.NoSuchFieldError: input。bug: http://code.google.com/p/mmseg4j/issues/detail?id=5

详情:http://blog.chenlb.com/2009/10/chinese-segment-mmseg4j-1_8-release.html

posted @ 2009-10-19 09:28 流浪汗 阅读(3426) | 评论 (1)编辑 收藏
中文分词 mmseg4j 1.7.2 版发布,其实两天前就发布了,只是没有写博客而已。与引版本发布的还有 1.6.2,两者基本一样,只是词库的数据结构不同,1.7的是键树,1.6的是数组与二分查找。 mmseg4j 1.7.2 版的主要更新:
  • 修复由 1.7-beta 升级到 1.7 版的 bug:添加 lowerCaseFilter 后的一个 bug: NullPointerException。
  • 核发程序与 lucene 和 solr 扩展分开打包, 同时给出低版本的 lucene 扩展(lucene 1.9 到 2.2; lucene 2.3)
如何从源码编译:下载源码:mmseg4j-1.7.2-srcmmseg4j-1.6.2-src。解压到如:e:/mmseg4j-1.7.2-src。然后到这个目录,运行:

 




上面编译是在 solr 1.3 和 lucene 2.4 环境下的。如果您要在 低版本的 lucene 中使用,到 e:/mmseg4j-1.7.2-src/contrib/lucene_1_9 或 e:/mmseg4j-1.7.2-src/contrib/lucene_2_3 运行:

 

说明:到 contrib 下的子项目中编译的话,先要编译 mmseg4j,contrib/lucene_1_9 可以支持到 2.2。

如果有任何疑问、建议,欢迎到论坛 http://groups.google.com/group/mmseg4j/topics?hl=zh_CN 讨论。或与我联系 chenlb2008#gmail.com。

还要感谢网友“苦涩可乐”提示 NullPointerException 的bug。

官方博客:mmseg4j,项目:google code mmseg4j
posted @ 2009-04-27 20:00 流浪汗 阅读(2892) | 评论 (0)编辑 收藏
很久没有在此博客写东西了。但一个多月了,原因是我已经有自己的博客空间了,此博客很少更新,不过如果写得好文就转载到此博客。

posted @ 2008-10-25 11:54 流浪汗 阅读(656) | 评论 (0)编辑 收藏
一直找代码高亮显示,在wp上可以有coolcode但,觉得美中不足的是服务器解析,每请求一次做一次。今天偶然看到 Unmi的博客,他的代码好漂亮,看源码,知道shCore,把他的拿过来试用下。 java 代码

java 代码

groovy 代码

 

posted @ 2008-09-05 00:26 流浪汗 阅读(1308) | 评论 (2)编辑 收藏
.tgz 解压:
tar zxvf myfile.tgz
posted @ 2008-09-03 13:33 流浪汗 阅读(46177) | 评论 (3)编辑 收藏
solr分发问题。
用rsync同步目录里出现:rsync:link_stat "snapshot.20080820124136/." (in solr) failed: No such file or directory (2)

上一编配置得没什么问题:http://www.blogjava.net/chenlb/archive/2008/07/04/212398.html 。现竟然出错,郁闷。

网上找了下, 说明路径有空格。http://bbs.chinaunix.net/viewthread.php?tid=1003058

二楼的回复:

带空格的文件/目录名不知道害死了多少人。

`rsync -av --progress $dir1 $dir2`;

`rsync -av --progress "$dir1" "$dir2"`;
代替。

其实 `` 虽然用着方便,
但不适合内插变量。
有变量作为参数的情况下,建议用 system。

此是解决那楼主的问题,可以本来就没有空格的问题,没解决到我的问题。仔细思索。

机子里有几个rsync服务,我部署的时候是复制相关的配置,rsync服务端口没改,子机同步这个服务的时候(子机同步端口与rsync一致,是错的,重复的),然后做同步的时候出现上面的问题。改了其它端口后就可以。

总的来讲,还是自己对linux了解不多。
posted @ 2008-09-02 16:14 流浪汗 阅读(6484) | 评论 (0)编辑 收藏
用unzip

unzip myfile.zip
posted @ 2008-09-02 16:03 流浪汗 阅读(809) | 评论 (0)编辑 收藏
上一篇记录了本机模式我虚拟分布模式。http://www.blogjava.net/chenlb/archive/2008/08/11/221311.html

现我在虚拟机里开三台机子,分别命名为:master(172.16.249.210),slave-1(172.16.249.211),slave-2(172.16.249.212)。

master可以无密码登录到slave机。
每台机子都匹配ip对应名。
127.0.0.1       localhost       localhost

172.16.249.210  master
172.16.249.211  slave-1
172.16.249.212  slave-2

修改conf/masters文件和conf/slaves文件。
conf/masters文件:
master

conf/slaves文件:
slave-1
slave-
2

格式化后可以启动了:
[chenlb@master hadoop-0.17.1]$ bin/start-all.sh 


参考资料:
http://hadoop.apache.org/core/docs/r0.17.1/quickstart.html
http://hadoop.apache.org/core/docs/r0.17.1/cluster_setup.html
posted @ 2008-08-11 15:45 流浪汗 阅读(792) | 评论 (0)编辑 收藏

 

Required Software

  1. JavaTM 1.5.x
  2. ssh与sshd

如果没有安装请自行安装。我以CentOS 4.6为例。

下载hadoop,http://apache.mirror.phpchina.com/hadoop/core/ 我下载的是0.17.1版本。

解压hadoop-0.17.1.tar.gz,然后conf/hadoop-env.sh 设置JAVA_HOME ,我是可JAVA_HOME 去注释,值自己的路径。如:

export JAVA_HOME=/usr/java/jdk1.6.0_06

如果不设置启动后用不了。

先从简单开始。

1、Local (Standalone) Mode ,叫单机模式。

[chenlb@master hadoop-0.17.1]$ bin/hadoop jar hadoop-0.17.1-examples.jar grep conf output 'dfs[a-z.]+'

 

[chenlb@master hadoop-0.17.1]$ cat output/*


如果,正常可以看到内容。像这样。

3       dfs.
3       dfs.class
2       dfs.period
2       dfs.replication
...    ...

2、Pseudo-Distributed Mode,虚拟分布模式。
vi conf/hadoop-site.xml
<configuration>
<property>
        
<name>fs.default.name</name>
        
<value>hdfs://master:9000/</value>
</property>
<property>
        
<name>mapred.job.tracker</name>
        
<value>hdfs://master:9001/</value>
</property>
<property>
        
<name>dfs.replication</name>
        
<value>1</value>
</property>
<property>
        
<name>hadoop.tmp.dir</name>
        
<value>/home/chenlb/hadoop-0.17.1/tmp/</value>
</property>
</configuration>

在/etc/hosts里添加本机ip对应master,例如我的:172.16.249.210    master
保证可以无密码登录。请看那一篇文章:http://www.blogjava.net/chenlb/archive/2008/07/03/212293.html

用ssh localhost试一下是否免密码登录。

格式化分布式文件系统:
[chenlb@master hadoop-0.17.1]$ bin/hadoop namenode -format

启动Hadoop:
[chenlb@master hadoop-0.17.1]$ bin/start-all.sh 

默认可以在${HADOOP_HOME}/logs里看到日志。

可以用web看浏览NameNode和JobTracker
  • NameNode - http://localhost:50070/
  • JobTracker - http://localhost:50030/


    把文件放到分布式文件系统里:

    [chenlb@master hadoop-0.17.1]$ bin/hadoop dfs -put conf input

    此时已经在分布文件系统里建立了input文件夹。而conf是本地的文件夹。

    执行示例:
    [chenlb@master hadoop-0.17.1]$ bin/hadoop jar hadoop-*-examples.jar grep input output 'dfs[a-z.]+'

    这里input和output都是分布式文件系统的的文件夹,而且output在分布式文件系统里不存在,否则报错(也可以先删除它bin/badoop dfs -rmr output)。

    耐心等待。结束后可以查看。
    [chenlb@master hadoop-0.17.1]$ bin/hadoop dfs -get output output 
    [chenlb
    @master hadoop-0.17.1]$ cat output/* 

    也可以直接在分布式文件系统里查:
    [chenlb@master hadoop-0.17.1]$ bin/hadoop dfs -cat output/*

    成功运行后可以关闭它了:
    [chenlb@master hadoop-0.17.1]$ bin/stop-all.sh

    我在第2阶段,出了些问题:output已经存在,要先删除它(第二次运行前,可以不用output)。

    下一篇讲:Fully-Distributed Mode http://www.blogjava.net/chenlb/archive/2008/08/11/221314.html
  • posted @ 2008-08-11 15:28 流浪汗 阅读(4944) | 评论 (2)编辑 收藏
    在linux下改了ip地址后,不能立即生效。以前是重启机器,我觉得这样很傻,后来知道网卡可以重启。

    /etc/init.d/network restart
    posted @ 2008-08-11 09:34 流浪汗 阅读(6056) | 评论 (1)编辑 收藏
    一直想了解分布搜索与索引。Lucene有MultiSearcher,solr1.2的只能有单个索引,现在1.3可以有Distributed Searching这玩意。可以从多个索引里搜索出并合并结果返回给你。这些索引不是replication的,是分割的。可以先%num方式索引在num台机器上,然后用solr的shards参数。

    如:
    shards=localhost:8080/use-solr1.3,localhost:9080/use-solr1.3&q=chenlb

    测试后可以返回结果,但合并的时候发了点时间,我的机子上40-60ms,单个搜索基本是0ms

    测试数据是14W结果,分开索引到两个tomcat里。看了后台,一个搜索有两次请求,其中合并的那机子是三次请求。时间可能花在请求里,还有就是合并可能缓存不到。

    官方建议:如果单个solr足够快的话没有必要搞Distributed Searching,如果再高点要求可以index repliction。

    当索引很大的时候可能Distributed Searching用的上场, 个人之见。

    参考:http://wiki.apache.org/solr/DistributedSearch
    posted @ 2008-08-07 18:31 流浪汗 阅读(1009) | 评论 (0)编辑 收藏
    html 与 xml的转义符不同, xml就只有5个:

    < &lt;
    > &gt;
    & &amp;
    " &quot;
    ' &apos;


    xml没有&nbsp;
    posted @ 2008-08-06 12:40 流浪汗 阅读(15374) | 评论 (2)编辑 收藏
    我比较喜欢免安装版(非安装版)的mysql,

    下载如: mysql-noinstall-5.0.45-win32.zip

    把它解压到如: E:/mysql-5.0.45, 当然可以任意位置。

    然后改my-medium.ini文件为my.ini,当然也可以不改名,但要改内容

    basedir="E:/mysql-5.0.45/"

    datadir
    ="E:/mysql-5.0.45/Data/"

    如果上面,最好加个字符集,在[mysqld]和[mysql]下面加
    default-character-set=utf8

    当然可能是其它字符集, 如:gbk

    写个mysql-startup.bat
    "E:\mysql-5.0.45\bin\mysqld" --defaults-file="E:\mysql-5.0.45\my.ini"

    双击mysql-startup.bat即可启动。

    用mysqladmin关闭mysql服务:
    E:/mysql-5.0.45/bin/mysqladmin -u root shutdown


    ^_^
    posted @ 2008-08-03 16:22 流浪汗 阅读(3081) | 评论 (1)编辑 收藏
        想让Tomcat支持ssi,一般是shtml文件。配置比较简单。

    默认tomcat不支持ssi。

    现以tomcat5.5.x为例。

    改conf/web.xml配置。

    有两种方式:一是servlet,二是filter。

    servlet方式的:
    <!--
        <servlet>
            <servlet-name>ssi</servlet-name>
            <servlet-class>
              org.apache.catalina.ssi.SSIServlet
            </servlet-class>
            <init-param>
              <param-name>buffered</param-name>
              <param-value>1</param-value>
            </init-param>
            <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
            </init-param>
            <init-param>
              <param-name>expires</param-name>
              <param-value>666</param-value>
            </init-param>
            <init-param>
              <param-name>isVirtualWebappRelative</param-name>
              <param-value>0</param-value>
            </init-param>
            <load-on-startup>4</load-on-startup>
        </servlet>
    -->

    <!--
        <servlet-mapping>
            <servlet-name>ssi</servlet-name>
            <url-pattern>*.shtml</url-pattern>
        </servlet-mapping>
    -->

    找到上面的内容,去掉注释。

    filter方式:
    <!--
        <filter>
            <filter-name>ssi</filter-name>
            <filter-class>
              org.apache.catalina.ssi.SSIFilter
            </filter-class>
            <init-param>
              <param-name>contentType</param-name>
              <param-value>text/x-server-parsed-html(;.*)?</param-value>
            </init-param>
            <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
            </init-param>
            <init-param>
              <param-name>expires</param-name>
              <param-value>666</param-value>
            </init-param>
            <init-param>
              <param-name>isVirtualWebappRelative</param-name>
              <param-value>0</param-value>
            </init-param>
        </filter>
    -->

    <!--
        <filter-mapping>
            <filter-name>ssi</filter-name>
            <url-pattern>*.shtml</url-pattern>
        </filter-mapping>
    -->

    同样是去掉上面的注释。但是filter方式的还要加mime-mapping=text/x-server-parsed-html
    <!--
        <mime-mapping>
            <extension>shtml</extension>
            <mime-type>text/x-server-parsed-html</mime-type>
        </mime-mapping>
    -->

    去掉mime-mapping的shtml注释。

    在test的web试下:
    index.shtml
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ssi 示例</title>
    </head>

    <body>
    ssi area 
    <!--#include virtual="ssi.html" -->
    <p>

            footer 
    <!--#include virtual="footer.html" --><p>
            
            
    <p>
                
    <!--#config timefmt="%D" -->
            Me last modified 
    <!--#echo var="LAST_MODIFIED" -->

    </body>
    </html>

    footer.html
    <ul>
        
    <li>index</li>
        
    <li>about</li>
    </ul>

    ssi.html
    <p>this is ssi.html file</p><p>
    <p>中文</p>
    ssi.html file end
    <p/>


    现在可以,http://localhost:8080/test/index.shtml 有结果了。
    posted @ 2008-07-27 21:55 流浪汗 阅读(1370) | 评论 (0)编辑 收藏
        有一个项目的代码提交是用https协议的。一提交的时候出现如下错误:

    svn: PROPFIND request failed on '/svn/trunk/xxx'
    svn: PROPFIND of '/svn/trunk/xxx': Could not create SSL connection through proxy server (https://.

        这下郁闷,看了下eclipse设置,又没有设代理。google一下,看到一个邮件列表,有一个字眼“TSVN”。哦,快去看看TortoiseSVN。任意一个目录右击->TortoiseSVN->设置->网络,有学校时用的代理。去掉一试,好了没错了。

        前端时间用Subclipse时,一定要安装TortoiseSVN才可保存密码,现在又TortoiseSVN的设置Subclipse又有效。带着探索心去看eclipse的设置。Team->svn那里有一个选项:

    SVN接口:
    1.JavaHL(JNI)
    2.SVNkit(纯Java)

    原来选的是JavaHL(JNI),现在明白了。改用SVNkit试一下,现在的subclipse不会理TortoiseSVN了。

    posted @ 2008-07-26 13:34 流浪汗 阅读(3707) | 评论 (0)编辑 收藏
    有些windows操作系统被人"强奸"过的, 导致语言栏变灰色,无法显示,在任务栏里不显示.

    一般是ctfmon.exe问题. 看下C:\windows\system32\ctfmon.exe文件. 没有就下载

    http://www.blogjava.net/Files/chenlb/ctfmon_xp.rar

    安装它,

    然后在: 控制面板->区域和语言选项->语言->详细信息->高级->去掉"关闭高级文字服务"

    即可.

    那一种(百度知道): http://zhidao.baidu.com/question/31477300.html

    看你是使用2003 还是XP系统

    要是XP系统的话了就设置两个地方
    1.开始,运行,msconfig,勾选ctfmon.exe

    控制面板--区域和语言选项--语言--详细信息--高级--不要选“关闭高级文字服务”
    2.开始--控制面板--日期、时间、语言和区域设置--区域和语言选择--语言--详细信息--语言栏(选择在桌面显示语言栏 还有 选择:在任务栏中显示其他语言栏图标)

    参考: http://www.nvyouwm.cn/html/jishuwendang/huanjingpeizhi/20080602/266_2.html
    posted @ 2008-07-12 13:26 流浪汗 阅读(7552) | 评论 (9)编辑 收藏
    setTimeout(script,millisecond); 是从现在算起多少微秒后运行该代码(只运行一次)

    setInterval(script,millisecond);  是每隔多少微秒运行一次代码

    示例:
    1.执行一次
    <span id="time"></span> 秒
    <script type="text/javascript">
    var i = 1;
    var txt = document.getElementById("time");
    function addT(i) {
    txt.innerHTML
    =i;
    }
    setTimeout("addT(i++)",1000);
    </script>


    2.复制执行
    <span id="time">3</span> 秒
    <script type="text/javascript">
    var i = 1;
    var txt = document.getElementById("time");
    function addT(i) {
    txt.innerHTML
    =i;
    }
    setInterval(
    "addT(i++)",1000); 
    </script>

    setTimeout也可以做成重复执行
    <span id="time"></span> 秒
    <script type="text/javascript">
    var i = 1;
    var txt = document.getElementById("time");
    function addT(i) {
    txt.innerHTML
    =i;
    setTimeout(
    "addT(i++)",1000);
    }
    addT(i);
    </script>
    posted @ 2008-07-10 21:36 流浪汗 阅读(1070) | 评论 (0)编辑 收藏

    linux下的很软件都是 tar.gz后缀的,解压久了不用就忙了,写备忘。现我知的直接解压方法有两种

    1.gunzip与tar

    gunzip < *.tar.gz | tar -xvf -

    2.只用tar
    tar -zxvf *.tar.gz

    说明:
    z表示:通过gzip指令处理备份文件
    x表示:解压
    v表示:输出解压过程信息
    f表示:指定备份文件
    posted @ 2008-07-08 11:14 流浪汗 阅读(2510) | 评论 (0)编辑 收藏
    solr 1.3 还没有正式发布,在这里记录下从solr 1.2的主要改动:
    1. solrj     solr的java客户端,可以嵌入搜索(不是http/xml交互)
    2. multi-core     多核心——1个web应用可以用多种的搜索服务,即可以多个schema.xml
    3. search components    搜索组件。
    4. distributed search    分布式搜索。

    api的变动:

    1. org.apache.util 包下的大部分类移到org.apache.common.util包下面。
    2. org.apache.solr.request包下面的很多类移到org.apache.solr.common.params包下面。
    3. org.apache.solr.request.StandardRequestHandler 类改为 org.apache.solr.handler.StandardRequestHandler,同时它改为org.apache.solr.handler.SearchHandler的子类
    4. org.apache.solr.request.DisMaxRequestHandler 类改为 org.apache.solr.handler.DisMaxRequestHandler,同时不推荐在 StandardRequestHandler 的初始参数用'defType=dismax' 。
    posted @ 2008-07-08 10:20 流浪汗 阅读(440) | 评论 (0)编辑 收藏
        solr 分布式其实是分发,这概念像Mysql的复制。所有的索引的改变都在主服务器里,所有的查询都在从服务里。从服务器不断地(定时)从主服务器拉内容,以保持数据一致。

    先描述下我的环境:
    solr-master(192.168.1.181), solr-slave(192.168.1.155), jdke1.6.0_06, tomcat-5.5.26, solr-1.2 
    tomcat_home在 /home/chenlb/tomcat-5.5.26
    solr_home在 /home/chenlb/solr-home
    solr解压后的目录 /home/chenlb/solr-1.2.0
    最好两机可以ssh无密码交互,ssh无密码登录请看:http://www.blogjava.net/chenlb/archive/2008/07/03/212293.html

        solr的分发是用rsync的。
        快照与分发过程:

    1.snapshooter 命令在主服务器产生快照。一般在commit和optimize之后被solr调用。

    2.snappuller 命令在从服务器运行,所做的事是从主服务器拉最新的快照。 用rsync的daemon模式来运行可以获得更好的性能与更底的CPU利用率。

    3.snapinstaller 命令在从服务器运行,当从服务器从主服务器拉完快照后才执行。它会通知本地Solr服务器打开一个新的index reader,然后预热这个新index reader的缓存,此时有请求,原来的index reader继续为这此请求服务。一但预热完成,Solr 启用新的index reader,旧的被消亡。

        Solr 的Distribution(分发) 在Scripts文件里记录。在solr_home/conf/scripts.conf文件里。

    我现在这样配置:
    user=chenlb
    solr_hostname
    =localhost
    solr_port
    =8080
    rsyncd_port
    =18080
    data_dir
    =/home/chenlb/solr-home/data
    webapp_name
    =solr
    master_host
    =192.168.1.181
    master_data_dir
    =/home/chenlb/solr-home/data
    master_status_dir
    =/home/chenlb/solr-home/logs

    上面的配置两机都一样。

    1.安装好solr后启动它们,怎样在tomcat安装solr请看:http://www.blogjava.net/chenlb/archive/2008/03/25/188459.html
    [chenlb@solr-master ~]$ ./tomcat-5.5.26/bin/startup.sh

    启用且启动rsync
    [chenlb@solr-master ~]$ ./solr-home/bin/rsyncd-enable -u chenlb -v
    [chenlb@solr-master ~]$ ./solr-home/bin/rsyncd-start -u chenlb -v


    [chenlb@solr-slave ~]$ ./tomcat-5.5.26/bin/startup.sh

    2.solr-master
    先修改post.sh
    [chenlb@solr-master ~]$ cd solr-1.2.0/example/exampledocs/
    [chenlb@solr
    -master exampledocs]$ vi post.sh
    [chenlb@solr
    -master exampledocs]$
    #把http://localhost:8389/solr/update改下面的
    http://localhost:8080/solr/update

    提交数据
    [chenlb@solr-master exampledocs]$ ./post.sh *.xml

    产生快照
    [chenlb@solr-master ~]$ ./solr-home/bin/snapshooter -u chenlb -v

    说明:由于<listener event="postCommit" class="solr.RunExecutableListener">...</listener>没有设置成功(出现java.io.IOException: Cannot run program "snapshooter" (in directory "solr/bin"): java.io.IOException: error=2, No such file or directory,现在还没解决),可以只能手动生成快照(当然也可以cron)

    3.solr-slave
    启用快照下拉
    [chenlb@solr-slave ~]$ ./solr-home/bin/snappuller-enable -u chenlb -v

    拉快照
    [chenlb@solr-slave ~]$ ./solr-home/bin/snappuller -u chenlb -v

    安装
    [chenlb@solr-slave ~]$ ./solr-home/bin/snapinstaller -u chenlb -v


    现在可以在solr-slave里看结果了:
    http://192.168.1.155:8080/solr/select?q=solr
    http://192.168.1.181:8080/solr/select?q=solr

    看结果是否一样。
    posted @ 2008-07-04 16:49 流浪汗 阅读(3151) | 评论 (0)编辑 收藏

        由于svn服务器的调整,很多项目里的链接还是旧的服务器,又由于项目里有些东西还没有提交,所不能删除svn的元数据,怎样才能适应svn的迁移呢?

        我的项目全在Eclipse下面,用subclipse客户端,在subclipse找了好久没找到此功能,最后在TortoiseSVN找,找到了右击本地与svn相连的目录-->"TortoiseSVN"-->"Reloate..."在to URL那改就行了。^_^
     
        subclipse远不如TortoiseSVN强大,且它还依赖TortoiseSVN——如果没有TortoiseSVN,subclipse不能保存密码。

    posted @ 2008-07-04 11:06 流浪汗 阅读(1516) | 评论 (1)编辑 收藏
    ssh 无密码登录要使用公钥与私钥。linux下可以用用ssh-keygen生成公钥/私钥对,下面我以CentOS为例。

    有机器A(192.168.1.155),B(192.168.1.181)。现想A通过ssh免密码登录到B。

    1.在A机下生成公钥/私钥对。
    [chenlb@A ~]$ ssh-keygen -t rsa -''

    -P表示密码,-P '' 就表示空密码,也可以不用-P参数,这样就要三车回车,用-P就一次回车。
    它在/home/chenlb下生成.ssh目录,.ssh下有id_rsa和id_rsa.pub。

    2.把A机下的id_rsa.pub复制到B机下,在B机的.ssh/authorized_keys文件里,我用scp复制。
    [chenlb@A ~]$ scp .ssh/id_rsa.pub chenlb@192.168.1.181:/home/chenlb/id_rsa.pub 
    chenlb@
    192.168.1.181's password:
    id_rsa.pub                                    100%  223     0.2KB/s   00:00

    由于还没有免密码登录的,所以要输入密码。

    3.B机把从A机复制的id_rsa.pub添加到.ssh/authorzied_keys (打错了,使用下面的代码块)文件里。
    [chenlb@B ~]$ cat id_rsa.pub >> .ssh/authorized_keys
    [chenlb@B 
    ~]$ chmod 600 .ssh/authorized_keys

    authorized_keys的权限要是600

    4.A机登录B机。
    [chenlb@A ~]$ ssh 192.168.1.181
    The authenticity of host 
    '192.168.1.181 (192.168.1.181)' can't be established.
    RSA key fingerprint is 00:a6:a8:87:eb:c7:40:10:39:cc:a0:eb:50:d9:6a:5b.
    Are you sure you want to 
    continue connecting (yes/no)? yes
    Warning: Permanently added 
    '192.168.1.181' (RSA) to the list of known hosts.
    Last login: Thu Jul  
    3 09:53:18 2008 from chenlb
    [chenlb@B 
    ~]$

    第一次登录是时要你输入yes。

    现在A机可以无密码登录B机了。

    小结:登录的机子可有私钥,被登录的机子要有登录机子的公钥。这个公钥/私钥对一般在私钥宿主机产生。上面是用rsa算法的公钥/私钥对,当然也可以用dsa(对应的文件是id_dsa,id_dsa.pub)

    想让A,B机无密码互登录,那B机以上面同样的方式配置即可。

    参考:SSH-KeyGen 的用法 http://blog.163.com/chen98_2006@126/blog/static/158584272007101862513886/
    posted @ 2008-07-03 12:19 流浪汗 阅读(13712) | 评论 (3)编辑 收藏
    我用CentOS为例。

    简介:
        cron来源于希腊单词chronos(意为“时间”),是linux系统下一个自动执行指定任务的程序。例如,你想在每晚睡觉期间创建某些文件或文件夹的备份,就可以用cron来自动执行。

    CentOS的cron默认是开机启动的,如果没有开机启动可以用chkconfig
    [root@chenlb-pc ~]# chkconfig crond on

    查看crond是否开机启动
    [root@chenlb-pc ~]# chkconfig --list crond
    crond           0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭

    说明已经是开机启动。

    cron是执行crontab里的任务,所以要把任务加到crontab里。

    1.查看当前用户的任务。
    [chenlb@chenlb-pc ~]$ crontab -l
    no crontab 
    for chenlb

    现在还没有任务,可以用crontab -e来编辑任务(可以直接输入crontab是新建,然后回车,Ctrl+D保存,注意这样会覆盖以前的,不建议直接用crontab),然后再新的文件里输入以下内容。

    2.编辑任务
    [chenlb@chenlb-pc ~]$ crontab -e

    */1 * * * * echo `date` >> /home/chenlb/cron-log.txt

    上面的意思是指每一分钟打印时间放到/home/chenlb/cron-log.txt文件里,过一分钟后看是否有效,如下命令。
    [chenlb@chenlb-pc ~]$ tail /home/chenlb/cron-log.txt
    Wed Jul 
    2 15:43:01 CST 2008

    3.删除任务
    [chenlb@chenlb-pc ~]$ crontab -r


    说明:如果是root除了有以上的功能,还有-u参数为用户查看、编辑、删除任务,如用chenlb编辑任务。
    [root@chenlb-pc ~]# crontab -u chenlb -e

    解说下任务的语法:
        min hour day month week user command

    忽略用“*”,每多少的用“/多少”,多个的用“,”,到关系的用“-”

    ---------------------------------来自htmlor's blog的示例----------------------------------------------

    以下是cron语句中的字段与字段说明:

    字段 说明
    1 分钟(0-59)
    2 小时(2-24)
    3 日期(1-31)
    4 月份(1-12;或英文缩写Jan、Feb等)
    5 周几(0-6,0为周日;或单词缩写Sun、Mon等)
    6 用户名(执行命令时以此用户的身份)
    7 要执行的命令(路径)

    现在来看第一行:

    12 3 * * * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1

    这条语句将在每天的凌晨3点12分(03:12)运行 tar czf /usr/local/backups/daily/etc.tar.gz /etc 命令。>> /dev/null 2>&1 表示把所有标准输出发送到 /dev/null(linux的回收站),把标准错误输出(2)发送到和标准输出(1)同样的地方(即 /dev/null)。运行这行命令将不会产生任何输出。

    这条语句可以变得稍微复杂一点:

    30 15 13 6 1 * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1

    它将在6月13日周一的15:30运行 tar czf /usr/local/backups/daily/etc.tar.gz /etc 命令。

    以下语句可以达到同样的效果:

    30 15 13 Jun Mon * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1

    如果你想以用户joey的身份每小时的第15分钟运行某个程序,可以使用:

    15 * * * * joey /usr/bin/somecommand >> /dev/null 2>&1

    其中的星号(*)是通配符,表示cron将忽略这个字段。

    如果你想每两小时就运行某个程序,可以在小时字段里使用 */2。它将会在2点,4点,6点……22点,24点运行。具体语句如下:

    0 */2 * * * joey /usr/bin/somecommand >> /dev/null 2>&1

    cron语句中还可以使用逗号(,)来指定多个时间。例如你想在每小时的15分和30分运行某个程序,可以在分钟字段使用 15,30

    15,30 * * * * joey /usr/bin/somecommand >> /dev/null 2>&1

    如果你想在每月的第一周(即1号到7号)每天的指定时间运行某个程序,可以在日期字段使用 1-7

    15,30 */2 1-7 * * joey /usr/bin/somecommand >> /dev/null 2>&1

    这条语句将在每月的第1-7日每两小时的15分和30分(02:15,02:30……22: 15,22:30等)运行 /usr/bin/somecommand 命令。

    如果你想在每天的16:18执行一个脚本集合,可以把所有要执行的脚本放到一个目录中(如 /home/username/cron),可以使用:

    18 16 * * * root run-parts /home/username/cron >> /dev/null 2>&1

    如果你想保存某个程序的输出结果, 可以把 >> /dev/null 2>&1 替换为 >> /home/user/somecommand.log 2>&1



    参考:http://blog.htmlor.com/2006/07/25/cron_guide/
    posted @ 2008-07-02 16:23 流浪汗 阅读(5367) | 评论 (0)编辑 收藏
     Solr 涉及的术语,简单介绍下:
    • Auto-warming(自动预热) 当打开一个新的缓存时,它把在旧缓存里命中较高的键/值添加到新的缓存里。
    • Constraint(限制) 限制对象集的方法。
    • Facet(层面) 对象集的一个方面或特定的一部分,这可以用来资源分类。
    • Filter(过虑器) 它由上下方决定,可能是:
      1. Constraint(限制)的那称呼。
      2. 限制查询结果的"fq"参数。
      3. 涉及特定的Lucene的"Filter"类。
    • Solr Home Dir(Solr主目录) 又叫Solr Home Directory或Solr Home,它是Solr查找配置文件、数据、插件的主要目录,默认是./solr目录,可以JNDI配置solr/home属性,也可配置系统的solr.solr.home属性。
    • Static warming(静态预热) 当newSearcher 和 firstSearcher 的事件监听器强逼预热事件时,Solr会根据solrconfig.xml配置里的"static"查询来填充缓存。

    来源:http://wiki.apache.org/solr/SolrTerminology

     

    说的不对的地方,希望指出,一起学习。

    posted @ 2008-06-27 13:29 流浪汗 阅读(466) | 评论 (0)编辑 收藏

        两字符串相似度计算方法有好多,现对基于编距的算法的相似度计算自己总结下。

     

        简单介绍下Levenshtein Distance(LD):LD 可能衡量两字符串的相似性。它们的距离就是一个字符串转换成那一个字符串过程中的添加、删除、修改数值。

        举例:

    • 如果str1="test",str2="test",那么LD(str1,str2) = 0。没有经过转换。
    • 如果str1="test",str2="tent",那么LD(str1,str2) = 1。str1的"s"转换"n",转换了一个字符,所以是1。

    如果它们的距离越大,说明它们越是不同。

     

         Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。不会拼读,可以叫它edit distance(编辑距离)。

     

        Levenshtein distance可以用来:

    • Spell checking(拼写检查)
    • Speech recognition(语句识别)
    • DNA analysis(DNA分析)
    • Plagiarism detection(抄袭检测)

    LD用m*n的矩阵存储距离值。算法大概过程:

    1. str1或str2的长度为0返回另一个字符串的长度。
    2. 初始化(n+1)*(m+1)的矩阵d,并让第一行和列的值从0开始增长。
    3. 扫描两字符串(n*m级的),如果:str1[i] == str2[j],用temp记录它,为0。否则temp记为1。然后在矩阵d[i][j]赋于d[i-1][j]+1 、d[i][j-1]+1、d[i-1][j-1]+temp三者的最小值。
    4. 扫描完后,返回矩阵的最后一个值即d[n][m]

    最后返回的是它们的距离。怎么根据这个距离求出相似度呢?因为它们的最大距离就是两字符串长度的最大值。对字符串不是很敏感。现我把相似度计算公式定为1-它们的距离/字符串长度最大值。

     

        源码:

    package com.chenlb.algorithm;

    /**
     * 编辑距离的两字符串相似度
     * 
     * 
    @author chenlb 2008-6-24 下午06:41:55
     
    */
    public class Similarity {

        
    private int min(int one, int two, int three) {
            
    int min = one;
            
    if(two < min) {
                min 
    = two;
            }
            
    if(three < min) {
                min 
    = three;
            }
            
    return min;
        }
        
        
    public int ld(String str1, String str2) {
            
    int d[][];    //矩阵
            int n = str1.length();
            
    int m = str2.length();
            
    int i;    //遍历str1的
            int j;    //遍历str2的
            char ch1;    //str1的
            char ch2;    //str2的
            int temp;    //记录相同字符,在某个矩阵位置值的增量,不是0就是1
            if(n == 0) {
                
    return m;
            }
            
    if(m == 0) {
                
    return n;
            }
            d 
    = new int[n+1][m+1];
            
    for(i=0; i<=n; i++) {    //初始化第一列
                d[i][0= i;
            }
            
    for(j=0; j<=m; j++) {    //初始化第一行
                d[0][j] = j;
            }
            
    for(i=1; i<=n; i++) {    //遍历str1
                ch1 = str1.charAt(i-1);
                
    //去匹配str2
                for(j=1; j<=m; j++) {
                    ch2 
    = str2.charAt(j-1);
                    
    if(ch1 == ch2) {
                        temp 
    = 0;
                    } 
    else {
                        temp 
    = 1;
                    }
                    
    //左边+1,上边+1, 左上角+temp取最小
                    d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+temp);
                }
            }
            
    return d[n][m];
        }
        
        
    public double sim(String str1, String str2) {
            
    int ld = ld(str1, str2);
            
    return 1 - (double) ld / Math.max(str1.length(), str2.length()); 
        }
        
        
    public static void main(String[] args) {
            Similarity s 
    = new Similarity();
            String str1 
    = "chenlb.blogjava.net";
            String str2 
    = "chenlb.javaeye.com";
            System.out.println(
    "ld="+s.ld(str1, str2));
            System.out.println(
    "sim="+s.sim(str1, str2));
        }
    }

    不知sim方法中的公式是合理,个人认为差强人意思,^_^

     

    参考: http://www.merriampark.com/ld.htm

    posted @ 2008-06-25 10:08 流浪汗 阅读(3822) | 评论 (2)编辑 收藏
        发现中国科学技术大学有快速的CentOS的镜像。具体设置如下:
    1.以root用户进入CentOS系统。
    [root@chenlb ~]# cd /etc/yum.repos.d

    2.备份repo
    [root@chenlb yum.repos.d]# mv CentOS-Base.repo  CentOS-Base.repo.save

    3.从USTC下载新的repo
    [root@chenlb yum.repos.d]# wget http://centos.ustc.edu.cn/CentOS-Base.repo

    现在可以yum了。^_^

    链接:http://centos.ustc.edu.cn/
    posted @ 2008-06-24 23:45 流浪汗 阅读(1499) | 评论 (2)编辑 收藏
        用String.substring方法,不小心会有越界异常。现实现一个没抛出越界异常,越界就返回null,不过直接返回的再用其它方法,可能有Null异常。现还实现可以负index的,可能逆向的。
    package com.chenlb.util;   
      
    public class StringUtil {   
           
        
    /**  
         * start与end均可负数<br/>  
         * start < end正向取, start > end逆向取<br/>  
         * 示例:str="I am chenlb"<br/>  
         * StringUtil.substring(str, 0, 12) -> null<br/>  
         * StringUtil.substring(str, 12, 12) -> null<br/>  
         * StringUtil.substring(str, 12, 13) -> null<br/>  
         * StringUtil.substring(str, 4, 4) -> ""<br/>  
         * StringUtil.substring(str, 0, 4) -> "I am"<br/>  
         * StringUtil.substring(str, -4, -1) -> "enl"<br/>  
         * StringUtil.substring(str, -2, 4) -> "lbI am"<br/>  
         * StringUtil.substring(str, 4, 0) -> "ma I"<br/>  
         * StringUtil.substring(str, -1, -4) -> "lne"<br/>  
         * StringUtil.substring(str, 1, -4) -> "Iblne"<br/>  
         * StringUtil.substring(str, 0, -4) -> "blne"<br/>  
         * StringUtil.substring(str, -4, 0) -> "enlb"<br/>  
         * 
    @return 越界返回null, start==end返回空  
         * 
    @author chenlb 2008-6-18 下午12:39:51  
         
    */  
        
    public static String substring(String str, int start, int end) {   
            
    if(str == null) {   
                
    return null;   
            }   
            
    int len = str.length();   
            
    if(Math.abs(start) >= len) {   
                
    return null;   
            }   
            
    if(Math.abs(end) > len) {   
                
    return null;   
            }   
            StringBuilder sb 
    = new StringBuilder();   
            
    if(end > start) {    //正向   
                substring(sb, str, start, end);   
            } 
    else if(end == start) {   
                
    return "";   
            } 
    else {    //逆向 end < start   
                substring(sb, str, end, start);   
                sb.reverse();   
            }   
            
    return sb.toString();   
        }   
           
        
    private static void substring(StringBuilder sb, String str, int start, int end) {   
            
    int len = str.length();   
            
    if(start < 0) {   
                
    if(end < 0) {   
                    sb.append(str.substring(len
    +start, len+end));   
                } 
    else {   
                    sb.append(str.substring(len
    +start, len));   
                    sb.append(str.substring(
    0, end));   
                }   
            } 
    else {   
                sb.append(str.substring(start, end));   
            }   
        }   
    }  

    测试代码:
    public void testSubstring() {   
            String str 
    = "I am chenlb";   
               
            assertEquals(
    null, StringUtil.substring(str, 012));   
            assertEquals(
    null, StringUtil.substring(str, 1212));   
            assertEquals(
    null, StringUtil.substring(str, 1213));   
               
            assertEquals(
    "", StringUtil.substring(str, 44));   
               
            assertEquals(
    "I am", StringUtil.substring(str, 04));   
            assertEquals(
    "am", StringUtil.substring(str, 24));   
            assertEquals(
    "I am chenlb", StringUtil.substring(str, 011));   
               
            assertEquals(
    "enl", StringUtil.substring(str, -4-1));   
            assertEquals(
    "lbI am", StringUtil.substring(str, -24));   
               
            assertEquals(
    "ma I", StringUtil.substring(str, 40));   
            assertEquals(
    "lne", StringUtil.substring(str, -1-4));   
            assertEquals(
    "Iblne", StringUtil.substring(str, 1-4));   
               
            assertEquals(
    "blne", StringUtil.substring(str, 0-4));   
            assertEquals(
    "enlb", StringUtil.substring(str, -40));   
    }  
    posted @ 2008-06-24 13:53 流浪汗 阅读(546) | 评论 (0)编辑 收藏

    Windows网络命令行程序 

     
    ipconfig /all 查看配置 
    ipconfig /renew 刷新配置 
    ipconfig 管理 DNS 和 DHCP 类别 ID
    Ping 测试连接
    Arp 解决硬件地址问题
    nbtstat 解决 NetBIOS 名称问题
    netstat 显示连接统计
    tracert 跟踪网络连接
    pathping 测试路由器

    posted @ 2008-06-24 13:51 流浪汗 阅读(262) | 评论 (0)编辑 收藏

        今天运行下程序,报错说“内存不够”。在Tomcat可以扩大JVM的内存栈呢?然后看那bin目录下启动文件,找到catalina.bat文件的JAVA_OPTS(大概在103行,5.5.X),在再添加一个set JAVA_OPTS参数即可如:

    set JAVA_OPTS=%JAVA_OPTS% -Xms100m -Xmx512m 
    posted @ 2008-06-24 13:49 流浪汗 阅读(365) | 评论 (0)编辑 收藏
        前段时间学习Linux命令,偶然发现curl命令很有用。这里简单介绍下。网络上部分解析是:curl是一个利用URL语法在命令行方式下工作的文件传输工具。

       它可以取得有规律的url的内容。比如:http://www.example.com/001.html 到 http://www.example.com/100.html ,它有一种表达式可以这些内容下载下来,这功能绝对比迅雷强,迅雷只支持一个变量,curl只你喜欢可任意多。它可继点续传,提交表单……

       来看下简单的使用:

    1.查看响应的头
    curl -I http://chenlb.javaeye.com 
    现在正如robbin说的可以看下X-Runtime: 0.47101

    2.在学校要代理才可以上javaeye.com。用-x设代理
    curl -x proxy.gdut.edu.cn:8080 -I http://chenlb.javaeye.com 

    3.把返回的内容保存下来,用-o filename参数
    curl -o chenlb.html http://chenlb.javaeye.com  

    4.保存内容时要filename很烦,用一个-O参数来指定用服务器的文件名,这个批量下载很有用。
    curl -O http://baike.baidu.com/view/[1-2].htm
    批量下载百科的1.htm 2.htm两个页面,这功能够强。

    我常用的就是以上四个。

    5.很多要referer的,有-e参数可以设置
    curl -o me.html -e http://www.javaeye.com http://chenlb.javaeye.com  

    还有很多很多参数,留给大家去发现,比如:发送数据,提交表单,设置用户与密码,用什么协议啊……
    posted @ 2008-06-24 13:47 流浪汗 阅读(1489) | 评论 (0)编辑 收藏
          java命令引入jar时可以-cp参数,但时-cp不能用通配符(多个jar时什么烦要一个个写,不能*.jar),面通常的jar都在同一目录,且多于1个。前些日子找到(发现)-Djava.ext.dirs太好。

    如:

    java -Djava.ext.dirs=lib MyClass  
    posted @ 2008-06-22 23:58 流浪汗 阅读(5070) | 评论 (0)编辑 收藏
        javascript xslt 处理xml备忘录。支持firefox。
    参考:
    w3school XSLT - 客户端 http://www.w3school.com.cn/xsl/xsl_client.asp
    如何使用Javascript XSLT 处理XML文件 http://java.chinaitlab.com/advance/533787.html

    1.xml文件,cdcatalog.xml
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <catalog>
        
    <cd>
            
    <title>Empire Burlesque</title>
            
    <artist>Bob Dylan</artist>
            
    <country>USA</country>
            
    <company>Columbia</company>
            
    <price>10.90</price>
            
    <year>1985</year>
        
    </cd>
        
    <cd>
            
    <title>Hide your heart</title>
            
    <artist>Bonnie Tyler</artist>
            
    <country>UK</country>
            
    <company>CBS Records</company>
            
    <price>9.90</price>
            
    <year>1988</year>
        
    </cd>
    </catalog>

    2.xsl文件,cdcatalog.xsl
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0"
    xmlns:xsl
    ="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>

    <xsl:template match="/">
      
    <html>
      
    <body>
      
    <h2>My CD Collection</h2>
        
    <table border="1">
          
    <tr bgcolor="#9acd32">
            
    <th align="left">Title</th>
            
    <th align="left">Artist</th>
          
    </tr>
          
    <xsl:for-each select="catalog/cd">
          
    <tr>
            
    <td><xsl:value-of select="title"/></td>
            
    <td><xsl:value-of select="artist"/></td>
          
    </tr>
          
    </xsl:for-each>
        
    </table>
      
    </body>
      
    </html>
    </xsl:template>
    </xsl:stylesheet>


    3.html文件,index.html
    <html>
    <body>

    <script type="text/javascript">
    var xml;
    var xsl;
    if(typeof window.ActiveXObject != 'undefined') {
        xml 
    = new ActiveXObject("Microsoft.XMLDOM");
        xsl 
    = new ActiveXObject("Microsoft.XMLDOM");
    else if(document.implementation && document.implementation.createDocument) {    //mozilla
        xml = document.implementation.createDocument(""""null);
        xsl 
    = document.implementation.createDocument(""""null);
    }
    // Load XML 

    xml.async 
    = false;
    xml.load(
    "cdcatalog.xml");

    // Load XSL

    xsl.async 
    = false;
    xsl.load(
    "cdcatalog.xsl");

    // Transform

    if(typeof window.ActiveXObject != 'undefined') {
        document.write(xml.transformNode(xsl));
    else if(document.implementation && document.implementation.createDocument) {    //mozilla
        var xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl);
        
    // transformToDocument方式
        var result = xsltProcessor.transformToDocument(xml);
        
    var xmls = new XMLSerializer();
        document.write(xmls.serializeToString(result));
    }

    </script>

    </body>
    </html>


    posted @ 2008-05-18 19:02 流浪汗 阅读(787) | 评论 (1)编辑 收藏
         摘要: 自己实现的优先队列 PriorityQueue  阅读全文
    posted @ 2008-05-08 23:08 流浪汗 阅读(1002) | 评论 (0)编辑 收藏
        想到局域网上建一个dns服务器,昨天晚上搞了好久都不成,包括今天也发了好多时间也不能通过.最后找到

    水小筑之Blog

    http://blog.chinaunix.net/u/5302/showart_238337.html
    的博客, 帮了大忙,网上的很多文章都试过了都没有很好的结果.

    我安装的centos是单CD的服务版本.安装后已经有bind了

    1.配置文件在/etc/named.conf
    //
    // named.conf for Red Hat caching-nameserver 
    //

    options {
        directory 
    "/var/named";
        dump
    -file "/var/named/data/cache_dump.db";
            statistics
    -file "/var/named/data/named_stats.txt";
        
    /*
         
    * If there is a firewall between you and nameservers you want
         
    * to talk to, you might need to uncomment the query-source
         
    * directive below.  Previous versions of BIND always asked
         
    * questions using port 53, but BIND 8.1 uses an unprivileged
         
    * port by default.
         
    */
         
    // query-source address * port 53;
    };

    // 
    // a caching only nameserver config
    // 
    controls {
        inet 
    127.0.0.1 allow { localhost; } keys { rndckey; };
    };

    zone 
    "." IN {
        type hint;
        file 
    "named.ca";
    };

    zone 
    "localdomain" IN {
        type master;
        file 
    "localdomain.zone";
        allow
    -update { none; };
    };

    zone 
    "localhost" IN {
        type master;
        file 
    "localhost.zone";
        allow
    -update { none; };
    };

    zone 
    "chenlb.com" IN {
        type master;
        file 
    "chenlb.com.zone";
        allow
    -query { any; };
        allow
    -transfer { any; };
        allow
    -update { none; };
    };

    zone 
    "0.0.127.in-addr.arpa" IN {
        type master;
        file 
    "named.local";
        allow
    -update { none; };
    };

    zone 
    "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" IN {
            type master;
        file 
    "named.ip6.local";
        allow
    -update { none; };
    };

    zone 
    "255.in-addr.arpa" IN {
        type master;
        file 
    "named.broadcast";
        allow
    -update { none; };
    };

    zone 
    "0.in-addr.arpa" IN {
        type master;
        file 
    "named.zero";
        allow
    -update { none; };
    };

    include 
    "/etc/rndc.key";

        只要添加一个zone就行,看上面
    zone "chenlb.com" IN {
        type master;
        file 
    "chenlb.com.zone";
        allow
    -query { any; };
        allow
    -transfer { any; };
        allow
    -update { none; };
    };

    2.在/var/named/chroot/var/named/目录里建个chenlb.com.zone(上面的file),内容如下:
    $TTL    86400
    @       IN      SOA    chenlb.com.  root.chenlb.com.(
                                          
    2008050201 ; Serial
                                          
    28800      ; Refresh
                                          
    14400      ; Retry
                                          
    3600000    ; Expire
                                          
    86400 )    ; Minimum
            IN NS    chenlb.com.
            IN MX 
    10 mail.chenlb.com.
    @       IN A     
    192.168.0.60
    www     IN A     
    192.168.0.60
    ftp     IN A     
    192.168.0.60
    mail    IN A     
    192.168.0.60

    3.在/var/named目录下建链接
    # ch /var/named
    #
     ln -s /var/named/chroot/var/named/chenlb.com.zone chenlb.com.zone

    4.启动named
    # /etc/init.d/named start

    5.测试前添加nds服务地址
    # vi /etc/resolv.conf

    在加
    nameserver 192.168.0.60
    search chenlb.com
    说明:192.168.0.60是我本机地址

    现在本机下可以ping  www.chenlb.com了

    要在加的机上可以使用DNS服务,要在防火墙里允许

    6.修改/etc/sysconfig/iptables添加下面的
    -A RH-Firewall-1-INPUT -p udp -m udp --dport 53 -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT

        OK,现在在win里添加dns地址192.168.0.60就在ping  www.chenlb.com了. 呵呵


    posted @ 2008-05-02 20:46 流浪汗 阅读(1006) | 评论 (0)编辑 收藏
        昨天安装好了lighttpd,现在想试下与tomcat的一起工作。把所有的*.jsp让tomcat去处理。用到lighttpd的代理,lighttpd与tomcat比apache与tomcat要简单多。开始喜欢上了lighttpd。

    修改lighttpd的配置
    # vi /usr/local/lighttpd-1.4.19/lighttpd.conf

    去掉mod_proxy注释
    server.modules              = (
    #...
    #                               
    "mod_proxy",
    #...
                                  )

    去掉proxy.server注释
    proxy.server               = ( ".jsp" =>
                                   ( 
    "localhost" =>
                                     (
                                       
    "host" ="192.168.0.60",
                                       
    "port" =8080
                                     )
                                   )
                                 )



    重启lighttpd,然后http://192.168.0.60/index.jsp就可以看到tomcat的页面了。
    posted @ 2008-05-02 00:03 流浪汗 阅读(2270) | 评论 (0)编辑 收藏
        近几日都想玩下服务器。此文是在linux下的lighttpd安装php。参考疯狂的鼠标 的博客: http://blog.csdn.net/shined_zhang/archive/2007/10/28/1852349.aspx

    1.安装lighttpd看http://www.blogjava.net/chenlb/archive/2008/04/30/197617.html

    2.安装mysql看http://www.blogjava.net/chenlb/archive/2007/03/20/105114.html

    3.安装php,先到http://www.php.net 下载,我下载的是php-5.2.5
    # tar -zxvf php-5.2.5.tar.gz
    # cd php-
    5.2.5
    #./configure --prefix
    =/usr/local/php-5.2.5 --enable-fastcgi --with-mysql=/usr/local/mysql --enable-zend-multibyte --with-config-file-path=/usr/local/php-5.2.5/conf --enable-discard-path --enable-force-cgi-redirect
    # make
    # make install
    #mkdir /usr/local/php-
    5.2.5/conf
    #cp php.ini-dist /usr/local/php-
    5.2.5/conf/php.ini

        我在安装过程中也出过问题,说我没有找到xml2。要yum install libxml2*一下。

    4.修改lighttpd的配置。  把mod_fastcgi去掉注释。
    # vi /usr/local/lighttpd-1.4.19/lighttpd.conf

    server.modules              = (
    #
    #                               
    "mod_fastcgi",
    #
                                  )

      

        找到fastcgi.server去掉注释,修改后看起来像。
    fastcgi.server             = ( ".php" =>
                                   ( 
    "localhost" =>
                                     (
                                       
    "socket" ="/usr/local/lighttpd-1.4.19/php-fastcgi.socket",
                                       
    "bin-path" ="/usr/local/php-5.2.5/bin/php-cgi"
                                     )
                                   )
                                )


    5.php测试页面phpinfo.php放到你的www目录下。
    <?php
    echo phpinfo();
    ?>


    最后启动或重启lighttpd即可。

    posted @ 2008-05-01 16:48 流浪汗 阅读(1154) | 评论 (0)编辑 收藏
            想搭个服务器,但外面访问不到,是防火墙的原因,把端口设置一下就行。

    1.在/etc/sysconfig/iptables里添加
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

    2.重启iptables
    [root@localhost ~]# /etc/init.d/iptables restart

    3.看下状态
    [root@localhost ~]# /etc/init.d/iptables status
    posted @ 2008-05-01 14:14 流浪汗 阅读(4399) | 评论 (0)编辑 收藏
            在VMware安装一个CentOS的Sever版,终端里的内容不可滚动,不方便。在win下远程登录不错(win下有个Xshell)。默认安装ssh是有的。只是hosts访问问题。

    1.在hosts.deny文件尾添加sshd:ALL
    意思是拒绝所有访问请求
    [root@localhost ~]# vi /etc/hosts.deny

    修改后看起来如下:
    #
    #
     hosts.deny    This file describes the names of the hosts which are
    #
                   *not* allowed to use the local INET services, as decided
    #
                   by the '/usr/sbin/tcpd' server.
    #
    #
     The portmap line is redundant, but it is left to remind you that
    #
     the new secure portmap uses hosts.deny and hosts.allow.  In particular
    #
     you should know that NFS uses portmap!
    sshd:ALL

    2.在hosts.allow文件尾添加sshd:192.168.0.
    意思是允许192.168.0.1 到254的主机,内网。
    [root@localhost ~]# vi /etc/hosts.allow 
    #
    #
     hosts.allow   This file describes the names of the hosts which are
    #
                   allowed to use the local INET services, as decided
    #
                   by the '/usr/sbin/tcpd' server.
    #
    sshd:192.168.0.

    3.重启ssh
    [root@localhost ~]# /etc/rc.d/init.d/sshd restart
    停止 sshd:                                                [  确定  ]
    启动 sshd                                                  [  确定  ]


    好了,用putty和Xshell(Xmanager)可以登录了。^_^

    4.ssh增强配置
    [root@localhost ~]# vi /etc/ssh/sshd_config  ← 用vi打开SSH的配置文件

    #Protocol 2,1 ← 找到此行将行头“#”删除,再将行末的“,1”删除,只允许SSH2方式的连接
     
    Protocol 
    2 ← 修改后变为此状态,仅使用SSH2

    #ServerKeyBits 768 ← 找到这一行,将行首的“#”去掉,并将768改为1024
     
    ServerKeyBits 
    1024 ← 修改后变为此状态,将ServerKey强度改为1024比特

    #PermitRootLogin yes  ← 找到这一行,将行首的“#”去掉,并将yes改为no
     
    PermitRootLogin no  ← 修改后变为此状态,不允许用root进行登录

    #PasswordAuthentication yes ← 找到这一行,将yes改为no
     
    PasswordAuthentication no ← 修改后变为此状态,不允许密码方式的登录

    #PermitEmptyPasswords no  ← 找到此行将行头的“#”删除,不允许空密码登录
     
    PermitEmptyPasswords no  ← 修改后变为此状态,禁止空密码进行登录

    参考: http://www.centospub.com/make/sshd.html
    posted @ 2008-05-01 10:13 流浪汗 阅读(12537) | 评论 (0)编辑 收藏

    想学习在linux下建一个服务平台。
    安装lighttpd

    1.下载安装
    http://www.lighttpd.net/下载,lighttpd-1.4.19.tar.gz

    $ wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz
    $ gzip 
    -cd lighttpd-1.4.19.tar.gz | tar xf -
    $ cd lighttpd
    -1.4.19
    $ .
    /configure --prefix=/usr/local/lighttpd-1.4.19
    $ make
    $ make install


    2.copy conf

    cp doc/lighttpd.conf /usr/local/lighttpd-1.4.19/ 


    3.配置

    lighttpd.conf里server.document-root是服务目录、server.errorlog是错误日志目录,自己更改。

    4.运行

    $ cd /usr/local/lighttpd-1.4.19
    $ sbin
    /lighttpd -f lighttpd.conf


    呵呵,现在可以运行了。

    posted @ 2008-04-30 23:23 流浪汗 阅读(1327) | 评论 (2)编辑 收藏
    转载: http://www.bullog.cn/blogs/cathayan/archives/33231.aspx

    在Linux下面全面用UTF-8后就曾发现过中文排序有点不理解了,昨天才看到别人讨论,原来Unicode里面的汉字顺序居然是《康熙字典》的偏旁部首顺序。查了一下,康熙字典中的部首共有214个:

    一丨丶丿乙亅二亠人儿入八冂冖冫几凵刀力勹匕匚匸十卜卩厂厶又口囗土士夂夊夕大女子宀寸小尢尸屮山巛工己巾干幺广廴廾弋弓彐彡彳心戈戶手支攴文斗斤方无日曰月木欠止歹殳毋比毛氏气水火爪父爻爿片牙牛犬玄玉瓜瓦甘生用田疋疒癶白皮皿目矛矢石示禸禾穴立竹米糸缶网羊羽老而耒耳聿肉臣自至臼舌舛舟艮色艸虍虫血行衣襾見角言谷豆豕豸貝赤走足身車辛辰辵邑酉釆里金長門阜隶隹雨靑非面革韋韭音頁風飛食首香馬骨高髟鬥鬯鬲鬼魚鳥鹵鹿麥麻黃黍黑黹黽鼎鼓鼠鼻齊齒龍龜龠

    像在Google Docs里面,如果对Spreadsheet表格排序,中文就依据上面的部首顺序进行,部首在前的字就排在前面,如果部首相同,则算笔划数,笔划数相同的就不知道怎么排了。比如有这样的结果:

    刘孙康张李王赵钱齊

    它们的部首分别是:刀子广弓木王走金齊。

    又有:刈刘则刹剂剔,文和贝同为4划,杀和齐同为6划,而点在竖前,撇在横前,按传统应该是“江山千古”(丶丨丿一乛)的顺序。另外还有“寒来暑往”(丶一丨丿乛),“天上人间”(一丨丿丶乛),札字(一丨丿丶乛)法,礼(丶一丨丿乛)字法等。

    这样用Unicode的话,就是不加任何处理,排序出来的汉字也是很有道理的。但如果想排出拼音顺序就还得再想办法。

    查Unicode和康熙的时候,还查到了这个海峰五笔超大字符集输入法,一个用于Win系统的五笔输入法,有86和98标准,最厉害的是:收录UNICODE超大字集全部七万多中日韩汉字,同时他们还提供一个exe来安装这个字体

    CJK基本 [4E00-9FFF] 20992码位 实际20924字

    CJK扩展A [3400-4DBF] 6592码位 实际6582字

    CJK扩展B [20000-2A6DF] 42720码位 实际42711字

    CJK扩展C [2A700-2BA7F] 4224码位 实际4219字

    CJK兼容扩展 [2F800-2FA1F] 544码位 实际542字

    CJK部首扩展 [2E80-2EFF] 128码位 实际116字

    CJK康熙部首 [2F00-2FDF] 224码位 实际214字

    CJK笔画 [31C0-31EF] 48码位 实际36字

    CJK兼容 [F900-FAFF] 512个码位 实际474字
    posted @ 2008-04-21 17:23 流浪汗 阅读(1376) | 评论 (0)编辑 收藏


    log4j.properties文件

    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout
    =org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern
    =%-4r %d %-5p %l - %m%n
    log4j.logger.net.blogjava.chenlb
    =DEBUG
    log4j.rootLogger
    =INFO, stdout

    解释下pattern

    r 开始到日志的毫秒数
    d 日志的时间
    p 日志级别
    l 包括类全名.方法还有在第几行,这样在eclipse的Console里点可以直接转到源码
    m 日志的内容
    n 换行
    c 类全名
    M 日志所在的方法名
    L 日志所在的行号
    t 可能是线程启动的方法名
    F 文件名,包括后缀
    posted @ 2008-04-11 12:01 流浪汗 阅读(557) | 评论 (0)编辑 收藏
    jdk14的logging还有点麻烦,要覆盖jre/lib/logging.properties的配置,还要在启动时加-Djava.util.logging.config.file=mylogging.properties





    java 1.4
    日志纪录在java.util.logging.Level类中定义了下列日志级别常数
    Ø          SERVER表示一个严重失败。常常将有一个伴随的Throwable
    Ø          CONFIG为应用配置期间所生成的消息而设计的。
    Ø          INFO中等优先级。表示一个构件正在做什么(例如,监视一项任务的  运行进度),但不是用来帮助调试该构件。
    Ø          FINE跟踪信息。该级别和较低优先级的级别应该用来帮助调试某些类,但不应该用来总体的说明该应用的工作方式。
    Ø          FINER详细的跟踪信息。
    Ø          FINEST非常详细的跟踪信息。
    Log4jorg.apache.log4j.Level类中定义了下列日志级别常数
    Ø          FATAL表示一个严重失败。导致application的中断。
    Ø          ERROR表示一个错误事件。可以允许Application可以继续运行。
    Ø          WARN表示一个有潜在的危险。
    Ø          INFO表示一个构件正在做重要运行情况,信息比较粗糙。
    Ø          DEBUG表示一个构件详细的运行情况,用于调试Application
    Ø          ALL表示纪录所有级别的日志信息。
    Common-logging的日志级别分为6种,从低到高分别为tracedebuginfowarnerrorfatal
    Ø          FATAL表示一个严重失败。导致application的中断。
    Ø          ERROR表示一个错误事件。可以允许Application可以继续运行。
    Ø          WARN表示一个有潜在的危险。
    Ø          INFO表示一个构件正在做重要运行情况,信息比较粗糙。
    Ø          DEBUG表示一个构件详细的运行情况,用于调试Application
    Ø          TRACE非常详细的跟踪信息,仅仅用于纪录该日志而已。






    posted @ 2008-04-11 11:50 流浪汗 阅读(1065) | 评论 (0)编辑 收藏
        用ajax去请求solr服务。返回json,然后解释。让solr返回json的参数是wt=json。然后javascript用evel()解释成对象。
    我的solr会返回:auother,title,introduce这几个域。先创建一个jsp或html,如:json.jsp

    1.json.jsp关键的html内容
      <form action="select/" name="f1" method="get" onsubmit="xmlhttpPost('/solr/select'); return false;" >
          Chenlb: 
          
    <input type="text" name="q" size="80" value="文档">
          
    <input name="start" type="hidden" value="0">
        
    <input name="rows" type="hidden" value="10">
        
    <input name="indent" type="hidden" value="on">
        
    <input name="wt" type="hidden" value="">
          
    <input type="button" value=" 搜 索 " onclick="xmlhttpPost('/solr/select');">
          
    <input type="button" value=" get json " onclick="document.forms['f1'].wt.value='json';document.forms['f1'].submit();">
          
    <input type="button" value=" get xml " onclick="document.forms['f1'].wt.value='';document.forms['f1'].submit();">
      
    </form>
      
    <div style="background-color: #ccccff; height: 15px;"></div>
      
    <p>
        
    <div id="header"></div>
        
    <div id="response"></div>
        
    <table id="docs" class="tab" cellspacing="1">
            
    <tr height="25" style="background-color: #cccccc; color: #0000ff;">
                
    <td>作者</td>
                
    <td>简介</td>
                
    <td>标题</td>
                
    <td>score</td>
            
    </tr>
        
    </table>

    2.javascript部分
    function xmlhttpPost(strURL) {
        
    var xmlHttpReq = false;
        
    var self = this;
        
    if (window.XMLHttpRequest) { // Mozilla/Safari
            self.xmlHttpReq = new XMLHttpRequest(); 
        }
        
    else if (window.ActiveXObject) { // IE
            self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
        }
        
        
    var params = getstandardargs().concat(getquerystring());
        
    var strData = params.join('&');
        
        
    var header = document.getElementById("response");
        header.innerHTML 
    = strURL+'?'+strData;

        self.xmlHttpReq.open('get', strURL
    +'?'+strData+'&time='+new Date().getTime(), true);
        self.xmlHttpReq.setRequestHeader('Content
    -Type', 'application/x-www-form-urlencoded');
        self.xmlHttpReq.onreadystatechange 
    = function() {
            
    if (self.xmlHttpReq.readyState == 4) {
                updatepage(self.xmlHttpReq.responseText);
            }
        }
        self.xmlHttpReq.send(
    null);
    }

    function getstandardargs() {
        
    var params = [
            'wt
    =json'
            , 'indent
    =on'
            , 'hl
    =true'
            , 'hl.fl
    ='
            , 'fl
    =*,score'
            , 'start
    =0'
            , 'rows
    =10'
            ];

        
    return params;
    }
    function getquerystring() {
      
    var form = document.forms['f1'];
      
    var query = form.q.value;
      qstr 
    = 'q=+ encodeURI(query);    //escape
      return qstr;
    }

    // this function does all the work of parsing the solr response and updating the page.
    function updatepage(str){
      
    //document.getElementById("response").innerHTML = str;
      var rsp = eval("("+str+")"); // use eval to parse Solr's JSON response
      parse(rsp);
    }

    function parse(j) {
        
    var header = document.getElementById("header");
        
    var rh = j.responseHeader;
        
    var header_str = " 搜索: \""+rh.params.q+"\", 花了: "+rh.QTime+"ms, 共显示: "+j.response.numFound+"条记录, 总共有: "+rh.params.rows;
        header.innerHTML 
    = header_str;
        
    var docs = j.response.docs;
        
    var tab = document.getElementById("docs");
        
    for(; tab.rows.length >1; ) {
            tab.deleteRow(
    -1);
        }
        
    var tr;
        
    var td;
        
    for(var i=0; i<docs.length; i++) {
            tr 
    = tab.insertRow(-1);
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].author;
            
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].introduce;
            
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].title;
            
            td 
    = tr.insertCell(-1);
            td.innerHTML 
    = docs[i].score;
        }
       }

    3.现在可以搜索了。
    http://localhost:8080/solr/json.jsp

    solr怎么部署到Tomcat里请看:http://www.blogjava.net/chenlb/archive/2008/03/25/188459.html

    posted @ 2008-03-28 17:33 流浪汗 阅读(2072) | 评论 (0)编辑 收藏
        在Tomcat下部署solr自带的例子

    下载:
    apache-solr-1.2.0.zip http://apache.mirror.phpchina.com/lucene/solr/1.2/apache-solr-1.2.0.zip
    apache-tomcat-5.5.26.zip  http://apache.mirror.phpchina.com/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.zip

    1.solr解压到E:\solr。tomcat解压到e:\tomcat。

    2.把E:\solr\dist\apache-solr-1.2.0.war放到E:\tomcat\webapps目录下改名为solr.war。

    3.把E:\solr\example目录中的solr文件夹复制到E:\tomcat\目录下。

    4.在E:\tomcat\conf\Catalina\localhost目录下创建一个solr.xml文件,内容如下:
    <?xml version="1.0" encoding="UTF-8"?>

    <Context docBase="" debug="0" crossContext="true" >
       
    <Environment name="solr/home" type="java.lang.String" value="e:/tomcat/solr" override="true" />
    </Context>

    5.启动Tomcat。可以打开http://localhost:8080/solr/admin

    也可以不用JNDI方式。第3步把它复制到E:\tomcat\bin目录下,就不用第4步了。

    我部署时困了很久,启动Tomcat后
    org.apache.catalina.core.StandardContext start
    严重: Error filterStart
    org.apache.catalina.core.StandardContext start
    严重: Context 
    [/solr] startup failed due to previous errors

    老是怀疑solr/home配置错了。但启动日志又有Loaded SolrConfig: solrconfig.xml。又换了solr版本,又换tomcat版本。还是出现上面的错误。只是郁闷。后来怀疑jdk了。JAVA_HOME改前几天我安装的,然后一片惊喜,可以启动了。那JDK是机子本来就有的,怀疑就没有安装好,或版本太低了是:(build 1.5.0-b64),我安装的是 (build 1.5.0_15-b04)。

    终于解决,就写下来。高兴ing... 吃饭。
    posted @ 2008-03-25 12:40 流浪汗 阅读(4121) | 评论 (0)编辑 收藏
        cygwin 使用心得 转载 鱼漂 (一直漂)  http://www.eit.name/blog/read.php?171

    1.在cygwin里访问Windows盘
    cd /cygdrive/c
    cd c:

    2.整合cygwin命令到Windows中
    假设cygwin安装在d:/develop/cygwin,则将d:/develop/cygwin/bin添加到系统变量PATH中(最好加在windows前面,这样的话,有些相同的命令的话,是先执行cygwin的命令,而不是windows命令,比如find)

    就可以直接在cmd.exe下面执行tar czvf xxx.tgz ./
    基本上所有的命令都可以用了,包括ls,more,less,find,grep等。

    3.使用TGZ备份
    将cygwin的BIN加入到PATH
    建一个BAT文件:
    @echo off
    d:
    cd d:\website\8thmanage
    tar czvf 8thmanage.tgz 8thmanage

    4.Windows使用SHELL脚本
    将cygwin的BIN加入到PATH
    在$CYGWIN的目录/var/下面建一脚本t.sh,注意,t.sh里面的路径,都是相对于$CYGWIN的,里面需要访问C盘的,请用/cygdrive/c/
    在Windows下执行:
    d:\cygwin\bin\bash d:\cygwin\var\t.sh
    (可以定期执行)

    5.同步Windows系统用户
    mkpasswd -l > /etc/passwd
    mkgroup -l > /etc/group
    如果有Domain的话,需要加上-d domainname

    6.安装系统服务
    cygrunsrv

    7.cygwing下使用rsync
    a.安装rsync组件
    b.进入cygwin,配置服务器
    vi /etc/rsyncd.conf

    ...screts file=/etc/tom.ipaddr.pas

    配置文件,参考我写的另外一篇rsync的文章,注意:密码文件权限必须是0400
    chmod 0400 /etc/tom.ipaddr.pas
    c.启动服务端
    rsync --daemon

    d.客户端同步
    在客户端的cygwin下面,运行rsync同步,具体命令,请参考另外一篇rsync的文章。

    8.cygwin下使用SSHD
    a.需要安装了cygrunsrc,openssh
    b.运行ssh-host-config -y
    一路回车,直到出现CYGWIN=时,输入tty ntsec,再回车,
    (或者,增加一系统环境变量CUGWIN=nesec tty)
    c.已经安装好SSHD服务到你的Windows服务中,可以直接在服务中启动,关闭。
    (cygrunsrc -S sshd或者net start sshd)

    9.中文显示
    vi ~/.bashrc
    # 让ls和dir命令显示中文和颜色
    alias ls='ls --show-control-chars --color'
    alias dir='dir -N --color'
    # 设置为中文环境,使提示成为中文
    export LANG="zh_CN.GBK"
    # 输出为中文编码
    export OUTPUT_CHARSET="GBK"

    ~/.inputrc为
    set completion-ignore-case on
    set meta-flag on
    set output-meta on
    set convert-meta off

    cygwin.bat脚本为:
    @echo off
    set MAKE_MODE=UNIX
    posted @ 2008-03-19 09:12 流浪汗 阅读(3023) | 评论 (0)编辑 收藏
        用URLEncoder转换。

    String filename = URLEncoder.encode("中文.zip""UTF-8");      
    response.addHeader(
    "Content-Disposition","attachment;filename="+filename); 
    posted @ 2008-03-16 14:29 流浪汗 阅读(375) | 评论 (0)编辑 收藏
            加style="cursor:hand" ,firefox无效。
    posted @ 2008-03-16 12:56 流浪汗 阅读(4141) | 评论 (2)编辑 收藏
         收集于网络,自已小改动下。
    有DrawImage(ImgD, width, height) 调整图像比例的javascript函数。

    <script language="javascript">
    <!--

    var flag=false;
    function DrawImage(ImgD, width, height){
    var image=new Image();
    var iwidth = width;
    var iheight = height;
    image.src
    =ImgD.src;
    if(image.width>0 && image.height>0){
    flag
    =true;
    if(image.width/image.height>= iwidth/iheight){
    if(image.width>iwidth){
    ImgD.width
    =iwidth;
    ImgD.height
    =(image.height*iwidth)/image.width;
    }
    else{
    ImgD.width
    =image.width;
    ImgD.height
    =image.height;
    }
    ImgD.alt
    =image.width+""+image.height;
    }
    else{
    if(image.height>iheight){
    ImgD.height
    =iheight;
    ImgD.width
    =(image.width*iheight)/image.height;
    }
    else{
    ImgD.width
    =image.width;
    ImgD.height
    =image.height;
    }
    ImgD.alt
    =image.width+""+image.height;
    }
    }
    }
    //-->
    </script>
    <style type="text/css">
    .pic_size 
    {border:1px solid #CCCCCC;width:240px;height:200px;margin-top:5px;background:#FFF;}
    </style>
    <div class="pic_size"><table width="100%" height="100%"><tr><td style="text-align: center;vertical-align: middle;"><img src="my.jpg" onload = "DrawImage(this,240,200)"></td></tr></table></div>
    posted @ 2008-03-16 12:43 流浪汗 阅读(363) | 评论 (0)编辑 收藏
        在HTML内头部加以下内容。

    <link rel="shortcut icon" href="/images/my.ico" type="image/x-icon" />
    posted @ 2008-03-16 12:32 流浪汗 阅读(325) | 评论 (0)编辑 收藏
        以前想用循环来System.in (或是其它输入方式老是达不预想的效果,第一次输入后回车,不会接收下一次用户的输入)。后来才发现readline() != null才能达到效果。

    package net.blogjava.chenlb;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;

    /**
     * 重复接收用户输入一行命令
     * 
    @author chenlb 2008-3-11 下午09:24:50
     
    */
    public class UserInput {

        
        
    public static void main(String[] args) throws IOException {
            System.out.println(
    "说明: 输入QUIT退出");
            System.out.print(
    "\ninput>");
            String inputStr 
    = null;
            BufferedReader br 
    = new BufferedReader(new InputStreamReader(System.in));
            
    while((inputStr = br.readLine()) != null) {
                
    if(inputStr.equals("QUIT")) {
                    System.exit(
    0);
                }
                System.out.println(
    "你输入的是: "+inputStr);    //处理你的逻辑
                System.out.print("\ninput>");
            }

        }

    }
    posted @ 2008-03-11 21:49 流浪汗 阅读(968) | 评论 (0)编辑 收藏
         最近看下Lucene的东西,把它写下来可以看下。Lucene结构和工作原理我就不说了,网上好多。

    我的环境是Lucene2.0
    写一个简单使用Lucene的示例。此类首创建索引,然后显示索引文档的情况,最后搜索(只在content找,和在title或content里找)。

    package net.blogjava.chenlb.lucene;

    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.index.IndexReader;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.queryParser.MultiFieldQueryParser;
    import org.apache.lucene.queryParser.QueryParser;
    import org.apache.lucene.search.BooleanClause;
    import org.apache.lucene.search.Hits;
    import org.apache.lucene.search.IndexSearcher;
    import org.apache.lucene.search.Query;

    /**
     * Lucene简单使用
     * 
    @author chenlb 2008-3-8 下午11:42:55
     
    */
    public class LuceneUse {

        
    public static void main(String[] args) throws Exception {
            LuceneUse liu 
    = new LuceneUse();
            
    //索引
            IndexWriter iw = new IndexWriter("index"new StandardAnalyzer(), true);
            
    //添加要索引的Lucene文档
            Document doc = liu.createDoc("Lucene创建索引示例""chenlb""2008-03-08""Lucene索引的内容在这里,这些内容不被存储.");
            iw.addDocument(doc);
            
            doc 
    = liu.createDoc("文档2""bin""2007-10-03""这是索引的另一个文档");
            iw.addDocument(doc);
            
            doc 
    = liu.createDoc("学习内容""chenlb""2008-3-3""要努力奋斗,祝网友们天天快乐");
            iw.addDocument(doc);
            
            iw.optimize();    
    //优化
            iw.close();
            
            
    //
            System.out.println("===========索引文档内容=============");
            IndexReader reader 
    = IndexReader.open("index");
            
    for(int i=0; i<reader.numDocs(); i++) {
                Document d 
    = reader.document(i);
                liu.printDoc(d);
            }
            
            System.out.println(
    "===========以下是单域查找'天天'结果============");
            
    //单域搜索
            IndexSearcher searcher = new IndexSearcher("index");
            QueryParser parser 
    = new QueryParser("content"new StandardAnalyzer());
            Query q 
    = parser.parse("天天"); 
            
            
    long start = System.currentTimeMillis();
            Hits hits 
    = searcher.search(q);
            
    long end = System.currentTimeMillis();
            
    for(int i=0; i<hits.length(); i++) {
                liu.printDoc(hits.doc(i));
            }
            System.out.println(
    "共找到: "+hits.length()+" 个文档,花了:"+(end-start)+"ms");
            
            
    //多域搜索
            System.out.println("===========以下多域是查找'内容'结果============");
            
    //从title或content找
            q = MultiFieldQueryParser.parse("内容"new String[] {"title""content"}, new BooleanClause.Occur[] {BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD}, new StandardAnalyzer());
            start 
    = System.currentTimeMillis();
            hits 
    = searcher.search(q);
            end 
    = System.currentTimeMillis();
            
    for(int i=0; i<hits.length(); i++) {
                liu.printDoc(hits.doc(i));
            }
            System.out.println(
    "共找到: "+hits.length()+" 个文档,花了:"+(end-start)+"ms");
        }
        
        
    /**
         * 显示文档内容
         
    */
        
    private void printDoc(Document d) {
            System.out.println(
    "标题: "+d.get("title")+", 作者: "+d.get("author")+", 日期: "+d.get("date")+", 内容: "+d.get("content"));
        }
        
        
    /**
         * 创建一个Lucene文档
         
    */
        
    private Document createDoc(String title, String author, String date, String content) {
            Document doc 
    = new Document();
            doc.add(
    new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED));
            doc.add(
    new Field("author", author, Field.Store.YES, Field.Index.NO));
            doc.add(
    new Field("date", date, Field.Store.YES, Field.Index.NO));
            doc.add(
    new Field("content", content, Field.Store.YES, Field.Index.TOKENIZED));
            
    return doc;
        }
    }
    posted @ 2008-03-09 00:47 流浪汗 阅读(964) | 评论 (0)编辑 收藏
        这几天想用Java读富文档。用javax.swing.text和javax.swing.text.rtf包中的类读RTF文档时出现中文乱码问题(出现?号)。
        幸好找到 ANGEL SKY 的博客。用ISO8859_1编码转换。

    代码片断:
    String bodyText = null;
            DefaultStyledDocument styledDoc 
    = new DefaultStyledDocument();    //javax.swing.text.Document的一个实例
            try {
                InputStream is 
    = new FileInputStream(new File("data/java.swing.text读RTF文档测试.rtf"));
                
    new RTFEditorKit().read(is, styledDoc, 0);
                bodyText 
    = new String(styledDoc.getText(0, styledDoc.getLength()).getBytes("ISO8859_1"));    //提取文本
            } catch (IOException e) {
                
    throw new DocumentHandlerException("不能从RTF中摘录文本!", e);
            } 
    catch (BadLocationException e) {
                
    throw new DocumentHandlerException("不能从RTF中摘录文本!", e);
            }
            System.out.println(bodyText);
    posted @ 2008-02-01 17:05 流浪汗 阅读(2270) | 评论 (0)编辑 收藏
        这学期,应聘的时候有一些是线程相关的,虽然自己对线程编程有点概念,但没有写过经典的例子。放假了有点时候,就想写多线程的例子。

        笔试的题目类似地:一个生产者一次生产10个,满了后通知消费者,然后等待。一个消费者产品有满了就消费。到空时通知生产者,然后等待。

        那时对等待/通知机制没怎么写过,那次笔试应该写的大概对(想法对),但写的wait()和notifyAll()的位置不对。现在有时间就写了这个例子。
        描述:生产者一次生产N个产品,池中达到M就等待,通知等待的消费者。消费者有产品就消费,到没有时就通知生产者,然后等待。

    1.生产者:
    package net.blogjava.chenlb.multithreaded;

    import java.util.List;

    /**
     * 
    @author chenlb
     * 
     * 生产者.<br/>
     * 默认产品池大小M=20,产品梯阶大小N=5.在生产过程中,池的大小会超过20,但池中最大应该是M+N-1.
     
    */
    public class Producer implements Runnable {

        
    /**
         * 池默认大小
         
    */
        
    public static final int DEFALUT_SIZE = 20;
        
    /**
         * 默认一次生产的数量
         
    */
        
    public static final int DEFALUT_STEP_SIZE = 5;
        
        
    private static int PRODUCER_ID = 0;    //生产者号
        
        
    private List<Product> pool = null;
        
    private int size = DEFALUT_SIZE;
        
    private int stepSize = DEFALUT_STEP_SIZE;
        
        
    private String name = "Producer_"+(++PRODUCER_ID);    //生产者名
        
        
    private boolean isRun = true;
        
        
    /**
         * 默认产品池大小20, 默认产品增长梯阶大小5
         
    */
        
    public Producer(List<Product> pool) {
            
    this.pool = pool;
        }

        
    /**
         * 
    @param pool
         * 
    @param size 池大小
         
    */
        
    public Producer(List<Product> pool, int size) {
            
    this.pool = pool;
            
    this.size = size;
        }
        
        
        
    /**
         * 
    @param pool
         * 
    @param size 池大小
         * 
    @param stepSize 一次生产多少
         
    */
        
    public Producer(List<Product> pool, int size, int stepSize) {
            
    this.pool = pool;
            
    this.size = size;
            
    this.stepSize = stepSize;
        }

        
    public void run() {
            
    // TODO 生产者线程
            
    //int pi = 0;
            while(isRun) {//&& pi<10
                
    //pi++;
                synchronized (pool) {    //同步产品池
                    if(pool.size() >= size) {
                        
    try {
                            System.out.println(name
    +" 等待!");
                            pool.wait();    
    //同步什么就等待什么,否则抛出java.lang.IllegalMonitorStateException
                        } catch (InterruptedException e) {
                            isRun 
    = false;
                            System.out.println(name
    +" thread interrupt!");                    
                        }
                    } 
    else {
                        
                        
    for(int i=0; i<stepSize; i++) {    //一次生产stepSize个产品
                            pool.add(product());    //生产产品
                        }
                        System.out.println(
    "产品池中有: "+pool.size());
                        pool.notifyAll();    
    //通知等待的线程(主要用来通知消费者, 但生产者线程也会通知到)
                    }
                }
                
                
    try {
                    System.out.println(name
    +" 休息1秒!");
                    Thread.sleep(
    1000);    //调试用
                } catch (InterruptedException e) {
                    System.out.println(name
    +" sleep 1s thread interrupt");
                }
            }
            System.out.println(name
    +" end! pool size: "+pool.size());
        }

        
    private static int P_ID = 0;
        
    /**
         * 生产产品
         * 
    @return 产品
         
    */
        
    private Product product() {
            String name 
    = "product_"+(++P_ID);
            System.out.println(
    this.name+" 生产了: "+name);
            
    return new Production(name);
        }
        
    }


    2.消费者:

    package net.blogjava.chenlb.multithreaded;

    import java.util.List;

    /**
     * 
    @author chenlb
     * 
     * 消费者
     
    */
    public class Consumer implements Runnable {

        
    private static int C_ID = 0;    //消费者ID
        
        
    private List<Product> pool = null;
        
    private String name = "Consumer_"+(++C_ID);
        
    private boolean isRun = true;
        
    public Consumer(List<Product> pool) {
            
    this.pool = pool;
        }
        
        
    public void run() {
            
    // TODO 消费者线程
            
    //int pi = 0;
            while(isRun) {//&& pi<10
                
    //pi++;
                synchronized (pool) {
                    
    if(pool.size() < 1) {
                        
    try {
                            System.out.println(name
    +" 等待!");
                            pool.notifyAll();    
    //通知线程(主要是生产者,但也会通知到生产者线程)
                            pool.wait();
                        } 
    catch (InterruptedException e) {
                            isRun 
    = false;
                            System.out.println(name
    +" thread interrupt!");
                        }
                    } 
    else {
                        Product p 
    = pool.remove(0);    //消费
                        printProduct(p);
                        
                    }
                }
                
    try {
                    Thread.sleep(
    1000);    //调试用
                } catch (InterruptedException e) {
                    
                    System.out.println(name
    +" sleep 1s thread interrupt");
                }
            }
            System.out.println(name
    +" end! pool size: "+pool.size());
        }

        
    private void printProduct(Product p) {
            System.out.println(name
    +" 消费了: "+p.getName());
        }
    }


    3.Demo
    package net.blogjava.chenlb.multithreaded;

    import java.util.LinkedList;
    import java.util.List;

    /**
     * 
    @author chenlb
     *
     
    */
    public class Sale {

        
        
    public static void main(String[] args) {
            
    //链表产品池
            List<Product> pool = new LinkedList<Product>();
            
    //两个生产者
            Producer p1 = new Producer(pool);
            Producer p2 
    = new Producer(pool);
            
            Thread tp1 
    = new Thread(p1);
            Thread tp2 
    = new Thread(p2);
            
            tp1.start();
            tp2.start();
            
            
    //两个消费者
            Consumer c1 = new Consumer(pool);
            Consumer c2 
    = new Consumer(pool);
            
            Thread tc1 
    = new Thread(c1);
            Thread tc2 
    = new Thread(c2);
            
            tc1.start();
            tc2.start();
            
            

        }

    }

    注意:等待时候要用pool.wait()因为同步的是pool。否则会抛出java.lang.IllegalMonitorStateException

    ^_^

    代码下载
    posted @ 2008-01-24 11:36 流浪汗 阅读(532) | 评论 (0)编辑 收藏


    1.聚合关系也称"has-a"关系,组合关系也称"contains-a"关系

    2.聚合关系表示事物的整体/部分关系的较弱情况,组合关系表示事物的整体/部分关系的较强的情况.

    3.在聚合关系中,代表部分事物的可以属于多个聚合对象,可以为多个聚合对象共享,而且可以随时改变它所从属的聚合对象.代表部分事物的对象与代表聚合事物对象的生存期无关,一旦删除了它的一个聚合对象,不一定也就随即删除代表部分事物的对象.在组合关系中,代表整体事物的对象负责创建和删除代表部分事物的对象,代表部分事物只属于一个组合对象.一旦删除了组合对象,也就随即删除了相应的代表部分事物的对象.
    posted @ 2008-01-15 22:02 流浪汗 阅读(2637) | 评论 (0)编辑 收藏
          oracle 用户SYS 和 SYSTEM的默认口令:TIGER
    posted @ 2008-01-03 15:10 流浪汗 阅读(1491) | 评论 (0)编辑 收藏
    .什么是pv
      PV(page view),即页面浏览量,或点击量;通常是衡量一个网络新闻频道或网站甚至一条网络新闻的主要指标。

      高手对pv的解释是,一个访问者在24小时(0点到24点)内到底看了你网站几个页面。这里需要强调:同一个人浏览你网站同一个页面,不重复计算pv量,点100次也算1次。说白了,pv就是一个访问者打开了你的几个页面。

      PV之于网站,就像收视率之于电视,从某种程度上已成为投资者衡量商业网站表现的最重要尺度。

      pv的计算:当一个访问着访问的时候,记录他所访问的页面和对应的IP,然后确定这个IP今天访问了这个页面没有。如果你的网站到了23点,单纯IP有60万条的话,每个访问者平均访问了3个页面,那么pv表的记录就要有180万条。

        有一个可以随时查看PV流量以及你的网站世界排名的工具alexa工具条,安装吧!网编们一定要安装这个。

      .什么是uv
    uv(unique visitor),指访问某个站点或点击某条新闻的不同IP地址的人数。

      在同一天内,uv只记录第一次进入网站的具有独立IP的访问者,在同一天内再次访问该网站则不计数。独立IP访问者提供了一定时间内不同观众数量的统计指标,而没有反应出网站的全面活动。

      .什么是PR值
    PR值,即PageRank,网页的级别技术。取自Google的创始人Larry Page,它是Google排名运算法则(排名公式)的一部分,用来标识网页的等级/重要性。级别从1到10级,10级为满分。PR值越高说明该网页越受欢迎(越重要)。

      例如:一个PR值为1的网站表明这个网站不太具有流行度,而PR值为7到10则表明这个网站非常受欢迎(或者说极其重要)。

      我们可以这样说:一个网站的外部链接数越多其PR值就越高;外部链接站点的级别越高(假如Macromedia的网站链到你的网站上),网站的PR值就越高。例如:如果ABC.COM网站上有一个XYZ.COM网站的链接,那为ABC.COM网站必须提供一些较好的网站内容,从而Google会把来自XYZ.COM的链接作为它对ABC.COM网站投的一票。

      你可以下载和安装Google工具条来检查你的网站级别(PR值)。  


    详细看: http://www.skynuo.com/faq_qc7.htm

    posted @ 2007-12-31 13:51 流浪汗 阅读(365) | 评论 (0)编辑 收藏

    RIA(Rich Internet Application,富互联网应用系统)技术允许我们在因特网上以一种象使用Web一样简单的方式来部署富客户端程序。这是一个用户接口,它比用HTML能实现的接口更加健壮、反应更加灵敏和更具有令人感兴趣的可视化特性。无论将来RIA是否能够如人们所猜测的那样完全代替HTML应用系统,对于那些采用胖客户端技术运行复杂应用系统的机构来说,RIA确实提供了一种廉价的选择。

    RIA的产生背景

      基于HTML的应用程序之所以变得流行是由于应用系统的部署成本低、结构简单,且HTML易于学习和使用。很多用户和开发人员都乐于放弃由桌面计算机带来的用户界面改进,来实现对新数据和应用系统的快速访问。与丧失一些重要的UI功能相比,基于Web的方式所带来的好处要更大得多。

      然而,某些应用系统并不完全适合采用HTML技术。复杂的应用系统可能要求多次提取网页来完成一项事务处理,在某些领域中,如医药和财务领域,这往往导致交互速度低得无法接受。让我考虑一个项目管理系统:我们可以将其实现为一个HTML应用系统,但是如果用户可以看到并且操作图表、进度表和各种层次结构,那么显然会工作得更好。

      此外,虽然HTML开始走向简单,但是即使简单的交互活动也仍然需要用很多的脚本来完成。即使一个输入窗体经过仔细的布置和全面的脚本设计它从浏览器所能发送的也仅仅是简单的"名字/值"对。如果一个HTML窗体能够以XML文档形式发送和接收更复杂的数据结构,那就好多了。

      RIA利用相对健壮的客户端描述引擎,这个引擎能够提供内容密集、响应速度快和图形丰富的用户界面。除了提供一个具有各种控件(滑标、日期选择器、窗口、选项卡、微调控制器和标尺等)的界面之外,RIA一般还允许使用SVG(Scalable Vector Graphics,可伸缩向量图)或其他技术来随时构建图形。一些RIA技术甚至能够提供全活动的动画来对数据变化作出响应。

      RIA的另一个好处在于,数据能够被缓存在客户端,从而可以实现一个比基于HTML的响应速度更快且数据往返于服务器的次数更少的用户界面。对于无线设备和需要偶尔连接的设备来说,将来的趋势肯定是向富客户端的方向发展,并且会逐渐远离基于文本的Web客户端。那些运行在膝上设备上的应用系统,可以被设计成以离线方式工作,或者至少当连接丢失的时候能基本上以离线的方式工作。



    看详细的介绍(来源):http://develop.csai.cn/web/200610261348351031.htm
    posted @ 2007-12-30 14:05 流浪汗 阅读(279) | 评论 (0)编辑 收藏