一些常见的PHP面试题

这都是我面试的血泪史啊:(

一、 数组及传值方式的考察

1
2
3
4
5
6
7
8
9
10
<?php
$arr = ['a','b','c'];
foreach ($arr as &$v) {
# code...
}

foreach ($arr as $v) {
# code...
}
print_r($arr);

结果是$arr = [‘a’,’b’,’b’],你答对了吗?

反正我是想了一个礼拜才弄明白:)

解析:这道题首先要注意第一次循环中的”&”符号,考察的是PHP中的引用赋值和拷贝赋值。

最后出现“令人意外”的结果的原因就在于,第一次循环是每次把$arr元素的地址给了$v,而$v的地址在循环结束后有没被释放掉,所以第一次循环结束后$v存的是$arr[2]的地址,第二次循环是把$arr的值分别给了$v,由于此时的$v指向的是$arr[2],所以每次指针的移动都是把当前的元素放入$arr[2]中,所以

  • 第一次循环$arr = [‘a’,’b’,’a’];
  • 第二次循环$arr = [‘a’,’b’,’b’];
  • 第三次循环$arr = [‘a’,’b’,’b’];

第三次循环的结果就是把自己的$arr[2]的内容取出来赋给$arr[2],所以结果是$arr = [‘a’,’b’,’b’];

因此我们在使用”&”符号时,最好将其unset掉,否则会导致意外行为

最后上一个图说明一下:
foreach问题

参考资料:https://segmentfault.com/q/1010000008279730


二、 数组的考察

1
2
3
4
5
6
7
8
<?php
$a = 9;
$t = [1];
foreach($t as $v)
{
$v += $a;
}
var_dump($t);

结果是1而不是10


三、 SQL的考察

现有一个学生成绩表student,内容如下:

学生成绩表

请据表查询,

  1. 用一个select查出两门及以上的不及格者的平均成绩
  2. 统计学生不及格科目的个数
  3. 获取每个学生的最佳科目及成绩
  4. 获取不及格学生的名字及科目

答:

  1. select name, sum(score<60) as num, avg(score) as avg_score from student group by name having num > 1;

    两门及以上不及格的平均分

  2. select name, sum(score < 60) as no_pass from student group by name;

    不及格科目数

  3. select name, subject, score from student where score in (select max(score) as score from student group by name);

    最佳科目及成绩

  4. select name, group_concat(subject) as subject from (select name, subject from student where score < 60) as info group by name;//此处需要注意的是,子查询语句结果需要给一个alias,否则会报错

    不及格科目列表

因为热爱,所以执着。