精选一些PHP面试题汇总一下给个参考:
数据库字段 int(10)
与 int(11)
的区别
在字段被指定为 int
时就确定了他是占用 4bytes
(字节),也就是 8bit
(位),而 int(10)
代表的其实是显示宽度,也就是存储的时候如果不足10位会自动补全,比如 int(4)
,输入的是 100
,那么会被补全为 0100
。
所以 int(M)
中的M理解为最大显示宽度。最大有效显示宽度是255。显示宽度与存储大小或类型包含的值的范围无关。
char
和 varchar
的区别
char(10)
指定字符串长度为10,即使不足10位也一样占用10字节,并且 MySQL
在存储时会自动删除字符串末尾的空格。 char
一般用来存储很短并且固定长度的字符串,比如 md5
值。
varchar(n)
用于存储可变长的字符串,长度为n个字节的可变长度且非 Unicode
的字符数据。比如 varchar(10)
, 输入 abc
三个字符,那么实际存储大小为3个字节。除此之外, varchar
还需要使用1或2个额外字节记录字符串的长度,如果列的最大长度小于等于255字节(是定义的最长长度,不是实际长度),则使用1个字节表示长度,否则使用2个字节来表示。
综上,在存储很短的固定长度的字符串上应该采用效率更高的 char
,而存储可变长度的字符串应该采用存储空间上更有优势的 varchar
。
MyISAM
与 InnoDB
引擎的区别,怎样选用
InnoDB:
支持事务处理等
不加锁读取
支持外键
支持行锁
不支持FULLTEXT类型的索引
不保存表的具体行数,扫描表来计算有多少行
DELETE 表时,是一行一行的删除
InnoDB 把数据和索引存放在表空间里面
跨平台可直接拷贝使用
InnoDB中必须包含AUTO_INCREMENT类型字段的索引
表格很难被压缩
MyISAM:
不支持事务,回滚将造成不完全回滚,不具有原子性
不支持外键
不支持外键
支持全文搜索
保存表的具体行数,不带where时,直接返回保存的行数
DELETE 表时,先drop表,然后重建表
MyISAM 表被存放在三个文件 。frm 文件存放表格定义。 数据文件是MYD (MYData) 。 索引文件是MYI (MYIndex)引伸
跨平台很难直接拷贝
MyISAM中可以使AUTO_INCREMENT类型字段建立联合索引
表格可以被压缩
如何选择:
因为MyISAM相对简单所以在效率上要优于InnoDB.如果系统读多,写少。对原子性要求低。那么MyISAM最好的选择。且MyISAM恢复速度快。可直接用备份覆盖恢复。
如果系统读少,写多的时候,尤其是并发写入高的时候。InnoDB就是首选了。
MySQL扩展实现方式,分库分表策略
实现方式
业务拆分、主从复制,数据库分库与分表。
分库分表策略
id取模
首字符 a-z
分
hash路由
中间件(例如Cobar)
mysql的索引是什么数据结构,为什么使用这种数据结构。
B+tree结构。
myisam引擎使用b+tree作为索引结构,叶节点的data域存放的是数据记录的地址,myisam索引文件和数据文件是分离的。
而innodb的数据文件本身就是索引文件,表数据文件本身就是按b+tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
原因参考:
为什么mysql innodb索引是B+树数据结构
以下为常用算法
冒泡排序
function bubble_sort($array){
$count = count($array);
if ($count<=0) {
return false;
}
for ($i=0; $i <$count ; $i++) {
for ($j=0; $j <$count-$i-1 ; $j++) {
if ($array[$j]>$array[$j+1]) {
$tmp = $array[$j+1];
$array[$j+1]=$array[$j];
$array[$j]=$tmp;
}
}
}
return $array;
}
遍历文件夹内文件和子文件夹
function my_dir($dir) {
$files = array();
if(@$handle = opendir($dir)) { //加一个@,不然会有warning错误提示
while(($file = readdir($handle)) !== false) {
if($file != ".." && $file != ".") { //排除根目录;
if(is_dir($dir."/".$file)) { //如果是子文件夹,就进行递归
$files[$file] = my_dir($dir."/".$file);
} else { //不然就将文件的名字存入数组;
$files[] = $file;
}
}
}
closedir($handle);
return $files;
}
}
斐波那契数列
function fibonaci($n){
if($n <= 0){
return 0;
}else if($n == 1){
return 1;
}
$num1 = 0;
$num2 = 1;
$res = 0;
for($i = 2; $i <= $n; $i++){
$res = $num1 + $num2;
$num1 = $num2;
$num2 = $res;
}
return $res;
}
快速排序
方法一(递归):
/**
* @param $arr
* @return array
* 快速排序
*/
function quick_sort($arr) {
// 递归结束: 数组长度为1,直接返回
$length = count($arr);
if ($length <= 1) {
return $arr;
}
// 数组元素有多个,则定义两个空数组
$left = $right = array();
// 使用for循环进行遍历,默认第一个元素作为中枢点
for ($i = 1; $i < $length; $i++) {
// 判断当前元素的大小
if ($arr[$i] < $arr[0]) {
$left[] = $arr[$i];
} else {
$right[] = $arr[$i];
}
}
// 递归调用
$left = quick_sort($left);
$right = quick_sort($right);
// 将所有的结果合并
return array_merge($left, array($arr[0]), $right);// 中间切点
}
方法二(效率高):
/**
* @param $low
* @param $high
* @param $arr
* 快速排序 递归调用
* 关键点在于part动作
*/
function qsort($low, $high, &$arr){
if($low < $high){
$pivot = part($low, $high, $arr);
qsort($low, $pivot-1, $arr);
qsort($pivot+1, $high, $arr);
}
}
/**
* @param $low
* @param $high
* @param $arr
* @return mixed
* part的核心动作在于-- 中枢点的位置不断变换,比它小的换到它的左边,比它大的换到它的右边
*/
function part($low, $high, &$arr){
$pivot = $arr[$low];// 中枢点默认是列表第一个
while($low < $high){
while($low < $high && $arr[$high] >= $pivot){// 右边选比中枢点小的
$high--;
}
swap($arr, $low, $high);// 此时中枢点在低位置,而此时的高位置小于中枢点。两点交换
while($low < $high && $arr[$low] <= $pivot){// 左边选比中枢点大的
$low++;
}
swap($arr, $low, $high);// 此时中枢点在高位置,而此时的低位置大于中枢点。两点交换
}
return $low;// 低位此时是中枢点,返回中枢点位置
}
/**
* @param $arr
* @param $i
* @param $j
* 交换位置
*/
function swap(&$arr, $i, $j){
$temp = $arr[$i];
$arr[$i] = $arr[$j];
$arr[$j] = $temp;
}
计算N的质数
方法一(效率高):
/**
* 求n以内的质数(在大于1的自然数中,除了1和它本身意外,无法被其他自然数整除的数)
* @param int $n
* @return array
*/
function get_prime($n) {
$prime = array(2);//2为质数
for ($i = 3; $i <= $n; $i += 2) {//偶数不是质数,步长可以加大
$sqrt = intval(sqrt($i));//求根号n,只计算小于平方根的数,进一步缩小范围
for ($j = 3; $j <= $sqrt; $j += 2) {//i是奇数,当然不能被偶数整除,步长也可以加大。
if ($i % $j == 0) {
break;
}
}
if ($j > $sqrt) {
array_push($prime, $i);
}
}
return $prime;
}
方法二:
function get_prime_2($n) {
$prime = array(2);
for ($i=3; $i <= $n; $i++) {
$flag = 0;
for ($j=2; $j < $i; $j++) {
if($i % $j == 0){
$flag += 1;
break;
}
}
if(!$flag){
array_push($prime, $i);
}
}
return $prime;
}