慕课网Go-4.package、单元测试、并发编程
package
1_1_User.go
package usertype User struct {Name string
}
1_1_UserGet.go
package userfunc GetCourse(c User) string {return c.Name
}
1_1_UserMain.go
package mainimport ("fmt"Userch03 "goproj/IMOOC/ch03/user"//别名,防止同名歧义
)func main() {c := Userch03.User{Name: "hi,user",}fmt.Println(Userch03.GetCourse(c))
}
gin
github链接
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",})})r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
首次使用时,包的导入报错:
鼠标放在"github.com/gin-gonic/gin",出现提示框,点击Sycn…,等一会报错消失
Sync过程自动下载,可以在go.mod中看到
或者在终端打开、go mod tidy
单元测试
package mainfunc add(a, b int) int {return a + b
}
package mainimport "testing"func TestAdd(t *testing.T) {if testing.Short(){t.Skip("short模式")}re := add(1, 2)if re != 3 {t.Errorf("expect:%d,actual:%d", 3, re)}
}
终端go test
测试函数前的运行箭头右键后
基于表格
func TestAdd2(t *testing.T) {var dataset = []struct {a intb intout int}{{1, 1, 2},{-9, 8, 1},{0, 0, 0},}for _, value := range dataset {re := add(value.a, value.b)if re != value.out {t.Errorf("expect:%d,actual:%d", 3, re)}}
}
性能测试
const numbers = 10000func BenchmarkStringSprintf(b *testing.B) {b.ResetTimer()for i := 0; i < b.N; i++ {var str stringfor j := 0; j < numbers; j++ {str = fmt.Sprintf("%s%d", str, j)}}b.StopTimer()
}func BenchmarkStringAdd(b *testing.B) {b.ResetTimer()for i := 0; i < b.N; i++ {var str stringfor j := 0; j < numbers; j++ {str += strconv.Itoa(j)}}b.StopTimer()
}func BenchmarkStringBuilder(b *testing.B) {b.ResetTimer()for i := 0; i < b.N; i++ {var builder strings.Builderfor j := 0; j < numbers; j++ {builder.WriteString(strconv.Itoa(j))}_ = builder.String()}b.StopTimer()
}
并发编程
package mainimport ("fmt""time"
)func asyncPrint() {time.Sleep(time.Second)fmt.Println("hi")
}func main() {go asyncPrint()fmt.Println("main")time.Sleep(2 * time.Second)fmt.Println("main2")
}
import "fmt"func main() {fmt.Println("method1")for i := 0; i < 100; i++ {go func() {fmt.Println(i)}()}//fmt.Println("method2")//for i := 0; i < 100; i++ {// tmp := i// go func() {// fmt.Println(tmp)// }()//}//fmt.Println("method3")//for i := 0; i < 100; i++ {// go func(i int) {// fmt.Println(i)// }(i)//}
}
waitgroup
package mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupwg.Add(100)fmt.Println("method3")for i := 0; i < 100; i++ {go func(i int) {defer wg.Done()fmt.Println(i)}(i)}wg.Wait()
}
互斥锁mutex
package mainimport ("fmt""sync""sync/atomic"
)var total int32
var wg sync.WaitGroup
var lock sync.Mutexfunc add() {defer wg.Done()for i := 0; i < 10000; i++ {atomic.AddInt32(&total, 1)//lock.Lock()//total += 1//lock.Unlock()}
}func sub() {defer wg.Done()for i := 0; i < 10000; i++ {atomic.AddInt32(&total, -1)//lock.Lock()//total -= 1//lock.Unlock()}
}func main() {wg.Add(2)go add()go sub()wg.Wait()fmt.Println(total)fmt.Println("all done")
}
读写锁rwlock
package mainimport ("fmt""sync""time"
)func main() {var rwlock sync.RWMutexvar wg sync.WaitGroupwg.Add(6)//写锁go func() {time.Sleep(3 * time.Second)rwlock.Lock()defer rwlock.Unlock()fmt.Println("writing")time.Sleep(5 * time.Second)fmt.Println("write finish")}()time.Sleep(time.Second)//读锁for i := 0; i < 5; i++ {go func() {defer wg.Done()for j := 0; j < 10; j++ {rwlock.RLock()time.Sleep(500 * time.Millisecond)fmt.Println("read")rwlock.RUnlock()}}()}wg.Wait()
}
channel
package mainimport "fmt"func main() {//有缓存var msg1 chan stringmsg1 = make(chan string, 1) //1是缓存空间大小msg1 <- "harry"data := <-msg1fmt.Println(data)//无缓存,happen-before机制var msg2 chan stringmsg2 = make(chan string, 0)go func(msg2 chan string) {data2 := <-msg2fmt.Println(data2)}(msg2)msg2 <- "potter"var msg3 chan intmsg3 = make(chan int, 2)go func(msg3 chan int) {for data3 := range msg3 {fmt.Println(data3)}fmt.Println("all done")}(msg3)msg3 <- 1msg3 <- 2close(msg3)var ch1 chan int //双向var ch2 chan<- int //只写入var ch3 <-chan int //只读取c := make(chan int, 3)var send chan<- int = cvar receive <-chan int = c
}
打印数字和字母
package mainimport ("fmt""time"
)var number, letter = make(chan bool), make(chan bool)func printNum() {i := 1for {<-numberfmt.Printf("%d%d", i, i+1)i += 2letter <- true}`在这里插入代码片`
}func printLetter() {i := 0str := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"for {<-letterif i >= len(str) {return}fmt.Print(str[i : i+2])i += 2number <- true}
}func main() {go printNum()go printLetter()number <- truetime.Sleep(100 * time.Second)
}
select
package mainimport ("fmt""time"
)// 空结构体不占内存、channel多线程安全
var done = make(chan struct{})func g1(ch1 chan struct{}) {time.Sleep(time.Second)ch1 <- struct{}{}
}func g2(ch2 chan struct{}) {time.Sleep(1 * time.Second)ch2 <- struct{}{}
}func main() {ch1 := make(chan struct{})ch2 := make(chan struct{})go g1(ch1)go g2(ch2)//执行先就绪的channel,都就绪则随机(防止饥饿)//select {//case <-ch1:// fmt.Println("g1 done")//case <-ch2:// fmt.Println("g2 done")//default:// fmt.Println("default")//}timer := time.NewTimer(5 * time.Second)select {case <-ch1:fmt.Println("g1 done")case <-ch2:fmt.Println("g2 done")case <-timer.C:fmt.Println("time our")return}
}
context
package mainimport ("fmt""sync""time"
)var wgc sync.WaitGroupfunc cpuInfo(stop chan struct{}) {defer wgc.Done()for {select {case <-stop:fmt.Println("退出CPU监控")returndefault:time.Sleep(2 * time.Second)fmt.Println("CPU信息")}}
}func main() {var stop = make(chan struct{})wgc.Add(1)go cpuInfo(stop)time.Sleep(6 * time.Second)stop <- struct{}{}wgc.Wait()fmt.Println("监控完成")
}
package mainimport ("context""fmt""sync""time"
)var wgc2 sync.WaitGroupfunc cpuInfo2(ctx context.Context) {defer wgc2.Done()for {select {case <-ctx.Done():fmt.Println("退出CPU监控")returndefault:time.Sleep(2 * time.Second)fmt.Println("CPU信息")}}
}func main() {wgc2.Add(1)ctx, cancel := context.WithCancel(context.Background())go cpuInfo2(ctx)time.Sleep(6 * time.Second)cancel()wgc2.Wait()fmt.Println("监控完成")
}
相关文章:

慕课网Go-4.package、单元测试、并发编程
package 1_1_User.go package usertype User struct {Name string }1_1_UserGet.go package userfunc GetCourse(c User) string {return c.Name }1_1_UserMain.go package mainimport ("fmt"Userch03 "goproj/IMOOC/ch03/user"//别名,防止同名…...

[JavaWeb]SQL介绍-DDL-DML
SQL介绍-DDL-DML 一.SQL简介1.简介2.SQL通用语法3.SQL语言的分类 二.DDL-操作数据库与表1.DDL操作数据库2.DDL操作表①.查询表(Retrieve)②.创建表(Create)③.修改表(Update)④.删除表(Delete) 三.Navicat的安装与使用四.DML-操作表数据1.添加(Insert)2.修改(Update)3.删除(Del…...
git源码安装(无sudo权限)
git源码安装(无sudo权限) 下载源码解压安装添加到环境变量 下载源码 去https://mirrors.edge.kernel.org/pub/software/scm/git/下载需要的版本。我下载的是2.41.0版本 wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.41.0.tar.gz解…...

Web3 叙述交易所授权置换概念 编写transferFrom与approve函数
前文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 中 我们通过ERC-20一种开发者设计的不成文规定 也将我们的代币开发的很像个样子了 我们打开 ERC-20文档 我们transfer后面的函数就是transferFrom 这个也是 一个账号 from 发送给另一个账号 to 数量 val…...

Redis系列二:Clion+MAC+Redis环境搭建
1. ClionMACRedis-3.0-annotated环境搭建 参考: https://github.com/huangz1990/redis-3.0-annotated https://gitee.com/dumpcao/redis-3.0-annotated-cmake-in-clion https://tool.4xseo.com/a/12910.html 1.1 下载并导入Clion git clone https://gitee.com/dum…...

Linux下 Docker容器引擎基础(2)
目录 创建私有仓库 将修改过的nginx镜像做标记封装,准备上传到私有仓库 将镜像上传到私有仓库 从私有仓库中下载镜像到本地 CPU使用率 CPU共享比例 CPU周期限制 CPU 配额控制参数的混合案例 内存限制 Block IO 的限制 限制bps 和iops 创建私有仓库 仓库&a…...

现场服务管理系统有哪些?5个现场服务管理软件对比
现场售后服务管理软件的使用者通常是机械设备、家电、仪表仪器、医疗器械等厂商的工程师和客服调度人员。现场售后服务管理软件可将服务过程标准化,包括工单派发、服务过程步骤、配件订购出货和付款、客户评价都有系统支持,有的现场售后服务软件还支持数…...

leetcode 912.排序数组
⭐️ 题目描述 🌟 leetcode链接:排序数组 思路: 此题如果使用冒泡插入选择这些时间复杂度 O ( N 2 ) O(N^2) O(N2) 的算法会超时,使用快排 优化也过不去,因为里面有一个测试用例全是 2 即使加了三数取中也会是 O (…...

利用MMPreTrain微调图像分类模型
前言 MMPreTrain是一款基于PyTorch的开源深度学习预工具箱,是OpenMMLab项目的成员之一MMPreTrain的主要特性有: 支持多元化的主干网络与预训练模型支持多种训练策略(有监督学习,无监督学习,多模态学习等)提…...

express学习笔记3 - 三大件
便于统一管理router,创建 router 文件夹,创建 router/index.js: const express require(express)// 注册路由 const router express.Router() router.get(/,function(req,res){res.send(让我们开始express之旅) }) /*** 集中处理404请求的…...

Java课题笔记~Maven基础
2、Maven 基础 2.1 Maven安装与配置 下载安装 配置:修改安装目录/conf/settings.xml 本地仓库:存放的是下载的jar包 中央仓库:要从哪个网站去下载jar包 - 阿里云的仓库 2.2 创建Maven项目...

三步问题(力扣)n种解法 JAVA
目录 题目:1、dfs:2、dfs 备忘录(剪枝):(1)神器 HashMap 备忘录:(2)数组 memo 备忘录: 3、动态规划:4、利用 static 的储存功能:&…...
flask---》登录认证装饰器/配置文件/路由系统
登录认证装饰器 # 0 装饰器的本质原理-# 类装饰器:1 装饰类的装饰器 2 类作为装饰器 # 1 装饰器使用位置,顺序 # 3 flask路由下加装饰器,一定要加endpoint-如果不指定endpoint,反向解析的名字都是函数名,不加装饰器…...
Jvm实际运行情况-JVM(十七)
上篇文章说jmap和jstat的命令,如何查看youngGc和FullGc耗时和次数。 Jmap-JVM(十六) Jvm实际运行情况 背景: 机器配置:2核4G JVM内存大小:2G 系统运行天数:7天 期间发生FULL GC次数和耗时…...

【BASH】回顾与知识点梳理(二)
【BASH】回顾与知识点梳理 二 二. Shell 的变量功能2.1 什么是变量?2.2 变量的取用与设定: echo, 变量设定规则: set/unset2.3 环境变量的功能用 set 观察所有变量 (含环境变量与自定义变量)export: 自定义变量转成环境变量那如何将环境变量转成自定义变…...
【分布式训练】Accelerate 多卡训练,单卡评测,进程卡住的解决办法
最近想把之前的一个模型的改成多卡训练的。我并不懂DDP,DP。一开始打算使用Transformers的Trainer,但是配置的过程踩了很多坑也没有弄成功。【我是自己写的评测方法,但是我找不到能让触发Trainer去用我的方法评测的路劲】,后来偶然…...

时间复杂度为O(nlogn)的两种排序算法
1.归并排序 归并排序的核心思想:如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。 归并排序使用的就是分治思想。分治&#x…...
java调用onnx模型,支持yolov5和yolov7
不点star不给解答问题 可直接运行主文件:ObjectDetection_1_25200_n.java 或者 ObjectDetection_n_7.java 都可以直接运行两个可以运行的主文件是为了支持不用网络结构的模型,即使是onnx模型,输出的结果参数也不一样,支持以下两种…...

DP-GAN损失
在前面我们看了生成器和判别器的组成。 生成器损失公式: 首先将fake image 和真实的 image输入到判别器中: 接着看第一个损失:参数分别为fake image经过判别器的输出mask,和真实的label进行损失计算。对应于: 其中l…...

自监督去噪:Noise2Void原理和调用(Tensorflow)
文章原文: https://arxiv.org/abs/1811.10980 N2V源代码: https://github.com/juglab/n2v 参考博客: https://zhuanlan.zhihu.com/p/445840211https://zhuanlan.zhihu.com/p/133961768https://zhuanlan.zhihu.com/p/563746026 文章目录 1. 方法原理1.1 Noise2Noise回…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...