All posts

常见PHP面试题

PHP 的垃圾回收机制 PHP 可以自动进行内存管理,清除不需要的对象。 PHP 使用了引用计数(reference counting)GC 机制。 每个对象都内含一个引用计数器 refcount,每个 referenc…

常见PHP面试题

PHP 的垃圾回收机制

PHP 可以自动进行内存管理,清除不需要的对象。

PHP 使用了引用计数(reference counting)GC 机制。

每个对象都内含一个引用计数器 refcount,每个 reference 连接到对象,计数器加 1。当 reference 离开生存空间或被设为 NULL,计数器减 1。当某个对象的引用计数器为零时,PHP 知道你将不再需要使用这个对象,释放其所占的内存空间。

官方文档:https://www.php.net/manual/zh/features.gc.refcounting-basics.php

session 与 cookie 的区别和联系

区别:

  1. 存放位置:Session 保存在服务器,Cookie 保存在客户端。
  2. 存放的形式:Session 是以对象的形式保存在服务器,Cookie 以字符串的形式保存在客户端。
  3. 用途:Cookies 适合做保存用户的个人设置,爱好等,Session 适合做客户的身份验证
  4. 路径:Session 不能区分路径,同一个用户在访问一个网站期间,所有的 Session 在任何一个地方都可以访问到。而 Cookie 中如果设置了路径参数,那么同一个网站中不同路径下的 Cookie 互相是访问不到的。
  5. 安全性:Cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗,考虑到安全应当使用 session
  6. 大小以及数量限制:每个域名所包含的 cookie 数:IE7/8,FireFox:50 个,Opera30 个;Cookie 总大小:Firefox 和 Safari 允许 cookie 多达 4097 个字节,Opera 允许 cookie 多达 4096 个字 节,InternetExplorer 允许 cookie 多达 4095 个字节;一般认为 Session 没有大小和数量限制。

关系:

Session 需要借助 Cookie 才能正常工作。如果客户端完全禁止 Cookie,Session 将失效!因为 Session 是由应用服务器维持的一个 服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的 SessionID,用该 SessionID 为标识符来存取服务器端的 Session 存储空间。而 SessionID 这一数据则是保存到客户端,用 Cookie 保存的,用户提交页面时,会将这一 SessionID 提交到服务器端,来存取 Session 数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用 Cookie,那么 Session 也会失效。

长连接、短连接的区别和使用

长连接:client 方与 server 方先建立连接,连接建立后不断开,然后再进行报文发送和接收。这种方式下由于通讯连接一直存在。此种方式常用于 P2P 通信。

短连接:Client 方与 server 每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此方式常用于一点对多点通讯。C/S 通信。

长连接与短连接的使用时机:

长连接:

短连接多用于操作频繁,点对点的通讯,而且连接数不能太多的情况。每个 TCP 连 接的建立都需要三次握手,每个 TCP 连接的断开要四次握手。如果每次操作都要建立连接然后再操作的话处理速度会降低,所以每次操作下次操作时直接发送数据 就可以了,不用再建立 TCP 连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成 socket 错误,频繁的 socket 创建也是对资源的浪 费。

短连接:

web 网站的 http 服务一般都用短连接。因为长连接对于服务器来说要耗费一定的资源。像 web 网站这么频繁的成千上万甚至上亿客户端的连接用短连接更省一些资源。试想如果都用长连接,而且同时用成千上万的用户,每个用户都占有一个 连接的话,可想而知服务器的压力有多大。所以并发量大,但是每个用户又不需频繁操作的情况下需要短连接。

http 协议

一个 HTTP 请求报文由请求行(request line)、请求头部(header)、空行和请求数据 4 个部分组成

请求行

请求行由请求方法字段、URL 字段和 HTTP 协议版本字段 3 个字段组成,它们用空格分隔。

请求头部

  • 请求头部由关键字 / 值对组成,每行一对,关键字和值用英文冒号“:”分隔。
  • 请求头部通知服务器有关于客户端请求的信息,典型的 请求头有:

User­Agent:产生请求的浏览器类型。

Accept:客户端可识别的内容类型列表。

Host:请求的主机名,允许多个域名同处一个 IP 地址,即虚拟主机。

空行

后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

请求数据

请求数据不在 GET 方法中使用,而是在 POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求数据相关的常使 用的请求头是 Content­Type 和 Content­Length。

HTTP 响应报文

HTTP 响应也由三个部分组成,分别是:状态行、消息响应头、响应正文。

状态码

1xx:指示信息表示请求已接收,继续处理。

2xx:成功表示请求已被成功接收、理解、接受。

3xx:重定向要完成请求必须进行更进一步的操作。

4xx:客户端错误请求有语法错误或请求无法实现。

5xx:服务器端错误服务器未能实现合法的请求。

常见状态代码、状态描述的说明如下

200 OK:客户端请求成功。

400 Bad Request:客户端请求有语法错误,不能被服务器所理解。

401 Unauthorized:请求未经授权,这个状态代码必须和 WWW­Authenticate 报头域一起使用。

403 Forbidden:服务器收到请求,但是拒绝提供服务。

404 Not Found:请求资源不存在,举个例子:输入了错误的 URL。500 Internal Server Error:服务器发生不可预期的错误。

503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。

响应消息头

信息型状态码,提示目前为止一切正常,客户端应该继续请求,如果已完成请求则忽略。

header(‘HTTP/1.1 100 OK’);

// 通知浏览器 页面不存在

header(‘HTTP/1.1 404 Not Found’);

// 资源被永久的重定向 301 ;302:临时重定向(该资源临时被改变位置)

header(‘HTTP/1.1 301 Moved Permanently’);

// 跳转到一个新的地址

header(‘Location:http://php.itcast.cn/’);

// 延迟转向也就是隔几秒跳转

header(‘Refresh:10;url=http://php.itcast.cn/’);

// 网页编码

header(‘Content-Type:text/html;charset=utf-8’);

// 纯文本格式

header(‘Content-Type:text/plain’);

//JPG、JPEG

header(‘Content-Type:image/jpeg’);

//ZIP 文件

header(‘Content-Type:application/zip’);

//PDF 文件

header(‘Content-Type:application/pdf’);

// 音频文件

header(‘Content-Type:’);

//css 文件

header(‘Content-type:text/css’);

声明一个下载的文件

header(‘Content-Type:application/octet-stream’);

header(‘Content-Disposition:attachment;filename=“ITblog.zip”’);

显示一个需要验证的登陆对话框

header(‘HTTP/1.1 401Unauthorized’);

header(‘WWW-Authenticate:Basic realm=“TopSecret”’);

HTTP/2 新增功能

2015 年,HTTP/2 发布。它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。

二进制协议

HTTP/1.1 版的头信息肯定是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为“帧”(frame):头信息帧和数据帧。

二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。

多工

HTTP/2 复用 TCP 连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了“队头堵塞”。

举例来说,在一个 TCP 连接里面,服务器同时收到了 A 请求和 B 请求,于是先回应 A 请求,结果发现处理过程非常耗时,于是就发送 A 请求已经处理好的部分,接着回应 B 请求,完成后,再发送 A 请求剩下的部分。

这样双向的、实时的通信,就叫做多工(Multiplexing)。

数据流

因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。

HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流 ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID 一律为奇数,服务器发出的,ID 为偶数。

数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM 帧),取消这个数据流。1.1 版取消数据流的唯一方法,就是关闭 TCP 连接。这就是说,HTTP/2 可以取消某一次请求,同时保证 TCP 连接还打开着,可以被其他请求使用。

客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。

头信息压缩

HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。

HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

服务器推送

HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。

常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析 HTML 源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。

超全局变量

$GLOBALS 是 PHP 的一个超级全局变量组,在一个 PHP 脚本的全部作用域中都可以访问。是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。

$_REQUEST 用于收集 HTML 表单提交的数据。

$_POST 被广泛应用于收集表单数据,在 HTML form 标签的指定该属性:“method=”post“。

$_GET 同样被广泛应用于收集表单数据,在 HTML form 标签的指定该属性:”method=“get”。

$_COOKIE 经由 HTTP Cookies 方法提交至脚本的变量

$_SESSION 当前注册给脚本会话的变量。类似于旧数组 $HTTP_SESSION_VARS 数组。

$_FILES 经由 HTTP POST 文件上传而提交至脚本的变量。类似于旧数组 $HTTP_POST_FILES 数组。

$_ENV 执行环境提交至脚本的变量。类似于旧数组 $HTTP_ENV_VARS 数组。

MySQL 索引

什么是索引

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。(摘自百度百科)

索引类型

1.FULLTEXT 全文索引

全文索引,仅 MyISAM 引擎支持。其可以在 CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。

2.HASH 哈希索引

HASH 索引的唯一性及类似键值对的形式十分适合作为索引,HASH 索引可以一次定位,不需要像树形索引那样逐层参照,因此具有极高的效率。但是这种高效是有条件的。即只在“=”和“in”条件下高效,对于范围查询,排序及组合索引仍然效率不高。

3.BTREE 树形索引

BTREE 所以是一种将索引按一定算法,存入一个树形的数据结构中(二叉树),每次查询都是从树的入口 root 开始,一次遍历 node,获取 leaf。这是 MySQL 中默认也是最常用的索引类型。

4.RTREE

RTREE 在 MySQL 中很少使用,仅支持 geometry 数据类型,支持该存储引擎只有 MyISAM、BDb、InnoDb、NDb、Archive 几种。相对于 BTREE,RTREE 的优势在于范围查找。

索引种类

普通索引:仅加速查询

唯一索引:加速查询+列值唯一(可以有 null)

主键索引:加速查询+列值唯一(不可以有 null)+表中只有一个

组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

全文索引:对文本内容进行分词,进行搜索

外键索引:与主键索引形成联系,保证数据的完整性。

索引使用的注意事项

1.符合索引遵循前缀原则

2.like 查询%不能再前,否则索引失效。如有需要,使用全文索引

3.column is null 可以使用索引

4.如果 MySQL 估计使用索引比全表扫描慢,则放弃使用索引

5.如果 or 前的条件中列有索引,后面的没有,索引不会生效。

6.列类型是字符串,查询时,一定要给值加引号,否则索引失效。

7.确定 order by 和 group by 中只有一个表的列,这样才能使用索引

常见高并发的解决方案

web 服务器优化 :负载均衡

流量优化:防盗链处理 将恶意请求屏蔽,

前端优化:减少 http 请求、添加异步请求、启用浏览器缓存和文件压缩、cdn 加速、建立独立的图片服务器、

服务端优化:页面静态化、并发处理、队列处理、

数据库优化:数据库缓存、分库分表、分区操作 、读写分离、负载均衡

Discussion