golangcpp混合,golang pprof heap

本文目錄一覽:

編程都有哪些語言?

編程常用語言有:1、PHP語言,是一種通用開源腳本語言;2、C語言,一門面向過程的、抽象化的通用程序設計語言;3、JAVA語言,一種可以撰寫跨平台應用軟體的面向對象的程序設計語言;4、Go語言,是開源編程語言;5、Python,一種跨平台計算機程序設計語言等。 C語言是一門面向過程的、抽象化的通用程序設計語言,廣泛應用於底層開發。 C語言能以簡易的方式編譯、處理低級存儲器。 C語言是僅產生少量的機器語言以及不需要任何運行環境支持便能運行的高效率程序設計語言

一、Java最流行

與一年前一樣,Java仍然是最流行的編程語言。據TIOBE的數據顯示,幾十年來,Java比其他語言更常名列榜首。許多知名公司使用Java來開發軟體和應用程序,所以如果你碰巧使用Java,絕對不必為找工作而苦惱。Java受歡迎的主要原因是它擁有可移植性、可擴展性和龐大的用戶社區。

二、經典的C語言

作為最古老的編程語言之一,C依然高居榜首,這歸功於其可移植性以及微軟、Oracle和蘋果等科技巨頭採用它。它與幾乎所有系統兼容,很適合操作系統和嵌入式系統。

由於運行時環境相對小巧,因此C是保持這種系統精簡的完美選擇。強烈建議初學者學C,它實際上是編程語言的通用語言,已催生出了同樣很受歡迎的衍生語言,比如C++和C#。

三、C ++繼續佔主導地位

這種面向對象編程語言在20世紀80年代開發而成,現在仍應用於從桌面Web應用程序到伺服器基礎設施的眾多系統。由於靈活性、高性能以及可用於多種環境,C ++依然很吃香。以C++為業的工作通常需要開發面向性能密集型任務的桌面應用程序。掌握C++可以更深入地了解編程語言,幫助獲得低級內存處理方面的技能。

四、Python:不斷上升

過去15年來,Python的受歡迎程度穩步上升。過去這幾年,它一直能夠躋身TIOBE指數前5名的位置。作為如今人工智慧、機器學習、大數據和機器人等一些最有前途的技術背後的主要語言,Python近年來積累了龐大的粉絲群。你會驚訝地發現學習Python很容易,這就是為什麼許多經驗豐富的開發人員選擇Python作為第二或第三語言的原因。

五、C#:遊戲開發人員的寵兒

C#是一種現代的面向對象編程語言,由微軟開發,與當時商業軟體開發人員廣泛使用的Java相抗衡。它專為在微軟平台上開發應用程序而設計,需要Windows上的.NET框架才能工作。與前一年一樣,C#保持穩定的位置,名次沒有重大變化。可以使用C#開發幾乎所有應用程序,但它尤其擅長於Windows桌面應用程序和遊戲開發。

六、Visual Basic .NET

Visual Basic .NET與去年一樣,在指數中繼續保持第六位。它是微軟的OOP語言之一,結合了基於.NET框架的類和運行時環境的強大功能。它自VB6衍生而來,擅長開發GUI應用程序,為程序員簡化了任務,並提高生產力。對於程序員來說,除了Web服務和Web開發外,還為針對Windows平台開發桌面應用程序提供了一種快速簡單的方法。

七、用於Web開發的PHP

據TIOBE顯示,PHP在TIOBE最受歡迎的編程語言排行榜中位居第七,取代JavaScript成為更受歡迎的腳本語言。 PHP主要用在伺服器端上用於Web開發,約佔網站總數的80%。

Facebook最初使用的就是PHP,PHP在WordPress內容管理系統中扮演的角色讓它很受歡迎。PHP提供了幾個框架,比如Laravel和Drupal,幫助開發人員更快地構建應用程序,擁有更高的可擴展性和可靠性。因此,如果你在找Web開發方面的職位,PHP是不錯的選擇。

八、JavaScript必不可少

今年JavaScript的使用量有所下降,名次比去年有所下滑。但是現在所有軟體開發人員都以某種方式使用JavaScript。與HTML和CSS一起使用,JavaScript對於前端Web開發來說必不可少,以便創建互動式網頁,並向用戶動態顯示內容。

超過90%的網站使用這種語言,它也是初學者開始上手的最友好的編程語言之一。所以,如果你掌握JavaScript,根本不缺機會。然而,你需要學習其他支持性的語言和框架,才能成為主攻桌面和移動應用程序或遊戲開發的專業的前端開發人員。

九、SQL

SQL奪得第九名,實現了顯著的增長,畢竟去年它未能躋身於TIOBE指數20大編程語言。儘管存在其他資料庫技術,但用於管理資料庫的這種標準查詢語言在過去四十年一直處於主導地位。

原因在於它具有簡單性、可靠性、無處不在,以及對保持這種開源語言活力大有幫助的活躍社區。與其他語言相比,初學者通常更容易學習SQL;就職業發展而言,像數據分析員這類高薪職位要求SQL非懂不可。

十、GO編程語言

Go是谷歌公司推出的一款相對較新的語言,對於web伺服器開發、網路開發以及命令行程序開發來說,它是又一個比較優秀的選擇

go面試題整理(附帶部分自己的解答)

原文:【 】

如果有解答的不對的,麻煩各位在評論寫出來~

go的調度原理是基於GMP模型,G代表一個goroutine,不限制數量;M=machine,代表一個線程,最大1萬,所有G任務還是在M上執行;P=processor代表一個處理器,每一個允許的M都會綁定一個G,默認與邏輯CPU數量相等(通過runtime.GOMAXPROCS(runtime.NumCPU())設置)。

go調用過程:

可以能,也可以不能。

因為go存在不能使用==判斷類型:map、slice,如果struct包含這些類型的欄位,則不能比較。

這兩種類型也不能作為map的key。

類似棧操作,後進先出。

因為go的return是一個非原子性操作,比如語句 return i ,實際上分兩步進行,即將i值存入棧中作為返回值,然後執行跳轉,而defer的執行時機正是跳轉前,所以說defer執行時還是有機會操作返回值的。

select的case的表達式必須是一個channel類型,所有case都會被求值,求值順序自上而下,從左至右。如果多個case可以完成,則會隨機執行一個case,如果有default分支,則執行default分支語句。如果連default都沒有,則select語句會一直阻塞,直到至少有一個IO操作可以進行。

break關鍵字可跳出select的執行。

goroutine管理、信息傳遞。context的意思是上下文,在線程、協程中都有這個概念,它指的是程序單元的一個運行狀態、現場、快照,包含。context在多個goroutine中是並發安全的。

應用場景:

例子參考:

waitgroup

channel

len:切片的長度,訪問時間複雜度為O(1),go的slice底層是對數組的引用。

cap:切片的容量,擴容是以這個值為標準。默認擴容是2倍,當達到1024的長度後,按1.25倍。

擴容:每次擴容slice底層都將先分配新的容量的內存空間,再將老的數組拷貝到新的內存空間,因為這個操作不是並發安全的。所以並發進行append操作,讀到內存中的老數組可能為同一個,最終導致append的數據丟失。

共享:slice的底層是對數組的引用,因此如果兩個切片引用了同一個數組片段,就會形成共享底層數組。當sliec發生內存的重新分配(如擴容)時,會對共享進行隔斷。詳細見下面例子:

make([]Type,len,cap)

map的底層是hash table(hmap類型),對key值進行了hash,並將結果的低八位用於確定key/value存在於哪個bucket(bmap類型)。再將高八位與bucket的tophash進行依次比較,確定是否存在。出現hash衝撞時,會通過bucket的overflow指向另一個bucket,形成一個單向鏈表。每個bucket存儲8個鍵值對。

如果要實現map的順序讀取,需要使用一個slice來存儲map的key並按照順序進行排序。

利用map,如果要求並發安全,就用sync.map

要注意下set中的delete函數需要使用 delete(map) 來實現,但是這個並不會釋放內存,除非value也是一個子map。當進行多次delete後,可以使用make來重建map。

使用sync.Map來管理topic,用channel來做隊列。

參考:

多路歸併法:

pre class=”vditor-reset” placeholder=”” contenteditable=”true” spellcheck=”false”p data-block=”0″(1)假設有K路a href=””數據流/a,流內部是有序的,且流間同為升序或降序;

/pp data-block=”0″(2)首先讀取每個流的第一個數,如果已經EOF,pass;

/pp data-block=”0″(3)將有效的k(k可能小於K)個數比較,選出最小的那路mink,輸出,讀取mink的下一個;

/pp data-block=”0″(4)直到所有K路都EOF。

/p/pre

假設文件又1個G,內存只有256M,無法將1個G的文件全部讀到內存進行排序。

第一步:

可以分為10段讀取,每段讀取100M的數據並排序好寫入硬碟。

假設寫入後的文件為A,B,C…10

第二步:

將A,B,C…10的第一個字元拿出來,對這10個字元進行排序,並將結果寫入硬碟,同時記錄被寫入的字元的文件指針P。

第三步:

將剛剛排序好的9個字元再加上從指針P讀取到的P+1位數據進行排序,並寫入硬碟。

重複二、三步驟。

go文件讀寫參考:

保證排序前兩個相等的數其在序列的前後位置順序和排序後它們兩個的前後位置順序相同的排序叫穩定排序。

快速排序、希爾排序、堆排序、直接選擇排序不是穩定的排序演算法。

基數排序、冒泡排序、直接插入排序、折半插入排序、歸併排序是穩定的排序演算法。

參考:

head只請求頁面的首部。多用來判斷網頁是否被修改和超鏈接的有效性。

get請求頁面信息,並返回實例的主體。

參考:

401:未授權的訪問。

403: 拒絕訪問。

普通的http連接是客戶端連接上服務端,然後結束請求後,由客戶端或者服務端進行http連接的關閉。下次再發送請求的時候,客戶端再發起一個連接,傳送數據,關閉連接。這麼個流程反覆。但是一旦客戶端發送connection:keep-alive頭給服務端,且服務端也接受這個keep-alive的話,兩邊對上暗號,這個連接就可以復用了,一個http處理完之後,另外一個http數據直接從這個連接走了。減少新建和斷開TCP連接的消耗。這個可以在Nginx設置,

這個keepalive_timout時間值意味著:一個http產生的tcp連接在傳送完最後一個響應後,還需要hold住keepalive_timeout秒後,才開始關閉這個連接。

特別注意TCP層的keep alive和http不是一個意思。TCP的是指:tcp連接建立後,如果客戶端很長一段時間不發送消息,當連接很久沒有收到報文,tcp會主動發送一個為空的報文(偵測包)給對方,如果對方收到了並且回復了,證明對方還在。如果對方沒有報文返回,重試多次之後則確認連接丟失,斷開連接。

tcp的keep alive可通過

net.ipv4.tcp_keepalive_intvl = 75 // 當探測沒有確認時,重新發送探測的頻度。預設是75秒。

net.ipv4.tcp_keepalive_probes = 9 //在認定連接失效之前,發送多少個TCP的keepalive探測包。預設值是9。這個值乘以tcp_keepalive_intvl之後決定了,一個連接發送了keepalive之後可以有多少時間沒有回應

net.ipv4.tcp_keepalive_time = 7200 //當keepalive起用的時候,TCP發送keepalive消息的頻度。預設是2小時。一般設置為30分鐘1800

修改:

可以

tcp是面向連接的,upd是無連接狀態的。

udp相比tcp沒有建立連接的過程,所以更快,同時也更安全,不容易被攻擊。upd沒有阻塞控制,因此出現網路阻塞不會使源主機的發送效率降低。upd支持一對多,多對多等,tcp是點對點傳輸。tcp首部開銷20位元組,udp8位元組。

udp使用場景:視頻通話、im聊天等。

time-wait表示客戶端等待服務端返回關閉信息的狀態,closed_wait表示服務端得知客戶端想要關閉連接,進入半關閉狀態並返回一段TCP報文。

time-wait作用:

解決辦法:

close_wait:

被動關閉,通常是由於客戶端忘記關閉tcp連接導致。

根據業務來啊~

重要指標是cardinality(不重複數量),這個數量/總行數如果過小(趨近於0)代表索引基本沒意義,比如sex性別這種。

另外查詢不要使用select *,根據select的條件+where條件做組合索引,盡量實現覆蓋索引,避免回表。

殭屍進程:

即子進程先於父進程退出後,子進程的PCB需要其父進程釋放,但是父進程並沒有釋放子進程的PCB,這樣的子進程就稱為殭屍進程,殭屍進程實際上是一個已經死掉的進程。

孤兒進程:

一個父進程退出,而它的一個或多個子進程還在運行,那麼那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,並由init進程對它們完成狀態收集工作。

子進程死亡需要父進程來處理,那麼意味著正常的進程應該是子進程先於父進程死亡。當父進程先於子進程死亡時,子進程死亡時沒父進程處理,這個死亡的子進程就是孤兒進程。

但孤兒進程與殭屍進程不同的是,由於父進程已經死亡,系統會幫助父進程回收處理孤兒進程。所以孤兒進程實際上是不佔用資源的,因為它終究是被系統回收了。不會像殭屍進程那樣佔用ID,損害運行系統。

原文鏈接:

產生死鎖的四個必要條件:

(1) 互斥條件:一個資源每次只能被一個進程使用。

(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。

(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關係。

避免方法:

埠佔用:lsof -i:埠號 或者 nestat

cpu、內存佔用:top

發送信號:kill -l 列出所有信號,然後用 kill [信號變化] [進程號]來執行。如kill -9 453。強制殺死453進程

git log:查看提交記錄

git diff :查看變更記錄

git merge:目標分支改變,而源分支保持原樣。優點:保留提交歷史,保留分支結構。但會有大量的merge記錄

git rebase:將修改拼接到最新,複雜的記錄變得優雅,單個操作變得(revert)很簡單;缺點:

git revert:反做指定版本,會新生成一個版本

git reset:重置到某個版本,中間版本全部丟失

etcd、Consul

pprof

節省空間(非葉子節點不存儲數據,相對b tree的優勢),減少I/O次數(節省的空間全部存指針地址,讓樹變的矮胖),範圍查找方便(相對hash的優勢)。

explain

其他的見:

runtime2.go 中關於 p 的定義: 其中 runnext 指針決定了下一個要運行的 g,根據英文的注釋大致意思是說:

所以當設置 runtime.GOMAXPROCS(1) 時,此時只有一個 P,創建的 g 依次加入 P, 當最後一個即 i==9 時,加入的最後 一個 g 將會繼承當前主 goroutinue 的剩餘時間片繼續執行,所以會先輸出 9, 之後再依次執行 P 隊列中其它的 g。

方法一:

方法二:

[圖片上傳失敗…(image-4ef445-1594976286098)]

方法1:to_days,返回給的日期從0開始算的天數。

方法2:data_add。向日期添加指定時間間隔

[圖片上傳失敗…(image-b67b10-1594976286098)]

剛畢業適合學習哪個編程比較好?

入門選擇哪門語言最好

推薦學習Java,Java相對於C語言來說更加的簡單,包含的內容更加豐富,而且Java的就業方向也較廣。

一 · 編程語言及其主要用途

常見的是 C Family (C系列語言),比如:C、Cpp(C++)、C Sharp(C#)、Java、Python、R、JavaScript、Objective-C、Swift、Go、Kotlin 等等。然後有很多腳本語言,Python 也在其內,比如:Ruby、Perl 等。

光說名字意義不大,所以舉幾個例子。

C 常用於單片機開發和一些接底層硬體的操作使用;

C++ 是 C 的超集,因為直接支持了面向對象所以更多用於遊戲、圖像開發方面;

C# 是微軟為了把 Java 人才引入 Windows 平台設計的語言,和 Java 語法幾乎一致,目前多用於伺服器後端開發和 Unity 3D 的遊戲開發,也有人會用這個做很多 windows 平台下的軟體插件甚至常說的軟體外掛(外掛其實嚴格說就是插件,但大陸地區已經有更深層的意義了,所以兩者並列舉例出來);

Java 是目前最流行的伺服器後端開發語言和 Android 開發語言,因為有大量框架和工具包的支持,Java 語言的運行速度已經不能阻擋 Java 成為伺服器開發的首選語言。至於是什麼伺服器後端開發,題主學了 JavaEE 自然便知,通俗舉例來說可以 yy 一下:我寫了這篇答案,答案存在哪裡呢?肯定是在知乎那邊!至於怎麼存、怎麼取,都是後端開發需要設計的問題了。Java 也曾一度是 Android 的首選語言(雖然目前 Kotlin 的影響很多人轉戰 Kotlin 去了),負責 Android 頂層的 APP 層開發。

Python 是目前機器學習最流行的語言,也可以做伺服器開發,有堪比 Java Spring 框架的 Django 作為支持。更多的人會使用 Python 作為機器學習、深度學習的首選語言,因為 Python 語法的簡潔和類似數學式表達的規範,當然還是因為包多,很多學者科學家都會使用 Python 做科學研究。

R 語言作用類似 Python,常用於工程方面。還有一門語言是 Matlab,其實稱之為語言是不恰當的,因為這是一個軟體,脫離了軟體就無法生存,遠不是編譯器那麼簡單的結構了。MatLab 彙集了太多的工具,便於科學從業人員快速分析數據,寫出優良的程序,這種程序語言通常也稱之為 Matlab;

JavaScript 是前端開發首選語言,在使用 HTML + CSS 模式繪製出頁面圖像後,通常都會使用 JS (JavaScript)來寫交互、動畫、請求、視圖內容更新這些操作,這門語言是函數式也是面向對象的語言,靈活度極高,但有了 C Family 任何一門語言的基礎就很容易學;

Objective-C 是蘋果(Apple.Inc)開發的一門為 mac 和 iPhone 設備開發程序的語言,和 C++ 類似,也是 C 的超集,也是面向對象。但由於其太過於面向對象了(基於消息的傳遞數據機制)導致很不 C Family,所以對 C 系列人員上手難度偏大,比較冷門。但後來 iPhone 的崛起,導致該語言又一度熱議起來;

Swift 是蘋果最新發明的一門函數式編程語言,和 OC(Objective-C)的目的一樣,為蘋果設備而生,但蘋果也提倡用該語言做工程方面的擴展,比如蘋果會在宣傳的時候拿它和 Python 對比。為了兼容 OC 的所有工具包,避免該語言的冷門,創造了 bridge 作為兩個語言直接的橋樑,解決了語言兼容問題;

Go 語言是 Google 開發的一門函數式語言,特點是能解決大規模的高並發問題,天然支持多線程使得該語言一出來就廣受關注。目前多用於機器學習和一些 Google 自己產品的開發以及後端伺服器開發;

Kotlin 是大家常用的 IDEA 開發工具的開發商 Jetbrains 發明的函數式語言,這門語言是基於 JVM 進行設計的,比較完美地兼容了 Java 語言,所以前後端開發都可以使用該語言替代 Java,不確切統計是可以用比 Java 少一半的代碼量完成同樣的功能並擁有同樣的運行效率。類似的 JVM 語言也有 Scale,但比較元老了,兼容力度不大所以也開始廣受詬病;

Ruby 和 Perl 這些是典型的腳本語言,Ruby 多用於各個語言的粘合劑,Perl 是 Linux 下最常用的腳本語言,文本處理能力極強。

二 · 如何自學

這個問題其實答案很多,就像問一個人「如何才能提高分數」一樣,是個「上帝問題」。我來簡單解釋一下什麼是「上帝問題」:一個問題條件不充分,導致問題答案變數太大甚至可以出現毫無任何限制的答案,這類答案往往無意義或者意義不大,稱之為「上帝問題」。

所以這個問題是沒有好的答案的。

於是我便假設題主問題是:「一個時間充足、智力正常、周圍電子設備允許、自律能力可以、、、等等的男生該如何自學達到學會某一門語言的目標?」

這樣的話我們探討起來可能會容易很多。

來個老套路吧,其實真的自律可以什麼套路都行,自律不行,說什麼都是廢話。以下不是捷徑,是遠方:

通過視頻入門(視頻擁有大量的聲音、圖像、文字以及講師不經意的犯錯引發的笑點),視頻和書不一樣,視頻是容納了很多錯誤的,這些錯誤都是編程中可能會犯的,比如講師少打了一個分號,變數名字寫錯了等等等等,這些在書本裡面是看不到的,視頻帶給你的信息量遠大於書本。

通過書本紮實思考,書本還是得看,必須得看,書是代表系統的、完備的,書總是一章一節地講,不會錯一個字地講,很多東西就得從書里找,視頻老師可能會講漏,但書漏了第二版本還可以修訂。至於怎麼選好書,三步篩選:是否有第二版(或者第三四五… 版本)、豆瓣評價、實地摸(怎麼說都不如自己去摸一摸,試試就知道適不適合自己了)

以一本書為主,其餘書為輔,不出數月即可見效。

然後練習項目,此時你已經有了一定的基礎了,而且在學習過程中肯定也是不斷地碼代碼練習小項目小題目。此時你需要更多的時間去做更大的項目,通常很多雜牌書後面都會附一兩個項目實戰,可以試試手。項目必須練,這會讓你成為和以前不同的兩個人。

學習java,就來北京尚學堂

區塊鏈技術想要快速入門,一般涉及哪些編程語言?

任何一門計算機語言,都能在特定某個領域的應用中,實現區塊鏈技術;

具體使用哪一門語言,完全看我們相應領域行業企業項目的技術要求,以及更關鍵的:跟已有信息系統的有效對接聯通。

區塊鏈具有自下而上生成記錄,生成兩方或多方合同類記錄,加入第三方確認機制,分布存儲,……等特點;

從而讓它相比集中式的存儲運算而言,變得更為可信。

常見的總統投票,就非常適合以區塊鏈技術重新架構;採用區塊鏈技術的投票系統,能夠避免哪一家技術公司、某一個關鍵技術人員,操縱選票統計結果的可能。

像我們的法院證據,也特別適合採用區塊鏈技術重新架構開發。

其實像當前我們各類互聯網時代的「版權系統」,它們中一些就是採用區塊鏈技術架構而來,只不過,目前我們的新聞出版局、專利局(或者更廣義地被稱作「專家評委」),都尚未接入這些由互聯網公司創新而來的版權平台。

我們耳熟能詳 的「法大大」(雖然名字不甚好聽、甚至乍一聽來有些讓人「摸不著頭腦」),它也其實正準備採用最新的區塊鏈技術重新架構;採用區塊鏈技術的合同平台,因為變得更加可信,也才能更便於互聯網時代人們簽訂各類商務合同。

還有像我們的「徵信系統」,也非常適合以區塊鏈技術加以改造。能夠讓它更有說服力,而不致於出現一家單位、乃至隨意某個關鍵技術人員,能隨意往其中添加「徵信污點數據」的情況。

還有像我們的P2P貸款,如果能夠以區塊鏈技術重新架構的話,也能夠變得更加可信,而不致於出現違約、捲款跑路這樣的失信情況。

說說這篇我為什麼從python轉向go

恩看了這篇我為什麼從python轉向go,

看來作者也是 KSO 輕辦公/企業快盤團隊的。作為快盤從無到有時期的工程師之一(總是被瀟洒哥說他們改我留下的 bug ),又恰好是

Python/Go 雙修(大霧其實我是 Rust 黨),其實一開始我是拒絕的,duang duang duang,那就隨手寫一點把。

一段段來吧,首先作者說 Python 是動態語言

python是一門動態語言,不是強類型系統。對於一個變數,我們有時候壓根不知道它是什麼類型,然後就可能出現int + string這樣的運行時錯誤。

在python裡面,可以允許同名函數的出現,後一個函數會覆蓋前一個函數,有一次我們系統一個很嚴重的錯誤就是因為這個導致的。

事實上,如果是靜態檢查,pylint 和 pyflakes 是可以做這件事的,雖然不能和 go

那種靜態編譯型語言比,但也足夠了。如果沒記錯的話,阿通當年是要求全組都在提交前做靜態檢查的。我認為這種問題更多的應該是人員素質上來避免,畢竟蔥頭

也說過,代碼自己寫的就要多回頭看看,看能不能重構,能不能做更好。不是說偷懶不行,但是從中得出 Python

動態特性太靈活,Python:怪我咯看

另外,函數作為第一對象,在 Python 中是 feature,Go 要寫個 mock,簡直虐得不要不要的。

其實這個一直是很多人吐槽python的地方,不過想想,python最開始是為了解決啥問題而被開發出來的看我們硬是要將他用到高性能伺服器開發上面,其實也是有點難為它。

如果沒記錯,無論是輕辦公還是快盤,是重 IO 不重 CPU,最大耗時是數據塊加密那塊,我在的時候是 Java 寫的。另外高性能伺服器選 Go 也是虐得不要不要的,各種小心翼翼避免 GC。大多數極端情況下,pypy 的性能足矣勝任了,我認為這不算充分條件。

python的GIL導致導致無法真正的多線程,大家可能會說我用多進程不就完了。但如果一些計算需要涉及到多進程交互,進程之間的通訊開銷也是不得不考慮的。

其實,Python 有宏可以繞開這個 GIL,但是呢架構設計得好其實可以避免的,到非同步那塊我會說。

無狀態的分散式處理使用多進程很方便,譬如處理http請求,我們就是在nginx後面掛載了200多個django server來處理http的,但這麼多個進程自然導致整體機器負載偏高。

但即使我們使用了多個django進程來處理http請求,對於一些超大量請求,python仍然處理不過來。所以我們使用openresty,將高頻次的http請求使用lua來實現。可這樣又導致使用兩種開發語言,而且一些邏輯還得寫兩份不同的代碼。

如果推測沒錯,你們現在還在用五年前寫的 Gateway看那個基於 django route

的流量分發層看四年前我離開的時候已經小範圍的使用 Flask+Gevent Demo 測試過了,無論是性能還是負載都比同步模型的 django

有優勢。如果還是 django

這套的話,我只能說比較遺憾,畢竟當年金山新員工大賽頭牌就是我和幾個小夥伴寫的實時同步在線文檔編輯系統,用的就是這套技術。

因此這是個工程問題,並非語言問題。 Python 提供給了你了這麼多工具,硬要選一個傳統的,Old fashion 的,Python:怪我咯看

django的網路是同步阻塞的,也就是說,如果我們需要訪問外部的一個服務,在等待結果返回這段時間,django不能處理任何其他的邏輯(當然,多線程的除外)。如果訪問外部服務需要很長時間,那就意味著我們的整個服務幾乎在很長一段時間完全不可用。

為了解決這個問題,我們只能不斷的多開django進程,同時需要保證所有服務都能快速的處理響應,但想想這其實是一件很不靠譜的事情。

同步模型並非不行,因為 overhead 足夠低,很多業務場景下用同步模型反而會取得更好的效果,比如豆瓣。同步模型最大的問題是對於 IO 密集型業務等待時間足夠長,這時候需要的不是換語言 ,而是提醒你是不是架構要改一下了。

雖然tornado是非同步的,但是python的mysql庫都不支持非同步,這也就意味著如果我們在tornado裡面訪問資料庫,我們仍然可能面臨因為資料庫問題造成的整個服務不可用。

tornado 是有這個問題,但是 gevent 已經解決了。我在 node.js 的某問題下曾經回答過,對於 node

而言,能選擇的非同步模型只有一個,而 Python 就是太多選擇了。另外 pypy+tornado+redis

可以隨意虐各種長連接的場景,比如我給我廠寫過的一個 push service。

其實非同步模型最大的問題在於代碼邏輯的割裂,因為是事件觸發的,所以我們都是通過callback進行相關處理,於是代碼裡面就經常出現干一件事情,傳一個callback,然後callback裡面又傳callback的情況,這樣的結果就是整個代碼邏輯非常混亂。

這個還真不是,如果說沒有 ES6 的 JavaScript,可能真有 Callback hell,但這是 Python 啊!Python

早就實現了左值綁定唉,yield 那姿勢比某些天天吹的語言不知道高到哪裡去了,當然我說的是完整版的 Python3 yield。即便是不完整的

Python 2 yield 用於非同步表達式求值也是完全足夠的,tornado 的 gen.coroutine 啊。

同步形態寫非同步,在 Python 實力強的公司裡面早普及了,這是個工程問題,並非語言問題。當然把這種事怪在 Python 身上,Python:怪我咯看

python沒有原生的協程支持,雖然可以通過gevent,greenlet這種的上patch方式來支持協程,但畢竟更改了python源碼。另外,python的yield也可以進行簡單的協程模擬,但畢竟不能跨堆棧,局限性很大,不知道3.x的版本有沒有改進。

無論是 Gevent 還是 Greenlet 均沒修改 Python 源碼,事實上這貨已經成為了 Py2 coroutine 的標準,加上豆瓣開源出來的greenify,基本上所有的庫都可以平滑的非同步化,包括 MySQL 等 C 一級的 lib。自從用上這套技術後,豆瓣的 Python dev 各種爽得不要不要的。

當我第一次使用python開發項目,我是沒成功安裝上項目需要的包的,光安裝成功mysql庫就弄了很久。後來,是一位同事將他整個python目錄打包給我用,我才能正常的將項目跑起來。話說,現在有了docker,是多麼讓人幸福的一件事情。

而部署python服務的時候,我們需要在伺服器上面安裝一堆的包,光是這一點就讓人很麻煩,雖然可以通過puppet,salt這些自動化工具解決部署問題,但相比而言,靜態編譯語言只用扔一個二進位文件,可就方便太多了。

恰好我又是在開發基於 docker 的平台, docker 還真不是用來做部署這事的。首先, Python 是有 virtualenv

這個工具的,事實上對比包管理和包隔離,Python 比 Go 高得不知道哪裡去了。Python 跟 Git 談笑風生的時候, Go 的 dev

們還得考慮我怎樣才能使得 import 的包穩定在一個版本上(當然現在有很多第三方方案)。Virtualenv + Pip 完全可以實現

Python 部署自動化,所以這個問題我認為是,工具鏈選取問題。畢竟是個十幾年的老妖怪了,Python

啥情況沒見過啊,各種打包工具任君選擇,強行說 Python 部署不方便,Python:怪我咯看

python非常靈活簡單,寫c幾十行代碼才能搞定的功能,python一行代碼沒準就能解決。但是太簡單,反而導致很多

同學無法對代碼進行深層次的思考,對整個架構進行細緻的考量。來了一個需求,啪啪啪,鍵盤敲完開速實現,結果就是代碼越來越混亂,最終導致了整個項目代碼

失控。

曾經知乎有個帖子問 Python 會不會降低程序員編程能力,

我只能說這真的很人有關。你不去思考深層次的東西怪語言不行是沒道理的,那好,Go 裡面 goroutine 是怎麼實現的,一個帶 socket 的

goroutine

最小能做到多少內存,思考過看任何語言都有自己的優勢和劣勢,都需要執行者自己去判斷,一味的覺得簡單就不會深入思考這是有問題的。另外,代碼混亂我認為

還是工程上的控制力不夠,豆瓣有超過10W行的 Python 實現,雖然不說很完美,大體上做到了不會混亂這麼個目標。

還有,C 寫幾十行搞定的 Python 一行解決這絕對是重大 feature,生產力啊,人員配置啊,招人培養的成本啊,從工程上來說,Python 在這一塊完全是加分項,不是每個項目都要求極致的並發,極致的效率,做工程很多時候都是要取捨的。

雖然java和php都是最好的編程語言(大家都這麼爭的),但我更傾向一門更簡單的語言。而openresty,雖然性

能強悍,但lua仍然是動態語言,也會碰到前面說的動態語言一些問題。最後,前金山許式偉用的go,前快盤架構師蔥頭也用的go,所以我們很自然地選擇了

go。

Openresty 用 lua 如果按照動態語言的角度去看,還真算不上,頂多是個簡單點的 C。許式偉走的時候大多數都是

CPP,蔥頭目前我還不知道他創業用的是什麼寫的,不過他肯定沒語言傾向。當年無論是 leo 還是 ufa,一個用 Python 一個用

Java, 他都是從工程實際來選擇使用什麼樣的語言。

error,好吧,如果有語言潔癖的同學可能真的受不了go的語法,尤其是約定的最後一個返回值是error。

這其實是 Go style,無論是 go fmt 還是 error style,Go 其實是想抹平不同工程師之間的風格問題。不再為了一個縮進和大括弧位置什麼的浪費時間。這種方法並不是不好,只是我個人覺得沒 rust 那種返回值處理友善。

GC,java的GC發展20年了,go才這麼點時間,gc鐵定不完善。所以我們仍然不能隨心所欲的寫代碼,不然在大請求量下面gc可能會卡頓整個服務。所以有時候,該用對象池,內存池的一定要用,雖然代碼丑了點,但好歹性能上去了。

1.4 開始 go 就是 100% 精確 GC 了,另外說到卡頓啊,完全和你怎麼用對象有關,能內聯絕不傳引用大部分場景是完全足夠的,這樣 gc 的影響程度會最低。實在想用池……只能說為啥不選 Java。

天生的並行支持,因為goroutine以及channel,用go寫分散式應用,寫並發程序異常的容易。沒有了蛋疼的callback導致的代碼邏輯割裂,代碼邏輯都是順序的。

這是有代價的,goroutine 的內存消耗計算(當然1.3還是1.4開始得到了很大的改善,內存最小值限制已經沒了),channel

跨線程帶來的性能損耗(跨線程鎖),還有對 goroutine 的控制力幾乎為 0

等。總之這種嘛,算不上是殺手級特性,大家都有,是方便了一點,但也有自己的弊端。比如我們用 go 吧,經常就比較蛋疼 spawn 出去的

goroutine 怎麼優美的 shutdown,反而有時候把事情做複雜化了。

性能,go的性能可能趕不上c,c++以及openresty,但真的也挺強悍的。在我們的項目中,現在單機就部署了一個go的進程,就完全能夠勝任以前200個python進程乾的事情,而且CPU和MEM佔用更低。

我不嚴謹的實測大概 gevent+py2 能達到同樣邏輯 go 實現的 30%~40%,pypy+tornado 能達到

80%~90%,混合了一些計算和連接處理什麼的。主要還是看業務場景吧,純粹的 CPU bound 當然是 go 好,純粹的 IO bound

你就是用 C 也沒用啊。

運維部署,直接編譯成二進位,扔到伺服器上面就成,比python需要安裝一堆的環境那是簡單的太多了。當然,如果有cgo,我們也需要將對應的動態庫給扔過去。

我們現在根據 glibc 所處的 host 版本不同有2套編譯環境,看上去是部署簡單了,編譯起來坑死你。另外雖然說 disk 便宜,這幾行代碼就幾M了,集群同步部署耗時在某些情況下還真會出簍子。

開發效率,雖然go是靜態語言,但我個人感覺開發效率真的挺高,直覺上面跟python不相上下。對於我個人來說,最好的

例子就是我用go快速開發了非常多的開源組件,譬如ledisdb,go-mysql等,而這些最開始的版本都是在很短的時間裡面完成的。對於我們項目來

說,我們也是用go在一個月就重構完成了第一個版本,並發布。

原創文章,作者:TPEO,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/139509.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
TPEO的頭像TPEO
上一篇 2024-10-04 00:22
下一篇 2024-10-04 00:22

相關推薦

  • 使用Golang調用Python

    在現代軟體開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇…

    編程 2025-04-29
  • 使用Golang創建黑色背景圖片的方法

    本文將從多個方面介紹使用Golang創建黑色背景圖片的方法。 一、安裝必要的代碼庫和工具 在開始創建黑色背景圖片之前,我們需要先安裝必要的代碼庫和工具: go get -u git…

    編程 2025-04-29
  • 如何通過IDEA設置gradle的heap大小

    在IDEA中設置gradle的heap大小可以有效提高gradle編譯、運行等使用效率,本文將從以下幾個方面介紹如何通過IDEA設置gradle的heap大小。 一、設置gradl…

    編程 2025-04-28
  • Golang中使用strings.Split函數進行字元串分割的方法

    一、Split函數的基本用法 字元串是編程中常見的數據類型,它們可以在程序中被處理、存儲和傳輸。在Go語言中,字元串也是一個基本的數據類型,而strings包提供了一些操作字元串的…

    編程 2025-04-23
  • 深入下探golang http server

    Go語言已經成為了軟體開發領域的熱門語言,它的高性能、應用廣泛、安全性好,使得它成為了眾多開發者心目中的首選編程語言。在眾多應用場景中,golang http server的應用非…

    編程 2025-04-23
  • Golang環境變數全面解析

    Golang是一門非常流行的開發語言,擁有高效的CGO、簡單易懂的語法、高並發能力等優點,然而它也需要使用環境變數來配置一些參數。在本篇文章中,我們將從多個方面對Golang環境變…

    編程 2025-04-23
  • Compacted:一個高性能的Golang緩存庫

    一、簡介 Compacted是一個使用Golang編寫的緩存庫,旨在提供高性能的內存緩存功能。相對於其他常見的緩存庫,Compacted在內存使用和性能方面都做了一定的優化。 緩存…

    編程 2025-04-23
  • Golang nil解析

    一、什麼是nil Nil是Golang語言中的一個預定義標識符,表示一個零值對象,通常表示一個空指針。Nil被定義為指針類型、函數類型、介面類型、map類型、Slice類型、Cha…

    編程 2025-04-23
  • Golang中文社區介紹

    Go語言或者叫Golang是一個開源項目,目前是由Google開發維護的一種靜態類型、並發安全、編譯型的編程語言。Go語言的特點是結構清晰、並發能力強、具有垃圾回收機制並且支持跨平…

    編程 2025-04-23
  • 詳解golang walk控制項庫

    Golang提供的可視化庫有很多個,其中walk是一個比較好用且強大的庫。本文將從多個方面對walk進行詳細闡述,包括基本控制項、布局、菜單、圖標等方面的內容。 一、控制項基礎 Gol…

    編程 2025-04-22

發表回復

登錄後才能評論