PHP面试题 | https://blog.csdn.net/hzbskak/article/details/120852249 |
---|---|
REDIS面试题 | https://blog.csdn.net/hzbskak/article/details/120852279 |
MYSQL面试题 | https://blog.csdn.net/hzbskak/article/details/120852285 |
NGINX面试题 | https://blog.csdn.net/hzbskak/article/details/120852271 |
列举一些 PHP 中的设计模式?
-
单例模式:保证在整个应用程序的生命周期中,单例类的实例只存在一个
-
工厂模式:定义一个创建对象的接口,让子类去实例化具体类。
-
观察者模式 发布/订阅模式:当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
-
适配器模式:将一个类的接口转换成客户希望的接口,使得原本不兼容的接口可以兼容
-
依赖注入模式:是ioc的一种实现方式。用来减少程序中的耦合
简述一下 PHP 垃圾回收机制(GC)
php使用了引用计数,同时使用根缓存区机制,当php发现有存在循环引用的zval时,就会把其投入到根缓冲区,当根缓冲区达到配置文件中的指定数量后,就会进行垃圾回收,一次解决循环引用导致的内存泄露问题
- 如果引用计数减少到零,所在变量容器将被清除(free),不属于垃圾;
- 如果一个zval的引用计数减少后还大于0,那么它会进入垃圾周期。其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾。
每个对象都内含一个引用计数器refcount,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为 NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。
如何解决 PHP 内存溢出问题
1.增大 PHP 脚本的内存分配
2.变量引用之后及时销毁
3.将数据分批处理
php类的静态调用和实例化调用各自的利弊
静态方法可以直接调用,比实例化效率高,但不能自动销毁
列出一些防范SQL注入、XSS攻击、CSRF攻击的方法
转义关键字符,使用PDO预处理方式
过滤输入,使用htmlspecialchars过滤转义
使用token验证 使用验证码
******秒杀
前端:
- 静态化:将活动页面上所有可以静态显示的元素全部静态化,尽量减少动态元素。
- 限流:针对某个ip,限制单位之间内的请求数量
后台:
- redis:将所有DB操作放到队列中排队,使用串行处理。
isset() 和 empty() 区别
isset检测变量是否存在,可以传多个值
empty检测变量是否为空
冒泡排序
function mysort($arr)
{
for ($i = 0; $i < count($arr); $i++) {
for ($j = 0; $j < count($arr) - 1 - $i; $j++) {
if ($arr[$j] > $arr[$j + 1]) {
$tmp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $tmp;
}
}
}
return $arr;
}
$arr = array(3, 2, 5, 1);
print_r(mysort($arr));
请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用?
按值传递:函数范围内对值的任何改变在函数外部都会被忽略
按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。按引用传递则不需要复制值,对于性能提高很有好处。(优缺点会考到)
SESSION 与 COOKIE的区别是什么?这是重点
session存在服务器端,cookie存在浏览器端,session比较安全,禁用cookie后,session还可以使用。
PHP 如何实现多继承
-
接口多继承
-
trait
include和require的区别是什么?
include在引入不存在文件时会产生一个警告但会继续运行
require会出现一个致命性错误,并不会运行
长连接、短连接的区别和使用
长连接:client与server建立连接,连接后不断开。且一直存在。
短连接:client与server在通讯时才建立连接。完成后久会断开。
长连接常用于socket通信,短链接常用于web http服务
swoole
为什么你要用swoole,能解决你项目中的哪些痛点?
swoole是一个网络通讯和异步IO的引擎。
swoole相比于传统的apache/fpm,节省了框架对全局对象每次创建和销毁带来的性能开销。升进程常驻内存型。
你是如何通过swoole提升性能的,怎么做的?
进程常驻内存:在进程启动的时候就将php框架等代码读取并编译完成,不需要每次启动的时候都执行编译步骤。
连接池:fpm的模式php每次请求结束都会销毁所有资源,无法使用连接池。swoole进程是常驻内存模式,可以通过连接池的方式来降低程序的响应时间。
协程IO:fpm是阻塞式运行的,不能够并行的运行请求。swoole可以开启多个协程。
swoole里的协程是什么,怎么用?为什么协程可以提高并发?
协程是通过协作而不是抢占的方式来进行切换的。他的切换对内存的资源要求比线程小得多。
协程可以异步处理任务,支持并发。且资源消耗少
用了swoole以后,会不会发生内存泄漏?如果发生了怎么解决?
局部变量会在函数返回后将所有的变量回收释放。
全局变量不会被释放。但可以设置max_requset。当进线程结束运行时或者打到任务上线后进程自动退出,该进程的所有变量和资源都会被回收。
协程适用的场景?
高并发服务,如秒杀系统、高性能API接口、RPC服务器,使用协程模式,服务的容错率会大大增加,某些接口出现故障时,不会导致整个服务崩溃。
爬虫,可实现非常巨大的并发能力,即使是非常慢速的网络环境,也可以高效地利用带宽。
即时通信服务,如IM聊天、游戏服务器、物联网、消息服务器等等,可以确保消息通信完全无阻塞,每个消息包均可即时地被处理。
协程与线程区别
Swoole的协程在底层实现上是单线程的,因此同一时间只有一个协程在工作,协程的执行是串行的。这与线程不同,多个线程会被操作系统调度到多个CPU并行执行。
一个协程正在运行时,其他协程会停止工作。当前协程执行阻塞IO操作时会挂起,底层调度器会进入事件循环。当有IO完成事件时,底层调度器恢复事件对应的协程的执行。
对CPU多核的利用,仍然依赖于Swoole引擎的多进程机制。
什么是心跳机制?
心跳就是业务层来提供一个连接判断是否存活
- 客户端定时发送一个心跳包,告诉服务器,服务器定时检测所有客户端。看最后一个心跳包的时间长短。如果过长则主动关闭这个连接。
- 服务器定时询问所有的客户端。如果没有反馈则关闭连接。
两种心跳方案有什么区别?
第一种,对服务和网络压力小,但需要客户但配合。
第二种对服务器和网络压力大。
PHP/Swoole 如何处理高并发?
swoole采用的架构模式是多线程Reactor + 多进程Worker,又因为Reactor是基于epoll的,所以每个Reactor可以用来处理多个连接请求。
Swoole 如何实现异步I/O
swoole的worker进程有两种类型,一种是普通的woker进程,一种是task worker进程。
worker进程:用来处理普通的不怎么耗时的请求。
task worker:用来处理比较耗时的请求。比如数据库的I/O操作
传输层主要有哪些协议?
主要有 TCP 和 UDP 协议。他们的区别是 TCP 是需要连接的 会经过三次握手,而且可以保证消息的可靠性。UDP 是不需要连接的,不保证消息的可靠性。
你能大体说说 TCP 的三次握手吗?
首先服务器监听某个端口,客户端发起请求 携带 syn 数据包 (第一次),服务端接收到这个数据包,返回 syn/ack 的数据包给客户端 (第二次),最后客户端再次发送一个 ack 的数据包(第三次)。
为什么需要三次握手?
为了确认双方接收是否正常
假设现在有多个入口可以同时使用一个账户操作,这个账户只有十块钱,有哪些方法可以使得不超扣消费?
使用悲观锁
redis:lua脚本
队列