1.Iptolong long2ip 注意转换成整形的时候负数问题
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. 不使用第三个变量来交换两个变量的值
两个为 数字时
两个为字符串时
<?php
/**
* 双方变量为字符串或者数字时,可用交换方法四
* 使用异或运算
*/
$a = "This is A"; // a变量原始值
$b = "This is B"; // b变量原始值
echo '交换之前 $a 的值:' . $a . ', $b 的值:' . $b, '<br>'; // 输出原始值
/**
* 原始二进制:
* $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, '<br>'; // 输出结果值
或者 str_replace 处理
<?php
$a = "This is A"; // a变量原始值
$b = "This is B"; // b变量原始值
echo '交换之前 $a 的值:' . $a . ', $b 的值:' . $b, '<br>'; // 输出原始值
$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, '<br>'; // 输出结果值
4.Strtoupper/strtolower 遇到中文会乱码
5.Php-fpm 和 NGINX 通信机制
CGI就是规定要传哪些数据,以什么样的格式传递给后方处理这个请求的协议,例如 URL、查询字符串、POST数据、HTTP header,缺点是每次请求都有启动和退出操 作,不适合并发场景 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 运行的三种模式:
8.Php-fpm 运行的逻辑:
Fpm 的实现就是创建一个 master 进程,在 master 进程中创建 worker pool 并监听 socket,然后 fork出多个子进程(work),这些 worker 在启动后阻塞在 fcgi_accept_request() 上,各自 accept 请求,有请求到达后 worker 开始读取请求数 据,读取完成后开始处理然后再返回,在这期间是不会接收其它请求的,也就是说 fpm 的子进程同时只能响应一个请求,只有把这个请求处理完成后才会 accept 下一个请 求,所以有多少子进程就能同时处理多少请求。
10.Fpm 工作流程:
11.Nginx 与 php-fpm 有两种通信方式:
tcp socket和 unix socket,unix 不需要经过 网络协议栈,不需要打包拆包,计算校验和,维护序号和应答,只是将应用层数据从一 个进程拷贝到另一个进程,减少不必要的 tcp 开销,高并发时性能不稳定,tcp 模式可 以保证通信的正确性和完整性,效率可以通过负载均衡等优化。
一段PHP代码会经过词法解析、语法解析等阶段,会被翻译成一个个指令 (opcode),然后 zend 虚拟机会顺序执行这些指令。PHP 本身是用C语言实现的,因 此最终调用的也是C语言的函数,实际上我们可以把 PHP 看做一个C语言开发的软 件。Opcode 是php执行的最基本单位
12.数据库连接池实现原理
连接池的作用就是为了提高性能,将已经创建好的连接保存在池中,当有请求来时,直 接使用已经创建好的连接对 Server 端进行访问。这样 省略了创建连接和销毁连接的过 程,从而提高性能。
13.Redis 常见应用场景
首页热点新闻/商品,避免频繁读取数据库 bitmap 用来记录连续签到/登录情况 新 闻阅读量的计数器 最新新闻列表 lpush 就行,然后读取 简单的消息发布系统 pubsub sortedset 来做 排行榜
14.负载均衡的几种实现方式及原理
1 ip负载均衡,相当于多一到N次重定向,过程 2 DNS 负载均衡,DNS支持一个域名多个ip地址了 3 反向代理负载均衡,NGINX 根据一定规则进行请求分发 4 F5硬件级别 6 CDN 对于静态文件的负载均衡 负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和 网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
15.数据库主从复制的原理,会不会延迟,会该怎样解决
三个要点:网络延迟,master 负载 slave 负载 slave 对数据安全性的要求
原理
Tps 是事务数/秒 qps 是每秒查询率
延迟原因:主库的 tps 并发较高时,产生的 ddl 超过 slave 的执行,或者网络延迟较 大,也有可能是从库性能很差
解决:减少网络延迟,关闭 slave 的 sync_binlog 设置成大点就行,累计多次事务之后 刷盘 innodb_flush_log_at_trx_commit = 2 事务提交之后刷盘,slave 上也可以关闭 这个,缺点是意外断电了会丢失数据
16.如何保障数据的可用性,即使被删库了也能恢复到分钟级别。你会怎么做。
数据库集群方案就行,删掉主库了会自动选举从库,业务保持稳定,然后就是精细化的 备份