PHPer 面试
A:怎么保证促销商品不会超卖?
答:这个问题是我们当时开发时遇到的一个难点,超卖的原因主要是下的订单的数目和我们要促销的商品的数目不一致导致的,每次总是订单的数比我们的促销商品的数目要多,当时我们的小组讨论了好久,给出了好几个方案来实现:
第一种方案是:①在每次下订单前我们判断促销商品的数量够不够,不够不允许下订单,更改库存量时加上一个条件,只更改商品库存大于0的商品的库存,当时我们使用ab进行压力测试,当并发超过500,访问量超过2000时,还是会出现超卖现象。所以被我们否定了。
第二种方案是:②使用mysql的事务加排他锁来解决,首先我们选择数据库的存储引擎为innoDB,使用的是排他锁实现的,刚开始的时候我们测试了下共享锁,发现还是会出现超卖的现象。有个问题是,当我们进行高并发测试时,对数据库的性能影响很大,导致数据库的压力很大,最终也被我们否定了。
第三种方案是:③使用文件锁实现。当用户抢到一件促销商品后先触发文件锁,防止其他用户进入,该用户抢到促销品后再解开文件锁,放其他用户进行操作。这样可以解决超卖的问题,但是会导致文件得I/O开销很大。
最后我们使用了redis的队列来实现。将要促销的商品数量以队列的方式存入redis中,每当用户抢到一件促销商品则从队列中删除一个数据,确保商品不会超卖。这个操作起来很方便,而且效率极高,最终我们采取这种方式来实现.
B:怎么保证促销商品不会超卖?[竞争状态下如何解决库存的正确减少(超卖问题)]?
答:对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis。第二个问题,我们可以使用redis队列来完成,把要秒杀的商品放入到队列中,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,文件锁和事务在高并发下性能下降很快,当然还要考虑其他方面的东西,比如抢购页面做成静态的,通过ajax调用接口,其中也可能会出现一个用户抢多次的情况,这时候需要再加上一个排队队列和抢购结果队列及库存队列。高并发情况下,将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在,则已抢购,否则未抢购,库存减1,写数据库,将用户入结果队列。
C:如何处理负载、高并发?(好好看看,经常问到,能回答到主要的东西即可)?
答:从低成本、高性能和高扩张性的角度来说有如下处理方案:
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。
D:接口和抽象类的区别是什么?
答:抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。抽象类是通过关键字abstract来声明的。
抽象类与普通类相似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少要包含一个抽象方法,抽象方法没有方法体,该方法天生就是要被子类重写的。
抽象方法的格式为:abstract function abstractMethod();
接口是通过 interface 关键字来声明的,接口中的成员常量和方法都是 public 的,方法可以不写关键字public,接口中的方法也是没有方法体。接口中的方法也天生就是要被子类实现的。
抽象类和接口实现的功能十分相似,最大的不同是接口能实现多继承。在应用中选择抽象类还是接口要看具体实现。
子类继承抽象类使用 extends,子类实现接口使用implements。
E:
a.TP 框架有哪些优点?
答:TP 框架是我们中国人自己开发的框架,各种资料比较齐全,国内用的比较多,比较简单和方便,而且是免费开源的
b.TP 的特性有哪些?
答: 1.多表查询非常方便,在 model 中几句代码就可以完成对多表的关联操作 2.融合了 smarty 模板,使前后台分离 3.支持多种缓存技术,尤其对 memcache 技术支持非常好 4.命名规范,模型,视图,控制器严格遵循命名规则,通过命名一一对应 5.支持多种 url 模式 6.内置 ajax 返回方法,包括 xml,json,html 等 7.支持应用扩展,类库扩展,驱动扩展等
F:
a.请介绍一下 laravel 框架?
答: laravel 框架的设计思想比较先进,非常适合应用各种开发模式,作为一个框架,它为你准备好了一切,composer 是 php 的未来,没有 composer,php 肯定要走向没落 laravel 框架最大的特点和优秀之处就是集合了 php 比较新的特点,以及各种各样的设计模式,Ioc 模式,依赖注入等
b.laravel 有那些特点?
答:回答一: 1.强大的 rest router:用简单的回调函数就可以调用,快速绑定 controller 和 router 2.artisan:命令行工具,很多手动的工作都自动化
3.可继承的模板,简化 view 的开发和管理
4.blade 模板:渲染速度更快
5.ORM 操作数据库
6.migration:管理数据库和版本控制
7.测试功能也很强大
8.composer 也是亮点
回答二: laravel 框架引入了门面,依赖注入,Ioc 模式,以及各种各样的设计模式等
H:请简述一下数据库的优化?
答:数据库的优化可以从四个方面来优化: 1.从结构层: web 服务器采用负载均衡服务器,mysql 服务器采用主从复制,读写分离 2.从储存层: 采用合适的存储引擎,采用三范式 3.从设计层: 采用分区分表,索引,表字段合适的字段属性,适当采用逆范式,开启 mysql 缓存 4.sql 语句层:结果一样的情况下,采用效率高,速度快节省资源的 sql 语句执行
PHPer 面试的更多相关文章
- PHPer面试指南-laravel 篇
简述 Laravel 的生命周期 Laravel 采用了单一入口模式,应用的所有请求入口都是 public/index.php 文件. 注册类文件自动加载器 : Laravel通过 composer ...
- 我的新书——《PHP程序员面试笔试宝典》
你好,是我琉忆. 一个文艺的PHP开发工程师. 很荣幸能够在这里带来我的第一本新书--<PHP程序员面试笔试宝典>. 一.创作过程 <PHP程序员面试笔试宝典>是我的第一本书, ...
- PHP内核探索之变量(7)- 不平凡的字符串
切,一个字符串有什么好研究的. 别这么说,看过<平凡的世界>么,平凡的字符串也可以有不平凡的故事.试看: (1) 在C语言中,strlen计算字符串的时间复杂度是?PHP中呢? ...
- 【转】3年PHPer的面试总结
[转]3年PHPer的面试总结 算法# 1.反转函数的实现# /** * 反转数组 * @param array $arr * @return array */ function reverse($a ...
- 3-5年的PHPer常见的面试题
看到有很多,的总结一下,比较适合有一定经验的PHPer 1.平时喜欢哪些php书籍及博客?CSDN.虎嗅.猎云 2.js闭包是什么? 3.for与foreach哪个更快? 4.php鸟哥是谁?能不能讲 ...
- PHP程序员面试技巧之口试题分享
网络上流传很广的一部分php工程师面试题目,有些phper们认为这些很形式,天下面试题目一大把,不能考核一个人的真实水平,其实细细研究起来,无论怎样,能存在就表明其有存在的价值.下面小编整理了12条P ...
- 从一次面试经历谈PHP的普通传值与引用传值以及unset
关于这个概念一般都会在PHP的第一堂课说变量的时候给介绍,并且我以前还给其他PHPer介绍这个概念.但是作为一个工作一段时间的PHPer的我,竟然在面试的时候一下子拿不定主意最后还答错了,很觉得丢脸( ...
- 【PHP面试题】通俗易懂的两个面试必问的排序算法讲解:冒泡排序和快速排序
又到了金三银四找工作的时间,相信很多开发者都在找工作或者准备着找工作了.一般应对面试,我们无可厚非的去刷下面试题.对于PHPer来说,除了要熟悉自己所做的项目,还有懂的基本的算法.下面来分享下PHP面 ...
- PHPer常见的面试题总结
1.平时喜欢哪些php书籍及博客?CSDN.虎嗅.猎云 2.js闭包是什么? 3.for与foreach哪个更快? 4.php鸟哥是谁?能不能讲一下php执行原理? 5.php加速器有哪些?apc.z ...
随机推荐
- PyQt(Python+Qt)学习随笔:QTreeWidgetItem项的子项排序sortChildren及获取项对应的树型部件对象方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.sortChildren对子项排序 树型部件QTreeWidget中的QTreeWidgetIt ...
- 百度前端技术学院-基础-day20-21
第二十到第二十一天:让你和页面对话 task1 控制元素的显示及隐藏 实现以下功能: 当用户选择了 School 的单选框时,显示 School 的下拉选项,隐藏 Company 的下拉选项 当用户选 ...
- js内存泄漏的问题?
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在. 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量.如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环 ...
- tornado 作业 简单首页 登录页 个人中心
s4 index.py 1 import tornado.ioloop 2 import tornado.web 3 import time 4 5 6 class IndexHandler(torn ...
- STL—— 容器(vector)的数据插入之 insert()
vector 容器可以使用 vectorName.insert() 方法插入元素,vectorName.insert() 函数一共有4种重载方法: 第一种 insert() 用法:在指定地址插入单个元 ...
- C++ 虚函数表与多态 —— 关键字 override 的用法
override 仅能用于虚函数,他属于C++新特性,是重写覆盖的意思,他的存在仅仅是为了提高代码的可阅读性: 作用: 1. 提示程序的阅读者,这个函数是重写父类的功能. 2. 防止程序员在重写父类的 ...
- 【adb命令的使用,及logcat日志的分析】
实时记录日志: adb logcat -v time >D:\maimang.txtadb logcat -v threadtime > E:\Desktop\SSGame_log.txt ...
- 推荐系统实践 0x0f AutoRec
从这一篇开始,我们开始学习深度学习推荐模型,与传统的机器学习相比,深度学习模型的表达能力更强,并且更能够挖掘出数据中潜藏的模式.另外.深度学习模型结构也非常灵活,能够根据业务场景和数据结构进行调整.还 ...
- Java读取系统默认时区
工作中,遇到一个Java读取默认时区的问题,后来看了openjdk的源码,大致整理一下过程 public class Test { public void test(){ TimeZone.getDe ...
- Flink内存溢出
Flink内存模型 此图是基于flink1.12版本. 一个taskmanager给了6g内存,可以有很清楚的看到各个部分占用的内存,还是实时变化的. 名词解释 组件 配置项 描述 Framework ...