A. 用ld怎樣連接用了STL的c++程序
STL中沒有那麼高深的東西...
STL實際上也只規定各種容器應該滿足的操作復雜度之類,沒有規定具體的數據結構
比如map一般用紅黑樹實現,但也不排除有編譯器願意用avl樹實現
至於後面兩個我名字都沒聽說過的東西,在STL中是不會有直接的對應的
B. 那位給個思路!只學過c++
其實c++stl里頭的std::set和std::unordered_set可以提供一些思路,如果你不怕麻煩的話,這2種結構是比較優的,std::set採用的是紅黑樹實現,std::unordered_set(在支持c++11特性的編譯器中可用)採用哈希表實現,可以實現交並差方法,如果你想這么做的話(當然非常鼓勵去研究一下stl的源代碼,盡管可能很難看),必須具有較好的數據結構及其復雜度的知識。這是thehardway!
如果想偷懶,用線性結構(如在std::vector這種動態數組上封裝,或者std::list這種雙鏈表上封裝皆可)來實現,但是你必須清楚,這樣損失了某些操作的效率,如集合中元素的查詢或者插入、刪除。這是theeasyway!
你可以再想一想。希望你能明白我說的意思。如果你沒用過std::set或者std::unordered_set,強烈建議先用一下,看看它們提供的介面,玩一玩,不知道的api搜索cppreference的website。python中也有set這個類型,也可以玩玩。
給一段代碼,可以玩玩找一下感覺:
#include<iostream>
#include<set>
#include<algorithm>
#include<iterator>
voidfeedNumbers(intstart,intend,intdivisor,std::set<int>&s);
voidshow(std::set<int>&s);
intmain()
{
std::set<int>a,b,c,d,e,f;
feedNumbers(0,100,2,a);
feedNumbers(0,100,3,b);
show(a);
show(b);
std::set_intersection(a.begin(),a.end(),b.begin(),b.end(),std::inserter(c,c.end()));
std::set_union(a.begin(),a.end(),b.begin(),b.end(),std::inserter(d,d.end()));
std::set_difference(a.begin(),a.end(),b.begin(),b.end(),std::inserter(e,e.end()));
std::set_difference(b.begin(),b.end(),a.begin(),a.end(),std::inserter(f,f.end()));
show(c);
show(d);
show(e);
show(f);
return0;
}
voidfeedNumbers(intstart,intend,intdivisor,std::set<int>&s)
{
for(inti=start;i<=end;++i){
if(i%divisor==0){
s.insert(i);
}
}
}
voidshow(std::set<int>&s)
{
for(std::set<int>::iteratori=s.begin();i!=s.end();++i){
std::cout<<*i<<std::endl;
}
std::cout<<std::endl;
}
C. 誰能提供一些C++面試的常見程序題
流個郵箱,我可以發給你!
經典C++面試題
1.介紹一下STL,詳細說明STL如何實現vector。
Answer
STL (標准模版庫,Standard Template Library.它由容器演算法迭代器組成。
STL有以下的一些優點:
可以方便容易地實現搜索數據或對數據排序等一系列的演算法;
調試程序時更加安全和方便;
即使是人們用STL在UNIX平台下寫的代碼你也可以很容易地理解(因為STL是跨平台的)。
vector實質上就是一個動態數組,會根據數據的增加,動態的增加數組空間。
2.如果用VC開發程序,常見這么幾個錯誤,C2001,c2005,c2011,這些錯誤的原因是什麼。
Answer
在學習VC++的過程中,遇到的LNK2001錯誤的錯誤消息主要為:
unresolved external symbol 「symbol」(不確定的外部「符號」)。
如果連接程序不能在所有的庫和目標文件內找到所引用的函數、變數或標簽,將產生此錯誤消息。
一般來說,發生錯誤的原因有兩個:一是所引用的函數、變數不存在、拼寫不正確或者使用錯誤;其次可能使用了不同版本的連接庫。
編程中經常能遇到LNK2005錯誤——重復定義錯誤,其實LNK2005錯誤並不是一個很難解決的錯誤.
3.繼承和委派有什麼分別,在決定使用繼承或者委派的時候需要考慮什麼。
在OOD,OOP中,組合優於繼承.
當然多態的基礎是繼承,沒有繼承多態無從談起。
當對象的類型不影響類中函數的行為時,就要使用模板來生成這樣一組類。
當對象的類型影響類中函數的行為時,就要使用繼承來得到這樣一組類.
4.指針和引用有什麼分別;如果傳引用比傳指針安全,為什麼?如果我使用常量指針難道不行嗎?
(1) 引用在創建的同時必須初始化,即引用到一個有效的對象;而指針在定義的時候不必初始化,可以在定義後面的任何地方重新賦值.
(2) 不存在NULL引用,引用必須與合法的存儲單元關聯;而指針則可以是NULL.
(3) 引用一旦被初始化為指向一個對象,它就不能被改變為另一個對象的引用;而指針在任何時候都可以改變為指向另一個對象.給引用賦值並不是改變它和原始對象的綁定關系.
(4) 引用的創建和銷毀並不會調用類的拷貝構造函數
(5) 語言層面,引用的用法和對象一樣;在二進制層面,引用一般都是通過指針來實現的,只不過編譯器幫我們完成了轉換.
不存在空引用,並且引用一旦被初始化為指向一個對象,它就不能被改變為另一個對象的引用,顯得很安全。
const 指針仍然存在空指針,並且有可能產生野指針.
總的來說:引用既具有指針的效率,又具有變數使用的方便性和直觀性.
5.參數傳遞有幾種方式;實現多態參數傳遞採用什麼方式,如果沒有使用某種方式原因是什麼;
傳值,傳指針或者引用
6.結合一個項目說明你怎樣應用設計模式的理念。
設計模式更多考慮是擴展和重用,而這兩方面很多情況下,往往會被忽略。
不過,我不建議濫用設計模式,以為它有可能使得簡單問題復雜化.
7.介紹一下你對設計模式的理解。(這個過程中有很多很細節的問題隨機問的)
設計模式概念是由建築設計師Christopher Alexander提出每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題的解決方案的核心.這樣,你就能一次又一次地使用該方案而不必做重復勞動.上述定義是對設計模式的廣義定義.將其應用到面向對象軟體的領域內,就形成了對設計模式的狹義定義.
可以簡單的認為設計模式就是解決某個特定的面向對象軟體問題的特定方法, 並且已經上升到理論程度。
框架與設計模式的區別
1,設計模式和框架針對的問題域不同.設計模式針對面向對象的問題域;框架針對特定業務的問題域
2,設計模式比框架更為抽象.設計模式在碰到具體問題後,才能產生代碼;框架已經可以用代碼表示
3,設計模式是比框架更小的體系結構元素.框架中可以包括多個設計模式
設計模式就像武術中基本的招式.將這些招式合理地縱組合起來,就形成套路(框架),框架是一種半成品.
8.C++和C定義結構的分別是什麼。
C language 的結構僅僅是數據的結合
C plus plus的struct 和 class 其實具備幾乎一樣的功能,只是默認的訪問屬性不一樣而已。
9.構造函數可否是虛汗數,為什麼?析構函數呢,可否是純虛的呢?
構造函數不能為虛函數,要構造一個對象,必須清楚地知道要構造什麼,否則無法構造一個對象。
析構函數可以為純虛函數。
10,拷貝構造函數相關問題,深拷貝,淺拷貝,臨時對象等。
深拷貝意味著拷貝了資源和指針,而淺拷貝只是拷貝了指針,沒有拷貝資源
這樣使得兩個指針指向同一份資源,造成對同一份析構兩次,程序崩潰。
臨時對象的開銷比局部對象小些。
11.結合1個你認為比較能體現OOP思想的項目,用UML來描述。(最好這個項目繼承,多態,虛函數都有體現)這個問題大概會占面試時間的一半,並且會問很多問題,一不小心可能會被問住)。
。。。
12。基類的有1個虛函數,子類還需要申明為virtual嗎?為什麼。
不申明沒有關系的。
不過,我總是喜歡顯式申明,使得代碼更加清晰。
13.C也可以通過精心封裝某些函數功能實現重用,那C++的類有什麼優點嗎,難道僅僅是為實現重用。
並不僅僅是這樣的。
OOD,OOP從根本上改變了程序設計模式和設計思想,具備重大和深遠的意義。
類的三大最基本的特徵:封裝,繼承,多態.
14.C++特點是什麼,如何實現多態?畫出基類和子類在內存中的相互關系。
多態的基礎是繼承,需要虛函數的支持,簡單的多態是很簡單的。
子類繼承父類大部分的資源,不能繼承的有構造函數,析構函數,拷貝構造函數,operator=函數,友元函數等等
15.為什麼要引入抽象基類和純虛函數?
主要目的是為了實現一種介面的效果。
16.介紹一下模板和容器。如何實現?(也許會讓你當場舉例實現)
模板可以說比較古老了,但是當前的泛型編程實質上就是模板編程。
它體現了一種通用和泛化的思想。
STL有7種主要容器:vector,list,deque,map,multimap,set,multiset.
17.你如何理解MVC。簡單舉例來說明其應用。
MVC模式是observer 模式的一個特例,典型的有MFC裡面的文檔視圖架構。
18,多重繼承如何消除向上繼承的二義性。
使用虛擬繼承即可.
1. STL中Map內部是怎麼實現的?
答:紅黑樹.
二叉樹在平衡時或者葉子結點到根結點的高度在一定的范圍內時工作起來是最有效的。紅黑樹演算法是平衡樹的一種演算法。這個名字就是由於樹的每個結點都被著上了紅色或者黑色,結點所著的顏色被用來檢測樹的平衡性。在對結點插入和刪除的操作中,可能會被旋轉來保持樹的平衡性。平均和最壞情況插入,刪除,查找時間都是O(lg n)。詳細內容請參考 Cormen [2001]。
理論
一個紅黑樹是一顆二叉查找樹,具有下列的屬性:
1. 所有的結點都被著色為紅色或者是黑色。
2. 每一個葉子結點都是空結點,並且被著為黑色。
3. 如果父結點是紅色的,那麼兩個子結點都是黑色的。
4. 結點到其子孫結點的每條簡單路徑上都包含相同數目的黑色結點。
5. 根結點永遠是黑色的。
2. 對象在內存中是怎麼存放的?
答:需要閱讀<<Inside The C++ Object Model>>
簡單說來,
在類對象的內存布局中,如果有虛函數,首先是該類的vtbl指針,然後才是對象數據,對象數據都是順序存
放,當然會涉及到位元組對齊,這樣會帶來存取效率的提升.
3. 說說COM的原理和實現?
答:COM,簡單地說,是一種不同應用程序和不同語言來共享二進制代碼的方法,不同於C++,只是源代碼級的重用。Windows允許你使用DLL實現二進制級的代碼共享,如kernel32.dll,user32.dll等,但因為這都是用C寫的DLL,所以它們只能被C或者理解C調用方式的語言所調用。MFC引入了另一種二進制級的代碼共享機制--MFC extension DLLs,但這種機制限制更多,你只能在MFC程序中使用它們。而COM通過建立一種二進制的規范來解決這些問題,這也意味著COM二進制模塊要按照一種特別的結構來組織,在內存中亦然。規則是語言無關的,重擔交給了編譯器。
COM對象在內存中的組織結構和C++的虛函數一樣,這就是為什麼大多數COM代碼都使用C++的原因,但記住,COM確實是語言無關的,因為生成的結果代碼可以被其它所有語言所使用。順便說,COM不是Win32規范,理論上,它能移植到Unix和其它任意的操作系統,但我沒見過Windows世界以外的COM.
4. 為什麼要用智能指針?是怎麼實現的?
以免資源泄漏.
內部使用了引用計數機制,具體實現非常復雜.
5. 給你一個指針,並用new動態申請空間,在另一個函數中釋放,不知道是申請的一個元素還是一個數組的情況下,怎麼確定用delete還是delete []?
不同的編譯器有不同的實現機制,比較常用的有兩種:
1.new 時,在第一個對象前面記錄分配了多少對象.
2.使用鍵值,即key-value
For ex:
int *p = new int[n];
p為key,n為value.
6. 虛函數是怎麼實現的?
答:簡單說來使用了虛函數表.
7. 虛函數表又是怎樣實現的?
答:
每個含有虛函數的類有一張虛函數表(vtbl),表中每一項指向一個虛函數的地址,實現上是一個函數指針的數組。
虛函數表既有繼承性又有多態性。每個派生類的vtbl繼承了它各個基類的vtbl,如果基類vtbl中包含某一項,則其派生類的vtbl中也將包含同樣的一項,但是兩項的值可能不同。如果派生類覆蓋(override)了該項對應的虛函數,則派生類vtbl的該項指向重載後的虛函數,沒有重載的話,則沿用基類的值。
在類對象的內存布局中,首先是該類的vtbl指針,然後才是對象數據。在通過對象指針調用一個虛函數時,編譯器生成的代碼將先獲取對象類的vtbl指針,然後調用vtbl中對應的項。對於通過對象指針調用的情況,在編譯期間無法確定指針指向的是基類對象還是派生類對象,或者是哪個派生類的對象。但是在運行期間執行到調用語句時,這一點已經確定,編譯後的調用代碼能夠根據具體對象獲取正確的vtbl,調用正確的虛函數,從而實現多態性。
分析一下這里的思想所在,問題的實質是這樣,對於發出虛函數調用的這個對象指針,在編譯期間缺乏更多的信息,而在運行期間具備足夠的信息,但那時已不再進行綁定了,怎麼在二者之間作一個過渡呢?把綁定所需的信息用一種通用的數據結構記錄下來,該數據結構可以同對象指針相聯系,在編譯時只需要使用這個數據結構進行抽象的綁定,而在運行期間將會得到真正的綁定。這個數據結構就是vtbl。可以看到,實現用戶所需的抽象和多態需要進行後綁定,而編譯器又是通過抽象和多態而實現後綁定的.
一、C++程序設計:
1)標准C++模板庫中有一個名為bind1st的函數配接器(實際就是一個函數模板),它接受兩個參數,一個是二元函數對象bin_op,一個是二元函數對象的參數value。返回一個新的一元函數對象uni_op。在使用uni_op(param)等效於bin_op(value,param)。即二元函數對象的第一個value被「固定」了。
試編寫程序實現一個類似功能的my_bind1st函數配接器,並給出相應的測試代碼。
2)如果想禁止類被復制的功能(也就是保持類實例的唯一性),怎麼辦?
二、C程序設計
1)定義一個宏 SWAP_MIN(x, y)
交換x和y的值,並返回x和y中的最小值。
例如:
////////////////////////////////////////////////////
int x, y;
x = 1;
y = 3;
printf(「--%d--%d--%d--」, SWAP_MIN(x,y), x, y);
//////////////////////////////////////////////////////
結果是
--1--3--1--
2)我想在C文件裡面重用一些C++的函數,怎麼做?
三、程序設計技巧
1.1. 用C/C++實現一個簡單的hash鏈表, 定義讀和寫的用戶介面並實現
1.2. 如果用戶需要對上述鏈表規定能夠存儲的最大元素個數,例如
set_max_size (int n)
如何修改上步中的代碼來實現?
2. 設計一種數據結構用20個byte存儲32個不超過32的正整數值, 給出
對每個數讀,寫, ++等操作的代碼
3. 用正則表達式將程序中的int替換成unsigned int
4. 下面的程序的運行結果是什麼,如果有錯誤,如何修正
char get_last ( char *str ) {
int length = sizeof (str);
return str[length-1];
}
int main () {
char* a = "hello world!";
char last = get_last (a);
printf ("%c\n", get_last (a) );
}
5. 寫一段程序找出一個數列中第二大數
6. 用戶定義類型如下:
packet_type packet {
int id;
int data;
}
怎樣讓下面的代碼能夠列印p中的id和data
packet p;
cout << p << endl;
四、語法制導翻譯題:
下面定義文法G:
1) 終結符共7個『VAR』 id 『*』 『+』 『,』 『;』 『.』
2) G: <program> --> <decl說明><statement>』.』
<decl說明> --> 『VAR』 id{『,』id}』;』
<statement> --> <中綴表達式>{『;』<中綴表達式>}
<中綴表達式> --> <中綴表達式>』+』<中綴表達式>
<中綴表達式> --> <中綴表達式>』*』<中綴表達式>
<中綴表達式> --> id
要求:
1) 檢測G中在中綴表達式中出現的變數id必須在<decl說明>中定義過,且不能重復定義
2) 將中綴表達式轉化為後綴表達式,給出語義翻譯
五、如何在C程序中,實現一個能夠存儲任意類型數據的堆棧?比如:
push (a, int); 表示push一個int型數據a進棧。
push (b, defined_type); defined_type可以是用戶自己定義的類型,如struct。這樣的話,該語句表示push一個struct defined_type類型的數據b進入堆棧。
D. c++ stl set 中find方法是如何實現的
是用在平衡二叉樹上查找的演算法實現的,復雜度是O(log n)。
STLport裡面的實現代碼如下:
_Base_ptr _M_find(const _KT& __k) const {
_Base_ptr __y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data); // Last node which is not less than __k.
_Base_ptr __x = _M_root(); // Current node.
while (__x != 0)
if (!_M_key_compare(_S_key(__x), __k))
__y = __x, __x = _S_left(__x);
else
__x = _S_right(__x);
if (__y != &this->_M_header._M_data) {
if (_M_key_compare(__k, _S_key(__y))) {
__y = __CONST_CAST(_Base_ptr, &this->_M_header._M_data);
}
}
return __y;
}
第二個問題,單獨使用的話,set應該比較快些(vector 的話,要先來個排序然後再二分,估計速度也差不多),不過如果你用的編譯器新的話,能支持C++11的話,建議你用unordered_set應該可以更快些。 要想速度更更快些的話,就不要用stl了,自己小心點實現個哈希演算法應該可以辦到。
E. .stl是什麼文件後綴
STL = Standard Template Library,標准模板庫,惠普實驗室開發的一系列軟體的統稱。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普實驗室工作時所開發出來的。這可能是一個歷史上最令人興奮的工具的最無聊的術語。從根本上說,STL是一些「容器」的集合,這些「容器」有list,vector,set,map等,STL也是演算法和其他一些組件的集合。這里的「容器」和演算法的集合指的是世界上很多聰明人很多年的傑作。STL的目的是標准化組件,這樣就不用重新開發,可以使用現成的組件。STL現在是C++的一部分,因此不用額外安裝什麼。
目錄
標准模板庫演算法
容器
迭代器
科學和技術素養
司太立特合金
中國星際戰隊聯賽
北京大學國際法學院
一種3D模型文件格式
台達PLC命令
夢幻西遊門派
操作應用標准模板庫 演算法
容器
迭代器
科學和技術素養
司太立特合金
中國星際戰隊聯賽
北京大學國際法學院
一種3D模型文件格式
台達PLC命令
夢幻西遊門派
操作應用展開 編輯本段標准模板庫
STL被內建在你的編譯器之內。 在C++標准中,STL被組織為下面的13個頭文件:、、、、、、、、、、、和。
演算法
大家都能取得的一個共識是函數庫對數據類型的選擇對其可重用性起著至關重要的作用。舉例來說,一個求方根的函數,在使用浮點數作為其參數類型的情況下的可重用性肯定比使用整型作為它的參數類性要高。而C++通過模板的機制允許推遲對某些類型的選擇,直到真正想使用模板或者說對模板進行特化的時候,STL就利用了這一點提供了相當多的有用演算法。它是在一個有效的框架中完成這些演算法的——你可以將所有的類型劃分為少數的幾類,然後就可以在模版的參數中使用一種類型替換掉同一種類中的其他類型。 STL提供了大約100個實現演算法的模版函數,比如演算法for_each將為指定序列中的每一個元素調用指定的函數,stable_sort以你所指定的規則對序列進行穩定性排序等等。這樣一來,只要我們熟悉了STL之後,許多代碼可以被大大的化簡,只需要通過調用一兩個演算法模板,就可以完成所需要的功能並大大地提升效率。 演算法部分主要由頭文件,和組成。是所有STL頭文件中最大的一個(盡管它很好理解),它是由一大堆模版函數組成的,可以認為每個函數在很大程度上都是獨立的,其中常用到的功能范圍涉及到比較、交換、查找、遍歷操作、復制、修改、移除、反轉、排序、合並等等。體積很小,只包括幾個在序列上面進行簡單數學運算的模板函數,包括加法和乘法在序列上的一些操作。中則定義了一些模板類,用以聲明函數對象。
容器
在實際的開發過程中,數據結構本身的重要性不會遜於操作於數據結構的演算法的重要性,當程序中存在著對時間要求很高的部分時,數據結構的選擇就顯得更加重要。 經典的數據結構數量有限,但是我們常常重復著一些為了實現向量、鏈表等結構而編寫的代碼,這些代碼都十分相似,只是為了適應不同數據的變化而在細節上有所出入。STL容器就為我們提供了這樣的方便,它允許我們重復利用已有的實現構造自己的特定類型下的數據結構,通過設置一些模版類,STL容器對最常用的數據結構提供了支持,這些模板的參數允許我們指定容器中元素的數據類型,可以將我們許多重復而乏味的工作簡化。 容器部分主要由頭文件,,,,,和組成。對於常用的一些容器和容器適配器(可以看作由其它容器實現的容器),可以通過下表總結一下它們和相應頭文件的對應關系。 數據結構 描述 實現頭文件
向量(vector) 連續存儲的元素
列表(list) 由節點組成的雙向鏈表,每個結點包含著一個元素
雙隊列(deque) 連續存儲的指向不同元素的指針所組成的數組
集合(set) 由節點組成的紅黑樹,每個節點都包含著一個元素,節點之間以某種作用於元素對的謂詞排列,沒有兩個不同的元素能夠擁有相同的次序
多重集合(multiset) 允許存在兩個次序相等的元素的集合
棧(stack) 後進先出的值的排列
隊列(queue) 先進先出的值的排列
優先隊列(priority_queue) 元素的次序是由作用於所存儲的值對上的某種謂詞決定的的一種隊列
映射(map) 由{鍵,值}對組成的集合,以某種作用於鍵對上的謂詞排列
多重映射(multimap) 允許鍵對有相等的次序的映射
迭代器
下面要說的迭代器從作用上來說是最基本的部分,可是理解起來比前兩者都要費力一些(至少筆者是這樣)。軟體設計有一個基本原則,所有的問題都可以通過引進一個間接層來簡化,這種簡化在STL中就是用迭代器來完成的。概括來說,迭代器在STL中用來將演算法和容器聯系起來,起著一種黏和劑的作用。幾乎STL提供的所有演算法都是通過迭代器存取元素序列進行工作的,每一個容器都定義了其本身所專有的迭代器,用以存取容器中的元素。 迭代器部分主要由頭文件,和組成。是一個很小的頭文件,它包括了貫穿使用在STL中的幾個模板的聲明,中提供了迭代器使用的許多方法,而對於的描述則十分的困難,它以不同尋常的方式為容器中的元素分配存儲空間,同時也為某些演算法執行期間產生的臨時對象提供機制,中的主要部分是模板類allocator,它負責產生所有容器中的默認分配器。
F. 想學編程,需要擁有什麼樣的條件
以下摘自《程序員的十層樓》
自西方文藝復興以來,中國在自然科學方面落後西方很多,軟體領域也不例外。當然現在中國的許多程序員們對此可能有許多不同的意見,有些人認為中國的程序員水平遠落後於西方,有些則認為中國的程序員個人能力並不比西方的程序員差,只是整個軟體產業落後而已。那麼,到底中國的程序員水平比西方程序員水平差,還是中國有許多優秀的程序員達到或超過了西方程序員同等水平呢?要解決這個問題,必須先知道程序員 有多少種技術層級,每個層級需要什麼樣的技術水平,然後再比較中國和西方在各個技術層級的人數,就可以知道到底有沒有差距,差距有多大。
當然,對於如何劃分程序員的技術層級,不同公司或不同人會有不同的劃分標准,下面的劃分僅代表個人的觀點,如有不當之處,還請砸板磚予以糾正。
第1層 菜鳥第1層樓屬於地板層,邁進這層樓的門檻是很低的。基本上懂計算機的基本操作,了解計算機專業的一些基礎知識,掌握一門基本的編程語言如C/C++,或者Java,或者JavaScript,...,均可入門邁進這層。
在這層上,中國有著絕對的優勢,除了從計算機專業畢業的眾多人數外,還有大量的通信、自動化、數學等相關專業的人士進入這一行,此外還有眾多的其他專業轉行的人士,人數絕對比西方多出甚多。並且還有一個優勢就是我們這層人員的平均智商比西方肯定高。
沒有多少人願意一輩子做菜鳥,因為做"菜鳥"的滋味實在是不咋的,整天被老大們吆喝著去裝裝機器,搭建一下測試環境,或者對照著別人寫好的測試用例 做一些黑盒測試,好一點的可以被安排去寫一點測試代碼。當然如果運氣"好"的話,碰到了國內的一些作坊式的公司,也有機會去寫一些正式的代碼。
所以,菜鳥們總是在努力學習,希望爬更高的一層樓去。
第2層 大蝦從第1層爬到第2層相對容易一些,以C/C++程序員為例,只要熟練掌握C/C++編程語言,掌握C標准庫和常用的各種數據結構演算法,掌握STL的 基本實現和使用方法,掌握多線程編程基礎知識,掌握一種開發環境,再對各種操作系統的API都去使用一下,搞網路編程的當然對socket編程要好好掌握 一下,然後再學習一些面向對象的設計知識和設計模式等,學習一些測試、軟體工程和質量控制的基本知識,大部分人經過2~3年的努力,都可以爬到第2層,晉 升為"大蝦"。
中國的"大蝦"數量和"菜鳥"數量估計不會少多少,所以這層上仍然遠領先於西方。
大蝦們通常還是有些自知之明,知道自己只能實現一些簡單的功能,做不了大的東西,有時候還會遇到一些疑難問題給卡住,所以他們對那些大牛級的人物通 常是非常崇拜的,國外的如Robert C. Martin、Linus Torvalds,國內的如求伯君、王志東等通常是他們崇拜的對象。其中的有些人希望有一天也能達到這些大牛級人物的水平,所以他們繼續往樓上爬去。
第3層 牛人由於"大蝦"們經常被一些疑難問題給卡住,所以有了"大蝦"們只好繼續學習,他們需要將原來所學的知識進一步熟練掌握,比如以熟練掌握C++編程語 言為例,除了學一些基礎性的C++書籍如《C++ Primer》,《Effective C++》,《Think in C++》,《Exception C++》等之外,更重要的是需要了解C++編譯器的原理和實現機制,了解操作系統中的內部機制如內存管理、進程和線程的管理機制,了解處理器的基礎知識和 代碼優化的方法,此外還需要更深入地學習更多的數據結構與演算法,掌握更深入的測試和調試知識以及質量管理和控制方法,對各種設計方法有更好的理解等。
學習上面說的這些知識不是一揮而就的,不看個三五十本書並掌握它是做不到的。以數據結構演算法來說,至少要看個5~10本這方面的著作;以軟體設計來 說,光懂結構化設計、面向對象設計和一些設計模式是不夠的,還要了解軟體架構設計、交互設計、面向方面的設計、面向使用的設計、面向數據結構演算法的設計、 情感化設計等,否則是很難進到這個樓層的。
當然除了上面說的知識外,大蝦們還需要去學習各種經驗和技巧。當然這點難不倒他們,現在出版的書籍眾多,網路上的技術文章更是不勝數,然後再去各種 專業論壇里泡一泡,把這些書籍和文章中的各種經驗、技能、技巧掌握下來,再去學習一些知名的開源項目如Apache或Linux操作系統的源代碼實現等。 此時對付一般的疑難問題通常都不在話下,菜鳥和大蝦們會覺得你很"牛",你也就爬到了第3層,晉升為"牛人"了。
看了上面所講的要求,可能有些大蝦要暈過去了,成為牛人要學這么多東西啊!要求是不是太高了?其實要求一點也不高,這么點東西都掌握不了的話,怎麼能讓別人覺得你"牛"呢?
需要提一下的是,進入多核時代後,從第2層爬到第3層增加了一道多核編程的門檻。當然要邁過這道門檻並不難,已經有很多前輩高人邁進了這道門檻,只要循著他們的足跡前進就可以了。想邁進這道門檻者不妨去學習一下TBB開源項目的源代碼(鏈接:http://www.threadingbuildingblocks.org/),然後上Intel的博客(http://softwareblogs-zho.intel.com/)和多核論壇(http://forum.csdn.net/Intel/IntelMulti-core/)去看看相關文章,再買上幾本相關的書籍學習一下。
在國內, 一旦成為"牛人",通常可以到許多知名的公司里去,運氣好者可以掛上一個架構師的頭銜,甚至掛上一個"首席架構師"或者"首席xx學家"的頭銜也不足為 奇。有不少爬到這層的人就以為到了樓頂了,可以眼睛往天上看了,開始目空一切起來,以為自己什麼都可以做了,什麼都懂了,經常在網路上亂砸板磚是這個群體 的最好寫照。由此也看出,國內的牛人數量仍然眾多,遠多於西方的牛人數量,在這層上仍然是領先的。
也有不少謙虛的"牛人",知道自己現在還不到半桶水階段。他們深知爬樓的游戲就像猴子上樹一樣,往下看是笑臉,往上看是屁股。為了多看笑臉,少看屁股,他們並沒有在此停步不前,而是繼續尋找到更上一層的樓梯,以便繼續往上爬。
第4層 大牛從第3層爬到第4層可不像上面說過的那幾層一樣容易,要成為大牛的話,你必須要能做牛人們做不了的事情,解決牛人們解決不了問題。比如牛人們通常都 不懂寫操作系統,不會寫編譯器,不懂得TCP/IP協議的底層實現,如果你有能力將其中的任何一個實現得象模象樣的話,那麼你就從牛人升級為"大牛"了。
當然,由於各個專業領域的差別,這里舉操作系統、編譯器、TCP/IP協議只是作為例子,並不代表成為"大牛"一定需要掌握這些知識,以時下熱門的 多核編程來說,如果你能比牛人們更深入地掌握其中的各種思想原理,能更加自如的運用,並有能力去實現一個象開源項目TBB庫一樣的東西,也可以成為"大 牛",又或者你能寫出一個類似Apache一樣的伺服器,或者寫出一個資料庫,都可以成為"大牛"。
要成為"大牛"並不是一件簡單的事情,需要付出比牛人們多得多的努力,一般來說,至少要看過200~400本左右的專業書籍並好好掌握它,除此之外,還得經常關注網路和期刊雜志上的各種最新信息。
當"牛人"晉升為"大牛",讓"牛人們"發現有比他們更牛的人時,對"牛人"們的心靈的震撼是可想而知的。由於牛人們的數量龐大,並且牛人對大蝦和 菜鳥階層有言傳身教的影響,所以大牛們通常能獲得非常高的社會知名度,幾乎可以用"引無數菜鳥、大蝦、牛人競折腰"來形容,看看前面提過的Linus Torvalds等大牛,應該知道此言不虛。
雖然成為"大牛"的條件看起來似乎很高似的,但是這層樓並不是很難爬的一層,只要通過一定的努力,素質不是很差,還是有許多"牛人"可以爬到這一層的。由此可知,"大牛"這個樓層的人數其實並不像想像的那麼少,例如比爾·蓋茨之類的人好像也是屬於這一層的。
由於"大牛"這層的人數不少,所以也很難統計除到底是中國的"大牛"數量多還是西方的大牛數量多?我估計應該是個旗鼓相當的數量,或者中國的"大牛"們會更多一些。
看到這里,可能會有很多人會以為我在這里說瞎話,Linus Torvalds寫出了著名的Linux操作系統,我國並沒有人寫出過類似的東西啊,我國的"大牛"怎麼能和西方的比呢? 不知大家注意到沒有,Linus Torvalds只是寫出了一個"象模象樣"的操作系統雛形,Linux後來真正發展成聞名全球的開源操作系統期間,完全是因為許多支持開源的商業公司如 IBM等,派出了許多比Linus Torvalds更高樓層的幕後英雄在裡面把它開發出來的。
可能有些菜鳥認為Linus Torvalds是程序員中的上帝,不妨說個小故事:
Linus,Richard Stallman和Don Knuth(高德納)一同參加一個會議。
Linus 說:"上帝說我創造了世界上最優秀的操作系統。"
Richard Stallman自然不甘示弱地說:"上帝說我創造了世界上最好用的編譯器。"
Don Knuth一臉疑惑的說:"等等,等等,我什麼時候說過這些話?"
由此可以看出,Linus Torvalds的技術水平並不像想像中那麼高,只是"牛人"和"大蝦"覺得"大牛"比他們更牛吧了。在我國,有一些當時還處於"大蝦"層的人物,也能寫 出介紹如何寫操作系統的書,並且書寫得非常出色,而且寫出了一個有那麼一點點象模象樣的操作系統來。我想中國的"大牛"們是不會比西方差的,之所以沒有人 寫出類似的商業產品來,完全是社會環境的原因,並不是技術能力達不到的原因。
"大牛"們之所以成為大牛,主要的原因是因為把"牛人"給蓋了下去,並不是他們自己覺得如何牛。也許有很多菜鳥、大蝦甚至牛人覺得"大牛"這層已經 到頂了,但大多數"大牛"估計應該是有自知之明的,他們知道自己現在還沒有爬到半山腰,也就勉強能算個半桶水的水平,其中有些爬到這層沒有累趴下,仍然能 量充沛,並且又有志者,還是會繼續往更上一層樓爬的。
看到這里,也許有些菜鳥、大蝦、牛人想不明白了,還有比"大牛"們更高的樓層,那會是什麼樣的樓層?下面就來看看第5層樓的奧妙。
第5層 專家當大牛們真正動手做一個操作系統或者類似的其他軟體時,他們就會發現自己的基本功仍然有很多的不足。以內存管理為例,如果直接抄襲Linux或者其 他開源操作系統的內存管理演算法,會被人看不起的,如果自動動手實現一個內存管理演算法,他會發現現在有關內存管理方法的演算法數量眾多,自己並沒有全部學過和 實踐過,不知道到底該用那種內存管理演算法。
看到這里,可能有些人已經明白第5層樓的奧妙了,那就是需要做基礎研究,當然在計算機里,最重要的就是"計算"二字,程序員要做基礎研究,主要的內容就是研究非數值"計算"。
非數值計算可是一個非常龐大的領域,不僅時下熱門的"多核計算"與"雲計算"屬於非數值計算范疇,就是軟體需求、設計、測試、調試、評估、質量控 制、軟體工程等本質上也屬於非數值計算的范疇,甚至晶元硬體設計也同樣牽涉到非數值計算。如果你還沒有真正領悟"計算"二字的含義,那麼你就沒有機會進到 這層樓來。
可能有人仍然沒有明白為什麼比爾·蓋茨被劃在了大牛層,沒有進到這層來。雖然比爾·蓋茨大學未畢業,學歷不夠,但是家有藏書2萬余冊,進入軟體這個 行業比絕大部分人都早,撇開他的商業才能不談,即使只看他的技術水平,也可以算得上是學富五車,頂上幾個普通的計算機軟體博士之和是沒有問題的,比起 Linus Torvalds之類的"大牛"們應該技高一籌才對,怎麼還進不了這層樓呢?
非常遺憾的是,從Windows操作系統的實現來看,其對計算的理解是很膚淺的,如果把Google對計算方面的理解比做大學生,比爾·蓋茨只能算做一個初中生,所以比爾·蓋茨永遠只能做個大牛人,成不了"專家"。
看到這里,也許國內的大牛們要高興起來了,原來比爾·蓋茨也只和我等在同一個層次,只要再升一層就可以超越比爾·蓋茨了。不過爬到這層可沒有從"牛 人"升為"大牛"那麼簡單,人家比爾·蓋茨都家有2萬多冊書,讓你看個500~1000本以上的專業書籍並掌握好它應該要求不高吧。當然,這並不是主要的 條件,更重要的是,需要到專業的學術站點去學習了,到ACM,IEEE,Elsevier,SpringerLink,SIAM等地方去下載論文應該成為 你的定期功課,使用Google搜索引擎中的學術搜索更是應該成為你的日常必修課。此外,你還得經常關注是否有與你研究相關的開源項目冒出來,例如當聽到 有TBB這樣針對多核的開源項目時,你應該第一時間到Google里輸入"TBB"搜索一下,將其源代碼下載下來好好研究一番,這樣也許你的一隻腳已經快 邁進了這層樓的門檻。
當你象我上面說的那樣去做了以後,隨著時間的推移,總會有某天,你發現,在很多小的領域里,你已經學不到什麼新東西了,所有最新出來的研究成果你幾 乎都知道。此時你會發現你比在做"牛人"和"大牛"時的水平不知高出了多少,但是你一點也"牛"不起來,因為你學的知識和思想都是別人提出來的,你自己並 沒有多少自己的知識和思想分享給別人,所以你還得繼續往樓上爬才行。
我不知道國內的"專家"到底有多少,不過有一點可以肯定的是,如果把那些專門蒙大家的"磚家"也算上的話,我們的磚家比西方的要多得多。
第6層 學者
當"專家"們想繼續往上一層樓爬時,他們幾乎一眼就可以看到樓梯的入口,不過令他們吃驚的是,樓梯入口處豎了一道高高的門檻,上面寫著"創新"二字。不幸的是,大多數人在爬到第5層樓時已經體能消耗過度,無力翻過這道門檻。
有少數體能充足者,可以輕易翻越這道門檻,但是並不意味著體力消耗過度者就無法翻越,因為你只是暫時還沒有掌握恢復體能的方法而已,當掌握了恢復體能的方法,將體能恢復後,你就可以輕易地翻越這道門檻了。
怎麼才能將體能恢復呢?我們的老祖宗"孔子"早就教導過我們"溫故而知新",在英文里,研究的單詞是"research",其前綴"re" 和"search"分別是什麼意思不用我解釋吧。或許有些人覺得"溫故而知新"和"research"有些抽象,不好理解,我再給打個簡單的比方,比如你 在爬一座高山,爬了半天,中途體力不支,怎麼恢復體力呢?自然是休息一下,重新進食一些食物,體力很快就可以得到恢復。
由此可知,對體能消耗過度者,休息+重新進食通常是恢復體能的最佳選擇。可惜的是,國內的老闆們並不懂得這點,他們的公司里不僅連正常國家規定的休 息時間都不給足,有些公司甚至有員工"過勞死"出現。所以國內能翻越"創新"這道門檻的人是"少之又少",和西方比起來估計是數量級的差別。
再說說重新進食的問題,這個重新進食是有講究的,需要進食一些基礎性易消化的簡單食物,不能進食山珍海味級的復雜食物,否則很難快速吸收。以查找為 例,並不是去天天盯著那些復雜的查找結構和演算法進行研究,你需要做的是將二分查找、哈希查找、普通二叉樹查找等基礎性的知識好好地復習幾遍。
以哈希查找為例,首先你需要去將各種沖突解決方法如鏈式結構、二次哈希等編寫一遍,再試試不同種類的哈希函數,然後還需要試試在硬碟中如何實現哈希 查找,並考慮數據從硬碟讀到內存後,如何組織硬碟中的數據才能快速地在內存中構建出哈希表來,...,這樣你可能需要將一個哈希表寫上十幾個不同的版本, 並比較各個版本的性能、功能方面的區別和適用范圍。
總之,對任何一種簡單的東西,你需要考慮各種各樣的需求,以需求來驅動研究。最後你將各種最基礎性的查找結構和演算法都瞭然於胸後,或許某天你再看其他更復雜的查找演算法,或者你在散步時,腦袋裡靈光一現,突然間就發現了更好的方法,也就從專家晉升為"學者"了。
學者所做的事情,通常都是在前人的基礎上,進行一些小的優化和改進,例如別人發明了鏈式基數排序的方法,你第1個發現使用一定的方法,可以用數組替代鏈表進行基數排序,性能還能得到進一步提高。
由於學者需要的只是一些小的優化改進,因此中國還是有一定數量的學者。不過和國外的數量比起來,估計少了一個數量級而已。
也許有人會覺得現在中國許多公司申請專利的數量達到甚至超過西方發達國家了,我們的學者數量應該不會比他們少多少。因此,有必要把專利和這里說的創新的區別解釋一下。
所謂專利者,只要是以前沒有的,新的東西,都可以申請專利;甚至是以前有的東西,你把他用到了一個新的領域的產品里去,也可以申請專利。比如你在房 子里造一個水泥柱子,只要以前沒有人就這件事申請專利,那麼你就可以申請專利,並且下次你把水泥柱子挪一個位置,又可以申請一個新的專利;或者你在一個櫃 子上打上幾個孔,下次又把孔的位置改一改,...,均可申請專利。
這層樓里所說的創新,是指學術層面的創新,是基礎研究方面的創新,和專利的概念是完全不同的,難度也是完全不同的。你即使申請了一萬個象那種打孔一類的專利,加起來也夠不到這層樓里的一個創新。
當你爬到第6層樓時,你也許會有一種突破極限的快感,因為你終於把那道高高的寫著"創新"二字的門檻給翻過去了,實現了"0"的突破。這時,你也許 有一種"獨上高樓,慾望盡天涯路"的感覺,但是很快你會發現看到的都是比較近的路,遠處的路根本看不清楚。如果你還有足夠的體力的話,你會想爬到更高一層 的樓層去。
第7層 大師
從第6層樓爬到第7層樓,並沒有多少捷徑可走,主要看你有沒有足夠的能量。你如果能象Hoare一樣設計出一個快速排序的演算法;或者象Eugene W. Myers一樣設計出了一個用編輯圖的最短路徑模型來解決diff問題的演算法;或者象M.J.D. Powell一樣提出了一個能夠處理非線性規劃問題的SQP方法;或者你發現基於比較的排序演算法,它的復雜度下界為O(NLogN);或者你發現用棧可以 將遞歸的演算法變成非遞歸的;或者你設計出一個紅黑樹或者AVL樹之類的查找結構;或者你設計出一個象C++或Java一樣的語言;或者你發明了 UML;...,你就爬到了第7層,晉升為"大師"了。
上面舉的這些例子中,其中有些人站的樓層比這層高,這里只是為了形象說明而舉例他們的某個成就。從上面列出的一些大師的貢獻可以看出,成為大師必須 要有較大的貢獻。首先解決問題必須是比較重要的,其次你要比前輩們在某方面有一個較大的提高,或者你解決的是一個全新的以前沒有解決過的問題;最重要的 是,主要的思路和方法必須是你自己提供的,不再是在別人的思路基礎上進行的優化和改進。
看了上面這些要求,如果能量不夠的話,你也許會覺得有些困難,所以不是每個人都能成為"大師"的。中國軟體業里能稱得上是"大師"的人,用屈指可數來形容,估計是綽綽有餘。值得一提得是,國外的"大師"就象我們的"大牛"一樣滿天飛的多。
我把我猜測本國有可能進到這層樓的大師列一下,以起個拋磚引玉的作用。漢王的"手寫識別"技術由於是完全保密的,不知道它裡面用了什麼思想,原創思 想占的比重有多少,因此不知道該把它劃到這層樓還是更高一層樓去。原山東大學王小雲教授破解DES和MD5演算法時,用到的方法不知道是不是完全原創的,如 果是的話也可進到這層樓來。
陳景潤雖然沒有徹底解決哥德巴赫猜想,但他在解決問題時所用的方法是創新的,因此也可以進到這層樓來。當然,如果能徹底解決哥德巴赫猜想,那麼可以算到更高的樓層去。
求伯君和王志東等大牛們,他們在做WPS和表格處理之類的軟體時,不知是否有較大的原創演算法在裡面,如果有的話就算我錯把他們劃到了大牛層。由於所 學有限,不知道國內還有那些人能夠得上"大師"的級別,或許有少量做研究的教授、院士們,可以達到這個級別,有知道的不妨回個帖子晾一晾。
鑒於"大師"這個稱號的光環效應,相信有不少人夢想著成為"大師"。或許你看了前面舉的一些大師的例子,你會覺得要成為大師非常困難。不妨說一下,現在有一條通往"大師"之路的捷徑打開了,那就是多核計算領域,有大量的處女地等待大家去挖掘。
以前在單核時代開發的各種演算法,現在都需要改寫成並行的。數據結構與演算法、圖像處理、數值計算、操作系統、編譯器、測試調試等各個領域,都存在大量的機會,可以讓你進到這層樓來,甚至有可能讓你進到更高一層樓去。
第8層 科學家
科學家向來都是一個神聖的稱號,因此我把他放在了「大師」之上。要成為科學家,你的貢獻必須超越大師,不妨隨便舉一些例子。
如果你象Dijkstra一樣設計了ALGOL語言,提出了程序設計的三種基本結構:順序、選擇、循環,那麼你可以爬到第8層樓來。順便說一下,即使拋開這個成果,Dijkstra憑他的PV操作和信號量概念的提出,同樣可以進到這層樓。
如果你象Don Knuth一樣,是數據結構與演算法這門學科的重要奠基者,你也可以進到這層樓來。當然,數據結構和演算法這門學科不是某個人開創的,是許多大師和科學家集體開創的。
如果你象巴科斯一樣發明了Fortran語言,並提出了巴科斯範式,對高級程序語言的發展起了重要作用,你也可以進到這層樓來。
或者你象Ken Thompson、Dennis Ritchie一樣發明了Unix操作系統和功能強大、高效、靈活、表達力強的C語言,對操作系統理論和高級編程語言均作出重大貢獻,那麼你也可以進到這層樓來。
或者你有Frederick P. Brooks一樣機會,可以去領導開發IBM的大型計算機System/360和OS/360操作系統,並在失敗後反思總結,寫出《人月神話》,對軟體工程作出里程碑式的貢獻,你也可以進到這層來。
或者你提出了面向對象設計的基本思想,或者你設計了互聯網的TCP/IP協議,或者你象Steven A.Cook一樣奠定NP完全性的理論基礎,或者你象Frances Allen一樣專注於並行計算來實現編譯技術,在編譯優化理論和技術取得基礎性的成就,…,均可進入這層。
當然,如果你發明了C++語言或者Java語言,你進不到這層來,因為你用到的主要思想都是這層樓中的科學家提出的,你自己並沒有沒有多少原創思想在裡面。
看了上面列出的科學家的成就,你會發現,要成為「科學家」,通常要開創一門分支學科,或者是這個分支學科的奠基者,或者在某個分支學科里作出里程碑式的重大貢獻。如果做不到這些的話,那麼你能象Andrew C. Yao(姚期智)一樣在對計算理論的多個方向如偽隨機數生成,密碼學與通信復雜度等各個方向上作出重要貢獻,成為集大成者,也可以進入這層樓。
成為「科學家」後,如果你有幸象Dijkstra一樣,出現在一個非常重視科學的國度。當你去世時,你家鄉滿城的人都會自動地去為你送葬。不過如果不幸生錯地方的話,能不挨「板磚」估計就算萬幸了。
從上面隨便舉的一些例子中,你可能能猜到,西方科學家的數量是非常多的,於是你會想中國應該也有少量的科學家吧?我可以很負責任地告訴你一個不幸的結果,中國本土產生的科學家的數量為0。目前在國內,軟體領域的唯一的科學家就是上面提過的姚期智,還是國外請回來的,並不是本土產生的。
可能你不同意我說的本土科學家數量為0的結論,因為你經常看到有許多公司里都有所謂「首席XX科學家」的頭銜。我想說的是,這些所謂的「首席XX科學家」都是遠遠夠不到這層樓的級別的,有些人的水平估計也就是一個「牛人」或「大牛」的級別,好一點的最多也就一個「學者」的級別。尤其是那些被稱作「首席經X學家」的,基本上可以把稱號改為「首席坑大家」。
雖然我國沒有人能爬到這層樓上來,但是西方國家仍然有許多人爬到了比這層更高的樓上。如果要問我們比西方落後多少?那麼可以簡單地回答為:「落後了三層樓」。下面就來看看我們做夢都沒有到過的更高一層樓的秘密。
第9層 大科學家
進入這層樓的門檻通常需要一些運氣,比如某天有個蘋果砸到你頭上時,你碰巧發現了萬有引力,那麼你可以進到這層樓來。當然,萬有引力幾百年前就被人發現了,如果你現在到處嚷嚷著說你發現了萬有引力,恐怕馬上會有人打110,然後警察會把你送到不正常人類的聚集地去。因此,這里舉萬有引力的例子,只是說你要有類似的成就才能進到這層樓來。
牛頓發現萬有引力定律開創 了經典物理運動力學這門學科,如果你也能開創一門大的學科,那麼你就從科學家晉升為「大科學家」。比如愛因斯坦創建了相對論,從一個小職員變成了大科學 家。當然大科學家可遠不止這兩人,數學界里比物理學界更是多得多,如歐幾里得創建了平面幾何,笛卡爾開創解析幾何,還有歐拉、高斯、萊布尼茨等數不清的人 物,跟計算相關的大科學家則有圖靈等人。
從上面列出的一些大科學家 可以發現,他們的成就不僅是開創了一個大的學科,更重要的是他們的成就上升到了「公理」的層面。發現公理通常是需要一點運氣的,如果你的運氣不夠好的話, 另外還有一個笨辦法也可以進到這層樓來,那就是成為集大成者。例如馮·諾伊曼,對數學的所有分支都非常了解,許多領域都有較大的貢獻,即使撇開他對計算機 的開創貢獻,成為大科學家照樣綽綽有餘。
當然,程序員們最關心的是 自己有沒有機會變成大科學家。既然計算機這門大學科的開創性成果早就被馮·諾伊曼、圖靈等人摘走了,那麼程序員們是不是沒有機會變成大科學家了呢?我們的 古人說得好:「江山代有才人出,各領風騷數百年」,現在在計算機這門學科下面誕生了許多非常重要的大的分支,所以你還是有足夠的機會進到這層樓的。
如果你能夠徹底解決自然語言理解(機器翻譯)這門學科中的核心問題, 或者你在人工智慧或者機器視覺(圖像識別)方面有突破性的發現,那麼你同樣可以輕易地晉升為「大科學家」。這樣當某天你老了去世時,或許那天國人已經覺醒,你也能享受到如Dijkstra一樣的待遇,有滿城甚至全國的人去為你送葬。
G. map 的參數可以是類嗎
你的cls作為Key來說需要滿足
1. 支持 < 運算符,或者給定了<判斷式,map內部是紅黑樹需要用<,很明顯你的cls不滿足這個條件。
2. 支持拷貝運算符,以及賦值運算(=) ,key在容器內是相互拷貝的。你的這個類編譯器都為你生成了,所以沒問題。
H. C++交叉編譯 請幫忙看看是哪個庫沒有鏈接
C++交叉編譯 請幫忙見見是哪個庫沒有鏈接
www.MyException.Cn 網友分享於:2013-10-12 瀏覽:103次
C++交叉編譯 請幫忙看看是哪個庫沒有鏈接
我在交叉編譯一個cpp程序的時候,提示說:
undefined reference to `std::_Rb_tree_decrement(std::_Rb_tree_node_base const*)'
undefined reference to `std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'
undefined reference to `std::_Rb_tree_increment(std::_Rb_tree_node_base const*)'
undefined reference to `android::RefBase::decStrong(void const*) const'
是不是我在鏈接 的時候,忘記鏈接哪個庫了,請幫忙看下,謝謝!
我鏈接的庫有:-lcutils -ldl -lstlport -lc -lm -lz -ldl -llog -lstdc++ -lstagefright -lbinder
但還是 出現上面 的錯誤。請問下為什麼?
分享到:
------解決方案--------------------
std::_Rb_tree
應該是map或者set用到的紅黑樹啊。
頭文件是bits/stl_tree.h
庫的話應該是-lstdc++, 或者-lstlport啊
為了排除靜態庫原因引起的問題,建議樓主試試在最後在鏈接一下這幾個庫試試
-lcutils -ldl -lstlport -lc -lm -lz -ldl -llog -lstdc++ -lstagefright -lbinder -lstlport -lstdc++ -lstl
加上紅色部分
I. 你是如何用最簡單的方式普及C語言的請具體說說
語言是實現演算法的工具,語言在設計的時候就考慮應用的場景,c是很基礎的語言,功能強大,但便利性不足,所以不用所有人都去學,但應學習c的嚴謹編程態度