当前位置: 首页 > news >正文

高效定位 Go 应用问题:Go 可观测性功能深度解析

作者:古琦

背景

自 2024 年 6 月 26 日,阿里云 ARMS 团队正式推出面向 Go 应用的可观测性监控功能以来,我们与程序语言及编译器团队携手并进,持续深耕技术优化与功能拓展。这一创新性的解决方案旨在为开发者提供更为全面、深入且高效的应用性能监控体验,助力企业在数字化转型中实现卓越的系统稳定性与性能表现。

从商业化版本的首次亮相至今,我们已历经五次重大版本迭代及若干次精细化的小版本更新。相较于初始版本,系统性能实现了翻倍提升,同时在功能层面亦展现出前所未有的丰富性与灵活性。新增特性包括但不限于智能化应用诊断、高度可定制的扩展能力、灵活的应用开关机制、接口全量采样以及代码热点分析等模块。这些功能的引入不仅显著提升了系统的实用性,也赢得了广大用户的广泛认可与积极反馈。而基于编译时插桩(Compile-time Instrumentation)的技术路径,更被实践证明是 Go 语言应用监控领域的一次突破性创举,堪称当前最优解。

为进一步赋能用户在复杂场景下快速定位与解决问题,我们结合近期发布的一系列全新功能,精心梳理了一套从接入到问题发现、再到问题排查与精准定位的最佳实践指南。

应用接入

通过 ARMS 提供的 Instgo 工具,只需要在 go build 前添加 instgo 命令,无需用修改一行代码,通过编译时插桩的方式实现监控能力注入[1]。

instgo go build {arg1} {arg2} {arg3}

智能告警

应用接入到 ARMS 后,可以在应用列表查看到应用的名称,点击进去查看到应用详情,包括了请求数、错误数、延迟等指标,还提供了每个接口的指标、以及依赖的接口指标,为了快速发现问题,可以通过配置应用的告警来第一时间发现问题。

可以创建对应的告警,如最近 1 分钟调用响应时间大于等于 500ms 就报警。

应用详情

通过监控告警第一时间发现问题后,到对应服务的详情查看这个接口的平均耗时非常长,即知道了告警是由于这个接口导致的。

查看对应的调用链,可以按耗时排列,找到耗时最长的调用链:

点击查看调用链详情,可以看到它的子 span 调用时间都非常短,可以确定是这个接口本身慢导致的,而不是其他对外请求导致的。

应用诊断

通过上述应用详情找到了请求慢的接口后,如何确认这时候的问题呢,我们可以通过应用诊断来发现问题,在应用监控中除了指标、链路、日志外,Profiling 的数据成为了应用监控的四大支柱之一。

通过 Profiling 数据能快速发现性能的瓶颈,ARMS Go 可观测提供了 CPU、内存、代码热点三个 Profiling 功能,用于快速发现应用性能问题。

ARMS 的持续剖析能力跟通过类似 https://github.com/grafana/pyroscope 或者 go 提供的 pprof 等工具相比,ARMS 提供的 Profiling 能力可以做到随开随关,通过应用设置-持续性能剖析设置即可进行开关设置,无需重启,直接生效。

CPU Profiling

CPU Profiling 用于收集和分析 Go 应用程序中的 CPU 使用情况,了解你的程序在运行时有多少时间花费在各个函数上。通过分析这些数据,开发者可以识别出程序中最耗费 CPU 时间的部分,ARMS 提供的 CPU Profiling 数据会采集每分钟的 CPU  运行情况,通过下面的火焰图即可找到当前执行时间最长的函数。

除了每分钟的数据之外,还提供了 CPU Profiling 数据的对比功能,对比前后 CPU 的消耗的不同,确定性能瓶颈。

内存 Profiling

跟 CPU Profiling 一样,内存 Profiling 也提供了对比的功能,可以对比前后不同时刻内存分配的情况,找到内存分配的热点。

除了通过内存 Profiling 找到内存分配热点外,还可以通过 Runtime 监控,找到每个时刻 Goroutines 数量、以及堆对象的数量来看某个时刻是否异常,是否因为流量突增导致的数量增加。

代码热点

在出现应用请求超时、响应慢的时候,为了快速定位到性能问题,从提供服务找到出现响应慢的接口,跳转到调用链,从调用链分析看出来对应接口在某些请求中响应的时间超出正常值很多,这时候如果还要进一步定位到这个请求执行过程中响应慢的函数是哪个,则无法通过单纯的调用链分析获取到,代码热点就是用来解决这个问题。点开对应的 Trace,通过放大镜即可查看当前的调用 Profiling[2]:

可以看到 main 中的 onCpu 函数消耗时间长达 0.62 秒,这样去排查这个函数的问题即可。

自定义扩展

通过上述方式可以查看到大部分问题,我们还提供了自定义扩展的功能[3],通过一个规则+一段待注入的代码组成,通过 Go Agent 的能力,在编译时完成代码的插桩,而不需要去修改原始代码,这个功能的优势是对于一些非项目开发人员可以在不修改原始代码的情况下完成相关功能实现。以下是我们经常会碰到的通过自定义扩展可以解决的问题:

日志打印

为了快速定位问题或者业务需求,日志可以记录非常详细的信息,比如函数的出入参数、Http 的返回的 body、sql 的请求语句参数等,以下是介绍打印 sql 请求的语句、参数:

第一步,创建 hook 文件夹,使用 go mod init hook 初始化该文件夹,然后新增下面的 hook.go 代码,它是即将注入的代码:

package hookimport ("database/sql""fmt""github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api"
)func sqlQueryOnEnter(call api.CallContext, db *sql.DB, query string, args ...interface{}) {fmt.Println("sql is ", query)fmt.Println("sql arg is", args)
}

第二步,编写测试 Demo。创建文件夹并使用 go mod init demo 初始化,然后添加 main.go

package mainimport ("context""database/sql""fmt"_ "github.com/go-sql-driver/mysql"
)func main() {mysqlDSN := "test:test@tcp(127.0.0.1:3306)/test"db, _ := sql.Open("mysql", mysqlDSN)db.ExecContext(context.Background(), `CREATE TABLE IF NOT EXISTS usersx (id char(255), name VARCHAR(255), age INTEGER)`)db.ExecContext(context.Background(), `INSERT INTO usersx (id, name, age) VALUE ( ?, ?, ?)`, "0", "foo", 10)maliciousAnd := "'foo' AND 1 = 1"injectedSql := fmt.Sprintf("SELECT * FROM userx WHERE id = '0' AND name = %s", maliciousAnd)db.Query(injectedSql, "abc")
}

第三步,在 Demo 文件夹下编写下面的 conf.json 配置,告诉工具我们想要将 hook 代码注入到 database/sql:😦*DB).Query()。

[{"ImportPath": "database/sql","Function": "Query","ReceiverType": "*DB","OnEnter": "sqlQueryOnEnter","Path": "/path/to/hook" # Path修改为hook代码的本地路径
}]

第四步,切换到 Demo 目录,使用 instgo 工具编译并执行程序,以验证 SQL 注入保护的效果。

$ ./instgo set --rule=./conf.json
$ docker run -d -p 3306:3306 -p 33060:33060 -e MYSQL_USER=test -e MYSQL_PASSWORD=test -e MYSQL_DATABASE=test -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:8.0.36
$ ./instgo go build .
$ ./demo

可以看到,使用 instgo 工具编译出的二进制文件成功检测到了潜在的 SQL 注入攻击,并打印出了相应日志:

sql is  SELECT * FROM userx WHERE id = '0' AND name = 'foo' AND 1 = 1
sql arg is [abc]

记录Span

ARMS 链路追踪记录的 span 信息都是对开源的 SDK 进行埋点获取的,用户在业务中如果有关心的函数需要记录可以通过自定义插件的功能,记录当前函数的 span。

第一步,创建 hook文件夹,使用 go mod init hook 初始化该文件夹,然后新增下面的 hook.go 代码,它是即将注入的代码:

package hookimport ("context""fmt""github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api""go.opentelemetry.io/otel""go.opentelemetry.io/otel/attribute"
)func requestDbOnEnter(call api.CallContext) {tracer := otel.GetTracerProvider().Tracer("")_, span := tracer.Start(context.Background(), "Client/User defined span")span.SetAttributes(attribute.String("client", "client-with-ot"))span.SetAttributes(attribute.Bool("user.defined", true))span.End()fmt.Println(span.SpanContext().SpanID().String())
}

第二步,编写测试 Demo。创建文件夹并使用 go mod init demo 初始化,然后添加 main.go

package mainimport ("demo/common"_ "github.com/go-sql-driver/mysql"_ "go.opentelemetry.io/otel"
)func main() {common.RequestDb()
}

common 文件夹下增加 common.go 如下:

package commonimport ("context""database/sql""fmt"_ "github.com/go-sql-driver/mysql"
)func RequestDb() {mysqlDSN := "test:test@tcp(127.0.0.1:3306)/test"db, _ := sql.Open("mysql", mysqlDSN)db.ExecContext(context.Background(), `CREATE TABLE IF NOT EXISTS usersx (id char(255), name VARCHAR(255), age INTEGER)`)db.ExecContext(context.Background(), `INSERT INTO usersx (id, name, age) VALUE ( ?, ?, ?)`, "0", "foo", 10)maliciousAnd := "'foo' AND 1 = 1"injectedSql := fmt.Sprintf("SELECT * FROM userx WHERE id = '0' AND name = %s", maliciousAnd)db.Query(injectedSql, "abc")
}

第三步,在 Demo文件夹下编写下面的 conf.json 配置,告诉工具我们想要将 hook 代码注入到 common/RequestDb()。

[{"ImportPath": "demo/common","Function": "RequestDb","ReceiverType": "","OnEnter": "requestDbOnEnter","Path": "/path/to/hook" # Path修改为hook代码的本地路径
}]

第四步,切换到 Demo 目录,使用 instgo 工具编译并执行程序,以验证 SQL 注入保护的效果。

$ ./instgo set --rule=./conf.json
$ docker run -d -p 3306:3306 -p 33060:33060 -e MYSQL_USER=test -e MYSQL_PASSWORD=test -e MYSQL_DATABASE=test -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:8.0.36
$ ./instgo go build .
$ ./demo

可以看到,使用 instgo 工具编译出的二进制文件成功创建了 span,并打印出了相应 trace spanId:

0000000000000000

如果上报 span 到服务端,则可以看到自定义的 span。

流量回放

除了简单的打印日志和创建 Span 外,还可以对生产的请求进行录制,用于开发和测试阶段回归,提高测试质量,减少线上故障,以下是介绍通过对 Http 的请求、返回进行记录,将这些数据可以记录到日志或者数据库中,用于下次测试回归。

第一步,创建 hook 文件夹,使用 go mod init hook 初始化该文件夹,然后新增下面的 hook.go 代码,它是即将注入的代码:

package hookimport ("encoding/json""fmt""github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api""io""net/http"
)func httpClientOnEnter(call api.CallContext, t *http.Transport, req *http.Request) {if req == nil {return}h, _ := json.Marshal(req.Header)fmt.Println("http request header is ", string(h))if req.GetBody == nil {return}requestBody, err := req.GetBody()if err != nil {return}defer requestBody.Close()requestData, err := io.ReadAll(requestBody)if err != nil {return}fmt.Println("http request body is ", string(requestData))
}

第二步,编写测试 Demo。创建文件夹并使用 go mod init demo 初始化,然后添加 main.go

package mainimport ("bytes""context""encoding/json""net/http""time""unicode"
)func hello(w http.ResponseWriter, r *http.Request) {_, err := w.Write([]byte("Hello Http!"))if err != nil {panic(err)}
}func setupHttp() {http.Handle("/http-service1", http.HandlerFunc(hello))err := http.ListenAndServe(":9114", nil)if err != nil {panic(err)}
}// 定义一个结构体用于构造 JSON 数据
type RequestBody struct {Name  string `json:"name"`Email string `json:"email"`
}func requestServer() {ctx := context.Background()reqBody := RequestBody{Name:  "Alice",Email: "alice@example.com",}// 将结构体序列化为 JSON 格式jsonData, err := json.Marshal(reqBody)if err != nil {return}req, err := http.NewRequestWithContext(ctx, "POST", "http://localhost:9114/http-service1", bytes.NewBuffer(jsonData))if err != nil {panic(err)}req.Header.Add("Content-Type", "application/json")req.Header.Add("test-key", "log")req.Header.Add("hello", "arms")client := &http.Client{}resp, err := client.Do(req)if err != nil {panic(err)}defer resp.Body.Close()
}func Is(s string) bool {for i := 0; i < len(s); i++ {if s[i] > unicode.MaxASCII {return false}}return true
}
func main() {go setupHttp()time.Sleep(3 * time.Second)requestServer()
}

第三步,在 Demo文件夹下编写下面的 conf.json 配置,告诉工具我们想要将 hook 代码注入到 net/http:😦*Transport).RoundTrip()。

[{"ImportPath": "net/http","Function": "RoundTrip","ReceiverType": "*Transport","OnEnter": "httpClientOnEnter","OnExit": "","Path": "/path/to/hook" # Path修改为hook代码的本地路径
}]

第四步,切换到 Demo 目录,使用 instgo 工具编译并执行程序,以验证 SQL 注入保护的效果。

$ ./instgo set --rule=./conf.json
$ ./instgo go build .
$ ./demo

可以看到,使用 instgo 工具编译出的二进制文件成功获取到了请求的 header 和 body,并打印出了相应日志:

http request header is  {"Content-Type":["application/json"],"Hello":["arms"],"Test-Key":["log"]}
http request body is  {"name":"Alice","email":"alice@example.com"}

通过自定义插件打印了日志,或者通过已有代码的日志也可以进行快速查看问题,我们提供了 TraceID 和 SpanID 关联到日志的能力[4]。

按需全采

针对一些重要的接口如果需要全采样,可以通过应用设置-采样设置配置接口名称,也可以通过前缀、后缀匹配来配置,这样这个接口的请求都会被采样到,避免被丢掉。

后续

为了进一步提升系统的可观测性与诊断能力,我们正致力于引入一系列高级性能分析工具,包括 Goroutine Profiling(协程剖析)、Mutex Profiling(互斥锁剖析)、Block Profiling(阻塞剖析)以及 Go Trace(Go语言运行轨迹追踪)。这些功能将为开发者提供更深入的洞察力,帮助他们在复杂的应用场景中精准定位性能瓶颈与潜在问题。

与此同时,我们将扩展对前沿技术的支持,特别是与大语言模型(LLM)相关的插件生态。例如,我们将集成 langchaingo 这一高效的语言处理框架,并引入 dify 的创新组件,如 dify-sandbox(沙盒环境)和 dify-plugin-daemon(插件守护进程),以满足开发者在多样化场景下的需求。

我们还计划推出一套在线调试工具,旨在为用户打造一个实时、交互式的问题诊断平台。通过这一平台,开发者可以快速定位并解决复杂问题,从而大幅缩短故障排查时间,提升系统的稳定性和可靠性。我们相信,这些能力的引入将为开发者带来前所未有的便捷体验,同时推动技术生态的进一步繁荣与发展。

最后诚邀大家试用我们的商业化产品,并加入我们的钉钉群(开源群:102565007776,商业化群:35568145) ,共同提升 Go 应用监控与服务治理能力。通过群策群力,我们相信能为 Golang开发者社区带来更加优质的云原生体验。

相关链接:

[1] instgo 工具介绍:

https://help.aliyun.com/zh/arms/application-monitoring/developer-reference/instgo-tool-introduction

[2] 代码热点:

https://help.aliyun.com/zh/arms/application-monitoring/user-guide/use-hotspot-code-to-diagnose-slow-calls-in-go-applications

[3] 自定义扩展:

https://help.aliyun.com/zh/arms/application-monitoring/use-cases/use-golang-agent-to-customize-scalability

[4] Go 应用日志 Trace 关联:

https://help.aliyun.com/zh/arms/application-monitoring/use-cases/associate-trace-ids-with-business-logs-for-a-go-application

相关文章:

高效定位 Go 应用问题:Go 可观测性功能深度解析

作者&#xff1a;古琦 背景 自 2024 年 6 月 26 日&#xff0c;阿里云 ARMS 团队正式推出面向 Go 应用的可观测性监控功能以来&#xff0c;我们与程序语言及编译器团队携手并进&#xff0c;持续深耕技术优化与功能拓展。这一创新性的解决方案旨在为开发者提供更为全面、深入且…...

emWin图片旋转

图片取模&#xff1a; //emwin6.16 //正常绘制 hMem0 GUI_MEMDEV_Create(0, 0, bmPHPH.XSize, bmPHPH.YSize); hMem1 GUI_MEMDEV_Create(0, 0, bmPHPH.XSize, bmPHPH.YSize); //正常绘制 hMem0 GUI_MEMDEV_CreateFixed32 (0,0, bmPHPH.XSize, bmPHPH.YSize); hMem1 GUI_M…...

CSS 父类元素的伪类 选择器

父元素的 :hover 状态可以影响子元素的样式。当父元素处于 :hover 状态时&#xff0c;可以通过 CSS 的选择器为子元素设置样式。 .parent:hover .child 这种选择器叫做 后代选择器&#xff08;Descendant Selector&#xff09; &#xff0c;结合了 :hover 伪类。它的作用是&…...

【Spring Boot 与 Spring Cloud 深度 Mape 之三】服务注册与发现:Nacos 核心实战与原理浅析

【Spring Boot 与 Spring Cloud 深度 Mape 之三】服务注册与发现&#xff1a;Nacos 核心实战与原理浅析 #SpringCloudAlibaba #Nacos #服务注册 #服务发现 #服务治理 #微服务 #SpringBoot #Java 系列衔接&#xff1a;在前两篇 [【深度 Mape 之一】 和 [【深度 Mape 之二】] 中…...

JS实现动态点图酷炫效果

实现目标 分析问题 整个图主要是用canvas实现&#xff0c;其中难点是将线的长度控制在一定范围内、并且透明度随长度变化。 前置知识 canvas绘制点、线、三角形、弧形 // 点ctx.moveTo(this.x, this.y);ctx.arc(this.x, this.y, this.r,0, 2 * Math.PI, false);ctx.fillStyle …...

使用ModbusRTU读取松下测高仪的高度

使用C#通过Modbus RTU读取松下测高仪高度 1. 准备工作 1.1 硬件连接 确保松下测高仪支持Modbus RTU协议(需查阅设备手册确认)。通过RS-485或RS-232接口连接设备与计算机,可能需要USB转串口适配器。确认通信参数(波特率、数据位、停止位、奇偶校验),常见设置为:9600波特…...

SQL Server从安装到入门一文掌握应用能力。

本篇文章主要讲解,SQL Server的安装教程及入门使用的基础知识,通过本篇文章你可以快速掌握SQL Server的建库、建表、增加、查询、删除、修改等基本数据库操作能力。 作者:任聪聪 日期:2025年3月31日 一、SQL Server 介绍: SQL Server 是微软旗下的一款主流且优质的数据库…...

Ubuntu上给AndroidStudio创建桌面图标

最近使用了Ubuntu开发了&#xff0c;默认的android studio没有桌面图标&#xff0c;还是很不方便&#xff0c;每次都要cd到bin目录启动studio.sh。 步骤1&#xff1a;cd /usr/share/applications linux系统里面&#xff0c;所有的应用启动入口都在 /usr/share/applications …...

HarmonyOS:ComposeTitleBar 组件自学指南

在日常的鸿蒙应用开发工作中&#xff0c;我们常常会面临构建美观且功能实用的用户界面的挑战。而标题栏作为应用界面的重要组成部分&#xff0c;它不仅承载着展示页面关键信息的重任&#xff0c;还能为用户提供便捷的操作入口。最近在参与的一个项目里&#xff0c;我就深深体会…...

C# System.Net.Dns 使用详解

总目录 前言 在网络编程中&#xff0c;域名系统&#xff08;DNS&#xff09;是互联网的核心组成部分之一&#xff0c;它将人类可读的域名转换为机器可用的IP地址。在.NET框架中&#xff0c;System.Net.Dns类提供了一组静态方法&#xff0c;用于执行与DNS相关的操作。本文将详细…...

Spring-事务属性

1.隔离属性 数据库对于隔离属性的支持 隔离属性的值MySQLOracle ISOLATION.READ_COMMITTED √ √ ISOLATION.REPEATABLE_READ√ISOLATION.SERIALIZABLE√√ Oracle不支持REPEATABLE_READ值 如何解决不可重复度 采用的多版本比对的方式 解决不可重复读 默认隔离属性 ISO…...

“上云入端” 浪潮云剑指组织智能化落地“最后一公里”

进入2025年&#xff0c;行业智能体正在成为数实融合的核心路径。2025年初DeepSeek开源大模型的横空出世&#xff0c;通过算法优化与架构创新&#xff0c;显著降低算力需求与部署成本&#xff0c;推动大模型向端侧和边缘侧延伸。其开源策略打破技术垄断&#xff0c;结合边缘计算…...

Docker 的实质作用是什么

Docker 的实质作用是什么 目录 Docker 的实质作用是什么**1. Docker 的实质作用****2. 为什么使用 Docker?****(1)解决环境一致性问题****(2)提升资源利用率****(3)简化部署与扩展****(4)加速开发与协作****3. 举例说明****总结**Docker 的实质是容器化平台,核心作用…...

WEB安全--文件上传漏洞--白名单绕过

一、MIME类型&#xff08;Content-Type&#xff09;绕过 原理&#xff1a;在我们不能绕过白名单后缀限制时&#xff0c;如果后端检测的是文件类型&#xff08;数据包中的Content-Type字段&#xff09;&#xff0c;那我们可以利用合法类型替换 示例&#xff1a;在上传,php后缀…...

Mac 本地化部署 dify

Macbook 本地化部署 dify 目录 Macbook 本地化部署 dify安装dockerdocker下载地址 安装dify下载dify到本地github可能遇到的问题: github打开超时在本地解压dify.zip文件本地化部署docker部署可能遇到的问题: 部署超时登录体验 dify 安装docker docker下载地址 根据电脑芯片选…...

MySQL和navicat日常使用记录

navicat界面上之前跟localhost连接的数据库可以直接点开了 这里有excel导入的地方 然后添加文件&#xff0c;选则文件是哪个&#xff0c;勾选excel的表是哪个&#xff0c;根据实际情况定义一些附加选项&#xff0c;注意时间格式&#xff0c;下一步下一步&#xff0c;然后选择主…...

linux进程信号 ─── linux第27课

在 Linux 系统中&#xff0c;信号&#xff08;Signals&#xff09; 是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;用于通知进程发生了某种事件或请求进程执行特定操作。 你怎么能识别信号呢&#xff1f;识别信号是内置的&#xff0c;进程识别信号&#xff0c;是…...

云安全之k8s未授权漏洞总结

一、k8s介绍 全称是 kubernetes&#xff0c;是谷歌在2014年推出的一种开源容器编排系统&#xff0c;后来捐赠给了云原生计算基金会&#xff08;CNCF&#xff09;。因将k后面的8个字母进行缩写后&#xff0c;被广泛简称为K8s。随着容器技术的发展&#xff0c;面临着容器数量庞大…...

博客学术汇测试报告

Author&#xff1a;MTingle major:人工智能 Build your hopes like a tower! 目录 一.项目简介 二.开发技术 三.测试用例设计 四.自动化测试代码 common包 博客编辑 博客列表 登录页面 未登录测试 主函数 五.性能测试 六.测试总结 一.项目简介 该项目是一款基于 S…...

揭秘:父子组件之间的传递

基础知识 组件与组件之间有三大方面的知识点&#xff1a; 子组件通过props defineProps&#xff08;{}&#xff09;接收父组件传递到参数和方法&#xff1b;子组件可以通过定义 emit 事件&#xff0c;向父组件发送事件&#xff1b;父组件调用子组件通过defineExpose 导出的方法…...

leetcode 169.Majority Element

这道题虽然简单&#xff0c;但适合用来练习各种解法。《剑指offer》5.2节 面试题29与此题一样&#xff0c;并且给出了leetcode官方题解未给出的快速选择的解法。 方法一、用哈希表解决 class Solution { public:int majorityElement(vector<int>& nums) {unordered…...

魔改chromium——基础环境搭建

谷歌chromium环境要求详细文档 软件和环境要求&#xff0c;必须安装&#xff0c;硬性要求 系统环境&#xff1a;Windows 10&#xff0c;内存最小8GB&#xff0c;推荐16GB&#xff0c;NTFS格式磁盘最少100GB空间Git版本&#xff1a;安装最新版本即可&#xff0c;Git桌面端下载…...

[网络_1] 因特网 | 三种交换 | 拥塞 | 差错 | 流量控制

目录 一、网络、互连网与因特网 二、因特网发展 三、因特网的组成与功能 四、计算机网络的分类 五、因特网的标准化与意义 一、三种传输方式&#xff1a;电路交换 vs 报文交换 vs 分组交换 1. 电路交换&#xff08;Circuit Switching&#xff09;——像“打电话” 2. 报…...

android 何如查找内网设备 IP

前沿 最近在与嵌入式设备打交道,需要对设备进行配网。发现 UpnP 服务不稳定,经常收不到设备的信息。就想着能不能通过内网查找到 IP 后,直接与设备通信,不停的请求设备信息。 1.Android 端通过 UDP 组播(Multicast)查找设备 如果嵌入式设备支持 UDP 组播,Android 端可…...

Oracle数据库数据编程SQL<3.5 PL/SQL 存储过程(Procedure)>

存储过程(Stored Procedure)是 Oracle 数据库中一组预编译的 PL/SQL 语句集合&#xff0c;存储在数据库中并可通过名称调用执行。它们是企业级数据库应用开发的核心组件。 目录 一、存储过程基础 1. 存储过程特点 2. 创建基本语法 3. 存储过程优点 4. 简单示例 二、没有…...

六级词汇量积累day13

commend 表扬 exhaust 耗尽&#xff0c;用尽 weary 疲惫的&#xff0c;劳累的 fatigue 疲惫&#xff0c;劳累 obese 臃肿的&#xff0c;肥胖的 adopt 采纳&#xff0c;收养 adapt 适应 accomplish 完成&#xff0c;实现 accomplishment 成就 achieve 实现&#xff0c;完成 achi…...

蓝桥杯15届JAVA_A组

将所有1x1转化为2x2 即1x1的方块➗4 然后计算平方数 记得-1 2 import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter;public class Main{static BufferedReader in new BufferedReader(new In…...

OpenCV图像输入输出模块imgcodecs(imwrite函数的用法)

《OpenCV计算机视觉开发实践&#xff1a;基于Python&#xff08;人工智能技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 3.2.3 imwrite保存图片 函数imwrite可以用来输出图像到文件&#xff0c;其声明如下&#xff1a; imwrite(filename,…...

win 远程 ubuntu 服务器 安装图形界面

远程结果&#xff1a;无法使用docker环境使用此方法 注意要写IP和:数字 在 ubuntu 服务器上安装如下&#xff1a; # 安装 sudo apt-get install tightvncserver # 卸载 sudo apt purge tightvncserver sudo apt autoremove#安装缺失的字体包&#xff1a; sudo apt update s…...

地下管线三维建模软件工具MagicPipe3D V3.6.1

经纬管网建模系统MagicPipe3D&#xff0c;基于二维矢量管线管点数据本地离线参数化构建地下管网三维模型&#xff08;包括管道、接头、附属设施等&#xff09;&#xff0c;输出标准3DTiles、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、…...

vue子组件生命周期的执行顺序

在 Vue 中&#xff0c;子组件的生命周期钩子函数的执行顺序受父组件的影响&#xff0c;通常遵循**“先创建子组件&#xff0c;后创建父组件&#xff1b;先销毁父组件&#xff0c;后销毁子组件”**的原则。 1. 组件创建&#xff08;挂载&#xff09;阶段 当父组件挂载时&#x…...

【含文档+PPT+源码】基于微信小程序的在线考试与选课教学辅助系统

项目介绍 本课程演示的是一款基于微信小程序的在线考试与选课教学辅助系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统…...

树莓派超全系列文档--(17)树莓派配置显示器

树莓派配置显示器 显示支持 HDMI 显示器设置分辨率和旋转手动设置分辨率和旋转确定显示设备名称设置自定义分辨率设置自定义旋转 控制台分辨率和旋转 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 显示 要配置 Raspberry Pi 使用非默认显示模式…...

python将pdf文件转为图片,如果pdf文件包含多页,将转化的多个图片通过垂直或者水平合并成一张图片

要将PDF文件转换为图片&#xff0c;并将多页PDF垂直合并成一张图片&#xff0c;可以使用PyMuPDF&#xff08;也称为fitz&#xff09;库来读取PDF文件&#xff0c;并使用Pillow库来处理和合并图片。以下是一个示例代码&#xff0c;展示了如何实现这个功能&#xff1a; 首先&…...

JVM基础原理

JVM是一个虚拟化的计算机&#xff0c;它可以执行Java字节码文件&#xff08;.class文件&#xff09;&#xff0c;实现Java程序跨平台的特性。JVM负责将Java程序的字节码翻译成具体操作系统的机器码&#xff0c;从而能够在不同的平台上运行。JVM的核心原理涉及以下几个重要方面 …...

Miniforge3高效管理 Python环境:2025年最新实践指南

Miniforge3 高效管理 Python 环境:2025 年最新实践指南 在现代开发中,灵活高效地管理 Python 环境至关重要。Miniforge3 作为一款轻量级 Conda 管理工具,不仅默认采用更新更快的 conda-forge 软件源,还对 ARM 架构(例如 Apple M1/M2/M3)有着出色的适配性。相比于传统的 …...

31天Python入门——第17天:初识面向对象

你好&#xff0c;我是安然无虞。 文章目录 面向对象编程1. 什么是面向对象2. 类(class)3. 类的实例关于self 4. 对象的初始化5. __str__6. 类之间的关系继承关系组合关系 7. 补充练习 面向对象编程 1. 什么是面向对象 面向对象编程是一种编程思想,它将现实世界的概念和关系映…...

困于环中的机器人

************* c topic: 1041. 困于环中的机器人 - 力扣&#xff08;LeetCode&#xff09; ************* Inspect the topic first. And it looks really familiar with another robot topic. 657. 机器人能否返回原点 - 力扣&#xff08;LeetCode&#xff09;https://lee…...

阿里 FunASR 开源中文语音识别大模型应用示例(准确率比faster-whisper高)

文章目录 Github官网简介模型安装非流式应用示例流式应用示例 Github https://github.com/modelscope/FunASR 官网 https://www.funasr.com/#/ 简介 FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端…...

spring boot前后端开发上传文件时报413(Request Entity Too Large)错误的可能原因及解决方案

可能原因及解决方案 1. Spring Boot默认文件大小限制 原因&#xff1a;Spring Boot默认单文件最大为1MB&#xff0c;总请求体限制为10MB。解决方案&#xff1a; 在application.properties中配置&#xff1a;spring.servlet.multipart.max-file-size10MB # 单文件最大 spring…...

Transformer:破局山地暴雨预测的「地形诅咒」--AI智能体开发与大语言模型的本地化部署、优化技术

极端降雨预测的技术痛点与边缘破局 1. 传统预警系统的三重瓶颈‌ ‌延迟致命‌&#xff1a;WRF模式在1km分辨率下3小时预报耗时>45分钟&#xff0c;错过山洪黄金响应期 ‌地形干扰大‌&#xff1a;复杂地形区&#xff08;如横断山脉&#xff09;降水预测误差超50% ‌数据…...

游戏引擎学习第187天

看起来观众解决了上次的bug 昨天遇到了一个相对困难的bug&#xff0c;可以说它相当棘手。刚开始的时候&#xff0c;没有立刻想到什么合适的解决办法&#xff0c;所以今天得从头开始&#xff0c;逐步验证之前的假设&#xff0c;收集足够的信息&#xff0c;逐一排查可能的原因&a…...

05-02-自考数据结构(20331)- 动态查找-知识点

自考数据结构动态查找算法主要讲二叉树和平衡二叉树,但是感觉到了,就又续接了一部分,所以这篇备考的小伙伴着重看前两种就可以了。 知识拓扑 知识点介绍 二叉排序树(BST) 定义 二叉排序树(Binary Search Tree)又称二叉查找树,它或者是一棵空树,或者是具有下列性质的二…...

PyQt6实例_批量下载pdf工具_使用pyinstaller与installForge打包成exe文件

目录 前置&#xff1a; 步骤&#xff1a; step one 准备好已开发完毕的项目代码 step two 安装pyinstaller step three 执行pyinstaller pdfdownload.py&#xff0c;获取初始.spec文件 step four 修改.spec文件&#xff0c;将data文件夹加入到打包程序中 step five 增加…...

NVR接入录像回放平台EasyCVR视频融合平台城市/乡镇污水处理厂解决方案

一、方案背景 随着经济的快速发展和城市化的加快&#xff0c;城市污水排放量急剧增加&#xff0c;给城市环境和粮食安全带来了威胁。因此&#xff0c;污水处理厂的建设和高效运营成为对城市环境保护的重要任务。 目前&#xff0c;国内许多城市虽已建成污水处理系统&#xff0…...

Vue2 vs Vue3 生命周期全面对比:created 的进化与革新!!!

&#x1f3af; Vue2 vs Vue3 生命周期全面对比&#xff1a;created 的进化与革新 &#x1f525; 核心差异全景图 一、钩子函数命名与定位变化 1. 命名规范革新 Vue2 钩子Vue3 钩子 (Options API)Vue3 Composition APIbeforeCreate❌ 无setup() 替代created✅ 保留setup() 替代…...

Ubuntu 22.04安装MongoDB:GLM4模型对话数据收集与微调教程

在Ubuntu 22.04安装MongoDB Community Edition的教程请点击下方链接进行参考&#xff1a; 点击这里获取MongoDB Community Edition安装教程 今天将为大家带来如何微调GLM4模型并连接数据库进行对话的教程。快跟着小编一起试试吧~ 1. 大模型 ChatGLM4 微调步骤 1.1 从 github…...

并查集(Union-Find Set)课程笔记

目录 1. 并查集原理 2. 并查集的实现 3. 并查集应用 应用 1&#xff1a;省份数量问题 应用 2&#xff1a;等式方程的可满足性 1. 并查集原理 并查集用于处理需要将不同元素划分成若干不相交集合的问题。最开始时&#xff0c;每个元素都是单独的一个集合&#xff0c;随后根…...

算法刷题记录——LeetCode篇(1.4) [第31~40题](持续更新)

更新时间&#xff1a;2025-03-29 算法题解目录汇总&#xff1a;算法刷题记录——题解目录汇总技术博客总目录&#xff1a;计算机技术系列博客——目录页 优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注&#xff01; 32. 最长有效括号 给你一个只包…...

【区块链安全 | 第十四篇】类型之值类型(一)

文章目录 值类型布尔值整数运算符取模运算指数运算 定点数地址&#xff08;Address&#xff09;类型转换地址成员balance 和 transfersendcall&#xff0c;delegatecall 和 staticcallcode 和 codehash 合约类型&#xff08;Contract Types&#xff09;固定大小字节数组&#x…...