PHP 面试要点
简单做一下自我介绍? 介绍一下三年内最得意的项目?
操作系统
IO 多路复用是什么?有哪些 api?
select 和 epoll 的区别?水平触发和边缘触发的区别是啥?使用的时候需要注意什么?
select:fd_setsize有限制1024,fd基于数组存储,每次调用都要将fd集合从用户态拷贝到内核态,每次调用都需要在内核中遍历所有的fd
poll:本质和select没有区别,fd_size不限制,原因是fd是基于链表存储的
epoll:fd_size不限制,fd基于红黑树存储,同时每一次通过epoll_ctl来将fd加入内核中
epoll 储存描述符的数据结构是什么?
select 有描述符限制吗?是多少?
进程 / 线程 / 协程区别?go 和 swoole 的协程实现有啥区别?(分配资源的基本单位 / 运行和调度的基本单位 / 用户线程,M:N 模型和 N:1 模型)
计算机网络
TCP 三次握手的流程
客户端发送一个 SYN 标志位置 1 的包,指明客户端要连接服务器端的接口,发送完毕后,客户端进入 SYN_SEND 状态
服务器发回确认包 (ACK) 应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
TCP 三次握手和四次挥手,为什么三次握手,为什么四次挥手 在Tcp连接中,服务端的SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中,B端向A端发送的ACK和FIN是分两次发送的。因为在B端接收到A端的FIN后,B端可能还有数据要传输,所以先发送ACK,等B端处理完自己的事情后就可以发送FIN断开连接了
一次完整的 HTTP 请求(从浏览器输入 www.baidu.com 到加载出页面发生了什么) 1. dns 解析 ip port 2. 建立 tcp 连接 3. 发送 HTTP 报文 4. 接收 HTTP 报文 5. 浏览器解析显示 6. 断开 tcp 连接
HTTP 协议包括哪些请求? 1. GET:请求读取由URL所标志的信息。 2. POST:给服务器添加信息(如注释)。 3. PUT:在给定的URL下存储一个文档。 4. DELETE:删除给定的URL所标志的资源。
GET 和 POST 区别 1. GET在浏览器回退时是无害的,而POST会再次提交请求。 2. GET产生的URL地址可以被Bookmark,而POST不可以。 3. GET请求会被浏览器主动cache,而POST不会,除非手动设置。 4. GET请求只能进行url编码,而POST支持多种编码方式application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml 5. GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。 6. GET请求在URL中传送的参数是有长度限制的,而POST没有。 7. 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。 8. GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。 9. GET参数通过URL传递,POST放在Request body中。 10. GET产生一个TCP数据包,POST产生两个TCP数据包。GET请求将http header和data一起发送,POST请求先发header,再发送data,返回数据
Cookie存在哪
如果设置了过期时间,Cookie存在硬盘里
如果没有设置过期时间,Cookie存在内存里(会随着浏览器的关闭而消失)
Session 和 Cookie 的区别,禁用 Cookie 后怎么办 1. COOKIE保存在客户端,而SESSION则保存在服务器端 2. 从安全性来讲,SESSION的安全性更高 3. 从保存内容的类型的角度来讲,COOKIE只保存字符串(及能够自动转换成字符串) 4. 从保存内容的大小来看,COOKIE保存的内容是有限的,比较小,而SESSION基本上没有这个限制 5. 从性能的角度来讲,用SESSION的话,对服务器的压力会更大一些 6. SEEION依赖于COOKIE,但如果禁用COOKIE,也可以通过url传递
PHP
PHP执行过程
扫描:将index.php内容变成一个个语言片段(token)
解析:将一个个语言片段有意义的表达式
编译:将表达式编译成中间码(opcode)
执行:将中间码一条条的执行
输出:将要输出的内容输出到缓冲区
nginx中php-fpm的socket是什么类型。
unix socket适合nginx和php-fpm都在一台机器上
tcp socket适合nginx和php-fpm不在同一台机器上
PHP 的解析方式有哪几种?cgi、fastcgi、php-fpm 区别
cgi:公共网关接口,http服务器发起请求,会启动对应的实现了cgi协议的php解析器,php解析器解析php.ini,初始化执行环境,并处理请求,在以cgi规定的格式返回结果,推出进程。
fast-cgi:由cgi发展而来,是一种进程池,先启动一个master进程,解析php.ini和初始化执行环境,然后启动多个worker进程,php请求发到master进程,通过master进程分发的到worker进程进行处理
php-fpm:fastcgi进程管理器,用于替换php内核的fastcgi大部分附加功能
描述一下 cli 模式下的几个生命周期? 1. 模块初始化阶段 (Module init):即调用每个拓展源码中的的 PHP_MINIT_FUNCTION 中的方法初始化模块,进行一些模块所需变量的申请,内存分配等。 2. 请求初始化阶段 (Request init):即接受到客户端的请求后调用每个拓展的 PHP_RINIT_FUNCTION 中的方法,初始化 PHP 脚本的执行环境。 3. 执行该 PHP 脚本。 4. 请求结束 (Request Shutdown):这时候调用每个拓展的 PHP_RSHUTDOWN_FUNCTION 方法清理请求现场,并且 ZE 开始回收变量和内存 5. 关闭模块 (Module shutdown):Web 服务器退出或者命令行脚本执行完毕退出会调用拓展源码中的 PHP_MSHUTDOWN_FUNCTION 方法
PHP7 为什么比 PHP5 性能提升了 1. 变量存储字节减小,减少内存占用,提升变量操作速度 2. 改善数组结构,数组元素和 hash 映射表被分配在同一块内存里,降低了内存占用、提升了 cpu 缓存命中率 3. 改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
PHP7 与 PHP5 1. 性能提升:PHP7 比 PHP5.0 性能提升了两倍。 2. 全面一致的 64 位支持。 3. 以前的许多致命错误,现在改成 [抛出异常]。 4. PHP 7.0 比 PHP5.0 移除了一些老的不在支持的 SAPI([服务器端] 应用编程端口)和扩展。 5. PHP 7.0 比 PHP5.0 新增了空接合操作符。 6. PHP 7.0 比 PHP5.0 新增加了结合比较运算符。 7. PHP 7.0 比 PHP5.0 新增加了函数的返回类型声明。 8. PHP 7.0 比 PHP5.0 新增加了标量类型声明。 9. PHP 7.0 比 PHP5.0 新增加匿名类。
GC(垃圾回收) 的出现是为了解决什么问题?什么时候会触发 GC?说下大概流程 1. PHP 5.3 版本之前都是采用引用计数的方式管理内存 2. PHP 所有的变量存在一个叫 zval 的变量容器中,当变量被引用的时候,引用计数会+1,变量引用计数变为0时,PHP 将在内存中销毁这个变量 3. 引用计数中的循环引用,引用计数不会消减为 0,就会导致内存泄露 4. 在 5.3 版本之后,做了这些优化: 1. 并不是每次引用计数减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收; 2. 可以解决循环引用问题; 3. 可以总将内存泄露保持在一个阈值以下。
如何解决 PHP 内存溢出问题 1. 增大 PHP 脚本的内存分配 2. 变量引用之后及时销毁 3. 将数据分批处理
php-fpm 运行机制?(master 管理,worker 循环 accept)
php-fpm 模式下,kill -9 master-pid,会怎么样?kill matser-pid 呢?(信号机制)
内存分配流程?为什么要这么设计?
php 里的数组是怎么实现的?(这里要注意下 php5 和 php7 实现的区别,优化了非常多)
nginx 和 php-fpm 的通信机制?fast-cgi 和 cgi 区别?
php-fpm 创建 worker 进程的规则是什么?不同场景下怎么选择?
php 和 mysql 的通信机制?长链接和短链接啥区别?怎么实现的?连接池要怎么实现?
swoole 协程的原理?(遇到阻塞时引发 php 栈和 c 栈的切换,细节可以参考下我的文章)
依赖注入是什么?如何实现的?能解决什么问题?(代码层面不再依赖具体实现,解耦)
mysql
MySQL主要的存储引擎MyISAM和InnoDB的不同之处?
解答思路:可以从五个方向去介绍。
事务的支持不同(InnoDB支持事务、MyISAM不支持事务);
锁粒度(InnoDB行锁应用、MyISAM表锁);
存储空间(InnoDB既缓存索引文件,又缓存数据文件,MyISAM只能缓存索引文件);
存储结构(MyISAM:数据文件的扩展名为.MYD myData,索引文件的扩展名是.MYI myIndex;InnoDB:所有的表都保存在同一个数据文件里面,即.Ibd);
统计记录行数(MyISAM:保存有表的总行数,select count() from table会直接取出该值;InnoDB:没有保存表的总行数,select count() from table会遍历整个表,消耗相当大)。
Mysql 主从同步了解吗? 1. MySQL之间的数据复制的基础是二进制日志文件binlog 2. 台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中, 3. 其它数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化, 4. 如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据的一致性,也就实现了主从复制 (主服务器把数据更新记录到二进制日志中,从服务器通过I/O thread向主库发起binlog请求,主服务器通过I/O dump thread把二进制日志传递给从库,从库通过I/O thread记录到自己的中继日志中。然后通过SQL thread应用中继日志中SQL的内容。)
如何查看机器运行的建康指标,如:CPU的LOAD和使用率,内存使用率,磁盘使用率,IOWAIT等,除此之外还有那些重要指标可以用来分析特定场景问题?
yum install iotop iftop iostat htop 安装一系列工具 htop是top命令的加强版,可以看到cpu,内存,执行的进程等信息
iftop 是监控网卡的
iotop 是监控io的
free -m 监控可用内存
uptime 查看当前系统负载
df -hl 查看磁盘
安装smart 工具yum install -y smartmontools,查看磁盘的smart信息smartctl -a /dev/sda
查看cpu信息cat /proc/cpuinfo
查看内存信息 cat /proc/meminfo
nginx
LVS 和 Nginx 分别作用在 osi 哪一层?
负载均衡算法 1. 轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。 2. Weight 指定轮询几率,weight 和访问比率成正比, 用于后端服务器性能不均的情况。 3. ip_hash 每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 共享的问题。 4. fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。 5. url_hash(第三方)
安全防范
CSRF 是什么?如何防范? 1. CSRF(Cross-site request forgery)通常被叫做「跨站请求伪造」,可以这么理解:攻击者盗用用户身份,从而欺骗服务器,来完成攻击请求。 2. 防范措施: 1. 使用验证码 2. 给每一个请求添加令牌 token 并验证 只使用json api(js 发起ajax请求是限制跨域的) 禁用cross-origin(只允许options、head、get方法跨域请求) 检验referer头部 GET总是幂等 避免使用POST 不要复写方法 不要兼容旧浏览器 CSRF Tokens
XSS 是什么?如何防范? 1. XSS(Cross Site Scripting),跨站脚本攻击,攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。 2. 防止 XSS 攻击的方式有很多,其核心的本质是:永远不要相信用户的输入数据,始终保持对用户数据的过滤 3. 将重要的cookie标记为http only,这样的话Javascript 中的document.cookie语句就不能获取到cookie了
什么是 SQL 注入?SQL注入产生的原因?如何防范? 1. SQL注入产生的原因: 1. 程序开发过程中不注意规范书写SQL语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行 2. 防范措施 1. 保持对用户数据的过滤(严格检查输入变量的类型和格式) 2. 过滤和转义特殊字符比如addslashes()函数 3. 利用mysql的预编译机制
1、为什么使用redis (一)性能 我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。 (二)并发 在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。 2.使用redis有什么缺点 (一)缓存和数据库双写一致性问题 (二)缓存雪崩问题 (三)缓存击穿问题 (四)缓存的并发竞争问题 3、单线程的redis为什么这么快 (一)纯内存操作 (二)单线程操作,避免了频繁的上下文切换 (三)采用了非阻塞I/O多路复用机制 参照上图,简单来说,就是。我们的redis-client在操作的时候,会产生具有不同事件类型的socket。在服务端,有一段I/0多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中。 4、redis的数据类型,以及每种数据类型的使用场景 回答:一共五种 (一)String 这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。 (二)hash 这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。 (三)list 使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。 (四)set 因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。 另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。 (五)sorted set sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。
Redis 如何实现持久化
RDB 持久化,将 Redis 在内存中的的状态保存到硬盘中,相当于备份数据库状态。
AOF 持久化(Append-Only-File),AOF 持久化是通过保存 Redis 服务器锁执行的写状态来记录数据库的。相当于备份数据库接收到的命令,所有被写入 AOF 的命令都是以 Redis 的协议格式来保存的
Last updated
Was this helpful?