Java 基础知识点 笔记总结 (七),我凭着这份《Kafka源码实战》碾压面试官

  • 比较字符串内容值是否相同。

package com.holmes.java04;

import org.junit.Test;

public class StringTest {

@Test

public void test1(){

String s1 = “abc”;

String s2 = “abc”;

System.out.println(s1 == s2);//比较s1和s2的地址是否相同。

System.out.println(s1.equals(s2));//比较字符串内容值是否相同。

}

}


String字符串,什么情况下,重新指定内存区域进行赋值:

无论,重复赋值,还是拼接字符串,还是修改指定替换字符串等,都是要重新指定内存区域进行赋值!!!

2. String的字面量创建 和 new 对象形式

========================================================================================


String对象创建的四种方式:

在这里插入图片描述

整体上,也就两种方式:一种字面量,一种new创建对象。

  • 通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。

  • 通过 new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对象的值。

package com.holmes.java04;

import org.junit.Test;

public class StringTest {

@Test

public void test1(){

//通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。

String s1 = “javaEE”;

String s2 = “javaEE”;

//通过 new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对象的值。

String s3 = new String(“javaEE”);

String s4 = new String(“javaEE”);

System.out.println(s1 == s2);//true

System.out.println(s1 == s3);//false

System.out.println(s3 == s4);//false

}

}

3. String 字符串 内存存储原理

==================================================================================


字面形式和new + 对象的内存存储原理:

在这里插入图片描述

在这里插入图片描述

面试题:String s = new String(“abc”);方式创建对象,在内存中创建了几个对象?

两个,一个是堆空间中new的对象,另一个是char[]对应常量池中的数据:“abc”。

4. String 不同拼接对比 效果

=================================================================================

下面的拼接效果必须牢记!!!!

在这里插入图片描述

package com.holmes.java04;

import org.junit.Test;

public class StringTest {

@Test

public void test1(){

String s1 = “javaEE”;

String s2 = “hadoop”;

String s3 = “javaEEhadoop”;

String s4 = “javaEE”+“hadoop”;

String s5 = s1 + “hadoop”;

String s6 = “javaEE” + s2;

String s7 = s1 + s2;

String s8 = (s1 + s2).intern();

//没有变量相加,仅仅只是字符串,这样声明的s4的内存地址就仅仅在常量池中。

System.out.println(s3 == s4); //true

//只要有变量相加的,那么该创建方式就是new对象形式,也就是要存储到堆内存地址。

System.out.println(s3 == s5); //false

System.out.println(s3 == s6); //false

System.out.println(s5 == s6); //false

System.out.println(s3 == s7); //false

System.out.println(s5 == s7); //false

System.out.println(s6 == s7); //false

//通过调用intern()方法,返回值就在常量池中!

System.out.println(s3 == s8); //true

}

}

5. String 和 数组 常用的混合面试题

=====================================================================================

package com.holmes.java04;

public class StringTest2 {

//也算涉及到了String类型的不可变性。

//这里与下面change函数中的str的内存地址不同!

String str = new String(“good”);

char[] ch = {‘t’,‘e’,‘s’,‘t’};

public void change(String str,char ch[]){

//这里的str与上面的str不同!!地址不同,这里是形参是参数!!!

str = “test ok”;

ch[0] = ‘b’;

}

public static void main(String[] args) {

StringTest2 ex = new StringTest2();

ex.change(ex.str,ex.ch);

//有人疑惑这里为什么不是test ok, 原因很简单,因为这里的ex.str是作为形参传入。

System.out.println(ex.str); //good

//至于数组没有不可变形,对应地址相同,只不过内容中的第一个值变化了而已。

System.out.println(ex.ch); //best

}

}

6. JVM涉及字符串 内存结构

==============================================================================


JDK1.6版本,字符串常量池都在方法区中:

在这里插入图片描述


JDK除了1.7版本,字符串常量池在堆中:

在这里插入图片描述


JDK1.8以及以后的版本,字符串常量池都在方法区中:

在这里插入图片描述

7. String 常用方法

============================================================================


在这里插入图片描述

在这里插入图片描述

问题一:什么情况下,indexOf(str) 和 lastIndexOf(str)返回值相同?

**答:情况一:存在唯一的一个str。情况二:不存在str时。

此外,indexOf 和 lastIndexOf方法如果未找到都是返回-1。**


在这里插入图片描述

上面的replaceAll()函数方法,matches()函数方法,涉及到正则表达式内容,如下:

在这里插入图片描述

8. 涉及到String 类与其他结构之间的转换

======================================================================================

8.1 常见的小错误



首先,纠正一个经常犯下的错误:

String str = “123”;

//错误的,强转的前提必须是子父类的前提下!!!

int num = (int)str;

8.2 String 和 int 之间的转换



String 转 int:(调用包装类的静态方法,Integer.parseXxx())

String str = “123”;

//调用包装类的静态方法,才是正确的

int num = Integer.parseInt(str)

int 转 String:(调用包装类的静态方法,Integer.toString() 和 String.valueOf())

String s2;

String s3;

int num2 = 123;

//方式一:Integer.toString()方法

s2 = Integer.toString(num2);

//方式二:String.valueOf()方法

s3 = String.valueOf(num2);

System.out.println(s2.getClass()+ “,” +s3.getClass());

//class java.lang.String , class java.lang.String

//方式三:就是通过加空字符串 “” 。

String s4 = 123 + “”;


8.3 String 和 char[]字符组 之间的转换


在这里插入图片描述

牢记toCharArray()函数方法:

package com.holmes.java04;

import org.junit.Test;

public class StringTest {

@Test

public void test1(){

String str1 = “abc123”;

//调用String的toCharArray()拆分字符串 转为 字符数组。

char[] charArray = str1.toCharArray();

//遍历一下charArray

for (int i=0;i<charArray.length;i++){

System.out.println(charArray[i]);

}

char[] arr = new char[]{‘h’,‘e’,‘l’,‘l’,‘o’};

//直接将字符数组当作参数放入字符串对象,就直接形成了字符串

String str2 = new String(arr);

System.out.println(str2);

}

}

8.4 String字符串 和 byte[]字节数组 之间的转换


这里就会出现一个编码和解码的一个效果:

在这里插入图片描述


**String 转为 byte[]:

(调用String的getBytes()方法)**

package com.holmes.java04;

import org.junit.Test;

import java.io.UnsupportedEncodingException;

import java.lang.reflect.Array;

import java.util.Arrays;

public class StringTest {

@Test

public void test1() throws UnsupportedEncodingException {

//调用String的getBytes()方法

String str1 = “abc123中国”;

byte[] bytes = str1.getBytes(); //使用默认的字符集(utf-8),进行转换

//Arrays.toString()方法显示字符串。

System.out.println(Arrays.toString(bytes));

//[97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67],这里结果就是aciII码

//此外,在utf-8当中一个汉字是占3个字节。

//使用gbk编码,就要添加参数

byte[] gbks = str1.getBytes(“gbk”);

System.out.println(Arrays.toString(gbks));

//[97, 98, 99, 49, 50, 51, -42, -48, -71, -6] 在gbk中一个汉字包含两个字节。

}

}


**byte[]字节数组 转 String字符串:

(new对象参数传入,来转换)**

package com.holmes.java04;

import org.junit.Test;

import java.io.UnsupportedEncodingException;

public class StringTest {

@Test

public void test1() throws UnsupportedEncodingException {

//调用String的getBytes()方法

String str1 = “abc123中国”;

byte[] bytes = str1.getBytes(); //使用默认的字符集(utf-8),进行转换

byte[] gbks = str1.getBytes(“gbk”);

//同样这里也是用默认的字符集(utf-8)来进行解码

String str2 = new String(bytes);

System.out.println(str2);

//因为这里是通过gbk编码的,但使用utf-8来解码就会乱码

String str3 = new String(gbks);

System.out.println(str3);

//abc123中国

//abc123�й�

}

}

9. String 拼接 小面试题

===============================================================================

因为一个final,就导致结果不同,牢记常量与常量拼接的结果是存储在常量池中,且常量池不会存在相同内容的常量。final声明后变量就变成了常量!

package com.holmes.java04;

import org.junit.Test;

public class StringTest {

@Test

public void test1(){

String s1 = “javaEEhadoop”;

String s2 = “javaEE”;

String s3 = s2 + “hadoop”;

System.out.println(s1 == s3); //false

//final声明后,s4就变成了常量,常量和常量的拼接结果就在常量池中,因此返回true。

final String s4 = “javaEE”;

String s5 = s4 + “hadoop”;

System.out.println(s1 == s5); //true

}

}

10. StringBuffer 和 StringBuilder 介绍

=================================================================================================

本质上字符串存储规则,其实就是个char[]数组,String不可变,StringBuffer和StringBuilder可变。


String , StringBuffer , StringBuilder三者的异同?

String:不可变的字符序列。

StringBuffer:可变的字符序列:线程安全的,效率偏低。

StringBuilder:可变的字符序列:jdk5.0新增,线程不安全的,效率高。

上面三者底层使用char[]存储。(StringBuffer和StringBuilder因为继承AbstractStringBuilder,因此也是char[] value存储。)


11. String ,StringBuffer,StringBuilder 源码分析

=========================================================================================================


String源码分析:

String str = new String();

//执行实际源码为:char[] value = new char[0];

String str1 = new String(“abc”);

//执行实际源码为:char[] value = new char[]{‘a’,‘b’,‘c’};


StringBuffer源码分析:(StringBuilder源码差不多,就是安不安全的问题)

在这里插入图片描述

StringBuffer sb1 = new StringBuffer();

//执行实际源码为:char[] value = new char[16]; 底层创建了一个长度是16的数组。

sb1.append(‘a’); //value[0] = ‘a’;

sb1.append(‘b’); //value[1] = ‘b’;

StringBuffer sb2 = new StringBuffer(“abc”);

//执行实际源码为:char[] value = new char[“abc”.length() + 16]; 字符串的长度外加16个长度数组。

//问题1:System.out.println(sb2.length()); 输出为3呢,还是3+16呢?

//答案:其实和加不加16没关系,因为length返回的count,是数组中有多少数据。

//问题2:既然开始定义长度为16,一旦满了就会有一个扩容问题?

//如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。

//append方法中,调用了ensureCapacityInternal(确保容量完整的)方法,进而满足扩容。

//默认情况下扩容为原来容量的2倍(向左进位1,就是乘于2)+2,同时将原有数组中的元素复制到新的数组中。

开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)。可以直接定义容量大小,区别就是安全不安全。

12. StringBuffer 和 StringBuilder类常用的方法

====================================================================================================

StringBuffer和StringBuilder的常用方法差不多,都是一样:

在这里插入图片描述

在这里插入图片描述

当append和insert时,如果原来value数组长度不够,可扩容。

在这里插入图片描述

package com.holmes.java04;

import org.junit.Test;

public class StringBufferBuilderTest {

@Test

public void test1(){

StringBuffer sb1 = new StringBuffer(“abc”);

sb1.append(1);

sb1.append(‘1’);

System.out.println(sb1);

//注意:像delete这样的方法,删除的索引是左闭右开!!

sb1.delete(2,4);

System.out.println(sb1);

sb1.replace(2,4,“hello”);

System.out.println(sb1);

sb1.insert(2,“c”);

System.out.println(sb1);

sb1.reverse();

System.out.println(sb1);

System.out.println( sb1.indexOf(“c”));

System.out.println(sb1.substring(2,4));

System.out.println(sb1.charAt(5));

sb1.setCharAt(0,‘m’);

System.out.println(sb1);

}

}


方法链是一个很重要的形式,方法链的原理:

在这里插入图片描述


13. 对比String ,StringBuffer,StringBuilder的效率

=========================================================================================================

package com.holmes.java04;

import org.junit.Test;

public class StringBufferBuilderTest {

@Test

public void test1(){

long startTime = 0;

long endTime = 0;

String text = “”;

StringBuffer buffer = new StringBuffer(“”);

StringBuilder builder = new StringBuilder(“”);

startTime = System.currentTimeMillis();

for (int i = 0;i < 20000; i++){

buffer.append(String.valueOf(i));

}

endTime = System.currentTimeMillis();

System.out.println(“StringBuffer的执行时间:” + (endTime - startTime));

startTime = System.currentTimeMillis();

for (int i = 0;i < 20000; i++){

builder.append(String.valueOf(i));

}

endTime = System.currentTimeMillis();

System.out.println(“StringBuilder的执行时间:” + (endTime - startTime));

startTime = System.currentTimeMillis();

for (int i = 0;i < 20000; i++){

text += i;

}

endTime = System.currentTimeMillis();

System.out.println(“String的执行时间:” + (endTime - startTime));

//String的效率远远小于前两者

//效率从高到低排列: StringBuilder > StringBuffer > String

//考虑是否有线程安全问题是否要同步,就要使用StringBuffer. StringBuffer线程安全,StringBuilder线程不安全。

}

}

14. Java 时间日期 的相关API

==================================================================================


计算世界时间的主要标准有:

在这里插入图片描述


方法一:

java.lang.System类的日期时间:(计算时间差)

  • System.currentTimeMillis()返回当前时间于1970年1月1日0时0分0秒之间以毫秒为单位的时间差。

  • 此方法经常用来计算时间差。


方法二:

java.util.Date类表示特定的瞬间,精确到毫秒:

package com.holmes.java04;

/*

方式一:两个构造器使用

构造器一:Date() :创建一个对应当前时间的Date对象。

构造器二:创建指定毫秒数(时间戳)的Date对象。

方式二:两个方法的使用

调用toString()方法:显示当前的年,月,日,时,分,秒。

getTime()方法:获取当前Date对象对应的毫秒数(时间戳)。

*/

import org.junit.Test;

import java.util.Date;

public class DateTimeTest {

@Test

public void test2(){

//构造器一:Date() :创建一个对应当前时间的Date对象

Date date1 = new Date();

//调用toString()方法:显示当前的年,月,日,时,分,秒

System.out.println(date1.toString());//Sat Nov 06 14:55:02 CST 2021

//getTime()方法:获取当前Date对象对应的时间戳

System.out.println(date1.getTime());//1636181996537

//构造器二:创建指定毫秒数(时间戳)的Date对象

Date date2 = new Date(1636181996537L);

System.out.println(date2.toString());

}

}


在sql也有一个,java.sql.Date类,对应着数据库中的日期类型的变量。

package com.holmes.java04;

/*

java.sql.Date类的Date对象:

同样调用toString()方法和getTime()方法

*/

import org.junit.Test;

import java.sql.Date;

public class DateTimeTest {

@Test

public void test2(){

//创建java.sql.Date的对象

Date date1 = new Date(23453456342L);

System.out.println(date1.toString()); //1970-09-29

System.out.println(date1.getTime()); //23453456342

}

}


怎么将sql.Date 转为 util.Date对象?

因为多态性,直接赋值就可。

package com.holmes.java04;

import org.junit.Test;

public class DateTimeTest {

@Test

public void test2(){

//创建java.sql.Date的对象

java.sql.Date date1 = new java.sql.Date(23453456342L);

//创建java.util.Date的对象

java.util.Date date2 = new java.util.Date();

//sql.Date 转 util.Date 多态性直接赋值就可

date2 = date1;

System.out.println(date2);

}

}

怎么将util.Date 转为 sql.Date对象?

因为参数都有毫秒(时间戳),所以我们可以通过getTime()的方式来解决这种问题!!

package com.holmes.java04;

import org.junit.Test;

public class DateTimeTest {

@Test

public void test2(){

//创建java.sql.Date的对象

java.sql.Date date1 = new java.sql.Date(23453456342L);

//创建java.util.Date的对象

//情况一:左边是util,右边是sql,多态性,这样就可以强转。

java.util.Date date2 = new java.sql.Date(32453476342L);

java.sql.Date date3 = (java.sql.Date)date2;

System.out.println(date3); //1971-01-11

//情况二:都是util直接强转会报错!!cannot be cast

java.util.Date date4 = new java.util.Date(32453476342L);

//java.sql.Date date5 = (java.sql.Date)date4; 错误的!

//但是有一个方法getTime(),来获得毫秒数就可以直接当作参数传递过去,就完美解决了

java.sql.Date date6 = new java.sql.Date(date4.getTime());

System.out.println(date6); //2021-11-06

}

}

15. IDEA 的 debug调试

================================================================================

在这里插入图片描述

16. JDK8之前日期时间API SimpleDateFormat类

=================================================================================================

16.1 SimpleDateFormat默认无参数情况



SimpleDateFormat是对日期Date类的格式化和解析。

  • 使用format()方法,格式化:日期 转为 字符串。

  • 使用parse()方法,解析:格式化的逆过程,字符串 转为 日期

package com.holmes.java05;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class DateTimeTest {

@Test

public void testSimpleDateFormat() throws ParseException {

//实例化SimpleDateFormat:使用默认的构造器

SimpleDateFormat sdf = new SimpleDateFormat();

//格式化:日期 转为 字符串

Date date = new Date();

String formatStr = sdf.format(date);

System.out.println(formatStr);

//解析:格式化的逆过程,字符串 转为 日期

//需要注意的是字符串的格式也必须和date格式一样,不然就抛出异常了

String str = “21-11-7 下午3:04”;

Date date1 = sdf.parse(str);

System.out.println(date1);

}

}

16.2 SimpleDateFormat有参数情况



SimpleDateFormat的参数,不同格式的参数对应不同返回的结果。可以查看java参考手册这对SimpleDateFormat有参数的构造器这一节。

jdk参考手册

在这里插入图片描述

package com.holmes.java05;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class DateTimeTest {

@Test

public void testSimpleDateFormat() throws ParseException {

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat(“yyyy.MM.dd G ‘at’ HH:mm:ss z”);

System.out.println(sdf.format(date));

//常用格式如下:

//年:小写y,月:大写M,时分秒:小写hms。

SimpleDateFormat sdf1 = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);

//格式化format:日期 转为 字符串

System.out.println(sdf1.format(date));

//解析,同样这里parse解析的格式也必须和参数定义的格式一样!!否则抛出异常

System.out.println(sdf1.parse(“1999-11-07 04:07:55”));;

//2021.11.07 公元 at 16:09:21 CST

//2021-11-07 04:09:21

//Sun Nov 07 04:07:55 CST 1999

}

}


很多页面传字符串"2020-09-08" 转为java.sql.Date(以方便存储数据库中)。

package com.holmes.java05;

import org.junit.Test;

import java.text.ParseException;

import java.text.SimpleDateFormat;

public class DateTimeTest {

@Test

public void testExer() throws ParseException {

String str = “2020-09-08”;

//参数格式有一种为:“yyyy-MM-dd hh:mm:ss”

//要对应前端传过来的数据,像后面的hh:mm:ss,忽略就行。

SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd”);

//util下的date

java.util.Date dateUtil = sdf.parse(str);

java.sql.Date dateSql = new java.sql.Date(dateUtil.getTime());

System.out.println(dateSql);

}

}


总天数差的一些计算,可以用到方法类和getTime类方法。

在这里插入图片描述


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

image.png

ws ParseException {

String str = “2020-09-08”;

//参数格式有一种为:“yyyy-MM-dd hh:mm:ss”

//要对应前端传过来的数据,像后面的hh:mm:ss,忽略就行。

SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd”);

//util下的date

java.util.Date dateUtil = sdf.parse(str);

java.sql.Date dateSql = new java.sql.Date(dateUtil.getTime());

System.out.println(dateSql);

}

}


总天数差的一些计算,可以用到方法类和getTime类方法。

在这里插入图片描述


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-AsXkF6vm-1711692406432)]
[外链图片转存中…(img-mNCCYhNI-1711692406432)]
[外链图片转存中…(img-TVZi6ous-1711692406433)]
[外链图片转存中…(img-Ck2IB3sf-1711692406433)]
[外链图片转存中…(img-fXdpBu5E-1711692406433)]
[外链图片转存中…(img-I2iCfyuH-1711692406434)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-M4LiQdO4-1711692406434)]

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

[外链图片转存中…(img-hEE5JvTE-1711692406434)]

[外链图片转存中…(img-FBNgKe9H-1711692406435)]

[外链图片转存中…(img-jrnCpdeo-1711692406435)]

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值