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

Go错误与日志处理—推荐实践

错误的分类

在 Go 语言中,错误是通过实现 error 接口的类型表示的,但不同场景下的错误可以按性质和用途进行分类。以下是 Go 语言错误的常见分类,以及每类错误的解释和示例:


标准错误类型

标准库中定义了许多常见的错误类型,用于表示各种常见的错误场景。以下是一些 Go 标准库中常见的错误类型和相关包:

errors.Newfmt.Errorf

  • 用于创建自定义的错误。

  • 标准库提供的最基础的错误类型。

示例

import ( "errors" "fmt"
) err1 := errors.New("this is an error") 
err2 := fmt.Errorf("formatted error: %d", 42)

IO 相关错误

io

  • 包含基础 I/O 操作的错误类型。

常见错误

  • io.EOF:表示流结束(End Of File)。

  • io.ErrUnexpectedEOF:在读取流时遇到意外的 EOF。

  • io.ErrClosedPipe:操作已关闭的管道。

示例

import "io" 
if err == io.EOF { fmt.Println("Reached end of file") 
}

文件操作相关错误

os

  • 处理文件系统相关的错误。

常见错误

  • os.ErrNotExist:文件或目录不存在。

  • os.ErrExist:文件或目录已经存在。

  • os.ErrPermission:权限不足。

  • os.ErrInvalid:无效操作。

示例: 

import "os" if errors.Is(err, os.ErrNotExist) {fmt.Println("File does not exist") 
}

网络相关错误

net

  • 网络操作相关的错误。

常见错误

  • net.InvalidAddrError:无效地址错误。

  • net.UnknownNetworkError:未知网络类型错误。

  • net.AddrError:地址解析错误。

  • net.DNSError:域名解析错误。

示例

import "net"_, err := net.LookupHost("invalid_domain")
if dnsErr, ok := err.(*net.DNSError); ok {fmt.Println("DNS error:", dnsErr) 
}

 JSON 相关错误

encoding/json

  • JSON 编码和解码的错误。

常见错误

  • json.InvalidUnmarshalError:解码到无效的目标。

  • json.UnmarshalTypeError:JSON 与目标类型不匹配。

示例

import "encoding/json" var data interface{}
err := json.Unmarshal([]byte("invalid json"), &data) if syntaxErr, ok := err.(*json.SyntaxError); ok { fmt.Println("JSON Syntax Error at offset:", syntaxErr.Offset) 
}

HTTP 相关错误

net/http

  • HTTP 请求与响应相关的错误。

常见错误

  • http.ErrHandlerTimeout:HTTP 处理程序超时。

  • http.ErrBodyNotAllowed:HTTP 请求体不被允许。

示例

import "net/http" if errors.Is(err, http.ErrHandlerTimeout) { fmt.Println("HTTP handler timeout") 
}

时间解析相关错误

time

  • 处理时间解析或格式化错误。

常见错误

  • time.ErrBad:时间字符串格式错误。

示例

import "time"_, err := time.Parse("2006-01-02", "invalid-date")
if err != nil { fmt.Println("Time parsing error:", err) 
}

数据库相关错误

database/sql

  • 数据库操作相关的错误。

常见错误

  • sql.ErrNoRows:查询未返回结果。

  • sql.ErrTxDone:事务已完成,不能再执行操作。

示例

import "database/sql" if errors.Is(err, sql.ErrNoRows) { fmt.Println("No rows found") 
}

压缩解压相关错误

compress/gzip

  • 用于处理 gzip 格式的错误。

常见错误

  • gzip.ErrHeader:gzip 文件头错误。


加密解密相关错误

cryptocrypto/x509

  • 加密或证书解析相关错误。

常见错误

  • x509.IncorrectPasswordError:密码错误。

  • x509.UnknownAuthorityError:未知的证书颁发机构。


按错误来源分类

应用级错误

应用程序逻辑中定义的错误,如输入验证失败、业务规则不满足等。这些错误通常由程序员明确定义。

示例

type ValidationError struct { Field string Msg string 
} func (e ValidationError) Error() string { return fmt.Sprintf("validation failed on field %s: %s", e.Field, e.Msg) 
}

系统级错误

系统资源相关的错误,包括文件访问、网络问题等。 示例

func readConfig(filename string) error { _, err := os.ReadFile(filename) if err != nil {return fmt.Errorf("failed to read config: %w", err) } return nil 
}

第三方库错误

使用第三方库时返回的错误,需要通过文档或代码了解这些错误的含义,并采取适当措施。 示例

func sendMessageToKafka() error { err := producer.SendMessage(message) if err != nil { return fmt.Errorf("kafka producer error: %w", err) } return nil 
}

按错误处理方式分类

可恢复错误

可以通过重新尝试或特定逻辑处理恢复的错误。 示例

func retryOperation(attempts int) error { for i := 0; i < attempts; i++ {err := doSomething() if err == nil { return nil } time.Sleep(1 * time.Second) // 等待后重试 } return fmt.Errorf("operation failed after %d attempts", attempts) 
}

不可恢复错误

表示程序的逻辑或系统的严重错误,无法通过重新尝试解决,如非法状态、编程错误等。

示例

func mustDivide(a, b int) int { if b == 0 { panic("division by zero") } return a / b 
}


按错误语义分类

用户输入错误

用户提供的输入不满足预期导致的错误。

示例

func validateInput(input string) error { if input == "" {return fmt.Errorf("input cannot be empty") } return nil 
}

数据处理错误

数据格式、解析、转换等问题。

示例

func parseInt(value string) (int, error) { num, err := strconv.Atoi(value) if err != nil { return 0, fmt.Errorf("failed to parse integer: %w", err) } return num, nil 
}

网络/IO 错误

网络连接失败、超时、文件系统操作失败等问题。

示例

func fetchData(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { return nil, fmt.Errorf("failed to fetch data: %w", err) } defer resp.Body.Close() return io.ReadAll(resp.Body) }

业务逻辑错误

业务逻辑不满足需求导致的错误。

示例

func checkAccountBalance(balance, withdrawAmount float64) error { if withdrawAmount > balance { return fmt.Errorf("insufficient balance") } return nil 
}

按错误表现分类

明确错误

明确的错误通过 error 接口表示,并具有清晰的语义。

示例

return fmt.Errorf("unable to connect to database: %w", err)

模糊错误

返回的错误缺乏上下文信息,不利于调试。

示例

return errors.New("something went wrong") // 不清楚具体问题是什么

总结

Go 中的错误分类可以帮助开发者更清晰地理解错误的来源和性质,从而制定合理的处理策略。推荐:

  1. 使用明确的错误上下文。

  2. 尽量细化错误类型,尤其是应用级错误。

  3. 使用 errors.Iserrors.As 对错误进行分类处理。

  4. 在必要的场景下记录日志,但不要重复记录错误信息。


错误处理规范

错误检查与优先处理

  • 及时检查错误:不要忽略返回的错误值。

  • 优先处理错误:如果发生错误,尽快中止当前流程或采取修复措施。

好的示例:

func readFile(filename string) ([]byte, error) { data, err := os.ReadFile(filename) if err != nil { return nil, fmt.Errorf("failed to read file %s: %w", filename, err) } return data, nil 
}

坏的示例:

func readFile(filename string) ([]byte, error) { data, _ := os.ReadFile(filename) // 忽略错误,可能导致不可预见的问题 return data, nil 
}

使用错误包装提供上下文信息

  • 使用 fmt.Errorf%w 包装错误,保留错误链路。

  • 错误信息应清晰表明发生错误的上下文。

好的示例:

func processFile(filename string) error { file, err := os.Open(filename) if err != nil { return fmt.Errorf("failed to open file %s: %w", filename, err) } defer file.Close() // 文件处理逻辑... return nil 
}

坏的示例:

func processFile(filename string) error { _, err := os.Open(filename) if err != nil { return err // 丢失了错误上下文,难以追踪来源 } return nil 
}

自定义错误类型

  • 针对特定业务场景,创建自定义错误类型以提供丰富的上下文。

好的示例:

type ValidationError struct { Field string Message string 
} func (e ValidationError) Error() string { return fmt.Sprintf("validation failed on field %s: %s", e.Field, e.Message) 
} func validateInput(input string) error { if input == "" { return ValidationError{"input", "cannot be empty"} } return nil 
}

坏的示例:

func validateInput(input string) error { if input == "" { return fmt.Errorf("invalid input") // 错误信息缺乏上下文 } return nil 
}

使用 errors.Iserrors.As 检查错误

  • 使用 errors.Is 检查错误是否是某种特定类型。

  • 使用 errors.As 提取并处理特定的错误类型。

对比

特性errors.Iserrors.As
用途检查错误值是否相等或包装目标错误检查错误是否为特定类型
参数错误和目标错误值错误和目标错误类型的指针
返回值布尔值布尔值,目标指针可能会被赋值
支持链式错误
适用场景判断是否是某个特定错误判断是否属于某个特定类型的错误

好的示例:

func handleError(err error) { if errors.Is(err, os.ErrNotExist) { fmt.Println("文件不存在") } var pathErr *os.PathError if errors.As(err, &pathErr) { fmt.Printf("路径错误: %s\n", pathErr.Path) } 
}

避免滥用 panic,使用显式错误返回

  • panic 仅用于不可恢复的错误,普通错误应返回 error

  • 提供有意义的错误信息。

好的示例:

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

坏的示例:

func divide(a, b int) int { if b == 0 { panic("division by zero") // 滥用 panic,不建议用于常规错误处理 } return a / b 
}

日志与错误分离

  • 错误和日志分层:日志应由调用方处理,库函数仅返回错误。

  • 日志通常在服务层或调用者处理,库函数不应记录日志。

好的示例:

func fetchData(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { return nil, fmt.Errorf("failed to fetch data from %s: %w", url, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } return io.ReadAll(resp.Body) 
}

坏的示例:

func fetchData(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { log.Printf("error: %v", err) // 不必要的日志记录 return nil, err } defer resp.Body.Close() return io.ReadAll(resp.Body) 
}

使用 defer 简化资源清理

  • 使用 defer 保证资源在函数退出时被正确释放。

好的示例:

func processLargeFile(filename string) error { file, err := os.Open(filename) if err != nil { return fmt.Errorf("failed to open file: %w", err) } defer file.Close() // 确保资源释放 // 文件处理逻辑... return nil 
}

坏的示例:

func processLargeFile(filename string) error { file, err := os.Open(filename) if err != nil { return err } // 如果忘记关闭文件,会导致资源泄露 file.Close() return nil 
}

分层处理错误

  • 在业务逻辑层返回错误,允许调用方决定是否记录日志。

  • 在顶层捕获错误并进行统一处理。

好的实践:

// 库函数 
func queryDatabase(query string) ([]Record, error) { rows, err := db.Query(query) if err != nil { return nil, fmt.Errorf("database query failed: %w", err) } defer rows.Close() // 解析数据... return records, nil 
} // 应用层 
func handleRequest(query string) { records, err := queryDatabase(query) if err != nil { log.Printf("query error: %v", err) return } fmt.Println(records) 
}

错误与日志处理的推荐实践

不同层级对错误和日志的处理

数据访问层DAL/Repository)

职责:直接与数据库或其他持久化存储交互。

  • 错误处理

    • 返回具体的、易于处理的错误。例如:SQL 执行失败、数据未找到等。

    • 尽量使用错误包装 (fmt.Errorf),为上层提供上下文。

    • 不要记录日志,交由上层决定是否需要记录。

  • 示例

func GetUserByID(id int) (*User, error) { user := &User{} err := db.QueryRow("SELECT * FROM users WHERE id = ?", id).Scan(&user.ID, &user.Name) if errors.Is(err, sql.ErrNoRows) { return nil, fmt.Errorf("user with ID %d not found: %w", id, err) } if err != nil { return nil, fmt.Errorf("failed to fetch user: %w", err) } return user, nil 
}

服务层(Service/Use Case)

职责:实现业务逻辑。

  • 错误处理

    • 捕获底层错误并添加业务语义上下文。

    • 根据需要返回特定业务错误或通用错误。

    • 可对一些关键错误进行日志记录(如影响业务流程的错误)。

  • 日志记录

    • 记录错误可能对调试或审计有价值的信息。

    • 日志应包含业务上下文(如用户 ID、请求参数等)。

  • 示例

func ProcessOrder(orderID int) error { order, err := repo.GetOrderByID(orderID) if err != nil { return fmt.Errorf("failed to process order %d: %w", orderID, err) } if order.Status != "pending" { return fmt.Errorf("order %d is not in a pending state", orderID) } // 业务逻辑... return nil 
}

控制器层(Controller/Handler)

职责:处理用户请求并返回响应。

  • 错误处理

    • 将服务层的错误转换为用户友好的消息(HTTP 状态码或自定义响应)。

    • 不应暴露底层实现细节。

  • 日志记录

    • 在请求入口处记录重要的请求信息。

    • 在错误返回时记录错误上下文和请求相关信息。

  • 示例

func OrderHandler(w http.ResponseWriter, r *http.Request) { orderID, err := strconv.Atoi(r.URL.Query().Get("id")) if err != nil { http.Error(w, "invalid order ID", http.StatusBadRequest) return } err = service.ProcessOrder(orderID) if err != nil { log.Printf("failed to process order: %v", err) http.Error(w, "failed to process order", http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) 
}

错误与日志的推荐实践

错误返回层级

  1. 底层(如 DAL

    1. 返回详细的上下文错误,方便上层理解问题。

    2. 不记录日志,避免重复记录。

  2. 中间层(如 Service)

    1. 包装底层错误,提供业务相关的上下文。

    2. 根据需要选择是否记录关键日志。

  3. 顶层(如 Controller

    1. 转换错误为用户友好的消息。

    2. 记录完整的请求上下文和错误信息。


日志记录层级

  1. 入口点(Controller/Handler)

    1. 记录请求相关的信息(URL、参数、用户身份等)。

    2. 记录最终的响应状态。

  2. 服务层

    1. 记录对业务有重要影响的错误或状态变化。

  3. 数据层

    1. 尽量不记录日志,避免暴露内部实现细节。


常见反模式与改进

  1. 重复记录日志

    1. 底层记录错误,上层再次记录相同错误,导致日志冗余。

    2. 改进:仅在一个明确的层级记录日志。

  2. 暴露内部错误细节

    1. 直接将数据库错误返回到用户端。

    2. 改进:在顶层捕获并转换为用户友好的消息。

  3. 忽略日志上下文

    1. 日志中缺乏关键信息(如用户 ID、操作参数等)。

    2. 改进:在日志中包含足够的上下文信息。


总结

错误处理应遵循逐层封装的原则,每一层专注于自身职责,避免信息泄漏或日志冗余。日志记录应关注调试和审计价值,并在错误信息中添加业务或操作上下文,从而提高系统的可维护性和可观测性。

相关文章:

Go错误与日志处理—推荐实践

错误的分类 在 Go 语言中&#xff0c;错误是通过实现 error 接口的类型表示的&#xff0c;但不同场景下的错误可以按性质和用途进行分类。以下是 Go 语言错误的常见分类&#xff0c;以及每类错误的解释和示例&#xff1a; 标准错误类型 标准库中定义了许多常见的错误类型&…...

Android 13 Aosp Settings Android Studio版本

Android 13 Aosp Settings Android Studio版本 Settings相关源码 Settings https://android.googlesource.com/platform/packages/apps/Settings/+/refs/heads/android13-release SettingsIntelligence https://android.googlesource.com/platform/packages/apps/SettingsIn…...

Jedis存储一个以byte[]的形式的对象到Redis

1.1 准备一个User实体类 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.io.Serializable; import java.util.Date;Data NoArgsConstructor AllArgsConstructor public class User implements Serializable {private In…...

updatexml报错注入原理分析

《网络安全自学教程》 SQL注入时&#xff0c;经常利用updatexml()的报错特性来脱库。 updatexml报错原理 1、updatexml语法参数2、报错原理分析3、使用updatexml()脱库4、分割显示结果 updatexml() 的作用是修改xml文件的内容。 1、updatexml语法参数 updatexml(参数1&#x…...

蓝桥杯c++算法秒杀【6】之动态规划【上】(数字三角形、砝码称重(背包问题)、括号序列、组合数问题:::非常典型的必刷例题!!!)

下将以括号序列、组合数问题超级吧难的题为例子讲解动态规划 别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! ! &#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 动态规划 一、数字三角形 【问题描述】 上图给出了…...

【Qt】重写QComboBox下拉展示多列数据

需求 点击QComboBox时&#xff0c;下拉列表以多行多列的表格展示出来。 实现 直接上代码&#xff1a; #include <QComboBox> #include <QTableWidget> #include <QVBoxLayout> #include <QWidget> #include <QEvent> #include <QMouseEve…...

【mac】终端左边太长处理,自定义显示名称(terminal路径显示特别长)

1、打开终端 2、步骤 &#xff08;1&#xff09;修改~/.zshrc文件 nano ~/.zshrc&#xff08;2&#xff09;添加或修改PS1&#xff0c;我是自定义了名字为“macminiPro” export PS1"macminiPro$ "&#xff08;3&#xff09;使用 nano: Ctrl o &#xff08;字母…...

基于Springboot的流浪宠物管理系统

基于javaweb的流浪宠物管理系统 介绍 基于javaweb的流浪宠物管理系统的设计与实现&#xff0c;后端框架使用Springbootmybatis&#xff0c;前端框架使用Vuehrml&#xff0c;数据库使用mysql&#xff0c;使用B/S架构实现前台用户系统和后台管理员系统&#xff0c;和不同权限级别…...

web博客系统的自动化测试

目录 前言测试用例编写自动化脚本测试准备博客登录页相关测试用例登陆成功登录失败 博客首页相关测试用例登陆成功登录失败 博客详情页相关测试用例登录成功登录失败 博客编辑页相关测试用例登陆成功登录失败 编写测试文档测试类型内容 前言 本次测试是运用个人写的一个博客系…...

【论文阅读】Multi-level Semantic Feature Augmentation for One-shot Learning

用于单样本学习的多层语义特征增强 引用&#xff1a;Chen, Zitian, et al. “Multi-level semantic feature augmentation for one-shot learning.” IEEE Transactions on Image Processing 28.9 (2019): 4594-4605. 论文地址&#xff1a;下载地址 论文代码&#xff1a;https:…...

网络知识面试

1、http状态码 101: 切换请求协议 200:(请求成功)。服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 301 : (永久移动,永久性重定向,会缓存) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。…...

图片预览 图片上传到服务器

首先要明白 理解 multipart/form-data&#xff1a;‌multipart/form-data是一种在HTTP请求中使用的MIME类型&#xff0c;主要用于在客户端和服务器之间传输包含文件或二进制数据的表单数据。它通过一个边界&#xff08;boundary&#xff09;来分隔不同的表单字段和文件数据‌。…...

前端:base64的作用

背景 项目中发现&#xff0c;img标签中写src&#xff0c;读取一个png图片&#xff0c;只有16kb&#xff0c;速度特别慢。 解决办法&#xff0c;将图片转为base64&#xff0c;然后读取&#xff0c;速度特别快17ms就解决。 定义&#xff1a;base64是一种基于64个可打印字符(A-…...

Django在fitler过滤不等于的条件

提问 django 在API接口fitler的时候如何过滤 category 不等于6的 解答 为了在AoYuStudentFilter中设置过滤category不等于6的条件&#xff0c;需要使用django_filters库中的exclude方法。不过直接在FilterSet中使用exclude可能不那么直观&#xff0c;因为FilterSet主要设计用…...

Spring Boot英语知识分享网站:技术与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

京准电钟:NTP网络校时服务器从入门到精准

京准电钟&#xff1a;NTP网络校时服务器从入门到精准 京准电钟&#xff1a;NTP网络校时服务器从入门到精准 1.前言 由计算机网络系统组成的分布式系统&#xff0c;若想协调一致进行&#xff1a;IT行业的“整点开拍”、“秒杀”、“Leader选举”&#xff0c;通信行业的“同步…...

C++趣味编程玩转物联网:用树莓派Pico控制四位数码管

数码管是一种常用的数字显示器件&#xff0c;广泛应用于电子时钟、记分牌和智能设备显示界面。在本项目中&#xff0c;我们将通过树莓派Pico板控制一个四位数码管模块&#xff0c;展示从 0000 到 9999 的数字动态显示。这不仅是一次硬件和软件结合的实践&#xff0c;还可以帮助…...

DRM(数字权限管理技术)防截屏录屏----视频转hls流加密、web解密播放

提示&#xff1a;视频转hls流加密、web解密播放 需求&#xff1a;研究视频截屏时&#xff0c;播放器变黑&#xff0c;所以先研究的视频转hls流加密 文章目录 [TOC](文章目录) 前言一、工具ffmpeg、openssl二、后端nodeexpress三、web播放四、文档总结 前言 ‌HLS流媒体协议‌&a…...

实验三 z变换及离散时间LTI系统的z域分析

实验原理 有理函数z 变换的部分分式展开 【实例2-1】试用Matlab 命令对函数 X ( z ) 18 18 3 − 1 − 4 z − 2 − z − 3 X\left(z\right)\frac{18}{183^{-1} -4z^{-2} -z^{-3} } X(z)183−1−4z−2−z−318​ 进行部分分式展开&#xff0c;并求出其z 反变换。 B[18]; A…...

Python中的DrissionPage详解

文章目录 Python中的DrissionPage详解一、引言二、DrissionPage的基本使用1、安装与启动2、元素定位与操作 三、高级功能1、截图功能2、数据提取3、与其他库的集成 四、具体使用示例五、总结 Python中的DrissionPage详解 一、引言 DrissionPage是一个强大的Python库&#xff…...

python除了熟悉的pandas,openpyxl库也很方便的支持编辑Excel表

excel表格是大家经常用到的文件格式&#xff0c;各行各业都会跟它打交道。之前文章我们介绍了使用openpyxl和xlrd库读取excel表数据&#xff0c;使用xlwt库创建和编辑excel表&#xff0c;在办公自动化方面可以方便我们快速处理数据&#xff0c;帮助我们提升效率。 python之open…...

go语言怎么实现bash cmd里的mv功能?

在Go语言中实现类似于Bash命令行中的mv命令的功能&#xff0c;主要是通过文件系统的操作来完成的。mv命令可以用来移动文件或目录&#xff0c;也可以用来重命名文件或目录。在Go语言中&#xff0c;可以使用标准库中的os和io/ioutil包来实现这些功能。 以下是一个简单的例子&…...

Vue前端面试进阶(五)

使用Element UI开发的实际项目 在实际项目中&#xff0c;我使用Element UI来快速构建用户界面。Element UI是一套为开发者、设计师和产品经理准备的基于Vue 2.0的桌面端组件库&#xff0c;它提供了丰富的UI组件&#xff0c;极大地提高了开发效率。然而&#xff0c;在使用过程中…...

面试手撕题积累

1、实现滑动窗口限流&#xff0c;允许每分钟最多有100个请求 阿里一面题。 核心&#xff1a; 时间窗口管理&#xff1a;滑动窗口会根据时间流逝不断更新&#xff0c;需要记录请求的时间戳&#xff0c;并根据当前时间计算窗口内的请求数量。 限流判断&#xff1a;每次请求到来…...

notepad++文件github下载

1、github下载网址&#xff1a;Releases notepad-plus-plus/notepad-plus-plus GitHub 2、找到操作系统支持的软件&#xff1a; 3、CSDN下载链接&#xff1a;https://download.csdn.net/download/u013083576/90046203...

.NET新知识点笔记

using 用法介绍 using (SqlCommand cmd new SqlCommand(SQLString, connection)) 为什么使用上面的using 而不直接使用下述的来直接 SqlCommand cmd new SqlCommand(SQLString, connection&#xff09;如果你需要使用一个对象&#xff0c;这个对象需要占用很多紧缺的资源&am…...

数据结构:链表进阶

链表进阶 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3.链表面试题4.LinkedList的使用5.1 什么是LinkedList4.2 LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 通过源码知道&#xff0c;ArrayList底层使用数组来存储元素&#xff1…...

Python 爬虫入门教程:从零构建你的第一个网络爬虫

网络爬虫是一种自动化程序&#xff0c;用于从网站抓取数据。Python 凭借其丰富的库和简单的语法&#xff0c;是构建网络爬虫的理想语言。本文将带你从零开始学习 Python 爬虫的基本知识&#xff0c;并实现一个简单的爬虫项目。 1. 什么是网络爬虫&#xff1f; 网络爬虫&#x…...

Java面试题、八股文——JVM篇最终篇

1.如何选择垃圾收集器&#xff1f; 选择合适的垃圾收集器&#xff08;Garbage Collector, GC&#xff09;对于优化Java应用程序的性能至关重要。不同的应用场景和系统需求可能需要不同类型的垃圾收集器来满足。以下是一些考虑因素以及常见的垃圾收集器选项&#xff0c;帮助您做…...

Spring Boot整合Redis Stack构建本地向量数据库相似性查询

Spring Boot整合Redis Stack构建本地向量数据库相似性查询 在微服务架构中&#xff0c;数据的高效存储与快速查询是至关重要的。Redis作为一个高性能的内存数据结构存储系统&#xff0c;不仅可以用作缓存、消息代理&#xff0c;还可以扩展为向量数据库&#xff0c;实现高效的相…...

五莲网站建设公司/山东免费网络推广工具

2019独角兽企业重金招聘Python工程师标准>>> 1、在index.php添加调试的配置为true&#xff0c;否则配置修改后不能立即生效 define (APP_DEBUG, true ); 2、通用的配置文件放在 Application/Common/Conf下面 3、修改config.php,配置数据库类型&#xff0c;否则报错:…...

做网站什么分类流量多/西安seo王尘宇

axios用多了就开始疑惑它里面到底是个啥&#xff0c;虽然总被告知它就是基于ajax的封装&#xff0c;但掐指一算&#xff0c;事情应该没这么简单&#xff0c;于是开始深挖&#xff0c;挖着挖着就挖到了Promise。毕竟axios的官方描述是这样的&#xff1a;Promise based HTTP clie…...

相亲网站做推广的照片是谁/培训机构需要哪些证件

一.概述 linux中不区分进程和线程,都认为是个任务,都是创建一个task_struct.如何区分?线程是共享相同地址空间,而进程是独占地址空间. 多线程共享同一进程的地址空间 优点: 通信方便,可以通过全局变量. 缺点: 访问共享数据时需要考虑同步和互斥. 二.线程共享资源: 可执行的指令…...

无锡企业做网站/接app推广

一、正常流程下的拦截器&#xff08;全部放行&#xff09; 1.springMVC中拦截器实现这个接口HandlerInterceptor 第一个拦截器 HandlerInterceptor1 public class HandlerInterceptor1 implements HandlerInterceptor {//进入 Handler方法之前执行//用于身份认证、身份授权//比…...

一级a做爰片免费网站录像/关键词优化需要从哪些方面开展

题目传送门 1 /*2 二分搜索&#xff1a;式子两边取对数&#xff0c;将x提出来&#xff0c;那么另一边就是一个常数了&#xff0c;函数是&#xff1a;lnx/x。二分搜索x&#xff0c;注意要两次 3 */4 #include <cstdio>5 #include <algorithm>6 #include <cma…...

ssh架构jsp网站开发/小程序推广50个方法

转自&#xff1a;超定方程组最优解&#xff08;最小二乘解&#xff09;推导 --------------------------------------------------------------------------------------------------------- 扩展阅读 &#xff08;1&#xff09;最小二乘以及最小二乘求解超定方程组最优解的推…...