golang現場,GOG比賽

本文目錄一覽:

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)]

golang培訓班在哪找

可以先在網上查詢自己城市的golang培訓機構的口碑。然後去現場了解老師工作經歷和具體項目,並諮詢具體的學習內容。

記一次go module的坑

事情是這樣的,因為小馬本次要寫一個go項目。但是因為一些許可權問題,一些依賴包在內網小馬獲取不到,於是只能求助大大。大大給的策略就是他先把所有的依賴包go mod,然後go mod vendor遷移到項目目錄vendor下進行本地依賴載入即可,也就是使用 go build -mod=vendor來編譯即可。一切似乎看起來還是那麼完美。然後正要起飛,直接翻車,現場如下。【這裡插播一條發現,就是使用golang IDE go build 和使用命令行go build 的區別在於前者不會生成.exe文件】

將大大go mod vendor完的包pull到本地,只要編譯就會發生如下錯誤(以下省略了一部分類似的報錯)。其實是 go.mod內的所有依賴包都報錯。

大大說他的本地編譯是正常的。不得不懷疑是不是因為大大本地gopath還有一份包依賴的原因,然而經查並不是這個問題。翻閱了網路上的大部分資料無果,網路上要麼是說是因為識別不到包,按照提示重新go mod vendor一下就可以了。小馬蠻試了一下,不出所料必然地報遠程報獲取不到呢,IDE的報錯定位其實是不準確的。再次檢查vendor/modules.txt文件,沒有問題,無果。 於是開始質疑golang IDE 的版本支持問題,無果。看了下go.mod文件中寫著go 1.14,也沒錯呢,小馬用的GO SDK正是1.14.4版本。敲出go env 查看環境配置,GO111MODULE=on,因為環境變數是auto,但是go到一定版本後默認是on,也沒問題,無果。那問題出在哪呢?由於沒有依賴包拉取許可權,只能再次求助大大,大大表示也很奇怪,一番折騰,於是問題得到解決。【這裡插播一條好玩的東西,就是GO111MODULE為什麼是GO111呢,因為其實1.11版本開始支持MODULE的】

結論是:因為大大go  mod的時候用的是go 1.13,而我編譯的時候用的 1.14,所以就報了這個奇怪的錯誤。you what?直接懵逼。但是為啥go.mod文件中寫的版本要求是1.14,而大大用1.13也編譯得好好的。

這是個大坑,掉進坑裡自己撲騰了一天!!希望大家謹慎入坑。

爬坑一小時出坑一秒鐘,每一次的爬坑都是充滿著十八般絕技。奇怪的姿勢又增加了。

go運行方式有哪幾種?

如果GO111MODULE是auto則根據項目目錄位置和是否含有go.mod文件來決定使用什麼模式。如果是GO111MODULE=off則使用gopath,如果是on則使用module模式。gopath模式下的src目錄下不能有go.mod文件,否則報錯。

一些go mod命令 記錄備用,國內的資料並不多(注意go mod 命令在 $GOPATH 里默認是執行不了的,因為 GO111MODULE 的默認值是 auto。默認在$GOPATH 里是不會執行, 如果一定要強制執行,就設置環境變數為 on。):

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-20 15:05
下一篇 2024-12-20 15:05

相關推薦

  • 使用Golang調用Python

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

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

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

    編程 2025-04-29
  • 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
  • Golang泛型詳解

    Golang泛型成為眾多開發人員關注的話題,因為它使得代碼更加通用、可重用、簡單、易於維護。那麼,什麼是泛型、為什麼它如此重要,如何使用它?本文將從多個方面為您詳細闡述Golang…

    編程 2025-04-20

發表回復

登錄後才能評論