深信服2018年实习生校园招聘总结

时间:2022-07-22 18:50:39

参加了深信服2018届实习生的笔试,面试,顺利拿到offer,下面记录一下自己在这次笔试和面试的一下问题,题目很基础,但是是多选题,非常容易出错,及其考验基本功。

1下面代码能输出hell的是:

A.char buf[4]="hell";
B.char buf[]="hell";
C.char buf[8]=0;memcpy(buf,"hello",strlen("hell"));
D.char buf[4];strcpy(buf,"hell");
//答案bc,因为ad的内存分配不过,出现错误

2.简单略。

3 .下面代码的运行结果:
这里注意一个宏定义的函数功能,他传进去的arr是数组的指针,因此此题有解,而不是运行错误,本题答案为2。

#include<iostream>
using namespace std;
#define ADD(arr,cnt) \
do { \
int i; \
for (i = 0; i < cnt; ++i){ \
ret += arr[i]; \
} \
}while(0) //只会执行一次循环
int main(){
int arr[2][2] = { 1,1 };
//cout << arr[1][1] << arr[1][0] << endl;
int i, ret = 0;
for (i = 0; i < 2; i++)
ADD(arr[i], 2);
printf("%d", ret);
}

4.下代码运行结果

//t.a=1,t.b=0,因此错误
1.struct {int a, b;}t = { 1 };printf("%d", t.a/t.b);
//a为初始化,错误
2.void func() {
int a;
printf("%d", a);
}
//静态局部变化自动初始化为0,
3. void func() {
static int a;
printf("%d", a);
}
//全局变量初始化为0
4. int a;
void func() {
printf("%d", a);
}

5.下面代码输出结果

#include<iostream>
using namespace std;
int main(){
int i1 = 0xf0000000;
unsigned int i2 = 0xf0000000;
//cout << i1 << " " << i2 << endl;
i1 >>= 1;
i2 >>= 1;
printf("%08x,%08x", i1, i2);
}

解析:i1为负数,i2为正数,c中的右移为算数右移,因此i1应为oxf80000,i2为0x78000000。

6.过于简单略
7.下面代码输出结果是:

#include<iostream>
using namespace std;
int main(){
signed char c1 = -1;
int i1 = (int)c1;
unsigned char c2 = -1;
int i2 = (int)c2;
int i3 = int(3 * 1.0 / 2 * 3);
cout << i1 << " " << i2 << " " << i3 << endl;
}

解析:有符号的char类型十六进制0xff,转成int要进行符号扩展成0xffffffff,因此为-1。声明成无符号-1,0xff,转成255,转成int后为255,i3=4,很简单。

8.简单略。
9.下面代码输出结果是:

#include<iostream>
using namespace std;
int main(){
int a[6][2] = { 1,2,3,4,5,6,7,8,9 };
int *p = a[1];
//cout << *(p++) << endl; //3
//cout << *p++ << endl; //3
int(*q)[2] = &a[1];
printf("%d,%d,%d", *++p, q[0][0], q[1][2]);
}

解析:依次输出4,3,7,int(*q)[2] = &a[1];比较疑惑q[1][2]=7,本来以为会出错的,这里注意q是一个数组指针。

11.32位x86,下面输出结果为:

#include <iostream>
using namespace std;
int main() {
const char* str = "hello";
char str1[] = "he";
cout << sizeof(str) << endl;
cout << sizeof(str1) << endl;
cout << sizeof("hello") << endl;
}

分别输出为4,3,6。
注意什么时候数组会退化成指针,比如如果将数组作为形参传入一个函数是,其将退化成指针。

12.下面代码输出结果:

#include <iostream>
using namespace std;
int get(int val) {
static int s1, s2 = 1;
if (val > 0)
s1 = val;
return s1 + s2;
}
int main() {
cout << get(0) << endl;
cout << get(2) << endl;
cout << get(0) << endl;
}

解析:*1. 注意到声明的类型为static,因此编译器会自动的初始化s1=0,2. s1的值只声明一次,一旦被修改其不会重新赋值为0,因此本题一次输出:1,3,3*。

13. 在32位x86平台,下面代码输出结果:

#include <iostream>
using namespace std;
struct {
int val1;
int val2;
}a = { 1 };
int main() {
int *p = (int *)&a;
p[0] = 2;
cout << p[0] << " " << p[1] << endl;
}

解析:这里a是全局的变量,因此a.val1=1,a.val2=0,而p指向的是a.val1,因此分别输出2,0.

14:32位x86,4字节对齐,下面代码的输出结果为:

#include <iostream>
#pragma pack(4)
using namespace std;
union uni {
struct {
int n3;
}s1;
struct{
int n4;
int n5;
}s2;
};
int main() {
union uni u;
cout << sizeof(u) << endl;
int *p = &u.s2.n4;
memset(&u, 0, sizeof(u));
u.s1.n3 = 1;
u.s2.n4 = 2;
u.s2.n5 = 3;
*p = 4;
cout << u.s1.n3 << " " << u.s2.n4 << " " << u.s2.n5 << endl;
}

解析:首先要明白的是共用体的特性,这里sizeof(u)=8,指针p指向的是共用体的初始地址,这个地址可以使s1.n3或者s2.n4,因此如果改变了p所指向地址的值,那么将会同时改变,他们两个的值。
因此本题,输出的结果为:4,4,3

15. 下面哪些算法不能保证得到最优解(当存在解的时候):

A.Digikstra算法
B.Floyd算法
C.贪婪算法
D.遗传算法

此题,众所周知贪婪不一定得到最优解的,经查阅资料认为,遗传算法也不一定能得到最优解,因此,我个人认为此题应为CD(如有错误,欢迎指正).

16. 有一颗二叉树,其前序遍历为abcdefg,可能的中序遍历有:

A. abcdefg
B. gfedcba
C. gabcdef
D. cdefbag

解析:此题不难,需要注意的是两种遍历之间的关系,此题选择ABD