• 常见问题汇总


    1、php版本的各个不同 

    答: 

    1. php 版本1.0 1995-06-08
    2. php 版本5.6 2014-08-28
    3. php 版本7.0 2015-12-03
    4. php 版本7.1 2016-12-01
    5. php 版本7.2 2017-11-30
    6. php 版本7.3 2018-12-06
    7. php 版本8.1 2021-11-25
    8. php5与php7之间的区别:
    9. 1、性能提升:PHP7比PHP5.0性能提升了两倍。
    10. 2、以前的许多致命错误,现在改成抛出异常。
    11. 3、PHP 7.0比PHP5.0移除了一些老的不在支持的SAPI(服务器端应用编程端口)和扩展。
    12. 4、PHP 7.0比PHP5.0新增了空接合操作符,增加了空结合操作符(??),相当于三元运算符
    13. 5、PHP 7.0比PHP5.0新增加了结合比较运算符。
    14. 6、PHP 7.0比PHP5.0新增加了函数的返回类型声明。
    15. 7、PHP 7.0比PHP5.0新增加了标量类型声明。
    16. 8、PHP 7.0比PHP5.0新增加匿名类。
    17. 9、错误处理和64位支持
    18. 如果您了解错误和异常之间的区别,那么您就会知道在PHP 5中处理致命错误非常不容易。PHP7简化了流程,因为它已用可以轻松处理的异常替换了几个主要错误。这是通过引入新的引擎异常对象实现的。
    19. 您可能已经知道,PHP 5不支持64位整数或大文件,但PHP 7中的情况已发生变化。PHP7具有64位支持,因此您也可以使用本机64位整数作为大文件,因此,您可以在64位系统体系结构上完美运行应用程序。
    20. 10、声明返回类型
    21. 在PHP 5中,程序员无法定义函数或方法的返回类型。在现实生活中,这是一个巨大的缺点,因为程序员无法防止意外的返回类型并在其他情况下生成异常。
    22. 幸运的是,PHP 7允许程序员根据期望的返回值声明函数的返回类型。这肯定会使代码健壮和准确。有四种不同的返回类型可用-boolintstringfloat
    23. 为什么 PHP7 比 PHP5 性能提升了?
    24. 1、变量存储字节减小,减少内存占用,提升变量操作速度
    25. 2、改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用、提升了 cpu 缓存命中率
    26. 3、改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
    27. PHP8 新特性
    28. 1、新增对联合参数
    29. 联合参数使一个变量有多个类型值 ,而不是一个(参考c语言中的联合类型参数就很好理解)
    30. 2、新增weakmap新特性
    31. WeakMap 允许你创建对象到任意值的映射(类似 SplObjectStorage),同时也不会阻止作为键的对象被垃圾回收。如果某个对象键被垃圾回收,对应键值对将从集合中移除。
    32. 这一新特性非常有用,因为这样一来,开发者就不必担心代码存在内存泄露了。大多数 PHP 开发者可能对此并不关心,但是当你编写长时间运行的进程时一定要提防这个问题,比如使用 ReactPHP 进行事件驱动编程时:有了 WeakMap 后,引用的对象会在失效时自动被垃圾回收。
    33. 3、新增 ValueError 异常
    34. PHP 8 引入了新的名为 ValueError 的内置异常类,它继承自 Exception 基类。每次当你传递值到函数时,如果是一个无效类型,则会抛出该异常,在 PHP 8 之前,这样的操作会导致警告。
    35. 4、重写方法时允许可变参数
    36. 当我们在子类重写父类方法时,任何数量的参数现在都可以被替换成可变参数,只要对应参数类型是兼容的即可
    37. 5、静态返回类型
    38. PHP 8 中可以使用 static 关键字标识某个方法返回该方法当前所属的类,即使它是继承的(后期静态绑定)
    39. 6、对象的类名字面量
    40. PHP 8 中可以使用 o b j e c t : : c l a s s 获 取 对 象 的 类 名 , 其 返 回 结 果 和 g e t c l a s s ( object::class 获取对象的类名,其返回结果和 get_class(object::class获取对象的类名,其返回结果和getc​lass(object) 一样
    41. 7、变量语法调整
    42. newinstanceof 关键字现在可以被用于任意表达式
    43. 8Stringable 接口
    44. PHP 8 引入了新的 Stringable 接口,只要某个类实现了 __toString 方法,即被视作自动实现了 Stringable 接口(咋和 Go 接口实现有点像),而不必显式声明实现该接口
    45. 9、Trait 现在可以定义抽象私有方法
    46. 10throw 现在可以被用作表达式
    47. throw 语句现在可以用在只允许表达式出现的地方,例如箭头函数、合并运算符和三元运算符等
    48. 11、参数列表中允许出现可选的尾部逗号
    49. 和数组中的尾部逗号类似,现在也可以在参数列表中定义一个尾部逗号
    50. 12、捕获异常而不存储到变量
    51. 现在可以编写 catch (Exception) 代码来捕获异常而不必将其存储到一个变量中
    52. 13、新增对 mixed 类型的支持
    53. PHP 8 引入了新的名为 mixed 的类型,该类型等价于 array|bool|callable|int|float|null|object|resource|string
    54. 14、新增对注解的支持
    55. 注解绝对是 PHP 8 引入的最大新特性之一,一开始理解起来可能有点困难(不过有 Java 基础的话会很简单)。简而言之,注解允许你添加元数据到 PHP 函数、参数、类等,这些元数据随后可以通过可编程方式获取,在 PHP 7 或者更低版本中实现类似功能需要解析代码注释块,而通过注解可以直接访问深度集成到 PHP 自身的这些信息。
    56. 15、新增构造函数属性提示支持
    57. 这个新特性只是一个语法简写而言,可以将属性声明和构造函数属性初始化合并到一起
    58. 16、新增 match 表达式支持
    59. match 表达式和 switch 分支语句类型,但是语义上更加安全并且可以直接返回值
    60. 17、新增对空安全运算符 ?-> 的支持

    2、isset 与empty之间的区别

    答:

    1. isset()函数一般用来检测变量是否设置。
    2. 格式: isset ( mixed $var [, mixed $... ] )
    3. 参数说明: $var:要检测的变量
    4. 返回值: 若变量不存在则返回 FALSE
    5. 若变量存在且其值为NULL,也返回 FALSE
    6. 若变量存在且值不为NULL,则返回 TURE
    7. empty()函数用来判断值为否为空。
    8. 格式: bool empty ( mixed var )
    9. 参数说明: $var:待检查的变量
    10. 返回值: 当 var 存在,并且是一个非空非零的值时返回 FALSE 否则返回 TRUE
    11. 以下的变量会被认为是空的:
    12. "" (空字符串) 0 (作为整数的0) 0.0 (作为浮点数的0) "0" (作为字符串的0) NULL FALSE array() (一个空数组) $var; (一个声明了,但是没有值的变量)

    3、传值与引用之间的区别

    答:

    1. 传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值
    2. 在php中传值的意思相当于复制,我将你的值复制给我,我可以随意改变复制之后的值,对你是不会产生影响的。
    3. 举例:
    4. $a = 1;
    5. $b = $a;
    6. echo $b.'
      '
      ; //1
    7. $b = 2;
    8. echo $a .'
      '
      .$b; //1 2
    9. // 解释:将a的值赋给b,改变b的值,a的值不受影响。
    10. 传引用 :真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值
    11. 在php中传引用用‘&’符号,是相当于我不仅将你的值赋给我,还将你的内存地址也复制过来了,那么我们两个任何一个改变,另外一个就跟着改变。
    12. 举例:
    13. $a = 1;
    14. $b = &$a;
    15. echo $b.'
      '
      ; //1
    16. $b = 2;
    17. echo $a .'
      '
      .$b; //2 2
    18. // 解释:将a的值和内存地址赋给b,改变b的值,a的值也改变。

    4、==与===的区别

    答:

    1. ==比较两个变量的值,不比较数据类型。
    2. ===比较两个变量的值和类型
    3. 举例:
    4. $a = '123'; string
    5. $b = 123; int
    6. 进行条件判断
    7. $a === $b //为假; 类型不一致
    8. $a == $b //为真; 变量值一致

    5、常用的处理数组的方法

    答:

    1. 获取键则是:array_keys($array);
    2. 交换数组中的键值:array_flip($array);
    3. 判断数组中是否存在某个键:array_key_exits('php',$array);
    4. 向某数组的最后填充数据:array_push($array,'xxx','cccc');
    5. 将数组的第一个元素弹出,并且之后元素前移一位:array_pop($array);
    6. 返回两个数组中不同的地方,即求同存异:array_diff($array,$array2);
    7. 返回数组中相同的元素:array_diff_assoc($array,$array2);
    8. 将两个数组合并返回一个新的数组:array_merge($array,$array2);
    9. 从数组中取出任意一个单元:array_rand($array);
    10. 获取单元顺序相反的数组:array_reverse($array);
    11. 将数组中重复的值去除:array_unique($array);

    6、 在数组中如何让key 与value 值交换

    答:

    1. array_flip() 函数用来交换数组中的键和值
    2. $trans = array("a" => 1, "b" => 1, "c" => 2);
    3. print_r(array_flip($trans));
    4. 如果同一个值出现了多次,那么最后一个键名将作为它的值,所有其他的都丢失了。
    5. Array
    6. (
    7. [1] => b
    8. [2] => c
    9. )

    7、多维数组去重与单数组去重

    答:

    1. php多维数组去除重复值的方法:
    2. 1、使用“array_map('serialize', $arr)”将多维数组转换为以字符串形式的一维数组;
    3. 2、使用array_unique()去除一维数组中的重复值;
    4. 3、将去重后的一维数组重新转为多维数组。
    5. $t = array_map('serialize', $arr);
    6. //利用serialize()方法将数组转换为以字符串形式的一维数组
    7. $t = array_unique($t);
    8. //去掉重复值
    9. $new_arr = array_map('unserialize', $t);
    10. //然后将刚组建的一维数组转回为php值
    11. return $new_arr;

    8、php 系列化方法

    答:

    1. serialize:序列化 :把一个对象转成字符串形式, 可以用于保存
    2. unserialize: 反序列化:把serialize序列化后的字符串变成一个对象
    3. json_encode 和 json_decode JSON格式比serialize返回数据结果小。
    4. JSON格式是开放的、可移植的。其他语言也可以使用它。
    5. var_export 函数把变量作为一个字符串输出;
    6. eval把字符串当成PHP代码来执行,反序列化得到最初变量的内容。
    7. ddx_serialize_value函数可以序列化数组变量,并以XML字符串形式输出。
    8. XML标签字符较多,导致这种格式的序列化还是占了很多空间。

    9、php面向对象的三大基本特征

    答:

    1. 封装:可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作
    2. 继承:对现有类的一种复用机制。一个类如果继承现有类,则这个类将拥有被继承类的所有非私有特性
    3. 多态:是在继承基础上实现的,父类引用指向不同子类对象时,调用相同的方法,呈现出不同的行为
    4. oop七大设计原则? 开里依单接迪合
    5. 开闭原则:对扩展开放,对修改关闭
    6. 依赖倒置原则:面向接口编程,而不面向实现了类
    7. 接口隔离原则:为各个类提供所需的专用接口

    10、抽象类与接口类的区别

    答:

    1. 1、抽象类可以有属性、普通方法,接口不能有属性和普通方法;
    2. 2、抽象类中未必有抽象方法,接口中一定有抽象方法;
    3. 3、抽象类使用abstract关键字声明,接口使用interface关键字声明。
    4. 4、抽象类是用extends关键字让子类继承父类后,在子类实现详细的抽象方法。而接口则是用implements让普通类在类里实现接口的详细方法,且接口可以一次性实现多个方法,用逗号分开各个接口就可
    5. 抽象类:是基于类来说,其本身就是类,只是一种特殊的类,不能直接实例,可以在类里定义方法,属性。类似于模版,规范后让子类实现详细功能。
    6. 接口:主要基于方法的规范,有点像抽象类里的抽象方法,只是其相对于抽象方法来说,更加独立。可让某个类通过组合多个方法来形成新的类。
    7. 相同:
    8. 1、都是用于声明某一种事物,规范名称、参数,形成模块,未有详细的实现细节。
    9. 2、都是通过类来实现相关的细节工作
    10. 3、语法上,抽象类的抽象方法与接口一样,不能有方法体,即{}符号
    11. 4、都可以用继承,接口可以继承接口形成新的接口,抽象类可以继承抽象类从而形成新的抽象类

    11、抽象类与接口类是可以被继承的麽

    答:

    1. 一个类只能实现一个抽象类;但一个类可以实现多个接口,接口可以继承多个接口

    12、PHP 的设计模式

    答:

    1. 单例模式:保证在整个应用程序的生命周期中,单例类的实例只存在一个
    2. 私有化静态属性,私有化构造方法,私有化克隆方法,公有化静态方法。
    3. 工厂模式:定义一个创建对象的接口,让子类去实例化具体类。
    4. 观察者模式 发布/订阅模式:当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
    5. 适配器模式:将一个类的接口转换成客户希望的接口,使得原本不兼容的接口可以兼容
    6. 依赖注入模式:是ioc的一种实现方式。用来减少程序中的耦合

    13、laravel 的生命周期

    答:Laravel生命周期_思维小刀的博客-CSDN博客_laravel的生命周期

    14、laravel生命周期自动加载过那些事情

    答:注册加载composer自动生成的c lass loader ,就是加载初始化第三方依赖。

    15、Laravel容器依赖注入、依赖导致、控制反转

    答:

    1. Laravel服务容器
    2. IoC (控制反转)
    3. DI (依赖注入)
    4. Laravel服务容器是-个用于管理类依赖和执行依赖注入的强大工具。
    5. IoC (控制反转)与DI (依赖注入)
    6. IoC (控制反转)与DI (依赖注入)是现在特别流行的概念,也是目前 降低软件开发复杂度;提升模块低耦合、高内聚所使用的-种设计模 式。
    7. 控制反转与IoC容器
    8. 控制反转:容器控制应用程序,由容器反向的向应用程序注入应用程序 所需要的外部资源;
    9. 控制反转是用来进行对象解耦。通过借助第三方 (IoC容器),将具有 依赖关系的对象进行解耦。
    10. 比如全体齿轮的转动由-个对象来控制,如类B。如下图所示:
    11. 引入了IoC容器后,对象A、B 、C、D之间没有了依赖关系,全体齿轮转
    12. 动的控制权交给IoC容器。这时候齿轮转动控制权不属于任何对象,而 属于IoC容器,所以控制权反转了,从某个对象转到了IoC容器。
    13. 依赖注入
    14. 依赖注入,首先依赖就是指-种关系,如果在类A中创建了类B的实例, 我们就可以说类A依赖类B。
    15. 例如:
    16. class B {
    17. public function func() {
    18. print_r(__CLASS__);
    19. }
    20. }
    21. class A {
    22. private $b;
    23. public function A() {
    24. $this->b = new B();
    25. }
    26. public function func() {
    27. $this->b->func();
    28. }
    29. }
    30. 而使用这种方式,则会出现以下问题:
    31. 问题1:如果现在要改变类B的创建方式,如需要用new B(String name)初始化B,需要修改类A中的源代码;
    32. 问题2:如果想测试不同B对象对A的影响很困难,因为B的初始化 被写死在了A的构造函数中;
    33. 问题3:如果要对类B的实例进行调试时,就必须在类A中对类B的 实例进行测试,增加了测试难度和复杂度;因为当出现问题时,不
    34. 知道是类A的问题 还是类B的问题。
    35. 基于此,提出以下的解决方案:
    36. class A {
    37. private $b;
    38. public function A() {
    39. $this->b = $bObj;
    40. }
    41. public function func() {
    42. $this->b->func();
    43. }
    44. }
    45. 将B对象实例作为类A的构造器参数进行传入,在调用类A构造器之前, 类B实例已经被初始化好了。像这种非自己主动初始化依赖,而通过外 部传入依赖对象的方式,就很完美的解决了上述的问题,这就是依赖注 入。

    16、laravel 服务提供者、门面、中间件带来的好处

     答:

    Laravel 中的门面总体上还是遵循着门面模式的基本思想的。Laravel 中的门面是为应用的服务容器提供一个【静态】接口,相当于是服务容器底层类中的一个【静态代表】,能够提供更加灵活、易于测试、优雅的语法。laravel为什么要用门面-Laravel-PHP中文网

    服务提供者是laravel 的引导中心 https://www.jianshu.com/p/ad60c37a29e0

    $middleware:全局中间件,要对所有的请求要做一些处理的时候,就适合定义在该属性内。(比如统计请求次数这些)
    $middlewareGroups:中间件组,比如我们项目有 api 请求和 web 的请求的时候,就要把两种类型的请求中间件分离开来,这时候就需要我们中间件组啦。
    $routeMiddleware:路由中间件,有些个别的请求,我们需要执行特别的中间件时,就适合定义在这属性里面。  https://www.jb51.net/article/171835.htm

    17、简述PHP-FPM的了解

    答: PHP-FPM采用的是Master/Worker进程模型。当PHP-FPM启动时,会读取配置文件,然后创建一个Master进程和若干个Worker进程(具体是几个Worker进程是由php-fpm.conf中配置的个数决定)。Worker进程是由Master进程fork出来的。PHP-FPM进程模型 - 知乎

    18、如何提高一个接口的并发量

    19、Mysql优化

    答:

    1. 减少数据访问:设置合理的字段类型,启用压缩,通过索引访问等减少磁盘IO
    2. 返回更少的数据:只返回需要的字段和数据分页处理 减少磁盘io及网络io
    3. 减少交互次数:批量DML操作,函数存储等减少数据连接次数
    4. 减少服务器CPU开销:尽量减少数据库排序操作以及全表查询,减少cpu 内存占用
    5. 利用更多资源:使用表分区,可以增加并行操作,更大限度利用cpu资源

     MySQL最全优化总结 - 知乎

    1. 1. 尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描
    2. 2. 尽量避免使用in 和not in,会导致引擎走全表扫
    3. 3. 尽量避免使用 or,会导致数据库引擎放弃索引进行全表扫描
    4. 4. 尽量避免进行null值的判断,会导致数据库引擎放弃索引进行全表扫描。
    5. 5. 尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描。
    6. 等等

    20、现在有一个表,然后里面有 abcde 五个字段,然后我给 ECD 加了一个联合索引。那我在查询的时候哪些情况下会用到这个索引

    答: 最左匹配

    21、当联合索引遇到where条件是 索引失效

    22、现在一个Sql语句,他已经用到了我设定的索引,但是他还是查询效率非常低。那他可能存在的原因是什么?

    答:为什么我使用了索引,查询还是慢? - 知乎

    • 全表扫描
    • 全索引扫描
    • 索引过滤性不好
    • 频繁回表的开销

    23、Mysql 主从复制 主从同步的实现机制

    答: MySQL——主从复制与读写分离 - 知乎 (zhihu.com)

    24、Redis 的数据类型 及常用的使用场景

    答:(4条消息) Redis的五种常用数据类型、三种特殊数据类型详解_Coder_Oldou的博客-CSDN博客_redis特殊数据类型

    25、redis签到为什么使用bitmap 而不使用string?

    答:   bitmap 存储格式 12进制 kb  字符串 存储占用内存

             读写方面 bitmap 比string 更加稳定

    26、秒杀场景

    答:秒杀场景实现思路_QQsilhonette的博客-CSDN博客_秒杀场景实现

    1. 1、首先在秒杀前先进行预热,将商品的库存加载到redis上;
    2. 2、秒杀开始,后端收到请求后,redis预减库存,如果库存已经没有了,就直接返回失败;
    3. 3、另外还要判断是否重复进行秒杀,避免一个账户重复秒杀;
    4. 4、如果库存充足且没有重复秒杀,就将秒杀请求加入消息队列,然后返回前端正在排队中;
    5. 5、后端消费端监听消息,如果有消息来了,则在数据表中再次判断库存和是否重复秒杀;
    6. 6、最后执行秒杀,减库存的时候要通过sql where条件>0的原子性来保证不会卖超,成功则返回订单号,否则返回秒杀失败。
    7. 在这个过程中还需要做一些安全性的优化:
    8. 1、要防止缓存穿透,要对不存在的对象也建立缓存;
    9. 2、要做接口防刷:a.通过隐藏秒杀地址的方式,在点击秒杀按钮时,先去请求一个动态的字符串并保存到缓存中,然后前端再将收到的这个字符串和秒杀接口做拼接再去请求秒杀,并判断这个字符串。b.通过url+userId拼接Key,并设置次数和有效期,控制5秒内最多访问5次。前端也可以加入验证码。
    10. 最后要做一个定时器,对30分钟还没有完成支付的订单要做退库存处理。

  • 相关阅读:
    Pooling Revisited: Your Receptive Field is Suboptimal 论文解读和感想
    C++11的互斥量
    使用Obfuscar 混淆WPF(Net6)程序
    docker如何下载国外镜像
    springcloudalibaba架构(13):Spring Cloud Gateway服务网关和入门案例
    服务器数据恢复—VMware虚拟化下误操作导致服务器崩溃的数据恢复案例
    Android -- 每日一问:两个 Activity 之间如何传递参数?
    Kamiya丨Kamiya艾美捷小鼠脱细胞素ELISA说明书
    设计模式-工厂方法模式
    Lua 模块 module
  • 原文地址:https://blog.csdn.net/qq_63530862/article/details/126566114