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

php redis mysql apache 下载地址

php,mysql,linux,redis,docker等相关技术经典面试题,新手收藏学习,持续更新中。。。

linux上docker简单部署lnmp+redis

Linux的企业-Redis 作 mysql 的缓存服务器

CentOS搭建Apache+php+MySQL+Redis环境