面试总结
redis缓存
缓存穿透(缓存穿透是指恶意或异常的查询请求导致缓存系统无法命中缓存,每次请求都要查询数据库或其他存储后端,导致数据库或存储系统压力过大的问题)
-
缓存空数据
-
布隆过滤器
缓存击穿(缓存击穿是给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB给压垮)
- 逻辑过期(逻辑过期,意味着永不过期。缓存击穿问题产生的原因是某个热点key过期了,请求都打到数据库了,造成数据库压力过大。因此我们可以提前准备一个不过期的热点key ,不设置它的过期时间,将这个key保存到redis中,这样理论上总能命中redis。那是怎么判断这个key逻辑上过期了?答案是这个key的value存储一个过期时间,我们判断这个key是否过期的依据,就是这个key的value保存的过期时间。)
缓存雪崩
- 给不同的key的过期时间设置添加一个随机值,降低同一个时段大量key同时过期的概率
- 如果redis服务宕机,可以利用redis一些高可用的方案 比如哨兵模式,集群模式
- 给缓存业务添加降级限流策略 可以利用ngxin或者getway
- 给业务添加多级缓存 Guava或者caffeine为一级缓存,redis为二级缓存
Redis作为计数器
-
Redis INCR
-
Redis Sets
-
Redis Bitmap
-
Redis HyperLogLog
-
同步策略
php面试
-
解释PHP中的 _construct 和 _destruct 魔术方法的作用
construct构造方法 类实例化时调用 destruct 析构函数 实例销毁时调用
-
include和require在执行失败的情况下有什么不同?
include 载入的文件不存在时 会出发警告错误, require 载入文件不存在时会报致命错误
-
在YII框架中,如何实现RESTFUL API?
使用Gii生成。针对GET, POST,DELETE,PUT调用不同的方法
-
简要说明 ThinkPHP框架中,路由的配置方式及其实现原理是什么?
多应用 或 单应用下的route文件夹下面新建php文件内容使用Route类的Rule,Get,Post方法配置url与controller方法的映射关系。
实现原理是Request类根据route配置自动将url地址与controller方法绑定。 保存在一个数组里
-
如何优化一个PHP程序的执行速度
- 优先使用单引号包含字符串。
- 优先file_get_contents读取文件内容
- foreach比for的效率更高
- 使用OPcache 可以把预编译的PHP字节码缓存在内存中 减少重复编译的开销
- 减少不必要的数据库交互
- 尽量使用PHP内置函数
-
解释并举例说明PHP中的内存泄漏,以及如何避免
- 及时关闭不需要的资源
- 避免类的相互引用 导致内存泄漏
- 避免大面积使用静态变量
-
简单描述下在面对高并发的场景,可以做那些优化
- 服务器加入负载均衡
- 热点数据加入缓存
- 耗时长的操作加入消息队列
- 请求排队访问策略,熔断策略
-
PHP7的新特性 (参考:https://www.runoob.com/php/php7-new-features.html)
-
标量类型与返回值类型声明 (为变量标识类型)
-
NULL 合并运算符 (?? 替代 ? 😃
-
太空船运算符(组合比较符 <=> 用于比较两个表达式 $a 和 $b,如果 $a 小于、等于或大于 $b时,它分别返回-1、0或1。)
-
常量数组
-
匿名类
-
Closure::call()
-
增加了可以为 unserialize() 提供过滤的特性,可以防止非法数据进行代码注入,提供了更安全的反序列化数据。
-
通过 intl 扩展来支持国际化 (i18n) 和本地化 (l10n) 。此扩展仅仅是对 ICU 库的基础包装,并提供了和 ICU 库类似的方法和特性。
-
通过引入几个 CSPRNG 函数提供一种简单的机制来生成密码学上强壮的随机数。(random_bytes, random_int)
-
异常用于向下兼容及增强旧的assert()函数
-
可以使用一个 use 从同一个 namespace 中导入类、函数和常量
-
PHP 7 改变了大多数错误的报告方式。不同于 PHP 5 的传统错误报告机制,现在大多数错误被作为 Error 异常抛出。
这种 Error 异常可以像普通异常一样被 try / catch 块所捕获。如果没有匹配的 try / catch 块, 则调用异常处理函数(由 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。
Error 类并不是从 Exception 类 扩展出来的,所以用 catch (Exception $e) { ... } 这样的代码是捕获不 到 Error 的。你可以用 catch (Error $e) { ... } 这样的代码,或者通过注册异常处理函数( set_exception_handler())来捕获 Error。
-
新增加了 intdiv() 函数,接收两个参数,返回值为第一个参数除于第二个参数的值并取整。
-
session_start() 函数可以接收一个数组作为参数,可以覆盖 php.ini 中 session 的配置项。
这个特性也引入了一个新的 php.ini 设置(session.lazy_write), 默认情况下设置为 true,意味着 session 数据只在发生变化时才写入。
除了常规的会话配置指示项, 还可以在此数组中包含 read_and_close 选项。如果将此选项的值设置为 TRUE, 那么会话文件会在读取完毕之后马上关闭, 因此,可以在会话数据没有变动的时候,避免不必要的文件锁。
-
-
PHP8的新特性 (参考:https://segmentfault.com/a/1190000039038319, https://learnku.com/articles/86368)
-
命名参数可以让函数或者方法的调用更加清晰直观,对于如下的函数定义
-
相对于以前的 PHPDoc 声明类型的组合, 现在可以用原生支持的联合类型声明取而代之,可在实际运行中验证。
-
新的
mixed
类型 -
引入了 JIT (Just-In-Time) 编译器(即时编译引擎),可以显著提高代码执行速度。JIT 编译器已经集成在了 Opcache 插件中,只有启动 Opcache 插件才有效;
-
在 PHP 8 之前,类的属性必须在构造函数中进行初始化。然而,在 PHP 8 中,你可以直接在属性声明时为其赋予默认值,这样就不需要再在构造函数中进行初始化。
-
PHP 8 引入了更严格的类型系统,允许你在属性声明时指定其类型。这有助于在开发过程中捕获类型错误,并提高代码的可读性和可维护性。
-
PHP 8 引入了只读属性(read-only properties)的概念。使用 public readonly 关键字定义的属性只能在对象构造时或在 __construct 方法内部被赋值,之后就不能再修改了。这有助于确保对象的不变性。
-
match
表达式允许你根据表达式的值来匹配不同的情况,并执行相应的代码块。它使用了一种类似于数组解构的语法,使得代码更加简洁和直观。 -
在 PHP 8 中,引入了一个新的运算符叫做 Nullsafe 运算符(?->)。这个运算符提供了一种安全的方式来访问对象的属性或调用对象的方法,而不需要担心对象本身是否为 null。在 PHP8 以前的版本 中,如果你尝试访问一个 null 对象的属性或方法,将会引发一个错误。为了避免这种情况,开发者通常需要在使用对象之前进行空值检查。然而,这会导致代码变得冗长且难以阅读。
Nullsafe 运算符的引入解决了这个问题。它允许你在不进行显式空值检查的情况下安全地访问对象的属性或方法。如果对象本身是 null,Nullsafe 运算符将返回 null,而不会引发错误。
-
支持注解
-
构造器属性提升
-