




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 1. C#語(yǔ)言方面 1.1 垃圾回收 垃圾回收解放了手工管理對(duì)象的工作,提高了程序的健壯性,但副作用就是程序代碼可能對(duì)于對(duì)象創(chuàng)建變得隨意。 1.1.1 避免不必要的對(duì)象創(chuàng)建 由于垃圾回收的代價(jià)較高,所以C#程序開發(fā)要遵循的一個(gè)基本原則就是避免不必要的對(duì)象創(chuàng)建。以下列舉一些常見的情形。 避免循環(huán)創(chuàng)建對(duì)象 如果對(duì)象并不會(huì)隨每次循環(huán)而改變狀態(tài),那么在循環(huán)中反復(fù)創(chuàng)建對(duì)象將帶來性能損耗。高效的做法是將對(duì)象提到循環(huán)外面創(chuàng)建。 在需要邏輯分支中創(chuàng)建對(duì)象 如果對(duì)象只在某些邏輯分支中才被用到,那么應(yīng)只在該邏輯分支中創(chuàng)建對(duì)象。 使用常量避免創(chuàng)建對(duì)象 程序中不應(yīng)出現(xiàn)
2、如 new Decimal(0) 之類的代碼,這會(huì)導(dǎo)致小對(duì)象頻繁創(chuàng)建及回收,正確的做法是使用Decimal.Zero常量。我們有設(shè)計(jì)自己的類時(shí),也可以學(xué)習(xí)這個(gè)設(shè)計(jì)手法,應(yīng)用到類似的場(chǎng)景中。 使用StringBuilder做字符串連接 1.1.2 不要使用空析構(gòu)函數(shù) 如果類包含析構(gòu)函數(shù),由創(chuàng)建對(duì)象時(shí)會(huì)在 Finalize 隊(duì)列中添加對(duì)象的引用,以保證當(dāng)對(duì)象無法可達(dá)時(shí),仍然可以調(diào)用到 Finalize 方法。垃圾回收器在運(yùn)行期間,會(huì)啟動(dòng)一個(gè)低優(yōu)先級(jí)的線程處理該隊(duì)列。相比之下,沒有析構(gòu)函數(shù)的對(duì)象就沒有這些消耗。如果析構(gòu)函數(shù)為空,這個(gè)消耗就毫無意義,只會(huì)導(dǎo)致性能降低!因此,不要使用空的
3、析構(gòu)函數(shù)。 在實(shí)際情況中,許多曾在析構(gòu)函數(shù)中包含處理代碼,但后來因?yàn)榉N種原因被注釋掉或者刪除掉了,只留下一個(gè)空殼,此時(shí)應(yīng)注意把析構(gòu)函數(shù)本身注釋掉或刪除掉。 1.1.3 實(shí)現(xiàn) IDisposable 接口 垃圾回收事實(shí)上只支持托管內(nèi)在的回收,對(duì)于其他的非托管資源,例如 Window GDI 句柄或數(shù)據(jù)庫(kù)連接,在析構(gòu)函數(shù)中釋放這些資源有很大問題。原因是垃圾回收依賴于內(nèi)在緊張的情況,雖然數(shù)據(jù)庫(kù)連接可能已瀕臨耗盡,但如果內(nèi)存還很充足的話,垃圾回收是不會(huì)運(yùn)行的。 C#的 IDisposable 接口是一種顯式釋放資源的機(jī)制。通過提供 using 語(yǔ)句,還簡(jiǎn)化了使用方式(編譯器自動(dòng)生成 try . fin
4、ally 塊,并在 finally 塊中調(diào)用 Dispose 方法)。對(duì)于申請(qǐng)非托管資源對(duì)象,應(yīng)為其實(shí)現(xiàn) IDisposable 接口,以保證資源一旦超出 using 語(yǔ)句范圍,即得到及時(shí)釋放。這對(duì)于構(gòu)造健壯且性能優(yōu)良的程序非常有意義!為防止對(duì)象的 Dispose 方法不被調(diào)用的情況發(fā)生,一般還要提供析構(gòu)函數(shù),兩者調(diào)用一個(gè)處理資源釋放的公共方法。同時(shí),Dispose 方法應(yīng)調(diào)用 System.GC.SuppressFinalize(this),告訴垃圾回收器無需再處理 Finalize 方法了。PS:using語(yǔ)句的確能簡(jiǎn)化tryfinally的代碼編寫,并自動(dòng)調(diào)用對(duì)象的Dispose方法,但
5、是,并不總能夠在大括號(hào)的右邊正確調(diào)用Dispose方式。你需要根據(jù)對(duì)象Dispose方法產(chǎn)生異常的可能性來決定是使用using,還是顯示的trycatchfinally。 1.2 String 操作 1.2.1 使用 StringBuilder 做字符串連接 String 是不變類,使用 + 操作連接字符串將會(huì)導(dǎo)致創(chuàng)建一個(gè)新的字符串。如果字符串連接次數(shù)不是固定的,例如在一個(gè)循環(huán)中,則應(yīng)該使用 StringBuilder 類來做字符串連接工作。因?yàn)?StringBuilder 內(nèi)部有一個(gè) StringBuffer ,連接操作不會(huì)每次分配新的字符串空間。只有當(dāng)連接后的字符串超出 Buffer 大小
6、時(shí),才會(huì)申請(qǐng)新的 Buffer 空間。典型代碼如下: StringBuilder sb = new StringBuilder( 256 ); for ( int i = 0 ; i Results.Count; i + ) sb.Append (Resultsi); 如果連接次數(shù)是固定的并且只有幾次,此時(shí)應(yīng)該直接用 + 號(hào)連接,保持程序簡(jiǎn)潔易讀。實(shí)際上,編譯器已經(jīng)做了優(yōu)化,會(huì)依據(jù)加號(hào)次數(shù)調(diào)用不同參數(shù)個(gè)數(shù)的 String.Concat 方法。例如: String str = str1 + str2 + str3 + str4; 會(huì)被編譯為 String.Concat(str1, str2, s
7、tr3, str4)。該方法內(nèi)部會(huì)計(jì)算總的 String 長(zhǎng)度,僅分配一次,并不會(huì)如通常想象的那樣分配三次。作為一個(gè)經(jīng)驗(yàn)值,當(dāng)字符串連接操作達(dá)到 10 次以上時(shí),則應(yīng)該使用 StringBuilder。 這里有一個(gè)細(xì)節(jié)應(yīng)注意:StringBuilder 內(nèi)部 Buffer 的缺省值為 16 ,這個(gè)值實(shí)在太小。按 StringBuilder 的使用場(chǎng)景,Buffer 肯定得重新分配。經(jīng)驗(yàn)值一般用 256 作為 Buffer 的初值。當(dāng)然,如果能計(jì)算出最終生成字符串長(zhǎng)度的話,則應(yīng)該按這個(gè)值來設(shè)定 Buffer 的初值。使用 new StringBuilder(256) 就將 Buffer 的初始長(zhǎng)
8、度設(shè)為了256。 1.2.2 避免不必要的調(diào)用 ToUpper 或 ToLower 方法 String是不變類,調(diào)用ToUpper或ToLower方法都會(huì)導(dǎo)致創(chuàng)建一個(gè)新的字符串。如果被頻繁調(diào)用,將導(dǎo)致頻繁創(chuàng)建字符串對(duì)象。這違背了前面講到的“避免頻繁創(chuàng)建對(duì)象”這一基本原則。 例如,bool.Parse方法本身已經(jīng)是忽略大小寫的,調(diào)用時(shí)不要調(diào)用ToLower方法。 另一個(gè)非常普遍的場(chǎng)景是字符串比較。高效的做法是使用 Compare 方法,這個(gè)方法可以做大小寫忽略的比較,并且不會(huì)創(chuàng)建新字符串。 還有一種情況是使用 HashTable 的時(shí)候,有時(shí)候無法保證傳遞 key 的大小寫是否符合預(yù)期,往往會(huì)把
9、 key 強(qiáng)制轉(zhuǎn)換到大寫或小寫方法。實(shí)際上 HashTable 有不同的構(gòu)造形式,完全支持采用忽略大小寫的 key: new HashTable(StringComparer.OrdinalIgnoreCase)。 1.2.3 最快的空串比較方法 將String對(duì)象的Length屬性與0比較是最快的方法:if (str.Length = 0) 其次是與String.Empty常量或空串比較:if (str = String.Empty)或if (str = ) 注:C#在編譯時(shí)會(huì)將程序集中聲明的所有字符串常量放到保留池中(intern pool),相同常量不會(huì)重復(fù)分配。 1.3 多線程 1.3
10、.1 線程同步 線程同步是編寫多線程程序需要首先考慮問題。C#為同步提供了 Monitor、Mutex、AutoResetEvent 和 ManualResetEvent 對(duì)象來分別包裝 Win32 的臨界區(qū)、互斥對(duì)象和事件對(duì)象這幾種基礎(chǔ)的同步機(jī)制。C#還提供了一個(gè)lock語(yǔ)句,方便使用,編譯器會(huì)自動(dòng)生成適當(dāng)?shù)?Monitor.Enter 和 Monitor.Exit 調(diào)用。 同步粒度 同步粒度可以是整個(gè)方法,也可以是方法中某一段代碼。為方法指定 MethodImplOptions.Synchronized 屬性將標(biāo)記對(duì)整個(gè)方法同步。例如: MethodImpl(MethodI
11、mplOptions.Synchronized) public static SerialManager GetInstance() if (instance = null ) instance = new SerialManager(); return instance; 通常情況下,應(yīng)減小同步的范圍,使系統(tǒng)獲得更好的性能。簡(jiǎn)單將整個(gè)方法標(biāo)記為同步不是一個(gè)好主意,除非能確定方法中的每個(gè)代碼都需要受同步保護(hù)。 同步策略 使用 lock 進(jìn)行同步,同步對(duì)象可以選擇 Type、this 或?yàn)橥侥康膶iT構(gòu)造的成員變量。 避免鎖定Type 鎖定Type對(duì)象會(huì)影響同一進(jìn)程中所有AppD
12、omain該類型的所有實(shí)例,這不僅可能導(dǎo)致嚴(yán)重的性能問題,還可能導(dǎo)致一些無法預(yù)期的行為。這是一個(gè)很不好的習(xí)慣。即便對(duì)于一個(gè)只包含static方法的類型,也應(yīng)額外構(gòu)造一個(gè)static的成員變量,讓此成員變量作為鎖定對(duì)象。 避免鎖定 this 鎖定 this 會(huì)影響該實(shí)例的所有方法。假設(shè)對(duì)象 obj 有 A 和 B 兩個(gè)方法,其中 A 方法使用 lock(this) 對(duì)方法中的某段代碼設(shè)置同步保護(hù)?,F(xiàn)在,因?yàn)槟撤N原因,B 方法也開始使用 lock(this) 來設(shè)置同步保護(hù)了,并且可能為了完全不同的目的。這樣,A 方法就被干擾了,其行為可能無法預(yù)知。所以,作為一種良好的習(xí)慣,建議避免使用 lock
13、(this) 這種方式。 使用為同步目的專門構(gòu)造的成員變量 這是推薦的做法。方式就是 new 一個(gè) object 對(duì)象, 該對(duì)象僅僅用于同步目的。 如果有多個(gè)方法都需要同步,并且有不同的目的,那么就可以為些分別建立幾個(gè)同步成員變量。 集合同步 C#為各種集合類型提供了兩種方便的同步機(jī)制:Synchronized 包裝器和 SyncRoot 屬性。 / Creates and initializes a new ArrayList ArrayList myAL = new ArrayList();myAL.Add( The );myAL.Add( quick );myAL.Add
14、( brown );myAL.Add( fox ); / Creates a synchronized wrapper around the ArrayList ArrayList mySyncdAL = ArrayList.Synchronized(myAL); 調(diào)用 Synchronized 方法會(huì)返回一個(gè)可保證所有操作都是線程安全的相同集合對(duì)象??紤] mySyncdAL0 = mySyncdAL0 + test 這一語(yǔ)句,讀和寫一共要用到兩個(gè)鎖。一般講,效率不高。推薦使用 SyncRoot 屬性,可以做比較精細(xì)的控制。 1.3.2 使用 ThreadStatic 替代 NameDataS
15、lot 存取 NameDataSlot 的 Thread.GetData 和 Thread.SetData 方法需要線程同步,涉及兩個(gè)鎖:一個(gè)是 LocalDataStore.SetData 方法需要在 AppDomain 一級(jí)加鎖,另一個(gè)是 ThreadNative.GetDomainLocalStore 方法需要在 Process 一級(jí)加鎖。如果一些底層的基礎(chǔ)服務(wù)使用了 NameDataSlot,將導(dǎo)致系統(tǒng)出現(xiàn)嚴(yán)重的伸縮性問題。 規(guī)避這個(gè)問題的方法是使用 ThreadStatic 變量。示例如下: public sealed class InvokeContext ThreadStatic
16、 private static InvokeContext current; private Hashtable maps = new Hashtable(); 1.3.3 多線程編程技巧 使用 Double Check 技術(shù)創(chuàng)建對(duì)象 internal IDictionary KeyTable get if ( this ._keyTable = null ) lock ( base ._lock) if ( this ._keyTable = null ) this ._keyTable = new Hashtable(); return this ._keyTable; 創(chuàng)
17、建單例對(duì)象是很常見的一種編程情況。一般在 lock 語(yǔ)句后就會(huì)直接創(chuàng)建對(duì)象了,但這不夠安全。因?yàn)樵?lock 鎖定對(duì)象之前,可能已經(jīng)有多個(gè)線程進(jìn)入到了第一個(gè) if 語(yǔ)句中。如果不加第二個(gè) if 語(yǔ)句,則單例對(duì)象會(huì)被重復(fù)創(chuàng)建,新的實(shí)例替代掉舊的實(shí)例。如果單例對(duì)象中已有數(shù)據(jù)不允許被破壞或者別的什么原因,則應(yīng)考慮使用 Double Check 技術(shù)。 1.4 類型系統(tǒng) 1.4.1 避免無意義的變量初始化動(dòng)作 CLR保證所有對(duì)象在訪問前已初始化,其做法是將分配的內(nèi)存清零。因此,不需要將變量重新初始化為0、false或null。 需要注意的是:方法中的局部變量不是從堆而是從棧上分配,所以C#不會(huì)做清零工
18、作。如果使用了未賦值的局部變量,編譯期間即會(huì)報(bào)警。不要因?yàn)橛羞@個(gè)印象而對(duì)所有類的成員變量也做賦值動(dòng)作,兩者的機(jī)理完全不同! 1.4.2 ValueType 和 ReferenceType 以引用方式傳遞值類型參數(shù) 值類型從調(diào)用棧分配,引用類型從托管堆分配。當(dāng)值類型用作方法參數(shù)時(shí),默認(rèn)會(huì)進(jìn)行參數(shù)值復(fù)制,這抵消了值類型分配效率上的優(yōu)勢(shì)。作為一項(xiàng)基本技巧,以引用方式傳遞值類型參數(shù)可以提高性能。 為 ValueType 提供 Equals 方法 .net 默認(rèn)實(shí)現(xiàn)的 ValueType.Equals 方法使用了反射技術(shù),依靠反射來獲得所有成員變量值做比較,這個(gè)效率極低。
19、如果我們編寫的值對(duì)象其 Equals 方法要被用到(例如將值對(duì)象放到 HashTable 中),那么就應(yīng)該重載 Equals 方法。 public struct Rectangle public double Length; public double Breadth; public override bool Equals ( object ob) if (ob is Rectangle) return Equels (Rectangle)ob) else return false ; private bool Equals (Rectangle rect) return this .Len
20、gth = rect.Length & this .Breadth = rect.Breach; 避免裝箱和拆箱 C#可以在值類型和引用類型之間自動(dòng)轉(zhuǎn)換,方法是裝箱和拆箱。裝箱需要從堆上分配對(duì)象并拷貝值,有一定性能消耗。如果這一過程發(fā)生在循環(huán)中或是作為底層方法被頻繁調(diào)用,則應(yīng)該警惕累計(jì)的效應(yīng)。 一種經(jīng)常的情形出現(xiàn)在使用集合類型時(shí)。例如: ArrayList al = new ArrayList(); for ( int i = 0 ; i 1000 ; i + ) al.Add(i); / Implicitly boxed because Add() takes an obje
21、ct int f = ( int )al 0 ; / The element is unboxed 1.5 異常處理 異常也是現(xiàn)代語(yǔ)言的典型特征。與傳統(tǒng)檢查錯(cuò)誤碼的方式相比,異常是強(qiáng)制性的(不依賴于是否忘記了編寫檢查錯(cuò)誤碼的代碼)、強(qiáng)類型的、并帶有豐富的異常信息(例如調(diào)用棧)。 1.5.1 不要吃掉異常 關(guān)于異常處理的最重要原則就是:不要吃掉異常。這個(gè)問題與性能無關(guān),但對(duì)于編寫健壯和易于排錯(cuò)的程序非常重要。這個(gè)原則換一種說法,就是不要捕獲那些你不能處理的異常。 吃掉異常是極不好的習(xí)慣,因?yàn)槟阆私鉀Q問題的線索。一旦出現(xiàn)錯(cuò)誤,定位問題將非常困難。除了這種完全吃掉異常的方式外,只將異常信息寫入日
22、志文件但并不做更多處理的做法也同樣不妥。 1.5.2 不要吃掉異常信息 有些代碼雖然拋出了異常,但卻把異常信息吃掉了。 為異常披露詳盡的信息是程序員的職責(zé)所在。如果不能在保留原始異常信息含義的前提下附加更豐富和更人性化的內(nèi)容,那么讓原始的異常信息直接展示也要強(qiáng)得多。千萬(wàn)不要吃掉異常。 1.5.3 避免不必要的拋出異常 拋出異常和捕獲異常屬于消耗比較大的操作,在可能的情況下,應(yīng)通過完善程序邏輯避免拋出不必要不必要的異常。與此相關(guān)的一個(gè)傾向是利用異常來控制處理邏輯。盡管對(duì)于極少數(shù)的情況,這可能獲得更為優(yōu)雅的解決方案,但通常而言應(yīng)該避免。 1.5.4 避免不必要的重新拋出異常 如果是為了包裝異常的目
23、的(即加入更多信息后包裝成新異常),那么是合理的。但是有不少代碼,捕獲異常沒有做任何處理就再次拋出,這將無謂地增加一次捕獲異常和拋出異常的消耗,對(duì)性能有傷害。 1.6 反射 反射是一項(xiàng)很基礎(chǔ)的技術(shù),它將編譯期間的靜態(tài)綁定轉(zhuǎn)換為延遲到運(yùn)行期間的動(dòng)態(tài)綁定。在很多場(chǎng)景下(特別是類框架的設(shè)計(jì)),可以獲得靈活易于擴(kuò)展的架構(gòu)。但帶來的問題是與靜態(tài)綁定相比,動(dòng)態(tài)綁定會(huì)對(duì)性能造成較大的傷害。 1.6.1 反射分類 type comparison :類型判斷,主要包括 is 和 typeof 兩個(gè)操作符及對(duì)象實(shí)例上的 GetType 調(diào)用。這是最輕型的消耗,可以無需考慮優(yōu)化問題。注意 typeof 運(yùn)算符比對(duì)象
24、實(shí)例上的 GetType 方法要快,只要可能則優(yōu)先使用 typeof 運(yùn)算符。 member enumeration : 成員枚舉,用于訪問反射相關(guān)的元數(shù)據(jù)信息,例如Assembly.GetModule、Module.GetType、Type對(duì)象上的IsInterface、IsPublic、GetMethod、GetMethods、GetProperty、GetProperties、GetConstructor調(diào)用等。盡管元數(shù)據(jù)都會(huì)被CLR緩存,但部分方法的調(diào)用消耗仍非常大,不過這類方法調(diào)用頻度不會(huì)很高,所以總體看性能損失程度中等。 member invocation:成員調(diào)用,包括動(dòng)態(tài)創(chuàng)建對(duì)
25、象及動(dòng)態(tài)調(diào)用對(duì)象方法,主要有Activator.CreateInstance、Type.InvokeMember等。 1.6.2 動(dòng)態(tài)創(chuàng)建對(duì)象 C#主要支持 5 種動(dòng)態(tài)創(chuàng)建對(duì)象的方式: 1. Type.InvokeMember 2. ContructorInfo.Invoke 3. Activator.CreateInstance(Type) 4. Activator.CreateInstance(assemblyName, typeName) 5. Assembly.CreateInstance(typeName) 最快的是方式 3 ,與 Direct Create 的差異在一個(gè)數(shù)量級(jí)之內(nèi),
26、約慢 7 倍的水平。其他方式,至少在 40 倍以上,最慢的是方式 4 ,要慢三個(gè)數(shù)量級(jí)。 1.6.3 動(dòng)態(tài)方法調(diào)用 方法調(diào)用分為編譯期的早期綁定和運(yùn)行期的動(dòng)態(tài)綁定兩種,稱為Early-Bound Invocation和Late-Bound Invocation。Early-Bound Invocation可細(xì)分為Direct-call、Interface-call和Delegate-call。Late-Bound Invocation主要有Type.InvokeMember和MethodBase.Invoke,還可以通過使用LCG(Lightweight Code Generation)技術(shù)生
27、成IL代碼來實(shí)現(xiàn)動(dòng)態(tài)調(diào)用。 從測(cè)試結(jié)果看,相比Direct Call,Type.InvokeMember要接近慢三個(gè)數(shù)量級(jí);MethodBase.Invoke雖然比Type.InvokeMember要快三倍,但比Direct Call仍慢270倍左右??梢妱?dòng)態(tài)方法調(diào)用的性能是非常低下的。我們的建議是:除非要滿足特定的需求,否則不要使用! 1.6.4 推薦的使用原則 模式 1 如果可能,則避免使用反射和動(dòng)態(tài)綁定 2 使用接口調(diào)用方式將動(dòng)態(tài)綁定改造為早期綁定 3 使用Activator.CreateInstance(Type)方式動(dòng)態(tài)創(chuàng)建對(duì)象 4 使用typeof操作符代替GetType調(diào)用 反模
28、式 1 在已獲得Type的情況下,卻使用Assembly.CreateInstance(type.FullName) 1.7 基本代碼技巧 這里描述一些應(yīng)用場(chǎng)景下,可以提高性能的基本代碼技巧。對(duì)處于關(guān)鍵路徑的代碼,進(jìn)行這類的優(yōu)化還是很有意義的。普通代碼可以不做要求,但養(yǎng)成一種好的習(xí)慣也是有意義的。 1.7.1 循環(huán)寫法 可以把循環(huán)的判斷條件用局部變量記錄下來。局部變量往往被編譯器優(yōu)化為直接使用寄存器,相對(duì)于普通從堆或棧中分配的變量速度快。如果訪問的是復(fù)雜計(jì)算屬性的話,提升效果將更明顯。for (int i = 0, j = collection.GetIndexOf(item); i j; i
29、+) 需要說明的是:這種寫法對(duì)于CLR集合類的Count屬性沒有意義,原因是編譯器已經(jīng)按這種方式做了特別的優(yōu)化。 1.7.2 拼裝字符串 拼裝好之后再刪除是很低效的寫法。有些方法其循環(huán)長(zhǎng)度在大部分情況下為1,這種寫法的低效就更為明顯了: public static string ToString(MetadataKey entityKey) string str = ; object vals = entityKey.values; for ( int i = 0 ; i vals.Length; i + ) str += , + valsi.ToString(); return str =
30、? : str.Remove( 0 , 1 ); 推薦下面的寫法: if (str.Length = 0 ) str = valsi.ToString(); else str += , + valsi.ToString(); 其實(shí)這種寫法非常自然,而且效率很高,完全不需要用個(gè)Remove方法繞來繞去。 1.7.3 避免兩次檢索集合元素 獲取集合元素時(shí),有時(shí)需要檢查元素是否存在。通常的做法是先調(diào)用ContainsKey(或Contains)方法,然后再獲取集合元素。這種寫法非常符合邏輯。 但如果考慮效率,可以先直接獲取對(duì)象,然后判斷對(duì)象是否為null來確定元素是否存在。對(duì)于Hashtable,這
31、可以節(jié)省一次GetHashCode調(diào)用和n次Equals比較。如下面的示例: public IData GetItemByID(Guid id) IData data1 = null ; if ( this .idTable.ContainsKey(id.ToString() data1 = this .idTableid.ToString() as IData; return data1; 其實(shí)完全可用一行代碼完成:return this.idTableid as IData; 1.7.4 避免兩次類型轉(zhuǎn)換 考慮如下示例,其中包含了兩處類型轉(zhuǎn)換: if (obj is SomeType) SomeType st = (SomeType
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)校秋季志愿服務(wù)計(jì)劃
- 制定有效的輪崗計(jì)劃
- 教學(xué)工作總結(jié)規(guī)劃執(zhí)行情況安排布置計(jì)劃
- 提升效率的年度工作流程計(jì)劃
- 優(yōu)化住院患者出院管理的措施計(jì)劃
- 聚焦品牌合作與推廣的策略計(jì)劃
- 《貴州久泰邦達(dá)能源開發(fā)有限公司盤縣紅果鎮(zhèn)苞谷山煤礦(優(yōu)化重組)調(diào)整礦產(chǎn)資源綠色開發(fā)利用方案(三合一)》評(píng)審意見
- 2025年舟山貨運(yùn)上崗證考試題庫(kù)答案
- 大單元集備《光現(xiàn)象》(教學(xué)設(shè)計(jì))-2023-2024人教版物理八年級(jí)上冊(cè)
- 人教版小學(xué)四年級(jí)語(yǔ)文下冊(cè)2024-2025學(xué)年度第二學(xué)期期末質(zhì)量檢測(cè)試卷
- 建設(shè)工程施工專業(yè)分包合同 GF-2003-0213
- 2024解析:第二章聲現(xiàn)象-講核心(解析版)
- 2025年初級(jí)社會(huì)工作者綜合能力全國(guó)考試題庫(kù)(含答案)
- 2024解析:第十章 浮力綜合應(yīng)用-講核心(解析版)
- Unit4BodylanguageUsingLanguage肢體語(yǔ)言在續(xù)寫中的運(yùn)用課件高中英語(yǔ)人教版選擇性
- 大數(shù)據(jù)與人工智能營(yíng)銷(南昌大學(xué))知到智慧樹章節(jié)答案
- 《讓座》(課件)西師大版音樂二年級(jí)上冊(cè)
- 廣告創(chuàng)作與視覺傳媒考核試卷
- 2024年江西省公務(wù)員考試《行測(cè)》真題及答案解析
- 醫(yī)學(xué)裝備管理工作總結(jié)
- 2024-2025學(xué)年湖南省雅禮集團(tuán)高二(上)第一次月考數(shù)學(xué)試卷(含答案)
評(píng)論
0/150
提交評(píng)論