【PHP】高级面试题之十万个为什么?(二)

一曲冷凌霜 提交于 2019-12-09 06:32:37

成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。


这里写图片描述


1、处理PHP数组,foreach和for那个效率更高?效率高的原因是什么呢?

答:foreach的效率更高,因为foreach走的是链表的遍历,详细解释请查看另外一篇文章“for和foreach那个效率更高?原因是什么?”

for和foreach那个效率更高?

2、PHP数组底层采用的是循环链表,正向、反向遍历数组都很方便是否正确呢?

答:这个说话是错误的,php数组是双向链表,故而可以正向、反向遍历数组

什么是链表呢?

    链表是一种经常被使用的一种数据结构。链表中的每一个元素都至少有两个元素,一个指向它的下一个元素,一个用来存放它自己的数据——>我们称之为单项链表,缺点是每次查询都需要从开始位置开始一次像下找。
    后来加了一个元素指向前一个元素,这样我们不管知道链表中哪一个元素,我们都能正向、反向的查到所有的元素(php数组就是这样)——>双向链表

3、PHP数组插入和删除操作的时间复杂度都是O(1)?

答:我们可以用一个整数来当作下标去数组中取出我们想要的数据,就像var_dump()的实现中通过args[i]来获取参数并把它传递给php_var_dump()函数那样。使用数组最大的好处便是速度!读写都可以在O(1)内完成,因为它每个元素的大小都是一致的,只要知道下标,便可以瞬间计算出其对应的元素在内存中的位置,从而直接取出或者写入。

4、unset一个引用,只是断开了变量名和变量内容之间的绑定,这并不意味着变量内容被销毁了吗?

答:如果在函数中 unset() 一个通过引用传递的变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。
<?php
    function foo(&$bar) {
            unset($bar);
            $bar = "blah";
    }

    $bar = 'something';
     echo "$bar\n";        // 输出的结果是something

    foo($bar);
     echo "$bar\n";        // 输出的结果是something
?>

5、PHP引用本质就是指针,在函数调用范围内可以绑定到别的变量上面?

答:错,引用只是值内存块的别名,而指针是一个实体,存放的值内存地址,需要额外分配内存空间。

6、PHP官方推荐使用Apache的prefork模式,此模式下建议选用Non Thread Safe版本?

目前主要有两种模式:

prefork模式和worker模式,Apache官方推荐使用prefork模式,两种模式的区别:worker模式可以应对高流量,但是安全性不太好;prefork模式安全性比较好,但是性能会差一点,各位可以根据自己服务器的类别选取不同的模式,更好的使用apache。

Non Thread Safe版本是什么意思?

先从字面意思上理解,None-Thread Safe就是非线程安全,在执行时不进行线程(thread)安全检查;Thread Safe就是线程安全,执行时会进行线程(thread)安全检查,以防止有新要求就启动新线程的 CGI 执行方式耗尽系统资源。

PHP的两种执行方式:

ISAPI和FastCGI。FastCGI执行方式是以单一线程来执行操作,所以不需要进行线程的安全检查,除去线程安全检查的防护反而可以提高执行效率,所以,如果是以 FastCGI(无论搭配 IIS 6 或 IIS 7)执行 PHP ,都建议下载、执行 non-thread safe 的 PHP (PHP 的二進位檔有兩種包裝方式:msi 、zip ,請下載 zip 套件)。而线程安全检查正是为ISAPI方式的PHP准备的,因为有许多php模块都不是线程安全的,所以需要使用Thread Safe的PHP。

7、用PHP彩蛋能大致获取PHP的版本, PHP中一共隐藏了4个彩蛋

四个菜单分别为:

?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000 (PHP贡献者列表)  
?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 (PHP的LOGO)  
?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 (Zend LOGO)  
?=PHPE9568F36-D428-11d2-A769-00AA001ACF42 (PHP LOGO 蓝色大象)  

8、类名可以是任何非 PHP保留字的合法标签,汉字也可以作为PHP的类名?

首先要了解什么是PHP保留字?

例如一些关键字,不能使用它们的任何一个作为常量、方法名或是类名,但是可以使用它们作为变量名,如:clone、do、die()等等。汉字也可以作为PHP的类名,但是基本没人这么干~~~

9、如果PHP的子类中定义了构造函数,则创建子类的对象时,会隐式的调用其父类的构造函数吗?

必须显式调用 parent::__construct();

10、序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

为了能够unserialize()一个对象,这个对象的类必须已经定义过。如果序列化类A的一个对象,将会返回一个跟类A相关,而且包含了对象所有变量值的字符串。 如果要想在另外一个文件中解序列化一个对象,这个对象的类必须在解序列化之前定义,可以通过包含一个定义该类的文件或使用函数spl_autoload_register()来实现。

<?php
// classa.inc:

  class A {
      public $one = 1;

      public function show_one() {
          echo $this->one;
      }
  }

// page1.php:

  include("classa.inc");

  $a = new A;
  $s = serialize($a);
  // 把变量$s保存起来以便文件page2.php能够读到
  file_put_contents('store', $s);

// page2.php:

  // 要正确了解序列化,必须包含下面一个文件
  include("classa.inc");

  $s = file_get_contents('store');
  $a = unserialize($s);

  // 现在可以使用对象$a里面的函数 show_one()
  $a->show_one();
?>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!