版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
搭建Spark集群環(huán)境
學完本課程后,您將可以:了解Spark基本架構的概念了解Spark的特點了解Spark常用的開發(fā)環(huán)境能夠完成Spark的安裝與部署能夠對搭建環(huán)境過程中遇到的問題進行分析01認識Spark02搭建Spark集群03Spark運行架構與原理301認識SparkSpark是什么2009年誕生于美國加州大學伯克利的AMP實驗室2013年加入Apache孵化器項目后發(fā)展迅猛2014年正式成為Apache軟件基金會的頂級項目(5月發(fā)布Spark1.0正式版本)Spark是專為大規(guī)模數(shù)據(jù)處理而設計的快速通用的計算引擎2010年正式開放源代碼2018年發(fā)布Spark2.0版本,成為全球最大的開源項目2019年6月發(fā)布Spark3.0版本Spark的誕生因為Hadoop-MapReduce計算引擎太慢2025年9月發(fā)布Spark4.0版本(企業(yè)主流版本為Spark3.x系列)Spark生態(tài)系統(tǒng)
SparkSQL(操作結構化數(shù)據(jù))SparkStreaming(實時計算)MLlib(機器學習)GraphX(分布式圖計算)SparkCore(核心組件)StandaloneYARNMesosSparkCoreSparkCore(核心組件)SparkCore實現(xiàn)
Spark
的基本功能(包含任務調度、內(nèi)存管理、錯誤恢復、與存儲系統(tǒng)交互等模塊)SparkCore包含對彈性分布式數(shù)據(jù)集(ResilientDistributedDatasets,RDD)的API定義(RDD是只讀的分區(qū)記錄的集合,只能基于在穩(wěn)定物理存儲中的數(shù)據(jù)集和其他已有的RDD上執(zhí)行確定性操作來創(chuàng)建)SparkSQLSparkSQL(操作結構化數(shù)據(jù))SparkSQL是用來操作結構化數(shù)據(jù)的核心組件,通過SparkSQL可以直接查詢Hive、HBase等多種外部數(shù)據(jù)源中的數(shù)據(jù)SparkSQL重要特點是能夠統(tǒng)一處理關系表和RDD(在處理結構化數(shù)據(jù)時,開發(fā)人員無須編寫復雜的程序,直接使用SQL命令就能完成更加復雜的數(shù)據(jù)查詢操作)SparkStreamingSparkStreming(實時計算)SparkStreaming是Spark提供的流式計算框架,支持高吞吐量、可容錯處理的實時流式數(shù)據(jù)處理SparkStreaming核心原理是將流數(shù)據(jù)分解成一系列短小的批處理作業(yè),每個短小的批處理作業(yè)都可以使用SparkCore進行快速處理SparkStreaming支持多種數(shù)據(jù)源,如Kafka、Flume以及TCP套接字等SparkMLlibSparkMLlib(機器學習)SparkMLlib提供關于機器學習功能的算法程序庫(包括分類、回歸、聚類、協(xié)同過濾算法等)SparkMLlib還提供模型評估、數(shù)據(jù)導人等額外的功能(開發(fā)人員只需了解一定的機器學習算法知識就能進行機器學習方面的開發(fā),降低了學習成本)SparkGraphXSparkGraphX(分布式圖處理)SparkGraphX提供的分布式圖處理框架,擁有圖計算和圖挖掘算法的API接口以及豐富的功能和運算符(極大地方便了對分布式圖的處理需求,能在海量數(shù)據(jù)上運行復雜的圖算法)Standalone、YARN和MesosSpark框架可以高效地在一個到數(shù)千個節(jié)點之間伸縮計算,集群管理器則主要負責各個節(jié)點的資源管理工作,為了實現(xiàn)這樣的效果,同時獲得最大的靈活性,Spark支持在各種集群管理器(ClusterManager)上運行,HadoopYARN、ApacheMesos以及Spark自帶的獨立調度器StandaloneYARNMesos集群管理器Spark的四大特點通用性Spark提供了完整而強大的技術棧,包括SQL查詢、流式計算、機器學習和圖算法組件,這些組件可以無縫整合在同一個應用中,足以應對復雜的計算3便于使用Spark支持使用Scala、Java、Python和R語言進行編程,簡潔的API設計有助于用戶輕松構建并行程序,并且可以通過SparkShell進行交互式編程2運行速度快Spark使用先進的DAG(DirectedAcyclicGraph,有向無環(huán)圖)執(zhí)行引擎,以支持循環(huán)數(shù)據(jù)流與內(nèi)存計算,基于內(nèi)存的執(zhí)行速度可比HadoopMapReduce快上百倍,基于磁盤的執(zhí)行速度也能快十倍1運行模式多樣Spark可運行于獨立的集群模式中,或者運行于Hadoop中,也可運行于AmazonEC2等云環(huán)境中,并且可以訪問HDFS、Cassandra、HBase、Hive等多種數(shù)據(jù)源4ApacheSpark在絕大多數(shù)數(shù)據(jù)處理場景下都比HadoopMapReduce快得多(通???0到100倍)Spark的應用場景復雜的批量處理場景基于歷史數(shù)據(jù)的交互式查詢場景基于實時數(shù)據(jù)流的數(shù)據(jù)處理場景可以用Hadoop的MapReduce來進行批量海量數(shù)據(jù)處理,偏重點在于處理海量數(shù)據(jù)的能力,至于處理速度可忍受(通常的時間可能是在數(shù)十分鐘到數(shù)小時)可以Impala進行交互式查詢(通常的時間在數(shù)十秒到數(shù)十分鐘之間)可以用Storm分布式處理框架處理實時流式數(shù)據(jù)(通常在數(shù)百毫秒到數(shù)秒之間)Spark應用場景總結特點01特點02特點03數(shù)據(jù)集大,反復操作次數(shù)越多,受益越大,數(shù)據(jù)量小計算密度大的場景,受益相對較小由于RDD的特性Spark不適用于異步細粒度更新狀態(tài)的應用,例如Web服務的存儲或者是增量的Web爬蟲和索引對于那種增量修改的應用模型不適合,如數(shù)據(jù)量不是特別大,但是要求實時統(tǒng)計分析Spark和HadoopMapReduce特點對比SparkHadoopMapReduce場景編程范式存儲方式運行方式流批一體(靜態(tài)、動態(tài)數(shù)據(jù))批處理(靜態(tài)數(shù)據(jù))更簡潔、更高級的API、主要使用Scala、Java、Python和R等編程語言使用MapReduce編程模型,其API相對較低級,開發(fā)者需要編寫更多的代碼來實現(xiàn)相同的功能RDD結果在內(nèi)存(延遲?。㏕ask以線程方式維護(啟動快)中間結果在磁盤(延遲大)Task以進程方式維護(啟動慢)對比項Spark與HadoopMapReduce原理對比在絕大多數(shù)場景下,Spark已經(jīng)取代HadoopMapReduce,成為大數(shù)據(jù)批處理領域的事實標準(多選)Spark適用于以下哪些場景?(
)復雜的批量數(shù)據(jù)處理實時數(shù)據(jù)流處理機器學習分布式圖處理
Spark為何比HadoopMapReduce處理速度快?
描述了Spark的起源和演進講解了Spark生態(tài)系統(tǒng)講解了Spark的四大特點講解了Spark的應用場景講解了Spark和Hadoop對比2002搭建Spark集群安裝準備21虛擬機運行環(huán)境軟硬件環(huán)境要求主機操作系統(tǒng):Windows64位(至少8GB內(nèi)存)虛擬軟件:WMwareWorkstation16(推薦)虛擬機操作系統(tǒng):Linux系統(tǒng)CentOS7JDK:jdk-11.0.29(推薦)Hadoop:Hadoop-3.3.4(Scala2.12)Spark:spark-3.4.0-bin-hadoop3(Scala2.12)Spark的三種分布式部署方式22Standalone模式SparkonMesos模式SparkonYARN模式集群單機模式Mesos提供資源調度服務YARN提供資源調度服務Spark自帶完整的資源調度管理服務,不依賴其他系統(tǒng)來為其提供資源管理調度服務Spark依賴Mesos(一種資源調度管理框架)提供資源調度服務適合企業(yè)生產(chǎn)場景Spark可以運行于YARN上,與Hadoop進行統(tǒng)一部署,資源管理和調度依賴于YARN,分布式存儲依賴于HDFS不同的場景決定采用不同Spark相應的分布式部署方式適合個人學習場景適合企業(yè)/個人場景Spark集群的安裝與部署Master節(jié)點
Slave1節(jié)點
Slave2節(jié)點
313233注:準備三臺虛擬機并完成初始化(Hadoop集群環(huán)境、JDK、免密登錄)MasterWorkerWorker下載Spark安裝包Spark官網(wǎng)下載解壓Spark安裝包#tar-zxvfspark-3.4.0-bin-hadoop3.tgz執(zhí)行tar解壓命令tar命令用于解壓由gzip壓縮的.tar.gz或.tgz格式的歸檔文件參數(shù)z:代表gzip。它告訴tar命令,歸檔文件是使用gzip工具進行壓縮的。因此,在
解壓時,需要先使用gzip算法進行解壓縮參數(shù)x:代表extract(解壓、提取)。這是最核心的操作,指示tar從歸檔文件中提取
文件參數(shù)v:代表verbose(詳細信息)。加上這個參數(shù)后,命令會在執(zhí)行過程中列出正在
提取的每一個文件的名稱參數(shù)f:代表file(文件)。這個參數(shù)必須后面緊跟你要操作的歸檔文件的文件名配置環(huán)境變量#vim/etc/profile使用vim文本編輯器編輯環(huán)境變量export
SPARK_HOME=/data/apps/spark-3.4.0export
PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin添加內(nèi)容如下:#source/etc/profile執(zhí)行source命令使環(huán)境變量生效配置Spark運行環(huán)境#vimworkers修改workers文件(明確master節(jié)點和worker節(jié)點)slave1slave2添加內(nèi)容如下:#vimspark-env.shexportJAVA_HOME=/opt/software/jdk-11.0.29exportHADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoopexportSPARK_MASTER_HOST=masterexportSPARK_MASTER_PORT=7077修改spark-env.sh配置文件(設置JDK、Hadoop配置路徑)分發(fā)Spark目錄#scp-rspark-3.4.0/slave1:/data/apps/spark-3.4.0/#scp-rspark-3.4.0/slave2:/data/apps/spark-3.4.0/執(zhí)行scp分發(fā)目錄命令scp命令用于通過網(wǎng)絡在主機之間安全地傳輸文件參數(shù)r:用于遞歸復制整個目錄及其子目錄下的所有內(nèi)容scp命令是系統(tǒng)管理、開發(fā)和運維工作中不可或缺的工具(簡單、安全、高效)啟動Spark集群(Standalone模式)執(zhí)行Spark啟動腳本start-all.sh#start-all.sh執(zhí)行jps命令查看進程(JVM)#jps2576Jps2472Master#jps2576Jps2472WorkerMaster節(jié)點Worker節(jié)點啟動Spark集群Web管理頁面測試Spark集群#spark-submit--masterspark://master:7077--classorg.apache.spark.examples.SparkPi/data/apps/spark-3.4.0/examples/jars/spark-examples_2.12-3.4.0.jar1000運行SparkPi案例(計算圓周率π)spark-submit是Spark中最重要、最核心的作業(yè)提交命令--master:指定集群的運行主節(jié)點--class:指定Spark應用程序的主類測試Spark集群運行SparkPi案例輸出結果π=3.1418942714189426(多選)以下哪些是
Spark的部署方式?(
)Standalone模式SparkonMesosSparkonYARNSparkonHive
以下運行SparkPi案例中最后的數(shù)字1000代表何意?
#spark-submit--masterspark://master:7077--classorg.apache.spark.examples.SparkPi/data/apps/spark-3.4.0/examples/jars/spark-examples_2.12-3.4.0.jar
1000講解了Spark集群安裝準備講解了Spark集群部署方式講解了Spark集群安裝與部署3603Spark運行架構與原理Spark集群的分布式運行架構37Spark分布式運行架構的核心重點(1)38核心組件與協(xié)調機制Spark應用在集群上運行時,包含多個獨立進程,這些進程之間通過驅動器程序(DriverPrograme)中的SparkContext對象進行協(xié)調SparkContext?是核心協(xié)調器,位于驅動程序內(nèi),負責與集群資源管理器通信和任務調度資源申請與執(zhí)行器Spark通過與集群資源管理器(ClusterManager)通信,為應用在各節(jié)點上申請執(zhí)行器進程執(zhí)行器(Executor)負責運行具體任務和存儲數(shù)據(jù)Spark分布式運行架構的核心重點(2)39應用級隔離模型每個Spark應用擁有專屬的執(zhí)行器進程,在應用生命周期內(nèi)保持運行應用間互不干擾,各自獨立調度任務(優(yōu)勢)執(zhí)行器的高效運行模式執(zhí)行器以多線程方式執(zhí)行任務(任務啟動快,避免了進程級頻繁創(chuàng)建銷毀的開銷,同一應用內(nèi)的任務可共享數(shù)據(jù))應用間無法直接共享內(nèi)存數(shù)據(jù),需借助外部存儲(缺點)Spark分布式運行架構的核心重點(3)40與集群管理器的解耦設計Spark底層與集群管理器無關,只需其能分配執(zhí)行器資源即可Spark具備良好移植性,可運行在多種資源管理器上驅動程序的網(wǎng)絡與部署要求驅動程序必須能被所有工作節(jié)點訪問,以接收執(zhí)行器的連接驅動程序應部署在離工作節(jié)點較近的局域網(wǎng)內(nèi),以保證調度效率。若需遠程訪問,應通過代理方式實現(xiàn)(最佳實踐)Spark運行的基本原理Spark運行的基本流程提交應用
→
啟動Driver→
創(chuàng)建SparkContext→
申請資源
→
初始化DAG/任務調度器Driver申請資源
→ClusterManager調度
→Worker節(jié)點啟動ExecutorExecutor注冊反饋
→ClusterManager監(jiān)控
→
故障后自動重啟Executor會向SparkContext反向注冊申請TaskTaskScheduler將Task發(fā)送給Worker進程中的Executor運行并提供應用程序代碼當程序執(zhí)行完畢后寫入數(shù)據(jù),Driver向ClusterManager注銷申請的資源010203040506(多選)關于Spark運行架構的描述,以下哪些是正確的?(
)Driver程序負責協(xié)調應用程序在集群上的運行每個Spark應用都有其對應的一個執(zhí)行器(Executor)進程執(zhí)行器(Executor)進程在應用程序生命周期內(nèi)保持運行狀態(tài)Driver進程必須能夠被所有Worker節(jié)點訪問到
44Spark分布式運行架構中,執(zhí)行器(Executor)與執(zhí)行器(Executor)之間可以共享數(shù)據(jù)嗎?為什么?講解了Spark運行架構與原理講解了Spark運行的基本原理許斌/0181932025.11.17新開發(fā)使用Scala實現(xiàn)人事管理系統(tǒng)
學完本課程后,您將可以:能夠搭建Scala開發(fā)環(huán)境能夠掌握Scala的基本語法能夠使用Scala實現(xiàn)簡單編程能夠使用Scala開發(fā)完成案例01搭建Scala開發(fā)環(huán)境02學習Scala基本語法03實現(xiàn)人事管理系統(tǒng)5101搭建Scala開發(fā)環(huán)境Scala是什么Scala這一名稱來自“ScalableLanguage”的縮寫,意為“可伸縮的語言”,旨在其可以適應不斷變化的編程需求Scala是一種集面向對象和函數(shù)式編程優(yōu)點于一身的現(xiàn)代多范式編程語言Scala語言由馬丁·奧德斯基(MartinOdersky)和他的團隊在2003年開發(fā)Scala=Java+函數(shù)式編程Scala作為一種運行在Java虛擬機(JVM)上的語言,Scala能夠無縫地利用Java的豐富類庫資源Scala的特點面向對象函數(shù)式編程靜態(tài)類型擴展性兼容性Scala是一種純面向對象的語言,每個值都是對象,包括數(shù)字、函數(shù)和數(shù)組。Scala支持高級的面向對象特性,如類繼承、抽象類、接口(特質Trait)和對象組合Scala同樣支持函數(shù)式編程范式。它提供了不可變數(shù)據(jù)類型,以及將函數(shù)作為一等公民的能力。這意味著函數(shù)可以被作為參數(shù)傳遞,可以作為結果返回,以及可以被賦值給變量盡管Scala是靜態(tài)類型的語言,它的類型系統(tǒng)是非常靈活的,支持泛型、類型推導以及復合類型等。靜態(tài)類型系統(tǒng)在編譯時期就能夠捕捉到很多錯誤,這是動態(tài)類型語言難以比擬的Scala的設計允許以一種非常自然的方式來擴展語言本身。通過隱式轉換和宏,用戶可以在不改變語言語法的情況下,引入新的語言結構由于Scala是運行在JVM上的,它可以非常容易地與Java代碼和庫進行互操作。這為Scala的使用提供了極大的靈活性和強大的生態(tài)系統(tǒng)支持。ScalaScala的這些特點不僅在大數(shù)據(jù)處理領域表現(xiàn)出色,也完美適用于各類通用軟件開發(fā)場景搭建Scala開發(fā)環(huán)境-下載Scala官網(wǎng)下載注意:2.12.x與2.13.x并不兼容,需要獨立升級搭建Scala開發(fā)環(huán)境-安裝Scala搭建Scala開發(fā)環(huán)境-安裝Scala搭建Scala開發(fā)環(huán)境-安裝Scala搭建Scala開發(fā)環(huán)境-校驗Scala安裝是否正確Win+R搭建Scala開發(fā)環(huán)境-校驗Scala安裝是否正確輸入scala命令VSCode運行Scala代碼Scala代碼的4種運行方式運行方式操作步驟適用場景CMD命令行窗口記事本IDE(集成開發(fā)環(huán)境)SBT環(huán)境在命令行工具中輸入“scala”命令以進入Scala交互式環(huán)境,隨后可在此環(huán)境中直接輸入并執(zhí)行代碼段適合快速測試和交互式編程使用文本編輯器新建并編寫Scala代碼,保存為“.scala”文件后,通過執(zhí)行“scalac文件名.scala”進行編譯適用于簡單的代碼編寫和學習練習在VSCode或IDEA等集成開發(fā)環(huán)境中創(chuàng)建Scala項目,編寫代碼后可直接運行。對于需要用戶輸入的情況,只需在運行配置中預先設定即可適合大型項目開發(fā)和代碼調試啟動命令行工具,輸入“sbtconsole”命令進入SBT控制臺,此時可在此環(huán)境中錄入并執(zhí)行所需的Scala代碼段適用于需要構建和管理Scala項目的場合VSCode方式運行Scala-下載VSCode官網(wǎng)下載VSCode方式運行Scala-安裝VSCodeVSCode方式運行Scala-安裝VSCodeVSCode方式運行Scala-安裝VSCode插件安裝官方提供的Scala(Metals)插件,該插件支持語法高亮、代碼補全等功能編寫第一個Scala程序編譯Scala程序執(zhí)行編譯命令:
scalac源文件名.后綴名
注意:Scala源文件編譯后將生成class文件(與Java相同)運行Scala程序執(zhí)行運行命令:
scalaclass文件名
注意:運行scala程序時,不要添加文件后綴名如何編譯和運行Scala程序?
Scala與Java之間有關系嗎?Scala是否可以直接使用Java的SDK庫?
講解了Scala語言簡介講解了Scala語言特點講解了Scala開發(fā)環(huán)境搭建講解了Scala程序運行7102學習Scala基本語法基本語法和結構在Scala中,import語句用于將類、接口、對象或方法從其他包引入到當前代碼文件中包導入在Scala中,可以使用var和val來聲明變量變量聲明函數(shù)定義的基本格式是deffunctionName(parameters):函數(shù)定義Scala中的for循環(huán)非常強大,它可以用作傳統(tǒng)的迭代循環(huán),也可以用于操作集合或序列的元素循環(huán)Scala程序的入口點是定義為main的方法主函數(shù)Scala中的if-else結構與Java非常相似,但Scala提供了更豐富的表達式語法條件語句數(shù)據(jù)類型與操作-類型別名importscala.collection.immutableobjectDataTypesAndOperationsExample{//類型別名typeStudentGrades=immutable.Map[String,Double]...}它提供了一種方式來給復雜的類型命名,以提高代碼的可讀性和易用性類型別名typeStudentGrades=Map[String,Double]定義了一個類型別名StudentGrades,它簡化了Map[String,Double]的表示,使代碼更加清晰數(shù)據(jù)類型與操作-字符串插值defmain(args:Array[String]):Unit={//字符串插值valschoolName="Scala高中"println(s"歡迎來到$schoolName!")}通過字符串插值可以方便地構造字符串,允許在字符串文字中嵌入表達式的值字符串插值s插值器(s"..."):用于簡單的情形,其中字符串文字中的表達式被替換為它們的字符串表示形式Scala提供兩種主要的插值器f插值器(f"..."):用于格式化字符串,可以指定格式選項,比如浮點數(shù)的精度等數(shù)據(jù)類型與操作-Map集合defmain(args:Array[String]):Unit={
//集合(Map)和類型推斷valgrades:StudentGrades=immutable.Map("Alice"->95.5,"Bob"->87.0,"Charlie"->92.5)}Scala中的Map是一個鍵值對集合,其中每個鍵都關聯(lián)一個值Map集合使用immutable.Map創(chuàng)建了一個不可變集合來存儲學生的名字和成績。通過“->”操作符添加元素到集合中,對于不可變Map,可以使用“+”操作符創(chuàng)建一個包含新元素的新Map。對于可變Map,可通過“+=”操作符更新Map數(shù)據(jù)類型與操作-類型推斷defmain(args:Array[String]):Unit={
//計算平均成績valaverageGrade=grades.values.sum/grades.sizeprintln(f"班級平均成績是:$averageGrade%.2f")}在Scala中如果未顯式聲明變量的類型,編譯器會自動推斷出最合適的類型類型推斷在代碼中,雖然未明確聲明averageGrade的類型,但Scala編譯器根據(jù)其值自動推斷出它是Double類型面向對象編程-類與對象(普通類)普通類//普通類classEmployee(privatevar_name:String,privatevar_salary:Double){//封裝:使用私有字段和公共方法defname:String=_namedefsalary:Double=_salarydefsalary_=(newSalary:Double):Unit={if(newSalary>0)_salary=newSalary}}Scala普通類定義比Java更簡潔,成員變量可直接聲明在類體中,無需顯式構造器賦值普通類面向對象編程-類與對象(單例對象)單例對象//單例對象objectHRSystem{privatevalemployees=scala.collection.mutable.ArrayBuffer[Employee]()defaddEmployee(employee:Employee):Unit={employees+=employee}defprintAllEmployees():Unit={employees.foreach(println)}}在Scala中,單例對象是只初始化一次的單例模式實例單例對象面向對象編程-類與對象(caseclass)caseclass//caseclasscaseclassDepartment(name:String,head:Employee)用于創(chuàng)建不可變的數(shù)據(jù)結構,通常用于模式匹配caseclass面向對象編程-封裝(私有字段與公共方法)私有字段//私有字段classEmployee(privatevar_name:String,privatevar_salary:Double){...}用于創(chuàng)建不可變的數(shù)據(jù)結構,通常用于模式匹配私有字段在scala中所有方法默認為公共方法,可在任何位置訪問公共方法公共方法//公共方法defsalary_=(newSalary:Double):Unit={if(newSalary>0)_salary=newSalary}面向對象編程-方法重載方法重載//方法重載
defpromote(amount:Double):Unit={salary+=amount}defpromote(percentage:Int):Unit={salary*=(1+percentage/100.0)}即同一個方法名可以根據(jù)傳入?yún)?shù)的不同(Double類型或Int類型),執(zhí)行不同的邏輯方法重載面向對象編程-命名約定命名約定小駝峰命名法大駝峰命名法用于方法和變量名(如addEmployee,printAllEmployees),除了第一個單詞外,每個單詞的首字母都大寫用于類名(如Employee,Department),每個單詞的首字母都大寫,不使用下劃線面向對象編程-擴展說明caseclass特性可變與不可變集合與普通類相比,caseclass自動具備一些功能,如模式匹配、自動生成的toString方法等在HRSystem中使用了可變的ArrayBuffer來存儲雇員,這在多線程環(huán)境下可能會導致問題。對于并發(fā)程序設計,推薦使用不可變集合函數(shù)式編程-模式匹配類似于Java中的swichcase語法,即對一個值進行條件判斷,然后針對不同的條件,執(zhí)行相應的操作模式匹配模式匹配//模式匹配
defdescribeBook(book:Book):String=bookmatch{caseBook(_,title,"MartinOdersky",_)=>s"《$title》是Scala的創(chuàng)始人編寫的書"caseBook(_,title,author,price)ifprice>40=>s"《$title》是一本昂貴的書,作者是$author"caseBook(_,title,author,_)=>s"《$title》的作者是$author"}函數(shù)式編程-Option和EitherOption類型是函數(shù)式編程中處理可能的空值的一種方式。它有兩種形式:Some(value)表示存在值,而None表示不存在值。這避免了直接使用null,從而減少了空指針異常的風險OptionEither類型用于表示操作的兩種可能結果:右側(Right)通常表示成功的結果,而左側(Left)表示某種形式的失敗或錯誤EitherOption與Either區(qū)別Scala中Either和Option是兩種用于處理可能缺失或失敗結果的類型,但它們的設計目的和使用場景有顯著區(qū)別Opiton用于處理可能為空的值(僅區(qū)分存在與否,不提供錯誤信息);Either用于處理可能失敗的操作(Left通常承載錯誤信息,Right表示成功結果)函數(shù)式編程-不可變性Scala的不可變性是指一旦創(chuàng)建集合(如List、Vector等),其元素和結構無法被修改,任何操作都會返回新的集合實例(這種設計提升了線程安全性和函數(shù)式編程的友好性)不可變性核心特性線程安全:不可變集合無需同步機制,多個線程可安全共享引用函數(shù)式友好:支持鏈式操作且不產(chǎn)生副作用,符合純函數(shù)原則持久化數(shù)據(jù)結構:通過共享節(jié)點優(yōu)化內(nèi)存使用,修改操作僅生成新實例函數(shù)式編程-不可變性Scala鼓勵使用不可變數(shù)據(jù)結構和純函數(shù)式操作,以增強代碼的線程安全性、可測試性和可維護性使用caseclass定義不可變的類使用不可變的Map存儲數(shù)據(jù)使用函數(shù)式操作處理數(shù)據(jù)caseclass自動為它的字段生成了一些有用的方法(如equals、hashCode和toString),并且它是不可變的,意味著一旦創(chuàng)建,其狀態(tài)就不能被修改與可變的HashMap不同,Scala中的Map默認是不可變的,這意味著一旦創(chuàng)建,就不能添加或刪除元素。這鼓勵了純粹的函數(shù)式操作,避免了副作用通過使用filter、map、sum等高階函數(shù),可以對集合進行復雜的操作,而不需要改變原始數(shù)據(jù)。這種操作方式避免了直接修改數(shù)據(jù),使得代碼更加清晰且易于理解和維護控制臺輸入與輸出控制臺輸入輸出是指通過標準輸入(stdin)從用戶那里讀取數(shù)據(jù),以及通過標準輸出(stdout)向用戶顯示信息的過程輸入函數(shù):StdIn.readInt()輸出函數(shù):println(...)和print(...)它是Scala的一個標準輸入函數(shù),用于從控制臺讀取用戶輸入的整數(shù)。如果用戶輸入的不是一個有效的整數(shù),那么這個函數(shù)會拋出一個異常。是Scala的標準輸出函數(shù),分別用于打印字符串并在末尾添加換行符以及打印字符串但不添加換行符。在這個例子中,它們被用來向用戶展示信息或者提示文件輸入與輸出文件輸入輸出是指程序與外部文件系統(tǒng)進行數(shù)據(jù)交換的過程,包括從文件讀取數(shù)據(jù)(輸入)和向文件寫入數(shù)據(jù)(輸出)輸入函數(shù):PrintWriter()輸出函數(shù):scala.io.Source它是Java的一個類,用于將文本寫入文件它是Scala的一個類,用于從文件中讀取文本錯誤處理-EitherScala中使用Either[A,B]類型來表示可能失敗的操作結果的方法,其中Left表示錯誤信息,Right表示成功結果,允許以函數(shù)式和類型安全的方式處理和傳播錯誤valwriteResult=writeToFile(filename,content)writeResultmatch{caseRight(_)=>println("文件寫入成功。")caseLeft(error)=>println(s"文件寫入錯誤:$error")}異常處理異常處理是用于捕獲、處理和管理程序執(zhí)行過程中可能發(fā)生的異常情況或錯誤,以確保程序能夠優(yōu)雅地響應并從這些異常中恢復,而不是突然終止defreadFromFile(filename:String):Either[String,String]={try{valsource=scala.io.Source.fromFile(filename)try{Right(source.mkString)}finally{source.close()}}match{caseSuccess(content)=>contentcaseFailure(e)=>Left(s"讀取文件失敗:${e.getMessage}")}}高級特性-泛型泛型是一種允許在定義類、接口和方法時使用類型參數(shù)的編程技術,使得代碼可以獨立于具體的數(shù)據(jù)類型而工作泛型泛型//泛型特質(類型類)traitPrintable[A]{defformat(value:A):String}//泛型類caseclassBox[A](value:A)高級特性-隱式轉換和隱式類隱式轉換和隱式類是Scala中的特性,允許編譯器自動應用某些轉換或添加方法到現(xiàn)有類型,以增強代碼的靈活性和表達能力隱式轉換和隱式類隱式轉換和隱式類//隱式類(用于擴展方法)implicitclassPrintableOps[A](value:A){defformat(implicitp:Printable[A]):String=p.format(value)}//隱式轉換implicitdefboxToValue[A](box:Box[A]):A=box.value高級特性-類型類類型類是一種設計模式,允許在不修改原有代碼的情況下,為不同類型添加新的行為或接口類型類類型類//隱式值(類型類實例)implicitvalintPrintable:Printable[Int]=newPrintable[Int]{defformat(value:Int):String=s"Int:$value"}高級特性-高階函數(shù)高階函數(shù)是可以接受其他函數(shù)作為參數(shù)或返回函數(shù)的函數(shù),增加了代碼的抽象能力和靈活性高階函數(shù)高階函數(shù)//高階函數(shù)deftwice[A](f:A=>A):A=>A=x=>f(f(x))//使用高階函數(shù)valdouble:Int=>Int=x=>x*2valquadruple=twice(double)println(s"4的4倍:${quadruple(4)}")//輸出:4的4倍:16高級特性-柯里化柯里化是將接受多個參數(shù)的函數(shù)轉換為一系列接受單個參數(shù)的函數(shù)的技術柯里化柯里化//柯里化defadd(x:Int)(y:Int):Int=x+y//使用柯里化valadd5=add(5)_println(s"5+3=${add5(3)}")//輸出:5+3=8高級特性-偏函數(shù)偏函數(shù)是只對其定義域的一個子集有定義的函數(shù),允許更精確地控制函數(shù)的應用條件偏函數(shù)偏函數(shù)//偏函數(shù)valdivide:PartialFunction[Int,Int]={casedifd!=0=>100/d}println(s"100/4=${divide(4)}")//輸出:100/4=25println(s"是否定義了100/0:${divide.isDefinedAt(0)}")高級特性-尾遞歸優(yōu)化尾遞歸優(yōu)化是編譯器將尾遞歸函數(shù)轉換為迭代形式的技術,避免了棧溢出的風險,使遞歸更加高效尾遞歸優(yōu)化尾遞歸優(yōu)化//尾遞歸優(yōu)化@scala.annotation.tailrecdeffactorial(n:Int,acc:BigInt=1):BigInt={if(n<=1)accelsefactorial(n-1,n*acc)}println(s"10的階乘:${factorial(10)}")//輸出:10的階乘:3628800(單選)Scala程序的主函數(shù)正確的定義格式是?(
)defmain():Unit={}defmain(args:Array[String]):Unit={}publicstaticvoidmain(String[]args)functionmain(args){}
Scala中如何實現(xiàn)單例設計模式?講解了Scala語言的基本語法與結構講解了Scala語言的數(shù)據(jù)類型與操作講解了Scala語言的面向對象編程講解了Scala語言的函數(shù)式編程講解了Scala語言的輸入輸出和異常處理講解了Scala語言的高級特性10203實現(xiàn)人事管理系統(tǒng)人事管理系統(tǒng)需求介紹103薪資管理模塊人事管理機系統(tǒng)員工信息管理模塊提供員工信息管理,支持新增、刪除、修改和查詢員工基本信息,包括姓名、工號和職位。同時,系統(tǒng)也管理員工的薪資數(shù)據(jù),包括基本工資、獎金和扣款等,確保數(shù)據(jù)的準確性,以支持人力資源決策具備智能化的薪資管理,可以根據(jù)員工的基本工資、獎金和扣款計算最終的薪資。通過薪資管理模塊,可以自動計算薪資,保證薪資計算的準確性、公正性和合規(guī)性,有效執(zhí)行和調整企業(yè)薪資政策系統(tǒng)架構與技術設計員工類(Employee)人事管理系統(tǒng)類(HRSystem)主函數(shù)(Mainobject)人事管理系統(tǒng)系統(tǒng)架構與技術設計-員工類(Employee)
員工類(caseclass
Employee)員工ID:String姓名:String職位:String薪資:Double系統(tǒng)架構與技術設計-人事管理系統(tǒng)類(HRSystem)
人事管理系統(tǒng)類(class
HRSystem)員工映射表:mutable.MapaddEmployee(employee:Employee):添加員工信息deleteEmployee(id:String):根據(jù)ID刪除員工記錄updateEmployee(employee:Employee):更新或新增員工信息getEmployee(id:String):通過ID獲取員工信息calculateSalary(id:String,bonus:Double,deduction:Double):計算指定員工在獎金和扣款影響下的薪資系統(tǒng)架構與技術設計-主函數(shù)(Mainobject)
主函數(shù)(Mainobject)作為程序入口,通過無限循環(huán)與用戶交互展示操作菜單,根據(jù)用戶輸入調用HRSystem相應方法支持添加、刪除、修改、查詢員工信息,計算薪資以及退出系統(tǒng)使用match語句處理用戶選擇,確保輸入的有效性,對于無效的操作將會提示用戶重新輸入,提升用戶體驗需求功能實現(xiàn)-定義員工類(Employee)//定義員工類
caseclassEmployee(id:String,name:String,position:String,salary:Double)需求功能實現(xiàn)-創(chuàng)建人事管理系統(tǒng)類(HRSystem)classHRSystem{privatevalemployees=mutable.Map[String,Employee]()
//...各種方法...}需求功能實現(xiàn)-定義人事管理類方法//添加員工defaddEmployee(employee:Employee):Unit={employees(employee.id)=employee}//刪除員工defdeleteEmployee(id:String):Unit={employees.remove(id)}111//修改員工信息defupdateEmployee(employee:Employee):Unit={employees(employee.id)=employee}//查詢員工信息defgetEmployee(id:String):Option[Employee]={employees.get(id)}112//計算薪資defcalculateSalary(id:String,bonus:Double,deduction:Double):Option[Double]={employees.get(id).map(e=>e.salary+bonus-deduction)}需求功能實現(xiàn)-編寫主函數(shù)objectMain{defmain(args:Array[String]):Unit={//...與用戶交互邏輯...}}在main方法內(nèi),需要實現(xiàn)的邏輯如下:初始化一個HRSystem實例hrSystem,用于處理人事管理操作設立一個布爾變量running,初始值為true,用于控制循環(huán)是否繼續(xù)在循環(huán)內(nèi)部,展示操作菜單供用戶選擇,如“1.添加員工”,“2.刪除員工”等讀取用戶輸入的整數(shù)(代表所選操作),并使用match語句根據(jù)用戶選擇調用相應的方法需求功能實現(xiàn)-編寫主函數(shù)valhrSystem=newHRSystem()varrunning=truewhile(running){println("請輸入操作:1.添加員工2.刪除員工3.修改員工4.查詢員工5.計算薪資6.退出")valoperation=scala.io.StdIn.readInt()operationmatch{case1=>
115println("請輸入員工ID、姓名、職位和薪資:")valid=scala.io.StdIn.readLine()valname=scala.io.StdIn.readLine()valposition=scala.io.StdIn.readLine()valsalary=scala.io.StdIn.readDouble()hrSystem.addEmployee(Employee(id,name,position,salary))case2=>println("請輸入員工ID:")
116valid=scala.io.StdIn.readLine()hrSystem.deleteEmployee(id)case3=>println("請輸入員工ID、姓名、職位和薪資:")編譯代碼終端輸入
scalac*.scala
命令,編譯所有scala源文件運行代碼終端輸入
scalaMain
命令,運行Main程序代碼優(yōu)化代碼優(yōu)化防止數(shù)據(jù)沖突與冗余提升用戶體驗與程序反饋清晰度增強數(shù)據(jù)輸入有效性與程序健壯性代碼優(yōu)化-防止數(shù)據(jù)沖突與冗余在添加或更新員工信息時,若不檢查ID是否存在并詢問用戶是否覆蓋,可能導致同一ID對應多條數(shù)據(jù)(更新時)或重復記錄(添加時)。通過提示并確認,可確保數(shù)據(jù)一致性,避免信息混亂,修改代碼如下://添加員工defaddEmployee(employee:Employee):Unit={
if(employees.contains(employee.id)){//這里可以詢問用戶是否要更新println(s"員工ID為${employee.id}的員工已存在,是否要更新?")}else{employees(employee.id)=employee}}121//修改員工信息defupdateEmployee(employee:Employee):Unit={
if(!employees.contains(employee.id)){println(s"員工ID為${employee.id}的員工不存在.")}else{employees(employee.id)=employee}}代碼優(yōu)化-提升用戶體驗與程序反饋清晰度
當查詢或計算薪資涉及的員工ID不存在時,直接返回“None”對用戶而言可能難以理解。提供明確的錯誤信息,如“員工ID未找到”,有助于用戶快速識別問題所在,提高系統(tǒng)易用性及交互友好度。修改后的代碼如下://查詢員工信息defgetEmployee(id:String):Either[String,Employee]={
employees.get(id)match{caseSome(employee)=>Right(employee)caseNone=>Left(s"員工ID為$id的員工不存在.")}}123//計算薪資defcalculateSalary(id:String,bonus:Double,deduction:Double):Either[String,Double]={
employees.get(id)match{caseSome(employee)=>Right(employee.salary+bonus-deduction)caseNone=>Left(s"員工ID為$id的員工不存在.")}}代碼優(yōu)化-增強數(shù)據(jù)輸入有效性與程序健壯性
當查詢或計算薪資涉及的員工ID不存在時,直接返回“None”對用戶而言可能難以理解。提供明確的錯誤信息,如“員工ID未找到”,有助于用戶快速識別問題所在,提高系統(tǒng)易用性及交互友好度。修改前后的代碼對比如下:valoperation=scala.io.StdIn.readInt()operationmatch{case1=> ...valsalary=scala.io.StdIn.readDouble()hrSystem.addEmployee(Employee(id,name,position,salary))valoperation=scala.io.StdIn.readInt()operationmatch{case1=>...valsalary=scala.io.StdIn.readDouble()
if(salary<0){println("薪資必須是非負數(shù).")}else{hrSystem.addEmployee(Employee(id,name,position,salary))}修改前修改后代碼優(yōu)化-提升用戶體驗與程序反饋清晰度
valoperation=scala.io.StdIn.readInt()operationmatch{...case3=>println("請輸入員工ID、姓名、職位和薪資:")valid=scala.io.StdIn.readLine()valname=scala.io.StdIn.readLine()valposition=scala.io.StdIn.readLine()valsalary=scala.io.StdIn.readDouble()hrSystem.updateEmployee(Employee(id,name,position,salary))valoperation=scala.io.StdIn.readInt()operationmatch{...case3=>println("請輸入員工ID、姓名、職位和薪資:")valid=scala.io.StdIn.readLine()valname=scala.io.StdIn.readLine()valposition=scala.io.StdIn.readLine()valsalary=scala.io.StdIn.readDouble()
if(salary<0){println("薪資必須是非負數(shù).")}else{hrSystem.updateEmployee(Employee(id,name,position,salary))}修改前修改后代碼優(yōu)化-提升用戶體驗與程序反饋清晰度
valoperation=scala.io.StdIn.readInt()operationmatch{...case4=>println("請輸入員工ID:")valid=scala.io.StdIn.readLine()valemployee=hrSystem.getEmployee(id)println(s"員工信息:$employee")valoperation=scala.io.StdIn.readInt()operationmatch{...case4=>println("請輸入員工ID:")valid=scala.io.StdIn.readLine()
hrSystem.getEmployee(id)match{caseRight(employee)=>println(s"員工信息:$employee")caseLeft(error)=>println(error)}}修改前修改后代碼優(yōu)化-提升用戶體驗與程序反饋清晰度
valoperation=scala.io.StdIn.readInt()operationmatch{...case5=>println("請輸入員工ID、獎金和扣款:")valid=scala.io.StdIn.readLine()valbonus=scala.io.StdIn.readDouble()valdeduction=scala.io.StdIn.readDouble()valsalary=hrSystem.calculateSalary(id,bonus,deduction)println(s"計算后的薪資:$salary")valoperation=scala.io.StdIn.readInt()operationmatch{...case5=>println("請輸入員工ID、獎金和扣款:")valid=scala.io.StdIn.readLine()valbonus=scala.io.StdIn.readDouble()valdeduction=scala.io.StdIn.readDouble()
hrSystem.calculateSalary(id,bonus,deduction)match{caseRight(salary)=>println(s"計算后的薪資:$salary")caseLeft(error)=>println(error)}}修改前修改后128你認為還有哪些地方可以進行代碼優(yōu)化?(多選)Scala中用于錯誤處理的類型包括?(
)OptionEitherTryExceptionError
講解了人事管理系統(tǒng)的需求分析講解了人事管理系統(tǒng)的系統(tǒng)架構與技術設計講解了人事管理系統(tǒng)的需求功能實現(xiàn)講解了人事管理系統(tǒng)的編譯與運行講解了人事管理系統(tǒng)的代碼優(yōu)化許斌/0181932025.11.18新開發(fā)電商用戶行為數(shù)據(jù)分析
學完本課程后,您將可以:了解RDD的概念和特點掌握RDD操作的分類掌握SparkShell環(huán)境的使用能在SparkShell環(huán)境中進行實踐操作能使用RDD對數(shù)據(jù)進行預處理能使用RDD對數(shù)據(jù)進行統(tǒng)計與需求功能實現(xiàn)01認識RDD02RDD操作實踐03使用RDD實現(xiàn)電商用戶行為分析13601認識RDDRDD的概念RDD的全稱是ResilientDistributedDataset(彈性分布式數(shù)據(jù)集),是Spark中最基本的數(shù)據(jù)結構之一(可以簡單地把RDD理解成一個提供了很多操作接口的數(shù)據(jù)集合)Resilient(彈性的)Distributed(分布式的)Dataset(數(shù)據(jù)集)包括存儲和計算兩個方面。在存儲方面,RDD中的數(shù)據(jù)可以保存在內(nèi)存中,當內(nèi)存不足時也可以保存在磁盤上;在計算方面,RDD具有自動容錯的特點,當運算過程中出現(xiàn)異常導致Partition數(shù)據(jù)丟失或運算失敗時,可以根據(jù)Lineage(血統(tǒng))關系對數(shù)據(jù)進行重建同樣包括存儲和計算兩個方面。RDD的數(shù)據(jù)元素是分布式存儲的,同時其運算方式也是分布式的RDD本質上是一個存放元素的分布式數(shù)據(jù)集合RDD的特點RDD具有分布式計算、容錯性、數(shù)據(jù)可讀性、內(nèi)存計算、優(yōu)化執(zhí)行計劃和支持多種數(shù)據(jù)源等特點,可以幫助大數(shù)據(jù)處理更加高效和靈活分布式計算RDD可以在集群中的多個節(jié)點上進行分區(qū)和并行計算,利用集群的計算資源進行高效的數(shù)據(jù)處理容錯性RDD通過記錄轉換操作的血統(tǒng)(lineage)信息,可以在節(jié)點故障時重新計算丟失的部分,保證計算結果的可靠性數(shù)據(jù)可讀性RDD提供了高級的數(shù)據(jù)操作接口,如map、filter、reduce等,使得數(shù)據(jù)的處理更加靈活和高效內(nèi)存計算RDD可以將數(shù)據(jù)緩存在內(nèi)存中,通過內(nèi)存計算來加速數(shù)據(jù)的處理,大幅提升計算性能優(yōu)化執(zhí)行計劃Spark可以通過優(yōu)化執(zhí)行計劃來減少數(shù)據(jù)的傳輸和計算開銷,提高作業(yè)執(zhí)行效率支持多種數(shù)據(jù)源RDD可以從多種數(shù)據(jù)源中讀取數(shù)據(jù),如HDFS、本地文件系統(tǒng)、數(shù)據(jù)庫等,方便靈活地處理不同類型的數(shù)據(jù)RDD操作分類RDD操作指的是Spark中對RDD進行操作(使用Spark高效地處理大規(guī)模數(shù)據(jù),都離不開RDD操作)轉換操作(轉換算子)行動操作(行動算子)對RDD進行轉換并生成新的RDD,而不改變原有的RDD。轉換操作是惰性求值的,即在調用轉換操作時,并不會立即執(zhí)行計算,而是記錄下轉換操作的邏輯,并在執(zhí)行行動操作時才進行實際計算。轉換操作返回的是一個新的RDD,可以進行鏈式調用對RDD執(zhí)行計算并返回結果。行動操作會觸發(fā)RDD的計算過程,從而產(chǎn)生實際的結果或副作用。行動操作會立即執(zhí)行,返回一個具體的結果,而不是一個新的RDD常用的轉換操作轉換操作(轉換算子)含義map(func)返回一個新的RDD,該RDD由每一個輸入元素經(jīng)過func函數(shù)轉換后組成filter(func)返回一個新的RDD,該RDD由經(jīng)過func函數(shù)計算后返回值為true的輸入元素組成flatMap(func)類似于map,但是每一個輸入元素可以被映射為0或多個輸出元素(所以func應該返回一個序列,而不是單一元素)mapPartitions(func)類似于map,但獨立地在RDD的每一個分片上運行,因此在類型為T的RDD上運行時,func的函數(shù)類型必須是Iterator[T]=>Iterator[U]mapPartitionsWithIndex(func)類似于mapPartitions,但func帶有一個整數(shù)參數(shù)表示分片的索引值,因此在類型為T的RDD上運行時,func的函數(shù)類型必須是(Int,Interator[T])=>Iterator[U]常用的轉換操作轉換操作(轉換算子)含義union(otherDataset)對源RDD和參數(shù)RDD求并集后返回一個新的RDDintersection(otherDataset)對源RDD和參數(shù)RDD求交集后返回一個新的RDDdistinct([numTasks]))對源RDD進行去重后返回一個新的RDDgroupByKey([numTasks])在一個(K,V)的RDD上調用,返回一個(K,Iterator[V])的RDDreduceByKey(func,[numTasks])在一個(K,V)的RDD上調用,返回一個(K,V)的RDD,使用指定的reduce函數(shù),將相同key的值聚合到一起,與groupByKey類似,reduce任務的個數(shù)可以通過第二個可選的參數(shù)來設置常用的轉換操作轉換操作(轉換算子)含義sortByKey([ascending],[numTasks])在一個(K,V)的RDD上調用,K必須實現(xiàn)Ordered接口,返回一個按照key進行排序的(K,V)的RDDsortBy(func,[ascending],[numTasks])與sortByKey類似,但是更靈活join(otherDataset,[numTasks])在類型為(K,V)和(K,W)的RDD上調用,返回一個相同key對應的所有元素對在一起的(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 攝像機網(wǎng)絡協(xié)議書
- 蘇州工傷賠償協(xié)議書
- 朝陽股權協(xié)議書辦法
- 線上商城商品購銷協(xié)議書
- 防災減災協(xié)議書儲備方案
- 內(nèi)科疾病護理與康復護理
- 個體化液體復蘇策略的醫(yī)患溝通
- 個體化撤機策略:預測模型在重癥監(jiān)護中的實踐
- 先進護理技術探索與實踐
- 2026年旅游行業(yè)供應鏈管理面試題行程規(guī)劃與資源分配
- 上海財經(jīng)大學2026年輔導員及其他非教學科研崗位人員招聘備考題庫帶答案詳解
- 2026湖北恩施州建始縣教育局所屬事業(yè)單位專項招聘高中教師28人備考筆試試題及答案解析
- 心肺康復課件
- 2025中原農(nóng)業(yè)保險股份有限公司招聘67人筆試參考題庫附帶答案詳解(3卷)
- 2026年內(nèi)蒙古商貿(mào)職業(yè)學院單招職業(yè)技能測試題庫及參考答案詳解一套
- 退贓后賠償協(xié)議書
- 骶部炎性竇道的護理
- 多元催化體系下羊毛脂轉酯化制備膽固醇的工藝解析與效能探究
- 家庭農(nóng)場的商業(yè)計劃書(6篇)
- 高處安全作業(yè)培訓
- 2023-2024學年北京市通州區(qū)數(shù)學九年級第一學期期末綜合測試試題含解析
評論
0/150
提交評論