java小游戏——动漫美女拼图

1:继承

1.1 继承概述

首先,我们来说一下,什么是继承:

  • 继承是面向对象三大特征之一(封装,继承和多态)

  • 可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法

也就是说,通过继承,可以把父类中能够被访问到的成员变量和成员方法拿过来直接使用。

了解了什么是继承后,我们在来说一下,继承是如何实现的。

那继承是如何实现的呢?我们一起来看一下继承的格式:

  • 格式:public class 子类名 extends 父类名 { }

  • 范例:public class Zi extends Fu { }

  • Fu:是父类,也被称为基类、超类

  • Zi:是子类,也被称为派生类

在这里,Zi类和Fu类,通过extends就产生了继承关系。这样呢,Zi类就可以使用Fu类中的成员了。

在这里,Fu这个类,被称为是父类,也被称为基类、超类,Zi这个类:是子类,也被称为派生类

了解了继承是如何实现的,下面呢,我们再来举例说明一下,其实我们在前面已经使用过继承的知识了。

看这里,我们使用过GUI中这样的几个组件:

JLabel,JButton,JTextField,JTextArea

并且还使用过它们的一些方法,比如说:public void setBounds(int x, int y, int width, int height),这几个组件我们都使用过这样的一个方法。

大家想一下,如果我们在每个类中都定义这样的同体系的多个类中都使用的方法,有多个这样的组件,我们就要定义多少个这样的方法。

将来如果有新的组件,我们还是需要定义这样的方法,这样设计起来,我们程序的复用性是不是就太差了啊。

而且,这是Java给我们提供的API,Java大师们肯定不会有这么low的设计,

所以,为了提高代码的复用性,这里就采用了继承的思想,让一个类中定义这样的方法,所有继承该类的类就可以使用这个方法了。

来,打开帮助文档,我们一起去看一下:

其他的几个,大家打开文档自己去看,最终能够找到他们共同的父类:Component

看完文档之后,回来总结一下,继承的好处之一是:提高了代码的复用性

1.2 继承的练习

首先,我们来看一下需求:使用继承的方式,改写用户登录界面展示的案例

知道了,要做什么之后,下面呢,我们到IDEA中一边分析,一边实现:

import javax.swing.*;public class UserLoginFrame extends JFrame {public UserLoginFrame() {//窗体初始化initFrame();//绘制窗体paintView();this.setVisible(true);}public void paintView() {//显示用户名文本JLabel usernameLable = new JLabel("用户名");usernameLable.setBounds(50, 50, 50, 20);this.add(usernameLable);//用户名输入框JTextField usernameField = new JTextField();usernameField.setBounds(150, 50, 180, 20);this.add(usernameField);//显示密码文本JLabel passwordLable = new JLabel("密码");passwordLable.setBounds(50, 100, 50, 20);this.add(passwordLable);//密码输入框JPasswordField passwordField = new JPasswordField();passwordField.setBounds(150, 100, 180, 20);this.add(passwordField);//登录按钮JButton loginButton = new JButton("登录");loginButton.setBounds(50, 200, 280, 20);this.add(loginButton);}public void initFrame() {this.setTitle("用户登录");this.setSize(400, 300);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);this.setAlwaysOnTop(true);this.setLayout(null);}}
public class App {public static void main(String[] args) {UserLoginFrame userLoginFrame = new UserLoginFrame();}
}

用继承改进后,代码看起来清晰多了,所以,如果我们做GUI开发的,在做窗体的时候,就会定义类继承自JFrame来使用。

2:动漫美女拼图

2.1 项目演示

这里我们先来演示一下该项目:

来,打开准备好的Java文件,这里有两个类:

一个是动漫拼图窗体的类,一个是测试类。

右键运行测试类,我们看到了这样的一个界面。

大家可以通过按钮来玩这个游戏了。还可以点击求助按钮和重置按钮。

2.2 动漫美女拼图游戏实现

2.2.1 窗体绘制

分析思路:

1:新建一个模块:itheima-picture-puzzle;在模块的src下新建一个包com.itheima

2:在com.itheima这个包下定义类:PictureFrame,继承自JFrame

3:在PictureFrame类中编写无参构造方法,在构造方法中调用两个方法:

第一个方法:initFrame(),用于窗体的基本设置

第二个方法:setVisible(true),用于设置窗体可见

4:在initFrame()方法中编写代码,进行窗体的基本设置

窗体大小

窗体标题

窗体居中

窗体关闭时退出应用程序

窗体位于其他窗口之上

取消窗体默认布局

5:在com.itheima包下定义测试类:App;创建PictureFrame的对象进行测试

代码实现:

public class PictureFrame extends JFrame {public PictureFrame() {//用于窗体的基本设置initFrame();//设置窗体可见this.setVisible(true);}//用于窗体的基本设置public void initFrame() {//窗体大小this.setSize(960,565);//窗体标题this.setTitle("动漫拼图");//窗体居中this.setLocationRelativeTo(null);//窗体关闭时退出应用程序this.setDefaultCloseOperation(3);//窗体位于其他窗口之上this.setAlwaysOnTop(true);//取消窗体默认布局this.setLayout(null);}
}
public class App {public static void main(String[] args) {PictureFrame pf = new PictureFrame();}
}
2.2.2 窗体上组件绘制

分析思路:

1:定义方法,用于窗体上的组件绘制:paintView()

2:按照如下组件绘制

标题图片

面板图片,存储着将来要移动的图片

参照图

上按钮

左按钮

下按钮

右按钮

求助按钮

重置按钮

3:在构造方法中调用paintView()方法

代码实现:

	//窗体上组件的绘制public void paintView() {//标题图片JLabel titleLabel = new JLabel(new ImageIcon("itheima-picture-puzzle\\images\\title.png"));titleLabel.setBounds(354,27,232,57);this.add(titleLabel);//定义一个二维数组,用来存储图片的编号int[][] datas = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};//创建面板JPanel imagePanel = new JPanel();imagePanel.setBounds(150,114,360,360);imagePanel.setLayout(null);//遍历二维数组,得到图片编号for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//创建JLabel对象,加载图片资源JLabel imageLabel = new JLabel(new ImageIcon("itheima-picture-puzzle\\images\\"+datas[i][j]+".png"));//调整图片的位置imageLabel.setBounds(j*90,i*90,90,90);imagePanel.add(imageLabel);}}//把面板添加到窗体上this.add(imagePanel);//动漫参照图JLabel canZhaoTuLabel = new JLabel(new ImageIcon("itheima-picture-puzzle\\images\\canzhaotu.png"));canZhaoTuLabel.setBounds(574,114,122,121);this.add(canZhaoTuLabel);//上下左右,求助,重置按钮JButton shangButton = new JButton(new ImageIcon("itheima-picture-puzzle\\images\\shang.png"));shangButton.setBounds(732,265,57,57);this.add(shangButton);JButton zuoButton = new JButton(new ImageIcon("itheima-picture-puzzle\\images\\zuo.png"));zuoButton.setBounds(650,347,57,57);this.add(zuoButton);JButton xiaButton = new JButton(new ImageIcon("itheima-picture-puzzle\\images\\xia.png"));xiaButton.setBounds(732,347,57,57);this.add(xiaButton);JButton youButton = new JButton(new ImageIcon("itheima-picture-puzzle\\images\\you.png"));youButton.setBounds(813,347,57,57);this.add(youButton);JButton qiuZhuButton = new JButton(new ImageIcon("itheima-picture-puzzle\\images\\qiuzhu.png"));qiuZhuButton.setBounds(626,444,108,45);this.add(qiuZhuButton);JButton chongZhiButton = new JButton(new ImageIcon("itheima-picture-puzzle\\images\\chongzhi.png"));chongZhiButton.setBounds(786,444,108,45);this.add(chongZhiButton);//展示背景图JLabel backgroundLabel = new JLabel(new ImageIcon("itheima-picture-puzzle\\images\\background.png"));backgroundLabel.setBounds(0,0,960,530);this.add(backgroundLabel);}
//构造方法方法中调用绘图方法public PictureFrame() {//用于窗体的基本设置initFrame();//窗体上组件的绘制paintView();//设置窗体可见this.setVisible(true);}

2.2.3 图片打乱

图片打乱,其实就是二维数组元素打乱。

注意事项:

  • 由于在多个方法中使用同一个数组,故将二维数组的定义放置在成员位置

  • 为了能够进行图片的移动,把16号图片用0号图片替换,当前15个移动到正确位置,显示正确的图片

分析思路:

1:定义方法,用于二维数组元素打乱:initData()

2:创建Random对象

3:遍历存储图片编号的二维数组,得到每一个元素

4:产生两个随机索引,进行二维数组元素交换

	int x = r.nextInt(datas.length);//行索引int y = r.nextInt(datas[x].length);//列索引//元素交换int temp = datas[i][j];datas[i][j] = datas[x][y];datas[x][y] = temp;

5:在构造方法中调用initData()方法

代码实现:

private int[][] datas = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}
};
//二维数组元素打乱
public void randomData() {Random r = new Random();for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {int x = r.nextInt(datas.length);int y = r.nextInt(datas[i].length);int temp = datas[i][j];datas[i][j] = datas[x][y];datas[x][y] = temp;}}
}public PictureFrame() {//用于窗体的基本设置initFrame();//二维数组元素打乱randomData();//窗体上组件的绘制paintView();//设置窗体可见this.setVisible(true);
}

2.2.4 纪录0号图片的索引

为什么要纪录0号图片索引呢?

  • 由于将来要进行图片的移动,以实现动漫拼图的实现

  • 而移动的操作,得有一个空白的区别,这里我们采用0号图片表示,需要纪录0号图片的位置,也就是在数组中的索引

分析思路:

1:在PictureFrame类中定义两个成员变量用于纪录0号图片的索引

private int x0;

private int y0;

2:在initData()方法中继续编写代码,在打乱后的数组中找到0号图片的位置

遍历二维数组,得到每一个元素

如果元素为0,则纪录该元素的索引,并结束循环。

代码实现:

//定义两个int类型的变量,用于纪录0号图片的位置
private int x0;
private int y0;
//二维数组元素打乱
public void randomData() {Random r = new Random();for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {int x = r.nextInt(datas.length);int y = r.nextInt(datas[i].length);int temp = datas[i][j];datas[i][j] = datas[x][y];datas[x][y] = temp;}}//纪录0号图片的位置wc:for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {if(datas[i][j] == 0) {x0 = i;y0 = j;break wc;}}}//System.out.println(x0+","+y0);
}

2.2.5 给按钮注册事件

注意事项:由于在多个方法中使用同一个按钮,故将按钮的定义放置在成员位置

分析思路:

1:定义方法,用于给按钮添加事件:addButtonEvent()

2:在addButtonEvent()方法中给每一个按钮添加事件,并给出输出语句提示

3:在构造方法中调用addButtonEvent()方法

代码实现:

//给按钮添加事件
public void addButtonEvent() {shangButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("上");}});zuoButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("左");}});xiaButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("下");}});youButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("右");}});qiuzhuButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("求助");}});chongzhiButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("重置");}});
}
//无参构造方法
public PictureFrame() {//用于窗体的基本设置initFrame();//二维数组元素打乱randomData();//窗体上组件的绘制paintView();//给按钮添加事件addButtonEvent();//设置窗体可见this.setVisible(true);
}

2.2.6 移动业务实现

移动原理:图片的移动,其实就是做元素的交换,也就是二维数组的元素改变了,然后进行图片重绘就可以了

2.2.6.1 上移业务实现

分析思路:

1:移动规则:竖的是x,横的是y

空白图片,和下方元素(x0+1),进行交换

2:把空白图片和下方图片的位置交换

datasx0 = datasx0 + 1;

datasx0 + 1 = 0;

x0 = x0 + 1;

3:编写重绘方法:rePaintView()

先移除,再重新绘制

4:调用重绘方法

5:边界问题处理:当x0=3,不能进行上移动

代码实现:

shangButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//边界处理if (x0 == 3) {return;}//位置交换datas[x0][y0] = datas[x0 + 1][y0];datas[x0 + 1][y0] = 0;x0 = x0 + 1;//重绘方法调用rePaintView();}
});//移动的图形重新绘制
public void rePaintView() {//移除所有imagePanel.removeAll();//遍历二维数组,得到每一个图片编号for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//在遍历的过程中,创建 JLabel 对象,加载图片资源JLabel imageLabel = new JLabel(new ImageIcon("itheima-picture-puzzle\\images\\" + datas[i][j] + ".png"));//调整图片资源的摆放位置imageLabel.setBounds(j * 90, i * 90, 90, 90);imagePanel.add(imageLabel);}}//重新绘制窗体imagePanel.repaint();
}

2.2.6.2 其他移动业务实现

分析思路:

1:左移动

边界:y0=3

移动代码:

        datas[x0][y0] = datas[x0][y0 + 1];datas[x0][y0 + 1] = 0;y0 = y0 + 1;

2:下移动

边界:x0=0

移动代码:

     datas[x0][y0] = datas[x0 - 1][y0];datas[x0 - 1][y0] = 0;x0 = x0 - 1;

3:右移动

边界:y0=0

移动代码:

        datas[x0][y0] = datas[x0][y0 - 1];datas[x0][y0 - 1] = 0;y0 = y0 - 1;

代码实现:

zuoButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (y0 == 3) {return;}datas[x0][y0] = datas[x0][y0 + 1];datas[x0][y0 + 1] = 0;y0 = y0 + 1;rePaintView();}
});
xiaButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (x0 == 0) {return;}datas[x0][y0] = datas[x0 - 1][y0];datas[x0 - 1][y0] = 0;x0 = x0 - 1;rePaintView();}
});
youButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (y0 == 0) {return;}datas[x0][y0] = datas[x0][y0 - 1];datas[x0][y0 - 1] = 0;y0 = y0 - 1;rePaintView();}
});

2.2.7 求助业务实现

注意事项:

  • 数组元素应该是1-16,而不是0-15了

  • 按钮也不能在点击了

分析思路:

1:定义移动成功的方法:success()

2:在success()方法内部进行如下操作:

修改datas数组的元素为正确的元素值

按钮设置为不可用

3:在重置操作中调用两个方法:

第一个方法:success()

第二个方法:rePaintView()

代码实现:

//移动成功的操作
public void success() {datas = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16}};shangButton.setEnabled(false);zuoButton.setEnabled(false);xiaButton.setEnabled(false);youButton.setEnabled(false);
}
qiuzhuButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {success();rePaintView();}
});

2.2.8 移动业务的问题

问题分析:每次移动之后,都要判断是否移动成功,如果成功了,需要调用成功的方法。

而判断移动是否成功,我们来写方法实现。

分析思路:

1:定义一个方法,用于比较两个数组元素是否相同

2:每次移动完毕,调用该方法:

如果返回值为true,则调用success()方法

代码实现:

//定义移动成功后的数组
private int[][] winDatas = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}
};
//判断移动是否成功
public boolean isSuccess() {for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {if (datas[i][j] != winDatas[i][j]) {return false;}}}return true;
}shangButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//边界处理if (x0 == 3) {return;}//位置交换datas[x0][y0] = datas[x0 + 1][y0];datas[x0 + 1][y0] = 0;x0 = x0 + 1;//判断移动是否成功if(isSuccess()) {success();}//调用重绘的方法rePaintView();}
});
zuoButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//边界处理if (y0 == 3) {return;}//位置交换datas[x0][y0] = datas[x0][y0 + 1];datas[x0][y0 + 1] = 0;y0 = y0 + 1;//判断移动是否成功if(isSuccess()) {success();}//调用重绘的方法rePaintView();}
});
xiaButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//边界处理if (x0 == 0) {return;}//位置交换datas[x0][y0] = datas[x0 - 1][y0];datas[x0 - 1][y0] = 0;x0 = x0 - 1;//判断移动是否成功if(isSuccess()) {success();}//调用重绘的方法rePaintView();}
});
youButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//边界处理if (y0 == 0) {return;}//位置交换datas[x0][y0] = datas[x0][y0 - 1];datas[x0][y0 - 1] = 0;y0 = y0 - 1;//判断移动是否成功if(isSuccess()) {success();}//调用重绘的方法rePaintView();}
});
2.2.9 重置业务实现

分析思路:

1:当重置的时候,需要修改数组为1,2...15,0

2:打乱数组元素

3:重绘面板图

4:设置按钮可用

代码实现:

chongzhiButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {datas = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};initData();rePaintView();shangButton.setEnabled(true);zuoButton.setEnabled(true);xiaButton.setEnabled(true);youButton.setEnabled(true);}
});

讲解完毕后,大家赶快动手练习一下吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/623512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【办公技巧】ppt修改全部字体怎么改?

制作完PPT之后&#xff0c;想要更换ppt中的字体&#xff0c;有没有什么快捷的方法呢&#xff1f;今天分享两个方法&#xff0c;一键修改ppt文件字体。 方法一&#xff1a; 找到功能栏中的编辑选项卡&#xff0c;点击替换 – 替换字体&#xff0c;在里面选择我们想要替换的字体…

【DolphinScheduler】datax读取hive分区表时,空分区、分区无数据任务报错问题解决

问题背景&#xff1a; 最近在使用海豚调度DolphinScheduler的Datax组件时&#xff0c;遇到这么一个问题&#xff1a;之前给客户使用海豚做的离线数仓的分层搭建&#xff0c;一直都运行好好的&#xff0c;过了个元旦&#xff0c;这几天突然在数仓做任务时报错&#xff0c;具体报…

JUC之锁

乐观锁和悲观锁 悲观锁 当一个线程在操作资源的时候&#xff0c;会悲观的任务有其他的线程会来抢占该资源&#xff0c;因此会在操作资源前进行加锁&#xff0c;避免其他线程抢占。 Synchronized关键字和Lock实现类就是悲观锁。 显示的锁定资源后再对资源进行操作。 使用场景&…

生日视频模板-试试这样制作

视频制作已经成为表达情感、记录生活的重要方式。尤其在生日这样的特殊日子&#xff0c;一份个性化的视频祝福不仅能让人感到温馨&#xff0c;还能成为长久珍藏的回忆。那么&#xff0c;如何快速制作出精美的生日模版视频呢&#xff1f;下面就给大家介绍几种可以制作生日模版的…

通信入门系列——离散卷积、连续卷积、卷积性质

本节目录 一、线性系统的激励响应 1、离散δ信号 2、离散卷积 3、连续δ信号 4、连续卷积 二、卷积性质 1、交换律 2、分配律 3、结合律 4、与冲激函数卷积本节内容 一、线性系统的激励响应 输入信号又称为激励&#xff0c;输出信号又称为响应。一个信号输入给一个线性系统的时…

基于单片机设计的智慧农业大棚检测系统

一、设计目标 本项目基于单片机设计一个智慧农业大棚检测系统&#xff0c;以提供实时监测和管理大棚环境的关键参数。系统支持环境温度、湿度检测&#xff0c;光照强度检测&#xff0c;并能根据预设的阀值进行报警提示。为了实现数据的显示和管理&#xff0c;该系统还利用Qt开…

生成式人工智能研究焦点:揭秘基于扩散的模型

生成式人工智能研究焦点&#xff1a;揭秘基于扩散的模型 文章目录 生成式人工智能研究焦点&#xff1a;揭秘基于扩散的模型去噪扩散是什么让扩散发挥作用&#xff1f;采样生成图像的设计选择以更少的步骤理顺流程在低噪音水平下步骤高阶求解器可实现更准确的步骤训练降噪器的设…

50天精通Golang(第17天)

beego框架总结及数据库连接配置 一、beego框架总结 1.1 Beego项目组织架构 上节课程内容对beego的案例代码进行了一个简单的分析&#xff0c;总结一下beego项目的组织结构&#xff0c;总结如下&#xff1a; 1.1.1 项目配置&#xff1a;conf 项目配置文件所在的目录&#x…

异常处理注解 @ExceptionHandler

今天记录下 SpringBoot 中 ExceptionHandler 的使用。 场景 有一个员工表(employee)&#xff0c;且给表中的 username 属性设置了唯一性。 -- auto-generated definition create table employee (id bigint auto_increment comment 主键primary key,name va…

【WPF.NET开发】OpenType字体

本文内容 OpenType 字体格式变量大写字母连字花体备用项数字样式版式类 本主题概述了 Windows Presentation Foundation (WPF) 中 OpenType 字体技术的一些主要功能。 1、OpenType 字体格式 OpenType 字体格式是 TrueType 字体格式的扩展&#xff0c;增加了对 PostScript 字…

Linux的SSH远程管理和服务器之间的免密连接

目录 一、远程管理基础 1.ssh协议 2.ssh原理 3、使用ssh协议传输的命令 4.登录方法 二、免密连接 1.免密连接的原理 2.实战 一、远程管理基础 1.ssh协议 ssh协议是基于C/S机构的安全通道协议&#xff0c;通信数据进行加密处理&#xff0c;用于远程管理。 ssh的服务名…

MATLAB二维与三维绘图实验

本文MATLAB源码&#xff0c;下载后直接打开运行即可[点击跳转下载]-附实验报告https://download.csdn.net/download/Coin_Collecter/88740747 一、实验目的 掌握图形对象属性的基本操作。掌握利用图形对象进行绘图操作的方法。 二、实验内容 利用图形对象绘制曲线&#xff…

【图解数据结构】深入剖析时间复杂度与空间复杂度的奥秘

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;图解数据结构、算法模板 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️算法的定义二. ⛳️算法的特性2.1 &#x1f514;输入输出2.2 &#x1f514;输入输出2.3 &…

MySQL面试题2

文章目录 面试题 (9-15) 面试题 (9-15) 09&#xff09;查询学过「张三」老师授课的同学的信息 SELECT s.*,c.cname,t.tname FROM t_mysql_teacher t,t_mysql_student s,t_mysql_course c,t_mysql_score sc WHERE t.tidc.tid and c.cidsc.cid and sc.sids.sid and tname ‘张…

网站建设网络设计营销类网站eyouCMS模板(PC+WAP)

模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0c;原创设计、手工书写DIVCSS&#xff0c;完美兼容IE7、Firefox、Chrome、360浏览器等&#xff1b;主流浏览器&#xff1b;结构容易优化&#xff1b;多终端均可正常预览。

【面试合集】说说微信小程序的登录流程?

面试官&#xff1a;说说微信小程序的登录流程&#xff1f; 一、背景 传统的web开发实现登陆功能&#xff0c;一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录 服务端校验用户信息通过之后&#xff0c;下发一个代表登录态的 token 给客户端&#xff0c;以便进行…

线程安全2

文章目录 锁的可重入性死锁内存可见性引起的线程安全 锁的可重入性 直观来看这个代码不能运行 为啥没有出现阻塞&#xff1f; 当前由于是同一个线程&#xff0c;此时的锁对象&#xff0c;就知道了第二次加锁的线程&#xff0c;就是持有锁的线程&#xff0c;第二次操作&#xff…

前端开发必备:掌握正则表达式,轻松应对复杂的表单验证

前言 在前端开发中&#xff0c;经常需要处理 URL 地址、校验手机号合法性、提取域名等。正则表达式是一种常用的工具。通过使用正则表达式&#xff0c;我们可以对用户输入进行有效的验证&#xff0c;确保数据的合法性和完整性。本文将介绍一些常见的正则表达式&#xff0c;帮助…

使用JDK自带的jvisualvm工具查看堆dump文件【回顾】

JDK自带的jvisualvm的使用 打开方式&#xff1a; 直接命令行输入&#xff1a;jvisualvm ,然后回车​​​​​​​ ​​ 或者去jdk的bin目录下找到打开 安装visual GC插件 检测死锁 再点击“死锁 dump”就可以看到死锁的线程信息了&#xff1b;