一次被头条面试血虐的总结

5,424 阅读4分钟
原文链接: laravel-china.org
  • 手写代码题目1:
    /*
    * 有n个房间,现在i号房间里的人需要被重新分配,分配的规则是这样的:先让i号房间里的人全都出来,
    * 接下来按照 i+1, i+2, i+3, ... 的顺序依此往这些房间里放一个人,n号房间的的下一个房间是1号房间,直到所有的人都被重新分配。
    * 现在告诉你分配完后每个房间的人数以及最后一个人被分配的房间号x,你需要求出分配前每个房间的人数。数据保证一定有解,若有多解输出任意一个解。
    *
    *
    * 最先想到的是爆破的思路:从最后一个人被分配的房间开始往前递推,每个房间减一个人,直到某个房间人数减为0,但是并不是最优解法。。。
    * 面试完想到了另一种解法是找到分配后各个房间人数的最小值便是起始的i号房间。最小人数就是重新分配的轮次数。
    * */
    function findRoom($n, $x, $room)
    {
        $min = min($room);
        $index = function ($i) use($n) {
                return $i >= 0?$i % $n:$i % $n + $n;
        };
        //从最后分配房间回退到前一轮的i号房间
        for ($i = $x - 1, $d = 0;$min != $room[$index($i)]; $i --, $d ++ ) {
                $room[$index($i)] -= $min + 1;
        }
        //i号房间原人数
        $room[$index($i)] = $min * $n + $d;
        if ($index($i) != $x) {
                //恢复其它房间人数
                for ($i = $i - 1; $index($i) != $x; $i --) {
                        $room[$index($i)] -= $min;
                }
                $room[$index($i)] -= $min;
        }
        var_dump($room);
    }
  • 手写代码题目2

    /*
    * 打印二叉树从左视角看到节点
    * 给定一颗普通二叉树,请输出二叉树左视角能看到的节点
    * 例如,普通二叉树
    *                  1
    *               /       \
    *             2          3
    *          /    \      /     \
    *         4      5    6       7
    *                            /
    *                          8
    * 从左边看,输出能看到的 1,2,4,8 这四个节点。
    * 使用层序遍历,从右到左,然后将最左侧放入结果集中
    * */
    class Node{
        public $val, $left, $right;
        public function __construct($val)
        {
                $this->val = $val;
        }
    }
    function leftView($root)
    {
        $stack = [];
        $stack[] = $root;
        $ret = [];
        while (!empty($stack)) {
                foreach ($stack as $eachNode) {
                    $leftNode = array_shift($stack);
                    if (!empty($leftNode->right)) {
                            $stack[] = $leftNode->right;
                    }
                    if (!empty($leftNode->left)) {
                            $stack[] = $leftNode->left;
                    }
                }
                $ret[] = $leftNode->val;
        }
        var_dump($ret);
    }
    • Redis的优点和缺点?
      • 上面两道算法都基本没做出来,导致心态大崩,所以答得也不是很好,优点就是围绕着Redis的几个特性和数据结构及其应用场景,持久化,哨兵,集群来说明的,缺点就只说了它并不能完全容错和恢复,下面仔细记录学习一下。
      • 优点:
        1. 数据存放在内存中,读写速度很快,采用单线程结构,防止了因多线程竞争可能出现的问题和消耗。
        2. 数据类型丰富,五种基础数据类型,并且有很多很有用的扩展数据类型,如位图,HyperLogLog,发布订阅,GEO等。
        3. 功能丰富,提供键过期,简单事务,Lua脚本管理,Pipeline等功能。
        4. 数据可持久化,可通过RDB和AOF两种方式进行数据持久化。
        5. 提供主从复制,可利用集群,哨兵构建高可用的分布式架构。
      • 缺点:
        1. 不具备自动容错和恢复功能。
        2. 主机宕机,宕机未同步到从机的数据无法恢复。
        3. 主从复制采用全量复制,若快照文件过大,对集群的服务能力会产生较大影响。
        4. 难以支持在线扩容。
  • 死锁产生的条件:

    1. 互斥请求
    2. 不可剥夺
    3. 循环等待
    4. 请求保持
  • 进程和线程的区别:

    • 进程是资源拥有的基本单位,线程是CPU调度和分派的基本单位。
    • 一个程序至少有一个进程,一个进程至少有一个线程。
    • 进程在执行程序中拥有独立的内存单元,而多个线程共享内存,从而极大地提高程序的运行效率。
    • 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
  • 假如现在有50M的数据,网络延迟为50ms,仅考虑TCP的情况下,请预估一下将这个数据从北京发往深圳所需要的时间。
    • 听完我....一脸懵逼啊。。然后就只能扯了一下TCP从客户端发送数据再到服务端接收处理的整个处理过程,感觉面试官也很不满意。
    • 个人感觉这个问题的考点在于TCP传输中会将数据进行分段,每一段的最大长度是有限的,减去TCP头部长度便是每段的可发送的数据长度,然后在进行计算,但当时心态已经被算法题搞崩了就没心思再思考了。
    • 也顺便求一波答案,想了很久还是没明白,先谢过各位啦........