java面试知识点整理(持续更新)
此处记录一些java面试常常考察的知识点,方面自己复习,如果有不对的地方欢迎指正.
1.JVM内存模型:
分为程序计数器,java虚拟机栈,本地方法栈,java堆,方法区.
Java1.7时候讲常量池从方法区移到了java堆(原因是因为方法区内存大小固定,容易产生内存溢出),1.8的时候取消了方法区,改为元空间,存在本地内存区域,和堆独立.
2.类加载:
a.加载:获取定义此类的二进制字节流
b.验证: 文件格式验证,元数据验证,字节码验证以及符号引用验证。
c.准备: 为类变量分配内存并设置初始值
d.解析: 解析时虚拟机将常量池中的符号引用替换为直接引用的过程。
e.初始化:(4种情况)
1)当使用new关键字实例化对象时,当读取或者设置一个类的静态字段(被final修饰的除外)时,以及当调用一个类的静态 方法时(比如构造方法就是静态方法),如果类未初始化,则需先初始化。
2)通过反射机制对类进行调用时,如果类未初始化,则需先初始化。
3)当初始化一个类时,如果其父类未初始化,先初始化父类。
4)用户指定的执行主类(含main方法的那个类)在虚拟机启动时会先被初始化。
3.java内存模型(JMM):
定义了一个线程对另一个线程可见。共享变量存放在主内存中,每个线程都有自己的本地内存,当多个线程同时访问一个数据时,可能本地内存没有及时刷新到主内存,所以就会发生线程安全问题。
4.gc:
大多数的刚创建的对象会被分在Eden区(大多数很快就会消亡),Eden区满了以后,进行一次Minor GC,仍然存活下来的对象复制到存活区From(两个Survivor区必定一个是空的)
下次Eden区满了,再执行一次Minor GC,将消亡的对象清理掉,将存活的对象复制到TO 中,然后清空Eden区同时也 将From 中消亡的对象清理掉,将存活的对象也复制到TO 区,然后清空From区;之后,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。
默认切换15次(MaxTenuringThreshold)后,仍然存货的对象复制到老年代.
当老年代空间不足的时候,会触发Full GC,速度一般比Minor GC慢10倍以上.
永久代(方法区): XX:MaxPermSize进行设置
5.hashmap源码:
a.有一个叫做 Entry内部类,用来存放key-value对
b.Entry存在叫做table的数组中
c.table的索引在逻辑上叫做”桶”,它存储链表上的第一个元素
d.key的hashcode()方法用来找到Entry对象所在的桶
e.key的equal()方法保证key的唯一性
f.value的hashcode()方法和equal()方法没有用.
6.concurrenthashmap源码:
Node数组+链表+红黑树实现
CAS算法+synchronized保证线程安全
jdk1.8以后的结构和hashmap类似
7.线程
a.进程是资源分配的一个独立单元,线程是CPU调度的基本单元
b.一个进程可以有很多个线程,并且线程共享整个进程的资源,一个进程至少包括一个线程
c.进程创建调用fork或者vfork,线程创建调用pthread_create,进程结束会销毁它的所有线程,线程结束不影响同进程中的其他线程
d.线程是轻量级的进程
e.线程中执行时一般要进行同步和互斥
8.线程池源码
重要参数:
- corePoolSize:核心线程数,可以理解成即使没有任务,线程池也会维护线程的最少数量。(只不过是睡眠状态,来了一个任务唤醒一个)
- maximumPoolSize:线程池维护线程的最大数量(任务超过corePoolSize且缓冲队列也满的时候,会新创建线程)
- keepAliveTime: 线程池维护线程所允许的空闲时间(只有线程数大于corePoolSize时候才会生效)
- workQueue:线程池用的缓冲队列
- handler: 线程池中的数量大于maximumPoolSize,对拒绝任务的处理策略
execute源码:
- 活动线程数小于corePoolSize时候,创建新的线程
- 活动线程数大于corePoolSize的时候,将任务加到队列中
- 任务队列满了以后创建新的线程,如果达到maximumPoolSize的话就拒绝任务
9.数据结构:
10.排序
11.树(B树,B+树)
先序中序后序排列算法:
详见idea
B树与B+树的区别:
- B+树种只有叶子节点有指向记录的指针,B树所有节点都带有,内部结点出现的索引项不会再出现在叶子节点中
- B+树种所有叶子节点都是通过指针连接在一起,而B树没有
B+树的有点:
- 非叶子结点不会带上指针,这样的话,一个块可以容纳更多的索引项,从而可以降低树的高度,而且一个内部类可以定位更多的叶子节点.
- 因为叶子节点之间有连接,所以范围扫描将会很简单,而B树需要在叶子节点和内部结点不停往返移动
B树的优点:
对于内部结点,可以直接得到,二不必根据叶子结点定位
12.堆
13.数据库
14.ACID
15.索引源码
在MySQL中,不同存储引擎对索引的实现方式是不同的
MyISAM引擎索引实现:(非聚集索引)
- 使用B+树作为索引结构,叶节点存放的是数据记录的地址
- 主索引和辅助索引无太大区别,只是主索引要求key唯一
InnoDB引擎索引实现:(聚集索引)
- 使用B+树
- 数据文件本身就是索引文件
- 要求必须有主键
- InnoDB的辅助索引的data域存放的是主键的值,而不是地址,故辅助索引需要搜索两遍,先通过副主索引找到主键,再通过主索引找到记录.
因为所有辅助索引都引用主索引,所以主索引的字段不宜过长
索引优化:
- 联合索引,最左前缀原理
- 前缀索引:用列前缀代替
- 主键外键一定要建索引
- where,on,group by,order by等字段要建索引
- 区分度高的列要建索引
16.锁机制
锁的分类(oracle)
一、按操作划分,可分为DML锁、DDL锁
二、按锁的粒度划分,可分为表级锁、行级锁、页级锁(mysql)
三、按锁级别划分,可分为共享锁、排他锁
四、按加锁方式划分,可分为自动锁、显示锁
五、按使用方式划分,可分为乐观锁、悲观锁
表级锁(整张表加锁),行级锁(当前行加锁,行级锁基于索引),页级锁
MySQL:
MyISAM和MEMORY采用表级锁(table-level locking)
BDB采用页面锁(page-level locking)或表级锁,默认为页面锁
InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁
17.数据库三范式
第一范式:数据库字段具有原子性,不可再分
第二范式:每个实例或行可被唯一确定,即有主键
第三范式:这条记录中的其他字段和主键都有直接关系
18.网络
a.https是添加了加密和认证机制的http,是http+SSL的结合体
b.tcp与udp区别:
- TCP是面向连接的,UDP是无连接的;
- TCP是可靠的,UDP是不可靠的;
- TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多的通信模式;
- TCP是面向字节流的,UDP是面向报文的;
- TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信;
- TCP首部开销(20个字节)比UDP的首部开销(8个字节)要大;
19.tcp
三次握手四次挥手:
第一次握手:SYN=1(表示请求),seq=x
第二次握手:ACK=1(确认序号有效),SYN=1(表示请求),seq=y,ack=x+1(确认序号)
第三次握手:ACK=1,seq=x+1,ack=y+1
第一次挥手:FIN=1(释放一个连接),seq=u
第二次挥手:ACK=1,ack=u+1,seq=v
第三次挥手:FIN=1,ACK=1,seq=w,ack=u+1
第四次挥手:ACK=1,seq=u+1,ack=w+1
20.https与http:
一次完整的http请求:
首先域名解析(浏览器DNS缓存找,系统DNS缓存找,找不到向配置的DNS服务器地址发送域名解析请求)
然后发起tcp请求,就是三次握手
发起http请求
服务器相应,浏览器接受返回的html代码,然后解析代码,渲染页面
https连接过程:
- 客户端发送请求到服务器端
- 服务器端返回证书和公开**,公开**作为证书的一部分而存在
- 客户端验证证书和公开**的有效性,如果有效,则生成共享**并使用公开**加密发送到服务器端
- 服务器端使用私有**解密数据,并使用收到的共享**加密数据,发送到客户端
- 客户端使用共享**解密数据
- SSL加密建立………
21. spring
a.IOC
b.AOP
22.mybatis
23.数据库设计
24.分布式
25.中间件