《程序員筆試寶典》


static:修飾變量,只能初始化一次,修飾函數是指此函數只能在本文件中調用

const:定義常量;可以進行類型檢查

switch(c)中c唯獨不可以是float類型

volatile:爲了解決多線程共享導致的變量值的不一致,規定每次讀取變量值時候從內存中去讀取。

ASSERT()一般稱爲斷言,它是一個調試程序時經常用到的宏,它定義在<assert.h>頭文件中,通常用於判斷程序是否出現了非法的數據。使用assert()的缺點是頻繁的調用會極大的影響程序的性能。

枚舉變量:enum{a,b=5,d,c=4,e};在枚舉中,某個枚舉變量的值爲默認爲前一個變量的值加1,而如果第一個枚舉變量沒有賦值,則其默認值 爲0.


命令行參數:int main(int argc,char * argv[])

c++中不是所有的動作都是由mian()函數引起的


對操作符的優先級總結如下:

1.關係操作符優於邏輯運算符。

2.移位運算符介於算術運算符和關係運算符之間。

3.除單目運算符外,算術運算符的優先級最高。


a++後綴表達式不能做爲左值,應爲a++返回的是編譯器自動分配的臨時變量temp


與0值的比較:

1.!var--------邏輯判斷

2.var==0------數值比較

3.var==NULL---判斷指針


無論是float還是double類型的變量,由於它們在內存中的存儲機制與整型數不同,有舍入誤差,所以在計算機中,大多數浮點數都是無法精確表達


new/delete與malloc/free的區別

1.new能夠自動計算需要分配的內存空間,而malloc需要手工計算字節數。列如,int*p1=new int[2],int *p2=malloc(2*sizeof(int))

2.new與delete帶具體的類型的指針,而malloc與free返回void類型的指針。列如:char*p=(char *)malloc(100)

3.new一般有兩部組成,分別是new操作和構造。new操作對應malloc,new操作將調用構造函數,而malloc不能,delete將調用析構函數,而free不能

4.malloc/free需要庫文件stdlib.h支持,new/delete則不需要庫文件支持


c++中用export關鍵字來實現模板函數的外部調用

c++中關鍵字explicit表示不允許隱試轉換的發生。


回調函數就是指被調用者回頭調用的函數,它是一個通過函數指針調用的函數。如果把函數的指針(地址)作爲參數傳遞給另外一個函數,當這個指針被用爲調用它所指向的函數時候,此時就可以稱它爲回調函數。回調函數不是由該函數的實現方直接調用的,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。


內存分配:

一個c/c++編譯的程序所佔用的系統內存一般分爲以下幾個部分的內容:

1.由符號起始的區塊(Block Started by Symbol,BSS)段;BSS段通常是用來存放程序中爲初始化的全局數據和靜態數據的一塊內存區域

2.數據段(data segment):數據段通常用來存放程序中已經初始化的全局變量的一塊內存區域

3.代碼段(code segment/text segment): 代碼段有時候也叫文本段,通常是指用來存放程序執行代碼(包括類成員函數和全局函數以及其他函數代碼)的一塊內存區域,這部分區域在程序運行前就已經確定了,並且在內存區域中通常是隻讀的,

4.堆(heap):堆用於存放進程運行中被動態分配的內存段,它的大小並不固定,可以動態擴張或縮減。

5,棧(stack):棧用戶存放程序臨時創建的局部變量,一般包括函數括弧{}中定義的變量(但不包括static聲明的變量,staticn意味着在數據段中存放變量)


棧是向地地址擴展的數據結構,是一塊連續的內存的區域,棧頂的地址和棧的最大容量是系統預先規定好的,在windows下,棧的大小是2MB,而申請堆空間的大小一般小於2GB,堆是動態分配的內存的,並且可以分配使用很大的內存,使用不好會產生內存泄露。頻繁地使用Malloc和free會產生內存碎片(類此磁盤碎片)


內存泄露(未能釋放的內存)----失去控制

緩衝區溢出是目前導致“黑客”型病毒橫行的主要原因。


c語言一共有32關鍵字和5中語言類型

1.表達式語句

2.函數調用語句

3.控制語句

4.複合語句

5.空語句

需要注意的是,由於預處理指令的結尾不能添加分號,所以預處理指令不是語句


strlen-----不包括‘/0’,執行的是一個計數的工作。

sizeof是類型的大小,

大部分編譯程序的sizeof都是在編譯時候計算的,所以可以通過sizeof(x)來定義數組的維數,而strlen的計算則是在運行期計算的,用來計算字符串的實際長度,不是類型真用內存的大小。


一般而言,struct的sizeof是所有成員對齊後長度相加,而union的sizeof是取最大的成員長度。

野指針是指指向不可用內存的指針。任何指針變量在被創建時,不會自動成爲NULL指針(空指針),其默認值是隨機的,所有指針變量在創建的同時也應對被初始化,或者將指針設置爲NULL,或者讓它指向合法的內存,而不應該放置不理,否則就會成爲野指針,而同時由於指針被釋放(free或delete)後,未能將其設置成爲NULL,也會導致該指針變爲野指針。雖然free和delete把指針所指的內存給釋放掉了,但它們並沒有把指針本身也釋放掉了。


爲了提高程序的可讀性,標準庫定義了一個與0等價的符號常量NULL,程序裏可以寫P==0或者p==NULL,

預處理只要是進行文本代碼的替換。


如何判斷一個數是有符號數還是無符號數:

1.取反,都大於0是整數,。。

2.通過符號位來判斷,將最高位置成1,然後判斷A是否大於0(A=A|(1<<31))


不用sizeof,如何求出int佔用的字節數:(char *)(&Value+1)-(char *)&Value


c語言中的struct是用戶自定義數據類型,它是沒有權限設置的,它只能是一些變量的集合體,雖然可以封裝數據卻不可以隱藏數據,而且成員不可以是函數。‘

具體而言,在c++中,class和struct做類型定義時候只有兩點區別:首先是默認權限,class繼承默認是private繼承,而struct繼承默認是public繼承;其次是class還用於定義模板參數,就像typename,但是關鍵字struct不用於定義模板參數。


二進制是現代計算機發展的基礎,所有的程序代碼都需要轉換成最終的二進制代碼才能執行,合理地進行二進制的位操作,對於編寫優質代碼,特別是嵌入式應用軟件開發非常關鍵。


位操作求兩個數的平均值:(x&y)+((x^y)>>1)-----------原理:每個二進制都可以分解爲各個各位與其權的乘積的和

位操作計算數的絕對值:(x^y)-y  其中y表示x右移31位



採用小端模式的CPU對操作數的存放方式是從地字節到高字節,而大端模式對操作的存放方式是從高字節到低字節。x86機是小端模式,單片機一般爲大端模式。

N位二進制數中有多少個數不存在兩個相鄰的1------這個滿足斐波拉契遞歸

用邏輯運算實現加法運算:
int add(int num1,int num2)
{
if(0==num2)
return num1;
int sumTemp=num1^num2;
int  carry=(num1&num2)<<1;
return add(sumTemp,carry)
}


編譯器一般使用堆棧來實現函數調用,堆棧是存取器的一個區域,嵌入式環境有時需要程序員自己定義一個數組作爲堆棧。Windows爲每一個線程自動維護一個堆棧,堆棧的大小可以設置。編譯器使用堆棧來存放沒個函數的參數,局部變量等信息。


全局變量和靜態全局變量的區別在於作用域不同
就是說一個項目裏如果有多個源程序文件
非靜態全局變量可以在所有源文件裏調用
靜態全局變量只能在本文件裏調用,不允許在其他文件裏調用

一個有10個指針的數組,該指針指向一個整型數--------------------------------------------------------------------------------------------------------int  *a[10]

一個指向有10個正型數數組的指針--------------------------------------------------------------------------------------------------------------------------int (*a)[10]

一個指向函數的指針,該函數有一個整型參數並返回一個整型數-------------------------------------------------------------------------------------int (*a)(int)

一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數---------------------------------------------------int (*a[10])(int)


在c/c++程序設計中,任何變量在使用前都需要定義或聲明,定義是爲了變量分配存儲空間,還可以爲變量指定初始值,在一個程序中,變量有且僅有一個定義。

而聲明是指向程序表明變量的類型和名字。定義也是聲明。如果程序前面都沒有出現過a這個變量,這時候要使用a,就必須要讓程序知道使用a這個變量,這時候寫入int a,以前沒有a這個變量的,現在程序爲了記住它,就得爲它分配空間,於是這是個定義。

一般爲了敘述方便,吧建立存儲空間的聲明叫定義,而不把建議存儲空間的聲明成爲聲明。


不使用第三方變量,交換兩個變量的值:

1.加減法

   a=a+b

   b=a-b

   a=a-b


2.異或發

    a=a^b

    b=a^b

    a=a^b


c++中全局對象、變量的構造函數調用順序是跟聲明有一定關係的,即在同一個文件中先聲明的先調用。


C語言中各變量的默認初始值是:

全局變量存放在全局數據區,有編譯器建立,如果在定義的時候不做初始化,則系統將自動爲其初始化,數值型爲0,字符型爲NULL,即0,指針型變量也被初始化爲NULL。靜態變量的情況和全局變量類似。而對非靜態變量如果不顯示初始化,那麼其內容是不可預料的,將是隨機數,會很危險,對系統的安全造成非常大的隱患。


字符串是編程語言的基礎,對於字符串的處理一直是程序設計的重要組成部分,所以在面試筆試中,經常會考察字符串處理函數的機理。掌握常見的字符串處理函數的原理,並能自己實現其原型,對於應對程序員面試筆試非常重要。


在多道程序環境中,要想將用戶源代碼變成一個可以在內存中執行的程序,通常可以分爲3個步驟:編譯,鏈接,載入

編譯:經過詞法,語法分析、語義分析以及優化後編譯成若干個目標模塊

鏈接:有鏈接程序將編譯後形成的一組目標模塊以及它們所需要的庫函數鏈接在一起,形成一個完整的載入模型,鏈接主要解決模塊間相互引用問題,分爲地址和空間分配,符號解析和重定位幾個步驟。

載入:由載入程序將載入模塊載入內存


友元函數不是成員函數,但是它可以訪問類中的私有成員,


當一個類中有指針類型的成員變量時候,一定要重寫複製構造函數和複製構造函數,不能使用默認的。


初始化列表和函數初始化的區別:

對於非內置類型成員變量,因爲類類型的數據成員對象在進入函數體前已經構造完成,也就是說在成員初始化列表處進行構造對象的工作,調用構造函數,在進行函數體之後,進行的是對已經構造好的類對象的賦值,又調用一個複製賦值操作符才能完成(如果並未提供,則使用編譯器提供的默認成員賦值行爲)。爲了避免兩次構造,推薦使用類構造函數初始化列表。

有些情況下只能使用初始化列表:比如const對象或引用類型只能初始化,不能對它們賦值。

在c++中哪些情況下只能用初始化列表而不能用賦值:

在c++中,賦值和初始化列表的原理是不一樣的,賦值是刪除原值,賦予新值,初始化列表開闢空間和初始化是同時完成的,直接給與了一個值。

1.當類中含有const常量和引用成員變量時候,只能使用初始化不能對它們賦值,常量不能被賦值,只能被初始化,所以必須在初始化列表中完成,c++引用也一定要初始化,所以必須在初始化列表中完成

2.基類的構造函數都需要初始化列表,構造函數的意思是先開闢空間然後爲其賦值,只能算是賦值,不算初始化。

3.成員類型是沒有默認構造函數的類,若沒有提供顯示初始化,則編譯器隱式使用成員類型的默認構造函數,若類沒有默認構造函數,則編譯器嘗試用於默認構造函數將會失敗



因爲構造函數沒有返回值,所以通知對象的構造失敗的唯一方法就是在構造函數中拋出異常。


c++中空類會產生哪些成員函數:(6個)

默認構造函數,賦值構造函數,析構函數,賦值運算符重載函數,取地址運算符重載函數,const取地址運算符重載函數


虛函數:

指向基類的指針在操作它的多態對象時,會根據不同的類對象調用其相應的函數,這個函數就是虛函數,虛函數用virtual修飾函數名,虛函數的作業是在程序運行階段動態地選擇合適的成員函數,在定義了虛函數後,可以在基類的派生類中對虛函數進行重新定義。在派生類中重新定義的函數應與虛函數具有相同的形參個數和形參類型(參數類型的順序也要一致),以實現統一的接口,如果在派生類中沒有對虛函數重新定義,則繼承其基類的虛函數。


虛函數的使用可以大大地提高軟件開發的效率,虛函數是通過一張虛函數表(Virtual Table)來實現的,該表是一個類的虛函數的地址表,解決了繼承、覆蓋的問題、保證它能真實反應實際的函數。c++編譯器能夠保證虛函數表的指針存在於對象實例中的最前面的位置,通過對象實例的地址得到這張虛函數表,然後就可以遍歷其中的函數指針,並調用相應的函數。虛函數的本質就是通過基類訪問派生類定義的函數。


對於純虛函數,編譯器要求在派生類中予以重載以實現多態性。含有純虛函數的類稱爲抽象類,抽象類不能生產對象。純虛函數永遠不會被調用,它們主要用來統一管理子類對象。


基類的構造函數/析構函數是不能被派生類繼承的,派生類中需要聲明自己的構造函數。


什麼函數不能聲明爲虛函數:

1.只有類的成員函數才能說明爲虛函數

2.靜態成員函數不能爲虛函數,應爲調用靜態成員函數不需要實例,但調用虛函數需要從一個實例中指向虛函數表的指針,這樣就矛盾了

3,內聯函數不能爲虛函數

4.構造函數不能爲虛函數

5.析構函數可以爲虛函數,而且通常聲明爲虛函數


雖然虛函數很有效,但是不可以把每個函數都聲明爲虛函數,因爲使用虛函數是需要付出代價的,由於每個虛函數的對象在內存中都必須維護一個虛函數表,因此在使用虛函數時候,儘管帶來了使用方便,卻會額外產生一個系統開銷。


c++中可以通過使用抽象類,或者將構造函數聲明爲private阻止一個類被實例化。


用一條語句實現判斷x是否爲2的若干次冪的判斷:x&(x-1)判斷爲不爲0


逗號表達式的運算過程是從做往右,逗號表達式作爲一個整體,它的值爲最後一個表達式(也即表達式n)的值



數據庫

sql server不區分大小寫

oracle默認是區分大小寫


請熟悉常見的sql語句的操作


內連接值顯示覆合連接條件的記錄,外鏈接出了顯示符合連接條件的記錄外,還顯示左表中的記錄


事務是數據庫中一個單獨的執行單元(unit),它通常由高級數據庫操作語言(如SQL)或編程語言(如c++,java)書寫的用戶程序的執行所引起的。

事務必須滿足4個屬性:原子性(atomicity),一致性(consistency),隔離性(isolation),持久性(durability)即ACID4種屬性。

一般情況下,通過執行COMMIT或ROLLBACK語句來終止事務。


存取過程:實現編譯好的爲了完成某特定功能的sql語句(爲了提高效率)。


死鎖產生4個必要的條件:1.互斥 2,請求和保存等待 3,不可剝奪 4,環路等待


數據庫

sql server不區分大小寫

oracle默認是區分大小寫


請熟悉常見的sql語句的操作


 

關於數據庫幾種範式的理解


1,第一範式        數據庫表中的字段都是單一屬性的,不可再分。這個單一屬性由基本類型構成,包括整型、實數、字符型、邏輯型、日期型等。

2,第二範式      在第一範式的基礎上,第二範式要求數據庫表中的每個實例或行必須可以被惟一地區分。

如果關係模式R(U,F)中的所有非主屬性都完全依賴於任意一個候選關鍵字,則稱關係R 是屬於第二範式的。 
3,第三範式    如果關係模式R(U,F)中的所有非主屬性對任何候選關鍵字都不存在傳遞信賴,則稱關係R是屬於第三範式的。 

BCNF:如果關係模式R(U,F)的所有屬性(包括主屬性和非主屬性)都不傳遞依賴於R的任何候選關鍵字,那麼稱關係R是屬於BCNF的。或是關係模式R,如果每個決定因素都包含關鍵字(而不是被關鍵字所包含),則RCNF的關係模式。 


內連接值顯示覆合連接條件的記錄,外鏈接出了顯示符合連接條件的記錄外,還顯示左表中的記錄


事務是數據庫中一個單獨的執行單元(unit),它通常由高級數據庫操作語言(如SQL)或編程語言(如c++,java)書寫的用戶程序的執行所引起的。

事務必須滿足4個屬性:原子性(atomicity),一致性(consistency),隔離性(isolation),持久性(durability)即ACID4種屬性。

一般情況下,通過執行COMMIT或ROLLBACK語句來終止事務。


存取過程:實現編譯好的爲了完成某特定功能的sql語句(爲了提高效率)。


死鎖產生4個必要的條件:1.互斥 2,請求和保存等待 3,不可剝奪 4,環路等待


在併發環境下,一般可以採用多種機制來保證數據的一致性,例如oracle系統提供的事務級的一致性、行級鎖、表級鎖等


索引是一種提高數據庫查詢速度的機制,它是一個在數據庫的表或視圖上按照某個關鍵字段的值,升序或降序排序創建的對象。

遊標:提供了一種對從表中檢索的數據進行操作的靈活手段。它實際是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。


數據備份有:完全備份,差異備份,事務日誌備份,增量備份






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章