2022PHP面试题总结笔记

1、什么是 HTTP 中间件?laravel中间件做什么?
HTTP 中间件是一种用于过滤 HTTP 请求的技术。
Laravel 包含一个中间件,用于检查应用程序用户是否已通过身份验证。

2、身份认证系统OAuth2的四种模式?
授权码模式、隐式授权模式/简化模式、密码模式、客户端凭证模式。

3、什么是事务?
MySQL事务使您能够执行一组MySQL操作,以确保数据库从不包含部分操作的结果。 在一组操作中,如果其中一个失败,则会恢复回滚数据库。 如果没有发生错误,则将整个语句集合提交到数据库。
事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

4、mysql左连接右连接(查询两张表不同的数据)区别?
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 ;
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录;
inner join(等值连接) 只返回两个表中联结字段相等的行;

5、Redis支持五种数据类型?
string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

6、什么是乐观锁和悲观锁?
锁分为乐观锁和悲观锁,它的目的是用来解决并发控制的问题。
乐观锁,简单地说,就是从应用系统层面上做并发控制,去加锁。
实现乐观锁常见的方式:版本号version实现方式,在数据表中增
加版本号字段,每次对一条数据做更新之前,先查出该条数据的版本号,每次更新数据都会对版本号进行更新。在更新时,把之前查出的版本号跟库中数据的版本号进行比对,如果相同,则说明该条数据没有被修改过,执行更新。如果比对的结果是不一致的,则说明该条数据已经被其他人修改过了,则不更新,客户端进行相应的操作提醒。
使用版本号实现乐观锁使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。并判断当前版本号是不是该数据的最新的版本号。

悲观锁,简单地说,就是从数据库层面上做并发控制,去加锁。
悲观锁的实现方式有两种:共享锁(读锁)和排它锁(写锁)
共享锁(IS锁),实现方式是在sql后加LOCK IN SHARE MODE,比如SELECT … LOCK IN SHARE MODE,即在符合条件的rows上都加了共享锁,这样的话,其他session可以读取这些记录,也可以继续添加IS锁,但是无法修改这些记录直到你这个加锁的session执行完成(否则直接锁等待超时)。
排它锁(IX锁),实现方式是在sql后加FOR UPDATE,比如SELECT … FOR UPDATE ,即在符合条件的rows上都加了排它锁,其他session也就无法在这些记录上添加任何的S锁或X锁。如果不存在一致性非锁定读的话,那么其他session是无法读取和修改这些记录的,但是innodb有非锁定读(快照读并不需要加锁),for update之后并不会阻塞其他session的快照读取操作,除了select …lock in share mode和select … for update这种显示加锁的查询操作。

7、rabbitMq六种工作模式?
这里简单介绍下六种工作模式的主要特点:
简单模式:一个生产者,一个消费者
work模式:一个生产者,多个消费者,每个消费者获取到的消息唯一。
订阅模式:一个生产者发送的消息会被多个消费者获取。
路由模式:发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key
topic模式:将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。

8、php 单引号和双引号的区别?
1、变量。双引号解释变量,单引号不解释变量;双引号里插入单引号,其中单引号里如果有变量的话,变量解释;
2、字符。双引号解释转义字符,单引号不解释转义字符,但是解释’\和\;
3、效率。能使单引号字符尽量使用单引号,单引号的效率比双引号要高(因为双引号要先遍历一遍,判断里面有没有变量,然后再进行操内作,而单引容号则不需要判断)。

10、php赋值与引用区别?
PHP 的引用允许用两个变量来指向同一个内容。相当于他们可以是 不同的名字,却可以指向 同一个 物理空间。
赋值,它实际上意味着把右边表达式的值赋给左边的运算数相当于,他们是 不同的名字,不同的物理空间。

11、http状态码的503和504的区别?
503服务不可用是的一种状态;
504网关超时。

12、php如何防御XSS 攻击?
在接受数据处理的时候用上过滤函数htmlspecialchars,这个函数会把代码中的特殊字符转义成HTML实体,输出的时候就不会影响页面了;
strip_tags函数可以出去字符串中HTML和PHP标签,仅保留参数中指定的标签

13、如何防止接口恶意刷新?
要求在页面间传递一个验证字符串,
在生成页面的时候 随机产生一个字符串,
做为一个必须参数在所有连接中传递。同时将这个字符串保存在session中。
点连接或者表单进入页面后,判断session中的验证码是不是与用户提交的相同,如果相同,则处理,不相同则认为是重复刷新。
在处理完成后将重新生成一个验证码,用于新页面的生成

14、如何写出安全的API接口?
参数加密+超时处理+私钥验证+Https

15、php常用加密算法?
不可逆的加密函数为:md5()、crypt(),
可逆转的加密为:base64_encode()、urlencode() 相对应的解密函数:base64_decode() 、urldecode() 。

16、从URL输入到页面展现到底发生什么?
总体来说分为以下几个过程:
DNS 解析:将域名解析成 IP 地址
TCP 连接:TCP 三次握手
发送 HTTP 请求
服务器处理请求并返回 HTTP 报文
浏览器解析渲染页面
断开连接:TCP 四次挥手
17、构造函数__construct()和析构函数__destruct()
1. 构造函数__construct()
在对应对象实例化时会自动被调用,具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
2. 析构函数__destruct()
析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。
18、GET、POST 区别
GET是从服务器上获取数据,POST是向服务器传送数据。
GET安全性非常低(参数暴露在地址栏),但执行效率快,POST安全性较高。
get传送的数据量较小,不能大于2KB,post传送的数据量较大,一般被默认为不受限制。
GET是通过URL方式请求,POST是通过请求header请求。

THE END