2020年PHP 面试问题(三)

2022-10-08,

2020年php 面试问题(一)

2020年php 面试问题(二)

 

一.数据库三范式

第一范式:1nf是对属性的原子性约束,要求属性具有原子性,不可再分解;

第二范式:2nf是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

第三范式:3nf是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。

范式化设计优缺点:

优点:

可以尽量得减少数据冗余,使得更新快,体积小

缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化

反范式化:

优点:可以减少表得关联,可以更好得进行索引优化

缺点:数据冗余以及数据异常,数据得修改需要更多的成本

二.mysql 中有哪几种锁

- myisam支持表锁,innodb支持表锁和行锁,默认为行锁
- 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低
- 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高

 

三.什么是存储过程

我们常用的操作数据库语言sql语句在执行的时候需要要先编译,然后执行,而存储过程(stored procedure)是一组为了完成特定功能的sql语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有sql语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。

优点:

(1).存储过程增强了sql语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的sql语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

(3).存储过程能实现较快的执行速度。如果某一操作包含大量的transaction-sql代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的transaction-sql语句在每次运行时都要进行编译和优化,速度相对要慢一些。

(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的transaction-sql语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。

 

(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。

四.如何处理负载、高并发

1、html静态化
其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。

2、图片服务器分离
把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等。

3、数据库集群和库表散列及缓存

数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。

4、镜像
尽量减少下载,可以把不同的请求分发到多个镜像端。

5、负载均衡:
apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如f5服务器。当然硬件的成本比较高,我们往往从软件方面着手。

 

负载均衡 (load balancing) 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力,同时能够提高网络的灵活性和可用性。目前使用最为广泛的负载均衡软件是nginx、lvs、haproxy。我分别来说下三种的优缺点:

**nginx的优点是:**

工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比haproxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,nginx单凭这点可利用的场合就远多于lvs了。

nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势之一;相反lvs对网络稳定性依赖比较大,这点本人深有体会;

nginx安装和配置比较简单,测试起来比较方便,它基本能把错误用日志打印出来。lvs的配置、测试就要花比较长的时间了,lvs对网络依赖比较大。

 

可以承担高负载压力且稳定,在硬件不差的情况下一般能支撑几万次的并发量,负载度比lvs相对小些。

nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,nginx会把上传切到另一台服务器重新处理,而lvs就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。

nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的web应用服务器。lnmp也是近几年非常流行的web架构,在高流量的环境中稳定性也很好。

nginx现在作为web反向加速缓存越来越成熟了,速度比传统的squid服务器更快,可以考虑用其作为反向代理加速器。

nginx可作为中层反向代理使用,这一层面nginx基本上无对手,唯一可以对比nginx的就只有 lighttpd了,不过 lighttpd目前还没有做到nginx完全的功能,配置也不那么清晰易读,社区资料也远远没nginx活跃。

nginx也可作为静态网页和图片服务器,这方面的性能也无对手。还有nginx社区非常活跃,第三方模块也很多。

 

 

**nginx的缺点是:**

nginx仅能支持http、https和email协议,这样就在适用范围上面小些,这个是它的缺点。

对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。不支持session的直接保持,但能通过ip_hash来解决。

lvs:使用linux内核集群实现一个高性能、高可用的负载均衡服务器,它具有很好的可伸缩性(scalability)、可靠性(reliability)和可管理性(manageability)。

 

**lvs的优点是:**

抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,对内存和cpu资源消耗比较低。

 

配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率。

 

工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,如lvs+keepalived,不过我们在项目实施中用得最多的还是lvs/dr+keepalived。

 

无流量,lvs只分发请求,而流量并不从它本身出去,这点保证了均衡器io的性能不会受到大流量的影响。

 

应用范围比较广,因为lvs工作在4层,所以它几乎可以对所有应用做负载均衡,包括http、数据库、在线聊天室等等。

 

**lvs的缺点是:**

 

软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是nginx/haproxy+keepalived的优势所在。

 

如果是网站应用比较庞大的话,lvs/dr+keepalived实施起来就比较复杂了,特别后面有 windows server的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,nginx/haproxy+keepalived就简单多了。

 

**haproxy的特点是:**

 

haproxy也是支持虚拟主机的。

 

haproxy的优点能够补充nginx的一些缺点,比如支持session的保持,cookie的引导;同时支持通过获取指定的url来检测后端服务器的状态。

 

haproxy跟lvs类似,本身就只是一款负载均衡软件;单纯从效率上来讲haproxy会比nginx有更出色的负载均衡速度,在并发处理上也是优于nginx的。

 

haproxy支持tcp协议的负载均衡转发,可以对mysql读进行负载均衡,对后端的mysql节点进行检测和负载均衡,大家可以用lvs+keepalived对mysql主从做负载均衡。

 

haproxy负载均衡策略非常多,haproxy的负载均衡算法现在具体有如下8种:

 

① roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;

 

② static-rr,表示根据权重,建议关注;

 

③ leastconn,表示最少连接者先处理,建议关注;

 

④ source,表示根据请求源ip,这个跟nginx的ip_hash机制类似,我们用其作为解决session问题的一种方法,建议关注;

 

⑤ ri,表示根据请求的uri;

 

⑥ rl_param,表示根据请求的url参数’balance url_param’ requires an url parameter name;

 

⑦ hdr(name),表示根据http请求头来锁定每一次http请求;

 

⑧ rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次tcp请求。

 

**nginx和lvs对比的总结:**

 

nginx工作在网络的7层,所以它可以针对http应用本身来做分流策略,比如针对域名、目录结构等,相比之下lvs并不具备这样的功能,所以nginx单凭这点可利用的场合就远多于lvs了;但nginx有用的这些功能使其可调整度要高于lvs,所以经常要去触碰触碰,触碰多了,人为出问题的几率也就会大。

 

nginx对网络稳定性的依赖较小,理论上只要ping得通,网页访问正常,nginx就能连得通,这是nginx的一大优势!nginx同时还能区分内外网,如果是同时拥有内外网的节点,就相当于单机拥有了备份线路;lvs就比较依赖于网络环境,目前来看服务器在同一网段内并且lvs使用direct方式分流,效果较能得到保证。另外注意,lvs需要向托管商至少申请多一个ip来做visual ip,貌似是不能用本身的ip来做vip的。要做好lvs管理员,确实得跟进学习很多有关网络通信方面的知识,就不再是一个http那么简单了。

 

nginx安装和配置比较简单,测试起来也很方便,因为它基本能把错误用日志打印出来。lvs的安装和配置、测试就要花比较长的时间了;lvs对网络依赖比较大,很多时候不能配置成功都是因为网络问题而不是配置问题,出了问题要解决也相应的会麻烦得多。

 

nginx也同样能承受很高负载且稳定,但负载度和稳定度差lvs还有几个等级:nginx处理所有流量所以受限于机器io和配置;本身的bug也还是难以避免的。

 

nginx可以检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点。目前lvs中 ldirectd也能支持针对服务器内部的情况来监控,但lvs的原理使其不能重发请求。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,nginx会把上传切到另一台服务器重新处理,而lvs就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而恼火。

 

nginx对请求的异步处理可以帮助节点服务器减轻负载,假如使用 apache直接对外服务,那么出现很多的窄带链接时apache服务器将会占用大 量内存而不能释放,使用多一个nginx做apache代理的话,这些窄带链接会被nginx挡住,apache上就不会堆积过多的请求,这样就减少了相当多的资源占用。这点使用squid也有相同的作用,即使squid本身配置为不缓存,对apache还是有很大帮助的。

 

nginx能支持http、https和email(email的功能比较少用),lvs所支持的应用在这点上会比nginx更多。在使用上,一般最前端所采取的策略应是lvs,也就是dns的指向应为lvs均衡器,lvs的优点令它非常适合做这个任务。重要的ip地址,最好交由lvs托管,比如数据库的 ip、webservice服务器的ip等等,这些ip地址随着时间推移,使用面会越来越大,如果更换ip则故障会接踵而至。所以将这些重要ip交给 lvs托管是最为稳妥的,这样做的唯一缺点是需要的vip数量会比较多。nginx可作为lvs节点机器使用,一是可以利用nginx的功能,二是可以利用nginx的性能。当然这一层面也可以直接使用squid,squid的功能方面就比nginx弱不少了,性能上也有所逊色于nginx。nginx也可作为中层代理使用,这一层面nginx基本上无对手,唯一可以撼动nginx的就只有lighttpd了,不过lighttpd目前还没有能做到 nginx完全的功能,配置也不那么清晰易读。另外,中层代理的ip也是重要的,所以中层代理也拥有一个vip和lvs是最完美的方案了。具体的应用还得具体分析,如果是比较小的网站(日pv小于1000万),用nginx就完全可以了,如果机器也不少,可以用dns轮询,lvs所耗费的机器还是比较多的;大型网站或者重要的服务,机器不发愁的时候,要多多考虑利用lvs。

 

更多学习内容请访问:

腾讯t3-t4标准精品php架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)

 

《2020年PHP 面试问题(三).doc》

下载本文的Word格式文档,以方便收藏与打印。