導航:首頁 > 源碼編譯 > 源碼版本的梳理

源碼版本的梳理

發布時間:2023-02-09 23:51:20

① OkHttp源碼解析 (三)——代理和路由

初看OkHttp源碼,由於對Address、Route、Proxy、ProxySelector、RouteSelector等理解不夠,讀源碼非常吃力,看了幾遍依然對於尋找復用連接、創建連接、連接伺服器、連接代理伺服器、創建隧道連接等邏輯似懂非懂,本篇決定梳理一遍相關的概念及基本原理。

● HTTP/1.1(HTTPS)
● HTTP/2
● SPDY

一個http請求的流程(直連):
1、輸入url及參數;
2、如果是url是域名則解析ip地址,可能對應多個ip,如果沒有指定埠,則用默認埠,http請求用80;
3、創建socket,根據ip和埠連接伺服器(socket內部會完成3次TCP握手);
4、socket成功連接後,發送http報文數據。

一個https請求的流程(直連):
1、輸入url及參數;
2、如果是url是域名則解析ip地址,可能對應多個ip,如果沒有指定埠,則用默認埠,https請求用443;
3、創建socket,根據ip和埠連接伺服器(socket內部會完成3次TCP握手);
4、socket成功連接後進行TLS握手,可通過java標准款提供的SSLSocket完成;
5、握手成功後,發送https報文數據。

1、分類
● HTTP代理:普通代理、隧道代理
● SOCKS代理:SOCKS4、SOCKS5

2、HTTP代理分類及說明
普通代理
HTTP/1.1 協議的第一部分。其代理過程為:
● client 請求 proxy
● proxy 解析請求獲取 origin server 地址
● proxy 向 origin server 轉發請求
● proxy 接收 origin server 的響應
● proxy 向 client 轉發響應
其中proxy獲取目的伺服器地址的標准方法是解析 request line 里的 request-URL。因為proxy需要解析報文,因此普通代理無法適用於https,因為報文都是加密的。

隧道代理
通過 Web 代理伺服器用隧道方式傳輸基於 TCP 的協議。
請求包括兩個階段,一是連接(隧道)建立階段,二是數據通信(請求響應)階段,數據通信是基於 TCP packet ,代理伺服器不會對請求及響應的報文作任何的處理,都是原封不動的轉發,因此可以代理 HTTPS請求和響應。
代理過程為:
● client 向 proxy 發送 CONNET 請求(包含了 origin server 的地址)
● proxy 與 origin server 建立 TCP 連接
● proxy 向 client 發送響應
● client 向 proxy 發送請求,proxy 原封不動向 origin server 轉發請求,請求數據不做任何封裝,為原生 TCP packet.

3、SOCKS代理分類及說明
● SOCKS4:只支持TCP協議(即傳輸控制協議)
● SOCKS5: 既支持TCP協議又支持UDP協議(即用戶數據包協議),還支持各種身份驗證機制、伺服器端域名解析等。
SOCK4能做到的SOCKS5都可得到,但反過來卻不行,比如我們常用的聊天工具QQ在使用代理時就要求用SOCKS5代理,因為它需要使用UDP協議來傳輸數據。

有了上面的基礎知識,下面分析結合源碼分析OkHttp路由相關的邏輯。OkHttp用Address來描述與目標伺服器建立連接的配置信息,但請求輸入的可能是域名,一個域名可能對於多個ip,真正建立連接是其中一個ip,另外,如果設置了代理,客戶端是與代理伺服器建立直接連接,而不是目標伺服器,代理又可能是域名,可能對應多個ip。因此,這里用Route來描述最終選擇的路由,即客戶端與哪個ip建立連接,是代理還是直連。下面對比下Address及Route的屬性,及路由選擇器RouteSelector。

描述與目標伺服器建立連接所需要的配置信息,包括目標主機名、埠、dns,SocketFactory,如果是https請求,包括TLS相關的SSLSocketFactory 、HostnameVerifier 、CertificatePinner,代理伺服器信息Proxy 、ProxySelector 。

Route提供了真正連接伺服器所需要的動態信息,明確需要連接的伺服器IP地址及代理伺服器,一個Address可能會有很多個路由Route供選擇(一個DNS對應對個IP)。

Address和Route都是數據對象,沒有提供操作方法,OkHttp另外定義了RouteSelector來完成選擇的路由的操作。

1、讀取代理配置信息:resetNextProxy()

讀取代理配置:
● 如果有指定代理(不讀取系統配置,在OkHttpClient實例中指定),則只用1個該指定代理;
● 如果沒有指定,則讀取系統配置的,可能有多個。

2、獲取需要嘗試的socket地址(目標伺服器或者代理伺服器):resetNextInetSocketAddress()

結合Address的host和代理,解析要嘗試的套接字地址(ip+埠)列表:
● 直連或者SOCK代理, 則用目標伺服器的主機名和埠,如果是HTTP代理,則用代理伺服器的主機名和埠;
● 如果是SOCK代理,根據目標伺服器主機名和埠號創建未解析的套接字地址,列表只有1個地址;
● 如果是直連或HTTP代理,先DNS解析,得到InetAddress列表(沒有埠),再創建InetSocketAddress列表(帶上埠),InetSocketAddress與InetAddress的區別是前者帶埠信息。

3、獲取路由列表:next()

選擇路由的流程解析:
● 遍歷每個代理對象,可能多個,直連的代理對象為Proxy.DIRECT(實際是沒有中間代理的);
● 對每個代理獲取套接字地址列表;
● 遍歷地址列表,創建Route,判斷Route如果在路由黑名單中,則添加到失敗路由列表,不在黑名單中則添加到待返回的Route列表;
● 如果最後待返回的Route列表為空,即可能所有路由都在黑名單中,實在沒有新路由了,則將失敗的路由集合返回;
● 傳入Route列表創建Selection對象,對象比較簡單,就是一個目標路由集合,及讀取方法。

為了避免不必要的嘗試,OkHttp會把連接失敗的路由加入到黑名單中,由RouteDatabase管理,該類比較簡單,就是一個失敗路由集合。

1、創建Address
Address的創建在RetryAndFollowUpInteceptor里,每次請求會聲明一個新的Address及StreamAllocation對象,而StreamAllocation使用Address創建RouteSelector對象,在連接時RouteSelector確定請求的路由。

每個Requst都會構造一個Address對象,構造好了Address對象只是有了與伺服器連接的配置信息,但沒有確定最終伺服器的ip,也沒有確定連接的路由。

2、創建RouteSelector
在StreamAllocation聲明的同時會聲明路由選擇器RouteSelector,為一次請求尋找路由。

3、選擇可用的路由Route

下面在測試過程跟蹤實例對象來理解,分別測試直連和HTTP代理HTTP2請求路由的選擇過程:
● 直連請求流程
● HTTP代理HTTPS流程
請求url: https://www.jianshu.com/p/63ba15d8877a

1、構造address對象

2、讀取代理配置:resetNextProxy

3、解析目標伺服器套接字地址:resetNextInetSocketAddress

4、選擇Route創建RealConnection

5、確定協議

測試方法:
● 在PC端打開Charles,設置埠,如何設置代理,網上有教程,比較簡單;
● 手機打開WIFI,選擇連接的WIFI修改網路,在高級選項中設置中指定了代理伺服器,ip為PC的ip,埠是Charles剛設置的埠;
● OkHttpClient不指定代理,發起請求。

1、構造address對象

2、讀取代理配置:resetNextProxy

3、解析目標伺服器套接字地址:resetNextInetSocketAddress

4、選擇Route創建RealConnection

5、創建隧道
由於是代理https請求,需要用到隧道代理。

從圖可以看出,建立隧道其實是發送CONNECT請求,header包括欄位Proxy-Connection,目標主機名,請求內容類似:

6、確定協議,SSL握手

1、代理可分為HTTP代理和SOCK代理;
2、HTTP代理又分為普通代理和隧道代理;普通代理適合明文傳輸,即http請求;隧道代理僅轉發TCP包,適合加密傳輸,即https/http2;
3、SOCK代理又分為SOCK4和SOCK5,區別是後者支持UDP傳輸,適合代理聊天工具如QQ;
4、沒有設置代理(OkHttpClient沒有指定同時系統也沒有設置),客戶端直接與目標伺服器建立TCP連接;
5、設置了代理,代理http請求時,客戶端與代理伺服器建立TCP連接,如果代理伺服器是域名,則解釋代理伺服器域名,而目標伺服器的域名由代理伺服器解析;
6、設置了代理,代理https/http2請求時,客戶端與代理伺服器建立TCP連接,發送CONNECT請求與代理伺服器建立隧道,並進行SSL握手,代理伺服器不解析數據,僅轉發TCP數據包。

如何正確使用 HTTP proxy
OkHttp3中的代理與路由
HTTP 代理原理及實現(一)

② VC++6.0中如何把源代碼格式整理規范

只有縮進的功能,就是選中後按Alt+F8,沒有自動幫你換行幫你整理的功能,只能用第三方軟體實現。

③ 如何高效閱讀源代碼

下面是之前寫的一篇文章:《如何快速閱讀源碼》

本文探討在需要了解一個開源項目時,如何快速的理清開源項目的代碼邏輯!

以下是個人認為行之有效的方法:

本文以Mybatis為例來進行演示!

先「跑起來」

程序界有個老傳統,學習新技術時都是從「Hello World」開始的!無論是學習新語言時,列印「Hello World」;還是學習新框架時編寫個demo!那為什麼這里的「跑起來」要打個引號呢?

實際上,當你想要閱讀一個開源項目的源碼時,絕大部分情況下,你已經能夠使用這個開源項目了!所以這里的「跑起來」就不是寫個「Hello World」,也不是能跑起來的程序了!而是能__在你的腦子里「跑起來」__!什麼意思?

Mybatis你會用了吧?那麼請問Mybatis是如何執行的呢?仔細想想,你能否用完整的語句把它描述出來?

這里是Mybatis的官方入門文章!你是如何看這篇文章的?讀一遍就行了嗎?還是跟著文章跑一遍就夠了嗎?從這篇文章里你能獲得多少信息?

我們來理一下:

回答出了上面這些問題!你也就基本能在腦子里把Mybatis「跑起來」了!之後,你才能正真的開始閱讀源碼!

當你能把一個開源項目「跑起來」後,實際上你就有了對開源項目最初步的了解了!就像「 書的索引 」一樣!基於這個索引,我們一步步的進行拆解,來細化出下一層的結構和流程,期間可能需要深入技術細節,考量實現,考慮是否有更好的實現方案!也就是說後面的三步並不是線性的,而是__不斷交替執行__的一個過程!最終就形成一個完整的源碼執行流程!

自頂向下拆解

繼續通過Mybatis來演示(限於篇幅,我只演示一個大概流程)!我們現在已經有了一個大概的流程了:

雖說每個點都可以往下細化,但是也分個輕重緩急!

很明顯,SqlSession去執行 sql才是Mybatis的核心!我們先從這個點入手!

首先,你當然得先下載Mybatis的源碼了(請自行下載)!

我們直接去看SqlSession!它是個介面,裡面有一堆執行sql的方法!

這里只列出了一部分方法:

SqlSession就是通過這些方法來執行sql的!我們直接看我們常用的,也是Mybatis推薦的用法,就是基於Mapper的執行!也就是說「SqlSession通過Mapper來執行具體的sql」!上面的流程也就細化成了:

那SqlSession是如何獲取Mapper的呢?Mapper又是如何執行sql的呢?

深入細節

我們來看SqlSession的實現!SqlSession有兩個實現類SqlSessionManager和DefaultSqlSession!通過IDE的引用功能可以查看兩個類的使用情況。你會發現SqlSessionManager實際並沒有使用!而DefaultSqlSession是通過DefaultSqlSessionFactory構建的!所以我們來看DefaultSqlSession是如何構建Mapper的!

它直接委託給了Configuration的getMapper方法!

Configuration又委託給了MapperRegistry類的getMapper方法!

在MapperRegistry類的getMapper中:

在這里knowMappers是什麼?MapperProxyFactory又是什麼?mapperProxyFactory.newInstance(sqlSession)具體做了什麼?

其實很簡單,knowMappers是個Map,裡麵包含了class與對應的MapperProxyFactory的對應關系!MapperProxyFactory通過newInstance來構建對應的Mapper(實際上是Mapper的代理)!

快接近真相了,看mapperProxyFactory.newInstance(sqlSession)里的代碼:

這里幹了什麼?

最終實際還是委託給了sqlSession去執行具體的sql!後面具體怎麼實現的就自行查看吧!

延伸改進

現在我們的流程大概是這樣的一個過程:

現在我們大概知道了:

那麼,

這個問題列表可以很長,可以按個人需要去思考並嘗試回答!可能最終這些問題已經和開源項目本身沒有什麼關系了!但是你思考後的收獲要比看源碼本身要多得多!

再循環

一輪結束後,可以再次進行:

不斷的拆解->深入->改進,最終你能__通過一個開源項目,學習到遠比開源項目本身多得多的知識__!

最重要的是,你的流程是完整的。無論是最初的大致流程:

還是到最終深入的細枝末節,都是個完整的流程!

這樣的好處是,你的時間能自由控制:

而不像debug那樣的方式,需要一下子花費很長的時間去一步步的理流程,費時費力、收效很小,而且如果中斷了就很難繼續了!

總結

本文通過梳理Mybatis源碼的一個簡單流程,來講述一個個人認為比較好的閱讀源碼的方式,並闡述此方法與傳統debug方式相比的優勢。

閱讀源碼是每個優秀開發工程師的必經之路,那麼這篇文章就來講解下為什麼要閱讀源碼以及如何閱讀源碼。

首先來說下為什麼要讀源碼,有學習源碼的必要嗎?

為什麼要閱讀源碼?

關於為什麼閱讀和學習源碼,我個人認為可能有以下幾點:

(一)吊打面試官,應對面試

為了找到更好的工作,應對面試,因為在面試中肯定會問到源碼級別的問題,比如:為什麼 HashMap 是線程不安全的?

如果你沒有閱讀過源碼,面試官可能會對回答的結果不滿意,進而導致面試結果不太理想,但如果你對源碼有所研究,並能夠很好地問答面試官的問題,這可能就是你的加分點,可以形成自己獨特的競爭力,吊打面試官,升職加薪不是夢。

(二)解決問題(bug)

在開發過程中,我們或多或少會遇到 bug,比如:在 foreach 循環里進行元素的 remove/add 操作,為啥有可能會報 異常?

我們可以先在 Google、Stack Overflow 以及對應項目的 Issues 里看有沒有類似問題以及解決辦法,如果沒有的話,我們只能通過閱讀源碼的方式去解決了。如果我們對相關源碼有所涉獵,就可以快速定位到問題所在。

(三)提升編程能力

和閱讀一本好書一樣,閱讀源碼就是和編程大牛面對面交流的機會,在許多優秀的開源項目中,它們的編碼規范和架構設計都是很棒的,另外在設計上也使用了大量的設計模式,通過閱讀和學習源碼,能夠快速提升我們的編碼水平,以及對設計模式有更深的理解。

同時,在我們閱讀完一個源碼後,可以觸類旁通,能夠快速地對其他框架的源碼進行閱讀和學習,減少時間成本。

除了上述提到的原因之外,可能還有許多,在這里就不一一贅述了,那麼在確定了要閱讀源碼之後,就讓我們看下如何閱讀源碼吧!

如何閱讀源碼?

如何閱讀源碼取決於你為什麼要讀源碼,比如:

下面大概說下閱讀源碼的幾點建議:

在閱讀之前,可以先從開源項目的官網上看它的架構設計和功能文檔,了解這個項目的 整體架構、模塊組成以及各個模塊之間的聯系

如果沒有對應的項目文檔,可以根據代碼的模塊進行梳理,以形成對項目的初步了解,或者 查看已有的源碼解析文章或者書籍 ,在閱讀源碼之前,了解項目的架構和思路會使閱讀源碼事半功倍。

在了解一個類的時候,可以使用 ctrl+F12 來查看類中的成員變數和方法。

可以通過 IDEA 的 Diagrams 功能去了解一個類的繼承關系。

多打 斷點調試 ,斷點追蹤源碼是很好的閱讀源碼的方式,可以先通過 debug 了解下調用邏輯,都和哪些類有關聯,有大致了解後再通過 debug 了解整體代碼的功能實現,各個類都起到了什麼作用,有沒有涉及到設計模式等。

另外,優秀的開源項目中肯定會有許多地方應用到了 設計模式 ,建議在閱讀源碼之前,需要對常用的設計模式有大致的了解,不然閱讀源碼的效率會大大降低。

如果遇到讀不懂某部分源碼的時候,可以先跳過,之後再回來看,如果屬於搞不懂這部分就茶不思飯不想的人,可以在網上找是否有該部分源碼的解析或者文檔,也可以自己通過 源碼注釋和測試用例 去閱讀學習。

一般優秀的開源項目都會有 單元測試 ,可以通過對應類的單元測試去了解方法的含義和用法,加深對源碼邏輯的理解。

在閱讀源碼的時候,可以在代碼上加上 注釋和總結 ,同時還可以畫出 時序圖和類圖 ,這樣對閱讀源碼有很大的幫助,可以很清楚地知道類之間的調用關系和依賴關系,也方便以後回顧,重新閱讀。

在這里推薦大家一個 IDEA 插件 SequenceDiagram,可以根據源碼生成調用時序圖,便於閱讀源碼。

剛開始閱讀源碼,不建議直接看框架源碼,可以先從 jdk 源碼看起:

jdk 源碼也是非常龐大的,可以分模塊來閱讀,下面是建議的閱讀順序:

其他包下的代碼也可以做下了解,JDK源碼閱讀筆記:https://github.com/wupeixuan/JDKSourceCode1.8

再有了一定的源碼閱讀經驗後,可以再去學習 Spring、Spring Boot、Dubbo、Spring Cloud 等框架的源碼。

總結

主要介紹了為什麼讀源碼以及如何讀源碼,供大家參考,每個人都有適合自己的閱讀源碼的方式,希望可以在學習中去摸索出一套屬於自己的方式。

閱讀源碼不是一蹴而就的,這是持久戰,只要你能夠堅持下來,肯定受益匪淺。閱讀源碼的過程比較枯燥,可以在社群里一起討論學習,這樣可能效率更高些。

沒看過源代碼,都不好意思出來說了,最近剛好在看一些,來說一個。

先看使用 https://element.eleme.cn/#/zh-CN/component/installation


先看一下這個庫是做什麼用的,然後提供了哪些功能。

看GitHub https://github.com/elemefe


一般會看下項目最新的情況,然後沒有關閉的issue,看下wiki,大家在討論什麼。

再看代碼


clone 一份到本地,然後先看下目錄結構,然後根據文檔看幾個簡單的組件的時候,一邊看掘金上的分析,一邊自己看下實現。


e le

餓了么這個框架代碼結構還是很清楚的,基本上每個組件都是分開的,所以你只要看其他的一個文件夾就行。然後一些工具的都在src文件夾。



要學會看issue,一般開源的項目都有人會來提建議,有些是bug,有些是功能,你可以看看自己是否有能力去解決,如果可以的話,你可以去fork代碼,然後自己修改,再提pr。

我最近恰好找摸索出一個梳理遺留系統架構的技巧:自底向上 找到一個典型的切面 沿著調用和回調的路徑 在代碼中添加結構化注釋(比如eclipse中加//TAG 流程A1.1 甲->>乙),這樣便得到了一個code地圖,並且在tasks視圖中看起來很直觀(看起來跟書的目錄一樣)可快速跳轉。將目錄到有道雲筆記的markdown序列圖中 就自動生成了一個序列圖。

我覺得這基本上就是可縮放的可視化架構地圖了,對維護一個比較亂和龐大的遺留系統非常有幫助,定位代碼 修改維護都方便多了。

1、需要過硬的基礎知識,這個前提。不然基本語法、常用的模式都不曉得怎麼讀。

2、多參考 歷史 版本和更新變化,好的源碼都是反復迭代出來的精華,開始就讀精華是很不明智的,所以看看版本更新說明,版本的 歷史 演變。就想人一樣是怎樣進化過來的。

3、參考別人閱讀注釋,想必在你讀源碼之前也有人讀過了源碼,並且總結,注釋。和分享原理,可供你參考,畢竟每個人讀一篇文章,理解的東西是有差異化的。

4、直接買書,有些作品直接出書就是源碼精解

5、找個大神給你慢慢分析,這個最快。娓娓道來,直接面授比啥都強。缺點是,你容易跟著他的思維走下去。

我覺得閱讀代碼就不應該高效,而應該像看小說一樣,看的過程就像是在和作者交流,有趣才是看代碼的動力。

畫圖,看數據走向,邏輯走向

先弄清楚這些代碼實現了哪些功能,然後從主線開始往下看,好的代碼光看變數和介面名稱就能明白是什麼意思?扒出源碼實現的整體框架邏輯,然後再對自己感興趣的模塊進行剖析,還是從整體把握,細節深入,慢慢地整個框架就被豐滿了。

接下來是思考為什麼要如此設計,這樣設計的好處是什麼?如果是你來做應該怎麼設計,把你覺得源碼缺點的地方進行仔細研究,了解裡面是否包含自己不清楚的細節,避免遺漏。

接下來就是根據代碼改造或者是調試錯誤,對於源碼中遇到的不理解的地方一定要弄明白,有的確實是畫蛇添足,有的有獨特的作用。

多多學習,對每一種主流框架銘記於心,對主流設計模式了如指掌,萬變不離其宗,源碼看多了,跟看一個電視機遙控器的操作說明一樣。

1、一邊閱讀代碼一邊寫注釋。這是我用過的最好的方法,對代碼理解得更深入,看一些重要代碼或者特別難懂的代碼時挺有用。更何況,注釋也是一種文檔嘛。

2、一邊閱讀代碼一邊繪制UML。這個方法適用於類之間的關系較復雜和調用層次較深的情況,我一般都是先繪制順序圖,然後為順序圖中的類繪制關系圖。

3、通過Debug來跟蹤程序的主要執行過程,這樣就可以分清主次了,閱讀的時候更有針對性。

4、類的快速閱讀。先弄清楚它在繼承鏈中的位置,看看它的內部狀態,也就是成員變數,一般來說,類的對外介面都是對成員變數的訪問、加工、代理等,然後看看它的對外介面,也就是公有成員函數,識別核心的一個或多個函數,這時候你應該可以大概了解這個類的職責或作用了。可能這個類是某個設計模式中的一個組成部分,所以,設計模式的掌握對代碼的快速閱讀也是很有幫助的。

5、帶著問題去閱讀。比如想了解android中的消息機制,那麼看看Looper、Handler、MessegeQueue這幾個類就可以了,其他的不要去看,要不然就跑題了。

下面列幾個閱讀源碼時所處的情景,在特定場景下用哪些方法: 不太熟悉業務邏輯,還不是很清楚它是幹啥的,可以用3、5。 代碼量很大,有幾十萬行,甚至百萬行,可以用2、3、5。 你無法看見程序的運行過程,比如沒有用戶界面,也有可能是無法運行的,可以用3、5。 設計復雜,用了大量的設計模式,調用鏈很深,可以用1、2、3、4、5。 時間有限,沒有那麼多時間讓你看源碼,可以用3、5。

畫出邏輯流程圖,先了解整體流程,再詳解具體函數

④ 看源代碼時,你喜歡怎麼做筆記

學習編程的人,往往繞不過 Github,經過這段時間的嘗試,我發現 Github 的確有很適合做筆記的地方。 但,非常不建議用issue,其最大的問題在於不支持 git 操作,也就是備份及版本管理非常麻煩。 顧名思義啊,issue是提出問題,討論問題的地方,用這個寫筆記,抑或是寫博客。的確非常特立獨行,但是否真的合適,值得商榷。我知道這種方式的流行是因為某些前端大牛。但,我始終認為,永遠不要跟風大牛的行徑,多聽聽自己內心的聲音。 那麼在 Github 我推薦什麼?是 Wiki,About GitHub Wikis · GitHub Help。這個東西的初衷是用來做項目說明文檔的,而文檔,不就是更規范的一種筆記形式嗎?況且, Wiki 因其自身特性,本來就是最高效知識整理工具,大牛們用 Wiki 來積累知識與技能的例子數不勝數:例如閑耘™. Wiki ,第一次看到時真的把我震撼到了。

⑤ 大牛們是怎麼閱讀 Android 系統源碼的

由於工作需要大量修改framework代碼, 在AOSP(Android Open Source Project)源碼上花費了不少功夫, Application端和Services端都看和改了不少.
如果只是想看看一些常用類的實現, 在Android包管理器里把源碼下載下來, 隨便一個IDE配好Source Code的path看就行.
但如果想深入的了解Android系統, 那麼可以看下我的一些簡單的總結.

知識
Java
Java是AOSP的主要語言之一. 沒得說, 必需熟練掌握.
熟練的Android App開發
Linux
Android基於Linux的, 並且AOSP的推薦編譯環境是Ubuntu 12.04. 所以熟練的使用並了解Linux這個系統是必不可少的. 如果你想了解偏底層的代碼, 那麼必需了解基本的Linux環境下的程序開發. 如果再深入到驅動層, 那麼Kernel相關的知識也要具備.
Make
AOSP使用Make系統進行編譯. 了解基本的Makefile編寫會讓你更清晰了解AOSP這個龐大的項目是如何構建起來的.
Git
AOSP使用git+repo進行源碼管理. 這應該是程序員必備技能吧.
C++
Android系統的一些性能敏感模塊及第三方庫是用C++實現的, 比如: Input系統, Chromium項目(WebView的底層實現).

硬體
流暢的國際網路
AOSP代碼下載需要你擁有一個流暢的國際網路. 如果在下載代碼這一步就失去耐心的話, 那你肯定沒有耐心去看那亂糟糟的AOSP代碼. 另外, 好程序員應該都會需要一個流暢的Google.
一台運行Ubuntu 12.04的PC.
如果只是閱讀源碼而不做太多修改的話, 其實不需要太高的配置.
一台Nexus設備
AOSP項目默認只支持Nexus系列設備. 沒有也沒關系, 你依然可以讀代碼. 但如果你想在大牛之路走的更遠, 還是改改代碼, 然後刷機調試看看吧.
高品質USB線
要刷機時線壞了, 沒有更窩心的事兒了.
軟體
Ubuntu 12.04
官方推薦, 沒得選.
Oracle Java 1.6
注意不要用OpenJDK. 這是個坑, 官方文檔雖然有寫, 但還是單獨提一下.
安裝:
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer
sudo apt-get install oracle-java6-set-default

Eclipse
估計會有不少人吐槽, 為什麼要用這個老古董. 其實原因很簡單, 合適. 剛開始搞AOSP時, 為了找到效率最優的工具, 我嘗試過Eclipse, IntelliJ IDEA, Vim+Ctags, Sublime Text+Ctags. 最終結果還是Eclipse. 主要優點有:
有語法分析 (快速准確的類, 方法跳轉).
支持C++ (IntelliJ的C++支持做的太慢了).
嵌入了DDMS, View Hierarchy等調試工具.
為了提高效率, 花5分鍾背下常用快捷鍵非常非常值得.
調整好你的classpath, 不要導入無用的代碼. 因為AOSP項目代碼實在是太多了. 當你還不需要看C++代碼時, 不要為項目添加C++支持, 建索引過程會讓你崩潰.
Intellij IDEA
開發App必備. 當你要調試系統的某個功能是, 常常需要迅速寫出一個調試用App, 這個時候老舊的Eclipse就不好用了. Itellij IDEA的xml自動補全非常給力.
巨人的肩膀

這個一定要先讀. 項目介紹, 代碼下載, 環境搭建, 刷機方法, Eclipse配置都在這里. 這是一切的基礎.

這個其實是給App開發者看的. 但是裡面也有不少關於系統機制的介紹, 值得細讀.

此老羅非彼老羅. 羅升陽老師的博客非常有營養, 基本可以作為指引你開始閱讀AOSP源碼的教程. 你可以按照博客的時間順序一篇篇挑需要的看.但這個系列的博客有些問題:
早期的博客是基於舊版本的Android;
大量的代碼流程追蹤. 讀文章時你一定要清楚你在看的東西在整個系統處於什麼樣的位置.

鄧凡平老師也是為Android大牛, 博客同樣很有營養. 但是不像羅升陽老師的那麼系統. 更多的是一些技術點的深入探討.

Android官方Issue列表. 我在開發過程中發現過一些奇怪的bug, 最後發現這里基本都有記錄. 當然你可以提一些新的, 有沒有人改就是另外一回事了.

一定要能流暢的使用這個工具. 大量的相關知識是沒有人系統的總結的, 你需要自己搞定.
其它
代碼組織
AOSP的編譯單元不是和git項目一一對應的, 而是和Android.mk文件一一對應的. 善用mmm命令進行模塊編譯將節省你大量的時間.
Binder
這是Android最基礎的進程間通訊. 在Application和System services之間大量使用. 你不僅要知道AIDL如何使用, 也要知道如何手寫Binder介面. 這對你理解Android的Application和System services如何交互有非常重要的作用. Binder如何實現的倒不必著急看.
HAL
除非你對硬體特別感興趣或者想去方案公司上班, 否則別花太多時間在這一層.
CyanogenMod
這是一個基於AOSP的第三方Rom. 從這個項目的wiki里你能學到很多AOSP官方沒有告訴你的東西. 比如如何支持Nexus以外的設備.
DIA
這是一個Linux下畫UML的工具, 能夠幫你梳理看過的代碼.
XDA

這里有最新資訊和最有趣的論壇.
想到了再補充.

⑥ 昭通java培訓學校告訴你java源碼管理與版本控制工具

java項目一般都是團隊開發,當多人共同編寫一個項目的時候。代碼的整合就需要用到專門的源碼管理工具了。另外java項目版本的不斷更新,也需要版本的管理。所以源碼管理與版本控制工具也是每個java程序員必須要熟練掌握的。目前比較流行的java版本控制工具主要有svn、git這兩款軟體。昭通北大青鳥http://www.kmbdqn.cn/認為這兩種工具也是每個java程序員必須要熟練掌握的。



SVN


SVN是Subversion的簡稱,是一個開放源代碼的版本控制系統,相較於RCS、CVS,它採用了分支管理系統,它的設計目標就是取代CVS。互聯網上很多版本控制服務已從CVS遷移到Subversion。說得簡單一點SVN就是用於多個人共同開發同一個項目,共用資源的目的。SVN的缺陷是過分依賴網路,不適合分布式開發。


使用svn的工作流程如下:1、早上從從伺服器下載項目組最新代碼。


2、進入自己的分支,進行工作,每隔一個小時向伺服器自己的分支提交一次代碼(很多人都有這個習慣。因為有時候自己對代碼改來改去,最後又想還原到前一個小時的版本,或者看看前一個小時自己修改了哪些代碼,就需要這樣做了)。


3、下班時間快到了,把自己的分支合並到伺服器主分支上,一天的工作完成,並反映給伺服器。


Git


Git是一個開源的分布式版本控制系統,可以有效、高速的處理從很小到非常大的項目版本管理。


Git是LinusTorvalds為了幫助管理Linux內核開發而開發的一個開放源碼的版本控制軟體。與常用的版本控制工具CVS,Subversion等不同,它採用了分布式版本庫的方式,不必伺服器端軟體支持(ps:這得分是用什麼樣的服務端,使用http協議或者git協議等不太一樣。並且在push和pull的時候和伺服器端還是有交互的。),使源代碼的發布和交流極其方便。


目前GIT已經可以在windows下使用,主要方法有二:msysgit和Cygwin。Cygwin和Linux使用方法類似,Windows版本的GIT提供了友好的GUI(圖形界面),安裝後很快可以上手使用。


⑦ Zookeeper選主過程,理論和源碼結合,看這一篇足夠了

【共4239字,閱讀需要15分鍾】

Zookeeper作為Dubbo生態的默認注冊中心,得到了非常的普遍的應用,雖然後來阿里又出了nacos,但是不可否認的是ZK仍然是一款非常優秀的開源產品,非常優秀的注冊中心備選方案。

ZK有很多特性,本篇文章主要介紹ZK的選主過程(後宮佳麗三千,我就獨寵你一人)

要說選主的過程,我們首先得了解ZK到底有哪些節點,這些節點充當得角色是什麼?

ZK本身得節點主要分為三類:

Leader:主要是負責數據的寫入,如果超過半數同意,那麼就廣播進行寫入;

Follower:主要負責查詢請求並將寫入請求發送給leader,參與選舉和寫入投票;

Observe:也是負責查詢請求並將寫入請求發送給leader,不參加投票,只被動接收結果

獲取半數投票以上的節點成為leader節點。

萬事萬物都有一個准則,好的比較壞的,壞的比較更壞的,世上本沒有痛苦,痛苦都是自己尋找的結果,海燕你可長點心吧,哎呀跑偏了。

ZK比較的時候有三個指標或者三個維度:

(1)任期

(2)事務ID(ZK中的事務ID)

(3)節點編號(集群中每個節點的編號)

根據以上三個指標就可以說出最終的結論了:選擇任期大的,任期一樣選擇事務ID大的,前兩個都一樣,選擇節點編號大的。

就這么簡單?是的。規則就是這么簡單,但是源碼還是有那麼一丟丟的繞。

源碼看著相對比較枯燥,但是作為一個手藝人,怎麼能不去了解怎麼做的呢,我們先來梳理一下代碼的流程,方便更好的看第四部分內容。

節點先投自己一票,然後進行廣播

節點內部循環進行消息接收

收到消息後

如果消息為空,就進行重新發送消息或者建立連接

如果消息不為空,且消息接收者和投票的leader都是合法節點就進行下邊步驟。

如果節點為looking節點

根據當前節點的投票和接收到的投票進行比較來決定是否需要再次發送投票並且記錄投票的結果

每次都判斷記錄的票數,如果過半就進行節點狀態的設置

選主的邏輯是在lookForLeader開始的,像金字塔的第一塊磚一樣,我們先看ZK選主的第一塊磚lookForLeader,第一次看源碼得時候一定要把握主線,忽略從線,等主線完全理清楚了之後才去處理從線,要不會陷入迷宮之中。

下邊就是主要的投票代碼,看里邊的注釋:

更新投票或者投票的方法為:

發送通知的方法為:

待到山花爛漫時,她在叢中笑,消息都已經發完了,肯定就到了接收到選票的時候應該怎麼操作了,接收選票的代碼也是在lookForLeader中:

接上代碼繼續討論,校驗發送投票節點的狀態,我們從本文的第一章節知道Observe節點是不參與投票的,只是轉發寫請求和被動接收數據,負責查詢請求,所以從代碼中我們也可以看出來:

當發送投票的節點狀態是FOLLOWING和LEADING時,代表發送節點已經選舉完成,所以處理方法的邏輯都是一樣滴,這部分限於篇幅太長,暫時就不深入討論了,感興趣的朋友可以私信我或者加我微信號M_P_E_D進行交流和溝通。

終於到重頭戲了,咱們看看LOOKING狀態時的代碼:
我們先把totalOrderPredicate方法放前邊,這個其實就是選舉leader的規則的實現。

道阻且長,行則將至,行而不輟,未來可期,加油。

⑧ 如何查看源代碼的版本

確認的方法很簡單:

1. 編譯的時候在終端中一開始就會列印出來:

PLATFORM_VERSION:2.3.1
2. 直接去make文件中去看:

build\core\version_defaults.mk //搜索該文件中的 PLATFORM_VERSION值

⑨ Category實現的原理一:底層結構及源碼分析

❓比如說有如下3個類,思考一下如下圖所示的實例方法存放在哪裡?

下面我們就來驗證一下上面的結論.

我們的分類 HHPerson+eat 被轉換為類型為 static struct _category_t ,變數名為: _OBJC_$_CATEGORY_HHPerson_$_eat :

實例方法列表:

協議列表: (HHPerson+eat實現了 NSCopying,NSCoding 協議)

屬性列表:

以上就是分類的底層結構,可以看到,分類的信息在編譯期間都被分離出來了,下面我們從 runtime 源碼研究一下分類.

我們梳理一下 attachCategories (cls,cats,true) 方法. attach 一詞是 附加 的意思,從名字上我們可以看出這個方法大概意思是: 附加分類 .事實上它的確如此,下面我開始研究:

本篇主要講了 category 的底層數據結構,和分析 runtime 如何處理 category 分類信息的.在下篇文章中-- Category實現的原理二:分類信息如何添加到本類中 將介紹 runtime 如何將分類信息添加到本類中.

閱讀全文

與源碼版本的梳理相關的資料

熱點內容
pdf合並成一個pdf在線 瀏覽:383
柱加密區構造要求 瀏覽:514
地板木龍骨標准跟加密區別 瀏覽:150
解壓放鬆的好地方河南 瀏覽:965
搜狗怎麼移動到文件夾 瀏覽:617
文件自動選擇到文件夾 瀏覽:794
贈送的app怎麼在ipad下載 瀏覽:508
頸椎解壓後神經恢復 瀏覽:849
怎麼看app訂閱扣費 瀏覽:314
linux系統的負載均衡 瀏覽:419
遇到挫折解壓視頻 瀏覽:778
什麼指令看伺服器運行負載 瀏覽:84
因碩智能門鎖卡片是加密的么 瀏覽:336
為什麼會伺服器不可用 瀏覽:290
wow宏命令設置 瀏覽:264
解壓神器一張紙折疊魔術球 瀏覽:23
怎麼樣可以取消加密軟體oppo 瀏覽:580
屏幕共享源碼哪家比較不錯 瀏覽:665
vb中雙擊命令按鈕 瀏覽:208
伺服器做了磁碟陣列怎麼重裝 瀏覽:606