PHP程序员2021年最新面试题集-持续更新中...

管理员 发布于 3年前   397

PHP中级开发

1. $a=[0,1,2,3]; $b=[1,2,3,4,5]; $a+=$b; $a值是多少?

知识点:【数组相加】

答案:[0,1,2,3,5];


2. HTTP 状态中302、403、 500代码含义?

知识点:【http协议理解】

答案:302:临时转移成功,请求的内容已转移到新位置(临时重定向) 403:禁止访问 500:服务器内部错误


3. echo、print_r、print、var_dump区别

知识点:【PHP函数基础】


4. 语句include和require的区别是什么?重复包含同一个文件分别会有什么提示?

知识点:【include 与require问题】

答案:

1、PHP程序执行到require()时,只会读取一次档案,故常放在程序开头,档案引入后PHP会将网页档重新编译,让引入档成为原先网页的一部分。 

2、PHP程序执行到include()时,每次皆会读取档案,故常用于流程控制的区段,如条件判断或循环中。


5. PHP7 与 PHP5 的区别

知识点:【PHP】

答案:

函数返回类型声明, null合并运算符, 常量数组, 匿名类, use语句可以导入多个统一namespace下的类, php7移除mysql扩展, 变量储存字节减少, 改善数组结构, 改进函数的调用机制。 优化参数传递环节


6. php中字符串处理函数列举5个,简述用途

知识点:【PHP函数】


7. 列举下使用过的框架,及其优缺点【PHP框架】

8. 有两个数组[1,2,5,11,32,15,77]和[99,32,15,5,1,77]两个数组,写段程序找出它们共同都拥有的数,

知识点:【PHP函数】

答案:array_intersect


9. 写条语句从user 表随机调取 1 条数据?

答案:select * from table order by rand() limit 1;


10. 设计一个商品分类表,写出sql语句查询某个分类的所有下级?

答案: id,name,fid;  sql:fid=xx


11. 写出一个类,包含面向对象三大特征和至少三个魔术方法?

知识点:【面向对象特性】【魔术方法】

class f {
public $a;
function aaa(){
echo '我是f类aaa';
}
function __construct($a){ $this->a=$a; } 
function __set($a){ $this->a=$a; }
function __get($a){ $this->a=$a; }
}
class son extends f{ 
//覆盖、重写 
function aaa(){ 
echo '我是son类aaa'; 
f::cry();//这里不会报错,能正确执行父类的cry(); 


PHP高级开发

1. 设计一个商品分类表,写出sql语句查询某个分类的所有上级?【mysql】

答案:请看 上面第10题


2. php中数组处理函数列举5个,简述用途【php函数】

答案:array_values| array_keys |in_array |array_key_exists |array_flip |array_reverse |array_unique |array_map


3. SQL语言数据定义(DDL)语句中有哪些操作关键字?【mysql】

答案:create | drop | alter


4. php7有哪些特点?描述下Trait的继承优先级?【Trait特性】

答案:在trait继承中,优先顺序依次是:来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。


5. php缓存可以使用哪些软件,各自特点是什么?【缓存数据库】

答案:使用redis,memcached等nosql数据库;

redis:适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。例如:股票价格、数据分析、实时数据搜集、实时通讯。


6. 如何排查和优化查询比较慢的sql语句?【mysql 慢sql】

答案:开启慢查询,捕获超时sql进行定位优化 比如:explain


7. mysql数据库索引有哪些?什么情况下不适合建立索引?【mysql索引】

答案:普通索引 | 唯一索引 |主键索引 |组合索引| 全文索引

适合建索引

  1. 频繁作为where条件语句查询的字段

  2. 关联字段需要建立索引,例如外键字段,student表中的classid,   classes表中的schoolid 等

  3. 排序字段可以建立索引

  4. 分组字段可以建立索引,因为分组的前提是排序

  5. 统计字段可以建立索引,例如count(),max()

不适合建索引

  1.频繁更新的字段不适合建立索引

  2.where条件中用不到的字段不适合建立索引

  3.表数据可以确定比较少的不需要建索引

  4.数据重复且发布比较均匀的的字段不适合建索引(唯一性太差的字段不适合建立索引),例如性别,真假值

  5. 参与列计算的列不适合建索引


8. 是否用过mysql分库分表?使用了哪种策略, 如何解决增表,减表问题.【mysql 分库分表】

答案:水平切分(横向切分):是对同一个表中的数据进行切分,存储到不同的数据库(主机)之上。规则是根据表中数据的逻辑关系,按照某种条件拆分。

用的mysql-MERGE实现分表,读取分表规则用哈希

//code作为主键,对code做hash 
//return 表名
function get_hash_table($table,$code,$s=9){
      $hash = sprintf("%u", crc32($code));
      $hash1 = intval(fmod($hash, $s));
      return $table."_".$hash1;
}

9. 现需要实现高可用高性能架构,列出你需要用到的软件及其作用?

答案:主备架构,应用层跟静态资源分离

nginx(负载均衡) | redis(缓存,主从) | mysql(主从,读写分离) | cdn


10. 事务的其特性有哪些?mysql是否支持嵌套事务?【mysql事务】

答案:

在 MySQL 中只有 InnDB 引擎支持事务,它的四个特性如下:

原子性(Atomic):要么全部执行,要么全部不执行;

一致性(Consistency):事务的执行使得数据库从一种正确状态转化为另一种正确状态;

隔离性(Isolation):在事务正确提交之前,不允许把该事务对数据的任何改变提供给其他事务;

持久性(Durability):事务提交后,其结果永久保存在数据库中。


Mysql是不支持嵌套事务的,开启了一个事务的情况下,再开启一个事务,会隐式的提交上一个事务。


11. mysql数据库中innodb和myisam引擎的区别【mysql 引擎】

答案:

InnoDB: 

InnoDB 给 MySQL 提供了具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。

InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs)。这些特性均提高了多用户并发操作的性能表现。

在InnoDB表中不需要扩大锁定(lock escalation),因为 InnoDB 的列锁定(row level locks)适宜非常小的空间。

InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。

InnoDB 的设计目标是处理大容量数据库系统,它的 CPU 利用率是其它基于磁盘的关系数据库引擎所不能比的。在技术上,InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 InnoDB 把数据和索引存放在表空间里,可能包含多个文件,这与其它的不一样,举例来说,在 MyISAM 中,表被存放在单独的文件中。

InnoDB 表的大小只受限于操作系统的文件大小,一般为 2 GB。

InnoDB 所有的表都保存在同一个数据文件 ibdata1 中(也可能是多个文件,或者是独立的表空间文件),相对来说比较不好备份,可以拷贝文件或用navicat for mysql。 


对于支持事务的InnoDB类型的表,影响速度的主要原因是AUTO COMMIT默认设置是打开的,而且程序没有显式调用BEGIN 开始事务,导致每插入一条都自动Commit,严重影响了速度。

可以在执行sql前调用begin,多条sql形成一个事物(即使autocommit打开也可以),将大大提高性能。 


MyISAM: 

每张MyISAM 表被存放在三个文件 :frm 文件存放表格定义。 数据文件是MYD (MYData) 。 索引文件是MYI (MYIndex) 引伸。 

因为MyISAM相对简单所以在效率上要优于InnoDB,小型应用使用MyISAM是不错的选择。

MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。 

MyIASM是IASM表的新版本,有如下扩展: 

1. 二进制层次的可移植性。 

2. NULL列索引。 

3. 对变长行比ISAM表有更少的碎片。 

4. 支持大文件。 

5. 更好的索引压缩。 

6. 更好的键吗统计分布。 

7. 更好和更快的auto_increment处理。


12. 缓存穿透、缓存雪崩、缓存击穿的区别以及对应的解决方案?【缓存数据库】

答案:

缓存穿透:

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

1.接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;

2.从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击


缓存击穿:

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案:

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

2.加互斥锁

缓存雪崩:

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,        

缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

2.如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。

3.设置热点数据永远不过期。


13. 用php实现冒泡排序算法,使用php实现快速排序算法?

答案:

冒泡排序:
    /**
     * @param $arr
     * 冒泡排序算法的原理如下:
     * 1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
     * 2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
     * 3.针对所有的元素重复以上的步骤,除了最后一个。
     * 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
     */
    private function bubbleSort($arr)
    {
        //获取 长度
        $len = count($arr);
        //循环比较(相邻的两个元素,比较,交换)
        for ($k = 0; $k <= $len; $k++) {
            for ($j = $len - 1; $j > $k; $j--) {
                //比较
                if ($arr[$j] < $arr[$j - 1]) {
                    //交换
                    $temp = $arr[$j];
                    $arr[$j] = $arr[$j - 1];
                    $arr[$j - 1] = $temp;
                }
            }
        }
        return $arr;
    }
快速排序
  /** @param $arr
     * 快速排序算法原理如下:
     *  1.通过设置一个初始中间值,来将需要排序的数组分成3部分:小于中间值的左边,中间值,大于中间值的右边
     *  2.继续递归用相同的方式来排序左边和右边
     *  3.最后合并数组
     */
    function quick_sort($arr)
    {
      //先判断是否需要继续进行
      $length = count($arr);
      if($length <= 1){ return $arr; }
      $base_num = $arr[0];//选择一个标尺 选择第一个元素
      //初始化两个数组
      $left_array = array();//小于标尺的
      $right_array = array();//大于标尺的
      for($i=1; $i<$length; $i++){      
      //遍历 除了标尺外的所有元素,按照大小关系放入两个数组内
        if($base_num > $arr[$i]){
          //放入左边数组
          $left_array[] = $arr[$i];
        }else{
          //放入右边
          $right_array[] = $arr[$i];
        }
      }
      //再分别对 左边 和 右边的数组进行相同的排序处理方式
      //递归调用这个函数,并记录结果
      $left_array = quick_sort($left_array);
      $right_array = quick_sort($right_array);
      //合并左边 标尺 右边
      return array_merge($left_array, array($base_num), $right_array);
    }
    $arr = array(3,1,2);
    var_dump(quick_sort($arr));

14. 设置php错误级别,除通知错误都可以显示

答案:

error_reporting(E_ALL ^ E_NOTICE);


15. 安全对一套程序来说至关重要,请说说在开发中应该注意哪些安全机制?

答案:

1.使用验证码防止注册机灌水。

2.使用预处理,绑定参数,参数过滤转义 防止sql注入

3.使用token防止远程提交,使用token验证登录状态。


16. 作用域操作符::如何使用?都在哪些场合下使用?

答案:

1.调用类常量

2.调用静态方法(使用static修饰的类方法)


17. $this和self、parent这三个关键词分别代表什么?在哪些场合下使用?

答案:

$this 当前对象

self 当前类

parent 当前类的父类


$this 在当前类中使用,使用->调用属性和方法。

self 也在当前类中使用,不过需要使用::调用。

parent 在类中使用。


18. PHP的 数组底层实现原理

答案:PHP的数组是用链地址法的哈希结构去实现的,链表是双向链表,这样既可以动态分配数组空间,也可以通过key值去计算hash值去访问对应的元素,是一种非常高效的数据结构。


19. PHP的变量底层实现原理

https://zongscan.com/demo333/411.html


20. PHP的GC机制原理

答案:引用计数

每个php变量存在一个叫"zval"的变量容器中。包括四个字段:-name:字段值,-type:字段类型 ,-Is_ref:标识这个变量是否是属于引用集合变量,-refcount:表示指向这个zval变量容器的变量(也称符号即symbol)个数 。容器在”refcount“变成0时就被销毁。

当被变量引用时refcount+1,当变量撤掉时refcount-1,当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。


21. Laravel的依赖注入实现原理

答案:主要运用了 PHP 反射 api 的 ReflectionMethod 类,在 PHP 运行状态中,扩展分析 PHP 程序


22. LUMEN的中间件原理

23. MYSQL B+TREE底层原理

答案:

B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。在讲B+树之前必须先了解二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree),B+树即由这些树逐步优化而来


24. 一条SQL语句在MySQL中如何执行的?

答案:

查询sql:

1.先检查该语句是否有权限,如果没有权限,直接返回错误信息,如果有权限,在 MySQL8.0 版本以前,会先查询缓存,以这条 sql 语句为 key 在内存中查询是否有结果,如果有直接缓存,如果没有,执行下一步。

2.通过分析器进行词法分析,提取 sql 语句的关键元素,比如提取上面这个语句是查询 select,提取需要查询的表名为 tb_student,需要查询所有的列,查询条件是这个表的 id='1'。然后判断这个 sql 语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。

3.优化器根据自己的优化算法进行选择执行效率最好的一个方案(优化器认为,有时候不一定最好)。那么确认了执行计划后就准备开始执行了。

4.进行权限校验,如果没有权限就会返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果。

更新sql:

先查询如果有缓存,也是会用到缓存。然后拿到查询的语句,把要更改的字段更新,然后调用引擎 API 接口,写入这一行数据,InnoDB 引擎把数据保存在内存中,同时记录 redo log,此时 redo log 进入 prepare 状态,然后告诉执行器,执行完成了,随时可以提交。•执行器收到通知后记录 binlog,然后调用引擎接口,提交 redo log 为提交状态。更新完成。


25. 什么是静态延迟绑定

答案:

在父类中获取子类的最终状态。在父类中,如果出现self关键字,被子类继承后,这个self值的还是父类而不是子类。

如果在父类中出现了self关键字,并且子类继承了含有self的这段代码,那么需要考虑静态延迟绑定。在父类中使用static代替self.


26. redis 持久化策略

答案:2种

1.rdb:快照形式是直接把内存中的数据保存到一个dump文件中,定时保存,保存策略

备注:该方式不能完全保证数据持久化,因为是定时保存,所以当redis服务down掉,就会丢失一部分数据,而且数据量大,写操作多的情况下,会引起大量的磁盘IO操作,会影响性能。

2.aof:把所有的对redis的服务器进行修改的命令都存到一个文件里,命令的集合

备注:该方式Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。


27. Redis淘汰策略

答案:6种

1.volatile-lru:从已设置过期时间的数据集(server. db[i]. expires)中挑选最近最少使用的数据淘汰。

2.volatile-ttl:从已设置过期时间的数据集(server. db[i]. expires)中挑选将要过期的数据淘汰。

3.volatile-random:从已设置过期时间的数据集(server. db[i]. expires)中任意选择数据淘汰。

4.allkeys-lru:从数据集(server. db[i]. dict)中挑选最近最少使用的数据淘汰。

5.allkeys-random:从数据集(server. db[i]. dict)中任意选择数据淘汰。

6.no-enviction(驱逐):禁止驱逐数据。


28. Redis高可用

答案:

Redis高可用常见的有两种方式:

1.主从复制(Replication-Sentinel模式)

2.Redis集群(Redis-Cluster模式)


29. http协议理解 

答案:

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写。HTTP 协议和 TCP/IP 协议族内的其他众多的协议相同, 用于客户端和服务器之间的通信。请求访问文本或图像等资源的一端称为客户端, 而提供资源响应的一端称为服务器端。 


30. TCP协议理解【三次握手,四次挥手】

答案:

三次握手:

1.Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

2.Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

3.Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

四次挥手:

1.Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

2.Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

3.Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

4.Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。


31. 判断一个数是否为2的整数次幂 

答案:

0和1按位与运算的结果是0,所以凡是2的整数次幂和它本身减1的结果进行与运算,结果都必定是0。

反之,如果一个整数不是2的整数次幂,结果一定不是0!

对于一个整数n,只需要计算n&(n-1)的结果是不是0。这个方法的时间复杂度只有O(1)

公式判断:(num & num - 1) == 0?是:否;


32. linux 中存在一日志文件非常大,打开速度很慢,如何查找其中部分指定内容

答案:grep -n -e '关键词1' -e '关键词2' xxx.log


33. 负载均衡方式

答案:

1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

2、weight

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

3、ip_hash

如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器

4、fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

5、url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。


34. 两数组直接相加,array_merge 与直接相加的区别

答案:

+:左边数组根据key覆盖右边数组,右边数组多出来的元素添加到左边数组尾部,array_merge反之


35. session与cookie区别

答案:

1.cookie数据是存储到客户端,而session是存储到服务端

2.在浏览器中,cookie存储的数据大小有限 ;而session没有大小限制,跟服务端的内存有关

3.cookie安全性差,可以通过拦截或本地文件可以对cookie进行攻击;而session运行在服务端,安全性高

4.如果浏览器禁用了cookie,那么cookie就不能使用,而session不能禁用


36. 遍历两个一个数组最后的结果

$a = [1,2,3];
foreach($a as &$v){
//啥也不干
}
foreach($a as $v){
//啥也不干
}
$a = ?[1,2,2];


37. PHP计算最大公约数

function baseDefine($m, $n) {
    if($m ==0 && $n == 0) {
        return false;
    }
    $min = min($m, $n);
    while($min >= 1) {
        if($m % $min == 0){
        if($n % $min ==0) {
            return $min;
            }
        }
        $min -= 1;
    }
    return $min;
}

38...


最新收集

整理时间:2021-03-01

1. PHP的性能优化

2. mysql 性能调优

3. 压测工具使用与具体使用参数含义(ab压测)

4. laravel队列的延迟分发(delay)

5. TCP长连接与短连接的区别,各自的优点与缺点,以及其使用场景

6. laravel autoload实现原理

7. Innodb下创建表,表中不创建主键索引,创建一般索引后,查询逻辑是怎样。


整理时间:2021-03-03

1. 运算符题 //+= 与-=优先级一致,靠右原则

$a = 3;

$a += $a -= $a*$a;

$a = ?;//$a += $a-($a*$a)  $a = -6+(-6) = -12

2.TCP/IP协议支持哪些协议? 

应用层  表示层  会话层  传输层  网络层  数据链路层  物理层


3.如题

function f(x){

    return x>0 ?x*f(x-1) :2;

}

求f(f(1));

A:无限递归,B:2 ,C:4, D:8

答:C


4. TCP/IP协议 四层模型是哪四个?TCP四次挥手过程具体描述?

5. 假定一条微博有7大特征,用户特征,爱好特征,地点特征,等··,如果现在需要用1byte存储微博特征,请写出算法。

6. 现有两组排好序的数组,如何以高效率判断两组中重复数字,请写出代码。

7. 假定一个微博服务现连接数100万/S,mysql最大QPS支持10万/S,架构是memcache+mysql 

1:需要memcache至少保证多少的数据命中率

2:假定一个k-v大小为200B,问memcache需要多少带宽?

3:memcache大概需要使用多少内存

8. localhost与127.0.01的区别

9. 事务的隔离级别与锁


10. workman 与 swoole 的缺点

11. nginx 与 PHP-FPM 通信方式

12. 500W的一个mysql 的表,需要新增字段,为防止表锁,可行方法?


持续更新中....


请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

该博客于2020-12-7日,后端基于go语言的beego框架开发
前端页面使用Bootstrap可视化布局系统自动生成

是我仿的原来我的TP5框架写的博客,比较粗糙,底下是入口
侯体宗的博客

      订阅博客周刊

文章标签

友情链接

HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群
侯体宗的博客