题目
1 空指针判断
判断下方代码是否存在问题
char* str1 = "hello world!";
char chr_arr[64] = "hello world!";
char* str2;
int i = 2;
sprintf(str2, "hello world %d !", i);
printf("%s %s %s \r\n", str1, str2, chr_arr);
2 数组大小
下边这段代码的输出是?
int a[4] = {1, 2, 3, 4};
printf("%d %d %d %d\r\n", a[1], a[2], a[3], a[4]);
3 字节序
请简述0x11223344在大端和小端中的内存存放情况(32位内存),并简述什么情况下需要注意大小端问题
大端/小端 | baseAddr + 3 | baseAddr + 2 | baseAddr + 1 | baseAddr |
---|---|---|---|---|
大端 | ||||
小端 |
4 多级指针
请简述c,cp,cpp的含义,以及printf(“%x\r\n”, **cpp++);的结果
char* c[] = {"hello", "world", "china", "ready"};
char** cp[] = {c + 3, c + 2, c + 1, c};
char*** cpp = cp;
5 对象中的静态变量
静态对象是否调用构造函数?
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A's Constructor Called " << endl; }
};
class B
{
static A a;
public:
B() { cout << "B's Constructor Called " << endl; }
};
int main()
{
B b;
return 0;
}
6 修改形参
这段代码的输出结果是?
#include <iostream>
#include <string>
using namespace std;
void chg_str(string str) {
str = "ichgit";
}
int main() {
string s = "sarrr";
chg_str(s);
printf("%s\n", s.c_str());
cout << s << endl;
return 0;
}
7 const修饰符
你觉得下面两种写法有区别吗?
int GetInt(void)
const int GetInt(void)
8 new和delete
以下代码存在什么问题
class A {
public:
A(){;}
void showMessage() { MessageBox* box = new MessageBox(); box->exec();};
}
9 简述指针和引用的区别
简述指针和引用的区别
10 QtGui和后台线程问题
如果界面上有一个按钮pushButton,对应槽函数为on_pushButton_clicked(),以下代码会对界面造成什么影响
void on_pushButton_clicked()
{
//apped 512MB data into file "./data.rec"
...
}
11 Vector、List模板
以下代码存不存在问题?
class A {
public :
A(){};
void append(QString s) { _list.append(s); }
void clear() {_list.clear(); }
QString getStringByIndex(unsigned int index) { return _list.at(index); }
private:
QStringList _list;
}
12 TCP通信
请写出一段伪代码,实现TCP Server功能,要求支持多台client同时连接,且当连接数量超过5时,关闭最老的连接
13 栈
如下代码存不存在问题,为什么?
void func()
{
int arg[1024*1024*64];
.....
}
14 请简述如何添加自定义的链接库
15 简述tcp通信和udp通信的区别
16 如何处理tcp的分包和拼包现象
17 如何看待编译器warning和需要注意的warning类别
答案
1 空指针判断
判断下方代码是否存在问题
char* str1 = "hello world!";
char chr_arr[64] = "hello world!";
char* str2;
int i = 2;
sprintf(str2, "hello world %d !", i);
printf("%s %s %s \r\n", str1, str2, chr_arr);
答案:
在sprintf处崩溃,原因是str2为空指针,指向了不存在的内存空间。
基础题
2 数组大小
下边这段代码的输出是?
int a[4] = {1, 2, 3, 4};
printf("%d %d %d %d\r\n", a[1], a[2], a[3], a[4]);
答案:
2 3 4 xxxxxxxx
基础题
最后一个打印是随机的因为a[4]访问越界了。
3 字节序
网络通信和控制FPGA时会常遇到字节序的问题
请简述0x11223344在大端和小端中的内存存放情况(32位内存),并简述什么情况下需要注意大小端问题
大端/小端 | baseAddr + 3 | baseAddr + 2 | baseAddr + 1 | baseAddr |
---|---|---|---|---|
大端 | ||||
小端 |
答案:
大端/小端 | baseAddr + 3 | baseAddr + 2 | baseAddr + 1 | baseAddr |
---|---|---|---|---|
大端 | 0x44 | 0x33 | 0x22 | 0x11 |
小端 | 0x11 | 0x22 | 0x33 | 0x44 |
进阶题
4 多级指针
请简述c,cp,cpp的含义,以及printf(“%x\r\n”, **cpp++);的结果
char* c[] = {"hello", "world", "china", "ready"};
char** cp[] = {c + 3, c + 2, c + 1, c};
char*** cpp = cp;
答案:
指针 | 含义 |
---|---|
c | 指向字符数组(字符串)指针 |
cp | 指向的指针为指向字符串的指针 |
cpp | 指向的指针为指向指向字符串的指针 |
进阶题 |
5 对象中的静态变量
静态对象是否调用构造函数?
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A's Constructor Called " << endl; }
};
class B
{
static A a;
public:
B() { cout << "B's Constructor Called " << endl; }
};
int main()
{
B b;
return 0;
}
答案:
不会执行class A的构造函数,因为static A a是声明,不是定义。需要在类的外部定义B:a = A();
进阶题
6 修改形参
这段代码的输出结果是?
#include <iostream>
#include <string>
using namespace std;
void chg_str(string str) {
str = "ichgit";
}
int main() {
string s = "sarrr";
chg_str(s);
printf("%s\n", s.c_str());
cout << s << endl;
return 0;
}
答案:
sarrr
基础题,形参是值传递而不是地址传递
7 const修饰符
你觉得下面两种写法有区别吗?
int GetInt(void)
const int GetInt(void)
答案:
实际功能没区别,但是第二个const实属多余,且在gcc编译器下,第二种还会报警告
进阶题
8 new和delete
以下代码存在什么问题
class A {
public:
A(){;}
void showMessage() { MessageBox* box = new MessageBox(); box->exec();};
}
答案:
没有释放new的对象box,多次调用会产生内存泄露。
基础题
9 简述指针和引用的区别
简述指针和引用的区别
答案:
1.C语言中只有指针没有引用
2.引用是安全的,会有参数为空的检查和越界检查
3.指针速度比引用快
基础题
10 QtGui和后台线程问题
可以考察出对Qt的理解程度
如果界面上有一个按钮pushButton,对应槽函数为on_pushButton_clicked(),以下代码会对界面造成什么影响
void on_pushButton_clicked()
{
//apped 512MB data into file "./data.rec"
...
}
答案:
槽函数执行时界面会卡住不动
能够完美的答出此题,说明对多线程、界面编程理解比较到位
如何解决
1.发送信号量给另一个线程,而不是在GUI中直接做操作 //推荐
//这种做法需要对Qt的线程有一定的理解,否则容易出现看似是在后台执行,实则还是在GUI线程工作的情况。
2.在GUI线程中操作另一个线程中的标志位,操作完直接返回,另一个线程在run函数中检测到标志位改变,执行动作
11 Vector、List模板
以下代码存不存在问题?
class A {
public :
A(){};
void append(QString s) { _list.append(s); }
void clear() {_list.clear(); }
QString getStringByIndex(unsigned int index) { return _list.at(index); }
private:
QStringList _list;
}
答案:
getStringByIndex接口中未对_list的大小和index是否合法进行判断,如果index超出了_list的实际大小,则程序会崩溃
12 TCP通信
请写出一段伪代码,实现TCP Server功能,要求支持多台client同时连接,且当连接数量超过5时,关闭最老的连接
答案:
传统代码写法(C/标准C++)
伪代码:
绑定ip和端口号
开始监听
循环开始
如果 有新的链接
当前连接数量 > 5?
关闭当前活动的最早的socket连接,并停止子线程
否则
创建一个子线程,用于处理和client的通信
Qt
伪代码
创建一个QTcpSocket对象
设置ip和端口
连接newConnection信号和处理槽函数
在槽函数中建立子线程
13 栈
如下代码存不存在问题,为什么?
void func()
{
int arg[1024*1024*64];
.....
}
答案:
栈溢出。一般系统里边不可能把栈设置到64MB这么大,有些编译器会在编译阶段发现此问题,给出警告或者错误。有些编译器不会报错,但是程序运行到这个地方的时候,就会出现错误。
栈溢出很多情况下是代码中定义了较大的局部变量导致,这种情况出现了以后还不容易排查出来
14 请简述如何添加自定义的链接库
答案:
以下答案为在linux系统下
- 在编译选项中增加库的直接引用(-lzmq)或增加库的搜索路径(如-L/usr/local/lib)
- 在系统的库搜索路径中添加 export LD_LIBRARY_PATH:=/usr/loca/ffmpeg:$LD_LIBRARY_PATH
在新环境下编译时经常遇到的问题
15 简述tcp通信和udp通信的区别
本题主要目的考察是否有网络通信基础和相关的调试经验,基础比较扎实的可能会说一堆区别出来,调试经验比较足的可能会专注于两点比较重要的来讲
- tcp需要建立链接,udp不需要建立链接
- tcp不丢包但是可能阻塞,还可能分包和拼包,udp会丢包,但不会分包、拼包
网络通信基础
16 如何处理tcp的分包和拼包现象
答案:
使用tcp通信,一定要做好对tcp分包和拼包的处理,就算是在网络环境特别好的情况下,这种现象也可能出现。一般来说可以通过构造一个缓冲区缓存接收到的tcp链路上的原始数据,再对缓冲区内部的数据进行解析或者加入长度和校验信息保证数据正确性。
一个tcp通信程序,不做分包和拼包可能直连情况下运行起来依然良好,但是很可能在经过交换机后运行会偶发不正常,且问题不容易复现
17 如何看待编译器warning和需要注意的warning类别
答案:
本题主要考察应聘人员对编程细节的注重程度。解决warning就是解决潜在的bug。
需要注意的warning类别举例
- -Wsign-compare:有符号数和无符号数进行比较
- -Wuninitialized:变量未初始化直接使用,初值不确定
- -Wunused-paramete:存在声明了但未使用的变量
- -Wreturn-type:返回值和声明不一致