(已拿offer)阿里云2020实习面经
本人21届毕业生,目前在找暑假实习,会陆续发布春招以来的相关面经,回馈牛客,觉得有用的话可以关注一波,本人在春秋招备战过程中的记录和总结已发布到语雀文档,欢迎学习和参考。
语雀文档:https://www.yuque.com/ouweibin/interview
个人Github:https://github.com/ouweibin
CVTE2020实习面经 - C/C++软件开发工程师:https://www.nowcoder.com/discuss/384664
腾讯CDG2020实习面经 - 事务型开发:https://www.nowcoder.com/discuss/381058
阿里云2020实习面经 - 研发工程师C/C++:https://www.nowcoder.com/discuss/404896
网易雷火2020实习面经 - 游戏研发工程师(服务端方向):https://www.nowcoder.com/discuss/380829
阿里云2020实习面经 - 研发工程师C/C++
2020-03-02 内推简历
电话面 一面 30min 2020-03-04 15:00
- 自我介绍
- 华为云KVStore比赛
- 有写过测试用例吗?
:测试用例是华为云给的,自己本地测试的时候修改过测试用例 - 代码如何做调试的?
:日志打印,根据日志信息定位错误 - 具体场景是怎样的?做了哪些性能优化?
:KV分离,使用DIO + mmap方式提高读写效率,同时防止数据丢失 - 刷盘一次延迟是多少?刷盘的时候来了数据怎么办?
:没有异步操作
系统的瓶颈主要在刷盘延迟,实际上16个线程并发写入数据已经能到跑满磁盘IO带宽,不需要进行异步操作 - 用了哪些主要的数据结构?(说了vector,答得太快了,其实不是的)
KV长度固定,数据量大小确定,内存操作实际是通过malloc内存然后通过地址 + 指针操作,磁盘操作使用pread和pwrite函数 - 引擎是使用的多线程吗?
:测试用例里写入和读取数据是多线程并发的,引擎实现里没有多线程
实际上在构建索引时可以多线程处理,平衡CPU和IO - 线程间有加锁吗?
:线程间数据是独立的,不会彼此读取,可以通过每个线程创建一个实例的方式进行读写操作,不需要加锁 - 同时有读写操作如何进行设计?如何对数据进行保护?(答得不好)
参考B+树原理或者LevelDB原理,数据可以有序存储,如果要求按写入顺序读取,可以添加时间戳
如果线程间数据是混合的就需要进行加锁操作,加锁的粒度可大可小,大粒度的锁可在调用接口后就立即加锁,小粒度的锁则需要在对底层的共享数据结构操作进行加锁
锁可以分成共享锁和排它锁,写入的时候加排他锁,读取的时候加共享锁,这样可以提高并发性能 - vector的内存原理?数据会不会失效?
:vector容量不够时会进行扩容,扩容会出现数据搬移的情况
:数据量大小已经确定,可以通过reserve预先分配内存 - 操作系统怎么实现锁?
:可能是操作系统的原子操作(不太清楚)
有几种实现方式:关中断,原子操作,锁总线,加锁和解锁可抽象成对一个整数加减1的操作
关中断保证线程访问共享资源时不会切换到另外一个线程,但是效率很低
单核环境下通过原子操作(硬件实现),多核环境下需要锁住数据总线,效率高 - 编程题:给定一个二维数组,每一行代表树的一个节点,每一行有3个数据,第一个表示节点本身的值,第二个表示节点左孩子的值,第3个表示节点右孩子的值(NULL用-1表示),如何判断这些节点构成一棵树还是多棵树,先介绍思路,等下写完发到邮箱
:先把树(可能是森林)构建出来,因为不知道根节点,所以只能遍历所有的节点,求出以该节点作为根节点的树的总结点数,如果总结点数等于给出的节点数,那么就是树,如果遍历到最后没有,就是森林,时间复杂度O(n^2)(可能不是最优解)
插曲:阿里邮箱屏蔽外网邮件,发送邮件后无法投递成功,后来给面试官发短信了,但是当天都没回,后面以为是自己太菜已经挂了,到了第二天上午面试官才回的短信,最后是通过钉钉把代码发过去了
电话面 二面 56min 2020-03-07 16:00
- 自我介绍
- 从背景,任务等方面介绍一下RTSP流媒体服务器
- 为什么使用RTSP协议,不使用其它协议?
:RTSP协议应用比较广泛,文档资料多
:视频监控服务一般使用RTSP + RTP协议而不用HTTP协议,满足实时性的要求 - RTSP协议和HTTP协议有哪些优缺点?
:HTTP协议无法满足实时性的要求
:HTTP协议一般用在浏览器上,可能无法适配流媒体相关的客户端 - 云端部分有了解吗?
:师兄在做,目前还是独立的,以后可能要把视频流推送到云端 - 为什么用非阻塞IO+IO多路复用方式?
:提高并发访问量 - 最终的性能如何?CPU开销呢?
:网络库部分主要测试了吞吐量,基本上能够打满网卡带宽,QPS测试比较困难
:没有关心CPU开销
服务器性能指标:CPU负载,CPU使用率,QPS,响应时间等 - 在Linux下面开发怎么调试代码?
:小程序或单个文件的程序使用GDB
:比较大的项目移植日志库,通过打印日志的方式定位错误 - GDB命令了解吗?打断点?查看变量?
:用的比较少,需要查文档,打断点用b,查看变零用watch - 介绍一下华为云KVStore比赛
- key和value如何保证进程意外退出时不丢失数据?
:KV分离,key数据量小,直接写入到磁盘mmap的内存,由操作系统保证写入磁盘
:value数据量大,不能采用key的方式,而是通过mmap一块Cache实现每次flush多条value - 进程退出时如何恢复?
:key不会丢失数据,value的话找到mmap那块Cache对应的磁盘数据就能恢复了 - 为什么要分片?
:不分片直接用哈希索引的方法空间复杂度太高
:不分片直接排序索引 + 二分查找的方法时间复杂度太高 - 对于实际的KV系统,索引如何处理?(参考MySQL的B+树原理)
:一边写入数据,一边修改索引(对于经常写的场景性能太低)
:使用哈希索引(内存要求高)
实际上数据应该有序存储
借鉴B+树原理,通过目录项记录快速定位到页,在页里面根据页目录快速定位value,写入删除数据可能会有页的分裂合并操作
借鉴LevelDB原理,每个SSTable文件的每个Block都有索引信息,根据索引信息快速定位value,索引信息只在内存插入数据和磁盘合并SSTable文件时才会修改 - 有重复key的时候如何覆盖写Value?
:根据索引定位到value,然后更新value - 随机写性能很低,有没有其他方法?
:借鉴MySQL原理,把修改记录写入日志(顺序写)避免丢失,然后在内存修改value,定时或者定量之后再刷磁盘
借鉴LevelDB原理,先不覆盖写,读取的时候按照从内存,最上层到最下层的顺序读取最新数据就行,在合并SSTable文件的时候再删除旧的无效数据 - new和malloc的区别?
:new先通过operator new分配内存再调用构造函数,operator new其实就是c++版本的malloc - 静态局部变量存在哪个地方?静态局部变量的地址是编译时确定的还是运行时确定的?
:静态存储区,静态存储区的内存在程序编译时已经确定 - 多态和重载的区别?多态的原理?
:重写和重载的区别,虚函数表指针,虚函数表 - 虚函数表指针放在对象的哪个地方?
:在类的内存结构的最开始位置
虚表指针在类的内存结构位置没有规定,不同编译器有不同的实现 - 手撕代码:数组中出现次数超过一半的数字
:使用多数投票算法,6min写完,写完后介绍思路,3min查错
电话面 三面 38min 2020-03-10 20:00
面试官没有预约时间,直接打电话过来就开始面了
- 自我介绍
- 使用C++的人越来越少了,为什么搞C++?
:以前搞嵌入式,后面实验室的项目用的C++ - 从需求,设计,分工,难点等几个方面介绍下华为云KVStore比赛(把数据随机分布说成了随机写,低级错误)
- 你的任务是什么?
:负责编程 - 和LevelDB对比过优劣势吗?(答不出来)
LevelDB写性能很高,但是读性能一般
LevelDB支持长度可变的KV,固定长度的KV在设计方面可以进一步优化
LevelDB不支持按写入顺序读取
考虑到具体场景,LevelDB不是通用的,但是可以借鉴LevelDB的设计思路 - 借鉴LevelDB的思路,不需要做LSM,采用WAL的方法,写入一条记录时就KV合一flush一次,和你的方案比较?(没听清楚,也没答好)
实际上以4K的整数倍写入性能会更好
KV合一存储的话构建索引需要遍历磁盘所有数据,而KV分离存储只需要读取key那部分数据就行
一次flush一条记录性能太低,无法跑满磁盘IO带宽,通过mmap实现每次flush多条记录 - 这个比赛拿奖了吗?
:排名20+ - 对LevelDB了解吗?(只知道有Compaction操作)
写入一条记录时,先用WAL的方式写入Log文件(避免数据丢失,顺序写效率高),再把记录插入到Memtable(跳表)的合适位置
Memtable最后变成Immutable Memtable,然后写入到Level0的一个SSTable文件
某一层的SSTable文件达到一定数量时,触发该层某个SSTable文件与下一层SSTable文件进行合并 - 学过操作系统吗?对操作系统哪一块比较熟悉?
:进程调度,内存管理(有点虚) - 进程运行的时候,内存空间由哪些段组成的?
:代码段,数据段,堆,共享空间,栈,内核空间 - 进程的内存空间怎么映射一个共享库的?
:程序运行时才链接共享库,通过mmap把磁盘的共享库文件映射到虚拟地址空间,程序真正访问时触发缺页异常,操作系统把共享库文件内容加载到内存 - 多个进程映射一个共享库,进程退出时释放共享库,内存管理上是怎样的机制?共享库都没进程引用了会怎么办?(没答到关键点)
多个进程共用共享库,共享库在内存肯定只有一份,可能有个引用计数,进程加载同个共享库时引用计数加1,进程释放共享库时引用计数减1,最后没有进程引用时引用计数为0,操作系统卸载共享库,释放内存 - 从用户态陷入内核态,地址映射转换是怎么做的?(强答成分页机制和系统调用原理,被怼了)
程序从用户态进入内核态,由内核栈的pt_regs结构存储用户态上下文,此时代码段已经变成了内核相关代码,DS寄存器存储段选择子,根据段选择子在内核的全局描述符表(GDT)找到段描述符,根据段描述符里面的段基址以及虚拟地址的偏移量就能够找到映射在3G-4G的内核地址 - 有在哪个公司实习?
:大三在华为实习过,做底层软件开发,和后台开发关系不大 - 发过论文没?专利呢?
2020-03-19 官网流程启动,正式在官网投递简历
牛客网 笔试 1h 2020-03-25 16:00
本来预约了字节跳动的面试,但是后面被割了,于是就参加了阿里的笔试
之前已经对阿里笔试题的难度级别有所耳闻,于是抱着会零AC的心态上了
运气比较好,第二道题直接用模拟的方法AC了,第一道题用动规的方法,最后没写完
电话面 四面 38min 2020-03-30 19:50
本来预约了晚上八点半的面试,结果面试官提前打来了,说等下有个会议,所以先提前面了
- 介绍下华为云KVStore比赛
- 你的优化都是在操作系统以上的优化,能否进一步优化?
:索引完全使用哈希索引 - 放开了思考,还有没有其它优化方法?
:自己搞缓存策略,加锁方面的优化,数据压缩 - 磁盘读写本身呢?了解过磁盘硬件层面的优化没?(完全不了解)
- x86的中断处理过程?中断现场怎么保存?
:中断向量表,内核栈(中断栈) - 学习过程中有没有什么特别困难的经历?(强答了某个项目,现在都不知道怎么答好)
- 学的课程有没有觉得很难的,考得不太好?
:射频,电磁场电磁波,其它都还好吧 - 微积分里面连续的定义能不能描述下(已经忘了)
△x->0时,△y->0 - 前面两轮面试有哪些问题回答得不好?
:第三轮印象深刻 - KV分离和KV合一的方案比较,现在会怎么回答?
:以4K的整数倍写入性能会更好
:KV合一存储的话构建索引需要遍历磁盘所有数据,而KV分离存储只需要读取Key那部分数据就行
:一次flush一条记录性能太低,无法跑满磁盘IO带宽,通过mmap实现每次flush多条记录 - 业界常用的KV引擎有没有调研过?
:三面之后专门去看了LevelDB和Redis - LevelDB和RocksDB的区别?
:RocksDB没调研过(看了LevelDB又来了个RocksDB) - 介绍下RTSP流媒体服务器的网络模型
:Reactor模式,基于非阻塞IO + IO复用,IO复用使用epoll,epoll采用LT模式 - select,poll,epoll的区别是什么?poll怎么优化文件描述符的上限?
:select有三个缺点...
:poll通过链表优化 - epoll从O(n)优化到O(1)怎么做的?
:红黑树 + 注册中断 + 就绪列表 - 为什么使用LT模式而不使用ET模式?出于什么考虑?
:LT和ET的区别,触发条件不同
:ET每次都要读走全部数据,LT编程更简单 - 在你的项目场景下,为什么ET比LT好?
:我的项目并发要求不高,应该都是差不多的
在并发量很高的情况下ET会优于LT,因为减少了触发次数
阿里会议 HR面 25min 2020-04-07 15:30
- 自我介绍
- 介绍下项目
- RTSP流媒体服务器的场景
- 专业是通信与信息系统,为什么要投阿里云存储?你的内推人是谁?
- 笔试50分是怎么回事?
- 保研吗?有没有科研成果?
- 专利具体是关于哪方面的?
- 你自己的性格有哪些优点和缺点?
2020-04-10 上晚上十点半收到offer call
从内推简历到offer call中间经历了差不多1个多月,阿里的流程还是有点漫长的,阿里的面试给人一种没有底的感觉,面完一面和三面都感觉自己是已经挂了的状态。几乎没被问到多少基础,都是项目和拓展性的问题比较多,这些问题也不好回答,手撕代码也不多,面试时间都不长,感觉有部分运气在里面,只是侥幸被认可了,还是要继续努力啊
#实习##面经##阿里云##C++工程师#