大数据开发总结

个人总结

kafka

1、kafka的消费者组是如何消费的?

一个分区只能被消费者组中的一个消费者消费
一个消费者组中的一个消费者可以消费多个分区
一个消费者组中的不同消费者消费的分区一定不会重复
一个topic可以有多个consumer group,但每个partition只会把消息发给该consumer group中的一个consummer

2、kafka为什么有消费者组?

(1)消费效率高
(2)消费模式灵活(广播模式,单播模式)
(3)便于故障容灾
https://blog.csdn.net/john1337/article/details/103060820
来自面试题库:
(1)如果所有的消费者都属于同一个组,消息会在消费者之间均衡
(2)如果所有的消费者都属于不同的组,就是发布-订阅模式,广播模式

3、kafka的数据offset读取流程

(1)连接zk集群,从ZK中拿到对应的topic的partition信息和partition的leader的相关信息
(2)连接到对应的leader对应的broker
(3)consumer将自己保存的offset发送给leader
(4)leader根据offset等信息定位到segment(索引文件和日志文件)
(5)根据索引文件中的内容,定位到日志文件中该偏移量对应的开始位置读取相应长度的数据并返回给consumer

flume

1、负载均衡和故障转移

load_balance和failover

Hadoop

1、Hadoop的job tracker和task tracker

(1)用户程序提交了一个job,job的信息就会被发送到Job Tracker,Job Tracker是Map-Reduce框架的中心,需要与集群中的机器定时通信heartbeat,需要管理哪些程序应该跑在哪些机器上,需要管理所有job失败、重启等.
(2)Task Tracker是MapReduce集群中每台机器都有的一个部分,他负责监视自己所在机器的资源情况,同时监视当前机器的task运行情况。TaskTracker会把这些信息通过heartbeat发送给JobTracker,JobTracker会收集这些信息以给新提交的job分配运行在哪些机器上。

在0.23.0版本之后,取而代之的是ResourceManager、ApplicationMaster、NodeManager

2、ResourceManager、NodeManager、ApplicationMaster 、Container

  1. ResourceManager
    (1)负责处理客户端请求
    (2)负责监控NodeManager
    (3)启动和监控ApplicationMaster
    (4)资源的分配与调度
  2. NodeManager
    (1)管理单个节点上的资源
    (2)处理来自ResourceManager的命令
    (3)处理来自ApplicationMaster
  3. ApplicationMaster
    (1)任务的监视和容错
    (2)申请资源,分配任务
  4. Container
    资源

3、为什么配置了HA,但是备用的节点起不来

小文件的影响,导致占用了大量的存储空间

java

1、进程间通信的方法,共享内存这种方式要注意什么问题?

https://www.cnblogs.com/joker-wz/p/11000489.html
linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程和全局变量在另一个进程中看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1吧数据从用户空间考到内核缓冲区,进程2在从内核缓冲区把数据读走,内核提供的这种机制叫做进程间通信。
在进程间完成数据传递需要借助操作系统的提供的特殊方法,如管道、命名管道、信号、消息队列、共享内存、信号量、套接字等。

使用共享内存效率高,但是问题如下:
(1)内存大小
(2)看这个地址吧 https://blog.csdn.net/weixin_30872671/article/details/96263270

2、线程与进程的区别

进程。
进程是程序的一次执行过程,是个动态概念。是程序在执行过程中分配和管理资源的基本单位,每个进程都有一个自己的地址空间。
线程。
线程是CPU调度和分派的基本单位,它可与同属一个进程的其他线程共享进程的拥有的资源。
区别

根本区别:进程是操作系统分配资源的基本单位,而线程是任务调度和执行的基本单位。
开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间切换会有较大的开销;线程可看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换开销小。
内存分配方面:系统在运行时会为每个进程分配不同的内存空间;而线程,除了CPU外,系统不会为线程分配内存。
一个进程可以包含>=1个线程。

3、TCP三次握手

第一次:客户主动连接服务器,向服务器发送SYN,假设系列号是J,服务器被动打开
第二次:服务器收到SYN后,会发送一个SYN和一个ACK给用户,ACK的序列号是J+1, SYN的序列号是K
第三次:客户收到信的SYN和ACK后,会向服务器回应ACK K+1,表示收到了,然后两边就可以开始发送数据了

4、get和post的区别

get和post是HTTP请求的两种基本方法,
区别:

  • 最直观的区别就是get把参数包含在URL中,POST通过request body传递参数
  • get传输的数据量小,因为受到URL长度限制;而post可以传输大量的数据
  • get是从服务器上获得数据,而post则是向服务器传递数据的
  • get不安全,因为一些操作可能被第三方看到,而post的所有操作对用户是不可见的
  • 值的字符集不同

5、http状态码

  • 1开头:信息状态码
  • 2开头:成功状态码
  • 3开头:重定向状态码
  • 4开头:客户端错误状态码
  • 5开头:服务端错误状态码

6、线程的同步方式?区别

1.有synchronized关键字修饰的方法
由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态
2.有synchronized修饰的代码块
被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
3.使用特殊域变量volatile实现线程同步
原理是每次线程要访问volatile修饰的变量时都是从内存中读取,而不是从缓存中读取,因此每个线程访问到的变量都是一样的,这样就保证了同步。
volatile不能保证原子操作,因此volatile不能代替synchronized。此外volatile会组织编译器对代码优化,降低了程序的执行效率
4.使用重入锁实现同步
java.util.concurrent包来支持同步
此时注意及时释放锁
5.使用局部变量实现线程同步
ThreadLocal

6、死锁

1、什么是死锁

由于两个过着两个以上的线程相互持有对方需要的资源,导致这些线程处于等待状态,无法执行

2、产生死锁的四个必要条件
  1. 互斥性:线程对资源的战友是排他性的,一个资源只能被一个线程占有,直到释放
  2. 请求和保持条件:一个线程对请求被占有资源发生阻塞时,对已经获得的资源不释放
  3. 不剥夺:一个线程在释放资源之前,其他的线程无法剥夺占用
  4. 循环等待:发生死锁时,线程进入死循环吗,永久阻塞
3、产生死锁的原因

当线程A持有独占锁a,并尝试去获取独占锁b 的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生阻塞现象。

  1. 竞争不可抢占性资源:P1已经打开了F1,想去打开F2,P2已经打开了F2,想去打开F1,但是F1和F都是不可抢占的,这是发生死锁
  2. 竞争可消耗资源引起死锁:进行间通信,如果顺序不当,会产生死锁。
  3. 进程推进顺序不当:进程在运行过程中,请求和释放资源的顺序不当,也同样会导致进程死锁
4、避免死锁的方法
  1. 破坏“请求和保持”条件
    想办法让进程不那么贪心,自己已经有了资源就不要去竞争那些不可抢占的资源
    2.破坏不可抢占资源
    允许进程进行抢占,如果去抢资源,就是放自己的资源;或只要优先级大,可以抢到
    3.破坏“循环等待”条件
    将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序提出
5、死锁的检测

1、每个进程、每个资源指定唯一编号
2、设定一张资源分配表,记录各进程与占用资源之间的关系
3、设置一张进程等待表,记录各进程与要申请资源之间的关系

6、死锁的解除

1、抢占资源,从一个或多个进程中抢占足够数量的资源,分配给死锁进程,以解除死锁状态
2、终止(撤销)进程,终止(或撤销)系统中的一个或者多个死锁进程,直到打破循环换了,是系统从死锁状态解脱出来

7、JVM的四种GC算法(垃圾收集的方法)

  1. 引用计数法:每个对象在创建的时候,就给这个对象绑定一个计数器。每当有一个引用指向该对象时,计数器加1;每当有一个指向他的引用被删除时,计数器减1.当计数器为0时,进行垃圾回收
  2. 标记-清除:标记那些要被回收的对象,然后统一回收
  3. 标记-整理:该算法只要是解决标记-清除,产生大量内存碎片的问题;当对象存活率较高时,也解决了复制算法的效率问题。他的不同之处就是在清除对象的时候将可回收对象移动到一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片。
  4. 复制算法:该算法将内存平均分成两部分,然后每次只使用其中的一部分,当这部分存满的时候,将内存中所有存活的对象复制到另一个内存中,然后将之前的内存清空,只使用这部分内存,循环下去
  5. 分代收集器:根据对象的生存周期,将堆分为新生代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时采用复制算法。老年代里面的对象存活率较高,没有额外的空间进行分配担保,所以可以使用标记-整理或者标记-清除

8、怎样保证集合中的元素不能被篡改

当时用final变量修饰引用变量时,则该变量的地址值不能改变,但是变量的内容可以改变。所以需要使用Collections.unmodifiableList()

9、线程池中execute和submit有什么区别?

execute只能执行Runnable类型的任务,没有返回值
submit既能执行Runnable,又能执行Callable类型的任务,有返回值

10、多线程锁升级的原理

synchronized锁升级的原理:在锁对象的对象头里面有一个threadid字段,在第一次访问的时候threadid为空,jvm让其持有偏向锁,并将threadid设置为其线程id,再次进入的时候会先判断threadid是否和其线程id一致,如果一致则可以直接使用此对象;如果不一致,则升级偏向锁为轻量级锁。通过自旋循环一定次数来获取锁,执行一定次数后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁。

锁升级的目的:锁升级的目的是为了降低锁带来的性能消耗。

11、synchronized的底层实现原理

底层是基于每个对象的监视器(monitor)来实现的。被synchronized修饰的代码,在被编译器编译后在被修饰的代码前后加上了一组字节指令。
在代码开始加入了monitorenter,在代码后面加入了monitorexit,这两个字节码指令配合完成了synchronized关键字修饰代码的的互斥访问。
在虚拟机执行到monitorenter指令的时候,会请求获取对象的monitor锁,基于monitor锁又衍生出了一个锁计数器的概念。
当执行到monitorenter的时候,若对象未被锁定时,或者当前线程已经拥有了次对此对象的monitor锁,则锁计数器+1,该线程获取该对象锁;
当执行monitorexit时,锁计数器-1,当计数器为0时,此对象就被释放了。那么其他阻塞的线程则可以请求获取该monitor锁。

12、线程安全问题

volatile解决可见性问题->atomic解决volatile的原子问题->时间戳解决CAS的ABA问题

13、锁的相关简记

synchronized和reentrantlock都是可重入锁;synchronized是非公平锁;再默认值下reentrantlock是非公平锁,参数为false时是公平锁。

14、哪些对象可以作为GC ROOT

1、虚拟机栈(栈帧中的局部变量区,也叫局部变量表)中引用的对象
2、方法区中的类静态属性应用的对象
3、方法区中常量的对象
4、本地方法栈中JNI(Native方法)引用的对象

15、WeakHashMap

当key没有被使用的情况下,会产生垃圾回收

16、垃圾回收器

1、serial 串行回收器:为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。不适合服务器环境
对应:SerialGC
2、parallel并行回收器:多个垃圾收集器并行工作,此时用户线程是暂停,适用于科学计算/大数据处理首台处理等交互场景
(1)新生代:ParNewGC是在新生代用并行,老年代用串行
(2)新生代:Parallel Scavenge GC新生代GC,使用复制算法,俗称吞吐量优先收 集器,可控制吞吐量,自适应调节(自适应调节策略:虚拟机会根据当前系统运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大吞吐量),在串行收集器在新生代和老年代的并行化
(3)老年代:ParallelOldGC是Parallel Scavenge的老年代版本,使用多线程的标记-整理算法

3、CMS(并发标记清除)并发回收器: 老年代,用户线程和垃圾收集线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程
对应:ConcMarkSweepGC
是一种以获取最短回收停顿时间为目标的收集器,希望系统停顿时间最短
缺点:CPU压力大(多线程并发)、磁盘碎片
4、G1回收器:将堆内存分割成不同的区域然后并发的对其进行垃圾回收
在实现高吞吐量的同时,尽可能的满足垃圾收集暂停时间的要求。
(1)G1是一个用标记-整理内存过程的垃圾收集器,不会产生很多内存碎片
(2)G1在停顿时间上添加了预测机制,用户可以指定期望停顿时间
在这里插入图片描述回收步骤:
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

17、ArrayList和LinkedList的区别

相同点:都是继承List
不同点:
(1)ArrayList是基于数组实现的,LinkedList是基于双向链表
(2)ArrayList查询快,LinkedList增删快
(3)ArrayList需要扩容

MySQL

1、MySQL的行锁是怎样实现的?

InnoDB是通过给索引上的索引项加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁;否则InnoDB将使用表锁。

Linux

在这里插入图片描述

1、top

查看整机的系统性能,例如load average(uptime直接查看)和系统内存使用情况

2、vmstat

vmstat -n 2 3:表示每两秒采样一次,共采样3次
查看CPU

在这里插入图片描述查看所有CPU核信息 mpstat -P ALL 2
每个进程使用CPU的用量分解信息 pidstat -u 1 -p 进程编号

3、free

查看内存 free -m
pidstat -p 进程号 -r 采样间隔秒数

4、df

查看磁盘 df -h

5、iostat

磁盘IO :iostat -xdk 2 3

6、ifstat

网络IO : ifstat 1

计算机网络

1、TCP的粘包

  • 发送端需要等缓冲区满才将数据发出去,造成粘包(发送数据的时间间隔很短,数据量很小,会合到一起,产生粘包)
  • 接收方不及时接收缓冲区的包,造成多个包被接收(客户端发送了一段数据,服务端只接受了一小部分,服务端下次再收的时候还是从缓冲区拿上一次遗留的数据,产生粘包)

2、TCP的拆包

1、客户端写入缓冲区的数据大于缓冲区大小
2、当TCP报文长度-TCP头部长度 > MSS的时候将发生拆包

3、粘包和拆包的解决方法

1、设置定长消息
2、设置消息边界

4、get和post的区别

get和post是HTTP请求的两种基本方法,
区别:

  • 最直观的区别就是get把参数包含在URL中,POST通过request body传递参数
  • get传输的数据量小,因为受到URL长度限制;而post可以传输大量的数据
  • get不安全,因为一些操作可能被第三方看到,而post的所有操作对用户是不可见的
  • 值的字符集不同,get的请求参数只能是ASCII,而post没有限制
  • get是产生一个TCP数据包,post产生两个TCP数据包。具体地,get是吧header和data一起发送给服务器;而post是先吧header发给服务器,服务器返回100 continue,客户端再发送data

5、http的长短连接的区别

  1. http 1.0 中默认使用的是短连接,客户端和服务端每进行一次http操作,就建立一次连接,任务结束就中断连接
  2. HTTP 1.1起开始使用长连接,使用长连接情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。

6、cookies被禁用怎么办?

在重写URL,把 session ID直接附加在URL路径的后面

7、HTTP1.0和HTTP1.1的主要区别

  1. 长短连接
  2. 1.1中增加了错误状态响应码
  3. 带宽优化及网络连接的使用:1.1解决了1.0的带宽浪费的现象,例如,客户端只需要某个对象的一部分,而服务器却将整个对象送过来,为了解决这个问题,1.1在请求头引入了range头域

8、URI和URL的区别

URI像身份证,作为资源的唯一标识;URL像家庭住址,不仅唯一标识,还可以定位 ‘’;;‘’fgdfg-09sdf=gfdgh09ogvfad-0


Hygiene 635

数据库

1、数据库的ACID属性

  1. 原子性(Atomactic):要么全部做完,要么全部不做
  2. 一致性(Consistency):如A向B转账,不可能A扣了钱,B却没收到
  3. 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同事物之间彼此没有任何干扰
  4. 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚

2、事务的隔离级别

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

(1) 未提交读
A事务已执行,但未提交;B事务查询到A事务的更新后数据;A事务回滚;—出现脏数据
(2) 已提交读
A事务执行更新;B事务查询;A事务又执行更新;B事务再次查询时,前后两次数据不一致 ---- 不可重复读
(3) 可重复读(默认)
A事务无论执行多少次,只要不提交,B事务查询值都不变;B事务仅查询A事务开始时那一瞬间的数据快照
(4) 串行化
不允许读写并发操作,写执行时,读必须等待

3、B-树和B+树

1、B-树将关键字、索引和记录都存放在一起;B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录放在叶子节点中
2、在B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;在B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字

4、为什么索引能够提高查询速度

5、最左前缀原则

最左前缀原则是发生在复合索引上的,只有复合索引才会有所谓的左和右之分。

6、MySQL的NULL和空值的区别

NULL使用is NULL来判断
空值使用 =’'来判断

项目

1、项目中用到的shell脚本

(1)Flume启动停止脚本

#!/bin/bash
case $1 in 
"start") {
	for i in hd1 hd2 hd3
	do 
		ssh $i "nohup /flume-ng agent --conf-file file-flume-kafk.conf --name a1 -Dflume.root.logger=INFO,LOGFILE > /dev/null 2> &1 &"
	done
};;
"stop" ){
	for i in hd1 hd2 hd3 
	do
	 	ssh $i "ps -ef | grep file-flume-kafka |grep -v grep | awk '{print \$2}' | xargs kill"
	done
};;
esac

(2)kafka启动停止脚本

#!/bin/bash
case $1 in
"start"){
	for i in hd1 hd2 hd3 
	do 
		ssh $i "export JMX_PORT=9988 && kafka-server-start.sh -daemon server.properties"
	done
 };;
"stop"){
	for i in hd1 hd2 hd3
	do 
		ssh $i "kafka-server-stop.sh stop"
	done
};;
esac

(3)采集通道启动/停止脚本

#! /bin/bash

case $1 in
"start"){
	echo " -------- 启动 集群 -------"

	echo " -------- 启动 hadoop集群 -------"
	/opt/module/hadoop-2.7.2/sbin/start-dfs.sh 
	ssh hadoop103 "/opt/module/hadoop-2.7.2/sbin/start-yarn.sh"

	#启动 Zookeeper集群
	zk.sh start

sleep 4s;

	#启动 Flume采集集群
	f1.sh start

	#启动 Kafka采集集群
	kf.sh start

sleep 6s;

	#启动 Flume消费集群
	f2.sh start

	};;
"stop"){
    echo " -------- 停止 集群 -------"

    #停止 Flume消费集群
	f2.sh stop

	#停止 Kafka采集集群
	kf.sh stop

    sleep 6s;

	#停止 Flume采集集群
	f1.sh stop

	#停止 Zookeeper集群
	zk.sh stop

	echo " -------- 停止 hadoop集群 -------"
	ssh hadoop103 "/opt/module/hadoop-2.7.2/sbin/stop-yarn.sh"
	/opt/module/hadoop-2.7.2/sbin/stop-dfs.sh 
};;
esac

2、项目中用到的是星型模型还是雪花模型?区别对比?

1、星型模型存在冗余;雪花模型不存在冗余
2、星型模型的效率要高。星型模型因为数据的冗余所以很多统计查询不需要做外部的连接,因此一般情况下效率比雪花模型要高
3、雪花模型的维护复杂

操作系统

1、虚拟内存的实现原理?作用?

spark

1、持久化和checkpoint的区别

  • 持久化只是将数据保存在BlockManager中,而RDD的Lineage是不变的。但是checkpoint执行之后,RDD已经没有之前所谓的依赖RDD了,而只有一个强行为其设置的checkpointRDD,RDD的Lineage改变了
  • 持久化的数据丢失的可能性更大,因为磁盘和内存可能会存在数据丢失的情况。但是checkpoint的数据通常是存储在HDFS等容错、高可用的文件系统和中,数据丢失的可能性小
  • 没有持久化,直接使用checkpoint的话,会计算两次。所以先checkpoint,在cache

2、join算子会产生shuffle吗?

当RDD的分区数和分区方法相同的情况下是不会产生shuffle的

3、四种shuffle

  1. 未优化的hash shuffle:每个task都会创建一个buffer,在buffer里面创建reducer个数的bucket,这样的话,就会产生Task个数 * Reducer个数的小文件
  2. 优化的hash shuffle : 启用合并机制,复用buffer
  3. 普通sort shuffle :task一边map局部聚合,一边写入缓存;当到达阈值后,对key进行排序后会分批溢写到磁盘,清空缓存。一个task会产生多个临时文件;然后将所有的临时文件merge成为一个文件,并同时单独写一份索引文件,用于标识各个task的数据在文件中的索引
  4. bypassshuffle需要满足两个条件:
    (1)shuffle map task数量小于200
    (2)不是聚合类的shuffle算子(没有预聚合,例如groupByKey)
    该方式下,与未经优化的hashshuffle的过程是一样的,与普通的sortshuffle相比,不会进行排序

MapReduce

1、reduce是怎样获取到对应分区的数据?

map任务一直和TaskTracker保持联系,而TaskTracker又一直和JobTracker保持心跳,JobTracker保存了整个集群的宏观信息,只要reduce任务向JobTracker获取对应的map输出位置就可以了

2、SecondNameNode的作用?

1、备份editlog
2、定期合并edit log和fsimage
上面的两个过程同时进行,称为checkpoint

滴滴大数据开发(实习)

一面(电话)

1、说一下RDD

2、hive的优化

列式存储(ORC、parque)
忘说LZO压缩格式存储

3、HIVE为什么列式存储算是优化?

https://www.cnblogs.com/bigdatafly/articles/5037745.html
比较行式存储和列式存储
(1)行式存储
优点:基于hadoop系统运行存储结构的优点在于快速数据加载和动态负载的高适应能力,这是因为行存储保证了相同的记录的所有域都在同一个集群节点,即同一个HDFS
缺点:不支持快速查询处理,因为他不能跳过不必要的列读取,压缩比大
(2)列式存储
优点:查询时列存储可以避免读不必要的列,容易得到较大的压缩比
缺点:列存储不能保证同一记录的所有域都存储在同一节点,会导致大量的IO传输

所以,使用列存储的话,最好配合使用压缩,获得最大压缩比

4、spark的内存管理

5、spark的shuffle过程

持续更新ing……

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐