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

UI架构的历史与基础入门

本笔记的目的是通过一系列连贯的例子来探讨“事物-模型-视图-编辑器”这一隐喻。

这些例子都来自我的规划系统(planning system),用于解释上述四个概念。所有例子都已实现,但并未在本文描述的清晰类结构中实现。

这些隐喻对应于《关于DynaBook需求的笔记》中提出的现实世界-模型-视图-工具(Thing-Model-View-Tool)的概念。

——摘自1979年挪威数学家Trygve Reenskaug的笔记

什么是架构?

事实上,从韩国、中国、美国到西方的案例可以看出,大多数情况下,代码结构被用作架构的代名词。然而,正因为如此,初学者很容易对编程架构感到困惑。

尽管关注点的范围和焦点不同,但由于它们经常在同一层级上混用,因此容易引发混淆。

也就是说,诸如结构架构、UI架构、流程控制等具有不同关注点和范围的概念被当作平等的内容讨论。

无论是在韩国、中国、西方还是日本,这种现象经常出现在所谓的资深开发者中。

那么,为了便于理解,简单来说,

架构是什么?

架构是指软件系统中的高层次设计,它定义了系统的组成部分以及这些部分之间的关系和交互方式。架构的核心目标是解决特定问题,同时满足系统的功能性需求和非功能性需求(如可扩展性、可维护性和性能)。根据不同的关注点,架构可以分为以下几类:

架构分类与示例

类别

描述

代表性架构

整体系统结构

层级依赖方向、领域隔离、业务核心保护

Clean Architecture, Hexagonal (Ports & Adapters), Onion, Layered (3-tier)

UI结构与视图流架构

视图-逻辑-模型间的数据流、用户事件处理

MVC, MVP, MVVM, MVI, VIPER, Redux

内部逻辑控制架构

状态转换/消息驱动的控制逻辑

FSM, Saga, Workflow, RuleEngine

部署与基础设施架构

物理部署/通信结构

Microservices, Monolith, Serverless, Service Mesh

各类架构的主要目标通常如下:

  • 系统结构架构 → 控制依赖方向、提升测试便利性、保护核心业务逻辑。
  • UI结构架构 → 整理用户输入 → 状态变更 → 渲染流程。
  • 行为控制架构 → 内部状态与流程控制。
  • 部署架构 → 根据网络/服务分布设计物理结构。

本文主要讨论的是UI结构,即视图架构(View Architecture)

视图架构是什么?

视图架构是一种专注于如何连接视图与逻辑的局部架构模式。

它与实际的领域逻辑、基础设施或部署无关,是整体系统架构的一部分。

该架构的起源可以追溯到将UI视为机器的尝试,其核心在于如何理解单向状态流。

(Trygve Reenskaug)

MVC(Model - View - Controller)

视图架构(以下简称架构)的起源可以追溯到挪威数学家Trygve Reenskaug在施乐帕洛阿尔托研究中心(Xerox PARC)开发Smalltalk GUI系统时首次提出的概念。

其目的是将用户界面(UI)逻辑与领域逻辑分离。

最初的名称是TMVE(Thing-Model-View-Editor),但后来经过多次演变,最终形成了MVC(Model-View-Controller)模式。MVC通过马丁·福勒(Martin Fowler)的经典著作《企业应用架构模式》(Patterns of Enterprise Application Architecture)等广泛传播。(虽然他不是最初的发明者,但在推广方面做出了巨大贡献。)

MVC的构成要素如下:

构成要素

角色

说明

Model

数据状态管理

包含应用程序的核心逻辑和状态,例如数据库、内存状态、业务规则等。View和Controller引用或操作Model。

View

视觉显示

负责向用户展示Model的状态。它负责屏幕上的信息、布局和样式,自身的逻辑最少化。

Controller

用户输入处理

接收用户输入(如按钮点击、键盘输入等),操作适当的Model,并请求更新View。充当View和Model之间的中介角色。

MVC最具影响力的案例之一是基于Java的Spring框架(2002年至今)。

尽管Spring仍然被广泛使用,但实际上许多最初基于MVC的框架已经发生了很大的变化。例如,虽然Spring被称为MVC框架,但如今的Spring已经有了很大的演变:它不再将View视为Java的一部分,甚至可以在没有View的情况下仅保留Controller。此外,Controller也逐渐演变为更像是HTTP处理器的角色,而非传统意义上的控制器。因此,MVC在某种程度上已经成为一种“品牌化”的概念。

除此之外,AngularJS和React等框架也被归类为MVC,但实际上它们并不是传统的MVC,而是变体:

  • AngularJS更接近于MVVM模式,其中Controller扮演ViewModel的角色,并支持双向绑定,使得View和Model之间的界限变得模糊。
  • React则并非MVC,而是基于单一View的设计,与传统MVC相去甚远。

那么,什么时候应该使用MVC?

MVC适用于结构简单、视图和逻辑相对明确分离的情况,特别是在以服务器端渲染为中心的架构中非常适合。

然而,随着现代架构设计的多样化发展,MVC更适合用于小规模个人项目,而不是大型复杂系统。

传统的小型对话(Smalltalk)控制器功能被提升到了应用层面,
同时考虑了中间过程的选择(selection)、命令(command)和交互(interactor)等概念。为了捕捉这一差异,我们将这种类型的控制器称为“Presenter(展示器)”。因此,我们将这种编程模型整体称为Model-View-Presenter(MVP) ,并承认它是MVC的一种泛化形式。

——摘自1996年Taligent文档

MVP (Model - View - Presenter)

MVC有一个问题:Controller在处理View事件和Model时承担了过多的职责,导致所谓的“Fat Controller”问题。

此外,View和Controller之间的耦合性较强,事件循环与UI框架紧密结合,使得测试变得困难。

最终,为了解决这些问题:

引入了一个新的中介角色——Presenter,并将View抽象为接口,从而可以在Presenter中进行测试。

MVP的构成要素如下:

构成要素

角色

说明

Model

状态及数据处理

负责处理应用程序的状态和数据,包括数据存储、业务规则应用、外部API调用等纯粹的业务逻辑层,与UI分离。

View

UI呈现及用户输入传递

负责向用户显示UI并将输入传递给Presenter。View应设计为尽可能简单的“Dumb View”,不包含复杂的逻辑或状态处理,通常通过接口与Presenter连接。

Presenter

接收View事件 → 操作Model → 将结果反馈给View

接收来自View的用户事件,操作Model,并将结果返回给View。充当View和Model之间的中介,负责调整数据流和管理流程,同时通过接口松散依赖于View,以便于单元测试。

MVP在2010年代初期被广泛应用于Android开发中。

原因是Activity/Fragment结构承担了过多的职责,因此作为最佳实践,将其职责分离到Presenter中。

  • View : Activity/Fragment(实现View接口)
  • Presenter : 向View传递结果
  • Model : Repository、UseCase等

以这种方式,许多项目采用了MVP架构。

不过,目前只有在使用.NET的WinForm时才倾向于采用MVP架构。
这是因为UI事件循环与UI对象紧密绑定,而通过抽象化可以更方便地进行单元测试,因此MVP成为了一个常见的选择。

MVP主要用于客户端应用程序,但随着技术发展,许多框架逐渐转向MVVM架构。

那么,什么时候应该使用MVP?

当复杂UI事件处理非常重要且需要高测试便利性的移动应用时,MVP是一个很好的选择。

它主要应用于客户端开发,尤其是状态管理较为简单的客户端应用时,推荐使用MVP。

自从人们开始开发软件用户界面以来,就出现了一些流行的设计模式来简化这一工作。

例如,MVP(Model-View-Presenter)模式在各种UI编程平台中广受欢迎。

MVP是几十年来使用的Model-View-Controller模式的变体。对于不熟悉MVP模式的读者,简单来说:屏幕上看到的是View,显示的数据是Model,而将两者连接起来的是Presenter。View通过Model数据填充界面,响应用户输入,并提供输入验证(例如委托给Model),同时使用Presenter来处理这些任务。

——MSDN杂志第09期


(John Gossman)

(笔者个人是WPF等C#技术的忠实用户,因此作为程序员,我一直希望能有机会得到John Gossman的签名。他可以说是许多微软技术粉丝的偶像。)

MVVM(Model-View-ViewModel)

2005年,John Gossman在他的博客中首次撰写了关于MVVM的文章。

MVP模式在分离View和逻辑、提升测试便利性以及控制依赖性方面无疑是非常有效的模式。

然而,由于结构性、生产力以及绑定方面的局限性,MVVM逐渐成为自然的选择。

在MVP中,View和Presenter之间的手动连接会产生大量的模板代码,并且在View与Presenter之间传递数据时需要编写大量重复的过程。

此外,由于MVP缺乏数据绑定机制,频繁调用Presenter会导致较大的开销。而在MVVM中,ViewModel负责状态绑定并实现自动更新,即具备“响应式”特性。

最终,现代UI框架大多转向了MVVM架构,例如MAUI、WPF等基于数据绑定的UI框架,MVVM成为了最理想的选择。

MVVM的构成要素如下:

构成要素

角色

说明

Model

数据状态管理

负责应用程序的核心数据和业务逻辑,包括服务器API、数据库、业务规则等。它直接与ViewModel交换数据。

View

UI显示及绑定

以视觉方式呈现用户界面(UI)。View通过绑定到ViewModel,在状态发生变化时自动更新。自身没有复杂的逻辑,通常以声明式方式构建。

ViewModel

状态保持及中介

接收来自View的用户输入,与Model交互以更新状态,并以可绑定的形式将状态提供给View。ViewModel与View分离,便于进行单元测试。

实际上,在大多数使用C#的开发环境中,如WPF、Xamarin、MAUI等,MVVM被采用为默认架构。

这不仅仅是惯例问题,而是因为这些框架本身假定了基于XAML和数据绑定的UI声明方式。

因此,在C#生态系统中,考虑到UI与逻辑的分离、状态同步的自动化以及测试便利性,MVVM几乎成为了“默认选项”。

开发者也自然而然地熟悉了ViewModel这一中间层,MVVM也因此成为了C#开发者中最广为人知的UI模式之一。

那么,什么时候应该使用MVVM?

  1. 使用XAML基础的UI时特别有效:
    在WPF、MAUI、Xamarin.Forms等框架中,基于数据绑定的UI结构很自然地会导向MVVM。

  2. 状态频繁变化且需要实时反映到UI时:
    例如表单状态、过滤条件、网络响应结果、有效性验证等场景中推荐使用。

  3. 希望通过可测试的ViewModel层验证业务逻辑时:
    ViewModel与View分离,使其易于进行单元测试。

  4. 设计师与开发者需要分工协作时:
    View(XAML)与ViewModel(C#)明确分离,从而提高了协作效率。

当然,MVVM并不总是最佳选择。当界面非常简单且状态仅有一两个时,反而使用代码后置或MVP结构可能会更加简洁。

虽然MVVM无疑是一个非常优秀的模式,但在开发简单的工具类应用时,它可能会引入不必要的复杂性,可以说是一把双刃剑。

 

(André Staltz)

MVI(Model-View-Intent)

2015年,André Staltz在JSConf Budapest上发布了Cycle.js框架。

MVI是一种以单向状态流为核心的现代UI架构,而Cycle.js则是将MVI概念提升到结构化层面的代表性框架。Cycle.js通过基于流(Stream)的方式完全抽象了Intent → Model → View → Intent的循环结构,并将副作用(Side Effect)分离到Driver中,尝试实现函数式UI的实际应用。

MVI不仅仅是一个简单的模式,更是改变了编程模型的历史性演变路径的一部分。

MVI的构成要素如下:

构成要素

角色

说明

Model (State)

UI的单一状态

表示当前View状态的单一不可变对象。所有UI状态都包含在这个State中,且状态始终保持完整形式。

View

基于状态渲染界面

根据状态(State)绘制UI,并将用户的交互转换为Intent传递出去。View是无状态的,以声明式方式运行。

Intent

定义用户事件

将用户的输入(如点击、输入等)语义化表达的对象。例如:AddTodoClicked、SearchTextChanged、RetryButtonPressed。

Reducer

状态转移函数

接收前一个状态和Intent,返回新的状态。这是一个纯函数,不包含副作用,仅计算状态。

Effect/Side Effect(可选)

外部系统调用等非确定性操作

如API调用、文件I/O、数据库访问等非纯操作被单独分离处理。在Redux或Elm中通常以Eff

虽然看起来复杂,但实际上可以更简单地理解:

Intent → Reducer → State → View → Intent 结构

通过单向状态流转,路径变得可预测,从而使得调试更加容易。

Swift、Kotlin StateFlow、Jetpack Compose等技术也很有名,但最重要的是,Flutter中经常使用这种技术。

MVI是继MVVM之后出现的一种基于单向状态流的声明式UI架构。

它通过单一不可变对象管理所有UI状态,并基于用户的意图(Intent)执行清晰的状态转移。

强调测试能力、状态可预测性和副作用分离的结构,已成为现代声明式UI框架中的事实标准。

那么,什么时候应该使用MVI?

  1. 当UI状态复杂且难以追踪时:
    通过将状态定义为单一对象,并通过意图(Intent)控制状态转移,使调试变得更加容易。

  2. 分离副作用以便更容易区分非确定性操作:
    通过分离副作用,调试变得更加直观。

然而,这些优点也表明,如果UI简单或未基于函数式编程(FP)进行思考,则可能会显得复杂。

也就是说,由于其自身具有一定的复杂性以及较高的学习曲线,随意引入该架构可能会面临困难。

“简单的事情应该简单,复杂的事情应该可能。” — Alan Kay

结语

架构就像一门没有语法的语言。

我们选择架构并不是因为它是我们的主观决定,而是所使用的技术、试图解决的问题以及所属组织的哲学对我们提出了结构上的要求。

从MVC、MVP、MVVM、MVI,到最近的VIPER、RIBs等,无数种架构存在。

所有这些架构都不过是对“如何更好地将人类的意图反映到代码中”这一古老问题的回答罢了。

本文旨在展示架构不仅仅是简单地应用,而是随着需求的变化不断演化的。

编程并不仅仅是记忆答案并复制粘贴的人的工作。

编程是一种思维方式,永远追求更好的答案。

架构不是理论,而仅仅是一个解决现场问题的工具。

即使今天选择了一种架构,明天又改变了自己的决定,只要这个判断是基于上下文考虑的,那这就是一个好的选择。

希望这篇文章能在你做出判断时提供一些帮助。

相关文章:

UI架构的历史与基础入门

本笔记的目的是通过一系列连贯的例子来探讨“事物-模型-视图-编辑器”这一隐喻。 这些例子都来自我的规划系统(planning system),用于解释上述四个概念。所有例子都已实现,但并未在本文描述的清晰类结构中实现。 这些隐喻对应于《…...

(三)MMA(KeyCloak身份服务器/OutBox Pattern)

文章目录 项目地址一、KeyCloak二、OutBox Pattern2.1 配置Common模块的OutBox1. OutboxMessage2. 数据库配置OutboxMessageConfiguration3. 创建Save前的EF拦截器4. 创建Quartz后台任务5. 配置后台任务6. 注册服务2.2 创建OutBox的消费者项目地址 教程作者:教程地址:代码仓库…...

【通用智能体】Playwright:跨浏览器自动化工具

Playwright:跨浏览器自动化工具 一、Playwright 是什么?二、应用场景及案例场景 1:端到端(E2E)测试场景 2:UI 自动化(表单批量提交)场景 3:页面截图与 PDF 生成场景 4&am…...

单片机设计_停车场车位管理系统(AT89C52、LCD1602)

想要更多项目私wo!!! 一、电路设计 此电路由AT89C52单片机和LCD1602液晶显示模块等器件组成。 二、运行结果 三、部分代码 #include <reg52.h> //调用单片机头文件 #define uchar unsigned char //无符号字符型 宏定义 变量范围0~255 #define uint unsigned…...

【android bluetooth 协议分析 01】【HCI 层介绍 5】【SetEventMask命令介绍】

1. HCI_Set_Event_Mask 命令作用 项目内容命令名HCI_Set_Event_MaskOCF0x0001作用主机通过设置 Event Mask 告诉控制器&#xff1a;我只对某些事件感兴趣&#xff0c;屏蔽其他事件&#xff0c;以减少中断。事件来源事件是 HCI 与主机之间通信的反馈机制&#xff0c;控制器通过…...

python打卡day29

类的装饰器 知识点回顾 类的装饰器装饰器思想的进一步理解&#xff1a;外部修改、动态类方法的定义&#xff1a;内部定义和外部定义 回顾一下&#xff0c;函数的装饰器是 &#xff1a;接收一个函数&#xff0c;返回一个修改后的函数。类也有修饰器&#xff0c;类装饰器本质上确…...

【数据结构】树状数组

树状数组 假设一个数可以 x x x可以被二进制分解成 x 2 i 1 2 i 2 . . . 2 i m x 2^{i_1} 2^{i_2} ... 2^{i_m} x2i1​2i2​...2im​&#xff0c;不妨设 i 1 > i 2 > . . . > i m i_1 > i_2 > ... > i_m i1​>i2​>...>im​&#xff0c;进…...

Java虚拟机 - JVM与Java体系结构

Java虚拟机 JVM与Java体系结构为什么要学习JVMJava与JVM简介Java 语言的核心特性JVM&#xff1a;Java 生态的基石JVM的架构模型基于栈的指令集架构&#xff08;Stack-Based&#xff09;基于寄存器的指令集架构&#xff08;Register-Based&#xff09;JVM生命周期 总结 JVM与Jav…...

翻译:20250518

翻译题 文章目录 翻译题一带一路中国结 一带一路 The “One Belt and One Road” Initiative aims to achieve win-win and shared development. China remains unchanged in its commitment to foster partnerships. China pursues an independent foreign policy of peace, …...

SparkSQL基本操作

以下是 Spark SQL 的基本操作总结&#xff0c;涵盖数据读取、转换、查询、写入等核心功能&#xff1a; 一、初始化 SparkSession scala import org.apache.spark.sql.SparkSession val spark SparkSession.builder() .appName("Spark SQL Demo") .master("…...

Ansible模块——文件内容修改

修改文件单行内容 ansible.builtin.lineinfile 可以按行修改文件内容&#xff0c;一次修改一行&#xff0c;支持正则表达式。 选项名 类型 默认值 描述 attributesstrnull 设置目标文件的 Linux 文件系统属性&#xff08;attribute bits&#xff09;&#xff0c;作用类似于…...

基于单片机路灯自动控制仪仿真设计

标题:基于单片机路灯自动控制仪仿真设计 内容:1.摘要 本设计旨在解决传统路灯控制方式效率低、能耗大的问题&#xff0c;开展了基于单片机的路灯自动控制仪仿真设计。采用单片机作为核心控制单元&#xff0c;结合光照传感器、时钟模块等硬件&#xff0c;运用相关软件进行编程和…...

Spring Web MVC————入门(3)

今天我们来一个大练习&#xff0c;我们要实现一个登录界面&#xff0c;登录进去了先获取到登录人信息&#xff0c;可以选择计算器和留言板两个功能&#xff0c;另外我们是学后端的&#xff0c;对于前端我们会些基础的就行了&#xff0c;知道ajax怎么用&#xff0c;知道怎么关联…...

拓展运算符与数组解构赋值的区别

拓展运算符与数组解构赋值是ES6中用于处理数组的两种不同的特性&#xff0c;它们有以下区别&#xff1a; 概念与作用 • 拓展运算符&#xff1a;主要用于将数组展开成一系列独立的元素&#xff0c;或者将多个数组合并为一个数组&#xff0c;以及在函数调用时将数组作为可变参…...

【Linux】第二十章 管理基本存储

目录 1. 对 Linux 磁盘进行分区时有哪两种方案&#xff1f;分别加以详细说明。 2. 简单说下创建MBR磁盘分区涉及哪几个步骤&#xff1f; 3. 创建GPT分区与创建MBR分区有什么不同&#xff1f; 4. 在创建分区时就会在分区上创建文件系统吗&#xff1f; 5. 如何持久挂载文件系…...

DeepSeek本地部署全攻略:从零搭建到Web可视化及数据训练

目录 1. 环境准备与硬件要求2. 安装Ollama框架3. 部署DeepSeek模型4. Web可视化配置5. 数据投喂与模型训练6. 进阶技巧与常见问题1. 环境准备与硬件要求 硬件配置建议 基础配置:16GB内存 + RTX 3060显卡(流畅运行7B参数模型)进阶配置:32GB内存 + RTX 4090显卡(支持14B模型…...

JavaScript性能优化实战(12):大型应用性能优化实战案例

在前面的系列文章中,我们探讨了各种JavaScript性能优化技术和策略。本篇将聚焦于实际的大型应用场景,通过真实案例展示如何综合运用这些技术,解决复杂应用中的性能挑战。 目录 电商平台首屏加载优化全流程复杂数据可视化应用性能优化案例在线协作工具的实时响应优化移动端W…...

前缀和——中心数组下标

此题我们不应局限于前缀和的模板&#xff0c;因为该中心下标把数组分为两个部分且每个部分都要求和&#xff0c;我们就一个再创建一个”后缀和” 定义两个数组f&#xff0c;g。f[i]表示[0,i-1]所有元素的和 f[i]f[i-1]nums[i-1];g[i]表示[i1,n-1]的和 g[i]g[i1]nums[i1];因为依…...

Java——创建多线程的四种方式

一、继承Thread 步骤 1.定义一个类继承Thread 2.重写run方法&#xff0c;在方法中设置线程任务&#xff08;此线程具体执行的代码&#xff09; 3.创建自定义线程类对象 4.调用Thread中的start方法&#xff0c;开启线程&#xff0c;jvm自动调用run方法 常用方法 void sta…...

广域网学习

PPPoE技术&#xff08;拨号上网&#xff09; PPPoE &#xff08; PPP over Ethernet &#xff0c;以太网承载 PPP 协议&#xff09;是一种把 PPP 帧封装到以太网帧中的链路层协议。 PPPoE 可以使以太网网络中的多台主机连接到远端的宽带接入服务器。 应用场景 PPPoE 组网结构采…...

inverse-design-of-grating-coupler-3d

一、设计和优化3D光栅耦合器 1.1 代码讲解 通过预定义的环形间距参数(distances数组),在FDTD中生成椭圆光栅结构,并通过用户交互确认几何正确性后,可进一步执行参数扫描优化。 # os:用于操作系统相关功能(如文件路径操作) import os import sys# lumapi:Lumerical 的…...

渗透测试流程-中篇

#作者&#xff1a;允砸儿 #日期&#xff1a;乙巳青蛇年 四月廿一&#xff08;2025年5月18日&#xff09; 今天笔者带大家继续学习&#xff0c;网安的知识比较杂且知识面很广&#xff0c;这一部分会介绍很多需要使用的工具。会用各种工具是做网安的基础&#xff0c;ok咱们继续…...

2026武汉门窗门业移门木门铝艺门智能锁展会3月国博举办

展出面积&#xff1a;60000㎡ 观众&#xff1a;80000人次 参展企业&#xff1a;800 专业活动&#xff1a;20 2026武汉门窗门业移门木门铝艺门智能锁展会3月国博举办 2026第二届中国武汉整装定制家居暨门窗装饰材料博览会/2026武汉建博会 时间&#xff1a;2026年3月20-22日 …...

如何用mockito+junit测试代码

Mockito 是一个流行的 Java 模拟测试框架&#xff0c;用于创建和管理测试中的模拟对象(mock objects)。它可以帮助开发者编写干净、可维护的单元测试&#xff0c;特别是在需要隔离被测组件与其他依赖项时。 目录 核心概念 1. 模拟对象(Mock Objects) 2. 打桩(Stubbing) 3. 验…...

31、魔法生物图鉴——React 19 Web Workers

一、守护神协议&#xff08;核心原理&#xff09; 1. 灵魂分裂术&#xff08;线程架构&#xff09; // 主组件中初始化Workerconst workerRef useRef(null);​useEffect(() > {workerRef.current new Worker(new URL(./creatureWorker.js, import.meta.url));workerRef.…...

洛谷题目:P4052 [JSOI2007] 文本生成器 题解 本题(极难)

个人介绍: 题目传送门: P4052 [JSOI2007] 文本生成器 - 洛谷 (luogu.com.cn) 前言: 这道题要求计算长度为 m 的文章中,至少包含一个给定单词的可读文章的数量,并且结果需要对 10007 取模。下面是小亦为大家逐步分析解题思路: 题目整体思路: 为了方便计算…...

【Linux】命令行参数和环境变量

目录 一、命令行参数 二、环境变量 &#xff08;一&#xff09;PATH &#xff08;二&#xff09;查看环境变量 &#xff08;三&#xff09;获取环境环境变量 &#xff08;四&#xff09;为什么要环境变量 &#xff08;五&#xff09;环境变量特点总结 &#xff08;1&am…...

AGI大模型(23):LangChain框架快速入门之LangChain介绍

1 什么是LangChain? LangChain是一个基于大语言模型用于构建端到端语言模型应用的框架,它提供了一系列工具、套件和接口,让开发者使用语言模型来实现各种复杂的任务,如文本到图像的生成、文档问答、聊天机器人等。 官网地址:https://python.langchain.com/docs/introduc…...

vmware虚拟机运行多个产生卡顿问题

最近在工作中使用电脑运行两个虚拟机&#xff0c;用来测试程序。运行的时候发现电脑会非常卡顿。导致调试工作进行到一半就会闪退卡死。 首先尝试的解决方案是开一个虚拟机&#xff0c;然后在windows上部署测试程序&#xff0c;后面发现操作很受限制。然后使用windows管…...

八股碎碎念01——HashMap原理

Java面试题周总结 HashMap HashMap实现原理 Java 1.7版本 在Java1.7中HashMap通过数组链表的方式实现&#xff0c;由于链表查询速度为O(n)&#xff0c;因此在插入大量元素后查询速度会明显降低。 Java 1.8版本 在Java1.8中对HashMap进行改进&#xff0c;采用数组链表/红黑…...

长篇小说《白鹿原》原著版本在当当网可购到

著名作家陈忠实所真实描写上世纪1959年、1960年、1961年我国三年饥荒时人吃人的长篇小说《白鹿原》原著版本&#xff0c;现能在当当网上购到&#xff0c;价格仅26元。特此推荐。 笔者是从那段不堪回首的饥饿历史中幸存下来的过来人&#xff0c;也是在改革开放初期的文艺复兴年代…...

ColorAid —— 一个面向设计师的色盲模拟工具开发记

我正在参加CodeBuddy「首席试玩官」内容创作大赛&#xff0c;本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 起因&#xff1a;CodeBuddy&#xff0c;说干就干 起初只是一个随口的想法——我想做一个“色盲辅助工具”&…...

对称加密与非对称加密在 JWT 中的应用详解

文章目录 对称加密与非对称加密在 JWT 中的应用详解引言对称加密与非对称加密概述对称加密&#xff08;Symmetric Encryption&#xff09;非对称加密&#xff08;Asymmetric Encryption&#xff09; 对称加密生成和验证 JWT 的过程生成 JWT&#xff08;HS256 示例&#xff09;验…...

Python 中 if 和 else 基础知识的详解和使用

一、基本语法结构 if 条件1:# 条件1 为真时执行的代码块 elif 条件2:# 条件1 不成立&#xff0c;条件2 成立时执行 else:# 所有条件都不成立时执行注意&#xff1a; elif 是“else if”的缩写&#xff0c;可以有多个&#xff1b;else 可省略&#xff1b;条件表达式必须是可以…...

学习黑客Active Directory 入门指南(三)

Active Directory 入门指南&#xff08;三&#xff09;&#xff1a;关键服务、用户与组管理 &#x1f91d;&#x1f4bb; 大家好&#xff01;欢迎来到 “Active Directory 入门指南” 系列的第三篇。在前两篇中&#xff0c;我们已经了解了AD的基本概念、逻辑结构&#xff08;对…...

10.9 LangChain LCEL革命:43%性能提升+声明式语法,AI开发效率飙升实战指南

LangChain 表达式语言(LCEL)架构解析:新一代链式编排引擎 关键词:LangChain Expression Language, Runnable 协议, 链式编排, 并行处理, 生产级应用开发 1. LCEL 设计理念与技术突破 LangChain Expression Language(LCEL)是 LangChain v0.3 的核心革命性升级,重新定义…...

一文读懂-嵌入式Ubuntu平台

现在直接在一些嵌入式Soc上移植ubuntu来用到产品上&#xff0c;刚开始感觉还挺臃肿的&#xff0c;后来细聊了下感觉还是有一定的优势。 ubuntu相信大家在熟悉不过了&#xff0c;几乎无处不在&#xff0c;小到咖啡机&#xff0c;大到火星车&#xff0c;为什么ubuntu如此广泛&am…...

centos7.9扩展已有分区空间

新增50G硬盘 分区 fdisk /dev/sdb Command (m for help): p #打印分区表Disk /dev/sdb: 53.7 GB, 53687091200 bytes, 104857600 sectors Units sectors of 1 * 512 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 byte…...

ubuntu22.04搭建ROS2环境

在 Ubuntu 22.04 上安装 ROS 2&#xff08;Humble Hawksbill&#xff09;时&#xff0c;针对国内网络问题&#xff0c;建议使用镜像源加速。以下是分步指南&#xff1a; 1. 更换 Ubuntu 系统源&#xff08;使用清华镜像&#xff09; sudo sed -i "shttp://.*archive.ubunt…...

java中sleep()和wait()暂停线程的区别

1. Thread.sleep() 所属类&#xff1a;它是Thread类的静态方法。作用&#xff1a;让当前正在执行的线程暂停指定的时间&#xff0c;在暂停期间&#xff0c;线程会一直持有对象锁&#xff08;也就是synchronized锁&#xff09;。中断响应&#xff1a;当线程处于sleep()状态时&a…...

printf函数参数与入栈顺序

01. printf()的核心功能 作用&#xff1a;将 格式化数据 输出到 标准输出&#xff08;stdout&#xff09;&#xff0c;支持多种数据类型和格式控制。 int printf(const char *format, ...);参数&#xff1a; format&#xff1a;格式字符串,字符串或%开头格式符...&#xff1a;…...

代码案例分析

以下是一个使用线性回归进行简单房价预测的机器学习代码案例分析&#xff1a; 代码示例 import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split # 生成一些示例数据…...

Baklib赋能企业知识资产AI化升级

AI驱动知识管理革新 在数字化转型浪潮中&#xff0c;企业知识管理的范式正经历AI技术的深度重构。传统知识库受限于静态存储与人工维护&#xff0c;而Baklib通过构建知识中台架构&#xff0c;将多模态数据处理与语义理解引擎深度融合&#xff0c;实现知识资产的动态聚合与智能…...

Leetcode 3552. Grid Teleportation Traversal

Leetcode 3552. Grid Teleportation Traversal 1. 解题思路2. 代码实现 题目链接&#xff1a;3552. Grid Teleportation Traversal 1. 解题思路 这一题的话核心就是一个广度优先遍历&#xff0c;我们只需要从原点开始&#xff0c;一点点考察其所能到达的位置&#xff0c;直至…...

【Bluedroid】蓝牙HID DEVICE 报告发送与电源管理源码解析

本文基于Android蓝牙协议栈代码&#xff0c;深度解析HID设备&#xff08;如键盘、鼠标&#xff09;从应用层发送输入报告到主机设备的完整流程&#xff0c;涵盖数据封装、通道选择、L2CAP传输、电源管理四大核心模块。通过函数调用链&#xff08;send_report → BTA_HdSendRepo…...

day15-进程管理

1. 概述 运行起来的软件就是进程&#xff0c;在内存中运行守护进程/服务&#xff1a;一直运行的进程 2. 僵尸进程 2.1. 僵尸进程zombie 当子进程比父进程先结束&#xff0c;而父进程又没有回收子进程&#xff0c;释放子进程占用的资源&#xff0c;此时子进程将成为一个僵尸…...

抖音视频下载工具 v1.1 自用分享

用免费的公益接口用AI写了个简单的抖音视频下载工具&#xff0c;自用的&#xff0c;不支持批量下载 内置两套API&#xff0c;解析失败会自动切换&#xff0c;支持视频预览播放&#xff0c;视频截图等操作 使用方法也很简单&#xff1a; 软件打开后会监听粘贴板&#xff0c;当检…...

46、什么是Windows服务,它的⽣命周期与标准的EXE程序有什么不同?

Windows服务是一种在Windows操作系统后台运行的特殊应用程序&#xff0c;与标准的EXE程序相比&#xff0c;其生命周期在启动方式、运行持续性、用户交互、运行账户、管理方式、进程状态及开发要求等方面存在显著差异。以下是对Windows服务及其与标准EXE程序生命周期差异的详细分…...

用 UniApp 构建习惯打卡 App —— HabitLoop 开发记

我正在参加CodeBuddy「首席试玩官」内容创作大赛&#xff0c;本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 当我脑海中突然冒出一个念头&#xff1a;“做一个自己能每天打卡的习惯 App 吧”&#xff0c;我立刻打开了 Cod…...

NB-IoT技术深度解析:部署模式与节能机制全指南

知识点1【NB-IoT的介绍】 NB-IoT 是指Narrow Band Internet of Things&#xff0c;聚集于低功耗窄带宽广域物联网。 1、License介绍 “有牌照”&#xff08;license&#xff09;频谱&#xff0c;指的是政府或者监管机构通过拍卖&#xff0c;划拨等方式&#xff0c;授予给各个…...