先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:xhs1999xhs (备注Java)
正文
文章目录
优化目标
引入
我们先从回顾一下Logistic回归,看看Logistic回归是如何演变为支持向量机的。
当
y
=
1
y=1
y=1时,如果我们希望
h
θ
(
x
)
≈
1
h_{\theta}(x)≈1
hθ(x)≈1,则
θ
T
x
\theta^{T}x
θTx远大于0.
当
y
=
0
y=0
y=0时,如果我们希望
h
θ
(
x
)
≈
0
h_{\theta}(x)≈0
hθ(x)≈0,则
θ
T
x
\theta^{T}x
θTx远小于0.
下面是每个样本的代价函数,注意没有求和,代表每个单独的训练样本对Logistic回归的总体目标函数的贡献。
然后我们将
h
θ
(
x
)
h_{\theta}(x)
hθ(x)的具体公式带入进去,得到的就是每个训练样本对总体函数的具体贡献:
现在我们再来考虑
y
=
1
,
y
=
0
y=1,y=0
y=1,y=0的情况,函数图像如下:
下面我们
y
=
1
y=1
y=1为例,用两条直线近似等效曲线,来向支持向量机转换,例如我以
z
=
1
z=1
z=1为起点,作两条直线近似取代曲线
−
l
o
g
1
1
e
−
z
-log\frac{1}{1+e^{-z}}
−log1+e−z1,同理
y
=
0
y=0
y=0时也一样。
当
y
=
1
y=1
y=1时,两条直线记为
C
o
s
t
1
(
z
)
Cost_1(z)
Cost1(z)。
当
y
=
0
y=0
y=0时,两条直线记为
C
o
s
t
0
(
z
)
Cost_0(z)
Cost0(z)。
构建支持向量机
这是我们在Logistic回归中使用的正规化代价函数
J
(
θ
)
J(\theta)
J(θ)
然后我们用
C
o
s
t
1
(
θ
T
x
(
i
)
)
Cost_1(\theta{T}x{(i)})
Cost1(θTx(i))和
C
o
s
t
0
(
θ
T
x
(
i
)
)
Cost_0(\theta{T}x{(i)})
Cost0(θTx(i))将
−
l
o
g
h
θ
(
x
(
i
)
)
-logh_{\theta}(x^{(i)})
−loghθ(x(i))和
−
l
o
g
(
1
−
h
θ
(
x
(
i
)
)
)
-log(1-h_{\theta}(x^{(i)}))
−log(1−hθ(x(i)))代替,去掉
1
m
\frac{1}{m}
m1,然后对于正规项,我们不再用
λ
\lambda
λ来控制正规项的权重,而选择用不同的常数C来控制第一项的权重,最后我们得到支持向量机的总体优化目标如下:
与Logistic回归不同的是,sigmoid函数输出的不是概率,而是直接输出0或者1。
直观理解SVM
这是SVM的代价函数和图像:
下面我们来想一下如何让代价函数最小化。
若
y
=
1
y=1
y=1,则当
θ
T
x
≥
1
\theta^{T}x≥1
θTx≥1时,
C
o
s
t
1
(
z
)
=
0
Cost_1(z)=0
Cost1(z)=0.
若
y
=
0
y=0
y=0,则当
θ
T
x
≤
−
1
\theta^{T}x≤-1
θTx≤−1时,
C
o
s
t
2
(
z
)
=
0
Cost_2(z)=0
Cost2(z)=0.
下面我们想象一下,如果将常数C设得比较大,例如C=100000,那么当进行最小化时,我们将迫切希望找到一个合适的值,使第一项等于0,那么现在我们试着在这种情况下来理解优化问题。
要使第一项为0,则有以下两种情况:
若
y
=
1
y=1
y=1,则
θ
T
x
≥
1
\theta^{T}x≥1
θTx≥1,即
y
=
1
y=1
y=1的样本点在超平面
H
1
:
θ
T
x
≥
1
H_1:\theta^{T}x≥1
H1:θTx≥1上。
若
y
=
0
y=0
y=0,则
θ
T
x
≤
−
1
\theta^{T}x≤-1
θTx≤−1,即
y
=
0
y=0
y=0的样本点在超平面
H
2
:
θ
T
x
≤
−
1
H_2:\theta^{T}x≤-1
H2:θTx≤−1上。
如下图所示,在
H
1
、
H
2
H_1、H_2
H1、H2上的点就是支持向量:
这里两个超平面
H
1
、
H
2
H_1、H_2
H1、H2平行,它们中间没有样本点。
H
1
、
H
2
H_1、H_2
H1、H2之间的距离成为间隔(margin)。
间隔依赖于分离超平面的法向量
θ
\theta
θ,等于
2
∣
∣
θ
∣
∣
\frac{2}{||\theta||}
∣∣θ∣∣2。
H
1
、
H
2
H_1、H_2
H1、H2是间隔边界。
核函数(kernel)
简单介绍
如下图,我们需要得到一个非线性的决策边界:
按我们之前学的方法,可以通过增加项数来进行拟合,如下:
现在我们用一些新的符号
f
1
,
f
2
,
f
3
.
.
.
f_1,f_2,f_3…
f1,f2,f3…来表示新的特征值:
θ
0
θ
1
f
1
θ
2
f
2
θ
3
f
3
θ
4
f
4
θ
5
f
5
.
.
.
≥
0
\theta_0+\theta_1f_1+\theta_2f_2+\theta_3f_3+\theta_4f_4+\theta_5f_5+…≥0
θ0+θ1f1+θ2f2+θ3f3+θ4f4+θ5f5+…≥0
f
1
=
x
1
,
f
2
=
x
2
,
f
3
=
x
1
x
2
,
f
4
=
x
1
2
.
.
.
f_1=x_1,f_2=x_2,f_3=x_1x_2,f_4=x_1^2…
f1=x1,f2=x2,f3=x1x2,f4=x12…
现在我们用
f
1
,
f
2
,
f
3
f_1,f_2,f_3
f1,f2,f3来举例:
如图,我们在图上选择三个标记
l
(
1
)
,
l
(
2
)
,
l
(
3
)
l{(1)},l{(2)},l^{(3)}
l(1),l(2),l(3)
然后来定义新的特征:
给定一个实例x,然后将
f
1
f_1
f1定义为度量实例
x
x
x与标记点
l
(
1
)
l^{(1)}
l(1)的相似度
f
1
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
1
)
)
=
e
x
p
(
−
∣
∣
x
−
l
(
1
)
∣
∣
2
2
σ
2
)
f_1=similarity(x,l{(1)})=exp(-\frac{{||x-l{(1)}||}2}{2\sigma2})
f1=similarity(x,l(1))=exp(−2σ2∣∣x−l(1)∣∣2)
类似地,
f
2
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
2
)
)
=
e
x
p
(
−
∣
∣
x
−
l
(
2
)
∣
∣
2
2
σ
2
)
f_2=similarity(x,l{(2)})=exp(-\frac{{||x-l{(2)}||}2}{2\sigma2})
f2=similarity(x,l(2))=exp(−2σ2∣∣x−l(2)∣∣2)
f
3
=
s
i
m
i
l
a
r
i
t
y
(
x
,
l
(
3
)
)
=
e
x
p
(
−
∣
∣
x
−
l
(
3
)
∣
∣
2
2
σ
2
)
f_3=similarity(x,l{(3)})=exp(-\frac{{||x-l{(3)}||}2}{2\sigma2})
f3=similarity(x,l(3))=exp(−2σ2∣∣x−l(3)∣∣2)
这种函数我们称为高斯核函数,后面我们还会学到其他的核函数。
下面来看看这些核函数的表达式有什么含义。
假设现在有一点非常接近与标记点
l
(
1
)
l^{(1)}
l(1),那么欧氏距离
∣
∣
x
−
l
(
1
)
∣
∣
2
{||x-l{(1)}||}2
∣∣x−l(1)∣∣2就会接近于0,此时
f
1
≈
e
x
p
(
0
)
=
1
f_1≈exp(0)=1
f1≈exp(0)=1。
相反,如果这点离
l
(
1
)
l^{(1)}
l(1)很远,欧式距离
∣
∣
x
−
l
(
1
)
∣
∣
2
{||x-l{(1)}||}2
∣∣x−l(1)∣∣2会变得很大,此时
f
1
≈
0
f_1≈0
f1≈0。
讲完了特征值的定义,接下来我们看看核函数是如何应用于决策边界的。
给定一个训练样本,当
θ
0
θ
1
f
1
θ
2
f
2
θ
3
f
3
≥
0
\theta_0+\theta_1f_1+\theta_2f_2+\theta_3f_3≥0
θ0+θ1f1+θ2f2+θ3f3≥0时,预测
y
=
1
y=1
y=1。
假设我们已经得到了参数
θ
\theta
θ的值:
θ
0
=
−
0.5
,
θ
1
=
1
,
θ
2
=
1
,
θ
3
=
0
\theta_0=-0.5,\theta_1=1,\theta_2=1,\theta_3=0
θ0=−0.5,θ1=1,θ2=1,θ3=0
现在我们有一个实例
x
x
x(蓝点),落在如图所示位置,显然,该实例与标记点
l
(
1
)
l^{(1)}
l(1)间距离很近,故
f
1
=
1
f_1=1
f1=1,与标记点
l
(
2
)
,
l
(
3
)
l{(2)},l{(3)}
l(2),l(3)相距较远,故
f
2
,
f
3
=
0
f_2,f_3=0
f2,f3=0,然后我们代入
θ
0
θ
1
f
1
θ
2
f
2
θ
3
f
3
\theta_0+\theta_1f_1+\theta_2f_2+\theta_3f_3
θ0+θ1f1+θ2f2+θ3f3得
θ
0
θ
1
=
0.5
>
0
\theta_0+\theta_1=0.5>0
θ0+θ1=0.5>0,所以预测
y
=
1
y=1
y=1。
若一个实例如绿点所示,与
l
(
1
)
,
l
(
2
)
,
l
(
3
)
l{(1)},l{(2)},l^{(3)}
l(1),l(2),l(3)的距离都很远,此时
f
1
,
f
2
,
f
3
=
0
f_1,f_2,f_3=0
f1,f2,f3=0
代入
θ
0
θ
1
f
1
θ
2
f
2
θ
3
f
3
\theta_0+\theta_1f_1+\theta_2f_2+\theta_3f_3
θ0+θ1f1+θ2f2+θ3f3得
θ
0
=
−
0.5
<
0
\theta_0=-0.5<0
θ0=−0.5<0,所以预测
y
=
0
y= 0
y=0。
如此,便会得到一个可以区分正负样本的非线性的决策边界。
那么现在大家可能会想如何去得到我们的标记点
l
(
1
)
,
l
(
2
)
,
l
(
3
)
l{(1)},l{(2)},l^{(3)}
l(1),l(2),l(3),并且在一些复杂的分类问题中,也许我们需要更多的标记点。
一般情况下,我们会直接选择训练样本作为标记点。
如下给定
m
m
m个训练样本,然后选定与
m
m
m个训练样本完全一样的位置作为标记点。
转化为向量:
f
=
[
f
0
f
1
f
2
f
3
.
.
.
]
∈
R
m
1
f=\left[ \begin{matrix} f_0 \ f_1 \ f_2 \ f_3\… \end{matrix} \right]∈R^{m+1}
f=⎣⎢⎢⎢⎢⎡f0f1f2f3…⎦⎥⎥⎥⎥⎤∈Rm+1
则当
θ
T
f
≥
0
\theta^Tf≥0
θTf≥0时,预测
y
=
1
y= 1
y=1.
最小化函数
参数选择
- 首先我们看看参数
C
C
C,前面我们知道
C
C
C和
1
λ
\frac{1}{\lambda}
λ1作用一样,如果选择了较大的
C
C
C,则意味着选择了较大的
λ
\lambda
λ,则是一个高偏差,低方差的模型(欠拟合)。
如果选择了较小的
C
C
C,则意味着选择了较小的
λ
\lambda
λ,则是一个高方差,低偏差的模型(过拟合)。
- 还有一个参数
σ
2
\sigma^2
σ2,如果
σ
2
\sigma^2
σ2比较大,则高斯核函数
e
x
p
(
−
∣
∣
x
−
l
(
i
)
∣
∣
2
2
σ
2
)
exp(-\frac{{||x-l{(i)}||}2}{2\sigma^2})
exp(−2σ2∣∣x−l(i)∣∣2)相对平滑,模型高偏差低方差。反之则相对陡峭,模型低偏差高方差。
例题
在本次代码练习中,我们先从基础的线性分类出发,再到非线性分类来熟悉SVM的工作原理,最后再构建区分垃圾邮件的分类器。
import numpy as np
import pandas as pd
import seaborn as sb
import matplotlib.pyplot as plt
import scipy.io as sio
线性SVM
df = sio.loadmat('E:\\happy\\ML&DL\\My\_exercise\\ex5-SVM\\data\\ex6data1.mat')
data = pd.DataFrame(df['X'], columns=['X1', 'X2'])
data['y'] = df['y']
data.head()
fig = plt.subplots(figsize=(8,6))
plt.scatter(data['X1'], data['X2'], s=50, c=data['y'], cmap='Spectral')
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
from sklearn import svm
C=1
#C=1
svc_1 = svm.LinearSVC(C=1, loss='hinge', max_iter=10000)
svc_1.fit(data[['X1', 'X2']], data['y'])
svc_1.score(data[['X1', 'X2']], data['y'])
0.9803921568627451
#C=1时,画图看看每个类别预测的置信度
data['SVM1 Confidence'] = svc_1.decision_function(data[['X1', 'X2']])
data.head()
fig = plt.subplots(figsize=(8,6))
plt.scatter(data['X1'], data['X2'], s=50, c=data['SVM1 Confidence'], cmap='RdBu')
plt.title('SVM (C=1) Decision Confidence')
plt.show()
C=100
#C=100时,画图看看每个类别预测的置信度
data['SVM100 Confidence'] = svc_100.decision_function(data[['X1', 'X2']])
fig = plt.subplots(figsize=(8,6))
plt.scatter(data['X1'], data['X2'], s=50, c=data['SVM100 Confidence'], cmap='RdBu')
plt.title('SVM (C=100) Decision Confidence')
plt.show()
非线性SVM
#高斯核函数
def gaussian\_kernel(x1, x2, sigma):
return np.exp(-np.power(x1 - x2, 2).sum() / (2 \* (sigma \*\* 2)))
#测试一下
x1 = np.array([1, 2, 3])
x2 = np.array([2, 0, 1])
sigma = 2
gaussian_kernel(x1, x2, sigma)
0.32465246735834974
df = sio.loadmat('E:\\happy\\ML&DL\\My\_exercise\\ex5-SVM\\data\\ex6data2.mat')
data = pd.DataFrame(df['X'], columns=['X1', 'X2'])
data['y'] = df['y']
data
fig = plt.subplots(figsize=(8,6))
plt.scatter(data['X1'], data['X2'], s=30, c=data['y'], cmap='Spectral')
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
#用内置的高斯核函数求解
svc = svm.SVC(C=100, gamma=10, probability=True)
svc.fit(data[['X1', 'X2']], data['y'])
svc.score(data[['X1', 'X2']], data['y'])
0.9698725376593279
#选一类按照概率画出来
prob = svc.predict_proba(data[['X1', 'X2']])[:, 0]
fig = plt.subplots(figsize=(8,6))
plt.scatter(data['X1'], data['X2'], s=30, c=prob, cmap='Reds')
网络搜索寻找最优参数
#读取训练集和验证集
df = sio.loadmat('E:\\happy\\ML&DL\\My\_exercise\\ex5-SVM\\data\\ex6data3.mat')
df.keys()
gamma =
1
2
σ
2
\frac{1}{2\sigma^2}
2σ21
X = df['X']
Xval = df['Xval']
y = df['y']
yval = df['yval']
candidate = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
gamma_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
best_score = 0
best_params = {'C': None, 'gamma': None}
for C in candidate:
for gamma in gamma_values:
svc = svm.SVC(C=C, gamma=gamma)
svc.fit(X, y)
score = svc.score(Xval, yval)
if score > best_score:
best_score = score
best_params['C'] = C
best_params['gamma'] = gamma
best_score, best_params
(0.965, {'C': 0.3, 'gamma': 100})
实现垃圾邮件过滤器
train = sio.loadmat('E:\\happy\\ML&DL\\My\_exercise\\ex5-SVM\\data\\spamTrain.mat')
test = sio.loadmat('E:\\happy\\ML&DL\\My\_exercise\\ex5-SVM\\data\\spamTest.mat')
train.keys(),test.keys()
#X是一个二进制向量,1表示邮件中存在该单词,0表示不存在
X = train['X']
y = train['y'].ravel()
Xtest = test['Xtest']
ytest = test['ytest'].ravel()
svc = svm.SVC()
svc.fit(X, y)
svc.score(Xtest, ytest)
0.987
例题数据和jupyter获取
关注公众号“大拨鼠Code”,回复“机器学习”可领取上面例题的源文件,jupyter版本的,例题和数据也一起打包了,之前的练习也在里面,感谢支持。
参考资料:
[1] https://www.bilibili.com/video/BV164411b7dx
[2] https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes
最后
经过日积月累, 以下是小编归纳整理的深入了解Java虚拟机文档,希望可以帮助大家过关斩将顺利通过面试。
由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:xhs1999xhs (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
VM100 Confidence’] = svc_100.decision_function(data[[‘X1’, ‘X2’]])
fig = plt.subplots(figsize=(8,6))
plt.scatter(data[‘X1’], data[‘X2’], s=50, c=data[‘SVM100 Confidence’], cmap=‘RdBu’)
plt.title(‘SVM (C=100) Decision Confidence’)
plt.show()
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b17ccd972ed6f36be9d2f4e77c938c58.png)
#### 非线性SVM
#高斯核函数
def gaussian_kernel(x1, x2, sigma):
return np.exp(-np.power(x1 - x2, 2).sum() / (2 * (sigma ** 2)))
#测试一下
x1 = np.array([1, 2, 3])
x2 = np.array([2, 0, 1])
sigma = 2
gaussian_kernel(x1, x2, sigma)
0.32465246735834974
df = sio.loadmat(‘E:\happy\ML&DL\My_exercise\ex5-SVM\data\ex6data2.mat’)
data = pd.DataFrame(df[‘X’], columns=[‘X1’, ‘X2’])
data[‘y’] = df[‘y’]
data
fig = plt.subplots(figsize=(8,6))
plt.scatter(data[‘X1’], data[‘X2’], s=30, c=data[‘y’], cmap=‘Spectral’)
plt.xlabel(‘X1’)
plt.ylabel(‘X2’)
plt.show()
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/65eeef6d20820dc879da5441dec5847d.png)
#用内置的高斯核函数求解
svc = svm.SVC(C=100, gamma=10, probability=True)
svc.fit(data[[‘X1’, ‘X2’]], data[‘y’])
svc.score(data[[‘X1’, ‘X2’]], data[‘y’])
0.9698725376593279
#选一类按照概率画出来
prob = svc.predict_proba(data[[‘X1’, ‘X2’]])[:, 0]
fig = plt.subplots(figsize=(8,6))
plt.scatter(data[‘X1’], data[‘X2’], s=30, c=prob, cmap=‘Reds’)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2228082f1b287acb7c2423064c2ed61a.png)
#### 网络搜索寻找最优参数
#读取训练集和验证集
df = sio.loadmat(‘E:\happy\ML&DL\My_exercise\ex5-SVM\data\ex6data3.mat’)
df.keys()
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a09562b5ed5cc040f03507fd4f06190e.png)
gamma =
1
2
σ
2
\frac{1}{2\sigma^2}
2σ21
X = df[‘X’]
Xval = df[‘Xval’]
y = df[‘y’]
yval = df[‘yval’]
candidate = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
gamma_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
best_score = 0
best_params = {‘C’: None, ‘gamma’: None}
for C in candidate:
for gamma in gamma_values:
svc = svm.SVC(C=C, gamma=gamma)
svc.fit(X, y)
score = svc.score(Xval, yval)
if score > best_score:
best_score = score
best_params['C'] = C
best_params['gamma'] = gamma
best_score, best_params
(0.965, {‘C’: 0.3, ‘gamma’: 100})
#### 实现垃圾邮件过滤器
train = sio.loadmat(‘E:\happy\ML&DL\My_exercise\ex5-SVM\data\spamTrain.mat’)
test = sio.loadmat(‘E:\happy\ML&DL\My_exercise\ex5-SVM\data\spamTest.mat’)
train.keys(),test.keys()
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e1394690e827545aeec84463365f856f.png)
#X是一个二进制向量,1表示邮件中存在该单词,0表示不存在
X = train[‘X’]
y = train[‘y’].ravel()
Xtest = test[‘Xtest’]
ytest = test[‘ytest’].ravel()
svc = svm.SVC()
svc.fit(X, y)
svc.score(Xtest, ytest)
0.987
### 例题数据和jupyter获取
关注公众号“**大拨鼠Code**”,回复“**机器学习**”可领取上面例题的源文件,jupyter版本的,例题和数据也一起打包了,之前的练习也在里面,感谢支持。
参考资料:
[1] https://www.bilibili.com/video/BV164411b7dx
[2] https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes
### 最后
**经过日积月累, 以下是小编归纳整理的深入了解Java虚拟机文档,希望可以帮助大家过关斩将顺利通过面试。**
由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。
[外链图片转存中...(img-vDgwfuU4-1713688539647)]
[外链图片转存中...(img-3HRcvId7-1713688539648)]
[外链图片转存中...(img-SYqG5ArD-1713688539648)]
[外链图片转存中...(img-DIFzBrSw-1713688539648)]
[外链图片转存中...(img-VYalfCYX-1713688539649)]
[外链图片转存中...(img-vpubrRfa-1713688539649)]
[外链图片转存中...(img-25qA6F6c-1713688539649)]
**由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:xhs1999xhs (备注Java)**
[外链图片转存中...(img-imQuUG28-1713688539650)]
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**