Java面试重点合集

Java面试重点合集

红黑树

红黑树是一种平衡二叉树,是为了解决二叉树变成链表查询效率下降的问题。
红黑树有一下特点:

  1. 每个节点要么是红色,要么是黑色。
  2. 根节点是黑色。
  3. 每个叶子节点是黑色。
  4. 每个红色节点的子节点一定是黑色。
  5. 任意一个节点到叶子节点都包含了相同数量的黑色节点。

红黑树的平衡是黑色完美平衡。(就是性质5),本身并不是绝对的平衡。
红黑树有三种操作:

  1. 左旋
    以某个结点作为支点(旋转结点),其右子结点变为旋转结点的父结点,右子结点的左子结点变为旋转结点的右子结点,左子结点保持不变。如图所示:
  2. 右旋
    以某个结点作为支点(旋转结点),其左子结点变为旋转结点的父结点,左子结点的右子结点变为旋转结点的左子结点,右子结点保持不变。如图所示:

    其实这个左旋右旋和平衡二叉树的平衡调整是一个道理,反正你要保证他是一个二叉排序树的性质不能变。
    详情可看这篇文章
    红黑树与AVL树有啥区别呢?
    AVL树是带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树树高不超过1,和红黑树相比,AVL树是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而的英文旋转非常耗时的,由此我们可以知道AVL树适合用于插入与删除次数比较少,但查找多的情况.
    由于维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果应用场景中对插入删除不频繁,只是对查找要求较高,那么AVL还是较优于红黑树。

IOC

控制反转。
实体bean的构建: 1. 基于class构建 2. 构造方法构建 3. 静态工厂方法构建 4. FactoryBean 创建。

AOP及实现原理

AOP就是面向切面编程,可以横向扩展代码的功能。可无侵入的在原本功能的切面层添加自定义代码,一般用于日志收集、权限认证等场景。
使用了两种实现方式,1. JDK动态代理,实现对接口的代理。不能代理具体的类对象。 2. CGLIB 通过继承类来实现代理,不能代理final类。

RPC远程方法调用

看这篇详解

HashMap

不同的key用hashcode(有扰动函数)来决定存在数组里的位置,如果位置一样,equals()结果不同,就用链表连接,链表超过8个,就用红黑树连接。equals()相同就替换。没有key就新增,数组不够用了就扩容一倍,重新hash。并发条件下有死循环的问题,不建议用hashmap,应该用hashmap的并发版corrunthashmap。

corrunthashmap为啥安全

Innodb和myisam的区别

MyISAM不支持事务,InnoDB支持事务。
MyISAM不支持外键,InnoDB支持外键。
MyISAM是表级锁,InnoDB是行级锁。
执行大量select,myisam是最好的选择;执行大量的update和insert最好用innodb。
myisam使用非聚集索引,索引和数据分开,只缓存索引;innodb使用聚集索引,索引和数据存在一个文件。
myisam保存表具体行数;innodb不保存。

怎么找出执行很慢的SQL。

开启慢查询,执行超过多少秒就会被记录到日志中。

http1.0/2.0

1.0是短链接,每次请求都需要建立一次连接。
1.1支持持久连接,不用等待上一次请求返回结果就可以发出下一次请求。1.1支持host请求字段。1.1支持文件断点续传。
状态码 1继续处理,2成功,3重定向,4客户端错误5服务器错误
2.0 多路复用,二进制分帧(对数据进行封装),首部压缩,服务端推送,。https加密(证书,加密,公钥加密密钥,私钥解密密钥,用密钥解密正文)

三次握手和四次挥手

看这里

CMS垃圾收集器

初始标记,并发标记,重新标记,并发清除。

TCP和UDP的区别

TCP如何保证可靠传输的

一是校验和,二是seq和ack.

TCP流量控制

有个滑动窗口,接收端的缓存快满的时候,发送到会收到信号,然后不再传输,不断查询,直到接收端缓存有空间了,再继续发送。

TCP拥塞控制

慢启动,然后指数增长,后来线性增长,拥塞了之后,降到一半,再继续增长。

阻塞,非阻塞,同步,异步

cocurrentHashMap的原理

HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。这里“按顺序”是很重要的,否则极有可能出现死锁,在ConcurrentHashMap内部,段数组是final的,并且其成员变量实际上也是final的,但是,仅仅是将数组声明为final的并不保证数组成员也是final的,这需要实现上的保证。这可以确保不会出现死锁,因为获得锁的顺序是固定的。

OSI参考模型

7层 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。
应用层 针对特定应用的协议。
表示层 将应用处理的信息转化为适合网络传输的格式,或者将来自下一层的数据转换为上层能够处理的格式。
会话层 负责建立和断开通信连接,以及数据的分割等数据传输相关的管理。
传输层 起着可靠传输的作用,只在通信双方节点上进行处理,而无需在路由器上处理。
网络层 将数据传输到目标地址,目标地址可以是多个网络通过路由器连接而成的某一个地址,因此这一层主要负责寻址和路由选择。
数据链路层 负责物理层面上的互连的,节点之间的通信传输,将0,1序列划分为具有意义的数据帧传送给对端。
物理层 负责0,1比特流与电压的高低,光的闪灭之间的互换。

当你输入域名访问一个网站的时候,背后的过程是什么

  1. DNS解析,将对应的域名解析为对应的IP地址 。
  2. 根据获取的IP地址,通过三次握手建立TCP连接。
  3. 通过TCP连接发起HTTP请求。
  4. 服务器根据响应的HTTP请求,交给特定的处理器进行处理,并将结果和响应的视图进行返回。
  5. 浏览器解析并渲染试图。

中断和异常

外部引起的响应叫中断,内部cpu引起的叫异常。

用户态和内核态

一般都是在用户态,以下情况会切换到内核态:

  1. 系统调用
  2. 异常
  3. 外围设备的中断。

线程池的submit() execute()有什么区别

submit更方便,可以有返回值,可以是callable(),execute没有返回值,不方便异常处理。

多线程锁的升级原理

无锁:没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功,其他修改失败的线程会不断重试直到修改成功。

偏向锁:对象的代码一直被同一线程执行,不存在多个线程竞争,该线程在后续的执行中自动获取锁,降低获取锁带来的性能开销。偏向锁,指的就是偏向第一个加锁线程,该线程是不会主动释放偏向锁的,只有当其他线程尝试竞争偏向锁才会被释放。

偏向锁的撤销,需要在某个时间点上没有字节码正在执行时,先暂停拥有偏向锁的线程,然后判断锁对象是否处于被锁定状态。如果线程不处于活动状态,则将对象头设置成无锁状态,并撤销偏向锁;

如果线程处于活动状态,升级为轻量级锁的状态。

轻量级锁:轻量级锁是指当锁是偏向锁的时候,被第二个线程 B 所访问,此时偏向锁就会升级为轻量级锁,线程 B 会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。

当前只有一个等待线程,则该线程将通过自旋进行等待。但是当自旋超过一定的次数时,轻量级锁便会升级为重量级锁;当一个线程已持有锁,另一个线程在自旋,而此时又有第三个线程来访时,轻量级锁也会升级为重量级锁。

重量级锁:指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。

重量级锁通过对象内部的监视器(monitor)实现,而其中 monitor 的本质是依赖于底层操作系统的 Mutex Lock 实现,操作系统实现线程之间的切换需要从用户态切换到内核态,切换成本非常高。
Java为甚么要用反射看这里
或者一句话总结就是,反射赋予了Java在运行时加载编译期间完全未知的类,就是说,你编译时没他,这时候突然给Java个类,Java照样能在运行时读取这个类的参数方法等信息,并进行调用. 普通的我们是编译时就要确定这个类.有了反射,Java就有了这种动态的能力
Java为什么需要动态代理呢

posted @ 2020-01-02 14:02  时光轻轻吹  阅读(260)  评论(0)    收藏  举报