java基础学习笔记

Corejava学习笔记
学习方法
多花时间,多动手 多问题(三多)
1、 语法和基本规则(记/用)
2、 面向对象的概念和思想(尽量理解)
3、 Java官方类库(记/会用)
Java编程规范
  编程规范不是语法,不遵守也不会报错。
  1.包名全小写
  2.类名/接口名 所有单词首字母大写(UserName)
  3.方法名/变量名 除了首字母外,其他单词首字母大写(userName)
  4.java常量 所有字母全大写,不同单词 _ 隔开


入门了解
一、Java中基本术语:
JDK  java开发工具包,Sun公司提供的java下载安装包
JRE  java运行环境,下载JDK,配制环境变量
JVM  java虚拟机,是java核心功能的提供者
GC  内存垃圾回收机制,由JVM提供
IDE  集成开发环境(商业开发工具)
API  应用程序接口,在java中特指在Sun官方提供的说明文档
二、环境变量的配制(以本机为例:win7)
JAVA_HOME:配制java的安装目录(E:\jdk1.6)
CLASS_PATH:配制java类库的路径以及当前目录(.;%JAVA_HOME%\jre\lib\rt.jar)
PATH: 命令的搜索路径(%JAVA_HOME%\bin)
注:jdk安装目录里的一些文档:
在JDK安装好后的档夹中有个bin目录,里面一般是我们经常用到的一些命令,比如javac、java
   在JDK目录下有个src.zip檔,解压开后就是JDK类库中的源码,也就是rt.jar压缩檔中class檔的源码。
   jre目录是JDK自带的JRE,里面也有bin目录,一般存放的是运行时的一些命令
   jre文件夹中的lib文件中有一些jar文件,里面都是一些class檔在虚拟机运行时作为类代码其中一个比较重要的jar檔就是rt.jar,里面放的是JDK给我们提供的一整套类库的字节码。
三、关于包


分目录以后,有些类在使用前,需要 import语句导入。除了在本包中的类和sun官方提供的 java.lang包中的类,其他类必须用 import导入
java.lang包中的类, 虚拟机自动完成加载
    语法:import 包名.类名 
    写在package后,类定义前
    引入一个类
    注意:
     package在java文档中只能出现一次,并在最前面
     import可以有多条 写在package后,类前
在java中,package 语句用于分目录,用
javac -d . xx.java 编译
java 包名.类名 运行
关于包的例子


四、java注释
//单行注释,从//开始到本行结束都是注释
多行注释:/*开始   */结束,中间都是注释
/**开始  */结束
/**开始的注释,可以被javadoc命令提取成单独的文档,API就是这样生成的。
五、java类的书写格式
package xx;//为class文件分目录
import xx.xx;//导入包中的类
public class 类名{
public static void main(String[] args){
//实现功能的代码
}
}
六、JDK中的基础包
java.lang 核心包,放最核心的类(Object/String/System/Thread)
    java.awt/javax.swing/java.awt.event 图形开发包
    java.applet JAVA的applet小程序包
    java.io 输入输出流包
    java.net 网络包
java.util 工具包(算法/数据结构/集合/设计模式/日期)
java.sql和javax.sql 数据库
运算符
Strictfp:关键字标记的方法必须使用严格的浮点计算来产生理想的结果。
Eg:可以把main方法标记为:public static strictfp void main(String [] args)
  这样,在main方法中的所有指令都将使用严格的浮点计算
 数值类型之间的转换














上图中实心箭头表示无信息丢失轮换,虚箭头表示可能有精度损失的转换
当使用两个数值进行二元操作时,先要将两个转换为同一种类型,然后进行计算:
如果两个操作数有一个是double类型的,另一个操作数就会转换为double类型
否则,如果期中一个操作数是float类型,另一个操作数将会转换为float类型
否则,如果期中一个操作数是long类型,另一个操作数将会转换成long类型
否则,两个操作数都将被 转换为int类型
String 详解 
FLOW CONTROL
一、If-else statement
if(条件1){//only 1次   如果
  //满足条件1时执行的语句
}else if(条件2){//0—n次   或者
  //满足条件2时执行的语句
}else {//0-1次  否则
  //以上条件都不满足时执行的语句
}
按条件,从n个分支选1个执行(没有else可能不选)
TestIf
二、循环
Ctrl +C/D退出死循环
(一)for循环
for(循环变量的初始化;循环条件;步进语句){
//需要反复执行的语句
}
for循环
循环次数不确定的循环
for( ; ; ){
……
if (条件)  break;
……
}
//break 用于跳出循环
循环次数不确定
for循环的执行顺序
双重循环
Eg:有36人,36块砖,每人搬一次,正好搬完  男人 每人搬4块,女人每人搬3块,小孩两个人搬一块
问:几个男,几个女,几个小孩
答案:砖的问题
生成随机数//Random  r = new Random(); int random = r.nextInt(100)+1//[1,100]
(二)、while循环
--语法
初始化循环变量
While(条件){
语句;
步进语句;
}
(三)、do-while循环
--语法
      do{
        ...
      }while(boolean) ;
--先do后while   
--无论如何都会先执行一次再判断条件是否为真,其它的和while循环规则一样


while与do-while
(四)break与continue
break:用于退出循环
continue:退出本次循环,执行下次
break与continue
三、switch分支//写程序尽量用if-else
switch语句只适用于有限种清单的分支
switch(变量){
case 值1: break;
case 值2:break;
default: break;//其他情况
}
注:1、switch后括号中的值必须是int,byte,char,short,枚举类型的变量之一,其它类型的就不行了。
2、每个case后面的值必须是不相等的,而且必须是常量
    3、如果每个case冒号后面的语句执行完后没有break,还会继续执行后面case里的语句,所以在每个case的语句结束后加一个break
    4、default代表如果和所有case后的值都不匹配,就执行这里的语句。无论default写哪都是最后执行的。
Arrays
Int[] arr = new int[5];
注:arr是数组
0-4是数组下标
arr[下标]是数组元素
arr.length可以得到数组的元素个数,也叫数组长度
arr/arr[0]-arr[4]/arr.length 均是可以使用的变量
数组基本使用
数组应用
生成随机密码
彩票生成
一、 递归
1,1,2, 3, 5, 8, 1,3, ……费氏数列 f(n)=f(n-1)+f(n-2) (n>2)
计算数据的第n项值
数组的拷贝
二、一维数组
数组是引用类型   
1、声明数组
     语法:
       --类型[] 数组名 or 类型 数组名[]
       比如:int[] a 或者 int a[]
2、声明数组只是声明了一个数组的引用,并没有在内存中给数组开辟空间
      数组是被当作对象来处理的,所以要初始化,语法:
      --类型[] 数组名=new 类型[长度] 比如:int[] a=new int[10];
3、遍历数组
     for(int i=0;i<a.length;i++){
        System.out.println(a[i]);
     }
for(int g:a){
System.out.println(g);
}
     注意:数组的下标是从0开始的,所以最后一个数组元素的下标为数组长度减1
4、也可以在初始化数组的时候就给数组赋值
比如:int a=new int[]{1,2,3,4};//声明了一个长度是4的int数组,里面的值为1234
          上面的内容还可以简写为:int a={1,2,3,4};
      注意:只有实例化数组的时候才可以给数组一次性赋值,以后就只能单独赋值了
5、 数组排序(由小到大(强调))
冒泡排序
相邻两个进行比较,如果前面大于后面的,交换位置。
选择排序(作业)
记录最小的数的下标,与第一个数字交换,后n-1个依次交换……
插入排序(作业)
拿第一个数做一个小数组然后把第二个数插入进来,然后插入第三个数,……
快速排序
先找一个参照元素(随意),然后把所有比参照小牛放在参照前,同时把所有比参照大的在参照的后面。 把数组分成三个部分:比参照小的、参照元素、比参照大的。然后递归处理比参照小的部分和比参照大的部分。
eg: 49  67  76  13  15  27
i = 1,j = 6(n) 从j开始找比参照小的数字,找到了交换( j=数字所在的位置-1) 
27  67  76  13  15  49 (i=1,j=5)
从i开始找比参照大的数字,找到了交换(i=数字+1)
27  49  76  13  15  67(i=3,j=5)
重复1,2
27  15  76  13  49  67(i=3,j=4)
27  15  13  49  76  67(i=3,j=3)
6、二叉树
平衡二叉树:小的在左边,大的在右边,每个节点左右的层数差不能超过[-1,1]
三、二维数组
   一般最多用到二维数组
 由一维数组组成的数组叫二维数组,二维数组的数组元素就是一维数组。
int[][] arr = new int[一维数组的个数][一维数组的元素个数]
for(;;){
for(;;){
}
}
arr 代表二维数组
arr[0] 代表二维数组的第一个元素(一维数组)
arr[i][j] 代表int ,第i+1个一维数组的第j+1个元素
i 一维数组在二维数组的下标
j 数据在一维数组的下标
eg:二维数组的创建
Basic Conceptions of OOP
一、基本术语
OOA—面向对象的分析
OOD—面向对象的设计
OOP—面向对象的编程
OOT—面向对象的测试
二、 面向对象
面向过程的编程思想:
面向对象的编程思想:师法自然,一切皆是对象,按照类别分类(class)
对象:客观世界的一个事物
类:把同一类别的对象归纳总结成一类,是概念上的,客观世界中找不到具体的类
属性:记录了事物的特征(状态)
学号/姓名/班级/年龄(特征)
方法:记录了事物的行为
考试(行为)
类的语法:
package xx.xx;// 0-1
import xx.xx;// 0-1
[修饰符] class 类名{}
在类的{}中,可以写属性/方法/构造,不能直接写语句
属性方法:
[修饰符] 属性类型   属性名[=默认值]
    属性如果不赋值,有系统默认值(与数组元素一样),属性必须直接定义在类体{}中
方法语法:
[修饰符]  返回类型  方法名(参数列表)
[throws  XXException]{}
方法如果有返回的话,必须用return 语句
写代码时需要写类,用代码用对象,构造用于创造某个类的对象,每个类都有构造。 如果程序员不写构造,系统会提供一个默认无参的构造。如果程序员写了,系统不会提供。
构造语法:
[修饰符]  类名 (参数列表)[throws XXException]{}
构造没有返回这个说法,名字必须是类名
用面向对象的思想写一个学生类
学生{
特征: id/name/age/sex
特为:study/eat
构造两个:无参/4个参数(与特征对应)
}
注:eclipse技巧//保存后自动编译
}//方法/属性最好点出来先
//红线红点是有错误,是警告
//右键点白色区域,先run as -->java Application
//不用写import 语句,在写完ctrl+s自动编译 用
//syso+alt+'/'


方法的重载:
this用法:
this代表本类的一个对象,在方法中代表方法的调用者,在构造中代表即将构造的对象
this.调本类的属性和方法,如果没有重名时,可以省略this.
this()调本类的构造,一般少参的调多参的
this()必须出现在本类构造的第一行
this 不能出现在static方法里


三、 变量和作用范围
变量的作用范围
属性:
类变量 直接定义在类体{}中,有static修饰,作用范围:本类的所有地方
成员变量  直接定义在类体{}中,没static修饰,作用范围:本类所有非static的地方
局部变量  定义在其他位置  作用范围:看定义所在的{}


属性的封装
有些属性不能直接赋值,直接赋值会导致非常错误的属性值
封装步骤:
1 private 修饰属性,隐藏属性
2 提供操作属性的方法,一般是读/写方法 getXX/setXX
3 在构造中,调用set方法操作发情,不直接赋值
只要是非常量的属性一般都要封装
四、参数传递
java中,所有的参数的传递都是值传递(和变量本身没有关系)
基本类型:传的不是变量,是变量的值
引用类型:传的不是变量指针,是引用(地址)
参数传递
五、 创建对象过程
1. 申请内存空间(包括属性)
2. 执行默认初始化
3. 执行显式初始化
4. 执行构造代码
六、 继承
继承例子
继承的好处:
1.代码利用(子类利用父类的代码)
2.支持多态
使用继承的前提条件:
在逻辑关系上,必须 子类is a 父类 ,否则不能使用继承
类与类之间的继承,用extends 关键字
public class 子类 extends 父类{ }
一个子类只能有一个直接父类,所有类的根 是 对象类(java.lang.Object)
如果没有写extends,默认继承Object
属性/非私有方法,可以继承过来
构造不能继承,私有的方法/属性继承不过来
在构造子类对象时,会调用父类的构造。可以默认调用,也可以显式调用。默认调用父类无参构造。
如果父类继承的方法不满足子类的需要(不合适),可以对父类的方法进行重写(覆盖)
原则:
方法名相同/参数必须相同/返回类型相同(5.0以后可以返回子类类型)
访问的权限不能变小
抛出异常不能变大
七、 多态
 :一个名称,多种形态
1、 基本类型的多态:基本类型的自动类型转换
double d = 2.0;
double d = 2;
2、 方法多态
重写/重载
3、 类/接口多态
Pet p = new Pet();//没有发生多态
Pet p = new Cat() ;//多态  拿子类的对象当父类来用
父类的引用可以指向本类或者子类的对象
Pet p = new Object() ;(错)
只能使用父类中定义过的属性和方法,子类自己扩展的属性和方法不能直接使用。
如果子类对方法进行了重写,调重写后的方法(非静态方法)。
如果想使用子类中定义的属性和方法,需要强制类型转换
4、 引用类型的类型转换
必须发生在父子类之间
子类可以自动转换成父类(向上造型)
父类可以强制转换成子类(向下造型)
引用类型的强制类型转换  必须保证 是一种还原,否则会导致类型转换异常
对象/引用的类型,用 instanceof 判断
多态可以用于方法参数和返回类型的设计:
public void print(Object boj){
    ……
}
八、 static、final、abstact、接口
 
static 修饰的元素属于类,所有对象共享
static 属性放在静态池(常驻内存,反复利用)中
static 可以修饰属性、方法、语句块、内部类,可以用 类名. 调用
静态方法的重写问题:
1. 静态方法重写后也是静态方法
2. 发生多态时,父类被引用,如果调用重写的静态方法。调父类中重写前的方法。
static 应该是在类加载完成,static语句块只在类加载时完成一次
类加载的代码:
1. 类名. 的时候
2. 创建该类对象时(new 构造)
3. 声明变量时,不真正加载类 (类名 变量名)
静态语句块在类加载时执行,非静态语句块在构造对象时执行(在执行构造代码前执行)
 
final 关键字 代表不能改变
final 可以修饰变量(属性+局部变量)/方法/类
final 类 不能被继承
final 方法  不能被重写
final 变量  必须只能赋值一次
例题1:写一个程序,模拟领号的算法
要求:每个对象编号不变
    编号自己增加(static  final)
例题2 :写一人银行系统
写用户帐户类:
定期/活期(计算利息的方法完全不同)
定期帐户/活期帐户—>帐户
账户类Account应该包括计算利息的方法  怎么写?(无法实现)




  抽象就是用来解决类似的问题的
abstract 代表无需实现或者无法实现,
可以修饰类?方法,即抽象类/抽象方法
抽象类有构造。无法调用构造 new 抽象类构造(错)
public  abstract 返回类型 方法名(参数列表)[ throws XXException];
抽象类的引用指向的是非抽象子类对象(多态)
抽象方法的调用其实是在调用子类重写以后的非抽象方法
为了保证非抽象子类重写抽象方法:
抽象类可以不包括抽象方法,但是含有抽象方法的类必须是抽象类
接口例:写一个类,黄金
黄金是一种金属
黄金是一种货币
如何实现?接口用于解决些类问题
 一个类只能直接继承另外一个类,但是可以实现多个无关接口(implements)
1. 接口使用interface关键字 public  interface 接口名{}
2. 接口多重继承
3. 接口与接口的是多继承但使用extends 关键
4. 接口可以看成一种特殊的抽象类
5. 接口没有构造,接口中所有的属性都是public static final 的常量
6. 接口中所有方法都是public  abstact 
7. 强制类型转换成接口时,不检测继承关系,但如果类型不匹配,引发类型转换异常
在设计中会大量的采用接口,面向接口编程
特别关注:抽象类与接口的区别(面试题)
接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的,
另外,实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。
还有,接口可以实现多重继承,而一个类只能继承一个超类,但可以通过继承多个接口实现多重继承,接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用.
Advanced Language Feature
一、 访问权限
protected 受保护的,专门为子类继承设计的(就是写给子类用的,出了子类就不能用了)
二、 Object类
1. Object clone()创建原对象的复制品
sun为clone() 定义了规范java.lang.Cloneable接口 实现Cloneable才可以克隆。Cloneable 写给JVM看的,不需要重写任何方法  。Object 只复制一层内存(浅克隆)
实现克隆:
(1)、实现Cloneable接口
(2)、重写clone() 改写权限为public 
2. boolean equals(Object) 所有对象的比较用equals,不用==
用于比较对象之间的相等
Student s1 = new Student(1,”liu”);
Student s2 = new Student(2, ”liu”);
现实世界中,s1 == s2  在计算机中,s1 != s2
java中所有的运算符不可以重写。 所以在Object中定义了对象比较相等的方法(equals),然后子类可以根据自己的比较原则对该方法进行了重写。
== 比较的内存地址,equal()可以根据自己的需要进行重写。Object中equals就是用==实现的。
public boolean equals (Object obj)
关于equals和==的比较
基本类型的比较用==
引用类型和null比较用 ==
引用类型的比较用 equals
引用类型的地址比较用==
3. void finalize() gc前,JVM调用
finalize() 是jvm在gc完成前,自动调用  但gc 不受该方法影响
一般可以在该方法中释放一些非关键资源  关键资源最好还是程序员控制释放,比如:数据库连接
4. String toString() 用String介绍对象
当System.out.print/println 打印对象时 + 作字符串连接对象时,自动调用对象的toString()。  一般来说,类都建议重写toString()。
5. int hashCode() 哈希码,为哈希表提供部分算法
从语法的角度说,equals和hashCode 是独立的,但java中定义的hashCode的规范,使得两个方法连在一起。equals 为true 的两个对象,哈希码必须相同。否则对哈希表影响巨大。  重写equals ,必须也重写hashCode
三、 字符串
java中字符串包括:
String/StringBuffer/StringBuilder
通常情况下,字符串特指String
String  是一组不可改变的unicode的字符序列
编码的问题:ISO 西欧拉丁编码
GBK 东亚(中日朝)gb2312 简体中文
UTF-8 全球文字都可以
UTF和unicode可以相互转换
unicode 16位编码 65536
String s1 = “abc”; //”” 叫字符串常量
String s2 = new String(“abc”);//在堆中
字符串有常量池
 方法例子
char  charAt(int index) 返回该下标的char
boolean endsWith(Strng) 判定字符串的结束
boolean startsWith(String) 判定字符串的开始
boolean equals(Object) 比较字符串与指定字符串是否相等
boolean equalsIgnoreCase(Sting) 忽略大小写比较字符串
new String(byte[])    byte[] getBytes() 实现字符串和byte[]的转换
int indexOf(String ,int index)返回在大字符串中要查找的小字符串的第一个位置,可以设置开始位置 找不到返回-1
int length()返回此字符串的长度
boolean matches(String) 字符串是否匹配给写的正则表达式,用于验证输入
String replace(CharSequence target, CharSequence replacement) 可以替换字符串
String[] split(String)   根据给定正则表达式的匹配拆分此字符串。
String substring(int beginIndex)  返回从指定位置开始截取的字符串
String substring(int beginIndex,int endIndex) JAVA中几乎所有的区间都是前闭后开
String  toUpperCase()  将此 String 中的所有字符都转换为大写。
String trim() 去年前导空白和尾部空白
StringBuffer/StringBuilder
用于字符串的频繁修改
StringBuffer 写成线程安全的,必然降低了效率
StringBuilder 写成非线程安全的,效率高


四、 正则表达式
^ 正则表达式的开始
$ 正则表达式的结束
\ 转义字符
( ) 可以提升结合的优先级
| 或者
.  任意一个字符
[] 代表in的概念,从[] 中任选其一。在[] 中,^ 代表非—代表到(范围)
[b-f]双闭区间


\d 代表所有数字,就是[0-9]
\D 代表非数字
\w 代表所有单词字符,英文中文字符
\W 代表非单词字符


+ 代表前面的内容出现1-n次
? 代表前面的内容出现0-1次
* 代表前面的内容出现0-n次
{n} 代表出现n次
{n,} 代表至少出现n次
{n,m}代表出现n-m次(包括n和m)
五、 包装类
Integer
Double 
包装类的用途
1. 把基本类型包装在一个对象里,实现了基本类型的对象化
2. 可心用parseXX() (parseInt()/parseDouble())可以把字符串转换成基本类型
Integer.parseInt() 可以将字符串转换成int 。int i= Integer.parseInt(s);
toXXString(int ) 可以转换进制(二、八、十六)
所有基本类型都有包装类
包装类和基本类型之间自动转换(5.0以后 自动装箱/解箱)
在[-128,127]之间,发生自动装箱时,从缓冲池里取。
包装类最重要的用法:把String转换成对应的基本类型


六、BigDecimal
//解决大数字(超过long)/double的精度问题 BigDecimal
BigDecimal中的方法:
add() 加法
substract() 减法
multiply () 乘法
divide() 除法
intValue() 转int
doubleValue() 转double
练习:用Scanner 录入全班的同学成绩,先录入人数,然后成绩存入String[]。把成绩从String[]取出,并且求出平均分,打印。
注:成绩从String[]中取出时,需要使用BigDecimal进行计算。
    平均分要求保留小数点后2位即可。


七、 枚举类型
信号灯类(清单类)
红/黄/绿
private 构造
public static 方法
可变参数
在类型后面”…” 代表0-N个该类型,编译时按数组处理
静态导入
使用静态导入可以省略”类名.” 不推荐使用静态导入,严重降低程序的可读性
内部类InnerClass
定义在另一个类内部(在类体{})的类叫做内部类
静态内部类(类似类属性):直接定义在类体{}中,有static 修饰的,
成员内部类(类似成员):直接定义在类体{}中,无static 修饰
局部内部类:可以使用属性和final的局部变量
 匿名内部类:(重点)4无(无类名,无class关键字,有继承关系无继承关键字,无构造)2有(有父类名或者父接口名(代替了匿名内部类的类名),有类体)
集合
一、 使用集合中的ArrayList和HashMap
ArrayList
集合中只能存放多个对象。
ArrayList底层是Object[]
记录元素个数 int
Object[] 初始大小
当元素个数超过初始大小,new 更大的Object[](原大小*3/2+1)
使用arraycopy后,把原来的元素复制到新数组即可


构造/增加元素/删除元素/修改元素/查找元素/取出元素
构造 无参
 增加: add()
删除:clear() 全删/ remove() 单删
修改:set() 用新的元素替换老的元素,同时返回老的元素
查找:contains()/ indexOf()
取出:get()/size()
练习:
用Scanner输入文件名,要求:
1. 用ArrayList 记录所有文件名,输入“over”代表输入结束。
2. 所有文件名输入完毕后,分出文本文件(.txt/.java)和图片文件(.jpg/.bmp)。
3. 并且把所有的文本文件名打印出来,还要打印所有的图片文件名。格式:
文本文件:。。。。。。
图片文件:。。。。。。(本题答案)
HashMap
HashMap 是一个哈希表,存储的是键值对。按key取value
构造/增加/删除/查找/取出
构造 无参
 增加: put(key,values)
删除:clear() 全删/ remove(key) 单删
修改:set() 用新的元素替换老的元素,同时返回老的元素
取出:get(key)/size() 键值对的个数
  取出时知道key,用get()
    取出时不知道key?
1. 调用keySetSet
2. 迭代Set,取出所有的key
Iterator  it = set.iterator();
while(it.hasNext()){
Object obj = it.next();
}
3. 用get(key)取出value
泛型可以回避强制类型转换,同规范参数的类型。在集合类名/接口名后加<元素类型>,然后元素不需要强制类型转换,但集合只能接受该类型对象。


二、List、Map、Set
 List:放入有序,元素可重复
Set:放入无序,元素不可重复
Map:放入无序,key不可重复,value可重复(键值对)
以后变量的类型统一定义成接口的类型(可以兼容所有的类型)
LinkedList—>双向链表,ArrayList—>数组,Vector—>同步实现
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值