Java知识体系复习笔记

笔记

收集自其他资料面经等,非原创

Java基础

1. Java程序的运行原理

跨平台性:JVM实现

2. JDK/JRE的区别

  • JDK ≈ JRE + javac
    JRE:Java Runtime Environment Java运行环境
    JDK:Java Development Kit Java开发工具包

JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些标准的类别函数库(Class Library)

3. Java的基础类型

  • char / byte / int / short / long / boolean / double / float
  • String不是基本类型

4. Java的参数传递是传值还是传引用

  • Java世界的一切对象都是指针
  • 函数调用永远是传值

引用对象本身是一个地址,所以传值的时候就是把那个地址传过去

5. StringBuffer 和 StringBuilder 的区别 / 线程安全性

@重要

  • 如果没有额外声明,所有的类默认都是线程不安全
  • StringBuilder更快,但是线程不安全,常用
  • StringBuffer稍慢,但是线程安全

6. Object中有哪些方法?

  • equals / getClass / hashCode / toString / ....

native关键字的函数是操作系统实现的

7. String中有哪些方法?

  • compareTo / indexOf / isEmpty / length / split(正则) / subString / toUpper(Lower)Case / valueOF


Java面向对象

1. ==/equals有什么区别?

  • ==是对比地址
  • equals方法可以根据需求设计

2. 深拷贝 / 浅拷贝 有什么区别?

@重要

  • 浅拷贝: 把引用的地址复制一份
  • 深拷贝:把所有东西都复制一份

3. 接口和抽象类有什么区别和联系?

  • interface(接口):定义功能,只能包含方法(实现),不能包含成员变量
  • abstract(抽象类):定义抽象的骨架实现,可以包含抽象方法或者具体实现,也可以包含成员变量
    Java8之后可以用default关键字实现interface的方法体。
    Java是单根继承的,所以只能继承一个类,但是接口可以实现若干次。

4. final的作用是什么?

  • final class:不可以被继承的类
  • final 方法():不能被覆盖的方法
  • final 变量:不可修改的变量

5. override 和 overload 有什么区别?

  • overload(重载):方法名相同,参数类型不相同的方法
  • override(重写):覆盖父类的方法


集合框架

1. HashMap原理

@重要

2. List / Set / Map 的区别

重要

  • List:有序,可重复
  • Set:无序,不可重复
  • Map:映射,kv键值对

3. HashMap 和 HashTable 的区别

  • 相同点:都基于哈希表
  • 不同点:
    • HashTable只接受非空的对象
    • HashTable是被废弃的
    • HashTable是线程安全的(方法全是用synchronized实现的),HashMap不是线程安全的(ConcurrentHashMap是线程安全的)

4. ConcurrentHashMap原理

  • Java7:
    • 分段锁:锁的时候不锁整个hash表,而是只锁一部分
      -Java8以后:
      synchronized + cas,直接用链表的头节点做为锁

synchronized是悲观锁,这种线程一旦得到锁,其他需要锁的线程就挂起的情况就是悲观锁
CAS操作的就是乐观锁,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止

5. HashSet原理

Map的Key部分就是Set,所以HashSet的设计很简单,里面维护了一个HashMap

HashSet本质Value为 static final Object 的HashMap

6. TreeSet原理

需求:

  1. 元素有序
  2. 插入/删除高效
类型 元素有序 插入效率 删除效率 描述
ArrayList 有序 插入删除效率很差
HashSet 无序 插入删除基本O(1),但是无序
LinkedHashSet 有序 只能保存插入的顺序,而不能保证元素本身的顺序
LinkedList 有序 查询非常慢
TreeSet 有序 平衡树 -> 查找插入都是O(logn)
二叉查找树:
对于所有元素:左孩子比根节点小,右孩子比根节点大
平衡树:
任何节点的左子树高度和右子树的高度几乎相等

TreeSet源码注释中的NavigableSet:

  • 可以导航的(大概就是说可以按照元素顺序排好吧)

7. equals / hashCode 区别/什么时候使用?

hashCode():返回对象的hashCode值,它可以让基于哈希表的实现变得高效,例如 hashMap


equals():判断两个对象是否一样

三个约定:

  1. 当它在同一对象上被多次调用时,必须返回相同的值
  2. 如果两个对象equals相等,hashCode必须相等
  3. 如果两个对象equals不相等,hashCode也有可能相等(碰撞)

8. ArrayList / LinkedList 区别?

  • ArrayList是可以动态扩容的基于数组的对于List接口的实现
  • LinkedList是双向链表的实现

9. 哪些集合类是线程安全的?

  • Concurrent...类 , CopyOnWriteArrayList

10. 如何保证一个集合类不被修改?

  • 可以使用Collections.UnmodifiableXXX
  • Guava 的 ImmutableXXX

11. ArrayList / Vector区别

  • 基于数组的自动扩容实现
  • Vector线程安全,但是慢,Java1.2被废弃
  • ArrayList线程不安全,但是效率高

12. 说一些常见的 List / Set / Map 实现?

  • ArrayList , LinkedList
  • HashSet , LinkedHashSet , ConcurrentHashSet , TreeSet
  • HashMap , LinkedHashMap , ConcurrentHashMap , TreeMap

13. Collection 和 Collections 有什么区别?

  • X是类名的话,Xs就是与之相关的工具方法集合


Java的异常体系

1. Java的异常体系结构?

  • Throwable:任何异常/错误的祖先类
    • Exception:异常,可以从异常状态中恢复
      • RuntimeException:预料之外 的异常,uncheckedException;通常代表一个bug
      • 其他Exception:预料之中的异常,checked;代表预期中的异常状态,例如:IOException
    • Error:无法恢复的异常状态,unchecked

2. 什么是checked/unchecked/runtime exception?

  • checked:除了unchecked,其他都是checked
  • unchecke和runtime其实是一个东西,代表一个bug

3. try/catch/finally的执行顺序

  • try:尝试做
  • catch:抓异常
  • finally:最后执行,始终会执行

4. finally中return了,会发生什么事情?

  • 会覆盖掉在这之前的return

5. throw/throws的区别?

  • throw:用于丢出异常,阻止当前程序的正常运行
  • throws:用于在方法签名声明该方法可能会丢出异常

6. final/finally/finalize的区别?

  • final class / final method / final field
  • finally:try/catch的过程中最后执行的代码块
  • finalize:在垃圾回收的时候由垃圾回收器调用


计算机的体系原理

1. 进程和线程的区别?

@重要

  • 进程:独享一个隔离的内存,文件等资源的基本程序执行单元
    • 内存空间,文件描述符(file descriptor)
  • 线程:同一个进程内的线程共享内存/文件等资源
# ps aux
# top

2. 进程和线程是如何调度的?

  • CPU调度:时间片轮转

3. Java中的线程和操作系统线程是什么关系?

  • JVM的线程和OS的线程是一一对应的
  • OS负责调度线程
    缺点:
  1. 上下文切换导致比较慢
  2. 占用资源多,内存等
  3. 不灵活,完全取决于CPU

上下文切换(context switching)
协程:用户态的线程 -> 没有以上缺点

  • 因此,Java的线程模型饱受诟病

4. 是不是有了协程一切并发问题就不存在了呢?

  • 并不会,并发问题还会存在,协程解决的只是上下文开销/资源占用/不够灵活等问题,但是死锁/竞争/临界条件等问题依然存在

5. 线程之间是如何通信的?

  • 消息队列
  • 管道(Pipe)
  • 信号(Signal)
  • 共享内存
  • 套接字(Socket)

附上一个博客:Linux 线程间通信方式+进程通信方式总结


计算机网络

1. TCP/UDP的区别?

@重要

TCP:Transmission Control Protocol 传输控制协议
UDP:User Datagram Protocol 用户数据报协议
DNF:Domain Name System 域名服务器

  • TCP :稳定可靠,纠错重新发送,但是比较慢
    • 保证交付
    • 对质量要求很高的场景
  • UDP:质量低,但是非常快
    • 尽最大可能交付
    • 对质量要求不高

2. 为什么TCP的端口最大值是65536?

  • 因为TCP端口是16位的,2^16是65536

3. TCP的三次握手和四次挥手?

@重要

  • 占坑

4. 从浏览器发出请求到服务器接收到请求发生了什么?

确定一条TCP连接:

  • srcIP 源
  • srcPort 源
  • destIP 目标
  • destPort 目标



算法与数据结构

1. 集合类中常见的数据结构?

  • ArrayList:数组,随机查找是常数时间
  • LinkedList:双链表,可当作队列
  • HashSet/HashMap:哈希表
  • TreeSet/TreeMap:红黑树
  • ConcurrentHashMap:分段+哈希表
  • LinkedHashMap:链表+哈希表

2. 链表和二叉查找树的时间复杂度区别?

  • ArrayList:寻址O(1)/更新O(n)/二分查找O(logn)
  • LinkedList:寻找O(n)/更新O(1)/查找O(n)
  • 哈希表:都是O(1)
  • 红黑树:都是O(logn)
  • 二叉查找树:都是O(logn) , 某些情况会退化成链表

3. 队列和栈分别是什么?

  • 队列:FIFO(先进先出)
    • 例子:二叉树层次遍历:ABCDEFG => A进队列,将孩子节点放进队列并出列,-B+DE-C+FG....等顺序
  • 栈:FILO(先进后出,后进先出)
    • 例子:方法栈



Web

1. 常见的HTTP状态码?

@重要

  • 2xx 一切正常/3XX 跳转/4XX 客户端异常/5XX 服务端异常
  • 200 ok/201 created/301 永久跳转/302 临时跳转/403 禁止/404 找不到/502 错误网关/503 找不到服务器/504 网关超时

2. GET/POST有什么区别?

  • GET 获取资源,只有header => 查询/获取资源
  • POST 发送数据,把重要数据放在body => 登陆,修改数据
  • GET是幂等的(多次发送和一次发送的结果完全相同),POST不是

3. Cookie和Session(会话)有什么区别?

  • HTTP协议是无状态的
  • Cookie:随着HTTP请求一起发送的一小段标识用户身份的信息(HTTP的Header里面放的一小段信息)
  • Session:放在服务端的,用于通过Cookie和用户身份对应关系来鉴权的数据

4. 什么是跨域?如何解决跨域?

同源策略:只有在向同一个域名(协议,端口)下的链接发出的http请求才会带上cookie
绕开同源策略:

  • JSONP
  • CORS(Cross-Origin Resource Sharing 跨域资源共享)
  • nginx转发(反向代理)

跨域访问,或者说 JavaScript 的跨域访问问题,是浏览器出于安全考虑而设置的一个限制,即同源策略。当 A、B 两个网站属于不同域的时候,来自于 A 网站页面中的 JavaScript 代码希望访问 B 网站时,浏览器会拒绝该访问。


类型与反射(reflaction)

1. 什么是反射?

@重要

  • 运行时行为,动态调用

2. 动态代理的原理是什么?

  • 运行时动态生成字节码,完成一些功能扩展
  • JDK动态代理:方便,受限制(只能代理接口)
  • 字节码增强:不受限制,但是麻烦,原理是子类化(final不可)

3. 反射为什么性能较差?

  • JDK无法预测被调用的方法,因此无法实施优化

4. 什么是序列化?

Java对象 ——序列化——>字节流——反序列化——>Java对象

  • 将Java对象变成字节流的过程叫序列化(serialize)
  • 将字节流变成Java对象的过程叫做反序列化(deserialize)
  • 可读:JSON/XML
  • 不可读:Java自带的序列化



Spring

1. 什么是IoC容器,为什么需要IoC?

@重要

IoC:Inverse Of Control 控制反转

  • 不需要手工控制各种对象的创建和依赖,由容器帮你完成

2. AOP与AOP原理

@重要

AOP:Aspect Oriented Programming 面向切面编程
OOP:面向对象编程

  • 面向一个特定的切面编程,使得重复的逻辑可以在一起编写,方便维护,减少重复。

XXX$$EnhanceXXX.class

3. Bean的生命周期

@重要

  • Bean从零开始:从指定的配置文件中加载BeanDefinition(定义),然后Spring容器根据该定义开始进行Bean的装配工作
  • Spring维护了一套完整的生命周期,每个Bean都可以自定义在生命周期的任何一个阶段完成的工作

4. SpringBoot相对于Spring MVC有哪些改进?

  • 自动化配置:
    • SpringMVC - 通过XML配置,手工指定
    • SpringBoot - 通过注解或者自动化扫描
  • 自带Servle容器,可以直接启动
    • SpringMVC - 不自带Servlet容器,需要额外配置
    • SpringBoot - 直接打成jar包,可以直接启动
  • SpringBoot对于微服务和快速开发更为友好
    • 优点:大大简化了开发配置的难度
    • 缺点:有很多潜在的默认约定,使得开发者更难深入了解奇中的细节
posted @ 2020-02-25 12:42  带了1个小才艺  阅读(182)  评论(0编辑  收藏  举报