您现在的位置是:首页 > php php面试大全 (不定时更新) 马力 2021-11-22 11:07:44 【php】 3368人已围观 简介php 面试 #1. HTTP状态码详解 **HTTP状态码(响应码)用来表明HTTP请求是否已经成功完成.HTTP响应类型一共分五大类:消息响应,成功响应,重定向,客户端错误,服务器端错误.** ##(1)消息响应 **100 Continue (继续)** 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收, 且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应. 服务器必须在请求完成后向客户端发送一个最终响应. HTTP/1.1 可用 **101 Switching Protocol (切换协议)** 服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。 在发送完这个响应最后的空行后,服务器将会切换到 在Upgrade消息头中定义的那些协议。 只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP版本比旧版本更有优势, 或者切换到一个实时且同步的协议以传送利用此类特 性的资源。HTTP/1.1 可用 ##(2)成功响应 **200 OK (请求成功)** 成功的意义根据请求所使用的方法不同而不同. GET: 资源已被提取,并作为响应体传回客户端. HEAD: 实体头已作为响应头传回客户端 POST: 经过服务器处理客户端传来的数据,适合的资源作为响应体传回客户端. TRACE: 服务器收到请求消息作为响应体传回客户端. HTTP/0.9 可用 **201 Created(已创建)** 请求成功,而且有一个新的资源已经依据请求的需要而建立, 通常这是 PUT 方法得到的响应码. HTTP/0.9 可用 **202 Accepted (已创建)** 服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。 在异步操作的场合下,没有比发送这个状态码更方便的做法了。 返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作), 而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。 在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息, 以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。 HTTP/0.9 可用 **203 Non-Authoritative Information(未授权信息)** 服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合, 而是来自本地或者第三方的拷贝,如果不是上述情况,使用200状态码才是最合适的. HTTP/0.9 and 1.1 **204 No Content(无内容)** 该响应没有响应内容,只有响应头,响应头也可能是有用的. 用户代理可以根据新的响应头来更新对应资源的缓存信息. HTTP/0.9 可用 **205 Reset Content(重置内容)** 告诉用户代理去重置发送该请求的窗口的文档视图. HTTP/1.1 可用 **206 Partial Content(部分内容)** 当客户端通过使用range头字段进行文件分段下载时使用该状态码 HTTP/1.1 可用 ##(3)重定向 **300 Multiple Choice(多种选择)** 该请求有多种可能的响应,用户代理或者用户必须选择它们其中的一个. 服务器没有任何标准可以遵循去代替用户来进行选择. HTTP/1.0 and later **301 Moved Permanently(永久移动)** 该状态码表示所请求的URI资源路径已经改变,新的URL会在响应的Location:头字段里找到. HTTP/0.9 可用 **302 Found(临时移动)** 该状态码表示所请求的URI资源路径临时改变,并且还可能继续改变. 因此客户端在以后访问时还得继续使用该URI.新的URL会在响应的Location:头字段里找到. HTTP/0.9 可用 **303 See Other(查看其他位置)** 服务器发送该响应用来引导客户端使用GET方法访问另外一个URI. HTTP/0.9 and 1.1 **304 Not Modified(未修改)** 告诉客户端,所请求的内容距离上次访问并没有变化. 客户端可以直接从浏览器缓存里获取该资源. HTTP/0.9 可用 **305 Use Proxy(使用代理)** 所请求的资源必须统过代理才能访问到. 由于安全原因,该状态码并未受到广泛支持. HTTP/1.1 可用 **306 unused(未使用)** 这个状态码已经不再被使用,当初它被用在HTTP 1.1规范的旧版本中. HTTP/1.1 可用 **307 Temporary Redirect(临时重定向)** 服务器发送该响应用来引导客户端使用相同的方法访问另外一个URI来获取想要获取的资源. 新的URL会在响应的Location:头字段里找到.与302状态码有相同的语义, 且前后两次访问必须使用相同的方法(GET POST). HTTP/1.1 可用 **308 Permanent Redirect(永久重定向)** 所请求的资源将永久的位于另外一个URI上.新的URL会在响应的Location:头字段里找到. 与301状态码有相同的语义,且前后两次访问必须使用相同的方法(GET POST). HTTPbis (试验草案) ##(4)客户端错误 **400 Bad Request(错误请求)** 因发送的请求语法错误,服务器无法正常读取. HTTP/0.9 可用 **401 Unauthorized(未授权)** 需要身份验证后才能获取所请求的内容,类似于403错误. 不同点是.401错误后,只要正确输入帐号密码,验证即可通过. HTTP/0.9 可用 **402 Payment Required(需要付款)** 该状态码被保留以供将来使用.创建此代码最初的目的是为数字支付系统而用, 然而,到现在也没投入使用. HTTP/0.9 and 1.1 **403 Forbidden(禁止访问)** 客户端没有权利访问所请求内容,服务器拒绝本次请求. HTTP/0.9 可用 **404 Not Found(未找到)** 服务器找不到所请求的资源.由于经常发生此种情况, 所以该状态码在上网时是非常常见的. HTTP/0.9 可用 **405 Method Not Allowed(不允许使用该方法)** 该请求使用的方法被服务器端禁止使用, RFC2616中规定, GET 和 HEAD 方法不能被禁止. HTTP/1.1 可用 **406 Not Acceptable(无法接受)** 在进行服务器驱动内容协商后,没有发现合适的内容传回给客户端. HTTP/1.1 可用 **407 Proxy Authentication Required(要求代理身份验证)** 类似于状态码 401,不过需要通过代理才能进行验证. HTTP/1.1 可用 **408 Request Timeout(请求超时)** 客户端没有在服务器预备等待的时间内完成一个请求的发送.这意味着服务器将会切断和客户端的连接. 在其他浏览器中,这种响应更常见一些, 例如Chrome 和 IE9, 目的是为了使用HTTP 预连机制加快浏览速度. 同时注意,一些服务器不发送此种响应就直接切断连接. HTTP/1.1 可用 **409 Conflict(冲突)** 该请求与服务器的当前状态所冲突. HTTP/1.1 可用 **410 Gone(已失效)** 所请求的资源已经被删除. HTTP/1.1 可用 **411 Length Required(需要内容长度头)** 因服务器在本次请求中需要 Content-Length 头字段,而客户端没有发送. 所以,服务器拒绝了该请求. HTTP/1.1 可用 **412 Precondition Failed(预处理失败)** 服务器没能满足客户端在获取资源时在请求头字段中设置的先决条件. HTTP/1.1 可用 **413 Request Entity Too Large(请求实体过长)** 请求实体大小超过服务器的设置的最大限制,服务器可能会关闭HTTP链接并返回Retry-After 头字段. HTTP/1.1 可用 **414 Request-URI Too Long(请求网址过长)** 客户端请求所包含的URI地址太长,以至于服务器无法处理. HTTP/1.1 可用 **415 Unsupported Media Type(媒体类型不支持)** 服务器不支持客户端所请求的媒体类型,因此拒绝该请求. HTTP/1.1 可用 **416 Requested Range Not Satisfiable(请求范围不合要求)** 请求中包含的Range头字段无法被满足,通常是因为Range中的数字范围超出所请求资源的大小. HTTP/1.1 可用 **417 Expectation Failed(预期结果失败)** 在请求头 Expect 中指定的预期内容无法被服务器满足. HTTP/1.1 可用 ##(5)服务器端错误 **500 Internal Server Error(内部服务器错误)** 服务器遇到未知的无法解决的问题. HTTP/0.9 可用 **501 Not Implemented(未实现)** 服务器不支持该请求中使用的方法,比如POST 和 PUT.只有GET 和 HEAD 是RFC2616规范中规定服务器必须实现的方法. HTTP/0.9 可用 **502 Bad Gateway(网关错误)** 服务器作为网关且从上游服务器获取到了一个无效的HTTP响应. HTTP/0.9 可用 **503 Service Unavailable(服务不可用)** 由于临时的服务器维护或者过载,服务器当前无法处理请求. 这个状况是临时的,并且将在一段时间以后恢复. 如果能够预计延迟时间,那么响应中可以包含一个Retry-After:头用以标明这个延迟时间. 如果没有给出这个Retry-After:信息,那么客户端应当以处理500响应的方式处理它. 同时,这种情况下,一个友好的用于解释服务器出现问题的页面应当被返回, 并且,缓存相关的HTTP头信息也应该包含,因为通常这种错误提示网页不应当被客户端缓存. HTTP/0.9 可用 **504 Gateway Timeout(网关超时)** 服务器作为网关且不能从上游服务器及时的得到响应返回给客户端. HTTP/1.1 可用 **505 HTTP Version Not Supported(HTTP版本不受支持)** 服务器不支持客户端发送的HTTP请求中所使用的HTTP协议版本. HTTP/1.1 可用 #2.http请求中get和post方法的区别 ## (1)GET产生一个TCP数据包;POST产生两个TCP数据包。 * 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); * 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据) ##(2)post更安全 * post不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中 * GET方式传输的参数安全性低,因为传输的数据会显示在请求的URL中 * POST方式将表单内各个字段和内容放置在HTML HEADER中一起传送到Action属性所指定的URL地址,用户是看不到这个过程的。 ##(3)post发送的数据更大 * get有url长度限制,传送的数据量不超过2KB * POST方式传送的数据量比较大,一般被默认为没有限制,但是根据IIS的配置,传输量也是不同的 ##(4)post能发送更多的数据类型 * get只能发送ASCII字符,URL编码格式采用的是ASCII编码,而不是Unicode,即所有的非ASCII字符都要编码之后再传输 ##(5)post比get慢 * 因为post需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段 * 最重要的一条,post在真正接收数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据 * get会将数据缓存起来,而post不会可以做个简短的测试,使用ajax采用get方式请求静态数据(比如html页面,图片)的时候,如果两次传输的数据相同,第二次以后消耗的时间将会在10ms以内(chrome测试),而post每次消耗的时间都差不多。 ##(6)post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作目的是资源的获取,读取数据 # 3.php单引号,双引号区别 ## (1) 对变量的解析不同 *PHP 会解析双引号中的变量,而不会解析单引号中的变量。也就是说,如果使用单引号定义的字符串中出现变量,在输出时变量会被原样输出,不会解析成变量的值。而如果使用双引号定义的字符串中存在变量,在输出时变量会被解析为具体的值。 ## (2) 转义的字符不同 *单引号和双引号中都可以使用转义字符\,但是,在单引号定义的字符串中只能转义单引号和转义符本身,而在双引号定义的字符串中,PHP 可以转义更多的特殊字符比如 \r \t \n等等。 ## (3) 解析速度不同 * 因为单引号不需要考虑变量的解析,所以处理速度比双引号要快,我们在定义字符串时应该尽量遵循能用单引号尽量用单引号的原则。 * 如果在字符串中不需要加入变量或者单引号'和反斜杠\时,尽量使用单引号来定义字符串。因为省去了双引号检查处理转义字符和解析变量的时间,所以可以提高程序的运行效率。 # 4.大流量,高并发解决方案 ##(1)硬件方面: * CPU 从 32 位提升为 64 位 * 内存从 64GB 提升为 256GB(比如缓存服务器); * 磁盘从 HDD(Hard Disk Drive)提升为 SSD(固态硬盘(Solid State Drives)),有大量读写的应用 * 磁盘扩容,1TB 扩展到 2TB,比如文件系统 * 千兆网卡提升为万兆网卡 * 但是不管怎么提升硬件性能,硬件性能的提升不可能永无止尽,所以最终还是要靠分布式解决 ##(2)http 缓存 * 浏览器缓存: 当我们使用浏览器访问一些网站页面或者 HTTP 服务时, 根据服务器端返回的缓存设置响应头将响应内容缓存到浏览器, 下次可以直接使用缓存内容或者仅需要去 服务器端验证内容是否过期即可, 这样可以减少浏览器和服务器之间来回传输的数据量,节 省带宽,提升性能; * Nginx 缓存: 当用户访问时,Nginx 拦截到请求后先从 Nginx 本地缓存查询数据, 如果有并且没有过期,则直接返回缓存内容 * CDN 缓存: CDN 的全称是 Content Delivery Network,即内容分发网络。 CDN 是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器, 通过中心平台的负载均衡、内容分发、调度等 功能模块,使用户就近获取所需内容, 降低网络拥塞,提高用户访问响应速度和命中率。 CDN 的关键技术主要有内容存储和分发技术。 CDN 它本身也是一个缓存,它把后端应用的数据缓存起来, 用户要访问的时候,直接从CDN 上获取,不需要走后端的 Nginx, 以及具体应用服务器 Tomcat,它的作用主要是加速数据的传输, 也提高稳定性,如果从 CDN 上没有获取到数据,再走后端的Nginx 缓存 Nginx 上也没有,则走后端的应用服务器,CDN 主要缓存静态资源 ##(3)应用缓存 * 内存缓存: 在内存中缓存数据,效率高,速度快,应用重启缓存丢失 * 磁盘缓存: 在磁盘缓存数据,读取效率较之内存缓存稍低,应用重启缓存不会丢失 代码组件:Guava、Ehcache 服务器:Redis、MemCache ##(4)多级缓存 * 在整个应用系统的不同层级进行数据的缓存,多层次缓存,来提升访问效率; * 比如:浏览器 -> CDN -> Nginx -> Redis -> DB (磁盘、文件系统) * 经常需要读取的数据、频繁访问的数据、热点数据缓存、IO 瓶颈数据、计算昂贵的数据、无需实时更新的数据进行缓存 * 缓存的目的是减少对后端服务的访问,降低后端服务的压力 ##(5)集群 * 有一个单体应用,当访问流量很大无法支撑,那么可以集群部署,也叫单体应用水平扩容, * 原来通过部署一台服务器提供服务,现在就多部署几台,那么服务的能力就会提升。 * 部署了多台服务器,但是用户访问入口只能是一个, * 比如 www.web.com,所以就需要负载均衡,负载均衡是应用集群扩容后的必须步骤,集群部署后,用户的会话 session 状态要保持的话,就需要实现 session 共享。 * session 共享解决机制: ①可以把用户的session放在cookie但是不安全 ②可以把用户的session放在数据库中,但是网站是一个成千上万用户的网站,如果把session放在数据库中,会造成数据库压力太大,从而使得网站不能正常运转 ③可以把用户的session放在缓存服务器中,这是最好的解决方案是放在缓存服务器中 ##(6)拆分 * 应用拆分: 按照业务维度进行应用拆分,采用分布式开发; * 数据库拆分: 数据库拆分分为:垂直拆分和水平拆分 (分库分表) 按照业务维度把相同类型的表放在一个数据库,另一些表放在另一个数据库,这种方式 的拆分叫垂直拆分,也就是在不同库建不同表,把表分散到各个数据库 根据数据行的特点和规则,将表中的某些行切分到一个数据库,而另外的某些行又切分 到另一个数据库,这种方式的拆分叫水平拆分 单库单表在数据量和流量增大的过程中,大表往往会成为性能瓶颈,所以数据库要进行 水平拆分数据库拆分,采用一些开源方案,降低开发难度,比如:MyCat、Sharding-Sphere ## (7) 静态化 * 对于一些访问量大,更新频率较低的数据,可直接定时生成静态 html 页面,供前端访问,而不是访问 jsp * 常用静态化的技术:freemaker、velocity * 定时任务,每隔 2 分钟生成一次首页的静态化页面 * 页面静态化首先可以大大提升访问速度,不需要去访问数据库或者缓存来获取数据,浏 览器直接加载 html 页即可 * 页面静态化可以提升网站稳定性,如果程序或数据库出了问题,静态页面依然可以正常访问 ## (8)动静分离 * 采用比如 Nginx 实现动静分离,Nginx 负责代理静态资源,Tomcat 负责处理动态资源 * Nginx 的效率极高,利用它处理静态资源,可以为后端服务器分担压力动静分离架构示意图 * redis 和 nginx 并发量 5w 左右,tomcat 和 mysql700 左右,当然可以通过一些方式调整 ## (9)队列 * 采用队列是解决高并发大流量的利器 * 队列的作用就是:异步处理/流量削峰/系统解耦 * 异步处理是使用队列的一个主要原因,比如注册成功了,发优惠券/送积分/送红包/发短信/发邮件等操作都可以异步处理 * 使用队列流量削峰,比如并发下单、秒杀等,可以考虑使用队列将请求暂时入队, 通过队列的方式将流量削平,变成平缓请求进行处理,避免应用系统因瞬间的巨大压力而压垮 * 使用队列实现系统解耦,比如支付成功了,发消息通知物流系统,发票系统,库存 系统等,而无需直接调用这些系统; * 不是所有的处理都必须要实时处理、不是所有的请求都必须要实时告诉用户结果不是所有的请求都必须 100%一次性处理成功、不知道哪个系统需要我的协助来实现它的业务处理,保证最终一致性,不需要强一致性 ## (10)池化 * 对象池: 通过复用对象,减少对象创建和垃圾收集器回收对象的资源开销 ,实际项目采用对象池并不常见,主要在开发框架或组件的时候会采用 * 数据库连接池: 与数据库建立连接是一个消耗资源的过程,减少不必要的重复创建链接,充分利用单次建立的连接 * HttpClient 连接池 # 5.MySQL中常用存储引擎有哪些?它们相互之间有什么区别? [![](https://ask.qcloudimg.com/http-save/7454047/rprsh64crh.png?imageView2/2/w/1620)](https://ask.qcloudimg.com/http-save/7454047/rprsh64crh.png?imageView2/2/w/1620) ## (1)InnoDB InnoDB 从 MySQL5.5(2010年) 版本代替 MyISAM 成为默认引擎,可以说只要玩儿过 MySQL 的,都用过InnoDB,相比MyISAM强调性能,InnoDB 侧重于提供事务支持以及外部键等高级数据库功能。 特点: 支持事务。默认的事务隔离级别为可重复读(REPEATABLE-READ),通过MVCC(并发版本控制)来实现。 使用的锁粒度默认为行级锁,可以支持更高的并发;当然,也支持表锁。其实有这两点就足以奠定InnoDB在存储引擎中的霸主地位了。你知道的,使用场景真的太多了。 支持外键约束;外键约束其实降低了表的查询速度,但是增加了表之间的耦合度。 可以通过自动增长列,方法是auto_increment。 配合一些热备工具可以支持在线热备份; 在InnoDB中存在着缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度; 对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于B+数的叶子节点上; InnoDB 表的select count(*) 比 MyISAM 慢很多;当执行 select count(*) from t 时,会先把数据读出来,一行一行的累加,最后返回总数量。 是的,真的会很慢。需要注意的是,当count(*) 语句包含 where 条件时,两种表的操作是一样的。 DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。InnoDB的存储表和索引有下面两种形式:共享表空间存储:所有的表和索引存放在同一个表空间中。多表空间存储:表结构放在.frm文件,数据和索引放在.ibd文件中。分区表的话,每个分区对应单独的.ibd文件,分区表的定义可以查看我的其他文章。使用分区表的好处在于提升查询效率。 对于InnoDB来说,最大的优势在于支持事务,当然这是以牺牲效率为代价的。 ## (2)MyISAM 特点: 不支持事务。这也算特点???没错,就是这么不要脸。不支持事务,像是挣脱了枷锁,在读写(Insert、select)效率上,要高于InnoDB不少。场景在:日志记录、调查统计表时,绝对值得一用。对了,不支持事务,自然就不支持锁! 体积小,质量大。MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。同时能加载更多索引,而Innodb的索引和数据是紧密捆绑的,没有使用压缩从而会造成 Innodb 比 MyISAM 数据文件体积庞大很多。每张MyISAM表在磁盘上会对应三个文件。(1).frm文件:存储表的定义数据(2).MYD文件:存放表具体记录的数据(3).MYI文件:存储索引 从以往经验来说,select count(*) 和 order by 大概是使用最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的,很多人以为Innodb是行级锁,那个只是where对它主键是有效,非主键的还是会锁全表的。 常常应用部门需要我给他们定期某些表的数据,MyISAM的话很方便,只要发给他们对应那表的(frm.MYD,MYI)的文件,让他们自己在对应版本的数据库启动就行,而Innodb就需要导出.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。 如果和 MyISAM 比 Insert 写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,确实MyISAM会慢与InnoDB,但在并发环境下,从库同步也是个事儿,还不如通过多实例分库分表架构来解决。 MyISAM表的select count(*) 是非常快的;在 MyISAM 存储引擎中,把表的总行数(row)存储在磁盘上,当执行 select count(*) from t 时,直接返回总数据。同样,当 count(*) 语句包含 where条件时,两种表的操作是一样的。 DELETE FROM table时,MyISAM会先将表结构备份到一张虚拟表中,然后执行drop,最后根据备份重建该表。 ## (3)Memory 你可以将它理解为,临时表。没错,Memory是将数据直接存在内存中的,特别适合数据量小的表。同时为了提高数据的访问速度,每一个表实际上和一个磁盘文件关联,文件是frm。 特点: 支持的数据类型有限制,比如:不支持TEXT和BLOB类型。对于字符串类型的数据,只支持固定长度的行,VARCHAR(64)会被自动存储为CHAR(64)类型; 只支持表级锁。所以,在访问量比较大时,表级锁会成为MEMORY存储引擎的瓶颈; 由于数据是存放在内存中,一旦服务器宕机,数据就会丢失;数据库主从切换的配置要设置好。 查询的时候,如果有用到临时表,而且临时表中有BLOB,TEXT类型的字段,那么这个临时表就会转化为MyISAM类型的表,性能会急剧降低; 默认使用hash索引。 很赞哦! (2) 上一篇:laravel的上线配置操作 下一篇:php实现的滑动时间窗口的限流算法 相关文章 php面试题 随机图文 Ubuntu18.04虚拟机过一段时间无法上网 Ubuntu18.04虚拟机过一段时间无法上网 php常用的 命令行 php常用的 命令行 记录一下 MacOS 每次升级都会遇到的 xcrun: error: invalid active developer path 错误 记录一下 MacOS 每次升级都会遇到的 xcrun: error: invalid active developer path 错误 PHP面试八股文 PHP面试八股文 文章评论 评论总数:0来说两句吧... 用户名: 验证码: 点击排行 php中关于冬夏时令切换引发的问题 php代码更新到服务器上 代码没有立即生效篇 解决方法 php常用的 命令行 php面试题 php实现的滑动时间窗口的限流算法 PHP面试八股文 最近更新 PHP面试八股文 php实现的滑动时间窗口的限流算法 php面试大全 (不定时更新) php中关于冬夏时令切换引发的问题 php代码更新到服务器上 代码没有立即生效篇 解决方法 php面试题 php常用的 命令行