1. 程式人生 > 其它 >三個小專案入門Go語言|位元組青訓營筆記

三個小專案入門Go語言|位元組青訓營筆記

前言

這是青訓營的第一課,今天的課程比較快速的講解了go語言的入門,並配合三個小的專案實踐梳理所學知識點,這裡詳細回顧一下這三個專案,結合課後作業要求做一些程式碼補充,並附上自己的分析,青訓期間的所有課程筆記會同步文末公眾號,有需要同學請關注~。

專案倉庫地址:https://github.com/wangkechun/go-by-example

實戰

專案一:guessing-game

生成一個100以內隨機數,玩家在控制檯輸入猜測的數字,程式會不斷反饋猜測的值與生產值的大小關係,直到玩家輸入正確,程式碼簡單,這裡直接貼出(需要注意不要忘記新增隨機數種子):

專案二:simpledict

先概述一下功能:使用者將需要翻譯的單詞作為引數在命令列執行go的main函式,程式會返回翻譯結果。通過下面的語句可以直接執行樣例倉庫程式碼中的main函式,得到翻譯結果。

那麼程式是如何實現這個翻譯功能的呢?它做了下面幾件事:

  • 獲取main函式執行時的引數hello作為需要翻譯的單詞(通過go的api獲取)

  • 請求翻譯軟體的api獲取結果資料:

    • 這個過程和爬蟲的工作比較像,模擬使用者在網頁上提交翻譯的請求,其本質上就是傳送了一個http請求,攜帶需要翻譯的單詞資訊,響應翻譯結果的json並由瀏覽器解析,通過下圖的copy as cURL可以將本次request的請求以cURL請求的方式拷貝。
    • 訪問:https://curlconverter.com/#go,這個線上工具可以將curl命令轉換成go語言程式碼(或者其他語言),將得到的程式碼直接複製到goland中執行就可以實現用go程式碼模擬請求這個翻譯介面,得到響應資料(文字格式的json)

  • 解析結果資料

    • 此時得到的翻譯資料是文字格式的json(就是byte陣列,或者說字串),因此需要將其反序列化為go的結構體,然後打印出我們需要的翻譯資訊。

    • 訪問:https://oktools.net/json2go,這個線上工具可以將json轉go的struct,然後將這個結構放入go程式碼中,使用json包的Unmarshal函式將json字串字串反序列化為結構體,後面就可以列印結構體中需要的屬性(包含翻譯結果)

  • 改進:用到兩個翻譯軟體的介面,並且併發訪問,思路是一樣的,就是再找一個翻譯軟體的介面重複上面的操作,然後重點在於併發的實現,這裡啟用兩個goroutine,藉助sync包的WaitGroup,先初始化一個2的容量,然後在一個go程結束之後呼叫wg.Done(),只有全部容量次數的Done呼叫後wg.Wait()才會放行,否則任意一個go程未完成,主go程都不會繼續執行(但是如果沒有這個WaitGroup去限制,則在主go程結束時,因為由其建立的子go程可能並沒有完成,但依舊會結束,而恰恰因為併發的關係,編碼先後順序的失去了作用,發生這種情況的概率很高)

專案三:proxy

實現一個簡易版的socks5的代理伺服器,代理的工作流程如下:

  • 本質就是客戶端要先和代理伺服器建立TCP連線,然後socks代理伺服器和需要訪問的目標伺服器建立TCP連線,對於所有從客戶端發來的請求由代理伺服器轉發給目標伺服器,且目標伺服器的響應資料也由代理伺服器轉發給客戶端(socks5代理伺服器就是以sock5s協議為標準去建立客戶端和代理伺服器的通訊)

  • 觀察proxy專案包的v4版本(clone地址已經給出),看到代理服務端的process函式如下:

    • 代理的工作由auth()認證和connect()連線兩個部分組成,看一下最上面給出的代理工作流程圖,可以看到對應著協商階段和通訊階段。而我們發現,本例項的客戶端發起的是一條curl --socks5 127.0.0.1:1080 -v https://www.qq.com,需要注意的細節是,auth和connect工作並不是一蹴而就的,它們從reader緩衝區讀取客戶端傳送過來的資料,驗證之後返回給客戶端,然後再獲取從客戶端傳送過來的資料,而客戶端的這部分工作已經被curl工具隱藏,而非只是發起了一次請求。
    • 因為auth和connect函式中多次使用到的從緩衝區讀取位元組的這個api在緩衝區沒有byte的時候,是會被阻塞的,因此會等待客戶端傳送資料,因此只要代理伺服器遵守socks5協議規定的通訊規則進行解析客戶端的資料,傳送指定的響應,而客戶端也遵守這個規則解析和傳送資料(本例就是curl --socks5 xxx幫我們完成了),就可以實現socks5代理伺服器的工作模式
    • 因此我理解中的socks5代理伺服器就是完全在socks5協議約束的基礎上進行編碼的一個伺服器,之後的請求和響應轉發則和socks5沒關係了

結束語

對於第三個樣例這裡只是著重講了一下我的一些理解,socks5代理部分還有很多值得深入學習的地方。關於後面課程的學習,也儘量會保證筆記的輸出,歡迎各位一起探討學習~

關注微信公眾號【程式設計師白澤】,將同步更新位元組青訓營的學習筆記