【Java】Java基础知识面试题大全(2024最新版,先收藏慢慢看)

本文详尽解读了Java基础知识,涵盖了从基本语法、数据类型,到面向对象编程的核心概念,再到异常处理、集合框架、多线程、JVM与内存管理、IO/NIO、网络编程、序列化与反序列化、反射和注解等内容。希望通过本文,你不仅能够更好地理解和掌握Java基础知识,还能在面试中游刃有余,顺利拿下心仪的职位。不论是初学还是复习,这篇文章都将是你不可或缺的指南。记住,学习Java并非难事,关键在于坚持和实践。预祝你在Java的世界中不断探索与进步!


🧑 博主简介:
现任阿里巴巴嵌入式技术专家,15年工作经验,深耕嵌入式+人工智能领域,精通嵌入式领域开发、技术管理、简历招聘面试。CSDN优质创作者,提供产品测评、学习辅导、简历面试辅导、毕设辅导、项目开发、C/C++/Java/Python/Linux/AI等方面的服务,如有需要请站内私信或者联系任意文章底部的的VX名片(ID:gylzbk

💬 博主粉丝群介绍:① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。③ 群内也有职场精英,大厂大佬,可交流技术、面试、找工作的经验。④ 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬。⑤ 进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。

在这里插入图片描述

【Java】Java基础知识面试题大全

在这里插入图片描述

我想说

Java,这门编程语言,已经风靡全球二十多年了。无论你坐在某大厂的高端办公椅上,还是坐在大学课堂的硬板凳上,Java都悄悄潜入你的生活中,成为一门你绕不过去的科目。它像是编程世界里的万能胶,黏合着无数伟大的项目。想要轻松应对Java面试,赢得面试官的青睐?那么快坐稳扶好,让我们一起穿越Java基础知识的海洋,一路挥洒汗水直奔知识的彼岸!接下来,这些基础知识问题将成为你的秘密武器,助你在面试中所向披靡。看完这篇文章,你离Java大神也就不远了!
在这里插入图片描述

基本语法与数据类型

1. 简述Java是什么?

Java是一门面向对象、跨平台的编程语言,由Sun Microsystems(现被甲骨文公司收购)于1995年推出。它具有以下特点:

  • 跨平台性:通过JVM(Java虚拟机)让Java程序可以在多种平台上运行。
  • 面向对象:一切皆对象,封装、继承和多态是其三大特性。
  • 安全性:提供了强大的内置安全机制。
  • 多线程:支持多线程编程,能够开发高性能应用程序。

2. Java的基本数据类型有哪些?

Java的基本数据类型分为四类,共八种:

  • 整数类型byte(8位, -128~127)、short(16位, -32768~32767)、int(32位, -231~231-1)、long(64位, -263~263-1)
  • 浮点类型float(32位, 单精度)、double(64位, 双精度)
  • 字符类型char(16位, 单个字符,Unicode码)
  • 布尔类型boolean(truefalse)

3. 简述Java和C++的区别?

  • 平台独立性:Java通过JVM实现跨平台,C++需要根据平台重新编译。
  • 指针支持:Java不支持指针,降低程序的复杂度和提高安全性,C++支持指针。
  • 内存管理:Java有自动垃圾回收机制,C++需要手动管理内存。
  • 多重继承:Java不支持多重继承,通过接口实现多态,C++支持多重继承。
  • 类库丰富度:Java有丰富的标准类库,C++的标准库较少。

4. 比较==equals的区别?

== 用于比较两个对象的内存地址,即两个引用是否指向同一个对象。

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);  // false

equals 用于比较两个对象的内容,通常在类中重写equals方法。

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.equals(s2));  // true

5. 什么是自动装箱与拆箱?

  • 自动装箱:把基本数据类型自动转换为对应的包装类对象。例如,int -> Integer
  • 自动拆箱:把包装类对象自动转换为对应的基本数据类型。例如,Integer -> int

代码示例:

Integer x = 10;  // 自动装箱
int y = x;      // 自动拆箱

6. 什么是final关键字?

final 关键字可以用于修饰类、方法和变量,具体用途如下:

  • final类:类不能被继承,例如public final class MyClass {}
  • final方法:方法不能被重写,例如public final void myMethod() {}
  • final变量:变量成为常量,只能被赋值一次,例如final int MAX_SIZE = 100;

面向对象编程

7. 什么是面向对象编程(OOP)?

面向对象编程是一种编程范式,基于对象和类的概念。OOP具有以下几个主要特性:

  • 封装:隐藏对象的内部状态,通过方法来操作数据。
  • 继承:一个类可以继承另一个类的属性和方法,代码重用性高。
  • 多态:同一个方法可以有不同的表现形式,通过方法重载和方法重写实现。
  • 抽象:通过抽象类和接口实现数据抽象,只暴露必要的功能。

8. 解释什么是类和对象?

  • :类是抽象的模板,描述了一类对象的共同行为和属性。例如,Car类描述了汽车的共同行为(如启动、加速)和属性(如颜色、速率)。
  • 对象:对象是类的实例,具有具体的属性值和行为。例如,一辆具体的汽车对象。

9. 解释什么是继承?

继承是面向对象编程的一种机制,允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码重用和扩展。Java中的继承通过extends关键字实现。

class Animal {
    void eat() {
        System.out.println("Animal eats");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks");
    }
}

10. 解释什么是多态?

多态允许同一个接口在不同对象执行时表现出不同的行为。分为编译时多态(方法重载)和运行时多态(方法重写)。

  • 方法重载:同一个方法名在同一个类中可以有不同的参数列表,表现为不同的功能。
  • 方法重写:子类可以重写父类的方法,在子类调用时表现出不同的行为。
class Animal {
    void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog barks");
    }
}

11. 解释什么是封装?

封装是将对象的状态(属性)和行为(方法)捆绑在一起,同时隐藏对象的内部实现细节,只对外暴露必要的接口。通过privateprotectedpublic等访问修饰符来控制访问权限。

class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

12. 区别抽象类和接口?

  • 抽象类:可以包含普通方法和抽象方法,且可以有成员变量。通过abstract关键字定义。
  • 接口:只能包含抽象方法(Java 8开始可以有默认方法和静态方法)和常量,不能有成员变量。通过interface关键字定义。

示例:

abstract class Animal {
    abstract void makeSound();
    void eat() {
        System.out.println("Animal eats");
    }
}

interface Flyable {
    void fly();
}

异常处理

13. 解释什么是异常?

异常是程序在运行过程中发生的不正常情况,能够中断程序的正常流程。Java提供了一套异常处理机制来捕获和处理这些异常,确保程序的健壮性和稳定性。

14. Java异常的分类?

  • 检查性异常(Checked Exception):编译时异常,必须进行处理,否则编译不通过。例如IOException
  • 运行时异常(Unchecked Exception):运行时异常,不强制要求处理,可选择进行处理。例如ArrayIndexOutOfBoundsException
  • 错误(Error):严重错误,如内存溢出,通常不会对这些错误进行处理。

15. 异常处理的关键字?

  • try:用于监控代码块。
  • catch:用于捕获并处理异常。
  • finally:用于执行释放资源的代码,无论是否发生异常都会执行。
  • throw:用于抛出异常。
  • throws:用于声明方法可能抛出的异常。

代码示例:

try {
    int[] arr = new int[2];
    System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Array index is out of bounds!");
} finally {
    System.out.println("This block will always execute.");
}

16. 自定义异常

你可以创建自己的异常类来描述应用程序中特定的错误条件。自定义异常类需要继承Exception类或其子类。

class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}

public class Test {
    public static void main(String[] args) {
        try {
            throw new MyException("Custom Exception");
        } catch (MyException e) {
            System.out.println(e.getMessage());
        }
    }
}

集合框架

17. Java集合框架的核心接口有哪些?

Java集合框架提供了多个核心接口,用于存储和操作一组对象:

  • Collection:根接口,用于存储一组元素。
    • List:元素有序且可重复。
    • Set:元素无序且不可重复。
    • Queue:用于存储等待处理的元素。
  • Map:存储键值对(key-value pairs),键不可重复。

18. List和Set的区别?

  • List:元素有序且可重复,可以通过索引访问元素。常见实现类有ArrayListLinkedList等。
  • Set:元素无序且不可重复,不允许存储重复的元素。常见实现类有HashSetLinkedHashSetTreeSet等。

19. Map接口的常见实现类有哪些?

  • HashMap:无序键值对,允许一个null键和多个null值。
  • LinkedHashMap:有序键值对(按插入顺序或访问顺序),允许一个null键和多个null值。
  • TreeMap:按自然顺序或比较器顺序排序键值对,不允许null键。

20. ArrayList和LinkedList的区别?

  • ArrayList:基于动态数组实现,查找速度快(O(1)复杂度),增删速度慢(O(n)复杂度)。
  • LinkedList:基于双向链表实现,查找速度慢(O(n)复杂度),增删速度快(O(1)复杂度)。

代码示例:

List<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);

List<Integer> linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);

21. 如何遍历集合?

Java提供了多种遍历集合的方法:

  1. 使用增强for循环
for (String element : collection) {
    System.out.println(element);
}
  1. 使用迭代器
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
  1. 使用forEach方法(Java 8后)
collection.forEach(element -> System.out.println(element));

多线程与并发

22. 什么是线程?

线程是程序执行的最小单元,一个进程可以包含多个线程。Java通过Thread类和Runnable接口来实现多线程。

23. 创建线程的两种方式?

  1. 继承Thread类
class MyThread extends Thread {
    public void run() {
        System.out.println("MyThread is running.");
    }
}

public class Test {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start();
    }
}
  1. 实现Runnable接口
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("MyRunnable is running.");
    }
}

public class Test {
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable());
        t1.start();
    }
}

24. 什么是同步?同步方法和同步块的区别?

同步是指多个线程在访问共享资源时,通过协调来避免资源冲突。Java提供了synchronized关键字来实现同步:

  • 同步方法:整个方法被同步,只有一个线程可以访问:
public synchronized void method() {
    // 同步方法
}
  • 同步块:只同步方法中的一部分代码,可以提高效率:
public void method() {
    synchronized(this) {
        // 同步块
    }
}

25. 什么是线程池?

线程池是一种限制系统中线程数量,将任务提交到线程池执行,而不是直接创建新线程。Java通过java.util.concurrent包中的Executor框架提供了多种线程池实现。

示例:

ExecutorService executor = Executors.newFixedThreadPool(10);
executor.execute(new MyRunnable());
executor.shutdown();

26. 什么是死锁?

死锁是两个或多个线程互相持有对方需要的资源,导致线程永远等待下去。解决死锁的方法包括:

  • 避免嵌套锁。
  • 使用超时锁。
  • 避免循环等待。

示例:

public class DeadlockDemo {
    public static void main(String[] args) {
        final Object lock1 = new Object();
        final Object lock2 = new Object();
        
        Thread t1 = new Thread(() -> {
            synchronized (lock1) {
                try { Thread.sleep(50); } catch (InterruptedException e) {}
                synchronized (lock2) {}
            }
        });
        
        Thread t2 = new Thread(() -> {
            synchronized (lock2) {
                try { Thread.sleep(50); } catch (InterruptedException e) {}
                synchronized (lock1) {}
            }
        });
        
        t1.start();
        t2.start();
    }
}

JVM与内存管理

27. 简述JVM(Java虚拟机)?

JVM是Java虚拟机,是运行Java字节码的虚拟机,它将字节码文件转换为机器代码,并运行在不同的平台上。JVM屏蔽了底层的操作系统差异,使Java程序具有跨平台性。

28. JVM的主要组件有哪些?

  • 类加载器(Class Loader):负责加载类文件。
  • 运行时数据区
    • 方法区:存储类信息、常量、静态变量等。
    • 堆(Heap):存储所有对象实例和数组。
    • 栈(Stack):每个线程有一个独立的栈,存储局部变量、方法调用等。
    • 程序计数器(PC寄存器):记录当前线程执行的行号指示器。
    • 本地方法栈(Native Method Stack):为JVM使用的native方法服务。
  • 执行引擎:负责执行字节码,包括解释器、即时编译器(JIT)和垃圾回收器(GC)。

29. 什么是垃圾回收(GC)?

垃圾回收是自动释放不再使用的对象内存的过程。Java中不需要手动管理内存,JVM提供自动垃圾回收机制,主要通过标记-清除和标记-整理算法实现。

30. 常见的垃圾回收算法有哪些?

  • 标记-清除(Mark-Sweep):标记所有可达对象,然后清除所有未标记的对象。
  • 标记-整理(Mark-Compact):标记所有可达对象,然后将所有存活的对象移到一端,清理内存碎片。
  • 复制(Copying):将存活对象从一个内存区域复制到另一个内存区域。

31. 分代垃圾回收机制是什么?

JVM使用分代垃圾回收机制,将堆内存分为年轻代(Young Generation)和老年代(Old Generation)。大多数对象在年轻代分配,寿命较长的对象最终被移动到老年代。

  • 年轻代:分为Eden区、Survivor区(From和To)。
  • 老年代:存放经过多次垃圾回收仍然存活的对象。

IO与NIO

32. 解释什么是IO和NIO?

  • IO (Input/Output):提供同步和阻塞的流式API,用于读取和写入数据,例如FileInputStreamFileOutputStreamBufferedReader等。
  • NIO (New Input/Output):提供非阻塞的API,通过通道(Channel)和缓冲区(Buffer)实现,高效处理大规模IO操作。主要类有FileChannelSelectorByteBuffer等。

33. 文件和目录的操作

Java中通过java.io.File类进行文件和目录的操作。

示例代码:

import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) {
        File file = new File("example.txt");
        
        // 创建文件
        try {
            if (file.createNewFile()) {
                System.out.println("File created: " + file.getName());
            } else {
                System.out.println("File already exists.");
            }
        } catch (IOException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }

        // 删除文件
        if (file.delete()) {
            System.out.println("Deleted the file: " + file.getName());
        } else {
            System.out.println("Failed to delete the file.");
        }

        // 创建目录
        File dir = new File("exampleDir");
        if (dir```java
        // 创建目录
        File dir = new File("exampleDir");
        if (dir.mkdir()) {
            System.out.println("Directory created: " + dir.getName());
        } else {
            System.out.println("Failed to create directory.");
        }

        // 列举目录内容
        if (dir.isDirectory()) {
            String[] content = dir.list();
            if (content != null) {
                for (String item : content) {
                    System.out.println(item);
                }
            } else {
                System.out.println("Directory is empty.");
            }
        }

        // 删除目录
        if (dir.delete()) {
            System.out.println("Directory deleted: " + dir.getName());
        } else {
            System.out.println("Failed to delete directory.");
        }

        // 递归删除非空目录
        deleteDirRecursively(new File("exampleDir"));
    }

    // 递归删除目录方法
    public static void deleteDirRecursively(File dir) {
        if (dir.isDirectory()) {
            File[] content = dir.listFiles();
            if (content != null) {
                for (File file : content) {
                    deleteDirRecursively(file);
                }
            }
        }
        dir.delete();
    }
}

34. 基于NIO的文件操作示例:

NIO相对于传统IO而言,提供了更高效的数据处理和操作方式。以下是通过NIO进行文件读取和写入的示例:

import java.nio.file.*;
import java.nio.channels.*;
import java.nio.ByteBuffer;
import java.io.IOException;

public class FileNIO {
    public static void main(String[] args) {
        String filePath = "example.txt";

        // 写入文件
        try (FileChannel fileChannel = FileChannel.open(Paths.get(filePath), StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
            String content = "Hello, NIO!";
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            buffer.put(content.getBytes());
            buffer.flip();
            fileChannel.write(buffer);
            System.out.println("Content written to file.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取文件
        try (FileChannel fileChannel = FileChannel.open(Paths.get(filePath), StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int bytesRead = fileChannel.read(buffer);
            if (bytesRead != -1) {
                buffer.flip();
                System.out.println("Content read from file: " + new String(buffer.array(), 0, bytesRead));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

网络编程

35. 什么是套接字(Socket)?

套接字是网络通信的基础,通过套接字,程序可以实现服务器和客户端之间的通信。Java提供了java.net.Socket类用于客户端,java.net.ServerSocket类用于服务器端。

36. 使用Socket类进行TCP通信示例:

下面是一个简单的TCP客户端和服务器端例子:

服务器端:

import java.io.*;
import java.net.*;

public class Server {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(6666)) {
            System.out.println("Server started...");
            while (true) {
                try (Socket clientSocket = serverSocket.accept()) {
                    System.out.println("Client connected...");
                    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

                    String message;
                    while ((message = in.readLine()) != null) {
                        System.out.println("Received: " + message);
                        out.println("Echo: " + message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端:

import java.io.*;
import java.net.*;

public class Client {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 6666)) {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));

            String message;
            while ((message = userInput.readLine()) != null) {
                out.println(message);
                System.out.println("Server response: " + in.readLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

序列化与反序列化

37. 什么是序列化?

序列化是将对象转换为字节序列,以便存储或者在网络上传输。Java通过Serializable接口实现序列化。

38. 简单的序列化与反序列化示例:

序列化:

import java.io.*;

class Person implements Serializable {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class SerializeDemo {
    public static void main(String[] args) {
        Person person = new Person("John", 30);
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
            oos.writeObject(person);
            System.out.println("Person object serialized.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

反序列化:

import java.io.*;

public class DeserializeDemo {
    public static void main(String[] args) {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person person = (Person) ois.readObject();
            System.out.println("Person object deserialized: " + person);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

反射

39. 什么是反射?

反射是Java提供的一个功能,通过反射可以在运行时获取类的结构(属性、方法、构造函数等)并调用它们。反射提供了动态性和灵活性,但也带来了性能开销和安全问题。

40. 反射的基本操作示例:

import java.lang.reflect.*;

public class ReflectionDemo {
    public static void main(String[] args) {
        try {
            // 获取Person类的Class对象
            Class<?> personClass = Class.forName("Person");

            // 创建Person类的实例
            Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
            Object person = constructor.newInstance("John", 30);

            // 调用getName方法
            Method getName = personClass.getMethod("getName");
            System.out.println("Name: " + getName.invoke(person));

            // 调用setName方法
            Method setName = personClass.getMethod("setName", String.class);
            setName.invoke(person, "Doe");

            // 再次调用getName方法
            System.out.println("Name: " + getName.invoke(person));

            // 获取所有属性
            Field[] fields = personClass.getDeclaredFields();
            for (Field field : fields) {
                System.out.println("Field: " + field.getName());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

注解

41. 什么是注解?

注解是一种用于元数据的语法结构,可以为程序元素(如类、方法、变量等)添加额外的信息。注解不会直接影响程序的运行,但可以通过工具或框架在编译时或运行时进行处理。

42. 自定义注解示例:

import java.lang.annotation.*;
import java.lang.reflect.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
    String value() default "default";
}

class Demo {
    @MyAnnotation(value = "Annotated Method")
    public void annotatedMethod() {
        System.out.println("This method is annotated");
    }
}

public class AnnotationDemo {
    public static void main(String[] args) {
        try {
            Method method = Demo.class.getMethod("annotatedMethod");
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("Annotation value: " + annotation.value());
            }
            method.invoke(new Demo());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

总结

Java作为一门主流的面向对象编程语言,具备很多强大的特性和功能。从基本语法和数据类型,到面向对象编程的四大特性;从异常处理和集合框架,到多线程和并发,再到JVM、IO/NIO、网络编程、序列化、反序列化、反射和注解,Java提供了丰富的工具和 API 来满足各种开发需求。

通过本文的详细讲解,希望初学者能够全面理解 Java 的基础知识,为面试及实际开发工作做好充分的准备。风浪越大,鱼越贵,虽然 Java 的知识点丰富,但只要坚持学习和实践,最终一定能够收获满满。希望本文能够为准备 Java 面试的你提供帮助,祝你面试顺利、前程似锦!

  • 14
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

I'mAlex

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

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

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

打赏作者

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

抵扣说明:

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

余额充值