package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class Enemy implements Runnable{
//坐标
private int x;
private int y;
//初始坐标
private int startx;
private int starty;
//怪物类型
private int type;
//显示图片
private BufferedImage showImage;
//移动方向
private boolean isLeftOrUp = true;
//移动范围
private int upMax = 0;
private int downMax = 0;
//加入线程
private Thread t = null;
//定义图片变化
private int imageType = 0;
//定义所在场景
private BackGround bg ;
//存活状态
private boolean alive = false;
//蘑菇怪
public Enemy(int x,int y,boolean isLeft,int type,BackGround bg){
this.x = x;
this.y = y;
this.startx = x;
this.starty = y;
this.isLeftOrUp = isLeft;
this.type = type;
this.bg = bg;
if(type==1){
this.showImage = StaticValue.allTriangleImage.get(0);
}
this.t = new Thread(this);
t.start();
}
//食人花
public Enemy(int x,int y,boolean isUp,int type,int upMax,int downMax,BackGround bg){
this.x = x;
this.y = y;
this.startx = x;
this.starty = y;
this.isLeftOrUp = isUp;
this.type = type;
this.upMax = upMax;
this.downMax = downMax;
this.bg = bg;
if(type==2){
this.showImage = StaticValue.allFlowerImage.get(0);
}
this.t = new Thread(this);
t.start();
}
//绘制
public void draw(Graphics g){
g.drawImage(showImage,x,y,null);
}
//现场的run方法
public void run() {
while (true) {
if(alive){
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public BufferedImage getShowImage() {
return showImage;
}
public void setBg(BackGround bg) {
this.bg = bg;
}
public int getType() {
return type;
}
public void startMove(){
alive = true;
}
}
场景中初始化敌人,修改buildBackGround1 方法,加入以下代码。
//绘制怪物
this.allEnemy.add(new Enemy(600, 480, true, 1,this));
//绘制食人花
this.allEnemy.add(new Enemy(690, 540, true, 2, 420, 540,this));
在GamePanel类中创建方法,并在paint中调用,绘制出敌人。
//绘制敌人
private void drawEnemy(Graphics g){
//绘制怪物敌人
Iterator iterEnemy = this.nowBG.getAllEnemy().iterator();
while(iterEnemy.hasNext()){
Enemy e = iterEnemy.next();
e.draw(g);
}
}
运行
让敌人运动起来
一、蘑菇怪运动
-
先向左运动,让其X坐标递减就行,到最左边后反过来向右运动,坐标依次递增,碰到障碍物反过来继续。
-
每次线程执行的时候,要切换图片哦。
修改Enemy类的run方法(同时把alive先默认设置为true,测试用)
if(alive){
//判断怪物类型
if (type == 1) {
//左右移动
if (this.isLeftOrUp) {
this.x -= 5;
} else {
this.x += 5;
}
//imageType的切换来达到图片的切换
if (imageType == 0) {
imageType = 1;
} else {
imageType = 0;
}
//定义标记
boolean canLeft = true;
boolean canRight = true;
for (int i = 0; i < this.bg.getAllObstruction().size(); i++) {
Obstruction ob = this.bg.getAllObstruction().get(i);
//不能向右移动
if (ob.getX() == this.x + 60 && (ob.getY() + 50 > this.y
&& ob.getY() - 50 < this.y)) {
canRight = false;
}
//不能向左移动
if (ob.getX() == this.x - 60 && (ob.getY() + 50 > this.y
&& ob.getY() - 50 < this.y)) {
canLeft = false;
}
}
if (!canLeft && this.isLeftOrUp || this.x == 0) {
this.isLeftOrUp = false;
} else if (!canRight && !this.isLeftOrUp || this.x == 840) {
this.isLeftOrUp = true;
}
this.showImage = StaticValue.allTriangleImage.get(imageType);
}
}
在GamePanel加入主线程代码。
private class RefreshThread implements Runnable {
@Override
public void run() {
while (true) {
if (!“end”.equals(gameFlag)) {
repaint();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
构造函数里面调用此线程
运行效果:
二、食人花运动
-
向上运动在递减y坐标,向下运动递增y坐标。
-
每次切换图片
-
达到最高处,则反过来往下;达到最低处,反过来往上;
在Enemy类中的run方法加入以下代码:
if (type == 2) {
if (this.isLeftOrUp) {//向上运动
this.y -= 5;
} else {//向下运动
this.y += 5;
}
//imageType的切换来达到图片的切换
if (imageType == 0) {
imageType = 1;
} else {
imageType = 0;
}
//达到最高处,则反过来往下
if (this.isLeftOrUp && this.y == this.upMax) {
this.isLeftOrUp = false;
}
//达到最低处,则反过来往上
if (!this.isLeftOrUp && this.y == this.downMax) {
this.isLeftOrUp = true;
}
this.showImage = StaticValue.allFlowerImage.get(imageType);
}
加入马里奥
创建类
package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class Mario implements Runnable {
//坐标
private int x;
private int y;
//定义玛丽奥所在场景
private BackGround bg;
//加入线程
private Thread t = null;
//移动速度e
private int xmove = 0;
//跳跃速度
private int ymove = 0;
private int speed = 5;
//状态
private String status;
//显示图片
private BufferedImage showImage;
//生命和分数
private int score;
private int life;
//当前移动中的图片
private int moving = 0;
//跳跃时间
private int upTime = 0;
//标记玛丽奥是否死亡
private boolean isDead = false;
//完成游戏,游戏结束
private boolean isClear = false;
//构造方法
public Mario(int x, int y) {
this.x = x;
this.y = y;
//初始化玛丽奥图片
this.showImage = StaticValue.allMarioImage.get(0);
this.score = 0;
this.life = 3;
this.t = new Thread(this);
t.start();
this.status = “right-standing”;
}
public void draw(Graphics g) {
g.drawImage(showImage, x, y, null);
}
public void run() {
while(true){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void setBg(BackGround bg) {
this.bg = bg;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public boolean isDead() {
return isDead;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public boolean isClear() {
return isClear;
}
public void setClear(boolean isClear) {
this.isClear = isClear;
}
}
修改init方法,加入马里奥的初始化
//初始化
private void init() {
//图片初始化
StaticValue.init();
//创建全部场景
for (int i = 1; i <= 7; i++) {
//i==7?true:false 最后一个场景有点区别,有个结束的城堡
this.allBG.add(new BackGround(i, i == 7 ? true : false));
}
//将第一个场景设置为当前场景
this.nowBG = this.allBG.get(0);
//初始化玛丽奥
this.mario = new Mario(0, 480);
//将玛丽奥放入场景中
this.mario.setBg(nowBG);
}
paint方法中绘制马里奥
运动
移动代码
public void leftMove(){
//移动速度
xmove = -speed;
//改变状态
//如果当前已经是跳跃,应该保持原有状态,不能再改变
if(this.status.indexOf(“jumping”) != -1){
this.status = “left-jumping”;
}else{
this.status = “left-moving”;
}
}
public void rightMove(){
xmove = speed;
if(this.status.indexOf(“jumping”) != -1){
this.status = “right-jumping”;
}else{
this.status = “right-moving”;
}
}
public void leftStop(){
this.xmove = 0;
if(this.status.indexOf(“jumping”) != -1){
this.status = “left-jumping”;
}else{
this.status = “left-standing”;
}
}
public void rightStop(){
this.xmove = 0;
if(this.status.indexOf(“jumping”) != -1){
this.status = “right-jumping”;
}else{
this.status = “right-standing”;
}
}
跳跃和死亡方法
public void jump(){
if(this.status.indexOf(“jumping”) == -1){
if(this.status.indexOf(“left”) != -1){
this.status = “left-jumping”;
}else{
this.status = “right-jumping”;
}
ymove = -10;
upTime = 18;
}
}
//下落方法
public void down(){
if(this.status.indexOf(“left”) != -1){
this.status = “left-jumping”;
}else{
this.status = “right-jumping”;
}
ymove = 10;
}
//死亡方法
public void dead(){
this.life–;
if(this.life == 0){
this.isDead = true;
}else{
if(!isDead){
}
this.x = 0;
this.y = 480;
}
}
加入键盘事件
在GamePanel中加入键盘事件,并在构造方法在调用。
//添加键盘监听
private void createKeyListener() {
KeyAdapter l = new KeyAdapter() {
//按下
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(“start”.equals(gameFlag)){
switch (key) {
//向上
case KeyEvent.VK_UP:
case KeyEvent.VK_W:
mario.jump();
break;
//向右
case KeyEvent.VK_RIGHT:
case KeyEvent.VK_D:
mario.rightMove();
break;
//向左
case KeyEvent.VK_LEFT:
case KeyEvent.VK_A:
mario.leftMove();
break;
//空格
case KeyEvent.VK_SPACE:
//起跳
mario.jump();
break;
}
}else if(“load”.equals(gameFlag)||“end”.equals(gameFlag)){
//游戏开始
//gameStart();
}
}
//松开
@Override
public void keyReleased(KeyEvent e) {
if(“start”.equals(gameFlag)){
int key = e.getKeyCode();
//控制玛丽奥的停止
if(keyKeyEvent.VK_RIGHT||keyKeyEvent.VK_D){
mario.rightStop();
}
if(keyKeyEvent.VK_LEFT||keyKeyEvent.VK_A){
mario.leftStop();
}
}
}
};
//给主frame添加键盘监听
mainFrame.addKeyListener(l);
}
修改马里奥类的run方法
public void run() {
while(true){
//判断是否与障碍物碰撞
//定义标记
if(this.bg.isFlag() && this.x >= 520){
if(!this.bg.isOver()){
}
this.bg.setOver(true);
if(this.bg.isDown()){
//降旗后玛丽奥开始移
this.status = “right-moving”;
if(this.x < 580){
//向右
this.x += 5;
}else{
if(this.y < 480){
//向下
this.y += 5;
}
this.x += 5;
if(this.x >= 780){
//游戏结束
this.setClear(true);
}
}
}else{
//如果为最后一个场景,同事Mario的x坐标到了550,游戏结束
//自动控制玛丽奥
if(this.y < 420){
this.y += 5;
}
if(this.y >= 420){
this.y = 420;
this.status = “right-standing”;
}
}
}else{
boolean canLeft = true;
boolean canRight = true;
//能否跳跃标记
boolean onLand = false;
for(int i=0;i<this.bg.getAllObstruction().size();i++){
Obstruction ob = this.bg.getAllObstruction().get(i);
if(this.status.indexOf(“jumping”) != -1){//在空中
//不能向右移动
if((ob.getX()<=this.x+60 && this.x <ob.getX() )&& (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canRight = false;
}
}
//不能向左移动
if((ob.getX()>=this.x-60 && this.x >ob.getX())&& (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canLeft = false;
}
}
}else{
//不能向右移动
if(ob.getX()==this.x+60 && (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canRight = false;
}
}
//不能向左移动
if(ob.getX()==this.x-60 && (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canLeft = false;
}
}
}
//判断能否跳跃
if(ob.getY()==this.y+60 && (ob.getX()+60>this.x && ob.getX()-60<this.x)){
if(ob.getType() != 3){
onLand = true;
}
}
//判断玛丽奥跳跃时是否撞到障碍物
if(ob.getY()==this.y-60 && (ob.getX()+50>this.x && ob.getX()-50<this.x)){
//如果是砖块
if(ob.getType()==0){
//移除砖块
this.bg.getAllObstruction().remove(ob);
//保存到移除的障碍物中
this.bg.getRemoveObstruction().add(ob);
}
//如果是问号||隐藏的砖块
if((ob.getType()==4 || ob.getType()==3) && upTime > 0){
//增加分数
score += 10;
ob.setType(2);
ob.setImage();
}
upTime = 0;
}
}
//对敌人的判断
for(int i=0;i<this.bg.getAllEnemy().size();i++){
Enemy e = this.bg.getAllEnemy().get(i);
if((e.getX()+50>this.x && e.getX()-50<this.x) && (e.getY()+60>this.y && e.getY()-60<this.y)){
//玛丽奥死亡
this.dead();
canLeft=false;
canRight=false;
}
if(e.getY()==this.y+60 && (e.getX()+60>this.x && e.getX()-60<this.x)){
if(e.getType() == 1){
//e.dead();
this.upTime = 5;
this.ymove = -10;
//敌人死亡,增加分数
score += 10;
}else if(e.getType() == 2){
this.dead();
canLeft=false;
canRight=false;
}
}
}
if(onLand && upTime == 0){
if(this.status.indexOf(“left”) != -1){
if(xmove != 0){
this.status = “left-moving”;
}else{
this.status = “left-standing”;
}
}else{
if(xmove != 0){
this.status = “right-moving”;
}else{
this.status = “right-standing”;
}
}
}else{
//上升状态
if(upTime != 0){
upTime–;
}else{
this.down();
}
y += ymove;
}
if(this.y>600){
this.dead();
canLeft=false;
canRight=false;
}
if(canLeft && xmove<0 || canRight && xmove>0){
x += xmove;
if(x<0){
x = 0;
}
}
}
//默认向右
int temp = 0;
//向左状态
if(this.status.indexOf(“left”) != -1){
temp += 5;
}
//判断是否移动
if(this.status.indexOf(“moving”) != -1){
temp += this.moving;
moving++;
if(moving==4){
this.moving = 0;
}
}
if(this.status.indexOf(“jumping”) != -1){
temp += 4;
}
//改变显示图片
this.showImage = StaticValue.allMarioImage.get(temp);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
加入其他场景的代码
//第2个场景
void buildBackGround2(){
for(int i=0;i<15;i++){
if(i != 9 && i != 10 && i != 11 ){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
}
//绘制水管
this.allObstruction.add(new Obstruction(60, 540, 6,this));
this.allObstruction.add(new Obstruction(120, 540, 5,this));
this.allObstruction.add(new Obstruction(60, 480, 6,this));
this.allObstruction.add(new Obstruction(120, 480, 5,this));
this.allObstruction.add(new Obstruction(60, 420, 8,this));
this.allObstruction.add(new Obstruction(120, 420, 7,this));
this.allObstruction.add(new Obstruction(300, 540, 6,this));
this.allObstruction.add(new Obstruction(360, 540, 5,this));
this.allObstruction.add(new Obstruction(300, 480, 6,this));
this.allObstruction.add(new Obstruction(360, 480, 5,this));
this.allObstruction.add(new Obstruction(300, 420, 6,this));
this.allObstruction.add(new Obstruction(360, 420, 5,this));
this.allObstruction.add(new Obstruction(300, 360, 8,this));
this.allObstruction.add(new Obstruction(360, 360, 7,this));
//绘制怪物
this.allEnemy.add(new Enemy(330, 360, true, 2, 300, 420,this));
}
//第3个场景
void buildBackGround3(){
for(int i=0;i<15;i++){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
//绘制砖块和问号
this.allObstruction.add(new Obstruction(180, 360, 4,this));
this.allObstruction.add(new Obstruction(420, 360, 4,this));
this.allObstruction.add(new Obstruction(660, 360, 4,this));
this.allObstruction.add(new Obstruction(420, 180, 4,this));
}
//第4个场景
void buildBackGround4(){
for(int i=0;i<15;i++){
if(i<2||i>12){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
}
this.allObstruction.add(new Obstruction(120, 360, 0,this));
this.allObstruction.add(new Obstruction(180, 360, 0,this));
this.allObstruction.add(new Obstruction(300, 180, 0,this));
this.allObstruction.add(new Obstruction(360, 180, 0,this));
this.allObstruction.add(new Obstruction(420, 180, 0,this));
this.allObstruction.add(new Obstruction(480, 180, 0,this));
this.allObstruction.add(new Obstruction(540, 180, 0,this));
this.allObstruction.add(new Obstruction(660, 360, 0,this));
this.allObstruction.add(new Obstruction(720, 360, 0,this));
}
//第5个场景
void buildBackGround5(){
int z = 2;
for(int i=0;i<15;i++){
if(i%2==0 && i<7){
this.allObstruction.add(new Obstruction(i60, 540-(i60), 9,this));
for(int x=i;x>0;x–){
this.allObstruction.add(new Obstruction(i60, 540-(x60)+60, 10,this));
}
}
if(i%2==0 && i>7){
this.allObstruction.add(new Obstruction(i*60, 540-((i-z)*60), 9,this));
for(int x=i-z;x>0;x–){
this.allObstruction.add(new Obstruction(i60, 540-(x60)+60, 10,this));
}
z+=4;
}
}
}
//第6个场景
void buildBackGround6(){
for(int i=0;i<15;i++){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
this.allObstruction.add(new Obstruction(480, 480, 1,this));
this.allObstruction.add(new Obstruction(480, 420, 1,this));
this.allObstruction.add(new Obstruction(480, 360, 1,this));
this.allObstruction.add(new Obstruction(480, 300, 1,this));
this.allObstruction.add(new Obstruction(480, 240, 1,this));
this.allObstruction.add(new Obstruction(480, 180, 1,this));
this.allObstruction.add(new Obstruction(540, 240, 1,this));
this.allObstruction.add(new Obstruction(540, 300, 1,this));
this.allObstruction.add(new Obstruction(540, 360, 1,this));
this.allObstruction.add(new Obstruction(540, 420, 1,this));
this.allObstruction.add(new Obstruction(540, 480, 1,this));
this.allObstruction.add(new Obstruction(600, 300, 1,this));
this.allObstruction.add(new Obstruction(600, 360, 1,this));
this.allObstruction.add(new Obstruction(600, 420, 1,this));
this.allObstruction.add(new Obstruction(600, 480, 1,this));
this.allObstruction.add(new Obstruction(660, 360, 1,this));
this.allObstruction.add(new Obstruction(660, 420, 1,this));
this.allObstruction.add(new Obstruction(660, 480, 1,this));
this.allObstruction.add(new Obstruction(720, 420, 1,this));
this.allObstruction.add(new Obstruction(720, 480, 1,this));
this.allObstruction.add(new Obstruction(780, 480, 1,this));
//通关要点,隐形砖块
this.allObstruction.add(new Obstruction(300, 360, 3,this));
}
//第7个场景
void buildBackGround7(){
for(int i=0;i<15;i++){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
this.allObstruction.add(new Obstruction(490, 180, 11,this));
this.allObstruction.add(new Obstruction(520, 480, 2,this));
//地上障碍物
this.allObstruction.add(new Obstruction(240, 360, 1,this));
this.allObstruction.add(new Obstruction(240, 420, 1,this));
this.allObstruction.add(new Obstruction(240, 480, 1,this));
this.allObstruction.add(new Obstruction(180, 420, 1,this));
this.allObstruction.add(new Obstruction(180, 480, 1,this));
this.allObstruction.add(new Obstruction(120, 480, 1,this));
}
加入积分、生命、场景切换、游戏结束、背景音乐等就完成了
看到这里的大佬,动动发财的小手 点赞 + 回复 + 收藏,能【 关注 】一波就更好了。
**代码获取方式:
订阅我的专栏《Java游戏大全》后,可以查看专栏内所有的文章,并且联系博主免费获取其中1-3份你心仪的源代码,专栏的文章都是上过csdn热榜的,值得信赖!专栏内目前有[ 13 + 1 ] 篇实例,未来2个月内专栏会更新到15篇以上,一般2周一更,了解一下我的专栏。**
===================================================================
【1】Java小游戏(俄罗斯方块、飞机大战、植物大战僵尸等)
【2】JavaWeb项目实战(图书管理、在线考试、宿舍管理等)
【3】JavaScript精彩实例(飞机大战、贪吃蛇、验证码等)
总结
一般像这样的大企业都有好几轮面试,所以自己一定要花点时间去收集整理一下公司的背景,公司的企业文化,俗话说「知己知彼百战不殆」,不要盲目的去面试,还有很多人关心怎么去跟HR谈薪资。
这边给大家一个建议,如果你的理想薪资是30K,你完全可以跟HR谈33~35K,而不是一下子就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。
最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!
Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。
还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
);
}
this.allObstruction.add(new Obstruction(490, 180, 11,this));
this.allObstruction.add(new Obstruction(520, 480, 2,this));
//地上障碍物
this.allObstruction.add(new Obstruction(240, 360, 1,this));
this.allObstruction.add(new Obstruction(240, 420, 1,this));
this.allObstruction.add(new Obstruction(240, 480, 1,this));
this.allObstruction.add(new Obstruction(180, 420, 1,this));
this.allObstruction.add(new Obstruction(180, 480, 1,this));
this.allObstruction.add(new Obstruction(120, 480, 1,this));
}
加入积分、生命、场景切换、游戏结束、背景音乐等就完成了
看到这里的大佬,动动发财的小手 点赞 + 回复 + 收藏,能【 关注 】一波就更好了。
**代码获取方式:
订阅我的专栏《Java游戏大全》后,可以查看专栏内所有的文章,并且联系博主免费获取其中1-3份你心仪的源代码,专栏的文章都是上过csdn热榜的,值得信赖!专栏内目前有[ 13 + 1 ] 篇实例,未来2个月内专栏会更新到15篇以上,一般2周一更,了解一下我的专栏。**
===================================================================
【1】Java小游戏(俄罗斯方块、飞机大战、植物大战僵尸等)
【2】JavaWeb项目实战(图书管理、在线考试、宿舍管理等)
【3】JavaScript精彩实例(飞机大战、贪吃蛇、验证码等)
总结
一般像这样的大企业都有好几轮面试,所以自己一定要花点时间去收集整理一下公司的背景,公司的企业文化,俗话说「知己知彼百战不殆」,不要盲目的去面试,还有很多人关心怎么去跟HR谈薪资。
这边给大家一个建议,如果你的理想薪资是30K,你完全可以跟HR谈33~35K,而不是一下子就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。
最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!
Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。
还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
[外链图片转存中…(img-9eKglzzB-1714360399345)]