一、单选题
1、假设整数0x12345678 存放在内存地址0x0开始的连续四个字节中 (即地址0x0到 0x3). 那么在以Little Endian字节序存储的memory中,地址0x3的地方存放的字节是:
A、0x12
B、0x34
C、0x56
D、0x78
1、A
a) Little-Endian就是低位字节排放在内存的低地址端, 高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
如果是 Little-Endian:0x0-0x3内存分别存放的是:0x78、0x56、0x34、0x12;
如果是 Big-Endian :0x0-0x3内存分别存放的是:0x12、0x34、0x56、0x78;
2、以下代码输出的是__?
int foo(int x,int y)
{
if(x<=0||y<=0) return 1;
return 3*foo(x-1,y/2);
}
cout<<foo(3,5)<<endl;
A、81
B、27
C、9
D、3
2、B
递归:3*3*3*f(0,0)=3*3*3*1=27。
3、给定下列程序,那么执行printf("%\n",foo(20,13)); 的输出结果是多少?
int foo (int x,int y )
{
if (x<=0││y<=0)
return 1;
return 3*foo(x-6,y/2);
}
A、3
B、9
C、27
D、81
3、D
4、如果x=2014,下面函数的返回值是()
int fun(unsigned int x)
{
int n=0;
while((x+1))
{
n++;
x=x|(x+1);
}
return n;
}
A、20
B、21
C、23
D、25
4、C
返回值为:23
2014对应的二进制为:0000 0000 000 0000 0000 0111 1101 1110
而x|(x+1)的作用是对一个数中二进制0的个数进行统计
例如本题:
第一次循环:0000 0000 000 0000 0000 0111 1101 1110 |0000 0000 000 0000 0000 0111 1101 1110 =0000 0000 000 0000 0000 0111 1101 1111
第二次循环:0000 0000 000 0000 0000 0111 1101 1111 |0000 0000 000 0000 0000 0111 1110 0000 =0000 0000 000 0000 0000 0111 1111 1111
.
.
.
每循环一次0的数量减一 ,直到溢出
所以2014二进制中一共有23个0则返回值为23
5、以下代码的输出是()
int a[5]={1,2,3,4,5};
int *ptr=(int*)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
A、1,2
B、2,5
C、2,1
D、1,5
5、B
a 代表的是int * 每次步长为一个int
&a 代表的是 int[]* 每次步长为所指向的数组的大小
故
ptr 指向的是数组a最后一个元素的下一个元素
所以ptr-1指向的是数组a的最后一个元素
a+1指向的是数组a的第二个元素
所以正确答案是B
6、在linux下64位c程序,请计算输出的三个sizeof分别是()
void func(char str_arg[100])
{
cout<<sizeof(str_arg)<<endl;
}
int main(int argc,char* argv[])
{
char str[]="Hello";
char *p=str;
cout<<sizeof(str)<<endl;
cout<<sizeof(p)<<endl;
func("test");
return 0;
}
A、5,5,8
B、6,6,4
C、6,8,4
D、6,8,8
6、D
这里主要是区分sizeof运算符的测量对象
sizeof(str)测量的是字符数组的占用长度,注意字符串后还有个\0,所以是6
sizeof(p)测量的是指针的占用长度,64位系统下是8字节
sizeof(str_arg)测量的是指针长度,因为这里是形参。
7、下面关于迭代器失效的描述哪个是错误的()
A、vector的插入操作不会导致迭代器失效
B、map的插入操作不会导致迭代器失效
C、vector的删除操作只会导致指向被删除元素及后面的迭代器失效
D、map的删除操作只会导致指向被删除元素的迭代器失效
7、A
因为由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的 :如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。
8、函数fun的声明为int fun(int *p[4]),以下哪个变量可以作为fun的合法参数()
A、int a[4][4];
B、int **a;
C、int **a[4]
D、int (*a)[4];
8、B
可以看出fun函数的形参是一个指针数组,也就是指针指向一个地址,地址中存放的内容也是指针。
A,二维数组,不符合
B,二级指针,也就是指针指向的内容也还是存放指针的,符合
C,二级指针数组,数组的内容是二级指针,不符合
D,数组指针,不符合
9、下面说法正确的是()
A、C++已有的任何运算符都可以重载
B、const对象只能调用const类型成员函数
C、构造函数和析构函数都可以是虚函数
D、函数重载返回值类型必须相同
9、B
A 不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。
不能重载 ?: ,因为这个运算符对于类对象来说没有实际意义,相反还会引起歧义
还有::
C 构造函数 不能是虚函数。
D 函数重载只跟 参数类型 和参数个数 有关。
10、典型的创建Windows窗口过程的流程为()
A、注册窗口类->创建窗口->显示窗口->更新窗口->消息循环
B、注册窗口类->创建窗口->更新窗口->显示窗口->消息循环
C、创建窗口->注册窗口类->更新窗口->显示窗口->消息循环
D、创建窗口->注册窗口类->显示窗口->更新窗口->消息循环
10、A
在屏幕上显示一个窗口的过程一般有以下步骤,这就是主程序的结构流程:
(1)得到应用程序的句柄(GetModuleHandle)。
(2)注册窗口类(RegisterClassEx)。在注册之前,要先填写RegisterClassEx的参数WNDCLASSEX结构。
(3)建立窗口(CreateWindowEx)。
(4)显示窗口(ShowWindows)。
(5)刷新窗口客户区(UpdateWindow)。
(6)进入无限的消息获取和处理的循环。首先获取消息(GetMessage),如果有消息到达,则将消息分派到回调函数处理(DispatchMessage),如果消息是WM_QUIT,则退出循环。
11、下面哪个API返回的不属于windows内核对象()
A、CreateFile
B、CreateSemaphore
C、CreateDC
D、eateEvent
11、C
ABD选项是内核对象:事件对象HANDLE CreateEvent();文件对象HANDLE CreateFile();信号量对象HANDLE CreateSemaphore();
C选项是GDI对象。设备上下文(HDC) CreateDC
12、用户双击鼠标时产生的消息序列,下面正确的是()
A、WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDOWN,WM_LBUTTONUP
B、WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONUP,WM_LBUTTONDBLCLK
C、WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDOWN,WM_LBUTTONDBLCLK
D、WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDBLCLK,WM_LBUTTONUP
12、D
双击即点击左键两下,第一次触发LBUTTONDOWN和LBUTTONUP,第二次点击时触发双击事件LBUTTONDBLCLK(doubleclick),放掉再触发LBUTTONUP
13、以下关于线程以下描述正确的是()
1.windows线程创建时,默认绑定在1个特定的CPU上
2.可采用SetThreadAffinityMask接口设置线程与某个cpu绑定
3._beginthreadex比CreateThread创建线程安全是因为使用_beginthreadex会创建一个_tiddata,在调用一些诸如strtok函数时会将需要保护的数据存入_tiddata
4.使用_beginthread创建线程时,线程执行函数必须为_cdecl约束规范,而_beginthreadex指定的线程执行函数必须为_stdcall
A、1,2
B、1,3
C、1
D、以上都不正确
13、D
解释:1:不正确。windows线程创建时,不会绑定在特定的CPU上,需要手动绑定,或者调用 SetThreadAffinityMask接口进行绑定;
2:正确。参考 http://blog.csdn.net/beyond_cn/article/details/15813361
3:不正确。参考2的链接。欢迎各位纠正。
4:正确。参考msdn:
_beginthread 函数可创建在 start_address 开始执行例程的线程。 start_address 中的例程必须使用 __cdecl (用于本机代码)或 __clrcall (用于托管代码)调用约定,并且应没有返回值。
传递给 _beginthreadex 的 start_address 中的例程必须使用 __stdcall (用于本机代码)或 __clrcall (用于托管代码)调用约定,并且必须返回线程退出代码。
所以,通过1,就能选出D。
14、以下哪些线程同步锁可以为递归锁
1.信号量 2.读写锁 3.互斥量 4.事件 5.临界区(Critical Section)
A、1,3,4,5
B、5
C、3,5
D、1,3,5
14、C
进程/线程同步方法
常见的进程/线程同步方法有互斥锁(或称互斥量Mutex)、读写锁(rdlock)、条件变量(cond)、信号量(Semophore)等。
在windows系统中,临界区(Critical Section)和事件对象(Event)也是常用的同步方法。
递归锁/非递归锁
Mutex可以分为递归锁(recursive mutex)和非递归锁(non-recursive mutex)。 递归锁也叫可重入锁(reentrant mutex),非递归锁也叫不可重入锁(non-reentrant mutex)。
二者唯一的区别是:
同一个线程可以多次获取同一个递归锁,不会产生死锁。
如果一个线程多次获取同一个非递归锁,则会产生死锁。
Windows下的Mutex和Critical Section是可递归的。
Linux下的pthread_mutex_t锁是默认是非递归的。可以通过设置PTHREAD_MUTEX_RECURSIVE属性,将pthread_mutex_t锁设置为递归锁。
15、关于sendmessage和postmessage的区别,下面的说法错误的是()
A、postmessage发出消息后,将消息放到消息队列中,马上返回
B、sendmessage发出消息后,一直等到该消息执行完毕,才返回
C、用sendmessage给其他线程创建的窗口发送消息时,消息也会进消息队列
D、用2个函数只能给当前进程的窗口发送消息
15、D
A:PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。
B:SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。
C:当某线程调用sendmessage给别的线程创建的窗口时,发送的消息首先追加到接收线程的发送消息队列,发送线程处于空闲状态,等待接收线程处理完他的消息返回给发送线程的应答队列,等到后发送线程被唤醒取得应答队列的消息 (就是处理完消息的返回值),继续执行。
D:sendmessage和postmessage都可以给其他线程发送消息
16、关于WM_COPYDATA消息的处理,下面描述错误的是()
A、可以在不同进程之间传递少量只读数据
B、只能通过sendmessage方式来发送该消息
C、只能在窗口过程函数中处理该消息
D、可以在消息队列或窗口过程函数中处理该消息
16、C
A:WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。
B;该消息只能由SendMessage()来发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。
D:可以在消息队列或窗口过程函数中处理该消息
17、常用的windows进入点函数wWinMain共有四个参数,其中不包括以下哪种类型的参数()
A、int
B、char*
C、PWSTR
D、HINSTANCE
17、C
WinMain 函数的原型声明如下:
int WINAPI WinMain(
HINSTANCE hInstance , // handle to current instance
HINSTANCE hPrevInstance , // handle to previous instance
LPSTR lpCmdLine , // command line
int nCmdShow // show state
);
第一个参数 hInstance 表示该程序当前运行的实例的句柄,这是一个数值。
第二个参数 hPrevInstance 表示当前实例的前一个实例的句柄。
第三个参数 lpCmdLine 是一个以空终止的字符串,指定传递给应用程序的命令行参数。
第四个参数 nCmdShow 指定程序的窗口应该如何显示,例如最大化、最小化、隐藏等。
18、下列windows消息中,优先级相对较低的是哪一个()
A、WM_MOUSEMOVE
B、WM_TIMER
C、WM_CHAR
D、WM_WINDOWPOSCHANGED
18、B
WM_TIMER消息的优先级最低,所以在有其他消息的情况下,WM_TIMER消息得不到处理
A:WM_MOUSEMOVE消息在鼠标移动时被发送至已获焦点的窗口
B:Windows定时器是一种周期性的消息产生装置,它会每隔一段指定时间发送一次定时消息WM_TIMER。
C:未经输入法而直接送人程序中的字符会响应WM_CHAR消息
D:发送此消息给那个窗口的大小和位置已经被改变时,来调用setwindowpos函数或其它窗口管理函数
19、最小堆[0,3,2,5,7,4,6,8],在删除堆顶元素0之后,其结果是()
A、[3,2,5,7,4,6,8]
B、[2,3,5,7,4,6,8]
C、[2,3,4,5,7,8,6]
D、[2,3,4,5,6,7,8]
19、C
根据堆的删除规则,删除操作只能在堆顶进行,也就是删除0元素。
然后让最后一个节点放在堆顶,做向下调整工作,让剩下的数组依然满足最小堆。
删除0后用8填充0的位置,为[8,3,2,5,7,4,6]
然后8和其子节点3,2比较,结果2最小,将2和8交换,为:[2,3,8,5,7,4,6]
然后8的下标为2,其两个孩子节点下标分别为2*2+1=5,2*2+2=6
也就是4和6两个元素,经比较,4最小,将8与4交换,为[2,3,4,5,7,8,6]
这时候8已经没有孩子节点了,调整完成。
20、对一个由A,B,C,D随机组成的序列进行哈弗曼编码,据统计,各个元素的概率分别为:P(A)=0.4,P(B)=0.35,P(C)=0.2,P(D)=0.05,请问该编码的平均期望编码长度为()bits?
A、1.45
B、1.7
C、1.85
D、1.92
20、C
首先要建立哈夫曼树,然后计算平均期望编码长度:0.4*1 + 0.35*2 + 0.2*3 + 0.05*3 = 1.85