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))
- 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))
- 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到數據了
線層池:
- 創建一定數量線層 創建事件 用於控制線層的退出 初始化信號量 裏面車位剛開始位滿 控制活躍的線層屬 初始化臨界區 用於控制讀取任務的互斥
- 線層函數裏面一個大循環,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到數據了
線層池:
- 創建一定數量線層 創建事件 用於控制線層的退出 初始化信號量 裏面車位剛開始位滿 控制活躍的線層屬 初始化臨界區 用於控制讀取任務的互斥
- 線層函數裏面一個大循環,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);
存儲過程
沒有明確的返回值 編譯後再服務器執行 熟讀快
經過編譯後存儲在數據庫中,用戶通過 存儲過程名字,並給出參數來執行它
函數 函數有返回值