基础题

1 、面向对象的特征主要有哪些

  • 抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而是选择其中一部分,暂时不用部分细节。抽象包括两个部分 ,一是抽象过程,而是数据抽象。
  • 继承: 继承是一种联结类的层次模型,并且允许和鼓励类重用,他提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类的继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或新增新的方法使之更加适合特殊需求。
  • 封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义好的方法。面向对象计算始于这一概念,即现实世界可以被描述成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
  • 多态性:多态性是指允许不同的类的对象对同一消息做出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活性、抽象、行为共享、代码共享的优势,很好的解决了应用函数同名问题。

2、作用域 public ,private ,protected ,以及不写时的区别

作用域

当前类

同包

子类

其他类

public





protected




×

default



×

×

private


×

×

×

default 为不写是

3、String 是最基本数据类型吗?

不是,字符的基本类型为char

4、float 型 float f=3.4; 是否正确

不正确,精准度不准确,应当强制转类型——> float f =(float) 3.4;

5、short s1 =1; s1=s1+1;有什么错?
short s1 ==1;s1=s1+1; s1+1 运算结果为int 型,需要强制转换;short s1 =1; s1 += 1 ;可以正确编译,自动类型提升。

6、Java 有没有goto?

goto 是java 中保留字,现在没有在java 中使用。

7、int 和Integer 区别

Java 中提供两种不同的类型:引用类型和原始类型 int 为原始数据类型,Integer 是Java 为 int 提供的封装类。Java为每个原始类型提供了封装类。
原始类型有: boolean,char,float,byte,short,int,long,double
封装类型有:Boolean,Character,Float,Byte,Short,Integer,Long,Double
引用型类型和原始类型的行为完全不用,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题。这种类型以哪种数据结构存储,当引用类型和原始数据类型作用某一个类的实例数据时所制定的缺省值。对象引用实例变量的缺省值为null,而原始类型实例变量的缺省值与它们的类型有关。

8、Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

答案: 12 、11
方法返回与参数最接近的长整数 相当于四舍五入。

9、&和&& 区别

& 是位运算符,表示按位与运算,&& 是逻辑运算符,表示逻辑与(and)
在做逻辑判断时 && 还具有短路功能 如果第一个为 false 就不进行下一个判断了,&还会对下一个进行判断。

String a ="sunbird";
if(a!=null & a!="sun"){
 sysout.println.out("判断了两次");
}
if(a!=null && a=="sun"){
 sysout.println.out("判断了两次");
}eles{
 sysout.println.out("a!=null 为false  后面的不去管了");
}

10、heap 和 stack 有什么区别?

都是用来存放数据的地方:二者区别在于:

stack(栈) 栈是一种线性集合,其添加和删除元素的操作应在同一端完成,栈按照的是先进先出的方式进行处理。存在栈中的数据大小与生存周期必须要确定的,缺乏灵活性。栈取数据比堆速度块,仅次于直接位于CPU中的寄存器。
heap(堆) 堆是栈的一个组成元素。可以动态的分配内存大小,生存期也可以不必事先告诉编译器,Java 的垃圾收集器会自动回收不再使用的数据。

11、swtich 是否能作用在byte上,是否能够在long 上,是否能作用在String 上

答:java 5 swtich (express) 中 ,express 是一个整数表达式。因此传递给switch 和case 语句的参数应该是 int 、short 、char 或者 byte 。long 和 String 不支持
java7 swtich (express。因此传递给switch 和case 语句的参数应该是 int 、short 、char 或者 byte、 String 。long 不支持 。但是不建议使用String 类型,缺点是可读性差、后维护复杂麻烦、在程序中多次出现字符串常量是不好的现象。

12、最有效的计算2乘以8

2<<3

13、数组有没有length()方法?String 有没有length()这个方法?

答:数组没有length () 方法,但是有length 属性。String 有length()方法。

14、在Java 中,如何跳出当前的多重嵌套循环

答:在最外层循环前加label 标识,然后用break:label方法即可跳出多重循环。

15、分析:Java 采用自动垃圾回收技术(GC) ,因此不会出现内存泄漏

对象的建立和放置都是在堆栈上面进行的,程序或者其他对象可以锁定一块堆栈地址来进行其他对象的引用,
当一个对象没有任何引用的时候Java的GC 就发挥了作用,自动删除这个对象占有的空间,释放内存避免内存泄漏,但是内存泄漏并不是就此完全避免了,当程序员忘记解除一个对象不应该有的引用时候,内存泄漏依旧不可避免,不过发生的概率比不启动垃圾回收机制的C++ 程序少很多。

16、简单描述单子模式(单例模式)的各种不同实现方式,极其各自优缺点。请列举只是两种其他设计模式及应用场景

/* 单例设计模式主要有两种实现方式:懒汉模式 、饿汉模式
  他们实现分别有如下实现:
   饿汉式:
  实现起来简单,没有多线程同步问题
  当Singleton1 被加载的时候 会初始化static 的变量。 静态变量创建并分配内存空间,从这以后static 对象一直占用这段内存。当类卸载时静态变量被摧毁,内存释放。
  */
 public class Singleton1 {
	 private Singleton1 (){} //私有构造方法
	 private static  final Singleton1 single =new Singleton1();//自行实例化
//静态工厂方法
public static Singleton1 getInstance (){
 return single;
}

/*
懒汉式
在多线程情况下保证了线性安全
但是效率低下
*/
 public class Singleton2 {
	 private Singleton2 (){} //私有构造方法
	 private static  Singleton2 single =null;//自行实例化
//静态工厂方法
public synchronized static Singleton1 getInstance (){
 if(single==null){
 	single =new  Singleton2 ();
 	}
 return single;
}
	
}

其他设计模式 :
1、适配器模式
应用场景 :比如说在朋友聚会上遇到一个德国人,可是我不会德语,他不会中文,只要求助我的朋友了,他作为我和德国人的adapt。让我们进行交流。
2、 装饰模式
首先,装饰器的价值在于装饰,他并不影响被装饰类本身的核心功能。在一个继承的体系中,子类通常是互斥的。比如一辆车,品牌只能要么是奥迪、要么是宝马,不可能同时属于奥迪和宝马,而品牌也是一辆车本身的重要属性特征。但当你想要给汽车喷漆,换坐垫,或者更换音响时,这些功能是互相可能兼容的,并且他们的存在不会影响车的核心属性:那就是他是一辆什么车。这时你就可以定义一个装饰器:喷了漆的车。不管他装饰的车是宝马还是奥迪,他的喷漆效果都可以实现。

17、 解析以下代码

String s1 = "Hello";
 String s2 = "Hello";
 System.out.println(s1 == s2); // 输出 true 
 String s3 =new String ("Hello"); 
 String s4 = new String ("Hello");
 System.out.println(s3 == s4); //输出false

为什么两个数据结果不一致:
”Hello“ 是 一个字符串常量,他存在内存的常量池中。而创建s2对象的时候会先到常量池中检查释放存在字符串”Hello“,如果存在,则直接引用已存在的对象。
s3 和 s4 所引用的对象都是通过new 关键字创建的,会在堆中分别创建。这两个引用的分别指向不同的对象。 ”==“ 只有两个变量同时指向同一个对象才返回true。

18、String 和 StringBuffer 、StringBuilder区别?

String 的长度是不可变的;StringBuffer 的长度是可变的,如果你对字符串中的内容经常进行操作,特别是内容需要修改时应该使用StringBuffer,如果是最后需要String,那么使用StringBuffer 的 toString () 方法; 线程安全。 StringBuilder 不是线程安全的,为StringBuffer改类补充了一个单个线程使用的等价类。由于它不执行同步,所以速度更快。

19、Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值的类型?

方法的重写Overriding 和重载Overloading 是Java 多态性的不同表现。重写Overriding 是父类与子类之间多态性的一种表现,重载Overloading 是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded 的方法是可以改变返回值的类型。

20 描述JVM 加载class 文件的原理机制

JVM 中类装载是由ClassLoader 和他的子类来实现的,Java ClassLoader是一个很重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

21、char 型变量中能不能存贮一个中文汉字?为什么?
能够定义为一个中文,因为java中以Unicode 编码,一个char 占16给字节,所以存贮一个中文没有问题。

22、abstract class 和 interface 有什么区别
声明方法的存在而不去实现它的类叫抽象类(abstract class)。然而可以创建一个变量,其类型是一个抽象类,它用于要创建一个体现某些基本行为的类,并为该类声明方法,但是不能在该类中实现改类的情况。不能创建abstract 类的实例并让它指向具体子类的一个实例。不能有抽象构造函数或者抽象静态方法。Abstract类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类取而代之,在子类中实现该方法。知道其行为的其他类可以在类中实现这些方法。
接口(interface) 是抽象类的变体。新型多继承性可以通过实现这样的接口而获得。接口中的所有方法都是抽象的,所有成员变量都是 public staict final 的(静态常量)。一个类可以是西安多个接口,当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将 生效。引用就可以转换到接口类型或者从接口类型转换,instanceof 运算符就可以用来决定某一对象类是否实现接口。

23、Java中会存在内存泄漏吗?
会,存在无用但可达对象,这些对象无法被GC回收,导致消耗内存资源。

24、abstract 的 方法是否同时是static ,是否同时是native ,是否可同时是synchronized?
都不能

25、静态变量和实例变量的区别
静态变量也称为类变量,归全类共有,它不依赖某个对象,可以通过类名直接访问;而实例变量必须依赖某一实例,只能通过对象才能访问。
26、是否可以从一个static 方法内部发出对非static 方法调用? **
不可以,如果其中包含对象额method(),不能保证对象初始化。
27、GC 是什么?为什么要有GC?
GC(Gabage Collection) 是垃圾收集器,主要是内存处理。编程人员容易出现问题的地方,或者忘记的内存回收内存导致程序或者系统不稳定甚至崩溃,Java 提供的GC 功能可以自动检测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法,Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用System.gc();或者Runtime.getRuntime().gc();
** 28、垃圾回收的优点和原理 并且考虑两种回收机制

Java 语言中一个显著的特点就是引入垃圾回收机制,可以让程序员不必要去考虑内存泄漏。
原理 : 垃圾回收机制是在JVM 上面的,存在一个堆的空间存放内存。在堆中JVM 进行GC,堆可以分为两个区域(新生代、老年代)这两个区域都可以GC ,老年代GC 新生代必定GC ,新生代GC 老年代不一定GC 。对象GC 大多数都是在新生代GC 【朝生夕死】 而新生代 又分为两个区 Eden 和Survivor 区 Survivor 分为 S0 和 S1。GC 是对于已经死亡或者长时间未使用的对象进行GC 。
机制: 标记-整理 ,复制,标记-清除 等。

29、Java 中会存在内存泄漏吗?
会 存在内存泄漏。
一般来说内存泄漏存在两种情况:
1、堆分配的内存在没有将其释放的情况下,就将其能访问这块内存的方式都删掉了,
2、内存已经不需要的时候,还仍然保留着这块内存和它的访问方式。
第一种情况在引入Java 垃圾回收得到很好的处理。内存溢出主要是第二种情况。
例如
我们循环申请Object 对象,并将所申请的对象放入一个List 中。如果我仅仅释放引用本身,那么List 仍然引用该对象,所以这个对象GC 来说 是不可回收的。

List list = new ArrayList(10);
		for(int i =1; i<100;i++){
			Object o =new Objetc();
			list.add(o);
			o=null;
		}

30、Java 中的异常处理机制的简单原理和应用?
当Java 程序违反了Java 语义规则时,Java虚拟机就会将发生错误表示为一个异常。违反语义包括2种情况。一种是Java 类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException ;访问为null 对象会引发为Null PointerException。另外一种情况就是Java允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有异常都是java.lang.Thowable子类。
31、error 和exception 有什么区别?
error 表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可指望程序能处理这样的情况:exception 表示需要捕捉或者需要程序进行处理的异常,是一种设计或者实现问题;也就是说,它表示如果程序运行正常,从不会发生情况。
32、try{} 里面有一个return 语句,那么紧跟在这个try后的finlly {}里的代码会不会执行,什么时候执行?
会执行,在return。

33、 Java 语言如何处理异常,关键字:throws ,throw ,try ,catch , finally 分别代表什么意义?在try 块中可以抛出异常吗?
Java 通过面向对象的方式进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java 中,每一个异常都是一个对象,它是Throwable 类或者其它子类的实例。当一个方法出现异常后便抛出一个异常对象,对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java的异常处理通过五个关键字来实现的: try 、catch 、throw 、throws 、finally。一般情况下用try 来执行一段程序,如果出现异常,系统会抛出(throws ) 一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;try 用来指定一块预防所有“异常”的程序;catch 子句紧跟在try 块后面,用来指定你想要捕捉的“异常”的类型;throw 语句用来明确地抛出一个“异常”;throws 用来标明一个成员函数可能抛出的各种“异常”;Finally 为确保一段代码不管发生什么“异常”都被执行一段代码;可以在一个成员函数调用的外面写一个try 语句,在这个成员函数内部写另一个try 语句保护其他代码。每当遇到一个try 语句,“异常”的框架就放到堆栈上面,直到所有的try 语句都完成。如果下一级的try 语句没有对某种“异常”进行处理,堆栈就会展开,直到遇到有处理这种“异常”的try 语句。

34、final, finally, finalize 的区别? 【基础】
答:final:修饰符(关键字);如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承,因此一个类不能既被声明为abstract的,又被声明为final 的;将变量或方法声明为final,可以保证它们在使用中不被改变;被声明为final 的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改;被声明为final 的方法也同样只能使用,不能重载。finally:再异常处理时提供finally 块来执行任何清除操作;如果抛出一个异常,那么相匹配的catch 子句就会执行,然后控制就会进入finally 块(如果有的话)。finalize:方法名;Java 技术允许使用finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object 类中定义的,因此所有的类都继承了它。子类覆盖finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

35、介绍JAVA 中的Collection FrameWork(及如何写自己的数据结构)【基础】
答:Collection FrameWork 如下:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection 是最基本的集合接口,一个Collection 代表一组Object,即Collection 的元素(Elements); Map 提供key 到value 的映射。

36、 说出Array List ,Vector ,LinkedList 的存储性能和特性

  • ArrayList : 使用的是动态数组方式存储数据,此数据元素大于实际存储,这样以便于增加和插入元素,可以直接按照序号索引元素,但是插入元素要涉及元素的移动等内存操作所以查询快于插入。
  • Vector 和ArrayList 差不多 但是使用了synchronized 方法 线程安全 ,所以性能上较差于ArrayList ,
  • LinkedList 使用的是双向链表存储,按照序号索引数据需要进行向前或者向后遍历,但是插入数据时只要记录本项的前后即可,所以插入速度较块。

37 Collection 和 Collections 的区别

  • Collection 是java.util 下的接口 ,它是各种集合的父类接口,继承它的接口主要有List 、Set 。
  • Collections 是java.util 下的类 ,针对集合的帮助类,提供一系列的静态方法对各种集合搜索、排序、线程安全化操作。

38、HashMap 和 HashTable 区别
答: 两者都是实现了Map 接口,是将唯一键映射到特定的值上,两者区别:

  • HashMap 具有无序性、允许一个null的键和多个为 null ,而HashTable 不允许。
  • HashMap 没有contains 方法,改为了containsvalue 和 containsKey,
  • HashTable 继承自Distionary 类 ,HashMap 是 Java 1.2 引进的Map 接口的实现。
  • HashTable 方法是synchronized 的,而HashMap 不是,在多个线程访问Hashtable 时,不需要自己为它实现同步方法,而Hash Map需要额外的提供同步,Hashtable 和 HashMap 采用hash/rehash 算法大致一样,所以性能差异不是很大。

39、用程序给出随便大小的是个数,序号为 1-10 按大小排列,并输出响应的序号

public class RandomSort{
	 	
	 	 public static void printRandomBySort(){
	 	   //生成随机数
	 	   Random random  =new Random();
	 	   List list =new ArrayList();// 存储数
			for(int i =0 ;i<10;i++){
			  list.add(random.nextInt(1000));//生成1000以内的是个随机数
			 }
			 Collections.sotr(list);// 对集合进行排序
			 Iterator it =list.iterator();
			 int count =0;
			 whlie(it.hasNext()){
			   System.out.println(count+":"+it.next());
			  }
	 	 }
  	public staic void main (String[] args){
    printRandomBySort();
   	}	
 }

基本算法

40 使用二分查找法查询字符串数组{“a”,“b”,“c”,“d”,“e”,“f”,“g”,“h”} 中的 g 元素

public class Query4Half {

    public	static int bsearch(String [] arr ,String v){
        int start=0; //最小数下标
        int  last =arr.length -1; //最大数下标
        while ( start <=last ){//确保不重复查询
            //计算中间索引值
            int mid =(last+start)>>>1;
            if(arr[mid].compareTo(v)==0){
                return mid;
            }else if (arr[mid].compareTo(v)>0){ //根据字母排序来匹配大小
                last=mid -1;
             }else{
                start=mid +1;
         }
    }
        return  -1;
}
    public static void main(String[] args) {
        String arr [] ={"a","b","c","d","e","f","g","h"};
        System.out.println(bsearch(arr,"g"));
    }
 }

41、简单说明一下什么是递归?什么情况下会使用递归?并且使用Java实现一个简单的递归程序
参考答案:
1、递归做为一种算法在程序设计语言中广泛应用,是指函数/过程/子程序在运行过程中直接货简介调用自身而产生的重入现象。
2、递归算法一般用于解决三类问题:

  1. 数据定义是按递归定义的。(斐波那契函数)
  2. 问题解法按递归实现。(回溯)
  3. 数据的结构形式是按递归定义的。(树遍历和图的搜索)

3、递归算法实现某个整数在二进制中的个数。

/**
 *  计算二进制中1的个数
 * N 为奇数。二进制中1的个数等于N/2的个数
 */
 public static int getBinary(int num){
 	if(num==1)
 		return 1;
 		if(0==num%2){
 			return getBinary(num/2);
 		}else{
		return getBinary(num/2)+1;
	}
 }

42、请写出n!的算法

public class Factorial {
	public static long doFactiorial(long n){
		if(n<1){
			return 0;
			}else if(n == 1 || n ==2){
			return n;
		  }else{
		 return n* doFactorial(n-1);
  		}
	}	
}

43、排序都有哪几种方法

排序的方法有:插入排序(直接插入排序、希尔排序)、交换排序(冒泡排序、快速排序)、选择排序(直接选择排序、堆排序)、归并排序、分配排序(箱排序、基数排序)。

44、写一个排序算法,将10个 1-100随机数进行排序。

public class SelectSort{
	
	//选择排序方法
	public static void selectionSort(int [] number){
 		for (int i = 0 ;  i < number.length - 1; i++){
 		 int m =i; // 设置一个标识 用来交换大小比较
 		  	for ( int j = i + 1; j < number.length; j++){
 		  	  	// 前面一位大于后面一位
 		  	  	if(number[j] < number[m]){
 		  	  	// 修改标识
					 m=j;
					}
 		  	}
 		  	// 前面一位大于后面一位时
 		  	if(i != m){
 		  	//交换位置
 		  	 swap(number ,i ,m);
 		  	}
 		}
  }	
  
  //用于交换数组索引位置
  public static viod swap(int [] number ,int i, int j){
  	int t ;
  	t =number [i];
  	number[i] = number[j];
  	number[j] =t;
  } 
	
  }

45 、 冒泡算法

public class  BubbleSort{
	
	public static void  bubbleSort(int[] arr){
			for(int i = 0; i <  arr.length-1 ; i++){//循环数组长度 ,每一次循环找出最大值
				for(int y = 0 ; y <arr.length - i - 1 ;y++){//
				 	if(arr[y + 1] <  arr[y]){
				 	 int t =arr[y];
					arr[y]=arr[y +1] ;
					arr[y +1] =t;
					 	}
				}
			}
	}

}

46、快速排序

public class QuickSort  {
      public  static void sort(int [ ] number) {
    	quickSort(number,0,number.length - 1 );
    }
 
 private static  void quickSort(int [] number ,int left ,int right){
     		if(left < right){
			        int s =number[left];
	        		int i = left ;
			       int j = right + 1;
		     	while (true){
			        //向右找大于 s 的 数的索引
			         while (i + i < number.length && number[++i] < s);
			        while (j + i < -1 && number[--j] > s);
			       if(i  >= j){
			             break;
			        }
			        swap(number , i ,j);
			  } 
			     number[left] = number[j];
			     number[j] = s;
			 // 对左边进行递归
			 quickSort(number, left, j -1);
			 // 对右边进行递归
			 quickSort(number, j + 1, right);
			}
	}
		
           //用于交换数组索引位置
          public static viod swap(int [] number ,int i, int j){
         	int t ;
         	t =number [i];
         	number[i] = number[j];
        	number[j] =t;
     } 


 
/*//方式二:减少交换次数,提高效率/*/
private<TextendsComparable<?superT>>voidquickSort(T[]targetArr,intstart,intend){
   			inti=start,j=end;
			Tkey=targetArr[start];
		while(i<j){
		/*按j--方向遍历目标数组,直到比key小的值为止*/
    		while(j>i&&targetArr[j].compareTo(key)>=0){
 					j--;
           }
    		if(i<j){
	  		/*targetArr[i]已经保存在key中,可将后面的数填入*/
	  				targetArr[i]=targetArr[j];
					i++;
   				  }
		/*按i++方向遍历目标数组,直到比key大的值为止*/
		while(i<j&&targetArr[i].compareTo(key)<=0){
		/*此处一定要小于等于零,假设数组之内有一亿个1,0交替出现的话,而key的值又恰巧是1的话,那么这个小于等于的作用就会使下面的if语句少执行一亿次。*/
					i++;
								}
		if(i<j){
/*targetArr[j]已保存在targetArr[i]中,可将前面的值填入*/
		targetArr[j]=targetArr[i];
			j--;
			}
		}
		/*此时i==j*/
		targetArr[i]=key;//应加判断
		/*递归调用,把key前面的完成排序*/
		this.quickSort(targetArr,start,i-1);
		/*递归调用,把key后面的完成排序*/
		this.quickSort(targetArr,j+1,end);
		//两个递归应加判断
		}

}

线程基础

47、sleep() 和wait() 的区别 ?

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

48、当一个线程进入一个对象的一个synchronized 方法后,其他线程是否可进入此对象的其他方法?

答:其它线程只能访问该对象的其它非同步方法,同步方法则不能进入。

49、请说出你所知道的线程同步的方法。

使用wait() 使得一个线程进入等待状态、并且释放所持的对象的lock; sleep() 使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException 异常;notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM 确定唤醒哪个线程,而且不是按优先级;
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。(生产者和消费者模式);

/**
	* 定义一个中间仓库 存放信息
	*
	**/
 public class MyStorage{
		
		// 定义容器
		private static List<Object> list = new ArryList<Object>; // 保存容器
		
		private static final MAX_SIZE = 10 ; // 容器最大存储

   /**
   *  定义存储
   * @parm object 存储的信息
   **/
	public void save(Object object){
			
		synchronized (MyStorage .class){
			while(list.size()>10){// 只有 list 数量小于或等于10  才生产
				System.out.println("生产者"+Thread.currentThread().getName()+" waiting");  
                 this.wait();  
			 }
			 list.add(object);
		}
	}
}