- c++和c的區(qū)別 發(fā)布文章
面向過程、面向對象
C++中new和delete是對內存分配的運算符,引用、類、函數重載,C++ 用析構函數回收垃圾,C中的malloc和free、函數的開頭處聲明和定義而C++隨時定義隨時使用;
函數重載:函數名稱相同 ,參數不同
什么是面向對象?面向對象的幾大特性是什么? 繼承、封裝、多態(tài)的特性。
-
c++內存分配
棧局部變量 編譯器自由管理 ;默認1M ,變量通常是局部變量、函數參數、指針等
堆 malloc、free 產生碎片問題 32位 4g
自由存儲區(qū):new與delete動態(tài)分配和釋放的對象的存儲區(qū),頻繁動態(tài)分配會導致堆破碎風險
全局/靜態(tài)存儲區(qū):全局變量又分為初始化的和未初始化的,未被初始化的對象存儲區(qū)可以通過 void* 來訪問和操縱
常量存儲區(qū)
棧和堆:管理方式(編譯器、手動分配)、空間大?。?2 位堆內存可達到4G,堆內存幾乎是沒有什么限制,棧一般都是有一定的空間大小的,默認1M )、生長方向(堆是先進先出,棧是先進后出)、分配方式(堆都是動態(tài)分配的、棧有2種分配方式:靜態(tài)分配和動態(tài)分配,靜態(tài)分配是編譯器完成的,比如局部變量的分配。動態(tài)分配由 malloc 函數進行分配)、分配效率不同(堆的效率比棧要低得多)
-
構造函數和析構函數可否為虛函數:
構造函數不能為虛函數,而析構函數可以且常常是虛函數。
c++對象構建三個地方:函數堆棧、自由存儲區(qū)(堆 )、靜態(tài)存儲區(qū) ;如果構造函數是虛函數,那么就需要通過vtable來調用,vtable 是在構造函數中才初始化的。
構造函數可否調用虛函數,會有什么后果?
在基類構造的時候,虛函數是非虛,不會走到派生類中,既是采用的靜態(tài)綁定,如果在基類的構造中調用虛函數,如果可以的話就是調用一個還沒有被初始化的對象,總只能調用到基類的虛函數,無法調用到子類的虛函數
類的內存分布(成員函數不占內存),虛表
在非虛繼承的情況下,虛函數指針是存在于類的頂部的,如果虛繼承的子類中沒有新的虛函數,那新的虛函數表指針也將不復存在。
智能指針,內存泄漏怎么檢測
忘記delete,內存泄漏;2、還有指針引用,就釋放 了對象,產生非法內存指針,auto_ptr、unique_ptr和shared_ptr,將基本類型指針封裝為類對象指針(這個類肯定是個模板,以適應不同基本類型的需求),并在析構函數里編寫delete語句刪除指針指向的內存空間。
auto_ptr主要是用來解決資源自動釋放的問題 auto_ptr<Obj> ptr( new Obj(20) )
unique_ptr可以對象的引用比較專一,不允許隨隨便便的進行轉移。
auto_ptr和unique_ptr都只能一個智能指針引用對象,而shared_ptr則是可以多個智能指針同時擁有一個對象。
shared_ptr是一種強引用的關系,智能指針直接引用對象。那么這個會代碼一個隱含的問題,就是循環(huán)引用,從而造成內存泄漏
auto_ptr<Obj> ap(new Obj() ); auto_ptr<Obj> one (ap) ; // ok auto_ptr<Obj> two = one; //ok
unique_ptr<Obj> ap(new Obj() ); unique_ptr<Obj> one (ap) ; // 會出錯 unique_ptr<Obj> two = one; //會出錯
消息隊列:主要解決應用解耦,異步消息,流量削鋒等問題,實現高性能,高可用msgget、msgrcv、msgctl msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1
-
指針和引用的區(qū)別
指針保存的是指向對象的地址,引用相當于變量的別名,引用在定義的時候必須初始化,指針沒有這個要求
指針可以改變地址,引用必須從一而終
不存在空應引用,但是存在空指針NULL,相對而言引用更加安全
引用的創(chuàng)建不會調用類的拷貝構造函數,拷貝構造函數,它只有一個參數,參數類型是本類的引用。 class Complex ; Complex cl(1, 2); Complex c2 (cl);
-
new/delete與malloc/free的區(qū)別
new是運算符(數據類型)、可以重載,malloc是C語言庫函數、malloc不能重載(字節(jié)大?。?/p>
new可以調用構造函數,delete可以調用析構函數,malloc/free不能
new返回的是指定對象的指針,而malloc返回的是void*,因此malloc的返回值一般都需要進行類型轉化
malloc分配的內存不夠的時候可以使用realloc擴容,new沒有這樣的操作
new內存分配失敗拋出bad_malloc,malloc內存分配失敗返回NULL值
-
volatile關鍵字
編譯器對訪問該變量的代碼就不再進行優(yōu)化,從而可以提供對特殊地址的穩(wěn)定訪問。訪問寄存器要比訪問內存要塊,因此CPU會優(yōu)先訪問該數據在寄存器中的存儲結果,但是內存中的數據可能已經發(fā)生了改變,而寄存器中還保留著原來的結果。為了避免這種情況的發(fā)生將該變量聲明為volatile,告訴CPU每次都從內存去讀取數據。
一個參數可以即是const又是volatile的嗎?可以,一個例子是只讀狀態(tài)寄存器,是volatile是因為它可能被意想不到的被改變,是const告訴程序不應該試圖去修改他
-
static關鍵字的作用
修飾全局變量、局部變量、全局函數、局部函數、類的成員變量、成員函數
static修飾的變量屬于類變量,可以通過類名.變量名直接引用,而不需要new出一個類來
static修飾全局函數有什么作用? 限制他的作用域只能在本文件之內。
extern關鍵字作用 聲明一個外部變量。
const關鍵字的作用
const修飾全局變量
const修飾局部變量
const修飾指針,const int *
const修飾指針指向的對象, int * const
const修飾引用做形參
const修飾成員變量,必須在構造函數列表中初始化
const修飾成員函數,說明該函數不應該修改非靜態(tài)成員,但是這并不是十分可靠的,指針所指的非成員對象值可能會被改變
- define/const/inline的區(qū)別 本質:define只是字符串替換,const參與編譯運行,具體的:
define不會做類型檢查,const擁有類型,會執(zhí)行相應的類型檢查 . define僅僅是宏替換,不占用內存,而const會占用內存
const內存效率更高,編譯器通常將const變量保存在符號表中,而不會分配存儲空間,這使得它成為一個編譯期間的常量,沒有存儲和讀取的操作
本質:define只是字符串替換,inline由編譯器控制,具體的:
1. 內聯函數在編譯時展開,而宏是由預處理器對宏進行展開
2. 內聯函數會檢查參數類型,宏定義不檢查函數參數 ,所以內聯函數更安全。
3. 宏不是函數,而inline函數是函數
4. 宏在定義時要小心處理宏參數,(一般情況是把參數用括弧括起來)
- 有哪些內存泄漏?如何判斷內存泄漏?如何定位內存泄漏?
**全局變量和局部變量的區(qū)別**
**C++智能指針**
**C++動態(tài)內存**
**C++11新特性**
**純虛函數的作用和實現方式**
**STL源碼、vector、list、map、set**
**字節(jié)對齊的原則**
從0位置開始存儲;
變量存儲的起始位置是該變量大小的整數倍;
結構體總的大小是其最大元素的整數倍,不足的后面要補齊;
結構體中包含結構體,從結構體中最大元素的整數倍開始存;
如果加入pragma pack(n) ,取n和變量自身大小較小的一個。
空結構體的sizeof()返回值 答案是1
靜態(tài)連接與動態(tài)鏈接的區(qū)別
靜態(tài)鏈接 所謂靜態(tài)鏈接就是在編譯鏈接時直接將需要的執(zhí)行代碼拷貝到調用處,優(yōu)點就是在程序發(fā)布的時候就不需要依賴庫,也就是不再需要帶著庫一塊發(fā)布,程序可以獨立執(zhí)行,但是體積可能會相對大一些。
動態(tài)鏈接 所謂動態(tài)鏈接就是在編譯的時候不直接拷貝可執(zhí)行代碼,而是通過記錄一系列符號和參數,在程序運行或加載時將這些信息傳遞給操作系統(tǒng),操作系統(tǒng)負責將需要的動態(tài)庫加載到內存中,然后程序在運行到指定的代碼時,去共享執(zhí)行內存中已經加載的動態(tài)庫可執(zhí)行代碼,最終達到運行時連接的目的。優(yōu)點是多個程序可以共享同一段代碼,而不需要在磁盤上存儲多個拷貝,缺點是由于是運行時加載,可能會影響程序的前期執(zhí)行性能。
多態(tài)是什么?舉一個多態(tài)的例子
多態(tài)性與虛函數表
靜態(tài)多態(tài)和動態(tài)多態(tài) 多態(tài)分為靜態(tài)多態(tài)和動態(tài)多態(tài)。靜態(tài)多態(tài)是通過重載和模板技術實現,在編譯的時候確定。動態(tài)多態(tài)通過虛函數和繼承關系來實現,執(zhí)行動態(tài)綁定,在運行的時候確定。
重寫、重載與隱藏的區(qū)別 重載的函數都是在類內的。只有參數類型或者參數個數不同,重載不關心返回值的類型。 覆蓋(重寫)派生類中重新定義的函數,其函數名,返回值類型,參數列表都跟基類函數相同,并且基類函數前加了virtual關鍵字。 隱藏是指派生類的函數屏蔽了與其同名的基類函數,注意只要同名函數,不管參數列表是否相同,基類函數都會被隱藏。有兩種情況:(1)參數列表不同,不管有無virtual關鍵字,都是隱藏;(2)參數列表相同,但是無virtual關鍵字,也是隱藏。
構造函數為什么不能定義為虛函數,析構函數為什么可以
虛函數的執(zhí)行依賴于虛函數表。而虛函數表需要在構造函數中進行初始化工作,即初始化vptr,讓他指向正確的虛函數表。而在構造對象期間,虛函數表還沒有被初始化,將無法進行。
在類的繼承中,如果有基類指針指向派生類,那么用基類指針delete時,如果不定義成虛函數,派生類中派生的那部分無法析構。
構造函數不要調用虛函數。在基類構造的時候,虛函數是非虛,不會走到派生類中,既是采用的靜態(tài)綁定。顯然的是:當我們構造一個子類的對象時,先調用基類的構造函數,構造子類中基類部分,子類還沒有構造,還沒有初始化,如果在基類的構造中調用虛函數,如果可以的話就是調用一個還沒有被初始化的對象,那是很危險的,所以C++中是不可以在構造父類對象部分的時候調用子類的虛函數實現。但是不是說你不可以那么寫程序,你這么寫,編譯器也不會報錯。只是你如果這么寫的話編譯器不會給你調用子類的實現,而是還是調用基類的實現。
必須在構造函數初始化式里進行初始化的數據成員有哪些 1) 常量成員,因為常量只能初始化不能賦值,所以必須放在初始化列表里面 2) 引用類型,引用必須在定義的時候初始化,并且不能重新賦值,所以也要寫在初始化列表里面 3) 沒有默認構造函數的類類型,因為使用初始化列表可以不必調用默認構造函數來初始化,而是直接調用拷貝構造函數初始化
C++四種類型轉換 static_cast, dynamic_cast, const_cast, reinterpret_cast
const_cast用于將const變量轉為非const
static_cast用的最多,對于各種隱式轉換,非const轉const,void*轉指針等, static_cast能用于多態(tài)想上轉化,如果向下轉能成功但是不安全,結果未知;
dynamic_cast用于動態(tài)類型轉換。只能用于含有虛函數的類,用于類層次間的向上和向下轉化。只能轉指針或引用。向下轉化時,如果是非法的對于指針返回NULL,對于引用拋異常。要深入了解內部轉換的原理。
reinterpret_cast幾乎什么都可以轉,比如將int轉指針,可能會出問題,盡量少用;
為什么不使用C的強制轉換?C的強制轉換表面上看起來功能強大什么都能轉,但是轉化不夠明確,不能進行錯誤檢查,容易出錯。
如何讓一個類不能實例化? 將類定義為抽象基類或者將構造函數聲明為private。
如何讓main函數之前執(zhí)行函數? 1)C++中在main函數之前定義一個全局對象,調用構造函數。 2) C語言中使用gcc的attribute關鍵字,聲明constructor和destructor。
C++如何創(chuàng)建一個類,使得他只能在堆或者棧上創(chuàng)建?
只能在堆上生成對象:將析構函數設置為私有。 原因:C++是靜態(tài)綁定語言,編譯器管理棧上對象的生命周期,編譯器在為類對象分配棧空間時,會先檢查類的析構函數的訪問性。若析構函數不可訪問,則不能在棧上創(chuàng)建對象。
只能在棧上生成對象:將new 和 delete 重載為私有。 原因:在堆上生成對象,使用new關鍵詞操作,其過程分為兩階段:第一階段,使用new在堆上尋找可用內存,分配給對象;第二階段,調用構造函數生成對象。將new操作設置為私有,那么第一階段就無法完成,就不能夠再堆上生成對象。
C++命名空間,命名空間的嵌套 可作為附加信息來區(qū)分不同庫中相同名稱的函數、類、變量等。使用了命名空間即定義了上下文。
-
explict關鍵字的作用
算法
鏈表
輸出鏈表中倒數第k個節(jié)點
找到鏈表環(huán)結點入口
單鏈表的倒置
-
排序算法
手寫快速排序(快速排序的基準)
歸并排序
堆排序
void shuffle(int cards[],int n)
{
<pre lang="" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; width: inherit; white-space: normal; display: block; break-inside: avoid; text-align: left; background: rgb(51, 51, 51); padding: 10px 10px 10px 30px; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial; position: relative !important;">if(cards==NULL)</pre>
return ;
srand(time(0));
for(int i=0;i<n-1;++i)
{
//保證每次第i位的值不會涉及到第i位以前
int index=i+rand()%(n-i);
int temp=cards[i];
cards[i]=cards[index];
cards[index]=temp;
}</pre>
}
哈希表
哈希處理沖突的解決方法
開放地址法
鏈表法
二叉樹
二叉樹的非遞歸前序遍歷,中序遍歷,后續(xù)遍歷,層序遍歷
二叉樹的高度
二叉樹的鏡像
二叉樹的前k大個節(jié)點(堆排序)
紅黑樹和平衡二叉樹
高級數據結構
紅黑樹
-
算法
找到數組中第一次出現1次的值
背包九講
最長公共子序列(動態(tài)規(guī)劃)
最長重復子序列(find和rfind的應用)
找零錢問題(動態(tài)規(guī)劃&貪心算法)
-
排列組合問題(遞歸&回溯)
海量數據處理問題
網絡技術(TCP/IP)
OSI七層網絡模型
TCP三次握手過程,為什么需要三次?
首先Client向Server發(fā)送請求報文段,同時同步自己的SYN(x),Client進入SYN_SENT狀態(tài)。
Server接收到Client的請求報文段,返回CLient自己的seq(y)及ack(x+1),Server進入SYN_REVD狀態(tài)。
-
CLinet收到Server的SYN+ACK包,向服務器發(fā)送一個序列號seq(x+1),確認號為ack(y+1),此包發(fā)送完畢,Client和Server進入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。
需要三次的原因:防止已失效的報文段出現在本連接中。
TCP四次揮手的過程
客戶端發(fā)送斷開TCP連接請求的報文,其中報文中包含seq序列號,是由發(fā)送端隨機生成的,并且還將報文中的FIN字段置為1,表示需要斷開TCP連接。(FIN=1,seq=x,x由客戶端隨機生成)
服務端會回復客戶端發(fā)送的TCP斷開請求報文,其包含seq序列號,是由回復端隨機生成的,而且會產生ACK字段,ACK字段數值是在客戶端發(fā)過來的seq序列號基礎上加1進行回復,以便客戶端收到信息時,知曉自己的TCP斷開請求已經得到驗證。(FIN=1,ACK=x+1,seq=y,y由服務端隨機生成)
服務端在回復完客戶端的TCP斷開請求后,不會馬上進行TCP連接的斷開,服務端會先確保斷開前,所有傳輸到A的數據是否已經傳輸完畢,一旦確認傳輸數據完畢,就會將回復報文的FIN字段置1,并且產生隨機seq序列號。(FIN=1,ACK=x+1,seq=z,z由服務端隨機生成)
客戶端收到服務端的TCP斷開請求后,會回復服務端的斷開請求,包含隨機生成的seq字段和ACK字段,ACK字段會在服務端的TCP斷開請求的seq基礎上加1,從而完成服務端請求的驗證回復。(FIN=1,ACK=z+1,seq=h,h為客戶端隨機生成) 至此TCP斷開的4次揮手過程完畢
為什么TCP建立連接需要三次握手,而斷開連接需要四次揮手? 因為當Server端收到Client端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能并不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,”你發(fā)的FIN報文我收到了”。只有等到我Server端所有的報文都發(fā)送完了,我才能發(fā)送FIN報文,因此不能一起發(fā)送。故需要四步握手。
TIME_WAIT的意義,為什么等于2MSL? MSL是最長報文段壽命,設置的目的是:
保證A發(fā)送的最后一個ACK能夠到達B
防止已失效的報文段出現在本連接中
<mark style="box-sizing: border-box; background: rgb(211, 212, 14); color: rgb(0, 0, 0);">TCP頭部校驗的原理,安全嗎,可以仿造嗎</mark> TCP校驗和是一個端到端的校驗和,由發(fā)送端計算,然后由接收端驗證。其目的是為了發(fā)現TCP首部和數據在發(fā)送端到接收端之間發(fā)生的任何改動。如果接收方檢測到校驗和有差錯,則TCP段會被直接丟棄。 可以仿造。
TCP、UDP的區(qū)別?服務器和客戶端建立的過程? TCP---傳輸控制協議,提供的是面向連接、可靠的字節(jié)流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數據。TCP提供超時重發(fā),丟棄重復數據,檢驗數據,流量控制等功能,保證數據能順序地從一端傳到另一端。 UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發(fā)送出去,但是并不能保證它們能到達目的地。由于UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發(fā)等機制,不保證數據按順序傳遞,故而傳輸速度很快。
UDP編程的服務器端一般步驟
創(chuàng)建一個socket,用函數socket();
設置socket屬性,用函數setsockopt();* 可選
綁定IP地址、端口等信息到socket上,用函數bind();
循環(huán)接收數據,用函數recvfrom();
關閉網絡連接;
UDP編程的客戶端一般步驟是
創(chuàng)建一個socket,用函數socket();
設置socket屬性,用函數setsockopt();* 可選
綁定IP地址、端口等信息到socket上,用函數bind();* 可選
設置對方的IP地址和端口等屬性;
發(fā)送數據,用函數sendto();
關閉網絡連接;
TCP編程的服務器端一般步驟是
創(chuàng)建一個socket,用函數socket();
設置socket屬性,用函數setsockopt(); * 可選
綁定IP地址、端口等信息到socket上,用函數bind();
開啟監(jiān)聽,用函數listen();
接收客戶端上來的連接,用函數accept();
收發(fā)數據,用函數send()和recv(),或者read()和write();
關閉網絡連接;
關閉監(jiān)聽.
TCP編程的客戶端一般步驟是
創(chuàng)建一個socket,用函數socket();
設置socket屬性,用函數setsockopt();* 可選
綁定IP地址、端口等信息到socket上,用函數bind();* 可選
設置要連接的對方的IP地址和端口等屬性;
連接服務器,用函數connect();
收發(fā)數據,用函數send()和recv(),或者read()和write();
關閉網絡連接.
socket中的close是一次就關閉的嗎?半關閉狀態(tài)是怎么產生的? 不是,當A發(fā)送給B控制FIN的時候,A到B這個方向的連接就關閉了,這個時候處于半關閉的狀態(tài),但是B到A這個方向的連接并沒有關閉,因為B要等到將數據全部發(fā)送完畢之后才會發(fā)送FIN給A。
TCP擁塞控制 重點掌握慢開始、擁塞避免、快重傳、快恢復。
-
TCP流量控制,采用滑動窗口會用什么問題? 流量控制是為了讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收。 Nagle算法:①當發(fā)送方首都哦啊哦對第一個數據字符的確認后,再把發(fā)送緩存中的所有數據組裝成一個報文段發(fā)送出去,同時繼續(xù)對隨后到到達的數據進行緩存。②當到達的數據已達到發(fā)送窗口大小的一半或已達到報文段的長度的時候就立即發(fā)送一個報文段。 糊涂窗口綜合征:就是由于發(fā)送端和接收端上的處理不一致,導致網絡上產生很多的小包,結果報文段包含了一個大大的頭部,攜帶數據很少。數據傳輸效率低。處理方法是等待窗口大小滿足一定的條件之后(能夠接收一個最大報文,或者緩沖區(qū)的一半),再來發(fā)送窗口通告,這樣就不會產生小報文。
滑動窗口機制為端到端設備間的數據傳輸提供了可靠的流量控制機制。然而,它只能在源端設備和目的端設備起作用,當網絡中間設備(例如路由器等)發(fā)生擁塞時,滑動窗口機制將不起作用。
擁塞控制和流量控制的區(qū)別?
擁塞控制就是防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或鏈路不會過載
流量控制往往是點對點通信量的控制,是一個端到端的問題,流量控制要做的是抑制發(fā)送端發(fā)送數據的速率,以便接收端來得及接收。
TCP怎么保證可靠性?
應用數據被分割成TCP認為最適合發(fā)送的數據塊
超時重傳:當TCP發(fā)出一個段后,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發(fā)這個報文段
TCP給發(fā)送的每一個包進行編號,接收方對數據包進行排序,把有序數據傳送給應用層
校驗和:TCP將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段
TCP的接收端會丟棄重復的數據
流量控制:讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收
擁塞控制:當網絡擁塞時,減少數據的發(fā)送
TCP滑動窗口協議
“窗口”對應的是一段可以被發(fā)送者發(fā)送的字節(jié)序列,其連續(xù)的范圍稱之為“窗口”
“滑動”則是指這段“允許發(fā)送的范圍”是可以隨著發(fā)送的過程而變化的,方式就是按順序“滑動”
http協議與TCP協議的聯系 TPC協議是傳輸層協議,主要解決數據如何在網絡中傳輸,而HTTP是應用層協議,主要解決如何包裝數據。 Http協議是建立在TCP協議基礎之上的,當瀏覽器需要從服務器獲取網頁數據的時候,會發(fā)出一次Http請求。Http會通過TCP建立起一個到服務器的連接通道,當本次請求需要的數據完畢后,Http會立即將TCP連接斷開,這個過程是很短的。所以Http連接是一種短連接,是一種無狀態(tài)的連接。
http1.1提供永久性連接,即1.0使用非持久連接
http1.1增加host頭
http1.1還提供了身份認證,狀態(tài)管理和cache緩存機制等相關的請求頭和響應頭。
http請求方法有哪些?get和post的區(qū)別
OPTIONS 返回服務器針對特定資源所支持的HTTP請求方法,也可以利用向web服務器發(fā)送‘*’的請求來測試服務器的功能性
HEAD 向服務器索與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以再不必傳輸整個響應內容的情況下,就可以獲取包含在響應小消息頭中的元信息。
GET 向特定的資源發(fā)出請求。注意:GET方法不應當被用于產生“副作用”的操作中,例如在Web Application中,其中一個原因是GET可能會被網絡蜘蛛等隨意訪問。Loadrunner中對應get請求函數:web_link和web_url
POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 Loadrunner中對應POST請求函數:web_submit_data,web_submit_form
PUT 向指定資源位置上傳其最新內容
DELETE 請求服務器刪除Request-URL所標識的資源
TRACE 回顯服務器收到的請求,主要用于測試或診斷
CONNECT HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。
(1)根據HTTP規(guī)范,GET用于信息獲取,而且應該是安全的和冪等的 (2)根據HTTP規(guī)范,POST表示可能修改變服務器上的資源的請求
http和https的區(qū)別?由http升級到https需要哪些操作? HTTP 指的是超文本傳輸協議,https 指的是超文本傳輸安全協議。HTTPS 就是將 HTTP 中的傳輸內容進行了加密,然后通過可靠的連接,傳輸到對方的機器上。加密的協議是 TLS,其前身是 SSL。
https具體怎么實現?,怎么確保安全性?
http中瀏覽器一個URL的流程,這個過程中瀏覽器做些什么,URL包括哪三個部分?
瀏覽器向DNS服務器查找輸入URL對應的IP地址。
DNS服務器返回網站的IP地址。
瀏覽器根據IP地址與目標web服務器在80端口上建立TCP連接
瀏覽器獲取請求頁面的html代碼。
瀏覽器在顯示窗口內渲染HTML。
窗口關閉時,瀏覽器終止與服務器的連接。 URL包括:①協議(或稱為服務方式);②存有該資源的主機IP地址(有時也包括端口號);③主機資源的具體地址,如目錄和文件名等。
http四個會話過程?
建立tcp連接
發(fā)出請求文檔
發(fā)出響應文檔
釋放tcp連接
網頁解析的過程
<mark style="box-sizing: border-box; background: rgb(211, 212, 14); color: rgb(0, 0, 0);">一個機器能使用的端口號上限是多少?為什么?可以改變嗎?如果想要用的端口超過這個限制怎么辦?</mark> 端口號最多是65535個,端口號2個字節(jié),16位,所以最大表示65535.不能改變
對稱加密和非對稱加密 對稱加密(也叫私鑰加密)指加密和解密使用相同密鑰的加密算法。有時又叫傳統(tǒng)密碼算法,就是加密密鑰能夠從解密密鑰中推算出來,同時解密密鑰也可以從加密密鑰中推算出來。 非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數據進行加密,那么只有用對應的公開密鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。
數字證書的了解(高頻)
客戶端為什么信任第三方證書?
RSA加密算法,MD5原理
單條記錄高并發(fā)訪問的優(yōu)化
介紹一下ping的過程,分別用到了那些協議? ping用來測試兩臺主機之間的連通性。ICMP協議
正常情況:如果Socket Client 發(fā)送的數據包,在Socket Server端也是一個一個完整接收的,那個就不會出現粘包和分包情況,數據正常讀取。
粘包情況:Socket Client發(fā)送的數據包,在客戶端發(fā)送和服務器接收的情況下都有可能發(fā)送,因為客戶端發(fā)送的數據都是發(fā)送的一個緩沖buffer,然后由緩沖buffer最后刷到數據鏈路層的,那么就有可能把數據包2的一部分數據結合數據包1的全部被一起發(fā)送出去了,這樣在服務器端就有可能出現這樣的情況,導致讀取的數據包包含了數據包2的一部分數據,這就產生粘包,當然也有可能把數據包1和數據包2全部讀取出來。
分包情況:意思就是把數據包2或者數據包1都有可能被分開一部分發(fā)送出去,接著發(fā)另外的部分,在服務器端有可能一次讀取操作只讀到一個完整數據包的一部分。
在數據包發(fā)送的情況下,有可能后面的數據包分開成2個或者多個,但是最前面的部分包,黏住在前面的一個完整或者部分包的后面,也就是粘包和分包同時產生了。
<mark style="box-sizing: border-box; background: rgb(211, 212, 14); color: rgb(0, 0, 0);">一個IP配置多個域名,靠什么識別?</mark> 主機頭
路由器的工作原理和作用,交換機的工作原理和作用
對路由協議的了解與介紹。內部網關協議IGP包括RIP,OSPF和外網網關協議EGP和BGP
路由協議使用的算法
服務器攻擊(DDos攻擊)
TCP為什么最后要等2MSL
操作系統(tǒng)
什么是臨界區(qū)?進程進入臨界區(qū)的調度原則是? 臨界區(qū)是一段對共享資源的保護代碼,該保護代碼在任意時刻只允許一個線程對共享資源訪問。 進程進入臨界區(qū)的調度原則是: ①如果有若干進程要求進入空閑的臨界區(qū),一次僅允許一個進程進入。②任何時候,處于臨界區(qū)內的進程不可多于一個。如已有進程進入自己的臨界區(qū),則其它所有試圖進入臨界區(qū)的進程必須等待。③進入臨界區(qū)的進程要在有限時間內退出,以便其它進程能及時進入自己的臨界區(qū)。④如果進程不能進入自己的臨界區(qū),則應讓出CPU,避免進程出現“忙等”現象。
-
互斥對象、臨界區(qū)和事件的區(qū)別? 互斥是一種用途非常廣泛的內核對象。能夠保證多個線程對同一共享資源的互斥訪問。 事件對象也是屬于內核對象,它的主要成員包括:1.使用計數 2.指明該事件是一個自動重置事件還是一個人工重置事件的布爾值3.指明該事件處于已通知狀態(tài)還是未通知狀態(tài)的布爾值。
互斥對象、事件對象與臨界區(qū)的比較:
互斥對象、事件對象都是屬于內核對象,利用內核對象進行線程同步,速度較慢,但可以在多個進程中的多個線程間可以進行同步。
臨界區(qū)屬于在用戶模式下,同步速度較快,但是很容易進入死鎖狀態(tài),因為在等待進入臨界區(qū)時無法設定超時值。
-
進程和線程的區(qū)別?進程和程序的區(qū)別? 進程是資源(CPU、內存等)分配的基本單位,它是程序執(zhí)行時的一個實例。程序運行時系統(tǒng)就會創(chuàng)建一個進程,并為它分配資源,然后把該進程放入進程就緒隊列,進程調度器選中它的時候就會為它分配CPU時間,程序開始真正運行。 線程是程序執(zhí)行時的最小單位,它是進程的一個執(zhí)行流,是CPU調度和分派的基本單位,一個進程可以由很多個線程組成,線程間共享進程的所有資源,每個線程有自己的堆棧和局部變量。線程由CPU獨立調度執(zhí)行,在多CPU環(huán)境下就允許多個線程同時運行。同樣多線程也可以實現并發(fā)操作,每個請求分配一個線程來處理。
進程和程序的區(qū)別
進程是動態(tài)的,而程序是靜態(tài)的。
進程有一定的生命期,而程序是指令的集合,本身無“運動”的含義。沒有建立進程的程序不能作為1個獨立單位得到操作系統(tǒng)的認可。
1個程序可以對應多個進程,但1個進程只能對應1個程序。進程和程序的關系猶如演出和劇本的關系。
一個進程可以創(chuàng)建多少個線程?和什么有關? 一個進程可以創(chuàng)建的線程數由可用虛擬空間和線程的棧的大小共同決定
-
什么是死鎖?死鎖產生的原因?死鎖四個必要條件?死鎖的解除、死鎖控制? 死鎖是指多個進程因競爭資源而造成的一種僵局(互相等待),若無外力作用,這些進程都將無法向前推進。
死鎖產生的原因
系統(tǒng)資源的競爭 系統(tǒng)資源的競爭導致系統(tǒng)資源不足,以及資源分配不當,導致死鎖。
進程運行推進順序不合適 進程在運行過程中,請求和釋放資源的順序不當,會導致死鎖。
死鎖的四個條件
互斥條件:一個資源每次只能被一個進程使用,即在一段時間內某 資源僅為一個進程所占有。此時若有其他進程請求該資源,則請求進程只能等待。
請求與保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源 已被其他進程占有,此時請求進程被阻塞,但對自己已獲得的資源保持不放。
不可剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能 由獲得該資源的進程自己來釋放(只能是主動釋放)。
循環(huán)等待條件: 若干進程間形成首尾相接循環(huán)等待資源的關系 這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發(fā)生死鎖。
死鎖的避免與預防
死鎖避免的基本思想 系統(tǒng)對進程發(fā)出每一個系統(tǒng)能夠滿足的資源申請進行動態(tài)檢查,并根據檢查結果決定是否分配資源,如果分配后系統(tǒng)可能發(fā)生死鎖,則不予分配,否則予以分配。這是一種保證系統(tǒng)不進入死鎖狀態(tài)的動態(tài)策略。 理解了死鎖的原因,尤其是產生死鎖的四個必要條件,就可以最大可能地避免、預防和解除死鎖。所以,在系統(tǒng)設計、進程調度等方面注意如何讓這四個必要條件不成立,如何確定資源的合理分配算法,避免進程永久占據系統(tǒng)資源。此外,也要防止進程在處于等待狀態(tài)的情況下占用資源。因此,對資源的分配要給予合理的規(guī)劃。
死鎖避免和死鎖預防的區(qū)別 死鎖預防是設法至少破壞產生死鎖的四個必要條件之一,嚴格的防止死鎖的出現,而死鎖避免則不那么嚴格的限制產生死鎖的必要條件的存在,因為即使死鎖的必要條件存在,也不一定發(fā)生死鎖。死鎖避免是在系統(tǒng)運行過程中注意避免死鎖的最終發(fā)生。
死鎖的解除
一旦檢測出死鎖,就應立即釆取相應的措施,以解除死鎖。死鎖解除的主要兩種方法:
搶占資源。從一個或多個進程中搶占足夠數量的資源,分配給死鎖進程,以解除死鎖狀態(tài)。
終止(或撤銷)進程。終止(或撤銷)系統(tǒng)中的一個或多個死鎖進程,直至打破循環(huán)環(huán)路,使系統(tǒng)從死鎖狀態(tài)解脫出來。
Windows內存管理方式
分頁存儲 用戶程序的邏輯地址空間被劃分成若干固定大小的區(qū)域,稱為“頁”或者“頁面”,相應地,內存物理空間也分成相對應的若干個物理塊,頁和塊的大小相等。提高了內存的利用率。
分段存儲 將用戶程序地址空間分成若干個大小不等的段,每段可以定義一組相對完整的邏輯信息。提高程序的邏輯性。
段頁式存儲 兩者結合。作業(yè)的地址空間首先被分成若干個邏輯分段,每段都有自己的段號,然后再將每段分成若干個大小相等的頁。
一個程序從開始運行到結束的完整過程(四個過程) 預處理,編譯,匯編,鏈接。
源代碼.c 文件先經過預處理器,生成一個中間文件.i 文件,這個階段有兩個作用,一是把include的頭文件內容進行替換,二是處理宏定義。
.i 文件經過編譯生成匯編.s 文件
.s 的匯編文件經過匯編器生成.obj 的目標文件
.obj 經過鏈接器和 lib(靜態(tài)鏈接庫) dll(動態(tài)鏈接庫)文件生成 exe 可執(zhí)行程序
頭文件在編譯過程中的作用?(網易游戲) 頭文件并不參加鏈接和編譯。編譯器第一步要做的就是簡單的把頭文件在包含它的源文件中展開。不知你是否能理解這句話。也就是頭文件里面有什么內容,通通把它移到包含這個頭文件的源文件里。(我覺得這是個很重要的概念,可以幫助我們簡化理解編譯鏈接的過程,包括理解頭文件中定義靜態(tài)變量或靜態(tài)函數是怎么回事)。編譯器經過這一步轉換后剩下什么呢?就是一堆cpp文件了。而頭文件已經不再是編譯器需要關心的東西了。編譯器接下來就要處理這一堆cpp文件了。 所以第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。如#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。 第二個階段編譯、優(yōu)化階段。
為何不能在頭文件中定義? 防止多重定義。
進程間通信的方法?
管道pipe:管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。
命名管道FIFO:有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
消息隊列MessageQueue:消息隊列是由消息的鏈表,存放在內核中并由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點。
共享存儲SharedMemory:共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創(chuàng)建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
信號量Semaphore:信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
套接字Socket:套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用于不同及其間的進程通信。
信號 ( sinal ) : 信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經發(fā)生。
線程同步方法?
-
鎖機制
互斥鎖:提供了以排它方式阻止數據結構被并發(fā)修改的方法。
讀寫鎖:允許多個線程同時讀共享數據,而對寫操作互斥。
條件變量:可以以原子的方式阻塞進程,直到某個特定條件為真為止。對條件測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一起使用。
信號量機制:包括無名線程信號量與有名線程信號量
信號機制:類似于進程間的信號處理。 線程間通信的主要目的是用于線程同步,所以線程沒有象進程通信中用于數據交換的通信機制。
線程創(chuàng)建的方式有幾種?
先來先去服務
短作業(yè)(進程)優(yōu)先調度算法SJ(P)F
輪轉法
多級反饋隊列算法
最優(yōu)頁面置換算法
最近未使用頁面置換算法(NRU)
先進先出頁面置換算法(FIFO)及其改進
時鐘頁面置換算法(clock)
最近最少使用頁面置換算法(LRU)
工作集算法
布隆過濾器的優(yōu)點與缺點
布隆過濾器處理大規(guī)模問題時的持久化,包括內存大小首先、磁盤換入換出問題
文件讀寫使用的系統(tǒng)調用
線程池的了解、優(yōu)點、調度處理方式和保護任務隊列的方式 于是為了避免一個程序需要大量創(chuàng)建線程時的不必要浪費,也就是最好的去避免線程創(chuàng)建與線程銷毀的時間浪費,此時線程池就出現了。線程池的實現就是在初始的時候創(chuàng)建一些線程(業(yè)界通常認為創(chuàng)建CPU核心數的兩倍為最佳,也有說是兩倍+1),創(chuàng)建的線程為掛起狀態(tài)(就緒),當我們有任務要處理的時候,我們就激活一個就緒的線程去完成任務,完成任務后,線程又變?yōu)榫途w態(tài)進行繼續(xù)等待任務的到來。這樣過程使得每個線程一次創(chuàng)建,多次使用,如果你的程序并沒有多次任務處理,使得線程池中的線程長時間處于就緒態(tài),此時就建議你直接使用一個線程就好,不必使用線程池。
線程池怎么創(chuàng)建?
怎么回收線程
多線程同步(項目中可能會問)
mencache
異常和中斷的區(qū)別
如何保證線程安全?
Linux
阻塞IO
非阻塞IO
IO復用
信號驅動IO
異步IO
Linux進程管理
Linux內核的進程調度
fork返回值是什么?
什么是虛擬內存?
EXT4:使用廣泛
XFS:XFS 文件系統(tǒng)是擴展文件系統(tǒng)的一個擴展,XFS 文件系統(tǒng)有一些缺陷,例如它不能壓縮,刪除大量文件時性能低下。
btrfs:有很多好用的功能,例如寫復制、擴展校驗、快照、清洗、自修復數據、冗余刪除以及其它保證數據完整性的功能。
Linux基本命令?
| 命令 | 作用 |
|---|---|
| pwd | 顯示當前目錄 |
| rm | 刪除 |
| touch | 生成文件 |
| cat | 讀取指定文件的內容并打印到終端輸出 |
| mkdir | 新建目錄make directory |
| file | 查看文件類型 |
| whereis,which,find 和 locate | 查找 |
| chown | 改變文件所有者 |
| df | 查看磁盤容量 |
| wc | 計數工具 |
| tr | 刪除一段文本信息中的某些文字?;蛘邔⑵溥M行轉換 |
| join | 連接兩個文件 |
| paste | 它是在不對比數據的情況下,簡單地將多個文件合并一起,以Tab隔開 |
grep命令用于打印輸出文本中匹配的模式串,它使用正則表達式作為模式匹配的條件。
sed用于過濾和轉換文本的流編輯器。
AWK是一種用于處理文本的編程語言工具。
Linux是如何避免內存碎片的
伙伴算法,用于管理物理內存,避免內存碎片;
高速緩存Slab層用于管理內核分配內存,避免碎片。
文件權限的查看與修改?
文件權限查看ls -l,查看文件所有者,所屬組,其他的文件權限,rwx為777
修改使用chmod命令
Linux如何打開一個文件?如何處理一個正在動態(tài)增長的文件?
IO復用的三種方法,poll、epoll和select的特點和區(qū)別 select,poll,epoll都是IO多路復用的機制。I/O多路復用就通過一種機制,可以監(jiān)視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進行相應的讀寫操作。但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程是阻塞的,而異步I/O則無需自己負責進行讀寫,異步I/O的實現會負責把數據從內核拷貝到用戶空間。
-
select:是最初解決IO阻塞問題的方法。用結構體fd_set來告訴內核監(jiān)聽多個文件描述符,該結構體被稱為描述符集。由數組來維持哪些描述符被置位了。對結構體的操作封裝在三個宏定義中。通過輪尋來查找是否有描述符要被處理,如果沒有返回。
存在的問題:
內置數組的形式使得select的最大文件數受限與FD_SIZE;
每次調用select前都要重新初始化描述符集,將fd從用戶態(tài)拷貝到內核態(tài),每次調用select后,都需要將fd從內核態(tài)拷貝到用戶態(tài);
輪尋排查當文件描述符個數很多時,效率很低;
poll:通過一個可變長度的數組解決了select文件描述符受限的問題。數組中元素是結構體,該結構體保存描述符的信息,每增加一個文件描述符就向數組中加入一個結構體,結構體只需要拷貝一次到內核態(tài)。poll解決了select重復初始化的問題。輪尋排查的問題未解決。
epoll:輪尋排查所有文件描述符的效率不高,使服務器并發(fā)能力受限。因此,epoll采用只返回狀態(tài)發(fā)生變化的文件描述符,便解決了輪尋的瓶頸。
為什么使用IO多路復用,最主要的原因是什么?
epoll有兩種觸發(fā)模式?這兩種觸發(fā)模式有什么區(qū)別?編程的時候有什么區(qū)別?
上一題中編程的時候有什么區(qū)別,是在邊緣觸發(fā)的時候要把套接字中的數據讀干凈,那么當有多個套接字時,在讀的套接字一直不停的有數據到達,如何保證其他套接字不被餓死(面試網易游戲的時候問的一個問題,答不上來,印象賊深刻)。
GDB調試
Linux進程和線程如何創(chuàng)建、退出?進程退出的時候,自己沒有釋放的資源(如內存沒有free)會怎樣?
數據庫
存儲過程 我們常用的關系型數據庫是MySQL,操作數據庫的語言一般為SQL語句,SQL在執(zhí)行的時候需要要先編譯,然后執(zhí)行,而存儲過程(Stored Procedure)是一組為了完成某種特定功能的SQL語句集,經編譯后存儲在數據庫中,用戶通過指定存儲過程的名字并給定參數(如果該存儲過程帶有參數)來調用執(zhí)行它。 一個存儲過程是一個可編程的函數,它在數據庫中創(chuàng)建并保存。它可以有SQL語句和一些特殊的控制結構組成。當希望在不同的應用程序或平臺上執(zhí)行相同的函數,或者封裝特定功能時,存儲過程是非常有用的。數據庫中的存儲過程可以看做是對面向對象方法的模擬,它允許控制數據的訪問方式。 <mark style="box-sizing: border-box; background: rgb(211, 212, 14); color: rgb(0, 0, 0);">存儲過程的優(yōu)點:</mark>
存儲過程增強了SQL語言的功能和靈活性:存儲過程可以用流控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的運算。
存儲過程允許標準組件式編程:存儲過程被創(chuàng)建后,可以在程序中被多次調用,而不必重新編寫該存儲過程的SQL語句。而且可以隨時對存儲過程進行修改,對應用程序源代碼毫無影響。
存儲過程能實現較快的執(zhí)行速度:如果某一操作包含大量的Transaction-SQL代碼或分別被多次執(zhí)行,那么存儲過程要比批處理的執(zhí)行速度快很多。因為存儲過程是預編譯的。在首次運行一個存儲過程時,優(yōu)化器對其進行分析優(yōu)化,并且給出最終被存儲在系統(tǒng)表中的執(zhí)行計劃。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優(yōu)化,速度相對要慢一些。
存儲過程能減少網絡流量:針對同一個數據庫對象的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織成存儲過程,那么當在客戶計算機上調用該存儲過程時,網絡中傳送的只是該調用語句,從而大大增加了網絡流量并降低了網絡負載。
存儲過程可被作為一種安全機制來充分利用:系統(tǒng)管理員通過執(zhí)行某一存儲過程的權限進行限制,能夠實現對相應的數據的訪問權限的限制,避免了非授權用戶對數據的訪問,保證了數據的安全。
索引 索引(Index)是幫助MySQL高效獲取數據的數據結構;在數據之外,數據庫系統(tǒng)還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,可以在這些數據結構上實現高級查找算法,提高查詢速度,這種數據結構,就是索引。 B-Tree 索引:最常見的索引類型,大部分引擎都支持B樹索引。 HASH 索引:只有Memory引擎支持,使用場景簡單。 R-Tree 索引(空間索引):空間索引是MyISAM的一種特殊索引類型,主要用于地理空間數據類型。 Full-text (全文索引):全文索引也是MyISAM的一種特殊索引類型,主要用于全文索引,InnoDB從MySQL5.6版本提供對全文索引的支持。
事物是什么? 事務(Transaction)是并發(fā)控制的基本單位。所謂的事務,它是一個操作序列,由一條或者多條sql語句組成,這些操作要么都執(zhí)行,要么都不執(zhí)行,它是一個不可分割的工作單位。
acid特性?
原子性(Atomicity):指整個數據庫事務是不可分割的工作單位。只有事務中所有的數據庫操作都執(zhí)行成功,整個事務的執(zhí)行才算成功。事務中任何一個sql語句執(zhí)行失敗,那么已經執(zhí)行成功的sql語句也必須撤銷,數據庫狀態(tài)應該退回到執(zhí)行事務前的狀態(tài)。
一致性(Consistency):事務應確保數據庫的狀態(tài)從一個一致狀態(tài)轉變?yōu)榱硪粋€一致狀態(tài)。一致狀態(tài)的含義是數據庫中的數據應滿足完整性約束,也就是說在事務開始之前和事務結束以后,數據庫的完整性約束沒有被破壞
隔離性(Isolation):隔離性也叫做并發(fā)控制、可串行化或者鎖。事務的隔離性要求每個讀寫事務的對象與其它事務的操作對象能相互分離,即該事務提交前對其它事務都不可見,這通常使用鎖來實現多個事務并發(fā)執(zhí)行時,一個事務的執(zhí)行不應影響其他事務的執(zhí)行。
持久性(Durability):表示事務一旦提交了,其結果就是永久性的,也就是數據就已經寫入到數據庫了,如果發(fā)生了宕機等事故,數據庫也能將數據恢復。
數據庫中的“主屬性”、“碼”、“主碼”的區(qū)別是什么?
在數據庫的表(關系)中能夠用于唯一區(qū)分開每個記錄(元組)的屬性或屬性的集合,我們稱之為碼(候選碼)。
當我們指定其中一個用來區(qū)分開每個記錄(元組)的碼為主碼。
主屬性是指包含在候選碼中的屬性。 換句話說:主碼和碼的關系就像班長和班長候選人之間的關系。 每個班長候選人,我們可稱之為主屬性,只不過在數據庫中,候選碼可能是多個屬性共同組成的。
100層樓,2個雞蛋,雞蛋從某一個臨界樓層丟下會摔碎,請設計方案,能用最小的次數找到臨界樓層
用3,4,5,6,7,8組成不重復的4位奇數,按照從小到大的順序排序,第62個數字是? 首先是奇數的話,末位只能是3,5,7中的一種,則有種方法。前面3個數是排列方法,那么總的方法數為種方法,組成的奇數按照從小到大排序。當第一位是3的時候,末位一定是5或者7,那么這樣的數一共有種方法,當第一位是4的時候,末位一定是3或者5或者7,這樣的數一共有種方法,那么這里一共就有種方法,當第一位是5的時候,末位一定是3或者7,取較小的數,第二位是3,最后一位是7,那么第61個數是5347,第62個數為5367.
24點游戲
25匹馬,5個跑道,如何通過最少的比賽次數確定前3名?
一家人過橋問題
瀏覽器輸入URL后的流程
.什么是IO復用,什么是非阻塞IO
-
作者:東東兒 鏈接:https://www.nowcoder.com/discuss/383932?type=all&order=time&pos=&page=1&channel=-1&source_id=search_all_nctrack 來源:??途W
.什么是IO復用,什么是非阻塞IO 2.TCP和UDP 3.流量控制解決了什么問題,怎么實現,接收窗口為0了怎么辦 4.哈希表的作用,怎么解決哈希沖突 5.布隆過濾器原理作用 6.redis的線程模型 7.項目結構 8.判定是否是鏡像二叉樹
作者:東東兒 鏈接:https://www.nowcoder.com/discuss/383932?type=all&order=time&pos=&page=1&channel=-1&source_id=search_all_nctrack 來源:??途W
聊項目,reactor模型,線程模型 2.epoll高效嗎?為什么?什么情況高效 3.LRU置換算法實現(說思路,不實現) 3.http?無狀態(tài)?無狀態(tài)怎么實現用戶登錄? 4.session,cookie,token 5.csrf攻擊,怎么防御 6.linux進程空間分布 7.簡單題(從一個棋盤的左上角走到右下角有多少種走法,只能向右和向下走)
5.url訪問網頁的過程,用了哪些協議? 6.算法,不用乘除運算實現除法(一開始用減法,面試官讓優(yōu)化,提醒了用位運算) 7.算法,判斷4張撲克牌是不是順子,大小王可以作為任意牌
算法:
旋轉數組找最小值,如果有重復值怎么辦?
給定東西視圖和南北視圖,求城市體積最大值