1、Websocket协议的应用场景,解决了什么问题,列举你所了解的实现了websocket协议的项目或者软件(不分语言)。
答:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术
的一种。在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,
然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
2、简述Https双向认证的主要过程。
答:
② 服务器将自己的证书,以及同证书相关的信息发送给客户浏览器。
③ 客户浏览器检查服务器送过来的证书是否是由自己信赖的 CA 中心所签发的。如果是,就继续执行协议;如果不是,客户浏览器就给客户一个警告消息:警告客户这个证书不是可以信赖的,询问客户是否需要继续。
④ 接着客户浏览器比较证书里的消息,例如域名和公钥,与服务器刚刚发送的相关消息是否一致,如果是一致的,客户浏览器认可这个服务器的合法身份。
⑤ 服务器要求客户发送客户自己的证书。收到后,服务器验证客户的证书,如果没有通过验证,拒绝连接;如果通过验证,服务器获得用户的公钥。
⑥ 客户浏览器告诉服务器自己所能够支持的通讯对称密码方案。
⑦ 服务器从客户发送过来的密码方案中,选择一种加密程度最高的密码方案,用客户的公钥加过密后通知浏览器。
⑧ 浏览器针对这个密码方案,选择一个通话密钥,接着用服务器的公钥加过密后发送给服务器。
⑨ 服务器接收到浏览器送过来的消息,用自己的私钥解密,获得通话密钥。
⑩ 服务器、浏览器接下来的通讯都是用对称密码方案,对称密钥是加过密的。
3、CGI、php-cgi、Fastcgi、php-fpm几者的关系。
答:
CGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php,perl,tcl等。
PHP-CGI是PHP自带的FastCGI管理器。
FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。它还支持分布式的运算,即 FastCGI 程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。
PHP-FPM是一个PHP FastCGI管理器,是只用于PHP的。PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。
4、PHP有哪几种运行模式,并说明每种模式应用场景。
答:
1、CGI
2、Fastcgi
3、module形式,一般用于apache模块,模式是以mod_php5模块的形式集成,此时mod_php5模块的作用是接收Apache传递过来的PHP文件请求,并处理这些请求,然后将处理后的结果返回给Apache。
4、cli模式。命令行执行php
5、简述PHP类的自动加载原理和实现方式。
6、简述对观察者模式的理解,用伪代码说明观察者模式。
<?php //观察则模式 // 目标 interface Observables{ public function attach(Observer $ob):void; public function detach(Observer $ob):void; public function notify():void; } // 具体目标 class Saler implements Observables{ protected $obs = []; protected $range = 0; public function attach(Observer $ob):void{ $this->obs[] = $ob; } public function detach(Observer $ob):void{ foreach ($ob as $value) { if ($value != $ob) { $this->obs[] = $value; } } } public function notify():void{ if ($this->range != 0) { foreach ($this->obs as $ob) { $ob->update($this); } } } public function increPrice(int $range):void{ $this->range = $range; } public function getRange():int{ return $this->range; } } // 观察者 interface Observer{ public function update(Observables $obv):void; } // 具体观察者1 class PoorBuyer implements Observer{ public function update(Observables $obv):void{ if ($obv->getRange() > 0) { echo "穷人:涨价了不买了\n"; }else{ echo "穷人:降价了赶紧买\n"; } } } // 具体观察者2 class RichBuyer implements Observer{ public function update(Observables $obv):void{ if ($obv->getRange() > 0) { echo "富人:涨价了啊,价格波动没关系,赶紧买吧\n"; }else{ echo "富人:降价了啊,价格波动没关系,赶紧买吧\n"; } } } $poor = new PoorBuyer(); $rich = new RichBuyer(); $saler = new Saler(); $saler->increPrice(-1); $saler->attach($rich); $saler->attach($poor); $saler->notify();
7、简述对适配器模式的理解,如果日常开发中使用了适配器模式,请写出伪代码。
8、PHP匹配IP地址的正则表达式,要求匹配结果为有效的IP地址。
9、PHP匹配邮箱的正则表达式。
$mail = 'kevinlee@test.com'; //邮箱地址 $pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/"; preg_match($pattern, $mail, $matches); var_dump($matches); //输出匹配结果
10、简述Laravel应用的生命周期。
11、如何实现多机器session共享?
12、请阐述opcache原理。
13、请简述进程与线程的区别。
答:
1、 址空间和其他资源(如打开文件):进程间相互独立,同一进程的每个线程间共享。某进程内的线程在其他进程不可见。
2、通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信—需要进程同步和互斥手段的辅助,以保证数据的一致性。
3、调度和切换:线程上下文切换比进程上下文切换要快得多
4、在多线程操作系统中,进程不是一个可执行的实体
14、在mysql中存有2000W数据,redis中只存20W数据,如何保证redis中的数据都是热点数据?
15、请写出HTTP工作过程步骤。
16、抽象工厂模式。
<?php abstract class AbstractClass{ abstract public function myTest():void; } class Mysql extends AbstractClass{ public function myTest():void{ echo 'mysql'; } } class MyPdo extends AbstractClass{ public function myTest():void{ echo "pdo"; } } class Factory{ public static function myFactory(string $className='Mysql'):object{ return new $className(); } } $mysql = Factory::myFactory('Mysql'); $pdo = Factory::myFactory('MyPdo'); var_dump($pdo); var_dump($mysql); $mysql->myTest(); echo "\n"; $pdo->myTest();
17、单列模式模式
<?php class Single { private static $instance = null; private function __construct(){} public static function getInstance(){ if (!(self::$instance instanceof self)) { self::$instance = new self; } return self::$instance; } private function __clone(){} } $test1 = Single::getInstance(); $test2 = Single::getInstance(); var_dump($test1); var_dump($test2);
18、Redis的两种持久化RDB和AOF的区别。
RDB:在指定时间间隔内,将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时是将快照文件直接读到内存中,来达到恢复数据的。在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。通过触发快照的形式,来做到将指定时间间隔内的数据持久化到dump.rdb。例如,可以2分钟内持久化一次,将对数据库的写操作,备份到磁盘上的dump.rdb。如何触发持久化呢?可以通过查看或者设置redis.conf配置文件来指定触发规则。
RDB优点:
1、如果要进行大规模数据的恢复,RDB方式要比AOF方式恢复速度要快。
2、RDB可以最大化Redis性能,父进程做的就是fork子进程,然后继续接受客户端请求,让子进程负责持久化操作,父进程无需进行IO操作。
3、RDB是一个非常紧凑(compact)的文件,它保存了某个时间点的数据集,非常适合用作备份,同时也非常适合用作灾难性恢复,它只有一个文件,内容紧凑,通过备份原文件到本机外的其他主机上,一旦本机发生宕机,就能将备份文件复制到redis安装目录下,通过启用服务就能完成数据的恢复。
RDB的缺点:
1、RDB这种持久化方式不太适应对数据完整性要求严格的情况,因为,尽管我们可以用过修改快照实现持久化的频率,但是要持久化的数据是一段时间内的整个数据集的状态,如果在还没有触发快照时,本机就宕机了,那么对数据库所做的写操作就随之而消失了并没有持久化本地dump.rdb文件中。
2、每次进行RDB时,父进程都会fork一个子进程,由子进程来进行实际的持久化操作,如果数据集庞大,那么fork出子进程的这个过程将是非常耗时的,就会出现服务器暂停客户端请求,将内存中的数据复制一份给子进程,让子进程进行持久化操作。
AOF:以日志的形式记录Redis每一个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件不可以改写文件,redis启动之后会读取appendonly.aof文件来实现重新恢复数据,完成恢复数据的工作。默认不开启,需要将redis.conf中的appendonly no改为yes启动Redis。
AOF的优点:
1、AOF有着多种持久化策略:
appendfsync always:每修改同步,每一次发生数据变更都会持久化到磁盘上,性能较差,但数据完整性较好。
appendfsync everysec: 每秒同步,每秒内记录操作,异步操作,如果一秒内宕机,有数据丢失。
appendfsync no:不同步。
2、AOF文件是一个只进行追加操作的日志文件,对文件写入不需要进行seek,即使在追加的过程中,写入了不完整的命令(例如:磁盘已满),可以使用redis-check-aof工具可以修复这种问题
3、Redis可以在AOF文件变得过大时,会自动地在后台对AOF进行重写:重写后的新的AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建AOF文件的过程中,会继续将命令追加到现有的AOF文件中,即使在重写的过程中发生宕机,现有的AOF文件也不会丢失。一旦新AOF文件创建完毕,Redis就会从旧的AOF文件切换到新的AOF文件,并对新的AOF文件进行追加操作。
4、AOF文件有序地保存了对数据库执行的所有写入操作。这些写入操作一Redis协议的格式保存,易于对文件进行分析;例如,如果不小心执行了FLUSHALL命令,但只要AOF文件未被重写,通过停止服务器,移除AOF文件末尾的FLUSHALL命令,重启服务器就能达到FLUSHALL执行之前的状态。
AOF的缺点:
1、对于相同的数据集来说,AOF文件要比RDB文件大
2、根据所使用的持久化策略来说,AOF的速度要慢与RDB。一般情况下,每秒同步策略效果较好。不使用同步策略的情况下,AOF与RDB速度一样快。
19、简述下laravel的控制反转。
答: