JAVA开发面试题

1.当数据表中A、B字段做个组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果)

答:看A、B两字段做组合索引的时候,谁在前面,谁在后面,如果A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,如果只是使用前面%,那么有索引效果,如果使用双%匹配,则无索引效果。

2.Java Object类中有哪些方法?

答:①clone()②getClass()③toString()④finalize()⑤equals()⑥hashCode()

3.HTTP协议,GET和POST的区别?

答:Form中的get和post方法,在数据传输过程中分别对应了http协议中的get和post方法。二者主要区别如下:①get是用来从服务器上获得数据而post是用来向服务器上传递数据②get将表单中数据按照variable=value的形式添加到URL后面,并且两者使用“?”连接,而各个变量之间使用“&”连接;post是将表单中的数据放在form的数据体中,按照变量和值相对应的方式,传递到action所指向URL③get是不安全的,因为在传输过程,数据被放在请求的URL中;post所有操作对用户来说都是不可见的④get传输的数据量小,而post可以传输大量的数据,所以我们上传文件只用post。⑤get限制form表单的数据集必须为ASCII字符,而post支持整个ISO10646字符集。⑥get是form的默认方法。

4.分布式、集群环境中,缓存如何刷新,如何保持同步?

答:A、缓存如何刷新:①定时刷新②主动刷新覆盖,每个缓存框架都有自带的刷新机制,或者说缓存失效机制,就拿Redis和Ehcache举例,他们都有自带的过期机制,另外主动刷新覆盖时,只需获取对应的key进行数据的覆盖即可  B、缓存如何保持同步?这个redis有自带的集群同步机制,即复制功能,具体参考:基于Redis分布式缓存实现,Ehcache也有分布式缓存同步的配置,只需要配置不同服务器地址即可,参照:Ehcache分布式缓存同步

5.一条sql执行过长时间,如何优化?

答:①在查询语句中尽量不使用*来代替所查询的字段②不要使用过多索引,优化where子句(将能过滤掉最大数量记录的条件写在最后)③having子句消耗资源大,尽量避免使用④from子句:执行顺序应从后往前,从右往左,数量较少的表放在最后

6.内存溢出可能原因和解决方法?

①内存中加载的数据量过于庞大,如一次从数据库取出过多数据。解决方法:检查对数据库查询中,是否有一次获得全部数据的查询,对于数据库查询尽量采用分页的方式查询。②集合类中有对对象的引用,使用完后未清空,使得JVM不能回收。解决方法:检查List、MAP等集合对象是否有使用完后,未清除的问题。List、Map等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。③代码中存在死循环或循环产生过多重复的对象实体。解决方法:检查代码中是否有死循环或递归调用,检查是否有大循环重复产生新对象实体④使用的第三方软件中的bug。解决方法:使用内存查看工具动态查看内存使用情况。⑤启动参数内存值设定过小。解决方法:修改JVM启动参数(-Xms,-Xmx),直接增加内存

7.java反射机制?

答:①Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法,本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。②Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译器知道运行的对象是谁。

8.bean的生命周期

实例化(Instantiation)->属性赋值(Populate)->初始化(Initialization)->销毁(Destruction)

9.SpringMVC工作原理

答:浏览器发送请求到DispatcherServlet,然后会根据请求信息匹配对应的HandlerMapping,处理器映射器解析出一个Handler由HandlerAdapter(处理器适配器)进行处理,然后适配器根据Handler找到真正的处理器方法来处理请求和业务逻辑,处理完毕后返回ModelAndView对象,视图解析器(ViewReslover)解析视图并响应给前台页面

10.对线程的理解?

答:线程:线程属于进程,是进程中的一个执行单元,负责进程的执行。在多任务操作系统中,每个运行的程序都是一个进程,用来执行不同的任务,而在一个进程中还可以有多个执行单元同时运行,来同时完成一个或多个程序任务,这些执行单元可以看做程序执行的一条条线索,被称之为线程。操作系统中的每一个进程中都至少存在一个线程,当一个Java程序启动时,就会产生一个进程,该进程中会默认创建一个线程,在这个线程上会运行main()方法中的代码。

单核心单线程CPU:cpu在多个线程之间做高速的运行,轮流执行多个线程,效率低,切换的速度(1/n毫秒)。

多线程:效率高,多个线程之间不影响。例如4核心8线程,速度是单线程cpu的8倍(每个任务被执行到的几率被提高了8倍)

11.怎么实现线程安全?

答:按照“线程安全”的安全程度由强到弱来排序,我们可以将java语言中各种操作共享的数据分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。线程安全解决方法:① 加锁 利用Synchronized或者ReenTrantLock来对不安全对象进行加锁,来实现线程执行的串行化,从而保证多线程同时操作对象的安全性,一个是语法层面的互斥锁,一个是API层面的互斥锁.②非阻塞同步来实现线程安全。原理就是:通俗点讲,就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;如果共享数据有争用,产生冲突,那就再采取其他措施(最常见的措施就是不断地重试,直到成功为止)。这种方法需要硬件的支持,因为我们需要操作和冲突检测这两个步骤具备原子性。通常这种指令包括CAS SC,FAI TAS等。③线程本地化,一种无同步的方案,就是利用Threadlocal来为每一个线程创造一个共享变量的副本来(副本之间是无关的)避免几个线程同时操作一个对象时发生线程安全问题。

12.如何实现多表联查(表与表之间怎么关联SQL语句)?

答:①left join:返回包括左表中的所有的记录和右表连接字段相等的记录 select * from A left join B on A.id = B.id ;因为left join是以左表为主表,所以只要左表有数据,不管右表有没有数据。(如果右表没有数据则为null),查询结果都会存在。②right join:返回包括右表中的所有的记录和左表连接字段相等的记录 select * from A right join B on A.id = B.id;③inner join:等值连接,只返回两个表中连接字段相等的值

13.你了解过哪些数据结构?

答:

数组:

是一块连续的数据存储在内中,按照索引执行查询和遍历速度很快, 执行增删效率不高, 因为数组一旦创建就确定了大小, 后续改动需要迁移数据 ArrayList底层就是基于数组的动态数组实现的

链表:

以链式的方式分散存储在内存中, 增删效率很高, 由于遍历需要移动指针, 所以遍历跟查找的效率不如数组  LinkList底层就是基于双向链表实现的

栈: 

像一个弹夹一样, 按照先进后出, 的原则来存储数据, 先插入的数据被压入栈底, 后插入的数据在栈顶  队列: 按照先进先出的方式操作数据, 而且队列对两端进行了定义, 队头只允许出队操作, 队尾只允许入队操作

散列表:

也叫做哈希表 是一种以 k-v 的方式直接访问的数据结构, java中的map就是实现了散列表的结构, 是当今查询速度最快的数据结构

还有树结构, 堆结构, 以及图暂时没有去了解

14.怎么实现单点登录?

答:①session广播机制实现:通过session的广播机制将服务器session中的内容赋值到其他模块所在服务器的session中,这样其他的模块也就得到了用户的登录信息,用户在访问其他模块时就不需要重复登陆了,但这种模式会多次复制session中的内容,造成用户数据的冗余存储,因此不推荐这种方式实现单点登录②cookie+redis实现:用户在项目的任意一个模块登录后,该模块会将用户的登录信息放到redis和cookie中。首先系统会将用户的登录信息存入redis中,其在redis的key生成唯一值,value值存放用户的是登录信息;然后系统会将这名用户在redis中的key值存入该用户的cookie中,用户每次访问任意模块时都会带着这个cookie;用户在访问其他模块发送请求时,都会带着客户端的cookie进行请求,而客户端的cookie已经存入了该用户在redis中的key值,其他模块在处理用户的请求时,可以先获取用户cookie中的key值,然后拿着这个key到redis中进行查询,如果在redis中能查询到该用户相应的登录信息,就说明该用户已登录,就无需用户重复登录了。③使用token实现:token 是按照一定规则生成的字符串,字符串中可以包含用户信息。开发人员可以自行定制这个生成规则,也可以使用提供好的生成规则(如使用 JWT 自动生成包含用户信息的字符串)。用户在项目的某个模块进行登录后,系统会按照一定的规则生成字符串,把用户登录之后的信息包含到这个生成的字符串中,然后系统可以将这个字符串返回,主要有两种返回方式:(1)可以把字符串通过 cookie 返回(2)可以把字符串通过地址栏返回。样用户在访问其他的模块时,每次访问的地址栏都会带着生成的字符串(或者 cookie 中带着生成的字符串),被访问模块就可以获取地址栏中的生成字符串(或者获取 cookie 中的生成字符串),然后根据字符串获取用户信息,如果可以获取到用户的登录信息,说明该用户已登录,用户就不需要重复登录了。

15.SpringBoot和SpringMVC的联系和区别

联系: Spring最初利用工厂模式(DI)和代理模式解耦应用组件,为了解耦开发了springmvc;而实际开发过程中,经常会使用到注解,程序的样板很多,于是开发了starter,这套就是springboot。

区别:①springboot是约定大于配置,可以简化spring的配置流程;springmvc是基于servlet的mvc框架,个人感觉少了model中的映射。②以前web应用要使用到tomat服务器启动,而springboot内置服务器容器,通过@SpringBootApplication中注解类中main函数启动即可。

16.char和varchar的区别

①最大长度:char最大长度是255字符,varchar最大长度是65535个字节。

②定长:char是定长的,不足的部分用隐藏空格填充,varchar是不定长的。

③空间使用:char会浪费空间,varchar会更加节省空间。

④查找效率:char查找效率会很高,varchar查找效率会更低。

⑤尾部空格:char插入时可省略,vaechar插入时不会省略,查找时省略。

17.如何利用Redis缓存,和数据库有什么不同?

答:redis和mysql的区别总结

(1)类型上:从类型上来说,mysql是关系型数据库,redis是缓存数据库

(2)作用上:mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢;redis用于存储使用较为频繁的数据到缓存中,读取速度快

(3)需求上:mysql和redis因为需求的不同,一般都是配合使用。

18.什么是gateway(API Gateway)?

网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。

API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

19.vue的生命周期 

Vue 的生命周期总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后。

①beforeCreate(创建前)②created(创建后)③beforeMount(挂载前)④mounted(挂载后)⑤beforeUpdate(更新前)⑥updated(更新后)⑦beforeDestory(销毁前)⑧destoryed(销毁后)

1.创建前:vue实例的挂载元素$el和**数据对象**data都还未初始化

2.在created阶段,vue实例的数据对象data有了,$el还没有。

3.在beforeMount阶段,vue实例的$el和data都初始化了

4.在mounted阶段,vue实例挂载完成,data.message(数据消息)成功渲染。

5.更新前/后:当data变化时,会触发beforeUpdate和updated方法。

6.销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数

20.list和map set的区别

①List、Set都是继承自Collection接口,Map则不是②List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。) ③Set和List对比:Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。  List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。 ④Map适合储存键值对的数据⑤线程安全集合类与非线程安全集合类 :LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;HashMap是非线程安全的,HashTable是线程安全的;StringBuilder是非线程安全的,StringBuffer是线程安全的。

21.ElasticSearch的大致流程

索引-> 分析 -> 检索

索引 : 将收集到的数据建立倒排索引并存储

分析 : 将用户输入的 keyword 分解为索引服务可识别的词缀

检索 : 将对应 token 与索引库中的倒排索引进行对比,并返回检索结果。

22.SpringAop是什么,有什么用处?

AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。可用于权限认证、日志、事务处理。

AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。

23.SpringCloud的执行流程?

24.SQL语句查询,内连接外连接等值连接

25.maven的特性

①核心特征:依赖管理。maven可以对成千上万个模块或者子项目进行高度控制,批量管理它们之间的依赖关系。②多模块构建。多模块有两个问题:重复操作问题的解决和重复配置问题的解决。在maven中需要定义一个parentPOM作为一组module的聚合POM。在该POM中可以使用标签赖定义一组子模块。parentPOM不会有什么实际的构建产出。而parentPOM中的build配置以及依赖配置都会自动继承给子module。③一致的项目结构。之前我们写的项目在不同的编译器里生成的目录是不同的,比如eclipse和idea就不大一样,但是maven解决了这个问题,它在任何idea中创建的项目目录结构都是一样的。④一致的构建模型和插件机制。-通过统一的pom.xml文件来配置tomcat、jetty等插件,非常方便。比如之前构建一个web项目还要各种配置tomcat服务器等的,就很麻烦。

26.如何从controller中获取request对象

答:第一种方式:通过RequestContextHolder类的方法获取requestAttributes,再从中获取请求和响应对象;第二种方式:可以将请求和响应对象抽取出来放在一个超类中,需要使用这两个对象的controller继承这个类,直接使用即可。

27.如何使用动态sql中的if

答:在项目的.xml文件中 例如: name=#{name}

28.装配bean的常用注解?组件类注解?

答:

bean自动装配:   

@Autowired @Resource   不同点:①autowried是Spring的注解,而Resource则是javax.annotation的注解②autowired默认按照类型(byType)进行注入,而Resource默认按照名称(byName)进行注入

组件类注解:

@Component:所有组件都可以使用,对另外三个注解进行了标注,可以代替另外三个组件。

@Service:标记这个类属于业务逻辑组件。

@Controller:标记这个类属于控制层的组件。

@Repository:标记这个类是持久层的组件(Dao层)。

29.SpringBoot对象单例的并发安全问题

①单例变原型:对web项目,可以Controller类上加注解@Scope("prototype")或@Scope("request"),对非web项目,在Component类上添加注解@Scope("prototype")。②线程隔离类ThreadLocal③尽量避免使用成员变量④使用并发安全的类⑤分布式或微服务的并发安全:借助于可以共享某些信息的分布式缓存中间件如Redis等,这样即可保证同一种服务的不同服务实例都拥有同一份共享信息。

30.kafka/rabbitMQ是如何使用的

31.hashMap底层是如何实现的?

答:存储:put 方法 put(key,value)  查询 : get 方法 get(key)

      HashMap 是由 数组,链表,红黑树 组成的  算法:哈希算法  

      查询快,插入和删除慢

32.Hashtable与HashMap的区别

答:Map是一个以键值对存储的接口。Map下有两个具体的实现,分别是HashMap和HashTable①HashMap是线程非安全的,HashTable是线程安全的,所以HashMap的效率高于HashTable.②HashMap允许键或值为空,而HashTable不允许键或值为空.

33.字节流与字符流的区别

答:stream结尾都是字节流,reader和writer结尾都是字符流

两者的区别就是读写的时候一个是按字节读写,一个是按字符。

实际使用通常差不多。

在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。

只是读写文件,和文件内容无关的,一般选择字节流。

34.spring的ioc和di?IOC有哪些注解?

IOC(控制反转):本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,Spring的IoC容器主要使用DI(注入)方式实现的,不需要主动查找,对象的查找、定位和创建全部由容器管理。

DI(依赖注入):  相对于IoC而言,依赖注入(DI)更加准确地描述了IOC的设计理念。所谓依赖注入(Dependency Injection), 即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关 系的目标对象 实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

35.Dubbo的注册发现流程

① 首先服务的提供者开启服务时, 将自己具备的服务注册到注册中心, 启动包括当前提供者的ip地址和端口号等信息,Dubbo会同时注册该项目提供的远程调用的方法

②消费者启动项目, 也注册到注册中心, 同时从注册中心获得当前项目具备的所有服务列表

③当注册中心有新服务出现时, 会通知已经订阅发现的消费者, 消费者会更新所有服务列表

④ RPC调用, 消费者需要调用远程方法时, 根据注册中心服务列表的信息, 只需要服务名称,

不需要ip地址和端口号等信息,就可以利用Dubbo调用远程方法了

36.负载均衡 -> Loadbalance

在实际开发中, 一个服务基本都是集群模式的, 也就是多个功能相同的项目在运行,

这样才能承受更高的并发, 这是 一个请求 到这个服务, 就需要确定访问哪一个服务器

Dubbo框架内部支持负载均衡算法, 能够尽可能的让请求在相对空闲的服务器上运行

Dubbo内置的4种负载均衡算法:

random: 随机分配策略(默认)

优点: 算法简单, 效率高, 长时间运行下, 任务分配比例准确

缺点: 偶发性高, 如果几个请求同时被随机分配到性能较弱的服务器上, 会导致异常甚至宕机

roundRobin: 权重平滑分配

优秀的权重平滑分配算法会让每个服务器都有机会运行

leastactive: 活跃度自动感知

记录每个服务器处理一次请求的时间

按照时间比例来分配任务数, 运行一次需要时间多的分配请求书较少

consistanthash: 一致性hash算法

根据请求的参数进行hash运算

因为根据参数选择服务器, 不能平均分配到每台服务器上

37.什么是http协议?

答:http超文本传输协议, 是浏览器与服务器的应用层协议, 规定了浏览器与服务器之间遵循一问一答的交互规则 ,而且http要求浏览器与服务端的传输层协议必须是可靠的传输, 因此是使用TCP协议作为传输层协议的,浏览器发送给服务器的内容称为请求Request,反之, 服务端发送给服务器的内容称为响应Response,请求和响应中大部分内容都是文本信息, 这些文本数据使用的字符集为ISO8859-1

38.三次握手, 四次挥手

答:

三次握手 -> 客户端发送SYN开始建立连接 -> 服务器收到请求后确认连接, 并指定初始化序列号 -> 客户端接收到确认信息后再次向服务器发送确认信息 -> 服务器接收到最后的确认信息后, 双方就建立起了连接

四次挥手 -> 客户端发起关闭请求 并停止发送数据 等待服务器确认 -> 接收到关闭请求后发送ACK报文表明已经收到关闭信息 -> 此时客户端也想断开连接会像客户端的第一次挥手一样 -> 客户端收到关闭请求后 会再发送ACK报文给服务端确认信息, 服务端接收到ACK报文后, 就处于关闭状态了

39.前端怎么往后端发送请求

Get请求类型: ①a标签发起请求 点击事件②事件跳转window ③iframe标签跳转

Get和Post请求均可:1、form表单提交 2、Ajax(Axios)提交

40.spring怎么截取字符串

答:String str = "错误信息";   String errMsg = str.substring(0, "具体字段大小值");

41.SQL字符串怎么拼接

答:①CONCAT() 拼接字符串基本型:SELECT CONCAT ( lastname , firstname) AS student_name FROM kalacloud_student;②2.使用空格拼接字符串:仍然使用 SELECT CONCAT() 命令,空格需要使用' ' 两个单引号引起来。SELECT CONCAT(firstname, ' ', Subject) AS StudentDetail FROM kalacloud_student;③使用特殊符号拼接字符串:SELECT CONCAT(firstname, '-', subject, '-', qualification) AS Detail FROM kalacloud_student;④在筛选查询中进行字符串拼接并显示在表格里:SELECT CONCAT(qualification, ' ', firstname, ' - ', subject) AS 候选人资料, wechat_id, phone FROM kalacloud_student WHERE qualification = 'MPhil';⑤字符串与中文文本的拼接:SELECT CONCAT('候选人:', lastname,firstname, ' 学科:',subject,' 学历:', qualification) AS 简历 FROM kalacloud_student ORDER BY qualification DESC;⑥CONCAT_WS() 仅需写一次分隔符即可拼接所有字符串:SELECT CONCAT_WS(' / ', firstname, phone, subject, qualification) AS Detail FROM kalacloud_student;⑦总结:CONCAT() 字符串拼接功能在日常工作场景中使用非常频繁,但它的原理很好理解。任何非数据库中的字符串都加上' 单引号引起来即可。

42.v-if和v-show的区别

①原理

v-show指令:元素始终被渲染到HTML,它只是简单的伪元素设置css的style属性,当不满足条件的元素被设置style=“display:none”的样,是通过修改元素的的CSS属性(display)来决定实现显示还是隐藏

v-if指令:满足条件是会渲染到html中,不满足条件时是不会渲染到html中的,是通过操纵dom元素来进行切换显示

②应用场景

v-if需要操作dom元素,有更高的切换消耗,v-show只是修改元素的的CSS属性有更高的初始渲染消耗,如果需要非常频繁的切换,建议使用v-show较好,如果在运行时条件很少改变,则使用v-if较好

43.redis的数据类型

①String字符串②List列表③Hash哈希表④SET集合⑤Zset有序集合

44.什么是gateway

答:如果当前是一个微服务项目, 那么网关就是各个微服务下模块的统一入口 , 程序中的网关就是当前微服务项目对外界开放的统一入口

当提供了统一的入口后, 就可以方便的对所有请求进行统一的检查和管理

Spring Gateway 是Spring自己编写的 SpringCloud中的组件

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/

主要功能: 由网关作为所有请求的统一入口

网关可以对这些请求进行检查

网关方便记录所有请求的日志

网关可以统一将所有请求路由到正确的模块\服务上

内置断言 -> 判断某个条件是否满足

常用  Path -> 路径 例如: /sh/**

        Query -> 是否包含指定的参数名称 例如: name -> 参数中是否包含name属性

断言关键词 : after , before, between, cookie, header, host, method, path, query, remoteaddr

时间相关 -> after, before, between

注意: Spring Gateway 依赖 与 Spring MVC 依赖在同一个项目,

在项目启动时会报错, 可以在配置文件(.yml) spring:main:web-application-type:reactive

45.ElasticSearch

答:是java开发的一个 全文搜索引擎 软件, 能够高效的从大量数据中搜索匹配指定关键字的内容 , 本质上是一个JAVA项目, 使用它进行数据的增删改查, 就是访问这个项目控制器方法(url)路径, ES也会将数据保存在硬盘上

ES使用了java的一套名为Lucene的API, 这个API提供了全文搜索引擎核心操作的接口, 相当于搜索引擎的核心支持, ES是在Lucene的基 础上进行的完善, 实现了开箱即用的搜索引擎软件

46.redis存储原理

答:Redis将内存划分为16384个区域(类似hash槽),

将数据的key使用CRC16算法计算出一个值, 取余16384 得到0~16383 ,

将这个key保存在计算结果对应的槽位, 在此查询这个key时, 直接找到这个槽位查找, 效率很高

47.消息队列

消息队列是采用异步的方式来传递数据 完成业务操作流程的业务处理方式

消息队列特征(面试题):

-> 利用异步的特性, 提高服务器的运行效率, 减少因为远程调用出现的线程等待/阻塞

-> 削峰填谷: 在并发峰值超过当前系统处理能力时, 将没有处理的信息保存在消息队列中,

 在后面出现的较闲的时间中去处理, 直到所有数据依次处理完成, 能够防止在并发峰值时, 短时间大量请求而导致的系统不稳定

-> 消息队列的延迟: 因为是异步执行, 请求的发起者并不知道消息何时能处理完成, 如果业务不能接受这种延迟, 就不要使用消息队列

消息队列异常处理(面试题):

-> 当消息队列中发生异常时, 在异常处理的代码中,

我们可以向消息的发送者发送消息, 通知发送者处理, 消息的发送者接收到消息后,

一般要手写代码回滚, 如果在回滚的代码中又发生了异常 可以将信息发给"死信队列",

死信队列没有任何处理者, 通常情况下会有专人周期性处理死信队列的消息

48.SpringData框架?

答:SpringData框架提供的基本增删改查方法, 并不能完全满足我的业务需要, 针对当前ES数据, 进行个性化的自定义查询,

SpringData自定义查询:

遵循SpringData框架给定的格式, 编写方法名称就可以自动生成查询语句

-> query(查询) 表示当前方法是一个查询方法

-> Item/Items 表示要查询的实体类, 不带s返回单个对象, 带s返回集合类型

-> By(通过): 表示开始设置条件的关键词, 类似sql中的where

-> Title: 要查询的字段名称

-> Matches: 执行的查询操作, Matches表示执行查询支持分词的字符串 类似 like

-> and/or: 多个条件之间需要使用逻辑运算符And或Or来分割, 参数赋值依据时根据方法名称参数的顺序来决定的

SpringData支持分页查询

最后一个参数的位置添加声明类型Pageable的变量

返回值类型修改Page类型, 这个类型的对象不但能够保存查询出的数据, 还能自动计算出分页信息

49.Redis缓存淘汰策略

答: Redis将数据保存在内存中, 内存中的容量是有限的

Redis内存全满, 仍然需要保存新的数据的操作, 就是缓存淘汰策略

默认 -> noeviction 返回错误(默认)

如果不想发生错误, 需要设置它满足某些条件的信息删除后, 再将新的信息保存

-> allkeys-random: 所有数据中随机删除数据

-> volatile-random: 有过期时间的数据中随机删除数据

-> volatile- ttl: 删除剩余有效时间最少的数据

-> allkeys-lru: 所有数据中删除上次使用时间最久的数据

-> volatile-lru: 有过期时间的数据中删除上次使用时间最久的数据

-> allkeys-lfu: 所有数据中删除使用频率最少的

-> volatile- lfu: 有过期时间的数据中删除使用频率最少的

缓存穿透 -- 缓存击穿 -- 缓存雪崩

50.Redis持久化?

答:RDB策略 -> RDB本质上就是数据库快照(将当前Redis中所有数据转换成二进制的对象, 保存在硬盘上), 默认情况下, 会生成一个dump.rdb的文件

优点 -> 数据是整体恢复的,

缺点 -> 生成的文件生成在硬盘上, 读写效率低, 突然断电, 只能恢复最后一次生成的rdb中的数据

AOF策略 -> 将Redis运行过得所有命令(日志)备份下来, 即使断电, 也可以根据运行过得日志, 恢复为断电前的样子

               > AOF为减少日志文件的大小 支持 AOF rewrite 能够将日志中无效的语句删除, 能够减少占用的空间

优点 -> 相对RDB, 信息丢失较少

缺点 -> 因为保存的是运行的日志, 所以占用空间较大

-- 实际开发中, RDB和AOF可以同时开启--

51.servlet生命周期总结

实例化:servlet容器创建servlet对象。默认创建servlet实例的时机:当我们发送servlet对应的请求时(在使用时创建)。类似单例模式中的懒加载方式。希望容器一旦启动,就自动创建servlet实例通过load-on-startup=1设置,正数数值越低优先级别越高,优先实例化

初始化:servlet实例一旦创建,就开始初始化一些参数配置,我们可以做一些参数配置,比如编码,可以在web.xml或注解中配置

就绪状态:当发送对应的servlet请求时,会调用service()方法,注意此时不会重新创建servlet实例,也不会调用init()方法

销毁状态:调用了destroy()方法后,当前servlet实例将会被标记为回收垃圾,会对servlet实例进行清除处理

52.mybatis原理

答: ①读取mabatis的mybatis-config.xml配置文件

   ②加载映射文件③构建SQLSessionFactory会话工厂(工厂模式)

④Executor执行器根据SqlSession传递的参数动态地生成需要执行的SQL语句操作数据库

总结:mybatis就是针对JDBC做了封装,可以根据设置的字段映射,以及配置或者脚本等拼接sql语句并执行,获取到结果集后再按照字段映射进行封装或返回值.

53.SpringBoot的执行过程是什么?

答: SpringBoot核心在于自动装配,并且约定优于配置.

SpringBoot的执行过程是run方法开始,首先创建一个SpringApplication对象,并初始化各种参数,然后调用SpringApplaction对象的run方法,并创建应用程序监听器和应用上下文,并将上下文添加到监听器中,然后创建配置环境和其他组件,最后将配置环境和其他组件添加到上下文中,并基于以上条件自动配置bean,最后run返回上下文.

54.JVM调优?

答:抱歉JVM调优这一方面我不太了解,我想知道有几个人有权限能动生产机器,能对着生产运行的机器调优..我目前所理解的调优应该是先进行代码实现,然后再考虑架构,如果到了动JVM的时候了,是不是就该考虑换人了,项目得做成多烂的时候才考虑jvm调优?

55.说几个 Spring 中用于定义组件的注解?

答:@Component @Service @Controller @Configuration @Repository @Bean

56.说几个 Spring MVC 中描述方法的注解? 

答:@RequestMapping@PostMapping@GetMapping@DeleteMapping @PutMapping   @PatchMapping @ResponseBody

57.说几个 Spring MVC 中描述方法参数的注解? 

答:@RequestParam @PathVariable @RequestBody @RequestPart

58.Spring 中常见哪些设计模式有哪些? 

1) 建造模式:BeanDefinitionBuilder

2) 简单工厂模式:BeanFactory。

3) 工厂方法模式:ProxyFactoryBean。

4) 单例模式: 单例 Bean 对象。

5) 代理模式:Aop Proxy。

6) 策略模式:AOP 代理策略, SimpleInstantiationStrategy。

7) 适配器模式:AdvisorAdapter。

8) 模版方法模式:JdbcTemplate。

9) 责任链模式:HandlerInterceptor。

10) 观察者模式:ApplicationListener

59.Spring 中定义了哪些事务隔离级别? 

1) DEFAULT

2) READ_UNCOMMITTED

3) READ_COMMITTED

4) REPEATABLE_READ

5) SERIALIZABLE

60.MyBatis 是什么? 

答:MyBatis 是一个优秀的 Java 持久层(数据访问层)框架,由 apache 的 ibatis 演变而来,它通过 XML 或注解方式将对象与 SQL 关联起来,实现了对 JDBC 操作的封装,简化 JDBC 代码手动设置参数和手动进行结果集映射的过程。

61.MyBatis 框架有什么优势和劣势? 

优势:

1) 可以更好的实现 JAVA 代码与 SQL 语句的分离,提高可维护性。

2) 通过动态 SQL 可以更好的适配灵活的需求变更。

3) 通过 SQL 映射简化了 JDBC 代码中 SQL 参数及结果集处理。

4) 合理的架构设计,提高了系统的稳定性,访问性能,可扩展性。

劣势:

1) SQL 语句编写的工作量相对较大。(相对 hibernate 框架)

2) SQL 语句依赖于数据库,移植性相对较差。(不是最大劣势)

62.MyBatis 中的核心 API 有哪些? 

1) SqlSessionFactory

2) SqlSession

3) DefaultSqlSession

4) SqlSessionTemplate

63.MyBatis 的缓存架构是怎样的? 

答:MyBatis 为了提高其查询的性能,提供了一些数据缓存特性,我们可以将这些缓存分为两大类,一级缓存和二级缓存,一级缓存可以理解为 SqlSession 级缓存,同一个 SqlSession 会话执行多次同样的 SQL 查询,查询结果可以从缓存获取。二级缓存默认是没有开启的,需要在映射文件或数据层对象中进行开启,可以多个 SqlSession 会话共享同一个缓存。

64.Spring 是一个什么框架? 

Spring 是一个资源整合框架,其核心是资源整合,然后以一种更加科学的方式对外提供服务,例如提高对象的应用效率,降低系统开销,提高代码的可维护性等等。其官方网址为 spring.io.

65.SpringBoot 是什么? 

Spring Boot 是一个全新的 Java 软件开发框架,很多人现在把它理解为一个脚手架。它基于快速构建理念,通过约定大于配置,开箱即用的方式,来简化 Spring 项目的初始搭建以及开发过程,提高开发效率。

66.简述容器化技术与物理机部署的差异与优缺点?

答:容器化正在称为软件开发的首选方法,这也是有充分理由的。让我们来看看容器化的一些优缺点:

①降低软件和运营成本,使用更少的资源②提供更大的可扩展性(与VM相比)

③提供轻量级和快速的基础架构来运行更新和进行更改④使用其依赖项、库和配置文件封装整个代码,有效消除传统配置可能导致的错误。

但就像其他任何技术一样,容器化也有一些缺点:

①它需要大量的工作才能在组织中以最佳水平执行②它需要有经验或了解流程的人来管理版本和更改。

67.列出典型权限管理所一般具备的表及关系?

答:设计基础:用户、角色、权限三大核心表,加上用户角色、角色权限两个映射表(用于给用户表联系上权限表)。这样就可以通过登录的用户来获取权限列表,或判断是否拥有某个权限。

  大致用到5张表:用户表(UserInfo)、角色表(RoleInfo)、菜单表(MenuInfo)、用户角色表(UserRole)、角色菜单表(RoleMenu)。

各表的大体表结构如下:

  1、用户表(UserInfo):Id、UserName、UserPwd

  2、角色表(RoleInfo):Id、RoleName

  3、菜单表(MenuInfo):Id、MenuName

  4、用户角色表(UserRole):Id、UserId、RoleId

  5、角色菜单表(RoleMenu):Id、RoleId、MenuId

68.@Controller与@RestController的区别

答:① @Controller类中的方法可以直接通过返回String跳转到jsp、ftl、html等模板页面,在方法上加@ResponseBody注解,也可以返回实体对象。

②RestController的所有方法只能返回String、Object、Json等实体对象,不能跳转到模板页面。③@RestController=@Controller+@ResponseBody

69.程序开发过程中应注意哪些安全问题?

答:①服务器的安全预算太少②缺乏相应的安全知识③在服务器的操作系统没有进行安全更新和定期检测③在服务器的操作系统没有进行安全更新和定期检测④由于跨平台开发和编译的脆弱性造成安全问题

除了服务器以外,不安全的数据储存也是另一个常见安全漏洞之一。开发人员的常见做法是依赖于数据的客户端存储,但客户端存储不是沙箱环境,安全漏洞是不可避免的。另外传输层保护不足也是软件的一大安全问题,在传输层安全不足的情况下,黑客可以通过网络抓取来访问数据,并根据自己的意愿修改或窃取数据。一般常规的解决方法是采用SSL和TLS加密通信,除了两种通讯加密外,大家在进行软件开发时要使用具有适当密钥长度的行业标准密码套件,在软件中添加通信证书检测模块,如果检测到无效的证书,应立即提醒用户。

软件开发时所有的安全保护方法都只能起到预防的效果,避免软件程序受到潜在攻击。

 70.mysql实现不使用limit查询第x到第y条的数据

答:

SET @rownum = 0;
SELECT
 * 
FROM 
emp a 
INNER JOIN
 ( SELECT ( @rownum := @rownum + 1 ) ids, emp_id AS id FROM emp  AS b 
ON a.emp_id = b.id
HAVING ids BETWEEN 10 AND 20;

71.MYSQL数据库事务的隔离级别

答:数据库事务的隔离级别分为四种:

读未提交(Read Uncommited)事务1修改的数据被事务2给回滚了

读已提交(Read Commited)事务1读到其他事务修改但是没有提交的信息

可重复读(Repeatable Read)在事务1进行多次的查询操作的时候,查询的结果不一致的

可串行化(Serializable)在同一事务中查询的时候发现多了很多条记录

四种事务隔离级别各自解决的问题

JAVA开发面试题_第1张图片

四种隔离级别的比较总结

并发性

从字面意思上即可理解:

1.可串行化并发能力最低,所有的事务等待执行,解决所有问题,安全性高,但是效率低下

2.之后并发能力一次递增:串行化<可重复度<读已提交<读未提交

3.在实际的开发中根据业务的具体需求,权衡并发性和数据安全性选择对应的隔离级别

72.什么是数据库的事务,事物的特性。

答:事物就是为了保证原有事物的完整性和一致性,通过一定的条件规定该事物的可靠性和安全性(如数据库中的事物)。

A:原子性:一个事物是不可再分的工作单位,该事物要么成功要么失败。

B:一致性:事物必须是使数据库从另外一个一致性状态到另一个一致性状态,与原子性密切相关。

C:持久性:指一个事物一旦提交后对数据库中数据的改变应该是永久不变的。

D:隔离性:一个事物的执行不能够被其他事物所干扰。

73.如果用户使用的是弱密码登录,在用户登录之后怎么去提示用户修改密码.

答:

74.如果用户使用的是弱密码登录,在用户登录之后怎么强制用户修改密码.

答:

75.转发和重定向的区别?

JAVA开发面试题_第2张图片

76.SpringMVC中 后端怎么获取前端传来的数据,使用什么注解?

第一种:@RequestParam注解

作用: 将指定的请求参数赋值给方法中的形参。

接收形式: Get传参请求。

属性:

(1)value :绑定请求的参数名,默认绑定为同名的形参;

(2)required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错;

(3)defaultValue:默认值,表示如果请求中没有接收到值时的默认值。

用法示例:

@GetMapping("/test")
public void test(@RequestParam(required=true) String name,@RequestParam(defaultValue = "20")Integer age) {
        System.out.println("name:"+name+",age:"+age);
}

第二种:@PathVariable注解

作用: 接收请求路径中占位符的值。

接收形式: Get路径请求。

属性: value:String类型,绑定请求的参数名,默认绑定为同名的形参。

用法示例:

@GetMapping("/selectOne/{id}")
public void test(@PathVariable Integer id) {
         System.out.println("id:"+id); 
}

第三种:@RequestBody注解

作用:接收前端传递的Json对象的字符串。

接收形式: Post请求。

用法示例:

@PostMapping("/test")
public void test(@RequestBody User user){
   System.out.println("user:"+user);
}

77.过滤器和拦截器的区别?

拦截器和过滤器其实都是AOP编程思想的实现,都可以体现例如权限的检查日志的记录等功能.

但是有不同之处:

1、使用范围不同

拦截器既可以用在web层 又可以用在Application和Swing程序中

而filter是Servlet规范规定的 只能用于web程序中

2、规范不同

拦截器是在Spring容器内的 是Spring框架支持的

而filter是Servlet规范规定的 是Servlet容器支持的

JAVA开发面试题_第3张图片

78.@RequestParam是干什么的 和@ResponseBody的区别?

@RequestBody这个一般处理的是在ajax请求中声明contentType: “application/json; charset=utf-8”时候。也就是json数据格式或者 xml 数据格式

@RequestParam这个一般就是在ajax里面没有声明contentType的时候,为默认的. 另外使用form提交数据的就只能使用@RequestParam接收。 

@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML

数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

79.JAVA线程池工作原理?

1、线程在有任务的时候会创建核心的线程数corePoolSize

2、当线程满了(有任务但是线程被使用完)不会立即扩容,而是放到阻塞队列中,当阻塞队列满了之后才会继续创建线程。

3、如果队列满了,线程数达到最大线程数则会执行拒绝策略。

4、当线程数大于核心线程数事,超过KeepAliveTime(闲置时间),线程会被回收,最终会保持corePoolSize个线程。

80.数据库三范式?

答:

第一范式(1NF):列不可再分

1.每一列属性都是不可再分的属性值,确保每一列的原子性

2.两列的属性相近或相似或一样,尽量合并属性一样的列,确保不产生冗余数据

第二范式(2NF)属性完全依赖于主键

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。

第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主键

每一行的数据只能与其中一列相关,即一行数据只做一件事,只要数据列中出现重复的数据,那么就要把表拆分开来。

第三范式(3NF)属性不依赖于其它非主属性    属性直接依赖于主键

第二范式(3NF)是在第一范式(2NF)的基础上建立起来的,即满足第三范式(3NF)必须先满足第二范式(2NF)。

简单点意思就是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。

81.数据库事务的特点?

事务就是为了保证原有事物的安全性和一致性,通过一定条件规定该事物的可靠性和安全性.

A:原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
C:一致性(Consistency)
事务前后数据的完整性必须保持一致。
I:隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
D:持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

82.SpringBoot工作流程:

1.手动运行启动类SpringBootApplication.java,同时启动内置tomcat

2.注解@MapperScan("com.xly.dao")读取到dao层

3.加载配置文件,读取端口号,建立JDBC连接,读取到dao的Mapper配置文件等其它配置

4.dao层之后的Service,Controller正常走Spring加载流程

5.Service自动装配记录到dao层,Controller自动装配记录Service层

6.Controller连接到前端资源,完成页面展示

你可能感兴趣的:(java,数据库,服务器)