關於Spark的面試題,你應該知道這些!

        以前分享過一篇博客,????不會這20個Spark熱門技術點,你敢出去面試大數據嗎?,那一篇確實是很是精華,提煉出了很是重要一樣很是高頻的Spark技術點,也算是收到了一些朋友們的好評。本篇博客,博主打算再出個番外篇,也就是再爲你們分享一些Spark面試題,敢問各位準備好了麼~javascript

在這裏插入圖片描述


一、Spark Application在沒有得到足夠的資源,job就開始執行了,可能會致使什麼問題發生?

        執行該job時候集羣資源不足,致使執行job結束也沒有分配足夠的資源,分配了部分Executor,該job就開始執行task,應該是task的調度線程和Executor資源申請是異步的;若是想等待申請完全部的資源再執行job的:須要將spark.scheduler.maxRegisteredResourcesWaitingTime設置的很大;spark.scheduler.minRegisteredResourcesRatio 設置爲1,可是應該結合實際考慮,不然很容易出現長時間分配不到資源,job一直不能運行的狀況。java

二、driver的功能是什麼?

  • 一個Spark做業運行時包括一個Driver進程,也是做業的主進程,具備main函數,而且有SparkContext的實例,是程序的人口點;
  • 功能:負責向集羣申請資源向master註冊信息,負責了做業的調度,負責做業的解析、生成Stage並調度Task到Executor上。包括DAGScheduler,TaskScheduler

三、Spark中Work的主要工做是什麼?

        主要功能:管理當前節點內存,CPU的使用情況,接收master分配過來的資源指令,經過ExecutorRunner啓動程序分配任務。node

        worker就相似於包工頭,管理分配新進程,作計算的服務,至關於process服務。面試

        須要注意的是:sql

        1)worker會不會彙報當前信息給master?worker心跳給master主要只有workid,它不會發送資源信息以心跳的方式給master,master分配的時候就知道work,只有出現故障的時候纔會發送資源。express

        2)worker不會運行代碼,具體運行的是Executor是能夠運行具體appliaction寫的業務邏輯代碼,操做代碼的節點,它不會運行程序的代碼的。apache

四、Spark爲何比mapreduce快?

  1. spark是基於內存進行數據處理的,MapReduce是基於磁盤進行數據處理的
  2. spark中具備DAG有向無環圖,DAG有向無環圖在此過程當中減小了shuffle以及落地磁盤的次數
  3. spark是粗粒度資源申請,也就是當提交spark application的時候,application會將全部的資源申請完畢,若是申請不到資源就等待,若是申請到資源才執行application,task在執行的時候就不須要本身去申請資源,task執行快,當最後一個task執行完以後task纔會被釋放。而MapReduce是細粒度資源申請,當提交application的時候,task執行時,本身申請資源,本身釋放資源,task執行完畢以後,資源當即會被釋放,task執行的慢,application執行的相對比較慢。

五、Mapreduce和Spark的都是並行計算,那麼他們有什麼相同和區別?

  • hadoop的一個做業稱爲job,job裏面分爲map task和reduce task,每一個task都是在本身的進程中運行的,當task結束時,進程也會結束。
  • spark用戶提交的任務成爲application,一個application對應一個sparkcontext,app中存在多個job,每觸發一次action操做就會產生一個job。這些job能夠並行或串行執行,每一個job中有多個stage,stage是shuffle過程當中DAGSchaduler經過RDD之間的依賴關係劃分job而來的,每一個stage裏面有多個task,組成taskset有TaskSchaduler分發到各個executor中執行,executor的生命週期是和app同樣的,即便沒有job運行也是存在的,因此task能夠快速啓動讀取內存進行計算。
  • hadoop的job只有map和reduce操做,表達能力比較欠缺並且在mr過程當中會重複的讀寫hdfs,形成大量的io操做,多個job須要本身管理關係。 而spark的迭代計算都是在內存中進行的,API中提供了大量的RDD操做如join,groupby等,並且經過DAG圖能夠實現良好的容錯

六、Spark應用程序的執行過程是什麼?

  1. 構建Spark Application的運行環境(啓動SparkContext),SparkContext向資源管理器(能夠是Standalone、Mesos或YARN)註冊並申請運行Executor資源;
  2. 資源管理器分配Executor資源並啓動StandaloneExecutorBackend,Executor運行狀況將隨着心跳發送到資源管理器上;
  3. SparkContext構建成DAG圖,將DAG圖分解成Stage,並把Taskset發送給Task Scheduler。Executor向SparkContext申請Task,Task Scheduler將Task發放給Executor運行同時SparkContext將應用程序代碼發放給Executor。
  4. Task在Executor上運行,運行完畢釋放全部資源。

七、spark on yarn Cluster 模式下,ApplicationMaster和driver是在同一個進程麼?

        是,driver 位於ApplicationMaster進程中。該進程負責申請資源,還負責監控程序、資源的動態狀況。編程

八、Spark on Yarn 模式有哪些優勢?

  1. 與其餘計算框架共享集羣資源(eg.Spark框架與MapReduce框架同時運行,若是不用Yarn進行資源分配,MapReduce分到的內存資源會不多,效率低下);資源按需分配,進而提升集羣資源利用等。
  2. 相較於Spark自帶的Standalone模式,Yarn的資源分配更加細緻
  3. Application部署簡化,例如Spark,Storm等多種框架的應用由客戶端提交後,由Yarn負責資源的管理和調度,利用Container做爲資源隔離的單位,以它爲單位去使用內存,cpu等。
  4. Yarn經過隊列的方式,管理同時運行在Yarn集羣中的多個服務,可根據不一樣類型的應用程序負載狀況,調整對應的資源使用量,實現資源彈性管理。

九、spark中的RDD是什麼,有哪些特性?

        RDD(Resilient Distributed Dataset)叫作分佈式數據集,是spark中最基本的數據抽象,它表明一個不可變,可分區,裏面的元素能夠並行計算的集合。json

        五大特性:緩存

  • A list of partitions:一個分區列表,RDD中的數據都存儲在一個分區列表中
  • A function for computing each split:做用在每個分區中的函數
  • A list of dependencies on other RDDs:一個RDD依賴於其餘多個RDD,這個點很重要,RDD的容錯機制就是依據這個特性而來的
  • Optionally,a Partitioner for key-value RDDs(eg:to say that the RDD is hash-partitioned):可選的,針對於kv類型的RDD纔有這個特性,做用是決定了數據的來源以及數據處理後的去向
  • 可選項,數據本地性,數據位置最優

十、spark如何防止內存溢出?

        driver端的內存溢出 :

        能夠增大driver的內存參數:spark.driver.memory (default 1g)

        map過程產生大量對象致使內存溢出:

        具體作法能夠在會產生大量對象的map操做以前調用repartition方法,分區成更小的塊傳入map。

        數據不平衡致使內存溢出:

        數據不平衡除了有可能致使內存溢出外,也有可能致使性能的問題,解決方法和上面說的相似,就是調用repartition從新分區。

        shuffle後內存溢出:

        shuffle內存溢出的狀況能夠說都是shuffle後,單個文件過大致使的。在Spark中,join,reduceByKey這一類型的過程,都會有shuffle的過程,在shuffle的使用,須要傳入一個partitioner,大部分Spark中的shuffle操做,默認的partitioner都是HashPatitioner,默認值是父RDD中最大的分區數,這個參數經過spark.default.parallelism控制(在spark-sql中用spark.sql.shuffle.partitions) , spark.default.parallelism參數只對HashPartitioner有效,因此若是是別的Partitioner或者本身實現的Partitioner就不能使用spark.default.parallelism這個參數來控制shuffle的併發量了。若是是別的partitioner致使的shuffle內存溢出,就須要從partitioner的代碼增長partitions的數量。

        standalone模式下資源分配不均勻致使內存溢出:

        這種狀況的解決方法就是同時配置–executor-cores或者spark.executor.cores參數,確保Executor資源分配均勻。使用rdd.persist(StorageLevel.MEMORY_AND_DISK_SER)代替rdd.cache()。

rdd.cache()和rdd.persist(Storage.MEMORY_ONLY)是等價的,在內存不足的時候rdd.cache()的數據會丟失,再次使用的時候會重算,而rdd.persist(StorageLevel.MEMORY_AND_DISK_SER)在內存不足的時候會存儲在磁盤,避免重算,只是消耗點IO時間

十一、spark中cache和persist的區別?

        cache:緩存數據,默認是緩存在內存中,其本質仍是調用persist。

        persist:緩存數據,有豐富的數據緩存策略。數據能夠保存在內存也能夠保存在磁盤中,使用的時候指定對應的緩存級別就能夠了。

十二、Spark手寫WordCount程序

        這個常出如今筆試階段,手寫WordCount算是一項基本技能。

//建立SparkConf並設置App名稱和master地址
val conf=new SparkConf().setAppName(「wc」).setMaster(「Local[*])
//建立SparkContext,該對象是提交Spark App的入口
val sc=new SparkContext(conf)
//使用sc建立RDD並執行相應的transformation和action
val result=sc.textFile(「輸入文件的路徑」)
Val rdd2=result.flatmap(x=>x.split(「 」))
.map((_,1)).reduceBykey((_+_)).saveAsTextFile(「輸出文件路徑」)
//關閉連接
sc.stop()

1三、Spark中建立RDD的方式總結3種

        一、從集合中建立RDD;

val rdd = sc.parallelize(Array(1,2,3,4,5,6,7,8))
val rdd = sc.makeRDD(Array(1,2,3,4,5,6,7,8))

        二、從外部存儲建立RDD;

val rdd= sc.textFile("hdfs://node01:8020/data/test")

        三、從其餘RDD建立。

val rdd1 = sc.parallelize(Array(1,2,3,4))
val rdd2 =rdd.map(x=>x.map(_*2))

1四、經常使用算子

        這個涉及到的算子就比較多了,感興趣的朋友能夠去看看博主的這兩篇博客:

        Spark之【RDD編程】詳細講解(No2)——《Transformation轉換算子》

        Spark之【RDD編程】詳細講解(No3)——《Action行動算子》

        絕對不會讓你失望的~

1五、什麼是寬窄依賴

        窄依賴指的是每個父RDD的Partition最多被子RDD的一個Partition使用。
        寬依賴指的是多個子RDD的Partition會依賴同一個父RDD的Partition,會引發shuffle。

1六、任務劃分的幾個重要角色

        RDD任務切分中間分爲:Application、Job、Stage和Task

        1)Application:初始化一個SparkContext即生成一個Application;

        2)Job:一個Action算子就會生成一個Job;

        3)Stage:根據RDD之間的依賴關係的不一樣將Job劃分紅不一樣的Stage,遇到一個寬依賴則劃分一個Stage;

        4)Task:Stage是一個TaskSet,將Stage劃分的結果發送到不一樣的Executor執行即爲一個Task

1七、SparkSQL中RDD、DataFrame、DataSet三者的區別與聯繫?

RDD

        彈性分佈式數據集;不可變、可分區、元素能夠並行計算的集合。

優勢:

  • RDD編譯時類型安全:編譯時能檢查出類型錯誤;
  • 面向對象的編程風格:直接經過類名點的方式操做數據。

缺點:

  • 序列化和反序列化的性能開銷很大,大量的網絡傳輸;
  • 構建對象佔用了大量的heap堆內存,致使頻繁的GC(程序進行GC時,全部任務都是暫停)

DataFrame

        DataFrame以RDD爲基礎的分佈式數據集。

優勢:

  • DataFrame帶有元數據schema,每一列都帶有名稱和類型。
  • DataFrame引入了off-heap,構建對象直接使用操做系統的內存,不會致使頻繁GC。
  • DataFrame能夠從不少數據源構建;
  • DataFrame把內部元素當作Row對象,表示一行行的數據
  • DataFrame=RDD+schema

缺點

  • 編譯時類型不安全;
  • 不具備面向對象編程的風格。

Dataset

        DataSet包含了DataFrame的功能,Spark2.0中二者統一,DataFrame表示爲DataSet[Row],即DataSet的子集。

        (1)DataSet能夠在編譯時檢查類型;

        (2)而且是面向對象的編程接口。

        (DataSet 結合了 RDD 和 DataFrame 的優勢,並帶來的一個新的概念 Encoder。當序列化數據時,Encoder 產生字節碼與 off-heap 進行交互,可以達到按需訪問數據的效果,而不用反序列化整個對象。)。

三者之間的轉換:

在這裏插入圖片描述

1八、自定義函數的過程

        1)建立DataFrame

scala> val df = spark.read.json("/export/spark/examples/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

        2)打印數據

scala> df.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|

        3)註冊UDF,功能爲在數據前添加字符串

scala> spark.udf.register("addName", (x:String)=> "Name:"+x)
res5: org.apache.spark.sql.expressions.UserDefinedFunction = UserDefinedFunction(<function1>,StringType,Some(List(StringType)))

        4)建立臨時表

scala> df.createOrReplaceTempView("people")

        5)應用UDF

scala> spark.sql("Select addName(name), age from people").show()
+-----------------+----+
|UDF:addName(name)| age|
+-----------------+----+
|     Name:Michael|null|
|        Name:Andy|  30|
|      Name:Justin|  19|

        本篇博客就分享到這裏,建議全部沒看過開頭提到的《不會這20個Spark熱門技術點,你敢出去面試大數據嗎?》這篇博客的朋友都去閱讀一下,真的牆裂推薦!!!

        若是以上過程當中出現了任何的紕漏錯誤,煩請大佬們指正????

        受益的朋友或對大數據技術感興趣的夥伴記得點贊關注支持一波????

        但願咱們都能在學習的道路上越走越遠????
在這裏插入圖片描述

相關文章
相關標籤/搜索