php相关面试大全 个人总结 长期更新

请选择以下代码运行的结果: <?php if ('1e3' == '1000') echo 'LOL'; ?>

  A 无任何输出结果     B LOL       C 不执行且报错

解析:1e3 是 科学计数法 实数的指数形式 为1乘以10的三次方,故‘1e3’=='1000'是成立的,输出echo ‘LOL’


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

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

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

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

list1 做为高优先级任务队列
list2 做为普通任务队列

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

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

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


请选出以下代码运行的结果: <?php $a = "aabbzz"; $a++; echo $a; ?>

  A b            B aabbzz           C aabcaa

解析: 字符串字母相加其实就是在末尾字母加一 如:$a = "a"; $a++;答应结果就是 b,$a=''aa';结果就是ab 故$a = "aabb";打印结果就是 aabc ,如$a = "aabbz";结果就是 aabca,因为Z是末尾字母故加一变为a,向前一位进一,b就变为c,故结果为C;


写出一下程序的输出结果:<?php  

$data = ['a','b','c'];

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

$v = &$data[$k];

}

A $data = ['a','b','c'];            B $data = ['b','b','c'];           C $data = ['b','c','c'];

解析:这里有个考点要记得 就是&是引用;修改引用变量的值,那么空间的值也会改变,第一次循环 得到$v=&$data[0]=>'a',第二次循环$v=&$data[1]=>'b',可见第一次引用的$data[0]的值已经被改变,所以此时的$data[0]=b,此时$v引用的$data[1],进入第三次循环 此时$v又变为 $v=&$data[2]=>'c',,$v又一次改变,引用的$data[1]的值也被改变为C,所以此时的$data[1]=c,这样循环结束 $data[0]=>'b', $data[1]=>'c', $data[2]=>'c',


写出一下程序的输出结果:<?php $a= 0.1; $b = 0.7;if($a+$b ==0.8){ echo true; }else{ echo false; } >

    A 空;     B true;    C false;     D、1;  E、0;  F:报错

    解析:这里的考点有两个:1,echo false和true的值;2、浮点类型不能用于精确计算;首先浮点类型的数据不能用于计算,他会将浮点类型转为二进制,所以有一定的损耗,故它无限接近于0.8,也就是0.79999999...,所以echo 应该是个false;echo false;结果是空;echo true;结果是1;


用PHP写出显示客户端的IP和服务端的IP

    echo $_SERVER[‘REMOTE_ADDR’];//客户端IP

    echo gethostbyname(“www.baidu.com”)//服务端


以下表达式的结果是:

$a= 0;

$b= 0;

if($a= 3>0 || $b= 3>0){

$a++;

$b++;

}

echo $a,$b;

A报错;    B:1,1; (要是真的只有两个选项该多好肯定大家都选B)

解析:此题考查的是运算符的优先级问题,首先在此题中比较运算符>逻辑运算符>赋值,所以1,先看 3>0为true,2,因为是||运算所以后面的$b=3>0 形成短路作用,这时的$a=true,$b=0;

  故$a++;为1;$b++;为1这里解释下布尔类型运算不影响布尔类型结果;但是$b=0;$b++;就改变为1, echo true;结果为1


PHP中如何优化多个if...esleif语句的情况

    解析:首先尽可能将表达式可能性越大的越往前面放,其次如果我们判断的内容比较复杂且 判断的值只是字符串,整型,浮点 那么就可以用switch...case来代替

用正则 写出以139开头的手机号码

$str = '13812345678';
$pattern = '/^139\d{8}$/';
preg_match($pattern,$str,$macth);
var_dump($macth);


用PHP方式对目录进行遍历
$dir = './test';

function loopDir($dir){

$handle = opendir($dir);
while(false !==($file =readdir($handle))){
    if($file!='.'&&$file!='..'){
        echo $file."<br>";
        if(filetype($dir.'/'.$file)=='dir'){
            loopDir($dir.'/'.$file);
        }
    }
}

}

loopDir($dir);


请简单叙述 CGI fastCGI h和 PHP-FPM的区别
CGI 代表为了联系PHP 和websevae 的一个桥梁
fastCGI 是CGI的改良版
PHP-FPM 进程管理器


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

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

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

优缺点:按值传递时,php必须复制值。特别是对于大型的字符串和对象来说,这将会是一个代价很大的操作。

    按引用传递则不需要复制值,对于性能提高很有好处。


MySQL数据库中的字段类型varchar和char的主要区别是什么?

  char和varchar最大的不同就是一个是固定长度,一个是可变长度.由于是可变长度,因此存储的是实际字符串再加上一个记录字符串长度的字节。如果分配给char或varchar列的值超过 列的最大长度,则对值进行裁剪.

  varchar(M)和char(M),M都表示字符数.varchar的最大长度为65535个字节,不同的编码所对应的最大可存储的字符数不同.char最多可以存放255个字符,不同的编码最大可用字节数不同


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

确认服务器硬件是否足够支持当前的流量
优化数据库访问。
禁止外部的盗链。
控制大文件的下载。
使用不同主机分流主要流量
使用流量分析统计软件
尽量使用静态页,缓存


优化mysql数据库的方法

    1,数据表中的数据类型的优化 如选择合适的字段,选择效率快速的字段

    2,索引优化

    3、SQL语句的优化

      (1)优化查询过程中的数据访问如使用limit、使用返回列不用*

      (2)优化长难句的查询语句 变复杂为简单、切分查询、分解关联查询

      (3)优化特定类型的查询语句如优化count()、优化关联查询、优化子查询、优化Group by、优化li'mit

    4、存储引擎的优化

      (1)尽量使用InnoDB存储引擎,因为它支持事务、外键、使用独立表空间、使用的是行级锁、

    5、数据表结构的设计优化

      (1)分区操作 如通过特定的策略对数据进行物理拆分、对用户透明的、partition by

      (2)分库分表 如水平拆分(以行级进行拆分)、垂直拆分(列及拆分)

    6、数据架构的优化

      (1)主从复制

      (2)读写分离

      (3)双主热备

      (4)负载均衡  通过LVS的三种模式实现的、Mycat数据库中间件实现的


语句include和require的区别是什么?

    require是无条件包含,也就是如果一个流程里加入require,无论条件成立与否都会先执行require,当文件不存在或者无法打开的时候,会提示错误,并且会终止程序执行

    include有返回值,而require没有(可能因为如此require的速度比include快),如果被包含的文件不存在的化,那么会提示一个错误,但是程序会继续执行下去


redis和memcacahe、mongoDB的区别?

    都是非关系型数据库,性能都非常高,但是mongoDB和memcache、redis是不同的两种类型。后两者主要用于数据的缓存,前者主要用在查询和储存大数据方面,是最接近数据库的文档型的非关系数据库。

    从数据存储位置上来分,memcache的数据存在内存中,而redis既可以存储在内存中,也可以存储的到磁盘中,达到持久化存储的功能,memcache一旦断电,数据全部丢失,redis可以利用快照和AOF把数据存到磁盘中,当恢复时又从磁盘中读取到内存中,当物理内存使用完毕后,可以把数据写入到磁盘中。

    从存储数据的类型上来分,memcache和redis存储的方式都是键值对,只不过redis值的类型比较丰富,有string(字符串),hash(哈希),list(列表),set(集合)zset(有序集合),而memcache主要存储的是字符串。


四种标量类型:boolean (布尔型)、integer (整型)、float (浮点型, 也称作 double)、string (字符串)

    两种复合类型:array (数组)、object (对象)

    最后是两种特殊类型:resource(资源)、NULL(NULL


静态化如何实现的?伪静态如何实现?

    1、 静态化指的是页面静态化,也即生成实实在在的静态文件,也即不需要查询数据库就可以直接从文件中获取数据,指的是真静态。
      实现方式主要有两种:

        一种是我们在添加信息入库的时候就生成的静态文件,也称为模板替换技术。

        一种是用户在访问我们的页面时先判断是否有对应的缓存文件存在,如果存在就读缓存,不存在就读数据库,同时生成缓存文件。

    2、伪静态不是真正意义上的静态化,之所以使用伪静态,主要是为了SEO推广,搜索引擎对动态的文件获取难度大,不利于网站的推广。实习原理是基于Apache或Nginx的rewrite机智
  主要有两种方式:

      一种是直接在配置虚拟机的位置配置伪静态,这个每次修改完成后需要重启web服务器。

      另一种采用分布式的,可以在网站的根目录上创建.htaccess的文件,在里面配置相应的重写规则来实现伪静态,这种每次重写时不需要重启web服务器,且结构上比较清晰。


如何处理负载,高并发

1、HTML静态化
效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。
2、图片服务器分离
把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等
3、数据库集群和库表散列及缓存
数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。
4、镜像:
尽量减少下载,可以把不同的请求分发到多个镜像端。
5、负载均衡:
Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。


说一下单引号双引号?

  单引号内部的变量不会执行, 双引号会执行

    单引号解析速度比双引号快。

    单引号只能解析部分特殊字符,双引号可以解析所有特殊字符


PHP7的新特性?重点

标量类型声明:PHP 7 中的函数的形参类型声明可以是标量了。在 PHP 5 中只能是类名、接口、array 或者 callable (PHP 5.4,即可以是函数,包括匿名函数),现在也可以使用 string、int、float和 bool 了。

  返回值类型声明:增加了对返回类型声明的支持。 类似于参数类型声明,返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。

  NULL 合并运算符:由于日常使用中存在大量同时使用三元表达式和 isset()的情况,NULL 合并运算符使得变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。

  use 加强:从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了

  匿名类:现在支持通过new class 来实例化一个匿名类


PHP 数组排序

sort() - 以升序对数组排序

rsort() - 以降序对数组排序

asort() - 根据值,以升序对关联数组进行排序

ksort() - 根据键,以升序对关联数组进行排序

arsort() - 根据值,以降序对关联数组进行排序

krsort() - 根据键,以降序对关联数组进行排序


PHP支持多继承吗?

  不支持。PHP中只允许单继承,父类可以被一个子类用关键字“extends”继承。

PHP如何实现多继承吗?

  可以使用 interface 或 trait 实现 。

    1.使用 interface 声明类不能被实例化,并且属性必须是常量,方法不能有方法体 

    2.trait 声明的类不能被实例化,由use引入,会覆盖父类的相同属性及方法,如果有多个use,那么按顺序下面的覆盖最上面的相同的属性及方法


优化MYSQL数据库的方法

(1)选择最有效率的表名顺序

(2)WHERE子句中的连接顺序

(3)SELECT子句中避免使用‘*’

(4)用Where子句替换HAVING子句

(5)通过内部函数提高SQL效率

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

(7)提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉。

(1).选取最适用的字段属性,应该尽量把字段设置为NOT NULL

(2).使用连接(JOIN)来代替子查询(Sub-Queries)

(3).使用联合(UNION)来代替手动创建的临时表

(4).尽量少使用 LIKE 关键字和通配符

(5).使用事务和外键


MySQL主从备份的原理?

  mysql支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。


error_reporting() 的作用?

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


如何修改session的生存时间

在php.ini 中设置 session.gc_maxlifetime = 1440 //默认时间

代码实现 123

$lifeTime = 24 * 3600; // 保存一天

session_set_cookie_params($lifeTime);

session_start();


常见的 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的远程文件


__FILE__表示什么意思?

   文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径


 http的3次握手
     第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;

     第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包

     第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。

     完成三次握手,主机A与主机B开始传送数据。


PHP处理数组的常用函数?(重点看函数的‘参数’和‘返回值’)

(1)array() 创建数组

(2)in_array() 判断元素是否在数组中

(3)count() 返回数组中元素的数目

(4)array_merge() 将多个数组合并成一个数组

(5)array_diff() 比较两个或两个以上数组的差异

(6)array_intersect() 获取两个或两个数组以上的交集

(7)array_keys() 获取数组的key列表

(8)array_values() 获取数组的值列表

(9)array_unique() 删除数组中的重复值

(10)array_push()将一个或多个元素插入数组的末尾(入栈)

(11)array_pop() 弹出并返回 array 数组的最后一个单元(出栈)

(12)array_walk() 使用用户自定义函数对数组中的每个元素做回调处理


PHP处理字符串的常用函数?(重点看函数的‘参数’和‘返回值’)

(1)trim() 移除字符串两侧的空白字符和其他字符;

(2)strlen() 获取字符串的长度

(3)mb_strlen() 获取字符串长度(可指定字符编码,对中文字符串计算长度)

(4)substr()返回字符串的一部分;

(5)str_replace() 子字符串替换

(6)str_repeat () 重复一个字符串

(7)is_string() 检测变量是否是字符串;

(8)str_shuffle () 随机打乱一个字符串

(9)sprintf() 返回根据格式化字符串生成的字符串(通常用于获取分表后的数据表名)

(10)strstr() 查找字符串的首次出现

(11)addslashes 使用反斜线引用字符串


PHP处理时间的常用函数?(重点看函数的‘参数’和‘返回值’)

(1)date() 格式化一个本地时间/日期。

(2)getdate() 取得日期/时间信息。

(3)date_default_timezone_set() 设定默认时区。

(4)date_default_timezone_get() 返回默认时区。

(5)mktime() 返回一个日期的 Unix时间戳。

(6)strtotime() 将任何字符串的日期时间描述解析为 Unix 时间戳

(7)strftime() 根据区域设置格式化本地时间/日期


PHP处理数据库的常用函数?(重点看函数的‘参数’和‘返回值’)


PHP操作文件的常用函数?(重点看函数的‘参数’和‘返回值’)

(1)打开文件 fopen()

(2)读取文件 fgets() ; 注:file_get_contents()也是读取文件

(3)写入文件fwrite() ; 注:file_put_contents()同样可以写入文件

(4)关闭文件句柄 fclose()

(5)移动 / 重命名文件 rename()

(6)复制文件 copy()

(7)创建文件 vim 或 touch

(8)删除文件 unlink()

(9)获取文件上次访问的时间 fileatime()

(10)获取文件上次修改的时间 filemtime()

(11)获取文件大小 filesize()

(12)获取文件类型 filetype()

(13)获取文件详细信息 state()

(14)判断是否是目录 is_dir()


PHP操作目录(文件夹)的常用函数?(重点看函数的‘参数’和‘返回值’)

(1)打开目录 opendir()

(2)读取目录 readdir()

(3)删除目录 rmdir()

(4)关闭目录句柄 closedir()

(5)创建目录 mkdir()

(6)返回路径中的目录部分 dirname()

(7)取得当前工作目录 getcwd()

(8)列出指定路径中的文件和目录 scandir()


SQL语言包括哪几部分?每部分都有哪些操作关键字?
答:SQL语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL)四个部分。
数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index等
数据操纵:Select ,insert,update,delete,
数据控制:grant,revoke
数据查询:select


什么是事务?及其特性?
事务:是一系列的数据库操作,是数据库应用的基本逻辑单位。

特性:

(1)原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。

(2)一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态

(3)隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,

(4) 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。

简单理解:在事务里的操作,要么全部成功,要么全部失败


什么叫视图?游标是什么?
视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。

游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。


什么是存储过程?用什么来调用?
存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个命令对象来调用存储过程。


索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。

缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。


如何通俗地理解三个范式?
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;

第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。。


你可以用什么来确保表格里的字段只接受特定范围里的值?
Check限制,它在数据库表格里被定义,用来限制输入该列的值。


说说对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 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描


SQL语句中‘相关子查询’与‘非相关子查询’有什么区别?
(1)非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。

(2)相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。

因此非相关子查询比相关子查询效率高


Mysql 的存储引擎,myisam和innodb的区别。
MyISAM 是非事务的存储引擎;适合用于频繁查询的应用;表锁,不会出现死锁;不支持事务。适合小数据,小并发

innodb是支持事务的存储引擎;适合于插入和更新操作比较多的应用;设计合理的话是行锁(最大区别就在锁的级别上);适合大数据,大并发。


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.


对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?
(1) 确认服务器是否能支撑当前访问量。

(2) 优化数据库访问。

(3)禁止外部访问链接(盗链), 比如图片盗链。

(4)控制文件下载。

(5)做负载均衡,使用不同主机分流。

(6)使用浏览统计软件,了解访问量,有针对性的进行优化。


堆和栈的区别?

栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;

堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。


XML 与 HTML 的主要区别

语法要求不同:

(1)在html中不区分大小写,在xml中严格区分。

(2)在HTML中,有时不严格,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略

或者之类的结束标记。在XML中,是严格的树状结构,绝对不能省略掉结束标记。
(3) 在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个/ 字符作为结尾。这样分析器就知道不用查找结束标记了。

(4)在XML中,属性值必须分装在引号中。在HTML中,引号是可用可不用的。

(5)在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。

(6) 在XML文档中,空白部分不会被解析器自动删除;但是html是过滤掉空格的。

标记不同:

(1)html使用固有的标记;而xml没有固有的标记。

(2)Html标签是预定义的;XML标签是免费的、自定义的、可扩展的。

作用不同:

(1)html是用来显示数据的;xml是用来描述数据、存放数据的,所以可以作为持久化的介质!Html将数据和显示结合在一起,在页面中把这数据显示出来;xml则将数据和显示分开。 XML被设计用来描述数据,其焦点是数据的内容。HTML被设计用来显示数据,其焦点是数据的外观。

(2)xml不是HTML的替代品,xml和html是两种不同用途的语言。 XML 不是要替换 HTML;实际上XML 可以视作对 HTML 的补充。XML 和HTML 的目标不同HTML 的设计目标是显示数据并集中于数据外观,而XML的设计目标是描述数据并集中于数据的内容。

(3)对于XML最好的形容可能是: XML是一种跨平台的,与软、硬件无关的,处理与传输信息的工具。

(4)XML未来将会无所不在。XML将成为最普遍的数据处理和数据传输的工具。


出现性能瓶颈如何快速定位解决
服务器负载 慢日志 xhprof 慢sql


如何保证代码质量
高质量代码三要素:可读性,可维护性,可变更性


如何设计一个微博
用户可以关注他人 可以发布微博 可以查看关注人的微博 可以评论微博

用户表 关注表 微博表 评论表


获取上周一和周日的日期
echo date('Y-m-d',strtotime('monday last week'));
echo date('Y-m-d', strtotime('-' . (6+date('w')) . ' days'));
echo date('Y-m-d',strtotime('sunday last week'));


对数组实现去除空元素 排重 按值从大到小排序 重新建立数字索引
array_values(rsort(array_unique(array_filter($arr))))


对二维数组按照 title+pubscore 去重

function unique_by_key($arr, $key1,$key2) {
  $tmp_key = [];
  foreach ($arr as $key => $item) {
      if ( in_array($item[$key1].$item[$key2], $tmp_key) ) {
        unset($arr[$key]);
      } else {
        $tmp_key[] = $item[$key1].$item[$key2];
    }
  }
  return $arr;
}
//使用示例:
$arr = array(
  array('id' => 1, 'title' => 'a','pubscore'=>1),
  array('id' => 2, 'title' => 'a','pubscore'=>1),
  array('id' => 3, 'title' => 'b','pubscore'=>2),
  array('id' => 4, 'title' => 'c','pubscore'=>3),
  array('id' => 5, 'title' => 'd','pubscore'=>3),
);
print_r(unique_by_key($arr,'title','num'));

写一个正则 匹配新闻标题不能为数字,纯字母,不能包含 彩票/广告/启示


linux 压缩 解压缩命令
tar -cvf jpg.tar *.jpg
tar -xvf jpg.tar

linux下后台执行 test.php 将结果输出到test.log
php test.php & >test.log


无限级多种实现
第一种(推荐)

function infiniteSort($data, $showFName, $titleFName, $pidFName = 'pid', $idFName = 'id', $levelFName = 'level', $pid = 0, $level = 0)
{
    $tree = array();

    foreach ($data as $key => $value) {

        if ($value[$pidFName] == $pid) {
            $value[$levelFName] = $level;
            $value[$showFName] = str_repeat('&nbsp;&nbsp;', $level) . '|-' . $value[$titleFName];
            $tree[] = $value;
            unset($data[$key]);
            $tempArr = infiniteSort($data, $showFName, $titleFName, $pidFName, $idFName, $level, $value[$idFName], $level + 1);
            if(!empty($tempArr)){
                $tree = array_merge($tree, $tempArr);
            }
        }

    }

    return $tree;
}

注意:
1、$data 已经asc排序过的所有数据
2、$showFName 显示名字的字段名(格式化过的)
3、$titleFName 标题的字段名(无格式化)
4、$levelFName 层级字段名
5、$pidFName 父id的字段名
6、$idFName id的字段名

第二种(使用引用变量)

/**
 * 无限级分类
 * @param Array $treeList //接受处理完成数据的数组
 * @param Array $data //数据库里获取的结果集
 * @param String $level //格式化层级字段名
 * @param Int $pid
 * @param Int $count //第几级分类
 */
function tree(&$treeList, &$data, $level, $show_name, $field_name, $field_pid = 'pid', $field_id = 'id', $pid = 0, $count = 0)
{
    foreach ($data as $key => $value) {

        if ($value[$field_pid] == $pid) {
            $value[$level] = $count;
            $value[$show_name] = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;',$count).'|-'.$value[$field_name];
            $treeList[] = $value;
            unset($data[$key]);
            tree($treeList, $data, $level, $show_name, $field_name,$field_pid, $field_id, $value[$field_id], $count+1);
        }

    }
}

注意:
1、$data 已经asc排序过的所有数据
2、返回的无限级列表数据都存在$treeList里面

第三种(使用静态变量有限制:如果一次请求调用两次来实现2个无限级分类就会出现问题,所以不推荐)

public function getTree($list, $parent_id, $level=0) {

//应该是静态的局部变量,这样才能保证,在递归调用时,所有
//的getTree方法,操作的是一个Tree空间。
static $tree = array();//保存找到的分类的数组
//遍历所有分类,通过parent_id判断,哪些是我们正在查找的
foreach($list as $row) {
    //判断当前所遍历的分类$row, 是否是当前需要查找的子分类
    if($row['pid'] == $parent_id) {
        //找到了一个分类
        //存起来,存哪?
        $row['level'] = $level;
        $tree[] = $row;
        //继续查找当前$row所代表的分类的子分类
        $this->getTree($list, $row['id'], $level+1);
    }
}
return $tree;

}

注意:
1、$list 已经asc排序过的所有数据


写一个shell命令 实现找出所有包含 spread的进程,杀死这些进程并记录日志,日志包含杀死进程名称和杀死进程的时间

ps -ef |grep spread |grep -v grep |awk '{print $2}'|xargs kill -9
kill -9 $(ps -ef | grep spread| grep -v grep | awk '{print $2}')

排行榜统计 sql
订单表有如下字段
id 自增id
user_id 购买者id
product_id 商品id
time 购买时间
price 订单总价
找出销量大于1000的商品,按销量倒序 和 找出消费最多的10个用户

select product_id,count(*) s from orders group by product_id order by s having s>1000;

select user_id,sum(price) s from orders group by user_id order by s desc limit 10;


写出你知道的http头部属性 注意大小写 并说明用途
Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html
Accept-Charset 浏览器可以接受的字符编码集。 Accept-Charset: iso-8859-5
Accept-Encoding 指定浏览器可以支持的web服务器返回内容压缩编码类型。 Accept-Encoding: compress, gzip
Accept-Language 浏览器可接受的语言 Accept-Language: en,zh
Accept-Ranges 可以请求网页实体的一个或者多个子范围字段 Accept-Ranges: bytes
Authorization HTTP授权的授权证书 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control 指定请求和响应遵循的缓存机制 Cache-Control: no-cache
Connection 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) Connection: close
Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new;
Content-Length 请求的内容长度 Content-Length: 348
Content-Type 请求的与实体对应的MIME信息 Content-Type: application/x-www-form-urlencoded
Date 请求发送的日期和时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect 请求的特定的服务器行为 Expect: 100-continue
From 发出请求的用户的Email From: user@email.com
Host 指定请求的服务器的域名和端口号 Host: www.zcmhi.com
If-Match 只有请求内容与实体相匹配才有效 If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since 只在实体在指定时间之后未被修改才请求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards 限制信息通过代理和网关传送的时间 Max-Forwards: 10
Pragma 用来包含实现特定的指令 Pragma: no-cache
Proxy-Authorization 连接到代理的授权证书 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range 只请求实体的一部分,指定范围 Range: bytes=500-999
Referer 先前网页的地址,当前请求网页紧随其后,即来路 Referer: http://www.zcmhi.com/archives...
TE 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 TE: trailers,deflate;q=0.5
Upgrade 向服务器指定某种传输协议以便服务器进行转换(如果支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent User-Agent的内容包含发出请求的用户信息 User-Agent: Mozilla/5.0 (Linux; X11)
Via 通知中间网关或代理服务器地址,通信协议 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 关于消息实体的警告信息 Warn: 199 Miscellaneous warning


有一个文本文件,内容为ip 每行一个ip 格式为
1.2.3.4
4.5.6.7
2.3.4.5
1.2.3.4
写出 shell命令 统计 ip出现的次数 结果类似
1.2.3.4 2
4.5.6.7 1
2.3.4.5 1

awk '{arr[$1]++;}END{for(i in arr){print i , arr[i] }}' test.txt

__destruction() 和 __autoload()触发时机
unset 和 加载一个为包含的文件


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

echo monkey(10,4);//5
function monkey($m,$n){
    $arr=range(1,$m);
    $i=0;
    while(count($arr)>1){
        if(($i+1)%$n==0){
            unset($arr[$i]);
        }else{
            $arr[]=$arr[$i];
            unset($arr[$i]);
        }
        $i++;
    }
    return $arr[$i];
}

实现一个发红包功能,100元发给8人


实现斐波那契数列

function fib($n) {
    if($n <= 0) return 0;
    if ($n <= 2) return 1;
    return fib($n - 1) + fib($n - 2);
} 
 
function fib2($n) {
if ($n <= 2) return 1;
$arr = [0,1,1];
for ($i = 3; $i <= $n; $i++) {
    $arr[$i] = $arr[$i - 1] + $arr[$i - 2];
}
return $arr[$n];
} 

二分查找

function binSearch($arr,$search){
$height=count($arr)-1;
$low=0;
while($low<=$height){
$mid=floor(($low+$height)/2);//获取中间数
if($arr[$mid]==$search){
return $mid;
}elseif($arr[$mid]<$search){//当中间值小于所查值时,则$mid左边的值都小于$search,此时要将$mid赋值给$low
$low=$mid+1;
}elseif($arr[$mid]>$search){//中间值大于所查值,则$mid右边的所有值都大于$search,此时要将$mid赋值给$height
$height=$mid-1;
}
}
return "查找失败";
}

二维数组转换成一维数组

$user = array(
     array('id' => 100, 'username' => 'a1'),
     array('id' => 101, 'username' => 'a2'),
     array('id' => 102, 'username' => 'a3'),
     array('id' => 103, 'username' => 'a4'),
     array('id' => 104, 'username' => 'a5'),
);
$result = array_reduce($user, function ($result, $value) {
    return array_merge($result, array_values($value));
}, array());
/*
Array
(
    [0] => 100
    [1] => a1
    [2] => 101
    [3] => a2
    [4] => 102
    [5] => a3
    [6] => 103
    [7] => a4
    [8] => 104
    [9] => a5
)
*/
$result = [];
array_walk_recursive($user, function($value) use (&$result) {
    array_push($result, $value);
});
$result = [];
array_map(function ($value) use (&$result) {
    $result = array_merge($result, array_values($value));
}, $user);

2次foreach 输出什么

//参考https://segmentfault.com/q/1010000008279730
$arr = [1,2,3];
    foreach($arr as &$v) {
        //nothing todo.
    }
    foreach($arr as $v) {
        //nothing todo.
    }
    var_export($arr);
    //output:array(0=>1,1=>2,2=>2)

读取1G大文件
使用游标或者yield生成器来获取数据库的数据


http https 区别
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
https://www.itcodemonkey.com/article/4195.html


权限如何设计
user用户表、role角色表、perm权限表、role-user用户角色关联表、role-perm角色权限关联表


apache nginx 区别
https://juejin.im/entry/5b34b2d7e51d4558ae19f2eb


redis 持久化
aof rdb https://www.hoohack.me/2018/04/04/deep-learning-redis-durability
https://juejin.im/entry/5b35ad87f265da597759804b/


数据库锁的了解
乐观锁(代码处理)与悲观锁( select for update)


2038 时间问题
//解决:DateTime 或者 使用64位操作系统

$str_time = '2100-10-02'; 
 function newStrToTime($str_time) { 
$result = strtotime($str_time);
if(empty($result)) { 
$date = new DateTime($str_time); 
$result = $date->format('U'); 
} 
return $result; 
} 

谈谈最近微信支付 xxe 漏洞
php 调用simplexml_load_string之前把外部引用实体关掉:

libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

写个定时任务
分 时 日 月 周


opcache了解
缓存字节码


array_merge + 区别

<?php

$arrFirst = [
    "first_key"  => 1,
    "second_key" => 1,
    "third_key"  => 1,
];

$arrSecond = [
    "first_key"  => 2,
    "second_key" => 2,
    "fourth_key" => 2,
];

//对于重复的字符串键,array_merge后,后面数组的键值会覆盖前面的
echo sprintf("\narray_merge result:\n%s", print_r(array_merge($arrFirst, $arrSecond), true));

//对于重复的字符串键,+操作后,前面数组的键值会覆盖后面的
echo sprintf("\narray + result:\n%s", print_r($arrFirst + $arrSecond, true));

//对于重复的字符串键,array_merge_recursive后,相同键名的键值会被合并到同一数组中(会递归)
echo sprintf("\narray_merge_recursive result:\n%s", print_r(array_merge_recursive($arrFirst, $arrSecond), true));

所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站部分内容收集于互联网,如果有侵权内容、不妥之处,请联系我们删除。敬请谅解!

  Previous post PHP 无限级分类最佳实践
Next post   mysql explain详解

添加新评论

有种脾气叫,不放弃。

梦想是注定孤独的旅行,路上少不了质疑和嘲笑,但那又怎样,哪怕遍体鳞伤也要活的漂亮。

不管现在有多么艰辛,我们也要做个生活的舞者。

命运从来不会同情弱者。

不怕万人阻挡在前方,只怕自己先行投降。