PHP核心技术面试题汇总

207人已阅读 2020-11-02 16:46:12
导读 今天小编为大家总结整理的是有关PHP核心技术面试题汇总供大家参考学习,下面和小编一起来学习下吧!
Web前端 PHP 移动端编程 二次开发技术

新闻详情

2020-11-02 16:46:12
PHP核心技术面试题汇总

  1 oop是什么?
  答:oop是面向对象编程,面向对象编程是一种计算机编程架构,OOP的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。
  OOP具有三大特点
  1、封装性:也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只需要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现MVC分工合作,也能有效避免程序间相互依赖,实现代码模块间松藕合。
  2、继承性:就是子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。PHP只支持单继承,也就是说一个子类只能有一个父类。
  3、多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。
  1、易维护
  采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
  2、质量高
  在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
  3、效率高
  在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
  4、易扩展
  由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
  2合并两个数组有几种方式,试比较它们的异同
  方式:
  1、array_merge()
  2、’+’
  3、array_merge_recursive
  异同:
  array_merge简单的合并数组
  array_merge_recursive合并两个数组,如果数组中有完全一样的数据,将它们递归合并
  array_combine和‘+’:合并两个数组,前者的值作为新数组的键
  3 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;
  }
  }
  4 PHP的垃圾收集机制是怎样的?
  PHP可以自动进行内存管理,清除不再需要的对象。PHP使用了引用计数(reference counting)这种单纯的垃圾回收(garbage collection)机制。每个对象都内含一个引用计数器,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。
  5写一个函数,尽可能高效的,从一个标准url里取出文件的扩展名,
  例如:http://www.startphp.cn/abc/de/fg.php?id=1需要取出php或.php
  <?php
  //方案一
  function getExt1($url){
  $arr=parse_url($url);
  //Array([scheme]=>http[host]=>www.startphp.cn[path]=>/abc/de/fg.php[query]=>id=1)
  $file=basename($arr['path']);
  $ext=explode('.',$file);
  return$ext[count($ext)-1];
  }
  //方案二
  function getExt2($url){
  $url=basename($url);
  $pos1=strpos($url,'.');
  $pos2=strpos($url,'?');
  if(strstr($url,'?')){
  return substr($url,$pos1+1,$pos2-$pos1-1);
  }else{
  return substr($url,$pos1);
  }
  }
  $path="http://www.startphp.cn/abc/de/fg.php?id=1";
  echo getExt1($path);
  echo"<br/>";
  echo getExt2($path);
  ?>
  6使用正则表达式提取一段标识语言(html或xml)代码段中指定标签的指定属性值(需考虑属性值对不规则的情况,如大小写不敏感,属性名值与等号间有空格等)。此处假设需提取test标签的attr属性值,请自行构建*含该标签的串(腾讯)
  如下:
  <?php
  header("content-type:text/html;charset=utf-8");
  function getAttrValue($str,$tagName,$attrName){
  $pattern1="/<".$tagName."(s+w+s*=s*(['"]?)([^'"]*)())*s+".$attrName."s*=s*(['"]?)([^'"]*)()(s+w+s*=s*(['"]?)([^'"]*)(9))*s*>/i";
  $arr=array();
  $re=preg_match($pattern1,$str,$arr);
  if($re){
  echo"<br/>$arr[6]={$arr[6]}";
  }else{
  echo"<br/>没找到。";
  }
  }
  //示例
  $str1="<test attr='ddd'>";
  getAttrValue($str1,"test","attr");//找test标签中attr属性的值,结果为ddd
  $str2="<test2 attr='ddd'attr2='ddd2't1="t1 value"t2='t2 value'>";
  getAttrValue($str2,"test2","t1");//找test2标签中t1属性的值,结果为t1 value
  ?>
  7 php中WEB上传文件的原理是什么,如何限制上传文件的大小?
  上传文件的表单使用post方式,并且要在form中添加enctype='multipart/form-data'。
  一般可以加上隐藏域:<input type=hidden name='MAX_FILE_SIZE'value=dddddd>,位置在file域前面。
  value的值是上传文件的客户端字节限制。可以避免用户在花时间等待上传大文件之后才发现文件过大上传失败的麻烦。
  使用file文件域来选择要上传的文件,当点击提交按钮之后,文件会被上传到服务器中的临时目录,在脚本运行结束时会被销毁,所以应该在脚本结束之前,将其移动到服务器上的某个目录下,可以通过函数move_uploaded_file()来移动临时文件,要获取临时文件的信息,使用$_FILES。
  限制上传文件大小的因素有:
  客户端的隐藏域MAX_FILE_SIZE的数值(可以被绕开)。
  服务器端的upload_max_filesize,post_max_size和memory_limit。这几项不能够用脚本来设置。
  自定义文件大小限制逻辑。即使服务器的限制是能自己决定,也会有需要个别考虑的情况。所以这个限制方式经常是必要的。
  8请说明PHP中传值与传引用的区别,什么时候传值什么时候传引用?
  按值传递:函数范围内对值的任何改变在函数外部都会被忽略
  按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
  优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。按引用传递则不需要复制值,对于性能提高很有好处。(优缺点会考到)
  9 MySQL数据库中的字段类型varchar和char的主要区别是什么?
  Varchar是变长,节省存储空间,char是固定长度。查找效率要char型快,因为varchar是非定长,必须先查找长度,然后进行数据的提取,比char定长类型多了一个步骤,所以效率低一些。
  10静态化如何实现的?伪静态如何实现?
  1、静态化指的是页面静态化,也即生成实实在在的静态文件,也即不需要查询数据库就可以直接从文件中获取数据,指的是真静态。
  实现方式主要有两种:一种是我们在添加信息入库的时候就生成的静态文件,也称为模板替换技术。一种是用户在访问我们的页面时先判断是否有对应的缓存文件存在,如果存在就读缓存,不存在就读数据库,同时生成缓存文件。
  2、伪静态不是真正意义上的静态化,之所以使用伪静态,主要是为了SEO推广,搜索引擎对动态的文件获取难度大,不利于网站的推广。实习原理是基于Apache或Nginx的rewrite机智
  主要有两种方式:一种是直接在配置虚拟机的位置配置伪静态,这个每次修改完成后需要重启web服务器。另一种采用分布式的,可以在网站的根目录上创建.htaccess的文件,在里面配置相应的重写规则来实现伪静态,这种每次重写时不需要重启web服务器,且结构上比较清晰。
  11如何处理负载,高并发?
  1、HTML静态化
  效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。
  2、图片服务器分离
  把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等
  3、数据库集群和库表散列及缓存
  数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。
  4、镜像:
  尽量减少下载,可以把不同的请求分发到多个镜像端。
  5、负载均衡:
  Apache的*并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。
  12 PHP7的新特性?
  标量类型声明:PHP 7中的函数的形参类型声明可以是标量了。在PHP 5中只能是类名、接口、array或者callable(PHP 5.4,即可以是函数,*括匿名函数),现在也可以使用string、int、float和bool了。
  返回值类型声明:增加了对返回类型声明的支持。类似于参数类型声明,返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。NULL合并运算符:由于日常使用中存在大量同时使用三元表达式和isset()的情况,NULL合并运算符使得变量存在且值不为NULL,它就会返回自身的值,否则返回它的第二个操作数。
  use加强:从同一namespace导入的类、函数和常量现在可以通过单个use语句一次性导入了匿名类:现在支持通过new class来实例化一个匿名类
  13常见的PHP安全性攻击SQL注入:
  用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行。
  防止:使用mysql_real_escape_string()过滤数据手动检查每一数据是否为正确的数据类型使用预处理语句并绑定变量参数化SQL:是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter)来给值,用 或?来表示参数。
  XSS攻击:跨站点脚本攻击,由用户输入一些数据到你的网站,其中*括客户端脚本(通常JavaScript)。如果你没有过滤就输出数据到另一个web页面,这个脚本将被执行。
  防止:为了防止XSS攻击,使用PHP的htmlentities()函数过滤再输出到浏览器。
  CSRF:跨站点请求伪造,是指一个页面发出的请求,看起来就像是网站的信任用户,但是是伪造的
  防止:一般来说,确保用户来自你的表单,并且匹配每一个你发送出去的表单。有两点一定要记住:对用户会话采用适当的安全措施,例如:给每一个会话更新id和用户使用SSL。生成另一个一次性的令牌并将其嵌入表单,保存在会话中(一个会话变量),在提交时检查它。如laravel中的_token
  代码注入:代码注入是利用计算机漏洞通过处理无效数据造成的。问题出在,当你不小心执行任意代码,通常通过文件*含。写得很糟糕的代码可以允许一个远程文件*含并执行。如许多PHP函数,如require可以*含URL或文件名。
  防止代码注入过滤用户输入在php.ini中设置禁用allow_url_fopen和allow_url_include。这将禁用require/include/fopen的远程文件
  16面向对象的特征有哪些方面?
  主要有封装,继承,多态。如果是4个方面则加上:抽象。
  封装:
  封装是*软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的高内聚,低耦合,防止程序相互依赖性而带来的变动影响.
  继承:
  在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
  多态:
  多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
  抽象:
  抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。
  17说说对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子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
  18 MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
  (1)设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。
  (2)选择合适的表字段数据类型和存储引擎,适当的添加索引。
  (3)做mysql主从复制读写分离。
  (4)对数据表进行分表,减少单表中的数据量提高查询速度。
  (5)添加缓存机制,比如redis,memcached等。
  (6)对不经常改动的页面,生成静态页面(比如做ob缓存)。
  (7)书写高效率的SQL。比如SELECT*FROM TABEL改为SELECT field_1,field_2,field_3 FROM TABLE.
  19对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?
  (1)确认服务器是否能支撑当前访问量。
  (2)优化数据库访问。
  (3)禁止外部访问链接(盗链),比如图片盗链。
  (4)控制文件下载。
  (5)做负载均衡,使用不同主机分流。
  (6)使用浏览统计软件,了解访问量,有针对性的进行优化。
  20谈谈你对mysql引擎中的MyISAM与InnoDB的区别理解?
  InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定。基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。
  以下是一些细节和具体实现的差别:
  MyISAM与InnoDB的区别是什么?
  1、存储结构
  MyISAM:每个MyISAM在磁盘上存储成三个文件。*个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD(MYData)。索引文件的扩展名是.MYI(MYIndex)。
  InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。
  2、存储空间
  MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
  InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
  3、可移植性、备份及恢复
  MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
  InnoDB:免费的方案可以是拷贝数据文件、备份binlog,或者用mysqldump,在数据量达到几十G的时候就相对痛苦了。
  4、事务支持
  MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
  InnoDB:提供事务支持事务,外部键等高级数据库功能。具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe(ACID compliant))型表。
  5、AUTO_INCREMENT
  MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是*列,他可以根据前面几列进行排序后递增。
  InnoDB:InnoDB中必须*含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的*列。
  6、表锁差异
  MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
  InnoDB:支持事务和行级锁,是innodb的*特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。
  7、全文索引
  MyISAM:支持FULLTEXT类型的全文索引
  InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。
  8、表主键
  MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
  InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
  9、表的具体行数
  MyISAM:保存有表的总行数,如果select count(*)from table;会直接取出出该值。
  InnoDB:没有保存表的总行数,如果使用select count(*)from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。
  10、CURD操作
  MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
  InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,*使用truncate table这个命令。
  11、外键
  MyISAM:不支持
  InnoDB:支持
  通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能*的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。
  21 redis和memache缓存的区别
  总结一:
  1.数据类型
  Redis数据类型丰富,支持set list等类型
  memcache支持简单数据类型,需要客户端自己处理复杂对象
  2.持久性
  redis支持数据落地持久化存储
  memcache不支持数据持久存储
  3.分布式存储
  redis支持master-slave复制模式
  memcache可以使用一致性hash做分布式
  value大小不同
  memcache是一个内存缓存,key的长度小于250字符,单个item存储要小于1M,不适合虚拟机使用
  4.数据一致性不同
  redis使用的是单线程模型,*了数据按顺序提交。
  memcache需要使用cas*数据一致性。CAS(Check and Set)是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作
  5.cpu利用
  redis单线程模型只能使用一个cpu,可以开启多个redis进程
  总结二:
  1.Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个*的区别。
  2.Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
  3.Redis支持数据的备份,即master-slave模式的数据备份。
  4.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  我个人认为最本质的不同是Redis在很多方面具备数据库的特征,或者说就是一个数据库系统,而Memcached只是简单的K/V缓存
  总结三:
  redis和memecache的不同在于:
  1、存储方式:
  memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
  redis有部份存在硬盘上,这样能*数据的持久性。
  2、数据支持类型:
  redis在数据支持上要比memecache多的多。
  3、使用底层模型不同:
  新版本的redis直接自己构建了VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
  4、运行环境不同:
  redis目前官方只支持Linux上去行,从而省去了对于其它系统的支持,这样的话可以更好的把精力用于本系统环境上的优化,虽然后来微软有一个小组为其写了补丁。但是没有放到主干上
  memcache只能当做缓存,cache
  redis的内容是可以落地的,就是说跟MongoDB有些类似,然后redis也可以作为缓存,并且可以设置master-slave
  22 redis消息队列先进先出需要注意什么?
  答:通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务,实现方式有以下几种方式:
  1)单一列表实现:队列正常的操作是左进右出(lpush,rpop)为了先处理高优先级任务,在遇到高级别任务时,可以直接插队,直接放入队列头部(rpush),这样,从队列头部(右侧)获取任务时,取到的就是高优先级的任务(rpop)
  2)使用两个队列,一个普通队列,一个高级队列,针对任务的级别放入不同的队列,获取任务时也很简单,redis的BRPOP命令可以按顺序从多个队列中取值,BRPOP会按照给出的key顺序查看,并在找到的*个非空list的尾部弹出一个元素,redis>BRPOP list1 list2 0
  list1做为高优先级任务队列
  list2做为普通任务队列
  这样就实现了先处理高优先级任务,当没有高优先级任务时,就去获取普通任务
  方式1最简单,但实际应用比较局限,方式3可以实现复杂优先级,但实现比较复杂,不利于维护
  方式2是推荐用法,实际应用最为合适


上一篇: PHP如何为函数执行设置超时? 下一篇: PHP是如何实现多线程编程的?

相关文章

推荐课程

查看全部课程
石家庄代码加工厂

石家庄代码加工厂

长安校区

查看全部校区 进入官方主页