php经典面试题八 -- Swoole相关

臭大佬 2020-07-02 20:55:33 8582
php  linux 
简介 php经典面试题八 -- 各种概念及Swoole相关

RESTful API风格

链接地址:RESTful API风格

网络七层协议

链接地址:网络七层协议、三次握手、四次挥手

并发与并行

并发

并发是不同的代码块交替执行,也就是交替可以做不同的事情。

当你在敲代码的时候,突然女朋友回来了(程序员怎么可能有女朋友?),然后你去开门,开完门后你又继续敲代码(是的,你这样肯定没有女朋友)…..这就是并发,敲代码和开门交替进行。

并行

并行是不同的代码块同时执行,也就是同时可以做不同的事情。

举个栗子:
我现在在敲代码的同时,我在听《麻雀》,“相信海枯石烂,也许我笨蛋….”,真香…..,我一边敲代码一边听歌,这就是并行。

程序、进程、线程、 协程

程序

编译好的二进制文件,不占用资源。

进程

活跃着的程序,占用资源,是操作系统的基本单位。表示一个程序的上下文执行活动(打开、执行、保存…),是系统资源分配的最小单位,一个程序至少有一个进程。

进程状态图

我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程再创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。

  孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

  僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程控制块(PCB)仍然保存在系统中。这种进程称之为僵死进程。

具体查看如下文章:
孤儿进程和僵尸进程总结

进程间通信(IPC)

管道(Pipe)、命名管道(FIFO)、消息队列(Message Queue) 、信号量(Semaphore) 、共享内存(Shared Memory);套接字(Socket)。

线程

进程的执行单位,与进程共享资源。
一个进程至少有一个线程。进程执行程序时候的最小调度单位(执行a,执行b…),是CPU调度的最小单位.进程相当于一个容器,而线程而是运行在容器里面的,因此对于容器内的东西,线程是共同享有的,因此线程间的通信可以直接通过全局变量进行通信,共享意味着竞争,导致数据不安全,为了保护内存空间的数据安全,引入”互斥锁”。
线程状态图

协程

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。
迭代器最基本的规定了对象可以通过next返回下一个值,而不是像数组,列表一样一次性返回。
生成器: 使用 yield 关键字的函数,生成器也可通过next返回下一个值。

进程与程序关系:

用户角度:进程是程序的一个执行过程。
操作系统角度:进程是系统分配的内存、CPU时间片等资源的基本单位。

进程与程序区别:

进程是戏剧,程序是剧本,戏剧根据剧本来。
程序是一个静态文件,存于磁盘中。
进程处于动态程序运行的系统资源管理实体。

多线程比,协程有何优势?

极高的执行效率:因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显;
不需要多线程的锁机制:因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

通信

管道pipe:

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

消息队列MessageQueue:

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

共享存储SharedMemory:

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

信号量Semaphore:

信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

套接字Socket:

套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

信号 ( sinal ) :

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

Swoole结构和流程

全局变量(global)为什么在onRequest函数中不能使用。

因为swoole是多线程编程,global是不能在多个进程间共享的。如果要实现预期的效果,需要使用swoole_table的相关函数。

PHP的垃圾回收机制

  1. PHP可以自动进行内存管理,清除不需要的对象,主要使用了引用计数

  2. 在zval结构体中定义了ref_count和is_ref , ref_count是引用计数 ,标识此zval被多少个变量引用 , 为0时会被销毁
    is_ref标识是否使用的 &取地址符强制引用。

gc的关键就是能说出引用计数的原理和写时拷贝

详情查看:PHP的垃圾回收机制

  1. 为了解决循环引用内存泄露问题 , 使用同步周期回收算法
    比如当数组或对象循环的引用自身 , unset掉数组的时候 , 当refcount-1后还大于0的 , 就会被当成疑似垃圾 , 会进行遍历 ,并且模拟的删除一次refcount-1如果是0就删除 ,如果不是0就恢复

工作流程

当客户端请求发送到master,会被 main reactor 接收,
将读写操作的监听注册到对应的Reactor线程中,并通知Worker进程处理Onconnect(接收到连接的回调)
客户端的数据会通知对应的Reactor发送给Worker进程处理。
如果Worker投递任务 将数据通过管道发送给Task。Task处理完成后会发送给Worker,
Worker会通知Reactor发送数据给客户端。
当Worker出现异常关闭,Manager会重新创建一个Worker进程,保证Worker数量是固定的。

为什么客户端请求一次数据,服务器接收两条记录

icons

为什么onReceive收到的数据这么大

客户端发送的多次请求,服务端是可以一次性接收的。并不是客户端发送一次,服务端接收一次
不可以。

进程,线程与多核,多cpu之间的关系

进程,线程与多核,多cpu之间的关系