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
    修饰符实例子类类内
    publicOOO
    protectedXOO
    privateXXO
  • 请写出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/38177

    php:
    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

相关文章

此处评论已关闭