纪录我的春招之路 (持续更新到找到实习)

写在前面#

大三了,所以该找找实习了,用这个文章记录一下在各个面试中遇到的问题和总结,希望可以早日好的找到实习。。

腾讯#

一面#

  1. 指针和引用;定义和声明;内存泄漏和内存溢出;堆和栈的区别
  2. PHP 垃圾回收机制
  3. 进程,线程讲一下
  4. MySQL 常用引擎及其区别
  5. 索引相关,底层实现,B 树和红黑树
  6. MySQL 优化,问了很多
  7. MySQL 死锁出现原因及解决方法
  8. 各种排序的时间复杂度,稳定性,空间复杂度
  9. TCP 三次握手,四次挥手
  10. awk 的使用
  11. HTTP 的常用状态码,请求方法
  12. IO 多路复用,它们的区别
  13. https 中证书内都存放哪些内容
  14. 手写代码:洗牌,发牌算法

    二面#

  15. IPC 通信的各种机制,越详细越好,哪种开销最小,为什么
  16. 进程的内存分配
  17. 用户态,核心态。为什么要区分,OS 是怎么做到区分的,什么情况下会发生切换
  18. 进程,线程问了很多很多,具体记不清楚了
  19. MySQL 主从复制
  20. 事务,储存引擎,联合索引,最左前缀原则
  21. Redis 的 LRU 算法实现,集群,哨兵机制,数据类型,各个数据类型的底层实现
  22. 手写代码: a. 堆排序 b. 双向链表转排序二叉树,不能申请新空间 c. 快排及其优化方法
  23. https 过程,证书认证是怎么做的
  24. RSA 加解密过程,RSA 签名,使用时有什么需要注意的点
  25. TCP 三次握手,四次挥手,为什么是四次,TIME_WAIT 状态相关。SYN 洪泛攻击怎么解决
  26. 分布式事务
  27. 幂等性
  28. 在确保幂等性时,前端防抖是怎么做的
  29. 逻辑题目:用几个不同容积的水桶分水的题目。。具体数字不记得了
  30. PHP 怎么实现弱类型,7.0 版本在这方面和之前的版本有什么不同
  31. Web 安全的常见漏洞,CSRF,XSS,注入
  32. select 和 epoll
  33. Linux 命令, a. 查看内存使用 b. 查看某个进程使用的系统调用 c.awk 编程
  34. 缓存穿透,缓存雪崩的预防方法,布隆过滤器

搜狗#

  1. Cookie 相关,set-cookie 函数的用法,原理。
  2. HTTP 协议 Request 和 Reponse 包的结构和内容。
  3. 301 和 302 的区别,Location 字段的含义。
  4. 布隆过滤器。
  5. 内存对齐。
  6. B+-Tree 结构,前缀索引为什么可以使用到索引。
  7. c10k 问题。
  8. 手写代码,多叉树的层序遍历。
  9. PHP7 的特性和优化。
  10. PHP 的协程。

小米#

  • 电话面试,感觉还好,有一些问题确实没有了解过,也没有办法。。有没有后续就还不知道了。

  • 项目相关,说了说寒假实习公司的项目和自己做的两个开源的小东西。。

  • MySQL 中的常用优化手段:

    1. 避免 select *
    2. 提高索引选择性,索引选择性 = 不重复的索引值/数据表记录总数
    3. 使用多列索引并选择更加合适的索引顺序。在不考虑排序和分组时,将选择性最高的索引放在索引最前列
    4. 遵循最左前缀原则,保证索引不失效
    5. 在遇到慢查时,使用 explain 关键字查看语句运行情况
    6. 各种小的点,比如有 between 代替 in,limit 优化,自查询优化等等。
  • 使用 Explain 语句时,你会关注哪些信息,这些信息都表示什么。。。只答出了自己记着的

    1. type 字段,该字段表示索引使用情况,最差是 all,最好是 system。
    2. rows 字段,表示 MySQL 引擎执行计划中估算的扫描行数,如果该数值过大,就表示有可能索引失效或者索引选择性不够高,应该对索引顺序进行调整。
    3. key 字段,真正用到的索引。
  • MySQL 中的隔离级别,你使用的是哪一级别

    1. 未提交读,最低的级别, 会造成脏读。
    2. 提交读,个事务从开始到提交,所做的任何修改对其他事务都是 不可见的。
    3. 可重复读,MySQL 默认的隔离级别,解决脏读,但可能出现幻读。
    4. 可串行化:最高的级别,解决幻读。
    5. 自己都是使用默认的,并没有做过修改。。。。
  • 如果两个事务同时读取一行数据,是否会阻塞

    • 不会,读锁是共享锁,写锁是排他锁,所以在读取时并不会阻塞其他事务
  • 那如果我要强制阻塞呢

    • 我只知道可以显式地添加一个排他锁。。但是怎么做给忘了。。面完之后查了一下,好像是用 for update 可以加一个排他锁。。
  • 索引默认是基于什么数据结构实现的,为什么

    • 基于 B-Tree 或 B+Tree 实现的,至于为什么,自己只知道是因为 B-Tree 结构可以既满足了平衡二叉树在查找时的高效率,又相对于红黑树等其他平衡树来说,它的树高很低,可以大大减少 I/O 次数,节省时间。具体的就不知道了,后面再查查学一下。
  • 那 B-Tree 和 B+Tree 有什么区别啊

    • B+Tree 会在叶子节点储存具体的数据信息,B-Tree 不会。。。只知道这个?
  • 了解聚簇索引嘛,说一说

    • 聚簇索引是一种数据储存方式,当有聚簇索引时,,数据行实际存放在索引的叶子节点中,聚簇索引可以大量减少磁盘 I/O,提高访问速率。但是插入和更新的代价都很大。
  • PHP 是弱类型语言,它是怎么实现弱类型的

    • maya... 这也太底层了吧。自己知道的只是 PHP 的 Zval 结构,每个变量在 zend 引擎层面都会维护一个 Zval 结构体。在 Zval 这个结构体中包含有引用计数,是否为引用,还包含有这个变量的具体的数据类型和值,只是在具体使用的时候没有暴露出来而已。。。这快确实懂得不多,还要多看看底层的知识。
  • 那如果让你来实现 PHP 的这个特性,你会选择什么数据结构

    • 我。。。。。我会选择结构体吧(因为我貌似记得 PHP 底层就是结构体吧)。
  • 为什么是结构体而不是联合体,结构体和联合体有什么区别

    • C 语言的知识,但是给忘记了?。。就直说了不知道。
  • 在操作系统中,进程的调度算法都有什么。

    • 就在嘴边的知识,就是想不起来了,面完之后才想起来了有先来先服务,短作业优先,时间片轮转,高响应比,多级反馈队列。。
  • 死锁的条件

    • 下面有,就不重复了。
  • 银行家算法知道吗

    • 银行家算法可以通过预估资源分配,防止系统进入不安全状态的方法来避免死锁,自己在操作系统学习的时候,也做过相关实现。
  • 写一个算法题目吧,有两个操作,一个是给一个数乘以 2,一个是给一个数减 1,给定两个数字 A 和 B,求出将 A 通过前面两个操作变成 B 的最少步骤。例如,A 是 4,B 是 6,则可以 A 乘 2 减 1 减 1,也可以 A 减 1 再乘 2,所以其最少步骤就是 2。。

    • 最讨厌的算法题目又来了。真想抽死自己,竟然说成了深度优先遍历,面试官还好心的提示问了下是深度优先还是广度优先,然后自己范傻又说了是深度优先。。
    • 具体代码:
      function bfs($a, $b)
      {
      //结果数组
      $mask = [$a => 0];
      //队列
      $queue = [$a];
      while(!empty($queue)) {
              //出队
              $A = array_shift($queue);
              if ($A == $b) {
                      return $mask[$A];
              }
              $C = $A * 2;
              if (!isset($mask[$C])) {
                      $mask[$C] = $mask[$A] + 1;
              }
              //入队
              $queue[] = $C;
              $C = $A - 1;
              if (!isset($mask[$C])) {
                      $mask[$C] = $mask[$A] + 1;
              }
              //入队
              $queue[] = $C;
      }
      return false;
      }
  • HTTP 的头部常用字段都有哪些,说出你知道的。

    • 只说出了一部分的
    • Cache-Control 控制缓存的行为
    • Connection 连接管理
    • Content 系列,Type,Length 之类的
    • UA HTTP 客户端程序的信息
    • Host 请求资源所在服务器
    • Referer 对请求中 URI 的原始获取方
    • 太多了,就没说完,可以参考这篇文章,写得很不错
  • Connection 字段是干什么的,有什么特殊作用

    • 在 HTTP1.1 中默认采用 keep-alive 保持长链接,已避免每次请求都要建立 TCP 连接所带来的消耗。
  • 如果在一个页面中,有一个请求是用了 keep-alive,那么后面的请求会有什么影响嘛?

    • 这个真的不知道,就说了一下其他的,说了如果是在最新的 HTTP/2 中,由于其是比特流协议,所以可以多个请求进行多路复用。而在 HTTP1.1 中,我所能想到的只是如果是一个页面的话,它能同时发起的请求数量是有限制的。。。感觉完全没答到点上。。

今日头条#

  • 头条的面试真的好难好难,上来就考算法,手撕代码,这又是自己最大的弱项,所以很明显的挂掉了。。。。

  • 手写代码题目 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 头部长度便是每段的可发送的数据长度,然后在进行计算,但当时心态已经被算法题搞崩了就没心思再思考了。
    • 也顺便求一波答案,想了很久还是没明白,先谢过各位啦........
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 7年前 自动加精
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 26

好难啊。。同大三,共勉吧。。

7年前 评论

同感 头条这种公司都是这样的,对计算机组成原理,数据结构与算法,计算机网络,甚至是概率,看的特别重,只能说现在对大三学生要求太高了,又要有项目经验实战能力,还要你底子好,基础扎实,真的难啊

7年前 评论
DenverB

@沐雨 嗯嗯,加油啦。。

7年前 评论
DenverB

@licheng 对啊,面完头条都想去考研了??,主要是因为自己是学网络安全的,所以数据结构和算法的底子还是太弱了,每次都死在这个上面,还在不断学习中。。

7年前 评论

一个实习生要求都这么高,汗

7年前 评论
DenverB

@风中的白鸽 头条要求确实比较高...... 毕竟它们实习一天 400。

7年前 评论

// 已知条件,分配后的每个房间人数 $num, 分配后的最后一个房间 $room_id
// 求未分配前的房间人数

public function($num,$room_id){

return $room_id*$num/($num+1);

}

// 求二叉树的左侧视角

public function($x=2,$val=8){
$arr[0]=1;
$a= sqrt($val)
for($i=1;$<=$val;$i++){
$arr[$i]=pow($x,$i)
}

var_dump($arr);
}

7年前 评论
蔺焕然

好难。。大四的表示不会

7年前 评论
DenverB

@xiaolun 第一个题目是要求分配前所有房间的人数。。第二个的话,它是普通二叉树,所以并不是满二叉树,也不是二叉搜索树,所以基本只能使用层序遍历来做。

7年前 评论
DenverB

@蔺焕然 唉。。只能慢慢学习了.....

7年前 评论

今天我正好也收到一个头条发来的社招面邀,这么虐,还是不去了算了。

7年前 评论
JaguarJack

@wilson_yang 不要怕,多去面试,不然不知道自己的底在哪里

7年前 评论

头条这公司确实要用到算法,所以考算法,还是很合理的,这两题我反正搞不起来

7年前 评论

题目 1 的要求能重新写下吗,看不太清楚

7年前 评论
DenverB

@ChaosKevin

file屏幕快照 2018-03-29 下午 7.16.51

7年前 评论

同是大三,操作系统那部分还能做做,算法等其他内容,根本没法做,好心塞啊

7年前 评论
DenverB

@g1f9 只能慢慢学习了......

7年前 评论

厉害。。

7年前 评论

@DenverB 你看你的图嘛 二叉树最后一个数字是 8 他其实就是左边的 8 嘛 你第一题我也没搞懂啥意思 按我的理解就其实这个应该就是一道数学题,所以我的解法就是一道数学公式洛。。

7年前 评论

二叉树那个不对啊兄弟,你只是层序遍历了所有节点,然后打印出来。https://blog.csdn.net/qq_35546040/article/... 这个答案没准靠谱点,头条这道题还考 java 和 php 通用

7年前 评论
DenverB

@holashatu 是层序遍历,但是最终打印的节点是每一层的最左边的节点。给最终 $ret 数组添加元素是在每一次的 foreach 循环外的,所以只添加了每层最左边的那个节点。

7年前 评论

@DenverB 谢谢,我 foreach 用法理解的问题。。

7年前 评论
ShMichaelLi

@DenverB 兄弟可以的,大三这种水平,已经算比较扎实的了,记得我算法巅峰也就是考研的时候。

7年前 评论
黑将军

惭愧,工作三四年,这些题目有百分八十不会或者说不上来的

6年前 评论