面向Java程序员的Go工程开发入门流程
对于一个像我这样没有go背景的java程序员来说,使用go开发一个可用的程序的速度是肉眼可见的缓慢。
其难点不在于go语言本身,而是搭建整个工程链路的过程,即所谓的“配环境”。
本文主要讲述如何配出一个适合go开发的环境,以免有同事陷入困境时对我使出“您配吗”之类的大招。
假如拿到一台新电脑
安装brew:/bin/bash-c"$(curl-fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
安装完成后可以执行 brew--version
查看brew是否安装成功。
安装go编译器和调试器
▐ 安装go编译器
brew install go
这将安装go的最新版本。在发文的这一刻,go的最新版本是1.22。
如果想要安装某个特定的go历史版本,可以使用brew install go@1.21
这将安装go1.21。
可以使用brew search go
来查看当前brew仓库中可用的go版本列表。
安装完成后可以执行 go version
查看go是否安装成功。
▐ 安装go调试器
brew install delve
delve可以理解为是go版本的gdb。brew install gdb
如果遇到delve搞不定的场景,就需要gdb出来救场了。
安装完成后可以执行 dlv version
查看delve是否安装成功,执行 gdb --version
查看gdb是否安装成功。
▐ 配置 go 在编译产物中附加上调试信息
在shell脚本(.bash_profile或.zshrc)中添加一行
export GOFLAGS="-ldflags=-compressdwarf=false"
▐ 配置github gfw代理
在shell脚本(.bash_profile或.zshrc)中添加一行
export GOPROXY=https://goproxy.io,direct
▐ 配置私有代码仓库
在shell脚本(.bash_profile或.zshrc)中添加一行 export GOPRIVATE="你的私有gitlab地址.com/*,另外的私有gitlab地址.com/*"
,不要带http或https前缀
安装ide
隆重推荐goland,真的好用,但是要花钱。
其次推荐idea安装go插件,但是要求idea是Ultimate版本。
不想花钱的话可以用vscode。
vscode的必装插件:Go
认准Microsoft出品。
工程结构
如果开发的是一个独立运行的程序(存在main函数),推荐的目录结构如下:
your_app_name/
├── cmd/
│ ├── your_app_name/ # 应用程序的入口点,包含main包
│ │ └── main.go # 应用程序的主函数所在
│ └── ... # 如果有多个可执行文件,可以在这里添加
├── internal/ # 可选,存放仅供本应用内部使用的包
│ └── ... # 内部包结构,比如业务逻辑、工具函数等
├── config/ # 配置文件或配置加载逻辑
│ └── ... # 如yaml, toml, env等配置文件
├── scripts/ # 构建、部署脚本等
│ └── ...
├── tests/ # 单元测试、集成测试等
│ └── ...
├── README.md # 项目说明文档
├── go.mod # Go模块定义文件
├── go.sum # Go模块依赖的校验和文件
├── .gitignore # Git忽略规则文件
└── ... # 其他必要的文件,如Dockerfile、Makefile等
如果开发的是一个给别人用的类库,推荐的目录结构如下:
your_library_name/
├── internal/ # 可选,用于存放不希望对外暴露的包
│ └── ... # 内部使用的包
├── pkg/ # 存放库的公开对外接口。pkg 这一层可以省略,直接把源代码放在/your_library_name 目录下
│ └── your_library_name/
│ ├── your_library.go
│ └── ... # 库的各个源文件
├── tests/ # 单元测试、集成测试等
│ └── ...
├── README.md # 项目说明文档,包括安装、使用方法等
├── go.mod # Go模块定义文件
├── go.sum # Go模块的校验和文件
├── .gitignore # Git忽略文件列表
└── ... # 其他必要的文件,如Dockerfile、Makefile等
依赖管理
go的依赖项通过 go.mod
文件描述,类似于java的 pom.xml
或py的 requirements.txt
go是源代码依赖,没有制品的概念。可以理解为每次编译时,go都会从git上面把所有的依赖项的源代码全部拉下来,放在一起编译。官方的源代码仓库就是github。
一个典型的go.mod示例如下:
module github.com/dapr/dapr
^^^ 声明该模块的名字,类似于 groupId:artifactId强烈建议在这里填写这个工程的实际可访问的git地址,否则会带来无穷无尽的麻烦go 1.21
^^^ 指定要求的最低 go 版本,类似于 <java.version>1.8</java.version>require (
^^^ 这里列出所有直接依赖项,类似于 <dependencies>contrib.go.opencensus.io/exporter/prometheus v0.4.2github.com/PaesslerAG/jsonpath v0.1.1github.com/PuerkitoBio/purell v1.2.1
)require (
^^^ 这一大片后面带有 // indirect 的是 go 自动生成的所有间接依赖,类似 mvn dependency:tree 的产出。千万不要手工修改这部分。cloud.google.com/go v0.110.10 // indirectcloud.google.com/go/compute v1.23.3 // indirectcloud.google.com/go/compute/metadata v0.2.3 // indirectcloud.google.com/go/datastore v1.15.0 // indirectcloud.google.com/go/iam v1.1.5 // indirect
)replace (
^^^ 这一段用于模块的名称和实际 git 地址不匹配的情况。上面提到的无穷无尽的麻烦就是指,所有引用你的包的项目都需要使用 replace 来将你的包指向实际的 git 地址github.com/toolkits/concurrent => github.com/niean/gotools v0.0.0-201512replace github.com/dapr/components-contrib => ../components-contrib^^^ 也可以将模块的路径指向本地,以便于二方包开发过程中进行调试
)
当工程的多个依赖项发生冲突时,比如说app依赖lib1和lib2,lib1依赖libaaa的 1.0版本,lib2依赖libaaa的2.0版本,go不会进行仲裁,会直接报编译错。你需要在go.mod中手工指定libaaa到底应当使用哪个版本。
当依赖的二方包并没有放在github上,而是放在自建的gitlab上时,直接编译是编不过的,即使你有对应 gitlab 仓库的权限。
这是因为go在编译时并不是真的去直接拉git,而是会去尝试访问一个代理服务器(类似于cdn)。你需要指定go在访问我们自己的git时不要走官方的cdn,因为那上面肯定没有我们集团内部的包。
如果遇到这种情况,就需要在shell脚本(.bash_profile或.zshrc)中添加一行 export GOPRIVATE="你的私有gitlab地址.com/*,另外的私有gitlab地址.com/*"
,这在第1节中已经讲过。
当依赖的二方包的owner修改了git的访问权限配置,导致你没有权限访问其代码仓库时,编译会失败。除了找项目owner开权限之外没有任何办法。
在代码中引用二方包
首先必须要说,go的import体系对于java程序员来说是非常难以上手的。主要体现在如下几个方面:
▐ 时刻注意区分清楚【模块 / module】和【包 / package】的概念
这个在java中根本不是问题,没人会弄混。但是在go中经常会造成混淆,因为这两者在go里面看起来长得差不多。以及,go的import语句和java的import有本质的区别,你更应当把go的import理解为c语言的#include。
【模块】指的是一个库,类似于一个jar包,其名称是groupId:artifactId对应的git地址,只在go.mod中出现。
模块的名称(通常)等同于其git地址,形式为 github.com/groupId/artifactId
具体来说,一个典型的模块名大概类似于 github.com/apache/dubbo-go
,在域名后面只有两段(groupId 和 artifactId)
【包】指的是把相关联的文件放在一起的集合,类似于java概念中的package
具体来说,一个在import语句后面跟的典型的包路径大概类似于
github.com/apache/dubbo-go/remoting
其中的 github.com/apache/dubbo-go
部分是模块名,后面的 /remoting
表示这个包所处的具体git路径。
再次强调,请一定要抛开java的import语义,将go的import直接理解成#include
如果遇到依赖相关的难以理解的编译错误,请检查是否误将模块路径放在了import语句里面,或者是不是把包路径误放在了go.mod里。
▐ import包时是import包的git地址,但是这个地址和包的名称可以不一致
对于 java 程序员来说有一个冷知识:在常见的语言中,只有java强行规定了包名必须和目录结构一致、类名必须和文件名一致,而go并没有这条规定。所以import一个包时,这个包在实际代码中使用的名称和包的路径可以完全看不出任何关系。
从人道主义角度来讲,非常不推荐向别人提供这样的包,但也只是不推荐而已。
比如:
import ("github.com/go-playground/validator/v10"
)
...
func foo() {validator.Xxx()
}
引用这个包时需要依赖包的路径
("github.com/go-playground/validator/v10"),但是在具体使用的时候使用的包名是validator,这中间看不出任何对应关系,只能去翻源代码。
个人建议:除了标准库的包之外,对所有import的包都自己定义一个别名,例如:
import (validator "github.com/go-playground/validator/v10"
)
▐ go在import中引入的包在代码中必须被使用,否则编译会报错
在ide中,默认会把没使用的包对应的import语句直接删掉。
所以如果临时注释掉一条语句,再回头把注释去掉时,很有可能因为import语句被删掉了而编译不过。
个人建议:当临时需要禁用掉某些代码时,不要直接注释,要使用if false {} 给包起来。
if false {validator.Xxx() // 不要直接注掉,免得ide把对应的import语句也给删了
}
▐ 修改go.mod后必须执行一次go mod tidy
当要新增/删除依赖时,需要修改go.mod文件,类似于修改pom.xml。在修改之后,需要手工执行 go mod tidy
,否则会编译失败。go不会在编译时帮你更新依赖。
顺便,受上一条规则影响,所有的import都必须是实际被使用的。如果代码中去掉了某个import,而这一行import是整个工程中唯一引用某个依赖的位置,那么就意味着这个依赖不再被需要。此时需要从go.mod中去掉该依赖并执行 go mod tidy
,否则会导致编译不通过。
个人建议:直接把go mod tidy命令放在编译脚本中,每次编译时都执行一下。下面【编译】一节会详细解释。
▐ 执行过go mod tidy之后, go.mod文件本身会被修改
go mod tidy会原地修改go.mod,把所有间接依赖也明确地标在原文件中。
如果go.mod中声明的依赖没有被实际使用,go mod tidy会直接把这一行require给删掉。
这一条规则尤其坑爹。前面提到了,go要求代码中所有import进来的包都必须被使用。如果你注掉了一行代码,很有可能导致IDE把对应的import删掉,然后go mod tidy会把go.mod中的依赖声明给删掉。这样你再把注释恢复回去之后,就需要从go.mod改起。
个人建议:每次执行过 go mod tidy
之后都要记得检查一下go.mod文件,以免被go mod tidy命令改坏。
以及,再重申一次,千万不要碰go.mod里面标了 // indirect的那一片自动生成的require指令。
最后再重复一遍之前提到过的个人建议:当临时需要禁用掉某些代码时,不要直接注释,要使用if false {} 给包起来。
向别人提供二方包
和maven一样,当向别人提供二方包时,我们需要向用户提供二方包的GAV坐标。
其中GroupId、ArtifactId是被包含在git repo的地址中的,形式为 gitlab.mycompany.com/${groupId}/${artifactId}
之前已经强调过,这个地址必须是可以被直接访问的,里面放的就是二方包的源代码,并且要配置好合适的访问权限。
不建议将git repo设置为除了PUBLIC之外的任何级别,除非你能明确地管控所有下游使用场景。否则但凡你的包被别人引用了,就永远会有不知道哪的人过来找你开权限。
Version比较特殊,我们分成正式包和snapshot包两种情况来讨论。
▐ 正式包的发版是通过git的tag机制来实现的
当一个版本开发完成时,我们需要在git repo里面把最新版本的代码打一个tag,名称需要遵循SemVer规范。
业务方可以使用下述语法在go.mod中依赖这个包:require gitlab.mycompany.com/${groupId}/${artifactId} v$tag
例如:require gitlab.mycompany.com/shop/libaaa v0.3.6-rc9
▐ snapshot包的发版是通过git的branch机制实现的
当一个版本仍在持续开发过程中时,我们可以把正在开发的分支直接公布出去,
业务方可以使用下述语法在go.mod中依赖这个包:
require gitlab.mycompany.com/${groupId}/${artifactId} v0.0.0-notexist
replace gitlab.mycompany.com/${groupId}/${artifactId} => gitlab.mycompany.com/${groupId}/${artifactId} v0.0.0-${branch}
例如:
require gitlab.mycompany.com/shop/libaaa v0.0.0-notexist
replace gitlab.mycompany.com/shop/libaaa => gitlab.mycompany.com/shop/libaaa v0.0.0-develop2
类似于maven的snapshot包,如果上游向分支里push了新代码,下游需要重新执行 go get -u
(类似于mvn -U命令)更新所有snapshot。
这里也可以看到,go的snapshot机制叠加上基于源代码的依赖机制,比mvn的 snapshot二方包要危险得多。你甚至可以向分支中提交一段编译不过的代码,从而让所有下游的编译过程全部炸掉。maven好歹总得先编译个jar包出来。
总结一下,如果我们开发好了一个二方包,需要提供给别人使用,那么需要公布两个信息:
二方包的git repo地址,形式为
gitlab.mycompany.com/${groupId}/${artifactId}
如果是正式包,需要公布其tag,使用SemVer格式;如果是snapshot,需要公布其branch,没有命名格式要求
编译
沧海月明珠有泪,蓝田日暖玉生烟。
此情可待成追忆,只是当时已惘然。—— (唐)李商隐
离开了maven的温室之后,我们必须直面go build的冰冷现实了。
go的编译命令是 go build
。它有很多参数,非常灵活,但是每次编译都把完整命令全部敲一遍的话,精神方面可能就有点问题了。这个时候我们需要用make来简化构建工作,这又是一个大坑。
在java世界中,我们熟悉的构建工具就是Maven。Maven预先定义了 validate
compile
package
test
deploy
之类的阶段,直接敲 mvn clean build
即可让 maven 完成预先定义的动作。
而make没有提供任何预定义的阶段,在敲下 make clean build
之后要执行什么操作都需要在Makefile中手工声明。这份Makefile应当放在工程根目录下,文件名即为 Makefile
八个字母,注意大小写。
这里仅给出一份个人推荐的Makefile文件样例,具体使用时请酌情修改:
# 定义一些常量
APPNAME := your_application_name
BINDIR := /build/bin
GOBIN := $(shell go env GOPATH)/bin
export GO111MODULE := on# 目标: 清理
clean:@rm -rf $(BINDIR)/*@echo "Cleanup completed."# 目标: 构建
build: go_mod_tidy compile# 执行go mod tidy
go_mod_tidy:@go mod tidy@echo "go mod tidy completed."# 编译项目
compile: @mkdir -p $(BINDIR)@go build -o $(BINDIR)/${APPNAME}@echo "Build completed."# 使用帮助信息
help:@echo "Usage:"@echo "make build - 整理模块依赖,编译项目,将产出物放到 /build/bin 目录下"@echo "make clean - 清理构建产物".PHONY: clean build go_mod_tidy compile help
make build 整理模块依赖,编译项目,将产出物放到 /build/bin目录下
make clean 清理构建产物
make help 输出上述说明
调试
首先需要重申一个常识,对于go这种编译型语言来说,“调试”这个动作是面向可执行程序,即编译的产物的,而不是面向源代码的。
如果是在vscode中调试,需要修改项目 /.vscode目录中的launch.json文件,以指定待调试的可执行程序的位置、运行该程序时需要传递的参数和需设置的环境变量等信息。
{"version": "0.2.0","configurations": [{"name": "Launch Go Program with Args","type": "go","request": "launch","mode": "debug","program": "${fileDirname}", // 当前文件所在的目录作为工作目录,如果你需要指定特定的可执行文件路径,可以改为该路径"args": ["arg1", "arg2", "--option=value"], // 在这里添加你的命令行参数"env": {"env1":"env_value1", "env2":"env_value2"}, // 可以在这里添加环境变量,如果需要"showLog": true, // 是否在调试控制台显示Delve的日志,默认为false"trace": "verbose" // 设置为"verbose"可以获取更详细的调试信息,根据需要调整}]
}
实际的调试过程无需赘述。只能说vscode + go插件又不是不能用,其提供的断点和watch功能相比,goland来说还是有些差距。
如果发现调试过程非常跳跃甚至不可用,请检查一下是否在编译选项中配置了 -ldflags=-compressdwarf=false
,这个参数用于在编译产物中保留debug信息。
如果因为各种原因,无法在vscode环境内进行调试,我们可以尝试使用delve命令行工具来进行调试。
调试命令为 dlv exec xxxx -- 要传给xxx的命令行参数
,要记得它调试的是编译出来的可执行文件。
delve提供的是基于命令行的交互方式。使用exec命令启动时,整个程序不会开始运行,而是会停在整个main函数的入口外面。
此时可以敲命令与程序进行交互,常用的命令如下:
b 命令 设置断点
c 命令 执行至下一个断点
n 命令 step over
s 命令 step in
so 命令 step out
args 命令 查看方法参数
p 命令 查看变量的值
delve同样支持 dlv debug xxx.go
的语法,可以直接指定源文件,此时它会调用go编译器把这个文件编译出来之后再去调试。对于特别小的工程来说较为方便。
如果delve也搞不定,就只能上gdb了。gdb具体的用法我就不讲了,因为我也不熟。
打包
脱离了java/maven后,我们需要重新熟悉一下linux世界中“正统”的软件分发方式。
集团最初选择了将各系统运行在centos上,也就意味着集团的软件包分发是基于rpm/yum体系的。与之类似的还有Debian系的deb/apt、Archlinux使用的 tar.xz/pacman之类。
我们需要将我们的构建产物打成rpm包(类似于jar包),具体打rpm包的过程请学习 RPM打包操作手册。
面向ChatGPT老师教程
Q: 我需要以《面向chatgpt老师编程》为题写一篇几百字的短文,向同事们介绍如何借助您的知识迅速掌握go的编程技能,请帮我提供一份草稿
A: 《面向ChatGPT老师编程:快速掌握Go语言技能》
在技术日新月异的今天,Go语言以其简洁的语法、高效的并发模型和卓越的性能,在众多编程语言中脱颖而出,成为众多开发者的新宠。但对于初学者而言,如何高效、系统地学习Go,快速掌握其精髓,却是一个值得探讨的话题。在此,我们引入一位特别的“老师”——ChatGPT,来指导我们如何在编程之旅中乘风破浪,迅速提升Go语言技能。
第一步:基础搭建,从Hello World开始
与ChatGPT老师的对话,不妨就从最经典的“Hello, World!”程序开始。通过编写这个简单的程序,ChatGPT不仅能帮你熟悉Go的基本语法,还能深入浅出地解释背后的工作原理,比如包的导入、函数定义等基础概念。
第二步:深入理解并发模型
Go语言的一大亮点是其内置的goroutine和channel机制,这对于构建高性能的并发服务至关重要。通过向ChatGPT提出具体场景的问题,如“如何使用goroutine处理大量并发请求?”或“如何利用channel实现数据安全共享?”,ChatGPT能以实例结合理论的方式,让你轻松掌握并发编程的核心技巧。
第三步:实战演练,项目驱动学习
理论知识虽好,但没有实践的支撑,就如同空中楼阁。不妨向ChatGPT请教一些小型实战项目,如编写一个简易的Web服务器、实现一个文件上传下载服务等。ChatGPT不仅会提供代码示例,还会引导你思考如何优化代码结构、提高执行效率,让你在实践中深刻理解Go的高级特性。
第四步:调试与优化,进阶之道
遇到bug怎么办?性能瓶颈如何突破?ChatGPT在这些方面同样能给予帮助。你可以询问如何使用Go的调试工具(如delve)进行代码调试,或是如何利用pprof进行性能分析。通过ChatGPT的指导,你将学会如何高效地定位问题并进行性能调优,让代码更加健壮、高效。
第五步:持续学习,紧跟Go生态发展
Go语言的生态系统不断发展壮大,新的库和框架层出不穷。ChatGPT可以帮助你追踪最新的Go语言动态,推荐优秀的开源项目和文章,让你的学习之路永不止步。
总之,ChatGPT不仅是你的编程助手,更是你学习Go语言道路上的良师益友。它以无尽的知识库、耐心的解答态度,帮助你快速成长,从Go语言新手进化为高手。在这个过程中,记得多提问、多实践,与ChatGPT老师一起探索Go语言的无限可能。
¤ 拓展阅读 ¤
3DXR技术 | 终端技术 | 音视频技术
服务端技术 | 技术质量 | 数据算法
相关文章:
面向Java程序员的Go工程开发入门流程
对于一个像我这样没有go背景的java程序员来说,使用go开发一个可用的程序的速度是肉眼可见的缓慢。 其难点不在于go语言本身,而是搭建整个工程链路的过程,即所谓的“配环境”。 本文主要讲述如何配出一个适合go开发的环境,以免有同…...
vue3开发高德地图
在vue3的index.html 使用动态注入地址名和key <html lang"en"><head><meta charset"UTF-8" /><link rel"icon" type"image/svgxml" href"/vite.svg" /><meta name"viewport" conten…...
通过DLL方式链接glfw3.dll
主要是CMakeLists.txt文件变化 cmake_minimum_required(VERSION 3.10) project(glfwTest) set(CMAKE_CXX_STANDARD 11) aux_source_directory(. SRC_SOURCES) set(GLFW_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) set(GLFW_LIBRARY_DIR ${CMAKE_SOURCE_DIR}/lib/glfw) add_ex…...
Python自然语言处理(NLP)库之NLTK使用详解
概要 自然语言处理(NLP)是人工智能和计算机科学中的一个重要领域,涉及对人类语言的计算机理解和处理。Python的自然语言工具包(NLTK,Natural Language Toolkit)是一个功能强大的NLP库,提供了丰富的工具和数据集,帮助开发者进行各种NLP任务,如分词、词性标注、命名实体…...
sqoop操作
介绍 sqoop是隶属于Apache旗下的, 最早是属于cloudera公司的,是一个用户进行数据的导入导出的工具, 主要是将关系型的数据库(MySQL, oracle...)导入到hadoop生态圈(HDFS,HIVE,Hbase...) , 以及将hadoop生态圈数据导出到关系型数据库中 操作 将数据从mysql中导入到HDFS中 1.全量…...
【Qt秘籍】[002]-开始你的Qt之旅-下载
一、Qt的开发工具有哪些? Qt的开发工具概述Qt支持多种开发工具,其中最常见的开发工具是 1.QtCreator 【易上手/有少量bug/适合新手】 2.VisualStudio 【功能强大/易出错/需要更多额外配置】 3.Eclipse 【清朝老兵IDE/不建议使用】 【注意࿱…...
【自动驾驶】点与向量从ego系转odometry系
1.点从ego系转odometry系(ego -> odometry) struct Point {float x;float y;float angle; }; Point trans; // is the odom to ego transform Point odom_coord; is the odom coord Point ego_coord; is the ego coordfloat odom_coord.x = (ego_coord.x - trans.x) * st…...
jsmug:一个针对JSON Smuggling技术的测试PoC环境
关于jsmug jsmug是一个代码简单但功能强大的JSON Smuggling技术环境PoC,该工具可以帮助广大研究人员深入学习和理解JSON Smuggling技术,并辅助提升Web应用程序的安全性。 背景内容 JSON Smuggling技术可以利用目标JSON文档中一些“不重要”的字节数据实…...
Qt 控件提升
什么是控件提升(Widget Promotion) 控件提升是一个在Qt编程中常见但容易被忽视的概念。简单来说,控件提升就是将一个基础控件(Base Widget)转换为一个更特定、更复杂的自定义控件(Custom Widget)…...
封装一个websocket,支持断网重连、心跳检测,拿来开箱即用
封装一个websocket,支持断网重连、心跳检测 代码封装 编写 WebSocketClient.js import { EventDispatcher } from ./dispatcherexport class WebSocketClient extends EventDispatcher {constructor(url) {console.log(url, urlurl)super()this.url url}// #soc…...
推荐一款开源电子签章/电子合同系统
文章目录 前言一、项目介绍二、项目地址三、技术架构四、代码结构介绍五、功能模块六、功能界面首页面手写签名面板电子印章制作数字证书生成 总结 前言 大家好!我是智航云科技,今天为大家分享一个免费开源的电子签字系统。 一、项目介绍 开放签电子签…...
Qt Creator(Qt 6.6)拷贝一行
Edit - Preference - Environment: 可看到,拷贝一行的快捷键是: ctrl Ins...
红队内网攻防渗透:内网渗透之数据库权限提升技术
红队内网攻防渗透 1. 内网权限提升技术1.1 数据库权限提升技术1.1.1 数据库提权流程1.1.1.1 先获取到数据库用户密码1.1.1.2 利用数据库提权工具进行连接1.1.1.3 利用建立代理解决不支持外联1.1.1.4 利用数据库提权的条件及技术1.1.2 Web到Win-数据库提权-MSSQL1.1.3 Web到Win-…...
从0开始制作微信小程序
目录 前言 正文 需要事先准备的 需要事先掌握的 什么是uniapp 平台应用的分类方式 什么是TypeScript 创建项目 项目文件作用 源码地址 尾声 🔭 Hi,I’m Pleasure1234🌱 I’m currently learning Vue.js,SpringBoot,Computer Security and so on.…...
Linux学习笔记:日志文件的编写
日志文件Log.hpp 日志文件的作用简单的日志文件编写 日志文件的作用 日志文件可以很好的帮我们显示出程序运行的信息,例如,进程pid,运行时间,运行状况等,通过日志记录程序的执行路径、变量值、函数调用等,可以帮助我们快速定位和修复代码中的错误。 简单的日志文件…...
为什么要保持方差为1
1.数值稳定性: 在机器学习和深度学习中,维持激活函数输入的方差在一个合理范围内(如1)是很重要的,这有助于防止在训练过程中发生梯度消失或梯度爆炸的问题。如果方差过大或过小,经过多层网络后输出结果的方…...
Wpf 使用 Prism 实战开发Day31
登录数据绑定 1.首先在LoginViewModel 登录逻辑处理类中,创建登录要绑定属性和命令 public class LoginViewModel : BindableBase, IDialogAware {public LoginViewModel(){ExecuteCommand new DelegateCommand<string>(Execure);}public string Title { ge…...
Linux权限提升二
#应用场景: 获取到Web权限或普通用户在Linux服务器上时进行的SUID&SUDO提权 SUID (Set owner User ID up on execution)是给予文件的一个特殊类型的文件权限。在Linux/Unix中,当一个程序运行的时候,程序将从登录用户处继承权限。SUID被定…...
[AI OpenAI] 推出ChatGPT Edu
一种负担得起的解决方案,帮助大学将AI负责任地引入校园。 我们宣布推出ChatGPT Edu,这是一个专为大学设计的ChatGPT版本,旨在负责任地向学生、教职员工、研究人员和校园运营部署AI。ChatGPT Edu由GPT-4o提供支持,能够跨文本和视觉…...
HTML5+CSS3回顾总结
一、HTML5新特性 1.语义化标签 <header> 头部标签<nav> 导航标签<article> 内容标签<section> 定义文档某个区域<aside> 侧边栏标签<footer> 尾部标签 2.多媒体标签 2.1视频标签vedio 》常规写法(尽量都使用mp4࿰…...
AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2024.05.01-2024.05.10
文章目录~ 1.Pseudo-Prompt Generating in Pre-trained Vision-Language Models for Multi-Label Medical Image Classification2.VLSM-Adapter: Finetuning Vision-Language Segmentation Efficiently with Lightweight Blocks3.Memory-Space Visual Prompting for Efficient …...
Python 点云生成高程模型图(DSM)
点云生成高程模型图 一、什么是DSM?二、python代码三、结果可视化一、什么是DSM? DSM(Digital Surface Model)是一种数字高程模型,通常用于描述地表地形的数字化表示。它是由一系列离散的高程数据点组成的三维地形模型,其中每个点都具有其相应的高程值。 DSM主要用于…...
[第五空间 2021]WebFTP
题目是WebFTP 通过标签可以看出git泄露(git泄露是指开发人员利用git进行版本控制) 通过网上了解WebFTP的源码账号admin 密码admin888 进去之后正常思路是我们利用/.git 在githack里面进行复现 查看log看看有没有flag 但是经过我们查询之后不是这样子 通过一段时间摸索在phpinf…...
SQL—DQL(数据查询语言)之小结
一、引言 在前面我们已经学习完了所有的关于DQL(数据查询语言)的基础语法块部分,现在对DQL语句所涉及的语法,以及需要注意的事项做一个简单的总结。 二、DQL语句 1、基础查询 注意: 基础查询的语法是:SELE…...
找回xmind文件办法:一切意外均可找回(误删/重启关机等)
我周三编辑完,周四下午评审完用例忘记保存 结果到了快乐星期五,由于是周五我太开心了...早上到公司后觉得电脑卡,直接点了重启啥都没保存啊啊啊啊啊 准备上传测试用例时才想起来我的用例找不见了!!!&…...
微信小程序 npm构建+vant-weaap安装
微信小程序:工具-npm构建 报错 解决: 1、新建miniprogram文件后,直接进入到miniprogram目录,再次执行下面两个命令,然后再构建npm成功 npm init -y npm install express(Node js后端Express开发ÿ…...
【LeetCode 63】 不同路径 II
1. 题目 2. 分析 这道题比较典型,跟最小路径和 是同样的思想。比较简单。 3. 代码 class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:row len(obstacleGrid)col len(obstacleGrid[-1]) dp [[0] *(col) f…...
OpenAI助手API接入-问答对自动生成
支持GPT-3.5-Turbo, GPT-4o, GPT-4-Turbo import json import openai from pathlib import Path import os client openai.OpenAI(base_urlbase_url, api_keyapi_key) file client.files.create( fileopen("H3.pdf", "rb"), purposeassistants ) …...
9. C++通过epoll+fork的方式实现高性能网络服务器
epollfork 实现高性能网络服务器 一般在服务器上,CPU是多核的,上述epoll实现方式只使用了其中的一个核,造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。 创建子进程函数–fork( ) 要了解线程我们先来了解…...
【Mac】XMind for mac(XMind思维导图)v24.04.10311软件介绍和安装教程
软件介绍 XMind for Mac是一款功能强大的思维导图软件。它具有以下主要特点: 1.多样化的思维导图功能:XMind for Mac提供了丰富的思维导图编辑功能,用户可以创建各种类型的思维导图,包括组织结构图、逻辑图、时间轴图等…...
长沙专业网站设计服务/线上营销推广的公司
随着html5的快速发展,很多学生都加入进来,那么如此具有前景的前端我们该怎么入门呢?新手在学习前端的时候要学习那些内容呢?下面我们来总结一下web前端学什么内容?前端入门需要注意什么? 打造全网web前端全…...
快站建站教程/免费建站网站
本文实例讲述了jquery及js实现动态加载js文件的方法。分享给大家供大家参考,具体如下:问题:如果用jquery append直接加载script标签的话,会报错的。除了document.write外,还有没有其他的比较好的动态加载js文件的方法。…...
wordpress添加页面模块/卖友情链接赚钱
大数据在十年前是一个有趣的概念,而现在却成为现代企业的一个普遍特征。数据从根本上讲是有价值的,这取决于所收集的内容以及如何使用,数据可以给企业带来更好的商业洞察力,帮助企业改变经营方向,并指导学习以及为什么…...
公司注销后 网站备案/推广页面
点击蓝字关注我们Python标识符在 Python 里,标识符有字母、数字、下划线组成。在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。Python 中的标识符是区分大小写的。以下划线开头的标识符是有特殊意义的。以单下划…...
政府网站建设 经费保障/aso安卓优化公司
nfsiostat介绍Sysstat家族包括一个名叫nfsiostat的实用程序,它和iostat有诸多类似之处,它允许你监控NFS文件系统上的读写情况,其用法也和iostat类似,最基本的命令用法是跟上几个参数和两个数字,这两个数字分别表示&…...
山东城乡建设部网站首页/上海seo优化公司kinglink
在构建插件式的应用程序框架(二)----订立契约一文中,可以看到我们的IApplication接口是派生于IServiceContainer接口的。为什么要派生于IServiceContainer呢?我们来看看IServiceContainer的定义,…...