【精讲】2022年PHP中高级面试题(二)
共 518字,需浏览 2分钟
·
2022-02-17 13:59
function IP2Long($ip) {
$ips = explode('.', $ip);
if(count($ips) != 4) {
return false;
}
return ($ips[0] << 24) + ($ips[1] << 16) + ($ips[2] << 8) + $ips[3];
}
function Long2IP($int) {
$ip1 = $ipint >> 24;
$ip2 = ($ipint >> 16) & 255;
$ip3 = ($ipint >> 8) & 255;
$ip4 = $ipint & 255;
return $ip1.'.'.$ip2.'.'.$ip3.'.'.$ip4;
}
2.php链式调用:
1 使用魔法函数__call结合call_user_func来实现
2 使用魔法函数__call结合call_user_func_array来实现
3 不使用魔法函数__call来实现,修改 __call() 为 trim重点在于,返回$this指针,方便调用后者函数。
3. 不使用第三个变量来交换两个变量的值
两个为 数字时
/**
*双方变量为数字时,可用交换方法,使用加减运算符,相当于数学运算了
*/
$a = 1; //a变量原始值
$b = 2; //b变量原始值
echo '交换之前 $a 的值:' . $a . ', $b 的值:' . $b, '
'; // 输出原始值
$a = $a + $b; // $a $b和值
$b = $a - $b; // 不解释..
$a = $a - $b; // 不解释..
echo '交换之后 $a 的值:' . $a . ', $b 的值:' . $b, '
'; // 输出结果值两个为字符串时
/**
* 双方变量为字符串或者数字时,可用交换方法四
* 使用异或运算
*/
$a = "This is A"; // a变量原始值
$b = "This is B"; // b变量原始值
echo '交换之前 $a 的值:' . $a . ', $b 的值:' . $b, '
'; // 输出原始值
/**
* 原始二进制:
* $a:010101000110100001101001011100110010000001101001011100110010000001 000001
* $b:010101000110100001101001011100110010000001101001011100110010000001 000010
* 下面主要使用按位异或交换,具体请参照下列给出的二进制过程,
*/
$a = $a ^ $b; // 此刻 $a:000000000000000000000000000000000000000000000000000000000000000000 000011
$b = $b ^ $a; // 此刻 $b:010101000110100001101001011100110010000001101001011100110010000001 000001
$a = $a ^ $b; // 此刻 $a:010101000110100001101001011100110010000001101001011100110010000001 000010
echo '交换之后 $a 的值:' . $a . ', $b 的值:' . $b, '
'; // 输出结果值或者 str_replace 处理
$a = "This is A"; // a变量原始值
$b = "This is B"; // b变量原始值
echo '交换之前 $a 的值:' . $a . ', $b 的值:' . $b, '
'; // 输出原始值
$a .= $b; // 将$b的值追加到$a中
$b = str_replace($b, "", $a); // 在$a(原始$a+$b)中,将$b替换为空,则余下的返回值为$a
$a = str_replace($b, "", $a); // 此时,$b为原始$a值,则在$a(原始$a+b)中将$b(原始$a)替换为空,则余下的返回值则为原始$b,交换成功
echo '交换之后 $a 的值:' . $a . ', $b 的值:' . $b, '
'; // 输出结果值
4.Strtoupper/strtolower 遇到中文会乱码
需要手动分割字符串,然后 ord 函数判断是否是单词,是则大小写转换,中文则不处 理
mb_convert_case 函数中有可选参数,直接能处理这种情况
CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。
FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。
PHP-CGI:是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程 序。
PHP-FPM:是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口 程序,额外还提供了相对智能一些任务管理。
Fastcgi 是常驻类型的,不需要每次去激活了
FastCGI程序会 先启动一个master,解析配置环境,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请 求。
首先要说的是:fastcgi是一个协议,php-fpm实现了这个协议。
大家都知道,PHP的解释器是php-cgi。php-cgi只是个CGI程序,他自己本身只能解析 请求,返回结果,不会进程管理,所以就出现了一些能够调度php-cgi进程的程序,php-fpm就是这样的一个东西。它克服了php-cgi变更php.ini配置后,需重启php-cgi才能让新的php-ini生效,不可以平滑重启,直接杀死php-cgi进程,php就不能运行了 的问题。修改php.ini之后,php-cgi进程的确没办法平滑重启的。php-fpm对此的处理 机制是新的worker用新的配置,已经存在的worker处理完手上的活就可以歇着了,通 过这种机制来平滑过度。
6.Explain 后需要关注的信息
列名
|
备注
|
type
|
本次查询表联接类型,从这里可以看到本次查询大概的效率
|
key
|
最终选择的索引,如果没有索引的话,本次查询效率通常很差
|
key_le n
|
本次查询用于结果过滤的索引实际长度,参见另一篇分享(FAQ系列-解读EXPLAIN执行计划中的key_len)
|
rows
|
预计需要扫描的记录数,预计需要扫描的记录数越小越好
|
Extra
|
额外附加信息,主要确认是否出现 Using filesort、Using temporary 这 两种情况
|
首先看下 type 有几种结果,分别表示什么意思:
类型
|
备注
|
ALL
|
执行full table scan,这是最差的一种方式
|
index
|
执行full index scan,并且可以通过索引完成结果扫描并且直接从索引中 取的想要的结果数据,也就是可以避免回表,比ALL略好,因为索引文件通 常比全部数据要来的小
|
range
|
利用索引进行范围查询,比index略好
|
index_sub query
|
子查询中可以用到索引
|
unique_su bquery
|
子查询中可以用到唯一索引,效率比 index_subquery 更高些
|
index_mer ge
|
可以利用index merge特性用到多个索引,提高查询效率
|
ref_or_null
|
表连接类型是ref,但进行扫描的索引列中可能包含NULL值
|
fulltext
|
全文检索
|
ref
|
基于索引的等值查询,或者表间等值连接
|
eq_ref
|
表连接时基于主键或非NULL的唯一索引完成扫描,比ref略好
|
const
|
基于主键或唯一索引唯一值查询,最多返回一条结果,比eq_ref略好
|
system
|
查询对象表只有一行数据,这是最好的情况
|
上面几种情况,从上到下一次是最差到最好。再来看下Extra列中需要注意出现的几种情况:
关键字
|
备注
|
Using filesort
|
将用外部排序而不是按照索引顺序排列结果,数据较少时从内存排序, 否则需要在磁盘完成排序,代价非常高,需要添加合适的索引
|
Using temporary
|
需要创建一个临时表来存储结果,这通常发生在对没有索引的列进行GROUP BY时,或者ORDER BY里的列不都在索引里,需要添加合适 的索引
|
Using index
|
表示MySQL使用覆盖索引避免全表扫描,不需要再到表中进行二次查 找数据,这是比较好的结果之一。注意不要和type中的index类型混淆
|
Using where
|
通常是进行了全表引扫描后再用WHERE子句完成结果过滤,需要添加 合适的索引
|
Impossible WHERE
|
对Where子句判断的结果总是false而不能选择任何数据,例如where 1=0,无需过多关注
|
Select tables optimized away
|
使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直 接一次定位到所需要的数据行完成整个查询,例如MIN()\MAX(),这 种也是比较好的结果之一
|
7.Php-fpm 运行的三种模式:
Static模式最简单,直接启动配置的固定数量的进程,但是灵活性不够高
ondemand 模式相对 static 模式比较复杂,会根据请求量的增加动态增加,但是处理完请求后不会立即释放,而是由定时事件定时的检测空闲到一定时间的进程才会释放
Dynamic 模式类似于 ondemand 模式,但进程的回收机制不同于 ondemand 模式, 会根据 idle 数量进行增加和减少worker数量
8.Php-fpm 运行的逻辑:
Fpm 的实现就是创建一个 master 进程,在 master 进程中创建 worker pool 并监听 socket,然后 fork出多个子进程(work),这些 worker 在启动后阻塞在 fcgi_accept_request() 上,各自 accept 请求,有请求到达后 worker 开始读取请求数 据,读取完成后开始处理然后再返回,在这期间是不会接收其它请求的,也就是说 fpm 的子进程同时只能响应一个请求,只有把这个请求处理完成后才会 accept 下一个请 求,所以有多少子进程就能同时处理多少请求。
10.Fpm 工作流程:
FastCGI 进程管理器自身初始化,启动多个 CGI 解释器进程,并等待来自 Web Server 的连接。
Web 服务器与 FastCGI 进程管理器进行 Socket 通信,通过 FastCGI 协议发 送 CGI 环境变量和标准输入数据给 CGI 解释器进程。
CGI 解释器进程完成处理后将标准输出和错误信息从同一连接返回 Web Server。
CGI 解释器进程接着等待并处理来自 Web Server 的下一个连接。
11.Nginx 与 php-fpm 有两种通信方式:
12.数据库连接池实现原理
连接池的作用就是为了提高性能,将已经创建好的连接保存在池中,当有请求来时,直 接使用已经创建好的连接对 Server 端进行访问。这样 省略了创建连接和销毁连接的过 程,从而提高性能。
13.Redis 常见应用场景
首页热点新闻/商品,避免频繁读取数据库 bitmap 用来记录连续签到/登录情况 新
闻阅读量的计数器
最新新闻列表 lpush 就行,然后读取 简单的消息发布系统 pubsub sortedset 来做
排行榜
2 DNS 负载均衡,DNS支持一个域名多个ip地址了
3 反向代理负载均衡,NGINX 根据一定规则进行请求分发
4 F5硬件级别
6 CDN 对于静态文件的负载均衡 负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和 网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
15.数据库主从复制的原理,会不会延迟,会该怎样解决
三个要点:网络延迟,master 负载 slave 负载 slave 对数据安全性的要求
master 将数据改变记录到 binlog 中
slave 启动一个io线程,从指定位置开 始同步 binlog
读取到 master 数据的更新,slave 写入到 replaylog 中,然后开始重 放数据
Tps 是事务数/秒 qps 是每秒查询率
解决:减少网络延迟,关闭 slave 的 sync_binlog 设置成大点就行,累计多次事务之后 刷盘 innodb_flush_log_at_trx_commit = 2 事务提交之后刷盘,slave 上也可以关闭 这个,缺点是意外断电了会丢失数据
数据库集群方案就行,删掉主库了会自动选举从库,业务保持稳定,然后就是精细化的 备份
2021年最新大厂php+go面试题集(四)
2021年最新大厂php+go面试题集(三)
2021年最新大厂php+go面试题集(二)
2021年最新大厂php+go面试题集(1)
面试官问:如何防超卖,有几种实现方式