6.30 Java面试

1.HashMap和HashTable区别?HashMap的原理?如何实现线程安全的HashMap(ConcurrentHashMap原理)?

HashMap是基于哈希表实现的,每个元素是一个key-value对,内部通过单链表解决哈希冲突。
HashMap存放数据过程:
HashMap内部维护了一个Entry数组,每一个Entry实际上是一个链表,在添加一个key-value键值对时,首先通过hash(key)函数计算哈希值,然后通过index索引计算出key-value对应的存放位置(哈希值 & 0x7FFFFFFF实现均匀散列,比取模效率高),若某位置上的key和hashcode相等,则进行覆盖,否则将value插入到头节点。
HashMap的默认数组长度为16,size记录所有元素数量,threshold是HashMap阈值,用于判断是否需要扩容(size>threshold),注意,扩容是新建一个2倍大小的HashMap,重新计算hash值索引并复制,比较耗费性能。

jdk1.8优化:当Hash冲突严重,数组上的链表长度过长时,会降低查询效率,jdk1.8增加了树阈值用于判断是否需要将链表转换为红黑树,每增加一个元素都会判断当前链表是否需要转为红黑树

HashTable与HashMap结构相近,不同点在于:
1.Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类,二者都实现了Map接口
2.Hashtable 中的方法是Synchronize修饰线程安全的。
3.HashTable不允许key-value为null,
4.HashTable在不指定容量的情况下的默认容量为11,而HashMap为16;Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍

ConcurrentHashMap原理
CHP在Entry数组的基础上进行了分段,关键用了volatile修饰value值和链表,保证了可见性,同时采用了分段锁技术,其中Segment继承于ReentrantLock,当一个线程占用锁访问一个Segment时,不会影响到其他的Segment访问。

jdk1.8优化:同样为了解决查询效率低,增加了红黑树,抛弃了原来的分段锁,而是采用了CAS和Synchronized保证并发安全。详情见博客put(),get()方法。
面试详细阐述get(),put(),扩容操作,多总结多表达。
博客详情

2.Synchronized的使用与底层原理,除了Synchronized锁还有哪些方法实现线程安全?Volatile原理?

实现并发的几种方式:
①synchronized同步方法
②synchronized同步代码块
③使用volatile 原理:多线程访问volatile修饰的变量时都是从内存中读取,而不是从线程缓存读取,因此每个线程访问到的变量值都是一样的。以此保证同步
④使用重入锁ReentrantLock
⑤使用ThreadLocal管理局部变量,每个线程会创建该变量的独立副本,不受其他线程影响。
⑥线程需要同步的根本原因在于对共享变量的操作不是原子的,因此可以将一些共享变量设为原子类

3.MySQL两种引擎区别?什么是聚簇索引和非聚簇索引?查询性能下降如何优化?

常用的有InnoDB和InnoDB
InnoDB是MySQL默认的引擎,主要原因在于:1.支持事务ACID属性 2.支持行级锁,高并发 3.支持外键约束 4.索引更高效
两种引擎的区别:
① InnoDB索引是聚簇索引,InnoDB是非聚簇索引
② InnoDB主键索引的叶子节点存放行数据,因此索引效率高;MyISAM叶子节点存放的是行数据的地址,需要二次寻址。
③ InnoDB锁粒度是行级的,MyISAM锁粒度是表级的。
④ InnoDB同时缓存索引和数据,而MyISAM只缓存索引
⑤ InnoDB 哈希索引√全文索引× MyISAM 哈希索引× 全文索引 √
————————————————
聚簇索引:
数据存储与索引存放在一起,找到索引也就找到了数据。
非聚簇索引是指索引与数据分开,访问数据时先通过索引到磁盘找相应数据。
应用场景:
InnoDB:支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。

MyISAM:插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比 较低,也可以使用。
————————————————
索引
索引本身是一种数据结构,是为了帮助快速查找数据,其实现通常是B树/B+树(大多数场景,范围查询)或哈希索引(查询单条记录,对等=查询),通俗的说就是帮助查找的目录。
索引的四种类型:主键索引(表唯一),唯一索引,普通索引,全文索引
索引查询方式:
主键索引区:PI(关联保存的时数据的地址)按主键查询,
普通索引区:si(关联的id的地址,然后再到达上面的地址)。所以按主键查询,速度最快
索引原理:
6.30 Java面试6.30 Java面试
数据库为什么使用B+树而不是B树?
1.B树只适合随机检索,而B+树支持顺序检索和随机检索
2.B+树查询效率更稳定,空间利用更好,可以减少IO次数,增删节点(文件)更快

4.TCP为什么三次握手,两次会产生什么问题,第三次握手失败怎么处理?

网上答案:第三次握手是为了防止已经失效的连接请求报文又传到了服务端,产生错误。
根据TCP服务器和客户端的状态,第三次握手失败服务器不会重传ack报文,而是直接发生RTS报文,进度CLOSED状态,这么做的目的是防止SYN洪泛攻击

两次握手的问题:
两次握手,客户端收到服务端的应答后进入ESTABLISHED(已建立连接状态),而服务端在收到客户端的连接请求之后就进入了ESTABLISHED状态。如果出现网络拥塞,客户端发送的连接请求报文A过了很久没有到达服务端,会超时重发请求报文B,服务端正确接受并确认应答,连接建立并开始通信传输数据,等通信结束之后释放连接。此时,如果之前失效的连接请求A到达服务端,由于两次握手就能成功建立连接,服务端收到请求A之后进入ESTABLISHED已建立连接状态,等待发送数据或者主动发送数据,此时,客户端已经进入CLISED断开连接状态,服务器会一直等下去,浪费服务器连接资源。
解释
洪泛攻击
解决方法:
对于SYN泛洪攻击的防范,优化主机系统设置是常用的手段。如降低SYN timeout时间,使得主机尽快释放半连接的占用;又比如采用SYN cookie设置,如果短时间内连续收到某个IP的重复SYN请求,则认为受到了该IP的攻击,丢弃来自该IP的后续请求报文。此外合理地采用防火墙等外部网络安全设施也可缓解SYN泛洪攻击。
————————————————