1.COW机制
Copy On Write 写时复制。变量在写入时才真正复制一份内存进行修改。
具体参考:写时复制COW机制
2. PHP字符串的4种表达方式
- 单引号(效率最高)
- 双引号
- heredoc(类似双引号)
- nowdoc(类似单引号)
具体参考:PHP字符串的4种表达方式
3. 不要用等号去比较浮点数
因为计算机在计算浮点数时,会将浮点数转换为二进制数,难免会造成精度丢失。
4. FALSE的七种情况
0,0.0,false,'','0',[],null
整型0,浮点0.0,布尔false,空字符串,0字符串,空数组,NULL
5. NULL的三种情况
直接赋值为NULL、未定义的变量、unset销毁的变量
6. 运算符
- PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。
- 运算符优先级:递增/递减 > ! > 算术运算符 > 大小比较 > (不)相等比较 > 引用 > 位运算符( ^ ) > 位运算符( | ) > 逻辑与 > 逻辑或 > 三目 > 赋值 > and > xor > or
- 括号可以增加代码可读性
- 递增/递减运算符不影响布尔值
- 递增NULL值为1,递减NULL值没有效果
- 逻辑运算符短路效应:&& 或 || ,当左边部分符合条件是,右边部分将不会执行
7. PHP遍历数组的三种方式
- 使用for循环:只能遍历索引数组
- 使用foreach循环:可以遍历索引和关联数组,会reset()
- 使用while、list()、each()组合循环:可以遍历索引和关联数组,不会reset()
8. include和require区别
- 无论require位置如何,指定文件都将包含到出现require的脚本中。例如,即时require放在计算为假的if语句中,依然会包含指定文件
- 加载过程中,如果未找到文件则include会发出一条警告,而require会发出一个致命错误
- require(include)/require_once(include_once)唯一区别是后者PHP会检查该文件是否已被包含过,如果是则不会再次包含
9. 字符串函数
具体参考:字符串函数
10. 数组函数
具体参考:数组函数
11. 可变函数
如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。
function foo() {
echo "In foo()
\n";
}
$a = 'foo';
$a(); // 等于foo()
12. 正则表达式
- 作用:分割、查找、匹配、替换字符串
- preg_match($pattern, $subject, $match):执行匹配正则表达式,匹配一次,返回pattern的匹配次数
- preg_match_all($pattern, $subject, $match):执行一个全局正则表达式匹配,全局匹配,返回全局匹配的次数
- preg_replace($pattern, $replacement, $subject):执行一个正则表达式的搜索和替换,返回全部结果
- preg_filter($pattern, $replacement, $subject):执行一个正则表达式的搜索和替换,仅仅返回(可能经过转化)与目标匹配的结果
- preg_grep($pattern, $subject):返回给定数组$subject中与$pattern相匹配的元素组成的数组
- preg_split($pattern, $subject):类似explode()函数,通过一个正则表达式分隔字符串
- preg_quote($str):转义正则表达式字符
13.会话控制
- 为什么要使用会话控制技术?因为HTTP协议是无状态的,为了保存用户信息,所以使用会话控制技术。
- Cookie:存储在客户端,不占用服务器资源,但是不安全
- Session:存储在服务端,占用服务器资源,比较安全
- Session是基于Cookie的,用户禁用Cookie也可以使用Session,可以用session_name()、session_id()函数或SID常量传递SessionID (SID在用户开启Cookie时为空,关闭时有值)
...
...
14.文件函数
具体参考:文件函数
15.HTTP协议
特点
HTTP协议是无状态、无连接的;基于B/S模式;通信开销小、简单快速、传输成本低;使用灵活、可使用超文本传输协议;节省传输时间。
工作原理
客户端发送请求给服务器,创建一个TCP连接,指定端口号,默认为80,连接到服务器,服务器监听浏览器请求,一旦监听到客户端请求,分析请求类型后,服务器会向客户端返回状态信息和数据内容。
HTTP请求方法
- GET 请求指定的页面信息,并返回实体主体
- HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
- PUT 从客户端向服务器传送的数据取代指定的文档的内容。
- DELETE 请求服务器删除指定的页面
- CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
- OPTIONS 允许客户端查看服务器的性能
- TRACE 回显服务器收到的请求,主要用于测试或诊断。
HTTP状态码
- 1** 信息,服务器收到请求,需要请求者继续执行操作
- 2** 成功,操作被成功接收并处理
- 3** 重定向,需要进一步的操作以完成请求
- 4** 客户端错误,请求包含语法错误或无法完成请求
- 5** 服务器错误,服务器在处理请求的过程中发生了错误
常见HTTP状态码
- 200 请求成功
- 301 资源(网页等)被永久转移到其它URL
- 404 请求的资源(网页等)不存在
- 500 内部服务器错误
16.OSI七层模型
- 物理层
- 数据链路层
- 网络层
- 传输层:协议有TCP、UDP 数据包一旦离开网卡即进入网络传输层
- 会话层
- 表示层
- 应用层:协议有HTTP、HTTPS、FTP、SMTP、DNS、DHCP
17.Mysql整数类型
TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT
属性:UNSIGNED
长度:可以为整数类型指定宽度,对大多数应用是没有意义的,它不会限制值的合法范围,只会影响显示字符的个数。例如:INT(3):指定该字段为3位,如果不足,则可以为0填充。e.g:001
18.Mysql索引
索引的影响
- 大大减少服务器需要扫描的数据量
- 帮助服务器避免排序和临时表
- 将随机I/O变顺序I/O
- 大大提高查询速度,降低写的速度,占用磁盘
索引的使用场景
- 对于非常小的表,大部分情况下全表扫描效率更高
- 中到大型表,索引有效
- 特大型的表,建立和使用索引的代价将随之增长,可以使用分区技术来解决
索引的类型
- 普通索引:最基本的索引,没有任何约束限制
- 唯一索引:与普通索引类似,但是具有唯一性约束
- 主键索引:特殊的唯一索引,不允许有空值
- 组合索引:将多个列组合在一起创建索引,可以覆盖多个列
- 外键索引:只有InnoDB类型的表才可以使用外键索引,保证数据的一致性,完整性和实现级联操作
- 全文检索:Mysql自带的全文索引只能用去MyISAM,并且只能对英文进行全文检索
注意
- 复合索引遵循前缀原则
- like查询,%不能在前,否则索引失效,可以使用全文索引解决
- 如果or前的条件中的列有索引,后面的没有,则索引不会被用到
- 列类型是字符串,查询时一定要给值加引号,否则索引失效
19.关联查询
六种关联查询
- 交叉连接(CROSS JOIN)
SELECT * FROM A,B(,C)
SELECT * FROM A CROSS JOIN B (CROSS JOIN C)
- 内连接(INNER JOIN)
SELECT * FROM A,B WHERE A.id=B.id
SELECT * FROM A INNER JOIN B ON A.id=B.id
- 外连接(LEFT JOIN/RIGHT JOIN)
- 联合查询(UNION与UNINO ALL)
- 全连接(FULL JOIN):Mysql不支持全连接,可以使用LEFT JOIN 和 RIGHT JOIN 联合使用
SELECT * FROM A LEFT JOIN B ON A.id=B.id UNION SELECT * FROM A RIGHT JOIN B ON A。id=B.id
20.Mysql查询优化
查找分析查询速度慢的原因
- 记录慢查询日志,可以使用pt-query-digest工具分析
- 使用show profile。set profile=1;开启,服务器上执行的所有语句会检测消耗的时间,存到临时表中
- show status:返回一些计数器,show global status查看服务器级别的所有计数
- show processlist:观察是否有大量线程处于不正常的状态或特征
- explain:分析单条SQL语句
21.Mysql分表和分区
分区
适用场景
- 表非常大,无法全部存在内存,或者只在表的最后有热点数据,其他都是历史数据
- 分区表的数据更易维护,可以对独立的分区进行独立的操作
- 分区表的数据可以分布在不同的机器上,从而高效使用资源
- 可以备份和恢复独立的分区
缺点
- 一个表最多只有1024个分区
- 分区字段中如果有主键和唯一索引列,那么主键列和唯一列都必须包含进来
- 分区表无法使用外键约束
- 所有分区必须使用相同的存储引擎
分表:垂直分表/水平分表
22.高并发和大流量解决方案
相关概念
- 高并发:通常一个系统的日PV在千万以上,有可能是一个高并发的系统
- PV:Page View 综合浏览量,即页面浏览量或点击量。同一个人浏览网站同一个页面,只记作一次PV
- UV:独立访客(Unique Visitor),即一定时间范围呢相同的访客多次访问网站,只计算一个独立访客
- QPS:每秒钟请求的查询数量,在互联网领域,指每秒响应请求数(HTTP请求)
- 吞吐量:单位时间内处理的请求数量(通常由QPS与并发数决定)
- 响应时间:从请求发出到收到相应花费的时间。例如系统处理一个HTTP请求需要100ms,100ms就是响应时间
- 日网站带宽=PV / 统计时间(s)*平均页面大小(KB)*8
- 峰值每秒请求数(QPS)=(总PV数*80%)/(6小时秒数*20%) 80%的访问量集中在20%的时间
- 压力测试:测试能承受的最大并发,QPS值 使用ab等压力工具
解决方案
- 流量优化:防盗链处理
- 前端优化:减少HTTP请求、添加异步请求、启用浏览器缓存和文件压缩、CDN加速、建立独立图片服务器
- 服务端优化:页面静态化、并发处理
- 数据库优化:数据库缓存、分库分表、分区、读写分离、负载均衡
- web服务器优化:负载均衡
23.流量优化——web资源防盗链
相关概念
- 盗链:在自己的页面上展示一些不在自己服务器的内容。获得他人服务器上的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容。
- 防盗链:防止别人通过一些技术手段绕过本站的资源展示页面,盗用本站的资源,让绕开本站资源展示页面的资源链接失效。
- 防盗链工作原理:通过Referer或者签名,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。一旦检测来源不是本站即进行阻止或者返回指定的页面。
解决方案
Rererer
Nginx模块ngx_http_referer_module用于阻挡来源非法的签名请求。
Nginx指令valid_referers,全局变量$invalid_referer
valid_referers none | blocked | server_names | string ... ;
none:"Rerferer"来源头部为空的情况
blocked:"Referer"来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值不已http://或https://开头
server_names:"Referer"来源头部包含当前的server_names,允许列表
加密签名
使用第三方模块HttpAccessKeyModule实现
accesskey on | off 模块开关
accesskey_hashmethod md5 | sha-1 签名加密方式
asccesskey_arg GET参数名称
accesskey_signature 加密规则
24.前端优化——减少HTTP请求
相关概念
- 性能黄金法则:只有10%-20%的最终用户响应时间花在接收请求的HTML文档上,剩下的80%-90%的时间花在HTML文档所引用的所有组件(图片、script、css、flash等等)进行的HTTP请求上
- HTTP连接产生的开销:域名解析——TCP连接——发送请求——等待——下载资源——解析时间
解决方案
改善响应时间的最简单途径就是减少组件的数量,并由此减少HTTP请求的数量
- 图片地图:允许在一个图片上关联多个URL,目标URL的选择取决于用户单击了图片上的哪个位置。使用
- CSS精灵:CSS Sprites,通过使用合并图片,通过指定css的backgroud-image和backgroud-position来显示元素
- 合并脚本和样式表
- 图片使用Base64编码减少页面请求数:采用Base64的编码方式将图片直接嵌入到网页中,而不是从外部载入
25.前端优化——启用浏览器缓存和数据压缩
相关概念
缓存分类
- 200 from cache:本地缓存,直接从本地缓存中获取相应,最快速,最省流量,没有向服务器发送请求
- 304 Not Modified:协商缓存,浏览器在本地没有命中的情况下,请求头中发送一定的校验数据到服务端,如果服务端没有改变,浏览器从本地缓存相应,返回304。快速,发送数据少,只返回一些基本的响应头信息,数据量很小,不发送实际相应体
本地缓存相关Header
Cache-Control:HTTP1.1,告知浏览器缓存过期的时间间隔,而不是时刻。
- no-store:禁止浏览器缓存相应
- no-cache:不允许直接使用本地缓存,先发起请求和服务器协商
- max-age = delta-seconds:告知浏览器该相应本地缓存有效的最长期限,以秒为单位
协商缓存相关Header
- Last-Modified:通知浏览器资源的最后修改时间
- If-Modified-Since:得到资源的修改时间后,会将这个信息通过If-Modified-Since提交到服务器做检查,如果没有修改,返回304
- ETag:HTTP1.1,文件指纹标识符,如果文件内容修改,指纹会改变
- If-None-Match:本地缓存失效,会携带此值去请求服务端,服务端判断该资源是否改变,如果没有改变,直接使用本地缓存,返回304
适合本地缓存的内容(长期不变)
- 不变的图像,如LOGO,图标
- js、css静态文件
- 可下载的内容,媒体文件
适合协商缓存的内容(经常改变)
- HTML文件
- 经常替换的图片
- 经常修改的js、css文件。可以加入文件签名来拒绝缓存(index.css?签名、index.签名.js)
不建议缓存的内容
解决方案
Nginx
本地缓存配置
expires指令:通知浏览器过期时长
expires time; time为负值时表示Cache-Control:no-cache; 为正值或0时,表示Cache-Control:max-age=指定时间
协商缓存配置
Etag:指定签名 etag on | off; 默认是on
资源压缩
gzip
26.前端优化——CDN加速
相关概念
CDN:Content Delivery Network,即内容分发网络,尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络。
工作原理:用户发起请求-->智能DNS的解析(根据IP判断地理位置、接入网类型、选择路由最短和负载最轻的服务器)-->取得缓存服务器IP-->把内容返回给用户(如果缓存中有内容)-->(如果缓存中没有内容)向源站发起请求-->将结果返回给用户-->将结果存入缓存服务器
适用场景:站点或者应用中大量静态资源的加速分发,如html、css、js、图片;大文件下载;直播网站
实现:BAT提供的CDN服务;可以使用LVS做4层负载均衡
27.前端优化——独立图片服务器的部署
相关概念
- 独立的必要性:分担Web服务器的I/O负载,将耗费资源的图片服务分离出来,提高服务器的性能和稳定性
- 采用独立域名;同一域名下浏览器的并发连接数有限制,为了突破浏览器连接数的限制
28.服务端优化——动态语言静态化
相关概念
- 动态语言静态化:将现有PHP等动态语言的逻辑代码生成为静态HTML文件,用户访问动态脚本重定向到静态HTML文件的过程
- 原因:动态脚本通常会做逻辑计算和数据查询,访问量越大,服务器压力越大,访问量大时可能造成CPU负载过高,数据库服务器压力过大,静态化可以减低逻辑处理压力,降低数据库服务器查询压力
解决方案
ob_start():打开输出控制缓冲
ob_get_contents():返回输出缓冲区内容
ob_clean():清空输出缓冲区
ob_end_flush():冲刷出输出缓冲区内容并关闭缓冲
29.服务端优化——动态语言的并发处理
相关概念
进程
Process,是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。进程是一个“执行中的程序”。
进程的三态模型:多道程序系统中,进程在处理器上交替运行,状态不断地发生变化
- 运行:当一个进程在处理机上运行时,则称该进程处于运行状态。处于此状态的进程数目小于此处理器的数目,对于单处理机系统,处于运行状态的进程只有一个。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程
- 就绪:当一个进程获得了除处理机以外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程有I/O操作完成而进入就绪状态时,排入高优先级队列
- 阻塞:也称为等待或睡眠状态,一个进程正在等待某一件事发生(例如请求I/0而等待I/O完成等)而暂时停止运行,这时即时把处理机分配给进程也无法进行,故称该进程处于阻塞状态。
进程的五态模型:对于一个实际的系统,进程的状态及其转换更为复杂
新建态、活跃就绪/静止就绪、运行、活跃阻塞/静止阻塞、终止态
- 新建态:对应与进程刚刚被创建时没有被提交的状态,并等待系统完成创建进程的所有必要信息
- 终止态:进程已结束运行,回收除进程控制块之外的其他资源,并让其他进程从进程控制块中收集有关信息。
- 活跃就绪:指进程在主存并且可被调度的状态
- 静止就绪(挂机就绪):是指进程被对换到辅存时的就绪状态,是不能被直接调度的状态,只有当主存中没有活跃就绪态进程,或者挂起就绪态进程具有更高的优先级,系统将把挂起就绪态进程调回主存并转换为活跃就绪
- 活跃阻塞:指进程已在主存,一旦等待的时间产生便进入活跃就绪状态
- 静止阻塞:进程对换到辅存时的阻塞状态,一旦等待的时间产生便进入就绪状态
线程
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源
线程三状态:就绪、运行、阻塞
协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制
线程与进程程的区别
- 线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有自己独立的地址空间
- 进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
- 线程是处理器调度的基本单位,但进程不是
- 二者均可并发执行
- 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
线程与协程的区别
- 一个线程可以拥有多个协程,一个进程也可以单独拥有多个协程
- 线程进程都是同步机制,协程是异步
- 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态
多进程
同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态,这就是多进程
多线程
线程就是把一个进程分为很多片,每一片都可以使一个独立的流程。在单个程序中同时运行多个线程完成不同的工作。与多进程的区别是只会使用一个进程的资源,线程间可以直接通信
同步阻塞
异步非阻塞
PHP并发编程实践
- PHPSwoole扩展
- 消息队列
- 接口并发请求:curl_multi_init
30.数据库优化——数据库缓存
相关概念
mysql查询缓存
查询缓存可以看做是SQL文本和查询结果的映射,第二次查询的SQL和第一次查询的SQL完全相同时,则会使用缓存
query_cache_type 查询缓存类型:
- 0:不用查询缓存
- 1:始终使用查询缓存,也可以关闭查询缓存 SELECT SQL_NO_CACHE * FROM WHERE condition;
- 2:按需使用查询缓存 SELECT SQL_CACHE * FROM table_name WHERE condition;
query_cache_size:默认为0,表示查询缓存预留的内存大小,0则无法使用查询缓存
SHOW STATUS LIKE 'Qcache_hits';查看命中次数
FLUSH QUERY CACHE; 清理查询缓存内存碎片
RESET QUERY CACHE; 从查询缓存中移出所有查询
FLUSH TABLES; 关闭所有打开的表,也会清空查询缓存的内容
Memcache缓存
工作原理:先检查客户端的请求数据是否在memcache中,如果有,直接把请求数据返回,不再对数据库进行任何操作;如果没有,则去查询数据库,把从数据库中查询的数据返回客户端,同时缓存一份到memcache中
Redis与Memcache的区别
- 性能相差不大
- Memcache不支持持久化,通常做缓存,提升性能,Redis支持持久化
- Memcache在并发场景下,用cas保持一致性,Redis事务支持比较弱,只能保证事务中的每个操作连续执行
- Redis支持多种类的数据类型
- Redis用于数据量较小的高性能操作和运算上
31.Mysql数据层的优化
- 数据表数据类型的优化
- 索引优化
- SQL语句优化
- 存储引擎优化
- 数据表结构设计优化:分区操作、分库分表
- 数据库服务器架构优化:主从复制、读写分离、双主热备、负载均衡
32.Web服务端优化——负载均衡
七层负载均衡的实现
四层负载均衡的实现