PHP一些面试题

原创
2019/09/07 01:57
阅读数 41

Web篇

1. 谈谈对Web语义化的理解

语义化的含义就是用正确的标签做正确的事情,语义化让网页的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析,利于SEO,也有利于代码阅读、便于维护。

2. 写出一个使用flex布局,在div垂直居中的css代码

div {
    display: flex;
    justify-content: center;
    align-items: center;
}

3. 为什么把JavaScript放在html底部

  • 因为浏览器渲染HTML文件是从上往下渲染的,JavaScript放在HTML头部,会阻碍浏览器的渲染速度,增加用户的等待时间
  • 浏览器加载 JavaScript 脚本之后会自动执行,如果放在头部,此时的Dom还没有加载完,很容易出现BUG。

4. 谈谈对 JavaScript 闭包的理解

闭包是 JavaScript 函数的一种,声明即运行,可以在函数内容调用外部变量。

5. 如何处理Ajax跨域问题

  • 代理
  • Jsonp
  • iframe
  • cors

6. 一句话解释JsonP的原理

Jsonp,即 json padding,原理就是利用 <script>标签没有跨域限制达到与第三方通讯的目的。

前端扩展阅读

协议篇

1. 网络协议有哪些?

  • 应用层:HTTP、FTP、SSH、SMTP、SFTP
  • 表示层
  • 会话层
  • 传输层:TCP、UDP
  • 网络层:IP
  • 数据链路层
  • 物理层

2. 简述HTTP协议的工作流程

  1. 地址解析——在浏览器中输入URL,浏览器会从中解析出协议名、主机名、端口、对象路径等部分
  2. 封装HTTP请求数据包
  3. 浏览器获取主机 IP 地址,建立 TCP 连接(TCP的三次握手)
  4. TCP链接建立后发送HTTP请求
    • 请求方式的格式为:统一资源标识符(URL)、协议版本号、后面是 MIME 信息包括请求修饰符、客户机信息和可用内容
  5. 服务器接到请求后,给予相应的响应信息
    • 其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是 MIME 信息包括服务器信息、实体信息和可能的内容
  6. 服务器断开 TCP 连接

3. 什么是HTTPS?实现过程是什么?

HTTPS (超文本传输安全协议)是一种通过计算机网络进行安全通信的传输协议,提供对网站服务器的身份认证,保护数据传输的完整性、安全性。

实现过程:

  1. 客户端发起一个 https 的请求
  2. 服务端接收客户端请求,返回数字证书相关信息
  3. 客户端收到服务端响应
    1. 验证证书的合法性
    2. 如果证书受信任,生成随机数的密码
    3. 使用约定好的HASH算法计算握手信息,并使用生成的随机数对消息进行加密,然后发送给服务端
  4. 网站接收浏览器发来的密文后
    1. 使用私钥来解密握手消息取出随机密码,再用随机密码解密,握手消息与HASH值,并与传过来的HASH值对比确认是否一致
    2. 使用密码加密一段握手消息,发送给浏览器
  5. 浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据,将由之前的浏览器生成的随机密码,并利用对加密算法进行加密。

4. 数字证书都包括哪些信息?

  • 证书的版本信息;
  • 证书的序列号,每个证书都有一个唯一的证书序列号;
  • 证书所使用的签名算法;
  • 证书的发行机构名称;
  • 证书的有效期;
  • 证书所有人的名称、公开密钥;
  • 证书发行者对证书的签名;

5. TCP 三次握手的流程

  • 客户端发送一个 SYN 标志位置 1 的包,指明客户端要连接服务器端的接口,发送完毕后,客户端进入SYN_SEND 状态。
  • 服务器发回确认包(ACK)应答。即 SYN 标志和 ACK 标志位均为 1。服务端选择自己的 ISN 序列号,放到Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加 1,即 X + 1。发送完毕后,服务器端进入 SYN_RCVD 状态。
  • 客户端再次发送确认包(ACK),SYN 标志位为 0,ACK 标志位为 1,并且把服务器发来 ACK 的序号字段 +1,放在确定字段中发送给对方,并且在数据段放写 ISN 的 +1。
  • 发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。

6. 什么是Socket?工作流程是怎样的?

Socket 又称 网络套接字,是一种操作系统提供的进程间通信机制。

工作流程:

  1. 服务端先用Socket函数来建立一个套接字,并调用 listen 函数,使服务端的这个端口和 IP 处于监听状态,等待客户端的连接
  2. 客户端用 socket 函数建立一个套接字,设定远程 IP 和端口,并调用connect函数
  3. 服务端用 accept 函数来接受远程计算机的连接,建立起与客户端之间的通信
  4. 完成通信以后,最后使用 close 函数关闭 socket 连接

7. HTTP 1.1 与 WebSocket 的区别?

  • HTTP 是一种单链接,只能单向通讯,而 WebSocket 是一个持久连接,可用作双向通讯。
  • WebSocket 是基于 HTTP 来建立连接的,但在建立连接之后,真正的数据传输阶段是不需要 HTTP 协议参与的
  • WebSocket 的请求的头部和 HTTP 请求头部不同
  • WebSocket 传输的数据是二进制流,是以帧为单位,HTTP 是明文字符串传输

8. 什么是 OAuth 2.0 协议?运行流程是怎么样的?

OAuth(Open Authorization)协议为用户资源的授权提供了一个安全的、开放而有简易的标准,第三方无需使用用户的用户名与密码,就可以申请获得该用户资源的授权。

运行流程:

  1. 用户打开客户端以后,客户端要求用户给予授权
  2. 用户同意给予客户端授权
  3. 客户端使用上一步获得的授权,向认证服务器申请令牌
  4. 认证服务器对客户端进行认证以后,确认无误,同意发放令牌
  5. 客户端使用令牌,向资源服务器申请获取资源
  6. 资源服务器确认令牌无误,同意向客户端开放资源

OAuth 2.0 定义了四种授权方式,授权码模式、简化模式、密码模式、客户端模式,具体的授权流程,请看阮一峰老师的文章理解OAuth 2.0

扩展阅读

PHP基础篇

1. PHP的两种用法

  • 常规用法
<body>
<?php echo '<p>Hello World</p>';
</body>
  • 高级用法
<html>
<head>
    <body>
        <ul>
    		<?php for ( $i = 1; $i <= 3; i++ ) {?> 
        		<li>listnum<?php echo $i;?></li>
            <?php }?>
        </ul>
    </body>
</head>
</html>

2. PHP的输出语句

  1. echo

    用来输出字符串到网页上,由于它不是函数,因此不需要对其使用括号;echo不返回值,不能对其赋值。

<?php
	echo "Hello World";
  1. print

    print与echo功能类似,用于将字符输出到网页上,echo可以使用的地方print也可以使用;

    print不是函数,不支持都好分隔多个变量,向print传递一个以上的参数时会发生解析错误;

    print总是返回1,与echo不一样,效率没有echo 搞笑。

<?php
	$x = print("hello world");
	echo $x; // 1
	print "hello world";
  1. printf

    用于格式化打印字符串,语法是printf(format, arg1, arg2, arg3, ...),format为转换的模板,arg1、arg2、arg++参数被插入format中的%处,此函数逐步执行,arg1插入到第一个%处,依次类推。

<?php
	printf("Hello %s", "大猫");
format content
%% 返回百分号
%b 二进制数
%c 依照ASCII编码
%d 带符号十进制数
%e 科学计数法(例如:1.5e3)
%u 无符号十进制数
%f 浮点数
%o 八进制
%s 字符串
%x 十六进制(小写字母)
%X 十六进制(大写字母)
  1. sprintf

    sprintf 与 printf 用法相同,sprintf将格式化的字符串写入变量中,不直接输出结果。

<?php
	echo sprintf("This is %1\$s %2\$s\n", "A", "B"); // This is A B
    $out = sprintf("This is %1\$s %1\$s", "A", "B");
    echo $out . PHP_EOL; // This is A A
  1. print_r

    print_r 显示关于一个变量的易于理解的信息,主要用来输出数组、对象等复合数据类型,返回布尔类型

<?php
	$arr = ['a' => 'A', 'b' => 'B', 'c' => ['a', 'b', 'c']];
	print_r($arr);
  1. var_dump

    var_dump 用于调试,作用是输出变量的内容、类型或字符串的内容、类型、长度。

<?php
	$numberOne = 1.5;
	var_dump($numberOne); // 输出 float(1.5)
	$numberTwo = 2;
	var_dump($numberTwo); // 输出 int(2)

3. 单引号与双引号的区别

双引号解析 $ 开头的变量和转义字符串,单引号不解析也不转义字符。

4. Get 与 Post 的区别

  • get参数通过url传递,post放在request body中
  • get请求在url中传递的参数是有长度限制的,而post没有
  • get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息
  • get请求只能进行url编码,而post支持多种编码方式
  • get请求会浏览器主动cache,而post不可以被缓存
  • get请求参数会被完整保留在浏览器历史记录里,而post中的参数不会被保留。
  • get产生一个TCP数据包;POST产生两个TCP数据包
    • get方式的请求,浏览器会把http header和data一并发送出去,服务器响应200
    • post方式的请求,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok

5. isset 和 empty 的区别

  • isset 判断变量是否存在或者变量名是否为null
  • empty 判断变量是否为空,0、“0”、’‘、FALSE、array()都会被判定成为空。比isset需要判断更多的条件

6. 什么是 MVC?

  • M —— Model 模型 多用于处理业务逻辑
  • V —— View 视图 负责跟用户进行页面交互
  • C —— Controller 控制器 用于处理请求和调用 Model 模型把处理结果分发给 View

优点:

  1. 分工明确(开发人员可以关注整个结构中的其中某一层):使用MVC可以把数据库开发,程序业务逻辑开发,页面开发分开,每一层都具有相同的特征,方便以后的代码维护。
  2. 松耦合(可以降低层与层之间的依赖):视图层和业务层分离,这样就允许修改视图层代码不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规划的改变只需要改动MVC的模型层即可。因为模型层与数据层和视图相分离,所以很容易改变应用程序的数据层和业务规则。
  3. 复用性高(利于各层逻辑的复用):像多个视图能够共享一个模型,不论你视图层用的flash界面或是wap界面,用一个模型就能处理。将数据和业务规则从表示层分开,就可以最大化重用代码
  4. 有利于标准化

缺点:

  1. 有时会导致级联的修改。这种修改其实体现在自上而下的方向。如果表示层中增加一个功能,为保证设计符合分层式结构,可能需要再相应的业务逻辑层和数据访问层中都增加相应的代码。
  2. 降低了系统的性能。如果不采用分层式结构,很多业务直接造访数据库,以此获取相应的数据,现在必须通过中间层来完成。
  3. 由于它没有明确的定义,所以完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花一些时间去思考
  4. MVC并不适合小型甚至中等规模的应用程序,话费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。

如何改善:

  • 可以采用一些设计模式来改善
  • 可以通过系统的缓存机制来减小对性能的影响

7. 传值和传引用的区别?

  • 传值只是传递一个变量的拷贝
  • 传引用实际就是传递一个变量的地址,函数可以直接改变变量的值

8. Cookie 和 Session 的区别和关系

  1. Cookie 存在客户端(浏览器),Session 存在服务器端
  2. Session 比 Cookie 安全性更高
  3. 单个 Cookie 保存的数据不能超过 4K
  4. Session 是基于 Cookie,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其他方式实现,比如在 url 中传递 Session ID)

9. 简述 S.O.L.I.D 设计原则

英文描述 中文描述 备注解释
SRP 单一职责原则 一个类有且只有一个更改的原因
OCP 开闭原则 对扩展开放,对修改关闭
LSP 里氏替换原则 派生类可以替换其基类使用
ISP 接口隔离原则 使用客户端特定的细粒度接口
DIP 依赖反转原则 依赖抽象而不是具体实现

10. 列举一些PHP中的设计模式?

  • 单例模式:保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个,同时这个类还必须提供一个访问该类的全局访问点。
  • 工厂模式:定义一个创建对象的接口,但是让之类去实现具体类。工厂方法模式让类的实例化延迟到了子类中。
  • 观察者模式:观察者模式有时也被成为发布/订阅模式,该模式用于对象实现 发布/订阅功能:一旦主题对象发生改变,与之关联的观察者对象会收到通知,并进行相应操作。
  • 适配器模式:适配器模式将一个类的接口转换成为客户希望的另外一个接口,使得原本由于接口不兼容不能一起工作的那些类可以一起工作。

了解更多,请看PHP 设计模式系列

11. PHP7 和 PHP5 的区别,具体多了哪些新特性?

  1. 性能提升了两倍
  2. 增加了结合比较运算符(<=>)
  3. 增加了标量类型生命、返回类型声明
  4. try...catch 增加多条件判断,更多 Error 错误可以进行异常处理
  5. 增加了匿名类,现在支持通过 new class来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义

12. 为什么 PHP7 比 PHP5 性能提升了?

  1. 变量存储字节减小,减少内存占用,提升变量操作速度
  2. 改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用、提升了 CPU 缓存命中率
  3. 改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高了执行效率

13. 简述一下 PHP 垃圾回收机制(GC)

PHP 5.3 版本之前都是采用引用计数的方式管理内存,PHP所有的变量存在一个叫 zval 的变量容器中,当这个变量被引用的时候,引用计数会 +1,变量引用计数变为 0 时, PHP将在内存中销毁这个变量。

但是引用计数中的循环引用,引用计数不会消减为 0,就会导致内存泄漏。

在 5.3版本之后,做了这些优化:

  1. 并不是每次引用计数减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收;
  2. 可以解决循环引用问题;
  3. 可以总将内存泄漏保持在一个阈值一下。

了解更多可以查看 PHP 手册,垃圾回收机制

14. 如何解决 PHP 内存溢出问题

  1. 增大 PHP 脚本的内存分配
  2. 变量引用之后及时销毁
  3. 将数据分批处理

15. Redis、Memecached 这两者有什么区别?

  1. Redis 支持更加丰富的数据存储类型:

    • String
    • Hash
    • List
    • Set
    • Sorted Set

    Memecached 仅支持简单的 key-value结构

  2. Memcached key-value存储比 Redis 采用 hash 结构来做 key-value 存储的内存利用率更高。

  3. Redis 提供了事务的功能,可以保证一系列命令的原子性

  4. Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中

  5. Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。

16. Redis 如何实现持久化?

  1. RDB 持久化,将 Redis 在内存中的状态保存到硬盘中,相当于备份数据库状态。
  2. AOF 持久化(Append-Only-File),AOF 持久化是通过保存 Redis 服务器锁执行的写状态来记录数据库的。相当于备份数据库接收到的命令,所有被写入 AOF 的命令都是以 Redis 的协议格式来保存的。

Web 安全防范

1. CSRF 是什么?如何防范?

CSRF (Cross-site request forgery)通常被叫做【跨站请求伪造】,攻击者盗用用户身份,从而欺骗服务器,来完成攻击请求。

防范措施:

  1. 使用验证码
  2. 给每一个请求添加令牌 token 并验证

2. XSS 是什么? 如何防范?

XSS(Cross Site Scripting),跨站脚本攻击,攻击者往 Web 页面里面插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。

防范措施:

  1. 核心本质:永远不要相信用户的输入数据,始终保持对用户数据的过滤。

3. 什么是 SQL 注入?如何防范?

SQL 注入就是攻击者通过一些方式欺骗服务器,结果执行了一些不该被执行的SQL语句。

常见场景:

  1. 数据库被注入了大量的垃圾数据,导致服务器运行缓慢、崩溃。
  2. 利用 SQL 注入 暴露了应用程序的隐私数据

防范措施:

  1. 保持对用户数据的过滤
  2. 不要使用动态拼装 SQL
  3. 对隐私数据加密,禁止明文存储

扩展阅读

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部