學習計算機組成原理、編譯原理、操作系統對學習編程有哪些幫助呢?

我基本上是自學編程,從零開始學Java然後學Android


有幫助啊,這幾門課加上計算機網路和數學,基本上決定了你能走多遠。

舉個例子,從聯繫最緊密的操作系統來說吧,你寫多線程/多進程的程序就得和操作系統的知識打交道。寫多線程得加鎖吧,臨界區、死鎖的四個條件之類的標準的操作系統的內容吧(不得不吐槽一下,某國內一線電商幹了三年的程序猿,寫多線程居然不知道加鎖,也是醉了)。進程間通信的幾種方式什麼管道、socket、共享內存等,這也是操作系統的內容吧。文件系統,這也是經常要打交道的東西。還有內存什麼的,你做 Android 開發,這些裡邊有很多東西都在系統層面被封裝好了,但是你要是不知道原理,一旦出了錯根本無從調試,況且你該不會打算寫一輩子寫 Android 就是填邏輯吧。

然後,是編譯原理,普通的程序猿是接觸不到編譯器或者虛擬機的開發的。但是這並不意味著編譯原理就用不到。說個最常見的讀取配置文件,只要你的配置文件有自定義的語法,你就要用編譯原理的東西。還有類似於自動生成代碼啦、正則表達式啦這些都算是編譯原理的內容。你既然是寫 Java 的不了解虛擬機怎麼可以,最基本的位元組碼總是需要能看懂的吧,分析一些疑難雜症的時候位元組碼還是很有用的。

最後,是計算機原理,如果只是做應用開發的話計算機原理其實不必要掌握的多深入,但是一些基本的概念還是要清楚的。比如 寄存器、緩存、中斷什麼的,關鍵的時候可以幫助你調試。在一些對性能要求非常高的場合,也是很有作用的。此外,學了計算機組成基本上彙編差不多能夠看懂了吧,這個對於優化代碼、查錯、反彙編還是很有用的。


這個回答是2016-2-14年寫的,那個時候還沒有開始學習操作系統的內核源碼,現在在學習計算機網路了,而且碰到有人點贊,我也不想困囿於之前的思維框架里,所以用前段時間另外一個問題的回答來補充一下。

作者:安陽

鏈接:當你學會了什麼之後感覺自己的編程算是入門了? - 安陽的回答

來源:知乎

著作權歸作者所有,轉載請聯繫作者獲得授權。

計算機這個體系,每一個環節都是為了解決某個問題而衍生出來的

1、計算機組成原理,最早的計算機是為了解決具有大計算量的問題,從最開始的邏輯門,到加法器,到控制器等等,都是為了讓計算機能夠快速自動計算。

2、操作系統是為了解決cpu利用率(程序的並發執行:單核上),以及在並發的基礎上,解決並發進程共享所有資源所出現的一些問題(總的來說操作系統比較重要的點 就是並發、以及解決從並發所帶來的共享一些資源所帶來的問題)。

3、計算機網路是為了解決不同的計算機上進程(運行中或者準備運行的程序)通信的問題。

4、高級語言是為了解決計算機只能識別二進位語言,但是二進位語言對人類並不友好,所以先有彙編語言,但是彙編語言也有一定的局限性,寫起來啰嗦,所以延伸出高級語言來幫助提高人的理解。(要注意這裡的理解只是相對於彙編而言,不要把例子延伸到面向過程、面向對象或者一些設計的問題上)

5、總的來說,計算機本身只能識別二進位語言,所以不管你用什麼語言來控制計算機,總歸要編譯成二進位語言,這裡面就又延伸出編譯原理這門課。

6、最後還有就是非常重要的在整個體系裡面,就是分散式,在c/s這個結構中,伺服器是有可擴展性的,原因是因為普通用戶使用網路具有突發性的特點(這個特點在網路中是非常重要的一個特點),伺服器不能預測什麼時候用戶的請求會到來,會有多少用戶的請求到來。從這裡面就又能推導出很對的問題。

7、數據結構與演算法,我自己認為這是一種有效提高cpu利用率的一種方法,一種操作數據存儲數據的一種方式。

整個體系結構就在這裡,所以我不再恐懼,學下去就是。

我一直認為計算機就是一門處理各種問題的學科,圍繞不同的問題而發展起來的不同的分支,不管是工程上還是科學上,都是存在各種各樣的問題,學習計算機的過程就是解決這些問題的過程。

2016-9-21 11:32

我學了一年半之後的感想:編程是什麼?

單純從學習的角度來看,編程首先要明確的是這一門課要解決的是怎麼樣的問題。

然後就是沿著這個問題不斷的思考,按照一定的基本原則,考慮你能想到的場景去思考這些問題的解決方法,而看教科書則是在思考的同時,不斷地去踏前人已經踏過的坑,看看別人是怎麼思考,是怎麼解決這個問題。

從一個點不斷的往外延伸,如果我們要學的課程整個體系是主幹的話,那麼普通意義上的編程(寫代碼)就是主幹的觸鬚。運用你的思考去解決一些實際問題,然後不斷反饋修正主幹的認知。

寫於2017-1-22,15:04

=========================(原回答)====================================

題豬,你好,我也是跟你一樣是自學計算機,而你問的這個人問題,我曾經也問過類似的題目,我到目前為止沒有做過小項目,就我目前的學習我來說說我的學習經驗。

為什麼要學習計算機組成原理?

作為一個想要玩計算機的人我覺得學這門課是很有必要的,不僅僅是為了了解問題,而是裡面一層又一層的架構,比如存儲器的層次結構,為什麼要有cache(高速緩存存儲器)怎麼平衡各級存儲器的速度和價格的不對等。

了解cpu是非常有必要的,cpu是怎麼執行指令的,cpu是怎麼定址的,至於更細的cpu中的寄存器有什麼作用這些都能在彙編中(哪怕是16位的8086)中有更多的細節了解。

不學習計算機組成原理,那麼你學彙編就會有點困難,我學的是王爽的彙編語言,因為學過計算機組成原理,這本書的前三章基本上沒有什麼障礙,在這本書中我最喜歡的一個概念是分段和中斷(我始終覺得這個概念是貫穿計算機始終的)

這個時候你學習操作系統,你也能很快理解其中的一些原理,比如進程,進程的切換,進程的調度等等,存儲器的管理,為什麼要用虛擬內存,分頁的話又要分成幾頁呢,因為多頁要多次訪問內存,能不能快速取出指令呢。

學習這些就是不斷提出問題解決問題的過程。

數據結構和演算法也是。


謝邀。

我自頂向下地分析一個最簡單的小程序好了。

#include &

int main(int argc, char const *argv[])
{
int a = 1;
int b = 2;
int c = a + b;
printf("%d
", c);
return 0;
}

這就是一個最簡單的a+b程序。相信大家在初學編程的時候都會寫過這個。

那麼,當你在Visual Studio敲下這段小程序,按下「運行」的時候發生了什麼?

大體來講是這麼兩個階段:編譯源碼生成可執行文件-&>執行生成的可執行文件。

編譯的時候做了什麼事情?

拿gcc來說,首先是預處理。預處理的時候,並根據定義的預處理語句來處理源碼。

然後進行編譯。編譯又可以大體分為幾個階段:

  1. 詞法分析,把源碼流分割轉換為token流
  2. 語法分析,把token流轉換為某種中間表示(比如AST)
  3. 優化。這個過程會根據優化的需要,把AST轉換為其他的中間表示形式(比如為了暴露出控制流,轉換為CFG)
  4. 代碼生成。這個過程生成與源碼對應的用目標語言表示出來的程序集合。

其中1、2可以說是編譯器的前端。3算是編譯器中端。4是編譯器的後端。

(當然這只是一個基本的模型,不是所有編譯器都是這種形式的。比如只是搞一個像babel、http://bridge.NET這種把高級語言編譯成另一種高級語言的,其實是不需要寫優化器的,或者是我生成完代碼之後再跑一遍窺孔優化也是完全有可能的,或者說有的為了性能,把詞法分析和語法分析放到一起寫。不要以為所有的編譯器都是這幾個階段就好。)

在這裡,編譯之後生成的是彙編代碼。然後gcc把彙編處理為目標文件。得到目標文件之後,把這個目標文件和其他lib鏈接起來,生成可執行的exe文件。

然後你發現這個程序調用了printf。C本身不實現任何IO操作的。那這個printf是誰實現的?很顯然是操作系統實現的這個函數。你自己實現操作系統的時候,也會實現自己的printf()、scanf()、malloc()和free()。

然後你發現,最後所有的程序,運行的時候其實是運行了機器碼(彙編只是機器語言的助記符)。那麼add這些彙編指令是怎麼實現的?這時候你就要看看加法器是怎麼實現的,也就是組成原理的內容。

對應這三部分推薦幾本書吧。

編譯器設計 (豆瓣)

深入理解計算機系統(原書第2版) (豆瓣)

編碼 (豆瓣)

後面可以當作你實現操作系統和解釋器時的指導。當然《兩周自製腳本語言》里造的那個語言過於粗糙了,入個門什麼的還是不錯的。

30天自製操作系統 (豆瓣)

兩周自製腳本語言 (豆瓣)


瀉藥

別的先不說,編譯原理可是有大用的。僅就編譯器前端(parsing)來說,人造語言,文法,自動機這些知識在處理字元串方面相當有用啊,更別說自動機這個應用很廣泛的東西了。另外parsing不僅對編譯器有用,也為通用的字元串處理提供了範式。(想想正則表達式吧)

另外兩個似乎沒有直接的應用,要是說僅僅為了「加深理解」去學習組成原理和操作系統好像比較虧……剛想起來中斷這個概念對理解linux的signal有用,結果題主是寫android的……這樣的話,學習操作系統的概念對多線程編程有幫助吧,我猜。另外有利於鍛煉大腦,加強工作記憶/滑稽

題主沒有寫計網,我猜應該是很深刻地理解了計網的重要性才不寫了吧/滑稽

樓上安陽的說法我比較贊同,組成原理和操作系統的很多知識是常識性的知識,不知道就不能算懂計算機,所以想玩好計算機是必須懂的,當然,搞不懂計算機也可以編程/滑


從基礎學起可以讓你在學上層框架時舉一反三,因為他們的原理是一樣的。比如先花了3個月學了android,再學ios可能又要3個月,但是基礎好的話,入門ios可能只要幾天就可以做出東西了。再比如,實際工作中會碰到各種各樣的問題,很多百度不到,如果不懂這些基礎就只能瞎猜,自己解決問題的能力很弱。最後,寫出的程序在性能、質量上都會有差距。

簡單地說,學好基礎意味著錢多些。


概括的說,程序員乾的活就是將問題轉化為恰當的形式後通過編寫程序,控制計算機自動化的解決問題。對於計算機的深入理解有助於更好的轉化問題、編寫程序、提升工作效率。

實踐中,學習以上知識至少可以回答你以下問題:

C語言解析二進位文件時,先把文件全部讀入到內存一個字元數組裡,再解析是否能提高效率?

CPU 只能進行數值運算,那麼計算機是怎麼顯示出字元的?

計算機中的浮點數在數軸上分布均勻嗎?

等等,知乎上一抓一大把。


瀉藥。如果只是做兩年碼農,只需要掌握工具即可。如果定位於工程師,理論基礎不可少。但是學習的步驟科學化則是先學會使用,再探究原理。


這三門課從計算機發展的角度看是從0到1的質變,重要的是思想


如今講究的是挖地三尺,就看深不深了


我的理解:

組成原理解釋了計算機硬體是如何實現軟體的程序邏輯的。

現在你用Android寫了一個算1+1等於幾的app。

組成原理告訴了你計算機是怎麼把『1』,『+』,『1』 這三個輸入變成 2 的。

-------------------------------------------------------

拿Android來說吧。

在1.x、2.x版本的Android系統上,系統默認關閉應用的硬體加速選項。這時圖形系統的計算是通過CPU來完成的,結果就是界面非常卡頓。特別是如果你在進行後台耗CPU任務時,圖形交互簡直不能用。如果手機有GPU,而應用打開了硬體加速選項,那麼響應速度可以有成倍提高,並大大減少CPU佔用。因為GPU的浮點計算能力遠遠強於CPU。原理就在組成原理上講。

簡單來說,GPU有更多的計算核心,適合做流水,適合大規模數據計算;而CPU有更多的cache,更多的邏輯判斷硬體,適合複雜邏輯計算。比方說,100個四則運算求結果,用GPU來做更好;如果是一個100行的代碼,裡面有各種if、while、switch,那麼用CPU更好,因為編譯器會幫你把這段代碼優化成更好的處理邏輯。怎麼利用CPU的硬體,怎麼優化,編譯原理里編譯器優化講的。

在Android中一個很重要的部分就是binder機制,也就是IPC在Android中的實現。為什麼要有binder?因為進程在用戶態有自己的運行空間且互不侵犯,binder是為了解決一個進程往另一個進程送消息的問題的。那它們怎麼通信?大概思路就是想辦法在內核態註冊一個共享的緩衝區。這些都是操作系統的原理。

其實如果只是要做一個比較偏上層的程序員的話,組成原理和編譯原理只知道個大概就行了,操作系統是無論如何都都要懂的。

但是如果都很精通,你的方向就是系統架構師這個等級。


推薦閱讀:

Windows 操作系統中的公文包是什麼?有什麼作用?
怎樣自己寫一個簡單的操作系統?
從操作系統本身來看Linux是否比Windows優秀?
為什麼很多人覺得瀏覽器會成為下一代操作系統,而不認為操作系統會成為下一代瀏覽器?
為什麼列印店的電腦都特別喜歡用XP或者最多win7的系統?

TAG:操作系統 | 編程 | 編譯原理 | 計算機組成原理 |