PHP 面试题

2021/6/15 12:21:24

本文主要是介绍PHP 面试题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

明天就双十一了,准备好剁手了吗?我是没什么买的了,今天给大家推荐一些 PHP 面试题。

反转函数的实现

  1. /**

  2. * 反转数组

  3. * @param  array $arr

  4. * @return array

  5. */

  6. function reverse($arr)

  7. {

  8.    $n = count($arr);

  9.  

  10.    $left = 0;

  11.    $right = $n - 1;

  12.  

  13.    while ($left < $right) {

  14.        $temp = $arr[$left];

  15.        $arr[$left++] = $arr[$right];

  16.        $arr[$right--] = $temp;

  17.    }

  18.  

  19.    return $arr;

  20. }

  21. >>> reverse(range(1,10))

  22. => [

  23.     10,

  24.     9,

  25.     8,

  26.     7,

  27.     6,

  28.     5,

  29.     4,

  30.     3,

  31.     2,

  32.     1,

  33.   ]

两个有序int集合是否有相同元素的最优算法

  1. /**

  2. * 寻找两个有序数组里相同的元素

  3. * @param  array $arr1

  4. * @param  array $arr2

  5. * @return array      

  6. */

  7. function find_common($arr1, $arr2)

  8. {

  9.    $common = array();

  10.    $i = $j = 0;

  11.    $count1 = count($arr1);

  12.    $count2 = count($arr2);

  13.    while ($i < $count1 && $j < $count2) {

  14.        if ($arr1[$i] < $arr2[$j]) {

  15.            $i++;

  16.        } elseif ($arr1[$i] > $arr2[$j]) {

  17.            $j++;

  18.        } else {

  19.            $common[] = $arr1[$i];

  20.            $i++;

  21.            $j++;

  22.        }

  23.    }

  24.    return array_unique($common);

  25. }

  26. print_r(find_common(range(1,10),range(5,15)));

  27. Array

  28. (

  29.    [0] => 5

  30.    [1] => 6

  31.    [2] => 7

  32.    [3] => 8

  33.    [4] => 9

  34.    [5] => 10

  35. )

将一个数组中的元素随机

  1. /**

  2. * 打乱数组

  3. * @param  array $arr

  4. * @return array      

  5. */

  6. function custom_shuffle($arr)

  7. {

  8.    $n = count($arr);

  9.    for ($i = 0; $i < $n; $i++) {

  10.        $rand_pos = mt_rand(0, $n);

  11.        if ($rand_pos != $i) {

  12.            $temp = $arr[$i];

  13.            $arr[$i] = $arr[$rand_pos];

  14.            $arr[$rand_pos] = $temp;

  15.        }

  16.    }

  17.    return $arr;

  18. }

  19. >>> custom_shuffle(range(1,5))

  20. => [

  21.     5,

  22.     3,

  23.     1,

  24.     4,

  25.     2,

  26.   ]

给一个有数字和字母的字符串,让连着的数字和字母对应

  1. function number_alphabet($str)

  2. {

  3.    $number = preg_split('/[a-z]+/', $str, -1, PREG_SPLIT_NO_EMPTY);

  4.    $alphabet = preg_split('/\d+/', $str, -1, PREG_SPLIT_NO_EMPTY);

  5.    $n = count($number);

  6.    for ($i = 0; $i < $count; $i++) {

  7.        echo $number[$i] . ':' . $alphabet[$i] . '</br>';

  8.    }

  9. }

  10. $str = '1a3bb44a2ac';

  11. number_alphabet($str);//1:a 3:bb 44:a 2:ac

求n以内的质数

  1. /**

  2. * 求n内的质数

  3. * @param int $n

  4. * @return array

  5. */

  6. function get_prime($n)

  7. {

  8.    $prime = array(2);//2为质数

  9.  

  10.    for ($i = 3; $i <= $n; $i += 2) {//偶数不是质数,步长可以加大

  11.        $sqrt = intval(sqrt($i));//求根号n

  12.  

  13.        for ($j = 3; $j <= $sqrt; $j += 2) {//i是奇数,当然不能被偶数整除,步长也可以加大。

  14.            if ($i % $j == 0) {

  15.                break;

  16.            }

  17.        }

  18.  

  19.        if ($j > $sqrt) {

  20.            array_push($prime, $i);

  21.        }

  22.    }

  23.  

  24.    return $prime;

  25. }

  26.  

  27. >>> get_prime(10)

  28. => [

  29.     2,

  30.     3,

  31.     5,

  32.     7,

  33.   ]

约瑟夫环问题

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

  2. /**

  3. * 获取大王

  4. * @param  int $n

  5. * @param  int $m

  6. * @return int  

  7. */

  8. function get_king_mokey($n, $m)

  9. {

  10.    $arr = range(1, $n);

  11.  

  12.    $i = 0;

  13.  

  14.    while (count($arr) > 1) {

  15.        $i++;

  16.        $survice = array_shift($arr);

  17.  

  18.        if ($i % $m != 0) {

  19.            array_push($arr, $survice);

  20.        }

  21.    }

  22.  

  23.    return $arr[0];

  24. }

  25. var_dump(get_king_mokey(10,10));//8

  26. function getKingMokey($n, $m)

  27. {

  28.    $monkey[0] = 0;

  29.    //将1-n只猴子顺序编号 入数组中

  30.    for($i= 1; $i<= $n; $i++)

  31.    {

  32.        $monkey[$i] = $i;

  33.    }

  34.    $len = count($monkey);

  35.    //循环遍历数组元素(猴子编号)

  36.    for($i= 0; $i< $len; $i= $i)

  37.    {

  38.        $num = 0;

  39.        /*

  40.         * 遍历$monkey数组,计算数组中值不为0的元素个数(剩余猴子的个数)

  41.         * 赋值为$num,并获取值不为0的元素的元素值

  42.        */

  43.        foreach($monkey as $key => $value)

  44.        {

  45.           if($value == 0) continue;

  46.           $num++;

  47.           $values = $value;

  48.        }

  49.        //若只剩一只猴子 则输出该猴子编号(数组元素值) 并退出循环

  50.        if($num == 1)

  51.        {

  52.            return $values;

  53.            exit;

  54.        }

  55.        /*

  56.         * 若剩余猴子数大于1($num > 1)

  57.         * 继续程序

  58.        */

  59.        //将第$i只猴子踢出队伍(相应数组位置元素值设为0)

  60.        $monkey[$i] = 0;

  61.        /*

  62.         * 获取下一只需要踢出队伍的猴子编号

  63.         * 在$m值范围内遍历猴子 并设置$m的计数器

  64.         * 依次取下一猴子编号

  65.         * 若元素值为0,则该位置的猴子已被踢出队伍

  66.         * 若不为0,继续获取下一猴子编号,且计数器加1

  67.         * 若取得的猴子编号大于数组个数

  68.         * 则从第0只猴子开始遍历(数组指针归零) 步骤同上

  69.         * 直到计数器到达$m值 * 最后获取的$i值即为下一只需要踢出队伍的猴子编号

  70.         */

  71.        //设置计数器

  72.        for($j= 1; $j<= $m; $j++)

  73.        {

  74.            //猴子编号加一,遍历下一只猴子

  75.            $i++;

  76.            //若该猴子未被踢出队伍,获取下一只猴子编号

  77.            if($monkey[$i] > 0) continue;

  78.            //若元素值为0,则猴子已被踢出队伍,进而循环取下一只猴子编号

  79.            if($monkey[$i] == 0)

  80.            {

  81.                //取下一只猴子编号

  82.                for($k= $i; $k< $len; $k++)

  83.                {

  84.                    //值为0,编号加1

  85.                    if($monkey[$k] == 0) $i++;

  86.                    //否则,编号已取得,退出

  87.                    if($monkey[$k] > 0) break;

  88.                }

  89.             }

  90.            //若编号大于猴子个数,则从第0只猴子开始遍历(数组指针归零) 步骤同上

  91.            if($i == $len) $i = 0;

  92.            //同上步骤,获取下一只猴子编号

  93.            if($monkey[$i] == 0)

  94.            {

  95.                for($k= $i; $k< $len; $k++)

  96.                {

  97.                    if($monkey[$k] == 0) $i++;

  98.                    if($monkey[$k] > 0) break;

  99.                }

  100.            }

  101.        }

  102.    }

  103. }

  104. //猴子个数

  105. $n = 10;

  106. //踢出队伍的编号间隔值

  107. $m = 3;

  108. //调用猴王获取函数https://9iphp.com/web/php/1112.html

  109. echo getKingMokey($n, $m)."是猴王";

  110. function yuesefu($n,$m) {  

  111.    $r=0;  

  112.    for($i=2; $i<=$n; $i++) {

  113.        $r=($r+$m)%$i;  

  114.    }

  115.    return $r+1;  

  116. }  

  117. echo yuesefu(10,3)."是猴王";

快速寻找一个数组里最小的1000个数

  1. //输入n个整数,输出其中最小的k个。

  2. /**

  3. * 获取最小的k个数

  4. * @param  array $arr

  5. * @param  int $k   [description]

  6. * @return array

  7. */

  8. function get_min_array($arr, $k)

  9. {

  10.    $n = count($arr);

  11.  

  12.    $min_array = array();

  13.  

  14.    for ($i = 0; $i < $n; $i++) {

  15.        if ($i < $k) {

  16.            $min_array[$i] = $arr[$i];

  17.        } else {

  18.            if ($i == $k) {

  19.                $max_pos = get_max_pos($min_array);

  20.                $max = $min_array[$max_pos];

  21.            }

  22.  

  23.            if ($arr[$i] < $max) {

  24.                $min_array[$max_pos] = $arr[$i];

  25.  

  26.                $max_pos = get_max_pos($min_array);

  27.                $max = $min_array[$max_pos];

  28.            }

  29.        }

  30.    }

  31.  

  32.    return $min_array;

  33. }

  34.  

  35. /**

  36. * 获取最大的位置

  37. * @param  array $arr

  38. * @return array

  39. */

  40. function get_max_pos($arr)

  41. {

  42.    $pos = 0;

  43.    for ($i = 1; $i < count($arr); $i++) {

  44.        if ($arr[$i] > $arr[$pos]) {

  45.            $pos = $i;

  46.        }

  47.    }

  48.  

  49.    return $pos;

  50. }

  51.  

  52. $array = [1, 100, 20, 22, 33, 44, 55, 66, 23, 79, 18, 20, 11, 9, 129, 399, 145, 2469, 58];

  53.  

  54. $min_array = get_min_array($array, 10);

  55.  

  56. print_r($min_array);

  57. Array

  58. (

  59.    [0] => 1

  60.    [1] => 18

  61.    [2] => 20

  62.    [3] => 22

  63.    [4] => 33

  64.    [5] => 44

  65.    [6] => 9

  66.    [7] => 11

  67.    [8] => 23

  68.    [9] => 20

  69. )

在有序的数组中找到一个数的位置

  1. /**

  2. * 二分查找

  3. * @param  array $array 数组

  4. * @param  int $n 数组数量

  5. * @param  int $value 要寻找的值

  6. * @return int

  7. */

  8. function binary_search($array, $n, $value)

  9. {

  10.    $left = 0;

  11.    $right = $n - 1;

  12.  

  13.    while ($left <= $right) {

  14.        $mid = intval(($left + $right) / 2);

  15.        if ($value > $mid) {

  16.            $right = $mid + 1;

  17.        } elseif ($value < $mid) {

  18.            $left = $mid - 1;

  19.        } else {

  20.            return $mid;

  21.        }

  22.    }

  23.  

  24.    return -1;

  25. }

  26. >>> binary_search(range(1,5),5,2)

  27. => 2

一个有序整数序列,找出绝对值最小的元素

  1. /**

  2. * 获取绝对值最小的元素

  3. * @param  array $arr

  4. * @return int  

  5. */

  6. function get_min_abs_value($arr)

  7. {

  8.    //如果符号相同,直接返回

  9.    if (is_same_sign($arr[0], $arr[$n - 1])) {

  10.        return $arr[0] >= 0 ? $arr[0] : $arr[$n - 1];

  11.    }

  12.  

  13.    //二分查找

  14.    $n = count($arr);

  15.    $left = 0;

  16.    $right = $n - 1;

  17.  

  18.    while ($left <= $right) {

  19.        if ($left + 1 === $right) {

  20.            return abs($arr[$left]) < abs($arr[$right]) ? $arr[$left] : $arr[$right];

  21.        }

  22.  

  23.        $mid = intval(($left + $right) / 2);

  24.  

  25.        if ($arr[$mid] < 0) {

  26.            $left = $mid + 1;

  27.        } else {

  28.            $right = $mid - 1;

  29.        }

  30.    }

  31. }

  32.  

  33. /**

  34. * 判断符号是否相同

  35. * @param  int  $a

  36. * @param  int  $b

  37. * @return boolean  

  38. */

  39. function is_same_sign($a, $b)

  40. {

  41.    if ($a * $b > 0) {

  42.        return true;

  43.    } else {

  44.        return false;

  45.    }

  46. }

找出有序数组中随机3个数和为0的所有情况

  1. function three_sum($arr)

  2. {

  3.    $n = count($arr);

  4.  

  5.    $return = array();

  6.  

  7.    for ($i=0; $i < $n; $i++) {

  8.        $left = $i + 1;

  9.        $right = $n - 1;

  10.  

  11.        while ($left <= $right) {

  12.            $sum = $arr[$i] + $arr[$left] + $arr[$right];

  13.  

  14.            if ($sum < 0) {

  15.                $left++;

  16.            } elseif ($sum > 0) {

  17.                $right--;

  18.            } else {

  19.                $numbers = $arr[$i] . ',' . $arr[$left] . ',' . $arr[$right];

  20.                if (!in_array($numbers, $return)) {

  21.                    $return[] = $numbers;

  22.                }

  23.  

  24.                $left++;

  25.                $right--;

  26.            }

  27.        }

  28.    }

  29.  

  30.    return $return;

  31. }

  32.  

  33. $arr = [-10, -9, -8, -4, -2, 0, 1, 2, 3, 4, 5, 6, 9];

  34. var_dump(three_sum($arr));

  35. >>> three_sum($arr)

  36. => [

  37.     "-10,1,9",

  38.     "-10,4,6",

  39.     "-10,5,5",

  40.     "-9,0,9",

  41.     "-9,3,6",

  42.     "-9,4,5",

  43.     "-8,2,6",

  44.     "-8,3,5",

  45.     "-8,4,4",

  46.     "-4,-2,6",

  47.     "-4,0,4",

  48.     "-4,1,3",

  49.     "-4,2,2",

  50.     "-2,0,2",

  51.     "-2,1,1",

  52.   ]

任意n个正负整数里面最大的连续和

  1. /**

  2. * 获取最大的连续和

  3. * @param  array $arr

  4. * @return int

  5. */

  6. function max_sum_array($arr)

  7. {

  8.    $currSum = 0;

  9.    $maxSum = 0;//数组元素全为负的情况,返回最大数

  10.  

  11.    $n = count($arr);

  12.  

  13.    for ($i = 0; $i < $n; $i++) {

  14.        if ($currSum >= 0) {

  15.            $currSum += $arr[$i];

  16.        } else {

  17.            $currSum = $arr[$i];

  18.        }

  19.    }

  20.  

  21.    if ($currSum > $maxSum) {

  22.        $maxSum = $currSum;

  23.    }

  24.  

  25.    return $maxSum;

  26. }

  27. >>> max_sum_array([1,6,2,3,8])

  28. => 20

HTTP中GET与POST的区别

  1. GET在浏览器回退时是无害的,而POST会再次提交请求。

  2. GET产生的URL地址可以被Bookmark,而POST不可以。

  3. GET请求会被浏览器主动cache,而POST不会,除非手动设置。

  4. GET请求只能进行url编码,而POST支持多种编码方式。

  5. GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

  6. GET请求在URL中传送的参数是有长度限制的,而POST没有。

  7. 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

  8. GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

  9. GET参数通过URL传递,POST放在Request body中。

  10. GET产生一个TCP数据包,POST产生两个TCP数据包。

COOKIE和SESSION的区别和关系

  1. COOKIE保存在客户端,而SESSION则保存在服务器端

  2. 从安全性来讲,SESSION的安全性更高

  3. 从保存内容的类型的角度来讲,COOKIE只保存字符串(及能够自动转换成字符串)

  4. 从保存内容的大小来看,COOKIE保存的内容是有限的,比较小,而SESSION基本上没有这个限制

  5. 从性能的角度来讲,用SESSION的话,对服务器的压力会更大一些

  6. SEEION依赖于COOKIE,但如果禁用COOKIE,也可以通过url传递

统计某一天网站的访问量

  1. awk '{print $1}' /var/log/access.log | sort | uniq | wc -l

fastcgi通过端口监听和通过文件监听的区别

  1. 监听方式    形式  nginx链接fastcgi方式

  2. 端口监听    fastcgi_pass 127.0.0.1:9000 TCP链接

  3. 文件监听    fastcgi_pass /tmp/php_cgi.sock  Unix domain Socket

Memcache与Redis的区别

  1. Memcache

  2. 该产品本身特别是数据在内存里边的存储,如果服务器突然断电,则全部数据就会丢失

  3. 单个key(变量)存放的数据有1M的限制

  4. 存储数据的类型都是String字符串类型

  5. 本身没有持久化功能

  6. 可以使用多核(多线程)

  7. Redis

  8. 数据类型比较丰富:String、List、Set、Sortedset、Hash

  9. 有持久化功能,可以把数据随时存储在磁盘上

  10. 本身有一定的计算功能

  11. 单个key(变量)存放的数据有1GB的限制

  12. redis 内存不够,使用 bitset

多进程同时写一个文件的问题

  1. function write($str)

  2. {

  3.    $fp = fopen($file, 'a');

  4.    do {

  5.        usleep(100);

  6.    } while (!flock($fp, LOCK_EX));

  7.    fwrite($fp, $str . PHP_EOL);

  8.    flock($fp, LOCK_UN);

  9.    fclose($fp);

  10. }

php7新特性

  1. ?? 运算符(NULL 合并运算符)

  2. 函数返回值类型声明

  3. 标量类型声明

  4. use 批量声明

  5. define 可以定义常量数组

  6. 闭包( Closure)增加了一个 call 方法

验证ip

  1. function check_ip($ip)

  2. {

  3.    if (!filter_var($ip, FILTER_VALIDATE_IP)) {

  4.    return false;

  5.    } else {

  6.        return true;

  7.    }

  8. }

验证日期是否合理

  1. function check_datetime($datetime)

  2. {

  3.    if (date('Y-m-d H:i:s', strtotime($datetime)) === $datetime) {

  4.        return true;

  5.    } else {

  6.        return false;

  7.    }

  8. }

设计一个秒杀系统

  1. $ttl = 4;

  2. $random = mt_rand(1,1000).'-'.gettimeofday(true).'-'.mt_rand(1,1000);

  3.  

  4. $lock = fasle;

  5. while (!$lock) {

  6.    $lock = $redis->set('lock', $random, array('nx', 'ex' => $ttl));

  7. }

  8.  

  9. if ($redis->get('goods.num') <= 0) {

  10.    echo ("秒杀已经结束");

  11.    //删除锁

  12.    if ($redis->get('lock') == $random) {

  13.        $redis->del('lock');

  14.    }

  15.    return false;

  16. }

  17.  

  18. $redis->decr('goods.num');

  19. echo ("秒杀成功");

  20. //删除锁

  21. if ($redis->get('lock') == $random) {

  22.    $redis->del('lock');

  23. }

  24. return true;

给某个ip找到对应的省和市

  1. //ip2long,把所有城市的最小和最大Ip录进去

  2. $redis_key = 'ip';

  3. $redis->zAdd($redis_key, 20, '#bj');//北京的最小IP加#

  4. $resid->zAdd($redis_key, 30, 'bj');//最大IP

  5.  

  6. function get_ip_city($ip_address)

  7. {

  8.    $ip = ip2long($ip_address);

  9.  

  10.    $redis_key = 'ip';

  11.    $city = zRangeByScore($redis_key, $ip, '+inf', array('limit' => array(0, 1)));

  12.    if ($city) {

  13.        if (strpos($city[0], "#") === 0) {

  14.            echo '城市不存在!';

  15.        } else {

  16.            echo '城市是' . $city[0];

  17.        }

  18.    } else {

  19.        echo '城市不存在!';

  20.    }

  21. }

网页/应用访问慢突然变慢,如何定位问题

  1. top、iostat查看cpu、内存及io占用情况

  2. 内核、程序参数设置不合理 查看有没有报内核错误,连接数用户打开文件数这些有没有达到上限等等

  3. 链路本身慢 是否跨运营商、用户上下行带宽不够、dns解析慢、服务器内网广播风暴什么的

  4. 程序设计不合理 是否程序本身算法设计太差,数据库语句太过复杂或者刚上线了什么功能引起的

  5. 其它关联的程序引起的 如果要访问数据库,检查一下是否数据库访问慢

  6. 是否被***了 查看服务器是否被DDos了等等

  7. 硬件故障 这个一般直接服务器就挂了,而不是访问慢

分析apache日志获取最多访问的前10个IP

  1. awk '{a[$1] += 1;} END {for (i in a) printf("%d %s\n", a[i], i);}' 日志文件 | sort -n | tail

  2. 首先用awk统计出来一个列表,然后用sort进行排序,最后用tail取最后的10个。

  3. 以上参数可以略作修改显示更多的数据,比如将tail加上-n参数等,另外日志格式不同命令也可能需要稍作修改。

  4. 当前WEB服务器中联接次数最多的ip地址

  5. #netstat -ntu |awk '{print $5}' |sort | uniq -c| sort -nr

  6.  

  7. 查看日志中访问次数最多的前10个IP

  8. #cat access_log |cut -d ' ' -f 1 | sort |uniq -c | sort -nr | awk '{print $0 }' | head -n 10 | less

  9.  

  10. 查看日志中出现100次以上的IP

  11. #cat access_log |cut -d ' ' -f 1 | sort |uniq -c | awk '{if ($1 > 100) print $0}'|sort -nr | less

  12.  

  13. 查看最近访问量最高的文件

  14. #cat access_log | tail -10000 | awk '{print $7}' | sort | uniq -c | sort -nr | less

  15.  

  16. 查看日志中访问超过100次的页面

  17. #cat access_log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less

  18.  

  19. 统计某url,一天的访问次数

  20. #cat access_log | grep '12/Aug/2009' | grep '/images/index/e1.gif' | wc | awk '{print $1}'

  21.  

  22. 前五天的访问次数最多的网页

  23. #cat access_log | awk '{print $7}' | uniq -c | sort -n -r | head -20

  24.  

  25. 从日志里查看该ip在干嘛

  26. #cat access_log | grep 218.66.36.119 | awk '{print $1"\t"$7}' | sort | uniq -c | sort -nr | less

  27.  

  28. 列出传输时间超过 30 秒的文件

  29. #cat access_log | awk '($NF > 30){print $7}' | sort -n | uniq -c | sort -nr | head -20

  30.  

  31. 列出最最耗时的页面(超过60秒的)

  32. #cat access_log | awk '($NF > 60 && $7~/\.php/){print $7}' | sort -n | uniq -c | sort -nr | head -100

  33.  

感谢 

PHP技术大全https://zhuanlan.zhihu.com/phpgod 

3年PHPer的面试总结http://coffeephp.com/articles/4 

面试过阿里等互联网大公司,我知道了这些套路https://juejin.im/post/59bd64c4f265da066d33333d 

前端面试题https://github.com/calabash519/interview-questions 

Laravel、PHPer 面试可能会遇到的问题https://github.com/todayqq/caseInterviewQuestions https://github.com/justcodingnobb/fuck-php-interview https://zhuanlan.zhihu.com/p/2593665

https://www.v2ex.com/t/375266

 



这篇关于PHP 面试题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程