1.下列程序输出
#include <iostream>
class Test {
public:
void test() {
std::cout << "No virtual test!" << std::endl;
}
virtual void test2() {
std::cout << "Virtual test!" << std::endl;
}
};
int main(int argc, char** atgv) {
Test *tp = NULL;
tp->test();
tp->test2();
return 0;
}
No virtual test!
// 解析:第二次调用未构造出对象,在0地址除不会有虚表指针,结果不会打印出字符串,其他情况未定义,无法走到后续流程。
2.预处理命令特点
①为了区别一般的语句,预处理命令行都必须以”#”号开始,结尾不加分号;②预处理命令可以放在程序中的任何位置;⑧在程序中凡是以”#”号开始的语句行都是预处理命令行。最常见的预处理有:文件包含,条件编译、布局控制和宏替换4种。
3.结构体sizeof以及alignof
#include <iostream>
struct Date
{
char a;
int b;
int64_t c;
char d;
};
struct Foo {
int i;
float f;
char c;
};
int main(int argc, char** atgv) {
std::cout << sizeof(Date) << std::endl;
std::cout << alignof(Date) << std::endl;
std::cout << alignof(Foo) << std::endl;
std::cout << sizeof(Foo) << std::endl;
return 0;
}
输出:
24
8
4
12
解析:每个成员按类型的大小对齐,即相对于结构体地址的成员地址能被类型大小整除.并且结构体的大小(sizeof(A))必须为成员所含类型中最大值sizeof(int64_t)的整数倍,不够就补空字节,如果Foo对象中包含比int64_t还大的基本类型T,就会以sizeof(T)的整数倍补齐。
4.为什么需要对齐?
(1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
(2)性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐,原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
5.注意以下程序的陷阱
#include <iostream>
int main(int argc, char** atgv) {
char c = 'a';
if ('a' < c <= 'z') {
printf ("Low\n");
} else {
printf("Up\n");
}
if ('a' < c && c <= 'z') {
printf ("Low\n");
} else {
printf("Up\n");
}
return 0;
}
输出:
Low
Up
6.函数重载,覆盖,隐藏
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
7.num变量的地址和值在父子进程中的差异
#include <stdio.h>
#include <iostream>
#include <unistd.h>
int main(){
int pid;
int num=1;
pid = fork();
if (pid > 0) {
num++;
printf("in parent:num:%d addr:%lx\n", num, (uint64_t)(&num));
} else if (pid == 0) {
printf("in child:num:%d addr:%lx\n", num, (uint64_t)(&num));
}
}
答案:
地址一样,值不一样
8.请问经过表达式a = 5 ? 0 : 1的运算,变量a的最终值是?
答案:0,条件运算符的优先级高于赋值运算符
9.redis集群模式中MOVED和ASK的区别?
MOVED在槽的维护权已经转移完毕。
ASK在槽的维护权转移正在进行中,key已经不在当前node中。