Java基础面试

Java的基本数据类型

整型 byte 占用1个字节

short 占用两个字节

int 占用4个字节

long 占用8个字节

浮点型 float 占用4个字节

double 占用8个字节

字符型 char 占用2 个字节

布尔型 Boolean 占用1个字节

 

String 类可以被继承吗

不能 因为String类是被final修饰的类

  使用final修饰方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。

 

String StringBuild StringBuffer 的区别

线程安全性

  String中的对象是不可变的,所以是线程安全的

  StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的

  StringBuilder 并没有对方法进行加锁,所以是线程不安全的

 

三者在性能方面的比较:StringBuilder > StringBuffer > String

 

如果要操作少量的数据用 String

单线程操作字符串缓冲区下操作大量数据用 StringBuilder

多线程操作字符串缓冲区下操作大量数据用 StringBuffer

线程不安全性能更高,所以我们在开发中优先使用stringBuilder

 

什么是悲观锁,乐观锁

 

说一说你了解的集合

ArraryList 底层是object数组 存储有序可重复 最常用的 线程不安全 效率高,查询快增删慢

LinkedList 底层是双向链表 存储无序不可重复 线程不安全 效率高 增删快,查询慢

TreeSet 底层是树结构 存储有序

HashSet 无序不可重复 底层是使用hashMap 使用map 的key值来进行存储 通过hashcode和equals

HashMap 1.7 底层是数组加链表 key存储无序可以重复 可以为null value可以重复,Map 的key 是根据哈希和当前数组的长度计算出来的,所以它是无序的,如果key值相等,会做equals判断,如果相同则覆盖保存

1.8 之后底层是数组加链表加红黑树 存储无序键是唯一

ConcurrentHashMap 是线程线程安全的 1.7底层采用的分段式锁机制 1.8 是菜用CAS机制和synchronized同步代码块形式保证线程安全

 

Java1.5 引入泛型是解决了什么问题

将运行期遇到的问题转移到了编译期 省去了类型强转的麻烦 提高程序安全性

 

线程创建的方式有哪些?

一、继承Thread类创建线程类

(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。

(2)创建Thread子类的实例,即创建了线程对象。

(3)调用线程对象的start()方法来启动该线程。

 

二、通过Runnable接口创建线程类

(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

(3)调用线程对象的start()方法来启动该线程。

 

三、通过Callable和Future创建线程

(1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。

(2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。

(3)使用FutureTask对象作为Thread对象的target创建并启动新线程。

(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

 

线程启动的方式,sleep和wait的区别, 哪个需要被手动唤醒

1、sleep是Thread类的静态本地方法,wait则是Object类的本地方法

2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中

(sleep就是把CPU的执行资格释放出去,不在运行此线程,当定时时间结束再取回CPU 的资源,参与CPU的调度,获取到CPU的资源后就可以继续运行了,而如果sleep时该线程有锁,那么sleep不会释放这个锁,而是把锁带着进入冻结状态,也就是说其他需要这个锁的线程根本不可能获取到这个锁。也就无法执行程序。如果在睡眠时其他线程调用了这个线程的interrupt方法,那么这个线程就会抛出interruptexception异常返回,这点和wait是一样的)

3、sleep方法不依赖与同步器synchronized ,但是wait需要依赖synchronized关键字

4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人打断)

5、sleep一般用于当前线程休眠,或者轮询暂停操作,wait则多用于多线程之间的通讯

6、sleep会让出CPU执行时间并强制上下文切换,而wait不一定,wait后可能还是有机会重新竞争到锁继续执行的

 

Java的反射机制

指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法.这种动态获取信息,以及动态调用对象方法的功能叫java语言的反射机制

posted @ 2021-03-18 00:49  余一洋  阅读(45)  评论(0编辑  收藏  举报