网易C++研发工程师一面凉经

又来发凉经了,想知道自己发多少次凉经才能拿到offer。
1. 自我介绍,聊聊项目。
2. C 与C语言内存分配的区别
3. 智能指针的原理
4. 简述下C/S模型的代码逻辑
5. select和epoll的区别
6. stl模板使用过哪些?挑几个聊聊原理?他们的优缺点是什么?
7. static的用法有哪些?
8. 下边代码片段中各个变量的值是什么?
int x = 2, y = 2, t = 0;
t = x   ||   y;
9. 下边代码段的输入是什么?
int func(int n) {
    static int i = 1;
    if (n > 5)
        return n;
    n  = i;
      i;
    return func(n);
}

int main() {
    func(1);
    return 0;
}
10. 链表反转

------------------------------------------------------------------------------------------------------------------------
分割线,下边写写自己的理解,是面试结束后再整理的,不一定正确和全面,督促自己面向面试学习,欢迎交流讨论。
-------------------------------------------------------------------------------------------------------------------------
2. C 与C语言内存分配的区别
C 使用new和delete操作符来完成内存的分配和释放,C语言使用malloc和free两个函数申请空间与释放。malloc只是向操作系统申请指定大小的堆空间,new操作符在申请适合对象大小的空间同时完成对象的初始化。同样free函数只是向操作系统归还指定空间,并不完成对象的析构,而delete操作符能正确调用对象的析构函数。

3. 智能指针的原理
shared_ptr可以在多个对象之间共享一个原始指针,每个复制都会使其中的引用计数 1,而智能指针对象析构时,将会使引用计数-1,当引用计数从1变为0时,表示没有任何对象在使用该指针了,因此会调用delete释放相应的空间。引用计数可以是一个整数或者结构体,多个智能指针内部共享一个引用计数的指针变量,通过指针操作该变量的值,共同维护一个正确的引用数值。
unique_ptr是唯一持有某一个原始指针,主要是通过禁止复制构造函数和使用移动构造函数实现的。移动构造函数是一个右值引用的形参,使用移动语义完成对象所有权的转移,其中并没有对原始对象进行拷贝,而只是将原始指针的所有权移动到另一个智能指针。

4.简述下C/S模型的代码逻辑
大致说了说服务器应该先在某一个端口进行监听,等待服务器的连接。视客户端的数量,决定采用select还是epoll方式处理事件。说到这里就跳到下一个问题。

5. select和epoll的区别
select管理的套接字数量有限制,通常是1024,是使用bit位来管理的,同时系统调用和系统返回时,内核和用户空间都需要发生大量句柄的复制操作,同时对select的返回需要进行遍历操作,才能找到发生事件 的套接字。
epoll使用了三个阶段,epoll_create、epoll_ctl、epoll_wait,分别创建epoll句柄,添加修改删除套接字事件,等待套接字事件发生。这其中使用红黑树来管理套接字句柄集合,这样就没有数量的限制,同时epoll_ctl对事件的管理也非常高效。epoll使用的mmap(内存映射),将用户空间和内核空间映射到同一块实存,这样既有内存访问的保护性,也可以避免用户空间与内核空间的反复复制。最后在epoll_wait的调用中,epoll会将在内部记录的发生的事件从双端链表中复制到events数组中,同时返回发生事件的数组,这样可以避免用户的无效遍历。

6. stl模板使用过哪些?挑几个聊聊原理?他们的优缺点是什么?
vector,内部是连续空间,使用start,finish,end_of_storage几个成员变量来快速获得容量,使用大小,头元素、尾元素等信息。使用push_back、insert会造成扩容操作,具体为当前大小为n,新增大小为m,如果m n超过当前容量,就会进行扩容,扩容后大小为max(2*n, m n)。扩容的步骤为:分配新的空间、复制之前的元素、构造新的元素、释放之前的空间。同时使用vector::clear()不会释放空间,只是将其中的元素清空,若需要立即释放空间,不待变量过期,可以使用和一个空的vector进行swap操作,这样就可以将内存还给操作系统。vector优点在于能够自动申请堆空间,自动扩容,不需要手动操作,也可以保证内存的正确回收。但扩容的过程可能会导致元素大量的复制,造成效率低下,同时会使得迭代器失效,造成程序崩溃。

7. static的用法有哪些?
(1)修饰局部变量。局部变量的生存期为声明之后,直至当前代码块结束。若使用static声明,该变量将变为静态持续性,存放在静态存储区,存在于整个程序运行周期。同时保证每个进入该代码块,变量保持上一次退出时的值。
(2)修饰全局变量。会改变全局变量的链接性,使用static修饰后,全局变量由外部链接性变为内存链接性,这样其他源文件不能使用extern变量使用该变量,该变量只能在当前文件内共享访问。
(3)修饰函数。函数默认具有外部链接性,同普通全局变量一样。使用static修饰后,其他源文件不能使用extern来使用该函数。该函数为内部链接性,当前文件可访问。
(4)修饰成员变量。修饰成员变量后,该变量将不在类对象的内存布局当中,存在于静态存储区。该变量存在于类对象声明之前,即使没有任何一个类对象声明,该变量依然存在。所有的类对象共享一份实例。
(5)修饰成员函数。静态成员函数不能访问普通成员变量,只能访问静态成员变量。同时不需要通过类实例进行调用。

8. 两条竖杠为逻辑或,一条为比特或。这里为逻辑或,先计算前半部分表达式的值,如果为真,则不计算后半表达时。如果为假则计算后半表达式。前半表达式为x ,后缀 运算符,将使x的值 1,返回的是原始值,因此前半表达式的值为2,非0逻辑为真,因此不计算后半表达式 y。所以逻辑表达式的值为真,赋给一个int变量,t = 1。最终t = 1, x = 3, y = 2.

9. static修饰的局部变量,只进行一次初始化操作。
过程依次为 i = 1, n = 1 1= 2;
i = 2; n = 2 2 = 4;
i = 3;n = 4 3 = 7;
n > 7,返回7





#网易##面经##秋招##C++工程师#
全部评论
🤣个人建议啊,只是个人建议,感觉可以多扯扯,比如说new和malloc,可以扯到new的底层实际上也是先malloc再构造函数,然后再扯扯malloc底层是怎么分配的。比如智能指针,再扯扯weak_ptr配合shared_ptr具体怎么解决循环引用的问题。反正你问我个问题,给你从盘古开天辟地说起🤣
点赞 回复
分享
发布于 2019-08-14 12:13
这都凉 网易就不招人了 拒佬
点赞 回复
分享
发布于 2019-08-14 12:12
阅文集团
校招火热招聘中
官网直投
我面的时候最后也是让写一下链表反转。。
点赞 回复
分享
发布于 2019-08-14 12:18
tql
点赞 回复
分享
发布于 2019-08-14 12:45
可以说是很常规题目了
点赞 回复
分享
发布于 2019-08-14 13:02
要是有面试机会我会这样?
点赞 回复
分享
发布于 2019-08-14 14:24
我看没有涉及到计算机网络,操作系统和数据库!这hr已经手下留情啦!哈哈哈
点赞 回复
分享
发布于 2019-08-14 15:22
好好努力,一定会有好运的😁
点赞 回复
分享
发布于 2019-08-14 15:22
老哥哪个院的
点赞 回复
分享
发布于 2019-08-20 18:10

相关推荐

8 110 评论
分享
牛客网
牛客企业服务