PHP Interview Questions(11)

面试时间:2019 年 11 月 4 日,星期一,下午两点。


1. 给定一个二维数组,数组每一行从左到右都是递增的,每一列也是递增的。请完成一个函数,输入为如上二维数组和一个整数,函数功能为判断该整数是否存在于数组中。时间复杂度尽可能的低。(请说明你的算法的复杂度。)

下面是一个例子:

二维数组:

1 2 8 9

2 4 9 12

4 7 10 13

6 8 11 15

数字:9

<?php

$array = [
    [1, 2, 8, 9],
    [2, 4, 9, 12],
    [4, 7, 10, 13],
    [6, 8, 11, 15],
];

$number = 9;

/**
 * 最简单的方法就是遍历整个数组
 * 时间复杂度 O(Row*Column-1)
 */
function findNumberInArray($array, $number) {
    foreach ($array as $rowArray) {
        foreach ($rowArray as $value) {
            echo $value, " ";
            if ($number == $value) {
                return true;
            }
        }
    }

    return false;
}

/**
 * 从二维数组的左下角开始逐行查找
 * 时间复杂度 O(Row+Column-1)
 */
function findNumberInArray2($array, $number) {
    $minRow = 0;
    $minColumn = 0;
    $maxRow = count($array) - 1;
    $maxColumn = count($array[0]) - 1;

    if ($number < $array[0][0] || $number > $array[$maxRow][$maxColumn]) {
        return false;
    }

    for ($row = $maxRow; $row >= $minRow; $row--) {
        for ($column = $minColumn; $column <= $maxColumn; $column++) {
            echo $array[$row][$column], " ";
            if ($array[$row][$column] == $number) {
                return true;
            }
            if ($array[$row][$column] > $number) {
                break;
            }
            if ($array[$row][$column] < $number) {
                $minColumn = $column + 1;
            }
        }
    }

    return false;
}

/**
 * 从二维数组的右上角开始逐行查找
 * 时间复杂度 O(Row+Column-1)
 */
function findNumberInArray3($array, $number) {
    $minRow = 0;
    $minColumn = 0;
    $maxRow = count($array) - 1;
    $maxColumn = count($array[0]) - 1;

    if ($number < $array[0][0] || $number > $array[$maxRow][$maxColumn]) {
        return false;
    }
    
    for ($row = $minRow; $row <= $maxRow; $row++) {
        for ($column = $maxColumn; $column >= $minColumn; $column--) {
            echo $array[$row][$column], " ";
            if ($array[$row][$column] == $number) {
                return true;
            }
            if ($array[$row][$column] > $number) {
                $maxColumn = $column - 1;
            }
            if ($array[$row][$column] < $number) {
                break;
            }
        }
    }

    return false;
}

echo "/**
* 最简单的方法就是遍历整个数组
* 时间复杂度 O(Row*Column-1)
*/\n";
for ($number = 0; $number <= 15; $number++) {
    echo "find ", $number, ": ";
    findNumberInArray($array, $number);
    echo "\n";
}

echo "/**
* 从二维数组的左下角开始逐行查找
* 时间复杂度 O(Row+Column-1)
*/\n";
for ($number = 0; $number <= 15; $number++) {
    echo "find ", $number, ": ";
    findNumberInArray2($array, $number);
    echo "\n";
}

echo "/**
* 从二维数组的右上角开始逐行查找
* 时间复杂度 O(Row+Column-1)
*/\n";
for ($number = 0; $number <= 15; $number++) {
    echo "find ", $number, ": ";
    findNumberInArray3($array, $number);
    echo "\n";
}

2.把数组最开始的若干个元素搬到数组末尾,称为数组的旋转。给定一个递增数组的旋转数组,请完成一个函数,时间复杂度尽可能的低,输出该旋转数组的最小元素。并给出复杂度。

例如输入数组(4,5,6,7,8,10,1,2,3),输出 1。

<?php

$array = [4, 5, 6, 7, 8, 10, 1, 2, 3];

/**
 * 使用 min() 函数
 * 时间复杂度:O(N)
 * 源码:https://github.com/php/php-src/blob/master/ext/standard/array.c
 */
echo min($array), "\n";

/**
 * 使用二分查找法
 * 时间复杂度:O(log2N)
 */
function findMinimumNumberInArray($array, $start = 0, $end = null) {
    if ($end == null) {
        $end = count($array) - 1;
    }

    if ($start == $end) {
        return $array[$start];
    }

    $middle = floor(($start + $end) / 2);

    if ($array[$start] < $array[$end]) {
        return findMinimumNumberInArray($array, $start, $middle);
    } else {
        return findMinimumNumberInArray($array, $middle, $end);
    }
}

echo findMinimumNumberInArray($array), "\n";

3.输入一个字符串,输出该字符串中字符的所有组合。(不限编程语言,请注明你选择的语言)

下面是一个例子:

输入参数:字符串:“abc”

输出:“a”, “b”, “c”, “ab”, “ac”, “bc”, “abc”

<?php

$string = "abc";
$length = strlen($string);

/**
 * 使用二进制表示不同的排列组合
 * 
 * 0 0 1 a
 * 0 1 0 b
 * 0 1 1 ab
 * 1 0 0 c
 * 1 0 1 ac
 * 1 1 0 bc
 * 1 1 1 abc
 */
 for ($i = 1; $i < 1 << $length; $i++) {
     for ($j = 0; $j < $length; $j++) {
         if ($i & (1 << $j)) {
             echo $string[$j];
         }
     }
     echo "\n";
 }

参考:

剑指Offer面试题:2.二维数组中的查找

剑指Offer面试题:7.旋转数组的最小数字

剑指Offer面试题:26.字符串的排列

127 total views, 7 views today

PHP Interview Questions(10)

面试时间:2019 年 3 月 22 日,星期五,下午四点。


什么是命名空间?

https://www.php.net/manual/zh/language.namespaces.rationale.php

Redis 常见数据结构的使用场景。

https://my.oschina.net/manmao/blog/688230

如何基于 Redis 设计一个秒杀系统。

把商品库存放入 Redis 队列。

了解过 JWT 吗?

https://jwt.io/

了解过 Protocol Buffers 吗?

https://developers.google.com/protocol-buffers/

在实际项目中使用过 Swoole 吗?

https://www.swoole.com/

Go 语言中的 slice 和 map 是线程安全的吗?

https://halfrost.com/go_map_chapter_one/
https://halfrost.com/go_map_chapter_two/

遇到过 TCP 粘包问题吗?如何解决。

https://crossoverjie.top/2018/08/03/netty/Netty(3)TCP-Sticky/

214 total views, no views today

PHP Interview Questions(9)

面试时间:2019 年 3 月 22 日,星期五,下午四点。


审批流程数据库设计

https://www.cnblogs.com/yyy116008/p/8330076.html

MySQL 索引数据结构

Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT) are stored in B-trees. Exceptions: Indexes on spatial data types use R-trees; MEMORY tables also support hash indexes; InnoDB uses inverted lists for FULLTEXT indexes.

 b-tree 和 b+tree 的区别

B-Tree
B+Tree

非聚集索引和聚集索引的区别

MySQL MyISAM Primary Key(非聚集索引)
MySQL MyISAM Secondary Key(非聚集索引)
MySQL InnoDB Primary Key(聚集索引)
MySQL InnoDB Secondray Key(聚集索引)

参考:

https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html

http://blog.codinglabs.org/articles/theory-of-mysql-index.html

223 total views, 2 views today

PHP Interview Questions(8)

面试时间:2018 年 9 月 21 日,星期五,下午三点。


单例模式

final class Singleton
{
    /**
     * @var Singleton
     */
    private static $instance;
    /**
     * gets the instance via lazy initialization (created on first usage)
     */
    public static function getInstance(): Singleton
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }
        return static::$instance;
    }
    /**
     * is not allowed to call from outside to prevent from creating multiple instances,
     * to use the singleton, you have to obtain the instance from Singleton::getInstance() instead
     */
    private function __construct()
    {
    }
    /**
     * prevent the instance from being cloned (which would create a second instance of it)
     */
    private function __clone()
    {
    }
    /**
     * prevent from being unserialized (which would create a second instance of it)
     */
    private function __wakeup()
    {
    }
}

https://github.com/domnikl/DesignPatternsPHP/blob/master/Creational/Singleton/Singleton.php

https://phptherightway.com/pages/Design-Patterns.html

https://stackoverflow.com/questions/203336/creating-the-singleton-design-pattern-in-php5

MySQL 分区表

https://www.jianshu.com/p/89311703b320

258 total views, 1 views today

PHP Interview Questions(7)

面试时间:2018 年 9 月 14 日,星期五,下午六点。


MySQL 主从备份的作用是什么?

防止一台宕机。

PHP-FPM 的运行原理是什么?

master/worker架构。

MySQL 使用 delete 语句删除数据,空间没有释放怎么解决?

optmize table {name}

怎么设计 1000W 用户量的用户签到系统?

分库分表
中间件

240 total views, 1 views today

PHP Interview Questions(6)

面试时间:2018 年 9 月 13 日,星期五,下午 13 : 00。


存在两个时间,如何计算两个日期的天数差。

<?php
$dateStart = '2017-05-03 12:34:56';
$dateEnd = '2020-12-12 09:17:18';
// 计算两个时间天数差
return intval((strtotime($dateEnd) - strtotime($dateStart)) / (24 * 60 * 60));

PHP 中传值和引用的区别是什么?叙述下其应用场景和优劣。

http://php.net/manual/zh/language.references.php

请写一个正则表达式,用来验证手机号码的正确性。

\d{11}

请列举出常用的PHP魔术方法,并说明其应用场景。

http://php.net/manual/zh/language.oop5.magic.php

请写出 echo,print,printf,sprintf,print_r,var_dump 的差异。

http://php.net/manual/en/ref.strings.php

请无乱码的切割中文字符(实例字符:“布克大学,就要不凡”,截取“布克大学”)。

mb_substr("布克大学,就要不凡", 0, 4)
substr("布克大学,就要不凡", 0, 12)

PHP 中异常处理时(try catch finally),return 应该写在哪里?

都可以。

有如下三张表,请写出查询每个学生平均分数的 SQL 语句。

>>> 学生表/students:
id
name # 学生姓名

>>> 成绩表/scores:
id
student_id # 学生id@students.id
subject_id # 科目id@subjects.id
score # 分数

>>> 科目表/subjects:
id
name # 科目名称

结果要求输出 学生姓名 科目名称 平均分数

select students.name as student_name, subjects.name as subject_name, sum(scores.score)/count(students.id) as avg_score
from scores
join students on (students.id = scores.student_id)
join subjects on (subjects.id = scores.subject_id)
group by students.id

PHP 中创建多进程、多线程的方式有哪些,使用多线程、多进程有哪些优缺点。

多进程:
http://php.net/manual/zh/book.pcntl.php
多线程:
http://php.net/manual/en/book.pthreads.php

描述下 IoC 和 DI 的实现原理。

https://phptherightway.com/#dependency_injection

OAuth2 的工作原理是怎么样的?

https://laravel.com/docs/master/passport

(口述作答)根据你的经验,如何规划一个大流量、高并发的WEB站点。

http://network.51cto.com/art/201809/583103.htm

聊聊  MySQL 主从同步。

https://www.digitalocean.com/community/tutorials/how-to-set-up-master-slave-replication-in-mysql

聊聊 RESTful API 设计。

https://www.toptal.com/laravel/restful-laravel-api-tutorial

如果团队有一个消极的人怎么处理。如果团队成员玩手机被老板发现了怎么处理。能否带领一个 3 到 5 人的团队完成开发任务。

不处理。

252 total views, no views today

PHP Interview Questions(5)

面试时间:2018 年 9 月 12 日,星期三,下午两点。


PHP 怎么实现多继承?

trait

Git 怎么撤销上次提交?

git commit --amend

ls -l 命令的前十位代表什么?

drwxrwxrwx

解释什么是 XSS,CSRF,SQL 注入以及如何防范

http://www.cnblogs.com/leecong/p/5898370.html

高并发下如何锁库存,防止超卖?/ 支付回调如何防止重复写入。

乐观锁

Nginx location 匹配规则。

http://nginx.org/en/docs/http/ngx_http_core_module.html#location

Nginx 为什么比 Apache 快?

Nginx 采用 epoll 模型,异步非阻塞。
Apache 采用 select 模型,同步阻塞。

TCP 和 UDP 的区别都有哪些?

https://www.diffen.com/difference/TCP_vs_UDP

235 total views, no views today

PHP Interview Questions (4)

面试时间:2018 年 9 月 10 日,周一,上午十点。


1. 求一个矩阵中最大的二维矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
要求: (1)写出代码; (2)分析时间复杂度

$matrix = [
[1, 2, 0, 3, 4],
[2, 3, 4, 5, 1],
[1, 1, 5, 3, 0]
];
$row = 3;
$col = 5;
$maxMatrix = [];
$maxSum = 0;

for ($i = 0; $i < $row - 1; $i++) {
    for ($j = 0; $j < $col - 1; $j++) {
        $sum = $matrix[$i][$j] + $matrix[$i][$j + 1] + $matrix[$i + 1][$j] + $matrix[$i + 1][$j + 1];
        if ($sum > $maxSum) {
            $maxSum = $sum;
            $maxMatrix = [
                [$matrix[$i][$j], $matrix[$i][$j + 1]],
                [$matrix[$i + 1][$j], $matrix[$i + 1][$j + 1]]
            ];
        }
    }
}

O(row*col)

2. 输入 n 个整数,输出其中最大的 k 个。例如输入 1,2,3,4,5,6,7,8 这 8 个数字,则其中最大的 3 个数字为 8,7,6。

$n = 8;
$k = 3;
$arr = [1, 2, 3, 4, 5, 6, 7, 8];

O(N*log2N)
rsort($arr);
for ($i = 0; $i < $k; $i++) {
    echo $arr[$i], "\n";
}

O(N*K)
$maxKeys = [];
for ($i = 0; $i < $k; $i++) {
    $max = 0;
    foreach ($arr as $key => $value) {
        if (!in_array($key, $maxKeys) && $value > $max) {
            $max = $value;
            $maxKey = $key;
        }
    }
    echo $max, "\n";
    $maxKeys[] = $maxKey;
}

3. 输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。

<?php
$str = 'abc';
$arr = str_split($str);
$len = strlen($str);

function exchange(&$a, &$b) {
    $temp = $a;
    $a = $b;
    $b = $temp;
}

function permutation($arr, $i, $len) {
    if ($i == $len) {
        return;
    }
    if ($i == $len - 1) {
        echo join('', $arr), "\n";
    }
    for ($j = $i; $j < $len; $j++) {
        exchange($arr[$i], $arr[$j]);
        permutation($arr, $i + 1, $len);
    }
}

permutation($arr, 0, $len);

248 total views, 1 views today

PHP Interview Questions (3)

面试时间:2018 年 9 月 7 日,周五,下午两点。


PHP

1. 数组 $arr = [1,  2,  3,…],如何在数组里追加一个元素x,请给出至少两种代码

array_push($arr, x);

$arr[count($arr)] = x;

2. 下面的代码,输出是 true 还是 false?

is_null(0)
is_null([])
empty(false)
empty(0)
false == []
null == []
false false true true true true

3. 现有一个字符串,$str = “欢迎来到享换机,You are welcome!”,请给出代码,截取前 7 个文字

echo mb_substr($str, 0, 7);

echo substr($str, 0, 21);

4. 请写一个正则表达式验证电子邮件的格式是否正确

^[A-Za-z0-9_\-\.]+@[A-Za-z0-9_\-\.]+\.[A-Za-z]{2,4}$

5. 给出下面代码的结果

$a = 1;
$b = $a;
$c = &$a;
$d = $c;
$e = &$c;
$e = 2;
echo $a, "\n", $b, "\n", $c, "\n", $d, "\n", $e, "\n";
2
1
2
1
2

6. 请简述Session原理,以及使用Session时的注意事项

https://www.jianshu.com/p/2b7c10291aad

7. 已有数组$arr = [1, 2, 3…] 以及变量 $a,使用 array_map 函数,生成新的数组,其每个元素在 $arr 每个元素的基础上加 $a。请给出代码

return array_map(function($v) use ($a) {
    return $v + $a;
}, $arr);

8. 请给出代码,输出当月最后一天的当前时间,格式:年-月-日 时:分:秒。eg:

当前时间:2018-05-10 22:05:35

输出时间:2018-05-31 22:05:35

echo date('Y-m-d H:i:s', strtotime("last day of this month"));

9. PHP 怎么避免 XSS 攻击?怎么避免 SQL 注入?

https://www.cnblogs.com/ITtangtang/p/3982297.html

10. 请给出下面代码在php7下的结果。如有错误,请指出

declare(strict_types=0);
static $c = 1;
$d = 3;
$res1 = test(1.5, 2);
echo $res1, "\n";
$res2 = test(1.5, 2);
echo $res1, "\n";

function test (int $a, int $b) : int {
    static $d = 4;
    $res = $a + $b;
    if (isset($c)) {
        $res += $c;
    }
    if (isset($d)) {
        $res += $d;
        $d += 1.5;
    }
    return $res;
}
7
7

数据结构 & 算法

1. n 只猴子,围成 1 圈坐,依次按 1、2、3、…、m循环报数,报到 m 的淘汰。请写出代码,求最后剩下的猴子。

function monkey($n, $m) {
    $out = [];
    $pointer = 0;

    for ($i = 1; $i <= $n - 1; $i++) {
        echo "round ", $i, ": ";
        $count = 0;
        while ($count < $m) {
            $pointer = $pointer % $n + 1;

            if (!in_array($pointer, $out)) {
                $count++;
                if ($count == $m) {
                    echo $pointer, "(out)\n";
                } else {
                    echo $pointer, ", ";
                }
            }
        }
        $out[] = $pointer;
    }

    for ($i = 1; $i <= $n; $i++) {
        if (!in_array($i, $out)) {
            return $i;
        }
    }
}

2. 请写出代码,构造单向链表。

class ListNode {
    public $val;
    public $next;

    public function __construct($val) {
        $this->val = $val;
        $this->next = null;
    }
}

$array = [1, 2, 3, 4, 5];

foreach ($array as $key => $val) {
    if ($key == 0) {
        $head = $node = new ListNode($val);
    } else {
        $node->next = new ListNode($val);
        $node = $node->next;
    }
}

return $list;

3. 有两个数组 [1, 4, 7, 8, 9], [2, 3, 7, 8, 10],请写出代码,将两个数组合并成一个升序的数组。

$arr1 = [1, 4, 7, 8, 9];
$arr2 = [2, 3, 7, 8, 10];
$arr = array_merge($arr1, $arr2);
sort($arr);

MySQL

1. 取表 A 里面 status 字段为 1 的 1000 到 1010 行数据,请写出 sql

select * from A where status = 1 limit 10, 1000

2. 请简述 left join, inner join, right join 的区别

https://stackoverflow.com/questions/448023/what-is-the-difference-between-left-right-outer-and-inner-joins

3. 表 A 有一个联合索引 idx(a, b, c)。下面的情况,是否可以使用到索引

select * from A where b = 2;
select * from A where a = 2;
select * from A where a > 2;
select * from A where c = 1;
select * from A where a = 1 and c = 2;
select * from A where a in (1, 2, 3) and c = 2;
No Yes Yes No Yes Yes

逻辑

1. 1 块钱可以买 2 瓶汽水,2 个瓶盖可以换 1 瓶汽水。问十块钱最多可以喝到多少瓶汽水?

40

2. 1000 个瓶子中有一瓶毒药,一只老鼠吃到毒药后一周才会死亡。如果要检测出有毒药的一瓶,问至少需要多少只老鼠?

一周时间:10 只老鼠
两周时间: 7 只老鼠
三周时间: 5 只老鼠

276 total views, 1 views today

PHP Interview Questions(2)

面试时间:2018 年 9 月 4 日,星期二,下午两点。


PHP

1. 列举出几种你知道的 PHP 遍历或者迭代数组的方法

for, foreach, array_walk, array_map

安全防护

2. 解释什么是 XSS,CSRF,SQL 注入以及如何防范

http://www.cnblogs.com/leecong/p/5898370.html

网络

3. 在浏览器中输入网址到页面显示,期间发生了哪些过程?

http://www.cnblogs.com/kongxy/p/4615226.html

数据库

4. 一张采用 Innodb 的 User 表,其中 id 为主键,name 为普通索引,试从 索引的数据结构 角度分析,以下两条语句(均返回一条记录)在检索过程中有哪些区别?

Sql 1: SELETE id, name, address from User where name = "smith";
Sql 1: SELETE id, name, address from User where id = 1;
http://blog.codinglabs.org/articles/theory-of-mysql-index.html

5. 现有一统计网站独立访客需求,流量百万以上,如以 IP 为标识,可以查看当天实时或指定某天的 IP 数(需要去重),采用 MySQL 来实现,那么:

5.1 你会如何设计表和索引?(文字、sql 均可,方案尽可能高效)

IP 地址转换为整形存储,按日期分表,以 (IP, 日期) 作为联合索引。

5.2 数据如何入库,当天实时和某天数据该如何查询?(写出 sql 语句)

redis 队列缓存 -> MySQL 批量入库

select count(ip) from visit_log_{yyyymm} where date = {yyyy-mm-dd};

面试部分

你平时都是怎么设计数据库的?

按照业务逻辑设计(其实想考察的是数据库三大范式)。

说说 PHP 的垃圾回收机制。

http://php.net/manual/zh/features.gc.php

331 total views, 1 views today