可怕的事件
2008/02/07 13:58 | by edwardproAdmin ]
最近太多用php了,居然写函数老是忘记返回值。。。
无类型真可怕
JSEclipse的小问题
2008/01/17 14:20 | by edwardproAdmin ]
function AdTv(){
this.playTime=5000;
this.widthDiv=320;
this.heightDiv=240;
this.templateHead="";
this.templateRear="";
this.divName="ad_tv";
this.posHeight=0;
this.posTop=0;
}
AdTv.prototype.setDivName=function(divName){this.divName=divName;}
在打this.的时候提示不出属性的值,只能手工打,似乎只能提示方法名(function关键字装饰的语句),如果用原型法植入属性也是如此,比如:
AdTv.prototype.xxx=123;
系统同样无法自动提示-_-
RUBY 1.9有些问题
2008/01/07 12:46 | by edwardproAdmin ]
1 ruby1.9 装不上fastthread意味着 mongrel就不能用,尝试了下手工安装还是不行
2 同期发布的rails 2.0.2也貌似有些问题 老的程序用rails 1.2.3写的经过调试还是不能用
3 RMgaic 2.0貌似也不能用,这个可能和rails有关系,总是提示RMgaic模块找不到,换装1.5之后正常了
看来ruby1.9和rails的产品化道路还需要一段时间才行。
百度和google的分词对比试验
2008/01/01 19:50 | by edwardproAdmin ]
实验方法:输入错误单词“克莱死勒” (正确应该是:克莱斯勒)
实验结果:
百度:首先告诉我你是不是输错了,应该是克莱斯勒,然后列出了克莱死勒关键字的内容,当然互联网是很大的因此大家可以看到确实有人和我一样输错了,但百度除了提示一下,并没有真正起到纠错的作用。
google:google中同样提示了,词条应该是克莱斯勒,但我们注意到google在分词算法上更先进,据我他推测他拥有的应该是字级词条和词级查询以及强大的常用词库,请大家注意第一条信息:克莱 和 死勒被拆开并分别匹配,而这个时候即使我们输错了,我们得到的信息也正确得多,至少有效信息要比百度多得多,当然有人肯定会问我就是要查那个错的词呢?当然可以!
google强制查询:依然提示,但已经按照克莱死勒来查询了,这就是google!不能不让人佩服的地方。
总结:在分词技术上,基本上有那么几种流派:
1 单字流派,由于中文的复杂度,因此在没有良好词库的情况下这种单字虽然在效率上极低(相对而言)但它依然能保证查什么得到什么,相信大多数朋友和我一样也是用这种模式比较多,他不需要后期维护,也能应付不断的发展,缺陷就是有一天会遇到效率瓶颈,无论是索引抓取还是前台查询
2 单词流派,也就是著名的两分词,缺点很简单查单字不要想了,查组合由于他的 2 2 组合 运算复杂度 是 n×n-1×n-2....应该说相比 单子的n*n*n。。。要高不少,但缺点就是不能查单字,应用比较狭窄。
3 词组合,这是目前大家流行的流派,有庖丁 中科院ices 等等,我也用过但最终都因为用户词库吸收难度非常大,而且用户库对于搜索结果影响极大,对于增量类系统(老索引都是update不删除重做)这会带来灾难性后果,词库不够时往往会产生不可预料的效果,本人曾应用过一个30万的词库索引it和生活类信息,但效果简直可以用失败来形容。但对于大型系统google百度等这样的复杂度并不难,首先baidu google的索引一定是在不断删除和增长的过程,不存在真正的老数据,第二他们可以利用索引本身记录用户输入习惯用概率算法(最简单的就是贝叶斯)实现词条的分拣,上述的词条查错应该就是这类应用,而且他们会不断修正和修改分词的基础算法,因此效果和效率上都会好过单字。但本次试验也可以看到百度和google在策略上的不同。google是单字+单词模式 baidu则是单一的单词模式。从效果上来说我个人倾向于google的模式,这种智能分词的模式和底层单字模式的设计应该是效果最好的(效率也不用担心,毕竟google多的是服务器和带宽,少的是访问量-_-)
APACHE REWRITE 拾遗
2007/12/11 20:29 | by edwardproAdmin ]
/a/b/?id=3 => /index.php?action=a&method=b&id=3
这样的链接,那是错误的,现在更新我的话语,实际上apache支持这样的配置方法。今天重新研究了一遍rewirte的文档,终于发现了重要参数:
上述的链接只要这样配置:
/(.*)/(.*)/$ /index.php?action=$1&method=$2 [QSA]
这样就可以生成上述的链接了。为了不让我的错误重演,我转贴一份 后面flag的参数大全:
- 'redirect|R [=code]' (强制重定向)
给当前的URI增加前缀http://thishost[:thisport]/, 从而生成一个新的URL,强制生成一个外部重定向(external redirection,指生的URL发送到客户端,由客户端再次以新的URL发出请求,虽然新URL仍指向当前的服务器). 如果没有指定的code值,则HTTP应答以状态值302 (MOVED TEMPORARILY),如果想使用300-400(不含400)间的其它值可以通过在code的位置以相应的数字指定,也可以用标志名指定: temp (默认值), permanent, seeother.
注意,当使用这个标志时,要确实substitution是个合法的URL,这个标志只是在URL前增加http://thishost[:thisport]/前缀而已,重写操作会继续进行。如果要立即将新URL重定向,用L标志来中重写流程。 - 'forbidden|F' (强制禁止访问URL所指的资源)
立即返回状态值403 (FORBIDDEN)的应答包。将这个标志与合适的RewriteConds 联合使用,可以阻断访问某些URL。 - 'gone|G' (强制返回URL所指资源为不存在(gone))
立即返回状态值410 (GONE)的应答包。用这个标志来标记URL所指的资源永久消失了. - # 'proxy|P' (强制将当前URL送往代理模块(proxy module))
这个标志,强制将substitution当作一个发向代理模块的请求,并立即将共送往代理模块。因此,必须确保substitution串是一个合法的URI (如, 典型的情况是以http://hostname开头),否则会从代理模块得到一个错误. 这个标志,是ProxyPass指令的一个更强劲的实现,将远程请求(remote stuff)映射到本地服务器的名字空间(namespace)中来。
注意,使用这个功能必须确保代理模块已经编译到Apache 服务器程序中了. 可以用“httpd -l ”命令,来检查输出中是否含有mod_proxy.c来确认一下。如果没有,而又需要使用这个功能,则需要重新编译``httpd''程序并使用mod_proxy有效。 - 'last|L' (最后一条规则)
中止重写流程,不再对当前URL施加更多的重写规则。这相当于perl的last命令或C的break命令。 - 'next|N' (下一轮)
重新从第一条重写规则开始执行重写过程,新开的过程中的URL不应当与最初的URL相同。 这相当于Perl的next命令或C的continue命令. 千万小心不要产生死循环。 - # 'chain|C' (将当前的规则与其后续规则綑绑(chained))
当规则匹配时,处理过程与没有綑绑一样;如果规则不匹配,则綑绑在一起的后续规则也不在检查和执行。 - 'type|T=MIME-type' (强制MIME类型)
强制将目标文件的MIME-type为某MIME类型。例如,这可用来模仿mod_alias模块对某目录的ScriptAlias指定,通过强制将该目录下的所有文件的类型改为 “application/x-httpd-cgi”. - 'nosubreq|NS' (used only if no internal sub-request )
这个标志强制重写引擎跳过为内部sub-request的重写规则.例如,当mod_include试图找到某一目录下的默认文件时 (index.xxx),sub-requests 会在Apache内部发生. Sub-requests并非总是有用的,在某些情况下如果整个规则集施加到它上面,会产生错误。利用这个标志可排除执行一些规则。 - 'nocase|NC' (模板不区分大小写)
这个标志会使得模板匹配当前URL时忽略大小写的差别。 - 'qsappend|QSA' (追加请求串(query string))
这个标志,强制重写引擎为Substitution的请求串追加一部分串,则不是替换掉原来的。借助这个标志,可以使用一个重写规则给请求串增加更多的数据。 - 'noescape|NE' (不对输出结果中的特殊字符进行转义处理)
通常情况下,mod_write的输出结果中,特殊字符(如'%', '$', ';', 等)会转义为它们的16进制形式(如分别为'%25', '%24', and '%3B')。这个标志会禁止mod_rewrite对输出结果进行此类操作。 这个标志只能在 Apache 1.3.20及以后的版本中使用。 - 'passthrough|PT' (通过下一个处理器)
这个标志强制重写引擎用filename字段的值来替换内部request_rec数据结构中uri字段的值。. 使用这个标志,可以使后续的其它URI-to-filename转换器的Alias、ScriptAlias、Redirect等指令,也能正常处理RewriteRule指令的输出结果。用一个小例子来说明它的语义:如果要用mod_rewrite的重写引擎将/abc转换为/def,然后用mod_alas将/def重写为ghi,则要:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
如果PT标志被忽略,则mod_rewrite也能很好完成工作,如果., 将 uri=/abc/... 转换为filename=/def/... ,完全符合一个URI-to-filename转换器的动作。接下来 mod_alias 试图做 URI-to-filename 转换时就会出问题。
注意:如果要混合都含有URL-to-filename转换器的不同的模块的指令,必须用这个标志。最典型的例子是mod_alias和mod_rewrite的使用。 - 'skip|S=num' (跳过后面的num个规则)
当前规则匹配时,强制重写引擎跳过后续的num个规则。用这个可以来模仿if-then-else结构:then子句的最后一条rule的标志是skip=N,而N是else子句的规则条数。 - 'env|E=VAR:VAL' (设置环境变量)
设置名为VAR的环境变量的值为VAL,其中VAL中可以含有正则式的后向引用($N或%N)。这个标志可以使用多次,以设置多个环境变量。这儿设置的变量,可以在多种情况下被引用,如在XSSI或CGI中。另外,也可以在RewriteCond模板中以%{ENV:VAR}的形式被引用。
zend新王者
2007/11/28 17:39 | by edwardproAdmin ]
这次zend是基于eclipse开发的,看来以后eclipse开发人员也会很好找工作啊^^,放弃了zend studio的框架,终于得到了革命性的提升:
1 判断是否包含了当前class需要的php文件
2 终于可以做出如下的代码完成: $a->obj1->method1(); 对于php的OO开发这是非常重要的提升。
3 基于sftp等的远程断点调试,不用再为本地开发环境配置而头痛
简单试用了下目前还没有把现有工程转换过去的打算,不过新的小玩意会尝试下下,看来这个就是以后PHP开发人员的标准开发工具了。
APACHE的REWRITE还是有它的局限性
2007/11/18 20:22 | by edwardproAdmin ]
http://www.test.com/a/b/c/?id=1
类似这样的rewrite,但apache中这样的规则似乎不可行,曾经尝试了这样的正则
RewriteRule ^/(.*)/(.*)/(.*)/\?(.*)$ index.php?action=$1&method=$2&user=$3&$4
但apache似乎不领情,这样的规则貌似是解析不出来的,原因我想也只可能是本身的url定位规则问题,apache和那些容器类服务器貌似不一样,它在原则上自作聪明地解析了参数表,但这种分类对于如今的mvc系统是完全不合时宜的,看看ruby的url规则就是最好的典范,似乎对于apache来说基本无望配置出这样的rewrite规则来。个人认为的解决方案就是推出一个新的rewrite模块,这种模块本身直接把整个url串拿来匹配,不解析url,这样?就会被以querystring德身份带入,相信也就能解决这样的矛盾,同理还有很多类似的问题。
目前我用的解决方法是
用~ 代替 ? 这个让url看起来比较不专业
Resin 3.1的BUG
2007/10/20 20:20 | by edwardproAdmin ]
我的应用程序是用webflow写的,webflow经过高度分装的request,返回的时候一般这样得到:
System.out.println(context.getRequestParameters());
在resin3.1中发现如果某个参数带入了中文,结果这个参数就神奇般的消失了!当时以为是编码问题,试了半天还是这个样子,这个参数只要有中文就会神奇消失!!!
在百般无奈的情况下,我换用了resin3.0.24程序一切正常,和原来在tomcat6下完全一致。
现在猜想一下问题所在:
webflow作为一种对request的高度封装,它本身的编码肯定是不会动的,而问题就出在了resin上,它传过来之后我估计是做了一次强制转码工作,造成中文神奇的消失了,之后webflow由于读到某个参数为空,因此就不在request的hashmap中出现了,希望resin下个版本能修复这个问题,解决同志们传输中文的问题。
今天是神奇的一天发现tomcat6.0.14修复了之前的一个小bug,之前写taglib时即使你的编码是gbk但是当用writer写到页面上的时候依然会自动变成iso-8859-1之前tomcat5.5是好的,今天换了tomcat6.0.14之后发现这个问题也好了^^
发现mysql jdbc 5.0.3版本驱动的一个bug
2007/10/10 11:13 | by edwardproAdmin ]
发现在5.0.3上执行如下的sql语句 as 重命名会失效:
select a.subject as title,c.lastpost as 'desc',b.name as style,concat(a.lastpost,"") as level,concat(FROM_UNIXTIME(a.dateline),'') as publishtime,c.name as 'column',a.subject as content,a.author as author from cdb_threads a left outer join cdb_threadtypes b on b.typeid=a.typeid left outer join cdb_forums c on c.fid=a.fid LIMIT 10
表现是字段得到的map依然是subject lastpost 而不是我as出来名字 原来程序在4.0.18上完全正常,数据库升级后出现了问题。
跑到mysql官网下载了5.0.7版本的驱动之后这个问题就消失了,确认应该是 mysql jdbc驱动的问题。
以486的名义
2007/09/18 10:01 | by edwardproAdmin ]
仅以此文献给那些,不求变化,活在自我圈子中的所谓元老,用温和的语句来表达一下我最强烈的抗议!
lunece 用的高亮类
2007/08/10 18:12 | by edwardproAdmin ]
网上有很多高亮的类,但我觉得太负责了(也许他们觉得这样性能更高),我写了一个很简单采用je分词+正则解决高亮问题,实际使用下来还是不错的:
- import java.util.Iterator;
- import java.util.List;
- /**
- * @author edwardpro
- *
- */
- public class HighlightProcess {
- /**
- *
- */
- private String str;
- private String key;
- private static final String HIGH_LIGHT = ";
- public HighlightProcess(String str, String key) {
- // TODO Auto-generated constructor stub
- this.str = str;
- this.key = key;
- }
- /**
- * @return the str
- */
- public String getStr() {
- return str;
- }
- /**
- * @param str
- * the str to set
- */
- public void setStr(String str) {
- this.str = str;
- }
- public String getResult() {
- List list = WordsManager.splitStrToList(key);
- for (Iterator it = list.iterator(); it.hasNext();) {
- String target = (String) it.next();
- this.str = RegxTools.regxReplace(this.str, target, HIGH_LIGHT);
- }
- return this.str;
- }
- }
分词这边使用了一个工厂方法,用来装载词库的,返回的是JE分词对象:
java 代码- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.StringTokenizer;
- import jeasy.analysis.MMAnalyzer;
- import org.apache.log4j.Logger;
- public class WordsManager {
- private static final Logger logger = Logger.getLogger(WordsManager.class);
- private static MMAnalyzer mmanalyzer;
- private static final String DEF_SPT = "<>";
- static {
- init();
- }
- private static void init() {
- reload();
- mmanalyzer = new MMAnalyzer();
- }
- public static void reload() {
- if (AppInit.getScb().getExtDic() != null
- && !AppInit.getScb().getExtDic().equalsIgnoreCase("")) {
- File dir = new File(AppInit.getScb().getExtDic());
- File[] dics = dir.listFiles();
- // add dict file
- for (int i = 0; i < dics.length; i++) {
- try {
- MMAnalyzer.addDictionary(new FileReader(dics[i]));
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- logger.error("Read File Error", e);
- }
- }
- }
- }
- /**
- * @return the mmanalyzer
- */
- public static MMAnalyzer getMmanalyzer() {
- return mmanalyzer;
- }
- /**
- * @param mmanalyzer
- * the mmanalyzer to set
- */
- public static void setMmanalyzer(MMAnalyzer mmanalyzer) {
- WordsManager.mmanalyzer = mmanalyzer;
- }
- public static String[] splitStrToArray(String source) {
- try {
- String target = mmanalyzer.segment(source, DEF_SPT);
- String[] ts = target.split(DEF_SPT);
- return ts;
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
- public static List splitStrToList(String source) {
- List ret = new ArrayList();
- try {
- String target = mmanalyzer.segment(source, DEF_SPT);
- StringTokenizer st = new StringTokenizer(target, DEF_SPT);
- for (; st.hasMoreTokens();) {
- ret.add(st.nextToken());
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- logger.error("segment error", e);
- }
- return ret;
- }
- public static void removeTag(String content) {
- MMAnalyzer.removeWord(content);
- }
- }
正则方法:
java 代码java 代码- String reg="$1";
- public static String regxReplace(String str, String key, String rep) {
- Pattern p = Pattern.compile("(" + key + ")", Pattern.CASE_INSENSITIVE);
- Matcher m = p.matcher(str);
- return m.replaceAll(rep);
- }
原理很简单,利用分词分开,然后用这则一个个匹配掉目标中的关键字,由于实际中大部分都是替换标题和200字的描述所以并没有使用流方法,下次有时间改用流或者stringbuffer或者其他更接近分词的方法来做下看看,有什么问题,欢迎大家拍砖
- public HighlightProcess(String str, String key) {
- // TODO Auto-generated constructor stub
- this.str = str;
- this.key = key;
- }
- /**
- * @return the str
- */
- public String getStr() {
- return str;
- }
- /**
- * @param str
- * the str to set
- */
- public void setStr(String str) {
- this.str = str;
- }
- public String getResult() {
- List list = WordsManager.splitStrToList(key);
- for (Iterator it = list.iterator(); it.hasNext();) {
- String target = (String) it.next();
- this.str = RegxTools.regxReplace(this.str, target, HIGH_LIGHT);
- }
- return this.str;
- }
- }
分词这边使用了一个工厂方法,用来装载词库的,返回的是JE分词对象:
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.StringTokenizer;
- import jeasy.analysis.MMAnalyzer;
- import org.apache.log4j.Logger;
- public class WordsManager {
- private static final Logger logger = Logger.getLogger(WordsManager.class);
- private static MMAnalyzer mmanalyzer;
- private static final String DEF_SPT = "<>";
- static {
- init();
- }
- private static void init() {
- reload();
- mmanalyzer = new MMAnalyzer();
- }
- public static void reload() {
- if (AppInit.getScb().getExtDic() != null
- && !AppInit.getScb().getExtDic().equalsIgnoreCase("")) {
- File dir = new File(AppInit.getScb().getExtDic());
- File[] dics = dir.listFiles();
- // add dict file
- for (int i = 0; i < dics.length; i++) {
- try {
- MMAnalyzer.addDictionary(new FileReader(dics[i]));
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- logger.error("Read File Error", e);
- }
- }
- }
- }
- /**
- * @return the mmanalyzer
- */
- public static MMAnalyzer getMmanalyzer() {
- return mmanalyzer;
- }
- /**
- * @param mmanalyzer
- * the mmanalyzer to set
- */
- public static void setMmanalyzer(MMAnalyzer mmanalyzer) {
- WordsManager.mmanalyzer = mmanalyzer;
- }
- public static String[] splitStrToArray(String source) {
- try {
- String target = mmanalyzer.segment(source, DEF_SPT);
- String[] ts = target.split(DEF_SPT);
- return ts;
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
- public static List splitStrToList(String source) {
- List ret = new ArrayList();
- try {
- String target = mmanalyzer.segment(source, DEF_SPT);
- StringTokenizer st = new StringTokenizer(target, DEF_SPT);
- for (; st.hasMoreTokens();) {
- ret.add(st.nextToken());
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- logger.error("segment error", e);
- }
- return ret;
- }
- public static void removeTag(String content) {
- MMAnalyzer.removeWord(content);
- }
- }
正则方法:
- String reg="$1";
- public static String regxReplace(String str, String key, String rep) {
- Pattern p = Pattern.compile("(" + key + ")", Pattern.CASE_INSENSITIVE);
- Matcher m = p.matcher(str);
- return m.replaceAll(rep);
- }
原理很简单,利用分词分开,然后用这则一个个匹配掉目标中的关键字,由于实际中大部分都是替换标题和200字的描述所以并没有使用流方法,下次有时间改用流或者stringbuffer或者其他更接近分词的方法来做下看看,有什么问题,欢迎大家拍砖
使用form dom要注意的小问题
2007/08/09 00:43 | by edwardproAdmin ]
几天调一个js遇到灵异问题:
var s=$('sform');
s.action="bb.html";
<form action="a.html" id='sform'>
<input type="hidden" name="action" />
...
</form>
js目标很简单,改变form上的action的值,结果却。。。alert出来 s.action 居然是一个对象,反复想,终于发现问题就出在from里的action组件,formObj.action居然被form里的同名组件覆盖了,修改后问题解决。
ubuntu 7.04 下配置 ruby环境
2007/07/02 00:26 | by edwardproAdmin ]
准备:
sudo apt-get install build-essential
sudo apt-get install gcc
sudo apt-get install g++
sudo apt-get install libssl0.9.8
sudo apt-get install libssl0.9.8-dbg
sudo apt-get install libssl-dev
sudo apt-get install build-essential
1 安装ruby
sudo apt-get install ruby
sudo apt-get install libzlib-ruby rdoc ri irb ruby1.8-dev
2 安装 gem
sudo apt-get install libzlib-ruby
sudo apt-get install gem
sudo gem update --system
3 install rails
sudo gem install rails
4 install mongrel
sudo gem install mongrel
sudo gem install mongrel_cluster --include-dependencies
5 install imagemagic
sudo apt-get install libopenssl-ruby
sudo apt-get install libgd-ruby1.8 libyaml-ruby libzlib-ruby
sudo apt-get install imagemagick
6 install rmmagic
sudo apt-get install libmagick9-dev ruby1.8-dev
sudo gem install RMagick
参考文献 http://www.javaeye.com/post/259577
最不要忘记升级整个ubuntu哦,哈哈,总算搞得差不多了!!!
ubuntu 虽然安装东西很方便,但是它把东西拆得太散了,说实话如果ruby全手动安装是不会有这些问题的,但是回过头来表扬下ubuntu,因为它装imagemagic很容易,会自动安装一大堆的lib的这个很赞,当年在redhat上装这个花了一整天几乎,简直就是惨痛的经历,ubuntu再也不会的^^有好有坏
在ruby中用编码控制搞定编码转型的问题
2007/06/10 09:08 | by edwardproAdmin ]
一般来说网站的编码是统一的不会出现问题的,不过有时候会有这样的编码需求出现,在ruby中需要怎么做呢?
现在有这样一个例子:
一个页面需要gbk 一个页面需要utf-8
非常幸运在ruby中的默认就是utf-8即使你在html中怎么写编码比如:
<meta http-equiv="content-type" content="text/html;charset=GBK" />
其实没有太大作用,关键时刻需要使用:
headers["Content-Type"] = "text/html; charset=GBK"
来解决问题
所以解决问题的方法很简单,所有的页面都用UTF-8存储
但如果这个页面需要用GBK,只需要加上header的设定,其他页面都不要加就行了,完美的造就了两种编码混编的状态,并能保持中文编码的无误。





