php经典面试题
一:什么是面向对象?
面向对象OO = 面向对象的分析OOA + 面向对象的设计OOD + 面向对象的编程OOP;通俗的解释就是“万物皆对象”,把所有的事物都看作一个个可以独立的对象(单元),它们可以自己完成自己的功能,而不是像C那样分成一个个函数。
现在纯正的OO语言主要是 Java和C#,PHP、C++也支持OO,C是面向过程的。
二:简述 private、 protected、 public修饰符的访问权限
- private : 私有成员, 在类的内部才可以访问。
- protected : 保护成员,该类内部和继承类中可以访问。
- public : 公共成员,完全公开,没有访问限制。
三:堆和栈的区别?
- 栈(操作系统):由操作系统(编译器)自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
- 堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
- 堆(数据结构):堆可以被看成是一棵树,如:堆排序。
- 栈(数据结构):一种先进后出的数据结构。
栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
四:XML 与 HTML 的主要区别?
- XML是区分大小写字母的,HTML不区分。
- 在HTML中,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略或者之类的结束 标记。在XML中,绝对不能省略掉结束标记。
- 在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个 / 字符作为结尾。这样分析器就知道不用 查找结束标记了。
- 在XML中,属性值必须分装在引号中。在HTML中,引号是可用可不用的。
- 在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。
五:面向对象的特征有哪些方面?
主要有封装,继承,多态。如果是4个方面则加上:抽象。
下面的解释为理解:
封装:
封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的高内聚,低耦合,防止程序相互依赖性而带来的变动影响.
继承:
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
多态:
多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
抽象:
抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。
六:抽象类和接口的概念以及区别?
抽象类:它是一种特殊的,不能
被实例化的类,只能作为其他类的父类使用。使用abstract
关键字声明。
接口:它是一种特殊的抽象类,也是一个特殊的类,使用 interface 声明。
- 抽象类的操作通过继承关键字
extends
实现,而接口的使用是通过implements
关键字来实现。 - 抽象类中有数据成员,可以实现数据的封装,但是接口没有数据成员。
- 抽象类中可以有构造方法,但是接口没有构造方法。
- 抽象类的方法可以通过
private、protected、public
关键字修饰(抽象方法不能是private),而接口中的方法只能使用public关键字修饰。 - 一个类只能继承于一个抽象类,而一个类可以同时实现多个接口。
- 抽象类中可以有成员方法的实现代码,而接口中不可以有成员方法的实现代码。
七:什么是构造函数,什么是析构函数,作用是什么?
构造函数(方法)是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。作用是执行一些初始化的任务。php中使用__construct()
声明构造方法,并且只能声明一个。
析构函数(方法)作用和构造方法正好相反,是对象被销毁之前最后一个被对象自动调用的方法。是PHP5中新添加的内容作用是用于实现在销毁一个对象之前执行一些特定的操作,诸如关闭文件和释放内存等。
八:如何重载父类的方法?举例说明
重载,即覆盖父类的方法,也就是使用子类中的方法替换从父类中继承的方法,也叫方法的重写。
覆盖父类方法的关键是在子类中创建于父类中相同的方法包括方法的名称、参数和返回值类型。PHP中只要求方法的名称相同即可。
九:常用的魔术方法有哪些?
php规定以两个下划线__
开头的方法都保留为魔术方法,所以建议大家函数名最好不用开头,除非是为了重载已有的魔术方法。
__construct()
实例化类时自动调用。__destruct()
类对象使用结束时自动调用。__set()
在给未定义的属性赋值的时候调用。__get()
调用未定义的属性时候调用。__isset()
使用isset()或empty()函数时候会调用。__unset()
使用unset()时候会调用。__sleep()
使用serialize序列化时候调用。__wakeup()
使用unserialize反序列化的时候调用。__call()
调用一个不存在的方法的时候调用。__callStatic()
调用一个不存在的静态方法是调用。__toString()
把对象转换成字符串的时候会调用。比如 echo。__invoke()
当尝试把对象当方法调用时调用。__set_state()
当使用var_export()函数时候调用。接受一个数组参数。__clone()
当使用clone复制一个对象时候调用。
十:常用的魔术常量有哪些?
魔术常量是一类预定义常量,它们的值在脚本运行时根据上下文动态变化。与普通常量不同,魔术常量通常以双下划线开头和结尾,例如__LINE__
、__FILE__
等
__LINE__
常量表示当前代码行的行号。它在调试和错误处理时非常有用,可以帮助开发者快速定位问题__FILE__
常量表示当前文件的完整路径和文件名。在包含文件时,这个常量可以帮助确定当前执行的文件。__DIR__
常量表示当前文件所在的目录。它与__FILE__
类似,但只包含目录路径,不包括文件名。__FUNCTION__
常量表示当前函数的名称。如果在函数外部使用,则返回一个空字符串。__CLASS__
常量表示当前类的名称。如果在类外部使用,则返回一个空字符串。__TRAIT__
常量表示当前Trait的名称。如果在Trait外部使用,则返回一个空字符串。__METHOD__
常量表示当前方法的名称。与__FUNCTION__
类似,但用于类的方法。__NAMESPACE__
常量表示当前命名空间的名称。如果没有命名空间,则返回一个空字符串。
十一:$this和self、parent这三个关键词分别代表什么?在哪些场合下使用?
- $this 当前对象
- self 当前类
- parent 当前类的父类
- $this在当前类中使用,使用->调用属性和方法。
- self也在当前类中使用,不过需要使用::调用。
- parent在类中使用。
十二:类中如何定义常量、如何类中调用常量、如何在类外调用常量?
类中的常量也就是成员常量,常量就是不会改变的量,是一个恒值。
定义常量使用关键字 const 例如:const PI = 3.1415326;
无论是类内还是类外,常量的访问和变量是不一样的,常量不需要实例化对象,访问常量的格式都是类名加作用域操作符号(双冒号)来调用。即:类名 :: 类常量名;
十三:作用域操作符::如何使用?都在哪些场合下使用?
- 调用类常量
- 调用静态方法
十四:__autoload()方法的工作原理是什么?
- 使用这个魔术函数的基本条件是类文件的文件名要和类的名字保持一致。
- 当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。
- 这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后就执行
include
或者require
来载入该类,然后程序继续执行,如果这个路径下不存在该文件时就提示错误。 - 使用自动载入的魔术函数可以不必要写很多个
include
或者require
函数。
十五:进程、线程、协程的区别是什么?
- 进程 Process
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位
通俗的讲:进程可以理解为我们在电脑上正在运行的一个个应用,例如:QQ,微信,LOL,打开一个浏览器就是一个进程,打开两个浏览器就是两个进程,进程和进程之间具有独立性,它们具有各自的虚拟地址空间和文件描述符
- 线程 thread
线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。同一个进程的多个线程之间是共享同一份虚拟空间地址和文件描述符的。在一个进程中的多线程,可以并发的执行。 就拿百度网盘来说,如果有下载任何和上传任务的话,那么百度网盘这个进程里面至少有两个线程来完成工作,一个是上传 一个是下载
- 协程coroutine
在详细讲解协程之前,我们先看一下这个场景,比如一个饭店有两个厨师,一个小工,小工负责摘菜 洗菜 啥的,那么饭店运转的时候,其实就有三个线程,这没有问题,但是忽然有一天小工请假了,就剩下两个厨师了?怎么办?老板这时候说,你看你俩也不是很忙,有人点菜的时候就炒菜,没人点菜的时候就洗洗菜啥的,别闲着(周扒皮已上线),明白了吧,就是为了更高效率的利用线程,而不是频繁的创建线程 销毁线程 以及CPU频繁的切换上下文,不能让线程闲着
协程,英文Coroutines,是一种基于线程之上,但又比线程更加轻量级的存在,因为是自主开辟的异步任务,所以很多人也更喜欢叫它们纤程(Fiber),或者绿色线程(GreenThread)。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。具有对内核来说不可见的特性。(其实这里有一个问题,就是协程是无序的,那么我们怎么保证数据的事务性呢?有好的想法可以和我交流哦)
本文来自博客园,作者:LiJialong,转载请注明原文链接:https://www.cnblogs.com/carver/p/17115986.html