signed

QiShunwang

“诚信为本、客户至上”

2021php面试题、笔试题总结

2021/4/26 13:59:42   来源:

记录了我这段时间在深圳求职以来被问到过的所有问题,以后有机会的话还会继续更新 ~

目录

数据库篇

Redis篇

PHP编程语言篇

网络篇

其它


数据库篇


一、谈谈数据库优化?

从sql优化方面来讲:

1. 不要返回任何用不到的字段

2. 尽量避免全表扫描,在where和order by涉及的字段上加索引

3. 尽量避免在 where 子句中对字段进行 null 值判断,会使索引失效

4. 尽量避免在 where 子句中使用 != 或 <> 操作符,会使索引失效

5. 尽量避免在 where 子句中使用 or 来连接条件,会使索引失效

6. 尽量避免在where子句中对字段进行函数操作,会使索引失效

从表优化方面来讲:

1. 可以水平分表,将一张表拆成多张结构一样的表,用表名区分

2. 可以垂直分表,将表中较大的字段拆分到另一张表中,该表与原表是一对一的关系

从库优化方面来讲:

可以将数据库分为主从库,主库用来写数据,多个从库用来读数据,主库与从库之间通过某种机制实现数据同步

二、Mysql有哪几种索引?

从逻辑角度来讲:

1. 普通索引:最基本的索引,没有任何限制

2. 主键索引:一种特殊的唯一索引,不允许有空值

3. 唯一索引:索引字段的值必须唯一,可以有空值

4. 组合索引:在多个字段上创建的索引,遵循最左前缀集合的原则

5. 全文索引:可以在varchar或text的字段上创建

从物理角度来讲:

1. 聚集索引

2. 非聚集索引

三、什么是事务?

满足ACID特性的一组操作,ACID包括原子性、隔离性、一致性、持久性

四、Inno和MyISAM这两种数据引擎有什么区别?

1. InnoDB支持事务、外键、行级锁等高级数据库功能,适合频繁修改以及安全性较高的应用

2. MyISAM不支持事务等高级数据库功能,适合以查询、插入为主的应用,更加注重查询的性能

五、什么是sql注入?怎么解决?

sql注入指web应用程序对用户输入数据的合法性没有判断或过滤不严格,进而导致攻击者可以在事先定义的sql语句上添加额外的sql语句,以此来实现欺骗数据库从而执行非授权的任意查询

解决方案:

1. 对用户的输入进行校验,可以通过正则表达或限制长度

2. 使用参数化的sql而不是使用动态拼装的sql

3. 避免直接响应数据库异常信息,最好自定义错误信息进行包装

4. 限制数据库权限

六、如何分析sql?explain有哪些常用字段?

使用explain关键字可以模拟优化器执行SQL语句,分析查询语句或是结构的性能瓶颈

常用字段:

1. id:表的读取顺序,id相同,读取顺序从上到下,id不同,值越大则优先级越高

2. select_type:查询类型simple表示简单查询,不包含子查询或联合查询;

若查询中包含复杂的子部分,则最外层查询为primary;

在select或where列表中包含的子查询,会被标记为subquery;from列表中包含的子查询,会被标记为derived;第二个select在union后,会被标记为union

3. table:显示sql操作属于那张表

4. type:表示sql语句的好坏,从好到坏依次为system > const > eq_ref > ref > range > index > all

5.  possible_key:可能使用的索引

6. key:实际使用的索引

七、谈谈数据库锁?

在并发的情况下,事务的隔离性很难保证,解决方案是锁

共享锁/读锁:成功申请读锁的前提是没有其它线程对查询结果使用过写锁,读锁申请成功后,其它线程可以对它进行读操作,但不允许对其进行写操作,即便是当前线程也不行

独占锁/写锁:成功申请写锁的前提是没有其它线程对查询结果使用过读锁或写锁,写锁申请成功后,其它线程不可对其进行读写操作

八、什么是死锁?如何解决?

两个及两个以上的线程因争夺资源而造成相互等待的现象

解决方案:尽可能使用低的隔离级别,将事务所设计的数据全部加锁,否则不予执行

九、笔试:如何查询每个班前三的成绩?

select stu.class,stu.score

from student stu

where (select count(*) from student where class=a.class and a.score<score) < 3

order by stu.class,stu.score desc; 

Redis篇


一、redis有哪几种数据类型?

1. string(set、get)

2. hash(hget、hset、hgetall)

3. list(lpush、lpop、rpush、rpop,有序可重复)

4. set(sadd、srem、spop,无序不可重复)

5. zset(zadd、zrem,有序不可重复)

二、redis和memcache有什么区别?

1. memcache可以缓存图片、视频等,而redis不行

2. redis不仅支持简单的key-value数据类型,还提供了hash、list、set等数据结构

3. redis还可以将数据持久化到磁盘上,memcache只能将数据存储于内存中

4. 当缓存挂掉后,memcache数据无法恢复,redis可以通过aof策略根据操作日志恢复数据

三、什么是雪崩?如何解决?

在高并发下,大量缓存key在同一时间失效,大量的请求直接落在数据库上,导致数据库压力过大宕机

解决方案:

1. 设置redis集群+哨兵模式的高可用,一旦redis出现宕机,可立即由其它机器顶替

2. 随机设置key的失效时间,避免大量key同时失效

四、什么是穿透?如何解决?

redis缓存和数据库中没有相关数据,请求无法进行拦截,直接被穿透到数据库,导致数据库压力过大宕机

解决方案:

1. 将不存在的数据也缓存到redis中,设置一个较短的过期时间

2. 采用布隆过滤器,将所有可能的数据都hash到一个足够大的bitmap中,一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层查询系统的压力

3. 拉黑该ip地址

四、什么是击穿?如何解决?

某一个热点key在不停的扛着高并发,当这个key失效的一瞬间,持续的高并发就会直接访问数据库,导致数据库压力过大宕机

解决方案:

1. 热点数据设置永不过期

2. 实现互斥锁,在第一次查询时使用互斥锁锁住它,等第一个线程查询到了数据将数据存入缓存,之后的线程就可以直接走缓存

PHP编程语言篇


一、什么是面向对象?有哪些特征?

面向对象是一种对现实世界理解和抽象的方法,将需求要素转化为对象进行问题分析的思想

特征:封装、继承、多态

二、什么是类?

类是在对象之上的抽象,对象是类的具体化

三、opcache有什么作用?

opcache可以将php脚本预编译的字节码存放在内存中来避免每次加载和解析php脚本的开销,解析器可以直接从内中读取已缓存的字节码,从而提高php的执行效率

四、有哪些常用函数?

1.数组:

count($array,$model); 统计数组元素个数

in_array($element,$array); 判断数组中是否存在某元素

array_merge($arr1,$arr2); 合并两个数组

implode($str,$array); 将数组中的元素用字符拼接成一个字符串

json_encode($array); 将数组转化为json字符串

2.字符串:

strlen(); 字符长度

substr($str,$start,$length); 截取字符串

str_replace($find,$replace,$str); 替换字符串

explode($s,$str); 分割字符串为数组

3.时间:

time(); 返回1970到现在的秒数

date($format,$timestap); 将时间戳转化为特定格式的字符串

五、for和foreach有什么区别?

1. 在固定长度或长度不需要计算的时候for的效率比foreach高

2. 在不确定长度或计算长度损耗性能的时候用foreach比较方便

六、笔试:实现冒泡排序算法?

//定义一个数组
$a = array(19,56,7,15,36,89,45,24,21,65,31,47,65);
//执行冒泡排序
for ($i = 0; $i < count($a) ; $i++) {
    for ($j = $i+1; $j < count($a); $j++) {
        if ($a[$i] > $a[$j]) {
            $tem = $a[$i]; 
            $a[$i] = $a[$j]; 
            $a[$j] = $tem; 
        }
    }        
}

网络篇


一、tcp有哪五层协议?

应用层、传输层、网络层、数据链路层、物理层

二、谈谈tcp三次握手?

1. 客户端向服务端发送一个连接请求报文段,其中SYN设置为1,并随即选择一个起始序号seq=x

2. 服务端收到请求报文段后,向客户端发送一个确认报文段,其中SYN和ACK设置为1,确认号字段为x+1,并生成一个起始序号seq=y

3. 当客户端收到确认报文段后,还要再向服务端一个确认报文段,其中ACK设置为1,确认号字段为y+1,序号字段为x+1

注:SYN为同步序号,ACK为确认序号标志

三、cookie和session有什么区别?

1. cookie存储在浏览器上,session存储在服务器上

2. 别人可以分析本地的cookie从而进行cookie欺骗,考虑安全性应用session

3. 单个cookie的存储限制是4k,而浏览器对session没有限制

四、http和https有什么区别?

1. http是不安全的,https是安全的

2. http的标准端口是80,https的标准端口是443

3. http无需认证证书,https需要认证证书

五、有哪些常见的http状态码?

200 服务器成功处理了请求

301 永久性重定向

302 临时性重定向

403 请求被服务器拒绝

404 服务器无法找到请求的资源

500 服务器内部错误

六、什么是csrf攻击?如何预防?

跨站请求伪造,利用浏览器的cookie和服务器的session盗取用户身份

解决方案:

1. 向表单添加字段标记,比如uuid令牌

2. 添加验证码

3.检查请求头中的referer字段

七、什么是xss攻击?如何预防?

跨站脚本攻击,攻击者会在web页面插入一些恶意的javascript代码,当用户浏览该页面时,嵌入到页面中的javascipt就会执行,以达到恶意攻击用户的目的

解决方案:

1. 设置httponly,使js脚本无法读取cookie信息

2. 同时在js和服务端上检查用户输入的合法性

3. 在变量输出到html页面时,使用编码或转义

八、接口签名应如何设计?

1. 接口调用方和接口提供方约定好统一的参数加密方法,如md5加密

2. 接口调用方将加密后的_sign放在参数中

3. 接口调用方将时间戳放在参数中保证请求的唯一性和有效性

其它


一、什么是单点登录?如何实现?

单点登录指在多个应用系统中,用户只需要登陆一次,就可以访问多个相互信任的应用系统

解决方案:

1. 同一个域下,把cookie的路径设置在顶级域名下,这样所有的子域都能够获取到cookie中的sessionid,实现共享session

2. 不同域下,系统A 验证完用户信息设置好session后,不立即响应浏览器,而是生成token保存至数据库中,并携带该token重定向至系统B设置好session,最后再回到需要返回的地址

二、谈谈微信网页登录流程?

1. 用户扫码请求服务器地址后,服务器携带appid并设置好回调地址请求微信接口

2. 用户同意授权后微信服务器将携带code重定向至该回调地址

3. 再拿到code之后再次携带appid和app密钥访问微信接口可获得access_token和用户对应的openid,并将该openid存入数据库,当开发者拥有多个应用时,微信还提供了unionid来区分用户的唯一性

三、谈谈支付宝扫码支付流程?

1. 用户下单后,服务器组合好支付宝所需的参数后调用统一下单接口,然后将支付宝将返回的html输出在页面上,最终将二维码展示在用户面前

2. 用户打开支付宝进行扫码支付,支付宝检测到支付成功后跳转到预先设置好的回调页面

3. 同时支付宝向服务器的异步通知地址发送通知,服务器根据支付结果返回sucess或fail给支付宝表示已收到通知

四、谈谈elasticsearch?

一种搜索引擎,本质是一个java服务器,使用前需要提前将数据录入elasticsearch才能够使用搜索功能

常用查询字段:match、match_phrase、multi_match、bool

常用分词器:standard analyzer(按词切分,小写处理)、simple analyzer(按照非字母切分,小写处理)、whitespace analyzer(按空格切分,不转小写)