phper
2021-12-21 17:07:02 4 举报
AI智能生成
php技术栈(最好照着写一遍,才能印象深刻。知识不是 看过即拥有,随着时间推移 大概率会忘记)。
作者其他创作
大纲/内容
简历
沟通
PPT
向上管理
https://github.com/yuhaqiang123/my-love
子主题
如何快速融入团队
软素质
为什么换工作
我的回答有什么建议
团队做的事
我如果入职 定位 & 向谁汇报
刚才问题、场景 的解决方案
我的 结果如何(有自己的判断,审时度势的问)
有什么想问我的
面试技巧
健康的活着
健康
https://www.processon.com/view/601958907d9c0858d76c10dc?fromnew=1
P7 P8 java架构师技能树
P7
P8
https://www.processon.com/view/5cae9e72e4b0773d8c0a550c?fromnew=1
php高级工程师知识体系
职级发展
https://juejin.cn/post/6986448496987471885
php 转go 注意事项
经验不多
照着框架 && 说明 可以敲代码
GO(另一个语言)
1.CPU负载和CPU利用率的区别是什么?
2.那如果CPU负载很高,利用率却很低该怎么办?
3.那如果负载很低,利用率却很高呢?
4.那如果CPU使用率达到100%呢?怎么排查?
ls
touch
https://mp.weixin.qq.com/s/7bSwKiPmtJbs7FtRWZZqpA
5.说说常见的Linux命令吧?
https://mp.weixin.qq.com/s/24vBHgtw5efC9V9yYqknNg
https://mp.weixin.qq.com/s/CGqy0j5WvarN6mTmYB8vSA
进程间通信
https://www.processon.com/mindmap/6177e182e401fd6d2b18ea9d
Linux 面试题
linux
nginx
1、php-fpm 单个 php 进程 占内存大小
在php-fpm启动的时候,不会给这个pool启动任何一个worker,是按需启动,当有连接过来才会启动。
优点:按流量需求创建,不浪费系统资源(在硬件如此便宜的时代,这个优点略显鸡肋)
在大流量的系统上master进程会变得繁忙,占用系统cpu资源,不适合大流量环境的部署
缺点:由于php-fpm是短连接的
ondemand
启动采用固定大小数量的worker
static
idle > pm.max_spare_servers
pm.max_spare_servers
默认pm.min_spare_servers + (pm.max_spare_servers - pm.min_spare_servers) / 2
优点:动态扩容,不浪费系统资源,master进程设置的1秒定时器对系统的影响忽略不计;
缺点:如果所有worker都在工作,新的请求到来只能等待master在1秒定时器内再新建一个worker,这时可能最长等待1s;
dynamic
2、php-fpm 三种模型
每个worker都在accept本pool内的监听套接字(linux已不存在惊群现象)
master + worker
php-fpm的工作模式和nginx类似
https://jiachuhuang.github.io/2017/07/06/PHP-FPM进程模型/
master:epoll
master 进程监控 端口
child :单进程单线程模型,每次只处理一个请求
worker 处理请求
可以保持 mysql reids 连接
4、进程模型
https://blog.csdn.net/wuhuagu_wuhuaguo/article/details/78918771
这个解释更准
https://www.cnblogs.com/shijianchuzhenzhi/p/6675203.html
https://blog.csdn.net/weixin_42510026/article/details/113475404
那么理所当然的是我们打开的数据库连接句柄也会被释放,但是这只限于我们打开连接的时候使用的是短链接
php在执行RSHUTDOWN的时候会释放所有处理本次请求的资源,如申请的变量。
https://blog.csdn.net/weixin_34187822/article/details/94704831?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.highlightwordscore&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.highlightwordscore
达到长连接目的
保留 句柄
处理完后php会收留在本次打开的连接
打开的是长连接
数据库允许连接数要大于php-fpm子进程数
php活动时这边会重新建立新连接。这样避免时间长了mysql有一大堆不活动的连接。
wait_timeout 和interactive_timeout控制连接时长当一个连接很长时间没活动的时候mysql就关闭它
mysq再配置一下
配合数据库的一些配置
BUT
no no no 不一定
长链接 硬伤
代理
需要新方案
长链接 数
这个可能会超越 mysql 、redis
一个worker 一个长链接
长链接数量会达到好几百
多个服务器
一个 master 多个 worker
php-fpm
lnmp 架构
唯一主键
分库分表
https://segmentfault.com/a/1190000016409178
https://www.zhihu.com/question/408729025
前端 自己解析???
如果长文本中==》存在动态数据怎么办
如果 静态文件还好
长文本存储方案
字段优化
没视图概念 都是返回最新的
读未提交
不同的read view
读已提交
用一个read view
可重复度
序列化
5.5之前回滚段删了文件也不会变小
没更早的read view删除
回滚日志
事务隔离级别
B+
等值查询
Hash
预发跑sql explain
排除 缓存 sql nocache
看一下行数对不对 不对可以用analyze table t 矫正
添加索引 索引不一定是最优的 force index 强制走索引 不建议用
存在回表的情况
主键索引
覆盖索引避免回表,不要*
联合索引 不能无限建 高频场景
最左前缀原则 按照索引定义的字段顺序写sql
合理安排联合索引的顺序
5.6之后 索引下推 减少回表次数
前缀索引
倒序存储
给字符串加索引
redo log满了 修改checkpoint flush到磁盘
要知道磁盘的io能力 设置innodb_io_capacity 设置为磁盘的IOPS fio测试
innodb_io_capacity设置低了 会让innoDB错误估算系统能力 导致脏页累积
buffer pool
系统内存不足淘汰数据页
系统空闲的时候 找间隙刷脏页
MySQL正常关闭,会把内存脏页flush到磁盘
数据库的flush的时机
脏页比例
redolog 写盘速度
机械磁盘的随机io不太行 减少随机io性能大幅提升 设置为 1最好
现在都是ssd了 设置为0就够了 8.0之后默认是0
innodb_flush_neighbors 0
innodb刷盘速度
如果触发隐式转换 那也会走cast函数 会放弃走索引
索引字段不要做函数操作,会破坏索引值的有序性,优化器会放弃走树结构
convert 也是函数所以走不上
字符集不同可能走不上索引
优化流程
聚集索引
减少回表
多扫描一次
非聚集索引
页满了 页分裂 页利用率下降
数据删除 页合并
自增 只追加可以不考虑 也分页
索引长度
索引维护
找到第一个之后 直到朋友不满足的
普通索引
找到第一个不满足的就停止了
唯一索引
包含主键索引值
覆盖索引
安排字段顺序
最左前缀原则
hash
索引空间问题
不需要多个回表 一边遍历 一边判断
5.6之后索引下推
页的概念
change buffer
更新操作来了 如果数据页不在内存 就缓存下来 下次来了 更新 在就直接更新
唯一索引 需要判断 所以 用不到change buffer
唯一索引 判断没冲突插入
普通索引 插入
记录在页内存
数据页读入内存 判断 插入
记录不再页中
数据读是随机IO 成本高
机械硬盘 change buffer 收益大 写多读少 marge
innodb的处理流程
更新
索引选择
索引
版本链 在聚集索引中 有两个隐藏列 trx_id roll_pointer
直接读取最新版本
加锁
每次读取前生成一个
第一次生成一个
Read View
MVCC
全库逻辑备份
全局锁
lock table read/write
MySQL5.5引入 自动添加 读锁不互斥 写锁互斥
MySQL的information_schema 库的 innodb_trx 表 找到对应长事务 kill掉
alter table里面设定等待时间
多个事务之前操作,如果查询的时候修改字段容易让线程池饱满
MDL(metadata lock)
Myisam是不支持表锁的
表锁
需要的时候才加上 并不是马上释放 等事务结束才释放 两阶段锁协议
默认是50s太久 但是如果设置太短会误判 一般采用死锁监测
innodb_lock_wait_timeout
超时时间
innodb_deadlock_detect = on
死锁机制 事务回滚
死锁
关掉死锁会出现大量重试
临时关闭
死锁消耗CPU
更多的机器 开启比较少的线程 消耗就少了
控制并发度
分治
热点行
行锁
间隙锁
lock in share mode
for update
读
写
读写锁
innodb如何加锁
锁
回滚 mvcc
undo log
sync_binlog 可以优化日志写入时机
物理日志 内存操作记录
redo log
组提交机制,可以大幅度降低磁盘的IOPS消耗。
binlog
两段式提交 redo 准备 binglog 提交
log
mvcc影响
count1 *
强制走主
sleep
主备延迟
驱动表
join
bigint
row_id 没设置主键的时候
thread_id
id用完
设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count参数,减少binlog的写盘次数。这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但没有丢失数据的风险。将sync_binlog 设置为大于1的值(比较常见是100~1000)。这样做的风险是,主机掉电时会丢binlog日志。将innodb_flush_log_at_trx_commit设置为2。这样做的风险是,主机掉电的时候会丢数据。
mysql io性能瓶颈
查看空闲忙碌链接
定时断开链接
mysql_reset_connection 恢复链接状态
客户端空闲时间
wait_timeout
show processlist
redolog事务持久化
innodb_flush_log_at_trx_commit
binlog事务持久化
sync_binlog
常见命令
数据库挂了 show processlist 一千个查询在等待 有个超长sql kill 但是不会引起flush table 周末 优化脚本 analyze 会导致 MySQL 监测到对应的table 做了修改 必须flush close reopen 就不会释放表的占用了
真实故障
MySQL
原子性
Atomicity
A
原子性、持久性和隔离
一致性
Consistency
C
MVCC + 间隙锁(Next-key Lock)
InnoDB默认级别
为解决问题:
解决了读数据情况下的幻读问题
解决:
修改的操作下 存在幻读问题
未解决:
并不是完全解决了幻读的问题
但是有一点大家是一致的,就是RR在数据库标准定义里是没有解决幻读问题的
同一条数据,在一次事务中 读取的数据是一致的(MVCC 读取记录的历史版本数据)
只要对 SELECT 操作也手动加行(X)锁即可类似 SERIALIZABLE 级别(它会对 SELECT 隐式加锁),即大家熟知的:
# 这里需要用 X锁, 用 LOCK IN SHARE MODE 拿到 S锁 后我们没办法做 写操作SELECT `id` FROM `users` WHERE `id` = 1 FOR UPDATE;
如果 id = 1 的记录存在则会被加行(X)锁,如果不存在,则会加 next-lock key / gap 锁(范围行锁),即记录存在与否,mysql 都会对记录应该对应的索引加锁,其他事务是无法再获得做操作的。
https://segmentfault.com/a/1190000016566788
这个讲得对!!!!
RR级别下防止幻读
MVCC + review机制 + 锁
可重复读
串行化读
四种级别
https://blog.csdn.net/zzti_erlie/article/details/88080822
锁 + MVCC
实现原理
隔离性
Isolation
脏读
侧重表达 读-读
不可重复读
类型
定义???
则是说 读-写,用写来证实读的是鬼影。
RR级别下,Next-Key Lock才能彻底解决幻读
产生幻觉似的情况
幻读
如果没有 隔离 ==》出现的问题
I
Innnodb有很多 log,持久性靠的是 redo log。
redo log
WAL
持久性
Durability
D
特性
事务 Transaction
https://zhuanlan.zhihu.com/p/358813168
行锁是在需要的时候才加上 的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
两阶段锁协议。
临键锁
共享锁
意向锁
自增锁
插入锁
https://blog.csdn.net/Saintyyu/article/details/91269087
参考
事务结束 锁就自动 解除了么???
lock tables table_name read
lock tables table_name write
unlock tables
创建行锁 必须 是 事务!!!
解锁呢???
===》 当前记录行 + 锁 && 对查询范围空间的数据 + 间隙锁(gap lock) ==> 阻止了幻读
当前读
Mysql==>朋
https://blog.csdn.net/marco__/article/details/95939503
ACID
事务
读到事务未提交的数据
未提交读
能够避免上一种 情况
读到 事务提交 但是未结束的 数据
提交读
本次事务内读取数据的一致性
避免了 上一种问题
存在幻读
MVCC + readview
undo log 就是 版本记录 多个undolog 就是数据的版本链(历史记录)
这个过程涉及 了 锁、wal、多版本、review 等
记录取数据时版本,
修改时版本+1
提交时 对比版本
数据版本实现
提交版本 > 数据库版本 ==》 成功; 反之则,失败
乐观锁
增删改
排它锁
包含
实现
悲观锁
可读不可写,想写须释放完
select * from table lock in share mode
共享锁(读锁)
注意: 其它应该是可以读的
select * from table for update
给一行数据进行加锁
快照读
行锁???
在索引上!!!
锁位置
record lock(记录锁)
在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。gap lock的机制主要是解决可重复读模式下的幻读问题。
gap lock(间隙锁)
next-key lock
优势是不加锁,并发性高。缺点是不是实时数据
mvcc
优势是获取实时数据,但是需要加锁。
next-key
mysql 两种事务隔离技术
锁的实现
如何实现的呢
MVCC + 锁 ===》实现
可以重复读取数据,不受其他事务(增删改)影响
key: 前后两次 范围内 筛选,不同结果
https://www.jianshu.com/p/77a1cd3187b6
幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。
避免 上述问题
序列化操作(读、写 都是 串行化执行)
序列化读
四种隔离级别
MySQL 锁、隔离级别 、MVCC 实现三者关系
参考:https://segmentfault.com/a/1190000012469586
UPDATE products SET quantity = '1' WHERE id=3 AND quantity > 0;update更新语句会把并发串行化
beginTranse(开启事务)try{ //quantity为请求减掉的库存数量 $dbca->query('update s_store set amount = amount - quantity where amount>=quantity and postID = 12345');}catch($e Exception){ rollBack(回滚)}commit(提交事务)
数据库防止库存超卖问题:
场景
https://zhuanlan.zhihu.com/p/267339165
雇佣表的 各种sql
SQL 书写
关系型数据库
Mongdb
redis
memecached
KV
非关系型数据库
中间件
原理
场景方案
数据库
https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzAwNDA2OTM1Ng==&action=getalbum&album_id=1761987817540206592&scene=173&from_msgid=2453150113&from_itemidx=1&count=3&nolastread=1#wechat_redirect
乐观锁、悲观锁
https://mp.weixin.qq.com/s/6QrQ0TZVqSQq26Rms0_mvA
互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景
高可用
高并发
new self()和new static()的区别只有在继承中才能体现出来,如果没有任何继承,那么这两者是没有区别的。
在继承中,new self()返回的实例是万年不变的,无论谁去调用,都返回同一个类的实例,而new static()则是由调用者决定的。
New self 和 new static 的区别:
语法
引用变量
boolean(布尔型)
integer(整型)
float(浮点型,也称double)
string(字符串型)
标量
哈希表的基本信息
HashTable结构体
保存数据的具体内容
Bucket结构体
哈希表+双向链表实现
hash 是无序的???
arData
为了实现 HashTable 的有序性,PHP 为其增加了一张中间映射表
中间表
https://juejin.cn/post/6844903696988373005
如何理解 有序 二字??
bucket 是数组 有序的
中间表 用来存储 hashTable 索引呗 !!!!
查找过程
数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型
实现原理 PHP7 底层实现
轻易的实现集合、栈、列表、字典等多种数据结构。
当插入一个元素且没有空闲空间时
时机:
移除已被逻辑删除的 Bucket
注意: 因为 Bucket 的下标发生了变动,所以还需要更改每个元素在中间映射表中储存的实际下标值。
后面的bucket 向前移动 ,补足被删除的位置
是
申请原数组两倍的 新数组
迁移 旧数据 ==》新数据
计算新的 映射关系 ===》重建索引
否
判断删除是否阈值
触发自动扩容机制
扩容后再执行插入
扩容
即在删除 value 时只是将 value 的 type 设置为 IS_UNDEF
不会立即删除该元素所在的 Bucket
标志位对该元素进行逻辑删除
删除 数组元素
删除元素达到一定数量 或扩容后都需要重建散列表
遍历 Bucket 数组中的 value,然后重新计算映射值更新到散列表
https://blog.csdn.net/wm31898/article/details/101511106
重建散列表
array(数组)
object(对象)
复合
resource(资源)
NULL
特殊
数据类型
网址
$GLOBALS
$_SERVER
$_REQUEST
$_POST
$_GET
$_FILES
$_ENV
$_COOKIE
$_SESSION
PHP超级全局变量
PHP_OS
PHP_VERSION
TRUE
FALSE
DIRECTORY_SEPARATOR
PATH_SEPARATOR
E_ERROR
E_WARNING
E_PARSE
E_NOTICE
M_PI
... ...
预定义常量
__FILE__
__LINE__
__FUNCTION__
__CLASS__
__METHOD__
_DIR_
_NAMESPACE_
魔术常量
常量
运算符
流程控制
内置函数
回调函数
匿名函数和闭包
函数的应用
预定义数组
数组函数
array_merge与数组相“+”的区别
数组
public
protect
private
类的权限修饰符
封装
单一继承
方法重写
继承
抽象类 abstract
接口 interface
多态
三大特性
__construct
__destruct
__set
__get
__call
__callstatic
__isset
__unset
__sleep
__wakeup
__tostring
__clone
魔术方法
工厂模式
单例模式
注册树模式
适配器模式
观察者模式和策略模式
https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzAwNDA2OTM1Ng==&action=getalbum&album_id=1761987817540206592&scene=173&from_msgid=2453150113&from_itemidx=1&count=3&nolastread=1#wechat_redirect
设计模式
https://www.php.net/manual/zh/language.oop5.object-comparison.php
对象 对比 == ===
面向对象
相关函数
字符串处理
行定位符
单词定界符
选择字符
排除字符
限定符
点号操作符
转义字符
预定义的字符集
括号字符
模式修饰符
字符类型
字符串匹配
字符串替换
字符串分隔
应用场景
贪婪匹配与懒惰匹配
回溯与固态分组
正则表达式
文件处理
COOKIE
SESSION
会话控制
Laravel
TP
CI
常用框架
swoole
PHP7与PHP5的区别
性能提升的原因
PHP7
如何解决PHP内存溢出问题
垃圾回收机制
CGI
FastCGI
PHP-FPM
PHP的运行原理
常用配置项
PHP
基础
基础数据类型
高级语法
SplDoublyLinkedLIst
双向链表
SplStack
栈
SplQueue
队列
SplHeap
堆
SplMaxHeap
大根堆
SplMinHeap
小根堆
SplPriorityQueue
优先级队列
SplFixedArray
固定数组
SplSorageObject
对象存储
wiki
数据结构
a collection of interfaces and classes that are meant to solve standard problems
使用 object 模仿 array行为 的 interface、 class
1、定义
current()
key()
next()
rewind()
valid()
function
https://www.ruanyifeng.com/blog/2008/07/php_spl_notes.html
可以在 foreach 、while中使用
Iterator 迭代器
offsetExists($offset)
offsetGet($offset)
offsetUnset($offset)
ArrayAccess
IteratorAggregate
getChildren()
hasChildren()
RecursiveIterator
seek()
SeekableIterator
interface
<?php// a simple foreach() to traverse the SPL class namesforeach(spl_classes() as $key=>$value) { echo $key.' -> '.$value.'<br />'; }?>
查看所有的内置类,可以使用下面的代码
foreach、while
实现了 哪些迭代的接口
DirectoryIterator
Array转化为object
ArrayObject
对ArrayObject类的补充,为后者提供遍历功能
ArrayIterator
RecursiveArrayIterator
RecursiveIteratorIterator
FilterIterator
SimpleXMLIterator
CachingIterator
SplFileObject
class
so ==>
当前类实现了哪个接口
class_implements()
查看某个类对象的父类
class_parents()
当前类对象所使用的 trait 特性信息
class_uses()
类的哈希
spl_object_hash(new TestA)
对象的 ID
spl_object_id()
类的继承、接口、特性查看
所有SPL 可使用 类
spl_classes()
类相关函数
iterator_to_array()
iterator_count($iterator)
array_wlack ???
通过一个指定的回调函数来遍历一个迭代器
iterator_apply()
迭代器相关的函数
相当于是多个 __autoload() 的功能
维护了一个自动加载方法的队列
spl_autoload_register()
获取 目前自动加载的 类 or 方法列表
spl_autoload_functions()
spl_autoload_unregister
深入学习Composer原理
https://zhuanlan.zhihu.com/p/426015371
应用方向 Composer
自动加载相关函数
SPL
高级语法 && 数据结构 && SPL
文件加锁 解锁 ==》 代码实现
curl
Tcp
Udp
socket更底层,类似于C语言的socket接口
使用起来比较麻烦。
必须安装socket扩展
是可以设置很多socket选项
优点:
socket
HTTP 上下文是为 PHP 内建的标准 I/O 接口准备
在 socket 基础上分装的
PHP自带的接口,无需安装任何扩展
使用非常简单
fread
fwrite
过滤器
streamWrapper
SSL加密等
stream相关的函数
stream_socket_server 创建的socket属于stream类型
socket_set_option设置stream_socket的socket选项了。
转换成底层sockets
===》
socket_import_stream
很多socket选项无法精确设置
缺点:
stream
http://www.blogdaren.com/post-2373.html
答案参考wiki
stream socket 扩展异同
https://www.processon.com/view/5e5f242fe4b0f8585546e105?fromnew=1
1、@
2、error_reporting(0);
3、display_errors -->php.ini
4、try catch
5、set_expetion_handler
6、set_error_handler
屏蔽PHP错误
PHP错误异常与处理
错误处理
程序启动,Zend引擎和核心组件初始化
moudle_init
request_init
PHP 代码 => Token => 抽象语法树 (AST)=> Opcodes => 执行
执行过程
excute
request_down
module_down
程序关闭
5个步骤
1、2、6、7 整个生命周期中只会执行一次
3、4、5 会在每次 request 生命周期内重复执行
SAPI生命周期
1~7 只执行一次
CGI/CLI模式
不同类型下 上述步骤执行不同
https://segmentfault.com/a/1190000015453391
生命周期
给扩展封装的,封装了对系统内存的请求
emalloc efee
接口层
程序员代码 交互
通过 zendMM 与 程序员代码 交互
free_bucket
large_free_bucket
rest_buckets
三种类型表
==》 皆为 hashtable
包含:全局符号表、局部符号表、常量表、函数表 --》zendmm_heap
堆层
跟系统内存交互;对 堆层屏蔽 系统操作。
mmap、malloc、free
存储层
三层次
https://www.jianshu.com/p/63a381a7f70c
内存分配机制
1、引用计数 计数为 0
2、离开变量的作用域---》会被自动清除(不包含静态变量)
--》 当refcount 为0 的时候就会回收垃圾。
现在发现的 所有垃圾回收都是 先 标记,后回收,并不是 马上清除,可能是考虑性能吧,可能会定时吧
==》归还 给 zendMM ;由其处理,归还操作系统 or 存放 bucket 、fastcache 中重复利用。
php 5.3 以前 简单引用计数
(https://blog.csdn.net/ty_hf/article/details/52906258)
zval 相关两个属性:isref refcount
分析第3种情况: 第3种情况的zval 放入(应该是减完之后的zval)一个节点( root)缓存区(root buffer)&& 标记紫色 && 且 在 缓存区只出现一次。==》缓存区满(10000个)--》GC判断 ==》 缓存区啥数据结构 ==》 双向链表==》 GC 操作: 对 每一个zval 进行深度遍历(每个zval 本身可能是链表、树啊)&& (zval 节点中包含的zval 都减1 ) && 标记灰色==> 再次 以 深度优先 判断节点中zval 中refcount 值 ==》a(if 0 && 标记白色)b (if !0 recount +1 ??? (对非垃圾还原) && 黑色)===》 遍历 zval 节点,将上一步,标记白色的zval 释放掉。
新算法: 三个准则: 1、 refcount 在增长 不处理,说明在使用 2、refcount 减少0 -》释放, 3、减少不为0 -》不释放,可能为垃圾 ==>需要判断
同步算法 --》还是基于引用计数法
5.3 之后引入复杂的算法,解决 循环引用导致内存泄露问题。
a、引用计数
3、5.3 循环引用 会内存泄露, 5.3后新的算法
(http://niliu.me/articles/1261.html) (- ~5.3) [5.3 ~7.0) [7.0 ~
历史角度 看 php gc 发展过程
php 内存回收机制
内存
GC
线程安全
PHP 源码的 /TSRM 目录下,调用随处可见,通常,我们称之为 TSRM 层
Win32 下的 Apache 来说,是基于多线程的,所以这个层在 Win32 下总是被开启的。
线程安全资源管理器(Thread Safe Resource Manager)
tsrm_tls_entry
tsrm_resource_type
线程之间共享的存在于进程的内存空间的全局变量
https://segmentfault.com/a/1190000010004035
TSRM??? 没看懂的这块什么鬼???
非线程安全版存在的意义就是Linux里很少用多线程模型所以不需要线程安全。
https://www.zhihu.com/question/36734873
进程&线程模型
编译
https://www.processon.com/view/5d08852ee4b0376de9bc407d?fromnew=1
https://www.processon.com/view/5e5b78c6e4b03627650b89df?fromnew=1
PHP 7底层设计与源码实现
7
8
php新特性
语言
Yii
https://www.processon.com/view/5f98cd96e401fd6f36652370?fromnew=1
https://www.processon.com/view/5876fa44e4b0de31f00c970f?fromnew=1
https://www.processon.com/view/5733e032e4b0c102ad204779?fromnew=1
https://www.processon.com/view/5b29c5c8e4b06df80ab46eaf?fromnew=1
laravel 生命周期
https://www.processon.com/view/57ad3864e4b0f39769da5b45?fromnew=1
DB
https://www.processon.com/view/58640aa6e4b049e79ed0fb74?fromnew=1
https://www.processon.com/view/5878a85ee4b0de31f0260e66?fromnew=1
https://www.processon.com/view/56736b09e4b0b315aefb62d4?fromnew=1
框架
Facdes
框架特性
https://mp.weixin.qq.com/s/WpRSitDqtgOuU9GnI1-HDw
IOC
https://mp.weixin.qq.com/s/NXZp8a3n-ssnC6Y1Hy9lzw
AOP
https://mp.weixin.qq.com/s/IglQITCkmx7Lpz60QOW7HA
事务传播
workerman
常驻内存类型框架
MVC
composer
github & packagist
annotation
di
Route
写一个框架注意的点
phpinfo();
get_loaded_extensions()
extension_loaded(\"redis\");
php -m
extension=要开启的扩展名称
PHP配置文件php.ini
安装
yaf
phalcon
Swoole
扩展
包管理
并发编程总结
php 并发编程
API设计
php 安全
单例
工厂
简单工厂
抽象工厂
建造者模式
桥接模式
代理模式
装饰器模式
策略模式
观察者模式
责任链模式
命令行模式
web socket
机械、电气、功能与规程的特性
基于 0 1 0 1 的传输
物理层
ISO1745--1975
每个设备一个 UUID
基于mac 的 帧
IP
ICMP
ARP 、RARP
链路层 data link layer
三次握手、四次挥手
TCP
UDP
传输层
FTP
DNS
Telent
SMTP
NFS
SNMP
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
CODE码
状态码、1XX,2XX 3XX 4XX 5XX
方法 get post delete
http的keep-alive 作用: 保持tcp 连接 防止, http、tcp 连接断开
HTTP1
HTTPS
HTTP2
HTTP3
https://mp.weixin.qq.com/s/AK1Pb9rx0q5Hf8dq6HNOhw
HTTP
http https 异同
应用层
地址 + 封包
本质
网络协议
LVS
网关
网络
无状态模式
broker向发心跳顺便带上所有的Topic信息
早期是zk后来改了
NameServer
中转消息,消息持久化
底层通信基于Netty
Broker
同步
异步
单向
Producer
pull
push
Consumer
基础组成
多master
多master多slave异步复制
多master多slave双写
支持集群模式
发送成功后返回consume_success
回溯消费
消费保证
NameService 集群
Broker 主从 双主 双从
Consumer 自动切换
producer 链接两个Broker
集群
同步 超时会返回错误
异步 不返回
刷盘
同步复制
异步复制
消息的主从复制
主从同步 异步刷盘
消费者是多线程
顺序发送 顺序消费由 消费者保证
RocketMQ提供了MessageQueueSelector队列选择机制
Hash取模
顺序消息
幂等
消息表主键冲突
去重
消息去重
消息表 不断轮训 人工干预
最大努力
发送半消息 发送成功 本地事务 觉得是否提交还是回滚 服务端没收到回查 检查本地事务 根据本地事务决定 提交
半消息
2/3pc
预发 持久化 返回状态 发送处理结果 判断是否干掉持久化的 发送
最终一致
分布式事务
producer 和NameService 节点建立一个长连接
定期从NameService获取Topic信息
并且向Broker Master 建立链接 发送心跳
发送消息给 Broker Master
consumer 从 Mater 和 Slave 一起订阅消息
完整的一个调用链路
不断重试 16次 4小时46分钟 可以修改尝试次数
对一个消费者设置 组内都会设置
可以获取消息重试次数
顺序消息重试
无序消息重试
消息重试
不再被正常消费
保存3天
面向消费者组
控制台 重发 重写消费者 单独消费
死信队列
事务消息
消息丢失
决定是否丢弃
判断吞吐量
停止消费 加机器 加topic
消息积压
RocketMQ
https://zhuanlan.zhihu.com/p/70123414
https://blog.csdn.net/wqc19920906/article/details/82193316
https://note.dolyw.com/mq/00-MQ-Select.html#_6-对比
MQ 选择对比
https://developer.aliyun.com/article/769883
https://cloud.tencent.com/developer/article/1816305
必知必会 RabbitMQ面试题 33道
https://www.processon.com/view/5fc0a588e0b34d3ef4953912?fromnew=1
底层原理
https://blog.csdn.net/fakerswe/article/details/81455340
就是把交换机(Exchange)里的消息发送给所有绑定该交换机的队列,忽略routingKey
RabbitMQ消息模型的核心思想(core idea): 生产者会把消息发送给RabbitMQ的交换中心(Exchange),Exchange的一侧是生产者,另一侧则是一个或多个队列,由Exchange决定一条消息的生命周期–发送给某些队列,或者直接丢弃掉。
广播
https://blog.csdn.net/lzx1991610/article/details/102970854
RabbitMQ使用教程(超详细)
RabbitMQ
基于kafka 设计的
https://zhuanlan.zhihu.com/p/75710822
RabbitMQ延时队列
https://juejin.cn/post/6844904150703013901
6种 延时队列的实现方案
延迟队列
MQ
RPC
两阶段
三提交TCC
选举机制
过半机制
预提交 ack 2pc
ZAB协议?
zk节点宕机如何处理?
如何实现分布式一致性
https://mp.weixin.qq.com/s/gphDLJMO3QcRoN3zkco4EA
https://github.com/AobingJava/JavaFamily
Zookeeper
羊群效应
临时节点顺序
性能没redis高
性能比较高
Redis
设置一个失效时间用定时任务去跑
数据库集群 主备同步
搞个死循环排队
可重入设计一个字段累加
用数据库自身的锁就可以了 行锁 索引
select XX for update
记得 提交
宕机数据库也会自动释放锁
比其他的更消耗资源
复杂
缺点
互斥
安全性
容错
特点
分布式锁
分布式
缓存穿透缓存击穿缓存雪崩缓存预热缓存更新缓存降级缓存穿透
https://cloud.tencent.com/developer/article/1666384
O(n)
1024 个fd
select
没有最大连接数的限制,原因是它是基于链表来存储的
poll
O(1)
是事件驱动(每个事件关联上fd)的
理解为event poll
epoll
就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
IO 多路复用
进程管理与调度算法
零拷贝& mmap
String
set
score
只需要调整前后节点指针
随机层数
还会比较value
不止比较score
成绩
积分
排行榜
zset
分页的坑
List
速度快。占用空间小
海量数据的计算
记录访问uv
比如每个页面的UV
计算UV 适量
基数个数计算
HyperLogLog
https://www.jianshu.com/p/81bf3baa64e5
Geo
https://blog.csdn.net/qq_41125219/article/details/120299819
已经被抛弃了。。。。
Pub/Sub
不光需要记录数据,还需要对数据进行验证的时候使用Bitmaps。
二值计算的场景
https://blog.csdn.net/u011957758/article/details/74783347
BitMap
SDS
双端链表
ziplist
最底层数据结构
键值的底层都是SDS
AOF缓存区
记录本身长度 C需要遍历
空间预支配
惰性空间释放
修改字符减少内存重新分配
C只能保存文本数据 无法保存图片等二进制数据
sds是使用长度去判断
二进制安全
杜绝缓冲区溢出
兼容部分C字符串函数
保存多个客户端的状态信息
列表订阅发布 慢查询 监视器
链表
数据库 哈希键
Hash表节点
hash冲突用单向链表解决
会逐渐rehash 新的键值对全部放到新的hash表
渐进式 rehash
一个平时用 一个rehash时候用
每个字典带 两个hash表
字典
压缩列表
整数集合
底层
https://blog.csdn.net/weixin_30016593/article/details/115502002?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.highlightwordscore&spm=1001.2101.3001.4242.1
与memcahe 对比
Keys
setnx
exprie
5分钟一次
冷备
恢复的时候比较快
快照文件生成时间久,消耗cpu
RDB
appendOnly
数据齐全
回复慢文件大
AOF
从节点发送命令主节点做bgsave同时开启buffer
数据初始化
持久化
offset
指令流
主从同步
缓冲区
快照同步
数据同步机制
集群监控
消息通知
故障转移
配置中心
脑裂
哨兵
横向扩容
多主
分片
加随机值
集群部署
==》众多流量 同时 ==》直接打到后端DB
很多key 在同一时刻 失效
==》减少同时失效的概率
过期时间,设置一定范围的随机时间,离散 过期点
降级
解决方案:
缓存雪崩
互斥锁
热点数据不失效
key 存在 && 过期时间边界==》大量请求--》直接打到后端DB
==>来设置一个短期key 锁 && 访问结束 删除锁
使用setnx (set if not exists)
缓存击穿
1、空值存入redis && 过期时间很短
(需要懂布隆姆算法原理)
==》不存在的key 直接被过滤掉
2、布隆姆过滤器==》bitmap
缓存穿透
延时双删
双写一致性
并发竞争
bigkey命令 找到干掉
Redis 4.0引入了memory usage命令和lazyfree机制
造成集群数据量倾斜
value 太大 比如几百兆 or 1G ==>导致网络问题;
1、业务上更小业务单元,就是拆分
2、删除大key 使用 unlink(会另起一个线程执行)
大Key
缓存时间不失效
多级缓存
布隆过滤器
读写分离
缓存集群中的某个key瞬间被数万甚至十万的并发请求打爆
1、分散成多个子key;数据备份其他节点,业务逻辑层做负载均衡
2、限流熔断保护
3、客户端缓存数据&&设置失效时间
热点key
常见问题
创建一个定时器
消耗内存
定时删除
可能存在大量key
读取的时候--》判断是否过期;过期则删除
惰性删除
检查 删除 但是是随机的
每隔时间,遍历数据库==》删除
定期删除
惰性 + 定期删除 ==》配合使用==>很好平衡 CPU 和内存
redis 方案:
过期策略
最少使用
LUR
noeviction: 不足时,报错 ==>默认策略 allkeys-lru :键空间,移除最近最少使用key allkeys-random: 键空间,随机删除 某个key volatile-lru:键空间中设置了过期的,删除最近最少使用key volatile-random: 在设置了过期的键空间,随机删除key volatile-ttl: 设置了过期时间的键空间中,更早过期的key 优先删除
6种具体策略
获取策略配置: config get maxmemory-policy
内存不足--》怎么淘汰内存,以获取新的内存空间给新的key
淘汰机制
主从+哨兵+cluster
ecache+Hystrix+降级+熔断+隔离
备用方案
rdb
aof
一般二者结合。rdb (每隔 10分钟备份) + aof (aof fsync 方式)
开始标志:MULTI 结束标志:EXEC
WATCH、DISCARD(取消事务)
setnx ex
窗口滑动
zset会越来越大
定时push
然后leftpop
重试
空连接异常
blpop
空轮训
问题
令牌
Redis-Cell
原子性有问题
make_space 灌水之前调用漏水 腾出空间 取决于流水速率
漏桶 funnel
redis cell
限流
二级缓存
备份热key 走不同的机器
选择方案
跳跃表
漏桶
scan
read得读到很多才返回 为0会卡在那 直到新数据来或者链接关闭
写不会阻塞除非缓冲区满了
非阻塞的IO 提供了一个选项 no_blocking 读写都不会阻塞 读多少写多少 取决于内核的套接字字节分配
非阻塞IO也有问题 线程要读数据 读了一点就返回了 线程什么时候知道继续读?写一样
一般都是select解决 但是性能低 现在都是epoll
多路IO复用
单机模式、主从模式、哨兵模式、集群模式
redis 部署模式
https://zhuanlan.zhihu.com/p/76294773https://blog.csdn.net/liu_dong_java/article/details/103411144?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
$value = md5($processid . time()); // 钥匙 不存在则设置 set key value px 1000 nx //毫秒 set key value ex 1000 nx // 秒 setnx key timeout value
a、获取锁
b、业务 :需要在 限定时间完成,否则锁失效,
if (uniquekey == GET(key)) { del key; }
===> 需要 保证这两个 操作是 原子的。都在redis 单线程内执行。===》引入 lua 脚本(redis 支持的)
c 、解锁:
实现过程
参考:https://redisbook.readthedocs.io/en/latest/index.html
1. Redis能够胜任存储工作
HGET
HMGET
hash结构
2.1 基本用户数据存储
INCRBY
HINCRBY
2.2 实现计数器
非常棒的平均响应时间(5ms以内)
千万甚至是亿的级别
ZADD sorted:xjjdog:2021-07 55 dog0
zadd
1 介绍返回指定索引区间元素ZRANGE key start stop [WITHSCORES]如果score相同,则按照字典序lexicographical order 排列默认按照score从小到大,如果需要score从大到小排列,使用ZREVRANGE
zrevrange
2.3 排行榜
获取A和B的共同好友
取两个集合的交集
zinterstore
https://segmentfault.com/a/1190000004260261
sinter
2.4 好友关系
>SETBIT online:2021-07-23 3876520333 1>SETBIT online:2021-07-24 3876520333 1>GETBIT online:2021-07-23 38765203331>BITOP AND active online:2021-07-23 online:2021-07-24>GETBIT active 38765203331>DEBUG OBJECT online:2021-07-23Value at:0x7fdfde438bf0 refcount:1 encoding:raw serializedlength:5506446 lru:16410558 lru_seconds_idle:5(0.96s)
bitmap
bitmap包含一串连续的2进制数字,使用1bit来表示真假问题。在bitmap上,可以使用and、or、xor等位操作(bitop)。
2.5 统计活跃用户数
2.6 分布式锁
incr key expire key 1
RRateLimiter limiter = redisson.getRateLimiter(\"xjjdogLimiter\
同样是redisson的RRateLimiter,实现了与guava中类似的分布式限流工具类,使用非常便捷。下面是一个简短的例子:
2.7 分布式限流
rpop
lpush
BRPOP
BLPUSH
阻塞型
list
Redis还有PUB/SUB模式
Redis5.0中,增加了stream类型
2.8 消息队列
GEOADD
坐标之间的距离计算
包含关系计算
附近的人等功能
PostgreSQL的PostGIS
强大的开源方案
2.9 LBS应用
2. Reids应用场景
https://juejin.cn/post/6989108481018036232
redis 除了做统计还能做什么
https://mp.weixin.qq.com/s/UT2JrfpkA5OUC9fJJ_MirQ
文件系统
这个bolg有不少题,可以练一下
top n
占比率等。
分析nginx 日志
awk
任务书写
crontab
查看内存 top 命令等
vim 一些操作
shell 脚本 ==》 这个如果你是高级PHP程序员,应该需要掌握吧
grep 考察
常用命令
5种
进程通信机制
操作系统
顺序查找
二分查找
hash 查找
分块查找
查找
冒泡
选择排序
跟冒泡有点类似
插入排序
希尔排序
3种低级排序
递归
动态规划
快速排序
归并排序
最变态的方法:堆排序
堆排序
3种 高级排序
快排思想解决
堆排序思想解决
topK 问题
排序
广度优先遍历
前序遍历
中序遍历
后序遍历
深度优先遍历
遍历
https://leetcode-cn.com/problems/linked-list-cycle/submissions/
https://zhuanlan.zhihu.com/p/60736361
快慢指针一定会相遇么
线性同余方程 [公式] 是否有解?
快慢指针
LeetCode
算法
Hive
Hdfs
ClickHouse
Hadoop
Flink
大数据
https://zhuanlan.zhihu.com/p/139762008
https://zhuanlan.zhihu.com/p/387891359
https://zhuanlan.zhihu.com/p/353592281
对比 Mysql 、MongoDB、ES
全文索引
https://www.cnblogs.com/wangzhen3798/p/10032898.html
Elasticsearch和MongoDB简要对比
倒排索引
https://www.processon.com/view/5bbf0100e4b0bd4db95e28c5?fromnew=1
知识图谱
https://www.processon.com/view/6162fd805653bb1336d2913d?fromnew=1
ElasticSearch 搜索底层原理图
https://www.processon.com/view/603d9e2d07912913b4f49aec?fromnew=1
redis、es、rocketmq持久化对照
https://www.processon.com/view/607192c5e0b34d78c0143181?fromnew=1
ES基础使用学习
https://blog.csdn.net/weixin_39920403/article/details/110647101
索引 底层数据结构 对比
https://elasticsearch.cn/article/114
sql to ES DSL
ES
MongoDB
PG
Luceue
Kibanna
Logstash
搜索引擎
单体
微服务
网格
Dubbo
服务治理框架
架构演进
Docker && K8s
https://mp.weixin.qq.com/s/KWb3POodisbOEsQVblsoGw
https://mp.weixin.qq.com/s/RRHN8t017ofOvb4nvlCStg
秒杀架构
秒杀
购物车
ID生成
如何设计一个服务框架
下单锁定商品、优惠券、红包等
https://blog.csdn.net/weixin_42405670/article/details/117898352
https://www.processon.com/view/link/5fb362c85653bb29a8f9966f
下单流程下单流程
https://www.processon.com/view/5fbc7a62f346fb4e415b96a4?fromnew=1
电商-订单管理
订单场景
遇到的坑
前端
普罗米修斯
ELK
监测
持续集成&发布等
取舍
评估 产出
需求评审
取舍 & 时间安排
排期
排期&&项目管理
与领导对齐 KPI
得到产出
分配精力
评估项目
对齐领导OKR
owner
友空间
美菜商城
看点
内容中台
问答项目
贝壳
???
个人项目
项目
公司
自我评价&&自我介绍
影响深刻的问题 项目
https://mp.weixin.qq.com/s/RzJkQuMAszkC8jw8hF-k1w
压测
phper
0 条评论
下一页