java 面试题总结(一)
从网上找了些面试题,自己手工总结了理解了一下,如有理解错误,还请指正。
java基础
4. 描述一下ArrayList和LinkedList各自实现和区别
ArrayList是线性表 ,随机取数快,数据删除插入较慢,占用内存小
LinkedList是链表 插入删除快,查找遍历较慢占用内存稍大
5. Java中的队列都有哪些,有什么区别。
队列是实现生产者消费者的重要工具,java中的队列一般氛围阻塞的和非阻塞的,或者是根据需要有其他多重的实现方式:
ArrayBlockingQueue——带边界的阻塞式队列
ConcurrentLinkedDeque / ConcurrentLinkedQueue——无边界的链表队列(CAS)
DelayQueue——元素带有延迟的队列
LinkedBlockingDeque / LinkedBlockingQueue——链表队列(带锁),可设定是否带边界
LinkedTransferQueue——可将元素`transfer`进行w/o存储
PriorityBlockingQueue——并发PriorityQueue
SynchronousQueue——使用Queue接口进行Exchanger
Queue在设计之处就考虑了多线程的安全性,代表性的Queue的两种实现,表示实现线程安全的两套方案:•BlockingQueue,•ConcurrentLinkedQueue
前者是阻塞的同步的,后者是并发的。
这里提一下多线程安全问题的含义,之前有些搞混了。线程安全的类 ,指的是类内共享的全局变量的访问必须保证是不受多线程形式影响的。如果由于多线程的访问(比如修改、遍历、查看)而使这些变量结构被破坏或者针对这些变量操作的原子性被破坏,则这个类就不是线程安全的。实现线程安全又有两种方式,一种是同步的,将多线程的请求排个队,A线程进来了关上厕所门,其他线程在外面等待。A线程执行结束,B线程进入同样关上门。这样的操作保证了多线程下共享变量不会被修改,但是效率比较差,如果线程太多会导致严重的锁争用。还有一种方式是并发的,多个线程可以同时进入一段代码,如何保证线程安全呢?就是通过各个线程之间对共享变量的修改和操作都是可见的,你改了什么我必须第一时间知道,然后针对性地做一些操作。这样极大地提高了处理速度,只是算法的实现会非常的复杂。另外,类自身实现线程安全,只是代表类自身的api保持原子性,但是外部使用多个api的情况下,还是要手动进行加锁。concurrent包下的集合类实现,都是采用的并发方式,而Collections工具类包装的集合都是使用同步锁方式。其中CurrentHashMap应该是使用了分段锁和volatile。java并发:同步容器&并发容器 - 烟雨暗千家 - 博客园
LinkedList实现了Queue接口,也可以作为队列使用,但是不可以访问非Queue接口的方法,以免发生错乱。
BlocingQueue:ArrayBlockingQueue,LinkedBlockingQueue(入队和出队两把锁),DelayQueue,PriorityBlockingQueue(公平锁),SynchronousQueue。
ReentrantLock 只锁部分代码块
ConcurrentLinkedQueue:使用volatile关键字使共享变量可见,具体细节颇为复杂。
【Java多线程总结之聊一聊Queue - I'm Sure - ITeye技术网站 】【java中线程队列BlockingQueue的用法-shwenwen-ITPUB博客 】
这个坑很深,目前只能研究到这里了……
6. 反射中,Class.forName和classloader的区别。
Class.forName()方法底层调用Class.forName(className,true,classloader);表示在加载类的时候,执行初始化步骤;
ClassLoader.loadClass()方法底层调用ClassLoader.loadClass(className,false);表示不执行初始化步骤;
初始化步骤会初始化静态变量和静态代码块,如果此处没有初始化,那就需要在newInstance时,初始化了。根据不同的需要,调用相应的方法。
可能会引申到JVM装载类的过程:编译解释java文件为二进制class,装载class(通过类的完全限定名和类加载器实例),链接(对二进制字节码校验,初始化静态变量,找到父类接口和类,确定调用的方法和类都是存在的且具备权限),初始化(静态代码块其他)。
7. Java7、Java8的新特性
java7的更新多数是语法糖:
try包含资源代码块,自动释放;多个catch合并;更强的类型推测,new的时候不再需要指定类型,直接<>即可;二进制字面量支持;通过[],{}初始化集合。
java8
Lambda表达式与函数接口,接口支持默认方法和静态方法,可使用类似于C++的方法引用 class::method,重复注解,更强的类型推测,可将参数名称保存在字节码中,Optional 支持对null的处理,Stream 类似于mapReduce的集合处理方式,api可以直接连缀调用,Date/Time API 的更新,在兼容旧api分基础上提供了许多新的api,传闻java 9 将进一步支持货币api,base64直接支持,支持运行javascript以及js和java的相互调用(java8就有了?),jvm的permGen移除,类依赖分析器jdeps。
8. Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高。
数组 不能动态扩容,占内存小,添加删除操作稍慢,查询快。
链表 可以动态扩容,占内存大,添加删除操作快,查询慢。
9. Java内存泄露的问题调查定位:jmap,jstack的使用等等。
没用过不好说
10. string、stringbuilder、stringbuffer区别
String 是final的字符串,不可变。StringBuffer是线程安全的可变String,StringBuilder是简化的可变字符串,不是线程安全的。
11. hashtable和hashmap的区别
上面有所提及:
1. HashTable不支持用null作为key,而HashMap支持
2. HashTable是线程安全的map集合,HashMap不是线程安全的。
3. HashTable因为支持线程安全,所以没有HashMap的快速失败机制,但是HashTable不能保证多个api复合调用时保证安全。
4. Map想要支持多线程安全可以通过Collections工具类获取同步的Map,或者通过concurrent包中的concurrentHashMap返回并发的Map,而且可以与有序的TreeMap转化,很多时候,即便是多线程环境下也并不一定需要HashTable。
13 .异常的结构,运行时异常和非运行时异常,各举个例子。
单独再说
14. String 类的常用方法
length() , subString , indexOf , lastIndexOf , charAt , equals ,toUpperCase , equalsIgnoreCase , trim , toString , toLowerCase , replace , match(用于正则) , startsWith , compareTo. format(允许类似于C语言的输出字符串格式控制)
15. Java 的引用类型有哪几种
String , Object ,基本类型的包装类型:Integer,Long , Boolean , Short , Float,Double,Byte,Character,Void。Enum枚举类型
16. 抽象类和接口的区别
从语法上来看:
参数 | 抽象类 | 接口 |
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
实现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
与正常Java类的区别 | 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 | 接口是完全不同的类型 |
访问修饰符 | 抽象方法可以有public、protected和default这些修饰符 | 接口方法默认修饰符是public。你不可以使用其它修饰符。 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象方法可以继承一个类和实现多个接口 | 接口只可以继承一个或多个其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 | 如果你往接口中添加方法,那么你必须改变实现该接口的类。 |
从本质上来看:
抽象类是对子类的一个抽象,抽象类提供了子类的某些方法约束,作为公共的大家都必须遵守的约束,有利于直接复用代码。不能确定的子类行为可以采用抽象方法定义,交给具体子类实现。抽象类更多的是在具体代码编写时的一种设计。
接口是定义一组约束规则,作为彻底的抽象层存在。它只要求实现者实现所有的方法,而不关心具体的实现方式,它只为子类指定功能,但是不存在对子类实现方式的要求,也就是说没有公共的已经实现的方法。更多的是用于软件架构设计中,对不同模块的抽象。
java8中支持了接口的默认方法,具体后面再研究。
18. java的基础类型和字节大小
java中基本数据类型(不是引用类型)有8种
byte | Byte | 1 | -128 | 127 |
char | Character | 2 | unicode-0 | unicode 2^16-1 |
short | Short | 2 | -2^15 | 2^15-1 |
int | Integer | 4 | -2^31 | 2^31-1 |
float | Float | 4 | ||
double | Double | 8 | ||
long | Long | 8 | ||
boolean | Boolean | - | true | false |
对char不太理解,因为char是2个字节,但是unicode中utf-8的中文是3个字节,产生了混乱。后来有人建议不要用char类型。因为char类型使用的老旧的utf16编码,65535个字符根本不够囊括所有语言的字符。这里记录以下防止被坑吧……
19. Hashtable,HashMap,ConcurrentHashMap底层实现原理与线程安全问题。
HashMap没有做多线程的控制,底层实现原理之前有提到过。HashTable是使用了重用锁,在操作时锁住了一段代码块,是同步的。ConcurrentHashMap,内部使用了volatile关键字,使得共享变量在多线程之间可见和同步,编程上考虑的比较多算法比较复杂。具体的上面的文章中有提到过。
20. Hash冲突怎么办?哪些解决散列冲突的方法?
hash冲突应该是hash算法的问题,也有可能是hashCode算法的问题。这个//todo
21. HashMap冲突很厉害,最差性能,你会怎么解决?从O(n)提升到log(n)。
首先哈希表是通过哈希函数计算元素的哈希值,然后将次哈希值作为要存放的数组地址的下标,以便达到用数组存放元素,同时能够实现较快的查找删除操作。
这里哈希函数就非常重要,如果哈希函数计算的不同元素的哈希值容易重复,就会导致哈希冲突(不同元素映射到同一下标),哈希表不得不额外地解决这些冲突。
好的哈希函数会尽量避免冲突,能均匀的分布。以及计算简单。
解决哈希冲突的办法主要有下面几种:
开放地址法:如果发现哈希值下标已经被占用,就向下查找下一个空元素存入,问题是非常容易产生集聚现象,使得冲突加剧。其中也有一些变种办法,例如不直接向下查找下一个元素,而是生成不同的查找步数,这个可以根据随机数或者二次哈希产生。
再哈希法:冲突后再次执行另一个哈希算法,得到新的地址。
链地址法:如果哈希冲突了,就直接将冲突的元素接在原占有的元素后面,形成一个链表。
而HashMap就是采用这种办法做的。HashMap的性能,也是与其hash函数有关,当存放的key是用户自定义的对象而不是String的时候,需要重写这个对象的hashCode方法,这个hashCode方法的效率就会影响到HashMap的哈希函数的效率,如果HashCode不能做到计算简单随机分布,hash函数就会容易冲突。
HashMap冲突很严重的话,还可以将HashMap转化为平衡树实现的TreeMap,后者的性能是logn.
23. rehash
看起来应该是HashMap的再哈希算法,主要用于当HashMap的容量超过负载因子(导致元素容易集聚成链表),HashMap就会扩容,所有的元素的哈希值就要重新计算,rehash大概就是用于此处的。rehash比较消耗性能,因此应该避免HashMap频繁扩容。
24. hashCode() 与 equals() 生成算法、方法怎么重写。
hashCode
hashCode用于生成标记一个对象的最好是唯一的散列码,它将被用在HashMap等散列表中,哈希函数会根据该散列码计算数组下标从而存放起来。
因此如果散列码是一样的话,在HashMap中认为是同一个对象,如果不一样,它就会认为这个一个新的对象。
大家说在重写equals时重写hashCode方法,是为了避免对象在用在哈希表的键时造成的问题。
设想重写了equals方法,两个不同的对象被认为是相等的,我们把相等的对象存到map的key中,然后再根据这个相等的对象取value的时候,就会出错。因为HashMap根据hashCode计算出来的两个对象的值不同,HashMap认为是不一样的。所以就找不到当初存放的对象。
所以hashCode需要重写,并且保证两个值相同的对象,它的hashCode一定是相同的。(如果固定地返回某个常量值,会导致系统会将所有的这种类型的对象都视为相同。)
重写hashCode方法是一项技术活,不过一些简单的重写方案还是有的。下面的代码从《effective java》中摘录
/**此处的变量都是int类型*/
@Override
public int hashCode(){
int result = 17;
result = 31*reuslt + areaCode;
result = 31*result + prefix;
result = 31*result + lineNumber;
return result;
}
equals
/**
* equals方法需要满足自反性,对称性,传递性,一致性和非空性
* equasl方法写完了要进行相关的测试
* 过程是:
* 检查被比较的对象是不是自己,如果是返回true
* 检查被比较的对象是不是null,如果是返回false
* 检查被比较的对象是不是和自己是同一个类型的,如果不是返回false
* 将被比较对象强制转换成自己的类型,然后逐一比较值。
* 对于float,double,数组等格式的域,需要使用特殊的比较方法,而不能用==。
*
*/
@Override
public boolean equals(Object obj){
if(this == obj)return true;
if(obj == null)return false;
if(obj.getClass() != this.getClass())return false;//!(obj instanceof Te1)
Te1 t = (Te1)obj;
if(!t.name.equals(name))return false;
if(!(t.id==id))return false;
if(Double.compare(salary,t.salary)!=0)return false;
if(!Arrays.equals(strs,t.strs))return false;
return true;
}
java 面试题总结(一)的更多相关文章
- java面试题及答案(转载)
JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...
- 115个Java面试题和答案——终极列表(下)
第一篇讨论了面向对象编程和它的特点,关于Java和它的功能的常见问题,Java的集合类,垃圾收集器,本章主要讨论异常处理,Java小应用程序,Swing,JDBC,远程方法调用(RMI),Servle ...
- Java面试题(全)
JAVA部分 什么是反射机制?反射机制应用(Struts中反射机制的应用) 答:运行状态中,对于任意一个类,都可以知道它的所有属性和方法,对于任意一个对象都可以调用它的任意一个方法,这种动态获取信息以 ...
- Java面试题大全(四)
JAVA代码查错 1. abstract class Name { private String name; public abstract boolean isStupidName(String n ...
- 大公司的Java面试题集
找工作要面试,有面试就有对付面试的办法.以下一些题目来自我和我朋友痛苦的面试经历,提这些问题的公司包括IBM, E*Trade, Siebel, Motorola, SUN, 以及其它大小公司. 面试 ...
- 收集了50道基础的java面试题
下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...
- Java笔试题解答和部分面试题
面试类 银行类的问题 问题一:在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环? HashMap本身没有什么问题,有没有问题取决于你是如何使用它的.比如,你 ...
- 转:Java面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101
Java面试题集(51-70) Java程序员面试题集(51-70) http://blog.csdn.net/jackfrued/article/details/17403101 摘要:这一部分主要 ...
- JAVA面试题集之基础知识
JAVA面试题集之基础知识 基础知识: 1.C 或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就 ...
- [原]Java面试题-将字符串中数字提取出来排序后输出
[Title][原]Java面试题-将字符串中数字提取出来排序后输出 [Date]2013-09-15 [Abstract]很简单的面试题,要求现场在纸上写出来. [Keywords]面试.Java. ...
随机推荐
- springboot学习笔记-2 一些常用的配置以及整合mybatis
一.一些常用的配置 1.1 使用没有父POM的springboot 通过添加scope=import的依赖,仍然能获取到依赖管理的好处: <dependencyManagement> &l ...
- java 对象的解释过程
- #46 delete(动态规划+树状数组)
二维的dp非常显然,但这也没有什么优化的余地了. 注意到最后的方案中只有产生贡献的位置是有用的,剩下的部分可以在该范围内任意选取. 所以我们考虑设f[i]为i号位最后产生贡献的答案,则f[i]=max ...
- python 求两个时间差
def timeInterval(self): today = datetime.date.today() print today modifiedTime = os.stat(filename).s ...
- 【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)
[BZOJ3551]Peaks加强版(Kruskal重构树,主席树) 题面 BZOJ Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相 ...
- 20135319zl内核模块编译报告
内核模块编程学习报告 1.编写一个简单的输出信息的模块 源代码: Makefile 编译模块 加载模块 测试模块(dmesg) 卸载模块 Sudo rmmod 1 使用dmesg查看情况 2.输出当前 ...
- HDU.2147 kiki's game (博弈论 PN分析)
HDU.2147 kiki's game (博弈论 PN分析) 题意分析 简单的PN分析 博弈论快速入门 代码总览 #include <bits/stdc++.h> using names ...
- 单点登录(一)-----理论-----单点登录SSO的介绍和CAS+选型
什么是单点登录(SSO) 单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录. 单点登录(Single Sign On),简称为 ...
- JVM 垃圾回收机制和常见算法
垃圾回收机制:释放那些不再持有引用的对象的内存. 如何判断对象是否需要回收? 引用计数:对象,内存,磁盘空间等被引用次数保存起来,次数为0时将其进行释放. 对象引用遍历:对象应用遍历从一组对象开始,沿 ...
- Pycharm远程连接服务器,并在本地调试服务器代码
问题描述 其实有很多教程了,我只是想记录一下设置得记录,这样就能充分利用阿里云服务器为我跑代码了... 步骤一:配置deployment 步骤二:选择远程python解释器 步骤三:将本地文件上传至远 ...