Java面试宝典(1)

16 篇文章 0 订阅
4 篇文章 0 订阅
  1. JAVA中能创建volatile数组吗?volatile能使得一个非原子操作变成原子操作吗?
    可以,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。
    Java 中读取 long 类型变量不是原子的,需要分成两步,如果一个线程正在修改该 long 变量的值,另一个线程可能只能看到该值的一半(前 32 位)。但是volatile 型的 long 或 double 变量的读写是原子。
  2. 10个线程和2个线程的同步代码,哪个更容易写?
    从写代码的角度来说,两者的复杂度是相同的,因为同步代码与线程数量是相互独立的。但是同步策略的选择依赖于线程的数量,因为越多的线程意味着更大的竞争,所以你需要利用同步技术,如锁分离,这要求更复杂的代码和专业知识。
  3. 什么是线程局部变量?
    对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
  4. 是否可以自己写一个容器类,然后使用for-each循环吗?
    可以,你可以写一个自己的容器类。如果你想使用 Java 中增强的循环来遍历,你只需要实现 Iterable接口。如果你实现 Collection 接口,默认就具有该属性。
  5. 说出5条IO的最佳实践?
  • 使用有缓冲区的 IO 类,而不要单独读取字节或字符。
  • 使用 NIO 和 NIO2
  • 在 finally 块中关闭流,或者使用 try-with-resource 语句。
  • 使用内存映射文件获取更快的 IO。
  • 使用非阻塞式而不要使用阻塞式的IO
  1. 说出至少5点在Java中使用线程的最佳实践?
  • 对线程命名
  • 将线程和任务分离,使用线程池执行器来执行 Runnable 或 Callable。
  • 使用线程池
  • 如果可以,更偏向于使用 volatile 而不是 synchronized。
  • 优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性。
  1. 能在不进行强制转换的情况下将一个double值赋值给long类型的变量吗?
    不能,因为 double 类型的范围比 long 类型更广,所以必须要进行强制转换。
  2. 能在Switch中使用String吗?
    在jdk 7 之前,switch 只能支持 byte、short、char、int 这几个基本数据类型和其对应的封装类型。switch后面的括号里面只能放int类型的值,但由于byte,short,char类型,它们会 自动 转换为int类型(精精度小的向大的转化),所以它们也支持。jdk1.7后,整形,枚举类型,boolean,字符串都可以。
    jdk1.7并没有新的指令来处理switch string,而是通过调用switch中string.hashCode,将string转换为int从而进行判断。
  3. poll()方法和remove()方法的区别?
    poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。
  4. LinkedList和ArrayList的区别?
  • ArrayList和LinkedList可想从名字分析,它们一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,此外,它们两个都是前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列对List接口的实现。
  • 当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
  • 当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
  • 从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
  • ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
  1. hashmap的扩容问题new hashmap(19)它的长度是多少?
    初始长度是19,当达到默认加载因子的时候会进行扩容
  2. hashtable为什么是线程安全的?
    Hashtable是线程安全的,其实现方式是在对应的方法上加上synchronized关键字,效率不高,不建议使用。目前,如果要使用线程安全的哈希表的话,推荐使用ConcurrentHashMap。
  3. java异常处理怎么做?
  • 对代码块用try…catch进行异常捕获处理;
  • 在该代码的方法体外用throws进行抛出声明,告知此方法的调用者这段代码可能会出现这些异常,你需要谨慎处理。此时有两种情况:1)如果声明抛出的异常是非运行时异常,此方法的调用者必须显示地用try…catch块进行捕获或者继续向上层抛出异常;2)如果声明抛出的异常是运行时异常,此方法的调用者可以选择地进行异常捕获处理。
  • 在代码块用throw手动抛出一个异常对象,此时也有两种情况,跟上一点中的类似:1)如果抛出的异常对象是非运行时异常,此方法的调用者必须显示地用try…catch块进行捕获或者继续向上层抛出异常;2)如果抛出的异常对象是运行时异常,此方法的调用者可以选择地进行异常捕获处理。
  1. 异常处理的作用是什么?
    因为不可能保证程序不出错,所以使用异常处理来防止程序出错的时候你无从下手的局面,对于调试程序和项目实际开发都是有用的
  2. jvm内存的分配?
  • 程序计数器:线程私有,当前线程执行的字节码的行号指示器。
  • 虚拟机栈:线程私有,存放基本数据类型、对象引用和returnAddress类型。
  • 本地方法栈:为虚拟机使用到的Native方法服务。
  • Java堆:线程共享,存放对象的实例,也是GC回收器管理的主要区域。
  • 方法区:线程共享,存放已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
  • 运行时常量池:方法区的一部分,存放编译期生成的各种字面量和符号引用。
  • 直接内存:不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,容易引起OOM异常,NIO会调用,不受Java堆大小的限制。
  1. Abstract和interface区别?
  • abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
  • 在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在 interface中一般不定义数据成员),所有的成员方法都是abstract的。
  • abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。
  • 实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
  • 接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
  • 抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。
  • 接口中的方法默认都是 public,abstract 类型的。
    码巢对标阿里P6
    获取更多面试以及学习资料,请扫码加入我们的群聊以及关注我们的微信公众号
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值