Go语言技能树实战:从并发模式到REST API的工程化演练

news2026/5/2 15:21:00
1. 项目概述一个Go语言技能树的实战演练场最近在GitHub上看到一个挺有意思的仓库叫guynhsichngeodiec/cc-skills-golang。光看这个名字你可能会有点懵但点进去就会发现这其实是一个围绕Go语言技能点构建的实战项目集合。它不是那种枯燥的教程或者简单的“Hello World”示例而更像是一个开发者为自己也可能是为团队搭建的、用于系统性练习和巩固Go核心技能的“演武场”。这个项目的核心价值在于“以练代学”。很多朋友学Go看语法、读文档感觉都懂了但一到实际项目中面对并发控制、错误处理、接口设计这些具体场景还是容易手忙脚乱。cc-skills-golang项目就试图解决这个问题。它通过一系列精心设计的小模块或小项目覆盖了从基础语法、标准库使用到并发编程、网络服务、测试、性能优化等Go开发者必须掌握的技能树分支。你可以把它看作一份“动手清单”每完成一个模块就意味着你在某个特定技能点上有了更扎实的实践经验。对于不同阶段的开发者这个项目都有参考价值。如果你是Go新手可以跟着它一步步构建对语言全貌的认知避免陷入“只会写单文件小程序”的困境。如果你是有经验的开发者可以把它当作一个代码沙盒用来验证某些设计模式在Go中的最佳实践或者快速重温某些不常用的标准库API。接下来我们就深入拆解一下这样一个技能树项目通常会包含哪些核心内容以及如何最高效地利用它来提升自己。2. 项目结构与核心模块设计思路2.1 技能树的模块化划分逻辑一个优秀的技能树项目其结构本身就应该体现良好的软件工程思想。cc-skills-golang这类项目通常不会把所有代码堆在一个文件里而是会按功能或技能点进行清晰的模块化划分。常见的目录结构可能如下cc-skills-golang/ ├── fundamentals/ # 基础核心 │ ├── variables-types/ │ ├── control-flow/ │ ├── functions-methods/ │ └── interfaces-structs/ ├── concurrency/ # 并发编程Go的招牌 │ ├── goroutines/ │ ├── channels/ │ ├── sync-primitives/ │ └── patterns/ # 如worker pool, pipeline ├── standard-lib/ # 标准库实战 │ ├── io-files/ │ ├── net-http/ │ ├── encoding-json-xml/ │ └── time-context/ ├── advanced/ # 进阶主题 │ ├── reflection/ │ ├── unsafe/ │ ├── performance-tuning/ │ └── profiling/ ├── projects/ # 综合小项目 │ ├── cli-tool/ │ ├── rest-api-server/ │ └── web-crawler/ └── tests-benchmarks/ # 测试与基准测试 ├── unit-testing/ ├── mocking/ └── benchmark/这种结构的好处是显而易见的。首先它降低了认知负担。你可以清晰地知道每个目录对应哪个知识领域想练习“通道”就直奔concurrency/channels而不会被其他无关代码干扰。其次它便于管理和扩展。当你想增加一个关于“数据库操作”的新技能模块时只需要在根目录下新建一个database/文件夹即可不会破坏现有结构。最后这种模块化本身就是一种示范告诉学习者如何组织一个中型Go项目的代码这比单纯讲理论要有用得多。注意在实际创建自己的技能树项目时不必一开始就追求大而全的结构。可以从你最薄弱或最感兴趣的1-2个模块开始比如先搭建好concurrency/和tests-benchmarks/。重要的是保持结构的清晰和一致后续再逐步填充内容。一个混乱的目录结构会让学习热情迅速消退。2.2 从“知道”到“做到”的练习设计模块划分只是骨架里面的内容即每个技能点的具体练习才是血肉。设计这些练习的关键在于如何把抽象的语言特性转化为具体的、可执行的编码任务。这需要设计者深入理解每个技能点的核心难点和常见应用场景。以“并发编程中的通道Channel”这个技能点为例。一个差的练习可能只是让你写一段代码演示如何创建通道、发送和接收数据。而一个好的练习应该模拟真实场景中的挑战。例如可以设计这样一个任务“实现一个简单的任务分发系统。主协程main goroutine生成一批任务比如计算1到N的平方通过一个缓冲通道分发给10个工作协程worker goroutine去执行。工作协程将结果写入另一个结果通道主协程收集所有结果并汇总。要求处理协程的优雅退出即所有任务完成后所有工作协程能自动结束不会发生goroutine泄漏。”这个练习看似简单但它强制你综合运用多个知识点创建带缓冲的通道、启动多个goroutine、使用select语句进行多路复用、使用sync.WaitGroup或context.Context来同步和传递取消信号、关闭通道的正确时机、以及防止向已关闭通道发送数据导致的panic。完成这个练习后你对通道的理解就不再是停留在语法层面而是真正具备了解决一类并发问题的能力。再比如“错误处理”这个基础技能。可以设计一个练习“编写一个函数模拟从文件读取配置、解析JSON、验证配置项这一系列操作。要求每一步都可能出错文件不存在、JSON格式错误、配置值非法你的函数需要能够精确地返回是哪一步出了错以及错误的上下文信息比如哪一行JSON有问题并且错误信息应该对调用者友好便于上层逻辑判断和处理。” 这个练习能让你深刻理解Go中error接口的价值以及如何通过自定义错误类型、错误包装fmt.Errorfwith%w来构建清晰的错误传播链。3. 核心技能点深度解析与实操要点3.1 并发模式超越简单的GoroutineGo的并发模型是其最吸引人的特性之一但go关键字只是起点。在技能树项目中并发模块必须深入几种经典模式。Worker Pool工作池模式是处理大量并行任务的标配。其核心是预先创建一组固定数量的工作goroutine即worker它们从一个共享的任务通道中读取并执行任务。这样做的最大好处是控制并发度避免无限制地创建goroutine导致系统资源耗尽。实现时要注意几个细节第一任务通道通常设为缓冲通道缓冲大小需要根据任务产生速度和消费速度来权衡太小会阻塞生产者太大可能占用过多内存。第二如何优雅关闭常见的做法是关闭任务通道然后等待所有worker在消费完通道内剩余任务后自然退出这通常配合sync.WaitGroup来实现。第三如何处理任务执行中的错误一种做法是让worker将错误发送到一个专门的错误通道由专门的协程处理。Pipeline流水线模式则将复杂处理流程分解为多个阶段每个阶段由一组goroutine完成特定工作阶段之间通过通道连接。比如一个数据处理流水线读取 - 过滤 - 转换 - 聚合 - 输出。实现Pipeline的关键在于设计好阶段间通道的关闭传播。通常当一个阶段完成其工作上游通道关闭且数据处理完毕后它应该关闭其下游通道以此类推最终让整个流水线有序停止。context.Context在这里非常有用它可以广播取消信号让所有阶段的goroutine都能及时响应外部中断。实操心得在实现这些模式时最容易踩的坑就是通道操作导致的goroutine泄漏。比如一个goroutine因为等待从通道读取而永远阻塞或者因为等待向通道发送而阻塞。务必确保你的逻辑在所有可能的执行路径上都能让goroutine有机会结束。使用select配合context.Done()是处理超时和取消、避免永久阻塞的黄金法则。另外可以使用go vet和像golangci-lint这样的工具来检查常见的并发问题。3.2 接口与组合Go的“面向对象”哲学Go没有传统的类和继承其代码复用的核心是接口Interface和组合Composition。技能树项目需要设计练习来体现这种思维转变。一个经典的练习是设计一个简单的缓存系统。你可以先定义一个Cache接口包含Get(key string) ([]byte, error)和Set(key string, value []byte) error方法。然后你可以实现两个具体的缓存类型InMemoryCache基于map和FileCache基于本地文件。客户端代码只需要依赖Cache接口这样就可以在不修改客户端逻辑的情况下灵活切换缓存的后端实现。这个练习能让你体会到“面向接口编程”带来的解耦好处。更进一步可以练习接口组合。例如除了基本的Cache接口你还可以定义MetricsCollector接口用于收集命中率和EvictionPolicy接口用于定义缓存淘汰策略。然后你可以创建一个InstrumentedCache结构体它内嵌embed了一个Cache实例同时实现了MetricsCollector接口。通过这种方式你就在不修改原有缓存实现的基础上为其添加了监控功能。这就是Go推崇的“组合优于继承”它比深层次的继承 hierarchy 更灵活、更清晰。空接口interface{}及其替代品也是一个重要知识点。虽然interface{}可以表示任何类型但滥用会导致类型安全和性能问题。练习应该引导开发者使用更精确的方案。例如需要处理多种类型的切片时可以考虑为每种类型实现相同的接口方法然后使用该接口的切片。或者在需要存储任意类型但以类型安全的方式取回时可以使用泛型GenericsGo 1.18。设计一个练习比如实现一个能存储任意类型、但能安全地按类型获取的容器先尝试用interface{}和类型断言实现再重构为使用泛型可以直观地对比两者的优劣和适用场景。3.3 错误处理与测试驱动开发Go的错误处理哲学是“错误就是值”这要求开发者必须仔细处理每个可能返回错误的操作。技能树中的练习应该强化这一点。错误包装与检视从Go 1.13开始引入了错误包装和errors.Is、errors.As函数。一个好的练习是模拟一个多层调用栈main - CallA - CallB - CallC在最深层的CallC返回一个自定义错误如ResourceNotFoundError。练习要求你在中间层用fmt.Errorf(“...%w”, err)包装这个错误并在最外层的main函数中使用errors.Is来判断错误链中是否包含特定的错误类型并使用errors.As来提取错误链中的具体错误值以获取更多上下文。这能让你掌握现代Go错误处理的标准方式。测试驱动开发TDD与表格驱动测试技能树项目本身就应该包含完善的测试这也是一个极佳的教学点。对于每个功能模块都可以先编写测试用例。Go的标准库testing非常强大特别是表格驱动测试非常适合测试多种输入输出组合的情况。例如测试一个字符串处理函数你可以定义一个结构体切片每个元素包含输入字符串、期望输出和测试用例名称。然后在测试函数中循环这个切片逐一验证。这样添加新的测试用例非常方便测试输出也清晰明了。Mock与依赖注入对于依赖外部服务如数据库、HTTP API的代码单元测试需要用到Mock。可以设计一个练习比如有一个UserService依赖一个UserRepository接口来存取数据。在测试UserService时你需要创建一个实现了UserRepository接口的Mock结构体可以手动创建也可以使用像gomock这样的库生成在Mock中预设返回值或验证调用参数。这个练习能让你理解如何通过接口来解耦依赖从而使代码更可测试。4. 综合实战构建一个微型REST API服务理论学习最终要落到项目上。在技能树项目中一个常见的综合练习是构建一个微型的REST API服务例如一个简单的待办事项Todo管理后端。这个项目虽小但五脏俱全能串联起众多技能点。4.1 项目初始化与结构设计首先使用go mod init初始化项目。一个清晰的项目结构对维护至关重要。可以参考如下布局todo-api/ ├── cmd/ │ └── server/ │ └── main.go # 应用入口 ├── internal/ # 私有应用代码 │ ├── handler/ # HTTP 处理器 │ ├── service/ # 业务逻辑层 │ ├── repository/ # 数据访问层接口定义 │ ├── model/ # 数据模型结构体 │ └── config/ # 配置读取 ├── pkg/ # 可公开的库代码如有 ├── storage/ # 数据存储实现 │ └── memory.go # 内存存储用于开发测试 ├── go.mod └── go.sum这种分层架构Handler - Service - Repository遵循了关注点分离原则。Handler负责处理HTTP请求和响应Service包含核心业务逻辑Repository负责数据持久化操作。各层之间通过接口通信这使得我们可以轻松替换存储层比如从内存存储切换到数据库而不影响上层业务逻辑。4.2 路由、中间件与请求处理在main.go中我们使用一个流行的Web框架例如Gin或Echo也可以从标准库net/http开始以理解原理。定义路由// 使用 Gin 框架示例 r : gin.Default() // 全局中间件日志、恢复 r.Use(gin.Logger(), gin.Recovery()) // 路由组 v1 : r.Group(/api/v1) { todos : v1.Group(/todos) { todos.GET(, handler.ListTodos) todos.POST(, handler.CreateTodo) todos.GET(/:id, handler.GetTodo) todos.PUT(/:id, handler.UpdateTodo) todos.DELETE(/:id, handler.DeleteTodo) } }中间件Middleware是Web框架的核心概念。你可以练习编写自己的中间件比如一个用于记录请求耗时的中间件func RequestDurationMiddleware() gin.HandlerFunc { return func(c *gin.Context) { start : time.Now() c.Next() // 处理请求 duration : time.Since(start) log.Printf(Request %s %s took %v, c.Request.Method, c.Request.URL.Path, duration) // 也可以将耗时设置到响应头中 c.Header(X-Request-Duration, duration.String()) } }在处理器Handler中你需要处理参数绑定、验证、调用服务层、生成响应。这里要特别注意错误处理。服务层返回的错误应该在Handler中被转换为合适的HTTP状态码和JSON错误信息体返回给客户端而不是直接panic。4.3 数据层与并发安全在Repository层我们首先定义一个接口package repository type TodoRepository interface { FindAll() ([]model.Todo, error) FindByID(id string) (*model.Todo, error) Create(todo *model.Todo) error Update(todo *model.Todo) error Delete(id string) error }初期我们可以实现一个基于内存Map的存储MemoryTodoRepository。这里就引出了一个关键问题并发安全。由于HTTP服务是并发处理请求的多个goroutine可能同时读写这个Map会导致竞态条件race condition。我们必须使用同步原语来保护它。package storage import sync type MemoryTodoStorage struct { mu sync.RWMutex // 读写锁 items map[string]model.Todo // 存储数据的map // ... 其他字段如自增ID } func (s *MemoryTodoStorage) FindByID(id string) (*model.Todo, error) { s.mu.RLock() // 读操作加读锁 defer s.mu.RUnlock() todo, exists : s.items[id] if !exists { return nil, ErrNotFound } return todo, nil } func (s *MemoryTodoStorage) Create(todo *model.Todo) error { s.mu.Lock() // 写操作加写锁 defer s.mu.Unlock() // 生成ID检查重复存储 s.items[todo.ID] *todo return nil }使用sync.RWMutex而不是普通的sync.Mutex是性能优化的一个细节。读多写少的场景下读写锁允许多个goroutine同时读提高了并发性能。4.4 配置管理与优雅关闭一个健壮的服务需要考虑配置管理和生命周期。配置如服务器端口、数据库连接字符串应该从环境变量或配置文件中读取而不是硬编码在代码里。可以使用viper库或者简单地从os.Getenv读取。优雅关闭Graceful Shutdown是生产级服务必备的特性。它确保在收到终止信号如SIGTERM时服务器能完成正在处理的请求再关闭连接和释放资源。func main() { router : setupRouter() srv : http.Server{ Addr: :8080, Handler: router, } // 在协程中启动服务器 go func() { if err : srv.ListenAndServe(); err ! nil err ! http.ErrServerClosed { log.Fatalf(listen: %s\n, err) } }() // 等待中断信号 quit : make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) -quit log.Println(Shutting down server...) // 创建一个5秒超时的上下文 ctx, cancel : context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err : srv.Shutdown(ctx); err ! nil { log.Fatal(Server forced to shutdown:, err) } log.Println(Server exiting) }这段代码创建了一个HTTP服务器并在一个单独的goroutine中运行它。主goroutine则监听操作系统的中断信号。当信号到来时它调用srv.Shutdown(ctx)。这个方法会停止接受新连接并等待所有正在处理的请求完成或直到上下文超时然后关闭服务器。这样就避免了强制关闭导致的请求中断和数据不一致。5. 性能剖析、调试与常见问题排查5.1 使用pprof进行性能剖析Go内置了强大的性能剖析工具pprof。在技能树项目中可以专门设置一个模块来练习如何使用它。首先在代码中导入net/http/pprof它会自动注册一系列HTTP端点如/debug/pprof/。然后你可以编写一段有性能问题的代码比如一个低效的字符串拼接循环或者一个有锁竞争的并发程序。运行程序并使用go tool pprof命令连接到你程序的pprof端点来采集和分析数据。CPU剖析go tool pprof http://localhost:8080/debug/pprof/profile。这会生成一个30秒的CPU使用情况快照并进入交互模式。你可以使用top命令查看最耗CPU的函数用list 函数名查看具体哪行代码消耗高。内存剖析go tool pprof http://localhost:8080/debug/pprof/heap。用于分析内存分配情况查找内存泄漏或过度分配的源头。inuse_space显示当前正在使用的内存alloc_space显示从程序启动开始的所有分配。Goroutine剖析go tool pprof http://localhost:8080/debug/pprof/goroutine。当怀疑有goroutine泄漏时即goroutine数量只增不减这个工具可以显示所有goroutine的堆栈跟踪帮你找到是哪里创建了它们却没有释放。通过实际运行剖析并解读火焰图你能直观地理解性能瓶颈所在这是优化代码不可或缺的技能。5.2 调试与常见并发问题排查Go的并发虽然强大但也容易引入隐蔽的Bug。技能树项目应该包含一些典型的“坑”及其排查方法。数据竞态Data Race这是最常见的并发问题。当两个以上的goroutine并发访问同一块内存且至少有一个是写操作时就会发生数据竞态。Go提供了竞态检测器在编译或运行时加上-race标志即可启用go run -race main.go或go test -race ./...。它会报告所有检测到的竞态访问及其堆栈信息。修复竞态通常意味着要使用通道或同步原语如sync.Mutex,sync.RWMutex,sync/atomic来保护共享数据。死锁Deadlock所有goroutine都在等待对方释放资源导致程序永久卡住。Go运行时在某些情况下能检测到死锁并panic例如所有的goroutine都锁住了。排查死锁需要仔细分析锁的获取顺序确保在所有goroutine中都是一致的避免循环等待。使用pprof查看所有goroutine的堆栈可以帮助你发现哪些goroutine在等待锁。通道阻塞导致的Goroutine泄漏一个goroutine因为试图从一个再也不会被写入的通道读取或向一个再也不会被读取的通道写入而永远阻塞。这会导致goroutine及其占用的内存无法被垃圾回收。排查方法是监控程序运行期间的goroutine数量可以通过pprof或runtime.NumGoroutine()如果数量持续异常增长就很可能存在泄漏。仔细检查通道的关闭逻辑和select语句中的default分支用于非阻塞操作是解决之道。Context使用不当context.Context用于传递截止时间、取消信号和请求域的值。一个常见错误是创建了context却没有传递或检查它。例如一个耗时的数据库查询如果没有接受context参数就无法被外部的取消信号中断。另一个错误是误用context.Background()和context.TODO()。前者通常用于main函数、初始化或测试中作为顶级context后者在不确定使用哪种context或暂时未确定时使用它是一个占位符提醒你后续需要替换成合适的context。5.3 依赖管理与构建优化随着项目增长依赖管理变得重要。Go Modules 现在是标准依赖管理工具。你需要熟悉go.mod和go.sum文件以及常用命令go get package添加依赖。go mod tidy整理模块移除未使用的依赖添加缺失的依赖。go mod vendor将依赖复制到项目下的vendor目录适用于需要完全离线构建或固定依赖版本的场景。构建优化可以通过添加-ldflags链接器参数来优化二进制文件。例如-s -w可以剔除调试信息显著减小二进制体积go build -ldflags-s -w -o myapp main.go。另外通过设置环境变量GOOS和GOARCH可以进行交叉编译比如在Linux上编译Windows可执行文件GOOSwindows GOARCHamd64 go build -o myapp.exe main.go。静态资源嵌入对于需要将模板、配置文件等资源打包进二进制文件的需求可以使用embed包Go 1.16。这是一个非常实用的特性它允许你在编译期将文件系统中的文件嵌入到程序中运行时直接访问。import _ embed //go:embed config.yaml var configData []byte // 或者嵌入整个目录 //go:embed static/* var staticFiles embed.FS掌握这些工具和技巧能让你更好地管理和交付Go项目从开发、调试到构建、部署形成一个完整的技能闭环。通过像cc-skills-golang这样的项目进行系统性练习将这些分散的知识点串联起来才能真正内化为你的开发能力。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

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> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…