




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
會C語?學(xué)go難嗎,為什么Go語?不是想象中的那么好我喜歡Go.常?它實現(xiàn)各種功能(包括在寫本?時的這個博客).Go很實?,但不夠好。不是說它有多差,只是沒那么好?已。?門編程語?,也許會?上?輩?,所以選擇的時候要注意。本?專注于Go的各種吐槽。??常談的有之,鮮為?知的也有。我?Rust和Haskell作為參照(?少,我以為,這倆都很不錯)。本?列出的所有問題,都有解決?案。常規(guī)編程那么問題來了我們寫代碼可以?于許多不同的事情。假如我寫了?個函數(shù)?來對?列數(shù)字求和,如果我可以?該函數(shù)對浮點數(shù)、整數(shù)以及其他任何類型進(jìn)?求和那該多棒。如果這些代碼包含了類型安全并且可以快速的寫出?于整型相加、浮點型相加等的獨?函數(shù)就更完美了。好的解決?案:基于限制的泛型和基于參數(shù)的多態(tài)到?前為?,我遇到的最好的泛型編程系統(tǒng)是rust和haskell所共?的那個。它?般被稱作”被限制的類型“。在haskell中,這個系統(tǒng)被稱作”typeclass“。?在Rust中,它被稱作”traits“。像這樣:(Rust,version0.11)fnid(item:T)->T{item}(Haskell)id::t->tida=a在上?這個簡單了例?中,我們定義了?個泛型函數(shù)id。id函數(shù)將它的參數(shù)原封不動傳回來。很重要的?點是這個函數(shù)可以接受任何類型的參數(shù),?不是某個特定的類型。在Rust和haskell中,id函數(shù)保留了它參數(shù)的類型信息,使得靜態(tài)檢查可以順利?作,并且沒有為次在運(yùn)?期付出任何代價。你可以使?這個函數(shù)來寫?個克隆函數(shù)。同樣,我們可以應(yīng)?這種?式來定義泛型數(shù)據(jù)結(jié)構(gòu)。例如:(Rust)structStack{items:Vec}(Haskell)dataStackt=Stack[t]跟上??樣,我們在沒有運(yùn)?期額外消耗的情況下得到完全的靜態(tài)安全。現(xiàn)在,如果我們想寫?個通?的函數(shù),我們必須告訴編譯器“這個函數(shù)只有在它的所有參數(shù)?持這個函數(shù)中所??到的操作時,才有意義”。舉個例?,如果我們想定義?個將它的三個參數(shù)相加,并返回其和的函數(shù),我們必須告訴編譯器:這三個參數(shù)必須?持加法運(yùn)算。就象這樣:(Rust)fnadd3(a:T,b:T,c:T)->T{a+b+c
}(Haskell)add3::Numt=>t->t->t->tadd3abc=a+b+c在上?這個例?中,我們告訴haskell的編譯器:“add3這個函數(shù)的參數(shù)必須是?個Num(算數(shù)數(shù)類型)“。因為編譯器知道?個Num類型的參數(shù)?持加法,所以這個函數(shù)的表達(dá)式可以通過類型檢查。在haskell中,這些限制也可應(yīng)?于data關(guān)鍵字所做的定義中。這是?個可以優(yōu)雅地定義百分之百類型安全的靈活泛型函數(shù)的?式。go的解決?案:interface{}Go的普通類型系統(tǒng)的結(jié)果是,Go對通?編程的?持很差。你可以?常輕松的寫通??程。假如你想寫?個可以打印被哈希的對象的哈希值。你可以定義?個擁有靜態(tài)類型安全保證的interface,像這樣:(Go)typeHashableinterface{Hash()[]byte}funcprintHash(itemHashable){fmt.Println(item.Hash())}現(xiàn)在,你可以提供給printHash任何Hashable的對象,你也得到靜態(tài)類型檢查。這很好。但如果你想寫?個通?的數(shù)據(jù)結(jié)構(gòu)呢?讓我們寫?個簡單的鏈表。在Go?寫通?數(shù)據(jù)結(jié)構(gòu)的慣??法是:(Go)typeLinkedListstruct{valueinterface{}next*LinkedList}func(oldNode*LinkedList)prepend(valueinterface{})*LinkedList{return&LinkedList{value,oldNode}}functail(valueinterface{})*LinkedList{return&LinkedList{value,nil}}functraverse(ll*LinkedList){ifll==nil{return}
fmt.Println(ll.value)traverse(ll.next)}funcmain(){node:=tail(5).prepend(6).prepend(7)traverse(node)}發(fā)現(xiàn)什么了嗎?value的類型是interface{}。interface{}就是所謂的“最?類型”,意味著所有其他的類型都是interface{}的?類型。這?致相當(dāng)于Java中的Object。呀!(注意:對于Go中是否有最?類型還有爭議,因為Go宣稱沒有?類型。不管這些,保留類?的情況。在Go??“正確”構(gòu)建通?數(shù)據(jù)結(jié)構(gòu)的?法是將對象設(shè)置為最?類,然后把它們放?到數(shù)據(jù)結(jié)構(gòu)中。?約在2004年,Java就是這么做的。后來?們發(fā)現(xiàn)這完全違背了類型系統(tǒng)的本意。當(dāng)你有這樣的數(shù)據(jù)結(jié)構(gòu)時,你完全消除了?個類型系統(tǒng)能提供的所有好處。?如,下?這個是完全有效的代碼:node:=tail(5).prepend("Hello").prepend([]byte{1,2,3,4})?這在?個良好結(jié)構(gòu)化的程序?完全沒有意義。你可能期望的時?個整數(shù)鏈表,但在某個情況下,?些疲憊、靠咖啡清醒的程序員在截??期前偶然在某處加?了?個字符串。因為Go??的通?數(shù)據(jù)結(jié)構(gòu)不知道它們值的類型,Go的編譯器也不會改正,你的程序在你失去從interface{}??捕獲時將崩潰。相同的問題在任何通?數(shù)據(jù)結(jié)構(gòu)?都存在,?論是listm、apg、rapht、reeq、ueue等。語?可擴(kuò)展性問題?級語?通常有復(fù)雜任務(wù)的關(guān)鍵字和符號簡寫。?如,在很多語?中,迭代?個如數(shù)組?樣的數(shù)據(jù)集合中所有元素的簡寫:(Java)for(Stringname:names){...}(Python)fornameinnames:...如果我們能在任何集合類型上操作,不僅僅是那些語?內(nèi)建類型(如數(shù)組),會很美好。如果我們可以定義類型的相加也會很美好,那么我們可以這么做(Python)point3=point1+point2好的解決?案:把運(yùn)算符視作函數(shù)將內(nèi)建的運(yùn)算符和某個特別命名的函數(shù)對應(yīng)起來,亦或?qū)㈥P(guān)鍵字視作特定函數(shù)的別名,這樣做可以很好的解決該問題。某些編程語?,像Python,Rust和Haskell允許我們重載運(yùn)算符。我們只需要給我們?定義的類添加?個函數(shù),?此,當(dāng)我們使?某個運(yùn)算符的時候(例如”+“),解釋器(編譯器)就會直接調(diào)?我們所添加的函數(shù)。在Python中,運(yùn)算符”+“對應(yīng)于__add__()函數(shù)。在Rust中,”+“運(yùn)算符在Add這個trait中定義為add()函數(shù)。在Haskell中,”+“對應(yīng)于Num這個typeclass中的(+)。許多語?都有擴(kuò)展關(guān)鍵字的?法,例如for-each循環(huán)。Haskell沒有循環(huán),但是像Rust,Java和Python這樣的語?中都有”迭代器“這樣的概念使得for-each循環(huán)可以應(yīng)?于任何種類的數(shù)據(jù)集合結(jié)構(gòu)。某些?可能會?這個特性做?些很操蛋的事情,這是?個潛在的缺點。例如,某些瘋狂的家伙使?”-“來代表兩個向量之間的點乘。但這并不完全是運(yùn)算符重載的問題。?論使?何種語?,都可以寫出胡亂命名的函數(shù)。
Go的解決?案:沒有Go語?不?持操作符重載或者關(guān)鍵字?jǐn)U展。那么如果我們想給其他的東西(例如樹,鏈表)實現(xiàn)range關(guān)鍵字的操作怎么辦?太糟糕了。這不是語?的?部分。你這能在內(nèi)建對象上使?range關(guān)鍵字。對于關(guān)鍵字make也?樣,它不能給?內(nèi)建數(shù)據(jù)結(jié)構(gòu)申請內(nèi)存和初始化。最接近這個可以使?迭代器的關(guān)鍵字的?式是寫?個包裝函數(shù),這個函數(shù)以?標(biāo)數(shù)據(jù)結(jié)構(gòu)為參數(shù)并返回?個可迭代的對象,我們通過使?這個對象在?標(biāo)數(shù)據(jù)結(jié)構(gòu)上迭代(譯者注:參見設(shè)計模式中的迭代器模式或C++中的迭代器實現(xiàn))。但是這樣做可能會很慢并且復(fù)雜,?且?法保證不引?其他的bug。對于這樣?個問題,有?辯解道,“這樣更容易讓?理解代碼,并且我看到的代碼就是真正被執(zhí)?的代碼。”也就是說,如果Go語?允許我們擴(kuò)展像range這樣的東西,那么range本?的機(jī)制和實現(xiàn)就會變得復(fù)雜難以理解。我認(rèn)為這樣的說法沒有什么營養(yǎng),因為不管Go是否通過這種?式讓其變得更簡單,更易懂,?們總要進(jìn)?這種在某些數(shù)據(jù)結(jié)構(gòu)上進(jìn)?迭代操作。如果我們不想把實現(xiàn)細(xì)節(jié)隱藏在range()函數(shù)?,我們就要把它隱藏在其他的?具函數(shù)?,沒什么改進(jìn)。所有的好代碼都是易讀的,?多數(shù)糟糕代碼讓?很難懂,很顯然Go不能改變這個事實。基礎(chǔ)案例與失敗條件那么問題來了當(dāng)遇到遞歸的數(shù)據(jù)結(jié)構(gòu)(如鏈表和樹)時,我們希望找到?個途徑來指出我們到達(dá)數(shù)據(jù)結(jié)構(gòu)的末端。當(dāng)遇到可能會執(zhí)?失敗的函數(shù)或包含缺失數(shù)據(jù)?的數(shù)據(jù)結(jié)構(gòu)時,我們希望找到?個途徑明?我們遇到的?種失敗情況。Go的?解決案:Nil(和多個返回值)這回我先說Go的,才好引出其他更好解決?案的討論.Go?持null指針(nil).每次看到新的編程語?(如:tabularasa),實現(xiàn)這個導(dǎo)致bug滿天飛的功能,我替他們可惜.null指針的歷史,滿滿的都是bug.?論是歷史,還是現(xiàn)實,我都看不出來,數(shù)據(jù)存在內(nèi)存地址為0x0的地?有什么意義.指向0x0的指針通常都有特定的含義.?如,返回類型是指針的函數(shù)出錯,會返回0x0.遞歸數(shù)據(jù)結(jié)構(gòu)把0x0當(dāng)作基底(basecase),如:樹結(jié)構(gòu)的頁節(jié)點,或鏈表的結(jié)尾.這也是null指針在Go中的?法.然?,這樣使?null指針也是不安全的。事實上,null指針是類型系統(tǒng)的后門,它讓你能夠創(chuàng)造某個根本不是所屬類型的實例。程序員有時候會忘記某個指針的值可能是null這個事實,這是?個很常見的情況。在最好的情況下,你的程序會掛掉,?在最壞的情況下,這會產(chǎn)??個可以被?利?的漏洞。編譯器?法輕易地阻?這種情況的發(fā)?,因為null指針破壞了語?的類型系統(tǒng)。對于Go來說,使?多重返回值這個機(jī)制,利?它第?個返回值來返回?個代表“失敗”的值是?個正確也被?勵的做法。然?,這種機(jī)制很容易被忽略或者誤?,并且在表?遞歸數(shù)據(jù)結(jié)構(gòu)的時候沒有什么??處。好的解決?案:代數(shù)數(shù)據(jù)類型和類型安全的錯誤模式我們可以使?類型系統(tǒng)來包裝錯誤狀況,基底,?不是試圖打破類型系統(tǒng)。現(xiàn)在我們想要構(gòu)建?個表?鏈表的類型。我們想表?兩種情況:我們是否已經(jīng)到達(dá)了鏈表的末尾,某個鏈表的節(jié)點上到底有沒有被存放在那?的數(shù)據(jù)。?種類型安全的?式是分別使?不同的類型來表?這些情況,最后將它們組合成?個單獨的類型(使?代數(shù)數(shù)據(jù)類型)。現(xiàn)在我們有?個叫做Cons的類型來表??個存放有某些數(shù)據(jù)的鏈表,?個叫做End的類型來表?鏈表的末尾。我們可以這樣寫:(Rust)enumList{Cons(T,Box>),End}letmy_list=Cons(1,boxCons(2,boxCons(3,boxEnd)));(Haskell)
dataListt=End|Const(Listt)letmy_list=Cons1(Cons2(Cons3End))每個類型都為遞歸操作這個數(shù)據(jù)結(jié)構(gòu)的算法聲明了?個基底(End)。。Rust和Haskell都不允許null指針的出現(xiàn),所以我們永遠(yuǎn)都不會碰到null指針解引?所造成的bug(除?我們做?些很?膽的底層操作)。這些代數(shù)數(shù)據(jù)結(jié)構(gòu)通過像模式匹配(后?講它)這樣的技術(shù),允許我們寫出?常明了的代碼。那么,我們?nèi)绾蔚玫?個可能返回或者不返回給定類型的數(shù)據(jù)的函數(shù),或是?個可能內(nèi)部包含或者沒有包含?個給定類型的數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)呢?也就是說,我們?nèi)绾螌㈠e誤狀況(failurecondition)封裝到我們的類型系統(tǒng)中來呢?Rust使?Option,Haskell使??個叫Maybe的類型來解決這個問題。我們想象這樣?個函數(shù),它所作的事情是搜索?個?空字符串的數(shù)組,尋找?個以這‘H’開頭的字符串,返回第?個找到的這樣的字符串,如果沒有找到,就返回某種錯誤狀況。在Go語?中,我們可以通過返回nil來表?“沒找到”這個錯誤。但是在Haskell和Rust中,不使?危險的指針,我們就可以安全地完成這個任務(wù)。(Rust)fnsearch(strings:&'a[String])->Option{forstringinstrings.iter(){ifstring.as_slice()[0]=='H'asu8{returnSome(string.as_slice());}}None}(Haskell)search[]=Nothingsearch(x:xs)=if(headx)=='H'thenJustxelsesearchxs我們可以返回?個包含或者沒有包含?個字符串的對象來代替返回?個字符串或者null指針的做法。使?search()函數(shù)的程序員也會很清楚地知道這個函數(shù)可能會失敗(因為它返回的對象的類型已經(jīng)這么說了),?且程序員必須處理這兩種狀況,否則報錯。這樣我們就跟null指針解引?所造成的bug說再見了。類型推導(dǎo)(TypeInference)問題給程序中的每個值都指定類型,有時看起來點過??。某些場合,值的類型顯?易見,如intx=5y=x*2這?的y明顯就是整形。更復(fù)雜點的,我們甚?可以根據(jù)函數(shù)的參數(shù)類型推斷出它的返回類型(反之亦然)。出?的解決?案:通?類型推導(dǎo)(GeneralTypeInference)Rust和Haskell都基于Hindley-Milner類型系統(tǒng),他們都很擅長類型推導(dǎo),你可以實現(xiàn)像下?這樣好玩的功能:(Haskell)map::(a->b)->[a]->[b]letdoubleNumsnums=map(*2)numsdoubleNums::Numt=>[t]->[t]
函數(shù)(*2)有?個Num類型參數(shù),返回也是?個Num類型,Haskell由此推斷a和b也是Num類型.最后推斷出,該函數(shù)有若?個Num類型參數(shù),返回若個Num類型的值.這種?式?Go和C++的簡單類型推導(dǎo)強(qiáng)?多了.有了它,哪怕是結(jié)構(gòu)復(fù)雜的程序,就算我們不聲明這么多顯性類型,編譯器也能正確處理.Go的解決?案::=Go?持:=賦值操作符,?法如下:(Go)foo:=bar()它的原理是:查找bar()的返回類型,然后賦給foo.下列代碼的道理也?樣:(C++)autofoo=bar();沒什么稀奇的,??省去了??查找函數(shù)bar()的返回類型,在鍵盤上多敲?個字聲明foo的類型那點時間?已.不變性(Immutability)問題不變性是指,在程序?成的時候,設(shè)好的值,以后不會再變。它的優(yōu)勢很明顯,能減少因程序某個地?的數(shù)據(jù)結(jié)構(gòu)改變,導(dǎo)致另?個地?出現(xiàn)問題的概率。此外對程序優(yōu)化也有利。出?的解決?案:默認(rèn)使?不變性程序員應(yīng)當(dāng)盡可能使?不可變數(shù)據(jù)結(jié)構(gòu)。不變性使得判斷負(fù)?影響和安全性變得更簡單。同時也能減少各種Bug。Haskell默認(rèn)情況下,所有的值都是不可變的。改變數(shù)據(jù)結(jié)構(gòu)就意味著,在保證正確性的前提下,重新創(chuàng)建?個新的數(shù)據(jù)結(jié)構(gòu)。由于Haskell采?的是惰性求值(lazyevaluation)和永久性數(shù)據(jù)結(jié)構(gòu)(persistentdatastructures),所以運(yùn)?的速度還是粉快的。Rust屬于系統(tǒng)級編程語?。不可能使?惰性求值,也就不能像Haskell那樣始終使?不變性。因此,雖然Rust默認(rèn)情況下,變量的值是不可變的。但是,在需要的時候,還是可以將變量設(shè)置成可變的。這樣挺好,因為它迫使程序員問??,底需不需要將這個變量設(shè)成可變的。這是很好的變成習(xí)慣,對編譯器優(yōu)化代碼也有好處。Go的?案:?Go不?持這項功能。控制流結(jié)構(gòu)(ControlFlowStructures)問題控制流結(jié)構(gòu)是?級編程語?有別于匯編的原因之?.它允許我們在抽象層?,有條理地控制程序流程.毫?疑問,所有?級語?都?持控制流結(jié)構(gòu),否則,我還說個?啊.可惜,有那么?種相當(dāng)不錯的控制流結(jié)構(gòu)Go不?持.出?的解決?案:模式匹配和復(fù)合表達(dá)式模式匹配配合數(shù)據(jù)結(jié)構(gòu)或值使?的時候,效果相當(dāng)好.簡直就是case/switch的加強(qiáng)版.我們可以像這樣對值進(jìn)?匹配:(Rust)matchx{0|1=>action_1(),2..9=>action_2(),_=>action_3()};
或者像這樣解構(gòu)數(shù)據(jù)結(jié)構(gòu)(deconstructdatastructures):(Rust)deg_kelvin=matchtemperature{Celsius(t)=>t+273.15,Fahrenheit(t)=>(t-32)/1.8+273.15};上?的例?,有時也稱作復(fù)合表達(dá)式.C和Go中的if和case/switch語句只?來控制程序流程,不會返回值;?Rust和Haskell的if和模式匹配語句則可以.既然有值返回,當(dāng)然也能?來賦給其他東東.這?給出?個if語句的例?:(Haskell)x=if(y=="foo")then1else2Go的?案:C語?風(fēng)格的?值語句(ValuelessStatements)不是我故意找Go的茬;它確實有?個不錯的的控制流元素,如,?于并?計算的select.可惜沒有我鐘愛的復(fù)合表達(dá)式和模式匹配.Go唯??持賦值的語句,是像這樣的原?表達(dá)式x:=5或x:=foo().嵌?式編程給嵌?式系統(tǒng)編寫程序與在?個有完整操作系統(tǒng)的計算機(jī)上編寫程序有很?不同。某些語?相???更適合嵌?式編程的需要。對于不少?贊成Go語?可以給機(jī)器?編程這件事我很疑惑。基于?些原因,Go語?并不適合?來為嵌?式系統(tǒng)編寫程序。這?節(jié)并不是對Go語?的指責(zé),Go語?并不是被設(shè)計?來編寫嵌?式程序的語?。這?章節(jié)針對那些吹捧Go語?可以勝任嵌?式編程的?。?問題#1:堆和動態(tài)內(nèi)存分配堆是?塊在運(yùn)?期創(chuàng)建的可以存儲任意數(shù)量對象的內(nèi)存區(qū)域。我們將對堆的使?稱作”動態(tài)內(nèi)存分配“。通常,在嵌?式系統(tǒng)中使?堆存儲空間是不明智的。較?的內(nèi)存開銷和需要管理復(fù)雜的數(shù)據(jù)結(jié)構(gòu)是主要的原因,尤其是當(dāng)你在?塊主頻只有8MHz,RAM只有2KB的MCU上寫程序的時候。在實時系統(tǒng)(因為某?操作耗時過長就可能會跪的系統(tǒng))中使?堆也是不明智的,因為對堆上空間的申請和釋放所消耗的時間有很?的不確定性。舉個例?,如果你的MCU正在控制?個?箭的引擎,就在這時,如果?個對棧空間的申請?平常多消耗了?百毫秒,導(dǎo)致對閥門的錯誤計時,就會發(fā)??爆炸。還有?些原因致使動態(tài)內(nèi)存分配對嵌?式編程沒有多??。例如,許多使?堆的語?同時也擁有垃圾收集機(jī)制。垃圾收集機(jī)制經(jīng)常會暫停整個程序?會?,在堆上尋找垃圾(不再被程序使?的內(nèi)存)并清除它們。這?單純的堆空間申請更加具有不確定性。好的解決?案:讓動態(tài)內(nèi)存分配成為可選項Rust語?的標(biāo)準(zhǔn)庫中有很多特性依賴于堆。然?,Rust語?的編譯器?持完全關(guān)閉這些有關(guān)堆的語?特性,并且能夠靜態(tài)地確保這些特性在程序中不被使?。寫出完全不使?堆的Rust程序是完全可?的。Go語?的解決?案:沒有Go語?嚴(yán)重依賴于對堆的運(yùn)?。沒有可?的?式讓Go程序完全不使?堆。這不是Go語?的問題。這在Go語?的?的應(yīng)?領(lǐng)域完全沒
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年游戲化營銷在品牌傳播中的內(nèi)容營銷策略研究報告
- 2025年長沙餐飲行業(yè)企業(yè)戰(zhàn)略規(guī)劃思路方案及未來五年行業(yè)預(yù)測報告
- DB32/T 4560-2023固態(tài)發(fā)酵飼料生產(chǎn)工藝規(guī)程
- DB32/T 4518-2023紫花苜蓿-青貯玉米周年輪作生產(chǎn)技術(shù)規(guī)程
- 2025年裝卸搬運(yùn)設(shè)備項目可行性研究報告項目建議書
- 2025年石灰和石膏項目可行性分析報告
- 2025年中國防水墻行業(yè)市場研究及深度專項調(diào)查投資預(yù)測報告
- 2025年影視文化產(chǎn)業(yè)的數(shù)字化影視制作與發(fā)行的國際版權(quán)合作平臺建設(shè)可行性研究報告
- 2025年熱量表項目投資分析及可行性報告
- 2025-2030中國電蒸籠行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 硫酸的安全培訓(xùn)
- 外國教育史知到智慧樹章節(jié)測試課后答案2024年秋山東師范大學(xué)
- 幼兒教師信息素養(yǎng)養(yǎng)成(運(yùn)城幼兒師范高等專科學(xué)校)知到智慧樹答案
- T-CBDA 70-2023 中小型體育館室內(nèi)裝飾裝修技術(shù)規(guī)程
- 女孩青春期生理健康教育
- 2024年物理實驗室安全教育:從理論到實踐
- 急救藥品的安全管理
- 煤礦居間合同范本
- 公司-績效管理與績效考核制度
- 2024年安裝陽光房訂購協(xié)議書模板
- 網(wǎng)約車停運(yùn)損失賠償協(xié)議書范文
評論
0/150
提交評論