代码
- 找出如下代码的问题
struct XX {
std::list<std::string> name;
};
int main()
{
XX* p = (XX*)malloc(sizeof(XX));
if (p != NULL) {
p->name.push_back("aa");
p->name.push_back("bb");
free(p);
}
return 0;
}
- 求值
char* (*a)[3][4];
char* b[3][4];
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
char* (*a)[3][4]
,a
是一个函数指针。char* b[3][4]
,b
是一个数组名。
答案:4 48
- 指针转换
int c = (int)(((int*)0) + 4);
求c
的值是多少。
答案:16。0被转换为了一个指针地址,((int*)0) + 4
操作是从0地址开始偏移4个地址,每偏移一个地址(指针加一),对应的地址要加sizeof(int)
即4个长度。加4后该地址的值是16。如下图:
问题
-
用位移来计算除法。除以2,向右移1位,除以4,向右移2位。。。
-
fread/read的区别
fread带缓冲,read不带缓冲。fread每次都会读比要求更多的数据,然后放到缓冲区中,这样下次再读数据只需要到缓冲区中去取就可以了。
缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓冲区”依此读入接收的变量。执行写文件的操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存 “缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,执行速度就快、效率高。一般来说,文件“缓冲区”的大小随机器而定。 fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等是带缓冲的。 -
系统调用比函数调用耗时有多少,耗时在哪里?
函数调用是一条CALL或者JMP指令。系统调用是一条INT(软件中断)指令,或者是后来Intel推出的SYSCALL/SYSENTER/SYSEXIT指令(只要CPU和Linux内核都支持sysenter指令,则标准库libc中的封装函数就可以使用它)。
系统调用开销大,关键不在于切换用户栈、内核栈,保存寄存器信息,关键在于页表切换,导致的CPU缓存失效。内核空间跟用户空间地址空间相差很大,指令预测系统也会失效。汇编语言指令INT由于要执行几个一致性和安全性检查,所以速度慢(参考于《深入理解LINUX内核》第十章系统调用-通过sysenter指令发出系统调用) -
系统调用参数传递。
参数传递是通过先将用户态的参数存入CPU寄存器,进入内核态后,再将CPU寄存器中的数据拷贝到内核态堆栈中。参考于《深入理解LINUX内核》第十章系统调用-参数传递) -
函数调用的整个流程。esp、ebp指针的移动,返回等操作。
-
如何定位到开源库的内存泄露?比如是你使用的开源库方式不对,没有成套,导致泄露,请定位到点。可以使用符号加载顺序定位。
-
动态库链接加载的过程
-
网络分成几层,网络层、传输层的区别,有哪些功能。
-
a.so中有一个函数fun,二进制exe中也有一个fun函数,如何引用,或者引用顺序如何。
-
weak_ptr如何实现的
weak_ptr类中通过原始指针地址判断是否是同一个地址,来处理对weak_count的增加。 -
共享内存的使用
问题:当前使用的QSharedMemory
,使用了对应的QSharedMemory::lock()
接口做锁使用,而其有一个问题是,多进程间可以锁定,同一个进程内存的多线程确无法加锁,即同一个进程内的其他线程依旧可以进入到对应的临界区操作。
使用:创建、映射、解引用共享内存。
同步问题:Windows下可以使用事件来同步。m_hReadEvent = CreateEvent(NULL, true, true, L"Global\\ShareMemoryReadEvent");
创建事件,调用WaitForSingleObject
等待事件置位,操作完后调用SetEvent
来置位。 -
LRU算法、cache算法 1.小林手撕 LRU 算法 2.手撕 LRU 算法(更正版)
-
红黑树的具体实现,为何插入会快?
-
哈希算法中桶的增长策略。
按两倍的增加,取最近的一个质数作为最新的桶的长度,并重新计算所有的数据的哈希表的位置。 -
volatile
lock和unlock之间的代码指令是否会被编译器重排
参考:C/C++中volatile关键字介绍 -
constexpr
是一种很强的约束,更好地保证程序的正确语义不被破坏。
编译器可以在编译期对constexpr的代码进行非常大的优化,比如将用到的constexpr表达式都直接替换成最终结果等。
相比宏来说,没有额外的开销,但更安全可靠。
参考:C++总结:C++中的const和constexpr -
内存泄露定位
Valgrind原理:valgrind如何工作?
windows下用_CrtDumpMemoryLeaks()
接口。如下:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>
using namespace std;
void GetMemory(char *p, int num)
{
p = (char*)malloc(sizeof(char) * num);
}
int main(int argc,char** argv)
{
char *str = NULL;
GetMemory(str, 100);
cout<<"Memory leak test!"<<endl;
_CrtDumpMemoryLeaks();
return 0;
}
网友评论