项目

内容

这个作业属于哪个课程

https://www.cnblogs.com/nwnu-daizh/

这个作业的要求在哪里

https://www.cnblogs.com/nwnu-daizh/p/11435127.html

作业学习目标

(1) 掌握Java应用程序的打包操作;

(2) 掌握线程概念;

(3) 掌握线程创建的两种技术。

(4) 学习设计应用程序的GUI。

第一部分:总结教材14.1-14.3知识内容

1.1 多线程原理

自定义线程类Thread类:


public class MyThread extends Thread{
/*
* 利用继承中的特点
* 将线程名称传递 进行设置
*/
public MyThread(String name){
super(name);
}
/*
* 重写run方法
* 定义线程要执行的代码
*/
public void run(){
for (int i = 0; i < 20; i++) {
//getName()方法 来自父亲
System.out.println(getName()+i);
}
}
}

测试类

public class Demo {
public static void main(String[] args) { System.out.println("这里是main线程"); MyThread mt = new MyThread("小强"); mt.start();//开启了一个新的线程
for (int i = 0; i < 20; i++) { System.out.println("旺财:"+i);
}
}
}

程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。随着调用mt的对象的

start方法,另外一个新的线程也启动了,这样,整个应用就在多线程下运行。

通过这张图我们可以很清晰的看到多线程的执行流程,那么为什么可以完成并发执行呢?我们再来讲一讲原理。  多线程执行时,到底在内存中是如何运行的呢?以上个程序为例,进行图解说明:

多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。

当执行线程的任务结束了,线程自动在栈内存中释放了。但是当所有的执行线程都结束了,那么进程就结束了。

1.2 Thread

 

在上一天内容中我们已经可以完成最基本的线程开启,那么在我们完成操作过程中用到了 类,

API中该类中定义了有关线程的一些方法,具体如下:

构造方法

常用方法:

public String getName() :获取当前线程名称。

public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。

public void run() :此线程要执行的任务在此处定义代码。

public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。

public static Thread currentThread() :返回对当前正在执行的线程对象的引用。

翻阅API后得知创建线程的方式总共有两种,一种是继承Thread类方式,一种是实现Runnable接口方式,方式一我  们上一天已经完成,接下来讲解方式二实现的方式。

1.3 创建线程方式二

采用Runnable接口

步骤如下:

也是非常常见的一种,我们只需要重写run方法即可。

  1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
  2. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
  3. 调用线程对象的start()方法来启动线程。

代码如下:

public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
public class Demo {
public static void main(String[] args) {
//创建自定义类对象 线程任务对象
MyRunnable mr = new MyRunnable();
//创建线程对象
Thread t = new Thread(mr, "小强");
t.start();
for (int i = 0; i < 20; i++) { System.out.println("旺财 " + i);
}
}
}

通过实现Runnable接口,使得该类有了多线程类的特征。run()方法是多线程程序的一个执行目标。所有的多线程  代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。

在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread 对象的start()方法来运行多线程代码。

实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是继承Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程 编程的基础。

tips:Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

1.4 ThreadRunnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。 总结:

实现Runnable接口比继承Thread类所具有的优势:

  1. 适合多个相同的程序代码的线程去共享同一个资源。
  2. 可以避免java中的单继承的局限性。
  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
  4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进  程。

第二部分:实验部分

1、实验目的与要求

(1) 掌握Java应用程序的打包操作;

(2) 掌握线程概念;

(3) 掌握线程创建的两种技术。

2、实验内容和步骤

实验1: 导入第13章示例程序,测试程序并进行代码注释。

测试程序1

elipse IDE中调试运行教材585页程序13-1,结合程序运行结果理解程序;

将所生成的JAR文件移到另外一个不同的目录中,再运行该归档文件,以便确认程序是从JAR文件中,而不是从当前目录中读取的资源。

掌握创建JAR文件的方法;

实验代码:

package 线程;

import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*; /**
* @version 1.41 2015-06-12
* @author Cay Horstmann
*/
public class ResourceTest
{
public static void main(String[] args)
{ //设置图像界面窗口
EventQueue.invokeLater(() -> {
JFrame frame = new ResourceTestFrame();
frame.setTitle("ResourceTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
} /**
* A frame that loads image and text resources.
*/
class ResourceTestFrame extends JFrame
{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 300; public ResourceTestFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
URL aboutURL = getClass().getResource("about.gif"); //利用about.gif图像文件制作图标
Image img = new ImageIcon(aboutURL).getImage();
setIconImage(img); JTextArea textArea = new JTextArea();//创建一个文本空白框
InputStream stream = getClass().getResourceAsStream("about.txt");//读取about.txt文件
try (Scanner in = new Scanner(stream, "UTF-8"))
{
while (in.hasNext())//判断读取的文件这行是否有数据
textArea.append(in.nextLine() + "\n");
}
add(textArea);//将读取的文件添加到文本框中
}
}

实验结果:

点击后:

测试程序2:

l 在elipse IDE中调试运行ThreadTest,结合程序运行结果理解程序;

l 掌握线程概念;

l 掌握用Thread的扩展类实现线程的方法;

利用Runnable接口改造程序,掌握用Runnable接口创建线程的方法。

class Lefthand extends Thread {
public void run()
{
for(int i=0;i<=5;i++)
{ System.out.println("You are Students!");
try{ sleep(500); }
catch(InterruptedException e)
{ System.out.println("Lefthand error.");}
}
}
}
class Righthand extends Thread {
public void run()
{
for(int i=0;i<=5;i++)
{ System.out.println("I am a Teacher!");
try{ sleep(300); }
catch(InterruptedException e)
{ System.out.println("Righthand error.");}
}
}
}
public class ThreadTest
{
static Lefthand left;
static Righthand right;
public static void main(String[] args)
{ left=new Lefthand();
right=new Righthand();
left.start();
right.start();
}
}

利用Runnable接口改造程序后

package 线程;
//线程的接口Runnable
class Lefthand implements Runnable{
@Override
public void run()
{
for(int i=0;i<=5;i++)
{ System.out.println("You are Students!");
try{ Thread.sleep(500); }
catch(InterruptedException e)
{ System.out.println("Lefthand error.");}
}
}
}
class Righthand implements Runnable {
public void run()
{
for(int i=0;i<=5;i++)
{ System.out.println("I am a Teacher!");
try{ Thread.sleep(300); }
catch(InterruptedException e)
{ System.out.println("Righthand error.");}
}
}
}
public class ThreadTest
{
static Lefthand left;
static Righthand right;
public static void main(String[] args)
{ left=new Lefthand();
right=new Righthand();
new Thread(left).start();
new Thread(right).start(); }
}

运行结果:

测试程序3:

l 在Elipse环境下调试教材625页程序14-1、14-2 、14-3,结合程序运行结果理解程序;

l 在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;

l 对比两个程序,理解线程的概念和用途;

l 掌握线程创建的两种技术。

14-1

package 线程;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*; /**
* Shows an animated bouncing ball.
* @version 1.34 2015-06-21
* @author Cay Horstmann
*/
public class Bounce
{
public static void main(String[] args)
{
EventQueue.invokeLater(() -> {
JFrame frame = new BounceFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});//创建一个GUI界面
}
} /**
* The frame with ball component and buttons.
*/
class BounceFrame extends JFrame
{
private BallComponent comp;
public static final int STEPS = 1000;
public static final int DELAY = 3; /*构造包含用于显示弹跳球和启动和关闭按钮*/
public BounceFrame()
{
setTitle("Bounce");
comp = new BallComponent();
add(comp, BorderLayout.CENTER);//设置组件在页面的布局为边框布局的中央
JPanel buttonPanel = new JPanel();
addButton(buttonPanel, "Start", event -> addBall());//添加按钮到按钮面板中,并为其添加事件监听器addBall方法
addButton(buttonPanel, "Close", event -> System.exit(0));
add(buttonPanel, BorderLayout.SOUTH);//
pack();
} /**
* Adds a button to a container.
* @param c the container
* @param title the button title
* @param listener the action listener for the button
*/
public void addButton(Container c, String title, ActionListener listener)
{
JButton button = new JButton(title);
c.add(button);
button.addActionListener(listener);
} /* 在面板中添加一个弹跳球,使其弹跳1000次。
*/
public void addBall()
{
try
{
Ball ball = new Ball();
comp.add(ball); for (int i = 1; i <= STEPS; i++)
{
ball.move(comp.getBounds());
comp.paint(comp.getGraphics());
Thread.sleep(DELAY);//调用线程当中的Thread.sleep方法。用于暂停当前的线程活动
}
}
catch (InterruptedException e)
{
}
}
}

14-2

package 线程;

import java.awt.geom.*;

/* 在长方形边缘上移动和反弹的球*/
public class Ball
{
private static final int XSIZE = 15;
private static final int YSIZE = 15;
private double x = 0;
private double y = 0;
private double dx = 1;
private double dy = 1; // 将球移动到下一个位置,如果球碰到其中一个边,则反转方向
public void move(Rectangle2D bounds)
{
x += dx;
y += dy;
if (x < bounds.getMinX())
{
x = bounds.getMinX();
dx = -dx;
}
if (x + XSIZE >= bounds.getMaxX())
{
x = bounds.getMaxX() - XSIZE;
dx = -dx;
}
if (y < bounds.getMinY())
{
y = bounds.getMinY();
dy = -dy;
}
if (y + YSIZE >= bounds.getMaxY())
{
y = bounds.getMaxY() - YSIZE;
dy = -dy;
}
} //获取球在其当前位置的形状
public Ellipse2D getShape()
{
return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
}
}

14-3

package 线程;

import java.awt.*;
import java.util.*;
import javax.swing.*;
public class BallComponent extends JPanel
{
private static final int DEFAULT_WIDTH = 450;
private static final int DEFAULT_HEIGHT = 350; private java.util.List<Ball> balls = new ArrayList<>(); //在面板上添加一个球
public void add(Ball b)
{
balls.add(b);
} public void paintComponent(Graphics g)
{
super.paintComponent(g); // erase background
Graphics2D g2 = (Graphics2D) g;
for (Ball b : balls)
{
g2.fill(b.getShape());
}
} public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
}

运行结果:

14-4

package Main;

import java.awt.*;
import java.awt.event.*; import javax.swing.*; /**
* Shows animated bouncing balls.
* @version 1.34 2015-06-21
* @author Cay Horstmann
*/
public class BounceThread
{
public static void main(String[] args)
{
EventQueue.invokeLater(() -> {
JFrame frame = new BounceFrame();
frame.setTitle("BounceThread");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
} //在框架上添加面板和按钮
class BounceFrame extends JFrame
{
private BallComponent comp;
public static final int STEPS = ;
public static final int DELAY = ; //构造包含用于显示弹跳球和启动和关闭按钮
public BounceFrame()
{
comp = new BallComponent();
add(comp, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
addButton(buttonPanel, "Start", event -> addBall());
addButton(buttonPanel, "Close", event -> System.exit());
add(buttonPanel, BorderLayout.SOUTH);
pack();
} public void addButton(Container c, String title, ActionListener listener)
{
JButton button = new JButton(title);
c.add(button);
button.addActionListener(listener);
} // 在画布上添加一个弹跳球并开始一条线使其弹跳
public void addBall()
{
Ball ball = new Ball();
comp.add(ball);
Runnable r = () -> {
try
{
for (int i = ; i <= STEPS; i++)
{
ball.move(comp.getBounds());
comp.repaint();
Thread.sleep(DELAY);
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}

运行结果:

实验2:结对编程练习:采用GUI界面设计以下程序,并创建程序归档文件。

l 设计一个100以内整数小学生四则运算练习程序,由计算机随机产生10道加减乘除练习题,学生输入答案,由程序检查答案是否正确,每道题正确计10分,错误不计分,10道题测试结束后给出测试总分;

l 将程序中测试练习题及学生答题结果输出到文件,文件名为test.txt。

结对编程对象:胡欢欢

程序代码:

package jsq;

import java.awt.EventQueue;

import javax.swing.JFrame;

public class jsq {
public static void main(String[] args) {
EventQueue.invokeLater(()->{
JFrame g = new gui();
g.setVisible(true);
g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new jisuan();
});
}
}
package jsq;
import java.io.*;
import java.math.*; import javax.swing.JTextArea; public class jisuan {
char fh;
public int m() {
int m = (int)(1+Math.random()*100);
return m;
}
public int n() {
int n = (int)(1+Math.random()*100);
return n;
}
public char fh() {
int x = (int)(1+Math.random()*4);
switch (x) {
case 1:
fh='+';
break;
case 2:
fh='-';
break;
case 3:
fh='*';
break;
case 4:
fh='/';
break;
}
return fh;
}
public int pd(int m, char fh ,int n) {
int jg=0 ;
switch (fh) {
case '+':
jg = m+n;
break;
case '-':
jg = m-n;
break;
case '*':
jg = m*n;
break;
case '/':
jg = m/n;
break;
}
return jg;
}
public void wfile(String str) {
File f = new File("C:\\Users\\huhuanhuan\\Desktop\\test.txt");
try {
BufferedWriter b = new BufferedWriter(new FileWriter("C:\\Users\\huhuanhuan\\Desktop\\test.txt"));
b.write(str);
b.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package jsq;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import javax.swing.*; public class gui extends JFrame {
int m,n,jg,cj,jsq,btcj,sj,sjjg=1;
char fh;
public static int width=600;
public static int height=400;
JPanel JP0 = new JPanel();
JPanel JP1 = new JPanel();
JPanel JP2 = new JPanel();
JLabel L1 = new JLabel();
JLabel L2 = new JLabel();
JLabel L3 = new JLabel();
JLabel L4 = new JLabel();
JLabel L5 = new JLabel();
JLabel L6 = new JLabel();
JTextField text = new JTextField();
JTextField text1 = new JTextField();
JTextArea Are = new JTextArea();
JButton ks = new JButton("开始答题");
JButton xyt = new JButton("下一题");
JButton jc = new JButton("检查");
JButton jj = new JButton("交卷");
jisuan j = new jisuan();
JOptionPane o;
ActionListener listener1 = new time();
Timer t = new Timer(1000,listener1);
public gui() { Dimension scrSize=Toolkit.getDefaultToolkit().getScreenSize();
setBounds((scrSize.width-width)/2,(scrSize.height-height)/2,width,height);
JP1.setBounds(0,0,width,height/2);
JP2.setBounds(0,200,width,height/2);
JP0.setBounds(0, 0, width, height);
add(JP1);
add(JP2);
JP1.setLayout(null);
JP2.setLayout(null);
L1.setBounds(150, 40, width/10, height/8);
L1.setText("题目:");
JP1.add(L1);
L2.setBounds(150, 83, width/10, height/8);
L2.setText("答案:");
JP1.add(L2);
L3.setBounds(210, 40, width/6, height/8);
JP1.add(L3);
L4.setBounds(310, 40, width/6, height/8);
JP1.add(L4);
L5.setBounds(230, 10, 220, height/12);
L5.setVisible(false);
Font font = new Font("Default",Font.PLAIN,30);
L5.setFont(font);
L5.setForeground(Color.red);
JP1.add(L5);
L6.setBounds(103, 10, 90, height/12);
L6.setText("输入倒计时/s:");
JP1.add(L6);
text.setBounds(190, 95, 220, height/12);
JP1.add(text);
text1.setBounds(190, 10, 220, height/12);
JP1.add(text1);
ks.setBounds(240, 200, 120, 45);
JP2.add(ks);
jc.setBounds(170, 200, 120, 45);
xyt.setBounds(310, 200, 120, 45);
jj.setBounds(310, 200, 120, 45);
jc.setVisible(false);
xyt.setVisible(false);
jj.setVisible(false);
JP2.add(jc);
JP2.add(xyt);
JP2.add(jj);
ks.addActionListener(event->{
ks.setVisible(false);
jc.setVisible(true);
xyt.setVisible(true);
// var j = new jisuan();
m = j.m();
n = j.n();
fh = j.fh();
L3.setText(m+" "+fh+" "+n+" "+"=");
L6.setVisible(false);
text1.setVisible(false);
L5.setVisible(true);
sj=Integer.parseInt(text1.getText());
t.start();
});
xyt.addActionListener(event->{
jsq++;
Are.append(m+" "+fh+" "+n+" "+"="+" "+jg+" 本题得分:"+btcj+'\n');
m = j.m();
n = j.n();
fh = j.fh();
L3.setText(m+" "+fh+" "+n+" "+"=");
text.setText("");
L4.setText("");
btcj=0;
jg=0;
if(jsq==9)
{
xyt.setVisible(false);
jj.setVisible(true);
}
});
jc.addActionListener(event->{
jg = (Integer.parseInt(text.getText()));
if((j.pd(m, fh, n))==(jg)) {
L4.setText(jg+" "+"√");
L4.setForeground(Color.green);
btcj=10;
}
else
{
L4.setText(jg+" "+"×");
L4.setForeground(Color.red);
btcj=0;
}
cj=cj+btcj;
});
jj.addActionListener(event->{
JP1.setVisible(false);
JP2.setVisible(false);
Are.setSize(width, height);
add(Are);
Are.append(m+" "+fh+" "+n+" "+"="+" "+jg+" 本题得分:"+btcj+'\n');
Are.append("总分:"+cj);
j.wfile(Are.getText());
}); }
class time implements ActionListener{ @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(sj==0) {
o.showMessageDialog(gui.this, "时间到");;
t.stop();
text.setEditable(false);
}
L5.setText(" "+sj);
sj--;
Toolkit.getDefaultToolkit().beep();
} }
}

运行截图:

结对编程照片:

实验心得:

多线程是进程执行过程中产生的多条执行线索。线程是比进程执行更小的单位。线程不能独立存在,必须存在于进程中,同一进程的各线程间共享进程空间的数据。每个线程有它自身的产生、存在和消亡的过程,是一个动态的概念。多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。线程创建、销毁和切换的负荷远小于进程,又称为轻量级进程。

线程两种创建方法比较:实现Runnable接口的优势:符合OO设计的思想;便于用extends继承其它类。采用继承Thread类方法的优点:代码简单。

Java 的线程调度采用优先级策略:优先级高的先执行,优先级低的后执行;多线程系统会自动为每个线程分配一个优先级,缺省时,继承其父类的优先级; 任务紧急的线程,其优先级较高; 同优先级的线程按“先进先出”的队列原则。

通过本周的编程练习,对前面学习的知识得到了充分的温习,而且此次编程练习虽然难度较大,但还是和结对编程伙伴的到了对于知识的理解和 完成试验任务

201871010114-李岩松《面向对象程序设计(java)》第十六周学习总结的更多相关文章

  1. 201571030332 扎西平措 《面向对象程序设计Java》第八周学习总结

    <面向对象程序设计Java>第八周学习总结   项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https: ...

  2. 201771010118马昕璐《面向对象程序设计java》第八周学习总结

    第一部分:理论知识学习部分 1.接口 在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成.Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个 ...

  3. 201771010134杨其菊《面向对象程序设计java》第八周学习总结

    第八周学习总结 第一部分:理论知识 一.接口.lambda和内部类:  Comparator与comparable接口: 1.comparable接口的方法是compareTo,只有一个参数:comp ...

  4. 201771010134杨其菊《面向对象程序设计java》第七周学习总结

    第七周学习总结 第一部分:理论知识 1.继承是面向对象程序设计(Object Oriented Programming-OOP)中软件重用的关键技术.继承机制使用已经定义的类作为基础建立新的类定义,新 ...

  5. 201771010128 王玉兰《面象对象程序设计 (Java) 》第六周学习总结

    ---恢复内容开始--- 第一部分:基础知识总结: 1.继承 A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况: B:特点:具有层次结构. ...

  6. 201771010123汪慧和《面向对象程序设计JAVA》第六周实验总结

    一.理论部分: 1.继承 用已有类来构建新类的一种机制.当定义了一个新类继承了一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的方法和域以适应新的情况. 2.类.超类.子类 (1)类继承 ...

  7. 201871010126 王亚涛《面向对象程序设计 JAVA》 第十三周学习总结

      内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  8. 201777010217-金云馨《面向对象程序设计Java》第八周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  9. 201871010126 王亚涛 《面向对象程序设计 (Java)》第十七周学习总结

    内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/12 ...

  10. 马凯军201771010116《面向对象程序设计Java》第八周学习总结

    一,理论知识学习部分 6.1.1 接口概念 两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构:二,一个类所具有的方法的特征集合,是一种逻辑上的抽象.前者叫做“Java接口”,后 ...

随机推荐

  1. Grafana = 可视化分析 + 监控告警

    Grafana是一个完美地分析和监控的开发平台 可以把Grafana理解为一个可视化面板(Dashboard),其实Kibana也是一个分析和可视化平台,只不过在大家的日常使用中Kibana是跟着Lo ...

  2. MTDDL 美团分布式数据访问中间件(转)

    MTDDL 美团分布式数据访问中间件(转) 原文地址:MTDDL--美团点评分布式数据访问层中间件 因原文文字和图显示有问题,故整理于此,仅供参考. 业界方案 组件 简介 Atlas Qihoo 36 ...

  3. Access the Security System in Code 在代码中访问安全系统

    This lesson will guide you through using the static SecuritySystem class to check whether or not a u ...

  4. Windows添加自定义开机用户登录启动程序

    默认的启动程序 Ctrl+shift -> Esc调用任务管理器-->启动项选项即可完成计算机开机自启动选项,不过这里只有系统默认添加的. 添加自定义开机启动程序 Windows+R调用运 ...

  5. C++ --const修饰指针

    const修饰指针 1.const修饰指针 (常量指针)常量的指针 const int *p = &a; const修饰的是*p(表示内容为常量),不是p(指针) 指针指向的地址可以改,但指针 ...

  6. 集合 set方法

    集合 number = {1, 2, 4} # 添加元素到集合 number.add(100) print(number) # 从集合中删除 number.remove(2) print(number ...

  7. [MySQL] mysql中bitmap的简单运用

    bitmap就是在一个二进制的数据中,每一个位代表一定的含义,这样最终只需要存一个整型数据,就可以解释出多个含义.业务中有一个字段专门用来存储用户对某些功能的开启和关闭,如果是传统的思维,肯定是建一个 ...

  8. Java之Lambda表达式

    函数式编程思想概述 面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做. 面向对象的思想: 做一件事情,找一个能解决这个事情的对 ...

  9. 一些你不知道的js特性【一】

    关于js 我们知道完整的js包括三个方面ECMAScript.DOM(文档对象模型).BOM(浏览器对象模型). ECMAScript定义了与宿主无关的预言基础,比如:语法(包含正则语法).类型.语句 ...

  10. 函数式编程 - Functional Programming

    什么是函数式编程 函数式编程是一种编程范式. 编程范式又是什么? 编程范式是一种解决问题的思路. 命令式编程 把程序看作 一系列改变状态的指令: 函数式编程 把程序看作 一系列数学函数映射的组合. i ...