• 2021年奇虎360技术岗(程序员)面试题

    小编:管理员 217阅读 2021.06.24

    第1题:



    Class A;

    Class B;

    void F() {

            A a;

            B b;

    }

      

    在函数F中,本地变量a和b的构造函数(constructor)和析构函数(destructor)的调用顺序是:

             

    A  b构造 a构造 a析构 b析构

    B  a构造 a析构 b构造 b析构

    C  b构造 a构造 b析构 a析构

    D  a构造 b构造 b析构 a析构




    按变量声明顺序构造对象,然后入栈

    按相反顺序出栈,析构对象。


    第2题:


     假定指针变量p定义为“int *p=new int(100);”,要释放p所指向的动态内存,应使用语句( )

     

    A  delete p;

    B  delete *p;

    C  delete &p;

    D  delete []p;



     A


    第3题:


     选择填空:


    #include

    void test(void *data) {

        unsigned int value = (此处应填入)

        printf("%u", value);

    }

    using namespace std;

    int main() {

        unsigned int value = 10;

        test(&value);

        return 0;

    }

     

    A  *data

    B  (unsigned int)(*data)

    C  (unsigned*)data

    D  *((unsigned int *)data)




     D

    解释: 

      <span class="kwd" style="color: rgb(0, 0, 136);">void<span class="pln" style="color: rgb(0, 0, 0);">

     注意,参数类型是void,     所以先要进行指针转换:(unsigned    int *)然后再取值。



    第4题:


     在C++, 下列哪一个可以做为对象继承之间的转换

        

    A  static_cast

    B  dynamic_cast

    C  const_cast

    D  reinterpret_cast



     B
    dynamic_cast 动态转换


    第5题:


     如果进栈序列为e1,e2,e3,e4,则不可能的出栈序列是( )

         

    A  e2,e4,e3,e1

    B  e4,e3,e2,e1

    C  e1,e2,e3,e4

    D  e3,e1,e4,e2



     D

    如果e3第一个出栈,拿下一个应该是e4或者e2,但绝不可能是e1


    第6题:


     若某二叉树的前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序遍历的结点访问顺序是( )

     

    A  gdbehfca

    B  hcdeabf

    C  fdcehgba

    D  gdbehcfa



     A

    根据前序和中序序列画出二叉树的结构,写出其后序序列即可。


    第7题:


     用二分法查找长度为10的、排好序的线性表,查找不成功时,最多需要比较多少次?

      

    A  3

    B  4

    C  5

    D  6



     B

    8<10<16,而log16=4


    第8题:


     以下程序是用辗转相除法来计算两个非负数之间的最大公约数:


    long long gcd(long long x, long long y) {

        if (y == 0)

            return x;

        else

            return gcd(y, x % y);

    }

      

    我们假设x,y中最大的那个数的长度为n,x>y,基本运算时间复杂度为O(1),那么该程序的时间复杂度为( )

     

    A  O(1)

    B  O(logy)

    C  O(n)

    D  O(x)




     求最大公约数的最常用的算法是欧几里得算法,也称为辗转相除法.
    问题定义为求i和j的最大公约数gcd(i,j),其中i和j是整数,不妨设i>j.
    算法可以递归的表示:
    1.如果j能整除i,那么gcd(i,j)=j;
    2.j不能整除i,令r=i%j,那么gcd(i,j)=gcd(j,r).
    使用C语言实现:

    int gcd(int i, int j)

    {

        int r = i % j;

        return r == 0 ? j : gcd(j, r);

    }

    正确性分析:
    算法的步骤1,显然成立(最大公约数定义).关键是要证明步骤2.
    设d是i和j的最大公约数,
    那么i=md,j=nd,m和n互质(否则d不是最大公约数).
    由r=i%j可以得到i=kj+r,k=?m/n?,k≥1(我们前面假设过i>j).
    把i=md,j=nd代入得到
    md=knd+r
    那么
    r=(m-kn)d
    m-kn和m也是互质的.
    所以得到d是j和r的最大公约数.

    时间复杂度分析:
    逆着看该算法,最后的余数是0,倒数第二次余数是d,倒数第三次是kd,k>1…
    由于组成了一个数列,{0,d,kd,nkd+d,…}
    数列的n项加上n+1项,比n+2项要小,所以比斐波纳契数列增长的要快.
    我们已知斐波纳契数列增长速度是指数,那么待分析的数列也是指数增长.
    设欧几里得算法需要k次,那么j=O(2^k),则k=O(lg j).

    所以欧几里得算法求最大公约数的时间复杂度是对数量级的,速度非常快.


    第9题:


     一棵有124个叶节点的完全二叉树,最多有( )个节点。

     

    A  247

    B  248

    C  249

    D  250



     B

    n0 = n2 + 1,于是度为2的结点个数123个完全二叉树中度为1结点个数最多1个因此该完全二叉树中结点最多有123  + 1 + 124 = 248个


    第10题:


     链表不具备的特点是( )

     

    A  可随机访问任何一个元素

    B  插入、删除操作不需要移动元素

    C  无需事先估计存储空间大小

    D  所需存储空间与线性表长度成正比



     A

    不同于寻秩访问的数组,链表无法实现随机访问任何一个元素O(1), 访问时需要遍历链表直到访问到该元素。


    第11题:


     下列排序算法中,在待排序数据有序的情况下,花费时间最多的是( )

     

    A  快速排序

    B  希尔排序

    C  冒泡排序

    D  堆排序



     A

    待排序数据有序就是快排的最差情况,此时的时间复杂度是O(n   2   )


    第12题:


     有 1000 个无序的整数,希望使用最快的方式找出前 50 个最大的,最佳的选择是( )

    A  冒泡排序

    B  基数排序

    C  堆排序

    D  快速排序



     C

    找出若干个数中最大/最小的前K个数,用堆排序是最好的

    找最大数,用小根堆

    找最小数,用大根堆


    第13题:


     下面哪个不是用来解决哈希表冲突的开放地址法?

     

    A  线性探测法

    B  线性补偿探测法

    C  拉链探测法

    D  随机探测法



     C

    拉链探测法,开放定址法区分为线性探查法、线性补偿探测法、随机探测等。


    第14题:


     下列数最大的是( )。括号内为数字,括号外为进制。

     

    A  (10010101)2

    B  (227)8

    C  (96)16

    D  (143)10



     B


    第15题:


     在CPU和内存之间增加cache的作用是(  )

         

    A  提高内存稳定性

    B  解决内存速度低于CPU的性能问题

    C  增加内存容量

    D  增加内存容量且加快存取速度



     B

    这是存储器分层部分的内容,可以参考《深入理解计算机系统》


    第16题:


     假设整数0x12345678 存放在内存地址0x0开始的连续四个字节中 (即地址0x0到 0x3). 那么在以Little Endian字节序存储的memory中,地址0x3的地方存放的字节是:

    A  0x12

    B  0x34

    C  0x56

    D  0x78



     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;          


    第17题:


     将逻辑代码:

    if (x % 2) {

        return x - 1;

    } else {

        return x;

    }

      

    用表达式:return x & -2; 替代,以下说法中不正确的是( )

       

    A  计算机的补码表示使得两段代码等价

    B  用第二段代码执行起来会更快一些

    C  这段代码只适用于x为正数的情况

    D  第一段代码更适合阅读

     



     C


    第18题:


     代码生成阶段的主要任务是( )

             

    A  把高级语言翻译成汇编语言

    B  把高级语言翻译成机器语言

    C  把中间代码变换成依赖具体机器的目标代码

    D  把汇编语言翻译成机器语言



     C

    编译程序的工作过程一般划分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。所以选C 。


    第19题:


     后缀式 ab+cd+/可用表达式( )来表示

     

    A  a+b/c+d

    B  (a+b)/c+d

    C  a+b/(c+d)

    D  (a+b)/(c+d)



     D

    后缀表达式不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行,不再考虑运算符的优先规则。
     最后一个操作是'/',而且前面是一个+操作,后面没有操作,可知/操作最后进行,由此可得,另外两个操作数是a+b和c+d,因此表达式为D (a+b)/(c+d)


    第20题:


     以下关于函数调用的说法哪个是正确的?

          

    A  传值后对形参的修改会改变实参的值

    B  传地址后实参和形参指向不同的对象

    C  传引用后形参和实参是不同的对象

    D  以上都不对



     D

    解释:传地址和传引用,形参,实参指向同一对象,修改形参会影响实参

    传值则相反,修改形参不会影响实参


    第21题:


     一个合法的 360 账户名称要求如下:是一个合法的邮箱地址,如 kefu@#;邮箱前缀的长度为 [ 4, 16 ] 个字符;邮箱前缀必须以字母开头,字母或数字结尾;邮箱前缀可以包括字母、数字、下划线。请问如下正则表达式中,哪一个能正确校验用户名的合法性:

     

    A  \w[0-9a-zA-Z_]{3,15}\@\w+.([-.]\w+)*

    B  [a-zA-Z]\w{3,15}@\w+.\w*

    C  [a-zA-Z]\w{2,14}[0-9a-zA-Z]\@\w+([-.]\w+)*

    D  [a-zA-Z]\w{2,14}[0-9a-zA-Z]@\w



     C

    邮箱前缀必须以字母开头,字母或数字结尾    这句话 排除A

    邮箱中肯定有“.”     ,D中没有 排除D

    邮箱前缀可以包括字母、数字、下划线    ,B中 没有数字,排除B


    所以答案是C


    第22题:


     词法分析器用于识别( )

      

    A  句子

    B  句型

    C  单词

    D  生产式



     C

    思路:参见维基百科:http://zh.wikipedia.org/zh/%E8%AF%8D%E6%B3%95%E5%88%86%E6%9E%90

    词法分析器是将源文件识别为单词,对单词进行分类


    第23题:


     在下列说法中,哪个是错误的( )

     

    A  若进程A和进程B在临界段上互斥,那么当进程A处于该临界段时,它不能被进程B中断

    B  虚拟存储管理中采用对换(swapping)策略后,用户进程可使用的存储空间似乎增加了

    C  虚拟存储管理中的抖动(thrashing)现象是指页面置换(page replacement)时用于换页的时间远多于执行程序的时间

    D  进程可以由程序、数据和进程控制块(PCB)描述



     C

    c选项中:是请求分页虚拟存储管理。
    当需要执行否条的指令或使用某个数据而发现他们不再内存中时候,会产生缺页异常。
    系统从磁盘中把此指令或数据所在的页面装入。缺页异常是由硬件所产生的一种特殊终端信号,其中当中断率较高时,整个系统的页面调度非常频繁造成大部分时间都花费在来回调度上,而不是执行任务,这种现象叫做“抖动”。——《操作系统》


    第24题:


     操作系统采用分页式存储管理(PAGING)方法,要求( )

      

    A  每个进程拥有一张页表,且进程的页表驻留在内存中

    B  每个进程拥有一张页表,但只要执行进程的页表驻留在内存中,其他进程的页表不必驻留在内存中

    C  所有进程共享一张页表,以节约有限的内存空间,但页表必须驻留在内存中

    D  所有进程共享一张页表,只有页表中当前使用的页面必须驻留在内存中,以最大限度地节约有限的内存空间



     B 

    在内核中 所有进程都是用一个页目录表,每个进程都有自己的页表 


    第25题:


     计算机操作系统出现死锁的原因是什么?

           

    A  资源数大大少于进程数,或进程同时申请的资源数大大超过资源总数

    B  有多个封锁的进程同时存在

    C  一个进程进入死循环

    D  若干进程因竞争资源而无休止的等待着其他进程释放已占有的资源



     D

    死锁的原因在于进程在等待其它进程占有的某些资源,而自身的资源又被其它进程等待着,造成了死循环。


    第26题:


     进程间通讯的方式中哪种的访问速度最快?

        

    A  管道

    B  消息队列

    C  共享内存

    D  套接字



     C

    常见进程间通信方式的比较:

    管道:速度慢,容量有限
    消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
    信号量:不能传递复杂消息,只能用来同步
    共享内存区:能够很容易控制容量,速度快 ,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了一块内存的。


    第27题:


     TCP的关闭过程,说法正确的是( )

    A  处于TIME_WAIT状态的连接等待2MSL后真正关闭连接

    B  对一个established状态的TCP连接,在调用shutdown函数之前调用close接口,可以让主动调用的一方进入半关闭状态

    C  主动发送FIN消息的连接端,收到对方回应ack之前不能发只能收,在收到对方回复ack之后不能发也不能收,进入CLOSING状态

    D  在已经成功建立连接的TCP连接上,任何情况下都不允许丢失数据。



     A
     TIME_WAIT状态下发送的ACK丢失,服务器端的LAST_ACK时刻设定的重传定时器超时,发送重传的FIN,很不幸,这个FIN也丢失,主动关闭方在   TIME_WAIT状态等待2MSL没收到任何报文段,进入CLOSED状态,当此时被动关闭方并没有收到最后的ACK。所以即使要主动关闭方在 TIME_WAIT状态下停留2MSL,也不一定表示四次握手关闭就一定正常完成


    第28题:


     linux中调用write发送网络数据返回n(n>0)表示(  )

       

    A  对端已收到n个字节

    B  本地已发送n个字节

    C  系统网络buff收到 n个字节

    D  系统调用失败



     B

    已发送,但不保证对方收到

    write函数的返回值的含义本来就是这样  


    第29题:


     HTTP 应答中的 500 错误是:

         

    A  服务器内部出错

    B  文件未找到

    C  客户端网络不通

    D  没有访问权限



     A

    403:禁止访问;

    404:找不到该页面;

    503:服务器繁忙;

    500:内部服务器访问出错。


    第30题:


     下列关于 Android 数字签名描述错误的是:

         

    A  所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序

    B  Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证

    C  如果要正式发布一个Android程序,可以使用集成开发工具生成的调试证书来发布。

    D  数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。



     C

    必须要使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。


    第31题:


     二、填空题

    小支欲用积分兑换安仔娃娃。兑换的规则是10积分可以兑一个安仔并返还5积分。小支有200积分,最多可以兑到         ________个安仔?(假设可以借积分)



     40

    借我200积分换成40个按仔,返回的200积分还给你


    第32题:


     五对夫妇甲,乙,丙,丁,戊举行家庭聚会 每一个人都可能和其他人握手, 但夫妇之间绝对不握手. 聚会结束时, 甲先生问其他人: 各握了几次手? 得到的答案是: 0,1,2,3,4,5,6,7,8. 试问: 甲太太握了__________ 次手?



     4

    甲太太握了4次手。 首先,可以断言握了8次手的人和握了0次手的人是一家人。因为一个人握了0次手,说明他(她)没有和其他任何人握手,而握了8次手的人握了别家的所有人的手,如果握了8次手的这个人和握了0次手的这个人不是一家人,握了8次手的这个人就必然握过握了0次手的人,那么,握了0次手的人就被握了8次手的人握了1次,这就矛盾了。 其次,可以断言握了1次手的人和握了7次手的人是一家人。因为现在大家都至少握过一次手了(和握过8次手的那个人握的),所以握过7次手的人必须和除了第一家和自己家的所有人握手,而握过1次手的人已经不能再和任何人握手了,因此,他们只能是一家人。 同理,握了2次手的人和握了6次手的人是一家人,握了3次手的人和握了5次手的人是一家人,握了4次手的是最后一家人。 现在来看,如果甲太太握了0次手,那么甲先生必然要握8次手,而且没有其他人可以握8次手,但是,甲先生是提问的人,因此,他没有握8次手,因此,甲太太也就不可能握0次手。 同理,甲太太也不可能握了1,2,3,5,6,7,8次手。 甲太太只可能握了4次手。


    第33题:


     赛马,有25匹马,每次只能5匹马进行比赛,比赛只能得到5匹马之间的快慢程度,而不是速度,请问,最少要比_____________次,才能获得最快的前3匹马?



     7

    25匹马,速度都不同,但每匹马的速度都是定值。现在只有5条赛道,无法计时,即每赛一场最多只能知道5匹马的相对快慢。问最少赛几场可以找出25匹马中速度最快的前3名? 每匹马都至少要有一次参赛的机会,所以25匹马分成5组,一开始的这5场比赛是免不了的。接下来要找冠军也很容易,每一组的冠军在一起赛一场就行了 (第6场)。最后就是要找第2和第3名。我们按照第6场比赛中得到的名次依次把它们在前5场比赛中所在的组命名为A、B、C、D、E。即:A组的冠军是第 6场的第1名,B组的冠军是第6场的第2名……每一组的5匹马按照他们已经赛出的成绩从快到慢编号: A组:1,2,3,4,5 B组:1,2,3,4,5 C组:1,2,3,4,5 D组:1,2,3,4,5 E组:1,2,3,4,5 从现在所得到的信息,我们可以知道哪些马已经被排除在3名以外。只要已经能确定有3匹或3匹以上的马比这匹马快,那么它就已经被淘汰了。可以看到, 只有上表中粗体的那5匹马是有可能为2、3名的。即:A组的2、3名;B组的1、2名,C组的第1名。取这5匹马进行第7场比赛,第7场比赛的前两名就是 25匹马中的2、3名。故一共最少要赛7场。


    第34题:


     店主销售电话卡,他以60元的价格各销售了两张。其中一张是赚了20%,另一张是亏了20%。 请问他总共赚了_____________钱(亏了的话请用负数表示)?



     -5

    有两个电话卡,a(赚钱)和b(亏钱),a的成本为x,x(1+0.2)=60,所以x=50,a赚10元

    b的成本为y,y(1-0.2)=60,y=75,b亏15元

    所以综合起来 亏5元


    第35题:


     三、问答题

    在审计某一开源项目的代码时,假设有下面一个foo()子函数的实现。 从安全的角度看,会存在安全漏洞吗?有的话,请
    (1)描述漏洞细节,
    (2)说明可以利用的方法,
    (3) 还有该怎么修补漏洞。没有的话,也请说明为什么。

    int foo((void*funcp)()) {

        char *ptr = pointer_to_an_array;

        char buf[128];

        gets(buf);

        strncpy(ptr,buf,8)

        (*funcp)();

    }



     ptr 定义在 buf 的前面。在栈上开变量的话,后开的内存地址较小,也就是 ptr 是恰好接在 buf 数组的后面。所以如果数组越界就可以修改 ptr 指向的内存地址。


    第36题:


     写一个函数找出一个整数数组中,第二大的数



     

    int Find_Second_Max(int data[],int n)

    {

        if(n<2) return -1;

        int max_num = max(data[0],data[1]);

        int sec_num = min(data[0],data[1]);

        for(int i=2;i<n;i++)

        {

            if(data[i]>=max_num);

            {

                sec_num = max_num;

                max_num = data[i];

            }

            else if(data[i] > sec_num)//排除等于情况

                sec_num = data[i];

        }

        return sec_num;

    }


    关联标签:
    天乐棋牌