天天看點

如何學好 Linux、C++,并搞定 BAT 面試 作者/分享人:天千

學好Linux運維需要做到以下幾點

1、多做實驗

實驗環境完全可以通過VMware來模拟,模拟私有網絡,模拟多台機器,要搞懂VMware提供的集中網絡模式的工作原理(橋接網絡、主控端網絡、NAT等),這對整個Linux後續的學習幫助都非常之大,還可以通過虛拟機模拟Grub損壞并進行修複、模拟忘記密碼并通過單使用者模式修改密碼等等。

2、LNMP、DHCP、DNS、MySQL等等這些網絡服務需要完全基于源碼來編譯

這樣更加有體感,對于編譯的參數要了解,因為通過yum安裝的軟體包都是上一個穩定版本,并不是最新穩定版本,還有另外一點就是編譯安裝可以通過編譯參數對軟體進行一定的優化。

3、Linux基礎要紮實

底層原理要了解,典型的檔案系統的組成、inode和資料存放的位置、Linux程序是如何排程的、排程算法有哪些、磁盤排程算法有哪些、TCP/IP的三次握手和四次揮手的過程是如何的,網絡中的資料是如何流向的(參考《建構高性能web站點》),iptables的三表五鍊、Nginx的網絡IO模型(這個很重要,你要能講清楚為什麼Nginx要比Apache好),馬哥Linux對于這個部分的内容講解是我最喜歡的,我強力推薦大家都去聽一聽馬哥的視訊。

4、英文文檔的閱讀能力

閱讀各類開源軟體的官方文檔是必經之路,這個也是了解一個開源軟體最快的捷徑,如果你沒有一定的英文閱讀能力,那麼你隻能等到有人把這些文章翻譯成中文後你才能學習到。

5、寫部落格

很多時候,看了視訊和書後,如果你不能講這些知識用你的語言表達出來,那麼很大可能,你并沒有真正的了解這些知識,通過寫部落格的方式會逼迫你回憶知識,然後總結出來,部落格被大量人通路也會在一定程度上激勵你,讓你有一定的成就感,促使你把部落格寫的更好。

6、Shell腳本的要熟悉

運維這條路上腳本會幫我們省掉不少體力活,此外必須要學習一門程式設計語言Python、Golang等

C語言要學好必須了解三個概念

1、什麼是指針?

指針和數組的關系。

2、程式分為哪幾個段

能說清楚全局變量,局部變量,靜态變量等分别屬于哪個段,各個段的特點是什麼?

3、C語言的編譯和鍊的接過程

真心不推薦在Windows上來學習C語言,因為它屏蔽了太多的細節,而這些細節卻又是C程式員不可或缺的一部分。C語言這個階段過去後,我開始學習Linux C系統程式設計這個部分,最開始接觸的一本書就是《Unix/Linux程式設計實踐教程》強力推薦給大家,這本書會給你介紹如何通過man手冊來幫助程式設計,如何去實作who、cat、ls、ps等系統指令。通過這本書的學習會讓你對Linux上很多的原理有一個深刻的認識。

這本書學完後我就開始看UNP和APUE,其中APUE我并不推薦給大家,我推薦給大家的是《Linux/UNIX系統程式設計手冊》這本書的内容更全面,更新。建議大家在看這些書的時候可以做詳細的筆記和代碼練習,在我的部落格上就有我總結的文章。系統程式設計ok後,就要重點看UNP了,看這本書的時候要找重點看,裡面有的章節已經過時了,還有一些章節對于我們目前來說用途并不大,比如STCP的部分。

對于這本書《Linux/UNIX系統程式設計手冊》,重點有三個部分

1、各個socket API的對應到OS,做了哪些事情

比如connect後,做了哪些事情?,accept呢?,什麼是RST封包?,什麼是SIGPIPE,如何觸發的?

2、網絡IO模型,同步和異步,阻塞和非阻塞的概念

Linux上各種網絡IO模型的優缺點對比,epoll、select、信号驅動IO等

3、伺服器的網絡程式設計模型,多線程、多程序、線程池等,各自優缺點

在我的部落格上也有一篇文章介紹了相關的内容,學完這個後,剩下的就靠多實踐和多讀一些開源的項目來積累自己的經驗了,這裡推薦cjson、webbench、Tinyhttpd等,代碼量都不大,很容易讀懂,在讀懂的基礎上可以進行适當的改造和重寫。

C語言和Linux系統程式設計這個部分結束後,就要開始踏入C++的世界了,自從C++11出來後,我覺得C++易學了,但是苦于現存的老的C++代碼還是有很多,是以我們不得不去學習C++98相關的知識,這裡我推薦《C++ primer》一書,注意是C++ primer,不是《C++ primer plus》

我看書的方法都比較老套,第一遍力求看懂,第二遍開始抄代碼,練習,第三遍開始總結寫部落格。是以這本書我前前後後看了大半年, 後面又看了C++程式設計思想上冊,Effective C++、深度了解C++對象模型、Exceptional C++、深入了解C++11等經典書籍,看書的模式基本上都是二到三遍,通過抄書上的代碼和寫部落格來加深記憶。看完這些書說真的,我覺得我的C++還隻是一個小白,我真正蛻變要從讀《Linux C++服務端程式設計》陳碩的這本書開始,通過這本書我覺得我的C++水準有了一個質的飛躍。

C++有以下幾個要點(隻是部分):

1、RAII

這個很重要,是C++的核心,很多學習了C++的人都不知道RAII

2、值語義和對象語義

這個決定了你如何寫好一個C++類

3、對象的生命周期,類的生命周期要清晰

4、智能指針

現代C++程式設計幾乎不太可能出現delete語句,記憶體洩漏的問題真的很少會出現

5、各種STL和C++的一些坑

比如疊代器周遊過程中如何删除元素、std::list的size接口的複雜度居然是O(N)(C++11已經修正)等等

6、善用std::bind和std::function

7、基于對象程式設計和面向對象程式設計的差別

8、移動語義很重要

9、Lambda的捕獲表達式

10、搞清楚C++的三五法則

11、std::string的實作方式,是否是線程安全的

12、std::map和std::set的底層資料結構等

《Effective Modern C++》,這本書我重點推薦給大家,在我的部落格上也有全部的總結,這本書講了很多C++11種的一些實作細節、坑以及建議。最後推薦一些linux核心相關的書籍和學習方法

《深入了解Linux核心架構》《Linux環境程式設計 從應用到核心》

重點找自己感興趣的子產品來看,比如我就對檔案系統,通過核心子產品來探索,不能隻看代碼不練習

網絡上有很多從頭開始編寫一個記憶體檔案系統的文章,在我的部落格上也有一個系列講解Linux核心子產品程式設計入門的文章,通過編寫Linux核心子產品可以做很多有趣的事情,比如系統調用攔截、網絡攔截、做安全審計等等,通過編寫核心子產品可以提高對Linux核心學習的興趣。

在整個求職過程中,我做了以下幾件事

1、刷leetcode的題目

從牛客網和google上搜集面試題,分門别類的進行整理,每天都回顧一下

2、拓寬自己的知識面,學習一些新的知識

比如當時流行的docker,更側重學習其原理

3、加深自己對一些底層的OS知識的了解

比如epoll的原理、docker的cgroup機制和namespace機制的實作、檔案系統VFS的實作、Linux信号、管道等的實作。

整理面試題和學習一些底層的OS知識對我整個面試過程中幫助很大,正常情況下如果你隻學習Java或者C++是很難拿到阿裡巴巴的Offer,阿裡巴巴對應屆生的知識面、知識的了解程度要求還是比較高的,在我的整個C++面試過程中,問的最多的就是IO複用、智能指針、記憶體洩漏的問題如何解決、如何排查Load高的問題、Linux核心相關的知識等,而這些問題對我來說早已得心應手,在搜集面試題的時候很多問題都是反複被提及到的,我隻需要好好總結即可。

另外一點就是大家在準備面試題的時候不能隻記一個結論,多問問為什麼,舉個例子,TCP/IP的三次握手和四次揮手的過程是什麼樣的,我們不光光要知道這個問題的結論,還要知道為什麼是三次握手,四次揮手,為什麼不是二次?當被問及到epoll、select的差別時,你應該從使用方法、可移植性、性能、優缺點、核心實作等多個方面分析和總結。而不是簡簡單單的就提及一個優缺點就完事了。 你擅長的地方你應該多多引導你的面試官去問。

工作心得

在公司實習了大約1年,今年七月份正式入職,在這整個過程中我也零散的做了很多小需求,對C++的了解更加深刻,尤其是對軟體工程有了一個新的了解,在此我想分享給大家。

1、要有造輪子的能力,但是不要輕易的去造輪子

2、單元測試的重要性

通過單元測試也可以提高程式員的信心,為了更好的寫單測,會逼迫我們将子產品之間的耦合降到最低,這樣可以友善單測。

3、寫易讀的、可維護的代碼

4、Google的C++程式設計規範,每一條都值得細細品味

5、Chromium開源項目有很多值得我們借鑒的地方

6、畫UML圖是程式員的基本素質,要有好的設計,設計要做評審

7、CodeReview一定要有的

8、類名和變量名的易讀性

可能對于很多人來說編碼規範、CodeReview、UML、單測好像都是說說而已,我起初也是這麼認為,感觸并不是很深刻,直到我的同僚開始帶我的時候,我自己親身去體驗的時候才發現這其中奧妙無窮, 我們團隊使用Chromium的base庫作為自己的基礎庫,編碼規範、全都follow Chromium,至于為什麼不用boost,我的理由則是,boost是一個我無法駕馭的怪獸,而chromium的base庫是我可以駕馭的,可以打組合拳,代碼的穩定性已經經過上億人的考驗,值得我們信賴。推薦大家看看chromium的base庫,源代碼很易讀。通過閱讀它的代碼可以學習到很多知識。推薦一本書給大家《C++ API設計》,講解了很多軟體工程、設計層面的知識。

總結

上面說了很多,更側重分享了我的學習經曆,和一些感悟,可能我說的比較簡單,實際上了解上面這些東西,是存在一個過程的,是一個從量變到質變的過程,在整個過程中我了解到,學習要堅持,不是一蹴而就的,要經曆量變到質變的過程。