nodejs php go語言瞭解

1、Nodejs

1) 簡單的說 Node.js 就是運行在服務端的 JavaScript。

2) Node.js 是一個基於Chrome JavaScript 運行時建立的一個平臺。

3) Node.js是一個事件驅動I/O服務端JavaScript環境,基於Google的V8引擎,V8引擎執行Javascript的速度非常快,性能非常好。

4) 我們寫下的js代碼,是在單線程的環境中執行,但nodejs本身不是單線程的。如果我們在代碼中調用了nodejs提供的異步api(如IO等),它們可能是通過底層的c(c++?)模塊在另外的線程中完成。但對於我們自己的js代碼來說,它們處於單線程中。因爲異步函數執行完將結果通過回調函數傳給我們的時候,我們的代碼一次只能處理一個。

5) 我們寫的js代碼就像是一個國王,而nodejs給國王提供了很多僕人。早上,一個僕人叫醒了國王,問他有什麼需要。國王給他一份清單,上面列舉了所有需要完成的任務,然後睡回籠覺去了。當國王回去睡覺之後,僕人才離開國王,拿着清單,給其它的僕人一個個佈置任務。僕人們各自忙各自的去了,直到完成了自己的任務後,纔回來把結果稟告給國王。國王一次只召見一個人,其它的人就在外面排着隊等着。國王處理完這個結果後,可能給他佈置一個新的任務,或者就直接讓他走了,然後再召見下一個人。等所有的結果都處理完了,國王就繼續睡覺去了。直接有新的僕人完成任務後過來找他。這就是國王的幸福生活。

6) nodejs不適合用來開發cpu密集運算的程序,而適合做那些IO操作比較多,但本身不需要計算太多的程序。因爲IO操作通過都是通過異步由nodejs在其它線程中完成,所以不會影響到主線程。

7)從他推出至今,充滿讚美和飽受詬病的都是其單線程模型,所有的任務都在一個線程中完成(I/O等例外),優勢的地方自然是免去了頻繁切換線程的開銷,以及減少資源互搶的問題等等,但是當nodejs面對cpu密集型模型的時候就力不從心了。儘管node擁有異步機制,可以把一些耗時算法丟入eventloop等待下個事件循環再做,但是因爲其任然是單線程模型,所以終究會造成阻塞。

先解釋一下兩個名詞,Fibers 和 Threads。Fibers 又稱纖程,可以理解爲協同程序,類似py和lua都有這樣的模型。使用Fibers可以避免對資源的互搶,減少cpu和內存的消耗,但是Fibers並不能夠真正的並行執行,同一時刻只有一個Fibers在執行,如果在其中一個Fibers中執行過多的cpu操作或者寫了個死循環,則整個主程序將卡死住。node中的異步事件循環模型就有點象這個。Threads 又稱線程,他可以在同一時刻並行的執行,他們共享主進程的內存,在其中某一時刻某一個threads鎖死了,是不會影響主線程以及其他線程的執行。但是爲了實現這個模型,我們不得不消耗更多的內存和cpu爲線程切換的開銷,同時也存在可能多個線程對同一內存單元進行讀寫而造成程序崩潰的問題。


2、php

1)PHP 是一種創建動態交互性站點的強有力的服務器端腳本語言。

2)PHP是一個單線程的腳本開發語言,它常在Web開發及系統集成中出現。

http://www.tuicool.com/articles/JNn2ai


3、Go

1)Go有什麼優勢
  • 可直接編譯成機器碼,不依賴其他庫,glibc的版本有一定要求,部署就是扔一個文件上去就完成了。
  • 靜態類型語言,但是有動態語言的感覺,靜態類型的語言就是可以在編譯的時候檢查出來隱藏的大多數問題,動態語言的感覺就是有很多的包可以使用,寫起來的效率很高。
  • 語言層面支持併發,這個就是Go最大的特色,天生的支持併發,我曾經說過一句話,天生的基因和整容是有區別的,大家一樣美麗,但是你喜歡整容的還是天生基因的美麗呢?Go就是基因裏面支持的併發,可以充分的利用多核,很容易的使用併發。
  • 內置runtime,支持垃圾回收,這屬於動態語言的特性之一吧,雖然目前來說GC不算完美,但是足以應付我們所能遇到的大多數情況,特別是Go1.1之後的GC。
  • 簡單易學,Go語言的作者都有C的基因,那麼Go自然而然就有了C的基因,那麼Go關鍵字是25個,但是表達能力很強大,幾乎支持大多數你在其他語言見過的特性:繼承、重載、對象等。
  • 豐富的標準庫,Go目前已經內置了大量的庫,特別是網絡庫非常強大,我最愛的也是這部分。
  • 內置強大的工具,Go語言裏面內置了很多工具鏈,最好的應該是gofmt工具,自動化格式化代碼,能夠讓團隊review變得如此的簡單,代碼格式一模一樣,想不一樣都很困難。
  • 跨平臺編譯,如果你寫的Go代碼不包含cgo,那麼就可以做到window系統編譯linux的應用,如何做到的呢?Go引用了plan9的代碼,這就是不依賴系統的信息。
  • 內嵌C支持,前面說了作者是C的作者,所以Go裏面也可以直接包含c代碼,利用現有的豐富的C庫。
2)Go適合用來做什麼
  • 服務器編程,以前你如果使用C或者C++做的那些事情,用Go來做很合適,例如處理日誌、數據打包、虛擬機處理、文件系統等。
  • 分佈式系統,數據庫代理器等
  • 網絡編程,這一塊目前應用最廣,包括Web應用、API應用、下載應用、
  • 內存數據庫,前一段時間google開發的groupcache,couchbase的部分組建
  • 雲平臺,目前國外很多雲平臺在採用Go開發,CloudFoundy的部分組建,前VMare的技術總監自己出來搞的apcera雲平臺。
3)Go還存在的缺點
以下缺點是我自己在項目開發中遇到的一些問題:
  • Go的import包不支持版本,有時候升級容易導致項目不可運行,所以需要自己控制相應的版本信息
  • Go的goroutine一旦啓動之後,不同的goroutine之間切換不是受程序控制,runtime調度的時候,需要嚴謹的邏輯,不然goroutine休眠,過一段時間邏輯結束了,突然冒出來又執行了,會導致邏輯出錯等情況。
  • GC延遲有點大,我開發的日誌系統傷過一次,同時併發很大的情況下,處理很大的日誌,GC沒有那麼快,內存回收不給力,後來經過profile程序改進之後得到了改善。
  • pkg下面的圖片處理庫很多bug,還是使用成熟產品好,調用這些成熟庫imagemagick的接口比較靠譜


4、select poll epoll

select:http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html

poll:http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html

epoll:http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html

總結:

(1)select,poll實現需要自己不斷輪詢所有fd集合,直到設備就緒,期間可能要睡眠和喚醒多次交替。而epoll其實也需要調用epoll_wait不斷輪詢就緒鏈表,期間也可能多次睡眠和喚醒交替,但是它是設備就緒時,調用回調函數,把就緒fd放入就緒鏈表中,並喚醒在epoll_wait中進入睡眠的進程。雖然都要睡眠和交替,但是select和poll在“醒着”的時候要遍歷整個fd集合,而epoll在“醒着”的時候只要判斷一下就緒鏈表是否爲空就行了,這節省了大量的CPU時間。這就是回調機制帶來的性能提升。

(2)select,poll每次調用都要把fd集合從用戶態往內核態拷貝一次,並且要把current往設備等待隊列中掛一次,而epoll只要一次拷貝,而且把current往等待隊列上掛也只掛一次(在epoll_wait的開始,注意這裏的等待隊列並不是設備等待隊列,只是一個epoll內部定義的等待隊列)。這也能節省不少的開銷。



5、unix與linux bsd關係描述

Linux 和 BSD 都是類 UNIX 操作系統。我們可以通過閱讀類 UNIX 操作系統歷史發現 Linux 和 BSD 有不同的譜系。Linux 是由 Linus Torvalds 在芬蘭上大學的時候開發的。BSD 則代表“Berkeley Software Distribution,伯克利軟件套件”,其源於對加州大學伯克利分校所開發的貝爾實驗室UNIX的一系列修改,它最終發展成一個完整的操作系統,現在有多個不同的BSD分支。

https://linux.cn/article-3186-1.html





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章