uniapp小程序开发 | 从零实现一款影视类app (后台接口实现,go-zero微服务的使用)

uniapp小程序开发实战系列,完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中,喜欢的可以点击收藏。

该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。 

后台服务使用golang,因为它太适合做后台服务了。而且配合使用go-zero微服务框架,不但强大,还提供了好用的goctl工具,自动生成接口框架代码,让你写接口速度飞升。

下文以两个接口(轮播图接口和豆瓣热门影视接口)示例,可以看到使用go-zero写服务接口是多么的简单。

为了示例和快速实现,暂无后台管理界面。只实现后台接口。

轮播图接口,返回json数据,图片存储在腾讯云的COS对象存储服务,作为图床使用。

豆瓣正在热映电影接口,使用go-zero的httpc转发客户端请求,到豆瓣v2的开源api服务(https://api.douban.com/v2)接口去请求数据。

go-zero 介绍

go-zero是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验。

go-zero 包含极简的 API 定义和生成工具 goctl,可以根据定义的 api 文件一键生成 Go, iOS, Android, Kotlin, Dart, TypeScript, JavaScript 代码,并可直接运行。

详细介绍:go-zero 缩短从需求到上线的距离

github地址:https://github.com/zeromicro/go-zero

文档介绍:go-zero/readme-cn.md at master · zeromicro/go-zero · GitHub 

goctl 工具安装

goctl 是 go-zero 的内置脚手架,是提升开发效率的一大利器,可以一键生成代码、文档、部署 k8s yaml、dockerfile 等。

# Go
GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest

# For Mac
brew install goctl

# docker for amd64 architecture
docker pull kevinwan/goctl
# run goctl like
docker run --rm -it -v `pwd`:/app kevinwan/goctl --help

由于我是在我的ubuntu20服务器上安装使用的,所以选择了方式三。其实如果使用vscode, 则可以直接安装插件即可,在vscode中搜索goctl插件。 在windows 上安装就不提了,更简单了。

由于我的测试代码跑在腾讯云服务器上,建议使用vscode远程连接的开发方式。在vscode上安装Remote - SSH插件,非常好用,使用方法:VSCODE远程连接服务器,远程开发。

goctl快速使用文档:zero-doc/docs/zero/goctl-api.md at main · zeromicro/zero-doc · GitHub 

快速开始 

前提是具备golang环境和成功安装完成了goctl工具。

简易使用教程,参加我的博客:go-zero微服务框架入门教程_go-zero教程-CSDN博客

下面介绍下如何快速开始一个使用go-zero微服务框架的一个项目。

goctl api new greet
cd greet
go mod tidy
go run greet.go -f etc/greet-api.yaml

执行以上代码,会自动创建工程目录greet,生成一些可以运行的模板文件。一个工程就创建完啦,且执行go run 命令,后台网关服务就已经启动起来啦,默认端口8888,这么简单。

接下来可以使用 curl命令测试一下接口: 

curl -i http://localhost:8888/from/you
  • api 文件定义了服务对外 HTTP 接口,可参考 api 规范
  • 可以在 servicecontext.go 里面传递依赖给 logic,比如 mysql, redis 等。

生成 api 服务

完成上面后,只是一个空的服务接口,如何增加自己的呢?接下来详细介绍。其实就是写好api文件。api 文件定义了服务对外 HTTP 接口,按它的api规范定义自己的接口文件。

我的api文件如下:

syntax = "v1"

info (
	title:   "doc title"
	desc:    "imovie background service api"
	version: "1.0"
)

type (
	//轮播图--应答
	SwiperData {
		id       int    `json:"id"`
		imageUrl string `json:"imageUrl"`
		title    string `json:"title"`
		desc     string `json:"description"`
	}
	SwiperResp {
		code    int          `json:"code"`
		message string       `json:"message"`
		data    []SwiperData `json:"data"`
	}
	//热门影视--请求
	HotMovieReq {
		start int    `json:"start"`
		count int    `json:"count"`
		city  string `json:"city"`
	}
	//热门影视--应答
	HotItem {
		id    string `json:"id"`
		cover string `json:"cover"`
		title string `json:"title"`
		rate  int    `json:"rate"`
	}
	HotMovieResp {
		code    int       `json:"code"`
		message string    `json:"message"`
		data    []HotItem `json:"data"`
		count   int       `json:"count"`
		start   int       `json:"start"`
		total   int       `json:"total"`
		title   string    `json:"title"`
	}
)

type Request {
	Name string `path:"name,options=you|me"`
}

type Response {
	Message string `json:"message"`
}

service imovie-api {
	@doc (
		summary: "imovie api"
	)
	@handler TestHandler
	get /test/:name (Request) returns (Response)

	@handler SwiperHandler
	get /api/v1/swiperdata returns (SwiperResp)

	@handler HotMovieHandler
	post /api/v1/hotmovie (HotMovieReq) returns (HotMovieResp)
}

由于我是在ubuntu服务器上以docker方式安装的goctl工具,所以使用起来有点儿麻烦,类似下面这样这么长一串:

docker run --rm -it -v `pwd`:/app kevinwan/goctl --help

为了简单使用docker方式安装部署的goctl工具,写了以下配置: 

docker-compose.yml

   version: '3'
   services:
     goctl:
       image: kevinwan/goctl
       volumes:
         - .:/app
       working_dir: /app
   

于是后续再使用goctl命令,变成了下面这种方式,使用下述命令自动生成接口代码: 

sudo docker-compose run goctl api go -api go-imovie/imovie.api -dir go-imovie/

上述命令,就根据 api 文件自动生成了服务接口代码。

参数含义介绍:

业务代码编写 

接下来开始关键的地方了,业务接口的业务逻辑编写,这部分主要在internal文件夹下的logic文件夹下实现。

轮播图接口

swiperlogic.go文件实现

package logic

import (
	"context"

	"imovie/internal/svc"
	"imovie/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type SwiperLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

var MyPic_ = "https://pic-1258623197.cos.ap-beijing.myqcloud.com"

func NewSwiperLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SwiperLogic {
	return &SwiperLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SwiperLogic) Swiper() (resp *types.SwiperResp, err error) {
	// todo: add your logic here and delete this line
	//var item types.SwiperData
	var responseData []types.SwiperData

	item1 := types.SwiperData{
		Id:       1,
		ImageUrl: MyPic_ + "/pic0/1.jpg",
		Title:    "标题1",
	}

	item2 := types.SwiperData{
		Id:       2,
		ImageUrl: MyPic_ + "/pic0/2.jpg",
		Title:    "标题2",
	}

	item3 := types.SwiperData{
		Id:       3,
		ImageUrl: MyPic_ + "/pic0/3.jpg",
		Title:    "标题3",
	}

	responseData = append(responseData, item1)
	responseData = append(responseData, item2)
	responseData = append(responseData, item3)

	resp = &types.SwiperResp{
		Code:    0,
		Message: "success",
		Data:    responseData,
	}
	return resp, nil
}

热映电影接口 

hotmovielogic.go文件实现,实现客户端接口转发到豆瓣服务接口。

package logic

import (
	"context"
	"encoding/json"
	"io"
	"net/http"

	"imovie/internal/svc"
	"imovie/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpc"
)

type HotMovieLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

var Url_ = "https://api.douban.com/v2/movie/in_theaters"
var ApiKey_ = "xxxxxxxxxx"
var Referer_ = "https://images.weserv.nl/?url="

func NewHotMovieLogic(ctx context.Context, svcCtx *svc.ServiceContext) *HotMovieLogic {
	return &HotMovieLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *HotMovieLogic) HotMovie(req *types.HotMovieReq) (resp *types.HotMovieResp, err error) {
	// todo: add your logic here and delete this line
	type Request struct {
		Req    types.HotMovieReq
		ApiKey string `json:"apikey"`
	}
	req_ := Request{
		Req:    *req,
		ApiKey: ApiKey_,
	}
	l.Debug(req_)
	url := Url_
	res, err_ := httpc.Do(l.ctx, http.MethodPost, url, req_)
	if err_ != nil {
		l.Error(err_)
		return nil, err_
	}
	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)
	if err != nil {
		l.Errorf("Failed to read response body:", err)
		return nil, err
	}
	//格式化输出json
	//var str bytes.Buffer
	//_ = json.Indent(&str, []byte(body), "", "    ")
	//l.Debugf("formated: ", str.String())
	var keyVal map[string]interface{}
	err = json.Unmarshal(body, &keyVal)
	if err != nil {
		l.Errorf("Failed to extract key value:", err)
	}
	//l.Debug(keyValue)
	var hot types.HotItem
	var responseData []types.HotItem
	list_, ok := keyVal["subjects"].([]interface{})
	if ok {
		for _, item := range list_ {
			itemMap, ok := item.(map[string]interface{})
			if ok {
				//l.Debug(itemMap)
				hot.Id = itemMap["id"].(string)
				hot.Title = itemMap["title"].(string)
				tmp := itemMap["images"].(map[string]interface{})
				hot.Cover = Referer_ + tmp["small"].(string)
				hot.Rate = int(itemMap["rating"].(map[string]interface{})["average"].(float64))
			}
			responseData = append(responseData, hot)
		}
	}
	//t := reflect.TypeOf(keyVal["count"])
	//l.Debugf("Type: %v\n", t)
	resp = &types.HotMovieResp{
		Code:    0,
		Message: res.Status,
		Data:    responseData,
		Count:   int(keyVal["count"].(float64)),
		Start:   int(keyVal["start"].(float64)),
		Total:   int(keyVal["total"].(float64)),
		Title:   keyVal["title"].(string),
	}
	return resp, nil
}

启动服务

启动服务很简单,直接进入项目目录并执行 go run imovie.go即可。默认端口8888.

如果要更改配置,可以进入项目目录下的etc文件夹,找到imovie-api.yml文件修改。配置文件默认是yaml格式。日志的级别也可以在这里配置更改:

Name: imovie-api
Host: 0.0.0.0
Port: 8000
Log:
  Level: debug

关于YAML文件

YAML(YAML Ain't Markup Language)是一种简洁、易读、易写的,用于数据序列化的数据交换格式。它常用于配置文件,因为它比XML更简洁,比JSON更易读写(支持多行文本、注释等)。

YAML的基本特点:

1.大小写敏感

2.使用缩进表示层级关系:不允许使用Tab键,必须使用空格,且相同层级的元素左侧对齐。

3.# 表示注释,从这个字符开始直到行尾的内容都会被忽略。

YAML 文件示例

下面是一个简单的YAML文件示例,展示了如何定义键值对、数组、嵌套结构以及使用注释。

# 这是一个YAML配置文件示例
server:
  # 服务器地址
  host: "localhost"
  # 服务器端口
  port: 8080

# 数据库配置
database:
  # 数据库类型
  type: "mysql"
  # 数据库地址
  host: "127.0.0.1"
  # 用户名
  username: "root"
  # 密码
  password: "password123"

# 应用日志设置
logging:
  level: "info"    # 日志级别
  # 日志文件路径
  file: "/var/log/app.log"

# 开发者列表
developers:
  - name: "张三"
    email: "zhangsan@example.com"
  - name: "李四"
    email: "lisi@example.com"

在这个示例中,server、database、logging 和 developers 是顶层键,每个键下可以有子键。
# 符号后面的内容是注释。

数组(如 developers)通过 - 符号标识每个元素,并且每个元素都是一个映射(键值对)。

YAML文件在许多编程语言和框架中都有良好的支持,用于配置应用程序的各种设置。 

接口测试工具

推荐使用vscode的rest client插件,编写以下测试(文件名test.http):

post http://175.178.126.10:8000/api/v1/hotmovie
Content-Type:application/json
 
{
    "start": 0,
    "count": 1,
    "city": "郑州"
}

### 下一项测试,注意前面三个###分割

 结果成功收到应答:

豆瓣接口介绍

获取正在热映的电影

使用vscode的rest client插件测试接口:

### Below is the code of douban.http,use vscode extension REST Client to send request.

post https://api.douban.com/v2/movie/in_theaters
Content-Type:application/json
 
{
    "start": 0,
    "count": 1,
    "city": "郑州",
    "apikey": "xxxxxxxxxxx"
}


### Respondse

{
  "count": 1,
  "start": 0,
  "total": 43,
  "subjects": [
  ],
  "title": "\u6b63\u5728\u4e0a\u6620\u7684\u7535\u5f71-\u90d1\u5dde"
}

或者使用curl命令测试接口: 

curl --location --request POST 'https://api.douban.com/v2/movie/in_theaters?city=广州&start=0&count=1' --data-urlencode 'apikey=xxxxxxxxxxxxxx' |python3 -m json.tool

% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1732  100  1693  100    39   4480    103 --:--:-- --:--:-- --:--:--  4582
{
    "count": 1,
    "start": 0,
    "total": 46,
    "subjects": [
        {
            "rating": {
                "max": 10,
                "average": 9.5,
                "stars": "50",
                "min": 0
            },
            "genres": [
                "\u7eaa\u5f55\u7247",
                "\u97f3\u4e50"
            ],
            "title": "\u5742\u672c\u9f99\u4e00\uff1a\u6770\u4f5c",
            "casts": [
                {
                    "alt": "https://movie.douban.com/celebrity/1148641/",
                    "avatars": {
                        "small": "https://img1.doubanio.com/view/personage/m/public/12ce4a9f67eac0cb029736ae87549dd0.jpg",
                        "large": "https://img1.doubanio.com/view/personage/m/public/12ce4a9f67eac0cb029736ae87549dd0.jpg",
                        "medium": "https://img1.doubanio.com/view/personage/m/public/12ce4a9f67eac0cb029736ae87549dd0.jpg"
                    },
                    "name": "\u5742\u672c\u9f99\u4e00",
                    "id": "1148641"
                }
            ],
            "collect_count": 19158,
            "original_title": "Ryuichi Sakamoto | Opus",
            "subtype": "movie",
            "directors": [
                {
                    "alt": "https://movie.douban.com/celebrity/1442776/",
                    "avatars": {
                        "small": "https://img1.doubanio.com/view/celebrity/m/public/pXA5FFrGwJ94cel_avatar_uploaded1597077781.8.jpg",
                        "large": "https://img1.doubanio.com/view/celebrity/m/public/pXA5FFrGwJ94cel_avatar_uploaded1597077781.8.jpg",
                        "medium": "https://img1.doubanio.com/view/celebrity/m/public/pXA5FFrGwJ94cel_avatar_uploaded1597077781.8.jpg"
                    },
                    "name": "\u7a7a\u97f3\u592e",
                    "id": "1442776"
                }
            ],
            "year": "2023",
            "images": {
                "small": "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2907966076.jpg",
                "large": "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2907966076.jpg",
                "medium": "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2907966076.jpg"
            },
            "alt": "https://movie.douban.com/subject/36491177/",
            "id": "36491177"
        }
    ],
    "title": "\u6b63\u5728\u4e0a\u6620\u7684\u7535\u5f71-\u5e7f\u5dde"
}

访问外部图片返回 403 Forbidden 错误问题

遇到提示{"code":"40310015","msg":"referer uri is forbidden"},表明豆瓣对图片资源的访问实施了Referer策略,只允许特定来源(referer)的请求访问图片资源。当你直接在浏览器中输入图片链接能访问,是因为浏览器的请求被视为合法的直接访问,而前端应用(尤其是Web应用)发起请求时,如果其域名不在豆瓣允许的Referer列表中,就会被拒绝访问。

可以在前端页面头部添加一个meta:

<meta name="referrer" content="no-referrer" />

或者最简单的方式就是在<img>标签中增加:

<img src=""    referrerPolicy="no-referrer">

各有优缺点吧,某些旧版本或非主流浏览器可能不支持 referrer-policy。如果原始服务器严格限制Referer,上述这种方法可能无效。

也可以借助Images.weserv.nl图片缓存网站帮我们解决这个问题。

images.weserv.nl 是一个免费的图片托管和缓存服务,它可以用来间接访问受Referer限制的图片。这个服务会将原始图片URL作为参数传递,然后返回一个新的URL,这个新URL可以直接在前端使用,而不需要担心Referer限制。

使用 images.weserv.nl 的步骤如下:

替换图片URL:将豆瓣的原始图片URL替换为 https://images.weserv.nl/?url=<原始图片URL>。

在前端处理:

// 图片防盗链问题解决
function attachImageUrl(srcUrl) {
	if (srcUrl !== undefined) {
	  return srcUrl.replace(/http\w{0,1}:\/\/p/g, 'https://images.weserv.nl/?url=p')
	}
}

或者后台处理,返回的图片url上做处理。

var Referer_ = "https://images.weserv.nl/?url="
    var Referer_ = "https://images.weserv.nl/?url="
    var keyVal map[string]interface{}
	err = json.Unmarshal(body, &keyVal)
	if err != nil {
		l.Errorf("Failed to extract key value:", err)
	}
	//l.Debug(keyValue)
	var hot types.HotItem
	var responseData []types.HotItem
	list_, ok := keyVal["subjects"].([]interface{})
	if ok {
		for _, item := range list_ {
			itemMap, ok := item.(map[string]interface{})
			if ok {
				//l.Debug(itemMap)
				hot.Id = itemMap["id"].(string)
				hot.Title = itemMap["title"].(string)
				tmp := itemMap["images"].(map[string]interface{})
				hot.Cover = Referer_ + tmp["small"].(string)
				hot.Rate = int(itemMap["rating"].(map[string]interface{})["average"].(float64))
			}
			responseData = append(responseData, hot)
		}
	}

由于豆瓣接口返回的json数据比较多且略显杂乱,上述的json解析显得很麻烦。其实可以借助golang的三方库gjson处理这种格式的json数据。 gjson地址:GitHub - tidwall/gjson: Get JSON values quickly - JSON parser for Go

图床服务推荐

我使用的是腾讯云,上面的COS对象存储服务,可以作为开发测试用。它提供试用和免费额度,且提供免费域名直接可以https访问,挺不错的。虽然github和gitee也能用作免费图床,但是github访问慢,而gitee直接停止page服务,无法用了。

关于图床工具,推荐使用PicList.

PicList是一款高效的云存储和图床平台管理工具,在PicGo的基础上经过深度的二次开发,不仅完整保留了PicGo的所有功能,还增添了许多新的feature。例如相册支持同步云端删除文件,内置图床额外添加了WebDav、本地图床和SFTP等。

PicList同时增加了完整的云存储管理功能,包括云端目录查看、文件搜索、批量上传下载和删除文件,复制多种格式文件链接和图片/markdown/文本/视频预览等,另外还有更加强大的相册和多项功能新增或优化。

写在最后

最后,附上完整后台golang源码:https://download.csdn.net/download/qq8864/89401886

其他资源

0ab215a8b1977939201640fa14c66bab

https://go-zero.dev/docs/tutorials

https://zhuanlan.zhihu.com/p/570979109

https://github.com/zeromicro/go-zero?tab=readme-ov-file

https://github.com/zeromicro/zero-doc/blob/main/docs/zero/goctl-api.md

https://zhuanlan.zhihu.com/p/529462051

GitHub - tidwall/gjson: Get JSON values quickly - JSON parser for Go

https://www.jianshu.com/p/ef3fcf94295b

https://zhuanlan.zhihu.com/p/113500478

https://juejin.cn/post/6844903832040767496

https://blog.51cto.com/lanxf/5536521

uniapp中image不显示网络图片_uniapp image站外图片-CSDN博客

https://www.cnblogs.com/bigron/p/17334936.html

小白的最强保姆教学:PicGo + gitee +Typora免费搭建属于个人的图床工具_picgo+csdn-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/682549.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3学习(七)

前言 接上一篇学习笔记&#xff0c;今天主要是分享上次学习完了&#xff0c;还没来得及记录&#xff0c;趁今天晚上换换脑子的时间记录下。 今天主要是记录的vuex文件的拆分&#xff0c;因为毕竟如果只在一个index.js文件写&#xff0c;文件会随着业务的复杂性上升&…

益智内容教培教育课程小程序的效果是什么

从孩子出生开始&#xff0c;很多家长们就可以开始制定学习计划&#xff0c;幼儿园前后时间段益智学习家长们很看重&#xff0c;各样的线上课程、线下读本及老师指导等。 市场中也有相关从业公司&#xff0c;在品牌拓展和内容触达转化方面发力&#xff0c;客商双方服务获取条件…

王道408数据结构CH4_串

概述 4 串 4.1 串的实现 4.1.1 存储结构 定长顺序存储 #define Maxsize 255typedef struct{char *ch[Maxsize];int length; }SString;堆分配存储 typedef struct{char *ch;int length; }HString;块链存储 4.1.2 基本操作 4.2 模式匹配&#xff08;子串定位&#xff09; 4.2.…

如何有效防御.360勒索病毒:.360勒索病毒加密文件预防方法探讨

导言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全问题也日益凸显。其中&#xff0c;勒索病毒作为一种新型的网络安全威胁&#xff0c;给用户和企业带来了极大的困扰和损失。特别是.360勒索病毒&#xff0c;以其独特的加密方式和恶劣的勒索手段&#xff0c;引起了…

宝兰德参编!《2023年中国数据库年度行业分析报告》正式发布

近日&#xff0c;墨天轮发布 《2023年中国数据库年度行业分析报告》&#xff08;以下简称《报告》&#xff09;。宝兰德深度参与《报告》重要章节内容的编写工作&#xff0c;凭借在中间件领域深厚的技术沉淀和丰富的实践经验&#xff0c;输出了大量具有专业性和前瞻性的意见&am…

计算机组成原理一轮

目录 一、计算机系统概论 组成 概念 二、计算机的运算方法 二进制和八进制、二进制和八进制间的转换 任意进制数转换为十进制数 十进制转二进制 移码 定点数的移位运算 定点数的加减运算 定点数的乘除运算 相乘 相除 溢出的判别方法 采用一位符号位 采用双符号…

【微机原理与汇编语言】并行接口8255实验

一、实验目的 掌握可编程并行接口芯片8255的工作原理及初始化方法掌握8255在实际应用中的硬件连接及编程应用 二、实验要求 根据实验室现有条件&#xff0c;针对实验任务&#xff0c;设计实验方案并进行实现。 三、实验内容 启动0#计数器&#xff0c;每计5个数&#xff08…

elasticsearch安装与使用(1)-使用docker安装Elasticsearch

1、Elasticsearch安装 docker network create elastic docker pull docker.elastic.co/elasticsearch/elasticsearch:8.3.3 docker run --name es-node01 --net elastic -p 9200:9200 -p 9300:9300 -it docker.elastic.co/elasticsearch/elasticsearch:8.3.3-----------------…

大模型时代,是 Infra 的春天还是冬天?

Highlights 大模型时代元年感悟 Scaling Laws 是大模型时代的摩尔定律,是最值得研究的方向 LLM 发展的三个阶段: 算法瓶颈 -> 数据瓶颈 -> Infra 瓶颈 为什么 GPT 一枝独秀, BERT、T5 日落西山? 大模型时代,是大部分 Infra 人的冬天,少部分 Infra 人的春天(算法研…

PID控制算法介绍及使用举例

PID 控制算法是一种常用的反馈控制算法&#xff0c;用于控制系统的稳定性和精度。PID 分别代表比例&#xff08;Proportional&#xff09;、积分&#xff08;Integral&#xff09;和微分&#xff08;Derivative&#xff09;&#xff0c;通过组合这三个部分来调节控制输出&#…

【成都信息工程大学】只考程序设计!成都信息工程大学计算机考研考情分析!

成都信息工程大学&#xff08;Chengdu University of Information Technology&#xff09;&#xff0c;简称“成信大”&#xff0c;由中国气象局和四川省人民政府共建&#xff0c;入选中国首批“卓越工程师教育培养计划”、“2011计划”、“中西部高校基础能力建设工程”、四川…

eNSP学习——VRRP基础配置、多备份组、跟踪接口及认证

目录 主要命令 实验一、VRRP基础配置 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、部署OSPF网络 3、配置VRRP协议 4、验证VRRP主备切换 实验二、配置VRRP多备份组 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本…

LeetCode-82. 删除排序链表中的重复元素 II【链表 双指针】

LeetCode-82. 删除排序链表中的重复元素 II【链表 双指针】 题目描述&#xff1a;解题思路一&#xff1a;用一个cur即可实现去重cur.next cur.next.next背诵版&#xff1a;解题思路三&#xff1a;0 题目描述&#xff1a; 给定一个已排序的链表的头 head &#xff0c; 删除原始…

数据结构:模拟栈

数据结构&#xff1a;模拟栈 题目描述参考代码 题目描述 输入样例 10 push 5 query push 6 pop query pop empty push 4 query empty输出样例 5 5 YES 4 NO参考代码 #include <iostream>using namespace std;const int N 1000010;int m, x; int q[N]; string op; int…

2024年数字化经济与智慧金融国际会议(ICDESF 2024)

2024 International Conference on Digital Economy and Smart Finance 【1】大会信息 大会时间&#xff1a;2024-07-22 大会地点&#xff1a;中国成都 截稿时间&#xff1a;2024-07-10(以官网为准&#xff09; 审稿通知&#xff1a;投稿后2-3日内通知 会议官网&#xff1a;h…

使用libgpiod库中的事件方式监测多个输入事件

Linux下要同时检测多个GPIO输入的方法有很多&#xff0c;这里我使用libgpiod库中的API实现多个GPIO输入检测&#xff0c;可以达到类似STM32利用外部中断实现输入事件检测的效果&#xff0c;示例代码如下所示&#xff1a; /* 示例使用的libgpiod库版本为V1.2.1 */ //示例功能是…

前端逆向之下载canvas引用的图片

前端逆向之下载canvas引用的图片 一、来源二、解决三、如果在Network这里也找不到呢&#xff1f; 一、来源 当我们用dom检查器的时候无法选中想要扒下来的图片&#xff0c;只能选中canvas&#xff0c;这种时候该怎么办呢&#xff1f; 二、解决 这个时候应该换个脑子&#xf…

SAP PP学习笔记17 - MTS(Make-to-Stock) 按库存生产(策略70)

上几章讲了几种策略&#xff0c;策略10&#xff0c;11&#xff0c;30&#xff0c;40。 SAP PP学习笔记14 - MTS&#xff08;Make-to-Stock) 按库存生产&#xff08;策略10&#xff09;&#xff0c;以及生产计划的概要-CSDN博客 SAP PP学习笔记15 - MTS&#xff08;Make-to-St…

MySQL的联合索引及案例分析

1. 联合索引 关于联合索引的详解参考博客【Mysql-----联合索引和最左匹配】&#xff0c;包含讲解 最左匹配 联合索引失效的情况 不遵循最左匹配原则范围查询右边失效原理like索引失效原理 比较关注的点在于&#xff1a; 对A、B、C三个字段创建一个联合索引&#xff08;A, …

计算机SCI期刊,中科院3区,对国人相当友好

一、期刊名称 Image and Vision Computing 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;4.7 中科院分区&#xff1a;3区 三、期刊征稿范围 图像和视觉计算的主要目标是为图像解释和计算机视觉各个方面的高质量理论和应…