百度二面:一次覆盖DevOps、系统设计到算法的技术对话

面经

docker与虚拟机的区别

docker是怎样实现资源隔离和资源限制的

docker如何实现相互通信

docker file了解吗

说一下epoll

水平触发和边缘触发

sql题,给stu_id,stu_score,stu_name求平均分

having是干嘛的

手撕:二叉树最大路径和

说一下几个在项目中遇到的难点,最能体现你技术的点

反问:如何学习k8s

原帖链接:https://www.nowcoder.com/feed/main/detail/539defc84556425987f2c750b73c4e4c?sourceSSR=search

参考回答

面试官:Docker和虚拟机有什么区别?

应聘者:嗯,这个问题挺常见的。Docker和虚拟机最大的不同就是Docker更轻量。虚拟机是完整的操作系统,而Docker只是共享主机的内核。所以Docker启动更快,占用资源更少。但是呢,虚拟机隔离性更好,安全性可能更高一些。

面试官:Docker是怎样实现资源隔离和资源限制的?

应聘者:Docker主要是用了Linux的一些特性来实现的。比如说,用cgroups来限制CPU、内存这些资源的使用,用namespace来隔离进程、网络、文件系统这些。这样每个容器就像是独立的环境,互不影响。

面试官:Docker如何实现相互通信?

应聘者:Docker容器间通信主要有几种方式。最简单的就是用Docker网络了,创建一个网络,把容器都加进去,它们就能互相通信了。还可以用端口映射,把容器的端口映射到主机上。如果是同一个主机上的容器,还可以用IPC共享内存或者volume共享文件来通信。

面试官:Docker file了解吗?

应聘者:抱歉,这个我不太了解。我主要是使用现成的Docker镜像,还没有自己写过Dockerfile。

面试官:那你能说说epoll吗?

应聘者:epoll是Linux下的一种I/O多路复用机制,效率比select和poll高多了。它能同时监控多个文件描述符,当I/O事件发生时,只需要遍历那些发生了事件的fd,不用像select那样遍历所有的fd。所以在高并发的场景下,epoll特别有用。

面试官:水平触发和边缘触发有什么区别?

应聘者:这两个是epoll的工作模式。水平触发就是只要有数据就一直通知你,而边缘触发是有新的数据到达的时候才通知你。用边缘触发的话,你得一次性把数据都读完,不然就不会再通知了。所以边缘触发效率更高,但是编程更难一些。

面试官:给你一个SQL题目,有stu_id, stu_score, stu_name这些字段,你怎么求平均分?

应聘者:哦,这个简单。用AVG函数就行了:

SELECT AVG(stu_score) as average_score FROM student_table;

如果想按学生分组的话,可以加个GROUP BY:

SELECT stu_name, AVG(stu_score) as average_score 
FROM student_table 
GROUP BY stu_name;

面试官:HAVING是干什么的?

应聘者:HAVING主要是用来过滤分组后的数据的。比如说,我们想找出平均分大于80的学生,就可以这么写:

SELECT stu_name, AVG(stu_score) as average_score 
FROM student_table 
GROUP BY stu_name
HAVING average_score > 80;

它和WHERE的区别就是,HAVING是在分组之后进行过滤,而WHERE是在分组之前。

面试官:好的,现在来道算法题。求二叉树的最大路径和。

应聘者:嗯,这题我们可以用递归来解决。基本思路是对每个节点,我们计算包含它的最大路径和。这个和可能是节点值加左子树的最大路径和,或者是节点值加右子树的最大路径和,或者是节点值加左右子树的最大路径和。我们用一个全局变量来记录最大值。大概的代码是这样:

class Solution:
    def maxPathSum(self, root):
        self.max_sum = float('-inf')
        
        def max_gain(node):
            if not node:
                return 0
            
            left_gain = max(max_gain(node.left), 0)
            right_gain = max(max_gain(node.right), 0)
            
            path_sum = node.val + left_gain + right_gain
            self.max_sum = max(self.max_sum, path_sum)
            
            return node.val + max(left_gain, right_gain)
        
        max_gain(root)
        return self.max_sum

这样,时间复杂度是O(n),n是节点数,因为我们遍历了每个节点一次。空间复杂度是O(h),h是树的高度,因为递归调用栈的深度最大是树的高度。

面试官:说说你在项目中遇到的难点,最能体现你技术能力的点。

应聘者:嗯,让我想想。我觉得最有挑战性的是我们做的一个高并发的订单系统。我们遇到的主要问题是数据库压力大,还有就是出现了一些数据不一致的情况。

为了解决这些问题,我们做了几个优化:

  1. 首先,我们用了Redis来做缓存,减轻数据库压力。
  2. 然后,我们把一些不需要实时处理的操作,比如发送通知啊,更新统计数据啊,都放到消息队列里异步处理。
  3. 对于数据一致性问题,我们实现了分布式事务,用的是两阶段提交协议。

这个过程中,我学到了很多关于缓存、消息队列和分布式事务的知识。最重要的是,我更深入地理解了如何设计可扩展的系统架构。

面试官:好的,你还有什么想问的吗?

应聘者:是的,我想请教一下,您觉得学习k8s最好的方式是什么?

面试官:学习k8s,我建议你可以先从官方文档开始,理解基本概念。然后搭建一个本地的minikube环境,动手实践。再就是跟着一些实战教程走一遍,比如部署一个完整的应用。最后,参与一些开源项目或者在工作中实际使用,才能真正掌握。记住,k8s是个复杂的系统,需要慢慢积累经验。

应聘者:明白了,谢谢您的建议!

面试官:好的,今天的面试就到这里,我们后续会通知你结果。

应聘者:好的,非常感谢您的时间。期待您的好消息,再见!

#面经##24届软开秋招面试经验大赏##悬赏#
2024计算机面经详解 文章被收录于专栏

收录网络上的各个公司,包括但不限于阿里、字节、腾讯、小红书等公司的面经,并给出参考答案。 什么?!你不会面试?🤨 看这个就对了!😄 OfferNow!

全部评论

相关推荐

2 9 评论
分享
牛客网
牛客企业服务