Go 1.19.4 HTTP编程-Day 20
1. HTTP协议
1.1 基本介绍
- HTTP协议又称超文本传输协议,属于应用层协议,在传输层使用TCP协议。
- HTTP协议属是无状态的,对事务处理没有记忆能力,如果需要保存状态需要引用其他技术,如Cookie。
- HTTP协议属是无连接的,每次连接只处理一个请求。因为早期带宽和计算资源有限,这么做是为了加快传输速度,后来通过Connection:Keep-Alive实现了长连接。
- http1.1废弃了Keep-Alive,默认支持长连接。
1.2 http requst(请求报文)
(1)请求行:GET / HTTP/1.1
- GET:请求方法。
- /:URL(请求路径)
- 协议版本:HTTP/1.1
(2)请求头
- Host: www.baidu.com:告诉服务器请求的目标地址。
- User-Agent: curl/7.65.0:表明请求是由curl工具发起的,版本是7.65.0。
- Accept: */*:表示客户端可以接受任何类型的响应内容。
如果是POST请求,那么请求头中的内容更多。如:
- Accept-Language: en-US,en:客户端可接受的语言。
Accept-Encoding: gzip, deflate, br:
客户端能够处理的压缩格式。- Authorization: Bearer token_value:如果需要认证,此处包含认证(证书)信息。
- Cache-Control: no-cache:指定请求和响应遵循的缓存机制。no-cache表示无缓存机制。
- 等等其他内容。
(3)空行
就Accept: */*下面那个空行。
(4)请求正文注意:GET请求,是没有请求正文的。举例一个POST请求:
name=John+Doe&age=30,这就是POST请求的请求主正文。
1.3 请求方法介绍
请求方法 | 含义 |
GET | 请求获取Request-URI所标识的资源,如下载一张图片。 |
POST | 向服务器提交数据进行处理,比如提交表单或者上传文件。数据通常放在请求正文中。 |
HEAD | 类似于GET,但是返回的响应中没有具体的内容。主要用于获取响应头部。 |
PUT | 上传文件或提交资源到服务器,通常指定了资源的URI。 |
DELETE | 请求服务器删除指定的页面。 |
OPTIONS | 查看服务端的性能。 |
TRACE | 类似于链路追踪,可以看到请求经过了哪些节点以及耗时等。 |
PATCH | 类似PUT,但它可以只对资源的一部分进行更新,资源不存在时则创建。 |
注意:
- 实际工作中,服务端对各种请求方法的处理方式可能不是按照我们标准的协议来的,比如服务端收到的是PUT请求,但执行的是删除操作,具体还要看开发者怎么定义。
- 大多数浏览器只支持GET和POST。
1.4 http response(响应报文)
(1)响应状态行:HTTP/1.1 200 OK
- HTTP/1.1:表示请求协议版本。
- 200:表示请求状态码。
- OK:表示状态消息。
(2)响应头
- Accept-Ranges: bytes:表示服务器能够接受以字节为单位的范围请求。
- Cache-Control:指示响应不能被缓存。
- Connection: keep-alive:表示这个TCP连接在发送完响应后不会关闭,可以被重用。
- Content-Length: 2381:响应体的长度是2381字节。
- Content-Type: text/html:响应体的类型是HTML。
- Date:响应生成的日期和时间。
- Etag:资源的一个特定版本的标识。
- Last-Modified:资源最后被修改的日期和时间。
- Pragma: no-cache:一个指令,要求请求和响应遵循HTTP/1.0的缓存机制,不要缓存。
- Server: bfe/1.0.8.18:服务器使用的软件信息。
- Set-Cookie:服务器设置了一个名为BDOZ的cookie,有效期为86400秒,域名为.baidu.com。
(3)空行
(4)响应报文主体
- <!DOCTYPE html> ... </html>
1.5 URL和URI
1.5.1 基本介绍
- URI:统一资源标识符(Uniform Resource Identifier),是一个用于标识资源的字符串。它提供了一种方式,通过该方式可以唯一地标识互联网上的资源,但没有提供访问方式。
- URL:统一资源定位符(Uniform Resource Locator),是URI的一种,用于定位资源。它不仅标识资源,还提供了如何通过互联网访问该资源的具体信息。
1.5.2 示例
2. go语言http标准库
在go中实现http编程,主要是使用go包中的net/http。
net:net包为网络I/O提供了一个可移植的接口,包括TCP/IP、UDP、域名解析和Unix域套接字。
- http:http 包提供了 HTTP 客户端和服务器实现。
- 其余协议参考官网。
2.1 GET请求
2.1.1 http服务端
2.1.1.1 编辑代码
package mainimport ("fmt""log""net/http"
)// w http.ResponseWriter, r *http.Request: 为固定写法
func BoyHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprint(w, "Hello Boy")
}func GirlHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprint(w, "Hello Girl")
}func main() {// 定义路由// 请求"/boy"路径,就调用BoyHandler函数http.HandleFunc("/boy", BoyHandler)http.HandleFunc("/gir", GirlHandler)// 服务启动后的端口号err := http.ListenAndServe(":5656", nil) // 注意:成功启动的话,就会一直阻塞(没有输出)。if err != nil {log.Panic(err)}
}
2.1.1.2 浏览器请求服务端
2.1.2 http客户端
2.1.2.1 编辑代码并发起GET请求
package mainimport ("io""log""net/http""os"
)func get() {// 定义一个GET请求r, err := http.Get("http://localhost:5656/gir")if err != nil {log.Panic(err)}defer r.Body.Close() // 用完关闭,否则会协程泄露// 因为Body方法没有办法直接打印出来,所以把它复制到标准输出。io.Copy(os.Stdout, r.Body)
}func main() {get()
}
============调试结果============
Hello Girl
2.1.3 增加其他http信息
2.1.3.1 服务端
package mainimport ("fmt""log""net/http"
)// w http.ResponseWriter, r *http.Request: 为固定写法
func BoyHandler(w http.ResponseWriter, r *http.Request) {// 显示请求头for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}fmt.Fprint(w, "Hello Boy\n")
}func GirlHandler(w http.ResponseWriter, r *http.Request) {for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}fmt.Fprint(w, "Hello Girl\n")
}func main() {http.HandleFunc("/boy", BoyHandler)http.HandleFunc("/gir", GirlHandler)err := http.ListenAndServe(":5656", nil)if err != nil {log.Panic(err)}
}
2.1.3.2 客户端
package mainimport ("fmt""io""log""net/http""os"
)func get() {r, err := http.Get("http://localhost:5656/boy")if err != nil {log.Panic(err)}defer r.Body.Close()io.Copy(os.Stdout, r.Body)// 显示响应头for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}// 显示请求协议fmt.Printf("Proto:%v\n", r.Proto)fmt.Printf("Close: %v\n", r.Close)// 显示请求内容长度fmt.Printf("ContentLength: %v\n", r.ContentLength)// 请求协议主版本号fmt.Printf("ProtoMajor: %+v\n", r.ProtoMajor)// 请求协议次版本号fmt.Printf("ProtoMinor: %+v\n", r.ProtoMinor)// 原始请求fmt.Printf("Request: %+v\n", r.Request)// 请求状态,含状态码和OK与否fmt.Printf("Status: %+v\n", r.Status)// 请求状态码fmt.Printf("StatusCode: %+v\n", r.StatusCode)// 请求方法fmt.Printf("Request.Method: %+v\n", r.Request.Method)// 请求地址fmt.Printf("%+v\n", r.Request.URL)// 还有很多内容,这里只展示部分。
}func main() {get()
}
2.1.4 请求测试
2.1.4.1 客户端
2.1.4.2 服务端
2.2 POST请求
2.2.1 服务端代码
package mainimport ("fmt""io""log""net/http""os"
)func BoyHandler(w http.ResponseWriter, r *http.Request) {// 关闭请求主体defer r.Body.Close()// 显示请求主体io.Copy(os.Stdout, r.Body)for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}fmt.Fprint(w, "Hello Boy\n")
}func GirlHandler(w http.ResponseWriter, r *http.Request) {defer r.Body.Close()// 显示请求主体io.Copy(os.Stdout, r.Body)for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}fmt.Fprint(w, "Hello Girl\n")
}func main() {http.HandleFunc("/boy", BoyHandler)http.HandleFunc("/gir", GirlHandler)err := http.ListenAndServe(":5656", nil)if err != nil {log.Panic(err)}
}
2.2.2 客户端代码
package mainimport ("fmt""io""log""net/http""os""strings"
)func get() {r, err := http.Get("http://localhost:5656/boy")if err != nil {log.Panic(err)}defer r.Body.Close()io.Copy(os.Stdout, r.Body)// 显示响应头for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}
}func post() {// 请求服务端要发送的内容(请求主体)r := strings.NewReader("hello server\n")// 构建post请求r2, err := http.Post("http://localhost:5656/boy", "text/plain", r)if err != nil {log.Panic(err)}defer r2.Body.Close()io.Copy(os.Stdout, r2.Body)for k, v := range r2.Header {fmt.Printf("%v: %v\n", k, v)}
}func main() {post()
}
2.2.3 请求测试
2.3 POST请求进阶版
使用函数:
- http.NewRequest(method string, url string, body io.Reader) (*http.Request, error)
参数:
- method string:请求的方法,比如 "GET"、"POST"、"PUT"、"DELETE" 等。
- url string:请求的 URL,可以是一个完整的 URL 字符串。
- body io.Reader:请求的主体(body),它是一个
io.Reader
接口,可以是nil
,表示没有请求体。返回值:
- *http.Request:一个新建的 HTTP 请求对象。
- error:如果在创建请求的过程中出现错误,这个错误对象会被返回,否则为
nil
。
2.3.1 服务端代码编辑
package mainimport ("fmt""io""log""net/http""os"
)func BoyHandler(w http.ResponseWriter, r *http.Request) {// 关闭请求主体defer r.Body.Close()// 显示请求主体io.Copy(os.Stdout, r.Body)// 显示请求头for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}// 显示Cookiesfor _, cokkie := range r.Cookies() {fmt.Printf("%v: %v\n", cokkie.Name, cokkie.Value)}fmt.Fprint(w, "Hello Boy\n")
}func GirlHandler(w http.ResponseWriter, r *http.Request) {defer r.Body.Close()// 显示请求主体io.Copy(os.Stdout, r.Body)for k, v := range r.Header {fmt.Printf("%v: %v\n", k, v)}fmt.Fprint(w, "Hello Girl\n")
}func main() {http.HandleFunc("/boy", BoyHandler)http.HandleFunc("/gir", GirlHandler)err := http.ListenAndServe(":5656", nil)if err != nil {log.Panic(err)}
}
2.3.2 客户端代码编辑
package mainimport ("fmt""io""log""net/http""os""strings""time"
)func complexHttpRequest() {reader := strings.NewReader("hello server\n")req, err := http.NewRequest("POST", "http://localhost:5656/boy", reader)if err != nil {log.Panic(err)} else {// 增加自定义请求头req.Header.Add("User-Agent", "中国")req.Header.Add("MyHeaderKey", "MyHeaderValue")// 增加自定义Cokkiereq.AddCookie(&http.Cookie{// 传给服务端的信息Name: "auth",Value: "passwd",// 下面这3行信息,主要是作为记录,并不传给服务端Path: "/",Domain: "localhost",Expires: time.Now().Add(time.Duration(time.Hour)),})client := &http.Client{// Timeout: 100 * time.Microsecond, // 客户端等待服务端响应的超时时间为100毫秒Timeout: 10 * time.Second, // 客户端等待服务端响应的超时时间为10秒}// 提交http请求resp, err2 := client.Do(req)if err2 != nil {log.Panic(err2)} else {// 成功提交请求且拿到响应后,第一件事就是关闭请求defer resp.Body.Close()// 显示响应内容io.Copy(os.Stdout, resp.Body)for k, v := range resp.Header {fmt.Printf("%s: %v\n", k, v)}fmt.Println(resp.Proto)fmt.Println(resp.Status)}}}func main() {complexHttpRequest()
}
2.3.3 请求测试
2.3.3.1 客户端请求
2.3.3.2 服务端
3. http router
3.1 基本介绍
http router 是 Go语言 中用于处理 HTTP请求 的组件。它能够识别 URL 和 HTTP方法(如GET、POST),并将请求分发到对应的处理函数。
- 下载:go get -u github.com/julienschmidt/httprouter
- Router实现了http.Handler接口。
- 为各种request method提供了便捷的路由方式。
- 支持restful请求方式。
- 支持ServerFiles访问静态文件(如html)。
- 可以自定义捕获panic的方法。
3.2 编辑服务端代码
package mainimport ("fmt""io""net/http""os""github.com/julienschmidt/httprouter"
)func handle(method string, w http.ResponseWriter, r *http.Request) {fmt.Printf("request method: %v\n", r.Method)fmt.Print("request boy: \n")io.Copy(os.Stdout, r.Body)// defer r.Body.Close()// fmt.Fprint(w, "Hello boy")// 或者(上下等价)w.Write([]byte("Hello boy, your request method is " + method))
}func get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("GET", w, r)
}func post(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("POST", w, r)
}func main() {// 定义一个routerrouter := httprouter.New()router.GET("/", get)router.POST("/", post)// 服务启动后监听的端口号http.ListenAndServe(":5656", router)
}
3.3 测试
3.3.1 GET方法测试
3.3.2 POST方法测试
3.4 RESTful风格(POST传参)
3.4.1 服务端代码
package mainimport ("fmt""io""net/http""os""github.com/julienschmidt/httprouter"
)func handle(method string, w http.ResponseWriter, r *http.Request) {fmt.Printf("request method: %v\n", r.Method)// fmt.Print("request boy: \n")io.Copy(os.Stdout, r.Body)// defer r.Body.Close()// fmt.Fprint(w, "Hello boy")// 或者(上下等价)w.Write([]byte("Hello boy, your request method is " + method))
}func get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("GET", w, r)
}func post(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("POST", w, r)
}func main() {// 定义一个routerrouter := httprouter.New()router.GET("/", get)router.POST("/", post)// /user:是我们请求的路径。// :name:占位符,假定为请求时传递的用户名(参数)// :type:占位符,假定为请求时传递的类型(参数)// *addr:占位符,*表示可以匹配多级路径(参数)router.POST("/user/:name/:type/*addr", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {fmt.Printf("name: %v\ntype: %v\naddr: %v", p.ByName("name"), p.ByName("type"), p.ByName("addr"))})// 服务启动后监听的端口号http.ListenAndServe(":5656", router)
}
3.4.2 客户端代码
package mainimport ("fmt""io""log""net/http""os""strings""time"
)func complexHttpRequest() {reader := strings.NewReader("hello server\n")req, err := http.NewRequest("POST", "http://localhost:5656/user/sanhua/vip/shahnghai/changning/GDAS", reader)if err != nil {log.Panic(err)} else {// 增加自定义请求头req.Header.Add("User-Agent", "中国")req.Header.Add("MyHeaderKey", "MyHeaderValue")// 增加自定义Cokkiereq.AddCookie(&http.Cookie{// 传给服务端的信息Name: "auth",Value: "passwd",// 下面这3行信息,主要是作为记录,并不传给服务端Path: "/",Domain: "localhost",Expires: time.Now().Add(time.Duration(time.Hour)),})client := &http.Client{// Timeout: 100 * time.Microsecond, // 客户端等待服务端响应的超时时间为100毫秒Timeout: 10 * time.Second, // 客户端等待服务端响应的超时时间为10秒}// 提交http请求resp, err2 := client.Do(req)if err2 != nil {log.Panic(err2)} else {// 成功提交请求且拿到响应后,第一件事就是关闭请求defer resp.Body.Close()// 显示响应内容io.Copy(os.Stdout, resp.Body)for k, v := range resp.Header {fmt.Printf("%s: %v\n", k, v)}fmt.Println(resp.Proto)fmt.Println(resp.Status)}}}func main() {complexHttpRequest()
}
3.4.3 请求测试
3.4.3.1 客户端
3.4.3.2 服务端
下图可以看到,服务端把客户端请求时的传参,提取出来了。
3.5 指定静态html文件
3.5.1 准备html文件
这是我在网上随便找的一个静态页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>* {margin: 0;padding: 0;}html {height: 100%;}body {height: 100%;}.container {height: 100%;background-image: linear-gradient(to right, #999999, #330867);}.login-wrapper {background-color: bisque;width: 358px;height: 588px;border-radius: 15px;padding: 0 50px;position: relative;left: 50%;top: 50%;transform: translate(-50%,-50%);}.header {font-size: 38px;font-weight: bold;text-align: center;line-height: 200px;}.input-item {display: block;width: 100%;margin-bottom: 20px;border: 0;padding: 10px;border-bottom: 1px solid rgb(128,125,125);font-size: 15px;outline: none;}.input-item::placeholder {text-transform: uppercase;}.btn {text-align: center;padding: 10px;width: 100%;margin-top: 40px;background-image: linear-gradient(to right,#a6c1ee, #fbc2eb);color: #fff;}.msg {text-align: center;line-height: 88px;}a {text-decoration-line: none;color: #abc1ee;}</style>
</head>
<body><div class="container"><div class="login-wrapper"><div class="header">Login</div><div class="form-wrapper"><input type="text" name="username" placeholder="username" class="input-item"><input type="password" name="password" placeholder="password" class="input-item"><div class="btn">Login</div></div><div class="msg">Don't have account?<a href="#">Sign up</a></div></div></div>
</body>
</html>
3.5.2 服务端代码
package mainimport ("fmt""io""net/http""os""github.com/julienschmidt/httprouter"
)func handle(method string, w http.ResponseWriter, r *http.Request) {fmt.Printf("request method: %v\n", r.Method)// fmt.Print("request boy: \n")io.Copy(os.Stdout, r.Body)// defer r.Body.Close()// fmt.Fprint(w, "Hello boy")// 或者(上下等价)w.Write([]byte("Hello boy, your request method is " + method))
}func get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("GET", w, r)
}func post(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("POST", w, r)
}func main() {// 定义一个routerrouter := httprouter.New()router.GET("/", get)router.POST("/", post)// 请求/file路径,服务端就会去static目录下读取a.html文件中的内容router.ServeFiles("/file/*filepath", http.Dir("D:/个人/GO开发/20240624/static"))// 服务启动后监听的端口号http.ListenAndServe(":5656", router)
}
3.5.3 请求测试
3.6 错误处理
在实际工作中,可能会有很多路由规则,在任何一处都有可能会报错,所以需要定义一个统一的告警处理。
3.6.1 服务端代码
package mainimport ("fmt""io""net/http""os""github.com/julienschmidt/httprouter"
)func handle(method string, w http.ResponseWriter, r *http.Request) {fmt.Printf("request method: %v\n", r.Method)// fmt.Print("request boy: \n")io.Copy(os.Stdout, r.Body)// defer r.Body.Close()// fmt.Fprint(w, "Hello boy")// 或者(上下等价)w.Write([]byte("Hello boy, your request method is " + method))
}func get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("GET", w, r)// 手动定义一个数组超界的异常,触发panicvar arr []int_ = arr[1]
}func post(w http.ResponseWriter, r *http.Request, params httprouter.Params) {handle("POST", w, r)
}func main() {// 定义一个routerrouter := httprouter.New()// 错误处理router.PanicHandler = func(w http.ResponseWriter, r *http.Request, i interface{}) {fmt.Fprintf(w, "server panic %v", i)}router.GET("/", get)router.POST("/", post)// 服务启动后监听的端口号http.ListenAndServe(":5656", router)
}
3.6.2 请求测试
相关文章:

Go 1.19.4 HTTP编程-Day 20
1. HTTP协议 1.1 基本介绍 HTTP协议又称超文本传输协议,属于应用层协议,在传输层使用TCP协议。HTTP协议属是无状态的,对事务处理没有记忆能力,如果需要保存状态需要引用其他技术,如Cookie。HTTP协议属是无连接的&…...

MySQL 8.0 的主主复制(双向复制)
在 Windows Server 2022 Datacenter 上配置 MySQL 8.0 的主主复制(双向复制),步骤与 Linux 类似,但有一些特定的配置和路径需要注意。以下是详细的简化步骤: 1. 使用 root 用户登录 确保你以 root 用户登录到 MySQL …...

四、自然语言处理_03LSTM与GRU
0、前言 随着循环神经网络(RNN)在各种序列数据处理任务中被广泛应用,研究人员逐渐发现了其在处理长序列数据时会容易出现梯度消失(vanishing gradient)和梯度爆炸(exploding gradient)问题&…...

磁盘系列基础知识(一):硬盘;IDE;ATA;SATA;AHCI;SCSI;SAS
磁盘系列基础知识(一)硬盘 IDE ATA SATA AHCI SCSI SAS 硬盘厂家 西部数据Western Digital/WD. 希捷 SEAGATE、三星 SAMSUNG、东之 Toshiba、英特尔 Intel、金士顿 Kingston、闪迪 SanDisk、 英睿达 Crucial、浦科特 Plextor 硬盘类别 HDD (…...

taro小程序进入腾讯验证码
接入原因 昨天突然晚上有人刷我们公司的登录发送短信接口,紧急将小程序的验证码校验更新上去了 接下来就是我们的接入方法,其实很简单,不过有时候可能大家着急就没有仔细看文档,腾讯验证码文档微信小程序地址,注意这里…...

原子类相关
原子引用 JUC 并发包提供了: AtomicReferenceAtomicMarkableReferenceAtomicStampedReference AtomicReference 使用举例 public interface DecimalAccount {// 获取余额BigDecimal getBalance();// 取款void withdraw(BigDecimal amount);/*** 方法内会启动 10…...

RabbitMQ 客户端 连接、发送、接收处理消息
RabbitMQ 客户端 连接、发送、接收处理消息 一. RabbitMQ 的机制跟 Tcp、Udp、Http 这种还不太一样 RabbitMQ 服务,不是像其他服务器一样,负责逻辑处理,然后转发给客户端 而是所有客户端想要向 RabbitMQ服务发送消息, 第一步&a…...

Java Web 3 Axios Vue组件库
一 Ajax 1 同步 异步 2 原生Ajax 比较繁琐 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Documen…...

双目相机的标定,视差图,深度图,点云生成思路与实现。
该文档记录从双目相机标定到点云生成的所有过程,同时会附上代码。 代码直接能跑。https://github.com/stu-yzZ/stereoCamera 目录 大致思路如下: 一、相机标定 1、相机参数介绍 2、单目相机标定 3、双目相机标定 二、图片畸变矫正 三、极线矫正…...

【H2O2|全栈】MySQL的基本操作(三)
目录 前言 开篇语 准备工作 案例准备 多表查询 笛卡尔积 等值连接 外连接 内连接 自连接 子查询 存在和所有 含于 分页查询 建表语句 结束语 前言 开篇语 本篇继续讲解MySQL的一些基础的操作——数据字段的查询中的多表查询和分页查询,与单表查询…...

2、C++命名空间
命名空间 命名空间是一种用来避免命名冲突的机制; 原理是将一个全局的作用域分成一个个命名空间,每个命名空间是个单独的作用域,从而有效避免命名冲突。 注意:命名空间定义在全局 命名空间定义格式 使用: …...

Elemenu-UI时间日期单个组件,限制当前日期之后的时间
element的时间日期组件, type"datetime" ,当你设置了:picker-options"pickerOptions"之后 pickerOptions: { disabledDate(time) { return time.getTime() > Date.now(); }, }, 会发现,他只会限制日期,但不…...

flutter修改状态栏学习
在flutter中如何动态更改状态栏的颜色和风格。 前置知识点学习 AnnotatedRegion AnnotatedRegion 是 Flutter 中的一个小部件,用于在特定区域中提供元数据(metadata)以影响某些系统级的行为或外观。它通常用于改变系统 UI 的外观ÿ…...

解决Unity编辑器Inspector视图中文注释乱码
1.问题介绍 新创建一个脚本,用VS打开编辑,增加一行中文注释保存,在Unity中找到该脚本并选中,Inspector视图中预览的显示内容,该中文注释显示为乱码,如下图所示: 2.图示解决步骤 按上述步骤操作…...

关于csgo的游戏作弊与封禁
关于csgo的游戏作弊与封禁 一.关于作弊 什么叫作弊? 1.换肤,换库存 2.各种参(回溯,自瞄,透视,急停,连跳,假身,子弹跟踪等) 3.某一部分更改游戏内存&…...

严格单元测试造就安全软件
在信息技术迅速发展的今天,软件在各个行业中扮演着至关重要的角色,尤其是在汽车行业,其中软件的可靠性和安全性直接影响到人们的生命安全。软件缺陷所带来的潜在风险不容小觑,尤其在涉及到自动驾驶和车辆控制等关键系统时…...

ubuntu 根分区逻辑卷扩容
1、虚拟机关机通过管理界面给磁盘扩容。 rootcurtis:/home/curtis/git_code# pvdisplay--- Physical volume ---PV Name /dev/vda3VG Name ubuntu-vgPV Size <239.00 GiB / not usable 0Allocatable yes (but full)PE…...

如何查看电脑生产日期
查看电脑的生产日期通常可以通过以下方法实现,具体方式取决于操作系统和电脑类型: 方法 1:检查电脑 BIOS 生产日期通常记录在 BIOS 中。可以通过以下步骤查看: 重启电脑并进入 BIOS: 启动时按下特定的键(…...

MAC M1 mysql 8.0 如何修改root用户密码
关闭mysql服务 使用brew方式安装,可以通过一下命令关闭 brew services stop mysql使用安装包安装的方式 可以选择🍎->系统偏好设置->最下方单机MySQL图标->stop mysql server 启动 MySQL 到安全模式 sudo mysqld_safe --skip-grant-tables …...

漫画之家系统:Spring Boot框架下的漫画版权保护
摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&a…...

在 MacOS 上为 LM Studio 更换镜像源
在 MacOS 之中使用 LM Studio 部署本地 LLM时,用户可能会遇到无法下载模型的问题。 一般的解决方法是在 huggingface.co 或者国内的镜像站 hf-mirror.com 的项目介绍卡页面下载模型后拖入 LM Studio 的模型文件夹。这样无法利用 LM Studio 本身的搜索功能。 本文将…...

Nginx配置https(Ubuntu、Debian、Linux、麒麟)
Ubuntu操作系统,Debian系统底层是Ubuntu,差异不大 ubuntu 安装nginx 1.安装依赖 sudo apt-get update sudo apt-get install gcc sudo apt-get install libpcre3 libpcre3-dev sudo apt-get install zlib1g zlib1g-dev sudo apt-get install openssl lib…...

「Mac畅玩鸿蒙与硬件40」UI互动应用篇17 - 照片墙布局
本篇将带你实现一个简单的照片墙布局应用,通过展示多张图片组成照片墙效果,用户可以点击图片查看其状态变化。 关键词 UI互动应用照片墙布局Grid 布局动态图片加载用户交互 一、功能说明 照片墙布局应用的特点: 动态加载多张图片组成网格布…...

VMware Workstation 安装Ubuntu 系统(图文步骤)
之前一直在讲Ubuntu Linux的用户和组 链接: Linux专栏 今天来讲讲Ubuntu 系统基础的安装步骤!!! 废话少说,马上开始! 文章目录 前言准备安装环境先下载Ubuntu 镜像 详细安装步骤如下新建虚拟机默认使用 15.…...

mybatis用pagehelper 然后用CountJSqlParser45,发现自己手写的mapper查询效率很慢
如题 效率慢疑惑 效率慢 分页查询,发现效率很慢,然后发现是比较复杂的sql,CountJSqlParser45它不会帮忙优化掉,就是select多少字段它count的时候也还是这么多字段 框架里的用法是这样的 所以去看了CountJSqlParser45里面的代码,发现如果有group之类的,它就不帮忙把count优化…...

【优选算法 二分查找】二分查找入门详解:二分查找 & 在排序数组中查找元素的第一个和最后一个位置
二分查找 题目描述 题目解析 暴力解法 我们可以从左往右遍历一次数组,如果存在 target 则返回数组的下标,否则返回 -1; 时间复杂度 O(N),因为没有利用数组有序的特点,每次比较只能舍弃一个要比较的数&…...

WPF编写工业相机镜头选型程序
该程序满足面阵和线阵的要求。 前端代码 <Window x:Class"相机镜头选型.MainWindow" Loaded"Window_Loaded"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml…...

网络安全内容整理二
网络嗅探技术 网络监听 网络监听,也称网络嗅探(Network Sniffing):在他方未察觉的情况下捕获其通信报文、通信内容的技术 网卡的工作模式: 1.广播模式(Broadcast Mode):网卡能够接收网络中的广播信息 2.组播模式(Multicast Mo…...

解决git did not exit cleanly (exit code 128)问题
解决 git did not exit cleanly (exit code 128)问题 1、错误描述2、解决方法2.1 方法一2.2 方法二 1、错误描述 使用TortoiseGit进行操作时,总是提示下述错误。 2、解决方法 2.1 方法一 打开 TortoiseGit -> Settings 点击 Network&…...

Linux入门攻坚——40、Linux集群系统入门-lvs(1)
Cluster,集群,为了解决某个特定问题将多台计算机组合起来形成的单个系统。 这个单个集群系统可以扩展,系统扩展的方式:scale up,向上扩展,更换更好的主机;scale out,向外扩展&…...