【Blazor学习笔记】.NET Blazor学习笔记
我是大标题
我学习Blazor的顺序是基于Blazor University,然后实际内容不完全基于它,因为它的例子还是基于.NET Core 3.1做的,距离现在很遥远了。
截至本文撰写的时间,2025年,最新的.NET是.NET9了都,可能10也快了。我发现有些它上面说的例子其实现在都不一定能运行了,我结合Deep Seek和其他几家人工智能辅助的情况下,进行Blazor的学习,基于原来的教程,并补充了一些我好奇的部分,结合人工智能给我的教学,掌握blazor的核心知识。
我是冗长你不爱看的目录
- 我是大标题
- 组件与布局
- 单向绑定和双向绑定
- 单向绑定
- 访问HTML元素的DOM事件
- 双向绑定
- 组件之间的参数传递
- Blazor所支持的指令
- Blazor的属性与属性展开Attribute Splatting
- 如何捕获了未在组件中显式定义的属性CaptureUnmatchedValues
- Blazor的变量生命期
- Blazor的多线程与InvokeAsync
- 同步初始化
- 异步初始化
- ConfigureAwait(continueOnCapturedContext: bool)方法
- InvokeAsync
- Blazor的虚拟DOM功能
- Blazor的@key关键字
- Blazor的RenderFragments模板化
- Blazor的路由功能
- Blazor的表单功能
- Blazor的组件库
- Blazor下的.NET和JS互操作
- Blazor下的DI依赖注入
组件与布局
首先什么是布局,就是页面的模板
创建自己的模板需要
- 使用razor语法,@inherits LayoutComponentBase
然后一般的会基于一个已有的布局来做,如果这样的话就需要再写一句
@layout [其他布局]
例如这样

基于MainLayout创建一个叫Admin的布局。
然后如何使用自定义的布局到具体的页面呢
- 大批量的,通过_Imports.razor,在指定文件夹下的所有布局都会按照_Imports.razor来处理,就是这个razor文件放在哪个文件夹下,哪个文件夹下的razor都会按照这个_Imports.razor来渲染
- 小量的,直接就写@layout [你的布局]
如图所示,这样写Admin下面的razor都会按_Import的布局来渲染了

组件如果需要交互的话,需要在最前面加@rendermode InteractiveServer
这里我默认都是用服务器模式的Blazor
单向绑定和双向绑定
单向绑定
单向绑定就是C#->前端的意思
只需要把需要绑定的对象写一个[Parameter]属性,然后修改为public属性,在前端区域就可以使用@符号进行访问了
比如这样

访问HTML元素的DOM事件
对于像是button这类存在DOM的HTML元素,可以通过@onxxxx来访问其DOM事件,之后就可以和C#进行联动了,或者直接通过lambda表达式。某些事件还具备属性,只需要通过@onxxxx:yyyy进行更细致的控制。
联动C#区域代码

原地直接lambda表达式

访问某些事件更细化的属性功能【譬如这里的stopPropagation】

这个的作用就是让事件停止冒泡传递了,就停在button这一级了。
单向绑定的总结[来自AI]
单向绑定,这样写外部初始化这个Razor组件的时候就必须要传入一个参数,然后传入的参数就会投射到前端区域
在Blazor中,组件如何解释我们传递的值取决于我们正在设置的[Parameter]的类型,以及我们是否通过使用@符号明确表达了我们的意图。
关于[Parameter]属性:
在Blazor组件中,当你想要从父组件接收数据时,你会在子组件的代码中定义一个带有[Parameter]特性的属性。这个特性告诉Blazor这是一个可以从外部传递进来的值。
关于值的传递和解释:
当你向组件传递一个简单类型的值(如整数、字符串、布尔值)时,Blazor会根据属性的类型自动进行值的转换和绑定。例如,如果你传递了一个字符串给一个类型为string的[Parameter]属性,Blazor会直接将这个字符串值赋给该属性。
对于复杂类型的值(如对象、委托Func、事件处理程序等),Blazor同样会根据属性的类型进行绑定,但这里可能需要更多的考虑,比如对象的生命周期管理、委托的调用上下文等。
关于@符号的使用:
在Blazor的Razor语法中,@符号通常用于标记代码表达式。当你在HTML标记中嵌入C#代码时,你需要使用@符号来告诉Razor引擎这是一个代码块或表达式。
但是,在传递参数给组件时,@符号的使用并不是直接相关的。更常见的是,你会在父组件的Razor标记中直接使用属性名来传递值,而不需要额外的@符号(除非你是在传递一个代码表达式的结果作为值)。例如:。
有一点需要注意:如果你在传递参数时使用了绑定表达式(例如,绑定到一个组件的状态或父组件的状态),那么你可能需要使用@bind指令或@bind-Value(取决于属性的命名)来实现双向绑定。但即使在这种情况下,@符号也是用于标记绑定表达式本身,而不是用于标记参数属性。总结来说,Blazor如何解释传递给组件的值主要取决于[Parameter]属性的类型以及你传递值的方式(直接值、绑定表达式等)。@符号在Razor语法中用于标记代码表达式,但在传递参数时通常不是直接相关的,除非你在值中使用了代码表达式。
Blazor 在传递参数时,会根据目标参数的类型推断传递的值。
对于布尔、数字等非字符串类型,Blazor 会将字符串字面量推断为相应的表达式。
对于字符串类型,Blazor 会直接传递字符串值,而不会进行推断。
这种推断机制使得代码更简洁,同时确保类型安全。
双向绑定
双向绑定就是实现数据在前端区域和C#区域双向传递
通过@bind和@bind-value来实现
| 特性 | @bind | @bind-value |
|---|---|---|
| 语法简洁性 | 更简洁,适合大多数场景 | 更显式,适合复杂场景 |
| 默认绑定属性 | 自动绑定到 value 属性 | 显式绑定到 value 属性 |
| 默认事件 | 默认绑定到 onchange 事件 | 需要显式指定事件(如 oninput) |
| 适用场景 | 普通 HTML 元素或简单组件 | 自定义组件或需要显式控制的场景 |
| 灵活性 | 较低,适合简单绑定 | 较高,适合需要精细控制的场景 |
这里我们看下面这个例子,涵盖了双向绑定的各种情况
简单说就是懒的话,直接@bind,想精细点就@bind-value,毕竟牛逼

组件之间的参数传递
组件之间传递参数,可以通过将需要传递的组件通过[Parameter]暴露出去给父级组件来访问或者通过CascadingParameter来级联传递。
这里重点说CascadingParameter
它有两种模式
- 通过“名字”来让子组件索引自己要的信息
- 通过类型自动检索自己要的信息
先说“名字”索引
父组件想传递两个信息到子组件

传递的时候就这样套娃写,CascadingValue,然后指定传递的变量,然后给要传递的变量取一个“名字”,然后最后子组件就写在最内层就完了【我这里子组件叫CascadingChild】
子组件是这样的

在子组件里头需要用一个变量来接传递进来的参数
写一个属性CascadingParameter,然后指定好取的名字就可以接收到上层传递进来的参数了
基于类型的参数传递
父组件
我这里整了个复杂的类对象来传递,让子组件自动推断,类似于上面用“名字”来索引

子组件

最后再说下按“名字”传递的特殊情况-覆写
框架在按照名字进行索引的时候,会出现级联传递的名字一样的情况,这种情况下就会发生在传递过程中的覆写问题,框架并不禁止这种行为,可以在过程中组件将上一级传递的值修改,然后再往下传递。
父组件

子组件
这里就出现了子组件往更下一级的孙组件传递同样名字的参数,这个时候框架不禁止这种行为,可以自行修改变量的值,再往下传递。

孙组件

Blazor所支持的指令
| 类别 | 关键字/用法 |
|---|---|
| 控制流 | @if、@else、@switch、@for、@foreach、@while |
| 代码块 | @{ … } |
| 表达式 | @变量、@(表达式) |
| HTML 辅助方法 | @Html.Raw、@Html.ActionLink、@Html.Partial |
| 注释 | @* … *@ |
| 模型和视图数据 | @model、@using、@inherits |
| 布局和部分视图 | @section、@RenderBody、@RenderSection |
| 函数和属性 | @functions |
| Razor Pages | @page |
| 异步编程 | @await |
| 依赖注入 | @inject |
| 标签助手 | @addTagHelper、 |
| URL 和路径 | @Url.Action、@Url.Content |
| 表单和验证 | @Html.BeginForm、@Html.ValidationSummary、@Html.ValidationMessageFor |
| 组件渲染 | @(await Html.RenderComponentAsync) |
| 动态属性 | <div class=“@(isActive ? “active” : “inactive”)”> |
| 全局指令 | @namespace、@attribute |
| 转义字符 | @@ |
| 自定义指令 | 通过自定义 Razor 引擎或标签助手实现 |
控制流语句
@if、@else、@else if:条件判断。
@switch、@case、@default:多条件分支。
@for、@foreach、@while:循环语句。
代码块
@{ … }:定义多行C#代码块。
表达式
@变量:直接输出变量。
@(表达式):输出表达式的结果。
HTML辅助方法
@Html.Raw:输出未编码的HTML。
@Html.ActionLink:生成超链接。
@Html.Partial、@Html.RenderPartial:渲染部分视图。
注释
@* … *@:Razor注释。
模型和视图数据
@model:定义视图的强类型模型。
@using:引入命名空间。
@inherits:指定视图继承的基类。
布局和部分视图
@section:定义布局中的占位符内容。
@RenderBody():在布局页面中渲染主体内容。
@RenderSection:在布局页面中渲染特定部分。
函数和属性
@functions:定义视图中的函数或属性。
Razor Pages
@page:定义Razor页面的路由。
三元运算符
@(条件 ? “True” : “False”):条件化输出。
Lambda表达式
@{ Func<int, string> 函数名 = (参数) => “返回值”; }:定义和使用Lambda表达式。
其他
@await:用于异步操作。
Blazor的属性与属性展开Attribute Splatting
属性这个和前端部分联系比较紧密。
对于HTML组件来说,他们一般会有一些“键-值对”构成了属性描述
譬如举一个例子,可能某一个按钮有这些属性
| 属性名 | 值 |
|---|---|
| class | btn btn-primary |
| style | color:red; |
| disable | true |
| data-custom | 123 |
按照既有的理解,开发人员就直接在前端部分写HTML标签写这些玩意进去了。但是在Blazor框架下,这个可以通过C#的字典来定义,然后传递给前端HTML部分,这个就叫做属性了。就很方便可以动态在C#代码区修改属性
譬如我定义一个键值对属性字典

我把它给一个按钮附上

这样渲染的时候,框架就会把我希望的属性渲染给这个按钮
就是通过这个@attributes 来实现
这里就会引申出另一个问题,如果我HTML对象就本身存在了一些既有的键值对属性了,怎么处理呢,就要引出CaptureUnmatchedValues了。
来自AI的解读




如何捕获了未在组件中显式定义的属性CaptureUnmatchedValues
譬如我这里有一个组件CaptureUnmatchedValues

通过CaptureUnmatchedValues属性,配合一个键值对字典变量来接收外部传递进来的“属性”,接收没有显式定义的属性
外部我是这样写的

我在外部既有已经写了一个字体大小的属性,和内部显式定义的属性是重复的,这种时候就会按内部显式定义的属性来渲染,虽然这个组件也接收了来自外部的属性。

如果我把显式定义删掉

这样写,运行的效果这个按钮的字体大小就是10px了

来自AI的总结


Blazor的变量生命期
这里我让AI总结了下微软文档中关于【ASP.NET Core Razor组件生命周期】这篇文档的内容
就是每个组件自带的这些方法的执行顺序要小心,有很多坑

这部分就是理论性比较强,就没有去具体做些例子来试了,只能说是日后遇到用到的情况具体问题具体分析了。
Blazor的多线程与InvokeAsync
我先问了问AI,Blazor里的多线程和普通C#的多线程的区别
Blazor的多线程
- UI线程的限制:
在Blazor中,特别是Blazor WebAssembly应用程序中,所有的UI更新和事件处理都是在浏览器的UI线程上执行的。这意味着,如果开发者在Blazor中启动了一个异步操作(如使用Task.Run或await Task.Delay等),并且这个操作需要在UI线程上继续执行(如更新UI元素),那么就需要确保这个操作在完成后能够正确地返回到UI线程上。
为了实现这一点,Blazor通常会使用ConfigureAwait(true)来确保异步操作在完成后能够返回到捕获的同步上下文(即UI线程)上。
然而,这也可能导致性能问题,因为频繁的上下文切换会增加额外的开销。 - 线程安全性的考虑:
在Blazor中,由于UI线程的限制,开发者需要更加谨慎地处理线程安全问题。例如,当多个线程尝试同时访问或修改共享资源时,就需要使用适当的同步机制(如锁、信号量等)来避免竞态条件和死锁等问题。此外,由于Blazor运行在浏览器中,因此还需要考虑跨线程通信的问题。例如,如果需要在非UI线程上执行某些操作,并且这些操作的结果需要更新到UI上,那么就需要使用适当的方法(如通过消息传递或事件机制)来将结果传递回UI线程。 - Blazor Server的特殊性:
值得注意的是,Blazor Server的运行环境与Blazor WebAssembly有所不同。
在Blazor Server中,应用程序实际上是在服务器上运行的,而UI更新则是通过SignalR连接实时回传给客户端的。这意味着在Blazor Server中,多线程的使用可能更加复杂。
因为开发者需要处理服务器和客户端之间的通信、状态同步等问题。同时,由于服务器上的代码可以访问完整的.NET Core运行时支持,因此也可以使用更高级的多线程和并行编程技术来提高性能。
普通C#程序
C#提供了多种实现多线程的方式,如使用Thread类、ThreadPool类、Task类以及Parallel类等。这些类和方法允许开发者创建和控制线程,以实现并行执行多个任务。在普通C#程序中,多线程的访问和操作通常不会受到特定的框架或运行环境的限制。开发者可以自由地在线程之间共享数据、进行同步和通信等操作。然而,这也需要开发者自行处理线程安全问题,如避免竞态条件、死锁等问题。
这里先通过两种不同的初始化-同步初始化vs异步初始化,来体验下初探下多线程,然后再说一说InvokeAsync。
同步初始化

这里重写了OnInitialized方法,里面获取当前线程的管理线程ID。
然后外层父组件是通过一个for循环调用了5次这个组件

运行的效果就是这5个组件均会输出同一个管理线程的ID

然后我再问了AI关于这个的理解。
输出结果取决于以下因素:
情况 1:纯同步调用
如果父组件自身是完全同步的(例如没有 async 方法或 await):
所有子组件的 OnInitialized 会由同一个线程连续执行
输出的 IdThread 相同
这是因为同步代码会阻塞当前线程,直到所有子组件初始化完成。
情况 2:异步父组件
如果父组件包含异步逻辑(如 OnInitializedAsync):
可能在初始化过程中发生线程切换
子组件的 IdThread 可能不同(但未必一定会不同)
异步初始化
做一个异步初始化的代码,试一下,外层也是类似的for循环调用5次


出现了一些不同的线程ID了
输出的线程 ID 大概率会不同,因为异步操作可能导致线程切换。
ConfigureAwait(continueOnCapturedContext: bool)方法
这里再引申出另一个有关系的知识点-ConfigureAwait
实际上在异步初始化这里,我们的初始化是可以设置一个参数来控制线程控制权后面的归属的。
就是这个ConfigureAwait(continueOnCapturedContext: bool)方法。
用于指定在等待异步操作完成后,是否应该尝试将控制权返回给捕获的同步上下文(如果存在的话)。在这个上下文中,“捕获的同步上下文”通常指的是最初启动异步操作的上下文,比如ASP.NET Core的请求上下文或Blazor的UI线程
| 设置为true | 设置为false |
|---|---|
| 框架默认的行为是true,await 操作完成后,控制权将尝试返回给捕获的同步上下文。在Blazor中,这意味着如果异步操作是在UI线程上启动的,那么后续的操作也会尝试在UI线程上执行,以确保对UI元素的访问是线程安全的 | await 操作完成后,控制权不会返回给捕获的同步上下文,而是继续在当前可用的线程池线程上执行。这可以提高性能,因为它避免了不必要的上下文切换,但你必须小心确保不在错误的线程上访问UI元素 |
| 推荐的做法,保证UI访问的线程安全 | 不涉及UI的后台操作,使用false可以提高性能和响应 |
| 1. 需要操作 UI 组件(如更新 @currentCount)2. 访问 HttpContext(在 ASP.NET Core 中)3.使用 Blazor 的 JS 互操作(IJSRuntime.InvokeAsync) | 1. 通用类库代码(不依赖具体上下文)2. 纯后台任务(如日志记录、数据处理)3. 长时间运行的 CPU 密集型操作(避免阻塞 UI 线程) |
这里我们做一个测试
打印异步之前的线程ID,和不同设置下异步之后的线程ID


当使用await关键字时,默认情况下,它会捕获当前的同步上下文(在Blazor Server中,这通常是ASP.NET Core的同步上下文),并在异步操作完成后尝试回到这个上下文。这是为了确保像UI更新这样的操作能在正确的上下文中执行。在异步操作完成后,应该尝试回到原来的同步上下文。在Blazor Server中,这意味着回到处理该SignalR消息的线程或与之相关的线程。由于线程池的工作方式,这个“原来的线程”可能并不是实际开始执行异步操作的那个线程。因此,你看到的线程ID不同,是因为在await之后,代码可能是在线程池中的另一个线程上执行的,但这个线程被调度回来执行后续的代码,以确保它运行在正确的同步上下文中。所以线程ID会不一样。
如果是false的情况下

await之后它去到另一个线程ID了,没有回到之前的线程ID

InvokeAsync
Blazor的虚拟DOM功能
Blazor的@key关键字
Blazor的RenderFragments模板化
Blazor的路由功能
Blazor的表单功能
Blazor的组件库
Blazor下的.NET和JS互操作
Blazor下的DI依赖注入
相关文章:
【Blazor学习笔记】.NET Blazor学习笔记
我是大标题 我学习Blazor的顺序是基于Blazor University,然后实际内容不完全基于它,因为它的例子还是基于.NET Core 3.1做的,距离现在很遥远了。 截至本文撰写的时间,2025年,最新的.NET是.NET9了都,可能1…...
UE求职Demo开发日志#21 背包-仓库-装备栏移动物品
1 创建一个枚举记录来源位置 UENUM(BlueprintType) enum class EMyItemLocation : uint8 {None0,Bag UMETA(DisplayName "Bag"),Armed UMETA(DisplayName "Armed"),WareHouse UMETA(DisplayName "WareHouse"), }; 2 创建一个BagPad和WarePa…...
力扣988. 从叶结点开始的最小字符串
Problem: 988. 从叶结点开始的最小字符串 文章目录 题目描述思路复杂度Code 题目描述 思路 遍历思想(利用二叉树的先序遍历) 在先序遍历的过程中,用一个变量path拼接记录下其组成的字符串,当遇到根节点时再将其反转并比较大小(字典顺序大小&…...
《PYTHON语言程序设计》(2018版)1.7近似π。利用步幅来进行修改
利用循环的步幅来计算派 利用正常的办法, pi 4 *(1-(1/3)(1/5)-(1/7)(1/9)-(1/11)(1/13)-(1/15)) print(pi)利用这段代码得出结果 我们如何利用循环来进行呢 一、思路 首先我们来利用excel表格来计算一下结果 我做了一个设想,让相加的部分先进行相加,然后再进行减法呢?? 结…...
低通滤波算法的数学原理和C语言实现
目录 概述 1 原理介绍 1. 1 基本概念 1.2 一阶RC低通滤波器模型 2 C语言完整实现 2.1 滤波器结构体定义 2.2 初始化函数 2.3 滤波计算函数 3 应用示例 3.1 噪声信号滤波 3.2 输出效果对比 3.3 关键参数选择指南 4 性能优化技巧 4.1 定点数优化 4.2 抗溢出处理 …...
【BUUCTF杂项题】荷兰宽带数据泄露、九连环
一.荷兰宽带数据泄露 打开发现是一个.bin为后缀的二进制文件,因为提示宽带数据泄露,考虑是宽带路由器方向的隐写 补充:大多数现代路由器都可以让您备份一个文件路由器的配置文件,软件RouterPassView可以读取这个路由配置文件。 用…...
安全策略实验报告
1.实验拓扑图 2.实验需求 vlan2属于办公区,vlan3生产区 办公区pc在工作日时间可以正常访问OAserver,i其他时间不允许 办公区pc可以在任意时间访问Web server 生产区pc可以在任意时间访问OA server但不能访问web server 特例:生产区pc可以…...
Haproxy+keepalived高可用集群,haproxy宕机的解决方案
Haproxykeepalived高可用集群,允许keepalived宕机,允许后端真实服务器宕机,但是不允许haproxy宕机, 所以下面就是解决方案 keepalived配置高可用检测脚本 ,master和backup都要添加 配置脚本 # vim /etc/keepalived…...
亚博microros小车-原生ubuntu支持系列:20 ROS Robot APP建图
依赖工程 新建工程laserscan_to_point_publisher src/laserscan_to_point_publisher/laserscan_to_point_publisher/目录下新建文件laserscan_to_point_publish.py #!/usr/bin/env python3import rclpy from rclpy.node import Node from geometry_msgs.msg import PoseStam…...
Dockerfile构建容器镜像
Dockerfile 是一种文本格式的配置文件,用于自动化构建 Docker 镜像。它包含了一系列指令(命令),每个指令定义了容器镜像构建过程中的一步操作。通过Dockerfile,我们可以指定基础镜像、安装依赖、配置环境变量、复制文件…...
python 在包含类似字符\x16、\x12、\x某某的数组中将以\x开头的字符找出来的方法
话不多说直接看例子: import re# 原始列表 data [\x16, \x17, s, \x16, hello, \x1A]# 正则表达式匹配以 \x 开头的字符串 pattern r^\\x# 找出以 \x 开头的字符 result [item for item in data if isinstance(item, str) and re.match(pattern, repr(item)[1:-…...
Spring Bean 的生命周期介绍
Spring Bean 的生命周期涉及多个阶段,从实例化到销毁,在开发中我们可以通过各种接口和注解介入这些阶段来定制化自己的功能。以下是详细的生命周期流程: 1. Bean 的实例化(Instantiation) 方式:通过构造函…...
调用腾讯云批量文本翻译API翻译srt字幕
上一篇文章介绍了调用百度翻译API翻译日文srt字幕的方法。百度翻译API是get方式调用,参数都放在ur中,每次调用翻译文本长度除了接口限制外,还有url长度限制,而日文字符通过ur转码后会占9个字符长度,其实从这个角度来讲…...
车载软件架构 --- 软件定义汽车面向服务架构的应用迁移
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活…...
Baklib引领内容中台与人工智能技术的创新融合之路
内容概要 在数字化转型的浪潮中,各行业正在面临前所未有的挑战与机遇。内容中台作为一种新的概念,逐渐进入了企业的视野,它不仅是一个技术平台,更是提供了整合和管理内容的新思路。从根本上,内容中台旨在提升企业对信…...
想品客老师的第十一天:模块化开发
模块化概念 模块化开发可以提高代码的可维护性、可读性和复用性,同时降低开发和调试的复杂性,把业务根据功能分开写,解决变量命名的冲突,可以开放部分接口给类(例如调用模块里的一个函数)也更适合团队协作…...
接入DeepSeek大模型
接入DeepSeek 下载并安装Ollamachatbox 软件配置大模型 下载并安装Ollama 下载并安装Ollama, 使用参数ollama -v查看是否安装成功。 输入命令ollama list, 可以看到已经存在4个目录了。 输入命令ollama pull deepseek-r1:1.5b, 下载deepse…...
基于遗传算法的256QAM星座图的最优概率整形matlab仿真,对比优化前后整形星座图和误码率
目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下(完整代码运行后无水印): GA优化曲线: 优化前后星座图对比 优化前后误码率对比 仿真操作步骤…...
JavaScript系列(57)--工程化实践详解
JavaScript工程化实践详解 🏗️ 今天,让我们深入探讨JavaScript的工程化实践。良好的工程化实践对于构建可维护、高质量的JavaScript项目至关重要。 工程化基础概念 🌟 💡 小知识:JavaScript工程化是指在JavaScript开…...
Linux-CentOS的yum源
1、什么是yum yum是CentOS的软件仓库管理工具。 2、yum的仓库 2.1、yum的远程仓库源 2.1.1、国内仓库 国内较知名的网络源(aliyun源,163源,sohu源,知名大学开源镜像等) 阿里源:https://opsx.alibaba.com/mirror 网易源:http://mirrors.1…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
