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

【go语言规范】 使用函数式选项 Functional Options 模式处理可选配置

如何处理可选配置?

  1. Config Struct 方式 (config-struct/main.go)
    这是最简单的方式,使用一个配置结构体:
  • 定义了一个简单的 Config 结构体,包含 Port 字段
  • 创建服务器时直接传入配置对象
  • 优点:简单直接
  • 缺点:不够灵活,所有字段都必须设置值,即使只想修改其中一个
  1. Builder 模式 (builder/main.go)
    使用建造者模式:
  • 定义 ConfigBuilder 结构体来构建配置
  • 提供链式调用方法如 Port()
  • 通过 Build() 方法验证并生成最终配置
  • 优点:支持链式调用,可以进行参数验证
  • 缺点:需要编写较多样板代码
  1. 函数选项模式 (functional-options/main.go)
    这是最灵活的方式:
  • 定义 Option 函数类型用于修改配置
  • 使用 WithXXX 函数创建配置选项
  • 支持默认值和参数验证
  • 可以方便地添加新的配置项
  • 使用示例:
NewServer("localhost", WithPort(8080))

详细代码转载go语言经典100错

package mainimport ("errors""net/http"
)// 默认HTTP服务端口
const defaultHTTPPort = 8080// options 结构体用于存储所有配置选项
type options struct {port *int // 使用指针以区分是否设置了端口
}// Option 定义了功能选项的函数类型
// 每个选项都是一个函数,接收 options 指针并返回错误
type Option func(options *options) error// WithPort 创建一个设置端口的选项
// 这是一个工厂函数,返回一个闭包
// 闭包可以访问外部函数 WithPort 中的 port 参数
func WithPort(port int) Option {// 这里返回的匿名函数就是一个闭包// 它可以访问并持有外部函数 WithPort 的 port 参数// 即使 WithPort 函数执行完毕,返回的闭包仍然可以访问 port 值return func(options *options) error {if port < 0 {return errors.New("port should be positive")}options.port = &portreturn nil}
}// NewServer 创建一个新的 HTTP 服务器
// addr: 服务器地址
// opts: 可变参数,包含所有功能选项
func NewServer(addr string, opts ...Option) (*http.Server, error) {// 创建选项实例var options options// 应用所有选项for _, opt := range opts {err := opt(&options)if err != nil {return nil, err}}// 确定最终使用的端口var port intif options.port == nil {// 未设置端口,使用默认值port = defaultHTTPPort} else {if *options.port == 0 {// 端口为0,使用随机端口port = randomPort()} else {// 使用指定的端口port = *options.port}}_ = portreturn nil, nil
}// client 展示如何使用功能选项模式
func client() {_, _ = NewServer("localhost", WithPort(8080))
}// randomPort 返回一个随机端口号
// 注:这是一个示例实现,实际应用中应该使用真正的随机端口生成方法
func randomPort() int {return 4 // 通过掷骰子选择的,保证随机(开玩笑的)
}

函数选项模式的优势:

  1. 支持默认值
  2. 参数可选
  3. 易于扩展
  4. 支持参数验证
  5. API 使用简洁

这是 Go 语言中最推荐的配置模式之一,特别适合那些有很多可选配置项的情况。


在k8s 源码中,可以找到如下例子使用了 functional-options方法

Kubernetes 源码中大量使用了 Functional Options 模式,我来展示一个典型的例子:

ClientSet 的创建

// NewForConfig creates a new Clientset for the given config.
func NewForConfig(c *rest.Config) (*Clientset, error) {configShallowCopy := *cif configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)}var cs Clientset// ... 其他代码return &cs, nil
}// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {cs, err := NewForConfig(c)if err != nil {panic(err)}return cs
}

RESTClient 的选项模式

// RESTClientFor returns a RESTClient that satisfies the requested attributes on a client Config object.
func RESTClientFor(config *Config) (*RESTClient, error) {// ...existing code...return NewRESTClient(config.Host,config.APIPath,config.ContentConfig,config.QPS,config.Burst,config.RateLimiter,config.WrapTransport,)
}

Informer 的创建选项

// SharedInformerOption defines the functional option type for SharedInformerFactory.
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory// WithCustomResyncConfig sets a custom resync period for the specified informer types.
func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption {return func(factory *sharedInformerFactory) *sharedInformerFactory {for obj, resyncPeriod := range resyncConfig {factory.customResync[obj] = resyncPeriod}return factory}
}// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory.
func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption {return func(factory *sharedInformerFactory) *sharedInformerFactory {factory.tweakListOptions = tweakListOptionsreturn factory}
}// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
func NewSharedInformerFactoryWithOptions(client kubernetes.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {factory := &sharedInformerFactory{client:           client,namespace:        v1.NamespaceAll,defaultResync:    defaultResync,informers:        make(map[reflect.Type]cache.SharedIndexInformer),startedInformers: make(map[reflect.Type]bool),customResync:     make(map[reflect.Type]time.Duration),}// 应用所有选项for _, opt := range options {factory = opt(factory)}return factory
}

这些例子展示了 Kubernetes 如何使用 Functional Options 模式来:

  1. 灵活配置

    • 客户端配置
    • 资源监控器配置
    • REST 客户端选项
  2. 默认值处理

    • 速率限制
    • 同步周期
    • API 路径
  3. 可扩展性

    • 自定义选项
    • 可选功能
    • 行为修改

这种模式在 Kubernetes 中广泛使用,因为它:

  • 提供了良好的 API 扩展性
  • 保持了向后兼容性
  • 使配置更加灵活
  • 代码更易于维护和测试

Function Options 模式与接口定义的区别

你提出了一个很好的问题。让我们来分析一下:

接口与 Function Options 的不同点

  1. 接口定义的原则
// 接口应该在使用处定义
type userRepository interface {Save(user User) errorFind(id string) (*User, error)
}type UserService struct {repo userRepository  // 在使用处定义接口
}
  1. Function Options 的特点
// 选项定义在包的实现端
type Option func(*options) errorfunc WithPort(port int) Option {return func(o *options) error {o.port = &portreturn nil}
}

为什么 Function Options 不需要在客户端定义

  1. 不是抽象依赖

    • Function Options 是配置模式,不是依赖抽象
    • 它是实现细节的一部分,不是接口契约
  2. 封装性

// 实现包中
type options struct {port    *int    // 私有字段timeout *time.Duration
}// 客户端使用
server, _ := NewServer("localhost", WithPort(8080),WithTimeout(5 * time.Second),
)
  1. API 稳定性
    • 选项函数提供了稳定的公共 API
    • 内部 options 结构体可以随时更改而不影响客户端

实际例子

// 服务端定义(正确的方式)
package servertype Option func(*options) errorfunc WithPort(port int) Option { ... }
func WithTimeout(t time.Duration) Option { ... }// 客户端使用(简洁清晰)
package clientfunc main() {server.NewServer("localhost",server.WithPort(8080),server.WithTimeout(5 * time.Second),)
}

总结

  • 接口定义在使用处是为了依赖抽象
  • Function Options 定义在实现处是为了配置灵活性
  • 两者解决的是不同的问题:
    • 接口:依赖反转
    • Options:配置管理

Go Functional Options 模式与 Java 构建器模式的对比

Java 构建器模式

public class Server {private final String addr;private final int port;private final int timeout;private Server(Builder builder) {this.addr = builder.addr;this.port = builder.port;this.timeout = builder.timeout;}public static class Builder {private String addr;private int port = 8080;  // 默认值private int timeout = 30;  // 默认值public Builder(String addr) {this.addr = addr;}public Builder port(int port) {this.port = port;return this;}public Builder timeout(int timeout) {this.timeout = timeout;return this;}public Server build() {return new Server(this);}}
}

Go Functional Options 模式

type options struct {port    *inttimeout *time.Duration
}type Option func(*options) errorfunc WithPort(port int) Option {return func(o *options) error {if port < 0 {return errors.New("invalid port")}o.port = &portreturn nil}
}func NewServer(addr string, opts ...Option) (*Server, error) {var options optionsfor _, opt := range opts {if err := opt(&options); err != nil {return nil, err}}// ...
}

主要区别

  1. 语法风格

    • Java: 链式调用,方法返回 this
    • Go: 函数式风格,使用闭包
  2. 错误处理

    • Java: 通常在 build() 时检查参数有效性
    • Go: 每个选项函数都可以返回错误
  3. 使用方式

// Java
Server server = new Server.Builder("localhost").port(8080).timeout(30).build();
// Go
server, err := NewServer("localhost", WithPort(8080),WithTimeout(30 * time.Second))
  1. 扩展性

    • Java: 需要修改 Builder 类
    • Go: 只需添加新的选项函数
  2. 默认值处理

    • Java: 在 Builder 构造函数中设置
    • Go: 在 NewServer 函数中处理

Go 方式的优势

  1. 更符合 Go 语言特性

    • 利用函数式编程特性
    • 使用错误返回值而不是异常
  2. 更灵活的扩展性

    • 选项函数可以在任何包中定义
    • 不需要修改核心代码
  3. 更好的参数验证

    • 每个选项都可以独立验证
    • 立即返回错误
  4. 更简洁的 API

    • 没有额外的 Builder 类
    • 参数传递更直观

使用场景建议

  • Java Builder: 当参数较多且有复杂的构建逻辑时
  • Go Options: 当需要灵活配置且重视可扩展性时

是的,Java 的 Builder 模式和 Go 的 Functional Options 模式都是配置模式的不同实现。让我对比一下:

Java Builder 模式

public class Server {private final int port;private final int timeout;public static class Builder {// 可配置项,有默认值private int port = 8080;private int timeout = 30;// 链式配置方法public Builder port(int port) {this.port = port;return this;}// 构建最终对象public Server build() {// 参数验证if (port < 0) {throw new IllegalArgumentException("port must be positive");}return new Server(this);}}
}

Go Functional Options 模式

type options struct {port    *inttimeout *time.Duration
}type Option func(*options) errorfunc WithPort(port int) Option {return func(o *options) error {if port < 0 {return errors.New("port must be positive")}o.port = &portreturn nil}
}

共同点

  1. 配置的灵活性

    • 都支持可选参数
    • 都有默认值机制
    • 都支持参数验证
  2. 构建过程控制

    • Java: 通过 build() 方法
    • Go: 通过 NewServer() 函数
  3. 参数验证

    • 都可以在构建过程中进行参数验证

主要区别

  1. 语法风格
// Java: 链式调用
Server server = new Server.Builder().port(8080).timeout(30).build();
// Go: 函数式风格
server, err := NewServer("localhost",WithPort(8080),WithTimeout(30 * time.Second),
)
  1. 错误处理

    • Java: 使用异常
    • Go: 返回错误值
  2. 扩展方式

    • Java: 需要修改 Builder 类
    • Go: 只需添加新的选项函数

选择建议

  1. 使用 Java Builder 模式当:

    • 需要严格的参数校验
    • 对象构建过程复杂
    • 需要不可变对象
  2. 使用 Go Functional Options 模式当:

    • 需要高度灵活性
    • 配置项可能在不同包中扩展
    • 错误处理更为重要

两种模式都是优秀的配置模式实现,选择哪种主要取决于:

  • 使用的编程语言
  • 项目的具体需求
  • 团队的编程风格偏好

相关文章:

【go语言规范】 使用函数式选项 Functional Options 模式处理可选配置

如何处理可选配置&#xff1f; Config Struct 方式 (config-struct/main.go) 这是最简单的方式&#xff0c;使用一个配置结构体&#xff1a; 定义了一个简单的 Config 结构体&#xff0c;包含 Port 字段创建服务器时直接传入配置对象优点&#xff1a;简单直接缺点&#xff1a…...

vue中为组建添加样式的方式

在 Vue 中&#xff0c;可以通过多种方式为 view 添加样式&#xff0c;并且支持动态绑定样式。以下是几种常见的方式&#xff1a; 1. 内联样式 直接在模板中使用 style 属性来添加样式。 <template><div style"color: red; font-size: 14px;">这是一个…...

如何简单的去使用jconsloe 查看线程 (多线程编程篇1)

目录 前言 1.进程和线程 进程 PCB 的作用 并发编程和并行编程 线程 为什么选择多线程编程 2.在IDEA中如何简单创建一个线程 1. 通过继承Thread类 2. 通过实现 Runnable 接口 3. 使用 Lambda 表达式 3.如何简单使用jconsloe去查看创建好的线程 前言 2025来了,这是第…...

机器学习·最近邻方法(k-NN)

前言 上一篇简单介绍了决策树&#xff0c;而本篇讲解与决策树相近的 最近邻方法k-NN。 机器学习决策树-CSDN博客 一、算法原理对比 特性决策树最近邻方法&#xff08;k-NN&#xff09;核心思想通过特征分割构建树结构&#xff0c;递归划分数据基于距离度量&#xff0c;用最近…...

网络安全试题

ciw网络安全试题 &#xff08;1&#xff09;&#xff08;单选题&#xff09;使网络服务器中充斥着大量要求回复的信息&#xff0c;消耗带宽&#xff0c;导致网络或系统停止正常服务&#xff0c;这属于什么攻击类型? A、拒绝服务 B、文件共享 C、BIND漏洞 D、远程过程调用 &a…...

沃丰科技大模型标杆案例 | 索尼大模型智能营销机器人建设实践

AI大模型发展日新月异&#xff0c;国内外主流大模型每月必会升级。海外AI大模型市场由美国主导&#xff0c; 各模型已形成“多强竞合”的局面。中国积极响应全球大模型技术的发展趋势&#xff0c;高校、研究院所等科研机构、互联网企业&#xff0c;人工智能企业均不同程度地投入…...

​ ​rust学习四、控制语句

rust的控制语句和大部分语言没有什么区别&#xff0c;都是熟悉的for,while,loop,if。 比较不同的是&#xff0c;在绝大部分非常流行的语言中都有的switch&#xff0c;rust是没有的。 诸如c/c,java,javascript,c#。连PL/SQL都有case when语句。 一、基本的for、while、if&…...

会员购交易系统架构演进

本期作者 1.背景 会员购是B站2017年推出的IP消费体验服务平台&#xff0c;在售商品以手办、漫画、JK制服等贴合平台生态的商品为主。随着业务发展&#xff0c;会员购从最开始的预售&#xff0c;现货拓展到全款预售&#xff0c;盲盒&#xff0c;众筹等多种售卖方式&#xff0c;销…...

在Linux系统下修改Docker的默认存储路径

在Linux系统下修改Docker的默认存储路径可以通过多种方法实现&#xff0c;下边是通过修改daemon.json文件方式实现 查看当前Docker存储路径 使用命令 docker info | grep "Docker Root Dir" 查看当前Docker的存储路径&#xff0c;默认为 /var/lib/docker 停止Docker…...

【人工智能】释放数据潜能:使用Featuretools进行自动化特征工程

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 特征工程是机器学习流程中至关重要的一步,它直接影响模型的性能。然而,手动特征工程既耗时又需要领域专业知识。Featuretools是一个强大的…...

shell脚本备份PostgreSQL数据库和库下表

注意&#xff1a; 以下为对PostgreSQL13.16版本数据库备份shell脚本参考请确认备份节点上psql和pgdump的版本不至于太低&#xff0c;建议>13.16该脚本目前是对于整库、&#xff08;默认针对public这个schema&#xff0c;如果有其他schema&#xff0c;请自行添加一层循环&am…...

java面试笔记(一)

1. 一万个string类型的数据&#xff0c;设计一个算法如何按照String长度来排序 以使用 Arrays.sort() 方法&#xff0c;并结合一个自定义的比较器。以下是实现的示例代码: public class StringLengthSort {public static void main(String[] args) {// 定义一万个字符串的示例…...

网络分析仪E5071C的回波损耗测量

回波损耗&#xff08;Return Loss&#xff09;是评估射频/微波元件&#xff08;如滤波器、天线、电缆等&#xff09;信号反射特性的关键参数&#xff0c;反映端口阻抗匹配性能。E5071C矢量网络分析仪&#xff08;VNA&#xff09;通过以下步骤实现高精度回波损耗测量&#xff1a…...

sql注入中,如果information_schema被过滤,该怎么绕过

目录 一、sys.schema_auto_increment_columns 1.功能 2.利用思路 二、sys.schema_table_statistics_with_buffer 1.功能 2.利用思路 三、mysql.innodb_table_stats和mysql.innodb_index_stats 1.mysql.innodb_table_stats 1.1功能 2.mysql.innodb_index_stats 2.1功…...

若依Flowable工作流版本监听器使用方法

1.前言 本文详细介绍如何在若依Flowable工作流版本&#xff08;RuoYi-Vue-Flowable&#xff09;中配置执行监听器和任务监听器。是以我二次开发的代码为基础&#xff0c;介绍如何配置监听器&#xff0c;已解决源码在新增或删除监听器出现的问题&#xff0c;如果需要二次开发的…...

Linux(Centos 7.6)命令详解:cat

1.命令作用 将文件或标准输入连接到标准输出(Concatenate FILE(s), or standard input, to standard output)&#xff0c; 即将文件内容输出到屏幕上&#xff0c;或者将多个文件合并成一个文件。 2.命令语法 Usage: cat [OPTION]... [FILE]... 3.参数详解 OPTION: -A, -…...

使用DeepSeek+本地知识库,尝试从0到1搭建高度定制化工作流(自动化篇)

7.5. 配图生成 目的&#xff1a;由于小红书发布文章要求图文格式&#xff0c;因此在生成文案的基础上&#xff0c;我们还需要生成图文搭配文案进行发布。 原实现思路&#xff1a; 起初我打算使用deepseek的文生图模型Janus进行本地部署生成&#xff0c;参考博客&#xff1a;De…...

罗德与施瓦茨ZNB20,矢量网络分析仪9KHz-20GHz

罗德与施瓦茨ZNB20矢量网络分析仪9KHz-20GHz R&SZNB20矢量网络分析仪 产品型号: ZNB20 产品品牌&#xff1a;罗德与施瓦茨 R&S 产品名称: 矢量网络分析仪 频率范围&#xff1a;9kHz - 20GHz R&S ZNB 矢量网络分析仪 良好的测量速度、动态范围和操作方便性&am…...

Linux 固定 IP 地址和网关

Linux 固定 IP 地址和网关 查看 IP ifconfig ifconfig eth0 ip addr ip addr show eth0 查看网关 ip route show route -n netstat -rn 设置固定 IP // 配置静态IP文件/etc/network/interfaces $ vi /etc/network/interfacesauto eth0 iface eth0 inet static addre…...

C++ ——const关键字

const关键字通常表示只读&#xff0c;不可修改&#xff0c;可以保证数据的安全性 1、修饰局部变量 const修饰的局部变量&#xff0c;叫做常局部变量&#xff0c;表示该局部变量不可被修改&#xff0c;这种用法常用于引用参数 2、修饰成员变量 const修饰的成员变量&#xf…...

MySQL:MySQL8.0 JSON类型使用整理,基于用户画像的案例

摘要&#xff1a;MySQL&#xff0c;JSON类型&#xff0c;多值索引&#xff0c; 用户画像 MySQL是结构化数据存储&#xff0c;JSON是非结构化格式&#xff0c;在MySQL中使用JSON类型可以打通关系型和非关系型数据的存储之间的界限&#xff0c;为业务提供更好的架构选择&#xff…...

Python MoviePy 视频处理全攻略:从入门到实战案例

第1章 环境安装与配置 # 案例1&#xff1a;安装MoviePy及FFmpeg !pip install moviepy # Windows安装FFmpeg&#xff1a;https://ffmpeg.org/download.html # Linux: sudo apt-get install ffmpeg# 验证安装 from moviepy.editor import * print("MoviePy版本:", __…...

30道Qt面试题(答案公布)

前五个答案 ✦ 1. Qt中常用的五大模块是哪些? Qt中常用的五大模块包括: • Qt Core:提供核心非GUI功能,如数据结构、文件操作、国际化等。 • Qt GUI:提供与平台无关的图形和基本窗口功能。 • Qt Widgets:提供用于创建传统桌面应用程序的UI组件。 • Qt Netw…...

深入解析 MySQL 数据删除操作:DELETE、TRUNCATE 与 DROP 的原理与选择

引言 在 MySQL 中,删除数据或表结构的操作看似简单,但不同操作(如 DELETE、TRUNCATE、DROP)背后的原理和适用场景差异巨大。错误选择可能导致性能问题或数据丢失!本文通过通俗的比喻、流程图和表格,带你深入理解它们的原理与差异。 DELETE 操作的原理 DELETE … IN 执…...

spring cloud gateway限流常见算法

目录 一、网关限流 1、限流的作用 1. 保护后端服务 2. 保证服务质量 (QoS) 3. 避免滥用和恶意攻击 4. 减少资源浪费 5. 提高系统可扩展性和稳定性 6. 控制不同用户的访问频率 7. 提升用户体验 8. 避免API滥用和负载过高 9. 监控与分析 10. 避免系统崩溃 2、网关限…...

华为FusionCompute虚拟化平台

一、华为FusionCompute虚拟化套件介绍 华为FusionCompute虚拟化套件是业界领先的虚拟化解决方案&#xff0c;能够帮助客户带来如下的价值&#xff0c;从而大幅提升数据中心基础设施的效率。 帮助客户提升数据中心基础设施的资源利用率&#xff1b;帮助客户成倍缩短业务上线周期…...

自然语言处理入门1——单词的表示和距离

随着DeepSeek的火爆&#xff0c;AI大模型越来越被大众所接受&#xff0c;我们在日常生活和工作学习中也开始越来越频繁的使用豆包、通义千问、Kimi、DeepSeek、文心一言等大模型工具了。这些大模型底层技术都是Transformer模型&#xff0c;属于自然语言处理范畴。 今天开始&am…...

UART(一)——UART基础

一、定义 UART(Universal Asynchronous Receiver/Transmitter)是一种广泛使用的串行通信协议,用于在设备间通过异步方式传输数据。它无需共享时钟信号,而是依赖双方预先约定的参数(如波特率)完成通信。 功能和特点 基本的 UART 系统只需三个信号即可提供稳健的中速全双工…...

【数据结构初阶第十节】队列(详解+附源码)

好久不见。。。别不开心了&#xff0c;听听喜欢的歌吧 必须有为成功付出代价的决心&#xff0c;然后想办法付出这个代价。云边有个稻草人-CSDN博客 目录 一、概念和结构 二、队列的实现 Queue.h Queue.c test.c Relaxing Time&#xff01; ————————————《有没…...

确保设备始终处于最佳运行状态,延长设备的使用寿命,保障系统的稳定运行的智慧地产开源了

智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。通过计算机视觉和…...

SP字体UI放大代码

代码&#xff1a; echo off set QT_SCALE_FACTOR放大倍数 start "" "你的SP.exe启动路径"...

信息安全之网络安全防护

信息安全之网络安全防护 先来看看计算机网络通信面临的威胁&#xff1a; 截获——从网络上窃听他人的通信内容中断——有意中断他人在网络上的通信篡改——故意篡改网络上传送的报文伪造——伪造信息在网络上传送 截获信息的攻击称为被动攻击&#xff0c;而更改信息和拒绝用…...

idea无法联网,离线安装插件

插件地址&#xff1a;https://plugins.jetbrains.com/ JetBrains Marketplace 如果无法进入&#xff0c;可以试试 配置hosts 3.163.125.103 plugins.jetbrains.com ip 变了&#xff0c;可以查询个最新的&#xff1a; https://tool.chinaz.com/speedtest/plugins.jetbrai…...

数据结构——哈希表

一、哈希表 1.1 哈希表的概念 散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据关键码值(Key value)而直接进行访问的数据结构。也就是说&#xff0c;它通过把关键码值映射到表中一个位置来访问记录&#xff0c;以加快查找的速度。这个映射函…...

学习查看 linux 关于进程的文件信息 cat /proc/968/status

&#xff08;1&#xff09; 在 Linux 系统中&#xff0c;/proc 文件系统是一个伪文件系统&#xff0c;提供了一个接口来访问内核数据结构。/proc/[pid]/status 文件包含了关于特定进程的状态信息。当你运行 cat /proc/968/status 时&#xff0c;它会输出与进程 ID 为 968 的进程…...

记一次一波三折的众测SRC经历

视频教程和更多福利在我主页简介或专栏里 &#xff08;不懂都可以来问我 专栏找我哦&#xff09; 目录&#xff1a; 前言 波折一&#xff1a;RCE漏洞利用失败 波折二&#xff1a;SQL时间盲注 波折三&#xff1a;寻找管理后台 总结 前言 先谈个人SRC心得体会吧&#xff0c;我虽…...

python绘图之箱型图

箱型图&#xff08;Boxplot&#xff09;&#xff0c;也称为箱线图或盒须图&#xff0c;是一种用于展示一组数据的分布情况的统计图表。它通过简洁的图形形式&#xff0c;直观地呈现数据的集中趋势、离散程度、偏态以及异常值等信息。本节我们来学习使用python绘制箱型图 # 导入…...

http 响应码影响 video 标签播放视频

背景 使用后端给的文件下载接口地址实现视频播放&#xff0c;但是 video 标签一直无法播放视频如下图&#xff0c;把接口地址放到浏览器请求能直接下载。但就是不能播放 原因 http 响应码不正确&#xff0c;返回201是无法播放视频200可以如下图 状态码的影响&#xff1a; 20…...

【ClickHouse 特性及应用场景】

Clickhouse是一个用于联机分析处理&#xff08;OLAP&#xff09;的列式数据库管理系统&#xff08;columnar DBMS&#xff09;。 传统数据库在数据大小比较小&#xff0c;索引大小适合内存&#xff0c;数据缓存命中率足够高的情形下能正常提供服务。但残酷的是&#xff0c;这种…...

【基础架构篇九】《DeepSeek模型版本管理:Git+MLflow集成实践》

各位在模型迭代中反复去世的炼丹师们,扔掉你们那些混乱的v1.2.3_final_fix2模型压缩包!今天我们不聊什么单纯的Git分支管理,也不讲MLflow的入门教程,而是直接掀开算法迭代的黑箱,手把手教你用"外科手术级"的版本控制方案,让模型迭代从玄学变成精准的流水线作业…...

EasyExcel 自定义头信息导出

需求&#xff1a;需要在导出 excel时&#xff0c;合并单元格自定义头信息(动态生成)&#xff0c;然后才是字段列表头即导出数据。 EasyExcel - 使用table去写入&#xff1a;https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E4%BD%BF%E7%94%A8table%E…...

MySQL 之INDEX 索引(Index Index of MySQL)

MySQL 之INDEX 索引 1.4 INDEX 索引 1.4.1 索引介绍 索引&#xff1a;是排序的快速查找的特殊数据结构&#xff0c;定义作为查找条件的字段上&#xff0c;又称为键 key&#xff0c;索引通过存储引擎实现。 优点 大大加快数据的检索速度; 创建唯一性索引&#xff0c;保证数…...

Linux驱动学习(二)--字符设备

设备分类 字符设备块设备网络设备 内核结构图&#xff1a; 字符设备号 字符设备号是32位的无符号整型值 高12位&#xff1a;主设备号低20位&#xff1a;次设备号 查看设备号 cat /proc/devices 设备号构造 直接使用宏MKDEV #define MKDEV(ma,mi) (((ma) << MINORBITS…...

计算机毕业设计--基于深度学习技术(Yolov11、v8、v7、v5)算法的高效人脸检测模型设计与实现(含Github代码+Web端在线体验界面)

基于深度学习技术&#xff08;Yolov11、v8、v7、v5&#xff09;算法的高效人脸检测模型 Yolo算法应用之《基于Yolo的花卉识别算法模型设计》&#xff0c;请参考这篇CSDN作品&#x1f447; 计算机毕业设计–基于深度学习技术&#xff08;Yolov11、v8、v7、v5&#xff09;算法的…...

leetcode-414.第三大的数

leetcode-414.第三大的数 code review! 文章目录 leetcode-414.第三大的数一.题目描述二.代码提交 一.题目描述 二.代码提交 class Solution { public:int thirdMax(vector<int>& nums) {set<int> set_v(nums.begin(), nums.end());auto it set_v.rbegin()…...

使用API有效率地管理Dynadot域名,参与过期域名竞价

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…...

iOS 上自定义编译 FFmpeg

在 iOS 上自定义编译 FFmpeg 是一个复杂但非常灵活的过程。通过自定义编译,您可以选择启用或禁用特定的功能和编解码器,以满足项目的需求,同时减少二进制文件的大小。 1. 自定义编译 FFmpeg 1.1 准备工作 在开始编译之前,您需要以下工具和环境: macOS:运行编译的主机。…...

解锁 JavaScript 异步编程:Promise 链式操作、async/await 与 Promise.all 深度剖析

1.引言 在 JavaScript 的世界里,异步编程是一个核心且关键的概念。随着 Web 应用的复杂度不断提升,处理多个异步操作的需求也日益增长。传统的回调函数方式容易陷入 “回调地狱”,让代码的可读性和可维护性大打折扣。而 Promise 的出现为异步编程带来了新的曙光,后续又衍生…...

30 款 Windows 和 Mac 下的复制粘贴软件对比

在日常电脑操作中&#xff0c;复制粘贴是极为高频的操作&#xff0c;一款好用的复制粘贴软件能极大提升工作效率。以下为你详细介绍 30 款 Windows 和 Mac 下的复制粘贴软件&#xff0c;并对比它们的优缺点&#xff0c;同时附上官网下载地址&#xff0c;方便大家获取软件。 Pa…...

复现论文:DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization

论文&#xff1a;[2403.16697] DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization github: TYLfromSEU/DPStyler: DPStyler: Dynamic PromptStyler for Source-Free Domain Generalization 论文: 这篇论文还是在PromptStyler:Prompt-driven Style Gener…...