初中级PHP面试基础汇总,学以致用!

1 说几个你所知道的设计模式

单例模式

保证一个类仅有一个实例,并提供一个访问他的全局访问点例如框架中的数据库连接 – 类似DB类

策略模式

针对一组算法,将每一个算法封装到具有共同接口的独立的类中,例如进入个人主页时,根据浏览者的不同,给予不同的显示与操作 - 类似不同用户呈现不同效果

注册模式

提供了在程序中有条理的存放并管理一组全局对象 (object) - 类似服务提供者的注入

适配器模式

将不同接口适配成统一的API接口,例如数据操作有mysql、mysqli、pdo等,可利用适配器模式统一接口

观察者模式

一个对象通过添加一个方法使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。例如实现实现消息推送 – 将所有类的实例化注册到一个数组,通过循环批量执行类

装饰器模式

不修改原类代码和继承的情况下动态扩展类的功能,例如框架的每个Controller文件会提供before和after方法 – 在某个方法或输出之前执行或之后执行,用于修饰

迭代器模式

提供一个方法顺序访问一个聚合对象中各个元素,在PHP中将继承 Iterator 类 – yield

2 POST和GET有什么区别

第一种

GET在浏览器回退时是无害的,而POST会再次提交请求。

GET产生的URL地址可以被Bookmark(标记),而POST不可以。 

GET请求会被浏览器主动cache(存储),而POST不会,除非手动设置。 

GET请求只能进行url编码,而POST支持多种编码方式。 

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。 

GET请求在URL中传送的参数是有长度限制的,而POST么有。 

对参数的数据类型,GET只接受ASCII(美国信息交换标准码)字符,而POST没有限制。 

GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。 

GET参数通过URL传递,POST放在Request body中。

第二种

1、get是从服务器上获取数据,post是向服务器传送数据。

2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。

post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。

3.get传送的数据量较小,不能大于2KB。

post传送的数据量较大,一般被默认为不受限制。

4. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。

注意:post只是相比较get安全性更高一点,并不是说是万无一失的,在编程语言中,安全是最重要的(在输出语句中echo,print,var_dump等输出语句一定要使用过滤函数如htmlentiti()或正则过滤);

3 session与cookie的区别

Session的机制

session机制采用的是在服务器端保持状态的方案,并且有自己对应的唯一标识session_id,区分不同用户之前的信息。

Session的工作原理

  1. 当一个session第一次被启用时,一个唯一的标识被存储于本地的cookie中;
  2. 首先使用session_start()函数,PHP从session仓库中加载已经存储的session变量;
  3. 当执行PHP脚本时,通过使用session_register()函数注册session变量。
  4. 当PHP脚本执行结束时,未被销毁的session变量会被自动保存在本地一定路径下的session库中,这个路径可以通过php.ini文件中的session.save_path指定,下次浏览网页时可以加载使用。

Session的优缺点

优点

唯一性、方便调用、不会过多占用资源,是存储在服务器的一组临时数据。一般情况下,我们在做用户登录时,会将用户数据存入session。这样,在任何页面都可以方便调用,而且每个客户端会产生唯一的session_id,不会混淆。并且在关闭浏览器后,服务器会有session回收机制,自动删除过期session。

缺点

在客户端是以cookie方式保存的,禁用cookie,session就失效了。

Cookie

Cookie的机制

Cookie与Session的机制原理类似,都是会为每一个用户生成一个特定的值,这次是在客户端保存,当我们打开cookie里面保存了我们个人信息的网站,它会将我们的个人信息提交到服务器,之后请求服务器相应资料信息。

Cookie的优缺点

优点

不需要服务器资源空间,持久时间更长。

缺点

客户端大小受限制,用户禁用Cookie就失效了,不安全。

Cookie和Session的区别和联系

联系

Cookie可以在客户端为session保存唯一标识。

区别

Cookie机制采用的是在客户端(浏览器)保持状态的方案,而session机制采用的是在服务器端保持状态的方案。

4 数据库中的事务是什么?

指作为一个单元的一组有序的数据库操作,如果组中的所有操作都成功,则认为事务成功,即使有一个操作失败。

事务也不成功,如果所有操作完成,事务提交,其修改将作用于所有其他数据库进程,如果有一个操作失败,则事务回滚,该事务影响到的操作都会取消。

5 PHP中传引用与传值的区别?

php传值:在函数范围内,改变变量值的大小,都不会影响到函数外边的变量值。

PHP传引用:在函数范围内,对值的任何改变,在函数外部也有所体现,因为传引用传的是内存地址。

传值:和copy是一样的。打个比方,我有一橦房子,我给你建筑材料,你建了一个根我的房子一模一样的房子,你在你的房子做什么事都不会影响到我,我在我的房子里做什么事也不会影响到你,彼此独立。

<?php
$testa=1;        //定义变量a
$testb=2;        //定义变量b
$testb = $testa;    //变量a赋值给变量b
echo $testb;      //显示为1
?>

传引用:类似于C语言的指针了,感觉差不多。打个比方,我有一橦房子,我给你一把钥匙,我们二个都可以进入这个房子,你在房子做什么都会影响到我。

<?php
$param2=1;        //定义变量2
$param1 = &$param2;   //将变量2的引用传给变量1
echo $param2;      //显示为1
$param1 = 2;       //把2赋值给变量1
echo $param2;      //显示为2
?>
【优缺点:】传值会很耗时间,特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作,传送引用,函数内的任何操作等同于对传送变量的操作,传送大型变量时效率高!

MYSQL优化方案有哪些?

  1. 选用适合的字段类型,避免数据库增加不必要的空间,字段尽量设定为NOTNULL,类似性别,省份尽量使用枚举类型ENUM
  2. 使用JOIN查询代替子查询
  3. 使用UNION代替临时表
  4. 尽量不使用外键、除非必须保持数据表与表之间的一致性、完整性
  5. 尽量不使用视图
  6. 分表分库,读写分离
  7. 合理设置主键及索引
    • 索引分为:普通索引、唯一索引、全文索引、主键(也是一种唯一索引)
  8. 后期演变的数据表优化- 垂直拆分:表数据拆分到不同表中,按照业务拆分
    - 水平拆分:行数据拆分到不同表中,按照时间、类型、身份等因素拆分表
    - 水平垂直联合拆分

9.索引建立原则

  - 最左前缀匹配原则
- 索引列尽量不参与计算
- 尽量扩展索引不要新建索引

面向对象编程的五个基本原则 (S.O.L.I.D)

SRP 单一功能原则 (你可以这样干,并不是说你应该这样干)

- 引起类变化的因素永远不要多余一个,保证类的有且只有一个责任

OCP 开闭原则 (开胸手术时不需要穿一件外套)

- 对扩展开放,对修改闭合

LSP 里氏替换原则

- 当一个子类的实例应该能够替换任何其父类的实例时,它们之间才具有IS-A关系

ISP 接口隔离原则

- 不要强迫客户端(泛指调用者)去依赖那些他们不使用的接口

DIP 依赖反转原则

  • 高层模块不应该依赖底层模块,两者都应该依赖其抽象
  • 抽象不应该依赖于细节,细节应该依赖于抽象

yield的使用

生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。

子类重写父类的protected方法有什么限制?

1 final修饰的类方法不可被子类重写

2 5.3以后方法参数个数必须一致

3 重写时访问级别只可以等于或者宽松于当前重写方法的访问级别

什么是CGI? 什么是FastCGI? php-fpm , FastCGI,Nginx 之间是什么关系?

CGI 是通用网关接口,用户WEB服务器和应用程序间的交互,定义输入输出规范,用户的请求通过WEB服务器转发给FastCGI进程,FastCGI进程再调用应用程式进行处理,如PHP解析器,应用程序的处理结果如HTML返回给FastCGI,FastCGI返回给Nginx进行输出,假设WEB服务器是NGINX,应用程序是PHP,而 php-fpm 是管理FastCGI的,这就是php-fpm,fastCGI与NGINX的关系.

FastCGI 用来提高cgi程序性能,启动一个master,再启动多个worker,不需要每次解析php.ini 而php-fpm实现了fastcgi协议,是fastcgi的进程管理器,支持平滑重启可以启动的时候预先生成多个进程。

什么是 CSRF 攻击 ?XSS 攻击?如何防范?

CSRF,跨站请求伪造,攻击方伪装用户身份发送请求从而窃取信息或者破坏系统。
防范

  1. 合理规范api请求方式,GET,POST
  2. 对POST请求加token令牌验证,生成一个随机码并存入session,表单中带上这个随机码,提交的时候服务端进行验证随机码是否相同。

XSS,跨站脚本攻击。
防范

  1. 不相信任何输入,过滤输入。

基本算法

顺序查找

function search($arr,$k){
  $n = count($arr);
    $arr[$n]= $k;
    for($i=0; $i<$n; $i++){
        if($arr[$i]==$k){
        break;
        }
    }
    if ($i<$n){
        return $i;
    }else{
        return -1;
    }
}

二分查找

function binaryRecursive($arr,$low,$top,$target){
        if($low<=$top){
            $mid = floor(($low+$top)/2);
            if($arr[$mid]==$target){
                return $arr[$mid];
            }elseif($arr[$mid]<$target){
                return binaryRecursive($arr,$mid+1,$top,$target);
            }else{
                return binaryRecursive($arr,$low,$top-1,$target);
            }
        }else{
            return -1;
        }
    }

冒泡排序

function _sort($arr)
{
    $count = count ($arr) - 1;
    $temp  = 0;

    for ($i = 0; $i < $count; $i++) {

        for ($j = 0; $j < $count - $i; $j++) {
            if ($arr[$j] < $arr[$j + 1]) {
                $temp        = $arr[$j];
                $arr[$j]     = $arr[$j + 1];
                $arr[$j + 1] = $temp;
            }
        }
    }

    return $arr;
}

快速排序

function quick_sort($arr)
{
    //判断参数是否是一个数组
    if(!is_array($arr)) {
        return false;
    }else{
        //递归出口:数组长度为1,直接返回数组
        $length = count($arr);

        if($length<=1) return $arr;
            //数组元素有多个,则定义两个空数组
            $left = $right = array();
            //使用for循环进行遍历,把第一个元素当做比较的对象
            for($i=1; $i<$length; $i++)
            {
                //判断当前元素的大小
                if($arr[$i]<$arr[0]){
                    $left[]=$arr[$i];
                }else{
                    $right[]=$arr[$i];
                }
            }
        //递归调用
        $left=quick_sort($left);
        $right=quick_sort($right);
        //将所有的结果合并
        return array_merge($left,array($arr[0]),$right);
    }
}

NOSQL知识点

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

  1. Redis 支持更加丰富的数据存储类型,String、Hash、List、Set 和 Sorted Set。Memcached 仅支持简单的 key-value 结构。
  2. Memcached key-value存储比 Redis 采用 hash 结构来做 key-value 存储的内存利用率更高。
  3. Redis 提供了事务的功能,可以保证一系列命令的原子性
  4. Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中
  5. Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。

Redis 如何实现持久化?

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

Laravel 设计原理

服务提供者是什么?

服务提供者是所有Laravel应用程序引导启动的中心,Laravel的核心服务器、注册服务、绑定服务、监听器、中间件、路由注册以及我们应用程序都是由服务提供者引导启动的。

IOC容器是什么?

IOC就是控制反转,也被叫做依赖注入(DI),对象A可以依赖对象B,但是控制权在对象A中,所以叫做控制反转,依赖注入则是在IOC容器运行时动态将某种依赖关系注入到对象中。

作用:解决代码难易度,实现低耦合、高扩展

Facades 是什么?

提供了一个”static”(静态)接口去访问注册到 IoC 容器中的类。提供了简单、易记的语法,而无需记住必须手动注入或配置的长长的类名。此外,由于对 PHP 动态方法的独特用法,也使测试起来非常容易。

Contract 是什么?

Contract(契约)是 Laravel 定义框架提供的核心服务的接口。Contract 和 Facades 并没有本质意义上的区别,其作用就是使接口低耦合、更简单。

架构知识点

Thrift 实现的基本原理及作用

通过使用RPC通信协议,实现多语言开发场景下无感知的互相调用。
优点

  • 数据包呈二进制发送,流量消耗小
  • 传输效率高
  • 语言之间无障碍

如何解决优化网站App大数据大流量高并发

  • 硬件方面
  • 软件方面
  • 禁止外部盗链
  • 控制大文件的下载
  • 负载均衡
  • 分布式
  • 集群
  • 主从数据库
  • 分布式数据库
  • 分布式缓存

TCP 三次握手

三次握手就是客户端与服务器端建立TCP连接时需要发送3个包进行连接的确认,在三次握手完成后即可建立连接。

第一次握手。客户端发送请求报文,标志位SYN设置为1,随机产生seq值为x,客户端进入SYN_SENT状态,等待服务器端的回应。

第二次握手。服务器端接收到请求报文,将SYN和ACK都设置为1,ack为x+1,随机产生seq值为y,然后将数据包发送给客户端进行确认,服务器端进入SYN_RCVD状态。

第三次握手。客户端收到回应的数据包后,确认ack是否为x+1,以及ACK是否为1,若正确,则将ACK设置为1,ack为y+1,然后将数据发送给服务器端。服务器端在接受到数据后检查ack是否为y+1,ACK是否为1,若正确则正确建立连接,双方均进入ESTAB-LISHED状态,完成三次握手。

TCP 四次挥手
TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

1)首先客户端想要释放连接,向服务器端发送一段TCP报文,其中:

标记位为FIN,表示“请求释放连接“;序号为Seq=U;随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。

2)服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:

标记位为ACK,表示“接收到客户端发送的释放连接的请求”;序号为Seq=V;确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;随后服务器端开始准备释放服务器端到客户端方向上的连接。客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段

前”两次挥手”既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了

3)服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:

标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。序号为Seq=W;确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。

4)客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:

标记位为ACK,表示“接收到服务器准备好释放连接的信号”。序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。随后客户端开始在TIME-WAIT阶段等待2MSL

TCP 与 UDP 的区别

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的

UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对

实时应用很有用,如IP电话,实时视频会议等)

4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP首部开销20字节;UDP的首部开销小,只有8个字节

6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

一棵二叉树的前序遍历为ABCDEFG,则其中序遍历不可能为:

A.ABCDEFG

B.GFEDCBA

C.CBEDAGF

D.DBCEAFG

第一种方法:硬算,把每个答案都代入一遍,如果出现矛盾的话,结果不正确。
第二种:转化成入栈出栈问题。1.一棵二叉树的前序遍历结果,就是前序遍历时候元素入栈顺序。2.一颗二叉树的中序、后序遍历的结果,就是中序遍历、后序遍历遍历时候元素出栈顺序
所以这个问题就变成了,如果给定一个栈,入栈顺序是ABCDEFG,那么下面哪种出栈顺序是不可能的。我们来看看D选项。

DBCEAFG

如果D要第一个出栈,那么我们就必须:

  • 把ABCD按顺序压入栈,然后D作为栈顶元素出栈。
  • 然后我们看看第二个出栈元素是B,这时候栈里面还有ABC,栈顶是C,所以无论如何都无法让B出栈。矛盾。所以D选项错误。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇