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

ASP.NET Core 6.0 如何处理丢失的 Startup.cs 文件

介绍

    .NET 6.0 已经发布,ASP.NET Core 6.0 也已发布。其中有不少变化让很多人感到困惑。例如,“谁动了我的奶酪”,它在哪里Startup.cs?在这篇文章中,我将深入研究这个问题,看看它移动到了哪里以及其他变化。

    ASP.NET Core 的中间件并没有发生根本性的变化,但部分项目结构以及注册依赖项的位置发生了变化。为了更好地理解它,最好从 .NET Core 3.1 项目模板开始,然后手动升级它,看看它与新模板相比如何。

升级旧式控制台项目

    首先,让我们创建一个新的控制台项目。我将其命名为OldToNew。我选择了 .NET Core 3.1 目标,并将其升级到 .NET 6.0 以查看差异。如果您已经使用 .NET 一段时间,您会在文件中认出这个项目结构Program.cs。 

using System;

namespace OldToNew
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

        在 .NET 6.0 中,这些变化旨在简化和消除应用程序中的冗余。他们引入的首批功能之一是所谓的Filescoped Namespaces。传统命名空间如下所示:

namespace OldToNew
{
    // code goes here.
}

        如果您已经使用过 .NET 一段时间,那么您可能从未在文件中放置过多个命名空间。您可以删除花括号,只需添加分号,将整个文件标记为使用一个命名空间。

namespace OldToNew;
// code goes here.
 

using System;

namespace OldToNew;

internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
}
 

        Visual Studio 将会向我抱怨,因为这是一个 .NET Core 3.1 项目,所以在我们走得太远之前,我们需要编辑 .NET Core 3.1 .csproj 文件并将其转换为 .NET 6.0 应用程序。

<!-- .NET Core 3.1 -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

<!-- .NET 6.0 -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

</Project>

        一旦我们做出这一改变,Visual Studio 就会对文件范围的命名空间感到满意。

        我们要做的下一个更改是删除该using System;行。为此,我们需要再次编辑项目文件并启用Implicit Usings。

<!-- .NET 6.0 -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

</Project>

        如果我们启用隐式 using 语句,我们通常使用的大多数常用 using 语句将默认包含在 SDK 中,您不再需要将它们包含在文件中。我们可以删除该using System;行,因为编译器会自动为我们添加 using 语句。

namespace OldToNew;

internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }

        他们引入的下一个功能是所谓的“顶级语句”。 其目的是删除每个控制台应用程序或 ASP.NET Core 应用程序中存在的“垃圾”。

        使用顶级语句,我们可以删除static void Main(string[] args)方法和花括号以及命名空间和class Program声明。

Console.WriteLine("Hello World!");

        一旦删除所有这些,您就会看到我们剩下的唯一代码就是我们的Console.WriteLine()方法!

将控制台应用更改为 Web 应用 (ASP.NET Core)

    目前,这只是一个简单的控制台应用程序,但我想将其转换为 ASP.NET Core 应用程序。在执行此操作之前,让我们先查看解决方案资源管理器中的依赖项和框架节点。

        您可以在上方看到,Frameworks这Microsoft.NETCore.App是包含创建控制台应用程序所需的所有包的 SDK。让我们将 .csproj 文件中的 SDK 类型更改为 .Web 类型项目,看看会发生什么Microsoft.NET.Sdk:Microsoft.NET.Sdk.Web。

<!-- .NET 6.0 -->
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

</Project>
注意现在依赖下发生的情况:

        该框架现在包括Microsoft.AspNetCore.App将引入创建 ASP.NET Core 应用程序所需的所有包。它还将修改全局 using 语句以包含 ASP.NET 特定的 using 语句。

        现在让我们删除该Console.WriteLine("Hello World!");行并添加 ASP.NET Core 特定的代码。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(); 

        我们现在正在构建一个 Web 应用程序。WebApplication对象从哪里来?它属于Microsoft.AspNetCore.Builder命名空间。

        我们可以运行这个应用程序,但是由于没有端点,所以会有点无聊。让我们添加一个端点来完成这个任务:

app.MapGet("/", () => {
    return "Hello World!";
});   

        我们刚刚在 ASP.NET Core 6.0 中创建了一个最小 API Web 应用程序。让我们运行它并看看会发生什么。 

        当我们启动默认路径时,它会返回,hello world因此我们有一个功能齐全的 Web 应用程序。最少的 API 是快速构建 Web API 项目的好方法。

Startup.cs 怎么样?

    ASP.NET Core 6.0 中的中间件流程与完整 Web API MVC 项目的流程类似,并且共享许多相同的实现。在以前的 ASP.NET Core 项目中,您将获得一个Startup.cs包含两个方法的类ConfigureServices()和Configure()。

    在 ConfigureServices()中,您注册了依赖项注入服务。在 Configure() 中,您概述了中间件管道顺序和结构。

    在我们的新项目中,这是什么样子的?您将依赖注入放在哪里?答案是在第一行和第二行之间,注册中间件在第二行和第三行之间,如下所示。

var builder = WebApplication.CreateBuilder(args);
// REGISTER SERVICES HERE
var app = builder.Build();
// REGISTER MIDDLEWARE HERE
app.Run();

例如,如果我想添加身份验证,我会像这样注册: 

var builder = WebApplication.CreateBuilder(args);
// REGISTER SERVICES HERE
builder.Services.AddAuthentication(...) ...
builder.Services.AddAuthorization();
var app = builder.Build();
// REGISTER MIDDLEWARE HERE
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/", () => {
    return "Hello World!";
});  
app.Run();

        中间件管道中的顺序很重要,因此我在中间件MapGet()上方添加了UseAuthentication()和UseAuthorization()。但是,为了使其生效,您需要使用属性注释要保护的端点。这将需要使用语句[Authorize],必须引用:Microsoft.AspNetCore.Authorization 。

using Microsoft.AspNetCore.Authorization;

...

app.MapGet("/",[Authorize]() => {
    return "Hello World!";
});

Program.cs到目前为止,我们的文件的完整代码如下所示: 

var builder = WebApplication.CreateBuilder(args);
// REGISTER SERVICES HERE
builder.Services.AddAuthentication();
builder.Services.AddAuthorization();
var app = builder.Build();
// REGISTER MIDDLEWARE HERE
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/",[Authorize] () => {
    return "Hello World!";
});  
app.Run(); 

        如果我们现在运行它,我们将会得到一个异常,因为我们从未指定身份验证方案。

        让我们修复它。我们可以选择多种不同类型的身份验证方案,但在 WebAPI 中,我们通常使用诸如 bearer token 或 JWT token 之类的东西来保护应用程序。

        让我们继续将 JWT 承载者添加到最小 API。我们需要Microsoft.AspNetCore.Authentication.JwtBearer通过 NuGet 导入包,然后添加以下代码:

using Microsoft.AspNetCore.Authentication.JwtBearer;

...

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();

所以完整的块应该是这样的:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;

var builder = WebApplication.CreateBuilder(args);
// REGISTER SERVICES HERE
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();
builder.Services.AddAuthorization();
var app = builder.Build();
// REGISTER MIDDLEWARE HERE
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/", [Authorize] () => {
    return "Hello World!";
});
app.Run();

        JWT Bearer 已添加到应用程序中,让我们运行它并查看会发生什么。现在我们得到了我们正在寻找的状态,401 unauthorized因为我们没有为其提供任何类型的令牌。还需要其他步骤来设置获取令牌的方法并确保我们只允许接受有效的令牌,但这超出了本文的范围。本文的重点是演示在哪里注册依赖项和中间件以及如何使用它们。

        我们应该做的最后一项修改是将 [Authorize] 属性更改为使用“流畅的语法”,如下所示:

//FROM THIS:
app.MapGet("/", [Authorize] () => {
    return "Hello World!";
});

//TO THIS:
app.MapGet("/", () => {
  return "Hello World!";
}).RequireAuthorization();

它们都做同样的事情,但是在最小 API 情况下,“流畅的语法”感觉更自然。 

恢复丢失的 Startup.cs 文件

    接下来,让我们看看能否恢复我们的老朋友Startup.cs文件。如果将所有内容都放在一个文件中,最小 API 结构可能会变得混乱和臃肿。

    一定有办法让我们更好地组织这些。我将首先向Startup.cs项目添加一个名为的新类。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {

    }

     public void Configure(WebApplication app, IWebHostEnvironment env)
    {

    }

        这看起来应该与过去的完整 Web API 项目模板很相似。我只是将其粘贴到我的新Startup.cs文件中并删除了命名空间。该Startup.cs文件需要IConfiguration传入一个对象。我们可以从我们的 中提供该对象吗Program.cs? 

//  Program.cs file
var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration); 

        是的。我们可以这样做。builder创建的对象包含一个Configuration属性,我们可以使用该属性将其传递给Startup构造函数。

        接下来,让我们尝试为该ConfigureServices()方法提供一个IServiceCollection。

//  Program.cs file
var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services); 

        同样,builder包含一个Services我们可以用来传递给ConfigureServices()方法的属性。现在我们可以从中删除所有依赖注入代码Program.cs并将其移动到ConfigureServices中的方法Startup.cs。 

// Startup.cs file
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();
    services.AddAuthorization();
}

接下来,让我们尝试Configure()WebApplication类提供方法。 

//  Program.cs file
var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, builder.HostingEnvironment); 

        有趣的是,虽然我们传递的app是 类型WebApplication,但如果你检查它,该Configure()方法需要的是IApplicationBuilder,但它似乎没问题。为什么?如果你深入研究该WebApplication对象,你会看到它实现了IApplicationBuilder接口。

        我们将中间件管道代码剪切出来Program.cs,并将其粘贴到Configure()方法中Startup.cs。

// Startup.cs file
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  app.UseAuthentication();
  app.UseAuthorization();

  app.MapGet("/", () =>
  {
      return "hello world";
  }).RequireAuthorization();

  app.Run();
}

        不幸的是,这实际上行不通,因为接口IApplicationBuilder没有MapGet()方法或Run()方法。那些存在于WebApplication类中。如果我们将Configure()方法更改为接受WebApplication对象,它应该可以工作。 

// Startup.cs file
public void Configure(WebApplication app, IWebHostEnvironment env)
{
  app.UseAuthentication();
  app.UseAuthorization();

  app.MapGet("/", () =>
  {
      return "hello world";
  }).RequireAuthorization();

  app.Run();
}

让我们看一下完整的文件“Program.cs”和“Startup.cs”,看看它们现在是什么样子。 

// Program.cs file
var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);
var app = builder.Build();
startup.Configure(app, builder.Environment);

// Startup.cs file
using Microsoft.AspNetCore.Authentication.JwtBearer;

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer();
        services.AddAuthorization();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(WebApplication app, IWebHostEnvironment env)
    {
        app.UseAuthentication();
        app.UseAuthorization();

        app.MapGet("/", () =>
        {
            return "hello world";
        }).RequireAuthorization();

        app.Run();
    }
}

        如果我们运行它,我们会得到401 Unauthorized状态,这意味着它正在运行。除了将我们的配置内容移到 中之外Startup.cs,我们没有做太多改变,这让它看起来更像旧的 .Net Core 风格。 

我们可以做得更好吗?

    使用Startup.cs确实有助于改善组织,但我认为我们可以做得更好。我一直讨厌文件中Startup.cs单词ConfigureServices()和Configure()彼此太接近,而且你还要传递一个IConfiguration对象。这可能会让人搞不清楚什么放在哪里。

    我们为什么不尝试改进这一点呢?我不喜欢这个名字ConfigureServices()。如果我们将它重命名为RegisterDependentServices()并将其放在自己的文件中会怎么样?这将使我们更容易理解发生了什么。

// RegisterDependentServices.cs file
using Microsoft.AspNetCore.Authentication.JwtBearer;

public static class RegisterDependentServices
{
    public static WebApplicationBuilder RegisterServices(this WebApplicationBuilder builder)
    {
        // Register your dependencies
        builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer();
        builder.Services.AddAuthorization();
        return builder;
    }
}

        我决定创建该类static并使用扩展方法将其添加到该类中。我们稍后WebApplicationBuilder会看到这如何改进文件。Program.cs

        接下来,让我们创建一个新文件SetupMiddlewarePipeline.cs。此文件将包含中间件管道。

public static class SetupMiddlewarePipeline
{
    public static WebApplication SetupMiddleware(this WebApplication app)
    {
        // Configure the pipeline !! ORDER MATTERS !!
        app.UseAuthorization();
        app.UseAuthentication();
        app.MapGet("/", () =>
        {
            return "hello world";
        }).RequireAuthorization();
        return app;
    }
}

现在,这会如何改变我们的Program.cs文件? 

// Program.cs file
WebApplication app = WebApplication.CreateBuilder(args)
    .RegisterServices()
    .Build();

app.SetupMiddleware()
    .Run();

这样就生成了一个非常干净的Program.cs文件。事实上,如果您愿意,您可以将其全部放在一行中。

// Program.cs file
WebApplication.CreateBuilder(args)
    .RegisterServices()
    .Build()
    .SetupMiddleware()
    .Run();

我并不讨厌它。事实上,我觉得我喜欢它。

那么 IConfiguration 怎么样?

    之前,Startup()构造函数需要IConfiguration注入其中。但是,由于WebApplication和WebApplicationBuilder都具有.Configuration属性,因此我们不再需要显式注入它。

// RegisterDependentServices.cs file
public static class RegisterDependentServices
{
  public static WebApplicationBuilder RegisterServices(this WebApplicationBuilder builder)
  {
    // ******* Access the configuration *******
    var config = builder.Configuration;

    // Register your dependencies
    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer();
    builder.Services.AddAuthorization();
    return builder;
  }
}

// setupMiddlewarePipeline.cs file
public static class SetupMiddlewarePipeline
{
  public static WebApplication SetupMiddleware(this WebApplication app)
  {
    // ******** Access the configuration ********
    var config = app.Configuration;

    // Configure the pipeline !! ORDER MATTERS !!
    app.UseAuthorization();
    app.UseAuthentication();
    app.MapGet("/", () =>
    {
      return "hello world";
    }).RequireAuthorization();
    return app;
  }
}

如果我们需要访问应用程序的配置,它是可用的,而且我们的状况很好。 

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。 

相关文章:

ASP.NET Core 6.0 如何处理丢失的 Startup.cs 文件

介绍 .NET 6.0 已经发布&#xff0c;ASP.NET Core 6.0 也已发布。其中有不少变化让很多人感到困惑。例如&#xff0c;“谁动了我的奶酪”&#xff0c;它在哪里Startup.cs&#xff1f;在这篇文章中&#xff0c;我将深入研究这个问题&#xff0c;看看它移动到了哪里以及其他变化。…...

Java如何向http/https接口发出请求

用Java发送web请求所用到的包都在java.net下&#xff0c;在具体使用时可以用如下代码&#xff0c;你可以把它封装成一个工具类 import javax.net.ssl.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Outpu…...

数据分析 变异系数

目录 变异系数的应用场景包括&#xff1a; 特点&#xff1a; 注意事项&#xff1a; np.nanvar——方差&#xff0c;np.sanstd标准差 简单来讲就是平均值/标准差 变异系数&#xff08;Coefficient of Variation, CV&#xff09;是一种相对量的变异指标&#xff0c;常用于衡…...

利用免费GIS工具箱实现高斯泼溅切片,将 PLY 格式转换为 3dtiles

在地理信息系统&#xff08;GIS&#xff09;和三维数据处理领域&#xff0c;不同数据格式有其独特应用场景与优势。PLY&#xff08;Polygon File Format&#xff09;格式常用于存储多边形网格数据&#xff0c;而 3DTiles 格式在 Web 端三维场景展示等方面表现出色。将 PLY 格式…...

面试-二维数组

应用 快递业务有N个站点&#xff0c;1<N<10000&#xff1b;站点0、站点1可达&#xff0c;记作0-1&#xff1b;如果0-1、1-2&#xff0c;则站点0、站点2可达&#xff0c;记作0-2&#xff1b;s[i][j]1表示i-j可达&#xff0c;反之s[i][j]0表示i-j不可达&#xff1b;s[i][j…...

如何使用 findIndex() 方法查找数组中的第一个匹配元素的索引?

使用 findIndex() 方法查找数组中第一个匹配元素的索引 目录 简介findIndex() 方法概述如何使用 findIndex() 查找第一个匹配元素的索引 基本用法使用箭头函数和回调函数 实际项目中的代码示例 示例 1&#xff1a;查找第一个符合条件的用户索引示例 2&#xff1a;查找第一个符…...

5. 马科维茨资产组合模型+政策意图AI金融智能体(Qwen-Max)增强方案(理论+Python实战)

目录 0. 承前1. AI金融智能体1.1 What is AI金融智能体1.2 Why is AI金融智能体1.3 How to AI金融智能体 2. 数据要素&计算流程2.1 参数集设置2.2 数据获取&预处理2.3 收益率计算2.4 因子构建与预期收益率计算2.5 协方差矩阵计算2.6 投资组合优化2.7 持仓筛选2.8 AI金融…...

Centos类型服务器等保测评整/etc/pam.d/system-auth

修改服务器配置文件/etc/pam.d/system-auth&#xff0c;但是&#xff0c;把一下配置放在password的配置第一行才会生效 执行命令&#xff1a;配置口令要求&#xff1a;大小写字母、数字、特殊字符组合、至少8位&#xff0c;包括强制设置root口令&#xff01; sed -i 14a pas…...

从工厂到桌面:3D打印制造潮玩手办

传统潮玩手办的制造过程复杂且成本高昂。从设计到成品&#xff0c;需要经过多道工序&#xff0c;包括手工建模、模具制作、注塑成型等。这一过程不仅耗时耗力&#xff0c;而且难以满足消费者日益增长的个性化需求。此外&#xff0c;传统制造方式对于小批量生产或定制化产品的经…...

Java高频面试之SE-16

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java中异常的处理方式有哪些&#xff1f; 在 Java 中&#xff0c;异常的处理方式主要有以下几种&#xff1a; 1. 使用 try-catch 语句 …...

三分钟简单了解一些HTML的标签和语法_01

1.图片建议建立一个文件夹如下图所示 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"keywords"><title>魔神羽落</title><style>.testone{background-color: #ff53e…...

缓存-Redis-数据结构-redis哪些数据结构是跳表实现的?

在 Redis 中&#xff0c;跳表&#xff08;Skip List&#xff09; 被用于实现 有序集合&#xff08;Sorted Set&#xff09; 数据结构。以下是对此实现的详细解释&#xff1a; Redis中的有序集合&#xff08;Sorted Set&#xff09; 有序集合&#xff08;Sorted Set&#xff0…...

Linux 系统错误处理简介

Linux 系统错误处理简介 1. errno&#xff1a;错误代码的载体2. strerror()&#xff1a;错误信息的翻译官3. perror()&#xff1a;便捷的错误信息输出4. 系统调用与库函数的区别5. 错误处理的最佳实践 在 C/C 程序开发中&#xff0c;我们经常需要处理各种错误情况 Linux 系统提…...

逐笔成交逐笔委托Level2高频数据下载和分析:20250122

逐笔委托逐笔成交下载 链接: https://pan.baidu.com/s/1WP6eGLip3gAbt7yFKg4XqA?pwd7qtx 提取码: 7qtx Level2逐笔成交逐笔委托数据分享下载 通过Level2逐笔成交和逐笔委托这种每一笔的毫秒级别的数据可以分析出很多有用的点&#xff0c;包括主力意图&#xff0c;虚假动作&…...

第18个项目:微信开发入门:获取access_token的Python源码

源码下载地址:https://download.csdn.net/download/mosquito_lover1/90301829 功能特点: 输入AppID和AppSecret,点击按钮后异步获取access_token 1、自动保存功能: 当用户输入或修改 AppID 和 AppSecret 时自动保存 获取到新的 access_token 时自动保存 所有数据都保存在…...

如何将自己本地项目开源到github上?

环境&#xff1a; LLMB项目 问题描述&#xff1a; 如何将自己本地项目开源到github上&#xff1f; 解决方案&#xff1a; 步骤 1: 准备本地项目 确保项目整洁 确认所有的文件都在合适的位置&#xff0c;并且项目的 README.md 文件已经完善。检查是否有敏感信息&#xff0…...

Windows远程连接Docker服务

问题背景 本地开发了一个SpringBoot项目&#xff0c;想通过Docker部署起来&#xff0c;我本地是Window11系统&#xff0c;由于某些原因不能虚拟化并且未安装Docker-Desktop&#xff0c;所以我在想有没有办法本地不需要虚拟化也不需要安装Docker-Desktop来实现支持Docker命令远…...

在Qt中实现点击一个界面上的按钮弹窗到另一个界面

文章目录 步骤 1&#xff1a;创建新窗口类步骤 2&#xff1a;设计窗口的 UI步骤 3&#xff1a;设计响应函数 以下是一个完整的示例&#xff0c;展示在Qt中如何实现在一个窗口中通过点击按钮弹出一个新窗口。 步骤 1&#xff1a;创建新窗口类 假设你要创建一个名为 WelcomeWidg…...

嵌入式知识点总结 ARM体系与架构 专题提升(一)-硬件基础

嵌入式知识点总结 ARM体系与架构 专题提升(一)-硬件基础 目录 1.NAND FLASH 和NOR FLASH异同 ? 2.CPU,MPU,MCU,SOC,SOPC联系与差别? 3.什么是交叉编译&#xff1f; 4.为什么要交叉编译&#xff1f; 5.描述一下嵌入式基于ROM的运行方式和基于RAM的运行方式有什么区别? 1…...

全氟醚橡胶发展前景:高性能密封材料的璀璨之星

在当今科技飞速发展的时代&#xff0c;各类高性能材料不断涌现&#xff0c;全氟醚橡胶便是其中一颗闪耀的明珠。它以其卓越的性能和广泛的应用领域&#xff0c;在众多关键行业中发挥着不可或缺的作用&#xff0c;展现出巨大的市场潜力和发展前景。 一、引言 全氟醚橡胶&#…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...