完整复习PHP面试

本文深入探讨了PHP中的变量引用,包括其工作原理和在循环中的应用。详细解释了错误控制符@的用途,以及HTTP/1.1状态码200、301、302、400、401、403、404和500的含义。此外,还介绍了MySQL数据库的主键、唯一索引和分区操作,以及如何解决高并发和大流量问题,如页面静态化、数据库优化和负载均衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PHP 变量引用

阅读下面程序,解释运行过程及结果

<?php

/**
 * <?php
 * $data=['a','b','c'];
 * foreach ($data as $k=>$v){
 *  $v=&$data[$k]
 * }
 * 程序运行时,每一次循环结束后变量$data的值是什么?请解释
 * 程序执行完后,$data的值是什么?请解释
 */

/**
 * 解1:
 * 数组共循环三次
 * 1:将数组第一个元素的下标赋值给变量$k,值赋值给$v,然后将数组的第一个值的地址赋值给$v;即
 * $k=0;$v='a';$v=&$data[0];
 * $data=['a','b','c'];
 * 2.将数组第二个元素的下标赋值给变量$k、值赋值给$v(此时的赋值会改变第一个元素,因为在第一次循环将数组的第一个元素的地址赋值给了$v) 然后将数组的第二个值的地址赋值给$v;即
 * $k=1;$v='b';$v=&$data[1]
 * $data=['b','b','c'];
 * 3.将数组第三个元素的下标赋值给变量$k、值赋值给$v(此时的赋值会改变第二个元素,因为在第二次循环将数组的第二个元素的地址赋值给了$v) 然后将数组的第三个值的地址赋值给$v;即 
 * $k=2;$v='c';$v=&$data[2];
 * $data=['b','c','c'];
 * 解2:
 * 最终$data的结果为['b','c','c']
 */
//验证
$data=['a','b','c'];
foreach ($data as $k=>$v){
    $v=&$data[$k];
    print_r($data);
}
print_r($data);
 php tmp1.php  
Array
(
    [0] => a
    [1] => b
    [2] => c
)
Array
(
    [0] => b
    [1] => b
    [2] => c
)
Array
(
    [0] => b
    [1] => c
    [2] => c
)
Array
(
    [0] => b
    [1] => c
    [2] => c
)

变量cow机制

1)cow指copy on write(写时复制),表示变量在更新的时候会进行复制一份内存空间
2)对象是引用赋值,不会进行复制;如果要进行复制,用对象概念进行克隆一份 (clone)
什么是引用变量,考察概念
1)在PHP中用不同的变量名称访问同一个变量,
2)引用申明用&符号
3)通过debug工具xdebug_debug_zval(‘变量名’),来查看变量的结构体,refcount表示有多少个变量指向这个内存空间,is_ref表示是不是引用
注意: unset只会删除变量的引用

const与define的区别

const: 快,是语言结构、可以定义类常量
define:是函数、不可以定义类常量

PHP数据类型考察点

PHP字符串可以使用那三种方式定义以及各自的区别是什么

/**
 * PHP字符串可以使用那三种方式定义以及各自的区别是什么
 * 考点:字符串的定义方式和各自的区别
 */
/**
 * 解:
 * 单引号:不解析变量,不能解析转义字符,只能解析单引号和反斜杠本身,效率高于单引号;变量和变量,变量和字符串,字符串和字符串可以用点来连接
 * 双引号:可以解析变量,可以用特殊字符和{}包含,可以解析转义字符,也可以是用.连接
 * heredoc:类似于双引号
 * newdoc:类似于单引号
 */
//演示:
$tmp='dd';
echo PHP_EOL.'单引号'. PHP_EOL;
echo $a='12$tmp31\t23'.$tmp;
echo PHP_EOL.'双引号'. PHP_EOL;
echo $a="1231\t'$tmp'&$tmp&23".$tmp;
echo PHP_EOL.'heredoc'. PHP_EOL;
echo $str=<<<Str
asdasdasdasd===$tmp
Str;
echo PHP_EOL.'newdoc'. PHP_EOL;
echo $str=<<<'Str'
asdasdasdasd===$tmp
Str;
php tmp1.php

单引号
12$tmp31\t23dd
双引号
1231    'dd'&dd&23dd
heredoc
asdasdasdasd===dd
newdoc
asdasdasdasd===$tmp

阅读下面的程序,并解释最终输出的结果

<?php
$a=0.1;
$b=0.7;
var_dump(($a+$b)==0.8);
php tmp1.php
bool(false)
//浮点型不能运用到比较运算中,$a+$b=0.79999无限循环小数,因为计算都是交给cpu去执行的,而cpu执行的时二进制数,在转成二进制数时会有损耗

列举PHP值等于false的几种情况

<?php
/**
 *PHP值等于false的几种情况
 *
 * 解:
 * 一共七种
 * 0、0.0、'0'、''、array()、null、false
 */
//验证:
var_dump(false==0);
var_dump(false==0.0);
var_dump(false=='0');
var_dump(false=='');
var_dump(false==array());
var_dump(false==null);
var_dump(false==false);

php tmp1.php
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

用PHP写出显示客户端IP与服务端IP的代码

/**
 * 用PHP写出显示客户端IP与服务端IP的代码
 * 
 */
$clint_ip=$_SERVER['REMOTE_ADDR'];
$server_ip=$_SERVER['SERVER_ADDR'];
var_dump($clint_ip,$server_ip);

__FILE__是什么意思

__FILE__是PHP的预定义常量,返所在文件的路径加文件名称

运算符考点

foo()和@foo()的区别

考点:PHP的错误控制符@

PHP支持错误运算符:@。当放置在一个表达式之前,该表达式产生的任何错误都被忽略掉。

foo()程序运行过程中如果出现错误,会提示错误,@foo()则会被忽略掉

阅读程序给出运行结果

<?php
if ('==false'){
    echo 1;
}elseif('0'==0){
    echo 2;
}elseif(0.0==0){
    echo 2;
}

php tmp1.php
1
# 考察false的七种情况

阅读下面程序,给出a、a、ab的运行结果

<?php
$a=false||true;
$b=false or true;
var_dump($a,$b);
php tmp1.php
bool(true) 
bool(false)
# 考察运算符的优先级:&&大于||大于and大于or
$a=false||true  看做一块false||true 结果是true 然后赋值

$b=false 看做一块所以是false
优先级参考:https://www.php.net/manual/zh/language.operators.precedence.php

下列程序中请写出输出打印的结果

$a=0;
$b=0;
if($a=3>0||$b=3>0){
    $a++;
    $b++;
    var_dump($a,$b);
}

php tmp1.php
bool(true)
int(1)

考察:考察运算符的优先级 >大于||大于=
执行顺序

$a=((3>0)||$b=3>0);$a=true;$b=0;
$a++;
$b++;


流程控制考察点

请列出三种数组循环的操作语法,并注明各种循环的区别

<?php

/**
 * 请列出三种数组循环的操作语法,并注明各种循环的区别
 * for循环:只能遍历索引数组
 * foreach循环:可以遍历索引、关联数组
 * while、list、each组合循环:可以遍历索引、关联数组
 */
$tmp=[1,2,3];
$len=count($tmp);
for ($i=0;$i<$len;$i++){
    echo $tmp[$i].PHP_EOL;
}

$a=['name'=>'xiaoming','age'=>15];
foreach($a as $key=>$value){
    echo "{$key}:{$value}\n";
}
while(list($key,$value)=each($a)){
    echo "{$key}:{$value}\n";
}
 php tmp1.php
1
2
3
name:xiaoming
age:15       
name:xiaoming
age:15 

PHP中如何优化多个if…elseif的情况?

  1. 表达式可能性较大的往前挪
  2. 判断的值是整型、浮点型、或者字符串类型可以,可以使用switch case,switch实现的有跳转表

自定义函数以及内部函数考察点

写出如下程序的输出结果

/**
 * 写出如下程序的输出结果
 */
$count=5;
function get_count(){
    static $count;
    return $count++;
}
echo $count;
++$count;
echo get_count();
echo get_count();
/**
 * 考点:
 * 一:考察变量的作用域
    * 作用域:
    * 全局:申明在全局的变量,不能直接在函数内部使用,如要使用,需使用关键字 global关键字申明,或者超全局变量$_GLOBAL['variable']
    * 局部:申明在函数体的局部变量,只能在函数内使用,函数执行完后会消失
 * 静态变量:
    * 不仅在函数域中存在,当程序执行离开此作用域时,值并不会消失
    * static关键字:
    * 1)仅初始化一次
    * 2)初始化时需要赋值
    * 3)每次执行函数该值会保留
    * 4)static修饰的变量时局部的,仅在函数内部有效
    * 5)可以记录函数的调用次数,从而可以在某些条件下终止递归
 * 递增递减:
    * ++$a	前加	$a 的值加一,然后返回 $a
    * $a++	后加	返回 $a,然后将 $a 的值加一。
 * 运行过程分析:
 *$count=5;
 *function get_count(){
 *   static $count; // null
 *   return $count++; // 1
 *}
 *echo $count;// 5
 *++$count;// 6
 *echo get_count(); //null
 *echo get_count(); // 1
 * 
 */
//验证
php tmp1.php
51
//注意:null输出的时空

写出如下程序a、a、ab的输出结果

function &myfunc(){
    static $a=10;
    return $a;
}
$a=myfunc();
echo $a.PHP_EOL;
$a=100;
$a=myfunc();
echo $a.PHP_EOL;
$b=&myfunc();
echo $b.PHP_EOL;
$b=100;
$b=myfunc();
echo $b.PHP_EOL;

php tmp1.php
10 
10 
10 
100
/**
 * 考察:引用返回
 */

include、require、include_once、require_once函数的区别

include/require:都是引入文件操作,如果给出的有路径名,则按照给出的路径查找,否则从include_path中查找,如果include_path中也没有,则从调用脚本文件所在的目录和当前工作目录下寻找。当一个文件被包含时,其中所包含的的代码继承了include所在行的变量范围。

include/require区别:加载过程中未找到文件,include结构会发出一个警告,而require会报一个致命错误并终止程序

include/require与include_once、require_once的区别:都是引入文件操作,唯一的区别就是后者会检查文件是否被引入过,如果引入过就不再引入

用代码实现以下给出的时间点


 /**
  *1.上周的现在时间,输出格式:Y-m-d H:i:s
  *2.这个月的开始时间,输出格式:Y-m-d H:i:s
  *3.获取2021-10-01 23:59:59的时间戳
  *4.获取2021-10与2021-11月相差多少天
  */
echo "上周的现在时间,输出格式:Y-m-d H:i:s\n";
echo date("Y-m-d H:i:s", strtotime("-1 week"));
echo "\n";

echo "这个月的开始时间,输出格式:Y-m-d H:i:s\n";
echo date("Y-m-d H:i:s",mktime(0,0,0,date("m"),1,null));
//mktime(时,分,秒,月,天,年)
echo "\n";

echo "获取2021-10-01 23:59:59的时间戳\n";
echo mktime(23,59,59,10,01,2021);
echo "\n";

echo "获取2021-10与2021-11月相差多少天\n";
echo date('t',mktime(0,0,0,10,1,2021));
//求十月有多少天就行
echo "\n";
php tmp1.php
上周的现在时间,输出格式:Y-m-d H:i:s
2021-09-28 02:08:03
这个月的开始时间,输出格式:Y-m-d H:i:s
2000-10-01 00:00:00
获取2021-10-01 23:59:59的时间戳
1633132799
获取2021-10与2021-11月相差多少天
31

写出PHP的打印处理函数

/**
 * 1.print: 是语言结构,输出字符串,接收一个字符串变量
 * 2.printf:输出格式化字符串
 * 3.print_r:易于理解的格式打印变量。接收两个参数一个打印内容,一个是否要获取 print_r() 输出的内容默认false
 * 4.echo :输出一个或多个字符串,多个逗号隔开
 * 5.sprintf: 返回格式化字符串
 * 6.var_dump:打印变量的相关信息,会打印结构的类型,多个逗号隔开
 * 7.var_export:输出或返回变量的可解析字符串表示,接收两个参数,一个想要输出的变量名,第二个参数为 true 时,var_export() 将返回一个变量,而不是输出它
 */

写出下面程序的输出结果

 $var1= 5;
 $var2=10;
 function foo(&$my_var){
    global $var1;
    $var1+=2;
    $var2=4;
    $my_var+=3;
    return $var2;
 }
 $my_var=5;
 echo foo($my_var)."\n";
 echo $my_var."\n";
 echo $var1."\n";
 echo $var2."\n";
 $bar='foo';
 $my_var=10;
 echo $bar($my_var)."\n";
/**
 * 考察:
 * 作用域
 * 引用传递、引用返回
 * $var1= 5;
 * $var2=10;
 * function foo(&$my_var){
 *    global $var1;//5
 *    $var1+=2;//7
 *    $var2=4;//4
 *    $my_var+=3;//8
 *    return $var2;//4
 * }
 * $my_var=5;
 * echo foo($my_var)."\n";//4
 * echo $my_var."\n";//8
 * echo $var1."\n";//7
 * echo $var2."\n";//10
 * $bar='foo';
 * $my_var=10;
 * echo $bar($my_var)."\n";//4
 */
//验证
php tmp1.php
4
8
7
10
4

正则表达式

正则表达式的作用是什么

分割、查找、匹配、替换字符串

请写出139开头的11位手机号码的正则表达式

 /**
  * 请写出139开头的11位手机号码的正则表达式
  */
$str='13988888888';
$pattern='/^139\d{8}$/';
preg_match($pattern,$str,$match);
var_dump($match);
php tmp1.php
array(1) {
  [0]=>
  string(11) "13988888888"
}

请写出一个正则表达式,取出页面所有img标签中所有的src值


$str="<img alt='dd' id='test' src='a.jpg'>123</img>";
$pattern='/<img.*?src=\'(.*?)\'.*?\/?>/i';
preg_match($pattern,$str,$match);
var_dump($match);
php tmp1.php
array(2) {
  [0]=>   
  string(36) "<img alt='dd' id='test' src='a.jpg'>"
  [1]=>
  string(5) "a.jpg"
}

通过PHP的方式对目录进行遍历,写出程序

/**
 * 思路:
 * 打开目录
 * 读取目录中的文件
 * 如果文件类型是目录,继续打开目录
 * 读取子目录的文件
 * 如果文件类型是文件,输出文件名称
 * 关闭目录
 */
$dir='./test';
function loopdir($dir){
   $handle = opendir($dir);
   // readdir() 返回值的风格。这里明确地测试返回值是否全等于(值和类型都相同——更多信息参见比较运算符)false,否则任何目录项的名称求值为 false 的都会导致循环停止(例如一个目录名为“0”)
   while(false!==($file=readdir($handle))){
      if ($file != "." && $file != "..") {
         echo $dir.'/'.$file."\n";
         if(filetype($dir.'/'.$file)=='dir'){
            loopdir($dir.'/'.$file);
         }
     }
   }
}
loopdir($dir);
php tmp1.php
./test/a.log       
./test/b.log       
./test/test-1      
./test/test-1/a.log

会话控制

简述cookie和session的区别及各自的工作机制,存储位置等,简述cookie的优缺点

cookie:服务端发送给客户端的一个片段信息,存储在客户端内存、或硬盘当中的一种技术

优点:存储在客户端、不会占用服务端的资源,缺点:信息都保存在客户端,不安全,用户有权限禁止使用

session:将用户使用的信息存储在服务器中。session不完全脱离cookie,而是基于cookie。服务端会信息记录成一个文件,并生成一个sessionid发送给客户端, 客户端以cookie的方式进行存储,下次请求带上携带上sessionId

优点:存储在服务端,相对与cookie更加安全 缺点:信息都记录在服务端,占用服务器资源

面向对象考点

请写出PHP类权限控制修饰符号

  1. public
  2. private
  3. protected

PHP的继承是否可以多个类

PHP是单一继承,如果有接口的话可以继承一个类和一个接口,类只能同时继承一个

PHP中接口与抽象类的区别

  • 接口
    • 属性:接口不能拥有属性
    • 常量:可以拥有常量
    • 修饰符:只能拥有public
    • 参数:可以增加可选参数,必填参数会提示申明的致命错误
  • 抽象类
    • 属性:可以拥有属性
    • 常量:可以拥有属性
    • 修饰符:publicproteced,private;注意private不能申明抽象方法,也不能被继承
    • 参数:可以增加可选参数,必填参数会提示申明的致命错误
  • 继承
    • 子类会继承父类所有 publicprotected 的方法,属性和常量;子类可以重写父类方法.
    • 继承只能是单一继承,也就是说一个类只能extendsimplements一个父类,但一个类可以有多个子类

解释下PHP的self、static的区别以及什么是延迟静态绑定

答: selfstatic都是范围解析操作符(::)前所使用的变量,均在类的内部使用;static可以什么属性方法,而self只能用于访问当前类的属性以及方法
延迟静态绑定也叫后期静态绑定,后期绑定的意思是说,static::不再被解析定义为当前方法所在的类,而是实际运行是计算的(通常是在调用时范围解析操作符::的左侧部分)
备注(访问考察点):

self是否可以访问protected,private类型的方法

可以;self,parent 和 static 这三个特殊的关键字是用于在类定义的内部对其属性或方法进行访问的,他们的区别如下
self:用于访问当前类的属性、方法、常量
parent:用于访问父类的属性、方法、常量
static:运行时计算出得到的类的属性、方法、常量

像一个类中的某个方法既声明了修饰符,又申明了static 关键字,那这个方法可通过什么方式进行访问

一个方法有了修饰符,又加了static关键字,它的方法体不能不出现$this为变量,这个方法在可访问性的基础上加上了静态属性
在调用这个函数时,可以通过两种方法进行调用,一种$this,一种static::

面向对象编程的基本原则

  1. 单一职责:一个类,只需要做好一件事情
  2. 开放封闭:一个类,应该时可扩展而不可修改的
  3. 依赖倒置:一个类,不应该强依赖另一个类。每一个类对另一个类都是可替换的
  4. 配置化:尽可能的使用配置,而不是硬编码
  5. 面向接口编程:只需要关心接口,不需要关系实现

常用的设计模式

  1. 单例模式
    1. 解释:在应用程序中只有一个实例存在,一旦创建就会存在内存中
    2. 场景:一般用于数据库类设计,一次只连接一个数据库,防止打开多个数据库连接
  2. 工厂模式
    1. 解释:根据输入的参数不同或程序的配置不同,来创建一种专门用来实例化并返回其对应类的实例
    2. 场景:一边用于创建的场景;当使用new实例化类,每次只需要调用工厂类中的方法实例化即可
  3. 观察者模式
    1. 解释:观察者是定义的一种一对多的关系依赖,让多个观察者监听一个主题对象;这个主题对象在状态发生变化时,会通知所有观察者对象;是他们能能够自动更新自己
    2. 用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上
  4. 适配器模式
    1. 解释:将各种截然不同的函数接口封装成统一的API
    2. 场景:PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致
  5. 策略模式:
    1. 解释:策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。
    2. 场景:如果我需要在早晨从家里出发去上班,我可以有几个策略考虑:我可以乘坐地铁,乘坐公交车,走路或其它的途径。每个策略可以得到相同的结果,但是使用了不同的资源

网络协议考点

http/1.1中状态码 200,301,302,400,401,403,404,500的含义

状态码是负责客户端http请求的结果,标记服务端的处理是否正常,通知出现的错误

状态码分为五个大类:

  1. 1xx:信息类状态码,表示接收请求正在处理

  2. 2xx:成功类状态码,表示请求正常处理完毕了

  3. 3xx:表示重定向,需要进行附加操作

  4. 4xx:表示客户端错误,服务器无法处理请求

  5. 5xx:表示服务端错误,服务器处理请求出错

  6. 200:成功

  7. 301:永久重定向,请求的资源已被分配了新的url,以后应使用现在所指向的url

  8. 302:临时重定向,请求的资源已被分配了新的url,希望用户本次使用新的url进行访问

  9. 400:请求报文中存在语法错误

  10. 401:发送的信息需要通过http认证的认证信息

  11. 403:请求的资源被服务器拒绝了

  12. 404:服务器上无法找到请求的资源

  13. 500:服务器内部错误

简述osi七层模型

  1. 物理层:建立、维护、断开物理连接
  2. 数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能
  3. 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择
  4. 传输层:定义传输数据的协议端口号,以及流量控制和差错校验(协议有:TCP、UDP,数据包一旦离开网卡即进入网络传输层)
  5. 会话层:建立、管理、终止会话
  6. 表示层:数据的表示、安全、压缩
  7. 应用层:网络服务与最终用户的一个接口,协议有:HTTP,HTTPS、FTP、SMTP、DNS、POP3、DHCP

HTTP的工作特点和工作原理

工作特点:

  1. 基于B/S模式
  2. 通信开销小,简单快速,传输成本低
  3. 使用灵活,可使用超文本传输协议
  4. 节省传输时间
  5. 无状态

工作原理:客户端发送请求给服务器,创建一个TCP连接,指定端口号默认为80端口,连接到服务器、服务器监听浏览请求,一旦监听到客户端请求,分析请求类型后,服务端会向客户端返回状态信息和数据内容。

HTTP协议常见请求/响应头

  1. content-type:请求实体对应的MIME信息
  2. Accept:指定客户端能接收的内容、类型
  3. Origin:请求来源,主要用于POST
  4. Cookie:http请求发起时,发送给服务端cookie的值
  5. Cache-control:指定请求和响应的缓存机制
  6. User-Agent:用户信息
  7. Referrer:上级请求路径
  8. X-Forwarded-For:请求端的真实IP
  9. Access-Cotro-Allow-Origin:允许特定的域名来进行访问,通常做跨域使用
  10. Last-ModiFied:请求资源的最后的修改时间

HTTP协议常见的请求方法

  1. GET:用于资源的读取
  2. POST:用于资源的新增或修改
  3. PUT:用于资源修改
  4. DELETE:删除资源
  5. OPTIONS:与HEAD类似,用与查看服务器的性能,返回该资源所有支持HTTP的方法,主要用于测试服务器功能是否正常
  6. HEAD:与GET一样都是获取数据,区别是服务器在响应HEAD方法是不会响应内容部分,只会返回HEAD信息

HTTP中GET和POST的区别

  1. GET在做后退操作是无害的,而post的数据会被重新提交
  2. GET可以收藏为书签
  3. GET可以被浏览器缓存,POST不能被缓存
  4. GET请求的编码类型是 application/x-www-form-urlencoded,POST是multipart/form-data对二进制数据使用多重编码
  5. GET在历史记录中参数会被保存历史当中
  6. GET对数据长度有限制,2048个字符,POST没有限制
  7. GET对数据类型有限制,POST没有限制
  8. GET安全性较差,发送的数据是url的一部分,POST则好一些,参数不会被保存在浏览器历史,或者是web服务器日志当中

HTTPS的工作原理

HTTPS是一种基于SSL/TLS的HTTP协议,所有的数据都是在ssl/tls协议上封装之上传输的。

HTTPS协议在HTTPS协议的基础上,添加了SSL/TLS握手及数据加密传输,也属于应用层协议。

常见的网络协议含义及端口

  1. FTP:默认端口21 文件传输协议,用于下载文件上传文件
  2. Telnet:默认端口23 远程登陆协议,用户可以以自己的身份远程连接到计算机上
  3. SMTP:默认端口25 定义了简单邮件传输协议,用于发送邮件
  4. POP3:默认端口110 与SMTP对应,主要用于接收邮件
  5. HTTP:默认端口80 超文本传输协议
  6. DNS:默认端口53 用于域名解析服务

常见的HTTP协议、TCP协议分别位于osi网络模型的第几层?

HTTP:应用层

TCP:传输层

开发环境及配置相关考点

版本控制软件

  1. 集中式:版本信息都上传到中央服务器,只在中央服务器进行保存,上传和下载都是通过中央服务器进行连接,客户机需要连接网络才能进行上传和下载操作
  2. 分布式:没有中央服务器,一个版本库下的所有客户机都有一个完整的版本控制器,分布式的容灾性更好,不用连接网络

集中式的:CVS和svn

分布式:git

简述CGI、fastCGI和PHP-FPM的区别

CGI:解决不同语言与webserver之间的通信协议,按照CGI协议实现的程序,能实现语言解析器与webserver之间的通信;

FastCGI:FastCGI是CGI的改良版本,webserver每收到一个请求都会给CGI一个进程,然后请求结束后,再杀掉这个进程,当请求量大了,就非常浪费资源,导致效率很低,而FastCGI每次处理完后不会杀掉进程,会保留这个进程,使一个进程一次可以处理多个请求,这样就不用每次重启一个进程,大大的提升了处理效率。

PHP-FPM:PHP fastCGI process manage,叫做fastCGI进程管理器,PHP-FPM是fastCGI的进程管理器,FPM是fastCgi的实现,并且提供了进程管理的功能,进程包括master、work进程,master进程只有一个,负责监听端口(默认端口9000),接收来自webserver的请求,而work进程一般有多个,数量在fmp的配置中定义,每个进程的内部都会嵌入一个PHP解析器

Linux基础考察点

写出尽可能多的Linux命令

  • 系统安全

    sudo 、su、chmod、setfacl

  • 进程管理

    w、top、ps、kill、pkill、pstree、killall

  • 用户相关

    id、usermod、useradd、groupadd、userdel

  • 文件系统

    mount、umount、fsck、df、du

  • 系统关机和重启

    init、reboot、shutdown

  • 网络应用

    curl、wget、telnet、mail、elinks

  • 网络测试

    ping 、netstat、host

  • 网络配置

    hostname 、ifcofig、ip addr

  • 常用工具

    ssh、screen、clear、who、date

  • 软件包管理

    yum、rpm、apt-get

  • 文件查找和比较

    locate 、find

  • 文件内容查看

    head、tail、less、more

  • 文件处理

    touch、unlink、rename、ln、cat

  • 目录操作

    cd、mv、rm、pwd、tree、cp、ls

  • 文件权限属性

    setfacl、chmod、chwon、chgrp

  • 压缩/解压

    bzip2/bunzip2、gzip/gunzip、zip/unzip、tar

  • 文件传输

    ftp、scp、sync、rz、sz

linux定时任务

crontab 命令

* * * * *命令(分 时 日 月 周)

at命令:一次性执行,不是循环执行

# at 2:00 tomorrow
at>/home/jason/do_job
at>Ctrl+D

vim编辑器

模式:

  1. 一般模式:删除、粘贴、复制
  2. 编辑模式:i、I、o、O、a、A、r、R切换到编辑模式
  3. 命令模式:::、/、?

MySQL数据库考察点

请写出下面MySQL数据类型表达的意义

请写出下面MySQL数据类型表达的意义(int(0)、char(16)、varchar(16)、datetime、text)

  1. int(0): 数据类型为整型,显示宽度为0
  2. char(16):定长字符串为16位,如果不满16,char会采用空格进行填充
  3. varchar(16): 变长字符串为16位,如果超出指定长度,会进行截断 ;注意:变长只会往下缩,不会向大扩
  4. datetime:日期类型:Y-m-d H:i:s
  5. text:超文本

innoDB与MyISAM的区别

MYISAM:5.1版本以前,MYISAM是默认的存储引擎,拥有全文索引 压缩和空间函数,不支持事务和行级别锁,不支持崩溃后安全恢复,表存在两个文件,MYD和MYI

INNODB:5.1版本以后默认的存储引擎,默认的事务型引擎,支持热备份,支持崩溃后完全恢复,支持行及锁,支持外键

mysql锁的机制

基础概念:当多个查询同一时刻进行数据修改时,就会产生并发控制的问题.

共享锁和排他锁,就是读锁和写锁

读锁:共享的,不堵塞,多个用户可以读取同一个资源,互不干扰

写锁:排他的,一个写锁会阻塞其他的写锁和读锁,只允许一个人进行写入,防止其他用户读取正在写入的资源

按粒度分:

表锁:系统开销性能最小,会锁定整张表,MYISAM使用的就是表锁

行锁:最大程度的支持并发处理,但时也带来了最大的锁开销,INNODB实现行级锁

MYSQL事务处理

事务处理.MySQL提供事务处理的表引擎,InnoDB.服务器层不管理事务,由下层的引擎实现,所以同一个事务中,使用多种存储引擎不靠谱.在非事务的表上执行事务操作,MySQL也不会发出提醒和报错

存储过程

为以后使用保存一条或多条的MySQL语句的集合,是有业务逻辑和流程的集合,可以在存储过程中创建表,更新数据,删除等操作

使用场景:通过把处理封装在容易使用的单元中,简化复制操作,保证数据的一致性,简化对变动的管理

触发器

提供给程序员和数据分析员来保证数据完整性的一种方法,他是与表事件相关的特殊存储过程

使用场景:

可通过数据库中的相关表实现级联更改.

实时监控某个表中的某个字段的更改而需要做出相应的处理.

某些业务的编号生成等

滥用会造成数据库及应用程序的维护困难

脏读、不可重复读、幻读名词解释

  • 脏读
    • 指一个事务读取到了其他事务可能没回滚的数据;
    • 解决:隔离级别设置为:读已提交
  • 幻读
    • 指修同一数据,当前事务还没提交,但是另一个事务抢先改了回去,此时当前事务提交即认为是幻读,让用户认为没有改到
    • 解决:隔离级别设置为:串行化
  • 不可重复读
    • 一个事务不同时刻读取数据不一样
    • 解决:隔离级别设置为:不可重复读

区别:1、脏读就是指当一个事务正在访问数据,并且对数据进行了修改;2、不可重复读是指在一个事务内,多次读同一数据;3、幻读是指当事务不是独立执行时发生的一种现象

隔离级别

mysql在性能和安全方面采用的默认级别为:可重复读
读未提交:1)指一个事物可以读到另一个事物未提交的数据。
2)这是最不安全的隔离级别,也是读写操作最快的隔离级别,因为隔离级别都是依靠锁来实现的,读未提交直接裸奔没得加锁解锁的消耗。
3)也是安全系数最低的隔离级别会出现,脏读、不可重复读、幻读所有情况,可以理解为没有隔离

读已提交:1)指一个事物只能读到其他已经提交的事物。
2)每次执行(指当前读)都生成一份快照,不同时刻查询出来的数据可能不一样
3)读已提交解决了脏读,但是还剩下不可重复读和幻读
可重复读:1)事物不会读到其他事物已有的数据修改,以及其他事物的提交;注意:只是修改数据不会读取到,新插入的数据是可以读到的(这也是产生幻读的可能因素)
2)在事务开始的时候生成一个当前事务全局性的快照
3)解决了脏读、不可重复读、幻读(mysql依靠锁实现了)

串行化: 1)相当于单线程,后一个事物必须等前一个事物结束才能执行
2)读的时候加共享锁,也就是其他事务可以并发读但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读
3)安全级别最好,性能最差,解决了脏读、不可重复读、脏读

备注:
1)读提交和可重复读,这两种隔离级别是比较复杂的,既要允许一定的并发,又想要兼顾的解决问题
2)重复读和不可重复读的区别是在快照的创建上,可重复读仅在事务开始是创建一次,而读提交每次执行语句的时候都要重新创建一次

迸发问题

当两个事物对同一批数据进行修改,最后结果应该是执行最靠后的事物,
举例:假设事物1要对一批数据进行更新操作,而事物2也要对这批数据进行更新,1在开启事务后要对更新的数据先进行读取(这里的读取叫做当前读),读取后对这批要修改的数据加上行锁,2再开启事物后按照同样的操作,将读取到这批数据然后进行加锁;此时发现这批数据已经被事物1占有,2申请不到锁就只能等待,直到1提交,如果1的时间太长,2很有可能出现超时现象
这里的加锁分两种情况:有索引/无索引
1)有索引:MySQL直接就在索引数中找到了这行数据加上行锁就可以了
2)无索引:MySQL 会为这张表中所有行加行锁,但是在加上行锁后,MySQL会进行一遍过滤,发现不满足的行就释放锁,最终只留下符合条件的行 (大表的话,建议合理设计索引,如果真的出现这种情况,那很难保证并发度)

mysql可重复读如何解决幻读

解决幻读用的也是锁,叫做间隙锁,MySQL 把行锁和间隙锁合并在一起,解决了并发写和幻读的问题,这个锁叫做 Next-Key锁

MySQL创建高性能索引考点

简单描述MySQL中索引,主键,唯一索引,联合索引的区别,对数据库性能有什么影响?

考点:

MySQL索引的基础和类型

延伸考点:MySQL的索引创建原则

延伸考点:MySQL索引的注意事项

MySQL索引的基础和类型

索引的基础: 索引类似书籍的目录,要找到一本书的某个特定主题,需要先找到数的目录,定位对应的页码.存储引擎使用类似的进行数据查找,先去索引中找到对应的值,然后根据匹配的索引找到对应的数据行.
索引对性能的影响:大大减少服务器需要扫描的数据量. 帮助服务器避免排序和临时表.将随机i/o变顺序i/O,大大提高查询速度,降低了写的速度,占用磁盘

使用场景: 对非常小的表,全表扫描数据效率更高, 中到大型表,索引非常有效, 特大型的表,建立索引的代价将随之增长,可以使用分区技术来解决

索引的类型

索引的类型有很多种,都是是现在存储引擎的,

  • 普通索引:最基本的索引,没有任何约束限制

  • 唯一索引:与普通索引类型,具有唯一性的约束

  • 主键索引:特殊的唯一索引,不允许有空值

  • 组合索引:将多个列组合在一起创建索引,可以覆盖多个列

  • 外键索引:只有INNODB的数据表才可以使用外键索引,保证数据的一致性,完整性和实现联级操作

  • 全文索引:MySQL自带的全文索引,只能用于MYISAM,并且只能对英文进行全文检索

主键索引和唯一索引的区别:

  1. 一个表只能有一个主键索引,可以有多个唯一索引

  2. 主键索引一定时唯一索引,唯一索引不是主键索引

  3. 主键可以与外键构建成参照完整性约束,防止数据不一致,唯一索引不行

MySQL的索引创建原则

  1. 最适合索引的列是出现在WHERE子句中的列.或连接子句中的列,而不是出现在select关键字后的列
  2. 索引列的基数越大,效果越好
  3. 对字符串进行索引,应该定制一个前缀长度,可以节省大量的索引空间
  4. 根据情况创建复合索引,可以提高查询效率
  5. 避免创建过多索引,索引会占用额外的磁盘空间,降低写操作效率
  6. 主键尽可能的选择较短的数据类型,可以有效减少索引的磁盘占用提高查询效率

MySQL索引的注意事项

  1. 复合(组合)索引遵循前缀原则!!! (经常考)

回顾:key(a,b,c)

生效情况:

WHERE a=1 AND b=2 AND c=3

WHERE a=1 AND b=2

WHERE a=1

不生效情况:

WHERE b=2 AND c=3

WHERE a=1 AND c=3

  1. like查询,%不能在前,可以使用全文索引;如果对一个字段添加了索引,要使用模糊查询,%放在前面是使用不到索引的,这种情况可以考虑使用其他情况的搜索引擎,如ES,lucene

  2. cloumn is null 可以使用索引

  3. 如果MySQL估计使用索引比全表扫描更慢,会放弃使用索引

    如区间查询 WHERE id>1 AND id<100

  4. 如果or前的条件中的列有索引,后面的没有,索引都不会被用到

    如: where a=1 or b=2;

  5. 列类型是字符串,查询时一定要给值加引号,否则索引失效

    如: name varchar(16) WHERE name=100;

mysql的SQL编写考察点

有a(id,sex,par,c1,c2),b(id,age,c1,c2)两张表,其中a.id与b.id关联,要求写出一条sql语句,将b中age>50记录的c1,c2,更新到a表中的c1,c2字段中

关联更新:UPDATE a,b set a.c1=b.c1,a.c2=b.c2 WHERE a.id=b.id AND b.id>50;

内连接的方式:UPDATE a INNER JOIN b ON b.id=a.id set a.c1=b.c1,a.c2=b.c2 WHERE b.id>50;

MySQL查询优化考点

请简述项目中优化SQL语句执行效率的方法,从那些方面,SQL语句性能如何分析?

考点:

查找分析查询速度慢的原因

分析sql查询慢的方法

  • 记录慢查询日志

    分析查询日志。不要直接打开慢查询日志进行分析,这样比较浪费时间和精力,可以使用pt-query-digest工具进行分析

  • 使用 show profile

    set profiling=1;开启,服务器上执行的所有语句会检测消耗的时间,缓存到临时表中;

    show profiles;

    show profile for query 临时表id

  • 使用 show processlist;

    观察是否有大量的线程处于不正常的状态或特征

  • 使用explain(别名:desc)

    对单条SQL语句,观察扫描的行数,是否有用到索引

优化查询过程中的数据访问

  • 访问太多数据导致性能下降
  • 确定应用程序是否在检索大量超过需要的数据,可能是太多行或列
  • 确认mysql服务是否在分析大量不必要的数据行
  • 重复查询相同的数据,可以缓存数据,下次直接读取缓存

避免使用如下SQL

  • 避免查询不需要的记录,使用limit解决
  • 避免多表关联返回全部列,指定查询的字段
  • 避免使用SELECT * 会让优化器无法完成索引覆盖扫描的优化

优化长难的查询语句

  • MYSQL内部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢的多,

  • 使用尽可能小的查询,将一个大的查询分解成小的查询

优化特定类型的语句查询

  • 优化count查询,count(*)中的*会忽略所有的列,直接统计所有的列数,因此不要使用count(列名)
  • MYISAM中,没有任何条件的count(*)会非常的快,当有WHERE条件,MYISAM统计不一定比其他表引擎快;可以使用explain查询近似值,用近似值代替count(*),或者增加汇总表、使用缓存
  • 优化关联查询,确定ON或USING字句的列上有索引,没有索引的可以去建立索引,不然会导致全表扫描;确保group by和order by中的列只有一个表中的列,这样mysql才有可能使用索引
  • 优化子查询:尽可能使用关联查询来替代
  • 优化group by和distinct:这两种查询jun均可使用索引来优化,是最有效的优化方法,关联查询中,使用标识列进行分组查询效率会更高;如果不需要order by,进行group by时使用ORDER BY NULL ,MYSQL 不会再进行文件排序
  • 优化limit分页:limit偏移量大的时候,查询效率比较低,可以记录上次查询的最大ID,下次查询时直接根据ID来查询 ;
  • 优化union:UNION ALL的效率高于UNION

MySQL高可扩展和高可用考点

简述MySQL分表操作和分区操作的工作原理,分别说说分区和分表的使用场景和各自优缺点

考点:

分区表的原理

对用户而言,分区表是一个独立的逻辑表,但是底层MySQL将其分成了多个物理子表,这对用户来说是透明的,每一个分区表都会使用一个独立的表文件。

创建表时使用partition by子句定义每个分区存放的数据,执行查询时,优化器会根据分区定义过滤那些没有我们需要数据的分区,这样查询只需要查询数据所在的分区即可。

分区的主要目的将数据按照一个较粗的粒度分在不同的表中,这样可以将相关的数据存放在一起,而且想一次性删除整个分区的数据也很方便

适用场景:

  1. 表非常大,无法全部存在内存,或者只是在表的最后有热点数据,其他都是历史数据
  2. 分区表的数据更容易维护,可以对独立的分区进行独立的操作
  3. 分区表的数据可以分布在不同的机器上,从而高效使用资源
  4. 可以使用分区表来避免某些特殊的瓶颈
  5. 可以备份和恢复独立的分区

限制:

  1. 一个表只能有1024个分区
  2. 5.1版本中,分区表表达式必须时整数,5.5可以用列分区
  3. 分区字段中如果有主键和唯一索引列,那么主键列和唯一列都必须包含进来
  4. 分区表中无法使用外键约束
  5. 需要对现有表的结构进行修改
  6. 所有分区都必须使用相同的存储引擎
  7. 分区函数中可以使用的函数和表达式会有一些限制
  8. 某些存储引擎不支持分区
  9. 对于MYISAM的分区表,不能使用load index into cache
  10. 对于MYISAM表,使用分区表时需要打开更多的文件描述符

分库分表的原理

通过一些hash算法或者工具实现将一张数据表垂直或水平进行物理切分

适用场景:

  1. 单表记录条数达到百万到千万级别时
  2. 解决表锁的问题

分表方式:

水平分割:表很大,分割后可以降低在查询时需要读取的数据和索引的页数,同时也降低了索引的层数,提高查询速度

适用场景:

表中的数据本身就有独立性,例如表中分别记录各个地区的数据或者不同时期的数据,特别是有些数据常用,有些不常用

需要把数据存放在多个介质上

缺点:

  1. 给应用增加复杂度,通常查询时需要多个表名,查询所有数据都需union操作
  2. 在许多数据库应用中,这种复杂性会超过他带来的优点,查询时会增加读一个索引层的磁盘次数

垂直分表:把主键和一些列放在一个表中,然后把主键和另外的列放在另一个表中

适用场景:

  1. 如果一个表中某些列常用,而另外一些列不常用
  2. 可以使数据行变小,一个数据页能存储更多的数据,查询时减少i/o次数

缺点:

  1. 管理冗余列,查询所有数据需要join操作

整体缺点:

有些分表的策略时基于应用层的逻辑算法,一旦逻辑算法改变,整个分表逻辑都会改变,扩展性较差

对于应用层来说,逻辑算法无疑增加开发成本

延伸:MySQL复制的原理及负载均衡

在主库上把数据更改记录到二进制日志,从库将主库的日志复制到自己的中继日志,从库读取中继日志中的事件,将其放到从库数据中

解决的问题:

数据分布:随意停止或开始复制,并在不同地理位置分布数据备份

负载均衡:降低单个服务器的压力

高可用和故障切换:帮助应用程序避免单点失败

升级测试:可以使用更高版本的MySQL作为从库

MySQL的安全性考点

sql语句应该考虑哪些安全性?

考点:

SQL查询的安全方案

  1. 使用预处理语句防止SQL注入
  2. 写入数据库的数据需要进行特殊字符转义
  3. 查询错误信息不要返回给用户,将错误记录到日志

延伸:MySQL的其他安全设置

  1. 定期做数据的备份
  2. 不给用户root权限,合理分配权限
  3. 关闭远程访问数据库的权限
  4. 修改root口令,不用默认口令,使用复杂的口令
  5. 删除多余的用户
  6. 改变root用户名称
  7. 限制用户浏览其他库
  8. 限制用户对数据文件的访问权限
为什么使用PDO和mysqli连接数据库比mysql函数连接更加安全

pdo和mysqli本身支持预处理,预处理的方式本身就可以防止SQL注入,所以比mysql函数更安全

程序设计类考点

编写一个在线留言板,实现用户的在线留言,留言信息存储在数据库,要求设计数据表内容以及PHP编码完成
设计一个无限分类表

常见框架的特性考点

PHP的框架有哪些,你用过那些,各自的优缺点

Yaf、phalcon框架:yaf使用PHP扩展的形式写的一个PHP框架,也就是C语言为底层编写的,性能上要比PHP代码写的框架快一个数量级别

优点:执行效率高,轻量级框架,可扩展性强

缺点:底层代码可读性差,需要安装扩展

Yii框架:是一款非常优秀通用web后端框架,结构简单优雅,实用功能丰富,扩展性强,性能高是它最突出的优点

缺点:学习成本高,相对于其他框架量级较重

TP:ThinkPHP是一种PHP敏捷开发框架,同时多个版本中存在代码执行等漏洞(参考:https://www.seebug.org/appdir/ThinkPHP ),官方更新周期超过2个月,缺乏漏洞及时反馈渠道,容易导致潜在安全风险无法修复,使用该框架可能存在较高安全风险,因此应该避免使用。

CakePHP是一款基于MVC的PHP Web框架,老版本包含多个漏洞(参考:https://www.cvedetails.com/vulnerability-list/vendor_id-11278/product_id-20394/Cakefoundation-Cakephp.html ),具有较高的安全风险,应该避免使用。

Symfony是一款基于MVC的PHP web框架,18年一年曝出多个高危漏洞(参考:https://www.cvedetails.com/vulnerability-list/vendor_id-11981/product_id-22402/Sensiolabs-Symfony.html ),50%的漏洞评分超过6分,如果更新不及时,具有较高的安全风险,应该避免使用

MVC基本原理考点
谈谈你对MVC的认识,介绍几种目前比较流行的MVC框架

MVC原理:Model+view+controller M:代表数据模型层,通常用于数据加工 V:视图层,跟用户交互界面上的一些展示,C:处理业务逻辑

常见的MVC框架:TP、yii、phalcon、Ci、YAf

单一入口工作原理:用一个处理程序文件处理所有HTTP请求,根据请求的参数区分不同的模块和操作等

​ 优势:可以进行统一的安全性检查、集中处理程序

​ 劣势:url地址不美观(url重写)、处理效率低

模板引擎的理解:PHP是一种HTML内嵌式的在服务端执行的脚本语言,但是PHP有很多可以使用PHP代码和HTML代码分开的模板引擎,例如:smarty、Twig、Haml、Liquid等

工作原理:模板引擎就是庞大的完善的正则表达式替换库

常见算法考察点

请写出常见的排序算法,并用PHP实现冒泡排序,将数组按照从小到大的方式进行排序。

考点:

冒泡排序的原理和实现:

原理:两两相邻的数进行比较,如果反序就交换,否则不交换

时间复杂度:最坏(o(n2)),平均(o(n2))

$a= [2,31,5,1,4,6];
$len=count($a);
for ($i=0;$i<$len;$i++){
   for($j=0;$j<$len-1;$j++){
     if($a[$j]>$a[$j+1]){
         $tmp=$a[$j];
         $a[$j]=$a[$j+1];
         $a[$j+1]=$tmp;
     }
   }  
  
}
print_r($a);

算法的概念:

1+2+3+4+…n的值是多少

解决特定问题求解的步骤,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作

公式:n(1+n)/2

概念:一个问题可以有多种算法,每种算法都有不同的效率

算法的特征:有穷性、确切性、输入项、输出项、可行性

时间复杂度和空间复杂度的概念:

算法的评定:

算法分析的目的在与选择合适的算法和改进算法。一个算法的评价主要从时间复杂度和空间复杂度来考虑

时间复杂度:执行算法所需要的计算工作量,一般来说,计算机算法是问题规模n的函数f(n),算法的时间复杂度也因此记做 T(n)=O(f(n)),问题的规模n越大,算法执行时间的增长率与f(n)的增长率正相关,称作渐进时间复杂度(Asymptotic Time complexity)

计算方式:

得出算法的计算次数公式

用常数1来代替所有时间中的所有加法常数

在修改后运行次数函数中,只保留最高阶项,如果最高阶项存在且不是1,则去除这个项相乘的常数

o(n^2),o(1),o(n)

举例:

常数阶o(1):

function test($n){

echo $n;

echo $n;

echo $n;

}

$n不管是多少只运行了三次,所以时间复杂度为o(3)记做o(1)

线性阶o(n):

1+2+3+4+…n的值是多少

$sum=0;

for (i=1;i=1;i=1;i<=n;n;n;i++){

sum+=sum+=sum+=i;

}

n代表要加的次数,时间复杂度:o(n),所以说时间复杂度就是那计算的次数

平(立)方阶o(n2)/o(n3):

$sum=0;

for(i=1;i=1;i=1;i<=n;n;n;i++){

for(j=1;j=1;j=1;j<=n;n;n;j++){

sum+=sum+=sum+=j;

}

}

里面的循环执行n次,外面的循环也执行n次,即n*n也就是n2即o(n2),如果是三种循环的话就是立方

对数阶:。。。。。

nlog2n阶:。。。。。

指数阶:。。。。。

空间复杂度

算法需要消耗的内存空间,记作S(n)=O(f(n))

包括程序代码所占用的空间,输入数据所占用的空间和辅助变量所占用的空间

计算和表示方法与时间复杂度类似,一般用复杂度的渐进性来表示

常见的排序算法:

冒泡排序、直接插入排序、希尔排序、选择排序、快速排序、堆排序、归并排序

常见的查找算法:

二分查找:

从数据的中间元素开始,如果中间元素正好是要搜索的元素,搜索结束,如果某一个特定的元素大于或者小于中间元素,则在大于或小于的中间元素的那一边查找,而且跟开始一样从中间开始比较,如果某一步骤为空,代表找不到。

顺序查找:按照一定的顺序检查数组中每一个元素,直到找到所要寻找的特定值为止。

时间复杂度:最差(o(n))平均:o(o(n)) 空间复杂度:o(1)

常见数据结构考察点

请简单描述一下数据结构的特征(stack,heap,list,doubly-linked-list,queue,array(vector))

array:数组,最简单最广泛的数据结构之一

特性:使用连续的内存来存储,数组中所有元素必须是相同的类型或类型的衍生(同质数据结构)、元素可以通过下标直接访问

linkedList:链表,线性表的一种,最基本最简单,也是最常用的数据结构

特性:元素之间的关系是一对一的关系(除了第一个和最后一个元素,其他元素都是首尾相接),顺序存储结构和链式存储结构两种存储方式

Stack:栈,和队列相似,一个带有数据存储特性的数据结构

特性:存储数据时先进后出的,栈只有一个出口,只能从栈顶部增加和移除元素,有点像试管一样,一个出口先进后出

Heap: 堆,一般情况下,堆叫二叉堆,近似完全的二叉树结构

特性:子节点的键值或索引总是小于它的父节点,每个节点的左子树是一个二叉堆,根节点最大的堆叫最大堆或大根堆,最小的叫最小堆或者小根堆

list:线性表,由零个或多个元素组成的有序数列

特征:线性表是一个序列。0个元素的线性时空表、第一个元素无先驱,最后一个元素无后继,其他元素都只有一个先驱和后继、有长度,长度是元素个数,长度有限

doubly-linked-list:双向链表

特性:每个元素都是一个对象,每个对象都有一个关键字key两个指针(next和prev)

queue:队列

特性:先进先出(FIFIO)、并发中使用,可以安全将对象从一个任务交给另一个任务

set:集合

特性:保存不重复的元素

map:字典

特性:关联数组,也被叫做字典或者键值对

graph:图

特性:通常使用邻接矩阵和邻接表表示,前者易于实现但是对于稀疏矩阵会浪费比较多的空间,后者使用链表的方式存储信息但是对于图搜索时间复杂度较高

用PHP实现一个双向队列

$queue=[2];
print_r($queue);
//从头插入
array_unshift($queue,1);
print_r($queue);
//从头移除
array_shift($queue);
print_r($queue);

//从尾插入
array_push($queue,3);
print_r($queue);
//从尾移除
array_pop($queue);
print_r($queue);
php .\tmp1.php
Array       
(
    [0] => 2
)
Array       
(
    [0] => 1
    [1] => 2
)
Array       
(
    [0] => 2
)
Array
(
    [0] => 2
    [1] => 3
)
Array
(
    [0] => 2
)

其他逻辑算法考察点

1,1,2,3,5,8,13,21,34…求第三十位的数是多少,请用伪代码描述其实现方法。

$a=[1,1];
for($i=2;$i<30;$i++){
   $a[$i]=$a[$i-1]+$a[$i-2];
}
print_r($a);
php .\tmp1.php
Array
(
    [0] => 1
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 5
    [5] => 8
    [6] => 13
    [7] => 21
    [8] => 34
    [9] => 55
    [10] => 89
    [11] => 144
    [12] => 233
    [13] => 377
    [14] => 610
    [15] => 987
    [16] => 1597
    [17] => 2584
    [18] => 4181
    [19] => 6765
    [20] => 10946
    [21] => 17711
    [22] => 28657
    [23] => 46368
    [24] => 75025
    [25] => 121393
    [26] => 196418
    [27] => 317811
    [28] => 514229
    [29] => 832040
)

模拟内置函数实现考察点

不使用PHP内置函数,用方法写一个字符串反转的函数

function str_rev($str=''){
   for($i=0;true;$i++){
      if(!isset($str[$i])){
         break;
      }
   }
   $return='';
   for($j=$i-1;$j>=0;$j--){
      $return.=$str[$j];
   }
   return $return;
}
$str='abcdef';
echo str_rev($str);
php .\tmp1.php
fedcba

写一个函数要求不使用array_merge完成多个数组合并

function array_mer(){
   $return=[];
   $arrays = func_get_args();
   foreach($arrays as $item){
      if (is_array($item)){
         foreach($item as $v){
            $return[]=$v;
         }
      }
   }
   return $return;
}
print_r(array_mer([1],[2],[3]));
php .\tmp1.php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)

高并发和大流量解决方案考察点

PHP如何解决网站大浏览与高并发问题

高并发的问题我们应该关心什么:

  • qps:指每秒钟请求或查询的数量,在互联网领域,指每秒响应请求数(HTTP)

  • 吞吐量:单位时间内处理的请求数量(通常由QPS与并发数、和响应时间决定)

  • 响应时间:从请求发出到收到响应花费的时间。

  • PV:综合浏览量(Page View),页面浏览量或者点击量,一个访客在24小时内访问的页面数量。同一个人浏览你的网站同一页面,只记作一次PV。

  • uv:独立访客(unique visitor)一定时间范围内相同访客多次访问网站,只计算为1个独立访客

  • 带宽:计算带宽大小需关注两个指标,峰值流量和页面的平均大小

    日网站带宽:PV/统计时间(换算到秒)*平均页面大小(单位kb)*8

    (总PV数*80%)/(6小时秒数*20%)=峰值每秒请求数 80%的访问量集中在20%的时间

流量优化
防盗链处理

前端优化

减少HTTP请求(合并js、cs文件)

添加异步请求

启用浏览器缓存和文件压缩

CDN加速(把一些前端的文件和一些资源都放在CDN中)

建立独立的图片服务器

服务端优化

页面静态化(把PHP处理的逻辑、页面缓存起来)

并发处理

队列处理

数据库优化

数据库缓存

分库分表、分区操作

读写分离

负载均衡

web服务器优化

负载均衡(nginx的反向代理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值