转载 遇到过的一些php笔试题

遇到过的一些php笔试题

一、linux的多线程和多进程有什么区别?何时使用多线程,何时使用多进程?javascript

答:(1)进程资源调度的最小单位,线程是cpu调度的最小单位;多进程开销大,多线程开销小,这是最基本的区别;一个进程里面可能有不少线程,把进程分解为线程以后就能够有效利用cpu和内存php

     (2)当须要频繁建立和销毁时优先选用多线程;css

    须要进行大量计算的优先使用线程;html

    强相关的处理用线程,弱相关的处理用进程;前端

      可能要扩展到多机分布的用进程,多核分布的用线程;html5

    都知足需求的状况下用最熟悉最拿手的方式java

二、现有的nosql数据库都有哪些?node

答:NoSQL,指的是非关系型的数据库,Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB等等都是非关系型数据库mysql

三、javascript实现跨域的几种方法?linux

答:(1)document.domain+iframe的设置

对于主域相同而子域不一样的例子,能够经过设置document.domain的办法来解决。 具体的作法是能够在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上 document.domain = ‘a.com’;而后经过a.html文件中建立一个iframe,去控制iframe的contentDocument,这样两个js文件之间就能够 “交互”了。固然这种办法只能解决主域相同而二级域名不一样的状况,若是你异想天开的把script.a.com的domian设为alibaba.com 那显然是会报错地!代码以下:

www.a.com上的a.html

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
    var doc = ifr.contentDocument || ifr.contentWindow.document;
    // 在这里操纵b.html
    alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

script.a.com上的b.html

document.domain = 'a.com';

这种方式适用于{www.kuqin.com, kuqin.com, script.kuqin.com, css.kuqin.com}中的任何页面相互通讯。

备注:某一页面的domain默认等于window.location.hostname。主域名是不带www的域名,例如a.com,主域名前面 带前缀的一般都为二级域名或多级域名,例如www.a.com实际上是二级域名。 domain只能设置为主域名,不能够在b.a.com中将domain设置为c.a.com。

问题:
一、安全性,当一个站点(b.a.com)被攻击后,另外一个站点(c.a.com)会引发安全漏洞。
二、若是一个页面中引入多个iframe,要想可以操做全部iframe,必须都得设置相同domain。
(2)动态建立script

虽然浏览器默认禁止了跨域访问,但并不由止在页面中引用其余域的JS文件,并能够自由执行引入的JS文件中的function(包括操做cookie、Dom等等)。根据这一点,能够方便地经过建立script节点的方法来实现彻底跨域的通讯。具体的作法能够参考YUI的Get Utility

这里判断script节点加载完毕仍是蛮有意思的:ie只能经过script的readystatechange属性,其它浏览器是script的load事件。如下是部分判断script加载完毕的方法。

js.onload = js.onreadystatechange = function() {
    if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
        // callback在此处执行
        js.onload = js.onreadystatechange = null;
    }
};
(3)利用iframe和location.hash

这个办法比较绕,可是能够解决彻底跨域状况下的脚步置换问题。原理是利用location.hash来进行传值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash,改变hash并不会致使页面刷新,因此可 以利用hash值来进行数据传递,固然数据容量是有限的。假设域名a.com下的文件cs1.html要和cnblogs.com域名下的 cs2.html传递信息,cs1.html首先建立自动建立一个隐藏的iframe,iframe的src指向cnblogs.com域名下的 cs2.html页面,这时的hash值能够作参数传递用。cs2.html响应请求后再将经过修改cs1.html的hash值来传递数据(因为两个页面不在同一个域下IE、Chrome不容许修改parent.location.hash的值,因此要借助于a.com域名下的一个代理iframe;Firefox能够修改)。同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一点有变化则获取获取hash值。代码以下:

先是a.com下的文件cs1.html文件:

function startRequest(){
    var ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
    document.body.appendChild(ifr);
}

function checkHash() {
    try {
        var data = location.hash ? location.hash.substring(1) : '';
        if (console.log) {
            console.log('Now the data is '+data);
        }
    } catch(e) {};
}
setInterval(checkHash, 2000);

cnblogs.com域名下的cs2.html:

//模拟一个简单的参数处理操做
switch(location.hash){
    case '#paramdo':
        callBack();
        break;
    case '#paramset':
        //do something……
        break;
}

function callBack(){
    try {
        parent.location.hash = 'somedata';
    } catch (e) {
        // ie、chrome的安全机制没法修改parent.location.hash,
        // 因此要利用一个中间的cnblogs域下的代理iframe
        var ifrproxy = document.createElement('iframe');
        ifrproxy.style.display = 'none';
        ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';    // 注意该文件在"a.com"域下
        document.body.appendChild(ifrproxy);
    }
}

a.com下的域名cs3.html

//由于parent.parent和自身属于同一个域,因此能够改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

固然这样作也存在不少缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等……

(4)window.name实现的跨域数据传输

有三个页面:

a.com/app.html:应用页面。

a.com/proxy.html:代理文件,通常是一个没有任何内容的html文件,须要和应用页面在同一域下。

b.com/data.html:应用页面须要获取数据的页面,可称为数据页面。

实现起来基本步骤以下:

在应用页面(a.com/app.html)中建立一个iframe,把其src指向数据页面(b.com/data.html)。
数据页面会把数据附加到这个iframe的window.name上,data.html代码以下:

<script type="text/javascript">

window.name = 'I was there!'; // 这里是要传输的数据,大小通常为2M,IE和firefox下能够大至32M左右  //格式能够自定义,如json、字符串

</script>

在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,因此能够相互通讯)。app.html部分代码以下:

<script type="text/javascript">

var state = 0,

iframe = document.createElement('iframe'),

loadfn = function() {

   if (state === 1) {

        var data = iframe.contentWindow.name;  // 读取数据

        alert(data);    //弹出'I was there!'

   } else if (state === 0) {

        state = 1;

        iframe.contentWindow.location = "http://a.com/proxy.html";// 设置的代理文件

   } 

};

iframe.src = 'http://b.com/data.html';

if (iframe.attachEvent) {

   iframe.attachEvent('onload', loadfn);

} else {

   iframe.onload  = loadfn;

}

document.body.appendChild(iframe);

</script>

获取数据之后销毁这个iframe,释放内存;这也保证了安全(不被其余域frame js访问)。

<script type="text/javascript">

iframe.contentWindow.document.write('');

iframe.contentWindow.close();

document.body.removeChild(iframe);

</script>

总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操做。

(5)使用HTML5 postMessage

HTML5中最酷的新功能之一就是 跨文档消息传输Cross Document Messaging。 下一代浏览器都将支持这个功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。

otherWindow.postMessage(message, targetOrigin);
otherWindow: 对接收信息页面的window的引用。能够是页面中iframe的contentWindow属性;window.open的返回值;经过name或下标从window.frames取到的值。
message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,“*”表示不做限制

a.com/index.html中的代码:

<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
    var ifr = document.getElementById('ifr');
    var targetOrigin = 'http://b.com';  // 若写成'http://b.com/c/proxy.html'效果同样
                                        // 若写成'http://c.com'就不会执行postMessage了 ifr.contentWindow.postMessage('I was there!', targetOrigin); }; </script>

b.com/index.html中的代码:

<script type="text/javascript">
    window.addEventListener('message', function(event){
        // 经过origin属性判断消息来源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 弹出"I was there!"
            alert(event.source);  // 对a.com、index.html中window对象的引用
                                  // 但因为同源策略,这里event.source不能够访问window对象
        }
    }, false);
</script>
(6)利用flash

这是从YUI3的IO组件中看到的办法,具体可见http://developer.yahoo.com/yui/3/io/
能够看在Adobe Developer Connection看到更多的跨域代理文件规范:ross-Domain Policy File SpecificationsHTTP Headers Blacklist

四、Jquery最核心的部分是什么?

答:Jquery选择器

五、冒泡排序、快速排序、选择排序、堆排序、插入排序各写一例?说说冒泡排序和快速排序的核心思想

答:假设如下都是从小到大排序:

一、冒泡排序(稳定排序)

我的理解:冒泡排序就是两个循环,大循环套小循环,从头或者尾部开始比较连续的两个元素的大小,若是不符合本身的排序标准(由小到大,或由大到小),则交换其值。

function bubble_sort($array){

  $count=count($array);

  for($i=0;$i<$count;$i++){

    for($j=$count-1;$j>$i;$j--){

      if($array[$j]<$array[$j-1]){//若是后面的值小于前面的元素,则交换值

        $temp=$array[$j];

        $array[$j]=$array[$j-1];

        $array[$j-1]=$temp;

      }

    }

  }

}

二、快速排序(又称数组排序)(不稳定排序)

我的理解:在要排序的数组中找一个关键数据(标准值),一般把数组的第一个元素当成关键数据,而后循环数组,从第二个元素开始依次将元素值与关键数 据进行比较,若是小于关键数据,就把该元素放在关键值左边,若是答应关键数据,就把该元素放在关键数据右边,将关键值左边元素存成数组,右边元素也存成数 组,再分别进行以上排序,获得的数组与关键数据合并数组后就排序成功

function quick_sort($array){

  $count=count($array);

  if($count<=1) retrun $array;  //若是数组只有一个元素或为空,则直接返回数组,不用排序了

  $key=$array[0]; //将数组第一个元素设置为关键数据

  $left_arr=array();

  $right_ar=array();

  for($i=1;$i<$count;$i++){

    if($array[$i]<=$key)

      $left_arr[]=$array[$i];

    else

      $right_arr[]=$array[$i];

  }

  $left_arr=quick_sort($left_arr);

  $right_arr=quick_sort($right_arr);

  //返回合并后的数组

  return array_merge($left_arr,array($key),$right_arr);

}

三、选择排序(不稳定排序)

我的理解:选择排序就是在要排序的数组中选出最小值与第一个元素交换值,而后再剩下的元素中选出最小值与第二个元素交换值,如此循环到倒数第二个元素和最后一个元素比较为止。

function select_sort($array){

  $count=count($array);

  if($count<=1) return $array;

  for($i=0;$i<$count-1;$i++){

    $min=$array[$i]; //假设当前元素为数最小,比较后再调整

    for($j=$i+1;$j<$count;$j++){

      if($array[$j]<$min){

        $min=$array[$j];

        $key=$j; //将此时值最小的元素的键名记下,

      }

    }

    if($min!=$array[$i]){ //若是min在循环中改变了,就须要交换数据

      $temp=$array[$i];

      $array[$i]=$array[$key];

      $array[$key]=$temp;

    }

  }

}其余的排序之后再说吧

六、当前的web应用程序的网络协议都有哪些?

答:HTTP(超文本传输协议)、TCP/IP(传输控制协议/网络互联协议)、SMTP(邮件传输协议)、POP3(邮局协议第三版)、FTP(文件传输协议)等等

七、谈谈session和cookie的概念?并说说其各自的实现原理

八、nginx是什么?与linux的区别?

答:nginx(发音同 engine x)一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特色是占有内存少,并发能力强,因它的稳定性、丰富的功能集、示例配置文件和低系 统资源的消耗而闻名。linux是一种操做系统,两个根本不属同一类

九、jsonp和json有什么区别

答:JSON(JavaScript Object Notation)是Douglas Crockford提出的。他是一个轻量级的数据交换格式,基于JavaScript对象字面量。

    使用JSON的优势在于:

      (1) 比XML轻了不少,没有那么多冗余的东西

    (2)JSON也是具备很好的可读性的,可是一般返回的都是压缩事后的。不像XML这样的浏览器能够直接显示,浏览器对于JSON的格式化的显示就须要借助一些插件了

    (3)在JavaScript中处理JSON很简单

    (4)其余语言例如PHP对于JSON的支持也不错

    JSON也有一些劣势:

     (1) JSON在服务端语言的支持不像XML那么普遍,不过JSON.org上提供不少语言的库

     (2) 若是你使用eval()来解析的话,会容易出现安全问题

       尽管如此,JSON的优势仍是很明显的。他是Ajax数据交互的很理想的数据格式。

  JSONP是一个非官方的协议,它容许在服务器端集成Script tags返回至客户端,经过javascript callback的形式实现跨域访问

  区别:JSON没有实现跨域,JSONP能够实现跨域

十、谈谈tinyint  int  smallint  mediumint的 字节数 和长度范围

答:类型                     字节                             最小值(带符号/无符号)          最大值(带符号/无符号)

          TINYINT                 1                                 -128 / 0                                     127 / 255   

         SMALLINT              2                                 -32768 / 0                                       32767 / 65535

  MEDIUMINT            3                              -8388608 / 0                                     8388607 / 16777215

    int               4                   -2147483648 / 0                            2147483647 / 4294967295     

十一、说说对面向对象的理解?

答:面对对象就是: 把数据及对数据的操做方法放在一块儿,做为一个相互依存的总体——对象。对同类对象抽象出其共性,造成类。类中的大多数数据,只能用本类的方法进行处理。类 经过一个简单的外部接口与外界发生关系,对象与对象之间经过消息进行通讯。程序流程由用户在使用中决定。

     面向对象有三个特征:继承、封装、多态

十二、varchar和char的区别,各能存多少字节?

答:char(n)  定长 索引效率高 程序里面使用trim去除多余的空白 ,n 必须是一个介于 1 和 8,000 之间的数值,存储大小为 n 个字节
      varchar(n) 变长 效率没char高 灵活 ,n 必须是一个介于 1 和 8,000 之间的数值。存储大小为输入数据的字节的实际长度,而不是 n 个字节

1三、一个汉字在utf-8编码下占多少字节?

答:3个字节,用mb_strlen($str,'utf8')函数能够测试出,一个汉字在gbk编码下占两个字节

1四、说说mysql 水平分区和垂直分区?

答:数据库分区:  数据库分区是一种物理数据库设计技术,DBA和数据库建模人员对其至关熟悉。虽然分区技术能够实现不少效果, 但其主要目的是为了在特定的SQL操做中减小数据读写的总量以缩减响应时间。
     水平分区,垂直分区
   分区主要有两种形式:这里必定要注意行和列的概念(row是行,column是列)
     水平分区(Horizontal Partitioning)
                这种形式分区是对表的行进行分区,经过这样的方式不一样分组里面的物理列分割的数据集得以组合,从而进行个体分割(单分区)或集体分割(1个或多个分区)。
                全部在表中定义的列在每一个数据集中都能找到,因此表的特性依然得以保持。
                举个简单例子:一个包含十年发票记录的表能够被分区为十个不一样的分区,每一个分区包含的是其中一年的记录。
                必定要经过某个属性列来分割,譬如这里使用的列就是年份
     垂直分区(Vertical Partitioning)
                这种分区方式通常来讲是经过对表的垂直划分来减小目标表的宽度,使某些特定的列被划分到特定的分区,每一个分区都包含了其中的列所对应的行。
                举个简单例子:一个包含了大text和BLOB列的表,这些text和BLOB列又不常常被访问,这时候就要把这些不常用的text和BLOB了划分到另外一个分区,
                在保证它们数据相关性的同时还能提升访问速度。

1五、谈谈你对memcache的了解?

答:memcached 是高效、快速的分布式内存对象缓存系统 ,经过在内存里维护一个统一的巨大的Hash表,可以用来存储各类格式的数据。主要用于加速 WEB 动态应用程序。

  工做原理:首先 memcached 是以守护程序方式运行于一个或多个服务器中,随时接受客户端的链接操做,客户端能够由各类语言编写,目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客户端在与 memcached 服务创建链接以后,接下来的事情就是存取对象了,每一个被存取的对象都有一个惟一的标识符 key,存取操做均经过这个 key 进行,保存到 memcached 中的对象其实是放置内存中的,并非保存在 cache 文件中的,这也是为何 memcached 可以如此高效快速的缘由。注意,这些对象并非持久的,服务中止以后,里边的数据就会丢失。

1六、有一只猴子,旁边有100根香蕉,他离家有50米远,每次只能搬50根香蕉,否则就会被压死,每走一米就要吃掉一根,问最多能将几根香蕉搬回家?

答:16根.
  问题简化成走最短的路,背更多的水果.但路和水果之间有限制! 题目已经限制,猴子最多背50,咱们计算其消耗仅剩下50根的米处,
  假设猴子第一次背了50根,走了X米,在回来搬第2个50根,就有:
  100-3X ......... 剩下的香蕉数(先走X,往反2X)
  50-X ............ 剩下的米处
  问题就明白了:
  (100-3X)-(50-X)=50-2X ........回到家时的香蕉数
  问题就简化为在条件: (100-3X)<=50的状况下,求
  (50-2X)的最大值!
  获得: X=17时, 50-2X 最大值 16

1七、dir/upload.image.jpg请写出至少五种以上方法,获取文件类型,必须使用php内置函数,能够封装成方法,方法不能明显重复。

答:$file = "dir/upload.image.jpg";

第一种:

function getTypeOne($filename){
    if(empty($filename)) return false;
        $arr = array();
        $arr = explode('.',$filename);
        return $arr[count($arr)-1];
 }

echo getTypeOne($file);

第二种:

function getTypeTwo($filename){
 if(empty($filename)) return false;
 return str_replace('.','',strrchr($filename,'.'));//strrchr() 函数查找字符串在另外一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的全部字符。若是成失败,不然返回 false
}
echo getTypeTwo($file);

第三种:

function getTypeThree($filename){
 if(empty($filename)) return false;

 //substr()截取字符串函数
 //strrchr() 函数查找字符串在另外一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的全部字符。若是成失败,不然返回 false
 return substr(strrchr($filename,'.'),1);

}
echo getTypeThree($file);

第四种://end — 将数组的内部指针指向最后一个单元
echo end(explode('.',$str));

第五种:
//pathinfo — 返回文件路径的信息
$file = pathinfo($str);
echo $file['extension'];

1八、使用索引的好处和坏处都有哪些?

答:若是表上没有索引.在对表进行相关操做时会对表执行表面扫描.表越大,扫描时间越长.主要是扫描时须要顺序的存取数据的每一行.在作简单的查询时索引能够有效地提升速度.
若是在作巨复杂的查询时.表基本上会进行表扫描操做.索引的存贮主要是包含一个索引搜索键值跟一个指向包含该值行的一个指针还有行值.因此索引内存部分比表空间少.使用操做语句时,索取索引时间比表扫描快.

索引也有坏处(小坏处,忽略不计).对一个表进行的INSERT或者是DELETE时 操做都须要对表上的每一个索引进行额外的更新,增长了处理时间.单索引跟联合索引对于update 更改索引操做也是如此

1九、MySQL_connect和MySQL_pconnect有什么不一样?  

简单的来讲MySQL_pconnect是用来在php与MySQL间创建一条持续链接, 通常php的执行模式是脚本开始执行时初始化全部资源, 脚本运行结束后释放全部资源. 而MySQL_pconnect的方式则不这样, MySQL_connect每次都是从新经过tcp 或者unix domian socket跟sql服务器创建关系, 每次握手都是要消耗很多服务器资源的.

使用pconnect时, 有请求链接MySQL时, php会检查是否以前有条相同的链接(以相同的用户名密码链接到同一个MySQL服务器)已经创建, 若是有的话就直接使用这条链接, 值得注意的是这个相同的链接的概念是对进程来讲的, 不一样的进程call MySQL_pconnect创建会创建起多条链接.

connect与pconnect不会带来功能的差别, 只有性能上的差异.

通常php有俩种运行模式, 一是做为cgi运行, 二是做为apache的模块运行. 做为cgi的时候connect跟pconnect没什么不一样, 由于每次cgi进行运行结束后都会被销毁清理掉资源.

php做为apache模块方式运行时, 可使用到数据库持续链接, 但可能会存在潜在的问题, 这也是哥哥回答的一点.

假设MySQL服务器被配置为最大支持10个并发. 而apache被配置为使用100个子进程.

apache由一个父进程来协调将收到的http request分发给哪一个空闲中的子进程处理, 这样很快处理了10个http请求, 假设10个都分配给了不一样的子进程, 那末10条跟MySQL间的持久链接就创建了, MySQL的能力已经到了极限.

这时又来了一个http请求, apache将它分给其余的任意不在这10个子进程中的进程, 那末这个进程就没有办法创建到MySQL的链接了, 由于坑位已经满了.

使用持久链接还会有其余方面的问题.

若是在你脚本中使用了持久链接, 又进行了锁表操做的话, 若是到脚本结束也没有去解锁的话. 那么下次再运行这个脚本的话, 它为了得到lock table会在那里无尽地等待过去的它unlock table, 过去的它已经不能回来了, 这里成了个死循环. 除非重启web或者MySQL服务器. 另外一个会形成锁定的就是事务了.

避免这个东东的办法能够用register_shutdown_function来注册个回调函数, 在这里面释放表锁定, 或回滚事务.

 

20、构造函数和析构函数各是什么?他们能够接受参数吗?

构造函数:__construct()   能够接受参数  (是在建立对象实例后自动执行的成员方法)

析构函数:__destruct()  不能带有任何参数 (用来在对象使用结束后释放所使用的计算机资源)

 

2一、php代码:setcookie('key','value');print($_COOKIE['key']);输出结果?

 答案:不会输出任何结果,此题考查的是cookie机制的实现原理,这就涉及到cookie数据的移动过程了,Cookie数据按照下面的方式移动:   

    1. 若是你在你的浏览器中输入了web的URL,浏览器会象这个URL的web站点发送请求,好比,你在浏览器中输入一下URL:http: //www.verizon.com,浏览器会将请求发送到Verizon的web服务器,请求它的首页。  
    2.  当浏览器 发送请求时,它会查看你机器上跟域名www.verizon.com有关的Cookie文件,若是存在同www.verizon.com有关的 Cookie,浏览器就会把相关的Cookie“键-值”对数据跟请求一块儿发送到服务器,若是不存在同www.verizon.com有关的 Cookie,则浏览器不发送Cookie到服务器。  
    3. Verizon的web服务器收到Cookies数据和一个页面的Http请求,若是收到了Cookie“键-值”对,Verizon的web服务器将可以使用它们。  
    4. 若是没有收 到Cookie“键-值”对,Verizon的web服务器就能知道你之前没有访问过这个站点,服务器创建一个新的用户ID,并在把你所请求的 页面发回到你的浏览器时,把用户ID“键-值”对发送到你的机器,你的硬盘就会驻留了对应这个站点的“键-值”对Cookie。  
    5. web服务器能够在你访问站点时,随时的更改“键-值”对或者加入一个新的“键-值”对。  
    6. 同“键-值”对发送到客户端的还有同这个“键-值”对相关的一些其它信息,其中之一就是Cookie有效期,另外一个就是路径(为了在同一个站点的不通部分关联不一样的Cookie)。

从 以上资料中能够看出,当用户访问题目中代码所在的页面时,客户端浏览器将像web服务器发送请求,根据页面代码,web服务器将会创建一个名为key的 cookie值, 只有当用户请求的页面返回到客户端浏览器时才会将key这个cookie值发送到客户端的机器,而在本次web请求时并无一块儿发送key这个 cookie值(由于客户端机器并不存在key这个cookie的值),因此就输出不了任何东西,只有当客户端浏览器再次向web服务器发送http请求 (刷新或跳转到别的页面)时web服务器才能接收到key,才能输出key的值

顺便来一段session的实现与工做原理,由于你们老是把这两种方式放在一块儿讨论

session的工做流程:当客户端访问服务器时,服务器根据需求设置session,将会话信息保存在服务器上,同时将标示session的session_id传递给客户端浏览器,
浏 览器将这个session_id保存在内存中(也能够在php.ini里设置参数将其保存在用户的url中),咱们称之为无过时时间的cookie。浏览 器关闭后,这个cookie就清掉了,它不会存在用户的cookie临时文件。之后浏览器每次请求都会额外加上这个参数值,再服务器根据这个 session_id,就能取得客户端的数据状态。

若是客户端浏览器意外关闭,服务器保存的session数据不是当即释放,此时数据还会存在,只要咱们知道那个session_id,就能够继续经过请求得到此session的信息;可是这个时候后台的session还存在,可是session的保存有一个过时
时间,一旦超过规定时间没有客户端请求时,他就会清除这个session。

session的session存储机制,默认的session是保存在files中,即以文件的方式保存session数据

session的实例问题
现有系统A,B; 假设A系统是能够独立运行的web系统,便可以和浏览器直接处理session, B系统是基于mobile的,须要调用A系统的功能接口,
在保持A不改变的状况下,即登录验证,session存储都不变的状况下,B系统能处理前端用户的请求。

这里提供的方案是使用PHP实现

在用户登录成功后,将保存的session的session-id返回给B系统,而后B系统每次请求其余接口都带session_id。
A系统在session_start前加上session_id(session_id);

这样B系统就能安全的调用A

 

2二、php代码:

try{

  require('d:/www/log.txt');//已知此文件已被删除

  echo 'yes';

}catch{

  echo 'catch';

}以上一段代码的输出的结果?

 答案:没有任何输出,由于当require包含的文件不存在时,会致使一个致命错误(Fatal error),程序就此终止,不会再往下执行。解释到这里确定要说一下include包含的文件不存在时产生一个警告(Warning),该语句后面的程序会继续执行。

2三、sort(),asort(),ksort()三个函数的区别?

 答案:1、一维数组

假设有一个一维数组,以下:

1
$sortArr = array("name"=>"hiro", "age"=>"23", "city"=>"Shanghai", "code"=>"200051");

print_r()输出的原始数组结果为:

1
Array ( [name] => hiro [age] => 23 [city] => Shanghai [code] => 200051 )

1.sort()函数:根据数组下标进行升序排列;print_r()输出的数组结果为(输出时只有数组下标,而不是键名):

1
Array ( [0] => 23 [1] => 200051 [2] => Shanghai [3] => hiro )

2.rsort()函数:与sort()函数相反,根据数组下标进行降序排列;print_r()输出的数组结果为(输出时只有数组下标,而不是键名):

1
Array ( [0] => hiro [1] => Shanghai [2] => 200051 [3] => 23 )

3.asort()函数:根据数组的键名进行升序排列;print_r()输出的数组结果为:

1
Array ( [age] => 23 [code] => 200051 [city] => Shanghai [name] => hiro )

4.arsort()函数:与asort()函数相反,根据数组的键名进行降序排列;print_r()输出的数组结果为:

1
Array ( [name] => hiro [city] => Shanghai [code] => 200051 [age] => 23 )

5.ksort()函数:根据数组的键值进行升序排列;print_r()输出的数组结果为:

1
Array ( [age] => 23 [city] => Shanghai [code] => 200051 [name] => hiro )

6.krsort()函数:与ksort()函数相反,根据数组的键值进行降序排列;print_r()输出的数组结果为:

1
Array ( [name] => hiro [city] => Shanghai [code] => 200051 [age] => 23 )

7.reverse_array()函数:反向当前的数组排列顺序;print_r()输出的数组结果为:

1
Array ( [name] => hiro [age] => 23 [city] => Shanghai [code] => 200051 )

8.shuffle()函数:随机地排列数组顺序(每次刷新后排列的顺序都不相同);print_r()输出的数组结果为(只是其中一种随机排列):

1
Array ( [0] => 23 [1] => 200051 [2] => Shanghai [3] => hiro )

2、二维数组

假设有一个二维数组,以下:

1
2
3
4
5
$person = array( array("hiro", "23", "suzhou"), array("yoyo", "25", "shanghai"), array("janstar", "28", "xinjiang") );

print_r()输出的原始数组结果为:

1
Array ( [0] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [1] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) [2] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) )

二维数组的排序是根据每维的键名排序的,因此须要额外地编写比较函数。先举三个例子:

1.按每维的第一个元素升序排列,代码以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
function compare0($x, $y) { if($x[0] == $t[0]) { return 0; } elseif ($x[0] < $y[0]) { return -1; } else { return 1; } }   usort($person, compare0); echo "按第一个元素正向排序:"; print_r($person);

输出的结果以下:

1
按第一个元素正向排序:Array ( [0] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [1] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) [2] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) )

2.按每维的第三个元素升序排列,代码以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
function compare2($x, $y) { if($x[2] == $t[2]) { return 0; } elseif ($x[2] < $y[2]) { return -1; } else { return 1; } }   usort($person, compare2); echo "按第三个元素正向排序:"; print_r($person);

输出的结果以下:

1
按第三个元素正向排序:Array ( [0] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) [1] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [2] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) )

3.按每维的第三个元素升序排列,代码以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
function reverse_compare2($x, $y) { if($x[2] == $t[2]) { return 0; } elseif ($x[2] < $y[2]) { return 1; //改变后便可反向 } else { return -1; //改变后便可反向 } }   usort($person, reverse_compare2); echo "按第三个元素反向排序:"; print_r($person);

输出的结果以下:

1
按第三个元素反向排序:Array ( [0] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) [1] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [2] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) )

2四、php的垃圾收集机制是怎样的?

 答案:“PHP能够自动进行内存管理,清除再也不须要的对象。PHP使用了引用计数(reference counting)这种单纯的垃圾回收(garbage collection)机制。每一个对象都内含一个引用计数器,每一个reference链接到对象,计数器加1。当reference离开生存空间或被设为 NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将再也不须要使用这个对象,释放其所占的内存空间。

每一种计算机语言都有本身的自动垃圾回收机制,让程序员没必要过度关心程序内存分配,php也不例外,可是在面向对象编程(OOP)编程中,有些对象须要显式的销毁;防止程序执行内存溢出。
1、PHP 垃圾回收机制(Garbage Collector 简称GC)
在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾。PHP会将其在内存中销毁;这是PHP的GC垃圾处理机制,防止内存溢出。
当一个PHP线程结束时,当前占用的全部内存空间都会被销毁,当前程序中全部对象同时被销毁。GC进程通常都跟着每起一个SESSION而开始运行的.gc目的是为了在session文件过时之后自动销毁删除这些文件.

2、__destruct /unset
__destruct() 析构函数,是在垃圾对象被回收时执行。
unset 销毁的是指向对象的变量,而不是这个对象。

3、 Session 与 GC
因为PHP的工做机制,它并无一个daemon线程来按期的扫描 Session信息并判断其是否失效,当 一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor的值,来决定是否启用一个GC, 在默认状况下,session.gc_probability=1, session.gc_divisor =100也就是说有1%的可能性启动GC(也就是说100个请求中只有一个gc会伴随100个中的某个请求而启动).
GC的工做就是扫描全部的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,若是生存时间超过gc_maxlifetime(默认24分钟),就将该session删除。
可是,若是你Web服务器有多个站点,多个站点时,GC处理session可能会出现意想不到的结果,缘由就是:GC在工做时,并不会区分不一样站点的session.

那么这个时候怎么解决呢?
1. 修改session.save_path,或使用session_save_path()让每一个站点的session保存到一个专用目录,
2. 提供GC的启动率,天然,GC的启动率提升,系统的性能也会相应减低,不推荐。
3. 在代码中判断当前session的生存时间,利用session_destroy()删除.

2五、传值和传引用的区别?

 答案:传值的话,若是是非对象,会传一个值的拷贝,对这个变量作任何改动都不影响原值。
         传引用或者传对象,是传真实的内存地址,对这个变量作的改动会影响原值。
function func1($a) {
  $a = $a + 1;
}
function func2(&$a) {
  $a = $a + 1;
}
$sample = 1;
func1($sample);
echo $sample; // 输出 1
$sample = 1;
func2($sample);
echo $sample; // 输出 2

2六、求2012-11-11 11:11:11和2012-12-5 12:28:59 两个日期的差数(天数)

方法一:先用strtotime转换成unix时间戳,而后相减,除以一天的秒数86400.
方法二:先用mktime转换成unix时间戳,而后相减,除以一天的秒数86400.

具体代码以下:
方法一:
class Dtime{
  function get_days($date1, $date2){
     $time1 = strtotime($date1);
     $time2 = strtotime($date2);
     return abs($time2-$time1)/86400;
  }
}

$Dtime = new Dtime;
echo $Dtime->get_days('2007-2-5', '2007-3-6');
方法二:
$temp = explode('-', '2007-2-5');
$time1 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]);
$temp = explode('-', '2007-3-6');
$time2 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]);
echo ($time2-$time1)/86400;

2七、索引分几种?主键和惟一索引的区别?

 索引用来快速地寻找那些具备特定值的记录,全部MySQL索引都以B-树的形式保存。若是没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的全部记录,直至找到符合要求的记录。表里面的记录数量越多,这个操做的代价就越高。若是做为搜索条件的列上已经建立了索引,MySQL无需扫描任何记录便可迅速获得目标记录所在的位置。若是表有1000个记录,经过索引查找记录至少要比顺序扫描记录快100倍。

索引的类型:MySQL提供多种索引类型供选择:

(一)普通索引

    这是最基本的索引类型,并且它没有惟一性之类的限制。普通索引能够经过如下几种方式建立:

建立索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
建立表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );

(二)惟一性索引

    这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的全部值都只能出现一次,即必须惟一。惟一性索引能够用如下几种方式建立:

建立索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
建立表的时候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表)
);

(三)主键

主键是一种惟一性索引,但它必须指定为“PRIMARY KEY”。若是你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键通常在建立表的时候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,咱们也能够经过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每一个表只能有一个主键。

(四)全文索引

MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引能够在VARCHAR或者TEXT类型的列上建立。它能够经过CREATE TABLE命令建立,也能够经过ALTER TABLE或CREATE INDEX命令建立。对于大规模的数据集,经过ALTER TABLE(或者CREATE INDEX)命令建立全文索引要比把记录插入带有全文索引的空表更快。本文下面的讨论不再涉及全文索引,要了解更多信息,请参见MySQL documentation。

(四)单列索引与多列索引

索引能够是单列索引,也能够是多列索引。下面咱们经过具体的例子来讲明这两种索引的区别。假设有这样一个people表:

CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname CHAR(50)
NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT NOT
NULL, PRIMARY KEY (peopleid) );

2八、用php正则匹配全部包含index.com域名及全部子域名下的超连接的url

 

2九、静态缓存机制是如何实现的,如何判断静态页面是否过时,静态文件的生成时间怎么保存?

1、能够 根据模板生成静态文件:模版是没有内容的页面,能够是html类型的也能够是php类型的,简单的说就是:一、获取模板的结构代码内容 (非内容性的,如html标签等)二、将关键字进行内容替换(把关键字替换为从数据库里面取出来的数据),三、将替换好的内容写入一个新的html页面 (fopen、fget、fwrite、fclose)

2、实现即时更新:一、采用计划任务定时更新过时静态文件;二、在数据进行增长、修改和删除操做时从新生成静态页面

 静态文件的生成时间无需刻意保存,可根据相应php函数获取:

filemtime ( string filename )返回文件上次被修改的时间,出错时返回 FALSE。时间以 Unix 时间戳的方式返回,可用于 date()。 例如:$a=filemtime("log.txt"); echo "修改时间:".date("Y-m-d H:i:s",$a);

filectime ( string filename )返回文件建立的时间,若是出错则返回 FALSE。时间以 Unix 时间戳的方式返回。例如:$a=filectime("log.txt");echo "建立时间:".date("Y-m-d H:i:s",$a);

fileatime ( string filename )返回文件上次被访问的时间,若是出错则返回 FALSE。时间以 Unix 时间戳的方式返回。例如:$a=fileatime("log.txt");echo "修改时间:".date("Y-m-d H:i:s",$a);

 

30、已知一个用户评论表comment,包含字段 id,userid,content,instime,四个字段,写出查询全部用户的最后评论时间和用户id的sql语句

SELECT id,userid,instime FROM `comment` c WHERE c.instime=(SELECT MAX(instime) FROM `comment` WHERE userid = c.userid ) ORDER BY id;

相关文章
相关标签/搜索