热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《关于我的那些面经》——百度后端(附答案)

作者保证,本系列全是纯干货真实记录,绝对不是某些营销号瞎编乱造的面试。一、公司的简介百度是全球最大的中文搜索引擎,是中国最大的以信息和知

百度LOGO


作者保证,本系列全是纯干货真实记录,绝对不是某些营销号瞎编乱造的面试。



一、公司的简介

百度是全球最大的中文搜索引擎,是中国最大的以信息和知识为核心的互联网综合服务公司,更是全球领先的人工智能平台型公司。2000年1月1日创立于中关村,公司创始人李彦宏拥有“超链分析”技术专利,也使中国成为美国、俄罗斯、和韩国之外,全球仅有的4个拥有搜索引擎核心技术的国家之一。

百度作为全球最大的中文搜索引擎,百度每天响应来自100余个国家和地区的数十亿次搜索请求,是网民获取中文信息的最主要入口。百度以“用科技让复杂的世界更简单”为使命,不断坚持技术创新,致力于“成为最懂用户,并能帮助人们成长的全球顶级高科技公司”。

百度是中国最大的以信息和知识为核心的互联网综合服务公司。在AI驱动下,百度的移动生态是中国最大的以信息和知识为核心的移动生态,以百家号、智能小程序和托管页为主要支柱。2019年百度用户规模突破10亿。百度App日活跃用户2.22亿,信息流位居中国第一。百家号创作者达到300万。百度智能小程序是国内唯一完全开源的小程序平台,月活用户规模破3.54亿。百度知道、百度百科、百度文库等六大知识类产品累计生产超10亿条高质量内容,构建了中国最大的知识内容体系。

百度是全球领先的人工智能平台型公司。百度大脑是中国唯一的“软硬一体AI大生产平台”,是百度AI的集大成,对外全方位输出超过250多项AI能力。飞桨是中国首个全面开源开放、功能完备的产业级深度学习平台,是中国自主研发的“智能时代的操作系统”。百度智能云是百度AI To B业务的重要承载者和输出者,是产业智能化领导者。小度助手是中国最大的对话式人工智能操作系统,拥有中国市场规模最大、最繁荣的对话式人工智能生态,2020年3月,小度助手语音交互次数超过65亿次。作为全球最大自动驾驶开放平台,Apollo代表中国最强自动驾驶实力,被知名研究公司Navigant Research列为全球四大自动驾驶领域领导者之一。目前已形成自动驾驶、车路协同、智能车联三大开放平台。自动驾驶方面,超过十项中国第一,技术实力领跑行业。智能交通方面,百度“ACE交通引擎”是全球首个车路行融合的全栈式智能交通解决方案。

 

废话少说BATTMD哪个公司不是吹的天花乱坠,直接看工资

校招

SP代表special offer

SSP的offer级别还在SP之上

一般情况下薪资专栏中的18*15

是指1.8w一个月,一年总共15个月

其中15一般是13个月工资,包括2个月的年终奖

简单科普结束以后我们来看看数据吧

这是硕士的薪资,本科的自行减去1-2k,测试岗也是从研发减去1-2k。

社招

薪资方面呢,在BATTMD中不算很有竞争力,但是今年还是涨了不少,算是很有诚意,适合喜欢所谓“技术”以及没有更好选择的同学去。


二、对公司的评价

产品之神俞军在移动互联网前夕走了,百度在10-20掉队了,这是不可否认的事实。但是最近两年,百度一直在改变,押宝在无人车上。去年股票也确实表现不错,暂时可以坚持下去。

市值:1145亿美元(比去年翻了不止一倍,之前还以为他凉凉了)


三、面试过程

1)如何判断链表是否有环?

像模像样的要我现场写了一遍,说了一遍思路。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

 

示例 2:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

 

思路:首先我们要明白,链表不可能出现这种情况:

因为一个结点只有一个指针,所以链表只可能向实例一那样,在末尾出现一个环。

慢指针一次一步,快指针一次两步。能相遇就是有环,反之没有环。就像操场跑步,跑的快的总有一天可以追慢的一圈,相遇。

/*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public boolean hasCycle(ListNode head) {if (head == null || head.next == null) {return false;}ListNode slow = head;ListNode fast = head.next;while (slow != fast) {if (fast == null || fast.next == null) {return false;}slow = slow.next;fast = fast.next.next;}return true;}
}

那么,这对于懂算法的人来说可能是烂大街的问题,有些人可能不屑于看了,那么,第二个问题来了:如果让那个快指针一次走三步,还能不能做正确的答案呢?一次四步呢?五步呢?

如果看的人多,我会在下一期公布答案哈哈,大家不要以为应试被题就可以过关。

2)介绍一下堆这种数据结构

大根堆要求

①根节点的关键字既大于或等于左子树的关键字值,又大于或等于右子树的关键字值。

②为完全二叉树。

注意这是递归定义的。

对于大根小根堆,递归定义,实现,空间复杂度,各种操作的时间复杂度,真实写二叉树的情况和数组模拟的情况都要会。

有人要问了,会这些算法有啥用?其实Java的优先队列就是堆结构。八大排序之一的堆排序也是数组上堆结构,面试官让我手动实现一个,以下是实现。

/*
================================================
功能:堆排序
输入:数组名称(也就是数组首地址)、数组中元素个数
注:画画
================================================
*/
/*
功能:建堆
输入:数组名称(也就是数组首地址)、参与建堆元素的个数、从第几个元素开始
*/
void sift(int *x, int n, int s)
{int t, k, j;t = *(x+s); /*暂存开始元素*/k = s; /*开始元素下标*/j = 2*k + 1; /*左子树元素下标*/while (j}
/*
功能:堆排序
输入:数组名称(也就是数组首地址)、数组中元素个数
注:** ** - * ** * *
建堆时,从从后往前第一个非叶子节点开始调整,也就是“-”符号的位置
*/
void heap_sort(int *x, int n)
{int i, k, t;
//int *p;for (i=n/2-1; i>=0; i--){sift(x,n,i); /*初始建堆*/}for (k=n-1; k>=1; k--){t = *(x+0); /*堆顶放到最后*/*(x+0) = *(x+k);*(x+k) = t;sift(x,k,0); /*剩下的数再建堆*/}
}

3)排序知道哪些?来介绍介绍?

答:全知道,全会写,然后只说了冒泡的所有思路和优化、和快排BFPRT就被叫停了。我就把所有排序介绍和实现分享给大家。

全排序


一面结束,面试小哥表示对我很满意,说马上让另外一个人二面。


二面:

二面小哥说,一面说你算法贼强,咱们这次就不聊算法了,说说项目。

4)看我项目里用了redis,就问redis都有哪些数据结构。

我说有string、list、hash、set、zset。

问:你说的这些Java以及其他语言基本也都有,你说了解redis,那这些数据结构到底是不是快?咋实现的呢?

我举例子说了一下:


  • 1) 字符串

redis并未使用传统的c语言字符串表示,它自己构建了一种简单的动态字符串抽象类型。

当需要一个可以被修改的字符串时,redis就会使用自己实现的SDS(simple dynamic string)。比如在redis数据库里,包含字符串的键值对底层都是SDS实现的,不止如此,SDS还被用作缓冲区(buffer):比如AOF模块中的AOF缓冲区以及客户端状态中的输入缓冲区。

下面来具体看一下sds的实现:


  1. struct sdshdr

  2. {

  3. int len;//buf已使用字节数量(保存的字符串长度)

  4. int free;//未使用的字节数量

  5. char buf[];//用来保存字符串的字节数组

  6. };

sds遵循c中字符串以'\0'结尾的惯例,这一字节的空间不算在len之内。

这样的好处是,我们可以直接重用c中的一部分函数。比如printf;

    sds相对c的改进

    获取长度:c字符串并不记录自身长度,所以获取长度只能遍历一遍字符串,redis直接读取len即可。

    缓冲区安全:c字符串容易造成缓冲区溢出,比如:程序员没有分配足够的空间就执行拼接操作。而redis会先检查sds的空间是否满足所需要求,如果不满足会自动扩充。

    内存分配:由于c不记录字符串长度,对于包含了n个字符的字符串,底层总是一个长度n+1的数组,每一次长度变化,总是要对这个数组进行一次内存重新分配的操作。因为内存分配涉及复杂算法并且可能需要执行系统调用,所以它通常是比较耗时的操作。   

    redis内存分配:

1、空间预分配:如果修改后大小小于1MB,程序分配和len大小一样的未使用空间,如果修改后大于1MB,程序分配  1MB的未使用空间。修改长度时检查,够的话就直接使用未使用空间,不用再分配。 

2、惰性空间释放:字符串缩短时不需要释放空间,用free记录即可,留作以后使用。

    二进制安全

c字符串除了末尾外,不能包含空字符,否则程序读到空字符会误以为是结尾,这就限制了c字符串只能保存文本,二进制文件就不能保存了。

而redis字符串都是二进制安全的,因为有len来记录长度。


这就是redis中string的实现和要点,我大概都给他讲了一遍。然后他说你不用说了,又说到算法数据结构了,咱们聊点别的。


5)聊点实际的吧,你一直在吹redis,知道用redis会给你带来什么问题吗?

我有点懵,就给他说nosql和传动数据库的区别之类的,然后他说你不要给我说这些比较,举个例子,缓存雪崩听说过吗?我就明白他想聊什么了,又给他说了说以下内容。

缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就去后端系统查找(比如DB)。

一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

 

如何避免?

1:对查询结果为空的情况也进行缓存,这样,再次访问时,缓存层会直接返回空值。缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2:对一定不存在的key进行过滤。具体请看布隆过滤器

缓存击穿

是针对缓存中没有但数据库有的数据。

场景是,当Key失效后,假如瞬间突然涌入大量的请求,来请求同一个Key,这些请求不会命中Redis,都会请求到DB,导致数据库压力过大,甚至扛不住,挂掉。

解决办法

1、设置热点Key,自动检测热点Key,将热点Key的过期时间加大或者设置为永不过期,或者设置为逻辑上永不过期

2、加互斥锁。当发现没有命中Redis,去查数据库的时候,在执行更新缓存的操作上加锁,当一个线程访问时,其它线程等待,这个线程访问过后,缓存中的数据会被重建,这样其他线程就可以从缓存中取值。

缓存雪崩

是指大量Key同时失效,对这些Key的请求又会打到DB上,同样会导致数据库压力过大甚至挂掉。

解决办法

1)让Key的失效时间分散开,可以在统一的失效时间上再加一个随机值,或者使用更高级的算法分散失效时间。

2)构建多个redis实例,个别节点挂了还有别的可以用。

3)多级缓存:比如增加本地缓存,减小redis压力。

4)对存储层增加限流措施,当请求超出限制,提供降级服务(一般就是返回错误即可)


他说作为一个学生,知道这些知识就可以了,对我比较满意,说让三面。


三面面试官看样子是某个领导,问的比较随意。

6)输入网址到看到网页的过程

答:(能多细就多细,你背答案估计就死了,要理解)域名解析 --> TCP3次握手 --> 发http请求 --> 响应http请求,浏览器得到html代码 --> 浏览器解析代码,请求html代码中的资源(js、css、图片等) --> 浏览器对页面进行渲染呈现给用户

7)让手写快排(我寻思真就没别的可问了呗)

然后就结束了。

 


四、感受

感觉总体难度一般,问链表环问题改成三四步,我是没想到的,证明面试官有点东西。二面面试官给我的感觉应该也读过redis源码,我记录的应该不全,俩人这方面谈的挺投机。整体是挺好的体验,可能因为也是学长内推的关系,三次面试都像聊天一样就过去了。手写算法也基本没卡壳,平时因为很重视代码风格。自以为手撸代码他们也比较满意。结果就是通过所有面试发了offer,最后没去。


推荐阅读
  • 电商高并发解决方案详解
    本文以京东为例,详细探讨了电商中常见的高并发解决方案,包括多级缓存和Nginx限流技术,旨在帮助读者更好地理解和应用这些技术。 ... [详细]
  • Redis:缓存与内存数据库详解
    本文介绍了数据库的基本分类,重点探讨了关系型与非关系型数据库的区别,并详细解析了Redis作为非关系型数据库的特点、工作模式、优点及持久化机制。 ... [详细]
  • 大华股份2013届校园招聘软件算法类试题D卷
    一、填空题(共17题,每题3分,总共51分)1.设有inta5,*b,**c,执行语句c&b,b&a后,**c的值为________答:5 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
  • 实现系统调用
    实现系统调用一、实验环境​本次操作还是基于上次编译Linux0.11内核的实验环境进行操作。环境如下:二、实验目标​通过对上述实验原理的认识,相信 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • 本文探讨了如何在游戏启动画面中移除广告,特别是在游戏数据加载期间(大约5-6秒)广告会短暂显示的问题。通过调整XML布局和代码逻辑,可以实现广告的延迟加载或完全移除。 ... [详细]
  • Spring Boot + RabbitMQ 消息确认机制详解
    本文详细介绍如何在 Spring Boot 项目中使用 RabbitMQ 的消息确认机制,包括消息发送确认和消息接收确认,帮助开发者解决在实际操作中可能遇到的问题。 ... [详细]
  • Redis 是一个高性能的开源键值存储系统,支持多种数据结构。本文将详细介绍 Redis 中的六种底层数据结构及其在对象系统中的应用,包括字符串对象、列表对象、哈希对象、集合对象和有序集合对象。通过12张图解,帮助读者全面理解 Redis 的数据结构和对象系统。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • RocketMQ在秒杀时的应用
    目录一、RocketMQ是什么二、broker和nameserver2.1Broker2.2NameServer三、MQ在秒杀场景下的应用3.1利用MQ进行异步操作3. ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 本文深入探讨了MDK链接脚本的应用与优化技巧。首先,文章介绍了链接脚本的基本概念及其在嵌入式系统开发中的重要性。接着,通过具体实例详细分析了链接脚本的结构和功能,特别是在程序在FLASH中运行时,如何优化链接脚本以提高系统性能。此外,文章还讨论了无需将程序加载到SRAM中的技术细节,为开发者提供了实用的参考和指导。 ... [详细]
author-avatar
kenson4930
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有