redis有哪些数据结构?
string,hash,set,zset,list
redis的有序列表怎么实现?
跳表(实际上就是二分查找的有序链表),每个节点都有向下和向右两个节点,首先会在一层level中判断是否大于最小值,如果大于则在这一层继续向右遍历,当发现小于右侧的值时再向下一层移动,直到找到目标值或者到达最底层。跳表不仅能提高搜索性能,同时提高插入,删除效率,每个元素插入时会随机生成它的level,最底层包含了所有的元素,每个索引包含了两个指针,一个向下,一个向右
为什么redis选择跳表而不是红黑树来实现有序集合?
redis的有序集合支持的操作有:
插入元素
删除元素
查找元素
有序输出所有元素
查找区间所有元素
前面4个红黑树都可以实现,但是最后一项跳表的效率更高,在跳表中,要查找区间的元素,我们只需要定位到两个区间端点在最低层级的位置,然后按照顺序遍历就可以了,非常高效,并且跳表实现起来很容易且易读,而红黑树就算找了一个端点的值,还要通过中序遍历来找到后面的值
mysql用的什么数据结构存储,B+树是什么样的,和B树的区别,为什么用b+树不用b树
一般是B+树
b+树也是一种二叉查找树,是B树的一种变形,b+树只在叶子节点上存储数据,其他节点存储的是索引,因为B+树的磁盘IO更少,并且由于每次查询数据都是到叶子结点,所以更加稳定,而且叶子结点形成链表,所以便于范围查找
给定一个函数rand5(),该函数可以随机生成1-5的整数,且生成概率一样。现要求使用该函数构造函数rand7(),使函数rand7()可以随机等概率的生成1-7的整数?
利用rand5()函数生成1-25之间的数字,然后将其中的1-21映射成1-7,丢弃22-25。例如生成(1,1),(1,2),(1,3),则看成rand7()中的1,如果出现剩下的4种,则丢弃重新生成。
面向对象的特性?
抽象,封装,继承,多态
多态是怎么实现的?
父类或者接口定义的引用变量可以指向子类或者具体实现类的实例对象,由于程序调用方法是在运行期才动态绑定的,那么引用变量所指向的具体实例对象在运行期才确定。所以这个对象的方法是运行期正在内存运行的这个对象的方法而不是引用变量的类型中定义的方法。
三次握手的过程,为什么需要第三次?
第一次握手:客户端发送tcp包,将syn设置为1,序列号设置为x
第二次握手:服务器收到数据,将syn设置为1,ack设置为x+1,初始序列号设置为y,将tcp包发送给客户端
第三次握手:客户端确认服务端发过来的数据,将syn设置为0,ack设置为y+1,发送给服务端
三次握手完成,建立连接
因为如果去掉了第三次握手,那么服务端发送ack给客户端后,就以为建立好了连接,但是假如客户端没有收到,则不会发送请求,而服务端一直等待,这样的连接如果很多,那么服务端就会崩掉
滑动窗口是什么?
滑动窗口协议是tcp协议的一种,用来进行流量控制
tcp和udp的区别?
tcp面向连接,可靠,一对一通信,面向字节流
udp无连接,多种通信方式,面向报文
mysql数据库事务的隔离级别?
未提交读,提交读,可重复读,幻读
事务隔离级别的实现原理?
未提交读:一种乐观锁实现,对当前读取的数据不加锁,只在更新的时候加上行级锁
提交读:对当前读取的行加上行级锁,一旦读完,立即释放,更新数据时必须加上行级排他锁
可重复读:读取数据的时候加上行级共享锁,更新数据时加上行级排它锁
可串行化:读取时加上表级共享锁,更新时加上表级排它锁
mysql有哪些锁?
行级锁,表级锁,页级锁
http协议?
超文本传输协议,详细规定了浏览器和服务端通信的规则。是一种无状态的协议,只能由客户端发起,服务端不能主动向客户端发送数据
get和post的区别?
get一般来获取数据,post一般更新数据,get是将数据放在url上的,而post是放在消息体中的,由于url长度的限制,get发送的数据大小会收到限制,post更加地安全
数据库主键索引和普通索引的区别,哪个查询更快?
主键索引是一级索引,叶子节点存放的是整行数据,而普通索引是二级索引,叶子节点存储的是主键的值,如果根据主键查询则只要搜索主键id这个B+树,而如果是普通索引,要先搜索二级索引,找到对应的主键,然后再通过主键id搜索一次也就是回表。非主键索引的查询需要多扫描一棵索引树,所以效率相对较低
索引越多越好吗?索引建多了会有什么问题?对操作有什么影响?
不是,合理的索引能够加速数据查询效率,不合理的索引反而会拖累,索引越多,更新数据的速度越慢,并且不要在数据量少的表上建立索引,否则会得不偿失。经常频繁更新的列也不要建立索引
进程和线程的区别,哪个效率更高,为什么?
进程是操作系统调度的最小单元,线程是cpu调度的最小单元,一个进程可以有多个线程,不同的进程有不同的内存空间,多个线程共享一个内存空间,看情况,io密集型多线程效率高,cpu密集型进程更高
java的基本数据类型和字节数?
byte 1字节 short 2字节 int 4字节 long 8字节 float 4字节 double 8字节 char 2字节 bool 1字节
volatile关键字?
可以看做是一种轻量级的同步锁,看到的数据都是最新的数据,也就是可见性,也能禁止指令重排序,但是不能保证原子性,它的实现是是靠的lock指令,即将缓存中的数据写回到系统内存中,并且这个过程还能让其他缓存了该数据地址的数据失效,这也是可见性的实现原理
幻读?
事务在插入已经检查过不存在的数据时,突然发现数据存在,解决办法就是mvcc和间隙锁
死锁的条件?如何解决?
互斥条件,请求与保持条件,不可剥夺条件,循环等待条件
解决办法:死锁避免,死锁预防(破坏上面的四个条件中的一个就行)
进程如何进行同步?
通过信号量,管道,消息队列
如何查询比较高效?
索引
string,stringbuffer,StringBuilder的区别?
string是常量,所以不能更改
StringBuilder是变量,能够直接进行修改,但是不是线程安全的
stringbuffer是线程安全的能够直接进行修改的
HashMap为什么使用红黑树?
AVL树中,根到任何叶子的最短路径和最长路径之间的差异最多为1,而红黑树可以是两倍,虽然红黑树放弃了一定的平衡,但是当进行查找时AVL树可能需要O(Logn)次旋转,而红黑树只需要最多两次,红黑树的维护更加好
垃圾回收机制GC,cms,垃圾回收的算法?
垃圾回收就是用来回收死去的对象的,可以用引用计数法或可达性分析算法,现在一般都用可达性分析算法,因为引用计数法处理不了互相引用的问题,cms是就是并发低停顿垃圾收集器,是老年代的收集器,采用了标记清除算法,也就是初次标记,并发标记,重新标记,并发清除。
新生代采用的复制算法
tcp的连接和释放?
三次握手,四次挥手
类加载的过程,每一步做了什么?
加载,验证,准备,解析,初始化,使用,卸载
加载做的事:通过类的全限定名找到二进制字节流,将二进制字节流所代表的的静态存储结构转为运行时结构,在堆中生成class对象,作为方法区的数据的访问入口
验证:主要是为了避免对虚拟机本身造成伤害
准备:主要为类变量分配内存并设置初始值
解析:虚拟机将常量池中的符号引用转化为直接引用的过程
初始化:也就是类加载机制的最后一步,为变量赋值,赋的是自己定义的值
重载和覆盖的区别:重载是类中有多个同名的方法,只是参数不同,覆盖是子类覆盖父类的方法
返回值类型不同,不能重载,为什么?
因为编译器在编译时,不会判断函数的返回类型,只有在函数调用后才会去判断
java多线程阻塞的状态由几种?
等待阻塞,同步阻塞,其他阻塞
AtomicInteger的底层原理?
CAS,因为是无锁算法,所以是高效率的,优化的方式就是自旋的时候设置次数,如果上次获取成功了则这一次自旋的时间久一点,否则就变短自旋时间
@Transaction的原理?
自动提交:每一条语句处于单独的事件中,执行完毕后会隐式提交事务,否则隐式地回滚
原理:基于接口代理或者动态字节码代理,即jdk代理或CGLIB代理
mysql主键为什么不能过大?
因为内存很珍贵,mysql的缓冲区有限,如果主键太大,存储的索引和数据就会减少,磁盘io的概率也会增加
redis的集合有没有限制?
有因为redis的占用最大空间是500M,超过后就不行了
mysql join的底层原理?
嵌套循环算法
1:实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询结果,然后合并结果
2:如果还有第三个参与join,则再通过前两个表的join结果集作为循环基础数据,再一次通过循环查询到第三个表中查询数据,以此往复