这篇放上目前为止看的一些java题目。后期差不多就是整理复习了。应该在秋招结束后会再发一篇比较长的各类问题的汇总。
1.final关键字
如果一个类被修饰为final,则该类不能作为父类被继承;也因此final和abstract不能同时修饰,其语义冲突;
Final修饰方法,则该方法不能被重写(但是可以进行重载),前提是子类继承了该方法;
Final修饰变量,需要显式初始化,修饰的变量初始化后值不能再进行更改;在编译期间就能确定其值故在进入class文件时已经不存在了。
2.finally关键字
一般与try…catch连用,常用于释放资源等最后一步处理,除开在try..catch中执行了exit()退出了jvm都会执行(包括前面有返回的情况);返回值以finally中的值为准。
3.finalize方法
Object提供的方法,用于GC在回收对象前调用该方法,与析构函数不同(析构函数的调用时机是确定的,finalize时机不确定),至多由GC执行一次;在GC中判断不可达的对象,会检查是否重写了finalize方法,若是且未执行过,则放入队列执行后再次判断对象是否可达,若否则直接回收。
4.Hashmap与Hashtable
均实现了Map接口,hashtable的大致实现与hashtable相同,除了他是线程安全的,且不可以接受null值,性能低于hashmap。Java5后提供了ConcurrentHashmap,也可以使用Collections.sychronziedMap(hashmap)。Hashmap计算hash对key的hashcode进行了二次计算,hashtable则直接使用key的hashcode对数组长度进行取模。
5.String s = new String("xyz");创建了几个String Object?
如果“xyz”在常量池中没有则会创建一个String对象,值为“xyz”且存在常量池中;由于new关键词,肯定会创建一个String对象,放在堆中。S是一个引用类型变量,放在栈中
6.Sleep和wait的区别
Sleep是Tread的静态方法,让调用线程进入睡眠状态。休眠结束后进入就绪态和其他线程一起竞争cpu的执行时间。不释放对象的锁。
Wait是Object类的方法,当一个线程执行wait时,它会进入到一个等待池并且释放对象的锁。可以通过notify,notifyall来进行唤醒
7.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
S1+1会转化为int类型,此时赋值给s1没有进行强制转化所以会出错,s1 += 1等价于s1 = (T)(s1 + 1)自带了隐式的强制类型转化。
8.overload和override的区别
overload和override都是java多态的表现。Override发生在继承关系中,是指子类定义了和父类函数名及参数相同的函数,只能抛出父类异常或父类异常的子集,访问权限只能更大,返回值需要相同。Overload发生在同一个类中,在这个类中定义了两个或以上函数名相同,参数列表不同的函数(返回值,访问权限,抛出的异常可以不同)。
9.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
Set是collection的一个子接口,不允许有重复对象且最多只有一个null值。判断用的是equals。== 是用于判断对象的内存地址,equals未复写之前底层也是调用的==,复写后有些用于判断对象的具体内容。
HashSet区分重复元素:
先使用hashcode方法判断已经存在HashSet中元素的hashcode值和将要加入元素hashcode值是否相同。如果不同,直接添加;如果相同,再调用equals方法判断,如果返回true表示HashSet中已经添加该对象了,不需要再次添加(重复),如果返回false就表示不重复,可以直接加入HashSet中
TreeSet区分重复元素:
TreeSet中的元素对象如果实现Comparable接口,使用compareTo方法区分元素是否重复,如果没实现Comparable接口,自定义比较器(该类实现Comparator接口,覆盖compare方法)比较该元素对象,调用TreeSet的构造方法new TreeSet(自定义比较器参数),这样就可以比较元素对象了
10.Error和exception
都是throwable的子类,error通常表示的是系统或底层资源的错误,不应由程序进行处理。Exception划分为checked exception和runtime exception,前者有例如IO异常,SQL异常等,JVM强制要求在代码中进行捕捉或声明,runtime exception 无须捕获或声明,应由程序员在设计代码时进行避免,例如空指针,除零等异常。
11.String类为什么是final的
首先解释final类的含义。保证了效率和安全性。首先是避免了继承中出现的非安全性。String中的成员属性基本也是final,将String设计为一个不变类,可以将字符串对象保存在字符串常量池中以供与字面值相同字符串对象共享。多线程进行访问时也是安全的。
12.Hashmap的底层原理
数组+链表结构,在添加,删除,获取元素时都是先计算hash值,根据hash值和数组长度进行取模计算下标,若该下标已经有元素,会在该位置形成一个链表,新添加的元素放在头部,元素容量达到容量阈值时进行扩容。扩容时先创建一个容量为现在两倍的数组,更改阈值,然后计算每个元素的新地址。containsKey使用hash值进行查询,containsValue直接遍历所有元素。
13.list、set、queue、map实现类
List:ArrayList(数组实现) LinkedList(链表实现,也继承了deque)
Set:HashSet LinkedHashSet TreeSet ( 值为null的特殊map)
Queue:PriorityQueue ArrayDeque LinkedDeque
Map:TreeMap(红黑树实现) HashMap HashTable
14.描述一下ArrayList和LinkedList各自实现和区别
Arraylist和linkedlist都是线程非安全的,vector是线程安全的。Arraylist底层用数组实现,LinkedList底层是链表实现,
15.Java中的队列都有哪些,有什么区别。
LinkedList,PriorityQueue(非阻塞类型) , java.util.concurrent中有一些带阻塞的队列实现。
16.Cs与Bs的区别
Cs是client/server结构,客户端需要安装专用软件。交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。针对性开发,变更不够灵活,维护和管理的难度较大,不利于扩展。并且,由于该结构的每台客户机都需要安装相应的客户端程序,分布功能弱且兼容性差,不能实现快速部署安装和配置,因此缺少通用性,具有较大的局限性。有新版本时需要每个客户端都升级更新。
Bs是Browser/Server结构,客户端使用浏览器即可。分布性强,维护性好,开发简单,成本较低。不利于实现复杂的应用,数据传输的速度较慢。
17.Java的反射
Java反射机制是在运行状态中,动态获取类信息及调用对象的方法,需要先获取到该类的字节码文件对象。
获取Class对象的三种方式:
Object.getClass();(已有对象了,通常不适用)
任何数据类型都有一个静态的class属性;(需要导包)
Class类的静态方法forName();(常用)
18.Java中的class.forName()和classLoader
都可以用于类的加载。Class.ForName实际调用的是Class.forName(className,true,classloader),第二个参数代表类是否需要初始化,默认是需要的。初始化中会执行static方法块及对static参数再次初始化。ClassLoader.loadClass(className)调用的方法是ClassLoader.loadClass(className,false)第二个表示是否进行链接,不链接也就代表不会进入初始化步骤。
19.Java内存泄漏
内存泄漏是指无用对象(不在使用的对象)持续占有内存或无用对象的内存得不到释放。严重的内存泄漏会导致out of memory。
Java中的内存泄漏一般发生在长生命周期的对象持有短生命周期对象的引用。
例如:静态集合类 hashmap ,arraylist等。仅仅释放其中对象,由于hashmap依旧引用所以gc不会进行回收。Set里面对象属性被更改后,再调用remove不起作用。此外还有监听器,各种连接,内部类和外部模块的引用,单例模式。
20.发现内存泄漏
Out of memory常常是内存泄漏的一个标志。继续监听gc的活动。查看随着时间内存使用量是否会继续增加。
Jstat –gc pid 可以显示gc的信息,查看gc的次数和时间。
Jstat –gccapacity pid 可以显示内存分区中对象的使用和占用大小。
Jstat –gcutil pid 统计gc信息
Jstat –class pid加载class的数量及空间占用
MemoryAnalyzer可以检查内存泄漏的部分,使用jmap命令生成内存快照。
21.String,stringBuilder,Stringbuffer的区别
String是字符串常量,不可变。使用String伴随着对象的创建与回收。StringBuilder和StringBuffer是字符串变量。StringBuffer是线程安全的,效率更低。三个类底层都是字符数组。(String的被final修饰)
22.hashtable和hashmap的区别
都实现了map接口,hashmap几乎可以等价于hashtable,除了hashtable中的方法都是同步的,hashmap可以接收null值,hashtable不可以。Hashmap的速度更快。Hashmap计算hash值得方式不同(进行了二次hash)
23.异常的结构
Throuable
--error jvm级别的错误,无法通过代码进行处理
--exception
----runtime exception 应由程序员在代码中进行控制,javac在编译时不会进行提示或发现。例如数组越界,算术错误,空指针异常,类型转换异常等
----checked exception javac强制要求程序员为这样的异常做抛出并声明或是捕获,否则编译无法通过。例如文件IO异常,SQL异常等。
24.String类的常用方法
Length() : 长度
charAt() : 字符串某一位置字符
substring : 提取字符串中的子串
equals : 比较当前字符串和参数字符串
concat : 字符串的连接
trim :截去字符串两端的空格
25.Java的引用类型有几类
为了使程序能够更好的控制对象的生命周期。
强引用:类似Object a = new Object(),永远不会被回收。
软引用:如果内存空间够,则不会回收,内容空间不够时回收。
弱引用:扫描到就回收。
虚引用:主要用于跟踪对象被垃圾回收的的活动。必须和引用队列联合使用。
26.抽象类和接口的区别
抽象类:可以有实例方法,extends继承,有构造器不能被实例化,可以有main方法并进行运行,模板设计,对类的抽象
接口:无实例方法,implements实现,无构造器,访问修饰符默认public static final 和public abstract,java8中开始有静态方法和默认方法。对行为的抽象
27. java的基础类型和字节大小
byte(字节型) 1 -128~127
boolean(布尔型) 1 true或false
short(短整型) 2 -32768~32767
char(字符型) 2 从字符型对应的整型数来划分,其表示范围是0~65535
int(整型) 4 -2147483648~2147483647
float(浮点型) 4 -3.4E38~3.4E38
double(双精度型) 8 -1.7E308~1.7E308
long(长整型) 8 -9223372036854775808 ~ 9223372036854775807
28.Hashtable,HashMap,ConcurrentHashMap的底层原理和线程安全
Hashtable是用synchronized来修饰方法达到线程安全。
ConcurrenHashMap使用了锁分段技术,首先将数据分为一段一段存储,给每段数据配一把锁,一个线程占用锁访问不影响其他线程访问其他段。由Segment和HashEntry组成。Segment结构和HashMap类似(数组+链表),每个Segment守护一个HashEntry数组中的元素。
29.java支持的基本数据有哪些,什么是自动拆装箱。
java支持byte,short,int,long ,float,double,char,boolean。从java1.5开始有自动拆装箱,目的是将原始类型自动的转化为对应的对象。也可以进行逆行的转化(拆箱),是java语法糖。Integer.valueOf()会进行一个值的比较,如果不在范围内就新建对象。否则会返回已有的对象。double和folat则每次都会返回不同对象。一个基础类型和封装类型进行+-*/时会进行拆箱
30.值传递和引用传递
值传递:在方法调用的时候,实参是将自己的一份拷贝赋值给形参,在方法内部,对该参数值的修改不影响原来实参。引用传递是实参将自己的地址传递给形参,方法内对此参数值的改变会影响到原参数,在java中只有值传递。
31.floor,round,ceil的区别
floor返回不大于的最大整数,round为4舍5入=floor(x+0.5),ceil是不小于他的最小整数。
32.字节流和字符流的区别
字节流(inputstream,outputstream)在操作时不会使用到缓冲区,按字节进行处理,不支持直接写入或读取unicode。字符流(reader,writer)会先进入缓冲区再到文件,按虚拟机的encode进行处理。
33.Hash冲突的解决办法
开放地址法:发生冲突后用一定的函数再寻找下一个位置
再hash法:同时构造多个hash函数
链地址法:链表+数组
建立公共溢出区:分为基本表和溢出表,发生冲突的元素都放入溢出表
34.equals和hashcode方法
equals用于同一类中进行比较。Hashcode多用于hashtable等数据结构。Equals相等的对象,hashcode一定相等。Equals不相等不一定hashcode不相等。在hashset等插入时会先判断hashcode(或根据hashcode再次计算的值)是否相等,在hashcode相等的情况下再判断equals是否相等。