This module provides functions to insert items in sorted sequences.
insort(sequence, item) inserts item into the sequence, keeping it sorted. The sequence can be any mutable sequence object that implements __getitem__ and insert.
Example: Using the bisect module to insert items in an ordered list
# File: bisect-example-1.py
import bisect
list = [10, 20, 30]
bisect.insort(list, 25)
bisect.insort(list, 15)
print list
$ python [...]
jQuery is awesome. I’ve been using it for about a year now and although I was impressed to begin with I’m liking it more and more the longer I use it and the more I find out about it’s inner workings.
I’m no jQuery expert. I don’t claim to be, so if there are mistakes [...]
一、什么是闭包?
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
这段代码有两个特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
我猜想你一定还是不理解闭包,因为你不知道闭包有什么作用,下面让我们继续探索。
二、闭包有什么作用?
简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
那 么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引 用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。(关于Javascript的垃圾回收机制将在后面详细介绍)
三、闭包内的微观世界
如 果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。
1、当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。
2、当函数a执行的时候,a会进入相应的执行环境(excution context)。
3、在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。
4、然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。
5、下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。
6、最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。
到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。
当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:
如图所示,当在函数b中访问一个变量的时候,搜索顺序是先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依 次查找,直到找到为止。如果整个作用域链上都无法找到,则返回undefined。如果函数b存在prototype原型对象,则在查找完自身的活动对象 后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。
四、闭包的应用场景
1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
以上两点是闭包最基本的应用场景,很多经典案例都源于此。
五、Javascript的垃圾回收机制
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
var name = “The [...]
1. Apache服务器和nginx的优缺点:
我们之前大量使用Apache来作为HTTPServer。
Apache具有很优秀的性能,而且通过模块可以提供各种丰富的功能。
1)首先Apache对客户端的响应是支持并发的 ,运行httpd这个daemon进程之后,它会同时产生多个孩子进程/线程,每个孩子进程/线程分别对客户端的请求进行响应;
2)另外,Apache可以提供静态和动态的服务 ,例如对于PHP的解析不是通过性能较差的CGI实现的而是通过支持PHP的模块来实现的(通常为mod_php5,或者叫做apxs2)。
3)缺点:
因此通常称为Apache的这种Server为process-based server ,也就是基于多进程的HTTPServer,因为它需要对每个用户请求创建一个孩子进程/线程进行响应;
这样的缺点是,如果并发的请求非常多(这在大型门户网站是很常见的)就会需要非常多的线程,从而占用极多的系统资源CPU和内存。因此对于并发处理不是Apache的强项。
4)解决方法:
目前来说出现了另一种WebServer,在并发方面表现更加优越,叫做asynchronous servers异步服务器。最有名的为Nginx和Lighttpd。 所谓的异步服务器是事件驱动程序模式的event-driven,除了用户的并发请求通常只需要一个单一的或者几个线程。因此占用系统资源就非常少。这几种又被称为lightweight web server。
举例,对于10,000的并发连接请求,nginx可能仅仅使用几M的内存;而Apache可能需要使用几百M的内存资源。
2. 实际中单一的使用:
1)关于单一使用Apache来作为HTTPServer的情况我们不用再多做介绍,非常常见的应用;
上面我们介绍到Apache对于PHP等服务器端脚本的支持是通过自己的模块来实现的,而且性能优越。
2)我们同样可以单单使用nginx或者lighttpd来作为HTTPServer来使用。
nginx和lighttpd和Apache类似都通过各种模块可以对服务器的功能进行丰富的扩展,同样都是通过conf配置文件对各种选项进行配置。
对于PHP等,nginx和lighttpd都没有内置的模块来对PHP进行支持,而是通过FastCGI来支持的。
Lighttpd通过模块可以提供CGI, FastCGI和SCGI等服务,Lighttpd is capable of automatically spawning FastCGI backends as well as using externally spawned processes.
nginx则没有自己提供处理PHP的功能,需要通过第三方的模块来提供对PHP进行FastCGI方式的集成。
nginx has module support for FastCGI via a built-in module, SCGI and WSGI via 3rd Party module. The user must be able to spawn the processes separately [...]
php 的 file_get_contents 可以直接用 url 读取网页,用来抓内容很方便。而且用 context 参数指定请求头。
php 文件函数能访问 http 都是用的 stream wrapper 的东西,把不同形式的流包装成文件。在用 file_get_contents 访问 http 时,stream wrapper 会把响应头放到当前作用域下的 $http_response_header 数组变量里。
$http_response_header — HTTP response headers
Description:
The $http_response_header array is similar to the get_headers() function.
When using the HTTP wrapper, $http_response_header will be populated with the HTTP response headers.
e.g.
file_get_contents(’http://www.blogbus.com/’);
var_dump($http_response_header);
同样的,可以用get_headers
get_headers
(PHP 5)
get_headers — Fetches all the headers sent [...]
1)环境:
a. 我们本地是Windows系统,然后使用VirutalBox安装一个虚拟的Linux系统。
在本地的Windows系统上分别安装nginx(侦听8080端口)和apache(侦听80端口)。在虚拟的Linux系统上安装apache(侦听80端口)。
这样我们相当于拥有了1台nginx在前端作为反向代理服务器;后面有2台apache作为应用程序服务器(可以看作是小型的server cluster。;-) );
b. nginx用来作为反向代理服务器,放置到两台apache之前,作为用户访问的入口;
nginx仅仅处理静态页面,动态的页面(php请求)统统都交付给后台的两台apache来处理。
也就是说,可以把我们网站的静态页面或者文件放置到nginx的目录下;动态的页面和数据库访问都保留到后台的apache服务器上。
c. 如下介绍两种方法实现server cluster的负载均衡。
我们假设前端nginx(为127.0.0.1:80)仅仅包含一个静态页面index.html;
后台的两个apache服务器(分别为localhost:80和158.37.70.143:80),一台根目录放置phpMyAdmin文件夹和test.php(里面测试代码为print “server1″;),另一台根目录仅仅放置一个test.php(里面测试代码为print “server2″;)。
2)针对不同请求 的负载均衡:
a. 在最简单地构建反向代理的时候 (nginx仅仅处理静态不处理动态内容,动态内容交给后台的apache server来处理),我们具体的设置为:在nginx.conf中修改:
location ~ \.php$ {
proxy_pass 158.37.70.143:80 ;
}
>这样当客户端访问localhost:8080/index.html的时候,前端的nginx会自动进行响应;
>当用户访问localhost:8080/test.php的时候(这个时候nginx目录下根本就没有该文件),但是通过上面的设置location ~ \.php$(表示正则表达式匹配以.php结尾的文件,详情参看location是如何定义和匹配的http://wiki.nginx.org/NginxHttpCoreModule) ,nginx服务器会自动pass给158.37.70.143的apache服务器了。该服务器下的test.php就会被自动解析,然后将html的结果页面返回给nginx,然后nginx进行显示(如果nginx使用memcached模块或者squid还可以支持缓存),输出结果为打印server2。
如上是最为简单的使用nginx做为反向代理服务器的例子;
b. 我们现在对如上例子进行扩展,使其支持如上的两台服务器。
我们设置nginx.conf的server模块部分,将对应部分修改为:
location ^~ /phpMyAdmin/ {
proxy_pass 127.0.0.1:80 ;
}
location ~ \.php$ {
proxy_pass 158.37.70.143:80 ;
}
上面第一个部分location ^~ /phpMyAdmin/,表示不使用正则表达式匹配(^~),而是直接匹配,也就是如果客户端访问的URL是以http://localhost:8080/phpMyAdmin/ [...]
jquery1.2以后可以通过getJSON来实现ajax跨域请求访问了。
具体方法:
非跨域的方式:
客户端
$.getJSON(’testAjax.php’,{’name’:'henson’},function (data){
alert(data.name);
});
服务端:
$arr = array (’Name’=>’Henson’,'Sex’=>’Male’);
$ret = json_encode($arr);
echo $ret;
//实际输出 {”Name”:’Henson’,”Sex”:’Male’}
跨域的方式:
客户端
$.getJSON(’http://www.tinoweb.cn/test.php?callback=?’,function (data){
//区别在于增加callback传递回访函数?代表由jquery来指定
alert(json.Name);
});
服务端:
$arr = array (’Name’=>’Henson’,'Sex’=>’Male’);
$ret = json_encode($arr);
echo $_REQUEST['callback'] . ‘(’ . $ret . ‘)’;
//服务端的区别不是直接输出数据,把回访函数加上
//实际输出 jsonp1237114865030({”Henson”:”Henson”,’Sex’:'Male’})