PHP开发工程师常见面试题整理

Posted by

不同类型的公司,不同技术背景的面试官给的面试题,也是千奇百怪。不过,作为面试者也可以趁机找出自己知识点当中的不足之处。把面试当作学习的过程,以下就是文武双全自己手动整理的一些PHP开发工程师常见的面试题。

一:http状态码(http status codes)

常见的就不说了,这里补充一个304。其实浏览器里按下F12,各种本地缓存的资源状态码都是304。在nginx里设置文档类型的expires属性的话,其实就是告诉浏览器,资源本地缓存多长时间内不过期,不需要每次都发送请求到服务器。

所有http状态码参考W3C官方网站,https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

二:http头部(http headers)

这个http headers的问题,其实是个很大的问题,光这个东西就可以写1000字了。这里要注意的是,http的headers其实包含四大类,包括通用头(common header),请求头(request header),响应头(response header)和实体头(content header)。在谷歌和火狐等浏览器里按F12打开开发者工具,http的头部信息一览无余。

1 通用头域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。对通用头域的扩展要求通讯双方都支持此扩 展,如果存在不支持的通用头域,一般将会作为实体头域处理。这里比较重要的信息就是cache-control,指定内容缓存的机制。设置为no-cache,就是不在本地缓存,每次都从服务器获取资源的意思。

2 请求头多是客户端本地的一些信息,以及说要请求的URI的一些信息。

3 响应头多少服务器上的一些信息,不如说web服务所使用的程序是nginx还是apache。

4 实体头其实我觉得直接翻译过来,其实就是内容头。或者还可以叫资源头,因为每次请求都请求的是服务器的资源,URI嘛。实体头一般包含:文档的类型(content-type),长度(content-length),编码的类型(content-encoding)等。

三:RESTFull API 设计

REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的互联网软件架构(将网站视作软件)风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。RESTFull API设计就是完全符合REST风格的API设计方法。虽然这套API设计风格已经有17年的历史,但是到目前为止依然在国内大行其道。需要注意的是,Google等一些互联网巨头已经起草了一些新的API设计规范,来替代老掉牙的RESTFull。需要注意的是除了REST风格,还有诸如SOAP和XML-RPC设计风格。如上文所述,REST是一种设计风格,而不是设计标准。REST比另外两者更简单一点,于是越简单的东西就越流行了。

REST是Representational State Transfer的因为缩写,直译过来就是”表现层状态转换”的意思。我觉得加一个单词Resources,这个英文缩写就更好理解了。Resources Representational State Transfer,资源在表现层的状态转换。

REST毫无疑问是基于HTTP协议的,基于HTTP规范允许的使资源状态转变的动词有以下几种,(括号里是对应的SQL命令):

1:GET(SELECT)    列出URI,以及该资源组中每个资源的详细信息(后者可选),就是获取(一个或多个)资源的操作。

2 :POST(CREATE)  在本组资源中创建/追加一个新的资源,该操作往往返回新资源的URL。

3,PUT(UPDATE):使用给定的一组资源替换当前整组资源,在服务器更新资源(客户端提供改变后的完整资源)。

4,PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。

5,DELETE(DELETE):从服务器删除资源。

6,HEAD:获取资源的元数据,不常用。

7,OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的,不常用。

REST的优点如下:

  • 可更高效利用缓存来提高响应速度
  • 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
  • 浏览器即可作为客户端,简化软件需求
  • 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
  • 不需要额外的资源发现机制
  • 在软件技术演进中的长期的兼容性更好

四:javascript和php的闭包(closuer)

每个人对闭包的理解,都可以说上一大堆话。之前面试的时候,碰到一个面试的人说PHP的闭包就是匿名函数,其实这种说法是把匿名函数和闭包搞混淆了。匿名函数就是匿名函数,当定义一个匿名函数的时候,他就是匿名函数。如果这个匿名函数没有调用任何外部变量的话,就不会形成闭包。

当一个匿名函数被其他函数调用,而这个匿名函数调用了外部函数的变量。但外部函数在执行时,内部函数及其所调用的外部函数的变量,就一起形成了闭包。javascript的闭包跟php的闭包有点类似,又有点小区别。

五:mysql的左联合查询(LEFT JOIN)与右联合查询(RIGHT JOIN)的区别

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join(等值连接) 只返回两个表中联结字段相等的行

六:mysql中Index是什么意思?mysql的explain命令是干嘛的?

index就是中文的索引的意思,把字段加入索引可以提高查询的速度。explain是解释的意思,是mysql的性能优化的方式之一。根据查询语句,来寻找优化性能的方式。另外一种优化mysql的手段是,使用慢日志查询。不过这种方式,貌似会增加服务器负担,而且操作比较麻烦。。。

七:PHP的正则表达式(Regular Expression)

我都是用的时候在网上查的,正则的效率有问题,我不太喜欢用。使用preg_match函数进行匹配,以下内容从TP中复制而来。
邮箱验证:  pattern=/\w+([+.]\w+)@\w+([.]\w+)\.\w+([.]\w+)/’;
url匹配:  pattern=’/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\’:+!\.#\w]*)?/’;
手机验证:  pattern=/1[3458]\d10/’;

八:PHP中跟数组排序(sort)有关的函数

sort() 函数用于对数组单元从低到高进行排序。
rsort() 函数用于对数组单元从高到低进行排序。
asort() 函数用于对数组单元从低到高进行排序并保持索引关系。
arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。
ksort() 函数用于对数组单元按照键名从低到高进行排序。
krsort() 函数用于对数组单元按照键名从高到低进行排序。

九:手写一个单例模式的数据库连接类

class Database
{
private $connect;
static private $_instance;

     // 通过构造函数使得实例化数据库连接类时自动创建数据库链接
     private function __construct($host, $username, $password)
     {
          $this->connect = mysqli_connect($host, $username, $password);
          $this->query(“SET NAMES ‘utf8′”, $this->connect);
          //echo mysql_errno($this->link) . “: ” . mysql_error($link). “n”;
          //var_dump($this->connect);
          return $this->connect;
     }

      //创建__clone方法防止对象被复制克隆
      public function __clone()
      {
           trigger_error(‘Clone is not allow!’, E_USER_ERROR);
      }

      //单例方法,用于访问实例的公共的静态方法
     public static function getInstance()
     {
          if (!(self::$_instance instanceof self)) {
          self::$_instance = new self;
     }
          return self::$_instance;
     }

}

PHP的单例模式是相对而言的,因为PHP的解释运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收。

十:简单谈谈面向对象编程(Object Oriented Programming)

面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

对于OOP的准确定义及其本意存在着不少争论。通常,OOP被理解为一种将程序分解为封装数据及相关操作的模块而进行的编程方式。

十一:什么是反射类(ReflectionClass),反射类主要用来干什么?

它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。

其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

PHP反射api由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了那些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。
反射api是PHP内建的OOP技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些OOP扩展被称为反射。

默认情况下,ReflectionClass会获取到所有的属性,private 和 protected的也可以。

十二:什么是依赖注入(Dependency Injection)?

这里友情推荐下,phalcon框架大量使用了DI。

依赖注入的目的:是为了降低耦合,减少计算机程序员对象之间的耦合程度。

依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。

十三:PHP相关工具的使用

包括:composer,phpunit,php code sniffer,xdebug,KCachegrind/Qcachegrind

十四:PHP数组,链表的数据结构

当内存空间中有足够大的连续空间时,可以把数据连续的存放在内存中,各种编程语言中的数组一般都是按这种方式存储的(也可能有例外);当内存中只有一些离散的可用空间时,想连续存储数据就非常困难了,这时能想到的一种解决方式是移动内存中的数据,把离散的空间聚集成连续的一块大空间,这样做当然也可以,但是这种情况因为可能要移动别人的数据,所以会存在一些困难,移动的过程中也有可能会把一些别人的重要数据给丢失。另外一种,不影响别人的数据存储方式是把数据集中的数据分开离散地存储到这些不连续空间中。这时为了能把数据集中的所有数据联系起来,需要在前一块数据的存储空间中记录下一块数据的地址,这样只要知道第一块内存空间的地址就能环环相扣地把数据集整体联系在一起了。C/C++中用指针实现的链表就是这种存储形式。

由上可知,内存中的存储形式可以分为连续存储和离散存储两种。因此,数据的物理存储结构就有连续存储和离散存储两种,它们对应了我们通常所说的数组和链表。

考虑以上的总结可见,数组和链表各有优缺点。在具体使用时要根据具体情况选择。当查找数据操作比较多时最好用数组;当对数据集中的数据进行添加或删除比较多时最好选择链表。

在PHP内部以哈希表的方式实现,基础结构是zval结构。

十五:PHP的值类型和引用类型

在PHP中,大部分变量类型,如字符串,整型,浮点,数组等都是值类型的,而类和对象是引用类型,在使用的时候,需要注意这一点。

赋值时会创建不同的变量的形式我们称之为值类型,赋值时不会创建新的变量的形式我们称之为引用类型。

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据