Go红队开发—web网络编程
文章目录
- web网络编程
- Req
- 快速请求
- 调试
- DevMode
- DebugLog
- TraceInfo瓶颈分析
- 控制请求与响应
- 控制请求的字段内容
- 控制调试打印的内容
- 分开dump请求与响应部分
- 请求体设置
- 作用范围级别
- 设置参数查询
- URL 路径参数
- 表单请求设置
- 请求头设置
- 判断响应状态码
- 解析数据
- SetSuccessResult
- gjson
- 响应数据解析练习
- Cookie
- 默认行为
- 禁⽤Cookie
- 存储Cookie
- 证书校验
- 无视风险
- 配置证书
- Auth身份认证
- 文件上传下载
- 上传文件
- 下载文件
- 多线程下载练习
web网络编程
tips:这一章的铺垫比较重要,这章过后就是一些安全工具如何编写以及一些poc、exp的工具编写。
Req
简单的请求
- 客户端创建
- 请求设置
func reqHttp() {client := req.C() //客户端创建res, err := client.R(). //请求设置,这个点的意思链式调用,后续在控制请求中会讲Get("https://httpbin.org/uuid")if err != nil {log.Println("请求失败:", err)}fmt.Println(res)}
快速请求
- MustGet
测试使用可以,正式开发不建议使用,可控性差
// 快速使用,一般用在test的时候func testHttp() {resp := req.MustGet("https://httpbin.org/uuid") //这里就是发起了一次请求fmt.Println(resp.String()) //第一种打印*req.Response类型的响应体fmt.Println(string(resp.Bytes())) //第二种打印*req.Response类型的响应体}
调试
DevMode
DevMode是直接开启全局调试,自动打印出来
// 调试模式func devModeReq() {//使用req进行请求,所以req的调试模式也是在req启动req.DevMode() //开启调试模式,就会打印出来请求的过程以及响应内容req.SetCommonBasicAuth("username", "password"). //设置用户名和密码SetTimeout(5 * time.Second). //设置超时时间SetUserAgent("my-ua")resp := req.MustGet("https://httpbin.org/uuid")//没有开启调试模式但是想打印的话就正常打印fmt.Println(resp.String()) //第一种打印*req.Response类型的响应体fmt.Println(string(resp.Bytes())) //第二种打印*req.Response类型的响应体}
DebugLog
DebugLog 是跟踪请求的过程
他可以看到你整个请求的过程,重定向的信息等等
// 查看请求的过程发生了什么func deLog() {client := req.C().EnableDebugLog() //开启DebugLogclient.R().Get("http://baidu.com/s?wd=req")}
TraceInfo瓶颈分析
trace跟踪信息
func traceReq() {// Enable trace at request levelclient := req.C()resp, err := client.R().EnableTrace(). //开启瓶颈分析Get("https://api.github.com/users/imroc")if err != nil {log.Fatal(err)}trace := resp.TraceInfo() //trace跟踪信息fmt.Println(trace.Blame()) //分析总结(请求减慢的原因归咎)fmt.Println(trace) // 打印内容}
控制请求与响应
控制请求的字段内容
这里做一个了解,后面会详细说一下作用范围,这里就过一遍即可,知道哪些字段可控(其实都可控)
func controlReq() {client := req.C().SetUserAgent("my-ua"). //设置ua头,在client中设置,在下面的R()中设置不了//EnableDumpAllToFile("log.txt") //将请求的信息写到该文件中//捕获请求和响应,// 想要看的更加详细就可以开启dump所有内容,// 就能够看到我们是不是真的改变了请求内容EnableDumpAll()parms := map[string]string{"a": "123","b": "hello",}resp, err := client.R(). //拿到请求体SetPathParam("usernamae", "imroc"). //设置请求路径,用username作为占位符SetPathParam("xxx", "test"). //再次设置,用xxx作为占位符SetQueryParam("a", "12"). //设置请求参数,a=12SetQueryParams(parms). //用map来作为请求参数,用于多个参数的时候SetHeader("mycookie", "test"). //设置请求头SetHeader("mysession", "test2"). //设置请求头SetBody("body=world"). //设置请求体Get("https://httpbin.org/uuid")//以上设置暂时在初期阶段够用了。if err != nil {log.Println("请求出错:", err)}fmt.Println(resp)}
控制调试打印的内容
- SetCommonDumpOptions:控制输出的内容
- EnableDumpAllToFile:dump到文件中
输出的log2.txt文件内容如下
// 控制调试打印的内容// 全局应用func controlDevOptions() {client := req.C()opt := &req.DumpOptions{Output: os.Stdout, //标准输出RequestHeader: false, //不输出请求头RequestBody: false, //不输出请求体ResponseHeader: true, //输出响应头ResponseBody: true, //输出响应体Async: false, //不进行异步输出}client.SetCommonDumpOptions(opt).EnableDumpAllToFile("log2.txt")client.R().Get("https://httpbin.org/uuid")}
分开dump请求与响应部分
var bufReq, bufResp bytes.Buffer
:需要用变量来接收请求与响应不同部分- SetDumpOptions:控制dump导出部分
// 分别打印请求与响应部分// 在R中控制调试打印的内容,只作用与本次R请求,与上面的client直接全局设置的不同func controlReqRespOutPut() {client := req.C()var bufReq, bufResp bytes.Bufferclient.R().// 不开启的话就会导致无法转储出去单独打印请求体响应体EnableDump(). //EnableDump启用转储,包括请求和响应的所有内容。SetDumpOptions(&req.DumpOptions{RequestOutput: &bufReq, //将请求体输出到这里ResponseOutput: &bufResp, //将响应体输出到这里RequestHeader: true,RequestBody: true,ResponseHeader: true,ResponseBody: true,}).SetBody("body=hello+world!").Get("https://httpbin.org/uuid")fmt.Println("请求体")fmt.Println(bufReq.String())fmt.Println("响应体")fmt.Println(bufResp.String())}
请求体设置
SetBody 可以接受任意类型
PS: EnableDumpAllWithoutResponse
因为开启了调试模式,所以会打印很多东西,但是可以忽略响应打印出来结果,所以这函数就是忽略响应结果,只看请求。
在编写一些poc/exp的时候可能需要在body部分,需要加入一些结构体或者map数据,他会根据你设置的content-type来判断解析成json还是xml格式,如果都不设置的话他会默认将这些类型解析为json数据body。
添加上content-type类型后就自动转了,比较方便(后面还有更方便的)
- SetBodyXXX
不用设置content-type也能直接转想要的格式了
以下是代码:
// 设置请求体中的一些骚姿势func setbodyHttp() {type test struct {Name stringAge int}t := test{Name: "zhangsan",Age: 123,}client := req.C().DevMode().EnableDumpAllWithoutResponse()client.R().SetBody(t).SetContentType("application/xml").Get("https://httpbin.org/uuid")client2 := req.C().DevMode().EnableDumpAllWithoutResponse()client2.R().SetBodyXmlMarshal(t).Get("https://httpbin.org/uuid")}
作用范围级别
在设置请求参数的时候,有分两种作用范围设置,一种全局(客户端级别),另一种就是只作用与这一个client的对象(请求级别)。
以下就尽量快速过为妙,上面学的时候已经有很多函数都用过了,没必要花太多时间,知道即可,下面作为一个知识字典,以后方便查阅。
请记住:
用req.C().R()来设置的请求级别
用req.C()来设置的是全局级别(也即客户端级别client)
设置参数查询
请求级别:
- SetQueryParam:
SetQueryParam("test", "123")
即 httpxxx?test=123
设置多个的时候仅仅对最后一个设置的生效 - SetQueryParams:SetQueryParams接收map类型设置多个变量,由于map的键唯一,所以多个同名的话也只会作用一个。
- SetQueryString:直接给查询参数即可,
SetQueryString("test1=123&test2=456")
这个不会产生什么重复覆盖问题,字符串给啥他就拼接到你url中去 - AddQueryParam:
AddQueryParam("key", "value1")
如果该参数已存在,它不会覆盖原有的值,这个一般用在你临时需要添加什么查询参数的时候可以用,而且不会覆盖原有的同名键值
全局级别:
- SetCommonQueryParam
- SetCommonQueryParams
- SetCommonQueryString
- AddCommonQueryParam
URL 路径参数
请求级别:
- SetPathParam:
SetPathParam("username", "zhangsan")
- SetPathParams:接收map类型
全局级别:
- SetCommonPathParam
- SetCommonPathParams
表单请求设置
请求级别:
- SetFormData:接收map类型,但是同一个键只能有一个
- SetFormDataFromValues::
代码如下所示,但是注意的是url.Values是net/url包,所以要注意这个url不是我定义的,拿来就用即可。
client3 := req.C().DevMode().EnableDumpAllWithoutResponse()v := url.Values{"p": []string{"hello", "world", "!"},
}
client3.R().SetFormDataFromValues(v).Post("https://httpbin.org/post")
- multipart ⽅式提交表单:
EnableForceMultipart
client3 := req.C().DevMode().EnableDumpAllWithoutResponse()
v := url.Values{"p": []string{"hello", "world", "!"},
}
client3.R().EnableForceMultipart().SetFormDataFromValues(v).Post("https://httpbin.org/post")
全局级别:
- SetCommonFormData
- SetCommonFormDataFromValues
请求头设置
请求级别:
- SetHeader:自动将你传进的header键的首字母大写
- SetHeaders:接收map类型,自动将你传进的header键的首字母大写
- SetHeaderNonCanonical:你给什么样就输出什么样,不会自动给你首字母大写
- SetHeadersNonCanonical:你给什么样就输出什么样,不会自动给你首字母大写
- SetHeaderOrder:控制header的顺序,因为有的服务端可能会对header的顺序判断是否允许请求,设置了SetHeaderOrder,他就会按照你给定的顺序进行排序请求过去。
request.SetHeaderOrder( "cookie", "ssession", "test","ua",
)
全局级别
- SetCommonHeaderNonCanonical
- SetCommonHeadersNonCanonical
判断响应状态码
没啥好说的,都到这了这些应该对于各位师傅来说都是一眼就学会的基操了。
- resp.IsSuccessState
- resp.IsErrorState
- resp.StatusCode
// 判断响应状态码func judgeStatusCode() {client := req.C()resp, err := client.R().Get("http://www.baidu.com")if err != nil {log.Println("请求失败:", err)}if resp.IsSuccessState() {fmt.Println("ok")}if resp.IsErrorState() {fmt.Println("error")}//可以通过响应对应的代码判断if resp.StatusCode != http.StatusOK { //http有一个const变量,里面有很多对应的响应码,自行查看即可(文件:http\status.go)fmt.Println("error")}//打印响应体fmt.Println(resp.Bytes()) //bytes打印fmt.Println(resp.String()) //string打印}
解析数据
SetSuccessResult
-
SetSuccessResult:SetSuccessResult会⾃动解析你给的结构体或map
-
SetErrorResult
这里一同把SetErrorResult也讲了,可以自定义错误解析到你自己定义的错误中去,没啥好说感觉也时,定义好了就直接给到SetErrorResult即可(详细见代码处)
运行结果如下图所示:
// 接收响应回来的json数据type user struct {Login string `json:login`Id int `json:id`Name string `json:name`}// 接收错误响应type errorResp struct {Mess string `json:message`}// 解析响应的json数据// SetSuccessResult⾃动解析结构体或mapfunc getHttpJson() {client := req.C()var respUser uservar respError errorRespres, err := client.R().SetSuccessResult(&respUser). //接收响应回来的json数据,同时也可以解析mapSetErrorResult(&respError). //若请求错误将错误信息存储到该结构体中Get("https://api.github.com/users/whoisdhan")if err != nil {log.Println("代码请求出错:", err)return}if res.IsSuccessState() {fmt.Println("请求成功")fmt.Println(respUser.Login)fmt.Println(respUser.Id)fmt.Println(respUser.Name)} else if res.IsErrorState() {fmt.Println("网络请求出错:", respError.Mess)} else {fmt.Println("未知错误:", res.StatusCode)}}
gjson
字段名
、.
:表示读取该字段,字段名.0
表示读取该键名下的数据的第一个字段,字段名.1
读取第二个*
、?
:gjson支持通配符:像在linux命令行中使用的通配符那样用就行,a*a
收尾为a的都匹配#
:表示该字段所有元素。- 在结尾:
字段名1.字段名2.#
表示返回字段名2的数组长度 - 在中间,即
#
后面还有内容:字段名1.#.字段名2
表示返回字段名2所有元素 - 原因:这也是为啥我叫他
#
的意思是表示该字段所有元素,在结尾就是返回长度,不在就是返回整个数组列表
- 在结尾:
gjson解析json数据可提取指定字段,不用定义结构体
gjson非常适合提取几个字段出来之类的,方便的一笔。
// 由于我们的http请求回来的数据能方便的转为string所以也能用gjson// 模拟数据const httpjson = `{"name":{"first":"Tom", "last": "Anderson"},"age": 37,"children": ["Sara", "Alex", "Jack"],"fav.movie": "Dear Hunter","friends": [{"first": "Dale", "last":"Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}]}`func gjsonHttp() {//先简单用正常的httpjson数据尝试一下client := req.C()resp, _ := client.R().Get("https://api.github.com/users/whoisdhan")login := gjson.Get(resp.String(), "login")id := gjson.Get(resp.String(), "id")name := gjson.Get(resp.String(), "name")fmt.Println(login, id, name)//用httpjson测试数据fmt.Println(gjson.Get(httpjson, "name.first"))fmt.Println(gjson.Get(httpjson, "friends.#.first"))fmt.Println(gjson.Get(httpjson, "friends.#.nets"))fmt.Println(gjson.Get(httpjson, "fav\\.movie")) //字段存在符号的话用\\转义}
响应数据解析练习
这里的解析可能有点主观了,可以按照自己的想法,尽量不要被我带偏,我的不一定是最佳的
// 练习
// 1. 获取⽤户信息 https://api.github.com/users/{username}
// 2. 获取仓库列表信息 https://api.github.com/users/{username}/repos
// 3. 用户与仓库列表信息:普通读取json、Unmarshal转结构体⽅式解析、gjson读取
// 4. 用户与仓库列表信息:格式化输出到控制台
// 5. 仓库列表信息保存到本地 JSON ⽂件中。
//这里就固定拿仓库列表信息如下信息:
// (也可以随便获取你想要的字段)
// 用户信息{login、id、url、name、email}
// 仓库列表信息{name、owner.login、description}
- myMarshalIndent:为了方便格式化,我自己写了一个格式化函数方便不同方式保存的时候进行格式化
格式化都需要先转到map中存储才能够格式化正常的json数据出来,格式化好了就任意你想干啥就干啥了 - 需要注意的细节:
有的json他是列表包裹着[]
,所以转的时候要注意判断用map[string]interface{}
还是[]map[string]interface{}
- json.MarshalIndent:他可以对map列表进行格式化的,因为那样也时一个正常的json数据,只不过你需要用
[]map[string]interface{}
列表类型进行存储(这里是一个很重要的细节,开发过程中如果不注意很容易导致崩溃)
我用了三个函数完成这个练习:
- normalGetJson:普通读取,就是解析出来后整个data就直接write到文件中
- UnmarshalToStruct:Unmarshal转结构体⽅式解析,这里使用了上面学到的
SetSuccessResult
,给到结构体后进行解析,这样也很方便 - gjsonOutput:这里就是使用gjson了,gjson很方便,但是面对比较多字段提取的时候还是比较繁琐。
这里复习了一个细节:map想要后续不断地赋值的话就需要进行make空间出来才行,如果是[]map的话需要给定一个空间范围,0也行,你要说明这是一个切片。如果你只是单单定义一个map变量或者map切片变量,后续是无法使用的。
还有一个细节就是:make出来的空间是固定的,如果你要make出来的空间作为一个临时变量赋值给其他变量的时候要注意了,用了一个空间就不要继续用了,因为你将一个空间给了多个变量的话,那么那些变量都指向你这一个空间,那么他们的值其实都一样。
运行结果:这里就放几个保存出来的文件截图
-
normalGetJson:
-
UnmarshalToStruct
-
gjsonOutput
示例代码:
// 用户信息{login、id、url、name、email}// 仓库列表信息{name、owner.login、description}func gjsonOutput(username string) {//gjson就十分简单了,只需要拿到响应json数据即可取出来看mapUserData := make(map[string]interface{}) //用户信息存储//仓库信息存储,// 由于仓库是数组列表所以要给一个初始长度// 因为可能仓库为空的,所以就初始化为0即可mapReposData := make([]map[string]interface{}, 0)fmt.Println("-------------------用户信息-------------------")client := req.C()resp, err := client.R().SetPathParam("username", username).Get("https://api.github.com/users/{username}")if err != nil {log.Println("代码请求失败:", err)}//gjson想要写入文件就只能转储到struct或者map中mapUserData["login"] = gjson.Get(resp.String(), "login").String()mapUserData["id"] = gjson.Get(resp.String(), "id").String()mapUserData["url"] = gjson.Get(resp.String(), "url").String()mapUserData["name"] = gjson.Get(resp.String(), "name").String()mapUserData["email"] = gjson.Get(resp.String(), "email").String()data, err := json.MarshalIndent(mapUserData, "", "\t")if err != nil {log.Println("格式化失败:", err)}fmt.Println(string(data))// test := gjson.Get(resp.String(), "login")// fmt.Println(test)fmt.Println("---------------------------------------------")fmt.Println("-------------------仓库信息-------------------")client = req.C()resp, err = client.R().SetPathParam("username", username).Get("https://api.github.com/users/{username}/repos")if err != nil {log.Println("代码请求失败:", err)}// 仓库列表信息{name、owner.login、description}arr := gjson.Get(resp.String(), "#.name")for i, j := range arr.Array() {//一定要放到这里来,因为make指向同一个空间,// 如果你在for外面定义mapTmpRepos造成取到的值会全部变成最后一个值,// 因为同一个空间他会同步改变你map切片append里面所有的内容,// 因为同一个空间嘛mapTmpRepos := make(map[string]interface{})mapTmpRepos["name"] = j.String()mapTmpRepos["login"] = gjson.Get(resp.String(), (strconv.Itoa(i) + ".owner.login")).String()mapTmpRepos["description"] = gjson.Get(resp.String(), (strconv.Itoa(i) + ".description")).String()mapReposData = append(mapReposData, mapTmpRepos)}data, err = json.MarshalIndent(mapReposData, "", "\t")if err != nil {fmt.Println("格式化失败:", err)}fmt.Println(string(data)) //格式化的内容打印到终端file, err := os.OpenFile("gjson.json", os.O_CREATE|os.O_RDWR|os.O_RDWR, 0666)if err != nil {log.Println("打开文件失败:", err)}_, err = file.Write(data)if err != nil {log.Println("导出json失败:", err)}}
Cookie
请求级别:
- SetCookies
SetCookies(&http.Cookie{Name: "hacker",Value: "aaa",
})
全局级别:
- SetCommonCookies
SetCommonCookies(&http.Cookie{Name: "Global",Value: "dddd",
})
默认行为
就是当你请求的服务端响应了set-cookie回来后,当你再次请求的时候就会携带上这个set-cookie回来的cookie键值去请求。
禁⽤Cookie
- SetCookieJar(nil)
存储Cookie
安装
go get -u github.com/juju/persistent-cookiejar
使用
func saveCookies() {jar, err := cookiejar.New(&cookiejar.Options{Filename: "cookies.json",})if err != nil {log.Println("保存失败")}defer jar.Save()client := req.C().SetCookieJar(jar).DevMode()client.R().Get("http://www.baidu.com")}
证书校验
无视风险
针对一些不安全的网站请求可能会请求失败,所以需要忽略证书的校验
两种方式可以忽略:
client := req.C().DevMode().EnableDumpAllWithoutResponse()
//忽略证书风险
//第一种
//client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
//第二种
client.TLSClientConfig.InsecureSkipVerify = true
_, err := client.R().Get("https://self-signed.badssl.com/")
if err != nil {fmt.Println("代码请求失败:", err)
}
配置证书
配置好风险站点的证书即可访问风险站点
证书需要访问网站的时候在浏览器的小锁中下载即可(具体不演示了,自行百度网站证书如何下载)
- 证书文件配置
client := req.C().DevMode().EnableDumpAllWithoutResponse()
//可以同时配置多个网站的证书
client.SetRootCertsFromFile("cert1.crt","cert2.crt","cert3.crt")
- 证书内容配置
在下载了证书之后,可以编辑证书将里面的内容配置进来也行
client := req.C().DevMode().EnableDumpAllWithoutResponse()
client.SetRootCertFromString("-----BEGIN CERTIFICATE-----")
Auth身份认证
- SetBasicAuth
- SetDigestAuth
区别:
一个Basic认证,一个Digest认证
Digest认证比较安全,请求被拦截了攻击者无法直接获取密码
但是Basic的请求被拦截了就是直接获取到密码
服务端支持哪一个?
检查WWW-Authenticate
响应头,返回Basic 还是 Digest就知道支持哪一个。
func authHttp() {client := req.C().DevMode().EnableDumpAllWithoutResponse()client.R().SetBasicAuth("username", "password").Get("https://httpbin.org/uuid")client2 := req.C().DevMode().EnableDumpAllWithoutResponse()client2.R().SetDigestAuth("username2", "password2").Get("https://httpbin.org/uuid")}
文件上传下载
上传文件
- SetFile
- SetFiles:接收map类型,上传多个文件
- SetUploadCallback:显示上传进度
func uploadFileHttp() {//简单上传client := req.C().DevMode().EnableDumpAllWithoutResponse()callback := func(info req.UploadInfo) { //显示上传进度fmt.Printf("\n文件名:%q\n已上传:%.2f%%\n",info.FileName,float64(info.UploadedSize)/float64(info.FileSize)*100.0)}client.R().//SetFile("filename", "cookies.json").SetFiles(map[string]string{"test": "test.txt","test2": "test2.txt","test3": "test3.txt",}).SetUploadCallback(callback). //使用该函数:显示上传进度Post("https://httpbin.org/post")}
下载文件
- SetOutputFile:这里是指定下载的文件路径
- SetOutputDirectory:设置下载的默认路径,即SetOutputFile可以只给文件名,自动存在该路径下
- SetDownloadCallback:显示下载进度
func downloadFileHttp() {client := req.C() //.DevMode().EnableDumpAllWithoutResponse()callback := func(info req.DownloadInfo) {if info.Response.Response != nil { //响应不为空fmt.Printf("\n已下载:%.2f%%\n",float64(info.DownloadedSize)/float64(info.Response.ContentLength)*100.0)}} client.R().//这里是指定文件路径SetOutputFile("./baidu.html").Get("http://127.0.0.1/xxx.txt")client2 := req.C().//这里可以设置默认下载目录,后面直接download的时候就不用指定路径了,给文件名即可SetOutputDirectory("./").DevMode().EnableDumpAllWithoutResponse()client2.R().SetOutputFile("baidu2.html").SetDownloadCallback(callback).Get("http://127.0.0.1/xxx.txt")}
多线程下载练习
- NewParallelDownload:创建一个多线程下载客户端
- 其他函数在注释中标明了。
func threatDownload() {client := req.C()err := client.NewParallelDownload("http://xxxxx.xxxx.xxx/xxx.iso").SetConcurrency(5). //设置 5 个线程 并行下载SetFileMode(0777). //设置 文件权限(可读可写可执行)。SetOutputFile("xxx.iso"). //设定最终 存储文件名SetSegmentSize(1024 * 1024 * 5). //每个线程下载 5MB 的数据块SetTempRootDir("./tmp"). //这个是下载的时候指定的临时存储目录Do()if err != nil {log.Println("下载失败:", err)return}}
相关文章:
Go红队开发—web网络编程
文章目录 web网络编程Req快速请求 调试DevModeDebugLogTraceInfo瓶颈分析 控制请求与响应控制请求的字段内容控制调试打印的内容分开dump请求与响应部分请求体设置 作用范围级别设置参数查询URL 路径参数表单请求设置请求头设置 判断响应状态码解析数据SetSuccessResultgjson响…...
ollama不安装到c盘,安装到其他盘
ollama 安装包默认安装到c盘,安装程序并没有提供选择文件夹安装功能,本来c盘就快满了,下几个模型c盘都快爆了,如何将ollma安装到其他盘呢? ollama 默认安装位置 C:\Users\Admin\.ollama 是 Ollama 用来放大模型的文件夹…...
【HTML】一、基础标签
文章目录 1、开发环境准备2、html介绍3、html基本骨架4、标签的关系5、常用标签5.1 标题5.2 段落5.3 换行与水平线5.4 文本格式化标签5.5 图像标签5.6 超链接标签5.7 音频标签5.8 视频标签 6、路径7、网页制作 1、开发环境准备 在编辑器中写代码,在浏览器中看效果 …...
NPU、边缘计算与算力都是什么啊?
考虑到灵活性和经济性,公司购置一台边缘计算机,正在尝试将PCGPU的计算机视觉项目转到边缘计算机NPU上。本文简单整理了三个概念,并试图将其做个概要的说明。 一、算力:数字世界的“基础能源” 1.1 算力是什么 **算力(…...
spring声明式事务原理01-调用第1层@Transactional方法(事务访问入口)
文章目录 【README】【步骤1】UserAppService调用userSupport.saveNewUser()【步骤2】获取到TransactionInterceptor【步骤3】chain不为空,接着执行CglibMethodInvocation#proceed方法【补充】AopContext作用 【步骤4】CglibMethodInvocation#proceed方法【步骤5】调…...
[MoeCTF 2021]babyRCE
打开题目在线环境可以看到: <?php$rce $_GET[rce]; if (isset($rce)) {if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\|\%|\>|\<|\|\"/i", $rce)) {system($rce);}else {echo "hhhhhhacke…...
【leetcode hot 100 114】二叉树展开为链表
解法一:执行一次先序遍历,把元素放入list中,然后放回root中 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { th…...
嵌入式八股,为什么单片机中不使用malloc函数
1. 资源限制 单片机的内存资源通常非常有限,尤其是RAM的大小可能只有几KB到几十KB。在这种情况下,使用 malloc 进行动态内存分配可能会导致内存碎片化,使得程序在运行过程中逐渐耗尽可用内存。 2. 内存碎片问题 malloc 函数在分配和释放内…...
基于Python的selenium入门超详细教程(第1章)--WebDriver API篇
学习路线 自动化测试介绍及学习路线-CSDN博客 自动化测试之Web自动化(基于pythonselenium)-CSDN博客 参照博文:selenium入门超详细教程——网页自动化操作-CSDN博客 目录 前言 一、WebDriver API介绍 1.1 什么是WebDriver? 1.2 工…...
IIC通信协议详解与STM32实战指南
IIC通信协议详解与STM32实战指南 引言 IIC(Inter-Integrated Circuit)是Philips公司开发的串行通信协议,广泛应用于传感器、EEPROM、RTC等低速外设的连接。本文深入解析IIC协议原理,并提供基于STM32的GPIO模拟实现方案ÿ…...
【算法】数组、链表、栈、队列、树
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 持续更新中...数组、链表点击消除环形链表环形链表 II 栈、队列树 持续更新中… 数组、链表 点击消除 AB5 点击消除 这个题很容…...
vscode 配置golang开发环境
vscode 配置golang开发环境 在go1.20环境中需要指定工具的安装版本 go install golang.org/x/tools/goplsv0.15.3 go install github.com/go-delve/delve/cmd/dlvv1.21.0使用go Install/Update tool安装工具会报错 go版本太低, 而很多时候为了项目稳定或风险太高, 我们不太希…...
uniapp APP使用web-view内嵌 h5 解决打包发版浏览器有缓存需要清除的问题
1.在当前项目根节点下的public目录下的index.html里面写入禁止缓存的 meta <!-- 解决前端发版缓存问题 start --><meta http-equiv"pragma" content"no-cache"><meta http-equiv"cache-control" content"no-cache, no-stor…...
机器学习与深度学习中模型训练时常用的四种正则化技术L1,L2,L21,ElasticNet
L1正则化和L2正则化是机器学习中常用的两种正则化方法,用于防止模型过拟合。它们的区别主要体现在数学形式、作用机制和应用效果上。以下是详细对比: 1. 数学定义 L1正则化(也叫Lasso正则化): 在损失函数中加入权重参…...
LLM自动化评测
使用的数据集:ceval-exam import requests from datasets import load_dataset, concatenate_datasets import re from tqdm import tqdm import re, time, tiktoken, ollama from ollama import ChatResponse from ollama import Optionsdef llm(model, query, te…...
Android 英文文章选词
点击文章中的一个单词,获取它。 通过点击的坐标y来获取行数,通过x坐标获取字符偏移量,向前遍历匹配,向后遍历匹配,匹配不成功则跳出循环。截取开始位置和最后位置的字符串。 主要代码 public String getSelectText…...
56.HarmonyOS NEXT 登录模块开发教程(十):总结与展望
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT 登录模块开发教程(十):总结与展望 文章目录 HarmonyOS NEXT 登录模块开发教程(十&a…...
【Go每日一练】猜数字游戏
👻创作者:丶重明 👻创作时间:2025年3月16日 👻擅长领域:运维 目录 1.😶🌫️题目:猜数字游戏2.😶🌫️代码开发3.😶🌫…...
论文分享:PL-ALF框架实现无人机低纹理环境自主飞行
在室内仓库、地下隧道等低纹理复杂场景中,无人机依赖视觉传感器进行自主飞行时,往往会遇到定位精度低、路径规划不稳定等难题。针对这一问题,重庆邮电大学计算机学院雷大江教授团队在IEEE Trans期刊上提出了一种新型自主飞行框架:…...
element-plus中Autocomplete自动补全输入框组件的使用
目录 1.基本使用 ①从官网复制如下代码 ②查看运行效果 ③代码解读 2.调用后端接口,动态获取建议数据 结语 1.基本使用 ①从官网复制如下代码 <template> <div><!-- 自动补全输入框 --><el-autocompletev-model"state":fetc…...
【医学影像 AI】大型语言模型生成 ROP 患者信息材料的能力
【医学影像 AI】大型语言模型生成 ROP 患者信息材料的能力 0. 论文简介0.1 基本信息0.2 摘要 1. 引言2. 材料与方法2.1 大语言模型的使用2.2 可读性标准2.3 统计分析 3. 结果3.1 Bezirci-Yılmaz可读性评分3.2 Ateşman可读性评分3.3 全面性评分3.4 准确性评分 4. 讨论4.1 可读…...
(性能测试)性能测试工具 2.jmeter的环境搭建 3jmeter元件和4使用实例 5jmeter元件和参数化
目录 性能测试工具 性能测试工具 jemeter环境搭建 jmeter的常用目录介绍 jmeter修改语言和主题--jmeter界面的汉化 jmeter元件 jmeter元件和组件的介绍 jmeter的作用域原则 jmeter的执行顺序 案例:执行顺序 jmeter使用案例 jmeter线程组的介绍 jmeter…...
Matlab 四分之一车体车辆半主动悬架鲁棒控制
1、内容简介 略 Matlab 173-四分之一车体车辆半主动悬架鲁棒控制 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
Kafka可视化工具KafkaTool工具的使用
Kafka Tool工具 介绍 使用Kafka的小伙伴,有没有为无法直观地查看 Kafka 的 Topic 里的内容而发过愁呢?下面推荐给大家一款带有可视化页面的Kafka工具:Kafka Tool (目前最新版本是 3.0.2) 注意:以前叫Kafk…...
【Unity】在项目中使用VisualScripting
1. 在packagemanager添加插件 2. 在设置中进行初始化。 Edit > Project Settings > Visual Scripting Initialize Visual Scripting You must select Initialize Visual Scripting the first time you use Visual Scripting in a project. Initialize Visual Scripting …...
【Maven教程与实战案例】
文章目录 前言一、Maven是什么?二、Maven的安装与配置1. 安装前置条件2. 下载与配置 Maven3. 验证安装 三、Maven的核心概念1. POM.xml 文件2. 构建生命周期与插件机制 四、实战项目示例1. 项目目录结构2. 编写代码App.javaAppTest.java 3. 构建项目4. 运行项目 前言…...
Flask中使用with语句手动加载应用上下文
在 Flask 中,with app.app_context(): 手动加载应用上下文,使代码块可以访问 Flask 全局对象(如 current_app、g),即使代码不在请求中运行。 1. 为什么需要手动加载应用上下文? 在 Flask 中,某…...
ROS实践(五)机器人自动导航(robot_navigation)
目录 一、知识点 1. 定位 2. 路径规划 (1)全局路径规划 (2)局部路径规划 3. 避障 二、常用工具和传感器 三、相关功能包 1. move_base(决策规划) 2. amcl(定位) 3. costmap_2d(代价地图) 4. global_planner(全局规划器) 5. local_planner(局部规划器…...
【数学建模】层次分析法(AHP)详解及其应用
层次分析法(AHP)详解及其应用 引言 在现实生活和工作中,我们经常面临复杂的决策问题,这些问题通常涉及多个评价准则,且各准则之间可能存在相互影响。如何在这些复杂因素中做出合理的决策?层次分析法(Analytic Hierarchy Process…...
【大模型】Transformer、GPT1、GPT2、GPT3、BERT 的论文解析
前言 在自然语言处理(NLP)和深度学习的快速发展中,Transformer模型和 GPT系列模型扮演了至关重要的角色。本篇博客旨在对这些开创性的论文进行介绍,涵盖它们的提出时间、网络结构等关键信息,能够快速的理解这些模型的设…...
Android 手机启动过程
梳理 为了梳理思路,笔者画了一幅关于 Android 手机启动的过程图片内容纯属个人见解,如有错误,欢迎各位指正...
【redis】hash基本命令和内部编码
文章目录 表示形式命令HSET 和 HGET HEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSETNXHINCRBYHINCRBYFLOAT命令小结内部编码 表示形式 Redis 自身已经是键值对结构了 Redis 自身的键值对就是通过哈希的方式来组织的 把 key 这一层组织完成之后,到了 value 这一层&…...
统计数字字符个数(信息学奥赛一本通-1129)
【题目描述】 输入一行字符,统计出其中数字字符的个数。 【输入】 一行字符串,总长度不超过255。 【输出】 输出为1行,输出字符串里面数字字符的个数。 【输入样例】 Peking University is set up at 1898. 【输出样例】 4 【输出样例】 #in…...
基于javaweb的SSM+Maven网上选课管理系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...
算法及数据结构系列 - BFS算法
文章目录 框架思路经典题型111. 二叉树的最小深度752. 打开转盘锁 框架思路 BFS 的核心思想应该不难理解的,就是把一些问题抽象成图,从一个点开始,向四周开始扩散。一般来说,我们写 BFS 算法都是用队列这种数据结构,每…...
深入剖析 MetaSpace OOM 问题:根因分析与高效解决策略
目录 一、MetaSpace 区 OOM:概述 (一) MetaSpace的变革与挑战 (二)MetaSpace OOM的影响 (三) 为什么要关注MetaSpace OOM 二、MetaSpace 区 OOM的根本原因 (一)Met…...
java自带日志系统介绍(JUL)以及和Log4j 2、Logback、SLF4J不同日志工具的对比
Java 日志系统是开发中用于记录应用程序运行时信息的重要工具。以下是 Java 日志系统的核心组件及其使用场景、配置参数的详细介绍,以及不同日志系统的对比分析。 Java 日志系统核心组件 1. 日志记录器(Logger) 作用:负责生成日…...
Kubernetes 中metrics-server的采集周期,采集链路是什么样的?
0. 运维干货分享 软考高级系统架构设计师备考学习资料软考高级网络规划设计师备考学习资料Kubernetes CKA认证学习资料分享信息安全管理体系(ISMS)制度模板分享免费文档翻译工具(支持word、pdf、ppt、excel)PuTTY中文版安装包MobaXterm中文版安装包ping…...
一分钟了解深度学习
一分钟了解深度学习 A Minute to Know About Deep Learning By JacksonML 1. 什么是深度学习? 深度学习(Deep Learning) 是机器学习的一个子集,都属于人工智能的范畴;它使用多层神经网络(称为深度神经网络)来模拟人…...
Git LFS (Large File Storage) 简介
目录 Git LFS (Large File Storage) 简介 1. 什么是 Git LFS? 2. 为什么需要 Git LFS? 3. Git LFS 的工作原理 4. 如何使用 Git LFS? 4.1 安装 Git LFS 4.2 配置 Git LFS 5. Git LFS 的优缺点 优点 缺点 6. 适用场景 7. 结论 1. …...
前端权限系统
前端权限系统是为了确保用户只能访问他们有权限查看的资源而设计的。在现代前端开发中,权限控制不仅仅是简单的显示或隐藏元素,还涉及到对路由、组件、数据和操作权限的细致控制。下面是前端权限系统的常见设计方案和实现步骤。 前端权限系统的组成部分 …...
【蓝桥杯速成】| 4.递归
递归 题目一:最大公约数 问题描述 1979. 找出数组的最大公约数 - 力扣(LeetCode) 给你一个整数数组 nums ,返回数组中最大数和最小数的 最大公约数 。 两个数的 最大公约数 是能够被两个数整除的最大正整数。 解题步骤 需要…...
QEMU源码全解析 —— 块设备虚拟化(4)
接前一篇文章:QEMU源码全解析 —— 块设备虚拟化(3) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 类模板是创建类的模式_创建类是的模版-CSDN博客<...
92.HarmonyOS NEXT开发学习路径与最佳实践总结:构建高质量应用
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT开发学习路径与最佳实践总结:构建高质量应用 文章目录 HarmonyOS NEXT开发学习路径与最佳实践总结:构建高质…...
【004】deepseek本地化部署后,python的调用方式_#py
python调用本地deepseek 1 本地化部署deepseek2 python调用方式 1 本地化部署deepseek 已经有很多大佬们说了不少部署本地化部署deepseek的工作了,我就不过多重复了。 先安装Ollama软件,再通过Ollama获取deepseek的模型文件,大家根据电脑的配…...
基于Python+Flask+MySQL+HTML的爬取豆瓣电影top-250数据并进行可视化的数据可视化平台
FlaskMySQLHTML 项目采用前后端分离技术,包含完整的前端,以flask作为后端 Pyecharts、jieba进行前端图表展示 通过MySQL收集格列数据 通过Pyecharts制作数据图表 这是博主b站发布的详细讲解,感兴趣的可以去观看:【Python爬虫可…...
【Prometheus01】可观测性系统之Prometheus简介、优缺点对比、组件介绍、数据采集流程、TSDB简介
监控工具对比、黑盒监控与盒白盒监控、Kubernetes监控简介 监控简介: 监控的价值: 长期趋势分析:通过对监控样本数据的持续收集和统计,对监控指标进行长期趋势分析。例如,通过对磁盘空间增长率的判断,我们…...
Postman下载安装及简单入门
一.Postman简介 Postman是一款API测试工具,可以帮助开发、测试人员发送HTTP请求,与各种API进行交互,并分析响应 二.下载与安装 访问Postman官网(https://www.postman.com/),下载适…...
记第一次跟踪seatunnel的任务运行过程三——解析配置的具体方法getLogicalDag
前绪 记第一次跟踪seatunnel的任务运行过程二——ClientJobExecutionEnvironment的execture方法 从这里开始,就是使用seatunnel-2.3.9的源码了。前面部分没有变化,2.3.X版本都是通用的。 建议打开源码,边读文章,边阅读源码 正文…...
Maven 的核心包
由于前端项目不是核心,阅读 nexus-public 源代码似乎绕远路了。nexus-oss 社区版主要就是集成 maven 的上传包、认证、包解析、包存储这几个核心功能,前端实现重新可以使用新的现代前端工具来提高生产力。故重新疏理一下 maven 的核心机制,即…...