PHP⾯试经常被问到的问题(附答案)
PHP⾯试经常被问到的问题(附答案)
回答问题时带上你⾃⼰的理解会更好。
倾情整理,希望每道题都可以举⼀反三,防⽌被⾯试官挖坑。
⼀、PHP⽅⾯的问题
1.什么是composer?以及composer是⼲什么⽤的?⼯作原理
composer是⼀个依赖管理⼯具,composer会帮你安装这些依赖的库⽂件;
⽐如composer可以解决⾃动加载类,不⽤你写过多的new。
2.PHP如何实现静态化
PHP的静态化分为:纯静态和伪静态。其中纯静态⼜分为:局部纯静态和全部纯静态。
PHP伪静态:利⽤Apache mod_rewrite实现URL重写的⽅法;
PHP纯静态,就是⽣成HTML⽂件的⽅式,我们须要开启PHP⾃带的缓存机制,即ob_start来开启缓存。
3.你了解设计模式吗?说下你最常⽤的设计模式
4.观察者模式是如何实现的?⼯⼚模式是如何实现的?适配器模式是如何实现的?
观察者模式:定义了对象之间的⼀对多依赖,这样⼀来,当⼀个对象改变状态时,它的所有依赖者都会收到通知并且有所作为。即出版者
+订阅者=观察者模式。
⼯⼚模式 :将调⽤者和创建者分离,调⽤者直接向⼯⼚类请求获取调⽤对象,减少代码耦合,提⾼系统的维护性和扩展性;
⼯⼚模式应⽤场景:有多个产品类时就要⽤到⼯⼚模式,⽐如在数据库连接中,我们可以采⽤多种数据库连接⽅法,有mysql扩展,mysqli 扩展,PDO扩展等,在这种情况下我们可以⼀个扩展对应⼀个产品类,然后采⽤⼯⼚模式。
适配器模式核⼼思想:把对某些相似的类的操作转化为⼀个统⼀的“接⼝”(这⾥是⽐喻的说话)–适配器,
或者⽐喻为⼀个“界⾯”,统⼀或屏蔽了那些类的细节。适配器模式还构造了⼀种“机制”,使“适配”的类可以很容易的增减,⽽不⽤修改与适配器交互的代码,符
合“减少代码间耦合”的设计原则。
5.PHP的优化⽅案
常⽤性能优化⽅案
1.使⽤单引号替换双引号,单引号在运⾏的时候不检查运⾏引号内部的变量,执⾏效率是双引号的两倍;
2.使⽤PHP内置的数组操作⽅法,PHP内置的数组操作⽅法的运⾏效率是⾃⾏编写代码的10倍以上;
3.使⽤字符串函数替换正则函数,例如:使⽤ str_replace 替换 preg_replace;
a5)替换strlen(
4.使⽤isset(a)>5;
查⽂件的速度,解析操作系统路径所需时间会更少。
循环优化⽅案
1.在执⾏for循环之前确定最⼤循环数,不要把count/strlen/sizeof等每次都要重复做的但结果都⼀样的事情放到for循环的条件语句中,另外最好运⽤foreach代替for循环;
2.禁⽌在循环内部查询数据库,应将查询放在循环外部;
3.循环内部不宜使⽤@操作符;
4.循环内部不宜声明变量,尤其是⼤变量:对象,解决办法是循环之前预定义需要声明的变量。
6.说下你了解的session和cookie
(1)、存储位置不同:
cookie的数据信息存放在客户端浏览器上。
session的数据信息存放在服务器上;
(2)、存储容量不同:
单个cookie保存的数据<=4KB,⼀个站点最多保存20个Cookie。
对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制;
(3)、存储⽅式不同:
cookie中只能保管ASCII字符串,并需要通过编码⽅式存储为Unicode字符或者⼆进制数据。session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。
(4)、隐私策略不同:
cookie对客户端是可见的,别有⽤⼼的⼈可以分析存放在本地的cookie并进⾏cookie欺骗,所以它是不安全的。
session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。
(5)、有效期上不同:
开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
session依赖于名为JSESSIONID的cookie,⽽cookie JSESSIONID的过期时间默认为-1,只需关闭窗⼝该session就会失效,因⽽session不能达到长期有效的效果。
(6)、服务器压⼒不同:
cookie保管在客户端,不占⽤服务器资源。对于并发⽤户⼗分多的⽹站,cookie是很好的选择。
session是保管在服务器端的,每个⽤户都会产⽣⼀个session。假如并发访问的⽤户⼗分多,会产⽣⼗分多的session,耗费⼤量的内存。(7)、浏览器⽀持不同:
假如客户端浏览器不⽀持cookie:
cookie是需要客户端浏览器⽀持的,假如客户端禁⽤了cookie,或者不⽀持cookie,则会话跟踪会失效。关于WAP上的应⽤,常规的cookie就派不上⽤场了。
运⽤session需要使⽤URL地址重写的⽅式。⼀切⽤到session程序的URL都要进⾏URL地址重写,否则session会话跟踪还会失效。
假如客户端⽀持cookie:
cookie既能够设为本浏览器窗⼝以及⼦窗⼝内有效,也能够设为⼀切窗⼝内有效。
session只能在本窗⼝以及⼦窗⼝内有效。
(8)、跨域⽀持上不同:
cookie⽀持跨域名访问。centos关闭rpcbind服务
session不⽀持跨域名访问
7.如何实现不基于session和cookie的⽤户认证。
将⽤户信息加密放到http的header部分,每次拿到http的时候,验证获取header的信息。
8.说下你⽬前框架所⽤到的核⼼概念
主要说下⽬前所⽤框架的好处以及为什么要⽤这个框架。
⽐如:免费的,代码开源,类库强⼤,易扩展,上⼿容易等等。
TP框架:
ThinkPHP(FCS)是⼀个轻量级的中型框架,是从Java的Struts结构移植过来的中⽂PHP开发框架。它
使⽤⾯向对象的开发结构和MVC模式,并且模拟实现了Struts的标签库,各⽅⾯都⽐较⼈性化,熟悉J2EE的开发⼈员相对⽐较容易上⼿,适合php框架初学者。ThinkPHP的宗旨是简化开发、提⾼效率、易于扩展,其在对数据库的⽀持⽅⾯已经包括MySQL、MSSQL、Sqlite、PgSQL、 Oracle,以及PDO的⽀持。ThinkPHP有着丰富的⽂档和⽰例,框架的兼容性较强,但是其功能有限,因此更适合⽤于中⼩项⽬的开发。
Easyswoole框架:
EasySwoole是⼀款常驻内存型的分布式swoole框架,专为API⽽⽣,⽀持同时混合监听HTTP、WebSocket、⾃定义TCP、UDP协议,且拥有丰富的组件,例如协程 连接池、TP风格的协程ORM、协程SDK、协程⽀付宝SDK、协程Kafka客户端、协程ElasticSearch客户端、协程Consul客户端、协程Redis客户端、协程Apollo客户端、协程NSQ客户端、协程⾃定义队列、 协程Memcached客户端、协程视图引擎、JWT、协程RPC、协程SMTP客户端、协程HTTP客户端、协程Actor、Crontab定时器等诸多组件。让开发者以最低的学习成本和精⼒编写出多进程,可异步,⾼可⽤的应⽤服务。
9.什么是CSRF攻击,XSS攻击?如何防范
CSRF(Cross-site request forgery)跨站请求伪造,⿊客建⽴⼀个伪造⽹站或发送邮箱带了⼀个正常URL链接来让正常⽤户访问,来让正常⽤户让⾃⼰浏览器⾥的COOKIE权限来执⾏⼀些⾮法请求,
如转账,提权等操作,
防范⽅法有,验证 HTTP Referer 字段;在请求地址中添加 token 并验证;
XSS攻击
主要将XSS代码提交存储在服务器端(数据库,内存,⽂件系统等),下次请求⽬标页⾯时不⽤再提交XSS代码。当⽬标⽤户访问该页⾯获取数据时,XSS代码会从服务器解析之后加载出来,返回到浏览器做正常的HTML和JS解析执⾏,XSS攻击就发⽣了。
防范⽅法:通过过滤是针对⾮法的HTML代码包括单双引号等,使⽤htmlspecialchars()函数
10.你了解RESTful API吗?说说⼲什么⽤的。
正确的函数指针定义RESTful API是REST风格的API,是⼀套⽤来规范多种形式的前端和同⼀个后台的交互⽅式的协议。RESTful API由后台也就是SERVER 来提供前端来调⽤;前端调⽤API向后台发起HTTP请求,后台响应请求将处理结果反馈给前端。
11.设计的原则
⼀般认为遵从以下六⼤原则的代码是可扩展易维护⾼复⽤的代码:
(1)、单⼀职责原则
不要多管闲事。
(2)、开放封闭原则
对扩展开放,对修改封闭
(3)、⾥⽒代换原则
⼦类可以实现⽗类的抽象⽅法,但不能覆盖⽗类的⾮抽象⽅法。
⼦类中可以增加⾃⼰特有的⽅法。
当⼦类的⽅法重载⽗类的⽅法时,⽅法的前置条件(即⽅法的形参)要⽐⽗类⽅法的输⼊参数更宽松。
当⼦类的⽅法实现⽗类的抽象⽅法时,⽅法的后置条件(即⽅法的返回值)要⽐⽗类更严格。
引⾃⼤话设计模式⼀书 p41
“⾥⽒代换原则是Barbara Liskov ⼥⼠ 在1988 年发表的【ASD】,具体的数学定义⽐较复杂,你可以查相关资料,它的⽩话翻译就是⼀个软件实体如果使⽤的是⼀个⽗类的话,那么⼀定适⽤于其⼦类,⽽且它观察不出⽗类对象和⼦类对象的区别,也就是说,在软件⾥⾯,把⽗类都替换成它的⼦类,程序的⾏为没有变化,简单地说,⼦类型必须能够替换掉它们的⽗类型【ASD】” .
⾥⽒代换原则(LSP):⼦类型必须能替换掉它们的⽗类型。【ASD】
“这好像是学继承时就要理解的概念,⼦类继承了⽗类,所以⼦类就可以以⽗类的⾝份出现。”
“是的,我问你个问题,如果在⾯向对象设计时,⼀个鸟类,⼀个是企鹅类,如果鸟是可以飞的,企业是不会飞,那么企业是鸟吗?企鹅可以继承鸟这个类吗?”
“企鹅是⼀种特殊的鸟,尽管不能飞,但它也是鸟,当然可以继承。”
“哈,你上当了,我说的是在⾯象对象设计时,那⼜意味什么那?⼦类拥有⽗类所有⾮private的⾏为和属性。鸟会飞,⽽企鹅不会飞,尽管在⽣物学分类上,企鹅是⼀种鸟,但在编程世界⾥,企鹅不能以⽗类–鸟的⾝份出现,因为前提说所有鸟都能飞,企鹅飞不了,所以,企鹅不能继承鸟类。”
(4)、接⼝隔离原则
(5)、依赖倒转原则
(6)、迪⽶特法则–最少知道原则
这六⼤原则任何⾯向对象的语⾔都应该遵守,好的代码不⼀定是严格按照设计模式写的代码,如果你的代码符合这六⼤原则,那么你的代码就是好代码,所以这六⼤原则还是很重要的。
12.如何实现⾃动加载?不⽤composer如何实现?PSR-4是什么?
⾃动加载就是当我们在当前⽂件中实例化⼀个不存在的类时,调⽤⾃动加载机制引⼊相应的类⽂件。
注:⾃动加载有两种⽅式(都是php内置的),⼀种是通过__autoload(),另⼀种是通过spl_autoload_register()。
PSR是PHP Standards Recommendation的简称,制定的代码规范,简称PSR,是代码开发的事实标准。
write as原神
PSR-4使代码更加规范,能够满⾜⾯向package的⾃动加载,它规范了如何从⽂件路径⾃动加载类,同时规范了⾃动加载⽂件的位置。⼆、数据库⽅⾯
1.你知道nosql吗?你⽤的nosql都有哪些?
NoSQL 即⾮关系型数据库的统称
NoSQL其实就是关系型数据库的补充,就⽬前⽽⾔我们是不可能离开关系型数据库的,所以NoSQL就来弥补关系型数据库在某些情况下的不⾜。这⾥把常见的NoSQL分为4类:K-V类、⽂档型、列式存储型、全⽂搜索型。
我常⽤nosql主要有Redis、MongoDB、MemcacheDB;
为什么要⽤NOSQL? 为了处理超⼤量的数据。
索引其实是⼀种数据结构,其功能是帮助我们快速匹配查到需要的数据⾏,是数据库性能优化最常⽤的⼯具之⼀。其作⽤相当于超市⾥的导购员、书本⾥的⽬录。
索引的类型:主键索引、唯⼀索引、普通索引、组合索引、全⽂索引;
索引⼀经创建不能修改,如果要修改索引,只能删除重建。
索引设计的原则
(1)适合索引的列是出现在where⼦句中的列,或者连接⼦句中指定的列;
(2)基数较⼩的类,索引效果较差,没有必要在此列建⽴索引;
(3)使⽤短索引,如果对长字符串列进⾏索引,应该指定⼀个前缀长度,这样能够节省⼤量索引空间;
(4)不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进⾏更新甚⾄重构,索引列越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。
注意事项:
a. 更新⼗分频繁的字段上不宜建⽴索引:因为更新操作会变更B+树,重建索引。这个过程是⼗分消耗数据库性能的。
b. 区分度不⼤的字段上不宜建⽴索引:类似于性别这种区分度不⼤的字段,建⽴索引的意义不⼤。因为不能有效过滤数据,性能和全表扫描相当。另外返回数据的⽐例在30%以外的情况下,优化器不会选择使⽤索引。
c. 业务上具有唯⼀特性的字段,即使是多个字段的组合,也必须建成唯⼀索引。虽然唯⼀索引会影响insert速度,但是对于查询的速度提升是⾮常明显的。另外,即使在应⽤层做了⾮常完善的校验控制,只要没有唯⼀索引,在并发的情况下,依然有脏数据产⽣。
d. 多表关联时,要保证关联字段上⼀定有索引。
e. 创建索引时避免以下错误观念:索引越多越好,认为⼀个查询就需要建⼀个索引;宁缺勿滥,认为索引会消耗空间、严重拖慢更新和新增速度;抵制唯⼀索引,认为业务的唯⼀性⼀律需要在应⽤层通过“先查后插”⽅式解决;过早优化,在不了解系统的情况下就开始优化。
输出一个二维数组
MYSQL ⼋⼤优化⽅案
(1)、选取最适⽤的字段属性
(2)、使⽤(JOIN)连接来代替⼦查询(Sub-Queries)
(3)、使⽤联合(UNION)来代替⼿动创建的临时表
mysql面试题目及答案(4)、事务
(5)、锁定表
(6)、使⽤外键
(7)、使⽤索引
(8)、优化的查询语句
MySQL 事务主要⽤于处理操作量⼤,复杂度⾼的数据。⽐如说,在⼈员管理系统中,你删除⼀个⼈员,你既需要删除⼈员的基本资料,也要删除和该⼈员相关的信息,如信箱,⽂章等等,这样,这些数据库操作语句就构成⼀个事务!
在 MySQL 中只有使⽤了 Innodb 数据库引擎的数据库或表才⽀持事务。
事务处理可以⽤来维护数据库的完整性,保证成批的 SQL 语句要么全部执⾏,要么全部不执⾏。
mysql从入门到精通下载事务⽤来管理 insert,update,delete 语句
⼀般来说,事务是必须满⾜4个条件(ACID)::原⼦性(Atomicity,或称不可分割性)、⼀致性(Consistency)、隔离性(Isolation,⼜称独⽴性)、持久性(Durability)。
原⼦性:⼀个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间
某个环节。事务在执⾏过程中发⽣错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执⾏过⼀样。
⼀致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表⽰写⼊的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以⾃发性地完成预定的⼯作。
隔离性:数据库允许多个并发事务同时对其数据进⾏读写和修改的能⼒,隔离性可以防⽌多个事务并发执⾏时由于交叉执⾏⽽导致数据的不⼀致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串⾏化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
数据量增多,单机的数据库不⾜以⽀撑业务,需要⽤到数据库集。⽽读写分离,就是将数据库的读和写分离,对应到数据库⼀般就是主从数据库,⼀主⼀从或者⼀主多从;业务服务器把数据写到主数据库中,读操作都去从库读;主库会同步数据到从库,保证数据的⼀致性。读写分离理解和实现相对简单,但是只能减少访问的压⼒,不能分担存储的压⼒,当数据增多是,查询的速度还是会很慢。这时候就需要⽤到分库分表了。
正常情况下,单机不能⽀撑业务时,才会⽤数据库集,软件设计越简单的设计越好。
⼀般数据库的优化是,先优化⼀些查询操作,然后优化业务的逻辑,或者加⼊缓存,最后不⾏再⽤集,最后再分库分表。
6.消息队列如何实现
从本质上说消息对列就是⼀个队列结构的中间件,也就是说消息放⼊这个中间件之后就可以直接返回,并不需要系统⽴即处理,⽽另外会有⼀个程序读取这些数据,并按顺序进⾏逐次处理。
也就是说当你遇到⼀个并发特别⼤并且耗时特别长同时还不需要⽴即返回处理结果,使⽤消息队列可以解决这类问题。
7.查询优化
⼀个查询的⽣命周期⼤致可以按照顺序来看:从客户端,到服务器,然后在服务器上进⾏解析,⽣成执⾏计划,执⾏,并返回结果给客户端。其中在“执⾏”阶段包含了⼤量为了检索数据到存储引擎的调⽤以及调⽤后的数据处理,包括排序、分组。
查询速度慢的原因在于:某些不必要的额外操作,某些操作被额外地重复很多次,某些操作执⾏得太慢。
优化查询的⽬的就是减少和消除这些操作所花费的时间。
8.msyql的存储引擎,以及各⾃的区别
InnoDB 是事务型数据库的⾸选引擎,⽀持事务安全表(ACID),⽀持⾏锁定和外键。MySQL5.5.5之后,InnoDB 作为默认的存储引擎,InnoDB 主要特性有:
⽀持事务
灾难恢复性好
为处理巨⼤数据量的最⼤性能设计
实现了缓冲管理,不仅能缓冲索引也能缓冲数据,并且会⾃动创建散列索引以加快数据的获取
⽀持外键完整性约束。存储表中的数据时,每张表的存储都按逐渐顺序存放,如果没有显⽰在表定义时指定主键,InnoDB会为每⼀⾏⽣成⼀个6B的ROWID,并以此作为主键。
被⽤在众多需要⾼性能的⼤型数据库站点上
MyISAM 基于 ISAM 的存储引擎,并对其进⾏扩展。它是在Web、数据存储和其他应⽤环境下最常使
⽤的存储引擎之⼀。MyISAM 拥有较⾼的插⼊、查询速度,但不⽀持事务。在 MySQL5.5.5 之前的版本中,MyISAM 是默认的存储引擎。MyISAM 主要特性有:
不⽀持事务
使⽤表级锁,并发性差
主机宕机后,MyISAM表易损坏,灾难恢复性不佳
可以配合锁,实现操作系统下的复制备份、迁移
只缓存索引,数据的缓存是利⽤操作系统缓冲区来实现的。可能引发过多的系统调⽤且效率不佳
数据紧凑存储,因此可获得更⼩的索引和更快的全表扫描性能
可以把数据⽂件和索引⽂件放在不同⽬录
使⽤ MyISAM 引擎创建数据库,将产⽣3个⽂件。⽂件的名字以表的名字开始,扩展名指出⽂件类型:frm ⽂件存储表定义,数据⽂件的扩展名为 .MYD(MYData),索引⽂件的扩展名是 .MYI(MYIndex)。
Redis不仅仅⽀持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储;
Redis⽀持数据的备份,即master-slave模式的数据备份;
,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进⾏使⽤;
应⽤场景:
List:关注列表,粉丝列表,消息队列;
Set:Sets 集合的概念就是⼀堆不重复值的组合。利⽤Redis提供的Sets数据结构,可以存储⼀些集合性的数据,⽐如在微博应⽤中,可以将⼀个⽤户所有的关注⼈存在⼀个集合中,将其所有粉丝存在⼀个集合。
10.索引有哪些,你是如何做索引的?

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。