腾讯云智二面
#我的失利项目复盘##腾讯云智西安##面经#上次一面完凉了,没想到过了两天发送了二面连接,具体看这篇文章:https://www.nowcoder.com/discuss/475003541132673024?sourceSSR=users
面试官上来先问你这个实习是只实习暑假还是一直下去,我说当然一直下下去,能转正最好
自我介绍
挑一个项目说说
我的项目是利用C++11实现的简易RPC网络通信框架,实现了服务的发布、注册、远程过程调用等功能,在这个项目中我使用zookeeper的watch机制和znode节点实现服务的的分布式部署,利用protobuf进行数据的序列化和反序列化,利用muduo进行高性能网络发送,利用生产者消费者模型编写异步日志模块
面试官反问:你为什么选择使用zookeeper作为服务注册中心
在分布式环境中,我们需要用到一个服务注册中心,来将我们发布的服务注册到上面取,来保证客户端在这个注册中心找到我们对应的节点,同时服务注册中心还要能够监听我们注册服务结点的变化,如何节点出现故障了我们就需要动态删除节点,同时也需要通知客户端节点节点发生了变化,需要做哪些处理,而Zookeeper正好实现了这么一个机制,它通过心跳机制来检测rpc节点是否还存在,每个一段事件zookeeper服务端就像rpc节点发送心跳包来判断rpc节点是否存在,如果不存在就删除节点,同时通过watch机制告诉客户端节点出现了变化,需要做出相应的变化。
面试官:你用没有考虑使用其它中间件做服务注册中心
我说:zookeeper刚好满足我的服务注册中心的要求,所以我就选了它
面试官:有了解过其它的吗?
额,没有
面试官:做项目要横向对比,分析所有组件的优缺点,选出最合适的,不能说只看一两个
面试官:你的项目使用protobuf进行数据序列化和反序列化,为什么
利用protobuf主要是为了进行数据的序列化和反序列化,也可以用json,xml,但是它们没有protobuf高效,protobuf是以二进制形式存储的,json是以key value形式存储的,xml存储需要二外的文本,所以在同等条件下哦,protobuf的数据大小较小,传输效率较高,而且protobuf支持rpc方法的描述,更加有利于我们实现rpc服务
面试官:了解protobuf的底层实现吗
额,只了解过它的基本使用场景,没有了解底层具体实现(感觉要寄了)
面试官:也就是你这个项目都是使用了其它库,没有深入理解过,这个项目那个部分你深入了解过
muduo库部分,我在做这个项目的时候需要一个高性能网络传输框架,我就使用了muduo库,之后我看了muduo库的源码,进行了相应的了解
面试官:了解过源码,那么具体说说muduo的实现
使用“One Loop per thread”的设计模式,可以很好的处理网络IO和数据发送,不会导致我的框架在网络IO部分出现问题
One Loop per thread:一个线程里面还有一个EventLoop,一个Reactor模型包含4个部分,Event事件,Recator反应堆,事件分发器,事件处理器;在muduo库设计中,我们主线程的EventLoop只负责新用户的连接,每次找到连接的用户之后就会把他交给子线程进行处理,而每个子线程里面也维护者一个EventLoop,它负责监听已连接用户的读写事件,如果一个文件描述符上发生了对应文件描述符感兴趣的事件,就调用对应的事件处理器EventHandler进行处理
面试官:为什么使用muduo库
muduo库刚好满足我的需求,而且它的效率也很高,所有我是用了它
面试官:其它很多库也可能使用了这个设计,甚至比它设计好,为什么使用了它
(有点无语了,因为只会使用它啊)muduo基于C++11进行实现,很好的支持了现代C++语法,使用bind进行回调时间的绑定,更有利于现代C++的使用,同时它的设计也非常棒,基于one Loop per thread,效率非常好,同时他对于C++新手非常友好,代码通俗易懂,而且一般的网络库线程之间都是通过加锁来实现线程间通信的,而muduo网络库采取无锁的方式,利用threadlocal来判断当前Chanel是否有该EventLoop执行,更加提升了效率,对于学习C++高性能服务器开发非常有帮助
面试官:你是如何学习muduo库的,仅仅只是看了它的代码?
没有的,我在学习muduo库的时候不仅看过它的源代码,我还对muduo库进行改进,实现了muduo库的TcpServer部分,去除这部分对于boost库的依赖,同时进行归纳总结(埋坑了)
面试官:你是怎么进行归纳总结的,使用什么工具
(啊这,我当时就随口一说而已)我一般在本地使用typora进行归纳总结,然后自己一个人进行复习
面试官:项目部分差不多了,接下来问点算法的吧,如果求一个数的n次方
我说直接n个数相乘,然后考虑n为负数能特殊情况,判断特殊情况即可
面试官:还有其它想法吗,可以考虑优化一下吗?
我说:应该只能这样了吧,其它方法没有了解过,可以给点提示吗?
面试官:你试试递归,看看递归如何?
递归的话效率有点低吧,因为他需要大量重复值得计算,所以相比于递归可能上面迭代的效率更高(寄了)
面试官:为什么会有这种感觉吗,有没有学过归并排序
有的,它采取分支思想,局部有序之后在进行合并,艹,到这终于有点思路了
X^n=X^(n/2)**X^(n/2)=X^(n/4)*X^(n/4) X^(n/4) X^(n/4)
之后一直进行递归就可以找出答案了
面试官:没错的,就是这种方法,那么你在学校学过计算机组成原理吧,那么如何求一个浮点数得最大最小值
(直接寄,组成原理上课我都没有去过,压根不知道讲了什么)我说组成原理学过的时间有点久了,有点想不起来了
面试官:没关系,你可以在纸上画画,推导推导
我的内心mmp啊,直接不会啊,我说好,然后假装推导了几分钟之后就告诉面试官抱歉面试官,我下去在好好想想吧,是在是忘记了,太尴尬了
面试官:那行吧,问你一个简单得,如何求一个链表是否有环
(终于遇到一个会的了,后面才知道原来也有坑),快慢指针,快指针一次走两步,慢指针一次走1步,判断快慢指针是否会相遇,如果相遇就有环,如果没有相遇就没有环
面试官:还有其它方法吗?
利用unordered_map记录走过的节点,如果一个节点重复走过那么就是有环,如果没有重复节点就没有环
面试官:那么你怎么保证快慢指针一定可以遇到
我说这个问题就类比操场上跑圈,那跑得快得人到最后可以套那个跑的慢的一圈,两者就相遇了(面试官听到这😀了)
面试官:我们考虑问题要理性,而不能感性,要严谨得证明,那么假设快指针一次走5步,慢指针一次走2步,可以相遇吗
艹,这才想起来,可能快指针可能刚好超过慢指针,以前都没有考虑过,面试官然我再想想
想了一会还是没有思路啊,以前都没有注意过,寄了
面试官:时间差不多了,我们聊点其它得,chatgpt了解过吗
我说了解过
面试官:那你了解过它的底层吗
那肯定没有啊,我本科没有学过相关课程,所以没有了解过,抱歉了
面试官:看来只是简单注册了账号玩了玩啊
啊对对对()
面试官:看你对数据库索引,事务,索引优化有理解,讲一讲索引吧
索引是一种特殊的数据结构,通过建立索引可以加快数据搜索速度,它就像书的目录一样,MySQL默认使用innodb作为存储引擎,它的底层索引结果是B+树,查询效率是非常高的,但是不一定创建索引就是非常好的,索引的创建本身是非常消耗资源的,在数据量比较大的时候创建索引需要花费大量时间,而且索引本身是非常占用内存空间的;在后期新增数据的时候可能需要进行数据的移动,后期维护也是需要大量时间的;当数据量比较小的时候没有必要建立索引,MySQL底层在判断索引和整表查询时间差不多的时候是不会使用索引的;有时候建立索引过多或者建立不当可能起到相反的作用
面试官:应该如何建立索引
前缀索引优化:利用字符串前几个字符建立索引,而不是整个字符串建立索引
联合索引优化
自增主键作为索引
防止索引失效
面试官:优化索引,你如何做的,实际应用中
1.启动慢查询日志,记录操作时间过长的SQL语句,
2.利用explain分析执行时间过长的SQL语句
3.看看该语句是否加索引,没有加索引就加上索引,若有索引看看索引是否起作用
4.看看索引是否添加正确,查询是否用到索引,有没有用到回表,是否用到外排序,如果有外排序是否可以考虑建立联合索引,在sql语句中是否存在函数、强制类型转换等,然后具体问题进行具体分析
面试官:你在网络学习上花了多少时间
上学期一直在跟着学校课程学习,这学期也在积极自学
面试官:我也不问你了,你自己说说你网络学到了什么
学习了TCP/IP协议栈,学习了HTTP,TCP,UDP,IP,ICMP(埋坑了)等协议,了解网络通信基本流程,能够进行高并发网络编程
面试官:TCP三次握手四次挥手,及状态转换
这个就不写了
面试官:整整的网络环境可能不是这样的,抓包抓过吗
抓过,上学期实验课使用Wireshark抓包,Linux平台没有试过(辛亏给自己没有埋坑啊)
面试官:Linux平台没有抓过包就算了,有时候网络环境很差,需要进行探测,icmp了解吗
ICMP协议称为互联网报文控制协议,主要用来检测对端网络环境是否良好,通过发生ICMP报文判断是否有ICMP回应
面试官:那么icmp报文是怎么传输会我的发送端得,应用层面上有ip协议,这个是怎么做到的
直接寄,没有了解过,
面试官:(可能觉得没有希望了),直接问我我和其它同学相比有什么优势
瞎扯ing….
面试官:高数、概率论成绩怎么样,切比雪夫不等式了解过吗
高数,概率论当时成绩还可以,但是现在基本都忘光了,切比雪夫不等式我记得是概率论的,现在有点忘记了,抱歉啊
今典反问:
我有什么需要改进的吗
基础可以,但是学习东西不能只看重表面,编程是一个与时俱进,日新月异的,要注重持续学习
自我反思:为什么我的面试和别人的不一样啊,我看别人面经的东西我都没有考到,背了那么长时间面经好像没有用到,有点郁郁,感觉有点想kpi面,上次我答得很垃圾,过了两天给我发二面了,当时以为裂开了,兄弟门判断一下这个是不是kpi面