Go语言中的时间控制:定时器技术详细指南
Go语言中的时间控制:定时器技术详细指南
- 引言
- 定时器基础
- 创建和使用`time.Timer`
- 使用`time.Ticker`实现周期性任务
- 定时器的内部机制
- 小结
- 使用`time.Timer`实现简单的定时任务
- 创建和启动定时器
- 停止和重置定时器
- 定时器的实际应用
- 小结
- 利用`time.Ticker`处理重复的定时任务
- 创建和启动`Ticker`
- 停止`Ticker`
- `Ticker`的实际应用
- 小结
- 高级定时器技巧
- 结合通道(Channels)和`select`语句使用定时器
- 使用`select`语句实现超时控制
- 管理和取消定时器任务
- 使用`context`包取消定时任务
- 小结
- 定时器的最佳实践和性能考虑
- 避免创建大量的定时器
- 使用`time.After`和`time.AfterFunc`进行一次性超时控制
- 清理停止的定时器
- 考虑定时器的精度和系统负载
- 小结
- 实际案例分析
- 案例一:Web服务中的会话超时管理
- 案例二:基于定时器的任务调度系统
- 小结
引言
在现代软件开发中,时间的管理和利用成为了一个不可或缺的元素,尤其是在需要精确控制任务执行时间的场景下。Go语言,作为一种高效的编程语言,提供了强大的并发机制,让开发者能够更加容易地构建并发应用。其中,定时器的使用就是Go并发编程实践中的一个重要方面。无论是在web服务中定期清理过期的会话数据,还是在系统监控中周期性地检查系统的健康状态,定时器都扮演着至关重要的角色。
Go语言的定时器使用非常灵活,可以满足各种精确计时和周期性执行任务的需求。通过标准库time
包中的Timer
和Ticker
,Go让定时任务的实现变得既简单又高效。这些工具不仅能帮助我们管理时间相关的功能,还能在保持应用性能的同时,提高代码的可读性和维护性。
但是,要充分利用Go语言的定时器,就需要对其工作原理和使用方式有一个深入的理解。本文旨在为中级至高级的Go开发者提供一个全面的指南,通过详细介绍如何在Go中使用定时器来执行一次性或者周期性的任务,我们将探索time.Timer
和time.Ticker
的使用方法,讨论它们的工作原理,以及如何在实际项目中应用这些知识来解决具体问题。
我们将从定时器的基本概念讲起,通过实例代码深入分析定时器的创建、启动、停止以及重置等操作,进而探讨在并发环境中使用定时器的高级技巧,包括如何结合Go的并发特性,如通道(channels)和select
语句,来实现更加复杂的定时逻辑。最后,我们还将讨论定时器在实际开发中的最佳实践和性能考虑,帮助你避免常见的陷阱,提升应用的效率和稳定性。
随着我们的深入,你将发现,无论是构建高性能的网络服务,还是开发需要精确时间控制的系统应用,掌握Go语言定时器的使用都将为你打开新的可能性。让我们开始这一段旅程,探索Go定时器的奥秘吧。
定时器基础
在深入探讨Go语言中定时器的高级应用之前,首先需要理解定时器的基本概念和工作机制。在Go语言的time
包中,提供了Timer
和Ticker
两种定时器,它们分别用于处理单次定时任务和重复执行的定时任务。通过这两种定时器,我们可以在Go程序中实现精确的时间管理和任务调度。
创建和使用time.Timer
time.Timer
用于在未来某一时刻执行单次的任务。创建一个Timer
非常简单,只需要调用time
包的NewTimer
函数并传入一个时间间隔即可。这个时间间隔代表了从现在开始到定时器触发的时间长度。
timer := time.NewTimer(2 * time.Second)
上面的代码创建了一个定时器,它将在两秒后触发。一旦定时器到达指定时间,就可以从定时器的C
通道接收到一个时间值,表示定时器已经触发。
<-timer.C
fmt.Println("Timer expired")
Timer
还提供了Stop
和Reset
方法,允许你在定时器触发之前停止它,或者改变定时器的触发时间。
if timer.Stop() {fmt.Println("Timer stopped before expired")
}
使用time.Ticker
实现周期性任务
与time.Timer
相比,time.Ticker
用于处理需要重复执行的任务。通过NewTicker
函数,你可以创建一个新的Ticker
,它会按照指定的时间间隔重复触发。
ticker := time.NewTicker(1 * time.Second)
for range ticker.C {fmt.Println("Ticker ticked")
}
上面的代码创建了一个每秒触发一次的Ticker
。通过遍历Ticker
的C
通道,我们可以实现周期性执行的任务。与Timer
类似,Ticker
也提供了Stop
方法用于停止定时器。
定时器的内部机制
Go语言的定时器背后是一个高效的时间管理机制。定时器的触发基于时间轮(timer wheel)算法,这是一种减少时间检查开销的数据结构,能够保证即使在大量定时器存在的情况下也能保持较高的性能。
小结
定时器在Go语言中是实现时间管理和任务调度的基石。无论是执行一次性的延时任务,还是周期性的重复任务,time.Timer
和time.Ticker
都能够满足你的需求。理解和掌握这两种定时器的使用方法,是每一个Go开发者必备的技能。在接下来的章节中,我们将通过更多的示例和场景,深入探讨如何在实际开发中有效地使用定时器。
使用time.Timer
实现简单的定时任务
在Go语言中,time.Timer
是实现一次性定时任务的基本工具。这一节将详细介绍如何使用time.Timer
来执行简单的定时任务,包括定时器的启动、停止以及重置操作。
创建和启动定时器
要创建一个定时器,你只需调用time
包的NewTimer
函数,并传递一个表示时间间隔的time.Duration
值。以下示例展示了如何创建一个在10秒后触发的定时器:
timer := time.NewTimer(10 * time.Second)
创建定时器后,你可以通过timer.C
通道等待定时器触发。当定时器到达设定的时间后,当前时间会被发送到timer.C
通道,此时你可以执行需要的操作:
<-timer.C
fmt.Println("Timer 1 expired")
停止和重置定时器
在某些情况下,你可能需要在定时器触发之前停止它。Timer
提供了一个Stop
方法,可以用来阻止定时器的执行。如果定时器已经停止或者已经触发,Stop
会返回false
;如果成功阻止定时器触发,它会返回true
。
if !timer.Stop() {fmt.Println("Timer already expired or stopped")
} else {fmt.Println("Timer stopped")
}
如果你想要改变定时器的触发时间,可以使用Reset
方法。Reset
方法需要一个新的时间间隔作为参数,并重新开始计时。注意,在调用Reset
之前,你应该确保定时器的通道已经被清空,否则可能会错过定时器触发的消息。
if !timer.Stop() {<-timer.C
}
timer.Reset(5 * time.Second)
定时器的实际应用
定时器在实际开发中有广泛的应用,比如在Web服务中定时刷新缓存数据,或者在游戏开发中实现倒计时功能。通过time.Timer
,你可以精确地控制任务的执行时机,使得程序行为更加可预测和可控。
timer := time.NewTimer(2 * time.Hour)
<-timer.C
// 刷新缓存操作
refreshCache()
在使用定时器时,合理地管理定时器的生命周期是非常重要的。确保在不再需要定时器时停止它,并在使用Reset
方法时注意通道的清空,可以避免潜在的内存泄漏和逻辑错误。
小结
本节介绍了如何在Go语言中使用time.Timer
实现简单的定时任务。通过创建、启动、停止和重置定时器,你可以在程序中实现精确的时间控制和任务调度。随着对定时器更深入的理解,你将能够更加灵活地处理各种需要时间控制的场景。接下来,我们将探讨如何使用time.Ticker
来实现周期性的定时任务,以及如何在更复杂的应用场景中有效地使用定时器。
利用time.Ticker
处理重复的定时任务
在Go语言中,当你需要定期执行任务时,time.Ticker
是一个非常有用的工具。与time.Timer
相比,time.Ticker
可以在固定的时间间隔重复触发,非常适合用于实现如心跳检测、定期清理资源等周期性操作。
创建和启动Ticker
要创建一个Ticker
,你需要调用time
包的NewTicker
函数,并传递一个时间间隔作为参数。这个时间间隔定义了Ticker
触发的频率。以下代码展示了如何创建一个每秒触发一次的Ticker
:
ticker := time.NewTicker(1 * time.Second)
一旦Ticker
被创建,它就会在每个时间间隔结束时通过其C
通道发送当前时间。你可以通过遍历这个通道来处理周期性任务:
for t := range ticker.C {fmt.Println("Tick at", t)
}
停止Ticker
当你不再需要Ticker
时,应该调用它的Stop
方法来停止它。这是非常重要的,因为它可以防止Ticker
继续发送时间到通道,从而避免潜在的资源泄漏。
ticker.Stop()
请注意,与Timer
的Stop
方法不同,Ticker
的Stop
方法不会关闭C
通道。如果你试图从一个已停止的Ticker
的C
通道接收数据,会发生阻塞,因为没有更多的值会被发送到通道。
Ticker
的实际应用
Ticker
在很多场景下都非常有用。例如,在Web服务器中,你可能需要定期从数据库加载最新的配置信息,或者在后台服务中定期执行数据备份操作。
ticker := time.NewTicker(30 * time.Minute)
go func() {for range ticker.C {// 执行定期的数据备份操作backupData()}
}()
通过Ticker
,你可以确保这些任务能够按照预定的频率稳定运行,而不需要复杂的时间管理逻辑。
小结
time.Ticker
提供了一种方便的方法来执行周期性的定时任务。通过创建、启动和停止Ticker
,你可以在Go程序中实现精确的周期性操作,无论是简单的心跳检测,还是复杂的资源管理任务。正确使用Ticker
,能够让你的应用更加健壮和可靠。
接下来,我们将深入探讨一些高级定时器技巧,包括如何在并发环境中有效使用定时器,以及如何处理定时器相关的高级场景。这些技巧将帮助你更好地掌握Go语言的定时器功能,使你能够在更复杂的项目中灵活应用。
高级定时器技巧
随着对Go语言定时器更深入的探讨,我们来到了一些高级技巧,这些技巧对于构建高效且健壮的并发应用尤为重要。本节将重点讲解如何在并发环境中使用定时器,以及如何利用Go的特性来管理和取消定时器任务。
结合通道(Channels)和select
语句使用定时器
在Go的并发模型中,通道(Channels)和select
语句是核心组件。它们可以与定时器结合使用,以实现复杂的同步需求或超时控制。
使用select
语句实现超时控制
select
语句可以等待多个通道操作,并根据第一个就绪的通道执行相应的操作。这在处理超时场景时非常有用。例如,你可以使用select
语句来等待一个操作完成,同时设置一个超时限制:
operation := make(chan bool)
timeout := time.After(5 * time.Second)go func() {// 执行某项操作time.Sleep(2 * time.Second) // 模拟耗时操作operation <- true
}()select {
case <-operation:fmt.Println("Operation finished")
case <-timeout:fmt.Println("Operation timeout")
}
在这个例子中,如果操作在5秒内完成,则会输出"Operation finished";否则,超时分支被触发,输出"Operation timeout"。
管理和取消定时器任务
在并发程序中,有时你需要取消正在等待的定时器任务。虽然time.Timer
提供了Stop
方法来停止定时器,但在并发环境下取消任务可能需要更细致的控制。
使用context
包取消定时任务
Go的context
包提供了一种方式来发送取消信号到多个Goroutines,这可以用来在并发环境下取消定时器任务。以下是一个简单的示例:
ctx, cancel := context.WithCancel(context.Background())
timer := time.NewTimer(10 * time.Second)go func() {<-ctx.Done() // 等待取消信号if !timer.Stop() {<-timer.C // 如果定时器已经触发,确保清空通道}
}()// 在某个时刻取消定时器任务
cancel()
在这个例子中,当调用cancel()
函数时,通过context
发送的取消信号会导致等待ctx.Done()
的Goroutine被唤醒。然后,该Goroutine尝试停止定时器,如果定时器已经触发,则确保从timer.C
通道中读取,避免泄露。
小结
本节介绍了一些高级定时器技巧,包括如何结合Go的并发特性(如通道和select
语句)使用定时器,以及如何在并发环境中管理和取消定时器任务。通过运用这些技巧,你可以构建出更加灵活、健壮的并发应用。
接下来,我们将讨论定时器的最佳实践和性能考虑,这对于开发高性能应用来说至关重要。我们还将探讨一些常见的陷阱,以及如何避免它们,确保你的应用能够高效稳定地运行。
定时器的最佳实践和性能考虑
在Go语言中有效地使用定时器不仅仅是关于如何设置和取消它们。为了确保你的应用运行高效且稳定,了解定时器的最佳实践和性能考虑是非常重要的。本节将讨论一些关键的最佳实践和性能提示,以帮助你避免常见的陷阱,并优化你的定时器使用。
避免创建大量的定时器
在高并发的应用中,创建大量的定时器可能会对性能产生负面影响。每个time.Timer
和time.Ticker
都会占用一定的系统资源,包括内存和定时器管理的开销。如果可能,考虑使用更少的定时器来管理多个任务,或者使用其他同步机制(如select
语句和通道)来实现类似的功能。
使用time.After
和time.AfterFunc
进行一次性超时控制
当你需要简单的超时控制而不需要停止或重置定时器时,time.After
函数是一个更简洁和高效的选择。它返回一个通道,该通道在指定的时间后接收到一个时间值。这对于实现简单的超时逻辑非常有用,而且由于time.After
在内部复用定时器,因此它比手动创建和管理time.Timer
实例更高效。
select {
case result := <-operation:fmt.Println("Operation succeeded:", result)
case <-time.After(5 * time.Second):fmt.Println("Operation timed out")
}
同样,time.AfterFunc
允许你指定一个在时间到达后会被调用的回调函数,这对于需要执行异步操作的场景非常方便。
清理停止的定时器
当使用time.Timer
的Stop
方法成功停止定时器后,如果定时器已经触发但通道中的值还未被接收,则应清空该通道。这可以通过非阻塞的通道接收操作来实现,以避免潜在的Goroutine泄露。
if !timer.Stop() {select {case <-timer.C:default:}
}
考虑定时器的精度和系统负载
定时器的触发时间可能受到系统调度和当前系统负载的影响。在设计对时间敏感的应用时,应当考虑到这一点。虽然Go的定时器在大多数情况下足够精确,但在高负载或资源受限的环境下,定时器触发的时间可能会有所不同。
小结
本节探讨了使用Go语言定时器的一些最佳实践和性能考虑。通过遵循这些指导原则,你可以更有效地利用定时器,同时避免一些常见的问题。正确使用定时器不仅能提升应用的性能,还能保证其稳定性和可靠性。
至此,我们已经详细讨论了在Go语言中使用定时器的各个方面,从基本概念到高级技巧,再到最佳实践和性能考虑。希望这些知识能帮助你在实际开发中更加灵活和高效地使用定时器,无论是在简单的脚本中,还是在复杂的并发应用程序中。
最后,我们将通过一到两个实际的案例分析,深入探讨如何在复杂的应用场景中实现高效的定时任务处理。这将为你提供一些实用的示例,帮助你更好地理解并应用本文介绍的概念和技巧。
实际案例分析
在理论知识和最佳实践的基础上,通过实际案例的分析可以更好地理解定时器在复杂应用中的应用。本节将探讨几个实际案例,展示如何在Go语言中使用定时器来解决具体问题。
案例一:Web服务中的会话超时管理
在Web应用中,管理用户会话的超时是一个常见需求。通过使用定时器,我们可以有效地管理会话生命周期,自动清理过期的会话,从而释放资源并保持服务的性能。
假设我们有一个简单的会话存储,我们需要在会话到达一定时间后自动过期:
type Session struct {ID stringUser stringExpiresAt time.Time
}// sessionStore 存储所有活跃的会话
var sessionStore = make(map[string]Session)
var mutex sync.Mutex// 新建会话时启动定时器
func createSession(user string, duration time.Duration) string {expiresAt := time.Now().Add(duration)session := Session{ID: uuid.New().String(), User: user, ExpiresAt: expiresAt}mutex.Lock()sessionStore[session.ID] = sessionmutex.Unlock()// 启动定时器,到期时删除会话go func(id string) {<-time.After(duration)mutex.Lock()delete(sessionStore, id)mutex.Unlock()fmt.Printf("Session %s expired\n", id)}(session.ID)return session.ID
}
在这个案例中,每创建一个新会话时,我们都会启动一个定时器,当会话到期时自动删除会话。这种方式简单直观,但在会话非常多的情况下,可能会创建大量的Goroutines和定时器。对于更复杂的应用,考虑使用一个中心的定时器来管理所有会话的过期,或者使用第三方库来处理会话管理。
案例二:基于定时器的任务调度系统
在许多应用中,需要定期执行某些任务,比如数据备份、报告生成等。使用time.Ticker
可以很容易地实现一个基本的任务调度器:
type Task func()// scheduleTask 定期执行给定的任务
func scheduleTask(interval time.Duration, task Task) {ticker := time.NewTicker(interval)go func() {for range ticker.C {task()}}()
}// 示例任务
func backupData() {fmt.Println("Data backup started at", time.Now())
}func main() {// 每小时执行一次数据备份scheduleTask(1*time.Hour, backupData)// 阻塞主Goroutine,让调度器持续运行select {}
}
这个简单的调度器使用time.Ticker
来定期执行任务。虽然这个例子很基础,但它展示了如何利用Go的定时器来实现周期性任务的调度。对于更复杂的需求,可能需要考虑任务的优先级、错误处理、任务持久化等功能。
小结
通过上述案例分析,我们可以看到定时器在实际应用中的灵活性和强大功能。无论是进行会话管理还是构建任务调度系统,Go语言的定时器都能提供简洁有效的解决方案。然而,随着应用规模的增长,需要更加细致地考虑定时器的管理和性能优化,以确保应用的稳定和高效运行。
至此,我们已经全面探讨了在Go语言中使用定时器的方方面面,从基础知识、高级技巧到最佳实践,再到通过实际案例加深理解。希望本文能帮助你在Go语言项目中更加高效地使用定时器,为你的应用带来更大的价值。
相关文章:

Go语言中的时间控制:定时器技术详细指南
Go语言中的时间控制:定时器技术详细指南 引言定时器基础创建和使用time.Timer使用time.Ticker实现周期性任务定时器的内部机制小结 使用time.Timer实现简单的定时任务创建和启动定时器停止和重置定时器定时器的实际应用小结 利用time.Ticker处理重复的定时任务创建和…...

面试笔记系列六之redis+kafka+zookeeper基础知识点整理及常见面试题
目录 Redis redis持久化机制:RDB和AOF Redis 持久化 RDB的优点 RDB的缺点 AOF 优点 AOF 缺点 4.X版本的整合策略 Redis做分布式锁用什么命令? Redis做分布式锁死锁有哪些情况,如何解决? Redis如何做分布式锁?…...

Golang动态高效JSON解析技巧
JSON如今广泛用于配置和通信协议,但由于其定义的灵活性,很容易传递错误数据。本文介绍了如何使用mapstructure工具实现动态灵活的JSON数据解析,在牺牲一定性能的前提下,有效提升开发效率和容错能力。原文: Efficient JSON Data Ha…...

双重检验锁
双重检验锁:设计模式中的单例模式,细分为单例模式中的懒加载模式。 单例模式 单例模式:指的是一个类只有一个对象。最简单的实现方式是设一个枚举类,只有一个对象。缺点是当对象还没有被使用时,对象就已经创建存在了…...
【RISC-V 指令集】RISC-V DSP 扩展指令集介绍(一)
前言: 本笔记是基于对RISC-V DSP扩展指令集文档总结的,《P-ext-proposal.pdf》文档的关键内容如下: 主要介绍了RISC-V的P扩展指令集及其相关细节。 首先,对P扩展指令进行了概述,并列出了其与其他扩展重复的指令。 …...
RocketMQ - CentOS 7.x 安装单机版并测试
【安装前环境准备】检查是否安装好JDK(必要):java -version查看CPU信息: # cat /proc/cpuinfo # lscpu # getconf _NPROCESSORS_ONLN # cat /sys/devices/system/cpu/online # cat /proc/interrupts | egrep -i cpu查看内存信息: # free -hm …...

[JavaWeb玩耍日记]HTML+CSS+JS快速使用
目录 一.标签 二.指定css 三.css选择器 四.超链接 五.视频与排版 六.布局测试 七.布局居中 八.表格 九.表单 十.表单项 十一.JS引入与输出 十二.JS变量,循环,函数 十三.Array与字符串方法 十四.自定义对象与JSON 十五.BOM对象 十六.获取…...

如何使用ArcGIS Pro创建最低成本路径
虽然两点之间直线最短,但是在实际运用中,还需要考虑地形、植被和土地利用类型等多种因素,需要加权计算最低成本路径,这里为大家介绍一下计算方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…...

Neoverse CSS N3:实现市场领先能效的最快途径
区分老的架构 从云到边缘,Arm Neoverse 提供无与伦比的性能、效率、设计灵活性和 TCO 优势,正在颠覆传统基础设施芯片。 我们看到云和超大规模服务运营商正在推动更高的计算密度。随着 128 核心 CPU 设计上市(Microsoft Cobalt、阿里巴巴 Y…...

JavaScript实现的计时器效果
之前做过电商网站倒计时的效果,今天在倒计时的基础上,把代码修改了一下,改为计时器效果,实现了以下功能: 1.点击“开始”后,按秒计时且“开始”文字变为“停止”; 2.点击“停止”,计…...
仿函数(Functor(c++))
定义 仿函数(Functor)是一个可以像函数那样被调用的类对象。这意味着它实现了operator(),使得类的对象可以像函数那样被调用。 仿函数的主要特点 它是一个类。它重载了operator()。可以通过创建该类的对象,并像函数那样调用该对…...

智能汽车加速车规级存储应用DS2431P+TR 汽车级EEPROM 存储器IC
DS2431PT&R是一款1024位1-Wire EEPROM芯片,由四页存储区组成,每页256位。数据先被写入一个8字节暂存器中,经校验后复制到EEPROM存储器。该器件的特点是,四页存储区相互独立,可以单独进行写保护或进入EPROM仿真模式…...
js json转换成字符串
js中JSON数据转换成字符串,可以使用JSON.stringify()方法。 var obj {name: "张三", age: 18, gender: "男"}; var jsonString JSON.stringify(obj); console.log(jsonString); // 输出 {"name":"张三","age"…...
Linux笔记--基本操作指令
一、查看日期与日历 1.date指令 显示日期 #用法1:dateCST: China Standard Time时区,中国标准时间 #用法2: date 指定格式 [常用格式]: "%Y-%m-%d"(%F): 2022-07-25 "%H:%M:%S"(%T): 14:53:44 "%F %T" #用法3: date -d "-1 da…...

论文阅读:基于超像素的图卷积语义分割(图结构数据)
#Superpixel-based Graph Convolutional Network for Semantic Segmentation github链接 引言 GNN模型根据节点特征周围的边来训练节点特征,并获得最终的节点嵌入。通过利用具有不同滤波核的二维卷积对来自附近节点的信息进行整合,给定超像素方法生成的…...

记录踩过的坑-macOS下使用VS Code
目录 切换主题 安装插件 搭建Python开发环境 装Python插件 配置解释器 打开项目 打开终端 切换主题 安装插件 方法1 方法2 搭建Python开发环境 装Python插件 配置解释器 假设解释器已经通过Anaconda建好,只需要在VS Code中关联。 打开项目 打开终端...
30天JS挑战(第十四天)------数据的复制
第十四天挑战(数据的复制) 地址:https://javascript30.com/ 所有内容均上传至gitee,答案不唯一,仅代表本人思路 中文详解:https://github.com/soyaine/JavaScript30 该详解是Soyaine及其团队整理编撰的,是对源代码…...

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+辗转相除法)
[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中 N N N 个整数。 现在给出这 N N N 个整数,小明想知道包含这 N N N 个整数的最短的等差数列有几项? 输…...

Linux:kubernetes(k8s)部署CNI网络插件(4)
在上一章进行了node加入master Linux:kubernetes(k8s)node节点加入master主节点(3)-CSDN博客https://blog.csdn.net/w14768855/article/details/136420447?spm1001.2014.3001.5501 但是他们显示还是没准备好 看一下…...

docker save 命令 docker load 命令 快速复制容器
docker save 命令 docker load 命令 1、docker save 命令2、docker load 命令 1、docker save 命令 docker save 命令用于在系统上把正在使用的某个容器镜像 导出成容器镜像文件保存下载,以便在其他系统上导入这个容器镜像文件 以便快速在其他服务器上启动相同的容…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...