go print函數(shù)“%+v”可以訪問私有變量(如果私有變量里有map,打印相當于讀,會有map并發(fā)讀寫問題)

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供邢臺縣網(wǎng)站建設、邢臺縣做網(wǎng)站、邢臺縣網(wǎng)站設計、邢臺縣網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、邢臺縣企業(yè)網(wǎng)站模板建站服務,10年邢臺縣做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
比如http ctx里,就會有所有連接的map,打印ctx會有并發(fā)讀寫問題。因此,需要使用context標準方法Value
reflect遍歷struct卻不可以
tree
main.go
user.go
今天給大家推薦是由Social Explorer團隊開源的gods框架,自稱"上帝",聽這個名字就很霸氣,正確的解釋是GoDS(Go Data Structures),是數(shù)據(jù)結(jié)構與算法相關的框架。
全能戰(zhàn)士,該框架覆蓋了數(shù)據(jù)結(jié)構與算法里,大部分容器、集合類的實現(xiàn), 比golang 的標準開發(fā)包提供更豐富的數(shù)據(jù)結(jié)構。
在Go中實現(xiàn)各種數(shù)據(jù)結(jié)構和算法。
吸取了其他算法庫數(shù)十年的知識和經(jīng)驗。
通過針對給定的一組問題使用最佳算法和數(shù)據(jù)結(jié)構來避免消耗內(nèi)存,例如, 在TreeMap的情況下,紅黑樹避免在內(nèi)存中保留冗余排序的鍵數(shù)組。
結(jié)構良好的庫,具有簡單的原子操作集,勝任復雜的數(shù)據(jù)操作。
保持庫向后兼容
可參考的例子非常多
可以方便集成到產(chǎn)品中.
沒有額外的導入.當實現(xiàn)算法的時候,我們通常要在時間效率與內(nèi)存消耗之間權衡,我們選擇在內(nèi)存首先的情況下,不斷優(yōu)化得到最好的時間效率;線程安全不是重點,應該在更高的應用層上處理。
囊括了列表,棧,圖,樹等基本數(shù)據(jù)結(jié)構 ,集合實現(xiàn)了HashSet, TreeSet, LinkedHashSet,列表實現(xiàn)ArrayList, SinglyLinkedList, DoublyLinkedList,對棧實現(xiàn)LinkedListStack, ArrayStack,圖實現(xiàn)了HashMap, TreeMap, HashBidiMap, TreeBidiMap, LinkedHashMap,樹實現(xiàn)了RedBlackTree, AVLTree, BTree,BinaryHeap,都經(jīng)過性能測試的考驗,值得信賴。
對于Golang開發(fā)而言,gods對底層數(shù)據(jù)結(jié)構做很好的封裝,Social Explorer團隊在數(shù)據(jù)處理領域,數(shù)據(jù)可視化領域有極具競爭力的產(chǎn)品,相信在數(shù)據(jù)處理領域有很深的積淀,才創(chuàng)造這么優(yōu)秀的框架,由于篇幅限制,相關圖片展示效果不好,感興趣的上官網(wǎng)去看看。
官網(wǎng):
GitHub
希望大家能從emirpasic/gods學到有價值的東西。
愿我們在Go 語言的學習之路上 從此結(jié)伴而行
mina與netty都是Trustin Lee的作品,所以在很多方面都十分相似,他們線程模型也是基本一致,采用了Reactors in threads模型,即Main Reactor + Sub Reactors的模式。由main reactor處理連接相關的任務:accept、connect等,當連接處理完畢并建立
算法程序題:
該公司筆試題就1個,要求在10分鐘內(nèi)作完。
題目如下:用1、2、2、3、4、5這六個數(shù)字,用java寫一個main函數(shù),打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"與"5"不能相連。
static int[] bits = new int[] { 1, 2, 3, 4, 5 };
/**
* @param args
*/
public static void main(String[] args) {
sort("", bits);
}
private static void sort(String prefix, int[] a) {
if (a.length == 1) {
System.out.println(prefix + a[0]);
}
for (int i = 0; i a.length; i++) {
sort(prefix + a[i], copy(a, i));
}
}
private static int[] copy(int[] a,int index){
int[] b = new int[a.length-1];
System.arraycopy(a, 0, b, 0, index);
System.arraycopy(a, index+1, b, index, a.length-index-1);
return b;
}
**********************************************************************
基本思路:
1 把問題歸結(jié)為圖結(jié)構的遍歷問題。實際上6個數(shù)字就是六個結(jié)點,把六個結(jié)點連接成無向連通圖,對于每一個結(jié)點求這個圖形的遍歷路徑,所有結(jié)點的遍歷路徑就是最后對這6個數(shù)字的排列組合結(jié)果集。
2 顯然這個結(jié)果集還未達到題目的要求。從以下幾個方面考慮:
1. 3,5不能相連:實際要求這個連通圖的結(jié)點3,5之間不能連通, 可在構造圖結(jié)構時就滿足改條件,然后再遍歷圖。
2. 不能有重復: 考慮到有兩個2,明顯會存在重復結(jié)果,可以把結(jié)果集放在TreeSet中過濾重復結(jié)果
3. 4不能在第三位: 仍舊在結(jié)果集中去除滿足此條件的結(jié)果。
采用二維數(shù)組定義圖結(jié)構,最后的代碼是:
import java.util.Iterator;
import java.util.TreeSet;
public class TestQuestion {
private String[] b = new String[]{"1", "2", "2", "3", "4", "5"};
private int n = b.length;
private boolean[] visited = new boolean[n];
private int[][] a = new int[n][n];
private String result = "";
private TreeSet set = new TreeSet();
public static void main(String[] args) {
new TestQuestion().start();
}
private void start() {
// Initial the map a[][]
for (int i = 0; i n; i++) {
for (int j = 0; j n; j++) {
if (i == j) {
a[i][j] = 0;
} else {
a[i][j] = 1;
}
}
}
// 3 and 5 can not be the neighbor.
a[3][5] = 0;
a[5][3] = 0;
// Begin to depth search.
for (int i = 0; i n; i++) {
this.depthFirstSearch(i);
}
// Print result treeset.
Iterator it = set.iterator();
while (it.hasNext()) {
String string = (String) it.next();
// "4" can not be the third position.
if (string.indexOf("4") != 2) {
System.out.println(string);
}
}
}
private void depthFirstSearch(int startIndex) {
visited[startIndex] = true;
result = result + b[startIndex];
if (result.length() == n) {
// Filt the duplicate value.
set.add(result);
}
for(int j = 0; j n; j++) {
if (a[startIndex][j] == 1 visited[j] == false) {
depthFirstSearch(j);
} else {
continue;
}
}
// restore the result value and visited value after listing a node.
result = result.substring(0, result.length() -1);
visited[startIndex] = false;
}
}
? 隨著 2022 年 3 月 15 日 go 1.18 正式發(fā)布,新版本除了對性能的提升之外,還引入了很多新功能,其中就有 go 期盼已久的功能泛型(Generics),同時還引入的多模塊工作區(qū)(Workspaces)和模糊測試(Fuzzing)。
? 關于泛型網(wǎng)上已經(jīng)有很多介紹的教程了,這里我介紹一個實用的功能,多模塊工作區(qū)的使用方法和教程。
? Go 多模塊工作區(qū)能夠使開發(fā)者能夠更容易地同時處理多個模塊的工作,如:
? 多模塊工作區(qū)
? 開發(fā)流程演示
? 總結(jié)
? 參考文獻
? go 使用的是多模塊工作區(qū),可以讓開發(fā)者更容易同時處理多個模塊的開發(fā)。在 Go 1.17 之前,只能使用 go.mod replace 指令來實現(xiàn),如果你正巧是同時進行多個模塊的開發(fā),使用它可能是很痛苦的。每次當你想要提交代碼的時候,都不得不刪除掉 go.mod 中的 replace 才能使模塊穩(wěn)定的發(fā)布版本。 ?在使用 go 1.18 多模塊工作區(qū)功能的時候,就使用這項工作變得簡單容易處理。下面我來介紹怎么使用這一功能。? Go 多模塊工作區(qū)文檔、代碼示例[5]
? 首先 我們需要 go 1.18 或更高版本 go 安裝[6]
? 通常情況下,建議不要提交 go.work 文件到 git 上,因為它主要用于本地代碼開發(fā)。
? 推薦在: $GOPATH 路徑下執(zhí)行,生成 go.work 文件
? go work init 初始化工作區(qū)文件,用于生成 go.work 工作區(qū)文件
? go work use 添加新的模塊到工作區(qū)
? go work edit 用于編輯 go.work 文件
? go work sync 將工作區(qū)的構建列表同步到工作區(qū)的模塊
? go env GOWORK
? 文件結(jié)構和 go.mod 文件結(jié)構類似,支持 Go 版本號、指定工作區(qū)和需要替換的倉庫 ?文件結(jié)構示例:
? 可以使用 go work use hello 添加模塊,也可以手動修改 go.work 工作區(qū)添加新的模塊 ?在工作區(qū)中添加了模塊路徑,編譯的時候會自動使用 use 中的本地代碼進行代碼編譯,和 replaces 功能類似。
? replaces 命令與 go.mod 指令相同,用于替換項目中依賴的倉庫地址 ?需要注意的是 replaces 和 use 不能同時指定相同的本地路徑
? 錯誤示例
? 在同時使用 go.work 和 go.mod replace 功能的的時候分別指定不同的代碼倉庫路徑, go.work 優(yōu)先級高于 go.mod 中定義
? 在代碼構建時候使用的是 go.work 指定的 example1 倉庫的代碼, go.work 優(yōu)先級別更高
? 在 Go 1.18 go run 和 go build 都會默認使用工作區(qū)功能 ? GOWORK 也可以指定配置 go.work 文件位置
? Go 全局變量 GOWORK 設置 off 則可以禁用工作區(qū)功能
? 演示如何使用多模塊工作區(qū)功能。在現(xiàn)在微服務盛行的年代,一個人會維護多個代碼倉庫,很多的時候是多個倉庫進行同時開發(fā)
? 假設我們現(xiàn)在進行 hello 倉庫開發(fā),實現(xiàn)的功能是,實現(xiàn)將輸入的字符串反轉(zhuǎn)并輸出,字符串反轉(zhuǎn)功能依賴于 github.com/link1st/example (下文統(tǒng)稱 example )公共倉庫實現(xiàn)
? 新建 hello 項目
? main.go 代碼
? 運行代碼 go run main.go -str "hello world" 或 go run github.com/link1st/link1st/workspaces/hello -str "hello world" 可以看到輸出了 hello world 反轉(zhuǎn)以后的字符串
? 到這里,最初的功能已經(jīng)完成,但是后續(xù)需求變動,不僅需要輸出反轉(zhuǎn)以后的字符串,還需要將字符串大寫
? 我們則需要去 example 倉庫中添加開發(fā) 將字符串大寫的功能
? vim example/stringutil/to_upper.go 代碼如下
? 由于代碼還在本地調(diào)試,未提交 git 倉庫中,這個時候就需要用到 Go 多模塊工作區(qū)的功能了。
? 進入項目根目錄,初始化我們現(xiàn)在正在開發(fā)的模塊
? 文件結(jié)構如下
? 回到 hello 項目, vim main.go 將字符串大寫的功能添加上。
? 運行代碼
? 到這里,演示的代碼已經(jīng)全部完成
? 使用 Go 多模塊工作區(qū)的功能,可以讓我們輕松在多個模塊之間切換工作,更能適應現(xiàn)代微服務架構開發(fā)。
[1] Go 1.18 新特性多模塊工作區(qū)教程:
[2] Go 1.18 is released!:
[3] Tutorial: Getting started with multi-module workspaces:
[4] go-1.18-features:
原文:【 】
如果有解答的不對的,麻煩各位在評論寫出來~
go的調(diào)度原理是基于GMP模型,G代表一個goroutine,不限制數(shù)量;M=machine,代表一個線程,最大1萬,所有G任務還是在M上執(zhí)行;P=processor代表一個處理器,每一個允許的M都會綁定一個G,默認與邏輯CPU數(shù)量相等(通過runtime.GOMAXPROCS(runtime.NumCPU())設置)。
go調(diào)用過程:
可以能,也可以不能。
因為go存在不能使用==判斷類型:map、slice,如果struct包含這些類型的字段,則不能比較。
這兩種類型也不能作為map的key。
類似棧操作,后進先出。
因為go的return是一個非原子性操作,比如語句 return i ,實際上分兩步進行,即將i值存入棧中作為返回值,然后執(zhí)行跳轉(zhuǎn),而defer的執(zhí)行時機正是跳轉(zhuǎn)前,所以說defer執(zhí)行時還是有機會操作返回值的。
select的case的表達式必須是一個channel類型,所有case都會被求值,求值順序自上而下,從左至右。如果多個case可以完成,則會隨機執(zhí)行一個case,如果有default分支,則執(zhí)行default分支語句。如果連default都沒有,則select語句會一直阻塞,直到至少有一個IO操作可以進行。
break關鍵字可跳出select的執(zhí)行。
goroutine管理、信息傳遞。context的意思是上下文,在線程、協(xié)程中都有這個概念,它指的是程序單元的一個運行狀態(tài)、現(xiàn)場、快照,包含。context在多個goroutine中是并發(fā)安全的。
應用場景:
例子參考:
waitgroup
channel
len:切片的長度,訪問時間復雜度為O(1),go的slice底層是對數(shù)組的引用。
cap:切片的容量,擴容是以這個值為標準。默認擴容是2倍,當達到1024的長度后,按1.25倍。
擴容:每次擴容slice底層都將先分配新的容量的內(nèi)存空間,再將老的數(shù)組拷貝到新的內(nèi)存空間,因為這個操作不是并發(fā)安全的。所以并發(fā)進行append操作,讀到內(nèi)存中的老數(shù)組可能為同一個,最終導致append的數(shù)據(jù)丟失。
共享:slice的底層是對數(shù)組的引用,因此如果兩個切片引用了同一個數(shù)組片段,就會形成共享底層數(shù)組。當sliec發(fā)生內(nèi)存的重新分配(如擴容)時,會對共享進行隔斷。詳細見下面例子:
make([]Type,len,cap)
map的底層是hash table(hmap類型),對key值進行了hash,并將結(jié)果的低八位用于確定key/value存在于哪個bucket(bmap類型)。再將高八位與bucket的tophash進行依次比較,確定是否存在。出現(xiàn)hash沖撞時,會通過bucket的overflow指向另一個bucket,形成一個單向鏈表。每個bucket存儲8個鍵值對。
如果要實現(xiàn)map的順序讀取,需要使用一個slice來存儲map的key并按照順序進行排序。
利用map,如果要求并發(fā)安全,就用sync.map
要注意下set中的delete函數(shù)需要使用 delete(map) 來實現(xiàn),但是這個并不會釋放內(nèi)存,除非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=""數(shù)據(jù)流/a,流內(nèi)部是有序的,且流間同為升序或降序;
/pp data-block="0"(2)首先讀取每個流的第一個數(shù),如果已經(jīng)EOF,pass;
/pp data-block="0"(3)將有效的k(k可能小于K)個數(shù)比較,選出最小的那路mink,輸出,讀取mink的下一個;
/pp data-block="0"(4)直到所有K路都EOF。
/p/pre
假設文件又1個G,內(nèi)存只有256M,無法將1個G的文件全部讀到內(nèi)存進行排序。
第一步:
可以分為10段讀取,每段讀取100M的數(shù)據(jù)并排序好寫入硬盤。
假設寫入后的文件為A,B,C...10
第二步:
將A,B,C...10的第一個字符拿出來,對這10個字符進行排序,并將結(jié)果寫入硬盤,同時記錄被寫入的字符的文件指針P。
第三步:
將剛剛排序好的9個字符再加上從指針P讀取到的P+1位數(shù)據(jù)進行排序,并寫入硬盤。
重復二、三步驟。
go文件讀寫參考:
保證排序前兩個相等的數(shù)其在序列的前后位置順序和排序后它們兩個的前后位置順序相同的排序叫穩(wěn)定排序。
快速排序、希爾排序、堆排序、直接選擇排序不是穩(wěn)定的排序算法。
基數(shù)排序、冒泡排序、直接插入排序、折半插入排序、歸并排序是穩(wěn)定的排序算法。
參考:
head只請求頁面的首部。多用來判斷網(wǎng)頁是否被修改和超鏈接的有效性。
get請求頁面信息,并返回實例的主體。
參考:
401:未授權的訪問。
403: 拒絕訪問。
普通的http連接是客戶端連接上服務端,然后結(jié)束請求后,由客戶端或者服務端進行http連接的關閉。下次再發(fā)送請求的時候,客戶端再發(fā)起一個連接,傳送數(shù)據(jù),關閉連接。這么個流程反復。但是一旦客戶端發(fā)送connection:keep-alive頭給服務端,且服務端也接受這個keep-alive的話,兩邊對上暗號,這個連接就可以復用了,一個http處理完之后,另外一個http數(shù)據(jù)直接從這個連接走了。減少新建和斷開TCP連接的消耗。這個可以在Nginx設置,
這個keepalive_timout時間值意味著:一個http產(chǎn)生的tcp連接在傳送完最后一個響應后,還需要hold住keepalive_timeout秒后,才開始關閉這個連接。
特別注意TCP層的keep alive和http不是一個意思。TCP的是指:tcp連接建立后,如果客戶端很長一段時間不發(fā)送消息,當連接很久沒有收到報文,tcp會主動發(fā)送一個為空的報文(偵測包)給對方,如果對方收到了并且回復了,證明對方還在。如果對方?jīng)]有報文返回,重試多次之后則確認連接丟失,斷開連接。
tcp的keep alive可通過
net.ipv4.tcp_keepalive_intvl = 75 // 當探測沒有確認時,重新發(fā)送探測的頻度。缺省是75秒。
net.ipv4.tcp_keepalive_probes = 9 //在認定連接失效之前,發(fā)送多少個TCP的keepalive探測包。缺省值是9。這個值乘以tcp_keepalive_intvl之后決定了,一個連接發(fā)送了keepalive之后可以有多少時間沒有回應
net.ipv4.tcp_keepalive_time = 7200 //當keepalive起用的時候,TCP發(fā)送keepalive消息的頻度。缺省是2小時。一般設置為30分鐘1800
修改:
可以
tcp是面向連接的,upd是無連接狀態(tài)的。
udp相比tcp沒有建立連接的過程,所以更快,同時也更安全,不容易被攻擊。upd沒有阻塞控制,因此出現(xiàn)網(wǎng)絡阻塞不會使源主機的發(fā)送效率降低。upd支持一對多,多對多等,tcp是點對點傳輸。tcp首部開銷20字節(jié),udp8字節(jié)。
udp使用場景:視頻通話、im聊天等。
time-wait表示客戶端等待服務端返回關閉信息的狀態(tài),closed_wait表示服務端得知客戶端想要關閉連接,進入半關閉狀態(tài)并返回一段TCP報文。
time-wait作用:
解決辦法:
close_wait:
被動關閉,通常是由于客戶端忘記關閉tcp連接導致。
根據(jù)業(yè)務來啊~
重要指標是cardinality(不重復數(shù)量),這個數(shù)量/總行數(shù)如果過小(趨近于0)代表索引基本沒意義,比如sex性別這種。
另外查詢不要使用select *,根據(jù)select的條件+where條件做組合索引,盡量實現(xiàn)覆蓋索引,避免回表。
僵尸進程:
即子進程先于父進程退出后,子進程的PCB需要其父進程釋放,但是父進程并沒有釋放子進程的PCB,這樣的子進程就稱為僵尸進程,僵尸進程實際上是一個已經(jīng)死掉的進程。
孤兒進程:
一個父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養(yǎng),并由init進程對它們完成狀態(tài)收集工作。
子進程死亡需要父進程來處理,那么意味著正常的進程應該是子進程先于父進程死亡。當父進程先于子進程死亡時,子進程死亡時沒父進程處理,這個死亡的子進程就是孤兒進程。
但孤兒進程與僵尸進程不同的是,由于父進程已經(jīng)死亡,系統(tǒng)會幫助父進程回收處理孤兒進程。所以孤兒進程實際上是不占用資源的,因為它終究是被系統(tǒng)回收了。不會像僵尸進程那樣占用ID,損害運行系統(tǒng)。
原文鏈接:
產(chǎn)生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系。
避免方法:
端口占用:lsof -i:端口號 或者 nestat
cpu、內(nèi)存占用:top
發(fā)送信號:kill -l 列出所有信號,然后用 kill [信號變化] [進程號]來執(zhí)行。如kill -9 453。強制殺死453進程
git log:查看提交記錄
git diff :查看變更記錄
git merge:目標分支改變,而源分支保持原樣。優(yōu)點:保留提交歷史,保留分支結(jié)構。但會有大量的merge記錄
git rebase:將修改拼接到最新,復雜的記錄變得優(yōu)雅,單個操作變得(revert)很簡單;缺點:
git revert:反做指定版本,會新生成一個版本
git reset:重置到某個版本,中間版本全部丟失
etcd、Consul
pprof
節(jié)省空間(非葉子節(jié)點不存儲數(shù)據(jù),相對b tree的優(yōu)勢),減少I/O次數(shù)(節(jié)省的空間全部存指針地址,讓樹變的矮胖),范圍查找方便(相對hash的優(yōu)勢)。
explain
其他的見:
runtime2.go 中關于 p 的定義: 其中 runnext 指針決定了下一個要運行的 g,根據(jù)英文的注釋大致意思是說:
所以當設置 runtime.GOMAXPROCS(1) 時,此時只有一個 P,創(chuàng)建的 g 依次加入 P, 當最后一個即 i==9 時,加入的最后 一個 g 將會繼承當前主 goroutinue 的剩余時間片繼續(xù)執(zhí)行,所以會先輸出 9, 之后再依次執(zhí)行 P 隊列中其它的 g。
方法一:
方法二:
[圖片上傳失敗...(image-4ef445-1594976286098)]
方法1:to_days,返回給的日期從0開始算的天數(shù)。
方法2:data_add。向日期添加指定時間間隔
[圖片上傳失敗...(image-b67b10-1594976286098)]
名稱欄目:go語言treeset go語言教程
本文網(wǎng)址:http://chinadenli.net/article4/dodjjie.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供面包屑導航、品牌網(wǎng)站制作、ChatGPT、網(wǎng)站營銷、網(wǎng)站收錄、網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)