腾讯 2021年 pc客户端开发面试题

小编:管理员 512阅读 2021.06.18

第1题:


一、不定项选择题

下列说法错误的有( )            

A、在类方法中可用this来调用本类的类方法

B、在类方法中调用本类的类方法时可直接调用

C、在类方法中只能调用本类中的类方法

D、在类方法中绝对不能调用实例方法

 



答案:A C D

解析:

A:类方法是指类中被static修饰的方法,无this指针。

C:类方法是可以调用其他类的static方法的。

D:可以在类方法中生成实例对象再调用实例方法。(这个我也打错了,想想应该是这个意思)

 


第2题:


 下列运算符,在C++语言中不能重载的是()          

A、*

B、.*

C、::

D、operator  delete



答案: BC

解析:并不是所有的操作符都能被重载。除了   .    ,   .*    ,   ::    ,   ? :    ,   sizeof   ,   typeid   这几个运算符不能被重载,其他运算符都能被重载。

.表示成员选择

.*表示指向成员操作的指针

?=表示条件操作 expr?expr:expr



第3题:


 下列的模板说明中,正确的有(  )    

A、template <typename T1, typename T2>

B、template <class T1, T2>

C、template <class T1, class T2>

D、template <typename T1; typename T2>



答案:AC

解析:

D的分号是错的;
B的参数T2前加class 或者typename



第4题:


 In C++, which of the following keyword(s) can be used on both a variable and a function?       

A、static

B、virtual

C、extern

D、inline

E、const



答案:A C E



第5题:


 Which of the following statement(s) equal(s) value 1 in C programming language? 

A、the return value of main function if program ends normally

B、return (7&1)

C、char *str="microsoft"; return str=="microsoft"

D、return "microsoft"=="microsoft"

E、None of the above

答案: BCD  

解析:A.main成功返回,是0   B. 按位与 7&1 = 111 & 001 = 001  即 1  C.str这个指针就是指向"microsoft"这个字符串常量的地址,所以,str == "microsoft" 自然是成立的, D. 两个相同的字符串常量是放在同一个内存地址的,所以也相等,  答案为BCD



第6题:


 下列定义语句中,错误的是

A int px*;

B char*acp[10];

C char(*pac)[10];

D int(*p)();



答案: A



第7题:


 抽象基类是指( ) 

A 嵌套类

B 派生类

C 含有纯虚函数

D 多继承类



 答案:C

【解析】抽象基类是指含有纯虚函数,不能够实例化的基类。



第8题:


 给出以下定义,下列哪些操作是合法的?
 

const char *p1 = “hello”;

char *const p2 = “world”;

         

A p1++;

B p1[2] = ‘w’;

C p2[2] = ‘l’;

D p2++;



答案:A

解析:

p1是指向字符常量的指针,p1本身不是常量,所以p1++合法,A正确。

p2本身是指针常量,可以指向非常量的字符。但是"hello"这样声明的字符串是存储在只读存储区的,不可修改,所以B,C,D都错误。



第9题:


 关于IP地址下列说法错误的是?

A IP地址采用分层结构,它由网络号与主机号两部分组成

B 根据不同的取值范围IP地址可以分为五类

C 202.112.139.140属于B类地址

D 每个C类网络最多包含254台主机

E IPv6采用128位地址长度

F 私有地址只是ABC类地址的一部分



答案:C

解析:

最初设计互联网络时,为了便于寻址以及层次化构造网络,IP地址采用分层结构,每个IP地址包括两个标识码(ID),即网络ID和主机ID。同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包括网络上工作站,服务器和路由器等)有一个主机ID与其对应。IP地址根据网络ID的不同分为5种类型,A类地址、B类地址、C类地址、D类地址和E类地址。 

1. A类IP地址 
一个A类IP地址由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”, 地址范围从1.0.0.0     到126.0.0.0。可用的A类网络有126个,每个网络能容纳1亿多个主机。 
2. B类IP地址 
一个B类IP地址由2个字节的网络地址和2个字节的主机地址组成,网络地址的最高位必须是“10”,地址范围从128.0.0.0到191.255.255.255。可用的B类网络有16382个,每个网络能容纳6万多个主机    。 
3. C类IP地址 
一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址的最高位必须是“110”。范围从192.0.0.0到223.255.255.255。C类网络可达209万余个,每个网络能容纳254个主机。 
4. D类地址用于多点广播(Multicast)。 
D类IP地址第一个字节以“lll0”开始,它是一个专门保留的地址。它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。 
5. E类IP地址 
以“llll0”开始,为将来使用保留。 

在IP地址3种主要类型里,各保留了3个区域作为私有地址,其地址范围如下: 
A类地址:10.0.0.0~10.255.255.255 
   B类地址:172.16.0.0~172.31.255.255 
C类地址:192.168.0.0~192.168.255.255

另外IPv6地址长度为128位,是IETF(互联网工程任务组,Internet Engineering Task    Force)设计的用于替代现行版本IP协议(IPv4)的下一代IP协议。



第10题:


 对于二分查找算法下面描述正确的是哪个?

A 只能用于数组

B 只能用于链表

C 只能在已经排序的数据上进行查找

D 最坏情况下时间复杂度是O(N*logN)



答案: A,C

错误分析:

B:链表不支持随机访问.

D:最坏情况下时间复杂度是 O(logN).



第11题:


 用来检查到一台主机的网络层是否连通命令是( )?

A PING

B TRACERT

C TELNET

D IPCONFIG



答案:A

解析:
ping命令通过发送ICMP数据包检测网络层是否连通
tracert是用来跟踪路由的命令
telnet命令式通过telnet协议和另一主机相联。
ipconfig是查看ip地址信息



第12题:


 类B从类A派生,则类B可以访问类A中的( )成员?

A public成员

B private成员

C protected成员

D 数据成员

E 函数成员



答案:AC

解析:private成员只能在当前类中访问,派生类可以访问父类的public和protected属性成员



第13题:


 路由器转发数据包到非直接网段的过程中,依靠下列哪一个选项来寻找下一跳地址( )      

A 帧头

B IP报文头部

C SSAP子段

D DSAP子段



答案:B

解析:

路由器工作在OSI的网络层,转发的数据包是IP报文。

IP报文的头部有源IP和目的IP

路由器根据目的ip计算出iP所在的网段,根据网段转发到不同的端口。

如果在路由表中没有该网段的转发端口,则转发至默认路由端口



第14题:


 IPv6地址占____个字节          

A 4

B 6

C 8

D 16



答案:D

解析:IPv6二进位制下为128位(16字节)长度,以16位为一组,每组以冒号":"隔开,可以分为8组,每组以4位十六进制方式表示。



第15题:


 以下说法正确的是:

A 在并行程度中,当两个并行的线程,在没有任何约束的情况下,访问一个共享变量或者共享对象的一个域,而且至少要有一个操作是写操作,就可能发生数据竞争错误。

B 原语Compare-and-swap(CAS)是实现无锁数据结构的通用原语。

C 获得内部锁的唯一途径是:进入这个内部锁保护的同步块或方法。

D volatile变量具有synchronized的可见性特性,但是不具备原子特性。

E 减小竞争发生可能性的有效方式是尽可能缩短把持锁的时间



答案: A D



第16题:


 二、解答题

调用动态连接库的函数有哪几种方法?



 调用一个DLL中的函数有两种方法: 1.载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向系统提供了载入DLL时所需的信息及DLL函数定位。 2.运行时动态链接(run-time dynamic linking),运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了。



第17题:


 WM_QUIT消息的用途是什么?一个普通的Windows窗口能收到的最后一条消息是什么?



 WM_QUIT通知程序退出,一般情况下在主线程中会有一个循环如下:

    while(GetMessage(......))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

      如果GetMessage获得的是WM_QUIT消息,GetMessage便会返回FALSE,导致while循环退出,一般情况下,程序也会退出。windows窗口不会受到WM_QUIT消息。

     

    普通Windows窗口能收到的最后一条消息时WM_DESTROY。



第18题:


 有pqueue.h如下


#ifndef HEADER_PQUEUE_H

#define HEADER_PQUEUE_H

typedef struct_pqueue{

    pitem *items;

     int count;

}pqueue_s;

typedef struct_pqueue *pqueue;

typedef struct_pitem{

    unsigned char priority[8];

    void *data;

    struct_pitem *next;

}pitem;

typedef struct_pitem *piterator;

pitem *pitem_new(unsigned char *prio64be,void *data);

void pitem_free(pitem *item);

  

pqueue pqueue_new(void);

void pqueue_free(pqueue pq);

pitem *pqueue_insert(pqueue pq,pitem *item);

pitem *pqueue_peek(pqueue pq);

pitem *pqueue_pop(pqueue pq);

pitem *pqueue_find(pqueue pq,unsigned char *prio64be);

pitem *pqueue_iterator(pqueue pq);

pitem *pqueue_next(piterator *iter);

int pqueue_size(pqueue pq);

#endif /*! HEADER_PQUEUE_H */

pq_test.c如下:


#include<stdlib.h>

#include<string.h>

#include"pqueue.h"

/*remember to change expected.txt if you change there values*/

unsigned char prio1[8]="supercal";

unsigned char prio2[8]="ifragili";

unsigned char prio3[8]="sticexpi";

static void

pqueue_print(pqueue pq)

{

     pitem *iter,*item;

     iter=pqueue_iterator(pq);

     for(item=pqueue_next(&iter);item!=NULL;

         item=pqueue_next(&iter)){

         printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n",

             item ->priority[0],item->priority[1],

             item ->priority[2],item->priority[3],

             item ->priority[4],item->priority[5],

             item ->priority[6],item->priority[7],

         }

}

int main(void)

{

     pitem *item;

     pqueue pq;

     pq=pqueue_new();

     item=pitem_new(prio3,NULL);

     pqueue_insert(pq,item);

  

     item=pitem_new(prio1,NULL);

     pqueue_insert(pq,item);

  

     item=pitem_new(prio2,NULL);

     pqueue_insert(pq,item);

     item=pqueue_find(pq,prio1);

     fprintf(stderr,"found %p\n",item->priority);

     item=pqueue_find(pq,prio2);

     fprintf(stderr,"found %p\n",item->priority);

  

     item=pqueue_find(pq,prio3);

     fprintf(stderr,"found %p\n",item->priority);

      

     pqueue_print(pq);

     for(item=pqueue_pop(pq);item!=NULL;item=pqueue_pop(pq))

     pitem_free(item);

  

     pqueue_free(pq);

     return 0;

}

   

pq_test.sh如下:


#!/bin/sh

set -e

./pq_test | cmp $srcdir/pq_expected.txt-

   

pq_expected.txt如下:

item 6966726167696c69

item 7374696365787069

item 737570657263616c

1.根据测试代码描述pqueue的工作原理。

2.请实现 pitem *pqueue_insert(pqueue pq,pitem *item);






 测试文件的内容输出的是struct_pitem结构中的priority字段的16进制形式,将其转换为字符串正好是通过pqueue_insert函数放入到pqueue结构中的prio3、prio1、prio2的值。通过观察测试文件中每一行的值可以发现对应的字符串序列为prio3、prio2、prio1,跟插入字符串的顺序并不一致,说明pqueue既不是先进先出(队列),也不是后进先出(栈)。

另外,通过观察测试文件可以发现测试文件中的字符串是按照从小到大排列的,而且struct_pitem中的priority字段含义可以理解,这是一个优先级队列,priority字段代表队列的优先级,priority字段越小,优先级越高。

理解了队列的结构后,就可以写出插入的代码了。

pitem *pqueue_insert(pqueue pq, pitem *item)

{

    if (!item)

    {

        return NULL;

    }

     

    if (pq->count == 0)

    {

        pq->items = item;

        count++;

        return pq->items;

    }

     

    // 查找要插入的位置

    pitem *iter, *item2, *item_before = NULL;

    iter = pqueue_iterator(pq);

    for(item2=pqueue_next(&iter); item2!=NULL; item2=pqueue_next(&iter))

    {

        int result = 0;

        for (int i=0; i<8; i++)

        {

            if (item[i] < item2[i])

            {

                result = -1;

            }

            else if (item[i] < item2[i])

            {

                result = 1;

            }

        }

         

        if (result == -1)

        {

            break;

        }

        item_before = item2;

    }

     

    if (!item_before)

    {

        // item需要插入到队列中的第一个位置

        item_before = pq->items;

        pq->items = item;

        item->next = item_before;

    }

    else

    {

        pitem *tmp = item_before->next;

        item_before->next = item;

        item->next = tmp;

    }

    pq->count++;

    return item;

}


关联标签: