PHP面试问题总结

1,字符串函数
str_repeat — 重复一个字符串
str_replace — 子字符串替换
sha1 — 计算字符串的 sha1 散列值
rtrim — 删除字符串末端的空白字符(或者其他字符)
md5 — 计算字符串的 MD5 散列值
trim — 去除字符串首尾处的空白字符(或者其他字符)
php explode--字符串变数组
js split--字符串变数组
strrev 字符串反转
strstr 查找字符串首次出现的位置
2,数组函数
php implode--数组变字符串
js join--数组变字符串
array_merge — 合并一个或多个数组
array_pop — 弹出数组最后一个单元(出栈)
array_push — 将一个或多个单元压入数组的末尾(入栈)
array_shift — 将数组开头的单元移出数组
array_sum — 对数组中所有值求和
in_array — 检查数组中是否存在某个值
is_array 是否为数组
array_rand 随机取出一个或多个单元
3,三范式
字段不可再分
有主键,非主键依赖主键
非主键字段不能相互依赖
4,数据库事务的四个特性
单词:acid
原子性 Atomicity
要么做,要么不做。这个例子挺多的,就像二进制0/1 开关一样,要么开,要么关,不存在什么半开。还有类似boolean类型数据,就只有true ,false 。就像誓死如归的军人,要么战死,要么凯旋,绝对不会投降。
一致性 Consistency
要求A+B = 10 ,A B 两个变量必须一致,A=1 ,B一定要等于9,A=2,B一定要等于8.还有csdn博客,你关注了我 , 那么你就是我的粉丝,数据库两头都要存储。还有银行转账这个经典的例子。
隔离型 Isolation
[1] 脏读:
所谓脏读,就是读了未提交的数据。举个例子:B事务读取了A事务尚未commit的数据,不巧的是,之后A事务rollback了,这就叫脏读。
[2] 不可重复读:
所谓不可重复读,就是一个事务多次读取某一行,但是这一行在多次读取之中的值不一致(这个事务并为对这行作任何修改操作)。举例:A事务多次读取某一行,在它多次读取操作之间,B事务修改了这一行,这就是不可重复读。
[3] 幻像:
所谓幻像,在一个尚未提交的事务的读取的行的范围中插入新行或删除现有行。举例:B事务对A事务读取的行范围内插入新行或删除行,而A事务之后还会访问这些行(即操作会受到这些行的影响),这样A事务中就发生了幻像。
持久性 Durability
一旦事务提交成功,数据修改是永存的。这个与内存,磁盘数据存储有关,还要涉及到缓存
完全持久,当事务被提交之后,会把事务日志写入到磁盘,完成后返回给客户端。
延迟持久,事务提交是异步的,在事务写入到磁盘前,事务提交返回给客户端。
以前都是完全持久,现在多了个延迟持久,延迟持久只有当日志缓存刷新的时候才会被写入到磁盘保证事务完整性。
5,同步和异步的差别
同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事
异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

6,面对对象的三大特性和五大原则
三大特性是:封装,继承,多态
所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。

所谓继承是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

五大基本原则
单一职责原则SRP(Single Responsibility Principle)
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。

开放封闭原则OCP(Open-Close Principle)
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,
那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。

替换原则(the Liskov Substitution Principle LSP)
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,
也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。

依赖原则(the Dependency Inversion Principle DIP) 具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,
这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到
了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。
接口分离原则(the Interface Segregation Principle ISP)
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
加上 迪米特法则 就是PHP的六大原则
定义:一个对象应该对其他对象保持最少的了解。
7,高内聚和低耦合
内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系;
耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。

8,rbac理解
首先需要五张表: 用户表 ,角色表, 权限表 , 用户角色表 , 角色权限表
RBAC 认证的过程大致如下:
1. 判断当前模块的当前操作是否需要认证
2. 如果需要认证并且尚未登录,跳到认证网关,如果已经登录 执行5
3. 通过委托认证进行用户身份认证
4. 获取用户的决策访问列表
5. 判断当前用户是否具有访问权限
9,微信第三方登录

10,linux命令
vi的三种模式:指令行模式,文本输入模式,行末模式,按下esc进入文本模式
查看文件的命令:
more (根据窗口大小,一页一页的查看文件的内容)
less (与more类似,优点可以往前翻页)
head (查看头几行)
tail (查看后几行)
cat (从第一行开始显示内容,展示所有的内容)
pwd 查看当前所操作的目录
su 切换用的命令
whoami 查看当前的用户名
exit 可以退出连接 也可以退回到原用户
touch (创建文件)
mkdir (创建文件夹)
kill -9 进程号(杀死进程)
grep 所搜的内容 文件名(路径绝对,相对都可)
ps -A(查看系统活跃的进程)
du -h(查看当前目录或文件的在磁盘中大小)
date (查看系统时间)
df -h(查看系统分区情况)
cp file1 dir/file2(复制文件)
mv (移动目录或文件)
rm -rf (删除文件及子目录)
安装一般由3个步骤组成:
配置(configure)、./configure --prefix=/usr/local/supersparrow打算安装到哪个目录
编译(make)、
安装(make install),

11,js如何使用cookie
JS设置cookie:document.cookie="name="+username;
js如何销毁数组 splice

12,settimeout和setinterval区别
setTimeout(表达式,延时时间)在执行时,是在载入后延迟指定时间后,去执行一次表达式,记住,次数是一次
setInterval(表达式,交互时间)则不一样,它从载入后,每隔指定的时间就执行一次表达式

13,接口和抽象类的区别
1.抽象类 和 接口 都是用来抽象具体对象的. 但是接口的抽象级别最高
2.抽象类可以有具体的方法 和属性, 接口只能有抽象方法和不可变常量
3.抽象类主要用来抽象类别,接口主要用来抽象功能.
4、抽象类中,且不包含任何实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的。

当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

14,static,global,const
const是定义一个常量
static静态的
Global定义的是一个全局变量
普通变量只在自己的小范围内使用,static的变量作用域包含整个函数范围,global的作用域是包含整个程序运行的范围。

15,清表的方式truncate / delete from

16,分表分区
分表
垂直分割(并不常用)
就是将一个表按照字段来分,每张表保证有相同的主键就好。一般来说,将常用字段和大字段分表来放。
水平分割(重要)
水平分割是企业最常用到的,水平拆分就是大表按照记录分为很多子表:
分区
水平分区
垂直分区

17,Mysql如何为表字段添加索引
1.添加PRIMARY KEY(主键索引):
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
2.添加UNIQUE(唯一索引) :
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
3.添加INDEX(普通索引) :
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
4.添加FULLTEXT(全文索引) :
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
5.添加多列索引:
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

18,ngix反向代理
指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
正向代理:
是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
区别:正向代理代理客户端,反向代理代理服务器
反向代理的实现:
1)需要有一个负载均衡设备来分发用户请求,将用户请求分发到空闲的服务器上
2)服务器返回自己的服务到负载均衡设备
3)负载均衡将服务器的服务返回用户


19,支付宝支付流程(同步和异步两个方面)
app客户端
1>向自己的服务器请求一个订单,
2>接收到订单后,向支付宝sdk发送一个支付请求
3>交易结束后会返回一个成功或失败
服务器端需要处理的事情较多(服务端需要存放应用的私钥进行签名)
1>接收到客户端的请求时,生成一个带签名的订单返回给客户端的步骤有
把相应的配置数据生成一个数组,再把数组的数据生成一个有序的字符串,
将这组字符串进行RSA-SHA算法,得到的结果再与存在服务端的私钥进行签名
有序的字符串+得到的签名+签名方法就是生成的订单,将这组订单返回给客户端。
2>接下来就是如果前端支付成功,支付宝回向我们预留好的回调接口发送一个POST请求,让我们验证是否支付成功。
将支付宝发送过来的数据生成一个有序的字符串,
将有序的字符串进行hash,然后根据公钥进行对签名进行有效的验证,结果返回true和false,
如果验签成功再生成支付宝通知url,来验证是否是支付宝发来的通知,如果有数据则说明确实是支付宝发来的通知,这次交易有效

return_url 与 notify_url 的区别
买家付款成功后,如果接口中指定有return_url ,买家付完款后会跳到 return_url所在的页面,这个页面可以展示给客户看,这个页面只有付款成功才会跳转.

notify_url:服务器后台通知,这个页面是程序后台运行的(买家和卖家都看不到),买家付完款后,支付宝会调用notify_url这个页面所在的页面并把相应的参数传递到这个页面,这个页面根据支付宝传递过来的参数修改网站订单的状态,更新完订单后需要在页面上打印出一个success给支付宝,如果反馈给支付宝的不是success,支付宝会继续调用这个页面.
流程:买家付完款(trade_status=WAIT_SELLER_SEND_GOODS)--->支付宝通知notify_url---& gt;如果反馈给支付宝的是success(表示成功,这个状态下不再反馈,如果不是继续通知,一般第一次发送和第二次发送的时间间隔是3分钟)
剩下的过程,卖家发货,买家确认收货,交易成功都是这个流程


20,xml和json的区别
XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。
XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。
JSON相对于XML来讲,数据的体积小,传递的速度更快些。
21,加密详解
每四个字节表示一个16进制
在目前开发项目的时候主要用到base64加密,md5加密,sha1加密,
及更实用的哈希加密。base64编码算法不算是真正的加密算法。
MD5,sha1,哈希这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,
我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种
的加密并不可靠。base64的加密解密是双向的,可以求反解。MD5
sha1及哈希是单向加密,任何数据加密后只会产生唯一的一个加密串
通常用来效验数据在传输的过程中是否被修该。其中哈希算法有一个密钥
增强了数据传输过程中的安全性,强化算法外的不可控因素。单向加密的用途主要
是为了效验数据在传输的过程中是否被修该。
在目前开发项目中Base64 , urlencode 一般在发送邮件的时候会使用
根据我所看到的文档及一些的了解 MD5与sha1加密 基本上都是基于哈希的算法来计算的
起初我们在登录的时候来用MD5加密来对密码的一系列的加密 当然sha1 很少
在写接口的时候 及微信里的签名方法 通常会使用sha1加密的算法来开发项目
Base64
编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法!它其实只是定义用可打印字符传输内容一种方法,并不会产生新的字符集!
MD5 算法是单向散列算法的一种,可称为HASH算法,MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要
2017.10.02 新了解了一种解密的方法
password_get_info()、password_hash()、password_needs_rehash()、password_verify()。
首先看 password_hash() 函数它有三个参数 (密码,哈希算法,选项)【注:前两个参数必填】
代码如下:
$pwd = "123456";
$hash = password_hash($pwd, PASSWORD_DEFAULT);
echo $hash;
此函数的作用:加密成功后会生成60个字符的字符串,且如果失败返回false 记:当你刷新页面的时候该哈希值会不断的发生变化
2、password_verify() 来校验密码是否和哈希值匹配:
代码如下:
if (password_verify($pwd,'$2y$10$4kAu4FNGuolmRmSSHgKEMe3DbG5pm3diikFkiAKNh.Sf1tPbB4uo2')) {
echo "密码正确";
} else {
echo "密码错误";
}
3、
password_get_info() //查看哈希值的相关信息
password_needs_rehash() //检查一个hash值是否是使用特定算法及选项创建的
openssl加密的运算
总结:
对于几种的加密方法本人觉的还是password_hash 还是比较安全的,但是却降低了互操作性。
如果使用MD5加密的方法很容易被其他语言来进行效验的
而password_hash 加密的哈希值只能通过php的password_verify 来进行效验
这2种方法各有优劣,是使用md5(或sha1等)+salt(干扰字符串)的方式还是使用password_hash()大家根据具体情况取舍把。
哈希加盐法(HASH+SALT)
一些网站的数据库管理着用户的ID及口令,口令以MD5等加密后的形式存在,但是有些时候可能数据库泄露,HASH值被攻击者获取,如果此HASH值对应的口令是弱口令(被很多用户采用),则黑客可以通过此HASH暴力破解获取其他用户的ID及口令,破坏数据的机密性。
通过加入盐值(salt)即盐化可以很好的防治这种攻击手段。盐值是一组随机的字符串,通过插入在口令后进行HASH算法,这样即使是相同的口令,插入不同的盐值后生成的HASH值也是不相同的,由于MD5的不可逆性,想要逆向破解MD5也是非常耗时间的。
具体的流程是:
用户注册时:
1、用户在网站注册时提供ID与口令
2、系统为用户分配盐值
3、盐值插入口令后进行HASH
4、将ID,HASH值与盐值存入数据库
身份验证时:
1、用户提供ID与口令
2、系统在数据库中通过用户提供的ID查找HASH值与盐值
3、将盐值插入用户提供的口令后进行HASH
4、将HASH值与数据库中的HASH值比较,相等则验证成功,反之验证失败
22,设计模式
单列模式:
三私一共:私有静态属性,私有的静态方法,私有的克隆,公有的静态方法
工厂模式:。建立一个工厂(一个函数或一个类方法)来制造新的对象,它的任务就是把对象的创建过程都封装起来,创建对象不是使用new的形式了。而是定义一个方法,用于创建对象实例。

23,缓存
redis:
数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
端口:6379
优点:异常快,丰富的数据类型,原子性,消息队列
memcahce:
memcachedb也是cache的进程,memcacheq是memcache基础上的一个功能插件,q是queue的意思,是一个列队,很好用
端口:11211
优点:可以分布式,使用多台memcache服务器。
区别: redis支持持久化,可以备份。 都是多进程和多线程
24,邮箱正则 /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/ /w+@w+\.w+/i
URL正则
String check = @"((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?";
关于该正则表达式的说明:
①:该正则表达式匹配的字符串必须以http://、https://、ftp://开头;
②:该正则表达式能匹配URL或者IP地址;(如:http://www.baidu.com 或者 http://192.168.1.1)
③:该正则表达式能匹配到URL的末尾,即能匹配到子URL;(如能匹配:http://www.baidu.com/s?wd=a&rsv_spt=1&issp=1&rsv_bp=0&ie=utf-8&tn=baiduhome_pg&inputT=1236)
④:该正则表达式能够匹配端口号;
25,session和cookie
回话跟踪是web程序中常用技术,常用的回话跟踪有cookie和session,Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
26,sku
SKU=Stock Keeping Unit(库存量单位),包括商品表 商品属性表 货品表,即库存进出计量的基本单元,可以是以件,盒,托盘等为单位。SKU这是对于大型连锁超市DC(配送中心)物流管理的一个必要的方法。现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号。单品:对一种商品而言,当其品牌、型号、配置、等级、花色、包装容量、单位、生产日期、保质期、用途、价格、产地等属性与其他商品存在不同时,可称为一个单品。
27,PHP总共有三个模块:内核、Zend引擎、以及扩展层;
28,PHP的执行流程
PHP实现了一个典型的动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用C实现的,因此最终调用的也都是C的函数,实际上,我们可以把PHP看做是一个C开发的软件。
PHP的执行的核心是翻译出来的一条一条指令,也即opcode。
Opcode是PHP程序执行的最基本单位。一个opcode由两个参数(op1,op2)、返回值和处理函数组成。PHP程序最终被翻译为一组opcode处理函数的顺序执行。
29,CGI、FastCGI和php-fpm的概念和区别
1>. CGI
CGI(Common Gateway Interface),公共网关接口,它是Web服务器与外部应用程序(CGI程序)之间传递信息的接口标准。通过CGI接口,Web服务器就能够获取客户端提交的信息,并转交给服务器端的CGI程序处理,最后返回结果给客户端。
也就是说,CGI实际上是一个接口标准。我们通常所说的CGI是指CGI程序,即实现了CGI接口标准的程序。
只要某种语言具有标准输入、输出和环境变量,如perl、php、C等,就可以用来编写CGI程序。
CGI程序的工作方式:
Web服务器一般只处理静态文件请求(如 jpg、htm、html),如果碰到一个动态脚本请求(如php),web服务器主进程,就fork出一个新的进程来启动CGI程序,也就是说将动态脚本请求交给CGI程序来处理。启动CGI程序需要一个过程,比如,读取配置文件,加载扩展等。CGI程序启动后,就会解析动态脚本,然后将结果返回给Web服务器,最后Web服务器再将结果返回给客户端,刚才fork的进程也会随之关闭。
这样,每次用户请求动态脚本,Web服务器都要重新fork一个新进程,去启动CGI程序,由CGI程序来处理动态脚本,处理完后进程随之关闭。
这种工作方式的效率是非常低下的。
2>. Web服务器内置模块
后来,出现了一种比较高效的方式:Web服务器内置模块。例如,apache的mod_php模块。将php解释器做成模块,然后加载到apache服务器中。
这样,apache服务器在启动的时候,就会同时启动php模块。当客户端请求php文件时,apache服务器就不用再fork出一个新进程来启动php解释器,而是直接将php文件交给运行中的php模块处理。显然,这种方式下,效率会比较高。
由于在apache服务器启动时,才会读取php的配置文件,加载p-hp模块,在apache的运行过程中 ,不会再重新读取php的配置文件。所以,每次我们修改了php的配置文件后,必须重启apache,新的php配置文件才会生效。
3>. FastCGI
FastCGI就像是一个常驻(long-live)型的CGI程序,它可以一直运行着。FastCGI程序也可以和Web服务器分别部署在不同的主机上,它还可以接受来自其他Web服务器的请求。
FastCGI也是语言无关的。其主要行为是将CGI解释器进程保持在内存中并因此获得高效的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因。
FastCGI是一种进程管理工具,它可以在内存中管理CGI进程。
FastCGI进程管理器需要单独启动。启动FastCGI后,会生成一个FastCGI主进程和多个子进程(子进程其实就是CGI解释器进程)。
当客户端请求Web服务器上的动态脚本时,Web服务器会将动态脚本通过TCP协议交给FastCGI主进程,FastCGI主进程根据情况,安排一个空闲的子进程来解析动态脚本,处理完成后将结果返回给Web服务器,Web服务器再将结果返回给客户端。该客户端请求处理完毕后,FastCGI子进程并不会随之关闭,而是继续等待主进程安排工作任务。
由此可知,FastCGI的工作效率是非常高的。
4>. php-fpm
fpm是FastCGI Process Manager的缩写,那么,fpm就是FastCGI进程管理器的简称。
php-fpm就是php中的FastCGI进程管理器。
对于php5.3之前的版本来说,php-fpm是一个第三方的补丁包,旨在将FastCGI进程管理整合进PHP包中。
在php5.3之后的版本中,php-fpm不再是第三方的包,它已经被集成到php的源码中了。php-fpm提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以php-fpm被PHP官方收购了。

PHP运行模式有4钟(fork-and-execute)
1、cgi通用网关接口(Common Gateway Interface)
性能底下,每有一次连接请求就会有一个cgi子进程,反复加载是cgi性能底下的原因。
2、fast-cgi常驻(long-live)型的CGI
常驻型的CGI,他可以一直执行,只要激活后,不会每次都要花费时间去fork一次。
3、cli命令运行(Command Live Interface)
cli是PHP的命令行运行模式
4、web模块模式(apache等web服务器运行的模块模式)
mod_php5模块,在Apache启动前在其配置文件中配置好了PHP模块(mod_php5)
HTTPServer这块基本可以看到有三种stack比较流行:
(1)Apache+mod_php5
(2)lighttp+spawn-fcgi
(3)nginx+PHP-FPM
三者后两者性能可能稍优,但是Apache由于有丰富的模块和功能,目前来说仍旧是老大。有人测试nginx+PHP-FPM在高并发情况下可能会达到Apache+mod_php5的5~10倍,现在nginx+PHP-FPM使用的人越来越多。
TCP与UDP
1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
innodb是怎么支持事务的
分类
扁平事务:最常用的事物,但是一旦失败,就会全部回滚。
带有保存点的扁平事物:它会在事务中嵌入保存点,缺点,如果数据库崩溃,所有的保存点都会消失。
链事务:为了保存事务,它可以回滚到上一个事务或者上上个事务,缺点它只能回滚到最近的保存点,而不像带有保存点的扁平事务,它可以在事务内回滚到任意一个保存点。
嵌套事务:由顶层事务和子事务构成,类似于树结构。顶层负责逻辑,子事务负责工作。
特点:子事务可以提交,但真正提交要等到父事务提交。
如果上层事务回滚后,子事务都会回滚。
分布式事务:是在分布式环境中运行扁平化事务,前提是开启innodb对分布式事务的支持。
事务的实现:
redo log,重做日志,用来保证事务的原子性和持久性,undo log,回滚日志,用来保证事务的一致性。
redo 和undo都可以看作是一种恢复操作,但是redo是用来恢复事务修改的页操作,而undo是回滚到某个特定的版本,两个记录的内容是不一样的,redo一般是物理日志,记录的是页的物理修改记录,undo是逻辑日志,根据每行的记录来进行记录。
memcache处理高并发

include_once和require_once的区别
include_once()函数的作用与include相同,不过它会首先验证是否已经包含了该文件。如果已经包含,则不再执行include_once。否则,则必须包含该文件。除了这一点与include完全相同。
require_once函数确保文件只包含一次。在遇到require_once后,后面再试图包含相同的文件时将被忽略。


__autoload 和 spl_autoload_register()的区别
spl_autoload_unregister()注销已经注册的函数、spl_autoload_functions()返回所有已经注册的函数
如果需要多条 autoload 函数,spl_autoload_register() 满足了此类需求。 它实际上创建了 autoload 函数的队列,按定义时的顺序逐个执行。相比之下, __autoload() 只可以定义一次。

PHP合并数组array+array与array_merge的区别分析
1)键名为数字时,array_merge()不会覆盖掉原来的值,但+合并数组则会把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉(不是覆盖)

2)键名为字符时,+仍然把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值“抛弃”掉,但array_merge()此时会覆盖掉前面相同键名的值

缓存命中率的介绍
命中:可以直接通过缓存获取到需要的数据。
不命中:无法直接通过缓存获取到想要的数据,需要再次查询数据库或者执行其它的操作。原因可能是由于缓存中根本不存在,或者缓存已经过期
提高缓存命中率
缓存预加载(预热)、增加存储容量、调整缓存粒度、更新缓存等手段来提高命中率。
int(1)和int(10)的区别
有一个属性叫zerofill,我的理解是填零属性
int(1)的列插入1为1; int(10)的列插入1的时候为0000000001;

oauth2.0和oauth1.0的区别
oauth2.0授权过程有3步:
用户到授权服务器,请求授权,然后返回授权码(code)
客户端由授权码到授权服务器换取访问令牌(access_token)
用户用访问令牌去访问得到授权的资源
oauth1.0授权过程有4步:
客户端到授权服务器请求一个授权的令牌
引导用户到授权服务器请求授权
用访问令牌取到授权服务器换取访问令牌
用访问令牌去访问得到授权的资源

两者的对比:
  OAuth1.0协议每个Token都有一个加密,2.0则不需要。这样来看1.0似乎更加安全,但是2.0要求使用https协议,安全性也更高一筹。
  OAuth2.0充分考虑了客户端的各种子态,因而提供了多种途径获取访问令牌
   a)授权码
b)客户端私有证书
c)资源拥有者密码证书
d)刷新令牌
e)断言证书
  OAuth1.0只有一个用户授权流程。
   OAuth2.0较1.0相比,整个授权验证流程更简单更安全,也是未来最主要的用户身份验证和授权方式。

队列是一种线性表,按照先进先出的原则进行
单向队列:只能从头进,从尾出
双向队列:头尾都可以进出

MYSQL explain 的参数
key_len 使用的索引的长度。在不损失精确性的情况 下,长度越短越好。
rows MYSQL 认为必须检查的用来返回请求数据的行数
PHP错误级别(6个)
Deprecated最低级别错误,程序继续执行
 Notice 通知级别的错误 如直接使用未声明变量,程序继续执行
 Warning 警告级别的错误,可能得不到想要的结果
 Fatal error 致命级别错误致命级别错误,程序不往下执行
 parse error 语法解析错误,最高级别错误,连其他错误信息也不呈现出来
 E_USER_相关错误 用户设置的相关错误
如何设置错误级别
error_reporting(-1)显示所有错误,error_reporting(0)屏蔽所有错误。ini_set('error_reporting',0)也是屏蔽所有错误。可以在php.ini文件中设置error_reporting来使脚本显示或不显示某些错误。ini_set('display_errors','On')显示错误。
session共享
利用redis做session共享,首先需要与业务逻辑代码解耦,不然session共享将没有意义,其次支持动态切换到客户端cookie模式。redis的方案是,重写服务器中的HttpSession和HttpServletRequest,首先实现HttpSession接口,重写session的所有方法,将session以hash值的方式存在redis中,一个session的key就是sessionID,setAtrribute重写之后就是更新redis中的数据,getAttribute重写之后就是获取redis中的数据,等等需要将HttpSession的接口一一实现。
实现了HttpSesson,那么我们先将该session类叫做MySession(当然实践中不是这么命名的),当MySession出现之后问题才开始,怎么能在不影响业务逻辑代码的情况下,还能让原本的request.getSession()获取到的是MySession,而不是服务器原生的session。这里,我决定重写服务器的HttpServletRequet,这里先称为MyRequest,但是这可不是单纯的重写,我需要在原生的request基础上重写,于是我决定在filter中,实现request的偷梁换柱,我的思路是这样的,MyRequest的构建器,必须以request作为参数,于是我在filter中将服务器原生的request(也有可能是框架封装过的request),当做参数new出来一个MyRequest,并且MyRequest也实现了HttpServletRequest接口,其实就是对原生request的一个增强,这里主要重写了几个request的方法,但是最重要的是重写了request.getSession(),写到这里大家应该都明白为什么重写这个方法了吧,当然是为了获取MySession,于是这样就在filter中,偷偷的将原生的request换成MyRequest了,然后再将替换过的request传入chan.doFilter(),这样filter时候的代码都使用的是MyRequest了,同时对业务代码是透明的,业务代码获取session的方法仍然是request.getSession(),但其实获取到的已经是MySession了,这样对session的操作已经变成了对redis的操作。这样实现的好处有两个,第一开发人员不需要对session共享做任何关注,session共享对用户是透明的;第二,filter是可配置的,通过filter的方式可以将session共享做成一项可插拔的功能,没有任何侵入性。
GemFire由Apache Geode支持的内存数据网格
php设计模式
单例模式
简单工厂模式
观察者模式
策略模式
命令链模式

sphinx(支持中文检索)
Sphinx的整个工作流程就是Indexer程序到数据库里面提取数据,对数据进行分词,然后根据生成的分词生成单个或多个索引,并将它们传递给searchd程序。然后客户端可以通过API调用进行搜索。
如何进行流量削锋
必要的模块间使用消息队列通信
划分好动静资源,静态资源使用CDN进行服务分发
常用聚合函数
GROUP BY(聚合)函数
AVG([DISTINCT] expr)
返回expr 的平均值。 DISTINCT 选项可用于返回 expr的不同值的平均值。

count(*)返回检索的行数(包括null值)
COUNT(DISTINCT ...)返回检索的行数(不包括null值)
GROUP_CONCAT()返回连接起来的字符串,DISTINCT 可去重复值
MIN([DISTINCT] expr), MAX([DISTINCT] expr)
返回expr 的最小值和最大值。
SUM([DISTINCT] expr)
返回expr 的总数。

缓存雪崩: 缓存接连失效,缓存服务器连续崩溃;解决办法,做二级缓存
缓存穿透: 一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。对缓存结果为空的数据也进行缓存
缓存穿透
什么是缓存穿透?
一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?
1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。
2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。【感觉应该用的不多吧】
缓存雪崩
什么是缓存雪崩?
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。
如何避免?
1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
2:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
3:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期(此点为补充)

分布式缓存系统
分布式缓存系统面临的问题
缓存一致性问题
1:缓存系统与底层数据的一致性。这点在底层系统是“可读可写”时,写得尤为重要
2:有继承关系的缓存之间的一致性。为了尽量提高缓存命中率,缓存也是分层:全局缓存,二级缓存。他们是存在继承关系的。全局缓存可以有二级缓存来组成。
3:多个缓存副本之间的一致性。为了保证系统的高可用性,缓存系统背后往往会接两套存储系统(如memcache,redis等)
缓存穿透和缓存雪崩
上面有讲述。

缓存数据的淘汰
缓存淘汰的策略有两种: (1) 定时去清理过期的缓存。 (2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂,具体用哪种方案,大家可以根据自己的应用场景来权衡。
redis memcache 的应用场景
redis的五大数据类型String、Hash、List、Set和Sorted Set
String:常用命令:set/get/decr/incr/mget等 字符串
Hash
常用命令:hget/hset/hgetall等 内部存储的Value为一个HashMap
应用场景:我们要存储一个用户信息对象数据,其中包括用户ID、用户姓名、年龄和生日,通过用户ID我们希望获取该用户的姓名或者年龄或者生日
List
常用命令:lpush/rpush/lpop/rpop/lrange等;
应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现;
Set
常用命令:sadd/spop/smembers/sunion等;
应用场景:Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的;
Sorted Set
常用命令:zadd/zrange/zrem/zcard等;
应用场景:Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。
一个项目都会做哪些优化
安全
权限管理
ip验证
登录、操作日志、程序安全日志
SQL注入校验过滤
验证规范
动态验证码
验证码
扩展性能
实现代码分离
模块化开发
预留相关接口
用户体验
去除死链接
智能推介用户经常浏览的信息
多平台登录
数据库
查询数据大的话进行分页(between and 会比limit更快)
UNION ALL 和 UNION 的区别
UNION用的比较多union all是直接连接,取到得是所有值,记录可能有重复 union 是取唯一值,记录没有重复
尽量少使用or like and
数据库分库、数据分表、索引使用、数据分区、返回不必要的行和列
项目架构
四横两纵
四横即四个层次
用户渠道层、应用业务层、数据资源层、基础设施层
两纵即管理和安全两大体系;
SEO优化
清除垃圾代码 空格(shift+tab)左对齐
HTML标签 例如<b>和<strong>都是加粗,但<strong>比<b>多了5个字符
css优化 引用外部css文件、 尽量少使用全局reset * 、良好的命名习惯、
URL重写把动态页面.aspx .jsp .php重新成.html,让搜索引擎更容易识别
分布式
独立站点开发:模块结构化开发,实现资源分站点,数据分库
web站点:
1.web前端站点 
2.图片、文件资源站点
3.管理端站点
4.数据接口站点
数据库:
1.业务数据库
2.访问信息数据库、日志
分布式部署-CDN分布式网络:通过现有的Internet增加一层网络架构,将网站的内容发布到最接近用户的网络边缘,使用户可以就近取得所需的内容 (该项为收费的项目)
分布式部署-软负载均衡
代码优化
取数据不要查询全部字段
数据查询采用真分页

UI界面
尽量采用div+css布局
img合理使用尽量控制在20-100k
少使用js特效
生成静态页
图片延时加载
把样式放在顶部
减少cookie的体积

PHP优缺点
优点:开源 免费性 快捷性 [程序开发快,运行快,技术本身学习快]
插件丰富,网上的解决方案有很多,而且还有庞大的开源社区可以提供帮助。
跨平台性强 效率高 图像处理
缺点:支持web开发,不方便做 .exe文件,不方便做桌面应用程序. 不方便做手机程序.单线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值