go语法大赏
前些日子单机房稳定性下降,找了好一会才找到真正的原因。这里面涉及到不少go语法细节,正好大家一起看一下。
一、仿真代码
这是仿真之后的代码
package mainimport ("fmt""go.uber.org/atomic""time"
)type StopSignal struct{}// RecvChannel is the wrapped channel for recv side.
type RecvChannel[T any] struct {// Data will be passed through the result channel.DataChannel <-chan T// Error will be passed through the error channel.ErrorChannel <-chan error// Stop signal will be passed through the stop signal channel,// when signal is sent or channel is closed, it means recv side requires send side to stop sending data.StopChannel chan<- StopSignalstopped *atomic.Bool
}// Close sends stop signal to the sender side.
func (c *RecvChannel[T]) Close() {if !c.stopped.CompareAndSwap(false, true) {return}close(c.StopChannel)
}// Stopped returns whether the stop signal has been sent.
func (c *RecvChannel[T]) Stopped() bool {return c.stopped.Load()
}// GetError returns the last error, it waits at most 1s if the error channel is not closed.
func (c *RecvChannel[T]) GetError() error {select {case err := <-c.ErrorChannel:return errcase <-time.After(time.Second):return nil}
}// SendChannel is the wrapped channel for sender side.
type SendChannel[T any] struct {// Data will be passed through the result channel.DataChannel chan<- T// Error will be passed through the error channel.ErrorChannel chan<- error// Stop signal will be passed through the stop signal channel,// when signal is sent or channel is closed, it means recv side requires send side to stop sending data.StopChannel <-chan StopSignalstopped *atomic.Bool
}// Close closes the result channel and error channel, so the recv will know the sending has been stopped.
func (c *SendChannel[T]) Close() {close(c.DataChannel)close(c.ErrorChannel)c.stopped = atomic.NewBool(true)
}// Stopped returns whether the stop signal has been sent.
func (c *SendChannel[T]) Stopped() bool {return c.stopped.Load()
}// Publish sends data to the data channel, does nothing if it is closed.
func (c *SendChannel[T]) Publish(t T) {if c.Stopped() {return}select {case <-c.StopChannel:case c.DataChannel <- t:}
}func (c *SendChannel[T]) PublishError(err error, close bool) {if c.Stopped() {return}select {case <-c.StopChannel:case c.ErrorChannel <- err:}if close {c.Close()}
}func NewChannel[T any](bufSize int) (*SendChannel[T], *RecvChannel[T]) {resultC := make(chan T, bufSize)errC := make(chan error, 1)stopC := make(chan StopSignal, 1)stopped := atomic.NewBool(false)sc := &SendChannel[T]{DataChannel: resultC,ErrorChannel: errC,StopChannel: stopC,stopped: stopped,}rc := &RecvChannel[T]{DataChannel: resultC,ErrorChannel: errC,StopChannel: stopC,stopped: stopped,}return sc, rc
}// SliceToChannel creates a channel and sends the slice's items into it.
// It ignores if the item in the slices is not a type T or error.
func SliceToChannel[T any](size int, s []any) *RecvChannel[T] {sc, rc := NewChannel[T](size)go func() {for _, item := range s {if sc.Stopped() {sc.Close()return}switch v := item.(type) {case T:sc.DataChannel <- vcase error:sc.ErrorChannel <- vdefault:continue}}sc.Close()}()return rc
}// /// 真正的处理逻辑
func Process(send *SendChannel[int]) {defer func() {if send != nil {fmt.Println("3 Process close defer")send.Close()}}()go func() {for {select {case <-send.StopChannel:fmt.Println("2 Process stop channel")send.Close()return}}}()send.ErrorChannel <- fmt.Errorf("0 Start error \n")fmt.Println("0 Start error")time.Sleep(1 * time.Second)
}func main() {send, recv := NewChannel[int](10)go func() {Process(send)}()for {fmt.Println("only once")select {case <-recv.ErrorChannel:fmt.Println("1 recv errorchannel ")recv.Close()break}break}//panic(1)time.Sleep(5 * time.Second)
}
执行结果如下:
➜ my go run main.go
only once
0 Start error
1 recv errorchannel
2 Process stop channel
3 Process close defer
panic: close of closed channelgoroutine 21 [running]:
main.(*SendChannel[...]).Close(...)/Users/bytedance/My/work/go/my/main.go:60
main.Process.func1()/Users/bytedance/My/work/go/my/main.go:147 +0x6c
main.Process(0x14000092020)/Users/bytedance/My/work/go/my/main.go:163 +0x118
main.main.func1()/Users/bytedance/My/work/go/my/main.go:168 +0x20
created by main.main in goroutine 1/Users/bytedance/My/work/go/my/main.go:167 +0x70
exit status 2
不知道大家是否能够比较快的看出来问题。
二、相关语法
2.1channel
知识点
在 Go 语言中,channel
是用于在多个goroutine
之间进行通信和同步的重要机制,以下是一些关于channel
的重要知识点:
1. 基本概念
- 定义:
channel
可以被看作是一个类型安全的管道,用于在goroutine
之间传递数据,遵循 CSP(Communicating Sequential Processes)模型,即 “通过通信来共享内存,而不是通过共享内存来通信”,从而避免了传统共享内存并发编程中的数据竞争等问题。 - 声明与创建:使用
make
函数创建,语法为make(chan 数据类型, 缓冲大小)
。缓冲大小是可选参数,省略时创建的是无缓冲channel
;指定大于 0 的缓冲大小时创建的是有缓冲channel
。例如:
unbufferedChan := make(chan int) // 无缓冲channel
bufferedChan := make(chan int, 10) // 有缓冲channel,缓冲大小为10
2. 操作方式
- 发送数据:使用
<-
操作符将数据发送到channel
中,语法为channel <- 数据
。例如:
ch := make(chan int)
go func() {ch <- 42 // 发送数据42到ch中
}()
- 接收数据:同样使用
<-
操作符从channel
中接收数据,有两种形式。一种是将接收到的数据赋值给变量,如数据 := <-channel
;另一种是只接收数据不赋值,如<-channel
。例如:
ch := make(chan int)
go func() {ch <- 42
}()
value := <-ch // 从ch中接收数据并赋值给value
- 关闭
channel
:使用内置的close
函数关闭channel
,关闭后不能再向其发送数据,但可以继续接收已发送的数据。接收完所有数据后,再接收将得到该类型的零值。例如:
ch := make(chan int)
go func() {for i := 0; i < 5; i++ {ch <- i}close(ch) // 关闭channel
}()
for {value, ok := <-chif!ok {break // 当ok为false时,表示channel已关闭}fmt.Println(value)
}
3. 缓冲与非缓冲channel
- 无缓冲
channel
:也叫同步channel
,数据的发送和接收必须同时准备好,即发送操作和接收操作会互相阻塞,直到对方准备好。只有当有对应的接收者在等待时,发送者才能发送数据;反之,只有当有发送者发送数据时,接收者才能接收数据。这确保了数据的同步传递。 - 有缓冲
channel
:内部有一个缓冲区,只要缓冲区未满,发送操作就不会阻塞;只要缓冲区不为空,接收操作就不会阻塞。当缓冲区满时,继续发送会阻塞;当缓冲区为空时,继续接收会阻塞。例如:
bufferedChan := make(chan int, 3)
bufferedChan <- 1
bufferedChan <- 2
bufferedChan <- 3
// 此时缓冲区已满,再发送会阻塞
// bufferedChan <- 4
4. 单向channel
- 单向
channel
只能用于发送或接收数据,分别为只写channel
(chan<- 数据类型
)和只读channel
(<-chan 数据类型
)。单向channel
主要用于函数参数传递,限制channel
的使用方向,增强代码的可读性和安全性。例如:
// 只写channel
func sendData(ch chan<- int) {ch <- 42
}// 只读channel
func receiveData(ch <-chan int) {data := <-chfmt.Println(data)
}
5. select
语句与channel
select
语句用于监听多个channel
的操作,它可以同时等待多个channel
的发送或接收操作。当有多个channel
准备好时,select
会随机选择一个执行。select
语句还可以结合default
分支实现非阻塞操作。例如:
ch1 := make(chan int)
ch2 := make(chan int)go func() {ch1 <- 1
}()select {
case data := <-ch1:fmt.Println("Received from ch1:", data)
case data := <-ch2:fmt.Println("Received from ch2:", data)
default:fmt.Println("No channel is ready")
}
6. channel
的阻塞与死锁
- 阻塞:发送和接收操作在
channel
未准备好时会阻塞当前goroutine
。无缓冲channel
在没有对应的接收者时发送会阻塞,没有发送者时接收会阻塞;有缓冲channel
在缓冲区满时发送会阻塞,缓冲区空时接收会阻塞。 - 死锁:如果在一个
goroutine
中,channel
的发送和接收操作相互等待,且没有其他goroutine
来打破这种等待,就会发生死锁。例如,一个goroutine
向无缓冲channel
发送数据,但没有其他goroutine
接收;或者一个goroutine
从无缓冲channel
接收数据,但没有其他goroutine
发送数据。运行时系统会检测到死锁并报错。
7. channel
的底层实现
channel
的底层实现基于一个名为hchan
的结构体,它包含了当前队列中元素数量、环形队列大小(缓冲容量)、指向环形队列的指针、元素大小、关闭标志、元素类型信息、发送索引、接收索引、等待接收的协程队列、等待发送的协程队列以及一个互斥锁等字段。- 发送操作时,如果接收队列非空,直接将数据拷贝给第一个等待的接收者并唤醒该
goroutine
;如果缓冲区未满,将数据存入缓冲区;如果缓冲区已满或无缓冲channel
,将当前goroutine
加入发送队列并挂起。接收操作时,如果发送队列非空,直接从发送者获取数据并唤醒发送者;如果缓冲区不为空,从缓冲区取出数据;如果缓冲区为空且无缓冲channel
,将当前goroutine
加入接收队列并挂起。
8. channel
误用导致的问题
在 Go 语言中,操作channel
时可能导致panic
或者死锁等:
- 多次关闭同一个
channel
使用内置的close
函数关闭channel
后,如果再次调用close
函数尝试关闭同一个channel
,就会引发panic
。这是因为channel
的关闭状态是一种不可逆的操作,重复关闭没有实际意义,并且可能会导致难以调试的问题。例如:
ch := make(chan int)
close(ch)
close(ch) // 这里会导致panic
- 向已关闭的
channel
发送数据
当一个channel
被关闭后,再向其发送数据会导致panic
。因为关闭channel
意味着不再有数据会被发送到该channel
中,继续发送数据违反了这种约定。示例如下:
ch := make(chan int)
close(ch)
ch <- 1 // 向已关闭的channel发送数据,会导致panic
- 关闭未初始化(
nil
)的channel
如果尝试关闭一个值为nil
的channel
,会引发panic
。nil
的channel
没有实际的底层数据结构来支持关闭操作。例如:
var ch chan int
close(ch) // 这里会导致panic,因为ch是nil
- 死锁导致的
panic
在操作channel
时,如果多个goroutine
之间的通信和同步设计不当,可能会导致死锁。死锁发生时,所有涉及的goroutine
都在互相等待对方,从而导致程序无法继续执行,运行时系统会检测到这种情况。例如:
func main() {ch := make(chan int)ch <- 1 // 没有其他goroutine从ch中接收数据,这里会阻塞,导致死锁fmt.Println("This line will never be executed")
}
➜ my go run main.go
fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:
main.main()/Users/bytedance/My/work/go/my/main.go:172 +0x54
exit status 2
- 不恰当的
select
语句使用
在select
语句中,如果没有default
分支,并且所有的case
对应的channel
操作都无法立即执行(阻塞),那么当前goroutine
会被阻塞。如果在主goroutine
中发生这种情况且没有其他goroutine
可以运行,就会导致死锁。例如:
func main() {ch1 := make(chan int)ch2 := make(chan int)select {case <-ch1:// 没有数据发送到ch1,这里会阻塞case <-ch2:// 没有数据发送到ch2,这里会阻塞}
}
要避免这些panic
情况,编写代码时需要仔细设计channel
的使用逻辑,合理处理channel
的关闭、数据的发送和接收,以及确保goroutine
之间的同步和通信正确无误。
解析
在NewChannel函数中,send和recv channel被赋值的是同一个ErrorChannel,而send和recv都是单向channel,一个只写,一个只读。
所以当Process里send.ErrorChannel <- fmt.Errorf(“0 Start error \n”)执行的时候,main中的case <-recv.ErrorChannel被立即触发,然后执行recv.Close()函数,该函数执行了close(c.StopChannel),又触发了Process中的case <-send.StopChannel,执行了send.Close()。对于Process退出的时候,有defer,再次执行send.Close(),导致channel被多次关闭。
2.2defer
知识点
以前写过Go defer的一些神奇规则,你了解吗?,这次主要关注
- defer(延迟函数)执行按后进先出顺序执行,即先出现的 defer最后执行。
- Process中的defer的执行顺序与Process中的goroutine里的defer(如果有的话)执行顺序无关。
解析
其实这两个Close位置都有可能panic,主要看谁被先执行到。我是为了演示让Process sleep了1s。
defer func() {if send != nil {fmt.Println("3 Process close defer")send.Close()}}()go func() {for {select {case <-send.StopChannel:fmt.Println("2 Process stop channel")send.Close()return}}}()
2.3recover
知识点
在 Go 语言中,recover
只能用于捕获当前goroutine
内的panic
,它的作用范围仅限于当前goroutine
。具体说明如下:
只能捕获当前goroutine
的panic
:当一个goroutine
发生panic
时,该goroutine
会沿着调用栈向上展开,执行所有已注册的defer
函数。如果在这些defer
函数中调用recover
,则可以捕获到该goroutine
内的panic
,并恢复正常执行流程。而对于其他goroutine
中发生的panic
,当前goroutine
无法通过recover
捕获。例如:
package mainimport ("fmt""time"
)func worker() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered in worker:", r)}}()panic("Worker panicked")
}func main() {go worker()time.Sleep(1 * time.Second)fmt.Println("Main goroutine continues")
}
在上述代码中,worker
函数中的defer
语句里使用recover
捕获了该goroutine
内的panic
。main
函数中的goroutine
并不会受到影响,继续执行并打印出 “Main goroutine continues”。
解析
当时之所以查的比较困难,主要是发现Process中go func里配置了recover,报了很多错,但感觉没有大问题。加上代码不熟悉,没有发现有概率触发Process的defer中的panic。而且公司的监控没有监控到自建goroutine的panic情况。
三、解决方案
在Process中添加recover
defer func() {if r := recover(); r != nil {fmt.Println("Recovered in worker:", r)}}()
其实比较建议在涉及channel相关的地方,都加个recover,尤其是不太熟悉的时候。
相关文章:
go语法大赏
前些日子单机房稳定性下降,找了好一会才找到真正的原因。这里面涉及到不少go语法细节,正好大家一起看一下。 一、仿真代码 这是仿真之后的代码 package mainimport ("fmt""go.uber.org/atomic""time" )type StopSignal…...
运行vscode编辑器源码
距离上次二次开发vscode已经是三年前的事了,当时是1.60.0版本,目前vscode已升级到了1.99.2版本,里面改动很大,最近下载下来了新版源码跑起来看看 准备node、python 源码里面node版本做了限制 2025-01-27 09:53:00.450 [info] Fo…...
ShenNiusModularity项目源码学习(26:ShenNius.Admin.Mvc项目分析-11)
本文学习并分析ShenNiusModularity项目中商城系统模块的小程序用户页面、用户收货地址页面。 1、小程序用户页面 小程序用户页面用于检索、浏览使用商城系统的用户数据(保存在shop_appuser表内,系统用户保存在sys_user表内),该页…...
C#中的成员常量:编译时的静态魔法
在C#编程中,常量(const)是一个强大而特殊的语言特性,特别是当它们作为类的成员时。本文将深入探讨成员常量的特性、使用场景以及与静态量的区别。 成员常量的基本特性 成员常量是声明在类内部的常量,具有以下核心特点: 声明位置…...
C# 深入理解类(成员常量)
成员常量 成员常量类似前一章所述的局部常量,只是它们被声明在类声明中而不是方法内,如下面的 示例: 与局部常量类似,用于初始化成员肯量的值在编译时必须是可计算的,而且通常是一个预定 义简单类型或由它们组成的表达…...
服务端HttpServletRequest、HttpServletResponse、HttpSession
一、概述 在JavaWeb 开发中,获取客户端传递的参数至关重要。http请求是客户端向服务端发起数据传输协议,主要包含包含请求行、请求头、空行和请求体四个部分,在这四部分中分别携带客户端传递到服务端的数据。常见的http请求方式有get、post、…...
有哪些GIF图片转换的开源工具
以下是关于GIF图片转换的开源工具的详细总结,涵盖功能特点、适用场景及用户评价: 1. FFmpeg 功能特点: 作为开源命令行工具,FFmpeg支持视频转GIF、调整帧率、分辨率、截取片段等操作,可通过脚本批量处理。适用场景: 适合开发者或技术用户进行高效批处理,常用于服务器端自…...
Vue.js教学第五章:计算属性与侦听器详解
Vue.js 之计算属性与侦听器详解 一、计算属性 (一)概念 计算属性(Computed Properties)是 Vue.js 中的一个核心概念。它允许我们基于一个或多个数据属性来定义一个新的属性,该属性的值会根据其依赖的数据属性的变化而自动更新。这就好像是一个 “智能” 属性,它的值不是…...
第三章:UI 系统架构拆解与动态界面管理实录
还记得我们第二章刚跑通主场景,那时候是不是觉得“终于见到界面了”?但请等等,你看到的只是冰山一角,下面藏着的是 UIManager 的地狱之门。 本章我们将深入探讨: UI 界面如何加载(Prefab 动态加载机制&…...
第四章:WebSocket 通信机制全解与客户端发包实录
如果你以为一个游戏启动后只靠本地逻辑运转,那你真是低估了网络通信的存在感。在互动组件项目里,WebSocket 才是真正的灵魂通道——UI 再好看,没包发出去也等于白搭。 本章我们深入讲解 WebSocket 在安卓前端项目中的应用,从封装结…...
pnpm项目内网迁移
pnpm项目内网迁移 文章目录 pnpm项目内网迁移0.前言1.基础环境安装2.构建pnpm离线安装包3.使用pnpm重新安装项目依赖4.项目迁移参考链接: 0.前言 要将一个依赖pnpm的项目迁移到内网离线环境下进行开发。 1.基础环境安装 要保证NodeJS版本一致,否则执行…...
C++23 放宽范围适配器以允许仅移动类型(P2494R2)
文章目录 引言背景与动机提案内容与实现细节提案 P2494R2实现细节编译器支持 对开发者的影响提高灵活性简化代码向后兼容性 示例代码总结 引言 C23 标准中引入了许多重要的改进,其中一项值得关注的特性是放宽范围适配器(range adaptors)以允…...
[ctfshow web入门] web119
信息收集 import requestsurl "http://51a7e437-2e66-4742-bbfe-e4cce44e360b.challenge.ctf.show/" for i in range(255):data {"code": f"{chr(i)}"}response requests.post(url, datadata)# print(len(response.text))# print(response.t…...
vector--OJ3
链接: [link](链接: link) class Solution { public: vector<string> str{ "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };void CB(string& …...
第6章 实战案例:基于 STEVAL-IDB011V1 板级 CI/CD 全流程
在前五章中,我们完成了嵌入式 CI/CD 从环境搭建、编译自动化、测试自动化、发布分发到监控回归的全技术链条。本章将以 STEVAL-IDB011V1(搭载 BlueNRG-355)评估板为实战载体,手把手演示如何在 GitLab CI(或 Jenkins)上,构建一条从 Git Push → 编译 → 测试 → 刷写 → …...
逆变器的输出外特性分析
VSG 并网状态下,考虑到弱电网下线路阻抗不能忽略,VSG 的功率传输模型可以表示为 VSG 的输出电压经过线路阻抗后串联至电网(考虑滤波电感,且忽略滤波电容作用)。设 U 为 VSG 输出电压的幅值,Ug为电网电压的幅…...
如何给PSCAD添加库文件
1、点击Options 2、选择蓝色的选项 3、查看Intel(R) Visual Fortran Compiler XE 的版本 4、打开原文件的Library 5、打开 6、点击这个文件的右键 7、然后选择第一项project setting 9、先把第8步中link里面原有的路径删除,再点browes[A1] ,然后选择 [A…...
基于simulink搭建的模块化多电平MMC仿真模型
1. 模块化多电平换流器的运行原理 1.1模块化多电平换流器的拓扑结构 MMC共由6个桥臂构成。其中每个桥臂由若干个串联且结构相同的子模块(Sub-Module, SM)与一个电抗器L串联…...
基于simulink的LCC-HVDC输电模型
1.本模型基于simulink搭建常规直流输电模型,运行稳定。 有需要交流或者模型的可在CSDN上留言...
PWM整流器双闭环PI参数的整定
1. 整流侧电路拓扑图 整流电路由交流侧电源、线路电阻、线路电抗、整流器、滤波电容以及负载组成。整体电路图如图1所示。 图 1 整流电路拓扑图 其中,IGBT的开关状函数如下式所示 根据图 1 列出 KVL 公式如下,电流的正方向是从左到右 对于每一相的IGBT相…...
柔性直流输电系统介绍及simulink模型的搭建
1. 柔性直流输电的运行原理 柔性直流输电系统由电压源型换流器与直流输电线路构成, 图 1‑1所示为单端电压源型换流器原理图。柔性直流输电系统的功率可以双向流动,即换流器既可以作为整流站将从交流系统接收的功率通过直流线路输送出去,也可以作为逆变站将通过直流…...
matlab求矩阵的逆、行列式、秩、转置
inv - 计算矩阵的逆 用途:计算一个可逆矩阵的逆矩阵。 D [1, 2; 3, 4]; % 定义一个2x2矩阵 D_inv inv(D); % 计算矩阵D的逆 disp(D_inv);det - 计算矩阵的行列式 用途:计算方阵的行列式。 E [1, 2; 3, 4]; determinant det(E); % 计算行列式 disp…...
如何在纷杂的环境当中保持保持独立思考能力?
引言 当你在人群当中时,你是否经常容易受到身边人的干扰,而丢失自己原有的想法,其实在环境纷杂当中,我们很容易产生“从众效应”而丢失了自己对这件事独立思考的能力。拥有不受外界影响,独立思考的能力可以让我们更加…...
Linux:计算机的层状结构
1.冯诺依曼体系结构 我们常见的计算机,如笔记本、台式机。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系结构。 CPU:运算器和控制器组成。运算器主要工作是做算术运算和逻辑运算。控制器主要工作是协调设备之间信息流动的…...
注册表设置windows背景护眼色
方法一: CtrlR,输入regedit打开注册表 HKEY_CURRENT_USER\Control Panel\Colors 右侧窗口Windows键值由255 255 255改为202 234 206。 方法二: 还是注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\DefaultColo…...
《算法导论(第4版)》阅读笔记:p82-p82
《算法导论(第4版)》学习第 17 天,p82-p82 总结,总计 1 页。 一、技术总结 1. Matrix Matrices(矩阵) (1)教材 因为第 4 章涉及到矩阵,矩阵属于线性代数(linear algebra)范畴,如果不熟悉,可以看一下作者推荐的两本…...
政府数据开放试点企业如何抢占特许经营协议黄金席位
首席数据官高鹏律师团队 《中共中央办公厅 国务院办公厅关于 加快公共数据资源开发利用的意见》的落地,标志着数据从“封闭管理的行政资源”正式转变为“可流通的市场要素”。但机遇与风险从来是一枚硬币的两面——特许经营协议的黄金席位背后,隐藏着…...
Spring之Bean的初始化 Bean的生命周期 全站式解析
目录 导图 步骤 第一步 实例化 第二步 属性赋值 第三步 初始化 aware 接口 BeanPostProcessor 接口 InitializingBean 和 init-method 第四步使用 第五步使用后销毁 描述一下 Bean 的 生命周期 导图 步骤 总体上可以分为五步 首先是 Bean 的实例化Bean 在进行实例…...
exit耗时高
背景:程序退出发现被强制退出,而不是正常的退出。正常退出是发送15信号,而异常退出是发送信号9,强制退出。退出机制是先发送信号15,然后6s内没有退出完成,会发送信号9。通过查看退出流程,是将初…...
密文搜索-map容器+substr
https://www.luogu.com.cn/problem/P8630 ///因为密码是打乱顺序的,所以只要字母个数对上就行 ///用map存字母种类和个数 ///vector存每行密码 ///不用set,每行独立 再考察一个字符串分割函数substr,map自动比较 #include<bits/stdc.h…...
从专家编码到神经网络学习:DTM 的符号操作新范式
1st author: Paul Soulos paper: Differentiable Tree Operations Promote Compositional Generalization ICML 2023 code: psoulos/dtm: Differentiable Tree Machine 1. 问题与思路 现代深度学习在连续向量空间中取得了巨大成功,然而在处理具有显式结构&#x…...
江协科技GPIO输入输出hal库实现
首先先介绍一下GPIO在hal库里面的函数 GPIOhal库函数介绍 GPIO在hal库里面有两个文件,一个hal_gpio.h一个hal_gpio_ex.h 第一个文件主要存放的就是hal库里面对gpio的相关函数以及GPIO配置的结构体,还有hal库与标准库的一大区别回调函数。以及一些对gp…...
软件设计师教程—— 第二章 程序设计语言基础知识(上)
前言 在竞争激烈的就业市场中,证书是大学生求职的重要加分项。中级软件设计师证书专业性强、认可度高,是计算机相关专业学生考证的热门选择,既能检验专业知识,又有助于职业发展。本教程将聚焦核心重点,以点带面构建知…...
Java 快速转 C# 教程
以下是一个针对 Java 开发者快速转向 C# 的简明教程,重点对比 Java 与 C# 的异同,帮助你快速上手。 项目结构: .sln :解决方案文件,管理多个项目之间的依赖关系。.csproj :项目文件,定义目标框…...
Linux面试题集合(5)
把文件1的内容追加到文件2 cat 文件1>>文件2 把文件1和文件2合并成文件3 cat 文件1 文件2>文件3 使用less查看文件时,搜寻ab字符 /ab 用more和less如何查看文件 more: CtrlF -- 向下滚动一屏 CtrlB -- 返回上一屏 f -- 向下翻屏 b -- 向上翻屏 …...
OpenCV 光流估计:从原理到实战
在计算机视觉领域,光流估计(Optical Flow Estimation)是一项至关重要的技术,它能够通过分析视频序列中图像像素的运动信息,捕捉物体和相机的运动情况。OpenCV 作为强大的计算机视觉库,为我们提供了高效实现…...
星火杯大模型应用创新赛学习笔记——datawhale
背景——赛事任务 聚焦大学生真实应用场景,围绕阅读、写作、搜索、聊天、问答等方向,聚焦口语学习、面试招聘、论文写作、学习笔记等一个或多个细分应用场景,完成具有创新性、实用性的应用方案,呈现可演示、可落地、具备商业价值…...
Ulyssess Ring Attention
https://zhuanlan.zhihu.com/p/689067888https://zhuanlan.zhihu.com/p/689067888DeepSpeed Ulysess:切分Q、K、V序列维度,核心卖点保持通信复杂度低,和GPU数无关,和序列长度呈线性关系。 Ring-Attention:切分Q、K、V序…...
c++重要知识点汇总(不定期更新)
前言 真心希望各位dalao点赞收藏~ 树状数组 作用:高效求出区间前缀和,允许进行修改操作。 举个栗子: 刚开始有8项,分别为1-8。 首先构建二叉树: 1-8/ |/ |/ |/ |/ |1-4 5-8/ | / |/ | / |1-…...
重排序模型解读 mxbai-rerank-base-v2 强大的重排序模型
mxbai-rerank-base-v2 强大的重排序模型 模型介绍benchmark综合评价安装 模型介绍 mxbai-rerank-base-v2 是 Mixedbread 提供的一个强大的重排序模型,旨在提高搜索相关性。该模型支持多语言,特别是在英语和中文方面表现出色。它还支持代码和 SQL 排序&a…...
电子电路:到底该怎么理解电容器的“通交流阻直流”?
电容器“通交流,阻直流”的特性源于其对不同频率电信号的响应差异,具体可通过以下步骤理解: 一、电容器的基本结构与充放电机制 结构:由两个导体极板(如金属)和中间的绝缘介质组成。充放电过程:…...
售前工作.工作流程和工具
第一部分 售前解决方案及技术建议书的制作 售前解决方案编写的标准操作步骤SOP: 售前解决方案写作方法_哔哩哔哩_bilibili 第二部分 投标过程关键活动--商务标技术方案 1. 按项目管理--售前销售项目立项 销售活动和销售线索的跟踪流程和工具 1)拿到标书ÿ…...
ORACLE数据库实例报错ORA-00470: LGWR process terminated with error宕机问题分析报告
服务概述 10月21号03:22分,BOSS数据库实例发生异常宕机;工程师及时响应此问题并对此故障原因进行分析及相关建议,详细的故障情况及相关日志、TRACE文件的分析及总结、建议,请参阅本文档。 hzboss数据库实例宕机分析 4.1 数据库层面日志的分…...
深度学习---知识蒸馏(Knowledge Distillation, KD)
一、知识蒸馏的本质与起源 定义: 知识蒸馏是一种模型压缩与迁移技术,通过将复杂高性能的教师模型(Teacher Model)所学的“知识”迁移到轻量级的学生模型(Student Model),使学生模型在参数量和计…...
AI日报 - 2024年5月17日
🌟 今日概览 (60秒速览) ▎🤖 大模型前沿 | OpenAI推出自主编码代理Codex;Google DeepMind发布Gemini驱动的编码代理AlphaEvolve,能设计先进算法;Meta旗舰AI模型Llama 4 Behemoth发布推迟。 Codex能并行处理多任务&…...
OAuth2.0
OAuth2.0 1. 什么是OAuth2.02.OAuth2.0的应用场景3. OAuth2.0基本概念4. 经典OAuth2.0认证流程5. 四种授权模式5.1 授权码模式(Authorization Code Grant)5.2 隐式授权(Implicit Grant)5.3 密码模式(Resource Owner Pa…...
deepin v23.1 音量自动静音问题解决
有的机器上会有音量自动静音问题, 如果你的电脑上也遇到, 这个问题是 Linux 内核的原因, ubuntu上也可能会遇到相同问题(比如你升级了最新内核6.14), 而我测试得6.8.0的内核是不会自动静音的. Index of /mainline 到上面这个链接(linux 内核的官方链接)下载6.8.0的内核, s…...
Spring Security 集成指南:避免 CORS 跨域问题
Spring Security 集成指南:避免 CORS 跨域问题 在现代 Web 应用开发中,前后端分离架构已成为主流。当我们使用 Spring Security 保护后端 API 时,经常会遇到跨域资源共享(CORS)问题。这篇文章将详细解析 Spring Secur…...
stack和queue简单模拟实现
stackreverse_iteratorqueuepriority_queue仿函数具体代码 stack Stacks are a type of container adaptor, specifically designed to operate in a LIFO context (last-in first-out), where elements are inserted and extracted only from one end of the container. 上述描…...
2.单链表两数相加(java)
题目描述: 分析: 1.首先创建一个虚拟节点 ListNode dummy new ListNode(-1);再创建一个节点来保存虚拟节点,因为使用虚拟节点来移动,如果不保存,最后就会丢失。保存虚拟节点:ListNode pdummy; 2.进位标志…...