百度Java面试题前200页和答案都在这里了
其中题目来源github.com/tangyouhua/program-resource/blob/master/program-interview/java-baidu-200.md,答案我自己整理的。
有兴趣可以加入我QQ群 368614849(大型网站架构技术交流),
操作系统中 heap 和 stack 的区别
什么是基于注解的切面实现
什么是 对象/关系 映射集成模块
什么是 Java 的反射机制
什么是 ACID
BS与CS的联系与区别
Cookie 和 Session的区别
fail-fast 与 fail-safe 机制有什么区别
get 和 post请求的区别
Interface 与 abstract 类的区别
IOC的优点是什么
IO 和 NIO的区别,NIO优点
Java 8 / Java 7 为我们提供了什么新功能
什么是竞态条件? 举个例子说明。
JRE、JDK、JVM 及 JIT 之间有什么不同
MVC的各个部分都有那些技术来实现?如何实现?
RPC 通信和 RMI 区别
什么是 Web Service(Web服务)
JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。
WEB容器主要有哪些功能? 并请列出一些常见的WEB容器名字。
一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制
简单说说你了解的类加载器。是否实现过类加载器
解释一下什么叫AOP(面向切面编程)
请简述 Servlet 的生命周期及其相关的方法
请简述一下 Ajax 的原理及实现步骤
简单描述Struts的主要功能
什么是 N 层架构
什么是CORBA?用途是什么
什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”
什么是正则表达式?用途是什么?哪个包使用正则表达式来实现模式匹配
什么是懒加载(Lazy Loading)
什么是尾递归,为什么需要尾递归
什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)
关键字
finalize
什么是finalize()方法
finalize()方法什么时候被调用
析构函数(finalization)的目的是什么
final 和 finalize 的区别
final
final关键字有哪些用法
final 与 static 关键字可以用于哪里?它们的作用是什么
final, finally, finalize的区别
final、finalize 和 finally 的不同之处?
能否在运行时向 static final 类型的赋值
使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变
使用final关键字修饰一个引用变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
一个类被声明为final类型,表示了什么意思
认为该类已经达到完美,完全没有必要再去修改它,用final关键字。
不希望该类被继承,用final关键字修饰。
throws, throw, try, catch, finally分别代表什么意义
Java 有几种修饰符?分别用来修饰什么
volatile
volatile 修饰符的有过什么实践
答:1,线程1执行doWork()的过程中,可能有另外的线程2调用了shutdown,所以boolean变量必须是volatile。
2,独立观察,定期 “发布” 观察结果供程序内部使用。【例如】假设有一种环境传感器能够感觉环境温度。一个后台线程可能会每隔几秒读取一次该传感器,并更新包含当前文档的 volatile 变量。然后,其他线程可以读取这个变量,从而随时能够看到最新的温度值。
3,线程安全的计数器,使用 synchronized 确保增量操作是原子的,并使用 volatile 保证当前结果的可见性。如果更新不频繁的话,该方法可实现更好的性能,因为读路径的开销仅仅涉及 volatile 读操作,这通常要优于一个无竞争的锁获取的开销。
4,单例双检锁
总结一下,可以分为5个:作为状态位发布;一次性安全发布;独立观察;volatile bean模式;开销较低的读写锁策略。
volatile 变量是什么?volatile 变量和 atomic 变量有什么不同
答:1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
//线程1
boolean stop = false;
while(!stop){
doSomething();
}
//线程2
stop = true;
这个代码能够把线程中断,但是也有可能会导致无法中断线程。每个线程在运行过程中都有自己的工作内存,那么线程1在运行的时候,会将stop变量的值拷贝一份放在自己的工作内存当中。那么当线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,那么线程1由于不知道线程2对stop变量的更改,因此还会一直循环下去。但是用volatile修饰之后就变得不一样了:第一:使用volatile关键字会强制将修改的值立即写入主存;第二:使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效);第三:由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1再次读取变量stop的值时会去主存读取。那么线程1读取到的就是最新的正确的值。
happens-before规则中的volatile变量规则,但是要注意,线程1对变量进行读取操作之后,被阻塞了的话,并没有对inc值进行修改。然后虽然volatile能保证线程2对变量inc的值读取是从内存中读取的,但是线程1没有进行修改,所以线程2根本就不会看到修改的值。自增操作是不具备原子性的,它包括读取变量的原始值、进行加1操作、写入工作内存。
volatile 类型变量提供什么保证?能使得一个非原子操作变成原子操作吗
答:volatile 变量提供顺序和可见性保证,例如,JVM 或者 JIT为了获得更好的性能会对语句重排序,但是 volatile 类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。 volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。
某些情况下,volatile 还能提供原子性,如读 64 位数据类型,像 long 和 double 都不是原子的,但 volatile 类型的 double 和 long 就是原子的。
volatile修饰的变量如果是对象或数组之类的,其含义是对象获数组的地址具有可见性,但是数组或对象内部的成员改变不具备可见性:
能创建 volatile 数组吗?
答: volatile修饰的变量如果是对象或数组之类的,其含义是对象获数组的地址具有可见性,但是数组或对象内部的成员改变不具备可见性
:
transient变量有什么特点
答:
我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。
然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
super什么时候使用
答:子类的构造函数中不是必须使用super,在构造函数中,如果第一行没有写super(),编译器会自动插入.但是如果父类没有不带参数的构造函数,或这个函数被私有化了(用private修饰).此时你必须加入对父类的实例化构造.而this就没有这个要求,因为它本身就进行实例化的构造.
如果父类的构造函数是无参的,那子类构造函数会在第一行默认调用super().
下面这种情况是必须调用super()的:
1 public class Father {
2 public String name;
3 public Father(String name) {
4 this.name = name;
5 }
6 }
7
8 class Son extends Father{
9 public Son(String name) {
10 super(name);
11 }
12 //必须调用,否则他会默认调用父类的无参构造函数,而父类的无参构造函数已经被有参的覆盖,所以找不到
public static void 写成 static public void会怎样
说明一下public static void main(String args[])这段声明里每个关键字的作用
请说出作用域public, private, protected, 以及不写时的区别
sizeof 是Java 的关键字吗
static
static class 与 non static class的区别
内部静态类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。
非静态内部类能够访问外部类的静态和非静态成员。静态类不能访问外部类的非静态成员。他只能访问外部类的静态成员。
一个非静态内部类不能脱离外部类实体被创建,一个非静态内部类可以访问外部类的数据和方法,因为他就在外部类里面。
static 关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法
Static表示静态的意思,可用于修饰成员变量和成员函数,被静态修饰的成员函数只能访问静态成员,不可以访问非静态成员。静态是随着类的加载而加载的,因此可以直接用类进行访问。 重写是子类中的方法和子类继承的父类中的方法一样(函数名,参数,参数类型,反回值类型),但是子类中的访问权限要不低于父类中的访问权限。重写的前提是必须要继承,private修饰不支持继承,因此被私有的方法不可以被重写。静态方法形式上可以被重写,即子类中可以重写父类中静态的方法。但是实际上从内存的角度上静态方法不可以被重写。
静态类型有什么特点
答案:1、随着类的加载而加载
也就是说:静态会随着类的消失而消失,说明他的生命周期最长
2、优先于对象存在
3、被所有对象所共享
4、可以直接被类名调用
main() 方法为什么必须是静态的?能不能声明 main() 方法为非静态
答案:所有static成员都是在程序装载时初始化的,被分配在一块静态存储区域。这个区域的成员一旦被分配,就不再改变地址啦。直到程序结束才释放。main()就存储在这里。尽管包含main()的类还没有被实例化,但是main()方法已经可以使用啦。而且JVM将会自动调用这个方法。通过main()的调用,再实例化其他的对象,也包括自己所在的类。
是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用
静态变量在什么时候加载?编译期还是运行期?静态代码块加载的时机呢
答案:当类加载器将类加载到JVM中的时候就会创建静态变量,这跟对象是否创建无关。静态变量加载的时候就会分配内存空间。静态代码块的代码只会在类第一次初始化的时候执行一次。一个类可以有多个静态代码块,它并不是类的成员,也没有返回值,并且不能直接调用。静态代码块不能包含this或者super,它们通常被用初始化静态变量。
成员方法是否可以访问静态变量?为什么静态方法不能访问成员变量
答案:可以。static成员是在JVM的CLASSLOADER加载类的时候初始化的,而非static的成员是在创建对象,即new 操作的时候才初始化的;类加载的时候初始化static的成员,此时static 已经分配内存空间,所以可以访问;非static的成员还没有通过new创建对象而进行初始化,所以必然不可以访问。
简单点说:静态成员属于类,不需要生成对象就存在了.而非静态需要生成对象才产生,所以静态成员不能直接访问.
switch
switch 语句中的表达式可以是什么类型数据
switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上
while 循环和 do 循环有什么不同
操作符
&操作符和&&操作符有什么区别?
a = a + b 与 a += b 的区别?
逻辑操作符 (&,|,^)与条件操作符(&&,||)的区别
3*0.1 == 0.3 将会返回什么?true 还是 false?
float f=3.4; 是否正确?
short s1 = 1; s1 = s1 + 1;有什么错?
数据结构
基础类型(Primitives)
基础类型(Primitives)与封装类型(Wrappers)的区别在哪里
简述九种基本数据类型的大小,以及他们的封装类
int 和 Integer 哪个会占用更多的内存? int 和 Integer 有什么区别?parseInt()函数在什么时候使用到
float和double的默认值是多少
如何去小数四舍五入保留小数点后两位
char 型变量中能不能存贮一个中文汉字,为什么
类型转换
怎样将 bytes 转换为 long 类型
怎么将 byte 转换为 String
如何将数值型字符转换为数字
我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象
能在不进行强制转换的情况下将一个 double 值赋值给 long 类型的变量吗
类型向下转换是什么
数组
如何权衡是使用无序的数组还是有序的数组 答案:
有序数组最大的好处:在于查找的时间复杂度是O(log n),而无序数组是O(n)。
有序数组的缺点是:插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)。
怎么判断数组是 null 还是为空
怎么打印数组? 怎样打印数组中的重复元素
Array 和 ArrayList有什么区别?什么时候应该使用Array而不是ArrayList 答案:
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
数组和链表数据结构描述,各自的时间复杂度 答案:
1、存取方式上,数组可以顺序存取或者随机存取,而链表只能顺序存取;
2、存储位置上,数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定;
3、存储空间上,链表由于带有指针域,存储密度不如数组大;
4、按序号查找时,数组可以随机访问,时间复杂度为O(1),而链表不支持随机访问,平均需要O(n);
5、按值查找时,若数组无序,数组和链表时间复杂度均为O(n),但是当数组有序时,可以采用折半查找将时间复杂度降为O(logn);
6、插入和删除时,数组平均需要移动n/2个元素,而链表只需修改指针即可;
7、空间分配方面:
数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败;
链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效;
数组有没有length()这个方法? String有没有length()这个方法
队列
队列和栈是什么,列出它们的区别 答案:
队列(Queue):是限定只能在表的一端进行插入和在另一端进行删除操作的线性表;
栈(Stack):是限定只能在表的一端进行插入和删除操作的线性表。
一、规则不同
1. 队列:先进先出(First In First Out)FIFO
2. 栈:先进后出(First In Last Out )FILO
二、对插入和删除操作的限定不同
1. 队列:只能在表的一端进行插入,并在表的另一端进行删除;
2. 栈:只能在表的一端插入和删除。
三、遍历数据速度不同
1. 队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快;
2. 栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。
BlockingQueue是什么 答案:
1.BlockingQueue队列和平常队列一样都可以用来作为存储数据的容器,但有时候在线程当中涉及到数据存储的时候就会出现问题,而BlockingQueue是空的话,如果一个线程要从BlockingQueue里取数据的时候,该线程将会被阻断,并进入等待状态,直到BlockingQueue里面有数据存入了后,就会唤醒线程进行数据的去除。若BlockingQueue是满的,如果一个线程要将数据存入BlockQueue,该线程将会被阻断,并进入等待状态,直到BlcokQueue里面的数据被取出有空间后,线程被唤醒后在将数据存入
2.BlockingQueue定义的常用方法详解:
1)add(anObject):把anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则报异常
2)offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.
3)put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.
4)poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null
5)take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止
3.BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
1)ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的.
2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的 BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含 的对象是以FIFO(先入先出)顺序排序的
3)PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序.
4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的.
4.LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致 LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于 ArrayBlockingQueue.
简述 ConcurrentLinkedQueue LinkedBlockingQueue 的用处和不同之处。 答案:
1.由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
2.LinkedBlockingQueue是一个线程安全的阻塞队列,它实现了BlockingQueue接口,BlockingQueue接口继承自java.util.Queue接口,并在这个接口的基础上增加了take和put方法,这两个方法正是队列操作的阻塞版本。
3.ConcurrentLinkedQueue是无阻塞的队列,可伸缩性比BlockingQueue高。ConcurrentLinkedQueue是Queue的一个安全实现.Queue中元素按FIFO原则进行排序.采用CAS操作,来保证元素的一致性。
4.两个都是线程安全的
ArrayList、Vector、LinkedList的存储性能和特性
String
StringBuffer
ByteBuffer 与 StringBuffer有什么区别
HashMap
HashMap的工作原理是什么 答案:
HashMap的底层是用hash数组和单向链表实现的 ,当调用put方法是,首先计算key的hashcode,定位到合适的数组索引,然后再在该索引上的单向链表进行循环遍历用equals比较key是否存在,如果存在则用新的value覆盖原值,如果没有则插入到链表linkedlist的头部。HashMap的两个重要属性是容量capacity和加载因子loadfactor,默认值分布为16和0.75,当容器中的元素个数大于 capacity*loadfactor时,容器会进行扩容resize 为2n,在初始化Hashmap时可以对着两个值进行修改,负载因子0.75被证明为是性能比较好的取值,通常不会修改,那么只有初始容量capacity会导致频繁的扩容行为,这是非常耗费资源的操作,所以,如果事先能估算出容器所要存储的元素数量,最好在初始化时修改默认容量capacity,以防止频繁的resize操作影响性能。
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用LinkedList来解决碰撞问题,当发生碰撞了,对象将会储存在LinkedList的下一个节点中。 HashMap在每个LinkedList节点中储存键值对对象。
内部的数据结构是什么
HashMap 的 table的容量如何确定?loadFactor 是什么? 该容量如何变化?这种变化会带来什么问题? 答案:
HashMap使用的是懒加载,构造完HashMap对象后,只要不进行put 方法插入元素之前,HashMap并不会去初始化或者扩容table。这个问题可以跟踪一下HashMap的源码就知道了,根据输入的初始化容量(门槛?)的值(先了解HashMap中容量和负载因子的概念,其实这个和HashMap确定存储地址的算法有关),先判断是否大于最大容量,最大容量2的30次方,1<<30 =(1073741824),如果大于此数,初始化容量赋值为1<<30,如果小于此数,调用tableSizeFor方法 使用位运算将初始化容量修改为2的次方数,都是向大的方向运算,比如输入13,小于2的4次方,那面计算出来桶的初始容量就是16.
HashMap 实现的数据结构是什么?如何实现
HashMap 和 HashTable、ConcurrentHashMap 的区别
HashMap的遍历方式及效率
HashMap、LinkedMap、TreeMap的区别 Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
Hashtable与 HashMap类似,它继承自Dictionary类,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。
LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。
TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
一般情况下,我们用的最多的是HashMap,HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。
LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列,像连接池中可以应用。
TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
如何决定选用HashMap还是TreeMap
如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办
HashMap 是线程安全的吗?并发下使用的 Map 是什么,它们内部原理分别是什么,比如存储方式、 hashcode、扩容、 默认容量等
HashSet
HashSet和TreeSet有什么区别 答案:1、TreeSet 是二叉树实现的,Treeset中的数据是自动排好序的,不允许放入null值。 TreeSet是SortedSet接口的唯一实现类,向TreeSet中加入的应该是同一个类的对象。
2、HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。
3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。
HashSet 内部是如何工作的 答案:HashSet 的实现其实非常简单,它只是封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。
WeakHashMap 是怎么工作的? 答案:WeakHashMap当系统内存不足时,垃圾收集器会自动的清除没有在任何其他地方被引用的键值对,因此可以作为简单缓存表的解决方案。而HashMap就没有上述功能。但是,如果WeakHashMap的key在系统内持有强引用,那么WeakHashMap就退化为了HashMap,所有的表项都不会被垃圾回收器回收。但是在WeakHashMap中会删除那些已经被GC的键值对在源码中是通过调用expungeStaleEntries函数来完成的,而这个函数只在WeakHashMap的put、get、size()等方法中才进行了调用。
Set
Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用 == 还是 equals()? 它们有何区别? 答案:当使用HashSet时,hashCode方法就会得到调用,判断已经存储在集合中的对象的hash code值是否与增加的对象的hash code值一致:
1. 如果不一致,直接加进去;
2. 如果一致,再进行equals方法的比较,equals如果返回true,表示对象已经加进去了,就不会再增加新的对象;否则加进去。
TreeMap:TreeMap 是采用什么树实现的?TreeMap、HashMap、LindedHashMap的区别。TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素? 答案:TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。 三者区别参考文章:三者区别
TreeSet:一个已经构建好的 TreeSet,怎么完成倒排序。 答案:A:自然排序:要在自定义类中实现Comparerable<T>接口 ,并且重写compareTo方法
B:比较器排序:在自定义类中实现Comparetor<t>接口,重写compare方法
EnumSet 是什么 答案:Enumset是个虚类,我们只能通过它提供的静态方法来返回Enumset的实现类的实例。使用noneOf方法创建空的EnumSet,使用EnumSet.allOf方法创建一个拥有所有枚举类元素的EnumSet,使用EnumSet.of方法返回拥有部分元素的EnumSet,使用addAll方法,添加一个EnumSet中的所有元素到另外一个EnumSet,使用toArray方法,将EnumSet中的元素存放到数组中去
Hash算法
Hashcode 的作用
简述一致性 Hash 算法 答案:一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
1、平衡性(Balance)
2、单调性(Monotonicity)
3、分散性(Spread)
4、负载(Load)
普通的哈希算法(也称硬哈希)采用简单取模的方式,将机器进行散列,这在cache环境不变的情况下能取得让人满意的结果,但是当cache环境动态变化时,这种静态取模的方式显然就不满足单调性的要求(当增加或减少一台机子时,几乎所有的存储内容都要被重新散列到别的缓冲区中)。
一致性哈希算法的基本实现原理是将机器节点和key值都按照一样的hash算法映射到一个0~2^32的圆环上。当有一个写入缓存的请求到来时,计算Key值k对应的哈希值Hash(k),如果该值正好对应之前某个机器节点的Hash值,则直接写入该机器节点,如果没有对应的机器节点,则顺时针查找下一个节点,进行写入,如果超过2^32还没找到对应节点,则从0开始查找(因为是环状结构)。
有没有可能 两个不相等的对象有相同的 hashcode?当两个对象 hashcode 相同怎么办?如何获取值对象 答案:有。 可以用equal比较值。
为什么在重写 equals 方法的时候需要重写 hashCode 方法?equals与 hashCode 的异同点在哪里
a.hashCode() 有什么用?与 a.equals(b) 有什么关系 答案:
1、hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
2、如果两个对象相同,就是适用于equals(Java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
3、如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
4、两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。
再归纳一下就是hashCode是用于查找使用的,而equals是用于比较两个对象的是否相等的。
hashCode() 和 equals() 方法的重要性体现在什么地方
Object:Object有哪些公用方法?Object类hashcode,equals 设计原则? sun为什么这么设计?Object类的概述 答案:clone,getClass, toString, finalize, equal, hashCode,wait,notify, notifyAll Object类是所有Java类的祖先。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
如何在父类中为子类自动完成所有的 hashcode 和 equals 实现?这么做有何优劣。
可以在 hashcode() 中使用随机数字吗?
答案:不可以。Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。
LinkedHashMap
LinkedHashMap 和 PriorityQueue 的区别是什么 答案:PriorityQueue 保证最高或者最低优先级的的元素总是在队列头部,但是 LinkedHashMap 维持的顺序是元素插入的顺序。当遍历一个 PriorityQueue 时,没有任何顺序保证,但是 LinkedHashMap 课保证遍历顺序是元素插入的顺序。
List
List, Set, Map三个接口,存取元素时各有什么特点
List, Set, Map 是否继承自 Collection 接口
遍历一个 List 有哪些不同的方式
LinkedList
LinkedList 是单向链表还是双向链表
LinkedList 与 ArrayList 有什么区别
描述下 Java 中集合(Collections),接口(Interfaces),实现(Implementations)的概念。LinkedList 与 ArrayList 的区别是什么?
插入数据时,ArrayList, LinkedList, Vector谁速度较快?
ArrayList
ArrayList 和 HashMap 的默认大小是多数 答案:hashMap为16,ArrayList为10.
但是ArrayList比较特殊,只是初始化了10个空的数组。详情参考点击打开链接
ArrayList 和 LinkedList 的区别,什么时候用 ArrayList?
ArrayList 和 Set 的区别?
ArrayList, LinkedList, Vector的区别
ArrayList是如何实现的,ArrayList 和 LinkedList 的区别
ArrayList如何实现扩容 答案:
在JDK1.7中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。
每次按照1.5倍(位运算)的比率通过copeOf的方式扩容。
在JKD1.6中,如果通过无参构造的话,初始数组容量为10.每次通过copeOf的方式扩容后容量为原来的1.5倍加1.以上就是动态扩容的原理。
Array 和 ArrayList 有何区别?什么时候更适合用Array
说出ArraList,Vector, LinkedList的存储性能和特性
Map
Map, Set, List, Queue, Stack
Map 接口提供了哪些不同的集合视图 答案:
Map接口在Java集合中提供三个集合视图:
(1)Set keyset():返回map中包含的所有key的一个Set视图。集合是受map支持的,map的变化会在集合中反映出来,反之亦然。当一个迭代器正在 遍历一个集合时,若map被修改了(除迭代器自身的移除操作以外),迭代器的结果会变为未定义。
(2)Collection values():返回一个map中包含的所有value的一个Collection视图。这个collection受map支持的,map的变化会在 collection中反映出来,反之亦然。当一个迭代器正在遍历一个collection时,若map被修改了(除迭代器自身的移除操作以外),迭代器 的结果会变为未定义。
(3)Set<Map.Entry<K,V>> entrySet():返回一个map钟包含的所有映射的一个集合视图。这个集合受map支持的,map的变化会在collection中反映出来,反之 亦然。当一个迭代器正在遍历一个集合时,若map被修改了(除迭代器自身的移除操作,以及对迭代器返回的entry进行setValue外),迭代器的结 果会变为未定义。
以上集合都支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素 移除,从map中移除对应的映射。它不支持add和addAll操作。
为什么 Map 接口不继承 Collection 接口 答案:
尽管Map接口和它的实现也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map继承Collection毫无意义,反之亦然。
如果Map继承Collection接口,那么元素去哪儿?Map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合“一组对象”规范。
Collections
介绍Java中的Collection FrameWork。集合类框架的基本接口有哪些
Collections类是什么?Collection 和 Collections的区别?Collection、Map的实现
集合类框架的最佳实践有哪些
为什么 Collection 不从 Cloneable 和 Serializable 接口继承
说出几点 Java 中使用 Collections 的最佳实践? 答案:
a)使用正确的集合类,例如,如果不需要同步列表,使用 ArrayList 而不是 Vector。
b)优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性。
c)使用接口代表和访问集合,如使用List存储 ArrayList,使用 Map 存储 HashMap 等等。
d)使用迭代器来循环集合。
e)使用集合的时候使用泛型。
Collections 中 遗留类 (HashTable、Vector) 和 现有类的区别
什么是 B+树,B-树,列出实际的使用场景。
接口
Comparator 与 Comparable 接口是干什么的?列出它们的区别 答案:
1,Comparable
Comparable 定义在 Person类的内部:
public class Persion implements Comparable {..比较Person的大小..},
因为已经实现了比较器,那么我们的Person现在是一个可以比较大小的对象了,它的比较功能和String完全一样,可以随时随地的拿来
比较大小,因为Person现在自身就是有大小之分的。Collections.sort(personList)可以得到正确的结果。
2,Comparator
Comparator 是定义在Person的外部的, 此时我们的Person类的结构不需要有任何变化,如
public class Person{ String name; int age },
然后我们另外定义一个比较器:
public PersonComparator implements Comparator() {..比较Person的大小..},
在PersonComparator里面实现了怎么比较两个Person的大小. 所以,用这种方法,当我们要对一个 personList进行排序的时候,
我们除了了要传递personList过去, 还需要把PersonComparator传递过去,因为怎么比较Person的大小是在PersonComparator
里面实现的, 如:
Collections.sort( personList , new PersonComparator() ).
对象
拷贝(clone)
如何实现对象克隆
深拷贝和浅拷贝区别
深拷贝和浅拷贝如何实现激活机制
写clone()方法时,通常都有一行代码,是什么
比较
在比较对象时,”==” 运算符和 equals 运算有何区别
如果要重写一个对象的equals方法,还要考虑什么
两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对
构造器
构造器链是什么
创建对象时构造器的调用顺序
不可变对象
什么是不可变象(immutable object)
为什么 Java 中的 String 是不可变的(Immutable)
如何构建不可变的类结构?关键点在哪里
能创建一个包含可变对象的不可变对象吗
如何对一组对象进行排序
方法
构造器(constructor)是否可被重写(override)
方法可以同时即是 static 又是 synchronized 的吗
abstract 的 method是否可同时是 static,是否可同时是 native,是否可同时是synchronized 答案:都不可以,因为abstract申明的方法是要求子类去实现的,abstract只是告诉你有这样一个接口,你要去实现,至于你的具体实现可以是native和synchronized,也可以不是,抽象方法是不关心这些事的,所以写这两个是没有意义的。然后,static方法是不会被覆盖的,而abstract方法正是要子类去覆盖它,所以也是没有意义的。所以,总的来说,就是java语法不允许你这样做,事实上,也没有意义这样做。
abstract需要重载,static为类方法,没有重载一说 abstract为没有实现的方法,native为本机实现的方法,自相矛盾 abstract方法没有实现,也不可能实际调用抽象方法,没有必要synchronized修饰,当然子类可以根据需要同步该方法.所以 都不能。
Java支持哪种参数传递类型 答案:Java 应用程序有且仅有的一种参数传递机制,即按值传递。
对象是按引用传递的;
Java 应用程序有且仅有的一种参数传递机制,即按值传递;
按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本;
按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。
一个对象被当作参数传递到一个方法,是值传递还是引用传递 答案:是值传递。Java编程语言中只有由值传递参数的。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递
我们能否重载main()方法
如果main方法被声明为private会怎样
GC
概念
GC是什么?为什么要有GC
什么时候会导致垃圾回收
GC是怎么样运行的
新老以及永久区是什么
GC 有几种方式?怎么配置
什么时候一个对象会被GC? 如何判断一个对象是否存活 答案:参考文章对象是否存活
System.gc() Runtime.gc()会做什么事情? 能保证 GC 执行吗
垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收? 答案:可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
Minor GC 、Major GC、Young GC 与 Full GC分别在什么时候发生 答案:Minor GC
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。
当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。
内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,
取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。
执行 Minor GC 操作时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
质疑常规的认知,所有的 Minor GC 都会触发“全世界的暂停(stop-the-world)”,停止应用程序的线程。对于大部分应用程序,停顿导致的延迟都是可以忽略不计的。
其中的真相就 是,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多。
Major GC 是清理永久代。
Full GC 是清理整个堆空间—包括年轻代和永久代。
垃圾回收算法的实现原理
如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存? 答案:垃圾收集器不会立即释放对象占用的内存,在下一个垃圾回收周期中,这个对象将是可被回收的。
垃圾回收的最佳做法是什么 答案:1、标记-清除算法:
首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。标记过程中 实际上即时上面说的finaLize()的过程。主要缺点一个是效率问题。另外一个是空间问题,标记清除后会产生大量不连续的内存碎片。
2、复制算法:
这种算法将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了。就将还存活着的对象复制到另外一块上面,然后再把已经使用过的内存空间一次清理掉。
3、标记-整理算法:
复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会遍低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以对应被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。
标记过程仍然与标记-清除算法一样,但是后续步骤不是直接将对可回收对象进行清理,而是让所有存活的对象都向领一端移动,然后直接清理掉端边界以外的内存。
4、分代收集算法:
当代商业虚拟机的垃圾收集都采用的是“分代收集算法” ,根据对象的存活周期的不同,将内存化为几块,一般是把java堆分为新生代和老年代。这样就可以根据各个年代的特点采用最合适的收集算法。
新生代选用复制算法,老年代使用标记-清理算法 或者 标记-整理算法。
GC收集器有哪些
垃圾回收器的基本原理是什么?
串行(serial)收集器和吞吐量(throughput)收集器的区别是什么
Serial 与 Parallel GC之间的不同之处
CMS 收集器 与 G1 收集器的特点与区别
CMS垃圾回收器的工作过程
JVM 中一次完整的 GC 流程是怎样的? 对象如何晋升到老年代
吞吐量优先和响应优先的垃圾收集器选择
GC策略
举个实际的场景,选择一个GC策略
JVM的永久代中会发生垃圾回收吗
收集方法
标记清除、标记整理、复制算法的原理与特点?分别用在什么地方
如果让你优化收集方法,有什么思路
JVM
参数
说说你知道的几种主要的jvm 参数 答案:参考几个文章(JVM重要参数配置) 点击打开链接 点击打开链接 点击打开链接
-XX:+UseCompressedOops 有什么作用
类加载器(ClassLoader)
Java 类加载器都有哪些 答案:1)Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2)Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3)App ClassLoader
负责记载classpath中指定的jar包及目录中class
4)Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。
JVM如何加载字节码文件 答案:JVM主要完成三件事:
1、通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件)。而获取的方式,可以通过jar包、war包、网络中获取、JSP文件生成等方式。
2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。这里只是转化了数据结构,并未合并数据。(方法区就是用来存放已被加载的类信息,常量,静态变量,编译后的代码的运行时内存区域)
3、在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。这个Class对象并没有规定是在Java堆内存中,它比较特殊,虽为对象,但存放在方法区中。
内存管理
JVM内存分哪几个区,每个区的作用是什么
一个对象从创建到销毁都是怎么在这些部分里存活和转移的
解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法
JVM中哪个参数是用来控制线程的栈堆栈小
简述内存分配与回收策略
简述重排序,内存屏障,happen-before,主内存,工作内存
Java中存在内存泄漏问题吗?请举例说明
简述 Java 中软引用(SoftReferenc)、弱引用(WeakReference)和虚引用
内存映射缓存区是什么
jstack,jstat,jmap,jconsole怎么用
32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?32 位和 64 位的 JVM,int 类型变量的长度是多数?
怎样通过 Java 程序来判断 JVM 是 32 位 还是 64 位
JVM自身会维护缓存吗?是不是在堆中进行对象分配,操作系统的堆还是JVM自己管理堆
什么情况下会发生栈内存溢出
双亲委派模型是什么
多线程
基本概念
什么是线程
多线程的优点
多线程的几种实现方式
用 Runnable 还是 Thread
什么是线程安全
Vector, SimpleDateFormat 是线程安全类吗
什么 Java 原型不是线程安全的
哪些集合类是线程安全的
多线程中的忙循环是什么
如何创建一个线程
编写多线程程序有几种实现方式
什么是线程局部变量
线程和进程有什么区别?进程间如何通讯,线程间如何通讯
什么是多线程环境下的伪共享(false sharing)
同步和异步有何异同,在什么情况下分别使用他们?举例说明
Current
ConcurrentHashMap 和 Hashtable的区别
ArrayBlockingQueue, CountDownLatch的用法
ConcurrentHashMap的并发度是什么
CyclicBarrier 和 CountDownLatch有什么不同?各自的内部原理和用法是什么
Semaphore的用法
Thread
启动一个线程是调用 run() 还是 start() 方法?start() 和 run() 方法有什么区别
调用start()方法时会执行run()方法,为什么不能直接调用run()方法
sleep() 方法和对象的 wait() 方法都可以让线程暂停执行,它们有什么区别
yield方法有什么作用?sleep() 方法和 yield() 方法有什么区别
Java 中如何停止一个线程
stop() 和 suspend() 方法为何不推荐使用
如何在两个线程间共享数据
如何强制启动一个线程
如何让正在运行的线程暂停一段时间
什么是线程组,为什么在Java中不推荐使用
你是如何调用 wait(方法的)?使用 if 块还是循环?为什么
生命周期
有哪些不同的线程生命周期
线程状态,BLOCKED 和 WAITING 有什么区别
画一个线程的生命周期状态图
ThreadLocal 用途是什么,原理是什么,用的时候要注意什么
ThreadPool
线程池是什么?为什么要使用它
如何创建一个Java线程池
ThreadPool用法与优势
提交任务时,线程池队列已满时会发会生什么
newCache 和 newFixed 有什么区别?简述原理。构造函数的各个参数的含义是什么,比如 coreSize, maxsize 等
线程池的实现策略
线程池的关闭方式有几种,各自的区别是什么
线程池中submit() 和 execute()方法有什么区别?
线程调度
Java中用到的线程调度算法是什么
什么是多线程中的上下文切换
你对线程优先级的理解是什么
什么是线程调度器 (Thread Scheduler) 和时间分片 (Time Slicing)
线程同步
请说出你所知的线程同步的方法
synchronized 的原理是什么
synchronized 和 ReentrantLock 有什么不同
什么场景下可以使用 volatile 替换 synchronized
有T1,T2,T3三个线程,怎么确保它们按顺序执行?怎样保证T2在T1执行完后执行,T3在T2执行完后执行
同步块内的线程抛出异常会发生什么
当一个线程进入一个对象的 synchronized 方法A 之后,其它线程是否可进入此对象的 synchronized 方法B
使用 synchronized 修饰静态方法和非静态方法有什么区别
如何从给定集合那里创建一个 synchronized 的集合
锁
Java Concurrency API 中 的 Lock 接口是什么?对比同步它有什么优势
Lock 与 Synchronized 的区别?Lock 接口比 synchronized 块的优势是什么
ReadWriteLock是什么?
锁机制有什么用
什么是乐观锁(Optimistic Locking)?如何实现乐观锁?如何避免ABA问题
解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁 答案查看文章
什么时候应该使用可重入锁
简述锁的等级方法锁、对象锁、类锁 答案:
对象锁(方法锁),是针对一个对象的,它只在该对象的某个内存位置声明一个标识该对象是否拥有锁,所有它只会锁住当前的对象,一般一个对象锁是对一个非静态成员变量进行synchronized修饰,或者对一个非静态成员方法进行synchronized进行修饰,对于对象锁,不同对象访问同一个被synchronized修饰的方法的时候不会阻塞
java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。
java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,知道线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去。
java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的
上面已经对锁的一些概念有了一点了解,下面探讨synchronized关键字的用法。
synchronized的用法:synchronized修饰方法和synchronized修饰代码块。
其实,类锁修饰方法和代码块的效果和对象锁是一样的,因为类锁只是一个抽象出来的概念,只是为了区别静态方法的特点,因为静态方法是所有对象实例共用的,所以对应着synchronized修饰的静态方法的锁也是唯一的,所以抽象出来个类锁。其实这里的重点在下面这块代码,synchronized同时修饰静态和非静态方法
synchronized的缺陷:当某个线程进入同步方法获得对象锁,那么其他线程访问这里对象的同步方法时,必须等待或者阻塞,这对高并发的系统是致命的,这很容易导致系统的崩溃。如果某个线程在同步方法里面发生了死循环,那么它就永远不会释放这个对象锁,那么其他线程就要永远的等待。这是一个致命的问题。
一个类的对象锁和另一个类的对象锁是没有关联的,当一个线程获得A类的对象锁时,它同时也可以获得B类的对象锁。
Java中活锁和死锁有什么区别?
什么是死锁(Deadlock)?导致线程死锁的原因?如何确保 N 个线程可以访问 N 个资源同时又不导致死锁
死锁与活锁的区别,死锁与饥饿的区别 答案:死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。死锁发生的四个条件
1、互斥条件:线程对资源的访问是排他性的,如果一个线程对占用了某资源,那么其他线程必须处于等待状态,直到资源被释放。
2、请求和保持条件:线程T1至少已经保持了一个资源R1占用,但又提出对另一个资源R2请求,而此时,资源R2被其他线程T2占用,于是该线程T1也必须等待,但又对自己保持的资源R1不释放。
3、不剥夺条件:线程已获得的资源,在未使用完之前,不能被其他线程剥夺,只能在使用完以后由自己释放。
4、环路等待条件:在死锁发生时,必然存在一个“进程-资源环形链”,即:{p0,p1,p2,...pn},进程p0(或线程)等待p1占用的资源,p1等待p2占用的资源,pn等待p0占用的资源。(最直观的理解是,p0等待p1占用的资源,而p1而在等待p0占用的资源,于是两个进程就相互等待)
活锁:是指线程1可以使用资源,但它很礼貌,让其他线程先使用资源,线程2也可以使用资源,但它很绅士,也让其他线程先使用资源。这样你让我,我让你,最后两个线程都无法使用资源。
饥饿:是指如果线程T1占用了资源R,线程T2又请求*R,于是T2等待。T3也请求资源R,当T1释放了R上的*后,系统首先批准了T3的请求,T2仍然等待。然后T4又请求*R,当T3释放了R上的*之后,系统又批准了T4的请求......,T2可能永远等待。
怎么检测一个线程是否拥有锁
如何实现分布式锁
有哪些无锁数据结构,他们实现的原理是什么
读写锁可以用于什么应用场景
Executors类是什么? Executor和Executors的区别 答案:
Executor 和 ExecutorService 这两个接口主要的区别是:ExecutorService 接口继承了 Executor 接口,是 Executor 的子接口
Executor 和 ExecutorService 第二个区别是:Executor 接口定义了 execute()方法用来接收一个Runnable接口的对象,而 ExecutorService 接口中的 submit()方法可以接受Runnable和Callable接口的对象。
Executor 和 ExecutorService 接口第三个区别是 Executor 中的 execute() 方法不返回任何结果,而 ExecutorService 中的 submit()方法可以通过一个 Future 对象返回运算结果。
Executor 和 ExecutorService 接口第四个区别是除了允许客户端提交一个任务,ExecutorService 还提供用来控制线程池的方法。比如:调用 shutDown() 方法终止线程池。可以通过 《Java Concurrency in Practice》 一书了解更多关于关闭线程池和如何处理 pending 的任务的知识。
Executors 类提供工厂方法用来创建不同类型的线程池。比如: newSingleThreadExecutor() 创建一个只有一个线程的线程池,newFixedThreadPool(int numOfThreads)来创建固定线程数的线程池,newCachedThreadPool()可以根据需要创建新的线程,但如果已有线程是空闲的会重用已有线程。
什么是Java线程转储(Thread Dump),如何得到它 答案:线程转储是一个JVM活动线程的列表,它对于分析系统瓶颈和死锁非常有用。有很多方法可以获取线程转储——使用Profiler,Kill-3命令,jstack工具等等。有的更喜欢jstack工具,因为它容易使用并且是JDK自带的。由于它是一个基于终端的工具,所以可以编写一些脚本去定时的产生线程转储以待分析。
如何在Java中获取线程堆栈
说出 3 条在 Java 中使用线程的最佳实践
在线程中你怎么处理不可捕捉异常 答案:为了保证主线程不被阻塞,线程之间基本相互隔离,所以线程之间不论是异常还是通信都不共享。当然,因为你抓异常是主线程,而异常是在子线程出现,可以用thread.setUncaughtExceptionHandler()去处理线程的异常。在Thread中,Java提供了一个setUncaughtExceptionHandler的方法来设置线程的异常处理函数,你可以把异常处理函数传进去,当发生线程的未捕获异常的时候,由JVM来回调执行。类似的功能就可以组成线程池自己的异常处理机制,正常来说,你想在主线程异步执行子线程的代码并得知是否执行成功,可以直接使用Promise模式,即Java中线程池返回的Future对象。
实际项目中使用多线程举例。你在多线程环境中遇到的常见的问题是什么?你是怎么解决它的
请说出与线程同步以及线程调度相关的方法
程序中有3个 socket,需要多少个线程来处理
假如有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有 10 个线程同时调用它,如何做到
如何在 Windows 和 Linux 上查找哪个线程使用的 CPU 时间最长
如何确保 main() 方法所在的线程是 Java 程序最后结束的线程
非常多个线程(可能是不同机器),相互之间需要等待协调才能完成某种工作,问怎么设计这种协调方案
你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它
异常
基本概念
Error 和 Exception有什么区别
UnsupportedOperationException是什么
NullPointerException 和 ArrayIndexOutOfBoundException 之间有什么相同之处
什么是受检查的异常,什么是运行时异常 答案:
Java提供了两类主要的异常 :runtime exception和checked exception。 checked异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。 对于这种异常, JAVA编译器强制要求我们必需对出现的这些异常进行catch 。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。 这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误. 但是另外一种异常: runtime exception ,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过 NullPointerException 异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
运行时异常与一般异常有何异同
简述一个你最常见到的runtime exception(运行时异常)
finally
finally关键词在异常处理中如何使用
如果执行finally代码块之前方法返回了结果,或者JVM退出了,finally块中的代码还会执行吗
try里有return,finally还执行么?那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后
在什么情况下,finally语句不会执行
throw 和 throws 有什么区别?
OOM你遇到过哪些情况?你是怎么搞定的?
SOF你遇到过哪些情况?
既然我们可以用RuntimeException来处理错误,那么你认为为什么Java中还存在检查型异常
当自己创建异常类的时候应该注意什么
导致空指针异常的原因
异常处理 handle or declare 原则应该如何理解
怎么利用 JUnit 来测试一个方法的异常
catch块里别不写代码有什么问题
你曾经自定义实现过异常吗?怎么写的
什么是 异常链
在try块中可以抛出异常吗
JDBC
通过 JDBC 连接数据库有哪几种方式
阐述 JDBC 操作数据库的基本步骤
JDBC 中如何进行事务处理
什么是 JdbcTemplate
什么是 DAO 模块
使用 JDBC 操作数据库时,如何提升读取数据的性能?如何提升更新数据的性能
列出 5 个应该遵循的 JDBC 最佳实践
IO
File
File类型中定义了什么方法来创建一级目录
File类型中定义了什么方法来判断一个文件是否存在
流
为了提高读写性能,可以采用什么流
Java中有几种类型的流
JDK 为每种类型的流提供了一些抽象类以供继承,分别是哪些类
对文本文件操作用什么I/O流
对各种基本数据类型和String类型的读写,采用什么流
能指定字符编码的 I/O 流类型是什么
序列化
什么是序列化?如何实现 Java 序列化及注意事项
Serializable 与 Externalizable 的区别
Socket
socket 选项 TCP NO DELAY 是指什么
Socket 工作在 TCP/IP 协议栈是哪一层
TCP、UDP 区别及 Java 实现方式
说几点 IO 的最佳实践
直接缓冲区与非直接缓冲器有什么区别?
怎么读写 ByteBuffer?ByteBuffer 中的字节序是什么
当用System.in.read(buffer)从键盘输入一行n个字符后,存储在缓冲区buffer中的字节数是多少
如何使用扫描器类(Scanner Class)令牌化
面向对象编程(OOP)
解释下多态性(polymorphism),封装性(encapsulation),内聚(cohesion)以及耦合(coupling)
多态的实现原理
封装、继承和多态是什么
对象封装的原则是什么?
类
获得一个类的类对象有哪些方式
重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
说出几条 Java 中方法重载的最佳实践
抽象类
抽象类和接口的区别
抽象类中是否可以有静态的main方法
抽象类是否可实现(implements)接口
抽象类是否可继承具体类(concrete class)
匿名类(Anonymous Inner Class)
匿名内部类是否可以继承其它类?是否可以实现接口
内部类
内部类分为几种
内部类可以引用它的包含类(外部类)的成员吗
请说一下 Java 中为什么要引入内部类?还有匿名内部类
继承
继承(Inheritance)与聚合(Aggregation)的区别在哪里
继承和组合之间有什么不同
为什么类只能单继承,接口可以多继承
存在两个类,B 继承 A,C 继承 B,能将 B 转换为 C 么?如 C = (C) B
如果类 a 继承类 b,实现接口c,而类 b 和接口 c 中定义了同名变量,请问会出现什么问题
接口
接口是什么
接口是否可继承接口
为什么要使用接口而不是直接使用具体类?接口有什么优点
泛型
泛型的存在是用来解决什么问题
泛型的常用特点
List能否转为List
工具类
日历
Calendar Class的用途
如何在Java中获取日历类的实例
解释一些日历类中的重要方法
GregorianCalendar 类是什么
SimpleTimeZone 类是什么
Locale类是什么
如何格式化日期对象
如何添加小时(hour)到一个日期对象(Date Objects)
如何将字符串 YYYYMMDD 转换为日期
Math
Math.round()什么作用?Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
XML
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?DOM 和 SAX 解析器有什么不同?
Java解析XML的方式
用 jdom 解析 xml 文件时如何解决中文问题?如何解析
你在项目中用到了 XML 技术的哪些方面?如何实现
动态代理
描述动态代理的几种实现方式,分别说出相应的优缺点
设计模式
什么是设计模式(Design Patterns)?你用过哪种设计模式?用在什么场合
你知道哪些商业级设计模式?
哪些设计模式可以增加系统的可扩展性
单例模式
除了单例模式,你在生产环境中还用过什么设计模式?
写 Singleton 单例模式
单例模式的双检锁是什么
如何创建线程安全的 Singleton
什么是类的单例模式
写出三种单例模式实现
适配器模式
适配器模式是什么?什么时候使用
适配器模式和代理模式之前有什么不同
适配器模式和装饰器模式有什么区别
什么时候使用享元模式
什么时候使用组合模式
什么时候使用访问者模式
什么是模板方法模式
请给出1个符合开闭原则的设计模式的例子
开放问题
用一句话概括 Web 编程的特点
Google是如何在一秒内把搜索结果返回给用户
哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入
树(二叉或其他)形成许多普通数据结构的基础。请描述一些这样的数据结构以及何时可以使用它们
某一项功能如何设计
线上系统突然变得异常缓慢,你如何查找问题
什么样的项目不适合用框架
新浪微博是如何实现把微博推给订阅者
简要介绍下从浏览器输入 URL 开始到获取到请求界面之后 Java Web 应用中发生了什么
请你谈谈SSH整合
高并发下,如何做到安全的修改同一行数据
12306网站的订票系统如何实现,如何保证不会票不被超卖
网站性能优化如何优化的
聊了下曾经参与设计的服务器架构
请思考一个方案,实现分布式环境下的 countDownLatch
请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存
在你的职业生涯中,算得上最困难的技术挑战是什么
如何写一篇设计文档,目录是什么
大写的O是什么?举几个例子
编程中自己都怎么考虑一些设计原则的,比如开闭原则,以及在工作中的应用
解释一下网络应用的模式及其特点
设计一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新
说出数据连接池的工作机制是什么
怎么获取一个文件中单词出现的最高频率
描述一下你最常用的编程风格
如果有机会重新设计你们的产品,你会怎么做
如何搭建一个高可用系统
如何启动时不需输入用户名与密码
如何在基于Java的Web项目中实现文件上传和下载
如何实现一个秒杀系统,保证只有几位用户能买到某件商品。
如何实现负载均衡,有哪些算法可以实现
如何设计一个购物车?想想淘宝的购物车如何实现的
如何设计一套高并发支付方案,架构如何设计
如何设计建立和保持 100w 的长连接
如何避免浏览器缓存。
如何防止缓存雪崩
如果AB两个系统互相依赖,如何解除依
如果有人恶意创建非法连接,怎么解决
如果有几十亿的白名单,每天白天需要高并发查询,晚上需要更新一次,如何设计这个功能
如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算)
如果要设计一个图形系统,请你设计基本的图形元件(Point,Line,Rectangle,Triangle)的简单实现
如果让你实现一个并发安全的链表,你会怎么做
应用服务器与WEB 服务器的区别?应用服务器怎么监控性能,各种方式的区别?你使用过的应用服务器优化技术有哪些
大型网站在架构上应当考虑哪些问题
有没有处理过线上问题?出现内存泄露,CPU利用率标高,应用无响应时如何处理的
最近看什么书,印象最深刻的是什么
描述下常用的重构技巧
你使用什么版本管理工具?分支(Branch)与标签(Tag)之间的区别在哪里
你有了解过存在哪些反模式(Anti-Patterns)吗
你用过的网站前端优化的技术有哪些
如何分析Thread dump
你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念
你是如何处理内存泄露或者栈溢出问题的
你们线上应用的 JVM 参数有哪些
怎么提升系统的QPS和吞吐量
知识面
解释什么是 MESI 协议(缓存一致性)
谈谈 reactor 模型
Java 9 带来了怎样的新功能
Java 与 C++ 对比,C++ 或 Java 中的异常处理机制的简单原理和应用
简单讲讲 Tomcat 结构,以及其类加载器流程
虚拟内存是什么
阐述下 SOLID 原则
请简要讲一下你对测试驱动开发(TDD)的认识
CDN实现原理
Maven 和 ANT 有什么区别
UML中有哪些常用的图
Linux
Linux 下 IO 模型有几种,各自的含义是什么。
Linux 系统下你关注过哪些内核参数,说说你知道的
Linux 下用一行命令查看文件的最后五行
平时用到哪些 Linux 命令
用一行命令输出正在运行的 Java 进程
使用什么命令来确定是否有 Tomcat 实例运行在机器上
什么是 N+1 难题
什么是 paxos 算法
什么是 restful,讲讲你理解的 restful
什么是 zab 协议
什么是领域模型(domain model)?贫血模型(anaemic domain model) 和充血模型(rich domain model)有什么区别
什么是领域驱动开发(Domain Driven Development)
介绍一下了解的 Java 领域的 Web Service 框架
Web Server、Web Container 与 Application Server 的区别是什么
微服务(MicroServices)与巨石型应用(Monolithic Applications)之间的区别在哪里
描述 Cookie 和 Session 的作用,区别和各自的应用范围,Session工作原理
你常用的持续集成(Continuous Integration)、静态代码分析(Static Code Analysis)工具有哪些
简述下数据库正则化(Normalizations)
KISS,DRY,YAGNI 等原则是什么含义
分布式事务的原理,优缺点,如何使用分布式事务?
布式集群下如何做到唯一序列号
网络
HTTPS 的加密方式是什么,讲讲整个加密解密流程
HTTPS和HTTP的区别
HTTP连接池实现原理
HTTP集群方案
Nginx、lighttpd、Apache三大主流 Web服务器的区别
是否看过框架的一些代码
持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些
数值提升是什么
你能解释一下里氏替换原则吗
你是如何测试一个应用的?知道哪些测试框架
传输层常见编程协议有哪些?并说出各自的特点
编程题
计算加班费
加班10小时以下加班费是时薪的1.5倍。加班10小时或以上,按4元/时算。提示:(一个月工作26天,一天正常工作8小时)
计算1000月薪,加班9小时的加班费
计算2500月薪,加班11小时的加班费
计算1000月薪,加班15小时的加班费
卖东西
一家商场有红苹果和青苹果出售。(红苹果5元/个,青苹果4元/个)。
模拟一个进货。红苹果跟青苹果各进200个。
模拟一个出售。红苹果跟青苹果各买出10个。每卖出一个苹果需要进行统计。
提示:一个苹果是一个单独的实体。
日期提取
有这样一个时间字符串:2008-8-8 20:08:08 , 请编写能够匹配它的正则表达式,并编写Java代码将日期后面的时分秒提取出来,即:20:08:08
线程
8设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
用Java写一个多线程程序,如写四个线程,二个加1,二个对一个变量减一,输出
wait-notify 写一段代码来解决生产者-消费者问题
数字
判断101-200之间有多少个素数,并输出所有素数
用最有效率的方法算出2乘以17等于多少
有 1 亿个数字,其中有 2 个是重复的,快速找到它,时间和空间要最优
2 亿个随机生成的无序整数,找出中间大小的值
10 亿个数字里里面找最小的 10 个
1到1亿的自然数,求所有数的拆分后的数字之和,如286 拆分成2、8、6,如1到11拆分后的数字之和 => 1 + … + 9 + 1 + 0 + 1 + 1
一个数如果恰好等于它的因子之和,这个数就称为 “完数 “。例如6=1+2+3.编程 找出1000以内的所有完数
一个数组中所有的元素都出现了三次,只有一个元素出现了一次找到这个元素
一球从100米高度*落下,每次落地后反跳回原高度的一半;再落下,求它在 第10次落地时,共经过多少米?第10次反弹多高?
求100-1000内质数的和
求1到100的和的平均数
求s=a+a+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。 求出1到100的和
算出1到40的质数,放进数组里
显示放组里的数
找出第[5]个数
删除第[9]个数,再显示删除后的第[9]个
有 3n+1 个数字,其中 3n 个中是重复的,只有 1 个是不重复的,怎么找出来。
有一组数1.1.2.3.5.8.13.21.34。写出程序随便输入一个数就能给出和前一组数字同规律的头5个数
计算指定数字的阶乘
开发 Fizz Buzz
给定一个包含 N 个整数的数组,找出丢失的整数
一个排好序的数组,找出两数之和为m的所有组合
将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
打印出所有的 “水仙花数 “,所谓 “水仙花数 “是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个 “水仙花数 “,因为153=1的三次方+5的三次方+3的三次方
原地交换两个变量的值
找出4字节整数的中位数
找到整数的平方根
实现斐波那契
网络
用Java Socket编程,读服务器几个字符,再写入本地显示
反射
反射机制提供了什么功能?
反射是如何实现的
哪里用到反射机制
反射中 Class.forName 和 ClassLoader 区别
反射创建类实例的三种方式是什么
如何通过反射调用对象的方法
如何通过反射获取和设置对象私有字段的值
反射机制的优缺点
数据库
写一段 JDBC 连Oracle的程序,并实现数据查询
算法
50个人围坐一圈,当数到三或者三的倍数出圈,问剩下的人是谁,原来的位置是多少
实现一个电梯模拟器用
写一个冒泡排序
写一个折半查找
随机产生20个不能重复的字符并排序
写一个函数,传入 2 个有序的整数数组,返回一个有序的整数数组
写一段代码在遍历 ArrayList 时移除一个元素
古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少
约瑟芬环游戏
正则
请编写一段匹配IP地址的正则表达式
写出一个正则表达式来判断一个字符串是否是一个数字
字符串
写一个方法,入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。
写一个程序找出所有字符串的组合,并检查它们是否是回文串
写一个字符串反转函数,输入abcde转换成edcba代码
小游戏,倒转句子中的单词
将GB2312编码的字符串转换为ISO-8859-1编码的字符串
请写一段代码来计算给定文本内字符“A”的个数。分别用迭代和递归两种方式
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”
给定 2 个包含单词列表(每行一个)的文件,编程列出交集
打印出一个字符串的所有排列
将一个键盘输入的数字转化成中文输出(例如:输入1234567,输出:一百二拾三万四千五百六拾七)
在Web应用开发过程中经常遇到输出某种编码的字符,如从 GBK 到 ISO8859-1等,如何输出一个某种编码的字符串
日期
计算两个日期之间的差距
---------------------
作者:西海棱镜
来源:CSDN
原文:https://blog.csdn.net/zhanjianshinian/article/details/78763366?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!