2011年11月 的存档

javascript 正则表达式 全局修饰符

2011年11月10日 没有评论

在javascript中定义一个正则表达式可以有如下形式:

直接量语法
var re = /pattern/attributes //注意后面不能有分号
创建 RegExp 对象的语法
var re = new RegExp(pattern, attributes);

参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。

参数 attributes 是一个可选的字符串,包含属性 “g”、”i” 和 “m”,分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。

如果用错了attributes中的g修饰符,可能会导致意想不到的结果。例如如下例子中。

var str = "abc123";
var re = /a.c/g
var result1 = re.test(str);
var result2 = re.test(str);
var result3 = re.test(str);

可能第一眼看上去result1、result2、result3都为true吧,但是执行一下,得到的结果有些让人费解,result2为false。即使在var result2 = re.test(str)前对str从新赋值为str = “abctest”,得到结果还是false。为什么会这样呢?其实造成这个结果的原因就是在正则表达式中用全局匹配修饰符(/g),如果去掉/g,即re=/a.c/得到的结果就都为true。现在知道问题出在什么地方,但更深层的原因是什么呢?查看文档,发现RegExp对象有一个lastIndex的属性,如果使用了全局修饰符,那么执行test方法后,lastIndex就会记录匹配的字符串在原始字符串中最后一位的索引加一,例如执行了var result1 = re.test(str)后lastIndex为3,如果没有发现匹配lastIndex置为0。当下次再执行时,对给定的字符串匹配不是从开头位置,而是要依据lastIndex提供的位置,由于这个原因,所以导致上例中result2的值为false。另外也能通过程序重置lastIndex值。不知道这能不能算是javascript引擎的一个Bug。

最后总结一下正则表达式相关的一些操作,RegExp对象本身的方法有exec和test,字符串对象能使用正则的方法有search、match、replace和split。其中真正能用到全局修饰符的只有match和replace,所以在考虑使用正则表达式的时候不要滥用/g。

window中findstr命令的用法

2011年11月8日 没有评论

findstr是window系统自带的命令,用途是查找指定的一个或多个文件文件中包含(或通过参数 /V来控制不包含)某些特定字符串的行,并将该行完整的信息打印出来,或者打印查询字符串所在的文件名。其用途和用法都类似linux下的grep命令,基本用法如下:

findstr 参数 "搜索字符串" [[drive:][path]filename[ ...]]

其中参数可以组合多个,[drive:]、[path]是可选的,如果省略,默认是查找当前目录,至少指定一个文件,可以同时指定多个,用空格分隔,另外文件名可以使用通配符,例如所有文本文件,就可以写成 *.txt 即可。

另外findstr的输入也可以接受来自管道的输出,例如命令:netstat -nao | findstr “8080″ 可以查看命令netstat输出的信息中所有包含“8080”字符串的行。

用法1:打印出文件demo.txt中包含“hello world”字符串的行的完整信息(不区分大小写),并且打印出行号。

findstr /NI /C:"hello world" demo.txt

注意:不能漏写”/C:”,否则含有hello或者world的行都作为结果打印出来。

用法2:找出并打印出目录C:\deom下(包括其子目录)所有含有字符串“netingcn.com”的文本文件的文件名。

findstr /MSI "netingcn.com" *.txt

通过findstr /? 可以看到帮助信息,帮助信息如下:

在文件中寻找字符串。

FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/F:file]
        [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
        strings [[drive:][path]filename[ ...]]

  /B        在一行的开始配对模式。
  /E        在一行的结尾配对模式。
  /L        按字使用搜索字符串。
  /R        将搜索字符串作为一般表达式使用。
  /S        在当前目录和所有子目录中搜索匹配文件。
  /I        指定搜索不分大小写。
  /X        打印完全匹配的行。
  /V        只打印不包含匹配的行。
  /N        在匹配的每行前打印行数。
  /M        如果文件含有匹配项,只打印其文件名。
  /O        在每个匹配行前打印字符偏移量。
  /P        忽略有不可打印字符的文件。
  /OFF[LINE] 不跳过带有脱机属性集的文件。
  /A:attr   指定有十六进位数字的颜色属性。请见 "color /?"
  /F:file   从指定文件读文件列表 (/ 代表控制台)。
  /C:string 使用指定字符串作为文字搜索字符串。
  /G:file   从指定的文件获得搜索字符串。 (/ 代表控制台)。
  /D:dir    查找以分号为分隔符的目录列表
  strings   要查找的文字。
  [drive:][path]filename
            指定要查找的文件。

除非参数有 /C 前缀,请使用空格隔开搜索字符串。
例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或
"there" 。  'FINDSTR /C:"hello there" x.y' 文件 x.y  寻找
"hello there"。

一般表达式的快速参考:
  .        通配符: 任何字符
  *        重复: 以前字符或类别出现零或零以上次数
  ^        行位置: 行的开始
  $        行位置: 行的终点
  [class]  字符类别: 任何在字符集中的字符
  [^class] 补字符类别: 任何不在字符集中的字符
  [x-y]    范围: 在指定范围内的任何字符
  \x       Escape: 元字符 x 的文字用法
  \    字位置: 字的结束

参数/B等价于在搜索字符串前的”^”符号。

参数/E等价于在搜索字符串后的”$”符号。

参数/S会对目录进行递归查询。

参数/C就是强制把输入的子字符串作为查询目标,否则输入的字符串中有空格的话,findstr会以“或”的逻辑来进行查找。

参数/D可以实现对多个存放在不同路径的文件夹进行查询。

分类: 其它 标签: ,

深入理解JavaScript定时机制

2011年11月7日 没有评论

本文系转载,原文出处http://www.laruence.com/2009/09/23/1089.html

JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如:

setTimeout(function() {
    alert('你好!');
}, 0);
setInterval(callbackFunction, 100);

认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了.

同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!

但随着JavaScript应用开发经验不断的增加和丰富,有一天你发现了一段怪异的代码而百思不得其解:

div.onclick = function(){
        setTimeout(function() {
                document.getElementById('inputField').focus();
        }, 0);
};

既然是0毫秒后执行,那么还用setTimeout干什么, 此刻, 坚定的信念已开始动摇.

直到最后某一天 , 你不小心写了一段糟糕的代码:

setTimeout(function() {
        while (true) {
        }
}, 100);
setTimeout(function() {
        alert('你好!');
}, 200);
setInterval(callbackFunction, 200);

第一行代码进入了死循环,但不久你就会发现,第二,第三行并不是预料中的事情,alert问候未见出现,callbacKFunction也杳无音讯!

这时你彻底迷惘了,这种情景是难以接受的,因为改变长久以来既定的认知去接受新思想的过程是痛苦的,但情事实摆在眼前,对JavaScript真理的探求并不会因为痛苦而停止,下面让我们来展开JavaScript线程和定时器探索之旅!

拔开云雾见月明,出现上面所有误区的最主要一个原因是:潜意识中认为,JavaScript引擎有多个线程在执行,JavaScript的定时器回调函数是异步执行的.

而事实上的,JavaScript使用了障眼法,在多数时候骗过了我们的眼睛,这里背光得澄清一个事实:

JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序.

JavaScript引擎用单线程运行也是有意义的,单线程不必理会线程同步这些复杂的问题,问题得到简化.

那么单线程的JavaScript引擎是怎么配合浏览器内核处理这些定时器和响应浏览器事件的呢?下面结合浏览器内核处理方式简单说明.

浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假如某一浏览器内核的实现至少有三个常驻线程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产生不同的异步事件,下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的.虽然每个浏览器内核实现细节不同,但这其中的调用原理都是大同小异.

由图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,这些任务可以源自 JavaScript引擎当前执行的代码块,如调用setTimeout添加一个任务,也可来自浏览器内核的其它线程,如界面元素鼠标点击事件,定时触发器时间到达通知,异步请求状态变更通知等.从代码角度看来任务实体就是各种回调函数,JavaScript引擎一直等待着任务队列中任务的到来.由于单线程关系,这些任务得进行排队,一个接着一个被引擎处理.

上图t1-t2..tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务,假设现在是t1时刻,引擎运行在t1对应的任务方块代码内,在这个时间点内,我们来描述一下浏览器内核其它线程的状态.

t1时刻,GUI渲染线程:

该线程负责渲染浏览器界面HTML元素,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行.本文虽然重点解释JavaScript定时机制,但这时有必要说说渲染线程,因为该线程与JavaScript引擎线程是互斥的,这容易理解,因为 JavaScript脚本是可操纵DOM元素,在修改这些元素属性同时渲染界面,那么渲染线程前后获得的元素数据就可能不一致了.

在JavaScript引擎运行脚本期间,浏览器渲染线程都是处于挂起状态的,也就是说被”冻结”了.

所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来.

GUI事件触发线程:

JavaScript脚本的执行不影响html元素事件的触发,在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标点击事件正在等待处理.

定时触发线程:

注意这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件也是异步事件.

由图可知,在这t1的时间段内,继鼠标点击事件触发后,先前已设置的setTimeout定时也到达了,此刻对JavaScript引擎来说,定时触发线程产生了一个异步定时事件并放到任务队列中, 该事件被排到点击事件回调之后,等待处理.
同理, 还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理.

可见,假如时间段t1非常长,远大于setInterval的定时间隔,那么定时触发线程就会源源不断的产生异步定时事件并放到任务队列尾而不管它们是否已被处理,但一旦t1和最先的定时事件前面的任务已处理完,这些排列中的定时事件就依次不间断的被执行,这是因为,对于JavaScript引擎来说,在处理队列中的各任务处理方式都是一样的,只是处理的次序不同而已.

t1过后,也就是说当前处理的任务已返回,JavaScript引擎会检查任务队列,发现当前队列非空,就取出t2下面对应的任务执行,其它时间依此类推,由此看来:

如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是没法被执行的.

相信您现在已经很清楚JavaScript是否可多线程,也了解理解JavaScript定时器运行机制了,下面我们来对一些案例进行分析:
案例1:setTimeout与setInterval

setTimeout(function() {
        /* 代码块... */
        setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
        /*代码块... */
}, 10);

这两段代码看一起效果一样,其实非也,第一段中回调函数内的setTimeout是JavaScript引擎执行后再设置新的setTimeout 定时, 假定上一个回调处理完到下一个回调开始处理为一个时间间隔,理论两个setTimeout回调执行时间间隔>=10ms .第二段自setInterval设置定时后,定时触发线程就会源源不断的每隔十秒产生异步定时事件并放到任务队列尾,理论上两个setInterval 回调执行时间间隔

案例2:ajax异步请求是否真的异步?

很多同学朋友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行 onreadystatechange所设置的函数.

分类: web前端 标签: ,

URL编码问题

2011年11月5日 没有评论

一般来说,URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。这意味着,如果URL中有汉字,就必须编码后使用。但是麻烦的是,RFC 1738没有规定具体的编码方法,而是交给应用程序(浏览器)自己决定。这导致“URL编码”成为了一个混乱的领域。

下面就让我们看看,“URL编码”到底有多混乱。我会依次分析四种不同的情况,在每一种情况中,浏览器的URL编码方法都不一样。

  • 情况1:网址路径中包含汉字

网址路径的编码,不管是IE还是Firefox都是用的是utf-8编码。

  • 情况2:查询字符串包含汉字

对于查询字符串的编码,需要依赖操作系统,用的是操作系统的默认编码。一般来说Window中文操作系统默认为GB2312编码,所以查询字符串的编码使用GB2312。

  • 情况3:Get方法生成的URL包含汉字

在已打开的网页上,当用用Get或Post方法发出HTTP请求,例如提交表单。这时编码方法由网页的编码决定,也就是由HTML源码中字符集的设定决定。

  • 情况4:Ajax调用的URL包含汉字

在Ajax调用中,IE和Firefox的处理方式完全不一样,IE总是采用GB2312编码(操作系统的默认编码),而Firefox总是采用utf-8编码。

面对如此多种情况,解决的办法是借助于javascript,通过js对url进行编码,然后再提交给服务器,不要给浏览器插手的机会。因为Javascript的输出总是一致的,所以就保证了服务器得到的数据是格式统一的。

javascript的编码函数可以使用encodeURI()或encodeURIComponent(),还有一个escape(),不提倡使用,对于encodeURI和encodeURIComponent输出的结果都是utf-8形式,并且在每个字节前加上%,所以服务器端就可以进行按utf-8统一解码,encodeURI和encodeURIComponent区别如下:。

encodeURI不编码字符有82个:!,#,$,&,’,(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z

encodeURIComponent不编码字符有71个:!, ‘,(,),*,-,.,_,~,0-9,a-z,A-Z

本文系转载,原文地址:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

分类: web前端 标签:

Google网站管理员工具左边菜单无法导航

2011年11月4日 没有评论

今天(2011-11-04)使用Google网站管理员工具时候,Firefox(版本3.6.13)下发现无法使用左边的菜单进行导航,并且左边有一红色的小方块,当鼠标点击某一个具体导航菜单时出现水平方向的滚动条覆盖在上面,导致无法点击,具体症状如下图:
查看大图
当在IE6下查看,页面布局惨不忍睹啊,难道google彻底放弃IE6了么,截图如下:

查看大图初步看了一下,造成水平滚动条的原因是在css文件4046579917-wmt.css中#navigation .item 设置的overflow:auto导致的。本想把这个问题提交Google,在帮助里找了一圈,没有发现能供接受Bug(应该可以算作吧)反馈的地址。好在safari下还能用,就凑合看看算了。

解决ssh空闲一段时间后自动断开的方法

2011年11月3日 没有评论

用客户端工具,例如securecrt连接linux服务器,有的会出现过一段时间没有任何操作,客户端与服务器就断开了连接。造成这个的原因,主要是因为客户端与服务器之间存在路由器,防火墙以及为了本身的安全性,在超过特定的时间后就会把空闲连接断开。或者是服务器端设置了断开空闲连接。那么解决的方法有两种,一是从服务器着手,一是在客户端工具上下手。

  • 服务器端

修改/etc/ssh/sshd_config配置文件 ClientAliveInterval 300(默认为0),参数的是意思是每5分钟,服务器向客户端发一个消息,用于保持连接,使用service sshd reload 让其修改后生效。如果发现还是有问题,可以试着把300设置小一点,例如60。

  • 客户端工具

securecrt的设置方法:会话选项 –> 终端 –> 反空闲–>选中发送协议 NO-OP(p) 每 60 秒

putty的设置方法:putty -> Connection -> Seconds between keepalives ( 0 to turn off ), 默认为0, 改为300

分类: Linux 标签: , ,

php-fpm进程管理方式

2011年11月1日 没有评论

目前最新5.3.x的php-fpm,有两种管理进程的方式,分别是static和dynamic。

如果设置成static,进程数自始至终都是pm.max_children指定的数量,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers配置将没有作用。

如果设置成dynamic,则进程数是动态的,最开始是pm.start_servers指定的数量,如果请求较多,则会自动增加,但不超过pm.max_children指定的数量,同时保证空闲的进程数不小于pm.min_spare_servers,如果进程数较多,也会进行相应清理,保证多余的进程数不多于pm.max_spare_servers。

当php-fpm启动后,一个php-cgi进程约战3M内存,但是当它们处理过一些请求后,有些内存是释放不掉的,占用的内存能达到20M-30M不等。

对于内存比较吃紧,同时并发量不是很大的应用,可以考虑采用static的方式,这样可以很好的控制php-fpm的所消耗的总内存数,让系统更加平稳运行。另外由于并发量很小,可以适当的把设置pm.max_requests小一些,以便让php-fpm进程有机会重启,从而释放其占用的内存。

无觅相关文章插件,快速提升流量