php 面试题
第一部分
你做过的一个websocket程序后端用什么实现的?
gatewayworker
用什么做的压测?
ab -n 10000 -c 200 https://baidu.com
- swoole的事件轮询机制和原理是什么?
https://blog.csdn.net/qq_21630623/article/details/77946041
https://wiki.swoole.com/wiki/page/356.html
https://wiki.swoole.com/wiki/page/p-differences_with_go.html
事件轮询(EventLoop)
是一个很重要的概念,指的是计算机系统的一种运行机制。
EventLoop 是一个程序结构,用于等待和发送消息和事件。
简单说,就是在程序中设置两个线程:一个负责程序本身的运行,称为"主线程";另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"EventLoop线程"(可以译为"消息线程")。
运行以后的程序叫做"进程"(process),一般情况下,一个进程一次只能执行一个任务。
如果有很多任务需要执行,不外乎三种解决方法。
(1)排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。
(2)新建进程。使用fork命令,为每个任务新建一个进程。
(3)新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。
IO模型
go语言使用单线程eventloop处理IO事件,多线程实现协程调度,执行用户层代码
swoole使用多线程eventloop处理IO事件,多进程执行用户层php代码
Go协程(goroutine)是运行在多线程上的,线程可以共享堆栈和文件描述符,功能更强大,在实现连接池、并发库方面更有优势。额外的带来的一个问题是,存在数据同步问题,需要用户自行考虑加锁。
Swoole的用户代码运行在多进程环境,无需考虑加锁问题。但无法直接访问内存和资源。需要借助Task进程实现中转。
多线程
Swoole4的协程调度器是单线程的,因此不存在数据同步问题,同一时间只会有一个协程在运行
Go协程调度器是多线程的,同一时间可能会有多个协程同时执行
因此在Swoole4协程中操作全局变量是不需要加锁的。
进程共享数据
使用Table和Atomic对象,或者其他共享内存数据结构
使用IPC进程间通信
借助存储实现数据的共享和中转,如Redis、MySQL或文件操作
- swoole协程工作原理是什么?
https://wiki.swoole.com/wiki/page/956.html
4.0版本使用了PHP+C的双栈模式。创建协程时会创建一个C栈,默认尺寸为2M,创建一个PHP栈,默认为8K。
C栈
C栈主要用于保存底层函数调用的局部变量数据,用于解决call_user_func、array_map等C函数调用在协程切换时未能还原的问题。4.0版本无论如何切换协程,底层总是能正确地切换回原先的C函数栈帧继续向下执行。
PHP栈
PHP栈主要保存PHP函数调用的局部变量数据,主要是zval结构体,PHP中标量类型,如整型、浮点型、布尔型等是直接保存在zval结构体内的,而object、string、array是使用引用计数管理,在堆上存储的。8K的PHP栈足以保存整个函数调用的局部变量。
协程切换
C栈切换使用汇编代码,用于保存寄存器,切换指令序列。PHP栈的切换是跟随C栈切同步进行的。
底层会切换EG(vm_stack)使得PHP恢复到正确的PHP函数栈帧。
协程调度
4.0协程实现中,主协程即为Reactor协程,负责整个EventLoop的运行。主协程实现事件监听,在IO事件完成后唤醒其他工作协程。
协程挂起
在工作协程中执行一些IO操作时,底层会将IO事件注册到EventLoop,并让出执行权。
协程恢复
当主协程的Reactor接收到新的IO事件,底层会挂起主协程,并恢复IO事件对应的工作协程。该工作协程挂起或退出时,会再次回到主协程。
swoole协程是运作在线程还是进程上?
swoole使用多线程eventloop处理IO事件,多进程执行用户层php代码
redis里哪个数据结构可以做排行榜?列举redis常用数据结构有哪些?
常用:字符串(String) 哈希(Hash) 列表(List) 集合(Set) 有序集合(sorted set) HyperLogLog 有序集合(sorted set)通过 ZADD(添加) ZREVRANGE(从大到小) Zrange(从小到大)
- 高并发下,读写mysql可能出现数据错误,可能因为什么?一般如何处理?事务问题
https://www.cnblogs.com/huanongying/p/7021555.html
https://blog.csdn.net/liwenqiang758/article/details/81013005
1. mysql读可以并发,某些业务先读后写会,如果是某个用户并发请求,可能都是一样的数据
2. mysql事务下有幻读情况
事务要素
ACID 原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability)
并发问题
不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
脏读:(读到了未提交可能被丢弃的脏数据)事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
幻读:(有增删数据但是当前事务查不到)系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
不可重复读:(有修改数据但是查不到)事务 A 多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。
隔离级别
mysql默认的事务隔离级别为:可重复读(repeatable-read)
读未提交(read uncommitted)
读已提交(read committed)
可重复读(repeatable read)
串行化(serializable)
可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。
MVCC只在REPEATABLEREAD和READCOMMITTED两个隔离级别下工作。
- 死锁的产生条件或者举例?
https://www.cnblogs.com/zejin2008/p/5262751.html
https://www.cnblogs.com/baizhanshi/p/6889261.html
https://blog.csdn.net/cug_jiang126com/article/details/50544728
S锁,共享锁,读锁,shared lock为同义词,即read lock
X锁,排他锁,写锁,exclusive lock为同义词,即write lock,实例:for update
特例
实测lock in share mode与6889261.html有不同,根据50544728文章,这是意向共享锁
实测当前会话可以读也可以写入修改等
读锁,可以重复加读锁,其他会话不能对数据再加写锁
写锁,只有当前会话可以修改,其他事务不能加任何锁,直到当前会话释放锁
死锁
两个或两个以上的进程在执行过程中,争夺资源而造成的一种*互相等待*的现象,若无外力作用,它们都将无法推进下去.
根据观察,悲观锁:如果一个会话里出现两处以上的加锁,容易死锁.乐观锁:先加锁,后更新容易死锁
产生原因
两个(或以上)的Session加锁的顺序不一致。
写锁死锁
事务1锁住id = 9 for update,事务2试图加锁id < 10 for update,此时事务2会等待事务1释放锁,此时事务1执行update id = 10,事务1又会等待事务2释放锁,他们两个互相等待,系统会报错死锁
读锁死锁
事务1
step1:select * from index_test where a = "20" lock in share mode;加共享锁
step3:update index_teset set b = "30" where a = "20";自动尝试加排它锁
事务2
step2:update index_teset set b = "40" where a = "20";自动尝试加排它锁
以上实例中,step2会产生死锁报错
- 悲观锁,乐观锁都如何实现?
https://blog.csdn.net/lp2388163/article/details/80683383
悲观锁
for update
乐观锁
1. 先查询该数据(带上version) select * from order where id = 1
2. 执行update时候where带上version,这样即使两个会话同时update,mysql自动加锁机制也只会更新到一条
乐观锁死锁
事务A
step1:update order set price = 1 where id = 1
step3:update order set price = 2 where id = 2
事务B
step2:update order set price = 1 where id = 2
step4:update order set price = 2 where id = 1
如上所示,执行到4的时候,事务B等待A释放锁,A等待B释放锁,形成死锁
有一字段version为1,事务A开始把他改为2,事务B开始把他改为3,各自提交前重新读version,分别读到几?
此问题有些问题,首先两个事务使用repeatable read隔离级别,但是mysql自动加锁,所以事务A中改为2的时候,这个条数据就被加锁了,事务B会被写锁阻塞 当然题目原意还是mysql默认使用repeatable read的隔离级别,他们各自会话的修改,提交之前都读到各自的值,可重复读
事务的特性之一就是隔离性,mysql事务默认隔离级别是什么样的?
可重复读repeatable read
有一个表,事务A开始读取到表中有a,b,c三行,此时事务B插入一行d,事务A提交前又读表一次,他读到的数据时什么?
默认使用可重复读repeatable read:同一会话的事务,多次读取,结果一致 事务具有隔离性:不同的事务之间彼此没有任何干扰
如何解决以上数据不一致,不同步的问题?如何解决mysql幻读问题?
- mysql配置了主从同步,主库事务把字段version从1改为2,在同步情况下此时读取从库version是多少?为什么?
- mysql主从同步的原理什么?
https://blog.csdn.net/qq_41772936/article/details/80380950
https://blog.csdn.net/hardworking0323/article/details/81046408
https://www.cnblogs.com/cnmenglang/p/6393769.html
master IO线程,slave开启 IO线程 SQL线程
Slave 通过IO线程连接master,并且请求某个bin-log,position之后的内容。
MASTER服务器收到slave IO线程发来的日志请求信息,io线程去将bin-log内容,position返回给slave IO线程。
slave服务器收到bin-log日志内容,将bin-log日志内容写入relay-log中继日志,创建一个master.info的文件,该文件记录了master ip 用户名 密码 master bin-log名称,bin-log position。
slave端开启SQL线程,实时监控relay-log日志内容是否有更新,解析文件中的SQL语句,在slave数据库中去执行
mysql-5.6.3已经支持了多线程的主从复制
MySQL主从不同步情况
网络的延迟 主从两台机器的负载不一致 max_allowed_packet设置不一致 自增键不一致 key自增键开始的键值跟自增步长设置不一致引起的主从不一致 同步参数设置问题 自身bug 版本不一致
mysql锁机制可能降低效率,确保单用户不能并发访问,用redis如何实现?用什么数据结构?
redis有5中常用结构 string hash list set sortedset 使用string时需要结合get set方法 使用set时使用sadd方法,返回添加进去的新元素数量,如果为0则并发操作,如果超过1则首次操作
- 项目要求前端可以合法的并发提交文件,但程序要求每个人只能传5个文件,数据库里可能原来就有以前上传记录,如何保证程序不出问题?不能多传,用redis、mysql、swoole都如解决?
https://wiki.swoole.com/wiki/page/p-table.html
redis string类型 Incr命令
mysql 加锁for update
swoole可使用memory模块例如table的incr方法
book表查询bookid=1的所有数据并使用for update语句,bookid非索引非主键,锁的范围是什么?
mysql在使用索引条件时for udpate只锁住行,非索引时锁表
- mysql innodb引擎根据什么来加锁?
https://www.cnblogs.com/crazylqy/p/7611069.html
http://www.cnblogs.com/crazylqy/p/7773492.html
MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。MVCC最大的好处,相信也是耳熟能详:读不加锁,读写不冲突。
在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
快照读:简单的select操作,属于快照读,不加锁。(当然,也有例外,下面会分析)
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
InnoDB存储引擎的数据组织方式,是聚簇索引表:完整的记录,存储在主键索引中,通过主键索引,就可以获取记录所有的列。
不用for update和in share mode等语句是否会产生死锁?
会的 mysql在update delete insert时候会自动加锁 例如: 事务1 step1:update index_test set b = "b" where id in (1);#为id=1加锁 step4:update index_test set b = "b" where id in (2);#等待step解锁 事务2 step2:update index_test set b = "b" where id in (2);#为id=2加锁 step3:update index_test set b = "b" where id in (1);#等待step1解锁
如果出现死锁了,我们如何处理?
kill 实测mysql会报错
- 描述php-fpm的运作原理是什么?
https://blog.csdn.net/u013474436/article/details/52972699
php-fpm即php-Fastcgi Process Manager
php-fpm是 FastCGI 的实现,并提供了进程管理的功能。
进程包含 master 进程和 worker 进程两种进程。
master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。
php-fpm和nginx的通信方式什么?
nginx转发php类型的请求可以通过fastcgi的方式,fastcgi支持1.TCP和2.unix domain socket两种方式。
- unix socket和tcp socket有什么区别?
https://www.jianshu.com/p/aefe19723667
Unix domain socket
Unix domain socket,也叫IPC socket(inter-precess communication socket,也就是进程间通信套接字),用于同一台主机上的不同进程间交换数据,是Posix系统的标准组件。可以传输字节流(byte stream,SOCK_STREAM,TCP)或者数据报(datagram,SOCK_DGRAM,UDP).除了传输数据以外,还可以使用Unix domain socket传输文件描述符(file descriptor)。
IP socket
IP socket要利用主机的传输层(tcp),可以用于同一台主机上不同进程间的通信,也可以用于网络上不同主机间的通信。
- 用户发起了一个请求,传到了server,此时用户主动中断了请求,php还会继续执行吗?
https://www.cnblogs.com/yjf512/p/5362025.html
正常情况下,如果客户端client异常推出了,服务端的程序还是会继续执行,直到与IO进行了两次交互操作。服务端发现客户端已经断开连接,这个时候会触发一个user_abort,如果这个没有设置ignore_user_abort,那么这个php-fpm的程序才会被中断。
- php生产环境有什么好的定位问题的方式?
https://segmentfault.com/q/1010000017999503/
日志
set_error_handler
set_exception_handler
register_shutdown_function
- 用什么工具分析php程序日志?
微服务架构中,A可能调用B服务,B可能调用C服务,某用户请求异常,其他用户正常,如何确认问题在哪个服务里?
知道每个服务应该有的输入输出,借助requestid查找具体出错的服务
- 从开发到测试到上线,使用什么样的持续集成技术?
- 如何实现单点登录?
如何解决跨域问题?
jsonp header
组合索引顺序A,B,C,读的时候where中的顺序是A,C,B,可以命中索引吗?where中只有A,C,可以命中吗?
可以,最左原则
- 加索引有没有什么好的规范?
https://blog.csdn.net/u014172271/article/details/79943161
使用最频繁的列放到联合索引的左侧。
避免建立冗余索引和重复索引。
写一个单例模式
// 单例模式 class Single { //声明一个静态变量 public static $instance; //声明私有构造方法为了防止外部代码使用new来创建对象。 private function __construct() { } //声明一个getinstance()静态方法,用于检测是否有实例对象 public static function getInstance() { if (!self::$instance) { self::$instance = new self(); } return self::$instance; } } // 工厂模式 class Factory { //创建一个基本的工厂类 public static function fac($id) { //创建一个返回对象实例的静态方法 if (1 == $id) { return new A(); } elseif (2 == $id) { return new B(); } } } //创建一个接口 interface FetchName { public function getname(); // } class A implements FetchName { private $name = "AAAAA"; public function getname() { return $this->name; } } class B implements FetchName { private $name = "BBBBB"; public function getname() { return $this->name;} } $o = Factory::fac(1); //调用工厂类中的方法 if ($o instanceof FetchName) { echo $o->getname(); //DDDDD } $p = Factory::fac(2); echo $p->getname(); //CCCCC
写一个函数计算如下数列的第n个值:1,1,2,3,5,8,13,21
// 非递归写法 function fbnq1($n) { if ($n <= 0) { return 0; } //设第一个值和第二个值为1 $array[1] = $array[2] = 1; for ($i = 3; $i <= $n; $i++) { //后面的值都是当前值的前一个值加上前两个值的和 $array[$i] = $array[$i - 1] + $array[$i - 2]; } return $array; } // 递归写法 function fbnq2($n) { if ($n <= 0) { return 0; } if ($n == 1 || $n == 2) { return 1; } return fbnq2($n - 1) + fbnq2($n - 2); }
补充
php类的权限控制修饰符和区别
如果没有指明,默认均为public 修饰符 实例 子类 类内 public O O O protected X O O private X X O 请写出3种设计模式,并用合适模式及伪代码实现mysql连接
https://www.cnblogs.com/leedaily/p/8250158.html
策略 单例 工厂 注册 适配器 观察者策略模式
接口定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。面向接口编程.
- 抽象策略角色(定义接口)
- 具体策略角色(实现接口)
环境角色(调用抽象策略角色)
单例模式
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例
工厂模式
工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了
注册模式
已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。
适配器模式
将各种截然不同的函数接口封装成统一的API。 是在想使用一个已经存在的类,但是他的接口并不符合要求,因为在编码过程中要遵循对扩展开放,对修改关闭的原则,所以不能对原有的类进行修改,这时便需要使用适配器模式,将原有的类适配成自己需要的形式。有类适配器和对象适配器两种适配器。
策略模式和适配器模式区别interface IDatabase { public function connect($host, $user, $passwd, $dbname); public function query($sql); public function close(); } class MySQLi implements IDatabase { protected $conn; function connect($host, $user, $passwd, $dbname) { $conn = mysqli_connect($host, $user, $passwd, $dbname); $this->conn = $conn; } function query($sql) { return mysqli_query($this->conn, $sql); } function close() { mysqli_close($this->conn); } }
观察者模式
观察者模式(Observer),当一个对象状态发生某种变化时,依赖它的对象全部会收到通知,并自动更新
类的属性可以序列化后保存在session中,从而以后可以恢复整个类,这要用到的函数是?
serialize unserialize
请说说长连接和短连接的理解,至少各举一个应用场景
https://www.cnblogs.com/linuxws/p/10312834.html 长连接:长时间保持客户端与服务端的连接状态.在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包.例如:手机推送,websocket聊天,对战 短连接:指客户端和服务端有数据交互时,就建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送.例如:注册表单等数据刷新频度较低的场景
请写出InnoDB主要特点
支持事务,提供外键,提供多版本并发控制(mvcc)的行锁,一致性非锁定读
请写出至少3个索引类型及InnoDB索引结构原理
https://blog.csdn.net/qq_32534441/article/details/98767374 https://blog.csdn.net/banxia727706033/article/details/94995047 主键索引,普通索引,唯一索引,组合索引,全文索引 InnoDB表上的主键作为聚集索引,如果表上没有主键则InnoDB寻找到一个non-null且unique列作为聚集索引。如果都没有,则自主创建一个包含行ID的隐藏聚集索引。 主键索引的叶子结点存放了整行记录,普通索引的叶子结点存放了主键ID,查询的时候需要做一次回表查询 当查询的字段刚好是索引的字段或者索引的一部分,就可以不用回表
请解释6个shell命令的主要用途
top 实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。 ps Linux中的ps命令是Process Status的缩写。ps命令用来列出系统中当前运行的那些进程。ps命令列出的是当前那些进程的快照,例如:ps -aux df 显示目前在Linux系统上的文件系统的磁盘使用情况统计 chmod Linux/Unix 的文件调用权限分为三级 : 文件拥有者、群组、其他。利用 chmod 可以藉以控制文件如何被他人所调用。 grep 用于查找文件里符合条件的字符串,例如:grep test test* #查找前缀有“test”的文件包含“test”字符串的文件 wc 统计文件的行数,字数,字节数 ls 列出目前工作目录所含之文件及子目录,例如:ls -l kill 例如:kill -9 进程号
请写出让一个程序后台运行并把输出重定向到指定的文件
https://www.cnblogs.com/jinxiao-pu/p/9131057.html https://blog.csdn.net/themanofcoding/article/details/81948094 https://www.cnblogs.com/jinxiao-pu/p/9131057.html nohup command > myout.log 2>&1 & &:指在后台运行,但当用户推出(挂起)的时候,命令自动也跟着退出 nohup:不挂断的运行,注意并没有后台运行的功能,,就是指,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,例如我们断开SSH连接都不会影响他的运行,注意了nohup没有后台运行的意思;&才是后台运行
请解释这3个漏洞类型含义及防护措施:xss,csrf,sql注入
https://blog.iguojin.com/php/5167.html xss:未经HTML实体编码htmlspecialchars,js便能够注入到动态页面中,例如:url传参数或者用户提交数据 csrf:恶意请求通过伪装成受信任用户来访问网站,例如:通过src携带cookies就可以伪造get请求 sql注入:构造请求,让服务器执行恶意的SQL命令 防护措施: xss:输入时候可以替换有风险的字符串,输出使用htmlspecialchars csrf:检测HTTP_REFERER,增加token sql注入:预编译,参数绑定转义(mysqli_real_escape_string)
请简述tcp协议三次握手过程
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认,SYN:同步序列编号(Synchronize Sequence Numbers) 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.
请简要绘制hash数据结构图
https://wenku.baidu.com/view/21d6f41fff00bed5b9f31d17.html
2019-10-20
PHP第三方包如何引入?
composer require
php自动加载怎么实现的?
spl_autoload_register __autoload已废除
session如何工作的?
http://www.imooc.com/article/38177php: session_start(); $_SESSION header: Set-Cookie: PHPSESSID=8q8nkl8jnbgokj1hoi533jie83; path=/
自定义session
1.实现SessionHandlerInterface接口 2.session_set_save_handler
redis实现锁的方式?
sadd getset
redis还有什么样的数据结构?
string hash list set sortedset
redis replication和redis cluster
redis主从复制如何做?
redis集群如何把key分到不同的node?
mysql有哪几种锁?
https://www.cnblogs.com/drizzle-xu/p/9713018.html分为行锁,表锁,页锁 InnoDB行锁有以下类型: 共享锁(S) 排他锁(X) InnoDB内部使用的意向锁(不需用户干预): 意向共享锁(IS) 意向排他锁(IX) InnoDB行锁是通过给索引上的索引项加锁实现的,这意味着只有通过索引条件检索数据,InnoDB才使用行级锁,否则InnoDB使用表锁 当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB使用间隙锁(Next-Key锁)
什么条件会加表级共享锁?
悲观锁,乐观锁
mysql默认隔离级别如何?
可重复读级别解决了什么并发问题?
当前读和快照读
快照读(snapshot read)
简单的select操作(不包括 select ... lock in share mode, select ... for update)
2.当前读(current read)
select ... lock in share mode
select ... for update
insert
update
delete- mysql主从复制怎么做?
- mysql事务是如何实现的?
https://www.cnblogs.com/develop-SZT/p/10339138.html - 一个事务做了哪些事情?
- 还有什么技能?
上海三体云动
- swoole的reactor worker manager taskworker等进程是如何协调工作的?
https://wiki.swoole.com/wiki/page/66.html
https://wiki.swoole.com/wiki/page/347.html
https://wiki.swoole.com/wiki/page/163.html
IO事件循环
在Linux系统下使用epoll, MacOS/FreeBSD下使用kqueue
task进程没有事件循环,进程会循环阻塞读取管道
Reactor线程
Swoole的主进程是一个多线程的程序。其中有一组很重要的线程,称之为Reactor线程。它就是真正处理TCP连接,收发数据的线程。
完全是异步非阻塞的模式
全部为C代码,除Start/Shudown事件回调外,不执行任何PHP代码
Reactor以多线程的方式运行
接受由Reactor线程投递的请求数据包,并执行PHP回调函数处理数据
Manager进程
swoole中worker/task进程都是由Manager进程Fork并管理的。
Worker进程
Worker进程内可以像普通的apache+php或者php-fpm中写代码
生成响应数据并发给Reactor线程,由Reactor线程发送给TCP客户端
TaskWorker进程
接受由Worker进程通过swoole_server->task/taskwait方法投递的任务
完全是同步阻塞模式
TaskWorker以多进程的方式运行
- swoole解决了什么问题使得能提高php程序的性能?
- 协程,线程,进程之间有何区别?
- 有了js为何还会出现ts?
- 为何php7.4还无法加入jit?
- 进程间通信有哪些常用方法?
https://blog.csdn.net/wh_sjc/article/details/70283843
管道 FIFO 消息队列 信号量 共享内存
- redis使用中要面对缓存穿透,缓存雪崩,缓存击穿等问题,要如何解决缓存雪崩问题?
https://baijiahao.baidu.com/s?id=1619572269435584821
缓存穿透
缓存穿透,是指查询一个数据库一定不存在的数据,不经过缓存直接查询数据库。
正常很多人,数据为空就不存缓存,导致被恶意利用,应该即使为空也要写入缓存,只要设定的缓存过期时间较短
缓存雪崩
缓存雪崩,是指在某一个时间段,缓存集中过期失效。
对缓存时间加个随机因子.不同分类缓存时间不同
缓存击穿
缓存击穿,是指一个key非常热点,在不停的扛着大并发,当这个key在失效的瞬间,大并发就击穿缓存直接压力给数据库
后台脚本定时主动刷新缓存,增加开始缓存时间提前检查更新,加锁没有缓存时必须等待
- redis分布式锁的工作原理是什么?
https://www.jianshu.com/p/2d22df6eccf8
SETNX 命令在设置成功时返回1,设置失败时返回 0
GETSET 将键 key 的值设为 value , 并返回键 key 在被设置之前的旧值。键 key 在被设置之前并不存在, 那么命令返回 nil 。当键 key 存在但不是字符串类型时, 命令返回一个错误。
- mysql一主多从可以解决读的问题,但是如果业务暴增,主库将面临较大写压力可能随时崩溃,如何解决这个问题,让系统保持高可用?
https://blog.csdn.net/houdaxiami/article/details/79796330
http://www.cnblogs.com/luoahong/articles/8043035.html
https://blog.csdn.net/m0_37328475/article/details/82684699
https://blog.51cto.com/qiuyt/1930629
MHA
- 如何解决系统报too many open files问题?为何会出现这个问题?
http://www.cnblogs.com/fsw-blog/p/4543914.html
ulimit -n
/etc/security/limits.conf
最后更新于 2019-10-20 15:21:03 并被添加「PHP 面试题」标签,已有 807 位童鞋阅读过。
此处评论已关闭