Go语言项目实战班04 Go语言课程管理系统项目实战 20240807 课程笔记和上课代码

预览

在这里插入图片描述

课程特色

本教程录制于2024年8月8日,使用Go1.22版本,基于Goland2024进行开发,采用的技术栈比较新。

每节课控制在十分钟以内,课时精简,每节课都是一个独立的知识点,如果有遗忘,完全可以当做字典来查询,绝不浪费大家的时间。

整个课程从两行代码实现注册登录API接口讲起,以一个课程系统为实战,结合Vue3开发的前端,实现一个基本的前后端分离的课程管理系统,层层递进,学习路径平缓。

Golang是当前国内越来越多的企业正在全面转的一门系统级别的高性能的编程语言,比C语言写法更加的简单,比Python性能更加的好,是新时代的C语言,建议每个程序员都掌握!

视频课程

最近发现越来越多的公司在用Golang了,所以精心整理了一套视频教程给大家,这个是其中的第15部,后续还会有很多。

视频已经录制完成,完整目录截图如下:

在这里插入图片描述

本套录播课的售价是319元。

本套课程的特色是每节课都是一个核心知识点,每个视频控制在十分钟左右,精简不废话,拒绝浪费大家的时间。

课程目录

  • 01 概述
  • 02 搭建项目环境
  • 03 连接MySQL数据库
  • 04 课程表的设计和创建
  • 05 项目工程化
  • 06 整合gin框架
  • 07 两行代码自动生成注册和登录接口
  • 08 封装路由模块
  • 09 实现新增课程的接口
  • 10 实现分页查询的接口
  • 11 实现根据ID查询课程的接口
  • 12 解决根据ID查询不生效的问题
  • 13 实现根据ID修改课程的接口
  • 14 实现根据ID删除课程的接口
  • 15 前端界面的整体预览和开发思路
  • 16 实现登录的功能
  • 17 实现记录token和跳转首页的功能
  • 18 实现显示登录用户名的功能
  • 19 实现注销的功能
  • 20 解决注销按钮无法自动显示的BUG
  • 21 完善写作页面和双向绑定变量的设计
  • 22 给写作接口添加简单的权限校验
  • 23 实现添加文章的功能
  • 24 实现文章的请求和动态渲染
  • 25 将秒值转换为年月日字符串
  • 26 实现点击文章标题跳转详情页面的功能
  • 27 实现文章详情的渲染
  • 28 渲染课程的价格
  • 29 渲染编辑按钮
  • 30 实现编辑课程的功能
  • 31 给编辑文章的接口添加简单的权限校验
  • 32 总结

完整代码

03 连接MySQL数据库

package gimport ("api/model"ginLogin "github.com/zhangdapeng520/zdpgo_gin_login"gorm "github.com/zhangdapeng520/zdpgo_gorm"_ "github.com/zhangdapeng520/zdpgo_mysql"
)var GDB *gorm.DBfunc initMySQL() {var err errorGDB, err = gorm.Open("mysql","root:root@tcp(127.0.0.1:3306)/blog?charset=utf8mb4&parseTime=True&loc=Local",)if err != nil {panic(err)}GDB.AutoMigrate(&model.CourseArticle{})GDB.AutoMigrate(&ginLogin.GinLoginUser{})
}func closeMySQL() {GDB.Close()
}

04 课程表的设计和创建

package modeltype CourseArticle struct {Id          int     `json:"id"`Title       string  `json:"title" gorm:"unique"`          // 标题Category    string  `json:"category"`                     // 分类Description string  `json:"description"`                  // 描述Content     string  `json:"content" gorm:"type:longtext"` // 内容Price       float64 `json:"price" gorm:"type:decimal"`    // 价格SaleNum     int     `json:"sale_num"`                     // 销量GoodNum     int     `json:"good_num"`                     // 点赞数量MoneyNum    int     `json:"money_num"`                    // 打赏数量ViewNum     int     `json:"view_num"`                     // 浏览量AddTime     int     `json:"add_time"`                     // 添加时间UpdateTime  int     `json:"update_time"`                  // 修改时间
}

07 两行代码自动生成注册和登录接口

package routerimport ("api/g"gin "github.com/zhangdapeng520/zdpgo_gin"ginLogin "github.com/zhangdapeng520/zdpgo_gin_login"
)func initUser(app *gin.Engine) {group := app.Group("/user")group.POST("/register/",ginLogin.GetRegisterHandler(g.GDB, g.PasswordSalt),)group.POST("/login/",ginLogin.GetLoginHandler(g.GDB, g.JwtKey, g.PasswordSalt),)
}

09 实现新增课程的接口

package course_articleimport ("api/g""api/model"gin "github.com/zhangdapeng520/zdpgo_gin""time"
)func add(c *gin.Context) {// 解析请求var req requestCourseArticleif err := c.ShouldBindJSON(&req); err != nil {c.JSON(400, gin.H{"error": err.Error()})return}// 对作者做简单的限制,只有指定的作者才能拥有写作权限if req.Author != "zhangdapeng" {c.JSON(402, gin.H{"error": "you have not authorization"})return}// 新增now := int(time.Now().Unix())g.GDB.Create(&model.CourseArticle{Title:       req.Title,Category:    req.Category,Description: req.Description,Content:     req.Content,Price:       req.Price,SaleNum:     0,GoodNum:     0,MoneyNum:    0,ViewNum:     0,AddTime:     now,UpdateTime:  now,})c.JSON(200, nil)
}

10 实现分页查询的接口

package course_articleimport ("api/g""api/model"gin "github.com/zhangdapeng520/zdpgo_gin""strconv"
)func getAll(c *gin.Context) {pageStr := c.DefaultQuery("page", "1")sizeStr := c.DefaultQuery("size", "20")page, err := strconv.Atoi(pageStr)if err != nil {c.JSON(400, gin.H{"error": err.Error()})return}size, err := strconv.Atoi(sizeStr)if err != nil {c.JSON(400, gin.H{"error": err.Error()})return}var articles []model.CourseArticleg.GDB.Limit(size).Offset((page - 1) * size).Order("update_time desc").Find(&articles)c.JSON(200, articles)
}func get(c *gin.Context) {idStr := c.Param("id")id, err := strconv.Atoi(idStr)if err != nil {c.JSON(400, gin.H{"error": err.Error()})return}var article model.CourseArticleg.GDB.Find(&article, "id=?", id)c.JSON(200, article)
}

13 实现根据ID修改课程的接口

package course_articleimport ("api/g""api/model"gin "github.com/zhangdapeng520/zdpgo_gin""strconv"
)func update(c *gin.Context) {idStr := c.Param("id")id, err := strconv.Atoi(idStr)if err != nil {c.JSON(400, gin.H{"error": err.Error()})return}// 解析请求var req requestCourseArticleif err := c.ShouldBindJSON(&req); err != nil {c.JSON(400, gin.H{"error": err.Error()})return}// 添加简单的权限校验if req.Author != "zhangdapeng" {c.JSON(402, gin.H{"error": "you have not authorization"})return}// 根据ID查询var article model.CourseArticleg.GDB.Find(&article, "id=?", id)if article.Id == 0 {c.JSON(404, gin.H{"error": "article not found"})return}// 修改article.Title = req.Titlearticle.Category = req.Categoryarticle.Price = req.Pricearticle.Description = req.Descriptionarticle.Content = req.Contenterr = g.GDB.Save(&article).Errorif err != nil {c.JSON(500, gin.H{"error": err.Error()})return}c.JSON(200, nil)
}

14 实现根据ID删除课程的接口

package course_articleimport ("api/g""api/model"gin "github.com/zhangdapeng520/zdpgo_gin""strconv"
)func deleteArticle(c *gin.Context) {idStr := c.Param("id")id, err := strconv.Atoi(idStr)if err != nil {c.JSON(400, gin.H{"error": err.Error()})return}err = g.GDB.Delete(&model.CourseArticle{Id: id}).Errorif err != nil {c.JSON(500, gin.H{"error": err.Error()})return}c.JSON(200, nil)
}

16 实现登录的功能

<template><form class="p-3"><div class="form-group"><label for="username">账号</label><input type="text" class="form-control" id="username" v-model="username"></div><div class="form-group"><label for="password">密码</label><input type="password" class="form-control" id="password" v-model="password"></div><button class="btn btn-primary" @click="onLogin">立即登录</button></form></template><script setup lang="ts">
import {ref} from "vue";
import axios from "redaxios";
import {useRouter} from "vue-router";const username = ref("")
const password = ref("")
const router = useRouter()const onLogin = () => {if (username.value == "") {alert("请输入用户名")return}if (username.value.length < 3) {alert("用户名长度最小为3")return}if (username.value.length > 36) {alert("用户名长度最大为36")return}if (password.value == "") {alert("请输入密码")return}if (password.value.length < 6) {alert("密码长度最小为6")return}if (password.value.length > 128) {alert("密码长度最大为128")return}axios({method: "POST",url: "/api/user/login/",data: {username: username.value,password: password.value,}}).then((res) => {let data =res.dataif (data){localStorage.setItem("token", data.token)localStorage.setItem("username", data.username)router.push("/")}else{alert("登录失败!")}})
}
</script>

18 实现显示登录用户名的功能

<template><navclass="navbar navbar-expand-md navbar-light mb-0":style="`background-color: ${VUE_APP_NAVBAR_BG_CSS_COLOR}; color: ${VUE_APP_NAVBAR_TEXT_CSS_COLOR};`"><router-linkclass="navbar-brand":to="'/'":style="`color: ${VUE_APP_NAVBAR_TEXT_CSS_COLOR};`">{{ title }}</router-link><button:class="`navbar-toggler collapsed`"type="button"aria-label="Toggle navigation"@click.prevent="showDropdown = !showDropdown"><spanclass="navbar-toggler-icon":style="`background-color: ${VUE_APP_NAVBAR_TEXT_CSS_COLOR};`"/></button><divid="navbarNavDropdown"class="navbar-collapse"><ul class="navbar-nav ml-auto top-right"@focusout="focusOut"tabindex="1"><li class="category">Python</li><li class="category">Golang</li><li class="nav-item" v-if="username"><aclass="nav-link border rounded py-2 px-3 mr-2"style="color: white">{{ username }}</a></li><li class="nav-item" v-else><router-linkclass="nav-link border rounded py-2 px-3 mr-2":to="'/login'":style="`color: ${VUE_APP_NAVBAR_TEXT_CSS_COLOR};`">登录</router-link></li><li class="nav-item" v-if="username"><aclass="nav-link border rounded py-2 px-3 mr-2 logout"@click.prevent="onLogout"style="color: white">注销</a></li><li v-if="router.currentRoute.value.path !== '/editor'" class="nav-item"><router-linkclass="nav-link border rounded py-2 px-3":to="'/editor'":style="`color: ${VUE_APP_NAVBAR_TEXT_CSS_COLOR};`">写作</router-link></li></ul></div></nav>
</template><script setup lang="ts">
import {onMounted, ref} from 'vue';
import blogConfig from '../blog_config'
import router from '../router';
import {useRouter} from "vue-router";const {VUE_APP_NAVBAR_BG_CSS_COLOR = 'black', VUE_APP_NAVBAR_TEXT_CSS_COLOR = 'white'} = blogConfigdefineProps({title: {type: String,default: ''},sections: {type: Object,default: () => ({})}
});const showDropdown = ref(false)const focusOut = ({relatedTarget}: any) => {if (!(Array.from(relatedTarget?.classList ?? []).includes('dropdown-item'))) {showDropdown.value = false}
}const username = ref("")
const mrouter = useRouter()
const onLogout = () => {localStorage.removeItem("token")localStorage.removeItem("username")localStorage.removeItem("refresh")username.value = ""mrouter.push("/login")
}onMounted(() => {username.value = localStorage.getItem("username") || ""
})
</script><style scoped>
.top-right {display: flex;align-items: center;justify-content: center;
}.top-right .category {margin-right: 15px;
}.top-right .category:hover {color: cornflowerblue;cursor: pointer;
}.logout:hover {color: dodgerblue !important;cursor: pointer;
}
</style>

23 实现添加文章的功能

<template><form class="p-3"><div class="form-group"><label for="title">标题</label><input type="text" class="form-control" id="title" v-model="title"></div><div class="form-group"><label for="category">分类</label><input type="text" class="form-control" id="category" v-model="category"></div><div class="form-group"><label for="price">价格</label><input type="number" class="form-control" id="price" v-model="price"></div><div class="form-group"><label for="description">描述</label><textarea class="form-control" id="description" rows="3" v-model="description"></textarea></div><div class="form-group"><label for="content">内容</label><v-md-editor v-model="content" @save="onSave" height="100vh":right-toolbar="'preview sync-scroll fullscreen'"></v-md-editor></div><button class="btn btn-primary" @click="onSubmit">保存</button></form></template><script setup>
import {onMounted, ref} from "vue"
import axios from "redaxios";
import {useRouter} from "vue-router";const router = useRouter()
const editArticle = ref({}) // 编辑的文章
const author = ref("")
const title = ref("")
const category = ref("")
const price = ref(0)
const description = ref("")
const content = ref("支持Markdown语法")const onSave = (text, html) => {alert("保存成功")
}
const onSubmit = () => {if (title.value.length < 3) {alert("标题最小长度是3")return}if (category.value.length < 3) {alert("分类最小长度是3")return}if (price.value < 0) {alert("价格不能小于0")return}if (description.value.length < 6) {alert("描述最小长度是6")return}if (content.value.length < 6) {alert("内容最小长度是6")return}// 提交if (editArticle.value && editArticle.value.id){axios({method: "put",url: `/api/course_article/${editArticle.value.id}/`,data: {author: author.value,title: title.value,category: category.value,price: price.value,description: description.value,content: content.value,}}).then(() => {localStorage.removeItem("edit_article")router.push("/")}).catch(err => {alert(err)})}else{axios({method: "post",url: "/api/course_article/",data: {author: author.value,title: title.value,category: category.value,price: price.value,description: description.value,content: content.value,}}).then(() => {title.value = ""category.value = ""price.value = 0description.value = ""content.value = ""router.push("/")}).catch(err => {alert(err)})}}onMounted(() => {// 获取作者信息author.value = localStorage.getItem("username") || ""// 尝试获取编辑文章信息try {editArticle.value = JSON.parse(localStorage.getItem("edit_article"))title.value = editArticle.value.titlecategory.value = editArticle.value.categoryprice.value = editArticle.value.pricedescription.value = editArticle.value.descriptioncontent.value = editArticle.value.content} catch {}
})
</script>

24 实现文章的请求和动态渲染

<template><div :style="`background-color: ${VUE_APP_MAIN_BG_CSS_COLOR}; color: ${VUE_APP_MAIN_TEXT_CSS_COLOR};`"><divv-for="article in articles":key="article.id"class="container markdown-body p-3 p-md-4 my-3"><!-- 标题 --><a class="text-reset link-title" @click.prevent="onOpenDetail(article)"><h3 class="text-left m-0 p-0">{{ article.title }}</h3></a><!-- 日期 --><p class="font-weight-light  m-0 p-0 text-right">{{ secondsToDateStr(article.update_time) }}</p><!--分类--><div class="text-right"><a class="m-0 p-0 text-right font-weight-bold" style="cursor: pointer">#{{ article.category }}</a><span class="text-right font-weight-bold" style="margin: 0 5px; color: red;">{{ article.price }} 元</span><aclass="m-0 p-0 text-right font-weight-bold"style="cursor: pointer"@click.prevent="onEdit(article)"v-if="username==='zhangdapeng'">编辑</a></div><p class="font-weight-light mt-1">{{ article.description }}</p></div></div>
</template><script setup>
import {ref, computed, inject, onMounted} from 'vue'
import blogConfig from '../blog_config'
import axios from "redaxios";
import {useRouter} from "vue-router";const {VUE_APP_POSTS_PER_PAGE, VUE_APP_MAIN_BG_CSS_COLOR, VUE_APP_MAIN_TEXT_CSS_COLOR} = blogConfigconst router = useRouter()
const username = ref("")// 打开详情页面
const onOpenDetail = (article) => {localStorage.setItem("article", JSON.stringify(article))router.push("/detail")
}// 打开编辑页面
const onEdit = (article) => {localStorage.setItem("edit_article", JSON.stringify(article))router.push("/editor")
}// 将时间的秒值转化为年月日字符串
const secondsToDateStr = (seconds) => {const date = new Date(seconds * 1000)// 月份const month = date.getMonth() + 1let monthStr = month.toString();if (month < 10) {monthStr = "0" + monthStr}// 日期const mdate = date.getDate()let mdateStr = mdate.toString();if (mdate < 10) {mdateStr = "0" + mdateStr}// 时const hour = date.getHours()let hourStr = hour.toString();if (hour < 10) {hourStr = "0" + hourStr}// 分const minute = date.getMinutes()let minuteStr = minute.toString();if (minute < 10) {minuteStr = "0" + minuteStr}// 秒const second = date.getSeconds()let secondStr = second.toString();if (second < 10) {secondStr = "0" + secondStr}// 返回return `${date.getFullYear()}-${monthStr}-${mdateStr} ${hourStr}:${minuteStr}:${secondStr}`
}
const articles = ref([])
onMounted(() => {// 获取当前登录用户username.value = localStorage.getItem("username") || ""// 解决注销按钮无法自动显示的BUGif (!localStorage.getItem("refresh")) {window.location.href = "/"localStorage.setItem("refresh", "true")}// 加载数据axios({method: 'get',url: "/api/course_article/",params: {page: 1,size: 20,}}).then(res => {articles.value = res.data})
})
</script><style scoped>
.link-title {cursor: pointer;
}.link-title:hover {color: dodgerblue !important;
}
</style>

27 实现文章详情的渲染

<template><div class="container my-4 my-md-5"><h1>{{ article.title}}</h1><!--渲染富文本--><v-md-editormode="preview"v-model="article.content":style="`background-color: ${VUE_APP_MAIN_BG_CSS_COLOR}; color: ${VUE_APP_MAIN_TEXT_CSS_COLOR};`"/><!--返回按钮--><button type="button" :style="`color: ${VUE_APP_MAIN_TEXT_CSS_COLOR};`" class="border btn mt-4"@click="hasHistory() ? router.go(-1) : router.push('/')">&laquo; 返回</button></div>
</template><script setup lang="ts">
import {inject, onMounted, ref} from 'vue'
import {onBeforeRouteUpdate} from 'vue-router'
import router from '../router'
import axios from 'redaxios'
import {type PostIndex} from '../types/PostIndex'
import blogConfig from '../blog_config'const {VUE_APP_MAIN_BG_CSS_COLOR, VUE_APP_MAIN_TEXT_CSS_COLOR} = blogConfigconst props = defineProps({id: {type: String,default: ''}
})/* Hacky navigation when a href link is clicked within the compiled html Post */
onBeforeRouteUpdate(() => {location.reload()
})// Fetch Post markdown and compile it to html
const postsIndex: PostIndex[] = inject<PostIndex[]>('postsIndex', [])
const {url = ''} = postsIndex.find(({id}) => id === props.id) || {}
const {data: markDownSource} = await axios.get(url)// Patch page title
const [, title] = markDownSource.split('#')// Back button helper
const hasHistory = () => window.history?.length > 2const article = ref({}) // 文章
onMounted(() => {try {article.value = JSON.parse(localStorage.getItem("article"))console.log(article.value)} catch {console.error("读取文章信息失败")}
})
</script>

总结

整个课程从两行代码实现注册登录API接口讲起,以一个课程系统为实战,结合Vue3开发的前端,实现一个基本的前后端分离的课程管理系统,层层递进,学习路径平缓。

通过本套课程,能帮你入门gin+gorm+vue3开发前后端分离管理系统,积累实际的前后端分离开发经验。

如果您需要完整的源码,打赏20元即可。

人生苦短,我用PyGo,我是您身边的Python私教~

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于JSP技术的人事管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; JSP技术 Java语言 工具&#xff1a; Myeclipse 系统展示 首页 管理员功能模块 员工功能模…

攻击者劫持 Facebook 页面用于推广恶意 AI 照片编辑器

近日&#xff0c;有攻击者劫持了 Facebook 上的网页&#xff0c;诱骗用户下载一个合法的人工智能&#xff08;AI&#xff09;照片编辑器&#xff0c;但实际上他们真正下载的却是一个专门用以盗取用户的凭据信息窃取程序。 趋势科技的研究人员发现的这一恶意广告活动利用了人工…

什么是实时数据仓库?它有哪些不可替代之处?

【实时数据仓库】可以分开来理解&#xff1a; ✅【实时数据】&#xff1a;即能够快速处理数据&#xff0c;且几乎无延迟的提供最新的数据的能力。 ✅【仓库管理】&#xff1a;可以理解为对仓库的库存控制、对仓库的存储优化以及协调物流。 那么实时数据仓库就是&#xff1a;…

Stable Diffusion绘画 | 图生图-批量处理

批量处理中&#xff0c;对待处理图片的要求&#xff1a;宽高比一致 修改提示词后批量处理 调整参数&#xff1a; 确保宽高与原图一致增加一定的重绘幅度 调整提示词信息&#xff1a; 批量处理后&#xff0c;出图如下所示&#xff1a; 修改模型后批量处理 恢复提示词&#xf…

HTTP:从基础概念到协议机制,详解请求响应与状态保持

文章目录 一、HTTP概述1、HTTP的理解2、HTTP是无状态的协议 二、HTTP协议的过程1、URL&#xff08;统一资源定位符&#xff09;2、客户端3、服务器端 三、HTTP请求与响应1、HTTP请求和响应2、HTTP请求方法3、状态码 四、HTTP报文1、请求报文首部2、响应报文首部3、首部字段 五、…

Gstreamer实现udp帧数据的转发(一)

前言 最近有个项目&#xff0c;要求实现信息分发&#xff0c;大概意思是经过了各种交换机和电台&#xff0c;经过两个信息分发软件实现udp数据的转发&#xff0c;可能包括文本、指令、音视频等数据。 例如&#xff1a;设备1 《---》 设备2&#xff08;信息分发软件1&#xff09…

基于STM32的摇杆开关控制小恐龙游戏(附源码)

文章目录 一、 前言谷歌小恐龙 二、硬件三、软件3.1 摇杆开关3.2 OLED屏幕 四、展示五、总结 一、 前言 最近有看到别人在OLED屏幕上玩小恐龙&#xff0c;所幸查阅下资料&#xff0c;并下好源码。可惜他的源码的主控是STM32F103ZET6&#xff0c;用的是STM32CubeIDE&#xff0c…

vue3学习day04-provide和inject、defineOptions、defineModel、Pinia、pinia持久化

15、provide和inject &#xff08;1&#xff09;作用&#xff1a;顶层组件向任意的底层组件传递数据和方法&#xff0c;实现跨层组件通信 &#xff08;2&#xff09;语法&#xff1a; 1&#xff09;顶层组件通过provide函数提供数据 2&#xff09;底层函数提供inject获取数据…

AR眼镜:重型机械维修保养新利器

重型机械作为工业与建设领域的重要支柱&#xff0c;其稳定运行直接影响效率与成本。然而在偏远地区&#xff0c;面临复杂故障和高昂维修成本&#xff0c;传统维修方式常显得力不从心。如今&#xff0c;安宝特的AR远程协助解决方案结合Vuzix AR眼镜&#xff0c;正悄然改变这一现…

常见八股面试题:Dubbo 和 Spring Cloud Gateway 有什么区别?

大家好&#xff0c;我是鸭鸭&#xff01; 此答案节选自鸭鸭最近弄的面试刷题神器面试鸭&#xff0c;更多大厂常问面试题&#xff0c;可以点击进行阅读哈&#xff01; 目前这个面试刷题神器刚出&#xff0c;有网页和小程序双端可以阅读&#xff01; 回归面试题&#xff01; …

【每日刷题】Day96

【每日刷题】Day96 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. LCP 44. 开幕式焰火 - 力扣&#xff08;LeetCode&#xff09; 2. 1022. 从根到叶的二进制数之和 - …

栈和队列(数据结构)

1. 栈(Stack) 1.1 概念 栈 &#xff1a;一种特殊的线性表&#xff0c;其 只允许在固定的一端进行插入和删除元素操作 。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO &#xff08; Last In First Out &#xff09;的原…

Pytorch-张量的创建

&#x1f308;个人主页&#xff1a; 羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 简介&#xff1a; 一个Python深度学习框架&#xff0c;它将数据封装成张量&#xff08;Tensor&#xff09;进行处理&#xff0c;Python中的张量就是元素为同一种数据类型的多维…

算法训练,项目

一.木材加工 题解&#xff1a; 二分答案&#xff0c;左边0&#xff0c;右边可以为最长的木头&#xff0c;但我直接赋值了一个很大的值&#xff0c;进行二分&#xff0c;随后写个check;内部遍历木头截取为mid木块的个数&#xff0c;要是>k&#xff0c;满足要求&#xff0c;还…

开源免费的海报设计器vue-fabric-editor

vue-fabric-editor 是一个基于 Vue.js 和 Fabric.js 的创新前端富文本编辑器&#xff0c;它将传统的文本输入体验与图形设计元素相结合&#xff0c;为用户提供了全新的内容创作方式。 以下是关于 vue-fabric-editor 的详细介绍&#xff1a; 一、技术特点 框架结合&#xff1a;…

快速掌握Vue:基础命令详解

1. Vue概述 Vue.js&#xff08;读音 /vjuː/, 类似于 「view」&#xff09; 是一套构建用户界面的 「渐进式框架」。与其他重量级框架不同的是&#xff0c;Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层&#xff0c;并且非常容易学习&#xff0c;非常容易与其它库…

在Visual Studio/Qt Creator 中使用CMake安装和使用vcpkg包

文章目录 0. vcpkg简介和安装0.1 vcpkg简介0.2 vcpkg安装0.2.1 如何在Visual Studio 2022以及以上版本中安装vcpkg0.2.2 在其他VS版本或Qt Creator等平台上中安装vcpkg 1. 在Visual Studio 中使用CMake安装和使用vcpkg包1.1 创建Visual Studio项目1.2 设置项目文件a. 配置CMake…

FLUX.1 实测,堪比 Midjourney 的开源 AI 绘画模型,无需本地显卡,带你免费实战

要列举 AI 绘画开源界的几个关键贡献&#xff0c;一定少不了 Stable Diffusion。 还记否前不久刚推出的 Stable Diffusion 3&#xff1f; 其背后的团队 Stability AI&#xff0c;真的是一波三折&#xff0c;其核心成员出走&#xff0c;成立了一个新公司&#xff1a;Black For…

【Hot100】LeetCode—41. 缺失的第一个正数

原题链接&#xff1a;41. 缺失的第一个正数 1- 思路 手动实现哈希的方式 1- 遍历数组&#xff1a;如果当前的元素落在了 [1,N] 区间内&#xff0c;则 i 元素 赋值在 i-1 的位置上 比如对于数字 1 落在 数组 [0] 的位置 2- 判断条件 利用 while 加条件 ①当前元素落在了 [1,N]…

LVS(Linux virual server)

一&#xff1a;环境准备&#xff1a; rhel9 软件&#xff1a;httpd&#xff0c; ipvsadm 四台纯净的rhel9机子&#xff1a;一台LVS调度设备&#xff08;双网卡&#xff09;&#xff0c;两台webserver&#xff08;单网卡仅主机&#xff09;&#xff0c;一台客户机 DR模式多…