博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php技术汇总
阅读量:3898 次
发布时间:2019-05-23

本文共 7975 字,大约阅读时间需要 26 分钟。

redis优点

  • 1.读写性能优异,读的速度:110000次每秒,写的速度是81000每秒
  • 2.数据持久化,可将内存中的数据拷贝到硬盘,支持RDB和AOF操作
  • 3.事务处理,redis的所有操作都具有原子性,并且支持多个操作合并后的原子性执行
  • 4.支持多种数据结构:无序集合,有序集合,哈希,字符串,列表
  • 5.支持主从复制,主机会自动将数据复制到从机,可以进行读写分离

redis的缺点:

(一)缓存和数据库双写一致性问题:先更新数据库,再删缓存
(二)缓存雪崩问题
(三)缓存击穿问题
(四)缓存的并发竞争问题

redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据

redis缓存清理机制

  • 全局空间键移除策略:
  • 1.清除最少使用的key
  • 2.随机清除key
  • 有效期内的key移除策略:
  • 3.清除最少使用的key
  • 4.清除将要过期的key
  • 5.随机清除key

事务的4个特性

  • 原子性:一个事务包含多个操作,这些操作要么全都执行,要么全都不执行。
  • 隔离性:指并发事务间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据。
  • 持久性:事务提交后,对系统的影响是永久的。
  • 一致性:指事务使得系统从一个一致的状态转换到另一个一致的状态。
    总结:
    原子性:事务操作失败时,回滚。
    一致性:弱一致性时,A改了一个数,B不能立即读取到,这时B也修改了这个数,会导致A改的数被覆盖。多个原子性事务并不能保证一致性。
    隔离性:提交前可读、提交后可读、可重复读、串行化。
    持久性:事务提交后影响是永久的。

mysql优化方案:

  • 1.优化查询语句
  • 2.减少字段宽度,尽量将字段设置为 not null
  • 3.使用索引
  • 4.用join代替子查询
  • 5.避免使用select *
  • 6.事务处理
  • 6.like %A% 不会使用索引,A%会使用索引
  • 7.一个字段数据值有大量相同的字段,不建议建立索引,如:性别
  • 8.char比varChar快

myisam和innodb的区别

  • innoDb:
  • 1.支持事务
  • 2.支持外键
  • 3.不加锁读取
  • 4.不支持全表搜索
  • 5.查询数据总条数时,需全表扫描
  • 6.把数据和索引保存到表空间中
  • 7.跨平台可直接拷贝使用
  • 8.必须包含自动递增
  • 9.表很难被压缩
    *10.支持行级锁
  • myIsAm:
  • 1.不支持事务
  • 2.不支持外键
  • 3.表级锁
  • 4.支持全文索引
  • 5.不带where时,可直接返回表的具体行数
  • 6.表可以被压缩
  • 7.跨平台很难被拷贝
  • 8.表中可以使用自动递增类型字段建立联合索引
  • 9.删除表时, 先drop表,再新建表

php5和php7的区别

PHP7.0 比PHP5.6性能提升了两倍。
PHP7.0全面一致支持64位。
PHP7.0之前出现的致命错误,都改成了抛出异常。
增加了空结合操作符(??)。效果相当于三元运算符。
PHP7.0新增了函数的返回类型声明。
PHP7.0新增了标量类型声明
PHP7.0之后移除了一些老的不再支持的SAPI(服务器端应用编程端口)和扩展。

mysql优化方案:

  • 1.优化查询语句
  • 2.减少字段宽度,尽量将字段设置为 not null
  • 3.使用索引
  • 4.用join代替子查询
  • 5.避免使用select *
  • 6.事务处理
  • 7.使用外键
  • 8.锁定表
  • 9.分段查询
  • 6.like %A% 不会使用索引,A%会使用索引
  • 7.一个字段数据值有大量相同的字段,不建议建立索引,如:性别
  • 8.char比varChar快
  • 优化查询语句:
  • 1.减少使用select *
  • 2.模糊查询时,如不是必须查前后,建议使用name%
  • 3.尽量少使用or,如必须使用,则可以使用union all代替
  • 4.避免在where语句中使用null值判断
  • 5.避免在where子句中对字段进行表达式操作
  • 6.对于联合索引来说,要遵循最左前缀法则,如一个表中有3个索引,id,name,money,当查询id和name时
    ,可以使用索引,但是查询name和money时,就无法使用索引
  • 7.使用force index强制使用某个索引
  • 8.注意范围查询语句,比如where条件中使用了betWeen、<、>等判断符,则后面的索引将不生效
  • 9.join的使用,尽量使用inner join,因为两张表必定有大小之分,使用inner join则自动使用小表驱动
    大表

创建索引的技巧

  1. 维度高的列创建索引。
  2. 数据列中不重复值出现的个数,这个数量越高,维度就越高。
  3. 如数据表中存在8行数据a,b ,c,d,a,b,c,d这个表的维度为4。
  4. 要为维度高的列创建索引,如性别和年龄,那年龄的维度就高于性别。
    性别这样的列不适合创建索引,因为维度过低。
  5. 对 where,on,group by,order by 中出现的列使用索引。
  6. 对较小的数据列使用索引,这样会使索引文件更小,同时内存中也可以装载更多的索引键。
  7. 为较长的字符串使用前缀索引。
  8. 不要过多创建索引,除了增加额外的磁盘空间外,对于DML操作的速度影响很大,因为其每增删改一次就得从新建立索引。
  9. 使用组合索引,可以减少文件索引大小,在使用时速度要优于多个单列索引。

索引使用情况

网页优化方案:

网站访问慢的原因有哪些:
1.服务器负载过大忙不过来,无法承担巨大的流量。
1.DNS解析慢
2.访问量过载
3.网站代码繁琐
4.站点存在大量的JS或者图片的调用
5.服务器出口带宽不够用。
6.数据库的瓶颈,数据库文件过大,造成读取缓慢,没有建立索引,造成每次查询都对数据库进行全局查询。
7.没有设置CDN。
8.可能遭受到了分布式拒绝攻击即DDOS攻击或者中病毒木马。
9.死链:死链接是指残留的网站中不存在的页面,即网站改变前的页面,改动后删除此页面,但是搜索引擎
已经收录了,这样的页面称为死链接,用户通过死链接访问是会出现打不开的现象(就是那些你点开出现404
页面的页面)

怎么优化网站打开速度:

1.查看线上服务器的负载情况,CPU负载,内存负载,网络带宽,查看是否已经过载。
2.查看网络连接情况,是否受到DDOS攻击,消耗尽带宽资源,造成无法提供服务。
3.查看MySQL数据库的日志文件,查看mysql慢查询日志,查看造成MySQL访问过慢的原因。
4.可以查看应用程序的日志,如Apache,nginx,PHP,Tomcat日志文件,找出报错原因,查看是否是代码问题。
5.精简代码 (比如一些常见的死循环,数据库死锁等)
6.优化缓存
7.图片压缩(网站首页出现的图片,在加载过程中很耗时,首页越小越好)
8. 尽量不要放视频和flash,除非你是视频网站

缓存穿透:

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,
这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决办法:1. 对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则
是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个
bitmap拦截掉,从而避免了对底层存储系统的查询压力;2. 缓存空对象. 将 null 变成一个值
缓存空对象会有两个问题:
第一,空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间 ( 如果是攻击,问题更严重 ),
比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。
第二,缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为
5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用
消息系统或者其他方式清除掉缓存层中的空对象。

缓存雪崩

如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。
解决办法:1.尽量让失效时间点均匀分布;2.数据预热;3.做二级缓存,或者双缓存策略。A1为原始缓存,
A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。;

缓存雪崩的事前事中事后的解决方案如下。

事前:redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。
事中:本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死。
事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?走降级!可以返回一些默认的值,或者友情提示,或者空白的值。

缓存击穿

就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,
大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。
解决方式 :也很简单,可以将热点数据设置为永远不过期;或者基于 redis or zookeeper 实现互斥锁,
等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据;

PHP代码优化方案

网站优化方案:

1.HTML静态化
2.图片服务器分离
3.数据库集群、库表散列
4.数据库集群、库表散列
5.镜像
6.负载均衡

PHP优化方案:

1.echo比print要快很多。
2.include_once比include更加耗时。
3.对于长段落的字符串一定要使用单引号,而不是双引号
4.不要再循环中嵌套使用for循环
5. 如果能将函数定义为静态的,那么就不要定义成为成员函数,静态函数比成员函数快33%。
6. 如果你可以不通过正则表达式就能解决问题,那么就别用正则。正则表达式比PHP原生的函数要慢一些。
7. 尽量不要使用相对路径来包含文件
8. 全等符号 == 比相等 == 要快

针对thinkphp 有以下几种方式:

1 . 关闭调试模式
9. 开启页面压缩输出
3.开启缓存
4.字段缓存

数据库优化:

1.选择正确的存储引擎
2.优化字段的数据类型
3.为搜索字段添加索引
4.避免使用Select *从数据库里读出越多的数据,
5.使用 ENUM 而不是 VARCHAR
6.尽可能的使用 NOT NULL
7.固定长度的表会更快
8.垂直分割
9.EXPLAIN 你的 SELECT 查询;

前端优化:

1.PageSpeed 谷歌开发的工具
2.yslow YSlow

介绍一下PHP的垃圾回收机制

1.PHP使用了引用计数(reference counting)GC机制,同时使用根缓冲区机制,当php发现有存在循环引用的zval时,就会把其投入到根缓冲区,当根缓冲区达到配置文件中的指定数量后,就会进行垃圾回收,以此解决循环引用导致的内存泄漏问题。

  1. 如果引用计数减少到零,所在变量容器将被清除(free),不属于垃圾;
  2. 如果一个zval的引用计数减少后还大于0,那么它会进入垃圾周期。其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾。
    每个对象都内含一个引用计数器refcount,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为 NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。

TCP为什么要4次握手?

为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

为什么不能用两次握手进行连接?

答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

laravel框架和Yii2框架的区别:

1、url的访问
laravel框架中,要访问一个控制器,必须先定义其路由,有点麻烦。其底层访问实现是基于路由定义的。
yii2框架则不用,支持pathinfo模式。
这点上,yii2优势更明显。
 
2、中间件的使用
laravel 框架中可以定义中间件,并且很方便的使用中间件,只需要定义中间件和中间组,并在路由中定义好路由使用的中间件即可。
yii2 框架没有中间件的概念,但可以通过使用行为behaviors来实现,比如 Response::FORMAT_JSON
这点上,laravel优势更明显。

3、源码可读性

laravel由于门面模式的使用,使得源码阅读变得困难,有些为了追求优雅而过渡设计
yii2源码阅读很方便,直接跳转即可
这点上,yii2优势更明显。

4、数据库的使用

如果使用习惯了yii2,再使用laravel,会感觉laravel在操作数据库上有很多欠缺。
yii2生成模型文件直接使用gii,很方便,并且在操作数据库方面,使用上也非常易上手,方法名称见名识意
laravel使用起来则要生涩很多,有很多方法都不能做到见名识意,比如sql语句中的limit,在laravel中是take,还有添加where条件也不是很方便。
这点上,yii2优势更明显。

5、文档说明

yii2 中文文档 https://www.yiichina.com/, 页面美观程度与laravel社区https://learnku.com/docs/laravel/ 相比,相差甚多,yii2社区的文字排版稍显凌乱。
这点上,yii2稍逊一筹。

6、社区活跃

因为都是PHP语言的重量级框架,都经过了很多年的洗礼检验以及迭代更新,因此遇到的问题在网上基本都能搜索出来,二者的qq群也都比较活跃。
这一点上二者基本是不相上下的。

TP框架和Laravel框架的区别:

1、提交数据的方式
Laravel在提交表单时需要在表单中加入{csrf_field}来防止跨域攻击,而TP不会。

2、路由

Laravel必须先定义,再使用,路由文件为routes.php;TP在配置文件中开启路由后,路由格式是:‘路由表达式’ => ‘路由地址和参数’(使用路由的前提是URL支持phthinfo并且开启路由),路由可以使URL更符合SEO。

3、渲染模版方式

在Laravel框架里,使用return view()来渲染模版;而ThinkPHP里则使用了$this->display()的方式渲染模版。

4、操作数据库方式

都可以使用实例化(建立相对应的模型类)和DB:table(‘表名’)来操作数据库,使用原生查询时不太相同,Laravel使用Db::操作(‘原生sql’),TP使用Db::query(‘原生sql’)。

5、条件判断语句书写方式

Laravel框架里 if else判断语句和foreach语句 书写时必须以@if开头 以@endif结尾,如果没有则报语法错误,@foreach @endforeach同理。
而TP框架则和PHP语法规则使用方式一致直接ifesle语句判断和foreach循环遍历

6、中间件,Laravel特点,可以实现访问前后的处理,例如请求和返回,权限认证等;

7、Laravel升级十分简易,而TP大版本的升级要重构代码。

介绍一下你工作中用到的设计模式?

设计模式是程序员在设计过程中多年的最佳实践沉淀,可以提高工程师之间研发质量,沟通效率。

1.单例设计模式

所谓单例模式,即在应用程序中最多只有该类的一个实例存在,一旦创建,就会一直存在于内存中!

单例设计模式常应用于数据库类设计,采用单例模式,只连接一次数据库,防止打开多个数据库连接。

一个单例类应具备以下特点:

单例类不能直接实例化创建,而是只能由类本身实例化。因此,要获得这样的限制效果,构造函数必须标记为private,从而防止类被实例化。
需要一个私有静态成员变量来保存类实例和公开一个能访问到实例的公开静态方法。
在PHP中,为了防止他人对单例类实例克隆,通常还为其提供一个空的私有__clone()方法。

工厂设计模式

主要是当操作类的参数变化时,只用改相应的工厂类就可以

工厂设计模式常用于根据输入参数的不同或者应用程序配置的不同来创建一种专门用来实例化并返回其对应的类的实例。

我们举例子,假设矩形、圆都有同样的一个方法,那么我们用基类提供的API来创建实例时,通过传参数来自动创建对应的类的实例,他们都有获取周长和面积的功能。

观察者设计模式

观察者模式是挺常见的一种设计模式,使用得当会给程序带来非常大的便利,使用得不当,会给后来人一种难以维护的想法。
什么是观察者模式?一个对象通过提供方法允许另一个对象即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。观察者模式是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间紧密耦。看下面例子你就明白了!

适配器模式

将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。
应用场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。例如:php连接数据库的方法:mysql,mysqli,pdo,可以用适配器统一

策略模式

将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。
例如:一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有广告位展示不同的广告

装饰器模式

使用场景:当某一功能或方法draw,要满足不同的功能需求时,可以使用装饰器模式;实现方式:在方法的类中建addDecorator(添加装饰器),beforeDraw,afterDraw 3个新方法, 后2个分别放置在要修改的方法draw首尾.然后创建不同的装器类(其中要包含相同的,beforeDraw,afterDraw方法)能过addDecorator添加进去,然后在beforeDraw,afterDraw中循环处理,与观察者模式使用有点相似
1.装饰器模式(Decorator),可以动态地添加修改类的功能
2.一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法
3.使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性
DrawDecorator.php

mysql事务隔离级别对应什么读:

1.读未提交->脏读
2.读已提交->幻读
3.可重复读->
4.串行化->

转载地址:http://zsyen.baihongyu.com/

你可能感兴趣的文章
ubuntu中配置环境变量
查看>>
ubuntu安装weditor
查看>>
Ubuntu安装NVIDIA显卡驱动
查看>>
vue-cli中实现dolist
查看>>
sass的安装
查看>>
Vue-cli中路由配置
查看>>
豆瓣高分JAVA书籍,你都读过吗?
查看>>
java图书管理系统
查看>>
C#图书管理系统
查看>>
C#酒店管理系统
查看>>
你对ArrayList了解多少?
查看>>
《从Paxos到ZooKeeper分布式一致性原理与实践》学习知识导图
查看>>
Java基础面试题(一) (2020持续更新)
查看>>
JAVA人事管理系统
查看>>
Dubbo面试题(关注小R持续更新)
查看>>
JAVA仿微博系统(JAVA毕业设计含源码和运行教程)
查看>>
24BITBMP位图的文件结构及创建
查看>>
如何在自定义控件中获得width和height?
查看>>
Android UI开发专题之界面设计【基础API】
查看>>
ejarmaker: jar 、java类的加密工具
查看>>