PHP 相关
php 里的数组是怎么实现的?
- PHP哈希表内核实现
- PHP7 数组的底层实现
- arData数组索引下标为负的部分是uint32_t散列表,其他是bucket数组元素(有序的)
- 以访问$arr['a']为例,a用time33散列得到193496974,193496974与nTableMask位或运算得到-2
- 以-2为下标到散列表中找到value,value即是bucket数组的下标,即可找到元素
- 散列冲突:如果找到的元素的key不是a,则通过zval.u2.next(bucket数组的下标)继续找,直到找到元素为止。
Nginx 的配置
- Nginx进程和运行时控制
- 通常是1个master和n个worker,worker个数对应cpu的个数
nginx 和 php-fpm 的通信机制?fast-cgi 和 cgi 区别?
- PHP-FPM 与 Nginx 的通信机制总结
- nginx将请求对应的php文件发送给fpm,fpm通过php进程进行解析运行,再将结果返回给nginx
- tcp socket 和 unix socket(没有tcp的开销,高并发时不稳定)
- cgi针对每个http请求都是fork一个新进程,fast-cgi会预先fork好worker
php-fpm 创建 worker 进程的规则是什么?
- 阅读《 PHP7 内核剖析》的感悟笔记
- static: 这种方式比较简单,在启动时master按照pm.max_children配置fork出相应数量的worker进程,即worker进程数是固定不变的
- dynamic: 动态进程管理,首先在fpm启动时按照pm.start_servers初始化一定数量的worker,运行期间如果master发现空闲worker数低于pm.min_spare_servers配置数(表示请求比较多,worker处理不过来了)则会fork worker进程,但总的worker数不能超过pm.max_children,如果master发现空闲worker数超过了pm.max_spare_servers(表示闲着的worker太多了)则会杀掉一些worker,避免占用过多资源,master通过这4个值来控制worker数
- ondemand: 这种方式一般很少用,在启动时不分配worker进程,等到有请求了后再通知master进程fork worker进程,总的worker数不超过pm.max_children,处理完成后worker进程不会立即退出,当空闲时间超过pm.process_idle_timeout后再退出
php 和 mysql 的通信机制?长连接和短连接啥区别?连接池要怎么实现?
- PHP底层和mysql的通信原理
- PHP中实现MySQL连接池与持久化
- 通讯:tcp socket 和 unix socket,代码中不用关闭连接,php内部会去处理
- 短连接是用完就会关闭;长连接会复用连接,连接时长取决于mysql的wait_timeout,超时会报错MySQL server has gone away
- 长连接在fpm子进程生命结束时自动释放,断线重连应该直接mysql connect而不是mysql ping
- 连接池的方案:
- Apache + mpm功能
- nginx + stream-lua 模块
- swoole + AsyncTask模块
- swoole 的协程模式
依赖注入是什么?如何实现的?能解决什么问题?
业务代码不再依赖具体实现,解耦
static、self、$this 的区别
- static:static 可以用于静态或非静态方法中,也可以访问类的静态属性、方法和非静态方法,但不能访问非静态属性
- self:可以用于访问类的静态属性和方法,但 self 指向的是当前定义所在的类,这是 self 的限制
- $this:指向的是实际调用时的对象,但 $this 不能访问类的静态属性和方法,且 $this 不能存在于静态方法中
不实例化的调用类
静态调用、使用 PHP 反射方式
PSR-1, 2, 4, 7
- PSR-1,编码规范,命名大小写等
- PSR-2,编码风格,换行缩进等
- PSR-4,自动加载规范
- PSR-7,HTTP相关接口类:Request、Response、Streamable、Uri
BOM 头是什么,怎么除去
文件开头的3个字节用来标识该文件属于utf-8编码,php无法识别它
oauth2.0和jwt
- 读懂 SSO、OAuth 2.0、OpenID Connect
- oauth2.0(用户——网站/APP——第三方平台)授权类型有:
- 授权码模式,先得到Authorization Code,再得到Access Token
- 隐式模式,将授权码模式的2步合成一步,直接得到Access Token
- 密码凭证,用户直接输入账户密码
- 客户端证书,这种一般是适用于:网站/APP——第三方平台
- jwt:Authorization: Bearer
。适用场景是邮箱验证,邮箱改密码等。
一致性hash算法
- PHP 之一致性 hash 算法
- 先把server hash对应到2^32的圆形槽中,查key的时候也hash对应到槽中,取就近的server
- 为了保证server在圆形槽的均匀性,每个server虚拟化多个槽出来
composer自动加载
- 深入学习 Composer 自动加载
- autoload.php、autoload_real.php、autoload_static.php
- classmap、psr-4通过spl_autoload_register注册自动加载
- files是直接include的
- PS:要记得composer dump-autoload
什么是闭包
- PHP 新特性之闭包、匿名函数
- 创建闭包后,闭包所在的环境不存在了,闭包封装的状态依然存在
git rebase使用
- Git rebase使用
- 在local分支上先git fetch origin再git rebase origin/master
- 下游分支更新上游分支内容的时候使用 rebase
- 上游分支合并下游分支内容的时候使用 merge
- 更新当前分支的内容时一定要使用 --rebase 参数
- git pull = git fetch + git merge
PHP Trait
- 我所理解的 PHP Trait
- PHP 核心特性 - Trait
- PHP的trait abstract方法之灵异细节
- Trait 不是一个对象,而是对象的一个特性。
- 两种常用代码复用模式:继承和组合,PHP不能多继承,要实现多个特性,就要多层继承,增加了复杂性
- User 类要增加一个 Cacheable 特性,用 Trait 很好命名。若用继承命名成CacheableUser,不够优雅,多层继承也不直观
- 抽象类的抽象方法的访问控制必须和父类中一样(或者更为宽松),Trait 的抽象方法的访问控制没有限制
- PS:如果PHP支持多继承貌似也可以解决问题,不过“特性”这个用法更准确
PHP 的垃圾回收机制(简称GC)
- PHP 详细面试总结
- 每个对象都内含一个引用计数器,每个 reference 链接到对象,计数器加 1,当 reference 离开对象被设为 null, 计数器减 1,当某个引用计数器的对象为 0 时,PHP 知道你将不再需要使用这个对象,释放其所占有的内存空间
- 简单来说就是:在 PHP 中,没有任何变量指向一个对象的时侯,这个对象就成为垃圾。
PHP7 为什么比 PHP5 性能提升了
- PHP 详细面试总结
- 重写了底层的 Zend Engine,名为 Zend Engine 3。
- 在 PHP7 中的 zval, 已经变成了一个值指针,它要么保存着原始值,要么保存着指向一个保存原始值的指针
- 变量存储字节减小,减少内存占用,提升变量操作速度
- 改善数组结构,数组元素和 hash 映射表被分配在同一块内存里,降低了内存占用、提升了 cpu 缓存命中率
- 改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
PHP 生命周期
- PHP 生命周期
- MINIT(module init),读php.ini,初始化类、常量、扩展等 PHP 所用到的资源
- RINIT(request init),初始化脚本执行的基本环境,SAPI 将控制权交给 PHP,激活 Zend 引擎,初始化执行器
- PHP 脚本执行,Zend 引擎接管控制权,将 PHP 脚本编译成 Opcodes,并顺序执行
- RSHUTDOWN(request shutdown),将 flush 输出内容,发送 http 响应内容,关闭 PHP 执行器
- MSHUTDOWN(module shutdown),资源的清理、php 各模块的关闭操作