Go语言编写一个进销存Web软件的demo

Go语言编写一个进销存Web软件的demo

用户现在要求用。之前他们已经讨论了用Django实现的方案,现在突然切换到Go,可能有几个原因。首先,用户可能对Go语言感兴趣,或者他们公司的技术栈转向了Go。其次,用户可能希望比较不同语言实现的差异,或者需要更高性能的解决方案。

go和django的区别

接下来,我需要分析用户的具体需求。用户提到需要多个界面和权限管理,之前Django版本中已经涉及了这些内容,所以用户可能希望Go版本也能实现类似的功能,但用Go的特性来构建。同时,用户可能希望这个demo足够简单,但又能展示关键功能,比如库存管理、订单处理、用户权限等。

Gin是一个高性能的轻量级框架

我需要考虑Go语言常用的Web框架。Gin是一个高性能的轻量级框架,适合快速开发,所以选择Gin作为基础。数据库方面,使用SQLite作为嵌入式数据库,方便demo的部署和测试,不需要复杂的配置。

1.数据库模型

数据模型的设计需要与之前的Django模型对应,但结构体定义会有所不同。比如,Product结构体需要包含名称、库存、价格等字段。User结构体需要处理权限,可能使用角色(Role)字段来区分不同用户权限,如管理员、普通用户等。

2.权限管理

在Go中可以使用中间件来处理。比如,对于需要管理员权限的路由,添加一个中间件检查用户的角色是否为admin。登录认证可以使用JWT,生成token,然后在后续请求中验证token的有效性,并解析用户信息。

3.路由设计

需要区分公开路由(如登录)和需要认证的路由(如产品管理)。每个路由组可以应用不同的中间件,确保权限控制。

4.前端

用户可能希望有简单的HTML界面,所以使用Go的模板引擎来渲染页面。同时,提供RESTful API供前端调用,这样以后可以扩展为前后端分离的架构。

在实现具体功能时,比如创建采购订单,需要更新产品的库存。这里要注意事务处理,确保库存增减的原子性,避免并发问题。虽然demo可能不需要处理高并发,但良好的实践可以提升代码质量。

5.测试

需要确保各个接口的正常工作,比如添加产品、登录、创建订单等。使用curl命令或者Postman来测试API,同时检查数据库中的数据变化是否正确。

可能遇到的挑战包括Go与Django在ORM方面的差异。Go没有内置的ORM,所以需要使用database/sql库手动编写SQL语句,或者使用第三方库如gorm。但在demo中,为了简洁,可能直接使用SQLite的驱动和标准库操作数据库,这样减少依赖。

最后,需要提供清晰的步骤说明,包括如何安装依赖、运行程序、测试接口等。用户可能不熟悉Go的模块管理,所以需要指出使用go mod初始化项目,并获取必要的依赖包。

总结来说,用户需要一个用Go语言实现的简单进销存系统demo,具备基本的产品管理、订单处理、用户认证和权限控制功能。使用Gin框架和SQLite数据库,通过中间件和JWT实现权限管理,前端使用HTML模板渲染。需要确保代码结构清晰,易于理解和扩展。

一个使用Go语言(Gin框架)实现的简易进销存系统Demo

包含基础功能、权限控制和API接口:

main.go

package mainimport ("database/sql""fmt""log""net/http""os""time""github.com/gin-gonic/gin"_ "github.com/mattn/go-sqlite3""golang.org/x/crypto/bcrypt"
)// 数据结构定义
type Product struct {ID        int     `json:"id"`Name      string  `json:"name" binding:"required"`Stock     int     `json:"stock"`Price     float64 `json:"price" binding:"required"`CreatedAt string  `json:"created_at"`
}type User struct {ID       int    `json:"id"`Username string `json:"username" binding:"required"`Password string `json:"password" binding:"required"`Role     string `json:"role"` // admin/user
}type Order struct {ID         int     `json:"id"`ProductID  int     `json:"product_id" binding:"required"`Quantity   int     `json:"quantity" binding:"required"`Type       string  `json:"type" binding:"required"` // purchase/saleTotalPrice float64 `json:"total_price"`CreatedAt  string  `json:"created_at"`
}// 数据库初始化
func initDB() *sql.DB {db, err := sql.Open("sqlite3", "./inventory.db")if err != nil {log.Fatal(err)}// 创建表sqlStmt := `CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,stock INTEGER DEFAULT 0,price REAL NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP);CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT UNIQUE NOT NULL,password TEXT NOT NULL,role TEXT NOT NULL DEFAULT 'user');CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY AUTOINCREMENT,product_id INTEGER NOT NULL,quantity INTEGER NOT NULL,type TEXT NOT NULL,total_price REAL NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`_, err = db.Exec(sqlStmt)if err != nil {log.Printf("%q: %s\n", err, sqlStmt)return nil}return db
}// 中间件
func AuthMiddleware() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token == "" {c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未授权访问"})return}claims, err := ParseToken(token)if err != nil {c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效令牌"})return}c.Set("user", claims)c.Next()}
}func AdminMiddleware() gin.HandlerFunc {return func(c *gin.Context) {user, exists := c.Get("user")if !exists {c.AbortWithStatus(http.StatusUnauthorized)return}if user.(*UserClaims).Role != "admin" {c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "权限不足"})return}c.Next()}
}// 主函数
func main() {db := initDB()defer db.Close()r := gin.Default()// 公共路由public := r.Group("/api"){public.POST("/login", loginHandler(db))public.POST("/register", registerHandler(db))}// 需要认证的路由private := r.Group("/api")private.Use(AuthMiddleware()){// 产品管理private.GET("/products", getProductsHandler(db))private.POST("/products", AdminMiddleware(), createProductHandler(db))// 订单管理private.POST("/orders", createOrderHandler(db))private.GET("/orders", getOrdersHandler(db))}// 启动服务port := os.Getenv("PORT")if port == "" {port = "8080"}r.Run(":" + port)
}// 处理函数示例
func createProductHandler(db *sql.DB) gin.HandlerFunc {return func(c *gin.Context) {var product Productif err := c.ShouldBindJSON(&product); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}stmt, err := db.Prepare("INSERT INTO products(name, stock, price) VALUES(?, ?, ?)")if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}defer stmt.Close()result, err := stmt.Exec(product.Name, product.Stock, product.Price)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}id, _ := result.LastInsertId()c.JSON(http.StatusCreated, gin.H{"id": id})}
}func createOrderHandler(db *sql.DB) gin.HandlerFunc {return func(c *gin.Context) {var order Orderif err := c.ShouldBindJSON(&order); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 开始事务tx, err := db.Begin()if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}// 检查产品库存var currentStock interr = tx.QueryRow("SELECT stock FROM products WHERE id = ?", order.ProductID).Scan(&currentStock)if err != nil {tx.Rollback()c.JSON(http.StatusNotFound, gin.H{"error": "产品不存在"})return}// 更新库存newStock := currentStockif order.Type == "purchase" {newStock += order.Quantity} else if order.Type == "sale" {if currentStock < order.Quantity {tx.Rollback()c.JSON(http.StatusBadRequest, gin.H{"error": "库存不足"})return}newStock -= order.Quantity}_, err = tx.Exec("UPDATE products SET stock = ? WHERE id = ?", newStock, order.ProductID)if err != nil {tx.Rollback()c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}// 创建订单stmt, err := tx.Prepare("INSERT INTO orders(product_id, quantity, type, total_price) VALUES(?, ?, ?, ?)")if err != nil {tx.Rollback()c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}defer stmt.Close()_, err = stmt.Exec(order.ProductID, order.Quantity, order.Type, order.TotalPrice)if err != nil {tx.Rollback()c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}tx.Commit()c.JSON(http.StatusCreated, gin.H{"message": "订单创建成功"})}
}// JWT相关功能(示例代码)
func GenerateToken(user *User) (string, error) {// 实现JWT生成逻辑return "sample_token", nil
}func ParseToken(tokenString string) (*UserClaims, error) {// 实现JWT解析逻辑return &UserClaims{Username: "admin", Role: "admin"}, nil
}type UserClaims struct {Username stringRole     string
}

运行步骤

  1. 安装依赖:

go mod init inventory
go get github.com/gin-gonic/gin
go get github.com/mattn/go-sqlite3
go get golang.org/x/crypto/bcrypt
运行界面
D:\work\goproject>go mod init inventory
go: creating new go.mod: module inventory
go: to add module requirements and sums:go mod tidyD:\work\goproject>go get github.com/gin-gonic/gin
go: downloading github.com/gin-gonic/gin v1.10.0
go: downloading github.com/gin-contrib/sse v0.1.0
go: downloading github.com/mattn/go-isatty v0.0.20
go: downloading golang.org/x/net v0.25.0
go: downloading github.com/bytedance/sonic v1.11.6
go: downloading github.com/goccy/go-json v0.10.2
go: downloading github.com/json-iterator/go v1.1.12
go: downloading github.com/go-playground/validator/v10 v10.20.0
go: downloading github.com/pelletier/go-toml/v2 v2.2.2
go: downloading github.com/ugorji/go/codec v1.2.12
go: downloading google.golang.org/protobuf v1.34.1
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading golang.org/x/sys v0.20.0
go: downloading golang.org/x/text v0.15.0
go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: downloading github.com/leodido/go-urn v1.4.0
go: downloading github.com/modern-go/reflect2 v1.0.2
go: downloading golang.org/x/crypto v0.23.0
go: downloading github.com/gabriel-vasile/mimetype v1.4.3
go: downloading github.com/go-playground/universal-translator v0.18.1
go: downloading github.com/go-playground/locales v0.14.1

    下载完毕后会修改go.mod文件

    module inventorygo 1.24.2require (github.com/bytedance/sonic v1.11.6 // indirectgithub.com/bytedance/sonic/loader v0.1.1 // indirectgithub.com/cloudwego/base64x v0.1.4 // indirectgithub.com/cloudwego/iasm v0.2.0 // indirectgithub.com/gabriel-vasile/mimetype v1.4.3 // indirectgithub.com/gin-contrib/sse v0.1.0 // indirectgithub.com/gin-gonic/gin v1.10.0 // indirectgithub.com/go-playground/locales v0.14.1 // indirectgithub.com/go-playground/universal-translator v0.18.1 // indirectgithub.com/go-playground/validator/v10 v10.20.0 // indirectgithub.com/goccy/go-json v0.10.2 // indirectgithub.com/json-iterator/go v1.1.12 // indirectgithub.com/klauspost/cpuid/v2 v2.2.7 // indirectgithub.com/leodido/go-urn v1.4.0 // indirectgithub.com/mattn/go-isatty v0.0.20 // indirectgithub.com/mattn/go-sqlite3 v1.14.27 // indirectgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirectgithub.com/modern-go/reflect2 v1.0.2 // indirectgithub.com/pelletier/go-toml/v2 v2.2.2 // indirectgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirectgithub.com/ugorji/go/codec v1.2.12 // indirectgolang.org/x/arch v0.8.0 // indirectgolang.org/x/crypto v0.37.0 // indirectgolang.org/x/net v0.25.0 // indirectgolang.org/x/sys v0.32.0 // indirectgolang.org/x/text v0.24.0 // indirectgoogle.golang.org/protobuf v1.34.1 // indirectgopkg.in/yaml.v3 v3.0.1 // indirect
    )
    

    运行代码

    go run main.go

    提示错误

    .\main.go:129:25: undefined: loginHandler
    .\main.go:130:28: undefined: registerHandler
    .\main.go:138:28: undefined: getProductsHandler
    .\main.go:143:26: undefined: getOrdersHandler

    可以看出代码中没有上面4个函数,直接屏蔽掉就OK

    再次运行

    go run main.go
    2025/04/10 22:16:58 "Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub":CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,stock INTEGER DEFAULT 0,price REAL NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP);CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT UNIQUE NOT NULL,password TEXT NOT NULL,role TEXT NOT NULL DEFAULT 'user');CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY AUTOINCREMENT,product_id INTEGER NOT NULL,quantity INTEGER NOT NULL,type TEXT NOT NULL,total_price REAL NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP);
    [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.        - using env:   export GIN_MODE=release- using code:  gin.SetMode(gin.ReleaseMode)[GIN-debug] POST   /api/products             --> main.main.createProductHandler.func3 (5 handlers)
    [GIN-debug] POST   /api/orders               --> main.main.createOrderHandler.func4 (4 handlers)
    [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
    Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
    [GIN-debug] Listening and serving HTTP on :8080
    

    提升运行成功

    功能说明

    1. 核心功能

    • 产品管理(CRUD)

    • 采购/销售订单管理

    • 实时库存更新

    • 用户认证(JWT)

    • 角色权限控制(admin/user)

    1. API接口示例

    bash

    复制

    # 注册用户
    curl -X POST http://localhost:8080/api/register \-H "Content-Type: application/json" \-d '{"username":"admin","password":"admin123","role":"admin"}'# 登录获取Token
    curl -X POST http://localhost:8080/api/login \-H "Content-Type: application/json" \-d '{"username":"admin","password":"admin123"}'# 创建产品(需要admin权限)
    curl -X POST http://localhost:8080/api/products \-H "Authorization: Bearer sample_token" \-H "Content-Type: application/json" \-d '{"name":"MacBook Pro", "stock":10, "price":1999.99}'# 创建采购订单
    curl -X POST http://localhost:8080/api/orders \-H "Authorization: Bearer sample_token" \-H "Content-Type: application/json" \-d '{"product_id":1, "quantity":5, "type":"purchase", "total_price":9999.95}'
    1. 前端界面建议

    html

    复制

    <!-- 示例产品列表界面 -->
    <!DOCTYPE html>
    <html>
    <head><title>产品管理</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body><div class="container mt-4"><h2>产品列表</h2><div id="product-list" class="row"></div></div><script>// 使用fetch API获取产品数据fetch('/api/products', {headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}}).then(response => response.json()).then(data => {const container = document.getElementById('product-list');data.forEach(product => {const card = `<div class="col-md-4 mb-3"><div class="card"><div class="card-body"><h5 class="card-title">${product.name}</h5><p class="card-text">库存: ${product.stock}<br>价格: $${product.price}</p></div></div></div>`;container.innerHTML += card;});});</script>
    </body>
    </html>

    运行 HTML

    系统扩展建议

    1. 增强功能

    • 添加供应商/客户管理

    • 实现库存预警功能

    • 增加报表统计模块

    • 支持文件导入导出

    • 添加操作日志记录

    1. 性能优化

    • 添加Redis缓存层

    • 实现数据库连接池

    • 添加API限流中间件

    • 支持集群部署

    1. 安全增强

    • 实现HTTPS支持

    • 添加请求参数校验

    • 实现密码策略强制

    • 添加IP白名单控制

    1. 部署方案

    bash

    复制

    # 使用Docker部署
    FROM golang:1.18-alpine
    WORKDIR /app
    COPY go.mod ./
    COPY go.sum ./
    RUN go mod download
    COPY *.go ./
    RUN go build -o /inventory
    EXPOSE 8080
    CMD [ "/inventory" ]

    这个Demo实现了以下核心功能:

    • RESTful API设计

    • JWT身份验证

    • 角色权限控制

    • 库存事务管理

    • 基础数据操作

    • 错误处理机制

    可以根据实际需求继续扩展以下功能:

    1. 增加Swagger API文档

    2. 实现单元测试

    3. 添加Prometheus监控

    4. 集成消息队列

    5. 实现分布式锁

    6. 添加数据验证规则

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

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

    相关文章

    【前缀和】矩阵区域和(medium)

    矩阵区域和&#xff08;medium&#xff09; 题⽬描述&#xff1a;解法&#xff1a;代码Java 算法代码&#xff1a;C 算法代码&#xff1a; 题⽬描述&#xff1a; 题⽬链接&#xff1a;1314. 矩阵区域和 给你⼀个 m x n 的矩阵 mat 和⼀个整数 k &#xff0c;请你返回⼀个矩阵 …

    Java学习手册:Java发展历史与版本特性

    Java作为全球最流行的编程语言之一&#xff0c;其发展历程不仅见证了技术的演进&#xff0c;也反映了软件开发模式的变革。从1995年的首次发布到如今的持续更新&#xff0c;Java始终保持着强大的生命力和广泛的影响力。本文将简要回顾Java的发展历程&#xff0c;并重点介绍其关…

    winserver2022备份

    安装备份&#xff0c;然后等待安装完成即可 然后可以在这里看到安装好的win server2022备份 一直下一步然后到这里 不要用本地文件夹备份 备份到远程服务器&#xff0c;远程服务器路径 然后确定备份即可 如何恢复呢&#xff1f; 点击右侧的恢复就可以了 打开任务计划程序 这…

    Unity 设置弹窗Tips位置

    根据鼠标位于屏幕的区域&#xff0c;设置弹窗锚点以及位置 public static void TipsPos(Transform tf) {//获取ui相机var uiCamera GetUICamera();var popup tf.GetComponent<RectTransform>();//获取鼠标位置Vector2 mousePos Input.mousePosition;float screenWidt…

    【C++基础-关键字】:extern

    深入理解 C++ 关键字 extern 在 C++ 编程中,extern 关键字扮演着重要角色,主要用于声明全局变量或函数,使其在多个源文件间共享。本文将详细探讨 extern 的用法及其在实际开发中的应用。 1. 什么是 extern? extern 关键字用于声明一个变量或函数的引用,表示该变量或函数…

    我为女儿开发了一个游戏网站

    大家好&#xff0c;我是星河。 自从协助妻子为女儿开发了算数射击游戏后&#xff0c;星河就一直有个想法&#xff1a;为女儿打造一个专属的学习游戏网站。之前的射击游戏虽然有趣&#xff0c;但缺乏难度分级&#xff0c;无法根据女儿的学习进度灵活调整。而且&#xff0c;仅仅…

    基于 Python 卷积神经网络的新闻文本分类系统,附源码

    大家好&#xff0c;我是徐师兄&#xff0c;一个有着7年大厂经验的程序员&#xff0c;也是一名热衷于分享干货的技术爱好者。平时我在 CSDN、掘金、华为云、阿里云和 InfoQ 等平台分享我的心得体会。今天我来跟大家聊聊一个用 Python 和 Django 打造的人脸识别考勤系统&#xff…

    ngx_cycle_modules

    Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cycle_modules-CSDN博客 定义在 src/core/ngx_module.c ngx_int_t ngx_cycle_modules(ngx_cycle_t *cycle) {/** create a list of modules to be used for this cycle,* copy static modules to it*/cycle->modules ngx_pcalloc(…

    AI 代码生成工具如何突破 Java 单元测试效能天花板?

    一、传统单元测试的四大痛点 时间黑洞&#xff1a;根据 JetBrains 调研&#xff0c;Java 开发者平均花费 35% 时间编写测试代码覆盖盲区&#xff1a;手工测试覆盖率普遍低于 60%&#xff08;Jacoco 全球统计数据&#xff09;维护困境&#xff1a;业务代码变更导致 38% 的测试用…

    【保姆级图解】插入排序 算法详解:直接插入排序、希尔排序

    总体引入 在计算机科学的算法领域中&#xff0c;排序是一项基础且重要的操作。它旨在将一组无序的数据元素重新排列为有序序列&#xff0c;以满足特定的顺序要求&#xff0c;如升序或降序。常见的排序算法可分为不同类别&#xff0c;像插入排序&#xff0c;包含直接插入排序和…

    为什么ChatGPT选择SSE而非WebSocket?

    为什么ChatGPT选择SSE而非WebSocket&#xff1f; 一、ChatGPT回答问题的技术逻辑 ChatGPT的响应生成基于Transformer架构和自注意力机制&#xff0c;其核心是通过概率预测逐词生成文本。当用户输入问题后&#xff0c;模型会先解析上下文&#xff0c;再通过预训练的庞大语料库…

    Android 手机指纹传感器无法工作,如何恢复数据?

    天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据清除、数据备份、数据取证、数据迁移解决方案&#xff0c;并针对企业面临的数据安全风险&#xff0c;提供专业的相关数据安全培训。 天津鸿萌科贸发展有限公司是众多国…

    DeepSeek 在金融领域的应用解决方案

    DeepSeek 在金融领域的应用解决方案 一、背景 随着人工智能技术的快速发展&#xff0c;DeepSeek 作为一款国产大模型&#xff0c;凭借其强大的语义理解、逻辑推理和多模态处理能力&#xff0c;在金融行业迅速崭露头角。金融行业作为经济的核心&#xff0c;面临着激烈的市场竞…

    织光五载 焕新启航

    成都时尚产业协会5周年 以创新为笔&#xff0c;续写国际时尚之都的璀璨篇章 【一场跨越时空的时尚对话】 五年前&#xff0c;一颗名为"成都时尚产业协会"的种子在蓉城落地生根&#xff1b;五年后&#xff0c;这棵新芽已成长为枝繁叶茂的生态之树&#xff0c;用交织…

    scala集合

    一、数组&#xff08;Array&#xff09; 1.数组转换 不可变转可变&#xff1a;arr1.toBuffer&#xff0c;arr1本身没有变化 可变转不可变&#xff1a;arr2.toArray&#xff0c;arr2本身没有变化 2.多维数组 创建&#xff1a;val arr Array.ofDim[Int](3, 4)&#xff08;3 …

    常用 Excel VBA 技巧,简单好学易上手

    在日常办公中&#xff0c;我们常常会遇到各种繁琐的数据处理任务&#xff0c;而 Excel VBA&#xff08;Visual Basic for Applications&#xff09;作为一款强大的自动化工具&#xff0c;能够帮助我们轻松应对这些挑战。本文将介绍一些常用且简单好学的 Excel VBA 技巧&#xf…

    Java 基础 - 反射(1)

    文章目录 引入类加载过程1. 通过 new 创建对象2. 通过反射创建对象2.1 触发加载但不初始化2.2 按需触发初始化2.3 选择性初始化控制 核心用法示例1. 通过无参构造函数创建实例对象2. 通过有参构造函数创建实例对象3. 反射通过私有构造函数创建对象&#xff0c; 破坏单例模式4. …

    如何在React中集成 PDF.js?构建支持打印下载的PDF阅读器详解

    本文深入解析基于 React 和 PDF.js 构建 PDF 查看器的实现方案&#xff0c;该组件支持 PDF 渲染、图片打印和下载功能&#xff0c;并包含完整的加载状态与错误处理机制。 完整代码在最后 一个PDF 文件&#xff1a; https://mozilla.github.io/pdf.js/web/compressed.tracemo…

    数据结构与算法-动态规划-线性动态规划,0-1背包,多重背包,完全背包,有依赖的背包,分组背包,背包计数,背包路径

    动态规划原理 动态规划这玩意儿&#xff0c;就好比是在拓扑图上玩跳格子游戏。在图论中&#xff0c;咱们是从特定的节点跳到其他节点&#xff1b;而在动态规划里呢&#xff0c;我们是从一个状态 “嗖” 地转移到另一个状态。状态一般用数组来表示&#xff0c;就像 f [i][j]&am…

    解决文件夹解压中文字符产生乱码的问题

    太tm智能了&#xff0c;本来还想看看解压工具在哪里修改&#xff0c;智能的识别到乱码了。点赞 看到那个地球了吗&#xff0c;点击那个球&#xff0c;这个修改不是侵略性的&#xff0c;不会修改压缩文件本身所以需要在当前页面解压 参考 https://blog.csdn.net/QCSYSZQ/artic…