字节跳动大数据开发面试题-附答案 (二)

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 此面试题来自牛客网友分享的字节跳动应届一面,面试时长一小时。 网友情况:985 本硕。

下面就分几个方面介绍两个框架的主要区别:


  1. 架构模型:


  • Spark Streaming 在运行时的主要角色包括:Master、Worker、Driver、Executor;


  • Flink 在运行时主要包:Jobmanager、Taskmanager 和 Slot。


  1. 任务调度:


  • Spark Streaming 连续不断的生成微小的数据批次,构建有向无环图 DAG, Spark Streaming 会依次创 DStreamGraph、JobGenerator、JobScheduler;


  • Flink 根据用户提交的代码生成 StreamGraph,经过优化生成 JobGraph,然后提交给 JobManager 进行处理, JobManager 会根据 JobGraph 生成 ExecutionGraph,ExecutionGraph 是 Flink 调度最核心的数据结构,JobManager 根据 ExecutionGraph 对 Job 进行调度。


  1. 时间机制:


  • Spark Streaming 支持的时间机制有限,只支持处理时间。


  • Flink 支持了流处理程序在时间上的三个定义:处理时间、事件时间、注入时间。同时也支持 watermark 机 制来处理滞后数据。


  1. 容错机制:


  • 对于 Spark Streaming 任务,我们可以设置 checkpoint,然后假如发生故障并重启,我们可以从上次 checkpoint 之处恢复,但是这个行为只能使得数据不丢失,可能 会重复处理,不能做到恰好一次处理语义。


  • Flink 则使用两阶段提交协议来解决这个问题。

Flink 的两阶段提交协议具体可以看这篇文章:八张图搞懂 Flink 端到端精准一次处理语义 Exactly-once


9. spark 的几种 shuffle 说下?为什么要丢弃 hashshuffle?


前段时间刚写的,可以看下:Spark 的两种核心 Shuffle 详解

10. java gc 可达性分析+垃圾回收器+垃圾回收算法+为什么分代垃圾回收+调优


JVM 相关的面试题可看这篇文章,文中第四、五题和本问题相关:精选大数据面试真题 JVM 专项


11. 数据库引擎,innodb 索引实现+聚集和非聚集区别+为什么用 b+树不用 hash


innodb 索引实现


innoDB使用的是聚集索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。


第二步使用主键在主索引B+树中再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。


聚集索引和非聚集索引的区别


  • 聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。
  • 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。
  • 聚集索引:物理存储按照索引排序;聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序。
  • 非聚集索引:物理存储不按照索引排序;非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序。
  • 索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。


数据库索引使用B+树原因:


InnoDB采用B+树结构,是因为B+树能够很好地配合磁盘的读写特性,减少单次查询的磁盘访问次数,降低IO、提升性能等。


数据库索引不适合用hash的原因


  1. 区间值难找。因为单个值计算会很快,而找区间值,比如 100 < id < 200 就悲催了,需要遍历全部hash节点。


  1. 排序难。通过hash算法,也就是压缩算法,可能会很大的值和很小的值落在同一个hash桶里,比如一万个数压缩成1000个数存到hash桶里,也就是会产生hash冲突。


  1. 不支持利用索引完成排序、以及like ‘xxx%’ 这样的部分模糊查询。


  1. 不支持联合索引的最左前缀匹配规则。


12. 聊聊 tcp 和 udp 的区别


简单说下:


  1. TCP面向连接 (如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。


  1. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。


Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。


  1. UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。


  1. 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。


  1. TCP对系统资源要求较多;UDP对系统资源要求较少。


13. http 知道吗?说一下


超文本传输协议(缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。


HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。


以下是 HTTP 请求/响应的步骤:


  1. 客户端连接到Web服务器:


一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.baidu.com


  1. 发送HTTP请求:


通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。


  1. 服务器接受请求并返回HTTP响应:


Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。


  1. 释放连接TCP连接:


若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;


  1. 客户端浏览器解析HTML内容:


客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。


14. http 版本之间的比较


这道题字节经常问,需要记住:


http0.9


最初的http版本,仅支持get方法,只能传输纯文本内容,所以请求结束服务段会给客户端返回一个HTML格式的字符串,然后由浏览器自己渲染。


http0.9是典型的无状态连接(无状态是指协议对于事务处理没有记忆功能,对同一个url请求没有上下文关系,每次的请求都是独立的,服务器中没有保存客户端的状态)


http1.0


这个版本后任何文件形式都可以被传输,本质上支持长连接,但是默认还是短连接,增加了keep-alive关键字来由短链接变成长连接。


HTTP的请求和回应格式也发生了变化,除了要传输的数据之外,每次通信都包含头信息,用来描述一些信息。


还增加了状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。


http1.1


HTTP1.1最大的变化就是引入了长链接,也就是TCP链接默认是不关闭的可以被多个请求复用。客户端或者服务器如果长时间发现对方没有活动就会关闭链接,但是规范的做法是客户端在最后一个请求的时候要求服务器关闭链接。对于同一个域名,目前浏览器支持建立6个长链接。


节约带宽,HTTP1.1支持只发送header头信息不带任何body信息,如果服务器认为客户端有权限请求指定数据那就返回100,没有就返回401,当客户端收到100的时候可以才把要请求的信息发给服务器。并且1.1还支持了请求部分内容,如果当前客户端已经有一部分资源了,只需要向服务器请求另外的部分资源即可,这也是支持文件断点续传的基础。


1.1版本中增加了host处理,在HTTP1.0中认为每台服务器都绑定一个唯一的ip地址,因此在URL中并没有传递主机名,但是随着虚拟机技术的发展,可能在一台物理机器上存在多个虚拟主机,并且他们共享了一个ip地址,http1.1中请求消息和响应消息都支持host头域,如果不存在还会报出错误。


http2.0


多路复用:在一个连接里面并发处理请求,不像http1.1在一个tcp连接中各个请求是串行的,花销很大。


在1.0版本后增加了header头信息,2.0版本通过算法把header进行了压缩这样数据体积就更小,在网络上传输就更快。


服务端有了推送功能,将客户端感兴趣的东西推给客户端,当客户端请求这些时,直接去缓存中取就行。


15. 让你设计一个 hash 表,怎么设计?


可以把java的hashmap的实现原理说下,因为这就是hash表的经典设计!内容较多,并且网上资料很多,可以自己搜索查看!


16. 时间不多了,手撸一个二分查找


二分查找图解:


image.png


二分查找:时间复杂度O(log2n);空间复杂度O(1)


def binarySearch(arr:Array[Int],left:Int,right:Int,findVal:Int): Int={
  if(left>right){//递归退出条件,找不到,返回-1
    -1
  }
  val midIndex = (left+right)/2
  if (findVal < arr(midIndex)){//向左递归查找
    binarySearch(arr,left,midIndex,findVal)
  }else if(findVal > arr(midIndex)){//向右递归查找
    binarySearch(arr,midIndex,right,findVal)
  }else{//查找到,返回下标
    midIndex
  }
}


拓展需求:当一个有序数组中,有多个相同的数值时,如何将所有的数值都查找到。


/*
{1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中,有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000.
//分析
1. 返回的结果是一个可变数组 ArrayBuffer
2. 在找到结果时,向左边扫描,向右边扫描 [条件]
3. 找到结果后,就加入到ArrayBuffer
 */
def binarySearch2(arr: Array[Int], l: Int, r: Int,
                  findVal: Int): ArrayBuffer[Int] = {
  //找不到条件?
  if (l > r) {
    return ArrayBuffer()
  }
  val midIndex = (l + r) / 2
  val midVal = arr(midIndex)
  if (midVal > findVal) {
    //向左进行递归查找
    binarySearch2(arr, l, midIndex - 1, findVal)
  } else if (midVal < findVal) { //向右进行递归查找
    binarySearch2(arr, midIndex + 1, r, findVal)
  } else {
    println("midIndex=" + midIndex)
    //定义一个可变数组
    val resArr = ArrayBuffer[Int]()
    //向左边扫描
    var temp = midIndex - 1
    breakable {
      while (true) {
        if (temp < 0 || arr(temp) != findVal) {
          break()
        }
        if (arr(temp) == findVal) {
          resArr.append(temp)
        }
        temp -= 1
      }
    }
    //将中间这个索引加入
    resArr.append(midIndex)
    //向右边扫描
    temp = midIndex + 1
    breakable {
      while (true) {
        if (temp > arr.length - 1 || arr(temp) != findVal) {
          break()
        }
        if (arr(temp) == findVal) {
          resArr.append(temp)
        }
        temp += 1
      }
    }
    return resArr
  }
相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
相关文章
|
1月前
|
存储 安全 Java
每日大厂面试题大汇总 —— 今日的是“美团-后端开发-一面”
文章汇总了美团后端开发一面的面试题目,内容涉及哈希表、HashMap、二叉树遍历、数据库索引、死锁、事务隔离级别、Java对象相等性、多态、线程池拒绝策略、CAS、设计模式、Spring事务传播机制及RPC序列化工具等。
48 0
|
1月前
|
存储 消息中间件 NoSQL
每日大厂面试题大汇总 —— 今日的是“京东-后端开发-一面”
文章汇总了京东后端开发一面的面试题目,包括ArrayList与LinkedList的区别、HashMap的数据结构和操作、线程安全问题、线程池参数、MySQL存储引擎、Redis性能和线程模型、分布式锁处理、HTTP与HTTPS、Kafka等方面的问题。
116 0
|
1月前
|
SQL 安全 关系型数据库
第三次面试总结 - 吉云集团 - 全栈开发
本文是作者对吉云集团全栈开发岗位的第三次面试总结,面试结果非常好,内容全面覆盖了Java基础、MySQL和项目经验,作者认为自己的MySQL基础知识稍弱,需要加强。
35 0
第三次面试总结 - 吉云集团 - 全栈开发
|
1月前
|
消息中间件 存储 前端开发
资深Android开发的5个经典面试题
本文首发于公众号“AntDream”,欢迎关注。文章详细解答了五个常见的Android面试题,涵盖内存泄漏与溢出、Binder机制、MVC/MVP/MVVM架构、Handler机制及Context对象等内容,帮助读者深入了解Android开发的核心概念。
35 0
|
1月前
|
NoSQL 前端开发 关系型数据库
第四次面试总结 — 嘉和智能 - 全栈开发
本文是作者对嘉和智能全栈开发岗位的第四次面试总结,主要围绕对各种技术栈的了解程度进行提问,包括数据库的使用经验、对Redis和nginx的理解以及前端技能水平。
18 0
|
1月前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
31 0
|
1月前
|
存储 Java 数据库
每日大厂面试题大汇总 —— 今日的是“顺丰-后端开发-一面”
文章汇总了顺丰后端开发一面的面试题目,涵盖了Java虚拟机内存模型、HashMap与ConcurrentHashMap的区别、Spring框架设计模式、SpringBoot与SpringMVC差异、Nacos注册中心原理、Seata分布式架构、MySQL事务隔离级别、数据库死锁问题解决方法、乐观锁实现方式、HBASE底层设计、BIO与NIO区别、以及为何不使用现有开源框架而选择自建平台等问题。
20 0
|
2月前
|
SQL 分布式计算 大数据
代码编码原则和规范大数据开发
此文档详细规定了SQL代码的编写规范,包括代码的清晰度,执行效率,以及注释的必要性。它强调所有SQL关键字需统一使用大写或小写,并禁止使用select *操作。此外,还规定了代码头部的信息模板,字段排列方式,INSERT, SELECT子句的格式,运算符的使用,CASE语句编写规则,查询嵌套规范,表别名定义,以及SQL注释的添加方法。这些规则有助于提升代码的可读性和可维护性。
48 0
|
2月前
|
SQL 分布式计算 大数据
大数据开发SQL代码编码原则和规范
这段SQL编码原则强调代码的功能完整性、清晰度、执行效率及可读性,通过统一关键词大小写、缩进量以及禁止使用模糊操作如select *等手段提升代码质量。此外,SQL编码规范还详细规定了代码头部信息、字段与子句排列、运算符前后间隔、CASE语句编写、查询嵌套、表别名定义以及SQL注释的具体要求,确保代码的一致性和维护性。
98 0
|
3月前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
264 0
下一篇
无影云桌面