php,mysql,linux,redis,docker等相关技术经典面试题,新手收藏学习,持续更新中。。。
Posted 黄昏单车
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php,mysql,linux,redis,docker等相关技术经典面试题,新手收藏学习,持续更新中。。。相关的知识,希望对你有一定的参考价值。
php面试题
1、写出你能想到的所有HTTP返回状态值,并说明用途(比如:返回404表示找不到页面)
# 200:服务器请求成功
# 301:永久重定向,旧网页已被新网页永久替代
# 302:表示临时性重定向
# 400:错误请求
# 401:未授权,没有权限,未登录
# 403:禁止访问
# 404:找不到页面
# 500:系统错误,服务器错误
# 502:无效响应
# 503:服务不可用,服务器由于维护或者负载过重未能应答
# 504:网关超时(nginx做为反向代理服务器,所连接的应用服务器无响应导致)
2、HTTP中GET,POST和PUT的区别
1、GET在浏览器回退时是无害的(会从缓存中拿结果),而POST会再次提交请求。
2、GET产生的URL地址可以被Bookmark(收藏书签),而POST不可以。
3、GET请求会被浏览器主动cache,而POST不会,除非手动设置。
4、GET请求只能进行url编码,而POST支持多种编码方式。
5、GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
6、GET请求在URL中传送的参数是有长度限制的,2kb,而POST没有,但是根据IIS的配置,传输量也是不同的。
7、对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
8、GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
9、GET参数通过URL传递,POST放在Request body中
# 总结
POST和GET方式的安全性是相对的,另外也要看是从哪个角度来看的。从数据传输过程方面来看,POST方式是更加
安全的,但是从对服务器数据的操作来看,POST方式的安全性又是比较低的。即使是传输过程用POST来执行,
安全性也是相对的,如果了解HTTP协议漏洞,通过拦截发送的数据包,同样可以修改交互数据,
所以这里的安全不是绝对的。
# 1、PUT和POST
PUT和POST都有更改指定URI的语义.但PUT被定义为idempotent的方法,POST则不是.idempotent的方法:如果一
个方法重复执行多次,产生的效果是一样的,那就是idempotent的。也就是说:
PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源)
Post请求:后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源)
# 2、get和post补充
1、HTTP的底层是TCP/IP。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。GET/POST都是TCP链接。
GET和POST能做的事情是一样一样的。但是请求的数据量太大对浏览器和服务器都是很大负担。所以业界有了不成
文规定,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。
2、GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一
并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,
浏览器再发送data,服务器响应200 ok(返回数据)。
3、在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,
两次包的TCP在验证数据包完整性上,有非常大的优点。但并不是所有浏览器都会在POST中发送两次包,
Firefox就只发送一次。
3、php中双引号和单引号的区别
双引号解释变量,单引号不解释变量;所以单引号的执行效率比双引号要高
双引号可以解析所有的转义字符,单引号只能解析 \\ 和 ' 本身的转义;
4、echo、print_r、print、var_dump之间的区别
# echo 和 print 区别:
echo - 可以输出一个或多个字符串
print - 只允许输出一个字符串,返回值总为 1
提示:echo 输出的速度比 print 快, echo 没有返回值,print有返回值1。
# echo和print共同点
都是一个语言结构,使用的时候可以不用加括号,也可以加上括号
# var_dump()和print_r()的区别
共同点:都是函数,两者都可以打印数组,对象之类的复合型变量。
区别:
print_r() 是函数,用于格式化输出数组的结构
print_r() 只能打印一些易于理解的信息
print_r() 在打印数组时,会将把数组的指针移到最后边,使用reset() 可让指针回到开始处。
var_dump() 不但能打印复合类型的数据,还能打印资源类型的变量
var_dump() 输出的信息则比较详细,一般调试时用得多。
var_dump() 判断一个变量的类型和长度,并输出变量的数值
5、require一个不存在的文件时,如何避免抛出异常错误?
使用 try {} catch(Exception $e) 捕获异常
使用 file.exists() 判断文件是否存在,存在引入
6、写一段php demo代码实现单例模式
class Singleton
{
private static $instance;
private function __construct()
{
// Do nothing.
}
//获取实例
public static function getInstance()
{
if (!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
//防止克隆
private function __clone()
{
// Do nothing.
}
}
7、请描述一下PHP的自动加载机制
在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和require方法,去把定义这个class
的文件包含进来。这个在小规模开发的时候,没什么大问题。但在大型的开发项目中,这么做会产生大量的
require或者include方法调用,这样不因降低效率,而且使得代码难以维护,况且require_once的代价很大。
在PHP5之前,各个PHP框架如果要实现类的自动加载,一般都是按照某种约定自己实现一个遍历目录,自动加载
所有符合约定规则的文件的类或函数。 当然,PHP5之前对面向对象的支持并不是太好,类的使用也没有现在频繁。
在PHP5后,当加载PHP类时,如果类所在文件没有被包含进来,或者类名出错,Zend引擎会自动调用__autoload
函数。此函数需要用户自己实现__autoload函数。 在PHP5.1.2版本后,可以使用spl_autoload_register
函数自定义自动加载处理函数。当没有调用此函数,默认情况下会使用SPL自定义的spl_autoload函数。
1、 __autoload示例:
function __autoload($class_name) {
echo '__autload class:', $class_name, '<br />';
}
new Demo();
# 以上的代码在最后会输出:__autload class:Demo。
# 并在此之后报错显示: Fatal error: Class ‘Demo’ not found
# 我们一般使用_autoload自动加载类如下:
function __autoload($class_name) {
require_once ($class_name . “class.php”);
}
$memo= new Demo();
我们可以看出_autoload至少要做三件事情,第一件事是根据类名确定类文件名,第二件事是确定类文件所在的
磁盘路径(在我们的例子是最简单的情况,类与调用它们的PHP程序文件在同一个文件夹下),第三件事是将类从
磁盘文件中加载到系统中。第三步最简单,只需要使用include/require即可。要实现第一步,第二步的功能,
必须在开发时约定类名与磁盘文件的映射方法,只有这样我们才能根据类名找到它对应的磁盘文件。
因此,当有大量的类文件要包含的时候,我们只要确定相应的规则,然后在__autoload()函数中,将类名与实际
的磁盘文件对应起来,就可以实现lazy loading的效果。从这里我们也可以看出__autoload()函数的实现中
最重要的是类名与实际的磁盘文件映射规则的实现。
但现在问题来了,假如在一个系统的实现中,假如需要使用很多其它的类库,这些类库可能是由不同的开发工程师
开发,其类名与实际的磁盘文件的映射规则不尽相同。这时假如要实现类库文件的自动加载,就必须__autoload()
函数中将所有的映射规则全部实现,因此__autoload()函数有可能会非常复杂,甚至无法实现。最后可能会导致
__autoload()函数十分臃肿,这时即便能够实现,也会给将来的维护和系统效率带来很大的负面影响。在这种
情况下,在PHP5引入SPL标准库,一种新的解决方案,即spl_autoload_register()函数。
# 2、spl_autoload_register()函数
# 此函数的功能就是把函数注册至SPL的__autoload函数栈中,并移除系统默认的__autoload()函数。
# 下面的例子可以看出:
function __autoload($class_name) {
echo '__autload class:', $class_name, '<br />';
}
function classLoader($class_name) {
echo 'SPL load class:', $class_name, '<br />';
}
spl_autoload_register('classLoader');
new Test();
//结果:SPL load class:Test
语法:bool spl_autoload_register ( [callback $autoload_function] )
接受两个参数:一个是添加到自动加载栈的函数,另外一个是加载器不能找到这个类时是否抛出异常的标志。
第一个参数是可选的,并且默认指向spl_autoload()函数,这个函数会自动在路径中查找具有小写类名和.php
扩展或者.ini扩展名,或者任何注册到spl_autoload_extensions()函数中的其它扩展名的文件。
class CalssLoader {
public static function loader($classname){
$class_file = strtolower($classname).".php";
if (file_exists($class_file)){
require_once($class_file);
}
}
}
// 方法为静态方法
spl_autoload_register('CalssLoader::loader');
$test = new Test();
一旦调用spl_autoload_register()函数,当调用未定义类时,系统会按顺序调用注册到
spl_autoload_register()函数的所有函数,而不是自动调用__autoload()函数。
如果要避免这种情况,需采用一种更加安全的spl_autoload_register()函数的初始化调用方法:
if(false === spl_autoload_functions()){
if(function_exists('__autoload')){
spl_autoload_registe('__autoload',false);
}
}
spl_autoload_functions()函数会返回已注册函数的一个数组,如果SPL自动加载栈还没有被初始化,它会返回
布尔值false。然后,检查是否有一个名为__autoload()的函数存在,如果存在,可以将它注册为自动加载栈中的
第一个函数,从而保留它的功能。之后,可以继续注册自动加载函数。
还可以调用spl_autoload_register()函数以注册一个回调函数,而不是为函数提供一个字符串名称。如提供一个
如array('class','method')这样的数组,使得可以使用某个对象的方法。
下一步,通过调用spl_autoload_call('className')函数,可以手动调用加载器,而不用尝试去使用那个类。
这个函数可以和函数class_exists('className',false)组合在一起使用以尝试去加载一个类,并且在所有的
自动加载器都不能找到那个类的情况下失败
if(spl_autoload_call('className') && class_exists('className',false)){
} else {
}
SPL自动加载功能是由spl_autoload() ,spl_autoload_register(), spl_autoload_functions()
,spl_autoload_extensions()和spl_autoload_call()函数提供的。
总结:项目过大时,include和require使用过多,php5.2后出现__autoload自动载入,后面出现一个php工程
依赖多个框架,每个框架都有__autoload就会报方法重复定义错误,php5.3之后官方提供
spl_autoload_register('autoload1');,解决了方法重复定义冲突
8、发送POST请求时,application/x-www-form-urlencoded格式和multipart/form-data有什么区别,如果需要发送json格式到后台,发送时Content-Type应该如何设置
application/x-www-form-urlencoded是浏览器默认的编码格式,用于键值对参数,参数之间用&间隔;
multipart/form-data常用于文件等二进制,也可用于键值对参数,最后连接成一串字符传输
设置默认application/x-www-form-urlencoded
9、阐述下你对MVC的理解
Model(模型) - 模型代表一个存取数据的对象。它也可以带有逻辑,在数据变化时更新控制器。
View(视图) - 视图代表模型包含的数据的可视化。
Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。
它使视图与模型分离开。Controller层用来调度View层和Model层,将用户界面和业务逻辑合理的组织在一起,
起粘合剂的效果
# 总结:
优点:分层,结构清晰,耦合性低,大型项目代码的复用性得到极大的提高,开发人员分工明确,
提高了开发的效率,维护方便,降低了维护成本。
缺点:简单的小型项目,使用MVC设计反而会降低开发效率,层和层虽然相互分离,但是之间关联性太强,
没有做到独立的重用
10、什么是面向对象?主要特征是什么?
面向对象是程序的一种设计方式,
把具体的事物和行为抽象成类,对象有方法,属性值,不可变常量
它利于提高程序的重用性,使程序结构更加清晰。
主要特征:封装、继承、多态。
11、SESSION 与 COOKIE的区别是什么,请从协议,产生的原因与作用说明?
# 产生的背景和原理:
HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的
连接。这就意味着服务器无法从连接上跟踪会话。于是需要引入一种机制,COOKIE于是就顺应而生。
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session
# 区别:(位置,大小,安全)
1、cookie 是存放在浏览器端,不同的浏览器存储的cookie数量和数据的大小都不一致。
大多数情况下单个域名限制最多保存20个cookie,每个cookie保存的数据不能超过4K。
2、session存储在服务端,默认是以文件的形式存储,也可以存储在数据库和redis、memcache等缓存内存中。
3、session是占用的服务器内存,所以内存越大,能存的值就越大,原则上讲无上限,一般用于存储对安全要求
较高的重要数据;
# 补充
1、SESSION存储在服务器端,COOKIE保存在客户端。Session比较安全,cookie用某些手段可以修改,不安全。
Session依赖于cookie进行传递。
2、session为‘会话服务’,在使用时需要开启服务,cookie不需要开启,可以直接用
禁用cookie后,session不能正常使用。Session的缺点:保存在服务器端,每次读取都从服务器进行读取
对服务器有资源消耗。Session保存在服务器端的文件或数据库中,默认保存在文件中,文件路径由php配置
文件的session.save_path指定。Session文件是公有的。
12、isset() 和 empty() 区别
Isset判断变量是否存在,可以传入多个变量,若其中一个变量不存在则返回假
empty判断变量是否为空为假,只可传一个变量,如果为空为假则返回真
$a = 1;
$b = 2;
echo isset($a,$b) . "</br>"; // true
echo isset($a,$c) . "</br>"; // false
echo empty("") . "</br>"; // true
echo empty("0") . "</br>"; // true
echo empty(" ") . "</br>"; // false
echo empty("null") . "</br>"; // false
echo empty(null) . "</br>"; // true
13、请说明 PHP 中传值与传引用的区别。什么时候传值什么时候传引用?
按值传递:函数范围内对值的任何改变在函数外部都会被忽略
按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。
按引用传递则不需要复制值,对于性能提高很有好处。
14、在PHP中error_reporting这个函数有什么作用?
设置 PHP 的报错级别并返回当前级别。
error_reporting(2047):显示所有错误
15、请用正则表达式(Regular Expression)写一个函数验证电子邮件的格式是否正确。
if(isset($_POST['action']) && $_POST['action']==’submitted’){
$email=$_POST['email'];
if(!preg_match(“/^[0-9a-zA-Z-]+@[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+){1,3}$/”,$email)){
echo “电子邮件检测失败”;
}else{
echo “电子邮件检测成功”;
}
}
16、对于用户输入一串字符串$string,要求string中只能包含大于0的数字和英文逗号,请用正则 表达式验证,对于不符合要求的string返回出错信息
class regx {
public static function check($str) {
if(preg_match("/^([1-9,])+$/",$str)) {
return true;
}
return false;
}
}
$str="12345,6";
if(regx::check($str)) {
echo "suc";
} else {
echo "fail";
}
17、单例模式,创建mysqli数据库链接的单例对象
class Db {
private static $instance;
public $handle;
private function __construct($host,$username,$password,$dbname) {
$this->handle=NULL;
$this->getcon($host,$username,$password,$dbname);
}
public static function getBb() {
self::$instance=new Db();
return self::$instance;
}
private function getcon($host,$username,$password,$dbname) {
if($this->handle!=NULL){
return true;
}
$this->handle=mysqli_connect($host,$username,$password,$dbname);
}
}
18、windows平台, Apache Http Server启动失败, 排错思路是什么?
检查apache使用的80端口是否被占用,如果被占用,先停止占用80端口的服务,然后启动apache服务器
19、PHP session扩展默认将session数据储存在哪里? 答案:D
A) SQLite Database
B) MySQL Database
C) Shared Memory
D) File System
E) Session Server
20、如果你想要自动加载类,下面哪种函数声明是正确的 答案:C
A) function autoload($class_name)
B) function __autoload($class_name, $file)
C) function __autoload($class_name)
D) function _autoload($class_name)
E) function autoload($class_name, $file)
21、PHP程序使用utf-8编码, 以下程序输出结果是什么? 答案:B
$str = ’hello你好世界’;
echo strlen($str);
?>
A) 9
B) 13(gbk)
C) 18
D) 17(utf8)
22、你所知道的php数组相关的函数?
array()----创建数组
array_combine(keys,values);----通过合并两个数组来创建一个新数组
range(low,high,step)----创建并返回一个包含指定范围的元素的数组
compact()----创建一个包含变量名和它们的值的数组。
array_chunk(array,size,preserve_key);----将一个数组分割成多个
array_merge(array1,array2,array3...)----把两个或多个数组合并成一个数组
array_slice(array,start,length,preserve)----在数组中根据条件取出一段值
array_diff(array1,array2,array3...)----返回两个数组的差集数组
array_intersect(array1,array2,array3...)----计算数组的交集
array_search(value,array,strict)----在数组中搜索给定的值
array_splice(array,start,length,array)----移除数组的一部分且替代它
array_key_exists(key,array)----判断某个数组中是否存在指定的key
shuffle(array)----把数组中的元素按随机顺序重新排列
array_flip(array)----交换数组中的键和值
array_reverse(array,preserve)----将原数组中的元素顺序翻转,创建新的数组并返回
array_unique(array)----移除数组中重复的值
23、php读取文件内容的几种方法和函数?
打开文件,然后读取。fopen(filename,mode,include_path,context) fread(file,length)
打开读取一次完成 file_get_contents(path,include_path,context,start,max_length)
24、以下程序,变量str什么值的情况下输入111?
if( ! $str ) { echo 111; }
在$str值为:0,’0′,false,null,”",[],0.0
25、你所知道的PHP的一些技术(smarty等)?
Smarty,jquery,ajax,memcache,div+css,js,mysqli,pdo,svn,thinkphp,brophp,yii
26、你所熟悉的PHP论坛系统 有哪些?
Discuz
27、你所熟悉的PHP商城系统 有哪些?
Ecshop
28、你所熟悉的PHP开发框架 有哪些?
laravel,thinkphp
29、常用的魔术方法有哪些?举例说明?
__construct() 实例化类时自动调用。
__destruct() 类对象使用结束时自动调用。
__set() 在给未定义的属性赋值的时候调用。
__get() 调用未定义的属性时候调用。
__isset() 使用isset()或empty()函数时候会调用。
__unset() 使用unset()时候会调用。
__sleep() 使用serialize序列化时候调用。
__wakeup() 使用unserialize反序列化的时候调用。
__call() 调用一个不存在的方法的时候调用。
__callStatic()调用一个不存在的静态方法是调用。
__toString() 把对象转换成字符串的时候会调用。比如 echo。
__invoke() 当尝试把对象当方法调用时调用。
__set_state() 当使用var_export()函数时候调用。接受一个数组参数。
__clone() 当使用clone复制一个对象时候调用。
<?php
class Person{
public $a = 0;
public $arr = ['Moe','Larry','Curly'];
function __construct($name=""){
// unset($this->b); //__unset() 使用unset()时候会调用
//$this->getB; //__get() 调用未定义的属性时候调用。
}
function __sleep(){
echo '__sleep';
return [];
}
public function __wakeup() {
echo "__wakeup";
}
function __unset($argu){
echo 'unset';
}
function __set($name,$val){
echo $name;
}
function __get($name){
echo '__get'搭建服务器lmnpr-linux_Mysql_nginx_php_redis