java面试题

Java面试题收藏

2017-07-08  本文已影响156人  Luliang

Java面试题收藏

一篇比较好的面试题整理:

Java面试题集

自己的一些收藏:


静态变量和实例变量的区别

静态变量存储在方法区, 属于类所有,实例变量存储在当中, 其引用存在当前线程的栈


switch中能否使用string做参数

在jdk1.7之前, switch只能支持byte, short, char, int或者其对应的封装类以及Enum类型. 从jdk1.7之后, switch开始支持String


String对象的intern()是干什么的

intern()方法会首先从常量池中查找是否存在该常量值, 如果常量池中不存在则先在常量池中创建, 如果已经存在则直接返回, 如:

String s1="aa"; 
String s2=s1.intern(); 
System.out.print(s1==s2);//返回true

equals()和hashcode()的联系

hashCode()是Object类的一个方法, 返回一个哈希值, 如果两个对象根据equal()方法比较相等, 那么调用这两个对象中任意一个对象的hashCode()方法必须产生相同的哈希值. 如果两个对象根据eqaul()方法比较不相等, 那么产生的哈希值不一定相等(碰撞的情况下还是会相等的)


final, finalize和finally的不同之处


Thread类中的start()run()方法有什么区别

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。


wait()与sleep()的区别

sleep()来自Thread类,而wait()来自Object类. 调用sleep()方法的过程中,线程不会释放对象锁。而调用 wait()方法线程会释放对象锁. sleep()睡眠后不出让系统资源,而wait()会让出系统资源. sleep(milliseconds)需要指定一个睡眠时间,时间一到会自动唤醒.而wait()需要配合notify()或者notifyAll()使用


ThreadLoal的作用是什么

简单说ThreadLocal就是一种以空间换时间的做法, 在每个Thread里面维护了一个ThreadLocal。ThreadLocalMap把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。


如果你提交任务时,线程池队列已满,这时会发生什么

如果你使用的LinkedBlockingQueue,也就是无界队列的话,没关系,继续添加任务到阻塞队列中等待执行,因为LinkedBlockingQueue可以近乎认为是一个无穷大的队列,可以无限存放任务;如果你使用的是有界队列比方说ArrayBlockingQueue的话,任务首先会被添加到ArrayBlockingQueue中,ArrayBlockingQueue满了,则会使用拒绝策略RejectedExecutionHandler处理满了的任务,默认是AbortPolicy


volatile类型变量提供什么保证

volatile主要有两方面的作用:

  1. 避免指令重排
  2. 可见性保证
    例如,JVM 或者 JIT为了获得更好的性能会对语句重排序,但是 volatile 类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。 volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。某些情况下,volatile 还能提供原子性,如读 64 位数据类型,像 long 和 double 都不是原子的(低32位和高32位),但 volatile 类型的 double 和 long 就是原子的.

Comparator和Comparable的区别

Comparable 接口用于定义对象的自然顺序,而 comparator 通常用于定义用户定制的顺序。Comparable 总是只有一个,但是可以有多个 comparator 来定义对象的顺序。


Fail-fast和Fail-safe有什么区别

Iterator的fail-fast属性与当前的集合共同起作用,因此它不会受到集合中任何改动的影响。Java.util包中的所有集合类都被设计为fail->fast的,而java.util.concurrent中的集合类都为fail-safe的。当检测到正在遍历的集合的结构被改变时,Fail-fast迭代器抛出ConcurrentModificationException,而fail-safe迭代器从不抛出ConcurrentModificationException。


简述JVM内存分配

  1. 基本数据类型变量和对象的引用都是在栈分配的
  2. 堆内存用来存放由new创建的对象和数组
  3. 类变量(static修饰的变量),程序在加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中
  4. 实例变量,当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量,是根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的物理位置。实例变量的生命周期: 当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收名单中,但并不是马上就释放堆中内存。
  5. 局部变量: 由声明在某方法,或某代码段里(比如for循环),执行到它的时候在中开辟内存,当局部变量一但脱离作用域,内存立即释放

父类的静态方法能否被子类重写

不能, 重写只适用于实例方法, 不能用于静态方法, 而子类当中含有和父类相同签名的静态方法, 我们一般称之为隐藏


怎么唤醒一个阻塞的线程

如果线程是因为调用了wait()、sleep()方法而导致的阻塞,可以中断线程,并且通过抛出InterruptedException来唤醒它;如果线程遇到了IO阻塞,无能为力,因为IO是操作系统实现的,Java代码并没有办法直接接触到操作系统。


HashMap的实现原理

http://www.cnblogs.com/chenssy/p/3521565.html

HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个链表散列的数据结构,即数组和链表的结合体。
当我们往Hashmap中put元素时,首先根据key的hashcode重新计算hash值,根据hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放入链尾.如果数组中该位置没有元素,就直接将该元素放到数组的该位置上.
需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)


2张图记住Java的集合框架

图1 图2

JVM相关

深入JVM垃圾回收算法
http://gityuan.com/2016/01/09/java-memory/
小节:
JVM内存整理算法

分代收集只是根据对象生存周期的不同来选择不同的算法,其本身并没有任何新思想。


static关键字

public class Test {
    static int i = 0;
    public int test() {
        i++;// 1
        return i;
    }
    public static void main(String[] args) {
        Test test = new Test();
        test.test();
        System.out.println(new Test().test());
    }
}
// 输出结果为2

内部类的初始化

public class Outer {
    public void someOuterMethod() {
        // line3
        new Inner();// 正确的初始化内部类
    }

    public class Inner {
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        // line8
        // new Inner(); // error, 不能直接new内部类
        // new Outer.Inner(); // error, 没有这种写法
        // new outer.Inner(); // error,
    }
}

Thread

public class X extends Thread implements Runnable{
    public void run() {
        System.out.println("this is run()");
    }
    
    public static void main(String[] args) {
        Thread thread = new Thread(new X());// Thread implements Runnable
        thread.start();
    }

}
// 输出this is run()

原码反码与补码

http://www.cnblogs.com/wxf0701/archive/2008/08/14/1267639.html
在计算机系统中,数值一律用补码来表示(存储)。
主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补
码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
补码与原码的转换过程几乎是相同的。
已知原码求补码
数值的补码表示也分两种情况:
正数的补码:与原码相同。
例如,+9的补码是0000 1001。
负数的补码符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1
例如,-7的补码:因为是负数,则符号位为“1”,整个为10000111;其余7位为-7的绝对值+7的原码
0000111按位取反为1111000;再加1,所以-7的补码是11111001。

已知补码求源码
已知一个数的补码,求原码的操作分两种情况:
(1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。
(2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1
例如,已知一个补码为11111001,则原码是1000 0111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为 “1”;其余7位111 1001取反后为000 0110;再加1,所以是1000 0111。


StringBuffer是如何实现线程安全的?

synchronized关键字


了解过HTTP吗?说说它的特点,它里面有哪些方法,有了解过吗?知道 HTTPS 吗?这两者有什么区别?

关于HTTP协议,一篇就够了

Http和https的区别

  1. Https是ssl加密传输,Http是明文传输
  2. Https是使用端口443,而Http使用80
  3. HttpsSSL+HTTP协议构建的可进行加密传输、身份认证的网络协议要比Http协议安全
  4. Https协议需要到CA申请证书

ssl是什么?: SSL(Secure Sockets Layer 安全套接层), 及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。 TLS与SSL在传输层对网络连接进行加密。
CA是什么?: 证书机构


你平常是怎么进行加密的? MD5加密是可逆的吗?

对称加密: AES,DES
非对称加密: RSA、DSA(数字签名用), ECC(移动设备用)
HASH算法: MD5,SHA1

对称:使用相同密钥,需要在网络传输,安全性不高。
非对称:使用一对密钥,公钥和私钥,私钥不在网络传输,因此安全性高。
Hash算法: Hash算法特别的地方在于它是一种单向算法,用户可以通过Hash算法对目标信息生成一段特定长度的唯一的Hash值,却不能通过这个Hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。

MD5加密是不可逆

Base64算法: Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节可表示4个可打印字符。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。
Base64算法


ArrayList源码分析

http://www.jianshu.com/p/f10edaec36fa


了解过Java的集合吗?说说HashMap的底层实现原理?ArrayList 和 LinkedList 的区别?Java 集合中哪些是线程安全的?

在你写代码的过程中有使用过设计模式吗?你知道哪些?为什么要这样用,能解决什么问题?
了解注解吗?了解反射吗?为什么要使用反射?
数据结构中常用排序算法?

上一篇下一篇

猜你喜欢

热点阅读