2018百度雲校招面試總結
- 在這個面試體驗感很不舒服, 有壓力面試的感覺;
- 總結起來人家對我的項目一點不感興趣, 面后台的崗位都會很難;
現場筆試題
- 樹的和為k的所有路徑
- 樹的先序遍歷, 注意到遞歸結束條件
- 我代碼寫出來了, 但塗塗改改有點亂, 而且當時自己也不太確定, 就直接給面試官說給他講思路, 代碼應該是錯的;
- 這里犯了一個特別大的錯誤, 就是不夠自信, 一不自信就會給面試官的第一印象特別差, 導致后面的面試特別反感, 影響了整個面試過程的體驗;
面試官各種問題
- 問我的性格, 優缺點
- Nginx, hash, 紅黑樹, AVL樹, B+, B-樹
- 重新總結一下hash, 紅黑樹, AVL樹, B+樹, B-樹;
- 線程通信機制:
- 條件變量
- 條件變量的實現;
- 線程條件變量原理分析;
- 條件變量本質上是一個全局可訪問的flag,所以,線程在調用pthread_cond_wait之前必須先調用pthread_mutex_lock對條件變量加互斥鎖;
- pthead_cond_wait函數首先檢測當前條件變量的值,如果條件變量為真,線程直接從pthread_cond_wait函數返回,繼續執行下面的代碼;
- 如果為假,那么線程不具備工作的條件,必須等待,為了不浪費CPU資源,pthread_cond_wait函數讓線程進入了休眠狀態;
- 為了不阻塞其他線程,讓其他線程也可以訪問條件變量,pthread_cond_wait函數又釋放了互斥鎖;
- 但此時進入休眠狀態的線程依然位於pthread_cond_wait函數內,執行過程在pthread_cond_wait函數處阻塞;
- 當線程工作的條件具備時,pthread_cond_signal函數負責將條件變量修改為真,同時發信號通知等待的線程;
- 因等待條件變量而進入休眠狀態的線程將在pthread_cond_wait函數內被信號喚醒;
- 在pthread_cond_wait函數中, 先釋放鎖, 再睡眠, 再加鎖, 再對條件變量進行檢驗;
- 線程被喚醒的同時重新獲取了互斥鎖,並再次對條件變量檢測,發現條件變量為真,線程具備了工作的條件;
- pthread_cond_wait函數從阻塞(線程休眠)狀態返回,然后線程繼續執行下面的代碼;
- 線程在完成對全局資源的訪問后,釋放互斥鎖;
- 條件變量機子是將全局標記、線程信號、線程休眠、加鎖解鎖結合在一起, 主要包含在pthread_cond_wait函數內, 包括:
- 檢測條件變量, 為真從函數中返回, 繼續執行下一步, 為假則:
- 設置線程等待條件(變量變為真的)信號;
- 讓線程進入休眠狀態;
- 釋放互斥鎖;
- 接收到條件(變量變為真的)信號后, 則:
- 喚醒休眠的線程;
- 重新獲取互斥鎖;
- 重新檢驗條件變量, 為假, 則繼續執行步驟1, 為真則從函數內返回;
- pthread_cond_signal函數的主要工作是負責修改條件變量的值和發送信號提醒等待線程條件變量變成了真值;
- 檢測條件變量, 為真從函數中返回, 繼續執行下一步, 為假則:
- 條件變量和互斥量結合使用, 互斥鎖保護的是兩種資源: 條件變量和線程需要訪問的全局資源;
- 因為線程在pthread_cond_wait函數內被喚醒后,重新獲取了互斥鎖,然后才能檢測條件變量,條件變量為真,從函數返回后,並沒有申請獲取其他的互斥鎖,就繼續對全局資源訪問,並在完成訪問后只釋放了一次互斥鎖;
- 共享內存怎么加鎖
- shm_ptr是共享內存映射得來的虛擬地址, 用映射的虛擬地址來保存互斥量
- 用信號量來完成互斥的效果
- 文件記錄鎖
- 自己實現一個原子的自旋鎖
- 使用無所結構
- 生產者-消費者模型中的隊列,可以使用無鎖隊列來實現
- 包括共享線程鎖、文件鎖、使用無鎖結構
- 被問得懷疑人生
- gdb調試 core dump文件
- gdb調試coredump使用篇;
- coredump叫作核心轉儲, 它是進程運行時在突然崩潰的那一時刻的一個內存快照;
- 操作系統在程序發生異常而異常在進程內部又沒有被捕獲的情況下,會把進程此刻內存、寄存器狀態、運行堆棧等信息轉儲保存在一個文件里;
- 這個coredump產生的文件是一個二進制文件;
- 雖然我們知道進程在coredump的時候會產生core文件, 但有時候發現進程雖然core了, 但我們卻找不到core文件;
- ulimit -c 可以設置core文件的大小,如果這個值為0.則不會產生core文件,這個值太小,則core文件也不會產生,因為core文件一般都比較大;
- gdb的簡單使用教程;
- l 查看源碼(list);
- b 加斷點(break);
- r 開始運行調試(restart);
- n 下一步(next);
- s 下一步但是會進入子函數();
- p 輸出數據(printf);
- gdb 其它常用命令用法 c q b info;
- 多線程調試常用就這三個實用命令
- info threads
- thread id
- set scheduler-locking on/off
- gdb調試coredump使用篇;
- epoll機制怎么實現事件回調的
- 通過epoll_ctl向紅黑樹添加要被監測的事件時, 會向內核注冊回調函數, 當事件活躍的時候會觸發中斷函數, 調用回調函數, 然后把該活躍的事件添加到雙向鏈表中;
- C++11的四種智能指針, 有缺點
- auto_ptr 已經被C++11棄用了
- shared_ptr
- weak_ptr
- unique_ptr 是為了取代auto_ptr的產物;
- unique_ptr是一個獨享所有權的智能指針, 它提供了嚴格意義上的所有權;
- 擁有它指向的對象;
- 無法進行復制構造, 無法進行復制賦值操作, 即無法使兩個unique_ptr指向同一個對象, 但是可以進行移動構造和移動賦值操作;
- 保存指向對象的指針, 當它本身被刪除釋放的時候, 會使用給定的刪除器釋放它指向的對象;
- unique_ptr 可以實現如下功能:
- 為動態申請的內存提供異常安全
- 講動態申請的內存所有權傳遞給某函數
- 從某個函數返回動態申請內存的所有權
- 在容器中保存指針
- auto_ptr 應該具有的功能
- 迭代器什么時候才會失效
- STL各種容器迭代器失效的時機;
- 標准STL序列容器:vector、string、deque和list;
- 標准STL關聯容器:set、multiset、map和multimap。
- 非標准序列容器slist和rope;
- slist是一個單向鏈表,rope本質上是一個重型字符串
- 非標准關聯容器hash_set、hash_multiset、hash_map和hash_multimap;
- 幾種標准非STL容器,包括數組、bitset、valarray、stack、queue和priority_queue;
- 值得注意的是,數組可以和STL算法配合,因為指針可以當作數組的迭代器使用;
- vector:
- 當插入(push_back)一個元素后,end操作返回的迭代器肯定失效。
- 當插入(push_back)一個元素后,capacity返回值與沒有插入元素之前相比有改變,則需要重新加載整個容器,此時first和end操作返回的迭代器都會失效。
- 當進行刪除操作(erase,pop_back)后,指向刪除點的迭代器全部失效;指向刪除點后面的元素的迭代器也將全部失效。
- deque迭代器的失效情況:
- 在deque容器首部或者尾部插入元素不會使得任何迭代器失效。
- 在其首部或尾部刪除元素則只會使指向被刪除元素的迭代器失效。
- 在deque容器的任何其他位置的插入和刪除操作將使指向該容器元素的所有迭代器失效。
- List/set/map
- 刪除時,指向該刪除節點的迭代器失效;
- STL中迭代器失效詳解;
- vector重新申請內存迭代器就會失效;
- fork(), waitfork();
- 還有好多都忘得差不多了, (~衰~);
- 內存泄漏時, 用戶程序吃內存, 把程序內存吃滿了會怎么辦? 內核程序呢?
- 面試官當時說的是不管是用戶還是內核程序, 內核內存管理子系統都會把占用內存的程序kill掉;
- 淺談Linux的內存管理機制;
- 虛擬內存就是為了滿足物理內存的不足而提出的策略,它是利用磁盤空間虛擬出的一塊邏輯內存,用作虛擬內存的磁盤空間被稱為交換空間(Swap Space);
- Linux系統會不時的進行頁面交換操作,以保持盡可能多的空閑物理內存,即使並沒有什么事情需要內存,Linux也會交換出暫時不用的內存頁面, 避免需要時等待分配, 有點未雨綢繆的味道;
- 內核是如何管理內存的;