- Tomcat类加载
- 前端RequireJS模块加载
- 前端 Vue、Element-UI
面试准备
软件开发
后端
java基础
-
面向对象和面向过程 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
面向过程:优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 缺点:没有面向对象易维护、易复用、易扩展
面向对象:优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 缺点:性能比面向过程低
-
封装与构造函数:
函数是最基本的封装体,类也是封装体。封装的意义就是属性私有化,提供接口给外部访问,实现对属性的控制功能。
在未申明类构造函数时,没有默认自带参数为空的构造函数(声明后以声明构造函数为准)。
子类只继承父类的默认(缺省)构造函数,即无形参构造函数。如果父类没有默认构造函数,那子类不能从父类继承到任何构造函数。 在创建对象时,先调用父类默认构造函数对对象进行初始化,然后调用子类自身自己定义的构造函数。 如果子类想调用父类的非默认构造函数,则必须使用super来实现。
super
的使用与this
有点像,但super
和this
是不同的,this
引用一个对象,
是实实在在存在的,可以作为函数参数,可以作为返回值, 但super
只是一个关键字,
不能作为参数和返回值,它只是用于告诉编译器访问父类的相关变量和方法。
this.字段
:如果出现在父类代码中,指的就是父类属性。
this.字段
:如果出现在子类代码中,指的就是子类属性。
this.方法
:不管出现在父类还是子类代码中,指的都是子类方法。
- java内存模型
Java虚拟机栈:
线程私有,是Java方法执行的内存模型,每个方法被执行时都会创建一个栈帧,存储局部变量表、操作栈、动态链接、方法出口等信息。
每个线程都有自己独立的栈空间
线程栈只存基本类型和对象地址
方法中局部变量在线程空间中
Java堆:
所有线程共享的一块内存区域,存放对象实例, 几乎所有的对象实例都在这里分配内存。
方法区:
线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
JDK8以后,取消了“永久代”,取而代之的是“元空间”,永久代中的数据也进行了迁移,**静态成员变量迁移到了堆中**,方法区是JVM的规范,永久代是方法区的具体实现
- 对象内存模型
- 类的初始化-变量的初始化
Java常量
, final
修饰,值被设定后不能再被修改
静态变量
, static
修饰,顾名思义,无须创建对象,便可在内存中申请一个存储空间进行存储,存储在方法区(JDK6)
。
成员变量
, 也称实例变量
,它随着当前对象的建立而建立,随着对象的销毁而销毁,存在于对象所在的堆内存
中
构造器
,创建class对象时执行
静态初始化块
,执行优先级高于非静态的初始化块
,它会在对象装载到jvm的时候执行一次
,执行完成便销毁,只能初始化static
修饰的变量
非静态初始化块
,执行的时候如果有静态初始化块,先执行静态初始化块再执行非静态初始化块,在每个对象生成时都会被执行一次
,它可以初始化类的实例变量。但它会在构造函数执行之前被执行
。
初始化`父类的静态成员`
初始化`父类的静态代码块`
初始化**子类的静态成员**
初始化**子类的静态代码块**
初始化`父类的非静态成员`
初始化`父类的非静态代码块`
初始化`父类的构造方法`
初始化**子类的非静态成员**
初始化**子类的非静态代码块**
初始化**子类的构造方法**
成员变量与局部变量:类中的变量不用初始化 方法中的局部变量必须初始化。对于类的成员变量。不管程序有没有显示的初始化,Java虚拟机都会先自动给它初始化为默认值。
- 普通类、接口、抽象类的区别:
- 普通类可实例化,接口只能被子类实现再实例化,抽象类只能被子类继承并实现所有抽象方法后能实例化。
- 普通类只能实现方法,接口只能做方法的声明,抽象类可以做方法的声明和方法的实现。
- 接口中方法或变量没有写
public static final
或public abstract
会自动补齐。 - 抽象方法要被实现,所以不能是静态的,也不能是私有的。
- 抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类的抽象方法,那么该子类只能是抽象类。
- java常用关键字
关键字 | 含义 | 使用说明 |
---|---|---|
this | 指向本类实例对象 | this.字段:如果出现在父类代码中,指的就是父类属性;如果出现在子类代码中,指的就是子类属性。 this.方法:不管出现在父类还是子类代码中,指的都是子类方法。 |
super | 引用当前的类的超类 | super只是一个关键字, 不能作为参数和返回值,它只是用于告诉编译器访问父类的相关变量和方法。 |
final | 表明最终属性 | final 关键字可以应用于类,以指示不能扩展该类(不能有子类)。 final 关键字可以应用于方法,以指示在子类中不能重写此方法。 一个类不能同时是 abstract 又是 final。abstract 意味着必须扩展类,final 意味着不能扩展类。 |
static | 表明具有静态属性 | static 关键字可以应用于内部类(在另一个类中定义的类)、方法或字段(类的成员变量)。 |
volatile | 表明两个或者多个变量必须同步地发生变化(公开透明 ) |
volatile 关键字用于表示可以被多个线程异步修改的成员变量。 volatile 的目标用途是为了确保所有线程所看到的指定变量的值都是相同的。 Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。 |
synchronized | 表明一段代码需要同步执行 | synchronized 关键字可以应用于方法或语句块,并为一次只应由一个线程执行的关键代码段提供保护。 如果应用于静态方法,当该方法一次由一个线程执行时,整个类将被锁定。 如果应用于实例方法,当该方法一次由一个线程访问时,该实例将被锁定。 如果应用于对象或数组,当关联的代码块一次由一个线程执行时,对象或数组将被锁定。 |
数据库基础
算法/逻辑
框架应用
前端
Vue
Element-UI
RequireJS
大数据开发
hadoop
-
简要描述如何安装配置一个apache开源版hadoop?
-
独立模式,解压开箱即用(本地开发调测)
-
伪分布式模式(测试环境)
``` –解压hadoop包,到指定安装文件夹
-
–配置linux基本网络环境、jdk环境、防火墙环境
–修改主机名,方便后面UI的访问
–修改hadoop/etc/hadoop/conf下的配置文件,根据部署的模式和需要进行配置
–格式化namenode,对数据缓存的的路径进行格式化
–启动hadoop进程 ```
+ 完全分布式模式
-
正常工作的hadoop集群中hadoop都需要启动哪些进程,他们的作用分别是什么?
-
namenode =>HDFS的守护进程,负责维护整个文件系统,存储着整个文件系统的元数据信息,有image+edit log namenode不会持久化存储这些数据, 而是在启动时重建这些数据。
-
datanode =>是具体文件系统的工作节点,当我们需要某个数据,namenode告诉我们去哪里找,就直接和那个DataNode对应的服务器的后台进程进行通信, 由DataNode进行数据的检索,然后进行具体的读/写操作
-
secondarynamenode =>一个冗余的守护进程,相当于一个namenode的元数据的备份机制,定期的更新,和namenode进行通信, 将namenode上的image和edits进行合并,可以作为namenode的备份使用
-
resourcemanager =>是yarn平台的守护进程,负责所有资源的分配与调度,client的请求由此负责,监控nodemanager
-
nodemanager => 是单个节点的资源管理,执行来自resourcemanager的具体任务和命令
-
-
hadoop调度器,并简要说明其工作方法?
-
先进先出调度器(FIFO):Hadoop 中默认的调度器,也是一种批处理调度器。它先按照作业的优先级高低,再按照到达时间的先后选择被执行的作业。
-
容量调度器(Capacity Scheduler):支持多个队列,每个队列可配置一定的资源量,每个队列采用FIFO调度策略,为了防止同一个用户的作业独占队列中的资源, 该调度器会对同一用户提交的作业所占资源量进行限定。调度时,首先按以下策略选择一个合适队列:计算每个队列中正在运行的任务数与其应该分得的计算资源之间的比值, 选择一个该比值最小的队列;然后按以下策略选择该队列中一个作业:按照作业优先级和提交时间顺序选择,同时考虑用户资源量限制和内存限制
-
公平调度器(Fair Scheduler):公平调度是一种赋予作业(job)资源的方法,它的目的是让所有的作业随着时间的推移,都能平均的获取等同的共享资源。 所有的 job 具有相同的资源,当单独一个作业在运行时,它将使用整个集群。当有其它作业被提交上来时,系统会将任务(task)空闲资源(container)赋给这些新的作业, 以使得每一个作业都大概获取到等量的CPU时间。与Hadoop默认调度器维护一个作业队列不同,这个特性让小作业在合理的时间内完成的同时又不”饿”到消耗较长时间的大作业。 公平调度可以和作业优先权搭配使用——优先权像权重一样用作为决定每个作业所能获取的整体计算时间的比例。同计算能力调度器类似,支持多队列多用户,每个队列中的资源量可以配置, 同一队列中的作业公平共享队列中所有资源。
-
-
HDFS数据读写实现机制
hive
spark
mpp
HBase
-
Hbase 和 hive 有什么区别?hive 与 hbase 的底层存储是什么?hive 是产生的原因是什么?habase 是为了弥补 hadoop 的什么缺陷?
hbase与hive都是架构在hadoop之上的。都是用hadoop作为底层存储。hdfs 作为底层存储,hdfs 是存放文件的系统,而 Hbase 负责组织文件
- Hive是建立在Hadoop之上为了减少MapReducejobs编写工作的批处理系统,HBase是为了支持弥补Hadoop对实时操作的缺陷的项目 。
- 如果是全表扫描,就用Hive+Hadoop,如果是索引访问,就用HBase+Hadoop;
- Hive query就是MapReduce jobs可以从5分钟到数小时不止,HBase是非常高效的,肯定比Hive高效的多;
- Hive本身不存储和计算数据,它完全依赖于 HDFS 和 MapReduce,Hive中的表纯逻辑;
- hive借用hadoop的MapReduce来完成一些hive中的命令的执行;
- hbase是物理表,不是逻辑表,提供一个超大的内存hash表,搜索引擎通过它来存储索引,方便查询操作;
- hbase是列存储;
-
HBase是什么?
(1) Hbase一个分布式的基于列式存储的数据库,基于Hadoop的hdfs存储,zookeeper进行管理。 (2) Hbase适合存储半结构化或非结构化数据,对于数据结构字段不够确定或者杂乱无章很难按一个概念去抽取的数据。 (3) Hbase为null的记录不会被存储. (4) 基于的表包含rowkey,时间戳,和列族。新写入数据时,时间戳更新,同时可以查询到以前的版本. (5) hbase是主从架构。hmaster作为主节点,hregionserver作为从节点。
-
HBase 的特点是什么?
1)大:一个表可以有数十亿行,上百万列; 2)无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列; 3)面向列:面向列(族)的存储和权限控制,列(族)独立检索; 4)稀疏:空(null)列并不占用存储空间,表可以设计的非常稀疏; 5)数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳; 6)数据类型单一:Hbase 中的数据都是字符串,没有类型。
-
HBase 和 Hive 的区别?
Hive 和 Hbase 是两种基于 Hadoop 的不同技术–Hive 是一种类 SQL 的引擎,并且运行MapReduce 任务,Hbase 是一种在 Hadoop 之上的 NoSQL 的 Key/vale 数据库。当然,这两种工具是可以同时使用的。就像用 Google 来搜索,用 FaceBook 进行社交一样,Hive 可以用来进行统计查询,HBase 可以用来进行实时查询,数据也可以从 Hive 写到 Hbase,设置再从 Hbase 写回 Hive。
-
HBase 适用于怎样的情景?
- 半结构化或非结构化数据
- 记录非常稀疏
- 多版本数据
- 超大数据量
-
描述 HBase 的 rowKey 的设计原则?
- Rowkey 长度原则 Rowkey 是一个二进制码流,Rowkey 的长度被很多开发者建议说设计在 10~100 个字节,不过建议是越短越好,不要超过 16 个字节。
数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 Rowkey 过长比如 100个字节,1000 万列数据光 Rowkey 就要占用 100*1000 万=10 亿个字节,将近 1G 数据,这会极大影响 HFile 的存储效率;
MemStore 将缓存部分数据到内存,如果 Rowkey 字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此 Rowkey 的字节长度越短越好。
目前操作系统是都是 64 位系统,内存 8 字节对齐。控制在 16 个字节,8 字节的整数倍利用操作系统的最佳特性。
-
Rowkey 散列原则 如果Rowkey 是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段, 这样将提高数据均衡分布在每个Regionserver 实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer 上堆积的热点现象, 这样在做数据检索的时候负载将会集中在个别 RegionServer,降低查询效率。
-
Rowkey 唯一原则 必须在设计上保证其唯一性。
-
描述 HBase 中 scan 和 get 的功能以及实现的异同? HBase 的查询实现只提供两种方式:按指定 RowKey 获取唯一一条记录,get 方法(org.apache.hadoop.hbase.client.Get)Get 的方法处理分两种 : 设置了 ClosestRowBefore 和没有设置 ClosestRowBefore 的rowlock。主要是用来保证行的事务性,即每个 get 是以一个 row 来标记的。一个 row 中可以有很多 family 和 column。
按指定的条件获取一批记录,scan 方法(org.apache.Hadoop.hbase.client.Scan)实现条件查询功能使用的就是 scan 方式。
-
请详细描述 HBase 中一个 cell 的结构? HBase 中通过 row 和 columns 确定的为一个存贮单元称为 cell。 Cell:由
{row key, column(=<family> + <label>), version}
唯一确定的单元。cell
中的数据是没有类型的,全部是字节码形式存贮。 -
HBase 中 compact 用途是什么,什么时候触发,分为哪两种,有什么区别,有哪些相关配置参数? 在 hbase 中每当有 memstore 数据 flush 到磁盘之后,就形成一个 storefile,当 storeFile的数量达到一定程度后,就需要将 storefile 文件来进行 compaction 操作。
Compact 的作用:① 合并文件 、② 清除过期,多余版本的数据、③ 提高读写数据的效率
HBase 中实现了两种 compaction 的方式:minor and major. 这两种 compaction 方式的区别是:
Minor 操作只用来做部分文件的合并操作以及包括 minVersion=0 并且设置 ttl 的过期版本清理,不做任何删除数据、多版本数据的清理工作。 Major 操作是对 Region 下的 HStore 下的所有 StoreFile 执行合并操作,最终的结果是整理合并出一个文件。
-
HBase 优化
-
高可用:在 HBase 中 Hmaster 负责监控 RegionServer 的生命周期,均衡 RegionServer 的负载,如果 Hmaster 挂掉了,那么整个 HBase 集群将陷入不健康的状态,并且此时的工作状态并不会维持太久。所以 HBase 支持对 Hmaster 的高可用配置。
-
预分区:每一个 region 维护着 startRow 与 endRowKey,如果加入的数据符合某个 region 维护的rowKey 范围,则该数据交给这个 region 维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高 HBase 性能 .
-
RowKey 设计:一条数据的唯一标识就是 rowkey,那么这条数据存储于哪个分区,取决于 rowkey 处于哪个一个预分区的区间内,设计 rowkey 的主要目的 ,就是让数据均匀的分布于所有的 region中,在一定程度上防止数据倾斜(热点)。
-
内存优化:HBase 操作过程中需要大量的内存开销,毕竟 Table 是可以缓存在内存中的,一般会分配整个可用内存的 70%给 HBase 的 Java 堆。但是不建议分配非常大的堆内存,因为 GC 过程持续太久会导致 RegionServer 处于长期不可用状态,一般 16~48G 内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死。
-
基础优化 :网络、带宽、HDFS等
-
-
Region 如何预建分区? 预分区的目的主要是在创建表的时候指定分区数,提前规划表有多个分区,以及每个分区的区间范围,这样在存储的时候 rowkey 按照分区的区间存储,可以避免 region 热点问题。
-
shell 方法:
create 'tb_splits', {NAME => 'cf',VERSIONS=> 3},{SPLITS => ['10','20','30']}
-
JAVA 程序控制: · 取样,先随机生成一定数量的 rowkey,将取样数据按升序排序放到一个集合里; · 根据预分区的 region 个数,对整个集合平均分割,即是相关的 splitKeys; · HBaseAdmin.createTable(HTableDescriptor tableDescriptor,byte[][]splitkeys)可以指定预分区的 splitKey,即是指定 region 间的 rowkey 临界值。
-
-
HRegionServer 宕机如何处理?
1)ZooKeeper 会监控 HRegionServer 的上下线情况,当 ZK 发现某个 HRegionServer 宕机之后会通知 HMaster 进行失效备援; 2)该 HRegionServer 会停止对外提供服务,就是它所负责的 region 暂时停止对外提供服务; 3)HMaster 会将该 HRegionServer 所负责的 region 转移到其他 HRegionServer 上,并且会对 HRegionServer 上存在 memstore 中还未持久化到磁盘中的数据进行恢复; 4)这个恢复的工作是由 WAL 重播来完成,这个过程如下: · wal 实际上就是一个文件,存在/hbase/WAL/对应 RegionServer 路径下。 · 宕机发生时,读取该 RegionServer 所对应的路径下的 wal 文件,然后根据不同的region 切分成不同的临时文件 recover.edits。 · 当 region 被分配到新的 RegionServer 中,RegionServer 读取 region 时会进行是否存在 recover.edits,如果有则进行恢复。
-
HBase 读写流程?
-
读 ① HRegionServer 保存着 meta 表以及表数据,要访问表数据,首先 Client 先去访问zookeeper,从 zookeeper 里面获取 meta 表所在的位置信息,即找到这个 meta 表在哪个HRegionServer 上保存着。 ② 接着 Client 通过刚才获取到的 HRegionServer 的 IP 来访问 Meta 表所在的HRegionServer,从而读取到 Meta,进而获取到 Meta 表中存放的元数据。 ③ Client 通过元数据中存储的信息,访问对应的 HRegionServer,然后扫描所在HRegionServer 的 Memstore 和 Storefile 来查询数据。 ④ 最后 HRegionServer 把查询到的数据响应给 Client。
-
写 ① Client 先访问 zookeeper,找到 Meta 表,并获取 Meta 表元数据。 ② 确定当前将要写入的数据所对应的 HRegion 和 HRegionServer 服务器。 ③ Client 向该 HRegionServer 服务器发起写入数据请求,然后 HRegionServer 收到请求并响应。 ④ Client 先把数据写入到 HLog,以防止数据丢失。 ⑤ 然后将数据写入到 Memstore。 ⑥ 如果 HLog 和 Memstore 均写入成功,则这条数据写入成功 ⑦ 如果 Memstore 达到阈值,会把 Memstore 中的数据 flush 到 Storefile 中。 ⑧ 当 Storefile 越来越多,会触发 Compact 合并操作,把过多的 Storefile 合并成一个大的 Storefile。 ⑨ 当 Storefile 越来越大,Region 也会越来越大,达到阈值后,会触发 Split 操作,将Region 一分为二。
-
-
HBase 内部机制是什么?
Hbase 是一个能适应联机业务的数据库系统物理存储:hbase 的持久化数据是将数据存储在 HDFS 上。
存储管理:一个表是划分为很多 region 的,这些 region 分布式地存放在很多 regionserver上 Region 内部还可以划分为 store,store 内部有 memstore 和 storefile。
版本管理:hbase 中的数据更新本质上是不断追加新的版本,通过 compact 操作来做版本间的文件合并 Region 的 split。
集群管理:ZooKeeper + HMaster + HRegionServer。
-
HBase 在进行模型设计时重点在什么地方?一张表中定义多少个 Column Family 最合适?为什么? Column Family 的个数具体看表的数据,一般来说划分标准是根据数据访问频度,如一张表里有些列访问相对频繁,而另一些列访问很少,这时可以把这张表划分成两个列族,分开存储,提高访问效率。
- 如何提高 HBase 客户端的读写性能?
- 开启 bloomfilter 过滤器,开启 bloomfilter 比没开启要快 3、4 倍
- Hbase 对于内存有特别的需求,在硬件允许的情况下配足够多的内存给它
- 增大 RPC 数量,通过修改 hbase-site.xml 中的 hbase.regionserver.handler.count 属性,可以适当的放大RPC 数量,默认值为 10 有点小。
-
直接将时间戳作为行健,在写入单个 region 时候会发生热点问题,为什么呢?
region 中的 rowkey 是有序存储,若时间比较集中。就会存储到一个 region 中,这样一个 region 的数据变多,其它的 region 数据很少,加载数据就会很慢,直到 region 分裂,此问题才会得到缓解。
-
请描述如何解决 HBase 中 region 太小和 region 太大带来的冲突?
Region 过大会发生多次compaction,将数据读一遍并重写一遍到 hdfs 上,占用io,region过小会造成多次 split,region 会下线,影响访问服务,最佳的解决方法是调整 hbase.hregion.max.filesize 为 256m。
-
解释一下布隆过滤器原理?
- 为什么不建议在 HBase 中使用过多的列族?
一个Region中有多个Store,如果每个CF的数据量分布不均匀时,比如CF1为100万,CF2为1万,则Region分裂时导致CF2在每个Region中的数据量太少,查询CF2时会横跨多个Region导致效率降低。 如果每个CF的数据分布均匀,比如CF1有50万,CF2有50万,CF3有50万,则Region分裂时导致每个CF在Region的数据量偏少,查询某个CF时会导致横跨多个Region的概率增大。 多个CF代表有多个Store,也就是说有多个MemStore(2MB),也就导致内存的消耗量增大,使用效率下降。 Region 中的 缓存刷新 和 压缩 是基本操作,即一个CF出现缓存刷新或压缩操作,其它CF也会同时做一样的操作,当列族太多时就会导致IO频繁的问题。