面试汇总
基础部分=====
1.Java的深克隆浅克隆区别
浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
参考资料:https://blog.csdn.net/lovezhaohaimig/article/details/80372233
2.隔离级别,事物特性
事务隔离级别共有几种?由低至高都是什么?
事务隔离级别共四种,隔离的程度由低至高就是:1)READ-UNCOMMITTED(读取未提交内容)级别 2)READ-COMMITTED(读取提交内容)级别 3)REPEATABLE-READ(可重读)级别 4)SERIERLIZED(串行化,序列化) 。
资料参考:https://www.cnblogs.com/xrq730/p/5087378.html
3.分布式锁是怎么做的
单机的话:常见的诸如synchronize,lock,volatile,c.u.t包等等。
参考资料:https://www.cnblogs.com/shoshana-kong/p/9581557.html
4.aop应用
AOP的思想就是业务逻辑和横切面问题分离,从而达到解耦,使代码的重用性和开发效率提高。
AOP,面向切面编程,就是把可重用的功能提取出来,然后将这些通用功能在合适的时候织入到应用程序中,比如事务管理、权限控制、日志记录、性能统计(服务调用的时间,写一个方法通过注解注入方式,提高代码的复用复用性。
参考资料:https://blog.csdn.net/weixin_37020977/article/details/81007286
5.线程生命周期(状态),线程的配置参数
新建(new),可运行(runnable),运行(running),阻塞(blocked)销毁(dead)
从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。下面会对这7个参数一一解释。
5.1、corePoolSize 线程池核心线程大小
线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会 被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。
5.2、maximumPoolSize 线程池最大线程数量
一个任务被提交到线程池后,首先会缓存到工作队列(后面会介绍)中,如果工作队列满了,则会创建一个新线程,然后从工作队列中的取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize来指定。
5.3、keepAliveTime 空闲线程存活时间
一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定
5.4、unit 空间线程存活时间单位
keepAliveTime的计量单位
5.5、workQueue 工作队列
新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:
①ArrayBlockingQueue
基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
②LinkedBlockingQuene
基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
③SynchronousQuene
一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
④PriorityBlockingQueue
具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
5.6、threadFactory 线程工厂
创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等
5.7、handler 拒绝策略
当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:
①CallerRunsPolicy
该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
参考资料:https://blog.csdn.net/ye17186/article/details/89467919?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
7.hashmap 原理解释一下,底层结构,jdk1.8前后版本的差别。为什么是线程不安全的(put 死锁)
什么时候会扩容:加载因子的系数小于等于1,意指 即当 元素个数 超过 容量长度*加载因子的系数 时,进行扩容。
继承map,非线程安全,可以储存null key 和null键,以键值对的形式存在,底层结构是,数组和链表结构
1.8版本之后做了性能的优化,在链表长度超过阈值8,将链表转化为红黑树,提升性能。
总结版:HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中,在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的。
————————————————
9.==和===的区别
简单来说: == 代表相同, ===代表严格相同
比较过程:
双等号==:
(1)如果两个值类型相同,再进行三个等号(===)的比较
(2)如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:
1)如果一个是null,一个是undefined,那么相等
2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较
三等号===:
(1)如果类型不同,就一定不相等
(2)如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)
(3)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。
(4)如果两个值都是true,或是false,那么相等
(5)如果两个值都引用同一个对象或是函数,那么相等,否则不相等
(6)如果两个值都是null,或是undefined,那么相等
10.springbootapplication注解,组成 ,了解自动配置原理,读源码。?
解释一下,@SpringBootApplication其实就是以下三个注解的总和,
@Configuration: 用于定义一个配置类
@EnableAutoConfiguration :Spring Boot会自动根据你jar包的依赖来自动配置项目。
@ComponentScan: 告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。
11.autowired和resource注解的区别
作为controller层的service注入,
@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired。
@Autowired采取的策略为按照类型注入。
public class UserService {
@Autowired
private UserDao userDao;
}
如上代码所示,这样装配回去spring容器中找到类型为UserDao的类,然后将其注入进来。这样会产生一个问题,当一个类型有多个bean值的时候,会造成无法选择具体注入哪一个的情况,这个时候我们需要配合着@Qualifier使用。
@Qualifier告诉spring具体去装配哪个对象。
public class UserService {
@Autowired
@Qualifier(name="userDao1")
private UserDao userDao;
}
这个时候我们就可以通过类型和名称定位到我们想注入的对象。
@Resource
@Resource注解由J2EE提供,需要导入包javax.annotation.Resource。
@Resource默认按照ByName自动注入。
public class UserService {
@Resource
private UserDao userDao;
@Resource(name="studentDao")
private StudentDao studentDao;
@Resource(type="TeacherDao")
private TeacherDao teacherDao;
@Resource(name="manDao",type="ManDao")
private ManDao manDao;
}
①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
springmvc的执行流程
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)
第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)
第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域)
第十一步:前端控制器向用户响应结果
12.spring aop ioc 的含义以及项目运用
13.注入方式(动态注入,静态注入)
14.restcontroller和controller注解区别
开发RESTful API 时,一般都会在Controller上加上@Controller注解,但是有时候加上@RestController,当同事问为什么的时候,我也一脸懵逼,默默的看了资料,现在就说说他们的区别。
@RestController注解等价于@ResponseBody + @Controller。@RestController和@Controller的共同点是都用来表示Spring某个类是否可以接收HTTP请求,二者区别: @RestController无法返回指定页面,而@Controller可以;前者可以直接返回数据,后者需要@ResponseBody辅助。下面详细分析。
① 是否可以返回页面
答:@RestController无法返回指定页面,而@Controller可以。
解析:对于Controller, 如果只是使用@RestController注解,则其方法无法返回指定页面,此时配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是 return 里的内容。 如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
② 返回内容
如果需要返回JSON,XML或自定义mediaType内容到页面,@RestController自己就可以搞定,这个注解对于返回数据比较方便,因为它会自动将对象实体转换为JSON格式。而@Controller需要在对应的方法加上@ResponseBody注解。
15.resultMap 和resultype 的区别
基本映射 :(resultType)使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。(数据库,实体,查询字段,,这些全部都得一一对应)
高级映射 :(resultMap) 如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。(高级映射,字段名称可以不一致,通过映射来实现)
16.mysql 取出最大的一个值,去除第二个最大值
select top 1 id,name,age from 表 order by age desc
按照年龄倒序排序,然后取第一条。
考虑可能有多人年龄相同,如果都需取出,可以这样写:
select id,name,age from 表 where age=(select max(age) from 表)
select max(age) as '第二大年龄' from Students where age<(select max(age) from Students ;
17 springcloud 微服务的组件有哪些,分别是做什么的?
服务发现——Netflix Eureka 其作用是什么?负责管理服务列表,服务订阅,修改一些配置。 重点问如果出现单点故障怎么处理,方案用eureka集群来实现。
客服端负载均衡——Netflix Ribbon
负载均衡的策略:
1>轮询(默认) 2>基于权重的轮询 3>最小活跃数 4>一致性hash
断路器——Netflix Hystrix 要详细看代码原理。默认有两种处理方式,如果在调用其他服务失败,1>暂时屏蔽某服务。2>容错。均返回null。
服务网关——Netflix Zuul 网关路由是怎么做的 ,项目中的实际应用。
分布式配置——Spring Cloud Config
资料参考:https://www.cnblogs.com/lingboweifu/p/11807465.html
18.redis的数据类型常见的有哪些?分别是怎么应用的
string
hash:储存用户信息,格式为:key filed value.
list:实现最新消息的排行
set:自动排序
sorted set:以某一条件为权重排序,如京东商品按照价格排序。
资料参考:https://blog.csdn.net/GV7lZB0y87u7C/article/details/93986796
19.单例模式有哪几种,分别是什么,
懒汉模式 饿汉模式 、懒汉式同步锁、双重校验锁、利用静态内部类、枚举。手写单例,手写线程不安全的代码
20.dubbo的消费者和提供者分别指的是什么 , dubbo各个组件分别介绍
provider comsumer register minotor
个人理解:提供者是客户端,消费者是服务端。
21.前后端的测试工具
22.java接口中的方法用default修饰有什么特性
Java8给接口增加了default关键词,用default修饰的方法可以有实现内容,实现该接口的类可以不重写用default修饰的方法,类似于继承。但这样也会带来新的问题。
Java中只能继承一个类,但是可以实现多个接口,当多个接口中有版同一个方法时,以前是没问题的,因为实现类必须重写方法。但现在,当多个接口中有同一个用default修饰的方法时,就无法判断到底实现的是哪个接口的权方法。这种情况下,就必须重写方法。
还有一种情况,一个类继承的父类和实现的接口中都有同一个方法,而这个类又没有重写时,实现的是父类的方法,而不是接口中的方法。
23.java8 lambda表达式的几种使用场景
24.aop属于什么模式,动态代理,静态代理分别怎么理解
AOP就是动态代理,动态代理分/(jdk cglib).比如Spring的事务使用的是aop技术,当目标类没有实现接口时候,会使用cglib代理,实现了接口默认使用JDK代理。还有一个属性proxytargetclass 默认为false,如改为true 则优先使用的是cglib代理。
25 数据库设计的注意事项
命名规范,注释内容,数据库连接数。
26 自动化打包部署 jenkins 原理
27 外连接和inner连接
28 mysql不走索引(索引失效)的几种情况,建索引的规则(什么地方建索引),哪些位置不需要建索引。
1>对索引列进行函数运算。
2>like以%开头的查询语句。模糊查询
后通配 走索引
前通配 走全表 不走索引。
3>包含is null is/ not null/ !=/<>的语句。
4>字符串不加单引号。
8. like模糊查询是否走索引 %在左在右的区别
索引的本质是平衡b+数,是为了方便查询的
平衡多路查找树
B-Tree相比,B+Tree有以下不同点:
每个节点的指针上限为2d而不是2d+1;
内节点不存储data,只存储key;
叶子节点不存储指针
B+Tree比B-Tree更适合实现外存储索引结构
建立索引原则:数据量多,唯一性,经常用到排序
无需建立索引:1.数据量比较小,经常做增删改(如账户余额),where条件用不到的字段,过滤性不好(如性别字段)
30 接口和抽象类
string stringBuilder stringBuffer 之间的区别
string 修饰的是不可变字符数组,源码中使用的是final 修饰,char[]。减少使用,因为每次new对象会有内存消耗。
stringBuilder stringBuffer都是abstractStringBuilder的子类。修饰的是可变字符数组。所以经常用于字符串截取操作。其二者区别是stringBuilder 是非线程安全的,效率高。stringBuffer底层源码有synchonized关键字,线程安全,效率比较低。
31 spring cloud全家桶。
eruake集群解决单点故障问题,zuul是怎么做网关路由,项目中是怎么使用的,hystrix是怎么做服务熔断,降级,原理。
32 jvm的内存结构,以及怎么调优
程序计数器 虚拟机栈 本地栈 堆 方法区。分别表示什么意思 线程是否共享的问题,减少gc回收,full gc 伊甸园 8:1:1
33 通信 dubbo中的通信 netty nio/io 多路复用。
34 外部接口是怎么联调的。rpc调用。调用的步骤
connect = new URL(url);
HttpURLConnection connection = (HttpURLConnection) connect.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setReadTimeout(timeout);
connection.setRequestProperty("Content-Type", "application/json");
OutputStreamWriter paramout = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
paramout.write(object.toString());
paramout.flush();
InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader reader = new BufferedReader(inputStreamReader);
1,远程服务之间建立通讯协议
2,寻址:服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么
3,通过序列化和反序列化进行数据传递
4,将传递过来的数据通过java反射原理定位接口方法和参数
5,暴露服务:用map将寻址的信息暴露给远方服务(提供一个endpoint URI或者一个前端展示页面)
6,多线程并发请求业务
35 怎么解决下标越界
36 spring bean的生命周期,以及作用域
执行 docreatbean方法 。对象bean实例化 属性赋值 实例初始化 实例销毁
37 ELK了解 elasticSearch logback kibana
elasticSearch与solr的区别,各自优点:
都是分词技术。匹配检索,倒序索引进行查询。
solr是一个动态的web 项目。
实时建立索引,动态加载数据,es优于solr.
solr支持更多的数据格式(xml,json,csv,各种文档)。es只支持json。
38 重复提交数据,怎么保证数据的幂等性。MQ怎么防止重复数据?
1>前端控制:点击事件后加一个置灰处理。
2>后台传递token(唯一)
3>唯一索引
4>乐观锁悲观锁加锁处理。
2.1 做数据插入操作时,给一个主键。
2.2 全局加一个id,做判断,如果存在则更新,不存在则写入。
2.3 redis的set(不重复),天然的幂等性。
39 乐观锁和悲观锁的区别。
乐观锁:认为在读取数据的时候别人不会对其进行修改,所以不会上锁。适用于多读少写的情况。如果是必须要修改数据。有两种方式,1 添加版本号,在修改完数据并提交的时候对比一下此时的版本号和之前记录的版本号是否一致,如果一致则做修改操作。CAS:?????????????????????
悲观锁:认为在读取数据的时候别人一定回修改数据,所以不管怎么样都会加锁处理。线程A会被阻塞挂起,让出cpu,然后处理线程B.适用于多写少读的情况。
linkList双向链表结构,删除元素是从左边还是右边
gc算法有几种?fullGC 新生代 老年代。
创建线程的四种方式。
mysql的索引数据结构
redis缓存失效的策略
Java垃圾回收算法
MySQL数据类型
Linux 查看端口占用,切换用户