这是一面,不知道有没有通过。整个面试持续接近一个小时,问的主要都是C++,操作系统,网络等基础知识。现在抽空将这些问题整理一下,做个自我总结吧。
PS:每一道题都是回答一点之后,然后根据你的回答深入的追问。所以回答问题也要有技巧,不能自己给自己挖坑。
一、问题列表
1、const有哪些用法,结合自己项目谈谈。接着问了const和宏定义的区别。
2、sizeof的用法,顺带问了字节对齐,sizeof求指针,求char*,string,特别问了一下sizeof("abc")的结果。
3、全局变量,局部变量,静态变量的区别。
4、使用malloc时要注意哪些地方,然后就是问和new的区别?
5、问我看了哪些有关C++的书籍?面试官顺便给我推荐《C++对象模型》这边书?
6、问我在项目中使用了哪些STL?
7、C++中多继承中,子类对象构造顺序?问我继承底层是怎么实现的?
8、问我在Linux环境中编程多吗?我回答没怎么用过,他就没问Linux方面的知识,所以面后台的准备一下Linux编程会有一定的优势的。
9、深拷贝和浅拷贝什么意思?区别?
10、字节序是什么?
11、可重入是什么?
12、多线程安全问题?
13、进程间通信方式?共享内存分配在什么区?共享内存要不要经过内核?
14、互斥锁能在进程间传递吗?
15、2g内存能全部给一个进程使用吗?
16、TCP滑动窗口怎么工作?
二、问题解答
1、const
我根据平时自己写代码时用到const的地方说了一下,比如说定义常量,常函数或者修饰函数形参,特别形参是引用的时候,然后还说了一些常量指针和指针常量等。
当然这些肯定是不够,需要查资料详细了解const的用法。
参考:C/C++中const用法、C/C++中const用法总结
接下来就是问const和宏定义的区别,这个我回答的不是很好,没答到点子上,所以还要好好整理总结一下。
2、sizeof
首先肯定要知道这个key word是做什么的。sizeof求一个对象占用内存的字节数。其用法当然有很多,要想全部记住也不是很现实的,下面的连接有比较详细的介绍。
注意:sizeof(“abc”)的结果是4,其实就是求一个指针的字节大小。
字节对齐也是一个常问知识点,当时回答的不是很清楚,心里知道是怎么回事但就是不知道该怎么描述。
3、
这个问题首先要弄清楚C++内存地址划分情况。也就是C++中内存有哪几个区?分别存储什么样的数据类型?
4、malloc、free、new,delete
首先要知道malloc的作用是什么,简单地说就是为程序分配指定大小的内存空间,分配的内存空间位于堆区。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。 还有其他比较详细的知识点需要自己查资料。
5、略
6、有关STL的知识,我并不太清楚,只是平时做项目的时候会用到常见的STL,比如vector、map等结构,至于这些结构如何工作的,我也没有深入研究过,后续会慢慢看一些这方面的书籍。
7、略,有关继承的知识,需要另找其他资料复习;
8、略;
9、这道题我直接回答的是不清楚。后来查资料才慢慢理解了一些。首先要理解什么是深拷贝,什么是浅拷贝,其次就是理解浅拷贝会带来什么问题?
深拷贝,通俗的理解就是不仅复制当前值,还要深入复制指针指向内存中的值
10、字节序
这道题我直接回答的是不清楚,后来查资料才知道就是指的大小端,网络字节序,主机字节序。对于大小端这个问题我是知道,但是回答的时候却不清楚,都怪自己了解不全面,吸取教训。
11/12、可重入和线程安全
可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的
在多线程或有异常控制流的情况下,当某个函数运行到中途时,控制流(也就是当前指令序列)就有可能被打断而去执行另一个函数.而"另一个函数"很有可能是它本身.
如果在这种情况下不会出现问题,比如说数据或状态不会被破坏,行为确定。那么这个函数就被称做"可重入"的.
补充:
函数是可重入(reentrant)的,是指对于相同的(并且合法的)函数参数(包括无参函数的情况),多次调用此函数产生的行为是可预期的,即函数的行为一致,或者结果相同。不能保证这一点的函数称为不可重入(non-reentrant)函数。
13、进程间通信方式
共享内存:为了在多个进程间交换信息,内核专门留出了一块内存区,(尽在建立共享内存区域时需要系统调用,一旦建立好共享内存,所有的访问都为常规的内存访问,不需要内核帮助,当然,共享内存释放也需要内核调用,详见《操作系统概念第七版P85》)这段内存区可以由需要访问的进程将其映射到自己的私有地址空间。
Linux中 共享内存的实现分为两个步骤:第一步是创建共享内存,这里用到的函数是shmget(),也就是从内存中获得一段共享内存区域;第二步是映射共享内存,也就是把这段创建的共享内存映射到具体的进程空间中,这里使用的函数是shmat()。到这里,就可以使用这段共享内存了,也就是可以使用不带缓冲的I/O读写命令对其进行操作。除此之外,还有撤销映射的操作,其函数为shmdt()。
14、互斥锁
Windows多进程下使用CreateMutex
可以先调用OpenMutex方法,查看互斥量创建没有,如果创建了就会返回共有的句柄了,如果没创建,那你调用CreateMutex来创建
你现在Mutex在谁手里,只有owner能够Release
多个进程不同时刻是可以支配同一个mutex的。这里的关键是锁的所有者owner要说清楚:所有者不一定是创建者CreateMutex,而是加锁的进程,什么是加锁的进程?谁waitfor了,谁就加锁,就是该mutex当前的owner,必须由该进程Release。其它进程才能waitfor。关键是每个mutex个实例(object)中有一个数据成员,会记录它的owner。
A进程CreateMutex设置第2个BOOLbInitialOwner, // 初始化互斥对象的所有者,则A相当于加锁,是该mutex当前的owner,释放后,其它进程才可以waitfor。如果CreateMutex第2个参数是false,则任何进程都可以waitfor,并立即成为该mutex的owner。
另外,一个进程如果是某mutex的owner,可以连续多次waitfor该锁,object中有一个成员计数。要注意的是,一次Release是解不开n次加锁的,可能会造成调试中的困扰。
15、
在32位系统下理论上是4G.在windows环境下,windows下系统空间与用户空间各占一半,操作系统要占用2G,用户可以用的空间是2G,但还有其它一些应用程序也占内存,所以1G左右应该没问题
16、略