Web服務器(go net/http) 處理Get、Post請求

大家好 我是寸鐵👊
總結了一篇Go Web服務器(go net/http) 處理Get、Post請求的文章?
喜歡的小伙伴可以點點關注 💝

前言

go http請求如何編寫簡單的函數去拿到前端的請求(Get和Post) 服務器(后端)接收到請求后,又是怎么處理請求,再把響應返回給客戶端?

在這里插入圖片描述

操作步驟:

Step1:注冊監聽和服務的端口

一開始,我們需要注冊監聽和服務的端口

我們需要調用go中提供的net/http這個函數包的ListenAndServe函數

方式一:

http.ListenAndServe(":8080", nil)

注意:這里號要帶上,不能只寫8080(踩坑經歷)

等價于

http.ListenAndServe("127.0.0.1:8080", nil)

方式二:

考慮到很多時候,可能并不是直接訪問本機127.0.0.1:8080端口,這里可以寫具體地址:端口號(其實就是一個Socket)

如:

http.ListenAndServe("192.168.0.1:3306", nil)

在知道怎么操作后,我們來了解一下底層源碼具體是怎么實現?了解后,便于更清楚的知道整體的流程!

在這里插入圖片描述

ListenAndServe()函數有兩個參數,當前監聽的端口號和事件處理器Handler。

事件處理器的Handler接口定義如下:

 type Handler interface {ServeHTTP(ResponseWriter, *Request)}

Handler 接口: Handler 是一個接口類型,聲明了一個方法 ServeHTTP。這個接口規定了任何實現了 ServeHTTP 方法的類型都可以被視為一個 HTTP 請求處理器。

ServeHTTP 方法: ServeHTTP 方法有兩個參數,分別是 ResponseWriter*Request

  • ResponseWriter 接口用于構建 HTTP 響應。它提供了一系列方法,允許你設置響應的狀態碼、頭部信息以及響應主體內容。
  • *Request 類型表示 HTTP 請求。它包含了所有關于客戶端請求的信息,比如請求方法、請求頭、URL 等。

PS:實現Handle接口不用寫ServeHttp方法,會比較方便。

后面的代碼都是用的封裝好的handler處理器,幫我們寫好ResponseWriter*Request ,只需專注業務邏輯即可。

后續分析這兩個參數的包含的具體信息

只要實現了這個接口,就可以實現自己的handler處理器。Go語言在net/http包中已經實現了這個接口的公共方法:

 type HandlerFunc func(ResponseWriter, *Request)?// ServeHTTP calls f(w, r).func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r)}

如果ListenAndServe()傳入的第一個參數地址為空,則服務器在啟動后默認使用http://localhost:8080地址進行訪問;

如果這個函數傳入的第二個參數為nil,則服務器在啟動后將使用默認的多路復用器DefaultServeMux

再來分析一下內層的server代碼

server結構體

server := &Server{Addr: addr, Handler: handler}

這是一種原生的寫法,我們也可以自己根據這段代碼來對server進行更詳細的定義。如下:

 s := &http.Server{Addr:           ":8081", //地址Handler:        myHandler,//處理器ReadTimeout:    20 * time.Second, //讀的超時設置 WriteTimeout:   20 * time.Second, //寫的超時設置MaxHeaderBytes: 1 << 10, //傳輸的最大頭部字節}

net/http.ServerHTTP 服務器的主要結構體,用于控制 HTTP 服務器的行為。

其結構體定義為:

type Server struct {
//服務器監聽的地址和端口號,格式為 "host:port",例如 "127.0.0.1:8080"Addr                         string
//HTTP 請求的處理器。對于每個收到的請求,服務器會將其路由到對應的處理器進行處理。通常使用 http.NewServeMux() 方法創建一個默認的多路復用器,并將其作為處理器。如果沒有設置該字段,則使用 DefaultServeMuxHandler                      Handler
//一個布爾值,用于指示是否禁用 OPTIONS 方法的默認實現。如果該值為 true,則在收到 OPTIONS 請求時,服務器不會自動返回 Allow 頭部,而是交給用戶自行處理。默認為 false,即啟用 OPTIONS 方法的默認實現DisableGeneralOptionsHandler bool
//HTTPS 服務器的 TLS 配置,用于控制 HTTPS 服務器的加密方式、證書、密鑰等安全相關的參數TLSConfig                    *tls.Config
//HTTP 請求的讀取超時時間。如果服務器在該時間內沒有讀取到完整的請求,就會關閉連接。該字段為 time.Duration 類型,默認為 0,表示沒有超時限制ReadTimeout                  time.Duration
//HTTP 請求頭部讀取超時時間。如果服務器在該時間內沒有完成頭部讀取,就會關閉連接。該字段為 time.Duration 類型,默認為 0,表示沒有超時限制ReadHeaderTimeout            time.Duration
//HTTP 響應的寫入超時時間。如果服務器在該時間內沒有完成對響應的寫入操作,就會關閉連接。該字段為 time.Duration 類型,默認為 0,表示沒有超時限制WriteTimeout                 time.Duration
//HTTP 連接的空閑超時時間。如果服務器在該時間內沒有收到客戶端的請求,就會關閉連接。該字段為 time.Duration 類型,默認為 0,表示沒有超時限制IdleTimeout                  time.Duration
//HTTP 請求頭部的最大大小。如果請求頭部的大小超過該值,服務器就會關閉連接。該字段為 int 類型,默認為 1 << 20(1MB)MaxHeaderBytes               intTLSNextProto                 map[string]func(*Server, *tls.Conn, Handler)
//連接狀態變化的回調函數,用于處理連接的打開、關閉等事件ConnState                    func(net.Conn, ConnState) 
//錯誤日志的輸出目標。如果該字段為 nil,則使用 log.New(os.Stderr, "", log.LstdFlags) 創建一個默認的日志輸出目標ErrorLog                     *log.Logger
//所有 HTTP 請求的基礎上下文。當處理器函數被調用時,會將請求的上下文從基礎上下文派生出來。默認為 context.Background()。BaseContext                  func(net.Listener) context.Context 
//連接上下文的回調函數,用于創建連接上下文。每個連接上下文都與一個客戶端連接相關聯。如果未設置該字段,則每個連接的上下文都是 BaseContext 的副本ConnContext                  func(ctx context.Context, c net.Conn) context.Context
//標志變量,用于表示服務器是否正在關閉。該變量在執行 Shutdown 方法時被設置為 true,用于避免新的連接被接受inShutdown                   atomic.Bool 
//標志變量,用于控制服務器是否支持 HTTP keep-alive。如果該變量為 true,則服務器在每次響應完成后都會關閉連接,即不支持 keep-alive。如果該變量為 false,則服務器會根據請求頭部中的 Connection 字段來決定是否支持 keep-alive。該變量在執行 Shutdown 方法時被設置為 true,用于關閉正在進行的disableKeepAlives            atomic.Bool
// 一個 sync.Once 類型的值,用于確保在多線程環境下,NextProtoOnce 方法只被調用一次。NextProtoOnce 方法用于設置 Server.NextProto 字段nextProtoOnce                sync.Once 
// error 類型的值,用于記錄 NextProto 方法的調用結果。該值在多個 goroutine 之間共享,用于檢測 NextProto 方法是否成功nextProtoErr                 error 
//互斥鎖,用于保護 Server 結構體的字段。因為 Server 結構體可能被多個 goroutine 并發訪問,所以需要使用互斥鎖來確保它們的安全性mu                           sync.Mutex    
//存儲 HTTP 或 HTTPS 監聽器的列表。每個監聽器都是一個 net.Listener 接口類型的實例,用于接收客戶端請求。當調用 Server.ListenAndServe() 或 Server.ListenAndServeTLS() 方法時,會為每個監聽地址創建一個對應的監聽器,并將其添加到該列表中listeners                    map[*net.Listener]struct{}
//表示當前處于活動狀態的客戶端連接的數量。該字段只是一個計數器,并不保證一定準確。該字段用于判斷服務器是否處于繁忙狀態,以及是否需要動態調整服務器的工作負載等activeConn                   map[*conn]struct{}                                    
//在服務器關閉時執行的回調函數列表。當服務器調用 Server.Shutdown() 方法時,會依次執行該列表中的每個回調函數,并等待它們全部執行完畢。該字段可以用于在服務器關閉時釋放資源、保存數據等操作onShutdown                   []func()                                              
//表示所有監聽器的組。該字段包含一個讀寫互斥鎖 sync.RWMutex 和一個映射表 map[interface{}]struct{}。在監聽器啟動時,會將監聽器地址作為鍵添加到映射表中。該字段主要用于實現優雅地關閉服務器。在服務器關閉時,會遍歷所有監聽器,逐個關閉它們,并等待所有連接關閉。如果在等待連接關閉時,有新的連接進來,服務器會先將新連接添加到 activeConn 字段中,并等待所有連接關閉后再退出。這樣可以保證服務器在關閉過程中,不會丟失任何連接listenerGroup                sync.WaitGroup                                        
}

Step2.1: 調用HandleFunc函數處理get請求

HandleFunc函數

在上面的代碼的基礎上,開始調用常用的處理請求的函數HandleFunc函數

在調用前,不妨先了解一下HandleFunc函數的作用是什么?

HandleFunc 函數的作用是創建一個處理器并將其注冊到指定的路徑上。這個處理器會調用提供的函數處理請求。這種方式非常方便,因為你可以直接使用一個函數來處理請求,而不必實現完整的 http.Handler 接口。

有了上面的基礎后,編寫一個案例摸清HandleFunc函數。

測試案例

package mainimport ("fmt""net/http"
)func helloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprint(w, "Hello, World!")
}func main() {http.ListenAndServe(":8080", nil)http.HandleFunc("/hello", helloHandler)
}

輸出結果如下:

在這里插入圖片描述

分析一下這段代碼

在這里插入圖片描述

在這個例子中helloHandler 函數處理 /hello 路徑上的請求。通過 http.HandleFunc 將這個函數helloHandler 注冊到指定的路徑,然后使用 http.ListenAndServe 啟動 HTTP 服務器。

當有請求訪問 /hello 路徑時,將調用 helloHandler 函數來處理請求。


有了HandleFunc函數的基礎后,下面正式進入處理客戶端發送過來的get請求

處理客戶端的get請求
運行效果及逐行分析

代碼

package mainimport ("fmt""io""net/http"
)func main() {//get請求http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {query := request.URL.Query() //接收到客戶端發送的get請求的URLfmt.Print(request.URL.Path) //后端顯示打印很多相關的內容//io包下提供的寫方法,將服務端get到的id和name以字符串的形式寫到客戶端顯示io.WriteString(writer, "query:"+query.Get("id")+query.Get("name"))})http.ListenAndServe(":8080", nil)}

運行上面這段代碼后,我們來看一下運行的結果,從結果去不斷梳理整個處理的過程。

運行結果如下

在這里插入圖片描述

分析運行結果

在這里插入圖片描述

逐行逐行詳解:

http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) 
  • 這一行代碼使用 http.HandleFunc 函數將一個匿名函數注冊到根路徑("/")上,也就是處理默認的請求。這個匿名函數接受兩個參數,writer 是用于寫入響應的 http.ResponseWriter 接口,而 request 是表示客戶端請求的 http.Request 結構。
query := request.URL.Query()
  • 通過 request.URL.Query() 獲取請求的 URL 中的查詢參數,并將其存儲在 query 變量中。查詢參數通常是在 URL 中以 ? 后面的鍵值對形式出現的,例如:http://localhost:8080/?id=123&name=John
fmt.Print(request.URL.Path)
  • 在控制臺上查看請求的路徑信息
io.WriteString(writer, "query:"+query.Get("id")+query.Get("name"))
  • 使用 io.WriteString 將包含查詢參數的字符串寫入響應。它會將 “query:” 后面連接著 idname 參數的值。

總結:

當有請求訪問根路徑("/")時,打印請求的路徑并返回包含查詢參數的字符串響應。

request的api的具體信息

在演示了基本的get請求結果后,服務端往客戶端返回的響應(寫一句話)

下面開始在控制臺輸出request其他相關的具體信息

先來看一下可以調用request的哪些具體屬性(字段)

在這里插入圖片描述

request可調出的屬性比較多,每個屬性中對應的api方法也比較多。

這里演示常用的api,需要獲取request的具體api方法可以直接查。

演示結果如下:

在這里插入圖片描述

demo

package mainimport ("fmt""io""net/http"
)func main() {//get請求http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {query := request.URL.Query()//設置request請求頭部的字段 如設置name為hellofmt.Println("request.URL.Path內容:", request.URL.Path) //可以打印很多相關的內容fmt.Println("request.URL.Host內容:", request.URL.Host) //可以打印很多相關的內容fmt.Println("request.URL.Fragment內容:", request.URL.Fragment)fmt.Println("request.URL.Scheme內容:", request.URL.Scheme)fmt.Println("request.URL.User內容:", request.URL.User)fmt.Println("request.Header內容:", request.Header)fmt.Println("request.Body內容:", request.Body)fmt.Println("request.ContentLength內容為:", request.ContentLength)fmt.Println("request.Method內容為:", request.Method)fmt.Println("request.Close內容為:", request.Close)io.WriteString(writer, "query:"+query.Get("id")+query.Get("name"))})http.ListenAndServe(":8080", nil)}

處理器writer和request的具體信息

在前面的應用基礎上,下面正式分析處理器的writerrequest的來源和相關信息

http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) 
  • 先看writer http.ResponseWriter

http.ResponseWriter是一個接口類型:

// net/http/server.go
type ResponseWriter interface {Header() HeaderWrite([]byte) (int, error)WriteHeader(statusCode int)
}

用于向客戶端發送響應,實現了ResponseWriter接口的類型顯然也實現了io.Writer接口。所以在處理函數index中,可以調用fmt.Fprintln()ResponseWriter寫入響應信息。

這也很好的解釋了前面代碼調用io.writeString方法將返回的響應信息寫入實現了ResponseWriter接口的對象writer,再調用方法返回響應信息。

io.WriteString(writer, "query:"+query.Get("id")+query.Get("name"))

代碼剖析

定義了一個接口 ResponseWriter,該接口規定了用于寫入 HTTP 響應的方法。

接口中的每個方法如下:

Header() Header:

Header() 方法返回一個 Header 類型的值。Header 是一個映射(map),用于表示 HTTP 響應頭。響應頭包括一系列的鍵值對,每個鍵值對表示一個響應頭字段和它的值。


Write([]byte) (int, error):

Write 方法接受一個字節切片([]byte)作為參數,并返回寫入的字節數和可能的錯誤。這個方法用于將字節數據寫入 HTTP 響應體。


WriteHeader(statusCode int):

WriteHeader 方法接受一個整數參數 statusCode,用于設置 HTTP 響應的狀態碼。HTTP 狀態碼是一個三位數的代碼,用于表示服務器對請求的處理結果。例如,200 表示成功,404 表示資源未找到,500 表示服務器內部錯誤等。

編寫一個 HTTP 處理器時,會接收到一個實現了 ResponseWriter 接口的對象writer,可以通過該對象來設置響應頭、寫入響應體以及設置狀態碼等信息。

補充:

在 Go 中,通常會使用http.ResponseWriter類型的變量來表示實現了 ResponseWriter 接口的對象。例如,在你的 HTTP 處理器函數中,如下:

func MyHandler(writer http.ResponseWriter, r *http.Request) {// 使用 writer來設置響應頭、寫入響應體等
}

這樣,便可以通過 writer 對象來操作 HTTP 響應。


  • 再看request的具體信息

net/http中的 Request結構體表示一個HTTP請求,包含請求方法URL請求頭請求體等信息。信息主要在文件 net/http/request.go中。

結構體中字段的信息:

type Request struct {Method           string                    //HTTP請求方法,如GET、POST等URL              *url.URL//HTTP請求的URL地址,是一個指向url.URL類型的指針。Proto            string                        //HTTP協議版本,如"HTTP/1.0"或者"HTTP/1.1"ProtoMajor       int                          //HTTP協議的主版本號,整數類型。如1ProtoMinor       int                           //HTTP協議的次版本號,整數類型。如0Header           Header                       //HTTP請求頭信息,是一個http.Header類型的映射,用于存儲HTTP請求頭。Body             io.ReadCloser                 //HTTP請求體,是一個io.ReadCloser類型的接口,表示一個可讀可關閉的數據流。GetBody          func() (io.ReadCloser, error) //HTTP請求體獲取函數ContentLength    int64                        //HTTP請求體的長度,整數類型。TransferEncoding []string                      //HTTP傳輸編碼,如"chunked"等。Close            bool                          //表示在請求結束后是否關閉連接。Host             string                        //HTTP請求的主機名或IP地址,字符串類型。Form             url.Values                    //HTTP請求的表單數據,是一個url.Values類型的映射,用于存儲表單字段和對應的值。PostForm         url.Values                    //HTTP POST請求的表單數據,同樣是一個url.Values類型的映射。MultipartForm    *multipart.Form             //HTTP請求的multipart表單數據,是一個multipart.Form類型的結構體。Trailer          Header                        //HTTP Trailer頭信息,是一個http.Header類型的映射,用于存儲Trailer頭部字段和對應的值。RemoteAddr       string                       //請求客戶端的地址。RequestURI       string                        //請求的URI,包括查詢字符串。TLS              *tls.ConnectionState          //如果請求是使用TLS加密的,則該字段存儲TLS連接的狀態信息。Cancel           <-chan struct{}               //一個只讀通道,用于在請求被取消時發送信號。Response         *Response                     //一個指向http.Response類型的指針,表示HTTP響應信息。ctx              context.Context               //一個context.Context類型的上下文,用于控制請求的超時和取消。}

Step2.2: 調用HandleFunc函數處理post請求

http.HandleFunc("/user/add", func(writer http.ResponseWriter, request *http.Request) {// ...
})

這里使用 http.HandleFunc 函數注冊了一個處理 “/user/add” 路徑的回調函數。當有請求訪問 “/user/add” 路徑時,Go 將調用這個函數來處理請求。

這是注冊的回調函數的簽名,它接收兩個參數,一個是 http.ResponseWriter,用于構建 HTTP 響應,另一個是 http.Request,包含了客戶端的 HTTP 請求信息。

var params map[string]string //創建map
decoder := json.NewDecoder(request.Body)
//調用NewDecoder() 創建body的json解碼器
decoder.Decode(&params)
//json解碼成map后存儲到params變量 

這段代碼使用 Go 標準庫的 encoding/json 包創建了一個 JSON 解碼器 decoder,然后將 HTTP 請求的主體(body)中的 JSON 數據解碼到 params 變量中。params 是一個 map[string]string 類型,用于存儲 JSON 解析后的鍵值對。

其實就是將json轉換為map

io.WriteString(writer, "postjson:"+params["name"])

最后,通過 io.WriteStringhttp.ResponseWriter 寫入響應。這個響應是一個字符串,包含了 “postjson:” 和從 JSON 中提取的名為 “name” 的字段的值。

總結:

代碼用于處理 POST 請求,解析請求主體中的 JSON 數據,并返回一個字符串響應,其中包含從 JSON 中提取的 "name" 字段的值。

運行結果如下:

在這里插入圖片描述


http.HandleFunc("/user/del", func(writer http.ResponseWriter, request *http.Request) 

這里使用 http.HandleFunc 函數注冊了一個處理 “/user/del” 路徑的回調函數。當有請求訪問 “/user/del” 路徑時,Go 將調用這個函數來處理請求。

接著是注冊的回調函數的簽名,它接收兩個參數,一個是 http.ResponseWriter,用于構建 HTTP 響應,另一個是 http.Request,包含了客戶端的 HTTP 請求信息。

request.ParseForm()

這行代碼調用了 ParseForm 方法,用于解析請求的表單數據(包括 URL 中的查詢參數和請求體中的表單數據)。這是因為后面的代碼使用了 request.Form.Get("name") 來獲取表單中名為 “name” 的字段的值。

io.WriteString(writer, "form:"+request.Form.Get("name"))

最后,通過 io.WriteStringhttp.ResponseWriter 寫入響應。這個響應是一個字符串,包含了 “form:” 和從表單中提取的名為 “name” 的字段的值。

總結

其實就是用于處理·"/user/del"路徑的請求,解析表單數據,并返回一個字符串響應,其中包含從表單中提取的 "name" 字段的值。

運行結果如下:

在這里插入圖片描述


demo

package mainimport ("encoding/json""io""net/http"
)func main() {//Post請求//添加用戶 post client - server post entype postman JSON client ajax//客戶端向服務端發送請求http.HandleFunc("/user/add", func(writer http.ResponseWriter, request *http.Request) {//POST DATA ENTYPE JSONvar params map[string]stringdecoder := json.NewDecoder(request.Body)decoder.Decode(&params)//傳入地址 將傳入的json轉換為對應的map格式io.WriteString(writer, "postjson:"+params["name"]) //通過map獲取對應的值})http.HandleFunc("/user/del", func(writer http.ResponseWriter, request *http.Request) {request.ParseForm() //不能直接使用Get 需要轉換一下io.WriteString(writer, "form:"+request.Form.Get("name"))})http.ListenAndServe(":8080", nil)}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165080.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165080.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165080.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【限時免費】20天拿下華為OD筆試之【前綴和】2023B-尋找連續區間【歐弟算法】全網注釋最詳細分類最全的華為OD真題題解

文章目錄 題目描述與示例題目描述輸入描述輸出描述示例一輸入輸出說明 示例二輸入輸出 解題思路代碼PythonJavaC時空復雜度 華為OD算法/大廠面試高頻題算法練習沖刺訓練 題目描述與示例 題目描述 給定一個含有N個正整數的數組&#xff0c;求出有多少個連續區間&#xff08;包…

【網絡奇緣】- 計算機網絡|分層結構|ISO模型

&#x1f308;個人主頁: Aileen_0v0&#x1f525;系列專欄: 一見傾心,再見傾城 --- 計算機網絡~&#x1f4ab;個人格言:"沒有羅馬,那就自己創造羅馬~" 目錄 計算機網絡分層結構 OSI參考模型 OSI模型起源 失敗原因: OSI模型組成 協議的作用 &#x1f4dd;全文…

二十四、RestClient操作文檔

目錄 一、新增文檔 1、編寫測試代碼 二、查詢文檔 1、編寫測試代碼 三、刪除文檔 1、編寫測試代碼 四、修改文檔 1、編寫測試代碼 五、批量導入文檔 批量查詢 一、新增文檔 1、編寫測試代碼 SpringBootTest public class HotelDocumentTest {private RestHighLevelC…

【棧】不同字符的最小子序列

題目&#xff1a; /*** 思路&#xff1a;棧,使用數組記錄每個字母出現的次數&#xff0c;再用一個數組標記字符是否在棧中* 遍歷棧&#xff0c;存儲字符時比較棧頂字符&#xff0c;若小于棧頂字符并且后面有重復的字符則* 棧頂元素出棧&#xff0c;否則入棧。** au…

PS 注釋工具 基礎使用方法講解

好 上文PS 顏色取樣器&標尺工具 基本使用講解中 我們講了 顏色取樣器和標尺工具的基本用法 下面我們來看一下 注釋工具 這個 主要是后面 比較大的作品 可能不是我們一個人取設計 團隊作圖 就需要用到它 選擇 注釋工具 后 我們隨便點擊圖像任何一個位置 右側就會出現一個輸…

gitlab各版本安裝注意點:

研發團隊在安裝gitlab各版本過程中可能遇到各種問題&#xff0c;為了后續容易查看特將我們在實踐過程中遇到的各類問題要點總結如下&#xff1a; gitlab 10.8.3 (564c342&#xff09;安裝 centos Linux yum安裝網址查找網址&#xff1a;gitlab/gitlab-ce - Results for gitla…

執行shell腳本提示syntax error: unexpected end of file

具體報錯如下&#xff1a; ./test.sh: line 36: syntax error: unexpected end of file執行命令時需將test.sh替換為實際的腳本文件名稱。 情形一&#xff1a; shell腳本在Windows下編寫&#xff0c;上傳到Linux上執行&#xff0c;由于 fileformat 類型不同&#xff0c;所以報…

黑馬點評12-實現好友關注/取關功能,查看好友共同關注列表

好友關注 數據模型 數據庫中的tb_follow記錄博主與粉絲的關系 tb_follow表對應的實體類 Data EqualsAndHashCode(callSuper false) Accessors(chain true) TableName("tb_follow") public class Follow implements Serializable {private static final long ser…

代碼隨想錄算法訓練營第三十二天| 122 買賣股票的最佳時機 || 55 跳躍游戲 45 跳躍游戲 ||

目錄 122 買賣股票的最佳時機 || 55 跳躍游戲 45 跳躍游戲 || 122 買賣股票的最佳時機 || 設置變量now代表此時買入的股票&#xff0c;為賦值為Integer.MAX_VALUE&#xff0c;遍歷prices數組&#xff0c;有如下兩種情況&#xff1a; 如果比now小說明不能售出&#xff0c;可以…

關于unicloud云對象或云函數獲取時間不對的問題

話不多說&#xff0c;直接上代碼&#xff1a; function timeWeekFormat() { //定義一個日期對象; var dateTime getOffsetDate(8); //獲得系統年份; var year dateTime.getFullYear(); //獲得系統月份; var month dateTime.getMonth() 1; //獲…

棧和隊列的OJ題--12.括號匹配

12.括號匹配 20. 有效的括號 - 力扣&#xff08;LeetCode&#xff09; 解題思路&#xff1a;該題比較簡單&#xff0c;是對棧特性很好的應用&#xff0c;具體操作如下&#xff1a;循環遍歷String中的字符&#xff0c;逐個取到每個括號&#xff0c;如果該括號是&#xff1a;1. …

Git工作流和Commit規范

Git大家都非常熟悉了&#xff0c;就不做過多介紹&#xff0c;但是如何用好Git、如何進行合理的分支開發、Merge你是否有一個規范流程呢&#xff1f;&#x1f4a4; 不論是一個團隊一起開發一個項目&#xff0c;還是自己獨立開發一個項目&#xff0c;都少不了要和Git打交道&…

【NGINX--5】身份驗證

1、HTTP 基本身份驗證 需要通過 HTTP 基本身份驗證保護應用或內容。 生成以下格式的文件&#xff0c;其中的密碼使用某個受支持的格式進行了加密或哈希處理&#xff1a; # comment name1:password1 name2:password2:comment name3:password3第一個字段是用戶名&#xff0…

紫光展銳V8821榮獲“中國芯”重大創新突破產品獎

近日&#xff0c;“中國芯”優秀產品評選落下帷幕&#xff0c;紫光展銳首顆5G IoT-NTN衛星通信SoC芯片V8821憑借在衛星通信前沿領域的技術創新&#xff0c;從285家芯片企業、398款芯片產品中脫穎而出&#xff0c;榮獲第十八屆“中國芯”年度重大創新突破產品獎。 “中國芯”優…

ReentrantLock源碼解析

ReentrantLock源碼解析 文章目錄 ReentrantLock源碼解析一、ReentrantLock二、ReentrantLock 的 Sync、FairSync、NonfairSync2.1 Sync、FairSync、NonfairSync2.2 NonfairSync 下的 tryAcquire2.3 FairSync下的 tryAcquire2.4 tryRelease 三、lock.lock()3.1 NonfairSync.lock…

優橙內推青海專場——5G網絡優化(中高級)工程師

可加入就業QQ群&#xff1a;801549240 聯系老師內推簡歷投遞郵箱&#xff1a;hrictyc.com 內推公司1&#xff1a;浙江明訊網絡技術有限公司 內推公司2&#xff1a;南京華蘇科技有限公司 內推公司3&#xff1a;杭州華星創業通信技術有限公司 浙江明訊網絡技術有限公司 浙江明…

4.常見面試題--操作系統

特點&#xff1a;并發性、共享性、虛擬性、異步性。 Windows 和 Linux 內核差異 對于內核的架構?般有這三種類型&#xff1a; ● 宏內核&#xff0c;包含多個模塊&#xff0c;整個內核像?個完整的程序&#xff1b; ● 微內核&#xff0c;有?個最?版本的內核&#xff0…

名字大卻不中用的AI大模型,名不副實

這兩天 OpenAI 團隊&#xff08; ChatGPT 公司&#xff09;的戲比較多&#xff0c;兩三天的功夫&#xff0c;劇情發展都超出了 OpenAI 首席科學家的預期&#xff0c;目前來看&#xff0c;微軟還是最大的贏家。這是個引子&#xff0c;這個話題&#xff0c;網絡上早已傳爛了&…

云安全之盾:ZStack 云主機安全防護解決方案全方位保護云環境

隨著云計算的蓬勃發展&#xff0c;網絡威脅愈發復雜&#xff0c;涵蓋了從勒索病毒到APT攻擊的各種威脅類型。在這一風云變幻的網絡安全環境下&#xff0c;云主機安全不再僅僅是一個選項&#xff0c;它是信息系統安全的核心要素。云軸科技ZStack 云主機安全防護解決方案是為了滿…

6.3.WebRTC中的SDP類的結構

在上節課中呢&#xff0c;我向你介紹了sdp協議&#xff0c; 那這節課呢&#xff0c;我們再來看看web rtc中。是如何存儲sdp的&#xff1f;也就是sdp的類結構&#xff0c;那在此之前呢&#xff1f;我們先對sdp的內容啊&#xff0c;做一下分類。因為在上節課中呢&#xff0c;雖然…