双相元编程:一种新语言设计方法

本文讨论了编程语言的一种趋势,即允许相同的语法表达

  • 在两个不同阶段或环境(上下文)中执行的计算
  • 同时保持跨阶段(上下文)的一致行为。
  • 这些阶段通常在时间上(运行时间)或空间上(运行地点)有所不同。

作者提供了三种体现这种“双相编程(biphasic programming)”概念的语言示例:

  1. Zig:Zig 允许使用“comptime”关键字在编译时运行普通函数,提供与基础语言相同的表达能力.这使得源代码中的构建时间和运行时执行之间能够无缝切换。
  2. Winglang:Winglang 是一种用于编写云应用程序的编程语言,其设计采用了双相概念。它提供预检代码(在编译时运行以定义云基础设施)和运行中代码(在运行时运行以与基础设施交互)。两个阶段具有相同的语法,但具有不同的规则和功能。
  3. React 服务器组件 (RSC):RSC 允许 React 组件指定它们应该在服务器端还是客户端渲染,从而实现服务器渲染和客户端渲染组件的灵活组合。此方法旨在通过最小化服务器和客户端之间传输的动态 HTML 和组件信息量来优化页面性能。

作者提出,双相规划可用于解决各种问题,探索这些解决方案规则之间的重叠和差异可能会产生有趣的见解文章还提到,虽然编译时代码执行并不是一个新想法,但 Zig 的方法似乎避免了其他元编程 系统的几个缺点。

双相编程问题
虽然双相编程可以在表达力、性能和灵活性方面带来好处,但开发人员必须做好准备,以应对在项目中采用这种模式所带来的日益增加的复杂性和潜在挑战

  1. 复杂性增加:双相编程要求开发人员在同一代码库中管理两个不同的执行阶段(例如编译时和运行时),从而增加了一层复杂性。这会增加认知负担,使代码更难理解和维护。
  2. 参数化和数据需求:双相模型通常需要更多的参数和数据来捕捉两个阶段的细微差别,与更简单的单相模型相比,这使得它们更难以拟合和验证。
  3. 工具和生态系统支持:现有的开发工具、库和框架可能不完全支持双相编程范式,需要开发人员投入时间和精力来构建定制解决方案或调整他们的工作流程。
  4. 性能权衡:在编译时执行代码的能力可以提供性能优势,但也可能引入新的性能考虑,例如增加编译时间或缓存和记忆的潜在问题。
  5. 采用和学习曲线:双相编程代表了传统编程模型的转变,开发人员在加入团队并将新方法集成到现有代码库和开发实践中时可能会面临阻力或挑战。
  6. 调试和故障排除:将代码执行分为两个不同的阶段可能会使调试和解决问题变得更加困难,因为根本原因可能隐藏在编译时和运行时环境之间的交互中

1、案例:Zig
Zig一种系统编程语言,可让您编写高性能代码,并相对轻松地逐步采用到 C/C++ 代码库中。

它的主要创新之一是一种名为“comptime”的全新元编程方法,可让您在编译时运行普通函数。

与 C、C++ 和 Rust 中的预处理系统和宏系统相比,comptime 的独特之处在于,它通过“comptime”关键字为您提供了与基础语言相同的[2](https://rybicki.io/blog/2024/06/30/biphasic-programming.htmlfn:2)表达能力,而不是引入只有高级用户才可能想要学习的完全独立的领域特定语言。

const expect = @import("std").testing.expect;

fn fibonacci(index: u32) u32 {
if (index < 2) return index;
return fibonacci(index - 1) + fibonacci(index - 2);
}

test "fibonacci" { // 运行时测试斐波那契 try expect(fibonacci(7) == 13); //在编译时测试斐波那契 try comptime expect(fibonacci(7) == 13);
}

作为双相编程的一种情况,comptime 允许 Zig 用户在源代码中无缝切换在构建时运行代码和在运行时运行代码,而不会带来陡峭的学习曲线。

它改变了开发人员的思维模式,不再将元编程视为高级魔法,而是将其视为一种优化工具,还可以利用它来实现泛型和其他代码生成用途。

不管怎样,编译时代码执行并不是一个全新的想法。然而,Zig 的方法似乎确实避免了一些缺点。例如,与 Rust 及其const 函数不同,Zig 不会对 comptime 函数强制使用函数着色。同样,与 C++ 的模板系统不同,Zig 不会引入任何用于表示泛型的新语法。与支持 hygenic 宏的 Scheme 和 Racket 等 Lisp 相比,Zig 并不要求所有内容都是列表。

TL;DR: Zig 支持一种双相编程形式,其中相同的函数可以在两个不同的阶段运行,这两个阶段在时间上(构建时间与运行时间)和空间上(在构建系统上与在运行二进制文件的机器上)有所不同。

2、案例:React 服务器组件
我注意到的第二个双相编程示例是React Server Components (RSC)。React 本身并不是一门语言,但作为一个 JavaScript Web 框架,它作为编写和编写大型网站的 UI 组件及其相关 UI 逻辑的基础系统,拥有相当大的知名度。

最近,前端 JavaScript 生态系统一直在进行大量探索,以找出如何最有效地在服务器或客户端上呈现 UI 组件以提高页面性能。已经提出了许多解决方案,其中最雄心勃勃的解决方案之一就是 RSC。

RSC 背后的想法是允许 React 组件指定它应该在服务器端还是客户端呈现,并允许这些组件自由组合在一起。

例如,

  • 组件Feed可能在服务器上呈现(因为它需要从数据库获取 feed 项列表),

  • 而每个子组件FeedItem可以在客户端呈现(因为它们是项状态的纯函数),

  • 而FeedItemPreview可能在服务器上呈现(因为它需要从数据库获取项的内容)。

开发人员可以选择在哪里计算哪些组件,底层引擎(通常是生成服务器端代码和客户端代码的 JavaScript 打包器)会优化所有内容,以便在需要时在服务器或客户端上呈现组件,从而最大限度地减少来回传输的动态 HTML 和组件信息量。

让这一切正常运行并稳定下来仍是一项艰巨的工作。但我认为该范式是双相编程的一个有趣例子。

有很多方法可以减少需要在客户端浏览器上发送和执行的代码量,并将更多工作转移到服务器上,但当今大多数现有解决方案都要求开发人员将 React 组件视为纯客户端抽象,或纯服务器端抽象。

例如,要么在服务器上呈现整个页面,要么在客户端呈现整个页面,反之亦然。如果引擎可以得到足够的优化并且生成的代码可以足够调试,那么采用 React 组件模型并让开发人员切换组件的呈现位置似乎是一种强大的抽象。

React Server Components 承诺一种双相编程形式,其中可以使用相同的 JavaScript + JSX 语法来表示在服务器或客户端上呈现的组件,并且可以灵活组合。服务器端和客户端渲染同时进行,但它们在空间上有所不同(在服务器上与在浏览器上)。

我还想特别提到Electric Clojure ,这是我在[url=https://systemsdistributed.com/\]Systems Distributed[/url]的一次闪电演讲中发现的这个项目,它采用了类似的想法,在前端/后端边界上提供强大的组合,但使用的是 Clojure 语言。

3、案例:Winglang
我对“双相编程”理念如此好奇的很大一部分原因是,在过去的两年里,我一直在研究Winglang,这是一种用于编写云应用程序的新编程语言,它在设计中大量采用了这一概念。这个项目是我介绍的三个例子中最年轻的一个(它只开发了两年),但在本文中,我将尝试尽可能简短地介绍它,以便为其双相类型系统提供足够的背景信息。

Winglang 背后的要点是,由于拥有大量计算资源,AWS、Azure 和 GCP 等主要云提供商能够为开发人员提供各种可扩展的高级服务,如队列、发布-订阅主题、工作流、流、存储桶等。通俗地说,这些通常被称为资源。Terraform和CloudFormation等基础设施即代码工具使得使用 JSON 或[url=https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-overview.html\]YAML\[/url\]管理这些资源成为可能。

原则上,使用这些资源构建复杂的应用程序应该不难。但是,如果您的应用程序足够大并且拥有许多资源,那么将每个无服务器函数或容器服务与其所需资源的权限和配置明确连接起来就很容易出错。围绕这些资源设计自定义接口也很困难。

Winglang 旨在让您编写将基础架构资源和应用程序逻辑组合在一起的库和应用程序,通过该语言所称的预检和飞行代码。下面是一个示例程序来演示:

// Import some libraries.
bring s3;
bring lambda;
bring redis;
bring triggers;

// 定义我们的抽象。class Cache {
_redis: redis.Redis;
_bucket: s3.Bucket;
new() {
this._redis = new redis.Redis();
this._bucket = new s3.Bucket();
}

    pub inflight get(key: str): str { // Check Redis first, otherwise fall back to S3 let var value = this._redis.get(key);
if value == nil {
value = this._bucket.getObject(key);
this._redis.set(key, value!);
}
return value!;
}

    pub inflight set(key: str, value: str) { // Update S3 and redis with the new entry this._bucket.putObject(key, value);
this._redis.set(key, value);
}

    pub inflight reset() {
this._redis.flush();
this._bucket.empty();
}
}

let cache = new Cache();//每小时清空缓存一次。
let schedule = new triggers.Schedule(rate: 1h);
schedule.onTick(inflight () => {
cache.reset();
});

//创建一个 AWS Lambda 函数来执行一些虚假的业务逻辑。let fn = new lambda.Function(inflight (key) => {
let value = cache.get(key!);
return "Found value: " + value;
});
// 将功能发布到公共 URL。

fn.expose();

在程序的顶层范围内,所有代码都是预检代码。除其他外,我们可以定义类、实例化资源并调用预检函数(如onTick()和expose())来扩充和创建基础架构。这些语句在编译时执行。

但无论inflight使用关键字在哪里,我们都会引入一个代码范围,该代码只能在应用程序部署到云后运行。

get()、set()和reset()都是预检函数。

可以将 Winglang 的预检/运行中区别与 Zig 的计算时间/运行时区别进行比较。但由于这两种语言是围绕不同的用例构建的,因此它们的设计截然不同,这可能并不奇怪。例如,Zig 的计算时间旨在避免所有潜在的副作用,而 Winglang 的预检鼓励副作用,以便您可以改变基础设施图。

Wing 提供了一种双相编程形式,其中可以执行代码来定义云基础设施,或与云基础设施进行交互。这两个阶段称为预检和飞行,在时间(编译时与运行时)和空间上有所不同(预检在构建系统上运行,而飞行代码可以在支持 JavaScript 运行时的任何计算系统上执行)。

元编程总结
一个要点是,这种双相编程可用于解决许多不同的问题。在 Zig 中,它使人们能够轻松进行编译时元编程。在 React 中,它使编写更专业和优化的前端应用程序成为可能。在 Wing 中,它允许您对分布式程序的基础设施和应用程序问题进行建模。这太酷了!

但这里可能还有更多值得探索的地方:比如这些双相解决方案的规则如何重叠或不同。

  • 在 Zig 中,您可以在 comptime 运行的每个函数也可以在运行时安全运行——因此我们可以说,哪些函数可以在 comptime 运行以及哪些函数可以在运行时运行之间存在子集关系。
  • 这同样适用于 React Server Components——您可以在客户端上呈现的任何组件也可以在服务器上呈现。
  • 但在 Wing 中,预检和检修两个阶段是严格分开的,因此要表示可以在任一阶段运行的代码,您需要为这些函数添加单独的标签(如“非阶段函数”)。

另一个悬而未决的问题是了解双相编程在多大程度上代表了无法用普通语言表达的能力。?

  • Zig 需要为这个 comptime 事物添加一个新的关键字 

但是否有其他现有语言可以让你做到这一点,也许在用户空间?
将其作为专用语言功能提供是否会提供任何改进的安全性或错误处理?

  • 元编程系统与双相编程有关。例如,C 预处理可以被认为是双相编程,因为它允许您在预处理器中运行代码,这是运行时之前的编译阶段。但它不满足我提供的定义,因为预处理器只进行文本替换,而 C 的预处理器宏是有限的——ifdef 与真正的 if 语句完全不同。另一方面,Lisp 风格的卫生宏(如 Scheme 和 Racket 中的宏)是通过支持与基础语言相同的表达能力的函数来表达的,所以我认为可以说 Lisp 提供了一些最古老的双相编程示例 

  • 根据[Zig 文档](https://ziglang.org/documentation/master/comptime),comptime 表达式在某些方面受到限制 - 例如,它们不能调用外部函数、包含return或try表达式或执行副作用。但是,该语言的很大一部分是可用的,并且所包含的示例表明 comptime 函数不需要明确标记为这样,这有助于使该功能感觉更普通 

JavaScript 不是最快的语言,但它可靠且拥有广泛的生态系统。我们有兴趣在未来支持其他语言 

网友讨论:
1、我喜欢 "双相 "这个词!在 Javascript 网络开发中,以前的术语是 "同构 "或 "通用"。我认为这些术语并没有真正流行起来。
近十年来,我一直在服务器端和浏览器端渲染相同的 React 组件,我发现了一些非常好的模式,而这些模式在其他地方并不多见。

以下是我在个人项目中使用的架构模式。为了好玩,我开始用 F# 编写,并使用 Fable 编译成 JS:
https://fex-template.fly.dev

一个基本要素是将 express 移植到浏览器,并恰如其分地命名为 browser express:
https://github.com/williamcotton/browser-express

有了它,您不仅可以编写双相用户界面组件,还可以编写路由处理程序。在我看来,通过大量使用其他 React 框架的经验,这种方法远远优于主流框架所采用的方法,甚至优于 React 开发人员所期望的工具使用方式。一个很好的副作用是,网站在启用 Javascript 后也能正常运行。这也意味着交互时间是即时的。

它始终关注请求本身,通过浏览器中的点击和表单发布事件创建模拟 HTTP 请求。它围绕处理传入请求和传出响应的中间件进行了适当的架构,并为浏览器或服务器运行时提供了并行的中间件。它使用链接和表单等网页和浏览器原生概念来处理用户输入,而不是通过 React 中的受控表单来加倍处理浏览器的状态。我不禁注意到,React 正在开始摒弃受控表单。他们终于意识到这种设计是错误的。

因为代码是以这种双相的方式编写的,并且注入了运行时上下文,所以避免了浏览器或服务器运行时的任何条件。在我看来,将文件标记为 "使用客户端 "或 "使用服务器 "是一种漏洞百出的抽象。

总之,我很喜欢这篇文章,并打算在实践中使用这个术语!

2、最终,编译时和运行时之间的任何区别都会被消解。其他一些二分法的例子也可以通过类似的通用酸来部分消解:

  • 动态类型与静态类型,这是一个连续体,JIT 和编译可以从两端进行攻击--在某种意义上,动态类型的程序也是静态类型的--所有函数类型都是依赖函数类型,所有值类型都是和类型。毕竟,从属和的一个项、一个从属对只是一个盒装值。

  • 单态化与多态化--通过表/接口/协议,大致以指令缓存密度换取数据缓存密度

  • RC vs GC vs 堆分配,通过编译器辅助证明内存所有权关系,说明这应该如何发生

  • 将堆栈和指令指针特权化,而不是让这种瞬态程序状态成为与其他数据结构一样的一流数据结构,以实现你自己的共同程序和其他任何东西:Zig 决定,内存分配不应被赋予特权,以至于成为一种 "隐形设施",让人以为它是全局性的。

  • 我们可以使用指针函数,当你恰好知道需要多少项目,以及如何访问、拥有、分配和取消分配这些项目时,这些函数就能以更有效的方式透明地进行单形态化。

  • 取而代之的是,在优化代码的过程中,或多或少都要考虑到内存使用、执行效率、指令密度、表示语义的清晰度等等等等。

目前,我们有一些奇怪的孤立方式,可以在某些语言中实现特定的特权,并对你能走多远设定了相当武断的界限。我希望有一天,我们能有一种语言,能将所有这些决策制定和工程设计溶解到通用的设施中,在这种设施中,语言可以是你需要的任何东西--它只是一个中立的基底,用于表达计算,以及你想如何生产出可以以各种方式运行的机器制品。

据推测,未来这样的语言,如果真的存在,应该会从今天的证明助手中衍生出来。

3、编程语言和代码的其他 "双相 "特性:

  • - 由内联代码注释生成的文档(Knuth 的识字编程)
  • - 测试代码

我们可以扩展到

  • - 安全性(超越 perl 污点)
  • - O(n) 运行时和内存分析
  • - 并行或聚类
  • - 延迟预算

对于那些有学术倾向的人来说,形式语言语义,如 https://en.wikipedia.org/wiki/Denotational\_semantics 与运算等比较。

4、“双相编程”也存在于 Apache Spark、Tensorflow 等框架、Gradle 等构建工具以及代码优先工作流引擎中。第一阶段的执行会生成一个稍后要执行的代码 DAG。在我看来,对于新手来说,最难的事情是第一阶段和第二阶段的代码交错在一起,没有直接明确的界限(第一阶段的代码类似于内部 DSL)。

5、双相编程的另一个示例是使用 DSL 生成解析器的解析器生成器,例如 Tree Sitter 或 Lezer。

6、作者是自鸣得意的反 Lisp 狂人:Lisp 中并非所有东西都是列表。
事实上,Lisp 和 Forth 是最强大的“双相”语言之一,因为完整语言中的两种表达式都可以在编译时进行求值。
Pre-Scheme 是 Scheme 的一个无 GC、静态类型的“系统”子集,它允许您使用完整的 Scheme 语言来处理任何可以在编译时进行可证明求值的表达式(例如,使用 DEFINE 在顶层引入变量)。

更多元编程:https://www.jdon.com/74451.html

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

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

相关文章

前端技术(说明篇)

Introduction ##编写内容&#xff1a;1.前端概念梳理 2.前端技术种类 3.前端学习方式 ##编写人&#xff1a;贾雯爽 ##最后更新时间&#xff1a;2024/07/01 Overview 最近在广州粤嵌进行实习&#xff0c;项目名称是”基于Node实现多人聊天室“&#xff0c;主要内容是对前端界…

springboot图书馆座位预约系统-计算机毕业设计源码85670

目 录 摘要 1 绪论 1.1 选题背景与意义 1.2开发现状 1.3论文结构与章节安排 2 开发环境及相关技术介绍 2.1 MySQL数据库 2.2 Tomcat服务器 2.3 Java语言 2.4 SpringBoot框架介绍 3 图书馆座位预约系统系统分析 3.1 可行性分析 3.1.1 技术可行性分析 3.1.2 经济可…

【Qt】初识QtQt Creator

一.简述Qt 1.什么是Qt Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 。它为应⽤程序开发者提供了建⽴艺术级图形界⾯所需的所有功能。它是完全⾯向对象的&#xff0c;很容易扩展。Qt 为开发者提供了⼀种基于组件的开发模式&#xff0c;开发者可以通过简单的拖拽和组合来实现…

基于ESP32 IDF的WebServer实现以及OTA固件升级实现记录(三)

经过前面两篇的前序铺垫&#xff0c;对webserver以及restful api架构有了大体了解后本篇描述下最终的ota实现的代码以及调试中遇到的诡异bug。 eps32的实际ota实现过程其实esp32官方都已经基本实现好了&#xff0c;我们要做到无非就是把要升级的固件搬运到对应ota flash分区里面…

2.3 主程序和外部IO交互 (文件映射方式)----IO Server实现

2.3 主程序和外部IO交互 &#xff08;文件映射方式&#xff09;----IO Server C实现 效果显示 1 内存共享概念 基本原理&#xff1a;以页面为单位&#xff0c;将一个普通文件映射到内存中&#xff0c;达到共享内存和节约内存的目的&#xff0c;通常在需要对文件进行频繁读写时…

手写一个类似@RequestParam的注解(用来接收请求体的参数)

一、本文解决的痛点 按照大众认为的开发规范&#xff0c;一般post类型的请求参数应该传在请求body里面。但是我们有些post接口只需要传入一个字段&#xff0c;我们接受这种参数就得像下面这样单独创建一个类&#xff0c;类中再添加要传入的基本类型字段&#xff0c;配合Reques…

LLM指令微调Prompt的最佳实践(二):Prompt迭代优化

文章目录 1. 前言2. Prompt定义3. 迭代优化——以产品说明书举例3.1 产品说明书3.2 初始Prompt3.3 优化1: 添加长度限制3.4 优化2: 细节纠错3.5 优化3: 添加表格 4. 总结5. 参考 1. 前言 前情提要&#xff1a; 《LLM指令微调Prompt的最佳实践&#xff08;一&#xff09;&#…

nexus未开启匿名访问Anonymous Access,访问maven元数据maven-metadata,报401未授权Unauthorized错误

一、背景 下午在调试nexus的时候&#xff0c;其他同事不小心把匿名访问停用了&#xff0c;导致客户端android打包的时候&#xff0c;报错&#xff1a; Received status code 401 from server: Unauthorized。 访问http://192.168.xx.xx:8081/repository/public/com/xxx/xxxcor…

【软件测试】单元测试、系统测试、集成测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、单元测试的概念 单元测试是对软件基本组成单元进行的测试&#xff0c;如函数或一个类的方法…

PCL 点云最小图割(前景、背景点云提取)

点云最小图割 一、概述1.1 概念1.2 算法原理二、代码示例三、运行结果🙋 结果预览 一、概述 1.1 概念 最小图割算法(pcl::MinCutSegmentation):是一种基于图论的对象分割方法,主要用于点云数据的处理和分析。该算法将点云数据表示为一个图结构,其中点云中的点作为图的节…

【Java】微博系统设计:怎么应对热点事件的突发访问压力?

一、问题解析 微博&#xff08;microblog&#xff09;是一种允许用户即时更新简短文本&#xff08;比如140个字符&#xff09;&#xff0c;并可以公开发布的微型博客形式。今天我们就来开发一个面向全球用户、可以支持10亿级用户体量的微博系统&#xff0c;系统名称为“Weitte…

不同系统间数据交换要通过 api 不能直接数据库访问

很多大数据开发提供数据给外部系统直接给表结构&#xff0c;这是不好的方式。在不同系统间进行数据交换时&#xff0c;通过API&#xff08;应用程序编程接口&#xff09;而非直接访问数据库是现代系统集成的一种最佳实践。 目录 为什么要通过API进行数据交换如何通过API进行数据…

UG NX二次开发(C#)-根据草图创建拉伸特征(UFun+NXOpen)

文章目录 1、前言2、在UG NX中创建草图,然后创建拉伸特征3、基于UFun函数的实现4、基于NXOpen的实现代码1、前言 UG NX是基于特征的三维建模软件,其中拉伸特征是一个很重要的特征,有读者问如何根据草图创建拉伸特征,我在这篇博客中讲述一下草图创建拉伸特征的UG NX二次开发…

分布式链路追踪Micrometer Tracing和ZipKin基础入门与实践

【1】概述 在分布式与微服务场景下&#xff0c;我们需要解决如下问题&#xff1a; 在大规模分布式与微服务集群下&#xff0c;如何实时观测系统的整体调用链路情况。 在大规模分布式与微服务集群下&#xff0c;如何快速发现并定位到问题。 在大规模分布式与微服务集群下&…

AI网络爬虫006:从当当网批量获取图书信息

文章目录 一、目标二、输入内容三、输出内容一、目标 用户输入一个图书名称,然后程序自动从当当网批量获取图书信息 查看相关元素在源代码中的位置: 二、输入内容 第一步:在deepseek中输入提示词: 你是一个Python爬虫专家,一步步的思考,完成以下网页爬取的Python脚本任…

法制史学习笔记(个人向) Part.3

5. 三国两晋南北朝法律制度 以下为三国魏晋南北朝直到唐代的历史发展脉络图&#xff1a; #mermaid-svg-6AVVMjllKTBaBbRO {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6AVVMjllKTBaBbRO .error-icon{fill:#55222…

【Python实战因果推断】14_线性回归的不合理效果4

目录 Debiasing Step Denoising Step Standard Error of the Regression Estimator Debiasing Step 回想一下&#xff0c;最初由于混杂偏差&#xff0c;您的数据看起来是这样的、 随着信贷额度的增加&#xff0c;违约率呈下降趋势&#xff1a; 根据 FWL 定理&#xff0c;您可…

c文件读写

格式输入输出 文件指针 FILE *pf 文件打开 fopen("文件名",打开方式)  文件名&#xff1a;普通字符串 打开方式&#xff1a;读、写、文本文件、二进制文件 rt、wt、at、rb、wb、ab、rt、wt、at、rb、wb、ab (r 为读&#xff0c;w 为写&#xff0c; 为读写&…

解锁机器学习潜力的钥匙:深度剖析交叉验证集的应用与魅力

一、为何需要交叉验证集 在构建机器学习模型时&#xff0c;我们通常会面临一个关键问题&#xff1a;如何确保模型在新数据上的表现与在训练数据上一样出色&#xff1f;这涉及到模型的泛化能力——即模型对未见过的数据做出准确预测的能力。传统的训练集/测试集划分方法虽然简单…