java面试考点

1、round()方法“四舍五入”,其实非也,它的实现是Math.floor(x+0.5);floor地板就是向下取整的方法。round(-1.7)的结果是-1,而不是-2。

2、String str = "i";和 String str = new String("i");的区别?

答:①存放空间不同,前者存放在方法区的常量池中,后者存放在堆上。

  ②使用方式不同,"i"本身就代表常量池地址,常量池不准有两个不同常量,s1 = "i"与s2 = "i"指向同一块地址空间;

  但,s1 = new String("i")与s2 = new String("i")指向不同的地址空间。

3、==和equals()的区别是非常重要的。

  • ==比较的是引用
  • equals()方法比较的是实际内容,但是要注意,equals()方法默认是比较引用的(即从Object类继承而来的),只有重写了equals()方法才可以比较对象实际内容。

4、逻辑操作符&&与II有一个短路的问题,如(表达式一)&&(表达式二),一旦明确了整个式子的值就不会计算后面的表达式,即“表达式一”值为false整个表达式就为false,便不会再计算“表达式二”了。

5、访问权限

public > protected > friendly > private

其中类只有,public和friendly两种权限

protected:包访问权限 + 子类访问权限

friendly:包访问权限

解释:被friendly修饰的属性,在同一个包中对子类可见,在不同包中对子类不可见。被protected修饰的属性与方法,在不同包的子类中也可见。

6、初始化过程

①有基类先初始化基类静态变量和语句块

②初始化子类的静态变量与语句块

③初始化基类实例变量和语句块

④执行基类构造函数

⑤初始化子类实例变量和语句块

⑥执行子类构造函数

7、final关键字总结

  (1)final修饰数据,表示常量,必须在定义处或者构造器中进行初始化

  (2)  final修饰方法,第一种表示内联函数(现在已经过时,现在把关于性能的问题都交给编译器和虚拟机了)

    第二种表示:此方法禁止被覆盖,入过个覆盖会报错。

  (3)final修饰类,表示此类不可被继承(抽象类不可以被final修饰)

8、抽象类

抽象类不一定要有抽象方法

抽象类与接口的区别

  • 一个是类一个是接口
  • 接口中方法默认public,抽象类中任意
  • 抽象类中不全是抽象方法,接口中全是抽象方法

9、String、StringBuilder、StringBuffer的区别

String与StringBuilder:String是不可改变的,所有的操作都会生成新的String对象;StringBuilder准许在原串的基础上操作,适合于操作字符串多的情况。

StringBuilder与StringBuffer:前者是线程不安全的,但是更高效;后者是线程安全的,适用于多线程环境。

10、反射

反射:将类的成员封装成其他的对象,Class类与reflect包共同对反射机制提供了支持。

反射的原理:将字节码文件中的域、构造方法、方法、映射成Field、Constructor、Method类。

获得Class对象的三种方法

  • Class.forName(String name)
  • ClassName.class
  • 对象.getClass()

Class类的常用方法

与Field相关:

  • getField(String name):获得public的指定字段
  • getFields():获得所有public字段,返回Field[ ]
  • getDeclaredField(String name):获得指定的声明字段
  • getDeclaredFields():获得所有声明字段

与Method相关:

  • getMethod(String name, Class<?> ....parameterTypes):获得指定public方法
  • getMethod():获得所有public方法
  • getDeclaredMethod(String name, Class<?>....parameterTypes):获得声明的指定方法
  • getDeclaredMethods():获得声明的所有方法

与Constructor相关:

  • getDeclaredConstructor( Class<?>....parameterTypes):获得声明的构造方法
  • getDeclaredConstructors():获得声明的所有构造方法

其他:

  • getName():获得类的名称
  • newInstance():创建新的实例

Field类的常用方法

  • setAccessible():取消对成员的访问限制检查,用其访问私有成员
  • get(Object o):获得制定对象相应字段的值
  • set(Object o, Object Value):设置指定对象相应字段的值

Method类的常用方法

  • invoke(Object o, Object....args):调用指定对象的相应方法

 Constructor常用方法

  • newInstance(Object...args):调用类的构造函数创建新的实例

反射创建对象的两种方式

  • Class.newInstance():类必须有默认构造函数
  • constructor.newInstance():任何构造函数都可

11、hashCode()与equals()

hashCode():默认情况使用对象地址计算散列码

equals():默认情况下比较对象的地址

12、Comparable与Comparator区别

Comparable:实现compareTo(T  o),是元素的自然顺序,一般是元素继承

Comparator:是比较器实现compare(o1, o2),一般是内部类实现

 13、快速失败(fail-fast)与安全失败(fail-safe)机制的区别

快速失败:所有的java.util包下的集合都是快速失败机制,当一个线程在遍历集合时,另外一个线程对集合做出来修改,就会抛出ConcurrentModificationException,通过检查一个变量是否被修改来实现的。

安全失败:所有的juc包下的集合都采用安全失败机制,使用volatile数组,在“添加/修改/删除”数据时,会先拷贝副本,对副本操作,在复制给volatile数组。

 14、HashMap性能调优

容量:表中的桶位

初始容量:默认16

尺寸:当前存储的项数

负载因子:尺寸/容量 默认0.75 空间和效率的平衡

树化阀值:桶位中的项数,默认8 ---指链表

反树化阀值:桶中的项数,默认6

最小树化容量:默认64,容量没有达到64优先进行扩容,达到64并且达到树化阀值进行树化

数组+链表的数据结构,元素数量超过负载因子先扩容,桶位到达64,桶内元素到达8,链表树化。

处理哈希冲突的方法:拉链法和开放定址法(线性探测--同义词聚集现象)

15、实现用于容器的类

唯一性:实现equals()

散列:实现hashCode()

有序:实现Comparable接口

16、ArrayList扩容

数组容量增减1.5倍,把旧数组复制

 17、int的范围

-2^31__2^31-1

18、序列化

原理:将对象转化成能够保存在数据库或文件中的字节序列,并能够将字节序列还原。

ObjectOutputStream与ObjectInputStream对序列化提供了支持。

序列化需要实现Serializable和Externalizable接口

后者提供了订制序列化,但是因此也暴露了接口,恶意类可以利用接口修改数据。

transient和static修饰的变量不可序列化。

如果类中含有不可序列化的成员变量可以通过transient轻松解决。

如果不指定SerialVersionUID,虚拟机会自动生成,但是代价是如果改变类结构所有旧的序列化对象均不可用。

使用场景

  • 将内存中的对象保存到文件或数据库中
  • 在网络上传播对象
  • RMI

19、IO流

InputStream

  • ByteArrayInputStream
  • FileInputStream
  • PipedInputStream
  • FilterInputStream
    • BufferedInputStream
    • DataInputStream

OutputStream

  • ByteArrayOutputStream
  • FileOutputStream
  • PipedOutputStream
  • FilterOutputStream

Reader

  • CharArrayInputReader
  • FileReader
  • PipedReader
  • InputStreamReader

Writer

  • CharArrayWriter
  • FileWriter
  • PipedWriter
  • OutputStreamWriter

 20、IO模型

IO的两个过程

  • 等待数据准备好
  • 将数据拷贝到应用数据缓冲区

BIO阻塞IO:当应用线程发出IO请求,应用程序阻塞,直到内核收到数据并将数据拷贝应用缓冲区并返回结果。

NIO非阻塞IO:应用线程不断轮询,内核是否收到数据,内核马上返回结果,有数据拷贝数据没数据返回Error。

IO多路复用:一个线程管理多个连接,应用线程调用select()然后阻塞,内核轮询多个通道,一个通道有数据到来就返回。

AIO异步IO:应用线程发出IO请求,然后去做其他运算,等到内核把一切准备好了,通知应用线程。

Select:实时性要求较高的系统,可以移植性好。

poll:与select相似,没有最大描述符的限制

epoll:只需要运行在 Linux 平台上,有大量的描述符需要同时轮询,并且这些连接最好是长连接。

 21、泛型

上下界,与上下限

上限不存、下限不取

22、List、Set、Map取元素时有什么特点

  List:get(index)取相应位置元素

  Set:只能迭代,没有取单个元素的接口

  Map:get(key),根据键取值

23、多态的实现原理

  invokevirtual指令多态查找,从对象的实际类型由下而上查找,与描述符相符的方法。

24、浮点数与0比较会产生误差

  ①使用BigDecimal类

  ②两数相减去和一个很小的数比较(即精度)

  ③将两个数都乘以10的n次方比较(n为精度)

 

第十二章 迷迷糊糊的异常(一)

clone()方法解析

  

  

posted @ 2020-03-15 22:04  卑微芒果  Views(139)  Comments(0Edit  收藏  举报