阿里云大数据开发一面面经,已过,面试题已配答案
1、数据库三范式
第一范式:(字段不能重复且不能分解)
我们也叫1NF。这个范式主要还是让我们去看看表中不要存在可以被分割的列,同时表的列不能重复。当然,在实际操作过程中,我们如果录入相同的列,系统也是会报错的。
第二范式:(增加主键)
我们也叫2NF。这个范式的前提是必须要先满足第一范式的要求。当然,2NF的主要特点还是主键(从候选码挑选出来的字段,候选码是能决定唯一一行记录的属性组),所谓主键也是是能够决定一行数据的候选码。也就是说,主键可以是一列或者多列组成的,只要能够根据主键,马上能精确到特定的一行数据即可。
这里要注意的是,主键(我们有时候也会叫主属性)内存的值不能为空!
第三范式:(消除非主键的传递关系)
我们也叫3NF。这个范式的前提必须先满足第二范式的要求。第三范式主要是要看表中的非主键字段(列)与主键字段是否含有传递关系。什么叫是否有传递关系呢?
假设有一张表如下图:
这个表中的“商品类别名称”、“商品类别描述”其实是可以根据“商品类别编号”这个字段去检索到的,在这个表中具有字段传递关系。如果按照这个表去存储数据库的话,意味着要将“商品类别名称”、“商品类别描述”两个字段的数据重复很多次,使得表的空间产生严重冗余。因此,我们考虑将这个表拆分为两个表,如图所示。
这样建立数据表,就符合了数据库第三范式3NF规范。如果我们想要在表内单独增加一个商品类别也相当方便,假设我们系统想要显示出来我们的商品类别,那么就更方便了。
在实际开发中,我们的系统一般符合3NF就可以了,但是在实际工作生产过程中,为了优化我们的系统性能,有时候可能会牺牲数据空间换取工作性能,最终部分表的关系只能符合2NF。这种情况也是非常正常的。
2、队列
队列(Queue)。队列简称队。是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。其操作特性为先进先出(First In First Out,FIFO),并且只允许在队尾进,队头出。
至于其他的内容,网上也有很多了,这里就不多概述了。
3、OSI七层协议
4、三次握手
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
进行三次握手:
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SENT 状态。
首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号。
第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD 的状态。
在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y。
第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。
确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。
发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。
在socket编程中,客户端执行connect()时,将触发三次握手。
5、四次挥手
建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。
刚开始双方都处于ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。
在socket编程中,任何一方执行close()操作即可产生挥手操作。
6、ACID
分别是原子性、一致性、隔离性、持久性。
1、原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
2、一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。举例来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账、转几次账,事务结束后两个用户的钱相加起来应该还得是1000,这就是事务的一致性。
3、隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如同时操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。
4、持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务已经正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成。否则的话就会造成我们虽然看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。这是不允许的。
7、HDFS架构
架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。下面我们分别介绍这四个组成部分。
1)Client:就是客户端
(1)文件切分。文件上传HDFS的时候,Client将文件切分成一个一个的Block,然后进行存储;
(2)与NameNode交互,获取文件的位置信息;
(3)与DataNode交互,读取或者写入数据;
(4)Client提供一些命令来管理HDFS,比如启动或者关闭HDFS;
(5)Client可以通过一些命令来访问HDFS;
2)NameNode:就是Master,它是一个主管、管理者
(1)管理HDFS的名称空间;
(2)管理数据块(Block)映射信息;
(3)配置副本策略;
(4)处理客户端读写请求。
3)DataNode:就是Slave。NameNode下达命令,DataNode执行实际的操作
(1)存储实际的数据块;
(2)执行数据块的读/写操作。
4)Secondary NameNode:并非NameNode的热备。当NameNode挂掉的时候,它并不能马上替换NameNode并提供服务
(1)辅助NameNode,分担其工作量;
(2)定期合并Fsimage和Edits,并推送给NameNode;
(3)在紧急情况下,可辅助恢复NameNode。
8、Spark RDD
RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象。代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。
RDD特点:
1)弹性
存储的弹性:内存和磁盘的自动切换;
容错的弹性:数据丢失可以自动回复;
计算的弹性:计算出错重试机制;
分片的弹性:可根据需要重新分片。
2)分布式
数据存储在大数据集群的不同节点上
3)数据集
RDD封装了计算逻辑,并不保存数据
4)数据抽象
RDD是一个抽象类,需要子类具体实现
5)不可变
RDD封装了计算逻辑,是不可以改变的,想要改变,只能产生新的RDD,在新的RDD里面封装计算逻辑
6)可分区、并行计算
RDD属性:
1)一组分区(Partition),即是数据集的基本组成单位;
2)一个计算每个分区的函数;
3)RDD之间的依赖关系;
4)一个Partitioner,即RDD的分片函数;控制分区的数据流向(键值对);
5)一个列表,存储存取每个Partition的优先位置(preferredlocation)。移动数据不如移动资源,除非资源不够。
9、分布式一致性协议
为了解决数据一致性问题,出现了很多的一致性协议和算法。比如 2PC(两阶段提交),3PC(三阶段提交),Paxos算法等等。
2PC(两阶段提交)
Two-phase Commit(2PC):保证一个事务跨越多个节点时保持 ACID 特性;
两类节点:协调者(Coordinator)和参与者(Participants),协调者只有一个,参与者可以有多个。
过程:
- 准备阶段:协调者询问参与者事务是否执行成功;
- 提交阶段:如果事务在每个参与者上都执行成功,协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。
需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。
存在的问题
- 参与者发生故障。解决方案:可以给事务设置一个超时时间,如果某个参与者一直不响应,那么认为事务执行失败。
- 协调者发生故障。解决方案:将操作日志同步到备用协调者,让备用协调者接替后续工作。
3PC(三阶段提交)
2PC存在的一系列问题,比如单点,容错机制缺陷等等,从而产生了 3PC(三阶段提交) 。那么这三阶段又分别是什么呢?
千万不要吧PC理解成个人电脑了,其实他们是 phase-commit 的缩写,即阶段提交。
- CanCommit阶段:协调者向所有参与者发送 CanCommit 请求,参与者收到请求后会根据自身情况查看是否能执行事务,如果可以则返回 YES 响应并进入预备状态,否则返回 NO 。
- PreCommit阶段:协调者根据参与者返回的响应来决定是否可以进行下面的 PreCommit 操作。如果上面参与者返回的都是 YES,那么协调者将向所有参与者发送 PreCommit 预提交请求,参与者收到预提交请求后,会进行事务的执行操作,并将 Undo 和 Redo 信息写入事务日志中 ,最后如果参与者顺利执行了事务则给协调者返回成功的响应。如果在第一阶段协调者收到了 任何一个 NO 的信息,或者 在一定时间内 并没有收到全部的参与者的响应,那么就会中断事务,它会向所有参与者发送中断请求(abort),参与者收到中断请求之后会立即中断事务,或者在一定时间内没有收到协调者的请求,它也会中断事务。
- DoCommit阶段:这个阶段其实和 2PC 的第二阶段差不多,如果协调者收到了所有参与者在 PreCommit 阶段的 YES 响应,那么协调者将会给所有参与者发送 DoCommit 请求,参与者收到 DoCommit 请求后则会进行事务的提交工作,完成后则会给协调者返回响应,协调者收到所有参与者返回的事务提交成功的响应之后则完成事务。若协调者在 PreCommit 阶段 收到了任何一个 NO 或者在一定时间内没有收到所有参与者的响应 ,那么就会进行中断请求的发送,参与者收到中断请求后则会 通过上面记录的回滚日志 来进行事务的回滚操作,并向协调者反馈回滚状况,协调者收到参与者返回的消息后,中断事务。
这里是 3PC 在成功的环境下的流程图,你可以看到 3PC 在很多地方进行了超时中断的处理,比如协调者在指定时间内为收到全部的确认消息则进行事务中断的处理,这样能 减少同步阻塞的时间 。还有需要注意的是,3PC 在 DoCommit 阶段参与者如未收到协调者发送的提交事务的请求,它会在一定时间内进行事务的提交。为什么这么做呢?是因为这个时候我们肯定保证了在第一阶段所有的协调者全部返回了可以执行事务的响应,这个时候我们有理由相信其他系统都能进行事务的执行和提交,所以不管协调者有没有发消息给参与者,进入第三阶段参与者都会进行事务的提交操作。
总之,3PC 通过一系列的超时机制很好的缓解了阻塞问题,但是最重要的一致性并没有得到根本的解决,比如在 PreCommit 阶段,当一个参与者收到了请求之后其他参与者和协调者挂了或者出现了网络分区,这个时候收到消息的参与者都会进行事务提交,这就会出现数据不一致性问题。
Paxos 算法
Paxos 算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一,其解决的问题就是在分布式系统中如何就某个值(决议)达成一致 。
在 Paxos 中主要有三个角色,分别为 Proposer提案者、Acceptor表决者、Learner学习者。Paxos 算法和 2PC 一样,也有两个阶段,分别为 Prepare 和 accept 阶段。
1)prepare 阶段
- Proposer提案者:负责提出 proposal,每个提案者在提出提案时都会首先获取到一个 具有全局唯一性的、递增的提案编号N,即在整个集群中是唯一的编号 N,然后将该编号赋予其要提出的提案,在第一阶段是只将提案编号发送给所有的表决者。
- Acceptor表决者:每个表决者在 accept 某提案后,会将该提案编号N记录在本地,这样每个表决者中保存的已经被 accept 的提案中会存在一个编号最大的提案,其编号假设为 maxN。每个表决者仅会 accept 编号大于自己本地 maxN 的提案,在批准提案时表决者会将以前接受过的最大编号的提案作为响应反馈给 Proposer 。
下面是 prepare 阶段的流程图,你可以对照着参考一下。
2)accept 阶段
当一个提案被 Proposer 提出后,如果 Proposer 收到了超过半数的 Acceptor 的批准(Proposer 本身同意),那么此时 Proposer 会给所有的 Acceptor 发送真正的提案(你可以理解为第一阶段为试探),这个时候 Proposer 就会发送提案的内容和提案编号。
表决者收到提案请求后会再次比较本身已经批准过的最大提案编号和该提案编号,如果该提案编号 大于等于 已经批准过的最大提案编号,那么就 accept 该提案(此时执行提案内容但不提交),随后将情况返回给 Proposer 。如果不满足则不回应或者返回 NO 。
当 Proposer 收到超过半数的 accept ,那么它这个时候会向所有的 acceptor 发送提案的提交请求。需要注意的是,因为上述仅仅是超过半数的 acceptor 批准执行了该提案内容,其他没有批准的并没有执行该提案内容,所以这个时候需要向未批准的 acceptor 发送提案内容和提案编号并让它无条件执行和提交,而对于前面已经批准过该提案的 acceptor 来说 仅仅需要发送该提案的编号 ,让 acceptor 执行提交就行了。
而如果 Proposer 如果没有收到超过半数的 accept 那么它将会将 递增 该 Proposal 的编号,然后 重新进入 Prepare 阶段 。
这个题可以仔细看看JavaGuide的解释,讲的很详细
10、实习经历
这个每个人肯定是都不一样了,跟一面一样,说清楚自己的就行
11、数据仓库维度建模
维度模型如图所示,主要应用于OLAP系统中,通常以某一个事实表为中心进行表的组织,主要面向业务,特征是可能存在数据的冗余,但是能方便的得到数据。
关系模型虽然冗余少,但是在大规模数据,跨表分析统计查询过程中,会造成多表关联,这会大大降低执行效率。所以一般都会采用维度模型建模,把相关各种表整理成两种:事实表和维度表两种。
在维度建模的基础上又可分为三种模型:星型模型、雪花模型、星座模型。
维度建模是从分析决策的需求出发构建模型,为分析需求服务,因此它重点关注用户如何更快速的完成需求分析,同事具有较好的大规模复杂查询的相应能力。其典型的代表是星型模型,以及在一些特殊场景下使用的雪花模型。
维度建模设计分为以下步骤:
- 选择需要进行分析决策的业务过程
- 定义粒度
- 识别维度
- 确认事实
1)星型模型
星型模式是维度模型中最简单的形式,也是数据仓库以及数据集市开发中使用最广泛的形式。星型模式由事实表和维度表组成,一个星型模式中可以有一个或多个事实表,每个事实表引用任意数量的维度表。
星型模型与雪花模型的区别主要在于维度的层级,标准的星型模型维度只有一层,而雪花模型可能会涉及多层。
2)雪花模型
雪花模式是一种多维模型中表的逻辑布局,与星型模式相同,雪花模式也是由事实表和维度表所组成。所谓的“雪花化”就是将星型模型中的维度表进行规范化处理。当所有的维度表完成规范化后,就形成了以事实表为中心的雪花型结构,即雪花模式。
3)星座模型
数据仓库由多个主题构成,包含多个事实表,而维表是公共的,可以共享(例如两张事实表共用一些维度表时,就叫做星型模型),这种模式可以看做星型模式的汇集,因而称作星系模式或者事实星座模式。
4)模型选择
在数据仓库建模时,会涉及到模式的选择,我们要根据不同模式的特点选择适合具体业务的模式。
星型还是雪花,取决于性能优先,还是灵活更优先。
在实际开发中,不会绝对选择一种,根据情况灵活组合,甚至并存(一层维度和多层维度都保存)。但是整体看来,更倾向于维度更少的星型模型。
12、建模常用理论
可以看一下我整理的数据仓库的内容:https://www.nowcoder.com/discuss/934440
13、大数据的发展
先往好的说一通,然后再一个“但是”转折,凡事都有利有弊,吹牛就行~
比如:
1、党的十九大提出“推动互联网、大数据、人工智能和实体经济深度融合”。2、2020年初,中央推出34万亿“新基建”投资计划
"新基建"投资规模拆分 | |
项目 | 2020年投资规模(亿元) |
5G | 3000 |
特高压 | 600 |
轨道交通 | 5000 |
充电桩 | 100 |
数据中心 | 1000 |
人工智能 | 350 |
工业互联网 | 100 |
合计 | 10150 |
3、下一个风口
2020年是5G的元年,国家在大力铺设5G设备,2021年就是5G手机应用的开 始,也是大数据要爆发的1年。5G带来的是每秒钟10g的数据,会给每家公司都带来海量的数据。那么传统的Java工具根本解决不了海量数据的存储。就更不用说海量数据的计算了。如果你对5G的感触不够深,可以回忆一下3G和4G的区别。3G时只能打电话、发短信,当时还觉得很好,觉得3G不错。但是4G来了后,大家很少打电话和发短信了,都改为语音、视频、直播、网上购物等生活方式,带火了淘宝、京东、美团、字节跳动等企业。没有跟上节奏的百度,有点摇摇欲坠。
自古不变的真理:先入行者吃肉,后入行者喝汤,最后到的买单!
4、人才紧缺、竞争压力小
有句话叫:“选择大于努力”选择一个好的方向,少奋斗十年。是否记得国家在2017年才开设大数据课程,当时是北京大学、人民大学等25所高校开设 第一批大数据课程。今年才2021年。也就是今年才毕业,那么像Java、前端大学已经开设多少年了,包括培训班都加在一起,10多年,可想而知目前市场上, Java和前端的人才有多少。
大数据的人才目前除了培训机构培养的,没有真正的科班毕业,而且真正能培养好大数据人才的培训机构又有几个。 所以目前选择大数据是最佳选择。如果担心自己不是科班,其实也大可不必,因为大学真的学不了啥。只要是能考上本科,说明你不笨,那学大数据就没问题。
但是,无论什么行业,都要有自己的技术,不能站的太高,也要多做开源的东西,打好基础,迎接未知挑战。
14、最难的一次经历
跟实习经历一样,各人回答自己的就行,别搞得太离谱