数据研发侧重组件框架原理和编程实践经验,在面试中也会问到数据结构与算法、机器学习算法等。以下试题为作者日常整理的通用高频面经,包含题目,答案与参考文章,欢迎纠正与补充。
.linux常用命令
通过参考linuxTOY.org网站并制作出思维导图:
.Java虚拟机、垃圾回收机制
Java虚拟机即JVM(JavaVirtualMachine),通过软件来模拟出来的具有完整的硬件系统功能、运行在完全隔离的环境中的完整的计算机系统。JVM内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分:
程序计数器:内存空间小,线程私有。字节码解释器工作是就是通过改变这个计数器的值来选取下一条需要执行指令的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器完成
Java虚拟机栈:线程私有,生命周期和线程一致。描述的是Java方法执行的内存模型:每个方法在执行时都会床创建一个栈帧(StackFrame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。
本地方法栈:区别于Java虚拟机栈的是,Java虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。也会有StackOverflowError和OutOfMemoryError异常。
Java堆:对于绝大多数应用来说,这块区域是JVM所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组。内部会划分出多个线程私有的分配缓冲区(ThreadLocalAllocationBuffer,TLAB)。可以位于物理上不连续的空间,但是逻辑上要连续。
方法区:属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
Java内存回收机制:区别于C语言,C的垃圾回收是人工的,工作量大,但是可控性高。
而Java是自动化的,但是可控性很差,甚至有时会出现内存溢出的情况,内存溢出也就是jvm分配的内存中对象过多,超出了最大可分配内存的大小。
以上两张图可以形象理解一下。
.TCP“三次握手”、“四次挥手
三次握手:
第一次握手:客户端发送初始序号x和syn=1请求标志第二次握手:服务器发送请求标志syn,发送确认标志ACK,发送自己的序号seq=y,发送客户端的确认序号ack=x+1第三次握手:客户端发送ACK确认号,发送自己的序号seq=x+1,发送对方的确认号ack=y+1
四次挥手:
第一次挥手:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态第二次挥手:服务器收到客户端的后,发出ACK=1确认标志和客户端的确认号ack=u+1,自己的序列号seq=v,进入CLOSE-WAIT状态第三次挥手:客户端收到服务器确认结果后,进入FIN-WAIT-2状态。此时服务器发送释放FIN=1信号,确认标志ACK=1,确认序号ack=u+1,自己序号seq=w,服务器进入LAST-ACK(最后确认态)第四次挥手:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待)。客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态。
.大数据常见组件
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。Hadoop的核心是YARN,HDFS和MapReduce。Hdfs是分布式文件存储系统,用于存储海量数据;MapReduce是并行处理框架,实现任务分解和调度。Hadoop可以用来搭建大型数据仓库,对海量数据进行存储、分析、处理和统计等业务,功能十分强大。Hadoop具有成熟的生态系统,包括众多的开源工具,如下图:
HDFS:HDFS是Hadoop的核心组件,HDFS上的文件被分成块进行存储,默认块的大小是64M,块是文件存储处理的逻辑单元。HDFS是Master和Slave的结构。分NameNode(Master节点)、SecondaryNameNode(NameNode冷备份H)、DataNode(slave节点)这几个角色。
MapReduce:MapReduce的工作原理用一句话概括就是,分而治之,然后归约,即将一个大任务分解为多个小任务(map),并行执行后,合并结果(reduce)。整个MapReduce的过程大致分为Map--Shuffle(排序)--Combine(组合)--Reduce。
YARN:YARN是Hadoop2.0中的资源管理系统,它的基本设计思想是将MRv1中的JobTracker拆分成了两个独立的服务:一个全局的资源管理器ResourceManager和每个应用程序特有的ApplicationMaster。其中ResourceManager负责整个系统的资源管理和分配,而ApplicationMaster负责单个应用程序的管理。
Hive:Hive是构建在HadoopHDFS上的一个数据仓库,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能,其本质是将SQL转换为MapReduce程序。数据仓库是一个面向主题的、集成的、不可更新的、随时间变化的数据集合,它用于支持企业或组织的决策分析处理。Hive的表其实就是HDFS的目录/文件。
Pig:Pig是yahoo捐献给apache的一个项目,使用SQL-like语言,是在MapReduce上构建的一种高级查询语言,把一些运算编译进MapReduce模型的Map和Reduce中。
Zookeeper:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
Hbase:HBase–HadoopDatabase,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PCServer上搭建起大规模结构化存储集群。HBase是GoogleBigtable的开源实现,类似GoogleBigtable利用GFS作为其文件存储系统,HBase利用HadoopHDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用HadoopMapReduce来处理HBase中的海量数据;GoogleBigtable利用Chubby作为协同服务,HBase利用Zookeeper作为对应。
Sqoop:Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易。ApacheSqoop正在加紧帮助客户将重要数据从数据库移到Hadoop。随着Hadoop和关系型数据库之间的数据移动渐渐变成一个标准的流程,云管理员们能够利用Sqoop的并行批量数据加载能力来简化这一流程,降低编写自定义数据加载脚本的需求。
Flume:Flume作为cloudera开发的实时日志收集系统,受到了业界的认可与广泛应用。Flume初始的发行版本目前被统称为FlumeOG(originalgeneration),属于cloudera。重构后的版本统称为FlumeNG(nextgeneration),属于Apache。
Kafka:是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模网站中的所有动作流数据,目前已成为大数据系统在异步和分布式消息之间的最佳选择。
Spark:Spark是一个高速、通用大数据计算处理引擎。拥有HadoopMapReduce所具有的优点,但不同的是Job的中间输出结果可以保存在内存中,从而不再需要读写HDFS,因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的MapReduce的算法。它可以与Hadoop和ApacheMesos一起使用,也可以独立使用
Flink:Flink于今年跻身Apache顶级开源项目,与HDFS完全兼容。Flink提供了基于Java和Scala的API,是一个高效、分布式的通用大数据分析引擎。更主要的是,Flink支持增量迭代计算,使得系统可以快速地处理数据密集型、迭代的任务。
Storm:Storm是Twitter开源的一个类似于Hadoop的实时数据处理框架。编程模型简单,显著地降低了实时处理的难度,也是当下最人气的流计算框架之一。与其他计算框架相比,Storm最大的优点是毫秒级低延时。
.HDFS存储机制
HDFS存储机制,包括HDFS的写入过程和读取过程两个部分:
写入过程:
客户端向namenode请求上传文件,namenode检查目标文件是否已存在,父目录是否存在。namenode返回是否可以上传。客户端请求第一个block上传到哪几个datanode服务器上。namenode返回3个datanode节点,分别为dn1、dn2、dn3。客户端请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成dn1、dn2、dn3逐级应答客户端客户端开始往dn1上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位,dn1收到一个packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答当一个block传输完成之后,客户端再次请求namenode上传第二个block的服务器。(重复执行3-7步)读取过程:
客户端向namenode请求下载文件,namenode通过查询元数据,找到文件块所在的datanode地址。挑选一台datanode(就近原则,然后随机)服务器,请求读取数据。datanode开始传输数据给客户端(从磁盘里面读取数据放入流,以packet为单位来做校验)。客户端以packet为单位接收,先在本地缓存,然后写入目标文件。
.MapReduce基本流程
在MapReduce整个过程可以概括为以下过程:输入--map--shuffle--reduce--输出。输入文件会被切分成多个块,每一块都有一个maptask。map阶段的输出结果会先写到内存缓冲区,然后由缓冲区写到磁盘上。默认的缓冲区大小是M,溢出的百分比是0.8,也就是说当缓冲区中达到80M的时候就会往磁盘上写。如果map计算完成后的中间结果没有达到80M,最终也是要写到磁盘上的,因为它最终还是要形成文件。那么,在往磁盘上写的时候会进行分区和排序。一个map的输出可能有多个这个的文件,这些文件最终会合并成一个,这就是这个map的输出文件。
流程说明如下:
(1)输入文件分片,每一片都由一个MapTask来处理(2)Map输出的中间结果会先放在内存缓冲区中,这个缓冲区的大小默认是M,当缓冲区中的内容达到80%时(80M)会将缓冲区的内容写到磁盘上。也就是说,一个map会输出一个或者多个这样的文件,如果一个map输出的全部内容没有超过限制,那么最终也会发生这个写磁盘的操作,只不过是写几次的问题。(3)从缓冲区写到磁盘的时候,会进行分区并排序,分区指的是某个key应该进入到哪个分区,同一分区中的key会进行排序,如果定义了Combiner的话,也会进行