面试官:小伙子我们先来详细的好好聊一聊NIO的三大组件

通用策略04丨ORB魔改框架+自适应动量过滤模板 1、该策略第一次尝试使用低通滤波器进行行情择时过滤,同样该方法也可以用于主进场逻辑。2、出场逻辑适用于趋势、隔日波段、高低开等行情结构,对于日线级别长度K线一定积极作用,因此大家可以根据该逻辑进行反向品种筛选。3、在资金管理方面,我注意到一个问题,以往都是按照复权价格计算,但是资金却没有复权,所以这里实际上这里应该将价格除权计算,如下图所示:由于各平台差异,回测绩效以TBQ版本为准!!!本策略仅作学习、交流使用,实盘交易盈亏投资者个人负责!!! 阅读详情

NIO是啥?

NIO是Java从JDK1.4开始引入的一系列改进版输入输出处理手段,也就是New IO,简称NIO,也有说法叫NonBlocking IO,是同步非阻塞式的IO模型,准确地说它支持阻塞非阻塞两种模式。

本篇主要介绍NIO提供的三大组件的概念及使用:Buffer,Channel,Selector。

Buffer

Buffer可以理解为是一个容器,用于存储数据,本质是个数组,存储的元素类型是基本类型。

无论是发送还是读取Channel中的数据,都必须先置入Buffer。

java.nio.Buffer是一个抽象类,子类包括有除boolean外其他所有基本类型的XxBuffer,最常用的是ByteBuffer。

Buffer中的重要概念

capacity:缓冲区的容量,表示该Buffer的最大数据容量,即最多可以存储多少数据。

limit:限制位,标记position能够到达的最大位置,默认为缓冲区最后一位。

position:操作位,指向即将操作位置,默认指向0。

mark:可选标记位。默认不启用,Buffer允许直接将position定位到mark处。

他们满足的关系:mark <= position <= limit <= capacity

面试官:小伙子我们先来详细的好好聊一聊NIO的三大组件

 

以ByteBuffer.allocate(capacity)为例,说明几个重要的过程:

  • 初始化创建HeapByteBuffer,mark = -1,position = 0,limit = cap。
  • 通过put方法向Buffer中加入数据,position++。
  • 装入数据结束后,调用flip方法,将limit设置为position所在位置,position置为0,表示[position,limit]这段需要开始进行输出了【可以使用get方法读取数据】。
  • 输出结束后,调用clear方法,将position置为0,limit置为cap,为下一次读取数据做好准备。

Buffer的所有子类都提供了put和get方法,对应向Buffer存入数据和从Buffe中取出数据,方式分为以下两种:

  • 相对:从Buffer的当前pos处开始读取或写入数据,然后将pos的值按处理元素的个数增加。
  • 绝对:直接根据索引向Buffer中读取或写入数据,不会影响pos位置本身的值。

Buffer使用Demo

public static void main(String[] args) {

        // 创建 bytebuffer  allocate指定底层数组长度
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);

        // 添加数据
        byteBuffer.put("summerday".getBytes());

        // 获取操作位的位置pos = 9
        System.out.println(byteBuffer.position());
        
        // 如果我想遍历summerday呢?哪里结束? limit = 10
        System.out.println(byteBuffer.limit());

        //反转缓冲区 可以利用flip()代替下面两步操作
        //将limit移到position的位置
        byteBuffer.limit(byteBuffer.position());
        
        //将pos移到0
        byteBuffer.position(0);

        // position < limit 
        // 可以利用 hasRemaining代替判断pos和limit之间是否还有可处理元素。
        while(byteBuffer.position() < byteBuffer.limit()){
            // 获取数据
            byte b = byteBuffer.get();
            System.out.println(b);
        }
    }

常用方法介绍

其实Buffer操作的逻辑比较简单,每个方法操作的字段也不外乎上面介绍的几个,下面是一些常用的方法:

设置方法

  • Buffer position(newPosition): 将pos设置为newPosition。
  • Buffer limit(newLimit):将limit设置为newLimit。

数据操作

  • Buffer reset:将pos置为mark的位置。
  • Buffer rewind:将pos置为0,取消设置的mark。
  • Buffer flip: 将limit置pos位置,pos置0。
  • Buffer clear:将position置为0,limit置为cap。

其他操作

public static void main(String[] args) {

        // 如果数据已知,可以使用wrap方法创建ByteBuffer
        ByteBuffer byteBuffer = ByteBuffer.wrap("summerday".getBytes());
        // 获取底层字节数组
        byte[] array = byteBuffer.array();
        System.out.println(new String(array));

    }

Channel

Channel概述

Channel 类似于传统的流对象,但有些不同:

  • Channel 直接将指定文件的部分或全部直接映射 Buffer。
  • 程序不能直接访 Channel 中的数据,包括读取、写入都不行,Channel只能与 Buffer 进行交互。意思是,程序要读数据时需要先通过Buffer从Channel中获取数据,然后从Buffer中读取数据。
  • Channel通常可以异步读写,但默认是阻塞的,需要手动设置为非阻塞。

Channel不应该通过构造器来直接创建,而是通过传统的节点InputStream、OutputStream的getChannel()方法来返回对应的Channel,或者通过RandomAccessFile对象的getChannel方法。

Channel中最常用的三种方法:

  • map():将Channel对应的部分或全部数据映射成ByteBuffer。
  • read():从Buffer中读取数据。
  • write():向Buffer中写入数据。

RandomAccessFile#getChannel

下面是个简单的示例,通过RandomAccessFile的getChannel方法:

public static void main(String[] args) throws FileNotFoundException {

        RandomAccessFile file = new RandomAccessFile("D://b.txt", "rw");
        // 获取RandomAccessFile对应的channel
        try (FileChannel fileChannel = file.getChannel()) {
            ByteBuffer buf = ByteBuffer.allocate(48);
            int byteRead = fileChannel.read(buf);
            while(byteRead != -1){
                System.out.println("read " + byteRead);
                buf.flip();
                while (buf.hasRemaining()){
                    System.out.println((char) buf.get());
                }
                buf.clear();
                byteRead = fileChannel.read(buf);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

SocketChannel与ServerSocketChannel

Java为Channel接口根据不同功能,提供了不同的实现类,比如我们下面的示例:支持TCP网络通信的SocketChannel和ServerSocketChannel。

public class Client {

    public static void main(String[] args) throws IOException {
        // 开启客户端的channel
        SocketChannel sc = SocketChannel.open();
        // 手动设置为非阻塞模式
        sc.configureBlocking(false);
        // 发起连接
        sc.connect(new InetSocketAddress(8081));
        // 手动判断保证连接的建立
        while(!sc.isConnected()){
            // 如果多次连接都没有脸上,会认为此次连接无法建立
            sc.finishConnect();
        }
        // 发送数据
        sc.write(ByteBuffer.wrap("hello , i am client".getBytes()));
        // 关闭通道
        sc.close();
    }
}


public class Server {

    public static void main(String[] args) throws IOException {
        // 开启服务器端的通道
        ServerSocketChannel ssc = ServerSocketChannel.open();
        // 监听端口号
        ssc.bind(new InetSocketAddress(8081));
        // 手动设置为非阻塞模式
        ssc.configureBlocking(false);
        // 接收连接
        SocketChannel sc = ssc.accept();
        // 保证连接
        while (sc == null) {
            sc = ssc.accept();
        }
        // 读取数据
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        sc.read(buffer);
        byte[] bs = buffer.array();
        System.out.println(new String(bs, 0, buffer.position()));
        // 关流
        ssc.close();

    }
}

Selector

NIO实现非阻塞IO的其中关键组件之一就是Selector多路复用选择器,可以注册多个Channel到一个Selector中。Selector可以不断执行select操作,判断这些注册的Channel是否有已就绪的IO事件,如可读,可写,网络连接已完成等。

一个线程通过使用一个Selector管理多个Channel。

public class Server {

    public static void main(String[] args) throws IOException {

        // 开启服务端的通道
        ServerSocketChannel ssc = ServerSocketChannel.open();
        // 设置非阻塞
        ssc.configureBlocking(false);

        // 绑定端口
        ssc.bind(new InetSocketAddress(8081));

        // 开启选择器
        Selector selector = Selector.open();
        // 将通道注册到选择器上
        ssc.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 选择已注册的通道
            selector.select();
            // 获取选择通道的事件
            Set<SelectionKey> keys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = keys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                // 接收
                if (key.isAcceptable()) {
                    // 从事件中获取通道
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    // 接收连接
                    SocketChannel sc = channel.accept();
                    // 设置非阻塞
                    sc.configureBlocking(false);
                    // 注册读 + 写事件
                    sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                }
                // 读
                if (key.isReadable()) {
                    // 获取通道
                    SocketChannel sc = (SocketChannel) key.channel();
                    // 读取数据到buffer
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    sc.read(buffer);
                    // 反转缓冲区
                    buffer.flip();
                    System.out.println(new String(buffer.array(), 0, buffer.limit()));
                    // 在同一通道上注册,将会将之前注册的事件给注册
                    // 注销read事件
                    sc.register(selector, key.interestOps() ^ SelectionKey.OP_READ);
                }
                // 写
                if (key.isWritable()) {
                    // 获取通道
                    SocketChannel sc = (SocketChannel) key.channel();
                    sc.write(ByteBuffer.wrap("hello client, i am server!".getBytes()));
                    // 注销write事件
                    sc.register(selector, key.interestOps() ^ SelectionKey.OP_WRITE);
                }
            }
            iterator.remove();
        }
    }

}


public class Client {

    public static void main(String[] args) throws IOException {

        SocketChannel sc = SocketChannel.open();
        sc.connect(new InetSocketAddress(8081));
        sc.write(ByteBuffer.wrap("hello ! i am client !".getBytes()));
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        sc.read(buffer);
        System.out.println(new String(buffer.array(), 0, buffer.position()));

    }
}
什么是 SAP ABAP AMDP? SAP HANA是SAP开发的一种内存数据库管理系统,它具有出色的性能和处理大规模数据的能力。为了充分利用SAP HANA的性能,SAP引入了AMDP技术,以便将数据库操作推送到数据库服务器执行,从而减少数据传输和处理时间。AMDP方法通常需要输入参数和输出参数。输入参数用于传递数据到SQLScript代码,而输出参数用于接收SQLScript代码的结果数据。ENDMETHOD.ENDCLASS.我们定义了一个输入参数来传递销售订单数据,以及一个输出参数来接收计算结果。ENDMETHOD. 阅读详情

相关推荐

3D医学影像分割实战:从数据预处理到模型训练全流程解析

本文详细解析了3D医学影像分割的全流程,从数据预处理到模型训练,重点介绍了nnUNet框架的应用技巧。通过实战案例,帮助开发者掌握如何处理复杂的.nii.gz文件格式、优化数据预处理流程以及高效训练3D分割模型,特别适合医学影像分析领域的从业者参考。

weixin_29098367的博客 223

Java面试百分百问到的 —— 超详细解读 Java IO(基础篇)

IO,Input/Output,即输入/输出。判断输入输出以计算机内存为中心,如果从内存到外部存储就是输出,从外部存储到内存就是输入。数据传输过程类似于水流,因此称为 IO 流。在 Java 中,根据操作数据单位的不同,IO 流分为字节流和字符流;根据数据流的流向不同,分为输入流和输出流;根据流的角色不同,分为节点流和处理流。Java IO 流共涉及 40 多个类,但都是从表中的 4 个抽象基类派生而来,派生的子类名称都是以其父类名作为子类名的后缀。(抽象基类)字节流字符流输入流Reader。

wdj_yyds的博客 1106

libiec61850实战:手把手教你用C语言动态获取IED设备模型(附完整代码解析)

本文详细介绍了如何使用libiec61850库通过C语言动态获取IED设备模型,包括环境配置、连接建立、模型遍历及错误处理等关键步骤。通过完整的代码示例和实战案例,帮助开发者掌握智能变电站通信中的核心技术,提升工业自动化系统的开发效率。

weixin_42519985的博客 435

【JAVA面试题】之二:Java RandomAccessFile用法

《JAVA面试宝典》中6.3提到了RandomAccessFile,顺便看了下,摘抄如下: 文章: http://blog.youkuaiyun.com/akon_vm/article/details/7429245 说明RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4 RandomAccessFile可以用在断点续传功能上。文章:http:/

水滴石穿的博客 532

STM8S全解析之系列文章4---STM8S芯片项目升级引导程序(使用中断接收升级数据)

STM8S全解析之系列文章4—STM8S芯片项目升级引导程序(使用中断接收升级数据) 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 文章目录STM8S全解析之系列文章4---STM8S芯片项目升级引导程序(使用中断接收升级数据)前言一、Flash划分boot和App二、使用步骤1.引入库2.读入数据总结 前言 用过STM8S都知道它没有中断向量重定向,也就意味着STM8S的中断向量没办法指向其他的位置,间接说明升级的引导

weixin_39853312的博客 1032

Vitis开发环境下的双核ARM通信:Hello World背后的AMP架构解析

本文深入解析了Vitis开发环境下ZYNQ双核ARM Cortex-A9处理器的AMP架构与通信机制。通过详细的硬件配置、内存分配和核间通信实现步骤,展示了如何构建高效的双核Hello World系统,为嵌入式系统开发者提供了实用的开发指南和性能优化技巧。

weixin_29162439的博客 219

RandomAccessFile简介与使用

今儿翻阅jdk源码的时候,无意间发现了RandomAccessFile这个类,从来没见过,也没使用过,带着好奇心,我决定深入了解一下这个类的意义和使用方法。 从字面意思来看这个:随机 通行 文件 其实个人感觉就是: 一款功能较丰富的文本编辑api 翻阅类的注释可以看出,这是一个增强版的文本处理类。 曾经的我们如何处理文本 以前我们要处理一个文件会怎么做?是不是如下图所示: 上面是...

LJHSkyWalker的博客 9万+

OpenClaw 开机自启配置:Windows/macOS/Linux 全平台技术指南

OpenClaw 开机自启全平台配置指南 本文提供了在Windows、macOS和Linux系统上配置OpenClaw开机自启的完整技术方案。主要内容包括: Windows配置:提供三种方法(Windows服务、任务计划程序、启动文件夹),详细说明服务脚本创建、服务注册和测试流程 macOS配置:使用LaunchAgent实现开机自启,包含配置文件创建和加载方法 Linux配置:通过systemd服务实现,包括服务单元文件创建和启用步骤 系统要求:明确硬件(64位CPU/4GB内存)和软件(各平台操作系统版

一键难忘的博客 2995

java-----NIO总结(三)

前两篇博客我们通过将accept和read设置成非阻塞式的方式实现了同步非阻塞模式,但是缺点在于在服务端需要为每个客户端都要创建一个线程来处理每个客户端的请求,这点相对来说比较耗费服务端资源,比如我们通常用到的Socket长连接用于心跳检测,其实客户端根本就没有数据要发送,只是想要告诉服务端我还活着而已,这时候为客户端单独创建一个线程的话,未免就有点小题大做了,因此迫切的需要出现一种可以减少在服务

扇扇来驰的博客 2245

Cadence SPB16. 6 安装流程

1.首先下载CadenceAllegroSPBorCAD16.6安装包 下载之后运行其中的setup.exe,然后先安装第一项LicenseManager 一直按next或install, 直到被询问license时,单击cancel,然后选是和finish。 2,安装Product Installtion 直接点next跳过这一步 安装完成后,点Exit退出 3.按ctrl+alt+delete打开任务管...

wangjie36的博客 5153

82、yolov11检测模型迁移瑞芯微rk3588和使用昇腾设备300i DUO卡推理 batch=1/3,支持昇腾NMS迁移npu推理

本文介绍了使用昇腾设备进行分割推理的测试流程,包括两种测试方式(cann+onnx和om)。首先验证300iDUO卡的可用性,随后创建Docker镜像和容器以搭建独立环境。通过从指定仓库拉取Ubuntu 20.04镜像,创建容器并映射目录。进入容器后安装必要组件(Python3、GCC等)和系统工具(pciutils、net-tools等),为后续模型转换和迁移做准备。整个流程旨在构建可交付给第三方的标准化测试环境。

sxj731533730 1214

面试官:什么是 NIO?NIO 的原理是什么机制?

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!源码精品专栏原创 | Java 2020超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析...

weixin_44421461的博客 282

AIGC时代的必备技能:提示词工程(Prompt Engineering)全面指南

本文主要介绍了AIGC时代的重要技能——提示词工程(Prompt Engineering)。文章首先定义了提示词的概念,强调其作为人类与AI沟通桥梁的重要性,并详细阐述了提示词的功能特性,包括输入、大模型处理和输出三个环节。接着,文章探讨了提示工程的重要性,如提高输出质量、节省资源和时间等。随后,文章深入分析了提示词的基本构成要素,包括指令、上下文、输入数据和输出指示符,并提出了提示词的五大基本原则:清晰性与具体性、提供充足的上下文、明确任务与目标、考虑受众和迭代思维。最后,文章介绍了提示词的七大常见技巧

weixin_43178406的博客 27万+

面试官:BIO、NIO、AIO是什么,他们有什么区别?

面试官:BIO、NIO、AIO是什么,他们有什么区别?

真正的大师永远怀着一颗学徒的心 9949

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

netty+nio

netty是什么 面试官:介绍一下自己对 Netty 的认识吧!小伙子。 我:好的!那我就简单用 3 点来概括一下 Netty 吧! Netty 是一个 基于 NIO 的 client-server(客户端服务器)框架,使用它可以快速简单地开发网络应用程序。 它极大地简化并优化了 TCP 和 UDP 套接字服务器等网络编程,并且性能以及安全性等很多方面甚至都要更好。 支持多种协议 如 FTP,SMTP,HTTP 以及各种二进制和基于文本的传统协议。 用官方的总结就是:Netty 成功地找到了一种在不妥协

weixin_38446891的博客 1384

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Netty-常见面试题-总结

👨‍💻面试官:Netty 核心组件有哪些?分别有什么作用?🙋我:表面上,嘴上开始说起 Netty 的核心组件有哪些,实则,内心已经开始 mmp 了,深度怀疑这面试官是存心搞我啊!简单介绍 Netty 最核心的一些组件(对于每一个组件这里不详细介绍)。通过下面这张图你可以将我提到的这些 Netty 核心组件串联起来。这么说吧!EventLoop(事件循环)接口可以说是 Netty 中最核心的概念了!

Java程序员的知识博客 1279

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【刚拿了饿了么P7 offer】没想到面试官这么问我!!!

点关注,不迷路!如果本文对你有帮助的话不要忘记点赞支持哦! 今年初拿了个饿了么P7的offer,废话不多说,直接上题吧。 一面 首先上来就是自我介绍,简单的说下自己的项目经验,涉及的技术栈之类的。 然后每一轮必问的问题来了:说说你印象最深刻的项目! 这个已经被问的都不想说了,挑个有很多槽点的来说,并且自己已经知道问题答案的,我说了一个服务迁移同时双写的解决方案。 接着按照国际惯例先来一个HashMap原理。。。 那就来吧,简单说下HashMap数组+链表结构,hash的实现方式和好处,高低位异或降低.

SQY0809的博客 2453

Dubbo面试30连问!面试官问小伙子你00后吧?

1、为什么要用 Dubbo?随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就出现了,Dubbo 也就这样产生了。2、Dubbo 的整体架构设计有哪些分层?这不是秋招即将开始!鄙人不才整理了一些网上大厂面试资料,为了能让大家有更好的面试资料去面试大厂的技术岗位,够大家刷题好

Trouvailless的博客 234

【日拱一卒进击大厂系列】面试官:为什么单线程的Redis可以实现高并发访问(1)

2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。BAT面试经验实战系列:Spring全家桶+Redis等其他相关的电子书:源码+调优面试真题:《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》

Y1567409的博客 326

java面试官:程序员,请你告诉我是谁把公司面试题泄露给你的?

前情提要: 面试官:你好!请先做一下自我介绍! 程序员:balabalabala... 前戏先过了.... 面试官:先介绍SpringCloud核心组件及其作用 程序员:SpringCloud由以下5个核心组件构成...另外,SpringCloud的工作流程是这样子的↓ 面试官(疑惑的低头看了看自己的问题):嗯,不错,工作流程都说出来了。那介绍一下springcloud心跳机制 程序员:当一个服务器启动,会将它的IP地址等信息注册到Eureka...但是Eureka有....等缺点..

m0_50180963的博客 330

面试官:说说零拷贝技术的实现原理?

零拷贝(Zero-copy)技术是一种计算机操作系统中用于提高数据传输效率的优化策略。在传统的数据传输过程中,需要将数据从一个缓冲区拷贝到另一个缓冲区,然后再传输给目标。这涉及到多次的 CPU 和内存之间的数据拷贝操作,会消耗 CPU 的时间和内存带宽。而零拷贝技术通过直接共享数据的内存地址,避免了中间的拷贝过程,从而提高了数据传输的效率。

m0_69632475的博客 1011

【日拱一卒进击大厂系列】面试官:为什么单线程的Redis可以实现高并发访问

由于篇幅有限,这里就不一一罗列了,20道常见面试题(含答案)+21条MySQL性能调优经验小编已整理成Word文档或PDF文档还有更多面试复习笔记分享如下《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!**

2401_84413032的博客 919
上一篇: 弯道超车!阿里甩出Spring Security宝典我粉了
下一篇: 分布式事务(2PC/3PC/TCC 最终一致性详解)
爱玛士
博客等级 码龄7年 720粉丝 253原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值