.NET 6 攻略大全(二)

点击上方蓝字

关注我们

(本文阅读时间:15分钟)

接上篇内容,本篇文章将介绍:Arm64、容器、支持 OpenTelemetry 指标、Windows Forms 的相关攻略。 

bcfcb2c04e950d2f3381e8d31eaf356f.png

Arm64

54f7790485fa967d3a88fff6fd3a2bac.png

这些天来,对于笔记本电脑、云硬件和其他设备来说,Arm64 令人兴奋不已。我们对 .NET 团队感到同样兴奋,并正在尽最大努力跟上这一行业趋势。我们直接与 Arm Holdings、Apple 和 Microsoft 的工程师合作,以确保我们的实施是正确和优化的,并且我们的计划保持一致。这些密切的合作伙伴关系对我们帮助很大。

  • 特别感谢 Apple 在 M1 芯片发布之前向我们的团队发送了一蒲式耳 Arm64 开发套件供我们使用,并提供了重要的技术支持。

  • 特别感谢 Arm Holdings,他们的工程师对我们的 Arm64 更改进行了代码审查,并进行了性能改进。

在此之前,我们通过 .NET Core 3.0 和 Arm32 添加了对 Arm64 的初始支持。该团队在最近的几个版本中都对 Arm64 进行了重大投资,并且在可预见的未来这将继续下去。在 .NET 6 中,我们主要关注在 macOS 和 Windows Arm64 操作系统上支持新的 Apple Silicon 芯片和x64 仿真场景。

您可以在 macOS 11+ 和 Windows 11+ Arm64 操作系统上安装 Arm64 和 x64 版本的 .NET。我们必须做出多种设计选择和产品更改以确保其奏效。

我们的策略是“亲原生架构”。我们建议您始终使用与原生架构相匹配的 SDK,即 macOS 和 Windows Arm64 上的 Arm64 SDK。SDK 是大量的软件。在 Arm64 芯片上本地运行的性能将比仿真高得多。我们更新了 CLI 以简化操作。我们永远不会专注于优化模拟 x64。

默认情况下,如果您dotnet run是带有 Arm64 SDK 的 .NET 6 应用程序,它将作为 Arm64 运行。您可以使用参数轻松切换到以 x64 运行,例如-adotnet run -a x64. 相同的论点适用于其他 CLI 动词。有关更多信息,请参阅适用于 macOS 和 Windows Arm64 的 .NET 6 RC2 更新。

我想确保涵盖其中的一个微妙之处。当您使用-a x64时,SDK 仍以 Arm64 方式原生运行。.NET SDK 体系结构中存在进程边界的固定点。在大多数情况下,一个进程必须全是 Arm64 或全是 x64。我正在简化一点,但 .NET CLI 会等待 SDK 架构中的最后一个进程创建,然后将其作为您请求的芯片架构(如 x64)启动。这就是您的代码运行的过程。这样,作为开发人员,您可以获得 Arm64 的好处,但您的代码可以在它需要的过程中运行。这仅在您需要将某些代码作为 x64 运行时才相关。如果你不这样做,那么你可以一直以 Arm64 的方式运行所有东西,这很棒。

Arm64 支持

对于 macOS 和 Windows Arm64,以下是您需要了解的要点:

  • 支持并推荐 .NET 6 Arm64 和 x64 SDK。

  • 支持所有支持的 Arm64 和 x64 运行时。

  • .NET Core 3.1 和 .NET 5 SDK 可以工作,但提供的功能较少,并且在某些情况下不受完全支持。

  • dotnet test 尚未与 x64 仿真一起正常工作。我们正在努力。dotnet test 将作为 6.0.200 版本的一部分进行改进,并且可能更早。

有关更多完整信息,请参阅.NET 对 macOS 和 Windows Arm64的支持。

此讨论中缺少 Linux。它不像 macOS 和 Windows 那样支持 x64 仿真。因此,这些新的 CLI 特性和支持方法并不直接适用于 Linux,Linux 也不需要它们。

视窗 Arm64

我们有一个简单的工具来演示.NET 运行的环境。

C:Usersrich>dotnet tool install -g dotnet-runtimeinfo
You can invoke the tool using the following command: dotnet-runtimeinfo
Tool 'dotnet-runtimeinfo' (version '1.0.5') was successfully installed.C:Usersrich>dotnet runtimeinfo4242              ,d                             ,d42              42                             42,adPPYb,42  ,adPPYba, MM42MMM 8b,dPPYba,   ,adPPYba, MM42MMM
a8"    `Y42 a8"     "8a  42    42P'   `"8a a8P_____42   42
8b       42 8b       d8  42    42       42 8PP"""""""   42
"8a,   ,d42 "8a,   ,a8"  42,   42       42 "8b,   ,aa   42,`"8bbdP"Y8  `"YbbdP"'   "Y428 42       42  `"Ybbd8"'   "Y428

**.NET information

Version: 6.0.0

FrameworkDescription: .NET 6.0.0-rtm.21522.10

Libraries version: 6.0.0-rtm.21522.10

Libraries hash: 4822e3c3aa77eb82b2fb33c9321f923cf11ddde6

**Environment information

ProcessorCount: 8

OSArchitecture: Arm64

OSDescription: Microsoft Windows 10.0.22494

OSVersion: Microsoft Windows NT 10.0.22494.0

如您所见,该工具在 Windows Arm64 上本机运行。我将向您展示 ASP.NET Core 的样子。

9128451493694d815491feeff9ca81cd.png

macOS Arm64

您可以看到在 macOS Arm64 上的体验是相似的,并且还展示了架构目标。

rich@MacBook-Air app % dotnet --version
6.0.100
rich@MacBook-Air app % dotnet --info | grep RIDRID:         osx-arm64
rich@MacBook-Air app % cat Program.cs 
using System.Runtime.InteropServices;
using static System.Console;
WriteLine($"Hello, {RuntimeInformation.OSArchitecture} from {RuntimeInformation.FrameworkDescription}!");
rich@MacBook-Air app % dotnet run
Hello, Arm64 from .NET 6.0.0-rtm.21522.10!
rich@MacBook-Air app % dotnet run -a x64
Hello, X64 from .NET 6.0.0-rtm.21522.10!
rich@MacBook-Air app %

这张图片展示了 Arm64 执行是 Arm64 SDK 的默认设置,以及使用-a参数在目标 Arm64 和 x64 之间切换是多么容易。完全相同的体验适用于 Windows Arm64。

1fc6f7e000d0c8061613a1da432069a0.png

此图像演示了相同的内容,但使用的是 ASP.NET Core。我正在使用与您在上图中看到的相同的 .NET 6 Arm64 SDK。

Arm64 上的 Docker

Docker 支持在本机架构和仿真中运行的容器,本机架构是默认的。这看起来很明显,但当大多数 Docker Hub 目录都是面向 x64 时,这可能会让人感到困惑。您可以使用--platform linux/amd64来请求 x64 图像。

我们仅支持在 Arm64 操作系统上运行 Linux Arm64 .NET 容器映像。这是因为我们从不支持在QEMU中运行 .NET ,这是 Docker 用于架构模拟的。看来这可能是由于 QEMU 的限制。

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

0be3393a29100620d121ce7d18fb117e.png

此图像演示了我们维护的控制台示例:mcr.microsoft.com/dotnet/samples. 这是一个有趣的示例,因为它包含一些基本逻辑,用于打印您可以使用的 CPU 和内存限制信息。我展示的图像设置了 CPU 和内存限制。

自己试试吧:docker run --rm mcr.microsoft.com/dotnet/samples

Arm64 性能

Apple Silicon 和 x64 仿真支持项目非常重要,但是,我们也普遍提高了 Arm64 性能。

63b769924a4772e3dd841ecee1a5f67a.png

此图像演示了将堆栈帧的内容清零的改进,这是一种常见的操作。绿线是新行为,而橙色线是另一个(不太有益的)实验,两者都相对于基线有所改善,由蓝线表示。对于此测试,越低越好。

fb365ed044d1284b77a6db6df0c5f82d.png

容器

4f4aa6040109abbe17493f62d512b49c.png

.NET 6 更适合容器,主要基于本文中讨论的所有改进,适用于 Arm64 和 x64。我们还进行了有助于各种场景的关键更改。使用 .NET 6 验证容器改进演示了其中一些改进正在一起测试。

Windows 容器改进和新环境变量也包含在 11 月 9 日(明天)发布的11 月 .NET Framework 4.8 容器更新中。

发布说明可在我们的 docker 存储库中找到:

  • .NET 6 容器发行说明

  • .NET Framework 4.8 2021 年 11 月容器发行说明

Windows 容器

.NET 6 增加了对 Windows 进程隔离容器的支持。如果您在 Azure Kubernetes 服务 (AKS) 中使用 Windows 容器,那么您依赖于进程隔离的容器。进程隔离容器可以被认为与 Linux 容器非常相似。Linux 容器使用cgroups,Windows 进程隔离容器使用Job Objects。Windows 还提供 Hyper-V 容器,通过更强大的虚拟化提供更大的隔离。Hyper-V 容器的 .NET 6 没有任何变化。

此更改的主要价值是现在 Environment.ProcessorCount 将使用 Windows 进程隔离容器报告正确的值。如果在 64 核机器上创建 2 核容器,Environment.ProcessorCount 将返回2. 在以前的版本中,此属性将报告机器上的处理器总数,与 Docker CLI、Kubernetes 或其他容器编排器/运行时指定的限制无关。此值被 .NET 的各个部分用于扩展目的,包括 .NET 垃圾收集器(尽管它依赖于相关的较低级别的 API)。社区库也依赖此 API 进行扩展。

我们最近在 AKS 上使用大量 pod 在生产中的 Windows 容器上与客户验证了这一新功能。他们能够以 50% 的内存(与他们的典型配置相比)成功运行,这是以前导致异常的OutOfMemoryException水平StackOverflowException。他们没有花时间找到最低内存配置,但我们猜测它明显低于他们典型内存配置的 50%。由于这一变化,他们将转向更便宜的 Azure 配置,从而节省资金。只需升级即可,这是一个不错的、轻松的胜利。

优化缩放

我们从用户那里听说,某些应用程序在 Environment.ProcessorCount 报告正确的值时无法实现最佳扩展。如果这听起来与您刚刚阅读的有关 Windows 容器的内容相反,那么它有点像。.NET 6 现在提供 DOTNET_PROCESSOR_COUNT 环境变量来手动控制 Environment.ProcessorCount 的值。在典型的用例中,应用程序可能在 64 核机器上配置为 4 核,并且在 8 或 16 核方面扩展得最好。此环境变量可用于启用该缩放。

这个模型可能看起来很奇怪,其中Environment.ProcessorCount和--cpus(通过 Docker CLI)值可能不同。默认情况下,容器运行时面向核心等价物,而不是实际核心。这意味着,当你说你想要 4 个核心时,你得到的 CPU 时间与 4 个核心相当,但你的应用程序可能(理论上)在更多的核心上运行,甚至在短时间内在 64 核机器上运行所有 64 个核心。这可能使您的应用程序能够在超过 4 个线程上更好地扩展(继续示例),并且分配更多可能是有益的。这假定线程分配基于Environment.ProcessorCount 的值。如果您选择设置更高的值,您的应用程序可能会使用更多内存。对于某些工作负载,这是一个简单的权衡。至少,这是一个您可以测试的新选项。

Linux 和 Windows 容器均支持此新功能。

Docker 还提供了一个 CPU 组功能,您的应用程序可以关联到特定的内核。在这种情况下不建议使用此功能,因为应用程序可以访问的内核数量是具体定义的。我们还看到了将它与 Hyper-V 容器一起使用时的一些问题,并且它并不是真正适用于那种隔离模式。

Debian 11“bullseye”

我们密切关注 Linux 发行版的生命周期和发布计划,并尝试代表您做出最佳选择。Debian 是我们用于默认 Linux 映像的 Linux 发行版。如果您6.0从我们的一个容器存储库中提取标签,您将提取一个 Debian 映像(假设您使用的是 Linux 容器)。对于每个新的 .NET 版本,我们都会考虑是否应该采用新的 Debian 版本。

作为一项政策,我们不会为了方便标签而更改 Debian 版本,例如6.0, mid-release。如果我们这样做了,某些应用程序肯定会崩溃。这意味着,在发布开始时选择 Debian 版本非常重要。此外,这些图像得到了很多使用,主要是因为它们是“好标签”的引用。

Debian 和 .NET 版本自然不会一起计划。当我们开始 .NET 6 时,我们看到 Debian “bullseye” 可能会在 2021 年发布。我们决定从发布开始就押注于 Bullseye。我们开始使用.NET 6 Preview 1发布基于靶心的容器映像,并决定不再回头。赌注是 .NET 6 版本会输掉与靶心版本的竞争。到 8 月 8 日,我们仍然不知道 Bullseye 什么时候发货,距离我们自己的版本发布还有三个月,即 11 月 8 日。我们不想在预览版 Linux 上发布生产 .NET 6,但我们坚持我们会输掉这场竞赛的计划很晚。

当 Debian 11 “bullseye”于 8 月 14 日发布时,我们感到非常惊喜。我们输掉了比赛,但赢得了赌注。这意味着默认情况下,.NET 6 用户从第一天开始就可以获得最佳和最新的 Debian。我们相信 Debian 11 和 .NET 6 将是许多用户的绝佳组合。抱歉,克星,我们中了靶心。

较新的发行版在其软件包提要中包含各种软件包的较新主要版本,并且通常可以更快地获得CVE 修复。这是对较新内核的补充。新发行版可以更好地为用户服务。

再往前看,我们很快就会开始计划对Ubuntu 22.04的支持。Ubuntu是另一个 Debian 系列发行版,深受 .NET 开发人员的欢迎。我们希望为新的 Ubuntu LTS 版本提供当日支持。

向 Tianon Gravi 致敬,感谢他们为社区维护 Debian 映像并在我们有问题时帮助我们。

Dotnet Monitor

dotnet monitor 是容器的重要诊断工具。它作为 sidecar 容器镜像已经有一段时间了,但处于不受支持的“实验”状态。作为 .NET 6 的一部分,我们正在发布一个基于 .NET 6 的 dotnet monitor映像,该映像在生产中得到完全支持。

dotnet monitor 已被 Azure App Service 用作其 ASP.NET Core Linux 诊断体验的实现细节。这是预期的场景之一,建立在 dotnet monitor 之上,以提供更高级别和更高价值的体验。

您现在可以拉取新图像:

docker pull mcr.microsoft.com/dotnet/monitor:6.0

dotnet monitor 使从 .NET 进程访问诊断信息(日志、跟踪、进程转储)变得更加容易。在台式机上访问所需的所有诊断信息很容易,但是,这些熟悉的技术在使用容器的生产环境中可能不起作用。dotnet monitor 提供了一种统一的方式来收集这些诊断工件,无 论是在您的桌面计算机上还是在 Kubernetes 集群中运行。收集这些诊断工件有两种不同的机制:

  • 用于临时收集工件的 HTTP API 。当您已经知道您的应用程序遇到问题并且您有兴趣收集更多信息时,您可以调用这些 API 端点。

  • 基于规则的配置触发器,用于始终在线收集工件。您可以配置规则以在满足所需条件时收集诊断数据,例如,当您持续高 CPU 时收集进程转储。

dotnet monitor 为 .NET 应用程序提供了一个通用的诊断 API,可以使用任何工具在任何地方工作。“通用 API”不是 .NET API,而是您可以调用和查询的 Web API。dotnet monitor 包括一个 ASP.NET Web 服务器,它直接与 .NET 运行时中的诊断服务器交互并公开来自诊断服务器的数据。的设计 dotnet monitor 可实现生产中的高性能监控和安全使用,以控制对特权信息的访问。dotnet monitor 通过非 Internet 可寻址的 unix domain socket 与运行时交互——跨越容器边界。该模型通信模型非常适合此用例。

结构化 JSON 日志

JSON 格式化程序现在是 aspnet.NET 6 容器映像中的默认控制台记录器。.NET 5 中的默认设置为简单的控制台格式化程序。进行此更改是为了使默认配置与依赖机器可读格式(如 JSON)的自动化工具一起使用。

图像的输出现在如下所示 aspnet:

$ docker run --rm -it -p 8000:80 mcr.microsoft.com/dotnet/samples:aspnetapp
{"EventId":60,"LogLevel":"Warning","Category":"Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository","Message":"Storing keys in a directory u0027/root/.aspnet/DataProtection-Keysu0027 that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.","State":{"Message":"Storing keys in a directory u0027/root/.aspnet/DataProtection-Keysu0027 that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.","path":"/root/.aspnet/DataProtection-Keys","{OriginalFormat}":"Storing keys in a directory u0027{path}u0027 that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed."}}
{"EventId":35,"LogLevel":"Warning","Category":"Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager","Message":"No XML encryptor configured. Key {86cafacf-ab57-434a-b09c-66a929ae4fd7} may be persisted to storage in unencrypted form.","State":{"Message":"No XML encryptor configured. Key {86cafacf-ab57-434a-b09c-66a929ae4fd7} may be persisted to storage in unencrypted form.","KeyId":"86cafacf-ab57-434a-b09c-66a929ae4fd7","{OriginalFormat}":"No XML encryptor configured. Key {KeyId:B} may be persisted to storage in unencrypted form."}}
{"EventId":14,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Now listening on: http://[::]:80","State":{"Message":"Now listening on: http://[::]:80","address":"http://[::]:80","{OriginalFormat}":"Now listening on: {address}"}}
{"EventId":0,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Application started. Press Ctrlu002BC to shut down.","State":{"Message":"Application started. Press Ctrlu002BC to shut down.","{OriginalFormat}":"Application started. Press Ctrlu002BC to shut down."}}
{"EventId":0,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Hosting environment: Production","State":{"Message":"Hosting environment: Production","envName":"Production","{OriginalFormat}":"Hosting environment: {envName}"}}
{"EventId":0,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Content root path: /app","State":{"Message":"Content root path: /app","contentRoot":"/app","{OriginalFormat}":"Content root path: {contentRoot}"}}

Logging__Console__FormatterName 可以通过设置或取消设置环境变量或通过代码更改来更改记录器格式类型(有关更多详细信息,请参阅控制台日志格式)。

更改后,您将看到如下输出(就像 .NET 5 一样):

$ docker run --rm -it -p 8000:80 -e Logging__Console__FormatterName="" mcr.microsoft.com/dotnet/samples:aspnetapp
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]No XML encryptor configured. Key {8d4ddd1d-ccfc-4898-9fe1-3e7403bf23a0} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[14]Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]Content root path: /app

注意:此更改不会影响开发人员计算机上的 .NET SDK,例如 dotnet run. 此更改特定于 aspnet 容器映像。

b39bee094cbaad9b45baf766f422cc0b.png

支持 OpenTelemetry 指标

f2dd5ce2ff8ce75bb61dcf38d6784e03.png

作为我们关注可观察性的一部分,我们一直在为最后几个 .NET 版本添加对 OpenTelemetry 的支持。在 .NET 6 中,我们添加了对 OpenTelemetry Metrics API的支持。通过添加对 OpenTelemetry 的支持,您的应用程序可以与其他 OpenTelemetry 系统无缝互操作。

System.Diagnostics.Metrics 是 OpenTelemetry Metrics API 规范的 .NET 实现。Metrics API 是专门为处理原始测量而设计的,目的是高效、同时地生成这些测量的连续摘要。

API 包括 Meter 可用于创建仪器对象的类。API 公开了四个工具类:Counter、Histogram、ObservableCounter 和 ObservableGauge 以支持不同的度量方案。此外,API 公开 MeterListener 该类以允许收听仪器记录的测量值,以用于聚合和分组目的。

OpenTelemetry .NET 实现将被扩展以使用这些新的 API,这些 API 添加了对 Metrics 可观察性场景的支持。

▌图书馆测量记录示例

Meter meter = new Meter("io.opentelemetry.contrib.mongodb", "v1.0");Counter<int> counter = meter.CreateCounter<int>("Requests");counter.Add(1);counter.Add(1, KeyValuePair.Create<string, object>("request", "read"));

▌听力示例

MeterListener listener = new MeterListener();listener.InstrumentPublished = (instrument, meterListener) =>{if (instrument.Name == "Requests" && instrument.Meter.Name == "io.opentelemetry.contrib.mongodb"){meterListener.EnableMeasurementEvents(instrument, null);}};listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) =>{Console.WriteLine($"Instrument: {instrument.Name} has recorded the measurement {measurement}");});listener.Start();

1f8ac03a1fe36d26e5aed22ad4c8055b.png

Windows Forms

43e830158b1164cb9818ea9ddef6d301.png

我们继续在 Windows 窗体中进行重要改进。.NET 6 包括更好的控件可访问性、设置应用程序范围的默认字体、模板更新等的能力。

▌可访问性改进

在此版本中,我们添加了用于CheckedListBox、LinkLabel、Panel、ScrollBar和TabControlTrackBar的UIA 提供程序,它们使讲述人等工具和测试自动化能够与应用程序的元素进行交互。

▌默认字体

您现在可以使用.Application.SetDefaultFont

void Application.SetDefaultFont(Font font)

▌最小的应用程序

以下是带有 .NET 6 的最小 Windows 窗体应用程序:

class Program
{[STAThread]static void Main(){ApplicationConfiguration.Initialize();Application.Run(new Form1());}
}

作为 .NET 6 版本的一部分,我们一直在更新大多数模板,使其更加现代和简约,包括 Windows 窗体。我们决定让 Windows 窗体模板更传统一些,部分原因是需要将[STAThread]属性应用于应用程序入口点。然而,还有更多的戏剧而不是立即出现在眼前。

ApplicationConfiguration.Initialize()是一个源生成 API,它在后台发出以下调用:

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetDefaultFont(new Font(...));
Application.SetHighDpiMode(HighDpiMode.SystemAware);

这些调用的参数可通过 csproj 或 props 文件中的 MSBuild 属性进行配置。

Visual Studio 2022 中的 Windows 窗体设计器也知道这些属性(目前它只读取默认字体),并且可以向您显示您的应用程序,就像它在运行时一样:

8dffbaec42252d2db0c3aeb6e4aa4cb0.png

▌模板更新

C# 的 Windows 窗体模板已更新,以支持新的应用程序引导、global using 指令、文件范围的命名空间和可为空的引用类型。

▌更多运行时 designers

现在您可以构建通用设计器(例如,报表设计器),因为 .NET 6 具有设计器和与设计器相关的基础架构所缺少的所有部分。有关详细信息,请参阅此博客文章。

  • 博客文章

    https://devblogs.microsoft.com/dotnet/whats-new-in-windows-forms-in-net-6-0-preview-5/#more-runtime-designers

未完待续

更多内容请继续关注明日(周日)文章

2b8d82020a1a7f7ba4d0996f79ad6955.gif

 了解更多.NET 6 

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

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

相关文章

ubuntu 开启 apache mod_rewrite

2019独角兽企业重金招聘Python工程师标准>>> ci里需要隐藏index.php的输入需要使用apache的rewrite模块,按照下面的步骤开启mod_rewrite http://www.dev-metal.com/enable-mod_rewrite-ubuntu-14-04-lts/ 转载于:https://my.oschina.net/u/1177171/blog/354202

composer切换源_Composer具体安装方法

composer 作为依赖管理工具&#xff0c;使用频率还是挺高的。特别是对于我这种比较懒的程序猿&#xff0c;有现成轮子的时候坚决不自己重复造轮子。它主要有三部分构成&#xff1a;命令行工具&#xff0c;包仓库&#xff0c;代码库。包仓库就是我们常说的 composer 源&#xff…

C# 操作FireBird 附源码

写了一个C#操作firebird数据库的小Demo&#xff0c;有需要的可以研究研究, 步骤&#xff1a; 1.创建数据库 2.建数据表&#xff0c;插入数据&#xff0c;并读取、 写的时候碰到N多奇葩问题&#xff0c;记录了一些 解决方案&#xff1a; 程序集-生成-目标平台 改成 x86 源码地址…

.NET 6 攻略大全(三)

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;15分钟).NET 6 继续与大家相约周日啦。本篇文章将介绍&#xff1a;单文件应用、IL 修整、System.Text.Json、源代码构建、库AIP的相关攻略。 单文件应用 在 .NET 6中&#xff0c;已为 Windows 和 macOS 启用内存中单文…

测试眉形的有哪个软件_这五款自动化软件测试工具,你最喜欢用哪个?

对测试自动化的依赖性增加导致大量自动化软件测试工具的出现&#xff0c;使得很难确定哪些是最好的。为了帮助您完成自动化工作&#xff0c;我们根据自己和他人的经验创建了五大最佳自动化软件测试工具列表。1. SeleniumSelenium可以说是web开发人员和测试人员中最受欢迎的自动…

本科 8年经验,20k的Offer,接还是不接?

伴随着疫情的此起彼伏&#xff0c;今年的金三银四跳槽季比往年要低沉很多&#xff0c;近日一条朋友圈火遍社区&#xff0c;“坐标一线城市&#xff0c;本科毕业&#xff0c;8年经验&#xff0c;15天仅5场面试&#xff0c;最终接了20k的offer&#xff0c;今年真难&#xff01;”…

CAD中批量打印

同事在网上找各种软件来实现CAD图的批量打印&#xff0c;总是问题多多。于是&#xff0c;我想到一个更方便的解决方法&#xff0c;即只要我将一个打印出来&#xff0c;然后就可以用批量处理来实现。 1.在CAD中输入plot命令&#xff08;或快捷键CtrlP&#xff09;&#xff0c;即…

Photoshop脚本 使用ExtendScript编写Ps脚本

源自&#xff1a;http://coolketang.com/tutorials/menu1lesson3.php本节课程将演示如何使用ExtendScript编写脚本&#xff0c;它是由Adobe公司开发的一款脚本语言工具包。以后的所有课程也将使用这款工具编写脚本。您可以在开始菜单(Windows电脑)或Application目录(Mac电脑)上…

CentOS6.4安装Vbox增强包

2019独角兽企业重金招聘Python工程师标准>>> 1、升级#yum update2、安装gcc #yum install gcc安装编译系统3、安装外置核心模块#yum install kernel-devel4、添加一个连接 ln -s /usr/src/kernels/2.6.18- 164.15.1.el5-i686(内核版本) /usr/src/linux 5、重启以…

eltree ref什么时候有_Vue3响应式系统源码解析-Ref篇

文章转载自&#xff1a;https://zhuanlan.zhihu.com/p/85978064我们阅读源码的原因是什么&#xff1f;无非是1&#xff1a;学习&#xff1b;2&#xff1a;更好的使用这个库。如果只是想大致的了解下原理&#xff0c;倒不必花时间阅读源码&#xff0c;几句话&#xff0c;几张图就…

java邮件系统(java邮件收发系统源代码和下载地址)

2019独角兽企业重金招聘Python工程师标准>>> 本软件包包括源文件和可执行的jar文件 项目下载地址&#xff1a; 下载 1. 运行方式 A可以直接运行jar文件&#xff08;电脑上必须安装jdk1.6而且关联jar文件&#xff09; B可以用eclipse导入源文件然后运行 2功能简介…

两对光纤收发器用网线连接_为什么现在的人不喜欢用网线,反而更爱用光纤来传输呢?涨知识了...

随着通信技术的不断发展&#xff0c;信号传输介质已从原来的同轴电缆逐渐变为光纤。光纤传输完全满足大容量数据通信正确&#xff0c;可靠&#xff0c;高速传输和处理的要求&#xff0c;已成为世界上主要的通信方式。本文主要详细介绍光纤传输的基本知识&#xff0c;希望对您有…

openGauss学习笔记-170 openGauss 数据库运维-备份与恢复-导入数据-更新表中数据-使用合并方式更新和插入数据

文章目录 openGauss学习笔记-170 openGauss 数据库运维-备份与恢复-导入数据-更新表中数据-使用合并方式更新和插入数据170.1 前提条件170.2 操作步骤 openGauss学习笔记-170 openGauss 数据库运维-备份与恢复-导入数据-更新表中数据-使用合并方式更新和插入数据 在用户需要将…

C和指针之动态内存分配之编程练习4

1、问题 4.编写一个程序&#xff0c;按照下图中的样子创建数据结构&#xff0c;最后三个对象都是动态分配的结构。第一个对象则可能是一个静态的指向结构的指针。你不必使这个程序过于全面--我们将在下一章讨论这个结构。 2、代码实现 #include <stdio.h> #include <s…

.NET 6 攻略大全(四)

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;15分钟)接上篇内容&#xff0c;本篇文章将介绍&#xff1a;DependentHandle 现已公开、RyuJIT、即用型代码/Crossgen 2、.NET 诊断&#xff1a;EventPipe、SDK 的相关攻略。 DependentHandle 现已公开该 DependentHan…

[No000022]他们说:得诺贝尔奖到底有多难?

转载于:https://www.cnblogs.com/Chary/p/No000022.html

java操作redis简单学习3

2019独角兽企业重金招聘Python工程师标准>>> package com.hanchao.testredis;import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Set;import redis.clients.jedis.Jedis;import com.alibaba.fastjson.JSON; import com.al…

Xamarin效果第三篇之手机底部弹窗

前面一篇文章把基本的大框架搞定了,这不再逐个去实现里面的细节;今天主要是分享点击了CollectionView内的点点点然后从手机底部弹出一个可以交互的窗口;直接看看最终实现的效果:作为初来乍到的小萌新只能求助万能的群友让大佬们给指条光明通畅的大道,不然容易跑偏;最终给的方向…

自定义sql_一个简单易用的开源BI软件,专为SQL用户设计的开源库

poli一个易于使用的SQL报告应用程序&#xff0c;专为SQL爱好者而设计。SQL中的电源数据分析&#xff0c;可获得更快的业务洞察力。特性⚡️ 自托管和轻松设置平台独立的Web应用程序 单个JAR文件单个SQLite DB文件。在5分钟内启动并运行。连接任何支持JDBC驱动程序的数据库Postg…

echarty轴自定义显示不全_表格打印不全怎么办?这招超简单!

私信回复关键词【福利】~获取丰富办公资源&#xff0c;助你高效办公早下班&#xff01;大家好&#xff0c;我是小E~最近&#xff0c;秋叶 Excel 学习班花生 同学&#xff0c;从同事那里收到了一份开会要用的表格&#xff0c;需要马上就要打印出来。会议主题是&#xff0c;从五个…