PHP面试宝典之PHP篇
PHP数组函数?
array_merge(合并)
array_unique(去重)
array_intersect(交集)
array_diff(差集)
array_map(回调)
array_values(重置索引)
array_flip(key=>value颠倒)
array_column(二维变一维)
explode(字符转数组)
implode(数组转字符)
array_keys(键组成的新数组)
array_count_values(元素重复的次数数组)
array_search(查询数组元素键名)
sort(值正序)
rsort(值倒序)
ksort(键正序)
rksort(键倒序)
serialize(序列化)
PHP字符串函数?
unserialize(反序列化)
explode(字符转数组)
str_split(字符转数组)
strlen(字符长度)
strrev(字符串反转)
strpos(检索指定字符)
str_replace(替换字符)
usfilst(首字转大写)
ucwords(每个单词首字母转大写)
strtoupper(全转大写)
strtolower(全转小写)
strtotime(转时间戳)
date(时间格式)
json_encode(数组转json)
json_decode(json转数组,不加true转对象)
ceil(向上取整)
round(四舍五入)
number_format(四舍五入,可保留小数点)
PHP魔术方法?
__construct(构造函数)
__destruct(析构方法)
__get(获取不存在属性)
__set(给不存在属性赋值)
__isset(对不可用属性调用isset)
__unset(对不可用属性调用unset)
__clone(复制对象完成)
__toString(把对象当字符串用)
__sleep(对象序列化之前)
PHP5和PHP7的区别?
性能提升两倍
许多致命错误,改成抛出异常
移除了一些老的不再支持的sapi和扩展
三元运算符新增了表达方式
新增了结合比较运算符
新增了函数返回类型声明
新增了参数类型声明
PHP7可以define定义常量数组
PHP7性能提升的原因?
变量存储字节减小,减少内存占用,提升变量操作速度
改善数组结构,数组元素和hash映射表被分配在同一内存里,降低了内存占用、提升了cpu缓存命中率
改善了函数调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
编译优化:加入抽象语法树,将编译和执行解耦,提高编译扩展性
执行器层面的优化:变量采用寄存器存储,不再通过参数传递,避免频繁的出入栈操作,访问速度更快
PHP数组是怎么实现的?
哈希表+双向链表
数值索引,散列值就是索引值
字符串索引,key通过time33算法计算得到散列值
foreach和for哪个更快?
foreach更快,foreach可以直接访问,数组的数组桶,利用next遍历;而for,需要通过key进行hash后才能直到元素位置,所以foreach更快
PHP生命周期?
模块初始化、请求初始化、执行脚本、请求关闭、模块关闭
cli模式:每次执行都会完整执行一遍
fast-cgi模式:只有在第一次时执行模块初始化,然后执行(请求初始化、执行脚本和请求关闭)
模块初始化:进行框架、zend引擎的初始化操作,master进程启动时执行
请求初始化:worker进程接收一个请求且读取、解析完请求数据的一个阶段
执行脚本:PHP代码编译、执行两个步骤
请求关闭:PHP脚本解释执行完成后,输出内容,发送http响应,清理全局变量、关闭编译器、关闭执行器等
模块关闭:sapi关闭时执行,与模块初始化对应,进行资源清理、关闭PHP各个模块
0、字符串0、空字符串、null、false五种类型的比较?
null是不存在,内存中没有值
字符串0和空字符串不相等,字符串0有长度,空字符没长度
0和空字符串相等,类型不同进行比较时,会做类型转换,空字符串转成0
字符串0和null不相等,0和null相等
变量的 值传递与引用传递的区别?
值传递:是单独复制了一份,无论怎么修改双方互不影响,只用=赋值即可
引用传递:是将变量的值指向同一个空间地址,两个变量之间是相互影响的
变量的类型转换函数:
intval,floatval,boolval,strval,settype(变量,type)
intval:遇到小数点就舍弃,字符类型数字开头保留数字,非数字开头直接为0,
判断变量类型函数:
is_string,is_array,is_bool,is_float,is_numeric,is_object
定义常量的方法:
define(name,value)
constant(常量名)
预定义数组:
$_POST、$_GET、$_COOKIE、$_SESSION、$_FILES、$GLOBALS
如何解决异常处理?
抛出异常:使用try……catch,异常代码放在try中监控,若异常被触发则抛出异常,catch负责捕获异常并使用getMessage输出错误信息
时间函数:
time:当前时间戳
date:将时间戳转化为时间格式
strtotime:将时间格式转化为时间戳秒
include和require的区别?
都是包含并运行指定文件
include:每次执行都要读取和评估,用到时加载,出错文件继续执行
require:只读取一次,多次执行时代码效率更高,一开始就加载,出错文件停止执行
empty和isset的区别?
empty:判断变量值是否为空或零
isset:检查变量是否被定义,且不是null,可以同时检查多个变量
当变量可能为0时,用isset,当变量可能不存在时,用empty
PHP安全处理,过滤函数:
sql注入:mysql_real_escape_string
xss攻击:html special char (将标签原样输出)
html字符串转化为标签输出:html_entity_decode
PHP读取文件方法?
file_get_contents,整个文件读入一个字符串中
2:fopen,打开一个文件或url
is_dir:判断是否是目录
scandir:列出指定路径下的目录和文件,包含.和…(当前目录和父级目录),按数组格式返回
file_exists:检查文件或目录是否存在
opendir:打开目录并返回,如果目录不存在或无权限,则报错,需要用@抑制错误
readdir:读取目录
双引号,单引号区别?
双引号解析变量,把变量的值显示出来
单引号原样输出,把变量名原样显示出来
PHP常用模版引擎:
模版引擎是解析视图模版中的一些规则,将静态页面转化为PHP代码文件
smarty:响应速度快,判断模版是否发生改变,是否调用缓存文件
blade:laravel内置模版引擎,提供了模版继承和区块的功能,{{}}语句可自动使用htmlspecialchars函数转义,防范xss攻击
ThinkTemplate:tp内置模版引擎,xml标签库技术的编译型模版引擎,支持两种类型的模版标签,使用了动态编译和缓存技术,而且支持自定义标签库
编译型语言和解释型语言:
java两个都是,两个都不是
一、编译型
编译型语言:预先编译一次(后续不在预编译),编译成可执行的机器语言文件,所以执行效率高
代表:c、c++
优点:执行效率高
缺点:跨平台能力弱,不便调试
二、解释型
解释型语言:不预先编译,执行时再翻译执行,每次执行都要重复,所以执行速度慢。
代表:php,python,JavaScript
优点:跨平台能力强,易于调试
缺点:执行速度慢
什么是面向对象?什么是面向过程?二者的区别?
面向对象:是事情的参与者,以及参与者需要做什么
面向过程:事情发展的步骤和顺序
面向过程:比较直接,清晰明了且性能更高
面向对象:更易于复用,扩展性,维护性更高,但实例化对象会导致性能稍弱
设计模式?
单例、工厂、策略、适配器、注册树、观察者模式
单例模式:在程序中,一个类只实例化一次
工厂模式:通过传参的方式,创建对应的对象,减少代码耦合,提高可维护性,可扩展性
注册树模式:以二维数组的形式,对多个对象进行存储和管理,供全局使用
观察者模式:一个对象被修改时,会自动通知依赖它的对象
PHP单线程还是多线程?
PHP是单线程,但服务器是多线程,每个请求都会创建一个新的进程/线程,当并发时,多个请求访问一个php,这样也算是一种多线程
接口六大设计原则?
单一职责、里氏替换、开闭、迪米特、接口隔离、依赖倒置
单一职责:一个接口,只干一件事
里氏替换原则:子类可以扩展父类,不可以改变父类的功能
开闭原则:一个方法对扩展开放,对修改关闭
迪米特法则:只与朋友间相互调用
接口隔离原则:接口尽量小,定制服务
依赖倒置原则:面向接口编程,通过抽象方法使类保证独立
加密算法?
thqs算法,微信使用算法
参数按字母升序,追加时间戳,md5加密,将结果和参数拼接,代替参数进行请求
jwt:一种认证方式;是一个开源标准
使用场景:
认证:用户登录成功后,随后的请求都会包含jwt,允许用户经过当前的jwt授权路由,服务或者资源
信息交换:
jwt header包含两部分:token类型,即jwt;使用的签名算法:hmac或者rsa
jwt payload:三种形式:注册,共有,私有
jwt signature:
jwt如何工作:
在认证过程中,当用户登录成功后,就会返回一个jwt token,每当用户希望访问一个被保护的路由或者资源,就应当发送jwt
为什么要用jwt
cookie会被拦截,容易被跨站请求伪造攻击
session开销大,扩展性低
php数据结构?
双向链表、栈、队列、堆、最大堆、最小堆、优先队列、阵列、映射
双向链表和单向链表的区别?
单向链表:只记录,当前节点的值,和下一个节点的链接
双向链表:不仅记录,当前节点的值,和下一个节点的链接,还记录上一个节点的链接
什么是链表?
一个被实例化的类,有两或三个属性,一个记录当前节点的值,另一个记录上一个节点,或下一个节点的链接(实例)
class node{ public $item; #当前节点存储元素 public $next; #指向下一个节点的地址 public function __construct($item, $next = null) { $this->item = $item; $this->next = $next; }}$node1 = new node(1);$node2 = new node(2);$node3 = new node(3);$node1->next = $node2;$node2->next = $node3;
数组和链表的顺序遍历的效率比较?
数组遍历比链表更快;因为,数组的地址空间是连续的,遍历时会将后续的元素一起放入缓存中,减少了对内存的访问;链表的元素是分散在内存中的,所以每次都要对内存进行访问,这样一来,效率自然不如数组
如何检测链表是否有环?
通过快慢指针判断,同时从链表头出发,快指针每次走2步,慢指针每次走1步,当快指针追上慢指针说明是环形链表,如果快指针走到末尾,说明不是环形
如何找到环的入口?
先判断是否有环,如果有,就将快指针挪到链表头部,再每次走1步,当快慢指针再次相遇时,就是环路入口
php垃圾回收机制?也叫gc机制?
利用引用计数实现;引用次数为0的变量进行回收(未使用)
当引用计数减少到非0时,会进入垃圾缓冲区,当缓冲区达到临界值(1万,PHP7.3是100)时,会触发垃圾回收算法,将所有变量遍历一遍,并将计数减1,判断是否为0,如果是就进行销毁
内存泄漏:
程序在申请内存后,无法释放已申请的内存;随着系统运行占用的内存会持续上升,可能会因为占用内存过高而崩溃,或被系统杀掉
内存溢出:
过多的内存泄漏,导致程序在申请内存时,没有足够的内存供申请者使用;内存不够用
内存溢出的原因和解决方案?
原因:
内存中加载的数据量过去庞大,如:一次获取数据库全部数据
集合类中对象的引用,使用完后未清空
死循环或循环产生过多重复对象
启动参数内存值设定过小
解决:
直接增加内存
检查错误日志
检查代码,分析出可能存在内存溢出的位置
1):检查是否一次获取数据库全部数据
2):检查是否死循环
3):检查是否有大循环重复产生新对象实体
4):检查list、map等集合对象,是否使用完后未清除
检查内存使用情况
PHP属于高级语言,并没有内存的概念,在使用过程中完全不需要主动申请或释放内存,所以php用户代码级别不存在内存泄漏的概念;如果php程序内存泄漏了,要么是没有及时释放大变量,要么就是第三方扩展本身实现内存问题
如果程序执行过程中内存不够怎么办?
可以临时分配内存,配置memory_limit属性即可,如果操作系统将内存分配给了该程序,那在它释放内存之前,该内存区域是不允许其他内存使用的
PSR代码规范?
- PSR-1:基本代码规范
PSR-1规定了PHP代码的基本风格和规范,包括以下内容:
PHP代码必须使用
PHP代码必须使用4个空格缩进;
PHP文件必须只包含PHP代码,不得包含尾随空格或空行;
PHP代码的行长度不得超过80个字符;
PHP代码文件必须以不带BOM的UTF-8编码保存;
PHP命名空间和类名必须遵循自动加载标准(PSR-4)
- PSR-2:代码风格规范
PSR-2扩展了PSR-1,并详细规定了PHP代码的风格和规范,包括以下内容:
PHP代码必须使用驼峰式命名;
常量必须使用大写字母和下划线命名,如 MY_CONSTANT;
类名必须以大写字母开头,如 MyClass;
方法名必须以小写字母开头,多个单词之间用下划线分隔,如 my_method_name;
PHP代码中的关键字必须全部小写,如 if、else、foreach、try;
代码中必须使用4个空格缩进,而不是制表符;
在函数和控制语句中必须加空格,如 if ($condition);
代码块必须用花括号括起来,即使代码只有一行;
所有 PHP 文件必须以一个空白行结束。
- PSR-3:日志记录接口规范
PSR-3规范了PHP日志记录接口,定义了一组公共接口和方法,使得不同的日志库可以相互替换。主要包括以下内容:
提供了8个不同的日志级别(debug、info、notice、warning、error、critical、alert、emergency);
提供了几个不同的日志方法(log、debug、info、notice、warning、error、critical、alert、emergency);
提供了上下文信息的方法,如 withContext、withExtra、withUser等;
日志信息必须包含时间戳、级别、消息和上下文信息。
- PSR-4:自动加载规范
PSR-4规范了PHP的自动加载机制,定义了一组规范,以便实现自动加载功能。主要包括以下内容:
定义了命名空间和类名的映射规则;
PHP类文件必须遵循一定的命名规则;
定义了自动加载的算法
- PSR-7:HTTP消息接口规范
PSR-7规范了HTTP消息的接口,包括HTTP请求和响应。主要包括以下内容:
提供了RequestInterface和ResponseInterface两个接口,以定义HTTP请求和响应对象的基本方法和属性;
提供了UriInterface接口,以定义URI(Uniform Resource Identifier)对象的方法和属性;
提供了StreamInterface接口,以定义数据流对象的方法和属性;
定义了Request、Response、Uri和Stream等具体实现类,以便开发者可以直接使用;
强制要求使用PSR-3规范的日志接口来记录HTTP请求和响应。
- PSR-11:容器接口规范
PSR-11定义了一个通用的容器接口,以便开发者可以在不同的PHP应用中使用不同的依赖注入容器。主要包括以下内容:
提供了一个容器接口,以定义容器对象的基本方法和属性;
容器对象必须支持将对象绑定到容器中、从容器中解析对象和检查容器中是否存在指定对象等基本操作;
定义了一些可选的、扩展容器的功能,如装饰器、别名、标签等。
- PSR-13:超媒体链接规范
PSR-13定义了超媒体链接的规范,包括以下内容:
定义了LinkInterface接口,以表示超媒体链接对象;
提供了Link对象的具体实现;
定义了解析和生成超媒体链接的方法。
- PSR-15:HTTP处理器规范
PSR-15规范了HTTP请求处理器的接口和规范,包括以下内容:
定义了MiddlewareInterface接口,以表示HTTP请求处理器对象;
定义了ServerRequestHandlerInterface接口,以表示HTTP请求处理器对象链的末端;
提供了RequestHandler对象的具体实现;
定义了中间件处理器的执行流程。
- PSR-16:简单缓存规范
PSR-16定义了一个简单的缓存接口规范,以方便PHP开发者在不同的应用中使用不同的缓存库。主要包括以下内容:
定义了一个缓存接口,以表示缓存对象的基本方法和属性;
缓存对象必须支持获取、设置、删除和检查缓存数据的基本操作;
定义了一些可选的、扩展缓存功能的方法。
来源地址:https://blog.csdn.net/qq_38989173/article/details/130450348
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341