C#综合面试题(新手)-1

C#综合面试题(新手)

一、理论题

1、事务

​ 事务执行一系列的数据库语句内容,要么一起成功要么一起回滚(撤销成功的语句)

​ 四大特性:

​ ①**原子性:**一起执行,

​ ②**一致性:**数据库状态执行前后一致

​ ③**持久性:**一旦成功永久保存在数据库中

​ ④**隔离性:**并发事务彼此互不干扰

2、单例模式

​ 是一种创建型设计模式,旨在确保一个类只有一个实例,并提供全局访问点以获取该实例。这在需要限制类的实例数量,确保全局状态一致性,或避免重复资源消耗的情况下非常有用。(类在全局只有一个实例,节省资源)

特点:

  1. 单一实例: 单例模式确保一个类只能有一个实例。该实例由类自己管理,并在需要时进行创建。
  2. 全局访问点: 单例模式提供一个全局访问方法,允许其他代码在任何时候获取该唯一实例。

四种常用的创建方式:

  1. 经典的懒汉式(Lazy Initialization): 在首次使用时创建实例。需要注意的是,多线程环境下可能引发并发问题,需要进行同步处理。

    public class Singleton
    {
        private static Singleton instance;
    
        private Singleton() { }
        
        public static Singleton GetInstance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    
    }
    
  2. 线程安全的懒汉式(Thread-Safe Lazy Initialization): 在多线程环境下保证线程安全,但可能会带来性能开销。

    public class Singleton
    {
        private static Singleton instance;
        private static readonly object lockObject = new object();
    
        private Singleton() { }
        
        public static Singleton GetInstance()
        {
            lock (lockObject)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
            }
            return instance;
        }
    
    }
    
  3. 饿汉式(Eager Initialization): 在类加载时就创建实例,不存在多线程问题,但可能在程序启动时带来性能开销。

    public class Singleton
    {
        private static readonly Singleton instance = new Singleton();
    
        private Singleton() { }
        
        public static Singleton GetInstance()
        {
            return instance;
        }
    
    }
    
  4. 双重检查锁定(Double-Check Locking): 在多线程环境下保证线程安全,同时尽量减少锁的使用,提高性能。

public class Singleton
{
    private static volatile Singleton instance;
    private static readonly object lockObject = new object();

    private Singleton() { }

    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            lock (lockObject)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
3、委托和事件

①委托是一种类型,它可以用来引用一个或多个方法。它可以被认为是一个方法的指针,允许你将方法作为参数传递、存储在数据结构中或从方法中返回。委托可以用于实现回调机制、事件处理等。

delegate returnType DelegateName(parameters);

②事件是一种特殊类型的委托,它提供了一种更安全、更规范的方式来实现订阅和通知模式。事件允许对象注册为事件的监听者,并在事件发生时得到通知。

using System;
class Program
{
    public delegate void MyEventHandler(string message);

    public class MyEventPublisher
    {
        public event MyEventHandler MyEvent;

        public void RaiseEvent(string message)
        {
            MyEvent?.Invoke(message);
        }
    }

    public class MyEventListener
    {
        public void HandleEvent(string message)
        {
            Console.WriteLine("Event handled: " + message);
        }
    }

    static void Main()
    {
        MyEventPublisher publisher = new MyEventPublisher();
        MyEventListener listener = new MyEventListener();

        publisher.MyEvent += listener.HandleEvent;

        publisher.RaiseEvent("Hello from the event!");

        publisher.MyEvent -= listener.HandleEvent; // 取消事件订阅

        publisher.RaiseEvent("This won't be handled.");

        Console.ReadLine();
    }
}

二、C#基础题

1、static

​ 定义为静态字段,可以在不实例化类的情况下调用该字段,在类被初始化的时候会生成该字段,在整个应用程序生命周期下都存在

2、C#类的作用域

​ ①public:公共作用域,在该命名空间或程序集的外部也可见,其他命名空间或程序集可以通过引用和使用该类

​ ②Internal:内部作用域,将在同一命名空间内的其他文件中可见,其他命名空间或程序集不可以通过引用和使用该类

​ ③Protected:受保护的,类的派生类可以访问这些受保护成员,但其他非派生类的代码无法访问

​ ④private:私有的,只能在同一个类的内部访问,外部代码无法直接访问这些私有成员

3、线程实现

①使用ThreadPoolThreadPool.QueueUserWorkItem(WorkerMethod);实现多线程

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(WorkerMethod);

        // 主线程继续执行其他任务

        Thread.Sleep(2000); // 等待足够时间,使子线程有机会执行
    }

    static void WorkerMethod(object state)
    {
        Console.WriteLine("Worker thread from ThreadPool is starting...");
        Thread.Sleep(2000);
        Console.WriteLine("Worker thread from ThreadPool finished.");
    }
}

②实例化Task使用Task.Run(WorkerMethod)

using System;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        Task task = Task.Run(WorkerMethod);

        // 主线程继续执行其他任务
    
        task.Wait(); // 等待任务完成
    }
    
    static void WorkerMethod()
    {
        Console.WriteLine("Worker task is starting...");
        Task.Delay(2000).Wait();
        Console.WriteLine("Worker task finished.");
    }

}

③实例化Thread使用 thread.Start();

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(WorkerMethod);
        thread.Start();

        // 主线程继续执行其他任务

        thread.Join(); // 等待子线程完成
    }

    static void WorkerMethod()
    {
        Console.WriteLine("Worker thread is starting...");
        Thread.Sleep(2000);
        Console.WriteLine("Worker thread finished.");
    }
}

④异步方法

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        await WorkerMethodAsync();

        // 主线程继续执行其他任务
    }

    static async Task WorkerMethodAsync()
    {
        Console.WriteLine("Worker method is starting...");
        await Task.Delay(2000);
        Console.WriteLine("Worker method finished.");
    }
}
4、如何引用C++的dll文件
  1. 创建C++ DLL: 首先,你需要创建一个C++的动态链接库(DLL)。确保在创建DLL时,使用了与C#兼容的调用约定,通常使用__declspec(dllexport)来导出函数和类。

  2. 编译C++ DLL: 将C++代码编译为DLL文件。你可能需要使用特定的编译选项和链接库,以确保生成与C#兼容的DLL。

  3. 在C#中创建项目: 打开Visual Studio(或其他C#开发环境),创建一个新的C#项目,例如Class Library,Console Application等,用于在C#中调用C++的DLL。

  4. 添加DLL引用: 将生成的C++ DLL文件复制到C#项目的目录中,然后在C#项目中添加对该DLL文件的引用。在Solution Explorer中,右键点击项目,选择"Add" -> “Reference”,然后浏览并选择你的DLL文件。

  5. 使用DllImport特性: 在C#代码中,使用DllImport特性来引入C++ DLL中的函数。这允许你在C#代码中调用C++ DLL中的函数。示例如下:

    using System;
    using System.Runtime.InteropServices;
    
    public class Program
    {
        // 声明引用的DLL中的函数
        [DllImport("YourCppDll.dll")]
        public static extern int YourCppFunction(int parameter);
    
        public static void Main()
        {
            int result = YourCppFunction(42);
            Console.WriteLine("Result from C++ DLL: " + result);
        }
    }
    
  6. 编译并运行: 编译并运行C#项目。确保在运行时,C++的DLL文件与生成的C#可执行文件位于同一目录中,以便正确加载。

三、框架技术题

1、asp.net特点

(1)服务器端技术: ASP.NET 是一种服务器端技术,意味着 Web 应用程序的逻辑和处理发生在服务器上,然后将生成的 HTML 响应发送到客户端浏览器。

(2)面向对象编程: ASP.NET 支持面向对象编程的特性,可以使用 C#、VB.NET 等编程语言编写代码。

(3)Web Forms 和 MVC: ASP.NET 提供了两种主要的编程模型:Web Forms 和 MVC(Model-View-Controller)。Web Forms 强调了事件驱动的编程,而 MVC 更加注重分离应用的不同层,如数据处理、逻辑和视图。

(4)视图引擎: ASP.NET 支持多种视图引擎,允许开发者将数据和界面分离,以便更好地管理代码和界面。

(5)数据访问技术: ASP.NET 提供了多种数据访问技术,包括 ADO.NET、Entity Framework 等,用于连接数据库并执行数据操作。

(6)控件模型: ASP.NET 提供了丰富的服务器端控件,使开发者能够轻松地构建用户界面,从简单的按钮和文本框到复杂的数据表格。

(7)安全性: ASP.NET 提供了多种安全性功能,包括用户认证、授权、加密等,以保护应用程序的数据和功能。

(8)性能优化: ASP.NET 具有一些性能优化的特性,如输出缓存、数据缓存等,以提高应用程序的响应速度。

(9)跨平台: 最新版本的 ASP.NET(ASP.NET Core)支持跨平台开发,可以在 Windows、Linux 和 macOS 等操作系统上运行。

(10)集成开发环境: Microsoft Visual Studio 是一个强大的集成开发环境,用于开发 ASP.NET 应用程序,提供了代码编辑、调试、测试等功能。

2、MVC

MVC:M是model,V是View、c是controller

(1)Model(模型): 模型表示应用程序的数据和业务逻辑。它负责处理数据的获取、存储、验证和处理,以及实现业务规则。模型并不关心数据如何呈现给用户或从用户接收什么输入。

(2)View(视图): 视图是用户界面的呈现部分,负责展示数据给用户。它通常是用户可以看到和与之交互的部分。视图不包含业务逻辑,只负责将模型数据呈现出来。

(3)Controller(控制器): 控制器负责处理用户的请求,协调模型和视图之间的交互。它接收来自用户的输入,处理业务逻辑,更新模型,然后选择适当的视图来展示结果。

3、MVVM

(1)Model(模型): 模型表示应用程序的数据和业务逻辑,与其他架构模式中的模型类似。它负责管理数据的状态、获取、验证和处理。

(2)View(视图): 视图是用户界面的呈现部分,通常是 HTML、XML 或其他界面描述语言。在 MVVM 中,视图不应包含业务逻辑,只关注展示数据和用户交互。

(3)ViewModel(视图模型): 视图模型是连接模型和视图的桥梁,负责将模型的数据适配成视图所需的格式,以及处理视图中的用户交互。视图模型通常包含了展示逻辑、格式化数据和处理命令。

四、数据库题

1、group by和order by

①**group by**一般配合聚合函数(SUM、AVG、COUNT)一起使用,用于分组查询。

②**order by** 用于排序,ASC表示降序、DESC表示升序。

2、数据库函数

聚合函数: 用于对一组值执行计算,并返回一个单一的结果。

  • SUM:计算列中值的总和。
  • AVG:计算列中值的平均值。
  • COUNT:计算行数或特定列的非空值数量。
  • MAX:找到列中的最大值。
  • MIN:找到列中的最小值

②**字符串函数:**用于处理文本数据。

  • CONCAT:连接两个或多个字符串。
  • SUBSTRING:提取字符串的子串。
  • LENGTHLEN:获取字符串的长度。
  • UPPERUCASE:将字符串转换为大写。
  • LOWERLCASE:将字符串转换为小写。

③**日期和时间函数(Date and Time Functions): **用于处理日期和时间数据。

  • NOW:获取当前日期和时间。
  • DATE:提取日期部分。
  • TIME:提取时间部分。
  • YEARMONTHDAY:提取年、月、日。
  • DATEDIFF:计算日期之间的差值。

逻辑函数(Logical Functions): 用于执行逻辑操作。

  • IFCASE:条件语句,根据条件返回不同的值。
  • ANDORNOT:逻辑运算符。

数学函数(Mathematical Functions): 用于数值计算。

  • ABS:取绝对值。
  • ROUND:四舍五入。
  • CEILCEILING:向上取整。
  • FLOOR:向下取整。
  • POWERSQRT:计算幂次和平方根。

类型转换函数(Type Conversion Functions): 用于在不同数据类型之间进行转换。

  • CAST:将一个数据类型转换为另一个。
  • CONVERT:将一个数据类型转换为另一个,通常在不同数据库系统中有不同的语法。
3、存储过程

优点:

  • 性能优化: 存储过程可以在数据库服务器上进行预编译,提高查询性能。
  • 代码重用: 可以将常用的查询逻辑封装在存储过程中,从而减少代码重复。
  • 安全性: 存储过程可以限制用户对数据库的直接访问,通过存储过程来控制数据的访问。
  • 逻辑封装: 存储过程可以实现复杂的逻辑操作,比如事务处理、数据处理和转换等。
  • 简化客户端代码: 客户端代码只需要调用存储过程,而无需直接编写复杂的 SQL 查询。

示例:

-- 创建存储过程
CREATE PROCEDURE GetCustomerCountByCity
    @CityName NVARCHAR(50)
AS
BEGIN
    SELECT COUNT(*) AS CustomerCount
    FROM Customers
    WHERE City = @CityName;
END;
-- 调用存储过程并传递参数
DECLARE @Result INT;
EXEC GetCustomerCountByCity @CityName = 'New York', @Result OUTPUT;

-- 显示结果
PRINT 'Customer count in New York: ' + CAST(@Result AS NVARCHAR);
4、索引

​ 索引(Index)是一种数据结构,用于加速数据库表中数据的检索操作。通过创建索引,数据库可以更快地定位和访问表中的特定数据行,而不必进行全表扫描。索引通常基于表中的一个或多个列,提高了查询效率,但同时也会占用一定的存储空间并对写操作(插入、更新、删除)产生一定的影响。

(1)索引类型:

​ ①唯一索引(Unique Index): 唯一索引要求索引列中的每个值都是唯一的,用于确保数据的唯一性。例如,一个表中的主键通常会自动创建唯一索引。

​ ②聚集索引(Clustered Index): 聚集索引决定了数据在磁盘上的物理存储顺序。每个表只能有一个聚集索引,通常是主键索引。表的数据按照聚集索引的顺序存储,因此聚集索引对于范围查询效率较高。

​ ③非聚集索引(Non-clustered Index): 非聚集索引不会改变数据在磁盘上的物理存储顺序,而是创建一个单独的索引结构来加速数据的检索。一个表可以有多个非聚集索引。

(2)SQL SERVER索引实例:

①创建一个普通非聚集索引

CREATE NONCLUSTERED INDEX idx_FirstName ON Customers (FirstName);

②创建一个唯一非聚集索引:

CREATE UNIQUE NONCLUSTERED INDEX idx_CustomerID_unique ON Customers (CustomerID);

③创建一个聚集索引(一般用于主键):

CREATE CLUSTERED INDEX idx_CustomerID ON Customers (CustomerID);

(3)MYSQL索引实例:

①创建一个普通索引:

CREATE INDEX idx_username ON users (username);

②创建一个唯一索引:

CREATE UNIQUE INDEX idx_email_unique ON users (email);

③创建一个组合索引:

CREATE INDEX idx_username_email ON users (username, email);
5、数据类型

整型:

  • INT:常用、4bit;
  • SMALLINT:小范围整型、2bit、-32,768 到 32,767;
  • TINYINT:1bit、0-255;
  • BIGINT`:大范围整型、8bit。

浮点数:

  • float(n):单精度,n表示有效位数;
  • REAL:双精度浮点数。
  • DOUBLEDOUBLE PRECISION:双精度浮点数。

定点数:

DECIMAL(p, s)NUMERIC(p, s):精确的定点数,其中 p 表示总位数,s 表示小数位数。

字符串类型

  • CHAR(n):固定长度的字符,其中 n 表示字符数;
  • VARCHAR(n):可变长度的字符,其中 n 表示最大字符数;
  • TEXT:存储大文本块的类型;
  • NCHAR(n):用于存储 Unicode 字符的固定长度字符串;
  • NVARCHAR(n):用于存储 Unicode 字符的可变长度字符串;
  • NTEXT:存储大 Unicode 文本块的类型。
  • ENUM:用于存储从预定义选项中选择的值。
  • SET:用于存储多个从预定义选项中选择的值。

日期与时间型(Date and Time Types):

  • DATE:仅存储日期。
  • TIME:仅存储时间。
  • DATETIMEDATETIME2:同时存储日期和时间。
  • SMALLDATETIME:较小范围的日期和时间。
  • TIMESTAMP:用于记录日期和时间,通常用于记录数据修改时间。
  • YEAR:用于存储年份。

布尔型(Boolean Type):

  • SQL Server 本身没有内置的布尔数据类型,通常使用 BIT 数据类型,其中 0 表示假,1 表示真。
  • MySQL 中没有内置的布尔数据类型,通常使用 TINYINTENUM 来模拟布尔值,其中 0 表示假,1 表示真。

二进制型(Binary Types):

  • BINARY(n):固定长度的二进制数据。
  • VARBINARY(n):可变长度的二进制数据。
  • IMAGE:用于存储大二进制块的类型。
  • BLOB:用于存储大二进制块的类型。

JSON 和 XML 型:

  • JSON:用于存储 JSON 格式的数据。
  • XML:用于存储 XML 格式的数据。

自定义类型(User-Defined Types):

  • SQL Server 支持创建自定义数据类型。
  • MySQL 支持创建自定义数据类型。

空间数据类型(Spatial Data Types):

  • MySQL 支持存储和处理地理空间数据,如点、线、多边形等。

五、数据结构题

1、冒泡排序
public static void Main(string[] args){
    int[] numbers={1,2,3,4,5,6,7,8,9}
    for(int i=0;i<numbers.length;i++){
        for(int j=i;j<i;j++){
            if(numbers[i]<numbers[j]){
				int num=numbers[i];
                numbers[i]=numbers[j];
                numbers[j]=num;
            }
		}
	}
    foreach(var num in numbers){    
    	Console.WriteLine(num);
    }
}
2、递归排序
    static int Factorial(int n)
    {
        // 基本情况:阶乘的定义是0的阶乘为1,1的阶乘为1
        if (n == 0 || n == 1)
        {
            return 1;
        }
        else
        {
            // 递归调用:n的阶乘等于 n * (n - 1) 的阶乘
            return n * Factorial(n - 1);
        }
    }

    static void Main()
    {
        int number = 5;
        int result = Factorial(number);
        Console.WriteLine($"Factorial of {number} is {result}");
    }

六、前端技术题

1、HTTP协议工作原理
  • 客户端-服务器模型: HTTP 是基于客户端-服务器模型的,客户端发送请求,服务器响应请求并返回数据。
  • 请求-响应模型: 客户端发送一个 HTTP 请求给服务器,服务器处理请求并返回一个 HTTP 响应,其中包含请求的资源或错误信息。
  • 无连接: 每个请求和响应都是独立的,服务器不会保存客户端的状态信息,这种特性称为无状态性。
  • 无状态: HTTP 协议本身是无状态的,但通过使用 Cookie、Session 和其他机制,可以实现有状态的会话。
  • 支持多媒体类型: HTTP 支持传输各种类型的数据,包括文本、图像、音频、视频等。
  • URL(Uniform Resource Locator): URL 用于唯一标识 Web 上的资源。HTTP 请求使用 URL 来指定要请求的资源的位置。
  • 请求方法: HTTP 定义了多种请求方法,如 GET、POST、PUT、DELETE 等,用于指定请求的操作类型。
  • 状态码: HTTP 响应中包含状态码,用于表示请求的处理结果,例如 200 表示成功,404 表示未找到等。
  • 报文: HTTP 请求和响应以报文的形式传输,包含请求头、请求体、响应头和响应体等部分。
  • 持久连接: 为了减少连接的开销,HTTP 可以使用持久连接(Keep-Alive)来在一个连接上传输多个请求和响应。
  • 安全性: HTTPS(HTTP Secure)是在 HTTP 上添加了安全性的协议,使用 SSL/TLS 加密传输数据,确保通信的机密性和完整性
2、JSON格式类型
  • 对象(Object): 使用大括号 {} 包围,包含一系列键值对,每个键值对之间用逗号 , 分隔。键是字符串,值可以是字符串、数字、布尔值、对象、数组等。
  • 数组(Array): 使用方括号 [] 包围,包含一系列值,每个值之间用逗号 , 分隔。值可以是字符串、数字、布尔值、对象、数组等。
  • 字符串(String): 使用双引号 " 包围,表示文本数据。
  • 数字(Number): 表示整数或浮点数。
  • 布尔值(Boolean): 表示 truefalse
  • 空值(null): 表示空值。

七、中间件技术题

1、EF和ado.net

①ado.net是原生的数据库交互技术,常用类:SqlConnectionSqlCommandSqlDataReader,实例:

using System;
using System.Data.SqlClient;

class Program
{
    static void Main(string[] args)
    {
        string connectionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password";

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();

            string sql = "SELECT FirstName, LastName FROM Customers";
            SqlCommand command = new SqlCommand(sql, connection);

            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    string firstName = reader["FirstName"].ToString();
                    string lastName = reader["LastName"].ToString();
                    Console.WriteLine($"Name: {firstName} {lastName}");
                }
            }
        }
    }
}

②EF是一个对象关系映射(ORM)框架,用于在 .NET 应用程序中实现对象和数据库之间的映射。它允许开发者使用面向对象的方式来操作数据库,而无需直接编写 SQL 查询语句。EF 提供了一个抽象层,使开发者可以通过 C# 或 VB.NET 代码来查询、插入、更新和删除数据,从而简化了数据访问层的开发。步骤:

  1. 安装Entity Framework: 在项目中安装Entity Framework的NuGet包。您可以使用Visual Studio的包管理器控制台来执行此操作,或者在项目文件中手动添加相关的NuGet依赖。
  2. 创建数据模型: 使用Entity Framework,您需要创建数据模型,通常是用于表示数据库中表的类。这些类通常称为"实体"(Entities)。您可以手动创建这些类,也可以使用Entity Framework的工具自动生成这些类。
  3. 配置数据库连接: 在应用程序的配置文件中,配置数据库连接字符串,以便Entity Framework知道如何连接到数据库。
  4. 创建DbContext DbContext是Entity Framework中的核心类,它表示数据库上下文。您需要创建一个继承自DbContext的类,并将实体类添加到DbContext中。
  5. 进行CRUD操作: 使用DbContext可以执行各种数据库操作,如创建(Create)、读取(Read)、更新(Update)和删除(Delete)数据。您可以通过对实体对象进行操作,然后调用DbContext的相应方法来实现这些操作。
2、linq表达式关键词
  • from 用于指定数据源,可以是集合、数组、数据库表等。
  • where 用于筛选满足指定条件的数据项。
  • select 用于选择从数据源中提取的数据项,可以进行数据变换和投影。
  • orderby 用于对结果进行排序。
  • group 用于将结果分组。
  • join 用于在多个数据源之间执行联接操作。
  • let 用于定义一个中间变量,可以在查询的其他部分使用。
  • in 在查询表达式中用于指定要查询的数据源。
  • on 用于在联接操作中指定联接条件。
  • equals 用于在联接操作中指定等值比较条件。
  • by 在group子句中用于指定分组键。
  • ascendingorderby子句中用于指定升序排序。
  • descendingorderby子句中用于指定降序排序。
  • into 用于将一个查询的结果引入一个新的范围。
  • join into 在联接操作中用于将联接的结果引入一个新的范围。

linq示例:

using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
    public static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        var evenNumbers = from number in numbers
                          where number % 2 == 0
                          select number;
    
        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }

}
3、Lambda 表达式
(parameters) => expression_or_statement
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御用·小厮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值