大數(shù)據(jù)工程師面試題與參考答案集錦

1. 選擇題
1.1. 下面哪個(gè)程序負(fù)責(zé) HDFS 數(shù)據(jù)存儲(chǔ)。
a)NameNode b)Jobtracker c)Datanode d)secondaryNameNode e)tasktracker
答案 C datanode
1.2. HDfS 中的 block 默認(rèn)保存幾份?
a)3 份 b)2 份 c)1 份 d)不確定
答案 A 默認(rèn) 3 份
1.3. 下列哪個(gè)程序通常與NameNode在一個(gè)節(jié)點(diǎn)啟動(dòng)?
a)SecondaryNameNode b)DataNode c)TaskTracker d)Jobtracker
答案 D
1.4. HDFS 默認(rèn) Block Size
a)32MB b)64MB c)128MB
答案:B
1.5. 下列哪項(xiàng)通常是集群的最主要瓶頸
a)CPU b)網(wǎng)絡(luò) c)磁盤 IO d)內(nèi)存
答案:C 磁盤
首先集群的目的是為了節(jié)省成本,用廉價(jià)的 pc 機(jī),取代小型機(jī)及大型機(jī)。小型機(jī)和大型機(jī)有什么特點(diǎn)?
1.cpu 處理能力強(qiáng)
2.內(nèi)存夠大,所以集群的瓶頸不可能是 a 和 d
3.如果是互聯(lián)網(wǎng)有瓶頸,可以讓集群搭建內(nèi)網(wǎng)。每次寫入數(shù)據(jù)都要通過網(wǎng)絡(luò)(集群是內(nèi)網(wǎng)),然后還要寫入 3 份數(shù)據(jù),所以 IO 就會(huì)打折扣。
1.6. 關(guān)于 SecondaryNameNode 哪項(xiàng)是正確的?
a)它是 NameNode 的熱備 b)它對(duì)內(nèi)存沒有要求
c)它的目的是幫助 NameNode 合并編輯日志,減少 NameNode 啟動(dòng)時(shí)間
d)SecondaryNameNode 應(yīng)與 NameNode 部署到一個(gè)節(jié)點(diǎn)
答案 C。
1.7. 下列哪項(xiàng)可以作為集群的管理?
a)Puppet b)Pdsh c)Cloudera Manager d)Zookeeper
答案 ABD
具體可查看什么是 Zookeeper,Zookeeper 的作用是什么,在 Hadoop 及 hbase 中具體作用是什么。
1.8. Client 端上傳文件的時(shí)候下列哪項(xiàng)正確
a)數(shù)據(jù)經(jīng)過 NameNode 傳遞給 DataNode
b)Client 端將文件切分為 Block,依次上傳
c)Client 只上傳數(shù)據(jù)到一臺(tái) DataNode,然后由 NameNode 負(fù)責(zé) Block 復(fù)制工作
答案 B
分析:Client 向 NameNode 發(fā)起文件寫入的請(qǐng)求。NameNode 根據(jù)文件大小和文件塊配置情況,返回給 Client 它所管理部分 DataNode 的信息。Client 將文件劃分為多個(gè) Block,根據(jù) DataNode 的地址信息,按順序?qū)懭氲矫恳粋€(gè)DataNode 塊中。具體查看HDFS 體系結(jié)構(gòu)簡(jiǎn)介及優(yōu)缺點(diǎn)。
1.9. 下列哪個(gè)是 Hadoop 運(yùn)行的模式
a)單機(jī)版 b)偽分布式 c)分布式
答案 ABC 單機(jī)版,偽分布式只是學(xué)習(xí)用的。
2. 面試題
2.1. Hadoop的核心配置是什么?
Hadoop的核心配置通過兩個(gè)xml文件來完成:1,hadoop-default.xml;2,hadoop-site.xml。這些文件都使用xml格式,因此每個(gè)xml中都有一些屬性,包括名稱和值,但是當(dāng)下這些文件都已不復(fù)存在。
2.2. 那當(dāng)下又該如何配置?
Hadoop現(xiàn)在擁有3個(gè)配置文件:1,core-site.xml;2,hdfs-site.xml;3,mapred-site.xml。這些文件都保存在conf/子目錄下。
2.3. “jps”命令的用處?
這個(gè)命令可以檢查Namenode、Datanode、Task Tracker、 Job Tracker是否正常工作。
2.4. mapreduce的原理?
2.5. HDFS存儲(chǔ)的機(jī)制?
2.5.1. hdfs寫流程
流程:
1、 client鏈接namenode存數(shù)據(jù)
2、 namenode記錄一條數(shù)據(jù)位置信息(元數(shù)據(jù)),告訴client存哪。
3、 client用hdfs的api將數(shù)據(jù)塊(默認(rèn)是64M)存儲(chǔ)到datanode上。
4、 datanode將數(shù)據(jù)水平備份。并且備份完將反饋client。
5、 client通知namenode存儲(chǔ)塊完畢。
6、 namenode將元數(shù)據(jù)同步到內(nèi)存中。
7、 另一塊循環(huán)上面的過程。
2.5.2. 讀流程
流程:
1、 client鏈接namenode,查看元數(shù)據(jù),找到數(shù)據(jù)的存儲(chǔ)位置。
2、 client通過hdfs的api并發(fā)讀取數(shù)據(jù)。
3、 關(guān)閉連接。
2.6. 舉一個(gè)簡(jiǎn)單的例子說明mapreduce是怎么來運(yùn)行的 ?
wordcount的例子
2.7. 用mapreduce來實(shí)現(xiàn)下面需求?
現(xiàn)在有10個(gè)文件夾,每個(gè)文件夾都有1000000個(gè)url.現(xiàn)在讓你找出top1000000url。
解答:topk
(還可以用treeMap, 到1000000了每來一個(gè)都加進(jìn)去, 刪掉最小的)
2.8. hadoop中Combiner的作用?
combiner是reduce的實(shí)現(xiàn),在map端運(yùn)行計(jì)算任務(wù),減少map端的輸出數(shù)據(jù)。
作用就是優(yōu)化。
但是combiner的使用場(chǎng)景是mapreduce的map和reduce輸入輸出一樣。
2.9. 簡(jiǎn)述hadoop安裝
2.10. 請(qǐng)列出hadoop進(jìn)程名
2.11. 解決下面的錯(cuò)誤
1、 權(quán)限問題,可能曾經(jīng)用root啟動(dòng)過集群。(例如hadoop搭建的集群,是tmp/hadoop-hadoop/.....)
2、 可能是文件夾不存在
3、 解決: 刪掉tmp下的那個(gè)文件,或改成當(dāng)前用戶
2.12. 寫出下面的命令
2.13. 簡(jiǎn)述hadoop的調(diào)度器
2.14. 列出你開發(fā)mapreduce的語言
java
2.15. 書寫程序
wordcount
2.16. 不同語言的優(yōu)缺點(diǎn)
hadoop是java寫的,java的集成效果最好,并且平臺(tái)環(huán)境統(tǒng)一。
2.17. hive有哪些保存元數(shù)據(jù)的方式,個(gè)有什么特點(diǎn)。
1、 內(nèi)存數(shù)據(jù)庫derby,安裝小,但是數(shù)據(jù)存在內(nèi)存,不穩(wěn)定
2、 mysql數(shù)據(jù)庫,數(shù)據(jù)存儲(chǔ)模式可以自己設(shè)置,持久化好,查看方便。
2.18. combiner和partition的作用
combiner是reduce的實(shí)現(xiàn),在map端運(yùn)行計(jì)算任務(wù),減少map端的輸出數(shù)據(jù)。
作用就是優(yōu)化。
但是combiner的使用場(chǎng)景是mapreduce的map輸出結(jié)果和reduce輸入輸出一樣。
partition的默認(rèn)實(shí)現(xiàn)是hashpartition,是map端將數(shù)據(jù)按照reduce個(gè)數(shù)取余,進(jìn)行分區(qū),不同的reduce來copy自己的數(shù)據(jù)。
partition的作用是將數(shù)據(jù)分到不同的reduce進(jìn)行計(jì)算,加快計(jì)算效果。
2.19. hive內(nèi)部表和外部表的區(qū)別
內(nèi)部表:加載數(shù)據(jù)到hive所在的hdfs目錄,刪除時(shí),元數(shù)據(jù)和數(shù)據(jù)文件都刪除
外部表:不加載數(shù)據(jù)到hive所在的hdfs目錄,刪除時(shí),只刪除表結(jié)構(gòu)。
2.20. hbase的rowkey怎么創(chuàng)建好?列族怎么創(chuàng)建比較好?
hbase存儲(chǔ)時(shí),數(shù)據(jù)按照Row key的字典序(byte order)排序存儲(chǔ)。設(shè)計(jì)key時(shí),要充分排序存儲(chǔ)這個(gè)特性,將經(jīng)常一起讀取的行存儲(chǔ)放到一起。(位置相關(guān)性)
一個(gè)列族在數(shù)據(jù)底層是一個(gè)文件,所以將經(jīng)常一起查詢的列放到一個(gè)列族中,列族盡量少,減少文件的尋址時(shí)間。
2.21. 用mapreduce怎么處理數(shù)據(jù)傾斜問題?
數(shù)據(jù)傾斜:map /reduce程序執(zhí)行時(shí),reduce節(jié)點(diǎn)大部分執(zhí)行完畢,但是有一個(gè)或者幾個(gè)reduce節(jié)點(diǎn)運(yùn)行很慢,導(dǎo)致整個(gè)程序的處理時(shí)間很長(zhǎng),這是因?yàn)槟骋粋€(gè)key的條數(shù)比其他key多很多(有時(shí)是百倍或者千倍之多),這條key所在的reduce節(jié)點(diǎn)所處理的數(shù)據(jù)量比其他節(jié)點(diǎn)就大很多,從而導(dǎo)致某幾個(gè)節(jié)點(diǎn)遲遲運(yùn)行不完,此稱之為數(shù)據(jù)傾斜。
用hadoop程序進(jìn)行數(shù)據(jù)關(guān)聯(lián)時(shí),常碰到數(shù)據(jù)傾斜的情況,這里提供一種解決方法。
自己實(shí)現(xiàn)partition類,用key和value相加取hash值:
方式1:
源代碼:
public int getPartition(K key, V value, int numReduceTasks) { return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks; }
修改后
public int getPartition(K key, V value, int numReduceTasks) { return (((key).hashCode()+value.hashCode()) & Integer.MAX_VALUE) % numReduceTasks; }
方式2:
public class HashPartitioner<K, V> extends Partitioner<K, V> { private int aa= 0; /** Use {@link Object#hashCode()} to partition. */ public int getPartition(K key, V value, int numReduceTasks) { return (key.hashCode()+(aa++) & Integer.MAX_VALUE) % numReduceTasks; }
2.22. hadoop框架中怎么來優(yōu)化
(1) 從應(yīng)用程序角度進(jìn)行優(yōu)化。由于mapreduce是迭代逐行解析數(shù)據(jù)文件的,怎樣在迭代的情況下,編寫高效率的應(yīng)用程序,是一種優(yōu)化思路。
(2) 對(duì)Hadoop參數(shù)進(jìn)行調(diào)優(yōu)。當(dāng)前hadoop系統(tǒng)有190多個(gè)配置參數(shù),怎樣調(diào)整這些參數(shù),使hadoop作業(yè)運(yùn)行盡可能的快,也是一種優(yōu)化思路。
(3) 從系統(tǒng)實(shí)現(xiàn)角度進(jìn)行優(yōu)化。這種優(yōu)化難度是最大的,它是從hadoop實(shí)現(xiàn)機(jī)制角度,發(fā)現(xiàn)當(dāng)前Hadoop設(shè)計(jì)和實(shí)現(xiàn)上的缺點(diǎn),然后進(jìn)行源碼級(jí)地修改。該方法雖難度大,但往往效果明顯。
(4)linux內(nèi)核參數(shù)調(diào)整
2.22.1. 從應(yīng)用程序角度進(jìn)行優(yōu)化
(1) 避免不必要的reduce任務(wù)
如果mapreduce程序中reduce是不必要的,那么我們可以在map中處理數(shù)據(jù), Reducer設(shè)置為0。這樣避免了多余的reduce任務(wù)。
(2) 為job添加一個(gè)Combiner
為job添加一個(gè)combiner可以大大減少shuffle階段從map task拷貝給遠(yuǎn)程reduce task的數(shù)據(jù)量。一般而言,combiner與reducer相同。
(3) 根據(jù)處理數(shù)據(jù)特征使用最適合和簡(jiǎn)潔的Writable類型
Text對(duì)象使用起來很方便,但它在由數(shù)值轉(zhuǎn)換到文本或是由UTF8字符串轉(zhuǎn)換到文本時(shí)都是低效的,且會(huì)消耗大量的CPU時(shí)間。當(dāng)處理那些非文本的數(shù)據(jù)時(shí),可以使用二進(jìn)制的Writable類型,如IntWritable, FloatWritable等。二進(jìn)制writable好處:避免文件轉(zhuǎn)換的消耗;使map task中間結(jié)果占用更少的空間。
(4) 重用Writable類型
很多MapReduce用戶常犯的一個(gè)錯(cuò)誤是,在一個(gè)map/reduce方法中為每個(gè)輸出都創(chuàng)建Writable對(duì)象。例如,你的Wordcout mapper方法可能這樣寫:
public void map(...) { … for (String word : words) { output.collect(new Text(word), new IntWritable(1)); } }
這樣會(huì)導(dǎo)致程序分配出成千上萬個(gè)短周期的對(duì)象。Java垃圾收集器就要為此做很多的工作。更有效的寫法是:
class MyMapper … { Text wordText = new Text(); IntWritable one = new IntWritable(1); public void map(...) { for (String word: words) { wordText.set(word); output.collect(wordText, one); } } }
(5) 使用StringBuffer而不是String
當(dāng)需要對(duì)字符串進(jìn)行操作時(shí),使用StringBuffer而不是String,String是read-only的,如果對(duì)它進(jìn)行修改,會(huì)產(chǎn)生臨時(shí)對(duì)象,而StringBuffer是可修改的,不會(huì)產(chǎn)生臨時(shí)對(duì)象。
2.22.2. 對(duì)參數(shù)進(jìn)行調(diào)優(yōu)
查看linux的服務(wù),可以關(guān)閉不必要的服務(wù)
ntsysv
停止打印服務(wù)
#/etc/init.d/cups stop
#chkconfig cups off
關(guān)閉ipv6
#vim /etc/modprobe.conf
添加內(nèi)容
alias net-pf-10 off
alias ipv6 off
調(diào)整文件最大打開數(shù)
查看: ulimit -a 結(jié)果:open files (-n) 1024
臨時(shí)修改: ulimit -n 4096
持久修改:
vi /etc/security/limits.conf在文件最后加上:
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
修改linux內(nèi)核參數(shù)
vi /etc/sysctl.conf
添加
net.core.somaxconn = 32768
#web應(yīng)用中l(wèi)isten函數(shù)的backlog默認(rèn)會(huì)給我們內(nèi)核參數(shù)的net.core.somaxconn限制到128,而nginx定義的NGX_LISTEN_BACKLOG默認(rèn)為511,所以有必要調(diào)整這個(gè)值。
調(diào)整swap分區(qū)什么時(shí)候使用:
查看:cat /proc/sys/vm/swappiness
設(shè)置:vi /etc/sysctl.conf
在這個(gè)文檔的最后加上這樣一行: vm.swappiness=10
表示物理內(nèi)存使用到90%(100-10=90)的時(shí)候才使用swap交換區(qū)
關(guān)閉noatime
vi /etc/fstab
/dev/sda2 /data ext3 noatime,nodiratime 0 0
設(shè)置readahead buffer
blockdev --setra READAHEAD 512 /dev/sda
一下是修改mapred-site.xml文件
修改最大槽位數(shù)
槽位數(shù)是在各個(gè)tasktracker上的mapred-site.xml上設(shè)置的,默認(rèn)都是2
<property> <name>mapred.tasktracker.map.tasks.maximum</name> #++++maptask的最大數(shù) <value>2</value> </property> <property> <name>mapred.tasktracker.reduce.tasks.maximum</name> #++++reducetask的最大數(shù) <value>2</value> </property>
調(diào)整心跳間隔
集群規(guī)模小于300時(shí),心跳間隔為300毫秒
mapreduce.jobtracker.heartbeat.interval.min 心跳時(shí)間
mapred.heartbeats.in.second 集群每增加多少節(jié)點(diǎn),時(shí)間增加下面的值
mapreduce.jobtracker.heartbeat.scaling.factor 集群每增加上面的個(gè)數(shù),心跳增多少
啟動(dòng)帶外心跳
mapreduce.tasktracker.outofband.heartbeat 默認(rèn)是false
配置多塊磁盤
mapreduce.local.dir
配置RPC hander數(shù)目
mapred.job.tracker.handler.count 默認(rèn)是10,可以改成50,根據(jù)機(jī)器的能力
配置HTTP線程數(shù)目
tasktracker.http.threads 默認(rèn)是40,可以改成100 根據(jù)機(jī)器的能力
選擇合適的壓縮方式
以snappy為例:
<property> <name>mapred.compress.map.output</name> <value>true</value> </property> <property> <name>mapred.map.output.compression.codec</name> <value>org.apache.hadoop.io.compress.SnappyCodec</value> </property>
啟用推測(cè)執(zhí)行機(jī)制
推測(cè)執(zhí)行(Speculative Execution)是指在分布式集群環(huán)境下,因?yàn)槌绦駼UG,負(fù)載不均衡或者資源分布不均等原因,造成同一個(gè)job的多個(gè)task運(yùn)行速度不一致,有的task運(yùn)行速度明顯慢于其他task(比如:一個(gè)job的某個(gè)task進(jìn)度只有10%,而其他所有task已經(jīng)運(yùn)行完畢),則這些task拖慢了作業(yè)的整體執(zhí)行進(jìn)度,為了避免這種情況發(fā)生,Hadoop會(huì)為該task啟動(dòng)備份任務(wù),讓該speculative task與原始task同時(shí)處理一份數(shù)據(jù),哪個(gè)先運(yùn)行完,則將誰的結(jié)果作為最終結(jié)果。
推測(cè)執(zhí)行優(yōu)化機(jī)制采用了典型的以空間換時(shí)間的優(yōu)化策略,它同時(shí)啟動(dòng)多個(gè)相同task(備份任務(wù))處理相同的數(shù)據(jù)塊,哪個(gè)完成的早,則采用哪個(gè)task的結(jié)果,這樣可防止拖后腿Task任務(wù)出現(xiàn),進(jìn)而提高作業(yè)計(jì)算速度,但是,這樣卻會(huì)占用更多的資源,在集群資源緊缺的情況下,設(shè)計(jì)合理的推測(cè)執(zhí)行機(jī)制可在多用少量資源情況下,減少大作業(yè)的計(jì)算時(shí)間。
mapred.map.tasks.speculative.execution 默認(rèn)是true
mapred.rduce.tasks.speculative.execution 默認(rèn)是true
設(shè)置是失敗容忍度
mapred.max.map.failures.percent 作業(yè)允許失敗的map最大比例 默認(rèn)值0,即0%
mapred.max.reduce.failures.percent 作業(yè)允許失敗的reduce最大比例 默認(rèn)值0,即0%
mapred.map.max.attemps 失敗后最多重新嘗試的次數(shù) 默認(rèn)是4
mapred.reduce.max.attemps 失敗后最多重新嘗試的次數(shù) 默認(rèn)是4
啟動(dòng)jvm重用功能
mapred.job.reuse.jvm.num.tasks 默認(rèn)值1,表示只能啟動(dòng)一個(gè)task,若為-1,表示可以最多運(yùn)行數(shù)不限制
設(shè)置任務(wù)超時(shí)時(shí)間
mapred.task.timeout 默認(rèn)值600000毫秒,也就是10分鐘。
合理的控制reduce的啟動(dòng)時(shí)間
mapred.reduce.slowstart.completed.maps 默認(rèn)值0.05 表示map任務(wù)完成5%時(shí),開始啟動(dòng)reduce任務(wù)
跳過壞記錄
當(dāng)任務(wù)失敗次數(shù)達(dá)到該值時(shí),才會(huì)進(jìn)入skip mode,即啟用跳過壞記錄數(shù)功能,也就是先試幾次,不行就跳過
mapred.skip.attempts.to.start.skipping 默認(rèn)值 2
map最多允許跳過的記錄數(shù)
mapred.skip.map.max.skip.records 默認(rèn)值0,為不啟用
reduce最多允許跳過的記錄數(shù)
mapred.skip.reduce.max.skip.records 默認(rèn)值0,為不啟用
換記錄存放的目錄
mapred.skip.out.dir 默認(rèn)值${mapred.output.dir}/_logs/
2.23. 我們開發(fā)job時(shí),是否可以去掉reduce階段。
可以。設(shè)置reduce數(shù)為0 即可。
2.24. datanode在什么情況下不會(huì)備份
datanode在強(qiáng)制關(guān)閉或者非正常斷電不會(huì)備份。
2.25. combiner出現(xiàn)在那個(gè)過程
出現(xiàn)在map階段的map方法后。
2.26. hdfs的體系結(jié)構(gòu)
hdfs有namenode、secondraynamenode、datanode組成。
為n+1模式
namenode負(fù)責(zé)管理datanode和記錄元數(shù)據(jù)
secondraynamenode負(fù)責(zé)合并日志
datanode負(fù)責(zé)存儲(chǔ)數(shù)據(jù)
2.27. 3個(gè)datanode中有一個(gè)datanode出現(xiàn)錯(cuò)誤會(huì)怎樣?
這個(gè)datanode的數(shù)據(jù)會(huì)在其他的datanode上重新做備份。
2.28. 描述一下hadoop中,有哪些地方使用了緩存機(jī)制,作用分別是什么?
在mapreduce提交job的獲取id之后,會(huì)將所有文件存儲(chǔ)到分布式緩存上,這樣文件可以被所有的mapreduce共享。
2.29. 如何確定hadoop集群的健康狀態(tài)
通過頁面監(jiān)控,腳本監(jiān)控。
2.30. 生產(chǎn)環(huán)境中為什么建議使用外部表?
1、因?yàn)橥獠勘聿粫?huì)加載數(shù)據(jù)到hive,減少數(shù)據(jù)傳輸、數(shù)據(jù)還能共享。
2、hive不會(huì)修改數(shù)據(jù),所以無需擔(dān)心數(shù)據(jù)的損壞
3、 刪除表時(shí),只刪除表結(jié)構(gòu)、不刪除數(shù)據(jù)。
3. 15期新增
3.1. 新增
4、 通過節(jié)點(diǎn)信息和瀏覽器查看,通過腳本監(jiān)控
hadoop-deamon.sh start namenode
hdfs-deamon.sh start namenode
5、 自己書寫腳本監(jiān)控重啟
6、 行健以字典序排列,設(shè)計(jì)時(shí)充分利用這個(gè)特點(diǎn),將經(jīng)常一起查詢的行健設(shè)計(jì)在一起,例如時(shí)間戳結(jié)尾,用戶名開頭(位置相關(guān)性)
1、 用hive分析業(yè)務(wù)數(shù)據(jù)即可
2、 將數(shù)據(jù)導(dǎo)入到hive中
sql的設(shè)計(jì)思路:多表關(guān)聯(lián)
1、 找到所有在2015-01-01到2015-01-31時(shí)間內(nèi)訪問A頁面的用戶
2、 在這些用戶中刪選在2015-01-01到2015-03-31下單的用戶
3、 統(tǒng)計(jì)總數(shù)
3.2. 你們數(shù)據(jù)庫怎么導(dǎo)入hive 的,有沒有出現(xiàn)問題
在導(dǎo)入hive的時(shí)候,如果數(shù)據(jù)庫中有blob或者text字段,會(huì)報(bào)錯(cuò),解決方案在sqoop筆記中
3.3. 公司技術(shù)選型可能利用storm 進(jìn)行實(shí)時(shí)計(jì)算,講解一下storm
描述下storm的設(shè)計(jì)模式,是基于work、excutor、task的方式運(yùn)行代碼,由spout、bolt組成等等
3.4. 一個(gè)datanode 宕機(jī),怎么一個(gè)流程恢復(fù)
將datanode數(shù)據(jù)刪除,重新當(dāng)成新節(jié)點(diǎn)加入即可。
3.5. Hbase 的特性,以及你怎么去設(shè)計(jì) rowkey 和 columnFamily ,怎么去建一個(gè)table
hbase是列式數(shù)據(jù)庫,rowkey是字典序的,設(shè)計(jì)時(shí)的規(guī)則同上。
每個(gè)列族是一個(gè)文件,將經(jīng)常一起查詢的列放到同一個(gè)列族中,減少文件的尋址時(shí)間。
3.6. Redis,傳統(tǒng)數(shù)據(jù)庫,hbase,hive 每個(gè)之間的區(qū)別
redis:分布式緩存,強(qiáng)調(diào)緩存,內(nèi)存中數(shù)據(jù)
傳統(tǒng)數(shù)據(jù)庫:注重關(guān)系
hbase:列式數(shù)據(jù)庫,無法做關(guān)系數(shù)據(jù)庫的主外鍵,用于存儲(chǔ)海量數(shù)據(jù),底層基于hdfs
hive:數(shù)據(jù)倉庫工具,底層是mapreduce。不是數(shù)據(jù)庫,不能用來做用戶的交互存儲(chǔ)
3.7. shuffle 階段,你怎么理解的
shuffle的過程說清楚,目的說清楚
3.8. Mapreduce 的 map 數(shù)量 和 reduce 數(shù)量 怎么確定 ,怎么配置
map的數(shù)量有數(shù)據(jù)塊決定,reduce數(shù)量隨便配置。
3.9. 唯一難住我的是他說實(shí)時(shí)計(jì)算,storm 如果碰上了復(fù)雜邏輯,需要算很長(zhǎng)的時(shí)間,你怎么去優(yōu)化,怎么保證實(shí)時(shí)性
3.10. Hive 你們用的是外部表還是內(nèi)部表,有沒有寫過UDF,hive 的版本
外部表和內(nèi)部表的區(qū)別
3.11. Hadoop 的版本
1.04、1.20都為穩(wěn)定版,是兩個(gè)常用的hadoop1版本。
3.12. 實(shí)時(shí)流式計(jì)算 的結(jié)果內(nèi)容有哪些,你們需要統(tǒng)計(jì)出來么
3.13.
1、 通過flume將不同系統(tǒng)的日志收集到kafka中
2、 通過storm實(shí)時(shí)的處理PV、UV、IP
3、 通過kafka的consumer將日志生產(chǎn)到hbase中。
4、 通過離線的mapreduce或者h(yuǎn)ive,處理hbase中的數(shù)據(jù)
大體分為3個(gè)部分:
1、 離線hadoop技術(shù)分享(mapreduce、hive)
2、 nosql數(shù)據(jù)庫hbase分享
3、 實(shí)時(shí)流計(jì)算分享
1、 建表
2、 分組(group by)統(tǒng)計(jì)wordcount
select word,count(1) from table1 group by word;
可以估計(jì)每個(gè)文件的大小為50億×64=298G,遠(yuǎn)遠(yuǎn)大于內(nèi)存限制的4G。所以不可能將其完全加載到內(nèi)存中處理??紤]采取分而治之的方法。
1、 將文件存儲(chǔ)到hdfs中,這樣每個(gè)文件為64M或者是128M
2、 分別對(duì)兩個(gè)文件的url進(jìn)行去重、排序輸出,這樣能排除a文件中相同的url,b文件也一樣
3、 對(duì)a、b兩個(gè)文件處理后的結(jié)果進(jìn)行wordcount,并且在reduce中判斷單詞個(gè)數(shù),個(gè)數(shù)為2的時(shí)候輸出,這樣就找到了a、b文件中的相同url。
4、 此計(jì)算步驟中的每一步加載到內(nèi)存中的文件大小都不會(huì)超過64M,遠(yuǎn)遠(yuǎn)小于4G。
topk,強(qiáng)調(diào)使用treemap是為了節(jié)省內(nèi)存計(jì)算空間。
flume:日志收集系統(tǒng),主要用于系統(tǒng)日志的收集
kafka:消息隊(duì)列,進(jìn)行消息的緩存和系統(tǒng)的解耦
storm:實(shí)時(shí)計(jì)算框架,進(jìn)行流式的計(jì)算。
簡(jiǎn)單地說,就是一個(gè)變量和常量的關(guān)系。StringBuffer對(duì)象的內(nèi)容可以修改;而String對(duì)象一旦產(chǎn)生后就不可以被修改,重新賦值其實(shí)是兩個(gè)對(duì)象。
StringBuilder:線程非安全的
StringBuffer:線程安全的
當(dāng)我們?cè)谧址彌_去被多個(gè)線程使用是,JVM不能保證StringBuilder的操作是安全的,雖然他的速度最快,但是可以保證StringBuffer是可以正確操作的。當(dāng)然大多數(shù)情況下就是我們是在單線程下進(jìn)行的操作,所以大多數(shù)情況下是建議用StringBuilder而不用StringBuffer的,就是速度的原因。
1 HashMap不是線程安全的
hastmap是一個(gè)接口 是map接口的子接口,是將鍵映射到值的對(duì)象,其中鍵和值都是對(duì)象,并且不能包含重復(fù)鍵,但可以包含重復(fù)值。HashMap允許null key和null value,而hashtable不允許。
2 HashTable是線程安全的一個(gè)Collection。
HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable。 HashMap允許將null作為一個(gè)entry的key或者value,而Hashtable不允許。 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。 Hashtable繼承自Dictionary類,而HashMap是Java1.2引進(jìn)的Map interface的一個(gè)實(shí)現(xiàn)。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個(gè)線程訪問Hashtable時(shí),不需要自己為它的方法實(shí)現(xiàn)同步,而HashMap 就必須為之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會(huì)有很大的差
public static void main(String args[]) { HashTable h=new HashTable(); h.put("用戶1",new Integer(90)); h.put("用戶2",new Integer(50)); h.put("用戶3",new Integer(60)); h.put("用戶4",new Integer(70)); h.put("用戶5",new Integer(80)); Enumeration e=h.elements(); while(e.hasMoreElements()){ System.out.println(e.nextElement()); }
總結(jié):
hashmap |
線程不安全 |
允許有null的鍵和值 |
效率高一點(diǎn)、 |
方法不是Synchronize的要提供外同步 |
有containsvalue和containsKey方法 |
HashMap 是Java1.2 引進(jìn)的Map interface 的一個(gè)實(shí)現(xiàn) |
HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn) |
hashtable |
線程安全 |
不允許有null的鍵和值 |
效率稍低、 |
方法是是Synchronize的 |
有contains方法方法 |
、Hashtable 繼承于Dictionary 類 |
Hashtable 比HashMap 要舊 |
Vector & ArrayList
1) Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,由于線程的同步必然要影響性能,因此,ArrayList的性能比Vector好。
2) 當(dāng)Vector或ArrayList中的元素超過它的初始大小時(shí),Vector會(huì)將它的容量翻倍,而ArrayList只增加50%的大小,這樣,ArrayList就有利于節(jié)約內(nèi)存空間。
linkedlist & ArrayList
ArrayList 采用的是數(shù)組形式來保存對(duì)象的,這種方式將對(duì)象放在連續(xù)的位置中,所以最大的缺點(diǎn)就是插入刪除時(shí)非常麻煩
LinkedList 采用的將對(duì)象存放在獨(dú)立的空間中,而且在每個(gè)空間中還保存下一個(gè)鏈接的索引 但是缺點(diǎn)就是查找非常麻煩 要叢第一個(gè)索引開始
Hashtable和HashMap類有三個(gè)重要的不同之處。第一個(gè)不同主要是歷史原因。Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進(jìn)的Map接口的一個(gè)實(shí)現(xiàn)。
也許最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。這就意味著,雖然你可以不用采取任何特殊的行為就可以在一個(gè)多線程的應(yīng)用程序中用一個(gè)Hashtable,但你必須同樣地為一個(gè)HashMap提供外同步。一個(gè)方便的方法就是利用Collections類的靜態(tài)的synchronizedMap()方法,它創(chuàng)建一個(gè)線程安全的Map對(duì)象,并把它作為一個(gè)封裝的對(duì)象來返回。這個(gè)對(duì)象的方法可以讓你同步訪問潛在的HashMap。這么做的結(jié)果就是當(dāng)你不需要同步時(shí),你不能切斷Hashtable中的同步(比如在一個(gè)單線程的應(yīng)用程序中),而且同步增加了很多處理費(fèi)用。
第三點(diǎn)不同是,只有HashMap可以讓你將空值作為一個(gè)表的條目的key或value。HashMap中只有一條記錄可以是一個(gè)空的key,但任意數(shù)量的條目可以是空的value。這就是說,如果在表中沒有發(fā)現(xiàn)搜索鍵,或者如果發(fā)現(xiàn)了搜索鍵,但它是一個(gè)空的值,那么get()將返回null。如果有必要,用containKey()方法來區(qū)別這兩種情況。
一些資料建議,當(dāng)需要同步時(shí),用Hashtable,反之用HashMap。但是,因?yàn)樵谛枰獣r(shí),HashMap可以被同步,HashMap的功能比Hashtable的功能更多,而且它不是基于一個(gè)陳舊的類的,所以有人認(rèn)為,在各種情況下,HashMap都優(yōu)先于Hashtable。
關(guān)于Properties
有時(shí)侯,你可能想用一個(gè)hashtable來映射key的字符串到value的字符串。DOS、Windows和Unix中的環(huán)境字符串就有一些例子,如key的字符串PATH被映射到value的字符串C:\WINDOWS;C:\WINDOWS\SYSTEM。Hashtables是表示這些的一個(gè)簡(jiǎn)單的方法,但Java提供了另外一種方法。
Java.util.Properties類是Hashtable的一個(gè)子類,設(shè)計(jì)用于String keys和values。Properties對(duì)象的用法同Hashtable的用法相象,但是類增加了兩個(gè)節(jié)省時(shí)間的方法,你應(yīng)該知道。
Store()方法把一個(gè)Properties對(duì)象的內(nèi)容以一種可讀的形式保存到一個(gè)文件中。Load()方法正好相反,用來讀取文件,并設(shè)定Properties對(duì)象來包含keys和values。
注意,因?yàn)镻roperties擴(kuò)展了Hashtable,你可以用超類的put()方法來添加不是String對(duì)象的keys和values。這是不可取的。另外,如果你將store()用于一個(gè)不包含String對(duì)象的Properties對(duì)象,store()將失敗。作為put()和get()的替代,你應(yīng)該用setProperty()和getProperty(),它們用String參數(shù)。
在java中可有兩種方式實(shí)現(xiàn)多線程,一種是繼承Thread類,一種是實(shí)現(xiàn)Runnable接口;Thread類是在java.lang包中定義的。一個(gè)類只要繼承了Thread類同時(shí)覆寫了本類中的run()方法就可以實(shí)現(xiàn)多線程操作了,但是一個(gè)類只能繼承一個(gè)父類,這是此方法的局限。
AD:
在java中可有兩種方式實(shí)現(xiàn)多線程,一種是繼承Thread類,一種是實(shí)現(xiàn)Runnable接口;Thread類是在java.lang包中定義的。一個(gè)類只要繼承了Thread類同時(shí)覆寫了本類中的run()方法就可以實(shí)現(xiàn)多線程操作了,但是一個(gè)類只能繼承一個(gè)父類,這是此方法的局限。
下面看例子:
package org.thread.demo; class MyThread extends Thread{ private String name; public MyThread(String name) { super(); this.name = name; } public void run(){ for(int i=0;i<10;i++){ System.out.println("線程開始:"+this.name+",i="+i); } } } package org.thread.demo; public class ThreadDemo01 { public static void main(String[] args) { MyThread mt1=new MyThread("線程a"); MyThread mt2=new MyThread("線程b"); mt1.run(); mt2.run(); } }
但是,此時(shí)結(jié)果很有規(guī)律,先第一個(gè)對(duì)象執(zhí)行,然后第二個(gè)對(duì)象執(zhí)行,并沒有相互運(yùn)行。在JDK的文檔中可以發(fā)現(xiàn),一旦調(diào)用start()方法,則會(huì)通過JVM找到run()方法。下面啟動(dòng)start()方法啟動(dòng)線程:
package org.thread.demo; public class ThreadDemo01 { public static void main(String[] args) { MyThread mt1=new MyThread("線程a"); MyThread mt2=new MyThread("線程b"); mt1.start(); mt2.start(); } };
這樣程序可以正常完成交互式運(yùn)行。那么為啥非要使用start();方法啟動(dòng)多線程呢?
在JDK的安裝路徑下,src.zip是全部的java源程序,通過此代碼找到Thread中的start()方法的定義,可以發(fā)現(xiàn)此方法中使用了private native void start0();其中native關(guān)鍵字表示可以調(diào)用操作系統(tǒng)的底層函數(shù),那么這樣的技術(shù)成為JNI技術(shù)(java Native Interface)
Runnable接口
在實(shí)際開發(fā)中一個(gè)多線程的操作很少使用Thread類,而是通過Runnable接口完成。
public interface Runnable{ public void run(); }
例子:
package org.runnable.demo; class MyThread implements Runnable{ private String name; public MyThread(String name) { this.name = name; } public void run(){ for(int i=0;i<100;i++){ System.out.println("線程開始:"+this.name+",i="+i); } } };
但是在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。此時(shí)觀察Thread類,有一個(gè)構(gòu)造方法:public Thread(Runnable targer)此構(gòu)造方法接受Runnable的子類實(shí)例,也就是說可以通過Thread類來啟動(dòng)Runnable實(shí)現(xiàn)的多線程。(start()可以協(xié)調(diào)系統(tǒng)的資源):
package org.runnable.demo; import org.runnable.demo.MyThread; public class ThreadDemo01 { public static void main(String[] args) { MyThread mt1=new MyThread("線程a"); MyThread mt2=new MyThread("線程b"); new Thread(mt1).start(); new Thread(mt2).start(); } }
兩種實(shí)現(xiàn)方式的區(qū)別和聯(lián)系:
在程序開發(fā)中只要是多線程肯定永遠(yuǎn)以實(shí)現(xiàn)Runnable接口為主,因?yàn)閷?shí)現(xiàn)Runnable接口相比繼承Thread類有如下好處:
· 避免點(diǎn)繼承的局限,一個(gè)類可以繼承多個(gè)接口。
· 適合于資源的共享
以賣票程序?yàn)槔ㄟ^Thread類完成:
package org.demo.dff; class MyThread extends Thread{ private int ticket=10; public void run(){ for(int i=0;i<20;i++){ if(this.ticket>0){ System.out.println("賣票:ticket"+this.ticket--); } } } };
下面通過三個(gè)線程對(duì)象,同時(shí)賣票:
package org.demo.dff; public class ThreadTicket { public static void main(String[] args) { MyThread mt1=new MyThread(); MyThread mt2=new MyThread(); MyThread mt3=new MyThread(); mt1.start();//每個(gè)線程都各賣了10張,共賣了30張票 mt2.start();//但實(shí)際只有10張票,每個(gè)線程都賣自己的票 mt3.start();//沒有達(dá)到資源共享 } }
如果用Runnable就可以實(shí)現(xiàn)資源共享,下面看例子:
package org.demo.runnable; class MyThread implements Runnable{ private int ticket=10; public void run(){ for(int i=0;i<20;i++){ if(this.ticket>0){ System.out.println("賣票:ticket"+this.ticket--); } } } } package org.demo.runnable; public class RunnableTicket { public static void main(String[] args) { MyThread mt=new MyThread(); new Thread(mt).start();//同一個(gè)mt,但是在Thread中就不可以,如果用同一 new Thread(mt).start();//個(gè)實(shí)例化對(duì)象mt,就會(huì)出現(xiàn)異常 new Thread(mt).start(); } };
雖然現(xiàn)在程序中有三個(gè)線程,但是一共賣了10張票,也就是說使用Runnable實(shí)現(xiàn)多線程可以達(dá)到資源共享目的。
3.14.
hdfs在存儲(chǔ)的時(shí)候不會(huì)將數(shù)據(jù)進(jìn)行壓縮,如果想進(jìn)行壓縮,我們可以在向hdfs上傳數(shù)據(jù)的時(shí)候進(jìn)行壓縮。
1、 采用壓縮流
//壓縮文件 public static void compress(String codecClassName) throws Exception{ Class<?> codecClass = Class.forName(codecClassName); Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf); //指定壓縮文件路徑 FSDataOutputStream outputStream = fs.create(new Path("/user/hadoop/text.gz")); //指定要被壓縮的文件路徑 FSDataInputStream in = fs.open(new Path("/user/hadoop/aa.txt")); //創(chuàng)建壓縮輸出流 CompressionOutputStream out = codec.createOutputStream(outputStream); IOUtils.copyBytes(in, out, conf); IOUtils.closeStream(in); IOUtils.closeStream(out); }
2、 采用序列化文件
public void testSeqWrite() throws Exception { Configuration conf = new Configuration();// 創(chuàng)建配置信息 conf.set("fs.default.name", "hdfs://master:9000");// hdfs默認(rèn)路徑 conf.set("hadoop.job.ugi", "hadoop,hadoop");// 用戶和組信息 String uriin = "hdfs://master:9000/ceshi2/";// 文件路徑 FileSystem fs = FileSystem.get(URI.create(uriin), conf);// 創(chuàng)建filesystem Path path = new Path("hdfs://master:9000/ceshi3/test.seq");// 文件名 IntWritable k = new IntWritable();// key,相當(dāng)于int Text v = new Text();// value,相當(dāng)于String SequenceFile.Writer w = SequenceFile.createWriter(fs, conf, path, k.getClass(), v.getClass());// 創(chuàng)建writer for (int i = 1; i < 100; i++) {// 循環(huán)添加 k.set(i); v.set("abcd"); w.append(k, v); } w.close(); IOUtils.closeStream(w);// 關(guān)閉的時(shí)候flush fs.close(); }
hbase為列存數(shù)據(jù)庫,本身存在壓縮機(jī)制,所以無需設(shè)計(jì)。
1、 在庫表設(shè)計(jì)的時(shí)候,盡量考慮rowkey和columnfamily的特性
2、 進(jìn)行hbase集群的調(diào)優(yōu):見hbase調(diào)優(yōu)
hbase的filter是通過scan設(shè)置的,所以是基于scan的查詢結(jié)果進(jìn)行過濾。
1、 在進(jìn)行訂單開發(fā)的時(shí)候,我們使用rowkeyfilter過濾出某個(gè)用戶的所有訂單
2、 在進(jìn)行云筆記開發(fā)時(shí),我們使用rowkey過濾器進(jìn)行redis數(shù)據(jù)的恢復(fù)。
使用rowkey過濾器實(shí)現(xiàn)
Hive提供了三個(gè)虛擬列:
INPUT__FILE__NAME
BLOCK__OFFSET__INSIDE__FILE
ROW__OFFSET__INSIDE__BLOCK
但ROW__OFFSET__INSIDE__BLOCK默認(rèn)是不可用的,需要設(shè)置hive.exec.rowoffset為true才可以??梢杂脕砼挪橛袉栴}的輸入數(shù)據(jù)。
INPUT__FILE__NAME, mapper任務(wù)的輸出文件名。
BLOCK__OFFSET__INSIDE__FILE, 當(dāng)前全局文件的偏移量。對(duì)于塊壓縮文件,就是當(dāng)前塊的文件偏移量,即當(dāng)前塊的第一個(gè)字節(jié)在文件中的偏移量。
hive> SELECT INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE, line
> FROM hive_text WHERE line LIKE '%hive%' LIMIT 2;
har://file/user/hive/warehouse/hive_text/folder=docs/
data.har/user/hive/warehouse/hive_text/folder=docs/README.txt 2243
har://file/user/hive/warehouse/hive_text/folder=docs/
data.har/user/hive/warehouse/hive_text/folder=docs/README.txt 3646
1、 將小文件打成har文件存儲(chǔ)
2、 將小文件序列化到hdfs中
寫個(gè)mapreduce鏈 用依賴關(guān)系,一共三個(gè)mapreduce,第一個(gè)處理第一個(gè)文件,第二個(gè)處理第二個(gè)文件,第三個(gè)處理前兩個(gè)的輸出結(jié)果,第一個(gè)mapreduce將文件去重,第二個(gè)mapreduce也將文件去重,第三個(gè)做wordcount,wordcount為1的結(jié)果就是不同的
4. 共同朋友
思路:例如A,他的朋友是B\C\D\E\F\,那么BC的共同朋友就是A。所以將BC作為key,將A作為value,在map端輸出即可!其他的朋友循環(huán)處理。
import java.io.IOException; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.Mapper.Context; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.GenericOptionsParser; public class FindFriend { public static class ChangeMapper extends Mapper<Object, Text, Text, Text>{ @Override public void map(Object key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); Text owner = new Text(); Set<String> set = new TreeSet<String>(); owner.set(itr.nextToken()); while (itr.hasMoreTokens()) { set.add(itr.nextToken()); } String[] friends = new String[set.size()]; friends = set.toArray(friends); for(int i=0;i<friends.length;i++){ for(int j=i+1;j<friends.length;j++){ String outputkey = friends[i]+friends[j]; context.write(new Text(outputkey),owner); } } } } public static class FindReducer extends Reducer<Text,Text,Text,Text> { public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { String commonfriends =""; for (Text val : values) { if(commonfriends == ""){ commonfriends = val.toString(); }else{ commonfriends = commonfriends+":"+val.toString(); } } context.write(key, new Text(commonfriends)); } } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { Configuration conf = new Configuration(); String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); if (otherArgs.length < 2) { System.err.println("args error"); System.exit(2); } Job job = new Job(conf, "word count"); job.setJarByClass(FindFriend.class); job.setMapperClass(ChangeMapper.class); job.setCombinerClass(FindReducer.class); job.setReducerClass(FindReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); for (int i = 0; i < otherArgs.length - 1; ++i) { FileInputFormat.addInputPath(job, new Path(otherArgs[i])); } FileOutputFormat.setOutputPath(job, new Path(otherArgs[otherArgs.length - 1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
結(jié)果:
1. AB E:C:D 2. AC E:B 3. AD B:E 4. AE C:B:D 5. BC A:E 6. BD A:E 7. BE C:D:A 8. BF A 9. CD E:A:B 10. CE A:B 11. CF A 12. DE B:A 13. DF A 14. EF A |
5. 基站逗留時(shí)間
需求:
期望:
思路:
將數(shù)據(jù)導(dǎo)入hive表中,查詢時(shí),用電話號(hào)碼和時(shí)間排序即可!
6. 腳本替換
腳本:隨意命名為aaa.sh
#!/bin/bash ls $1 | while read line do sed -i 's,\$HADOOP_HOME\$,\/home\/aa,g' $1$line echo $1$line done |
腳本執(zhí)行命令:替換/home/hadoop/test/下的所有文件
./aaa.sh /home/hadoop/test/
7. 一鍵執(zhí)行
腳本:
vi runRemoteCmd.sh
#!/bin/bash $1 ssh -q hadoop@slave1 "$1" ssh -q hadoop@slave2 "$1" |
執(zhí)行命令
./runRemoteCmd.sh "ls -l" |
8. 大數(shù)據(jù)面試匯總
1. 講解一下MapReduce 的一些基本流程
任務(wù)提交流程,任務(wù)運(yùn)行流程
2. 你們數(shù)據(jù)庫怎么導(dǎo)入hive 的,有沒有出現(xiàn)問題
使用sqoop導(dǎo)入,我們公司的數(shù)據(jù)庫中設(shè)計(jì)了text字段,導(dǎo)致導(dǎo)入的時(shí)候出現(xiàn)了緩存不夠的情況(見云筆記),開始解決起來感覺很棘手,后來查看了sqoop的文檔,加上了limit屬性,解決了。
3. 公司技術(shù)選型可能利用storm 進(jìn)行實(shí)時(shí)計(jì)算,講解一下storm
從storm的應(yīng)用,代碼書寫,運(yùn)行機(jī)制講
4. 問你java 集合類的數(shù)據(jù)結(jié)構(gòu),比如hashmap
看java面試寶典
5. 問你知不知道concurrent 包下的東西,例如concurrenthashmap
看java面試寶典
6. 公司最近主要在自然語言學(xué)習(xí)去開發(fā),有沒有接觸過
沒有用過
9. 面試問題:
1. 從前到后從你教育背景(學(xué)過哪些課)到各個(gè)項(xiàng)目你負(fù)責(zé)的模塊,問的很細(xì)(本以為他是物理學(xué)博士,但是所有的技術(shù)都懂)
2. hadoop 的 namenode 宕機(jī),怎么解決
先分析宕機(jī)后的損失,宕機(jī)后直接導(dǎo)致client無法訪問,內(nèi)存中的元數(shù)據(jù)丟失,但是硬盤中的元數(shù)據(jù)應(yīng)該還存在,如果只是節(jié)點(diǎn)掛了,重啟即可,如果是機(jī)器掛了,重啟機(jī)器后看節(jié)點(diǎn)是否能重啟,不能重啟就要找到原因修復(fù)了。但是最終的解決方案應(yīng)該是在設(shè)計(jì)集群的初期就考慮到這個(gè)問題,做namenode的HA。
3. 一個(gè)datanode 宕機(jī),怎么一個(gè)流程恢復(fù)
Datanode宕機(jī)了后,如果是短暫的宕機(jī),可以實(shí)現(xiàn)寫好腳本監(jiān)控,將它啟動(dòng)起來。如果是長(zhǎng)時(shí)間宕機(jī)了,那么datanode上的數(shù)據(jù)應(yīng)該已經(jīng)被備份到其他機(jī)器了,那這臺(tái)datanode就是一臺(tái)新的datanode了,刪除他的所有數(shù)據(jù)文件和狀態(tài)文件,重新啟動(dòng)。
4. Hbase 的特性,以及你怎么去設(shè)計(jì) rowkey 和 columnFamily ,怎么去建一個(gè)table
因?yàn)閔base是列式數(shù)據(jù)庫,列非表schema的一部分,所以在設(shè)計(jì)初期只需要考慮rowkey 和 columnFamily即可,rowkey有位置相關(guān)性,所以如果數(shù)據(jù)是練習(xí)查詢的,最好對(duì)同類數(shù)據(jù)加一個(gè)前綴,而每個(gè)columnFamily實(shí)際上在底層是一個(gè)文件,那么文件越小,查詢?cè)娇?,所以講經(jīng)常一起查詢的列設(shè)計(jì)到一個(gè)列簇,但是列簇不宜過多。
5. Redis,傳統(tǒng)數(shù)據(jù)庫,hbase,hive 每個(gè)之間的區(qū)別(問的非常細(xì))
Redis是緩存,圍繞著內(nèi)存和緩存說
Hbase是列式數(shù)據(jù)庫,存在hdfs上,圍繞著數(shù)據(jù)量來說
Hive是數(shù)據(jù)倉庫,是用來分析數(shù)據(jù)的,不是增刪改查數(shù)據(jù)的。
6. 公司之后傾向用spark 開發(fā),你會(huì)么(就用java代碼去寫)
會(huì),spark使用scala開發(fā)的,在scala中可以隨意使用jdk的類庫,可以用java開發(fā),但是最好用原生的scala開發(fā),兼容性好,scala更靈活。
10. 面試問題:
1. 筆試: java基礎(chǔ)(基本全忘,做的很爛,復(fù)習(xí)大數(shù)據(jù)連單例都忘了怎么寫)
復(fù)習(xí)java面試寶典
2. 開始介紹項(xiàng)目,直接用大數(shù)據(jù)項(xiàng)目介紹,項(xiàng)目經(jīng)理也懂大數(shù)據(jù)
3. Mapreduce 一些流程,經(jīng)過哪些步驟
Map—combiner—partition—sort—copy—sort—grouping—reduce
4. 說下對(duì)hadoop 的一些理解,包括哪些組件
詳談hadoop的應(yīng)用,包括的組件分為三類,分別說明hdfs,yarn,mapreduce
5. 詳細(xì)講解下你流式實(shí)時(shí)計(jì)算的項(xiàng)目部署以及收集的結(jié)果情況
講解storm集群的部署方案,項(xiàng)目的大小,使用的worker數(shù),數(shù)據(jù)收集在hbase或者h(yuǎn)dfs,好處是什么
6. 你的數(shù)據(jù)庫是不是很大么,有沒有分表,分區(qū),你是怎么實(shí)現(xiàn)的
數(shù)據(jù)庫的分表在設(shè)計(jì)初期是按照月份進(jìn)行拆分的,不同的月份查詢不同的表。分區(qū)沒弄過。
7. 開始問java的一些東西(從各種框架原理到各種復(fù)雜SQL)
8. 多線程,并發(fā),垃圾回收機(jī)制,數(shù)據(jù)結(jié)構(gòu)(問這些,基本覺得看你是不是高級(jí)程序員了)
多線程要知道操作方式,線程安全的鎖,并且要知道lock鎖
垃圾回收機(jī)制需要詳細(xì)了解(見云筆記),主要從內(nèi)存劃分,垃圾回收主要的工作區(qū)域,垃圾回收器的種類,各有什么優(yōu)缺點(diǎn),用在哪里合適。
數(shù)據(jù)結(jié)構(gòu)基本的要知道,復(fù)雜的參考相關(guān)的書籍。
11. 面試問題:
1. BI小組的3個(gè)年輕學(xué)生一起技術(shù)面試(一個(gè)是南開博士
2. 數(shù)據(jù)量多少,集群規(guī)模多大,型號(hào)
一般中型的電商或者互聯(lián)網(wǎng)企業(yè),日志量每天在200-500M左右,集群規(guī)模在30-50臺(tái)左右,機(jī)器一般為dell的2000左右的服務(wù)器,型號(hào)不定
大型的互聯(lián)網(wǎng)公司據(jù)網(wǎng)上資料顯示,日志量在GP-PB不等,集群規(guī)模在500-4000不等,甚至更多,機(jī)器型號(hào)不確定。
3. 項(xiàng)目,mapreduce
介紹整個(gè)mapreduce項(xiàng)目流程,數(shù)據(jù)采集—數(shù)據(jù)聚合—數(shù)據(jù)分析—數(shù)據(jù)展示等
4. 實(shí)時(shí)流式計(jì)算框架,幾個(gè)人,多長(zhǎng)時(shí)間,細(xì)節(jié)問題,包括講flume ,kafka ,storm 的各個(gè)的組件組成,你負(fù)責(zé)那一塊,如果需要你搭建你可以完成么?
5. 你覺得spark 可以完全替代hadoop 么?
12. 面試問題:
1. 一些傳統(tǒng)的hadoop 問題,mapreduce 他就問shuffle 階段,你怎么理解的
Shuffle意義在于將不同map處理后的數(shù)據(jù)進(jìn)行合理分配,讓reduce處理,從而產(chǎn)生了排序、分區(qū)。
2. Mapreduce 的 map 數(shù)量 和 reduce 數(shù)量 怎么確定 ,怎么配置
Map無法配置,reduce隨便配置
3. 唯一難住我的是他說實(shí)時(shí)計(jì)算,storm 如果碰上了復(fù)雜邏輯,需要算很長(zhǎng)的時(shí)間,你怎么去優(yōu)化
拆分復(fù)雜的業(yè)務(wù)到多個(gè)bolt中,這樣可以利用bolt的tree將速度提升
4. Hive 你們用的是外部表還是內(nèi)部表,有沒有寫過UDF(當(dāng)然吹自己寫過了),hive 的版本
外部表,udf,udaf等,hive版本為1.0
5. Hadoop 的版本
如果是1.0版本就說1.2,如果是2.0版本,就說2.6或者2.7
1.2為官方穩(wěn)定版本,2.7為官方穩(wěn)定版本。
Apache Hadoop 2.7.1于美國(guó)時(shí)間2015年07月06日正式發(fā)布,本版本屬于穩(wěn)定版本,是自Hadoop 2.6.0以來又一個(gè)穩(wěn)定版,同時(shí)也是Hadoop 2.7.x版本線的第一個(gè)穩(wěn)定版本,也是 2.7版本線的維護(hù)版本,變化不大,主要是修復(fù)了一些比較嚴(yán)重的Bug
6. 實(shí)時(shí)流式計(jì)算的結(jié)果內(nèi)容有哪些,你們需要統(tǒng)計(jì)出來么(我就說highchart展示)
簡(jiǎn)單介紹日志監(jiān)控、風(fēng)控等結(jié)果內(nèi)容,統(tǒng)計(jì)出來顯示在報(bào)表或者郵件中。
7. 開始問java相關(guān),包括luecne,solr(倒排索引的原理),框架呀,redis呀
13. 京東商城 - 大數(shù)據(jù)
(1)Java篇
1、JVM,GC(算法,新生代,老年代),JVM結(jié)構(gòu)
2、hashcode,hashMap,list,hashSet,equals(結(jié)構(gòu)原理),A extends B(類的加載順序)
1.父類靜態(tài)代碼塊;
2.子類靜態(tài)代碼塊;
3.父類非靜態(tài)代碼塊;
4.父類構(gòu)造函數(shù);
5.子類非靜態(tài)代碼塊;
6.子類構(gòu)造函數(shù);
3、多線程,主線程,次線程,喚醒,睡眠
略
4、常見算法:冒泡算法,排序算法,二分查找,時(shí)間復(fù)雜度
略
(2)Flume篇
1、數(shù)據(jù)怎么采集到Kafka,實(shí)現(xiàn)方式
使用官方提供的flumeKafka插件,插件的實(shí)現(xiàn)方式是自定義了flume的sink,將數(shù)據(jù)從channle中取出,通過kafka的producer寫入到kafka中,可以自定義分區(qū)等。
2、flume管道內(nèi)存,flume宕機(jī)了數(shù)據(jù)丟失怎么解決
1、Flume的channel分為很多種,可以將數(shù)據(jù)寫入到文件
2、防止非首個(gè)agent宕機(jī)的方法數(shù)可以做集群或者主備
3、flume配置方式,flume集群(問的很詳細(xì))
Flume的配置圍繞著source、channel、sink敘述,flume的集群是做在agent上的,而非機(jī)器上。
4、flume不采集Nginx日志,通過Logger4j采集日志,優(yōu)缺點(diǎn)是什么?
優(yōu)點(diǎn):Nginx的日志格式是固定的,但是缺少sessionid,通過logger4j采集的日志是帶有sessionid的,而session可以通過redis共享,保證了集群日志中的同一session落到不同的tomcat時(shí),sessionId還是一樣的,而且logger4j的方式比較穩(wěn)定,不會(huì)宕機(jī)。
缺點(diǎn):不夠靈活,logger4j的方式和項(xiàng)目結(jié)合過于緊密,而flume的方式比較靈活,拔插式比較好,不會(huì)影響項(xiàng)目性能。
5、flume和kafka采集日志區(qū)別,采集日志時(shí)中間停了,怎么記錄之前的日志。
Flume采集日志是通過流的方式直接將日志收集到存儲(chǔ)層,而kafka試講日志緩存在kafka集群,待后期可以采集到存儲(chǔ)層。
Flume采集中間停了,可以采用文件的方式記錄之前的日志,而kafka是采用offset的方式記錄之前的日志。
(3)Kafka篇
1、容錯(cuò)機(jī)制
分區(qū)備份,存在主備partition
2、同一topic不同partition分區(qū)
????
3、kafka數(shù)據(jù)流向
Producer à leader partition à follower partition(半數(shù)以上) àconsumer
4、kafka+spark-streaming結(jié)合丟數(shù)據(jù)怎么解決?
5、kafka中存儲(chǔ)目錄data/dir.....topic1和topic2怎么存儲(chǔ)的,存儲(chǔ)結(jié)構(gòu),data.....目錄下有多少個(gè)分區(qū),每個(gè)分區(qū)的存儲(chǔ)格式是什么樣的?
1、topic是按照“主題名-分區(qū)”存儲(chǔ)的
2、分區(qū)個(gè)數(shù)由配置文件決定
3、每個(gè)分區(qū)下最重要的兩個(gè)文件是0000000000.log和000000.index,0000000.log以默認(rèn)1G大小回滾。
(4)Hive篇
1、hive partition分區(qū)
分區(qū)表,動(dòng)態(tài)分區(qū)
2、insert into 和 override write區(qū)別?
insert into:將某一張表中的數(shù)據(jù)寫到另一張表中
override write:覆蓋之前的內(nèi)容。
3、假如一個(gè)分區(qū)的數(shù)據(jù)主部錯(cuò)誤怎么通過hivesql刪除hdfs
alter table ptable drop partition (daytime='20140911',city='bj');
元數(shù)據(jù),數(shù)據(jù)文件都刪除,但目錄daytime= 20140911還在
(5)Storm篇
1、開發(fā)流程,容錯(cuò)機(jī)制
開發(fā)流程:
1、 寫主類(設(shè)計(jì)spout和bolt的分發(fā)機(jī)制)
2、 寫spout收集數(shù)據(jù)
3、 寫bolt處理數(shù)據(jù),根據(jù)數(shù)據(jù)量和業(yè)務(wù)的復(fù)雜程度,設(shè)計(jì)并行度。
容錯(cuò)機(jī)制:采用ack和fail進(jìn)行容錯(cuò),失敗的數(shù)據(jù)重新發(fā)送。
2、storm和spark-streaming:為什么用storm不同spark-streaming
3、mr和spark區(qū)別,怎么理解spark-rdd
Mr是文件方式的分布式計(jì)算框架,是將中間結(jié)果和最終結(jié)果記錄在文件中,map和reduce的數(shù)據(jù)分發(fā)也是在文件中。
spark是內(nèi)存迭代式的計(jì)算框架,計(jì)算的中間結(jié)果可以緩存內(nèi)存,也可以緩存硬盤,但是不是每一步計(jì)算都需要緩存的。
Spark-rdd是一個(gè)數(shù)據(jù)的分區(qū)記錄集合………………
4、sqoop命令
sqoop import --connect jdbc:mysql://192.168.56.204:3306/sqoop --username hive --password hive --table jobinfo --target-dir /sqoop/test7 --inline-lob-limit 16777216 --fields-terminated-by '\t' -m 2 |
sqoop create-hive-table --connect jdbc:mysql://192.168.56.204:3306/sqoop --table jobinfo --username hive --password hive --hive-table sqtest --fields-terminated-by "\t" --lines-terminated-by "\n"; |
(6)Redis篇
1、基本操作,存儲(chǔ)格式
略
(7)Mysql篇
1、mysql集群的分布式事務(wù)
京東自主開發(fā)分布式MYSQL集群系統(tǒng)
2、mysql性能優(yōu)化(數(shù)據(jù)方面)
數(shù)據(jù)的分表、分庫、分區(qū)
(6)Hadoop篇
1、hadoop HA 兩個(gè)namenode和zk之間的通信,zk的選舉機(jī)制?
HA是通過先后獲取zk的鎖決定誰是主
Zk的選舉機(jī)制,涉及到全新機(jī)群的選主和數(shù)據(jù)恢復(fù)的選主
2、mr運(yùn)行機(jī)制
3、yarn流程
1) 用戶向YARN 中提交應(yīng)用程序, 其中包括ApplicationMaster 程序、啟動(dòng)ApplicationMaster 的命令、用戶程序等。
2) ResourceManager 為該應(yīng)用程序分配第一個(gè)Container, 并與對(duì)應(yīng)的NodeManager 通信,要求它在這個(gè)Container 中啟動(dòng)應(yīng)用程序的ApplicationMaster。
3) ApplicationMaster 首先向ResourceManager 注冊(cè), 這樣用戶可以直接通過ResourceManage 查看應(yīng)用程序的運(yùn)行狀態(tài),然后它將為各個(gè)任務(wù)申請(qǐng)資源,并監(jiān)控它的運(yùn)行狀態(tài),直到運(yùn)行結(jié)束,即重復(fù)步驟4~7。
4) ApplicationMaster 采用輪詢的方式通過RPC 協(xié)議向ResourceManager 申請(qǐng)和領(lǐng)取資源。
5) 一旦ApplicationMaster 申請(qǐng)到資源后,便與對(duì)應(yīng)的NodeManager 通信,要求它啟動(dòng)任務(wù)。
6) NodeManager 為任務(wù)設(shè)置好運(yùn)行環(huán)境(包括環(huán)境變量、JAR 包、二進(jìn)制程序等)后,將任務(wù)啟動(dòng)命令寫到一個(gè)腳本中,并通過運(yùn)行該腳本啟動(dòng)任務(wù)。
7) 各個(gè)任務(wù)通過某個(gè)RPC 協(xié)議向ApplicationMaster 匯報(bào)自己的狀態(tài)和進(jìn)度,以讓ApplicationMaster 隨時(shí)掌握各個(gè)任務(wù)的運(yùn)行狀態(tài),從而可以在任務(wù)失敗時(shí)重新啟動(dòng)任務(wù)。在應(yīng)用程序運(yùn)行過程中,用戶可隨時(shí)通過RPC 向ApplicationMaster 查詢應(yīng)用程序的當(dāng)前運(yùn)行狀態(tài)。
8) 應(yīng)用程序運(yùn)行完成后,ApplicationMaster 向ResourceManager 注銷并關(guān)閉自己。
(7)Hbase
1、涉及到概念,文檔
(8)Spark篇
1、spark原理
Spark應(yīng)用轉(zhuǎn)換流程
1、 spark應(yīng)用提交后,經(jīng)歷了一系列的轉(zhuǎn)換,最后成為task在每個(gè)節(jié)點(diǎn)上執(zhí)行 2、 RDD的Action算子觸發(fā)Job的提交,生成RDD DAG 3、 由DAGScheduler將RDD DAG轉(zhuǎn)化為Stage DAG,每個(gè)Stage中產(chǎn)生相應(yīng)的Task集合 4、 TaskScheduler將任務(wù)分發(fā)到Executor執(zhí)行 5、 每個(gè)任務(wù)對(duì)應(yīng)相應(yīng)的一個(gè)數(shù)據(jù)塊,只用用戶定義的函數(shù)處理數(shù)據(jù)塊 |
Driver運(yùn)行在Worker上
通過org.apache.spark.deploy.Client類執(zhí)行作業(yè),作業(yè)運(yùn)行命令如下:
作業(yè)執(zhí)行流程描述: 1、客戶端提交作業(yè)給Master 2、Master讓一個(gè)Worker啟動(dòng)Driver,即SchedulerBackend。Worker創(chuàng)建一個(gè)DriverRunner線程,DriverRunner啟動(dòng)SchedulerBackend進(jìn)程。 3、另外Master還會(huì)讓其余Worker啟動(dòng)Exeuctor,即ExecutorBackend。Worker創(chuàng)建一個(gè)ExecutorRunner線程,ExecutorRunner會(huì)啟動(dòng)ExecutorBackend進(jìn)程。 4、ExecutorBackend啟動(dòng)后會(huì)向Driver的SchedulerBackend注冊(cè)。SchedulerBackend進(jìn)程中包含DAGScheduler,它會(huì)根據(jù)用戶程序,生成執(zhí)行計(jì)劃,并調(diào)度執(zhí)行。對(duì)于每個(gè)stage的task,都會(huì)被存放到TaskScheduler中,ExecutorBackend向SchedulerBackend匯報(bào)的時(shí)候把TaskScheduler中的task調(diào)度到ExecutorBackend執(zhí)行。 5、所有stage都完成后作業(yè)結(jié)束。
|
Driver運(yùn)行在客戶端 作業(yè)執(zhí)行流程描述: 1、客戶端啟動(dòng)后直接運(yùn)行用戶程序,啟動(dòng)Driver相關(guān)的工作:DAGScheduler和BlockManagerMaster等。 2、客戶端的Driver向Master注冊(cè)。 3、Master還會(huì)讓W(xué)orker啟動(dòng)Exeuctor。Worker創(chuàng)建一個(gè)ExecutorRunner線程,ExecutorRunner會(huì)啟動(dòng)ExecutorBackend進(jìn)程。 4、ExecutorBackend啟動(dòng)后會(huì)向Driver的SchedulerBackend注冊(cè)。Driver的DAGScheduler解析作業(yè)并生成相應(yīng)的Stage,每個(gè)Stage包含的Task通過TaskScheduler分配給Executor執(zhí)行。 5、所有stage都完成后作業(yè)結(jié)束。 |
相關(guān)文章
大數(shù)據(jù)基礎(chǔ)面試題考點(diǎn)與知識(shí)點(diǎn)整理
這篇文章主要介紹了大數(shù)據(jù)基礎(chǔ)面試題考點(diǎn)與知識(shí)點(diǎn),總結(jié)整理了大數(shù)據(jù)常見的各種知識(shí)點(diǎn)、難點(diǎn)、考點(diǎn)以及相關(guān)注意事項(xiàng),需要的朋友可以參考下2019-09-09BAT面試中的大數(shù)據(jù)相關(guān)問題筆記
這篇文章主要介紹了BAT面試中的大數(shù)據(jù)相關(guān)問題,涉及大數(shù)據(jù)相關(guān)的概念、原理、知識(shí)點(diǎn)與算法等問題,需要的朋友可以參考下2019-08-30BAT大數(shù)據(jù)面試題與參考答案小結(jié)
這篇文章主要介紹了BAT大數(shù)據(jù)面試題與參考答案,總結(jié)分析了大數(shù)據(jù)常見的各種知識(shí)點(diǎn)、疑難問題與參考答案,需要的朋友可以參考下2019-08-16- 這篇文章主要介紹了新浪面試php筆試題與參考答案,結(jié)合具體實(shí)例形式分析了php面試中正則、函數(shù)、目錄、文件等知識(shí)點(diǎn)及操作技巧,需要的朋友可以參考下2019-09-12
- 這篇文章主要介紹了華為筆試算法面試題與參考答案,結(jié)合實(shí)例形式分析了基于C++的字符串轉(zhuǎn)換、判斷、排序等算法相關(guān)操作技巧,需要的朋友可以參考下2019-09-05
- 這篇文章主要介紹了阿里常用Java并發(fā)編程面試試題,總結(jié)分析了java并發(fā)編程的概念、原理、常見操作與相關(guān)注意事項(xiàng),需要的朋友可以參考下2019-09-04
- 這篇文章主要介紹了兩道阿里python面試題與參考答案,結(jié)合具體實(shí)例形式分析了Python數(shù)組創(chuàng)建、遍歷、拆分及隨機(jī)數(shù)等相關(guān)操作技巧,需要的朋友可以參考下2019-09-02
- 這篇文章主要介紹了銀行java開發(fā)筆試面試題13道,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-08-27
騰訊前端面試題相關(guān)知識(shí)點(diǎn)集錦
這篇文章主要介紹了騰訊前端面試題相關(guān)知識(shí)點(diǎn),整理總結(jié)了騰訊前端面試中所涉及的相關(guān)基礎(chǔ)知識(shí)點(diǎn)與疑難問題,需要的朋友可以參考下2019-08-27- 這篇文章主要介紹了華為16道經(jīng)典面試題與參考思路,總結(jié)分析了華為面試中遇到的經(jīng)典問題,并提供了相應(yīng)的解答思路供讀者參考,需要的朋友可以參考下2019-08-01