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

【CodeMirror】系列(二)官网示例(六)自动补全、边栏

一、自动补全

@codemirror/autocomplete 包提供了在编辑器中显示输入建议的功能。这个示例展示了如何启用该功能以及如何编写自己的补全来源。
自动补全是通过在编辑器的配置项中加入 autocompletion 扩展实现的。有些语言包支持内置的自动补全功能,比如HTML包。
默认情况下,当用户键入内容的时候都会自动激活自动补全,查找自动补全项。但你也可以通过配置,只有通过命令command激活自动补全。
扩展显示的补全建议来自于一个或多个自动补全源 CompletionSource。这些源是函数,它们接收一个补全上下文的对象 CompletionContext,并返回一个描述正在补全的范围及可显示选项的对象。补全源可以异步运行,通过返回一个 Promise 来实现。
将补全源连接到编辑器的最简单方式是使用 override 选项。你可以在配置自动补全的扩展时,使用这个选项指定你的补全源。
例如下面代码,先定义一个自动补全源函数:

// 导入 CompletionContext 类型,以便在补全源函数中使用
import {CompletionContext} from "@codemirror/autocomplete"// 自定义的补全函数,接受一个 CompletionContext 作为参数
function myCompletions(context: CompletionContext) {// 使用 matchBefore 方法匹配光标前的单词,返回匹配的范围let word = context.matchBefore(/\w*/)// 检查匹配的范围是否为空,并且检查不是显式调用的补全if (word.from == word.to && !context.explicit) return null // 返回 null 表示没有补全建议// 返回补全建议return {from: word.from, // 返回补全建议的起始位置options: [ // 返回的补全选项列表{label: "match", type: "keyword"}, // 第一个补全项,类型为关键字{label: "hello", type: "variable", info: "(World)"}, // 第二个补全项,类型为变量,附加信息为 "(World)"{label: "magic", type: "text", apply: "⠁⭒*.✩.*⭒⠁", detail: "macro"} // 第三个补全项,类型为文本,附加信息和应用字符串]}
}

看一下第三项,我们输入 m 的时候,会显示 magic 的提示,并且会通过斜体显示这一项的 detail 内容
在这里插入图片描述
使用 enter 应用这一项自动补全之后,代码会被替换成这一项的 apply 属性:
在这里插入图片描述
这是提供补全的一种非常粗略的方法,实际上并没有真正考虑编辑上下文。但它展示了补全函数必须执行的基本操作。

  • 确定补全的文本范围:首先,需要找出光标前面可以补全的文本部分。这里使用 matchBefore 方法结合正则表达式来确定该部分文本。
  • 检查补全是否合适:然后要检查补全请求是否合适。explicit 标志表示补全是通过命令显式启动的还是通过输入隐式触发的。一般情况下,只有当补全是显式触发,或者补全位置在某个可以补全的结构之后时,才应该返回补全结果。
  • 构建补全列表并返回:构建一个补全选项列表,并返回它以及补全的起始位置。(结束位置默认为补全发生的位置。)
  • 补全对象的结构:补全本身是一个对象,包含一个 label 属性,提供了在选项列表中显示的文本以及用户选择补全时插入的文本。

默认情况下,补全列表只显示标签。通常你还会想提供一个 type 属性,用于确定补全旁边显示的图标。detail 可以用来显示一个简短的字符串,info 则用于显示更长的文本,当补全被选择时,该长文本会在列表旁边的窗口中展现。
自定义补全选择的行为:如果你想覆盖选择补全时的行为,可以使用 apply 属性。它可以是一个字符串,用来替换补全范围,或者是一个函数,调用时会执行特定的操作。
处理多个语言的补全源:当你作为一个通用扩展提供补全源时,或者处理混合语言文档时,设置全局源并不现实。当没有给出 override 时,插件会使用 EditorState.languageDataAt 方法通过名称 "autocomplete" 查询适合该语言的补全函数。要注册这些函数,你需要在语言对象中使用数据特征。例如,可以在你的状态配置中包含以下代码:

myLanguage.data.of({autocomplete: myCompletions
})

你也可以直接在这个属性中包含一个补全对象的数组,这样库会简单地使用这些对象(通过 completeFromList 包装)作为补全源。
上面提到的简单补全源不需要根据输入内容来过滤补全选项——插件会处理这个问题。它使用一种模糊匹配的方式来过滤和排序与当前输入文本匹配的补全选项,并会高亮显示每个补全项中与输入匹配的字母。

  • 影响排序:如果你想影响补全的排序,可以为补全对象设置一个 boost 属性,来增加或减少它们的匹配分数。这样,就可以让某些补全项在列表中更突出,或者让某些项排在后面。
  • 自定义过滤与排序:如果你确实希望自己过滤和排序补全选项,可以在返回的对象中包含 filter: false 属性,这样就会禁用内置的过滤功能。在这种情况下,你需要手动处理补全项的过滤和排序逻辑。

有些补全源需要在每次按键时重新计算结果,但对于许多补全源来说,这样做是不必要且低效的。它们会针对某个特定的结构返回完整的补全列表,只要用户在这个结构内输入(或删除)文本,就可以使用同一份列表(过滤当前输入)来填充补全列表。

因此,强烈建议在你的补全结果中提供一个 validFor 属性。这个属性应该包含一个函数或正则表达式,用于告诉扩展,只要更新后的输入(结果的 from 属性与补全点之间的范围)与这个值匹配,就可以继续使用这份补全列表。

在上面的 myCompletions 函数中,由于所有的补全项都是简单的单词,像 validFor: /^\w*$/ 这样的值是合适的。

为了使补全源更智能,检查补全点周围的语法树是非常有用的,这可以帮助我们更好地理解正在补全的结构类型。
例如,下面这个补全源专门用于 JavaScript,可以在块注释中补全(部分)JSDoc 标签。

// 从 @codemirror/language 导入语法树工具
import {syntaxTree} from "@codemirror/language"// 定义可补全的 JSDoc 标签选项
const tagOptions = ["constructor", "deprecated", "link", "param", "returns", "type"
].map(tag => ({label: "@" + tag, type: "keyword"})) // 将标签转换为补全对象格式// 定义补全 JSDoc 标签的函数
function completeJSDoc(context: CompletionContext) {// 使用语法树解析器获取光标之前的语法节点let nodeBefore = syntaxTree(context.state).resolveInner(context.pos, -1)// 检查当前节点是否是块注释,并且判断开始部分是否为 "/**"if (nodeBefore.name != "BlockComment" ||context.state.sliceDoc(nodeBefore.from, nodeBefore.from + 3) != "/**")return null // 如果条件不满足,返回 null,表示没有补全建议// 获取光标之前的文本let textBefore = context.state.sliceDoc(nodeBefore.from, context.pos)// 使用正则表达式检查光标前是否有 JSDoc 标签let tagBefore = /@\w*$/.exec(textBefore)// 如果没有找到标签且补全不是显式请求,返回 nullif (!tagBefore && !context.explicit) return null// 返回补全建议return {// 确定补全起始位置,如果找到了标签,则从标签的位置开始补全from: tagBefore ? nodeBefore.from + tagBefore.index : context.pos,// 选项是之前定义的可补全 JSDoc 标签options: tagOptions,// 定义有效输入的正则表达式,当输入为 "@标签" 或者为空时有效validFor: /^(@\w*)?$/}
}

您现在可以使用这样的扩展来为JavaScript内容启用此完成源,会显示 JSDoc 关键词的自动补全提示。
在这里插入图片描述

二、边栏

视图模块提供了为编辑器添加边栏(代码前面的垂直条形)功能。边栏的最简单用法就是在配置中简单地使用 lineNumbers(),这样就可以获得一个行号边栏。但这个模块也可以在你想定义自己的边栏并在其中显示自定义控件时提供帮助。

(一)添加边栏

从概念上讲,编辑器可以并排显示一组边栏(gutters),每个边栏都有自己的样式和内容(尽管通常希望保持它们的默认样式,以便与其他边栏融为一体,看起来像一个大边栏)。对于每一行,每个边栏可以显示一些内容。行号边栏显然会显示行号。
要添加一个边栏,调用 gutter 函数,并将结果包含在你的状态配置中。该扩展相对于其他边栏扩展的位置决定了边栏的顺序。所以,例如,下面这段代码会将我们的边栏放在行号之后:

extensions: [lineNumbers(), gutter({class: "cm-mygutter"})]

不过,除非 cm-mygutter CSS 类设置了最小宽度,否则你将看不到这样的边栏——它会只是一个空元素(在 CSS flexbox 中),浏览器会将其折叠。
在边栏中放置内容

要在边栏中显示内容,我们可以使用 lineMarker 选项,该选项会被调用以确定每可见行上要显示的内容,或者使用 markers 选项,它允许你构建一个持久的标记集(使用在装饰中使用的相同范围集合数据结构)以在边栏中显示。

与装饰一样,边栏标记由轻量级的不可变值表示,这些值知道如何将自己渲染为 DOM 节点,以允许更新以声明的方式表示,而不必在每次交易中重新创建大量的 DOM 节点。边栏标记还可以向边栏元素添加 CSS 类。

示例代码
以下代码定义了两个边栏,一个在每个空行上显示一个 ø 符号,另一个通过点击该边栏允许你切换每一行的“断点”标记。第一个很简单:

// 从 @codemirror/view 导入所需的模块
import {EditorView, gutter, GutterMarker} from "@codemirror/view"// 定义一个空行标记类,继承自 GutterMarker
const emptyMarker = new class extends GutterMarker {// 定义如何将标记渲染为 DOM 元素toDOM() { return document.createTextNode("ø") // 返回一个文本节点,内容为 "ø"}
}// 创建一个边栏,用于在空行上显示特定标记
const emptyLineGutter = gutter({// 定义行标记函数,根据行的起始和结束位置来决定显示内容lineMarker(view, line) {// 如果行的起始位置和结束位置相同,表示这是一个空行return line.from == line.to ? emptyMarker : null // 如果是空行,返回空标记,否则返回 null},// 设定初始的间隔标记initialSpacer: () => emptyMarker // 默认间隔使用空标记
})

为了避免空边栏根本不显示的问题,边栏允许你配置一个“间隔”元素,该元素以隐形的方式渲染在边栏中,以设置其最小宽度。这通常比用 CSS 设置显式宽度并确保其覆盖预期内容更容易。
lineMarker 选项检查该行是否为零长度,如果是,返回我们的标记。

断点边栏则稍微复杂一些。它需要跟踪状态(即断点的位置),为此我们使用一个状态字段,并通过状态效果来更新它。

// 从 @codemirror/state 导入必要的模块
import {StateField, StateEffect, RangeSet} from "@codemirror/state"// 定义断点效果,描述断点的位置和状态(开启/关闭)
const breakpointEffect = StateEffect.define<{pos: number, on: boolean}>({// 定义在应用映射时如何迁移效果值map: (val, mapping) => ({pos: mapping.mapPos(val.pos), on: val.on}) // 映射位置,保持状态不变
})// 定义断点状态字段,使用 RangeSet 来存储断点标记
const breakpointState = StateField.define<RangeSet<GutterMarker>>({// 创建函数,初始化为空的 RangeSetcreate() { return RangeSet.empty },// 更新函数,处理状态变化update(set, transaction) {// 根据事务的变化映射现有的断点集set = set.map(transaction.changes)// 遍历事务的效果for (let e of transaction.effects) {if (e.is(breakpointEffect)) { // 如果效果是断点效果if (e.value.on) // 如果断点状态是开启// 在指定位置添加断点标记set = set.update({add: [breakpointMarker.range(e.value.pos)]})else // 如果断点状态是关闭// 移除指定位置的断点标记set = set.update({filter: from => from != e.value.pos})}}return set // 返回更新后的断点集}
})// 切换断点的状态函数
function toggleBreakpoint(view: EditorView, pos: number) {// 获取当前状态中的断点let breakpoints = view.state.field(breakpointState)let hasBreakpoint = false// 检查指定位置是否已有断点breakpoints.between(pos, pos, () => {hasBreakpoint = true})// 调度一个效果来切换断点状态view.dispatch({// 发送断点效果,位置和状态(开启或关闭)effects: breakpointEffect.of({pos, on: !hasBreakpoint})})
}

状态起始时为空,当发生事务时,它会通过变更(如果有的话)来映射断点的位置,并查找添加或移除断点的效果,根据需要调整断点集合。
breakpointGutter 扩展将这个状态字段与边栏结合起来,并为该边栏添加一些样式。

// 定义一个断点标记类,继承自 GutterMarker
const breakpointMarker = new class extends GutterMarker {// 定义如何将标记渲染为 DOM 元素toDOM() { return document.createTextNode("💔") // 返回一个文本节点,显示为 "💔" 符号}
}// 创建断点边栏的扩展,包括状态字段、边栏设置和样式
const breakpointGutter = [breakpointState, // 包含断点状态字段// 定义边栏,配置其外观和行为gutter({class: "cm-breakpoint-gutter", // 设置边栏的 CSS 类名markers: v => v.state.field(breakpointState), // 设置边栏中显示的标记为当前状态字段中的断点集合initialSpacer: () => breakpointMarker, // 使用断点标记作为初始间隔,确保边栏有最小宽度domEventHandlers: {// 定义鼠标按下事件处理mousedown(view, line) {toggleBreakpoint(view, line.from) // 切换鼠标点击位置的断点状态return true // 返回 true,表示事件已被处理}}}),// 定义边栏的基础主题样式EditorView.baseTheme({".cm-breakpoint-gutter .cm-gutterElement": {color: "red", // 设置断点边栏中标记的颜色为红色paddingLeft: "5px", // 设置左侧内边距cursor: "default" // 设置鼠标悬停时的光标样式}})
]

domEventHandlers 选项允许您为该边栏指定事件处理程序。在这里,我们设置了一个 mousedown 事件处理程序,用于切换用户点击的行的断点。
以下是一个带有断点边栏的编辑器示例,断点边栏位于行号之前,空行边栏在其之后。这样的布局设计可以帮助用户直观地查看代码的状态和结构:
在这里插入图片描述

(二)自定义行号间距

lineNumbers 函数同样接受配置参数,允许您添加事件处理程序或自定义行号的显示方式。
以下示例展示了如何自定义行号的格式,通过 formatNumber 选项将行号格式化为十六进制字符串:

const hexLineNumbers = lineNumbers({formatNumber: n => n.toString(16)
})

此外,您还可以向行号边栏添加标记,这样可以在受到影响的行上替代默认的行号。这个功能通过 lineNumberMarkers 面貌实现,类似于在自定义边栏中使用的标记,但可以通过任何扩展提供,而不是仅仅针对单个边栏进行配置。
下面是一个示例,演示如何在行号边栏中使用标记:

// 定义一个行号标记类,继承自 GutterMarker
const specialLineMarker = new class extends GutterMarker {toDOM() { return document.createTextNode("★") // 返回一个特殊字符作为行号的替代}
}// 在某些行添加行号标记
const lineNumberMarkers = StateField.define<RangeSet<GutterMarker>>({create() { return RangeSet.empty; }, // 初始化为空的标记集合update(set, transaction) {set = set.map(transaction.changes); // 映射变更for (let e of transaction.effects) {if (e.is(specialEffect)) { // 如果效果是特殊效果// 根据效果的状态决定是否添加标记set = e.value.on ? set.update({add: [specialLineMarker.range(e.value.pos)]}) : set.update({filter: from => from !== e.value.pos});}}return set; // 返回更新后的标记集合}
});// 定义行号边栏,集成标记
const numberedGutter = [hexLineNumbers, // 使用十六进制行号格式gutter({class: "cm-line-number-gutter", // 设置边栏的 CSS 类名markers: v => v.state.field(lineNumberMarkers), // 从状态字段获取行号标记})
];

相关文章:

【CodeMirror】系列(二)官网示例(六)自动补全、边栏

一、自动补全 codemirror/autocomplete 包提供了在编辑器中显示输入建议的功能。这个示例展示了如何启用该功能以及如何编写自己的补全来源。 自动补全是通过在编辑器的配置项中加入 autocompletion 扩展实现的。有些语言包支持内置的自动补全功能&#xff0c;比如HTML包。 默…...

CSS 表格样式学习笔记

CSS 提供了强大的工具来美化和定制 HTML 表格的外观。通过合理使用 CSS 属性&#xff0c;可以使表格更加美观、易读且功能强大。以下是对 CSS 表格样式的详细学习笔记。 一、表格边框 1. 单独边框 默认情况下&#xff0c;表格的 <table>、<th> 和 <td> 元…...

简单记录一下Android四大组件

1、Android Layout 1.1、LinearLayout 线性布局&#xff0c;子控件按照水平或垂直的方向依次排列&#xff0c;排列方向通过属性android:orientation控制&#xff0c;horizontal为水平排列&#xff0c;vertical为垂直排列。对于同一水平线上的控件&#xff0c;可以调整它的lay…...

在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布

2025年4月11日&#xff0c;人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括&#xff1a;数据源方面&#xff0c;Oracle数据源支持获取和查询物化视图&#xff1b;图表方面&#xff0c;在线地图支持天地图、腾讯地图&#xff1b;新增子弹图&…...

【图像处理基石】什么是通透感?

一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现&#xff0c;具体表现为&#xff1a; 色彩鲜明&#xff1a;颜色纯净且饱和度适中&#xff0c;无灰暗或浑浊感&#xff1b;层次分明&#xff1a;明暗过渡自然&#xff0c;光…...

猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新

前情提要 家里养了三只猫咪&#xff0c;其中一只布偶猫经常出入厕所。但因为平时忙于学业&#xff0c;没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关&#xff0c;频繁如厕可能是泌尿问题&#xff0c;停留过久也可能是便秘或不适。为了更科学地了解牠的如…...

NoSQL入门指南:Redis与MongoDB的Java实战

一、为什么需要NoSQL&#xff1f; 在传统SQL数据库中&#xff0c;数据必须严格遵循预定义的表结构&#xff0c;就像把所有物品整齐摆放在固定尺寸的货架上。而NoSQL&#xff08;Not Only SQL&#xff09;数据库则像一个灵活的储物间&#xff0c;允许存储各种类型的数据&#x…...

游戏引擎学习第223天

回顾 今天我们正在进行过场动画序列的制作&#xff0c;因此我想深入探讨这个部分。昨天&#xff0c;我们暂时停止了过场动画的制作&#xff0c;距离最终结局还有一些内容没有完成。今天的目标是继续完成这些内容。 我们已经制作了一个过场动画的系列&#xff0c;并把它们集中…...

【redis进阶二】分布式系统之主从复制结构(1)

目录 一 为什么要有分布式系统&#xff1f; 二 分布式系统涉及到的非常关键的问题&#xff1a;单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制&#xff0c;要想配…...

(自用)若依生成左树右表

第一步&#xff1a; 在数据库创建树表和单表&#xff1a; SQL命令&#xff1a; 商品表 CREATE TABLE products (product_id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(255) , price DECIMAL(10, 2) , stock INT NOT NULL, category_id INT NOT NULL); 商品分类…...

VectorBT量化入门系列:第六章 VectorBT实战案例:机器学习预测策略

VectorBT量化入门系列&#xff1a;第六章 VectorBT实战案例&#xff1a;机器学习预测策略 本教程专为中高级开发者设计&#xff0c;系统讲解VectorBT技术在量化交易中的应用。通过结合Tushare数据源和TA-Lib技术指标&#xff0c;深度探索策略开发、回测优化与风险评估的核心方法…...

5G网络下客户端数据业务掉线频繁

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;客户端的日志&#xff0c;和界面在待机状态下&#xff08;即没有做通话等业务操作&#xff09;&#xff0c;会频繁提示“离线”。 主要先看有没有丢网&#xff0c;UL BLER有没有问题。确认没有问题。看到业务信道释…...

CPU(中央处理器)

一、CPU的定义与核心作用 CPU 是计算机的核心部件&#xff0c;负责 解释并执行指令、协调各硬件资源 以及 完成数据处理&#xff0c;其性能直接影响计算机的整体效率。 核心功能&#xff1a; 从内存中读取指令并译码。执行算术逻辑运算。控制数据在寄存器、内存和I/O设备间的…...

Java从入门到“放弃”(精通)之旅——程序逻辑控制④

Java从入门到“放弃”&#xff08;精通&#xff09;之旅&#x1f680;&#xff1a;程序逻辑的完美理解 一、开篇&#xff1a;程序员的"人生选择" 曾经的我&#xff0c;生活就像一段顺序执行的代码&#xff1a; System.out.println("早上8:00起床"); Syste…...

[Dify] 基于明道云实现金融业务中的Confirmation生成功能

在金融业务的日常流程中,交易记录的处理不仅涉及数据录入、流程审批,更重要的是其最终输出形式——交易确认函(Confirmation)。本文将介绍如何通过明道云的打印模板功能,快速、准确地生成符合业务需求的交易Confirmation,提升工作效率与合规性。 为什么需要Confirmation?…...

Qt安卓设备上怎么安装两个不同的Qt应用?

在安卓设备上安装两个不同的Qt应用时&#xff0c;需要确保这两个应用在安卓系统中被视为独立的应用程序。以下是详细的步骤和注意事项&#xff0c;帮助你实现这一目标&#xff1a; 一、修改应用的包名 安卓系统通过应用的包名&#xff08;package属性&#xff09;来区分不同的…...

Prompt工程提示词(1-6章)

White graces&#xff1a;个人主页 &#x1f439;今日诗词:怅望千秋一洒泪&#xff0c;萧条异代不同时&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; 目录 &#x1f680; 第…...

0基础 | 硬件滤波 C、RC、LC、π型

一、滤波概念 &#xff08;一&#xff09;滤波定义 滤波是将信号中特定波段频率滤除的操作&#xff0c;是抑制和防止干扰的重要措施。通过滤波器实现对特定频率成分的筛选&#xff0c;确保目标信号的纯净度&#xff0c;提升系统稳定性。 &#xff08;二&#xff09;滤波器分…...

C++ 编程指南34 - C++ 中 ABI 不兼容的典型情形

一:概述 ABI(Application Binary Interface)是二进制层面的接口规范。如果一个库的 ABI 发生了变化,那么基于旧 ABI 编译的代码可能在运行时与新库不兼容(即使接口名字都一样也不行)。那么在C++中编程中,哪些情形会导致ABI不兼容呢?下面逐一列举一下。 二:C++ 中 ABI…...

【动态规划】深入动态规划:背包问题

文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题&#xff0c;怎么解决算法中的背包问题呢&#xff1f; 背包问题 (Knapsack problem) 是⼀种组…...

NVIDIA AI Aerial

NVIDIA AI Aerial 适用于无线研发的 NVIDIA AI Aerial 基础模组Aerial CUDA 加速 RANAerial Omniverse 数字孪生Aerial AI 无线电框架 用例构建商业 5G 网络加速 5G生成式 AI 和 5G 数据中心 加速 6G 研究基于云的工具 优势100% 软件定义通过部署在数字孪生中进行测试6G 标准化…...

计算机视觉6——相机基础

一、数字相机基本工作原理 &#xff08;一&#xff09;像素概念 数字相机生成二维图像&#xff0c;图像最小单元是像素。 每个像素对应三维世界中某个特定方向&#xff0c;像素值衡量某一时刻来自该方向的光照强度/颜色 &#xff0c;即相机度量每个像素的光照情况并保存到对…...

入门到精通,C语言十大经典程序

以下是十个经典的C语言程序示例&#xff0c;这些程序涵盖了从基础到稍复杂的应用场景&#xff0c;适合初学者和有一定基础的开发者学习和参考。 1. Hello, World! 这是每个初学者学习编程时的第一个程序&#xff0c;用于验证开发环境是否正确配置。 #include <stdio.h>…...

【毕设】Python构建基于TMDB电影推荐系统

个性化电影推荐系统 这是一个基于FastAPI开发的现代化电影推荐系统&#xff0c;结合了协同过滤和深度学习技术&#xff0c;为用户提供个性化的电影推荐服务。 主要功能 &#x1f3af; 个性化电影推荐&#x1f50d; 电影搜索与浏览⭐ 电影评分系统&#x1f49d; 收藏夹功能&a…...

嵌入式常见概念的介绍

目录 一、MCU、MPU、ARM &#xff08;一&#xff09;MCU&#xff08;微控制器&#xff09; &#xff08;二&#xff09;MPU&#xff08;微处理器&#xff09; &#xff08;三&#xff09;ARM&#xff08;架构&#xff09; 二、DSP &#xff08;一&#xff09;数字信号处理…...

富兴号:拨云见日,打造普洱品质典范

在高端普洱茶市场的混沌格局中&#xff0c;价格与品质的天平严重失衡&#xff0c;消费者往往深陷 “高价却难觅好茶” 的困境。而新兴品牌富兴号强势崛起&#xff0c;奋力冲破这一迷局&#xff0c;致力于重塑 “号级茶” 的卓越品质&#xff0c;为茶叶赋予珍贵的品鉴与收藏价值…...

【WORD】批量将doc转为docx

具体步骤进行&#xff1a; 打开Word文档&#xff0c;按下AltF11快捷键&#xff0c;打开VBA编辑器。在VBA编辑器中&#xff0c;左侧的“项目资源管理器”窗口会显示当前打开的Word文档相关项目。找到您要添加代码的文档项目&#xff08;通常以文档名称命名&#xff09;&#xf…...

Linux内存管理架构(1)

0.内存空间架构 1.用户空间 在 Linux 系统中&#xff0c;应用程序通过 malloc() 申请内存&#xff0c;并通过 free() 释放内存时&#xff0c;底层的内存管理是由 glibc&#xff08;GNU C Library&#xff09;中的内存分配器实现的。glibc 的内存分配器负责与操作系统的内核交互…...

Ubuntu 各个常见长期支持历史版本与代号

文章目录 1. Ubuntu 历史版本与代号2. 查看当前系统版本 在 Ubuntu 操作系统里&#xff0c;每个版本都有一个别具特色的名字。该名字由一个形容词与一个动物名称构成&#xff0c;且形容词和动物名称的首字母是一样的。例如 “Warty Warthog&#xff08;长疣的疣猪&#xff09;”…...

信息安全管理与评估2021年国赛正式卷答案截图以及十套国赛卷

2021年全国职业院校技能大赛高职组 “信息安全管理与评估”赛项 任务书1 赛项时间 共计X小时。 赛项信息 赛项内容 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 平台搭建与安全设备配置防护 任务1 网络平台搭建 任务2 网络安全设备配置与防护 第二…...

在线上定位1G日志文件中的异常信息时,我这样做合适吗

1G级线上日志文件 的异常定位系统性方案 一、快速定位流程 import datetime import randomdef generate_springboot_log(file_name, file_size_gb):# 模拟Spring Boot日志内容log_levels ["INFO", "DEBUG", "WARNING", "ERROR"]cla…...

Transformer模型中的两种掩码

模型训练通常使用 批处理batch来提升训练效率。而实际中Transformer的输入序列&#xff08;如句子、文本片段&#xff09;长度往往不一致。为了让这些样本可以组成一个统一的形状 [B, T] 的张量给GPU进行并行计算提高效率&#xff0c;需要将较短的序列填充&#xff08;pad&…...

FastAPI-MPC正式发布,新的AI敏捷开发利器

FastAPI-MCP发布&#xff1a;零配置构建微服务控制平台的革命性实践 引言 在微服务架构日益复杂的今天&#xff0c;如何快速实现API接口的标准化管理与可视化控制成为开发者面临的核心挑战。近日&#xff0c;FastAPI-MCP工具的发布引发了技术社区广泛关注&#xff0c;其宣称能…...

Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!

全文目录&#xff1a; 开篇语前言一、责任链模式概述责任链模式的组成部分&#xff1a; 二、责任链模式的核心优势三、使用责任链模式解耦复杂接口1. 定义 Handler 接口2. 实现具体的 Handler3. 创建订单对象4. 在 Spring Boot 中使用责任链模式5. 配置责任链6. 客户端调用 四、…...

学习笔记八——内存管理相关

&#x1f4d8; 目录 内存结构基础&#xff1a;栈、堆、数据段Rust 的内存管理机制&#xff08;对比 C/C、Java&#xff09;Drop&#xff1a;Rust 的自动清理机制Deref&#xff1a;为什么 *x 能访问结构体内部值Rc&#xff1a;多个变量“共享一个资源”怎么办&#xff1f;Weak&…...

Deepseek Bart模型相比Bert的优势

BART&#xff08;Bidirectional and Auto-Regressive Transformers&#xff09;与BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;虽然均基于Transformer架构&#xff0c;但在模型设计、任务适配性和应用场景上存在显著差异。以下是BART…...

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM)

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数&#xff08;决策树、逻辑回归、KNN、SVM&#xff09; 问题模板解题思路1. 导入必要的库2. 加载数据3. 划分训练集和测试集4. 数据预处理5. 定义算法及其参数6. 存储算法和对应指标7. 训练模型并计算指标8. 找…...

达梦数据库-学习-20-慢SQL优化之CTE等价改写

目录 一、环境信息 二、介绍 三、优化过程 1、原始SQL 2、源SQL执行时间 3、原始SQL执行计划 4、拆分问题 5、过滤性 6、统计信息收集 7、改写思路一 8、改写SQL一 9、改写SQL一的执行计划 10、改写思路二 11、改写SQL二 12、改写SQL二的执行计划 一、环境信息…...

软件生命周期模型:瀑布模型、螺旋模型、迭代模型、敏捷开发、增量模型、快速原型模型

目录 1.软件生命周期 2.软件生命周期模型 2.1瀑布模型 缺点【存在的问题】&#xff1a; 优点&#xff1a; 2.2 螺旋模型 特点&#xff1a; 2.3 迭代模型 优点&#xff1a; 2.4 敏捷开发 2.5 增量模型 增量模型一般和迭代模型一起使用&#xff1a; 2.6 快速原型模型…...

AI agents系列之全面介绍

随着大型语言模型(LLMs)的出现,人工智能(AI)取得了巨大的飞跃。这些强大的系统彻底改变了自然语言处理,但当它们与代理能力结合时,才真正释放出潜力——能够自主地推理、规划和行动。这就是LLM代理大显身手的地方,它们代表了我们与AI交互以及利用AI的方式的范式转变。 …...

Ubuntu 下通过 Docker 部署 WordPress 服务器

最近想恢复写私人博客的习惯&#xff0c;准备搭建一个wordpress。 在这篇博客中&#xff0c;我将记录如何在 Ubuntu 环境下通过 Docker 部署一个 WordPress 服务器。WordPress 是一个流行的内容管理系统&#xff08;CMS&#xff09;&#xff0c;它让用户能够轻松地创建和管理网…...

Elasticsearch生态

目录 Elasticsearch核心概念 Elasticsearch实现全文检索的原理 Elasticsearch打分规则 常用的查询语法 ES数据同步方案 Elasticsearch生态非常丰富&#xff0c;包含了一系列工具和功能&#xff0c;帮助用户处理、分析和可视化数据&#xff0c;Elastic Stack是其核心部分&a…...

idea配置spring MVC项目启动(maven配置完后)

springmvc项目在idea中配置启动总结&#xff0c;下面的内容是在maven配置好后进行的。 配置 Tomcat 服务器 添加 Tomcat 到 IDEA&#xff1a; File → Settings → Build, Execution, Deployment → Application Servers → 点击 → 选择 Tomcat Server。 指定 Tomcat 安装目…...

大模型微调数据集怎么搞?基于easydataset实现文档转换问答对json数据集!

微调的难点之一在与数据集。本文介绍一种将文档转换为问答数据集的方法&#xff0c;超级快&#xff01; 上图左侧是我的原文档&#xff0c;右侧是我基于文档生成的数据集。 原理是通过将文档片段发送给ollama本地模型&#xff0c;然后本地模型生成有关问题&#xff0c;并基于文…...

【排序算法】快速排序

目录 一、递归版本 1.1 hoare版本 问题1&#xff1a;为什么left 和 right指定的数据和key值相等时不能交换&#xff1f; 问题2&#xff1a;为什么跳出循环后right位置的值⼀定不⼤于key&#xff1f; 1.2 挖坑法 1.3 lomuto前后指针版本 二、快排优化 2.1 时间复杂度的计算 2.1.…...

爬虫:IP代理

什么是代理 代理服务器 代理服务器的作用 就是用来转发请求和响应 在爬虫中为何需要使用代理&#xff1f; 有些时候&#xff0c;需要对网站服务器发起高频的请求&#xff0c;网站的服务器会检测到这样的异常现象&#xff0c;则会讲请求对应机器的ip地址加入黑名单&#xff…...

JUC.atomic原子操作类原理分析

摘要 多线程场景下共享变量原子性操作除了可以使用Java自带的synchronized关键字以及AQS锁实现线程同步外&#xff0c;java.util.concurrent.atomic 包下提供了对基本类型封装类(AtomicBoolean|AtomicLong|AtomicReference|AtomicBoolean) 以及对应的数组封装。对于已有的包含…...

【XCP实战】AUTOSAR架构下XCP从0到1开发配置实践

目录 前言 正文 1.CAN功能开发 1.1 DBC的制作及导入 1.2 CanTrcv模块配置 1.3 Can Controller模块配置 1.4 CanIf模块配置 2.XCP模块集成配置配置 2.1.XCP模块配置 2.2.XCP模块的Task Mapping 2.3.XCP模块的初始化 3.在链接文件中定义标定段 4.编写标定相关的测试…...

【STM32】STemWin库,使用template API

目录 CubeMX配置 工程文件配置 Keil配置 STemwin配置 GUIConf.c LCDConf.c 打点函数 修改屏幕分辨率 GUI_X.c 主函数 添加区域填充函数 移植过程中需要一些参考手册&#xff0c;如下 STemwin使用指南 emWin User Guide & Reference Manual CubeMX配置 参考驱…...

Web开发-JavaEE应用动态接口代理原生反序列化危险Invoke重写方法利用链

知识点&#xff1a; 1、安全开发-JavaEE-动态代理&序列化&反序列化 2、安全开发-JavaEE-readObject&toString方法 一、演示案例-WEB开发-JavaEE-动态代理 动态代理 代理模式Java当中最常用的设计模式之一。其特征是代理类与委托类有同样的接口&#xff0c;代理类…...