sql
五表联合查询
面试八股
JDK,JRE,JVM之间的区别
JDK,Java标准开发包,它提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行时环境,以及常用的Java类库等。
JRE(Java Runtime Environment),Java运行环境,用于运行lava的字节码文件。JRE中包括了JVM以及JVM工作所需要的类库,普通用户而只需要安装JRE来运行Java程序,而程序开发者必须安装JDK来编译、调试程序。
JVM(Java virtual Mechinal),Java虚拟机,是JRE的一部分,它是整个java实现跨平台的最核心的部分,负责运行字节码文件。
String、StringBuffer、StringBuilder的区别
1.String是不可变的,如果尝试去修改,会新生成一个字符串对象,StringBuffer和StringBuilder是可变的
2.StringBuffer是线程安全的,StringBuilder是线程不安全的,所以在单线程环境下stringBuilder效率会更高
==和equals方法的区别
.==︰如果是基本数据类型,比较是值,如果是引用类型,比较的是引用地址
equals:具体看各个类重写equas方法之后的比较逻辑,比如String类,虽然是引用类型,但是sting类中重写了equals方法,方法内部比较的是字符串中的各个字符是否全部相等。
hashCode()与equals()之间的关系
如果两个对象的hashCode不相同,那么这两个对东肯定不同的两个对象
如果两个对象的hashCode相同,不代表这两个对象一定是同一个对象,也可能是两个对象。
如果两个对象相等,那么他们的hashCode就一定相同
在Java的一些集合类的实现中,在比较两个对象是否相等时,会根据上面的原则,会先调用对象的hashCodel)方法得到hashCode进行比较,如果hashCode不相同,就可以直接认为这两个对象不相同,如果hashCode相同,那么就会进一步调用equals0)方法进行比较。而equals)方法,就是用来最终确定两个对象是不是相等的,通常equalsj法的实现会比较重,逻辑比较多,而hashCode)主要就是得到一个哈希值,实际上就一个数字,相对而言比较轻,所以在比较两个对象时,通常都会先根据hashCcode想比较---下。
泛型中extends和super的区别
- <? extends T>表示包括T在内的任何T的子类
- <? super T>表示包括T在内的任何T的父类
ApplicationContext和BeanFactory有什么区别
BeanFactory是Spring中非常核心的组件,表示Bean工厂,可以生成Bean,维护Bean,而ApplicationContext继承了BeanFactory ,所以ApplicationContext拥有
BeanFactory
所有的特点,也是一个Bean工厂,但是AplicationCcontext除开继承了ReanFactoy之外,还继承了诸如EnvironmentCapable、MessageSource、ApplicationEventPublisher等接口,从而ApplicationContext还有获取系统环境变量、国际化、事件发布等功能,这是BeanFactory所不具备的
ArrayList和LinkedList区别
1,首先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的
2.由于底层数据结构不同,他们所适用的场景也不同,Arraylist更适合随机查找,LinkedList更适合删除和添加,查询、添加、删除的时间复杂度不同
3.另外ArrayList和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以当做队列来使用
B树和B+树的区别,为什么Mysql使用B+树
B树的特点:
1.节点排序
2.一个节点了可以存多个元素,多个元素也排序了
B+树的特点:
1.拥有B树的特点
2.叶子节点之间有指针
3.非叶子节点上的元素在叶子节点上都冗余了,也就是叶子节点中存储了所有的元素,并且排好顺序
Mysql索引使用的是B+树,因为索引是用来加快查询的,而B+树通过对数据进行排序所以是可以提高查询速度的,然后通过一个节点中可以存储多个元素,从而可以使得B+树的高度不会太高,在Mysql中一个nodb页就是一个B+树节点,一个imodb页默认16kb,所以一般情况下一颗两层的B+树可以存2000万行左右的数据,然后通过利用B+树叶子节点存储了所有数据并且进行了排序,并且叶子节点之间有指针,可以很好的支持全表扫描,范围查找等sQL语句。
explain分析语句
通过对explain语句的分析,可以了解查询语句的执行情况,找出查询语句执行的瓶颈,从而优化查询语句。
explain语句的基本语法如下:
explain [EXTENDED] select * from table where name = "zhangsan";
Innodb是如何实现事务的
Innodb通过Buffer Pool,LogBuffer,Redo Log,Undo Log来实现事务,以一个update语句为例:
1.Innodb在收到一个update语句后,会先根据条件找到数据所在的页,并将该页缓存在Buffer Pool中
2.执行update语句,修改Buffer Pool中的数据,也就是内存中的数据
3.针对update语句生成一个RedoLog对象,并存入LogBuffer中
4.针对update语句生成undolog日志,用于事务回滚
5.如果事务提交,那么则把RedoLog对象进行持久化,后续还有其他机制将Buffer Pool中所修改的数据页持久化到磁盘中
6.如果事务回滚,则利用undolog日志进行回滚
Java死锁如何避免
造成死锁的几个原因:
1.---个资源每次只能被一个线程使用
2.一个线程在阻塞等待某个资源时,不释放已占有资源
3,一个线程已经获得的资源,在未使用完之前,不能被强行剥夺
4.若干线程形成头尾相接的循环等待资源关系
这是造成死锁必须要达到的4个条件,如果要避免死锁,只需要不满足其中某一个条件即可。而其中前3个条件是作为锁要符合的条件,所以要避免死锁就需要打破第4个条件,不出现循环等待锁的关系。
在开发过程中:
1.要注意加锁顺序,保证每个线程按同样的顺序进行加锁2.要注意加锁时限,可以针对所设置一个超时时间
3.要注意死锁检查,这是一种预防机制,确保在第一时间发现死锁并进行解决
Java中的异常体系是怎样的
. Java中的所有异常都来自顶级父类Throwable。
. Throwable下有两个子类Exception和Error。
·Error表示非常严重的错误,通常这些错误出现时,仅仅想靠程序自己是解决不了的,可能是虚拟机、磁盘、操作系统层面出现的问题了,所以通常也不建议在代码中去捕获这些Error,因为捕获的意义不大 ,因为程序可能已经根本运行不了了。
·Exception表示异常,表示程序出现Exception时,是可以靠程序自己来解决的,比如NulPpointerBxception .llegalAcessException等,我们可以捕获这些异常来做特殊处理。
. Exception的子类通常又可以分为RuntimeException和非RuntimeException两类
. RunTimeException表示运行期异常,表示这个异常是在代码运行过程中抛出的,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生,比如NullPointerException、IndexOutOfBoundsException等。
. 非RuntimeException表示非运行期异常,也就是我们常说的检查异常,是必须进行处理的异常,如果不处理,程序就不能检查异常通过。如OException、SQLException等以及用户自定义的Exception异常。
java中有哪些类加载器
JDK自带有三个类加载器: bootstrap ClassLoader、ExtClassLoader、AppClassLoader。
.BootStrapClassLoader是ExtClassLoader的父类加载器,默认负责加载%JAVA_HOME%lib下的jar包和class文件。
.ExtClassLoader是AppClassLoader的父类加载器,负责加载%JAVA_HOME%/lib/ext文件夹下的jar包和class类。
. AppClassLoader是自定义类加载器的父类,负责加载classpath下的类文件。
Jdk1.7到Jdk1.8 HashMap发生了什么变化(底层)?
1.1.7中底层是数组+链表,1.8中底层是数组+链表+红黑树,加红黑树的目的是提高HashMap插入和查询整体效率
JVM有哪些垃圾回收算法?
1.标记清除算法:
a.标记阶段:把垃圾内存标记出来
b.清除阶段:直接将垃圾内存回收。
c.这种算法是比较简单的,但是有个很严重的问题,就是会产生大量的内存碎片。
2.复制算法:为了解决标记清除算法的内存碎片问题,就产生了复制算法。复制算法将内存分为大小相等的两半,每次只使用其中一半。垃圾回收时,将当前这一块的存活对象全部拷贝到另一半,然后当前这一半内存就可以直接清涂。这种算法没有内存碎片,但是他的问题就在于浪费空间。而且,他的效率跟存活对象的个数有关。
3,标记压缩算法:为了解决复制算法的缺陷,就提出了标记压缩算法。这种算法在标记阶段跟标记清除算法是一样的,但是在完成标记之后,不是直接清理垃圾内存,而
是将存活对象往一端移动,然后将边界以外的所有内存直接清除。
Mybatis的优缺点
优点:
1.基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
2.与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
3.很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只粟JDBC支持的数据库MyBatis都文持)。
4.能够与Spring 很好的集成;
5.提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护
缺点:
1.SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。2.SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
#{}和${}的区别是什么?
#{}是预编译处理、是占位符,KaTeX parse error: Expected 'EOF', got '#' at position 26: ...拼接符。 Mybatis在处理#̲{}时,会将sql中的#{}替...{}时,会将sql中的${}替换成变量的值,调用Statement来赋值;
使用#{}可以有效的防止sQL注入,提高系统安全性。
Mysql慢查询该如何优化?
1.检查是否走了索引,如果没有则优化SQL利用索引
2.检查所利用的索引,是否是最优索引
3.检查所查字段是否都是必须的是否查询了过多字段,查出了多余数据
4.检查表中数据是否过多,是否应该进行分库分表了
5.检查数据库实例所在机器的性能配置,是否太低,是否可以适当增加资源
Mysql锁有哪些,如何理解
按锁粒度分类:
1.行锁:锁某行数据,锁粒度最小,并发度高
2.表锁:锁整张表,锁粒度最大,并发度低
3.间隙锁:锁的是一个区间
还可以分为:
1.共享锁:也就是读锁,一个事务给某行数据加了读锁,其他事务也可以读,但是不能写
2.排它锁:也就是写锁,一个事务给某行数据加了写锁,其他事务不能读,也不能写
还可以分为:
1.乐观锁:并不会真正的去锁某行记寻,而是通过一个版号实现的
2.悲观锁:上面所的行锁、表锁等都是悲观锁
在事务的隔离级别实现中,就需要利用锁来解决幻读
Redis和Mysql如何保证数据一致
延时双删,步骤是:先删除Redis缓存数据,再更新Mysql,延迟几百毫秒再删除Redis缓存数据,这样就算在更新Mysq时,有其他线程读了Mysqpl,把老数据读到了Redis中,那么也会被删除掉,从而把数据保持一致
Redis有哪些数据结构?分别有哪些典型的应用场景?
Redis的数据结构有:
1.字符串:可以用来做最简单的数据,可以缓存某个简单的字符串,也可以缓存某个son格式的字符串,Redis分布式锁的实现就利用了这种数据结构,还包括可以实现计数器、Session共享、分布式ID
2.哈希表:可以用来存储一些key-value对,更适合用来存储对象
3.列表: Redis的列表通过命令的组合,既可以当做栈,也可以当做队列来使用,可以用来缓存类似微信公众号、微博等消息流数据
4.集合:和列表类似,也可以存储多个元素,但是不能重复,集合可以进行交集、并集、差集操作,从而可以实现类似,我和某人共同关注的人、朋友圈点赞等功能
5.有序集合:集合是无序的,有序集合可以设置顺序,可以用来实现排行榜功能