Java 快速轉 C# 教程

以下是一個針對 Java 開發者快速轉向 C# 的簡明教程,重點對比 Java 與 C# 的異同,幫助你快速上手。


項目結構:

  • .sln :解決方案文件,管理多個項目之間的依賴關系。
  • .csproj :項目文件,定義目標框架(如 net6.0)、依賴項(NuGet 包或本地 DLL)。
  • global.json: 控制 .NET SDK 行為
    • 指定 .NET SDK 版本 :確保項目使用特定版本的 SDK 構建(避免本地環境版本不一致)。
    • 控制項目掃描范圍 :在多項目解決方案中,指定哪些目錄參與構建。
    • 啟用/禁用 SDK 安裝提示 :控制是否自動下載未安裝的 SDK 版本。
  • app.manifest: 應用程序清單文件
    • 聲明應用程序權限 (如以管理員身份運行)。
    • 指定兼容性需求 (如支持的 Windows 版本)。
    • 啟用 Visual Studio 高 DPI 支持 。
    • 配置應用程序隔離(Side-by-Side Assembly) 。
  • Program.cs :程序入口(包含 Main 方法)。

一、基礎語法對比

1. 變量與數據類型

JavaC#
int a = 10;int a = 10;
String name = "Hello";string name = "Hello";
final int MAX = 100;const int MAX = 100;
var list = new ArrayList<>(); (Java 10+)var list = new List<string>();

C# 特色:

  • var 是隱式類型變量(編譯器推斷類型)。
  • dynamic 類型可動態賦值(類似 Object)。

2. 拓展方法

C# 的擴展方法允許你為現有類型 (包括密封類、接口、甚至第三方庫的類型)“添加”方法,而無需修改其源代碼或繼承。這是 C# 特有的語法特性,Java 中無直接等價物(需通過工具類或繼承實現)。

定義擴展方法

  • 必須在靜態類 中定義。
  • 第一個參數使用 this 關鍵字,表示該方法擴展的目標類型
// 靜態類:擴展方法容器
public static class StringExtensions {// 擴展 string 類型的方法public static bool IsNullOrEmpty(this string str) {return string.IsNullOrEmpty(str);}
}

使用拓展方法

string name = null;// 調用擴展方法(如同實例方法)
if (name.IsNullOrEmpty()) {Console.WriteLine("Name is null or empty");
}

值得注意的是,拓展方法作為一個語法糖對應的可以解決在Java中 xxUtils 的工具類。同時具有以下注意:

  • 無法訪問內部方法/屬性
  • 若類型本身有同名方法,實例方法優先于擴展方法
  • 避免過度使用,防止命名沖突(需顯式導入命名空間)

3. 空運算符(Null Handling Operators)

C# 提供了強大的空值處理運算符,簡化空值檢查邏輯,避免 NullReferenceException

1. 空條件運算符(?.

用于安全訪問對象的成員,若對象為 null 則返回 null 而非拋出異常。

Person person = GetPerson(); // 可能為 null// 安全訪問屬性和方法
int length = person?.Name?.Length ?? 0;
person?.SayHello();

對比 Java

  • Java 中需顯式判斷或使用 Optional

    int length = Optional.ofNullable(person).map(p -> p.getName()).map(String::length).orElse(0);
    
2. 空合并運算符(??

提供默認值,當左側表達式為 null 時返回右側值。

string name = null;
string displayName = name ?? "Guest"; // 如果 name 為 null,則使用 "Guest"

對比 Java

  • Java 中使用三元運算符或 Optional

    String displayName = name != null ? name : "Guest";
    // 或
    String displayName = Optional.ofNullable(name).orElse("Guest");
    
3. 空合并賦值運算符(??=

僅當變量為 null 時才賦值(C# 8.0+)。

string message = GetMessage();
message ??= "Default Message"; // 如果 GetMessage() 返回 null,則賦值為默認值

對比 Java

  • Java 中需顯式判斷:
    if (message == null) {message = "Default Message";
    }
    

4. 非空斷言運算符(!

告知編譯器某個表達式不為 null(C# 8.0+,用于可空引用類型上下文)。

string name = GetName()!; // 告訴編譯器 GetName() 返回值不為 null

注意事項

  • 空條件運算符返回的類型可能是 null(需結合 ?? 使用)。
  • 空合并運算符適用于 null 檢查,但不適用于值類型(如 int)。
  • 使用 ?.?? 組合可顯著減少防御性代碼(如嵌套 if 判斷)。

二、面向對象編程

1. 類與對象

public class Person {// 字段private string name;// 屬性(推薦封裝字段)public string Name {get { return name; }set { name = value; }}// 構造函數public Person(string name) {this.name = name;}// 方法public void SayHello() {Console.WriteLine($"Hello, {name}");}
}

對比 Java:

  • C# 使用 property(屬性)替代 Java 的 getter/setter
  • this 關鍵字用法相同。

2. 繼承與接口

// 繼承
public class Student : Person {public Student(string name) : base(name) {}
}// 接口
public interface IRunnable {void Run();
}public class Car : IRunnable {public void Run() {Console.WriteLine("Car is running");}
}

對比 Java:

  • C# 使用 : 替代 Java 的 extends/implements
  • 接口方法默認 public,無需顯式聲明。

三、C# 特有特性

1. 委托與事件(Delegates & Events)

// 委托(類似 Java 的函數式接口)
// 定義一個名為 Notify 的委托類型,它表示一種方法模板,要求方法返回 void 并接受一個 string 參數
// 類比 Java :類似 Java 中的函數式接口(如 Consumer<String>),但 C# 的委托更直接,可以直接綁定方法。
public delegate void Notify(string message);// 事件
public class EventPublisher {// 聲明一個事件 OnNotify,其類型是 Notify 委托。事件本質上是委托的安全封裝,外部只能通過 +=/-= 訂閱/取消訂閱,不能直接調用(如 OnNotify.Invoke() 會報錯)。public event Notify OnNotify;// 調用 OnNotify?.Invoke(...) 觸發事件,?. 是空值保護操作符(避免空引用異常)。只有當至少有一個訂閱者時,才會執行。public void TriggerEvent() {OnNotify?.Invoke("Event triggered!");}
}// 使用
EventPublisher publisher = new EventPublisher();
publisher.OnNotify += (msg) => Console.WriteLine(msg);
publisher.TriggerEvent();
  • 訂閱事件
    使用 +=運算符將一個 lambda 表達式 (msg) => Console.WriteLine(msg)綁定到 OnNotify 事件。當事件觸發時,會執行此方法。

  • 觸發事件
    調用 TriggerEvent() 后,所有訂閱者都會收到 “Event triggered!” 消息。

2. LINQ(Language Integrated Query)

var numbers = new List<int> { 1, 2, 3, 4, 5 };
var even = numbers.Where(n => n % 2 == 0).ToList();

對比 Java:

  • 類似 Java Stream,但語法更簡潔。

3. 異步編程(Async/Await)

public async Task DownloadDataAsync() {var client = new HttpClient();var data = await client.GetStringAsync("https://example.com");Console.WriteLine(data);
}

對比 Java:

  • 類似 CompletableFuture,但語法更直觀。

Parallel.Invoke(() => {// 并行執行CPU密集任務
});
  • 多個 CPU 密集型任務并行執行。
  • 任務之間沒有依賴。
  • 不需要返回結果。

四、常用工具與框架

JavaC#
Maven/GradleNuGet(包管理)
Spring.NET Core(框架)
JUnitxUnit/NUnit(測試框架)
IntelliJ IDEAVisual Studio / IntelliJ Rider(IDE)

五、項目結構與命名空間

// 文件:Program.cs
using System;
namespace MyApplication;class Program {static void Main(string[] args) {Console.WriteLine("Hello World!");}
}

對比 Java:

  • C# 使用 namespace 組織代碼,Java 使用 package
  • 程序入口是 Main 方法(Java 是 main)。

六、Java 到 C# 的常見轉換技巧

JavaC#
System.out.println()Console.WriteLine()
ArrayList<T>List<T>
HashMap<K,V>Dictionary<K,V>
interfaceinterface
enumenum
try-catch-finallytry-catch-finally

C# 中,反射(Reflection) 是一種強大的機制,允許在運行時動態地獲取類型信息、創建對象實例、調用方法、訪問字段和屬性等。對于從 Java 轉向 C# 的開發者來說,反射的概念是相似的,但 C# 的反射 API 更加簡潔、直觀,并且與語言特性(如 dynamicnameofLINQ)結合更緊密。


七、反射

反射是指在 運行時(runtime) 動態地:

  • 獲取類型信息(如類名、方法、屬性等)
  • 創建對象實例
  • 調用方法、訪問字段或屬性
  • 檢查程序集(Assembly)的結構

Java 與 C# 反射的對比

功能JavaC#
獲取類型對象MyClass.classobj.getClass()typeof(MyClass)obj.GetType()
獲取方法clazz.getMethod("name", params...)type.GetMethod("Name")
調用方法method.invoke(obj, args)method.Invoke(obj, args)
獲取屬性clazz.getDeclaredField("name")type.GetProperty("Name")
獲取程序集無直接等價物Assembly.GetExecutingAssembly()
動態創建實例clazz.newInstance()Activator.CreateInstance(type)
動態訪問成員通過 Field/Method 對象通過 PropertyInfo/MethodInfo

1. 獲取 Type 對象

// 通過類型名獲取
Type type = typeof(string);// 通過對象獲取
object obj = new Person();
Type type = obj.GetType();

2. 獲取類成員信息(屬性、方法、字段)

Type type = typeof(Person);// 獲取所有屬性
PropertyInfo[] properties = type.GetProperties();// 獲取特定方法
MethodInfo method = type.GetMethod("SayHello");// 獲取所有字段
FieldInfo[] fields = type.GetFields();

3. 動態創建實例

object person = Activator.CreateInstance(typeof(Person));

4. 調用方法

MethodInfo method = type.GetMethod("SayHello");
method.Invoke(person, null);

5. 訪問屬性

PropertyInfo prop = type.GetProperty("Name");
prop.SetValue(person, "Alice");
string name = (string)prop.GetValue(person);

6. 訪問字段(不推薦,除非必要)

FieldInfo field = type.GetField("age", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(person, 30);
int age = (int)field.GetValue(person);

7. 獲取程序集信息

Assembly assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes()) {Console.WriteLine(type.Name);
}

8. 動態加載 DLL 并調用方法

Assembly assembly = Assembly.LoadFile("path/to/MyLibrary.dll");
Type type = assembly.GetType("MyNamespace.MyClass");
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("DoSomething");
method.Invoke(instance, null);

9. 使用 dynamic 替代部分反射操作

dynamic person = new ExpandoObject();
person.Name = "Bob";
person.SayHello = new Action(() => Console.WriteLine("Hello"));
person.SayHello(); // 無需反射即可調用

10. 使用 Expression 構建高性能的反射調用

Func<object> factory = Expression.Lambda<Func<object>>(Expression.New(typeof(Person))
).Compile();
object person = factory();

11. 使用 IL EmitSource Generator 優化性能

對于高性能場景(如 ORM、序列化框架),可以使用:

  • System.Reflection.Emit:動態生成 IL 代碼
  • Source Generator(C# 9+):編譯時生成代碼,避免運行時反射

性能問題

  • 反射調用比直接調用慢(約慢 10~100 倍)
  • 頻繁使用 GetMethodGetProperty 會增加開銷

解決方案

  • 緩存反射結果(如 MethodInfoPropertyInfo
  • 使用 Expression 構建委托
  • 使用 dynamic(在合適場景下)
  • 使用 System.Reflection.DispatchProxy 實現代理
  • 使用 System.Text.JsonNewtonsoft.Json 等庫已優化的反射機制

安全性

  • 可以訪問私有成員(需設置 BindingFlags.NonPublic
  • 在部分受限環境中(如 UWP、AOT 編譯)可能受限

Java 到 C# 反射的轉換技巧

JavaC#
Class.forName("MyClass")Type.GetType("MyNamespace.MyClass")
clazz.newInstance()Activator.CreateInstance(type)
method.invoke(obj, args)method.Invoke(obj, args)
clazz.getDeclaredMethods()type.GetMethods()
clazz.getDeclaredFields()type.GetFields()
clazz.getDeclaredField("name")type.GetField("Name")
clazz.getDeclaredMethod("name", params...)type.GetMethod("Name", parameterTypes)
clazz.getInterfaces()type.GetInterfaces()


八、引入包(NuGet 包管理)

在 C# 中,NuGet 是官方推薦的包管理系統,類似于 Java 中的 Maven/Gradle。它用于管理項目依賴項(如第三方庫、框架等)。

NuGet 包典型命名規則:[組織名].[功能模塊].[平臺/框架]

1. NuGet 的作用

  • 管理項目依賴(如 Newtonsoft.JsonEntityFramework 等)
  • 自動下載、安裝、更新依賴包
  • 支持跨平臺(Windows、Linux、macOS)

2. 常用方式

方法 1:通過 Visual Studio 引入
  1. 右鍵項目 → Manage NuGet Packages
  2. Browse 標簽頁搜索包名(如 Newtonsoft.Json
  3. 點擊 Install 安裝包
  4. 安裝完成后,會自動添加到項目中
方法 2:通過 CLI 命令行
# 安裝包
dotnet add package Newtonsoft.Json# 更新包
dotnet add package Newtonsoft.Json --version 13.0.1# 卸載包
dotnet remove package Newtonsoft.Json
方法 3:手動編輯 .csproj 文件

在項目文件中添加 <PackageReference>

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="Newtonsoft.Json" Version="13.0.1" /></ItemGroup>
</Project>

3. NuGet 源配置

默認源是 nuget.org,但也可以配置私有源(如公司內部源):

# 添加私有源
dotnet nuget add source https://mycompany.com/nuget -n MyCompany

4. 對比 Java

功能Java (Maven/Gradle)C# (NuGet)
包管理pom.xml / build.gradle.csproj
安裝包mvn install / gradle builddotnet add package
私有倉庫settings.xml / repositories { maven { url "..." } }dotnet nuget add source

九、引用本地的 DLL

有時你需要引用本地的 DLL 文件(如團隊內部開發的庫、第三方未提供 NuGet 包的庫),可以通過以下方式實現。

1. 添加本地 DLL 引用

方法 1:通過 Visual Studio 添加
  1. 右鍵項目 → Add → Reference…
  2. 在彈出窗口中選擇 Browse
  3. 瀏覽并選擇本地 DLL 文件(如 MyLibrary.dll
  4. 點擊 AddOK
方法 2:手動編輯 .csproj 文件
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net6.0</TargetFramework></PropertyGroup><ItemGroup><Reference Include="MyLibrary"><HintPath>..\Libraries\MyLibrary.dll</HintPath></Reference></ItemGroup>
</Project>

2. 確保 DLL 被正確復制到輸出目錄

.csproj 中添加以下配置,確保 DLL 被復制到 bin 目錄:

<ContentWithTargetPath Include="..\Libraries\MyLibrary.dll"><TargetPath>MyLibrary.dll</TargetPath><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</ContentWithTargetPath>

3. 加載本地 DLL 的運行時行為

  • Windows:直接復制到 bin\Debug\net6.0 目錄即可
  • Linux/macOS:確保 DLL 與主程序在同一目錄,或設置 LD_LIBRARY_PATH / DYLD_LIBRARY_PATH

4. 注意事項

  • 強名稱簽名(Strong Name):如果 DLL 是強名稱簽名的,引用時需確保簽名一致
  • 平臺相關性:某些 DLL 僅支持特定平臺(如 Windows 專用的 DLL)
  • 版本沖突:多個 DLL 依賴相同庫的不同版本時,可能出現沖突(需手動綁定重定向)

常見問題與解決方案

1. 無法找到 DLL

  • 原因:DLL 未正確復制到輸出目錄
  • 解決:檢查 .csproj 中是否設置了 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

2. 加載 DLL 失敗

  • 原因:DLL 依賴的其他庫缺失
  • 解決:使用 Fusion Log Viewerfuslogvw.exe)查看綁定失敗日志

3. 版本沖突

  • 原因:多個 DLL 依賴相同庫的不同版本


十、DllImport(平臺調用,P/Invoke)

在 C# 中,[DllImport("xxx.dll")]平臺調用(Platform Invocation Services,P/Invoke) 的核心特性,用于直接調用 非托管代碼(如 Windows API、C/C++ 編寫的 DLL)。這是 Java 中沒有的特性(Java 需要通過 JNI 調用本地代碼)。


1. 基本概念

[DllImport]System.Runtime.InteropServices 命名空間下的特性(Attribute),用于聲明某個方法的實現來自外部 DLL。它允許你在 C# 中直接調用 Windows API 或其他非托管函數。


2. 使用步驟

步驟 1:引入命名空間
using System.Runtime.InteropServices;
步驟 2:聲明外部方法

使用 [DllImport("dll名稱")] 特性修飾方法,指定 DLL 名稱和調用約定(Calling Convention)。

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
步驟 3:調用方法
MessageBox(IntPtr.Zero, "Hello from C#", "Greeting", 0);

3. 參數說明

參數說明
dllNameDLL 文件名(如 "user32.dll"
CharSet字符集(CharSet.AnsiCharSet.UnicodeCharSet.Auto
CallingConvention調用約定(默認為 CallingConvention.Winapi,也可指定 ThisCallStdCall 等)
EntryPoint可選,指定 DLL 中函數的入口點(當方法名與 DLL 函數名不同時使用)

4. 常見示例

示例 1:調用 user32.dllMessageBox
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);// 調用
MessageBox(IntPtr.Zero, "Hello from C#", "Greeting", 0);
示例 2:調用 kernel32.dllGetTickCount
[DllImport("kernel32.dll")]
public static extern uint GetTickCount();// 調用
uint tickCount = GetTickCount();
Console.WriteLine($"System uptime: {tickCount} ms");
示例 3:調用 gdi32.dllCreateDC
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);// 調用
IntPtr hdc = CreateDC("DISPLAY", null, null, IntPtr.Zero);

5. 結構體與指針傳參

當調用的函數需要結構體或指針參數時,需使用 refoutIntPtr,并可能需要使用 StructLayoutMarshalAs 來控制內存布局。

示例:調用 user32.dllGetWindowRect
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{public int Left;public int Top;public int Right;public int Bottom;
}[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);// 使用
RECT rect;
bool success = GetWindowRect(hWnd, out rect);
if (success)
{Console.WriteLine($"Window Rect: {rect.Left}, {rect.Top}, {rect.Right}, {rect.Bottom}");
}

6. 注意事項

安全性
  • 調用非托管代碼可能帶來 安全風險(如緩沖區溢出、非法訪問內存)。
  • 需要 Full Trust 權限 才能執行 P/Invoke 操作。
平臺依賴性
  • DllImport 僅適用于 Windows 平臺(除非使用跨平臺兼容的庫)。
  • 某些 DLL(如 user32.dllkernel32.dll)是 Windows 系統庫,其他平臺無法直接使用。
性能
  • P/Invoke 調用比純托管代碼慢(涉及 上下文切換參數封送)。
  • 頻繁調用時應考慮緩存結果或使用 unsafe 代碼優化。
參數封送(Marshaling)
  • 需要特別注意 數據類型映射(如 int 對應 Int32char* 對應 string)。
  • 使用 MarshalAs 明確指定封送方式(如 UnmanagedType.LPStrUnmanagedType.BStr)。

7. 示例:封裝一個 Windows API 工具類

using System;
using System.Runtime.InteropServices;public static class Win32Api
{[DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);[DllImport("kernel32.dll")]public static extern uint GetTickCount();[StructLayout(LayoutKind.Sequential)]public struct RECT{public int Left;public int Top;public int Right;public int Bottom;}[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
}// 使用
class Program
{static void Main(){// 調用 MessageBoxWin32Api.MessageBox(IntPtr.Zero, "Hello from C#", "Greeting", 0);// 獲取系統運行時間uint tickCount = Win32Api.GetTickCount();Console.WriteLine($"System uptime: {tickCount} ms");// 獲取窗口位置Win32Api.RECT rect;bool success = Win32Api.GetWindowRect(new IntPtr(0x123456), out rect);if (success){Console.WriteLine($"Window Rect: {rect.Left}, {rect.Top}, {rect.Right}, {rect.Bottom}");}}
}

通過掌握 DllImport 和 P/Invoke,你可以在 C# 中直接調用 Windows API 或其他非托管函數,實現更底層的系統級操作。結合良好的封裝和錯誤處理,可以顯著提升程序的功能性和靈活性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906020.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906020.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906020.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

EasyExcel詳解

文章目錄 一、easyExcel1.什么是easyExcel2.easyExcel示例demo3.easyExcel read的底層邏輯~~4.easyExcel write的底層邏輯~~ 二、FastExcel1.為什么更換為fastExcel2.fastExcel新功能 一、easyExcel 1.什么是easyExcel 內容摘自官方&#xff1a;Java解析、生成Excel比較有名的…

jvm安全點(三)openjdk17 c++源碼垃圾回收之安全點結束,喚醒線程

1. VMThread::inner_execute() - 觸發安全點?? cpp 復制 void VMThread::inner_execute(VM_Operation* op) { if (op->evaluate_at_safepoint()) { SafepointSynchronize::begin(); // 進入安全點&#xff0c;阻塞所有線程 // ...執行GC等操作... SafepointSynchronize::…

102. 二叉樹的層序遍歷遞歸法:深度優先搜索的巧妙應用

二叉樹的層序遍歷是一種經典的遍歷方式&#xff0c;它要求按層級逐層訪問二叉樹的節點。通常我們會使用隊列來實現層序遍歷&#xff0c;但遞歸法也是一種可行且有趣的思路。本文將深入探討遞歸法解決二叉樹層序遍歷的核心難點&#xff0c;并結合代碼和模擬過程進行詳細講解。 …

首個窗口級無人機配送VLN系統!中科院LogisticsVLN:基于MLLM實現精準投遞

導讀 隨著智能物流需求日益增長&#xff0c;特別是“最后一公里”配送場景的精細化&#xff0c;傳統地面機器人逐漸暴露出適應性差、精度不足等瓶頸。為此&#xff0c;本文提出了LogisticsVLN系統——一個基于多模態大語言模型的無人機視覺語言導航框架&#xff0c;專為窗戶級別…

WPF Datagrid 數據加載和性能

這篇文章并非討論 WPF Datagrid 的性能數據&#xff0c;而只是簡單介紹一下為了使其性能良好&#xff0c;你需要注意哪些方面。我不太想使用性能分析器來展示實際數據&#xff0c;而是盡可能地使用了 Stopwatch 類。這篇文章不會深入探討處理海量數據的技術&#xff0c;例如分頁…

matlab求矩陣的逆、行列式、秩、轉置

inv - 計算矩陣的逆 用途&#xff1a;計算一個可逆矩陣的逆矩陣。 D [1, 2; 3, 4]; % 定義一個2x2矩陣 D_inv inv(D); % 計算矩陣D的逆 disp(D_inv);det - 計算矩陣的行列式 用途&#xff1a;計算方陣的行列式。 E [1, 2; 3, 4]; determinant det(E); % 計算行列式 disp…

ridecore流水線解讀

文章目錄 流水線stage分屬前后端PCpipelineIFIDDPDP 與 SW 中間沒有latchSWCOM 源碼地址 流水線stage分屬前后端 IF -> ID -> DP -> SW -> EX -> COM分類階段說明前端IF指令獲取階段。PC 使用分支預測器&#xff0c;訪問指令存儲器。典型前端操作。前端ID解碼并…

【SpringBoot】關于MP使用中配置了數據庫表前綴的問題

problem 使用MP時&#xff0c;在application.yml配置文件中配置了MP匹配數據庫表中的表名時的前綴作了規定&#xff0c;如下&#xff1a; 那么當我運行時報錯了錯誤&#xff0c;報錯信息如下&#xff1a; 因為我數據庫表的書類表名是book&#xff0c;MP在匹配時使用了表名前…

印度Rummy游戲支付通道申請策略:技巧類游戲的合規與創新

本文為印度支付申請科普文&#xff0c;自去年開始&#xff0c;印度Rummy類游戲申請印度支付都需要擁有AIGF的會員及產品證書。 如需要rummy可以通過AIGF審核的源。碼&#xff0c;或咨詢AIGF的相關內容&#xff0c;可以聯。系老妙。 印度作為全球棋牌類游戲增長最快的市場之一&…

日志與策略模式

什么是設計模式 IT?業 ,為了讓 菜雞們不太拖?佬的后腿, 于是?佬們針對?些經典的常?的場景, 給定了?些對應的解決?案, 這個就是 設計模式 日志認識 計算機中的?志是記錄系統和軟件運?中發?事件的?件&#xff0c;主要作?是監控運?狀態、記錄異常信 息&#xff…

解鎖Ubuntu高效部署!自動安裝配置文件YAML全解析

我們之前介紹了兩種Ubuntu系統的安裝方式&#xff0c;分別對應桌面版&#xff08;準備搞OpenStack了&#xff0c;先裝一臺最新的Ubuntu 23.10&#xff09;和服務器版&#xff08;Ubuntu 22.04 LTS服務器版本安裝演示&#xff09;。但對于有些用戶&#xff0c;因為技術問題&…

關系代數和關系數據庫語言(SQL)

閱讀提示&#xff1a;本篇文章較長&#xff0c;建議從目錄上選取想看的內容。代碼上的話&#xff0c;我習慣用小寫&#xff0c;如果看不習慣建議跳過。有問題歡迎討論&#xff01;&#xff01;&#xff01; 一、基礎概念 1.1數據庫的概念 數據庫(Database)是按照數據結構來組…

EXO 可以將 Mac M4 和 Mac Air 連接起來,并通過 Ollama 運行 DeepSeek 模型

EXO 可以將 Mac M4 和 Mac Air 連接起來&#xff0c;并通過 Ollama 運行 DeepSeek 模型。以下是具體實現方法&#xff1a; 1. EXO 的分布式計算能力 EXO 是一個支持 分布式 AI 計算 的開源框架&#xff0c;能夠將多臺 Mac 設備&#xff08;如 M4 和 Mac Air&#xff09;組合成…

區塊鏈基本理解

文章目錄 前言一、什么是分布式賬本(DLT)二、什么是P2P網絡?二、共識算法三、密碼算法前言 區塊鏈是由一個一個數據塊組成的鏈條,按照時間順序將數據塊逐一鏈接,通過哈希指針鏈接,所有的數據塊共同維護一份分布式賬本(DLT),每個節點(可以理解為一個玩家,一臺計算機)都擁…

Node.js中的洋蔥模型

文章目錄 前言 前言 Node.js中的洋蔥模型是一種中間件執行機制&#xff0c;主要用于處理HTTP請求和響應的流程控制。該模型通過層層包裹的中間件結構&#xff0c;實現請求從外到內穿透、響應從內向外返回的順序執行。以下從核心概念、實現原理、框架差異及實際應用等方面解析&…

UI-TARS Desktop:用自然語言操控電腦,AI 重新定義人機交互

在人工智能技術飛速發展的今天,從文本生成到圖像識別,AI 的能力邊界不斷被打破。而字節跳動近期開源的 UI-TARS Desktop,則將這一技術推向了更復雜的交互場景——通過自然語言直接控制計算機界面,實現了圖形用戶界面(GUI)的智能化自動化。這款工具不僅降低了操作門檻,更…

一個可拖拉實現列表排序的WPF開源控件

從零學習構建一個完整的系統 推薦一個可通過拖拉&#xff0c;來實現列表元素的排序的WPF控件。 項目簡介 gong-wpf-dragdrop是一個開源的.NET項目&#xff0c;用于在WPF應用程序中實現拖放功能&#xff0c;可以讓開發人員快速、簡單的實現拖放的操作功能。 可以在同一控件內…

C語言中字符串函數的詳細講解

C語言提供了豐富的字符串處理函數&#xff0c;這些函數在<string.h>頭文件中聲明。以下是一些常用字符串函數的詳細講解&#xff1a; 字符串拷貝函數 strcpy 功能&#xff1a;將源字符串&#xff08;包括結尾的\0&#xff09;復制到目標字符串。原型&#xff1a;char *s…

可視化數據圖表怎么做?如何實現三維數據可視化?

目錄 一、三維數據可視化的要點 1. 明確數據可視化的目標 2. 篩選與整理數據 3. 選擇合適的圖表類型 4. 運用專業工具制作 5. 優化圖表的展示效果 二、數據可視化圖表怎么做&#xff1f; 1. 理解三維數據的特性 2. 數據處理與三維建模 3. 設置光照與材質效果 4. 添加…

在Linux服務器上部署Jupyter Notebook并實現ssh無密碼遠程訪問

Jupyter notebook版本7.4.2&#xff08;這個版本AI提示我Jupyter7&#xff08;底層是 jupyter_server 2.x&#xff09; 服務器開啟服務 安裝Jupyter notebook 7.4.2成功后&#xff0c;終端輸入 jupyter notebook --generate-config 這將在 ~/.jupyter/ 目錄下生成 jupyter_…