精华内容
下载资源
问答
  • PHP面试题

    2021-03-22 20:06:03
    词法结构1 php区分大小写吗?分析:用户定义的类和函数、内置的结构以及关键字例如echo,while,class是不区分大小写的,但是变量和常量区分大小写,例如$user,$User,$USER是3个不同的变量。表达式和操作符1.$a = ...

    词法结构

    题1 php区分大小写吗?

    分析:用户定义的类和函数、内置的结构以及关键字例如echo,while,class是不区分大小写的,但是变量和常量区分大小写,例如$user,$User,$USER是3个不同的变量。

    表达式和操作符

    题1.

    $a = 3;

    $b = 5;

    if($a = 5 || $b = 7) {

    $a++;

    $b++;

    }

    echo '$a = ',$a,', $b = ',$b;

    分析:该题考察php中操作符的优先级,根据 php手册,逻辑运算符||的优先级要高于赋值运算符=,因此if条件实际的顺序应该是if($a = (5 || $b = 7)),$a 的值是bool类型的,由于5为true,所以会执行$a++; $b++;,由于$a是bool类型的,所以$a++的结果仍然是1,用var_dump()打印$a的结果是boolean true,$b的结果是6。

    所以本题最后的结果是$a = 1, $b = 6。

    题2 不使用比较运算符求两个数中较大者

    function max($a, $b) {

    return ($a + $b + abs($a -$b)) / 2;

    }

    题3 求下面的程序输出什么

    echo '1+5='. 1 + 5,PHP_EOL;

    echo '1+5='. 5 + 1,PHP_EOL;

    echo '5+1='. 5 + 1,PHP_EOL;

    echo '5+1='. 1 + 5,PHP_EOL;

    分析:此题隐式转换和操作符优先级。.和+的优先级是相同的。字符串'1+5='. 1会转换成1,所以第一行会输出运算结果6,以此类推,后面3行输出2、6、10

    变量

    题1

    $a = array(1);

    $b = & $a[0];

    $c = $a;

    $c[0]++;

    echo $c[0].$a[0];

    分析:本题考察变量的引用。在赋值数组的时候,如果=右边的数据存在引用,那边赋值的新数组对应的元素也是引用,所以改变$c[0]的值 也会同时改变$a[0]的值,因此这段代码输出的结果是22。

    如果没有第2行$b = & $a,那么输出的结果是21。

    如果是$a是普通变量,例如

    $a = 1;

    $b = & $a;

    $c = $a;

    $c++;

    echo $c,$a;

    输出的结果也是21。

    题2

    $a = 1;

    $x = &$a;

    $b = $a++;

    求 $b 和 $x 的值

    分析:此题考察变量的引用赋值以及递增运算符(++$a, $a++, --$a, $a--)

    由于 $b = $a++;,因此 $b等于1,同时$a递增1,即此时$a等于2,由于$x是$a的引用,即$x是$a的别名,指向的是同一个内容,因此$x等于2。

    题3 以下代码输出什么

    $a = 2;

    $b = &$a;

    unset($a);

    echo $b;

    分析:此题同样考察变量的引用。在引用赋值之后,$a和$b有相同的值但不同的名称,销毁其中任何一个变量,不会影响其值的其他别名。

    题4 PHP如何管理内存,它的垃圾收集机制是怎样的

    分析:

    php使用引用计数和写时复制来管理内存。写时复制保证了变量间复制值不浪费内存,引用计数保证了不再需要时将内存释放给操作系统。

    当将一个变量的值复制到另一个变量时,php没有为复制值使用更多的内存,相反,它会更新符号表(符号表是一个将变量名映射到内存中变量值所在地址的数组)来说明这两个变量拥有相同的内存块,如果后来修改了任意一个副本,php将分配所学的内存来进行复制,例如:

    $username = ['dee', 'lee', 'john];

    $users = $username; // 数组不被复制

    $user[1] = 'jack'; // 值改变,数组被复制

    通过延迟分配和复制,php在很多情形下节省了时间和内存,这就是写时复制。符号表中每一个值都有一个引用计数器,它的数值表示获取那片内存的方式的数目。在上例中,在$username和$users初始化赋值后,数组指向了符号表,$username和$user的引用计数器的值为2,即那块内存有两种方式可以获得:通过$username和$users。当$users\[1\]被改变时,php为$users创建了一个新的数组,此时$username和$users的引用计数器的值各位1.

    当一个变量离开作用域,例如函数参数和局部变量到达函数末尾时,它的值的引用计数减1。当一个变量在其他内存空间被赋值时,旧值的引用计数减1。当引用计数的值为0时,他的内存被释放,这就是引用计数。

    题5 PHP中变量的生命周期

    分析:

    局部变量:为其所在函数被调用的整个过程。当局部变量所在的函数结构结束时,局部变量的生命周期也随之结束。

    全局变量:为其所在“.php”脚本文件被调用的整个过程。当全局变量所在脚本文件结束调用时,全局变量的生命周期结束

    静态变量:有时某个定义函数结束后,我们希望该函数内的变量仍然存在,就需要将这个变量声明为静态变量(static)。

    题6 请说说你对PHP中引用类型和值类型的理解

    分析:

    值类型:大部分变量类型,如字符串,整型,浮点型,数组等,赋值时会在内存中创建一个新的变量。

    引用类型:引用就是创建变量的别名。赋值之后两个变量拥有相同的变量但是不同的名称。对象的赋值不会创建新的变量。引用的优点是,当大的字符串或数组进行赋值时可以节省资源。

    题7 交换两个变量的值,不使用新的变量

    分析:

    方法① 使用异或运算符

    $a = 4;

    $b = 3;

    $a = $a ^ $b;

    $b = $a ^ $b;

    $a = $a ^ $b;

    方法②

    使用list()函数

    $a = 'memcached';

    $b = 'redis';

    list($a, $b) = array($b, $a);

    题7 用最短的代码找出3个数字中的最大值

    分析:可以使用三元运算

    ($a = ($a > $b ? $a : $b)) > $c ? $a : $c;

    不够短?还可以使用max()函数:

    $max = max(array($a, $b, $c));

    题8 以下代码会输出?

    $A="Hello";

    function print_A() {

    $A= "php mysql !!";

    global$A;

    echo$A;

    }

    echo$A;

    print_A();

    分析:HelloHello

    第一次执行echo $A; ,$A的值是Hello, 第二次在方法中赋值的$A是局部变量, global $A声明全局变量$A ,则在函数中echo $A由于是全局变量所以值还是Hello 。如果本题在globle $A后执行$A = "php mysql" 结果就是Hellophp mysql!!了。

    函数

    题1 include, include_once, require, require_once这几个函数有什么区别?

    分析:

    include和require这两个关键字都是包含并运行指定文件,不同的是include在引入不存的文件时产生一个警告且脚本还会继续执行,而require则会导致一个致命性错误且脚本停止执行

    include_once语句与include类似,唯一的区别是如果该文件中已经被加载成功了,则后续再次加在同一个文件的操作会被忽略,require_once与require的区别也是如此。

    题2 isset() 、empty()与is_null的区别

    分析:

    isset()函数检测变量是否设置,如果变量存在并且值不是 NULL 则返回 TRUE,否则返回 FALSE。

    empty()函数检查一个变量是否为空,当变量存在,并且是一个非空非零的值时返回 FALSE 否则返回 TRUE

    is_null()函数检测变量是否为 NULL,如果变量是 null 则返回 TRUE,否则返回 FALSE。

    题3 php中传值与传引用的区别

    按值传递:函数范围内对值的任何改变在函数外部都会被忽略

    引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改

    题4 用php写出显示客户端IP、服务器端IP的代码和网页地址

    客户端IP:$_SERVER["REMOTE_ADDR"]

    服务器端IP:$_SERVER["SERVER_ADDR"]

    网页地址:$_SERVER["REQUEST_URI"]

    当前脚本的执行路径:$_SERVER["SCRIPT_FILENAME"]或者__FILE__

    当前脚本的名称:$_SERVER["PHP_SELF"]或者$_SERVER["SERIPT_NAME"]

    链接到前一页的URL地址:$_SERVER["HTTP_REFERER"]

    题5 echo,print(),print_r(),printf(),sprintf(),var_dump()有什么区别

    echo是语言结构,用于输出字符串到页面

    print()函数发送一个值(它的参数)给浏览器

    print_r()函数可以智能地显示传给它的参数,可以打印字符串和数字,也可以打印数组和对象

    printf()函数可以通过替换模版中的值输出字符串

    var_dump()比print_r()更适合调试,它用更适合阅读的格式显示所有php的值

    题6 php中对数组序列化和反序列化的函数,把utf-8转换成gbk的函数

    serialize,unserialize,iconv("utf-8","gbk",$strs)

    题7 strlen()与mb_strlen的作用分别是什么?

    strlen()无法正确处理中文字符串的占位,对于gb2312得到的是汉字个数的2倍,utf8得到的是汉字个数的3倍

    mb_strlen()就很好的解决了这个问题,它的第二个参数就是设置字符编码的

    题7 exit和return有什么区别

    分析:

    脚本执行到exit语句时,就会停止执行

    return语句一般用于某个函数退出返回,或者囧啊本停止执行

    字符串

    题1 使用5种方式获取一个文件的扩展名

    分析:

    可以使用php内置的函数、数组函数、字符串函数来实现。

    1.内置函数pathinfo(),在返回的数组中键为extension的值就是扩展名

    $filename = 'pic.20160626.jpg';

    $pathinfo = pathinfo($filename);

    var_dump($pathinfo['extension']); // jpg

    2.同样使用内置函数pathinfo(),带上第二个参数PATHINFO_EXTENSION

    $ext = pathinfo($filename, PATHINFO_EXTENSION);

    var_dump($ext);

    3.数组函数explode()+count()

    $arr = explode('.', $filename);

    var_dump($arr[count($arr) - 1]); // jpg

    4.字符串函数strrpos()+substr():strrpos()用于计算指定字符串在目标字符串中最后一次出现的位置

    $position = strrpos($filename, '.');

    var_dump(substr($filename, $position + 1)); // jpg

    5.字符串函数strrchr():strrchr()查找指定字符在字符串中的最后一次出现,并该函数返回字符串的一部分

    var_dump(strrchr($filename, '.')); // .jpg

    题2 给任意一段URL,取出该URL中包含的扩展名

    分析:

    类似于上一题。也可以使用内置函数parse_url()+basename()来解析URL:

    $url = 'http://www.sina.cn/index.php?username=dee';

    $parse_url = parse_url($url);

    $basename = basename($parse_url['path']); // index.php

    $arr = explode('.', $basename);

    $ext = array_pop($arr); // php

    题3 PHP中单引号和双引号有什么区别?哪个速度更快?

    分析:

    1.用单引号括起来的变量不能被解析

    2.在单引号括起来的字符串中只有单引号'和反斜线܀要用反斜线转义;用双引号括起来的变量能够被解析,有双引号、换行符、回车、制表符、大括号、中括号等需要转义。

    3.如果包含的字符串中含有变量,使用单引号更快,因为单引号不会解析变量,而双引号解析变量需要时间。

    数组

    题1 写个函数用来对二维数组排序

    解析:

    情况一、如果是针对二维数组中每个元素的某个值进行排序,例如

    $arr = [

    ['name'=>'dee','age'=>28],

    ['name'=>'emperor', 'age'=>27],

    ['name'=>'Lee', 'age'=>20],

    ['name'=>'Arshavin', 'age'=>33],

    ['name'=>'Totti', 'age'=>40],

    ['name'=>'K6', 'age'=>27],

    ];

    按照age的值从小到大进行排序

    解法① 可以使用usort()函数

    $arr = [

    ['name'=>'dee','age'=>28],

    ['name'=>'emperor', 'age'=>27],

    ['name'=>'Lee', 'age'=>20],

    ['name'=>'Arshavin', 'age'=>33],

    ['name'=>'Totti', 'age'=>40],

    ['name'=>'K6', 'age'=>27],

    ];

    usort($arr, function($a, $b){

    return $a['age'] >= $b['age'] ? 1 : 0;

    });

    var_dump($arr);

    解法② 使用array_multisort()函数

    $arr = [

    ['name'=>'dee','age'=>28],

    ['name'=>'emperor', 'age'=>27],

    ['name'=>'Lee', 'age'=>20],

    ['name'=>'Arshavin', 'age'=>33],

    ['name'=>'Totti', 'age'=>40],

    ['name'=>'K6', 'age'=>27],

    ];

    $age = [];

    foreach($arr as $val) {

    $age[] = $val['age'];

    }

    array_multisort($age, SORT_ASC, $arr);

    var_dump($arr);

    情况二、如果是针对二维数组中每个元素的某几个值进行排序,例如

    $arr = [

    ['name'=>'dee','age'=>28, 'height'=>180],

    ['name'=>'emperor', 'age'=>27, 'height'=>181],

    ['name'=>'Lee', 'age'=>20, 'height'=>170],

    ['name'=>'Arshavin', 'age'=>33, 'height'=>173],

    ['name'=>'Totti', 'age'=>40, 'height'=>183],

    ['name'=>'Jonh', 'age'=>27, 'height'=>170],

    ];

    要根据age从小到到,age相同的按height从大到小排序:

    $arr = [

    ['name'=>'dee','age'=>28, 'height'=>180],

    ['name'=>'emperor', 'age'=>27, 'height'=>181],

    ['name'=>'Lee', 'age'=>20, 'height'=>170],

    ['name'=>'Arshavin', 'age'=>33, 'height'=>173],

    ['name'=>'Totti', 'age'=>40, 'height'=>183],

    ['name'=>'Jonh', 'age'=>27, 'height'=>170],

    ];

    $age = $height = [];

    foreach($arr as $val) {

    $age[] = $val['age'];

    $height[] = $val['height'];

    }

    array_multisort($age, SORT_ASC, $height, SORT_DESC, $arr);

    var_dump($arr);

    情况三、如果是针对多维数组中每个元素的某几个值进行排序,例如

    $arr = [

    ['name'=>'dee','info'=>['subinfo'=>['age'=>28, 'height'=>180]]],

    ['name'=>'emperor', 'info'=>['subinfo'=>['age'=>27, 'height'=>181]]],

    ['name'=>'Lee', 'info'=>['subinfo'=>['age'=>20, 'height'=>170]]],

    ['name'=>'Arshavin', 'info'=>['subinfo'=>['age'=>33, 'height'=>173]]],

    ['name'=>'Totti', 'info'=>['subinfo'=>['age'=>40, 'height'=>183]]],

    ['name'=>'Jonh', 'info'=>['subinfo'=>['age'=>27, 'height'=>170]]]

    ];

    要根据age从小到到,age相同的按height从大到小排序:

    $arr = [

    ['name'=>'dee','info'=>['subinfo'=>['age'=>28, 'height'=>180]]],

    ['name'=>'emperor', 'info'=>['subinfo'=>['age'=>27, 'height'=>181]]],

    ['name'=>'Lee', 'info'=>['subinfo'=>['age'=>20, 'height'=>170]]],

    ['name'=>'Arshavin', 'info'=>['subinfo'=>['age'=>33, 'height'=>173]]],

    ['name'=>'Totti', 'info'=>['subinfo'=>['age'=>40, 'height'=>183]]],

    ['name'=>'Jonh', 'info'=>['subinfo'=>['age'=>27, 'height'=>170]]]

    ];

    function get_key($arr, $key) {

    $weight = [];

    if(is_array($arr)) {

    foreach ($arr as $k => $v) {

    if ($key === $k) {

    $weight[] = $v;

    } else {

    $tmp = get_key($v, $key);

    if(! empty($tmp)) {

    $weight[] = $tmp[0];

    }

    }

    }

    return $weight;

    }

    }

    $age = 'age';

    $age = get\_key($arr, $age);

    $height = 'height';

    $height = get\_key($arr, $height);

    array_multisort($age, SORT\_ASC, $height, SORT_DESC, $arr);

    echo '

    ';

    print_r($arr);

    类和对象

    题1 接口与抽象类的区别是什么?

    抽象类:

    抽象类是不能被实例化的类,只能作为其他类的父类来使用,抽象类是通过关键字abstract来声明

    抽象类与普通类类似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少包含一个抽象方法

    抽象方法没有方法体,该方法天生就是要被子类重写的

    抽象方法的格式为:abstract function abstractMethod()

    子类继承抽象类使用extends

    接口:

    接口是通过interface关键字来声明,接口中的成员常量和方法都是public的,方法可以不写关键字public

    接口中的方法也是没有方法体的,接口中的方法也是天生要被子类实现的

    接口能实现多继承

    子类实现接口使用implements

    题2 以下代码会输出什么

    class Dog {

    public $age;

    public function __construct($age) {

    $this->age = $age;

    }

    }

    function test($dog) {

    $dog->age = 10;

    }

    $dog = new Dog(100);

    test($dog);

    echo $dog->age;

    题3 以下代码会输出什么

    class Dog {

    public $age;

    public function __construct($age) {

    $this->age = $age;

    }

    }

    function test($dog) {

    $dog = new Dog(10);

    }

    $dog = new Dog(100);

    test($dog);

    echo $dog->age;

    题4 以下代码会输出什么

    class Dog {

    public $age;

    public function __construct($age) {

    $this->age = $age;

    }

    }

    function test($dog) {

    $dog = null;

    }

    $dog = new Dog(100);

    test($dog);

    echo $dog->age;

    题5 以下代码会输出什么

    class Dog {

    public $age;

    public function __construct($age) {

    $this->age = $age;

    }

    }

    function test(&$dog) {

    $dog = new Dog(10);

    }

    $dog = new Dog(100);

    test($dog);

    echo $dog->age;

    错误和异常

    缓存与静态化

    时间日期

    题1 知道一天的日期,求任意一天叮得日期

    题2 用php打印出前一天的时间格式

    文件

    题1 写一个函数,算出两个文件的相对路径

    function relative_path($a, $b) {

    $a2arr = explode('/', $a);

    $b2arr = explode('/', $b);

    $diff = array_diff($a2arr, $b2arr);

    $count = count($diff);

    $relative = str_repeat('../', $count);

    array_pop($b2arr);

    return $relative.implode('/', array_diff($b2arr, $a2arr));

    }

    题2 写一个函数,能够遍历一个文件夹下的所有文件和子文件夹

    function tree($dir) {

    static $files;

    if(is_dir($dir)) {

    if($handle = opendir($dir)) {

    while(($file = readdir($handle)) !== false) {

    if(is_dir("$dir/$file")) {

    if(! in_array($file, array('.', '..'))) {

    $files[] = "$dir/$file";

    tree("$dir/$file");

    }

    } else {

    $files[] = "$dir/$file";

    }

    }

    }

    }

    return $files;

    }

    $dir = 'D:practise/test';

    题3 删除某目录下的子目录及文件

    分析:需要使用到的目录函数包括is_dir()、opendir()、readdir()、rmdir()、closedir();需要用到的文件函数包括is_file()、unlink(),使用递归算法

    function deldir($dir) {

    if(is_dir($dir)) {

    $handle = opendir($dir);

    while (false !== ($file = readdir($handle))) {

    if($file == '.' || $file == '..'){

    continue;

    }

    if(is_dir($dir.'/'.$file)) {

    deldir($dir.'/'.$file);

    } else {

    unlink($dir.'/'.$file);

    }

    }

    closedir($handle);

    rmdir($dir);

    } elseif(is_file($dir)) {

    unlink($dir);

    } else {

    return 'error dir';

    }

    return 'del complete';

    }

    题4 php中Web上传文件的原理是什么,如何限制上传文件的大小?

    分析:

    通过form表单使用POST方法上传,可以使用户上传文本和二进制文件

    客户端html部分如下

    服务端通过$\_FILES接收通过HTTP上传到服务器的文件,上传的内容存储在$_FILES'xx'中,然后再通过move_uploaded_file,将上传的文件移动到新位置:

    if(! empty($_FILES)) {

    if(is_uploaded_file($_FILES['userfile']['tmp_name'])) {

    if($_FILES['userfile']['error'] == UPLOAD_ERR_OK) {

    $upload_dir = './upload';

    $tmp_name = $_FILES['userfile']['tmp_name'];

    $name = $_FILES['userfile']['name'];

    if(move_uploaded_file($tmp_name, $upload_dir.'/'.$name)) {

    echo 'success.';

    } else {

    echo 'error';

    }

    }

    }

    }

    有多个配置可以限制上传文件的大小,在php.ini中:

    post_max_size:(php 5.5.12)默认3M

    upload_max_filesize:(php 5.5.12)默认64M

    max_execution_time:必要的情况下还需要修改该配置,设置了脚本被解析器中止之前允许的最大执行时间,单位秒。(php 5.5.12)默认120

    memory_limit:(php 5.5.12)默认128M

    Cookie和Session

    题1 禁用COOKIE 后 SEESION 还能用吗?

    分析:在默认情况下(PHP>=4.3.0),php.ini中session.use_only_cookies的值为1,也就是说在不更改任何配置的情况下,禁用了浏览器的 Cookie 功能,是没有办法使用 Session 的,因为默认情况下,Session_ID 保存在 Cookie 中。如果希望在禁用了 Cookie 之后仍然可以使用 Session,至少需要更改php.ini中的以下几个配置:session.use_cookies改为0、session.use_only_cookies改为0、·session.use_trans_id·改为1(表示Session_ID通过url的参数进行传递)。使用url传递Session_ID相比使用Cookie传递Session_ID来说非常不安全,一是完全暴露Session_ID,二是容易遭到Session固定攻击。

    题2 如何设置session的过期时间

    分析:如果没有设定Session的生存周期,保存Session_ID的Cookie是保存在内存中的,关闭浏览器后该ID自动注销。如果客户端没有禁用Cookie,Cookie在启动Session时扮演的是存储Session_ID和Session生命周期的角色,可以手动设置Session的生存期:

    $lifetime = 24 * 3600;

    set_cookie(session_name(), session_id(), time() + $lifetime, '/');

    也可以使用 session_set_cookie_params()函数设置Session的生存期。

    Session过期后,PHP会对其进行回收,因此Session并不是随着浏览器的关闭而消失。

    如果浏览器禁用了Cookie,那么Session的生命周期会随着浏览器进程的结束而结束,即只要关闭了浏览器,再次请求页面就要重新注册Session。

    题3 请介绍Session的原理

    分析:由于HTTP协议的无状态特性,协议本身并不支持服务器端保存客户端的状态信息,为了让服务器端和客户端保持联系,引入了Session的概念,用其来保持客户端的状态信息。Session通过一个成为PHPSESSID(可以更改名称)的Cookie和服务器端联系。Session通过Session_ID判断用户。

    当使用了session_start()函数,用户第一次访问站点时,PHP会为用户创建一个session ID,这就是该用户的唯一标识,每一个访问的用户都会得到一个自己唯一的session ID。session ID会存放在响应头(Response)里的cookie中,之后发送给客户端,于是客户端就有了该用户在这个站点的session ID。当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求(Request)一起发送到服务器,服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就重新创建一个Session_ID。

    题4 如何注销Session

    分析:Session的注销分为4个步骤:

    1.开启Session,所有有关Session的操作都需要先开启Session(除非在php.ini中设置session.auto_start为1,默认为0)

    session_start();

    2.删除所有的session变量,即把session数组清空

    $_SESSION = array();

    3.如果是基于Cookie的Session,则需要把保存Session_ID的Cookie删除

    if(isset($_COOKIE[session_name()])) {

    setcookie(session_name(), '', time() - 1, '/');

    }

    4.彻底销毁Session

    session_destroy();

    题5 简述Session的回收机制

    分析:如果用户退出网站时没有主动注销帐号,那么Session的回收将是被动的。php.ini中和Session回收有关的配置有:

    session.gc_maxlifetime:表示 Session 文件的过期时间,默认为 1440 秒即 24分钟

    session.gc_probability:默认值为1

    session.gc_divisor:默认值为1000

    后面两个配置代表 session_start() 函数每调用 1000 次触发一次 Session 文件的全部扫描,把过期的 Session 文件删除。过期的 Session 文件的判断标准是:文件的修改时间和当前时间相差是否大于 session.gc_maxlifetime。当用户每进行一个操作哪怕是一个刷新页面的动作时,都会修改 Session 文件的修改时间。对于设置分级目录存储的Session,php不会自动回收,需要自己实现回收机制。

    题6 session共享问题解决方案

    分析:可以将Session入库(普通数据库、内存表),或者使用内存存储系统例如Redis来存储Session,达到服务器间Session的共享。通过session_save_handler()函数实现。

    题7 大型网站中Session方面应注意什么

    分析:大型网站有很多衡量标准,访问量是其中一个。对于大访问量的网站,如果Session按照默认的设置存储,会影响系统性能。默认情况下,Session由文件的形式保存在指定的目录下,如果同一个目录下文件数超过10000,文件的定位将会非常耗时,可以通过修改php.ini中session.save_path将Session文件存储在多级目录下;也可以保存在数据库中;最好的方式是保存在key-value形式的内存数据库中,例如Redis。

    另一个方面,大型网站一般有多台服务器,要做好Session的同步。如果是使用数据库或者NoSQL来存储Session,Session的同步会比较容易。如果是文件形式保存Session文件,可以使用NFS或者FastDFS等文件系统存储Session文件。

    题8 Session和Cookie的联系和区别

    分析:

    如果不修改php的配置,则Session是基于Cookie的:Session的唯一标识Session_ID保存在Cookie中,通过Cookie中的Session_ID来维持服务器端和客户端之间的状态。

    可以通过设置保存Session_ID的Cookie的过期时间来设置Session的生存周期。

    Cookie通过文件或者数据库的形式保存客户端,Session通过文件、数据库等形式保存在服务器端。

    题9 服务器端设置了cookie的过期时间,然后修改本地时间小于cookie过期时间,cookie会不会被删除

    分析:

    会。因为Cookie的过期时间依赖于客户端时钟的标准。

    题10 如何设置Cookie的过期时间,关闭浏览器Cookie会消失吗

    分析:

    通过setcookie()函数的第三个参数expire设置Cookie的过期时间,单位为秒,例如

    setcookie('username', 'dee', time() + 24 * 3600, '/');

    这段代码表示name为username的Cookie,会在24小时后过期。

    如果要删除某个Cookie,同样使用setcookie()函数,例如

    setcookie('user', '', time() - 1, '/');

    只需要把Cookie的过期时间改为小于当前的一个时间即可。

    HTTP协议

    题1 HTTP状态码

    题2 get请求和post请求的区别

    算法

    题1 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    分析:可以用递归和递推两种方法实现。

    ① 递归

    如果台阶只有 1 级,则只有 1种跳法,如果台阶有2级,则有2种跳法(一次1级跳2次或一次2级)。把n级台阶时的跳法设为f(n),如果第一次只跳1级,则后面的n-1级的跳法为f(n-1),如果第一次跳2级,则后面n-2级的跳法为f(n-2)。当n > 2时,n级台阶的跳法为f(n) = f(n-1) + f(n-2),这就是一个斐波那契数列的问题

    function fibonacci($n) {

    $result = [0, 1, 2];

    if($n <= 2) {

    return $result[$n]; // $n = 1,1种跳法;$n = 2,2种跳法

    }

    return fibonacci($n - 1) + fibonacci($n - 2);

    }

    ② 递推

    function climbstairs($n) {

    $dp = [1, 1];

    if($n < 2) {

    return 1;

    }

    for($i = 2; $i <= $n; $i++) {

    $dp[2] = $dp[0] + $dp[1];

    $dp[0] = $dp[1];

    $dp[1] = $dp[2];

    }

    return $dp[2];

    }

    题2 用一段代码实现无限级分类

    分析:此题考察递归算法。

    function level_layer($cate, $name = 'child', $pid = 0) {

    $arr = [];

    foreach($cate as $val) {

    if($val['pid'] == $pid) {

    $val[$name] = level_layer($cate, $name, $val['id']);

    $arr[] = $val;

    }

    }

    return $arr;

    }

    $data = [

    ['id' => 1, 'title' => '北京市', 'pid' => 0],

    ['id' => 2, 'title' => '朝阳区', 'pid' => 1],

    ['id' => 3, 'title' => '海淀区', 'pid' => 1],

    ['id' => 4, 'title' => '江西省', 'pid' => 0],

    ['id' => 5, 'title' => '九江市', 'pid' => 4],

    ['id' => 6, 'title' => '浔阳区', 'pid' => 5],

    ['id' => 7, 'title' => '庐山区', 'pid' => 5],

    ['id' => 8, 'title' => '南昌市', 'pid' => 4],

    ['id' => 9, 'title' => '河北省', 'pid' => 0],

    ['id' => 10, 'title' => '保定市', 'pid' => 9],

    ['id' => 11, 'title' => '石家庄市', 'pid' => 9],

    ['id' => 12, 'title' => '江苏省', 'pid' => 0],

    ['id' => 13, 'title' => '浙江省', 'pid' => 0],

    ];

    echo '

    '; print_r(level_layer($data));

    题3 一群猴子排成一圈,按 1,2,...,n 依次编号。然后从第 1 只开始数,数到第 m 只,把它踢出圈,从它后面再开始数,再数到第 m 只,在把它踢出去...,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入 m、n,输出最后那个大王的编号。

    分析:这是一个“约瑟夫环”问题,可以使用循环队列、循环链表等多种方法来解决,这里使用循环链表。

    // 猴子类,链表上的每一个元素

    class Monkey {

    public $number;

    public $name = null;

    public function __construct($number, $name = null) {

    $this->number = $number;

    $this->name = $name;

    }

    }

    // 初始化链表,添加元素

    function init(&$first, $n) {

    $current = null;

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

    $monkey = new Monkey($i + 1);

    if($i == 0) {

    $first = $monkey;

    $first->next = $monkey; // 只有一个元素时

    $current = $first;

    } else {

    $current->next = $monkey;

    $monkey->next = $first; // $monkey 是变化的

    $current = $current->next;

    }

    }

    }

    // 显示链表

    function showList($first) {

    $current = $first;

    while($current->next != $first) {

    echo '猴子的编号是:',$current->number,'
    ';

    $current = $current->next;

    }

    echo '猴子的编号是:',$current->number,'
    ';

    }

    // 删除元素

    function delElement($first, $m, $start = 1) {

    $tail = $first; // 指向尾部节点的引用,在first节点之前

    while($tail->next != $first) {

    $tail = $tail->next; // 把tail节点设置在first节点之前

    }

    // 从第几个元素开始数

    for($i = 0; $i < $start - 1; $i++) {

    $tail = $tail->next;

    $first = $first->next;

    }

    while($tail != $first) { //当$tail==$first则说明只有最后一个元素

    for($i = 0; $i < $m - 1; $i++) {

    $tail = $tail->next;

    $first = $first->next;

    }

    echo '
    删除编号 '.$first->number,' 的元素';

    // 跳过被删除的节点(first指向的节点)

    $first = $first->next;

    $tail->next = $first;

    }

    echo '
    最后剩下的编号是: '.$tail->number;

    }

    $n = 4; // 元素的个数(猴子的数量)

    $m = 3; // 每次数几个元素

    $start = 1; // 从第几个元素开始数

    $first = null; // 链表头部节点的引用

    init($first, $n);

    showList($first);

    delElement($first, $m, $start);

    题4 写一段php代码实现冒泡排序

    解答:

    function bubble($array) {

    $count = count($array);

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

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

    // 递减

    if($array[$j] < $array[$j + 1]) {

    $tmp = $array[$j];

    $array[$j] = $array[$j + 1];

    $array[$j + 1] = $tmp;

    }

    }

    }

    return $array;

    }

    题5 写一段php代码实现快速排序

    /*快速排序*/

    function quick_sort($array) {

    // 递归到只有一个元素

    if(count($array) <= 1) {

    return $array;

    }

    $key = $array[0];

    $left_arr = [];

    $right_arr = [];

    // 左边数组的元素都比右边数组的元素小

    for($i = 1; $i < count($array); $i++) {

    if($array[$i] <= $key) {

    $left_arr[] = $array[$i];

    } else {

    $right_arr[] = $array[$i];

    }

    }

    // 递归对左右两个数组分别进行排序

    $left_arr = quick_sort($left_arr);

    $right_arr = quick_sort($right_arr);

    // 合并结果

    return array_merge($left_arr, array($key), $right_arr);

    }

    $arr = [10, 21, 1, 3, 89, 27, 75, 45, 91, 200, 451, 37, 2];

    var_dump(quick_sort($arr));

    题6 写一段php代码实现二分查找

    function binarySearch(array $array, $needle) {

    $start = 0;

    $end = count($array) - 1;

    while($start < $end) {

    $middle = floor(($start + $end) / 2);

    if($array[$middle] == $needle) {

    return $middle;

    }

    if($needle < $array[$middle]) {

    $end = $middle - 1;

    }

    if($needle > $array[$middle]) {

    $start = $middle + 1;

    }

    }

    return false;

    }

    题7 换硬币问题:如果有100元,可以使用1元、2元、5元、10元4种面额的零钱来兑换,有多少种兑换方法?

    $a = 1;

    $b = 2;

    $c = 5;

    $d = 10;

    $sum = 0;

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

    for ($j = 0; $j <= 50; $j++) {

    for ($k = 0; $k <= 20; $k++) {

    for($h = 0; $h <= 10; $h++) {

    if ($a * $i + $b * $j + $c * $k + $d * $h == 100) {

    $sum += 1;

    printf("%d个1元,%d个2元,%d个5元,%d个10元
    ", $i, $j, $k, $h);

    }

    }

    }

    }

    }

    printf("共%d种换法", $sum);

    题8 鸡兔同笼问题

    正则表达式

    题1 请写一个函数验证电子邮件的格式是否正确

    设计模式

    题1 请用单态设计模式方法设计类满足如下需求,使用php代码编写类实现在每次对数据库连接的访问中都只能获取唯一的一个数据库连接,具体连接数据库的详细代码忽略,请写出主要逻辑代码。

    MySQL

    题1 where和having的区别

    题2 内连接、左连接、右连接的区别

    题3 mysql优化常见的方案

    题4 explain的用法

    题5 索引的种类和用法

    题6 mysql的存储引擎Innodb和MyISAM的区别

    题7

    一个足球网站有一张新闻表news,字段包括新闻编号id、新闻分类cid、标题title、点击量click,现在需要对 news 表按照 cid (分类id)进行过分组,按照每组新闻的数量进行排序,同时取出每组点击量(click)最多的两篇新闻。

    分析:

    创建表

    CREATE TABLE `news` (

    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '新闻编号',

    `cid` int(11) NOT NULL COMMENT '分类编号 例如 1 世界足球新闻 2 英超新闻 3 西甲新闻',

    `title` varchar(25) NOT NULL COMMENT '新闻标题',

    `click` int(11) NOT NULL DEFAULT '0' COMMENT '点击量',

    PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

    表数据

    INSERT INTO `news` VALUES ('1', '1', '法国2-0力克德国进决赛', '1888');

    INSERT INTO `news` VALUES ('2', '2', '传曼联1亿英镑报价博格巴', '201');

    INSERT INTO `news` VALUES ('3', '3', '队报:巴萨接近签法国国脚', '150');

    INSERT INTO `news` VALUES ('4', '1', '克罗斯:德国队表现最好的一场', '100');

    INSERT INTO `news` VALUES ('5', '1', '决赛对阵:法国vs葡萄牙', '205');

    INSERT INTO `news` VALUES ('6', '1', '格列兹曼6场6球仅次普拉蒂尼', '211');

    INSERT INTO `news` VALUES ('7', '1', '阿森纳法国双星赛后安慰厄齐尔', '188');

    INSERT INTO `news` VALUES ('8', '2', '回声报:利物浦要求艾比交易中加入回购条款', '11');

    INSERT INTO `news` VALUES ('9', '3', '普约尔:没有比巴萨更适合梅西的地方', '225');

    INSERT INTO `news` VALUES ('10', '3', '皇家贝蒂斯有意狼堡前锋多斯特', '13');

    INSERT INTO `news` VALUES ('11', '3', '哈维:我觉得梅西不会想离开巴萨的', '1000');

    INSERT INTO `news` VALUES ('12', '2', '传温格已将西迪贝看作重点目标', '1200');

    此题的需求是 1.按新闻分类分组 2.按照新闻分类下新闻数量给分好的组排序 3.排好序的分组还需要取出该组分类下点击量最多的两篇新闻

    需求1 可以使用group by来进行分组

    需求2 可以使用count()+group by,取出每组分类下新闻的数量

    以上2个需求可以用一条sql完成

    select *, count(*) as num from news group by cid order by num desc;

    查询结果

    84f06c19283102847448e9aa2fdf4932.png

    可以看到已经按照数量num进行了排序

    需求3 可以cid+click进行排序,这个需求可以用一条sql完成,用子查询实现

    select a.* from news a

    where (

    select count(*) from news b where a.cid = b.cid and b.click > a.click

    ) < 2

    order by cid, click desc;

    查询结果

    9f197abf3d8a7d1bcba881d8094e6754.png

    此时每个cid下点击量最多的两篇文章已经查询出来了,只不过查询的结果没有按照每个分类下新闻数量的多少来排序

    只需要最后一步,把两个sql语句进行左(右)连接即可

    select * from (

    select a.* from news a

    where (

    select count(*) from news b where a.cid = b.cid and b.click > a.click

    ) < 2

    order by cid, click desc

    ) tablea RIGHT JOIN (

    select cid, count(*) as num from news group by cid order by num desc

    ) tableb on tablea.cid = tableb.cid

    order by tableb.num desc, click desc;

    查询结果:

    685f1df9231258424df6b85f2386fc7a.png

    题8 一张表有id,sortid,title,如何按照sortid进行分组,按照sortid数量进行排序,输出结果。

    分析:此题和题6类似。

    表结构

    CREATE TABLE `test` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `title` varchar(25) NOT NULL,

    `sortid` int(11) NOT NULL DEFAULT '0',

    PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

    创建数据

    INSERT INTO `test` VALUES ('1', 'title1', '106');

    INSERT INTO `test` VALUES ('2', 'title2', '78');

    INSERT INTO `test` VALUES ('3', 'title3', '56');

    INSERT INTO `test` VALUES ('4', 'title4', '78');

    INSERT INTO `test` VALUES ('5', 'title5', '78');

    INSERT INTO `test` VALUES ('6', 'title6', '12');

    INSERT INTO `test` VALUES ('7', 'title7', '56');

    分三步创建sql

    -- step 1

    select a.* from test a

    where (

    select count(*) from test b where b.sortid > a.sortid

    ) < (select count(*) from test)

    order by sortid;

    -- step2

    SELECT *, count(*) AS num, GROUP_CONCAT(id) AS ids FROM test GROUP BY sortid ORDER BY num;

    -- final

    select * from (

    select a.* from test a

    where (

    select count(*) from test b where b.sortid > a.sortid

    ) < (select count(*) from test)

    order by sortid

    ) tablea LEFT JOIN (

    SELECT *, count(*) AS num, GROUP_CONCAT(id) AS ids FROM test GROUP BY sortid ORDER BY num

    ) tableb

    on tablea.sortid = tableb.sortid

    order by tableb.num asc;

    此题没有要求列出每个分组的前N条数据,那就把每个分组下所有的数据都列出来,查询结果如下:

    3242acd4483882ca80cd56a365b11517.png

    题9

    有如下表及数据

    name

    subject

    score

    张三

    数学

    90

    张三

    语文

    50

    张三

    地理

    40

    李四

    语文

    55

    李四

    政治

    45

    王五

    政治

    30

    要求:查询出2门及2门以上不及格者的平均成绩

    解析:

    先查出所有人的平均分(AVG(score)),再找出每个人2门及2门以上不及格的数量(SUM(score<60)),最后筛选出数量大于等于2的人的信息(Having num>=2)

    SELECT name, AVG(score) AS avg, SUM(score < 60) AS num

    FROM result

    GROUP BY name

    HAVING num >= 2;

    查询结果:

    5016790085d6c0ed9b98eb67de3ea324.png

    方法2:

    SELECT `name`, AVG(score) AS avg FROM result WHERE `name` in (

    SELECT name FROM result GROUP BY name HAVING SUM(score<60) >= 2

    )

    GROUP BY `name`;

    查询结果:

    9399c7c3db8d2b195365b0015c5cb6d5.png

    方法3:复杂很多

    SELECT tablea.name, tablea.avg, tableb.num FROM (

    SELECT *,AVG(score) AS avg FROM result GROUP BY name

    ) tablea RIGHT JOIN (

    SELECT *, COUNT(*) AS num FROM (

    SELECT * FROM result WHERE score < 60

    ) a

    GROUP BY a.name HAVING num >= 2

    ) tableb on tablea.name = tableb.name;

    查询结果:

    ff7009036f28a2a18fa67dc5710563e0.png

    题10

    有两张表:

    表A

    id

    num

    a

    5

    b

    10

    c

    15

    d

    10

    表B

    id

    num

    b

    5

    c

    15

    d

    20

    e

    99

    要求查询出以下效果:

    id

    sum(num)

    a

    5

    b

    15

    c

    30

    d

    30

    e

    99

    分析:

    先使用UNION ALL将两张表联合起来,再使用SUM()+GROUP BY

    SELECT id, SUM(num) FROM (

    SELECT * FROM A

    UNION ALL

    SELECT * B

    ) AS tmp

    GROUP BY tmp.id

    ;

    题11 优化MySQL数据库的方法

    综合/解决方案

    题1 对于大流量的网站,可以采用哪些方法来解决访问量问题

    安全

    NoSQL

    题1 为什么不能使用Memcached存储Session

    题2 Redis相比Memcached有哪些优势

    题3 Redis有哪些优点

    题4 如何使用Redis存储Session

    题5 Redis如何与MySQL同步

    Linux

    题1 查看系统负载有哪些命令

    Node.js

    JavaScript / jQuery

    HTML / CSS

    SVN / Git

    展开全文
  • 除了口语表达能力之外,还有一点就是实力,这也是你的php面试题所要体现的!那么提前掌握最新的PHP面试题,必然能使你在求职过程中事半功倍! 以下这些php面试题,希望能帮你进入你自己喜欢的公司,拿到自己最理想...

    一、php面试前言

    每个Phper在应聘的时候,都会有php面试与笔试。除了口语表达能力之外,还有一点就是实力,这也是你的php面试题所要体现的!那么提前掌握最新的PHP面试题,必然能使你在求职过程中事半功倍!

    以下这些php面试题,希望能帮你进入你自己喜欢的公司,拿到自己最理想的收入!!!

    二、PHP面试题整理大全如下

    可以关注博主的微信公众号  “PHP大神”  回复  “面试题”  即可获取更多PHP面试题

    1、get与post 的区别?

    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中。

    GET产生一个TCP数据包,POST产生两个TCP数据包

    2、PHP 的垃圾回收机制

    PHP 可以自动进行内存管理,清除不需要的对象。

    PHP 使用了引用计数 (reference counting) GC 机制。

    每个对象都内含一个引用计数器 refcount,每个 reference 连接到对象,计数器加 1。当 reference 离开生存空间或被设为 NULL,计数器减 1。当某个对象的引用计数器为零时,PHP 知道你将不再需要使用这个对象,释放其所占的内存空间。

    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 的进程管理器,支持平滑重启,可以启动的时候预先生成多个进程。

    4、什么是 Redis 穿透和雪崩

    缓存穿透就是访问redis中一个不存在的key的时候,会直接穿过缓存,去数据库中进行查询.

    如果是黑客,进行恶意攻击的时候,每次都请求超过2000个/秒的时候,这个时候mysql基本上就挂了.

    解决办法是:每次从数据库中查询到一个不存在的key的时候,就写一个空值到缓存库中,有恶意攻击的时候,直接从缓存中取到这个空值.

    缓存雪崩就是每秒有5000个请求过来时候,redis缓存库崩了,然后这些请求瞬间落在了mysql数据库上,直接导致数据库死机.

    解决方案就是:

    事前:提高缓存库的高可用, 使用主从结构加哨兵 cluster集群,

    事中:使用ehcache+hystrix限流组件(当请求量非常巨大的时候,就调用自己开发好的一个降级饿组件,返回一些默认值,如友情提示,或者空白值)

    事后:做持久化,尽快恢复缓存集群,一旦恢复,自动从磁盘上读取数据,恢复内存中的数据.

    5、约瑟夫环问题,猴子选大王

    一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入m、n, 输出最后那个大王的编号。用程序模拟该过程。

    6、冒泡排序

    思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

    代码实现:

    7、redis 消息队列先进先出需要注意什么?

    通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务,实现方式有以下几种方式:

    A)单一列表实现:队列正常的操作是 左进右出(lpush,rpop)为了先处理高优先级任务,在遇到高级别任务时,可以直接插队,直接放入队列头部(rpush),这样,从队列头部(右侧)获取任务时,取到的就是高优先级的任务(rpop)

    B)使用两个队列,一个普通队列,一个高级队列,针对任务的级别放入不同的队列,获取任务时也很简单,redis的BRPOP命令可以按顺序从多个队列中取值,BRPOP会按照给出的 key 顺序查看,并在找到的第一个非空 list 的尾部弹出一个元素,redis> BRPOP list1 list2 0

    list1 做为高优先级任务队列

    list2 做为普通任务队列

    这样就实现了先处理高优先级任务,当没有高优先级任务时,就去获取普通任务

    方式1最简单,但实际应用比较局限,方式3可以实现复杂优先级,但实现比较复杂,不利于维护

    方式2是推荐用法,实际应用最为合适

    8、Redis 如何防止高并发?

    其实redis是不会存在并发问题的,因为他是单进程的,再多的命令都是一个接一个地执行的。我们使用的时候,可能会出现并发问题,比如获得和设定这一对。Redis的为什么 有高并发问题?Redis的的出身决定

    Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。

    同时,单线程的天性决定,高并发对同一个键的操作会排队处理,如果并发量很大,可能造成后来的请求超时。

    在远程访问redis的时候,因为网络等原因造成高并发访问延迟返回的问题。

    解决办法

    在客户端将连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

    服务器角度,利用setnx变向实现锁机制。

    9、说说对 SQL 语句优化有哪些方法?

    (1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。

    (2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。

    (3) 避免在索引列上使用计算

    (4)避免在索引列上使用IS NULL和IS NOT NULL

    (5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

    (6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描

    (7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

    10、我应该在什么时候使用 require 和 include 呢?

    require() 函数与 include() 函数相同,只是它处理错误的方式不同。如果出现错误,include() 函数会生成警告,但脚本会继续执行。require() 函数会产生致命错误,脚本会停止。

    我的建议是 99.9% 的时间里只使用 require_once。

    使用 require 或 include 代替意味着您的代码在其他地方不可重用,即您引入的脚本实际上是在执行代码,而不是提供类或某些类功能库。

    11、PHP 中的 stdClass 是什么?

    stdClass 只是将其他类型强制转换为对象时使用的通用” 空’’类。stdClass 不是 PHP 中对象的基类。这可以很容易地证明:

    对于匿名对象,动态属性等很有用。

    考虑 StdClass 的一种简单使用场景是替代关联数组。请参见下面的示例,该示例显示 json_decode() 如何允许获取 StdClass 实例或关联数组。

    同样但未在本示例中显示的SoapClient::__soapCall返回一个StdClass实例。

    12、PHP 中的 die () 和 exit () 函数有什么不同?

    没有区别,它们是一样的。 选择die()而不是exit()的唯一好处可能是你节省了额外键入一个字母的时间。

    13、isset () 和 array_key_exists () 之间有什么区别?

    array_key_exists 它会告诉你数组中是否存在键,并在 $a 不存在时报错。

    如果 key 或变量存在且不是 null,isset 才会返回 true。当 $a 不存在时,isset 不会报错。

    考虑:

    14、var_dump () 和 print_r () 有什么不同?

    var_dump函数用于显示变量 / 表达式的结构化信息,包括变量类型和变量值。数组递归浏览,缩进值以显示结构。它还显示哪些数组值和对象属性是引用。

    print_r()函数以我们可读的方式显示有关变量的信息。数组值将以键和元素的格式显示。类似的符号用于对象。

    考虑:

    var_dump($obj)将在屏幕的输出下方显示:

    print_r($obj)将在屏幕的输出下方显示:

    15、如何在 PHP 中启用错误报告?

    检查 php.ini 中的 “display_errors” 是否等于 “on”,或者在脚本中声明 “ini_set('display_error',1)”。

    然后,在你的代码中包含 “ERROR_REPORTING(E_ALL)”,以便在脚本执行期间显示所有类型的错误消息。

    16、我们如何在 PHP 中处理异常?

    当程序执行出现异常报错时,后面的代码将不会再执行,这时 PHP 将会尝试匹配第一个 catch 块进行异常的处理,如果没有捕捉到异常程序将会报致命错误并显示”Uncaught Exception”。

    可以在 PHP 中抛出和捕获异常。

    为了处理异常,代码可以被包围在”try” 块中.

    每个 try 必须至少有一个对应的catch块 。多个不同的 catch 块可用于捕获不同类的异常。

    在 catch 块中也可以抛出异常(或重新抛出之前的异常)。

    思考:

    17、PHP 和 Javascript 是如何交互的?

    PHP 和 Javascript 无法直接进行交互,因为 PHP 是一种服务器端语言,而 Javascript 是一种浏览器语言。但是,我们可以交换变量,因为 PHP 可以生成将由浏览器执行的 Javascript 代码,并且可以通过 URL 将特定的变量传递回 PHP。

    18、PHP 处理图片需要添加什么扩展?

    需要 GD 库来执行处理图片功能。

    19、获取图片属性(size, width, 和 height)的函数是什么?

    获取图片大小 size:getimagesize ();获取图片宽度 width:imagesx ();获取图片高度 height:imagesy ()。

    20、如何使用 PHP 脚本显示文本?

    可以使用以下两种方法:

    <!--?php echo "Method 1"; print "Method 2"; ?-->

    21如何将数据导出到 Excel 文件中?

    最常见和常用的方法是将数据转换为 Excel 支持的格式。例如,可以编写 .csv 文件,例如选择逗号作为字段之间的分隔符,然后使用 Excel 打开文件。

    22、如何在 PHP 中处理 MySQL 的结果集?

    可以使用 mysqli_fetch_array, mysqli_fetch_assoc, mysqli_fetch_object or mysqli_fetch_row 函数处理。可以关注博主的微信公众号  “PHP大神”  回复  “面试题”  即可获取更多PHP面试题

    23、如何检查给定变量的值为字母和数字字符?

    可以使用专用函数 ctype_alnum 来检查它是否为字母数字字符。

    24、哪种加密扩展可以生成和验证数字签名?

    PHP-OpenSSL 扩展提供了几种加密操作,包括数字签名的生成和验证。

    25、如何在 PHP 中强制转换类型?

    输出类型的名称必须在要强制转换的变量前的括号中指定,如下所示:

    (int), (integer) - 强制转换为整型

    (bool), (boolean) - 强制转换为布尔值

    (float), (double), (real) - 强制转换为浮点型

    (string) - 强制转换为字符串

    (array) - 强制转换为数组

    (object) - 强制转换为对象

    26、PHP 中如何使用三元条件运算符?

    它由三个表达式组成:一个条件和两个操作数,它们描述在指定条件为 true 或 false 时应执行的指令,如下所示:

    Expression_1?Expression_2 : Expression_3;

    27、如何完成微信的接口配置? 以及配置失败的原因?

    填写的URL需要正确响应微信发送的Token验证

    失败原因未删除里面的html文件

    28、如何获取微信发送的内容?

    $postStr = file_get_contents("php://input");

    29、网页授权用户消息流程步骤

    引导用户进入授权页面同意授权,获取code

    通过code换取网页授权access_token(与基础支持中的access_token不同)

    如果需要,开发者可以刷新网页授权access_token,避免过期

    通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

    30、描述小程序的框架

    框架名称:MINA (MINA IS NOT APP) 是在微信中开发小程序的框架。

    框架结构 :MINA 框架由两部分组成。视图层 (View) 和逻辑层 (App Service)。

    框架特征:响应式的数据绑定 (MINA 用响应式数据绑定的方式,在视图层和逻辑层之间进行通信。从某种程度上,可以看成是 MVVM 模式。)

    结构:MINA 程序包含一个描述整体程序的 app 和多个描述各自页面的 page。

    一个 MINA 程序主体部分由三个文件组成,必须放在根目录下。

    Paste_Image.png

    一个 MINA 页面由四个文件组成。

    31、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?

    使用 keys 指令可以扫出指定模式的 key 列表。

    对方接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题?

    这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。

    32、使用过 Redis 做异步队列么,你是怎么用的?

    一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。当 lpop 没有消息的时候,要适当 sleep 一会再重试。

    如果对方追问可不可以不用 sleep 呢?list 还有个指令叫 blpop,在没有消息的时候,它会阻塞住直到消息到来。

    如果对方追问能不能生产一次消费多次呢?使用 pub/sub 主题订阅者模式,可以实现 1:N 的消息队列。

    如果对方追问 pub/sub 有什么缺点?在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如 rabbitmq 等。

    如果对方追问 redis 如何实现延时队列?我估计现在你很想把面试官一棒打死如果你手上有一根棒球棍的话,怎么问的这么详细。但是你很克制,然后神态自若的回答道:使用 sortedset,拿时间戳作为 score,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。

    33、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?

    如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,redis 可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些。

    34、Yii2 的自动加载原理

    检查类名是否已缓存在$classMap或$_coreClasses数组中,如果是则直接require相应的文件路径,$_coreClasses是框架自有类的映射表;否则去第2步;

    检测YiiBase::$enableIncludePath是否为false,如果是则去第3步,否则直接include($className . '.php')

    遍历$includePaths数组,将目录名拼接上类名,检查是否为合法的php文件,如果是则include,然后跳出循环

    结束。

    35、进程和线程的关系

    进程就像地主,有土地(系统资源),线程就像佃户(线程,执行种地流程)。每个地主(进程)只要有一个干活的佃户(线程)。

    进程-资源分配的最小单位,相对健壮,崩溃一般不影响其他进程,但是切换进程时耗费资源,效率差些。

    线程-程序执行的最小单位,没有独立的地址空间,一个线程死掉可能整个进程就死掉,但是节省资源,切换效率高。

    36、php 编程常见的进程和线程

    在web应用中,我们每次访问php,就建立一个PHP进程,当然也会建立至少一个PHP线程。

    PHP使用pcntl来进行多进程编程

    PHP中使用pthreads来进行多线程编程

    nginx的每个进程只有一个线程,每个线程可以处理多个客户端的访问

    php-fpm使用多进程模型,每个进程只有一个线程,每个线程只能处理一个客户端访问。

    apache可能使用多进程模型,也可能使用多线程模型,取决于使用哪种SAPI.

    进程是cpu资源分配的最小单位,线程是cpu调度的最小单位

    37、如何设计支付接口

    接口规则

    传输方式 为保证交易安全性,采用HTTPS传输

    提交方式 采用POST方法提交

    数据格式 提交和返回数据都为XML格式,根节点名为xml

    字符编码 统一采用UTF-8字符编码

    签名算法 MD5,后续会兼容SHA1、SHA256、HMAC等。

    签名要求 请求和接收数据均需要校验签名,详细方法请参考安全规范-签名算法

    证书要求 调用申请退款、撤销订单接口需要商户证书

    判断逻辑 先判断协议字段返回,再判断业务返回,最后判断交易状态

    参数规定

    交易金额

    交易金额默认为人民币交易,接口中参数支付金额单位为【分】,参数值不能带小数。对账单中的交易金额单位为【元】。

    外币交易的支付金额精确到币种的最小单位,参数值不能带小数点。

    交易类型

    JSAPI--JSAPI支付(或小程序支付)、NATIVE--Native支付、APP--app支付,MWEB--H5支付,不同trade_type决定了调起支付的方式,请根据支付产品正确上传

    MICROPAY--付款码支付,付款码支付有单独的支付接口,所以接口不需要上传,该字段在对账单中会出现

    货币类型

    货币类型的取值列表:

    CNY:人民币

    时间

    标准北京时间,时区为东八区;如果商户的系统时间为非标准北京时间。参数值必须根据商户系统所在时区先换算成标准北京时间, 例如商户所在地为0时区的伦敦,当地时间为2014年11月11日0时0分0秒,换算成北京时间为2014年11月11日8时0分0秒。

    时间戳

    标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。

    商户订单号

    商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_、竖线|、星号*这些英文半角字符的组合,请勿使用汉字或全角等特殊字符。微信支付要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生成订单号)。重新发起一笔支付要使用原订单号,避免重复支付;已支付过或已调用关单、撤销(请见后文的API列表)的订单号不能重新发起支付。

    body字段格式

    使用场景 支付模式 商品字段规则 样例 备注

    PC网站 扫码支付 浏览器打开的网站主页title名 -商品概述 腾讯充值中心-QQ会员充值

    微信浏览器 公众号支付 商家名称-销售商品类目 腾讯-游戏 线上电商,商家名称必须为实际销售商品的商家

    门店扫码 公众号支付 店名-销售商品类目 小张南山店-超市 线下门店支付

    门店扫码 扫码支付 店名-销售商品类目 小张南山店-超市 线下门店支付

    门店刷卡 刷卡支付 店名-销售商品类目 小张南山店-超市 线下门店支付

    第三方手机浏览器 H5支付 浏览器打开的移动网页的主页title名-商品概述 腾讯充值中心-QQ会员充值

    第三方APP APP支付 应用市场上的APP名字-商品概述 天天爱消除-游戏充值

    银行类型

    安全规范

    签名算法

    (签名校验工具)

    签名生成的通用步骤如下:

    第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

    特别注意以下重要规则:

    ◆ 参数名ASCII码从小到大排序(字典序);

    ◆ 如果参数的值为空不参与签名;

    ◆ 参数名区分大小写;

    ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

    ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

    第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

    ◆ key设置路径:微信商户平台(微信支付 - 中国领先的第三方支付平台 | 微信支付提供安全快捷的支付方式)-->账户设置-->API安全-->密钥设置

    第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:

    第二步:拼接API密钥:

    生成随机数算法

    微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。我们推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串。

    API证书

    获取API证书(什么是api证书?如何升级?)

    微信支付接口中,涉及资金回滚的接口会使用到API证书,包括退款、撤销接口。商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:微信商户平台(微信支付 - 中国领先的第三方支付平台 | 微信支付提供安全快捷的支付方式)-->账户中心-->账户设置-->API安全 。证书文件说明如下:

    证书附件 描述 使用场景 备注

    pkcs12格式

    (apiclient_cert.p12、 包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份 撤销、退款申请API中调用 windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)

    以下两个证书在PHP环境中使用:

    证书附件 描述 使用场景 备注

    证书pem格式

    (apiclient_cert.pem) 从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制 PHP等不能直接使用p12文件,而需要使用pem,为了方便您使用,已为您直接提供 您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem

    证书密钥pem格式

    (apiclient_key.pem) 从apiclient_key.pem中导出密钥部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制 PHP等不能直接使用p12文件,而需要使用pem,为了方便您使用,已为您直接提供 您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem

    使用API证书

    ◆ apiclient_cert.p12是商户证书文件,除PHP外的开发均使用此证书文件。

    ◆ 商户如果使用.NET环境开发,请确认Framework版本大于2.0,必须在操作系统上双击安装证书apiclient_cert.p12后才能被正常调用。

    ◆ API证书调用或安装需要使用到密码,该密码的值为微信商户号(mch_id)

    API证书安全

    证书文件不能放在web服务器虚拟目录,应放在有访问权限控制的目录中,防止被他人下载;

    建议将证书文件名改为复杂且不容易猜测的文件名;

    商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。

    商户回调API安全

    在普通的网络环境下,HTTP请求存在DNS劫持、运营商插入广告、数据被窃取,正常数据被修改等安全风险。商户回调接口使用HTTPS协议可以保证数据传输的安全性。所以微信支付建议商户提供给微信支付的各种回调采用HTTPS协议。

    38、三次握手,四次挥手,为什么是三次握手四次挥手

    四次挥手

    TCP的连接的拆除需要发送四个包,因此称为四次挥手。客户端或服务器均可主动发起挥手动作。

    由于TCP连接时全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成他的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

    这是因为服务端的LISTEN状态下的socket当收到SYN报文连接的请求后,它可以把ACK和SYN放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,他仅仅表示对方没有数据发送给你了,但未必你的所有数据都全部发送给对方了,所以你可以不马上关闭socket,即你可能还会发送一些数据给对方之后,在发送FIN报文给对方来表示你同意现在可以关闭连接了,所以这里的ACK和FIN报文多情况下都是分开发送的。

    39、可以关注博主的微信公众号  “PHP大神”  回复  “面试题”  即可获取更多PHP面试题

    展开全文
  • 2021年最新PHP面试题(附带答案)

    千次阅读 2021-06-23 18:58:31
    php面试题的题型很多,但是都离不开PHP面试题基础常见的。没有经验的可能不懂试题,告诉你一个方法,那个时候我真的用了,就是把所有题型都背下来!方法很老套又不切合实际,但是很有用!因为常见的PHP面试题型都...

    一、前言

    在进入你心仪的公司之前,会有一到两轮的面试与笔试,做我们这个行业的都是这样,所以除了口语表达能力(能吹)之外,还有一点就是实力!这也是你的php面试题所要体现的。php面试题的题型很多,但是都离不开PHP面试题基础常见的。没有经验的可能不懂试题,告诉你一个方法,那个时候我真的用了,就是把所有题型都背下来!方法很老套又不切合实际,但是很有用!因为常见的PHP面试题型都遇到了~~可能是幸运吧!

    博主已将php相关面试题汇总整理成了PDF版的PHP面试宝典,关注微 信 公 众 号 “PHP大神” 回复“面试题”即可获取!

    二、PHP常见面试题

    1.详述一次完整的HTTP请求过程

    这个问题的核心是域名解析和服务器(nginx)解析这两部分,基本上这两部分详细阐述就可以了。

    步骤一、解析URL

    浏览器会解析当前的URL数据,判断此URL是否为合法的链接。如果是合法链接则正常的向下一步骤前进。如果不是合法的链接,则会执行搜索功能,例如执行百度、360、Google搜索等。

    步骤二、解析域名

    服务器是以ip的形式存在的。而域名需要解析到ip上,解析IP会有三个小的步骤:

    1)、从浏览器自身的缓存中解析此域名数据

    2)、从本地电脑的HOST文件中解析域名

    3)、通过DNS服务器解析域名

    步骤三、拿信息

    这个步骤我们拿到了URL的信息,主要是IP和端口信息。

    步骤四、封包并进行三次握手

    浏览器将请求信息进行打包,通过TCP的三次握手将数据传递至服务器。

    步骤五、服务器解析、处理、返回数据

    服务器通过种种层级、方式拿到传递的数据,对数据进行分析、处理,最后返回响应类MIME类型数据。正常状态码为200,非正常的错误码有404、500、501等等

    步骤六、浏览器获得、渲染、展现数据

    浏览器从服务器拿到数据、通过加载资源、渲染页面等操作,将页面展现给用户。

    2. SESSION 与 COOKIE的区别是什么,请从协议,产生的原因与作用说明?

    1)、http无状态协议,不能区分用户是否是从同一个网站上来的,同一个用户请求不同的页面不能看做是同一个用户。

    2)、SESSION存储在服务器端,COOKIE保存在客户端。Session比较安全,cookie用某些手段可以修改,不安全。Session依赖于cookie进行传递。

    禁用cookie后,session不能正常使用。Session的缺点:保存在服务器端,每次读取都从服务器进行读取,对服务器有资源消耗。Session保存在服务器端的文件或数据库中,默认保存在文件中,文件路径由php配置文件的session.save_path指定。Session文件是公有的。

    3.HTTP 状态中302、403、 500代码含义?

    一二三四五原则: 一. 消息系列 二 成功系列 三. 重定向系列 四. 请求错误系列 五. 服务器端错误系列

    302:临时转移成功,请求的内容已转移到新位置 403:禁止访问 500:服务器内部错误 401代表未授权。

    4. Linux 下建立压缩包,解压缩包的命令

    Tar.gz:

    打包: tar czf file.tar.gz file.txt

    解压: tar xzf file.tar.gz

    Bz2:

    打包: bzip2 [-k] 文件

    解压: bunzip2 [-k] 文件

    Gzip(只对文件,不保留原文件)

    打包: gzip file1.txt

    解压: gunzip file1.txt.gz

    Zip: -r 对目录

    打包: zip file1.zip file1.txt

    解压: unzip file1.zip

    5. 请写出数据类型(int char varchar datetime text)的意思;请问 varchar 和 char有什么区别?

    Int 整数 char 定长字符 Varchar 变长字符 Datetime 日期时间型 Text 文本型 Varchar 与char的区别 char是固定长度的字符类型,分配多少空间,就占用多长空间。 Varchar是可变长度的字符类型,内容有多大就占用多大的空间,能有效节省空间。 由于varchar类型是可变的,所以在数据长度改变的时,服务器要进行额外的操作,所以效率比char类型低。

    6. MyISAM 和 InnoDB 的基本区别?索引结构如何实现?

    MyISAM类型不支持事务,表锁,易产生碎片,要经常优化,读写速度较快,而InnoDB类型支持事务,行锁,有崩溃恢复能力。读写速度比MyISAM慢。

    创建索引:alert table tablename add index (`字段名`)

    7. 不使用cookie向客户端发送一个cookie.

    理解:session_start()开启时,生成一个常量 SID,当COOKIE开启时,这个常量为空,当COOKIE关闭时,这个常量中存储了PHPSESSID的值。通过在URL后加一个SID参数来传递SESSIONID的值,从而使客户端页面可以使用SESSION里面的值。 当客户端开启COOKIE和服务器端开启SESSION时。 浏览器第一次请求,服务器会向浏览器端发送一个COOKIE里面存储SESSIONID. 当浏览器第二次请求时,会把已存在

    8. isset() 和 empty() 区别

    Isset判断变量是否存在,可以传入多个变量,若其中一个变量不存在则返回假,empty判断变量是否为空为假,只可传一个变量,如果为空为假则返回真。

    9.持久化redis有几种方式?

    答:主要有两种方式:

    1) 快照持久化

    在redis配置文件中已经自动开启了,

    格式是:save N M

    表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。

    当然我们也可以手动执行save或者bgsave(异步)命令来做快照

    2)append only file  AOF持久化

     总共有三种模式,如

    appendfsync everysec默认的是每秒强制写入磁盘一次

    appendfsync always 每次执行写操作的时候就强制写入磁盘

    appendfsync no 完全取决于os,性能最好但是持久化没法保证

    其中第三种模式最好。redis默认的也是采取第三种模式。

    10.mysql存储引擎

    答:常用的主要分为两种,一种是innodb,一种是myisam,两者的主要区别是

    1)myisam不支持事务处理,而innoDB支持事务处理

    2)myisam 不支持外键,innoDB支持外键

    3)myisam支持全文检索,而innoDB在MySQL5.6版本之后才支持全文检索

    4)数据的存储形式不一样,mysiam表存放在三个文件:结构、索引、数据,innoDB存储把结构存储为一个文件,索引和数据存储为一个文件

    5)myisam在查询和增加数据性能更优于innoDB,innoDB在批量删除方面性能较高。

    6)myisam支持表锁,而innoDB支持行锁

    11.sql注入是什么及如何预防sql注入?

    答:SQL注入攻击指的是用户或者黑客通过构建特殊的输入作为参数传入我们的Web应用程序端,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序员没有细致地过滤用户输入的数据,致使非法数据侵入系统而造成的。因此我们在做开发过程中一定要预防sql注入,主要从两方面着手:

    1)占位符的方式,就是对sql语句进行预处理,然后执行sql语句

    2)通过addslashes或者mysql_real_escape_string这两个函数对用户输入的值进行转义处理,把一些特殊的字符转义掉。

    12.有用过预处理么?

    答:用过,PDO类中,有个prepare方法可以实现预处理,PDOStament类中 的excute方法可以执行预处理,预处理的参数分为两种,一种是:字符串占位符,另一种是?占位符,:字符串占位符在执行预处理传递参数时传入的是关联数组,而?占位符传递的是索引数组。两者不能混合使用,但一般推荐使用:字符串占位符。

    13.用框架还用自己的处理吗

    答:一般成熟的开源框架中都考虑到了数据安全这方面的东西,但有时候我们可能会使用一些原生的SQL语句时,我们就需要考虑自己对sql语句进行预处理。当然有时候框架中的过滤方法我们不希望采用,比如使用文本编辑器时,我们可以使用自己的过滤方式。

    14.mysql优化怎么做的?

    答:mysql优化主要从以下几个方面来实现:

      1)设计角度:存储引擎的选择,字段类型选择,范式

      2)功能角度:可以利用mysql自身的特性,如索引,查询缓存,碎片整理,分区、分表等

      3)sql语句的优化方面:尽量简化查询语句,能查询字段少就尽量少查询字段,优化分页语句、分组语句等。

      4)部署大负载架构体系:数据库服务器单独出来,负载大时可以采用主从复制,读写分离机制进行设计

      5)从硬件上升级数据库服务器。

    15.请说明 PHP 中传值与传引用的区别。什么时候传值什么时候传引用?

    按值传递:函数范围内对值的任何改变在函数外部都会被忽略

    按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改

    优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。按引用传递则不需要复制值,对于性能提高很有好处。

    16.在PHP中error_reporting这个函数有什么作用?

    设置 PHP 的报错级别并返回当前级别。

    17.使用PHP描述快速排序算法,对象可以是一个数组吗?

    原理:快速排序使用分治策略来把待排序数据序列分为两个子序列,具体步骤为:

    (1)从数列中挑出一个元素,称该元素为“基准”。

    (2)扫描一遍数列,将所有比“基准”小的元素排在基准前面,所有比“基准”大的元素排在基准后面。

    (3)通过递归,将各子序列划分为更小的序列,直到把小于基准值元素的子数列和大于基准值元素的子数列排序。

    //快速排序(数组排序)
    function QuickSort($arr){
     $num = count($arr);
     $l=$r=0;
     for($i=1;$i<$num;$i++){
      if($arr[$i] < $arr[0]){
       $left[] = $arr[$i];
       $l++;
      }else{
       $right[] = $arr[$i];
       $r++;
      }
     }
     if($l > 1){
      $left = QuickSort($left);
     }
     $new_arr = $left;
     $new_arr[] = $arr[0];
     if($r > 1){
      $right = QuickSort($right);
     }
     for($i=0;$i<$r;$i++){
      $new_arr[] = $right[$i];
     }
     return $new_arr;
    }

    18.使用PHP描述顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,对象可以是一个有序数组

    //二分查找(数组里查找某个元素)
    function bin_sch($array, $low, $high, $k){
     if ($low <= $high){
      $mid = intval(($low+$high)/2);
      if ($array[$mid] == $k){
       return $mid;
      }elseif ($k < $array[$mid]){
       return bin_sch($array, $low, $mid-1, $k);
      }else{
       return bin_sch($array, $mid+1, $high, $k);
      }
     }
     return -1;
    }
    //顺序查找(数组里查找某个元素)
    function seq_sch($array, $n, $k){
     $array[$n] = $k;
     for($i=0; $i<$n; $i++){
      if($array[$i]==$k){
       break;
      }
     }
     if ($i<$n){
      return $i;
     }else{
      return -1;
     }
    }

    19.写一个二维数组排序算法函数,能够具有通用性,可以调用php内置函数(array_multisort())

    //二维数组排序, $arr是数据,$keys是排序的健值,$order是排序规则,1是升序,0是降序
    function array_sort($arr, $keys, $order=0) {
     if (!is_array($arr)) {
      return false;
     }
     $keysvalue = array();
     foreach($arr as $key => $val) {
      $keysvalue[$key] = $val[$keys];
     }
     if($order == 0){
      asort($keysvalue);
     }else {
      arsort($keysvalue);
     }
     reset($keysvalue);
     foreach($keysvalue as $key => $vals) {
      $keysort[$key] = $key;
     }
     $new_array = array();
     foreach($keysort as $key => $val) {
      $new_array[$key] = $arr[$val];
     }
     return $new_array;
    }

    20.对于用户输入一串字符串$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"; 
    }

    21.单例模式,创建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); 
     } 
    }

    22.PHP session扩展默认将session数据储存在哪里? D

    A) SQLite Database

    B) MySQL Database

    C) Shared Memory

    D) File System

    E) Session Server

    23.PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode文字的字符串大小写转换

    答:原因是:中文是由多字节组成的,而只有英文系统的单个英文字符只有一个字节,所以该系统把中文的每一个字节都做了strtolower()处理,改变后的中文字节拼接在一起就成了乱码(新生成的编码映射对应的字符可能就不是中文了)

    手动解决:用str_split(string string,intstring,intsplit_length = 1)按每个字节切割,像中文能切割成三个字节。对识别到的字节若是英文字母则进行转换。

    <?php  
    function mystrtoupper($a){  
        $b = str_split($a, 1);  
        $r = '';  
        foreach($b as $v){  
            $v = ord($v);  
            if($v >= 97 && $v<= 122){  
                $v -= 32;  
            }  
            $r .= chr($v);  
        }  
        return $r;  
    }  
     
     
    $a = 'a中你继续F@#$%^&*(BMDJFDoalsdkfjasl';  
    echo 'origin string:'.$a."\n";  
    echo 'result string:';  
    $r = mystrtoupper($a);  
    var_dump($r); 

    24.PHP的is_writeable()函数存在Bug,无法准确判断一个目录/文件是否可写,请写一个函数来判断目录/文件是否绝对可写

    答:其中bug存在两个方面, 
    1)在windowns中,当文件只有只读属性时,is_writeable()函数才返回false,当返回true时,该文件不一定是可写的。 
    如果是目录,在目录中新建文件并通过打开文件来判断; 
    如果是文件,可以通过打开文件(fopen),来测试文件是否可写。

    2)在Unix中,当php配置文件中开启safe_mode时(safe_mode=on),is_writeable()同样不可用。 
    读取配置文件是否safe_mode是否开启。

    /**
    * Tests for file writability
    *
    * is_writable() returns TRUE on Windows servers when you really can't write to
    * the file, based on the read-only attribute. is_writable() is also unreliable
    * on Unix servers if safe_mode is on.
    *
    * @access   private
    * @return   void
    */
    if ( ! function_exists('is_really_writable'))
    {
        function is_really_writable($file)
        {
        // If we're on a Unix server with safe_mode off we call is_writable
        if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
        {
            return is_writable($file);
        }
     
        // For windows servers and safe_mode "on" installations we'll actually
        // write a file then read it. Bah...
        if (is_dir($file))
        {
            $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
     
            if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
            {
                return FALSE;
            }
     
            fclose($fp);
            @chmod($file, DIR_WRITE_MODE);
            @unlink($file);
            return TRUE;
        } elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE) {
            return FALSE;
        }
     
        fclose($fp);
        return TRUE;
        }
    }

    25.PHP处理上传文件信息数组中的文件类型$_FILES[‘type’]由客户端浏览器提供,有可能是黑客伪造的信息,请写一个函数来确保用户上传的图像文件类型真实可靠

    答:用getimagesize来判断上传图片的类型比$_FILES函数的type更可靠 
    同一个文件,使用不同的浏览器php返回的type类型是不一样的,由浏览器提供type类型的话, 
    就有可能被黑客利用向服务器提交一个伪装撑图片后缀的可执行文件。 
    可以通过getimagesize()函数来判断上传的文件类型,如果是头像文件 会返回这样的一个数组

    Array
    (
        [0] => 331
        [1] => 234
        [2] => 3
        [3] => width="331" height="234"
        [bits] => 8
        [mime] => image/png
    );

    26.如何实现PHP的安全最大化?怎样避免SQL注入漏洞和XSS跨站脚本攻击漏洞?

    答:基本原则:不对外界展示服务器或程序设计细节(屏蔽错误),不相信任何用户提交的数据(过滤用户提交) 

    1)屏蔽错误,将display_errors 设置为off 
    2)过滤用户提交参数,这里需要注意的是不能仅仅通过浏览器端的验证,还需要经过服务器端的过滤

    这里是需要注意最多的地方,因为所有用户提交的数据入口都在这里,这是过滤数据的第一步。
          1 考虑是否过滤select,insert,update,delete,drop,create等直接操作数据的命令语句
          2 使用addslashes 将所有特殊字符过滤
          3 打开magic_quotes_gpc,开启该参数数后自动将sql语句转换,将 ' 转换成  \'

    3)可以考虑设置统一入口,只允许用户通过指定的入口访问,不能访问未经许可的文件等内容 
    4)可以考虑对安全性要求高的文件进行来源验证,比如要想执行b.php必须先执行a.php,可以在b.php中判断来自a.php的referer,避免用户直接执行b.php

    27.请写出让PHP能够在命令行下以脚本方式执行时安装PHP所必须指定的configure参数,并说明如何在命令行下运行PHP脚本(写出两种方式)同时向PHP脚本传递参数?

    答:由于 –enable-cli 和 –enable-cgi 同时默认有效,因此,不必再配置行中加上 –enable-cli 来使得 CLI 在 make install 过程中被拷贝到 {PREFIX}/bin/php

    php -f “index.php” 
    php -r “print_r(get_defined_constants());”

    28.PHP的垃圾收集机制是怎样的?

    说明: 
    1)如果,你熟悉PHP源码,那么请从源码入手,回答些问题,会获得额外加分 
    2)如果,你不熟悉PHP源码,那么尽你所能,多写点东西,包括利用自己的编程直觉得到的信息,都可以。 
    3)对,则有分,错误不扣,不写无分。

    答:PHP可以自动进行内存管理,清除不再需要的对象。PHP使用了引用计数(referencecounting)这种单纯的垃圾回收(garbagecollection)机制。每个对象都内含一个引用计数器,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。

    29.get和post的区别?

    1. get是从服务器上获取数据,post是向服务器传送数据。
    2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
    3. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。
    4. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
    

    30.如何修改会话的生存时间?

    一:在php.ini中设置session.gc_maxlifetime = 1440 //默认时间
    二:代码实现      $ lifeTime = 24 * 3600; //保存一天
        session_set_cookie_params($ lifeTime); 
        在session_start(); 
    

    31.微信支付回调失败该如何处理?

    他问的是已经支付成功后,但是回调失败了。

    自己可以创建定时任务在每天的凌晨执行,去微信那边对账,然后更新数据库订单状态。

    32.调用区块链接口的安全措施,有那些实现方法?

    来自PHP技术交流群 群友分享

    1. 使用MD5实现对接口加签,目的是为了防止篡改数据。
    2. 基于网关实现黑明单与白名单拦截
    3. 可以使用rsa非对称加密 公钥和私钥互换
    4. 如果是开放接口的话,可以采用oath2.0协议
    5. 使用Https协议加密传输,但是传输速度慢
    6. 对一些特殊字符实现过滤 防止xss、sql注入的攻击
    7. 定期使用第三方安全扫描插件
    8. 接口采用dto、do实现参数转化 ,达到敏感信息脱敏效果
    9. 使用token+图形验证码方法实现防止模拟请求
    10. 使用对ip访问实现接口的限流,对短时间内同一个请求(ip)一直访问接口 进行限制。

    33.服务器受到dos攻击,这个问题如何应付?

    看看你的服务的访问日志,在防火墙中加过滤,或者在web服务器中加过滤吧。方法有以下几种。

    • 对于特定的IP访问的情况,限制IP访问
    • 限制同一IP在单位时间内的访问次数
    • 上级服务器,提高吞吐能力

    是消耗服务器资源为主还是纯流量攻击?消耗资源的可以通过配置防火墙过滤规则防御中小规模的攻击。如果是纯流量攻击,考虑你用的是linode真心无解。即便你封了IP封了端口也没用,人家不管你接不接受他的请求,他都会塞满你的带宽。linode必然认为你是被流量攻击或者消耗过多资源然后给你挂起。

    34.简述Linux下安装Mysql的过程?

    Groupadd mysql 添加一个用户组mysql
    Useradd -g mysql mysql 添加一个mysql用户指定分组为mysql
    Cd /lamp/mysql 进入mysql目录
    ./configure –prefix=/usr/local/mysql/ –with-extra-charsets=all
    Make
    Make all

    35.对于大流量的网站,您采用什么样的方法来解决访问量问题?

    优化程序,优化数据库,如果程序和数据库已经最优化,使用以下解决方法:

    • 确定当前服务器设备是否满足流量需求。
    • 使用Memcache缓存技术,把动态内容缓存到文件中,动态网页直接调用这些文件,而不必再访问数据库。
    • 禁止外部盗链,图片和文件外部盗链会给服务器带来大量的负载压力,可以通过refer来禁止外部盗链,或者使用apache来配置禁止盗链。
    • 控制大文件的下载,大文件的下载对于非SCSI硬盘来说会占用大量的资源,导致服务器的响应能力下降。
    • 使用不同的主机分流主要流量,使服务器均衡负载。
    • 使用流量统计软件统计分析网站流量,可以知道哪些地方耗费了大量的流量,哪些页面需要再进行优化。

    36.对关系型数据库而言,索引是相当重要的概念,请回答有关索引几个问题:

    1)索引的目的是什么?

    • 快速访问数据表中的特定信息,提高检索速度
    • 创建唯一性索引,保证数据库表中每一行数据的唯一性
    • 加速表和表之间的连接
    • 使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间

    2) 索引对数据库系统的负面影响是什么?

    负面影响:创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改的时候索引也要动态维护,这样就降低了数据的维护速度。

    3) 为数据表建立索引的原则有哪些?

    • 在最频繁使用的、用以缩小查询范围的字段上建立索引
    • 在平频繁使用的、需要排序的字段上建立索引

    4) 什么情况下不宜建立索引?

    • 对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引
    • 对于一些特殊的数据类型,不宜建立索引,比如文本字段(text),值范围较少的知道等。

    37.PHP字符串中单引号与双引号的区别?

    单引号不能解释变量,而双引号可以解释变量。

    单引号不能转义字符,在双引号中可以转义字符。

    38.求两个日期的差数,例如2021-2-5 ~ 2021-3-6 的日期差数

    方法一:
    <?php
    class Dtime{
     function get_days($date1, $date2){
      $time1 = strtotime($date1);
      $time2 = strtotime($date2);
      return ($time2-$time1)/86400;
     }
    }
    $Dtime = new Dtime;
    echo $Dtime->get_days(’2021-2-5′, ’2021-3-6′);
    ?>
    方法二:
    <?php
    $temp = explode(‘-’, ’2021-2-5′);
    $time1 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]);
    $temp = explode(‘-’, ’2021-3-6′);
    $time2 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]);
    echo ($time2-$time1)/86400;
    方法三:echo abs(strtotime(“2021-2-5″)-strtotime(“2021-3-1″))/60/60/24 计算时间差

    39.有一个一维数组,里面存储整形数据,请写一个函数,将他们按从大到小的顺序排列。要求执行效率高。并说明如何改善执行效率。(该函数必须自己实现,不能使用php函数)

    <?php
    function BubbleSort(&$arr){
     $cnt=count($arr);
     $flag=1;
     for($i=0;$i<$cnt;$i++){
     if($flag==0){
      return;
     }
     $flag=0;
     for($j=0;$j<$cnt-$i-1;$j++){
      if($arr[$j]>$arr[$j+1]){
       $tmp=$arr[$j];
       $arr[$j]=$arr[$j+1];
       $arr[$j+1]=$tmp;
       $flag=1;
      }
     }
     }
    }
    $test=array(1,3,6,8,2,7);
    BubbleSort($test);
    var_dump($test);

    40.博主已将php相关面试题汇总整理成了一个PDF版的PHP面试宝典,关注微 信 公 众 号 “PHP大神” 回复“面试题”即可获取!

    展开全文
  • 刚刚吃饭的时候想说今天再写点啥?...我认为这样的题目作为PHP面试题并不合适。不过作为一个有趣的知识点,我今天就说说这个小问题吧。我们知道64位的整数的表值范围是-9223372036854775808 到 ...

    CA00038.jpg

    刚刚吃饭的时候想说今天再写点啥?突然想起来前几天有人在微博上评论我的一个PHP 的面试题:

    var_dump(PHP_INT_MIN);var_dump(-9223372036854775808);

    输出一样么? 如果不一样为什么?

    我认为这样的题目作为PHP面试题并不合适。不过作为一个有趣的知识点,我今天就说说这个小问题吧。

    我们知道64位的整数的表值范围是

    -9223372036854775808 到 9223372036854775807

    在64位系统上,PHP内部是使用有符号的64位整形来表示IS_LONG, 分别有俩个常量来表示这俩个值, 分别是PHP_INT_MIN和PHP_INT_MAX。

    在64位平台上,PHP_INT_MIN就等于-9223372036854775808,那题目的意思是啥呢? 我们输出下看看:

    int(9223372036854775807)float(-9.2233720368548E+18)

    输出果然不一样,那是什么造成了这个差异呢?

    在PHP编译器处理输入文件输入的时候,对于负数字面量它的处理方式是:

    -{LNUM}=> '-' expr { $$ = zend_ast_create(ZEND_AST_UNARY_MINUS, $2); }=> UNARY_MINUS: 0 - expr

    也就是,首先把负号后面的数字作为一个整形接受进来,然后在把它求负。

    于是这就造成了这个问题, 开头我们说了64位的最大正表值是9223372036854775807,那当PHP处理-9223372036854775808的时候, 9223372036854775808 超出了64位整形的最大正表值范围,PHP没有办法用一个有符号64位整形存储它,于是只能把它自动转成了DOUBLE类型。于是接下来….

    其实在C语言中如果你写下如下的代码:

    int main() {long a = -9223372036854775808;return 0;}

    你应该会收到类似如下的警告:

    warning: integer constant is so large that it is unsigned

    也就是说,你直接写9223372036854775808的话,C编译器会提示你这个数字太大了,应该用unsigned才能表示,并默认给你转成了unsigned long,然后再求负。

    当然,也可以强制通过指明UL来避免这个警告从而进行直接赋值,但更多的时候,为了显示的表示此处有坑,大家一般都会这么写(比如在ubuntu的/usr/include/stdint.h):

    #define INT64_MIN (-__INT64_C(9223372036854775807)-1)

    也就是通过一个表达式来代替直接写一个字面量, 对应的,我们也可以通过在脚本中这么写:

    $min = -9223372036854775807 - 1;

    来避免这个限制,就能正常表达PHP_INT_MIN啦。其实在PHP7之前并没有定义PHP_INT_MIN的时候,我们也是这么习惯写的,比如PHP源代码中的一些测试脚本中(ext/date/tests/date_create-relative.phpt):

    if (!defined('PHP_INT_MIN')) {define('PHP_INT_MIN', intval(-PHP_INT_MAX - 1));}

    展开全文
  • 精选php面试题及答案

    2021-04-26 12:30:13
    精选php面试题及答案PHP是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。以下是百分网小编搜索整理的一份php面试题及答案,供参考学习,希望对大家有所...
  • 学会这些PHP面试题成功拿下offe 浅谈面试经验(面试官角度) go面试题:第一天 盘点2021年PHP开发工程师遇到的面试题 2021 年6月面试遭遇滑铁卢,现在这么内卷了吗 想跳槽涨薪,想进大厂,如何准备面试呢?
  • php面试题大全及答案

    千次阅读 2021-01-21 12:49:07
    ## 包括PHP基础部分、数据库部分、面向对象部分、ThinkPHP部分部分、smarty模板引擎、二次开发系统(DEDE、ecshop)、微信公众平台开发、对于自身掌握的技术描述等几部分PHP面试题。 ** 1、PHP语言的一大优势是跨...
  • 值得深思的PHP面试题

    2021-04-26 12:29:02
    值得深思的PHP面试题引导语:PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。以下是小编整理的值得深思的PHP面试题,欢迎参考阅读!Q6、$x应该是输出什么?$x = true and false;var_dump...
  • PHP面试题集锦(3)

    2021-04-30 06:19:37
    1、$_GET,$_POST,$_REQUEST 三者的区别从一个简单的理解来看在PHP中$_GET $_POST $_REQUEST都是接受数据了,get接受的是url参数而post可以说是由表单post过来的数据,而request是可以接受两者的数据,这个就是他们...
  • 在网上看到一些高级php面试题目…… 闲来无事,搞了一些答案……可能不是很全面,留这以后备用吧。 一。 基本知识点 1.1 HTTP协议中几个状态码的含义:503 500 401 403 404 200 301 302…… 200 : 请求成功,请求...
  • 2021php面试题整理

    2021-05-14 17:35:29
    基础类: 单引号和双引号的区别 isset和empty的区别 常用的数组函数 数据库类: mysql的索引有哪些 最左前缀原则 怎么优化mysql mysql的数据引擎 mysql事务隔离级别以及引起的问题 ......
  • 原标题:面试中常见的PHP面试题选择题汇总面试中常常因为几道面试题就面试失利的不再少数,那么我们该如果避免这样的事情发生呢?如何能在面试中顺利的拿下offer呢?当然除了自己专业的技术,还有就是能轻松的面对...
  • php面试题及答案

    2021-03-23 19:48:20
    如何用php的环境变量得到一个网页地址的内容?ip地址又要怎样得到?程序代码echo $_SERVER ["PHP_SELF"];echo $_SERVER ["SERVER_ADDR"];2. 求两个日期的差数,例如2007-2-5 ~ 2007-3-6 的日期差数程序代码$begin=...
  • 面试题的题型很多,但是都是离不开PHP基础的。一些刚出来的可能不懂试题的。告诉你一个方法,那个时候我真的用了!就是把所有题型都背下来了!方法很老套又不切合实际。但是很有用,因为常见的题型都遇到了~~可能是...
  • 结合我自己这段时间的面试情况,面对的一些php面试题列举出来,基本上结合自己的看法回答的,不妥的地方请大家指出去,与大家一起讨论分析,也希望能帮到正在面试的童鞋们:1、表单提交中的Get和Post的异同点get ...
  • PHP 面试题

    2021-08-11 14:18:40
    Session保存在服务器端的文件或数据库中,默认保存在文件中,文件路径由php配置文件的session.save_path指定。Session文件是公有的。 但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session。 通过url...
  • 这篇文章介绍的内容是关于最全最详细的PHP面试题(带有答案),有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下1、__FILE__表示什么意思?(5分)文件的完整路径和文件名。如果用在包含文件中,则返回...
  • 2021年3月phper必看的PHP面试题(附答案)

    千次阅读 多人点赞 2021-03-13 21:06:41
    另外还将大量面试题整理成了一个PHP面试手册,是PDF版的。 关注微信公众号:PHP大神,然后回复“面试手册”即可获取~ 1. 什么是面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性...
  • php面试题-Redis篇

    2021-08-02 17:02:58
    过程原理: 今天,我不自量力的面试了某大厂的开发岗位,迎面走来一位风尘仆仆的中年男子,手里拿着屏幕还亮着的 Mac。 他冲着我礼貌的笑了笑,然后说了句“不好意思,让你久等了”,然后示意我坐下,说:“我们...
  • 本文内容参考《linux就该这样学》1.执行查看帮助man2.常用系统命令echo 在终端输出字符串或变量提取后的值date 显示设置系统时间或日期 -s 设置系统时间 -%j当前日期为一年中的第几天reboot 重启 (需要root管理员...
  • PHP面试题附答案

    2021-04-16 13:04:20
    PHP面试题附答案》由会员分享,可在线阅读,更多相关《PHP面试题附答案(6页珍藏版)》请在人人文库网上搜索。1、PHP面试题附答案 1. Which of the following will not add john to the users array? 1. $users = ...
  • php面试题-2021-php高级篇

    千次阅读 2021-03-24 16:03:12
    PHP代码执行原理 1.源码通过词法分析得到Token。 2.基于语法分析器生成AST抽象语法树 3.抽象语法树转换为opcodes,php解释执行opcodes 1、词法分析器将php代码转换为有意义的标识Token,词法分析器底层使用Re2c实现...
  • 一、单选(共29,每5分) 1.PHP执行的时候有如下执行过程:Scanning(Lexing) - Compilation - Execution - Parsing,其含义分别为: A、将PHP代码转换为语言片段(Tokens)、将Tokens转换成简单而有意义的...
  • 一份php面试题

    2021-03-27 08:08:32
    一份php面试题考的很基础,但基础不牢,有一批不会做。像在HTTP 1.0中,状态码 401 的含义,error_reporting(2047)这些不知道。但用2047似乎有点儿变态,太不易读。如果可以参考手册~~~~1.在PHP中,当前脚本的名称...
  • PHP面试题,并带有答案,只需下载一份就轻松解决面试难题。函数返回的数组格式如下所示:Array([1] => Array ( [id] => 1 [name] => 一级类别 [level] => 0 [ParentID] => 0 )[4] => Array ( [id] =&...
  • 2021PHP面试题大全

    2021-03-26 19:41:40
    2021PHP面试题大全 一 、PHP基础部分 1、PHP语言的一大优势是跨平台,什么是跨平台? PHP的运行环境最优搭配为Apache+MySQL+PHP,此运行环境可以在不同操作系统(例如windows、Linux等)上配置,不受操作系统的限制...
  • 在我们PHP里对象是数据类型中的一种,整型、浮点、布尔、字符串又叫标量类型,标量相对复合类型而言,即是只能有一个值。数组作为复合类型能存储多种类型的值,但是当我要形容某一类的事物,且事物中又有很多种行为...
  • array_splice() 删除数组中的指定元array_splice(数组名,从前往后删的个数,new一个数组的大小);没有第三参数也就没有返数组,没有第三个参数时,第二个参数的意义为从前往后保留几个exp:...
  • 金三银四马上开始了,所以花了很长时间搜集整理出来了这套PHP面试题大全,希望对大家有帮助哈~ 博主还将大量面试题整理成了一个PHP面试手册,是PDF版的。 关注博主的微信公众号:PHP大神,然后回复“面试手册”...
  • Q28:你将如何使用PHP创建Singleton类?/*** Singleton class**/final classUserFactory {/*** Call this method to get singleton** @return UserFactory*/public staticfunctionInstance() {static $inst = null;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,240
精华内容 12,896
关键字:

php面试题

友情链接: s_xy241680.zip