1,二叉树
二叉树是数据结构中不可忽略的部分,但是相关的书籍上很少有用php来实现二叉树。简单理解,是通过操作节点来实现。树是递归结构。二叉树有多种类型 平衡树 搜索树等。
3,php各版本的差异
语法的差异
声明函数的参数类型;(以前是弱类型)
操作符一些变更;(三元运算符)
命名空间的优化。
一些函数的废弃使用(call_user_method,,)
php7比php5性能提升2倍
4支付宝和微信的流程是类似的,支付结果通知都是异步通知:
1.用户在商家(就是我们自己产品)下单,商家生成自己的订单号(要具有唯一性), 同时把相关下单数据存入自家的数据库,(此时这笔订单的状态是 未知付状态)
2. 调用微信或支付宝的SDK,请求 统一下单接口(按照文档要求把相应的参数传过去,参数中我们自己的订单号是必传的) ,如果成功,微信或者支付宝会返回 支付跳转链接(这个支付链接 分多种,比如 可以调起手机中的微信或者支付宝,那就是是接入的是手机支付;或是生成支付二维码,接入的是 网页支付 等等);
3.调起微信或者支付宝 用户支付确认后,回跳到一个页面(这个页面商家可自定义), 同时 微信或 支付宝会异步通知 支付结果
4.商家根据异步通知支付结果,成功:更新自己数据库中的 支付状态,然后给用户相应的商品, 同时要告知 微信或支付宝 异步接受成功
5 redis单线程为啥支持高并发?
Redis使用的是非阻塞IO、IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。
Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。
Redis全程使用hash结构,读取速度快。
Redis是纯内存数据库,(基于内存进行读写的,cpu 不是瓶颈)一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。
6 MySQL主从复制的原理
MySQL主从复制是一个异步的复制过程,主库发送更新事件到从库,从库读取更新记录,并执行更新记录,使得从库的内容与主库保持一致。
负载均衡集群如何分配访问
1.轮询 最基本的配置方法,是upstream模块默认的负载均衡策略。每个请求会按时间顺序...
2.weight 权重方式,在轮询策略的基础上指定轮询的几率。也可以认为是在轮询的基础上新增...
3.ip_hash 依据ip分配方式,指定负载均衡器按照基于客户端IP的分配方式,这个方法...
4.least_conn 最少连接方式,把请求发给链接数最少的后端服务器。轮询是把请求平均...
5.fair 响应时间方式,按照服务器端的响应时间来分配请求,响应时间短的优先分配...
cgi fast-cgi 和 php-fpm 区别
CGI的中文含义是通用网关接口,也就是说只要能够返回标准html数据的服务都可以叫做CGI。所以CGI不单单是php才有的东西。
请求量过大时CGI程序会严重浪费系统资源的。这样fastcgi就是为了解决这个问题,fastcgi会提供这样的功能:首先会由某个程序读取相应的配置文件并初始化执行环境,当这一系列步骤完成之后,他会一下生成很多个cgi进程(也就是进程池),这样在以后处理php的请求时就不需要频繁的“读取配置、创建进程、销毁进程这样的步骤了”,所以fastcgi可以理解为就是为了实现这种效果而产生的一种处理办法
php-fpm用来实现fast-cgi的操作
“php-fpm是fastcgi进程的管理器,用来管理fastcgi进程的”,这句话可以理解成php-fpm就是能够实现fastcgi功能的程序,他目前由php官方集成到php内核中。所以就是如果要实现cgi的进程池功能就需要使用php-fpm
opcache开启原理
操作码是PHP编译后的一个中间文件,是一个字节码。PHP的解析时在服务端的在解析PHP语言时会生成一个特定的操作码,默认情况下PHP将程序执行后就会删除此操作码,而操作码缓存的原理是将编译后的操作码保存下来,并放入到共享内存中,以便在下次调用该PHP页面时重用他,避免了相同代码的重复编译,节省了PHP引擎重复编译的时间,降低了服务器负载,同时减少了CPU和内存开销
mysql 索引的原理
索引的目的在于提高查询效率,通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。
建索引的规范
1,索引字段要尽量的小
2,索引的最左匹配特性(即从左往右匹配)。
mysql索引的两大类型hash与btree
我们可以在创建上述索引的时候,为其指定索引类型,分两类
hash类型的索引:查询单条快,范围查询慢
btree类型的索引:b+树,层数越多,数据量指数级增长(我们就用它,因为innodb默认支持它)
不同的存储引擎支持的索引类型也不一样
InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引。
mysql 加锁
1.表级锁:(myisam支持)开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
2.行级锁:(InnoDB支持)开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
3.页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
创建行锁条件:
1、表中创建索引, select 。。。 where 字段(必须是索引) 不然行锁就无效。
2、必须要有事务,这样才是 行锁(排他锁)
3、在select 语句后面 加 上 FOR UPDATE;
【PHP】几种经典排序算法
选择排序:
原理:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
插入排序:
原理:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
mysql 悲观锁
系统中的并发更新会非常频繁,并且事务失败了以后重来的开销很大,这样以来,我们就需要采用真正意义上的锁来进行实现。悲观锁的基本思想就是每次一个事务读取某一条记录后,就会把这条记录锁住,这样其它的事务要想更新,必须等以前的事务提交或者回滚解除锁。
乐观锁(Optimistic Lock)
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
我们认为系统中的事务并发更新不会很频繁,即使冲突了也没事,大不了重新再来一次。它的基本思想就是每次提交一个事务更新时,我们想看看要修改的东西从上次读取以后有没有被其它事务修改过,如果修改过,那么更新就会失败。
分布式集群如何保证数据的一致性?
采取事务(本地事务的ACID特性来保证一致性) 和 mq专业的队列(例如rocketMq)解决。
php抽象类和接口的区别
1.对接口的继承使用implements,抽象类使用extends.
2.接口中不可以声明变量,但可以声明类常量.抽象类中可以声明各种变量
3.接口没有构造函数,抽象类可以有
4.接口中的方法默认为public,抽象类中的方法可以用public,protected,private修饰
5.一个类可以继承多个接口,但只能继承一个抽象类
nginx 4种负载均衡算法
upstream 支持4种负载均衡调度算法:
A)轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器;
B)ip_hash:每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题。
C)url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。后台服务器为缓存的时候效率。
D)fair:这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair模块
php 随机发红包
PHP实现简单发红包(随机分配,平均分配)。保证每人至少能拿0.01元;剩下按照随机数分发