PHP 面试踩过的坑
1.get,post 的区别
**显示有区别 ** get方法是将字符串拼接在地址栏后面可以看见 而post方法看不见 **传递的大小有区别 ** 具体大小和浏览器有关系,ie浏览器是2k其他浏览器的最大值可能不同,但是也比较小。 而post方法传递参数的大小是可以设定的,原来是认为无限大。在Php当中在php.ini文件是可以设置参数的大小的。 **安全性 ** get方法安全性比较低因为暴露在外面而post方法安全性比较高 **提交的原理 ** get方法提交的数据都是独立的。 而Post方法将所有的提交的数据变成一个整体(将提交的数据变成xml格式) **灵活性** get方法很灵活, post方法不灵活,必须要有表单的参与才能用post提交很不方便
2.require,include 区别
require是无条件包含也就是如果一个流程里加入require,无论条件成立与否都会先执行require
include有返回值,而require没有(可能因为如此require的速度比include快)
包含文件不存在或者语法错误的时候require是致命的错误终止执行,include不是
3. 获取 URL 后缀名
1 pathinfo()解析文件路径,返回其组成部分; 2 返回关联数组 3 dirname 文件路径 4 basename 文件名+扩展名 5 extension 最后一个扩展名 6 filename 文件名 7 eg: print_r( pathinfo('/ab/cd/e.php') ); 8 Array( 9 [dirname] => /ab/cd 10 [basename] => e.php 11 [extension] => php 12 [filename] => e 13 ) 14 扩展: 15 打印解析路径 var_dump( pathinfo($path) ); 16 打印路径的父级路径 var_dump( pathinfo($path, PATHINFO_DIRNAME) ); 17 打印路径的尾名 var_dump( pathinfo($path, PATHINFO_BASENAME) ); 18 打印路径的最后的扩展名 var_dump( pathinfo($path, PATHINFO_EXTENSION) ); 19 打印路径的文件的名字 var_dump( pathinfo($path, PATHINFO_FILENAME) );
4.tcp,udp,http 区别
5. 获取上级目录的方法
echo __FILE__ ; // 获取当前所在文件的绝对路径及地址,结果:D:\aaa\my.php echo dirname(__FILE__); // 取得当前文件所在的绝对目录,结果:D:\aaa\ echo dirname(dirname(__FILE__)); //取得当前文件的上一层目录名,结果:D:\
6. 数据库主从复制,读写分离
* 什么是主从复制 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库; * 主从复制的原理: 1.数据库有个bin-log二进制文件,记录了所有的sql语句。 2.只需要把主数据库的bin-log文件中的sql语句复制。 3.让其从数据的relay-log重做日志文件中在执行一次这些sql语句即可。 * 主从复制的作用 1.做数据的热备份,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。 2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问频率,提高单机的I/O性能 3.主从复制是读写分离的基础,使数据库能制成更大 的并发。例如子报表中,由于部署报表的sql语句十分慢,导致锁表,影响前台的服务。如果前台服务使用master,报表使用slave,那么报表sql将不会造成前台所,保证了前台的访问速度。 * 主从复制的几种方式: 1.同步复制:所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,...,slave-n完成后才能返回。 2.异步复制:如同AJAX请求一样。master只需要完成自己的数据库操作即可。至于slaves是否收到二进制日志,是否完成操作,不用关心。MYSQL的默认设置。 3.半同步复制:master只保证slaves中的一个操作成功,就返回,其他slave不管。 这个功能,是由google为MYSQL引入的。 * 关于读写分离 在完成主从复制时,由于slave是需要同步master的。所以对于insert/delete/update这些更新数据库的操作,应该在master中完成。而select的查询操作,则落下到slave中。
7. 数据库索引
**什么是索引** 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。(摘自百度百科) **索引类型** 1.FULLTEXT 全文索引 全文索引,仅MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。 2.HASH 哈希索引 HASH索引的唯一性及类似键值对的形式十分适合作为索引,HASH索引可以一次定位,不需要像树形索引那样逐层参照,因此具有极高的效率。但是这种高效是有条件的。即只在“=”和“in”条件下高效,对于范围查询,排序及组合索引仍然效率不高。 3.BTREE 树形索引 BTREE所以是一种将索引按一定算法,存入一个树形的数据结构中(二叉树),每次查询都是从树的入口root开始,一次遍历node,获取leaf。这是MySQL中默认也是最常用的索引类型。 4.RTREE RTREE在MySQL中很少使用,仅支持geometry数据类型,支持该存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。相对于BTREE,RTREE的优势在于范围查找。 **索引种类** 普通索引:仅加速查询 唯一索引:加速查询+列值唯一(可以有null) 主键索引:加速查询+列值唯一(不可以有null)+表中只有一个 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并 全文索引:对文本内容进行分词,进行搜索 外键索引:与主键索引形成联系,保证数据的完整性。 **索引使用的注意事项** 1.符合索引遵循前缀原则 2.like查询%不能再前,否则索引失效。如有需要,使用全文索引 3.column is null可以使用索引 4.如果MySQL估计使用索引比全表扫描慢,则放弃使用索引 5.如果or前的条件中列有索引,后面的没有,索引不会生效。 6.列类型是字符串,查询时,一定要给值加引号,否则索引失效。 7.确定order by 和 group by 中只有一个表的列,这样才能使用索引
8. 高并发的解决方案
web服务器优化 :负载均衡
流量优化:防盗链处理 将恶意请求屏蔽,
前端优化:减少http请求、添加异步请求、启用浏览器缓存和文件压缩、cdn加速、建立独立的图片服务器、
服务端优化: 页面静态化、并发处理、队列处理、
数据库优化: 数据库缓存、分库分表、分区操作 、读写分离、负载均衡
9.MVC 的理解
1、Model(业务模型):应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
2、view(视图):应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
3、controller(控制器):应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
10. 常用的文件操作函数
1 **1. 获得文件名:** 2 basename — 返回路径中的文件名部分 3 4 $path = "/home/cate/index/index2.php";\ 5 $file = basename($path);\ 6 echo $file; //结果index2.php 7 8 **2. 获得目录名** 9 dirname — 返回路径中的目录部分 10 11 $path = "/home/cate/index/index2.php";\ 12 $file = dirname($path);\ 13 echo $file;//结果/home/cate/index 14 15 **3.得到路径关联数组** 16 pathinfo() 函数以数组的形式返回关于文件路径的信息。 17 返回的数组元素如下: 18 - [dirname]: 目录路径 19 - [basename]: 文件名 20 - [extension]: 文件后缀名 21 - [filename]: 不包含后缀的文件名 22 pathinfo(path,options) 23 | path | 必需。规定要检查的路径。 | 24 | options | 可选。规定要返回的数组元素。默认是 all。 25 26 可能的值: 27 28 - PATHINFO_DIRNAME - 只返回 dirname 29 - PATHINFO_BASENAME - 只返回 basename 30 - PATHINFO_EXTENSION - 只返回 extension 31 - PATHINFO_FILENAME - 只返回 filename 32 33 | 34 **4.filesize取得文件大小** 35 filesize ( string $filename ) 36 返回文件大小的字节数,如果出错返回 **FALSE** 并生成一条 **E_WARNING** 级的错误。 37 38 **判断目录是否存在** 39 $lujing = "./nihao/wohao"; 40 if(!is_dir($liujing)){ 41 mkdir(iconv("UTF-8", "GBK", $lujing),0777,true); 42 } 43 44 **判断文件是否存在** 45 file_exists(path);
11. 常见的排序算法
1 1. 冒泡排序 2 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。 3 4 代码实现: 5 $arr=array(1,43,54,62,21,66,32,78,36,76,39); 6 function bubbleSort($arr) 7 { 8 $len=count($arr); 9 //该层循环控制 需要冒泡的轮数 10 for($i=1;$i<$len;$i++) 11 { //该层循环用来控制每轮 冒出一个数 需要比较的次数 12 for($k=0;$k<$len-$i;$k++) 13 { 14 if($arr[$k]>$arr[$k+1]) 15 { 16 $tmp=$arr[$k+1]; 17 $arr[$k+1]=$arr[$k]; 18 $arr[$k]=$tmp; 19 } 20 } 21 } 22 return $arr; 23 } 24 25 2. 选择排序 26 思路分析:在要排序的一组数中,选出最小的一个数与第一个位置的数交换。然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。 27 28 代码实现: 29 function selectSort($arr) { 30 //双重循环完成,外层控制轮数,内层控制比较次数 31 $len=count($arr); 32 for($i=0; $i<$len-1; $i++) { 33 //先假设最小的值的位置 34 $p = $i; 35 36 for($j=$i+1; $j<$len; $j++) { 37 //$arr[$p] 是当前已知的最小值 38 if($arr[$p] > $arr[$j]) { 39 //比较,发现更小的,记录下最小值的位置;并且在下次比较时采用已知的最小值进行比较。 40 $p = $j; 41 } 42 } 43 //已经确定了当前的最小值的位置,保存到$p中。如果发现最小值的位置与当前假设的位置$i不同,则位置互换即可。 44 if($p != $i) { 45 $tmp = $arr[$p]; 46 $arr[$p] = $arr[$i]; 47 $arr[$i] = $tmp; 48 } 49 } 50 //返回最终结果 51 return $arr; 52 } 53 54 3.插入排序 55 思路分析:在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。 56 57 代码实现: 58 function insertSort($arr) { 59 $len=count($arr); 60 for($i=1, $i<$len; $i++) { 61 $tmp = $arr[$i]; 62 //内层循环控制,比较并插入 63 for($j=$i-1;$j>=0;$j--) { 64 if($tmp < $arr[$j]) { 65 //发现插入的元素要小,交换位置,将后边的元素与前面的元素互换 66 $arr[$j+1] = $arr[$j]; 67 $arr[$j] = $tmp; 68 } else { 69 //如果碰到不需要移动的元素,由于是已经排序好是数组,则前面的就不需要再次比较了。 70 break; 71 } 72 } 73 } 74 return $arr; 75 } 76 77 4.快速排序 78 思路分析:选择一个基准元素,通常选择第一个元素或者最后一个元素。通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。 79 80 代码实现: 81 function quickSort($arr) { 82 //先判断是否需要继续进行 83 $length = count($arr); 84 if($length <= 1) { 85 return $arr; 86 } 87 //选择第一个元素作为基准 88 $base_num = $arr[0]; 89 //遍历除了标尺外的所有元素,按照大小关系放入两个数组内 90 //初始化两个数组 91 $left_array = array(); //小于基准的 92 $right_array = array(); //大于基准的 93 for($i=1; $i<$length; $i++) { 94 if($base_num > $arr[$i]) { 95 //放入左边数组 96 $left_array[] = $arr[$i]; 97 } else { 98 //放入右边 99 $right_array[] = $arr[$i]; 100 } 101 } 102 //再分别对左边和右边的数组进行相同的排序处理方式递归调用这个函数 103 $left_array = quick_sort($left_array); 104 $right_array = quick_sort($right_array); 105 //合并 106 return array_merge($left_array, array($base_num), $right_array); 107 }