一、    填空题

  1. 处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入____阻塞_____状态。
  2. 处于新建状态的线程被启动后,将进入线程队列排队等待CPU,此时它已具备了运行条件,一旦轮到享用CPU资源就可以获得执行机会。上述线程是处于    就绪    状态。

解析: 线程的生命周期—五个阶段

新建状态---- new关键字创建线程对象

就绪状态---- start()方法运行之前

运行状态---- run()方法的运行

堵塞状态--- interrupt()  sleep()  join()  yield()  wait() 等方法

死亡状态--- stop()方法(已过时) /或run()方法运行结束

  1. 一个正在执行的线程可能被人为地中断,让出CPU的使用权,暂时中止自己的执行,进入     阻塞       状态。

解析:人为的中断正在执行的线程---- 执行wait() 、interrupt() 、sleep()方法等

  1. 在Java中编写实现多线程应用有两种途径:一种是继承Thread类创建线程,另一种是实现    Runnable         接口创建线程。

解析: 继承Thread类来创建线程,不能实现资源的共享,除非资源使用static修饰。

实现Runnable接口创建线程,此时还需要借助Thread类,因为Runnable接口

没有start()方法,同时Thread类是Runnable接口的子类….

  1. 在线程控制中,可以调用_____join()____方法,阻塞当前正在执行的线程,等插队线程执行完后后再执行阻塞线程。
  2. 多线程访问某个共享资源可能出现线程安全问题,此时可以使用______synchronized_____关键字来实现线程同步,从而避免安全问题出现,但会影响性能,甚至出现死锁。
  3. 在线程通信中,调用wait( )可以是当前线程处于等待状态,而为了唤醒一个等待的线程,需要调用的方法是____notify()/notifyAll()__________。

解析:线程等待使用wait()方法,此方法最先是存在于Object类,Thread类继承Object类,可以获取此方法,同时notify()方法和notifyAll()方法---线程唤醒,最先也是存在于

Object类当中。

  1. 在线程通信中,可以调用wait()、notify()、notifyAll()三个方法实现线程通信,这三个方法都是____Object____类提供的public方法,所以任何类都具有这三个方法。

二、    选择题

1.

下列关于Java线程的说法正确的是(   A )。(选择一项)

A

每一个Java线程可以看成由代码、一个真实的CPU以及数据三部分组成

B.

创建线程的两种方法中,从Thread类中继承方式可以防止出现多父类的问题

C.

Thread类属于java.util程序包

D.

使用new Thread(new X()).run();方法启动一个线程

解析:

A、语句正确。

B、创建线程两种方法:一是继承Thread类,一是实现Runnable接口

根据Java语言类的单继承特性,防止出现多继承,但是可以实现多

重继承,也可以出现多父类。

C、Thread类是存在于java.lang包下

D、启动一个线程是调用start()方法,之后JVM会默认的调用run()方法

run()方法是线程的主体,核心代码放到此方法当中。

 

2.

以下选项中可以填写到横线处,让代码正确编译和运行的是(  AD  。(选择一项)

 

public class Test implements Runnable {

public static void main(String[] args) {

___________________________________

t.start();

System.out.println("main");

}

public void run() {

System.out.println("thread1!");

}

}

A.

Thread t = new Thread(new Test());

B.

Test t = new Test();

C.

Thread t = new Test();

D.

Thread t = new Thread();

解析:

线程的创建有两种方式,其中之一就是实现Runnable接口。

此接口只有一个抽象方法---run()方法,启动线程又需要start()方法

此时还需要借助Thread类,根据Thread类的构造方法:

Public  Thread(Runnable  run)

需要传入Runnable接口对象

此题还有一个方法: 直接创建Thread类对象,调用start()方法

所以D选项也是正确的,但是此题重点还是考的子类实现Runnable接口

根据Thread类的构造方法启动线程。

 

3.

如下代码创建一个新线程并启动线程,问:四个选项中可以保证正确代码创建target对象,并能编译正确的是(   C  )?(选择一项)

 

public static void main(String[] args) {

Runnable target=new MyRunnable( );

Thread myThread=new Thread(target);

}

A

public class MyRunnable extends Runnable {

public void run( ) {        }

}

B.

public class MyRunnable extends Runnable {

void run( ) {  }

}

C.

public class MyRunnable  implements Runnable  {

public void run( ) {        }

}

D.

public class MyRunnable  implements Runnable  {

void run( ) { }

解析:接口是用来实现的,不是继承,所以AB两个选项错误。

根据Java多态机制,子类可以为父类(接口)实例化对象

根据子类实现接口的规则,子类必须重写接口当中的抽象方法

此时又复习到了方法重写的规则:子类重写的方法它的权限必须

大于等于父类方法权限(除去private外)。根据以上得出C是对的

 

4.

当线程调用start( )后,其所处状态为( C   )。(选择一项)

A

阻塞状态

B.

运行状态

C.

就绪状态

D.

新建状态

解析:线程的五个状态也就是它的生命周期:

新建状态----通过new关键字来创建线程对象

就绪状态----调用start()方法

运行状态----调用run()方法

阻塞状态----调用sleep()、wait()、join() 、yield()、interrupt ()等方法

消亡状态----调用stop()方法,但是此方法已经过时。

 

5.

下列关于Thread类提供的线程控制方法的说法中,错误的是(  C  )。(选择一项)

A

线程A中执行线程B的join()方法,则线程A等待直到B执行完成

B.

线程A通过调用interrupt()方法来中断其阻塞状态

C.

若线程A调用方法isAlive()返回值为false,则说明A正在执行中,也可能是可运行状态

D.

currentThread()方法返回当前线程的引用

解析:

A: join()方法—强制加入,加入的线程执行完毕之后才能执行其他线程

B:interrupt()方法---线程中断,题中的说法有些牵强

C:isAlive()方法---判断一个线程是否在活动,如果在活动返回真,反之假

D:currentThread()方法返回正在执行的线程

从以上得知,C明显错误。

 

6.

下列关于线程的优先级说法中,正确的是(  BD  )。(选择两项)

A

线程的优先级是不能改变的

B.

线程的优先级是在创建线程时设置的

C.

在创建线程后的任何时候都可以重新设置

D.

线程的优先级的范围在1-10之间

       解析:线程的优先级可以通过setPriority(int newPriority)的方法进行设置

             线程一共有三个优先级,分别是:最低优先级(1中等优先级(5

             最高优先级(10),咱们经常写的main方法就是中等优先级线程。

             A:线程的优先级是可以更改也可以获取,但是有一点,即使设置为最高

                优先级也不一定先执行,只是它优先执行的几率比较高。

             B:线程的优先级是在创建时进行设置,通过setPriority()方法设置

           C:正在执行的线程是不允许重新设置线程优先级的。

D:线程的优先级范围是1—10 符合要求

 

7.

以下选项中关于Java中线程控制方法的说法正确的是(  AD   )。(选择二项)

A.

join ( ) 的作用是阻塞指定线程等到另一个线程完成以后再继续执行

B.

sleep ( ) 的作用是让当前正在执行线程暂停,线程将转入就绪状态

C.

yield ( ) 的作用是使线程停止运行一段时间,将处于阻塞状态

D.

setDaemon( )的作用是将指定的线程设置成后台线程

解析:

A:join()方法—线程的强制加入,加入的线程执行完毕之后再执行其他线程

B:sleep()方法—线程休眠,等时间过时,线程处于运行状态

C:yield()方法—线程礼让,让出CUP资源,其他线程先执行,有些与join()

方法类似

D:setDaemon()方法--将指定的线程设置成后台线程,对的。

题的答案是:AD,但是个人感觉C选项也是对的……

 

8.

在多个线程访问同一个资源时,可以使用(  A  关键字来实现线程同步,保证对资源安全访问。(选择一项)

A.

Synchronized

B.

Transient

C.

Static

D.

Yield

         解析:关于同步,有两种实现方式,一种是同步方法,一种是同步代码块

                无论怎样,都需要使用到synchronized关键字。

同步方法:

权限修饰符  synchronized  返回值类型  方法名称(参数列表){

N行代码;

}

同步代码块:

Synchronized(对象){

N行代码;

}

9.

Java中线程安全问题是通过关键字(   C  )解决的?。(选择一项)

A.

Finally

B.

wait( )

C.

Synchronized

D.

notify( )

10.

以下说法中关于线程通信的说法错误的是(  D  ?。(选择一项)

A.

可以调用wait()、notify()、notifyAll()三个方法实现线程通信

B.

wait()、notify()、notifyAll()必须在synchronized方法或者代码块中使用

C.

wait()有多个重载的方法,可以指定等待的时间

D.

wait()、notify()、notifyAll()是Object类提供的方法,子类可以重写

解析:

A选项:

在线程通信中,可以调用wait()、notify()、notifyAll()三个方法实现线程通信,这三个方法都是Object类提供的public方法,所以任何类都具有这三个方法。

B选项:在编程题的第二题当中,wait()方法、notify()方法、notifyAll()方法都是写在同步方法当中,具体可以查看此类的源码。

C选项:Object类当中的wait方法的重载如下:

public final void wait()

public final void wait(long timeout)
public final void wait(long timeout, int nanos)
三个方法都抛出异常-- InterruptedException
   D选项 : 看A选项的解释
    以上三个方法都使用final修饰,所以子类是不能重写的

 

三、    判断题

  1. 进程是线程Thread内部的一个执行单元,它是程序中一个单一顺序控制流程。( ×  )

解析:线程是进程的一个执行单位,进程包含线程。

  1. Thread类实现了Runnable接口。(   √  )

解析:Thread类在JDK当中的定义如下:

Public class Thread extends Object  implements Runnable

从定义可知,它是Runnable接口的子类。

  1. 一个进程可以包括多个线程。两者的一个主要区别是:线程是资源分配的单位,而进程CPU调度和执行的单位。(  ×  )

解析:不管是进程还是线程,都是通过循环获得自己执行的时间片,获得CUP资源。

  1. 用new关键字建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start进入就绪状态。(  √  )

解析:具体解析看选择题第四题的解释。

  1. A线程的优先级是10,B线程的优先级是1,那么当进行调度时一定会先调用A( ×  )

解析:线程的执行,不是谁的优先级高就先执行,只是它的概率会高。

  1. 线程可以用yield使低优先级的线程运行。(  ×  )

解析:yield()方法是线程礼让,可以让出自己执行其他线程,由于线程的执行存在严重

的随机性,不能确定使低优先级的线程执行。

  1. Thread.sleep( )方法调用后,当等待时间未到,该线程所处状态为阻塞状态。当等待时间已到,该线程所处状态为运行状态。( √   )

解析:sleep()方法是线程休眠,处于阻塞状态,当时间一到,就会执行处于运行状态。

如果真要追究用词的严谨性,应该不是”等待时间”,而是”休眠时间”。

  1. 当一个线程进入一个对象的一个synchronized方法后,其它线程不可以再进入该对象同步的其它方法执行。(  √  )

解析:对的,可以查看一下编程题第二题的源码。

  1. wait方法被调用时,所在线程是会释放所持有的锁资源, sleep方法不会释放。( √  )

解析:sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,所以调用sleep 不会释放对象锁。
wait 是Object 类的方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

  1. wait、notify、notifyAll是在Object类中定义的方法。( √  )

解析:具体可以查看API帮助文档,查看。

  1. notify是唤醒所在对象wait
    pool中的第一个线程。(
    ×  )

解析:唤醒的不一定是第一个线程。

JDK已经明确说明唤醒哪个thread是随意决定的,没有特定顺序
The choice is arbitrary and occurs at the discretion of the implementation

四、   
简答题

  1. 简述程序、进程和线程的联系和区别。
  2. 创建线程的两种方式分别是什么?各有什么优缺点。
  3. sleep、yield、join方法的区别?
  4. synchronize修饰的语句块,如下面的代码。是表示该代码块运行时必须获得account对象的锁。如果没有获得,会有什么情况发生?

synchronized
(account) {

if(account.money-drawingNum<0){

return;

}

}

  1. 请你简述sleep( )和wait(
    )有什么区别?
  2. 死锁是怎么造成的?用文字表达。再写一个代码示例。
  3. Java中实现线程通信的三个方法及其作用。
  4. 为什么不推荐使用stop和destroy方法来结束线程的运行?

五、   
编码题

1.设计一个多线程的程序如下:设计一个火车售票模拟程序。假如火车站要有100张火车票要卖出,现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况。

 public class CharPrint extends Thread
{
// 定义属性
private Printer p;
//构造方法
public CharPrint(Printer p)
{
super();
this.p = p;
}
//重写run()方法
public void run()
{
char c = 'A';//定义起始位置
//通过for循环对其进行输出
while (c <= 'Z')
{
p.print(c);
c++;//控制while循环当中的条件表达式
}
}
}
public class NumberPrint extends Thread
{
//定义属性
private Printer p;
//构造方法
public NumberPrint(Printer p)
{
this.p = p;
}
//重写run()方法
public void run()
{
int i = 1;//定义起始位置
while (i <= 52)
{
p.print(i);
i++;//控制while循环当中的条件表达式
}
}
}
public class Printer
{
//定义一个int类型变量---用于计数
int index = 1;
//同步的方法---print()
public synchronized void print(int i)
{
//判断是否是3的倍数
while (index % 3 == 0)
{
try
{
wait();//线程等待
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//打印输出数字
System.out.print("" + i);
//控制while循环中的条件表达式
index++;
//线程唤醒
notifyAll();
}
public synchronized void print(char c)
{
//判断是否是3的倍数
while (index % 3 != 0)
{
try
{
wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//打印字母
System.out.print("" + c);
//控制while循环中的条件表达式
index++;
//唤醒线程
notifyAll();
}
}
public class Test
{
public static void main(String[] args)
{
//创建Printer对象,为NumberPrint()类构造方法做准备
Printer p = new Printer();
//创建线程---子类为父类实例化对象
Thread t1 = new NumberPrint(p);
Thread t2 = new CharPrint(p);
//启动线程
t1.start();
t2.start();
}
}

2.编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z。打印顺序为12A34B56C….5152Z。即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替循环打印,直到打印到整数52和字母Z结束。

要求:

1)         编写打印类Printer,声明私有属性index,初始值为1,用来表示是第几次打印。

2)         在打印类Printer中编写打印数字的方法print(int i),3的倍数就使用wait()方法等待,否则就输出i,使用notifyAll()进行唤醒其它线程。

3)         在打印类Printer中编写打印字母的方法print(char c),不是3的倍数就等待,否则就打印输出字母c,使用notifyAll()进行唤醒其它线程。

4)         编写打印数字的线程NumberPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出数字的方法。

5)         编写打印字母的线程LetterPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出字母的方法。

6)         编写测试类Test,创建打印类对象,创建两个线程类对象,启动线程。

 public class TicketSalSystem implements Runnable
{
// 定义变量---票数/票号
public int ticket = 100;
public int count = 0;
// 重写run()方法
public void run()
{
// 定义while循环, 循环售票
while (ticket > 0)
{
// 根据题的要求,实现同步,此时定义同步代码块
synchronized (this)
{// 传入对象,使用this代替当前类对象
// 判断是否还有票,如果大于零说明还有票可卖
if (ticket > 0)
{
// 线程休眠0.5秒
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
count++; // 票号++
ticket--;// 循环售票,卖一张少一张
// 输出当前的售票窗口和票号
System.out.println(Thread.currentThread().getName()
+ "\t当前票号:" + count);
}
}
}
}
}
public class TicketTest
{
public static void main(String[] args)
{
// 创建线程类对象
TicketSalSystem st = new TicketSalSystem();
// 启动5次线程
for (char i = 'A'; i <= 'F'; i++)
{
/*
* 创建匿名Thread类对象
* 1、根据Thread类构造方法,传入Runnable接口对象
* TicketSalSystem类是Runnable接口的子类,子类对象st可以让父类接收
* 2、Thread类的构造方法如下:
* public Thread(Runnable run,String name)
* 在创建线程的同时,为线程名称
* 3、启动线程是使用start方法,启动之后JVM会默认的区调用run()方法
*/
new Thread(st, "售票口" + i).start();
}
}
}

六、    可选题

1.设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。

要求:使用内部类实现线程,对j增减的时候不考虑顺序问题。

 public class ThreadTest61
{
//声明成员变量j
private int j;
public static void main(String[] args)
{
//创建ThreadTest61的对象
ThreadTest61 tt = new ThreadTest61();
//创建内部线程类对象
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (int i = 0; i < 2; i++)
{
// 创建线程对象,启动线程
Thread t = new Thread(inc);
t.start();
// 创建线程对象,启动线程
t = new Thread(dec);
t.start();
}
}
//实现同步对j的值加
private synchronized void inc()
{
//调用此方法一次,对j就增加一次
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
//实现同步对j的值减
private synchronized void dec()
{
//调用此方法一次,对j就减一次
j--;
System.out.println(Thread.currentThread().getName() + "-dec:" + j);
}
//内部类实现Runnable接口,重写run()方法
class Inc implements Runnable
{
public void run()
{
//for循环当中调用inc()方法,实现每次对j加1
for (int i = 0; i < 100; i++)
{
//调用加的方法
inc();
}
}
}
//内部类实现Runnable接口,重写run()方法
class Dec implements Runnable
{
public void run()
{
//for循环当中调用inc()方法,实现每次对j减1
for (int i = 0; i < 100; i++)
{
//调用减的方法
dec();
}
}
}
}

2.编写多线程程序,模拟多个人通过一个山洞的模拟。这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒,有10个人同时准备过此山洞,显示每次通过山洞人的姓名和顺序。

 public class ThreadTest62
{
public static void main(String[] args)
{
/*创建一个山洞对象,为Thread类构造方法做准备
* public Thread(Runnable run,String name)
*/
Tunnel tul = new Tunnel();
//创建十个过山洞线程,并为线程命名
Thread p1 = new Thread(tul, "p1");
Thread p2 = new Thread(tul, "p2");
Thread p3 = new Thread(tul, "p3");
Thread p4 = new Thread(tul, "p4");
Thread p5 = new Thread(tul, "p5");
Thread p6 = new Thread(tul, "p6");
Thread p7 = new Thread(tul, "p7");
Thread p8 = new Thread(tul, "p8");
Thread p9 = new Thread(tul, "p9");
Thread p10 = new Thread(tul, "p10");
//启动十个线程
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
p6.start();
p7.start();
p8.start();
p9.start();
p10.start();
}
}
//创建山洞类并实现Runnable接口,重写run()方法
class Tunnel implements Runnable
{
//定义变量,初始化过山洞人数
int crossedNum = 0;
//重写run()方法,在此方法当中调用cross()方法
public void run()
{
cross();
}
//定义过山洞的同步方法
public synchronized void cross()
{
//每个人通过山洞的时间为5秒
try
{
Thread.sleep(5000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//人数统计,过一个人增加一个人
crossedNum++;
//显示每次通过山洞人的姓名
System.out.println(Thread.currentThread().getName()
+ "通过了山洞,这是第" + crossedNum + "个用户");
}
}

Java多线程题库的更多相关文章

  1. Leetcode多线程题库练习(新功能尝鲜)& 个人感悟

    大家好, 我是方子龙.很久没有自己写文章了. 一面是因为工作上的需求开发任务比较重,下班回家基本上就躺床玩几把王者,度过闲暇时光. 二面是一有点时间就自己主动地去看书和学习,知道自己还缺少很多知识,由 ...

  2. 03.Java多线程并发库API使用2

    1.多个线程之间共享数据的方式探讨 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 2.如果每个线程执行的代 ...

  3. Java异常题库

    一.填空题 __异常处理__机制是一种非常有用的辅助性程序设计方法.采用这种方法可以使得在程序设计时将程序的正常流程与错误处理分开,有利于代码的编写和维护. 在Java异常处理中可以使用多个catch ...

  4. Java容器题库

    一.    填空题 Java集合框架提供了一套性能优良.使用方便的接口和类,包括Collection和Map两大类,它们都位于  java.util  包中 队列和堆栈有些相似,不同之处在于栈是先进后 ...

  5. 02.Java多线程并发库API使用

    1.        传统线程技术回顾 继承线程与实现Runnable的差异?为什么那么多人都采取第二种方式? 因为第二种方式更符合面向对象的思维方式.创建一个线程,线程要运行代码,而运行的代码都封装到 ...

  6. java程序设计题库

    选择题 答题要求:单选题,每题只有一个正确答案,选择正确给分,不正确不给分. 1. 下面(   A    )数据类型可用于main()方法中传递的参数 A.String   B.Integer   C ...

  7. java——多线程并发库

    JDK5中增加了Doug Lea的并发库,这一引进给Java线程的管理和使用提供了强大的便利性. java.util.current包中提供了对线程优化.管理的各项操作,使得线程的使用变得的心应手.该 ...

  8. 04.Java多线程并发库API使用3

    1.java5的Semaphere同步工具 Semaphore可以维护当前访问自身的线程个数,并提供了同步机制.使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数 ...

  9. java多线程编程题之连续打印abc的几种解法

    一道编程题如下: 实例化三个线程,一个线程打印a,一个打印b,一个打印c,三个线程同时执行,要求打印出6个连着的abc 题目分析: 通过题意我们可以得出,本题需要我们使用三个线程,三个线程分别会打印6 ...

随机推荐

  1. 使用批处理(bat)脚本对目录树下同种性质的目录或文件进行处理

    问题起源:每次从svn管理的目录下面复制目录之后里面总是有很多.svn的目录,虽说不影响使用但看着很碍眼.同时自己也懒得使用svn的export功能. 因此一个简单的批处理脚本可以帮助我们搞定一切,当 ...

  2. 【C语言入门教程】4.10 综合实例 - 媒体播放器

    4.10.1 建立播放列表 数据字典 名称 数据类型 说明 MAX_LENGTH 符号常量 用于定义数组长度,表示列表最大长度 MAX_FILE_LENGTH 符号常量 用于定义数组长度,表示文件名最 ...

  3. java常量池存放在哪里

    运行以下方法: public class Test { public static void main(String[] args) { String str = "abc"; c ...

  4. Ubuntu编译PHP7问题

    安装编译依赖 sudo apt-get -y install build-essential git autoconf sudo apt-get build-dep php5 sudo apt-get ...

  5. Javascript高级程序设计——函数

    函数Function 通过函数封装多条语句,在任何地方执行.javascript函数不会重载,相同名字函数,名字属于后定义的函数通过function关键词声明. function functionNa ...

  6. 关于outerWidth()属性

    在写代码的时候,获取元素的宽度通常用到这个属性.此属性具有如下特点: 1.默认情况下,它的值为所有后代元素(含此元素本身)中最大的宽度值. 2.若某后代元素的display属性为none,那么在计算的 ...

  7. 自动布局之autoresizingMask使用详解(Storyboard&Code)

    自动布局之autoresizingMask使用详解(Storyboard&Code) http://www.cocoachina.com/ios/20141216/10652.html 必须禁 ...

  8. sql执行顺序

    SQL 不同于与其他编程语言的最明显特征是处理代码的顺序.在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后 ...

  9. canvas 中save和restore的用法

    在创建新的控件或修改现有的控件时,我们都会涉及到重写控件或View的onDraw方法. onDraw方法会传入一个Canvas对象,它是你用来绘制控件视觉界面的画布. 在onDraw方法里,我们经常会 ...

  10. maven简单配置

    maven-3.3.9下载 Maven是一个项目管理和综合工具.Maven提供了开发人员构建一个完整的生命周期框架.开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周 ...