java经典面试题整理(12个题)
1、JDK1.8新特性:
https://blog.****.net/qq_29411737/article/details/80835658
Lambda表达式 lambda表达式本质上是一段匿名内部类,也可以是一段可以传递的代码
函数式接口 简单来说就是只定义了一个抽象方法的接口(Object类的public方法除外),就是函数式接口,并且还提供了注解:@FunctionalInterface
Stream API
*方法引用和构造器调用
接口中的默认方法和静态方法
新时间日期API LocalDate LocalTime LocalDateTime
表示日期的LocalDate
表示时间的LocalTime
表示日期时间的LocalDateTime
新日期api的优点 之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便,java.time.LocalDate月份和星期都改成了enum
- java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。
- java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,更加明确需求取舍
2、sql查询中 # 和 $ 的区别:
区别:
1.
# 它可以取任意类型的参数
$ 只能取对象中的值,不能取普通类型的值
2. # 取值可以有效防止sql注入,更加安全 ,$ 符号取值它是sql拼接,不能有效防止sql注入
3. # 取值让sql语句支持预编译的功能,而 $ 符号是不支持的,所以在性能上来说#取值性能要高于KaTeX parse error: Expected 'EOF', got '#' at position 25: … 4. 使用#̲一般是用来取值的,而符号一般用于动态排序;$符号内可以进行简单的运算,#内不能做运算
3、数据库表中主键自增怎么查询最后一条数据
最后一条:select * from表名 order by 表 _id desc limit 1
4、http和https的区别
http使用80端口,https使用443端口,http的连接很简单,是无状态的,而https室友ssl和http协议构建的可进行加密传输,身份认证的网络协议,要比http安全
https://前缀表明是用SSL(安全套接字)加密的,需要申请证书,一般都是要额外缴费的,web服务器启用SSL需要获得一个服务器证书并将改证书与药用的SSL服务器绑定;http不需要证书
http工作于应用层,https工作在传输层
5、http常见的状态码
200-请求成功
301-资源网页等被永久转移到其他URL
404-请求的资源不存在
500-内部服务器错误
6、Springboot、spring、springMVC的区别
spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc。
spring mvc 是只是spring 处理web层请求的一个模块。
因此他们的关系大概就是这样:
spring mvc < spring <springboot。
spring boot 我理解就是把 spring spring mvc spring data jpa 等等的一些常用的常用的基础框架组合起来,提供默认的配置,然后提供可插拔的设计,就是各种 starter ,来方便开发者使用这一系列的技术,套用官方的一句话, spring 家族发展到今天,已经很庞大了,作为一个开发者,如果想要使用 spring 家族一系列的技术,需要一个一个的搞配置,然后还有个版本兼容性问题,其实挺麻烦的,偶尔也会有小坑出现,其实蛮影响开发进度, spring boot 就是来解决这个问题,提供了一个解决方案吧,可以先不关心如何配置,可以快速的启动开发,进行业务逻辑编写,各种需要的技术,加入 starter 就配置好了,直接使用,可以说追求开箱即用的效果吧.
spring 框架有超多的延伸产品例如 boot security jpa etc… 但它的基础就是 spring 的 ioc 和 aop ioc 提供了依赖注入的容器 aop 解决了面向横切面的编程 然后在此两者的基础上实现了其他延伸产品的高级功能 Spring MVC 呢是基于 Servlet 的一个 MVC 框架 主要解决 WEB 开发的问题 因为 Spring 的配置太复杂了 各种 XML JavaConfig hin 麻烦 于是懒人改变世界推出了 Spring boot 约定优于配置 简化了 spring 的配置流程.
Spring 最初利用“工厂模式”( DI )和“代理模式”( AOP )解耦应用组件。大家觉得挺好用,于是按照这种模式搞了一个 MVC 框架(一些用 Spring 解耦的组件),用开发 web 应用( SpringMVC )。然后有发现每次开发都要搞很多依赖,写很多样板代码很麻烦,于是搞了一些懒人整合包( starter ),这套就是 Spring Boot 。
7、数据库复合索引,比如三个数据,第一个数据没有用到,这个索引条件会生效吗?
复合索引有一个最左原则,如果第一位第一个字段没有用到的话,这个索引就不会被使用;
对一张表来说,如果有一个复合索引 on (col1,col2),就没有必要同时建立一个单索引 on col1;
如果查询条件需要,可以在已有单索引 on col1的情况下,添加复合索引on (col1,col2),对于效率有一定的提高;
8、Cookie与session的区别
1,session 在服务器端,cookie 在客户端(浏览器)
2,session 默认被存在在服务器的一个文件里(不是内存)
3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id,即重写url)
4,session 可以放在 文件、数据库、或内存中都可以。
5,用户验证这种场合一般会用 session 因此,维持一个会话的核心就是客户端的唯一标识,即 session id
9、Redis持久化方法,缓存雪崩,缓存穿透和缓存击穿问题
缓存穿透:
redis中一般是key与value对应存储在内存中的,通过检索key来获取对应的数据。但当有人用key去请求一个不存在的value值,redis中检索不到对应的数据就会将请求转到数据源数据库,但这个数据在数据源中也并不存在,就会白白消耗资源。若有人利用此漏洞进行攻击可能压垮数据库。
解决方案:
通过查找资料发现一般有两种方法,第一是使用布隆过滤器(Bloom Filter),即将数据存储到一个更大的map中,当有请求不存在的数据时会被这个map拦截过滤掉,不会对后台的数据库造成压力;第二是将查询返回的结果设置为一个默认值,一般为null,并将这个结果返回到缓存中,一般返回的空值过期时间很短。
缓存击穿:
redis中有key对应的数据存在,但是过期了,这时候如果有大量并发请求过来,这些请求发现缓存过期一般都会从后端数据库加载数据并放置到缓存,这个时候大量并发的请求会给数据库带来极大压力,可能会瞬间把后端DB压垮。
解决方案:
首先这个问题,既然某个key值会被大量访问,一般就是俗称的热门key,从设计角度可以延长该key的过期时间甚至永不过期,这样可以避免大量请求转到后台;或者可以使用setnx(Set it Not exist)和添加互斥锁的方法。
缓存雪崩:
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样的短时间大范围集中失效的情况,也会给后端数据库带来很大压力。
解决方案:
出现缓存雪崩现象的根本原因就是redis缓存中的数据大范围失效,针对这一点我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
持久化方法:
Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(difference)等,还支持多种排序功能。所以Redis也可以被看成是一个数据结构服务器。
Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。
由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。
Redis跟memcache不同的是,储存在Redis中的数据是持久化的,断电或重启后,数据也不会丢失。因为Redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中,这些可以通过配置文件对其进行配置,正因为这样,Redis才能实现持久化。
10、网页怎么实现二级联动
11、mysql索引底层数据结构是什么样的
我们都知道mysql数据是以文件的形式存储在磁盘上的,而磁盘是由一圈一圈的磁道组成的,磁头移动到不同磁道,磁盘旋转,就可以读取到数据。磁盘存取原理 1.寻道时间(速度慢,费时) 2.旋转时间(速度较快);cpu读取数据都是从内存去读,内存去磁盘读取数据,内存读取磁盘数据大小都是已页的大小单位,一页=10kb;
总结:
通过上面的一些知识,我们知道当磁头移动到另一个磁道读取诗句就是我们常说的一次I/O操作,但是我们知道mysql数据是分布到不同的磁道上的,每次读取数据都要把所有磁道读取一遍,那我们进行I/O次数就很多了,查询效率就很低
那索引就是把索引字段数据的地址保存起来,来帮助mysql直接定位到哪个磁道的哪个扇区,这样就减少I/O操作了,自然查询效率就提高了
数据结构那么多,mysql索引为什么要用B+Tree数据结构,而不是其他呢?
常见的数据结构有:
1.二叉树
2.红黑树
3.Hash
4.B Tree
5.B+Tree
挨个分析:
a.二叉树
二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树组成。
不使用原因:会出现极端情况,一个节点只有一度,就是只有一个子节点,那读取树的一层就是一次I/O,那性能也不好
b.红黑树
红黑树即为平衡二叉树的一种
不使用原因:极端情况下,一个节点有2个子节点,那就出现一层只有2个节点的情况,这种性能也不好
c.hash
不使用原因:Hash是把索引数据进行Hash算法对应一个地址,我们会发现这个好像性能很好啊,直接找到,但是我们想想,它能满足我们日常开发大部分情况吗?比如通过大于或者小于去筛选数据,所以说也不合适,当然mysql还是提供了Hash索引,毕竟有些场合还是用起来也不错
d.B Tree
1.度(Degree)-节点的数据存储个数
2.叶节点具有相同的深度
3.叶节点的指针为空
4.节点中的数据key从左到右递增排列
不使用原因:虽然解决了每一层的节点数的极端情况下,但是我们会发现每个节点存储了索引和数据,那一层能存储的数据太多也不好,毕竟内存能读取的数据大小就是10kb
e.B+Tree
1.B+Tree(B-Tree变种)
2.非叶子节点不存储data,只存储key,可以增大度
3.叶子节点不存储指针
4.顺序访问指针,提高区间访问的性能
使用原因:设计有几个方面
1.非叶子节点不存储data,只存储key,可以增大度
2.叶子节点不存储指针
3.顺序访问指针,提高区间访问的性能
12、Java八大基础数据类型
个人觉得这个顺序比较好记忆
数值型 | 字节数 | 非数值型 | 结果显示 |
byte | 1 | boolean | ture/false |
short | 2 | ||
char | 2 | ||
int | 4 | ||
long | 8 | ||
float | 4 | ||
double | 8 |