1. 程式人生 > >用VC進行COM程式設計所必須掌握的理論知識

用VC進行COM程式設計所必須掌握的理論知識

<span style="font-size:32px;">一、為什麼要用COM 

  軟體工程發展到今天,從一開始的結構化程式設計,到面向物件程式設計,再到現在的COM程式設計,目標只有一個,就是希望軟體能象積方塊一樣是累起來的,是組裝起來的,而不是一點點編出來的。結構化程式設計是函式塊的形式,通過把一個軟體劃分成許多模組,每個模組完成各自不同的功能,儘量做到高內聚低藕合,這已經是一個很好的開始,我們可以把不同的模組分給不同的人去做,然後合到一塊,這已經有了組裝的概念了。軟體工程的核心就是要模組化,最理想的情況就是100%內聚0%藕合。整個軟體的發展也都是朝著這個方向走的。結構化程式設計方式只是一個開始。下一步就出現了面向物件程式設計,它相對於面向功能的結構化方式是一個巨大的進步。我們知道整個自然界都是由各種各樣不同的事物組成的,事物之間存在著複雜的千絲萬縷的關係,而正是靠著事物之間的聯絡、互動作用,我們的世界才是有生命力的才是活動的。我們可以認為在自然界中事物做為一個概念,它是穩定的不變的,而事物之間的聯絡是多變的、運動的。事物應該是這個世界的本質所在。面向物件的著眼點就是事物,就是這種穩定的概念。每個事物都有其固有的屬性,都有其固有的行為,這些都是事物本身所固有的東西,而面向物件的方法就是描述出這種穩定的東西。而面向功能的模組化方法它的著眼點是事物之間的聯絡,它眼中看不到事物的概念它只注重功能,我們平常在劃分模組的時侯有沒有想過這個函式與哪些物件有關呢?很少有人這麼想,一個函式它實現一種功能,這個功能必定與某些事物想聯絡,我們沒有去掌握事物本身而只考慮事物之間是怎麼相互作用而完成一個功能的。說白了,這叫本末倒置,也叫急功近利,因為不是我們智慧不夠,只是因為我們沒有多想一步。面向功能的結構化方法因為它注意的只是事物之間的聯絡,而聯絡是多變的,事物本身可能不會發生大的變化,而聯絡則是很有可能發生改變的,聯絡一變,那就是另一個世界了,那就是另一種功能了。如果我們用面向物件的方法,我們就可以以不變應萬變,只要事先把事物用類描述好,我們要改變的只是把這些類聯絡起來的方法,只是重新使用我們的類庫,而面向過程的方法因為它構造的是一個不穩定的世界,所以一點小小的變化也可能導致整個系統都要改變。然而面向物件方法仍然有問題,問題在於重用的方法。搭積木式的軟體構造方法的基礎是有許許多多各種各樣的可重用的部件、模組。我們首先想到的是類庫,因為我們用面向物件的方法產生的直接結果就是許多的類。但類庫的重用是基於原始碼的方式,這是它的重大缺陷。首先它限制了程式語言,你的類庫總是用一種語言寫的吧,那你就不能拿到別的語言裡用了。其次你每次都必須重新編譯,只有編譯了才能與你自己的程式碼結合在一起生成可執行檔案。在開發時這倒沒什麼,關鍵在於開發完成後,你的EXE都已經生成好了,如果這時侯你的類庫提供廠商告訴你他們又做好了一個新的類庫,功能更強大速度更快,而你為之心動又想把這新版的類庫用到你自己的程式中,那你就必須重新編譯、重新除錯!這離我們理想的積木式軟體構造方法還有一定差距,在我們的設想裡希望把一個模組拿出來再換一個新的模組是非常方便的事,可是現在不但要重新編譯,還要冒著很大的風險,因為你可能要重新改變你自己的程式碼。另一種重用方式很自然地就想到了是DLL的方式。Windows裡到處是DLL,它是Windows 的基礎,但DLL也有它自己的缺點。總結一下它至少有四點不足。(1)函式重名問題。DLL裡是一個一個的函式,我們通過函式名來呼叫函式,那如果兩個DLL裡有重名的函式怎麼辦?(2)各編譯器對C++函式的名稱修飾不相容問題。對於C++函式,編譯器要根據函式的引數資訊為它生成修飾名,DLL庫裡存的就是這個修飾名,但是不同的編譯器產生修飾的方法不一樣,所以你在VC 裡編寫的DLL在BC裡就可以用不了。不過也可以用extern "C";來強調使用標準的C函式特性,關閉修飾功能,但這樣也喪失了C++的過載多型性功能。(3)路徑問題。放在自己的目錄下面,別人的程式就找不到,放在系統目錄下,就可能有重名的問題。而真正的元件應該可以放在任何地方甚至可以不在本機,使用者根本不需考慮這個問題。(4)DLL與EXE的依賴問題。我們一般都是用隱式連線的方式,就是程式設計的時侯指明用什麼DLL,這種方式很簡單,它在編譯時就把EXE與DLL綁在一起了。如果DLL發行了一個新版本,我們很有必要重新連結一次,因為DLL裡面函式的地址可能已經發生了改變。DLL的缺點就是COM的優點。首先我們要先把握住一點,COM和DLL一樣都是基於二進位制的程式碼重用,所以它不存在類庫重用時的問題。另一個關鍵點是,COM本身也是DLL,既使是ActiveX控制元件.ocx它實際上也是DLL,所以說DLL在還是有重用上有很大的優勢,只不過我們通過制訂複雜的COM協議,通COM本身的機制改變了重用的方法,以一種新的方法來利用DLL,來克服DLL本身所固有的缺陷,從而實現更高一級的重用方法。COM沒有重名問題,因為根本不是通過函式名來呼叫函式,而是通過虛擬函式表,自然也不會有函式名修飾的問題。路徑問題也不復存在,因為是通過查登錄檔來找元件的,放在什麼地方都可以,即使在別的機器上也可以。也不用考慮和EXE的依賴關係了,它們二者之間是鬆散的結合在一起,可以輕鬆的換上元件的一個新版本,而應用程式混然不覺
 

 二、用VC進行COM程式設計,必須要掌握哪些COM理論知識 

  我見過很多人學COM,看完一本書後覺得對COM的原理比較瞭解了,COM也不過如此,可是就是不知道該怎麼程式設計序,我自己也有這種情況,我也是經歷了這樣的階段走過來的。要學COM的基本原理,我推薦的書是《COM技術內幕》。但僅看這樣的書是遠遠不夠的,我們最終的目的是要學會怎麼用COM去程式設計序,而不是拼命的研究COM本身的機制。所以我個人覺得對COM的基本原理不需要花大量的時間去追根問底,沒有必要,是吃力不討好的事。其實我們只需要掌握幾個關鍵概念就夠了。這裡我列出了一些我自己認為是用VC程式設計所必需掌握的幾個關鍵概念。(這裡所說的均是用C++語言條件下的COM程式設計方式) 

 

 (1) COM元件實際上是一個C++類,而介面都是純虛類。元件從介面派生而來。我們可以簡單的用純粹的C++的語法形式來描述COM是個什麼東西:

  class IObject
  {
  public:
    virtual Function1(...) = 0;
    virtual Function2(...) = 0;
    ....
  };
  class MyObject : public IObject
  {
  public:
    virtual Function1(...){...}
    virtual Function2(...){...}
....
  };


  看清楚了嗎?IObject就是我們常說的介面,MyObject就是所謂的COM元件。切記切記介面都是純虛類,它所包含的函式都是純虛擬函式,而且它沒有成員變數。而COM元件就是從這些純虛類繼承下來的派生類,它實現了這些虛擬函式,僅此而已。從上面也可以看出,COM元件是以 C++為基礎的,特別重要的是虛擬函式和多型性的概念,COM中所有函式都是虛擬函式,都必須通過虛擬函式表VTable來呼叫,這一點是無比重要的,必需時刻牢記在心。為了讓大家確切瞭解一下虛擬函式表是什麼樣子,從《COM+技術內幕》中COPY了下面這個示例圖:
 
  (2) COM元件有三個最基本的介面類,分別是IUnknown、IClassFactory、IDispatch。 

  COM規範規定任何元件、任何介面都必須從IUnknown繼承,IUnknown包含三個函式,分別是 QueryInterface、AddRef、Release。這三個函式是無比重要的,而且它們的排列順序也是不可改變的。QueryInterface用於查詢元件實現的其它介面,說白了也就是看看這個元件的父類中還有哪些介面類,AddRef用於增加引用計數,Release用於減少引用計數。引用計數也是COM中的一個非常重要的概念。大體上簡單的說來可以這麼理解,COM元件是個DLL,當客戶程式要用它時就要把它裝到記憶體裡。另一方面,一個元件也不是隻給你一個人用的,可能會有很多個程式同時都要用到它。但實際上DLL只裝載了一次,即記憶體中只有一個COM元件,那COM元件由誰來釋放?由客戶程式嗎?不可能,因為如果你釋放了元件,那別人怎麼用,所以只能由COM元件自己來負責。所以出現了引用計數的概念,COM維持一個計數,記錄當前有多少人在用它,每多一次呼叫計數就加一,少一個客戶用它就減一,當最後一個客戶釋放它的時侯,COM知道已經沒有人用它了,它的使用已經結束了,那它就把它自己給釋放了。引用計數是COM程式設計裡非常容易出錯的一個地方,但所幸VC的各種各樣的類庫裡已經基本上把AddRef的呼叫給隱含了,在我的印象裡,我程式設計的時侯還從來沒有呼叫過AddRef,我們只需在適當的時侯呼叫Release。至少有兩個時侯要記住呼叫Release,第一個是呼叫了 QueryInterface以後,第二個是呼叫了任何得到一個介面的指標的函式以後,記住多查MSDN 以確定某個函式內部是否呼叫了AddRef,如果是的話那呼叫Release的責任就要歸你了。 IUnknown的這三個函式的實現非常規範但也非常煩瑣,容易出錯,所幸的事我們可能永遠也不需要自己來實現它們。 

  IClassFactory的作用是建立COM元件。我們已經知道COM元件實際上就是一個類,那我們平常是怎麼例項化一個類物件的?是用‘new’命令!很簡單吧,COM元件也一樣如此。但是誰來new它呢?不可能是客戶程式,因為客戶程式不可能知道元件的類名字,如果客戶知道元件的類名字那元件的可重用性就要打個大大的折扣了,事實上客戶程式只不過知道一個代表著元件的128位的數字串而已,這個等會再介紹。所以客戶無法自己建立元件,而且考慮一下,如果元件是在遠端的機器上,你還能new出一個物件嗎?所以建立元件的責任交給了一個單獨的物件,這個物件就是類廠。每個元件都必須有一個與之相關的類廠,這個類廠知道怎麼樣建立元件,當客戶請求一個元件物件的例項時,實際上這個請求交給了類廠,由類廠建立元件例項,然後把例項指標交給客戶程式。這個過程在跨程序及遠端建立元件時特別有用,因為這時就不是一個簡單的new操作就可以的了,它必須要經過排程,而這些複雜的操作都交給類廠物件去做了。IClassFactory最重要的一個函式就是CreateInstance,顧名思議就是建立元件例項,一般情況下我們不會直接呼叫它,API函式都為我們封裝好它了,只有某些特殊情況下才會由我們自己來呼叫它,這也是VC編寫COM元件的好處,使我們有了更多的控制機會,而VB給我們這樣的機會則是太少太少了。 

  IDispatch叫做排程介面。它的作用何在呢?這個世上除了C++還有很多別的語言,比如VB、 VJ、VBScript、JavaScript等等。可以這麼說,如果這世上沒有這麼多亂七八糟的語言,那就不會有IDispatch。:-) 我們知道COM元件是C++類,是靠虛擬函式表來呼叫函式的,對於VC來說毫無問題,這本來就是針對C++而設計的,以前VB不行,現在VB也可以用指標了,也可以通過VTable來呼叫函數了,VJ也可以,但還是有些語言不行,那就是指令碼語言,典型的如 VBScript、JavaScript。不行的原因在於它們並不支援指標,連指標都不能用還怎麼用多型性啊,還怎麼調這些虛擬函式啊。唉,沒辦法,也不能置這些指令碼語言於不顧吧,現在網頁上用的都是這些指令碼語言,而分散式應用也是COM元件的一個主要市場,它不得不被這些指令碼語言所呼叫,既然虛擬函式表的方式行不通,我們只能另尋他法了。時勢造英雄,IDispatch應運而生。:-) 排程介面把每一個函式每一個屬性都編上號,客戶程式要呼叫這些函式屬性的時侯就把這些編號傳給IDispatch介面就行了,IDispatch再根據這些編號呼叫相應的函式,僅此而已。當然實際的過程遠比這複雜,僅給一個編號就能讓別人知道怎麼呼叫一個函式那不是天方夜潭嗎,你總得讓別人知道你要呼叫的函式要帶什麼引數,引數型別什麼以及返回什麼東西吧,而要以一種統一的方式來處理這些問題是件很頭疼的事。IDispatch介面的主要函式是Invoke,客戶程式都呼叫它,然後Invoke再呼叫相應的函式,如果看一看MS的類庫裡實現 Invoke的程式碼就會驚歎它實現的複雜了,因為你必須考慮各種引數型別的情況,所幸我們不需要自己來做這件事,而且可能永遠也沒這樣的機會。:-) 

  (3) dispinterface介面、Dual介面以及Custom介面 

  這一小節放在這裡似乎不太合適,因為這是在ATL程式設計時用到的術語。我在這裡主要是想談一下自動化介面的好處及缺點,用這三個術語來解釋可能會更好一些,而且以後遲早會遇上它們,我將以一種通俗的方式來解釋它們,可能並非那麼精確,就好象用虛擬碼來描述演算法一樣。-:) 

  所謂的自動化介面就是用IDispatch實現的介面。我們已經講解過IDispatch的作用了,它的好處就是指令碼語言象VBScript、 JavaScript也能用COM元件了,從而基本上做到了與語言無關它的缺點主要有兩個,第一個就是速度慢效率低。這是顯而易見的,通過虛擬函式表一下子就可以呼叫函數了,而通過Invoke則等於中間轉了道手續,尤其是需要把函式引數轉換成一種規範的格式才去呼叫函式,耽誤了很多時間。所以一般若非是迫不得已我們都想用VTable的方式呼叫函式以獲得高效率。第二個缺點就是隻能使用規定好的所謂的自動化資料型別。如果不用IDispatch我們可以想用什麼資料型別就用什麼型別,VC會自動給我們生成相應的排程程式碼。而用自動化介面就不行了,因為Invoke的實現程式碼是VC事先寫好的,而它不能事先預料到我們要用到的所有型別,它只能根據一些常用的資料型別來寫它的處理程式碼,而且它也要考慮不同語言之間的資料型別轉換問題。所以VC自動化介面生成的排程程式碼只適用於它所規定好的那些資料型別,當然這些資料型別已經足夠豐富了,但不能滿足自定義資料結構的要求。你也可以自己寫排程程式碼來處理你的自定義資料結構,但這並不是一件容易的事。考慮到IDispatch的種種缺點(它還有一個缺點,就是使用麻煩,:-) )現在一般都推薦寫雙介面元件,稱為dual介面,實際上就是從IDispatch繼承的介面。我們知道任何介面都必須從 IUnknown繼承,IDispatch介面也不例外。那從IDispatch繼承的介面實際上就等於有兩個基類,一個是IUnknown,一個是IDispatch,所以它可以以兩種方式來呼叫元件,可以通過 IUnknown用虛擬函式表的方式呼叫介面方法,也可以通過IDispatch::Invoke自動化排程來呼叫。這就有了很大的靈活性,這個元件既可以用於C++的環境也可以用於指令碼語言中,同時滿足了各方面的需要。 

  相對比的,dispinterface是一種純粹的自動化介面,可以簡單的就把它看作是IDispatch介面 (雖然它實際上不是的),這種介面就只能通過自動化的方式來呼叫,COM元件的事件一般都用的是這種形式的介面。 

  Custom介面就是從IUnknown介面派生的類,顯然它就只能用虛擬函式表的方式來呼叫介面了 

  (4) COM元件有三種,程序內、本地、遠端。對於後兩者情況必須排程介面指標及函式引數。 

  COM是一個DLL,它有三種執行模式。它可以是程序內的,即和呼叫者在同一個程序內,也可以和呼叫者在同一個機器上但在不同的程序內,還可以根本就和呼叫者在兩臺機器上。這裡有一個根本點需要牢記,就是COM元件它只是一個DLL,它自己是執行不起來的,必須有一個程序象父親般照顧它才行,即COM元件必須在一個程序內.那誰充當看護人的責任呢?先說說排程的問題。排程是個複雜的問題,以我的知識還講不清楚這個問題,我只是一般性的談談幾個最基本的概念。我們知道對於WIN32程式,每個程序都擁有4GB的虛擬地址空間,每個程序都有其各自的編址,同一個資料塊在不同的程序裡的編址很可能就是不一樣的,所以存在著程序間的地址轉換問題。這就是排程問題。對於本地和遠端程序來說,DLL 和客戶程式在不同的編址空間,所以要傳遞介面指標到客戶程式必須要經過排程。Windows 已經提供了現成的排程函式,就不需要我們自己來做這個複雜的事情了。對遠端元件來說函式的引數傳遞是另外一種排程。DCOM是以RPC為基礎的,要在網路間傳遞資料必須遵守標準的網上資料傳輸協議,資料傳遞前要先打包,傳遞到目的地後要解包,這個過程就是排程,這個過程很複雜,不過Windows已經把一切都給我們做好了,一般情況下我們不需要自己來編寫排程DLL。 

  我們剛說過一個COM元件必須在一個程序內。對於本地模式的元件一般是以EXE的形式出現,所以它本身就已經是一個程序。對於遠端DLL,我們必須找一個程序,這個程序必須包含了排程程式碼以實現基本的排程。這個程序就是dllhost.exe。這是COM預設的DLL代理。實際上在分散式應用中,我們應該用MTS來作為DLL代理,因為MTS有著很強大的功能,是專門的用於管理分散式DLL元件的工具。 

  排程離我們很近又似乎很遠,我們程式設計時很少關注到它,這也是COM的一個優點之一,既平臺無關性,無論你是遠端的、本地的還是程序內的,程式設計是一樣的,一切細節都由COM自己處理好了,所以我們也不用深究這個問題,只要有個概念就可以了,當然如果你對排程有自己特殊的要求就需要深入瞭解排程的整個過程了,這裡推薦一本《COM+技術內幕》,這絕對是一本講排程的好書。 

  (5) COM元件的核心是IDL。 

  我們希望軟體是一塊塊拼裝出來的,但不可能是沒有規定的胡亂拼接,總是要遵守一定的標準,各個模組之間如何才能親密無間的合作,必須要事先共同制訂好它們之間互動的規範,這個規範就是介面。我們知道介面實際上都是純虛類,它裡面定義好了很多的純虛擬函式,等著某個元件去實現它,這個介面就是兩個完全不相關的模組能夠組合在一起的關鍵試想一下如果我們是一個應用軟體廠商,我們的軟體中需要用到某個模組,我們沒有時間自己開發,所以我們想到市場上找一找看有沒有這樣的模組,我們怎麼去找呢?也許我們需要的這個模組在業界已經有了標準,已經有人制訂好了標準的介面,有很多元件工具廠商已經在自己的元件中實現了這個介面,那我們尋找的目標就是這些已經實現了介面的元件,我們不關心元件從哪來,它有什麼其它的功能,我們只關心它是否很好的實現了我們制訂好的介面。這種介面可能是業界的標準,也可能只是你和幾個廠商之間內部制訂的協議,但總之它是一個標準,是你的軟體和別人的模組能夠組合在一起的基礎,是COM元件通訊的標準。 

  COM具有語言無關性,它可以用任何語言編寫,也可以在任何語言平臺上被呼叫。但至今為止我們一直是以C++的環境中談COM,那它的語言無關性是怎麼體現出來的呢?或者換句話說,我們怎樣才能以語言無關的方式來定義介面呢?前面我們是直接用純虛類的方式定義的,但顯然是不行的,除了C++誰還認它呢?正是出於這種考慮,微軟決定採用IDL來定義介面。說白了,IDL實際上就是一種大家都認識的語言,用它來定義介面,不論放到哪個語言平臺上都認識它。我們可以想象一下理想的標準的元件模式,我們總是從IDL開始,先用IDL制訂好各個介面,然後把實現介面的任務分配不同的人,有的人可能善長用VC,有的人可能善長用VB,這沒關係,作為專案負責人我不關心這些,我只關心你把最終的DLL 拿給我。這是一種多麼好的開發模式,可以用任何語言來開發,也可以用任何語言來欣賞你的開發成果。 

  (6) COM元件的執行機制,即COM是怎麼跑起來的。 

  這部分我們將構造一個建立COM元件的最小框架結構,然後看一看其內部處理流程是怎樣的

    IUnknown *pUnk=NULL;
    IObject *pObject=NULL;
    CoInitialize(NULL);
    CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);
    pUnk->QueryInterface(IID_IOjbect, (void**)&pObject);
    pUnk->Release();
    pObject->Func();
    pObject->Release();
    CoUninitialize();
  這就是一個典型的建立COM元件的框架,不過我的興趣在CoCreateInstance身上,讓我們來看看它內部做了一些什麼事情。以下是它內部實現的一個虛擬碼:

    CoCreateInstance(....)
    {
    .......
    IClassFactory *pClassFactory=NULL;
    CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
    pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
    pClassFactory->Release();
    ........
   }
  這段話的意思就是先得到類廠物件,再通過類廠建立元件從而得到IUnknown指標。繼續深入一步,看看CoGetClassObject的內部偽碼:

   CoGetClassObject(.....)
   {
    //通過查登錄檔CLSID_Object,得知元件DLL的位置、檔名
    //裝入DLL庫
    //使用函式GetProcAddress(...)得到DLL庫中函式DllGetClassObject的函式指標。
    //呼叫DllGetClassObject 
   }
    DllGetClassObject是幹什麼的,它是用來獲得類廠物件的。只有先得到類廠才能去建立元件.
    下面是DllGetClassObject的偽碼:
    DllGetClassObject(...)
    {
    ......
    CFactory* pFactory= new CFactory; //類廠物件
    pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
    //查詢IClassFactory指標
    pFactory->Release();
    ......
    }
    CoGetClassObject的流程已經到此為止,現在返回CoCreateInstance,看看CreateInstance的偽碼:
    CFactory::CreateInstance(.....)
    {
    ...........
    CObject *pObject = new CObject; //元件物件
    pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
    pObject->Release();
    ...........
    }
  下圖是從COM+技術內幕中COPY來的一個例圖,從圖中可以清楚的看到CoCreateInstance的整個流程。
 
  (7) 一個典型的自注冊的COM DLL所必有的四個函式 

  DllGetClassObject:用於獲得類廠指標 

  DllRegisterServer:註冊一些必要的資訊到登錄檔中 

  DllUnregisterServer:解除安裝註冊資訊 

  DllCanUnloadNow:系統空閒時會呼叫這個函式,以確定是否可以解除安裝DLL 

  DLL還有一個函式是DllMain,這個函式在COM中並不要求一定要實現它,但是在VC生成的元件中自動都包含了它,它的作用主要是得到一個全域性的例項物件。 

  (8) 登錄檔在COM中的重要作用 

  首先要知道GUID的概念,COM中所有的類、介面、型別庫都用GUID來唯一標識,GUID是一個128位的字串,根據特製演算法生成的GUID可以保證是全世界唯一的。 COM元件的建立,查詢介面都是通過登錄檔進行的。有了登錄檔,應用程式就不需要知道元件的DLL檔名、位置,只需要根據CLSID查就可以了。當版本升級的時侯,只要改一下注冊表資訊就可以神不知鬼不覺的轉到新版本的DLL。</span>

相關推薦

VC進行COM程式設計所必須掌握理論知識

<span style="font-size:32px;">一、為什麼要用COM   軟體工程發展到今天,從一開始的結構化程式設計,到面向物件程式設計,再到現在的COM程式設計,目標只有一個,就是希望軟體能象積方塊一樣是累起來的,是組裝起來的,而不是一點點編

為什麼說 Java 程式設計師必須掌握 Spring Boot ?

Spring Boot 2.0 的推出又激起了一陣學習 Spring Boot 熱,那麼, Spring Boot 誕生的背景是什麼?Spring 企業又是基於什麼樣的考慮建立 Spring Boot? 傳統企業使用 Spring Boot 會給我們帶來什麼樣變革?   帶著這些問題,我們一起來

程式設計師必須掌握的600個英語單詞(轉自網路)

程式設計師必須掌握的600個英語單詞(轉自網路) application 應用程式 應用、應用程式 application framework 應用程式框架、應用框架 應用程式框架 architecture 架構、系統架構 體系結構 argument 引數(傳給函式的值)。叄見 para

程式設計師必須掌握的600個單詞

application 應用程式 應用、應用程式 application framework 應用程式框架、應用框架 應用程式框架 architecture 架構、系統架構 體系結構 argument 引數(傳給函式的值)。叄見 parameter 叄數、實質叄數、實叄、自變數&

為什麼說java程式設計師必須掌握Spring Boot?

Spring Boot——約定優於配置 一、導言 二、Spring歷史 三、Spring Boot的誕生與發展 四、Spring Boot介紹 五、Spring Boot特性及優點 六、Spring、Spring Boot和Spring C

為什麼說 Java 程式設計師必須掌握 Spring Boot?

Spring Boot 2.0 的推出又激起了一陣學習 Spring Boot 熱,那麼, Spring Boot 誕生的背景是什麼?Spring 企業又是基於什麼樣的考慮建立 Spring Boot? 傳統企業使用 Spring Boot 會給我們帶來什麼樣變革? 帶著這些問題,我們一

Java程式設計師必須掌握的常用Linux命令。

Java程式設計師也是半個運維了,在日常開發中經常會接觸到Linux環境操作。小公司的開發人員甚至是兼了全運維的工作,下面整理了一些常用的Linux操作命令。 Linux常用指令 ls   顯示檔案或目錄      -l   列出檔案詳細資訊l(list)      

【面試總結】涵蓋1-3年Java程式設計師必須掌握的面試技巧

前言 金三銀四,金九銀十,大多數程式設計師都會選擇在這兩個時機跳槽(認為公司沒發展,沒有提升空間,對上級領導不滿意的,薪資漲不了,忍了好長時間爆發的機會終於來了)同時也是求職者找工作的好機會。近期有很多朋友也問到了求職方面的問題,那麼如何在面試中脫穎而出呢?這裡

Java程式設計師必須掌握的網站知識 —— HTTP

介紹 HTTP協議是Hyper Text Transfer Protocol(超文字傳輸協議)的縮寫,是用於從全球資訊網(WWW:World Wide Web )伺服器傳輸超文字到本地瀏覽器的傳送協議。 HTTP是一個基於TCP/IP通訊協議來傳遞資料(HTML 檔案,

Java 程式設計師必須掌握的 8 道資料結構面試題,你會幾道

瑞士電腦科學家Niklaus Wirth在1976年寫了一本書,名為《演算法+資料結構=程式設計》。 40多年後,這個等式仍被奉為真理。這就是為什麼在面試過程中,需要考察軟體工程師對資料結構的理解。 幾乎所有的問題都需要面試者對資料結構有深刻的理解。無論你是初入職場的

程式設計師必須掌握的600個英語單詞

application 應用程式 應用、應用程式 application framework 應用程式框架、應用框架 應用程式框架 architecture 架構、系統架構 體系結構 argument 引數(傳給函式的值)。叄見 parameter 叄數、實質叄數、實叄

【本人禿頂程式設計師】【程式人生】為什麼說 Java 程式設計師必須掌握 Spring Boot

←←←←←←←←←←←← 我都禿頂了,還不點關注! Spring Boot 誕生的背景是什麼?Spring 企業又是基於什麼樣的考慮建立 Spring Boot? 傳統企業使用 Spring Boot 會給我們帶來什麼樣變革? Spring Boot 2.0 的推出又激起了

為什麼說JAVA程式設計師必須掌握SpringBoot?

Spring Boot 2.0 的推出又激起了一陣學習 Spring Boot 熱,那麼, Spring Boot 誕生的背景是什麼?Spring 企業又是基於什麼樣的考慮建立 Spring Boot? 傳統企業使用 Spring Boot 會給我們帶來什麼樣變革?   帶

為什麼說Java 程式設計師必須掌握 Spring Boot?

大部分人選擇學習Java,自然是因為看上了Java的薪資待遇,java的地位可謂在程式設計界屬於大佬,最近Spring Boot 2.0 的推出來後,又激起了一陣學習 Spring Boot 的熱潮,那麼, 使用 Spring Boot 會帶來什麼樣的變革?一起來了解下 Spring Boot 到底

VC進行64位程式設計

本文討論: • 64 位版本 Windows 的背景資訊 • 適當地利用 x64 體系結構 • 使用 Visual C++ 2005 進行 x64 開發 • 針對 x64 版本的除錯技術

程式設計師必須掌握的十種演算法---Dijkstra演算法

由荷蘭電腦科學家艾茲赫爾·戴克斯特拉提出的使用了廣度優先搜尋解決非負權有向圖的單源最短路徑問題。 #include<stdio.h> int main() { /* *e儲存圖的矩陣表示 *dis儲存1號頂點到其餘各個頂

程式設計師必須掌握的十種演算法---堆排序演算法

堆排序,就是利用完全二叉樹的某些特性對陣列進行排序。 #include<stdio.h> int h[101];//用來存放堆的陣列 int n;//用來儲存堆中元素的個數,也就是堆的

Java常用排序演算法/程式設計師必須掌握的8大排序演算法

本文由網路資料整理而來,如有問題,歡迎指正! 分類: 1)插入排序(直接插入排序、希爾排序) 2)交換排序(氣泡排序、快速排序) 3)選擇排序(直接選擇排序、堆排序) 4)歸併排序 5)分配排序(基數排序) 所需輔助空間最多:歸併排序 所需輔助空間最少:堆排序 平均速度最快

python進行應用程式自動化測試(uiautomation)

        本文主要用到一個uiautomation的開源框架,是一個咱們中國人寫的,支援MFC,Windows Forms,WPF,Metro,Qt介面;此文主要是自己的個人總結,開源作者原文:http://www.cnblogs.com/Yinkaisheng/p/3444132.html

Java程式設計師必須掌握的常用Linux命令

轉載自 https://www.cnblogs.com/javastack/p/8796178.htmlJava程式設計師也是半個運維了,在日常開發中經常會接觸到Linux環境操作。小公司的開發人員甚至是兼了全運維的工作,下面整理了一些常用的Linux操作命令。Linux常用