PHP常见面试题(持续更新中)

一.浏览器输入域名,整个过程发生了什么

   1.通过输入的域名通过DNS寻找到其IP地址,
   DNS过程:
    浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。

    系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。

    路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。

    ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。

    递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

   DNS有一点令人担忧,这就是像wikipedia.org 或者 facebook.com这样的整个域名看上去只是对应一个单独的IP地址。还好,有几方法可以消除这个瓶颈:

    循环 DNS 是DNS查找时返回多个IP时的解决方案。举例来说,Facebook.com实际上就对应了四个IP地

    负载平衡器 是以一个特定IP地址进行侦听并将网络请求转发到集群服务器上的硬件设备。 一些大型的站点一般都会使用这种昂贵的高性能负载平衡器。

    地理 DNS 根据用户所处的地理位置,通过把域名映射到多个不同的IP地址提高可扩展性。这样不同的服务器不能够更新同步状态,但映射静态内容的话非常好。

    Anycast是一个IP地址映射多个物理主机的路由技术。 美中不足,Anycast与TCP协议适应的不是很好,所以很少应用在那些方案中。
大多数DNS服务器使用Anycast来获得高效低延迟的DNS查找。

   2.浏览器给web服务器发送一个HTTP请求
    GET 这个请求定义了要读取的URL: “http://facebook.com/”。 浏览器自身定义 (User-Agent 头), 和它希望接受什么类型的相应 (Accept andAccept-Encoding 头).     Connection头要求服务器为了后边的请求不要关闭TCP连接
   3.服务器“处理”请求
   4.服务器发回一个HTML响应
   5.浏览器开始显示HTML

二.PHP底层原理

   简言之;PHP动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作

   1、多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,目前PHP也早支持多线程模型。

   2、弱类型语言:和C/C++、JAVA、C#等语言不同,PHP是一种弱类型的语言。一个变量的类型并不是一开始就确定不变的,运行中才会确定并可能发生隐式或显示的类型转换,这种机制的     灵活性在web开发中非常方便、高效,具体会在后面PHP变量中详述。

   3、引擎(Zend)+组件(ext)的模式降低内部耦合。

   4、中间层(sapi )Sapi全称是Server Application Programming Interface 隔绝web server和PHP。

   5、语法简单灵活,没有太多规范。缺点导致风格混杂。


    PHP从下倒上是一个4层体系:

    1、Zend引擎:Zend整体用纯C实现,是PHP的内核部分,他将PHP代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结    构(如:hashtable、OO)、内存分配机制及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕Zend实现。

    2、Extensions:围绕着Zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(array系列)、标准库等都是通过extension来实现,用户也可以根据    需要实现自己的extension的典型应用)。

    3、Sapi:Sapi全称Server Application Programming Interface,也就是服务端应用编程接口,Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的    设计,通过sapi成功的将PHP本身和上层应用解耦隔离,PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。

    4、上层应用:这就是我们平时编写的PHP程序,通过不同的spai方式得到各种各样的应用模式,如何通过webserver实现web应用、在命令行下已脚本方式运行等等。

    我们需要:性能优异的引擎(Zend)+合适的车轮(Ext)+正确的跑道(Sapi)。

    常见的Sapi:
        1.apache2handler:mod_php模式
        2.cgi:fastcgi协议

        Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module)
        FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自Web Server的连接。
        当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
        FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。 在CGI模式中,php-cgi在此便退出了。
        在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。


三.PHP缓存技术

    1.文件缓存    存储介质:磁盘文件  不足:IO操作慢,文件锁存在   适用:新闻数据,城市区域
    2.内存缓存    存储介质:内存      不足:占内存,不持久          适用:会员,商品,session
    3.opcode缓存 存储介质:内存      不足:部署代码刷新慢          适用:opcodecash(代码加速)

                             Memcached :    Redis :                        MongoDB
    储存数据类型    string      :    string, list, hash, set :    bson 丰富查询方式
    数据储存位置    内存          :    内存 + 硬盘                :    内存 + 硬盘
    持久化        最长30天      :    RDB 文件快照,AOF(记录写操作)持久化 : journal持久化
    使用场景        Session 商品缓存(缓存 < 1MB) :    缓存、队列  : 日志、区域信息、评论

四.常见的 PHP 安全性攻击

    SQL注入:用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行。
    防止:使用mysql_real_escape_string()过滤数据;手动检查每一数据是否为正确的数据类型;使用预处理语句并绑定变量

    参数化SQL:是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,用@或?来表示参数。

    XSS攻击 :跨站点脚本攻击,由用户输入一些数据到你的网站,其中包括客户端脚本(通常JavaScript)。如果你没有过滤就输出数据到另一个web页面,这个脚本将被执行。
    防止:为了防止XSS攻击,使用PHP的htmlentities()函数过滤再输出到浏览器。

    CSRF:跨站点请求伪造,是指一个页面发出的请求,看起来就像是网站的信任用户,但是是伪造的
    防止:一般来说,确保用户来自你的表单,并且匹配每一个你发送出去的表单。有两点一定要记住:

    对用户会话采用适当的安全措施,例如:给每一个会话更新id和用户使用SSL。

    生成另一个一次性的令牌并将其嵌入表单,保存在会话中(一个会话变量),在提交时检查它。 如laravel中的 _token

    代码注入:代码注入是利用计算机漏洞通过处理无效数据造成的。问题出在,当你不小心执行任意代码,通常通过文件包含。写得很糟糕的代码可以允许一个远程文件包含并执行。如许多PHP函数,如require可以包含URL或文件名。
    防止代码注入

    过滤用户输入
    在php.ini中设置禁用allow_url_fopen和allow_url_include。这将禁用require/include/fopen的远程文件

五.说一下单引号双引号?

  单引号内部的变量不会执行, 双引号会执行
  单引号解析速度比双引号快。
  单引号只能解析部分特殊字符,双引号可以解析所有特殊字符。

六.静态化如何实现的?伪静态如何实现?

 1、 静态化指的是页面静态化,也即生成实实在在的静态文件,也即不需要查询数据库就可以直接从文件中获取数据,指的是真静态。
      实现方式主要有两种:
   一种是我们在添加信息入库的时候就生成的静态文件,也称为模板替换技术。
   一种是用户在访问我们的页面时先判断是否有对应的缓存文件存在,如果存在就读缓存,不存在就读数据库,同时生成缓存文件。

 2、伪静态不是真正意义上的静态化,之所以使用伪静态,主要是为了SEO推广,搜索引擎对动态的文件获取难度大,不利于网站的推广。实习原理是基于Apache或Nginx的rewrite机智
  主要有两种方式:
   一种是直接在配置虚拟机的位置配置伪静态,这个每次修改完成后需要重启web服务器。
   另一种采用分布式的,可以在网站的根目录上创建.htaccess的文件,在里面配置相应的重写规则来实现伪静态,这种每次重写时不需

七.语句include和require的区别是什么?

    require是无条件包含,也就是如果一个流程里加入require,无论条件成立与否都会先执行require,当文件不存在或者无法打开的时候,会提示错误,并且会终止程序执行
    include有返回值,而require没有(可能因为如此require的速度比include快),如果被包含的文件不存在的化,那么会提示一个错误,但是程序会继续执行下去

八.对于大流量的网站,采用什么样的方法来解决访问量问题?

    确认服务器硬件是否足够支持当前的流量
    优化数据库访问。
    禁止外部的盗链。
    控制大文件的下载。
    使用不同主机分流主要流量
    使用流量分析统计软件
    尽量使用静态页,缓存

九.SESSION 与 COOKIE的区别是什么?

    1、http无状态协议,不能区分用户是否是从同一个网站上来的,同一个用户请求不同的页面不能看做是同一个用户。

`   2、SESSION存储在服务器端,COOKIE保存在客户端。Session比较安全,cookie用某些手段可以修改,不安全。Session依赖于cookie进行传递。
     禁用cookie后,session不能正常使用。Session的缺点:保存在服务器端,每次读取都从服务器进行读取,对服务器有资源消       耗。Session保存在服务器端的文件或数据库中,默认保存在文件中,文件路径由php配置文件的session.save_path指定。           Session文件是公有的。

十.请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用?

    按值传递:函数范围内对值的任何改变在函数外部都会被忽略
    按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
    优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。
        按引用传递则不需要复制值,对于性能提高很有好处。

十一.HTTP 状态中302、403、 500代码含义?

   一二三四五原则: 一. 消息系列 二 成功系列 三. 重定向系列 四. 请求错误系列 五. 服务器端错误系列
302:临时转移成功,请求的内容已转移到新位置 403:禁止访问 500:服务器内部错误 401代表未授权。

十二.冒泡排序

$a = array(31,4,6,1,45,32,26,5);
// 第一层可以理解为从数组中键为0开始循环到最后一个
for ($i = 0; $i < count($a) ; $i++) {
  // 第二层为从$i+1的地方循环到数组最后
    for ($j = $i+1; $j < count($a); $j++) {
     // 比较数组中两个相邻值的大小
        if ($a[$i] > $a[$j]) {
            $tem = $a[$i]; // 这里临时变量,存贮$i的值
            $a[$i] = $a[$j]; // 第一次更换位置
            $a[$j] = $tem; // 完成位置互换
        }
    }        
}

十三.快速排序

$a = array(2,13,42,34,56,23,67,365,87665,54,68,3);

function quick_sort($a)
{
    // 判断是否需要运行,因下面已拿出一个中间值,这里<=1
    if (count($a) <= 1) {
        return $a;
    }

    $middle = $a[0]; // 中间值

    $left = array(); // 接收小于中间值
    $right = array();// 接收大于中间值

    // 循环比较
    for ($i=1; $i < count($a); $i++) { 

        if ($middle < $a[$i]) {

            // 大于中间值
            $right[] = $a[$i];
        } else {

            // 小于中间值
            $left[] = $a[$i];
        }
    }

    // 递归排序划分好的2边
    $left = quick_sort($left);
    $right = quick_sort($right);

    // 合并排序后的数据,别忘了合并中间值
    return array_merge($left, array($middle), $right);
}

你可能感兴趣的:(PHP,php)