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

C++没有Y Combinator?使用 C++ 实现 Y Combinator(中英双语)

C++ 中并没有直接内置的 Y Combinator,但通过现代 C++ 特性(如 lambda 表达式std::function),我们可以实现一个类似 Y Combinator 的功能。

下面我们来详细讲解如何在 C++ 中实现 Y Combinator。


使用 C++ 实现 Y Combinator

目标

我们希望实现一个支持递归的匿名函数,而不需要显式命名递归函数。关于Y combinator的概念,可以参考笔者的另一篇博客:理解 Y Combinator:函数式编程中的递归技巧(中英双语)

实现步骤
  1. 基础概念
    在 C++ 中,lambda 表达式默认是无法直接递归调用自己的,因为它无法在定义时引用自己的名字。为了实现递归,我们需要一种方式让 lambda 表达式能够间接调用自身。

  2. Y Combinator 模板实现
    我们可以通过一个辅助的类或函数,把递归的能力注入到 lambda 表达式中。


示例代码

以下是一个通用的 Y Combinator 实现:(代码解析请看下文

#include <iostream>
#include <functional>template <typename Func>
class YCombinator {
public:explicit YCombinator(Func&& func) : func_(std::forward<Func>(func)) {}template <typename... Args>auto operator()(Args&&... args) const {// 将函数本身作为参数传递给 lambda,允许递归return func_(*this, std::forward<Args>(args)...);}private:Func func_;
};// 帮助函数:创建 Y Combinator
template <typename Func>
auto make_y_combinator(Func&& func) {return YCombinator<std::decay_t<Func>>(std::forward<Func>(func));
}

使用示例:计算阶乘

以下是如何使用 Y Combinator 计算阶乘的例子:

#include <iostream>
#include <functional>// 引入 Y Combinator 模板
template <typename Func>
class YCombinator {
public:explicit YCombinator(Func&& func) : func_(std::forward<Func>(func)) {}template <typename... Args>auto operator()(Args&&... args) const {return func_(*this, std::forward<Args>(args)...);}private:Func func_;
};template <typename Func>
auto make_y_combinator(Func&& func) {return YCombinator<std::decay_t<Func>>(std::forward<Func>(func));
}int main() {// 定义阶乘逻辑auto factorial = make_y_combinator([](auto self, int n) -> int {if (n == 0) {return 1;} else {return n * self(n - 1); // 使用 `self` 实现递归}});// 测试阶乘std::cout << "Factorial of 5: " << factorial(5) << std::endl; // 输出 120return 0;
}

工作原理解析

  1. YCombinator

    • YCombinator 是一个高阶函数包装器,它将递归逻辑注入到 lambda 表达式中。
    • 内部的 func_ 存储了实际的 lambda 表达式。
    • operator() 实现了调用逻辑,同时将自身 (*this) 作为参数传递给 lambda 表达式,允许 lambda 表达式递归调用。
  2. 递归逻辑
    factorial 中:

    auto factorial = make_y_combinator([](auto self, int n) -> int {if (n == 0) {return 1;} else {return n * self(n - 1);}
    });
    
    • self 是递归调用的关键,表示当前的递归函数。
    • 使用 self(n - 1) 代替传统的函数名调用,解决了匿名函数无法直接调用自己的问题。

优点

  • 通用性YCombinator 可以为任何递归逻辑提供支持,而不仅仅是阶乘。
  • 现代 C++ 风格:利用了 C++11/14/17 的 lambda 和模板特性,代码简洁且高效。

扩展:其他递归问题

Fibonacci 数列

使用相同的方法,我们可以定义 Fibonacci 数列:

auto fibonacci = make_y_combinator([](auto self, int n) -> int {if (n <= 1) {return n;} else {return self(n - 1) + self(n - 2);}
});
std::cout << "Fibonacci of 10: " << fibonacci(10) << std::endl; // 输出 55

总结

虽然 C++ 没有直接支持 Y Combinator,但通过使用现代 C++ 特性,我们可以优雅地实现一个通用的递归解决方案。这个实现既具有理论意义,也能在实践中帮助我们更深入地理解递归和高阶函数的机制。

解析上述C++代码

这段代码的关键在于 operator() 的实现,以及它如何通过 make_y_combinator 提供递归能力。我们分别解析以下几个核心点:


1. operator() 是如何工作的?

operator() 的定义

YCombinator 类中,operator() 被定义为一个模板方法:

template <typename... Args>
auto operator()(Args&&... args) const {return func_(*this, std::forward<Args>(args)...);
}
  • 它允许 YCombinator 的实例像普通函数一样被调用。
  • operator() 被调用时,它将当前对象(*this,即 YCombinator 自身)作为参数传递给存储的递归函数 func_,从而实现递归能力。
调用位置
  1. make_y_combinator 返回了一个 YCombinator 实例。

    auto factorial = make_y_combinator([](auto self, int n) -> int {if (n == 0) {return 1;} else {return n * self(n - 1);}
    });
    
    • factorial 是一个 YCombinator 实例。
  2. 当调用 factorial(5) 时:

    • 会调用 YCombinatoroperator() 方法。
    • operator() 将自身传入 lambda,支持递归调用。

2. std::forward 的作用

定义

std::forward 是 C++11 引入的模板工具,用于保持参数的“值类别”(左值或右值)属性。

具体作用

operator() 中:

return func_(*this, std::forward<Args>(args)...);
  • Args&&... args万能引用,它可以接受左值或右值参数。
  • std::forward<Args>(args)... 会根据 args 的实际类型(左值或右值)转发给 func_,确保传递时不会改变参数的值类别。
为什么需要 std::forward
  • 如果直接传递 args...,左值可能被误认为右值,导致性能问题或语义错误。
  • std::forward 保证了递归函数的参数传递是高效且正确的。
例子
template <typename T>
void print(T&& value) {forward_example(std::forward<T>(value)); // 确保原样传递
}
  • 如果 value 是左值,std::forward<T>(value) 会保持为左值。
  • 如果 value 是右值,std::forward<T>(value) 会保持为右值。

3. std::decay_t 的作用

定义

std::decay_t<T>std::decay<T>::type 的别名,用于移除模板参数的修饰符(如引用、const、volatile),并将数组或函数指针转换为普通指针。

具体作用

make_y_combinator 中:

return YCombinator<std::decay_t<Func>>(std::forward<Func>(func));
  • Func 可能是一个复杂类型(比如引用或 const 修饰的 lambda 表达式)。
  • 使用 std::decay_t<Func> 可以将 Func 转换为适合存储的普通类型。
为什么需要 std::decay_t
  • 如果直接用 Func,某些类型(如引用或 const 修饰的函数)可能导致编译错误。
  • std::decay_t 确保 YCombinator 中存储的 func_ 是一个干净的可调用对象。
例子
int arr[] = {1, 2, 3};
std::decay_t<decltype(arr)> ptr; // 等价于 int*

4. 完整调用流程

以阶乘计算为例:

auto factorial = make_y_combinator([](auto self, int n) -> int {if (n == 0) {return 1;} else {return n * self(n - 1);}
});
std::cout << factorial(5) << std::endl;
流程解析
  1. make_y_combinator 创建 YCombinator 实例

    • Func 是 lambda。
    • std::decay_t<Func> 确保 func_ 存储的是简化版本的 lambda。
  2. 调用 factorial(5)

    • operator() 被调用,*this(即 factorial 自身)作为参数传递。
    • std::forward<Args>(args)... 确保参数类型不变。
  3. 递归过程

    • 在 lambda 中,selfYCombinator 的实例。
    • 调用 self(n - 1) 时再次触发 operator(),实现递归。

总结

  • operator() 的作用:提供函数调用接口,使 YCombinator 的实例可以像普通函数一样调用,并支持递归。
  • std::forward 的作用:高效地传递参数,保证左值或右值的原始属性不变。
  • std::decay_t 的作用:清理类型修饰符,确保存储的 func_ 类型是普通可调用对象。

解析C++嵌套模板声明

在 C++ 中,template <typename Func> template <typename... Args> 是一种 嵌套模板声明,它通常出现在一个类模板的成员函数中,表示该成员函数本身也是一个模板。

让我们逐步拆解它的含义:


1. template <typename Func>

这一部分定义了一个类模板,表示类 YCombinator 是基于某种类型 Func 的模板类。例如:

template <typename Func>
class YCombinator {// 成员函数、变量等定义
};
  • Func 是一个泛型类型参数,用于表示函数对象类型(如 lambda 表达式)。
  • 这个模板类的作用是让 YCombinator 可以接受任意类型的函数对象。

2. template <typename... Args>

这是一个 函数模板声明,用来表示该成员函数可以接受任意数量、任意类型的参数。它和 typename... Args 中的 可变参数模板 结合使用,可以让函数变得非常灵活。例如:

template <typename Func>
class YCombinator {
public:template <typename... Args>auto operator()(Args&&... args) const {// 实现}
};
  • Args... 是类型参数包,可以代表 0 个或多个类型。
  • Args&&... args 是函数参数包,对应每个类型的实际值。

这允许 operator() 函数在调用时接受任意数量和类型的参数。


3. 为什么使用嵌套模板?

模板类的成员函数需要额外的模板参数

由于 YCombinator 类已经是一个模板类,operator() 又需要定义自己的模板参数(Args...),所以这里必须嵌套一个新的 template。这是 C++ 的语法要求。

具体来说:

  1. 外层模板 template <typename Func> 定义了类的类型参数。
  2. 内层模板 template <typename... Args> 定义了函数自己的参数类型。
示例:
template <typename Func>
class YCombinator {
public:template <typename... Args>auto operator()(Args&&... args) const {return func_(*this, std::forward<Args>(args)...);}private:Func func_;
};

4. 具体调用流程

假设我们使用如下代码:

auto factorial = make_y_combinator([](auto self, int n) -> int {if (n == 0) return 1;return n * self(n - 1);
});std::cout << factorial(5) << std::endl;
调用过程:
  1. factorial(5) 触发 operator()
  2. 编译器自动推断 Args...{int},因此 operator() 实际上被实例化为:
    auto operator()(int&& n) const {return func_(*this, std::forward<int>(n));
    }
    
  3. 通过递归调用,operator() 不断被实例化为适合当前参数的版本。

5. 总结:

  • template <typename Func> 定义了一个模板类,使类能够接受任意类型的函数对象。
  • template <typename... Args> 定义了一个模板成员函数,使函数能够接受任意数量和类型的参数。
  • 这种嵌套模板机制是 C++ 提供的灵活性工具,使模板类和函数可以适配更广泛的需求。

英文版

Does C++ Have a Y Combinator?

C++ does not natively include a Y Combinator, but you can implement it using modern C++ features such as lambda expressions and std::function. The Y Combinator is a functional programming concept that allows recursion for anonymous functions. In C++, this can be achieved by creating a wrapper that injects recursion into a lambda.


Implementing a Y Combinator in C++

Goal

Enable recursion in lambda functions without requiring explicit function names.


Implementation

Here’s a template-based implementation of the Y Combinator:

#include <iostream>
#include <functional>template <typename Func>
class YCombinator {
public:explicit YCombinator(Func&& func) : func_(std::forward<Func>(func)) {}template <typename... Args>auto operator()(Args&&... args) const {// Pass itself as an argument to allow recursionreturn func_(*this, std::forward<Args>(args)...);}private:Func func_;
};// Helper function to create the Y Combinator
template <typename Func>
auto make_y_combinator(Func&& func) {return YCombinator<std::decay_t<Func>>(std::forward<Func>(func));
}

Example: Calculating Factorial

Here’s how to use the above Y Combinator to calculate factorials:

#include <iostream>int main() {// Define the factorial logic using the Y Combinatorauto factorial = make_y_combinator([](auto self, int n) -> int {if (n == 0) {return 1;} else {return n * self(n - 1); // Recursive call using `self`}});// Test the factorial functionstd::cout << "Factorial of 5: " << factorial(5) << std::endl; // Output: 120return 0;
}

How It Works

  1. YCombinator Class:

    • It wraps a lambda function and provides the ability to call itself recursively.
    • The operator() function enables recursion by passing the current instance (*this) to the lambda.
  2. Recursive Logic:

    • The lambda function receives self (the Y Combinator instance) as its first argument.
    • The recursive calls use self(...) instead of an explicitly named function.
  3. General Usage:

    • You can use make_y_combinator to wrap any recursive logic into a callable lambda.

Advantages

  • Generic: This implementation works for any recursive logic, not just specific examples like factorials.
  • Modern: Leverages C++11/14/17 features like lambda expressions and perfect forwarding for clean and efficient code.

Example: Fibonacci Sequence

Here’s how to calculate Fibonacci numbers using the Y Combinator:

auto fibonacci = make_y_combinator([](auto self, int n) -> int {if (n <= 1) {return n;} else {return self(n - 1) + self(n - 2); // Recursive calls}
});std::cout << "Fibonacci of 10: " << fibonacci(10) << std::endl; // Output: 55

Key Takeaways

  1. Recursive Lambdas: Normally, lambda expressions in C++ cannot call themselves by name. The Y Combinator solves this by injecting recursion externally.
  2. Generalized Pattern: The YCombinator class is reusable for any recursive problem.
  3. Power of Functional Programming: This demonstrates how functional programming concepts like fixed-point combinators can be implemented in imperative languages like C++.

Why Use a Y Combinator?

  • Functional Programming: Encourages a declarative approach to recursion.
  • Anonymous Functions: Eliminates the need for explicitly naming recursive functions.
  • Learning Exercise: A great way to deepen your understanding of recursion, higher-order functions, and lambda calculus.

Even though it may not be necessary for most practical use cases in C++, it showcases the expressive power of the language and is a valuable theoretical concept.

后记

2025年1月16日20点31分于上海,在GPT4o大模型辅助下完成。

相关文章:

C++没有Y Combinator?使用 C++ 实现 Y Combinator(中英双语)

C 中并没有直接内置的 Y Combinator&#xff0c;但通过现代 C 特性&#xff08;如 lambda 表达式 和 std::function&#xff09;&#xff0c;我们可以实现一个类似 Y Combinator 的功能。 下面我们来详细讲解如何在 C 中实现 Y Combinator。 使用 C 实现 Y Combinator 目标 …...

YOLOv10-1.1部分代码阅读笔记-loaders.py

loaders.py ultralytics\data\loaders.py 目录 loaders.py 1.所需的库和模块 2.class SourceTypes: 3.class LoadStreams: 4.class LoadScreenshots: 5.class LoadImagesAndVideos: 6.class LoadPilAndNumpy: 7.class LoadTensor: 8.def autocast_list(source…...

《戴森球计划》异地远程联机攻略

文章目录 前言1. 下载MOD2.配置cpolar内网穿透3. 主机开启联机3.1 玩家加入游戏 4. 配置固定的TCP端口5. 游玩体验 前言 《戴森球计划》不仅是一款融合了科幻冒险与经营管理元素的游戏&#xff0c;更是一个让玩家在浩瀚宇宙中尽情探索和创造的平台。在这个游戏中&#xff0c;你…...

【Linux跬步积累】—— 线程

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;Linux跬步积累 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日一题 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0…...

计算机网络 (46)简单网络管理协议SNMP

前言 简单网络管理协议&#xff08;SNMP&#xff0c;Simple Network Management Protocol&#xff09;是一种用于在计算机网络中管理网络节点的标准协议。 一、概述 SNMP是基于TCP/IP五层协议中的应用层协议&#xff0c;它使网络管理员能够管理网络效能&#xff0c;发现并解决网…...

模型 前景理论

系列文章 分享模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。面对得失&#xff0c;人们更怕失&#xff0c;参考点定输赢。 1 前景理论的应用 1.1 前景理论在投资决策中的应用案例 假设一位投资者面临两个投资方案的选择&#xff1a; 方案A&#xff1a;投资一只…...

Android ScrollView嵌套X5WebView大片空白问题

scrollview嵌套后webview的高度不可控。留有大片空白。 注&#xff1a;官方不建议scrollview嵌套webview 最好让webview自身滚动 解决方案&#xff1a; act_news_detail_wv.setWebViewClient(new WebViewClient() {Overridepublic void onPageFinished(WebView webView, Str…...

频域增强通道注意力机制EFCAM模型详解及代码复现

背景与动机 在深度学习领域,如何有效处理时间序列数据一直是一个重要的研究方向。近年来, 频域分析技术 在时间序列处理中展现出了巨大潜力,特别是离散余弦变换(DCT)因其能够高效捕捉低频信息并避免高频噪声干扰而受到广泛关注。 FECAM模型的开发正是基于这一背景,旨在…...

[计算机网络]一. 计算机网络概论第一部分

作者申明&#xff1a;作者所有文章借助了各个渠道的图片视频以及资料&#xff0c;在此致谢。作者所有文章不用于盈利&#xff0c;只是用于个人学习。 1.0推荐动画 【网络】半小时看懂<计算机网络>_哔哩哔哩_bilibili 1.1计算机网络在信息时代的作用 在当今信息时代&…...

第十三章:数据库技术

文章目录&#xff1a; 一&#xff1a;基础 1.概念 2.特点 3.常见数据库品牌 4.数据库应⽤系统 4.1 C/S 4.2 B/S 5.数据模型的分类 6.名词解析 7.关系运算 二&#xff1a;Access 1.基础 2.操作 2.1 建立表 2.2 维护表 2.3 创建查询 2.4 创建窗体 2.5 创建报表…...

中等难度——python实现电子宠物和截图工具

import io # 文件处理 import nt # windows nt 库直接获取对应的磁盘空间 import time # 时间 import zlib # 加解密 import ctypes # 调用 import struct # 处理字节二进制 import base64 # 编解码 import threading # 线程 import tkinter as tk # tk from datetime…...

构建优雅、高效的 Nodejs 命令行工具 - Archons

目录 项目简介安装基本用法样例创建一个简单的命令行工具使用archons上下文创建进度条 最后 项目地址: https://github.com/noctisynth/archons Bug反馈或功能请求&#xff1a;https://github.com/noctisynth/archons/issues 项目简介 Archons意思是“执政官”&#xff0c;我使…...

源码编译安装httpd 2.4,提供系统服务管理脚本并测试

1.安装httpd wget https://downloads.apache.org/httpd/httpd-2.4.62.tar.gzbmcv tar -zxvf httpd-2.4.62.tar.gz cd httpd-2.4.62 2.安装依赖包 sudo yum install -y gcc make apr-devel apr-util-devel pcre-devel sudo yum groupinstall "Development Tools"…...

【爬虫】某某查cookie逆向

代码仅供技术人员进行学习和研究使用&#xff0c;请勿将其用于非法用途或以任何方式窃取第三方数据。使用该代码产生的所有风险均由用户自行承担&#xff0c;作者不对用户因使用该代码而造成的任何损失或损害承担任何责任。 加密参数 加密参数主要是cookie&#xff0c;其中只有…...

【华为路由/交换机的ssh远程设置】

华为路由/交换机的ssh远程设置 R1&#xff08;client&#xff09;&#xff1a;10.1.1.1 R2&#xff08;server&#xff09;&#xff1a;10.1.1.2 R2服务端配置&#xff1a; 生成本机密钥 查看生成的密钥 设置AAA授权验证方式&#xff0c;并设置支持SSH协议 创建本地用户&…...

Linux:System V - 共享内存

1.System V共享内存的原理 通过为用户提供系统调用接口&#xff0c;让用户可以申请一块空间&#xff0c;进程A/B也可以通过系统调用接口将创建好的内存通过页表映射进进程的地址空间。完成让不同的两个进程看见同一份资源的目的。如果未来不想继续通信&#xff0c;取消进程和内…...

闪豆多平台视频批量下载器

1. 视频链接获取与解析 首先&#xff0c;在哔哩哔哩网页中随意点击一个视频&#xff0c;比如你最近迷上了一个UP主的美食制作视频&#xff0c;想要下载下来慢慢学。点击视频后&#xff0c;复制视频页面的链接。复制完成后&#xff0c;不要急着关闭浏览器&#xff0c;因为接下来…...

《鸿蒙Next微内核:解锁人工智能决策树并行计算的加速密码》

在当今人工智能飞速发展的时代&#xff0c;提升运算速度是推动其进步的关键。鸿蒙Next以其独特的微内核特性&#xff0c;为设计决策树的并行计算框架提供了新的思路和契机。 鸿蒙Next微内核特性概述 鸿蒙Next的微内核架构将核心功能模块化&#xff0c;仅保留进程管理、内存管…...

AWS Lambda

AWS Lambda 是 Amazon Web Services&#xff08;AWS&#xff09;提供的无服务器计算服务&#xff0c;它让开发者能够运行代码而不需要管理服务器或基础设施。AWS Lambda 会自动处理代码的执行、扩展和计费&#xff0c;开发者只需关注编写和部署代码&#xff0c;而无需担心底层硬…...

Python入门教程丨2.3 流程控制、算法效率分析及优化

流程控制是用于控制程序执行顺序的机制&#xff0c;它决定了程序中的语句按照何种顺序被执行。 本节课将详细讲解 Python 流程控制的三大核心结构&#xff1a;顺序、条件和循环&#xff0c;并配备一些小案例。 1. 顺序结构&#xff1a;从头到尾依次执行 顺序结构是程序中最基…...

NVIDIA发布个人超算利器project digital,标志着ai元年的开启

上图NVIDIA公司创始人兼首席执行官 黄仁勋&#xff08;Jensen Huang&#xff09; 这些年被大家熟知的赛博朋克风格一直都是未来的代言词&#xff0c;可以承载人类记忆的芯片&#xff0c;甚至能独立思考的仿生人&#xff0c;现在&#xff0c;随着NVIDIA的project digital发布之后…...

spring-mvc源码分析v3.3.0

分析下springboot内嵌tomcat启动流程&#xff0c;即springboot-mvc <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.3.0</version> </dependency>环境…...

反爬风控设计之请求头顺序检测

本次主要讲解请求头的顺序检测的反爬实现&#xff0c; 如下使用Django写的headers请求头顺序检验算法&#xff1a; def index(request):# 获取请求头的顺序request_order list(request.META.keys())print(request_order)# 定义标准请求头顺序standard_order ["HTTP_HO…...

力扣 查找元素的位置

二分查找经典例题。 题目 要是只是从数组中用二分查找对应的元素&#xff0c;套一下模板一下就可以得出了&#xff0c;然后这题就在于其中会有多个目标元素&#xff0c;要用不同的方式在找到第一个元素时再做偏移。 时间复杂度&#xff1a;O(log n)&#xff0c;空间复杂度&am…...

Android-V lmkd 中的那些属性值

源码基于&#xff1a;Android V 相关博文&#xff1a; Android lmkd 机制详解&#xff08;一&#xff09; Android lmkd 机制详解&#xff08;二&#xff09; Android lmkd 机制从R到T 1. 汇总 属性名说明默认值 ro.lmk.debug 启动 lmkd 的debug 模式&#xff0c;会打印一…...

LabVIEW 程序中的 R6025 错误

R6025错误 通常是 运行时库 错误&#xff0c;特别是与 C 运行时库 相关。这种错误通常会在程序运行时出现&#xff0c;尤其是在使用 C 编译的程序或依赖 C 运行时库的程序时。 ​ 可能的原因&#xff1a; 内存访问冲突&#xff1a; R6025 错误通常是由于程序在运行时访问无效内…...

vmware虚拟机配置ubuntu 18.04(20.04)静态IP地址

VMware版本 &#xff1a;VMware Workstation 17 Pro ubuntu版本&#xff1a;ubuntu-18.04.4-desktop-amd64 主机环境 win11 1. 修改 VMware虚拟网络编辑器 打开vmware&#xff0c;点击顶部的“编辑"菜单&#xff0c;打开 ”虚拟化网络编辑器“ 。 选择更改设置&#…...

mybatis延迟加载、缓存

目录 一、所需表 二、延迟加载 1.延迟加载概念 2.立即加载和延迟加载的应用场景 3.多对一延迟加载查询演示 (1)实体类 User Account (2)AccountMapper接口 (3)AccountMapper.xml (4)UserMapper接口 (5)UserMapper.xml (6)在总配置文件(mybatis-config.xml)中开启延…...

云上贵州多彩宝荣获仓颉社区先锋应用奖 | 助力数字政务新突破

在信息技术应用创新的浪潮中&#xff0c;仓颉社区吸引了众多企业和开发者的积极参与&#xff0c;已有多个应用成功落地&#xff0c;展现出蓬勃的创新活力。仓颉编程语言精心遴选了在社区建设、应用创新、开源共建、技术布道等方面做出突出贡献的优秀项目应用&#xff0c;并颁发…...

设计模式02:结构型设计模式之适配器模式使用情景及其基础Demo

1.适配器模式 用途&#xff1a;接口兼容评价&#xff1a;复杂、冗余、难以调试&#xff0c;个人认为直接在旧系统那里封装一个新实现调用旧实现就好了场景&#xff1a;系统A、B、C想调用同一个功能接口&#xff0c;但是实现细节存在差异时&#xff08;其实就是入参和出参转化处…...

镭速大文件传输视频文件预览实现原理

镭速可以支持视频预览&#xff0c;在测试过程中需要大量不同格式的视频&#xff0c;如果直接去找各种格式的视频不太现实&#xff0c;所以就会用到一个视频格式转换的工具ffmpeg&#xff0c;本文将介绍ffmpeg的基本使用方法。FFmpeg 是一个免费开源的音视频处理工具&#xff0c…...

Mac上安装Label Studio

在Mac上安装Anaconda并随后安装Label Studio&#xff0c;可以按照以下步骤进行&#xff1a; 1. 在Mac上安装Anaconda 首先&#xff0c;你需要从Anaconda的官方网站下载适用于Mac的安装程序。访问Anaconda官网&#xff0c;点击“Download Anaconda”按钮&#xff0c;选择适合M…...

git操作(Windows中GitHub)

使用git控制GitHub中的仓库版本&#xff0c;并在Windows桌面中创建与修改代码&#xff0c;与GitHub仓库进行同步。 创建自己的GitHub仓库 创建一个gen_code实验性仓库用来学习和验证git在Windows下的使用方法&#xff1a;https://github.com/Martianing/gen_code git初始设置…...

低代码平台:技术复杂性的系统简化

在传统开发模式下&#xff0c;应用构建需要经历需求分析、代码开发、测试部署等多环节&#xff0c;流程繁琐且耗时&#xff0c;往往成为企业技术创新的瓶颈。低代码平台通过模块化和自动化技术重新定义开发流程&#xff0c;使开发者能够在较短时间内实现复杂的应用功能&#xf…...

物联网网关Web服务器--lighttpd服务器部署与应用测试

以下是在国产ARM处理器E2000飞腾派开发板上部署 lighttpd 并进行 CGI 应用开发的步骤&#xff1a; 1、lighttpd简介 Lighttpd 是一款轻量级的开源 Web 服务器软件&#xff0c;具有以下特点和功能&#xff1a; 特点 轻量级&#xff1a;Lighttpd 在设计上注重轻量级和高效性&a…...

Flutter+vsCode 安装问题记录

VSCode在安装完AndroidSDK以及相关插件后&#xff0c;运行Flutter项目时选择模拟器提示&#xff1a;avdmanager is missing from the Android SDK&#xff0c;确保环境变量中存在ANDROID_HOME&#xff0c;且执行了flutter config --android-sdk 地址后&#xff0c;如果还提示&a…...

【CompletableFuture实战】

CompletableFuture实战 前言 前言 过去的一年&#xff0c;匆匆忙忙&#xff0c;换了一次工作&#xff0c;写博客的习惯就落下了&#xff0c;总之&#xff0c;有点懈怠。希望今年能重拾信心&#xff0c;步入正规&#xff01; CompletableFuture的用法网上资料颇多&#xff0c;…...

【k8s面试题2025】3、练气中期

体内灵气的量和纯度在逐渐增加。 文章目录 在 Kubernetes 中自定义 Service端口报错常用控制器Kubernetes 中拉伸收缩副本失效设置节点容忍异常时间Deployment 控制器的升级和回滚日志收集资源监控监控 Docker将 Master 节点设置为可调度 在 Kubernetes 中自定义 Service端口报…...

【高可用自动化体系】自动化体系

架构设计的愿景就是高可用、高性能、高扩展、高效率。为了实现架构设计四高愿景&#xff0c;需要实现自动化系统目标&#xff1a; 标准化。 流程自助化。 可视化&#xff1a;可观测系统各项指标、包括全链路跟踪。 自动化&#xff1a;ci/cd 自动化部署。 精细化&#xff1a…...

Spring boot框架下的RocketMQ消息中间件

1. RocketMQ 基础概念 1.1 核心概念 以下是 RocketMQ 核心概念在 Spring Boot 的 Java 后端代码中的实际使用方式&#xff1a; Producer&#xff08;生产者&#xff09; 定义&#xff1a;Producer 是负责发送消息到 RocketMQ 的组件。它可以将消息发送到指定的 Topic。 实…...

http转化为https生成自签名证书

背景 项目开发阶段前后交互采用http协议&#xff0c;演示环境采用htttps协议 &#xff0c;此处为个人demo案例 组件 后端&#xff1a;springBoot 前端&#xff1a;vue web 服务&#xff1a;tomcat 部署环境&#xff1a;linux 生成自签名证书 创建目录 存储证书位置 # mkdir -p…...

关于2025年智能化招聘管理系统平台发展趋势

2025年&#xff0c;招聘管理领域正站在变革的十字路口&#xff0c;全新的技术浪潮与不断变化的职场生态相互碰撞&#xff0c;促使招聘管理系统成为重塑企业人才战略的关键力量。智能化招聘管理系统平台在这一背景下迅速崛起&#xff0c;其发展趋势不仅影响企业的招聘效率与质量…...

CentOS 9 Stream 上安装 Node.js 18.20.5

要在 CentOS 9 Stream 上安装 Node.js 18.20.5&#xff0c;可以按照以下步骤操作&#xff1a; 1. 安装依赖 首先&#xff0c;确保你已经更新了系统并安装了必要的依赖包。 sudo dnf update -y sudo dnf install -y gcc-c make2. 安装 Node.js 18.20.5 Node.js 官方提供了一…...

NSIS 创建一键安装程序

nsis 安装redis 、mysql 、jdk navicat、 notepad、 使用NSIS 创建一键安装程序 分为两步 下载 NSIS编写 一键安装代码 1.16脚本 ; 请求管理员权限运行安装程序 RequestExecutionLevel admin; 该脚本使用 HM VNISEdit 脚本编辑器向导产生; 安装程序初始定义常量 !define PRO…...

NanoKVM简单开箱测评和拆解,让普通电脑实现BMC/IPMI远程管理功能

Sipeed推出了NanoKVM&#xff0c;简直是没有BMC的台式机和工作站的福音。有了这个就可以轻松实现以往服务器才有的远程管理功能。 NanoKVM 简介 Lichee NanoKVM 是基于 LicheeRV Nano 的 IP-KVM 产品&#xff0c;继承了 LicheeRV Nano 的极致体积 和 强大功能。 NanoKVM 包含…...

【混合开发】CefSharp+Vue桌面应用程序开发

为什么选择CefSharpVue做桌面应用程序 CefSharp 基于 Chromium Embedded Framework (CEF) &#xff0c;它可以将 Chromium 浏览器的功能嵌入到 .NET 应用程序中。通过 CefSharp&#xff0c;开发者可以在桌面应用程序中集成 Web 技术&#xff0c;包括 HTML、JavaScript、CSS 等…...

2024最新版JavaScript逆向爬虫教程-------基础篇之Chrome开发者工具学习

目录 一、打开Chrome DevTools的三种方式二、Elements元素面板三、Console控制台面板四、Sources面板五、Network面板六、Application面板七、逆向调试技巧 7.1 善用搜索7.2 查看请求调用堆栈7.3 XHR 请求断点7.4 Console 插桩7.5 堆内存函数调用7.6 复制Console面板输出 工…...

下定决心不去读研了。。。

大家好&#xff0c;我是苍何。 之前发表过一篇文章&#xff0c;表达了自己读研的困惑和纠结&#xff0c;得到了大家很多的建议&#xff0c;也引起了很多人的共鸣&#xff0c;在留言区分享了自己的故事&#xff0c;看着这些故事&#xff0c;我觉得都够苍何写一部小说了。 可惜苍…...

Java21 正则表达式

在 Java 21 中&#xff0c;正则表达式主要通过 java.util.regex 包提供支持&#xff0c;其核心组件包括 Pattern、Matcher 和 String 类中自带的方法&#xff08;如 replaceAll 和 matches&#xff09;。以下是关于正则表达式在 Java 21 中的详细介绍及一些新的特性或用法。 核…...

Docker安装PostGreSQL docker安装PostGreSQL 完整详细教程

Docker安装PostGreSQL docker安装PostGreSQL 完整详细教程 Docker常用命令大全Docker 运行命令生成Docker 上安装 PostGreSQL 14.15 的步骤&#xff1a;1、拉取 PostGreSQL 14.15 镜像2、创建并运行容器3、测试连接4、设置所有IP都可以运行连接进入容器内 修改配置文件关闭容器…...