[关闭]
@Chiang 2020-02-15T16:42:54.000000Z 字数 13999 阅读 788

PHP面试题目搜集--合格的PHPer必过

面试题 2020-02


理论基础

PHP里面是区分大小写的吗?

  • PHP对于系统函数用户自定义函数类名称等是不区分大小写
  • PHP中的变量和常量是区分大小写的
  • 对于文件名又因服务器操作系统而定,linux中区分,Win不区分

$_POST$HTTP_RAW_POST_DATAphp://input 的区别?

$_POST

是获取表单POST过来数据,MIME类型是“application/x-www-form-urlencoded”。可参考《什么是 MIME TYPE?

意思就是字段名和值都编码了,每个 key-value 对使用 ‘&’ 字符分隔开,key 和 value 使用 ‘=’ 分开,其他特殊字符都会被使用 urlencode 方式进行编码。

$HTTP_RAW_POST_DATA

可以获取原始的POST数据,但需要在 php.ini 中设置开启,并且不支持 enctype="multipart/form-data"方式传递的数据

php://input

可以获取原始的 POST 数据,并且比$HTTP_RAW_POST_DATA更少消耗内存,也不支持"multipart/form-data",

可以使用 file_get_contents() 函数去获取它的内容

没有通过static定义的方法,能否通过”对象名::方法名“这样的形式来调用?

会产生一个strict错误,但在会继续执行代码。参考《PHP静态调用非静态方法》。这篇文章里面还讲到了一个概念“calling scope”。

静态调用并不是说有::就是静态调用,而是看calling scope。$this指针指向的对象就是这个方法被调用时刻的calling scope。

静态调用非静态

请介绍Session的原理

因为HTTP是无状态的,所以一次请求完成后客户端和服务端就不再有任何关系了,谁也不认识谁。

但由于一些需要(如保持登录状态等),必须让服务端和客户端保持联系,session ID就成了这种联系的媒介了。

当用户第一次访问站点时,PHP会用session_start()函数为用户创建一个session ID,这就是针对这个用户的唯一标识,

每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。

这样客户端就会拥有一个该站点给他的session ID。

当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,

服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。

参考《Session原理简述

session共享问题解决方案

a. 客户端Cookie保存,以cookie加密的方式保存在客户端,每次session信息被写在客服端,然后经浏览器再次提交到服务器。

b. 服务器间Session同步,使用主-从服务器的架构,当用户在主服务器上登录后,通过脚本或者守护进程的方式,将session信息传递到各个从服务器中

c. 使用集群统一管理Session,当应用系统需要session信息的时候直接到session群集服务器上读取,目前大多都是使用Memcache来对Session进行存储。

d. 把Session持久化到数据库,目前采用这种方案时所使用的数据库一般为mysql。

参考《Session共享实现方案调研

介绍一下常见的SSO(单点登陆)的原理。

SSO是一种统一认证和授权机制,通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。

解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录。

统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;

认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。

参考《单点登录SSO

PHP缓存技术有哪些?

  1. 全页面静态化缓存:也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程

  2. 页面部分缓存:将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示

  3. 数据缓存:通过一个id进行请求的数据,将数据缓存到一个php文件中,id和文件是对应的,下次通过这个id进行请求时直接读php文件

  4. 查询缓存:和数据缓存差不多,根据查询语句进行缓存;

  5. 内存式缓存:redis和memcache

参考《PHP中9大缓存技术总结

JSON格式数据有哪些特点

a. JSON一种轻量级的数据交换格式。它基于ECMAScript的一个子集。

b. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)

c. 这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(网络传输速率)。

d. "名称/值"对的集合,不同语言中,它被理解为对象(object),记录(record),结构(struct),字典(dictionary),哈希表(hash table),键列表(keyed list)等

e. 值的有序列表,多数语言中被理解为数组(array)

参考《介绍JSON

isset() 、empty()与is_null的区别

isset():仅当null和未定义,返回true
empty():""、0、"0"、NULL、FALSE、array(),未定义,均返回true
is_null():仅判断是否为null,未定义 报警告

MVC的优缺点

优点

分散关注、松散耦合、逻辑复用、标准定义

a. 开发人员可以只关注整个结构中的其中某一层,方便多开发人员间的分工

b. 可以很容易的用新的实现来替换原有层次的实现

c. 降低层与层之间的依赖

d. 利于各层逻辑的复用,有利于标准化

e. 对单元测试的支持更加出色

缺点

a. 清晰的构架以代码的复杂性为代价, 对小项目优可能反而降低开发效率

b. 降低了系统的性能,例如业务造访数据库现在必须通过中间层来完成

c. 控制层和表现层有时会过于紧密,导致没有真正分离和重用

d. 有时会导致级联的修改,如果在表示层中增加一个功能,为保证符合分层式结构,可能需要在相应的控制层和模型层中都增加相应的代码

PHP中单引号和双引号有什么区别?哪个速度更快?

单引号更快

单引号内的数据不会被解析(任何变量和特殊转义字符),所以速度更快

双引号要先查找语句中是否有变量,双引号内的数据会被解析,如变量($var)值会代入字符串中,特殊转义字符也会被解析成特定的单个字

这里顺便说个定界符(heredoc syntax)“<<<”,

其作用就是按照原样,包括换行格式什么的,输出在其内部的东西,任何特殊字符都不需要转义,变量会被正常的用其值来替换

简述GBK,GBK2312,BIG5,GB18030

GB2312支持的汉字较少,GBK是相比GB2312汉字更为丰富,包括全部的中日韩汉字

GB18030相比GBK增加了一些少数民族汉字汉字库更为多样,常人很少用

一般简体中文使用GBK而繁体中文使用BIG5

接口与抽象类的区别是什么?

抽象类:

抽象类是不能被实例化的类,只能作为其他类的父类来使用,抽象类是通过关键字abstract来声明

抽象类与普通类类似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少包含一个抽象方法

抽象方法没有方法体,该方法天生就是要被子类重写的

抽象方法的格式为:abstract function abstractMethod()

子类继承抽象类使用extends

接口:

接口是通过interface关键字来声明,接口中的成员常量和方法都是public的,方法可以不写关键字public

接口中的方法也是没有方法体的,接口中的方法也是天生要被子类实现的

接口能实现多继承

子类实现接口使用implements

谈谈对mvc的认识

MVC(Model/View/Controller)模式包括三类对象。

Model是应用对象,View是它在屏幕上的表示,Controller定义用户界面对用户输入的响应方式

模型(Model)模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑

视图(View) 视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面

控制器(controller) 控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态

php中传值与传引用的区别

按值传递:函数范围内对值的任何改变在函数外部都会被忽略

引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改

php5的构造函数和析构函数

__construct:这个函数将被当成是一个构造函数并在建立一个对象实例时被执行

__destruct:PHP将在对象被销毁前调用这个函数. 它称为析构函数

PHP编码

mysqli_real_connect()和mysqli_connect()有啥区别?

  • mysqli_real_connect() 要求一个由 mysqli_init() 创建的有效的对象
  • mysqli_real_connect() 可以与 mysqli_options() 一同使用来设置连接的不同选项
  • mysqli_real_connect() 有一个flag参数

遍历目录及子目录中的文件

这里可以用scandir(),或者glob()函数,这里有篇文章介绍了《四种方法》,在线代码中有两种方法

常规遍历方法

  1. /**
  2. * 获取当前目录及子目录下的所有文件
  3. * @param string $dir 路径名
  4. * @return array 所有文件的路径数组
  5. */
  6. function get_files($dir)
  7. {
  8. $files = array();
  9. if(!is_dir($dir)) {
  10. return $files;
  11. }
  12. $handle = opendir($dir);
  13. if($handle){
  14. while(false !== ($file = readdir($handle))) {
  15. if ($file != '.' && $file != '..') {
  16. $filename = $dir . "/" . $file;
  17. if(is_file($filename)) {
  18. $files[] = $filename;
  19. }else {
  20. $files = array_merge($files, get_files($filename));
  21. }
  22. }
  23. } // end while
  24. closedir($handle);
  25. }
  26. } // end function

使用glob

  1. <?PHP
  2. /**
  3. * 获取当前目录下的所有文件
  4. * @param string $dir 路径名
  5. * @return array 所有文件的路径数组
  6. */
  7. function get_files($dir) {
  8. $dir = realpath($dir) . "/";
  9. $files = array();
  10. if (!is_dir($dir)) {
  11. return $files;
  12. }
  13. $pattern = $dir . "*";
  14. $file_arr = glob($pattern);
  15. foreach ($file_arr as $file) {
  16. if (is_dir($file)) {
  17. $temp = get_files($file);
  18. if (is_array($temp)) {
  19. $files = array_merge($files, $temp);
  20. }
  21. }else {
  22. $files[] = $file;
  23. } // end if
  24. }
  25. return $files;
  26. } // end function
  27. ?>

使用directory 类

  1. /**
  2. * 递归显示当前指定目录下所有文件
  3. * 使用dir函数
  4. * @param string $dir 目录地址
  5. * @return array $files 文件列表
  6. */
  7. function get_files($dir) {
  8. $files = array();
  9. if (!is_dir($dir)) {
  10. return $files;
  11. }
  12. $d = dir($dir);
  13. while (false !== ($file = $d->read())) {
  14. if ($file != '.' && $file != '..') {
  15. $filename = $dir . "/" . $file;
  16. if(is_file($filename)) {
  17. $files[] = $filename;
  18. }else {
  19. $files = array_merge($files, get_files($filename));
  20. }
  21. }
  22. }
  23. $d->close();
  24. return $files;
  25. }

RecursiveDirectoryIterator类

  1. /**
  2. * 使用RecursiveDirectoryIterator遍历文件,列出所有文件路径
  3. * @param RecursiveDirectoryIterator $dir 指定了目录的RecursiveDirectoryIterator实例
  4. * @return array $files 文件列表
  5. */
  6. function get_files($dir) {
  7. $files = array();
  8. for (; $dir->valid(); $dir->next()) {
  9. if ($dir->isDir() && !$dir->isDot()) {
  10. if ($dir->haschildren()) {
  11. $files = array_merge($files, get_files($dir->getChildren()));
  12. };
  13. }else if($dir->isFile()){
  14. $files[] = $dir->getPathName();
  15. }
  16. }
  17. return $files;
  18. }
  19. $path = "/var/www";
  20. $dir = new RecursiveDirectoryIterator($path);
  21. print_r(get_files($dir));

给任意一段URL,取出该URL中包含的扩展名。如“http://www.pwstrick.com/test.php?somevar”,返回.php或php

使用了5种方法,pathinfo(),explode(),basename()、strpos()跟substr()的组合,

使用正则(可以参考我以前的一篇文章《JavaScript与PHP中正则》)以及parse_url()。查看在线代码。

PHP怎样防止SQL注入?

使用预处理语句参数化查询。预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。

这种方式使得攻击者无法注入恶意的SQL。 你有两种选择来实现该方法:PDO和MySQLI,查看在线代码。参考《PHP中该怎样防止SQL注入》

include、require、include_once与require_once的区别

  • include和require都是引入指定的文件。_once表示只引入一次,即之前已经引入过的不再引入。
  • 加载失败的处理方式不同:
    1. include在引入不存文件时产生一个警告且脚本还会继续执行,包含进来。通俗点儿讲就是:带上她!
    2. require则会导致一个致命性错误且脚本停止执行,有赖于这个文件。通俗点儿讲就是:我要她!
  • include是有条件包含函数,而 require则是无条件包含函数。
  • include()执行时需要引用的文件每次都要进行读取和评估,require()执行时需要引用的文件只处理一次(实际上执行时需要引用的文件内容替换了require()语句)
  • include有返回值,而require没有。参考《PHP中include require include_once require_once 的区别

shell命令方式向PHP传入参数的三种方式

使用argv;使用getopt函数();提示用户输入,然后获取输入的参数。参考《PHP传入参数

写一个函数,算出两个文件的相对路径,如 $a = "/a/b/c/d/e.php"; $b = "/a/b/12/34/c.php";计算出 $a 相对于$b 的相对路径应该是 "../../12/34/c.php"

先将两个字符串用“/”分割成数组,再用array_diff_assoc先检查b数组的差集。然后再$b$a做差集。查看在线代码

  1. <?php
  2. function calculateRelativePath($a,$b) {
  3. if (empty($a) || empty($b))
  4. return;
  5. $flag = "";
  6. $split1 = explode("/",$a);
  7. $split2 = explode("/",$b);
  8. $diff1 = array_diff_assoc($split1, $split2);
  9. $count = count($diff1 );
  10. for($i=0; $i < $count-1; $i++) {
  11. $flag .= "../";
  12. }
  13. $diff2 = array_diff_assoc($split2, $split1);
  14. return $flag. implode("/",$diff2);
  15. }
  16. $relative = calculateRelativePath("/a/b/c/d/e.php","/a/b/12/34/c.php");
  17. print_r($relative);

用php写出显示客户端IP、服务器端IP的代码和网页地址

客户端IP:$_SERVER["REMOTE_ADDR"]

服务器端IP:$_SERVER["SERVER_ADDR"]

网页地址:$_SERVER["REQUEST_URI"]

当前脚本的执行路径:$_SERVER["SCRIPT_FILENAME"]或者__FILE__

当前脚本的名称:$_SERVER["PHP_SELF"]或者$_SERVER["SERIPT_NAME"]

链接到前一页的URL地址:$_SERVER["HTTP_REFERER"]

error_reporting(2047)什么作用

error_reporting,设置应该报告何种 PHP 错误,这里是指显示所有的错误 E_ALL

echo,print(),print_r(),printf(),sprintf(),var_dump()有什么区别

echo:是语句不是函数,没有返回值,可输出多个变量值,不需要圆括号。不能输出数组和对象,只能打印简单类型(如int,string)

print:是语句不是函数,有返回值 1 ,只能输出一个变量,不需要圆括号。不能输出数组和对象,只能打印简单类型(如int,string)。

print_r:是函数,可以打印复合类型,例如:stirng、int、float、array、object等,输出array时会用结构表示,

而且可以通过print_r($str,true)来使print_r不输出而返回print_r处理后的值

printf:是函数,把文字格式化以后输出(参看C语言)

sprintf:是函数,跟printf相似,但不打印,而是返回格式化后的文字,其他的与printf一样。

var_dump:函数,输出变量的内容、类型或字符串的内容、类型、长度。常用来调试。

$a = 1; $x =&$a; $b=$a++; 求$b$x的值

$b=1,$x=2

php中对数组序列化和反序列化的函数,把utf-8转换成gbk的函数

serialize,unserialize,iconv("utf-8","gbk",$strs)

strlen()与mb_strlen的作用分别是什么?

strlen()无法正确处理中文字符串的占位,对于gb2312得到的是汉字个数的2倍,utf8得到的是汉字个数的3倍

mb_strlen()就很好的解决了这个问题,它的第二个参数就是设置字符编码的

用PHP能创建多级目录

mkdir($path, 0777, true);

mysql_num_rows()和mysql_affected_rows()的作用和区别

两者都是返回结果集中的行数,不同的是前者只对select操作有效,后者对update,insert,delete所影响的行数有效

请列举、你能想到的所有的字符串查找算法,并加注释简单说明

顺序查找,二分查找,分块查找,哈希表查找

根据下面的代码写出结果

  1. $a = 2;
  2. $b = &$a;
  3. unset($a);
  4. echo $b;

虽然使用了unset,释放给定的变量,仅仅是断开了变量名和变量内容之间的绑定,并不意味着变量内容被销毁了。所以输出结果为“2”。

  1. $a = 2;$b = 3;$c = &$a;$c = 2;
  2. if(($a=5)>0 || ($b=$a)>0) {
  3. $a++;$b++;
  4. }
  5. echo $a.'-'.$b.'-'.$c;

这里注意“||”这个符号,b=b还是3。

经过b++后,两个变量都加1,变成6和4。而a,那么值也变成6。最后输出结果为“6-4-6”。参考《PHP引用(&)使用详解》

写个函数来解决多线程同时读写一个文件的问题

首先用fopen打开某个文件,然后flock加锁,再用fwrite写内容,接着flock释放锁,最后fclose关闭文档。查看在线代码

lock

  1. <?php
  2. $fp = fopen("/tmp/lock.txt","w+");
  3. if(flock($fp, LOCK_EX)){// 进行排它型锁定
  4. fwrite($fp,"Write something here\n");
  5. flock($fp, LOCK_UN);// 释放锁定
  6. }else{
  7. echo "Couldn't lock the file !";
  8. }
  9. fclose($fp);

foo()和@foo()之间有什么区别?

foo()会执行这个函数,任何解释错误,语法错误,执行错误都会在页面上显示出来

@foo()在执行这个函数时,会隐藏上述的错误信息

sort(),asort(),ksort(),arsort(),rsort()各有什么区别

sort:对数组进行排序,当函数结束时数组单元将被从最低到最高重新安排

rsort:对数组进行逆向排序

asort:对数组进行排序并保持索引关系

arsort:对数组进行逆向排序并保持索引关系

ksort:对数组进行按照键名排序,保留键名到数据的关联,主要用于关联数组

什么是可变变量?以下程序的输入值是什么?

可变变量就是获取一个普通变量的值作为这个可变变量的变量名。输出值为“ok”。

  1. $str = 'cd';
  2. $$str = 'hotdog';
  3. $$str = 'ok';
  4. echo $cd;

echo count("abc")将会输出什么?

count()函数计算数组中的单元数目或者对象中的属性个数,通常是一个array()

对于对象,如果安装了 SPL,可以通过实现 Countable 接口来调用 count()。该接口只有一个方法count(),此方法返回count()函数的返回值。

如果参数不是数组型或者实现了countable接口的对象,将返回 1,只有一个例外,如果参数是NULL,则结果是 0。

GD库有什么作用?

GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片。

在网站上GD库通常用来生成缩略图或者用来对图片加水印或者对网站数据生成报表。

数据库

设一数据量为千万级的数据库,通过监控发现,有90%的查询请求都是指向同一部分数据的,而这部分数据只占整个数据库容量的1%。

  • 这种1%数据支撑了90%的查询工作,建义独立起来,这个方便数据在数据的buffer里,提高查询效率。
  • 分库:性能快速提升,如果效率还是上不去,可以考虑在那1%的数据上做一些nosql缓存。
  • 分表:能够在数据库缺少集群解决方案的情况下获得一定的横向扩展能力,同时负载也能分担到多台物理设备,从这个角度上讲也能解决一些性能瓶颈。
  • 如果有条件的话,此应用也可以通过缓存方案来解决,比如通过memcached,redis缓存1%结果集。

MySQL如何分库分表?

参考《MySQL分库分表环境下全局ID生成方案》,《第一次操刀数据库分表的教训与经验》,《mysql分库分表的一些技巧

MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?

  • 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。
  • 选择合适的表字段数据类型和存储引擎,适当的添加索引。
  • mysql库主从读写分离。
  • 找规律分表,减少单表中的数据量提高查询速度。
  • 添加缓存机制,比如memcached,apc等。
  • 不经常改动的页面,生成静态页面。
  • 书写高效率的SQL

关系数据库的瓶颈

Memcached+MySQL

随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。Memcached作为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务,在Memcached服务器上,又发展了根据hash算法来进行多台Memcached缓存服务的扩展,然后又出现了一致性hash来解决增加或减少缓存服务器导致重新hash带来的大量缓存失效的弊端。

MySQL主从读写分离

Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。

分表分库

随着web2.0的继续高速发展,MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。同时,开始流行使用分表分库来缓解写压力和数据增长的扩展问题。

MySQL的扩展性瓶颈

大数据量高并发环境下的MySQL应用开发越来越复杂,也越来越具有技术挑战性。分表分库的规则把握都是需要经验的。分库分表的子库到一定阶段又面临扩展问题。还有就是需求的变更,可能又需要一种新的分库方式。MySQL数据库也经常存储一些大文本字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库。大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题。

什么叫关系型数据库?

关系型数据库是支持采用了关系模型的数据库,简单来说,关系模型就是指二维表模型。

关系型数据库以行和列的形式存储数据,以便于用户理解。这一系列的行和列被称为表,一组表组成了数据库。

Linux基础

linux下查看当前系统负载信息的一些方法

参考《linux 下查看系统资源和负载,以及性能监控

网络基础

写出下列服务的用途和默认端口ftp、ssh、http、telnet、https

  • ftp文件传输协议是一种常见的文件拷贝方式,默认的是20用于数据连接,21用于控制连接端口。
  • ssh连接服务器执行操作,默认的是22端口号。
  • HTTP超文本传输协议,提供一种发布和接收HTML页面的方法,端口号为80
  • Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式,默认端口为23
  • HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版,默认端口为443

写出你能想到的所有HTTP返回状态值,并说明用途(比如:返回404表示找不到页面)

200 OK 请求成功(其后是对GET和POST请求的应答文档)

301 Moved Permanently 所请求的页面已经转移至新的url

302 Found 所请求的页面已经临时转移至新的url

304 Not Modified,服务器告诉客户,原来缓冲的文档还可以继续使用

401 Unauthorized 被请求的页面需要用户名和密码

403 Forbidden 对被请求页面的访问被禁止

500 Internal Server Error,请求未完成。服务器遇到不可预知的情况

502 Bad Gateway,请求未完成。服务器从上游服务器收到一个无效的响应

503 Service Unavailable 请求未完成。服务器临时过载或当机

POST和GET有什么区别?

a. GET是从服务器上获取数据,POST是向服务器传送数据

b. GET是通过发送HTTP协议通过URl参数传递进行接收,而POST是实体数据,通过表单提交

c. GET传送的数据量较小,不能大于2KB。POST传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB

d. GET安全性非常低,POST安全性较高

服务器基础

Apache与Nginx的优缺点比较

nginx相对于apache的优点:

轻量级,比apache 占用更少的内存及资源。高度模块化的设计,编写模块相对简单

抗并发,nginx 处理请求是异步非阻塞,多个连接(万级别)可以对应一个进程,而apache 则是阻塞型的,是同步多进程模型,一个连接对应一个进程,在高并发下nginx 能保持低资源低消耗高性能

nginx处理静态文件好,Nginx 静态处理性能比 Apache 高 3倍以上

apache 相对于nginx 的优点:

apache 的rewrite 比nginx 的rewrite 强大 ,模块非常多,基本想到的都可以找到 ,比较稳定,少bug ,nginx 的bug 相对较多

原因:

得益于Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(freebsd)网络I/O模型,而Apache则使用的是传统的select模型。

目前Linux下能够承受高并发访问的 Squid、Memcached都采用的是epoll网络I/O模型。

处理大量的连接的读写,Apache所采用的select网络I/O模型非常低效。

参考《Apache与Nginx的优缺点比较

Memcached和Redis区别

a. Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。

b. Redis在很多方面具备数据库的特征,或者说就是一个数据库系统,而Memcached只是简单的K/V缓存。

c. 在100k以上的数据中,Memcached性能要高于Redis。

d. 如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。

e. 如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。

f. Redis和Memcache在写入性能上面差别不大,读取性能上面尤其是批量读取性能上面Memcache更强。

参考《Redis和Memcached的区别


参考资料:
PHP饭米粒
PHP面试题目搜集

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注