AVL树的特点,红黑树的特点?
AVL树就是二叉平衡树,左右子树也都是平衡二叉树,左右子树的高度差的绝对值不超过1.红黑树是一种二叉查找树,是一种稍弱的平衡二叉树,它的旋转次数更少,红黑树插入最多需要两次旋转,删除最多需要三次旋转
索引的数据结构和原理?
索引是一种单独的,物理的对数据表中一列或多列的值进行排序的一种存储结构。索引的数据结构主要有B+树索引,B树索引。
SQL题:查询平均年龄前三的男子的年龄和所在城市?
select c.city_name,AVG(m.age) as avg_age from city join man m on c.city = m.city_id group by c.city_name order by avg_age desc limit 0,3;
四次挥手?
第一次挥手:客户端发送fin给服务端,请求断开连接
第二次挥手:服务端收到客户端的fin,确认断开客户端和服务端的连接,发送ack给客户端
第三次挥手:服务端向客户端发送数据完成后,将fin发送给客户端请求断开服务端和客户端的连接
第四次挥手:客户端收到服务端的fin后,确认断开连接,发送ack给服务端
time_wait的原因?
1)为实现tcp全双工连接的可靠释放:确保客户端最后的ack报文发送到服务端,假如发送失败,那么服务端会重发ack和fin给客户端请求客户端重新发送ack,假如没有time_wait,那么客户端就不会重发
2)为了使旧的数据包在网络中全部消失:避免下次建立连接时还存在以前的数据包
final,finally,finalize的却别?
final:是一个关键字,假如类被声明为final,那么不能被继承,将变量或方法声明为final,保证使用时不被修改
finally:在异常处理时提供finally块来执行清除操作,如果抛出异常,那么catch语句会执行,最后会进入finally块
finalize:是一个方法,使用该方法在将对象从内存中清除出去之间做必要的清理工作
tcp四层模型?
应用层,传输层,网络层,数据链路层
网络层的协议:icmp,ip
传输层的协议:tcp,udp
线程的基本状态:
new,Runnable,running,block,dead
匿名内部类?为什么使用匿名内部类传入参数时必须是final的?
匿名内部类就是没有名字的类,它只能只用一次,并且必须继承一个父类或实现一个接口
用final是为了保证数据的一致性,因为如果不用final修饰,那么这个变量可以变化,而变量变化后,匿名内部类是不知道的,因为匿名内部类是拷贝的变量的值,而不是直接使用的那个变量。而在jdk1.8中就不需要加final了,但是原来还是没变,只是一层语法糖罢了,其实底层还是加上了final的
redis的数据结构的底层实现?
string:String的底层是简单动态字符串,里面有三个属性,len,free,buf[],其中len是字符串的长度,free记录了buf数组中未使用的字节数量,buf[]保存字符串的每个元素。原因就是因为redis是用c写的,而c不会记录字符串的长度,如果要修改字符串必须重新分配内存,所以用len和free来实现了空间预分配和惰性空间释放,当进行扩展时,扩展的内存比实际的len多,进行缩短操作时不会立即回收多余的字节,而是用free记录字节的数量,等待后续使用
list:是一个快速链表,是压缩链表和双向链表的组合,可以直接获取到头,尾节点,而且能够在常数时间内的到链表的长度,也能获得指定位置的元素
zset(有序集合):是通过跳表来实现的,跳表主要有这几个部分:head,node,level,tail。当你查询的时候,它首先会在最高层查找,假如这一层的节点比查找数小,那么在这一层继续向后移动,假如发现比下一个节点大,那么跳跃到下一层,即可用向右和向下移动,直到找到该值或者最后查询不到
redis的主从复制+哨兵机制?
redis主从复制就是redis有主数据库和从数据库,主数据库负责读写操作,从数据库负责读操作,当发生写操作后自动将主数据库的操作读取到从数据库,通过主从复制可以实现数据库的读写分离,提高负载
过程:首先当一个从数据库启动时,会向主数据库发送sync命令,然后主数据库收到sync命令后会保存此时的数据快照,并将保存期间接收到的命令缓存起来,快照完成后再将快照和缓存的命令都发送给从数据库,从数据库收到后,会载入快照文件并执行收到的缓存命令
具体配置:主数据库里在它的conf文件里设置role:master,然后给它配置好从数据库的ip地址,在从数据库里面设置role:slave并配置好主数据库的host
哨兵机制:主要是用于管理多个redis服务器的,它会检查master和slave是否正常运作,当某个redis出现异常时,会向管理员或其他应用程序发送通知,如果是master出现异常时,会进行自动故障迁移操作,即将一个slave升级为master,然后更改其他的slave的master。
哨兵是一个分布式系统,可以有多个哨兵,哨兵使用流言协议来接受master的信息,并使用投票协议决定是否执行自动故障迁移操作,其中每个哨兵会向其他哨兵,master,slave定时发送消息,确认对方的状态,如果多个哨兵都报告某一个master无响应,则认为master挂掉了,然后开始选举新的master
聚簇索引和非聚簇索引?
数据库的索引从数据存储方式上可以分为聚簇索引和非聚簇索引,InnoDB使用的是聚簇索引,即在同一棵B-树中保存了索引列和具体的数据,其中叶子结点保存数据,非叶子节点保存索引,一个表只能有一个聚簇索引
聚簇索引的优点就是将索引和数据行保存在同一个B—树中,当你通过聚簇索引查询时可以直接获取数据,而非聚簇索引需要两次查找,所以效率更高
缺点是更新聚簇索引的代价很高,会强制InnoDB将每个被更新的行移动到新的位置,并且可能会导致全表扫描变慢(由于行比较稀疏或者页分裂操作)
非聚簇索引也叫作二级索引,它存放的不是数据本身,而是数据存放的地址,当你要查询一个数据时必须要进行两次查找,所以速度比聚簇索引慢。
为什么InnoDB的二级索引存储的是主键值?
这样的策略减少了当出现行移动或者数据页分裂时二级索引的维护工作,虽然使用主键值作指针会让二级索引占用更多的空间,但是却带来了在不需要在页分裂时更新指针的好处
最左前缀原则?
mysql中的索引可以以一定顺序引用多列,这种情况下当你查询的时候查询条件精确匹配索引的左边连续一列或者几列这个索引才可以生效
为什么数据库索引不使用HashMap而使用B+树?
1.hash表只能匹配是否相等,不能实现范围查找
2.当需要按照索引进行order by时,hash值没办法支持排序
3.数据量很大时,hashmap发生哈希冲突的概率也很大
4.当用b+树作为索引时,非叶子节点只保存索引,叶子节点才会保存数据
一个数组,等概率获取m个不同的元素?
mysql的可重复读是怎么实现的?
通过mvcc来实现的,它的读操作只会查找数据行版本早于当前事务版本号的数据行记录,保证了读取到的数据是当前事务开始前就已经存在的数据或者是自身事务改变过的数据,并且查询时的删除版本哈要么为null,要么大于当前事务版本号
间隙锁?
间隙锁就是在一个索引记录之间的间隙上的锁,能够保证某个间隙内的数据在锁定情况下不会发生任何变化
redis哈希槽?
一个redis集群包含了16384个哈希槽,当需要放置一个key-value时,会先对key算出一个结果,然后把结果对16384求余,就可以让每个key都对应到一个哈希槽里,redis会根据节点的数量大致均等的将哈希槽映射到不同的节点,它的好处是当需要增加节点时只需要把其他节点的某些哈希槽挪到新节点就行了,而删除节点时只需要把节点上的哈希槽挪到其他节点就行了,这样就能够在不停机的状况下进行添加和移除节点操作
手写一个死锁?
手写一个oom?