iBet uBet web content aggregator. Adding the entire web to your favor.
iBet uBet web content aggregator. Adding the entire web to your favor.



Link to original content: http://web.archive.org/web/20160413105706/http://www.ftorigin.com/
n9527,我是菜鸟
The Wayback Machine - http://web.archive.org/web/20150908115939/http://www.ftorigin.com/

php面试

关于PHP目前比较常见的五大运行模式:

1)CGI(通用网关接口 / Common Gateway Interface)

2)FastCGI(常驻型CGI / Long-Live CGI)

3)CLI(命令行运行 / Command Line Interface)

4)Web模块模式(Apache等Web服务器运行的模式)

5)ISAPI(Internet Server Application Program Interface)

nginx
1、nginx配置基础
1、正则表达式匹配
~ 区分大小写匹配
~* 不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
^ 以什么开头的匹配
$ 以什么结尾的匹配
转义字符。可以转. * ?等

  • 代表任意字符
    2、文件及目录匹配
    -f和!-f用来判断是否存在文件
    -d和!-d用来判断是否存在目录
    -e和!-e用来判断是否存在文件或目录
    -x和!-x用来判断文件是否可执行
    例:
    location = /

匹配任何查询,因为所有请求都已 / 开头。但是正则表达式规则和长的块规则将被优先和查询匹配

location ^~ /images/ {

匹配任何已/images/开头的任何查询并且停止搜索。任何正则表达式将不会被测试。

location ~* .(gif|jpg|jpeg)$ {

匹配任何已.gif、.jpg 或 .jpeg 结尾的请求

另外,在子类覆盖父类的方法时一定要注意,在子类中重写的方法访问权限一定不能低于父类被覆盖的方法的访问权限。例如,如果父类中的访问权限是protected,那么在子类中重写的方法的权限就要是protected或public。父类中是public,那么子类中也只能是public

php面试题之—"用123456这六个数随机排序,要求5不能在第3位,5和6不能相连",借用了php自身随机函数实现(解题思路为不正确在重新排序,方法有些傻):

版本一:

$arr = array(1,2,3,4,5,6);
print_r(my_sort($arr));
function my_sort(&$arr = array()) {
shuffle($arr);
if ($arr[2] == 5) {
$arr = my_sort($arr);
}
//增加‘e’字符防止56或65在首个位置出现
$tem_str = 'e'.implode('', $arr);
if (strpos($tem_str, '56') || strpos($tem_str, '65')) {
$arr = my_sort($arr);
}
return $arr;
}
版本二:

/**
*用123456随机排序,要求5不能在第3位,5和6不能相连
*----------------------------------------

  • @param string $str='123456';
    *----------------------------------------
  • @author 子衿阁
  • @return void
    */
    function my_sort2($str) {
    while (true) {
    $i = str_shuffle($str);
    $a = stripos($i, '5');
    $b = stripos($i, '56');
    $c = stripos($i, '65');
    if ($a != 2 && $b === false && $c === false) {
    break;
    }
    }
    return $i;
    }
    $str = '123456';
    echo my_sort2($str);
    版本三:

/**
*用123456随机排序,要求5不能在第3位,5和6不能相连
*----------------------------------------

  • @param string $str='123456';
    *----------------------------------------
  • @author 丢失的浮尘
  • @return void
    */
    function rand_str($str){
    $a = str_shuffle($str);
    $b = strpos($a,"5");
    if($b==2 or $a[$b+1]==6 or $a[$b-1]==6){
    return rand_str($str);
    }else{
    return $a;
    }
    }

mysql乐观锁和悲观锁

乐观所和悲观锁策略:
悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续
乐观所:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新
一般在悲观锁的等待时间过长而不能接受时我们才会选择乐观锁

update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};

悲观锁介绍(百科):
悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

使用场景举例:以MySQL InnoDB为例
商品goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品status为1。假设商品的id为1。

注:要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。

(明确指定主键,并且有此数据,row lock)
(明确指定主键,若查无此数据,无lock)
(无主键,table lock)
(主键不明确,table lock)
(明确指定索引,并且有此数据,row lock)
(明确指定索引,若查无此数据,无lock)

tcp协议原理

来源:http://www.cnblogs.com/liuxiaoming/archive/2013/04/27/3047803.html

TCP三次握手原理

本文主要讲述的是

1、TCP协议三次握手原理,以及为什么要三次握手,两次握手带来的不利后果。

2、TCP协议四次挥手原理,为什么要四次挥手。

TCP协议三次握手原理:

首先,给张图片,建立TCP三次握手的直观印象。

请输入图片描述

每次握手(发送数据请求或应答)时,发送的数据为TCP报文,TCP段包含了源/目的地址,端口号,初始序号,滑动窗口大小,窗口 扩大因子,最大报文段长度等。还有一些标志位:

(1)SYN:同步序号

(2)ACK:应答回复

(3)RST:复位连接,消除旧有的同步序号

(4)PSH:尽可能的将数据送往接收进程

(5)FIN:发送方完成数据发送

(6)URG

从图中,可以看出三次握手的基本步骤是:

第一次握手:客户端向服务器端发送连接请求包SYN(syn=j),等待服务器回应;

第二次握手:服务器端收到客户端连接请求包SYN(syn=j)后,将客户端的请求包SYN(syn=j)放入到自己的未连接队列,此时服务器需要发送两个包给客户端;

  (1)向客户端发送确认自己收到其连接请求的确认包ACK(ack=j+1),向客户端表明已知道了其连接请求

  (2)向客户端发送连接询问请求包SYN(syn=k),询问客户端是否已经准备好建立连接,进行数据通信;

  即在第二次握手时服务器向客户端发送ACK(ack=j+1)和SYN(syn=k)包,此时服务器进入SYN_RECV状态。

第三次握手:客户端收到服务器的ACK(ack=j+1)和SYN(syn=k)包后,知道了服务器同意建立连接,此时需要发送连接已建立的消息给服务器;

  向服务器发送连接建立的确认包ACK(ack=k+1),回应服务器的SYN(syn=k)告诉服务器,我们之间已经建立了连接,可以进行数据通信。

  ACK(ack=k+1)包发送完毕,服务器收到后,此时服务器与客户端进入ESTABLISHED状态,开始进行数据传送。

为什么不能只两次握手?

有了三次握手的详细步骤,就可以分析为什么需要三次握手而不是两次握手了。

三次握手的目的:消除旧有连接请求的SYN消息对新连接的干扰,同步连接双方的序列号和确认号并交换TCP 窗口大小信息。

设想:如果只有两次握手,那么第二次握手后服务器只向客户端发送ACK包,此时客户端与服务器端建立连接。在这种握手规则下:

假设:如果发送网络阻塞,由于TCP/IP协议定时重传机制,B向A发送了两次SYN请求,分别是x1和x2,且因为阻塞原因,导致x1连接请求和x2连接请求的TCP窗口大小和数据报文长度不一致,如果最终x1达到A,x2丢失,此时A同B建立了x1的连接,这个时候,因为AB已经连接,B无法知道是请求x1还是请求x2同B连接,如果B默认是最近的请求x2同A建立了连接,此时B开始向A发送数据,数据报文长度为x2定义的长度,窗口大小为x2定义的大小,而A建立的连接是x1,其数据包长度大小为x1,TCP窗口大小为x1定义,这就会导致A处理数据时出错。

很显然,如果A接收到B的请求后,A向B发送SYN请求y3(y3的窗口大小和数据报长度等信息为x1所定义),确认了连接建立的窗口大小和数据报长度为x1所定义,A再次确认回答建立x1连接,然后开始相互传送数据,那么就不会导致数据处理出错了。

TCP协议释放连接需四次挥手

先看图,直观的了解下:
请输入图片描述

需四次挥手原因:由于TCP的半关闭特性,TCP连接时双全工(即数据在两个方向上能同时传递),因此,每个方向必须单独的进行关闭。这个原则就是:当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向上的连接。当一端收到一个FIN后,它必须通知应用层另一端已经终止了那个方向的数据传送。即收到一个FIN意味着在这一方向上没有数据流动了。

目的:保证服务器与客户端都能完全的接受对方发送的数据。

假设客户机A向服务器B请求释放TCP/IP连接,则:

第一次挥手:主机A向主机B发送FIN包;A告诉B,我(A)发送给你(B)的数据大小是N,我发送完毕,请求断开A->B的连接。

第二次挥手:主机B收到了A发送的FIN包,并向主机A发送ACK包;B回答A,是的,我总共收到了你发给我N大小的数据,A->B的连接关闭。

第三次挥手:主机B向主机A发送FIN包;B告诉A,我(B)发送给你(A)的数据大小是M,我发送完毕,请求断开B->A的连接。

第四次挥手:主机A收到了B发送的FIN包,并向主机B发送ACK包;A回答B,是的,我收到了你发送给我的M大小的数据,B->A的连接关闭。

http请求头header

请求的header信息

  'host':'192.168.1.220',
'Referer':'http://www.cnodejs.org/',

 'Content-Type':'application/x-www-form-urlencoded', 
  'Content-Length':'19',
  'User-Agent':'node.js-v0.8.8', 
 'cookie':'userid=123456; mycookie2=abcdefg', 
  'X-Requested-With':'xmlhttprequest',
 'Connection':'keep-alive',
 'Accept':'text/html'

服务器响应返回的数据

HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8
Pragma: public
Expires: Sat, 28 Nov 2009 05:36:25 GMT
Etag: "pub1259380237;gz"
Cache-Control: max-age=3600, public
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
X-Pingback: http://net.tutsplus.com/xmlrpc.php
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent

tips:

  1. 所有这些头部信息都可以在PHP的$_SERVER数组中找到。你也可以用getallheaders() 函数一次性获取所有的头部信息。
    在PHP中,可以通过$_SERVER['HTTP_HOST'] 或 $_SERVER['SERVER_NAME']来查看。
    在PHP中,可以通过 $_SERVER['HTTP_USER_AGENT'] 来获取User-Agent
    在PHP中用 $_SERVER["HTTP_ACCEPT_LANGUAGE"] 来获取这一信息。
    在PHP中可以使用 $_SERVER["HTTP_ACCEPT_ENCODING"] 获取该信息。 然后调用ob_gzhandler()方法时会自动检测该值,所以你无需手动检测。
    在PHP中,单一的Cookie可以访问$_COOKIE数组获得。你可以直接用$_SESSION array获取session变量。如果你需要session id,那么你可以使用session_id()函数代替cookie。
    在PHP中,可以通过 $_SERVER['HTTP_REFERER'] 获取该值。
    在PHP中你可以通过 finfo_file() 来检测文件的ime-type。

HTTP Headers 中的 HTTP请求

现在我们来看一些在HTTP headers中常见的HTTP请求信息。
Host
一个HTTP请求会发送至一个特定的IP地址,但是大部分服务器都有在同一IP地址下托管多个网站的能力,那么服务器必须知道浏览器请求的是哪个域名下的资源。

Host: rlog.cn

这只是基本的主机名,包含域名和子级域名。
User-Agent
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
这个头部可以携带如下几条信息:

浏览器名和版本号.
操作系统名和版本号.
默认语言.
这就是某些网站用来收集访客信息的一般手段。例如,你可以判断访客是否在使用手机访问你的网站,然后决定是否将他们引导至一个在低分辨率下表现良好的移动网站。

Accept-Language
Accept-Language: en-us,en;q=0.5
这个信息可以说明用户的默认语言设置。如果网站有不同的语言版本,那么就可以通过这个信息来重定向用户的浏览器。
它可以通过逗号分割来携带多国语言。第一个会是首选的语言,其它语言会携带一个“q”值,来表示用户对该语言的喜好程度(0~1)。

Accept-Encoding
Accept-Encoding: gzip,deflate
大部分的现代浏览器都支持gzip压缩,并会把这一信息报告给服务器。这时服务器就会压缩过的HTML发送给浏览器。这可以减少近80%的文件大小,以节省下载时间和带宽。

If-Modified-Since
如果一个页面已经在你的浏览器中被缓存,那么你下次浏览时浏览器将会检测文档是否被修改过,那么它就会发送这样的头部:
If-Modified-Since: Sat, 28 Nov 2009 06:38:19 GMT
如果自从这个时间以来未被修改过,那么服务器将会返回“304 Not Modified”,而且不会再返回内容。浏览器将自动去缓存中读取内容
还有一个叫Etag的HTTP头信息,它被用来确定缓存的信息是否正确,稍后我们将会解释它。

Cookie

顾名思义,他会发送你浏览器中存储的Cookie信息给服务器。

Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120; foo=bar

它是用分号分割的一组名值对。Cookie也可以包含session id。

Referer

顾名思义, 头部将会包含referring url信息。

例如,我访问Nettuts+的主页并点击了一个链接,这个头部信息将会发送到浏览器:
Referer: http://net.tutsplus.com/

Authorization

当一个页面需要授权,浏览器就会弹出一个登陆窗口,输入正确的帐号后,浏览器会发送一个HTTP请求,但此时会包含这样一个头部:

Authorization: Basic bXl1c2VyOm15cGFzcw==

包含在头部的这部分信息是base64 encoded。例如,base64_decode(‘bXl1c2VyOm15cGFzcw==’) 会被转化为 ‘myuser:mypass’ 。

HTTP Headers 中的 HTTP响应

现在让我了解一些常见的HTTP Headers中的HTTP响应信息。

Cache-Control

w3.org 的定义是:“The Cache-Control general-header field is used to specify directives which MUST be obeyed by all caching mechanisms along the request/response chain.” 其中“caching mechanisms” 包含一些你ISP可能会用到的 网关和代理信息。

例如:

Cache-Control: max-age=3600, public

“public”意味着这个响应可以被任何人缓存,“max-age” 则表明了该缓存有效的秒数。允许你的网站被缓存降大大减少下载时间和带宽,同时也提高的浏览器的载入速度。

也可以通过设置 “no-cache” 指令来禁止缓存:

Cache-Control: no-cache

更多详情请参见w3.org。

Content-Type

这个头部包含了文档的”mime-type”。浏览器将会依据该参数决定如何对文档进行解析。例如,一个html页面(或者有html输出的php页面)将会返回这样的东西:

Content-Type: text/html; charset=UTF-8

‘text’ 是文档类型,‘html’则是文档子类型。 这个头部还包括了更多信息,例如 charset。

如果是一个图片,将会发送这样的响应:

Content-Type: image/gif

浏览器可以通过mime-type来决定使用外部程序还是自身扩展来打开该文档。如下的例子降调用Adobe Reader:

Content-Type: application/pdf

直接载入,Apache通常会自动判断文档的mime-type并且添加合适的信息到头部去。并且大部分浏览器都有一定程度的容错,在头部未提供或者错误提供该信息的情况下它会去自动检测mime-type。

你可以在这里找到一个常用mime-type列表。

Content-Disposition

这个头部信息将告诉浏览器打开一个文件下载窗口,而不是试图解析该响应的内容。例如:

Content-Disposition: attachment; filename="download.zip"

他会导致浏览器出现这样的对话框:

注意,适合它的Content-Type头信息同时也会被发送

Content-Type: application/zip
Content-Disposition: attachment; filename="download.zip"

Content-Length

当内容将要被传输到浏览器时,服务器可以通过该头部告知浏览器将要传送文件的大小(bytes)。

Content-Length: 89123

对于文件下载来说这个信息相当的有用。这就是为什么浏览器知道下载进度的原因。

Etag

这是另一个为缓存而产生的头部信息。它看起来会是这样:

Etag: "pub1259380237;gz"

服务器可能会将该信息和每个被发送文件一起响应给浏览器。该值可以包含文档的最后修改日期,文件大小或者文件校验和。浏览会把它和所接收到的文档一起缓存。下一次当浏览器再次请求同一文件时将会发送如下的HTTP请求:

If-None-Match: "pub1259380237;gz"

如果所请求的文档Etag值和它一致,服务器将会发送304状态码,而不是2oo。并且不返回内容。浏览器此时就会从缓存加载该文件。

Last-Modified

顾名思义,这个头部信息用GMT格式表明了文档的最后修改时间:

Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
它提供了另一种缓存机制。浏览器可能会发送这样的请求:
If-Modified-Since: Sat, 28 Nov 2009 06:38:19 GMT

在If-Modified-Since一节我们已经讨论过了。
Location

这个头部是用来重定向的。如果响应代码为 301 或者 302 ,服务器就必须发送该头部。例如,当你访问 http://www.nettuts.com 时浏览器就会收到如下的响应:

HTTP/1.x 301 Moved Permanently
...
Location: http://net.tutsplus.com/
...

在PHP中你可以通过这种方式对访客重定向:
header('Location: http://net.tutsplus.com/');

默认会发送302状态码,如果你想发送301,就这样写:

header('Location: http://net.tutsplus.com/', true, 301);

Set-Cookie

当一个网站需要设置或者更新你浏览的cookie信息时,它就会使用这样的头部:

Set-Cookie: skin=noskin; path=/; domain=.amazon.com; expires=Sun, 29-Nov-2009 21:42:28 GMT
Set-Cookie: session-id=120-7333518-8165026; path=/; domain=.amazon.com; expires=Sat Feb 27 08:00:00 2010 GMT

每个cookie会作为单独的一条头部信息。注意,通过js设置cookie将不会体现在HTTP头中。

在PHP中,你可以通过setcookie()函数来设置cookie,PHP会发送合适的HTTP 头。

setcookie("TestCookie", "foobar");

它会发送这样的头信息:

Set-Cookie: TestCookie=foobar

如果未指定到期时间,cookie就会在浏览器关闭后被删除。

WWW-Authenticate

一个网站可能会通过HTTP发送这个头部信息来验证用户。当浏览器看到头部有这个响应时就会打开一个弹出窗。

WWW-Authenticate: Basic realm="Restricted Area"

Content-Encoding

这个头部通常会在返回内容被压缩时设置。

Content-Encoding: gzip

HTTP协议的工作原理

HTTP协议的工作原理主要包括四个步骤(如图10-1所示)。
请输入图片描述

图10-1 HTTP协议工作原理

(1)连接:Web浏览器与Web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接建立成功。

(2)请求:Web浏览器通过socket向Web服务器提交请求。HTTP的请求一般是GET或POST命令(POST用于FORM参数的传递)。GET命令的格式为:GET 路径/文件名 HTTP/1。其中,文件名指出所访问的文件,HTTP/1.0指出Web浏览器使用的HTTP版本。

(3)应答:Web浏览器提交请求后,通过HTTP协议传送给Web服务器。Web服务器接到后,进行事务处理,处理结果又通过HTTP传回给Web浏览器,从而在Web浏览器上显示出所请求的页面。例:假设客户机与www.mycompany.com:8080/mydir/index.html建立了连接,就会发送GET命令:GET /mydir/index.html HTTP/1.0。主机名为www.mycompany.com的Web服务器从它的文档空间中搜索子目录mydir的文件index.html。如果找到该文件,Web服务器把该文件内容传送给相应的Web浏览器。为了告知 Web浏览器传送内容的类型,Web服务器首先传送一些HTTP头信息,然后传送具体内容(即HTTP体信息),HTTP头信息和HTTP体信息之间用一个空行分开。其中,常用的HTTP头信息如下。

HTTP 1.0 200 Ok:这是Web服务器应答的第一行,列出服务器正在运行的HTTP版本号和应答代码。代码"200 OK"表示请求完成。

MIME_Version:1.0:它指示MIME类型的版本。

content_type:类型:这个头信息非常重要,它指示HTTP体信息的MIME类型。如:content_type:text/html指示传送的数据是HTML文档。

content_length:长度值:它指示HTTP体信息的长度(以字节为单位)。

(4)关闭连接:当应答结束后,Web浏览器与Web服务器必须断开,以保证其他Web浏览器能够与Web服务器建立连接。

来源:http://book.51cto.com/art/201108/282329.htm