Java基础面试总结

1. 讲讲一个十进制的数在内存中是怎样存的?

以二进制补码的形式存储。

2. 请解释为什么会出现4.0 - 3.6 = 4.0000001这种现象?

计算机在计算十进制小数的过程中要先转换为二进制进行计算,而二进制的小数无法精确的表达十进制小数,所以在转换的过程中出现了误差。

3. 接口和抽象类的区别是什么?

  • 接口中的所有方法隐含的都是抽象的,而抽象类则可以同时包含抽象和非抽象方法。
  • 接口是多重实现,抽象类是单一继承。
  • 接口中的成员函数默认是public。抽象类的成员函数可以是private,protected或者是public。
  • 接口没有构造方法,抽象类可以有构造方法。

4. 面向对象开发的六个基本原则,在项目中用过哪些原则?

  • 单一原则:一个类只做它该做的事情(高内聚)。在面向对象中,如果只让一个类完成它该做的事,而不涉及与它无关的领域就是践行了高内聚的原则,这个类就只有单一原则。
  • 开闭原则:软件实体应当对扩展开发,对修改关闭,要做到开闭有两个要点:1. 抽象是关键,一个系统中如果没有抽象类或接口系统就没有扩展点;2. 封装可变性,将系统中的各种可变因素封装到一个继承结构中,如果多个可变因素混杂在一起,系统将变的复杂而繁乱。
  • 里氏替换原则:任何时候都可以用子类型替换掉父类型,子类一定是增加父类的能力而不是减少父类的能力。
  • 依赖倒置原则:面向接口编程。高层模块不应该依赖底层模块,两者都应该依赖其抽象,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代。
  • 接口隔离原则:类间的依赖关系应该建立在最小的接口上,不能大而全,接口表示能力,一个接口只应该描述一种能力,接口也应该高度内聚。
  • 迪米特法则:由叫最少知识原则,一个对象应该对其他对象有尽可能少的了解。
    根据自己的项目来聊:
    参考:https://www.cnblogs.com/qifengshi/p/5709594.html

5. Http请求的GET和POST方式的区别?

  • GET参数直接暴露在URL上,而POST将数据放在request body中
  • GET请求在URL中传送参数是有大小限制的,不能大于2KB,而POST可以说没有
  • GET在浏览器回退是无害的,而POST会再次提交请求
  • GET只接受ASCII字符,而POST没有限制
  • GET请求只能进行URL编码,而POST支持多种编码
  • GET请求参数会被完整保留在浏览器历史记录中,而POST中的参数不会被保留
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置

6. TCP 三次握手,四次挥手

参考:https://blog.csdn.net/qq_38950316/article/details/81087809

7. TCP 和 UDP区别?

  • TCP是面向连接的运输层协议。UDP是无连接的,即发送数据之前不需要建立连接
  • TCP只能一对一连接。UDP支持一对一,一对多,多对一和多对多的交互通信
  • TCP提供可靠的交付服务,提供全双工通信。UDP使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制。
  • TCP 面向字节流,头部最低20个字节。UDP是面向报文的,没有拥塞控制,适合多媒体通信要求;而且UDP首部开销小,只有8个字节。

8. 从输入网址到获取页面的过程。

  • 查询DNS, 获取域名对应的IP地址:
    分四步:1浏览器搜索自身的DNS缓存2搜索操作系统的DNS缓存3读取本地的HOST文件4发起一个DNS系统调用(宽带运营服务器查看本身缓存,运营服务器发起一个迭代DNS解析请求)
  • 浏览器获得域名对应的IP地址后,发起HTTP三次握手
  • TCP/IP建立连接后,浏览器可以向服务器发送HTTP请求了
  • 服务器接收到请求后,根据路径参数,经过后端处理将页面返回给浏览器
  • 浏览器渲染页面,和外部资源,最终将完整的页面呈现给用户

9.Session与Cookie区别?

  • Session:服务器端会为每个访问服务端的请求分配一个会话Session,其数据存储在服务器端,不依赖浏览器端环境,因此高效安全。
  • Cookie:数据已文件形式存在用户浏览器端,用户可以通过浏览器禁用Cookie,用户可以对Cookie进行查看,修改,和删除。

10. 列出自己常用的JDK包

  • java.lang 包装类,线程等都在该包
  • java.match 有BigDecimal 精确数字类型
  • java.util 并发,集合等都在该包内

11.==与equals的区别?

  • ==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
  • ==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
  • ==指引用是否相同, equals()指的是值是否相同
    总结:equals 比较两个实体值是否相同,可以被覆盖,但需要遵循几个约定。== 比较两个实体的引用地址是否相等,不能覆盖,如果引用地址相等,那认为两个实体为同一个实体

12. 请你说明符号“==”比较的是什么?

“==”对比两个对象基于内存引用,如果两个对象的引用完全相同(指向同一个对象)时,“==”操作将返回true,否则返回false。“==”如果两边是基本类型,就是比较数值是否相等。

13. hashCode和equals方法的区别与联系

对于覆盖了equals方法的类中,同样也要覆盖hashCode方法。这是JDK规定的结果。
比较两个对象是否相同,hashCode比equals效率更高,所以优先会根据hashCode来比较,但如果不重写hashCode,原本两个对象可以认为是相等,但由于hashCode默认返回表示对象地址的整数,必然不相等,所以需要重写hashCode。

14. 什么是Java序列化和反序列化,如何实现Java序列化?或者请解释Serializable 接口的作用?

序列化是一种用来处理对象流的机制,也就是将对象的内容转化成二进制流,可以将对象持久化或者网络传输反序列化是将二进制流还原为对象的过程。
实现Java序列化,通过实现Serializable即可。

15. Object类中常见的方法,为什么wait notify会放在Object里边?

因为Java提供的锁是对象级的,每个对象都有对象头,用来存储锁

16. 解释一下extends 和super泛型限定符?

  • 称为 上界限定符,list只能get,不能add(除了add null值),通常用于读
  • 称为 下界限定符,list只能add,不能get(只能用Object接收),通过用于写

17. 请列举你所知道的Object类的方法并简要说明?

Object()默认构造方法
clone()创建并返回此对象的一个副本
equals(Object obj) 当前对象是否与obj对象相同
finalize()当垃圾收集器确定该对象可以回收时,由垃圾收集器调用此方法
getClass返回一个对象的运行时类
hashCode()返回该对象的哈希码值
notify()唤醒此对象监视器上等待的单个线程
notifyAll()唤醒在此对象监视器上等待的所有线程
toString()返回该对象的字符串表示
wait()使当前线程等待,直到其他线程调用此对象的notify()或者notifyAll()方法
wait(long timeout)导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。wait(long timeout, int nanos) 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。

17. 创建线程的方式?

  • 继承Thread类创建线程,并重写run方法,调用实例对象的start()方法启动线程。
  • 实现Runnable接口,并实现run方法,将实现Runnable的类传入Thread构造函数中,并调用Thread实例对象的start方法启动线程。
  • 实现Callable接口,并实现call方法,创建Callable实现类的实例,使用FutureTask包装Callable对象,使用FutureTask对象传入Thread中,调用start方法启动线程,使用FutureTask对象的get方法获取线程的返回值。

18. ArrayList 与 LinkedList 区别?

  • ArrayList 是一种顺序存储的线性表,底层使用数组实现。
  • LinkedList是一种链式存储的线性表,本质是一个双向链表,实现了List、Deque接口,可以当成双向链表、队列、栈使用。

19. 自定义注解

  1. 声明注解的保留期限类型。
    @Retention(RetentionPolicy.RUNTIME)表示该注解可以在运行期保留
    保留期限类型:java.lang.annotation.Retention
    SOURCE: 注解信息仅保留在目标类源代码文件中,对应的字节码文件不会保留
    CLASS: 注解信息存在于源代码、字节码文件中,但运行期JVM不能获得该注解信息
    RUNTIME: 注解信息存在于源代码、字节码文件、运行期JVM中,能够通过反射机制获取注解类信息。
  2. 声明注解可以使用的目标类型。
    @Target(ElementType.METHOD) 表示这个注解只能在方法上使用
    目标类型:java.lang.annotation.ElementType
    TYPE: 类、接口、注解类、Enum
    FIELD: 类成员变量或常量
    METHOD: 方法
    PARAMETER: 参数
    CONSTRUCTOR: 构造器
    LOCAL_VARIABLE: 局部变量
    ANNOTATION_TYPE: 注解
    PACKAGE: 包
  3. 使用@interface 修饰类。
  4. 声明注解成员。
    成员无入参、不能抛出异常;
    可以通过default成员指定默认值
    成员类型只能使用基本数据类型、String、Class、enums、注解类型,及上述类型的数组类型。如ForumService value()是非法的
    如果注解只有一个成员,则成员名必须取名为value(),再使用时可以忽略成员名和赋值号,如果注解类拥有多个成员时,
    对value成员赋值,可以省略value和赋值号,如果是多个成员赋值,必须使用赋值号。

20. ArrayList扩容机制是怎么样的? 详细说一下。

在往ArrayList add元素的时候,如果ArrayList 已有元素数量+1 大于 ArrayList 存储元素的总长度,就会触发扩容。
首先ArrayList会计算新数组的长度,长度为老数组的0.5倍,如果新数组长度还是小于插入元素需要的最小长度,那么新数组长度赋值为最小长度,如果超过ArrayList允许的最大长度Integer.MAX_VALUE(),那么新数组长度为Integer.MAX_VALUE,否则为Integer.MAX_VALUE - 8(为什么要-8?Why the maximum array size of ArrayList is Integer.MAX_VALUE - 8?)
最后将原数组元素拷贝到新数组进行扩容。

21. HashMap 1.7 和 1.8 的区别

  • 1.7,在发生hash冲突的时候,数据结构只有链表;
  • 1.8,数据结构有链表和红黑树,使用红黑树是为了能够提高查询效率。在链表长度达到7时(bingCount >= TREEIFY_THRESHOLD - 1),并且hash tab[]数组长度大于等于64时,将链表转换成红黑树,如果数组长度小于64,只是对数组进行扩容
    https://blog.csdn.net/qq_21251983/article/details/90056067

22. HashMap中的key可以是任何对象或数据类型吗?

  • 可以是null,但不能是可变对象,如果是可变对象,对象中的属性改变,则对象的HashCode也相应改变,导致下次无法查找到已存在Map中的数据。
  • 如果要可变对象当着键,必须保证其HashCode在成员属性改变的时候保持不变。

23. HashMap、ConcurrentHashMap初始化阈值为什么要是8,才转为红黑树?

  1. 当初始阈值为8时,链表的长度达到8的概率变的很小,如果再大概率减小的并不明显。
  2. 树结构查找的时间复杂度是O(log(n)),而链表的时间复杂度是O(n),当阈值为8时,long8 = 3,相比链表更快,但树结构比链表占用的空间更多,所以这是一种时间和空间的平衡。

你可能感兴趣的:(Java基础面试总结)