掌握Go编程中的错误处理和日志记录

news2024/12/26 23:24:00

在这里插入图片描述

构建稳健可靠应用的全面指南

错误处理是编写可靠和稳健软件应用的重要方面。在任何编程语言中,错误是不可避免的,如何处理错误会极大地影响代码的质量和稳定性。在本文中,我们将探索Go中的错误处理世界,理解其重要性,错误值和类型的概念,以及程序员常遇到的常见错误场景。

错误处理简介

在软件开发领域,错误难以避免。无论是网络故障、文件未找到还是意外输入,您的程序都需要具备处理这种情况的能力。适当的错误处理确保应用程序为用户提供有意义的反馈,避免崩溃,并允许从意外事件中优雅地恢复。

在软件开发中处理错误的重要性

  1. 用户体验:当发生错误时,用户期望清晰且具有信息性的错误消息。优雅处理错误通过提供可理解的解释和指导如何继续提升用户体验。

  2. 稳定性:未处理的错误可能导致程序崩溃或意外行为,从而可能危及应用程序的稳定性。

  3. 调试:正确处理的错误为开发人员提供了有关出现问题的宝贵见解。这些信息对于调试和修复问题至关重要。

  4. 可维护性:有效处理错误的代码更容易维护和扩展。它对于变更更具弹性,不太容易引入新的错误。

日志记录基础知识

应用开发中日志记录的重要性

日志记录为您的应用程序的行为提供了见解,帮助您识别问题、监视性能并跟踪用户交互。它在诊断错误、理解应用程序流程和提高整体软件质量方面扮演着至关重要的角色。

不同的日志级别(信息,警告,错误,调试)

日志级别根据其严重程度对日志消息进行分类。常见的日志级别包括:

  • Info:一般信息消息。
  • Warning:关于潜在问题的警报,不会停止执行。
  • Error:报告影响应用程序功能的错误。
  • Debug:用于调试目的的详细信息,通常在生产中禁用。

Go中的错误值和错误类型概念

在Go中,错误使用error接口表示。这个接口只有一个方法,Error() string,用于返回描述错误的字符串。Go的简单和优雅体现在其错误处理方法中。与依赖异常或复杂的错误层次结构不同,Go使用简单的值和接口。

package main

import (
	"errors"
	"fmt"
)

func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("division by zero")
	}
	return a / b, nil
}

func main() {
	result, err := divide(10, 0)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Result:", result)
	}
}

编程中的常见错误场景

  1. 文件操作:在处理文件时,可能会出现由于找不到文件、权限问题或磁盘已满等情况而导致的错误。
  2. 网络操作:在与远程服务器或服务进行通信时,常见的网络错误包括连接超时或连接被拒绝。
  3. 用户输入:处理意外或无效的用户输入,例如表单中的格式错误,需要适当的错误处理。
  4. 资源枯竭:错误可能由于资源限制而产生,例如内存用尽或超出最大文件描述符。
  5. 并发:在并发程序中,竞争条件和同步问题可能导致错误。

错误检查:

错误检查是编程的一个重要方面,它确保您的代码能够优雅地处理意外情况并维护软件的可靠性。在本文中,我们将深入探讨错误检查的艺术,探讨有效管理代码中错误的技巧、模式和最佳实践。

使用条件语句来检查错误

条件语句在错误检查中扮演着关键角色。通过评估是否发生了错误,您可以决定如何在代码中继续。让我们来看一个基本的示例:

package main

import (
	"errors"
	"fmt"
)

func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("division by zero")
	}
	return a / b, nil
}

func main() {
	result, err := divide(10, 0)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Result:", result)
	}
}

在这个示例中,divide 函数在尝试除以零时返回一个错误。main 函数使用 if err != nil 模式来检查错误并根据需要作出响应。通过这样做,您的代码能够优雅地处理潜在的错误情况。

if err != nil 模式

if err != nil 模式是Go中常见的用于检查错误的做法。它允许您确定函数调用是否返回了一个错误值,并采取适当的措施。考虑涉及文件读取的另一个示例:

package main

import (
	"fmt"
	"io/ioutil"
)

func main() {
	data, err := ioutil.ReadFile("example.txt")
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	fmt.Println("File content:", string(data))
}

在这里,ioutil.ReadFile 函数返回文件内容和一个错误。通过使用 if err != nil 模式,您确保错误得到处理并报告。

处理不同的错误情况

当根据错误的性质处理不同的错误情况时,错误检查变得更加强大。考虑以下涉及网络连接的示例:

package main

import (
	"fmt"
	"net"
)

func main() {
	conn, err := net.Dial("tcp", "example.com:80")
	if err != nil {
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			fmt.Println("Timeout error:", netErr)
		} else {
			fmt.Println("Network error:", err)
		}
		return
	}
	defer conn.Close()
	fmt.Println("Connected successfully!")
}

在这种情况下,代码检查错误是否是 net.Error 类型,并且是否是超时错误,使用 .Timeout() 方法。区分错误类型允许您为每种情况提供特定的响应和处理。

延迟和恐慌

延迟(defer)和恐慌(panic)是Go中两种强大的机制,它们可以显著影响代码如何处理意外情况,并确保资源管理。在本文中,我们将探讨延迟、恐慌函数和恐慌-恢复机制的细节,以及有效利用它们的最佳实践。

用于清理的延迟语句

在Go中,defer 语句允许您安排在周围函数返回之前执行函数调用,无论是正常返回还是由于恐慌而返回。这个功能对于清理任务非常有价值,比如关闭文件或释放资源。

package main

import "fmt"

func main() {
	defer fmt.Println("Cleanup task executed")
	fmt.Println("Performing some work...")
}

在这个示例中,fmt.Println("Cleanup task executed") 语句被延迟执行,直到执行了 fmt.Println("Performing some work...") 语句。延迟任务确保清理操作发生在函数退出之前。

恐慌函数和恐慌-恢复机制

在Go中,panic 是一个内置函数,它停止程序的正常流程并引发恐慌。恐慌通常表示运行时错误,它会沿着调用堆栈传播,直到达到一个可以使用 recover 函数处理它的函数。

package main

import (
	"fmt"
)

func recoverFromPanic() {
	if r := recover(); r != nil {
		fmt.Println("Recovered from panic:", r)
	}
}

func main() {
	defer recoverFromPanic()

	panic("This is a panic!")
}

在这个示例中,recoverFromPanic 函数使用 recover 函数来捕获和处理恐慌。main 函数中的 panic 触发了恐慌,而 recoverFromPanic 函数从中恢复,允许程序继续执行。

何时使用 Panic 以及何时避免使用

Panic 应该保留用于不安全的特殊情况,其中继续执行可能会导致不安全的情况。它不适合常规错误处理。相反,对于处理预期错误,应使用错误值和 if err != nil 模式。

使用 panic 的情况包括:

  1. 遇到无法恢复的错误,例如损坏的数据文件或缺少关键组件。
  2. 想要发出开发人员的错误信号,比如使用未初始化的变量。
  3. 程序处于不一致状态,继续执行会导致不可预测的行为。

避免使用 panic 的情况包括:

  1. 处理预期错误,如用户输入验证或网络超时。对于这些情况,使用适当的错误处理技巧。
  2. 处理可恢复的错误,可以在不中断程序执行的情况下解决。
  3. 尝试处理正常的控制流或用户交互。在这些情况下使用 panic 会导致用户体验不佳。

错误包装和上下文

错误包装和上下文是错误处理中的高级技术,使您能够提供丰富和信息丰富的错误消息,从而更容易进行调试和理解错误。在本文中,我们将深入探讨Go中的错误包装和上下文,探讨如何向错误添加上下文,并利用 errors 包来增强错误处理。

使用 fmt.Errorf 向错误添加上下文

向错误添加上下文涉及提供有关错误发生环境的附加信息。fmt.Errorf 函数允许您用更多上下文包装现有的错误消息,从而创建更具信息性的错误。

package main

import (
	"errors"
	"fmt"
)

func main() {
	err := errors.New("original error")
	contextErr := fmt.Errorf("additional context: %w", err)
	fmt.Println(contextErr)
}

在这个示例中,fmt.Errorf 中的 %w 动词用于使用附加上下文包装原始错误。生成的错误消息包括原始错误和上下文。

使用 errors 包进行错误包装

errors 包在Go 1.13中引入,提供了更强大的错误处理功能。它包括用于创建和操作错误的函数,允许使用附加上下文甚至堆栈跟踪来进行错误包装。

package main

import (
	"errors"
	"fmt"
	"github.com/pkg/errors"
)

func fetchData() error {
	return errors.Wrap(errors.New("database connection error"), "fetching data failed")
}

func main() {
	err := fetchData()
	if err != nil {
		fmt.Println(err)
	}
}

在这个示例中,使用 errors.Wrap 函数来使用附加上下文包装现有错误。这将导致生成的错误消息包括原始错误消息以及 Wrap 函数提供的上下文。

创建详细的错误消息

详细的错误消息为开发人员提供了关于出了什么问题以及错误发生在哪里的关键信息。不要使用通用的消息,而是努力包括特定信息,例如函数名称、输入值和相关细节。

package main

import (
	"errors"
	"fmt"
)

func process(data []int) error {
	if len(data) == 0 {
		return errors.New("empty data slice")
	}
	return nil
}

func main() {
	data := []int{}
	err := process(data)
	if err != nil {
		fmt.Println("Error:", err)
	}
}

在这个示例中,错误消息 “empty data slice” 提供了对错误以及为什么发生错误的清晰理解。

使用 Go 中的 errors 包处理错误

在Go 1.13中引入的 errors 包通过提供一组强大的工具来增强错误消息的质量和清晰度,从而彻底改变了错误处理。在本文中,我们将探讨 errors 包的功能,重点关注其特点、包装和格式化错误的过程,以及如何提取有意义的错误消息和详细信息以进行有效的调试。

概述 errors 包的功能

errors 包通过以下功能丰富了Go中的错误处理:

  1. 包装错误:该包允许您使用附加上下文包装现有错误。这创建了一个错误链,保留了原始错误,并提供了有关错误发生的更多上下文。
  2. 格式化错误:通过使用类似 fmt.Printf 的格式化动词,您可以创建包括原始错误消息和添加的上下文的详细错误消息。
  3. 堆栈跟踪:使用 %+v 动词,该包可以生成带有错误消息的堆栈跟踪。这有助于确定错误的来源。
  4. 错误类型errors 包引入了 Errorf 函数,结合了 fmt.Errorferrors.New 的功能,使您能够轻松创建格式化的错误消息。

包装和格式化错误

errors 包中用于包装错误的主要函数是 fmt.Errorf。它结合了格式化功能和 %w 动词,用于包装错误并添加上下文。

package main

import (
	"fmt"
	"github.com/pkg/errors"
)

func main() {
	originalErr := errors.New("original error")
	wrappedErr := fmt.Errorf("additional context: %w", originalErr)
	fmt.Println(wrappedErr)
}

在这个示例中,wrappedErr 包含原始错误和添加的上下文,创建了一个有意义且信息丰富的错误消息。

提取错误消息和详细信息

要从使用 errors 包创建的错误中提取错误消息和详细信息,您可以使用 errors.Unwrap 函数来检索原始错误。

package main

import (
	"fmt"
	"github.com/pkg/errors"
)

func main() {
	originalErr := errors.New("original error")
	wrappedErr := fmt.Errorf("additional context: %w", originalErr)
	fmt.Println("Original error:", errors.Unwrap(wrappedErr))
	fmt.Println("Error details:", wrappedErr)
}

在这段代码中,errors.Unwrap 提取原始错误,允许您访问最初的错误消息。通过使用 %+v,还可以访问堆栈跟踪,有助于定位错误的来源。

Sentry 日志示例

错误监控和跟踪对于确保应用程序的可靠性和性能至关重要。Sentry 是一款强大的错误跟踪和监控平台,为捕获、分析和响应错误提供了无缝的解决方案。在本文中,我们将深入探讨错误监控的重要性,介绍 Sentry 作为综合错误跟踪平台,并突出使用 Sentry 记录错误的好处。

了解错误监控的重要性

错误监控是一项重要的实践,涉及积极监控应用程序中的错误和异常。通过早期识别错误并迅速响应,您可以防止用户感到沮丧,提高应用程序的稳定性,并优化用户体验。错误监控提供了有关应用程序健康状况的见解,使您能够主动解决问题并确保服务不中断。

Sentry 作为错误跟踪和监控平台的概述

Sentry 是一款领先的错误跟踪和监控平台,旨在帮助开发人员实时监控、识别和解决错误。它提供了一套全面的工具,使您能够捕获各种平台上的错误、分析错误数据并有效合作以解决问题。

使用 Sentry 记录错误的好处

  1. 实时错误捕获:Sentry 实时捕获错误,确保您在问题发生时立即收到警报。这种即时反馈使您能够迅速响应并防止长时间的停机。
  2. 详细的错误报告:Sentry 提供详细的错误报告,包括有关错误上下文、堆栈跟踪、用户信息等的信息。这些丰富的数据有助于快速诊断和解决问题。
  3. 跨平台支持:Sentry 支持多种编程语言和平台,包括 Go、JavaScript、Python 等。这种多功能性使其适用于具有多样技术堆栈的项目。
  4. 与框架和库的集成:Sentry 与流行的框架和库(如 Angular、React、Django 和 Flask)无缝集成。集成简单,增强了您的错误跟踪能力,无需大量努力。
  5. 问题管理和协作:Sentry 提供了问题管理、任务分配和与团队成员合作的功能。这个流程简化了高效的沟通和解决问题。
  6. 可自定义的警报:您可以设置自定义警报,以在发生特定错误时接收通知。这种主动的方法使您能够在影响用户之前解决问题。

记录错误到 Sentry:使用 Go 的示例

将 Sentry 集成到应用程序中以进行错误日志记录非常简单。以下是使用 Go 和 sentry-go 客户端库的示例:

package main

import (
	"fmt"
	"github.com/getsentry/sentry-go"
)

func main() {
	err := sentry.Init(sentry.ClientOptions{
		Dsn: "your-sentry-dsn",
	})
	if err != nil {
		fmt.Println("Sentry initialization failed:", err)
		return
	}
	defer sentry.Flush(2 * time.Second)

	// Simulate an error
	_, err = divide(10, 0)
	if err != nil {
		sentry.CaptureException(err)
	}
}

func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, fmt.Errorf("division by zero")
	}
	return a / b, nil
}

在这个示例中,应用程序使用提供的 DSN 初始化 Sentry,使用 sentry.CaptureException 捕获错误,并确保在程序退出之前将任何剩余的数据发送到 Sentry。

记录到文件

记录是应用程序开发中的一项基本实践,它使开发人员能够监视、排除故障和增强软件应用程序。在这份全面指南中,我们将介绍日志记录的重要性,介绍不同的日志级别,探讨Go中的日志记录库,并深入探讨日志记录到文件的细节。通过本文结束时,您将对有效的日志记录实践以及如何在Go应用程序中实现日志记录到文件有深刻的了解。

Go 中不同日志记录库的概述

Go 提供了各种日志记录库,每个库都满足不同的需求。一些热门的库包括 loglogruszerolog。选择正确的库取决于您的项目要求和所需的功能。

2. 使用 log

Go 中标准 log 包的概述

Go的标准库包括一个名为 log 的基本日志记录包。它提供了一种将日志消息输出到控制台的简单方法。

将日志消息记录到控制台

package main

import (
	"log"
)

func main() {
	log.Println("This is an info message")
	log.Printf("User %s logged in", "john_doe")
}

配置日志级别和输出

标准的 log 包没有内置的日志级别。然而,您可以根据需求使用条件语句来控制日志级别。

3. 使用第三方日志记录库

介绍热门的第三方日志记录库(logrus、zerolog)

第三方日志记录库提供了与标准 log 包相比更强大的功能。两个热门选择是 logruszerolog

安装和导入外部库

go get github.com/sirupsen/logrus
go get github.com/rs/zerolog
package main

import (
	"github.com/sirupsen/logrus"
	"github.com/rs/zerolog"
)

4. 高级日志记录功能

使用 JSON 输出的结构化日志

结构化日志将日志条目格式化为 JSON,使其更容易解析和分析。

向日志条目添加上下文和元数据

log.WithFields(log.Fields{
    "user":    "john_doe",
    "request": "GET /api/data",
}).Info("API request received")

自定义日志格式和输出目标

logruszerolog 都允许您自定义日志格式和输出目标。例如,您可以将日志输出到文件。

5. 记录到文件

将日志输出重定向到文件

logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
    log.Fatal("Error opening log file:", err)
}
log.SetOutput(logFile)

为更好的管理而切割轮询日志文件

使用像 lumberjackrotatelogs 这样的第三方库,您可以实现日志轮换以有效地管理日志文件。

实施基于文件的日志记录策略

您可以结合日志级别和日志轮换来创建有效的基于文件的日志记录策略,平衡存储使用和保留。

结论

在这份全面指南中,我们踏上了探索Go编程中错误处理、日志记录和监控领域的旅程。通过了解错误处理机制、利用高级日志记录技术,并与Sentry等错误跟踪平台集成,您将能够构建更具弹性、可维护和用户友好的应用程序。

处理错误不仅仅是应对意外问题,还涉及增强用户体验、保持应用程序稳定性和便于高效调试。通过认识到优雅地处理错误的重要性,您正在为稳健的软件开发打下坚实基础。

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

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

相关文章

修炼k8s+flink+hdfs+dlink(五:安装dockers,cri-docker,harbor仓库)

一:安装docker。(所有服务器都要安装) 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2添加软件源信息 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/cent…

通过商品链接查询淘宝商品详情数据,可以拿到商品标题,商品价格,商品库存,商品销量,商品sku数据等,淘宝API接口

通过商品链接查询淘宝商品详情数据可以参考以下步骤: 打开手机淘宝或者PC端,复制需要查询的商品链接。打开浏览器,输入商品链接,点击搜索。点击搜索结果中的商品链接,进入商品详情页面。点击鼠标右键,选择…

【前段基础入门之】=>CSS3新特性 3D 变换

导语 在上一章节中,我们分享了2D 变换的效果,也分享了一些案例,同时,既然有2D 变换,那么也就肯定有 3D 变换 那么本章节,就为大家带来有关3D 变换的分享. 文章目录 开启3D空间设置景深透视点位置3D 位移3D …

职场中,如何更高效地分析和解决问题(一)

要在职场取得成功,必须掌握多种技能。这些技能大致可分为三类: 一是职能性技能,二是分析和解决问题的技能,三是处理人际关系的技能。 无论在生活中还是工作中,我们都会面临各种问题,有些问题可能简单易处…

Avalonia 实现跨平台的视频聊天、屏幕分享(源码,支持Win、银河麒麟、统信UOS)

现在最火的.NET跨平台UI框架莫过于Avalonia了。Avalonia 基于.NET Core,因此它可以运行在任何支持.NET Core的平台上。之前基于CPF跨平台UI框架写过一个视频聊天的demo,而现在看来Avalonia是大势所趋,于是,我再写一个Avalonia版本…

TP5.1 导出excel文件

在 ThinkPHP 5.1 中引入 PHPExcel(现在已被官方弃用,推荐使用 PhpSpreadsheet)时,可以按照以下步骤进行操作: 在 composer.json 文件中添加 PHPExcel(PhpSpreadsheet)的依赖项。找到 require 部…

告别单调的列表页,探索JVS低代码列表页设计的新思路

列表页是什么? 列表页是管理平台中的基础页面,核心的逻辑是实现数据的增删改查(CRUD),列表页核心的几个要素:页面内容的数据展示、查询条件、页面按钮及按钮触发的逻辑。 列表页配置 具备应用配置权限的…

利用Python turtle绘制中国结附源码

一、中国结 01 平安喜乐 1)效果图 import turtle turtle.screensize(600,800) turtle.pensize(10) turtle.pencolor("red") turtle.seth(-45) turtle.fd(102) turtle.circle(-6,180) turtle.fd(102) turtle.circle(6,180) turtle.fd(102) turtle.circle(…

5、函数式编程--方法引用

目录 6. 方法引用6.1 推荐用法6.2 基本格式6.3 语法详解(了解)6.3.1 引用类的静态方法格式使用前提 6.3.2 引用对象的实例方法格式使用前提 6.3.4 引用类的实例方法格式使用前提 6.3.5 构造器引用格式使用前提 6. 方法引用 ​ 我们在使用lambda时,如果方法体中只有…

如何加入开源项目维护并提交代码?本地搭建源码阅读开发构建环境示例: kafka

如何加入开源项目维护并提交代码?本地搭建源码阅读开发构建环境示例: kafka。 大家对开源项目有兴趣、想成为committer,或者工作需要,会从github上获取最新的开源项目源码。本文做一个示例,怎样搭建本地的源码阅读、开发、构建环境。 首先,在github上找到项目的链接,…

OS 进程的描述与控制

目录 前趋图 程序执行 程序顺序执行 程序并发执行 进程 定义 进程控制块 PCB 进程实体 进程 特征 动态性 并发性 独立性 异步性 状态 3 种基本状态 就绪状态 执行状态 阻塞状态 3 种基本状态间的转换 其他状态 创建状态 终止状态 进程 5 种状态及其转换…

创建JUnit4 的TestBase类

Slf4j RunWith(SpringRunner.class) SpringBootTest(classes {TestApplication.class},webEnvironment SpringBootTest.WebEnvironment.RANDOM_PORT) public class TestBase { } 如图:

基于Bert模型的中文语义相似度匹配算法(离线模式)

1、准备中文离线模型 配置文件夹 文件获取方法: 访问官网:https://huggingface.co/bert-base-chinese/tree/main 下载以下文件 2、测试代码 # -*- coding: utf-8 -*- #pip install transformers -i https://mirrors.aliyun.com/pypi/simple/ #pip …

2023年中国机场建设标准、机场数量及机场系统投资完成情况分析[图]

机场,亦称飞机场、空港,较正式的名称是航空站。机场有不同的大小,除了跑道之外,机场通常还设有塔台、停机坪、航空客运站、维修厂等设施,并提供机场管制服务、空中交通管制等其他服务。 机场建设资质等级标准 资料来源…

当遇到修复错误0xc000000e时,你的电脑需要修复。如何在Windows 11/10上修复此错误

恢复错误代码0xc000000e,你的电脑需要修复,表示硬件故障或驱动器配置不正确,并可能伴随不同的错误消息,如: 所需设备未连接或无法访问 无法加载所选条目 由于应用程序丢失或损坏,无法加载所选条目 启动选择失败,因为无法访问所需的设备。 0xC000000E或STATUS_NO_SUCHDEV…

MBR20100CT-ASEMI肖特基MBR20100CT参数、规格、尺寸

编辑:ll MBR20100CT-ASEMI肖特基MBR20100CT参数、规格、尺寸 型号:MBR20100CT 品牌:ASEMI 芯片个数:2 封装:TO-220 恢复时间:>50ns 工作温度:-65C~175C 浪涌电流&#xff1a…

LeetCode //C++ - 427. Construct Quad Tree

427. Construct Quad Tree Given a n * n matrix grid of 0’s and 1’s only. We want to represent grid with a Quad-Tree. Return the root of the Quad-Tree representing grid. A Quad-Tree is a tree data structure in which each internal node has exactly four c…

2023年中国脱硫石膏产量、均价、综合利用量及市场规模分析[图]

脱硫石膏主要成分和天然石膏一样,为二水硫酸钙CaSO42H2O,含量≥93%。脱硫石膏是FGD过程的副产品,FGD过程是一项采用石灰-石灰石回收燃煤或油的烟气中的二氧化硫的技术,其中2022年中国脱硫石膏产量同比增长2.0%;综合利用…

[已解决]llegal target for variable annotation

llegal target for variable annotation 问题 变量注释的非法目标 思路 复制时编码错误,自己敲一遍后正常运行 #** 将垂直知识加入prompt,以使其准确回答 **# prompt_templates { # "recommand":"用户说:__INPUT__ …

上抖音热搜榜需要做哪些准备?

要想在抖音上获得高曝光,首先需要了解抖音热搜榜的算法和规则。抖音热搜榜的排名主要取决于作品的点赞数、评论数、分享数和播放量。其中,播放量是影响排名的关键因素。因此,在创作作品时,要注重提高作品的播放量。此外&#xff0…