北京Java笔试题整理
1、什么是java虚拟机?为什么ava被称作是“平台无关的编程语言?
答:Java虚拟机可以理解为一个特殊的“操作系统”,只是它连接的不是硬件,而是一般的操作系统和java程序。
正是因为有这样一层操作系统与程序之间的连接,Java程序就能在一台机子上编译后到处都能运行——只要有对应不同系统的Java虚拟机就可以了。因此Java被称为“平台无关”。
Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。
2、关键字是什么意思?Java中是否可以覆盖或者static的方法?
答:static表示静态的意义,它可以修饰一个变量,一个方法,被其修饰的变量被称为类变量,被其修饰的方法成为类方法,其随着类的加载而被加载。
无法重写被private修饰的方法,因为被private修饰的父类方法在子类中是不可见的。
static修饰的方法是静态绑定的,而方法覆盖是为了实现多态,是动态绑定,所以static修饰的方法不需要被覆盖
3、是否可以在static环境中访问非static变量?
答:不能。
static变量在java中是属于类的,在类的所有实例中,它的值都是一样的。在类被JVM载入时,静态变量的值就确定了。
而非静态变量是属于实例的,要在new一个实例之后,值才会存在。
在static环境中,调用非static变量,可能这个变量都还不存在,当然会出错。
4、java支持的数据类型有哪些?什么是自动拆装箱?
答:Java语言支持的8中基本数据类型是:
byte
short
int
long
float
double
boolean
char
自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成double,等等。反之就是自动拆箱。
5、Java中的方法覆盖和方法重载是什么意思?
答:重载: 在一个类当中才可以重载,方法名相同,参数个数不同或参数个数相同而参数类型不同。
覆盖: 又称重写,在派生类(子类)中重写基类(父类)的方法,名称、参数、类型都必须相同。
6、Java中,什么是构造函数?什么是构造函数重载?什么是赋值构造函数?
答:当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一个默认的构造函数。
Java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。
Java不支持像C++中那样的赋值构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java不会创建默认的赋值构造函数。
7、Java支持多继承吗?
答:
Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是java中的接口可以间接实现多继承,,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。
8、进程和线程的区别是什么?
答:1)进程是什么? 是具有一定独立功能的程序、它是系统进行资源分配和调度的一个独立单位,重点在系统调度和单独的单位,也就是说进程是可以独 立运行的一段程序。
2)线程又是什么? 线程进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源。 在运行时,只是暂用一些计数器、寄存器和栈 。二、他们之间的关系 3)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(通常说的主线程)。
9、什么是值传递和引用传递?
答:值传递 指的是在方法调用时,传递的参数是按值的拷贝传递。
引用传递 指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。
10、创建线程有几种方式?你喜欢哪一种?为什么?
答:链接:https://www.nowcoder.com/questionTerminal/e33c72bceb4343879948342e2b6e3bca?pos=48&mutiTagIds=570&orderByHotValue=1
来源:牛客网
1)继承Thread类(真正意义上的线程类),是Runnable接口的实现。
2)实现Runnable接口,并重写里面的run方法。
3)通过Callable接口实现多线程,重写call方法,优点是可以获取返回值,确定是比较繁琐
4)使用Executor框架创建线程池。Executor框架是juc里提供的线程池的实现。
调用线程的start():启动此线程;调用相应的run()方法
继承于Thread类的线程类,可以直接调用start方法启动线程(使用static也可以实现资源共享).一个线程(对象)只能够执行一次start(),而且不能通过Thread实现类对象的run()去启动一个线程。
实现Runnable接口的类需要再次用Thread类包装后才能调用start方法。(三个Thread对象包装一个类对象,就实现了资源共享)。
线程的使用的话,注意锁和同步的使用。(多线程访问共享资源容易出现线程安全问题)
一般情况下,常见的是第二种。
- Runnable接口有如下好处:
*①避免点继承的局限,一个类可以继承多个接口。
*②适合于资源的共享
11、概括的解释下线程的几种可用状态?
答:
- 新建( new ):新创建了一个线程对象。
- 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
- 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
- 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:
(一). 等待阻塞:运行( running )的线程执行 o . wait ()方法, JVM 会把该线程放 入等待队列( waitting queue )中。
(二). 同步阻塞:运行( running )的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
(三). 其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。 当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。 - 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生
12、同步方法和同步代码块的区别是什么?
答:
同步方法:(粗粒度锁):
1.修饰一般方法: public synchronized void method (){...},获取的是当前调用 对象this上的锁
2.修饰静态方法: public static synchronized void method (){...},获取当前类的 字节码对象上的锁
③同步代码块(细粒度锁):
synchronized ( obj ) {...},同步代码块可以指定获取哪个对象上的锁。
13、什么是死锁?
答:所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
14、为什么Java集合类没有实现Cloneable和Serializable接口?
答:克隆(cloning)或者序列化(serialization)的语义和含义是跟具体的实现相关的。因此应该由集合类的具体实现类来决定如何被克隆或者序列化
15、Java集合类框架的基本接口有哪些?
答:
1)总共有两大接口:Collection 和Map ,一个元素集合,一个是键值对集合; 其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合; 而ArrayList和 LinkedList 实现了List接口,HashSet实现了Set接口,这几个都比较常用; HashMap 和HashTable实现了Map接口,并且HashTable是线程安全的,但是HashMap性能更好;
2)
Java集合类里最基本的接口有:
Collection:单列集合的根接口
List:元素有序 可重复
ArrayList:类似一个长度可变的数组 。适合查询,不适合增删
LinkedList:底层是双向循环链表。适合增删,不适合查询。
Set:元素无序,不可重复
HashSet:根据对象的哈希值确定元素在集合中的位置
TreeSet: 以二叉树的方式存储元素,实现了对集合中的元素排序
Map:双列集合的根接口,用于存储具有键(key)、值(value)映射关系的元素。
HashMap:用于存储键值映射关系,不能出现重复的键key
TreeMap:用来存储键值映射关系,不能出现重复的键key,所有的键按照二叉树的方式排列
16、什么是迭代器?
答:
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Java中的Iterator功能比较简单,并且只能单向移动:
17、Iterator和Listiterator的区别是什么?
答:一.相同点
都是迭代器,当需要对集合中元素进行遍历不需要干涉其遍历过程时,这两种迭代器都可以使用。
二.不同点
1.使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。
2.ListIterator有add方法,可以向List中添加对象,而Iterator不能。
3.ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以。
4.ListIterator可以定位当前索引的位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
5.都可实现删除操作,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。
18、Java中的Hashmap的工作原理是什么?
答:java8对hashmap做了优化 ,底层有两种实现方法,一种是数组和链表,一种是数组和红黑树,hsahmap会根据数据量选择存储结构
if (binCount >= TREEIFY_THRESHOLD - 1)
当符合这个条件的时候,把链表变成treemap,这样查找效率从o(n)变成了o(log n)
19、hashcode()和equals()方法的重要性体现在什么地方?
答:Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。
20、Hashmap和Hashtable有什么区别?
答:
HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
HashMap不能保证随着时间的推移Map中的元素次序是不变的
21、数组((Array)和列表(ArrayList)有什么区别?什么时候应该使用Arrayi不是Arraylist?
答:
数据类型方面: Array数据可以是基本类型何包装类型,ArrayList只能是包装类型.
容量方面:Array容量是静态固定的,ArrayList是动态变化的。
支持操作:ArrayList提供更多操作,Array提供的更多依赖于Arrays提供的方法。
使用建议:如果你的操作对象是基本型别,而且需要在空间不足时自动扩增容量,Array便不适合,此时就得使用外覆类的容器了。
ArrayList存入对象时,抛弃类型信息,所有对象屏蔽为Object,编译时不检查类型,但是运行时会报错。
基于效率和类型检验,应尽可能使用Array,无法确定数组大小时才使用ArrayList!
22、Arraylist和Linkedlist有什么区别?
答:1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
23、Comparable和Comparator接口是干什么的?列出它们的区别?
答:
Comparatable接口必须由需要排序的多元素类本身来实现,且在其内部重写comparaTo()方法;Comparator接口是在需要排序的多元素类的外部(即使用外部类)来实现,且必须在该外部类中重写compara()方法。
两者的比较
comparable接口:
优点:对于单元素集合可以实现直接排序
缺点:对于多元素排序,排序依据是固定不可更改的。(元素内部只能实现一次compareTo方法)
comparator接口:
元素的排序依据时刻变的,所以可以通过定义多个外部类的方式来实现不同的排序。使用时按照需求选取。
创建外部类的代价太大。
24、Java中垃圾回收有什么目的?什么时候进行垃圾回收?
答:
目的:回收堆内存中不再使用的对象,释放资源
回收时间:当对象永久地失去引用后,系统会在合适的时候回收它所占的内存
垃圾回收的目的是回收堆中已经不在被使用的对象。垃圾回收机制是一个守护线程,优先级别低,其在当前服务器空闲或堆中老年代等占用率较大时触发。