php面试

MongoDB和MySQL对比

数据库MongoDBMySQL
数据库模型非关系型关系型
存储方式以类JSON的文档的格式存储不同引擎有不同的存储方式
查询语句MongoDB查询方式(类似JavaScript的函数)SQL语句
数据处理方式基于内存,将热数据存放在物理内存中,从而达到高速读写不同引擎有自己的特点
成熟度新兴数据库,成熟度较低成熟度高
广泛度NoSQL数据库中,比较完善且开源,使用人数在不断增长开源数据库,市场份额不断增长
事务性仅支持单文档事务操作,弱一致性支持事务操作
占用空间占用空间大占用空间小
join操作MongoDB没有joinMySQL支持join

并发防超卖处理方式

乐观锁

MySQL本身不提供乐观锁的功能,需要开发者自己实现。普遍的做法是在表中加一个version列,用来标记数据行的版本,当我们需要更新数据时,必须比对version版本,version一致说明这个期间数据没有被其他事务修改过,否则说明数据已经被其他事务修改,需要重试了。

redis 消息队列

在秒杀的情况下,高频率的去读写数据库,会严重造成性能问题。所以必须借助其他服务, 利用 redis 的单线程预减库存。比如商品有 100 件。那么我在 redis 存储一个 k,v。
例如每一个用户线程进来,key 值就减 1,等减到 0 的时候,全部拒绝剩下的请求。
那么也就是只有 100 个线程会进入到后续操作。所以一定不会出现超卖的现象。

redis 分布式锁
$expire = 10;//有效期10秒

$key = 'lock';//key

$value = time() + $expire;//锁的值 = Unix时间戳 + 锁的有效期

$lock = $redis->setnx($key, $value);

//判断是否上锁成功,成功则执行下步操作

if(!empty($lock))

{

//下单逻辑...

}

PHP的运行模式

CGI协议模式

cgi模式通用网关接口(Common Gateway Interface),它允许web服务器通过特定的协议与应用程序通信,通俗的讲CGI就像是一座桥,把网页和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器执行程序,再把服务器执行程序返回给HTML页。CGI的跨平台性能极佳,几乎可以在任何操作系统上实现。
调用原理大概为:用户请求->Web服务器接收请求->fork子进程 调用程序/执行程序->程序返回内容/程序调用结束->web服务器接收内容->返回给用户,由于每次用户请求,都得fork创建进程调用一次程序,然后销毁进程,所以性能较低。

fast-cgi协议模式

fast-cgi是cgi模式的升级版,它像是一个常驻型的cgi,只要开启后,不会每次都要花费时间去fork一次,就可一直处理请求,不再需要结束进程。
调用原理大概为:web服务器fast-cgi进程管理器初始化->预先fork n个进程用户请求->web服务器接收请求->交给fast-cgi进程管理器->fast-cgi进程管理区接收,给其中一个空闲fast-cgi进程处理->处理完成,fast-cgi进程变为空闲状态,等待下次请求->web服务器接收内容->返回给用户。

模块模式

apache+php运行时,默认使用的是模块模式,它把php作为apache的模块随apache启动而启动,接收到用户请求时则直接通过调用mod_php模块进行处理。

模块模式是以mod_php5模块的形式集成,此时mod_php5模块的作用是接收Apache传递过来的PHP文件请求,并处理这些请求,然后将处理后的结果返回给Apache。如果我们在Apache启动前在其配置文件中配置好了PHP模块(mod_php5),PHP模块通过注册apache2的ap_hook_post_config挂钩,在Apache启动的时候启动此模块以接受PHP文件的请求。

php-cli模式

php-cli模式属于命令行模式,对于很多刚开始学php就开始wamp,wnmp的开发者来说是最陌生的一种运行模式。该模式不需要借助其他程序,直接输入php xx.php 就能执行php代码,命令行模式和常规web模式明显不一样的是:

  • 没有超时时间
  • 默认关闭buffer缓冲
  • STDIN和STDOUT标准输入/输出/错误 的使用
  • echo var_dump,phpinfo等输出直接输出到控制台
  • 可使用的类/函数 不同
  • php.ini配置的不同
排查服务器CPU占用率高
  • 定位进程:登录服务器,执行top命令,查看CPU占用情况:top
  • 定位线程:如果进程23456占用率高:$top -Hp23456 进行定位线程
  • 定位代码:通过top命令,我们目前已经定位到导致CPU使用率较高的具体线程,将线程转为16进制,通过jstack命令,查看栈信息:$sudo -u admin jstack23456|grep -A20011a7

Session 的存储方式

文件存储

session.save_handler = files
session.save_path = “N;MODE;/path”

Redis

session.save_handler = redis
//多节点
session.save_path = “tcp://ip:port?auth=secret?weight=1&timeout=2.5,tcp://ip2:port2?weight=2”
//单个节点
session.save_path = “tcp://ip:port?auth=secret?weight=1&timeout=2.5”
//socket 方式
session.save_path = "unix:///var/run/redis/redis.sock?persistent=1&weight=1&database=0

Redis延时队列处理

适合的场景

1.数据场景简单且单一
2.对数据的丢失是有容忍度的
3.对消费数据的正确消费是有容忍度的

命令

lpush/rpush(推送消息)
rpop/lpop(拉取消息 非阻塞)
brpop/blpop(拉取消息 支持阻塞)

异常处理
  • 直接抛出异常,前端提醒用户是否要继续操作;
  • sleep一会再重试;
  • 将请求放到延时队列中,一会再重试;
    而Redis中延时队列,我们可以通过zset(有序列表)数据结构来实现。我们将消息序列化作为一个字符串作为zset的value,而消息的到期处理时间(延时时间)作为score。然后通过轮询zset获取到期时间进行处理,通过zrem将key从zset移除代表成功消费,进而处理任务。
    缺点:不支持重复消费,消息丢失
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值