C++面试题二

本文主要探讨了C++中的预处理命令,结构体的内存对齐原则及其原因,函数的重载、覆盖和隐藏概念,以及进程中的变量差异。同时涉及了表达式优先级和Redis集群模式中的MOVED与ASK区别。

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中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值