面试这么久了,感觉应该出个笔记,记录一下被问到的问题
操作系统
大小端
计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。举例来说,数值0x12345678共有四个字节,从高到低为12 34 56 78
大端:高位字节在低地址 小端:高位字节在高地址 参考链接
- 大端:基于其存储特点,符号位在所表示的数据的内存的第一个字节中,便于快速判断数据的正负和大小(CPU做数值运算时从内存中依顺序依次从低位地址到高位地址取数据进行运算,大端就会最先拿到数据的(高字节的)符号位))
- 小端:基于其存储特点,内存的低地址处存放低字节,所以在强制转换数据时不需要调整字节的内容(比如,把int—4字节强制转换成short—2字节,就可以直接把int数据存储的前两个字节给short就行,因为其前两个字节刚好就是最低的两个字节,符合转换逻辑;另外CPU做数值运算时从内存中依顺序依次从低位地址到高位地址取数据进行运算,开始只管取值,最后刷新最高位地址的符号位就行,这样的运算方式会更高效一些)
参考链接
int main(){
int x = 0x12345678;
short y = short(x);
cout << y << endl;
return 0;
}
- 为什么要有大小端
不同的CPU厂商并没有达成一致:
- x86,MOS Technology 6502,Z80,VAX,PDP-11等处理器为Little endian
- Motorola 6800,Motorola 68000,PowerPC 970,System/370,SPARC(除V9外)等处理器为Big endian
- ARM, PowerPC (除PowerPC 970外), DEC Alpha, SPARC V9, MIPS, PA-RISC and IA64的字节序是可配置的
主机字节序不管是大端还是小端并没有关系。问题是,网络的出现使得计算机可以通信了。通信,就意味着相处,相处必须得有共同语言啊,得说普通话,要不然就容易会错意,下了一个小时的小电影发现打不开,理解错误了!(参考链接 这个作者说话害挺有意思)
TCP/IP协议规定使用“大端”字节序为网络字节序,其他不使用大端的计算机发送数据的时候必须要将自己的主机字节序转换为网络字节序(即“大端”字节序),接收到的数据再转换为自己的主机字节序。这样就与CPU、操作系统无关了,实现了网络通信的标准化。BSD Socket提供了封装好的转换接口,方便程序员使用。包括从主机字节序到网络字节序的转换函数:htons、htonl;从网络字节序到主机字节序的转换函数:ntohs、ntohl
上下文切换
c/c++
内存释放free函数如何知道要释放多少内存
malloc如何工作
使用malloc分配内存时候根据参数指定的大小,分配一块内存,然后返回这块内存的起始位置给调用者(返回给调用者一个指针p)。但这个指针并不是真正的起始位置,真正的指针在malloc返回指针 p 的前面,内存分配器在 p 的前面用两个字节的空间来存放分配的内存大小信息。
参考链接 从参考链接内容可以看到,在p的前面16字节处存放分配的内存大小
因此内存释放free函数可以直接通过该值释放相应的内存
程序如何根据变量名在内存中找到存放这个变量的地址
- C++对变量名不作存储,在汇编以后不会出现变量名;
- 变量名作用只是用于方便编译成汇编代码,方便人阅读
内联函数和宏定义有什么区别
- 内联函数在编译时展开,而宏在预编译时展开
- 在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换
- 内联函数可以进行诸如类型安全检查、语句是否正确等编译功能,宏不具有这样的功能
- 宏在定义时要小心处理宏参数,一般用括号括起来,否则容易出现二义性。而内联函数不会出现二义性。
线程安全
当多个线程同时去访问一个对象时,就可能会出现线程安全问题。 多个线程访问了相同的资源,如,同一内存区(变量,数组,或对象)、系统(数据库,web services等)或文件。实际上,这些问题只有在一或多个线程向这些资源做了写操作时才有可能发生,只要资源没有发生变化,多个线程读取相同的资源就是安全的。
STL如何解决线程安全
- 锁
多读少写的场景可以用读写锁(也叫共享独占锁)
线程间通信方式
struct和union有什么区别
字节对齐
网络
get和post有什么区别
OSI七层协议,传输层网络层都有哪些协议
其他
如果在一个页面输入注册信息,返回错误,再在这个页面输入注册信息时显示账户已注册,可能原因有哪些
用一个vector存储一个歌单,想要实现随机播放,有哪些方式
|