golang 琐碎知识

news2024/9/21 10:30:18

golang 琐碎知识(持续进行)

时间格式

time.now.Format("2006-01-02T 15:04:05")

make声明切片bug

Golang:statusList := make([]*model.StatusList, 6)
会声明一个长为6的null切片,使用append添加时不会将null覆盖掉

去掉切片末尾元素

segments[:len(segments)-1]

互斥锁

  • 带缓存的channel

    var signal = make(chan struct{}, 1)
    func Test() {
    	signal <- struct{}{}
    	defer func() {
    		<-signal
    	}()
    }
    

    可以实现与mutex相同的功能,进入函数向带一个缓存的channel中写入一个元素,导致其处于阻塞状态,其余协程在进入该函数并写入的时候会阻塞等待其释放。该函数执行完毕,则会释放该缓存channel,其余协程便可依次进入执行。

  • sync.mutex

    var mu sync.Mutex
    func Test() {
    	mu.Lock()
    	defer mu.Unlock()
    }
    

    与上述具有相同的作用。

  • 注意:全局的变量i,其自增使用需要特别注意

    var signal = make(chan struct{}, 1)
    
    func IsPortAvailable(port int) bool {
    	address := fmt.Sprintf("%s:%d", "0.0.0.0", port)
    	listener, err := net.Listen("tcp", address)
    	if err != nil {
    		log.Printf("port %s is taken: %s", address, err)
    		return false
    	}
    
    	defer listener.Close()
    	return true
    }
    
    var avaiblePort = 1000
    
    func GetAvailablePort() int {
    	var j int
    	signal <- struct{}{}
    	for {
    		avaiblePort++
    		j = avaiblePort
    		if IsPortAvailable(j) {
    			break
    		}
    	}
    	<-signal
    
    	return j
    }
    

    上述写法没有问题,需要注意不能直接返回全局变量avaiblePort,因为这段代码只能保证在临界区内部可以保证自增是互斥的,但是除了临界区之后该变量会被其它协程抢占,所以在return的时候,该变量已经发生了改变,有可能是1001、1002。所以正确的做法是将该可用的全局变量赋值给一个局部变量,然后返回。并且注意该例子是获取可用端口的并发互斥实现,所以需要赋值给局部变量j之后再判断该端口是否可用,如果判断完再赋值,也会导致并发互斥失效。

panic recover

参考:https://geektutu.com/post/gee-day7.html

core dump 打印堆栈信息

https://blog.csdn.net/xmcy001122/article/details/105665732?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-105665732-blog-103850401.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-105665732-blog-103850401.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=3

任务队列,执行异步任务时需要考虑异步worker

https://lailin.xyz/post/go-training-03.html

编写实例:https://gitee.com/huoyingwhw/go_async_task

异步任务,如果需要使用 goroutine 时,应该使用同一的 Go 函数进行创建,这个函数中会进行 recover ,避免因为野生 goroutine panic 导致主进程退出,recover只会对当前goroutine生效,对子goroutine不起作用

func Go(f func()){
    go func(){
        defer func(){
            if err := recover(); err != nil {
                log.Printf("panic: %+v", err)
            }
        }()

        f()
    }()
}

panic两种出现情况:

  • 没有预期的一种异常的发生,自动抛出
  • 预期的抛出

设计模式

https://lailin.xyz/post/singleton.html

任务队列machinery使用与源码剖析

https://cloud.tencent.com/developer/article/1169675

redis 消息队列 golang

https://juejin.cn/post/7058699128284381221

golang build编译

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQQCZ6sK-1670136444071)(C:\Users\zzy\AppData\Roaming\Typora\typora-user-images\image-20221019132303376.png)]

golang 消息队列

NSQ,介绍:https://cloud.tencent.com/developer/article/1896007

golang 使用sqlite

https://learnku.com/docs/build-web-application-with-golang/053-uses-the-sqlite-database/3183

golang 分布式数据流转

https://juejin.cn/post/7088262766779170853

go test 添加性能打印

go test -benchmem -bench=“.” -v singleton.go singleton_test.go

多态

什么是多态?

概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说:就是用基类的引用指向子类的对象。

为什么要用多态呢?

原因:我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.。耦合度讲的是模块模块之间,代码代码之间的关联度,通过对系统的分析把他分解成一个一个子模块,子模块提供稳定的接口,达到降低系统耦合度的的目的,模块模块之间尽量使用模块接口访问,而不是随意引用其他模块的成员变量。

多态有什么好处?

有两个好处:

  • 1、应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。//继承
  • 2、派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 //多态的真正作用,

golang crypto/rsa 使用教程

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

golang 同步包

go mod tidy

面向对象的编程思维详解

https://github.com/aceld/golang/blob/main/6%E3%80%81%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E7%90%86%E8%A7%A3interface.md#6%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E7%90%86%E8%A7%A3interface

//实现架构层(基于抽象层进行业务封装-针对interface接口进行封装)
func BankerBusiness(banker AbstractBanker) {
	//通过接口来向下调用,(多态现象)
	banker.DoBusi()
}

解决exec.Start() 产生僵尸进程无法回收

// 执行shell
func ExecShell(s string) error {
	//execComand := func() error {
	//	err := exec.Command("/bin/bash", "-c", s).Start()
	//	logging.Infof("utils.ExecShell 脚本: %s\n", s)
	//	if err != nil {
	//		return err
	//	}
	//
	//}

	ctx := context.Background()

	cmd := exec.CommandContext(ctx, "/bin/bash", "-c", s)

	cmd.SysProcAttr = &syscall.SysProcAttr{}

	err := cmd.Start()
	if err != nil {
		return err
	}

	logging.Infof("utils.ExecShell 脚本: %s\n", s)

	// 监听进程wait,回收子进程
	errCmdCh := make(chan error, 1)

	go func() {
		go func() {
			errCmdCh <- cmd.Wait()
		}()
		for {
			select {
			case <-ctx.Done():
				logging.Infof("utils.ExecShell ctx.done\n")
				pid := cmd.Process.Pid
				if err := syscall.Kill(-1*pid, syscall.SIGKILL); err != nil {
					return
				}
                //想要杀死整个进程组,而不是单个进程,需要传递负数形式。
			case err := <-errCmdCh:
				if err != nil {
					logging.Errorf("utils.ExecShell 脚本: s, errCmdCh error %+v \n", s, err)
				}
				return
			default:
				time.Sleep(1 * time.Second)
			}
		}
	}()


	return nil
}

参考:https://blog.csdn.net/af2251337/article/details/125357359

注意指针问题

在实际开发中遇到了一个比较棘手的问题,在循环外声明了一个对象,然后循环内更改值并把地址赋值给另外一个对象,然后将该对象append一个切片中,因为是指针赋值,所以在该切片中存在的全是同一个地址,因此值也是一样的,都是最后一次赋值的内容。

golang 异步任务需传参

永不停息!!!:
大佬请教一下,我现在使用go关键字实现了异步任务,但是我这个地方有个疑问,就是taskResultService 这个对象要不要当作入参传入go关键字开启的这个匿名函数里面,像我这样使用有没有问题呀
代码:
func A(c *gin.Context) {
	var err error
	taskResultService := &service.TaskResultService{}
	err = c.ShouldBindJSON(&taskResultService.M)
	if err != nil {
		logging.Errorf("api.HandleTaskResult: bind json 失败, err: %v\n", err)
		c.JSON(400, utils.SyncErrorResponse(err))
		return
	}
	// sync response
	c.JSON(0, utils.SyncSuccessResponse())
	// async execute
	go func() {
		logging.Infof("api.HandleTaskResult: 开始获取任务结果目录 [%s]\n", taskResultService.M.BaseInfo.TaskId)
		// auth token
		ttSecret, err := oauthc.Agent2ServerAuthGetToken(taskResultService.M.BaseInfo.TaskId)
		if err != nil {
			logging.Errorf("api.HandleTaskResult: 从mysql获取token失败, err: %v\n", err)
			return
		}
	}()
}:
你这个可以不用

永不停息!!!:
这样使用的话,默认就把taskResultService这个对象传过去了吗,这里面的底层逻辑是怎样的,能详细说一下吗

ㅤ:
不是默认传进去了  你可以简单理解为for大括号里用了大括号外的变量 是一个原理

永不停息!!!:
如果存在并发的话,有多个taskResultService对象,会不会引起参数错乱

ㅤ:
会 如果你在for 循环里 开协程  用for语句里的变量。你会发现所有协程用的是for语句的最后一个值

那就只能传入参数来避免咯

golang 释放互斥锁

//var mutex sync.Mutex
//
//func MutexText() {
// defer func() {
//    if err := recover(); err != nil {
//       log.Println(err)
//    }
// }()
// log.Println("尝试获得锁")
// flag := mutex.TryLock()
// defer mutex.Unlock()
// log.Println(flag)
// log.Println("获得锁")
// time.Sleep(time.Second*3)
// panic("错误")
//
//}

func main() {
	//for i:=0; i<2; i++ {
	//	log.Println("123")
	//	go MutexText()
	//}
}

er(); err != nil {
// log.Println(err)
// }
// }()
// log.Println(“尝试获得锁”)
// flag := mutex.TryLock()
// defer mutex.Unlock()
// log.Println(flag)
// log.Println(“获得锁”)
// time.Sleep(time.Second*3)
// panic(“错误”)
//
//}

func main() {
//for i:=0; i<2; i++ {
// log.Println(“123”)
// go MutexText()
//}
}

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

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

相关文章

JMeter入门教程(10) --函数助手

文章目录1.CSVRead2.Random3.RandomString4.RandomDate5.time在JMeter的选项菜单中有一个“函数助手对话框”&#xff0c;点击打开“函数助手”对话框&#xff0c;使用函数助手&#xff0c;我们可以从“选择一个功能”下拉列表中选择一个函数&#xff0c;并为其参数设定值。表格…

SQL函数之分割

数据库中有一张地区数据统计表,但是并不规则 ,记录类似于,225100:02:3:20160725是一串代码,以:分割,第1位为地区代码,第2位为分类代码,第3位为数量,第4位为日期 地区代码含义225100-上海 225200-江苏 225300-浙江 为可能有某些位不存在,缺位时计算规则如下: 1、…

Golang开发习惯:变量、常量声明使用惯例

《Go语言精进之路》第二、三章部分内容学习记录笔记。 1.基本原则 Golang开发中&#xff0c;可遵守简单且一致的命名原则&#xff0c;力求命名精简、易懂和一致。 package声明 Golang的package声明以小写形式的单个词进行命名&#xff1a; shopservice、utils、logs、tcc、l…

计算机毕业论文java毕业设计选题源代码

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 《【论文】S2SH药膳馆会员管理系统》该项目采用技术jsp、strust2、Spring、hibernate、tomcat服务器、mysql数据库 &#xff0c;项目含有源码、论…

十四、使用 Vue Router 开发单页应用(2)

本章概要 动态路由匹配 查询参数 路由匹配语法 参数的自定义正则表达式可重复参数可选参数 嵌套路由 14.2 动态路由匹配 实际项目开发时&#xff0c;经常需要把匹配某种模式的路由映射到同一个组件。例如&#xff0c;有一个 Book 组件&#xff0c;对于所有 ID 各不相同的图书…

MOOC 大数据Note

MOOC 大数据NoteSparkSpark 一个软件栈满足不同交互场景Lineage 血缘关系创建 转换 动作ShuffleMapStageSpark的部署和应用方式RDD操作分为转换&#xff08;Transformation&#xff09;和动作&#xff08;Action&#xff09;两种类型&#xff0c;下列属于动作&#xff08;Actio…

开发工具——gcc/g++

开发工具gcc/g 完成代码的编写完后&#xff0c;要形成可执行程序&#xff0c;需要编译工具进行对代码的编译。 C语言的编译工具是gcc&#xff0c;c的编译工具是g。 如果g没有的话&#xff0c;可以切换到root执行命令yum install -y gcc-c C语言和C的编译&#xff1a; gc…

「点燃我,温暖你」用Python制作一个动态爱心效果

最近「点燃我&#xff0c;温暖你」这部剧非常火&#xff0c;讲述的是程序员的爱情故事。 其中陈飞宇饰演的男主李峋&#xff0c;在剧中用程序做出的爱心跳动效果&#xff0c;非常炫。 网上各个大佬也是纷纷给出看法&#xff0c;综合就是不太可能用C语言来实现的。 大概率是AE…

Reg注册表读写

在Windows 95及其后继版本中&#xff0c;采用了一种叫做“注册表”的数据库来统一进行管理&#xff0c;将各种信息资源集中起来并存储各种配置信息。按照这一原则&#xff0c;Windows各版本中都采用了将应用程序和计算机系统全部配置信息容纳在一起的注册表&#xff0c;用来管理…

Java内存溢出故障案例及Linux内存机制探究

文章目录Java内存溢出故障案例及Linux内存机制探究OOM Killer触发机制分析如何避免系统触发OOM Killer这部分内容属于demo案例分享&#xff0c;解决线上运维问题&#xff0c;思路是最重要的 Java内存溢出故障案例及Linux内存机制探究 这是一个线上数据分析应用故障案例&#…

Java—反射

文章目录什么是反射反射定义java创建对象的三个阶段反射过程反射第一步&#xff1a;获取类对象获取类对象的三种方式反射第二步&#xff1a;获取类信息如何获取类信息&#xff1f;1、获取成员变量&#xff1a;2、获取方法&#xff1a;3、获取构造器反射第三步&#xff1a;使用反…

vue学习笔记——简单入门总结(四)

文章目录1.Vue3的特性和变化1.1.创建vue3项目1.2.分析main.js变化&#xff1a;1.3.setup--组合式api的开端1.4.ref函数和reactive函数&#xff1a;1.5.watch监视属性1.5.watchEffect函数1.6.vue3生命周期&#xff1a;1.Vue3的特性和变化 1.1.创建vue3项目 1.这里我们使用脚手架…

RegAD-Registration based Few-Shot Anomaly Detection论文学习

摘要 本文为少样本异常检测&#xff08;FSAD&#xff09;&#xff0c;这是一种实用但尚未被研究的异常检测&#xff08;AD&#xff09;&#xff0c;少样本意味着在训练中只为每个类别提供有限数量的正常图像。 现有的少样本异常检测的研究主要使用的是 一类别一模型 学习范式…

李宏毅《DLHLP》学习笔记7 - Voice Conversion

视频链接&#xff1a;https://www.youtube.com/watch?vJj6blc8UijY&listPLJV_el3uVTsO07RpBYFsXg-bN5Lu0nhdG&index9&ab_channelHung-yiLee 课件链接&#xff1a;https://speech.ee.ntu.edu.tw/~tlkagk/courses/DLHLP20/Voice%20Conversion%20(v3).pdf 1. 语音转…

JAVA+MySQL 图书馆借阅信息管理系统

图书馆是当下很多大学生和有志青年学习和借阅图书的场所,图书馆每天都有大量的人员需要接待,如何能够更好的对用户的这些借阅信息进行信息化的管理是当下大多数图书馆管理人员所关心的问题 本系统是通过JAVA和MYSQL来进行开发的,通过本系统可以对图书馆内的图书信息,用户信息以…

基于PCIe的NVMe协议在FPGA中实现方法

NVMe协议是工作在PCIE的最上层协议层的&#xff0c;故需要先搞清楚PCIE。本文基于Xilinx的UltraScale&#xff0c;开发工具为Vivado2021.2。学习中以spec为主&#xff0c;其它资料辅助参考(重点介绍学习方法及资料&#xff0c;有时间再加细节)。请勿转载&#xff01; 1 PCIe学…

基于PHP+MySQL青年志愿者服务管理系统的设计与实现

志愿者管理系统能够通过互联网得到广泛的、全面的宣传,让尽可能多的人积极的参加到志愿者行列中来,不仅为需要的人提供了服务,而且锻炼了自己,志愿者是一个对社会和自己以及需要帮助的人都有很多好处的事情 PHP青年志愿者服务网站是一个公益类型的网站,系统通过PHp&#xff1a;…

HK1 BOX刷入 Armbian系统作为服务器

HK1 BOX刷入 Armbian系统作为服务器 1 安装Armbian到EMMC 硬件 HK1 BOX s905 x3 固件版本选择 Armbian_23.02.0_Aml_s905x3_bullseye_5.15.80_server_2022.12.01用usb启动&#xff0c;tf/sd有的设备不行&#xff0c;有干扰&#xff0c;有可能从TF卡无法启动系统。 用usb启…

Grid 布局实现九宫格图片动画

前言 &#x1f44f;Grid 布局实现九宫格&#xff0c;background-position设置背景图像起始位置&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义css变量&#xff1a;九宫格中每个宫格的长/宽为w&#xff0c…

Kafka - 14 Kafka消费者 | 分区的分配策略及再平衡 | Range | RoundRobin | Sticky | CooperativeSticky

文章目录1. 分区的分配以及再平衡2. Range 分区分配以及再平衡3. RoundRobin 分区分配以及再平衡4. Sticky 分区分配以及再平衡1. 分区的分配以及再平衡 一个consumer group中有多个consumer组成&#xff0c;一个 topic有多个partition组成&#xff0c;现在的问题是&#xff0…