讨论/求职面试/百度客户端|技术人求职记|三面面经(附答案) |2021|/
百度客户端|技术人求职记|三面面经(附答案) |2021|

主题一:C++

t1. 是否了解volatile关键字?

  1. volatile指的是易变的变量,该关键词提醒编译器其后所定义的变量随时都可能改变,因此编译后的程序每次需要存储或读取该变量时,都会直接从变量地址中读取数据。
  2. 若没有volatile,编译器可能优化读写,暂存某个变量至寄存器(寄存器速度快于内存),若该变量是由其他程序更新,就会出现不一致的现象。


t2. 简单说一下内存对齐的内容?

  1. CPU对不能被对齐量(要操作内存的大小)整除的内存地址的访问,便是访问未对齐内容,这或者对性能或者对可靠性造成影响,因此我们应该尽量避免访问未对齐内容,因此C/C++出现了内存对齐机制。
  2. 所有基础类型的对齐量就是其大小,但是struct、class、union的类型的对齐量等于其非静态成员变量中最大的对齐量。
  3. 比如一个结构体有一个char一个int一个short,那么该结构体的大小是12bytes,因为char后有三个空白填充,而short有两个空白填充。


t3.overload 、override、overwrite 之间的区别?

  1. Overload 重载,类内声明的几个具有不同参数列表的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
  2. Override 覆盖,子类重新定义基类中有相同名称、参数和返回值类型的虚函数,重写的基类中被重写的函数必须有virtual修饰。
  3. Overwrite 重写(重定义),若子类和基类的函数同名,但参数不同,则不管有无virtual,基类的函数被隐藏。若函数同名参数也相同,但没有virtual声明,则也被隐藏,否则就是重写了。



主题二:操作系统:

t1. 简要介绍一下局部性原理?用代码举例利用了时间局部性和空间局部性的算法?

  1. 局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。 包含时间局部性(近期很可能被再次访问)、空间局部性(临近空间很可能被访问)。
  2. 比如用一个临时变量sum计算一个数组A的和,那么遍历的过程中,我们根据内存顺序访问数组,利用了空间局部性,而每次都要对临时变量sum的访问便是利用了时间局部性。

t2. 说一下分页、分段、段页式分配的异同?

  1. 分页,用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。分页方式的优点是页长固定,因而便于构造页表、易于管理,且不存在外碎片。
  2. 分段,段是按照程序的自然分界划分的长度可以动态改变的区域。通常,程序员把子程序、操作数和常数等不同类型的数据划分到不同的段中,并且每个程序可以有多个相同类型的段。段的逻辑独立性使其易于编译、管理、修改和保护,段长可以根据需要动态改变,不存在内碎片。
  3. 段页式,程序的地址空间按逻辑单位分成基本独立的段,而每一段有自己的段名,再把每段分成固定大小的若干页。程序对内存的调入或调出是按页进行的。但它又可按段实现共享和保护。能有效地利用主存,为组织多道程序运行提供了方便,但增加了硬件成本、系统的复杂性和管理上的开销。



主题三:计算机网络:

t1. 是否了解RIP协议和OSPF协议?

  1. RIP(路由信息协议)

    RIP协议是一种采用距离向量算法的路由协议,基于距离-向量的路由选择协议。其设计思想简单,它要求路由器周期性地通知相邻路由器自己可以到达的网路,以及到达网络的距离(跳数),这里的“距离”实际上指的是“最短距离”。

    **简述RIP协议的工作原理:**路由器每30秒把自己的路由表发给邻居。路由器用邻居发来的路由表根据距离向量算法修改自己的路由表。初始时每个路由器只有到直连网距离为1的路由。

  2. OSPF(开放最短路径优先协议)

    OSPF不受某一家厂商控制,而是公开发表的。使用Dijikstra最短路径算法,使用分布式的链路状态协议。

    **简述OSPF协议的工作原理:**路由器互相发送直接相连的链路信息和它拥有的到其它路由器的链路信息。每个 OSPF 路由器维护相同自治系统拓扑结构的数据库。从这个数据库里,构造出最短路径树来计算出路由表。当拓扑结构发生变化时,OSPF 能迅速重新计算出路径,而只产生少量的路由协议流量。此外,所有 OSPF 路由选择协议的交换都是经过身份验证的。



主题四:算法

t1. 给定长度为 n1n - 1 的数组,所有元素均在 [1,n][1, n] 范围内,求唯一未出现的数字

int find(vector<int>& nums) {
    int t = 0, n = nums.size() + 1;
    for (int i = 1; i <= n; i++)
        t ^= i;
    for (int i = 0; i < n - 1; i++)
        t ^= nums[i];
    return t;
}

这道题可以用比较简单的映射作法,然后遍历一遍,看看哪个数字不存在即可找到答案。但是这样的话空间复杂度就是O(n)。

我们可以利用数学方法中的异或运算。当两个数相同时,异或结果为0,而任何数与0异或均为这个数。因此我们,可以先得到1一直异或到n的结果t,再将t与数组中每个数异或,最后留下来的数就是唯一未出现的数。空间复杂度也降低至O(1)O(1)

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

t2. 给定数组,将所有的 00 移动到数组末尾,要求时间复杂度 O(n)O(n)

本题采用双向查找的方式,分以下几个步骤完成:

  1. 设置数组左右两边的下标变量 i 和 j
  2. 先从数组右边开始查找不为 0 的数,等于 0 则用 continue 继续查找,直到找到再进行第 3 步
  3. 从左侧遍历查找等于 0 的数,找到之后与第2步找到的不为 0 的数进行互换
  4. 重复第 2 步和第 3 步直至一轮遍历结束,即可实现时间复杂度为 O(n)
void putzeroback(vector<int>& arr) { 
    int i = 0, j = arr.size()-1; 
    while(i < j) { 
        if(arr[j] == 0) { 
            j--; 
            continue; 
        } 
        if(arr[i] == 0) { 
            arr[i] = arr[j]; 
            arr[j] = 0; 
            j--; 
        } 
        i++; 
    } 
}


31
共 6 个回复

因为项目大家都不一样嘛,所以没有放上来。

2

嗯嗯

客户端问的问题好杂啊

学习了

感觉问的问题稍微有点少哇,而且没有项目问题呢

感谢大佬!