从0开始,用Go语言搭建一个简单的后端业务系统

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 从0开始,用Go语言搭建一个简单的后端业务系统

Hello 小伙伴们,今天给大家带来了一份Go语言搭建后端业务系统的教程,restful风格哦,既然是简单的业务系统,那么必要的功能就少不了增删改查,也就是传说中的CRUD,当然相比Spring Boot而言,Go语言写后端业务系统不是那么的流行,但是对比一下我们也很容易能发现,Go语言搭建的Web后端系统的优势:

  • (1)内存占用更少
  • (2)启动速度更快
  • (3)代码更加简洁

OK,下面我们开始正文,首先看下完成后的成品吧:

1 业务&技术概括

1.1 业务功能

实体(NumInfo)

  • Id:主键
  • Name :名称
  • InfoKey :Key
  • InfoNum :Num

业务功能

  • 根据Key将Num加1
  • 根据Key查找
  • 根据ID查找
  • 添加一个
  • 根据ID删除一个
  • 查看全部
  • 根据ID修改一个
1.2 技术点

框架

  • Gin
  • Viper
  • GORM

数据库

  • MySQL

前端

  • JQuery
  • layUI

2 接口规范

## 根据Key将Num加1
http://localhost:9888/add/{key}
### req:
http://localhost:9888/add/zs
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":"true"
}
```
## 根据Key查找
http://localhost:9888/findByKey/{key}
### req:
http://localhost:9888/findByKey/zs
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":{
        "id":"1"
        "name":"zs",
        "info_key":"zs",
        "info_num":"12"
  }
}
```
## 根据ID查找
http://localhost:9888/findById/{id}
### req:
http://localhost:9888/findById/1
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":{
        "id":"1"
        "name":"zs",
        "info_key":"zs",
        "info_num":"12"
  }
}
```
## 添加一个
http://localhost:9888/saveInfo
### req:
http://localhost:9888/saveInfo
```json
{
  "name":"ww",
  "info_key":"ww"
}
```
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":"true"
}
```
## 根据ID删除一个
http://localhost:9888/deleteInfo/{id}
### req:
http://localhost:9888/deleteInfo/1
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":"true"
}
```
## 查看全部
http://localhost:9888/getAll
### req:
http://localhost:9888/getAll
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":[{
        "id":"1"
        "name":"zs",
        "info_key":"zs",
        "info_num":"12"
  },{
        "id":"2"
        "name":"ls",
        "info_key":"ls",
        "info_num":"12"
  }]
}
```
## 根据ID修改一个
http://localhost:9888/update
### req:
http://localhost:9888/update
{
    "id":"1"
    "name":"zs",
    "info_key":"zs",
    "info_num":"12"
}
### resp:
```json
{
    "code": "0",
    "msg": "true",
    "count": "0",
    "data":"true"
}
```

3 后端代码

整体结构:

3.1 DAO层

接口

package dao
import (
   "context"
   "count_num/pkg/entity"
)
type CountNumDAO interface {
   //添加一个
   AddNumInfo(ctx context.Context, info entity.NumInfo) bool
   //根据Key获取一个
   GetNumInfoByKey(ctx context.Context, url string) entity.NumInfo
   //查看全部
   FindAllNumInfo(ctx context.Context) []entity.NumInfo
   //根据Key修改
   UpdateNumInfoByKey(ctx context.Context, info entity.NumInfo) bool
   //删除一个
   DeleteNumInfoById(ctx context.Context, id int64) bool
   //根据ID获取一个
   GetNumInfoById(ctx context.Context, id int64) entity.NumInfo
   //根据ID修改
   UpdateNumInfoById(ctx context.Context, info entity.NumInfo) bool
}

实现

package impl
import (
   "context"
   "count_num/pkg/config"
   "count_num/pkg/entity"
   "gorm.io/gorm"
)
type CountNumDAOImpl struct {
   db *gorm.DB
}
func NewCountNumDAOImpl() *CountNumDAOImpl {
   return &CountNumDAOImpl{db: config.DB}
}
func (impl CountNumDAOImpl) AddNumInfo(ctx context.Context, info entity.NumInfo) bool {
   var in entity.NumInfo
   impl.db.First(&in, "info_key", info.InfoKey)
   if in.InfoKey == info.InfoKey { //去重
      return false
   }
   impl.db.Save(&info) //要使用指针
   return true
}
func (impl CountNumDAOImpl) GetNumInfoByKey(ctx context.Context, key string) entity.NumInfo {
   var info entity.NumInfo
   impl.db.First(&info, "info_key", key)
   return info
}
func (impl CountNumDAOImpl) FindAllNumInfo(ctx context.Context) []entity.NumInfo {
   var infos []entity.NumInfo
   impl.db.Find(&infos)
   return infos
}
func (impl CountNumDAOImpl) UpdateNumInfoByKey(ctx context.Context, info entity.NumInfo) bool {
   impl.db.Model(&entity.NumInfo{}).Where("info_key = ?", info.InfoKey).Update("info_num", info.InfoNum)
   return true
}
func (impl CountNumDAOImpl) DeleteNumInfoById(ctx context.Context, id int64) bool {
   impl.db.Delete(&entity.NumInfo{}, id)
   return true
}
func (impl CountNumDAOImpl) GetNumInfoById(ctx context.Context, id int64) entity.NumInfo {
   var info entity.NumInfo
   impl.db.First(&info, "id", id)
   return info
}
func (impl CountNumDAOImpl) UpdateNumInfoById(ctx context.Context, info entity.NumInfo) bool {
   impl.db.Model(&entity.NumInfo{}).Where("id", info.Id).Updates(entity.NumInfo{Name: info.Name, InfoKey: info.InfoKey, InfoNum: info.InfoNum})
   return true
}
3.2 Web层
package controller
import (
   "bytes"
   "count_num/pkg/dao/impl"
   "count_num/pkg/entity"
   "encoding/json"
   "github.com/gin-gonic/gin"
   "github.com/spf13/cast"
   "io/ioutil"
   "strconv"
)
type NumInfoControllerImpl struct {
   dao *impl.CountNumDAOImpl
}
type NumInfoController interface {
   AddNumByKey(c *gin.Context)
   FindNumByKey(c *gin.Context)
   SaveNumInfo(c *gin.Context)
   DeleteById(c *gin.Context)
   FindAll(c *gin.Context)
   FindNumById(c *gin.Context)
   Update(context *gin.Context)
}
func NewNumInfoControllerImpl() *NumInfoControllerImpl {
   return &NumInfoControllerImpl{dao: impl.NewCountNumDAOImpl()}
}
func (impl NumInfoControllerImpl) AddNumByKey(c *gin.Context) {
   key := c.Param("key")
   numInfo := impl.dao.GetNumInfoByKey(c, key)
   numInfo.InfoNum = numInfo.InfoNum + 1
   isOk := impl.dao.UpdateNumInfoByKey(c, numInfo)
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": isOk})
}
func (impl NumInfoControllerImpl) FindNumByKey(c *gin.Context) {
   key := c.Param("key")
   numInfo := impl.dao.GetNumInfoByKey(c, key)
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": numInfo})
}
func (impl NumInfoControllerImpl) SaveNumInfo(c *gin.Context) {
   body := c.Request.Body
   bytes, err := ioutil.ReadAll(body)
   info := entity.NumInfo{}
   json.Unmarshal(bytes, &info)
   if err != nil {
      panic(err)
   }
   isOk := impl.dao.AddNumInfo(c, info)
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": isOk})
}
func (impl NumInfoControllerImpl) DeleteById(c *gin.Context) {
   id := c.Param("id")
   i, _ := strconv.Atoi(id)
   isOk := impl.dao.DeleteNumInfoById(c, int64(i))
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": isOk})
}
func (impl NumInfoControllerImpl) FindAll(c *gin.Context) {
   numInfos := impl.dao.FindAllNumInfo(c)
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": len(numInfos), "data": numInfos})
}
func (impl NumInfoControllerImpl) FindNumById(c *gin.Context) {
   id := c.Param("id")
   i, _ := strconv.Atoi(id)
   numInfo := impl.dao.GetNumInfoById(c, int64(i))
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": numInfo})
}
func (impl NumInfoControllerImpl) Update(c *gin.Context) {
   body := c.Request.Body
   jsonBytes, err := ioutil.ReadAll(body)
   d := json.NewDecoder(bytes.NewReader(jsonBytes))
   d.UseNumber()
   m := make(map[string]string)
   d.Decode(&m)
   if err != nil {
      panic(err)
   }
   info := entity.NumInfo{
      Id:      cast.ToInt64(m["id"]),
      Name:    m["name"],
      InfoKey: m["info_key"],
      InfoNum: cast.ToInt64(m["info_num"]),
   }
   isOk := impl.dao.UpdateNumInfoById(c, info)
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": isOk})
}

拦截器配置

package interceptor
import (
   "github.com/gin-gonic/gin"
   "log"
)
// HttpInterceptor 自定义拦截器
func HttpInterceptor() gin.HandlerFunc {
   return func(c *gin.Context) {
      // 设置 example 变量
      c.Set("example", "12345")
      // 请求前
      log.Print("--------------拦截器-------------")
      //定义错误,终止并返回该JSON
      //c.AbortWithStatusJSON(500, "error")
      //requestURI := c.Request.RequestURI
      //fmt.Println(requestURI)
      //通过请求
      c.Next()
   }
}

router

package web
import (
   "count_num/pkg/config"
   "count_num/pkg/web/controller"
   "count_num/pkg/web/interceptor"
   "github.com/gin-gonic/gin"
)
func RunHttp() {
   r := gin.Default()
   //增加拦截器
   r.Use(interceptor.HttpInterceptor())
   //解决跨域
   r.Use(config.CorsConfig())
   //路由组
   appInfoGroup := r.Group("/")
   {
      appInfoGroup.POST("/add/:key", controller.NewNumInfoControllerImpl().AddNumByKey)
      appInfoGroup.GET("/findByKey/:key", controller.NewNumInfoControllerImpl().FindNumByKey)
      appInfoGroup.GET("/findById/:id", controller.NewNumInfoControllerImpl().FindNumById)
      appInfoGroup.POST("/saveInfo", controller.NewNumInfoControllerImpl().SaveNumInfo)
      appInfoGroup.POST("/deleteInfo/:id", controller.NewNumInfoControllerImpl().DeleteById)
      appInfoGroup.GET("/getAll", controller.NewNumInfoControllerImpl().FindAll)
      appInfoGroup.POST("/update", controller.NewNumInfoControllerImpl().Update)
   }
   r.Run("127.0.0.1:" + config.PORT)
}
3.3 配置和实体结构体
package config
import (
   "fmt"
   _ "github.com/go-sql-driver/mysql"
   "github.com/spf13/viper"
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
)
var DB *gorm.DB
func init() {
   var err error
   viper.SetConfigName("app")
   viper.SetConfigType("properties")
   viper.AddConfigPath("./")
   err = viper.ReadInConfig()
   if err != nil {
      panic(fmt.Errorf("Fatal error config file: %w \n", err))
   }
   if err := viper.ReadInConfig(); err != nil {
      if _, ok := err.(viper.ConfigFileNotFoundError); ok {
         fmt.Println("No file ...")
      } else {
         fmt.Println("Find file but have err ...")
      }
   }
   PORT = viper.GetString("server.port")
   url := viper.GetString("db.url")
   db := viper.GetString("db.databases")
   username := viper.GetString("db.username")
   password := viper.GetString("db.password")
   dsn := username + ":" + password + "@tcp(" + url + ")/" + db + "?charset=utf8mb4&parseTime=True&loc=Local"
   DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
   if err != nil {
      panic(err)
   }
}

跨域问题

package config
import (
   "github.com/gin-gonic/gin"
   "net/http"
)
var PORT string
func CorsConfig() gin.HandlerFunc {
   return func(c *gin.Context) {
      c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
      c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
      c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
      c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
      c.Header("Access-Control-Allow-Credentials", "true")
      c.Writer.Header().Set("Access-Control-Max-Age", "86400")
      if c.Request.Method == http.MethodOptions {
         c.AbortWithStatus(200)
      } else {
         c.Next()
      }
   }
}

实体

package entity
type NumInfo struct {
   Id      int64  `json:"id"`
   Name    string `json:"name"`
   InfoKey string `json:"info_key"`
   InfoNum int64  `json:"info_num"`
}
func (stu NumInfo) TableName() string {
   return "num_info"
}
3.4 启动主函数
package main
import "count_num/pkg/web"
func main() {
   web.RunHttp()
}
3.5 配置文件和SQL
server.port=9888
db.driver=mysql
db.url=127.0.0.1:3306
db.databases=test
db.username=root
db.password=12345

SQL文件

CREATE TABLE `num_info`
(
    `id`       int(11) NOT NULL AUTO_INCREMENT,
    `name`     varchar(255) DEFAULT NULL,
    `info_key` varchar(255) NOT NULL,
    `info_num` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`, `info_key`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

4 前端代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>后台管理</title>
    <link rel="stylesheet" href="./layui/css/layui.css">
</head>
<body>
<div style="margin-left: 220px;position: absolute;top: 70px;width: 80%;">
    <button class="layui-btn layui-btn-normal" id="add_btn" lay-filter="add_btn">添加一个</button>
    <table id="demo" lay-filter="test"></table>
</div>
<script src="./layui/layui.js"></script>
<script src="./layui/jquery.min.js"></script>
<script>
    var base_url = 'http://localhost:9888'
    
    layui.use('element', function () {
        var element = layui.element;
    });
    layui.use('table', function () {
        var table = layui.table;
        //第一个实例
        table.render({
            elem: '#demo'
            , height: 500
            , url: base_url + '/getAll' //数据接口
            , page: false //开启分页
            , cols: [[ //表头
                {field: 'id', title: 'ID', width: '10%'}
                , {field: 'name', title: '名称', width: '30%'}
                , {field: 'info_key', title: '标记', sort: true, width: '20%'}
                , {field: 'info_num', title: '次数', width: '20%', sort: true}
                , {title: '操作', width: '20%', toolbar: '#barDemo'}
            ]]
        });
        //工具条事件
        table.on('tool(test)', function (obj) { 
            var data = obj.data; 
            var layEvent = obj.event; 
            var tr = obj.tr; 
            if ('edit' == layEvent) {
                layer.open({
                    title: '编辑',
                    type: 1,
                    content: '<form class="layui-form" style="margin-top: 20px;margin-right: 60px;">' +
                        '  <div class="layui-form-item">\n' +
                        '    <label class="layui-form-label">名称</label>\n' +
                        '    <div class="layui-input-inline">\n' +
                        '      <input type="text" class="layui-input" id="u_name" value="' + data.name + '">\n' +
                        '    </div>\n' +
                        '  </div>' +
                        '  <div class="layui-form-item">\n' +
                        '    <label class="layui-form-label">标记</label>\n' +
                        '    <div class="layui-input-inline">\n' +
                        '      <input type="text" class="layui-input" id="u_key" value="' + data.info_key + '">\n' +
                        '    </div>\n' +
                        '  </div>' +
                        '  <div class="layui-form-item">\n' +
                        '    <label class="layui-form-label">次数</label>\n' +
                        '    <div class="layui-input-inline">\n' +
                        '      <input type="text"  class="layui-input" id="u_num" value="' + data.info_num + '">\n' +
                        '    </div>\n' +
                        '  </div>' +
                        '<div class="layui-form-item">\n' +
                        '    <div class="layui-input-block">\n' +
                        '      <button class="layui-btn" type="button" οnclick="update()">确定修改</button>\n' +
                        '      <button type="reset" class="layui-btn layui-btn-primary">重置</button>\n' +
                        '    </div>\n' +
                        '  </div>' +
                        '  <input style="display: none;" id="u_id" value="' + data.id + '">' +
                        '</form>'
                });
            } else if ('del' == layEvent) {
                layer.confirm('确定删除吗?', function (index) {
                    //点击确认时执行
                    $.ajax({
                        url: base_url + '/deleteInfo/'+data.id,
                        type: 'POST',
                        success: function (r) {
                            if (r.data) {
                                location.reload();
                            }
                        }
                    })
                    layer.close(index);
                });
            }
        });
    });
    $('#add_btn').on('click', function () {
        layer.open({
            title: '添加',
            type: 1,
            content: '<form class="layui-form" style="margin-top: 20px;margin-right: 60px;">' +
                '  <div class="layui-form-item">\n' +
                '    <label class="layui-form-label">名称</label>\n' +
                '    <div class="layui-input-inline">\n' +
                '      <input type="text" class="layui-input" id="s_name">\n' +
                '    </div>\n' +
                '  </div>' +
                '  <div class="layui-form-item">\n' +
                '    <label class="layui-form-label">标记</label>\n' +
                '    <div class="layui-input-inline">\n' +
                '      <input type="text" class="layui-input" id="s_key">\n' +
                '    </div>\n' +
                '  </div>' +
                '<div class="layui-form-item">\n' +
                '    <div class="layui-input-block">\n' +
                '      <button class="layui-btn" οnclick="save()" type="button">立即提交</button>\n' +
                '      <button type="reset" class="layui-btn layui-btn-primary">重置</button>\n' +
                '    </div>\n' +
                '  </div>' +
                '</form>'
        });
    });
</script>
<script>
    function save() {
        var name = $("#s_name").val();
        var key = $("#s_key").val();
        $.ajax({
            url: base_url + '/saveInfo',
            type: 'POST',
            data: JSON.stringify({"name": name, "info_key": key}),  
            contentType: 'application/json',
            success: function (r) {
                if (r.data) {
                    location.reload();
                }
            }
        })
    }
    function update() {
        var id = $("#u_id").val();
        var name = $("#u_name").val();
        var key = $("#u_key").val();
        var num = $("#u_num").val();
        $.ajax({
            url: base_url + '/update',
            type: 'POST',
            data: JSON.stringify({"id": id, "name": name, "info_key": key, "info_num": num}),   
            contentType: 'application/json',
            success: function (r) {
                if (r.data) {
                    location.reload();
                }
            }
        })
    }
</script>
<script type="text/html" id="barDemo">
    <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
</body>
</html>

5 遇见的问题及排查方式

5.1 GORM的使用问题
5.1.1 自定义表名
func (stu NumInfo) TableName() string {
   return "num_info"
}
5.1.2 主键自增
impl.db.Save(&info) //要使用指针
5.2 跨域问题
func CorsConfig() gin.HandlerFunc {
   return func(c *gin.Context) {
      c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
      c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
      c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
      c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
      c.Header("Access-Control-Allow-Credentials", "true")
      c.Writer.Header().Set("Access-Control-Max-Age", "86400")
      if c.Request.Method == http.MethodOptions {
         c.AbortWithStatus(200)
      } else {
         c.Next()
      }
   }
}

在Gin中解决跨域问题

func RunHttp() {
   r := gin.Default()
   ......
   //解决跨域
   r.Use(config.CorsConfig())
   ......
   r.Run("127.0.0.1:" + config.PORT)
}
5.3 JSON字段转int64失效问题
func (impl NumInfoControllerImpl) Update(c *gin.Context) {
   body := c.Request.Body
   jsonBytes, err := ioutil.ReadAll(body)
   //先将JSON转为Map
   d := json.NewDecoder(bytes.NewReader(jsonBytes))
   d.UseNumber()
   m := make(map[string]string)
   d.Decode(&m)
   if err != nil {
      panic(err)
   }
   //再将Map转为实体
   info := entity.NumInfo{
      Id:      cast.ToInt64(m["id"]),
      Name:    m["name"],
      InfoKey: m["info_key"],
      InfoNum: cast.ToInt64(m["info_num"]),
   }
   isOk := impl.dao.UpdateNumInfoById(c, info)
   c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": isOk})
}

6 总结

好了,今天的分享就到这里,虽然学习了很长时间的Go语言,但是搭建这样较为完整的业务系统的机会不是很多,过程中也遇到了几个问题,但是都利用官方文档或搜索引擎独立的解决了。

当然目前的后端业务系统只支持restful风格的Http请求,如果后续有时间的话还会增加相同功能的rpc接口来做扩展,相关的GitHub地址分享给大家,如果有哪些地方需要改良和优化,还大家请多多指教!

源码获取方式:关注公众号[ 扯编程的淡 ],回复:0615

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
67 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
2天前
|
算法 安全 Go
Go语言中的加密和解密是如何实现的?
Go语言通过标准库中的`crypto`包提供丰富的加密和解密功能,包括对称加密(如AES)、非对称加密(如RSA、ECDSA)及散列函数(如SHA256)。`encoding/base64`包则用于Base64编码与解码。开发者可根据需求选择合适的算法和密钥,使用这些包进行加密操作。示例代码展示了如何使用`crypto/aes`包实现对称加密。加密和解密操作涉及敏感数据处理,需格外注意安全性。
27 14
|
2天前
|
Go 数据库
Go语言中的包(package)是如何组织的?
在Go语言中,包是代码组织和管理的基本单元,用于集合相关函数、类型和变量,便于复用和维护。包通过目录结构、文件命名、初始化函数(`init`)及导出规则来管理命名空间和依赖关系。合理的包组织能提高代码的可读性、可维护性和可复用性,减少耦合度。例如,`stringutils`包提供字符串处理函数,主程序导入使用这些函数,使代码结构清晰易懂。
26 11
|
2天前
|
存储 安全 Go
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
|
6天前
|
监控 安全 算法
深度剖析核心科技:Go 语言赋能局域网管理监控软件进阶之旅
在局域网管理监控中,跳表作为一种高效的数据结构,能显著提升流量索引和查询效率。基于Go语言的跳表实现,通过随机化索引层生成、插入和搜索功能,在高并发场景下展现卓越性能。跳表将查询时间复杂度优化至O(log n),助力实时监控异常流量,保障网络安全与稳定。示例代码展示了其在实际应用中的精妙之处。
28 9
|
16天前
|
算法 安全 Go
Go 语言中实现 RSA 加解密、签名验证算法
随着互联网的发展,安全需求日益增长。非对称加密算法RSA成为密码学中的重要代表。本文介绍如何使用Go语言和[forgoer/openssl](https://github.com/forgoer/openssl)库简化RSA加解密操作,包括秘钥生成、加解密及签名验证。该库还支持AES、DES等常用算法,安装简便,代码示例清晰易懂。
48 12
|
19天前
|
监控 算法 安全
解锁企业计算机监控的关键:基于 Go 语言的精准洞察算法
企业计算机监控在数字化浪潮下至关重要,旨在保障信息资产安全与高效运营。利用Go语言的并发编程和系统交互能力,通过进程监控、网络行为分析及应用程序使用记录等手段,实时掌握计算机运行状态。具体实现包括获取进程信息、解析网络数据包、记录应用使用时长等,确保企业信息安全合规,提升工作效率。本文转载自:[VIPShare](https://www.vipshare.com)。
25 0
|
1月前
|
存储 缓存 负载均衡
后端开发中的性能优化策略
本文将探讨几种常见的后端性能优化策略,包括代码层面的优化、数据库查询优化、缓存机制的应用以及负载均衡的实现。通过这些方法,开发者可以显著提升系统的响应速度和处理能力,从而提供更好的用户体验。
59 4
|
16天前
|
开发框架 小程序 前端开发
圈子社交app前端+后端源码,uniapp社交兴趣圈子开发,框架php圈子小程序安装搭建
本文介绍了圈子社交APP的源码获取、分析与定制,PHP实现的圈子框架设计及代码编写,以及圈子小程序的安装搭建。涵盖环境配置、数据库设计、前后端开发与接口对接等内容,确保平台的安全性、性能和功能完整性。通过详细指导,帮助开发者快速搭建稳定可靠的圈子社交平台。
129 18
|
28天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
85 3