网易互娱(C++服务端一面)(未出结果)
首先面试官人挺好的。
开始:自我介绍与项目介绍
项目拷打:我的项目是一个异步RPC框架作为服务端,还有客户端,刚开始没表达清楚。以为只有服务端
问:你的服务端里面,用户ID持久化问题,每次消息过来会不会落盘,如果只存在缓存里面是不是会造成信息丢失。
答:我刚才没说清楚,一共实现了两个业务功能,用户请求验证码,用户请求登录。用户消息携带用户ID(usr_ID)从客户端打过来的,接收之后就会落盘,存到数据库里面,会有一个map<usr_ID,code>,code是返回给客户端的验证码,这一步是为了利用缓存,如果用户继续请求登录,就会先从map里面查询了,如果查不到,从数据库里面找,是实现了数据落盘的
建议:你这个异步RPC框架是单进程的模型,单Reactor多线程模型,你后面可以考虑到升级到多进程看怎么实现,还有就是可以多提添加一些业务。
开始问算法场景题:
1.双栈实现队列:一个栈当进栈,一个栈当出栈,push(),pop()。push()就推入进栈,pop就从出栈出,如果出栈为空,从进栈里面移动过来。特殊情况:出栈进栈均为空,返回empty。
2.给你一个集合,每次都会往这个集合里面插入一个数字,然后求插入后的集合的中位数,给出思路,及空间,时间复杂度
思路:利用vector<int> nums作为容器载体,每次插入,都会保证插入后有序。一次插入操作,首先要利用集合有序的特点,利用二分查找要插入位置,找到后就要考虑向后移动元素,时间复杂度就是O(n+logn) = O(n);然后会有一个变量为size,代表着当前vector的大小,然后就可以算中位数了,如果size%2 == 0,偶数,那就取中间两个数(nums[size/2] + nums[size/2 - 1]) / 2;奇数就取nums[size/2]。
3.多态:静态多态和动态多态。静态多态多态为编译期实现,主要有函数重载和模板类,动态多态的原理是vptr和vtable(虚指针和虚表)。通过基类指针/引用调用虚函数实现。
4.智能指针:独占指针:unique_ptr,共享指针:shared_ptr,弱引用指针:weak_ptr
问:unique_ptr能被强制抢占吗,对象所有权能转移吗?
答:不能被强制抢占,但是可以对象所有权可以转移。unique_ptr本质上是封装的了裸指针和构造析构函数,内部的拷贝构造和赋值运算符被显式删除,无法拷贝赋值抢夺所有权。对象所有权通过std::move()函数,实现将对象的所有权转移到了新的智能指针(unique,shared,weak都可以。
问:共享指针shared_ptr底层是怎么实现的?
答:共享指针有一个控制块的结构,控制块里里面存放引用计数,分为强引用计数,和弱引用计数。被强引用了计数+1,失去强引用计数-1,弱引用计数为weak_ptr指向了该对象才会+1,只有当两个引用计数都为0后才会销毁对象和控制块
问:shared_ptr有什么注意的问题?
答:两个对象互相循环引用,造成对象无法析构,内存发生泄漏。通过引入weak_ptr来解决,weak_ptr只观察,强引用计数不会增加。shared_ptr的计数增减是原子操作,但是多线程环境下,对于指针的引用,还有对指向对象资源的访问都不是线程安全的
5.问:你了解其他编程语言吗?
答:了解JAVA,python,Node。
6.问:你知道JAVA里面的指针吗?
答:您还真问住我了,(面试官跟我相视一笑),个人猜测是对共享指针shared_ptr的延伸,因为java里面的引用也就是封装好的智能指针,用于自动回收,防止泄漏。
7.问:说说vector和list?
vector是动态数组,本质是顺序表,list底层是双向链表,本质是链表。
8.问:对于vector,我想减少动态扩容的次数该怎么办?
答:我答:初始化vector时通过reserve()预先分配capacity。批量插入,先有一个vector<T> buffer,预分配了大小,先往该buffer里面插入,如果满了,用insert()插入保存数据的vector.然后用swap将buffer清空,内存也释放掉了。
9.重点:问:好,如果我预分配一亿的大小,然后直接把它删除为0个,直接删空,vector会自动缩容吗?(贴主没答好)
答:不会,就算你直接干到0,那这一亿大小的内存也不会释放。C++,std::vector没有自动缩容机制,删光元素,size()会变为0,capacity还是一亿的大小。为什么不会自动缩容呢?因为已经有自动扩容机制了,你再自动缩容,频繁开辟销毁空间的I/O操作,vector的性能就炸了呀,然后迭代器也会失效,空间换时间的策略默认就是不主动释放内存
ps:贴主当时答的是,可能C++20,17会有新机制实现自动缩容吧,然后扩容跟缩容应该是配套的。(那还说啥呢,痛失不知道多少分)
而且,你问这种问题,你真要预分配一亿大小的内存,你不会被领导吊吗哈哈哈。当然面试官只是考察是否真的理解vector的设计理念。
10.问:说一下unordered_map和map吧
答:unordered_map是哈希表,无序;map是红黑树,有序。
问:你讲讲map为什么用红黑树实现,讲讲特点?为什么不用二叉平衡搜索树(AVL)树
答:红黑树和AVL首先都是二叉搜索树,二叉搜索树会在集合有序的情况下,退化为链表,所以有了AVL树和红黑树,AVL的特点就是任一节点的左右子树树高绝对值差不能超过1,而红黑树的性质就是:左根右、不红红、根叶黑、黑路同。AVL树在构造的时候调正的次数要比红黑树调整的次数多,但是查询效率比红黑树高,但是实际应用时还是选择了红黑树,因为红黑树构造时具有更少的调正操作。
11.讲一下为啥TCP握手三次,挥手四次
答:首先防止历史连接错误重连,造成服务器资源浪费。挥手其实简化成三次,其实就在于客户端给服务端发送FIN报文,这个时候服务端会返回ACK,但是不会返回FIN,因为还有数据没传完,但是如果数据传完了,FIN+ACK就会一起传送给服务端,然后客户端再发个确认ACK,服务端就断开连接了。
反问:
我:网易实习生岗位竞争激烈吗?
答:挺激烈的。你是第一次面试吗?
我:不是,之前面过腾讯IEG北极光游戏后台,进HR面被横向了
答:给你一些建议吧,你的表述有时候太繁琐了,可能你会,也表达出来了,但是就是花费时间太长了,导致也没时间多问你一些问题,你明白啥意思吧Ps:意思就是今天其实还应该再问一些问题,因为你在其他问题上花费时间太长了,所以就不能多得分
我:好的,明白明白,谢谢您
答:好,那今天就到这里
总结:问的确实深入,考察你是否真正的用过这些基础语法,我觉得最典型的就行vector<>的缩容问题了,这也侧面印证了候选人确实多,问的也确实底层了。如果贴主的回答不正确,不准确,欢迎各位大佬批评指正。
一些题外话:也算是一些求助吧,贴主本身是学院本,双非(重邮)硕,均为软件工程专业,去年7月份,脑子一热要搞C++后端,冲游戏后台开发,冲网易冲腾讯。现实是很残酷的,楼主现在相关实习都找不到,目前待定的方向就是学一下QT,就去做仿真开发了,不考虑学前端了,也就意味着与互联网大厂无缘了,但是我还是想冲击一下游戏后台开发,但是现在真的很迷惘,所以想走后端的大佬们一定要学JAVA和GO,优先学GO。如果看到该贴朋友觉得可能有一些C++从业经验,并愿意提供帮助,请在评论区留言,真的不甚感激。
#重来一次,你会对开始求职的自己说#
查看13道真题和解析