2018-春,深信服笔试(待完善)

  今天晚上接到笔试通知,感悟很深,自己学得不够仔细,因为今天考完,试卷还没出来,先记录一些自己记得的题目。
  因为是在线笔试,要开摄像头,而我的辣鸡笔记本摄像头坏了,借了一个朋友的笔记本在线笔试,没有IDE,很痛苦,编程题没法调试,编写代码格式对齐也很难受,很久没用STL,方法也记不得几个。
  然后是选择题,有多选和单选,做完很难受。

选择题

  1、int型全局变量、局部变量、静态变量未初始化,它们的值是什么。
  全局变量、静态变量未初始化,值默认为0,而局部变量未初始化使用则会报错。
  2、struct与union的区别,以及字节对齐方式(我被这个坑过两次,很久没学忘记了)
  a.在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct 可以存储多个成员信息,而Union每个成员会用同一个存储空间,只能存储最后一个成员的信息。
  b.都是由多个不同的数据类型成员组成,但在任何同一时刻,Union只存放了一个被先选中的成员,而结构体的所有成员都存在。
  c .对于Union的不同成员赋值,将会对其他成员重写,原来成员的值就不存在了,而对于struct 的不同成员赋值 是互不影响的。
  d.复合数据类型,union,struct,class的对齐方式为成员中数据类型的size最大的成员的对齐方式
  例如:

union test {
    int a;
    char b[13];
};

test a;
sizeof(a);  //16  按union中sizeof(int)>sizeof(char),按int对齐

  3、大小端
  这个可以勉强算是跟着上面来,
  大端模式
  是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

  小端模式
  是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

  通过使用一个十六进制的值,用指针去访问,就可以看出是否是大小端,或者利用union也可以。
  如 int x=0X11112222,char *p=(char*)&x,然后按十六进制输出printf("%x",*p);,小端,就会输出22,大端则是11.

  4、多线程
  之前看过并发教程第一二章,后面放了,所以很多知识都忘了,打算重新写一篇文章记录线程与进程的一些学习记录,也好好的理解进程与线程的概念,经历过秋招到现在面试的几家(只去过两三家),面试官都会问操作系统,多线程什么的,这方面知识是我最欠缺的,所以打算好好补一下。

  5、判断变量存放位置
  变量在内存地址的分布为:堆-栈-代码区-全局静态-常量数据
  同一区域的各变量按声明的顺序在内存的中依次由低到高分配空间(只有未赋值的全局变量是个例外)。
  全局变量和静态变量如果不赋值,默认为0。 栈中的变量如果不赋值,则是一个随机的数据。
  编译器会认为全局变量和静态变量是等同的,已初始化的全局变量和静态变量分配在一起,未初始化的全局变量和静态变量分配在另一起。
  堆的地址生长方向是低地址向高地址,而栈是高地址向低地址。

  6、c字符串
  在选择题看到给char ch[4]赋值“hell” 的时候,我感觉会报错,但是又很纠结,没试过这样赋值,因为“hell”中含有’\0‘,考完之后自己去试了一下,的确编译完成执行的时候会报错Stack around the variable 'ch' was corrupted.,也就是在栈中分配ch的内存的时候,就分配了4字节,而我们赋值溢出了,所以stack就被破坏了。

编程题

  二进制位反序
  这道题,看到的本来想法是,先用字符数组去存放求出的二进制数,然后倒着把值算出来,然而,在考试前几个小时,我在网上偶然看过这道题,再然而,我压根没记住那个算法是怎么设计的,我就大概记得是位运算,所以我特么把这个题给放了,一句代码都没写,我也不知道我那时候怎么想的,那时候在想用位运算去解出,而不是用我自己的想法去做。
我的代码:

unsigned int reverse(unsigned int num)
{
    int ch[1000];
    int index = 0;
    while (num / 2 != 0) {
        ch[index] = num % 2;
        num /= 2;
        index++;
    }
    ch[index] = 1;
    ch[index + 1] = '\0';
    int ret = 0;
    for (int i = 0; i <= index; i++) {
        ret += ch[i] * pow(2, index-i);
    }
    return ret;
}

别人的代码:
  不懂二进制运算的话的确有些难度,其实也就是把num从二进制低位加到高位,ret通过左移把低位移动到高位。

unsigned int reverse(unsigned int num)
{

    unsigned int ret = 0;
    for (int i = 0; i < 32; i++, num /= 2)
        ret = ret * 2 + num % 2;
    return ret;
}

  计算围棋的气:
  这道题让我很难受,看到题就想到用BFS做,我的做法是写出一个point类,然后利用stack来实现BFS,但是由于没有IDE,我开始想着用不用STL的stack….因为我记不住这个函数,好像有pop和push来着,有这两个的确也就足够了,那么问题就来了,调试,没有IDE,在线编辑器只提供对错,我毫无办法。
  解题思路,要先知道怎么才算是气,从某个棋子出发,如果遇到非同色棋子,或者是无棋子,那么这个位置有一个气。
  于是就很简单了,利用stack先进后出,把初始的位置压入栈,然后扩展身边的节点,符合以上条件,就压栈,直到遍历到stack为空,也就是遍历了所有的节点,然后就把计数的数组值都加起来就可以。

  调整最小堆:
  这个题是看代码,填空,由于在没有IDE的时候,莫名其妙的发呆,浪费了很多时间,所以做到这没多少时间,就随便看了看代码,可能是因为着急,没看到函数的参数是什么意思,我自己之前也写过一个调整最小堆,我卡在了我自己的想法,没好好的分析题目代码的含义。

题目代码(已填充的):

static void heap_arrange(int arr[], int cur, int cnt)  //调整为小顶堆
{
    int heaptop_val = arr[cur]; //堆顶的值
    while (cur < cnt) {
        int left = 2 * cur + 1;
        int right = 2 * cur + 2;
        int min = -1;
        int min_val = heaptop_val;//填空
        if (left < cnt && arr[left] < min_val) { //检查是否比左节点大
            min = left;
            min_val = arr[left];
        }
        if (right < cnt && arr[right] < min_val) {//检查是否比右节点大
            min = right;
        }
        if (min == -1)
            break;
        arr[cur] = arr[min]; //填空
        cur = min;//填空
    }
    arr[cur] = heaptop_val;//填空
}

我自己之前实现的调整最小堆: //一对比代码写得很丑…哈哈…

void adjust_heap(vector<int>&ary, int n) {
    if (n == 1) {
        return;
    }
    int index = pow(2, n - 2)-1;
    int len = ary.size() - 1;
    for (int i = index; i <= 2*index; i++) {
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        if (left < len &&right<=len) {
            int vleft = ary[left];
            int vright = ary[right];
            int min = ary[i];
            if (vleft < min) {
                min = vleft;
            }
            if (vright < min) {
                min = vright;
            }
            int tmpindex = (min == vleft) ? left : -1;
            if (tmpindex == -1) {
                tmpindex = (min == vright) ? right : -1;
            }
            if (tmpindex == -1) {
                tmpindex = i;
                continue;
            }
            swap(ary[i], ary[tmpindex]);
        }
        else if ((i * 2 + 1) == len) {
            if (ary[i * 2 + 1] < ary[i]) {
                swap(ary[i * 2 + 1], ary[i]);
            }
        }
    }
    adjust_heap(ary, n - 1);
}

猜你喜欢

转载自blog.csdn.net/qq_21049875/article/details/79575306