(一)2018.4 拼多多實習(xí)服務(wù)端
1、 一個C++源文件從文本到可執(zhí)行文件經(jīng)歷的過程
對于C/C++編寫的程序若厚,從源代碼到可執(zhí)行文件,一般經(jīng)過下面四個步驟:
1).預(yù)處理蜒什,產(chǎn)生.ii文件
2).編譯测秸,產(chǎn)生匯編文件(.s文件)
3).匯編,產(chǎn)生目標(biāo)文件(.o或.obj文件)
4).鏈接,產(chǎn)生可執(zhí)行文件(.out或.exe文件)
2灾常、#include 的順序以及尖叫括號和雙引號的區(qū)別
1. #include的順序的區(qū)別:
頭文件的引用順序?qū)τ诔绦虻木幾g還是有一定影響的霎冯。如果要在文件a.h中聲明一個在文件b.h中定義的變量,而不引用b.h钞瀑。那么要在a.c文件中引用b.h文件沈撞,并且要先引用b.h,后引用a.h,否則匯報變量類型未聲明錯誤雕什,也就是常見的某行少個“缠俺;”符號。
2. #include尖括號和雙引號的區(qū)別:
1)#include ?<> 贷岸,認為該頭文件是標(biāo)準(zhǔn)頭文件壹士。編譯器將會在預(yù)定義的位置集查找該頭文件,這些預(yù)定義的位置可以通過設(shè)置查找路徑環(huán)境變量或者通過命令行選項來修改偿警。使用的查找方式因編譯器的不同而差別迥異躏救。
2)#include "",認為它是非系統(tǒng)頭文件螟蒸,非系統(tǒng)頭文件的查找通常開始于源文件所在的路徑盒使。查找范圍大于<>。
3七嫌、進程和線程少办,為什么要有線程
1、和進程相比抄瑟,它是一種非常"節(jié)儉"的多任務(wù)操作方式凡泣。在linux系統(tǒng)下枉疼,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的數(shù)據(jù)表來維護它的代碼段鞋拟、堆棧段和數(shù)據(jù)段骂维,這是一種"昂貴"的多任務(wù)工作方式。(資源)
2贺纲、運行于一個進程中的多個線程航闺,它們之間使用相同的地址空間,而且線程間彼此切換所需時間也遠遠小于進程間切換所需要的時間猴誊。據(jù)統(tǒng)計潦刃,一個進程的開銷大約是一個線程開銷的30倍左右。(切換效率)
3懈叹、線程間方便的通信機制乖杠。對不同進程來說,它們具有獨立的數(shù)據(jù)空間澄成,要進行數(shù)據(jù)的傳遞只能通過進程間通信的方式進行胧洒,這種方式不僅費時,而且很不方便墨状。線程則不然卫漫,由于同一進城下的線程之間貢獻數(shù)據(jù)空間,所以一個線程的數(shù)據(jù)可以直接為其他線程所用肾砂,這不僅快捷列赎,而且方便。(通信)
除以上優(yōu)點外镐确,多線程程序作為一種多任務(wù)包吝、并發(fā)的工作方式,還有如下優(yōu)點:
1辫塌、使多CPU系統(tǒng)更加有效漏策。操作系統(tǒng)會保證當(dāng)線程數(shù)不大于CPU數(shù)目時,不同的線程運行于不同的CPU上臼氨。(CPU設(shè)計保證)
2、改善程序結(jié)構(gòu)芭届。一個既長又復(fù)雜的進程可以考慮分為多個線程储矩,成為幾個獨立或半獨立的運行部分,這樣的程序才會利于理解和修改褂乍。(代碼易維護)
4持隧、C++11有哪些新特性
1)關(guān)鍵字及新語法:auto、nullptr逃片、for
2)STL容器:std::array屡拨、std::forward_list、std::unordered_map、std::unordered_set
3)多線程:std::thread呀狼、std::atomic裂允、std::condition_variable
4)智能指針內(nèi)存管理:std::shared_ptr、std::weak_ptr
5)其他:std::function哥艇、std::bind和lamda表達式
5绝编、為什么可變參數(shù)模板至關(guān)重要,右值引用貌踏,完美轉(zhuǎn)發(fā)十饥,lambda
6、malloc的原理祖乳,brk系統(tǒng)調(diào)用干什么的逗堵,mmap呢
malloc的實現(xiàn)方案:
1)malloc 函數(shù)的實質(zhì)是它有一個將可用的內(nèi)存塊連接為一個長長的列表的所謂空閑鏈表。
2)調(diào)用 malloc()函數(shù)時眷昆,它沿著連接表尋找一個大到足以滿足用戶請求所需要的內(nèi)存塊蜒秤。 然后,將該內(nèi)存塊一分為二(一塊的大小與用戶申請的大小相等隙赁,另一塊的大小就是剩下來的字節(jié))垦藏。 接下來,將分配給用戶的那塊內(nèi)存存儲區(qū)域傳給用戶伞访,并將剩下的那塊(如果有的話)返回到連接表上掂骏。
3)調(diào)用 free 函數(shù)時,它將用戶釋放的內(nèi)存塊連接到空閑鏈表上厚掷。
4)到最后弟灼,空閑鏈會被切成很多的小內(nèi)存片段,如果這時用戶申請一個大的內(nèi)存片段冒黑, 那么空閑鏈表上可能沒有可以滿足用戶要求的片段了田绑。于是,malloc()函數(shù)請求延時抡爹,并開始在空閑鏈表上檢查各內(nèi)存片段掩驱,對它們進行內(nèi)存整理,將相鄰的小空閑塊合并成較大的內(nèi)存塊冬竟。
看我主頁簡介免費C++學(xué)習(xí)資源欧穴,視頻教程、職業(yè)規(guī)劃泵殴、面試詳解涮帘、學(xué)習(xí)路線、開發(fā)工具
每晚8點直播講解C++編程技術(shù)笑诅。
brk和mmap:
從操作系統(tǒng)角度來看调缨,進程分配內(nèi)存有兩種方式疮鲫,分別由兩個系統(tǒng)調(diào)用完成:brk和mmap(不考慮共享內(nèi)存)。
1弦叶、brk是將數(shù)據(jù)段(.data)的最高地址指針_edata往高地址推俊犯;
2、mmap是在進程的虛擬地址空間中(堆和棧中間湾蔓,稱為文件映射區(qū)域的地方)找一塊空閑的虛擬內(nèi)存瘫析。
這兩種方式分配的都是虛擬內(nèi)存,沒有分配物理內(nèi)存默责。在第一次訪問已分配的虛擬地址空間的時候贬循,發(fā)生缺頁中斷,操作系統(tǒng)負責(zé)分配物理內(nèi)存桃序,然后建立虛擬內(nèi)存和物理內(nèi)存之間的映射關(guān)系杖虾。
在標(biāo)準(zhǔn)C庫中,提供了malloc/free函數(shù)分配釋放內(nèi)存媒熊,這兩個函數(shù)底層是由brk奇适,mmap,munmap這些系統(tǒng)調(diào)用實現(xiàn)的芦鳍。
7嚷往、C++的內(nèi)存管理方式,STL的allocator柠衅,最新版本默認使用的分配器
C++的內(nèi)存管理方式:
在c++中內(nèi)存主要分為5個存儲區(qū):
棧(Stack):局部變量皮仁,函數(shù)參數(shù)等存儲在該區(qū),由編譯器自動分配和釋放.棧屬于計算機系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)菲宴,進棧出棧有相應(yīng)的計算機指令支持贷祈,而且分配專門的寄存器存儲棧的地址,效率分高喝峦,內(nèi)存空間是連續(xù)的势誊,但棧的內(nèi)存空間有限。
堆(Heap):需要程序員手動分配和釋放(new,delete)谣蠢,屬于動態(tài)分配方式粟耻。內(nèi)存空間幾乎沒有限制,內(nèi)存空間不連續(xù)眉踱,因此會產(chǎn)生內(nèi)存碎片勋颖。操作系統(tǒng)有一個記錄空間內(nèi)存的鏈表,當(dāng)收到內(nèi)存申請時遍歷鏈表勋锤,找到第一個空間大于申請空間的堆節(jié)點,將該節(jié)點分配給程序侥祭,并將該節(jié)點從鏈表中刪除叁执。一般茄厘,系統(tǒng)會在該內(nèi)存空間的首地址處記錄本次分配的內(nèi)存大小,用于delete釋放該內(nèi)存空間谈宛。
全局/靜態(tài)存儲區(qū):全局變量次哈,靜態(tài)變量分配到該區(qū),到程序結(jié)束時自動釋放吆录,包括DATA段(全局初始化區(qū))與BSS段(全局未初始化段)窑滞。其中,初始化的全局變量和靜態(tài)變量存放在DATA段恢筝,未初始化的全局變量和靜態(tài)變量存放在BSS段哀卫。BSS段特點:在程序執(zhí)行前BSS段自動清零,所以未初始化的全局變量和靜態(tài)變量在程序執(zhí)行前已經(jīng)成為0.
文字常量區(qū):存放常量撬槽,而且不允許修改此改。程序結(jié)束后由系統(tǒng)釋放。
程序代碼區(qū):存放程序的二進制代碼
SGI 版本STL的默認配置器std::alloc
參見:《STL源碼剖析》
1)考慮到小型區(qū)塊所可能造成的內(nèi)存碎片問題侄柔,SGI設(shè)計了雙層配置器共啃。第一級配置器直接使用malloc()和free();第二級則視情況采取不同的策略:當(dāng)配置區(qū)塊超過128bytes時暂题,視為“足夠大”移剪,便調(diào)用第一級配置器;當(dāng)配置區(qū)塊小于128bytes時薪者,視之為“過小”纵苛,為了降低額外負擔(dān),便采用memory pool(內(nèi)存池)整理方式啸胧,而不在求助于第一級配置器赶站。
2)內(nèi)存池的核心:內(nèi)存池和16個自由鏈表(各自管理8,16,...纺念,128bytes的小額區(qū)塊)贝椿。在分配一個小區(qū)塊時,首先在所屬自由鏈表中尋找陷谱,如果找到烙博,直接抽出分配;若所屬自由鏈表為空烟逊,則請求內(nèi)存池為所屬自由鏈表分配空間渣窜;默認情況下,為該自由鏈表分配20個區(qū)塊宪躯,若內(nèi)存池剩余容量不足乔宿,則分配可分配的最大容量;若內(nèi)存池連一個區(qū)塊都無法分配访雪,則調(diào)用chunk_alloc為內(nèi)存池分配一大塊區(qū)塊详瑞;若內(nèi)存不足掂林,則嘗試調(diào)用malloc分配,否則返回bad_alloc異常坝橡。
8泻帮、hash表的實現(xiàn),包括STL中的哈希桶長度常數(shù)计寇。
hash表的實現(xiàn)主要涉及兩個問題:散列函數(shù)和碰撞處理锣杂。
1)hash function (散列函數(shù))。最常見的散列函數(shù):f(x) = x % TableSize .
2)碰撞問題(不同元素的散列值相同)番宁。解決碰撞問題的方法有許多種元莫,包括線性探測、二次探測贝淤、開鏈等做法柒竞。SGL版本使用開鏈法,使用一個鏈表保持相同散列值的元素播聪。
雖然開鏈法并不要求表格大小必須為質(zhì)數(shù)朽基,但SGI STL仍然以質(zhì)數(shù)來設(shè)計表格大小,并且將28個質(zhì)數(shù)(逐漸呈現(xiàn)大約兩倍的關(guān)系)計算好离陶,以備隨時訪問稼虎,同時提供一個函數(shù),用來查詢在這28個質(zhì)數(shù)之中招刨,“最接近某數(shù)并大于某數(shù)”的質(zhì)數(shù)霎俩。
9、hash表如何rehash沉眶,怎么處理其中保存的資源
先想想為什么需要rehash:
因為打却,當(dāng)loadFactor(負載因子)<=1時,hash表查找的期望復(fù)雜度為O(1). 因此谎倔,每次往hash表中添加元素時柳击,我們必須保證是在loadFactor <1的情況下,才能夠添加片习。
模仿C++的vector擴容方式捌肴,Hash表中每次發(fā)現(xiàn)loadFactor==1時,就開辟一個原來桶數(shù)組的兩倍空間(稱為新桶數(shù)組)藕咏,然后把原來的桶數(shù)組中元素全部轉(zhuǎn)移過來到新的桶數(shù)組中状知。注意這里轉(zhuǎn)移是需要元素一個個重新哈希到新桶中的。
10孽查、Redis的rehash怎么做的饥悴,為什么要漸進rehash,漸進rehash怎么實現(xiàn)的
為了避免rehash對服務(wù)器造成影響,服務(wù)器不是一次將ht[0]里面的所有鍵值對全部rehash到ht[1]铺坞,而是分多次起宽、漸進式地將ht[0]里面的鍵值對慢慢地rehash到ht[1].
以下是哈希表漸進式 rehash 的詳細步驟:
為 ht[1] 分配空間, 讓字典同時持有 ht[0] 和 ht[1] 兩個哈希表济榨。
在字典中維持一個索引計數(shù)器變量 rehashidx , 并將它的值設(shè)置為 0 绿映, 表示 rehash 工作正式開始擒滑。
在 rehash 進行期間, 每次對字典執(zhí)行添加叉弦、刪除丐一、查找或者更新操作時, 程序除了執(zhí)行指定的操作以外淹冰, 還會順帶將 ht[0] 哈希表在 rehashidx 索引上的所有鍵值對 rehash 到 ht[1] 库车, 當(dāng) rehash 工作完成之后, 程序?qū)?rehashidx 屬性的值增一樱拴。
隨著字典操作的不斷執(zhí)行柠衍, 最終在某個時間點上, ht[0] 的所有鍵值對都會被 rehash 至 ht[1] 晶乔, 這時程序?qū)?rehashidx 屬性的值設(shè)為 -1 珍坊, 表示 rehash 操作已完成。
漸進式 rehash 的好處在于它采取分而治之的方式正罢, 將 rehash 鍵值對所需的計算工作均灘到對字典的每個添加阵漏、刪除、查找和更新操作上翻具, 從而避免了集中式 rehash 而帶來的龐大計算量履怯。
11、Redis的定時機制怎么實現(xiàn)的裆泳,有哪些弊端叹洲,你將如何改進這個弊端
Redis服務(wù)器是一個事件驅(qū)動程序,服務(wù)器需要處理以下兩類事件:文件事件(服務(wù)器對套接字操作的抽象)和時間事件(服務(wù)器對定時操作的抽象)晾虑。Redis的定時機制就是借助時間事件實現(xiàn)的疹味。
一個時間事件主要由以下三個屬性組成:id:時間事件標(biāo)識號;when:記錄時間事件的到達時間帜篇;timeProc:時間事件處理器糙捺,當(dāng)時間事件到達時,服務(wù)器就會調(diào)用相應(yīng)的處理器來處理時間笙隙。一個時間事件根據(jù)時間事件處理器的返回值來判斷是定時事件還是周期性事件洪灯。
弊端:Redis對時間事件的實際處理時間并不準(zhǔn)時,通常會比時間事件設(shè)定的到達事件稍晚一些竟痰。
改進:多線程签钩?一個處理文件事件掏呼,一個處理時間事件? (不確定)铅檩。
12憎夷、Redis是單線程的,為什么這么高效
雖然Redis文件事件處理器以單線程方式運行昧旨,但是通過使用I/O多路復(fù)用程序來監(jiān)聽多個套接字拾给,文件事件處理器既實現(xiàn)了高性能的網(wǎng)絡(luò)通信模型,又可以很好地與Redis服務(wù)器中其他同樣以單線程運行的模塊進行對接兔沃,這保持了Redis內(nèi)部單線程設(shè)計的簡單性蒋得。
13、Redis的數(shù)據(jù)類型有哪些乒疏,底層怎么實現(xiàn)
1)字符串:整數(shù)值额衙、embstr編碼的簡單動態(tài)字符串、簡單動態(tài)字符串(SDS)
2)列表:壓縮列表怕吴、雙端鏈表
3)哈希:壓縮列表窍侧、字典
4)集合:整數(shù)集合、字典
5)有序集合:壓縮列表械哟、跳躍表和字典
14疏之、Redis和memcached的區(qū)別
Redis和memcached的區(qū)別:
1)數(shù)據(jù)類型 :redis數(shù)據(jù)類型豐富,支持set liset等類型暇咆;memcache支持簡單數(shù)據(jù)類型锋爪,需要客戶端自己處理復(fù)雜對象
2)持久性:redis支持數(shù)據(jù)落地持久化存儲;memcache不支持數(shù)據(jù)持久存儲爸业。)
3)分布式存儲:redis支持master-slave復(fù)制模式其骄;memcache可以使用一致性hash做分布式。
4)value大小不同:memcache是一個內(nèi)存緩存扯旷,key的長度小于250字符拯爽,單個item存儲要小于1M,不適合虛擬機使用
5)數(shù)據(jù)一致性不同:redis使用的是單線程模型钧忽,保證了數(shù)據(jù)按順序提交毯炮;memcache需要使用cas保證數(shù)據(jù)一致性娃循。CAS(Check and Set)是一個確保并發(fā)一致性的機制竖瘾,屬于“樂觀鎖”范疇;原理很簡單:拿版本號笤受,操作大刊,對比版本號为迈,如果一致就操作,不一致就放棄任何操作
6)cpu利用:redis單線程模型只能使用一個cpu,可以開啟多個redis進程
15葫辐、TCP的模型搜锰,狀態(tài)轉(zhuǎn)移
TCP四層模型:
狀態(tài)轉(zhuǎn)移:
熟悉三次握手 和 四次釋放的TCP狀態(tài)轉(zhuǎn)移。
16耿战、用過哪些設(shè)計模式蛋叼,單例模式,觀察者模式的多線程安全問題
設(shè)計模式
1)Template Method模式:《effective c++》 條款35 :借助Non-virtual Interface手法實現(xiàn)Template Method模式
2)Strategy模式:《effective c++》 條款35:借助Function Pointers 實現(xiàn)Strategy模式昆箕、借助std::function完成Strategy模式鸦列、古典Strategy模式
17、用過多線程嗎鹏倘,以前的多線程代碼還能怎么優(yōu)化,線程池的實現(xiàn)
線程的創(chuàng)建
1#include 23int pthread_create(pthread_t *restrict thread,4constpthread_attr_t *restrict attr,5void *(*start_routine)(void*),6void *restrict arg);
線程終止:
從線程函數(shù)return顽爹。這種方法對主線程不適用纤泵,從main函數(shù)return相當(dāng)于調(diào)用exit。
一個線程可以調(diào)用pthread_cancel終止同一進程中的另一個線程镜粤。
線程可以調(diào)用pthread_exit終止自己捏题。
線程池的實現(xiàn):
18、epoll怎么實現(xiàn)的肉渴,reactor模型組成
epoll實現(xiàn):
第一步:epoll_create()系統(tǒng)調(diào)用公荧。此調(diào)用返回一個句柄,之后所有的使用都依靠這個句柄(eventpoll的對象)來標(biāo)識同规。
1structeventpoll{2....3/*紅黑樹的根節(jié)點循狰,這顆樹中存儲著所有添加到epoll中的需要監(jiān)控的事件*/4structrb_rootrbr;5/*雙鏈表中則存放著將要通過epoll_wait返回給用戶的滿足條件的事件*/6structlist_headrdlist;7....8};
第二步:epoll_ctl()系統(tǒng)調(diào)用。通過此調(diào)用向epoll對象中添加券勺、刪除绪钥、修改感興趣的事件,返回0標(biāo)識成功关炼,返回-1表示失敗程腹。
第三部:epoll_wait()系統(tǒng)調(diào)用。通過此調(diào)用收集收集在epoll監(jiān)控中已經(jīng)發(fā)生的事件儒拂。
Reactor模型:
1)Handle:即操作系統(tǒng)中的句柄寸潦,是對資源在操作系統(tǒng)層面上的一種抽象,它可以是打開的文件社痛、一個連接(Socket)见转、Timer等。由于Reactor模式一般使用在網(wǎng)絡(luò)編程中褥影,因而這里一般指Socket Handle池户,即一個網(wǎng)絡(luò)連接。
2)Synchronous Event Demultiplexer(同步事件復(fù)用器):阻塞等待一系列的Handle中的事件到來,如果阻塞等待返回校焦,即表示在返回的Handle中可以不阻塞的執(zhí)行返回的事件類型赊抖。這個模塊一般使用操作系統(tǒng)的select來實現(xiàn)。
3)Initiation Dispatcher:用于管理Event Handler寨典,即EventHandler的容器氛雪,用以注冊、移除EventHandler等耸成;另外报亩,它還作為Reactor模式的入口調(diào)用Synchronous Event Demultiplexer的select方法以阻塞等待事件返回,當(dāng)阻塞等待返回時井氢,根據(jù)事件發(fā)生的Handle將其分發(fā)給對應(yīng)的Event Handler處理弦追,即回調(diào)EventHandler中的handle_event()方法。
4)Event Handler:定義事件處理方法:handle_event()花竞,以供InitiationDispatcher回調(diào)使用劲件。
5)Concrete Event Handler:事件EventHandler接口,實現(xiàn)特定事件處理邏輯约急。
20零远、手撕代碼:1)給定一個數(shù)字數(shù)組,返回哈夫曼樹的頭指針厌蔽。2)最長公共連續(xù)子序列牵辣。
21、隨便挑一個自己收獲最多比賽或者項目介紹奴饮,收獲了什么
22纬向、單核機器上寫多線程程序,是否需要考慮加鎖拐云,為什么罢猪?
23、線程需要保存哪些上下文叉瘩,SP膳帕、PC、EAX這些寄存器是干嘛用的
24薇缅、HTTP和HTTPS的區(qū)別危彩,HTTPS有什么特點,帶來的好處和壞處泳桦,怎么實現(xiàn)的
25汤徽、線程間的同步方式,最好說出具體的系統(tǒng)調(diào)用
1)互斥量(mutex)
1#include<pthread.h>23intpthread_mutex_destroy(pthread_mutex_t*mutex);//銷毀4intpthread_mutex_init(pthread_mutex_t*restrictmutex,5constpthread_mutexattr_t*restrictattr);//初始化6pthread_mutex_tmutex = PTHREAD_MUTEX_INITIALIZER;78intpthread_mutex_lock(pthread_mutex_t*mutex);//上鎖9intpthread_mutex_trylock(pthread_mutex_t*mutex);//嘗試上鎖? ? 10intpthread_mutex_unlock(pthread_mutex_t*mutex);//解鎖
2)條件變量(Condition Variable)
1#include<pthread.h>23intpthread_cond_destroy(pthread_cond_t*cond);//銷毀4intpthread_cond_init(pthread_cond_t*restrictcond,5constpthread_condattr_t*restrictattr);//初始化6pthread_cond_tcond = PTHREAD_COND_INITIALIZER;78intpthread_cond_timedwait(pthread_cond_t*restrictcond,9pthread_mutex_t*restrictmutex,10conststructtimespec *restrictabstime);11intpthread_cond_wait(pthread_cond_t*restrictcond,12pthread_mutex_t*restrictmutex);13intpthread_cond_broadcast(pthread_cond_t*cond);14intpthread_cond_signal(pthread_cond_t*cond);
3)信號量(Semaphore)
1#include<semaphore.h>23intsem_init(sem_t*sem,intpshared,unsignedintvalue);4intsem_wait(sem_t*sem);5intsem_trywait(sem_t*sem);6intsem_post(sem_t* sem);7intsem_destroy(sem_t* sem);
調(diào)用sem_wait()可以獲得資源灸撰,使semaphore的值減1谒府,如果調(diào)用sem_wait()時semaphore的值已經(jīng)是0拼坎,則掛起等待。如果不希望掛起等待完疫,可以調(diào)用sem_trywait()泰鸡。調(diào)用sem_post()可以釋放資源,使semaphore的值加1壳鹤,同時喚醒掛起等待的線程盛龄。
26、哈希表的桶個數(shù)為什么是質(zhì)數(shù)芳誓,合數(shù)有何不妥余舶?
質(zhì)數(shù)比合數(shù)更容易避免沖撞,也就是說使用質(zhì)數(shù)時锹淌,哈希效果更好匿值,原始數(shù)據(jù)經(jīng)哈希后分布更均勻。
其余時間聊項目赂摆,聊拼多多使用的技術(shù)千扔。比較重要的一點是大家的項目經(jīng)歷,項目經(jīng)歷并不僅僅是擺在那里證明自己做過項目库正,要首先對項目有全局上的了解,再對自己負責(zé)的部分了如指掌厘唾,最好用到了什么組件和技術(shù)都去了解他們的原理褥符,那么在面試的時候就有很多很多聊的了。
(二)騰訊二面面經(jīng)
1抚垃、redis的主從復(fù)制怎么做的
Redis舊版復(fù)制功能只有同步和命令傳播喷楣。新版復(fù)制功能加入了部分同步的功能。
1)同步:
2)命令傳播:
當(dāng)主服務(wù)器會將自己執(zhí)行的寫命令鹤树,也即是造成主從服務(wù)器不一致的那條寫命令铣焊,發(fā)送給從服務(wù)器執(zhí)行,當(dāng)從服務(wù)器執(zhí)行了相同的寫命令之后罕伯,主從服務(wù)器將再次回到一致狀態(tài)曲伊。
3)部分同步:(斷線后重復(fù)制)
復(fù)制偏移量:通過對比主從服務(wù)器的復(fù)制偏移量,程序可以很容易地知道主從服務(wù)器是否處于一致狀態(tài)追他。
復(fù)制積壓緩沖區(qū):主服務(wù)保存最近的寫命令到復(fù)制積壓緩沖區(qū)坟募,是一個先進先出隊列
服務(wù)器運行ID:從服務(wù)器記錄上次同步的主服務(wù)器的Id。
2邑狸、寫代碼懈糯,去掉字符串中的空格空格
1#include 2using namespace std;3intmain()4{5charstr[40] =" abc 123? 456 ";6intnum =0;7inti;8for(i =0;str[i] !='\0'; ++i)9{10if(str[i] ==' ')11++num;12else13str[i-num] =str[i];14}15str[i-num] ='\0';16printf("%s\n",str);17}
3、如何把一個文件快速下發(fā)到100w個服務(wù)器
gossip算法单雾?Gossip有眾多的別名“閑話算法”赚哗、“疫情傳播算法”她紫、“病毒感染算法”、“謠言傳播算法”屿储。
4贿讹、如何判斷一個圖是否連同?
DFS扩所、BFS围详、并查集
5、ubuntu開機的時候系統(tǒng)做了什么
1)加載BIOS
BIOS程序首先檢查祖屏,計算機硬件能否滿足運行的基本條件助赞,這叫做”硬件自檢”。硬件自檢完成后袁勺,BIOS把控制權(quán)轉(zhuǎn)交給下一階段的啟動程序雹食。
2)讀取MBR
計算機讀取該設(shè)備的第一個扇區(qū),也就是讀取最前面的512個字節(jié)期丰。如果這512個字節(jié)的最后兩個字節(jié)是0x55和0xAA群叶,表明這個設(shè)備可以用于啟動;如果不是钝荡,表明設(shè)備不能用于啟動街立,控制權(quán)于是被轉(zhuǎn)交給”啟動順序”中的下一個設(shè)備。
3)Bootloader
在這種情況下埠通,計算機讀取”主引導(dǎo)記錄”前面446字節(jié)的機器碼之后赎离,不再把控制權(quán)轉(zhuǎn)交給某一個分區(qū),而是運行事先安裝的”啟動管理器”(boot loader)端辱,由用戶選擇啟動哪一個操作系統(tǒng)梁剔。
Boot Loader 就是在操作系統(tǒng)內(nèi)核運行之前運行的一段小程序。通過這段小程序舞蔽,我們可以初始化硬件設(shè)備荣病、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài)渗柿,以便為最終調(diào)用操作系統(tǒng)內(nèi)核做好一切準(zhǔn)備个盆。
Boot Loader有若干種,其中Grub做祝、Lilo和spfdisk是常見的Loader砾省。Linux環(huán)境中,目前最流行的啟動管理器是Grub混槐。
4)加載內(nèi)核
內(nèi)核的加載编兄,內(nèi)核加載后,接開始操作系統(tǒng)初始化声登,根據(jù)進程的優(yōu)先級啟動進程狠鸳。
看我主頁簡介免費C++學(xué)習(xí)資源揣苏,視頻教程、職業(yè)規(guī)劃件舵、面試詳解卸察、學(xué)習(xí)路線、開發(fā)工具
每晚8點直播講解C++編程技術(shù)铅祸。