最新Java面试题

1.sql中有select,from,where,group by,order by,having请问sql执行时的顺序是怎样的? 答: 前面从from(表)where(按条件取出数据)group by(再对取出的数据分组)having(分组后再过滤得到最新数据集)select(按照设置列从数据集里面去除数据)order by(对取出的数据进行排序) 执行顺序:from--where--group by--having--select--order by

2.mybatis中resultMap和resultType的区别? 答: resultMap更强大一些,可自定义字段为别名(column: 库表的 字段名,property: 实体类里的属性名 );一对多的情况时使用resultMap resultType是实体类和数据库表字段一一对应,直接返回类型。二者不可同时存在

3.hashMap和hashTable有哪些区别? 答: hashMap(jdk1.8采用 数组+链表+红黑树,链表阈值长度超过8转为红黑树): 1.key-value存储,单链表超出阈值自增; 2.线程不安全,适用于单线程(多线程下可能会产生死锁),多线程建议使用concurrent并发包下的concurrentHashMap(分段锁); 3.可以有一个null的key,可以有多个null的value;(使用containsKey()方法进行判断是否存在某个键) 4.效率高 hashTable: 1.key-value存储,单链表超出阈值自增; 2.线程安全,适用于多线程,因为hashTable每个方法都加了Synchronize; 3.key不可为null,value不可为null; 4.效率低


如果你想要学习Java的话,我给你分享一些Java的学习资料,你不用浪费时间到处搜了,从Java入门到精通的资料我都给你整理好了,这些资料都是我做Java这几年整理的Java最新学习路线,Java笔试题,Java面试题,Java零基础到精通视频课程,Java开发工具,Java练手项目,Java电子书,Java学习笔记,PDF文档教程,Java程序员面经,Java求职简历模板等,这些资料对你接下来学习Java一定会带来非常大的帮助,每个Java初学者都必备,请你进我的Java技术qq交流群自行下载,所有资料都在群文件里,进去要跟大家多交流学习哦。

 

4.Bean的生命周期? 答: 1.实例化bean对象(通过构造方法或工厂方法) 2.设置对象属性(setter,依赖注入等) 3.如果Bean实现了BeanNameWare接口,工厂调用Bean的setBeanName()方法传递Bean的id。(和下面一条均属于检查Ware接口) 4.如果Bean实现了BeanFactoryAware接口,工厂调用BeanFactoryAware()方法传入工程自身 5.将Bean实例传递给Bean的前置处理器postProcessBeforeInitialization(Object bean, String beanName)方法 6.调用Bean的初始化方法 7.将Bean实例传递给Bean的后置处理器postProcessAfterInitialization(Object bean, String beanName)方法 8.使用Bean 9.容器关闭之前,调用Bean的销毁方法; (简单描述:实例化--设置属性--检查ware接口--初始化--使用--销毁)

5.事务的四大特征?脏读,幻读,不可重复读? 答: 1.(Atomicity)原子性:要么全成功,要么全失败 2.(Isolation)隔离性:多个并发事务互不影响 3.(Consistency)一致性:事务前后数据的完整性始终保持一致 4.(Durability)持久性:当事务完成后,数据库的改变是永久的 5.脏读:读取未提交数据 6.幻读:前后多次读取,数据总量不一致 7.不可重复读:前后多次读取,数据内容不一致

6.跨域怎么解决? 当前端页面与后台运行在不同的服务器时,就必定会出现跨域这一问题。所谓同源策略是指,域名,协议,端口均相同;不同源则产生跨域。 答: 1.使用ajax的jsonp,该方式只适用于GET请求 2.使用negix的反向代理 3.使用Cros(在后台控制层加上:@CrossOrigin(origins = "*", maxAge = 3600)//origins : 允许可访问的域列表,"*"代表所有; maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。)

7.IOC和AOP可以说一下嘛? 答: IOC控制反转:将创建对象的权利交给核心容器(由容器来负责对象的生命周期和对象之间的关系)。IOC主要实现方式有两种:依赖注入和控制反转(DI:就是IOC容器把当前对象所需要的外部资源动态注入给我们;四种注入方式:注解注入,set注入,构造器注入,静态工厂注入) ----当某个角色 需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中 创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 因此也称为依赖注入。 AOP面向切面编程:可以说是OOP的补充和完善,OOP引入封装、继承和多态性等概念来建立一种对象层次结构。实现AOP的技术,主要分为两大类:一是采用动态代理技术,二是采用静态织入的方式。 ----这玩意我举个例子说下,比如你写了个方法用来做一些事情,但这个事情要求登录用户才能做,你就可以在这个方法执行前验证一下,执行后记录下操作日志,把前后的这些与业务逻辑无关的代码抽取出来放一个类里,这个类就是切面(Aspect),这个被环绕的方法就是切点(Pointcut),你所做的执行前执行后的这些方法统一叫做增强处理(Advice)。

8.过滤器和拦截器的区别简单说一下
答: 过滤器: 通俗的说过滤器就是筛选出你想要的东西(就是一堆请求过来时,过滤掉一些不合法的请求),比如request中你想要的那部分,依赖于servlet容器。(应用场景:URL级别的权限访问控制;过滤敏感词汇(防止sql注入);设置字符编码) springboot自定义过滤器实现步骤:1.利用@WebFilter创建Filter过滤器类;2.Application启动类添加@ServletComponentScan注解 拦截器: 拦截器,请求的接口被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略(底层是动态代理-反射)。 拦截器主要用来按照指定规则拒绝请求。 在做安全方便用的比较多,比如终止一些流程等(应用场景:Token令牌验证;请求数据校验;用户权限校验;放行指定接口;拦截未登录用户)。 springboot自定义拦截器实现只需两步:1.自定义拦截器,实现HandlerInterceptor这个接口;2.注册拦截器。 从灵活性上说拦截器功能更强大些,Filter能做的事情,他都能做;

9.HashMap组成原理和底层实现原理? 答: 在Java中最基本的数据结构有两种,数组和链表 数组:查询快,根据索引查询,添加和删除比较困难; 链表:查询慢,需要遍历整个链表,添加和删除容易; HashMap是由数组加链表组成,数据结构中又叫 “链表散列” 红黑树(jdk1.8): 一种二叉树,高效的检索效率 当链表达到一定长度后,链表就会变成红黑树(A下面有两个节点BC,B和C下面又有DEF) HashMap的特点: 1.快速存储:比如当我们对hashmap进行get和put的时候速度非常快;

2.快速查找:当我们通过key去get一个value的时候时间复杂度非常的低,效率非常高;

3.可伸缩:1数组扩容,边长。2,单线列表如果长度超过8的话会变成红黑树。

10.微服务架构有了解吗?(比如springCloud) 答: (可以说一下springCloud的五大组件,把你知道的都说出来) Eureka:服务注册中心(类似注册中心还有Consul,了解哪一种就描述哪一种) Ribbon:本地负载均衡(Feign:服务与服务间远程调用) Zuul/Gateway:服务网关(类似Nginx反相代理的功能;Gateway是基于Springboot2.0,取代Zuul) Hystrix:断路器 Spring Cloud Config:分布式配置(目前还是静态的,需要配合Spring Cloud Bus来实现动态的配置更新)

12.微服务动态配置有几种实现方式? 答: 1.使用Consul做注册中心,(微服务配置做在线配置统一管理,也可实现动态配置加载); 2.携程的Apollo(推荐使用,配置修改实时生效(热发布)); 3.springCloud全家桶自带的config(听说不是很好用,目前项目中还未用到); 4.阿里的 Nacos(即可做服务注册中心,也可做配置中心,听朋友说好用)

13.mysql优化常用到的几种方式,简单说一下? 答: mysql优化主要分为以下四大方面: 1.设计:存储引擎,字段类型,范式与逆范式,减少访问数据库的次数

2.功能:索引,缓存,分区分表。

3.架构:主从复制,读写分离,负载均衡。

4.合理SQL:合理使用join,尽量不要使用select *,in,not in ,or。

14.spring和springboot的区别(优缺点) 答: springboot基本上是spring框架的一个扩展,消除了spring的一些复杂配置

14.Redis用过吗? 答: 用过,支持多种存储类型,五大基本类型说一下 String(字符串):一个key对应一个value Hash(哈希):类似java中Map<String,Object> 常用 List(列表):字符串列表 Set(集合):String类型的无序集合 ZSet:不可重,有序集合 说一个使用场景:手机号验证码登录功能,session共享。

15.使用过什么中间件? 答: RabbitMQ(消息队列)

MyCat(分库分表,读写分离)

Mybatis(持久层框架)

Swagger2(swagger-ui,Rest APIs文档生成工具)

PageHelper(物理分页插件)

16.请说一下Java中的NIO,BIO,AIO分别是什么? 答: BIO:同步阻塞式IO,简单理解:一个连接一个线程,BIO适用于连接数目比较小且固定的架构,这种方式对服务器的资源要求比较高,并发局限于应用中,jdk1.4以前唯一的选择,单程序直观简单易理解。 NIO:同步非阻塞IO,简单理解:一个请求一个线程,NIO适合连接数目多且连接比较短(清操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,jdk1.4开始支持。 AIO:异步非阻塞IO,简单理解:一个有效请求一个线程,AIO适用于连接数目多,且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,jdk1.7开始支持。

17.说一下Spring的设计模式 答: 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例; 单例模式:Bean默认为单例模式; 代理模式:Spring的AOP就是使用了JDK的动态代理和CGLIB字节码生成技术; 模版方法:用来解决重复代码的问题,比如RedisTemplate, JpaTemplate。 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

如果你想要学习Java的话,我给你分享一些Java的学习资料,你不用浪费时间到处搜了,从Java入门到精通的资料我都给你整理好了,这些资料都是我做Java这几年整理的Java最新学习路线,Java笔试题,Java面试题,Java零基础到精通视频课程,Java开发工具,Java练手项目,Java电子书,Java学习笔记,PDF文档教程,Java程序员面经,Java求职简历模板等,这些资料对你接下来学习Java一定会带来非常大的帮助,每个Java初学者都必备,请你进我的Java技术qq交流群自行下载,所有资料都在群文件里,进去要跟大家多交流学习哦。18.用过那些前端框架? 答: Bootstarp;easyUI;LayUI Thymeleaf(springboot默认是不支持jsp的,默认使用的Thymeleaf模版引擎)

19.ThreadLocal有什么作用? 答: waitingThreadLocal是创建线程的本地变量,一个对像的所有线程共享它的全部局变量,所以这些变量是非线程安全的,我们可以使用同步技术。但是我们不想使用同步技术的时候,可以选择ThreadLocal变量。每个线程都会拥有他们自己的Thread变量,他们可以使用get(),set()去获取他们的默认值或者在线程内部改变他们的值。(说白了,ThreadLocal就是想在多线程下保证成员变量的安全)

20.多线程了解吗? 答: 可以从以下几个方面作出回答:

  • 创建多线程的四种方式:

1.继承Thread类(缺点:Java只支持单继承) 2.实现Runnable接口(可返回执行结果,run()方法不可向外抛异常,只能内部消化) 3.实现Callable接口(不返回执行结果,call()方法允许向外抛出异常) 4.通过线程池创建线程,Executors工具类是用来创建线程池的,可以指定线程也可以不指定。

  • 出现线程不安全的原因是什么?

答:如果我们创建多个线程,存在着共享数据,那么就有可能出现线程安全的问题:当其中一个线程操作共享数据时,还未操作完成,另外的线程就参与进来,导致共享数据的操作出现问题。

  • 线程不安全解决办法?

要求一个线程操作共享数据时,只有当其完成操作共享数据,其他线程才会有机会执行共享数据。Java提供了两种方式来实现同步互斥访问:synchronized和lock。

  • 多线程中wait()和sleep()的区别?

wait()会释放当前持有的锁,进行等待,sleep()不会释放锁; wait()只能在同步代码块或同步方法内使用,sleep()可以在任意地方进行使用; wait() notify()只唤醒一个线程 notifyAll()唤醒所有线程 不需要捕获异常,sleep()需要捕获异常; 推荐:由于sleep()不释放锁资源,容易导致死锁问题,而wait()不会,一般情况下推荐使用wait() 。

21.Java线程池的实现原理,主要方法ThreadPoolExecutor() 答: 线程池说白了就是一个线程集合workerSet和一个阻塞队列workQueue,当用户向线程池提交一个任务(也就是线程)时,线程池会先将任务放入workQueue中,workerSet中的线程会不断的从workQueue中获取线程然后执行。当workQueue没有任务的时候,worker就会阻塞,直到队列中有任务了就取出来继续执行。

22.mysql索引用过吗? 答: 用过,用的最多的就是主键唯一索引。

  • 什么是索引? 索引就像查词典一样,根据目录进行查找。
  • 你都知道那些索引类型? 唯一索引(unique):不可出现相同的值,允许又null值; 普通索引(index):允许出现相同的索引内容; 主键索引(promary key):不允许出现相同的值; 全文索引(fulltext text):可以针对值中的某个单词,效率低; 组合索引(combination):将多个字段组到一个索引里,列值的组合必须唯一;
  • 索引虽然好处好,但过多使用索引也会带来相反的问题 使用索引虽然可以提高查询效率,同时却会降低表的更新效率 建立索引会占用磁盘空间,索引建立过多,索引文件会膨胀很宽。

23.说一下你对Java动态代理的理解 答: 代理类在程序运行时创建的代理方式被称为动态代理。 最直白的例子就是spring的面向切面编程AOP,我们能在一个切点之前执行一些操作,在一个切点后执行一些操作,这个切点就是一个个方法。这些方法所在的类肯定是被代理了,在代理过程中切入一些其他操作。

24.项目中是怎么处理事务的? 答: Spring提供了好多事务管理机制,主要分为编程式事务和声明式事务两种。 编程式事务:是指在代码中手动的管理事务的提交,回滚等操作,代码侵入型很强,如下实例:

  try { transactionManager.commit(status);} 
     catch (Exception e) { transactionManager.rollback(status); throw new InvoiceApplyException("异常失败");}
复制代码

声明式事务:基于AOP面向切面,他将具体业务和事务处理部分解藕,代码侵入性很低,所以在实际项目开发中使用声明式事务较多。(声明式事务实现也分为两种,一是基于TX和AOP的xml配置文件方式,二是基于@Transactionl注解)如下实例:

//@Transactional 可以作用在接口、类、类方法。
@Transactional(rollbackFor = Exception.class)
复制代码

面试官这时又问:项目中使用注解的方式不会滚,能说下是什么情况吗? 答:1.检查你的方法是不是public; 2.你的异常类型是不是unchecked异常(Error或者RuntimeException(比如空指针,1/0)) unchecked异常:空指针等死检测不到的,叫unchecked异常。 checked异常:我们的编译器是能够检测到的,就叫checked异常; 3.数据库引擎要支持事务,如果是MySQL,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的; 4.是否开启了对注解的解析;

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
复制代码

5.spring是否扫描到你这个包,如下是扫描到org.test下面的包

<context:component-scan base-package="org.test" ></context:component-scan>
复制代码

6.检查是不是同一个类中的方法调用(如a方法调用同一个类中的b方法) 7.异常是不是被你catch住了。

25.是否看过spring源码,能不能说一下ioc底层的实现原理 答: 以前我们要调用某个类中的方法都是要new对象,现在有了ioc我们把对象交给BeanFactory(bean工厂)来管理,用的时候直接去工厂中取。 ioc是通过工厂模式,反射机制来实现的!

26.说说Jvm内存模型 答: 整个Jvm可以分为两大区 线程共享区 1.方法区(jdk1.8后方法区变为元空间):用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译的代码等数据 2.堆:Java虚拟机所管理的内存中最大的一块区域,所有线程共享区域。此内存区域的唯一目的就是存放对象实例, Java堆是垃圾收集器管理的主要区域(GC堆从内存回收的角度讲,收集器基本上使用分代收集算法,所以Java堆还可以细分为:新生代和老年代,永久代(jdk1.8后改名为元空间)) 线程私有区(随线程生而生,随线程死而死) 1.虚拟机栈:Java方法执行的内存模型,存储局部变量表,操作栈,动态链接,方法出口等信息; 2.本地方法栈:本地方法被执行的时候会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息; 3.程序计数器:程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。

27.对JVM的垃圾回收的认识? 答: 垃圾回收器的作用是回收(清除)和查找无用的对象。 以便让JVM更有效的使用内存。

哪些东西需要回收? 程序计算器、栈、本地方法栈3个区域的内存随着线程而生,随线程而灭;内存分配大体上在编译期间都已经确认;以此这些区域内存分配和回收都有确定性;故就不需要jvm打理回收了;方法结束或线程结束时,内存自然跟着回收了。而堆和方法区是动态分配的,只有在程序运行期间才知道哪些对象要建,内存分配和回收是动态的;故jvm只要关注此部分内存就好啦!!

什么时候回收? 其实很简单-----就是东西没有人用了,就可以回收了!在jvm中,假设对象没有线程或方法使用则证明该对象可以回收了。 如何判断对象没有被引用或使用呢? 第一种算法--引用计数器算法(给对象添加一个引用计数器,当有引用指向它时计数器就+1,当引用失效时-1,计数器为0时就不可被引用了;此方法简单高效但有个缺点就是两个对象互相引用的时候;gc就没有办法回收此对象了;故很少采用此算法。) 第二种方法--可达性分析算法(其算法思想就是通过gc_root节点作为起始点,往下搜索,搜索走过的路径叫做引用链;当一个对象没有一个gc root相连的话,则证明此对象已经没有使用,可以判断可以回收。)

用什么方式回收? 答: 1.标记-清除算法( 先标记好,然后统一回收;清除后产生零碎化内存;) 2.复制算法(将可用内存划分为大小相等的两块,每次只使用一块,当这一块内存使用完后,就将还存活的对象复制到另外一块上;然后再把已经用过的内存一次清空;) 3.分代收集算法(根据对象存活周期,分为新生代和老年代;针对不同的代采用不同的算法;)

28.JVM如何GC,新生代,老年代,持久代,都存储哪些东西? 答: JVM的GC算法有:引用计数器算法,根搜索方法(详情可参考27) 新生代:新生成的对象 老年代:在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中(生命周期较长的对象) 持久代:用于存放静态文件,如今Java类、方法等

29.什么情况下会发生栈内存溢出 答: 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。 向有经验的同学请教,说内存使用量飙高,一般都是中间件引起的内存泄漏。因为我们线上服务使用 Java 语言开发,所以先从 JVM 垃圾收集器 GC 入手,可以比较直观地看出 JVM 内存状况。(jstat -gcutil pgrep -u mapp java 1s)

30.讲讲你对Java反射机制的理解? 答: 首先我们要明白Java中创建对象的方式有四种 1.使用new关键字:这是我们最常见的也是最简单的创建对象的方式 2.使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去 3.使用反序列化:当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象 4.反射 什么是反射? 反射就是把Java类中的各个部分,映射成一个个的Java对象,拿到这些对象后可以做一些事情。(各个部分:成员变量,方法,构造方法,等信息) 怎么得到反射的类? 首先大家要明白一点,咱们写的代码是存储在后缀名是 .java的文件里的,但是它会被编译,最终真正去执行的是编译后的 .class文件;Java是面向对象的语言,一切皆对象,所以java认为 这些编译后的 class文件,这种事物也是一种对象,它也给抽象成了一种类,这个类就是Class。

31.mysql事务隔离级别? 答: 1.未提交读:所有事务都可以看到没有提交事务的数据; 2.提交读:事务成功提交后才可以查询到; 3.重复读:同一个事务多个实例读取数据时,可能将未提交的记录查询出来,而出现幻读(mysql默认级别); 4.可串行化:强制的进行排序,在每个读数据行上添加共享锁。会导致大量超时现象和锁竞争;

32.RabbitMQ死信队列如何处理? 答: 不希望:(如果不做任何处理,当消费消息时出现异常,默认会不断的重试,这显然不是我们希望的) 我们希望的:可以指定重试的次数,重试完了之后进入死信队列,然后就可以人为的对死信队列进行处理 1.需要将一个Queue关联死信队列的Exchange和RoutingKey 2.在UI页面可看到多次重试后的消息进入了死信队列 3.处理死信队列 ---3.1 通过人工去处理死信队列 ---3.2 等待系统正常后把死信队列中的消息路由到Queue去处理

33.说下对Synchronized关键字的理解 答:Synchronized是Java中解决并发问题的一种常见的方法,也是最简单一种方法(我们都知道synchronized可以让线程同步,所谓同步,就是同一时刻只有一个线程执行这段代码)。 三个主要作用: (1)确保线程互斥的访问同步代码 (2)保证共享变量的修改能够及时可见 (3)有效解决重排序问题 三种用法: (1)修饰普通方法 (2)修饰静态方法 (3)修饰代码块 sychronized原理:

34.mybatis加载mappers有几种方式? 答:共4种 1.resource 2.url 3.class 4.package(优先级最高)

35.Mybatis底层原理? 一. mybatis是如何获取数据源的? 答:mybatis获取数据源的创建使用工厂模式,基本分为两种:有带连接池的数据源,不带连接池的数据源(类似jdbc)。 二. mybatis是如何获取SQL的? 三. mybatis是如何操作的? 四. mybatis有几种执行器? 五. mybatis一级缓存默认状态?怎么创建,怎么使用的? 后面还会持续更新

 

最后


如果你想要学习Java的话,我给你分享一些Java的学习资料,你不用浪费时间到处搜了,从Java入门到精通的资料我都给你整理好了,这些资料都是我做Java这几年整理的Java最新学习路线,Java笔试题,Java面试题,Java零基础到精通视频课程,Java开发工具,Java练手项目,Java电子书,Java学习笔记,PDF文档教程,Java程序员面经,Java求职简历模板等,这些资料对你接下来学习Java一定会带来非常大的帮助,每个Java初学者都必备,请你进我的Java技术qq交流群自行下载,所有资料都在群文件里,进去要跟大家多交流学习哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值