[2020年面試題-PHP 與 golang] 1. Go,Go 和 PHP 在執行的時候有什麼區別和優勢?

wangchunbo發表於2020-05-12

@author
汪春波(www.shxdledu.cn)

分享:[分享] 大環境下瑟瑟發抖辭職的第二天,拿了兩個 offer

  1. 看你簡歷裡也有用過 Go,Go 和 PHP 在執行的時候有什麼區別和優勢?

題主原回答:
PHP 每個請求進來時都會建立 fpm-worker 程式,從而導致系統併發高時 CPU 會產生頻繁建立程式的開銷,而 Go 不會。

解析回答:PHP 每個請求進來時都會建立 fpm-worker 程式

補充下,這裡php 請求進來就會 由PHP - FPM(php-fpm是php-cgi的程式管理器)建立一個PHP-CGI程式來準備響應使用者的請求。具體過程如圖,大家也可以繼續往下看詳細解析。

【2020年面試題-php與golang】1. 看你簡歷裡也有用過 Go,Go 和 PHP 在執行的時候有什麼區別和優勢?

解析回答:而go不會

golang 是先編譯,後執行。 具體可以往下看詳細解析。

php 執行原理

PHP 執行模式與執行原理

目前常見的4種PHP執行模式

  1. CGI通用閘道器介面模式
  2. FAST-CGI模式
  3. CLI命令列模式
  4. 模組模式

CGI通用閘道器介面模式

每有一個使用者請求,都會先要建立cgi的子程式,然後處理請求,處理完後結束這個子程式

cgi是一種為了保證web server傳遞過來的資料是標準格式的通用閘道器介面協議

比較老,比較原始,大多已經不用了

FAST-CGI模式

是cgi的升級版本,FastCGI 像是一個常駐 (long-live) 型的 CGI,它可以一直執行著,只要啟用後,不會每次都要花費時間去fork 一次,也是一種協議

FastCGI的工作原理是:

  (1)、Web Server啟動時載入FastCGI程式管理器【PHP的FastCGI程式管理器是PHP-FPM(php-FastCGI Process Manager)】(IIS ISAPI或Apache Module);

  (2)、FastCGI程式管理器自身初始化,啟動多個CGI直譯器程式 (在工作管理員中可見多個php-cgi.exe)並等待來自Web Server的連線。

  (3)、當客戶端請求到達Web Server時,FastCGI程式管理器選擇並連線到一個CGI直譯器。Web server將CGI環境變數和標準輸入傳送到FastCGI子程式php-cgi。

  (4)、FastCGI子程式完成處理後將標準輸出和錯誤資訊從同一連線返回Web Server。當FastCGI子程式關閉連線時,請求便告處理完成。FastCGI子程式接著等待並處理來自FastCGI程式管理器(執行在 WebServer中)的下一個連線。在正常的CGI模式中,php-cgi.exe在此便退出了。

  在CGI模式中,可以想象 CGI通常有多慢。每一個Web請求PHP都必須重新解析php.ini、重新載入全部dll擴充套件並重初始化全部資料結構。使用FastCGI,所有這些都只在程式啟動時發生一次。一個額外的好處是,持續資料庫連線(Persistent database connection)可以工作。

CLI命令列模式

一般使用呼叫指令碼、檢視php資訊時會使用到該模式

php -r”phpinfo();” |less 分頁顯示

模組模式

  1. Apache + mod_php
  2. lighttp + spawn-fcgi
  3. nginx + PHP-FPM

執行原理

PHP-CGI:fast-cgi是一種協議,而php-cgi是實現了這種協議的程式。不過這種實現比較爛。它是單程式的,一個程式處理一個請求,處理結束後程式就銷燬

PHP - FPM:是對php-cgi的改進版,它直接管理多個php-cgi程式/執行緒。也就是說,php-fpm是php-cgi的程式管理器因此它也算是fastcgi協議的實現
php的執行原理,就是在伺服器啟動時,自動載入PHP-FPM程式管理器,從而管理多個PHP-CGI程式來準備響應使用者的請求,如下圖所示:

【2020年面試題-php與golang】1. 看你簡歷裡也有用過 Go,Go 和 PHP 在執行的時候有什麼區別和優勢?

【2020年面試題-php與golang】1. 看你簡歷裡也有用過 Go,Go 和 PHP 在執行的時候有什麼區別和優勢?

由於php-cgi是隨伺服器啟動載入的,所以初始化變數只會發生一次

執行模式和執行原理的區別

多個執行模式相當於超市的不同入口,執行原理就是進入超市後的固定的行走路線,通過不同的執行模式進入到底層(進入超市)




golang 執行原理

golang 是先編譯為靜態二進位制可執行檔案,再去執行。

看看 go run 與 go build 的區別

o的執行原理以及Go的命令

go run 的執行過程

2020年面試題-php與golang

  1. 建立了兩個臨時資料夾 b001 和 exe
  2. 先執行了 compile 命令,然後 link,生成了歸檔檔案.a 和 最終可執行檔案
  3. 最終的可執行檔案放在 exe 資料夾裡面。
  4. 命令的最後一步就是執行了可執行檔案。

舉個例子,生成的臨時檔案可以用go run -work看到,比如當前生成的臨時資料夾是如下的路徑:

localhost:hello ruby$ go run -work mytest.go 
WORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496
HelloWorld
你好,Go!!!
localhost:hello ruby$ 

我們進入:/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496目錄,可以看到如下目錄結構:

2020年面試題-php與golang

可以看到,最終go run命令是生成了2個檔案,一個是歸檔檔案,一個是可執行檔案。

go run 命令在第二次執行的時候,如果發現匯入的程式碼包沒有發生變化,那麼 go run 不會再次編譯這個匯入的程式碼包。直接靜態連結進來。

go build 的執行過程

go build 用於編譯我們指定的原始碼檔案或程式碼包以及它們的依賴包。但是注意如果用來編譯非命令原始碼檔案,即庫原始碼檔案,go build 執行完是不會產生任何結果的。這種情況下,go build 命令只是檢查庫原始碼檔案的有效性,只會做檢查性的編譯,而不會輸出任何結果檔案。

go build 編譯命令原始碼檔案,則會在該命令的執行目錄中生成一個可執行檔案,上面的例子也印證了這個過程。

go build 後面不追加目錄路徑的話,它就把當前目錄作為程式碼包並進行編譯。go build 命令後面如果跟了程式碼包匯入路徑作為引數,那麼該程式碼包及其依賴都會被編譯。

go build 命令究竟做了些什麼呢?我們可以執行-n這個命令來檢視。 這裡略過列印輸出。

執行過程和 go run 大體相同,唯一不同的就是在最後一步,go run 是執行了可執行檔案,但是 go build 命令,只是把庫原始碼檔案編譯了一遍,然後把可執行檔案移動到了當前目錄的資料夾中。

總結一下如下圖:

2020年面試題-php與golang

本作品採用《CC 協議》,轉載必須註明作者和本文連結

上海PHP自學中心-免費程式設計視訊教學|
7Dn78VKKcW.jpg!large
S3d25uqwht.png!large

相關文章