Go的Gin比java的Springboot更加的开箱即用?
前言
隔壁组的云计算零零后女同事,后文简称 云女士 ,非说 Go 的 Gin 框架比 Springboot 更加的开箱即用,我心想在 Java 里面 Springboot 已经打遍天下无敌手,这份底蕴岂是 Gin 能比。
但是云女士突出一个执拗,非我要 PK 一把, PK 内容就是她使用 Gin,而我使用 Springboot 快速搭建一个简单的 Crud 工程,最后让其他同事来评判哪个更开箱即用。我毫不犹豫就答应了,作为搭建 Springboot 学习工程的资深 Crud 选手,咱这份底气还是有的。
云女士选择使用 Gin + Gorm 来搭建,而我原本想选择 Springboot + MyBatis,后面转念一想,这 MyBatis 要写 XML 文件,指不定就因为这个被云女士嘲笑了,所以我把 MyBatis 替换为了 MyBatis-Plus,这就足够的简洁了吧。
正文
准备事项
既然是 Crud 工程,自然要准备好操作的表,我和云女士通过如下语句在各自的数据库中创建好了如下两张表。
CREATE TABLE people (id INT(11) PRIMARY KEY AUTO_INCREMENT,p_name VARCHAR(255) NOT NULL,p_age INT(11) NOT NULL
)CREATE TABLE book (id INT(11) PRIMARY KEY AUTO_INCREMENT,b_name VARCHAR(255) NOT NULL,b_price FLOAT NOT NULL
)
Gin快速搭建Crud工程
云女士的工程结构如下所示。

云女士的 go.mod 文件内容如下所示。
module gobasego 1.17require (github.com/gin-gonic/gin v1.6.0github.com/jinzhu/gorm v1.9.16github.com/sirupsen/logrus v1.9.3github.com/spf13/cast v1.5.1
)
云女士定义了两个结构体作为模型( Model ),book.go 文件内容如下所示。
package modelconst (BookTableName = "book"
)type Book struct {ID int64 `gorm:"column:id"`BookName string `gorm:"column:b_name"`BookPrice float64 `gorm:"column:b_price"`
}func (b *Book) TableName() string {return BookTableName
}
people.go 文件内容如下所示。
package modelconst (PeopleTableName = "people"
)type People struct {ID int64 `gorm:"column:id"`PeopleName string `gorm:"column:p_name"`PeopleAge int64 `gorm:"column:p_age"`
}func (p *People) TableName() string {return PeopleTableName
}
云女士补充道,TableName()方法是为模型指定对应的表名。
云女士为 book 表和 people 表分别定义了 Dao 接口,dao.go 文件内容如下所示。
package daoimport "gobase/model"type BookDao interface {AddBook(book *model.Book) errorUpdateBook(book *model.Book) errorDeleteBook(book *model.Book) errorListBookById(id uint) (*model.Book, error)
}type PeopleDao interface {AddPeople(book *model.People) errorUpdatePeople(book *model.People) errorDeletePeople(book *model.People) errorListPeopleById(id uint) (*model.People, error)
}
BookDao 接口对应的实现在book_dao_impl.go文件中,实现如下。
package daoimport ("github.com/jinzhu/gorm""gobase/model"
)type BookDaoImpl struct {DB *gorm.DB
}func (b *BookDaoImpl) AddBook(book *model.Book) error {if createResult := b.DB.Create(book); createResult.Error != nil {return createResult.Error}return nil
}func (b *BookDaoImpl) UpdateBook(book *model.Book) error {if saveResult := b.DB.Save(book); saveResult.Error != nil {return saveResult.Error}return nil
}func (b *BookDaoImpl) DeleteBook(book *model.Book) error {if deleteResult := b.DB.Delete(book); deleteResult.Error != nil {return deleteResult.Error}return nil
}func (b *BookDaoImpl) ListBookById(id uint) (*model.Book, error) {var book model.Bookif listResult := b.DB.Where("id = ?", id).First(&book); listResult.Error != nil {return nil, listResult.Error}return &book, nil
}
PeopleDao 接口对应的实现在people_dao_impl.go文件中,实现如下。
package daoimport ("github.com/jinzhu/gorm""gobase/model"
)type PeopleDaoImpl struct {DB *gorm.DB
}func (b *PeopleDaoImpl) AddPeople(people *model.People) error {if createResult := b.DB.Create(people); createResult.Error != nil {return createResult.Error}return nil
}func (b *PeopleDaoImpl) UpdatePeople(people *model.People) error {if saveResult := b.DB.Save(people); saveResult.Error != nil {return saveResult.Error}return nil
}func (b *PeopleDaoImpl) DeletePeople(people *model.People) error {if deleteResult := b.DB.Delete(people); deleteResult.Error != nil {return deleteResult.Error}return nil
}func (b *PeopleDaoImpl) ListPeopleById(id uint) (*model.People, error) {var people model.Peopleif listResult := b.DB.Where("id = ?", id).First(&people); listResult.Error != nil {return nil, listResult.Error}return &people, nil
}
要操作数据库,肯定需要数据库连接,云女士将数据库连接的管理实现在了mysql_connection_pool.go文件中,内容如下所示。
package mysqlimport ("fmt""github.com/jinzhu/gorm""gobase/dao""log""time"
)const (UserName = "root"PassWord = "root"Host = "192.168.101.8"Port = 3306Database = "gotest"MaxLifetime = 60 * time.SecondMaxIdletime = 30 * time.SecondMaxOpenconns = 6MaxIdleconns = 2Dialect = "mysql"
)type DataSouce struct {db *gorm.DB
}func NewDataSource() *DataSouce {var db *gorm.DBdsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Asia%%2FShanghai",UserName, PassWord, Host, Port, Database)db, err := gorm.Open(Dialect, dsn)if err != nil {log.Fatal(err.Error())}db.DB().SetConnMaxLifetime(MaxLifetime)db.DB().SetConnMaxIdleTime(MaxIdletime)db.DB().SetMaxOpenConns(MaxOpenconns)db.DB().SetMaxOpenConns(MaxIdleconns)return &DataSouce{db: db,}
}// BookDao 操作book表
func (d *DataSouce) BookDao() dao.BookDao {return &dao.BookDaoImpl{DB: d.db,}
}// PeopleDao 操作people表
func (d *DataSouce) PeopleDao() dao.PeopleDao {return &dao.PeopleDaoImpl{DB: d.db,}
}
云女士将路由写在了webservice.go文件中,内容如下。
package adapterimport ("github.com/gin-gonic/gin""gobase/mysql"
)func Init() error {dataSouce := mysql.NewDataSource()bookController := NewBookController(dataSouce)propleController := NewPropleController(dataSouce)engine := gin.Default()routerGroupBook := engine.Group("/book")routerGroupBook.POST("/add", bookController.AddBook)routerGroupBook.POST("/update", bookController.UpdateBook)routerGroupBook.POST("/delete", bookController.DeleteBook)routerGroupBook.POST("/list", bookController.ListBookById)routerGroupPeople := engine.Group("/people")routerGroupPeople.POST("/add", propleController.AddPeople)routerGroupPeople.POST("/update", propleController.UpdatePeople)routerGroupPeople.POST("/delete", propleController.DeletePeople)routerGroupPeople.POST("/list", propleController.ListPeopleById)return engine.Run()
}
其实除了绑定路由,云女士还在Init()函数中进行了简单的服务注入,也就是创建数据库连接池,然后将数据库连接池给到对应的 web 服务。
云女士将操作 book 表对应的 web 服务写在了book_controller.go文件中,其实现如下所示。
package adapterimport ("github.com/gin-gonic/gin""github.com/sirupsen/logrus""github.com/spf13/cast""gobase/model""gobase/mysql""net/http"
)type BookController struct {dataSource *mysql.DataSouce
}func NewBookController(dataSource *mysql.DataSouce) BookController {return BookController{dataSource: dataSource,}
}func (b *BookController) AddBook(ctx *gin.Context) {var book model.Bookif err := ctx.ShouldBind(&book); err != nil {logrus.Error("读取Book信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}bookDao := b.dataSource.BookDao()err := bookDao.AddBook(&book)if err != nil {logrus.Error("添加Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (b *BookController) UpdateBook(ctx *gin.Context) {var book model.Bookif err := ctx.ShouldBind(&book); err != nil {logrus.Error("读取Book信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}bookDao := b.dataSource.BookDao()err := bookDao.UpdateBook(&book)if err != nil {logrus.Error("更新Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (b *BookController) DeleteBook(ctx *gin.Context) {var book model.Bookif err := ctx.ShouldBind(&book); err != nil {logrus.Error("读取Book信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}bookDao := b.dataSource.BookDao()err := bookDao.DeleteBook(&book)if err != nil {logrus.Error("删除Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (b *BookController) ListBookById(ctx *gin.Context) {id := cast.ToUint(ctx.Query("id"))bookDao := b.dataSource.BookDao()book, err := bookDao.ListBookById(id)if err != nil {logrus.Error("查询Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, book)
}
云女士将操作 people 表对应的 web 服务写在了people_controller.go文件中,其实现如下所示。
package adapterimport ("github.com/gin-gonic/gin""github.com/sirupsen/logrus""github.com/spf13/cast""gobase/model""gobase/mysql""net/http"
)type PeopleController struct {dataSource *mysql.DataSouce
}func NewPropleController(dataSource *mysql.DataSouce) PeopleController {return PeopleController{dataSource: dataSource,}
}func (p *PeopleController) AddPeople(ctx *gin.Context) {var people model.Peopleif err := ctx.ShouldBind(&people); err != nil {logrus.Error("读取People信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}peopleDao := p.dataSource.PeopleDao()err := peopleDao.AddPeople(&people)if err != nil {logrus.Error("添加People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (p *PeopleController) UpdatePeople(ctx *gin.Context) {var people model.Peopleif err := ctx.ShouldBind(&people); err != nil {logrus.Error("读取People信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}peopleDao := p.dataSource.PeopleDao()err := peopleDao.UpdatePeople(&people)if err != nil {logrus.Error("更新People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (p *PeopleController) DeletePeople(ctx *gin.Context) {var people model.Peopleif err := ctx.ShouldBind(&people); err != nil {logrus.Error("读取People信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}peopleDao := p.dataSource.PeopleDao()err := peopleDao.DeletePeople(&people)if err != nil {logrus.Error("删除People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (p *PeopleController) ListPeopleById(ctx *gin.Context) {id := cast.ToUint(ctx.Query("id"))peopleDao := p.dataSource.PeopleDao()people, err := peopleDao.ListPeopleById(id)if err != nil {logrus.Error("查询People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, people)
}
最后,云女士简单的展示了一下对 book 表和 prople 表的 Crud 操作。
book 表和 people 表的增删改成功时返回内容如下所示。

book 表和 people 表的查询成功时返回内容如下所示。


Spring boot 快速搭建Crud工程
Spring Boot 基础就不介绍了
云女士基于 Gin 和 Gorm 搭建的 Crud 工程,我看完后内心扑哧一笑:不过如此。
那现在该轮到我表演了。首先给出整个工程结构图如下所示。

POM 文件内容如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.1</version></parent><groupId>com.lee.javabase</groupId><artifactId>javabase</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>
同样,定义 book 表和 people 表对应的实体类 Book 和 People,如下所示。
@Getter
@Setter
public class Book {@TableField("id")private int id;@TableField("b_name")private String bookName;@TableField("b_price")private float bookPrice;}@Getter
@Setter
public class People {@TableField("id")private int id;@TableField("p_name")private String peopleName;@TableField("p_age")private int peopleAge;}
然后定义定义接口,如下所示。
@Mapper
public interface BookMapper extends BaseMapper<Book> {
}@Mapper
public interface PeopleMapper extends BaseMapper<People> {
}
最后是对应的 Controller 实现, BookController 实现如下。
@Slf4j
@RestController
@RequestMapping("/book")
public class BookController {@Autowiredprivate BookMapper bookMapper;@PostMapping("/add")public ResponseEntity<String> addBook(@RequestBody Book book) {try {bookMapper.insert(book);return new ResponseEntity<>("添加图书成功", HttpStatus.OK);} catch (Exception e) {log.error("添加图书失败", e);return new ResponseEntity<>("添加图书失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/update")public ResponseEntity<String> updateBook(@RequestBody Book book) {try {bookMapper.updateById(book);return new ResponseEntity<>("更新图书成功", HttpStatus.OK);} catch (Exception e) {log.error("更新图书失败", e);return new ResponseEntity<>("更新图书失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/delete")public ResponseEntity<String> deleteBook(@RequestParam("id") int id) {try {bookMapper.deleteById(id);return new ResponseEntity<>("删除图书成功", HttpStatus.OK);} catch (Exception e) {log.error("删除图书失败", e);return new ResponseEntity<>("删除图书失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/list")public ResponseEntity<Book> listBook(@RequestParam("id") int id) {try {Book book = bookMapper.selectById(id);return new ResponseEntity<>(book, HttpStatus.OK);} catch (Exception e) {log.error("查询图书失败", e);return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);}}
}
PeopleController 实现如下所示。
@Slf4j
@RestController
@RequestMapping("/people")
public class PeopleController {@Autowiredprivate PeopleMapper peopleMapper;@PostMapping("/add")public ResponseEntity<String> addPeople(@RequestBody People people) {try {peopleMapper.insert(people);return new ResponseEntity<>("添加人物成功", HttpStatus.OK);} catch (Exception e) {log.error("添加人物失败", e);return new ResponseEntity<>("添加人物失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/update")public ResponseEntity<String> updatePeople(@RequestBody People people) {try {peopleMapper.updateById(people);return new ResponseEntity<>("更新人物成功", HttpStatus.OK);} catch (Exception e) {log.error("更新人物失败", e);return new ResponseEntity<>("更新人物失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/delete")public ResponseEntity<String> deletePeople(@RequestParam("id") int id) {try {peopleMapper.deleteById(id);return new ResponseEntity<>("删除人物成功", HttpStatus.OK);} catch (Exception e) {log.error("删除人物失败", e);return new ResponseEntity<>("删除人物失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/list")public ResponseEntity<People> listPeople(@RequestParam("id") int id) {try {People people = peopleMapper.selectById(id);return new ResponseEntity<>(people, HttpStatus.OK);} catch (Exception e) {log.error("查询人物失败", e);return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);}}
}
启动应用程序, book 表的 Crud 操作结果如下所示。

prople 表的 Crud 操作结果如下所示。

总结
我宣布,Springboot 就是快速搭建 Crud 工程的神。
其实,在基于 Gin 和 Gorm 搭建 Crud 工程时,云女士还是写得复杂了一点,但是我有幸看过她们云平台的项目的代码,云女士写得也没毛病,虽然是个简化版,但也是严格遵从她们项目的代码结构来实现的。
说回 Springboot,毫无疑问,无论是天然自带 Tomcat 或 Jetty ,还是和三方框架整合的各种 Starter 包,Springboot 都将开箱即用做到了极致,但是转念又一想,其实 Springboot 和 Gin 严格来说做比较没啥意义,就像 Java 和 Go 的比较一样,我觉得也没啥意义,各自的优势区间不一样,并且各自也都在相关的领域叱咤风云。
各位看官,你们觉得呢。
相关文章:
Go的Gin比java的Springboot更加的开箱即用?
前言 隔壁组的云计算零零后女同事,后文简称 云女士 ,非说 Go 的 Gin 框架比 Springboot 更加的开箱即用,我心想在 Java 里面 Springboot 已经打遍天下无敌手,这份底蕴岂是 Gin 能比。 但是云女士突出一个执拗,非我要…...
pickle常见Error解决
1. pickle OverflowError: cannot serialize a bytes object larger than 4 GiB 进行pickle.dump时出现上述错误,可以加上“protocol4”参数。依据:https://docs.python.org/3/library/pickle.html#data-stream-format 2. pickle EOFError: Ran out of…...
认识Java数据类型和变量
数据类型分类 基本数据类型(8个): 整数型 byte 8位 short 16位 int 32位 long 64位 默认整数类型是int类型 小数型/浮点型 float【单精度32位】 double【双进度64位】 字符型 char 16位 只能表示单个字符 布尔型 boolean 1位 只能有两个值 true 【真】 false 【…...
Qt开发技巧(二十四)滚动部件的滑动问题,Qt设置时区问题,自定义窗体样式不生效问题,编码格式问题,给按钮左边加个图,最小化后的卡死假象
继续记录一些Qt开发中的技巧操作: 1.滚动部件的滑动问题 再Linux嵌入式设备上,有时候一个页面的子部件太多,一屏放不下是需要做页面滑动,可以使用“QScrollArea”控件,拖来一个“QScrollArea”控件,将子部件…...
SHELL----正则表达式
一、文本搜索工具——grep grep -参数 条件 文件名 其中参数有以下: -i 忽略大小写 -c 统计匹配的行数 -v 取反,不显示匹配的行 -w 匹配单词 -E 等价于 egrep ,即启用扩展正则表达式 -n 显示行号 -rl 将指定目录内的文件打…...
44.5.【C语言】辨析“数组指针”和“指针数组”
目录 1.数组指针 2.指针数组 执行结果 底层分析 1.数组指针 从语文的角度理解,"数组"修饰"指针".因此数组指针是指针 例如以下代码 #include <stdio.h> int main() {char a[5] { "ABCDE" };return 0;} 其中a就是数组指针,因为数…...
node.js基础学习-express框架-路由及中间件(十)
一、前言 Express 是一个简洁、灵活的 Node.js Web 应用框架。它基于 Node.js 的内置 HTTP 模块构建,提供了一系列用于构建 Web 应用程序和 API 的功能,使开发者能够更高效地处理 HTTP 请求和响应,专注于业务逻辑的实现。 其特点包括简单易用…...
使用MSYS搭建linux开发环境踩坑笔记
前言: 使用linux系统或虚拟机进行嵌入式linux开发是常规方法; 使用MSYS是用于尝鲜和研究。 由于windows和linux的差异,使用MSYS代替Linux虚拟机会遇到很多坑。 主要原因在于: 1. windows和linux文件系统的差异:win不…...
vue3+ts+vite+ElementPlus上传进度条实时更新(UPLoad和progress)。
需求: 上传文件时,展示进度条实时更新: 下面是代码片段: <!-- 添加媒体弹窗 -- 上传 --><el-dialog v-model"centerDialogVisible" title"媒体信息" width"700" :close-on-click-modal"false&qu…...
AspNet WebAPI 模型绑定问题
继承System.Web.Http.ApiController的Action的Model如果被[Serializable]定义,会导致Model的字段无法绑定。 Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll [Serializable] public class Model {public string id { get; set; } }public MyA…...
Android 图形系统之七:SurfaceFlinger
一. 引言 什么是 SurfaceFlinger?SurfaceFlinger 的核心作用和地位?为什么需要了解 SurfaceFlinger? 二. SurfaceFlinger 的基本概念 Surface 和 SurfaceFlinger 的关系SurfaceFlinger 与图形渲染(OpenGL ES 和 Vulkan…...
14、鸿蒙学习——管理通知角标
针对未读的通知,系统提供了角标设置接口,将未读通知个数显示在桌面图标的右上角角标上。 通知增加时,角标上显示的未读通知个数需要增加。 通知被查看后,角标上显示的未读通知个数需要减少,没有未读通知时࿰…...
TongRDS分布式内存数据缓存中间件
命令 优势 支持高达10亿级的数据缓冲,内存优化管理,避免GC性能劣化。 高并发系统设计,可充分利用多CPU资源实现并行处理。 数据采用key-value多索引方式存储,字段类型和长度可配置。 支持多台服务并行运行,服务之间可互…...
[在线实验]-RabbitMQ镜像的下载与部署
镜像下载 docker的rabbitmq镜像资源-CSDN文库 加载镜像 docker load --input rabbitmq.tar 给镜像打标签 这里发现镜像名为none,需要给镜像重命名下 docker tag [镜像id] [新镜像名称]:[新镜像标签] docker tag ebaf409ffbe2 rabbitmq:management 运行镜像…...
Linux 系统文件描述符(File Descriptor)小白级介绍
1. 概述 Linux 遵循"一切皆文件"的理念。在 Linux 系统中,文件描述符是一个索引值(非负整数),指向内核为每个进程所维护的该进程打开文件的记录表。 如上所述,每个进程都维护着一张文件描述符表。 文件描述…...
【Verilog】实验二 数据选择器的设计与vivado集成开发环境
目录 一、实验目的 二、实验环境 三、实验任务 四、实验原理 五、实验步骤 top.v mux2_1.v 一、实验目的 1. 掌握数据选择器的工作原理和逻辑功能。 2. 熟悉vivado集成开发环境。 3. 熟悉vivado中进行开发设计的流程。 二、实验环境 1. 装有vivado的计算机。 2. Sw…...
IDL学习笔记(三)OMI数据处理。hdf5文件读取,图像反转,GeoTiff区别,月季年均值计算提取输出,单位转换,运行时间计算
modis Level 2 grid 数据是全球格网化数据。一天的数据全在其中。 modis Level 1 和 2 数据是一景一景的影像。 IDL学习笔记(三)OMI数据处理 hdf5文件读取单位转换,输出hdf5数据集的图像,并检查图像经纬度是否正确,若错…...
深入浅出:PHP中的数据类型全解析
文章目录 引言理解数据类型标量类型整数 (integer)浮点数 (float)布尔值 (boolean)字符串 (string) 复合类型数组 (array)对象 (object)资源 (resource)NULL 特殊类型Callable强制类型转换 实战案例总结与展望参考资料 引言 在编程的世界里,数据类型是构建任何应用…...
要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出
要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出 要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出方案一解决方案(openresty使用cjson)说明:使…...
智慧油客:从初识、再识OceanBase,到全栈上线
今天,我们邀请了智慧油客的研发总监黄普友,为我们讲述智慧油客与 OceanBase 初识、熟悉和结缘的故事。 智慧油客自2016年诞生以来,秉持新零售的思维,成功从过去二十年间以“以销售产品为中心”的传统思维模式,转向“以…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
WEB3全栈开发——面试专业技能点P4数据库
一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await…...
