1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?

Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。

2.“static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?

“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。 Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。

3.是否可以在static环境中访问非static变量?

static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

4.Java支持的数据类型有哪些?什么是自动拆装箱?

Java语言支持的8种基本数据类型是: • byte • short • int • long • float • double • boolean • char 。
自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成double,等等。反之就是自动拆箱。

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

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

6.Java支持多继承么?

不支持,Java不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。

7.接口和抽象类的区别是什么?

Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:
• 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
• 类可以实现很多个接口,但是只能继承一个抽象类
• 类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
• 抽象类可以在不提供接口方法实现的情况下实现接口。
• Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
• Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
• 接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
也可以参考JDK8中抽象类和接口的区别

8.什么是值传递和引用传递?

对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。

9.创建线程有几种不同的方式?你喜欢哪一种?为什么?

有三种方式可以用来创建线程:
• 继承Thread类
• 实现Runnable接口
• 应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。

10.同步方法和同步代码块的区别是什么?

在Java语言中,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上的锁。synchronized关键字可应用在方法级别(粗粒度锁:这里的锁对象可以是This)或者是代码块级别(细粒度锁:这里的锁对象就是任意对象)。

11.什么是死锁(deadlock)?

两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷入了无限的等待中。
synchronized在开发中最好不要嵌套使用,一不小心可能会导致死锁现象的发生。
代码表示:

Public class deadlock{Public static void main(String[] args){Object o1 = new Object();Object o2 = new Object();//t1和t2两个线程共享o1和o2Thread t1 = new MyClass1(o1,o2);Thread t2 = new MyClass2(o1,o2);}
}
Class MyClass1 extends Thread{Object o1;Object o2;Public MyClass1(Object o1, Object o2){This.o1 = o1;This.o2 = o2;}Public void run(){Synchronized(o1){Try{Thread.sleep(1000);}catch(InterruptedException e){E.printStackTrace();}Synchronized(o2){}}}
}
Class MyClass2 extends Thread{Object o1;Object o2;Public MyClass2(Object o1, Object o2){This.o1 = o1;This.o2 = o2;}Public void run(){Synchronized(o2){Try{Thread.sleep(1000);}catch(InterruptedException e){E.printStackTrace();}Synchronized(o1){}}}
}

12.如何确保N个线程可以访问N个资源同时又不导致死锁?

使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

13.Java集合类框架的基本接口有哪些?

Java集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。Java集合类里面最基本的接口有:
• Collection:代表一组对象,每一个对象都是它的子元素。
• Set:不包含重复元素的Collection。
• List:有顺序的collection,并且可以包含重复元素。
• Map:可以把键(key)映射到值(value)的对象,键不能重复。

14.什么是迭代器(Iterator)?

Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。

15.Iterator和ListIterator的区别是什么?

下面列出了他们的区别:
• Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
• Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
• ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。

16.Java中的HashMap的工作原理是什么?

Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合/从集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)。

17.HashMap和Hashtable有什么区别?

HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
• HashMap允许键和值是null,而Hashtable不允许键或者值是null。
• Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
• HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。 一般认为Hashtable是一个遗留的类。

18.数组(Array)和列表(ArrayList)有什么区别?什么时候应该使用Array而不是ArrayList?

下面列出了Array和ArrayList的不同点:
• Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
• Array大小是固定的,ArrayList的大小是动态变化的。
• ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
• 对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。

19.ArrayList和LinkedList有什么区别?

ArrayList和LinkedList都实现了List接口,他们有以下的不同点:
• ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素链表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
• 相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
• LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。 也可以参考ArrayList vs. LinkedList。

20.如何权衡是使用无序的数组还是有序的数组?

有序数组最大的好处在于查找的时间复杂度是O(log n),而无序数组是O(n)。有序数组的缺点是插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)。

21.HashSet和TreeSet有什么区别?

HashSet是由一个hash表来实现的,因此,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。
另一方面,TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是O(logn)。

22.Java中垃圾回收有什么目的?什么时候进行垃圾回收?

垃圾回收的目的是识别并且丢弃应用不再使用的对象来释放和重用资源。

23.如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?

不会,在下一个垃圾回收周期中,这个对象将是可被回收的。

24.String是最基本的数据类型吗?

基本数据类型包括byte、int、char、long、float、double、boolean和short。 java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类

25.int 和 Integer 有什么区别?

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。

26.String 和StringBuffer的区别?

JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。

27.说出ArrayList,Vector, LinkedList的存储性能和特性?

ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而 Linke dList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
List的子类特点:
ArrayList:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
Vector:
底层数据结构是数组,查询快,增删慢
线程安全,效率低
LinkedList:
底层数据结构是链表,查询慢,增删快
线程不安全,效率高

28.Collection和Collections的区别

Collection是集合类的上级接口,继承于他的接口主要有Set和List。
Collections是针对集合类的一个帮助类,他提供一些列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

29.&和&&的区别。

&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。

30.final,finally,finalize的区别。

final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的方法可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

31.sleep()和wait()有什么区别??

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

32.error和exception有什么区别?

Error表示恢复不是不可能但是很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能够处理这种情况。
Exception表示一种设计或实现问题。也就是说它表示如果程序运行正常,从不会发生的情况。

33.同步和异步有何异同,在什么情况下分别使用它们?举例说明。

如果数据将在线程间共享,例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

34.GC是什么?为什么要有GC?

GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,java提供的GC功能可以自动检测对象是否超过作用域从而达到自动回收内存的目的,java语言没有提供释放已分配内存的显示操作方法。

35.short s1=1;s1 = s1+1;有什么错?Short s1=1;s1 += 1;有什么错?

Short s1=1;s1 =s1+1;(s1+1运算结果是int类型,需要强制转换类型)
Short s1=1;s1 += 1;(可以正确编译,+=内置运算符运算时可以自动变换数据类型)

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

Math.round(11.5)=12;
Math.round(-11.5)=-11;
round方法返回与参数最接近的长整数,参数加1/2后求其floor。

37.String s = new String(“xyx”);创建了几个String Object?

两个,一个是在堆内存中创建s对象,一个是在字符串常量池中创建“xyx”。

38.接口是否可以继承接口?抽象类是否可以实现(implements)接口?抽象类是否可以继承实体类(concrete class)?

接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可以继承实体类,但前提是实体类必须有明确的构造函数。

39.List,Set,Map是否继承自Collection接口?

List,Set是,Map不是。

40.abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

都不能。

41.是否可以继承String类?

String类是final类故不可以继承。

42.switch是否能作用在byte上,是否能作用在long上?是否能作用在String上?

Switch(expr1)中,expr1是一个整数表达式。因此传递给switch和case语句的 参数应该是int、short、char或者byte。long,String都不能作用于switch(1.7版本之后switch语句支持String类型)

43.try{}里面有一个return语句,那么紧跟在这个try后面的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?

会执行,在return前执行(finally中程序一定会被执行,return结束后程序结束,所以肯定在之前执行)(如果在try中程序终止了或者死循环就不会执行finally中的语句块)

44.两个对象值相同(x.equals(y)==true),但却可有不同的hash code,这句话对不对?

不对,有相同的hash code。(hash code内部也是根据对象来做处理)

45.当一个线程进入一个对象的synchromized方法之后,其他线程是否可进入此对象的其他方法?

不能,当一个线程进入一个对象的synchronized方法后,其他线程可以进入此对象的非synchronized方法,不能进入synchronized方法,都是同一锁(同步代码块时对象锁可以是任何对象,同步方法时对象锁只能是this对象所以无法访问其他方法)

46.编程题:写一个Singleton出来

Singleton模式主要作用是保证在java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种形式:
第一种形式:
定义一个类,它的构造函数为private的 ,它有一个static的private的该类变量,在类初始化时实例化,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。

Public class Singleton{Private Singleton(){}//在自己内部定义一个自己的实例,是不是很奇怪?//注意这是private只供内部调用Private static Singleton instance = new Singleton();//这里提供了一个供外部访问本class的静态方法,可以直接访问Public static Singleton getInstance(){Return instance;}
}

第二种形式:

Public class Singleton{Private static Singleton instance  = null;Public static synchronized Singleton getInstance(){//这个方法比上面有所改进,不能每次都进行生成对象,只是第一次//使用时生成实例,提高了效率if(instance==null) instance = new Singleton();Return instance;}
}

其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全些。

47.java的接口和C++的虚类的相同和不同处。

由于java不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面的所有方法和属性,并且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是public,一个类可以实现多个接口。

待续…

48.java中的异常处理机制的简单原理和应用。

当java程序违反了java的语义规则时,java虚拟机就会将发生的错误表示为一个异常。违反语义规则包括两种情况。一种是java类库内置的语义检查,例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NULLPointerException。另一种情况是java允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

49.垃圾回收的优点和原理,并考虑2种回收机制。

Java语言中一个显著的特点就是引入了垃圾回收机制,使C++程序员最头疼的内存管理问题迎刃而解,它使得java程序员在编写程序的时候不需要考虑内存管理。由于有个垃圾回收机制,java中的对象不再有“作用域”的概念,只有对象引用才有“作用域”。垃圾回收可以有效防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。垃圾回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

50.char型变量中能不能存储一个中文汉字?为什么?

能够定义成为一个中文的,因为java中以unicode编码,一个char占2个字节,所以放一个中文是没问题的。

51.多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

多线程有两种实现方法,分别是继承Thread类和实现Runnable接口。
同步的实现方法有两种,分别是同步代码块和同步方法。

52.线程的基本概念、线程的基本状态以及状态之间的关系。

线程是指程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身。
Java中的线程有五种状态,分别是:新建、就绪、运行、阻塞、结束。

53.简述synchronized和java.util.concurrent.locks.Lock的异同?

主要相同点:Lock能完成synchroniezd所实现的所有功能。
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。
Lock是一个类,synchronized是一个关键字。
synchronized会自动释放锁,而Lock一定要求程序员手动释放,并且必须在finally从句中释放。

54.java语言如何进行异常处理?关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

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

55.一个“java源文件”中是否可以包含多个类(不是内部类)?有什么限制?

可以,必须只有一个类名与文件名相同。最多只有一个public类且public类的类名与文件名相同。

56.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

字节流、字符流。字节流继承于InputStream\OutputStream,字符流继承于InputStreamReader\OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。

57.java中会存在内存泄露吗?请简单描述。

会。如:int i,i2;return (i-i2);//when i为足够大的正数,i2为足够大的负数。结果会造成溢出,导致错误。(内存泄露不包括整型溢出)
内存泄露指对象脱离了JVM GC 的控制。

58.java中实现多态的机制是什么?

父类型引用指向子类型对象这种机制导致程程序存在编译阶段绑定和运行阶段绑定两种不同的形态/状态,这种机制可以称为一种多态语法机制。
方法的重写Overriding和重载Overloading是java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。

59.垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是“可达的”,哪些对象是“不可达的”。当GC确定一些独享为“不可达”时,GC就有责任回收这些内存空间。
垃圾回收器可以马上回收内存。
程序员可以手动执行System.gc();通知GC运行,但是java语言规范并不保证GC一定会执行。

60.什么是java序列化,如何实现java序列化?

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

61.是否可以从一个static方法内部发出非static方法的调用?

不可以,如果其中包含对象的method();不能保证对象初始化。

62.List、Map、Set三个接口,存取元素时,各有什么特点?

List 有序可重复
Set 无法拥有重复元素,内部排序
Map保存key-value值,value可多值。

63.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

使用final关键字修饰一个变量时,是指引用变量不能变,引用白能量所指向的对象中的内容还是可以改变的。例如,对于如下语句:
Final StringBuffer a = new StringBuffer(“immutable”);
执行如下语句将报告编译期错误:
a = new StringBuffer(“”);
但是,执行如下语句则可以通过编译:
a.append(“broken”);

有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:
Public void method(final StringBuffer param){
}
实际上,这是办不到的,在该方法内部任然可以增加加如下代码修改参数对象:
Param.append(“a”);

64.请说出作用域public,private,protected,以及不写时的区别。

四个作用域的可见范围如下表所示:
说明:如果在修饰元素上面没有写任何访问修饰符,则表示friendly。
作用域 当前类 同一package 子孙类 其他package
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
备注:只要记住了有四种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上分别安排从小到大或者从大到小的顺序排列,就很容易画出上面的图。

65、线程如何同步和通讯?

线程同步:
什么是线程同步?
当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一个数据导致数据不一致),所以我们用同步机制来解决这些问题。
使用同步机制有两个方法:
1、同步代码块:synchronized(同一个数据){}
同一个数据:就是N条线程同时访问一个数据。
2、同步方法:public synchronized 数据返回类型 方法名(){}
就是使用synchronized来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是this也就是该对象的本身(这里指的对象本身优点含糊,其实就是调用该同步方法的的对象),通过使用同步方法,可非常方便的将某类变成线程安全的类。
线程通讯:
为什么要用线程通讯?
当使用synchronized来修饰某个共享资源时(分同步代码块和同步方法两种情况),当某个线程获得共享资源的锁后就可以执行相应的代码块,直到该线程运行完该代码块后才释放该共享资源的锁,让其他线程有机会执行对该共享资源的修改。当某个线程占有某个共享资源的锁时,如果另外一个线程也想获得这把锁运行时就需要使用wait()和notify()/notifyAll()方法来进行线程通讯了。

66.String s=“hello”;s = s + “world”;这两行代码执行之后,原始的String对象中的内容到底变了没有?

没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是“hello”,然后我们对s进行+操作,那么s所指向的那个对象是否发生改变呢?答案是没有。这时,s不指向原来的对象了,而是指向另一个String对象,内容为“hello world”,原来的那个都想还存在内存之中,只是s这个引用变量不再指向它了。

67.String和StringBuffer的区别。

Java平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。String类表示内容不可改变的字符串。而StringBuffer类表示内容可以被修改的字符串。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。另外,String实现了equals方法,new String(“abc”).equals(new String(“abc”))的结果为true,而StringBuffer没有实现equals方法,所有new Stringbuffer(“abc”).equals(new String(“abc”))的结果为false。

68.StringBuffer和StringBuilder的区别。

StringBuffer和StringBuilder类都表示内容可以被修改的字符串,StringBuilder是线程不安全的,运行效率高,如果一个字符串变量是在方法区里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素,则用StringBuilder。如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用StringBuffer。

69.数组有没有length()这个方法?String有没有length()这个方法?

数组没有length()方法,有length属性。String有length()这个方法。

70.下面的程序代码输出的结果是多少?

Public class smallT{Public static void main(String[] args){smallT t = new smallT();int b = t.get();System.out.println(b);}Public int get(){Try{Return 1;}finally{Return 2;}}
}

返回结果是2.

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

//以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题
Public class ThreadTest1{Private int j;Public static void main(String[] args){ThreadTest1 tt = new ThreadTest1();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();}}Private synchronized void inc(){j++;System.out.println(Thread.currentThread().getName()+“-inc:”+j);}Private synchronized void dec(){j--;System.out.println(Thread.currentThread().getName()+“-dec:”+j);}Class Inc implements Runnable{Public void run(){For(int i=0;i<100;i++){inc();}}}Class Dec implements Runnable{Public void run(){For(int i=0;i<100;i++){dec();}}}
}

72.heap和stack有什么区别。

Java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈的变量也会随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

73.写一单实例类要求精简、清晰。

懒汉模式:

Public class SingletonDemo{private static SingletonDemo instance;Private static SingletonDemo(){}Public static SingletonDemo getInstance(){If(instance == null){Instance = new SingletonDemo();}Return instance;}
}

如上,通过提供一个静态的对象instance,利用private权限的构造方法和getInstance()方法来给予访问者一个单例。

74.一列数的规则如下:1,1,2,3,5,8,13,21,34…求第30位数是多少,用递归算法实现。

Public class Test{Public static void main(String[] args){System.out.println(“结果是:”+ Test.foo(30));}
/*递归算法的实现
*/Public static int foo(int i){If(i<=0){Return 0;}else if(i>0 && i<=2){Return 1;}Return foo(i-1) + foo(i-2);}
}

75.面试题:final修饰局部变量的问题

基本类型:基本类型的值不能发生改变。
引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。

Class Student{Int age =10;
}
Class FinalTest{Public static void main(String[] args){//局部变量是基本数据类型int x=10;x=100System.out.println(x);//100final int y = 10;//无法为最终变量y分配值//y=100;报错System.out.println(y);//10//局部变量是引用数据类型Student s = new Student();System.out.println(s.age);//10s.age=100;System.out.println(s.age);//100final Student ss = new Student();System.out.println(ss.age);//10ss.age=100;System.out.println(ss.age);//100//重新分配内存空间//无法为最终变量ss重新分配值//ss = new Student();报错}
}

76.多态中成员访问的特点。

多态:同一个对象(事物),在不同时刻体现出来的不同状态。
举例:猫是猫,猫是动物。水(液体,固体,气体)
多态的前提:
A:要有继承关系。
B:要有方法重写。
其实没有也可以,但是如果没有方法重写的话就没有意义。
动物 d = new 猫();//读的时候从右往左读(也可以这样理解猫是new出来的对象,而左边是一个类。所以相当于判断一个对象是不是这个类的实例)猫是猫,猫是动物。
D.show();
动物 d = new 狗();
D.show();
C:要有父类引用指向子类对象
父 f = new 子();

用代码体现一下多态。
多态中的成员访问特点:
A:成员变量
编译看左边,运行看左边
B:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
C:成员方法
编译看左边,运行看右边
由于成员方法存在方法重写,所以它运行看右边。
D:静态方法
编译看左边,运行看左边
(静态和类相关,算不上重写,所有还是左边的)

77.为什么集合类没有实现Cloneable和Serializable接口?

克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者序列化。
实现Serialization序列化的作用
1、将对象的状态保存在存储媒体中以便可以在以后重写创建出完全相同的复本。
2、按值将对象从一个应用程序域发向另一个应用程序域。
实现Serializable接口的作用就是可以把对象存到字节流,然后可以恢复。所以如果对象没有序列化,怎么才能进行网络传输?要网络传输就得转为字节流,所以在分布式应用中就得实现序列化。如果不需要分布式应用,那就没必要实现序列化。

Cloneable标识一个类可以被克隆,Serializable标识一个类可以被序列h化,集合的接口没有实现这两个接口,但是集合具体的类是有实现这两个接口的。接口不是具体的容器,所以不需要实现这两个接口,也没有意义。

78.自动装箱的原理

Java中提供了八种基本数据类型,同时提供了这八种基本数据类型对应的引用数据类型。
*自动装箱:基本数据类型的数据自动转化为对应的引用数据类型的数据。
*自动拆箱:引用数据类型的数据自动转化为对应的基本数据类型的数据。

底层原理以int与Integer类型为例:
*自动装箱:实际上调用的是Integer中的静态方法valueOf(),将基本数据类型的int数值包装成一个Integer对象。
Integer integerVal = 0;
//等效于
Integer integerVal = Integer.valueOf(0);
*自动拆箱:实际调用的是Integer对象的intValue(),得到对象内的int变量的数值,然后赋值给变量。
Int intVal = new Integer(0);
//等效于
Int intVal = new Integer(0).intValue();
*自动装箱的时候,存在一个数据缓存池问题,数据在一定范围内使用的是缓存池中在程序启动的时候创建好的对象,超出范围才是直接new对象。
*此外,除了基本数据类型使用“==”号判断相等外,引用数据类型一定要使用equals()方法来判断相等(除了特殊情况下需要比对是否为同一个对象的情况下)

79.什么时候Mysql调用行锁?

DML语句末尾加for update.
调用存储过程中,就会涉及到表锁,行锁的概念,这两个的区别:
有索引的时候就是行锁,没有索引的时候就是表锁。
innodb的行锁是在有索引的情况下,没有索引的表是锁定全表。

80.内部类,外部类互访

内部类又称为嵌套类,可以把内部类理解为外部类的一个普通成员。
内部类访问外部类:
里面的可以自由访问外面的,规则和static一样。(访问非静态时必须创建对象)。具体如下:
*非静态内部类的非静态方法:直接访问

Public class Outter{int i=5;static String string=“hello”;Class Inner1{void Test1(){System.out.println(i);System.out.println(string);}}
}

*静态内部类的非静态方法:因为静态方法访问非静态外部成员需先创建实例,所以访问i时必须先new外部类。

Public class Outter{int i = 5;static String string = “hello”;static class Inner2{void Test2(){System.out.println(new Outter().i);System.out.println(string);}}
}

*静态内部类的静态方法:规则如上

Public class Outter{int i = 5;static String string = “hello”;static class Inner3{static void Test2(){System.out.println(new Outter().i);System.out.println(string);}}
}

外部类访问内部类:
大方向:因为将内部类理解为外部类的一个普通成员,所以外面的访问里面的需先new一个对象。
*非静态方法访问非静态内部类的成员:new内部类对象

Public class Outter{void test1(){System.out.println(new Inner1().i);}Class Inner1{int i=5;}
}

*静态方法访问非静态内部类的成员:静态方法test2访问非静态Inner1需先new外部类;继续访问非静态成员i需先new内部类,所以访问规则为:new Outter().new Inner1().i;

Public class Outter{static void Test2(){System.out.println(new Outter().new Inner1().i);}Class Inner{Int = 5;}
}

附:为什么非静态内部类有可能造成内存泄漏?
因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。
*非静态方法访问静态内部类的成员:先“外部类.内部类”访问至内部类。若访问静态成员,则需先new再访问;若访问非静态成员,则可直接访问。

Public class Outter{void Test1(){Outter.Inner2 inner2 = new Outter.Inner2();System.out.println(inner2.i);System.out.println(inner2.string);System.out.println(Outter.Inner2.string)}static class Inner2{int i=5;static String string = “hello”;}
}

匿名内部类:
匿名内部类访问外部成员变量时,成员变量前面应该加final关键字。

final int k =6;
((Button)findViewById(R.id.button2)).setOnClickListener(new onClickListener(){@overridePublic void onClick(View v){System.out.println(k);}
});

81.深拷贝,浅拷贝

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,则认为是深拷贝。
方法:实现Cloneable接口,并重写clone()方法。

82.泛型擦除

什么是泛型?
泛型是为了参数化类型,或者说可以将类型当做参数传递给一个类或者方法。这个参数一旦确定,如果类型不匹配,编译器就不通过。
泛型有什么用?
1.与普通的Object代替一切类型这样简单粗暴而言,泛型使得数据的类别可以像参数一样由外部传递进来。它提供一种扩展能力。更符合面向抽象开发的软件编程宗旨。
2.当具体的类型确定之后,泛型又提供了一种类型检测的机制,只有相匹配的数据才能正常的赋值,否则编译器就不通过。所以说,它是一种类型安全检测机制,一定程度 上提高了软件的安全性放置出现低级的失误。
3.泛型提高了程序代码的可读性,不必要等到运行的时候才去强制转换,在定义或者实例化阶段,因为Cache这个类型显化的效果,程序员能够一目了然猜测出代码要操作的数据类型。
什么是类型擦除?
泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。
类型擦除带来的局限性:
类型 擦除会抹掉很多继承相关的特性。利用类型擦除原理,用反射的手段绕过正常开发中编译不允许的操作限制。

83.Java8 Stream,函数编程

待续…

84.start和run的区别

1.start():
API中对该方法的介绍:使线程开始执行;java虚拟机调用该线程的run方法。
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类德尔start方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到CPU时间片,就开始执行run方法,这里的run方法称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即结束。
2.run():
API中对该方法的介绍:
如果该线程使用独立的Runnable运行对象构造的,则调用该Runnable对象的run方法;否则,该方法不执行任何操作并返回。
Thread子类应该重写该方法。
run方法只是类的一个普通方法而已,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用run方法可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。

85.JVM内存屏障

待续…

86.Java构造器能被重载,但是不能被重写

首先,构造器不能被继承,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承。又由于构造器不能被继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的。

87.Thread类的方法

待续…

88.String是值类型,还是引用类型

String是引用类型。
例如:String a = “123”;String a = new String(“123”);
两式的不同之处:
*前者的String对象分配在堆中,但在常量池中保存了指向String对象的指针,而a为String型指针,指针的内容和常量之中“123”对应的指针相同,具体来说,执行过程如下:
首先,常量池中查找“123”的指针
如果在常量池中未能找到“123”的指针,则在堆中分配“123”的内存空间,把地址保存到常量池中,并把这个地址赋值给String型指针a。
如果在常量池中找到“123”的指针,说明堆中已经存在“123”的实体,因为常量表示一个不可变的对象,所以,没有必要再创建新的实例,直接把常量池中的指针内容赋值给String型指针a。
*而后者,实际上涉及到两个String实体,“123”在堆中存在一个实体,并且在常量池中存在一个指向“123”的指针,而new String()会在堆中创建一个新的String实体,并深度拷贝“123”的内容,并返回新的String实体的地址,赋值给指针a。

89.Java如何查看死锁

1、死锁产生的原因:当两个或者多个线程互相持有一定的资源,并互相等待其他线程释放资源而形成的一种僵局,就是死锁。
2、Jconsole查看死锁:进入java安装的位置,输入jconsole,然后弹出界面(或者进入安装目录/java/jdk1.70_80/bin/,点击Jconsole.exe)–>新建连接deadlockTest–>点击进入–>点击检测死锁–>然后可以看到造成死锁的两个线程,以及死锁原因。
3、Jstack查看死锁:在DOS命令窗口中进入jdk安装目录,输入jps,先查看我们要检测死锁的进程–>然后可以看到Test的进程号:8384,然后执行:Jstack -l 8384查看死锁信息。
4、死锁预防:
1.以确定的顺序获得锁:如果必须获取多个锁,那么在设计的时候需要充分考虑不同线程之前获得锁的顺序。
2.超时放弃:当使用synchronized关键字提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然后Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放已经获得的所有的锁。通过这种方式,也可以有效地避免死锁。
5、其他形式的死锁:
线程池死锁,解决方法:扩大线程池程数or任务结果之间不再互相依赖。
网络连接池死锁。

90.Count(1),count(*),count(列名)的执行区别

Count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL
Count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL
Count(列名)只包含列名那一行,在统计结果的时候,会忽略列值为空(这里的空不是空字符串或者0,而是NULL)的计数,即某个字段值为NULL,不统计。
执行效率上:
列名为主键,count(列名)会比count(1)快
列名不为主键,count(1)比count(列名)快
如果表多个列并没有主键则count(1)的执行效率优于count(*)
如果有主键,则select count(主键)的执行效率是最优的
如果表只有一个字段,则select count(*)最优。

91.主键,唯一检索区别

(1)主键一定会创建一个唯一索引,但是有唯一索引的列不一定是主键
(2)主键不允许为空值,唯一索引列允许空值
(3)一个表只能有一个主键,但是可以有多个唯一索引
(4)主键可以被其他表引用为外键,唯一索引列不可以
(5)主键是一种约束,而唯一索引是一种索引,是表的冗余数据结构,两者有本质的差别

92.死锁:

产生死锁的四个必要条件:
*互斥条件:一个资源每次只能被一个进程使用。
*占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
*不可强行占有:进程已获得的资源,在未使用完之前,不能强行剥夺。
*循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

93.乐观锁,悲观锁

JDK提供了AtomicInteger保证对数字的操作是线程安全的。关于线程安全还有synchronized和lock,但是这种方式又有一个名字,叫做互斥锁,一次只能有一个持有锁的线程进入,再加上还有不同线程争夺锁这个机制,效率比较低,所以又称“悲观锁”。
但是相应的有乐观锁的概念,它的思路就是,不加锁去完成某项操作,如果因为冲突就重试,直到成功为止。

94.公平锁,非公平锁

公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得。
非公平锁(Nonfair):加锁时不考虑排队等待问题,直到尝试获取锁,获取不到自动排队到队尾等待。
非公平锁性能比公平锁高5~10倍,因为公平锁需要在多核的情况下维护一个队列
Java中的ReentrantLock默认的lock()方法采用的是非公平锁。

95.synchronized实现原理

造成线程安全问题的主要诱因有两点:一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。在java中,关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块存在共享数据的操作),同时我们应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程看到(保证可见性,完全可以代替Volatile功能),这点确实重要。
synchronized的三种应用方式:
*修饰实例方法,作用于当前实例加锁,进入同步代码块前要获得当前实例的锁。
*修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。
*修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码块前要获取给定对象的锁。

96.Synchronized,lock的区别

*Thread的几个重要方法:
a、start()方法,调用该方法开始执行该线程;
b、stop()方法,调用该方法强制结束该线程的执行;
c、join方法,调用该方法等待该线程结束;
d、sleep()方法,调用该方法进入等待;
e、run()方法,调用该方法直接执行线程的run方法,但是线程调用start方法也会运行run方法,区别就是一个直接调用了线程中的run方法,一个是由线程调度运行run方法。
注意:wait()和notify()是Object的方法,不是Thread的方法,同时,wait()和notify()会配合使用,分别表示线程挂起和线程恢复。

*线程的五大状态:
新建状态:新建线程对象,并没有调用start方法
就绪状态:调用start方法之后线程就进入就绪状态,但是并不是说只要调用start方法线程就马上变为当前线程,在变为当前线程之前都是就绪状态。值得一提的是,线程在睡眠和挂起中恢复的时候也会进入就绪状态。
运行状态:线程被设置为当前线程,开始执行run方法,就是线程进入运行状态。
阻塞状态:线程被暂停,比如说调用sleep方法后线程就会进入阻塞状态
死亡状态:线程执行结束

*锁类型:
可重入锁:在执行对象中所有同步方法不用再次获得锁
可中断锁:在等待获取锁的过程中可中断
公平锁:等待获取锁的线程的等待时间进行获取,等待时间长的具有优先获取锁的权利
读写锁:对资源读取和写入的时候拆分为2部分处理,读的时候可以多线程一起读,写的时候必须同步地写。

*synchronized与lock的区别

类别 Synchronized Lock
存在层次 Java的关键字,在jvm层面上 是一个类
锁的释放 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 在finally中必须释放锁,不然会造成线程死锁
锁的获取 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 分情况而定,Lock有多个锁获取的方式,大致就是可以尝试获得锁,线程可以不用一直等待
锁状态 无法判断 可以判断
锁类型 可重入,不可中断,非公平 可重入,可判断,可公平(两者皆可)
性能 少量同步 大量同步

97.如何停止线程?

*主线程提供volatile boolean flag,线程内while判断flag
*线程内while(!This.isInterrupted),主线程里调用interrupt
*if(this.isInterrupter) throw new InterruptedException()或者return
主线程里调用interrupt
*将一个线程设置为守护线程后,当进程中没有非守护线程后,守护线程结束。

98.多线程实现方式?

*extends Thread
*implements Runnable
*implements Callable,重写call,返回future(主线程可以用线程池submit)

100.线程池:

*线程池的处理过程是怎样的?
如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(注意,执行这一步骤需要获取全局锁)。
如果运行的线程等于或多于corePoolSize,则将任务加入BlockingQueue。
如果无法将任务加入BlockingQueue(队列已满),则创建新的线程来处理任务(注意,执行这一步骤需要获取全局锁)。
如果创建新线程将使当前运行的线程超出maximumPoolSize,任务将被拒绝,并调用RejectedExecutionHandler.rejectedExecution()方法。

*有哪四种线程池?
CachedThreadPool
FixedThreadPool
ScheduledThreadPool
SingleThreadExecutor

*创建线程池的参数有哪些?
corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有基本线程。
runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。可以选择以下几个阻塞队列。
ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO(先进先出)原则对元素进行排序。
LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于Linked-BlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
PriorityBlockingQueue:一个具有优先级的无限阻塞队列。 maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是,如果使用了无界的任务队列这个参数就没什么效果。
ThreadFactory:用于设置创建线程的工厂
RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。

在JDK 1.5中Java线程池框架提供了以下4种策略。
AbortPolicy:直接抛出异常。
CallerRunsPolicy:只用调用者所在线程来运行任务。 DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
DiscardPolicy:不处理,丢弃掉。

101.ArrayList和LinkedList对比

ArrayList初始化可以指定大小,知道大小的建议指定 arraylist添加元素的时候,需要判断存放元素的数组是否需要扩容(扩容大小是原来大小的1/2+1)
LinkedList添加、删除元素通过移动指针 LinkedList遍历比arraylist慢,建议用迭代器 ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
对于随机访问get和set,ArrayList优于LinkedList,因为ArrayList可以随机定位,而LinkedList要移动指针一步一步的移动到节点处。(参考数组与链表来思考)
对于新增和删除操作add和remove,LinedList比较占优势,只需要对指针进行修改即可,而ArrayList要移动数据来填补被删除的对象的空间。

102.HashMap的实现原理?

HashMap最多只允许一条Entry的键为Null(多条会覆盖),但允许多条Entry的值为Null
HashSet 本身就是在 HashMap 的基础上实现的.
若负载因子越大,那么对空间的利用更充分,但查找效率的也就越低;若负载因子越小,那么哈希表的数据将越稀疏,对空间造成的浪费也就越严重。系统默认负载因子0.75
调用put方法存值时,HashMap首先会调用Key的hashCode方法,然后基于此获取Key哈希码,通过哈希码快速找到某个桶,这个位置可以被称之为bucketIndex.如果两个对象的hashCode不同,那么equals一定为false;否则,如果其hashCode相同,equals也不一定为 true。所以,理论上,hashCode可能存在碰撞的情况,当碰撞发生时,这时会取出bucketIndex桶内已存储的元素,并通过hashCode() 和 equals()来逐个比较以判断Key是否已存在。如果已存在,则使用新Value值替换旧Value值,并返回旧Value值;如果不存在,则存放新的键值对<Key, Value>到桶中。因此,在 HashMap中,equals() 方法只有在哈希码碰撞时才会被用到。
首先,判断key是否为null,若为null,则直接调用putForNullKey方法;若不为空,则先计算key的hash值,然后根据hash值搜索在table数组中的索引位置,如果table数组在该位置处有元素,则查找是否存在相同的key,若存在则覆盖原来key的value,否则将该元素保存在链头(最先保存的元素放在链尾)。此外,若table在该处没有元素,则直接保存。 HashMap 永远都是在链表的表头添加新元素。

java面试题(无序版)相关推荐

  1. Java面试题2017版

    Java面试宝典2017版 一. Java基础部分---------------------------------- 7 1.一个".java"源文件中是否可以包括多个类(不是内 ...

  2. Java面试题基础版

    一.Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java ...

  3. 牛客java面试题总结版(四)

    18.Java集合类框架的基本接口有哪些? 官方版: 集合类接口指定了一组叫做元素的对象.集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序.有的集合类允许重复的键,有些不允许 ...

  4. 牛客java面试题总结版(三)

    13.概括的解释下线程的几种可用状态. 官方版: 新建( new ):新创建了一个线程对象. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 star ...

  5. 牛客java面试题总结版(二)

    6.Java中的方法覆盖(Overriding)和方法重载(Overload)是什么意思? 官方版:Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况.与此相对,方 ...

  6. 牛客java面试题总结版(一)

    1.什么是Java虚拟机(JVM)?为什么Java被称作是"平台无关的编程语言"? 官方版:Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Jav ...

  7. java面试题2016_2016最新java面试题 详细版

    详解笔试面试题集 (1)下列各题ABCD四个选顼中,只有一个选项是正确的,请将正确选项填写在答题纸上 (1)下列关于栈的描述中错误的是( ) A. 栈是先进后出的线性表 B 栈只能顺序存储 C 栈具有 ...

  8. Java面试题大全(Android版)

    疯狂Java面试题大全(Android版) Java核心技术部分 Java核心技术部分的面试题,可能覆盖Java基本语法.面向对象(包括类定义.方法.构造器.递归.继承.抽象类.接口.枚举以及fina ...

  9. 疯狂Java面试题大全(Android版)

    疯狂Java面试题大全(Android版) 本大全每个月会定期更新,索取网址:http://www.fkjava.org Java核心技术部分 Java核心技术部分的面试题,可能覆盖Java基本语法. ...

  10. java面试题大全答案版文库_java高级面试题带答案

    java高级面试题,java面试题大全带答案,线程面试题,java面试宝典2019 1.[请对以下在J2EE中常用的名词进行解释(或简单描述)](http://www.wityx.com/post/1 ...

最新文章

  1. ​Leangoo在线SaaS模式的产品结构
  2. OS study plan
  3. C++ Primer 第三章 字符串、向量和数组
  4. CSS基本选择器(元素选择器、类选择器、id选择器)
  5. Java基础--通过反射获取成员方法并使用
  6. Caffe: Caffe的Python接口
  7. linux mysql 删除表脚本_linux shell脚本自动删除mysql表前3个月的数据
  8. 洛谷 P1656 炸铁路
  9. 公钥与私钥 数字签名是什么?
  10. Python自定义模块
  11. 华为认证hcia含金量_华为hcna认证含金量高吗?
  12. 04:AD采样【MSP430F5529】
  13. 跨境电商必看:amazon账号关联因素
  14. 挖掘:如何用迅雷下载4399小游戏站内的所有游戏
  15. 虚拟机没有USB网卡选项怎么解决
  16. 贝努利概率 matlab
  17. 什么是Bugzilla
  18. 安装Matlab R2022a/64位
  19. 西安腾讯云面试总结(已拿offer)
  20. 带外数据:TCP紧急模式分析

热门文章

  1. SAP中采购收货控制中的配置问题分析
  2. 斗拱展开面积表_古建筑斗拱换算问题
  3. The web application [] appears to have started a thread named [thread-0]
  4. 《计算机网络》学习笔记----第七版课后习题参考答案 第三章
  5. 找到一个在线网站截图的网站
  6. 社保能找公司代缴吗?小心问题找上门
  7. 化学反应中的能量变化
  8. 【图书管理系统】附源码+教程
  9. DevOps运维自动化工具系统平台
  10. 对比分析方法,数据异动的假设,如何找出羊毛党