c++常見面試問題總結

c++和C語言的區別

C語言是面向結構性語言,C++是面嚮對象語言 c語言是c++的子集,c++包含了c語言的全部詞法和語法內容,比c語言多出了類。

 

程序運行的保存的五個區

堆 棧 常量 全局變量 代碼區

 

什麼是面向對象:注重的是對象,當解決一個問題的時候,面向對象會把事務抽象成一個對象,就是說問題裏有哪些對象,然後給對象賦一些屬性和方法,然後讓每個對象去執行自己的方法,最後解決問題

 

什麼是面向結構:注重過程,當解決一個問題的時候,面向過程會把事情拆分成:一個個函數,然後按照一定的順序執行完這些函數,然後把問題解決。

 

程序編譯的幾個步驟:

預處理:如頭文件這些 輸出i文件

編譯:將文本文件.i 翻譯成.s文件

彙編:  將文本文件.s翻譯成機器語言 輸出.o文件

鏈接:  將所有的.o文件處理合並 生成exe 可執行程序 被系統加載到內存裏面

 

靜態庫  只生成lib文件

動態庫的的寫法  定義宏導出 ,把需要導出的方法前面加上預定義宏__ENTRY  

生成 lib 和dll

#ifndef __DLLEXPORT__

#define  __ENTRY__  extern "C" _declspec (dllimport)

#else   

#define  __ENTRY__  extern "C" _declspec (dllexport)

#endif

 

 

靜態庫和動態庫的區別  

靜態庫是把運行程序所需的代碼全部鏈接到exe文件中 成爲exe的一部分 相對來說使用了靜態庫的程序 當多個程序調用相同的函數時,內存中存這個函數的多個拷貝,浪費寶貴的內存資源。

而動態庫中exe僅僅包含了函數的描述信息,往往是一些重定位信息,僅當程序被裝載到內存開始運行時,在window系統的管理下,纔在應用程序與相應的dll之間建立鏈接關係,一般情況下 一個程序使用了dll  那麼在內存中只有dll的一份複製品,由系統內存映射保證。

 

內存映射:dll首先被系統調入全局堆;棧,然後映射到調用這個dll的進程的地址空間,

在wind32系統中每個進程都有自己的地址空間。

 

庫顯示加載和隱式加載的區別

隱式加載:在編譯前需要知道dll中具體有哪些函數,需要導入庫文件

 

顯示加載:在編譯之前並不知道dll中的函數,而是在運行期間根據需要決定調用哪個函數,

通過調用loadLibrary獲得dll的函數入口地址 在調用GetProcAdress獲取函數的出口地址,然後通過函數返回的函數指針調用dll裏面的函數,可以避免導入庫文件

 

理解 線層同步  互斥的概念  區別:

所謂互斥就是指 多個線程通過競爭的方式進入進入臨界區,在有限時間內,往往只允許單個用戶訪問,具體排他性,也沒有順序 。

 同步是指多個線程之間彼此合作,通過一定的邏輯關係共同完成一個任務,同步操作中往往包含互斥,同步也可以說是一中複雜的互斥。相當以一個線層的開始執行,依賴於另一個線層執行的進度。 比如一個線層要開始執行,需要另一個線層業務作爲統治你,否則你就在那裏等。

一臺電腦最多能開啓多少數量的線程:

一臺電腦能開啓的線程的數量 取決於進程調度策略,虛擬內存,硬件上主要是 物理內存、cpu   一般理論上上來說  線程的分析空間爲一兆,一G內存大概是1024個

 

理解進程和線層的區別  

一個進程可以看做是一個獨立的程序,有着自己的地址空間,一個進程下面可以有多個線層。

線層只能訪問自己所屬進程下的變量,而不能誇進程。

 

進程間的通信方式

管道  socket  共享內存  消息隊列  信號量(用於控制進程間對共享內存資源的訪問) 信號

 

事件  createEvent()分手動重置 自動重置 

mutex  createmutex();可以看成簡易版的事件

臨界區(用戶去 非內核 速度最快,進程死鎖問題)互相等問題 initialCriticalSection()

信號量  類似於車位  

Promise----futrue 同步  

 

網絡七層 四層 模型的劃分: 

七層: 物理層 數據鏈路層 網絡層 傳輸層 會話層 表示層 應用層

四層:物理層 網絡層 傳輸層 應用層

 

簡述tcp的三次握手

Connet  客戶端請求連接  發送字段syn = 1

Accept    服務器確認接收客戶端的連接 回覆syn = 1 ack=1;

Write  客戶端向服務器發送ack = 1

 

四次揮手:

假設客戶端先發起斷連

客戶端向服務器發送fin = 1 請求釋放連接

服務器端收到後發送ack = 1

服務器向客戶端發送釋放連接請求 fin =1

客戶端收到回覆ack 等待2msl時間後關閉 服務器收到ack立刻關閉

 

Udp和tcp客戶端其實都可以綁定自身的IP端口,而服務器必須綁定端口 IP

 

單播:服務器:1創建sosket   2.bind服務器IP端口,3.recvFrom

 

客戶端:1.創建socket    

2. sockaddr_in addrto = { 0 };//客戶端也可以bind綁定端口ip(指定某個端口發送)不綁定的話 系統默認分配一個,下面填的端口是服務器的端口 往哪裏發得端口

  Addrto.sin_addr.S_un.S_addr = inet_addr(“192.168.0.1”) //發往的服務器Ip

  Addrto.sin_family = AF_INet;

  Addrto.sin_port = ::htons(30001); //和服務器一致的端口  要發往的端口                

sendto(sockClient,”hello”,6,reinterpret_cast<cosnst sockaddr>(&addrto),sizeof(addrto));

 

廣播:服務器:1創建sosket   2.bind服務器IP端口3設置廣播屬性.BOOL ebnable =true;

 setSockopt(sockclient,SOL_SOCKET,SO_BRODCAST,reinterpret_cast<constchar*>(&enable),sizeof(eanable))   

  1. recvFrom接收   

 

客戶端:1.創建socket()    

2. sockaddr_in addrto = { 0 };//客戶端也可以bind綁定端口ip(指定某個端口發送)不綁定的話 系統默認分配一個,下面填的端口是服務器的端口 往哪裏發得端口

 

  Addrto.sin_addr.S_un.S_addr = inet_addr(“192.168.0.1”) //發往的服務器廣播的話也可以是192.168.0.255

  Addrto.sin_family = AF_INet;

 Addrto.sin_port = ::htons(30001); //和服務器一致的端口  如果服務器端設置了廣播屬性的話,客戶端sendto255 所有服務器都可以收的到          

sendto(sockClient,”hello”,6,reinterpret_cast<cosnst sockaddr>(&addrto),sizeof(addrto));

 

組播:比廣播更好控制發送給誰 有限定作用

組播和廣播區別不大 區別在設置屬性的函數

Ip_mreq mrq;

Mrq.imr_multiaddr.S_un.S_addr = ::inet(“224.0.0.2”)//s設置加入哪個組 定義組播號

Mrq.imr_interface.S_un._s_addr = 0;//使用默認網卡//

Setsockopt(socksever,IPPROTO_IP,IP_ADD_MEMBERSHIP,rinterpret_cast<const char*>(&mrq),sizeof(mrq));

客戶端區別  sendto 往192.168.0.1發也可以 往服務器設置的組播地址發也可以。

 

Tcp和udp的區別:

TCP是流式、可靠的,面向連接的 相當與管道從一頭流向另外一頭 建立連接需要三次握手

UDP是面向非連接的,不可靠

Tcp是有序的 一對一  udp是無序的 可以一對多

Tcp效率較低,適用於準確性要求較高的場景

Udp效率較高,適用於實時通信。

 

static  const 類成員變量 成員方法  相關用法:  

static成員變量不屬於類不佔用類的空間大小,可以被一般類方法訪問。static成員方法只能訪問類的static成員變量和static方法。

const成員方法 方法後面加const 在const方法裏面不能修任何改成員變量

const成員變量 初初始列表 const全局變量 定義的時候需要賦值

cosnt引用  目的是爲了提高效率

 

智能能指針  

shared_ptr  

weak_ptr   用與觀察shared_ptr當前裝態 引用計數 是否釋放 無效等    

unique_ptr;//禁止拷貝

 boost ::auto_ptr

scoped_prt;  //禁止轉移所有權

 make_shared;   用於給shared_ptr 賦值  消除new和delete不平衡性質

 

c++和C語言的區別

C語言是面向結構性語言,C++是面嚮對象語言 c語言是c++的子集,c++包含了c語言的全部詞法和語法內容,比c語言多出了類。

 

程序運行的保存的五個區

堆 棧 常量 全局變量 代碼區

 

什麼是面向對象:注重的是對象,當解決一個問題的時候,面向對象會把事務抽象成一個對象,就是說問題裏有哪些對象,然後給對象賦一些屬性和方法,然後讓每個對象去執行自己的方法,最後解決問題

 

什麼是面向結構:注重過程,當解決一個問題的時候,面向過程會把事情拆分成:一個個函數,然後按照一定的順序執行完這些函數,然後把問題解決。

 

程序編譯的幾個步驟:

預處理:如頭文件這些 輸出i文件

編譯:將文本文件.i 翻譯成.s文件

彙編:  將文本文件.s翻譯成機器語言 輸出.o文件

鏈接:  將所有的.o文件處理合並 生成exe 可執行程序 被系統加載到內存裏面

 

靜態庫  只生成lib文件

動態庫的的寫法  定義宏導出 ,把需要導出的方法前面加上預定義宏__ENTRY  

生成 lib 和dll

#ifndef __DLLEXPORT__

#define  __ENTRY__  extern "C" _declspec (dllimport)

#else   

#define  __ENTRY__  extern "C" _declspec (dllexport)

#endif

 

 

靜態庫和動態庫的區別  

靜態庫是把運行程序所需的代碼全部鏈接到exe文件中 成爲exe的一部分 相對來說使用了靜態庫的程序 當多個程序調用相同的函數時,內存中存這個函數的多個拷貝,浪費寶貴的內存資源。

而動態庫中exe僅僅包含了函數的描述信息,往往是一些重定位信息,僅當程序被裝載到內存開始運行時,在window系統的管理下,纔在應用程序與相應的dll之間建立鏈接關係,一般情況下 一個程序使用了dll  那麼在內存中只有dll的一份複製品,由系統內存映射保證。

 

內存映射:dll首先被系統調入全局堆棧,然後映射到調用這個dll的進程的地址空間,

在wind32系統中每個進程都有自己的地址空間。

 

庫顯示加載和隱式加載的區別

隱式加載:在編譯前需要知道dll中具體有哪些函數,需要導入庫文件

顯示加載:在編譯之前並不知道dll中的函數,而是在運行期間根據需要決定調用哪個函數,

通過調用loadLibrary獲得dll的函數入口地址 在調用GetProcAdress獲取函數的出口地址,然後通過函數返回的函數指針調用dll裏面的函數,可以避免導入庫文件

 

 

理解 線層同步  互斥的概念  區別:

 

所謂互斥就是指 多個線程通過競爭的方式進入進入臨界區,在有限時間內,往往只允許單個用戶訪問,具體排他性,也沒有順序 。

 同步是指多個線程之間彼此合作,通過一定的邏輯關係共同完成一個任務,同步操作中往往包含互斥,同步也可以說是一中複雜的互斥。相當以一個線層的開始執行,依賴於另一個線層執行的進度。 比如一個線層要開始執行,需要另一個線層業務作爲統治你,否則你就在那裏等。

 

 

一臺電腦能開啓的線程的數量 取決於進程調度策略,虛擬內存,硬件上主要是 物理內存、cpu   一般理論上上來說  線程的分析空間爲一兆,一G內存大概是1024個

 

 

理解進程和線層的區別  

一個進程可以看做是一個獨立的程序,有着自己的地址空間,一個進程下面可以有多個線層。

線層只能訪問自己所屬進程下的變量,而不能誇進程。

 

 

進程間的通信方式

管道  socket  共享內存  消息隊列  信號量(用於控制進程間對共享內存資源的訪問) 信號

 

事件  createEvent()分手動重置 自動重置 

mutex  createmutex();可以看成簡易版的事件

臨界區(用戶去 非內核 速度最快,進程死鎖問題)互相等問題 initialCriticalSection()

信號量  類式車位  

Promise----futrue 同步  

 

 

網絡七層 四層 模型的劃分: 

七層: 物理層 數據鏈路層 網絡層 傳輸層 會話層 表示層 應用層

四層:物理層 網絡層 傳輸層 應用層

 

簡述tcp的三次握手

Connet  客戶端請求連接  發送字段syn = 1

Accept    服務器確認接收客戶端的連接 回覆syn = 1 ack=1;

Write  客戶端向服務器發送ack = 1

 

四次揮手:

假設客戶端先發起斷連

客戶端向服務器發送fin = 1 請求釋放連接

服務器端收到後發送ack = 1

服務器向客戶端發送釋放連接請求 fin =1

客戶端收到回覆ack 等待2msl時間後關閉 服務器收到ack立刻關閉

http協議   結構 包含起始行 報文

Udp和tcp客戶端其實都可以綁定自身的IP端口,而服務器必須綁定端口 IP

 

單播:服務器:1創建sosket   2.bind服務器IP端口,3.recvFrom

 

客戶端:1.創建socket    

2. sockaddr_in addrto = { 0 };//客戶端也可以bind綁定端口ip(指定某個端口發送)不綁定的話 系統默認分配一個,下面填的端口是服務器的端口 往哪裏發得端口

 

  Addrto.sin_addr.S_un.S_addr = inet_addr(“192.168.0.1”) //發往的服務器Ip

  Addrto.sin_family = AF_INet;

  Addrto.sin_port = ::htons(30001); //和服務器一致的端口  要發往的端口                

sendto(sockClient,”hello”,6,reinterpret_cast<cosnst sockaddr>(&addrto),sizeof(addrto));

 

廣播:服務器:1創建sosket   2.bind服務器IP端口3設置廣播屬性.BOOL ebnable =true;

 setSockopt(sockclient,SOL_SOCKET,SO_BRODCAST,reinterpret_cast<constchar*>(&enable),sizeof(eanable))   

  1. recvFrom接收   

 

 

客戶端:1.創建socket()    

2. sockaddr_in addrto = { 0 };//客戶端也可以bind綁定端口ip(指定某個端口發送)不綁定的話 系統默認分配一個,下面填的端口是服務器的端口 往哪裏發得端口

 

  Addrto.sin_addr.S_un.S_addr = inet_addr(“192.168.0.1”) //發往的服務器廣播的話也可以是192.168.0.255

  Addrto.sin_family = AF_INet;

 Addrto.sin_port = ::htons(30001); //和服務器一致的端口  如果服務器端設置了廣播屬性的話,客戶端sendto255 所有服務器都可以收的到          

sendto(sockClient,”hello”,6,reinterpret_cast<cosnst sockaddr>(&addrto),sizeof(addrto));

 

組播:比廣播更好控制發送給誰 有限定作用

組播和廣播區別不大 區別在設置屬性的函數

 

Ip_mreq mrq;

Mrq.imr_multiaddr.S_un.S_addr = ::inet(“224.0.0.2”)//s設置加入哪個組 定義組播號

Mrq.imr_interface.S_un._s_addr = 0;//使用默認網卡//

Setsockopt(socksever,IPPROTO_IP,IP_ADD_MEMBERSHIP,rinterpret_cast<const char*>(&mrq),sizeof(mrq));

客戶端區別  sendto 往192.168.0.1發也可以 往服務器設置的組播地址發也可以。

 

Tcp和udp的區別:

TCP是流式、可靠的,面向連接的 相當與管道從一頭流向另外一頭 建立連接需要三次握手

UDP是面向非連接的,不可靠

Tcp是有序的 一對一  udp是無序的 可以一對多

Tcp效率較低,適用於準確性要求較高的場景

Udp效率較高,適用於實時通信。

 

static const類成員變量 成員方法  相關注意事項:  

static成員變量不屬於類不佔用類的空間大小,可以被一般類方法訪問。static成員方法只能訪問類的static成員變量和static方法。

 

const成員方法 方法後面加const 在const方法裏面不能修任何改成員變量

const成員變量 初初始列表 const全局變量 定義的時候需要賦值

cosnt引用  目的是爲了提高效率

 

智能能指針  

shared_ptr  

weak_ptr   用與觀察shared_ptr當前裝態 引用計數 是否釋放 無效等    

unique_ptr;//禁止拷貝

 boost ::auto_ptr

scoped_prt;  //禁止轉移所有權

 make_shared;   用於給shared_ptr 賦值  消除new和delete不平衡性質

 

stl 容器的迭代和刪除

Map 紅黑樹實現  鍵值對

Set  集合  裏面的元素對象不能重複

List  鏈表

Vector  動態數組

mutliSet  可重複集合

mutliLMap  一鍵對多值

仿函數: 就是一個類重載了()方法 看上去有點像函數

 

c++三大特性 :

繼承 :子類繼承基類  三種繼承方式 -基類的私有成員 子類和外部都是不能訪問的

封裝:隱藏細節,private和protect變量 外部不可訪問

多態:靜態多態  重載

動態多態 虛函數  重寫

虛函數表:指向 指針數組的指針  void(*a)[]

 

設計模式:

單例模式:

觀察者模式:

適配器模式:

 工廠模式:

 

及不用虛函數實現c++多態的方式   通過類模板的方式 藉助靜態類型轉換的方式  在基類裏面講將數接口在包一層。 WTL裏面很多類似這樣的做法

 

菱形繼承 +virtual  

 

爲什麼類作爲基類 析構函數最好是虛函數

Pbase * base = new child;  虛函數機制的話 根據實際對象調用析構函數;

Delete base;            不是虛函數機制的話,這樣會調用基類的析構函數,而導致子類的無法釋放

 

 

c++ 四種轉換:

  dynaimc_cast    動態類型轉換 鑑別真僞 條件:類 繼承 virtual

  Base *pBase = new Base;

  Child *pChild = dynamic_cast<Child*>(pBase); //鑑別實際對象和實際類型是否一致 這裏轉換失敗 : 下行轉換

  Base *pBase = new Child ;

  Child *pChild = dynamic_cast<Child*>(pBase); //鑑別實際對象和實際類型是否一致 這裏轉換成功

 

  static_cast   靜態類型轉換       類 繼承 可以基礎類型之間轉換如float轉換成int  下行轉換也是OK 用上面1的例子是可以轉換成功的只看指針類型

  reinterpret_cast          無關係的類之間也可以,基礎類型與類之間的轉換,類型與c語言的強制轉換

  const_cast<>       const 指針之間的轉換

  

  int value1 = 1;

  int value2 = 2;

  const int* pvalue =&value1;   

  *pvalue = 9;   //錯 指針常量 指向的值不讓修改

   pvalue = &value2; //對

 

  int* const pvalue =&value1;

  *pvalue = 9;   //對

   pvalue = &value2; //錯 常量指針 指針不讓修改

 

const int* const pvalue =&value1;   

  *const_cast<int* const>(pvalue) = 9;  //去掉const 可以修改

 

 int* const pvalue =&value1;

 cosnt_const<const int *>(pvalue) = &value2//去掉對應的const

 

memcpy 及帶內存重疊的實現

 

右值引用 深拷貝 淺拷貝:

類構造函數

A() = deafault   用於類中自己定義了構造函數 仍需要默認構造函數的情況 不然A a 這樣調用或報錯  必須A a(3)這樣傳一個參數。

A() = delete   //相當於這個類不能用

A() = explicit  // 相當於這個類不能隱式的調用  不能 A a = 5;只能A a(5);

 

迭代器iterator和指針的區別

迭代器是一個函數 只是重載了* ->這些符號

 

widows窗口程序的幾個步驟:  

創建窗口類  註冊窗口register: 創建窗口  顯示更新窗口   獲取窗口消息getmessage() 獲取後dispatch消息 調用窗口處理函數

動態類型  看實際對象類型

靜態類型(不加virtual)看左側指針類型:決定調用子類還是父類的方法 static下行轉換也是OK的

 

回去驗證 不存在虛函數 繼承之間的重寫  靜態類型static_cast Base*pBase = new Base;

                                                          Child * pChild = static_cast<Child*>(pBase);

 pChild ->show()  看看是調用基類還是之類的方法 期望調用子類的方法  然後去掉子類重寫的方法看看調用的是不是基類的方法

然後子類不重寫 看看是不是會調用基類類型的方法

 

iocp完成端口

完成端口等於異步IO+線層池 1.先建立一個空的完成端口IOCP = WASCreateIoCompletePort(),2.創建一定數量的線程,3.在WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr),overlapped這裏面需要創建事件overlapped.event = WASCreateEvent();之後,不同於重疊IO 不是通過getoverlapped獲取結果,通過線層池喚醒線層對接受的數據進行相關的業務處理,再次調用WASCreateIoCompletePort((HANDLE)sockClient,IOCP,/*傳入的參數,完成建*/,/線程的數量/)進行投遞到完成端口的隊列,申明線層函數,在線層函數等待一個完成端口的事件::GetQueuedCompletionStatus(iocp,totalRecvCount,/完成件/,overlapped,infinity),裏面通過傳入的完成建將wasbuff打印出來。

 

重疊端口:

WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr);/獲取數據 GetOverlappedResult((HANDLE)sockclint),&overlapped,&recvCount,,true); 系統通知你的時候把輸入操作已經幫你做了。

 

異步選擇事件:

事件和套接字綁定HANDLE aSock[50];

 HANDLE aEvent[50];

aEvent[0] = WSACreateEvent(); 創建事件

accept和recv需要由事件來通知  通過asock = socksever ;  WASEventSelect(sockserver,aEvent,FD_ACCEPT)中相關參數設置 accepte和recv的方式 用 ireturn = WSAWaitFormutilpleEvent(iicurrentNUm,aEvent,false,INFINITY,0)等待相應的事件置位 返回值是綁定對應數組的下標 由下標判斷是哪個事件置位 accept還是recv

 

異步選擇消息模型:通過windows消息的機制觸發 消息到了 肯定是有accept用戶連接 或者recv到數據了

線層池:

  1. 創建一定數量線層  創建事件 用於控制線層的退出  初始化信號量  裏面車位剛開始位滿 控制活躍的線層屬  初始化臨界區 用於控制讀取任務的互斥
  2.  線層函數裏面一個大循環,WaitForSingleObject(ms_pThreadPool->m_hSemaphore, INFINITE);  等待信號量提升 在addtask的時候提升信號量的空位

 

boost庫  字符算法、智能指針、

 

 

數據庫:

Mysql:

Mysqld  --install  //數據庫安裝

Net start mysql //數據庫服務啓動

Net stop mysql //停止數據庫服務

Mysqld  --remove  卸載數據庫

 

Select database()  當前使用的數據庫

Mysql -uroot   以管理員前線登錄

Show tables  查看當前數據庫有多少表

show databases  //查看當前數據庫所有數據庫

Use test   //使用哪個數據庫

Show engines  查看數據使用的哪種引擎

當前主要使用較多的兩種:1、myisan 2 innodb 支持事務

 

Drop table dd; //刪表

 

數據類型  decimal(p,s)//小數類型 前面是整數+小數一共的位數,後面是小數的位數

 

Crate datebase yy  建立數據庫yy

 

//查看建立數據庫語句

 Show create databse  ‘db’;

 

//建立一張表 id不能爲負 可以null填充 不足六個整數前面用0填充 插入一條記錄自增id

表尾 代表 引擎使用myisam 自增賦初值爲5 編碼格式使用gutf8

 Crate table dd(

 Id  INT(6) UNSIGNED  ZEROFILL  NOT NULL  AUTO_INCREMENT,

 Name VARCHAR(20) ,

 Sgender ENUM(‘男’,’女’,保密’’),

 PRIMARY_KEY(id)

)ENGINE=MYISAM  AUTO_INCREMENT =5  DEFAULT CHARSET = UTF8;

 

//查看錶結構

//desc dd;

 

//修改表名:、

Rename table dd to student

 

//修改表中字段名及類型

Alter table dd change id tid int(8);

Alter table name sname varchar(30);

 

//給表增加一列

Alter table dd ADD score tinyint;

 

//在表中哪一列後增加一列

Alter table dd address varchar(80) after id;

 

//在表中刪除某一列

Alter tabel dd drop COLUMN  address;

 

//插入

Insert  dd  valules(null,’李四’,’男’);

Insert  into dd values(null,’李四’,’男);

//插如多條記錄

Insert  dd  valules(null,’李四’,’男’),Insert  into dd values(null,’李四’,’男);

//選擇性插入

Insert dd(id,name) values(6,‘張三’);

//將表全部查出來在插入一遍

Insert into student(id,name,Sgender)select id name Sgender from dd;

 

 

//修改數據

Update student set Sgender = ‘男’ where name = ‘李四’

Update student set Sgender = ‘男’ ,id = 10 where name = ‘李四’

 

//刪除數據

Delete from dd where id  = 8;

Delete form dd  //無條件刪除所有記錄

Delete from dd where name like ‘張’;刪除姓張的

 

//查詢

Select  * from dd

 

只顯示姓名 成績 以別名的形式

Select  name 姓名 ,id 學號 from student;

 

成績小於八十的

Select *form student where score<80;

 

查詢條件 between  and

Select * from student where score between 80 and 90;

 

基本條件like 條件%

查詢姓名兩個字的學生信息

Select *from student  where name like ‘__’;  兩個下劃線

Select *from student  where name like ‘張_’; 姓張的 名字兩個字的

Select*from student where name ‘ %麗%’;名字有麗的  %代表一個和多個

 

基本條件查詢 in() not in  多個範圍

Select *from student where id in(8,9,10);

Select *from student where id not in(8,9,10);

 

基本條件運算 null  用is null 或 is not null

Select *from student where score is null

Update sutdent set scor = 0 where score is null;

 

分組查詢  聚集 集合函數  主要配合分組  group by

 

Max()

Avg()

Count() 統計多少條記錄

Sum()

Select avg(score) from student;

查詢最高分

Select max(score) from student;

查詢最高分學生的信息

Select *from student where score in(select max(score) from student);

統計多少人

Select cont(*)  from student

 

Select max(score)最高分, min(score) 最低分 from student;

 

查詢各地區的人數

Select count(*) from student group by adress;

注意:在分組查詢過程,只能出現聚集函數和分組字段 下面:

Select count(*) 人數,address 地區 from student group by adress  對

Select count(*) 人數,address 地區 , sname  姓名 from student group by adress  錯  出現了名字 不是分組字段

 

Select count(*) 人數,address 地區 from student

Where address is not null  --條件   分組前  成績爲空 不參加分組

group by adress       -- 分組字段

Order by count(*) DESC; --根據人數降序

 

 

 

分組條件 分完組後按條件查詢 需要放在 group by 後面

Select count(*) 人數,address 地區 from student

Where address is not null  --條件   分組前  成績爲空 不參加分組

group by adress       -- 分組字段

Having count(*)>2   --  分組後條件  分組後人數大於2的地區

Order by count(*) DESC; --根據人數降序

 

連接查詢

建立兩個表一個學生 一個老師

學生表裏麪包含老師的ID

 

多表查詢  公司不推薦

Select  s.name ,s.sgender* fronm s ,t where s.tid  = t.tid;

連接查詢  join  left join rignt join

Select s.name s.sgender from s left join  t  on s.tid  = t.tid;

 

Mysql 的約束

主鍵約束  primary key

默認約束  defaut

非空約束 not null

外鍵越蘇  foreign key reference僅支持引擎爲INoodb

Create table t

(

Tid  int unsigned not null auto increment

Tname varchar(20)

Key(tname) --建立表的時候 同事建立索引 名字不能重複

Primary_key(tid)

)

 

Create table t

(

sid  int unsigned not null auto increment,

sname varchar(20),

Tid int unsigned ,

Primary_key(tid)

Constraint fk foreign key (tid) reference t(tid)--建立外鍵 關聯到teacher表

)

由於存在外鍵 刪除某一項老師記錄需要對應的學生不存在,刪除老師表之前需要刪除學生表 不然不讓刪除老師表  解決方案如下  級聯刪除

Create table t

(

sid  int unsigned not null auto increment,

sname varchar(20),

Tid int unsigned ,

Primary_key(tid)

Constraint fk foreign key (tid) reference t(tid) on delete cascade

)

加上on delete casecade 就能刪除教師記錄  但是還是不能刪除教師表 除非先刪除學生表

 

主鍵 不能爲空 ,不能重複

外鍵  一遍一個表的外鍵指向 另外一個表的主鍵 且類型一致

增加一個表的主鍵()

alter table tt add constranit pk primary key(name);

增加一個表主鍵

Alter table tt drop primary key  

建立索引 方便檢索數據  類似於書籍的目錄  建立主鍵的時候 主鍵就是一個索引

Create index iia on(tname desc);

Alter table tt add index (tname desc);

 

刪除索引

Drop index iia on teacher;

Alter table tt drop index tname;

 

常用函數:

Select length(‘ghh’);長度

Select * from student where sname like ‘__’;

Select *from student where char_lenth(sname) = 2;

 

//隨機查詢出兩條記錄

Select *from student order by rand() limit 

查詢天前的日期

Selet date_add(now(),interval -10 day);

 

查詢10後的日期

Selet date_add(now(),interval 10 day);

 

存儲過程 

沒有明確的返回值 編譯後再服務器執行 熟讀快

經過編譯後存儲在數據庫中,用戶通過 存儲過程名字,並給出參數來執行它

函數 函數有返回值

 

Map 紅黑樹實現  鍵值對

Set  集合  裏面的元素對象不能重複

List  鏈表

Vector  動態數組

mutliSet  可重複集合

mutliLMap  一鍵對多值

仿函數: 就是一個類重載了()方法 看上去有點像函數

c++三大特性 :

繼承 :子類繼承基類  三種繼承方式

封裝:隱藏細節,private和protect變量 外部不可訪問

多態:靜態多態  重載

動態多態 虛函數  重寫

 

虛函數表:指向 指針數組的指針  void(*a)[]

 

設計模式:

單例模式:

觀察者模式:

適配器模式:

 工廠模式:

 

及不用虛函數實現c++多態的方式   通過類模板的方式 藉助靜態類型轉換的方式  在基類裏面講將數接口在包一層。 WTL裏面很多類似這樣的做法

 

菱形繼承 +virtual  

 

爲什麼類作爲基類 析構函數最好是虛函數

Pbase * base = new child;  虛函數機制的話 根據實際對象調用析構函數;

Delete base;            不是虛函數機制的話,這樣會調用基類的析構函數,而導致子類的無法釋放

 

 

c++ 四種轉換:

  dynaimc_cast    動態類型轉換 鑑別真僞 條件:類 繼承 virtual

  

  Base *pBase = new Base;

  Child *pChild = dynamic_cast<Child*>(pBase); //鑑別實際對象和實際類型是否一致 這裏轉換失敗 : 下行轉換

 

  Base *pBase = new Child ;

  Child *pChild = dynamic_cast<Child*>(pBase); //鑑別實際對象和實際類型是否一致 這裏轉換成功

 

 

 

  static_cast   靜態類型轉換       類 繼承 可以基礎類型之間轉換如float轉換成int  下行轉換也是OK 用上面1的例子是可以轉換成功的只看指針類型

  reinterpret_cast          無關係的類之間也可以,基礎類型與類之間的轉換,類型與c語言的強制轉換

  const_cast<>       const 指針之間的轉換

  

  int value1 = 1;

  int value2 = 2;

  const int* pvalue =&value1;   

  *pvalue = 9;   //錯 指針常量 指向的值不讓修改

   pvalue = &value2; //對

 

  int* const pvalue =&value1;

  *pvalue = 9;   //對

   pvalue = &value2; //錯 常量指針 指針不讓修改

 

const int* const pvalue =&value1;   

  *const_cast<int* const>(pvalue) = 9;  //去掉const 可以修改

 

 int* const pvalue =&value1;

 cosnt_const<const int *>(pvalue) = &value2//去掉對應的const

 

memcpy 及帶內存重疊的實現

 

右值引用 深拷貝 淺拷貝:

 

類構造函數

A() = deafault   用於類中自己定義了構造函數 仍需要默認構造函數的情況 不然A a 這樣調用或報錯  必須A a(3)這樣傳一個參數。

A() = delete   //相當於這個類不能用

A() = explicit  // 相當於這個類不能隱式的調用  不能 A a = 5;只能A a(5);

 

迭代器iterator和指針的區別

迭代器是一個函數 只是重載了* ->這些符號

 

 

 

widows窗口程序的幾個步驟:  

 

創建窗口類  註冊窗口register: 創建窗口  顯示更新窗口   獲取窗口消息getmessage() 獲取後dispatch消息 調用窗口處理函數

 

動態類型  看實際對象類型

靜態類型(不加virtual)看左側指針類型:決定調用子類還是父類的方法 static下行轉換也是OK的

 

回去驗證 不存在虛函數 繼承之間的重寫  靜態類型static_cast Base*pBase = new Base;

                                                          Child * pChild = static_cast<Child*>(pBase);

 pChild ->show()  看看是調用基類還是之類的方法 期望調用子類的方法  然後去掉子類重寫的方法看看調用的是不是基類的方法

然後子類不重寫 看看是不是會調用基類類型的方法

 

iocp完成端口 完成端口等於異步IO+線層池 1.先建立一個空的完成端口IOCP = WASCreateIoCompletePort(),2.創建一定數量的線程,3.在WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr),overlapped這裏面需要創建事件overlapped.event = WASCreateEvent();之後,不同於重疊IO 不是通過getoverlapped獲取結果,通過線層池喚醒線層對接受的數據進行相關的業務處理,再次調用WASCreateIoCompletePort((HANDLE)sockClient,IOCP,/*傳入的參數,完成建*/,/線程的數量/)進行投遞到完成端口的隊列,申明線層函數,在線層函數等待一個完成端口的事件::GetQueuedCompletionStatus(iocp,totalRecvCount,/完成件/,overlapped,infinity),裏面通過傳入的完成建將wasbuff打印出來。

 

重疊端口:WSARecv(sockClinet,wsaBuf,1,&recvCount,&dwFalg,overlapped,nullptr);/獲取數據 GetOverlappedResult((HANDLE)sockclint),&overlapped,&recvCount,,true); 系統通知你的時候把輸入操作已經幫你做了。

 

異步選擇事件:事件和套接字綁定HANDLE aSock[50];

 HANDLE aEvent[50];

aEvent[0] = WSACreateEvent(); 創建事件

accept和recv需要由事件來通知  通過asock = socksever ;  WASEventSelect(sockserver,aEvent,FD_ACCEPT)中相關參數設置 accepte和recv的方式 用 ireturn = WSAWaitFormutilpleEvent(iicurrentNUm,aEvent,false,INFINITY,0)等待相應的事件置位 返回值是綁定對應數組的下標 由下標判斷是哪個事件置位 accept還是recv

 

 

異步選擇消息模型:通過windows消息的機制觸發 消息到了 肯定是有accept用戶連接 或者recv到數據了

 

線層池:

  1. 創建一定數量線層  創建事件 用於控制線層的退出  初始化信號量  裏面車位剛開始位滿 控制活躍的線層屬  初始化臨界區 用於控制讀取任務的互斥
  2.  線層函數裏面一個大循環,WaitForSingleObject(ms_pThreadPool->m_hSemaphore, INFINITE);  等待信號量提升 在addtask的時候提升信號量的空位

 

boost庫  字符算法、智能指針、

 

 

數據庫:

Mysql:

 

Mysqld  --install  //數據庫安裝

Net start mysql //數據庫服務啓動

Net stop mysql //停止數據庫服務

Mysqld  --remove  卸載數據庫

 

Select database()  當前使用的數據庫

Mysql -uroot   以管理員前線登錄

Show tables  查看當前數據庫有多少表

show databases  //查看當前數據庫所有數據庫

Use test   //使用哪個數據庫

Show engines  查看數據使用的哪種引擎

當前主要使用較多的兩種:1、myisan 2 innodb 支持事務

 

Drop table dd; //刪表

 

數據類型  decimal(p,s)//小數類型 前面是整數+小數一共的位數,後面是小數的位數

 

Crate datebase yy  建立數據庫yy

 

//查看建立數據庫語句

 Show create databse  ‘db’;

 

//建立一張表 id不能爲負 可以null填充 不足六個整數前面用0填充 插入一條記錄自增id

表尾 代表 引擎使用myisam 自增賦初值爲5 編碼格式使用gutf8

 Crate table dd(

 Id  INT(6) UNSIGNED  ZEROFILL  NOT NULL  AUTO_INCREMENT,

 Name VARCHAR(20) ,

 Sgender ENUM(‘男’,’女’,保密’’),

 PRIMARY_KEY(id)

)ENGINE=MYISAM  AUTO_INCREMENT =5  DEFAULT CHARSET = UTF8;

 

//查看錶結構

//desc dd;

 

//修改表名:、

Rename table dd to student

 

//修改表中字段名及類型

Alter table dd change id tid int(8);

Alter table name sname varchar(30);

 

//給表增加一列

Alter table dd ADD score tinyint;

 

//在表中哪一列後增加一列

Alter table dd address varchar(80) after id;

 

//在表中刪除某一列

Alter tabel dd drop COLUMN  address;

 

//插入

Insert  dd  valules(null,’李四’,’男’);

Insert  into dd values(null,’李四’,’男);

//插如多條記錄

Insert  dd  valules(null,’李四’,’男’),Insert  into dd values(null,’李四’,’男);

//選擇性插入

Insert dd(id,name) values(6,‘張三’);

//將表全部查出來在插入一遍

Insert into student(id,name,Sgender)select id name Sgender from dd;

 

 

//修改數據

Update student set Sgender = ‘男’ where name = ‘李四’

Update student set Sgender = ‘男’ ,id = 10 where name = ‘李四’

 

//刪除數據

Delete from dd where id  = 8;

Delete form dd  //無條件刪除所有記錄

Delete from dd where name like ‘張’;刪除姓張的

 

//查詢

Select  * from dd

 

只顯示姓名 成績 以別名的形式

Select  name 姓名 ,id 學號 from student;

 

成績小於八十的

Select *form student where score<80;

 

查詢條件 between  and

Select * from student where score between 80 and 90;

 

基本條件like 條件%

查詢姓名兩個字的學生信息

Select *from student  where name like ‘__’;  兩個下劃線

Select *from student  where name like ‘張_’; 姓張的 名字兩個字的

Select*from student where name ‘ %麗%’;名字有麗的  %代表一個和多個

 

基本條件查詢 in() not in  多個範圍

Select *from student where id in(8,9,10);

Select *from student where id not in(8,9,10);

 

基本條件運算 null  用is null 或 is not null

Select *from student where score is null

Update sutdent set scor = 0 where score is null;

 

分組查詢  聚集 集合函數  主要配合分組  group by

 

Max()

Avg()

Count() 統計多少條記錄

Sum()

Select avg(score) from student;

查詢最高分

Select max(score) from student;

查詢最高分學生的信息

Select *from student where score in(select max(score) from student);

統計多少人

 

Select cont(*)  from student

 

Select max(score)最高分, min(score) 最低分 from student;

 

查詢各地區的人數

Select count(*) from student group by adress;

注意:在分組查詢過程,只能出現聚集函數和分組字段 下面:

Select count(*) 人數,address 地區 from student group by adress  對

Select count(*) 人數,address 地區 , sname  姓名 from student group by adress  錯  出現了名字 不是分組字段

 

Select count(*) 人數,address 地區 from student

Where address is not null  --條件   分組前  成績爲空 不參加分組

group by adress       -- 分組字段

Order by count(*) DESC; --根據人數降序

 

 

 

分組條件 分完組後按條件查詢 需要放在 group by 後面

Select count(*) 人數,address 地區 from student

Where address is not null  --條件   分組前  成績爲空 不參加分組

group by adress       -- 分組字段

Having count(*)>2   --  分組後條件  分組後人數大於2的地區

Order by count(*) DESC; --根據人數降序

 

連接查詢

建立兩個表一個學生 一個老師

學生表裏麪包含老師的ID

 

多表查詢  公司不推薦

Select  s.name ,s.sgender* fronm s ,t where s.tid  = t.tid;

連接查詢  join  left join rignt join

Select s.name s.sgender from s left join  t  on s.tid  = t.tid;

 

 

Mysql 的約束

主鍵約束  primary key

默認約束  defaut

非空約束 not null

外鍵越蘇  foreign key reference僅支持引擎爲INoodb

Create table t

(

Tid  int unsigned not null auto increment

Tname varchar(20)

Key(tname) --建立表的時候 同事建立索引 名字不能重複

Primary_key(tid)

)

 

Create table t

(

sid  int unsigned not null auto increment,

sname varchar(20),

Tid int unsigned ,

Primary_key(tid)

Constraint fk foreign key (tid) reference t(tid)--建立外鍵 關聯到teacher表

)

由於存在外鍵 刪除某一項老師記錄需要對應的學生不存在,刪除老師表之前需要刪除學生表 不然不讓刪除老師表  解決方案如下  級聯刪除

Create table t

(

sid  int unsigned not null auto increment,

sname varchar(20),

Tid int unsigned ,

Primary_key(tid)

Constraint fk foreign key (tid) reference t(tid) on delete cascade

)

加上on delete casecade 就能刪除教師記錄  但是還是不能刪除教師表 除非先刪除學生表

 

 

主鍵 不能爲空 ,不能重複

外鍵  一遍一個表的外鍵指向 另外一個表的主鍵 且類型一致

 

增加一個表的主鍵()

alter table tt add constranit pk primary key(name);

 

增加一個表主鍵

Alter table tt drop primary key  

 

建立索引 方便檢索數據  類似於書籍的目錄  建立主鍵的時候 主鍵就是一個索引

Create index iia on(tname desc);

Alter table tt add index (tname desc);

 

刪除索引

Drop index iia on teacher;

Alter table tt drop index tname;

 

常用函數:

Select length(‘ghh’);長度

Select * from student where sname like ‘__’;

Select *from student where char_lenth(sname) = 2;

 

//隨機查詢出兩條記錄

Select *from student order by rand() limit 

查詢天前的日期

Selet date_add(now(),interval -10 day);

 

查詢10後的日期

Selet date_add(now(),interval 10 day);

 

存儲過程 

沒有明確的返回值 編譯後再服務器執行 熟讀快

經過編譯後存儲在數據庫中,用戶通過 存儲過程名字,並給出參數來執行它

函數 函數有返回值

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