说说对hadoop的理解,都有哪些组件,分别是干什么的
hadoop是一个分布式系统基础框架,主要包括HDFS(分布式存储系统),Mapreduce(分布式计算框架),Yarn(资源管理框架)
kafka在什么地方需要用到zookeeper
kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。zookeeper中存储的信息有broker,consumer等重要znode信息;kafka节点broker的选举也是通过zookeeper来实现,主要流程是在zookeeper创建/controller临时节点来实现leader选举,并在该节点中写入当前broker的信息,利用Zookeeper的强一致性特性,一个节点只能被一个客户端创建成功,创建成功的broker即为leader,即先到先得原则,leader也就是集群中的controller,负责集群中所有大小事务
说下spark中的transform和action
transformation是得到一个新的RDD,比如从数据源生成一个新的RDD或者从RDD生成一个新的RDD;常见的transformation操作有 map,filter,flatMap,mapPartition,groupbyKey,reducebyKey,sortByKey,cartesian等等;action是得到一个值或者一个结果,常见的action操作有collect、count、saveAsTextFile、countByKey、take、first、foreach等等
为什么spark要把操作分为transform和action
transformation提交是不会执行计算的,计算只有在action被提交的时候才被触发。比如特别耗时的一些操作,不到必须要用这个操作的结果的时候可以不用执行,对性能提升比较明显。
spark中有了RDD,为什么还要有Dataframe和DataSet?
RDD是分布式的 Java对象的集合,Spark框架本身不了解Person内部的结构。而DataFrame是分布式的Row对象的集合,Spark SQL可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。DataFrame算子比较丰富,最终要的是提升执行效率、减少数据读取以及执行计划的优化,比如filter下推、裁剪等。DataSet是DataFrame的一个特例,它存储的是一个强类型值,而不是一个Row,所以在编译的时候会检查类型。 RDD API是函数式的,强调不变性,大部分场景是在创建新对象而不是修改老对象,API会比较简洁,但是带来的问题是会在运行期间不断创建对象回收对象,造成GC压力大。Spark SQL在框架内部已经在各种可能的情况下尽量重用对象,这样做虽然在内部会打破了不变性,但在将数据返回给用户时,还会重新转为不可变数据。利用 DataFrame API进行开发,可以免费地享受到这些优化效果
了解函数式编程吗?说下c/c++和scala这种函数式编程语言的区别
Java中抽象类和接口的区别
抽象类(抽象类就是为了被继承):抽象类中的抽象方法必须定义为protected或者public,因为如果我们将其定义为私有的话,就无法被子类继承(其实也不是不好继承,而是不好调用);抽象类中的抽象方法如果没有在某一个子类中实现,那这个子类也要声明为抽象类;抽象类是不可以实例化的;一个类只能继承一个抽象类
接口(为了方法而生):接口中可以有变量和方法,但是接口中的变量是被强制置为public static final 的,并且只能为该类型;接口中的方法,能且只能是public abstract方法,而且对于接口中的方法都不能有具体实现;一个列可以多继承接口
了解GC吗?
Java虚拟机中进行垃圾回收的场所有两个,一个是堆,一个是方法区。在堆中存储了Java程序运行时的所有对象信息,而垃圾回收其实就是对那些“死亡的”对象进行其所侵占的内存的释放,让后续对象再能分配到内存,从而完成程序运行的需要。关于何种对象为死亡对象,在下一部分将做详细介绍。Java虚拟机将堆内存进行了“分块处理”,从广义上讲,在堆中进行垃圾回收分为新生代(Young Generation)和老生代(Old Generation);从细微之处来看,为了提高Java虚拟机进行垃圾回收的效率,又将新生代分成了三个独立的区域(这里的独立区域只是一个相对的概念,并不是说分成三个区域以后就不再互相联合工作了),分别为:Eden区(Eden Region)、From Survivor区(Form Survivor Region)以及To Survivor(To Survivor Region),而Eden区分配的内存较大,其他两个区较小,每次使用Eden和其中一块Survivor。Java虚拟机在进行垃圾回收时,将Eden和Survivor中还存活着的对象进行一次性地复制到另一块Survivor空间上,直到其两个区域中对象被回收完成,当Survivor空间不够用时,需要依赖其他老年代的内存进行分配担保。当另外一块Survivor中没有足够的空间存放上一次新生代收集下来的存活对象时,这些对象将直接通过分配担保机制进入老生代,在老生代中不仅存放着这一种类型的对象,还存放着大对象(需要很多连续的内存的对象),当Java程序运行时,如果遇到大对象将会被直接存放到老生代中,长期存活的对象也会直接进入老年代。如果老生代的空间也被占满,当来自新生代的对象再次请求进入老生代时就会报OutOfMemory异常。新生代中的垃圾回收频率高,且回收的速度也较快。就GC回收机制而言,JVM内存模型中的方法区更被人们倾向的称为永久代(Perm Generation),保存在永久代中的对象一般不会被回收。其永久代进行垃圾回收的频率就较低,速度也较慢。永久代的垃圾收集主要回收废弃常量和无用类。
数据库都有哪些引擎
InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,上图也看到了,InnoDB是默认的MySQL引擎
MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事物。
MEMORY存储引擎将表中的数据存储到内存中,未查询和引用其他表数据提供快速访问。
数据库的锁了解哪些
行级锁:行级锁和表级锁是根据锁的粒度来区分的,行记录,表都是资源,锁是作用在这些资源上的。如果粒度比较小(比如行级锁),可以增加系统的并发量但需要较大的系统开销,会影响到性能,出现死锁,,因为粒度小则操作的锁的数量会增加;如果作用在表上,粒度大,开销小,维护的锁少,不会出现死锁,但是并发是相当昂贵的,因为锁定了整个表就限制了其它事务对这个表中其他记录的访问。
悲观锁:Pessimistic Lock正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守悲观态度,事务每次去操作数据的时候都假设有其他事务会修改需要访问的数据,所以在访问之前都要求上锁,行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能 真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系 统不会修改数据)。 一个典型的倚赖数据库的悲观锁调用: select * from account where name=”Erica” for update 这条sql 语句锁定了account 表中所有符合检索条件(name=”Erica”)的记录。 本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。
乐观锁:Optimistic Lock,和悲欢锁相反,事务每次去操作数据之前,都假设其他事务不会修改这些需要访问的数据 ,所以 在访问之前不要求上锁,只是在进行更新修改操作的时候判断一下在访问的期间有没有其他人修改数据 了。它适用于多读的应用类型,冲突真的发生比较少的时候就比较好,这样省去了开销的开销,可以提高吞吐量;但如果是真的经常要发生冲突的,那每次还要去判断进行retry,反倒降低的性能,这个时候悲欢锁比较好。数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
应用层协议有哪些
DNS:域名系统DNS是因特网使用的命名系统,用来把便于人们使用的机器名字转换为IP地址
FTP:文件传输协议FTP是因特网上使用得最广泛的文件传送协议。FTP提供交互式的访问,允许客户指明文件类型与格式,并允许文件具有存取权限。FTP其于TCP。
TELNET:telnet是一个简单的远程终端协议,它也是因特网的正式标准。又称为终端仿真协议
HTTP:超文本传送协议,是面向事务的应用层协议,它是万维网上能够可靠地交换文件的重要基础。http使用面向连接的TCP作为运输层协议,保证了数据的可靠传输。
SMTP:简单邮件传送协议。SMTP规定了在两个相互通信的SMTP进程之间应如何交换信息。SMTP通信的三个阶段:建立连接、邮件传送、连接释放。
这部分内容不可能全部记得住,建议说这几个常用的就欧克。
什么场景用TCP,什么场景用UDP
概念:两种协议都属于传输层协议,都是为应用层提供信息载体。TCP比较可靠,是基于连接,有流量控制和差错控制,也正是因为可靠性,所以传输性能较于UDP差一些。UDP基于无连接, 只是把数据传输给对方,没有控制手段,所以不可靠,而且数据传输效率高。
应用场景:TCP是基于三次握手建立的可靠性传输层协议,适用于相对于传输性能,更强调准确性的场景,比如:http、FTP等文本传输,互联网企业的客户端应用等场景。UDP更强调效率,无所谓传递正确性,或者说可以忍受一定程度的数据丢失,比较适用于音频、视频的传输。(但是博主发现好多视频网站用的都是http -_-)
HTTP状态码都有哪些,具体说一下
1.1xx ---- Informational(信息性状态码),表示接受的请求正在处理
2.2xx ---- Success (成功),表示请求正常处理完毕
3.3xx ---- Redirection (重定向),表示要对请求进行重定向操作,当然其中的304除外
4.4xx ---- Client Error (客户端错误),服务器无法处理请求
5.5xx ---- Server Error (服务器错误),服务器处理请求时出错
HTTP长连接和短连接
长连接:客户端向服务端发起请求,建立连接进行读写操作,之后并不会主动关闭,后续的操作继续复用这个连接。优点是省去很多TCP创建连接的时间,但是会带来一些问题,连接一直不关闭,client连接越来越多,那sever早晚要完,所以需要加一些限制,比如每个客户端的最大连接数等。
短连接:客户端向服务端发起请求,建立连接进行读写操作,然后关闭连接。但如果客户端请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽
url和uri的区别
url:统一资源标识符,主要包括是三部分,访问资源的命名机制,存放资源的主机名,资源本身的名称。比如:https://blog.csdn.net/xiaozhaoshigedasb/article/details/105814967
url:url是uri的子集,统一资源定位符,URI和URL都定义了资源是什么,但URL还定义了该如何访问资源。URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。
线程和进程的区别
进程和线程都是描述资源的单位,粒度不同。进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位。比如QQ,就可以看做一个进程,切换为QQ音乐,开销会比较大,因为每个进程都有独立的代码和上下文;线程是轻量级的进程,如果是同一类线程可以共享数据空间,线程切换代价比较小。进程中必然会有线程,一个操作系统可以运行多个进程,一个进程可以运行多个线程。系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源)
hashmap的实现
存储:
public V put(K key, V value) {
// HashMap允许存放null键和null值。
// 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。
if (key == null)
return putForNullKey(value);
// 根据key的keyCode重新计算hash值。
int hash = hash(key.hashCode());
// 搜索指定hash值在对应table中的索引。
int i = indexFor(hash, table.length);
// 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
// 如果发现已有该键值,则存储新的值,并返回原始值
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
// 如果i索引处的Entry为null,表明此处还没有Entry。
modCount++;
// 将key、value添加到i索引处。
addEntry(hash, key, value, i);
return null;
}
读取:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
总结:hashmap底层是用数组+链表来实现。数组中每一个元素是一个链表,链表的元素是Entry(key,value),Entry对象中包含下一个元素的引用。
20. hashmap的loadfactory是干嘛的
loadfactoryloadfactory是键值对的个数所占数组个数的比值,大于loadfactory的值,hashmap会扩容。比如,hashmap的数组length为16个,loadfactory为0.75,当entry对象超过12个以后,会进行扩容,扩容后的数组大小是当前数组大小的两倍。
hashmap的扩容,为什么每次扩容都是翻倍,增加1.5倍不行吗
链接:https://www.cnblogs.com/williamjie/p/9358291.html
扩容的时候为啥不多扩一点,比如4倍
spark和mapreduce比较
mapreduce是java写的,spark是scala写的。计算过程都是先将大文件split到map中,然后经过shuffle到reduce,区别在于mapreduce的中间结果会溢到磁盘,而spark保存在内存(内存不够也会写磁盘)减少迭代过程中的数据落地,能够实现数据高效共享,迭代运算效率高。spark只提供了map和reduce两种算子,其他的逻辑都是要在map和reduce中实现,代码写起来比较繁琐,spark编程比较简洁,提供了丰富的算子,分为transform和action两类,action算子提交触发rdd的关系提交,进而根据依赖关系划分stage。
传统关系型数据库和hdfs比较 (前者轻量级,侧重实时操作;后者重量级,分布式,分而治之化整为零,横向扩展性好)
map join实现?应用场景?两张大表怎么选?(通过广播大变量;一般用在大表join小表,可容忍小表数据冗余的场景;两张大表就分而治之,再sort merge)
输入网址到返回网页的过程(域名解析,tcp连接建立,数据传输,数据回传,渲染,显示)
sql这块如何(没有注重语法的掌握,表示日后工作用到会熟能生巧,重点学习了理论,索引原理,并发这一块儿)
海量数据处理成结构化数据 技术难点
mapreduce 的热点问题
flume 介绍
kafka 介绍
flume+kafka 为什么是经典组合
窗口函数 有哪些 有什么功能
reduce 任务过长 shuffle过长 如何解决
storm和spark最大的区别
Hadoop生态系统中,Hive数据库与Hbase数据库的区别,以及分别适用场景
HDFS数据一致性靠什么保证
一般来讲,datanode与应用交互的大部分情况都是通过网络进行的,而网络数据传输带来的一大问题就是数据是否原样到达。为了保证数据的一致性,HDFS采用了数据校验和(checkSum)机制。创建文件时,HDFS会为这个文件生成一个校验和,校验和文件和文件本身保存在同一空间中。传输数据时会将数据与校验数据和一同传输,应用收到数据后可以进行校验,如果两个校验的结果不同,则文件肯定出错了,这个数据块就变成无效的。如果判定无效,则需要从其他datanode上读取副本。
HDFS读写流程
MYISAM和InnoDB比较 很有可能继续往下问B+树
平衡二叉树算法时间复杂度
NP问题 P问题
Hadoop 用的什么发行版型
CDH(5.8~5.14,6.2,6.3用的比较多)
HA配置中节点信息同步靠什么
数据如何进行处理的 特别涉及用户隐私 userid字段如何处理
介绍死锁, 死锁的四个条件
死锁就是线程之间进行争夺资源造成的一种僵局。互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。 环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件) 只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件) 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件) 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
MR是怎么确定MapTask数量的
1.文件的大小。当块(dfs.block.size)为128m时,如果输入文件为128m,会被划分为1个split;当块为256m,会被划分为2个split。
2.文件的个数。FileInputFormat按照文件分割split,并且只会分割大文件,即那些大小超过HDFS块的大小的文件。如果HDFS中dfs.block.size设置为128m,而输入的目录中文件有100个,则划分后的split个数至少为100个。
3.splitSize的大小。分片是按照splitszie的大小进行分割的,一个split的大小在没有设置的情况下,默认等于hdfs block的大小。
HBase底层,rowkey怎么设计的,为什么这么设计
线程池种类,自己设计线程池,如何避免处理重复任务
Flink状态管理
状态的概念 状态意思是某个task或者operator在某一时刻的内存的状态。和checkpoint类似,只不过checkpoint针对的是全局,也就是所有operator的状态做一次快照。目的都是为了在任务失败的情况恢复。``state分为两种,Operator State和keyed state。Operator State跟一个特定operator的一个并发实例绑定,整个operator只对应一个state。keyed state是基于KeyStream之上的状态,keyBy之后的Operator State。
状态的形式Operator state和keyed state有两种形式存储:原始状态和托管状态。原始状态是指用户自行管理的具体的数据结构,使用byte[]读写状态,不了解具体的内部结构,需要序列化。托管状态是flink框架管理的状态,ValueState,ListState,MapState等,不需要序列化。
Flink的分布式快照原理