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

C# 入门学习教程(三)

文章目录

  • 一、字段、属性、索引器、常量
    • 1.字段
    • 2.属性
      • 2.1 什么是属性
      • 2.2 属性的声明
      • 2.3 属性与字段的关系
    • 3 索引器
    • 4. 常量
  • 二、传值 输出 引用 数组 具名 可选参数,扩展方法
    • 2.1 传值参数
      • 2.1.1 值类型 传参
      • 2.1.2 引用类型 传参
    • 2.2 引用参数
      • 2.2.1 引用参数-值类型 传参
      • 2.2.2 引用参数 - 引用类型 传参
    • 2.3 输出参数
      • 2.3.1 输出参数-值类型
      • 2.3.2 输出参数-引用类型
    • 2.4 数组参数 (params)
    • 2.5 具名参数
    • 2.6 可选参数
    • 2.7 扩展方法(this参数)
      • 扩展方法
      • LINQ 方法
    • 2.8 各种参数的使用场景总结

一、字段、属性、索引器、常量

1.字段

  • 什么是字段

    • 字段(field)是一种表示与对象或类型(类与结构体)关联的变量"字段是类型的成员,旧称“成员变量
    • 与对象关联的字段亦称“实例字段”
    • 与类型关联的字段称为“静态字段””,由static修饰
  • 字段的声明

    • 参见C#语言定义文档
    • 尽管字段声明带有分号但它不是语句
    • 字段的名字一定是名词
  • 字段的初始值

    • 无显式初始化时,字段获得其类型的默认值,所以字段“永远都不会未被初始化”
    • 实例字段初始化的时机–对象创建时
    • 静态字段初始化的时机–类型被加载(load )时
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;namespace ConsoleApplication1
    {class Program{static void Main(string[] args){//实例化一个学生Student student = new Student();student.Age = 10;student.Score = 100;Console.WriteLine(student.Score);//实例化100个学生,求平均年龄和平均分List<Student> studentList = new List<Student>();for (int i = 0; i < 100; i++) { Student stu = new Student();stu.Age = 25;stu.Score = i+10;studentList.Add(stu);}int totalAge = 0;int totalScore = 0;foreach (var stu in studentList){totalAge += stu.Age;totalScore += stu.Score;}Student.AverageAge = totalAge/Student.Amount;Student.AverageScore = totalScore/Student.Amount;Student.ReportAverageScore();Student.ReportAverageAge();}}class Student{public int Age;public int Score;// 字段初始化器public int AgeInit = 30;//平均年龄public static int AverageAge;//平均分public static int AverageScore;//静态字段的初始化器public static int Amount = 0;public Student(){Student.Amount++;}public static void ReportAverageAge(){Console.WriteLine(Student.AverageAge);}public static void ReportAverageScore(){Console.WriteLine(Student.AverageScore);}public void ReportAmount(int score){Console.WriteLine(Student.Amount);}}
    }
  • 只读字段

    • 实例只读字段
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;namespace ConsoleApplication1
    {class Program{static void Main(string[] args){StudentOne studentOne = new StudentOne(35);Console.WriteLine( studentOne.ID);//错误:给只读字段赋值将会报错studentOne.ID = 100;}}class StudentOne{//学生id设置为只读字段public readonly int ID;public string Name;public int Age;//只读字段实例化构造器public StudentOne(int Id){//只有在实例化的时候才能赋值this.ID = Id;}}
    }
    • 静态只读字段
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;namespace ConsoleApplication1
    {class Program{static void Main(string[] args){Console.WriteLine(Brush.DefaultColor.Red);Console.WriteLine(Brush.DefaultColor.Green);}}struct Color{public int Red;public int Green;public int Blue;}class Brush{//声明一个静态只读字段// public static readonly Color DefaultColor = new Color() { Red = 0, Green = 0, Blue = 0 };//静态只读字段构造器public static readonly Color DefaultColor;static Brush(){Brush.DefaultColor = new Color() { Red = 0, Green = 0, Blue = 0 };}}
    }

2.属性

2.1 什么是属性

  • 属性(property)是一种用于访问对象或类型的特征的成员,特征反映了状态
  • 属性是字段的自然扩展,
    • 从命名上看,field更偏向于实例对象在内存中的布局,property更偏向于反映现实世界对象的特征
    • 对外:暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的
    • 对内:保护字段不被非法值“污染”属性由Get/Set方法对进化而来
  • 又一个“语法糖”–属性背后的秘密
	using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace PropertyExample{class PropertyExample{static void Main(string[] args){//字段的定义使用try{Student student = new Student();student.setAge(30);Student student2 = new Student();student2.setAge(50);Student student1 = new Student();student1.setAge(80);int avgAge = (student.getAge() + student2.getAge() + student1.getAge()) / 3;Console.WriteLine(avgAge);}catch (Exception ex){Console.WriteLine(ex.Message);}//属性的使用try{Student student = new Student();student.Age = 25;Student student2 = new Student();student2.Age = 40;Student student1 = new Student();student1.Age = 50;int avgAge = (student.Age + student2.Age + student1.Age) / 3;Console.WriteLine(avgAge);}catch (Exception ex){Console.WriteLine(ex.Message);}}}class Student{private int age;//原始的字段获取和赋值public int getAge(){return this.age;}public void setAge(int age){if (age > 100 || age < 0){throw new Exception("Age has Error");}else{this.age = age;}}//演变成属性public int Age{get{return this.age;}set{if (value >= 0 && value < 120){this.age = value;}else{throw new Exception("Age is Error");}}}}}

反编译分析:

在这里插入图片描述

输入: ildasm , 打开反编译器

在这里插入图片描述

打开文件,找到对应的dll文件打开,如下:

在这里插入图片描述

2.2 属性的声明

  • 完整声明–后台(back)成员变量与访问器(注意使用code snippet和refactor工具)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PropertyExample
{class PropertyExample{static void Main(string[] args){//实例属性try{Student student = new Student();student.Age = 25;Console.WriteLine(student.Age );}catch (Exception ex){Console.WriteLine(ex.Message);}//静态属性try{Student.Amount = 80;Console.WriteLine(Student.Amount);}catch (Exception ex){Console.WriteLine(ex.Message);}}}class Student{//实例属性public int Age{get{return this.age;}set{if (value >= 0 && value < 120){this.age = value;}else{throw new Exception("Age is Error");}}}//静态属性private static int amount;public static int Amount{get { return amount; }set{if (value > 0){amount = value;}else{throw new Exception("amount is error");}}}}
}
  • 简略声明–只有访问器(查看IL代码 )
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PropertyExample
{class PropertyExample{static void Main(string[] args){Student student3 = new Student();student3.ageInit = 50;Console.WriteLine(student3.ageInit);}}class Student{public int ageInit { get; set; }}
}
  • 动态计算值的属性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PropertyExample
{class PropertyExample{static void Main(string[] args){Student student5 = new Student();student5.Age = 50;Console.WriteLine(  student5.CanWork);}}class Student{//年龄属性public int Age{get{return this.age;}set{if (value >= 0 && value < 120){this.age = value;}else{throw new Exception("Age is Error");}}}//能否工作属性public bool CanWork{get{if (this.age > 18){return true;}else{return false;}}}}
}
  • 注意实例属性和静态属性

  • 属性的名字一定是名词

  • 只读属性–只有getter没有setter

    • 尽管语法上正确,几乎没有人使用“只写属性”,因为属性的主要目的是通过向外暴露数据而表示对象/类型的状态
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PropertyExample
{class PropertyExample{static void Main(string[] args){//ageInit 是只读属性,不能赋值Student student3 = new Student();Console.WriteLine(student3.ageInit);//score 属性不允许外部赋值,只能内部赋值Student student4 = new Student();student4.setScore();Console.WriteLine(student4.score);}}class Student{//只读属性,没有set方法public int ageInit { get; }//有set方法,但是是私有的,只能内部进行赋值public int score {  get;private set;}//	内部赋值public void setScore(){this.score = 100;}}
}

2.3 属性与字段的关系

  • 一般情况下,它们都用于表示实体(对象或类型)的状态
  • 属性大多数情况下是字段的包装器(wrapper)
  • 建议:永远使用属性(而不是字段)来暴露数据,即字段永远都是private或protected的

3 索引器

  • 什么是索引器
    • 索引器 (indexer) 是这样一种成员:它使对象能够用与数组相同的方式(即使用下标)进行索引
  • 索引器的声明
    • 参见C#语言定义文档
    • 注意:没有静态索引器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PropertyExample
{class PropertyExample{static void Main(string[] args){Studentcj student6 = new Studentcj();var aa = student6["xiaoming"];Console.WriteLine(aa==null);student6["xiaoming"] = 60;Console.WriteLine(student6["xiaoming"]);}}class Studentcj{//定义一个集合private Dictionary<string,int> scoreDictionary = new Dictionary<string,int>();public int? this[string subject]{get {// 检测是否存在,存在则返回具体值,不存在返回nullif (this.scoreDictionary.ContainsKey(subject)){return this.scoreDictionary[subject];}else{return null;}}set{// 设置的值为null,直接异常if (value.HasValue == false){throw new Exception("值不能为空");}//检测是否有值,有值则覆盖,没有则新增if (this.scoreDictionary.ContainsKey(subject)){this.scoreDictionary[subject] = value.Value;}else{this.scoreDictionary.Add(subject, value.Value);}}}}
}

4. 常量

  • 什么是常量

    • 常量(constant)是表示常量值(即,可以在编译时计算的值)的类成员
      在这里插入图片描述

    • 常量隶属于类型而不是对象,即没有“实例常量

      • “实例常量”的角色由只读实例字段来担当
    • 注意区分成员常量与局部常量

    namespace consetExample
    {class Program{static void Main(string[] args){// 局部常量const int Age = 35; Console.WriteLine(baidu.url);}}class baidu{//成员常量public const string url = "www.baidu.com";}
    }
  • 常量的声明

  • 各种“只读”的应用场景

    • 为了提高程序可读性和执行效率–常量
    • 为了防止对象的值被改变一-只读字段
    • 向外暴露不允许修改的数据–只读属性(静态或非静态),功能与常量有一些重叠
    • 当希望成为常量的值其类型不能被常量声明接受时(类/自定义结构体)–静态只读字段
      • 常量的类型只能是普通的值类型,不能是类或者自定义结构体

二、传值 输出 引用 数组 具名 可选参数,扩展方法

2.1 传值参数

2.1.1 值类型 传参

值类型传参 是指将值类型(如 int、struct、enum 等)的变量作为参数传递给方法。值类型传参的核心特点是 传递的是变量值的副本,因此方法内部对参数的修改不会影响原始变量。

  • 副本创建:当值类型变量作为参数传递时,系统会创建一个与原始值相同的副本。
  • 独立作用域:方法内部操作的是副本,原始变量不受影响。
  • 内存分配:副本在方法调用栈上分配独立内存。

值类型传参 流程如图:
在这里插入图片描述

  • 代码实例:
namespace ParametersExample
{class Program{static void Main(string[] args){int num = 100;Student student = new Student();student.AddOne(num);Console.WriteLine(num);}}class Student{public void AddOne(int num){num ++;Console.WriteLine(num);}}
}
  • 定义一个值类型的变量 num

  • 传值进方法后,方法内的变量 num 会变更

  • 方法外的变量 num 不会随着值参数的变化而变化

  • 调试结果:

在这里插入图片描述

2.1.2 引用类型 传参


引用类型传参 是指将引用类型(如 class、array、string、interface 等)的变量作为参数传递给方法。引用类型传参的核心特点是 传递的是对象引用的副本,而非对象本身

  • 传递时创建引用的副本(内存地址的复制),而非对象的副本。
  • 原始引用和副本引用指向同一个对象实例。
  1. 引用类型传参,创建新对象

    重设引用副本:仅影响副本,不影响原始引用。

在这里插入图片描述

namespace ParametersExample
{class Program{static void Main(string[] args){StudentOne studentOne = new StudentOne();studentOne.Id = 100;studentOne.Name = "张三";SomeMethod(studentOne);Console.WriteLine(studentOne.Id);//打印对象的 HashCode,以及属性Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);}static void SomeMethod(StudentOne student){student = new StudentOne();student.Id = 1;studentOne.Name = "张三";Console.WriteLine(studentOne.Id);//打印对象的 HashCode,以及属性Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);}}class StudentOne{public int Id { get; set; }public string Name { get; set; }}
}
  • 定义StudentOne 类,属性ID,Name
  • 初始化一个studentOne 对象,属性赋值,将对象传进SomeMethod 方法
  • SomeMethod 方法内会初始化一个新对象 student ,并赋值
  • 打印方法内外变量的值,虽然名称都是张三,但是实例却不是同一个

在这里插入图片描述

  1. 引用类型传参,操作对象,不创建新对象

    修改对象属性 / 状态:影响原始对象。

在这里插入图片描述

namespace ParametersExample
{class Program{static void Main(string[] args){StudentOne studentOne = new StudentOne();studentOne.Id = 100;studentOne.Name = "张三";SomeMethodOne(studentOne);Console.WriteLine(studentOne.Id);Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);}static void SomeMethodOne(StudentOne studentOne){studentOne.Id = 2;  // 方法的副作用studentOne.Name = "李四";Console.WriteLine(studentOne.Id);Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);}}class StudentOne{public int Id { get; set; }public string Name { get; set; }}
}

在这里插入图片描述

  • SomeMethodOne 方法内操作对象,重新赋值,方法内外的变量会同时变化.
  • 方法内进行更新属性的操作,称为方法的副作用,较少见,需要避免使用

2.2 引用参数

引用参数(Reference Parameters) 允许方法直接操作调用者提供的变量,而非创建参数的副本。通过 ref 关键字声明引用参数,使方法能够修改原始变量的值或重设其引用。

这是一种强大的参数传递机制,适用于需要双向数据交换的场景。

  • 在方法定义和调用时均需显式使用 ref 关键字。
  • 传递变量的内存地址(而非值或引用的副本)。
  • 方法内部对参数的任何修改直接反映到原始变量
  • 实参必须是已初始化的变量,不能是常量或表达式

2.2.1 引用参数-值类型 传参

引用参数(ref)与值类型传参 的组合允许方法直接操作调用者提供的值类型变量,而非创建其副本。

这种方式结合了 ref 关键字的双向修改能力和值类型的内存特性,常用于需要高效修改值类型变量的场景。


在这里插入图片描述

namespace ParametersExample
{class Program{static void Main(string[] args){int x = 100;addNum(ref x);Console.WriteLine(x);}public static void addNum(ref int x){x++;Console.WriteLine(x);}}
}

在这里插入图片描述

2.2.2 引用参数 - 引用类型 传参

引用参数(ref)与引用类型传参 的组合允许方法直接操作调用者提供的引用类型变量,包括修改对象状态或重设引用本身。

这种方式结合了 ref 关键字的双向修改能力和引用类型的内存特性,常用于需要更灵活控制对象引用的场景。

  1. 引用参数 - 引用类型 , 创建新对象在这里插入图片描述
namespace ParametersExample
{class Program{static void Main(string[] args){StudentOne studentOne = new StudentOne() { Id=1,Name="李四"};Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);Console.WriteLine("=============================");IWantSideEffect(ref studentOne);Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);}static void IWantSideEffect(ref StudentOne stu){stu = new StudentOne(){Id = 1, Name="张三"};Console.WriteLine("{0},{1}",stu.GetHashCode(),stu.Name);}}class StudentOne{public int Id { get; set; }public string Name { get; set; }}
}

在这里插入图片描述

  1. 引用参数 - 引用类型 , 不创建新对象,改变对象值

在这里插入图片描述

namespace ParametersExample
{class Program{static void Main(string[] args){StudentOne studentOne = new StudentOne() { Name="李四"};Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);Console.WriteLine("=============================");IWantSideEffect(ref studentOne);Console.WriteLine("{0},{1}", studentOne.GetHashCode(), studentOne.Name);}static void IWantSideEffect(ref StudentOne stu){stu.Name = "李四";Console.WriteLine("{0},{1}",stu.GetHashCode(),stu.Name);}}class StudentOne{public string Name { get; set; }}
}

在这里插入图片描述

2.3 输出参数

输出参数(Output Parameters) 允许方法通过参数返回多个值,而不仅仅依赖于返回值。通过 out 关键字声明输出参数,使方法能够将计算结果赋值给调用者提供的变量。这是一种简洁且类型安全的多返回值解决方案。

  • 在方法定义和调用时均需显式使用 out 关键字。
  • 传递变量的引用(类似 ref),但无需初始化
  • 方法必须在返回前为所有 out 参数赋值
  • out 参数在方法调用后才被视为已初始化。

2.3.1 输出参数-值类型

在这里插入图片描述

namespace ParametersExample
{class Program{static void Main(string[] args){double y = 0;string x = "100";DoubleParser doubleParser = new DoubleParser();bool b = doubleParser.tryParser(x, out y);if (b){Console.WriteLine(y+1);}else{Console.WriteLine(y);}}}class DoubleParser{public bool tryParser(string x, out double y){try{y = double.Parse(x);return true;}catch (Exception e){y = 0;return false;}}}
}

在这里插入图片描述

2.3.2 输出参数-引用类型

在这里插入图片描述

namespace ParametersExample
{class Program{static void Main(string[] args){StudentFactory studentFactory = new StudentFactory();StudentOne studentOne = new StudentOne();bool res = studentFactory.CreateStu("张三", 35, out studentOne);if (res){Console.WriteLine("{0},{1}", studentOne.Age, studentOne.Name);}}}class StudentOne{public string Name { get; set; }public int Age { get; set; }}class StudentFactory(){public bool CreateStu(string Name, int Age, out StudentOne student){student = null;if (string.IsNullOrEmpty(Name)){return false;}if (Age > 100){return false;}student = new StudentOne();student.Name = Name;student.Age = Age;return true;}}
}

在这里插入图片描述

2.4 数组参数 (params)

使用 params 关键字允许方法接收任意数量的参数(包括零个),并在方法内部将其视为数组处理。

  • params 类型[] 参数名
  • 必须是形参列表中最后一个,有params 修饰
  • 可传递数组,或直接传递多个参数值
namespace ParametersExample
{class Program{static void Main(string[] args){int[] ints = new int[] { 1, 2, 3 };//传递数组int num = countSum(ints);//方法的数组参数用params修饰后,传值变简单int num2 = countSum(1, 2, 3);Console.WriteLine("{0},{1}", num, num2);}// 使用 params 关键字的方法static int countSum(params int[] array){int sum = 0;foreach (int i in array){sum += i;}return sum;}}
}
  • string.Split 方法演示:
namespace ParametersExample
{class Program{static void Main(string[] args){string aa = "张三, 李四; 王五# 赵六";string[] sss = aa.Split(',', ';', '#');foreach (var item in sss){Console.WriteLine(item);}}}
}

在这里插入图片描述

2.5 具名参数

具名参数(Named Arguments) 允许你在调用方法时通过参数名称而不是位置来指定参数值。这使得代码更具可读性,特别是在处理具有多个参数的方法时,还可以跳过可选参数或按任意顺序传递参数。

  • 通过 参数名: 值 的语法指定参数值。
  • 可以不按方法定义的参数顺序传递参数
  • 可以选择性地为可选参数赋值,未指定的参数使用默认值。
  • 参数位置不再受约束
namespace ParametersExample
{class Program{static void Main(string[] args){// 使用具名参数(顺序可任意)printInfo(age: 35,name:"张三");}static void printInfo(string name,int age){Console.WriteLine("{0},{1}",name,age);}}
}

2.6 可选参数

可选参数是方法定义里能够设定默认值的参数。调用方法时,这些参数可传值也能不传。

  • 定义方法时,通过赋值运算符(=)给参数赋予默认值
  • 可选参数必须放在必选参数的后面
  • 调用方法时,可以不传入可选参数的值,此时会使用默认值;也可以按顺序传值或者通过命名参数传值。
namespace ParamsExample
{internal class Program{static void Main(string[] args){showParams();}static void showParams(string Name="张三",int Age=35){Console.WriteLine("{0},{1}",Name,Age);}}
}

在这里插入图片描述

2.7 扩展方法(this参数)

扩展方法

扩展方法(Extension Methods) 允许你向现有类型 “添加” 方法,而无需创建新的派生类型、修改原始类型或使用复杂的装饰器模式。扩展方法使用 this 关键字修饰第一个参数,使其看起来像被扩展类型的实例方法。这是一种强大的语法糖,常用于增强框架类型或第三方库的功能。

  • 语法
    • 必须定义在静态类中。
    • 第一个参数必须使用 this 关键字修饰。
    • 通常为公共静态方法。
  • 调用方式
    • 像实例方法一样调用(无需显式传入第一个参数)。
    • 需要引入扩展方法所在的命名空间。
  • 优先级
    • 实例方法优先于扩展方法。
    • 多个扩展方法冲突时需显式指定类型调用。
namespace ParamsExample
{internal class Program{static void Main(string[] args){string str = "";Console.WriteLine(str.IsNullOrWhitespace());}}// 静态类:包含扩展方法public static class StringExtensions{//扩展方法:判断字符串是否为空或空白public static bool IsNullOrWhitespace(this string str){if (string.IsNullOrEmpty(str)){return true;}if (str.Trim().Length == 0){return true;}return false;}}
}

LINQ 方法

LINQ(Language Integrated Query) 提供了一组标准查询方法,用于对各种数据源(如集合、数组、数据库等)进行高效的查询、筛选、投影和聚合操作。

这些方法既可以通过 ** 方法语法(Method Syntax)直接调用,也可以通过查询语法(Query Syntax)** 以类似 SQL 的形式表达。

namespace ParamsExample
{internal class Program{static void Main(string[] args){List<int> list = new List<int>() { 11, 19, 20, 30,15, 19 };//访问静态方法bool x = AllGreaterThanTen(list);Console.WriteLine(x);//筛选大于10的bool y = list.All(i => i > 10);Console.WriteLine(y);}public static bool AllGreaterThanTen(List<int> ints){foreach (var item in ints){if (item > 10){continue;}else{return false;}}return true;}}
}

在这里插入图片描述

2.8 各种参数的使用场景总结

  • 传值参数:参数的默认传递方式
  • 输出参数:用于除返回值外还需要输出的场景
  • 引用参数:用于需要修改实际参数值的场景
  • 数组参数:用于简化方法的调用
  • 具名参数:提高可读性
  • 可选参数:参数拥有默认值
  • 扩展方法(this参数):为目标数据类型“追加”方法
http://www.dtcms.com/a/278883.html

相关文章:

  • Python基础语法1:注释与输入输出、变量与简单数据类型、运算符与表达式、条件判断与循环
  • 云原生技术与应用-Containerd容器技术详解
  • MySQL数据库的基础操作
  • AI驱动的软件工程(下):AI辅助的质检与交付
  • nvidia-smi命令参数解释
  • 机器学习(ML)、深度学习(DL)、强化学习(RL):人工智能的三驾马车
  • 外星人电脑Alienware Aurora R11原装出厂OEM预装Windows10系统
  • 自动驾驶数据仓库:时间片合并算法。
  • 【React Native】ScrollView 和 FlatList 组件
  • 基于ASP.NET+SQL Server实现(Web)排球赛事网站
  • Java文件操作
  • PTKQuery
  • 大规模测试自动化测试指南
  • day9 串口通信
  • 如何单独安装设置包域名
  • Kafka Broker源码解析(上篇):存储引擎与网络层设计
  • Java HTTP应用开发:从基础到实战
  • C语言-流程控制
  • 使⽤Pytorch构建⼀个神经⽹络
  • Linux 消息队列接收与处理线程实现
  • 【HTTP版本演变】
  • 考完数通,能转云计算/安全方向吗?转型路径与拓展路线分析
  • Elasticsearch9.x核心架构概述
  • Redis7持久化
  • 【postgresql数据库实现表的树结构查询】
  • 项目进度中间节点缺失,如何精细化分解任务
  • MIPI DSI(三) MIPI DSI 物理层和 D-PHY
  • 《大数据技术原理与应用》实验报告三 熟悉HBase常用操作
  • 现代数据平台能力地图:如何构建未来数据平台的核心能力体系
  • 为什么ER-GNSS/MINS-01能重新定义高精度导航?